3B2-700 Initial Public Release

This commit introduces dozens of changes to make the 3B2-700 simulator
fully functional and ready for wider use. In addition to 3B2-700
availability, this commit includes a tremendous amount of refactoring
of the 3B2-400 and common code to make the project structure easier to
maintain and reason about.

One final important change: ROM files are no longer included in the
source code. 3B2 ROM images must be obtained separately and loaded
into the simulator before boot.

Changes:

- The 3b2 target has been aliased to 3b2-400
- The formerly named 3b2-600 project has become 3b2-700
- SCSI QIC tape support has been added to sim_scsi.c
- Header files have been reworked to reduce complexity of includes
- Common code has been consolidated
- Timer code has been unified
This commit is contained in:
Seth Morabito 2022-09-15 07:05:18 -07:00
parent d862d024ea
commit 9b62da6567
67 changed files with 26013 additions and 40292 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,44 +1,46 @@
/* 3b2_csr.h: Common CSR header /* 3b2_csr.h: Common CSR/CSER header
Copyright (c) 2021, 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)
#endif /* _3B2_CSR_H_ */ extern CSR_DATA csr_data;
#endif /* _3B2_CSR_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,153 +1,153 @@
/* 3b2_ctc.h: AT&T 3B2 Model 400 "CTC" feature card /* 3b2_ctc.h: CM195H 23MB Cartridge Tape Controller CIO Card
Copyright (c) 2018, 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 cid); void ctc_sysgen(uint8 slot);
void ctc_express(uint8 cid); void ctc_express(uint8 slot);
void ctc_full(uint8 cid); void ctc_full(uint8 slot);
#endif /* _3B2_CTC_H_ */ #endif /* _3B2_CTC_H_ */

View file

@ -1,164 +1,166 @@
/* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions /* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions
Copyright (c) 2017, 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 UNIT_V_EXBRK (UNIT_V_UF + 0) #define ROM_SIZE (128 * 1024)
#define UNIT_V_OPBRK (UNIT_V_UF + 1) #define POLL_WAIT 70000
#define UNIT_EXBRK (1u << UNIT_V_EXBRK)
#define UNIT_OPBRK (1u << UNIT_V_OPBRK) #define UNIT_V_EXBRK (UNIT_V_UF + 0)
#define UNIT_V_OPBRK (UNIT_V_UF + 1)
#define EX_V_FLAG 1 << 21 #define UNIT_EXBRK (1u << UNIT_V_EXBRK)
#define UNIT_OPBRK (1u << UNIT_V_OPBRK)
#define PHYS_MEM_BASE 0x2000000
#define EX_V_FLAG 1 << 21
#define MSIZ_512K 0x80000
#define MSIZ_1M 0x100000 #define ROM_BASE 0
#define MSIZ_2M 0x200000 #define PHYS_MEM_BASE 0x2000000
#define MSIZ_4M 0x400000
#define MSIZ_8M 0x800000 #define MSIZ_512K 0x80000
#define MSIZ_16M 0x1000000 #define MSIZ_1M 0x100000
#define MSIZ_32M 0x2000000 #define MSIZ_2M 0x200000
#define MSIZ_64M 0x4000000 #define MSIZ_4M 0x400000
#define MSIZ_8M 0x800000
/* Simulator stop codes */ #define MSIZ_16M 0x1000000
#define STOP_RSRV 1 #define MSIZ_32M 0x2000000
#define STOP_IBKPT 2 /* Breakpoint encountered */ #define MSIZ_64M 0x4000000
#define STOP_OPCODE 3 /* Invalid opcode */
#define STOP_IRQ 4 /* Interrupt */ /* Simulator stop codes */
#define STOP_EX 5 /* Exception */ #define STOP_RSRV 1
#define STOP_ESTK 6 /* Exception stack too deep */ #define STOP_IBKPT 2 /* Breakpoint encountered */
#define STOP_MMU 7 /* Unimplemented MMU Feature */ #define STOP_OPCODE 3 /* Invalid opcode */
#define STOP_POWER 8 /* System power-off */ #define STOP_IRQ 4 /* Interrupt */
#define STOP_LOOP 9 /* Infinite loop stop */ #define STOP_EX 5 /* Exception */
#define STOP_ERR 10 /* Other error */ #define STOP_ESTK 6 /* Exception stack too deep */
#define STOP_MMU 7 /* Unimplemented MMU Feature */
/* Debug flags */ #define STOP_POWER 8 /* System power-off */
#define READ_MSG 0x0001 #define STOP_LOOP 9 /* Infinite loop stop */
#define WRITE_MSG 0x0002 #define STOP_ERR 10 /* Other error */
#define DECODE_MSG 0x0004
#define EXECUTE_MSG 0x0008 /* Debug flags */
#define INIT_MSG 0x0010 #define READ_MSG 0x0001
#define IRQ_MSG 0x0020 #define WRITE_MSG 0x0002
#define IO_DBG 0x0040 #define DECODE_MSG 0x0004
#define CIO_DBG 0x0080 #define EXECUTE_MSG 0x0008
#define TRACE_DBG 0x0100 #define INIT_MSG 0x0010
#define CALL_DBG 0x0200 #define IRQ_MSG 0x0020
#define PKT_DBG 0x0400 #define IO_DBG 0x0040
#define ERR_MSG 0x0800 #define CIO_DBG 0x0080
#define CACHE_DBG 0x1000 #define TRACE_DBG 0x0100
#define DECODE_DBG 0x2000 #define CALL_DBG 0x0200
#define PKT_DBG 0x0400
#define TIMER_SANITY 0 #define ERR_MSG 0x0800
#define TIMER_INTERVAL 1 #define CACHE_DBG 0x1000
#define TIMER_BUS 2 #define DECODE_DBG 0x2000
/* Timer */ #define TIMER_SANITY 0
#define TMR_CLK 0 /* The clock responsible for IPL 15 interrupts */ #define TIMER_INTERVAL 1
#define TPS_CLK 100 /* 100 ticks per second */ #define TIMER_BUS 2
/* Timers */
/* Global symbols */ #define TMR_CLK 0 /* Calibrated 100Hz timer */
extern DEBTAB sys_deb_tab[]; /* Global symbols */
extern DEVICE contty_dev;
extern DEVICE cpu_dev; extern DEBTAB sys_deb_tab[];
extern DEVICE csr_dev; extern DEVICE contty_dev;
extern DEVICE ctc_dev; extern DEVICE cpu_dev;
extern DEVICE dmac_dev; extern DEVICE csr_dev;
extern DEVICE id_dev; extern DEVICE ctc_dev;
extern DEVICE if_dev; extern DEVICE dmac_dev;
extern DEVICE iu_timer_dev; extern DEVICE id_dev;
extern DEVICE mau_dev; extern DEVICE if_dev;
extern DEVICE mmu_dev; extern DEVICE iu_timer_dev;
extern DEVICE ni_dev; extern DEVICE mau_dev;
extern DEVICE nvram_dev; extern DEVICE mmu_dev;
extern DEVICE ports_dev; extern DEVICE ni_dev;
extern DEVICE timer_dev; extern DEVICE nvram_dev;
extern DEVICE tod_dev; extern DEVICE ports_dev;
extern DEVICE tti_dev; extern DEVICE timer_dev;
extern DEVICE tto_dev; extern DEVICE tod_dev;
#if defined(REV3) extern DEVICE tti_dev;
extern DEVICE flt_dev; extern DEVICE tto_dev;
extern DEVICE ha_dev; #if defined(REV3)
#endif extern DEVICE flt_dev;
extern DEVICE ha_dev;
#endif #endif /* defined(REV3) */
#endif /* _3B2_DEFS_H_ */

View file

@ -1,468 +1,481 @@
/* 3b2_dmac.c: AT&T 3B2 DMA Controller Implementation /* 3b2_dmac.c: AM9517 DMA Controller
Copyright (c) 2021, 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"
DMA_STATE dma_state; #include "3b2_csr.h"
UNIT dmac_unit[] = { DMA_STATE dma_state;
{ UDATA (NULL, 0, 0), 0, 0 },
{ UDATA (NULL, 0, 0), 0, 1 }, UNIT dmac_unit[] = {
{ UDATA (NULL, 0, 0), 0, 2 }, { UDATA (NULL, 0, 0), 0, 0 },
{ UDATA (NULL, 0, 0), 0, 3 }, { UDATA (NULL, 0, 0), 0, 1 },
{ NULL } { UDATA (NULL, 0, 0), 0, 2 },
}; { UDATA (NULL, 0, 0), 0, 3 },
{ NULL }
REG dmac_reg[] = { };
{ NULL }
}; REG dmac_reg[] = {
{ NULL }
DEVICE dmac_dev = { };
"DMAC", dmac_unit, dmac_reg, NULL,
1, 16, 8, 4, 16, 32, DEVICE dmac_dev = {
NULL, NULL, &dmac_reset, "DMAC", dmac_unit, dmac_reg, NULL,
NULL, NULL, NULL, NULL, 1, 16, 8, 4, 16, 32,
DEV_DEBUG, 0, sys_deb_tab NULL, NULL, &dmac_reset,
}; NULL, NULL, NULL, NULL,
DEV_DEBUG, 0, sys_deb_tab
dmac_dma_handler device_dma_handlers[] = { };
#if defined(REV2)
{DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma}, dmac_dma_handler device_dma_handlers[] = {
#endif #if defined(REV2)
{DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma}, {DMA_ID_CHAN, IDBASE+ID_DATA_REG, &id_drq, dmac_generic_dma, id_after_dma},
{DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL}, #endif
{DMA_IUB_CHAN, IUBASE+IUB_DATA_REG, &iu_contty.drq, iu_dma_contty, NULL}, {DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma},
{0, 0, NULL, NULL, 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},
{0, 0, NULL, NULL, NULL }
uint32 dma_address(uint8 channel, uint32 offset, t_bool r) { };
uint32 addr, page;
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset); uint32 dma_address(uint8 channel, uint32 offset) {
#if defined (REV3) uint32 addr, page;
page = (uint32)dma_state.channels[channel].page; if (DMA_DECR(channel)) {
#else addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) - offset);
/* In Rev 2, the top bit of the page address is a R/W bit, so } else {
we mask it here */ addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset);
page = (uint32)dma_state.channels[channel].page & 0x7f; }
#endif #if defined (REV3)
addr |= page << 16; page = (uint32)dma_state.channels[channel].page;
return addr; #else
} /* In Rev 2, the top bit of the page address is a R/W bit, so
we mask it here */
t_stat dmac_reset(DEVICE *dptr) page = (uint32)dma_state.channels[channel].page & 0x7f;
{ #endif
int i; addr |= page << 16;
return addr;
memset(&dma_state, 0, sizeof(dma_state)); }
for (i = 0; i < 4; i++) { t_stat dmac_reset(DEVICE *dptr)
dma_state.channels[i].page = 0; {
dma_state.channels[i].addr = 0; int i;
dma_state.channels[i].wcount = 0;
dma_state.channels[i].addr_c = 0; memset(&dma_state, 0, sizeof(dma_state));
dma_state.channels[i].wcount_c = -1;
dma_state.channels[i].ptr = 0; for (i = 0; i < 4; i++) {
} dma_state.channels[i].page = 0;
dma_state.channels[i].addr = 0;
return SCPE_OK; dma_state.channels[i].mode = 0;
} dma_state.channels[i].wcount = 0;
dma_state.channels[i].addr_c = 0;
uint32 dmac_read(uint32 pa, size_t size) dma_state.channels[i].wcount_c = -1;
{ dma_state.channels[i].ptr = 0;
uint8 reg, base, data; }
base = (uint8) (pa >> 12); return SCPE_OK;
reg = pa & 0xff; }
switch (base) { uint32 dmac_read(uint32 pa, size_t size)
case DMA_C: /* 0x48xxx */ {
switch (reg) { uint8 reg, base, data;
case 0: /* channel 0 current address reg */
data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff; base = (uint8) (pa >> 12);
sim_debug(READ_MSG, &dmac_dev, reg = pa & 0xff;
"[%08x] Reading Channel 0 Addr Reg: %08x\n",
R[NUM_PC], data); switch (base) {
dma_state.bff ^= 1; case DMA_C:
break; switch (reg) {
case 1: /* channel 0 current address reg */ case 0: /* channel 0 current address reg */
data = ((dma_state.channels[0].wcount_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,
"[%08x] Reading Channel 0 Addr Count Reg: %08x\n", "Reading Channel 0 Addr Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 2: /* channel 1 current address reg */ case 1: /* channel 0 current address reg */
data = ((dma_state.channels[1].addr_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,
"[%08x] Reading Channel 1 Addr Reg: %08x\n", "Reading Channel 0 Addr Count Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 3: /* channel 1 current address reg */ case 2: /* channel 1 current address reg */
data = ((dma_state.channels[1].wcount_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,
"[%08x] Reading Channel 1 Addr Count Reg: %08x\n", "Reading Channel 1 Addr Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 4: /* channel 2 current address reg */ case 3: /* channel 1 current address reg */
data = ((dma_state.channels[2].addr_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,
"[%08x] Reading Channel 2 Addr Reg: %08x\n", "Reading Channel 1 Addr Count Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 5: /* channel 2 current address reg */ case 4: /* channel 2 current address reg */
data = ((dma_state.channels[2].wcount_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,
"[%08x] Reading Channel 2 Addr Count Reg: %08x\n", "Reading Channel 2 Addr Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 6: /* channel 3 current address reg */ case 5: /* channel 2 current address reg */
data = ((dma_state.channels[3].addr_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,
"[%08x] Reading Channel 3 Addr Reg: %08x\n", "Reading Channel 2 Addr Count Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 7: /* channel 3 current address reg */ case 6: /* channel 3 current address reg */
data = ((dma_state.channels[3].wcount_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,
"[%08x] Reading Channel 3 Addr Count Reg: %08x\n", "Reading Channel 3 Addr Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.bff ^= 1; dma_state.bff ^= 1;
break; break;
case 8: case 7: /* channel 3 current address reg */
data = dma_state.status; data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff;
sim_debug(READ_MSG, &dmac_dev, sim_debug(READ_MSG, &dmac_dev,
"[%08x] Reading DMAC Status %08x\n", "Reading Channel 3 Addr Count Reg: %08x\n",
R[NUM_PC], data); data);
dma_state.status = 0; dma_state.bff ^= 1;
break; break;
default: case 8:
sim_debug(READ_MSG, &dmac_dev, data = dma_state.status;
"[%08x] DMAC READ %lu B @ %08x\n", sim_debug(READ_MSG, &dmac_dev,
R[NUM_PC], size, pa); "Reading DMAC Status %08x\n",
data = 0; data);
} dma_state.status = 0;
break;
return data; default:
default: sim_debug(READ_MSG, &dmac_dev,
sim_debug(READ_MSG, &dmac_dev, "DMAC READ %lu B @ %08x\n",
"[%08x] [BASE: %08x] DMAC READ %lu B @ %08x\n", size, pa);
R[NUM_PC], base, size, pa); data = 0;
return 0; }
}
} return data;
default:
/* sim_debug(READ_MSG, &dmac_dev,
* Program the DMAC "[BASE: %08x] DMAC READ %lu B @ %08x\n",
*/ base, size, pa);
void dmac_program(uint8 reg, uint8 val) return 0;
{ }
uint8 channel_id, i, chan_num; }
dma_channel *channel;
/*
if (reg < 8) { * Program the DMAC
switch (reg) { */
case 0: void dmac_program(uint8 reg, uint8 val)
case 1: {
chan_num = 0; uint8 channel_id, i, chan_num;
break; dma_channel *channel;
case 2:
case 3: #if defined(REV3)
chan_num = 1; /* TODO: More general DMA interrupt clearing */
break; CPU_CLR_INT(INT_UART_DMA);
case 4: CLR_CSR(CSRDMA);
case 5: #endif
chan_num = 2;
break; if (reg < 8) {
case 6: switch (reg) {
case 7: case 0:
chan_num = 3; case 1:
break; chan_num = 0;
default: break;
chan_num = 0; case 2:
break; case 3:
} chan_num = 1;
break;
channel = &dma_state.channels[chan_num]; case 4:
case 5:
switch (reg & 1) { chan_num = 2;
case 0: /* Address */ break;
channel->addr &= ~(0xff << dma_state.bff * 8); case 6:
channel->addr |= (val & 0xff) << (dma_state.bff * 8); case 7:
channel->addr_c = channel->addr; chan_num = 3;
sim_debug(WRITE_MSG, &dmac_dev, break;
"Set address channel %d byte %d = %08x\n", default:
chan_num, dma_state.bff, channel->addr); chan_num = 0;
break; break;
case 1: /* Word Count */ }
channel->wcount &= ~(0xff << dma_state.bff * 8);
channel->wcount |= (val & 0xff) << (dma_state.bff * 8); channel = &dma_state.channels[chan_num];
channel->wcount_c = channel->wcount;
channel->ptr = 0; switch (reg & 1) {
sim_debug(WRITE_MSG, &dmac_dev, case 0: /* Address */
"Set word count channel %d byte %d = %08x\n", channel->addr &= ~(0xff << dma_state.bff * 8);
chan_num, dma_state.bff, channel->wcount); channel->addr |= (val & 0xff) << (dma_state.bff * 8);
break; channel->addr_c = channel->addr;
} sim_debug(WRITE_MSG, &dmac_dev,
"Set address channel %d byte %d = %08x\n",
/* Toggle the byte flip-flop */ chan_num, dma_state.bff, channel->addr);
dma_state.bff ^= 1; break;
case 1: /* Word Count */
/* Handled. */ channel->wcount &= ~(0xff << dma_state.bff * 8);
return; channel->wcount |= (val & 0xff) << (dma_state.bff * 8);
} channel->wcount_c = channel->wcount;
channel->ptr = 0;
/* If it hasn't been handled, it must be one of the following sim_debug(WRITE_MSG, &dmac_dev,
registers. */ "Set word count channel %d byte %d = %08x\n",
chan_num, dma_state.bff, channel->wcount);
switch (reg) { break;
case 8: /* Command */ }
dma_state.command = val;
sim_debug(WRITE_MSG, &dmac_dev, /* Toggle the byte flip-flop */
"[%08x] Command: val=%02x\n", dma_state.bff ^= 1;
R[NUM_PC], val);
break; /* Handled. */
case 9: /* Request */ return;
sim_debug(WRITE_MSG, &dmac_dev, }
"[%08x] Request set: val=%02x\n",
R[NUM_PC], val); /* If it hasn't been handled, it must be one of the following
dma_state.request = val; registers. */
break;
case 10: /* Write Single Mask Register Bit */ switch (reg) {
channel_id = val & 3; case 8: /* Command */
dma_state.command = val;
/* "Clear or Set" is bit 2 */ sim_debug(WRITE_MSG, &dmac_dev,
if ((val >> 2) & 1) { "Command: val=%02x\n",
dma_state.mask |= (1 << channel_id); val);
} else { break;
dma_state.mask &= ~(1 << channel_id); case 9: /* Request */
/* Set the appropriate DRQ */ sim_debug(WRITE_MSG, &dmac_dev,
/* *dmac_drq_handlers[channel_id].drq = TRUE; */ "Request set: val=%02x\n",
} val);
dma_state.request = val;
sim_debug(WRITE_MSG, &dmac_dev, break;
"[%08x] Write Single Mask Register Bit. channel=%d set/clear=%02x\n", case 10: /* Write Single Mask Register Bit */
R[NUM_PC], channel_id, (val >> 2) & 1); channel_id = val & 3;
break;
case 11: /* Mode */ /* "Clear or Set" is bit 2 */
sim_debug(WRITE_MSG, &dmac_dev, if ((val >> 2) & 1) {
"[%08x] Mode Set. val=%02x\n", dma_state.mask |= (1 << channel_id);
R[NUM_PC], val); } else {
dma_state.mode = val; dma_state.mask &= ~(1 << channel_id);
break; /* Set the appropriate DRQ */
case 12: /* Clear Byte Pointer Flip/Flop */ /* *dmac_drq_handlers[channel_id].drq = TRUE; */
dma_state.bff = 0; }
break;
case 13: /* Master Clear */ sim_debug(WRITE_MSG, &dmac_dev,
dma_state.bff = 0; "Write Single Mask Register Bit. channel=%d set/clear=%02x\n",
dma_state.command = 0; channel_id, (val >> 2) & 1);
dma_state.status = 0; break;
for (i = 0; i < 4; i++) { case 11: /* Mode */
dma_state.channels[i].page = 0; channel_id = val & 3;
dma_state.channels[i].addr = 0; sim_debug(WRITE_MSG, &dmac_dev,
dma_state.channels[i].wcount = 0; "Mode Set. channel=%d val=%02x\n",
dma_state.channels[i].addr_c = 0; channel_id, val);
dma_state.channels[i].wcount_c = -1; dma_state.channels[channel_id].mode = val;
dma_state.channels[i].ptr = 0; break;
} case 12: /* Clear Byte Pointer Flip/Flop */
break; dma_state.bff = 0;
case 15: /* Write All Mask Register Bits */ break;
sim_debug(WRITE_MSG, &dmac_dev, case 13: /* Master Clear */
"[%08x] Write DMAC mask (all bits). Val=%02x\n", dma_state.bff = 0;
R[NUM_PC], val); dma_state.command = 0;
dma_state.mask = val & 0xf; dma_state.status = 0;
break; for (i = 0; i < 4; i++) {
case 16: /* Clear DMAC Interrupt */ dma_state.channels[i].page = 0;
sim_debug(WRITE_MSG, &dmac_dev, dma_state.channels[i].addr = 0;
"[%08x] Clear DMAC Interrupt in DMAC. val=%02x\n", dma_state.channels[i].wcount = 0;
R[NUM_PC], val); dma_state.channels[i].addr_c = 0;
break; dma_state.channels[i].wcount_c = -1;
default: dma_state.channels[i].ptr = 0;
sim_debug(WRITE_MSG, &dmac_dev, }
"[%08x] Unhandled DMAC write. reg=%x val=%02x\n", break;
R[NUM_PC], reg, val); case 15: /* Write All Mask Register Bits */
break; sim_debug(WRITE_MSG, &dmac_dev,
} "Write DMAC mask (all bits). Val=%02x\n",
} val);
dma_state.mask = val & 0xf;
void dmac_page_update(uint8 base, uint8 reg, uint8 val) break;
{ case 16: /* Clear DMAC Interrupt */
uint8 shift = 0; sim_debug(WRITE_MSG, &dmac_dev,
"Clear DMA Interrupt in DMAC. val=%02x\n",
/* Sanity check */ val);
if (reg > 3) { break;
return; default:
} sim_debug(WRITE_MSG, &dmac_dev,
"Unhandled DMAC write. reg=%x val=%02x\n",
#if defined(REV2) reg, val);
/* In Rev2 systems, the actual register is a 32-bit, break;
byte-addressed register, so that address 4x000 is the highest }
byte, 4x003 is the lowest byte. */ }
shift = -(reg - 3) * 8;
#endif void dmac_page_update(uint8 base, uint8 reg, uint8 val)
{
switch (base) { uint8 shift = 0;
#if defined (REV2)
case DMA_ID: /* Sanity check */
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val); if (reg > 3) {
dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift); return;
dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift); }
break;
#endif #if defined(REV2)
case DMA_IF: /* In Rev2 systems, the actual register is a 32-bit,
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 1 = %x\n", val); byte-addressed register, so that address 4x000 is the highest
dma_state.channels[DMA_IF_CHAN].page &= ~(0xff << shift); byte, 4x003 is the lowest byte. */
dma_state.channels[DMA_IF_CHAN].page |= ((uint16)val << shift); shift = -(reg - 3) * 8;
break; #endif
case DMA_IUA:
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val); switch (base) {
dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift); #if defined (REV2)
dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift); case DMA_ID:
break; sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val);
case DMA_IUB: dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift);
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val); dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift);
dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift); break;
dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift); #endif
break; case DMA_IF:
} 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 |= ((uint16)val << shift);
void dmac_write(uint32 pa, uint32 val, size_t size) break;
{ case DMA_IUA:
uint8 reg, base; sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val);
dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift);
base = (uint8) (pa >> 12); dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift);
reg = pa & 0xff; break;
case DMA_IUB:
switch (base) { sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val);
case DMA_C: dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift);
dmac_program(reg, (uint8) val); dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift);
break; break;
#if defined (REV2) }
case DMA_ID: }
#endif
case DMA_IUA: void dmac_write(uint32 pa, uint32 val, size_t size)
case DMA_IUB: {
case DMA_IF: uint8 reg, base;
dmac_page_update(base, reg, (uint8) val);
break; base = (uint8) (pa >> 12);
} reg = pa & 0xff;
}
switch (base) {
void dmac_generic_dma(uint8 channel, uint32 service_address) case DMA_C:
{ dmac_program(reg, (uint8) val);
uint8 data; break;
int32 i; #if defined (REV2)
uint32 addr; case DMA_ID:
dma_channel *chan = &dma_state.channels[channel]; #endif
case DMA_IUA:
i = chan->wcount_c; case DMA_IUB:
case DMA_IF:
/* TODO: This does not handle decrement-mode transfers, dmac_page_update(base, reg, (uint8) val);
which don't seem to be used in SVR3 */ break;
}
switch ((dma_state.mode >> 2) & 0xf) { }
case DMA_MODE_VERIFY:
sim_debug(EXECUTE_MSG, &dmac_dev, void dmac_generic_dma(uint8 channel, uint32 service_address)
"[%08x] [dmac_generic_dma channel=%d] unhandled VERIFY request.\n", {
R[NUM_PC], channel); uint8 data;
break; int32 i;
case DMA_MODE_WRITE: uint32 addr;
sim_debug(EXECUTE_MSG, &dmac_dev, dma_channel *chan = &dma_state.channels[channel];
"[%08x] [dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n",
R[NUM_PC], channel, i = chan->wcount_c;
chan->wcount + 1,
dma_address(channel, 0, TRUE), /* TODO: This assumes every transfer is a block mode, which is not
service_address, guaranteed to be valid, but is likely safe? */
dma_state.channels[channel].page,
dma_state.channels[channel].addr); switch (DMA_XFER(channel)) {
for (; i >= 0; i--) { case DMA_XFER_VERIFY:
chan->wcount_c--; sim_debug(EXECUTE_MSG, &dmac_dev,
addr = dma_address(channel, chan->ptr, TRUE); "[dmac_generic_dma channel=%d] unhandled VERIFY request.\n",
chan->addr_c = dma_state.channels[channel].addr + chan->ptr; channel);
chan->ptr++; break;
data = pread_b(service_address); case DMA_XFER_WRITE:
write_b(addr, data); sim_debug(EXECUTE_MSG, &dmac_dev,
} "[dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n",
break; channel,
case DMA_MODE_READ: chan->wcount + 1,
sim_debug(EXECUTE_MSG, &dmac_dev, dma_address(channel, 0),
"[%08x] [dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n", service_address,
R[NUM_PC], channel, dma_state.channels[channel].page,
chan->wcount + 1, dma_state.channels[channel].addr);
dma_address(channel, 0, TRUE), for (; i >= 0; i--) {
service_address); chan->wcount_c--;
for (; i >= 0; i--) { addr = dma_address(channel, chan->ptr++);
chan->wcount_c = i; chan->addr_c = addr;
addr = dma_address(channel, chan->ptr++, TRUE); data = pread_b(service_address, BUS_PER);
chan->addr_c = dma_state.channels[channel].addr + chan->ptr; write_b(addr, data, BUS_PER);
data = pread_b(addr); }
write_b(service_address, data); break;
} case DMA_XFER_READ:
break; sim_debug(EXECUTE_MSG, &dmac_dev,
} "[dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n",
channel,
/* End of Process must set the channel's mask bit */ chan->wcount + 1,
dma_state.mask |= (1 << channel); dma_address(channel, 0),
dma_state.status |= (1 << channel); service_address);
} for (; i >= 0; i--) {
chan->wcount_c = i;
/* addr = dma_address(channel, chan->ptr++);
* Service pending DRQs chan->addr_c = addr;
*/ data = pread_b(addr, BUS_PER);
void dmac_service_drqs() write_b(service_address, data, BUS_PER);
{ }
volatile dmac_dma_handler *h; break;
}
for (h = &device_dma_handlers[0]; h->drq != NULL; h++) {
/* Only trigger if the channel has a DRQ set and its channel's /* End of Process must set the channel's mask bit */
mask bit is 0 */ dma_state.mask |= (1 << channel);
if (*h->drq && ((dma_state.mask >> h->channel) & 0x1) == 0) { dma_state.status |= (1 << channel);
h->dma_handler(h->channel, h->service_address); }
/* Each handler is responsible for clearing its own DRQ line! */
if (h->after_dma_callback != NULL) { /*
h->after_dma_callback(); * Service pending DRQs
} */
} void dmac_service_drqs()
} {
} volatile dmac_dma_handler *h;
for (h = &device_dma_handlers[0]; h->drq != NULL; h++) {
/* Only trigger if the channel has a DRQ set and its channel's
mask bit is 0 */
if (*h->drq && ((dma_state.mask >> h->channel) & 0x1) == 0) {
h->dma_handler(h->channel, h->service_address);
/* Each handler is responsible for clearing its own DRQ line! */
if (h->after_dma_callback != NULL) {
h->after_dma_callback();
}
}
}
}

