3b2: Update README.md and correct line endings

This change updates the 3B2 README.md file, and fixes
all line endings on 3B2 source files.
This commit is contained in:
Seth Morabito 2022-09-19 09:37:17 -07:00
parent 75aefcb75c
commit 84bf5f4d14
46 changed files with 25752 additions and 25833 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,46 +1,46 @@
/* 3b2_csr.h: Common CSR/CSER header /* 3b2_csr.h: Common CSR/CSER header
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_CSR_H_ #ifndef _3B2_CSR_H_
#define _3B2_CSR_H_ #define _3B2_CSR_H_
#if defined(REV3) #if defined(REV3)
#include "3b2_rev3_csr.h" #include "3b2_rev3_csr.h"
#else #else
#include "3b2_rev2_csr.h" #include "3b2_rev2_csr.h"
#endif #endif
#define SET_CSR(FLAGS) (csr_data |= (FLAGS)) #define SET_CSR(FLAGS) (csr_data |= (FLAGS))
#define CLR_CSR(FLAGS) (csr_data &= ~(FLAGS)) #define CLR_CSR(FLAGS) (csr_data &= ~(FLAGS))
#define CSR(FLAGS) ((csr_data & FLAGS) != 0) #define CSR(FLAGS) ((csr_data & FLAGS) != 0)
extern CSR_DATA csr_data; extern CSR_DATA csr_data;
#endif /* _3B2_CSR_H_ */ #endif /* _3B2_CSR_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,153 +1,153 @@
/* 3b2_ctc.h: CM195H 23MB Cartridge Tape Controller CIO Card /* 3b2_ctc.h: CM195H 23MB Cartridge Tape Controller CIO Card
Copyright (c) 2018-2022, Seth J. Morabito Copyright (c) 2018-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
/* /*
* CTC is an intelligent feature card for the 3B2 that supports a * CTC is an intelligent feature card for the 3B2 that supports a
* Cipher "FloppyTape(tm)" 525 drive that can read and write 23MB * Cipher "FloppyTape(tm)" 525 drive that can read and write 23MB
* DC600A cartridges. * DC600A cartridges.
* *
* The CTC card is based on the Common I/O (CIO) platform. * The CTC card is based on the Common I/O (CIO) platform.
* *
* Notes: * Notes:
* ------ * ------
* *
* The Cipher FloppyTape is an odd beast. Although it's a tape drive, * The Cipher FloppyTape is an odd beast. Although it's a tape drive,
* it is controlled by a floppy controller. It is divided into virtual * it is controlled by a floppy controller. It is divided into virtual
* sectors that can be addressed by Cylinder / Track / Sector. * sectors that can be addressed by Cylinder / Track / Sector.
* Stepping and head select pulses dictate where on the tape to read * Stepping and head select pulses dictate where on the tape to read
* from or write to. Moreover, System V maps a filesystem onto the * from or write to. Moreover, System V maps a filesystem onto the
* tape, and a properly formatted tape drive will have a VTOC on * tape, and a properly formatted tape drive will have a VTOC on
* partition 0. * partition 0.
* *
*/ */
#ifndef _3B2_CTC_H_ #ifndef _3B2_CTC_H_
#define _3B2_CTC_H_ #define _3B2_CTC_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define CTC_ID 0x0005 #define CTC_ID 0x0005
#define CTC_IPL 12 #define CTC_IPL 12
#define CTC_VERSION 1 #define CTC_VERSION 1
/* Request Opcodes */ /* Request Opcodes */
#define CTC_CONFIG 30 #define CTC_CONFIG 30
#define CTC_CLOSE 31 #define CTC_CLOSE 31
#define CTC_FORMAT 32 #define CTC_FORMAT 32
#define CTC_OPEN 33 #define CTC_OPEN 33
#define CTC_READ 34 #define CTC_READ 34
#define CTC_WRITE 35 #define CTC_WRITE 35
#define CTC_VWRITE 36 #define CTC_VWRITE 36
/* Completion Opcodes */ /* Completion Opcodes */
#define CTC_SUCCESS 0 #define CTC_SUCCESS 0
#define CTC_HWERROR 32 #define CTC_HWERROR 32
#define CTC_RDONLY 33 #define CTC_RDONLY 33
#define CTC_NOTREADY 36 #define CTC_NOTREADY 36
#define CTC_RWERROR 37 #define CTC_RWERROR 37
#define CTC_NOMEDIA 42 #define CTC_NOMEDIA 42
/* VTOC values */ /* VTOC values */
#define VTOC_VERSION 1 #define VTOC_VERSION 1
#define VTOC_SECSZ 512 #define VTOC_SECSZ 512
#define VTOC_PART 16 /* Number of "partitions" on tape */ #define VTOC_PART 16 /* Number of "partitions" on tape */
#define VTOC_VALID 0x600DDEEE /* Magic number for valid VTOC */ #define VTOC_VALID 0x600DDEEE /* Magic number for valid VTOC */
#define CTC_NUM_SD 2 #define CTC_NUM_SD 2
#define CTC_SD_FT25 4 #define CTC_SD_FT25 4
#define CTC_SD_FD5 1 #define CTC_SD_FD5 1
/* Physical Device Info (pdinfo) values */ /* Physical Device Info (pdinfo) values */
#define PD_VALID 0xCA5E600D /* Magic number for valid PDINFO */ #define PD_VALID 0xCA5E600D /* Magic number for valid PDINFO */
#define PD_DRIVEID 5 #define PD_DRIVEID 5
#define PD_VERSION 0 #define PD_VERSION 0
#define PD_CYLS 6 #define PD_CYLS 6
#define PD_TRACKS 245 #define PD_TRACKS 245
#define PD_SECTORS 31 #define PD_SECTORS 31
#define PD_BYTES 512 #define PD_BYTES 512
#define PD_LOGICALST 29 #define PD_LOGICALST 29
#define CTC_CAPACITY (PD_CYLS * PD_TRACKS * PD_SECTORS) /* In blocks */ #define CTC_CAPACITY (PD_CYLS * PD_TRACKS * PD_SECTORS) /* In blocks */
struct partition { struct partition {
uint16 id; /* Partition ID */ uint16 id; /* Partition ID */
uint16 flag; /* Permission Flags */ uint16 flag; /* Permission Flags */
uint32 sstart; /* Starting Sector */ uint32 sstart; /* Starting Sector */
uint32 ssize; /* Size in Sectors */ uint32 ssize; /* Size in Sectors */
}; };
struct vtoc { struct vtoc {
uint32 bootinfo[3]; /* n/a */ uint32 bootinfo[3]; /* n/a */
uint32 sanity; /* magic number */ uint32 sanity; /* magic number */
uint32 version; /* layout version */ uint32 version; /* layout version */
uint8 volume[8]; /* volume name */ uint8 volume[8]; /* volume name */
uint16 sectorsz; /* sector size in bytes */ uint16 sectorsz; /* sector size in bytes */
uint16 nparts; /* number of partitions */ uint16 nparts; /* number of partitions */
uint32 reserved[10]; /* free space */ uint32 reserved[10]; /* free space */
struct partition part[VTOC_PART]; /* partition headers */ struct partition part[VTOC_PART]; /* partition headers */
uint32 timestamp[VTOC_PART]; /* partition timestamp */ uint32 timestamp[VTOC_PART]; /* partition timestamp */
}; };
struct pdinfo { struct pdinfo {
uint32 driveid; /* identifies the device type */ uint32 driveid; /* identifies the device type */
uint32 sanity; /* verifies device sanity */ uint32 sanity; /* verifies device sanity */
uint32 version; /* version number */ uint32 version; /* version number */
uint8 serial[12]; /* serial number of the device */ uint8 serial[12]; /* serial number of the device */
uint32 cyls; /* number of cylinders per drive */ uint32 cyls; /* number of cylinders per drive */
uint32 tracks; /* number tracks per cylinder */ uint32 tracks; /* number tracks per cylinder */
uint32 sectors; /* number sectors per track */ uint32 sectors; /* number sectors per track */
uint32 bytes; /* number of bytes per sector */ uint32 bytes; /* number of bytes per sector */
uint32 logicalst; /* sector address of logical sector 0 */ uint32 logicalst; /* sector address of logical sector 0 */
uint32 errlogst; /* sector address of error log area */ uint32 errlogst; /* sector address of error log area */
uint32 errlogsz; /* size in bytes of error log area */ uint32 errlogsz; /* size in bytes of error log area */
uint32 mfgst; /* sector address of mfg. defect info */ uint32 mfgst; /* sector address of mfg. defect info */
uint32 mfgsz; /* size in bytes of mfg. defect info */ uint32 mfgsz; /* size in bytes of mfg. defect info */
uint32 defectst; /* sector address of the defect map */ uint32 defectst; /* sector address of the defect map */
uint32 defectsz; /* size in bytes of defect map */ uint32 defectsz; /* size in bytes of defect map */
uint32 relno; /* number of relocation areas */ uint32 relno; /* number of relocation areas */
uint32 relst; /* sector address of relocation area */ uint32 relst; /* sector address of relocation area */
uint32 relsz; /* size in sectors of relocation area */ uint32 relsz; /* size in sectors of relocation area */
uint32 relnext; /* address of next avail reloc sector */ uint32 relnext; /* address of next avail reloc sector */
}; };
typedef struct { typedef struct {
uint32 time; /* Time used during a tape session (in 25ms chunks) */ uint32 time; /* Time used during a tape session (in 25ms chunks) */
uint32 bytnum; /* Byte number, for streaming mode */ uint32 bytnum; /* Byte number, for streaming mode */
} CTC_STATE; } CTC_STATE;
t_stat ctc_reset(DEVICE *dptr); t_stat ctc_reset(DEVICE *dptr);
t_stat ctc_svc(UNIT *uptr); t_stat ctc_svc(UNIT *uptr);
t_stat ctc_attach(UNIT *uptr, CONST char *cptr); t_stat ctc_attach(UNIT *uptr, CONST char *cptr);
t_stat ctc_detach(UNIT *uptr); t_stat ctc_detach(UNIT *uptr);
void ctc_sysgen(uint8 slot); void ctc_sysgen(uint8 slot);
void ctc_express(uint8 slot); void ctc_express(uint8 slot);
void ctc_full(uint8 slot); void ctc_full(uint8 slot);
#endif /* _3B2_CTC_H_ */ #endif /* _3B2_CTC_H_ */

View file

@ -1,166 +1,166 @@
/* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions /* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_DEFS_H_ #ifndef _3B2_DEFS_H_
#define _3B2_DEFS_H_ #define _3B2_DEFS_H_
#include <setjmp.h> #include <setjmp.h>
#include "sim_defs.h" #include "sim_defs.h"
#if defined(REV3) #if defined(REV3)
#include "3b2_rev3_defs.h" #include "3b2_rev3_defs.h"
#else #else
#include "3b2_rev2_defs.h" #include "3b2_rev2_defs.h"
#endif #endif
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#endif #endif
#if defined(__GNUC__) #if defined(__GNUC__)
#define noret void __attribute__((noreturn)) #define noret void __attribute__((noreturn))
#else #else
#define noret void #define noret void
#endif #endif
#ifndef MAX #ifndef MAX
#define MAX(x, y) ((x) > (y) ? (x) : (y)) #define MAX(x, y) ((x) > (y) ? (x) : (y))
#endif #endif
#ifndef MIN #ifndef MIN
#define MIN(x, y) ((x) < (y) ? (x) : (y)) #define MIN(x, y) ((x) < (y) ? (x) : (y))
#endif #endif
#ifndef UNUSED #ifndef UNUSED
#define UNUSED(x) ((void)((x))) #define UNUSED(x) ((void)((x)))
#endif #endif
#define ATOW(arr, i) \ #define ATOW(arr, i) \
((uint32)(arr)[i + 3] + ((uint32)(arr)[i + 2] << 8) + \ ((uint32)(arr)[i + 3] + ((uint32)(arr)[i + 2] << 8) + \
((uint32)(arr)[i + 1] << 16) + ((uint32)(arr)[i] << 24)) ((uint32)(arr)[i + 1] << 16) + ((uint32)(arr)[i] << 24))
#define ATOH(arr, i) ((uint32)(arr)[i + 1] + ((uint32)(arr)[i] << 8)) #define ATOH(arr, i) ((uint32)(arr)[i + 1] + ((uint32)(arr)[i] << 8))
#define CSRBIT(bit, sc) \ #define CSRBIT(bit, sc) \
{ \ { \
if (sc) { \ if (sc) { \
csr_data |= (bit); \ csr_data |= (bit); \
} else { \ } else { \
csr_data &= ~(bit); \ csr_data &= ~(bit); \
} \ } \
} }
#define PCHAR(c) (((char) (c) >= 0x20 && (char) (c) < 0x7f) ? (char) (c) : '.') #define PCHAR(c) (((char) (c) >= 0x20 && (char) (c) < 0x7f) ? (char) (c) : '.')
#define ROM_SIZE (128 * 1024) #define ROM_SIZE (128 * 1024)
#define POLL_WAIT 70000 #define POLL_WAIT 70000
#define UNIT_V_EXBRK (UNIT_V_UF + 0) #define UNIT_V_EXBRK (UNIT_V_UF + 0)
#define UNIT_V_OPBRK (UNIT_V_UF + 1) #define UNIT_V_OPBRK (UNIT_V_UF + 1)
#define UNIT_EXBRK (1u << UNIT_V_EXBRK) #define UNIT_EXBRK (1u << UNIT_V_EXBRK)
#define UNIT_OPBRK (1u << UNIT_V_OPBRK) #define UNIT_OPBRK (1u << UNIT_V_OPBRK)
#define EX_V_FLAG 1 << 21 #define EX_V_FLAG 1 << 21
#define ROM_BASE 0 #define ROM_BASE 0
#define PHYS_MEM_BASE 0x2000000 #define PHYS_MEM_BASE 0x2000000
#define MSIZ_512K 0x80000 #define MSIZ_512K 0x80000
#define MSIZ_1M 0x100000 #define MSIZ_1M 0x100000
#define MSIZ_2M 0x200000 #define MSIZ_2M 0x200000
#define MSIZ_4M 0x400000 #define MSIZ_4M 0x400000
#define MSIZ_8M 0x800000 #define MSIZ_8M 0x800000
#define MSIZ_16M 0x1000000 #define MSIZ_16M 0x1000000
#define MSIZ_32M 0x2000000 #define MSIZ_32M 0x2000000
#define MSIZ_64M 0x4000000 #define MSIZ_64M 0x4000000
/* Simulator stop codes */ /* Simulator stop codes */
#define STOP_RSRV 1 #define STOP_RSRV 1
#define STOP_IBKPT 2 /* Breakpoint encountered */ #define STOP_IBKPT 2 /* Breakpoint encountered */
#define STOP_OPCODE 3 /* Invalid opcode */ #define STOP_OPCODE 3 /* Invalid opcode */
#define STOP_IRQ 4 /* Interrupt */ #define STOP_IRQ 4 /* Interrupt */
#define STOP_EX 5 /* Exception */ #define STOP_EX 5 /* Exception */
#define STOP_ESTK 6 /* Exception stack too deep */ #define STOP_ESTK 6 /* Exception stack too deep */
#define STOP_MMU 7 /* Unimplemented MMU Feature */ #define STOP_MMU 7 /* Unimplemented MMU Feature */
#define STOP_POWER 8 /* System power-off */ #define STOP_POWER 8 /* System power-off */
#define STOP_LOOP 9 /* Infinite loop stop */ #define STOP_LOOP 9 /* Infinite loop stop */
#define STOP_ERR 10 /* Other error */ #define STOP_ERR 10 /* Other error */
/* Debug flags */ /* Debug flags */
#define READ_MSG 0x0001 #define READ_MSG 0x0001
#define WRITE_MSG 0x0002 #define WRITE_MSG 0x0002
#define DECODE_MSG 0x0004 #define DECODE_MSG 0x0004
#define EXECUTE_MSG 0x0008 #define EXECUTE_MSG 0x0008
#define INIT_MSG 0x0010 #define INIT_MSG 0x0010
#define IRQ_MSG 0x0020 #define IRQ_MSG 0x0020
#define IO_DBG 0x0040 #define IO_DBG 0x0040
#define CIO_DBG 0x0080 #define CIO_DBG 0x0080
#define TRACE_DBG 0x0100 #define TRACE_DBG 0x0100
#define CALL_DBG 0x0200 #define CALL_DBG 0x0200
#define PKT_DBG 0x0400 #define PKT_DBG 0x0400
#define ERR_MSG 0x0800 #define ERR_MSG 0x0800
#define CACHE_DBG 0x1000 #define CACHE_DBG 0x1000
#define DECODE_DBG 0x2000 #define DECODE_DBG 0x2000
#define TIMER_SANITY 0 #define TIMER_SANITY 0
#define TIMER_INTERVAL 1 #define TIMER_INTERVAL 1
#define TIMER_BUS 2 #define TIMER_BUS 2
/* Timers */ /* Timers */
#define TMR_CLK 0 /* Calibrated 100Hz timer */ #define TMR_CLK 0 /* Calibrated 100Hz timer */
/* Global symbols */ /* Global symbols */
extern DEBTAB sys_deb_tab[]; extern DEBTAB sys_deb_tab[];
extern DEVICE contty_dev; extern DEVICE contty_dev;
extern DEVICE cpu_dev; extern DEVICE cpu_dev;
extern DEVICE csr_dev; extern DEVICE csr_dev;
extern DEVICE ctc_dev; extern DEVICE ctc_dev;
extern DEVICE dmac_dev; extern DEVICE dmac_dev;
extern DEVICE id_dev; extern DEVICE id_dev;
extern DEVICE if_dev; extern DEVICE if_dev;
extern DEVICE iu_timer_dev; extern DEVICE iu_timer_dev;
extern DEVICE mau_dev; extern DEVICE mau_dev;
extern DEVICE mmu_dev; extern DEVICE mmu_dev;
extern DEVICE ni_dev; extern DEVICE ni_dev;
extern DEVICE nvram_dev; extern DEVICE nvram_dev;
extern DEVICE ports_dev; extern DEVICE ports_dev;
extern DEVICE timer_dev; extern DEVICE timer_dev;
extern DEVICE tod_dev; extern DEVICE tod_dev;
extern DEVICE tti_dev; extern DEVICE tti_dev;
extern DEVICE tto_dev; extern DEVICE tto_dev;
#if defined(REV3) #if defined(REV3)
extern DEVICE flt_dev; extern DEVICE flt_dev;
extern DEVICE ha_dev; extern DEVICE ha_dev;
#endif /* defined(REV3) */ #endif /* defined(REV3) */
#endif /* _3B2_DEFS_H_ */ #endif /* _3B2_DEFS_H_ */

View file

@ -1,481 +1,481 @@
/* 3b2_dmac.c: AM9517 DMA Controller /* 3b2_dmac.c: AM9517 DMA Controller
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_dmac.h" #include "3b2_dmac.h"
#if defined(REV2) #if defined(REV2)
#include "3b2_id.h" #include "3b2_id.h"
#endif #endif
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_if.h" #include "3b2_if.h"
#include "3b2_iu.h" #include "3b2_iu.h"
#include "3b2_mem.h" #include "3b2_mem.h"
#include "3b2_stddev.h" #include "3b2_stddev.h"
#include "3b2_csr.h" #include "3b2_csr.h"
DMA_STATE dma_state; DMA_STATE dma_state;
UNIT dmac_unit[] = { UNIT dmac_unit[] = {
{ UDATA (NULL, 0, 0), 0, 0 }, { UDATA (NULL, 0, 0), 0, 0 },
{ UDATA (NULL, 0, 0), 0, 1 }, { UDATA (NULL, 0, 0), 0, 1 },
{ UDATA (NULL, 0, 0), 0, 2 }, { UDATA (NULL, 0, 0), 0, 2 },
{ UDATA (NULL, 0, 0), 0, 3 }, { UDATA (NULL, 0, 0), 0, 3 },
{ NULL } { NULL }
}; };
REG dmac_reg[] = { REG dmac_reg[] = {
{ NULL } { NULL }
}; };
DEVICE dmac_dev = { DEVICE dmac_dev = {
"DMAC", dmac_unit, dmac_reg, NULL, "DMAC", dmac_unit, dmac_reg, NULL,
1, 16, 8, 4, 16, 32, 1, 16, 8, 4, 16, 32,
NULL, NULL, &dmac_reset, NULL, NULL, &dmac_reset,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
DEV_DEBUG, 0, sys_deb_tab DEV_DEBUG, 0, sys_deb_tab
}; };
dmac_dma_handler device_dma_handlers[] = { dmac_dma_handler device_dma_handlers[] = {
#if defined(REV2) #if defined(REV2)
{DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma}, {DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma},
#endif #endif
{DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma}, {DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma},
{DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL}, {DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL},
{DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL}, {DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL},
{0, 0, NULL, NULL, NULL } {0, 0, NULL, NULL, NULL }
}; };
uint32 dma_address(uint8 channel, uint32 offset) { uint32 dma_address(uint8 channel, uint32 offset) {
uint32 addr, page; uint32 addr, page;
if (DMA_DECR(channel)) { if (DMA_DECR(channel)) {
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) - offset); addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) - offset);
} else { } else {
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset); addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset);
} }
#if defined (REV3) #if defined (REV3)
page = (uint32)dma_state.channels[channel].page; page = (uint32)dma_state.channels[channel].page;
#else #else
/* In Rev 2, the top bit of the page address is a R/W bit, so /* In Rev 2, the top bit of the page address is a R/W bit, so
we mask it here */ we mask it here */
page = (uint32)dma_state.channels[channel].page & 0x7f; page = (uint32)dma_state.channels[channel].page & 0x7f;
#endif #endif
addr |= page << 16; addr |= page << 16;
return addr; return addr;
} }
t_stat dmac_reset(DEVICE *dptr) t_stat dmac_reset(DEVICE *dptr)
{ {
int i; int i;
memset(&dma_state, 0, sizeof(dma_state)); memset(&dma_state, 0, sizeof(dma_state));
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
dma_state.channels[i].page = 0; dma_state.channels[i].page = 0;
dma_state.channels[i].addr = 0; dma_state.channels[i].addr = 0;
dma_state.channels[i].mode = 0; dma_state.channels[i].mode = 0;
dma_state.channels[i].wcount = 0; dma_state.channels[i].wcount = 0;
dma_state.channels[i].addr_c = 0; dma_state.channels[i].addr_c = 0;
dma_state.channels[i].wcount_c = -1; dma_state.channels[i].wcount_c = -1;
dma_state.channels[i].ptr = 0; dma_state.channels[i].ptr = 0;
} }
return SCPE_OK; return SCPE_OK;
} }
uint32 dmac_read(uint32 pa, size_t size) uint32 dmac_read(uint32 pa, size_t size)
{ {
uint8 reg, base, data; uint8 reg, base, data;
base = (uint8) (pa >> 12); base = (uint8) (pa >> 12);
reg = pa & 0xff; reg = pa & 0xff;
switch (base) { switch (base) {
case DMA_C: case DMA_C:
switch (reg) { switch (reg) {
case 0: /* channel 0 current address reg */ case 0: /* channel 0 current address reg */
data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 0 Addr Reg: %08x\n", "Reading Channel 0 Addr Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 1: /* channel 0 current address reg */ case 1: /* channel 0 current address reg */
data = ((dma_state.channels[0].wcount_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[0].wcount_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 0 Addr Count Reg: %08x\n", "Reading Channel 0 Addr Count Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 2: /* channel 1 current address reg */ case 2: /* channel 1 current address reg */
data = ((dma_state.channels[1].addr_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[1].addr_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 1 Addr Reg: %08x\n", "Reading Channel 1 Addr Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 3: /* channel 1 current address reg */ case 3: /* channel 1 current address reg */
data = ((dma_state.channels[1].wcount_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[1].wcount_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 1 Addr Count Reg: %08x\n", "Reading Channel 1 Addr Count Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 4: /* channel 2 current address reg */ case 4: /* channel 2 current address reg */
data = ((dma_state.channels[2].addr_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[2].addr_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 2 Addr Reg: %08x\n", "Reading Channel 2 Addr Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 5: /* channel 2 current address reg */ case 5: /* channel 2 current address reg */
data = ((dma_state.channels[2].wcount_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[2].wcount_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 2 Addr Count Reg: %08x\n", "Reading Channel 2 Addr Count Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 6: /* channel 3 current address reg */ case 6: /* channel 3 current address reg */
data = ((dma_state.channels[3].addr_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[3].addr_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 3 Addr Reg: %08x\n", "Reading Channel 3 Addr Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 7: /* channel 3 current address reg */ case 7: /* channel 3 current address reg */
data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff; data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading Channel 3 Addr Count Reg: %08x\n", "Reading Channel 3 Addr Count Reg: %08x\n",
data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 8: case 8:
data = dma_state.status; data = dma_state.status;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"Reading DMAC Status %08x\n", "Reading DMAC Status %08x\n",
data); data);
dma_state.status = 0; dma_state.status = 0;
break; break;
default: default:
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"DMAC READ %lu B @ %08x\n", "DMAC READ %lu B @ %08x\n",
size, pa); size, pa);
data = 0; data = 0;
} }
return data; return data;
default: default:
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"[BASE: %08x] DMAC READ %lu B @ %08x\n", "[BASE: %08x] DMAC READ %lu B @ %08x\n",
base, size, pa); base, size, pa);
return 0; return 0;
} }
} }
/* /*
* Program the DMAC * Program the DMAC
*/ */
void dmac_program(uint8 reg, uint8 val) void dmac_program(uint8 reg, uint8 val)
{ {
uint8 channel_id, i, chan_num; uint8 channel_id, i, chan_num;
dma_channel *channel; dma_channel *channel;
#if defined(REV3) #if defined(REV3)
/* TODO: More general DMA interrupt clearing */ /* TODO: More general DMA interrupt clearing */
CPU_CLR_INT(INT_UART_DMA); CPU_CLR_INT(INT_UART_DMA);
CLR_CSR(CSRDMA); CLR_CSR(CSRDMA);
#endif #endif
if (reg < 8) { if (reg < 8) {
switch (reg) { switch (reg) {
case 0: case 0:
case 1: case 1:
chan_num = 0; chan_num = 0;
break; break;
case 2: case 2:
case 3: case 3:
chan_num = 1; chan_num = 1;
break; break;
case 4: case 4:
case 5: case 5:
chan_num = 2; chan_num = 2;
break; break;
case 6: case 6:
case 7: case 7:
chan_num = 3; chan_num = 3;
break; break;
default: default:
chan_num = 0; chan_num = 0;
break; break;
} }
channel = &dma_state.channels[chan_num]; channel = &dma_state.channels[chan_num];
switch (reg & 1) { switch (reg & 1) {
case 0: /* Address */ case 0: /* Address */
channel->addr &= ~(0xff << dma_state.bff * 8); channel->addr &= ~(0xff << dma_state.bff * 8);
channel->addr |= (val & 0xff) << (dma_state.bff * 8); channel->addr |= (val & 0xff) << (dma_state.bff * 8);
channel->addr_c = channel->addr; channel->addr_c = channel->addr;
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Set address channel %d byte %d = %08x\n", "Set address channel %d byte %d = %08x\n",
chan_num, dma_state.bff, channel->addr); chan_num, dma_state.bff, channel->addr);
break; break;
case 1: /* Word Count */ case 1: /* Word Count */
channel->wcount &= ~(0xff << dma_state.bff * 8); channel->wcount &= ~(0xff << dma_state.bff * 8);
channel->wcount |= (val & 0xff) << (dma_state.bff * 8); channel->wcount |= (val & 0xff) << (dma_state.bff * 8);
channel->wcount_c = channel->wcount; channel->wcount_c = channel->wcount;
channel->ptr = 0; channel->ptr = 0;
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Set word count channel %d byte %d = %08x\n", "Set word count channel %d byte %d = %08x\n",
chan_num, dma_state.bff, channel->wcount); chan_num, dma_state.bff, channel->wcount);
break; break;
} }
/* Toggle the byte flip-flop */ /* Toggle the byte flip-flop */
dma_state.bff ^= 1; dma_state.bff ^= 1;
/* Handled. */ /* Handled. */
return; return;
} }
/* If it hasn't been handled, it must be one of the following /* If it hasn't been handled, it must be one of the following
registers. */ registers. */
switch (reg) { switch (reg) {
case 8: /* Command */ case 8: /* Command */
dma_state.command = val; dma_state.command = val;
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Command: val=%02x\n", "Command: val=%02x\n",
val); val);
break; break;
case 9: /* Request */ case 9: /* Request */
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Request set: val=%02x\n", "Request set: val=%02x\n",
val); val);
dma_state.request = val; dma_state.request = val;
break; break;
case 10: /* Write Single Mask Register Bit */ case 10: /* Write Single Mask Register Bit */
channel_id = val & 3; channel_id = val & 3;
/* "Clear or Set" is bit 2 */ /* "Clear or Set" is bit 2 */
if ((val >> 2) & 1) { if ((val >> 2) & 1) {
dma_state.mask |= (1 << channel_id); dma_state.mask |= (1 << channel_id);
} else { } else {
dma_state.mask &= ~(1 << channel_id); dma_state.mask &= ~(1 << channel_id);
/* Set the appropriate DRQ */ /* Set the appropriate DRQ */
/* *dmac_drq_handlers[channel_id].drq = TRUE; */ /* *dmac_drq_handlers[channel_id].drq = TRUE; */
} }
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Write Single Mask Register Bit. channel=%d set/clear=%02x\n", "Write Single Mask Register Bit. channel=%d set/clear=%02x\n",
channel_id, (val >> 2) & 1); channel_id, (val >> 2) & 1);
break; break;
case 11: /* Mode */ case 11: /* Mode */
channel_id = val & 3; channel_id = val & 3;
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Mode Set. channel=%d val=%02x\n", "Mode Set. channel=%d val=%02x\n",
channel_id, val); channel_id, val);
dma_state.channels[channel_id].mode = val; dma_state.channels[channel_id].mode = val;
break; break;
case 12: /* Clear Byte Pointer Flip/Flop */ case 12: /* Clear Byte Pointer Flip/Flop */
dma_state.bff = 0; dma_state.bff = 0;
break; break;
case 13: /* Master Clear */ case 13: /* Master Clear */
dma_state.bff = 0; dma_state.bff = 0;
dma_state.command = 0; dma_state.command = 0;
dma_state.status = 0; dma_state.status = 0;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
dma_state.channels[i].page = 0; dma_state.channels[i].page = 0;
dma_state.channels[i].addr = 0; dma_state.channels[i].addr = 0;
dma_state.channels[i].wcount = 0; dma_state.channels[i].wcount = 0;
dma_state.channels[i].addr_c = 0; dma_state.channels[i].addr_c = 0;
dma_state.channels[i].wcount_c = -1; dma_state.channels[i].wcount_c = -1;
dma_state.channels[i].ptr = 0; dma_state.channels[i].ptr = 0;
} }
break; break;
case 15: /* Write All Mask Register Bits */ case 15: /* Write All Mask Register Bits */
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Write DMAC mask (all bits). Val=%02x\n", "Write DMAC mask (all bits). Val=%02x\n",
val); val);
dma_state.mask = val & 0xf; dma_state.mask = val & 0xf;
break; break;
case 16: /* Clear DMAC Interrupt */ case 16: /* Clear DMAC Interrupt */
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Clear DMA Interrupt in DMAC. val=%02x\n", "Clear DMA Interrupt in DMAC. val=%02x\n",
val); val);
break; break;
default: default:
sim_debug(WRITE_MSG, &dmac_dev, sim_debug(WRITE_MSG, &dmac_dev,
"Unhandled DMAC write. reg=%x val=%02x\n", "Unhandled DMAC write. reg=%x val=%02x\n",
reg, val); reg, val);
break; break;
} }
} }
void dmac_page_update(uint8 base, uint8 reg, uint8 val) void dmac_page_update(uint8 base, uint8 reg, uint8 val)
{ {
uint8 shift = 0; uint8 shift = 0;
/* Sanity check */ /* Sanity check */
if (reg > 3) { if (reg > 3) {
return; return;
} }
#if defined(REV2) #if defined(REV2)
/* In Rev2 systems, the actual register is a 32-bit, /* In Rev2 systems, the actual register is a 32-bit,
byte-addressed register, so that address 4x000 is the highest byte-addressed register, so that address 4x000 is the highest
byte, 4x003 is the lowest byte. */ byte, 4x003 is the lowest byte. */
shift = -(reg - 3) * 8; shift = -(reg - 3) * 8;
#endif #endif
switch (base) { switch (base) {
#if defined (REV2) #if defined (REV2)
case DMA_ID: case DMA_ID:
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val); sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val);
dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift); dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift);
dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift); dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift);
break; break;
#endif #endif
case DMA_IF: case DMA_IF:
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 1 = %x\n", val); sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 1 = %x\n", val);
dma_state.channels[DMA_IF_CHAN].page &= ~(0xff << shift); dma_state.channels[DMA_IF_CHAN].page &= ~(0xff << shift);
dma_state.channels[DMA_IF_CHAN].page |= ((uint16)val << shift); dma_state.channels[DMA_IF_CHAN].page |= ((uint16)val << shift);
break; break;
case DMA_IUA: case DMA_IUA:
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val); sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val);
dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift); dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift);
dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift); dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift);
break; break;
case DMA_IUB: case DMA_IUB:
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val); sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val);
dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift); dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift);
dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift); dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift);
break; break;
} }
} }
void dmac_write(uint32 pa, uint32 val, size_t size) void dmac_write(uint32 pa, uint32 val, size_t size)
{ {
uint8 reg, base; uint8 reg, base;
base = (uint8) (pa >> 12); base = (uint8) (pa >> 12);
reg = pa & 0xff; reg = pa & 0xff;
switch (base) { switch (base) {
case DMA_C: case DMA_C:
dmac_program(reg, (uint8) val); dmac_program(reg, (uint8) val);
break; break;
#if defined (REV2) #if defined (REV2)
case DMA_ID: case DMA_ID:
#endif #endif
case DMA_IUA: case DMA_IUA:
case DMA_IUB: case DMA_IUB:
case DMA_IF: case DMA_IF:
dmac_page_update(base, reg, (uint8) val); dmac_page_update(base, reg, (uint8) val);
break; break;
} }
} }
void dmac_generic_dma(uint8 channel, uint32 service_address) void dmac_generic_dma(uint8 channel, uint32 service_address)
{ {
uint8 data; uint8 data;
int32 i; int32 i;
uint32 addr; uint32 addr;
dma_channel *chan = &dma_state.channels[channel]; dma_channel *chan = &dma_state.channels[channel];
i = chan->wcount_c; i = chan->wcount_c;
/* TODO: This assumes every transfer is a block mode, which is not /* TODO: This assumes every transfer is a block mode, which is not
guaranteed to be valid, but is likely safe? */ guaranteed to be valid, but is likely safe? */
switch (DMA_XFER(channel)) { switch (DMA_XFER(channel)) {
case DMA_XFER_VERIFY: case DMA_XFER_VERIFY:
sim_debug(EXECUTE_MSG, &dmac_dev, sim_debug(EXECUTE_MSG, &dmac_dev,
"[dmac_generic_dma channel=%d] unhandled VERIFY request.\n", "[dmac_generic_dma channel=%d] unhandled VERIFY request.\n",
channel); channel);
break; break;
case DMA_XFER_WRITE: case DMA_XFER_WRITE:
sim_debug(EXECUTE_MSG, &dmac_dev, sim_debug(EXECUTE_MSG, &dmac_dev,
"[dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n", "[dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n",
channel, channel,
chan->wcount + 1, chan->wcount + 1,
dma_address(channel, 0), dma_address(channel, 0),
service_address, service_address,
dma_state.channels[channel].page, dma_state.channels[channel].page,
dma_state.channels[channel].addr); dma_state.channels[channel].addr);
for (; i >= 0; i--) { for (; i >= 0; i--) {
chan->wcount_c--; chan->wcount_c--;
addr = dma_address(channel, chan->ptr++); addr = dma_address(channel, chan->ptr++);
chan->addr_c = addr; chan->addr_c = addr;
data = pread_b(service_address, BUS_PER); data = pread_b(service_address, BUS_PER);
write_b(addr, data, BUS_PER); write_b(addr, data, BUS_PER);
} }
break; break;
case DMA_XFER_READ: case DMA_XFER_READ:
sim_debug(EXECUTE_MSG, &dmac_dev, sim_debug(EXECUTE_MSG, &dmac_dev,
"[dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n", "[dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n",
channel, channel,
chan->wcount + 1, chan->wcount + 1,
dma_address(channel, 0), dma_address(channel, 0),
service_address); service_address);
for (; i >= 0; i--) { for (; i >= 0; i--) {
chan->wcount_c = i; chan->wcount_c = i;
addr = dma_address(channel, chan->ptr++); addr = dma_address(channel, chan->ptr++);
chan->addr_c = addr; chan->addr_c = addr;
data = pread_b(addr, BUS_PER); data = pread_b(addr, BUS_PER);
write_b(service_address, data, BUS_PER); write_b(service_address, data, BUS_PER);
} }
break; break;
} }
/* End of Process must set the channel's mask bit */ /* End of Process must set the channel's mask bit */
dma_state.mask |= (1 << channel); dma_state.mask |= (1 << channel);
dma_state.status |= (1 << channel); dma_state.status |= (1 << channel);
} }
/* /*
* Service pending DRQs * Service pending DRQs
*/ */
void dmac_service_drqs() void dmac_service_drqs()
{ {
volatile dmac_dma_handler *h; volatile dmac_dma_handler *h;
for (h = &device_dma_handlers[0]; h->drq != NULL; h++) { for (h = &device_dma_handlers[0]; h->drq != NULL; h++) {
/* Only trigger if the channel has a DRQ set and its channel's /* Only trigger if the channel has a DRQ set and its channel's
mask bit is 0 */ mask bit is 0 */
if (*h->drq && ((dma_state.mask >> h->channel) & 0x1) == 0) { if (*h->drq && ((dma_state.mask >> h->channel) & 0x1) == 0) {
h->dma_handler(h->channel, h->service_address); h->dma_handler(h->channel, h->service_address);
/* Each handler is responsible for clearing its own DRQ line! */ /* Each handler is responsible for clearing its own DRQ line! */
if (h->after_dma_callback != NULL) { if (h->after_dma_callback != NULL) {
h->after_dma_callback(); h->after_dma_callback();
} }
} }
} }
} }