View file

@ -1,84 +1,89 @@
/* 3b2_dmac.h: AT&T 3B2 DMA Controller Header /* 3b2_dmac.h: AM9517 DMA Controller
Copyright (c) 2021, 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_MODE_VERIFY 0 #define DMA_XFER_VERIFY 0
#define DMA_MODE_WRITE 1 /* Write to memory from device */ #define DMA_XFER_WRITE 1 /* Write to memory from device */
#define DMA_MODE_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)
typedef struct { #define DMA_MODE(C) ((dma_state.channels[(C)].mode >> 6) & 3)
uint16 page; #define DMA_DECR(C) ((dma_state.channels[(C)].mode >> 5) & 1)
uint16 addr; /* Original addr */ #define DMA_AUTOINIT(C) ((dma_state.channels[(C)].mode >> 4) & 1)
uint16 wcount; /* Original wcount */ #define DMA_XFER(C) ((dma_state.channels[(C)].mode >> 2) & 3)
uint16 addr_c; /* Current addr */
int32 wcount_c; /* Current word-count */ typedef struct {
uint16 ptr; /* Pointer into memory */ uint8 mode; /* Channel mode */
} dma_channel; uint16 page; /* Memory page */
uint16 addr; /* Original addr */
typedef struct { uint16 wcount; /* Original wcount */
/* Byte (high/low) flip-flop */ uint16 addr_c; /* Current addr */
uint8 bff; int32 wcount_c; /* Current word-count */
uint16 ptr; /* Pointer into memory */
/* Address and count registers for channels 0-3 */ } dma_channel;
dma_channel channels[4];
typedef struct {
/* DMAC programmable registers */ /* Byte (high/low) flip-flop */
uint8 command; uint8 bff;
uint8 mode;
uint8 request; /* Address and count registers for channels 0-3 */
uint8 mask; dma_channel channels[4];
uint8 status;
} DMA_STATE; /* DMAC programmable registers */
uint8 command;
typedef struct { uint8 request;
uint8 channel; uint8 mask;
uint32 service_address; uint8 status;
t_bool *drq; } DMA_STATE;
void (*dma_handler)(uint8 channel, uint32 service_address);
void (*after_dma_callback)(); typedef struct {
} dmac_dma_handler; uint8 channel;
uint32 service_address;
/* DMAC */ t_bool *drq;
t_stat dmac_reset(DEVICE *dptr); void (*dma_handler)(uint8 channel, uint32 service_address);
uint32 dmac_read(uint32 pa, size_t size); void (*after_dma_callback)();
void dmac_write(uint32 pa, uint32 val, size_t size); } dmac_dma_handler;
void dmac_service_drqs();
void dmac_generic_dma(uint8 channel, uint32 service_address); /* DMAC */
uint32 dma_address(uint8 channel, uint32 offset, t_bool r); t_stat dmac_reset(DEVICE *dptr);
uint32 dmac_read(uint32 pa, size_t size);
extern DMA_STATE dma_state; void dmac_write(uint32 pa, uint32 val, size_t size);
void dmac_service_drqs();
#endif void dmac_generic_dma(uint8 channel, uint32 service_address);
uint32 dma_address(uint8 channel, uint32 offset);
extern DMA_STATE dma_state;
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,178 +1,178 @@
/* 3b2_id.h: AT&T 3B2 Model 400 Hard Disk (uPD7261) Header /* 3b2_id.h: uPD7261 Integrated Disk Controller
Copyright (c) 2017, 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: AT&T 3B2 Model Floppy Controller (TMS2797NL) Header /* 3b2_if.h: TMS2797 Integrated Floppy Controller
Copyright (c) 2017, 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,252 +1,271 @@
/* 3b2_io.h: AT&T 3B2 Model 400 IO dispatch (Header) /* 3b2_io.h: Common I/O (CIO) Feature Card Support
Copyright (c) 2017, 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
/* CIO area */ #if defined(REV3)
#define CIO_BOTTOM 0x200000 #define UBUS_BOTTOM 0x1c00000
#define CIO_TOP 0x2000000 #define UBUS_TOP 0x2000000
#endif
#define IOF_ID 0
#define IOF_VEC 1 /* CIO area */
#define IOF_CTRL 3 #define CIO_BOTTOM 0x200000
#define IOF_STAT 5 #if defined(REV3)
#define CIO_TOP 0x1a00000
#define SYSGEN_PTR PHYS_MEM_BASE #else
#define CIO_TOP 0x2000000
/* CIO opcodes */ #endif
#define CIO_DLM 1
#define CIO_ULM 2 #define IOF_ID 0
#define CIO_FCF 3 #define IOF_VEC 1
#define CIO_DOS 4 #define IOF_CTRL 3
#define CIO_DSD 5 #define IOF_STAT 5
/* Response */ #define SYSGEN_PTR PHYS_MEM_BASE
#define CIO_SUCCESS 0
#define CIO_FAILURE 2 /* CIO opcodes */
#define CIO_SYSGEN_OK 3 #define CIO_DLM 1
#define CIO_ULM 2
/* Map a physical address to a card ID */ #define CIO_FCF 3
#define CID(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1) #define CIO_DOS 4
/* Map a card ID to a base address */ #define CIO_DSD 5
#define CADDR(bid) (((((bid) + 1) * 2) << 0x14))
/* Response */
/* Offsets into the request/completion queues of various values */ #define CIO_SUCCESS 0
#define LUSIZE 4 /* Load/Unload pointers size */ #define CIO_FAILURE 2
#define QESIZE 8 /* Queue entry is 8 bytes + application data */ #define CIO_SYSGEN_OK 3
#define CIO_STAT 0 /* Map a physical address to a card ID */
#define CIO_CMD 1 #define SLOT(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1)
/* Map a card ID to a base address */
/* Sysgen State */ #define CADDR(bid) (((((bid) + 1) * 2) << 0x14))
#define CIO_INT_NONE 0
#define CIO_INT0 1 /* Offsets into the request/completion queues of various values */
#define CIO_INT1 2 #define LUSIZE 4 /* Load/Unload pointers size */
#define CIO_SYSGEN 3 #define QESIZE 8 /* Queue entry is 8 bytes + application data */
#define CIO_SET_INT(slot) (cio_int_req |= (1 << slot)) #define CIO_STAT 0
#define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot)) #define CIO_CMD 1
typedef struct { /* Sysgen State */
uint16 id; /* Card ID */ #define CIO_INT_NONE 0
void (*exp_handler)(uint8 cid); /* Handler for express jobs */ #define CIO_INT0 1
void (*full_handler)(uint8 cid); /* Handler for full jobs */ #define CIO_INT1 2
void (*sysgen)(uint8 cid); /* Sysgen routine (optional) */ #define CIO_SYSGEN 3
void (*reset_handler)(uint8 cid); /* RESET request handler (optional) */
uint32 rqp; /* Request Queue Pointer */ #define CIO_SET_INT(slot) if (cio[slot].populated && cio[slot].ivec >= 2) (cio_int_req |= (1 << slot))
uint32 cqp; /* Completion Queue Pointer */ #define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot))
uint8 rqs; /* Request queue size */
uint8 cqs; /* Completion queue size */ #define CIO_NAME_LEN 8
uint8 ivec; /* Interrupt Vector */
uint8 no_rque; /* Number of request queues */ typedef struct {
uint8 ipl; /* IPL that this card uses */ t_bool populated; /* Populated? */
uint8 sysgen_s; /* Sysgen state */ uint16 id; /* CIO identifier */
uint8 seqbit; /* Squence Bit */ char name[CIO_NAME_LEN]; /* Device name */
uint8 op; /* Last received opcode */ void (*exp_handler)(uint8 slot); /* Handler for express jobs */
} CIO_STATE; void (*full_handler)(uint8 slot); /* Handler for full jobs */
void (*sysgen)(uint8 slot); /* Sysgen routine (optional) */
typedef struct { void (*reset_handler)(uint8 slot); /* RESET request handler (optional) */
uint16 byte_count; uint32 rqp; /* Request Queue Pointer */
uint8 subdevice; uint32 cqp; /* Completion Queue Pointer */
uint8 opcode; uint8 rqs; /* Request queue size */
uint32 address; uint8 cqs; /* Completion queue size */
} cio_entry; uint8 ivec; /* Interrupt Vector */
uint8 no_rque; /* Number of request queues */
typedef struct { uint8 ipl; /* IPL that this card uses */
uint32 low; uint8 sysgen_s; /* Sysgen state */
uint32 high; uint8 seqbit; /* Squence Bit */
uint32 (*read)(uint32 pa, size_t size); uint8 op; /* Last received opcode */
void (*write)(uint32 pa, uint32 val, size_t size); } CIO_STATE;
} iolink;
typedef struct {
/* Example pump structure uint16 byte_count;
* ---------------------- uint8 subdevice;
* uint8 opcode;
* Used during initial setup of PORTS card in slot 0: uint32 address;
* } cio_entry;
* dev = 0100
* min = 0000 typedef struct {
* cmdcode = 0003 uint32 low;
* options = 0000 uint32 high;
* bufaddr = 808821A0 uint32 (*read)(uint32 pa, size_t size);
* ioaddr = 00000500 void (*write)(uint32 pa, uint32 val, size_t size);
* size = 00000650 } iolink;
* numbrd = 00000000
* retcode = 00000008 (PU_NULL) /* Example pump structure
*/ * ----------------------
*
typedef struct { * Used during initial setup of PORTS card in slot 0:
uint16 dev; *
uint16 min; * dev = 0100
uint16 cmdcode; * min = 0000
uint16 options; * cmdcode = 0003
uint32 bufaddr; * options = 0000
uint32 ioaddr; * bufaddr = 808821A0
uint32 size; * ioaddr = 00000500
uint32 numbrd; * size = 00000650
uint32 retcode; * numbrd = 00000000
} pump; * retcode = 00000008 (PU_NULL)
*/
t_stat cio_reset(DEVICE *dptr);
t_stat cio_svc(UNIT *uptr); typedef struct {
uint16 dev;
void cio_clear(uint8 cid); uint16 min;
uint32 cio_crc32_shift(uint32 crc, uint8 data); uint16 cmdcode;
void cio_cexpress(uint8 cid, uint32 esize, cio_entry *cqe, uint8 *app_data); uint16 options;
void cio_cqueue(uint8 cid, uint8 cmd_stat, uint32 esize, cio_entry *cqe, uint8 *app_data); uint32 bufaddr;
t_bool cio_cqueue_avail(uint8 cid, uint32 esize); uint32 ioaddr;
void cio_rexpress(uint8 cid, uint32 esize, cio_entry *rqe, uint8 *app_data); uint32 size;
t_stat cio_rqueue(uint8 cid, uint32 qnum, uint32 esize, cio_entry *rqe, uint8 *app_data); uint32 numbrd;
t_bool cio_rqueue_avail(uint8 cid, uint32 qnum, uint32 esize); uint32 retcode;
uint16 cio_r_lp(uint8 cid, uint32 qnum, uint32 esize); } pump;
uint16 cio_r_ulp(uint8 cid, uint32 qnum, uint32 esize);
uint16 cio_c_lp(uint8 cid, uint32 esize); t_stat cio_reset(DEVICE *dptr);
uint16 cio_c_ulp(uint8 cid, uint32 esize); t_stat cio_svc(UNIT *uptr);
void cio_sysgen(uint8 cid);
t_stat cio_install(uint16 id,
uint32 io_read(uint32 pa, size_t size); CONST char *name,
void io_write(uint32 pa, uint32 val, size_t size); uint8 ipl,
void (*exp_handler)(uint8 slot),
void dump_entry(uint32 dbits, DEVICE *dev, CONST char *type, void (*full_handler)(uint8 slot),
uint32 esize, cio_entry *entry, uint8 *app_data); void (*sysgen)(uint8 slot),
void (*reset_handler)(uint8 slot),
extern uint16 cio_int_req; uint8 *slot);
extern CIO_STATE cio[CIO_SLOTS]; void cio_remove(uint8 slot);
void cio_remove_all(uint16 id);
#endif uint32 cio_crc32_shift(uint32 crc, uint8 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);
t_bool cio_cqueue_avail(uint8 slot, uint32 esize);
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_bool cio_rqueue_avail(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_c_lp(uint8 slot, uint32 esize);
uint16 cio_c_ulp(uint8 slot, uint32 esize);
void cio_sysgen(uint8 slot);
uint32 io_read(uint32 pa, size_t size);
void io_write(uint32 pa, uint32 val, size_t size);
extern uint16 cio_int_req;
extern CIO_STATE cio[CIO_SLOTS];
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,214 +1,234 @@
/* 3b2_iu.h: SCN2681A Dual UART Header /* 3b2_iu.h: SCN2681A Dual UART
Copyright (c) 2017, 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_TAI 0x01 /* Transmitter ready A */ #define ISTS_TXRA 0x01 /* Transmitter ready A */
#define ISTS_RAI 0x02 /* Receiver ready A */ #define ISTS_RXRA 0x02 /* Receiver ready A */
#define ISTS_CBA 0x04 /* Change in break A */ #define ISTS_DBA 0x04 /* Delta Break A */
#define ISTS_CRI 0x08 /* Counter ready */ #define ISTS_CRI 0x08 /* Counter ready */
#define ISTS_TBI 0x10 /* Transmitter ready B */ #define ISTS_TXRB 0x10 /* Transmitter ready B */
#define ISTS_RBI 0x20 /* Receiver ready B */ #define ISTS_RXRB 0x20 /* Receiver ready B */
#define ISTS_CBB 0x40 /* Change in 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
/* Used by the DMAC */ /* Transmitter State bits */
#define IUA_DATA_REG 3 #define T_HOLD 1
#define IUB_DATA_REG 11 #define T_XMIT 2
/* Registers - Read */ /* Used by the DMAC */
#define SRA 1 #define IUA_DATA_REG 3
#define RHRA 3 #define IUB_DATA_REG 11
#define IPCR 4
#define ISR 5 /* Registers - Read */
#define CTU 6 #define SRA 1
#define CTL 7 #define RHRA 3
#define SRB 9 #define IPCR 4
#define RHRB 11 #define ISR 5
#define INPRT 13 /* Input port data */ #define CTU 6
#define START_CTR 14 #define CTL 7
#define STOP_CTR 15 #define SRB 9
#define RHRB 11
/* Registers - Write */ #define INPRT 13
#define CSRA 1 #define START_CTR 14
#define CRA 2 #define STOP_CTR 15
#define THRA 3
#define ACR 4 /* Registers - Write */
#define IMR 5 #define CSRA 1
#define CTUR 6 #define CRA 2
#define CTLR 7 #define THRA 3
#define CSRB 9 #define ACR 4
#define CRB 10 #define IMR 5
#define THRB 11 #define CTUR 6
#define OPCR 13 #define CTLR 7
#define SOPR 14 #define CSRB 9
#define ROPR 15 #define CRB 10
#define THRB 11
/* Registers - R/W */ #define OPCR 13
#define MR12A 0 #define SOPR 14
#define MR12B 8 #define ROPR 15
/* Port configuration */ /* Registers - R/W */
#define TX_EN 1 #define MR12A 0
#define RX_EN 2 #define MR12B 8
#define UM_CTR_EXT 0 /* Port configuration */
#define UM_CTR_TXCA 1 #define TX_EN 1
#define UM_CTR_TXCB 2 #define RX_EN 2
#define UM_CTR_DIV16 3
#define UM_TMR_EXT 4 /* Control Register commands */
#define UM_TMR_EXT16 5 #define CR_RST_MR 1
#define UM_TMR_XTL 6 #define CR_RST_RX 2
#define UM_TMR_XTL16 7 #define CR_RST_TX 3
#define UM_MASK 0x70 #define CR_RST_ERR 4
#define UM_SHIFT 4 #define CR_RST_BRK 5
#define CR_START_BRK 6
/* IMR bits */ #define CR_STOP_BRK 7
#define IMR_TXRA 0x01
#define IMR_RXRA 0x02 /* IMR bits */
#define IMR_CTR 0x08 #define IMR_TXRA 0x01
#define IMR_TXRB 0x10 #define IMR_RXRA 0x02
#define IMR_RXRB 0x20 #define IMR_CTR 0x08
#define IMR_TXRB 0x10
/* Power-off bit */ #define IMR_RXRB 0x20
#define IU_KILLPWR 0x04
/* Power-off bit */
#define PORT_A 0 #define IU_KILLPWR 0x04
#define PORT_B 1
#define PORT_A 0
#define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT) #define PORT_B 1
#define IUBASE 0x49000 #define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT)
#define IUSIZE 0x100
#define IUBASE 0x49000
#define IU_BUF_SIZE 3 #define IUSIZE 0x100
#define IU_DCDA 0x01 #define IU_BUF_SIZE 3
#define IU_DCDB 0x02
#define IU_DTRA 0x01 /* Data Carrier Detect inputs and input change bits */
#define IU_DTRB 0x02 #if defined(REV3)
#define IU_DCDB_CH 0x80
#define DMA_NONE 0 #define IU_DCDA_CH 0x40
#define DMA_VERIFY 1 #define IU_DCDB 0x08
#define DMA_WRITE 2 #define IU_DCDA 0x04
#define DMA_READ 4 #else
#define IU_DCDB_CH 0x20
/* Default baud rate generator (9600 baud) */ #define IU_DCDA_CH 0x10
#define BRG_DEFAULT 11 #define IU_DCDB 0x02
#define IU_DCDA 0x01
#define IU_TIMER_RATE 2.114 /* microseconds per step */ #endif
/* Default baud rate generator (9600 baud) */
typedef struct iu_port { #define BRG_DEFAULT 11
uint8 stat; /* Port Status */
uint8 cmd; /* Command */ /* The 2681 DUART includes a 16-bit timer/counter that can be used to
uint8 mode[2]; /* Two mode buffers */ * trigger an interrupt after a certain amount of time has passed.
uint8 modep; /* Point to mode[0] or mode[1] */ *
uint8 conf; /* Configuration bits */ * The 2681 uses a crystal with a frequency of 3.686400 MHz, and the
uint8 txbuf; /* Transmit Holding Register */ * timer/counter uses this frequency divided by 16, giving a final
uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */ * timer/counter frequency of 230,400 Hz. There are therefore 4.34
uint8 w_p; /* Buffer Write Pointer */ * microseconds of wall time per tick of the timer.
uint8 r_p; /* Buffer Read Pointer */ *
uint8 dma; /* Currently active DMA mode */ * The multiplier defined below is a default that can be adjusted to
t_bool drq; /* DMA request enabled */ * make IU timing faster, but less accurate, if desired */
} IU_PORT;
#define IU_TIMER_MULTIPLIER 4
typedef struct iu_state {
uint8 istat; /* Interrupt Status */ typedef struct iu_port {
uint8 imr; /* Interrupt Mask Register */ uint8 cmd; /* Command */
uint8 acr; uint8 mode[2]; /* Two mode buffers */
uint8 opcr; /* Output Port Configuration */ uint8 modep; /* Point to mode[0] or mode[1] */
uint8 inprt; /* Input Port Data */ uint8 conf; /* Configuration bits */
uint8 ipcr; /* Input Port Change Register */ uint8 sr; /* Status Register */
} IU_STATE; uint8 thr; /* Transmit Holding Register */
uint8 txr; /* Transmit Shift Register */
typedef struct iu_timer_state { uint8 rxr; /* Receive Shift Register */
uint16 c_set; uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */
t_bool c_en; uint8 w_p; /* Receive Buffer Write Pointer */
} IU_TIMER_STATE; uint8 r_p; /* Receive Buffer Read Pointer */
uint8 tx_state; /* Transmitting state flags (HOLD, XMIT) */
/* Function prototypes */ t_bool dma; /* DMA currently active */
t_stat contty_attach(UNIT *uptr, CONST char *cptr); t_bool drq; /* DMA request enabled */
t_stat contty_detach(UNIT *uptr); t_bool rxr_full; /* Receive Shift Register is full */
t_stat tti_reset(DEVICE *dptr); } IU_PORT;
t_stat contty_reset(DEVICE *dptr);
t_stat iu_timer_reset(DEVICE *dptr); typedef struct iu_state {
t_stat iu_svc_tti(UNIT *uptr); uint8 isr; /* Interrupt Status Register */
t_stat iu_svc_tto(UNIT *uptr); uint8 imr; /* Interrupt Mask Register */
t_stat iu_svc_contty_rcv(UNIT *uptr); uint8 acr; /* Aux. Control Register */
t_stat iu_svc_contty_xmt(UNIT *uptr); uint8 opcr; /* Output Port Configuration */
t_stat iu_svc_timer(UNIT *uptr); uint8 inprt; /* Input Port Data */
t_stat iu_tx(uint8 portno, uint8 val); uint8 ipcr; /* Input Port Change Register */
uint32 iu_read(uint32 pa, size_t size); } IU_STATE;
void iu_write(uint32 pa, uint32 val, size_t size);
void iua_drq_handled(); typedef struct iu_timer_state {
void iub_drq_handled(); uint16 c_set;
void iu_txrdy_a_irq(); t_bool c_en;
void iu_txrdy_b_irq(); } IU_TIMER_STATE;
void iu_dma_console(uint8 channel, uint32 service_address);
void iu_dma_contty(uint8 channel, uint32 service_address); /* Function prototypes */
void increment_modep_a(); t_stat contty_attach(UNIT *uptr, CONST char *cptr);
void increment_modep_b(); t_stat contty_detach(UNIT *uptr);
t_stat tti_reset(DEVICE *dptr);
extern IU_PORT iu_console; t_stat contty_reset(DEVICE *dptr);
extern IU_PORT iu_contty; t_stat iu_timer_reset(DEVICE *dptr);
extern t_bool iu_increment_a; t_stat iu_timer_set_mult(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
extern t_bool iu_increment_b; t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, CONST void *desc);
t_stat iu_svc_tti(UNIT *uptr);
#endif t_stat iu_svc_tto(UNIT *uptr);
t_stat iu_svc_contty(UNIT *uptr);
t_stat iu_svc_contty_xmt(UNIT *uptr);
t_stat iu_svc_timer(UNIT *uptr);
uint32 iu_read(uint32 pa, size_t size);
void iu_write(uint32 pa, uint32 val, size_t size);
void iua_drq_handled();
void iub_drq_handled();
void iu_txrdy_a_irq();
void iu_txrdy_b_irq();
void iu_dma_console(uint8 channel, uint32 service_address);
void iu_dma_contty(uint8 channel, uint32 service_address);
void increment_modep_a();
void increment_modep_b();
extern IU_PORT iu_console;
extern IU_PORT iu_contty;
extern t_bool iu_increment_a;
extern t_bool iu_increment_b;
#endif

File diff suppressed because it is too large Load diff

View file

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

View file

@ -1,324 +1,346 @@
/* 3b2_mem.c: AT&T 3B2 memory access routines /* 3b2_mem.c: Memory Map Access Routines
Copyright (c) 2021, 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"
t_bool addr_is_rom(uint32 pa) #include "3b2_dmac.h"
{
return (pa < rom_size); #if defined(REV3)
} static uint32 ecc_addr; /* ECC address */
static t_bool ecc_err; /* ECC multi-bit error */
t_bool addr_is_mem(uint32 pa) #endif
{
return (pa >= PHYS_MEM_BASE && /*
pa < (PHYS_MEM_BASE + MEM_SIZE)); * 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.
t_bool addr_is_io(uint32 pa) */
{ static SIM_INLINE void check_ecc(uint32 pa, t_bool write, uint8 src)
#if defined(REV3) {
return ((pa >= IO_BOTTOM && pa < IO_TOP) || #if defined(REV3)
(pa >= CIO_BOTTOM && pa < CIO_TOP) || /* Force ECC Syndrome mode enables a diagnostic mode on the AM2960
(pa >= VCACHE_BOTTOM && pa < VCACHE_TOP) || data correction ICs */
(pa >= BUB_BOTTOM && pa < BUB_TOP)); if (write && !CSR(CSRFECC)) {
#else sim_debug(EXECUTE_MSG, &mmu_dev,
return ((pa >= IO_BOTTOM && pa < IO_TOP) || "ECC Error on Write. pa=%08x\n",
(pa >= CIO_BOTTOM && pa < CIO_TOP)); pa);
#endif ecc_addr = pa;
} ecc_err = TRUE;
} else if (ecc_err && !write && pa == ecc_addr) {
/* Read Word (Physical Address) */ sim_debug(EXECUTE_MSG, &mmu_dev,
uint32 pread_w(uint32 pa) "ECC Error detected on Read. pa=%08x psw=%08x cur_ipl=%d csr=%08x\n",
{ pa, R[NUM_PSW], PSW_CUR_IPL, csr_data);
uint32 *m; flt[0] = ecc_addr & 0x3ffff;
uint32 index; flt[1] = MA_CPU_IO|MA_CPU_BU;
ecc_err = FALSE;
if (pa & 3) { CSRBIT(CSRFRF, TRUE); /* Fault registers frozen */
sim_debug(READ_MSG, &mmu_dev, CSRBIT(CSRMBERR, TRUE); /* Multi-bit error */
"[%08x] Cannot read physical address. ALIGNMENT ISSUE: %08x\n", CPU_SET_INT(INT_MBERR);
R[NUM_PC], pa); /* Only abort if CPU is doing the read */
CSRBIT(CSRALGN, TRUE); if (src == BUS_CPU) {
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
} }
}
if (addr_is_io(pa)) { #endif
return io_read(pa, 32); }
}
/* Read Word (Physical Address) */
if (addr_is_rom(pa)) { uint32 pread_w(uint32 pa, uint8 src)
m = ROM; {
index = pa >> 2; uint8 *m;
} else if (addr_is_mem(pa)) { uint32 index = 0;
m = RAM;
index = (pa - PHYS_MEM_BASE) >> 2; #if defined(REV3)
} else { if ((pa & 3) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
return 0; #else
} if (pa & 3) {
#endif
return m[index]; sim_debug(READ_MSG, &mmu_dev,
} "Cannot read physical address. ALIGNMENT ISSUE: %08x\n",
pa);
/* CSRBIT(CSRALGN, TRUE);
* Write Word (Physical Address) cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
*/ }
void pwrite_w(uint32 pa, uint32 val)
{ if (IS_IO(pa)) {
if (pa & 3) { return io_read(pa, 32);
sim_debug(WRITE_MSG, &mmu_dev, }
"[%08x] Cannot write physical address. ALIGNMENT ISSUE: %08x\n",
R[NUM_PC], pa); if (IS_ROM(pa)) {
CSRBIT(CSRALGN, TRUE); m = ROM;
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); index = pa;
} } else if (IS_RAM(pa)) {
check_ecc(pa, FALSE, src);
if (addr_is_io(pa)) { m = RAM;
io_write(pa, val, 32); index = (pa - PHYS_MEM_BASE);
return; } else {
} return 0;
}
if (addr_is_mem(pa)) {
RAM[(pa - PHYS_MEM_BASE) >> 2] = val; return ATOW(m, index);
return; }
}
} /*
* Write Word (Physical Address)
/* */
* Read Halfword (Physical Address) void pwrite_w(uint32 pa, uint32 val, uint8 src)
*/ {
uint16 pread_h(uint32 pa) uint32 index;
{
uint32 *m; if (pa & 3) {
uint32 index; sim_debug(WRITE_MSG, &mmu_dev,
"Cannot write physical address. ALIGNMENT ISSUE: %08x\n",
if (pa & 1) { pa);
sim_debug(READ_MSG, &mmu_dev, CSRBIT(CSRALGN, TRUE);
"[%08x] Cannot read physical address. ALIGNMENT ISSUE %08x\n", cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
R[NUM_PC], pa); }
CSRBIT(CSRALGN, TRUE);
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); if (IS_IO(pa)) {
} io_write(pa, val, 32);
return;
if (addr_is_io(pa)) { }
return (uint16) io_read(pa, 16);
} if (IS_RAM(pa)) {
check_ecc(pa, TRUE, src);
if (addr_is_rom(pa)) { index = pa - PHYS_MEM_BASE;
m = ROM; RAM[index] = (val >> 24) & 0xff;
index = pa >> 2; RAM[index + 1] = (val >> 16) & 0xff;
} else if (addr_is_mem(pa)) { RAM[index + 2] = (val >> 8) & 0xff;
m = RAM; RAM[index + 3] = val & 0xff;
index = (pa - PHYS_MEM_BASE) >> 2; return;
} else { }
return 0; }
}
/*
if (pa & 2) { * Read Halfword (Physical Address)
return m[index] & HALF_MASK; */
} else { uint16 pread_h(uint32 pa, uint8 src)
return (m[index] >> 16) & HALF_MASK; {
} uint8 *m;
} uint32 index;
/* if (pa & 1) {
* Write Halfword (Physical Address) sim_debug(READ_MSG, &mmu_dev,
*/ "Cannot read physical address. ALIGNMENT ISSUE %08x\n",
void pwrite_h(uint32 pa, uint16 val) pa);
{ CSRBIT(CSRALGN, TRUE);
uint32 *m; cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
uint32 index; }
uint32 wval = (uint32)val;
if (IS_IO(pa)) {
if (pa & 1) { return (uint16) io_read(pa, 16);
sim_debug(WRITE_MSG, &mmu_dev, }
"[%08x] Cannot write physical address %08x, ALIGNMENT ISSUE\n",
R[NUM_PC], pa); if (IS_ROM(pa)) {
CSRBIT(CSRALGN, TRUE); m = ROM;
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT); index = pa;
} } else if (IS_RAM(pa)) {
check_ecc(pa, FALSE, src);
if (addr_is_io(pa)) { m = RAM;
io_write(pa, val, 16); index = pa - PHYS_MEM_BASE;
return; } else {
} return 0;
}
if (addr_is_mem(pa)) {
m = RAM; return ATOH(m, index);
index = (pa - PHYS_MEM_BASE) >> 2; }
} else {
return; /*
} * Write Halfword (Physical Address)
*/
if (pa & 2) { void pwrite_h(uint32 pa, uint16 val, uint8 src)
m[index] = (m[index] & ~HALF_MASK) | wval; {
} else { uint32 index;
m[index] = (m[index] & HALF_MASK) | (wval << 16);
} #if defined(REV3)
} if ((pa & 1) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
#else
/* if (pa & 1) {
* Read Byte (Physical Address) #endif
*/ sim_debug(WRITE_MSG, &mmu_dev,
uint8 pread_b(uint32 pa) "Cannot write physical address %08x, ALIGNMENT ISSUE\n",
{ pa);
uint32 data; CSRBIT(CSRALGN, TRUE);
int32 sc = (~(pa & 3) << 3) & 0x1f; }
if (addr_is_io(pa)) { if (IS_IO(pa)) {
return (uint8)(io_read(pa, 8)); io_write(pa, val, 16);
} return;
}
if (addr_is_rom(pa)) {
data = ROM[pa >> 2]; if (IS_RAM(pa)) {
} else if (addr_is_mem(pa)) { check_ecc(pa, TRUE, src);
data = RAM[(pa - PHYS_MEM_BASE) >> 2]; index = pa - PHYS_MEM_BASE;
} else { RAM[index] = (val >> 8) & 0xff;
return 0; RAM[index + 1] = val & 0xff;
} return;
}
return (data >> sc) & BYTE_MASK; }
}
/*
/* Write Byte (Physical Address) */ * Read Byte (Physical Address)
void pwrite_b(uint32 pa, uint8 val) */
{ uint8 pread_b(uint32 pa, uint8 src)
uint32 *m; {
int32 index; if (IS_IO(pa)) {
int32 sc = (~(pa & 3) << 3) & 0x1f; return (uint8)(io_read(pa, 8));
uint32 mask = 0xffu << sc; }
if (addr_is_io(pa)) { if (IS_ROM(pa)) {
io_write(pa, val, 8); return ROM[pa];
return; } else if (IS_RAM(pa)) {
} check_ecc(pa, FALSE, src);
return RAM[pa - PHYS_MEM_BASE];
if (addr_is_mem(pa)) { } else {
m = RAM; return 0;
index = (pa - PHYS_MEM_BASE) >> 2; }
m[index] = (m[index] & ~mask) | (uint32) (val << sc); }
return;
} /* Write Byte (Physical Address) */
} void pwrite_b(uint32 pa, uint8 val, uint8 src)
{
/* Read Byte (Virtual Address) */ uint32 index;
uint8 read_b(uint32 va, uint8 r_acc)
{ if (IS_IO(pa)) {
return pread_b(mmu_xlate_addr(va, r_acc)); io_write(pa, val, 8);
} return;
}
/* Write Byte (Virtual Address) */
void write_b(uint32 va, uint8 val) if (IS_RAM(pa)) {
{ check_ecc(pa, TRUE, src);
pwrite_b(mmu_xlate_addr(va, ACC_W), val); index = pa - PHYS_MEM_BASE;
} RAM[index] = val;
return;
/* Read Halfword (Virtual Address) */ }
uint16 read_h(uint32 va, uint8 r_acc) }
{
return pread_h(mmu_xlate_addr(va, r_acc)); /* Write to ROM (used by ROM load) */
} void pwrite_b_rom(uint32 pa, uint8 val) {
if (IS_ROM(pa)) {
/* Write Halfword (Virtual Address) */ ROM[pa] = val;
void write_h(uint32 va, uint16 val) }
{ }
pwrite_h(mmu_xlate_addr(va, ACC_W), val);
} /* Read Byte (Virtual Address) */
uint8 read_b(uint32 va, uint8 r_acc, uint8 src)
/* Read Word (Virtual Address) */ {
uint32 read_w(uint32 va, uint8 r_acc) return pread_b(mmu_xlate_addr(va, r_acc), src);
{ }
return pread_w(mmu_xlate_addr(va, r_acc));
} /* Write Byte (Virtual Address) */
void write_b(uint32 va, uint8 val, uint8 src)
/* Write Word (Virtual Address) */ {
void write_w(uint32 va, uint32 val) pwrite_b(mmu_xlate_addr(va, ACC_W), val, src);
{ }
pwrite_w(mmu_xlate_addr(va, ACC_W), val);
} /* Read Halfword (Virtual Address) */
uint16 read_h(uint32 va, uint8 r_acc, uint8 src)
t_stat read_operand(uint32 va, uint8 *val) {
{ return pread_h(mmu_xlate_addr(va, r_acc), src);
uint32 pa; }
t_stat succ;
/* Write Halfword (Virtual Address) */
succ = mmu_decode_va(va, ACC_IF, TRUE, &pa); void write_h(uint32 va, uint16 val, uint8 src)
{
if (succ == SCPE_OK) { pwrite_h(mmu_xlate_addr(va, ACC_W), val, src);
*val = pread_b(pa); }
} else {
*val = 0; /* Read Word (Virtual Address) */
} uint32 read_w(uint32 va, uint8 r_acc, uint8 src)
{
return succ; return pread_w(mmu_xlate_addr(va, r_acc), src);
} }
t_stat examine(uint32 va, uint8 *val) /* Write Word (Virtual Address) */
{ void write_w(uint32 va, uint32 val, uint8 src)
uint32 pa; {
t_stat succ; pwrite_w(mmu_xlate_addr(va, ACC_W), val, src);
}
succ = mmu_decode_va(va, 0, FALSE, &pa);
t_stat read_operand(uint32 va, uint8 *val)
if (succ == SCPE_OK) { {
if (addr_is_rom(pa) || addr_is_mem(pa)) { uint32 pa;
*val = pread_b(pa); t_stat succ;
return SCPE_OK;
} else { succ = mmu_decode_va(va, ACC_IF, TRUE, &pa);
*val = 0;
return SCPE_NXM; if (succ == SCPE_OK) {
} *val = pread_b(pa, BUS_CPU);
} else { } else {
*val = 0; *val = 0;
return succ; }
}
} return succ;
}
t_stat deposit(uint32 va, uint8 val)
{ t_stat examine(uint32 va, uint8 *val)
uint32 pa; {
t_stat succ; uint32 pa;
t_stat succ;
succ = mmu_decode_va(va, 0, FALSE, &pa);
succ = mmu_decode_va(va, 0, FALSE, &pa);
if (succ == SCPE_OK) {
if (addr_is_mem(pa)) { if (succ == SCPE_OK) {
pwrite_b(pa, val); if (IS_ROM(pa) || IS_RAM(pa)) {
return SCPE_OK; *val = pread_b(pa, BUS_CPU);
} else { return SCPE_OK;
return SCPE_NXM; } else {
} *val = 0;
} else { return SCPE_NXM;
return succ; }
} } else {
} *val = 0;
return succ;
}
}
t_stat deposit(uint32 va, uint8 val)
{
uint32 pa;
t_stat succ;
succ = mmu_decode_va(va, 0, FALSE, &pa);
if (succ == SCPE_OK) {
if (IS_RAM(pa)) {
pwrite_b(pa, val, BUS_CPU);
return SCPE_OK;
} else {
return SCPE_NXM;
}
} else {
return succ;
}
}

View file

@ -1,62 +1,79 @@
/* 3b2_mem.h: AT&T 3B2 3B2 memory access routines /* 3b2_mem.h: Memory Map Access Routines
Copyright (c) 2021, 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"
uint32 pread_w(uint32 pa); #define IS_ROM(PA) ((PA) < ROM_SIZE)
void pwrite_w(uint32 pa, uint32 val); #define IS_RAM(PA) (((PA) >= PHYS_MEM_BASE) && ((PA) < (PHYS_MEM_BASE + MEM_SIZE)))
uint8 pread_b(uint32 pa); #if defined(REV3)
void pwrite_b(uint32 pa, uint8 val); #define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
uint16 pread_h(uint32 pa); ((PA >= CIO_BOTTOM) && (PA < CIO_TOP)) || \
void pwrite_h(uint32 pa, uint16 val); ((PA >= VCACHE_BOTTOM) && (PA < VCACHE_TOP)) || \
((PA >= BUB_BOTTOM) && (PA < BUB_TOP)))
uint8 read_b(uint32 va, uint8 r_acc); #else
uint16 read_h(uint32 va, uint8 r_acc); #define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
uint32 read_w(uint32 va, uint8 r_acc); ((PA >= CIO_BOTTOM) && (PA < CIO_TOP)))
void write_b(uint32 va, uint8 val); #endif
void write_h(uint32 va, uint16 val);
void write_w(uint32 va, uint32 val); #define MA_BUB3 0x100 /* BUBUS slot 3 master on fault */
#define MA_BUB2 0x200 /* BUBUS slot 2 master on fault */
t_stat read_operand(uint32 va, uint8 *val); #define MA_BUB1 0x400 /* BUBUS slot 1 master on fault */
t_stat examine(uint32 va, uint8 *val); #define MA_CPU_BU 0x2000 /* CPU access BUBUS peripheral */
t_stat deposit(uint32 va, uint8 val); #define MA_BUB0 0x4000 /* BUBUS slot 0 master on fault */
#define MA_CPU_IO 0x8000 /* CPU accessing I/O peripheral */
t_bool addr_is_rom(uint32 pa); #define MA_IO_NLY 0x10000 /* IO Bus Master on fault */
t_bool addr_is_mem(uint32 pa); #define MA_IO_BM 0x80000 /* IO Bus Master or BUBUS was master on fault */
t_bool addr_is_io(uint32 pa);
#define BUS_PER 0 /* Read or Write is from peripheral */
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); #define BUS_CPU 1 /* Read or Write is from CPU */
void mmu_enable();
void mmu_disable(); uint32 pread_w(uint32 pa, uint8 src);
void pwrite_w(uint32 pa, uint32 val, uint8 src);
#endif /* _3B2_MEM_H_ */ uint8 pread_b(uint32 pa, uint8 src);
void pwrite_b(uint32 pa, uint8 val, uint8 src);
void pwrite_b_rom(uint32 pa, uint8 val);
uint16 pread_h(uint32 pa, uint8 src);
void pwrite_h(uint32 pa, uint16 val, uint8 src);
uint8 read_b(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);
void write_b(uint32 va, uint8 val, uint8 src);
void write_h(uint32 va, uint16 val, uint8 src);
void write_w(uint32 va, uint32 val, uint8 src);
t_stat read_operand(uint32 va, uint8 *val);
t_stat examine(uint32 va, uint8 *val);
t_stat deposit(uint32 va, uint8 val);
#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, 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,214 +1,210 @@
/* 3b2_ni.h: AT&T 3B2 Model 400 "NI" feature card /* 3b2_ni.h: CM195A Network Interface CIO Card
Copyright (c) 2018, 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 NI_PUMP_CRC1 0xfab1057c #define EIG_TABLE_SIZE 40
#define NI_PUMP_CRC2 0xf6744bed #define PKT_HEADER_LEN_OFFSET EIG_TABLE_SIZE
#define PKT_START_OFFSET (PKT_HEADER_LEN_OFFSET + 4)
#define EIG_TABLE_SIZE 40
#define PKT_HEADER_LEN_OFFSET EIG_TABLE_SIZE /*
#define PKT_START_OFFSET (PKT_HEADER_LEN_OFFSET + 4) * The NI card has two request queues for packet receive: One for
* small packets, and one for large packets. The small queue is meant
/* * for packets smaller than 128 bytes. The large queue is meant for
* The NI card has two request queues for packet receive: One for * packets up to 1500 bytes (no jumbo frames allowed)
* small packets, and one for large packets. The small queue is meant */
* for packets smaller than 128 bytes. The large queue is meant for
* packets up to 1500 bytes (no jumbo frames allowed) #define GE_QUEUE 0 /* General request CIO queue */
*/ #define SM_QUEUE 0 /* Small packet receive queue number */
#define LG_QUEUE 1 /* Large packet receive queue number */
#define GE_QUEUE 0 /* General request CIO queue */ #define SM_PKT_MAX 106 /* Max size of small packets (excluding CRC) */
#define SM_QUEUE 0 /* Small packet receive queue number */ #define LG_PKT_MAX 1514 /* Max size of large packets (excluding CRC) */
#define LG_QUEUE 1 /* Large packet receive queue number */
#define SM_PKT_MAX 106 /* Max size of small packets (excluding CRC) */ /*
#define LG_PKT_MAX 1514 /* Max size of large packets (excluding CRC) */ * NI-specific debugging flags
*/
/* #define DBG_TRACE 0x01
* NI-specific debugging flags #define DBG_IO 0x02
*/ #define DBG_CACHE 0x04
#define DBG_TRACE 0x01 #define DBG_DAT 0x08
#define DBG_IO 0x02 #define DBG_ERR 0x10
#define DBG_CACHE 0x04 #define DBG_ETH 0x20
#define DBG_DAT 0x08
#define DBG_ERR 0x10 #define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.')
#define DBG_ETH 0x20
#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp)
#define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.') /* Determine whether both job caches have available slots */
#define NI_BUFFERS_AVAIL ((ni.job_cache[0].wp != ni.job_cache[0].rp) && \
#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp) (ni.job_cache[1].wp != ni.job_cache[1].rp))
/* Determine whether both job caches have available slots */
#define NI_BUFFERS_AVAIL ((ni.job_cache[0].wp != ni.job_cache[0].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
* packet receive queues so that they are available immediately after
/* * receipt of a packet. These jobs are kept in small circular buffers.
* The NI card caches up to three jobs taken from each of the two * Each job is represented by an ni_rec_job structure, containing a
* packet receive queues so that they are available immediately after * buffer pointer and a slot number. The slot number is used by both
* receipt of a packet. These jobs are kept in small circular buffers. * the driver and the firmware to correlate a packet receive buffer
* Each job is represented by an ni_rec_job structure, containing a * with a completion queue event.
* buffer pointer and a slot number. The slot number is used by both */
* the driver and the firmware to correlate a packet receive buffer typedef struct {
* with a completion queue event. uint32 addr; /* address of job's buffer */
*/ uint8 slot; /* slot number of the job */
typedef struct { } ni_rec_job;
uint32 addr; /* address of job's buffer */
uint8 slot; /* slot number of the job */ #define NI_CACHE_LEN 4
} ni_rec_job;
typedef struct {
#define NI_CACHE_LEN 4 ni_rec_job req[NI_CACHE_LEN]; /* the cache */
int wp; /* write pointer */
typedef struct { int rp; /* read pointer */
ni_rec_job req[NI_CACHE_LEN]; /* the cache */ } ni_job_cache;
int wp; /* write pointer */
int rp; /* read pointer */ /*
} ni_job_cache; * When the NI driver submits a packet send request to the general
* request queue, it constructs one or more ni_prot_info structs in
/* * main memory that point to the protocol-specific byte data of the
* When the NI driver submits a packet send request to the general * packet (minus the Ethernet frame). These structs are packed one
* request queue, it constructs one or more ni_prot_info structs in * after the other following the Ethernet frame header in the job's
* main memory that point to the protocol-specific byte data of the * request buffer. The last entry has its "last" bit set to non-zero.
* packet (minus the Ethernet frame). These structs are packed one */
* after the other following the Ethernet frame header in the job's typedef struct {
* request buffer. The last entry has its "last" bit set to non-zero. uint32 addr; /* Physical address of the buffer in system RAM */
*/ uint16 size; /* Length of the buffer */
typedef struct { uint16 last; /* Is this the last entry in the list? */
uint32 addr; /* Physical address of the buffer in system RAM */ } ni_prot_info;
uint16 size; /* Length of the buffer */
uint16 last; /* Is this the last entry in the list? */ typedef struct {
} ni_prot_info; uint32 rq_taken;
uint32 tx_fail;
typedef struct { uint32 rx_dropped;
uint32 rq_taken; uint32 rx_pkt;
uint32 tx_fail; uint32 tx_pkt;
uint32 rx_dropped; uint32 rx_bytes;
uint32 rx_pkt; uint32 tx_bytes;
uint32 tx_pkt; } ni_stat_info;
uint32 rx_bytes;
uint32 tx_bytes; typedef struct {
} ni_stat_info; uint8 slot;
t_bool enabled;
typedef struct { uint32 crc;
uint8 cid; uint32 poll_rate;
t_bool initialized; char mac_str[MAC_SIZE_CHARS];
t_bool enabled; uint8 mac_bytes[MAC_SIZE_BYTES];
uint32 crc; ni_job_cache job_cache[2];
uint32 poll_rate; ni_prot_info prot;
char mac_str[MAC_SIZE_CHARS]; ni_stat_info stats;
uint8 mac_bytes[MAC_SIZE_BYTES]; uint8 fcf_seq;
ni_job_cache job_cache[2]; ETH_DEV* eth;
ni_prot_info prot; ETH_PACK rd_buf;
ni_stat_info stats; ETH_PACK wr_buf;
uint8 fcf_seq; ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */
ETH_DEV* eth; int filter_count; /* Number of filters available */
ETH_PACK rd_buf; ETH_PCALLBACK callback;
ETH_PACK wr_buf; } NI_STATE;
ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */
int filter_count; /* Number of filters available */ void ni_recv_callback(int status);
ETH_PCALLBACK callback; t_stat ni_reset(DEVICE *dptr);
} NI_STATE; t_stat ni_rcv_svc(UNIT *uptr);
t_stat ni_sanity_svc(UNIT *uptr);
void ni_recv_callback(int status); t_stat ni_rq_svc(UNIT *uptr);
t_stat ni_reset(DEVICE *dptr); t_stat ni_cio_svc(UNIT *uptr);
t_stat ni_rcv_svc(UNIT *uptr); t_stat ni_attach(UNIT *uptr, CONST char *cptr);
t_stat ni_sanity_svc(UNIT *uptr); t_stat ni_detach(UNIT *uptr);
t_stat ni_rq_svc(UNIT *uptr); t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat ni_cio_svc(UNIT *uptr); t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ni_attach(UNIT *uptr, CONST char *cptr); t_stat ni_try_job(uint8 slot);
t_stat ni_detach(UNIT *uptr); t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ni_setmac(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_showmac(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_try_job(uint8 cid); t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc); const char *ni_description(DEVICE *dptr);
t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc); void ni_cio_reset(uint8 slot);
t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc); void ni_process_packet();
const char *ni_description(DEVICE *dptr); void ni_int_ack(uint8 slot);
t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); void ni_sysgen(uint8 slot);
void ni_cio_reset(uint8 cid); void ni_express(uint8 slot);
void ni_process_packet(); void ni_full(uint8 slot);
void ni_int_ack(uint8 cid);
void ni_sysgen(uint8 cid); #endif /* _3B2_NI_H_ */
void ni_express(uint8 cid);
void ni_full(uint8 cid);
#endif /* _3B2_NI_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,230 +1,229 @@
/* 3b2_ports.h: AT&T 3B2 Model 400 "PORTS" feature card /* 3b2_ports.h: CM195B 4-Port Serial CIO Card
Copyright (c) 2018, 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_PORTS_CARDS 12 #define MAX_CARDS 8 /* Up to 8 PORTS cards with 32 lines total
#define PORTS_LINES 4 supported */
#define PORTS_RCV_QUEUE 5 #define PORTS_LINES 4
#define PORTS_RCV_QUEUE 5
/*
* 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 * Sub-field values for the PPC_DEVICE request entry; these are placed
* DR indicates that this is a code for use in "device" request * in app_data.bt[0] in the PPC_DEVICE application field. The prefix
* entries only. * DR indicates that this is a code for use in "device" request
*/ * entries only.
*/
#define DR_ENA 1 /* enable a device */
#define DR_DIS 2 /* disable a device */ #define DR_ENA 1 /* enable a device */
#define DR_ABR 3 /* abort reception on a device */ #define DR_DIS 2 /* disable a device */
#define DR_ABX 4 /* abort transmission on a device */ #define DR_ABR 3 /* abort reception on a device */
#define DR_BRK 5 /* transmit "break" on a device */ #define DR_ABX 4 /* abort transmission on a device */
#define DR_SUS 6 /* suspend xmit on a device */ #define DR_BRK 5 /* transmit "break" on a device */
#define DR_RES 7 /* resume xmit on a device */ #define DR_SUS 6 /* suspend xmit on a device */
#define DR_BLK 8 /* transmit STOP character */ #define DR_RES 7 /* resume xmit on a device */
#define DR_UNB 9 /* transmit START character */ #define DR_BLK 8 /* transmit STOP character */
#define DR_UNB 9 /* transmit START character */
/*
* Sub-field values for the PPC_DEVICE completion entry; these appear /*
* in app_data.bt[0] in the PPC_DEVICE application field. These are * Sub-field values for the PPC_DEVICE completion entry; these appear
* mutually exclusive and cannot be combined. The prefix DC indicates * in app_data.bt[0] in the PPC_DEVICE application field. These are
* that this is a code for use in "device" completion entries only. * mutually exclusive and cannot be combined. The prefix DC indicates
*/ * that this is a code for use in "device" completion entries only.
*/
#define DC_NORM 0x00 /* command executed as requested */
#define DC_DEV 0x01 /* bad device number */ #define DC_NORM 0x00 /* command executed as requested */
#define DC_NON 0x02 /* bad sub-code on request */ #define DC_DEV 0x01 /* bad device number */
#define DC_FAIL 0x03 /* failed to read express entry */ #define DC_NON 0x02 /* bad sub-code on request */
#define DC_FAIL 0x03 /* failed to read express entry */
/*
* 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 * Sub-field values for the PPC_RECV completion entry; these appear in
* mutually exclusive and may appear in combination. The prefix RC * app_data.bt[0] in the PPC_RECV application field. These are NOT
* indicates that this is a code for use in "read" completion entries * mutually exclusive and may appear in combination. The prefix RC
* only. * indicates that this is a code for use in "read" completion entries
*/ * only.
*/
#define RC_DSR 0x01 /* disruption of service */
#define RC_FLU 0x02 /* buffer flushed */ #define RC_DSR 0x01 /* disruption of service */
#define RC_TMR 0x04 /* inter-character timer expired */ #define RC_FLU 0x02 /* buffer flushed */
#define RC_BQO 0x08 /* PPC buffer queue overflow */ #define RC_TMR 0x04 /* inter-character timer expired */
#define RC_UAO 0x10 /* uart overrun */ #define RC_BQO 0x08 /* PPC buffer queue overflow */
#define RC_PAR 0x20 /* parity error */ #define RC_UAO 0x10 /* uart overrun */
#define RC_FRA 0x40 /* framing error */ #define RC_PAR 0x20 /* parity error */
#define RC_BRK 0x80 /* break received */ #define RC_FRA 0x40 /* framing error */
#define RC_BRK 0x80 /* break received */
/*
* The following codes are included on the DISC (disconnect) command. /*
* They are "or"ed into the app_data.bt[1] application field in a * The following codes are included on the DISC (disconnect) command.
* request. These codes are NOT mutually exclusive and can be used in * They are "or"ed into the app_data.bt[1] application field in a
* any combination. * request. These codes are NOT mutually exclusive and can be used in
*/ * any combination.
*/
#define GR_DTR 0x01
#define GR_CREAD 0x02 #define GR_DTR 0x01
#define GR_CREAD 0x02
/*
* Sub-field values for the PPC_XMIT and PPC_OPTIONS completion /*
* entries; these appear in app_data.bt[0] in the application fields. * Sub-field values for the PPC_XMIT and PPC_OPTIONS completion
* These are NOT mutually exclusive and may appear in combination. * entries; these appear in app_data.bt[0] in the application fields.
* The prefix GC indicates that this is a code for use in "general" * These are NOT mutually exclusive and may appear in combination.
* completion entries only. * The prefix GC indicates that this is a code for use in "general"
*/ * completion entries only.
*/
#define GC_DSR 0x01 /* disruption of service */
#define GC_FLU 0x02 /* buffer flushed */ #define GC_DSR 0x01 /* disruption of service */
#define GC_FLU 0x02 /* buffer flushed */
/*
* Sub-field values for the PPC_ASYNC completion entry; these appear /*
* in app_data.bt[0] in the PPC_ASYNC application field. These are * Sub-field values for the PPC_ASYNC completion entry; these appear
* mutually exclusive and cannot be combined. The prefix AC indicates * in app_data.bt[0] in the PPC_ASYNC application field. These are
* that this is a code for use in "asynchronous" completion entries * mutually exclusive and cannot be combined. The prefix AC indicates
* only. * that this is a code for use in "asynchronous" completion entries
*/ * only.
*/
#define AC_CON 0x01 /* connection detected */
#define AC_DIS 0x02 /* disconnection detected */ #define AC_CON 0x01 /* connection detected */
#define AC_BRK 0x03 /* asynchronous "break" */ #define AC_DIS 0x02 /* disconnection detected */
#define AC_FLU 0x04 /* xmit flush complete */ #define AC_BRK 0x03 /* asynchronous "break" */
#define AC_FLU 0x04 /* xmit flush complete */
/* Line Discipline flags (input and output) */
/* Line Discipline flags (input and output) */
#define IGNBRK 0x0001
#define BRKINT 0x0002 #define IGNBRK 0x0001
#define IGNPAR 0x0004 #define BRKINT 0x0002
#define PARMRK 0x0008 #define IGNPAR 0x0004
#define INPCK 0x0010 #define PARMRK 0x0008
#define ISTRIP 0x0020 #define INPCK 0x0010
#define INLCR 0x0040 #define ISTRIP 0x0020
#define IGNCR 0x0080 #define INLCR 0x0040
#define ICRNL 0x0100 #define IGNCR 0x0080
#define IUCLC 0x0200 #define ICRNL 0x0100
#define IXON 0x0400 #define IUCLC 0x0200
#define IXANY 0x0800 #define IXON 0x0400
#define IXANY 0x0800
#define OPOST 0x0001
#define OLCUC 0x0002 #define OPOST 0x0001
#define ONLCR 0x0004 #define OLCUC 0x0002
#define OCRNL 0x0008 #define ONLCR 0x0004
#define ONOCR 0x0010 #define OCRNL 0x0008
#define ONLRET 0x0020 #define ONOCR 0x0010
#define OFILL 0x0040 #define ONLRET 0x0020
#define OFDEL 0x0080 #define OFILL 0x0040
#define ONLDLY 0x0100 #define OFDEL 0x0080
#define OCRDLY 0x0600 #define ONLDLY 0x0100
#define OTABDLY 0x1800 #define OCRDLY 0x0600
#define OBSDLY 0x2000 #define OTABDLY 0x1800
#define OVTDLY 0x4000 #define OBSDLY 0x2000
#define OFFDLY 0x8000 #define OVTDLY 0x4000
#define OFFDLY 0x8000
/* Opcodes for PORTS card */
/* Opcodes for PORTS card */
#define PPC_OPTIONS 32 /* GEN, COMP queues: set PPC options */
#define PPC_XMIT 33 /* GEN, COMP queues: transmit a buffer */ #define PPC_OPTIONS 32 /* GEN, COMP queues: set PPC options */
#define PPC_CONN 34 /* GEN, COMP queues: connect a device */ #define PPC_XMIT 33 /* GEN, COMP queues: transmit a buffer */
#define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */ #define PPC_CONN 34 /* GEN, COMP queues: connect a device */
#define PPC_BRK 36 /* GEN, COMP queues: ioctl break */ #define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */
#define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */ #define PPC_BRK 36 /* GEN, COMP queues: ioctl break */
#define PPC_CLR 41 /* EXP, ECOMP entries: board clear */ #define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */
#define PPC_RECV 50 /* RECV, COMP queues: receive request */ #define PPC_CLR 41 /* EXP, ECOMP entries: board clear */
#define PPC_ASYNC 60 /* Asynchronous request */ #define PPC_RECV 50 /* RECV, COMP queues: receive request */
#define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */ #define PPC_ASYNC 60 /* Asynchronous request */
#define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */ #define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */
#define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */ #define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */
#define CFW_WRITE 73 /* GEN, COMP queues: write */ #define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */
#define PPC_VERS 80 /* EXP, COMP queues: Version */ #define CFW_WRITE 73 /* GEN, COMP queues: write */
#define PPC_VERS 80 /* EXP, COMP queues: Version */
typedef struct {
uint32 tx_addr; /* Address to next read from */ typedef struct {
uint32 tx_req_addr; /* Original request address */ uint32 tx_addr; /* Address to next read from */
uint32 tx_chars; /* Number of chars left to transfer */ uint32 tx_req_addr; /* Original request address */
uint32 tx_req_chars; /* Original number of chars */ uint32 tx_chars; /* Number of chars left to transfer */
uint8 rlp; /* Last known load pointer */ uint32 tx_req_chars; /* Original number of chars */
uint16 iflag; /* Line Discipline: Input flags */ uint8 rlp; /* Last known load pointer */
uint16 oflag; /* Line Discipline: Output flags */ uint16 iflag; /* Line Discipline: Input flags */
t_bool crlf; /* Indicates we are in a CRLF output transform */ uint16 oflag; /* Line Discipline: Output flags */
t_bool conn; /* TRUE if connected, FALSE otherwise */ t_bool crlf; /* Indicates we are in a CRLF output transform */
} PORTS_LINE_STATE; t_bool conn; /* TRUE if connected, FALSE otherwise */
} PORTS_LINE_STATE;
typedef struct {
uint16 line; /* line discipline */ typedef struct {
uint16 pad1; uint16 line; /* line discipline */
uint16 iflag; /* input options word */ uint16 pad1;
uint16 oflag; /* output options word */ uint16 iflag; /* input options word */
uint16 cflag; /* hardware options */ uint16 oflag; /* output options word */
uint16 lflag; /* line discipline options */ uint16 cflag; /* hardware options */
uint8 cerase; /* "erase" character */ uint16 lflag; /* line discipline options */
uint8 ckill; /* "kill" character */ uint8 cerase; /* "erase" character */
uint8 cinter; /* "interrupt" character */ uint8 ckill; /* "kill" character */
uint8 cquit; /* "quit" character */ uint8 cinter; /* "interrupt" character */
uint8 ceof; /* "end of file" character */ uint8 cquit; /* "quit" character */
uint8 ceol; /* "end of line" character */ uint8 ceof; /* "end of file" character */
uint8 itime; /* inter character timer multiplier */ uint8 ceol; /* "end of line" character */
uint8 vtime; /* user-specified inter char timer */ uint8 itime; /* inter character timer multiplier */
uint8 vcount; /* user-specified maximum buffer char count */ uint8 vtime; /* user-specified inter char timer */
uint8 pad2; uint8 vcount; /* user-specified maximum buffer char count */
uint16 pad3; uint8 pad2;
} PORTS_OPTIONS; uint16 pad3;
} PORTS_OPTIONS;
t_stat ports_reset(DEVICE *dptr);
t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat ports_reset(DEVICE *dptr);
t_stat ports_show_cqueue(FILE *st, UNIT *uptr, int32 val, CONST void *desc); t_stat ports_setnl(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat ports_show_rqueue(FILE *st, UNIT *uptr, int32 val, CONST 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 cid); void ports_express(uint8 slot);
void ports_express(uint8 cid); void ports_full(uint8 slot);
void ports_full(uint8 cid);
#endif /* _3B2_PORTS_H_ */
#endif /* _3B2_PORTS_H_ */

View file

@ -1,186 +1,182 @@
/* 3b2_rev2_csr.c: AT&T 3B2 Rev 2 Control and Status Register /* 3b2_rev2_csr.c: ED System Board Control and Status Register
Copyright (c) 2017, 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"
uint16 csr_data;
CSR_DATA csr_data;
BITFIELD csr_bits[] = {
BIT(IOF), BITFIELD csr_bits[] = {
BIT(DMA), BIT(IOF),
BIT(DISK), BIT(DMA),
BIT(UART), BIT(DISK),
BIT(PIR9), BIT(UART),
BIT(PIR8), BIT(PIR9),
BIT(CLK), BIT(PIR8),
BIT(IFLT), BIT(CLK),
BIT(ITIM), BIT(IFLT),
BIT(FLOP), BIT(ITIM),
BIT(NA), BIT(FLOP),
BIT(LED), BIT(NA),
BIT(ALGN), BIT(LED),
BIT(RRST), BIT(ALGN),
BIT(PARE), BIT(RRST),
BIT(TIMO), BIT(PARE),
ENDBITS BIT(TIMO),
}; ENDBITS
};
UNIT csr_unit = {
UDATA(NULL, UNIT_FIX, CSRSIZE) UNIT csr_unit = {
}; UDATA(NULL, UNIT_FIX, CSRSIZE)
};
REG csr_reg[] = {
{ HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) }, REG csr_reg[] = {
{ NULL } { HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) },
}; { NULL }
};
DEVICE csr_dev = {
"CSR", &csr_unit, csr_reg, NULL, DEVICE csr_dev = {
1, 16, 8, 4, 16, 32, "CSR", &csr_unit, csr_reg, NULL,
&csr_ex, &csr_dep, &csr_reset, 1, 16, 8, 4, 16, 32,
NULL, NULL, NULL, NULL, &csr_ex, &csr_dep, &csr_reset,
DEV_DEBUG, 0, sys_deb_tab NULL, NULL, NULL, NULL,
}; 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; {
return SCPE_OK; csr_data = 0;
} 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,
"[%08x] CSR=%04x\n", sim_debug(READ_MSG, &csr_dev,
R[NUM_PC], csr_data); "CSR=%04x\n",
csr_data);
switch (reg) {
case 0x2: switch (reg) {
if (size == 8) { case 0x2:
return (csr_data >> 8) & 0xff; if (size == 8) {
} else { return (csr_data >> 8) & 0xff;
return csr_data; } else {
} return csr_data;
case 0x3: }
return csr_data & 0xff; case 0x3:
default: return csr_data & 0xff;
return 0; default:
} 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) {
case 0x03: /* Clear Bus Timeout Error */ switch (reg) {
csr_data &= ~CSRTIMO; case 0x03: /* Clear Bus Timeout Error */
break; csr_data &= ~CSRTIMO;
case 0x07: /* Clear Memory Parity Error */ break;
csr_data &= ~CSRPARE; case 0x07: /* Clear Memory Parity Error */
break; csr_data &= ~CSRPARE;
case 0x0b: /* Set System Reset Request */ break;
full_reset(); case 0x0b: /* Set System Reset Request */
cpu_boot(0, &cpu_dev); full_reset();
break; cpu_boot(0, &cpu_dev);
case 0x0f: /* Clear Memory Alignment Fault */ break;
csr_data &= ~CSRALGN; case 0x0f: /* Clear Memory Alignment Fault */
break; csr_data &= ~CSRALGN;
case 0x13: /* Set Failure LED */ break;
csr_data |= CSRLED; case 0x13: /* Set Failure LED */
break; csr_data |= CSRLED;
case 0x17: /* Clear Failure LED */ break;
csr_data &= ~CSRLED; case 0x17: /* Clear Failure LED */
break; csr_data &= ~CSRLED;
case 0x1b: /* Set Floppy Motor On */ break;
csr_data |= CSRFLOP; case 0x1b: /* Set Floppy Motor On */
break; csr_data |= CSRFLOP;
case 0x1f: /* Clear Floppy Motor On */ break;
csr_data &= ~CSRFLOP; case 0x1f: /* Clear Floppy Motor On */
break; csr_data &= ~CSRFLOP;
case 0x23: /* Set Inhibit Timers */ break;
sim_debug(WRITE_MSG, &csr_dev, case 0x23: /* Set Inhibit Timers */
"[%08x] SET INHIBIT TIMERS\n", R[NUM_PC]); sim_debug(WRITE_MSG, &csr_dev,
csr_data |= CSRITIM; "SET INHIBIT TIMERS\n");
break; csr_data |= CSRITIM;
case 0x27: /* Clear Inhibit Timers */ timer_gate(TIMER_INTERVAL, TRUE);
sim_debug(WRITE_MSG, &csr_dev, break;
"[%08x] CLEAR INHIBIT TIMERS\n", R[NUM_PC]); case 0x27: /* Clear Inhibit Timers */
sim_debug(WRITE_MSG, &csr_dev,
/* A side effect of clearing the timer inhibit bit is to cause "CLEAR INHIBIT TIMERS\n");
* a simulated "tick" of any active timers. This is a hack to csr_data &= ~CSRITIM;
* make diagnostics pass. This is not 100% accurate, but it timer_gate(TIMER_INTERVAL, FALSE);
* makes SVR3 and DGMON tests happy. break;
*/ case 0x2b: /* Set Inhibit Faults */
timer_tick(); csr_data |= CSRIFLT;
csr_data &= ~CSRITIM; break;
break; case 0x2f: /* Clear Inhibit Faults */
case 0x2b: /* Set Inhibit Faults */ csr_data &= ~CSRIFLT;
csr_data |= CSRIFLT; break;
break; case 0x33: /* Set PIR9 */
case 0x2f: /* Clear Inhibit Faults */ csr_data |= CSRPIR9;
csr_data &= ~CSRIFLT; CPU_SET_INT(INT_PIR9);
break; break;
case 0x33: /* Set PIR9 */ case 0x37: /* Clear PIR9 */
csr_data |= CSRPIR9; csr_data &= ~CSRPIR9;
CPU_SET_INT(INT_PIR9); CPU_CLR_INT(INT_PIR9);
break; break;
case 0x37: /* Clear PIR9 */ case 0x3b: /* Set PIR8 */
csr_data &= ~CSRPIR9; csr_data |= CSRPIR8;
CPU_CLR_INT(INT_PIR9); CPU_SET_INT(INT_PIR8);
break; break;
case 0x3b: /* Set PIR8 */ case 0x3f: /* Clear PIR8 */
csr_data |= CSRPIR8; csr_data &= ~CSRPIR8;
CPU_SET_INT(INT_PIR8); CPU_CLR_INT(INT_PIR8);
break; break;
case 0x3f: /* Clear PIR8 */ default:
csr_data &= ~CSRPIR8; break;
CPU_CLR_INT(INT_PIR8); }
break; }
default:
break;
}
}