View file

@ -1,89 +1,89 @@
/* 3b2_dmac.h: AM9517 DMA Controller /* 3b2_dmac.h: AM9517 DMA Controller
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_DMAC_H_ #ifndef _3B2_DMAC_H_
#define _3B2_DMAC_H_ #define _3B2_DMAC_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define DMA_XFER_VERIFY 0 #define DMA_XFER_VERIFY 0
#define DMA_XFER_WRITE 1 /* Write to memory from device */ #define DMA_XFER_WRITE 1 /* Write to memory from device */
#define DMA_XFER_READ 2 /* Read from memory to device */ #define DMA_XFER_READ 2 /* Read from memory to device */
#define DMA_IF_READ (IFBASE + IF_DATA_REG) #define DMA_IF_READ (IFBASE + IF_DATA_REG)
#define DMA_MODE(C) ((dma_state.channels[(C)].mode >> 6) & 3) #define DMA_MODE(C) ((dma_state.channels[(C)].mode >> 6) & 3)
#define DMA_DECR(C) ((dma_state.channels[(C)].mode >> 5) & 1) #define DMA_DECR(C) ((dma_state.channels[(C)].mode >> 5) & 1)
#define DMA_AUTOINIT(C) ((dma_state.channels[(C)].mode >> 4) & 1) #define DMA_AUTOINIT(C) ((dma_state.channels[(C)].mode >> 4) & 1)
#define DMA_XFER(C) ((dma_state.channels[(C)].mode >> 2) & 3) #define DMA_XFER(C) ((dma_state.channels[(C)].mode >> 2) & 3)
typedef struct { typedef struct {
uint8 mode; /* Channel mode */ uint8 mode; /* Channel mode */
uint16 page; /* Memory page */ uint16 page; /* Memory page */
uint16 addr; /* Original addr */ uint16 addr; /* Original addr */
uint16 wcount; /* Original wcount */ uint16 wcount; /* Original wcount */
uint16 addr_c; /* Current addr */ uint16 addr_c; /* Current addr */
int32 wcount_c; /* Current word-count */ int32 wcount_c; /* Current word-count */
uint16 ptr; /* Pointer into memory */ uint16 ptr; /* Pointer into memory */
} dma_channel; } dma_channel;
typedef struct { typedef struct {
/* Byte (high/low) flip-flop */ /* Byte (high/low) flip-flop */
uint8 bff; uint8 bff;
/* Address and count registers for channels 0-3 */ /* Address and count registers for channels 0-3 */
dma_channel channels[4]; dma_channel channels[4];
/* DMAC programmable registers */ /* DMAC programmable registers */
uint8 command; uint8 command;
uint8 request; uint8 request;
uint8 mask; uint8 mask;
uint8 status; uint8 status;
} DMA_STATE; } DMA_STATE;
typedef struct { typedef struct {
uint8 channel; uint8 channel;
uint32 service_address; uint32 service_address;
t_bool *drq; t_bool *drq;
void (*dma_handler)(uint8 channel, uint32 service_address); void (*dma_handler)(uint8 channel, uint32 service_address);
void (*after_dma_callback)(); void (*after_dma_callback)();
} dmac_dma_handler; } dmac_dma_handler;
/* DMAC */ /* DMAC */
t_stat dmac_reset(DEVICE *dptr); t_stat dmac_reset(DEVICE *dptr);
uint32 dmac_read(uint32 pa, size_t size); uint32 dmac_read(uint32 pa, size_t size);
void dmac_write(uint32 pa, uint32 val, size_t size); void dmac_write(uint32 pa, uint32 val, size_t size);
void dmac_service_drqs(); void dmac_service_drqs();
void dmac_generic_dma(uint8 channel, uint32 service_address); void dmac_generic_dma(uint8 channel, uint32 service_address);
uint32 dma_address(uint8 channel, uint32 offset); uint32 dma_address(uint8 channel, uint32 offset);
extern DMA_STATE dma_state; extern DMA_STATE dma_state;
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,178 +1,178 @@
/* 3b2_id.h: uPD7261 Integrated Disk Controller /* 3b2_id.h: uPD7261 Integrated Disk Controller
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef __3B2_ID_H__ #ifndef __3B2_ID_H__
#define __3B2_ID_H__ #define __3B2_ID_H__
#include "3b2_defs.h" #include "3b2_defs.h"
#define ID0 0 #define ID0 0
#define ID1 1 #define ID1 1
#define ID_CTLR 2 #define ID_CTLR 2
/* Command Codes (bits 3-7 of command byte) */ /* Command Codes (bits 3-7 of command byte) */
#define ID_CMD_AUX 0x00 /* Auxiliary Command */ #define ID_CMD_AUX 0x00 /* Auxiliary Command */
#define ID_CMD_SIS 0x01 /* Sense int. status */ #define ID_CMD_SIS 0x01 /* Sense int. status */
#define ID_CMD_SPEC 0x02 /* Specify */ #define ID_CMD_SPEC 0x02 /* Specify */
#define ID_CMD_SUS 0x03 /* Sense unit status */ #define ID_CMD_SUS 0x03 /* Sense unit status */
#define ID_CMD_DERR 0x04 /* Detect Error */ #define ID_CMD_DERR 0x04 /* Detect Error */
#define ID_CMD_RECAL 0x05 /* Recalibrate */ #define ID_CMD_RECAL 0x05 /* Recalibrate */
#define ID_CMD_SEEK 0x06 /* Seek */ #define ID_CMD_SEEK 0x06 /* Seek */
#define ID_CMD_FMT 0x07 /* Format */ #define ID_CMD_FMT 0x07 /* Format */
#define ID_CMD_VID 0x08 /* Verify ID */ #define ID_CMD_VID 0x08 /* Verify ID */
#define ID_CMD_RID 0x09 /* Read ID */ #define ID_CMD_RID 0x09 /* Read ID */
#define ID_CMD_RDIAG 0x0A /* Read Diagnostic */ #define ID_CMD_RDIAG 0x0A /* Read Diagnostic */
#define ID_CMD_RDATA 0x0B /* Read Data */ #define ID_CMD_RDATA 0x0B /* Read Data */
#define ID_CMD_CHECK 0x0C /* Check */ #define ID_CMD_CHECK 0x0C /* Check */
#define ID_CMD_SCAN 0x0D /* Scan */ #define ID_CMD_SCAN 0x0D /* Scan */
#define ID_CMD_VDATA 0x0E /* Verify Data */ #define ID_CMD_VDATA 0x0E /* Verify Data */
#define ID_CMD_WDATA 0x0F /* Write Data */ #define ID_CMD_WDATA 0x0F /* Write Data */
#define ID_AUX_RST 0x01 #define ID_AUX_RST 0x01
#define ID_AUX_CLB 0x02 #define ID_AUX_CLB 0x02
#define ID_AUX_HSRQ 0x04 #define ID_AUX_HSRQ 0x04
#define ID_AUX_CLCE 0x08 #define ID_AUX_CLCE 0x08
#define ID_STAT_DRQ 0x01 #define ID_STAT_DRQ 0x01
#define ID_STAT_NCI 0x02 #define ID_STAT_NCI 0x02
#define ID_STAT_IER 0x04 #define ID_STAT_IER 0x04
#define ID_STAT_RRQ 0x08 #define ID_STAT_RRQ 0x08
#define ID_STAT_SRQ 0x10 #define ID_STAT_SRQ 0x10
#define ID_STAT_CEL 0x20 #define ID_STAT_CEL 0x20
#define ID_STAT_CEH 0x40 #define ID_STAT_CEH 0x40
#define ID_STAT_CB 0x80 #define ID_STAT_CB 0x80
#define ID_IST_SEN 0x80 /* Seek End */ #define ID_IST_SEN 0x80 /* Seek End */
#define ID_IST_RC 0x40 /* Ready Change */ #define ID_IST_RC 0x40 /* Ready Change */
#define ID_IST_SER 0x20 /* Seek Error */ #define ID_IST_SER 0x20 /* Seek Error */
#define ID_IST_EQC 0x10 /* Equipment Check */ #define ID_IST_EQC 0x10 /* Equipment Check */
#define ID_IST_NR 0x08 /* Not Ready */ #define ID_IST_NR 0x08 /* Not Ready */
#define ID_UST_DSEL 0x10 /* Drive Selected */ #define ID_UST_DSEL 0x10 /* Drive Selected */
#define ID_UST_SCL 0x08 /* Seek Complete */ #define ID_UST_SCL 0x08 /* Seek Complete */
#define ID_UST_TK0 0x04 /* Track 0 */ #define ID_UST_TK0 0x04 /* Track 0 */
#define ID_UST_RDY 0x02 /* Ready */ #define ID_UST_RDY 0x02 /* Ready */
#define ID_UST_WFL 0x01 /* Write Fault */ #define ID_UST_WFL 0x01 /* Write Fault */
#define ID_EST_ENC 0x80 #define ID_EST_ENC 0x80
#define ID_EST_OVR 0x40 #define ID_EST_OVR 0x40
#define ID_EST_DER 0x20 #define ID_EST_DER 0x20
#define ID_EST_EQC 0x10 #define ID_EST_EQC 0x10
#define ID_EST_NR 0x08 #define ID_EST_NR 0x08
#define ID_EST_ND 0x04 #define ID_EST_ND 0x04
#define ID_EST_NWR 0x02 #define ID_EST_NWR 0x02
#define ID_EST_MAM 0x01 #define ID_EST_MAM 0x01
#define ID_DTLH_POLL 0x10 #define ID_DTLH_POLL 0x10
#define ID_SEEK_NONE -1 #define ID_SEEK_NONE -1
#define ID_SEEK_0 0 #define ID_SEEK_0 0
#define ID_SEEK_1 1 #define ID_SEEK_1 1
/* Drive Geometries */ /* Drive Geometries */
/* Common across all drive types */ /* Common across all drive types */
#define ID_SEC_SIZE 512 #define ID_SEC_SIZE 512
#define ID_SEC_CNT 18 #define ID_SEC_CNT 18
#define ID_CYL_SIZE ID_SEC_SIZE * ID_SEC_CNT #define ID_CYL_SIZE ID_SEC_SIZE * ID_SEC_CNT
/* Specific to each drive type */ /* Specific to each drive type */
#define ID_MAX_DTYPE 3 #define ID_MAX_DTYPE 3
#define ID_HD30_DTYPE 0 #define ID_HD30_DTYPE 0
#define ID_HD30_CYL 697 #define ID_HD30_CYL 697
#define ID_HD30_HEADS 5 #define ID_HD30_HEADS 5
#define ID_HD30_LBN 62730 #define ID_HD30_LBN 62730
#define ID_HD72_DTYPE 1 #define ID_HD72_DTYPE 1
#define ID_HD72_CYL 925 #define ID_HD72_CYL 925
#define ID_HD72_HEADS 9 #define ID_HD72_HEADS 9
#define ID_HD72_LBN 149850 #define ID_HD72_LBN 149850
#define ID_HD72C_DTYPE 2 #define ID_HD72C_DTYPE 2
#define ID_HD72C_CYL 754 #define ID_HD72C_CYL 754
#define ID_HD72C_HEADS 11 #define ID_HD72C_HEADS 11
#define ID_HD72C_LBN 149292 #define ID_HD72C_LBN 149292
/* The HD135 is actually just an HD161 with only 1024 cylinders /* The HD135 is actually just an HD161 with only 1024 cylinders
* formatted. This is a software limitation, not hardware. */ * formatted. This is a software limitation, not hardware. */
#define ID_HD135_DTYPE 3 #define ID_HD135_DTYPE 3
#define ID_HD135_CYL 1224 #define ID_HD135_CYL 1224
#define ID_HD135_HEADS 15 #define ID_HD135_HEADS 15
#define ID_HD135_LBN 330480 #define ID_HD135_LBN 330480
#define ID_HD161_DTYPE 3 #define ID_HD161_DTYPE 3
#define ID_HD161_CYL 1224 #define ID_HD161_CYL 1224
#define ID_HD161_HEADS 15 #define ID_HD161_HEADS 15
#define ID_HD161_LBN 330480 #define ID_HD161_LBN 330480
#define ID_V_DTYPE (DKUF_V_UF + 0) #define ID_V_DTYPE (DKUF_V_UF + 0)
#define ID_M_DTYPE 3 #define ID_M_DTYPE 3
#define ID_DTYPE (ID_M_DTYPE << ID_V_DTYPE) #define ID_DTYPE (ID_M_DTYPE << ID_V_DTYPE)
#define ID_V_AUTOSIZE (ID_V_DTYPE + 2) #define ID_V_AUTOSIZE (ID_V_DTYPE + 2)
#define ID_AUTOSIZE (1 << ID_V_AUTOSIZE) #define ID_AUTOSIZE (1 << ID_V_AUTOSIZE)
#define ID_GET_DTYPE(x) (((x) >> ID_V_DTYPE) & ID_M_DTYPE) #define ID_GET_DTYPE(x) (((x) >> ID_V_DTYPE) & ID_M_DTYPE)
#define ID_DRV(d) { ID_##d##_HEADS, ID_##d##_LBN, #d } #define ID_DRV(d) { ID_##d##_HEADS, ID_##d##_LBN, #d }
#define ID_DSK_SIZE(d) ID_##d##_LBN #define ID_DSK_SIZE(d) ID_##d##_LBN
/* Unit, Register, Device descriptions */ /* Unit, Register, Device descriptions */
#define ID_FIFO_LEN 8 #define ID_FIFO_LEN 8
#define ID_IDFIELD_LEN 4 #define ID_IDFIELD_LEN 4
#define ID_NUM_UNITS 2 #define ID_NUM_UNITS 2
#define DMA_ID_SVC IDBASE+ID_DATA_REG #define DMA_ID_SVC IDBASE+ID_DATA_REG
#define CMD_NUM ((id_cmd >> 4) & 0xf) #define CMD_NUM ((id_cmd >> 4) & 0xf)
/* Function prototypes */ /* Function prototypes */
t_stat id_ctlr_svc(UNIT *uptr); t_stat id_ctlr_svc(UNIT *uptr);
t_stat id_unit_svc(UNIT *uptr); t_stat id_unit_svc(UNIT *uptr);
t_stat id_reset(DEVICE *dptr); t_stat id_reset(DEVICE *dptr);
t_stat id_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat id_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat id_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat id_show_type (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat id_attach(UNIT *uptr, CONST char *cptr); t_stat id_attach(UNIT *uptr, CONST char *cptr);
t_stat id_detach(UNIT *uptr); t_stat id_detach(UNIT *uptr);
uint32 id_read(uint32 pa, size_t size); uint32 id_read(uint32 pa, size_t size);
void id_write(uint32 pa, uint32 val, size_t size); void id_write(uint32 pa, uint32 val, size_t size);
CONST char *id_description(DEVICE *dptr); CONST char *id_description(DEVICE *dptr);
t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
void id_handle_data(uint8 val); void id_handle_data(uint8 val);
void id_handle_command(uint8 val); void id_handle_command(uint8 val);
void id_after_dma(); void id_after_dma();
extern t_bool id_drq; extern t_bool id_drq;
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,131 +1,131 @@
/* 3b2_if.h: TMS2797 Integrated Floppy Controller /* 3b2_if.h: TMS2797 Integrated Floppy Controller
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef __3B2_IF_H__ #ifndef __3B2_IF_H__
#define __3B2_IF_H__ #define __3B2_IF_H__
#include "3b2_defs.h" #include "3b2_defs.h"
typedef struct { typedef struct {
uint8 data; uint8 data;
uint8 cmd; uint8 cmd;
uint8 cmd_type; uint8 cmd_type;
uint8 status; uint8 status;
uint8 track; uint8 track;
uint8 sector; uint8 sector;
uint8 side; uint8 side;
uint8 read_addr_ptr; uint8 read_addr_ptr;
int8 step_dir; int8 step_dir;
t_bool drq; t_bool drq;
#if defined(REV3) #if defined(REV3)
uint8 csr; uint8 csr;
#endif #endif
} IF_STATE; } IF_STATE;
/* Status Bits */ /* Status Bits */
#define IF_BUSY 0x01 #define IF_BUSY 0x01
#define IF_DRQ 0x02 #define IF_DRQ 0x02
#define IF_INDEX 0x02 #define IF_INDEX 0x02
#define IF_TK_0 0x04 #define IF_TK_0 0x04
#define IF_LOST_DATA 0x04 #define IF_LOST_DATA 0x04
#define IF_CRC_ERR 0x08 #define IF_CRC_ERR 0x08
#define IF_SEEK_ERR 0x10 #define IF_SEEK_ERR 0x10
#define IF_RNF 0x10 #define IF_RNF 0x10
#define IF_HEAD_LOADED 0x20 #define IF_HEAD_LOADED 0x20
#define IF_RECORD_TYPE 0x20 #define IF_RECORD_TYPE 0x20
#define IF_WP 0x40 #define IF_WP 0x40
#define IF_NRDY 0x80 #define IF_NRDY 0x80
/* Type I Commands */ /* Type I Commands */
#define IF_RESTORE 0x00 #define IF_RESTORE 0x00
#define IF_SEEK 0x10 #define IF_SEEK 0x10
#define IF_STEP 0x20 #define IF_STEP 0x20
#define IF_STEP_T 0x30 #define IF_STEP_T 0x30
#define IF_STEP_IN 0x40 #define IF_STEP_IN 0x40
#define IF_STEP_IN_T 0x50 #define IF_STEP_IN_T 0x50
#define IF_STEP_OUT 0x60 #define IF_STEP_OUT 0x60
#define IF_STEP_OUT_T 0x70 #define IF_STEP_OUT_T 0x70
/* Type II Commands */ /* Type II Commands */
#define IF_READ_SEC 0x80 #define IF_READ_SEC 0x80
#define IF_READ_SEC_M 0x90 #define IF_READ_SEC_M 0x90
#define IF_WRITE_SEC 0xA0 #define IF_WRITE_SEC 0xA0
#define IF_WRITE_SEC_M 0xB0 #define IF_WRITE_SEC_M 0xB0
/* Type III Commands */ /* Type III Commands */
#define IF_READ_ADDR 0xC0 #define IF_READ_ADDR 0xC0
#define IF_READ_TRACK 0xE0 #define IF_READ_TRACK 0xE0
#define IF_WRITE_TRACK 0xF0 #define IF_WRITE_TRACK 0xF0
/* Type IV Command */ /* Type IV Command */
#define IF_FORCE_INT 0xD0 #define IF_FORCE_INT 0xD0
/* Command flags */ /* Command flags */
#define IF_C_FLAG 0x02 #define IF_C_FLAG 0x02
#define IF_V_FLAG 0x04 #define IF_V_FLAG 0x04
#define IF_E_FLAG 0x04 #define IF_E_FLAG 0x04
#define IF_U_FLAG 0x02 #define IF_U_FLAG 0x02
#define IF_H_FLAG 0x08 #define IF_H_FLAG 0x08
#define IF_S_FLAG 0x10 #define IF_S_FLAG 0x10
/* Constants */ /* Constants */
#define IF_SIDES 2 #define IF_SIDES 2
#define IF_SEC_COUNT 9 #define IF_SEC_COUNT 9
#define IF_SEC_SIZE 512 #define IF_SEC_SIZE 512
#define IF_TRACK_SIZE 4608 #define IF_TRACK_SIZE 4608
#define IF_TRACK_COUNT 80 #define IF_TRACK_COUNT 80
#define IF_STEP_IN_DIR 1 #define IF_STEP_IN_DIR 1
#define IF_STEP_OUT_DIR -1 #define IF_STEP_OUT_DIR -1
#define IF_DSK_SIZE_SECS (IF_SIDES * IF_TRACK_COUNT * IF_SEC_COUNT) #define IF_DSK_SIZE_SECS (IF_SIDES * IF_TRACK_COUNT * IF_SEC_COUNT)
/* Function prototypes */ /* Function prototypes */
t_stat if_svc(UNIT *uptr); t_stat if_svc(UNIT *uptr);
t_stat if_reset(DEVICE *dptr); t_stat if_reset(DEVICE *dptr);
t_stat if_attach(UNIT *uptr, CONST char *cptr); t_stat if_attach(UNIT *uptr, CONST char *cptr);
t_stat if_detach(UNIT *uptr); t_stat if_detach(UNIT *uptr);
uint32 if_read(uint32 pa, size_t size); uint32 if_read(uint32 pa, size_t size);
void if_write(uint32 pa, uint32 val, size_t size); void if_write(uint32 pa, uint32 val, size_t size);
#if defined(REV3) #if defined(REV3)
uint32 if_csr_read(uint32 pa, size_t size); uint32 if_csr_read(uint32 pa, size_t size);
void if_csr_write(uint32 pa, uint32 val, size_t size); void if_csr_write(uint32 pa, uint32 val, size_t size);
#endif #endif
void if_handle_command(); void if_handle_command();
void if_after_dma(); void if_after_dma();
CONST char *if_description(DEVICE *dptr); CONST char *if_description(DEVICE *dptr);
t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
extern IF_STATE if_state; extern IF_STATE if_state;
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,271 +1,271 @@
/* 3b2_io.h: Common I/O (CIO) Feature Card Support /* 3b2_io.h: Common I/O (CIO) Feature Card Support
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
/* Reference Documentation /* Reference Documentation
* ======================= * =======================
* *
* All communication between the system board and feature cards is * All communication between the system board and feature cards is
* done through in-memory queues, and causing interrupts in the * done through in-memory queues, and causing interrupts in the
* feature card by accessing the Control or ID/VEC memory-mapped IO * feature card by accessing the Control or ID/VEC memory-mapped IO
* addresses. The structure of these queues is defined below in * addresses. The structure of these queues is defined below in
* tables. * tables.
* *
* Sysgen Block * Sysgen Block
* ------------ * ------------
* *
* Pointed to by address at 0x2000000 after an INT0/INT1 combo * Pointed to by address at 0x2000000 after an INT0/INT1 combo
* *
* *
* | Address | Size | Contents | * | Address | Size | Contents |
* +---------------+------+-----------------------------------------+ * +---------------+------+-----------------------------------------+
* | SYSGEN_P | 4 | Address of request queue | * | SYSGEN_P | 4 | Address of request queue |
* | SYSGEN_P + 4 | 4 | Address of completion queue | * | SYSGEN_P + 4 | 4 | Address of completion queue |
* | SYSGEN_P + 8 | 1 | Number of entries in request queue | * | SYSGEN_P + 8 | 1 | Number of entries in request queue |
* | SYSGEN_P + 9 | 1 | Number of entries in completion queue | * | SYSGEN_P + 9 | 1 | Number of entries in completion queue |
* | SYSGEN_P + 10 | 1 | Interrupt Vector number | * | SYSGEN_P + 10 | 1 | Interrupt Vector number |
* | SYSGEN_P + 11 | 1 | Number of request queues | * | SYSGEN_P + 11 | 1 | Number of request queues |
* *
* *
* Queue Entry * Queue Entry
* ----------- * -----------
* *
* Each queue has one Express Entry, and n regular entries. * Each queue has one Express Entry, and n regular entries.
* *
* | Address | Size | Contents | * | Address | Size | Contents |
* +---------------+------+-----------------------------------------+ * +---------------+------+-----------------------------------------+
* | ENTRY_P | 2 | Byte Count | * | ENTRY_P | 2 | Byte Count |
* | ENTRY_P + 2 | 1 | Subdevice [1] | * | ENTRY_P + 2 | 1 | Subdevice [1] |
* | ENTRY_P + 3 | 1 | Opcode | * | ENTRY_P + 3 | 1 | Opcode |
* | ENTRY_P + 4 | 4 | Address / Data | * | ENTRY_P + 4 | 4 | Address / Data |
* | ENTRY_P + 8 | 4 | Application Specific Data | * | ENTRY_P + 8 | 4 | Application Specific Data |
* *
* [1] The "Subdevice" entry is further divided into a bitset: * [1] The "Subdevice" entry is further divided into a bitset:
* Bit 7: Command (1) / Status (0) * Bit 7: Command (1) / Status (0)
* Bit 6: Sequence Bit * Bit 6: Sequence Bit
* Bit 5-1: Subdevice * Bit 5-1: Subdevice
* *
* *
* Queue * Queue
* ----- * -----
* *
* The Queue structures (one for request, one for completion) hold: * The Queue structures (one for request, one for completion) hold:
* - An express entry * - An express entry
* *
* And then one or more queues, each queue consiting of * And then one or more queues, each queue consiting of
* - A set of pointers for load and unload from the queue * - A set of pointers for load and unload from the queue
* - One or more Queue Entries * - One or more Queue Entries
* *
* | Address | Size | Contents | * | Address | Size | Contents |
* +---------------+------+-----------------------------------------+ * +---------------+------+-----------------------------------------+
* | QUEUE_P | 12 | Express Queue Entry [1] | * | QUEUE_P | 12 | Express Queue Entry [1] |
* +---------------+------+-----------------------------------------+ * +---------------+------+-----------------------------------------+
* | QUEUE_P + 12 | 2 | Load Pointer for Queue 0 | * | QUEUE_P + 12 | 2 | Load Pointer for Queue 0 |
* | QUEUE_P + 14 | 2 | Unload Pointer for Queue 0 | * | QUEUE_P + 14 | 2 | Unload Pointer for Queue 0 |
* | QUEUE_P + 16 | 12 | Queue 0 Entry 0 [1] | * | QUEUE_P + 16 | 12 | Queue 0 Entry 0 [1] |
* | QUEUE_P + 28 | 12 | Queue 0 Entry 1 [1] | * | QUEUE_P + 28 | 12 | Queue 0 Entry 1 [1] |
* | ... | ... | ... | * | ... | ... | ... |
* +---------------+------+-----------------------------------------+ * +---------------+------+-----------------------------------------+
* | QUEUE_P + n | 2 | Load Pointer for Queue 1 | * | QUEUE_P + n | 2 | Load Pointer for Queue 1 |
* | QUEUE_P + n | 2 | Unload Pointer for Queue 1 | * | QUEUE_P + n | 2 | Unload Pointer for Queue 1 |
* | QUEUE_P + n | 12 | Queue 1 Entry 0 [1] | * | QUEUE_P + n | 12 | Queue 1 Entry 0 [1] |
* | QUEUE_P + n | 12 | Queue 1 Entry 1 [1] | * | QUEUE_P + n | 12 | Queue 1 Entry 1 [1] |
* | ... | ... | ... | * | ... | ... | ... |
* *
* [1] See Queue Entry above * [1] See Queue Entry above
* *
* NB: There are multiple Request queues, usually one per subdevice, * NB: There are multiple Request queues, usually one per subdevice,
* and EACH Request queue starts with a Load Pointer, an Unload * and EACH Request queue starts with a Load Pointer, an Unload
* Pointer, and then 'n' Queue Entries. * Pointer, and then 'n' Queue Entries.
* *
*/ */
#ifndef _3B2_IO_H_ #ifndef _3B2_IO_H_
#define _3B2_IO_H_ #define _3B2_IO_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define CRC_POLYNOMIAL 0xEDB88320 #define CRC_POLYNOMIAL 0xEDB88320
#define CIO_SLOTS 12 #define CIO_SLOTS 12
/* IO area */ /* IO area */
#define IO_BOTTOM 0x40000 #define IO_BOTTOM 0x40000
#define IO_TOP 0x50000 #define IO_TOP 0x50000
#if defined(REV3) #if defined(REV3)
#define UBUS_BOTTOM 0x1c00000 #define UBUS_BOTTOM 0x1c00000
#define UBUS_TOP 0x2000000 #define UBUS_TOP 0x2000000
#endif #endif
/* CIO area */ /* CIO area */
#define CIO_BOTTOM 0x200000 #define CIO_BOTTOM 0x200000
#if defined(REV3) #if defined(REV3)
#define CIO_TOP 0x1a00000 #define CIO_TOP 0x1a00000
#else #else
#define CIO_TOP 0x2000000 #define CIO_TOP 0x2000000
#endif #endif
#define IOF_ID 0 #define IOF_ID 0
#define IOF_VEC 1 #define IOF_VEC 1
#define IOF_CTRL 3 #define IOF_CTRL 3
#define IOF_STAT 5 #define IOF_STAT 5
#define SYSGEN_PTR PHYS_MEM_BASE #define SYSGEN_PTR PHYS_MEM_BASE
/* CIO opcodes */ /* CIO opcodes */
#define CIO_DLM 1 #define CIO_DLM 1
#define CIO_ULM 2 #define CIO_ULM 2
#define CIO_FCF 3 #define CIO_FCF 3
#define CIO_DOS 4 #define CIO_DOS 4
#define CIO_DSD 5 #define CIO_DSD 5
/* Response */ /* Response */
#define CIO_SUCCESS 0 #define CIO_SUCCESS 0
#define CIO_FAILURE 2 #define CIO_FAILURE 2
#define CIO_SYSGEN_OK 3 #define CIO_SYSGEN_OK 3
/* Map a physical address to a card ID */ /* Map a physical address to a card ID */
#define SLOT(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1) #define SLOT(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1)
/* Map a card ID to a base address */ /* Map a card ID to a base address */
#define CADDR(bid) (((((bid) + 1) * 2) << 0x14)) #define CADDR(bid) (((((bid) + 1) * 2) << 0x14))
/* Offsets into the request/completion queues of various values */ /* Offsets into the request/completion queues of various values */
#define LUSIZE 4 /* Load/Unload pointers size */ #define LUSIZE 4 /* Load/Unload pointers size */
#define QESIZE 8 /* Queue entry is 8 bytes + application data */ #define QESIZE 8 /* Queue entry is 8 bytes + application data */
#define CIO_STAT 0 #define CIO_STAT 0
#define CIO_CMD 1 #define CIO_CMD 1
/* Sysgen State */ /* Sysgen State */
#define CIO_INT_NONE 0 #define CIO_INT_NONE 0
#define CIO_INT0 1 #define CIO_INT0 1
#define CIO_INT1 2 #define CIO_INT1 2
#define CIO_SYSGEN 3 #define CIO_SYSGEN 3
#define CIO_SET_INT(slot) if (cio[slot].populated && cio[slot].ivec >= 2) (cio_int_req |= (1 << slot)) #define CIO_SET_INT(slot) if (cio[slot].populated && cio[slot].ivec >= 2) (cio_int_req |= (1 << slot))
#define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot)) #define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot))
#define CIO_NAME_LEN 8 #define CIO_NAME_LEN 8
typedef struct { typedef struct {
t_bool populated; /* Populated? */ t_bool populated; /* Populated? */
uint16 id; /* CIO identifier */ uint16 id; /* CIO identifier */
char name[CIO_NAME_LEN]; /* Device name */ char name[CIO_NAME_LEN]; /* Device name */
void (*exp_handler)(uint8 slot); /* Handler for express jobs */ void (*exp_handler)(uint8 slot); /* Handler for express jobs */
void (*full_handler)(uint8 slot); /* Handler for full jobs */ void (*full_handler)(uint8 slot); /* Handler for full jobs */
void (*sysgen)(uint8 slot); /* Sysgen routine (optional) */ void (*sysgen)(uint8 slot); /* Sysgen routine (optional) */
void (*reset_handler)(uint8 slot); /* RESET request handler (optional) */ void (*reset_handler)(uint8 slot); /* RESET request handler (optional) */
uint32 rqp; /* Request Queue Pointer */ uint32 rqp; /* Request Queue Pointer */
uint32 cqp; /* Completion Queue Pointer */ uint32 cqp; /* Completion Queue Pointer */
uint8 rqs; /* Request queue size */ uint8 rqs; /* Request queue size */
uint8 cqs; /* Completion queue size */ uint8 cqs; /* Completion queue size */
uint8 ivec; /* Interrupt Vector */ uint8 ivec; /* Interrupt Vector */
uint8 no_rque; /* Number of request queues */ uint8 no_rque; /* Number of request queues */
uint8 ipl; /* IPL that this card uses */ uint8 ipl; /* IPL that this card uses */
uint8 sysgen_s; /* Sysgen state */ uint8 sysgen_s; /* Sysgen state */
uint8 seqbit; /* Squence Bit */ uint8 seqbit; /* Squence Bit */
uint8 op; /* Last received opcode */ uint8 op; /* Last received opcode */
} CIO_STATE; } CIO_STATE;
typedef struct { typedef struct {
uint16 byte_count; uint16 byte_count;
uint8 subdevice; uint8 subdevice;
uint8 opcode; uint8 opcode;
uint32 address; uint32 address;
} cio_entry; } cio_entry;
typedef struct { typedef struct {
uint32 low; uint32 low;
uint32 high; uint32 high;
uint32 (*read)(uint32 pa, size_t size); uint32 (*read)(uint32 pa, size_t size);
void (*write)(uint32 pa, uint32 val, size_t size); void (*write)(uint32 pa, uint32 val, size_t size);
} iolink; } iolink;
/* Example pump structure /* Example pump structure
* ---------------------- * ----------------------
* *
* Used during initial setup of PORTS card in slot 0: * Used during initial setup of PORTS card in slot 0:
* *
* dev = 0100 * dev = 0100
* min = 0000 * min = 0000
* cmdcode = 0003 * cmdcode = 0003
* options = 0000 * options = 0000
* bufaddr = 808821A0 * bufaddr = 808821A0
* ioaddr = 00000500 * ioaddr = 00000500
* size = 00000650 * size = 00000650
* numbrd = 00000000 * numbrd = 00000000
* retcode = 00000008 (PU_NULL) * retcode = 00000008 (PU_NULL)
*/ */
typedef struct { typedef struct {
uint16 dev; uint16 dev;
uint16 min; uint16 min;
uint16 cmdcode; uint16 cmdcode;
uint16 options; uint16 options;
uint32 bufaddr; uint32 bufaddr;
uint32 ioaddr; uint32 ioaddr;
uint32 size; uint32 size;
uint32 numbrd; uint32 numbrd;
uint32 retcode; uint32 retcode;
} pump; } pump;
t_stat cio_reset(DEVICE *dptr); t_stat cio_reset(DEVICE *dptr);
t_stat cio_svc(UNIT *uptr); t_stat cio_svc(UNIT *uptr);
t_stat cio_install(uint16 id, t_stat cio_install(uint16 id,
CONST char *name, CONST char *name,
uint8 ipl, uint8 ipl,
void (*exp_handler)(uint8 slot), void (*exp_handler)(uint8 slot),
void (*full_handler)(uint8 slot), void (*full_handler)(uint8 slot),
void (*sysgen)(uint8 slot), void (*sysgen)(uint8 slot),
void (*reset_handler)(uint8 slot), void (*reset_handler)(uint8 slot),
uint8 *slot); uint8 *slot);
void cio_remove(uint8 slot); void cio_remove(uint8 slot);
void cio_remove_all(uint16 id); void cio_remove_all(uint16 id);
uint32 cio_crc32_shift(uint32 crc, uint8 data); uint32 cio_crc32_shift(uint32 crc, uint8 data);
void cio_cexpress(uint8 slot, uint32 esize, cio_entry *cqe, uint8 *app_data); void cio_cexpress(uint8 slot, uint32 esize, cio_entry *cqe, uint8 *app_data);
void cio_cqueue(uint8 slot, uint8 cmd_stat, uint32 esize, cio_entry *cqe, uint8 *app_data); void cio_cqueue(uint8 slot, uint8 cmd_stat, uint32 esize, cio_entry *cqe, uint8 *app_data);
t_bool cio_cqueue_avail(uint8 slot, uint32 esize); t_bool cio_cqueue_avail(uint8 slot, uint32 esize);
void cio_rexpress(uint8 slot, uint32 esize, cio_entry *rqe, uint8 *app_data); void cio_rexpress(uint8 slot, uint32 esize, cio_entry *rqe, uint8 *app_data);
t_stat cio_rqueue(uint8 slot, uint32 qnum, uint32 esize, cio_entry *rqe, uint8 *app_data); t_stat cio_rqueue(uint8 slot, uint32 qnum, uint32 esize, cio_entry *rqe, uint8 *app_data);
t_bool cio_rqueue_avail(uint8 slot, uint32 qnum, uint32 esize); t_bool cio_rqueue_avail(uint8 slot, uint32 qnum, uint32 esize);
uint16 cio_r_lp(uint8 slot, uint32 qnum, uint32 esize); uint16 cio_r_lp(uint8 slot, uint32 qnum, uint32 esize);
uint16 cio_r_ulp(uint8 slot, uint32 qnum, uint32 esize); uint16 cio_r_ulp(uint8 slot, uint32 qnum, uint32 esize);
uint16 cio_c_lp(uint8 slot, uint32 esize); uint16 cio_c_lp(uint8 slot, uint32 esize);
uint16 cio_c_ulp(uint8 slot, uint32 esize); uint16 cio_c_ulp(uint8 slot, uint32 esize);
void cio_sysgen(uint8 slot); void cio_sysgen(uint8 slot);
uint32 io_read(uint32 pa, size_t size); uint32 io_read(uint32 pa, size_t size);
void io_write(uint32 pa, uint32 val, size_t size); void io_write(uint32 pa, uint32 val, size_t size);
extern uint16 cio_int_req; extern uint16 cio_int_req;
extern CIO_STATE cio[CIO_SLOTS]; extern CIO_STATE cio[CIO_SLOTS];
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,234 +1,234 @@
/* 3b2_iu.h: SCN2681A Dual UART /* 3b2_iu.h: SCN2681A Dual UART
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef __3B2_IU_H__ #ifndef __3B2_IU_H__
#define __3B2_IU_H__ #define __3B2_IU_H__
#include "3b2_defs.h" #include "3b2_defs.h"
#define CMD_ERX 0x01 /* Enable receiver */ #define CMD_ERX 0x01 /* Enable receiver */
#define CMD_DRX 0x02 /* Disable receiver */ #define CMD_DRX 0x02 /* Disable receiver */
#define CMD_ETX 0x04 /* Enable transmitter */ #define CMD_ETX 0x04 /* Enable transmitter */
#define CMD_DTX 0x08 /* Disable transmitter */ #define CMD_DTX 0x08 /* Disable transmitter */
#define CMD_MISC_SHIFT 4 /* Command */ #define CMD_MISC_SHIFT 4 /* Command */
#define CMD_MISC_MASK 0x7 #define CMD_MISC_MASK 0x7
#define IU_SPEED_REGS 2 /* Two speed select registers, */ #define IU_SPEED_REGS 2 /* Two speed select registers, */
#define IU_SPEEDS 16 /* with 16 speeds each */ #define IU_SPEEDS 16 /* with 16 speeds each */
#define IU_PARITY_ODD 0 #define IU_PARITY_ODD 0
#define IU_PARITY_EVEN 1 #define IU_PARITY_EVEN 1
#define IU_PARITY_NONE 2 #define IU_PARITY_NONE 2
#define STS_RXR 0x01 /* Receiver ready */ #define STS_RXR 0x01 /* Receiver ready */
#define STS_FFL 0x02 /* FIFO full */ #define STS_FFL 0x02 /* FIFO full */
#define STS_TXR 0x04 /* Transmitter ready */ #define STS_TXR 0x04 /* Transmitter ready */
#define STS_TXE 0x08 /* Transmitter empty */ #define STS_TXE 0x08 /* Transmitter empty */
#define STS_OER 0x10 /* Overrun error */ #define STS_OER 0x10 /* Overrun error */
#define STS_PER 0x20 /* Parity error */ #define STS_PER 0x20 /* Parity error */
#define STS_FER 0x40 /* Framing error */ #define STS_FER 0x40 /* Framing error */
#define STS_RXB 0x80 /* Received break */ #define STS_RXB 0x80 /* Received break */
#define ISTS_TXRA 0x01 /* Transmitter ready A */ #define ISTS_TXRA 0x01 /* Transmitter ready A */
#define ISTS_RXRA 0x02 /* Receiver ready A */ #define ISTS_RXRA 0x02 /* Receiver ready A */
#define ISTS_DBA 0x04 /* Delta Break A */ #define ISTS_DBA 0x04 /* Delta Break A */
#define ISTS_CRI 0x08 /* Counter ready */ #define ISTS_CRI 0x08 /* Counter ready */
#define ISTS_TXRB 0x10 /* Transmitter ready B */ #define ISTS_TXRB 0x10 /* Transmitter ready B */
#define ISTS_RXRB 0x20 /* Receiver ready B */ #define ISTS_RXRB 0x20 /* Receiver ready B */
#define ISTS_DBB 0x40 /* Delta Break B */ #define ISTS_DBB 0x40 /* Delta Break B */
#define ISTS_IPC 0x80 /* Interrupt port change */ #define ISTS_IPC 0x80 /* Interrupt port change */
#define MODE_V_CHM 6 /* Channel mode */ #define MODE_V_CHM 6 /* Channel mode */
#define MODE_M_CHM 0x3 #define MODE_M_CHM 0x3
/* Transmitter State bits */ /* Transmitter State bits */
#define T_HOLD 1 #define T_HOLD 1
#define T_XMIT 2 #define T_XMIT 2
/* Used by the DMAC */ /* Used by the DMAC */
#define IUA_DATA_REG 3 #define IUA_DATA_REG 3
#define IUB_DATA_REG 11 #define IUB_DATA_REG 11
/* Registers - Read */ /* Registers - Read */
#define SRA 1 #define SRA 1
#define RHRA 3 #define RHRA 3
#define IPCR 4 #define IPCR 4
#define ISR 5 #define ISR 5
#define CTU 6 #define CTU 6
#define CTL 7 #define CTL 7
#define SRB 9 #define SRB 9
#define RHRB 11 #define RHRB 11
#define INPRT 13 #define INPRT 13
#define START_CTR 14 #define START_CTR 14
#define STOP_CTR 15 #define STOP_CTR 15
/* Registers - Write */ /* Registers - Write */
#define CSRA 1 #define CSRA 1
#define CRA 2 #define CRA 2
#define THRA 3 #define THRA 3
#define ACR 4 #define ACR 4
#define IMR 5 #define IMR 5
#define CTUR 6 #define CTUR 6
#define CTLR 7 #define CTLR 7
#define CSRB 9 #define CSRB 9
#define CRB 10 #define CRB 10
#define THRB 11 #define THRB 11
#define OPCR 13 #define OPCR 13
#define SOPR 14 #define SOPR 14
#define ROPR 15 #define ROPR 15
/* Registers - R/W */ /* Registers - R/W */
#define MR12A 0 #define MR12A 0
#define MR12B 8 #define MR12B 8
/* Port configuration */ /* Port configuration */
#define TX_EN 1 #define TX_EN 1
#define RX_EN 2 #define RX_EN 2
/* Control Register commands */ /* Control Register commands */
#define CR_RST_MR 1 #define CR_RST_MR 1
#define CR_RST_RX 2 #define CR_RST_RX 2
#define CR_RST_TX 3 #define CR_RST_TX 3
#define CR_RST_ERR 4 #define CR_RST_ERR 4
#define CR_RST_BRK 5 #define CR_RST_BRK 5
#define CR_START_BRK 6 #define CR_START_BRK 6
#define CR_STOP_BRK 7 #define CR_STOP_BRK 7
/* IMR bits */ /* IMR bits */
#define IMR_TXRA 0x01 #define IMR_TXRA 0x01
#define IMR_RXRA 0x02 #define IMR_RXRA 0x02
#define IMR_CTR 0x08 #define IMR_CTR 0x08
#define IMR_TXRB 0x10 #define IMR_TXRB 0x10
#define IMR_RXRB 0x20 #define IMR_RXRB 0x20
/* Power-off bit */ /* Power-off bit */
#define IU_KILLPWR 0x04 #define IU_KILLPWR 0x04
#define PORT_A 0 #define PORT_A 0
#define PORT_B 1 #define PORT_B 1
#define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT) #define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT)
#define IUBASE 0x49000 #define IUBASE 0x49000
#define IUSIZE 0x100 #define IUSIZE 0x100
#define IU_BUF_SIZE 3 #define IU_BUF_SIZE 3
/* Data Carrier Detect inputs and input change bits */ /* Data Carrier Detect inputs and input change bits */
#if defined(REV3) #if defined(REV3)
#define IU_DCDB_CH 0x80 #define IU_DCDB_CH 0x80
#define IU_DCDA_CH 0x40 #define IU_DCDA_CH 0x40
#define IU_DCDB 0x08 #define IU_DCDB 0x08
#define IU_DCDA 0x04 #define IU_DCDA 0x04
#else #else
#define IU_DCDB_CH 0x20 #define IU_DCDB_CH 0x20
#define IU_DCDA_CH 0x10 #define IU_DCDA_CH 0x10
#define IU_DCDB 0x02 #define IU_DCDB 0x02
#define IU_DCDA 0x01 #define IU_DCDA 0x01
#endif #endif
/* Default baud rate generator (9600 baud) */ /* Default baud rate generator (9600 baud) */
#define BRG_DEFAULT 11 #define BRG_DEFAULT 11
/* The 2681 DUART includes a 16-bit timer/counter that can be used to /* The 2681 DUART includes a 16-bit timer/counter that can be used to
* trigger an interrupt after a certain amount of time has passed. * trigger an interrupt after a certain amount of time has passed.
* *
* The 2681 uses a crystal with a frequency of 3.686400 MHz, and the * The 2681 uses a crystal with a frequency of 3.686400 MHz, and the
* timer/counter uses this frequency divided by 16, giving a final * timer/counter uses this frequency divided by 16, giving a final
* timer/counter frequency of 230,400 Hz. There are therefore 4.34 * timer/counter frequency of 230,400 Hz. There are therefore 4.34
* microseconds of wall time per tick of the timer. * microseconds of wall time per tick of the timer.
* *
* The multiplier defined below is a default that can be adjusted to * The multiplier defined below is a default that can be adjusted to
* make IU timing faster, but less accurate, if desired */ * make IU timing faster, but less accurate, if desired */
#define IU_TIMER_MULTIPLIER 4 #define IU_TIMER_MULTIPLIER 4
typedef struct iu_port { typedef struct iu_port {
uint8 cmd; /* Command */ uint8 cmd; /* Command */
uint8 mode[2]; /* Two mode buffers */ uint8 mode[2]; /* Two mode buffers */
uint8 modep; /* Point to mode[0] or mode[1] */ uint8 modep; /* Point to mode[0] or mode[1] */
uint8 conf; /* Configuration bits */ uint8 conf; /* Configuration bits */
uint8 sr; /* Status Register */ uint8 sr; /* Status Register */
uint8 thr; /* Transmit Holding Register */ uint8 thr; /* Transmit Holding Register */
uint8 txr; /* Transmit Shift Register */ uint8 txr; /* Transmit Shift Register */
uint8 rxr; /* Receive Shift Register */ uint8 rxr; /* Receive Shift Register */
uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */ uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */
uint8 w_p; /* Receive Buffer Write Pointer */ uint8 w_p; /* Receive Buffer Write Pointer */
uint8 r_p; /* Receive Buffer Read Pointer */ uint8 r_p; /* Receive Buffer Read Pointer */
uint8 tx_state; /* Transmitting state flags (HOLD, XMIT) */ uint8 tx_state; /* Transmitting state flags (HOLD, XMIT) */
t_bool dma; /* DMA currently active */ t_bool dma; /* DMA currently active */
t_bool drq; /* DMA request enabled */ t_bool drq; /* DMA request enabled */
t_bool rxr_full; /* Receive Shift Register is full */ t_bool rxr_full; /* Receive Shift Register is full */
} IU_PORT; } IU_PORT;
typedef struct iu_state { typedef struct iu_state {
uint8 isr; /* Interrupt Status Register */ uint8 isr; /* Interrupt Status Register */
uint8 imr; /* Interrupt Mask Register */ uint8 imr; /* Interrupt Mask Register */
uint8 acr; /* Aux. Control Register */ uint8 acr; /* Aux. Control Register */
uint8 opcr; /* Output Port Configuration */ uint8 opcr; /* Output Port Configuration */
uint8 inprt; /* Input Port Data */ uint8 inprt; /* Input Port Data */
uint8 ipcr; /* Input Port Change Register */ uint8 ipcr; /* Input Port Change Register */
} IU_STATE; } IU_STATE;
typedef struct iu_timer_state { typedef struct iu_timer_state {
uint16 c_set; uint16 c_set;
t_bool c_en; t_bool c_en;
} IU_TIMER_STATE; } IU_TIMER_STATE;
/* Function prototypes */ /* Function prototypes */
t_stat contty_attach(UNIT *uptr, CONST char *cptr); t_stat contty_attach(UNIT *uptr, CONST char *cptr);
t_stat contty_detach(UNIT *uptr); t_stat contty_detach(UNIT *uptr);
t_stat tti_reset(DEVICE *dptr); t_stat tti_reset(DEVICE *dptr);
t_stat contty_reset(DEVICE *dptr); t_stat contty_reset(DEVICE *dptr);
t_stat iu_timer_reset(DEVICE *dptr); t_stat iu_timer_reset(DEVICE *dptr);
t_stat iu_timer_set_mult(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat iu_timer_set_mult(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, CONST void *desc); t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, CONST void *desc);
t_stat iu_svc_tti(UNIT *uptr); t_stat iu_svc_tti(UNIT *uptr);
t_stat iu_svc_tto(UNIT *uptr); t_stat iu_svc_tto(UNIT *uptr);
t_stat iu_svc_contty(UNIT *uptr); t_stat iu_svc_contty(UNIT *uptr);
t_stat iu_svc_contty_xmt(UNIT *uptr); t_stat iu_svc_contty_xmt(UNIT *uptr);
t_stat iu_svc_timer(UNIT *uptr); t_stat iu_svc_timer(UNIT *uptr);
uint32 iu_read(uint32 pa, size_t size); uint32 iu_read(uint32 pa, size_t size);
void iu_write(uint32 pa, uint32 val, size_t size); void iu_write(uint32 pa, uint32 val, size_t size);
void iua_drq_handled(); void iua_drq_handled();
void iub_drq_handled(); void iub_drq_handled();
void iu_txrdy_a_irq(); void iu_txrdy_a_irq();
void iu_txrdy_b_irq(); void iu_txrdy_b_irq();
void iu_dma_console(uint8 channel, uint32 service_address); void iu_dma_console(uint8 channel, uint32 service_address);
void iu_dma_contty(uint8 channel, uint32 service_address); void iu_dma_contty(uint8 channel, uint32 service_address);
void increment_modep_a(); void increment_modep_a();
void increment_modep_b(); void increment_modep_b();
extern IU_PORT iu_console; extern IU_PORT iu_console;
extern IU_PORT iu_contty; extern IU_PORT iu_contty;
extern t_bool iu_increment_a; extern t_bool iu_increment_a;
extern t_bool iu_increment_b; extern t_bool iu_increment_b;
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,389 +1,389 @@
/* 3b2_mau.h: WE32106 and WE32206 Math Accelerator Unit /* 3b2_mau.h: WE32106 and WE32206 Math Accelerator Unit
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
--------------------------------------------------------------------- ---------------------------------------------------------------------
This file is part of a simulation of the WE 32106 and WE 32206 Math This file is part of a simulation of the WE 32106 and WE 32206 Math
Acceleration Units. The WE 32106 and WE 32206 are IEEE-754 Acceleration Units. The WE 32106 and WE 32206 are IEEE-754
compabitle floating point hardware math accelerators that were compabitle floating point hardware math accelerators that were
available as an optional component on the AT&T 3B2/310 and 3B2/400, available as an optional component on the AT&T 3B2/310 and 3B2/400,
and as a standard component on the 3B2/500, 3B2/600, 3B2/700, and and as a standard component on the 3B2/500, 3B2/600, 3B2/700, and
3B2/1000. 3B2/1000.
Portions of this code are derived from the SoftFloat 2c library by Portions of this code are derived from the SoftFloat 2c library by
John R. Hauser. Functions derived from SoftFloat 2c are clearly John R. Hauser. Functions derived from SoftFloat 2c are clearly
marked in the comments. marked in the comments.
Legal Notice Legal Notice
============ ============
SoftFloat was written by John R. Hauser. Release 2c of SoftFloat SoftFloat was written by John R. Hauser. Release 2c of SoftFloat
was made possible in part by the International Computer Science was made possible in part by the International Computer Science
Institute, located at Suite 600, 1947 Center Street, Berkeley, Institute, located at Suite 600, 1947 Center Street, Berkeley,
California 94704. Funding was partially provided by the National California 94704. Funding was partially provided by the National
Science Foundation under grant MIP-9311980. The original version Science Foundation under grant MIP-9311980. The original version
of this code was written as part of a project to build a of this code was written as part of a project to build a
fixed-point vector processor in collaboration with the University fixed-point vector processor in collaboration with the University
of California at Berkeley, overseen by Profs. Nelson Morgan and of California at Berkeley, overseen by Profs. Nelson Morgan and
John Wawrzynek. John Wawrzynek.
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable
effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS effort has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS
THAT WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS THAT WILL AT TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS
SOFTWARE IS RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND SOFTWARE IS RESTRICTED TO PERSONS AND ORGANIZATIONS WHO CAN AND
WILL TOLERATE ALL LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE WILL TOLERATE ALL LOSSES, COSTS, OR OTHER PROBLEMS THEY INCUR DUE
TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR THE TO THE SOFTWARE WITHOUT RECOMPENSE FROM JOHN HAUSER OR THE
INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE INTERNATIONAL COMPUTER SCIENCE INSTITUTE, AND WHO FURTHERMORE
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER
SCIENCE INSTITUTE (possibly via similar legal notice) AGAINST ALL SCIENCE INSTITUTE (possibly via similar legal notice) AGAINST ALL
LOSSES, COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND LOSSES, COSTS, OR OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND
CLIENTS DUE TO THE SOFTWARE, OR INCURRED BY ANYONE DUE TO A CLIENTS DUE TO THE SOFTWARE, OR INCURRED BY ANYONE DUE TO A
DERIVATIVE WORK THEY CREATE USING ANY PART OF THE SOFTWARE. DERIVATIVE WORK THEY CREATE USING ANY PART OF THE SOFTWARE.
The following are expressly permitted, even for commercial The following are expressly permitted, even for commercial
purposes: purposes:
(1) distribution of SoftFloat in whole or in part, as long as this (1) distribution of SoftFloat in whole or in part, as long as this
and other legal notices remain and are prominent, and provided also and other legal notices remain and are prominent, and provided also
that, for a partial distribution, prominent notice is given that it that, for a partial distribution, prominent notice is given that it
is a subset of the original; and is a subset of the original; and
(2) inclusion or use of SoftFloat in whole or in part in a (2) inclusion or use of SoftFloat in whole or in part in a
derivative work, provided that the use restrictions above are met derivative work, provided that the use restrictions above are met
and the minimal documentation requirements stated in the source and the minimal documentation requirements stated in the source
code are satisfied. code are satisfied.
--------------------------------------------------------------------- ---------------------------------------------------------------------
Data Types Data Types
========== ==========
The WE32106 MAU stores values using IEEE-754 1985 types, plus a The WE32106 MAU stores values using IEEE-754 1985 types, plus a
non-standard Decimal type. non-standard Decimal type.
- Decimal Type - 18 BCD digits long. Each digit is 4 bits wide. - Decimal Type - 18 BCD digits long. Each digit is 4 bits wide.
Sign is encoded in byte 0. Sign is encoded in byte 0.
3322 2222 2222 1111 1111 1100 0000 0000 3322 2222 2222 1111 1111 1100 0000 0000
1098 7654 3210 9876 5432 1098 7654 3210 1098 7654 3210 9876 5432 1098 7654 3210
+-------------------+----+----+----+----+ +-------------------+----+----+----+----+
| unused | D18| D17| D16| D15| High Word | unused | D18| D17| D16| D15| High Word
+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+
| D14| D13| D12| D11| D10| D09| D08| D07| Middle Word | D14| D13| D12| D11| D10| D09| D08| D07| Middle Word
+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+
| D06| D05| D04| D03| D02| D01| D00|sign| Low Word | D06| D05| D04| D03| D02| D01| D00|sign| Low Word
+----+----+----+----+----+----+----+----+ +----+----+----+----+----+----+----+----+
Sign: 0: Positive Infinity 10: Positive Number Sign: 0: Positive Infinity 10: Positive Number
1: Negative Infinity 11: Negative Number 1: Negative Infinity 11: Negative Number
2: Positive NaN 12: Positive Number 2: Positive NaN 12: Positive Number
3: Negative NaN 13: Negative Number 3: Negative NaN 13: Negative Number
4-9: Trapping NaN 14-15: Positive Number 4-9: Trapping NaN 14-15: Positive Number
- Extended Precision (80-bit) - exponent biased by 16383 - Extended Precision (80-bit) - exponent biased by 16383
3 322222222221111 1 111110000000000 3 322222222221111 1 111110000000000
1 098765432109876 5 432109876543210 1 098765432109876 5 432109876543210
+-----------------+-+---------------+ +-----------------+-+---------------+
| unused |S| Exponent | High Word | unused |S| Exponent | High Word
+-+---------------+-+---------------+ +-+---------------+-+---------------+
|J| Fraction (high word) | Middle Word |J| Fraction (high word) | Middle Word
+-+---------------------------------+ +-+---------------------------------+
| Fraction (low word) | Low Word | Fraction (low word) | Low Word
+-----------------------------------+ +-----------------------------------+
- Double Precision (64-bit) - exponent biased by 1023 - Double Precision (64-bit) - exponent biased by 1023
3 3222222222 211111111110000000000 3 3222222222 211111111110000000000
1 0987654321 098765432109876543210 1 0987654321 098765432109876543210
+-+----------+---------------------+ +-+----------+---------------------+
|S| Exponent | Fraction (high) | High Word |S| Exponent | Fraction (high) | High Word
+-+----------+---------------------+ +-+----------+---------------------+
| Fraction (low) | Low Word | Fraction (low) | Low Word
+----------------------------------+ +----------------------------------+
- Single Precision (32-bit) - exponent biased by 127 - Single Precision (32-bit) - exponent biased by 127
3 32222222 22211111111110000000000 3 32222222 22211111111110000000000
1 09876543 21098765432109876543210 1 09876543 21098765432109876543210
+-+--------+-----------------------+ +-+--------+-----------------------+
|S| Exp | Fraction | |S| Exp | Fraction |
+-+--------+-----------------------+ +-+--------+-----------------------+
*/ */
#ifndef _3B2_REV2_MAU_H_ #ifndef _3B2_REV2_MAU_H_
#define _3B2_REV2_MAU_H_ #define _3B2_REV2_MAU_H_
#include "sim_defs.h" #include "sim_defs.h"
#define SRC_LEN_INVALID 0 #define SRC_LEN_INVALID 0
#define SRC_LEN_SINGLE 1 #define SRC_LEN_SINGLE 1
#define SRC_LEN_DOUBLE 2 #define SRC_LEN_DOUBLE 2
#define SRC_LEN_TRIPLE 3 #define SRC_LEN_TRIPLE 3
#define MAU_ASR_RC_SHIFT 22 #define MAU_ASR_RC_SHIFT 22
#define MAU_ASR_PR 0x20u /* Partial Remainder */ #define MAU_ASR_PR 0x20u /* Partial Remainder */
#define MAU_ASR_QS 0x40u /* Divide By Zero Sticky */ #define MAU_ASR_QS 0x40u /* Divide By Zero Sticky */
#define MAU_ASR_US 0x80u /* Underflow Sticky */ #define MAU_ASR_US 0x80u /* Underflow Sticky */
#define MAU_ASR_OS 0x100u /* Overflow Sticky */ #define MAU_ASR_OS 0x100u /* Overflow Sticky */
#define MAU_ASR_IS 0x200u /* Invalid Operation Sticky */ #define MAU_ASR_IS 0x200u /* Invalid Operation Sticky */
#define MAU_ASR_PM 0x400u /* Inexact Mask */ #define MAU_ASR_PM 0x400u /* Inexact Mask */
#define MAU_ASR_QM 0x800u /* Divide by Zero Mask */ #define MAU_ASR_QM 0x800u /* Divide by Zero Mask */
#define MAU_ASR_UM 0x1000u /* Underflow Mask */ #define MAU_ASR_UM 0x1000u /* Underflow Mask */
#define MAU_ASR_OM 0x2000u /* Overflow Mask */ #define MAU_ASR_OM 0x2000u /* Overflow Mask */
#define MAU_ASR_IM 0x4000u /* Invalid Operation Mask */ #define MAU_ASR_IM 0x4000u /* Invalid Operation Mask */
#define MAU_ASR_UO 0x10000u /* Unordered */ #define MAU_ASR_UO 0x10000u /* Unordered */
#define MAU_ASR_CSC 0x20000u /* Context Switch Control */ #define MAU_ASR_CSC 0x20000u /* Context Switch Control */
#define MAU_ASR_PS 0x40000u /* Inexact Sticky */ #define MAU_ASR_PS 0x40000u /* Inexact Sticky */
#define MAU_ASR_IO 0x80000u /* Integer Overflow */ #define MAU_ASR_IO 0x80000u /* Integer Overflow */
#define MAU_ASR_Z 0x100000u /* Zero Flag */ #define MAU_ASR_Z 0x100000u /* Zero Flag */
#define MAU_ASR_N 0x200000u /* Negative Flag */ #define MAU_ASR_N 0x200000u /* Negative Flag */
#define MAU_ASR_RC 0x400000u /* Round Control */ #define MAU_ASR_RC 0x400000u /* Round Control */
#define MAU_ASR_NTNC 0x1000000u /* Nontrapping NaN Control */ #define MAU_ASR_NTNC 0x1000000u /* Nontrapping NaN Control */
#define MAU_ASR_ECP 0x2000000u /* Exception Condition */ #define MAU_ASR_ECP 0x2000000u /* Exception Condition */
#define MAU_ASR_RA 0x80000000u /* Result Available */ #define MAU_ASR_RA 0x80000000u /* Result Available */
#if defined(REV3) #if defined(REV3)
#define MAU_ASR_FE 0x1u /* Feature Enable */ #define MAU_ASR_FE 0x1u /* Feature Enable */
#define MAU_ASR_VER 0x2u /* Version */ #define MAU_ASR_VER 0x2u /* Version */
#define MAU_ASR_UW 0x10u /* Unaligned Word */ #define MAU_ASR_UW 0x10u /* Unaligned Word */
#define MAU_ASR_WF 0x8000u /* Write Fault Indicator */ #define MAU_ASR_WF 0x8000u /* Write Fault Indicator */
#define MAU_RC_RN 0 /* Round toward Nearest */ #define MAU_RC_RN 0 /* Round toward Nearest */
#define MAU_RC_RP 1 /* Round toward Plus Infin. */ #define MAU_RC_RP 1 /* Round toward Plus Infin. */
#define MAU_RC_RM 2 /* Round toward Neg. Infin. */ #define MAU_RC_RM 2 /* Round toward Neg. Infin. */
#define MAU_RC_RZ 3 /* Round toward Zero */ #define MAU_RC_RZ 3 /* Round toward Zero */
#endif #endif
#define SFP_SIGN(V) (((V) >> 31) & 1) #define SFP_SIGN(V) (((V) >> 31) & 1)
#define SFP_EXP(V) (((V) >> 23) & 0xff) #define SFP_EXP(V) (((V) >> 23) & 0xff)
#define SFP_FRAC(V) ((V) & 0x7fffff) #define SFP_FRAC(V) ((V) & 0x7fffff)
#define DFP_SIGN(V) (((V) >> 63) & 1) #define DFP_SIGN(V) (((V) >> 63) & 1)
#define DFP_EXP(V) (((V) >> 52) & 0x7ff) #define DFP_EXP(V) (((V) >> 52) & 0x7ff)
#define DFP_FRAC(V) ((V) & 0xfffffffffffffull) #define DFP_FRAC(V) ((V) & 0xfffffffffffffull)
#define XFP_SIGN(V) (((V)->sign_exp >> 15) & 1) #define XFP_SIGN(V) (((V)->sign_exp >> 15) & 1)
#define XFP_EXP(V) ((V)->sign_exp & 0x7fff) #define XFP_EXP(V) ((V)->sign_exp & 0x7fff)
#define XFP_FRAC(V) ((V)->frac) #define XFP_FRAC(V) ((V)->frac)
#define XFP_IS_NORMAL(V) ((V)->frac & 0x8000000000000000ull) #define XFP_IS_NORMAL(V) ((V)->frac & 0x8000000000000000ull)
#define DEFAULT_XFP_NAN_SIGN_EXP 0xffff #define DEFAULT_XFP_NAN_SIGN_EXP 0xffff
#define DEFAULT_XFP_NAN_FRAC 0xc000000000000000ull #define DEFAULT_XFP_NAN_FRAC 0xc000000000000000ull
#define SFP_IS_TRAPPING_NAN(V) (((((V) >> 22) & 0x1ff) == 0x1fe) && \ #define SFP_IS_TRAPPING_NAN(V) (((((V) >> 22) & 0x1ff) == 0x1fe) && \
((V) & 0x3fffff)) ((V) & 0x3fffff))
#define DFP_IS_TRAPPING_NAN(V) (((((V) >> 51) & 0xfff) == 0xffe) && \ #define DFP_IS_TRAPPING_NAN(V) (((((V) >> 51) & 0xfff) == 0xffe) && \
((V) & 0x7ffffffffffffull)) ((V) & 0x7ffffffffffffull))
#define XFP_IS_NAN(V) ((((V)->sign_exp & 0x7fff) == 0x7fff) && \ #define XFP_IS_NAN(V) ((((V)->sign_exp & 0x7fff) == 0x7fff) && \
(t_uint64)((V)->frac << 1)) (t_uint64)((V)->frac << 1))
#define XFP_IS_TRAPPING_NAN(V) ((((V)->sign_exp) & 0x7fff) && \ #define XFP_IS_TRAPPING_NAN(V) ((((V)->sign_exp) & 0x7fff) && \
((((V)->frac) & ~(0x4000000000000000ull)) << 1) && \ ((((V)->frac) & ~(0x4000000000000000ull)) << 1) && \
(((V)->frac) == ((V)->frac & ~(0x4000000000000000ull)))) (((V)->frac) == ((V)->frac & ~(0x4000000000000000ull))))
#define PACK_DFP(SIGN,EXP,FRAC) ((((t_uint64)(SIGN))<<63) + \ #define PACK_DFP(SIGN,EXP,FRAC) ((((t_uint64)(SIGN))<<63) + \
(((t_uint64)(EXP))<<52) + \ (((t_uint64)(EXP))<<52) + \
((t_uint64)(FRAC))) ((t_uint64)(FRAC)))
#define PACK_SFP(SIGN,EXP,FRAC) (((uint32)(SIGN)<<31) + \ #define PACK_SFP(SIGN,EXP,FRAC) (((uint32)(SIGN)<<31) + \
((uint32)(EXP)<<23) + \ ((uint32)(EXP)<<23) + \
((uint32)(FRAC))) ((uint32)(FRAC)))
#define PACK_XFP(SIGN,EXP,FRAC,V) do { \ #define PACK_XFP(SIGN,EXP,FRAC,V) do { \
(V)->frac = (FRAC); \ (V)->frac = (FRAC); \
(V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \ (V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \
(V)->s = FALSE; \ (V)->s = FALSE; \
} while (0) } while (0)
#define PACK_XFP_S(SIGN,EXP,FRAC,S,V) do { \ #define PACK_XFP_S(SIGN,EXP,FRAC,S,V) do { \
(V)->frac = (FRAC); \ (V)->frac = (FRAC); \
(V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \ (V)->sign_exp = ((uint16)(SIGN) << 15) + (EXP); \
(V)->s = (S) != 0; \ (V)->s = (S) != 0; \
} while (0) } while (0)
#define MAU_RM ((RM)((mau_state.asr >> 22) & 3)) #define MAU_RM ((RM)((mau_state.asr >> 22) & 3))
typedef enum { typedef enum {
M_ADD = 0x02, M_ADD = 0x02,
M_SUB = 0x03, M_SUB = 0x03,
M_DIV = 0x04, M_DIV = 0x04,
M_REM = 0x05, M_REM = 0x05,
M_MUL = 0x06, M_MUL = 0x06,
M_MOVE = 0x07, M_MOVE = 0x07,
M_RDASR = 0x08, M_RDASR = 0x08,
M_WRASR = 0x09, M_WRASR = 0x09,
M_CMP = 0x0a, M_CMP = 0x0a,
M_CMPE = 0x0b, M_CMPE = 0x0b,
M_ABS = 0x0c, M_ABS = 0x0c,
M_SQRT = 0x0d, M_SQRT = 0x0d,
M_RTOI = 0x0e, M_RTOI = 0x0e,
M_FTOI = 0x0f, M_FTOI = 0x0f,
M_ITOF = 0x10, M_ITOF = 0x10,
M_DTOF = 0x11, M_DTOF = 0x11,
M_FTOD = 0x12, M_FTOD = 0x12,
M_NOP = 0x13, M_NOP = 0x13,
M_EROF = 0x14, M_EROF = 0x14,
M_NEG = 0x17, M_NEG = 0x17,
M_LDR = 0x18, M_LDR = 0x18,
M_CMPS = 0x1a, M_CMPS = 0x1a,
M_CMPES = 0x1b M_CMPES = 0x1b
} mau_opcodes; } mau_opcodes;
typedef enum { typedef enum {
M_OP3_F0_SINGLE, M_OP3_F0_SINGLE,
M_OP3_F1_SINGLE, M_OP3_F1_SINGLE,
M_OP3_F2_SINGLE, M_OP3_F2_SINGLE,
M_OP3_F3_SINGLE, M_OP3_F3_SINGLE,
M_OP3_F0_DOUBLE, M_OP3_F0_DOUBLE,
M_OP3_F1_DOUBLE, M_OP3_F1_DOUBLE,
M_OP3_F2_DOUBLE, M_OP3_F2_DOUBLE,
M_OP3_F3_DOUBLE, M_OP3_F3_DOUBLE,
M_OP3_F0_TRIPLE, M_OP3_F0_TRIPLE,
M_OP3_F1_TRIPLE, M_OP3_F1_TRIPLE,
M_OP3_F2_TRIPLE, M_OP3_F2_TRIPLE,
M_OP3_F3_TRIPLE, M_OP3_F3_TRIPLE,
M_OP3_MEM_SINGLE, M_OP3_MEM_SINGLE,
M_OP3_MEM_DOUBLE, M_OP3_MEM_DOUBLE,
M_OP3_MEM_TRIPLE, M_OP3_MEM_TRIPLE,
M_OP3_NONE M_OP3_NONE
} op3_spec; } op3_spec;
/* Specifier bytes for Operands 1 and 2 */ /* Specifier bytes for Operands 1 and 2 */
typedef enum { typedef enum {
M_OP_F0, M_OP_F0,
M_OP_F1, M_OP_F1,
M_OP_F2, M_OP_F2,
M_OP_F3, M_OP_F3,
M_OP_MEM_SINGLE, M_OP_MEM_SINGLE,
M_OP_MEM_DOUBLE, M_OP_MEM_DOUBLE,
M_OP_MEM_TRIPLE, M_OP_MEM_TRIPLE,
M_OP_NONE M_OP_NONE
} op_spec; } op_spec;
/* /*
* 128-bit value * 128-bit value
*/ */
typedef struct { typedef struct {
t_uint64 low; t_uint64 low;
t_uint64 high; t_uint64 high;
} t_mau_128; } t_mau_128;
/* /*
* Not-a-Number Type * Not-a-Number Type
*/ */
typedef struct { typedef struct {
t_bool sign; t_bool sign;
t_uint64 high; t_uint64 high;
t_uint64 low; t_uint64 low;
} T_NAN; } T_NAN;
/* /*
* Extended Precision (80 bits). * Extended Precision (80 bits).
* *
* Note that an undocumented feature of the WE32106 requires the use * Note that an undocumented feature of the WE32106 requires the use
* of uint32 rather than uint16 for the sign and exponent components * of uint32 rather than uint16 for the sign and exponent components
* of the struct. Although bits 80-95 are "unused", several * of the struct. Although bits 80-95 are "unused", several
* diagnostics actually expect these bits to be moved and preserved on * diagnostics actually expect these bits to be moved and preserved on
* word transfers. They are ignored and discarded by math routines, * word transfers. They are ignored and discarded by math routines,
* however. * however.
* *
* The 's' field holds the Sticky bit used by rounding. * The 's' field holds the Sticky bit used by rounding.
*/ */
typedef struct { typedef struct {
uint32 sign_exp; /* Sign and Exponent */ uint32 sign_exp; /* Sign and Exponent */
t_uint64 frac; /* Fraction/Significand/Mantissa */ t_uint64 frac; /* Fraction/Significand/Mantissa */
t_bool s; /* Sticky bit */ t_bool s; /* Sticky bit */
} XFP; } XFP;
typedef struct { typedef struct {
uint32 h; uint32 h;
t_uint64 l; t_uint64 l;
} DEC; } DEC;
/* /*
* Supported rounding modes. * Supported rounding modes.
*/ */
typedef enum { typedef enum {
ROUND_NEAREST, ROUND_NEAREST,
ROUND_PLUS_INF, ROUND_PLUS_INF,
ROUND_MINUS_INF, ROUND_MINUS_INF,
ROUND_ZERO ROUND_ZERO
} RM; } RM;
/* /*
* Double Precision (64 bits) * Double Precision (64 bits)
*/ */
typedef t_uint64 DFP; typedef t_uint64 DFP;
/* /*
* Single Precision (32 bits) * Single Precision (32 bits)
*/ */
typedef uint32 SFP; typedef uint32 SFP;
/* /*
* MAU state * MAU state
*/ */
typedef struct { typedef struct {
uint32 cmd; uint32 cmd;
/* Exception */ /* Exception */
uint32 exception; uint32 exception;
/* Status register */ /* Status register */
uint32 asr; uint32 asr;
t_bool trapping_nan; t_bool trapping_nan;
/* Generate a Non-Trapping NaN */ /* Generate a Non-Trapping NaN */
t_bool ntnan; t_bool ntnan;
/* Source (from broadcast) */ /* Source (from broadcast) */
uint32 src; uint32 src;
/* Destination (from broadcast) */ /* Destination (from broadcast) */
uint32 dst; uint32 dst;
uint8 opcode; uint8 opcode;
uint8 op1; uint8 op1;
uint8 op2; uint8 op2;
uint8 op3; uint8 op3;
/* Data Register */ /* Data Register */
XFP dr; XFP dr;
/* Operand Registers */ /* Operand Registers */
XFP f0; XFP f0;
XFP f1; XFP f1;
XFP f2; XFP f2;
XFP f3; XFP f3;
} MAU_STATE; } MAU_STATE;
t_stat mau_reset(DEVICE *dptr); t_stat mau_reset(DEVICE *dptr);
t_stat mau_attach(UNIT *uptr, CONST char *cptr); t_stat mau_attach(UNIT *uptr, CONST char *cptr);
t_stat mau_detach(UNIT *uptr); t_stat mau_detach(UNIT *uptr);
t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst); t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst);
CONST char *mau_description(DEVICE *dptr); CONST char *mau_description(DEVICE *dptr);
t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst); t_stat mau_broadcast(uint32 cmd, uint32 src, uint32 dst);
#endif /* _3B2_REV2_MAU_H_ */ #endif /* _3B2_REV2_MAU_H_ */

View file

@ -1,346 +1,346 @@
/* 3b2_mem.c: Memory Map Access Routines /* 3b2_mem.c: Memory Map Access Routines
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_mem.h" #include "3b2_mem.h"
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_csr.h" #include "3b2_csr.h"
#include "3b2_io.h" #include "3b2_io.h"
#include "3b2_mmu.h" #include "3b2_mmu.h"
#include "3b2_stddev.h" #include "3b2_stddev.h"
#include "3b2_dmac.h" #include "3b2_dmac.h"
#if defined(REV3) #if defined(REV3)
static uint32 ecc_addr; /* ECC address */ static uint32 ecc_addr; /* ECC address */
static t_bool ecc_err; /* ECC multi-bit error */ static t_bool ecc_err; /* ECC multi-bit error */
#endif #endif
/* /*
* ECC is simulated just enough to pass diagnostics, and no more. * ECC is simulated just enough to pass diagnostics, and no more.
* *
* Checking and setting of ECC syndrome bits is a no-op for Rev 2. * Checking and setting of ECC syndrome bits is a no-op for Rev 2.
*/ */
static SIM_INLINE void check_ecc(uint32 pa, t_bool write, uint8 src) static SIM_INLINE void check_ecc(uint32 pa, t_bool write, uint8 src)
{ {
#if defined(REV3) #if defined(REV3)
/* Force ECC Syndrome mode enables a diagnostic mode on the AM2960 /* Force ECC Syndrome mode enables a diagnostic mode on the AM2960
data correction ICs */ data correction ICs */
if (write && !CSR(CSRFECC)) { if (write && !CSR(CSRFECC)) {
sim_debug(EXECUTE_MSG, &mmu_dev, sim_debug(EXECUTE_MSG, &mmu_dev,
"ECC Error on Write. pa=%08x\n", "ECC Error on Write. pa=%08x\n",
pa); pa);
ecc_addr = pa; ecc_addr = pa;
ecc_err = TRUE; ecc_err = TRUE;
} else if (ecc_err && !write && pa == ecc_addr) { } else if (ecc_err && !write && pa == ecc_addr) {
sim_debug(EXECUTE_MSG, &mmu_dev, sim_debug(EXECUTE_MSG, &mmu_dev,
"ECC Error detected on Read. pa=%08x psw=%08x cur_ipl=%d csr=%08x\n", "ECC Error detected on Read. pa=%08x psw=%08x cur_ipl=%d csr=%08x\n",
pa, R[NUM_PSW], PSW_CUR_IPL, csr_data); pa, R[NUM_PSW], PSW_CUR_IPL, csr_data);
flt[0] = ecc_addr & 0x3ffff; flt[0] = ecc_addr & 0x3ffff;
flt[1] = MA_CPU_IO|MA_CPU_BU; flt[1] = MA_CPU_IO|MA_CPU_BU;
ecc_err = FALSE; ecc_err = FALSE;
CSRBIT(CSRFRF, TRUE); /* Fault registers frozen */ CSRBIT(CSRFRF, TRUE); /* Fault registers frozen */
CSRBIT(CSRMBERR, TRUE); /* Multi-bit error */ CSRBIT(CSRMBERR, TRUE); /* Multi-bit error */
CPU_SET_INT(INT_MBERR); CPU_SET_INT(INT_MBERR);
/* Only abort if CPU is doing the read */ /* Only abort if CPU is doing the read */
if (src == BUS_CPU) { if (src == BUS_CPU) {
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
} }
} }
#endif #endif
} }
/* Read Word (Physical Address) */ /* Read Word (Physical Address) */
uint32 pread_w(uint32 pa, uint8 src) uint32 pread_w(uint32 pa, uint8 src)
{ {
uint8 *m; uint8 *m;
uint32 index = 0; uint32 index = 0;
#if defined(REV3) #if defined(REV3)
if ((pa & 3) && (R[NUM_PSW] & PSW_EA_MASK) == 0) { if ((pa & 3) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
#else #else
if (pa & 3) { if (pa & 3) {
#endif #endif
sim_debug(READ_MSG, &mmu_dev, sim_debug(READ_MSG, &mmu_dev,
"Cannot read physical address. ALIGNMENT ISSUE: %08x\n", "Cannot read physical address. ALIGNMENT ISSUE: %08x\n",
pa); pa);
CSRBIT(CSRALGN, TRUE); CSRBIT(CSRALGN, TRUE);
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
} }
if (IS_IO(pa)) { if (IS_IO(pa)) {
return io_read(pa, 32); return io_read(pa, 32);
} }
if (IS_ROM(pa)) { if (IS_ROM(pa)) {
m = ROM; m = ROM;
index = pa; index = pa;
} else if (IS_RAM(pa)) { } else if (IS_RAM(pa)) {
check_ecc(pa, FALSE, src); check_ecc(pa, FALSE, src);
m = RAM; m = RAM;
index = (pa - PHYS_MEM_BASE); index = (pa - PHYS_MEM_BASE);
} else { } else {
return 0; return 0;
} }
return ATOW(m, index); return ATOW(m, index);
} }
/* /*
* Write Word (Physical Address) * Write Word (Physical Address)
*/ */
void pwrite_w(uint32 pa, uint32 val, uint8 src) void pwrite_w(uint32 pa, uint32 val, uint8 src)
{ {
uint32 index; uint32 index;
if (pa & 3) { if (pa & 3) {
sim_debug(WRITE_MSG, &mmu_dev, sim_debug(WRITE_MSG, &mmu_dev,
"Cannot write physical address. ALIGNMENT ISSUE: %08x\n", "Cannot write physical address. ALIGNMENT ISSUE: %08x\n",
pa); pa);
CSRBIT(CSRALGN, TRUE); CSRBIT(CSRALGN, TRUE);
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
} }
if (IS_IO(pa)) { if (IS_IO(pa)) {
io_write(pa, val, 32); io_write(pa, val, 32);
return; return;
} }
if (IS_RAM(pa)) { if (IS_RAM(pa)) {
check_ecc(pa, TRUE, src); check_ecc(pa, TRUE, src);
index = pa - PHYS_MEM_BASE; index = pa - PHYS_MEM_BASE;
RAM[index] = (val >> 24) & 0xff; RAM[index] = (val >> 24) & 0xff;
RAM[index + 1] = (val >> 16) & 0xff; RAM[index + 1] = (val >> 16) & 0xff;
RAM[index + 2] = (val >> 8) & 0xff; RAM[index + 2] = (val >> 8) & 0xff;
RAM[index + 3] = val & 0xff; RAM[index + 3] = val & 0xff;
return; return;
} }
} }
/* /*
* Read Halfword (Physical Address) * Read Halfword (Physical Address)
*/ */
uint16 pread_h(uint32 pa, uint8 src) uint16 pread_h(uint32 pa, uint8 src)
{ {
uint8 *m; uint8 *m;
uint32 index; uint32 index;
if (pa & 1) { if (pa & 1) {
sim_debug(READ_MSG, &mmu_dev, sim_debug(READ_MSG, &mmu_dev,
"Cannot read physical address. ALIGNMENT ISSUE %08x\n", "Cannot read physical address. ALIGNMENT ISSUE %08x\n",
pa); pa);
CSRBIT(CSRALGN, TRUE); CSRBIT(CSRALGN, TRUE);
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
} }
if (IS_IO(pa)) { if (IS_IO(pa)) {
return (uint16) io_read(pa, 16); return (uint16) io_read(pa, 16);
} }
if (IS_ROM(pa)) { if (IS_ROM(pa)) {
m = ROM; m = ROM;
index = pa; index = pa;
} else if (IS_RAM(pa)) { } else if (IS_RAM(pa)) {
check_ecc(pa, FALSE, src); check_ecc(pa, FALSE, src);
m = RAM; m = RAM;
index = pa - PHYS_MEM_BASE; index = pa - PHYS_MEM_BASE;
} else { } else {
return 0; return 0;
} }
return ATOH(m, index); return ATOH(m, index);
} }
/* /*
* Write Halfword (Physical Address) * Write Halfword (Physical Address)
*/ */
void pwrite_h(uint32 pa, uint16 val, uint8 src) void pwrite_h(uint32 pa, uint16 val, uint8 src)
{ {
uint32 index; uint32 index;
#if defined(REV3) #if defined(REV3)
if ((pa & 1) && (R[NUM_PSW] & PSW_EA_MASK) == 0) { if ((pa & 1) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
#else #else
if (pa & 1) { if (pa & 1) {
#endif #endif
sim_debug(WRITE_MSG, &mmu_dev, sim_debug(WRITE_MSG, &mmu_dev,
"Cannot write physical address %08x, ALIGNMENT ISSUE\n", "Cannot write physical address %08x, ALIGNMENT ISSUE\n",
pa); pa);
CSRBIT(CSRALGN, TRUE); CSRBIT(CSRALGN, TRUE);
} }
if (IS_IO(pa)) { if (IS_IO(pa)) {
io_write(pa, val, 16); io_write(pa, val, 16);
return; return;
} }
if (IS_RAM(pa)) { if (IS_RAM(pa)) {
check_ecc(pa, TRUE, src); check_ecc(pa, TRUE, src);
index = pa - PHYS_MEM_BASE; index = pa - PHYS_MEM_BASE;
RAM[index] = (val >> 8) & 0xff; RAM[index] = (val >> 8) & 0xff;
RAM[index + 1] = val & 0xff; RAM[index + 1] = val & 0xff;
return; return;
} }
} }
/* /*
* Read Byte (Physical Address) * Read Byte (Physical Address)
*/ */
uint8 pread_b(uint32 pa, uint8 src) uint8 pread_b(uint32 pa, uint8 src)
{ {
if (IS_IO(pa)) { if (IS_IO(pa)) {
return (uint8)(io_read(pa, 8)); return (uint8)(io_read(pa, 8));
} }
if (IS_ROM(pa)) { if (IS_ROM(pa)) {
return ROM[pa]; return ROM[pa];
} else if (IS_RAM(pa)) { } else if (IS_RAM(pa)) {
check_ecc(pa, FALSE, src); check_ecc(pa, FALSE, src);
return RAM[pa - PHYS_MEM_BASE]; return RAM[pa - PHYS_MEM_BASE];
} else { } else {
return 0; return 0;
} }
} }
/* Write Byte (Physical Address) */ /* Write Byte (Physical Address) */
void pwrite_b(uint32 pa, uint8 val, uint8 src) void pwrite_b(uint32 pa, uint8 val, uint8 src)
{ {
uint32 index; uint32 index;
if (IS_IO(pa)) { if (IS_IO(pa)) {
io_write(pa, val, 8); io_write(pa, val, 8);
return; return;
} }
if (IS_RAM(pa)) { if (IS_RAM(pa)) {
check_ecc(pa, TRUE, src); check_ecc(pa, TRUE, src);
index = pa - PHYS_MEM_BASE; index = pa - PHYS_MEM_BASE;
RAM[index] = val; RAM[index] = val;
return; return;
} }
} }
/* Write to ROM (used by ROM load) */ /* Write to ROM (used by ROM load) */
void pwrite_b_rom(uint32 pa, uint8 val) { void pwrite_b_rom(uint32 pa, uint8 val) {
if (IS_ROM(pa)) { if (IS_ROM(pa)) {
ROM[pa] = val; ROM[pa] = val;
} }
} }
/* Read Byte (Virtual Address) */ /* Read Byte (Virtual Address) */
uint8 read_b(uint32 va, uint8 r_acc, uint8 src) uint8 read_b(uint32 va, uint8 r_acc, uint8 src)
{ {
return pread_b(mmu_xlate_addr(va, r_acc), src); return pread_b(mmu_xlate_addr(va, r_acc), src);
} }
/* Write Byte (Virtual Address) */ /* Write Byte (Virtual Address) */
void write_b(uint32 va, uint8 val, uint8 src) void write_b(uint32 va, uint8 val, uint8 src)
{ {
pwrite_b(mmu_xlate_addr(va, ACC_W), val, src); pwrite_b(mmu_xlate_addr(va, ACC_W), val, src);
} }
/* Read Halfword (Virtual Address) */ /* Read Halfword (Virtual Address) */
uint16 read_h(uint32 va, uint8 r_acc, uint8 src) uint16 read_h(uint32 va, uint8 r_acc, uint8 src)
{ {
return pread_h(mmu_xlate_addr(va, r_acc), src); return pread_h(mmu_xlate_addr(va, r_acc), src);
} }
/* Write Halfword (Virtual Address) */ /* Write Halfword (Virtual Address) */
void write_h(uint32 va, uint16 val, uint8 src) void write_h(uint32 va, uint16 val, uint8 src)
{ {
pwrite_h(mmu_xlate_addr(va, ACC_W), val, src); pwrite_h(mmu_xlate_addr(va, ACC_W), val, src);
} }
/* Read Word (Virtual Address) */ /* Read Word (Virtual Address) */
uint32 read_w(uint32 va, uint8 r_acc, uint8 src) uint32 read_w(uint32 va, uint8 r_acc, uint8 src)
{ {
return pread_w(mmu_xlate_addr(va, r_acc), src); return pread_w(mmu_xlate_addr(va, r_acc), src);
} }
/* Write Word (Virtual Address) */ /* Write Word (Virtual Address) */
void write_w(uint32 va, uint32 val, uint8 src) void write_w(uint32 va, uint32 val, uint8 src)
{ {
pwrite_w(mmu_xlate_addr(va, ACC_W), val, src); pwrite_w(mmu_xlate_addr(va, ACC_W), val, src);
} }
t_stat read_operand(uint32 va, uint8 *val) t_stat read_operand(uint32 va, uint8 *val)
{ {
uint32 pa; uint32 pa;
t_stat succ; t_stat succ;
succ = mmu_decode_va(va, ACC_IF, TRUE, &pa); succ = mmu_decode_va(va, ACC_IF, TRUE, &pa);
if (succ == SCPE_OK) { if (succ == SCPE_OK) {
*val = pread_b(pa, BUS_CPU); *val = pread_b(pa, BUS_CPU);
} else { } else {
*val = 0; *val = 0;
} }
return succ; return succ;
} }
t_stat examine(uint32 va, uint8 *val) t_stat examine(uint32 va, uint8 *val)
{ {
uint32 pa; uint32 pa;
t_stat succ; t_stat succ;
succ = mmu_decode_va(va, 0, FALSE, &pa); succ = mmu_decode_va(va, 0, FALSE, &pa);
if (succ == SCPE_OK) { if (succ == SCPE_OK) {
if (IS_ROM(pa) || IS_RAM(pa)) { if (IS_ROM(pa) || IS_RAM(pa)) {
*val = pread_b(pa, BUS_CPU); *val = pread_b(pa, BUS_CPU);
return SCPE_OK; return SCPE_OK;
} else { } else {
*val = 0; *val = 0;
return SCPE_NXM; return SCPE_NXM;
} }
} else { } else {
*val = 0; *val = 0;
return succ; return succ;
} }
} }
t_stat deposit(uint32 va, uint8 val) t_stat deposit(uint32 va, uint8 val)
{ {
uint32 pa; uint32 pa;
t_stat succ; t_stat succ;
succ = mmu_decode_va(va, 0, FALSE, &pa); succ = mmu_decode_va(va, 0, FALSE, &pa);
if (succ == SCPE_OK) { if (succ == SCPE_OK) {
if (IS_RAM(pa)) { if (IS_RAM(pa)) {
pwrite_b(pa, val, BUS_CPU); pwrite_b(pa, val, BUS_CPU);
return SCPE_OK; return SCPE_OK;
} else { } else {
return SCPE_NXM; return SCPE_NXM;
} }
} else { } else {
return succ; return succ;
} }
} }

View file

@ -1,79 +1,79 @@
/* 3b2_mem.h: Memory Map Access Routines /* 3b2_mem.h: Memory Map Access Routines
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_MEM_H_ #ifndef _3B2_MEM_H_
#define _3B2_MEM_H_ #define _3B2_MEM_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define IS_ROM(PA) ((PA) < ROM_SIZE) #define IS_ROM(PA) ((PA) < ROM_SIZE)
#define IS_RAM(PA) (((PA) >= PHYS_MEM_BASE) && ((PA) < (PHYS_MEM_BASE + MEM_SIZE))) #define IS_RAM(PA) (((PA) >= PHYS_MEM_BASE) && ((PA) < (PHYS_MEM_BASE + MEM_SIZE)))
#if defined(REV3) #if defined(REV3)
#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \ #define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
((PA >= CIO_BOTTOM) && (PA < CIO_TOP)) || \ ((PA >= CIO_BOTTOM) && (PA < CIO_TOP)) || \
((PA >= VCACHE_BOTTOM) && (PA < VCACHE_TOP)) || \ ((PA >= VCACHE_BOTTOM) && (PA < VCACHE_TOP)) || \
((PA >= BUB_BOTTOM) && (PA < BUB_TOP))) ((PA >= BUB_BOTTOM) && (PA < BUB_TOP)))
#else #else
#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \ #define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
((PA >= CIO_BOTTOM) && (PA < CIO_TOP))) ((PA >= CIO_BOTTOM) && (PA < CIO_TOP)))
#endif #endif
#define MA_BUB3 0x100 /* BUBUS slot 3 master on fault */ #define MA_BUB3 0x100 /* BUBUS slot 3 master on fault */
#define MA_BUB2 0x200 /* BUBUS slot 2 master on fault */ #define MA_BUB2 0x200 /* BUBUS slot 2 master on fault */
#define MA_BUB1 0x400 /* BUBUS slot 1 master on fault */ #define MA_BUB1 0x400 /* BUBUS slot 1 master on fault */
#define MA_CPU_BU 0x2000 /* CPU access BUBUS peripheral */ #define MA_CPU_BU 0x2000 /* CPU access BUBUS peripheral */
#define MA_BUB0 0x4000 /* BUBUS slot 0 master on fault */ #define MA_BUB0 0x4000 /* BUBUS slot 0 master on fault */
#define MA_CPU_IO 0x8000 /* CPU accessing I/O peripheral */ #define MA_CPU_IO 0x8000 /* CPU accessing I/O peripheral */
#define MA_IO_NLY 0x10000 /* IO Bus Master on fault */ #define MA_IO_NLY 0x10000 /* IO Bus Master on fault */
#define MA_IO_BM 0x80000 /* IO Bus Master or BUBUS was master on fault */ #define MA_IO_BM 0x80000 /* IO Bus Master or BUBUS was master on fault */
#define BUS_PER 0 /* Read or Write is from peripheral */ #define BUS_PER 0 /* Read or Write is from peripheral */
#define BUS_CPU 1 /* Read or Write is from CPU */ #define BUS_CPU 1 /* Read or Write is from CPU */
uint32 pread_w(uint32 pa, uint8 src); uint32 pread_w(uint32 pa, uint8 src);
void pwrite_w(uint32 pa, uint32 val, uint8 src); void pwrite_w(uint32 pa, uint32 val, uint8 src);
uint8 pread_b(uint32 pa, uint8 src); uint8 pread_b(uint32 pa, uint8 src);
void pwrite_b(uint32 pa, uint8 val, uint8 src); void pwrite_b(uint32 pa, uint8 val, uint8 src);
void pwrite_b_rom(uint32 pa, uint8 val); void pwrite_b_rom(uint32 pa, uint8 val);
uint16 pread_h(uint32 pa, uint8 src); uint16 pread_h(uint32 pa, uint8 src);
void pwrite_h(uint32 pa, uint16 val, uint8 src); void pwrite_h(uint32 pa, uint16 val, uint8 src);
uint8 read_b(uint32 va, uint8 r_acc, uint8 src); uint8 read_b(uint32 va, uint8 r_acc, uint8 src);
uint16 read_h(uint32 va, uint8 r_acc, uint8 src); uint16 read_h(uint32 va, uint8 r_acc, uint8 src);
uint32 read_w(uint32 va, uint8 r_acc, uint8 src); uint32 read_w(uint32 va, uint8 r_acc, uint8 src);
void write_b(uint32 va, uint8 val, uint8 src); void write_b(uint32 va, uint8 val, uint8 src);
void write_h(uint32 va, uint16 val, uint8 src); void write_h(uint32 va, uint16 val, uint8 src);
void write_w(uint32 va, uint32 val, uint8 src); void write_w(uint32 va, uint32 val, uint8 src);
t_stat read_operand(uint32 va, uint8 *val); t_stat read_operand(uint32 va, uint8 *val);
t_stat examine(uint32 va, uint8 *val); t_stat examine(uint32 va, uint8 *val);
t_stat deposit(uint32 va, uint8 val); t_stat deposit(uint32 va, uint8 val);
#endif /* _3B2_MEM_H_ */ #endif /* _3B2_MEM_H_ */

View file

@ -1,40 +1,40 @@
/* 3b2_mmu.h: Common MMU header /* 3b2_mmu.h: Common MMU header
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_MMU_H_ #ifndef _3B2_MMU_H_
#define _3B2_MMU_H_ #define _3B2_MMU_H_
#if defined(REV3) #if defined(REV3)
#include "3b2_rev3_mmu.h" #include "3b2_rev3_mmu.h"
#else #else
#include "3b2_rev2_mmu.h" #include "3b2_rev2_mmu.h"
#endif #endif
#endif /* _3B2_MMU_H_ */ #endif /* _3B2_MMU_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,210 +1,210 @@
/* 3b2_ni.h: CM195A Network Interface CIO Card /* 3b2_ni.h: CM195A Network Interface CIO Card
Copyright (c) 2018-2022, Seth J. Morabito Copyright (c) 2018-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_NI_H_ #ifndef _3B2_NI_H_
#define _3B2_NI_H_ #define _3B2_NI_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#include "sim_ether.h" #include "sim_ether.h"
#define NI_ID 0x0002 #define NI_ID 0x0002
#define NI_IPL 12 #define NI_IPL 12
/* Opcodes for NI card */ /* Opcodes for NI card */
#define NI_SETID 6 #define NI_SETID 6
#define NI_TURNOFF 7 #define NI_TURNOFF 7
#define NI_TURNON 8 #define NI_TURNON 8
#define NI_SEND 11 #define NI_SEND 11
#define NI_RECV 12 #define NI_RECV 12
#define NI_STATS 13 #define NI_STATS 13
#define NI_SANITY 15 #define NI_SANITY 15
#define NI_SEND_A 22 #define NI_SEND_A 22
#define MAC_SIZE_BYTES 6 #define MAC_SIZE_BYTES 6
#define MAC_SIZE_CHARS 20 #define MAC_SIZE_CHARS 20
#define NIQESIZE 12 #define NIQESIZE 12
#define NI_QUE_MAX 1024 #define NI_QUE_MAX 1024
#define NI_INT_DELAY 10000 #define NI_INT_DELAY 10000
#define NI_SANITY_INTERVAL_US 5000000 #define NI_SANITY_INTERVAL_US 5000000
/* Maximum allowed number of multicast addresses */ /* Maximum allowed number of multicast addresses */
#define NI_MULTI_MAX 64 #define NI_MULTI_MAX 64
/* At least two filter addresses are always configured: /* At least two filter addresses are always configured:
* 1. The host MAC * 1. The host MAC
* 2. The broadcast address */ * 2. The broadcast address */
#define NI_FILTER_MIN 2 #define NI_FILTER_MIN 2
/* Maximum total allowed number of filter addresses, including the /* Maximum total allowed number of filter addresses, including the
* host's MAC and the broadcast address. */ * host's MAC and the broadcast address. */
#define NI_FILTER_MAX NI_MULTI_MAX + NI_FILTER_MIN #define NI_FILTER_MAX NI_MULTI_MAX + NI_FILTER_MIN
/* Indexes in the internal filter address table of the /* Indexes in the internal filter address table of the
* host's MAC and the broadcast address */ * host's MAC and the broadcast address */
#define NI_NIC_MAC 0 #define NI_NIC_MAC 0
#define NI_BCST_MAC 1 #define NI_BCST_MAC 1
/* /*
* For performance reasons, there are two modes of polling the receive * For performance reasons, there are two modes of polling the receive
* queues. Initially, polling is VERY aggressive as we race the * queues. Initially, polling is VERY aggressive as we race the
* filling of the receive queues. Once we've taken three jobs from * filling of the receive queues. Once we've taken three jobs from
* each of the two receive queues, we switch to slow polling, * each of the two receive queues, we switch to slow polling,
* which uses coscheduling. * which uses coscheduling.
*/ */
#define NI_QPOLL_FAST 100 #define NI_QPOLL_FAST 100
#define NI_QPOLL_SLOW 50000 #define NI_QPOLL_SLOW 50000
#define EIG_TABLE_SIZE 40 #define EIG_TABLE_SIZE 40
#define PKT_HEADER_LEN_OFFSET EIG_TABLE_SIZE #define PKT_HEADER_LEN_OFFSET EIG_TABLE_SIZE
#define PKT_START_OFFSET (PKT_HEADER_LEN_OFFSET + 4) #define PKT_START_OFFSET (PKT_HEADER_LEN_OFFSET + 4)
/* /*
* The NI card has two request queues for packet receive: One for * The NI card has two request queues for packet receive: One for
* small packets, and one for large packets. The small queue is meant * small packets, and one for large packets. The small queue is meant
* for packets smaller than 128 bytes. The large queue is meant for * for packets smaller than 128 bytes. The large queue is meant for
* packets up to 1500 bytes (no jumbo frames allowed) * packets up to 1500 bytes (no jumbo frames allowed)
*/ */
#define GE_QUEUE 0 /* General request CIO queue */ #define GE_QUEUE 0 /* General request CIO queue */
#define SM_QUEUE 0 /* Small packet receive queue number */ #define SM_QUEUE 0 /* Small packet receive queue number */
#define LG_QUEUE 1 /* Large packet receive queue number */ #define LG_QUEUE 1 /* Large packet receive queue number */
#define SM_PKT_MAX 106 /* Max size of small packets (excluding CRC) */ #define SM_PKT_MAX 106 /* Max size of small packets (excluding CRC) */
#define LG_PKT_MAX 1514 /* Max size of large packets (excluding CRC) */ #define LG_PKT_MAX 1514 /* Max size of large packets (excluding CRC) */
/* /*
* NI-specific debugging flags * NI-specific debugging flags
*/ */
#define DBG_TRACE 0x01 #define DBG_TRACE 0x01
#define DBG_IO 0x02 #define DBG_IO 0x02
#define DBG_CACHE 0x04 #define DBG_CACHE 0x04
#define DBG_DAT 0x08 #define DBG_DAT 0x08
#define DBG_ERR 0x10 #define DBG_ERR 0x10
#define DBG_ETH 0x20 #define DBG_ETH 0x20
#define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.') #define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.')
#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp) #define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp)
/* Determine whether both job caches have available slots */ /* Determine whether both job caches have available slots */
#define NI_BUFFERS_AVAIL ((ni.job_cache[0].wp != ni.job_cache[0].rp) && \ #define NI_BUFFERS_AVAIL ((ni.job_cache[0].wp != ni.job_cache[0].rp) && \
(ni.job_cache[1].wp != ni.job_cache[1].rp)) (ni.job_cache[1].wp != ni.job_cache[1].rp))
/* /*
* The NI card caches up to three jobs taken from each of the two * The NI card caches up to three jobs taken from each of the two
* packet receive queues so that they are available immediately after * packet receive queues so that they are available immediately after
* receipt of a packet. These jobs are kept in small circular buffers. * receipt of a packet. These jobs are kept in small circular buffers.
* Each job is represented by an ni_rec_job structure, containing a * Each job is represented by an ni_rec_job structure, containing a
* buffer pointer and a slot number. The slot number is used by both * buffer pointer and a slot number. The slot number is used by both
* the driver and the firmware to correlate a packet receive buffer * the driver and the firmware to correlate a packet receive buffer
* with a completion queue event. * with a completion queue event.
*/ */
typedef struct { typedef struct {
uint32 addr; /* address of job's buffer */ uint32 addr; /* address of job's buffer */
uint8 slot; /* slot number of the job */ uint8 slot; /* slot number of the job */
} ni_rec_job; } ni_rec_job;
#define NI_CACHE_LEN 4 #define NI_CACHE_LEN 4
typedef struct { typedef struct {
ni_rec_job req[NI_CACHE_LEN]; /* the cache */ ni_rec_job req[NI_CACHE_LEN]; /* the cache */
int wp; /* write pointer */ int wp; /* write pointer */
int rp; /* read pointer */ int rp; /* read pointer */
} ni_job_cache; } ni_job_cache;
/* /*
* When the NI driver submits a packet send request to the general * When the NI driver submits a packet send request to the general
* request queue, it constructs one or more ni_prot_info structs in * request queue, it constructs one or more ni_prot_info structs in
* main memory that point to the protocol-specific byte data of the * main memory that point to the protocol-specific byte data of the
* packet (minus the Ethernet frame). These structs are packed one * packet (minus the Ethernet frame). These structs are packed one
* after the other following the Ethernet frame header in the job's * after the other following the Ethernet frame header in the job's
* request buffer. The last entry has its "last" bit set to non-zero. * request buffer. The last entry has its "last" bit set to non-zero.
*/ */
typedef struct { typedef struct {
uint32 addr; /* Physical address of the buffer in system RAM */ uint32 addr; /* Physical address of the buffer in system RAM */
uint16 size; /* Length of the buffer */ uint16 size; /* Length of the buffer */
uint16 last; /* Is this the last entry in the list? */ uint16 last; /* Is this the last entry in the list? */
} ni_prot_info; } ni_prot_info;
typedef struct { typedef struct {
uint32 rq_taken; uint32 rq_taken;
uint32 tx_fail; uint32 tx_fail;
uint32 rx_dropped; uint32 rx_dropped;
uint32 rx_pkt; uint32 rx_pkt;
uint32 tx_pkt; uint32 tx_pkt;
uint32 rx_bytes; uint32 rx_bytes;
uint32 tx_bytes; uint32 tx_bytes;
} ni_stat_info; } ni_stat_info;
typedef struct { typedef struct {
uint8 slot; uint8 slot;
t_bool enabled; t_bool enabled;
uint32 crc; uint32 crc;
uint32 poll_rate; uint32 poll_rate;
char mac_str[MAC_SIZE_CHARS]; char mac_str[MAC_SIZE_CHARS];
uint8 mac_bytes[MAC_SIZE_BYTES]; uint8 mac_bytes[MAC_SIZE_BYTES];
ni_job_cache job_cache[2]; ni_job_cache job_cache[2];
ni_prot_info prot; ni_prot_info prot;
ni_stat_info stats; ni_stat_info stats;
uint8 fcf_seq; uint8 fcf_seq;
ETH_DEV* eth; ETH_DEV* eth;
ETH_PACK rd_buf; ETH_PACK rd_buf;
ETH_PACK wr_buf; ETH_PACK wr_buf;
ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */ ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */
int filter_count; /* Number of filters available */ int filter_count; /* Number of filters available */
ETH_PCALLBACK callback; ETH_PCALLBACK callback;
} NI_STATE; } NI_STATE;
void ni_recv_callback(int status); void ni_recv_callback(int status);
t_stat ni_reset(DEVICE *dptr); t_stat ni_reset(DEVICE *dptr);
t_stat ni_rcv_svc(UNIT *uptr); t_stat ni_rcv_svc(UNIT *uptr);
t_stat ni_sanity_svc(UNIT *uptr); t_stat ni_sanity_svc(UNIT *uptr);
t_stat ni_rq_svc(UNIT *uptr); t_stat ni_rq_svc(UNIT *uptr);
t_stat ni_cio_svc(UNIT *uptr); t_stat ni_cio_svc(UNIT *uptr);
t_stat ni_attach(UNIT *uptr, CONST char *cptr); t_stat ni_attach(UNIT *uptr, CONST char *cptr);
t_stat ni_detach(UNIT *uptr); t_stat ni_detach(UNIT *uptr);
t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc); t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ni_try_job(uint8 slot); t_stat ni_try_job(uint8 slot);
t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
const char *ni_description(DEVICE *dptr); const char *ni_description(DEVICE *dptr);
t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
void ni_cio_reset(uint8 slot); void ni_cio_reset(uint8 slot);
void ni_process_packet(); void ni_process_packet();
void ni_int_ack(uint8 slot); void ni_int_ack(uint8 slot);
void ni_sysgen(uint8 slot); void ni_sysgen(uint8 slot);
void ni_express(uint8 slot); void ni_express(uint8 slot);
void ni_full(uint8 slot); void ni_full(uint8 slot);
#endif /* _3B2_NI_H_ */ #endif /* _3B2_NI_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,229 +1,229 @@
/* 3b2_ports.h: CM195B 4-Port Serial CIO Card /* 3b2_ports.h: CM195B 4-Port Serial CIO Card
Copyright (c) 2018-2022, Seth J. Morabito Copyright (c) 2018-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
/* /*
* PORTS is an intelligent feature card for the 3B2 that supports four * PORTS is an intelligent feature card for the 3B2 that supports four
* serial lines and one Centronics parallel port. * serial lines and one Centronics parallel port.
* *
* The PORTS card is based on the Common I/O (CIO) platform. It uses * The PORTS card is based on the Common I/O (CIO) platform. It uses
* two SCN2681A DUARTs to supply the four serial lines, and uses the * two SCN2681A DUARTs to supply the four serial lines, and uses the
* SCN2681A parallel I/O pins for the Centronics parallel port. * SCN2681A parallel I/O pins for the Centronics parallel port.
* *
* This file implements the required logic for the PORTS CIO * This file implements the required logic for the PORTS CIO
* interface. The SCN2681A functionality is implemented in the file * interface. The SCN2681A functionality is implemented in the file
* 3b2_duart.c, and is used by both this feature card and the System * 3b2_duart.c, and is used by both this feature card and the System
* Board console/contty functionality. * Board console/contty functionality.
*/ */
#ifndef _3B2_PORTS_H_ #ifndef _3B2_PORTS_H_
#define _3B2_PORTS_H_ #define _3B2_PORTS_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define PORTS_ID 0x0003 #define PORTS_ID 0x0003
#define PORTS_IPL 10 #define PORTS_IPL 10
#define PORTS_VERSION 1 #define PORTS_VERSION 1
#define MAX_CARDS 8 /* Up to 8 PORTS cards with 32 lines total #define MAX_CARDS 8 /* Up to 8 PORTS cards with 32 lines total
supported */ supported */
#define PORTS_LINES 4 #define PORTS_LINES 4
#define PORTS_RCV_QUEUE 5 #define PORTS_RCV_QUEUE 5
/* /*
* Sub-field values for the PPC_DEVICE request entry; these are placed * Sub-field values for the PPC_DEVICE request entry; these are placed
* in app_data.bt[0] in the PPC_DEVICE application field. The prefix * in app_data.bt[0] in the PPC_DEVICE application field. The prefix
* DR indicates that this is a code for use in "device" request * DR indicates that this is a code for use in "device" request
* entries only. * entries only.
*/ */
#define DR_ENA 1 /* enable a device */ #define DR_ENA 1 /* enable a device */
#define DR_DIS 2 /* disable a device */ #define DR_DIS 2 /* disable a device */
#define DR_ABR 3 /* abort reception on a device */ #define DR_ABR 3 /* abort reception on a device */
#define DR_ABX 4 /* abort transmission on a device */ #define DR_ABX 4 /* abort transmission on a device */
#define DR_BRK 5 /* transmit "break" on a device */ #define DR_BRK 5 /* transmit "break" on a device */
#define DR_SUS 6 /* suspend xmit on a device */ #define DR_SUS 6 /* suspend xmit on a device */
#define DR_RES 7 /* resume xmit on a device */ #define DR_RES 7 /* resume xmit on a device */
#define DR_BLK 8 /* transmit STOP character */ #define DR_BLK 8 /* transmit STOP character */
#define DR_UNB 9 /* transmit START character */ #define DR_UNB 9 /* transmit START character */
/* /*
* Sub-field values for the PPC_DEVICE completion entry; these appear * Sub-field values for the PPC_DEVICE completion entry; these appear
* in app_data.bt[0] in the PPC_DEVICE application field. These are * in app_data.bt[0] in the PPC_DEVICE application field. These are
* mutually exclusive and cannot be combined. The prefix DC indicates * mutually exclusive and cannot be combined. The prefix DC indicates
* that this is a code for use in "device" completion entries only. * that this is a code for use in "device" completion entries only.
*/ */
#define DC_NORM 0x00 /* command executed as requested */ #define DC_NORM 0x00 /* command executed as requested */
#define DC_DEV 0x01 /* bad device number */ #define DC_DEV 0x01 /* bad device number */
#define DC_NON 0x02 /* bad sub-code on request */ #define DC_NON 0x02 /* bad sub-code on request */
#define DC_FAIL 0x03 /* failed to read express entry */ #define DC_FAIL 0x03 /* failed to read express entry */
/* /*
* Sub-field values for the PPC_RECV completion entry; these appear in * Sub-field values for the PPC_RECV completion entry; these appear in
* app_data.bt[0] in the PPC_RECV application field. These are NOT * app_data.bt[0] in the PPC_RECV application field. These are NOT
* mutually exclusive and may appear in combination. The prefix RC * mutually exclusive and may appear in combination. The prefix RC
* indicates that this is a code for use in "read" completion entries * indicates that this is a code for use in "read" completion entries
* only. * only.
*/ */
#define RC_DSR 0x01 /* disruption of service */ #define RC_DSR 0x01 /* disruption of service */
#define RC_FLU 0x02 /* buffer flushed */ #define RC_FLU 0x02 /* buffer flushed */
#define RC_TMR 0x04 /* inter-character timer expired */ #define RC_TMR 0x04 /* inter-character timer expired */
#define RC_BQO 0x08 /* PPC buffer queue overflow */ #define RC_BQO 0x08 /* PPC buffer queue overflow */
#define RC_UAO 0x10 /* uart overrun */ #define RC_UAO 0x10 /* uart overrun */
#define RC_PAR 0x20 /* parity error */ #define RC_PAR 0x20 /* parity error */
#define RC_FRA 0x40 /* framing error */ #define RC_FRA 0x40 /* framing error */
#define RC_BRK 0x80 /* break received */ #define RC_BRK 0x80 /* break received */
/* /*
* The following codes are included on the DISC (disconnect) command. * The following codes are included on the DISC (disconnect) command.
* They are "or"ed into the app_data.bt[1] application field in a * They are "or"ed into the app_data.bt[1] application field in a
* request. These codes are NOT mutually exclusive and can be used in * request. These codes are NOT mutually exclusive and can be used in
* any combination. * any combination.
*/ */
#define GR_DTR 0x01 #define GR_DTR 0x01
#define GR_CREAD 0x02 #define GR_CREAD 0x02
/* /*
* Sub-field values for the PPC_XMIT and PPC_OPTIONS completion * Sub-field values for the PPC_XMIT and PPC_OPTIONS completion
* entries; these appear in app_data.bt[0] in the application fields. * entries; these appear in app_data.bt[0] in the application fields.
* These are NOT mutually exclusive and may appear in combination. * These are NOT mutually exclusive and may appear in combination.
* The prefix GC indicates that this is a code for use in "general" * The prefix GC indicates that this is a code for use in "general"
* completion entries only. * completion entries only.
*/ */
#define GC_DSR 0x01 /* disruption of service */ #define GC_DSR 0x01 /* disruption of service */
#define GC_FLU 0x02 /* buffer flushed */ #define GC_FLU 0x02 /* buffer flushed */
/* /*
* Sub-field values for the PPC_ASYNC completion entry; these appear * Sub-field values for the PPC_ASYNC completion entry; these appear
* in app_data.bt[0] in the PPC_ASYNC application field. These are * in app_data.bt[0] in the PPC_ASYNC application field. These are
* mutually exclusive and cannot be combined. The prefix AC indicates * mutually exclusive and cannot be combined. The prefix AC indicates
* that this is a code for use in "asynchronous" completion entries * that this is a code for use in "asynchronous" completion entries
* only. * only.
*/ */
#define AC_CON 0x01 /* connection detected */ #define AC_CON 0x01 /* connection detected */
#define AC_DIS 0x02 /* disconnection detected */ #define AC_DIS 0x02 /* disconnection detected */
#define AC_BRK 0x03 /* asynchronous "break" */ #define AC_BRK 0x03 /* asynchronous "break" */
#define AC_FLU 0x04 /* xmit flush complete */ #define AC_FLU 0x04 /* xmit flush complete */
/* Line Discipline flags (input and output) */ /* Line Discipline flags (input and output) */
#define IGNBRK 0x0001 #define IGNBRK 0x0001
#define BRKINT 0x0002 #define BRKINT 0x0002
#define IGNPAR 0x0004 #define IGNPAR 0x0004
#define PARMRK 0x0008 #define PARMRK 0x0008
#define INPCK 0x0010 #define INPCK 0x0010
#define ISTRIP 0x0020 #define ISTRIP 0x0020
#define INLCR 0x0040 #define INLCR 0x0040
#define IGNCR 0x0080 #define IGNCR 0x0080
#define ICRNL 0x0100 #define ICRNL 0x0100
#define IUCLC 0x0200 #define IUCLC 0x0200
#define IXON 0x0400 #define IXON 0x0400
#define IXANY 0x0800 #define IXANY 0x0800
#define OPOST 0x0001 #define OPOST 0x0001
#define OLCUC 0x0002 #define OLCUC 0x0002
#define ONLCR 0x0004 #define ONLCR 0x0004
#define OCRNL 0x0008 #define OCRNL 0x0008
#define ONOCR 0x0010 #define ONOCR 0x0010
#define ONLRET 0x0020 #define ONLRET 0x0020
#define OFILL 0x0040 #define OFILL 0x0040
#define OFDEL 0x0080 #define OFDEL 0x0080
#define ONLDLY 0x0100 #define ONLDLY 0x0100
#define OCRDLY 0x0600 #define OCRDLY 0x0600
#define OTABDLY 0x1800 #define OTABDLY 0x1800
#define OBSDLY 0x2000 #define OBSDLY 0x2000
#define OVTDLY 0x4000 #define OVTDLY 0x4000
#define OFFDLY 0x8000 #define OFFDLY 0x8000
/* Opcodes for PORTS card */ /* Opcodes for PORTS card */
#define PPC_OPTIONS 32 /* GEN, COMP queues: set PPC options */ #define PPC_OPTIONS 32 /* GEN, COMP queues: set PPC options */
#define PPC_XMIT 33 /* GEN, COMP queues: transmit a buffer */ #define PPC_XMIT 33 /* GEN, COMP queues: transmit a buffer */
#define PPC_CONN 34 /* GEN, COMP queues: connect a device */ #define PPC_CONN 34 /* GEN, COMP queues: connect a device */
#define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */ #define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */
#define PPC_BRK 36 /* GEN, COMP queues: ioctl break */ #define PPC_BRK 36 /* GEN, COMP queues: ioctl break */
#define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */ #define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */
#define PPC_CLR 41 /* EXP, ECOMP entries: board clear */ #define PPC_CLR 41 /* EXP, ECOMP entries: board clear */
#define PPC_RECV 50 /* RECV, COMP queues: receive request */ #define PPC_RECV 50 /* RECV, COMP queues: receive request */
#define PPC_ASYNC 60 /* Asynchronous request */ #define PPC_ASYNC 60 /* Asynchronous request */
#define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */ #define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */
#define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */ #define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */
#define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */ #define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */
#define CFW_WRITE 73 /* GEN, COMP queues: write */ #define CFW_WRITE 73 /* GEN, COMP queues: write */
#define PPC_VERS 80 /* EXP, COMP queues: Version */ #define PPC_VERS 80 /* EXP, COMP queues: Version */
typedef struct { typedef struct {
uint32 tx_addr; /* Address to next read from */ uint32 tx_addr; /* Address to next read from */
uint32 tx_req_addr; /* Original request address */ uint32 tx_req_addr; /* Original request address */
uint32 tx_chars; /* Number of chars left to transfer */ uint32 tx_chars; /* Number of chars left to transfer */
uint32 tx_req_chars; /* Original number of chars */ uint32 tx_req_chars; /* Original number of chars */
uint8 rlp; /* Last known load pointer */ uint8 rlp; /* Last known load pointer */
uint16 iflag; /* Line Discipline: Input flags */ uint16 iflag; /* Line Discipline: Input flags */
uint16 oflag; /* Line Discipline: Output flags */ uint16 oflag; /* Line Discipline: Output flags */
t_bool crlf; /* Indicates we are in a CRLF output transform */ t_bool crlf; /* Indicates we are in a CRLF output transform */
t_bool conn; /* TRUE if connected, FALSE otherwise */ t_bool conn; /* TRUE if connected, FALSE otherwise */
} PORTS_LINE_STATE; } PORTS_LINE_STATE;
typedef struct { typedef struct {
uint16 line; /* line discipline */ uint16 line; /* line discipline */
uint16 pad1; uint16 pad1;
uint16 iflag; /* input options word */ uint16 iflag; /* input options word */
uint16 oflag; /* output options word */ uint16 oflag; /* output options word */
uint16 cflag; /* hardware options */ uint16 cflag; /* hardware options */
uint16 lflag; /* line discipline options */ uint16 lflag; /* line discipline options */
uint8 cerase; /* "erase" character */ uint8 cerase; /* "erase" character */
uint8 ckill; /* "kill" character */ uint8 ckill; /* "kill" character */
uint8 cinter; /* "interrupt" character */ uint8 cinter; /* "interrupt" character */
uint8 cquit; /* "quit" character */ uint8 cquit; /* "quit" character */
uint8 ceof; /* "end of file" character */ uint8 ceof; /* "end of file" character */
uint8 ceol; /* "end of line" character */ uint8 ceol; /* "end of line" character */
uint8 itime; /* inter character timer multiplier */ uint8 itime; /* inter character timer multiplier */
uint8 vtime; /* user-specified inter char timer */ uint8 vtime; /* user-specified inter char timer */
uint8 vcount; /* user-specified maximum buffer char count */ uint8 vcount; /* user-specified maximum buffer char count */
uint8 pad2; uint8 pad2;
uint16 pad3; uint16 pad3;
} PORTS_OPTIONS; } PORTS_OPTIONS;
t_stat ports_reset(DEVICE *dptr); t_stat ports_reset(DEVICE *dptr);
t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat ports_rcv_svc(UNIT *uptr); t_stat ports_rcv_svc(UNIT *uptr);
t_stat ports_xmt_svc(UNIT *uptr); t_stat ports_xmt_svc(UNIT *uptr);
t_stat ports_cio_svc(UNIT *uptr); t_stat ports_cio_svc(UNIT *uptr);
t_stat ports_attach(UNIT *uptr, CONST char *cptr); t_stat ports_attach(UNIT *uptr, CONST char *cptr);
t_stat ports_detach(UNIT *uptr); t_stat ports_detach(UNIT *uptr);
void ports_sysgen(uint8 slot); void ports_sysgen(uint8 slot);
void ports_express(uint8 slot); void ports_express(uint8 slot);
void ports_full(uint8 slot); void ports_full(uint8 slot);
#endif /* _3B2_PORTS_H_ */ #endif /* _3B2_PORTS_H_ */

View file

@ -1,182 +1,182 @@
/* 3b2_rev2_csr.c: ED System Board Control and Status Register /* 3b2_rev2_csr.c: ED System Board Control and Status Register
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_rev2_csr.h" #include "3b2_rev2_csr.h"
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_sys.h" #include "3b2_sys.h"
#include "3b2_timer.h" #include "3b2_timer.h"
#include "3b2_sys.h" #include "3b2_sys.h"
CSR_DATA csr_data; CSR_DATA csr_data;
BITFIELD csr_bits[] = { BITFIELD csr_bits[] = {
BIT(IOF), BIT(IOF),
BIT(DMA), BIT(DMA),
BIT(DISK), BIT(DISK),
BIT(UART), BIT(UART),
BIT(PIR9), BIT(PIR9),
BIT(PIR8), BIT(PIR8),
BIT(CLK), BIT(CLK),
BIT(IFLT), BIT(IFLT),
BIT(ITIM), BIT(ITIM),
BIT(FLOP), BIT(FLOP),
BIT(NA), BIT(NA),
BIT(LED), BIT(LED),
BIT(ALGN), BIT(ALGN),
BIT(RRST), BIT(RRST),
BIT(PARE), BIT(PARE),
BIT(TIMO), BIT(TIMO),
ENDBITS ENDBITS
}; };
UNIT csr_unit = { UNIT csr_unit = {
UDATA(NULL, UNIT_FIX, CSRSIZE) UDATA(NULL, UNIT_FIX, CSRSIZE)
}; };
REG csr_reg[] = { REG csr_reg[] = {
{ HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) }, { HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) },
{ NULL } { NULL }
}; };
DEVICE csr_dev = { DEVICE csr_dev = {
"CSR", &csr_unit, csr_reg, NULL, "CSR", &csr_unit, csr_reg, NULL,
1, 16, 8, 4, 16, 32, 1, 16, 8, 4, 16, 32,
&csr_ex, &csr_dep, &csr_reset, &csr_ex, &csr_dep, &csr_reset,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
DEV_DEBUG, 0, sys_deb_tab DEV_DEBUG, 0, sys_deb_tab
}; };
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{ {
return SCPE_OK; return SCPE_OK;
} }
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw)
{ {
return SCPE_OK; return SCPE_OK;
} }
t_stat csr_reset(DEVICE *dptr) t_stat csr_reset(DEVICE *dptr)
{ {
csr_data = 0; csr_data = 0;
return SCPE_OK; return SCPE_OK;
} }
uint32 csr_read(uint32 pa, size_t size) uint32 csr_read(uint32 pa, size_t size)
{ {
uint32 reg = pa - CSRBASE; uint32 reg = pa - CSRBASE;
sim_debug(READ_MSG, &csr_dev, sim_debug(READ_MSG, &csr_dev,
"CSR=%04x\n", "CSR=%04x\n",
csr_data); csr_data);
switch (reg) { switch (reg) {
case 0x2: case 0x2:
if (size == 8) { if (size == 8) {
return (csr_data >> 8) & 0xff; return (csr_data >> 8) & 0xff;
} else { } else {
return csr_data; return csr_data;
} }
case 0x3: case 0x3:
return csr_data & 0xff; return csr_data & 0xff;
default: default:
return 0; return 0;
} }
} }
void csr_write(uint32 pa, uint32 val, size_t size) void csr_write(uint32 pa, uint32 val, size_t size)
{ {
uint32 reg = pa - CSRBASE; uint32 reg = pa - CSRBASE;
switch (reg) { switch (reg) {
case 0x03: /* Clear Bus Timeout Error */ case 0x03: /* Clear Bus Timeout Error */
csr_data &= ~CSRTIMO; csr_data &= ~CSRTIMO;
break; break;
case 0x07: /* Clear Memory Parity Error */ case 0x07: /* Clear Memory Parity Error */
csr_data &= ~CSRPARE; csr_data &= ~CSRPARE;
break; break;
case 0x0b: /* Set System Reset Request */ case 0x0b: /* Set System Reset Request */
full_reset(); full_reset();
cpu_boot(0, &cpu_dev); cpu_boot(0, &cpu_dev);
break; break;
case 0x0f: /* Clear Memory Alignment Fault */ case 0x0f: /* Clear Memory Alignment Fault */
csr_data &= ~CSRALGN; csr_data &= ~CSRALGN;
break; break;
case 0x13: /* Set Failure LED */ case 0x13: /* Set Failure LED */
csr_data |= CSRLED; csr_data |= CSRLED;
break; break;
case 0x17: /* Clear Failure LED */ case 0x17: /* Clear Failure LED */
csr_data &= ~CSRLED; csr_data &= ~CSRLED;
break; break;
case 0x1b: /* Set Floppy Motor On */ case 0x1b: /* Set Floppy Motor On */
csr_data |= CSRFLOP; csr_data |= CSRFLOP;
break; break;
case 0x1f: /* Clear Floppy Motor On */ case 0x1f: /* Clear Floppy Motor On */
csr_data &= ~CSRFLOP; csr_data &= ~CSRFLOP;
break; break;
case 0x23: /* Set Inhibit Timers */ case 0x23: /* Set Inhibit Timers */
sim_debug(WRITE_MSG, &csr_dev, sim_debug(WRITE_MSG, &csr_dev,
"SET INHIBIT TIMERS\n"); "SET INHIBIT TIMERS\n");
csr_data |= CSRITIM; csr_data |= CSRITIM;
timer_gate(TIMER_INTERVAL, TRUE); timer_gate(TIMER_INTERVAL, TRUE);
break; break;
case 0x27: /* Clear Inhibit Timers */ case 0x27: /* Clear Inhibit Timers */
sim_debug(WRITE_MSG, &csr_dev, sim_debug(WRITE_MSG, &csr_dev,
"CLEAR INHIBIT TIMERS\n"); "CLEAR INHIBIT TIMERS\n");
csr_data &= ~CSRITIM; csr_data &= ~CSRITIM;
timer_gate(TIMER_INTERVAL, FALSE); timer_gate(TIMER_INTERVAL, FALSE);
break; break;
case 0x2b: /* Set Inhibit Faults */ case 0x2b: /* Set Inhibit Faults */
csr_data |= CSRIFLT; csr_data |= CSRIFLT;
break; break;
case 0x2f: /* Clear Inhibit Faults */ case 0x2f: /* Clear Inhibit Faults */
csr_data &= ~CSRIFLT; csr_data &= ~CSRIFLT;
break; break;
case 0x33: /* Set PIR9 */ case 0x33: /* Set PIR9 */
csr_data |= CSRPIR9; csr_data |= CSRPIR9;
CPU_SET_INT(INT_PIR9); CPU_SET_INT(INT_PIR9);
break; break;
case 0x37: /* Clear PIR9 */ case 0x37: /* Clear PIR9 */
csr_data &= ~CSRPIR9; csr_data &= ~CSRPIR9;
CPU_CLR_INT(INT_PIR9); CPU_CLR_INT(INT_PIR9);
break; break;
case 0x3b: /* Set PIR8 */ case 0x3b: /* Set PIR8 */
csr_data |= CSRPIR8; csr_data |= CSRPIR8;
CPU_SET_INT(INT_PIR8); CPU_SET_INT(INT_PIR8);
break; break;
case 0x3f: /* Clear PIR8 */ case 0x3f: /* Clear PIR8 */
csr_data &= ~CSRPIR8; csr_data &= ~CSRPIR8;
CPU_CLR_INT(INT_PIR8); CPU_CLR_INT(INT_PIR8);
break; break;
default: default:
break; break;
} }
} }