View file

@ -1,46 +1,46 @@
/* 3b2_rev2_csr.h: AT&T 3B2 Rev 2 Control and Status Register /* 3b2_rev2_csr.h: ED System Board Control and Status Register
Copyright (c) 2021, 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"
/* CSR */ typedef uint16 CSR_DATA;
t_stat csr_svc(UNIT *uptr);
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); /* CSR */
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw); t_stat csr_svc(UNIT *uptr);
t_stat csr_reset(DEVICE *dptr); t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
uint32 csr_read(uint32 pa, size_t size); t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw);
void csr_write(uint32 pa, uint32 val, size_t size); t_stat csr_reset(DEVICE *dptr);
uint32 csr_read(uint32 pa, size_t size);
extern uint16 csr_data; 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: AT&T 3B2 Rev 2 (Model 400) Simulator Definitions /* 3b2_rev2_defs.h: Version 2 (3B2/400) Common Definitions
Copyright (c) 2017, 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 0x04 /* 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_ */

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,383 +1,358 @@
/* 3b2_rev2_mmu.c: AT&T 3B2 Rev 2 (Model 400) MMU (WE32101) Header /* 3b2_rev2_mmu.c: WE32101 MMU
Copyright (c) 2017, 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);
/* Physical memory read/write */ /* Virtual memory translation */
uint8 pread_b(uint32 pa); uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
uint16 pread_h(uint32 pa); t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
uint32 pread_w(uint32 pa); t_bool fc, uint32 *pa);
uint32 pread_w_u(uint32 pa);
void pwrite_b(uint32 pa, uint8 val); #define SHOULD_CACHE_PD(pd) \
void pwrite_h(uint32 pa, uint16 val); (fc && PD_PRESENT(pd))
void pwrite_w(uint32 pa, uint32 val);
#define SHOULD_CACHE_SD(sd) \
/* TODO: REMOVE AFTER DEBUGGING */ (fc && SD_VALID(sd) && SD_PRESENT(sd))
uint32 safe_read_w(uint32 va);
#define SHOULD_UPDATE_SD_R_BIT(sd) \
/* Virtual memory translation */ (MMU_CONF_R && !((sd) & SD_R_MASK))
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, #define SHOULD_UPDATE_SD_M_BIT(sd) \
t_bool fc, uint32 *pa); (MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK))
#define SHOULD_CACHE_PD(pd) \ #define SHOULD_UPDATE_PD_R_BIT(pd) \
(fc && PD_PRESENT(pd)) (!((pd) & PD_R_MASK))
#define SHOULD_CACHE_SD(sd) \ #define SHOULD_UPDATE_PD_M_BIT(pd) \
(fc && SD_VALID(sd) && SD_PRESENT(sd)) (r_acc == ACC_W && !((pd) & PD_M_MASK))
#define SHOULD_UPDATE_SD_R_BIT(sd) \ t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
(MMU_CONF_R && !((sd) & SD_R_MASK)) void mmu_enable();
void mmu_disable();
#define SHOULD_UPDATE_SD_M_BIT(sd) \
(MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK)) extern MMU_STATE mmu_state;
#define SHOULD_UPDATE_PD_R_BIT(pd) \ #endif /* _3B2_REV2_MMU_H_ */
(!((pd) & PD_R_MASK))
#define SHOULD_UPDATE_PD_M_BIT(pd) \
(r_acc == ACC_W && !((pd) & PD_M_MASK))
/* Dispatch to the MMU when enabled, or to physical RW when
disabled */
uint8 read_b(uint32 va, uint8 r_acc);
uint16 read_h(uint32 va, uint8 r_acc);
uint32 read_w(uint32 va, uint8 r_acc);
void write_b(uint32 va, uint8 val);
void write_h(uint32 va, uint16 val);
void write_w(uint32 va, uint32 val);
t_bool addr_is_rom(uint32 pa);
t_bool addr_is_mem(uint32 pa);
t_bool addr_is_io(uint32 pa);
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
void mmu_enable();
void mmu_disable();
extern MMU_STATE mmu_state;
#endif /* _3B2_REV2_MMU_H_ */

View file