View file

@ -1,46 +1,46 @@
/* 3b2_rev2_csr.h: ED System Board Control and Status Register /* 3b2_rev2_csr.h: ED System Board Control and Status Register
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_REV2_CSR_H_ #ifndef _3B2_REV2_CSR_H_
#define _3B2_REV2_CSR_H_ #define _3B2_REV2_CSR_H_
#include "3b2_defs.h" #include "3b2_defs.h"
typedef uint16 CSR_DATA; typedef uint16 CSR_DATA;
/* CSR */ /* CSR */
t_stat csr_svc(UNIT *uptr); t_stat csr_svc(UNIT *uptr);
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat csr_reset(DEVICE *dptr); t_stat csr_reset(DEVICE *dptr);
uint32 csr_read(uint32 pa, size_t size); uint32 csr_read(uint32 pa, size_t size);
void csr_write(uint32 pa, uint32 val, size_t size); void csr_write(uint32 pa, uint32 val, size_t size);
#endif /* 3B2_REV2_CSR_H_ */ #endif /* 3B2_REV2_CSR_H_ */

View file

@ -1,132 +1,132 @@
/* 3b2_rev2_defs.h: Version 2 (3B2/400) Common Definitions /* 3b2_rev2_defs.h: Version 2 (3B2/400) Common Definitions
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_REV2_DEFS_H_ #ifndef _3B2_REV2_DEFS_H_
#define _3B2_REV2_DEFS_H_ #define _3B2_REV2_DEFS_H_
#define NUM_REGISTERS 16 #define NUM_REGISTERS 16
#define DEFMEMSIZE MSIZ_4M #define DEFMEMSIZE MSIZ_4M
#define MAXMEMSIZE MSIZ_4M #define MAXMEMSIZE MSIZ_4M
#define HWORD_OP_COUNT 11 #define HWORD_OP_COUNT 11
#define CPU_VERSION 0x1A /* Version encoded in WE32100 */ #define CPU_VERSION 0x1A /* Version encoded in WE32100 */
#define TODBASE 0x41000 #define TODBASE 0x41000
#define TODSIZE 0x40 #define TODSIZE 0x40
#define TIMERBASE 0x42000 #define TIMERBASE 0x42000
#define TIMERSIZE 0x20 #define TIMERSIZE 0x20
#define NVRBASE 0x43000 #define NVRBASE 0x43000
#define NVRSIZE 0x1000 #define NVRSIZE 0x1000
#define CSRBASE 0x44000 #define CSRBASE 0x44000
#define CSRSIZE 0x100 #define CSRSIZE 0x100
#define IFBASE 0x4d000 #define IFBASE 0x4d000
#define IFSIZE 0x10 #define IFSIZE 0x10
#define IDBASE 0x4a000 #define IDBASE 0x4a000
#define IDSIZE 0x2 #define IDSIZE 0x2
#define IF_STATUS_REG 0 #define IF_STATUS_REG 0
#define IF_CMD_REG 0 #define IF_CMD_REG 0
#define IF_TRACK_REG 1 #define IF_TRACK_REG 1
#define IF_SECTOR_REG 2 #define IF_SECTOR_REG 2
#define IF_DATA_REG 3 #define IF_DATA_REG 3
#define ID_DATA_REG 0 #define ID_DATA_REG 0
#define ID_CMD_STAT_REG 1 #define ID_CMD_STAT_REG 1
/* CSR Flags */ /* CSR Flags */
#define CSRTIMO 0x8000 /* Bus Timeout Error */ #define CSRTIMO 0x8000 /* Bus Timeout Error */
#define CSRPARE 0x4000 /* Memory Parity Error */ #define CSRPARE 0x4000 /* Memory Parity Error */
#define CSRRRST 0x2000 /* System Reset Request */ #define CSRRRST 0x2000 /* System Reset Request */
#define CSRALGN 0x1000 /* Memory Alignment Fault */ #define CSRALGN 0x1000 /* Memory Alignment Fault */
#define CSRLED 0x0800 /* Failure LED */ #define CSRLED 0x0800 /* Failure LED */
#define CSRFLOP 0x0400 /* Floppy Motor On */ #define CSRFLOP 0x0400 /* Floppy Motor On */
#define CSRRES 0x0200 /* Reserved */ #define CSRRES 0x0200 /* Reserved */
#define CSRITIM 0x0100 /* Inhibit Timers */ #define CSRITIM 0x0100 /* Inhibit Timers */
#define CSRIFLT 0x0080 /* Inhibit Faults */ #define CSRIFLT 0x0080 /* Inhibit Faults */
#define CSRCLK 0x0040 /* Clock Interrupt */ #define CSRCLK 0x0040 /* Clock Interrupt */
#define CSRPIR8 0x0020 /* Programmed Interrupt 8 */ #define CSRPIR8 0x0020 /* Programmed Interrupt 8 */
#define CSRPIR9 0x0010 /* Programmed Interrupt 9 */ #define CSRPIR9 0x0010 /* Programmed Interrupt 9 */
#define CSRUART 0x0008 /* UART Interrupt */ #define CSRUART 0x0008 /* UART Interrupt */
#define CSRDISK 0x0004 /* Floppy Interrupt */ #define CSRDISK 0x0004 /* Floppy Interrupt */
#define CSRDMA 0x0002 /* DMA Interrupt */ #define CSRDMA 0x0002 /* DMA Interrupt */
#define CSRIOF 0x0001 /* I/O Board Fail */ #define CSRIOF 0x0001 /* I/O Board Fail */
/* Interrupt Sources */ /* Interrupt Sources */
#define INT_SERR 0x01 /* IPL 15 */ #define INT_SERR 0x01 /* IPL 15 */
#define INT_CLOCK 0x02 /* IPL 15 */ #define INT_CLOCK 0x02 /* IPL 15 */
#define INT_DMA 0x04 /* IPL 13 */ #define INT_DMA 0x04 /* IPL 13 */
#define INT_UART 0x08 /* IPL 13 */ #define INT_UART 0x08 /* IPL 13 */
#define INT_DISK 0x10 /* IPL 11 */ #define INT_DISK 0x10 /* IPL 11 */
#define INT_FLOPPY 0x20 /* IPL 11 */ #define INT_FLOPPY 0x20 /* IPL 11 */
#define INT_PIR9 0x40 /* IPL 9 */ #define INT_PIR9 0x40 /* IPL 9 */
#define INT_PIR8 0x80 /* IPL 8 */ #define INT_PIR8 0x80 /* IPL 8 */
#define INT_MAP_LEN 0x100 #define INT_MAP_LEN 0x100
/* Memory */ /* Memory */
#define MEMSIZE_REG 0x4C003 #define MEMSIZE_REG 0x4C003
#define MEMID_512K 0 #define MEMID_512K 0
#define MEMID_1M 2 #define MEMID_1M 2
#define MEMID_2M 1 #define MEMID_2M 1
#define MEMID_4M 3 #define MEMID_4M 3
/* DMA Controller */ /* DMA Controller */
#define DMACBASE 0x48000 #define DMACBASE 0x48000
#define DMACSIZE 0x11 #define DMACSIZE 0x11
/* DMA integrated disk page buffer */ /* DMA integrated disk page buffer */
#define DMAIDBASE 0x45000 #define DMAIDBASE 0x45000
#define DMAIDSIZE 0x5 #define DMAIDSIZE 0x5
/* DMA integrated uart A page buffer */ /* DMA integrated uart A page buffer */
#define DMAIUABASE 0x46000 #define DMAIUABASE 0x46000
#define DMAIUASIZE 0x5 #define DMAIUASIZE 0x5
/* DMA integrated uart B page buffer */ /* DMA integrated uart B page buffer */
#define DMAIUBBASE 0x47000 #define DMAIUBBASE 0x47000
#define DMAIUBSIZE 0x5 #define DMAIUBSIZE 0x5
/* DMA integrated floppy page buffer */ /* DMA integrated floppy page buffer */
#define DMAIFBASE 0x4E000 #define DMAIFBASE 0x4E000
#define DMAIFSIZE 0x5 #define DMAIFSIZE 0x5
#define DMA_ID_CHAN 0 #define DMA_ID_CHAN 0
#define DMA_IF_CHAN 1 #define DMA_IF_CHAN 1
#define DMA_IUA_CHAN 2 #define DMA_IUA_CHAN 2
#define DMA_IUB_CHAN 3 #define DMA_IUB_CHAN 3
#define DMA_ID 0x45 #define DMA_ID 0x45
#define DMA_IUA 0x46 #define DMA_IUA 0x46
#define DMA_IUB 0x47 #define DMA_IUB 0x47
#define DMA_C 0x48 #define DMA_C 0x48
#define DMA_IF 0x4E #define DMA_IF 0x4E
#endif /* _3B2_REV2_DEFS_H_ */ #endif /* _3B2_REV2_DEFS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,358 +1,358 @@
/* 3b2_rev2_mmu.c: WE32101 MMU /* 3b2_rev2_mmu.c: WE32101 MMU
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_REV2_MMU_H_ #ifndef _3B2_REV2_MMU_H_
#define _3B2_REV2_MMU_H_ #define _3B2_REV2_MMU_H_
#include "sim_defs.h" #include "sim_defs.h"
/************************************************************************ /************************************************************************
* *
* Vocabulary * Vocabulary
* ---------- * ----------
* *
* PD: Page Descriptor (in main memory) * PD: Page Descriptor (in main memory)
* PDT: Page Descriptor Table (in main memory) * PDT: Page Descriptor Table (in main memory)
* POT: Page Offset. Bits 0-10 of a Paged virtual address. * POT: Page Offset. Bits 0-10 of a Paged virtual address.
* PSL: Page Select. Bits 11-16 of a Paged virtual address. * PSL: Page Select. Bits 11-16 of a Paged virtual address.
* SD: Segment Descriptor (in main memory) * SD: Segment Descriptor (in main memory)
* SDT: Segment Descriptor Table (in main memory) * SDT: Segment Descriptor Table (in main memory)
* SID: Section ID. Bits 30-31 of all virtual addresses * SID: Section ID. Bits 30-31 of all virtual addresses
* SOT: Segment Offset. Bits 0-16 of a Contiguous virtual address. * SOT: Segment Offset. Bits 0-16 of a Contiguous virtual address.
* SSL: Segment Select. Bits 17-29 of all virtual addresses. * SSL: Segment Select. Bits 17-29 of all virtual addresses.
* *
* *
* The WE32101 MMU divides the virtual address space into four * The WE32101 MMU divides the virtual address space into four
* Sections with 8K Segments per section. Virtual address bits 30 and * Sections with 8K Segments per section. Virtual address bits 30 and
* 31 determine the section, bits 17-29 determine the Segment within * 31 determine the section, bits 17-29 determine the Segment within
* the section. * the section.
* *
* There are two kinds of address translation: Contiguous Translation * There are two kinds of address translation: Contiguous Translation
* and Paged Translation. Contiguous Translation just uses an offset * and Paged Translation. Contiguous Translation just uses an offset
* (bits 0-16 of the virtual address) into each Segment to find an * (bits 0-16 of the virtual address) into each Segment to find an
* address, allowing for 128K bytes per Segment. Paged translation * address, allowing for 128K bytes per Segment. Paged translation
* further break Segments down into 64 Pages of 2K each. * further break Segments down into 64 Pages of 2K each.
* *
* Details about how to do translation are held in main memory in * Details about how to do translation are held in main memory in
* Segment Descriptors and Page Descriptors. These are located in * Segment Descriptors and Page Descriptors. These are located in
* Segment Descriptor Tables and Page Descriptor Tables set up by the * Segment Descriptor Tables and Page Descriptor Tables set up by the
* computer before enabling the MMU. * computer before enabling the MMU.
* *
* In addition to details in main memory, the MMU has a small cache * In addition to details in main memory, the MMU has a small cache
* of both Segment Descriptors and Page Descriptors. This is NOT just * of both Segment Descriptors and Page Descriptors. This is NOT just
* used for performance reasons! Various features of the cache, * used for performance reasons! Various features of the cache,
* such as updating R and M bits in Segment and Page Descriptors, * such as updating R and M bits in Segment and Page Descriptors,
* are used by various operating system features. * are used by various operating system features.
* *
* *
* Virtual Address Fields * Virtual Address Fields
* ---------------------- * ----------------------
* *
* 31 30 29 17 16 0 * 31 30 29 17 16 0
* +-----+-------------------+-----------------------------+ * +-----+-------------------+-----------------------------+
* Contig: | SID | SSL | SOT | * Contig: | SID | SSL | SOT |
* +-----+-------------------+-----------------------------+ * +-----+-------------------+-----------------------------+
* *
* 31 30 29 17 16 11 10 0 * 31 30 29 17 16 11 10 0
* +-----+-------------------+---------+-------------------+ * +-----+-------------------+---------+-------------------+
* Paged: | SID | SSL | PSL | POT | * Paged: | SID | SSL | PSL | POT |
* +-----+-------------------+---------+-------------------+ * +-----+-------------------+---------+-------------------+
* *
* *
* Segment Descriptor Fields * Segment Descriptor Fields
* ------------------------- * -------------------------
* *
* 31 24 23 10 9 8 7 6 5 4 3 2 1 0 * 31 24 23 10 9 8 7 6 5 4 3 2 1 0
* +-------+---------+-----+---+---+---+---+---+---+---+---+ * +-------+---------+-----+---+---+---+---+---+---+---+---+
* sd0: | Acc | Max Off | Res | I | V | R | T | $ | C | M | P | * sd0: | Acc | Max Off | Res | I | V | R | T | $ | C | M | P |
* +-------+---------+-----+---+---+---+---+---+---+---+---+ * +-------+---------+-----+---+---+---+---+---+---+---+---+
* *
* +-----------------------------------------------+-------+ * +-----------------------------------------------+-------+
* sd1: | Address (high-order 27 or 29 bits) | Soft | * sd1: | Address (high-order 27 or 29 bits) | Soft |
* +-----------------------------------------------+-------+ * +-----------------------------------------------+-------+
* *
* *
* Segment Descriptor Cache Entry * Segment Descriptor Cache Entry
* ------------------------------ * ------------------------------
* *
* 31 24 23 10 9 0 * 31 24 23 10 9 0
* +-------+-------------------------+---------------------+ * +-------+-------------------------+---------------------+
* Low: | Acc | Max Off | Tag | * Low: | Acc | Max Off | Tag |
* +-------+-------------------------+---------------------+ * +-------+-------------------------+---------------------+
* *
* 31 5 4 3 2 1 0 * 31 5 4 3 2 1 0
* +-----------------------------------+---+---+---+---+---+ * +-----------------------------------+---+---+---+---+---+
* High: | Address | T | $ | C | M | G | * High: | Address | T | $ | C | M | G |
* +-----------------------------------+---+---+---+---+---+ * +-----------------------------------+---+---+---+---+---+
* *
* *
* Page Descriptor Fields * Page Descriptor Fields
* ---------------------- * ----------------------
* *
* 31 11 10 8 7 6 5 4 3 2 1 0 * 31 11 10 8 7 6 5 4 3 2 1 0
* +----------------+------+-----+---+---+-----+---+---+---+ * +----------------+------+-----+---+---+-----+---+---+---+
* | Page Address | Soft | Res | R | W | Res | L | M | P | * | Page Address | Soft | Res | R | W | Res | L | M | P |
* +----------------+------+-----+---+---+-----+---+---+---+ * +----------------+------+-----+---+---+-----+---+---+---+
* *
* *
* Page Descriptor Cache Entry * Page Descriptor Cache Entry
* --------------------------- * ---------------------------
* *
* 31 24 23 16 15 0 * 31 24 23 16 15 0
* +-----+------------------+------------------------------+ * +-----+------------------+------------------------------+
* Low: | Acc | Res | Tag | * Low: | Acc | Res | Tag |
* +-----+------------------+------------------------------+ * +-----+------------------+------------------------------+
* *
* 31 11 10 7 6 5 4 3 2 1 0 * 31 11 10 7 6 5 4 3 2 1 0
* +---------------------+-----+---+---+---+---+---+---+---+ * +---------------------+-----+---+---+---+---+---+---+---+
* High: | Address | Res | U | R | W | $ | L | M | G | * High: | Address | Res | U | R | W | $ | L | M | G |
* +---------------------+-----+---+---+---+---+---+---+---+ * +---------------------+-----+---+---+---+---+---+---+---+
* *
* "U" is only set in the left cache entry, and indicates * "U" is only set in the left cache entry, and indicates
* which slot (left or right) was most recently updated. * which slot (left or right) was most recently updated.
* *
***********************************************************************/ ***********************************************************************/
#define MMUBASE 0x40000 #define MMUBASE 0x40000
#define MMUSIZE 0x1000 #define MMUSIZE 0x1000
#define MMU_SRS 0x04 /* Section RAM array size (words) */ #define MMU_SRS 0x04 /* Section RAM array size (words) */
#define MMU_SDCS 0x20 /* Segment Descriptor Cache H/L array size #define MMU_SDCS 0x20 /* Segment Descriptor Cache H/L array size
(words) */ (words) */
#define MMU_PDCS 0x20 /* Page Descriptor Cache H/L array size #define MMU_PDCS 0x20 /* Page Descriptor Cache H/L array size
(words) */ (words) */
/* Register address offsets */ /* Register address offsets */
#define MMU_SDCL 0 #define MMU_SDCL 0
#define MMU_SDCH 1 #define MMU_SDCH 1
#define MMU_PDCRL 2 #define MMU_PDCRL 2
#define MMU_PDCRH 3 #define MMU_PDCRH 3
#define MMU_PDCLL 4 #define MMU_PDCLL 4
#define MMU_PDCLH 5 #define MMU_PDCLH 5
#define MMU_SRAMA 6 #define MMU_SRAMA 6
#define MMU_SRAMB 7 #define MMU_SRAMB 7
#define MMU_FC 8 #define MMU_FC 8
#define MMU_FA 9 #define MMU_FA 9
#define MMU_CONF 10 #define MMU_CONF 10
#define MMU_VAR 11 #define MMU_VAR 11
#define MMU_CONF_M (mmu_state.conf & 0x1) #define MMU_CONF_M (mmu_state.conf & 0x1)
#define MMU_CONF_R (mmu_state.conf & 0x2) #define MMU_CONF_R (mmu_state.conf & 0x2)
/* Caching */ /* Caching */
#define NUM_SEC 4u /* Number of memory sections */ #define NUM_SEC 4u /* Number of memory sections */
#define NUM_SDCE 8 /* SD cache entries per section */ #define NUM_SDCE 8 /* SD cache entries per section */
#define NUM_PDCE 8 /* PD cache entries per section per side (l/r) */ #define NUM_PDCE 8 /* PD cache entries per section per side (l/r) */
#define SET_SIZE 2 /* PDs are held in a 2-way associative set */ #define SET_SIZE 2 /* PDs are held in a 2-way associative set */
/* Cache Tag for SDs */ /* Cache Tag for SDs */
#define SD_TAG(vaddr) ((vaddr >> 20) & 0x3ff) #define SD_TAG(vaddr) ((vaddr >> 20) & 0x3ff)
/* Cache Tag for PDs */ /* Cache Tag for PDs */
#define PD_TAG(vaddr) (((vaddr >> 13) & 0xf) | ((vaddr >> 14) & 0xfff0)) #define PD_TAG(vaddr) (((vaddr >> 13) & 0xf) | ((vaddr >> 14) & 0xfff0))
/* Index of entry in the SD cache */ /* Index of entry in the SD cache */
#define SD_IDX(vaddr) ((vaddr >> 17) & 7) #define SD_IDX(vaddr) ((vaddr >> 17) & 7)
/* Index of entry in the PD cache */ /* Index of entry in the PD cache */
#define PD_IDX(vaddr) (((vaddr >> 11) & 3) | ((vaddr >> 15) & 4)) #define PD_IDX(vaddr) (((vaddr >> 11) & 3) | ((vaddr >> 15) & 4))
/* Shift and mask the flag bits for the current CPU mode */ /* Shift and mask the flag bits for the current CPU mode */
#define MMU_PERM(f) ((f >> ((3 - CPU_CM) * 2)) & 3) #define MMU_PERM(f) ((f >> ((3 - CPU_CM) * 2)) & 3)
/* Codes set in the MMU Fault register */ /* Codes set in the MMU Fault register */
#define MMU_F_SDTLEN 0x03 #define MMU_F_SDTLEN 0x03
#define MMU_F_PW 0x04 #define MMU_F_PW 0x04
#define MMU_F_PDTLEN 0x05 #define MMU_F_PDTLEN 0x05
#define MMU_F_INV_SD 0x06 #define MMU_F_INV_SD 0x06
#define MMU_F_SEG_NOT_PRES 0x07 #define MMU_F_SEG_NOT_PRES 0x07
#define MMU_F_OTRAP 0x08 #define MMU_F_OTRAP 0x08
#define MMU_F_PDT_NOT_PRES 0x09 #define MMU_F_PDT_NOT_PRES 0x09
#define MMU_F_PAGE_NOT_PRES 0x0a #define MMU_F_PAGE_NOT_PRES 0x0a
#define MMU_F_ACC 0x0d #define MMU_F_ACC 0x0d
#define MMU_F_SEG_OFFSET 0x0e #define MMU_F_SEG_OFFSET 0x0e
/* Access Request types */ /* Access Request types */
#define ACC_MT 0 /* Move Translated */ #define ACC_MT 0 /* Move Translated */
#define ACC_SPW 1 /* Support processor write */ #define ACC_SPW 1 /* Support processor write */
#define ACC_SPF 3 /* Support processor fetch */ #define ACC_SPF 3 /* Support processor fetch */
#define ACC_IR 7 /* Interlocked read */ #define ACC_IR 7 /* Interlocked read */
#define ACC_AF 8 /* Address fetch */ #define ACC_AF 8 /* Address fetch */
#define ACC_OF 9 /* Operand fetch */ #define ACC_OF 9 /* Operand fetch */
#define ACC_W 10 /* Write */ #define ACC_W 10 /* Write */
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ #define ACC_IFAD 12 /* Instruction fetch after discontinuity */
#define ACC_IF 13 /* Instruction fetch */ #define ACC_IF 13 /* Instruction fetch */
/* Pluck out Virtual Address fields */ /* Pluck out Virtual Address fields */
#define SID(va) (((va) >> 30) & 3) #define SID(va) (((va) >> 30) & 3)
#define SSL(va) (((va) >> 17) & 0x1fff) #define SSL(va) (((va) >> 17) & 0x1fff)
#define SOT(va) (va & 0x1ffff) #define SOT(va) (va & 0x1ffff)
#define PSL(va) (((va) >> 11) & 0x3f) #define PSL(va) (((va) >> 11) & 0x3f)
#define PSL_C(va) ((va) & 0x1f800) #define PSL_C(va) ((va) & 0x1f800)
#define POT(va) (va & 0x7ff) #define POT(va) (va & 0x7ff)
/* Get the maximum length of an SSL from SRAMB */ /* Get the maximum length of an SSL from SRAMB */
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len + 1) #define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len + 1)
/* Pluck out Segment Descriptor fields */ /* Pluck out Segment Descriptor fields */
#define SD_PRESENT(sd0) ((sd0) & 1) #define SD_PRESENT(sd0) ((sd0) & 1)
#define SD_MODIFIED(sd0) (((sd0) >> 1) & 1) #define SD_MODIFIED(sd0) (((sd0) >> 1) & 1)
#define SD_CONTIG(sd0) (((sd0) >> 2) & 1) #define SD_CONTIG(sd0) (((sd0) >> 2) & 1)
#define SD_PAGED(sd0) ((((sd0) >> 2) & 1) == 0) #define SD_PAGED(sd0) ((((sd0) >> 2) & 1) == 0)
#define SD_CACHE(sd0) (((sd0) >> 3) & 1) #define SD_CACHE(sd0) (((sd0) >> 3) & 1)
#define SD_TRAP(sd0) (((sd0) >> 4) & 1) #define SD_TRAP(sd0) (((sd0) >> 4) & 1)
#define SD_REF(sd0) (((sd0) >> 5) & 1) #define SD_REF(sd0) (((sd0) >> 5) & 1)
#define SD_VALID(sd0) (((sd0) >> 6) & 1) #define SD_VALID(sd0) (((sd0) >> 6) & 1)
#define SD_INDIRECT(sd0) (((sd0) >> 7) & 1) #define SD_INDIRECT(sd0) (((sd0) >> 7) & 1)
#define SD_SEG_ADDR(sd1) ((sd1) & 0xffffffe0) #define SD_SEG_ADDR(sd1) ((sd1) & 0xffffffe0)
#define SD_MAX_OFF(sd0) (((sd0) >> 10) & 0x3fff) #define SD_MAX_OFF(sd0) (((sd0) >> 10) & 0x3fff)
#define SD_ACC(sd0) (((sd0) >> 24) & 0xff) #define SD_ACC(sd0) (((sd0) >> 24) & 0xff)
#define SD_R_MASK 0x20 #define SD_R_MASK 0x20
#define SD_M_MASK 0x2 #define SD_M_MASK 0x2
#define SD_GOOD_MASK 0x1u #define SD_GOOD_MASK 0x1u
#define SDCE_TAG(sdcl) ((sdcl) & 0x3ff) #define SDCE_TAG(sdcl) ((sdcl) & 0x3ff)
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8)) #define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
/* Convert from sd to sd cache entry */ /* Convert from sd to sd cache entry */
#define SD_TO_SDCL(va,sd0) ((sd0 & 0xfffffc00)|SD_TAG(va)) #define SD_TO_SDCL(va,sd0) ((sd0 & 0xfffffc00)|SD_TAG(va))
#define SD_TO_SDCH(sd0,sd1) (SD_SEG_ADDR(sd1)|(sd0 & 0x1e)|1) #define SD_TO_SDCH(sd0,sd1) (SD_SEG_ADDR(sd1)|(sd0 & 0x1e)|1)
/* Note that this is a lossy transform. We will lose the state of the /* Note that this is a lossy transform. We will lose the state of the
I and R flags, as well as the software flags. We don't need them. I and R flags, as well as the software flags. We don't need them.
The V and P flags can be inferred as set. */ The V and P flags can be inferred as set. */
#define SDCE_TO_SD0(sdch,sdcl) ((sdcl & 0xfffffc00)|0x40|(sdch & 0x1e)|1) #define SDCE_TO_SD0(sdch,sdcl) ((sdcl & 0xfffffc00)|0x40|(sdch & 0x1e)|1)
#define SDCE_TO_SD1(sdch) (sdch & 0xffffffe0) #define SDCE_TO_SD1(sdch) (sdch & 0xffffffe0)
/* Maximum size (in bytes) of a segment */ /* Maximum size (in bytes) of a segment */
#define MAX_OFFSET(sd0) ((SD_MAX_OFF(sd0) + 1) * 8) #define MAX_OFFSET(sd0) ((SD_MAX_OFF(sd0) + 1) * 8)
#define PD_PRESENT(pd) (pd & 1) #define PD_PRESENT(pd) (pd & 1)
#define PD_MODIFIED(pd) ((pd >> 1) & 1) #define PD_MODIFIED(pd) ((pd >> 1) & 1)
#define PD_LAST(pd) ((pd >> 2) & 1) #define PD_LAST(pd) ((pd >> 2) & 1)
#define PD_WFAULT(pd) ((pd >> 4) & 1) #define PD_WFAULT(pd) ((pd >> 4) & 1)
#define PD_REF(pd) ((pd >> 5) & 1) #define PD_REF(pd) ((pd >> 5) & 1)
#define PD_ADDR(pd) (pd & 0xfffff800) /* Address portion of PD */ #define PD_ADDR(pd) (pd & 0xfffff800) /* Address portion of PD */
#define PD_R_MASK 0x20 #define PD_R_MASK 0x20
#define PD_M_MASK 0x2 #define PD_M_MASK 0x2
#define PD_GOOD_MASK 0x1u #define PD_GOOD_MASK 0x1u
#define PDCLH_USED_MASK 0x40u #define PDCLH_USED_MASK 0x40u
#define PDCXL_TAG(pdcxl) (pdcxl & 0xffff) #define PDCXL_TAG(pdcxl) (pdcxl & 0xffff)
#define PD_LOC(sd1,va) SD_SEG_ADDR(sd1) + (PSL(va) * 4) #define PD_LOC(sd1,va) SD_SEG_ADDR(sd1) + (PSL(va) * 4)
/* Page Descriptor Cache Entry /* Page Descriptor Cache Entry
* *
*/ */
/* Convert from pd to pd cache entry. Alwasy sets "Good" bit. */ /* Convert from pd to pd cache entry. Alwasy sets "Good" bit. */
#define SD_TO_PDCXL(va,sd0) ((sd0 & 0xff000000)|PD_TAG(va)) #define SD_TO_PDCXL(va,sd0) ((sd0 & 0xff000000)|PD_TAG(va))
#define PD_TO_PDCXH(pd,sd0) ((pd & 0xfffff836)|(sd0 & 0x8)|1) #define PD_TO_PDCXH(pd,sd0) ((pd & 0xfffff836)|(sd0 & 0x8)|1)
/* Always set 'present' to true on conversion */ /* Always set 'present' to true on conversion */
#define PDCXH_TO_PD(pdch) ((pdch & 0xfffff836)|1) #define PDCXH_TO_PD(pdch) ((pdch & 0xfffff836)|1)
#define PDCXL_TO_ACC(pdcl) (((pdcl & 0xff000000) >> 24) & 0xff) #define PDCXL_TO_ACC(pdcl) (((pdcl & 0xff000000) >> 24) & 0xff)
/* Fault codes */ /* Fault codes */
#define MMU_FAULT(f) { \ #define MMU_FAULT(f) { \
if (fc) { \ if (fc) { \
mmu_state.fcode = ((((uint32)r_acc)<<7)| \ mmu_state.fcode = ((((uint32)r_acc)<<7)| \
(((uint32)(CPU_CM))<<5)|f); \ (((uint32)(CPU_CM))<<5)|f); \
mmu_state.faddr = va; \ mmu_state.faddr = va; \
} \ } \
} }
typedef struct _mmu_sec { typedef struct _mmu_sec {
uint32 addr; uint32 addr;
uint32 len; uint32 len;
} mmu_sec; } mmu_sec;
typedef struct _mmu_state { typedef struct _mmu_state {
t_bool enabled; /* Global enabled/disabled flag */ t_bool enabled; /* Global enabled/disabled flag */
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */ uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
uint32 pdcll[MMU_PDCS]; /* PDC low bits (left) (0-31) */ uint32 pdcll[MMU_PDCS]; /* PDC low bits (left) (0-31) */
uint32 pdclh[MMU_PDCS]; /* PDC high bits (left) (32-63) */ uint32 pdclh[MMU_PDCS]; /* PDC high bits (left) (32-63) */
uint32 pdcrl[MMU_PDCS]; /* PDC low bits (right) (0-31) */ uint32 pdcrl[MMU_PDCS]; /* PDC low bits (right) (0-31) */
uint32 pdcrh[MMU_PDCS]; /* PDC high bits (right) (32-63) */ uint32 pdcrh[MMU_PDCS]; /* PDC high bits (right) (32-63) */
uint32 sra[MMU_SRS]; /* Section RAM A */ uint32 sra[MMU_SRS]; /* Section RAM A */
uint32 srb[MMU_SRS]; /* Section RAM B */ uint32 srb[MMU_SRS]; /* Section RAM B */
mmu_sec sec[MMU_SRS]; /* Section descriptors decoded from mmu_sec sec[MMU_SRS]; /* Section descriptors decoded from
Section RAM A and B */ Section RAM A and B */
uint32 fcode; /* Fault Code Register */ uint32 fcode; /* Fault Code Register */
uint32 faddr; /* Fault Address Register */ uint32 faddr; /* Fault Address Register */
uint32 conf; /* Configuration Register */ uint32 conf; /* Configuration Register */
uint32 var; /* Virtual Address Register */ uint32 var; /* Virtual Address Register */
} MMU_STATE; } MMU_STATE;
t_stat mmu_init(DEVICE *dptr); t_stat mmu_init(DEVICE *dptr);
uint32 mmu_read(uint32 pa, size_t size); uint32 mmu_read(uint32 pa, size_t size);
void mmu_write(uint32 pa, uint32 val, size_t size); void mmu_write(uint32 pa, uint32 val, size_t size);
CONST char *mmu_description(DEVICE *dptr); CONST char *mmu_description(DEVICE *dptr);
/* Virtual memory translation */ /* Virtual memory translation */
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc); uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
t_bool fc, uint32 *pa); t_bool fc, uint32 *pa);
#define SHOULD_CACHE_PD(pd) \ #define SHOULD_CACHE_PD(pd) \
(fc && PD_PRESENT(pd)) (fc && PD_PRESENT(pd))
#define SHOULD_CACHE_SD(sd) \ #define SHOULD_CACHE_SD(sd) \
(fc && SD_VALID(sd) && SD_PRESENT(sd)) (fc && SD_VALID(sd) && SD_PRESENT(sd))
#define SHOULD_UPDATE_SD_R_BIT(sd) \ #define SHOULD_UPDATE_SD_R_BIT(sd) \
(MMU_CONF_R && !((sd) & SD_R_MASK)) (MMU_CONF_R && !((sd) & SD_R_MASK))
#define SHOULD_UPDATE_SD_M_BIT(sd) \ #define SHOULD_UPDATE_SD_M_BIT(sd) \
(MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK)) (MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK))
#define SHOULD_UPDATE_PD_R_BIT(pd) \ #define SHOULD_UPDATE_PD_R_BIT(pd) \
(!((pd) & PD_R_MASK)) (!((pd) & PD_R_MASK))
#define SHOULD_UPDATE_PD_M_BIT(pd) \ #define SHOULD_UPDATE_PD_M_BIT(pd) \
(r_acc == ACC_W && !((pd) & PD_M_MASK)) (r_acc == ACC_W && !((pd) & PD_M_MASK))
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
void mmu_enable(); void mmu_enable();
void mmu_disable(); void mmu_disable();
extern MMU_STATE mmu_state; extern MMU_STATE mmu_state;
#endif /* _3B2_REV2_MMU_H_ */ #endif /* _3B2_REV2_MMU_H_ */

View file

@ -1,82 +1,82 @@
/* 3b2_rev2_sys.c: Version 2 (3B2/400) System Definition /* 3b2_rev2_sys.c: Version 2 (3B2/400) System Definition
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_defs.h" #include "3b2_defs.h"
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_csr.h" #include "3b2_csr.h"
#include "3b2_ctc.h" #include "3b2_ctc.h"
#include "3b2_id.h" #include "3b2_id.h"
#include "3b2_if.h" #include "3b2_if.h"
#include "3b2_iu.h" #include "3b2_iu.h"
#include "3b2_ni.h" #include "3b2_ni.h"
#include "3b2_ports.h" #include "3b2_ports.h"
#include "3b2_mau.h" #include "3b2_mau.h"
#include "3b2_stddev.h" #include "3b2_stddev.h"
#include "3b2_timer.h" #include "3b2_timer.h"
char sim_name[] = "AT&T 3B2/400"; char sim_name[] = "AT&T 3B2/400";
DEVICE *sim_devices[] = { DEVICE *sim_devices[] = {
&cpu_dev, &cpu_dev,
&mmu_dev, &mmu_dev,
&mau_dev, &mau_dev,
&timer_dev, &timer_dev,
&tod_dev, &tod_dev,
&nvram_dev, &nvram_dev,
&csr_dev, &csr_dev,
&tti_dev, &tti_dev,
&tto_dev, &tto_dev,
&contty_dev, &contty_dev,
&iu_timer_dev, &iu_timer_dev,
&dmac_dev, &dmac_dev,
&if_dev, &if_dev,
&id_dev, &id_dev,
&ports_dev, &ports_dev,
&ctc_dev, &ctc_dev,
&ni_dev, &ni_dev,
NULL NULL
}; };
void full_reset() void full_reset()
{ {
cpu_reset(&cpu_dev); cpu_reset(&cpu_dev);
mau_reset(&mau_dev); mau_reset(&mau_dev);
tti_reset(&tti_dev); tti_reset(&tti_dev);
contty_reset(&contty_dev); contty_reset(&contty_dev);
iu_timer_reset(&iu_timer_dev); iu_timer_reset(&iu_timer_dev);
timer_reset(&timer_dev); timer_reset(&timer_dev);
if_reset(&if_dev); if_reset(&if_dev);
id_reset(&id_dev); id_reset(&id_dev);
csr_reset(&csr_dev); csr_reset(&csr_dev);
ports_reset(&ports_dev); ports_reset(&ports_dev);
ctc_reset(&ctc_dev); ctc_reset(&ctc_dev);
ni_reset(&ni_dev); ni_reset(&ni_dev);
} }

View file

@ -1,293 +1,293 @@
/* 3b2_rev3_csr.c: CM518B System Board Control, Status & Error Register /* 3b2_rev3_csr.c: CM518B System Board Control, Status & Error Register
Copyright (c) 2020-2022, Seth J. Morabito Copyright (c) 2020-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_csr.h" #include "3b2_csr.h"
#include "3b2_if.h" #include "3b2_if.h"
#include "3b2_timer.h" #include "3b2_timer.h"
#include "3b2_sys.h" #include "3b2_sys.h"
CSR_DATA csr_data; CSR_DATA csr_data;
BITFIELD csr_bits[] = { BITFIELD csr_bits[] = {
BIT(UTIM), BIT(UTIM),
BIT(PWDN), BIT(PWDN),
BIT(OI15), BIT(OI15),
BIT(IUINT), BIT(IUINT),
BIT(IUDMA), BIT(IUDMA),
BIT(PIR9), BIT(PIR9),
BIT(PIR8), BIT(PIR8),
BIT(IUTIM), BIT(IUTIM),
BIT(ISTY), BIT(ISTY),
BIT(IUBUS), BIT(IUBUS),
BIT(IFLT), BIT(IFLT),
BIT(ISBER), BIT(ISBER),
BIT(IBUS), BIT(IBUS),
BIT(IBUB), BIT(IBUB),
BIT(FECC), BIT(FECC),
BIT(THERM), BIT(THERM),
BIT(FLED), BIT(FLED),
BIT(PSPWR), BIT(PSPWR),
BIT(FLSPD), BIT(FLSPD),
BIT(FLSD1), BIT(FLSD1),
BIT(FLMOT), BIT(FLMOT),
BIT(FLDEN), BIT(FLDEN),
BIT(FLSZ), BIT(FLSZ),
BIT(SBER), BIT(SBER),
BIT(MBER), BIT(MBER),
BIT(UBFL), BIT(UBFL),
BIT(TIMO), BIT(TIMO),
BIT(FLTFR), BIT(FLTFR),
BIT(DALGN), BIT(DALGN),
BIT(STTIM), BIT(STTIM),
BIT(ABRT), BIT(ABRT),
BIT(RSTR), BIT(RSTR),
ENDBITS ENDBITS
}; };
UNIT csr_unit = { UNIT csr_unit = {
UDATA(NULL, UNIT_FIX, CSRSIZE) UDATA(NULL, UNIT_FIX, CSRSIZE)
}; };
REG csr_reg[] = { REG csr_reg[] = {
{ HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) }, { HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) },
{ NULL } { NULL }
}; };
DEVICE csr_dev = { DEVICE csr_dev = {
"CSR", &csr_unit, csr_reg, NULL, "CSR", &csr_unit, csr_reg, NULL,
1, 16, 8, 4, 16, 32, 1, 16, 8, 4, 16, 32,
&csr_ex, &csr_dep, &csr_reset, &csr_ex, &csr_dep, &csr_reset,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
DEV_DEBUG, 0, sys_deb_tab DEV_DEBUG, 0, sys_deb_tab
}; };
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
{ {
return SCPE_OK; return SCPE_OK;
} }
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw) t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw)
{ {
return SCPE_OK; return SCPE_OK;
} }
t_stat csr_reset(DEVICE *dptr) t_stat csr_reset(DEVICE *dptr)
{ {
CSRBIT(CSRFECC, TRUE); CSRBIT(CSRFECC, TRUE);
CSRBIT(CSRTHERM, FALSE); CSRBIT(CSRTHERM, FALSE);
CSRBIT(CSRITIM, TRUE); CSRBIT(CSRITIM, TRUE);
CSRBIT(CSRISTIM, TRUE); CSRBIT(CSRISTIM, TRUE);
CSRBIT(CSRIBUB, TRUE); CSRBIT(CSRIBUB, TRUE);
CSRBIT(CSRPWRSPDN, FALSE); CSRBIT(CSRPWRSPDN, FALSE);
CSRBIT(CSRFLPMO, TRUE); CSRBIT(CSRFLPMO, TRUE);
return SCPE_OK; return SCPE_OK;
} }
uint32 csr_read(uint32 pa, size_t size) uint32 csr_read(uint32 pa, size_t size)
{ {
uint32 reg = (pa - CSRBASE) & 0xff; uint32 reg = (pa - CSRBASE) & 0xff;
switch (reg & 0xf0) { switch (reg & 0xf0) {
case 0x00: case 0x00:
return csr_data & 0xff; return csr_data & 0xff;
case 0x20: case 0x20:
return (csr_data >> 8) & 0xff; return (csr_data >> 8) & 0xff;
case 0x40: case 0x40:
return (csr_data >> 16) & 0xff; return (csr_data >> 16) & 0xff;
case 0x60: case 0x60:
return (csr_data >> 24) & 0xff; return (csr_data >> 24) & 0xff;
default: default:
sim_debug(WRITE_MSG, &csr_dev, sim_debug(WRITE_MSG, &csr_dev,
"CSR READ. Warning, unexpected register = %02x)\n", "CSR READ. Warning, unexpected register = %02x)\n",
reg); reg);
return 0; return 0;
} }
} }
#define SET_INT(flag, val) { \ #define SET_INT(flag, val) { \
if (val) { \ if (val) { \
CPU_SET_INT(flag); \ CPU_SET_INT(flag); \
} else { \ } else { \
CPU_CLR_INT(flag); \ CPU_CLR_INT(flag); \
} \ } \
} }
void csr_write(uint32 pa, uint32 val, size_t size) void csr_write(uint32 pa, uint32 val, size_t size)
{ {
uint32 reg = pa - CSRBASE; uint32 reg = pa - CSRBASE;
switch (reg) { switch (reg) {
case 0x00: case 0x00:
CSRBIT(CSRCLK, val); CSRBIT(CSRCLK, val);
SET_INT(INT_CLOCK, val); SET_INT(INT_CLOCK, val);
break; break;
case 0x04: case 0x04:
CSRBIT(CSRPWRDN, val); CSRBIT(CSRPWRDN, val);
SET_INT(INT_PWRDWN, val); SET_INT(INT_PWRDWN, val);
break; break;
case 0x08: case 0x08:
CSRBIT(CSROPINT15, val); CSRBIT(CSROPINT15, val);
SET_INT(INT_BUS_OP, val); SET_INT(INT_BUS_OP, val);
break; break;
case 0x0c: case 0x0c:
CSRBIT(CSRUART, val); CSRBIT(CSRUART, val);
SET_INT(INT_UART, val); SET_INT(INT_UART, val);
break; break;
case 0x10: case 0x10:
CSRBIT(CSRDMA, val); CSRBIT(CSRDMA, val);
SET_INT(INT_UART_DMA, val); SET_INT(INT_UART_DMA, val);
break; break;
case 0x14: case 0x14:
CSRBIT(CSRPIR9, val); CSRBIT(CSRPIR9, val);
SET_INT(INT_PIR9, val); SET_INT(INT_PIR9, val);
break; break;
case 0x18: case 0x18:
CSRBIT(CSRPIR8, val); CSRBIT(CSRPIR8, val);
SET_INT(INT_PIR8, val); SET_INT(INT_PIR8, val);
break; break;
case 0x1c: case 0x1c:
CSRBIT(CSRITIM, val); CSRBIT(CSRITIM, val);
timer_gate(TIMER_INTERVAL, CSR(CSRITIM)); timer_gate(TIMER_INTERVAL, CSR(CSRITIM));
break; break;
case 0x20: case 0x20:
CSRBIT(CSRISTIM, val); CSRBIT(CSRISTIM, val);
timer_gate(TIMER_SANITY, CSR(CSRISTIM)); timer_gate(TIMER_SANITY, CSR(CSRISTIM));
break; break;
case 0x24: case 0x24:
CSRBIT(CSRITIMO, val); CSRBIT(CSRITIMO, val);
timer_gate(TIMER_BUS, CSR(CSRITIMO)); timer_gate(TIMER_BUS, CSR(CSRITIMO));
break; break;
case 0x28: case 0x28:
CSRBIT(CSRICPUFLT, val); CSRBIT(CSRICPUFLT, val);
break; break;
case 0x2c: case 0x2c:
CSRBIT(CSRISBERR, val); CSRBIT(CSRISBERR, val);
break; break;
case 0x30: case 0x30:
CSRBIT(CSRIIOBUS, val); CSRBIT(CSRIIOBUS, val);
break; break;
case 0x34: case 0x34:
CSRBIT(CSRIBUB, val); CSRBIT(CSRIBUB, val);
break; break;
case 0x38: case 0x38:
CSRBIT(CSRFECC, val); CSRBIT(CSRFECC, val);
sim_debug(WRITE_MSG, &csr_dev, sim_debug(WRITE_MSG, &csr_dev,
"CSR WRITE. Force ECC Syndrome = %d\n", "CSR WRITE. Force ECC Syndrome = %d\n",
val); val);
break; break;
case 0x3c: case 0x3c:
CSRBIT(CSRTHERM, val); CSRBIT(CSRTHERM, val);
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
break; break;
case 0x40: case 0x40:
CSRBIT(CSRLED, val); CSRBIT(CSRLED, val);
break; break;
case 0x44: case 0x44:
CSRBIT(CSRPWRSPDN, val); CSRBIT(CSRPWRSPDN, val);
if (!val) { if (!val) {
/* Stop the simulator - power down */ /* Stop the simulator - power down */
stop_reason = STOP_POWER; stop_reason = STOP_POWER;
} }
break; break;
case 0x48: case 0x48:
CSRBIT(CSRFLPFST, val); CSRBIT(CSRFLPFST, val);
break; break;
case 0x4c: /* Floppy Side 1: Set when Cleared */ case 0x4c: /* Floppy Side 1: Set when Cleared */
if_state.side = (val & 1) ? 0 : 1; if_state.side = (val & 1) ? 0 : 1;
CSRBIT(CSRFLPS1, val & 1); CSRBIT(CSRFLPS1, val & 1);
break; break;
case 0x50: case 0x50:
CSRBIT(CSRFLPMO, val); CSRBIT(CSRFLPMO, val);
break; break;
case 0x54: case 0x54:
CSRBIT(CSRFLPDEN, val); CSRBIT(CSRFLPDEN, val);
break; break;
case 0x58: case 0x58:
CSRBIT(CSRFLPSZ, val); CSRBIT(CSRFLPSZ, val);
break; break;
case 0x5c: case 0x5c:
CSRBIT(CSRSBERR, val); CSRBIT(CSRSBERR, val);
if (val) { if (val) {
if (!(csr_data & CSRISBERR)) { if (!(csr_data & CSRISBERR)) {
SET_INT(INT_SBERR, TRUE); SET_INT(INT_SBERR, TRUE);
} }
} else { } else {
SET_INT(INT_SBERR, FALSE); SET_INT(INT_SBERR, FALSE);
} }
break; break;
case 0x60: case 0x60:
CSRBIT(CSRMBERR, val); CSRBIT(CSRMBERR, val);
SET_INT(INT_MBERR, val); SET_INT(INT_MBERR, val);
break; break;
case 0x64: case 0x64:
CSRBIT(CSRUBUBF, val); CSRBIT(CSRUBUBF, val);
SET_INT(INT_BUS_RXF, val); SET_INT(INT_BUS_RXF, val);
break; break;
case 0x68: case 0x68:
CSRBIT(CSRTIMO, val); CSRBIT(CSRTIMO, val);
if (val) { if (val) {
if (!(csr_data & CSRITIMO)) { if (!(csr_data & CSRITIMO)) {
SET_INT(INT_BUS_TMO, TRUE); SET_INT(INT_BUS_TMO, TRUE);
} }
} else { } else {
SET_INT(INT_BUS_TMO, FALSE); SET_INT(INT_BUS_TMO, FALSE);
} }
break; break;
case 0x6c: case 0x6c:
CSRBIT(CSRFRF, val); CSRBIT(CSRFRF, val);
break; break;
case 0x70: case 0x70:
CSRBIT(CSRALGN, val); CSRBIT(CSRALGN, val);
break; break;
case 0x74: case 0x74:
CSRBIT(CSRSTIMO, val); CSRBIT(CSRSTIMO, val);
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
break; break;
case 0x78: case 0x78:
CSRBIT(CSRABRT, val); CSRBIT(CSRABRT, val);
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
break; break;
case 0x7c: case 0x7c:
/* System reset request */ /* System reset request */
full_reset(); full_reset();
cpu_boot(0, &cpu_dev); cpu_boot(0, &cpu_dev);
break; break;
default: default:
/* Do nothing */ /* Do nothing */
break; break;
} }
} }