@ -1,82 +1,82 @@
/* 3b2_rev2_sys.c: AT&T 3B2 Rev 2 (Model 400) system definition /* 3b2_rev2_sys.c: Version 2 (3B2/400) System Definition
Copyright (c) 2017, 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,401 +0,0 @@
/* 3b2_rev2_timer.c: 8253 Interval Timer
Copyright (c) 2017, Seth J. Morabito
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Except as contained in this notice, the name of the author shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the author.
*/
/*
* 8253 Timer.
*
* The 8253 Timer IC has three interval timers, which we treat here as
* three units.
*
* Note that this simulation is very specific to the 3B2, and not
* usable as a general purpose 8253 simulator.
*
*/
#include "3b2_cpu.h"
#include "3b2_csr.h"
#include "3b2_defs.h"
#include "3b2_timer.h"
#define SET_INT do { \
CPU_SET_INT(INT_CLOCK); \
SET_CSR(CSRCLK); \
} while (0)
#define CLR_INT do { \
CPU_CLR_INT(INT_CLOCK); \
CLR_CSR(CSRCLK); \
} while (0)
struct timer_ctr TIMERS[3];
int32 tmxr_poll = 16667;
/*
* The three timers, (A, B, C) run at different
* programmatially controlled frequencies, so each must be
* handled through a different service routine.
*/
UNIT timer_unit[] = {
{ UDATA(&timer0_svc, 0, 0) },
{ UDATA(&timer1_svc, UNIT_IDLE, 0) },
{ UDATA(&timer2_svc, 0, 0) },
{ NULL }
};
UNIT *timer_clk_unit = &timer_unit[1];
REG timer_reg[] = {
{ HRDATAD(DIVA, TIMERS[0].divider, 16, "Divider A") },
{ HRDATAD(STA, TIMERS[0].mode, 8, "Mode A") },
{ HRDATAD(DIVB, TIMERS[1].divider, 16, "Divider B") },
{ HRDATAD(STB, TIMERS[1].mode, 8, "Mode B") },
{ HRDATAD(DIVC, TIMERS[2].divider, 16, "Divider C") },
{ HRDATAD(STC, TIMERS[2].mode, 8, "Mode C") },
{ NULL }
};
MTAB timer_mod[] = {
{ MTAB_XTD|MTAB_VDV|MTAB_VALR|MTAB_NC, 0, NULL, "SHUTDOWN",
&timer_set_shutdown, NULL, NULL, "Soft Power Shutdown" },
{ 0 }
};
DEVICE timer_dev = {
"TIMER", timer_unit, timer_reg, timer_mod,
1, 16, 8, 4, 16, 32,
NULL, NULL, &timer_reset,
NULL, NULL, NULL, NULL,
DEV_DEBUG, 0, sys_deb_tab
};
t_stat timer_reset(DEVICE *dptr) {
int32 i, t;
memset(&TIMERS, 0, sizeof(struct timer_ctr) * 3);
for (i = 0; i < 3; i++) {
timer_unit[i].tmrnum = i;
timer_unit[i].tmr = (void *)&TIMERS[i];
}
/* Timer 1 gate is always active */
TIMERS[1].gate = 1;
if (!sim_is_running) {
t = sim_rtcn_init_unit(timer_clk_unit, TPS_CLK, TMR_CLK);
sim_activate_after(timer_clk_unit, 1000000 / t);
}
return SCPE_OK;
}
static void timer_activate(uint8 ctrnum)
{
struct timer_ctr *ctr;
ctr = &TIMERS[ctrnum];
switch (ctrnum) {
case TIMER_SANITY:
break;
case TIMER_INTERVAL:
if ((csr_data & CSRITIM) == 0) {
sim_debug(EXECUTE_MSG, &timer_dev,
"[%08x] INTERVAL TIMER: Activating after %d ms\n",
R[NUM_PC], ctr->val);
sim_activate_after_abs(&timer_unit[ctrnum], ctr->val);
ctr->val--;
} else {
sim_debug(EXECUTE_MSG, &timer_dev,
"[%08x] INTERVAL TIMER: Currently disabled, not starting\n",
R[NUM_PC]);
}
break;
case TIMER_BUS:
break;
default:
break;
}
}
t_stat timer_set_shutdown(UNIT *uptr, int32 val, CONST char* cptr, void* desc)
{
struct timer_ctr *sanity = (struct timer_ctr *)timer_unit[0].tmr;
sim_debug(EXECUTE_MSG, &timer_dev,
"[%08x] Setting sanity timer to 0 for shutdown.\n", R[NUM_PC]);
sanity->val = 0;
CLR_INT;
CPU_SET_INT(INT_SERR);
CSRBIT(CSRTIMO, TRUE);
return SCPE_OK;
}
void timer_enable(uint8 ctrnum) {
timer_activate(ctrnum);
}
void timer_disable(uint8 ctrnum)
{
sim_debug(EXECUTE_MSG, &timer_dev,
"[%08x] Disabling timer %d\n",
R[NUM_PC], ctrnum);
sim_cancel(&timer_unit[ctrnum]);
}
/*
* Sanity Timer
*/
t_stat timer0_svc(UNIT *uptr)
{
struct timer_ctr *ctr;
int32 time;
ctr = (struct timer_ctr *)uptr->tmr;
time = ctr->divider * TIMER_STP_US;
if (time == 0) {
time = TIMER_STP_US;
}
sim_activate_after_abs(uptr, time);
return SCPE_OK;
}
/*
* Interval Timer
*/
t_stat timer1_svc(UNIT *uptr)
{
struct timer_ctr *ctr;
int32 t;
ctr = (struct timer_ctr *)uptr->tmr;
if (ctr->enabled && !(csr_data & CSRITIM)) {
/* Fire the IPL 15 clock interrupt */
SET_INT;
}
t = sim_rtcn_calb(TPS_CLK, TMR_CLK);
sim_activate_after_abs(uptr, 1000000/TPS_CLK);
tmxr_poll = t;
return SCPE_OK;
}
/*
* Bus Timeout Timer
*/
t_stat timer2_svc(UNIT *uptr)
{
struct timer_ctr *ctr;
int32 time;
ctr = (struct timer_ctr *)uptr->tmr;
time = ctr->divider * TIMER_STP_US;
if (time == 0) {
time = TIMER_STP_US;
}
sim_activate_after_abs(uptr, time);
return SCPE_OK;
}
uint32 timer_read(uint32 pa, size_t size)
{
uint32 reg;
uint16 ctr_val;
uint8 ctrnum;
struct timer_ctr *ctr;
reg = pa - TIMERBASE;
ctrnum = (reg >> 2) & 0x3;
ctr = &TIMERS[ctrnum];
switch (reg) {
case TIMER_REG_DIVA:
case TIMER_REG_DIVB:
case TIMER_REG_DIVC:
ctr_val = ctr->val;
if (ctr_val != ctr->divider) {
sim_debug(READ_MSG, &timer_dev,
"[%08x] >>> ctr_val = %04x, ctr->divider = %04x\n",
R[NUM_PC], ctr_val, ctr->divider);
}
switch (ctr->mode & CLK_RW) {
case CLK_LSB:
return ctr_val & 0xff;
case CLK_MSB:
return (ctr_val & 0xff00) >> 8;
case CLK_LMB:
if (ctr->lmb) {
ctr->lmb = FALSE;
return (ctr_val & 0xff00) >> 8;
} else {
ctr->lmb = TRUE;
return ctr_val & 0xff;
}
default:
return 0;
}
break;
case TIMER_REG_CTRL:
return ctr->mode;
case TIMER_CLR_LATCH:
/* Clearing the timer latch has a side-effect
of also clearing pending interrupts */
CLR_INT;
return 0;
default:
/* Unhandled */
sim_debug(READ_MSG, &timer_dev,
"[%08x] UNHANDLED TIMER READ. ADDR=%08x\n",
R[NUM_PC], pa);
return 0;
}
}
void handle_timer_write(uint8 ctrnum, uint32 val)
{
struct timer_ctr *ctr;
ctr = &TIMERS[ctrnum];
switch(ctr->mode & 0x30) {
case 0x10:
ctr->divider &= 0xff00;
ctr->divider |= val & 0xff;
ctr->val = ctr->divider;
ctr->enabled = TRUE;
ctr->stime = sim_gtime();
sim_cancel(timer_clk_unit);
sim_activate_after_abs(timer_clk_unit, ctr->divider * TIMER_STP_US);
break;
case 0x20:
ctr->divider &= 0x00ff;
ctr->divider |= (val & 0xff) << 8;
ctr->val = ctr->divider;
ctr->enabled = TRUE;
ctr->stime = sim_gtime();
/* Kick the timer to get the new divider value */
sim_cancel(timer_clk_unit);
sim_activate_after_abs(timer_clk_unit, ctr->divider * TIMER_STP_US);
break;
case 0x30:
if (ctr->lmb) {
ctr->lmb = FALSE;
ctr->divider = (uint16) ((ctr->divider & 0x00ff) | ((val & 0xff) << 8));
ctr->val = ctr->divider;
ctr->enabled = TRUE;
ctr->stime = sim_gtime();
sim_debug(READ_MSG, &timer_dev,
"[%08x] Write timer %d val LMB (MSB): %02x\n",
R[NUM_PC], ctrnum, val & 0xff);
/* Kick the timer to get the new divider value */
sim_cancel(timer_clk_unit);
sim_activate_after_abs(timer_clk_unit, ctr->divider * TIMER_STP_US);
} else {
ctr->lmb = TRUE;
ctr->divider = (ctr->divider & 0xff00) | (val & 0xff);
ctr->val = ctr->divider;
}
break;
default:
break;
}
}
void timer_write(uint32 pa, uint32 val, size_t size)
{
uint8 reg, ctrnum;
struct timer_ctr *ctr;
reg = (uint8) (pa - TIMERBASE);
switch(reg) {
case TIMER_REG_DIVA:
handle_timer_write(0, val);
break;
case TIMER_REG_DIVB:
handle_timer_write(1, val);
break;
case TIMER_REG_DIVC:
handle_timer_write(2, val);
break;
case TIMER_REG_CTRL:
/* The counter number is in bits 6 and 7 */
ctrnum = (val >> 6) & 3;
if (ctrnum > 2) {
sim_debug(WRITE_MSG, &timer_dev,
"[%08x] WARNING: Write to invalid counter: %d\n",
R[NUM_PC], ctrnum);
return;
}
ctr = &TIMERS[ctrnum];
ctr->mode = (uint8) val;
ctr->enabled = FALSE;
ctr->lmb = FALSE;
break;
case TIMER_CLR_LATCH:
sim_debug(WRITE_MSG, &timer_dev,
"[%08x] unexpected write to clear timer latch\n",
R[NUM_PC]);
break;
}
}
void timer_tick()
{
if (TIMERS[0].gate && TIMERS[0].enabled) {
TIMERS[0].val = TIMERS[0].divider - 1;
}
if (TIMERS[1].gate && TIMERS[1].enabled) {
TIMERS[1].val = TIMERS[1].divider - 1;
}
if (TIMERS[2].gate && TIMERS[2].enabled) {
TIMERS[2].val = TIMERS[2].divider - 1;
}
}

View file

@ -1,72 +0,0 @@
/* 3b2_rev2_timer.h: 8253 Interval Timer
Copyright (c) 2017, Seth J. Morabito
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Except as contained in this notice, the name of the author shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the author.
*/
#ifndef _3B2_REV2_TIMER_H_
#define _3B2_REV2_TIMER_H_
#include "sim_defs.h"
#define TIMER_STP_US 1
#define tmrnum u3
#define tmr up7
#define TIMER_REG_DIVA 0x03
#define TIMER_REG_DIVB 0x07
#define TIMER_REG_DIVC 0x0b
#define TIMER_REG_CTRL 0x0f
#define TIMER_CLR_LATCH 0x13
#define CLK_RW 0x30
#define CLK_LSB 0x10
#define CLK_MSB 0x20
#define CLK_LMB 0x30
struct timer_ctr {
uint16 divider;
uint16 val;
uint8 mode;
t_bool lmb;
t_bool enabled;
t_bool gate;
double stime; /* Most recent start time of counter */
};
t_stat timer_reset(DEVICE *dptr);
uint32 timer_read(uint32 pa, size_t size);
void timer_write(uint32 pa, uint32 val, size_t size);
void timer_tick();
t_stat timer0_svc(UNIT *uptr);
t_stat timer1_svc(UNIT *uptr);
t_stat timer2_svc(UNIT *uptr);
t_stat timer_set_shutdown(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
void timer_disable(uint8 ctrnum);
void timer_enable(uint8 ctrnum);
#endif /* _3B2_REV2_TIMER_H_ */

View file

@ -1,299 +1,293 @@
/* 3b2_rev3_csr.c: AT&T 3B2/600G Control and Status Register /* 3b2_rev3_csr.c: CM518B System Board Control, Status & Error Register
Copyright (c) 2020, 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"
uint32 csr_data;
CSR_DATA csr_data;
BITFIELD csr_bits[] = {
BIT(UTIM), BITFIELD csr_bits[] = {
BIT(PWDN), BIT(UTIM),
BIT(OI15), BIT(PWDN),
BIT(IUINT), BIT(OI15),
BIT(IUDMA), BIT(IUINT),
BIT(PIR9), BIT(IUDMA),
BIT(PIR8), BIT(PIR9),
BIT(IUTIM), BIT(PIR8),
BIT(IUTIM),
BIT(ISTY),
BIT(IUBUS), BIT(ISTY),
BIT(IFLT), BIT(IUBUS),
BIT(ISBER), BIT(IFLT),
BIT(IBUS), BIT(ISBER),
BIT(IBUB), BIT(IBUS),
BIT(FECC), BIT(IBUB),
BIT(THERM), BIT(FECC),
BIT(THERM),
BIT(FLED),
BIT(PSPWR), BIT(FLED),
BIT(FLSPD), BIT(PSPWR),
BIT(FLSD1), BIT(FLSPD),
BIT(FLMOT), BIT(FLSD1),
BIT(FLDEN), BIT(FLMOT),
BIT(FLSZ), BIT(FLDEN),
BIT(SBER), BIT(FLSZ),
BIT(SBER),
BIT(MBER),
BIT(UBFL), BIT(MBER),
BIT(TIMO), BIT(UBFL),
BIT(FLTFR), BIT(TIMO),
BIT(DALGN), BIT(FLTFR),
BIT(STTIM), BIT(DALGN),
BIT(ABRT), BIT(STTIM),
BIT(RSTR), BIT(ABRT),
BIT(RSTR),
ENDBITS
}; ENDBITS
};
UNIT csr_unit = {
UDATA(NULL, UNIT_FIX, CSRSIZE) UNIT csr_unit = {
}; UDATA(NULL, UNIT_FIX, CSRSIZE)
};
REG csr_reg[] = {
{ HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) }, REG csr_reg[] = {
{ NULL } { HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) },
}; { NULL }
};
DEVICE csr_dev = {
"CSR", &csr_unit, csr_reg, NULL, DEVICE csr_dev = {
1, 16, 8, 4, 16, 32, "CSR", &csr_unit, csr_reg, NULL,
&csr_ex, &csr_dep, &csr_reset, 1, 16, 8, 4, 16, 32,
NULL, NULL, NULL, NULL, &csr_ex, &csr_dep, &csr_reset,
DEV_DEBUG, 0, sys_deb_tab NULL, NULL, NULL, NULL,
}; 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)
/* Accordig to the technical reference manual, the CSR is NOT {
cleared on reset */ CSRBIT(CSRFECC, TRUE);
return SCPE_OK; CSRBIT(CSRTHERM, FALSE);
} CSRBIT(CSRITIM, TRUE);
CSRBIT(CSRISTIM, TRUE);
uint32 csr_read(uint32 pa, size_t size) CSRBIT(CSRIBUB, TRUE);
{ CSRBIT(CSRPWRSPDN, FALSE);
uint32 reg = (pa - CSRBASE) & 0xff; CSRBIT(CSRFLPMO, TRUE);
switch (reg & 0xf0) { return SCPE_OK;
case 0x00: }
return csr_data & 0xff;
case 0x20: uint32 csr_read(uint32 pa, size_t size)
return (csr_data >> 8) & 0xff; {
case 0x40: uint32 reg = (pa - CSRBASE) & 0xff;
return (csr_data >> 16) & 0xff;
case 0x60: switch (reg & 0xf0) {
return (csr_data >> 24) & 0xff; case 0x00:
default: return csr_data & 0xff;
sim_debug(WRITE_MSG, &csr_dev, case 0x20:
"[%08x] CSR READ. Warning, unexpected register = %02x)\n", return (csr_data >> 8) & 0xff;
R[NUM_PC], reg); case 0x40:
return 0; return (csr_data >> 16) & 0xff;
} case 0x60:
} return (csr_data >> 24) & 0xff;
default:
#define SET_INT(flag, val) { \ sim_debug(WRITE_MSG, &csr_dev,
if (val) { \ "CSR READ. Warning, unexpected register = %02x)\n",
CPU_SET_INT(flag); \ reg);
} else { \ return 0;
CPU_CLR_INT(flag); \ }
} \ }
}
#define SET_INT(flag, val) { \
void csr_write(uint32 pa, uint32 val, size_t size) if (val) { \
{ CPU_SET_INT(flag); \
uint32 reg = pa - CSRBASE; } else { \
CPU_CLR_INT(flag); \
switch (reg) { } \
}
case 0x00:
CSRBIT(CSRCLK, val); void csr_write(uint32 pa, uint32 val, size_t size)
SET_INT(INT_CLOCK, val); {
break; uint32 reg = pa - CSRBASE;
case 0x04:
CSRBIT(CSRPWRDN, val); switch (reg) {
SET_INT(INT_PWRDWN, val);
break; case 0x00:
case 0x08: CSRBIT(CSRCLK, val);
CSRBIT(CSROPINT15, val); SET_INT(INT_CLOCK, val);
SET_INT(INT_BUS_OP, val); break;
break; case 0x04:
case 0x0c: CSRBIT(CSRPWRDN, val);
CSRBIT(CSRUART, val); SET_INT(INT_PWRDWN, val);
SET_INT(INT_UART, val); break;
break; case 0x08:
case 0x10: CSRBIT(CSROPINT15, val);
CSRBIT(CSRDMA, val); SET_INT(INT_BUS_OP, val);
SET_INT(INT_UART_DMA, val); break;
break; case 0x0c:
case 0x14: CSRBIT(CSRUART, val);
CSRBIT(CSRPIR9, val); SET_INT(INT_UART, val);
SET_INT(INT_PIR9, val); break;
break; case 0x10:
case 0x18: CSRBIT(CSRDMA, val);
CSRBIT(CSRPIR8, val); SET_INT(INT_UART_DMA, val);
SET_INT(INT_PIR8, val); break;
break; case 0x14:
case 0x1c: CSRBIT(CSRPIR9, val);
CSRBIT(CSRITIM, val); SET_INT(INT_PIR9, val);
sim_debug(WRITE_MSG, &csr_dev, break;
"[%08x] CSR WRITE. Inhibit Interval Timer = %d\n", case 0x18:
R[NUM_PC], val); CSRBIT(CSRPIR8, val);
if (csr_data & CSRITIM) { SET_INT(INT_PIR8, val);
timer_disable(TIMER_INTERVAL); break;
} else { case 0x1c:
timer_enable(TIMER_INTERVAL); CSRBIT(CSRITIM, val);
} timer_gate(TIMER_INTERVAL, CSR(CSRITIM));
break; break;
case 0x20: case 0x20:
CSRBIT(CSRISTIM, val); CSRBIT(CSRISTIM, val);
sim_debug(WRITE_MSG, &csr_dev, timer_gate(TIMER_SANITY, CSR(CSRISTIM));
"[%08x] CSR WRITE. Inhibit Sanity Timer = %d\n", break;
R[NUM_PC], val); case 0x24:
if (csr_data & CSRISTIM) { CSRBIT(CSRITIMO, val);
timer_disable(TIMER_SANITY); timer_gate(TIMER_BUS, CSR(CSRITIMO));
} else { break;
timer_enable(TIMER_SANITY); case 0x28:
} CSRBIT(CSRICPUFLT, val);
break; break;
case 0x24: case 0x2c:
CSRBIT(CSRITIMO, val); CSRBIT(CSRISBERR, val);
sim_debug(WRITE_MSG, &csr_dev, break;
"[%08x] CSR WRITE. Inhibit Bus Timer = %d\n", case 0x30:
R[NUM_PC], val); CSRBIT(CSRIIOBUS, val);
if (csr_data & CSRITIMO) { break;
timer_disable(TIMER_BUS); case 0x34:
} else { CSRBIT(CSRIBUB, val);
timer_enable(TIMER_BUS); break;
} case 0x38:
break; CSRBIT(CSRFECC, val);
case 0x28: sim_debug(WRITE_MSG, &csr_dev,
CSRBIT(CSRICPUFLT, val); "CSR WRITE. Force ECC Syndrome = %d\n",
break; val);
case 0x2c: break;
CSRBIT(CSRISBERR, val); case 0x3c:
break; CSRBIT(CSRTHERM, val);
case 0x30: cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
CSRBIT(CSRIIOBUS, val); break;
break; case 0x40:
case 0x34: CSRBIT(CSRLED, val);
CSRBIT(CSRIBUB, val); break;
break; case 0x44:
case 0x38: CSRBIT(CSRPWRSPDN, val);
CSRBIT(CSRFECC, val); if (!val) {
break; /* Stop the simulator - power down */
case 0x3c: stop_reason = STOP_POWER;
CSRBIT(CSRTHERM, val); }
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ break;
break; case 0x48:
case 0x40: CSRBIT(CSRFLPFST, val);
CSRBIT(CSRLED, val); break;
break; case 0x4c: /* Floppy Side 1: Set when Cleared */
case 0x44: if_state.side = (val & 1) ? 0 : 1;
CSRBIT(CSRPWRSPDN, val); CSRBIT(CSRFLPS1, val & 1);
break; break;
case 0x48: case 0x50:
CSRBIT(CSRFLPFST, val); CSRBIT(CSRFLPMO, val);
break; break;
case 0x4c: /* Floppy Side 1: Set when Cleared */ case 0x54:
if_state.side = (val & 1) ? 0 : 1; CSRBIT(CSRFLPDEN, val);
CSRBIT(CSRFLPS1, val & 1); break;
break; case 0x58:
case 0x50: CSRBIT(CSRFLPSZ, val);
CSRBIT(CSRFLPMO, val); break;
break; case 0x5c:
case 0x54: CSRBIT(CSRSBERR, val);
CSRBIT(CSRFLPDEN, val); if (val) {
break; if (!(csr_data & CSRISBERR)) {
case 0x58: SET_INT(INT_SBERR, TRUE);
CSRBIT(CSRFLPSZ, val); }
break; } else {
case 0x5c: SET_INT(INT_SBERR, FALSE);
CSRBIT(CSRSBERR, val); }
if (val) { break;
if (!(csr_data & CSRISBERR)) { case 0x60:
SET_INT(INT_SBERR, TRUE); CSRBIT(CSRMBERR, val);
} SET_INT(INT_MBERR, val);
} else { break;
SET_INT(INT_SBERR, FALSE); case 0x64:
} CSRBIT(CSRUBUBF, val);
break; SET_INT(INT_BUS_RXF, val);
case 0x60: break;
CSRBIT(CSRMBERR, val); case 0x68:
SET_INT(INT_MBERR, val); CSRBIT(CSRTIMO, val);
break; if (val) {
case 0x64: if (!(csr_data & CSRITIMO)) {
CSRBIT(CSRUBUBF, val); SET_INT(INT_BUS_TMO, TRUE);
SET_INT(INT_BUS_RXF, val); }
break; } else {
case 0x68: SET_INT(INT_BUS_TMO, FALSE);
CSRBIT(CSRTIMO, val); }
if (val) { break;
if (!(csr_data & CSRITIMO)) { case 0x6c:
SET_INT(INT_BUS_TMO, TRUE); CSRBIT(CSRFRF, val);
} break;
} else { case 0x70:
SET_INT(INT_BUS_TMO, FALSE); CSRBIT(CSRALGN, val);
} break;
break; case 0x74:
case 0x6c: CSRBIT(CSRSTIMO, val);
CSRBIT(CSRFRF, val); cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
break; break;
case 0x70: case 0x78:
CSRBIT(CSRALGN, val); CSRBIT(CSRABRT, val);
break; cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
case 0x74: break;
CSRBIT(CSRSTIMO, val); case 0x7c:
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ /* System reset request */
break; full_reset();
case 0x78: cpu_boot(0, &cpu_dev);
CSRBIT(CSRABRT, val); break;
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */ default:
break; /* Do nothing */
case 0x7c: break;
/* System reset request */ }
cpu_boot(0, &cpu_dev); }
break;
default:
/* Do nothing */
break;
}
}

View file

@ -1,45 +1,45 @@
/* 3b2_rev3_csr.h: AT&T 3B2/600G Control and Status Register /* 3b2_rev3_csr.h: CM518B System Board Control, Status & Error Register
Copyright (c) 2020, 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"
t_stat csr_svc(UNIT *uptr); typedef uint32 CSR_DATA;
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_svc(UNIT *uptr);
t_stat csr_reset(DEVICE *dptr); t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
uint32 csr_read(uint32 pa, size_t size); t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw);
void csr_write(uint32 pa, uint32 val, size_t size); t_stat csr_reset(DEVICE *dptr);
uint32 csr_read(uint32 pa, size_t size);
extern uint32 csr_data; void csr_write(uint32 pa, uint32 val, size_t size);
#endif #endif

View file

@ -1,149 +1,141 @@
/* 3b2_rev3_defs.h: AT&T 3B2 Rev 3 (Model 600G) Simulator Definitions /* 3b2_rev3_defs.h: Veresion 3 (3B2/700) Common Definitions
Copyright (c) 2021, 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
/* Memory */ #define IFCSRBASE 0x40000
#define MEMID_4M 6 #define IFCSRSIZE 0x100
#define MEMID_16M 7 #define TIMERBASE 0x41000
#define MADDR_SLOT_0 0x4d000 #define TIMERSIZE 0x20
#define MADDR_SLOT_1 0x4d004 #define NVRBASE 0x42000
#define MADDR_SLOT_2 0x4d008 #define NVRSIZE 0x2000
#define MADDR_SLOT_3 0x4d00c #define CSRBASE 0x44000
#define CSRSIZE 0x100
#define IFCSRBASE 0x40000 #define DMAIFBASE 0x45000
#define IFCSRSIZE 0x100 #define DMAIFSIZE 0x5
#define TIMERBASE 0x41000 #define DMAIUABASE 0x46000
#define TIMERSIZE 0x20 #define DMAIUASIZE 0x5
#define NVRBASE 0x42000 #define DMAIUBBASE 0x47000
#define NVRSIZE 0x2000 #define DMAIUBSIZE 0x5
#define CSRBASE 0x44000 #define DMACBASE 0x48000
#define CSRSIZE 0x100 #define DMACSIZE 0x11
#define DMAIFBASE 0x45000 #define IFBASE 0x4a000
#define DMAIFSIZE 0x5 #define IFSIZE 0x10
#define DMAIUABASE 0x46000 #define TODBASE 0x4e000
#define DMAIUASIZE 0x5 #define TODSIZE 0x40
#define DMAIUBBASE 0x47000 #define MMUBASE 0x4f000
#define DMAIUBSIZE 0x5 #define MMUSIZE 0x1000
#define DMACBASE 0x48000 #define FLTLBASE 0x4c000
#define DMACSIZE 0x11 #define FLTLSIZE 0x1000
#define IFBASE 0x4a000 #define FLTHBASE 0x4d000
#define IFSIZE 0x10 #define FLTHSIZE 0x1000
#define TODBASE 0x4e000
#define TODSIZE 0x40 #define VCACHE_BOTTOM 0x1c00000
#define MMUBASE 0x4f000 #define VCACHE_TOP 0x2000000
#define MMUSIZE 0x1000
#define FLTLBASE 0x4c000 #define BUB_BOTTOM 0x6000000
#define FLTLSIZE 0x10 #define BUB_TOP 0x1a000000
#define FLTHBASE 0x4d000
#define FLTHSIZE 0x10 #define IF_STATUS_REG 0
#define IF_CMD_REG 0
#define VCACHE_BOTTOM 0x1c00000 #define IF_TRACK_REG 1
#define VCACHE_TOP 0x2000000 #define IF_SECTOR_REG 2
#define IF_DATA_REG 3
#define BUB_BOTTOM 0x6000000
#define BUB_TOP 0x1a000000 #define DMA_IF_CHAN 1
#define DMA_IUA_CHAN 2
#define IF_STATUS_REG 0 #define DMA_IUB_CHAN 3
#define IF_CMD_REG 0
#define IF_TRACK_REG 1 #define DMA_IF 0x45
#define IF_SECTOR_REG 2 #define DMA_IUA 0x46
#define IF_DATA_REG 3 #define DMA_IUB 0x47
#define DMA_C 0x48
#define DMA_IF_CHAN 1
#define DMA_IUA_CHAN 2 #endif
#define DMA_IUB_CHAN 3
#define DMA_IF 0x45
#define DMA_IUA 0x46
#define DMA_IUB 0x47
#define DMA_C 0x48
#endif

View file