View file

@ -1,45 +1,45 @@
/* 3b2_rev3_csr.h: CM518B System Board Control, Status & Error Register /* 3b2_rev3_csr.h: CM518B System Board Control, Status & Error Register
Copyright (c) 2020-2022, Seth J. Morabito Copyright (c) 2020-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_400_CSR_H_ #ifndef _3B2_400_CSR_H_
#define _3B2_400_CSR_H_ #define _3B2_400_CSR_H_
#include "3b2_defs.h" #include "3b2_defs.h"
typedef uint32 CSR_DATA; typedef uint32 CSR_DATA;
t_stat csr_svc(UNIT *uptr); t_stat csr_svc(UNIT *uptr);
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat csr_reset(DEVICE *dptr); t_stat csr_reset(DEVICE *dptr);
uint32 csr_read(uint32 pa, size_t size); uint32 csr_read(uint32 pa, size_t size);
void csr_write(uint32 pa, uint32 val, size_t size); void csr_write(uint32 pa, uint32 val, size_t size);
#endif #endif

View file

@ -1,141 +1,141 @@
/* 3b2_rev3_defs.h: Veresion 3 (3B2/700) Common Definitions /* 3b2_rev3_defs.h: Veresion 3 (3B2/700) Common Definitions
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_REV3_DEFS_H_ #ifndef _3B2_REV3_DEFS_H_
#define _3B2_REV3_DEFS_H_ #define _3B2_REV3_DEFS_H_
#define NUM_REGISTERS 32 #define NUM_REGISTERS 32
#define DEFMEMSIZE MSIZ_16M #define DEFMEMSIZE MSIZ_16M
#define MAXMEMSIZE MSIZ_64M #define MAXMEMSIZE MSIZ_64M
#define HWORD_OP_COUNT 12 #define HWORD_OP_COUNT 12
#define CPU_VERSION 0x1F /* Version encoded in WE32200 */ #define CPU_VERSION 0x1F /* Version encoded in WE32200 */
/* CSR Flags */ /* CSR Flags */
#define CSRCLK 1u /* UNIX Interval Timer Timeout */ #define CSRCLK 1u /* UNIX Interval Timer Timeout */
#define CSRPWRDN (1u << 1) /* Power Down Request */ #define CSRPWRDN (1u << 1) /* Power Down Request */
#define CSROPINT15 (1u << 2) /* Oper. Interrupt Level 15 */ #define CSROPINT15 (1u << 2) /* Oper. Interrupt Level 15 */
#define CSRUART (1u << 3) /* DUART Interrupt */ #define CSRUART (1u << 3) /* DUART Interrupt */
#define CSRDMA (1u << 4) /* DUART DMA Complete Interrupt */ #define CSRDMA (1u << 4) /* DUART DMA Complete Interrupt */
#define CSRPIR9 (1u << 5) /* Programmed Interrupt 9 */ #define CSRPIR9 (1u << 5) /* Programmed Interrupt 9 */
#define CSRPIR8 (1u << 6) /* Programmed Interrupt 8 */ #define CSRPIR8 (1u << 6) /* Programmed Interrupt 8 */
#define CSRITIM (1u << 7) /* Inhibit UNIX Interval Timer */ #define CSRITIM (1u << 7) /* Inhibit UNIX Interval Timer */
#define CSRISTIM (1u << 8) /* Inhibit System Sanity Timer */ #define CSRISTIM (1u << 8) /* Inhibit System Sanity Timer */
#define CSRITIMO (1u << 9) /* Inhibit Bus Timer */ #define CSRITIMO (1u << 9) /* Inhibit Bus Timer */
#define CSRICPUFLT (1u << 10) /* Inhibit Faults to CPU */ #define CSRICPUFLT (1u << 10) /* Inhibit Faults to CPU */
#define CSRISBERR (1u << 11) /* Inhibit Single Bit Error Rpt */ #define CSRISBERR (1u << 11) /* Inhibit Single Bit Error Rpt */
#define CSRIIOBUS (1u << 12) /* Inhibit Integral 3B2 I/O Bus */ #define CSRIIOBUS (1u << 12) /* Inhibit Integral 3B2 I/O Bus */
#define CSRIBUB (1u << 13) /* Inhibit 4 BUB Slots */ #define CSRIBUB (1u << 13) /* Inhibit 4 BUB Slots */
#define CSRFECC (1u << 14) /* Force ECC Syndrome */ #define CSRFECC (1u << 14) /* Force ECC Syndrome */
#define CSRTHERM (1u << 15) /* Thermal Shutdown Request */ #define CSRTHERM (1u << 15) /* Thermal Shutdown Request */
#define CSRLED (1u << 16) /* Failure LED */ #define CSRLED (1u << 16) /* Failure LED */
#define CSRPWRSPDN (1u << 17) /* Power Down -- Power Supply */ #define CSRPWRSPDN (1u << 17) /* Power Down -- Power Supply */
#define CSRFLPFST (1u << 18) /* Floppy Speed Fast */ #define CSRFLPFST (1u << 18) /* Floppy Speed Fast */
#define CSRFLPS1 (1u << 19) /* Floppy Side 1 */ #define CSRFLPS1 (1u << 19) /* Floppy Side 1 */
#define CSRFLPMO (1u << 20) /* Floppy Motor On */ #define CSRFLPMO (1u << 20) /* Floppy Motor On */
#define CSRFLPDEN (1u << 21) /* Floppy Density */ #define CSRFLPDEN (1u << 21) /* Floppy Density */
#define CSRFLPSZ (1u << 22) /* Floppy Size */ #define CSRFLPSZ (1u << 22) /* Floppy Size */
#define CSRSBERR (1u << 23) /* Single Bit Error */ #define CSRSBERR (1u << 23) /* Single Bit Error */
#define CSRMBERR (1u << 24) /* Multiple Bit Error */ #define CSRMBERR (1u << 24) /* Multiple Bit Error */
#define CSRUBUBF (1u << 25) /* Ubus/BUB Received Fail */ #define CSRUBUBF (1u << 25) /* Ubus/BUB Received Fail */
#define CSRTIMO (1u << 26) /* Bus Timer Timeout */ #define CSRTIMO (1u << 26) /* Bus Timer Timeout */
#define CSRFRF (1u << 27) /* Fault Registers Frozen */ #define CSRFRF (1u << 27) /* Fault Registers Frozen */
#define CSRALGN (1u << 28) /* Data Alignment Error */ #define CSRALGN (1u << 28) /* Data Alignment Error */
#define CSRSTIMO (1u << 29) /* Sanity Timer Timeout */ #define CSRSTIMO (1u << 29) /* Sanity Timer Timeout */
#define CSRABRT (1u << 30) /* Abort Switch Activated */ #define CSRABRT (1u << 30) /* Abort Switch Activated */
#define CSRRRST (1u << 31) /* System Reset Request */ #define CSRRRST (1u << 31) /* System Reset Request */
/* Interrupt Sources */ /* Interrupt Sources */
#define INT_CLOCK 0x0001 /* UNIX Interval Timer Timeout - IPL 15 */ #define INT_CLOCK 0x0001 /* UNIX Interval Timer Timeout - IPL 15 */
#define INT_PWRDWN 0x0002 /* Power Down Request - IPL 15 */ #define INT_PWRDWN 0x0002 /* Power Down Request - IPL 15 */
#define INT_BUS_OP 0x0004 /* UBUS or BUB Operational Interrupt - IPL 15 */ #define INT_BUS_OP 0x0004 /* UBUS or BUB Operational Interrupt - IPL 15 */
#define INT_SBERR 0x0008 /* Single Bit Memory Error - IPL 15 */ #define INT_SBERR 0x0008 /* Single Bit Memory Error - IPL 15 */
#define INT_MBERR 0x0010 /* Multiple Bit Memory Error - IPL 15 */ #define INT_MBERR 0x0010 /* Multiple Bit Memory Error - IPL 15 */
#define INT_BUS_RXF 0x0020 /* UBUS, BUB, EIO Bus Received Fail - IPL 15 */ #define INT_BUS_RXF 0x0020 /* UBUS, BUB, EIO Bus Received Fail - IPL 15 */
#define INT_BUS_TMO 0x0040 /* UBUS Timer Timeout - IPL 15 */ #define INT_BUS_TMO 0x0040 /* UBUS Timer Timeout - IPL 15 */
#define INT_UART_DMA 0x0080 /* UART DMA Complete - IPL 13 */ #define INT_UART_DMA 0x0080 /* UART DMA Complete - IPL 13 */
#define INT_UART 0x0100 /* UART Interrupt - IPL 13 */ #define INT_UART 0x0100 /* UART Interrupt - IPL 13 */
#define INT_FLOPPY_DMA 0x0200 /* Floppy DMA Complete - IPL 11 */ #define INT_FLOPPY_DMA 0x0200 /* Floppy DMA Complete - IPL 11 */
#define INT_FLOPPY 0x0400 /* Floppy Interrupt - IPL 11 */ #define INT_FLOPPY 0x0400 /* Floppy Interrupt - IPL 11 */
#define INT_PIR9 0x0800 /* PIR-9 (from CSER) - IPL 9 */ #define INT_PIR9 0x0800 /* PIR-9 (from CSER) - IPL 9 */
#define INT_PIR8 0x1000 /* PIR-8 (from CSER) - IPL 8 */ #define INT_PIR8 0x1000 /* PIR-8 (from CSER) - IPL 8 */
#define INT_MAP_LEN 0x2000 #define INT_MAP_LEN 0x2000
#define IFCSRBASE 0x40000 #define IFCSRBASE 0x40000
#define IFCSRSIZE 0x100 #define IFCSRSIZE 0x100
#define TIMERBASE 0x41000 #define TIMERBASE 0x41000
#define TIMERSIZE 0x20 #define TIMERSIZE 0x20
#define NVRBASE 0x42000 #define NVRBASE 0x42000
#define NVRSIZE 0x2000 #define NVRSIZE 0x2000
#define CSRBASE 0x44000 #define CSRBASE 0x44000
#define CSRSIZE 0x100 #define CSRSIZE 0x100
#define DMAIFBASE 0x45000 #define DMAIFBASE 0x45000
#define DMAIFSIZE 0x5 #define DMAIFSIZE 0x5
#define DMAIUABASE 0x46000 #define DMAIUABASE 0x46000
#define DMAIUASIZE 0x5 #define DMAIUASIZE 0x5
#define DMAIUBBASE 0x47000 #define DMAIUBBASE 0x47000
#define DMAIUBSIZE 0x5 #define DMAIUBSIZE 0x5
#define DMACBASE 0x48000 #define DMACBASE 0x48000
#define DMACSIZE 0x11 #define DMACSIZE 0x11
#define IFBASE 0x4a000 #define IFBASE 0x4a000
#define IFSIZE 0x10 #define IFSIZE 0x10
#define TODBASE 0x4e000 #define TODBASE 0x4e000
#define TODSIZE 0x40 #define TODSIZE 0x40
#define MMUBASE 0x4f000 #define MMUBASE 0x4f000
#define MMUSIZE 0x1000 #define MMUSIZE 0x1000
#define FLTLBASE 0x4c000 #define FLTLBASE 0x4c000
#define FLTLSIZE 0x1000 #define FLTLSIZE 0x1000
#define FLTHBASE 0x4d000 #define FLTHBASE 0x4d000
#define FLTHSIZE 0x1000 #define FLTHSIZE 0x1000
#define VCACHE_BOTTOM 0x1c00000 #define VCACHE_BOTTOM 0x1c00000
#define VCACHE_TOP 0x2000000 #define VCACHE_TOP 0x2000000
#define BUB_BOTTOM 0x6000000 #define BUB_BOTTOM 0x6000000
#define BUB_TOP 0x1a000000 #define BUB_TOP 0x1a000000
#define IF_STATUS_REG 0 #define IF_STATUS_REG 0
#define IF_CMD_REG 0 #define IF_CMD_REG 0
#define IF_TRACK_REG 1 #define IF_TRACK_REG 1
#define IF_SECTOR_REG 2 #define IF_SECTOR_REG 2
#define IF_DATA_REG 3 #define IF_DATA_REG 3
#define DMA_IF_CHAN 1 #define DMA_IF_CHAN 1
#define DMA_IUA_CHAN 2 #define DMA_IUA_CHAN 2
#define DMA_IUB_CHAN 3 #define DMA_IUB_CHAN 3
#define DMA_IF 0x45 #define DMA_IF 0x45
#define DMA_IUA 0x46 #define DMA_IUA 0x46
#define DMA_IUB 0x47 #define DMA_IUB 0x47
#define DMA_C 0x48 #define DMA_C 0x48
#endif #endif

File diff suppressed because it is too large Load diff

View file

@ -1,358 +1,358 @@
/* 3b2_rev3_mmu.h: WE32201 MMU /* 3b2_rev3_mmu.h: WE32201 MMU
Copyright (c) 2020-2022, Seth J. Morabito Copyright (c) 2020-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_REV3_MMU_H_ #ifndef _3B2_REV3_MMU_H_
#define _3B2_REV3_MMU_H_ #define _3B2_REV3_MMU_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define MMU_SRS 4 /* Section RAM array size (words) */ #define MMU_SRS 4 /* Section RAM array size (words) */
#define MMU_SDCS 8 /* SD Cache H/L array size */ #define MMU_SDCS 8 /* SD Cache H/L array size */
#define MMU_PDCS 64 /* PD Cache H/L array size */ #define MMU_PDCS 64 /* PD Cache H/L array size */
#define MMU_IDNCS 16 /* ID Number Cache array size */ #define MMU_IDNCS 16 /* ID Number Cache array size */
/* Register address offsets */ /* Register address offsets */
#define MMU_SDCL 0 /* SDC - Low Bits */ #define MMU_SDCL 0 /* SDC - Low Bits */
#define MMU_SDCH 1 /* SDC - High Bits */ #define MMU_SDCH 1 /* SDC - High Bits */
#define MMU_PDCL 2 /* PDC - Low Bits */ #define MMU_PDCL 2 /* PDC - Low Bits */
#define MMU_PDCH 3 /* PDC - High Bits */ #define MMU_PDCH 3 /* PDC - High Bits */
#define MMU_FDCR 4 /* Flush Data Cache Register */ #define MMU_FDCR 4 /* Flush Data Cache Register */
#define MMU_SRAMA 6 /* Section RAM A */ #define MMU_SRAMA 6 /* Section RAM A */
#define MMU_SRAMB 7 /* Section RAM B */ #define MMU_SRAMB 7 /* Section RAM B */
#define MMU_FC 8 /* Fault Code */ #define MMU_FC 8 /* Fault Code */
#define MMU_FA 9 /* Fault Address */ #define MMU_FA 9 /* Fault Address */
#define MMU_CONF 10 /* Configuration */ #define MMU_CONF 10 /* Configuration */
#define MMU_VAR 11 /* Virtual Address Register */ #define MMU_VAR 11 /* Virtual Address Register */
#define MMU_IDC 12 /* ID Number Cache */ #define MMU_IDC 12 /* ID Number Cache */
#define MMU_IDNR 13 /* ID Number Register */ #define MMU_IDNR 13 /* ID Number Register */
#define MMU_FIDNR 14 /* Flush ID Number Register */ #define MMU_FIDNR 14 /* Flush ID Number Register */
#define MMU_VR 15 /* Version Register */ #define MMU_VR 15 /* Version Register */
#define MMU_REV3_VER 0x23 /* Version byte returned by WE32201 MMU */ #define MMU_REV3_VER 0x23 /* Version byte returned by WE32201 MMU */
#define MMU_CONF_M (mmu_state.conf & 0x1) #define MMU_CONF_M (mmu_state.conf & 0x1)
#define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1) #define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1)
#define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1) #define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1)
#define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3) #define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3)
#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5) #define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5)
#define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6) #define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6)
/* Shift and mask the flag bits for the current CPU mode */ /* Shift and mask the flag bits for the current CPU mode */
#define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3) #define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3)
/* Codes set in the MMU Fault register */ /* Codes set in the MMU Fault register */
#define MMU_F_MISS_MEM 1 #define MMU_F_MISS_MEM 1
#define MMU_F_RM_UPD 2 #define MMU_F_RM_UPD 2
#define MMU_F_SDTLEN 3 #define MMU_F_SDTLEN 3
#define MMU_F_PW 4 #define MMU_F_PW 4
#define MMU_F_PDTLEN 5 #define MMU_F_PDTLEN 5
#define MMU_F_INV_SD 6 #define MMU_F_INV_SD 6
#define MMU_F_SEG_NOT_PRES 7 #define MMU_F_SEG_NOT_PRES 7
#define MMU_F_PDT_NOT_PRES 9 #define MMU_F_PDT_NOT_PRES 9
#define MMU_F_PAGE_NOT_PRES 10 #define MMU_F_PAGE_NOT_PRES 10
#define MMU_F_INDIRECT 11 #define MMU_F_INDIRECT 11
#define MMU_F_ACC 13 #define MMU_F_ACC 13
#define MMU_F_SEG_OFFSET 14 #define MMU_F_SEG_OFFSET 14
/* Access Request types */ /* Access Request types */
#define ACC_MT 0 /* Move Translated */ #define ACC_MT 0 /* Move Translated */
#define ACC_SPW 1 /* Support processor write */ #define ACC_SPW 1 /* Support processor write */
#define ACC_SPF 3 /* Support processor fetch */ #define ACC_SPF 3 /* Support processor fetch */
#define ACC_IR 7 /* Interlocked read */ #define ACC_IR 7 /* Interlocked read */
#define ACC_AF 8 /* Address fetch */ #define ACC_AF 8 /* Address fetch */
#define ACC_OF 9 /* Operand fetch */ #define ACC_OF 9 /* Operand fetch */
#define ACC_W 10 /* Write */ #define ACC_W 10 /* Write */
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ #define ACC_IFAD 12 /* Instruction fetch after discontinuity */
#define ACC_IF 13 /* Instruction fetch */ #define ACC_IF 13 /* Instruction fetch */
/* Pluck out Virtual Address fields */ /* Pluck out Virtual Address fields */
#define SID(va) (((va) >> 30) & 3) #define SID(va) (((va) >> 30) & 3)
#define SSL(va) (((va) >> 17) & 0x1fff) #define SSL(va) (((va) >> 17) & 0x1fff)
#define SOT(va) (va & 0x1ffff) #define SOT(va) (va & 0x1ffff)
/* PSL will be either: /* PSL will be either:
* - Bits 11-16 (2K pages: MMU_CONF_PS = 0) * - Bits 11-16 (2K pages: MMU_CONF_PS = 0)
* - Bits 12-16 (4K pages: MMU_CONF_PS = 1) * - Bits 12-16 (4K pages: MMU_CONF_PS = 1)
* - Bits 13-16 (8K pages: MMU_CONF_PS = 2) * - Bits 13-16 (8K pages: MMU_CONF_PS = 2)
*/ */
#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS)) #define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS))
#define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS])) #define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS]))
/* POT will be either: /* POT will be either:
* - Bits 0-10 (2K pages: MMU_CONF_PS = 0) * - Bits 0-10 (2K pages: MMU_CONF_PS = 0)
* - Bits 0-11 (4K pages: MMU_CONF_PS = 1) * - Bits 0-11 (4K pages: MMU_CONF_PS = 1)
* - Bits 0-12 (8K pages: MMU_CONF_PS = 2) * - Bits 0-12 (8K pages: MMU_CONF_PS = 2)
*/ */
#define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS)))) #define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS))))
/* Get the maximum length of an SSL from SRAMB */ /* Get the maximum length of an SSL from SRAMB */
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len) #define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len)
/* Pluck out Segment Descriptor fields */ /* Pluck out Segment Descriptor fields */
#define SD_PRESENT(sd_lo) ((sd_lo) & 1) #define SD_PRESENT(sd_lo) ((sd_lo) & 1)
#define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1) #define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1)
#define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1) #define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1)
#define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1) #define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1)
#define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1) #define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1)
#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f) #define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f)
#define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff) #define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff)
#define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u) #define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u)
#define SD_P_MASK 0x1 #define SD_P_MASK 0x1
#define SD_M_MASK 0x2 #define SD_M_MASK 0x2
#define SD_C_MASK 0x4 #define SD_C_MASK 0x4
#define SD_CACHE_MASK 0x8 #define SD_CACHE_MASK 0x8
#define SD_R_MASK 0x20 #define SD_R_MASK 0x20
#define SD_V_MASK 0x40 #define SD_V_MASK 0x40
#define SD_MAX_OFF_MASK 0xfc0000 #define SD_MAX_OFF_MASK 0xfc0000
#define SD_ACC_MASK 0xff000000u #define SD_ACC_MASK 0xff000000u
#define SD_ADDR_MASK 0xfffffff8u #define SD_ADDR_MASK 0xfffffff8u
#define SD_VADDR_MASK 0xfff00000u #define SD_VADDR_MASK 0xfff00000u
#define SD_RES_MASK 0xfffc00efu #define SD_RES_MASK 0xfffc00efu
#define SDC_VADDR_MASK 0xfff #define SDC_VADDR_MASK 0xfff
#define SDC_ACC_MASK 0xff000000u #define SDC_ACC_MASK 0xff000000u
#define SDC_MAX_OFF_MASK 0x001f8000 #define SDC_MAX_OFF_MASK 0x001f8000
#define SDC_G_MASK 0x1 #define SDC_G_MASK 0x1
#define SDC_C_MASK 0x2 #define SDC_C_MASK 0x2
#define SDC_CACHE_MASK 0x4 #define SDC_CACHE_MASK 0x4
#define SDC_M_MASK 0x400000 #define SDC_M_MASK 0x400000
#define SDC_R_MASK 0x800000 #define SDC_R_MASK 0x800000
#define PD_P_MASK 0x1 #define PD_P_MASK 0x1
#define PD_M_MASK 0x2 #define PD_M_MASK 0x2
#define PD_W_MASK 0x10 #define PD_W_MASK 0x10
#define PD_R_MASK 0x20 #define PD_R_MASK 0x20
#define PD_PADDR_MASK 0xfffff800u #define PD_PADDR_MASK 0xfffff800u
#define PDC_PADDR_MASK 0x1fffff #define PDC_PADDR_MASK 0x1fffff
#define PDC_C_MASK 0x2 #define PDC_C_MASK 0x2
#define PDC_W_MASK 0x200000 #define PDC_W_MASK 0x200000
#define PDC_M_MASK 0x400000 #define PDC_M_MASK 0x400000
#define PDC_R_MASK 0x800000 #define PDC_R_MASK 0x800000
#define PDC_G_MASK 0x40000000 #define PDC_G_MASK 0x40000000
#define PDC_U_MASK 0x80000000u #define PDC_U_MASK 0x80000000u
#define MAX_INDIRECTS 3 #define MAX_INDIRECTS 3
#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS])) #define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS]))
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8)) #define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
#define SDC_IDX(va) ((uint8)((va) >> 17) & 7) #define SDC_IDX(va) ((uint8)((va) >> 17) & 7)
/* Convert from sd to sd cache entry */ /* Convert from sd to sd cache entry */
#define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \ #define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \
((lo) & SD_C_MASK) >> 1 | \ ((lo) & SD_C_MASK) >> 1 | \
((lo) & SD_CACHE_MASK) >> 1 | \ ((lo) & SD_CACHE_MASK) >> 1 | \
(SDC_G_MASK)) (SDC_G_MASK))
#define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \ #define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \
((lo) & SD_MAX_OFF_MASK) >> 3 | \ ((lo) & SD_MAX_OFF_MASK) >> 3 | \
((lo) & SD_R_MASK) << 18 | \ ((lo) & SD_R_MASK) << 18 | \
((lo) & SD_M_MASK) << 21 | \ ((lo) & SD_M_MASK) << 21 | \
((va) & SD_VADDR_MASK) >> 20) ((va) & SD_VADDR_MASK) >> 20)
/* Convert from sd cache entry to sd */ /* Convert from sd cache entry to sd */
#define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK) #define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK)
#define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \ #define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \
((lo) & SDC_MAX_OFF_MASK) << 3 | \ ((lo) & SDC_MAX_OFF_MASK) << 3 | \
((lo) & SDC_R_MASK) >> 18 | \ ((lo) & SDC_R_MASK) >> 18 | \
((lo) & SDC_M_MASK) >> 21 | \ ((lo) & SDC_M_MASK) >> 21 | \
((hi) & SDC_C_MASK) << 1 | \ ((hi) & SDC_C_MASK) << 1 | \
((hi) & SDC_CACHE_MASK) << 1 | \ ((hi) & SDC_CACHE_MASK) << 1 | \
SD_V_MASK | SD_P_MASK) SD_V_MASK | SD_P_MASK)
/* Convert from pd cache entry to pd */ /* Convert from pd cache entry to pd */
#define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \ #define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \
(((pdcl) & PDC_W_MASK) >> 17) | \ (((pdcl) & PDC_W_MASK) >> 17) | \
(((pdcl) & PDC_M_MASK) >> 21) | \ (((pdcl) & PDC_M_MASK) >> 21) | \
(((pdcl) & PDC_R_MASK) >> 18) | \ (((pdcl) & PDC_R_MASK) >> 18) | \
PD_P_MASK) PD_P_MASK)
/* Convert from pd to pd cache entry (low word) */ /* Convert from pd to pd cache entry (low word) */
#define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \ #define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \
(((pd) & PD_W_MASK) << 17) | \ (((pd) & PD_W_MASK) << 17) | \
(((pd) & PD_M_MASK) << 21) | \ (((pd) & PD_M_MASK) << 21) | \
(((pd) & PD_R_MASK) << 18) | \ (((pd) & PD_R_MASK) << 18) | \
((sd_lo) & SD_ACC_MASK)) ((sd_lo) & SD_ACC_MASK))
/* Convert from va to pd cache entry (high word / tag) */ /* Convert from va to pd cache entry (high word / tag) */
#define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \ #define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \
(mmu_state.cidnr[SID(va)] << 26) | \ (mmu_state.cidnr[SID(va)] << 26) | \
((va & 0xfffff800u) >> 6) | \ ((va & 0xfffff800u) >> 6) | \
((sd_lo & SD_CACHE_MASK) >> 1) | \ ((sd_lo & SD_CACHE_MASK) >> 1) | \
((sd_lo & SD_C_MASK) >> 1)) ((sd_lo & SD_C_MASK) >> 1))
/* Maximum offset (in bytes) of a paged segment */ /* Maximum offset (in bytes) of a paged segment */
#define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1) #define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1)
#define IDNC_TAG(val) ((val) & 0xfffffff8) #define IDNC_TAG(val) ((val) & 0xfffffff8)
#define IDNC_U(val) ((val) & 0x1) #define IDNC_U(val) ((val) & 0x1)
/* Fault codes */ /* Fault codes */
#define MMU_FAULT(f) { \ #define MMU_FAULT(f) { \
if (fc) { \ if (fc) { \
mmu_state.fcode = ((((uint32)r_acc)<<7) | \ mmu_state.fcode = ((((uint32)r_acc)<<7) | \
(((uint32)(CPU_CM))<<5) | \ (((uint32)(CPU_CM))<<5) | \
(f & 0x1f)); \ (f & 0x1f)); \
mmu_state.faddr = va; \ mmu_state.faddr = va; \
} \ } \
} }
typedef struct { typedef struct {
uint32 addr; uint32 addr;
uint32 len; uint32 len;
} mmu_sec; } mmu_sec;
/* /*
* Segment Descriptor Cache Entry Format * Segment Descriptor Cache Entry Format
* ===================================== * =====================================
* *
* The Segment Descriptor Cache is a directly mapped cache, indexed by * The Segment Descriptor Cache is a directly mapped cache, indexed by
* bits 19, 18, and 17 of the virtual address. Some notes: * bits 19, 18, and 17 of the virtual address. Some notes:
* *
* - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all * - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all
* copied from the SD in main memory. * copied from the SD in main memory.
* - "VAddr" holds bits 20-31 of the virtual address * - "VAddr" holds bits 20-31 of the virtual address
* - "Address" holds a pointer (word-aligned, so the top 30 bits) to * - "Address" holds a pointer (word-aligned, so the top 30 bits) to
* a page descriptor table in paged mode, or a segment in * a page descriptor table in paged mode, or a segment in
* contiguous segment mode. * contiguous segment mode.
* - "Max Offset" holds the number of pages minus one in the * - "Max Offset" holds the number of pages minus one in the
* segment. Depending on current page size, various bits of this * segment. Depending on current page size, various bits of this
* field will be ignored: * field will be ignored:
* o Bits 20-15 are used for 2K pages * o Bits 20-15 are used for 2K pages
* o Bits 20-16 are used for 4K pages * o Bits 20-16 are used for 4K pages
* o Bits 20-17 are used for 8K pages * o Bits 20-17 are used for 8K pages
* *
* Low Word (bits 0-31) * Low Word (bits 0-31)
* -------------------- * --------------------
* *
* 31 24 23 22 21 20 15 14 12 11 0 * 31 24 23 22 21 20 15 14 12 11 0
* +-------+---+---+---+------------+------+--------------------------+ * +-------+---+---+---+------------+------+--------------------------+
* | Acc | R | M | - | Max Offset | - | VAddr | * | Acc | R | M | - | Max Offset | - | VAddr |
* +-------+---+---+---+------------+------+--------------------------+ * +-------+---+---+---+------------+------+--------------------------+
* *
* High Word (bits 32-63) * High Word (bits 32-63)
* ---------------------- * ----------------------
* *
* 31 3 2 1 0 * 31 3 2 1 0
* +------------------------------------------------------+---+---+---+ * +------------------------------------------------------+---+---+---+
* | Address | $ | C | G | * | Address | $ | C | G |
* +------------------------------------------------------+---+---+---+ * +------------------------------------------------------+---+---+---+
* *
* *
* Page Descriptor Cache Entry Format * Page Descriptor Cache Entry Format
* ================================== * ==================================
* *
* The Page Descriptor Cache is a fully associative cache, with a * The Page Descriptor Cache is a fully associative cache, with a
* tag constructed from the "G" and "IDN" bits, and bits 31-11 of * tag constructed from the "G" and "IDN" bits, and bits 31-11 of
* the virtual address. * the virtual address.
* *
* Depending on the current page size and access mode, various bits of * Depending on the current page size and access mode, various bits of
* "VAddr" are ignored. * "VAddr" are ignored.
* *
* o Multi-context mode, all ops except single-entry flush: * o Multi-context mode, all ops except single-entry flush:
* VAddr bits 29-11 are used. * VAddr bits 29-11 are used.
* o Multi-context mode, single-entry flush: * o Multi-context mode, single-entry flush:
* VAddr bits 31-11 are used. * VAddr bits 31-11 are used.
* o Single-context mode, all ops: * o Single-context mode, all ops:
* Vaddr bits 31-11 are used. * Vaddr bits 31-11 are used.
* o In ALL CASES: * o In ALL CASES:
* + 2KB Page Size: Bits 11-12 are used. * + 2KB Page Size: Bits 11-12 are used.
* + 4KB Page Size: Bit 11 ignored, 12 used. * + 4KB Page Size: Bit 11 ignored, 12 used.
* + 8KB Page Size: Bits 11-12 ignored. * + 8KB Page Size: Bits 11-12 ignored.
* *
* Low Word (bits 0-31) * Low Word (bits 0-31)
* -------------------- * --------------------
* *
* 31 24 23 22 21 20 0 * 31 24 23 22 21 20 0
* +-------+---+---+---+----------------------------------------------+ * +-------+---+---+---+----------------------------------------------+
* | Acc | R | M | W | Physical Address | * | Acc | R | M | W | Physical Address |
* +-------+---+---+---+----------------------------------------------+ * +-------+---+---+---+----------------------------------------------+
* *
* *
* High Word (bits 32-63) * High Word (bits 32-63)
* ---------------------- * ----------------------
* *
* 31 30 29 26 25 5 4 3 2 1 0 * 31 30 29 26 25 5 4 3 2 1 0
* +---+---+---------+----------------------------+-------+---+---+---+ * +---+---+---------+----------------------------+-------+---+---+---+
* | U | G | IDN | (31) VAddr (11)| - | $ | C | - | * | U | G | IDN | (31) VAddr (11)| - | $ | C | - |
* +---+---+---------+----------------------------+-------+---+---+---+ * +---+---+---------+----------------------------+-------+---+---+---+
* *
*/ */
typedef struct _mmu_state { typedef struct _mmu_state {
t_bool enabled; /* Global enabled/disabled flag */ t_bool enabled; /* Global enabled/disabled flag */
t_bool flush_u; /* If true, flush all but last cached entry */ t_bool flush_u; /* If true, flush all but last cached entry */
uint32 last_cached; /* The index of the last cached PDC entry */ uint32 last_cached; /* The index of the last cached PDC entry */
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */ uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */ uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */
uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */ uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */
uint32 sra[4]; /* Section RAM A */ uint32 sra[4]; /* Section RAM A */
uint32 srb[4]; /* Section RAM B */ uint32 srb[4]; /* Section RAM B */
uint32 cidnr[4]; /* Current ID Number Registers */ uint32 cidnr[4]; /* Current ID Number Registers */
uint32 idnc[16]; /* ID Number Cache */ uint32 idnc[16]; /* ID Number Cache */
mmu_sec sec[4]; /* Section descriptors decoded from mmu_sec sec[4]; /* Section descriptors decoded from
Section RAM A and B */ Section RAM A and B */
uint32 fcode; /* Fault Code Register */ uint32 fcode; /* Fault Code Register */
uint32 faddr; /* Fault Address Register */ uint32 faddr; /* Fault Address Register */
uint32 conf; /* Configuration Register */ uint32 conf; /* Configuration Register */
uint32 var; /* Virtual Address Register */ uint32 var; /* Virtual Address Register */
} MMU_STATE; } MMU_STATE;
t_stat mmu_init(DEVICE *dptr); t_stat mmu_init(DEVICE *dptr);
uint32 mmu_read(uint32 pa, size_t size); uint32 mmu_read(uint32 pa, size_t size);
void mmu_write(uint32 pa, uint32 val, size_t size); void mmu_write(uint32 pa, uint32 val, size_t size);
CONST char *mmu_description(DEVICE *dptr); CONST char *mmu_description(DEVICE *dptr);
/* Virtual memory translation */ /* Virtual memory translation */
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc); uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
t_bool fc, uint32 *pa); t_bool fc, uint32 *pa);
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
void mmu_enable(); void mmu_enable();
void mmu_disable(); void mmu_disable();
t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
#endif /* _3B2_REV3_MMU_H_ */ #endif /* _3B2_REV3_MMU_H_ */

View file