@ -1,31 +0,0 @@
/* 3b2_rev3_mau.c: WE32206 Math Accelration Unit Implementation
Copyright (c) 2021, Seth J. Morabito
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Except as contained in this notice, the name of the author shall
not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization
from the author.
*/
/* Stub file. Not Yet Implemented. */

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,356 +1,358 @@
/* 3b2_rev3_mmu.h: AT&T 3B2/600G MMU (WE32201) Header /* 3b2_rev3_mmu.h: WE32201 MMU
Copyright (c) 2020, 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_1000_MMU_H_ #ifndef _3B2_REV3_MMU_H_
#define _3B2_1000_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_CONF_M (mmu_state.conf & 0x1) #define MMU_REV3_VER 0x23 /* Version byte returned by WE32201 MMU */
#define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1)
#define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1) #define MMU_CONF_M (mmu_state.conf & 0x1)
#define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3) #define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1)
#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5) #define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1)
#define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6) #define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3)
#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5)
/* Shift and mask the flag bits for the current CPU mode */ #define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6)
#define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3)
/* Shift and mask the flag bits for the current CPU mode */
/* Codes set in the MMU Fault register */ #define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3)
#define MMU_F_MISS_MEM 1
#define MMU_F_RM_UPD 2 /* Codes set in the MMU Fault register */
#define MMU_F_SDTLEN 3 #define MMU_F_MISS_MEM 1
#define MMU_F_PW 4 #define MMU_F_RM_UPD 2
#define MMU_F_PDTLEN 5 #define MMU_F_SDTLEN 3
#define MMU_F_INV_SD 6 #define MMU_F_PW 4
#define MMU_F_SEG_NOT_PRES 7 #define MMU_F_PDTLEN 5
#define MMU_F_PDT_NOT_PRES 9 #define MMU_F_INV_SD 6
#define MMU_F_PAGE_NOT_PRES 10 #define MMU_F_SEG_NOT_PRES 7
#define MMU_F_INDIRECT 11 #define MMU_F_PDT_NOT_PRES 9
#define MMU_F_ACC 13 #define MMU_F_PAGE_NOT_PRES 10
#define MMU_F_SEG_OFFSET 14 #define MMU_F_INDIRECT 11
#define MMU_F_ACC 13
/* Access Request types */ #define MMU_F_SEG_OFFSET 14
#define ACC_MT 0 /* Move Translated */
#define ACC_SPW 1 /* Support processor write */ /* Access Request types */
#define ACC_SPF 3 /* Support processor fetch */ #define ACC_MT 0 /* Move Translated */
#define ACC_IR 7 /* Interlocked read */ #define ACC_SPW 1 /* Support processor write */
#define ACC_AF 8 /* Address fetch */ #define ACC_SPF 3 /* Support processor fetch */
#define ACC_OF 9 /* Operand fetch */ #define ACC_IR 7 /* Interlocked read */
#define ACC_W 10 /* Write */ #define ACC_AF 8 /* Address fetch */
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */ #define ACC_OF 9 /* Operand fetch */
#define ACC_IF 13 /* Instruction fetch */ #define ACC_W 10 /* Write */
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */
/* Pluck out Virtual Address fields */ #define ACC_IF 13 /* Instruction fetch */
#define SID(va) (((va) >> 30) & 3)
#define SSL(va) (((va) >> 17) & 0x1fff) /* Pluck out Virtual Address fields */
#define SOT(va) (va & 0x1ffff) #define SID(va) (((va) >> 30) & 3)
#define SSL(va) (((va) >> 17) & 0x1fff)
/* PSL will be either: #define SOT(va) (va & 0x1ffff)
* - Bits 11-16 (2K pages: MMU_CONF_PS = 0)
* - Bits 12-16 (4K pages: MMU_CONF_PS = 1) /* PSL will be either:
* - Bits 13-16 (8K pages: MMU_CONF_PS = 2) * - Bits 11-16 (2K pages: MMU_CONF_PS = 0)
*/ * - Bits 12-16 (4K pages: MMU_CONF_PS = 1)
#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS)) * - Bits 13-16 (8K pages: MMU_CONF_PS = 2)
#define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS])) */
#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS))
/* POT will be either: #define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS]))
* - Bits 0-10 (2K pages: MMU_CONF_PS = 0)
* - Bits 0-11 (4K pages: MMU_CONF_PS = 1) /* POT will be either:
* - Bits 0-12 (8K pages: MMU_CONF_PS = 2) * - Bits 0-10 (2K pages: MMU_CONF_PS = 0)
*/ * - Bits 0-11 (4K pages: MMU_CONF_PS = 1)
#define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS)))) * - Bits 0-12 (8K pages: MMU_CONF_PS = 2)
*/
/* Get the maximum length of an SSL from SRAMB */ #define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS))))
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len)
/* Get the maximum length of an SSL from SRAMB */
/* Pluck out Segment Descriptor fields */ #define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len)
#define SD_PRESENT(sd_lo) ((sd_lo) & 1)
#define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1) /* Pluck out Segment Descriptor fields */
#define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1) #define SD_PRESENT(sd_lo) ((sd_lo) & 1)
#define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1) #define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1)
#define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1) #define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1)
#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f) #define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1)
#define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff) #define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1)
#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f)
#define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u) #define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff)
#define SD_P_MASK 0x1 #define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u)
#define SD_M_MASK 0x2
#define SD_C_MASK 0x4 #define SD_P_MASK 0x1
#define SD_CACHE_MASK 0x8 #define SD_M_MASK 0x2
#define SD_R_MASK 0x20 #define SD_C_MASK 0x4
#define SD_V_MASK 0x40 #define SD_CACHE_MASK 0x8
#define SD_MAX_OFF_MASK 0xfc0000 #define SD_R_MASK 0x20
#define SD_ACC_MASK 0xff000000u #define SD_V_MASK 0x40
#define SD_ADDR_MASK 0xfffffff8u #define SD_MAX_OFF_MASK 0xfc0000
#define SD_VADDR_MASK 0xfff00000u #define SD_ACC_MASK 0xff000000u
#define SD_RES_MASK 0xfffc00efu #define SD_ADDR_MASK 0xfffffff8u
#define SD_VADDR_MASK 0xfff00000u
#define SDC_VADDR_MASK 0xfff #define SD_RES_MASK 0xfffc00efu
#define SDC_ACC_MASK 0xff000000u
#define SDC_MAX_OFF_MASK 0x001f8000 #define SDC_VADDR_MASK 0xfff
#define SDC_G_MASK 0x1 #define SDC_ACC_MASK 0xff000000u
#define SDC_C_MASK 0x2 #define SDC_MAX_OFF_MASK 0x001f8000
#define SDC_CACHE_MASK 0x4 #define SDC_G_MASK 0x1
#define SDC_M_MASK 0x400000 #define SDC_C_MASK 0x2
#define SDC_R_MASK 0x800000 #define SDC_CACHE_MASK 0x4
#define SDC_M_MASK 0x400000
#define PD_P_MASK 0x1 #define SDC_R_MASK 0x800000
#define PD_M_MASK 0x2
#define PD_W_MASK 0x10 #define PD_P_MASK 0x1
#define PD_R_MASK 0x20 #define PD_M_MASK 0x2
#define PD_PADDR_MASK 0xfffff800u #define PD_W_MASK 0x10
#define PD_R_MASK 0x20
#define PDC_PADDR_MASK 0x1fffff #define PD_PADDR_MASK 0xfffff800u
#define PDC_C_MASK 0x2
#define PDC_W_MASK 0x200000 #define PDC_PADDR_MASK 0x1fffff
#define PDC_M_MASK 0x400000 #define PDC_C_MASK 0x2
#define PDC_R_MASK 0x800000 #define PDC_W_MASK 0x200000
#define PDC_G_MASK 0x40000000 #define PDC_M_MASK 0x400000
#define PDC_U_MASK 0x80000000u #define PDC_R_MASK 0x800000
#define PDC_G_MASK 0x40000000
#define MAX_INDIRECTS 3 #define PDC_U_MASK 0x80000000u
#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS])) #define MAX_INDIRECTS 3
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS]))
#define SDC_IDX(va) ((uint8)((va) >> 17) & 7) #define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
/* Convert from sd to sd cache entry */ #define SDC_IDX(va) ((uint8)((va) >> 17) & 7)
#define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \
((lo) & SD_C_MASK) >> 1 | \ /* Convert from sd to sd cache entry */
((lo) & SD_CACHE_MASK) >> 1 | \ #define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \
(SDC_G_MASK)) ((lo) & SD_C_MASK) >> 1 | \
#define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \ ((lo) & SD_CACHE_MASK) >> 1 | \
((lo) & SD_MAX_OFF_MASK) >> 3 | \ (SDC_G_MASK))
((lo) & SD_R_MASK) << 18 | \ #define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \
((lo) & SD_M_MASK) << 21 | \ ((lo) & SD_MAX_OFF_MASK) >> 3 | \
((va) & SD_VADDR_MASK) >> 20) ((lo) & SD_R_MASK) << 18 | \
((lo) & SD_M_MASK) << 21 | \
/* Convert from sd cache entry to sd */ ((va) & SD_VADDR_MASK) >> 20)
#define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK)
#define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \ /* Convert from sd cache entry to sd */
((lo) & SDC_MAX_OFF_MASK) << 3 | \ #define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK)
((lo) & SDC_R_MASK) >> 18 | \ #define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \
((lo) & SDC_M_MASK) >> 21 | \ ((lo) & SDC_MAX_OFF_MASK) << 3 | \
((hi) & SDC_C_MASK) << 1 | \ ((lo) & SDC_R_MASK) >> 18 | \
((hi) & SDC_CACHE_MASK) << 1 | \ ((lo) & SDC_M_MASK) >> 21 | \
SD_V_MASK | SD_P_MASK) ((hi) & SDC_C_MASK) << 1 | \
((hi) & SDC_CACHE_MASK) << 1 | \
/* Convert from pd cache entry to pd */ SD_V_MASK | SD_P_MASK)
#define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \
(((pdcl) & PDC_W_MASK) >> 17) | \ /* Convert from pd cache entry to pd */
(((pdcl) & PDC_M_MASK) >> 21) | \ #define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \
(((pdcl) & PDC_R_MASK) >> 18) | \ (((pdcl) & PDC_W_MASK) >> 17) | \
PD_P_MASK) (((pdcl) & PDC_M_MASK) >> 21) | \
(((pdcl) & PDC_R_MASK) >> 18) | \
/* Convert from pd to pd cache entry (low word) */ PD_P_MASK)
#define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \
(((pd) & PD_W_MASK) << 17) | \ /* Convert from pd to pd cache entry (low word) */
(((pd) & PD_M_MASK) << 21) | \ #define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \
(((pd) & PD_R_MASK) << 18) | \ (((pd) & PD_W_MASK) << 17) | \
((sd_lo) & SD_ACC_MASK)) (((pd) & PD_M_MASK) << 21) | \
(((pd) & PD_R_MASK) << 18) | \
/* Convert from va to pd cache entry (high word / tag) */ ((sd_lo) & SD_ACC_MASK))
#define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \
(mmu_state.cidnr[SID(va)] << 26) | \ /* Convert from va to pd cache entry (high word / tag) */
((va & 0xfffff800u) >> 6) | \ #define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \
((sd_lo & SD_CACHE_MASK) >> 1) | \ (mmu_state.cidnr[SID(va)] << 26) | \
((sd_lo & SD_C_MASK) >> 1)) ((va & 0xfffff800u) >> 6) | \
((sd_lo & SD_CACHE_MASK) >> 1) | \
/* Maximum offset (in bytes) of a paged segment */ ((sd_lo & SD_C_MASK) >> 1))
#define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1)
/* Maximum offset (in bytes) of a paged segment */
#define IDNC_TAG(val) ((val) & 0xfffffff8) #define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1)
#define IDNC_U(val) ((val) & 0x1)
#define IDNC_TAG(val) ((val) & 0xfffffff8)
/* Fault codes */ #define IDNC_U(val) ((val) & 0x1)
#define MMU_FAULT(f) { \
if (fc) { \ /* Fault codes */
mmu_state.fcode = ((((uint32)r_acc)<<7) | \ #define MMU_FAULT(f) { \
(((uint32)(CPU_CM))<<5) | \ if (fc) { \
(f & 0x1f)); \ mmu_state.fcode = ((((uint32)r_acc)<<7) | \
mmu_state.faddr = va; \ (((uint32)(CPU_CM))<<5) | \
} \ (f & 0x1f)); \
} mmu_state.faddr = va; \
} \
typedef struct { }
uint32 addr;
uint32 len; typedef struct {
} mmu_sec; uint32 addr;
uint32 len;
} mmu_sec;
/*
* Segment Descriptor Cache Entry Format
* ===================================== /*
* * Segment Descriptor Cache Entry Format
* The Segment Descriptor Cache is a directly mapped cache, indexed by * =====================================
* bits 19, 18, and 17 of the virtual address. Some notes: *
* * The Segment Descriptor Cache is a directly mapped cache, indexed by
* - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all * bits 19, 18, and 17 of the virtual address. Some notes:
* copied from the SD in main memory. *
* - "VAddr" holds bits 20-31 of the virtual address * - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all
* - "Address" holds a pointer (word-aligned, so the top 30 bits) to * copied from the SD in main memory.
* a page descriptor table in paged mode, or a segment in * - "VAddr" holds bits 20-31 of the virtual address
* contiguous segment mode. * - "Address" holds a pointer (word-aligned, so the top 30 bits) to
* - "Max Offset" holds the number of pages minus one in the * a page descriptor table in paged mode, or a segment in
* segment. Depending on current page size, various bits of this * contiguous segment mode.
* field will be ignored: * - "Max Offset" holds the number of pages minus one in the
* o Bits 20-15 are used for 2K pages * segment. Depending on current page size, various bits of this
* o Bits 20-16 are used for 4K pages * field will be ignored:
* o Bits 20-17 are used for 8K pages * o Bits 20-15 are used for 2K pages
* * o Bits 20-16 are used for 4K pages
* Low Word (bits 0-31) * o Bits 20-17 are used for 8K pages
* -------------------- *
* * Low Word (bits 0-31)
* 31 24 23 22 21 20 15 14 12 11 0 * --------------------
* +-------+---+---+---+------------+------+--------------------------+ *
* | Acc | R | M | - | Max Offset | - | VAddr | * 31 24 23 22 21 20 15 14 12 11 0
* +-------+---+---+---+------------+------+--------------------------+ * +-------+---+---+---+------------+------+--------------------------+
* * | Acc | R | M | - | Max Offset | - | VAddr |
* High Word (bits 32-63) * +-------+---+---+---+------------+------+--------------------------+
* ---------------------- *
* * High Word (bits 32-63)
* 31 3 2 1 0 * ----------------------
* +------------------------------------------------------+---+---+---+ *
* | Address | $ | C | G | * 31 3 2 1 0
* +------------------------------------------------------+---+---+---+ * +------------------------------------------------------+---+---+---+
* * | Address | $ | C | G |
* * +------------------------------------------------------+---+---+---+
* Page Descriptor Cache Entry Format *
* ================================== *
* * Page Descriptor Cache Entry Format
* The Page Descriptor Cache is a fully associative cache, with a * ==================================
* tag constructed from the "G" and "IDN" bits, and bits 31-11 of *
* the virtual address. * The Page Descriptor Cache is a fully associative cache, with a
* * tag constructed from the "G" and "IDN" bits, and bits 31-11 of
* Depending on the current page size and access mode, various bits of * the virtual address.
* "VAddr" are ignored. *
* * Depending on the current page size and access mode, various bits of
* o Multi-context mode, all ops except single-entry flush: * "VAddr" are ignored.
* VAddr bits 29-11 are used. *
* o Multi-context mode, single-entry flush: * o Multi-context mode, all ops except single-entry flush:
* VAddr bits 31-11 are used. * VAddr bits 29-11 are used.
* o Single-context mode, all ops: * o Multi-context mode, single-entry flush:
* Vaddr bits 31-11 are used. * VAddr bits 31-11 are used.
* o In ALL CASES: * o Single-context mode, all ops:
* + 2KB Page Size: Bits 11-12 are used. * Vaddr bits 31-11 are used.
* + 4KB Page Size: Bit 11 ignored, 12 used. * o In ALL CASES:
* + 8KB Page Size: Bits 11-12 ignored. * + 2KB Page Size: Bits 11-12 are used.
* * + 4KB Page Size: Bit 11 ignored, 12 used.
* Low Word (bits 0-31) * + 8KB Page Size: Bits 11-12 ignored.
* -------------------- *
* * Low Word (bits 0-31)
* 31 24 23 22 21 20 0 * --------------------
* +-------+---+---+---+----------------------------------------------+ *
* | Acc | R | M | W | Physical Address | * 31 24 23 22 21 20 0
* +-------+---+---+---+----------------------------------------------+ * +-------+---+---+---+----------------------------------------------+
* * | 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 * ----------------------
* +---+---+---------+----------------------------+-------+---+---+---+ *
* | U | G | IDN | (31) VAddr (11)| - | $ | C | - | * 31 30 29 26 25 5 4 3 2 1 0
* +---+---+---------+----------------------------+-------+---+---+---+ * +---+---+---------+----------------------------+-------+---+---+---+
* * | U | G | IDN | (31) VAddr (11)| - | $ | C | - |
*/ * +---+---+---------+----------------------------+-------+---+---+---+
*
typedef struct _mmu_state { */
t_bool enabled; /* Global enabled/disabled flag */
typedef struct _mmu_state {
t_bool flush_u; /* If true, flush all but last cached entry */ t_bool enabled; /* Global enabled/disabled flag */
uint32 last_cached; /* The index of the last cached PDC entry */
t_bool flush_u; /* If true, flush all but last cached entry */
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */ uint32 last_cached; /* The index of the last cached PDC entry */
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */ uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */
uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */
uint32 sra[4]; /* Section RAM A */ uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */
uint32 srb[4]; /* Section RAM B */
uint32 sra[4]; /* Section RAM A */
uint32 cidnr[4]; /* Current ID Number Registers */ uint32 srb[4]; /* Section RAM B */
uint32 idnc[16]; /* ID Number Cache */
uint32 cidnr[4]; /* Current ID Number Registers */
mmu_sec sec[4]; /* Section descriptors decoded from uint32 idnc[16]; /* ID Number Cache */
Section RAM A and B */
mmu_sec sec[4]; /* Section descriptors decoded from
uint32 fcode; /* Fault Code Register */ Section RAM A and B */
uint32 faddr; /* Fault Address Register */
uint32 conf; /* Configuration Register */ uint32 fcode; /* Fault Code Register */
uint32 var; /* Virtual Address Register */ uint32 faddr; /* Fault Address Register */
uint32 conf; /* Configuration Register */
} MMU_STATE; uint32 var; /* Virtual Address Register */
t_stat mmu_init(DEVICE *dptr); } MMU_STATE;
uint32 mmu_read(uint32 pa, size_t size);
void mmu_write(uint32 pa, uint32 val, size_t size); t_stat mmu_init(DEVICE *dptr);
CONST char *mmu_description(DEVICE *dptr); uint32 mmu_read(uint32 pa, size_t size);
void mmu_write(uint32 pa, uint32 val, size_t size);
/* Virtual memory translation */ CONST char *mmu_description(DEVICE *dptr);
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc, /* Virtual memory translation */
t_bool fc, uint32 *pa); uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa); t_bool fc, uint32 *pa);
void mmu_enable();
void mmu_disable(); t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
void mmu_enable();
t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc); void mmu_disable();
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_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
#endif /* _3B2_1000_MMU_H_ */ t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
#endif /* _3B2_REV3_MMU_H_ */

View file