@ -1,80 +1,80 @@
/* 3b2_rev3_sys.c: Version 3 (3B2/700) System Definition /* 3b2_rev3_sys.c: Version 3 (3B2/700) System Definition
Copyright (c) 2020-2022, Seth J. Morabito Copyright (c) 2020-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_defs.h" #include "3b2_defs.h"
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_csr.h" #include "3b2_csr.h"
#include "3b2_if.h" #include "3b2_if.h"
#include "3b2_iu.h" #include "3b2_iu.h"
#include "3b2_mau.h" #include "3b2_mau.h"
#include "3b2_ni.h" #include "3b2_ni.h"
#include "3b2_ports.h" #include "3b2_ports.h"
#include "3b2_scsi.h" #include "3b2_scsi.h"
#include "3b2_stddev.h" #include "3b2_stddev.h"
#include "3b2_timer.h" #include "3b2_timer.h"
char sim_name[] = "AT&T 3B2/700"; char sim_name[] = "AT&T 3B2/700";
DEVICE *sim_devices[] = { DEVICE *sim_devices[] = {
&cpu_dev, &cpu_dev,
&csr_dev, &csr_dev,
&flt_dev, &flt_dev,
&mmu_dev, &mmu_dev,
&mau_dev, &mau_dev,
&timer_dev, &timer_dev,
&tod_dev, &tod_dev,
&nvram_dev, &nvram_dev,
&tti_dev, &tti_dev,
&tto_dev, &tto_dev,
&contty_dev, &contty_dev,
&iu_timer_dev, &iu_timer_dev,
&dmac_dev, &dmac_dev,
&if_dev, &if_dev,
&ha_dev, &ha_dev,
&ports_dev, &ports_dev,
&ni_dev, &ni_dev,
NULL NULL
}; };
void full_reset() void full_reset()
{ {
cpu_reset(&cpu_dev); cpu_reset(&cpu_dev);
mau_reset(&mau_dev); mau_reset(&mau_dev);
tti_reset(&tti_dev); tti_reset(&tti_dev);
contty_reset(&contty_dev); contty_reset(&contty_dev);
iu_timer_reset(&iu_timer_dev); iu_timer_reset(&iu_timer_dev);
timer_reset(&timer_dev); timer_reset(&timer_dev);
if_reset(&if_dev); if_reset(&if_dev);
ha_reset(&ha_dev); ha_reset(&ha_dev);
csr_reset(&csr_dev); csr_reset(&csr_dev);
ports_reset(&ports_dev); ports_reset(&ports_dev);
ni_reset(&ni_dev); ni_reset(&ni_dev);
} }

File diff suppressed because it is too large Load diff

View file

@ -1,288 +1,288 @@
/* 3b2_scsi.h: CM195W SCSI Controller CIO Card /* 3b2_scsi.h: CM195W SCSI Controller CIO Card
Copyright (c) 2020-2022, Seth J. Morabito Copyright (c) 2020-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_SCSI_H_ #ifndef _3B2_SCSI_H_
#define _3B2_SCSI_H_ #define _3B2_SCSI_H_
#include "3b2_defs.h" #include "3b2_defs.h"
/* CIO Opcodes */ /* CIO Opcodes */
#define HA_BOOT 0x0a #define HA_BOOT 0x0a
#define HA_READ_BLK 0x0b #define HA_READ_BLK 0x0b
#define HA_WRITE_BLK 0x0c #define HA_WRITE_BLK 0x0c
#define HA_CNTRL 0x20 #define HA_CNTRL 0x20
#define HA_VERS 0x40 #define HA_VERS 0x40
#define HA_DL_EEDT 0x42 #define HA_DL_EEDT 0x42
#define HA_UL_EEDT 0x43 #define HA_UL_EEDT 0x43
#define HA_EDSD 0x44 #define HA_EDSD 0x44
#define HA_RESET 0x45 #define HA_RESET 0x45
#define HA_TESTRDY 0x00 #define HA_TESTRDY 0x00
#define HA_FORMAT 0x04 #define HA_FORMAT 0x04
#define HA_WRITE 0x0a #define HA_WRITE 0x0a
#define HA_INQUIRY 0x12 #define HA_INQUIRY 0x12
#define HA_MODESEL 0x15 #define HA_MODESEL 0x15
#define HA_MODESNS 0x1a #define HA_MODESNS 0x1a
#define HA_RDCPCTY 0x25 #define HA_RDCPCTY 0x25
#define HA_READ 0x08 #define HA_READ 0x08
#define HA_READEXT 0x28 #define HA_READEXT 0x28
#define HA_WRTEXT 0x2a #define HA_WRTEXT 0x2a
#define HA_VERIFY 0x2f #define HA_VERIFY 0x2f
#define HA_PDLS_OFF 0x28 #define HA_PDLS_OFF 0x28
/* CIO Status */ /* CIO Status */
#define CIO_TIMEOUT 0x65 #define CIO_TIMEOUT 0x65
#define HA_BOOT_ADDR 0x2004000 #define HA_BOOT_ADDR 0x2004000
#define HA_PDINFO_ADDR 0x2004400 #define HA_PDINFO_ADDR 0x2004400
#define HA_ID 0x0100 #define HA_ID 0x0100
#define HA_IPL 12 #define HA_IPL 12
#define HA_GOOD 0x00 #define HA_GOOD 0x00
#define HA_CKCON 0x02 #define HA_CKCON 0x02
#define HA_DSD_DISK 0x100 #define HA_DSD_DISK 0x100
#define HA_DSD_TAPE 0x101 #define HA_DSD_TAPE 0x101
#define HA_VERSION 0x01 #define HA_VERSION 0x01
#define SCQRESIZE 24 #define SCQRESIZE 24
#define RAPP_LEN (SCQRESIZE - 8) #define RAPP_LEN (SCQRESIZE - 8)
#define SCQCESIZE 16 #define SCQCESIZE 16
#define CAPP_LEN (SCQCESIZE - 8) #define CAPP_LEN (SCQCESIZE - 8)
#define FC_TC(x) (((x) >> 3) & 7) #define FC_TC(x) (((x) >> 3) & 7)
#define FC_LU(x) ((x) & 7) #define FC_LU(x) ((x) & 7)
#define HA_EDT_LEN 1024 #define HA_EDT_LEN 1024
#define HA_BLKSZ 512 #define HA_BLKSZ 512
#define HA_MAX_CMD 12 #define HA_MAX_CMD 12
#define INQUIRY_MAX 36 #define INQUIRY_MAX 36
#define HA_STAT(tc,ha_stat,cio_stat) { \ #define HA_STAT(tc,ha_stat,cio_stat) { \
ha_state.ts[tc].rep.ssb = (ha_stat); \ ha_state.ts[tc].rep.ssb = (ha_stat); \
ha_state.ts[tc].rep.status = (cio_stat); \ ha_state.ts[tc].rep.status = (cio_stat); \
} }
#define HA_MAX_DTYPE 4 #define HA_MAX_DTYPE 4
/* Hardware Notes /* Hardware Notes
* ============== * ==============
* *
* Disk Drives * Disk Drives
* ----------- * -----------
* *
* There are two emulated SCSI disk drives available. * There are two emulated SCSI disk drives available.
* *
* 1. 155 MB CDC Wren III (CDC 94161-9) * 1. 155 MB CDC Wren III (CDC 94161-9)
* 2. 327 MB CDC Wren IV (CDC 94171-9) * 2. 327 MB CDC Wren IV (CDC 94171-9)
* *
* The CDC 94161-9 was also OEMed as the "AT&T KS23483,L3" * The CDC 94161-9 was also OEMed as the "AT&T KS23483,L3"
* The CDC 94171-9 was also OEMed as the "AT&T KS23483,L25" * The CDC 94171-9 was also OEMed as the "AT&T KS23483,L25"
* *
* *
* Tape Drive * Tape Drive
* ---------- * ----------
* *
* Wangtek 5125EN (AT&T Part number KS23417,L2) * Wangtek 5125EN (AT&T Part number KS23417,L2)
* *
* DC600A cartridge tape at 120MB (QIC-120 format) * DC600A cartridge tape at 120MB (QIC-120 format)
* *
*/ */
/* Other SCSI hard disk types /* Other SCSI hard disk types
* --------------------------- * ---------------------------
* *
* These geometries are supported natively and automatically * These geometries are supported natively and automatically
* by System V Release 3.2.3 UNIX. * by System V Release 3.2.3 UNIX.
* *
* 1. CDC 94161-9 155 MB/148 MiB 512 B/s, 35 s/t, 9 head, 965 cyl * 1. CDC 94161-9 155 MB/148 MiB 512 B/s, 35 s/t, 9 head, 965 cyl
* 2. AT&T KS23483 327 MB/312 MiB 512 B/s, 46 s/t, 9 head, 1547 cyl * 2. AT&T KS23483 327 MB/312 MiB 512 B/s, 46 s/t, 9 head, 1547 cyl
* (a.k.a CDC 94171-9) * (a.k.a CDC 94171-9)
* *
* Also supported was a SCSI-to-ESDI bridge controller that used the * Also supported was a SCSI-to-ESDI bridge controller that used the
* Emulex MD23/S2 SCSI-to-ESDI bridge. It allowed up to four ESDI * Emulex MD23/S2 SCSI-to-ESDI bridge. It allowed up to four ESDI
* drives to be mapped as LUNs 0-3. * drives to be mapped as LUNs 0-3.
* *
*/ */
/* AT&T 155 MB Hard Disk (35 sec/t, 9 hd, 964 cyl) */ /* AT&T 155 MB Hard Disk (35 sec/t, 9 hd, 964 cyl) */
#define SD155_DTYPE 0 #define SD155_DTYPE 0
#define SD155_PQUAL 0x00 #define SD155_PQUAL 0x00
#define SD155_SCSI 1 #define SD155_SCSI 1
#define SD155_BLK 512 #define SD155_BLK 512
#define SD155_LBN 303660 #define SD155_LBN 303660
#define SD155_MANU "AT&T" #define SD155_MANU "AT&T"
#define SD155_DESC "KS23483" #define SD155_DESC "KS23483"
#define SD155_REV "0000" #define SD155_REV "0000"
/* AT&T 300 MB Hard Disk (43 sec/t, 9 hd, 1514 cyl) */ /* AT&T 300 MB Hard Disk (43 sec/t, 9 hd, 1514 cyl) */
#define SD300_DTYPE 1 #define SD300_DTYPE 1
#define SD300_PQUAL 0x00 #define SD300_PQUAL 0x00
#define SD300_SCSI 1 #define SD300_SCSI 1
#define SD300_BLK 512 #define SD300_BLK 512
#define SD300_LBN 585937 #define SD300_LBN 585937
#define SD300_MANU "AT&T" #define SD300_MANU "AT&T"
#define SD300_DESC "KS23483" #define SD300_DESC "KS23483"
#define SD300_REV "0000" #define SD300_REV "0000"
/* AT&T 327 MB Hard Disk (46 sec/t, 9 hd, 1547 cyl) */ /* AT&T 327 MB Hard Disk (46 sec/t, 9 hd, 1547 cyl) */
#define SD327_DTYPE 2 #define SD327_DTYPE 2
#define SD327_PQUAL 0x00 #define SD327_PQUAL 0x00
#define SD327_SCSI 1 #define SD327_SCSI 1
#define SD327_BLK 512 #define SD327_BLK 512
#define SD327_LBN 640458 #define SD327_LBN 640458
#define SD327_MANU "AT&T" #define SD327_MANU "AT&T"
#define SD327_DESC "KS23483" #define SD327_DESC "KS23483"
#define SD327_REV "0000" #define SD327_REV "0000"
/* AT&T 630 MB Hard Disk (56 sec/t, 16 hd, 1447 cyl) */ /* AT&T 630 MB Hard Disk (56 sec/t, 16 hd, 1447 cyl) */
#define SD630_DTYPE 3 #define SD630_DTYPE 3
#define SD630_PQUAL 0x00 #define SD630_PQUAL 0x00
#define SD630_SCSI 1 #define SD630_SCSI 1
#define SD630_BLK 512 #define SD630_BLK 512
#define SD630_LBN 1296512 #define SD630_LBN 1296512
#define SD630_MANU "AT&T" #define SD630_MANU "AT&T"
#define SD630_DESC "KS23483" #define SD630_DESC "KS23483"
#define SD630_REV "0000" #define SD630_REV "0000"
/* Wangtek 120MB cartridge tape */ /* Wangtek 120MB cartridge tape */
#define ST120_DTYPE 4 #define ST120_DTYPE 4
#define ST120_PQUAL 0x00 #define ST120_PQUAL 0x00
#define ST120_SCSI 1 #define ST120_SCSI 1
#define ST120_BLK 512 #define ST120_BLK 512
#define ST120_LBN 1 #define ST120_LBN 1
#define ST120_MANU "WANGTEK" #define ST120_MANU "WANGTEK"
#define ST120_DESC "KS23465" #define ST120_DESC "KS23465"
#define ST120_REV "CX17" #define ST120_REV "CX17"
#define UNIT_V_DTYPE (SCSI_V_UF + 0) #define UNIT_V_DTYPE (SCSI_V_UF + 0)
#define UNIT_M_DTYPE 0x1f #define UNIT_M_DTYPE 0x1f
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE) #define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE) #define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
#define HA_DISK(d) \ #define HA_DISK(d) \
{ SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \ { SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d } d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
#define HA_TAPE(d) \ #define HA_TAPE(d) \
{ SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \ { SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d } d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
#define HA_SIZE(d) d##_LBN #define HA_SIZE(d) d##_LBN
#define HA_JOB_QUICK 0 #define HA_JOB_QUICK 0
#define HA_JOB_EXPRESS 1 #define HA_JOB_EXPRESS 1
#define HA_JOB_FULL 2 #define HA_JOB_FULL 2
typedef uint8 ha_jobtype; typedef uint8 ha_jobtype;
typedef struct { typedef struct {
uint32 addr; uint32 addr;
uint32 len; uint32 len;
} haddr; } haddr;
/* /*
* SCSI Command Request * SCSI Command Request
*/ */
typedef struct { typedef struct {
uint8 op; /* Destructured from the cmd byte array */ uint8 op; /* Destructured from the cmd byte array */
uint8 tc; uint8 tc;
uint8 lu; uint8 lu;
uint32 timeout; uint32 timeout;
uint8 dlen; uint8 dlen;
haddr daddr[48]; /* Support up to 48 transfer addresses */ haddr daddr[48]; /* Support up to 48 transfer addresses */
uint32 dma_lst; uint32 dma_lst;
uint16 cmd_len; uint16 cmd_len;
uint8 cmd[HA_MAX_CMD]; uint8 cmd[HA_MAX_CMD];
} ha_req; } ha_req;
/* /*
* SCSI Command Response * SCSI Command Response
*/ */
typedef struct { typedef struct {
ha_jobtype type; /* Job type */ ha_jobtype type; /* Job type */
uint8 status; /* Result Status */ uint8 status; /* Result Status */
uint8 op; /* Command Opcode */ uint8 op; /* Command Opcode */
uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */ uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */
uint8 ssb; /* SCSI Status Byte */ uint8 ssb; /* SCSI Status Byte */
uint32 addr; /* Response address */ uint32 addr; /* Response address */
uint32 len; /* Response length */ uint32 len; /* Response length */
} ha_resp; } ha_resp;
#define PUMP_NONE 0 #define PUMP_NONE 0
#define PUMP_SYSGEN 1 #define PUMP_SYSGEN 1
#define PUMP_COMPLETE 2 #define PUMP_COMPLETE 2
/* /*
* SCSI Target state * SCSI Target state
*/ */
typedef struct { typedef struct {
t_bool pending; /* Service pending */ t_bool pending; /* Service pending */
ha_req req; /* SCSI job request */ ha_req req; /* SCSI job request */
ha_resp rep; /* SCSI job reply */ ha_resp rep; /* SCSI job reply */
} ha_ts; } ha_ts;
/* /*
* General SCSI HA internal state. * General SCSI HA internal state.
*/ */
typedef struct { typedef struct {
uint8 slot; /* Card Backsplane Slot # */ uint8 slot; /* Card Backsplane Slot # */
uint32 pump_state; uint32 pump_state;
t_bool frq; /* Fast Request Queue enabled */ t_bool frq; /* Fast Request Queue enabled */
uint8 edt[HA_EDT_LEN]; /* Equipped Device Table */ uint8 edt[HA_EDT_LEN]; /* Equipped Device Table */
ha_ts ts[8]; /* Target state */ ha_ts ts[8]; /* Target state */
} HA_STATE; } HA_STATE;
t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat ha_reset(DEVICE *dptr); t_stat ha_reset(DEVICE *dptr);
t_stat ha_svc(UNIT *uptr); t_stat ha_svc(UNIT *uptr);
t_stat ha_rq_svc(UNIT *uptr); t_stat ha_rq_svc(UNIT *uptr);
t_stat ha_attach(UNIT *uptr, CONST char *cptr); t_stat ha_attach(UNIT *uptr, CONST char *cptr);
t_stat ha_detach(UNIT *uptr); t_stat ha_detach(UNIT *uptr);
void ha_fast_queue_check(); void ha_fast_queue_check();
void ha_sysgen(uint8 slot); void ha_sysgen(uint8 slot);
void ha_express(uint8 slot); void ha_express(uint8 slot);
void ha_full(uint8 slot); void ha_full(uint8 slot);
/* Fast Completion */ /* Fast Completion */
void ha_fcm_express(uint8 target); void ha_fcm_express(uint8 target);
#endif /* _3B2_SCSI_H_ */ #endif /* _3B2_SCSI_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,138 +1,138 @@
/* 3b2_stddev.h: Miscellaneous System Board Devices /* 3b2_stddev.h: Miscellaneous System Board Devices
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_STDDEV_H_ #ifndef _3B2_STDDEV_H_
#define _3B2_STDDEV_H_ #define _3B2_STDDEV_H_
#include "3b2_defs.h" #include "3b2_defs.h"
/* NVRAM */ /* NVRAM */
t_stat nvram_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); t_stat nvram_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
t_stat nvram_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat nvram_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw);
t_stat nvram_reset(DEVICE *dptr); t_stat nvram_reset(DEVICE *dptr);
uint32 nvram_read(uint32 pa, size_t size); uint32 nvram_read(uint32 pa, size_t size);
t_stat nvram_attach(UNIT *uptr, CONST char *cptr); t_stat nvram_attach(UNIT *uptr, CONST char *cptr);
t_stat nvram_detach(UNIT *uptr); t_stat nvram_detach(UNIT *uptr);
const char *nvram_description(DEVICE *dptr); const char *nvram_description(DEVICE *dptr);
t_stat nvram_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat nvram_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
void nvram_write(uint32 pa, uint32 val, size_t size); void nvram_write(uint32 pa, uint32 val, size_t size);
typedef struct tod_data { typedef struct tod_data {
time_t time; /* System time */ time_t time; /* System time */
uint8 ctrl; /* Control register (Rev 3 only) */ uint8 ctrl; /* Control register (Rev 3 only) */
uint8 flags; /* Data Changed & Interrutpt Flags (Rev 3 only) */ uint8 flags; /* Data Changed & Interrutpt Flags (Rev 3 only) */
uint8 clkset; /* Clock / Setting register (Rev 3 only) */ uint8 clkset; /* Clock / Setting register (Rev 3 only) */
uint8 tsec; /* 1/100th seconds, 00-99 */ uint8 tsec; /* 1/100th seconds, 00-99 */
uint8 sec; /* Seconds, 00-59 */ uint8 sec; /* Seconds, 00-59 */
uint8 min; /* Minutes, 00-59 */ uint8 min; /* Minutes, 00-59 */
uint8 hour; /* Hours, 00-23 */ uint8 hour; /* Hours, 00-23 */
uint8 day; /* Days, 00-27, 28, 29, or 30 */ uint8 day; /* Days, 00-27, 28, 29, or 30 */
uint8 mon; /* Months, 00-11 */ uint8 mon; /* Months, 00-11 */
uint8 year; /* Years, 00-99 (Rev 3 only) */ uint8 year; /* Years, 00-99 (Rev 3 only) */
uint8 wday; /* Day of Week, 0-6 */ uint8 wday; /* Day of Week, 0-6 */
uint8 lyear; /* Years since last leap year */ uint8 lyear; /* Years since last leap year */
} TOD_DATA; } TOD_DATA;
#if defined(REV2) #if defined(REV2)
#define TOD_TEST 0x00 #define TOD_TEST 0x00
#define TOD_TSEC 0x04 #define TOD_TSEC 0x04
#define TOD_1SEC 0x08 #define TOD_1SEC 0x08
#define TOD_10SEC 0x0c #define TOD_10SEC 0x0c
#define TOD_1MIN 0x10 #define TOD_1MIN 0x10
#define TOD_10MIN 0x14 #define TOD_10MIN 0x14
#define TOD_1HOUR 0x18 #define TOD_1HOUR 0x18
#define TOD_10HOUR 0x1c #define TOD_10HOUR 0x1c
#define TOD_1DAY 0x20 #define TOD_1DAY 0x20
#define TOD_10DAY 0x24 #define TOD_10DAY 0x24
#define TOD_WDAY 0x28 #define TOD_WDAY 0x28
#define TOD_1MON 0x2c #define TOD_1MON 0x2c
#define TOD_10MON 0x30 #define TOD_10MON 0x30
#define TOD_1YEAR 0x34 #define TOD_1YEAR 0x34
#define TOD_STARTSTOP 0x38 #define TOD_STARTSTOP 0x38
#define TOD_INT 0x3c #define TOD_INT 0x3c
#else #else
#define TOD_FLAG_CHG 0x08 #define TOD_FLAG_CHG 0x08
#define TOD_FLAG_IRQ 0x01 #define TOD_FLAG_IRQ 0x01
#define TOD_CTRL 0x00 #define TOD_CTRL 0x00
#define TOD_TSEC 0x04 #define TOD_TSEC 0x04
#define TOD_1SEC 0x08 #define TOD_1SEC 0x08
#define TOD_10SEC 0x0c #define TOD_10SEC 0x0c
#define TOD_1MIN 0x10 #define TOD_1MIN 0x10
#define TOD_10MIN 0x14 #define TOD_10MIN 0x14
#define TOD_1HOUR 0x18 #define TOD_1HOUR 0x18
#define TOD_10HOUR 0x1c #define TOD_10HOUR 0x1c
#define TOD_1DAY 0x20 #define TOD_1DAY 0x20
#define TOD_10DAY 0x24 #define TOD_10DAY 0x24
#define TOD_1MON 0x28 #define TOD_1MON 0x28
#define TOD_10MON 0x2c #define TOD_10MON 0x2c
#define TOD_1YEAR 0x30 #define TOD_1YEAR 0x30
#define TOD_10YEAR 0x34 #define TOD_10YEAR 0x34
#define TOD_WDAY 0x38 #define TOD_WDAY 0x38
#define TOD_SET_INT 0x3c #define TOD_SET_INT 0x3c
#endif #endif
void tod_update_delta(); void tod_update_delta();
t_stat tod_reset(DEVICE *dptr); t_stat tod_reset(DEVICE *dptr);
t_stat tod_attach(UNIT *uptr, CONST char *cptr); t_stat tod_attach(UNIT *uptr, CONST char *cptr);
t_stat tod_detach(UNIT *uptr); t_stat tod_detach(UNIT *uptr);
t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *tod_description(DEVICE *dptr); const char *tod_description(DEVICE *dptr);
uint32 tod_read(uint32 pa, size_t size); uint32 tod_read(uint32 pa, size_t size);
void tod_write(uint32, uint32 val, size_t size); void tod_write(uint32, uint32 val, size_t size);
/* Global symbols */ /* Global symbols */
extern int32 tmxr_poll; extern int32 tmxr_poll;
#if defined(REV3) #if defined(REV3)
/* Fault Register */ /* Fault Register */
#define FLT_MSK 0xffffff00 #define FLT_MSK 0xffffff00
#define MEM_EQP 0x4 #define MEM_EQP 0x4
#define MEM_4M 0x2 #define MEM_4M 0x2
#define MEM_16M 0x3 #define MEM_16M 0x3
uint32 flt_read(uint32 pa, size_t size); uint32 flt_read(uint32 pa, size_t size);
void flt_write(uint32 pa, uint32 val, size_t size); void flt_write(uint32 pa, uint32 val, size_t size);
t_stat flt_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat flt_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *flt_description(DEVICE *dptr); const char *flt_description(DEVICE *dptr);
extern uint32 flt[2]; extern uint32 flt[2];
#endif /* defined(REV3) */ #endif /* defined(REV3) */
#endif /* _3B2_STDDEV_H_ */ #endif /* _3B2_STDDEV_H_ */

View file

@ -1,192 +1,192 @@
/* 3b2_sys.c: Common System Definition /* 3b2_sys.c: Common System Definition
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#include "3b2_sys.h" #include "3b2_sys.h"
#include "3b2_cpu.h" #include "3b2_cpu.h"
#include "3b2_mem.h" #include "3b2_mem.h"
REG *sim_PC = &cpu_reg[NUM_PC]; REG *sim_PC = &cpu_reg[NUM_PC];
/* All opcodes are 1 or 2 bytes. Operands may be up to 6 bytes, and /* All opcodes are 1 or 2 bytes. Operands may be up to 6 bytes, and
there may be up to 3 operands, for a maximum of 20 bytes */ there may be up to 3 operands, for a maximum of 20 bytes */
int32 sim_emax = 20; int32 sim_emax = 20;
const char *sim_stop_messages[SCPE_BASE] = { const char *sim_stop_messages[SCPE_BASE] = {
"Unknown error", "Unknown error",
"Reserved Instruction", "Reserved Instruction",
"Breakpoint", "Breakpoint",
"Invalid Opcode", "Invalid Opcode",
"IRQ", "IRQ",
"Exception/Trap", "Exception/Trap",
"Exception Stack Too Deep", "Exception Stack Too Deep",
"Unimplemented MMU Feature", "Unimplemented MMU Feature",
"System Powered Off", "System Powered Off",
"Infinite Loop", "Infinite Loop",
"Simulator Error" "Simulator Error"
}; };
/* /*
* ROM and Binary loader * ROM and Binary loader
* *
* -r load ROM * -r load ROM
* -o for memory, specify origin * -o for memory, specify origin
* *
*/ */
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
{ {
t_stat r; t_stat r;
int32 i; int32 i;
uint32 origin = 0, limit = 0; uint32 origin = 0, limit = 0;
int32 cnt = 0; int32 cnt = 0;
if (flag) { if (flag) {
return sim_messagef(SCPE_NOFNC, "Command not implemented."); return sim_messagef(SCPE_NOFNC, "Command not implemented.");
} }
if (sim_switches & SWMASK('R')) { if (sim_switches & SWMASK('R')) {
origin = ROM_BASE; origin = ROM_BASE;
limit = ROM_BASE + ROM_SIZE; limit = ROM_BASE + ROM_SIZE;
} else { } else {
origin = 0; origin = 0;
limit = (uint32) cpu_unit.capac; limit = (uint32) cpu_unit.capac;
if (sim_switches & SWMASK('O')) { if (sim_switches & SWMASK('O')) {
origin = (uint32) get_uint(cptr, 16, 0xffffffff, &r); origin = (uint32) get_uint(cptr, 16, 0xffffffff, &r);
if (r != SCPE_OK) { if (r != SCPE_OK) {
return SCPE_ARG; return SCPE_ARG;
} }
} }
} }
while ((i = Fgetc (fileref)) != EOF) { while ((i = Fgetc (fileref)) != EOF) {
if (origin >= limit) { if (origin >= limit) {
return SCPE_NXM; return SCPE_NXM;
} }
if (sim_switches & SWMASK('R')) { if (sim_switches & SWMASK('R')) {
pwrite_b_rom(origin, (uint8)i); pwrite_b_rom(origin, (uint8)i);
} else { } else {
pwrite_b(origin, (uint8)i, BUS_CPU); pwrite_b(origin, (uint8)i, BUS_CPU);
} }
origin++; origin++;
cnt++; cnt++;
} }
if (sim_switches & SWMASK('R')) { if (sim_switches & SWMASK('R')) {
rom_loaded = TRUE; rom_loaded = TRUE;
sim_messagef(SCPE_OK, "%d bytes loaded into ROM\n", cnt); sim_messagef(SCPE_OK, "%d bytes loaded into ROM\n", cnt);
} else { } else {
sim_messagef(SCPE_OK, "%d bytes loaded at address 0x%08x\n", cnt, origin - cnt); sim_messagef(SCPE_OK, "%d bytes loaded at address 0x%08x\n", cnt, origin - cnt);
} }
return SCPE_OK; return SCPE_OK;
} }
t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw) t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw)
{ {
DEVICE *dptr; DEVICE *dptr;
t_stat r; t_stat r;
int32 k, num, vp; int32 k, num, vp;
int32 len = 4; int32 len = 4;
if (sw & (int32) SWMASK ('B')) { if (sw & (int32) SWMASK ('B')) {
len = 1; len = 1;
} else if (sw & (int32) SWMASK ('H')) { } else if (sw & (int32) SWMASK ('H')) {
len = 2; len = 2;
} else if (sw & (int32) SWMASK ('W')) { } else if (sw & (int32) SWMASK ('W')) {
len = 4; len = 4;
} }
// Parse cptr // Parse cptr
num = (int32) get_uint(cptr, 16, WORD_MASK, &r); num = (int32) get_uint(cptr, 16, WORD_MASK, &r);
if (r != SCPE_OK) { if (r != SCPE_OK) {
return r; return r;
} }
if (uptr == NULL) { if (uptr == NULL) {
uptr = &cpu_unit; uptr = &cpu_unit;
} }
dptr = find_dev_from_unit(uptr); dptr = find_dev_from_unit(uptr);
if (dptr == NULL) { if (dptr == NULL) {
return SCPE_IERR; return SCPE_IERR;
} }
vp = 0; vp = 0;
for (k = len - 1; k >= 0; k--) { for (k = len - 1; k >= 0; k--) {
val[vp++] = (num >> (k * 8)) & 0xff; val[vp++] = (num >> (k * 8)) & 0xff;
} }
return -(vp - 1); return -(vp - 1);
} }
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
{ {
uint32 len = 4; uint32 len = 4;
int32 k, vp, num; int32 k, vp, num;
unsigned int c; unsigned int c;
num = 0; num = 0;
vp = 0; vp = 0;
if (sw & (int32) SWMASK('M')) { if (sw & (int32) SWMASK('M')) {
return fprint_sym_m(of, addr, val); return fprint_sym_m(of, addr, val);
} }
if (sw & (int32) SWMASK ('B')) { if (sw & (int32) SWMASK ('B')) {
len = 1; len = 1;
} else if (sw & (int32) SWMASK ('H')) { } else if (sw & (int32) SWMASK ('H')) {
len = 2; len = 2;
} else if (sw & (int32) SWMASK ('W')) { } else if (sw & (int32) SWMASK ('W')) {
len = 4; len = 4;
} }
if (sw & (int32) SWMASK('C')) { if (sw & (int32) SWMASK('C')) {
len = 16; len = 16;
for (k = (int32) len - 1; k >= 0; k--) { for (k = (int32) len - 1; k >= 0; k--) {
c = (unsigned int)val[vp++]; c = (unsigned int)val[vp++];
if (c >= 0x20 && c < 0x7f) { if (c >= 0x20 && c < 0x7f) {
fprintf(of, "%c", c); fprintf(of, "%c", c);
} else { } else {
fprintf(of, "."); fprintf(of, ".");
} }
} }
return -(vp - 1); return -(vp - 1);
} }
for (k = len - 1; k >= 0; k--) { for (k = len - 1; k >= 0; k--) {
num = num | (((int32) val[vp++]) << (k * 8)); num = num | (((int32) val[vp++]) << (k * 8));
} }
fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO); fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO);
return -(vp - 1); return -(vp - 1);
} }

View file

@ -1,46 +1,46 @@
/* 3b2_sys.h: Common System Definition /* 3b2_sys.h: Common System Definition
Copyright (c) 2017-2022, Seth J. Morabito Copyright (c) 2017-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_SYS_H_ #ifndef _3B2_SYS_H_
#define _3B2_SYS_H_ #define _3B2_SYS_H_
#include "3b2_defs.h" #include "3b2_defs.h"
void full_reset(); void full_reset();
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag); t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag);
t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val, t_stat parse_sym(CONST char *cptr, t_addr addr, UNIT *uptr, t_value *val,
int32 sw); int32 sw);
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw); t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);
extern char sim_name[]; extern char sim_name[];
extern REG *sim_PC; extern REG *sim_PC;
extern int32 sim_emax; extern int32 sim_emax;
#endif /* _3B2_SYS_H_ */ #endif /* _3B2_SYS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,78 +1,78 @@
/* 3b2_timer.h: 8253/82C54 Interval Timer /* 3b2_timer.h: 8253/82C54 Interval Timer
Copyright (c) 2021-2022, Seth J. Morabito Copyright (c) 2021-2022, Seth J. Morabito
Permission is hereby granted, free of charge, to any person Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy, restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions: furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software. included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
Except as contained in this notice, the name of the author shall 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 not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization other dealings in this Software without prior written authorization
from the author. from the author.
*/ */
#ifndef _3B2_TIMER_H_ #ifndef _3B2_TIMER_H_
#define _3B2_TIMER_H_ #define _3B2_TIMER_H_
#include "3b2_defs.h" #include "3b2_defs.h"
#define TIMER_REG_DIVA 0x03 #define TIMER_REG_DIVA 0x03
#define TIMER_REG_DIVB 0x07 #define TIMER_REG_DIVB 0x07
#define TIMER_REG_DIVC 0x0b #define TIMER_REG_DIVC 0x0b
#define TIMER_REG_CTRL 0x0f #define TIMER_REG_CTRL 0x0f
#define TIMER_CLR_LATCH 0x13 #define TIMER_CLR_LATCH 0x13
#define TIMER_MODE(ctr) (((ctr->ctrl) >> 1) & 7) #define TIMER_MODE(ctr) (((ctr->ctrl) >> 1) & 7)
#define TIMER_RW(ctr) (((ctr->ctrl) >> 4) & 3) #define TIMER_RW(ctr) (((ctr->ctrl) >> 4) & 3)
#define CLK_LATCH 0 #define CLK_LATCH 0
#define CLK_LSB 1 #define CLK_LSB 1
#define CLK_MSB 2 #define CLK_MSB 2
#define CLK_LMB 3 #define CLK_LMB 3
#define TMR_SANITY 0 #define TMR_SANITY 0
#define TMR_INT 1 #define TMR_INT 1
#define TMR_BUS 2 #define TMR_BUS 2
struct timer_ctr { struct timer_ctr {
uint16 divider; uint16 divider;
uint16 val; uint16 val;
uint8 ctrl_latch; uint8 ctrl_latch;
uint16 cnt_latch; uint16 cnt_latch;
uint8 ctrl; uint8 ctrl;
t_bool r_lmb; t_bool r_lmb;
t_bool w_lmb; t_bool w_lmb;
t_bool enabled; t_bool enabled;
t_bool gate; t_bool gate;
t_bool r_ctrl_latch; t_bool r_ctrl_latch;
t_bool r_cnt_latch; t_bool r_cnt_latch;
}; };
t_stat timer_reset(DEVICE *dptr); t_stat timer_reset(DEVICE *dptr);
uint32 timer_read(uint32 pa, size_t size); uint32 timer_read(uint32 pa, size_t size);
void timer_write(uint32 pa, uint32 val, size_t size); void timer_write(uint32 pa, uint32 val, size_t size);
void timer_gate(uint8 ctrnum, t_bool inhibit); void timer_gate(uint8 ctrnum, t_bool inhibit);
t_stat tmr_svc(UNIT *uptr); t_stat tmr_svc(UNIT *uptr);
t_stat tmr_int_svc(UNIT *uptr); t_stat tmr_int_svc(UNIT *uptr);
CONST char *tmr_description(DEVICE *dptr); CONST char *tmr_description(DEVICE *dptr);
t_stat tmr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); t_stat tmr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
#endif /* _3B2_TIMER_H_ */ #endif /* _3B2_TIMER_H_ */

View file

@ -1,135 +1,54 @@
AT&T 3B2 Simulator AT&T 3B2 Simulator
================== ==================
This module contains the source for two simulators: This module contains the source for two simulators:
1. A simulator for the AT&T 3B2/400 computer (3b2 or 3B2.EXE) 1. A simulator for the AT&T 3B2/400 computer (3b2-400 or 3B2-400.EXE)
2. A simulator for the AT&T 3B2/700 computer (3b2-700 or 3B2-700.EXE) 2. A simulator for the AT&T 3B2/700 computer (3b2-700 or 3B2-700.EXE)
The 3B2/400 simulator is complete, usable, and robust. The 3B2/700 Full documentation for the 3B2 simulator is available here:
simulator is under active development and is not yet considered
stable. - https://loomcom.com/3b2/emulator.html
Full documentation for the 3B2 simulator is available here: 3B2/400 Simulator Devices
-------------------------
- https://loomcom.com/3b2/emulator.html
The following devices are simulated. The SIMH names for the simulated
3B2/400 Simulator Devices devices are given in parentheses:
-------------------------
- 3B2 Model 400 System Board with 1MB, 2MB, or 4MB RAM
The following devices are simulated. The SIMH names for the simulated - Configuration and Status Register (CSR)
devices are given in parentheses: - WE32100 CPU (CPU)
- WE32101 MMU (MMU)
- 3B2 Model 400 System Board with 1MB, 2MB, or 4MB RAM (CSR, NVRAM) - WE32106 Math Accelerator Unit (MAU)
- WE32100 CPU (CPU) - PD8253 Interval Timer (TMR)
- WE32101 MMU (MMU) - AM9517 DMA controller (DMAC)
- PD8253 Interval Timer (TMR) - SCN2681A Integrated DUART (IU)
- AM9517 DMA controller (DMAC) - TMS2793 Integrated Floppy Controller (IFLOPPY)
- SCN2681A Integrated DUART (IU) - uPD7261A Integrated MFM Fixed Disk Controller (IDISK)
- TMS2793 Integrated Floppy Controller (IFLOPPY) - Non-Volatile Memory (NVRAM)
- uPD7261A Integrated MFM Fixed Disk Controller (IDISK) - MM58174A Time Of Day Clock (TOD)
- Non-Volatile Memory (NVRAM) - CM195A Ethernet Network Interface (NI)
- MM58174A Time Of Day Clock (TOD) - CM195B 4-port Serial MUX (PORTS)
- CM195A Ethernet Network Interface (NI) - CM195H Cartridge Tape Controller (CTC)
- CM195B 4-port Serial MUX (PORTS)
- CM195H Cartridge Tape Controller (CTC) 3B2/700 Simulator Devices
-------------------------
3B2/400 Simulator Usage
----------------------- The following devices are simulated. The SIMH names for the simulated
devices are given in parentheses:
To boot the 3B2 simulator into firmware mode, simply type:
- 3B2 Model 700 System Board with 8MB, 16MB, 32MB, or 64MB RAM
sim> BOOT - Configuration and Status Registers (CSR)
- WE32200 CPU (CPU)
You will be greeted with the message: - WE32201 MMU (MMU)
- WE32106 Math Accelerator Unit (MAU)
FW ERROR 1-01: NVRAM SANITY FAILURE - PD8253 Interval Timer (TMR)
DEFAULT VALUES ASSUMED - AM9517 DMA controller (DMAC)
IF REPEATED, CHECK THE BATTERY - SCN2681A Integrated DUART (IU)
- TMS2793 Integrated Floppy Controller (IFLOPPY)
FW ERROR 1-02: DISK SANITY FAILURE - Non-Volatile Memory (NVRAM)
EXECUTION HALTED - MM58274C Time Of Day Clock (TOD)
- CM195W SCSI Host Adapter (SCSI)
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE - CM195A Ethernet Network Interface (NI)
- CM195B 4-port Serial MUX (PORTS)
NVRAM and Time of Day can be saved between boots by attaching both
devices to files.
sim> ATTACH NVRAM <nvram-file>
sim> ATTACH TOD <tod-file>
If you have no operating system installed on the hard drive, on
subsequent boots you will instead see the message
SELF-CHECK
FW ERROR 1-02: DISK SANITY FAILURE
EXECUTION HALTED
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE
Once you see the `SYSTEM FAILURE` message, this is actually an
invisible prompt. To access firmware mode, type the default 3B2
firmware password `mcp`, then press Enter or carriage return.
You should then be prompted with:
Enter name of program to execute [ ]:
Here, you may type a question mark (?) and press Enter to see a list
of available firmware programs.
Booting UNIX SVR3 on the 3B2/400
--------------------------------
UNIX System V UNIX is the only operating system available for the 3B2.
To boot UNIX, attach the first disk image from the 3B2 "Essential
Utilities" distribution.
sim> ATTACH IFLOPPY <floppy-image>
sim> BOOT
Once you reach the `SYSTEM FAILURE` message, type `mcp` to enter
firmware mode. When prompted for the name of a program to boot, enter
`unix`, and confirm the boot device is `FD5` by pressing Enter or
carriage return.
Enter name of program to execute [ ]: unix
Possible load devices are:
Option Number Slot Name
---------------------------------------
0 0 FD5
Enter Load Device Option Number [0 (FD5)]:
Installing SVR3 on the 3B2/400
------------------------------
To install SVR3 to the first hard disk, first, attach a new image
to the IDISK0 device:
sim> ATTACH IDISK0 <hd-image>
Then, boot the file `idtools` from the "3B2 Maintenance Utilities -
Issue 4.0" floppy diskette.
From `idtools`, select the `formhard` option and low-level format
integrated disk 0. Parameters for the default 72MB hard disk are:
Drive Id: 5
Number cylinders: 925
Number tracks/cyl: 9
Number sectors/track: 18
Number bytes/sector: 512
After low-level formatting integrated disk 0, boot the file `unix`
from the first diskette of the 3B2 "Essential Utilities" distribution,
and follow the prompts.
More information about installing AT&T System V Release 3.2 UNIX is
available on the web:
- https://loomcom.com/3b2/installing_unix.html