@ -1,80 +1,80 @@
/* 3b2_rev3_sys.c: AT&T 3B2/600G system definition /* 3b2_rev3_sys.c: Version 3 (3B2/700) System Definition
Copyright (c) 2020, 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/600G"; 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);
} }

View file

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

File diff suppressed because it is too large Load diff

View file

@ -1,260 +1,288 @@
/* 3b2_scsi.h: AT&T 3B2 SCSI (CM195W) Host Adapter /* 3b2_scsi.h: CM195W SCSI Controller CIO Card
Copyright (c) 2020, 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_CNTRL 0x20 #define HA_WRITE_BLK 0x0c
#define HA_VERS 0x40 #define HA_CNTRL 0x20
#define HA_DL_EEDT 0x42 #define HA_VERS 0x40
#define HA_UL_EEDT 0x43 #define HA_DL_EEDT 0x42
#define HA_EDSD 0x44 #define HA_UL_EEDT 0x43
#define HA_RESET 0x45 #define HA_EDSD 0x44
#define HA_RESET 0x45
#define HA_TESTRDY 0x00
#define HA_FORMAT 0x04 #define HA_TESTRDY 0x00
#define HA_WRITE 0x0a #define HA_FORMAT 0x04
#define HA_INQUIRY 0x12 #define HA_WRITE 0x0a
#define HA_MODESNS 0x1a #define HA_INQUIRY 0x12
#define HA_RDCPCTY 0x25 #define HA_MODESEL 0x15
#define HA_READ 0x08 #define HA_MODESNS 0x1a
#define HA_READEXT 0x28 #define HA_RDCPCTY 0x25
#define HA_WRTEXT 0x2a #define HA_READ 0x08
#define HA_VERIFY 0x2f #define HA_READEXT 0x28
#define HA_WRTEXT 0x2a
#define HA_PDLS_OFF 0x28 #define HA_VERIFY 0x2f
/* CIO Status */ #define HA_PDLS_OFF 0x28
#define CIO_TIMEOUT 0x65
/* CIO Status */
#define HA_BOOT_ADDR 0x2004000 #define CIO_TIMEOUT 0x65
#define HA_PDINFO_ADDR 0x2004400
#define HA_BOOT_ADDR 0x2004000
#define HA_ID 0x0100 #define HA_PDINFO_ADDR 0x2004400
#define HA_IPL 12
#define HA_ID 0x0100
#define HA_GOOD 0x00 #define HA_IPL 12
#define HA_CKCON 0x02
#define HA_GOOD 0x00
#define HA_DSD_DISK 0x100 #define HA_CKCON 0x02
#define HA_DSD_TAPE 0x101
#define HA_DSD_DISK 0x100
#define HA_VERSION 0x01 #define HA_DSD_TAPE 0x101
#define SCQRESIZE 24 #define HA_VERSION 0x01
#define RAPP_LEN (SCQRESIZE - 8)
#define SCQCESIZE 16 #define SCQRESIZE 24
#define CAPP_LEN (SCQCESIZE - 8) #define RAPP_LEN (SCQRESIZE - 8)
#define SCQCESIZE 16
#define FC_TC(x) (((x) >> 3) & 7) #define CAPP_LEN (SCQCESIZE - 8)
#define FC_LU(x) ((x) & 7)
#define FC_TC(x) (((x) >> 3) & 7)
#define HA_EDT_LEN 1024 #define FC_LU(x) ((x) & 7)
#define HA_BLKSZ 512 #define HA_EDT_LEN 1024
#define HA_MAX_CMD 12 #define HA_BLKSZ 512
#define INQUIRY_MAX 36
#define HA_MAX_CMD 12
#define HA_STAT(ha_stat,cio_stat) { \ #define INQUIRY_MAX 36
ha_state.reply.ssb = (ha_stat); \
ha_state.reply.status = (cio_stat); \ #define HA_STAT(tc,ha_stat,cio_stat) { \
} ha_state.ts[tc].rep.ssb = (ha_stat); \
ha_state.ts[tc].rep.status = (cio_stat); \
#define HA_MAX_DTYPE 1 }
/* CDC Wren IV 327 MB Hard Disk (AT&T KS-23483,L3) */ #define HA_MAX_DTYPE 4
#define SD327_DTYPE 0
#define SD327_PQUAL 0x00 /* Hardware Notes
#define SD327_SCSI 1 * ==============
#define SD327_BLK 512 *
#define SD327_LBN 640396 * Disk Drives
#define SD327_MANU "AT&T" * -----------
#define SD327_DESC "KS23483" *
#define SD327_REV "0001" /* TODO: Find real rev */ * There are two emulated SCSI disk drives available.
#define SD327_TPZ 9 *
#define SD327_ASEC 3 * 1. 155 MB CDC Wren III (CDC 94161-9)
#define SD327_ATPZ 0 * 2. 327 MB CDC Wren IV (CDC 94171-9)
#define SD327_ATPU 0 *
#define SD327_SPT 46 * The CDC 94161-9 was also OEMed as the "AT&T KS23483,L3"
#define SD327_CYL 1549 * The CDC 94171-9 was also OEMed as the "AT&T KS23483,L25"
#define SD327_HEADS 9 *
#define SD327_PREC 1200 *
#define SD327_RWC 1200 * Tape Drive
#define SD327_STEP 15 * ----------
#define SD327_LZ 1549 *
#define SD327_RPM 3600 * Wangtek 5125EN (AT&T Part number KS23417,L2)
*
/* Wangtek 120MB cartridge tape (AT&T KS-23465) */ * DC600A cartridge tape at 120MB (QIC-120 format)
#define ST120_DTYPE 1 *
#define ST120_PQUAL 0x00 */
#define ST120_SCSI 1
#define ST120_BLK 512
#define ST120_LBN 266004 /* Other SCSI hard disk types
#define ST120_MANU "WANGTEK" * ---------------------------
#define ST120_DESC "KS23465" *
#define ST120_REV "CX17" * These geometries are supported natively and automatically
#define ST120_DENS 5 * by System V Release 3.2.3 UNIX.
*
#define UNIT_V_DTYPE (SCSI_V_UF + 0) * 1. CDC 94161-9 155 MB/148 MiB 512 B/s, 35 s/t, 9 head, 965 cyl
#define UNIT_M_DTYPE 0x1f * 2. AT&T KS23483 327 MB/312 MiB 512 B/s, 46 s/t, 9 head, 1547 cyl
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE) * (a.k.a CDC 94171-9)
*
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE) * Also supported was a SCSI-to-ESDI bridge controller that used the
#define HA_DISK(d) { \ * Emulex MD23/S2 SCSI-to-ESDI bridge. It allowed up to four ESDI
SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \ * drives to be mapped as LUNs 0-3.
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d, 0 \ *
} */
#define HA_TAPE(d) { \
SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \ /* AT&T 155 MB Hard Disk (35 sec/t, 9 hd, 964 cyl) */
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d, 0 \ #define SD155_DTYPE 0
} #define SD155_PQUAL 0x00
#define HA_SIZE(d) d##_LBN #define SD155_SCSI 1
#define SD155_BLK 512
#define SD155_LBN 303660
/* Hardware Notes #define SD155_MANU "AT&T"
* ============== #define SD155_DESC "KS23483"
* #define SD155_REV "0000"
* Disk Drive
* ---------- /* AT&T 300 MB Hard Disk (43 sec/t, 9 hd, 1514 cyl) */
* #define SD300_DTYPE 1
* We emulate a 300-Megabyte Hard Disk, AT&T part number KS23483,L3. #define SD300_PQUAL 0x00
* #define SD300_SCSI 1
* This is the same as a CDC/Imprimis Wren IV 94171-327 #define SD300_BLK 512
* #define SD300_LBN 585937
* 512 bytes per block #define SD300_MANU "AT&T"
* 1,520 cylinders #define SD300_DESC "KS23483"
* 2 alternate cylinders (1518 available) #define SD300_REV "0000"
* 46 Sectors per Track
* 3 Alternate Sectors per Track (43 available) /* AT&T 327 MB Hard Disk (46 sec/t, 9 hd, 1547 cyl) */
* 9 tracks per cylinder (9 heads) #define SD327_DTYPE 2
* #define SD327_PQUAL 0x00
* Formatted Size: 587,466 blocks #define SD327_SCSI 1
* #define SD327_BLK 512
* #define SD327_LBN 640458
* Tape Drive #define SD327_MANU "AT&T"
* ---------- #define SD327_DESC "KS23483"
* #define SD327_REV "0000"
* Wangtek 5099EN (AT&T Part number KS23417,L2)
* /* AT&T 630 MB Hard Disk (56 sec/t, 16 hd, 1447 cyl) */
* DC600A cartridge tape #define SD630_DTYPE 3
* #define SD630_PQUAL 0x00
* 512 bytes per block #define SD630_SCSI 1
* 9 tracks #define SD630_BLK 512
* 13,956 blocks per track #define SD630_LBN 1296512
* #define SD630_MANU "AT&T"
* Formatted Size: 125,604 blocks #define SD630_DESC "KS23483"
* #define SD630_REV "0000"
*/
/* Wangtek 120MB cartridge tape */
#define HA_JOB_QUICK 0 #define ST120_DTYPE 4
#define HA_JOB_EXPRESS 1 #define ST120_PQUAL 0x00
#define HA_JOB_FULL 2 #define ST120_SCSI 1
#define ST120_BLK 512
typedef uint8 ha_jobtype; #define ST120_LBN 1
#define ST120_MANU "WANGTEK"
typedef struct { #define ST120_DESC "KS23465"
uint32 addr; #define ST120_REV "CX17"
uint32 len;
} haddr; #define UNIT_V_DTYPE (SCSI_V_UF + 0)
#define UNIT_M_DTYPE 0x1f
/* #define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
* SCSI Command Request
*/ #define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
typedef struct { #define HA_DISK(d) \
uint8 op; /* Destructured from the cmd byte array */ { SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \
uint8 tc; d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
uint8 lu;
uint32 timeout; #define HA_TAPE(d) \
{ SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \
uint8 dlen; d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
haddr daddr[48]; /* Support up to 48 transfer addresses */
#define HA_SIZE(d) d##_LBN
uint32 dma_lst;
uint16 cmd_len; #define HA_JOB_QUICK 0
uint8 cmd[HA_MAX_CMD]; #define HA_JOB_EXPRESS 1
} ha_req; #define HA_JOB_FULL 2
/* typedef uint8 ha_jobtype;
* SCSI Command Response
*/ typedef struct {
typedef struct { uint32 addr;
ha_jobtype type; /* Job type */ uint32 len;
t_bool pending; /* Pending or completed? */ } haddr;
uint8 status; /* Result Status */
uint8 op; /* Command Opcode */ /*
uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */ * SCSI Command Request
uint8 ssb; /* SCSI Status Byte */ */
uint32 addr; /* Response address */ typedef struct {
uint32 len; /* Response length */ uint8 op; /* Destructured from the cmd byte array */
} ha_resp; uint8 tc;
uint8 lu;
#define PUMP_NONE 0 uint32 timeout;
#define PUMP_SYSGEN 1
#define PUMP_COMPLETE 2 uint8 dlen;
haddr daddr[48]; /* Support up to 48 transfer addresses */
/*
* General SCSI HA internal state. uint32 dma_lst;
*/ uint16 cmd_len;
typedef struct { uint8 cmd[HA_MAX_CMD];
uint8 cid; /* Card Backsplane Slot # */ } ha_req;
uint32 pump_state;
uint32 haddr; /* Host address for read/write */ /*
uint32 hlen; /* Length for read or write */ * SCSI Command Response
t_bool initialized; /* Card has been initialized */ */
t_bool frq; /* Fast Request Queue enabled */ typedef struct {
uint8 edt[HA_EDT_LEN]; /* Equipped Device Table */ ha_jobtype type; /* Job type */
ha_req request; /* Current job request */ uint8 status; /* Result Status */
ha_resp reply; /* Current job reply */ uint8 op; /* Command Opcode */
} HA_STATE; uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */
uint8 ssb; /* SCSI Status Byte */
t_stat ha_show_type(FILE *st, UNIT *uptr, int32 val, CONST void *desc); uint32 addr; /* Response address */
t_stat ha_set_type(UNIT *uptr, int32 val, CONST char *cptr, void *desc); uint32 len; /* Response length */
t_stat ha_reset(DEVICE *dptr); } ha_resp;
t_stat ha_svc(UNIT *uptr);
t_stat ha_rq_svc(UNIT *uptr); #define PUMP_NONE 0
t_stat ha_attach(UNIT *uptr, CONST char *cptr); #define PUMP_SYSGEN 1
t_stat ha_detach(UNIT *uptr); #define PUMP_COMPLETE 2
void ha_fast_queue_check(); /*
void ha_sysgen(uint8 cid); * SCSI Target state
void ha_express(uint8 cid); */
void ha_full(uint8 cid); typedef struct {
t_bool pending; /* Service pending */
/* Fast Completion */ ha_req req; /* SCSI job request */
ha_resp rep; /* SCSI job reply */
void ha_fcm_express(); } ha_ts;
#endif /* _3B2_SCSI_H_ */ /*
* General SCSI HA internal state.
*/
typedef struct {
uint8 slot; /* Card Backsplane Slot # */
uint32 pump_state;
t_bool frq; /* Fast Request Queue enabled */
uint8 edt[HA_EDT_LEN]; /* Equipped Device Table */
ha_ts ts[8]; /* Target state */
} HA_STATE;
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_reset(DEVICE *dptr);
t_stat ha_svc(UNIT *uptr);
t_stat ha_rq_svc(UNIT *uptr);
t_stat ha_attach(UNIT *uptr, CONST char *cptr);
t_stat ha_detach(UNIT *uptr);
void ha_fast_queue_check();
void ha_sysgen(uint8 slot);
void ha_express(uint8 slot);
void ha_full(uint8 slot);
/* Fast Completion */
void ha_fcm_express(uint8 target);
#endif /* _3B2_SCSI_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,82 +1,138 @@
/* 3b2_stddev.h: AT&T 3B2 miscellaneous system board devices. /* 3b2_stddev.h: Miscellaneous System Board Devices
Copyright (c) 2017, 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);
/* TOD */ typedef struct tod_data {
typedef struct tod_data { time_t time; /* System time */
int32 delta; /* Delta between simulated time and real time (sec.) */
uint8 tsec; /* 1/10 seconds */ uint8 ctrl; /* Control register (Rev 3 only) */
uint8 unit_sec; /* 1's column seconds */ uint8 flags; /* Data Changed & Interrutpt Flags (Rev 3 only) */
uint8 ten_sec; /* 10's column seconds */ uint8 clkset; /* Clock / Setting register (Rev 3 only) */
uint8 unit_min; /* 1's column minutes */
uint8 ten_min; /* 10's column minutes */ uint8 tsec; /* 1/100th seconds, 00-99 */
uint8 unit_hour; /* 1's column hours */ uint8 sec; /* Seconds, 00-59 */
uint8 ten_hour; /* 10's column hours */ uint8 min; /* Minutes, 00-59 */
uint8 unit_day; /* 1's column day of month */ uint8 hour; /* Hours, 00-23 */
uint8 ten_day; /* 10's column day of month */ uint8 day; /* Days, 00-27, 28, 29, or 30 */
uint8 wday; /* Day of week (0-6) */ uint8 mon; /* Months, 00-11 */
uint8 unit_mon; /* 1's column month */ uint8 year; /* Years, 00-99 (Rev 3 only) */
uint8 ten_mon; /* 10's column month */ uint8 wday; /* Day of Week, 0-6 */
uint8 year; /* 1, 2, 4, 8 shift register */ uint8 lyear; /* Years since last leap year */
uint8 pad[3]; /* Padding to 32 bytes */ } TOD_DATA;
} TOD_DATA;
#if defined(REV2)
void tod_resync();
void tod_update_delta(); #define TOD_TEST 0x00
t_stat tod_reset(DEVICE *dptr); #define TOD_TSEC 0x04
t_stat tod_attach(UNIT *uptr, CONST char *cptr); #define TOD_1SEC 0x08
t_stat tod_detach(UNIT *uptr); #define TOD_10SEC 0x0c
const char *tod_description(DEVICE *dptr); #define TOD_1MIN 0x10
t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); #define TOD_10MIN 0x14
uint32 tod_read(uint32 pa, size_t size); #define TOD_1HOUR 0x18
void tod_write(uint32, uint32 val, size_t size); #define TOD_10HOUR 0x1c
#define TOD_1DAY 0x20
#if defined(REV3) #define TOD_10DAY 0x24
/* Fault Register */ #define TOD_WDAY 0x28
uint32 flt_read(uint32 pa, size_t size); #define TOD_1MON 0x2c
void flt_write(uint32 pa, uint32 val, size_t size); #define TOD_10MON 0x30
#endif #define TOD_1YEAR 0x34
#define TOD_STARTSTOP 0x38
#endif /* _3B2_STDDEV_H_ */ #define TOD_INT 0x3c
#else
#define TOD_FLAG_CHG 0x08
#define TOD_FLAG_IRQ 0x01
#define TOD_CTRL 0x00
#define TOD_TSEC 0x04
#define TOD_1SEC 0x08
#define TOD_10SEC 0x0c
#define TOD_1MIN 0x10
#define TOD_10MIN 0x14
#define TOD_1HOUR 0x18
#define TOD_10HOUR 0x1c
#define TOD_1DAY 0x20
#define TOD_10DAY 0x24
#define TOD_1MON 0x28
#define TOD_10MON 0x2c
#define TOD_1YEAR 0x30
#define TOD_10YEAR 0x34
#define TOD_WDAY 0x38
#define TOD_SET_INT 0x3c
#endif
void tod_update_delta();
t_stat tod_reset(DEVICE *dptr);
t_stat tod_attach(UNIT *uptr, CONST char *cptr);
t_stat tod_detach(UNIT *uptr);
t_stat tod_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
const char *tod_description(DEVICE *dptr);
uint32 tod_read(uint32 pa, size_t size);
void tod_write(uint32, uint32 val, size_t size);
/* Global symbols */
extern int32 tmxr_poll;
#if defined(REV3)
/* Fault Register */
#define FLT_MSK 0xffffff00
#define MEM_EQP 0x4
#define MEM_4M 0x2
#define MEM_16M 0x3
uint32 flt_read(uint32 pa, 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);
const char *flt_description(DEVICE *dptr);
extern uint32 flt[2];
#endif /* defined(REV3) */
#endif /* _3B2_STDDEV_H_ */

View file

@ -1,160 +1,192 @@
/* 3b2_sys.c: AT&T 3B2 common system definitions /* 3b2_sys.c: Common System Definition
Copyright (c) 2021, 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"
}; };
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag) /*
{ * ROM and Binary loader
int32 i; *
uint32 addr = 0; * -r load ROM
int32 cnt = 0; * -o for memory, specify origin
*
if ((*cptr != 0) || (flag != 0)) { */
return SCPE_ARG; t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
} {
t_stat r;
addr = R[NUM_PC]; int32 i;
uint32 origin = 0, limit = 0;
while ((i = getc (fileref)) != EOF) { int32 cnt = 0;
pwrite_b(addr, (uint8)i);
addr++; if (flag) {
cnt++; return sim_messagef(SCPE_NOFNC, "Command not implemented.");
} }
printf ("%d Bytes loaded.\n", cnt); if (sim_switches & SWMASK('R')) {
origin = ROM_BASE;
return SCPE_OK; limit = ROM_BASE + ROM_SIZE;
} } else {
origin = 0;
t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw) limit = (uint32) cpu_unit.capac;
{ if (sim_switches & SWMASK('O')) {
DEVICE *dptr; origin = (uint32) get_uint(cptr, 16, 0xffffffff, &r);
t_stat r; if (r != SCPE_OK) {
int32 k, num, vp; return SCPE_ARG;
int32 len = 4; }
}
if (sw & (int32) SWMASK ('B')) { }
len = 1;
} else if (sw & (int32) SWMASK ('H')) { while ((i = Fgetc (fileref)) != EOF) {
len = 2; if (origin >= limit) {
} else if (sw & (int32) SWMASK ('W')) { return SCPE_NXM;
len = 4; }
} if (sim_switches & SWMASK('R')) {
pwrite_b_rom(origin, (uint8)i);
// Parse cptr } else {
num = (int32) get_uint(cptr, 16, WORD_MASK, &r); pwrite_b(origin, (uint8)i, BUS_CPU);
}
if (r != SCPE_OK) { origin++;
return r; cnt++;
} }
if (uptr == NULL) { if (sim_switches & SWMASK('R')) {
uptr = &cpu_unit; rom_loaded = TRUE;
} sim_messagef(SCPE_OK, "%d bytes loaded into ROM\n", cnt);
} else {
dptr = find_dev_from_unit(uptr); sim_messagef(SCPE_OK, "%d bytes loaded at address 0x%08x\n", cnt, origin - cnt);
}
if (dptr == NULL) {
return SCPE_IERR; return SCPE_OK;
} }
vp = 0; t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw)
for (k = len - 1; k >= 0; k--) { {
val[vp++] = (num >> (k * 8)) & 0xff; DEVICE *dptr;
} t_stat r;
int32 k, num, vp;
return -(vp - 1); int32 len = 4;
}
if (sw & (int32) SWMASK ('B')) {
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) len = 1;
{ } else if (sw & (int32) SWMASK ('H')) {
uint32 len = 4; len = 2;
int32 k, vp, num; } else if (sw & (int32) SWMASK ('W')) {
unsigned int c; len = 4;
}
num = 0;
vp = 0; // Parse cptr
num = (int32) get_uint(cptr, 16, WORD_MASK, &r);
if (sw & (int32) SWMASK('M')) {
return fprint_sym_m(of, addr, val); if (r != SCPE_OK) {
} return r;
}
if (sw & (int32) SWMASK ('B')) {
len = 1; if (uptr == NULL) {
} else if (sw & (int32) SWMASK ('H')) { uptr = &cpu_unit;
len = 2; }
} else if (sw & (int32) SWMASK ('W')) {
len = 4; dptr = find_dev_from_unit(uptr);
}
if (dptr == NULL) {
if (sw & (int32) SWMASK('C')) { return SCPE_IERR;
len = 16; }
for (k = (int32) len - 1; k >= 0; k--) {
c = (unsigned int)val[vp++]; vp = 0;
if (c >= 0x20 && c < 0x7f) { for (k = len - 1; k >= 0; k--) {
fprintf(of, "%c", c); val[vp++] = (num >> (k * 8)) & 0xff;
} else { }
fprintf(of, ".");
} return -(vp - 1);
} }
return -(vp - 1);
} t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
{
for (k = len - 1; k >= 0; k--) { uint32 len = 4;
num = num | (((int32) val[vp++]) << (k * 8)); int32 k, vp, num;
} unsigned int c;
fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO); num = 0;
vp = 0;
return -(vp - 1);
} if (sw & (int32) SWMASK('M')) {
return fprint_sym_m(of, addr, val);
}
if (sw & (int32) SWMASK ('B')) {
len = 1;
} else if (sw & (int32) SWMASK ('H')) {
len = 2;
} else if (sw & (int32) SWMASK ('W')) {
len = 4;
}
if (sw & (int32) SWMASK('C')) {
len = 16;
for (k = (int32) len - 1; k >= 0; k--) {
c = (unsigned int)val[vp++];
if (c >= 0x20 && c < 0x7f) {
fprintf(of, "%c", c);
} else {
fprintf(of, ".");
}
}
return -(vp - 1);
}
for (k = len - 1; k >= 0; k--) {
num = num | (((int32) val[vp++]) << (k * 8));
}
fprint_val(of, (uint32) num, 16, len * 8, PV_RZRO);
return -(vp - 1);
}

View file

@ -1,46 +1,46 @@
/* 3b2_rev2_sys.h: AT&T 3B2 Rev 2 (Model 400) system header /* 3b2_sys.h: Common System Definition
Copyright (c) 2017, 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,42 +1,78 @@
/* 3b2_timer.h: Common TIMER header /* 3b2_timer.h: 8253/82C54 Interval Timer
Copyright (c) 2021, 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_
#if defined(REV3) #include "3b2_defs.h"
#include "3b2_rev3_timer.h"
#else #define TIMER_REG_DIVA 0x03
#include "3b2_rev2_timer.h" #define TIMER_REG_DIVB 0x07
#endif #define TIMER_REG_DIVC 0x0b
#define TIMER_REG_CTRL 0x0f
extern int32 tmxr_poll; #define TIMER_CLR_LATCH 0x13
#endif /* _3B2_TIMER_H_ */ #define TIMER_MODE(ctr) (((ctr->ctrl) >> 1) & 7)
#define TIMER_RW(ctr) (((ctr->ctrl) >> 4) & 3)
#define CLK_LATCH 0
#define CLK_LSB 1
#define CLK_MSB 2
#define CLK_LMB 3
#define TMR_SANITY 0
#define TMR_INT 1
#define TMR_BUS 2
struct timer_ctr {
uint16 divider;
uint16 val;
uint8 ctrl_latch;
uint16 cnt_latch;
uint8 ctrl;
t_bool r_lmb;
t_bool w_lmb;
t_bool enabled;
t_bool gate;
t_bool r_ctrl_latch;
t_bool r_cnt_latch;
};
t_stat timer_reset(DEVICE *dptr);
uint32 timer_read(uint32 pa, size_t size);
void timer_write(uint32 pa, uint32 val, size_t size);
void timer_gate(uint8 ctrnum, t_bool inhibit);
t_stat tmr_svc(UNIT *uptr);
t_stat tmr_int_svc(UNIT *uptr);
CONST char *tmr_description(DEVICE *dptr);
t_stat tmr_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
#endif /* _3B2_TIMER_H_ */

View file

@ -1,129 +1,135 @@
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 Model 400 computer (Rev. 2) 1. A simulator for the AT&T 3B2/400 computer (3b2 or 3B2.EXE)
2. A simulator for the AT&T 3B2 Model 600 computer (Rev. 3) 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/600 simulator The 3B2/400 simulator is complete, usable, and robust. The 3B2/700
is not yet usable, however. It is under active development. simulator is under active development and is not yet considered
stable.
Full documentation for the 3B2 simulator is available here:
Full documentation for the 3B2 simulator is available here:
- https://loomcom.com/3b2/emulator.html
- https://loomcom.com/3b2/emulator.html
Devices
------- 3B2/400 Simulator Devices
-------------------------
The following devices are simulated. The SIMH names for the simulated
devices are given in parentheses: The following devices are simulated. The SIMH names for the simulated
devices are given in parentheses:
- 3B2 Model 400 System Board with 1MB, 2MB, or 4MB RAM (CSR, NVRAM)
- WE32100 CPU (CPU) - 3B2 Model 400 System Board with 1MB, 2MB, or 4MB RAM (CSR, NVRAM)
- WE32101 MMU (MMU) - WE32100 CPU (CPU)
- PD8253 Interval Timer (TIMER) - 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)
Usage
----- 3B2/400 Simulator Usage
-----------------------
To boot the 3B2 simulator into firmware mode, simply type:
To boot the 3B2 simulator into firmware mode, simply type:
sim> BOOT
sim> BOOT
You will be greeted with the message:
You will be greeted with the message:
FW ERROR 1-01: NVRAM SANITY FAILURE
DEFAULT VALUES ASSUMED FW ERROR 1-01: NVRAM SANITY FAILURE
IF REPEATED, CHECK THE BATTERY DEFAULT VALUES ASSUMED
IF REPEATED, CHECK THE BATTERY
FW ERROR 1-02: DISK SANITY FAILURE
EXECUTION HALTED FW ERROR 1-02: DISK SANITY FAILURE
EXECUTION HALTED
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE
NVRAM and Time of Day can be saved between boots by attaching both
devices to files. 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> 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 If you have no operating system installed on the hard drive, on
subsequent boots you will instead see the message
SELF-CHECK
SELF-CHECK
FW ERROR 1-02: DISK SANITY FAILURE
EXECUTION HALTED FW ERROR 1-02: DISK SANITY FAILURE
EXECUTION HALTED
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE
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 Once you see the `SYSTEM FAILURE` message, this is actually an
firmware password `mcp`, then press Enter or carriage return. 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:
You should then be prompted with:
Enter name of program to execute [ ]:
Enter name of program to execute [ ]:
Here, you may type a question mark (?) and press Enter to see a list
of available firmware programs. Here, you may type a question mark (?) and press Enter to see a list
of available firmware programs.
Booting UNIX SVR3
----------------- Booting UNIX SVR3 on the 3B2/400
--------------------------------
UNIX SVR3 is the only operating system available for the 3B2. To boot
UNIX, attach the first disk image from the 3B2 "Essential Utilities" UNIX System V UNIX is the only operating system available for the 3B2.
distribution. To boot UNIX, attach the first disk image from the 3B2 "Essential
Utilities" distribution.
sim> ATTACH IFLOPPY <floppy-image>
sim> BOOT 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 Once you reach the `SYSTEM FAILURE` message, type `mcp` to enter
`unix`, and confirm the boot device is `FD5` by pressing Enter or firmware mode. When prompted for the name of a program to boot, enter
carriage return. `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: Enter name of program to execute [ ]: unix
Possible load devices are:
Option Number Slot Name
--------------------------------------- Option Number Slot Name
0 0 FD5 ---------------------------------------
0 0 FD5
Enter Load Device Option Number [0 (FD5)]:
Enter Load Device Option Number [0 (FD5)]:
Installing SVR3
--------------- Installing SVR3 on the 3B2/400
------------------------------
To install SVR3 to the first hard disk, first, attach a new image
to the IDISK0 device: To install SVR3 to the first hard disk, first, attach a new image
to the IDISK0 device:
sim> ATTACH IDISK0 <hd-image>
sim> ATTACH IDISK0 <hd-image>
Then, boot the file `idtools` from the "3B2 Maintenance Utilities -
Issue 4.0" floppy diskette. 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: 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 Drive Id: 5
Number tracks/cyl: 9 Number cylinders: 925
Number sectors/track: 18 Number tracks/cyl: 9
Number bytes/sector: 512 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, After low-level formatting integrated disk 0, boot the file `unix`
and follow the prompts. 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

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,34 +0,0 @@
:: 3b2-diag.ini
:: This script will run the available 3B2/400 core diagnostics.
::
cd %~p0
set runlimit 2 minutes
set on
on error ignore
on runtime echof "\r\n*** Test Runtime Limit %SIM_RUNLIMIT% %SIM_RUNLIMIT_UNITS% Exceeded ***\n"; exit 1
set env DIAG_QUIET_MODE=0
if ("%1" == "-v") set console notelnet
else set -qu console telnet=localhost:65432,telnet=buffered; set env -a DIAG_QUIET_MODE=1
:: Set maximum memory size
set cpu 4M
if not exist rev2_diags.dsk echof "\r\nMISSING - Diagnostic disk image '%~p0rev2_diags.dsk' is missing\n"; exit 1
attach -rq ifloppy rev2_diags.dsk
:: Initial setup
expect "UTILITIES GUIDE" send "mcp\r"; go -q
expect "Enter name of program to execute [ ]:" send "filledt\r"; go -q
expect "Enter Load Device Option Number [0 (FD5)]:" send "0\r"; go -q
expect "Enter name of program to execute [ ]:" send "dgmon\r"; go -q
expect "Enter Load Device Option Number [0 (FD5)]:" send "0\r"; go -q
expect "Did you boot filledt? [y or n] (n)" send "y\r"; go -q
expect "DGMON > " send "DGN SBD\r"; go -q
expect "SBD 0 (IN SLOT 0) DIAGNOSTICS PASSED" echof; echof "PASSED: 3B2 DGMON SBD Diagnostics."; exit 0
expect [4] "FAIL" echof; echof "FAILED: 3B2 DGMON SBD Diagnostics."; exit 1
:: Run tests
if (DIAG_QUIET_MODE) echof "\nStarting 3B2 DGMON SBD Diagnostics."
boot -q CPU
return

Binary file not shown.

View file

@ -2,9 +2,9 @@
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9.00"
Name="3B2" Name="3B2-400"
ProjectGUID="{56178F08-8783-4ADA-820C-20C06412678E}" ProjectGUID="{56178F08-8783-4ADA-820C-20C06412678E}"
RootNamespace="3B2" RootNamespace="3B2-400"
Keyword="Win32Proj" Keyword="Win32Proj"
TargetFrameworkVersion="131072" TargetFrameworkVersion="131072"
> >
@ -26,7 +26,7 @@
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id" Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE ROM" CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/> />
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
@ -94,7 +94,7 @@
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
Description="Running Available Tests" Description="Running Available Tests"
CommandLine="Post-Build-Event.cmd 3B2 &quot;$(TargetDir)$(TargetName).exe&quot;" CommandLine="Post-Build-Event.cmd 3B2-400 &quot;$(TargetDir)$(TargetName).exe&quot;"
/> />
</Configuration> </Configuration>
<Configuration <Configuration
@ -107,7 +107,7 @@
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id" Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE ROM" CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/> />
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
@ -180,7 +180,7 @@
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
Description="Running Available Tests" Description="Running Available Tests"
CommandLine="Post-Build-Event.cmd 3B2 &quot;$(TargetDir)$(TargetName).exe&quot;" CommandLine="Post-Build-Event.cmd 3B2-400 &quot;$(TargetDir)$(TargetName).exe&quot;"
/> />
</Configuration> </Configuration>
</Configurations> </Configurations>
@ -220,15 +220,7 @@
> >
</File> </File>
<File <File
RelativePath="..\3B2\3b2_sys.c" RelativePath="..\3B2\3b2_mau.c"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_mau.c"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_mmu.c"
> >
</File> </File>
<File <File
@ -243,22 +235,30 @@
RelativePath="..\3B2\3b2_ports.c" RelativePath="..\3B2\3b2_ports.c"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_rev2_sys.c"
>
</File>
<File <File
RelativePath="..\3B2\3b2_rev2_csr.c" RelativePath="..\3B2\3b2_rev2_csr.c"
> >
</File> </File>
<File <File
RelativePath="..\3B2\3b2_rev2_timer.c" RelativePath="..\3B2\3b2_rev2_mmu.c"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_sys.c"
> >
</File> </File>
<File <File
RelativePath="..\3B2\3b2_stddev.c" RelativePath="..\3B2\3b2_stddev.c"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_sys.c"
>
</File>
<File
RelativePath="..\3B2\3b2_timer.c"
>
</File>
<File <File
RelativePath="..\..\windows-build\pthreads\pthread.c" RelativePath="..\..\windows-build\pthreads\pthread.c"
> >
@ -499,6 +499,10 @@
RelativePath="..\3B2\3b2_cpu.h" RelativePath="..\3B2\3b2_cpu.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_csr.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_ctc.h" RelativePath="..\3B2\3b2_ctc.h"
> >
@ -507,10 +511,6 @@
RelativePath="..\3B2\3b2_defs.h" RelativePath="..\3B2\3b2_defs.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_rev2_defs.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_dmac.h" RelativePath="..\3B2\3b2_dmac.h"
> >
@ -532,21 +532,17 @@
> >
</File> </File>
<File <File
RelativePath="..\3B2\3b2_sys.h" RelativePath="..\3B2\3b2_mau.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_mau.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_mmu.h"
> >
</File> </File>
<File <File
RelativePath="..\3B2\3b2_mem.h" RelativePath="..\3B2\3b2_mem.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_mmu.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_ni.h" RelativePath="..\3B2\3b2_ni.h"
> >
@ -555,22 +551,18 @@
RelativePath="..\3B2\3b2_ports.h" RelativePath="..\3B2\3b2_ports.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_rev2_sys.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_csr.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_timer.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_stddev.h" RelativePath="..\3B2\3b2_stddev.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_sys.h"
>
</File>
<File
RelativePath="..\3B2\3b2_timer.h"
>
</File>
<File <File
RelativePath="..\scp.h" RelativePath="..\scp.h"
> >

View file

@ -2,9 +2,9 @@
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9.00"
Name="3B2-600" Name="3B2-700"
ProjectGUID="{A7AE7747-DFA0-49F5-9D6C-9094657A8EE3}" ProjectGUID="{A7AE7747-DFA0-49F5-9D6C-9094657A8EE3}"
RootNamespace="3B2-600" RootNamespace="3B2-700"
Keyword="Win32Proj" Keyword="Win32Proj"
TargetFrameworkVersion="131072" TargetFrameworkVersion="131072"
> >
@ -26,7 +26,7 @@
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id" Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE ROM" CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/> />
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
@ -94,7 +94,7 @@
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
Description="Running Available Tests" Description="Running Available Tests"
CommandLine="Post-Build-Event.cmd 3B2-600 &quot;$(TargetDir)$(TargetName).exe&quot;" CommandLine="Post-Build-Event.cmd 3B2-700 &quot;$(TargetDir)$(TargetName).exe&quot;"
/> />
</Configuration> </Configuration>
<Configuration <Configuration
@ -107,7 +107,7 @@
<Tool <Tool
Name="VCPreBuildEventTool" Name="VCPreBuildEventTool"
Description="Check for required build dependencies &amp; git commit id" Description="Check for required build dependencies &amp; git commit id"
CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE ROM" CommandLine="Pre-Build-Event.cmd &quot;$(TargetDir)$(TargetName).exe&quot; LIBPCRE"
/> />
<Tool <Tool
Name="VCCustomBuildTool" Name="VCCustomBuildTool"
@ -180,7 +180,7 @@
<Tool <Tool
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
Description="Running Available Tests" Description="Running Available Tests"
CommandLine="Post-Build-Event.cmd 3B2-600 &quot;$(TargetDir)$(TargetName).exe&quot;" CommandLine="Post-Build-Event.cmd 3B2-700 &quot;$(TargetDir)$(TargetName).exe&quot;"
/> />
</Configuration> </Configuration>
</Configurations> </Configurations>
@ -211,6 +211,10 @@
RelativePath="..\3B2\3b2_iu.c" RelativePath="..\3B2\3b2_iu.c"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_mau.c"
>
</File>
<File <File
RelativePath="..\3B2\3b2_mem.c" RelativePath="..\3B2\3b2_mem.c"
> >
@ -223,10 +227,6 @@
RelativePath="..\3B2\3b2_ports.c" RelativePath="..\3B2\3b2_ports.c"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_rev2_mau.c"
>
</File>
<File <File
RelativePath="..\3B2\3b2_rev3_csr.c" RelativePath="..\3B2\3b2_rev3_csr.c"
> >
@ -239,10 +239,6 @@
RelativePath="..\3B2\3b2_rev3_sys.c" RelativePath="..\3B2\3b2_rev3_sys.c"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_rev3_timer.c"
>
</File>
<File <File
RelativePath="..\3B2\3b2_scsi.c" RelativePath="..\3B2\3b2_scsi.c"
> >
@ -255,6 +251,10 @@
RelativePath="..\3B2\3b2_sys.c" RelativePath="..\3B2\3b2_sys.c"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_timer.c"
>
</File>
<File <File
RelativePath="..\..\windows-build\pthreads\pthread.c" RelativePath="..\..\windows-build\pthreads\pthread.c"
> >
@ -500,7 +500,7 @@
> >
</File> </File>
<File <File
RelativePath="..\3B2\3b2_ctc.h" RelativePath="..\3B2\3b2_csr.h"
> >
</File> </File>
<File <File
@ -527,10 +527,18 @@
RelativePath="..\3B2\3b2_iu.h" RelativePath="..\3B2\3b2_iu.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_mau.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_mem.h" RelativePath="..\3B2\3b2_mem.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_mmu.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_ni.h" RelativePath="..\3B2\3b2_ni.h"
> >
@ -539,30 +547,6 @@
RelativePath="..\3B2\3b2_ports.h" RelativePath="..\3B2\3b2_ports.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_rev3_csr.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev3_defs.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev2_mau.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev3_mmu.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev3_sys.h"
>
</File>
<File
RelativePath="..\3B2\3b2_rev3_timer.h"
>
</File>
<File <File
RelativePath="..\3B2\3b2_stddev.h" RelativePath="..\3B2\3b2_stddev.h"
> >
@ -571,6 +555,10 @@
RelativePath="..\3B2\3b2_sys.h" RelativePath="..\3B2\3b2_sys.h"
> >
</File> </File>
<File
RelativePath="..\3B2\3b2_timer.h"
>
</File>
<File <File
RelativePath="..\scp.h" RelativePath="..\scp.h"
> >

View file

@ -228,7 +228,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scelbi", "scelbi.vcproj", "
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2", "3B2.vcproj", "{56178F08-8783-4ADA-820C-20C06412678E}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2-400", "3B2-400.vcproj", "{56178F08-8783-4ADA-820C-20C06412678E}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection EndProjectSection
@ -373,7 +373,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tt2500", "tt2500.vcproj", "
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection EndProjectSection
EndProject EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2-600", "3B2-600.vcproj", "{A7AE7747-DFA0-49F5-9D6C-9094657A8EE3}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "3B2-700", "3B2-700.vcproj", "{A7AE7747-DFA0-49F5-9D6C-9094657A8EE3}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8} {D40F3AF1-EEE7-4432-9807-2AD287B490F8} = {D40F3AF1-EEE7-4432-9807-2AD287B490F8}
EndProjectSection EndProjectSection

View file

@ -2066,25 +2066,25 @@ KS10_OPT = -DKS=1 -DUSE_INT64 -I $(KS10D) -I $(PDP11D) ${NETWORK_OPT}
ATT3B2D = ${SIMHD}/3B2 ATT3B2D = ${SIMHD}/3B2
ATT3B2M400 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \ ATT3B2M400 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \
${ATT3B2D}/3b2_rev2_sys.c ${ATT3B2D}/3b2_rev2_mmu.c \ ${ATT3B2D}/3b2_rev2_sys.c ${ATT3B2D}/3b2_rev2_mmu.c \
${ATT3B2D}/3b2_rev2_mau.c ${ATT3B2D}/3b2_rev2_csr.c \ ${ATT3B2D}/3b2_mau.c ${ATT3B2D}/3b2_rev2_csr.c \
${ATT3B2D}/3b2_rev2_timer.c ${ATT3B2D}/3b2_stddev.c \ ${ATT3B2D}/3b2_timer.c ${ATT3B2D}/3b2_stddev.c \
${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \ ${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \
${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_id.c \ ${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_id.c \
${ATT3B2D}/3b2_dmac.c ${ATT3B2D}/3b2_io.c \ ${ATT3B2D}/3b2_dmac.c ${ATT3B2D}/3b2_io.c \
${ATT3B2D}/3b2_ports.c ${ATT3B2D}/3b2_ctc.c \ ${ATT3B2D}/3b2_ports.c ${ATT3B2D}/3b2_ctc.c \
${ATT3B2D}/3b2_ni.c ${ATT3B2D}/3b2_ni.c
ATT3B2M400_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV2 -I ${ATT3B2D} ${NETWORK_OPT} ATT3B2M400_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV2 -I ${ATT3B2D} ${NETWORK_OPT}
ATT3B2M600 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \ ATT3B2M700 = ${ATT3B2D}/3b2_cpu.c ${ATT3B2D}/3b2_sys.c \
${ATT3B2D}/3b2_rev3_sys.c ${ATT3B2D}/3b2_rev3_mmu.c \ ${ATT3B2D}/3b2_rev3_sys.c ${ATT3B2D}/3b2_rev3_mmu.c \
${ATT3B2D}/3b2_rev2_mau.c ${ATT3B2D}/3b2_rev3_csr.c \ ${ATT3B2D}/3b2_mau.c ${ATT3B2D}/3b2_rev3_csr.c \
${ATT3B2D}/3b2_rev3_timer.c ${ATT3B2D}/3b2_stddev.c \ ${ATT3B2D}/3b2_timer.c ${ATT3B2D}/3b2_stddev.c \
${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \ ${ATT3B2D}/3b2_mem.c ${ATT3B2D}/3b2_iu.c \
${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_dmac.c \ ${ATT3B2D}/3b2_if.c ${ATT3B2D}/3b2_dmac.c \
${ATT3B2D}/3b2_io.c ${ATT3B2D}/3b2_ports.c \ ${ATT3B2D}/3b2_io.c ${ATT3B2D}/3b2_ports.c \
${ATT3B2D}/3b2_scsi.c ${ATT3B2D}/3b2_ni.c ${ATT3B2D}/3b2_scsi.c ${ATT3B2D}/3b2_ni.c
ATT3B2M600_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV3 -I ${ATT3B2D} ${NETWORK_OPT} ATT3B2M700_OPT = -DUSE_INT64 -DUSE_ADDR64 -DREV3 -I ${ATT3B2D} ${NETWORK_OPT}
SIGMAD = ${SIMHD}/sigma SIGMAD = ${SIMHD}/sigma
SIGMA = ${SIGMAD}/sigma_cpu.c ${SIGMAD}/sigma_sys.c ${SIGMAD}/sigma_cis.c \ SIGMA = ${SIGMAD}/sigma_cpu.c ${SIGMAD}/sigma_sys.c ${SIGMAD}/sigma_cis.c \
@ -2155,13 +2155,13 @@ ALL = pdp1 pdp4 pdp7 pdp8 pdp9 pdp15 pdp11 pdp10 \
nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \ nova eclipse hp2100 hp3000 i1401 i1620 s3 altair altairz80 gri \
i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \ i7094 ibm1130 id16 id32 sds lgp h316 cdc1700 \
swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 intel-mds \ swtp6800mp-a swtp6800mp-a2 tx-0 ssem b5500 intel-mds \
scelbi 3b2 i701 i704 i7010 i7070 i7080 i7090 \ scelbi 3b2 3b2-700 i701 i704 i7010 i7070 i7080 i7090 \
sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 i650 \ sigma uc15 pdp10-ka pdp10-ki pdp10-kl pdp10-ks pdp6 i650 \
imlac tt2500 sel32 imlac tt2500 sel32
all : ${ALL} all : ${ALL}
EXPERIMENTAL = cdc1700 3b2-600 EXPERIMENTAL = cdc1700
experimental : ${EXPERIMENTAL} experimental : ${EXPERIMENTAL}
@ -2806,22 +2806,29 @@ ifneq (,$(call find_test,${B5500D},b5500))
$@ $(call find_test,${B5500D},b5500) ${TEST_ARG} $@ $(call find_test,${B5500D},b5500) ${TEST_ARG}
endif endif
3b2-400 : 3b2
3b2 : ${BIN}3b2${EXE} 3b2 : ${BIN}3b2${EXE}
${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM} ${BUILD_ROMS} ${BIN}3b2${EXE} : ${ATT3B2M400} ${SIM}
${MKDIRBIN} ${MKDIRBIN}
${CC} ${ATT3B2M400} ${SIM} ${ATT3B2M400_OPT} ${CC_OUTSPEC} ${LDFLAGS} ${CC} ${ATT3B2M400} ${SIM} ${ATT3B2M400_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifeq (${WIN32},)
cp ${BIN}3b2${EXE} ${BIN}3b2-400${EXE}
else
copy $(@D)\3b2${EXE} $(@D)\3b2-400${EXE}
endif
ifneq (,$(call find_test,${ATT3B2D},3b2)) ifneq (,$(call find_test,${ATT3B2D},3b2))
$@ $(call find_test,${ATT3B2D},3b2) ${TEST_ARG} $@ $(call find_test,${ATT3B2D},3b2) ${TEST_ARG}
endif endif
3b2-600 : ${BIN}3b2-600${EXE} 3b2-700 : ${BIN}3b2-700${EXE}
${BIN}3b2-600${EXE} : ${ATT3B2M600} ${SIM} ${BUILD_ROMS} ${BIN}3b2-700${EXE} : ${ATT3B2M700} ${SIM}
${MKDIRBIN} ${MKDIRBIN}
${CC} ${ATT3B2M600} ${SCSI} ${SIM} ${ATT3B2M600_OPT} ${CC_OUTSPEC} ${LDFLAGS} ${CC} ${ATT3B2M700} ${SCSI} ${SIM} ${ATT3B2M700_OPT} ${CC_OUTSPEC} ${LDFLAGS}
ifneq (,$(call find_test,${ATT3B2D},3b2-600)) ifneq (,$(call find_test,${ATT3B2D},3b2-700))
$@ $(call find_test,${ATT3B2D},3b2-600) ${TEST_ARG} $@ $(call find_test,${ATT3B2D},3b2-700) ${TEST_ARG}
endif endif
i7090 : ${BIN}i7090${EXE} i7090 : ${BIN}i7090${EXE}

View file

@ -70,9 +70,6 @@ struct ROM_File_Descriptor {
{"PDP11/dazzledart/dazzle.lda", "PDP11/pdp11_dazzle_dart_rom.h", 6096, 0xFFF83848, "dazzle_lda"}, {"PDP11/dazzledart/dazzle.lda", "PDP11/pdp11_dazzle_dart_rom.h", 6096, 0xFFF83848, "dazzle_lda"},
{"PDP11/11logo/11logo.lda", "PDP11/pdp11_11logo_rom.h", 26009, 0xFFDD77F7, "logo_lda"}, {"PDP11/11logo/11logo.lda", "PDP11/pdp11_11logo_rom.h", 26009, 0xFFDD77F7, "logo_lda"},
{"swtp6800/swtp6800/swtbugv10.bin", "swtp6800/swtp6800/swtp_swtbugv10_bin.h", 1024, 0xFFFE4FBC, "swtp_swtbugv10_bin"}, {"swtp6800/swtp6800/swtbugv10.bin", "swtp6800/swtp6800/swtp_swtbugv10_bin.h", 1024, 0xFFFE4FBC, "swtp_swtbugv10_bin"},
{"3B2/rom_rev2.bin", "3B2/rom_rev2_bin.h", 32768, 0xFFD55762, "rom_rev2_bin"},
{"3B2/rom_rev2_demon.bin", "3B2/rom_rev2_demon_bin.h", 65536, 0xFFB345BB, "rom_rev2_demon_bin"},
{"3B2/rom_rev3.bin", "3B2/rom_rev3_bin.h", 131072, 0xFFDC0EB8, "rom_rev3_bin"},
}; };

View file

@ -490,6 +490,9 @@ scsi_set_req (bus); /* request to send data
void scsi_mode_sel6 (SCSI_BUS *bus, uint8 *data, uint32 len) void scsi_mode_sel6 (SCSI_BUS *bus, uint8 *data, uint32 len)
{ {
UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
uint32 blk_size;
if (bus->phase == SCSI_CMD) { if (bus->phase == SCSI_CMD) {
scsi_debug_cmd (bus, "Mode Select(6) - CMD\n"); scsi_debug_cmd (bus, "Mode Select(6) - CMD\n");
memcpy (&bus->cmd[0], &data[0], 6); memcpy (&bus->cmd[0], &data[0], 6);
@ -499,9 +502,24 @@ if (bus->phase == SCSI_CMD) {
} }
else if (bus->phase == SCSI_DATO) { else if (bus->phase == SCSI_DATO) {
scsi_debug_cmd (bus, "Mode Select(6) - DATO\n"); scsi_debug_cmd (bus, "Mode Select(6) - DATO\n");
/* Not currently implemented so just return if (dev->devtype == SCSI_TAPE && uptr->flags & SCSI_QIC) {
good status for now */ blk_size = ((uint32)bus->buf[9]) << 16 |
scsi_status (bus, STS_OK, KEY_OK, ASC_OK); ((uint32)bus->buf[10]) << 8 |
(uint32)bus->buf[11];
/* QIC tape ONLY supports requesting a fixed block size of
* 0x200 bytes. Any other block size will cause an illegal
* request. */
if (blk_size == SCSI_QIC_BLKSZ) {
scsi_status(bus, STS_OK, KEY_OK, ASC_OK);
}
else {
scsi_status(bus, STS_CHK, KEY_ILLREQ|KEY_M_ILI, ASC_INVCDB);
}
}
else {
/* Not implemented for disk and non-QIC tape */
scsi_status(bus, STS_OK, KEY_OK, ASC_OK);
}
} }
} }
@ -784,8 +802,9 @@ void scsi_read6_tape (SCSI_BUS *bus, uint8 *data, uint32 len)
{ {
UNIT *uptr = bus->dev[bus->target]; UNIT *uptr = bus->dev[bus->target];
SCSI_DEV *dev = (SCSI_DEV *)uptr->up7; SCSI_DEV *dev = (SCSI_DEV *)uptr->up7;
t_seccnt sects, sectsread; t_seccnt sects, sectsread, new_buf_b;
t_stat r; t_stat r;
uint32 i;
if ((data[1] & 0x3) == 0x3) { /* SILI and FIXED? */ if ((data[1] & 0x3) == 0x3) { /* SILI and FIXED? */
scsi_status (bus, STS_CHK, KEY_ILLREQ, ASC_INVCDB); scsi_status (bus, STS_CHK, KEY_ILLREQ, ASC_INVCDB);
@ -793,6 +812,7 @@ if ((data[1] & 0x3) == 0x3) { /* SILI and FIXED? */
} }
sects = GETW (data, 3) | (data[2] << 16); sects = GETW (data, 3) | (data[2] << 16);
new_buf_b = 0;
sectsread = 0; sectsread = 0;
if (sects == 0) { /* no data to read */ if (sects == 0) { /* no data to read */
@ -803,35 +823,64 @@ if (sects == 0) { /* no data to read */
scsi_debug_cmd (bus, "Read(6) blks %d fixed %d\n", sects, (data[1] & 0x1)); scsi_debug_cmd (bus, "Read(6) blks %d fixed %d\n", sects, (data[1] & 0x1));
if (uptr->flags & UNIT_ATT) { if (uptr->flags & UNIT_ATT) {
if (data[1] & 0x1) { if (uptr->flags & SCSI_QIC) {
r = sim_tape_rdrecf (uptr, &bus->buf[0], &sectsread, (sects * dev->block_size)); if (data[1] & 0x1) {
scsi_debug_cmd (bus, "Read tape blk %d, read %d, r = %d\n", sects, sectsread, r); /* If this is a QIC tape drive and bit 0 is set, this is a
request to read multiple fixed-length blocks. */
scsi_debug_cmd(bus, "QIC in fixed block mode\n");
for (i = 0; i < sects; i++) {
r = sim_tape_rdrecf(uptr, &bus->buf[new_buf_b], &sectsread, SCSI_QIC_BLKSZ);
scsi_debug_cmd(bus, "Read tape blk %d, read %d, r = %d\n",
sects, sectsread, r);
if (r == MTSE_OK) {
new_buf_b += SCSI_QIC_BLKSZ;
} else {
scsi_tape_status(bus, r);
scsi_status(bus, bus->status, bus->sense_key, bus->sense_code);
return;
}
}
} else {
/* QIC drives respond with an illegal request when the
request does not specify fixed-block mode */
scsi_debug_cmd(bus, "QIC not in fixed block mode, invalid command\n");
scsi_status(bus, STS_CHK, KEY_ILLREQ|KEY_M_ILI, ASC_INVCDB);
return;
}
} }
else { else {
r = sim_tape_rdrecf (uptr, &bus->buf[0], &sectsread, sects); /* Otherwise, this is a normal streaming tape read */
scsi_debug_cmd (bus, "Read tape max %d, read %d, r = %d\n", sects, sectsread, r); if (data[1] & 0x1) {
if (r == MTSE_INVRL) { /* overlength condition */ r = sim_tape_rdrecf (uptr, &bus->buf[0], &sectsread, (sects * dev->block_size));
scsi_debug_cmd (bus, "Overlength\n"); scsi_debug_cmd (bus, "Read tape blk %d, read %d, r = %d\n", sects, sectsread, r);
if ((data[1] & 0x2) && (dev->block_size == 0)) { /* SILI set */ }
scsi_debug_cmd (bus, "SILI set\n"); else {
r = sim_tape_rdrecf (uptr, &bus->buf[0], &sectsread, sects);
scsi_debug_cmd (bus, "Read tape max %d, read %d, r = %d\n", sects, sectsread, r);
if (r == MTSE_INVRL) { /* overlength condition */
scsi_debug_cmd (bus, "Overlength\n");
if ((data[1] & 0x2) && (dev->block_size == 0)) { /* SILI set */
scsi_debug_cmd (bus, "SILI set\n");
}
else {
scsi_debug_cmd (bus, "SILI not set - check condition\n");
scsi_status (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK);
return;
}
} }
else { else if ((r == MTSE_OK) && (sectsread < sects)) { /* underlength condition */
scsi_debug_cmd (bus, "SILI not set - check condition\n"); scsi_debug_cmd (bus, "Underlength\n");
scsi_status (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK); if (data[1] & 0x2) { /* SILI set */
return; scsi_debug_cmd (bus, "SILI set\n");
} }
} else {
else if ((r == MTSE_OK) && (sectsread < sects)) { /* underlength condition */ scsi_debug_cmd (bus, "SILI not set - check condition\n");
scsi_debug_cmd (bus, "Underlength\n"); scsi_status_deferred (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK);
if (data[1] & 0x2) { /* SILI set */ bus->sense_info = (sects - sectsread);
scsi_debug_cmd (bus, "SILI set\n"); }
}
else {
scsi_debug_cmd (bus, "SILI not set - check condition\n");
scsi_status_deferred (bus, STS_CHK, (KEY_OK | KEY_M_ILI), ASC_OK);
bus->sense_info = (sects - sectsread);
} }
} }
new_buf_b = sectsread;
} }
if (r != MTSE_OK) { if (r != MTSE_OK) {
@ -845,7 +894,7 @@ else {
} }
if (sectsread > 0) { if (sectsread > 0) {
bus->buf_b = sectsread; bus->buf_b = new_buf_b;
scsi_set_phase (bus, SCSI_DATI); /* data in phase next */ scsi_set_phase (bus, SCSI_DATI); /* data in phase next */
} }
else { else {

View file

@ -68,10 +68,13 @@
#define SCSI_DBG_TAP 0x10000000 /* tape activity */ #define SCSI_DBG_TAP 0x10000000 /* tape activity */
#define SCSI_V_NOAUTO ((DKUF_V_UF > MTUF_V_UF) ? DKUF_V_UF : MTUF_V_UF)/* noautosize */ #define SCSI_V_NOAUTO ((DKUF_V_UF > MTUF_V_UF) ? DKUF_V_UF : MTUF_V_UF)/* noautosize */
#define SCSI_V_UF (SCSI_V_NOAUTO + 1) #define SCSI_V_QIC (SCSI_V_NOAUTO + 1)
#define SCSI_V_UF (SCSI_V_QIC + 1)
#define SCSI_QIC (1 << SCSI_V_QIC)
#define SCSI_WLK (UNIT_WLK|UNIT_RO) /* hwre write lock */ #define SCSI_WLK (UNIT_WLK|UNIT_RO) /* hwre write lock */
#define SCSI_NOAUTO DKUF_NOAUTOSIZE #define SCSI_NOAUTO DKUF_NOAUTOSIZE
#define SCSI_QIC_BLKSZ 0x200
struct scsi_dev_t { struct scsi_dev_t {
uint8 devtype; /* device type */ uint8 devtype; /* device type */