3b2: Update README.md and correct line endings
This change updates the 3B2 README.md file, and fixes all line endings on 3B2 source files.
This commit is contained in:
parent
75aefcb75c
commit
84bf5f4d14
46 changed files with 25752 additions and 25833 deletions
9756
3B2/3b2_cpu.c
9756
3B2/3b2_cpu.c
File diff suppressed because it is too large
Load diff
1368
3B2/3b2_cpu.h
1368
3B2/3b2_cpu.h
File diff suppressed because it is too large
Load diff
|
@ -1,46 +1,46 @@
|
|||
/* 3b2_csr.h: Common CSR/CSER header
|
||||
|
||||
Copyright (c) 2021-2022, 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_CSR_H_
|
||||
#define _3B2_CSR_H_
|
||||
|
||||
#if defined(REV3)
|
||||
#include "3b2_rev3_csr.h"
|
||||
#else
|
||||
#include "3b2_rev2_csr.h"
|
||||
#endif
|
||||
|
||||
#define SET_CSR(FLAGS) (csr_data |= (FLAGS))
|
||||
#define CLR_CSR(FLAGS) (csr_data &= ~(FLAGS))
|
||||
#define CSR(FLAGS) ((csr_data & FLAGS) != 0)
|
||||
|
||||
extern CSR_DATA csr_data;
|
||||
|
||||
#endif /* _3B2_CSR_H_ */
|
||||
/* 3b2_csr.h: Common CSR/CSER header
|
||||
|
||||
Copyright (c) 2021-2022, 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_CSR_H_
|
||||
#define _3B2_CSR_H_
|
||||
|
||||
#if defined(REV3)
|
||||
#include "3b2_rev3_csr.h"
|
||||
#else
|
||||
#include "3b2_rev2_csr.h"
|
||||
#endif
|
||||
|
||||
#define SET_CSR(FLAGS) (csr_data |= (FLAGS))
|
||||
#define CLR_CSR(FLAGS) (csr_data &= ~(FLAGS))
|
||||
#define CSR(FLAGS) ((csr_data & FLAGS) != 0)
|
||||
|
||||
extern CSR_DATA csr_data;
|
||||
|
||||
#endif /* _3B2_CSR_H_ */
|
||||
|
|
1496
3B2/3b2_ctc.c
1496
3B2/3b2_ctc.c
File diff suppressed because it is too large
Load diff
306
3B2/3b2_ctc.h
306
3B2/3b2_ctc.h
|
@ -1,153 +1,153 @@
|
|||
/* 3b2_ctc.h: CM195H 23MB Cartridge Tape Controller CIO Card
|
||||
|
||||
Copyright (c) 2018-2022, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CTC is an intelligent feature card for the 3B2 that supports a
|
||||
* Cipher "FloppyTape(tm)" 525 drive that can read and write 23MB
|
||||
* DC600A cartridges.
|
||||
*
|
||||
* The CTC card is based on the Common I/O (CIO) platform.
|
||||
*
|
||||
* Notes:
|
||||
* ------
|
||||
*
|
||||
* 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
|
||||
* sectors that can be addressed by Cylinder / Track / Sector.
|
||||
* Stepping and head select pulses dictate where on the tape to read
|
||||
* from or write to. Moreover, System V maps a filesystem onto the
|
||||
* tape, and a properly formatted tape drive will have a VTOC on
|
||||
* partition 0.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _3B2_CTC_H_
|
||||
#define _3B2_CTC_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define CTC_ID 0x0005
|
||||
#define CTC_IPL 12
|
||||
#define CTC_VERSION 1
|
||||
|
||||
/* Request Opcodes */
|
||||
#define CTC_CONFIG 30
|
||||
#define CTC_CLOSE 31
|
||||
#define CTC_FORMAT 32
|
||||
#define CTC_OPEN 33
|
||||
#define CTC_READ 34
|
||||
#define CTC_WRITE 35
|
||||
#define CTC_VWRITE 36
|
||||
|
||||
/* Completion Opcodes */
|
||||
#define CTC_SUCCESS 0
|
||||
#define CTC_HWERROR 32
|
||||
#define CTC_RDONLY 33
|
||||
#define CTC_NOTREADY 36
|
||||
#define CTC_RWERROR 37
|
||||
#define CTC_NOMEDIA 42
|
||||
|
||||
/* VTOC values */
|
||||
#define VTOC_VERSION 1
|
||||
#define VTOC_SECSZ 512
|
||||
#define VTOC_PART 16 /* Number of "partitions" on tape */
|
||||
#define VTOC_VALID 0x600DDEEE /* Magic number for valid VTOC */
|
||||
|
||||
#define CTC_NUM_SD 2
|
||||
#define CTC_SD_FT25 4
|
||||
#define CTC_SD_FD5 1
|
||||
|
||||
/* Physical Device Info (pdinfo) values */
|
||||
#define PD_VALID 0xCA5E600D /* Magic number for valid PDINFO */
|
||||
#define PD_DRIVEID 5
|
||||
#define PD_VERSION 0
|
||||
#define PD_CYLS 6
|
||||
#define PD_TRACKS 245
|
||||
#define PD_SECTORS 31
|
||||
#define PD_BYTES 512
|
||||
#define PD_LOGICALST 29
|
||||
|
||||
#define CTC_CAPACITY (PD_CYLS * PD_TRACKS * PD_SECTORS) /* In blocks */
|
||||
|
||||
struct partition {
|
||||
uint16 id; /* Partition ID */
|
||||
uint16 flag; /* Permission Flags */
|
||||
uint32 sstart; /* Starting Sector */
|
||||
uint32 ssize; /* Size in Sectors */
|
||||
};
|
||||
|
||||
struct vtoc {
|
||||
uint32 bootinfo[3]; /* n/a */
|
||||
uint32 sanity; /* magic number */
|
||||
uint32 version; /* layout version */
|
||||
uint8 volume[8]; /* volume name */
|
||||
uint16 sectorsz; /* sector size in bytes */
|
||||
uint16 nparts; /* number of partitions */
|
||||
uint32 reserved[10]; /* free space */
|
||||
struct partition part[VTOC_PART]; /* partition headers */
|
||||
uint32 timestamp[VTOC_PART]; /* partition timestamp */
|
||||
};
|
||||
|
||||
struct pdinfo {
|
||||
uint32 driveid; /* identifies the device type */
|
||||
uint32 sanity; /* verifies device sanity */
|
||||
uint32 version; /* version number */
|
||||
uint8 serial[12]; /* serial number of the device */
|
||||
uint32 cyls; /* number of cylinders per drive */
|
||||
uint32 tracks; /* number tracks per cylinder */
|
||||
uint32 sectors; /* number sectors per track */
|
||||
uint32 bytes; /* number of bytes per sector */
|
||||
uint32 logicalst; /* sector address of logical sector 0 */
|
||||
uint32 errlogst; /* sector address of error log area */
|
||||
uint32 errlogsz; /* size in bytes of error log area */
|
||||
uint32 mfgst; /* sector address of mfg. defect info */
|
||||
uint32 mfgsz; /* size in bytes of mfg. defect info */
|
||||
uint32 defectst; /* sector address of the defect map */
|
||||
uint32 defectsz; /* size in bytes of defect map */
|
||||
uint32 relno; /* number of relocation areas */
|
||||
uint32 relst; /* sector address of relocation area */
|
||||
uint32 relsz; /* size in sectors of relocation area */
|
||||
uint32 relnext; /* address of next avail reloc sector */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32 time; /* Time used during a tape session (in 25ms chunks) */
|
||||
uint32 bytnum; /* Byte number, for streaming mode */
|
||||
} CTC_STATE;
|
||||
|
||||
t_stat ctc_reset(DEVICE *dptr);
|
||||
t_stat ctc_svc(UNIT *uptr);
|
||||
t_stat ctc_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat ctc_detach(UNIT *uptr);
|
||||
void ctc_sysgen(uint8 slot);
|
||||
void ctc_express(uint8 slot);
|
||||
void ctc_full(uint8 slot);
|
||||
|
||||
#endif /* _3B2_CTC_H_ */
|
||||
/* 3b2_ctc.h: CM195H 23MB Cartridge Tape Controller CIO Card
|
||||
|
||||
Copyright (c) 2018-2022, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* CTC is an intelligent feature card for the 3B2 that supports a
|
||||
* Cipher "FloppyTape(tm)" 525 drive that can read and write 23MB
|
||||
* DC600A cartridges.
|
||||
*
|
||||
* The CTC card is based on the Common I/O (CIO) platform.
|
||||
*
|
||||
* Notes:
|
||||
* ------
|
||||
*
|
||||
* 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
|
||||
* sectors that can be addressed by Cylinder / Track / Sector.
|
||||
* Stepping and head select pulses dictate where on the tape to read
|
||||
* from or write to. Moreover, System V maps a filesystem onto the
|
||||
* tape, and a properly formatted tape drive will have a VTOC on
|
||||
* partition 0.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _3B2_CTC_H_
|
||||
#define _3B2_CTC_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define CTC_ID 0x0005
|
||||
#define CTC_IPL 12
|
||||
#define CTC_VERSION 1
|
||||
|
||||
/* Request Opcodes */
|
||||
#define CTC_CONFIG 30
|
||||
#define CTC_CLOSE 31
|
||||
#define CTC_FORMAT 32
|
||||
#define CTC_OPEN 33
|
||||
#define CTC_READ 34
|
||||
#define CTC_WRITE 35
|
||||
#define CTC_VWRITE 36
|
||||
|
||||
/* Completion Opcodes */
|
||||
#define CTC_SUCCESS 0
|
||||
#define CTC_HWERROR 32
|
||||
#define CTC_RDONLY 33
|
||||
#define CTC_NOTREADY 36
|
||||
#define CTC_RWERROR 37
|
||||
#define CTC_NOMEDIA 42
|
||||
|
||||
/* VTOC values */
|
||||
#define VTOC_VERSION 1
|
||||
#define VTOC_SECSZ 512
|
||||
#define VTOC_PART 16 /* Number of "partitions" on tape */
|
||||
#define VTOC_VALID 0x600DDEEE /* Magic number for valid VTOC */
|
||||
|
||||
#define CTC_NUM_SD 2
|
||||
#define CTC_SD_FT25 4
|
||||
#define CTC_SD_FD5 1
|
||||
|
||||
/* Physical Device Info (pdinfo) values */
|
||||
#define PD_VALID 0xCA5E600D /* Magic number for valid PDINFO */
|
||||
#define PD_DRIVEID 5
|
||||
#define PD_VERSION 0
|
||||
#define PD_CYLS 6
|
||||
#define PD_TRACKS 245
|
||||
#define PD_SECTORS 31
|
||||
#define PD_BYTES 512
|
||||
#define PD_LOGICALST 29
|
||||
|
||||
#define CTC_CAPACITY (PD_CYLS * PD_TRACKS * PD_SECTORS) /* In blocks */
|
||||
|
||||
struct partition {
|
||||
uint16 id; /* Partition ID */
|
||||
uint16 flag; /* Permission Flags */
|
||||
uint32 sstart; /* Starting Sector */
|
||||
uint32 ssize; /* Size in Sectors */
|
||||
};
|
||||
|
||||
struct vtoc {
|
||||
uint32 bootinfo[3]; /* n/a */
|
||||
uint32 sanity; /* magic number */
|
||||
uint32 version; /* layout version */
|
||||
uint8 volume[8]; /* volume name */
|
||||
uint16 sectorsz; /* sector size in bytes */
|
||||
uint16 nparts; /* number of partitions */
|
||||
uint32 reserved[10]; /* free space */
|
||||
struct partition part[VTOC_PART]; /* partition headers */
|
||||
uint32 timestamp[VTOC_PART]; /* partition timestamp */
|
||||
};
|
||||
|
||||
struct pdinfo {
|
||||
uint32 driveid; /* identifies the device type */
|
||||
uint32 sanity; /* verifies device sanity */
|
||||
uint32 version; /* version number */
|
||||
uint8 serial[12]; /* serial number of the device */
|
||||
uint32 cyls; /* number of cylinders per drive */
|
||||
uint32 tracks; /* number tracks per cylinder */
|
||||
uint32 sectors; /* number sectors per track */
|
||||
uint32 bytes; /* number of bytes per sector */
|
||||
uint32 logicalst; /* sector address of logical sector 0 */
|
||||
uint32 errlogst; /* sector address of error log area */
|
||||
uint32 errlogsz; /* size in bytes of error log area */
|
||||
uint32 mfgst; /* sector address of mfg. defect info */
|
||||
uint32 mfgsz; /* size in bytes of mfg. defect info */
|
||||
uint32 defectst; /* sector address of the defect map */
|
||||
uint32 defectsz; /* size in bytes of defect map */
|
||||
uint32 relno; /* number of relocation areas */
|
||||
uint32 relst; /* sector address of relocation area */
|
||||
uint32 relsz; /* size in sectors of relocation area */
|
||||
uint32 relnext; /* address of next avail reloc sector */
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32 time; /* Time used during a tape session (in 25ms chunks) */
|
||||
uint32 bytnum; /* Byte number, for streaming mode */
|
||||
} CTC_STATE;
|
||||
|
||||
t_stat ctc_reset(DEVICE *dptr);
|
||||
t_stat ctc_svc(UNIT *uptr);
|
||||
t_stat ctc_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat ctc_detach(UNIT *uptr);
|
||||
void ctc_sysgen(uint8 slot);
|
||||
void ctc_express(uint8 slot);
|
||||
void ctc_full(uint8 slot);
|
||||
|
||||
#endif /* _3B2_CTC_H_ */
|
||||
|
|
332
3B2/3b2_defs.h
332
3B2/3b2_defs.h
|
@ -1,166 +1,166 @@
|
|||
/* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions
|
||||
|
||||
Copyright (c) 2017-2022, 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_DEFS_H_
|
||||
#define _3B2_DEFS_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "sim_defs.h"
|
||||
|
||||
#if defined(REV3)
|
||||
#include "3b2_rev3_defs.h"
|
||||
#else
|
||||
#include "3b2_rev2_defs.h"
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define noret void __attribute__((noreturn))
|
||||
#else
|
||||
#define noret void
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)((x)))
|
||||
#endif
|
||||
|
||||
#define ATOW(arr, i) \
|
||||
((uint32)(arr)[i + 3] + ((uint32)(arr)[i + 2] << 8) + \
|
||||
((uint32)(arr)[i + 1] << 16) + ((uint32)(arr)[i] << 24))
|
||||
|
||||
#define ATOH(arr, i) ((uint32)(arr)[i + 1] + ((uint32)(arr)[i] << 8))
|
||||
|
||||
#define CSRBIT(bit, sc) \
|
||||
{ \
|
||||
if (sc) { \
|
||||
csr_data |= (bit); \
|
||||
} else { \
|
||||
csr_data &= ~(bit); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PCHAR(c) (((char) (c) >= 0x20 && (char) (c) < 0x7f) ? (char) (c) : '.')
|
||||
|
||||
#define ROM_SIZE (128 * 1024)
|
||||
#define POLL_WAIT 70000
|
||||
|
||||
#define UNIT_V_EXBRK (UNIT_V_UF + 0)
|
||||
#define UNIT_V_OPBRK (UNIT_V_UF + 1)
|
||||
#define UNIT_EXBRK (1u << UNIT_V_EXBRK)
|
||||
#define UNIT_OPBRK (1u << UNIT_V_OPBRK)
|
||||
|
||||
#define EX_V_FLAG 1 << 21
|
||||
|
||||
#define ROM_BASE 0
|
||||
#define PHYS_MEM_BASE 0x2000000
|
||||
|
||||
#define MSIZ_512K 0x80000
|
||||
#define MSIZ_1M 0x100000
|
||||
#define MSIZ_2M 0x200000
|
||||
#define MSIZ_4M 0x400000
|
||||
#define MSIZ_8M 0x800000
|
||||
#define MSIZ_16M 0x1000000
|
||||
#define MSIZ_32M 0x2000000
|
||||
#define MSIZ_64M 0x4000000
|
||||
|
||||
/* Simulator stop codes */
|
||||
#define STOP_RSRV 1
|
||||
#define STOP_IBKPT 2 /* Breakpoint encountered */
|
||||
#define STOP_OPCODE 3 /* Invalid opcode */
|
||||
#define STOP_IRQ 4 /* Interrupt */
|
||||
#define STOP_EX 5 /* Exception */
|
||||
#define STOP_ESTK 6 /* Exception stack too deep */
|
||||
#define STOP_MMU 7 /* Unimplemented MMU Feature */
|
||||
#define STOP_POWER 8 /* System power-off */
|
||||
#define STOP_LOOP 9 /* Infinite loop stop */
|
||||
#define STOP_ERR 10 /* Other error */
|
||||
|
||||
/* Debug flags */
|
||||
#define READ_MSG 0x0001
|
||||
#define WRITE_MSG 0x0002
|
||||
#define DECODE_MSG 0x0004
|
||||
#define EXECUTE_MSG 0x0008
|
||||
#define INIT_MSG 0x0010
|
||||
#define IRQ_MSG 0x0020
|
||||
#define IO_DBG 0x0040
|
||||
#define CIO_DBG 0x0080
|
||||
#define TRACE_DBG 0x0100
|
||||
#define CALL_DBG 0x0200
|
||||
#define PKT_DBG 0x0400
|
||||
#define ERR_MSG 0x0800
|
||||
#define CACHE_DBG 0x1000
|
||||
#define DECODE_DBG 0x2000
|
||||
|
||||
#define TIMER_SANITY 0
|
||||
#define TIMER_INTERVAL 1
|
||||
#define TIMER_BUS 2
|
||||
|
||||
/* Timers */
|
||||
#define TMR_CLK 0 /* Calibrated 100Hz timer */
|
||||
|
||||
/* Global symbols */
|
||||
|
||||
extern DEBTAB sys_deb_tab[];
|
||||
extern DEVICE contty_dev;
|
||||
extern DEVICE cpu_dev;
|
||||
extern DEVICE csr_dev;
|
||||
extern DEVICE ctc_dev;
|
||||
extern DEVICE dmac_dev;
|
||||
extern DEVICE id_dev;
|
||||
extern DEVICE if_dev;
|
||||
extern DEVICE iu_timer_dev;
|
||||
extern DEVICE mau_dev;
|
||||
extern DEVICE mmu_dev;
|
||||
extern DEVICE ni_dev;
|
||||
extern DEVICE nvram_dev;
|
||||
extern DEVICE ports_dev;
|
||||
extern DEVICE timer_dev;
|
||||
extern DEVICE tod_dev;
|
||||
extern DEVICE tti_dev;
|
||||
extern DEVICE tto_dev;
|
||||
#if defined(REV3)
|
||||
extern DEVICE flt_dev;
|
||||
extern DEVICE ha_dev;
|
||||
#endif /* defined(REV3) */
|
||||
|
||||
#endif /* _3B2_DEFS_H_ */
|
||||
/* 3b2_defs.h: AT&T 3B2 Shared Simulator Definitions
|
||||
|
||||
Copyright (c) 2017-2022, 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_DEFS_H_
|
||||
#define _3B2_DEFS_H_
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#include "sim_defs.h"
|
||||
|
||||
#if defined(REV3)
|
||||
#include "3b2_rev3_defs.h"
|
||||
#else
|
||||
#include "3b2_rev2_defs.h"
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define noret void __attribute__((noreturn))
|
||||
#else
|
||||
#define noret void
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(x, y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
#ifndef UNUSED
|
||||
#define UNUSED(x) ((void)((x)))
|
||||
#endif
|
||||
|
||||
#define ATOW(arr, i) \
|
||||
((uint32)(arr)[i + 3] + ((uint32)(arr)[i + 2] << 8) + \
|
||||
((uint32)(arr)[i + 1] << 16) + ((uint32)(arr)[i] << 24))
|
||||
|
||||
#define ATOH(arr, i) ((uint32)(arr)[i + 1] + ((uint32)(arr)[i] << 8))
|
||||
|
||||
#define CSRBIT(bit, sc) \
|
||||
{ \
|
||||
if (sc) { \
|
||||
csr_data |= (bit); \
|
||||
} else { \
|
||||
csr_data &= ~(bit); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define PCHAR(c) (((char) (c) >= 0x20 && (char) (c) < 0x7f) ? (char) (c) : '.')
|
||||
|
||||
#define ROM_SIZE (128 * 1024)
|
||||
#define POLL_WAIT 70000
|
||||
|
||||
#define UNIT_V_EXBRK (UNIT_V_UF + 0)
|
||||
#define UNIT_V_OPBRK (UNIT_V_UF + 1)
|
||||
#define UNIT_EXBRK (1u << UNIT_V_EXBRK)
|
||||
#define UNIT_OPBRK (1u << UNIT_V_OPBRK)
|
||||
|
||||
#define EX_V_FLAG 1 << 21
|
||||
|
||||
#define ROM_BASE 0
|
||||
#define PHYS_MEM_BASE 0x2000000
|
||||
|
||||
#define MSIZ_512K 0x80000
|
||||
#define MSIZ_1M 0x100000
|
||||
#define MSIZ_2M 0x200000
|
||||
#define MSIZ_4M 0x400000
|
||||
#define MSIZ_8M 0x800000
|
||||
#define MSIZ_16M 0x1000000
|
||||
#define MSIZ_32M 0x2000000
|
||||
#define MSIZ_64M 0x4000000
|
||||
|
||||
/* Simulator stop codes */
|
||||
#define STOP_RSRV 1
|
||||
#define STOP_IBKPT 2 /* Breakpoint encountered */
|
||||
#define STOP_OPCODE 3 /* Invalid opcode */
|
||||
#define STOP_IRQ 4 /* Interrupt */
|
||||
#define STOP_EX 5 /* Exception */
|
||||
#define STOP_ESTK 6 /* Exception stack too deep */
|
||||
#define STOP_MMU 7 /* Unimplemented MMU Feature */
|
||||
#define STOP_POWER 8 /* System power-off */
|
||||
#define STOP_LOOP 9 /* Infinite loop stop */
|
||||
#define STOP_ERR 10 /* Other error */
|
||||
|
||||
/* Debug flags */
|
||||
#define READ_MSG 0x0001
|
||||
#define WRITE_MSG 0x0002
|
||||
#define DECODE_MSG 0x0004
|
||||
#define EXECUTE_MSG 0x0008
|
||||
#define INIT_MSG 0x0010
|
||||
#define IRQ_MSG 0x0020
|
||||
#define IO_DBG 0x0040
|
||||
#define CIO_DBG 0x0080
|
||||
#define TRACE_DBG 0x0100
|
||||
#define CALL_DBG 0x0200
|
||||
#define PKT_DBG 0x0400
|
||||
#define ERR_MSG 0x0800
|
||||
#define CACHE_DBG 0x1000
|
||||
#define DECODE_DBG 0x2000
|
||||
|
||||
#define TIMER_SANITY 0
|
||||
#define TIMER_INTERVAL 1
|
||||
#define TIMER_BUS 2
|
||||
|
||||
/* Timers */
|
||||
#define TMR_CLK 0 /* Calibrated 100Hz timer */
|
||||
|
||||
/* Global symbols */
|
||||
|
||||
extern DEBTAB sys_deb_tab[];
|
||||
extern DEVICE contty_dev;
|
||||
extern DEVICE cpu_dev;
|
||||
extern DEVICE csr_dev;
|
||||
extern DEVICE ctc_dev;
|
||||
extern DEVICE dmac_dev;
|
||||
extern DEVICE id_dev;
|
||||
extern DEVICE if_dev;
|
||||
extern DEVICE iu_timer_dev;
|
||||
extern DEVICE mau_dev;
|
||||
extern DEVICE mmu_dev;
|
||||
extern DEVICE ni_dev;
|
||||
extern DEVICE nvram_dev;
|
||||
extern DEVICE ports_dev;
|
||||
extern DEVICE timer_dev;
|
||||
extern DEVICE tod_dev;
|
||||
extern DEVICE tti_dev;
|
||||
extern DEVICE tto_dev;
|
||||
#if defined(REV3)
|
||||
extern DEVICE flt_dev;
|
||||
extern DEVICE ha_dev;
|
||||
#endif /* defined(REV3) */
|
||||
|
||||
#endif /* _3B2_DEFS_H_ */
|
||||
|
|
962
3B2/3b2_dmac.c
962
3B2/3b2_dmac.c
|
@ -1,481 +1,481 @@
|
|||
/* 3b2_dmac.c: AM9517 DMA Controller
|
||||
|
||||
Copyright (c) 2021-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_dmac.h"
|
||||
|
||||
#if defined(REV2)
|
||||
#include "3b2_id.h"
|
||||
#endif
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_iu.h"
|
||||
#include "3b2_mem.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_csr.h"
|
||||
|
||||
DMA_STATE dma_state;
|
||||
|
||||
UNIT dmac_unit[] = {
|
||||
{ UDATA (NULL, 0, 0), 0, 0 },
|
||||
{ UDATA (NULL, 0, 0), 0, 1 },
|
||||
{ UDATA (NULL, 0, 0), 0, 2 },
|
||||
{ UDATA (NULL, 0, 0), 0, 3 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
REG dmac_reg[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE dmac_dev = {
|
||||
"DMAC", dmac_unit, dmac_reg, NULL,
|
||||
1, 16, 8, 4, 16, 32,
|
||||
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},
|
||||
#endif
|
||||
{DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma},
|
||||
{DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL},
|
||||
{DMA_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) {
|
||||
uint32 addr, page;
|
||||
if (DMA_DECR(channel)) {
|
||||
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) - offset);
|
||||
} else {
|
||||
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset);
|
||||
}
|
||||
#if defined (REV3)
|
||||
page = (uint32)dma_state.channels[channel].page;
|
||||
#else
|
||||
/* In Rev 2, the top bit of the page address is a R/W bit, so
|
||||
we mask it here */
|
||||
page = (uint32)dma_state.channels[channel].page & 0x7f;
|
||||
#endif
|
||||
addr |= page << 16;
|
||||
return addr;
|
||||
}
|
||||
|
||||
t_stat dmac_reset(DEVICE *dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(&dma_state, 0, sizeof(dma_state));
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
dma_state.channels[i].page = 0;
|
||||
dma_state.channels[i].addr = 0;
|
||||
dma_state.channels[i].mode = 0;
|
||||
dma_state.channels[i].wcount = 0;
|
||||
dma_state.channels[i].addr_c = 0;
|
||||
dma_state.channels[i].wcount_c = -1;
|
||||
dma_state.channels[i].ptr = 0;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 dmac_read(uint32 pa, size_t size)
|
||||
{
|
||||
uint8 reg, base, data;
|
||||
|
||||
base = (uint8) (pa >> 12);
|
||||
reg = pa & 0xff;
|
||||
|
||||
switch (base) {
|
||||
case DMA_C:
|
||||
switch (reg) {
|
||||
case 0: /* channel 0 current address reg */
|
||||
data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 0 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 1: /* channel 0 current address reg */
|
||||
data = ((dma_state.channels[0].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 0 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 2: /* channel 1 current address reg */
|
||||
data = ((dma_state.channels[1].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 1 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 3: /* channel 1 current address reg */
|
||||
data = ((dma_state.channels[1].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 1 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 4: /* channel 2 current address reg */
|
||||
data = ((dma_state.channels[2].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 2 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 5: /* channel 2 current address reg */
|
||||
data = ((dma_state.channels[2].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 2 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 6: /* channel 3 current address reg */
|
||||
data = ((dma_state.channels[3].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 3 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 7: /* channel 3 current address reg */
|
||||
data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 3 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 8:
|
||||
data = dma_state.status;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading DMAC Status %08x\n",
|
||||
data);
|
||||
dma_state.status = 0;
|
||||
break;
|
||||
default:
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"DMAC READ %lu B @ %08x\n",
|
||||
size, pa);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
return data;
|
||||
default:
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"[BASE: %08x] DMAC READ %lu B @ %08x\n",
|
||||
base, size, pa);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Program the DMAC
|
||||
*/
|
||||
void dmac_program(uint8 reg, uint8 val)
|
||||
{
|
||||
uint8 channel_id, i, chan_num;
|
||||
dma_channel *channel;
|
||||
|
||||
#if defined(REV3)
|
||||
/* TODO: More general DMA interrupt clearing */
|
||||
CPU_CLR_INT(INT_UART_DMA);
|
||||
CLR_CSR(CSRDMA);
|
||||
#endif
|
||||
|
||||
if (reg < 8) {
|
||||
switch (reg) {
|
||||
case 0:
|
||||
case 1:
|
||||
chan_num = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
chan_num = 1;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
chan_num = 2;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
chan_num = 3;
|
||||
break;
|
||||
default:
|
||||
chan_num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
channel = &dma_state.channels[chan_num];
|
||||
|
||||
switch (reg & 1) {
|
||||
case 0: /* Address */
|
||||
channel->addr &= ~(0xff << dma_state.bff * 8);
|
||||
channel->addr |= (val & 0xff) << (dma_state.bff * 8);
|
||||
channel->addr_c = channel->addr;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Set address channel %d byte %d = %08x\n",
|
||||
chan_num, dma_state.bff, channel->addr);
|
||||
break;
|
||||
case 1: /* Word Count */
|
||||
channel->wcount &= ~(0xff << dma_state.bff * 8);
|
||||
channel->wcount |= (val & 0xff) << (dma_state.bff * 8);
|
||||
channel->wcount_c = channel->wcount;
|
||||
channel->ptr = 0;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Set word count channel %d byte %d = %08x\n",
|
||||
chan_num, dma_state.bff, channel->wcount);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Toggle the byte flip-flop */
|
||||
dma_state.bff ^= 1;
|
||||
|
||||
/* Handled. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If it hasn't been handled, it must be one of the following
|
||||
registers. */
|
||||
|
||||
switch (reg) {
|
||||
case 8: /* Command */
|
||||
dma_state.command = val;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Command: val=%02x\n",
|
||||
val);
|
||||
break;
|
||||
case 9: /* Request */
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Request set: val=%02x\n",
|
||||
val);
|
||||
dma_state.request = val;
|
||||
break;
|
||||
case 10: /* Write Single Mask Register Bit */
|
||||
channel_id = val & 3;
|
||||
|
||||
/* "Clear or Set" is bit 2 */
|
||||
if ((val >> 2) & 1) {
|
||||
dma_state.mask |= (1 << channel_id);
|
||||
} else {
|
||||
dma_state.mask &= ~(1 << channel_id);
|
||||
/* Set the appropriate DRQ */
|
||||
/* *dmac_drq_handlers[channel_id].drq = TRUE; */
|
||||
}
|
||||
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Write Single Mask Register Bit. channel=%d set/clear=%02x\n",
|
||||
channel_id, (val >> 2) & 1);
|
||||
break;
|
||||
case 11: /* Mode */
|
||||
channel_id = val & 3;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Mode Set. channel=%d val=%02x\n",
|
||||
channel_id, val);
|
||||
dma_state.channels[channel_id].mode = val;
|
||||
break;
|
||||
case 12: /* Clear Byte Pointer Flip/Flop */
|
||||
dma_state.bff = 0;
|
||||
break;
|
||||
case 13: /* Master Clear */
|
||||
dma_state.bff = 0;
|
||||
dma_state.command = 0;
|
||||
dma_state.status = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
dma_state.channels[i].page = 0;
|
||||
dma_state.channels[i].addr = 0;
|
||||
dma_state.channels[i].wcount = 0;
|
||||
dma_state.channels[i].addr_c = 0;
|
||||
dma_state.channels[i].wcount_c = -1;
|
||||
dma_state.channels[i].ptr = 0;
|
||||
}
|
||||
break;
|
||||
case 15: /* Write All Mask Register Bits */
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Write DMAC mask (all bits). Val=%02x\n",
|
||||
val);
|
||||
dma_state.mask = val & 0xf;
|
||||
break;
|
||||
case 16: /* Clear DMAC Interrupt */
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Clear DMA Interrupt in DMAC. val=%02x\n",
|
||||
val);
|
||||
break;
|
||||
default:
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Unhandled DMAC write. reg=%x val=%02x\n",
|
||||
reg, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_page_update(uint8 base, uint8 reg, uint8 val)
|
||||
{
|
||||
uint8 shift = 0;
|
||||
|
||||
/* Sanity check */
|
||||
if (reg > 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(REV2)
|
||||
/* In Rev2 systems, the actual register is a 32-bit,
|
||||
byte-addressed register, so that address 4x000 is the highest
|
||||
byte, 4x003 is the lowest byte. */
|
||||
shift = -(reg - 3) * 8;
|
||||
#endif
|
||||
|
||||
switch (base) {
|
||||
#if defined (REV2)
|
||||
case DMA_ID:
|
||||
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val);
|
||||
dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift);
|
||||
dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift);
|
||||
break;
|
||||
#endif
|
||||
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);
|
||||
break;
|
||||
case DMA_IUA:
|
||||
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val);
|
||||
dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift);
|
||||
dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift);
|
||||
break;
|
||||
case DMA_IUB:
|
||||
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val);
|
||||
dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift);
|
||||
dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_write(uint32 pa, uint32 val, size_t size)
|
||||
{
|
||||
uint8 reg, base;
|
||||
|
||||
base = (uint8) (pa >> 12);
|
||||
reg = pa & 0xff;
|
||||
|
||||
switch (base) {
|
||||
case DMA_C:
|
||||
dmac_program(reg, (uint8) val);
|
||||
break;
|
||||
#if defined (REV2)
|
||||
case DMA_ID:
|
||||
#endif
|
||||
case DMA_IUA:
|
||||
case DMA_IUB:
|
||||
case DMA_IF:
|
||||
dmac_page_update(base, reg, (uint8) val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_generic_dma(uint8 channel, uint32 service_address)
|
||||
{
|
||||
uint8 data;
|
||||
int32 i;
|
||||
uint32 addr;
|
||||
dma_channel *chan = &dma_state.channels[channel];
|
||||
|
||||
i = chan->wcount_c;
|
||||
|
||||
/* TODO: This assumes every transfer is a block mode, which is not
|
||||
guaranteed to be valid, but is likely safe? */
|
||||
|
||||
switch (DMA_XFER(channel)) {
|
||||
case DMA_XFER_VERIFY:
|
||||
sim_debug(EXECUTE_MSG, &dmac_dev,
|
||||
"[dmac_generic_dma channel=%d] unhandled VERIFY request.\n",
|
||||
channel);
|
||||
break;
|
||||
case DMA_XFER_WRITE:
|
||||
sim_debug(EXECUTE_MSG, &dmac_dev,
|
||||
"[dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n",
|
||||
channel,
|
||||
chan->wcount + 1,
|
||||
dma_address(channel, 0),
|
||||
service_address,
|
||||
dma_state.channels[channel].page,
|
||||
dma_state.channels[channel].addr);
|
||||
for (; i >= 0; i--) {
|
||||
chan->wcount_c--;
|
||||
addr = dma_address(channel, chan->ptr++);
|
||||
chan->addr_c = addr;
|
||||
data = pread_b(service_address, BUS_PER);
|
||||
write_b(addr, data, BUS_PER);
|
||||
}
|
||||
break;
|
||||
case DMA_XFER_READ:
|
||||
sim_debug(EXECUTE_MSG, &dmac_dev,
|
||||
"[dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n",
|
||||
channel,
|
||||
chan->wcount + 1,
|
||||
dma_address(channel, 0),
|
||||
service_address);
|
||||
for (; i >= 0; i--) {
|
||||
chan->wcount_c = i;
|
||||
addr = dma_address(channel, chan->ptr++);
|
||||
chan->addr_c = addr;
|
||||
data = pread_b(addr, BUS_PER);
|
||||
write_b(service_address, data, BUS_PER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* End of Process must set the channel's mask bit */
|
||||
dma_state.mask |= (1 << channel);
|
||||
dma_state.status |= (1 << channel);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 3b2_dmac.c: AM9517 DMA Controller
|
||||
|
||||
Copyright (c) 2021-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_dmac.h"
|
||||
|
||||
#if defined(REV2)
|
||||
#include "3b2_id.h"
|
||||
#endif
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_iu.h"
|
||||
#include "3b2_mem.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_csr.h"
|
||||
|
||||
DMA_STATE dma_state;
|
||||
|
||||
UNIT dmac_unit[] = {
|
||||
{ UDATA (NULL, 0, 0), 0, 0 },
|
||||
{ UDATA (NULL, 0, 0), 0, 1 },
|
||||
{ UDATA (NULL, 0, 0), 0, 2 },
|
||||
{ UDATA (NULL, 0, 0), 0, 3 },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
REG dmac_reg[] = {
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE dmac_dev = {
|
||||
"DMAC", dmac_unit, dmac_reg, NULL,
|
||||
1, 16, 8, 4, 16, 32,
|
||||
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},
|
||||
#endif
|
||||
{DMA_IF_CHAN, IFBASE+IF_DATA_REG, &if_state.drq, dmac_generic_dma, if_after_dma},
|
||||
{DMA_IUA_CHAN, IUBASE+IUA_DATA_REG, &iu_console.drq, iu_dma_console, NULL},
|
||||
{DMA_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) {
|
||||
uint32 addr, page;
|
||||
if (DMA_DECR(channel)) {
|
||||
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) - offset);
|
||||
} else {
|
||||
addr = (PHYS_MEM_BASE + (uint32)(dma_state.channels[channel].addr) + offset);
|
||||
}
|
||||
#if defined (REV3)
|
||||
page = (uint32)dma_state.channels[channel].page;
|
||||
#else
|
||||
/* In Rev 2, the top bit of the page address is a R/W bit, so
|
||||
we mask it here */
|
||||
page = (uint32)dma_state.channels[channel].page & 0x7f;
|
||||
#endif
|
||||
addr |= page << 16;
|
||||
return addr;
|
||||
}
|
||||
|
||||
t_stat dmac_reset(DEVICE *dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset(&dma_state, 0, sizeof(dma_state));
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
dma_state.channels[i].page = 0;
|
||||
dma_state.channels[i].addr = 0;
|
||||
dma_state.channels[i].mode = 0;
|
||||
dma_state.channels[i].wcount = 0;
|
||||
dma_state.channels[i].addr_c = 0;
|
||||
dma_state.channels[i].wcount_c = -1;
|
||||
dma_state.channels[i].ptr = 0;
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 dmac_read(uint32 pa, size_t size)
|
||||
{
|
||||
uint8 reg, base, data;
|
||||
|
||||
base = (uint8) (pa >> 12);
|
||||
reg = pa & 0xff;
|
||||
|
||||
switch (base) {
|
||||
case DMA_C:
|
||||
switch (reg) {
|
||||
case 0: /* channel 0 current address reg */
|
||||
data = ((dma_state.channels[0].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 0 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 1: /* channel 0 current address reg */
|
||||
data = ((dma_state.channels[0].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 0 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 2: /* channel 1 current address reg */
|
||||
data = ((dma_state.channels[1].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 1 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 3: /* channel 1 current address reg */
|
||||
data = ((dma_state.channels[1].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 1 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 4: /* channel 2 current address reg */
|
||||
data = ((dma_state.channels[2].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 2 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 5: /* channel 2 current address reg */
|
||||
data = ((dma_state.channels[2].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 2 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 6: /* channel 3 current address reg */
|
||||
data = ((dma_state.channels[3].addr_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 3 Addr Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 7: /* channel 3 current address reg */
|
||||
data = ((dma_state.channels[3].wcount_c) >> (dma_state.bff * 8)) & 0xff;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading Channel 3 Addr Count Reg: %08x\n",
|
||||
data);
|
||||
dma_state.bff ^= 1;
|
||||
break;
|
||||
case 8:
|
||||
data = dma_state.status;
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"Reading DMAC Status %08x\n",
|
||||
data);
|
||||
dma_state.status = 0;
|
||||
break;
|
||||
default:
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"DMAC READ %lu B @ %08x\n",
|
||||
size, pa);
|
||||
data = 0;
|
||||
}
|
||||
|
||||
return data;
|
||||
default:
|
||||
sim_debug(READ_MSG, &dmac_dev,
|
||||
"[BASE: %08x] DMAC READ %lu B @ %08x\n",
|
||||
base, size, pa);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Program the DMAC
|
||||
*/
|
||||
void dmac_program(uint8 reg, uint8 val)
|
||||
{
|
||||
uint8 channel_id, i, chan_num;
|
||||
dma_channel *channel;
|
||||
|
||||
#if defined(REV3)
|
||||
/* TODO: More general DMA interrupt clearing */
|
||||
CPU_CLR_INT(INT_UART_DMA);
|
||||
CLR_CSR(CSRDMA);
|
||||
#endif
|
||||
|
||||
if (reg < 8) {
|
||||
switch (reg) {
|
||||
case 0:
|
||||
case 1:
|
||||
chan_num = 0;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
chan_num = 1;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
chan_num = 2;
|
||||
break;
|
||||
case 6:
|
||||
case 7:
|
||||
chan_num = 3;
|
||||
break;
|
||||
default:
|
||||
chan_num = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
channel = &dma_state.channels[chan_num];
|
||||
|
||||
switch (reg & 1) {
|
||||
case 0: /* Address */
|
||||
channel->addr &= ~(0xff << dma_state.bff * 8);
|
||||
channel->addr |= (val & 0xff) << (dma_state.bff * 8);
|
||||
channel->addr_c = channel->addr;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Set address channel %d byte %d = %08x\n",
|
||||
chan_num, dma_state.bff, channel->addr);
|
||||
break;
|
||||
case 1: /* Word Count */
|
||||
channel->wcount &= ~(0xff << dma_state.bff * 8);
|
||||
channel->wcount |= (val & 0xff) << (dma_state.bff * 8);
|
||||
channel->wcount_c = channel->wcount;
|
||||
channel->ptr = 0;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Set word count channel %d byte %d = %08x\n",
|
||||
chan_num, dma_state.bff, channel->wcount);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Toggle the byte flip-flop */
|
||||
dma_state.bff ^= 1;
|
||||
|
||||
/* Handled. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If it hasn't been handled, it must be one of the following
|
||||
registers. */
|
||||
|
||||
switch (reg) {
|
||||
case 8: /* Command */
|
||||
dma_state.command = val;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Command: val=%02x\n",
|
||||
val);
|
||||
break;
|
||||
case 9: /* Request */
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Request set: val=%02x\n",
|
||||
val);
|
||||
dma_state.request = val;
|
||||
break;
|
||||
case 10: /* Write Single Mask Register Bit */
|
||||
channel_id = val & 3;
|
||||
|
||||
/* "Clear or Set" is bit 2 */
|
||||
if ((val >> 2) & 1) {
|
||||
dma_state.mask |= (1 << channel_id);
|
||||
} else {
|
||||
dma_state.mask &= ~(1 << channel_id);
|
||||
/* Set the appropriate DRQ */
|
||||
/* *dmac_drq_handlers[channel_id].drq = TRUE; */
|
||||
}
|
||||
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Write Single Mask Register Bit. channel=%d set/clear=%02x\n",
|
||||
channel_id, (val >> 2) & 1);
|
||||
break;
|
||||
case 11: /* Mode */
|
||||
channel_id = val & 3;
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Mode Set. channel=%d val=%02x\n",
|
||||
channel_id, val);
|
||||
dma_state.channels[channel_id].mode = val;
|
||||
break;
|
||||
case 12: /* Clear Byte Pointer Flip/Flop */
|
||||
dma_state.bff = 0;
|
||||
break;
|
||||
case 13: /* Master Clear */
|
||||
dma_state.bff = 0;
|
||||
dma_state.command = 0;
|
||||
dma_state.status = 0;
|
||||
for (i = 0; i < 4; i++) {
|
||||
dma_state.channels[i].page = 0;
|
||||
dma_state.channels[i].addr = 0;
|
||||
dma_state.channels[i].wcount = 0;
|
||||
dma_state.channels[i].addr_c = 0;
|
||||
dma_state.channels[i].wcount_c = -1;
|
||||
dma_state.channels[i].ptr = 0;
|
||||
}
|
||||
break;
|
||||
case 15: /* Write All Mask Register Bits */
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Write DMAC mask (all bits). Val=%02x\n",
|
||||
val);
|
||||
dma_state.mask = val & 0xf;
|
||||
break;
|
||||
case 16: /* Clear DMAC Interrupt */
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Clear DMA Interrupt in DMAC. val=%02x\n",
|
||||
val);
|
||||
break;
|
||||
default:
|
||||
sim_debug(WRITE_MSG, &dmac_dev,
|
||||
"Unhandled DMAC write. reg=%x val=%02x\n",
|
||||
reg, val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_page_update(uint8 base, uint8 reg, uint8 val)
|
||||
{
|
||||
uint8 shift = 0;
|
||||
|
||||
/* Sanity check */
|
||||
if (reg > 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(REV2)
|
||||
/* In Rev2 systems, the actual register is a 32-bit,
|
||||
byte-addressed register, so that address 4x000 is the highest
|
||||
byte, 4x003 is the lowest byte. */
|
||||
shift = -(reg - 3) * 8;
|
||||
#endif
|
||||
|
||||
switch (base) {
|
||||
#if defined (REV2)
|
||||
case DMA_ID:
|
||||
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 0 = %x\n", val);
|
||||
dma_state.channels[DMA_ID_CHAN].page &= ~(0xff << shift);
|
||||
dma_state.channels[DMA_ID_CHAN].page |= ((uint16)val << shift);
|
||||
break;
|
||||
#endif
|
||||
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);
|
||||
break;
|
||||
case DMA_IUA:
|
||||
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 2 = %x\n", val);
|
||||
dma_state.channels[DMA_IUA_CHAN].page &= ~(0xff << shift);
|
||||
dma_state.channels[DMA_IUA_CHAN].page |= ((uint16)val << shift);
|
||||
break;
|
||||
case DMA_IUB:
|
||||
sim_debug(WRITE_MSG, &dmac_dev, "Set page channel 3 = %x\n", val);
|
||||
dma_state.channels[DMA_IUB_CHAN].page &= ~(0xff << shift);
|
||||
dma_state.channels[DMA_IUB_CHAN].page |= ((uint16)val << shift);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_write(uint32 pa, uint32 val, size_t size)
|
||||
{
|
||||
uint8 reg, base;
|
||||
|
||||
base = (uint8) (pa >> 12);
|
||||
reg = pa & 0xff;
|
||||
|
||||
switch (base) {
|
||||
case DMA_C:
|
||||
dmac_program(reg, (uint8) val);
|
||||
break;
|
||||
#if defined (REV2)
|
||||
case DMA_ID:
|
||||
#endif
|
||||
case DMA_IUA:
|
||||
case DMA_IUB:
|
||||
case DMA_IF:
|
||||
dmac_page_update(base, reg, (uint8) val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dmac_generic_dma(uint8 channel, uint32 service_address)
|
||||
{
|
||||
uint8 data;
|
||||
int32 i;
|
||||
uint32 addr;
|
||||
dma_channel *chan = &dma_state.channels[channel];
|
||||
|
||||
i = chan->wcount_c;
|
||||
|
||||
/* TODO: This assumes every transfer is a block mode, which is not
|
||||
guaranteed to be valid, but is likely safe? */
|
||||
|
||||
switch (DMA_XFER(channel)) {
|
||||
case DMA_XFER_VERIFY:
|
||||
sim_debug(EXECUTE_MSG, &dmac_dev,
|
||||
"[dmac_generic_dma channel=%d] unhandled VERIFY request.\n",
|
||||
channel);
|
||||
break;
|
||||
case DMA_XFER_WRITE:
|
||||
sim_debug(EXECUTE_MSG, &dmac_dev,
|
||||
"[dmac_generic_dma channel=%d] write: %d bytes to %08x from %08x (page=%04x addr=%08x)\n",
|
||||
channel,
|
||||
chan->wcount + 1,
|
||||
dma_address(channel, 0),
|
||||
service_address,
|
||||
dma_state.channels[channel].page,
|
||||
dma_state.channels[channel].addr);
|
||||
for (; i >= 0; i--) {
|
||||
chan->wcount_c--;
|
||||
addr = dma_address(channel, chan->ptr++);
|
||||
chan->addr_c = addr;
|
||||
data = pread_b(service_address, BUS_PER);
|
||||
write_b(addr, data, BUS_PER);
|
||||
}
|
||||
break;
|
||||
case DMA_XFER_READ:
|
||||
sim_debug(EXECUTE_MSG, &dmac_dev,
|
||||
"[dmac_generic_dma channel=%d] read: %d bytes from %08x to %08x\n",
|
||||
channel,
|
||||
chan->wcount + 1,
|
||||
dma_address(channel, 0),
|
||||
service_address);
|
||||
for (; i >= 0; i--) {
|
||||
chan->wcount_c = i;
|
||||
addr = dma_address(channel, chan->ptr++);
|
||||
chan->addr_c = addr;
|
||||
data = pread_b(addr, BUS_PER);
|
||||
write_b(service_address, data, BUS_PER);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* End of Process must set the channel's mask bit */
|
||||
dma_state.mask |= (1 << channel);
|
||||
dma_state.status |= (1 << channel);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
178
3B2/3b2_dmac.h
178
3B2/3b2_dmac.h
|
@ -1,89 +1,89 @@
|
|||
/* 3b2_dmac.h: AM9517 DMA Controller
|
||||
|
||||
Copyright (c) 2021-2022, 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_DMAC_H_
|
||||
#define _3B2_DMAC_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define DMA_XFER_VERIFY 0
|
||||
#define DMA_XFER_WRITE 1 /* Write to memory from device */
|
||||
#define DMA_XFER_READ 2 /* Read from memory to device */
|
||||
|
||||
#define DMA_IF_READ (IFBASE + IF_DATA_REG)
|
||||
|
||||
#define DMA_MODE(C) ((dma_state.channels[(C)].mode >> 6) & 3)
|
||||
#define DMA_DECR(C) ((dma_state.channels[(C)].mode >> 5) & 1)
|
||||
#define DMA_AUTOINIT(C) ((dma_state.channels[(C)].mode >> 4) & 1)
|
||||
#define DMA_XFER(C) ((dma_state.channels[(C)].mode >> 2) & 3)
|
||||
|
||||
typedef struct {
|
||||
uint8 mode; /* Channel mode */
|
||||
uint16 page; /* Memory page */
|
||||
uint16 addr; /* Original addr */
|
||||
uint16 wcount; /* Original wcount */
|
||||
uint16 addr_c; /* Current addr */
|
||||
int32 wcount_c; /* Current word-count */
|
||||
uint16 ptr; /* Pointer into memory */
|
||||
} dma_channel;
|
||||
|
||||
typedef struct {
|
||||
/* Byte (high/low) flip-flop */
|
||||
uint8 bff;
|
||||
|
||||
/* Address and count registers for channels 0-3 */
|
||||
dma_channel channels[4];
|
||||
|
||||
/* DMAC programmable registers */
|
||||
uint8 command;
|
||||
uint8 request;
|
||||
uint8 mask;
|
||||
uint8 status;
|
||||
} DMA_STATE;
|
||||
|
||||
typedef struct {
|
||||
uint8 channel;
|
||||
uint32 service_address;
|
||||
t_bool *drq;
|
||||
void (*dma_handler)(uint8 channel, uint32 service_address);
|
||||
void (*after_dma_callback)();
|
||||
} dmac_dma_handler;
|
||||
|
||||
/* DMAC */
|
||||
t_stat dmac_reset(DEVICE *dptr);
|
||||
uint32 dmac_read(uint32 pa, size_t size);
|
||||
void dmac_write(uint32 pa, uint32 val, size_t size);
|
||||
void dmac_service_drqs();
|
||||
void dmac_generic_dma(uint8 channel, uint32 service_address);
|
||||
uint32 dma_address(uint8 channel, uint32 offset);
|
||||
|
||||
extern DMA_STATE dma_state;
|
||||
|
||||
#endif
|
||||
/* 3b2_dmac.h: AM9517 DMA Controller
|
||||
|
||||
Copyright (c) 2021-2022, 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_DMAC_H_
|
||||
#define _3B2_DMAC_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define DMA_XFER_VERIFY 0
|
||||
#define DMA_XFER_WRITE 1 /* Write to memory from device */
|
||||
#define DMA_XFER_READ 2 /* Read from memory to device */
|
||||
|
||||
#define DMA_IF_READ (IFBASE + IF_DATA_REG)
|
||||
|
||||
#define DMA_MODE(C) ((dma_state.channels[(C)].mode >> 6) & 3)
|
||||
#define DMA_DECR(C) ((dma_state.channels[(C)].mode >> 5) & 1)
|
||||
#define DMA_AUTOINIT(C) ((dma_state.channels[(C)].mode >> 4) & 1)
|
||||
#define DMA_XFER(C) ((dma_state.channels[(C)].mode >> 2) & 3)
|
||||
|
||||
typedef struct {
|
||||
uint8 mode; /* Channel mode */
|
||||
uint16 page; /* Memory page */
|
||||
uint16 addr; /* Original addr */
|
||||
uint16 wcount; /* Original wcount */
|
||||
uint16 addr_c; /* Current addr */
|
||||
int32 wcount_c; /* Current word-count */
|
||||
uint16 ptr; /* Pointer into memory */
|
||||
} dma_channel;
|
||||
|
||||
typedef struct {
|
||||
/* Byte (high/low) flip-flop */
|
||||
uint8 bff;
|
||||
|
||||
/* Address and count registers for channels 0-3 */
|
||||
dma_channel channels[4];
|
||||
|
||||
/* DMAC programmable registers */
|
||||
uint8 command;
|
||||
uint8 request;
|
||||
uint8 mask;
|
||||
uint8 status;
|
||||
} DMA_STATE;
|
||||
|
||||
typedef struct {
|
||||
uint8 channel;
|
||||
uint32 service_address;
|
||||
t_bool *drq;
|
||||
void (*dma_handler)(uint8 channel, uint32 service_address);
|
||||
void (*after_dma_callback)();
|
||||
} dmac_dma_handler;
|
||||
|
||||
/* DMAC */
|
||||
t_stat dmac_reset(DEVICE *dptr);
|
||||
uint32 dmac_read(uint32 pa, size_t size);
|
||||
void dmac_write(uint32 pa, uint32 val, size_t size);
|
||||
void dmac_service_drqs();
|
||||
void dmac_generic_dma(uint8 channel, uint32 service_address);
|
||||
uint32 dma_address(uint8 channel, uint32 offset);
|
||||
|
||||
extern DMA_STATE dma_state;
|
||||
|
||||
#endif
|
||||
|
|
1992
3B2/3b2_id.c
1992
3B2/3b2_id.c
File diff suppressed because it is too large
Load diff
356
3B2/3b2_id.h
356
3B2/3b2_id.h
|
@ -1,178 +1,178 @@
|
|||
/* 3b2_id.h: uPD7261 Integrated Disk Controller
|
||||
|
||||
Copyright (c) 2017-2022, 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_ID_H__
|
||||
#define __3B2_ID_H__
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define ID0 0
|
||||
#define ID1 1
|
||||
#define ID_CTLR 2
|
||||
|
||||
/* Command Codes (bits 3-7 of command byte) */
|
||||
|
||||
#define ID_CMD_AUX 0x00 /* Auxiliary Command */
|
||||
#define ID_CMD_SIS 0x01 /* Sense int. status */
|
||||
#define ID_CMD_SPEC 0x02 /* Specify */
|
||||
#define ID_CMD_SUS 0x03 /* Sense unit status */
|
||||
#define ID_CMD_DERR 0x04 /* Detect Error */
|
||||
#define ID_CMD_RECAL 0x05 /* Recalibrate */
|
||||
#define ID_CMD_SEEK 0x06 /* Seek */
|
||||
#define ID_CMD_FMT 0x07 /* Format */
|
||||
#define ID_CMD_VID 0x08 /* Verify ID */
|
||||
#define ID_CMD_RID 0x09 /* Read ID */
|
||||
#define ID_CMD_RDIAG 0x0A /* Read Diagnostic */
|
||||
#define ID_CMD_RDATA 0x0B /* Read Data */
|
||||
#define ID_CMD_CHECK 0x0C /* Check */
|
||||
#define ID_CMD_SCAN 0x0D /* Scan */
|
||||
#define ID_CMD_VDATA 0x0E /* Verify Data */
|
||||
#define ID_CMD_WDATA 0x0F /* Write Data */
|
||||
|
||||
#define ID_AUX_RST 0x01
|
||||
#define ID_AUX_CLB 0x02
|
||||
#define ID_AUX_HSRQ 0x04
|
||||
#define ID_AUX_CLCE 0x08
|
||||
|
||||
#define ID_STAT_DRQ 0x01
|
||||
#define ID_STAT_NCI 0x02
|
||||
#define ID_STAT_IER 0x04
|
||||
#define ID_STAT_RRQ 0x08
|
||||
#define ID_STAT_SRQ 0x10
|
||||
#define ID_STAT_CEL 0x20
|
||||
#define ID_STAT_CEH 0x40
|
||||
#define ID_STAT_CB 0x80
|
||||
|
||||
#define ID_IST_SEN 0x80 /* Seek End */
|
||||
#define ID_IST_RC 0x40 /* Ready Change */
|
||||
#define ID_IST_SER 0x20 /* Seek Error */
|
||||
#define ID_IST_EQC 0x10 /* Equipment Check */
|
||||
#define ID_IST_NR 0x08 /* Not Ready */
|
||||
|
||||
#define ID_UST_DSEL 0x10 /* Drive Selected */
|
||||
#define ID_UST_SCL 0x08 /* Seek Complete */
|
||||
#define ID_UST_TK0 0x04 /* Track 0 */
|
||||
#define ID_UST_RDY 0x02 /* Ready */
|
||||
#define ID_UST_WFL 0x01 /* Write Fault */
|
||||
|
||||
#define ID_EST_ENC 0x80
|
||||
#define ID_EST_OVR 0x40
|
||||
#define ID_EST_DER 0x20
|
||||
#define ID_EST_EQC 0x10
|
||||
#define ID_EST_NR 0x08
|
||||
#define ID_EST_ND 0x04
|
||||
#define ID_EST_NWR 0x02
|
||||
#define ID_EST_MAM 0x01
|
||||
|
||||
#define ID_DTLH_POLL 0x10
|
||||
|
||||
#define ID_SEEK_NONE -1
|
||||
#define ID_SEEK_0 0
|
||||
#define ID_SEEK_1 1
|
||||
|
||||
/* Drive Geometries */
|
||||
|
||||
/* Common across all drive types */
|
||||
#define ID_SEC_SIZE 512
|
||||
#define ID_SEC_CNT 18
|
||||
#define ID_CYL_SIZE ID_SEC_SIZE * ID_SEC_CNT
|
||||
|
||||
/* Specific to each drive type */
|
||||
#define ID_MAX_DTYPE 3
|
||||
|
||||
#define ID_HD30_DTYPE 0
|
||||
#define ID_HD30_CYL 697
|
||||
#define ID_HD30_HEADS 5
|
||||
#define ID_HD30_LBN 62730
|
||||
|
||||
#define ID_HD72_DTYPE 1
|
||||
#define ID_HD72_CYL 925
|
||||
#define ID_HD72_HEADS 9
|
||||
#define ID_HD72_LBN 149850
|
||||
|
||||
#define ID_HD72C_DTYPE 2
|
||||
#define ID_HD72C_CYL 754
|
||||
#define ID_HD72C_HEADS 11
|
||||
#define ID_HD72C_LBN 149292
|
||||
|
||||
/* The HD135 is actually just an HD161 with only 1024 cylinders
|
||||
* formatted. This is a software limitation, not hardware. */
|
||||
|
||||
#define ID_HD135_DTYPE 3
|
||||
#define ID_HD135_CYL 1224
|
||||
#define ID_HD135_HEADS 15
|
||||
#define ID_HD135_LBN 330480
|
||||
|
||||
#define ID_HD161_DTYPE 3
|
||||
#define ID_HD161_CYL 1224
|
||||
#define ID_HD161_HEADS 15
|
||||
#define ID_HD161_LBN 330480
|
||||
|
||||
#define ID_V_DTYPE (DKUF_V_UF + 0)
|
||||
#define ID_M_DTYPE 3
|
||||
#define ID_DTYPE (ID_M_DTYPE << ID_V_DTYPE)
|
||||
#define ID_V_AUTOSIZE (ID_V_DTYPE + 2)
|
||||
#define ID_AUTOSIZE (1 << ID_V_AUTOSIZE)
|
||||
#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_DSK_SIZE(d) ID_##d##_LBN
|
||||
|
||||
/* Unit, Register, Device descriptions */
|
||||
|
||||
#define ID_FIFO_LEN 8
|
||||
#define ID_IDFIELD_LEN 4
|
||||
|
||||
#define ID_NUM_UNITS 2
|
||||
|
||||
#define DMA_ID_SVC IDBASE+ID_DATA_REG
|
||||
|
||||
#define CMD_NUM ((id_cmd >> 4) & 0xf)
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
t_stat id_ctlr_svc(UNIT *uptr);
|
||||
t_stat id_unit_svc(UNIT *uptr);
|
||||
t_stat id_reset(DEVICE *dptr);
|
||||
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_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat id_detach(UNIT *uptr);
|
||||
uint32 id_read(uint32 pa, size_t size);
|
||||
void id_write(uint32 pa, uint32 val, size_t size);
|
||||
CONST char *id_description(DEVICE *dptr);
|
||||
t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
void id_handle_data(uint8 val);
|
||||
void id_handle_command(uint8 val);
|
||||
void id_after_dma();
|
||||
|
||||
extern t_bool id_drq;
|
||||
|
||||
#endif
|
||||
/* 3b2_id.h: uPD7261 Integrated Disk Controller
|
||||
|
||||
Copyright (c) 2017-2022, 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_ID_H__
|
||||
#define __3B2_ID_H__
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define ID0 0
|
||||
#define ID1 1
|
||||
#define ID_CTLR 2
|
||||
|
||||
/* Command Codes (bits 3-7 of command byte) */
|
||||
|
||||
#define ID_CMD_AUX 0x00 /* Auxiliary Command */
|
||||
#define ID_CMD_SIS 0x01 /* Sense int. status */
|
||||
#define ID_CMD_SPEC 0x02 /* Specify */
|
||||
#define ID_CMD_SUS 0x03 /* Sense unit status */
|
||||
#define ID_CMD_DERR 0x04 /* Detect Error */
|
||||
#define ID_CMD_RECAL 0x05 /* Recalibrate */
|
||||
#define ID_CMD_SEEK 0x06 /* Seek */
|
||||
#define ID_CMD_FMT 0x07 /* Format */
|
||||
#define ID_CMD_VID 0x08 /* Verify ID */
|
||||
#define ID_CMD_RID 0x09 /* Read ID */
|
||||
#define ID_CMD_RDIAG 0x0A /* Read Diagnostic */
|
||||
#define ID_CMD_RDATA 0x0B /* Read Data */
|
||||
#define ID_CMD_CHECK 0x0C /* Check */
|
||||
#define ID_CMD_SCAN 0x0D /* Scan */
|
||||
#define ID_CMD_VDATA 0x0E /* Verify Data */
|
||||
#define ID_CMD_WDATA 0x0F /* Write Data */
|
||||
|
||||
#define ID_AUX_RST 0x01
|
||||
#define ID_AUX_CLB 0x02
|
||||
#define ID_AUX_HSRQ 0x04
|
||||
#define ID_AUX_CLCE 0x08
|
||||
|
||||
#define ID_STAT_DRQ 0x01
|
||||
#define ID_STAT_NCI 0x02
|
||||
#define ID_STAT_IER 0x04
|
||||
#define ID_STAT_RRQ 0x08
|
||||
#define ID_STAT_SRQ 0x10
|
||||
#define ID_STAT_CEL 0x20
|
||||
#define ID_STAT_CEH 0x40
|
||||
#define ID_STAT_CB 0x80
|
||||
|
||||
#define ID_IST_SEN 0x80 /* Seek End */
|
||||
#define ID_IST_RC 0x40 /* Ready Change */
|
||||
#define ID_IST_SER 0x20 /* Seek Error */
|
||||
#define ID_IST_EQC 0x10 /* Equipment Check */
|
||||
#define ID_IST_NR 0x08 /* Not Ready */
|
||||
|
||||
#define ID_UST_DSEL 0x10 /* Drive Selected */
|
||||
#define ID_UST_SCL 0x08 /* Seek Complete */
|
||||
#define ID_UST_TK0 0x04 /* Track 0 */
|
||||
#define ID_UST_RDY 0x02 /* Ready */
|
||||
#define ID_UST_WFL 0x01 /* Write Fault */
|
||||
|
||||
#define ID_EST_ENC 0x80
|
||||
#define ID_EST_OVR 0x40
|
||||
#define ID_EST_DER 0x20
|
||||
#define ID_EST_EQC 0x10
|
||||
#define ID_EST_NR 0x08
|
||||
#define ID_EST_ND 0x04
|
||||
#define ID_EST_NWR 0x02
|
||||
#define ID_EST_MAM 0x01
|
||||
|
||||
#define ID_DTLH_POLL 0x10
|
||||
|
||||
#define ID_SEEK_NONE -1
|
||||
#define ID_SEEK_0 0
|
||||
#define ID_SEEK_1 1
|
||||
|
||||
/* Drive Geometries */
|
||||
|
||||
/* Common across all drive types */
|
||||
#define ID_SEC_SIZE 512
|
||||
#define ID_SEC_CNT 18
|
||||
#define ID_CYL_SIZE ID_SEC_SIZE * ID_SEC_CNT
|
||||
|
||||
/* Specific to each drive type */
|
||||
#define ID_MAX_DTYPE 3
|
||||
|
||||
#define ID_HD30_DTYPE 0
|
||||
#define ID_HD30_CYL 697
|
||||
#define ID_HD30_HEADS 5
|
||||
#define ID_HD30_LBN 62730
|
||||
|
||||
#define ID_HD72_DTYPE 1
|
||||
#define ID_HD72_CYL 925
|
||||
#define ID_HD72_HEADS 9
|
||||
#define ID_HD72_LBN 149850
|
||||
|
||||
#define ID_HD72C_DTYPE 2
|
||||
#define ID_HD72C_CYL 754
|
||||
#define ID_HD72C_HEADS 11
|
||||
#define ID_HD72C_LBN 149292
|
||||
|
||||
/* The HD135 is actually just an HD161 with only 1024 cylinders
|
||||
* formatted. This is a software limitation, not hardware. */
|
||||
|
||||
#define ID_HD135_DTYPE 3
|
||||
#define ID_HD135_CYL 1224
|
||||
#define ID_HD135_HEADS 15
|
||||
#define ID_HD135_LBN 330480
|
||||
|
||||
#define ID_HD161_DTYPE 3
|
||||
#define ID_HD161_CYL 1224
|
||||
#define ID_HD161_HEADS 15
|
||||
#define ID_HD161_LBN 330480
|
||||
|
||||
#define ID_V_DTYPE (DKUF_V_UF + 0)
|
||||
#define ID_M_DTYPE 3
|
||||
#define ID_DTYPE (ID_M_DTYPE << ID_V_DTYPE)
|
||||
#define ID_V_AUTOSIZE (ID_V_DTYPE + 2)
|
||||
#define ID_AUTOSIZE (1 << ID_V_AUTOSIZE)
|
||||
#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_DSK_SIZE(d) ID_##d##_LBN
|
||||
|
||||
/* Unit, Register, Device descriptions */
|
||||
|
||||
#define ID_FIFO_LEN 8
|
||||
#define ID_IDFIELD_LEN 4
|
||||
|
||||
#define ID_NUM_UNITS 2
|
||||
|
||||
#define DMA_ID_SVC IDBASE+ID_DATA_REG
|
||||
|
||||
#define CMD_NUM ((id_cmd >> 4) & 0xf)
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
t_stat id_ctlr_svc(UNIT *uptr);
|
||||
t_stat id_unit_svc(UNIT *uptr);
|
||||
t_stat id_reset(DEVICE *dptr);
|
||||
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_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat id_detach(UNIT *uptr);
|
||||
uint32 id_read(uint32 pa, size_t size);
|
||||
void id_write(uint32 pa, uint32 val, size_t size);
|
||||
CONST char *id_description(DEVICE *dptr);
|
||||
t_stat id_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
void id_handle_data(uint8 val);
|
||||
void id_handle_command(uint8 val);
|
||||
void id_after_dma();
|
||||
|
||||
extern t_bool id_drq;
|
||||
|
||||
#endif
|
||||
|
|
1290
3B2/3b2_if.c
1290
3B2/3b2_if.c
File diff suppressed because it is too large
Load diff
262
3B2/3b2_if.h
262
3B2/3b2_if.h
|
@ -1,131 +1,131 @@
|
|||
/* 3b2_if.h: TMS2797 Integrated Floppy Controller
|
||||
|
||||
Copyright (c) 2017-2022, 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_IF_H__
|
||||
#define __3B2_IF_H__
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
typedef struct {
|
||||
uint8 data;
|
||||
uint8 cmd;
|
||||
uint8 cmd_type;
|
||||
uint8 status;
|
||||
uint8 track;
|
||||
uint8 sector;
|
||||
uint8 side;
|
||||
uint8 read_addr_ptr;
|
||||
int8 step_dir;
|
||||
t_bool drq;
|
||||
#if defined(REV3)
|
||||
uint8 csr;
|
||||
#endif
|
||||
} IF_STATE;
|
||||
|
||||
/* Status Bits */
|
||||
#define IF_BUSY 0x01
|
||||
#define IF_DRQ 0x02
|
||||
#define IF_INDEX 0x02
|
||||
#define IF_TK_0 0x04
|
||||
#define IF_LOST_DATA 0x04
|
||||
#define IF_CRC_ERR 0x08
|
||||
#define IF_SEEK_ERR 0x10
|
||||
#define IF_RNF 0x10
|
||||
#define IF_HEAD_LOADED 0x20
|
||||
#define IF_RECORD_TYPE 0x20
|
||||
#define IF_WP 0x40
|
||||
#define IF_NRDY 0x80
|
||||
|
||||
/* Type I Commands */
|
||||
#define IF_RESTORE 0x00
|
||||
#define IF_SEEK 0x10
|
||||
#define IF_STEP 0x20
|
||||
#define IF_STEP_T 0x30
|
||||
#define IF_STEP_IN 0x40
|
||||
#define IF_STEP_IN_T 0x50
|
||||
#define IF_STEP_OUT 0x60
|
||||
#define IF_STEP_OUT_T 0x70
|
||||
|
||||
/* Type II Commands */
|
||||
#define IF_READ_SEC 0x80
|
||||
#define IF_READ_SEC_M 0x90
|
||||
#define IF_WRITE_SEC 0xA0
|
||||
#define IF_WRITE_SEC_M 0xB0
|
||||
|
||||
/* Type III Commands */
|
||||
#define IF_READ_ADDR 0xC0
|
||||
#define IF_READ_TRACK 0xE0
|
||||
#define IF_WRITE_TRACK 0xF0
|
||||
|
||||
/* Type IV Command */
|
||||
#define IF_FORCE_INT 0xD0
|
||||
|
||||
/* Command flags */
|
||||
|
||||
#define IF_C_FLAG 0x02
|
||||
#define IF_V_FLAG 0x04
|
||||
#define IF_E_FLAG 0x04
|
||||
#define IF_U_FLAG 0x02
|
||||
#define IF_H_FLAG 0x08
|
||||
#define IF_S_FLAG 0x10
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define IF_SIDES 2
|
||||
#define IF_SEC_COUNT 9
|
||||
#define IF_SEC_SIZE 512
|
||||
#define IF_TRACK_SIZE 4608
|
||||
#define IF_TRACK_COUNT 80
|
||||
|
||||
#define IF_STEP_IN_DIR 1
|
||||
#define IF_STEP_OUT_DIR -1
|
||||
|
||||
#define IF_DSK_SIZE_SECS (IF_SIDES * IF_TRACK_COUNT * IF_SEC_COUNT)
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
t_stat if_svc(UNIT *uptr);
|
||||
t_stat if_reset(DEVICE *dptr);
|
||||
t_stat if_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat if_detach(UNIT *uptr);
|
||||
uint32 if_read(uint32 pa, size_t size);
|
||||
void if_write(uint32 pa, uint32 val, size_t size);
|
||||
#if defined(REV3)
|
||||
uint32 if_csr_read(uint32 pa, size_t size);
|
||||
void if_csr_write(uint32 pa, uint32 val, size_t size);
|
||||
#endif
|
||||
void if_handle_command();
|
||||
void if_after_dma();
|
||||
CONST char *if_description(DEVICE *dptr);
|
||||
t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
|
||||
extern IF_STATE if_state;
|
||||
|
||||
#endif
|
||||
/* 3b2_if.h: TMS2797 Integrated Floppy Controller
|
||||
|
||||
Copyright (c) 2017-2022, 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_IF_H__
|
||||
#define __3B2_IF_H__
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
typedef struct {
|
||||
uint8 data;
|
||||
uint8 cmd;
|
||||
uint8 cmd_type;
|
||||
uint8 status;
|
||||
uint8 track;
|
||||
uint8 sector;
|
||||
uint8 side;
|
||||
uint8 read_addr_ptr;
|
||||
int8 step_dir;
|
||||
t_bool drq;
|
||||
#if defined(REV3)
|
||||
uint8 csr;
|
||||
#endif
|
||||
} IF_STATE;
|
||||
|
||||
/* Status Bits */
|
||||
#define IF_BUSY 0x01
|
||||
#define IF_DRQ 0x02
|
||||
#define IF_INDEX 0x02
|
||||
#define IF_TK_0 0x04
|
||||
#define IF_LOST_DATA 0x04
|
||||
#define IF_CRC_ERR 0x08
|
||||
#define IF_SEEK_ERR 0x10
|
||||
#define IF_RNF 0x10
|
||||
#define IF_HEAD_LOADED 0x20
|
||||
#define IF_RECORD_TYPE 0x20
|
||||
#define IF_WP 0x40
|
||||
#define IF_NRDY 0x80
|
||||
|
||||
/* Type I Commands */
|
||||
#define IF_RESTORE 0x00
|
||||
#define IF_SEEK 0x10
|
||||
#define IF_STEP 0x20
|
||||
#define IF_STEP_T 0x30
|
||||
#define IF_STEP_IN 0x40
|
||||
#define IF_STEP_IN_T 0x50
|
||||
#define IF_STEP_OUT 0x60
|
||||
#define IF_STEP_OUT_T 0x70
|
||||
|
||||
/* Type II Commands */
|
||||
#define IF_READ_SEC 0x80
|
||||
#define IF_READ_SEC_M 0x90
|
||||
#define IF_WRITE_SEC 0xA0
|
||||
#define IF_WRITE_SEC_M 0xB0
|
||||
|
||||
/* Type III Commands */
|
||||
#define IF_READ_ADDR 0xC0
|
||||
#define IF_READ_TRACK 0xE0
|
||||
#define IF_WRITE_TRACK 0xF0
|
||||
|
||||
/* Type IV Command */
|
||||
#define IF_FORCE_INT 0xD0
|
||||
|
||||
/* Command flags */
|
||||
|
||||
#define IF_C_FLAG 0x02
|
||||
#define IF_V_FLAG 0x04
|
||||
#define IF_E_FLAG 0x04
|
||||
#define IF_U_FLAG 0x02
|
||||
#define IF_H_FLAG 0x08
|
||||
#define IF_S_FLAG 0x10
|
||||
|
||||
/* Constants */
|
||||
|
||||
#define IF_SIDES 2
|
||||
#define IF_SEC_COUNT 9
|
||||
#define IF_SEC_SIZE 512
|
||||
#define IF_TRACK_SIZE 4608
|
||||
#define IF_TRACK_COUNT 80
|
||||
|
||||
#define IF_STEP_IN_DIR 1
|
||||
#define IF_STEP_OUT_DIR -1
|
||||
|
||||
#define IF_DSK_SIZE_SECS (IF_SIDES * IF_TRACK_COUNT * IF_SEC_COUNT)
|
||||
|
||||
/* Function prototypes */
|
||||
|
||||
t_stat if_svc(UNIT *uptr);
|
||||
t_stat if_reset(DEVICE *dptr);
|
||||
t_stat if_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat if_detach(UNIT *uptr);
|
||||
uint32 if_read(uint32 pa, size_t size);
|
||||
void if_write(uint32 pa, uint32 val, size_t size);
|
||||
#if defined(REV3)
|
||||
uint32 if_csr_read(uint32 pa, size_t size);
|
||||
void if_csr_write(uint32 pa, uint32 val, size_t size);
|
||||
#endif
|
||||
void if_handle_command();
|
||||
void if_after_dma();
|
||||
CONST char *if_description(DEVICE *dptr);
|
||||
t_stat if_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
|
||||
extern IF_STATE if_state;
|
||||
|
||||
#endif
|
||||
|
|
1544
3B2/3b2_io.c
1544
3B2/3b2_io.c
File diff suppressed because it is too large
Load diff
542
3B2/3b2_io.h
542
3B2/3b2_io.h
|
@ -1,271 +1,271 @@
|
|||
/* 3b2_io.h: Common I/O (CIO) Feature Card Support
|
||||
|
||||
Copyright (c) 2017-2022, 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.
|
||||
*/
|
||||
|
||||
/* Reference Documentation
|
||||
* =======================
|
||||
*
|
||||
* All communication between the system board and feature cards is
|
||||
* done through in-memory queues, and causing interrupts in the
|
||||
* feature card by accessing the Control or ID/VEC memory-mapped IO
|
||||
* addresses. The structure of these queues is defined below in
|
||||
* tables.
|
||||
*
|
||||
* Sysgen Block
|
||||
* ------------
|
||||
*
|
||||
* Pointed to by address at 0x2000000 after an INT0/INT1 combo
|
||||
*
|
||||
*
|
||||
* | Address | Size | Contents |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | SYSGEN_P | 4 | Address of request queue |
|
||||
* | SYSGEN_P + 4 | 4 | Address of completion queue |
|
||||
* | SYSGEN_P + 8 | 1 | Number of entries in request queue |
|
||||
* | SYSGEN_P + 9 | 1 | Number of entries in completion queue |
|
||||
* | SYSGEN_P + 10 | 1 | Interrupt Vector number |
|
||||
* | SYSGEN_P + 11 | 1 | Number of request queues |
|
||||
*
|
||||
*
|
||||
* Queue Entry
|
||||
* -----------
|
||||
*
|
||||
* Each queue has one Express Entry, and n regular entries.
|
||||
*
|
||||
* | Address | Size | Contents |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | ENTRY_P | 2 | Byte Count |
|
||||
* | ENTRY_P + 2 | 1 | Subdevice [1] |
|
||||
* | ENTRY_P + 3 | 1 | Opcode |
|
||||
* | ENTRY_P + 4 | 4 | Address / Data |
|
||||
* | ENTRY_P + 8 | 4 | Application Specific Data |
|
||||
*
|
||||
* [1] The "Subdevice" entry is further divided into a bitset:
|
||||
* Bit 7: Command (1) / Status (0)
|
||||
* Bit 6: Sequence Bit
|
||||
* Bit 5-1: Subdevice
|
||||
*
|
||||
*
|
||||
* Queue
|
||||
* -----
|
||||
*
|
||||
* The Queue structures (one for request, one for completion) hold:
|
||||
* - An express entry
|
||||
*
|
||||
* And then one or more queues, each queue consiting of
|
||||
* - A set of pointers for load and unload from the queue
|
||||
* - One or more Queue Entries
|
||||
*
|
||||
* | Address | Size | Contents |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | QUEUE_P | 12 | Express Queue Entry [1] |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | QUEUE_P + 12 | 2 | Load Pointer for Queue 0 |
|
||||
* | QUEUE_P + 14 | 2 | Unload Pointer for Queue 0 |
|
||||
* | QUEUE_P + 16 | 12 | Queue 0 Entry 0 [1] |
|
||||
* | QUEUE_P + 28 | 12 | Queue 0 Entry 1 [1] |
|
||||
* | ... | ... | ... |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | QUEUE_P + n | 2 | Load 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 1 [1] |
|
||||
* | ... | ... | ... |
|
||||
*
|
||||
* [1] See Queue Entry above
|
||||
*
|
||||
* NB: There are multiple Request queues, usually one per subdevice,
|
||||
* and EACH Request queue starts with a Load Pointer, an Unload
|
||||
* Pointer, and then 'n' Queue Entries.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _3B2_IO_H_
|
||||
#define _3B2_IO_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define CRC_POLYNOMIAL 0xEDB88320
|
||||
|
||||
#define CIO_SLOTS 12
|
||||
|
||||
/* IO area */
|
||||
#define IO_BOTTOM 0x40000
|
||||
#define IO_TOP 0x50000
|
||||
|
||||
#if defined(REV3)
|
||||
#define UBUS_BOTTOM 0x1c00000
|
||||
#define UBUS_TOP 0x2000000
|
||||
#endif
|
||||
|
||||
/* CIO area */
|
||||
#define CIO_BOTTOM 0x200000
|
||||
#if defined(REV3)
|
||||
#define CIO_TOP 0x1a00000
|
||||
#else
|
||||
#define CIO_TOP 0x2000000
|
||||
#endif
|
||||
|
||||
#define IOF_ID 0
|
||||
#define IOF_VEC 1
|
||||
#define IOF_CTRL 3
|
||||
#define IOF_STAT 5
|
||||
|
||||
#define SYSGEN_PTR PHYS_MEM_BASE
|
||||
|
||||
/* CIO opcodes */
|
||||
#define CIO_DLM 1
|
||||
#define CIO_ULM 2
|
||||
#define CIO_FCF 3
|
||||
#define CIO_DOS 4
|
||||
#define CIO_DSD 5
|
||||
|
||||
/* Response */
|
||||
#define CIO_SUCCESS 0
|
||||
#define CIO_FAILURE 2
|
||||
#define CIO_SYSGEN_OK 3
|
||||
|
||||
/* Map a physical address to a card ID */
|
||||
#define SLOT(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1)
|
||||
/* Map a card ID to a base address */
|
||||
#define CADDR(bid) (((((bid) + 1) * 2) << 0x14))
|
||||
|
||||
/* Offsets into the request/completion queues of various values */
|
||||
#define LUSIZE 4 /* Load/Unload pointers size */
|
||||
#define QESIZE 8 /* Queue entry is 8 bytes + application data */
|
||||
|
||||
#define CIO_STAT 0
|
||||
#define CIO_CMD 1
|
||||
|
||||
/* Sysgen State */
|
||||
#define CIO_INT_NONE 0
|
||||
#define CIO_INT0 1
|
||||
#define CIO_INT1 2
|
||||
#define CIO_SYSGEN 3
|
||||
|
||||
#define CIO_SET_INT(slot) if (cio[slot].populated && cio[slot].ivec >= 2) (cio_int_req |= (1 << slot))
|
||||
#define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot))
|
||||
|
||||
#define CIO_NAME_LEN 8
|
||||
|
||||
typedef struct {
|
||||
t_bool populated; /* Populated? */
|
||||
uint16 id; /* CIO identifier */
|
||||
char name[CIO_NAME_LEN]; /* Device name */
|
||||
void (*exp_handler)(uint8 slot); /* Handler for express jobs */
|
||||
void (*full_handler)(uint8 slot); /* Handler for full jobs */
|
||||
void (*sysgen)(uint8 slot); /* Sysgen routine (optional) */
|
||||
void (*reset_handler)(uint8 slot); /* RESET request handler (optional) */
|
||||
uint32 rqp; /* Request Queue Pointer */
|
||||
uint32 cqp; /* Completion Queue Pointer */
|
||||
uint8 rqs; /* Request queue size */
|
||||
uint8 cqs; /* Completion queue size */
|
||||
uint8 ivec; /* Interrupt Vector */
|
||||
uint8 no_rque; /* Number of request queues */
|
||||
uint8 ipl; /* IPL that this card uses */
|
||||
uint8 sysgen_s; /* Sysgen state */
|
||||
uint8 seqbit; /* Squence Bit */
|
||||
uint8 op; /* Last received opcode */
|
||||
} CIO_STATE;
|
||||
|
||||
typedef struct {
|
||||
uint16 byte_count;
|
||||
uint8 subdevice;
|
||||
uint8 opcode;
|
||||
uint32 address;
|
||||
} cio_entry;
|
||||
|
||||
typedef struct {
|
||||
uint32 low;
|
||||
uint32 high;
|
||||
uint32 (*read)(uint32 pa, size_t size);
|
||||
void (*write)(uint32 pa, uint32 val, size_t size);
|
||||
} iolink;
|
||||
|
||||
/* Example pump structure
|
||||
* ----------------------
|
||||
*
|
||||
* Used during initial setup of PORTS card in slot 0:
|
||||
*
|
||||
* dev = 0100
|
||||
* min = 0000
|
||||
* cmdcode = 0003
|
||||
* options = 0000
|
||||
* bufaddr = 808821A0
|
||||
* ioaddr = 00000500
|
||||
* size = 00000650
|
||||
* numbrd = 00000000
|
||||
* retcode = 00000008 (PU_NULL)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint16 dev;
|
||||
uint16 min;
|
||||
uint16 cmdcode;
|
||||
uint16 options;
|
||||
uint32 bufaddr;
|
||||
uint32 ioaddr;
|
||||
uint32 size;
|
||||
uint32 numbrd;
|
||||
uint32 retcode;
|
||||
} pump;
|
||||
|
||||
t_stat cio_reset(DEVICE *dptr);
|
||||
t_stat cio_svc(UNIT *uptr);
|
||||
|
||||
t_stat cio_install(uint16 id,
|
||||
CONST char *name,
|
||||
uint8 ipl,
|
||||
void (*exp_handler)(uint8 slot),
|
||||
void (*full_handler)(uint8 slot),
|
||||
void (*sysgen)(uint8 slot),
|
||||
void (*reset_handler)(uint8 slot),
|
||||
uint8 *slot);
|
||||
void cio_remove(uint8 slot);
|
||||
void cio_remove_all(uint16 id);
|
||||
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
|
||||
/* 3b2_io.h: Common I/O (CIO) Feature Card Support
|
||||
|
||||
Copyright (c) 2017-2022, 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.
|
||||
*/
|
||||
|
||||
/* Reference Documentation
|
||||
* =======================
|
||||
*
|
||||
* All communication between the system board and feature cards is
|
||||
* done through in-memory queues, and causing interrupts in the
|
||||
* feature card by accessing the Control or ID/VEC memory-mapped IO
|
||||
* addresses. The structure of these queues is defined below in
|
||||
* tables.
|
||||
*
|
||||
* Sysgen Block
|
||||
* ------------
|
||||
*
|
||||
* Pointed to by address at 0x2000000 after an INT0/INT1 combo
|
||||
*
|
||||
*
|
||||
* | Address | Size | Contents |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | SYSGEN_P | 4 | Address of request queue |
|
||||
* | SYSGEN_P + 4 | 4 | Address of completion queue |
|
||||
* | SYSGEN_P + 8 | 1 | Number of entries in request queue |
|
||||
* | SYSGEN_P + 9 | 1 | Number of entries in completion queue |
|
||||
* | SYSGEN_P + 10 | 1 | Interrupt Vector number |
|
||||
* | SYSGEN_P + 11 | 1 | Number of request queues |
|
||||
*
|
||||
*
|
||||
* Queue Entry
|
||||
* -----------
|
||||
*
|
||||
* Each queue has one Express Entry, and n regular entries.
|
||||
*
|
||||
* | Address | Size | Contents |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | ENTRY_P | 2 | Byte Count |
|
||||
* | ENTRY_P + 2 | 1 | Subdevice [1] |
|
||||
* | ENTRY_P + 3 | 1 | Opcode |
|
||||
* | ENTRY_P + 4 | 4 | Address / Data |
|
||||
* | ENTRY_P + 8 | 4 | Application Specific Data |
|
||||
*
|
||||
* [1] The "Subdevice" entry is further divided into a bitset:
|
||||
* Bit 7: Command (1) / Status (0)
|
||||
* Bit 6: Sequence Bit
|
||||
* Bit 5-1: Subdevice
|
||||
*
|
||||
*
|
||||
* Queue
|
||||
* -----
|
||||
*
|
||||
* The Queue structures (one for request, one for completion) hold:
|
||||
* - An express entry
|
||||
*
|
||||
* And then one or more queues, each queue consiting of
|
||||
* - A set of pointers for load and unload from the queue
|
||||
* - One or more Queue Entries
|
||||
*
|
||||
* | Address | Size | Contents |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | QUEUE_P | 12 | Express Queue Entry [1] |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | QUEUE_P + 12 | 2 | Load Pointer for Queue 0 |
|
||||
* | QUEUE_P + 14 | 2 | Unload Pointer for Queue 0 |
|
||||
* | QUEUE_P + 16 | 12 | Queue 0 Entry 0 [1] |
|
||||
* | QUEUE_P + 28 | 12 | Queue 0 Entry 1 [1] |
|
||||
* | ... | ... | ... |
|
||||
* +---------------+------+-----------------------------------------+
|
||||
* | QUEUE_P + n | 2 | Load 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 1 [1] |
|
||||
* | ... | ... | ... |
|
||||
*
|
||||
* [1] See Queue Entry above
|
||||
*
|
||||
* NB: There are multiple Request queues, usually one per subdevice,
|
||||
* and EACH Request queue starts with a Load Pointer, an Unload
|
||||
* Pointer, and then 'n' Queue Entries.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _3B2_IO_H_
|
||||
#define _3B2_IO_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define CRC_POLYNOMIAL 0xEDB88320
|
||||
|
||||
#define CIO_SLOTS 12
|
||||
|
||||
/* IO area */
|
||||
#define IO_BOTTOM 0x40000
|
||||
#define IO_TOP 0x50000
|
||||
|
||||
#if defined(REV3)
|
||||
#define UBUS_BOTTOM 0x1c00000
|
||||
#define UBUS_TOP 0x2000000
|
||||
#endif
|
||||
|
||||
/* CIO area */
|
||||
#define CIO_BOTTOM 0x200000
|
||||
#if defined(REV3)
|
||||
#define CIO_TOP 0x1a00000
|
||||
#else
|
||||
#define CIO_TOP 0x2000000
|
||||
#endif
|
||||
|
||||
#define IOF_ID 0
|
||||
#define IOF_VEC 1
|
||||
#define IOF_CTRL 3
|
||||
#define IOF_STAT 5
|
||||
|
||||
#define SYSGEN_PTR PHYS_MEM_BASE
|
||||
|
||||
/* CIO opcodes */
|
||||
#define CIO_DLM 1
|
||||
#define CIO_ULM 2
|
||||
#define CIO_FCF 3
|
||||
#define CIO_DOS 4
|
||||
#define CIO_DSD 5
|
||||
|
||||
/* Response */
|
||||
#define CIO_SUCCESS 0
|
||||
#define CIO_FAILURE 2
|
||||
#define CIO_SYSGEN_OK 3
|
||||
|
||||
/* Map a physical address to a card ID */
|
||||
#define SLOT(pa) (((((pa) >> 0x14) & 0x1f) / 2) - 1)
|
||||
/* Map a card ID to a base address */
|
||||
#define CADDR(bid) (((((bid) + 1) * 2) << 0x14))
|
||||
|
||||
/* Offsets into the request/completion queues of various values */
|
||||
#define LUSIZE 4 /* Load/Unload pointers size */
|
||||
#define QESIZE 8 /* Queue entry is 8 bytes + application data */
|
||||
|
||||
#define CIO_STAT 0
|
||||
#define CIO_CMD 1
|
||||
|
||||
/* Sysgen State */
|
||||
#define CIO_INT_NONE 0
|
||||
#define CIO_INT0 1
|
||||
#define CIO_INT1 2
|
||||
#define CIO_SYSGEN 3
|
||||
|
||||
#define CIO_SET_INT(slot) if (cio[slot].populated && cio[slot].ivec >= 2) (cio_int_req |= (1 << slot))
|
||||
#define CIO_CLR_INT(slot) (cio_int_req &= ~(1 << slot))
|
||||
|
||||
#define CIO_NAME_LEN 8
|
||||
|
||||
typedef struct {
|
||||
t_bool populated; /* Populated? */
|
||||
uint16 id; /* CIO identifier */
|
||||
char name[CIO_NAME_LEN]; /* Device name */
|
||||
void (*exp_handler)(uint8 slot); /* Handler for express jobs */
|
||||
void (*full_handler)(uint8 slot); /* Handler for full jobs */
|
||||
void (*sysgen)(uint8 slot); /* Sysgen routine (optional) */
|
||||
void (*reset_handler)(uint8 slot); /* RESET request handler (optional) */
|
||||
uint32 rqp; /* Request Queue Pointer */
|
||||
uint32 cqp; /* Completion Queue Pointer */
|
||||
uint8 rqs; /* Request queue size */
|
||||
uint8 cqs; /* Completion queue size */
|
||||
uint8 ivec; /* Interrupt Vector */
|
||||
uint8 no_rque; /* Number of request queues */
|
||||
uint8 ipl; /* IPL that this card uses */
|
||||
uint8 sysgen_s; /* Sysgen state */
|
||||
uint8 seqbit; /* Squence Bit */
|
||||
uint8 op; /* Last received opcode */
|
||||
} CIO_STATE;
|
||||
|
||||
typedef struct {
|
||||
uint16 byte_count;
|
||||
uint8 subdevice;
|
||||
uint8 opcode;
|
||||
uint32 address;
|
||||
} cio_entry;
|
||||
|
||||
typedef struct {
|
||||
uint32 low;
|
||||
uint32 high;
|
||||
uint32 (*read)(uint32 pa, size_t size);
|
||||
void (*write)(uint32 pa, uint32 val, size_t size);
|
||||
} iolink;
|
||||
|
||||
/* Example pump structure
|
||||
* ----------------------
|
||||
*
|
||||
* Used during initial setup of PORTS card in slot 0:
|
||||
*
|
||||
* dev = 0100
|
||||
* min = 0000
|
||||
* cmdcode = 0003
|
||||
* options = 0000
|
||||
* bufaddr = 808821A0
|
||||
* ioaddr = 00000500
|
||||
* size = 00000650
|
||||
* numbrd = 00000000
|
||||
* retcode = 00000008 (PU_NULL)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint16 dev;
|
||||
uint16 min;
|
||||
uint16 cmdcode;
|
||||
uint16 options;
|
||||
uint32 bufaddr;
|
||||
uint32 ioaddr;
|
||||
uint32 size;
|
||||
uint32 numbrd;
|
||||
uint32 retcode;
|
||||
} pump;
|
||||
|
||||
t_stat cio_reset(DEVICE *dptr);
|
||||
t_stat cio_svc(UNIT *uptr);
|
||||
|
||||
t_stat cio_install(uint16 id,
|
||||
CONST char *name,
|
||||
uint8 ipl,
|
||||
void (*exp_handler)(uint8 slot),
|
||||
void (*full_handler)(uint8 slot),
|
||||
void (*sysgen)(uint8 slot),
|
||||
void (*reset_handler)(uint8 slot),
|
||||
uint8 *slot);
|
||||
void cio_remove(uint8 slot);
|
||||
void cio_remove_all(uint16 id);
|
||||
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
|
||||
|
|
2294
3B2/3b2_iu.c
2294
3B2/3b2_iu.c
File diff suppressed because it is too large
Load diff
468
3B2/3b2_iu.h
468
3B2/3b2_iu.h
|
@ -1,234 +1,234 @@
|
|||
/* 3b2_iu.h: SCN2681A Dual UART
|
||||
|
||||
Copyright (c) 2017-2022, 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_IU_H__
|
||||
#define __3B2_IU_H__
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define CMD_ERX 0x01 /* Enable receiver */
|
||||
#define CMD_DRX 0x02 /* Disable receiver */
|
||||
#define CMD_ETX 0x04 /* Enable transmitter */
|
||||
#define CMD_DTX 0x08 /* Disable transmitter */
|
||||
#define CMD_MISC_SHIFT 4 /* Command */
|
||||
#define CMD_MISC_MASK 0x7
|
||||
|
||||
#define IU_SPEED_REGS 2 /* Two speed select registers, */
|
||||
#define IU_SPEEDS 16 /* with 16 speeds each */
|
||||
|
||||
#define IU_PARITY_ODD 0
|
||||
#define IU_PARITY_EVEN 1
|
||||
#define IU_PARITY_NONE 2
|
||||
|
||||
#define STS_RXR 0x01 /* Receiver ready */
|
||||
#define STS_FFL 0x02 /* FIFO full */
|
||||
#define STS_TXR 0x04 /* Transmitter ready */
|
||||
#define STS_TXE 0x08 /* Transmitter empty */
|
||||
#define STS_OER 0x10 /* Overrun error */
|
||||
#define STS_PER 0x20 /* Parity error */
|
||||
#define STS_FER 0x40 /* Framing error */
|
||||
#define STS_RXB 0x80 /* Received break */
|
||||
|
||||
#define ISTS_TXRA 0x01 /* Transmitter ready A */
|
||||
#define ISTS_RXRA 0x02 /* Receiver ready A */
|
||||
#define ISTS_DBA 0x04 /* Delta Break A */
|
||||
#define ISTS_CRI 0x08 /* Counter ready */
|
||||
#define ISTS_TXRB 0x10 /* Transmitter ready B */
|
||||
#define ISTS_RXRB 0x20 /* Receiver ready B */
|
||||
#define ISTS_DBB 0x40 /* Delta Break B */
|
||||
#define ISTS_IPC 0x80 /* Interrupt port change */
|
||||
|
||||
#define MODE_V_CHM 6 /* Channel mode */
|
||||
#define MODE_M_CHM 0x3
|
||||
|
||||
/* Transmitter State bits */
|
||||
#define T_HOLD 1
|
||||
#define T_XMIT 2
|
||||
|
||||
/* Used by the DMAC */
|
||||
#define IUA_DATA_REG 3
|
||||
#define IUB_DATA_REG 11
|
||||
|
||||
/* Registers - Read */
|
||||
#define SRA 1
|
||||
#define RHRA 3
|
||||
#define IPCR 4
|
||||
#define ISR 5
|
||||
#define CTU 6
|
||||
#define CTL 7
|
||||
#define SRB 9
|
||||
#define RHRB 11
|
||||
#define INPRT 13
|
||||
#define START_CTR 14
|
||||
#define STOP_CTR 15
|
||||
|
||||
/* Registers - Write */
|
||||
#define CSRA 1
|
||||
#define CRA 2
|
||||
#define THRA 3
|
||||
#define ACR 4
|
||||
#define IMR 5
|
||||
#define CTUR 6
|
||||
#define CTLR 7
|
||||
#define CSRB 9
|
||||
#define CRB 10
|
||||
#define THRB 11
|
||||
#define OPCR 13
|
||||
#define SOPR 14
|
||||
#define ROPR 15
|
||||
|
||||
/* Registers - R/W */
|
||||
#define MR12A 0
|
||||
#define MR12B 8
|
||||
|
||||
/* Port configuration */
|
||||
#define TX_EN 1
|
||||
#define RX_EN 2
|
||||
|
||||
/* Control Register commands */
|
||||
#define CR_RST_MR 1
|
||||
#define CR_RST_RX 2
|
||||
#define CR_RST_TX 3
|
||||
#define CR_RST_ERR 4
|
||||
#define CR_RST_BRK 5
|
||||
#define CR_START_BRK 6
|
||||
#define CR_STOP_BRK 7
|
||||
|
||||
/* IMR bits */
|
||||
#define IMR_TXRA 0x01
|
||||
#define IMR_RXRA 0x02
|
||||
#define IMR_CTR 0x08
|
||||
#define IMR_TXRB 0x10
|
||||
#define IMR_RXRB 0x20
|
||||
|
||||
/* Power-off bit */
|
||||
#define IU_KILLPWR 0x04
|
||||
|
||||
#define PORT_A 0
|
||||
#define PORT_B 1
|
||||
|
||||
#define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT)
|
||||
|
||||
#define IUBASE 0x49000
|
||||
#define IUSIZE 0x100
|
||||
|
||||
#define IU_BUF_SIZE 3
|
||||
|
||||
/* Data Carrier Detect inputs and input change bits */
|
||||
#if defined(REV3)
|
||||
#define IU_DCDB_CH 0x80
|
||||
#define IU_DCDA_CH 0x40
|
||||
#define IU_DCDB 0x08
|
||||
#define IU_DCDA 0x04
|
||||
#else
|
||||
#define IU_DCDB_CH 0x20
|
||||
#define IU_DCDA_CH 0x10
|
||||
#define IU_DCDB 0x02
|
||||
#define IU_DCDA 0x01
|
||||
#endif
|
||||
|
||||
/* Default baud rate generator (9600 baud) */
|
||||
#define BRG_DEFAULT 11
|
||||
|
||||
/* The 2681 DUART includes a 16-bit timer/counter that can be used to
|
||||
* trigger an interrupt after a certain amount of time has passed.
|
||||
*
|
||||
* The 2681 uses a crystal with a frequency of 3.686400 MHz, and the
|
||||
* timer/counter uses this frequency divided by 16, giving a final
|
||||
* timer/counter frequency of 230,400 Hz. There are therefore 4.34
|
||||
* microseconds of wall time per tick of the timer.
|
||||
*
|
||||
* The multiplier defined below is a default that can be adjusted to
|
||||
* make IU timing faster, but less accurate, if desired */
|
||||
|
||||
#define IU_TIMER_MULTIPLIER 4
|
||||
|
||||
typedef struct iu_port {
|
||||
uint8 cmd; /* Command */
|
||||
uint8 mode[2]; /* Two mode buffers */
|
||||
uint8 modep; /* Point to mode[0] or mode[1] */
|
||||
uint8 conf; /* Configuration bits */
|
||||
uint8 sr; /* Status Register */
|
||||
uint8 thr; /* Transmit Holding Register */
|
||||
uint8 txr; /* Transmit Shift Register */
|
||||
uint8 rxr; /* Receive Shift Register */
|
||||
uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */
|
||||
uint8 w_p; /* Receive Buffer Write Pointer */
|
||||
uint8 r_p; /* Receive Buffer Read Pointer */
|
||||
uint8 tx_state; /* Transmitting state flags (HOLD, XMIT) */
|
||||
t_bool dma; /* DMA currently active */
|
||||
t_bool drq; /* DMA request enabled */
|
||||
t_bool rxr_full; /* Receive Shift Register is full */
|
||||
} IU_PORT;
|
||||
|
||||
typedef struct iu_state {
|
||||
uint8 isr; /* Interrupt Status Register */
|
||||
uint8 imr; /* Interrupt Mask Register */
|
||||
uint8 acr; /* Aux. Control Register */
|
||||
uint8 opcr; /* Output Port Configuration */
|
||||
uint8 inprt; /* Input Port Data */
|
||||
uint8 ipcr; /* Input Port Change Register */
|
||||
} IU_STATE;
|
||||
|
||||
typedef struct iu_timer_state {
|
||||
uint16 c_set;
|
||||
t_bool c_en;
|
||||
} IU_TIMER_STATE;
|
||||
|
||||
/* Function prototypes */
|
||||
t_stat contty_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat contty_detach(UNIT *uptr);
|
||||
t_stat tti_reset(DEVICE *dptr);
|
||||
t_stat contty_reset(DEVICE *dptr);
|
||||
t_stat iu_timer_reset(DEVICE *dptr);
|
||||
t_stat iu_timer_set_mult(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, CONST void *desc);
|
||||
t_stat iu_svc_tti(UNIT *uptr);
|
||||
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
|
||||
/* 3b2_iu.h: SCN2681A Dual UART
|
||||
|
||||
Copyright (c) 2017-2022, 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_IU_H__
|
||||
#define __3B2_IU_H__
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define CMD_ERX 0x01 /* Enable receiver */
|
||||
#define CMD_DRX 0x02 /* Disable receiver */
|
||||
#define CMD_ETX 0x04 /* Enable transmitter */
|
||||
#define CMD_DTX 0x08 /* Disable transmitter */
|
||||
#define CMD_MISC_SHIFT 4 /* Command */
|
||||
#define CMD_MISC_MASK 0x7
|
||||
|
||||
#define IU_SPEED_REGS 2 /* Two speed select registers, */
|
||||
#define IU_SPEEDS 16 /* with 16 speeds each */
|
||||
|
||||
#define IU_PARITY_ODD 0
|
||||
#define IU_PARITY_EVEN 1
|
||||
#define IU_PARITY_NONE 2
|
||||
|
||||
#define STS_RXR 0x01 /* Receiver ready */
|
||||
#define STS_FFL 0x02 /* FIFO full */
|
||||
#define STS_TXR 0x04 /* Transmitter ready */
|
||||
#define STS_TXE 0x08 /* Transmitter empty */
|
||||
#define STS_OER 0x10 /* Overrun error */
|
||||
#define STS_PER 0x20 /* Parity error */
|
||||
#define STS_FER 0x40 /* Framing error */
|
||||
#define STS_RXB 0x80 /* Received break */
|
||||
|
||||
#define ISTS_TXRA 0x01 /* Transmitter ready A */
|
||||
#define ISTS_RXRA 0x02 /* Receiver ready A */
|
||||
#define ISTS_DBA 0x04 /* Delta Break A */
|
||||
#define ISTS_CRI 0x08 /* Counter ready */
|
||||
#define ISTS_TXRB 0x10 /* Transmitter ready B */
|
||||
#define ISTS_RXRB 0x20 /* Receiver ready B */
|
||||
#define ISTS_DBB 0x40 /* Delta Break B */
|
||||
#define ISTS_IPC 0x80 /* Interrupt port change */
|
||||
|
||||
#define MODE_V_CHM 6 /* Channel mode */
|
||||
#define MODE_M_CHM 0x3
|
||||
|
||||
/* Transmitter State bits */
|
||||
#define T_HOLD 1
|
||||
#define T_XMIT 2
|
||||
|
||||
/* Used by the DMAC */
|
||||
#define IUA_DATA_REG 3
|
||||
#define IUB_DATA_REG 11
|
||||
|
||||
/* Registers - Read */
|
||||
#define SRA 1
|
||||
#define RHRA 3
|
||||
#define IPCR 4
|
||||
#define ISR 5
|
||||
#define CTU 6
|
||||
#define CTL 7
|
||||
#define SRB 9
|
||||
#define RHRB 11
|
||||
#define INPRT 13
|
||||
#define START_CTR 14
|
||||
#define STOP_CTR 15
|
||||
|
||||
/* Registers - Write */
|
||||
#define CSRA 1
|
||||
#define CRA 2
|
||||
#define THRA 3
|
||||
#define ACR 4
|
||||
#define IMR 5
|
||||
#define CTUR 6
|
||||
#define CTLR 7
|
||||
#define CSRB 9
|
||||
#define CRB 10
|
||||
#define THRB 11
|
||||
#define OPCR 13
|
||||
#define SOPR 14
|
||||
#define ROPR 15
|
||||
|
||||
/* Registers - R/W */
|
||||
#define MR12A 0
|
||||
#define MR12B 8
|
||||
|
||||
/* Port configuration */
|
||||
#define TX_EN 1
|
||||
#define RX_EN 2
|
||||
|
||||
/* Control Register commands */
|
||||
#define CR_RST_MR 1
|
||||
#define CR_RST_RX 2
|
||||
#define CR_RST_TX 3
|
||||
#define CR_RST_ERR 4
|
||||
#define CR_RST_BRK 5
|
||||
#define CR_START_BRK 6
|
||||
#define CR_STOP_BRK 7
|
||||
|
||||
/* IMR bits */
|
||||
#define IMR_TXRA 0x01
|
||||
#define IMR_RXRA 0x02
|
||||
#define IMR_CTR 0x08
|
||||
#define IMR_TXRB 0x10
|
||||
#define IMR_RXRB 0x20
|
||||
|
||||
/* Power-off bit */
|
||||
#define IU_KILLPWR 0x04
|
||||
|
||||
#define PORT_A 0
|
||||
#define PORT_B 1
|
||||
|
||||
#define IU_MODE(x) ((x & UM_MASK) >> UM_SHIFT)
|
||||
|
||||
#define IUBASE 0x49000
|
||||
#define IUSIZE 0x100
|
||||
|
||||
#define IU_BUF_SIZE 3
|
||||
|
||||
/* Data Carrier Detect inputs and input change bits */
|
||||
#if defined(REV3)
|
||||
#define IU_DCDB_CH 0x80
|
||||
#define IU_DCDA_CH 0x40
|
||||
#define IU_DCDB 0x08
|
||||
#define IU_DCDA 0x04
|
||||
#else
|
||||
#define IU_DCDB_CH 0x20
|
||||
#define IU_DCDA_CH 0x10
|
||||
#define IU_DCDB 0x02
|
||||
#define IU_DCDA 0x01
|
||||
#endif
|
||||
|
||||
/* Default baud rate generator (9600 baud) */
|
||||
#define BRG_DEFAULT 11
|
||||
|
||||
/* The 2681 DUART includes a 16-bit timer/counter that can be used to
|
||||
* trigger an interrupt after a certain amount of time has passed.
|
||||
*
|
||||
* The 2681 uses a crystal with a frequency of 3.686400 MHz, and the
|
||||
* timer/counter uses this frequency divided by 16, giving a final
|
||||
* timer/counter frequency of 230,400 Hz. There are therefore 4.34
|
||||
* microseconds of wall time per tick of the timer.
|
||||
*
|
||||
* The multiplier defined below is a default that can be adjusted to
|
||||
* make IU timing faster, but less accurate, if desired */
|
||||
|
||||
#define IU_TIMER_MULTIPLIER 4
|
||||
|
||||
typedef struct iu_port {
|
||||
uint8 cmd; /* Command */
|
||||
uint8 mode[2]; /* Two mode buffers */
|
||||
uint8 modep; /* Point to mode[0] or mode[1] */
|
||||
uint8 conf; /* Configuration bits */
|
||||
uint8 sr; /* Status Register */
|
||||
uint8 thr; /* Transmit Holding Register */
|
||||
uint8 txr; /* Transmit Shift Register */
|
||||
uint8 rxr; /* Receive Shift Register */
|
||||
uint8 rxbuf[IU_BUF_SIZE]; /* Receive Holding Register (3 bytes) */
|
||||
uint8 w_p; /* Receive Buffer Write Pointer */
|
||||
uint8 r_p; /* Receive Buffer Read Pointer */
|
||||
uint8 tx_state; /* Transmitting state flags (HOLD, XMIT) */
|
||||
t_bool dma; /* DMA currently active */
|
||||
t_bool drq; /* DMA request enabled */
|
||||
t_bool rxr_full; /* Receive Shift Register is full */
|
||||
} IU_PORT;
|
||||
|
||||
typedef struct iu_state {
|
||||
uint8 isr; /* Interrupt Status Register */
|
||||
uint8 imr; /* Interrupt Mask Register */
|
||||
uint8 acr; /* Aux. Control Register */
|
||||
uint8 opcr; /* Output Port Configuration */
|
||||
uint8 inprt; /* Input Port Data */
|
||||
uint8 ipcr; /* Input Port Change Register */
|
||||
} IU_STATE;
|
||||
|
||||
typedef struct iu_timer_state {
|
||||
uint16 c_set;
|
||||
t_bool c_en;
|
||||
} IU_TIMER_STATE;
|
||||
|
||||
/* Function prototypes */
|
||||
t_stat contty_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat contty_detach(UNIT *uptr);
|
||||
t_stat tti_reset(DEVICE *dptr);
|
||||
t_stat contty_reset(DEVICE *dptr);
|
||||
t_stat iu_timer_reset(DEVICE *dptr);
|
||||
t_stat iu_timer_set_mult(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat iu_timer_show_mult(FILE *st, UNIT *uptr, int val, CONST void *desc);
|
||||
t_stat iu_svc_tti(UNIT *uptr);
|
||||
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
|
||||
|
|
7190
3B2/3b2_mau.c
7190
3B2/3b2_mau.c
File diff suppressed because it is too large
Load diff
778
3B2/3b2_mau.h
778
3B2/3b2_mau.h
|
@ -1,389 +1,389 @@
|
|||
/* 3b2_mau.h: WE32106 and WE32206 Math Accelerator Unit
|
||||
|
||||
Copyright (c) 2021-2022, 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 WE 32106 and WE 32206 Math
|
||||
Acceleration Units. The WE 32106 and WE 32206 are IEEE-754
|
||||
compabitle floating point hardware math accelerators that were
|
||||
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
|
||||
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_ */
|
||||
/* 3b2_mau.h: WE32106 and WE32206 Math Accelerator Unit
|
||||
|
||||
Copyright (c) 2021-2022, 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 WE 32106 and WE 32206 Math
|
||||
Acceleration Units. The WE 32106 and WE 32206 are IEEE-754
|
||||
compabitle floating point hardware math accelerators that were
|
||||
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
|
||||
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_ */
|
||||
|
|
692
3B2/3b2_mem.c
692
3B2/3b2_mem.c
|
@ -1,346 +1,346 @@
|
|||
/* 3b2_mem.c: Memory Map Access Routines
|
||||
|
||||
Copyright (c) 2021-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_mem.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_io.h"
|
||||
#include "3b2_mmu.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_dmac.h"
|
||||
|
||||
#if defined(REV3)
|
||||
static uint32 ecc_addr; /* ECC address */
|
||||
static t_bool ecc_err; /* ECC multi-bit error */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
static SIM_INLINE void check_ecc(uint32 pa, t_bool write, uint8 src)
|
||||
{
|
||||
#if defined(REV3)
|
||||
/* Force ECC Syndrome mode enables a diagnostic mode on the AM2960
|
||||
data correction ICs */
|
||||
if (write && !CSR(CSRFECC)) {
|
||||
sim_debug(EXECUTE_MSG, &mmu_dev,
|
||||
"ECC Error on Write. pa=%08x\n",
|
||||
pa);
|
||||
ecc_addr = pa;
|
||||
ecc_err = TRUE;
|
||||
} else if (ecc_err && !write && pa == ecc_addr) {
|
||||
sim_debug(EXECUTE_MSG, &mmu_dev,
|
||||
"ECC Error detected on Read. pa=%08x psw=%08x cur_ipl=%d csr=%08x\n",
|
||||
pa, R[NUM_PSW], PSW_CUR_IPL, csr_data);
|
||||
flt[0] = ecc_addr & 0x3ffff;
|
||||
flt[1] = MA_CPU_IO|MA_CPU_BU;
|
||||
ecc_err = FALSE;
|
||||
CSRBIT(CSRFRF, TRUE); /* Fault registers frozen */
|
||||
CSRBIT(CSRMBERR, TRUE); /* Multi-bit error */
|
||||
CPU_SET_INT(INT_MBERR);
|
||||
/* Only abort if CPU is doing the read */
|
||||
if (src == BUS_CPU) {
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Read Word (Physical Address) */
|
||||
uint32 pread_w(uint32 pa, uint8 src)
|
||||
{
|
||||
uint8 *m;
|
||||
uint32 index = 0;
|
||||
|
||||
#if defined(REV3)
|
||||
if ((pa & 3) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
|
||||
#else
|
||||
if (pa & 3) {
|
||||
#endif
|
||||
sim_debug(READ_MSG, &mmu_dev,
|
||||
"Cannot read physical address. ALIGNMENT ISSUE: %08x\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
return io_read(pa, 32);
|
||||
}
|
||||
|
||||
if (IS_ROM(pa)) {
|
||||
m = ROM;
|
||||
index = pa;
|
||||
} else if (IS_RAM(pa)) {
|
||||
check_ecc(pa, FALSE, src);
|
||||
m = RAM;
|
||||
index = (pa - PHYS_MEM_BASE);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ATOW(m, index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write Word (Physical Address)
|
||||
*/
|
||||
void pwrite_w(uint32 pa, uint32 val, uint8 src)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
if (pa & 3) {
|
||||
sim_debug(WRITE_MSG, &mmu_dev,
|
||||
"Cannot write physical address. ALIGNMENT ISSUE: %08x\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
io_write(pa, val, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_RAM(pa)) {
|
||||
check_ecc(pa, TRUE, src);
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
RAM[index] = (val >> 24) & 0xff;
|
||||
RAM[index + 1] = (val >> 16) & 0xff;
|
||||
RAM[index + 2] = (val >> 8) & 0xff;
|
||||
RAM[index + 3] = val & 0xff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read Halfword (Physical Address)
|
||||
*/
|
||||
uint16 pread_h(uint32 pa, uint8 src)
|
||||
{
|
||||
uint8 *m;
|
||||
uint32 index;
|
||||
|
||||
if (pa & 1) {
|
||||
sim_debug(READ_MSG, &mmu_dev,
|
||||
"Cannot read physical address. ALIGNMENT ISSUE %08x\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
return (uint16) io_read(pa, 16);
|
||||
}
|
||||
|
||||
if (IS_ROM(pa)) {
|
||||
m = ROM;
|
||||
index = pa;
|
||||
} else if (IS_RAM(pa)) {
|
||||
check_ecc(pa, FALSE, src);
|
||||
m = RAM;
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ATOH(m, index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write Halfword (Physical Address)
|
||||
*/
|
||||
void pwrite_h(uint32 pa, uint16 val, uint8 src)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
#if defined(REV3)
|
||||
if ((pa & 1) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
|
||||
#else
|
||||
if (pa & 1) {
|
||||
#endif
|
||||
sim_debug(WRITE_MSG, &mmu_dev,
|
||||
"Cannot write physical address %08x, ALIGNMENT ISSUE\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
io_write(pa, val, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_RAM(pa)) {
|
||||
check_ecc(pa, TRUE, src);
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
RAM[index] = (val >> 8) & 0xff;
|
||||
RAM[index + 1] = val & 0xff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read Byte (Physical Address)
|
||||
*/
|
||||
uint8 pread_b(uint32 pa, uint8 src)
|
||||
{
|
||||
if (IS_IO(pa)) {
|
||||
return (uint8)(io_read(pa, 8));
|
||||
}
|
||||
|
||||
if (IS_ROM(pa)) {
|
||||
return ROM[pa];
|
||||
} else if (IS_RAM(pa)) {
|
||||
check_ecc(pa, FALSE, src);
|
||||
return RAM[pa - PHYS_MEM_BASE];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write Byte (Physical Address) */
|
||||
void pwrite_b(uint32 pa, uint8 val, uint8 src)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
io_write(pa, val, 8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_RAM(pa)) {
|
||||
check_ecc(pa, TRUE, src);
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
RAM[index] = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write to ROM (used by ROM load) */
|
||||
void pwrite_b_rom(uint32 pa, uint8 val) {
|
||||
if (IS_ROM(pa)) {
|
||||
ROM[pa] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read Byte (Virtual Address) */
|
||||
uint8 read_b(uint32 va, uint8 r_acc, uint8 src)
|
||||
{
|
||||
return pread_b(mmu_xlate_addr(va, r_acc), src);
|
||||
}
|
||||
|
||||
/* Write Byte (Virtual Address) */
|
||||
void write_b(uint32 va, uint8 val, uint8 src)
|
||||
{
|
||||
pwrite_b(mmu_xlate_addr(va, ACC_W), val, src);
|
||||
}
|
||||
|
||||
/* Read Halfword (Virtual Address) */
|
||||
uint16 read_h(uint32 va, uint8 r_acc, uint8 src)
|
||||
{
|
||||
return pread_h(mmu_xlate_addr(va, r_acc), src);
|
||||
}
|
||||
|
||||
/* Write Halfword (Virtual Address) */
|
||||
void write_h(uint32 va, uint16 val, uint8 src)
|
||||
{
|
||||
pwrite_h(mmu_xlate_addr(va, ACC_W), val, src);
|
||||
}
|
||||
|
||||
/* Read Word (Virtual Address) */
|
||||
uint32 read_w(uint32 va, uint8 r_acc, uint8 src)
|
||||
{
|
||||
return pread_w(mmu_xlate_addr(va, r_acc), src);
|
||||
}
|
||||
|
||||
/* Write Word (Virtual Address) */
|
||||
void write_w(uint32 va, uint32 val, uint8 src)
|
||||
{
|
||||
pwrite_w(mmu_xlate_addr(va, ACC_W), val, src);
|
||||
}
|
||||
|
||||
t_stat read_operand(uint32 va, uint8 *val)
|
||||
{
|
||||
uint32 pa;
|
||||
t_stat succ;
|
||||
|
||||
succ = mmu_decode_va(va, ACC_IF, TRUE, &pa);
|
||||
|
||||
if (succ == SCPE_OK) {
|
||||
*val = pread_b(pa, BUS_CPU);
|
||||
} else {
|
||||
*val = 0;
|
||||
}
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
t_stat examine(uint32 va, uint8 *val)
|
||||
{
|
||||
uint32 pa;
|
||||
t_stat succ;
|
||||
|
||||
succ = mmu_decode_va(va, 0, FALSE, &pa);
|
||||
|
||||
if (succ == SCPE_OK) {
|
||||
if (IS_ROM(pa) || IS_RAM(pa)) {
|
||||
*val = pread_b(pa, BUS_CPU);
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
*val = 0;
|
||||
return SCPE_NXM;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
/* 3b2_mem.c: Memory Map Access Routines
|
||||
|
||||
Copyright (c) 2021-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_mem.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_io.h"
|
||||
#include "3b2_mmu.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_dmac.h"
|
||||
|
||||
#if defined(REV3)
|
||||
static uint32 ecc_addr; /* ECC address */
|
||||
static t_bool ecc_err; /* ECC multi-bit error */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
static SIM_INLINE void check_ecc(uint32 pa, t_bool write, uint8 src)
|
||||
{
|
||||
#if defined(REV3)
|
||||
/* Force ECC Syndrome mode enables a diagnostic mode on the AM2960
|
||||
data correction ICs */
|
||||
if (write && !CSR(CSRFECC)) {
|
||||
sim_debug(EXECUTE_MSG, &mmu_dev,
|
||||
"ECC Error on Write. pa=%08x\n",
|
||||
pa);
|
||||
ecc_addr = pa;
|
||||
ecc_err = TRUE;
|
||||
} else if (ecc_err && !write && pa == ecc_addr) {
|
||||
sim_debug(EXECUTE_MSG, &mmu_dev,
|
||||
"ECC Error detected on Read. pa=%08x psw=%08x cur_ipl=%d csr=%08x\n",
|
||||
pa, R[NUM_PSW], PSW_CUR_IPL, csr_data);
|
||||
flt[0] = ecc_addr & 0x3ffff;
|
||||
flt[1] = MA_CPU_IO|MA_CPU_BU;
|
||||
ecc_err = FALSE;
|
||||
CSRBIT(CSRFRF, TRUE); /* Fault registers frozen */
|
||||
CSRBIT(CSRMBERR, TRUE); /* Multi-bit error */
|
||||
CPU_SET_INT(INT_MBERR);
|
||||
/* Only abort if CPU is doing the read */
|
||||
if (src == BUS_CPU) {
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Read Word (Physical Address) */
|
||||
uint32 pread_w(uint32 pa, uint8 src)
|
||||
{
|
||||
uint8 *m;
|
||||
uint32 index = 0;
|
||||
|
||||
#if defined(REV3)
|
||||
if ((pa & 3) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
|
||||
#else
|
||||
if (pa & 3) {
|
||||
#endif
|
||||
sim_debug(READ_MSG, &mmu_dev,
|
||||
"Cannot read physical address. ALIGNMENT ISSUE: %08x\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
return io_read(pa, 32);
|
||||
}
|
||||
|
||||
if (IS_ROM(pa)) {
|
||||
m = ROM;
|
||||
index = pa;
|
||||
} else if (IS_RAM(pa)) {
|
||||
check_ecc(pa, FALSE, src);
|
||||
m = RAM;
|
||||
index = (pa - PHYS_MEM_BASE);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ATOW(m, index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write Word (Physical Address)
|
||||
*/
|
||||
void pwrite_w(uint32 pa, uint32 val, uint8 src)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
if (pa & 3) {
|
||||
sim_debug(WRITE_MSG, &mmu_dev,
|
||||
"Cannot write physical address. ALIGNMENT ISSUE: %08x\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
io_write(pa, val, 32);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_RAM(pa)) {
|
||||
check_ecc(pa, TRUE, src);
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
RAM[index] = (val >> 24) & 0xff;
|
||||
RAM[index + 1] = (val >> 16) & 0xff;
|
||||
RAM[index + 2] = (val >> 8) & 0xff;
|
||||
RAM[index + 3] = val & 0xff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read Halfword (Physical Address)
|
||||
*/
|
||||
uint16 pread_h(uint32 pa, uint8 src)
|
||||
{
|
||||
uint8 *m;
|
||||
uint32 index;
|
||||
|
||||
if (pa & 1) {
|
||||
sim_debug(READ_MSG, &mmu_dev,
|
||||
"Cannot read physical address. ALIGNMENT ISSUE %08x\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
cpu_abort(NORMAL_EXCEPTION, EXTERNAL_MEMORY_FAULT);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
return (uint16) io_read(pa, 16);
|
||||
}
|
||||
|
||||
if (IS_ROM(pa)) {
|
||||
m = ROM;
|
||||
index = pa;
|
||||
} else if (IS_RAM(pa)) {
|
||||
check_ecc(pa, FALSE, src);
|
||||
m = RAM;
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ATOH(m, index);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write Halfword (Physical Address)
|
||||
*/
|
||||
void pwrite_h(uint32 pa, uint16 val, uint8 src)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
#if defined(REV3)
|
||||
if ((pa & 1) && (R[NUM_PSW] & PSW_EA_MASK) == 0) {
|
||||
#else
|
||||
if (pa & 1) {
|
||||
#endif
|
||||
sim_debug(WRITE_MSG, &mmu_dev,
|
||||
"Cannot write physical address %08x, ALIGNMENT ISSUE\n",
|
||||
pa);
|
||||
CSRBIT(CSRALGN, TRUE);
|
||||
}
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
io_write(pa, val, 16);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_RAM(pa)) {
|
||||
check_ecc(pa, TRUE, src);
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
RAM[index] = (val >> 8) & 0xff;
|
||||
RAM[index + 1] = val & 0xff;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Read Byte (Physical Address)
|
||||
*/
|
||||
uint8 pread_b(uint32 pa, uint8 src)
|
||||
{
|
||||
if (IS_IO(pa)) {
|
||||
return (uint8)(io_read(pa, 8));
|
||||
}
|
||||
|
||||
if (IS_ROM(pa)) {
|
||||
return ROM[pa];
|
||||
} else if (IS_RAM(pa)) {
|
||||
check_ecc(pa, FALSE, src);
|
||||
return RAM[pa - PHYS_MEM_BASE];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write Byte (Physical Address) */
|
||||
void pwrite_b(uint32 pa, uint8 val, uint8 src)
|
||||
{
|
||||
uint32 index;
|
||||
|
||||
if (IS_IO(pa)) {
|
||||
io_write(pa, val, 8);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_RAM(pa)) {
|
||||
check_ecc(pa, TRUE, src);
|
||||
index = pa - PHYS_MEM_BASE;
|
||||
RAM[index] = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write to ROM (used by ROM load) */
|
||||
void pwrite_b_rom(uint32 pa, uint8 val) {
|
||||
if (IS_ROM(pa)) {
|
||||
ROM[pa] = val;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read Byte (Virtual Address) */
|
||||
uint8 read_b(uint32 va, uint8 r_acc, uint8 src)
|
||||
{
|
||||
return pread_b(mmu_xlate_addr(va, r_acc), src);
|
||||
}
|
||||
|
||||
/* Write Byte (Virtual Address) */
|
||||
void write_b(uint32 va, uint8 val, uint8 src)
|
||||
{
|
||||
pwrite_b(mmu_xlate_addr(va, ACC_W), val, src);
|
||||
}
|
||||
|
||||
/* Read Halfword (Virtual Address) */
|
||||
uint16 read_h(uint32 va, uint8 r_acc, uint8 src)
|
||||
{
|
||||
return pread_h(mmu_xlate_addr(va, r_acc), src);
|
||||
}
|
||||
|
||||
/* Write Halfword (Virtual Address) */
|
||||
void write_h(uint32 va, uint16 val, uint8 src)
|
||||
{
|
||||
pwrite_h(mmu_xlate_addr(va, ACC_W), val, src);
|
||||
}
|
||||
|
||||
/* Read Word (Virtual Address) */
|
||||
uint32 read_w(uint32 va, uint8 r_acc, uint8 src)
|
||||
{
|
||||
return pread_w(mmu_xlate_addr(va, r_acc), src);
|
||||
}
|
||||
|
||||
/* Write Word (Virtual Address) */
|
||||
void write_w(uint32 va, uint32 val, uint8 src)
|
||||
{
|
||||
pwrite_w(mmu_xlate_addr(va, ACC_W), val, src);
|
||||
}
|
||||
|
||||
t_stat read_operand(uint32 va, uint8 *val)
|
||||
{
|
||||
uint32 pa;
|
||||
t_stat succ;
|
||||
|
||||
succ = mmu_decode_va(va, ACC_IF, TRUE, &pa);
|
||||
|
||||
if (succ == SCPE_OK) {
|
||||
*val = pread_b(pa, BUS_CPU);
|
||||
} else {
|
||||
*val = 0;
|
||||
}
|
||||
|
||||
return succ;
|
||||
}
|
||||
|
||||
t_stat examine(uint32 va, uint8 *val)
|
||||
{
|
||||
uint32 pa;
|
||||
t_stat succ;
|
||||
|
||||
succ = mmu_decode_va(va, 0, FALSE, &pa);
|
||||
|
||||
if (succ == SCPE_OK) {
|
||||
if (IS_ROM(pa) || IS_RAM(pa)) {
|
||||
*val = pread_b(pa, BUS_CPU);
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
*val = 0;
|
||||
return SCPE_NXM;
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
|
158
3B2/3b2_mem.h
158
3B2/3b2_mem.h
|
@ -1,79 +1,79 @@
|
|||
/* 3b2_mem.h: Memory Map Access Routines
|
||||
|
||||
Copyright (c) 2021-2022, 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_MEM_H_
|
||||
#define _3B2_MEM_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define IS_ROM(PA) ((PA) < ROM_SIZE)
|
||||
#define IS_RAM(PA) (((PA) >= PHYS_MEM_BASE) && ((PA) < (PHYS_MEM_BASE + MEM_SIZE)))
|
||||
#if defined(REV3)
|
||||
#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
|
||||
((PA >= CIO_BOTTOM) && (PA < CIO_TOP)) || \
|
||||
((PA >= VCACHE_BOTTOM) && (PA < VCACHE_TOP)) || \
|
||||
((PA >= BUB_BOTTOM) && (PA < BUB_TOP)))
|
||||
#else
|
||||
#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
|
||||
((PA >= CIO_BOTTOM) && (PA < CIO_TOP)))
|
||||
#endif
|
||||
|
||||
#define MA_BUB3 0x100 /* BUBUS slot 3 master on fault */
|
||||
#define MA_BUB2 0x200 /* BUBUS slot 2 master on fault */
|
||||
#define MA_BUB1 0x400 /* BUBUS slot 1 master on fault */
|
||||
#define MA_CPU_BU 0x2000 /* CPU access BUBUS peripheral */
|
||||
#define MA_BUB0 0x4000 /* BUBUS slot 0 master on fault */
|
||||
#define MA_CPU_IO 0x8000 /* CPU accessing I/O peripheral */
|
||||
#define MA_IO_NLY 0x10000 /* IO Bus Master on fault */
|
||||
#define MA_IO_BM 0x80000 /* IO Bus Master or BUBUS was master on fault */
|
||||
|
||||
#define BUS_PER 0 /* Read or Write is from peripheral */
|
||||
#define BUS_CPU 1 /* Read or Write is from CPU */
|
||||
|
||||
uint32 pread_w(uint32 pa, uint8 src);
|
||||
void pwrite_w(uint32 pa, uint32 val, uint8 src);
|
||||
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_ */
|
||||
/* 3b2_mem.h: Memory Map Access Routines
|
||||
|
||||
Copyright (c) 2021-2022, 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_MEM_H_
|
||||
#define _3B2_MEM_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define IS_ROM(PA) ((PA) < ROM_SIZE)
|
||||
#define IS_RAM(PA) (((PA) >= PHYS_MEM_BASE) && ((PA) < (PHYS_MEM_BASE + MEM_SIZE)))
|
||||
#if defined(REV3)
|
||||
#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
|
||||
((PA >= CIO_BOTTOM) && (PA < CIO_TOP)) || \
|
||||
((PA >= VCACHE_BOTTOM) && (PA < VCACHE_TOP)) || \
|
||||
((PA >= BUB_BOTTOM) && (PA < BUB_TOP)))
|
||||
#else
|
||||
#define IS_IO(PA) (((PA >= IO_BOTTOM) && (PA < IO_TOP)) || \
|
||||
((PA >= CIO_BOTTOM) && (PA < CIO_TOP)))
|
||||
#endif
|
||||
|
||||
#define MA_BUB3 0x100 /* BUBUS slot 3 master on fault */
|
||||
#define MA_BUB2 0x200 /* BUBUS slot 2 master on fault */
|
||||
#define MA_BUB1 0x400 /* BUBUS slot 1 master on fault */
|
||||
#define MA_CPU_BU 0x2000 /* CPU access BUBUS peripheral */
|
||||
#define MA_BUB0 0x4000 /* BUBUS slot 0 master on fault */
|
||||
#define MA_CPU_IO 0x8000 /* CPU accessing I/O peripheral */
|
||||
#define MA_IO_NLY 0x10000 /* IO Bus Master on fault */
|
||||
#define MA_IO_BM 0x80000 /* IO Bus Master or BUBUS was master on fault */
|
||||
|
||||
#define BUS_PER 0 /* Read or Write is from peripheral */
|
||||
#define BUS_CPU 1 /* Read or Write is from CPU */
|
||||
|
||||
uint32 pread_w(uint32 pa, uint8 src);
|
||||
void pwrite_w(uint32 pa, uint32 val, uint8 src);
|
||||
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_ */
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
/* 3b2_mmu.h: Common MMU header
|
||||
|
||||
Copyright (c) 2021-2022, 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_MMU_H_
|
||||
#define _3B2_MMU_H_
|
||||
|
||||
#if defined(REV3)
|
||||
#include "3b2_rev3_mmu.h"
|
||||
#else
|
||||
#include "3b2_rev2_mmu.h"
|
||||
#endif
|
||||
|
||||
#endif /* _3B2_MMU_H_ */
|
||||
/* 3b2_mmu.h: Common MMU header
|
||||
|
||||
Copyright (c) 2021-2022, 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_MMU_H_
|
||||
#define _3B2_MMU_H_
|
||||
|
||||
#if defined(REV3)
|
||||
#include "3b2_rev3_mmu.h"
|
||||
#else
|
||||
#include "3b2_rev2_mmu.h"
|
||||
#endif
|
||||
|
||||
#endif /* _3B2_MMU_H_ */
|
||||
|
|
2242
3B2/3b2_ni.c
2242
3B2/3b2_ni.c
File diff suppressed because it is too large
Load diff
420
3B2/3b2_ni.h
420
3B2/3b2_ni.h
|
@ -1,210 +1,210 @@
|
|||
/* 3b2_ni.h: CM195A Network Interface CIO Card
|
||||
|
||||
Copyright (c) 2018-2022, 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_NI_H_
|
||||
#define _3B2_NI_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
#include "sim_ether.h"
|
||||
|
||||
#define NI_ID 0x0002
|
||||
#define NI_IPL 12
|
||||
|
||||
/* Opcodes for NI card */
|
||||
|
||||
#define NI_SETID 6
|
||||
#define NI_TURNOFF 7
|
||||
#define NI_TURNON 8
|
||||
#define NI_SEND 11
|
||||
#define NI_RECV 12
|
||||
#define NI_STATS 13
|
||||
#define NI_SANITY 15
|
||||
#define NI_SEND_A 22
|
||||
|
||||
#define MAC_SIZE_BYTES 6
|
||||
#define MAC_SIZE_CHARS 20
|
||||
|
||||
#define NIQESIZE 12
|
||||
#define NI_QUE_MAX 1024
|
||||
#define NI_INT_DELAY 10000
|
||||
#define NI_SANITY_INTERVAL_US 5000000
|
||||
|
||||
/* Maximum allowed number of multicast addresses */
|
||||
#define NI_MULTI_MAX 64
|
||||
|
||||
/* At least two filter addresses are always configured:
|
||||
* 1. The host MAC
|
||||
* 2. The broadcast address */
|
||||
#define NI_FILTER_MIN 2
|
||||
|
||||
/* Maximum total allowed number of filter addresses, including the
|
||||
* host's MAC and the broadcast address. */
|
||||
#define NI_FILTER_MAX NI_MULTI_MAX + NI_FILTER_MIN
|
||||
|
||||
/* Indexes in the internal filter address table of the
|
||||
* host's MAC and the broadcast address */
|
||||
#define NI_NIC_MAC 0
|
||||
#define NI_BCST_MAC 1
|
||||
|
||||
/*
|
||||
* For performance reasons, there are two modes of polling the receive
|
||||
* queues. Initially, polling is VERY aggressive as we race the
|
||||
* filling of the receive queues. Once we've taken three jobs from
|
||||
* each of the two receive queues, we switch to slow polling,
|
||||
* which uses coscheduling.
|
||||
*/
|
||||
|
||||
#define NI_QPOLL_FAST 100
|
||||
#define NI_QPOLL_SLOW 50000
|
||||
|
||||
#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
|
||||
* 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 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
|
||||
#define DBG_IO 0x02
|
||||
#define DBG_CACHE 0x04
|
||||
#define DBG_DAT 0x08
|
||||
#define DBG_ERR 0x10
|
||||
#define DBG_ETH 0x20
|
||||
|
||||
#define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.')
|
||||
|
||||
#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp)
|
||||
/* 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.
|
||||
* Each job is represented by an ni_rec_job structure, containing a
|
||||
* buffer pointer and a slot number. The slot number is used by both
|
||||
* the driver and the firmware to correlate a packet receive buffer
|
||||
* with a completion queue event.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 addr; /* address of job's buffer */
|
||||
uint8 slot; /* slot number of the job */
|
||||
} ni_rec_job;
|
||||
|
||||
#define NI_CACHE_LEN 4
|
||||
|
||||
typedef struct {
|
||||
ni_rec_job req[NI_CACHE_LEN]; /* the 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
|
||||
* packet (minus the Ethernet frame). These structs are packed one
|
||||
* after the other following the Ethernet frame header in the job's
|
||||
* request buffer. The last entry has its "last" bit set to non-zero.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 addr; /* Physical address of the buffer in system RAM */
|
||||
uint16 size; /* Length of the buffer */
|
||||
uint16 last; /* Is this the last entry in the list? */
|
||||
} ni_prot_info;
|
||||
|
||||
typedef struct {
|
||||
uint32 rq_taken;
|
||||
uint32 tx_fail;
|
||||
uint32 rx_dropped;
|
||||
uint32 rx_pkt;
|
||||
uint32 tx_pkt;
|
||||
uint32 rx_bytes;
|
||||
uint32 tx_bytes;
|
||||
} ni_stat_info;
|
||||
|
||||
typedef struct {
|
||||
uint8 slot;
|
||||
t_bool enabled;
|
||||
uint32 crc;
|
||||
uint32 poll_rate;
|
||||
char mac_str[MAC_SIZE_CHARS];
|
||||
uint8 mac_bytes[MAC_SIZE_BYTES];
|
||||
ni_job_cache job_cache[2];
|
||||
ni_prot_info prot;
|
||||
ni_stat_info stats;
|
||||
uint8 fcf_seq;
|
||||
ETH_DEV* eth;
|
||||
ETH_PACK rd_buf;
|
||||
ETH_PACK wr_buf;
|
||||
ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */
|
||||
int filter_count; /* Number of filters available */
|
||||
ETH_PCALLBACK callback;
|
||||
} NI_STATE;
|
||||
|
||||
void ni_recv_callback(int status);
|
||||
t_stat ni_reset(DEVICE *dptr);
|
||||
t_stat ni_rcv_svc(UNIT *uptr);
|
||||
t_stat ni_sanity_svc(UNIT *uptr);
|
||||
t_stat ni_rq_svc(UNIT *uptr);
|
||||
t_stat ni_cio_svc(UNIT *uptr);
|
||||
t_stat ni_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat ni_detach(UNIT *uptr);
|
||||
t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat ni_try_job(uint8 slot);
|
||||
t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
const char *ni_description(DEVICE *dptr);
|
||||
t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
void ni_cio_reset(uint8 slot);
|
||||
void ni_process_packet();
|
||||
void ni_int_ack(uint8 slot);
|
||||
void ni_sysgen(uint8 slot);
|
||||
void ni_express(uint8 slot);
|
||||
void ni_full(uint8 slot);
|
||||
|
||||
#endif /* _3B2_NI_H_ */
|
||||
/* 3b2_ni.h: CM195A Network Interface CIO Card
|
||||
|
||||
Copyright (c) 2018-2022, 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_NI_H_
|
||||
#define _3B2_NI_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
#include "sim_ether.h"
|
||||
|
||||
#define NI_ID 0x0002
|
||||
#define NI_IPL 12
|
||||
|
||||
/* Opcodes for NI card */
|
||||
|
||||
#define NI_SETID 6
|
||||
#define NI_TURNOFF 7
|
||||
#define NI_TURNON 8
|
||||
#define NI_SEND 11
|
||||
#define NI_RECV 12
|
||||
#define NI_STATS 13
|
||||
#define NI_SANITY 15
|
||||
#define NI_SEND_A 22
|
||||
|
||||
#define MAC_SIZE_BYTES 6
|
||||
#define MAC_SIZE_CHARS 20
|
||||
|
||||
#define NIQESIZE 12
|
||||
#define NI_QUE_MAX 1024
|
||||
#define NI_INT_DELAY 10000
|
||||
#define NI_SANITY_INTERVAL_US 5000000
|
||||
|
||||
/* Maximum allowed number of multicast addresses */
|
||||
#define NI_MULTI_MAX 64
|
||||
|
||||
/* At least two filter addresses are always configured:
|
||||
* 1. The host MAC
|
||||
* 2. The broadcast address */
|
||||
#define NI_FILTER_MIN 2
|
||||
|
||||
/* Maximum total allowed number of filter addresses, including the
|
||||
* host's MAC and the broadcast address. */
|
||||
#define NI_FILTER_MAX NI_MULTI_MAX + NI_FILTER_MIN
|
||||
|
||||
/* Indexes in the internal filter address table of the
|
||||
* host's MAC and the broadcast address */
|
||||
#define NI_NIC_MAC 0
|
||||
#define NI_BCST_MAC 1
|
||||
|
||||
/*
|
||||
* For performance reasons, there are two modes of polling the receive
|
||||
* queues. Initially, polling is VERY aggressive as we race the
|
||||
* filling of the receive queues. Once we've taken three jobs from
|
||||
* each of the two receive queues, we switch to slow polling,
|
||||
* which uses coscheduling.
|
||||
*/
|
||||
|
||||
#define NI_QPOLL_FAST 100
|
||||
#define NI_QPOLL_SLOW 50000
|
||||
|
||||
#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
|
||||
* 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 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
|
||||
#define DBG_IO 0x02
|
||||
#define DBG_CACHE 0x04
|
||||
#define DBG_DAT 0x08
|
||||
#define DBG_ERR 0x10
|
||||
#define DBG_ETH 0x20
|
||||
|
||||
#define CHAR(c) ((((c) >= 0x20) && ((c) < 0x7f)) ? (c) : '.')
|
||||
|
||||
#define NI_CACHE_HAS_SPACE(i) (((ni.job_cache[(i)].wp + 1) % NI_CACHE_LEN) != ni.job_cache[(i)].rp)
|
||||
/* 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.
|
||||
* Each job is represented by an ni_rec_job structure, containing a
|
||||
* buffer pointer and a slot number. The slot number is used by both
|
||||
* the driver and the firmware to correlate a packet receive buffer
|
||||
* with a completion queue event.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 addr; /* address of job's buffer */
|
||||
uint8 slot; /* slot number of the job */
|
||||
} ni_rec_job;
|
||||
|
||||
#define NI_CACHE_LEN 4
|
||||
|
||||
typedef struct {
|
||||
ni_rec_job req[NI_CACHE_LEN]; /* the 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
|
||||
* packet (minus the Ethernet frame). These structs are packed one
|
||||
* after the other following the Ethernet frame header in the job's
|
||||
* request buffer. The last entry has its "last" bit set to non-zero.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32 addr; /* Physical address of the buffer in system RAM */
|
||||
uint16 size; /* Length of the buffer */
|
||||
uint16 last; /* Is this the last entry in the list? */
|
||||
} ni_prot_info;
|
||||
|
||||
typedef struct {
|
||||
uint32 rq_taken;
|
||||
uint32 tx_fail;
|
||||
uint32 rx_dropped;
|
||||
uint32 rx_pkt;
|
||||
uint32 tx_pkt;
|
||||
uint32 rx_bytes;
|
||||
uint32 tx_bytes;
|
||||
} ni_stat_info;
|
||||
|
||||
typedef struct {
|
||||
uint8 slot;
|
||||
t_bool enabled;
|
||||
uint32 crc;
|
||||
uint32 poll_rate;
|
||||
char mac_str[MAC_SIZE_CHARS];
|
||||
uint8 mac_bytes[MAC_SIZE_BYTES];
|
||||
ni_job_cache job_cache[2];
|
||||
ni_prot_info prot;
|
||||
ni_stat_info stats;
|
||||
uint8 fcf_seq;
|
||||
ETH_DEV* eth;
|
||||
ETH_PACK rd_buf;
|
||||
ETH_PACK wr_buf;
|
||||
ETH_MAC macs[NI_FILTER_MAX]; /* List of all filter addresses */
|
||||
int filter_count; /* Number of filters available */
|
||||
ETH_PCALLBACK callback;
|
||||
} NI_STATE;
|
||||
|
||||
void ni_recv_callback(int status);
|
||||
t_stat ni_reset(DEVICE *dptr);
|
||||
t_stat ni_rcv_svc(UNIT *uptr);
|
||||
t_stat ni_sanity_svc(UNIT *uptr);
|
||||
t_stat ni_rq_svc(UNIT *uptr);
|
||||
t_stat ni_cio_svc(UNIT *uptr);
|
||||
t_stat ni_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat ni_detach(UNIT *uptr);
|
||||
t_stat ni_setmac(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat ni_showmac(FILE* st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat ni_try_job(uint8 slot);
|
||||
t_stat ni_show_stats(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat ni_set_stats(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat ni_show_poll(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat ni_show_filters(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
const char *ni_description(DEVICE *dptr);
|
||||
t_stat ni_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
|
||||
void ni_cio_reset(uint8 slot);
|
||||
void ni_process_packet();
|
||||
void ni_int_ack(uint8 slot);
|
||||
void ni_sysgen(uint8 slot);
|
||||
void ni_express(uint8 slot);
|
||||
void ni_full(uint8 slot);
|
||||
|
||||
#endif /* _3B2_NI_H_ */
|
||||
|
|
1676
3B2/3b2_ports.c
1676
3B2/3b2_ports.c
File diff suppressed because it is too large
Load diff
458
3B2/3b2_ports.h
458
3B2/3b2_ports.h
|
@ -1,229 +1,229 @@
|
|||
/* 3b2_ports.h: CM195B 4-Port Serial CIO Card
|
||||
|
||||
Copyright (c) 2018-2022, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PORTS is an intelligent feature card for the 3B2 that supports four
|
||||
* serial lines and one Centronics parallel port.
|
||||
*
|
||||
* 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
|
||||
* SCN2681A parallel I/O pins for the Centronics parallel port.
|
||||
*
|
||||
* This file implements the required logic for the PORTS CIO
|
||||
* interface. The SCN2681A functionality is implemented in the file
|
||||
* 3b2_duart.c, and is used by both this feature card and the System
|
||||
* Board console/contty functionality.
|
||||
*/
|
||||
|
||||
#ifndef _3B2_PORTS_H_
|
||||
#define _3B2_PORTS_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define PORTS_ID 0x0003
|
||||
#define PORTS_IPL 10
|
||||
#define PORTS_VERSION 1
|
||||
|
||||
#define MAX_CARDS 8 /* Up to 8 PORTS cards with 32 lines total
|
||||
supported */
|
||||
#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
|
||||
* 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_ABR 3 /* abort reception on a device */
|
||||
#define DR_ABX 4 /* abort transmission on a device */
|
||||
#define DR_BRK 5 /* transmit "break" on a device */
|
||||
#define DR_SUS 6 /* suspend xmit on a device */
|
||||
#define DR_RES 7 /* resume xmit on a device */
|
||||
#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
|
||||
* 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_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
|
||||
* mutually exclusive and may appear in combination. The prefix RC
|
||||
* 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_TMR 0x04 /* inter-character timer expired */
|
||||
#define RC_BQO 0x08 /* PPC buffer queue overflow */
|
||||
#define RC_UAO 0x10 /* uart overrun */
|
||||
#define RC_PAR 0x20 /* parity error */
|
||||
#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
|
||||
* request. These codes are NOT mutually exclusive and can be used in
|
||||
* any combination.
|
||||
*/
|
||||
|
||||
#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.
|
||||
* These are NOT mutually exclusive and may appear in combination.
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
* Sub-field values for the PPC_ASYNC completion entry; these appear
|
||||
* in app_data.bt[0] in the PPC_ASYNC application field. These are
|
||||
* mutually exclusive and cannot be combined. The prefix AC indicates
|
||||
* 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_BRK 0x03 /* asynchronous "break" */
|
||||
#define AC_FLU 0x04 /* xmit flush complete */
|
||||
|
||||
/* Line Discipline flags (input and output) */
|
||||
|
||||
#define IGNBRK 0x0001
|
||||
#define BRKINT 0x0002
|
||||
#define IGNPAR 0x0004
|
||||
#define PARMRK 0x0008
|
||||
#define INPCK 0x0010
|
||||
#define ISTRIP 0x0020
|
||||
#define INLCR 0x0040
|
||||
#define IGNCR 0x0080
|
||||
#define ICRNL 0x0100
|
||||
#define IUCLC 0x0200
|
||||
#define IXON 0x0400
|
||||
#define IXANY 0x0800
|
||||
|
||||
#define OPOST 0x0001
|
||||
#define OLCUC 0x0002
|
||||
#define ONLCR 0x0004
|
||||
#define OCRNL 0x0008
|
||||
#define ONOCR 0x0010
|
||||
#define ONLRET 0x0020
|
||||
#define OFILL 0x0040
|
||||
#define OFDEL 0x0080
|
||||
#define ONLDLY 0x0100
|
||||
#define OCRDLY 0x0600
|
||||
#define OTABDLY 0x1800
|
||||
#define OBSDLY 0x2000
|
||||
#define OVTDLY 0x4000
|
||||
#define OFFDLY 0x8000
|
||||
|
||||
/* 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_CONN 34 /* GEN, COMP queues: connect a device */
|
||||
#define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */
|
||||
#define PPC_BRK 36 /* GEN, COMP queues: ioctl break */
|
||||
#define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */
|
||||
#define PPC_CLR 41 /* EXP, ECOMP entries: board clear */
|
||||
#define PPC_RECV 50 /* RECV, COMP queues: receive request */
|
||||
#define PPC_ASYNC 60 /* Asynchronous request */
|
||||
#define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */
|
||||
#define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */
|
||||
#define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */
|
||||
#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 */
|
||||
uint32 tx_req_addr; /* Original request address */
|
||||
uint32 tx_chars; /* Number of chars left to transfer */
|
||||
uint32 tx_req_chars; /* Original number of chars */
|
||||
uint8 rlp; /* Last known load pointer */
|
||||
uint16 iflag; /* Line Discipline: Input flags */
|
||||
uint16 oflag; /* Line Discipline: Output flags */
|
||||
t_bool crlf; /* Indicates we are in a CRLF output transform */
|
||||
t_bool conn; /* TRUE if connected, FALSE otherwise */
|
||||
} PORTS_LINE_STATE;
|
||||
|
||||
typedef struct {
|
||||
uint16 line; /* line discipline */
|
||||
uint16 pad1;
|
||||
uint16 iflag; /* input options word */
|
||||
uint16 oflag; /* output options word */
|
||||
uint16 cflag; /* hardware options */
|
||||
uint16 lflag; /* line discipline options */
|
||||
uint8 cerase; /* "erase" character */
|
||||
uint8 ckill; /* "kill" character */
|
||||
uint8 cinter; /* "interrupt" character */
|
||||
uint8 cquit; /* "quit" character */
|
||||
uint8 ceof; /* "end of file" character */
|
||||
uint8 ceol; /* "end of line" character */
|
||||
uint8 itime; /* inter character timer multiplier */
|
||||
uint8 vtime; /* user-specified inter char timer */
|
||||
uint8 vcount; /* user-specified maximum buffer char count */
|
||||
uint8 pad2;
|
||||
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_rcv_svc(UNIT *uptr);
|
||||
t_stat ports_xmt_svc(UNIT *uptr);
|
||||
t_stat ports_cio_svc(UNIT *uptr);
|
||||
t_stat ports_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat ports_detach(UNIT *uptr);
|
||||
void ports_sysgen(uint8 slot);
|
||||
void ports_express(uint8 slot);
|
||||
void ports_full(uint8 slot);
|
||||
|
||||
#endif /* _3B2_PORTS_H_ */
|
||||
/* 3b2_ports.h: CM195B 4-Port Serial CIO Card
|
||||
|
||||
Copyright (c) 2018-2022, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* PORTS is an intelligent feature card for the 3B2 that supports four
|
||||
* serial lines and one Centronics parallel port.
|
||||
*
|
||||
* 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
|
||||
* SCN2681A parallel I/O pins for the Centronics parallel port.
|
||||
*
|
||||
* This file implements the required logic for the PORTS CIO
|
||||
* interface. The SCN2681A functionality is implemented in the file
|
||||
* 3b2_duart.c, and is used by both this feature card and the System
|
||||
* Board console/contty functionality.
|
||||
*/
|
||||
|
||||
#ifndef _3B2_PORTS_H_
|
||||
#define _3B2_PORTS_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define PORTS_ID 0x0003
|
||||
#define PORTS_IPL 10
|
||||
#define PORTS_VERSION 1
|
||||
|
||||
#define MAX_CARDS 8 /* Up to 8 PORTS cards with 32 lines total
|
||||
supported */
|
||||
#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
|
||||
* 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_ABR 3 /* abort reception on a device */
|
||||
#define DR_ABX 4 /* abort transmission on a device */
|
||||
#define DR_BRK 5 /* transmit "break" on a device */
|
||||
#define DR_SUS 6 /* suspend xmit on a device */
|
||||
#define DR_RES 7 /* resume xmit on a device */
|
||||
#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
|
||||
* 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_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
|
||||
* mutually exclusive and may appear in combination. The prefix RC
|
||||
* 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_TMR 0x04 /* inter-character timer expired */
|
||||
#define RC_BQO 0x08 /* PPC buffer queue overflow */
|
||||
#define RC_UAO 0x10 /* uart overrun */
|
||||
#define RC_PAR 0x20 /* parity error */
|
||||
#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
|
||||
* request. These codes are NOT mutually exclusive and can be used in
|
||||
* any combination.
|
||||
*/
|
||||
|
||||
#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.
|
||||
* These are NOT mutually exclusive and may appear in combination.
|
||||
* 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 */
|
||||
|
||||
/*
|
||||
* Sub-field values for the PPC_ASYNC completion entry; these appear
|
||||
* in app_data.bt[0] in the PPC_ASYNC application field. These are
|
||||
* mutually exclusive and cannot be combined. The prefix AC indicates
|
||||
* 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_BRK 0x03 /* asynchronous "break" */
|
||||
#define AC_FLU 0x04 /* xmit flush complete */
|
||||
|
||||
/* Line Discipline flags (input and output) */
|
||||
|
||||
#define IGNBRK 0x0001
|
||||
#define BRKINT 0x0002
|
||||
#define IGNPAR 0x0004
|
||||
#define PARMRK 0x0008
|
||||
#define INPCK 0x0010
|
||||
#define ISTRIP 0x0020
|
||||
#define INLCR 0x0040
|
||||
#define IGNCR 0x0080
|
||||
#define ICRNL 0x0100
|
||||
#define IUCLC 0x0200
|
||||
#define IXON 0x0400
|
||||
#define IXANY 0x0800
|
||||
|
||||
#define OPOST 0x0001
|
||||
#define OLCUC 0x0002
|
||||
#define ONLCR 0x0004
|
||||
#define OCRNL 0x0008
|
||||
#define ONOCR 0x0010
|
||||
#define ONLRET 0x0020
|
||||
#define OFILL 0x0040
|
||||
#define OFDEL 0x0080
|
||||
#define ONLDLY 0x0100
|
||||
#define OCRDLY 0x0600
|
||||
#define OTABDLY 0x1800
|
||||
#define OBSDLY 0x2000
|
||||
#define OVTDLY 0x4000
|
||||
#define OFFDLY 0x8000
|
||||
|
||||
/* 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_CONN 34 /* GEN, COMP queues: connect a device */
|
||||
#define PPC_DISC 35 /* GEN, COMP queues: disconnect a device */
|
||||
#define PPC_BRK 36 /* GEN, COMP queues: ioctl break */
|
||||
#define PPC_DEVICE 40 /* EXP, ECOMP entries: device control command */
|
||||
#define PPC_CLR 41 /* EXP, ECOMP entries: board clear */
|
||||
#define PPC_RECV 50 /* RECV, COMP queues: receive request */
|
||||
#define PPC_ASYNC 60 /* Asynchronous request */
|
||||
#define CFW_CONFIG 70 /* GEN, COMP queues: set PPC port 0 hardware options */
|
||||
#define CFW_IREAD 71 /* GEN, COMP queues: read immediate one to four bytes */
|
||||
#define CFW_IWRITE 72 /* GEN, COMP queues: write immediate one to four bytes */
|
||||
#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 */
|
||||
uint32 tx_req_addr; /* Original request address */
|
||||
uint32 tx_chars; /* Number of chars left to transfer */
|
||||
uint32 tx_req_chars; /* Original number of chars */
|
||||
uint8 rlp; /* Last known load pointer */
|
||||
uint16 iflag; /* Line Discipline: Input flags */
|
||||
uint16 oflag; /* Line Discipline: Output flags */
|
||||
t_bool crlf; /* Indicates we are in a CRLF output transform */
|
||||
t_bool conn; /* TRUE if connected, FALSE otherwise */
|
||||
} PORTS_LINE_STATE;
|
||||
|
||||
typedef struct {
|
||||
uint16 line; /* line discipline */
|
||||
uint16 pad1;
|
||||
uint16 iflag; /* input options word */
|
||||
uint16 oflag; /* output options word */
|
||||
uint16 cflag; /* hardware options */
|
||||
uint16 lflag; /* line discipline options */
|
||||
uint8 cerase; /* "erase" character */
|
||||
uint8 ckill; /* "kill" character */
|
||||
uint8 cinter; /* "interrupt" character */
|
||||
uint8 cquit; /* "quit" character */
|
||||
uint8 ceof; /* "end of file" character */
|
||||
uint8 ceol; /* "end of line" character */
|
||||
uint8 itime; /* inter character timer multiplier */
|
||||
uint8 vtime; /* user-specified inter char timer */
|
||||
uint8 vcount; /* user-specified maximum buffer char count */
|
||||
uint8 pad2;
|
||||
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_rcv_svc(UNIT *uptr);
|
||||
t_stat ports_xmt_svc(UNIT *uptr);
|
||||
t_stat ports_cio_svc(UNIT *uptr);
|
||||
t_stat ports_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat ports_detach(UNIT *uptr);
|
||||
void ports_sysgen(uint8 slot);
|
||||
void ports_express(uint8 slot);
|
||||
void ports_full(uint8 slot);
|
||||
|
||||
#endif /* _3B2_PORTS_H_ */
|
||||
|
|
|
@ -1,182 +1,182 @@
|
|||
/* 3b2_rev2_csr.c: ED System Board Control and Status Register
|
||||
|
||||
Copyright (c) 2017-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_rev2_csr.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_sys.h"
|
||||
#include "3b2_timer.h"
|
||||
#include "3b2_sys.h"
|
||||
|
||||
CSR_DATA csr_data;
|
||||
|
||||
BITFIELD csr_bits[] = {
|
||||
BIT(IOF),
|
||||
BIT(DMA),
|
||||
BIT(DISK),
|
||||
BIT(UART),
|
||||
BIT(PIR9),
|
||||
BIT(PIR8),
|
||||
BIT(CLK),
|
||||
BIT(IFLT),
|
||||
BIT(ITIM),
|
||||
BIT(FLOP),
|
||||
BIT(NA),
|
||||
BIT(LED),
|
||||
BIT(ALGN),
|
||||
BIT(RRST),
|
||||
BIT(PARE),
|
||||
BIT(TIMO),
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
UNIT csr_unit = {
|
||||
UDATA(NULL, UNIT_FIX, CSRSIZE)
|
||||
};
|
||||
|
||||
REG csr_reg[] = {
|
||||
{ HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE csr_dev = {
|
||||
"CSR", &csr_unit, csr_reg, NULL,
|
||||
1, 16, 8, 4, 16, 32,
|
||||
&csr_ex, &csr_dep, &csr_reset,
|
||||
NULL, NULL, NULL, NULL,
|
||||
DEV_DEBUG, 0, sys_deb_tab
|
||||
};
|
||||
|
||||
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_reset(DEVICE *dptr)
|
||||
{
|
||||
csr_data = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 csr_read(uint32 pa, size_t size)
|
||||
{
|
||||
uint32 reg = pa - CSRBASE;
|
||||
|
||||
sim_debug(READ_MSG, &csr_dev,
|
||||
"CSR=%04x\n",
|
||||
csr_data);
|
||||
|
||||
switch (reg) {
|
||||
case 0x2:
|
||||
if (size == 8) {
|
||||
return (csr_data >> 8) & 0xff;
|
||||
} else {
|
||||
return csr_data;
|
||||
}
|
||||
case 0x3:
|
||||
return csr_data & 0xff;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void csr_write(uint32 pa, uint32 val, size_t size)
|
||||
{
|
||||
uint32 reg = pa - CSRBASE;
|
||||
|
||||
switch (reg) {
|
||||
case 0x03: /* Clear Bus Timeout Error */
|
||||
csr_data &= ~CSRTIMO;
|
||||
break;
|
||||
case 0x07: /* Clear Memory Parity Error */
|
||||
csr_data &= ~CSRPARE;
|
||||
break;
|
||||
case 0x0b: /* Set System Reset Request */
|
||||
full_reset();
|
||||
cpu_boot(0, &cpu_dev);
|
||||
break;
|
||||
case 0x0f: /* Clear Memory Alignment Fault */
|
||||
csr_data &= ~CSRALGN;
|
||||
break;
|
||||
case 0x13: /* Set Failure LED */
|
||||
csr_data |= CSRLED;
|
||||
break;
|
||||
case 0x17: /* Clear Failure LED */
|
||||
csr_data &= ~CSRLED;
|
||||
break;
|
||||
case 0x1b: /* Set Floppy Motor On */
|
||||
csr_data |= CSRFLOP;
|
||||
break;
|
||||
case 0x1f: /* Clear Floppy Motor On */
|
||||
csr_data &= ~CSRFLOP;
|
||||
break;
|
||||
case 0x23: /* Set Inhibit Timers */
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"SET INHIBIT TIMERS\n");
|
||||
csr_data |= CSRITIM;
|
||||
timer_gate(TIMER_INTERVAL, TRUE);
|
||||
break;
|
||||
case 0x27: /* Clear Inhibit Timers */
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"CLEAR INHIBIT TIMERS\n");
|
||||
csr_data &= ~CSRITIM;
|
||||
timer_gate(TIMER_INTERVAL, FALSE);
|
||||
break;
|
||||
case 0x2b: /* Set Inhibit Faults */
|
||||
csr_data |= CSRIFLT;
|
||||
break;
|
||||
case 0x2f: /* Clear Inhibit Faults */
|
||||
csr_data &= ~CSRIFLT;
|
||||
break;
|
||||
case 0x33: /* Set PIR9 */
|
||||
csr_data |= CSRPIR9;
|
||||
CPU_SET_INT(INT_PIR9);
|
||||
break;
|
||||
case 0x37: /* Clear PIR9 */
|
||||
csr_data &= ~CSRPIR9;
|
||||
CPU_CLR_INT(INT_PIR9);
|
||||
break;
|
||||
case 0x3b: /* Set PIR8 */
|
||||
csr_data |= CSRPIR8;
|
||||
CPU_SET_INT(INT_PIR8);
|
||||
break;
|
||||
case 0x3f: /* Clear PIR8 */
|
||||
csr_data &= ~CSRPIR8;
|
||||
CPU_CLR_INT(INT_PIR8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* 3b2_rev2_csr.c: ED System Board Control and Status Register
|
||||
|
||||
Copyright (c) 2017-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_rev2_csr.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_sys.h"
|
||||
#include "3b2_timer.h"
|
||||
#include "3b2_sys.h"
|
||||
|
||||
CSR_DATA csr_data;
|
||||
|
||||
BITFIELD csr_bits[] = {
|
||||
BIT(IOF),
|
||||
BIT(DMA),
|
||||
BIT(DISK),
|
||||
BIT(UART),
|
||||
BIT(PIR9),
|
||||
BIT(PIR8),
|
||||
BIT(CLK),
|
||||
BIT(IFLT),
|
||||
BIT(ITIM),
|
||||
BIT(FLOP),
|
||||
BIT(NA),
|
||||
BIT(LED),
|
||||
BIT(ALGN),
|
||||
BIT(RRST),
|
||||
BIT(PARE),
|
||||
BIT(TIMO),
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
UNIT csr_unit = {
|
||||
UDATA(NULL, UNIT_FIX, CSRSIZE)
|
||||
};
|
||||
|
||||
REG csr_reg[] = {
|
||||
{ HRDATADF(DATA, csr_data, 16, "CSR Data", csr_bits) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE csr_dev = {
|
||||
"CSR", &csr_unit, csr_reg, NULL,
|
||||
1, 16, 8, 4, 16, 32,
|
||||
&csr_ex, &csr_dep, &csr_reset,
|
||||
NULL, NULL, NULL, NULL,
|
||||
DEV_DEBUG, 0, sys_deb_tab
|
||||
};
|
||||
|
||||
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_reset(DEVICE *dptr)
|
||||
{
|
||||
csr_data = 0;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 csr_read(uint32 pa, size_t size)
|
||||
{
|
||||
uint32 reg = pa - CSRBASE;
|
||||
|
||||
sim_debug(READ_MSG, &csr_dev,
|
||||
"CSR=%04x\n",
|
||||
csr_data);
|
||||
|
||||
switch (reg) {
|
||||
case 0x2:
|
||||
if (size == 8) {
|
||||
return (csr_data >> 8) & 0xff;
|
||||
} else {
|
||||
return csr_data;
|
||||
}
|
||||
case 0x3:
|
||||
return csr_data & 0xff;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void csr_write(uint32 pa, uint32 val, size_t size)
|
||||
{
|
||||
uint32 reg = pa - CSRBASE;
|
||||
|
||||
switch (reg) {
|
||||
case 0x03: /* Clear Bus Timeout Error */
|
||||
csr_data &= ~CSRTIMO;
|
||||
break;
|
||||
case 0x07: /* Clear Memory Parity Error */
|
||||
csr_data &= ~CSRPARE;
|
||||
break;
|
||||
case 0x0b: /* Set System Reset Request */
|
||||
full_reset();
|
||||
cpu_boot(0, &cpu_dev);
|
||||
break;
|
||||
case 0x0f: /* Clear Memory Alignment Fault */
|
||||
csr_data &= ~CSRALGN;
|
||||
break;
|
||||
case 0x13: /* Set Failure LED */
|
||||
csr_data |= CSRLED;
|
||||
break;
|
||||
case 0x17: /* Clear Failure LED */
|
||||
csr_data &= ~CSRLED;
|
||||
break;
|
||||
case 0x1b: /* Set Floppy Motor On */
|
||||
csr_data |= CSRFLOP;
|
||||
break;
|
||||
case 0x1f: /* Clear Floppy Motor On */
|
||||
csr_data &= ~CSRFLOP;
|
||||
break;
|
||||
case 0x23: /* Set Inhibit Timers */
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"SET INHIBIT TIMERS\n");
|
||||
csr_data |= CSRITIM;
|
||||
timer_gate(TIMER_INTERVAL, TRUE);
|
||||
break;
|
||||
case 0x27: /* Clear Inhibit Timers */
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"CLEAR INHIBIT TIMERS\n");
|
||||
csr_data &= ~CSRITIM;
|
||||
timer_gate(TIMER_INTERVAL, FALSE);
|
||||
break;
|
||||
case 0x2b: /* Set Inhibit Faults */
|
||||
csr_data |= CSRIFLT;
|
||||
break;
|
||||
case 0x2f: /* Clear Inhibit Faults */
|
||||
csr_data &= ~CSRIFLT;
|
||||
break;
|
||||
case 0x33: /* Set PIR9 */
|
||||
csr_data |= CSRPIR9;
|
||||
CPU_SET_INT(INT_PIR9);
|
||||
break;
|
||||
case 0x37: /* Clear PIR9 */
|
||||
csr_data &= ~CSRPIR9;
|
||||
CPU_CLR_INT(INT_PIR9);
|
||||
break;
|
||||
case 0x3b: /* Set PIR8 */
|
||||
csr_data |= CSRPIR8;
|
||||
CPU_SET_INT(INT_PIR8);
|
||||
break;
|
||||
case 0x3f: /* Clear PIR8 */
|
||||
csr_data &= ~CSRPIR8;
|
||||
CPU_CLR_INT(INT_PIR8);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
/* 3b2_rev2_csr.h: ED System Board Control and Status Register
|
||||
|
||||
Copyright (c) 2021-2022, 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_CSR_H_
|
||||
#define _3B2_REV2_CSR_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
typedef uint16 CSR_DATA;
|
||||
|
||||
/* CSR */
|
||||
t_stat csr_svc(UNIT *uptr);
|
||||
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_reset(DEVICE *dptr);
|
||||
uint32 csr_read(uint32 pa, size_t size);
|
||||
void csr_write(uint32 pa, uint32 val, size_t size);
|
||||
|
||||
#endif /* 3B2_REV2_CSR_H_ */
|
||||
/* 3b2_rev2_csr.h: ED System Board Control and Status Register
|
||||
|
||||
Copyright (c) 2021-2022, 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_CSR_H_
|
||||
#define _3B2_REV2_CSR_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
typedef uint16 CSR_DATA;
|
||||
|
||||
/* CSR */
|
||||
t_stat csr_svc(UNIT *uptr);
|
||||
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_reset(DEVICE *dptr);
|
||||
uint32 csr_read(uint32 pa, size_t size);
|
||||
void csr_write(uint32 pa, uint32 val, size_t size);
|
||||
|
||||
#endif /* 3B2_REV2_CSR_H_ */
|
||||
|
|
|
@ -1,132 +1,132 @@
|
|||
/* 3b2_rev2_defs.h: Version 2 (3B2/400) Common Definitions
|
||||
|
||||
Copyright (c) 2017-2022, 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_DEFS_H_
|
||||
#define _3B2_REV2_DEFS_H_
|
||||
|
||||
#define NUM_REGISTERS 16
|
||||
|
||||
#define DEFMEMSIZE MSIZ_4M
|
||||
#define MAXMEMSIZE MSIZ_4M
|
||||
|
||||
#define HWORD_OP_COUNT 11
|
||||
#define CPU_VERSION 0x1A /* Version encoded in WE32100 */
|
||||
|
||||
#define TODBASE 0x41000
|
||||
#define TODSIZE 0x40
|
||||
#define TIMERBASE 0x42000
|
||||
#define TIMERSIZE 0x20
|
||||
#define NVRBASE 0x43000
|
||||
#define NVRSIZE 0x1000
|
||||
#define CSRBASE 0x44000
|
||||
#define CSRSIZE 0x100
|
||||
#define IFBASE 0x4d000
|
||||
#define IFSIZE 0x10
|
||||
#define IDBASE 0x4a000
|
||||
#define IDSIZE 0x2
|
||||
|
||||
#define IF_STATUS_REG 0
|
||||
#define IF_CMD_REG 0
|
||||
#define IF_TRACK_REG 1
|
||||
#define IF_SECTOR_REG 2
|
||||
#define IF_DATA_REG 3
|
||||
|
||||
#define ID_DATA_REG 0
|
||||
#define ID_CMD_STAT_REG 1
|
||||
|
||||
/* CSR Flags */
|
||||
#define CSRTIMO 0x8000 /* Bus Timeout Error */
|
||||
#define CSRPARE 0x4000 /* Memory Parity Error */
|
||||
#define CSRRRST 0x2000 /* System Reset Request */
|
||||
#define CSRALGN 0x1000 /* Memory Alignment Fault */
|
||||
#define CSRLED 0x0800 /* Failure LED */
|
||||
#define CSRFLOP 0x0400 /* Floppy Motor On */
|
||||
#define CSRRES 0x0200 /* Reserved */
|
||||
#define CSRITIM 0x0100 /* Inhibit Timers */
|
||||
#define CSRIFLT 0x0080 /* Inhibit Faults */
|
||||
#define CSRCLK 0x0040 /* Clock Interrupt */
|
||||
#define CSRPIR8 0x0020 /* Programmed Interrupt 8 */
|
||||
#define CSRPIR9 0x0010 /* Programmed Interrupt 9 */
|
||||
#define CSRUART 0x0008 /* UART Interrupt */
|
||||
#define CSRDISK 0x0004 /* Floppy Interrupt */
|
||||
#define CSRDMA 0x0002 /* DMA Interrupt */
|
||||
#define CSRIOF 0x0001 /* I/O Board Fail */
|
||||
|
||||
/* Interrupt Sources */
|
||||
#define INT_SERR 0x01 /* IPL 15 */
|
||||
#define INT_CLOCK 0x02 /* IPL 15 */
|
||||
#define INT_DMA 0x04 /* IPL 13 */
|
||||
#define INT_UART 0x08 /* IPL 13 */
|
||||
#define INT_DISK 0x10 /* IPL 11 */
|
||||
#define INT_FLOPPY 0x20 /* IPL 11 */
|
||||
#define INT_PIR9 0x40 /* IPL 9 */
|
||||
#define INT_PIR8 0x80 /* IPL 8 */
|
||||
|
||||
#define INT_MAP_LEN 0x100
|
||||
|
||||
/* Memory */
|
||||
#define MEMSIZE_REG 0x4C003
|
||||
#define MEMID_512K 0
|
||||
#define MEMID_1M 2
|
||||
#define MEMID_2M 1
|
||||
#define MEMID_4M 3
|
||||
|
||||
/* DMA Controller */
|
||||
#define DMACBASE 0x48000
|
||||
#define DMACSIZE 0x11
|
||||
|
||||
/* DMA integrated disk page buffer */
|
||||
#define DMAIDBASE 0x45000
|
||||
#define DMAIDSIZE 0x5
|
||||
|
||||
/* DMA integrated uart A page buffer */
|
||||
#define DMAIUABASE 0x46000
|
||||
#define DMAIUASIZE 0x5
|
||||
|
||||
/* DMA integrated uart B page buffer */
|
||||
#define DMAIUBBASE 0x47000
|
||||
#define DMAIUBSIZE 0x5
|
||||
|
||||
/* DMA integrated floppy page buffer */
|
||||
#define DMAIFBASE 0x4E000
|
||||
#define DMAIFSIZE 0x5
|
||||
|
||||
#define DMA_ID_CHAN 0
|
||||
#define DMA_IF_CHAN 1
|
||||
#define DMA_IUA_CHAN 2
|
||||
#define DMA_IUB_CHAN 3
|
||||
|
||||
#define DMA_ID 0x45
|
||||
#define DMA_IUA 0x46
|
||||
#define DMA_IUB 0x47
|
||||
#define DMA_C 0x48
|
||||
#define DMA_IF 0x4E
|
||||
|
||||
#endif /* _3B2_REV2_DEFS_H_ */
|
||||
/* 3b2_rev2_defs.h: Version 2 (3B2/400) Common Definitions
|
||||
|
||||
Copyright (c) 2017-2022, 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_DEFS_H_
|
||||
#define _3B2_REV2_DEFS_H_
|
||||
|
||||
#define NUM_REGISTERS 16
|
||||
|
||||
#define DEFMEMSIZE MSIZ_4M
|
||||
#define MAXMEMSIZE MSIZ_4M
|
||||
|
||||
#define HWORD_OP_COUNT 11
|
||||
#define CPU_VERSION 0x1A /* Version encoded in WE32100 */
|
||||
|
||||
#define TODBASE 0x41000
|
||||
#define TODSIZE 0x40
|
||||
#define TIMERBASE 0x42000
|
||||
#define TIMERSIZE 0x20
|
||||
#define NVRBASE 0x43000
|
||||
#define NVRSIZE 0x1000
|
||||
#define CSRBASE 0x44000
|
||||
#define CSRSIZE 0x100
|
||||
#define IFBASE 0x4d000
|
||||
#define IFSIZE 0x10
|
||||
#define IDBASE 0x4a000
|
||||
#define IDSIZE 0x2
|
||||
|
||||
#define IF_STATUS_REG 0
|
||||
#define IF_CMD_REG 0
|
||||
#define IF_TRACK_REG 1
|
||||
#define IF_SECTOR_REG 2
|
||||
#define IF_DATA_REG 3
|
||||
|
||||
#define ID_DATA_REG 0
|
||||
#define ID_CMD_STAT_REG 1
|
||||
|
||||
/* CSR Flags */
|
||||
#define CSRTIMO 0x8000 /* Bus Timeout Error */
|
||||
#define CSRPARE 0x4000 /* Memory Parity Error */
|
||||
#define CSRRRST 0x2000 /* System Reset Request */
|
||||
#define CSRALGN 0x1000 /* Memory Alignment Fault */
|
||||
#define CSRLED 0x0800 /* Failure LED */
|
||||
#define CSRFLOP 0x0400 /* Floppy Motor On */
|
||||
#define CSRRES 0x0200 /* Reserved */
|
||||
#define CSRITIM 0x0100 /* Inhibit Timers */
|
||||
#define CSRIFLT 0x0080 /* Inhibit Faults */
|
||||
#define CSRCLK 0x0040 /* Clock Interrupt */
|
||||
#define CSRPIR8 0x0020 /* Programmed Interrupt 8 */
|
||||
#define CSRPIR9 0x0010 /* Programmed Interrupt 9 */
|
||||
#define CSRUART 0x0008 /* UART Interrupt */
|
||||
#define CSRDISK 0x0004 /* Floppy Interrupt */
|
||||
#define CSRDMA 0x0002 /* DMA Interrupt */
|
||||
#define CSRIOF 0x0001 /* I/O Board Fail */
|
||||
|
||||
/* Interrupt Sources */
|
||||
#define INT_SERR 0x01 /* IPL 15 */
|
||||
#define INT_CLOCK 0x02 /* IPL 15 */
|
||||
#define INT_DMA 0x04 /* IPL 13 */
|
||||
#define INT_UART 0x08 /* IPL 13 */
|
||||
#define INT_DISK 0x10 /* IPL 11 */
|
||||
#define INT_FLOPPY 0x20 /* IPL 11 */
|
||||
#define INT_PIR9 0x40 /* IPL 9 */
|
||||
#define INT_PIR8 0x80 /* IPL 8 */
|
||||
|
||||
#define INT_MAP_LEN 0x100
|
||||
|
||||
/* Memory */
|
||||
#define MEMSIZE_REG 0x4C003
|
||||
#define MEMID_512K 0
|
||||
#define MEMID_1M 2
|
||||
#define MEMID_2M 1
|
||||
#define MEMID_4M 3
|
||||
|
||||
/* DMA Controller */
|
||||
#define DMACBASE 0x48000
|
||||
#define DMACSIZE 0x11
|
||||
|
||||
/* DMA integrated disk page buffer */
|
||||
#define DMAIDBASE 0x45000
|
||||
#define DMAIDSIZE 0x5
|
||||
|
||||
/* DMA integrated uart A page buffer */
|
||||
#define DMAIUABASE 0x46000
|
||||
#define DMAIUASIZE 0x5
|
||||
|
||||
/* DMA integrated uart B page buffer */
|
||||
#define DMAIUBBASE 0x47000
|
||||
#define DMAIUBSIZE 0x5
|
||||
|
||||
/* DMA integrated floppy page buffer */
|
||||
#define DMAIFBASE 0x4E000
|
||||
#define DMAIFSIZE 0x5
|
||||
|
||||
#define DMA_ID_CHAN 0
|
||||
#define DMA_IF_CHAN 1
|
||||
#define DMA_IUA_CHAN 2
|
||||
#define DMA_IUB_CHAN 3
|
||||
|
||||
#define DMA_ID 0x45
|
||||
#define DMA_IUA 0x46
|
||||
#define DMA_IUB 0x47
|
||||
#define DMA_C 0x48
|
||||
#define DMA_IF 0x4E
|
||||
|
||||
#endif /* _3B2_REV2_DEFS_H_ */
|
||||
|
|
1644
3B2/3b2_rev2_mmu.c
1644
3B2/3b2_rev2_mmu.c
File diff suppressed because it is too large
Load diff
|
@ -1,358 +1,358 @@
|
|||
/* 3b2_rev2_mmu.c: WE32101 MMU
|
||||
|
||||
Copyright (c) 2017-2022, 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_MMU_H_
|
||||
#define _3B2_REV2_MMU_H_
|
||||
|
||||
#include "sim_defs.h"
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* Vocabulary
|
||||
* ----------
|
||||
*
|
||||
* PD: Page Descriptor (in main memory)
|
||||
* PDT: Page Descriptor Table (in main memory)
|
||||
* POT: Page Offset. Bits 0-10 of a Paged virtual address.
|
||||
* PSL: Page Select. Bits 11-16 of a Paged virtual address.
|
||||
* SD: Segment Descriptor (in main memory)
|
||||
* SDT: Segment Descriptor Table (in main memory)
|
||||
* SID: Section ID. Bits 30-31 of all virtual addresses
|
||||
* SOT: Segment Offset. Bits 0-16 of a Contiguous virtual address.
|
||||
* SSL: Segment Select. Bits 17-29 of all virtual addresses.
|
||||
*
|
||||
*
|
||||
* The WE32101 MMU divides the virtual address space into four
|
||||
* Sections with 8K Segments per section. Virtual address bits 30 and
|
||||
* 31 determine the section, bits 17-29 determine the Segment within
|
||||
* the section.
|
||||
*
|
||||
* There are two kinds of address translation: Contiguous Translation
|
||||
* and Paged Translation. Contiguous Translation just uses an offset
|
||||
* (bits 0-16 of the virtual address) into each Segment to find an
|
||||
* address, allowing for 128K bytes per Segment. Paged translation
|
||||
* further break Segments down into 64 Pages of 2K each.
|
||||
*
|
||||
* Details about how to do translation are held in main memory in
|
||||
* Segment Descriptors and Page Descriptors. These are located in
|
||||
* Segment Descriptor Tables and Page Descriptor Tables set up by the
|
||||
* computer before enabling the MMU.
|
||||
*
|
||||
* In addition to details in main memory, the MMU has a small cache
|
||||
* of both Segment Descriptors and Page Descriptors. This is NOT just
|
||||
* used for performance reasons! Various features of the cache,
|
||||
* such as updating R and M bits in Segment and Page Descriptors,
|
||||
* are used by various operating system features.
|
||||
*
|
||||
*
|
||||
* Virtual Address Fields
|
||||
* ----------------------
|
||||
*
|
||||
* 31 30 29 17 16 0
|
||||
* +-----+-------------------+-----------------------------+
|
||||
* Contig: | SID | SSL | SOT |
|
||||
* +-----+-------------------+-----------------------------+
|
||||
*
|
||||
* 31 30 29 17 16 11 10 0
|
||||
* +-----+-------------------+---------+-------------------+
|
||||
* Paged: | SID | SSL | PSL | POT |
|
||||
* +-----+-------------------+---------+-------------------+
|
||||
*
|
||||
*
|
||||
* Segment Descriptor Fields
|
||||
* -------------------------
|
||||
*
|
||||
* 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 |
|
||||
* +-------+---------+-----+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* +-----------------------------------------------+-------+
|
||||
* sd1: | Address (high-order 27 or 29 bits) | Soft |
|
||||
* +-----------------------------------------------+-------+
|
||||
*
|
||||
*
|
||||
* Segment Descriptor Cache Entry
|
||||
* ------------------------------
|
||||
*
|
||||
* 31 24 23 10 9 0
|
||||
* +-------+-------------------------+---------------------+
|
||||
* Low: | Acc | Max Off | Tag |
|
||||
* +-------+-------------------------+---------------------+
|
||||
*
|
||||
* 31 5 4 3 2 1 0
|
||||
* +-----------------------------------+---+---+---+---+---+
|
||||
* High: | Address | T | $ | C | M | G |
|
||||
* +-----------------------------------+---+---+---+---+---+
|
||||
*
|
||||
*
|
||||
* Page Descriptor Fields
|
||||
* ----------------------
|
||||
*
|
||||
* 31 11 10 8 7 6 5 4 3 2 1 0
|
||||
* +----------------+------+-----+---+---+-----+---+---+---+
|
||||
* | Page Address | Soft | Res | R | W | Res | L | M | P |
|
||||
* +----------------+------+-----+---+---+-----+---+---+---+
|
||||
*
|
||||
*
|
||||
* Page Descriptor Cache Entry
|
||||
* ---------------------------
|
||||
*
|
||||
* 31 24 23 16 15 0
|
||||
* +-----+------------------+------------------------------+
|
||||
* Low: | Acc | Res | Tag |
|
||||
* +-----+------------------+------------------------------+
|
||||
*
|
||||
* 31 11 10 7 6 5 4 3 2 1 0
|
||||
* +---------------------+-----+---+---+---+---+---+---+---+
|
||||
* High: | Address | Res | U | R | W | $ | L | M | G |
|
||||
* +---------------------+-----+---+---+---+---+---+---+---+
|
||||
*
|
||||
* "U" is only set in the left cache entry, and indicates
|
||||
* which slot (left or right) was most recently updated.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#define MMUBASE 0x40000
|
||||
#define MMUSIZE 0x1000
|
||||
|
||||
#define MMU_SRS 0x04 /* Section RAM array size (words) */
|
||||
#define MMU_SDCS 0x20 /* Segment Descriptor Cache H/L array size
|
||||
(words) */
|
||||
#define MMU_PDCS 0x20 /* Page Descriptor Cache H/L array size
|
||||
(words) */
|
||||
|
||||
/* Register address offsets */
|
||||
#define MMU_SDCL 0
|
||||
#define MMU_SDCH 1
|
||||
#define MMU_PDCRL 2
|
||||
#define MMU_PDCRH 3
|
||||
#define MMU_PDCLL 4
|
||||
#define MMU_PDCLH 5
|
||||
#define MMU_SRAMA 6
|
||||
#define MMU_SRAMB 7
|
||||
#define MMU_FC 8
|
||||
#define MMU_FA 9
|
||||
#define MMU_CONF 10
|
||||
#define MMU_VAR 11
|
||||
|
||||
#define MMU_CONF_M (mmu_state.conf & 0x1)
|
||||
#define MMU_CONF_R (mmu_state.conf & 0x2)
|
||||
|
||||
/* Caching */
|
||||
#define NUM_SEC 4u /* Number of memory sections */
|
||||
#define NUM_SDCE 8 /* SD cache entries per section */
|
||||
#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 */
|
||||
|
||||
/* Cache Tag for SDs */
|
||||
#define SD_TAG(vaddr) ((vaddr >> 20) & 0x3ff)
|
||||
|
||||
/* Cache Tag for PDs */
|
||||
#define PD_TAG(vaddr) (((vaddr >> 13) & 0xf) | ((vaddr >> 14) & 0xfff0))
|
||||
|
||||
/* Index of entry in the SD cache */
|
||||
#define SD_IDX(vaddr) ((vaddr >> 17) & 7)
|
||||
|
||||
/* Index of entry in the PD cache */
|
||||
#define PD_IDX(vaddr) (((vaddr >> 11) & 3) | ((vaddr >> 15) & 4))
|
||||
|
||||
/* Shift and mask the flag bits for the current CPU mode */
|
||||
#define MMU_PERM(f) ((f >> ((3 - CPU_CM) * 2)) & 3)
|
||||
|
||||
/* Codes set in the MMU Fault register */
|
||||
#define MMU_F_SDTLEN 0x03
|
||||
#define MMU_F_PW 0x04
|
||||
#define MMU_F_PDTLEN 0x05
|
||||
#define MMU_F_INV_SD 0x06
|
||||
#define MMU_F_SEG_NOT_PRES 0x07
|
||||
#define MMU_F_OTRAP 0x08
|
||||
#define MMU_F_PDT_NOT_PRES 0x09
|
||||
#define MMU_F_PAGE_NOT_PRES 0x0a
|
||||
#define MMU_F_ACC 0x0d
|
||||
#define MMU_F_SEG_OFFSET 0x0e
|
||||
|
||||
/* Access Request types */
|
||||
#define ACC_MT 0 /* Move Translated */
|
||||
#define ACC_SPW 1 /* Support processor write */
|
||||
#define ACC_SPF 3 /* Support processor fetch */
|
||||
#define ACC_IR 7 /* Interlocked read */
|
||||
#define ACC_AF 8 /* Address fetch */
|
||||
#define ACC_OF 9 /* Operand fetch */
|
||||
#define ACC_W 10 /* Write */
|
||||
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */
|
||||
#define ACC_IF 13 /* Instruction fetch */
|
||||
|
||||
/* Pluck out Virtual Address fields */
|
||||
#define SID(va) (((va) >> 30) & 3)
|
||||
#define SSL(va) (((va) >> 17) & 0x1fff)
|
||||
#define SOT(va) (va & 0x1ffff)
|
||||
#define PSL(va) (((va) >> 11) & 0x3f)
|
||||
#define PSL_C(va) ((va) & 0x1f800)
|
||||
#define POT(va) (va & 0x7ff)
|
||||
|
||||
/* Get the maximum length of an SSL from SRAMB */
|
||||
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len + 1)
|
||||
|
||||
/* Pluck out Segment Descriptor fields */
|
||||
#define SD_PRESENT(sd0) ((sd0) & 1)
|
||||
#define SD_MODIFIED(sd0) (((sd0) >> 1) & 1)
|
||||
#define SD_CONTIG(sd0) (((sd0) >> 2) & 1)
|
||||
#define SD_PAGED(sd0) ((((sd0) >> 2) & 1) == 0)
|
||||
#define SD_CACHE(sd0) (((sd0) >> 3) & 1)
|
||||
#define SD_TRAP(sd0) (((sd0) >> 4) & 1)
|
||||
#define SD_REF(sd0) (((sd0) >> 5) & 1)
|
||||
#define SD_VALID(sd0) (((sd0) >> 6) & 1)
|
||||
#define SD_INDIRECT(sd0) (((sd0) >> 7) & 1)
|
||||
#define SD_SEG_ADDR(sd1) ((sd1) & 0xffffffe0)
|
||||
#define SD_MAX_OFF(sd0) (((sd0) >> 10) & 0x3fff)
|
||||
#define SD_ACC(sd0) (((sd0) >> 24) & 0xff)
|
||||
#define SD_R_MASK 0x20
|
||||
#define SD_M_MASK 0x2
|
||||
#define SD_GOOD_MASK 0x1u
|
||||
#define SDCE_TAG(sdcl) ((sdcl) & 0x3ff)
|
||||
|
||||
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
|
||||
|
||||
|
||||
/* Convert from sd to sd cache entry */
|
||||
#define SD_TO_SDCL(va,sd0) ((sd0 & 0xfffffc00)|SD_TAG(va))
|
||||
#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
|
||||
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. */
|
||||
|
||||
#define SDCE_TO_SD0(sdch,sdcl) ((sdcl & 0xfffffc00)|0x40|(sdch & 0x1e)|1)
|
||||
#define SDCE_TO_SD1(sdch) (sdch & 0xffffffe0)
|
||||
|
||||
/* Maximum size (in bytes) of a segment */
|
||||
#define MAX_OFFSET(sd0) ((SD_MAX_OFF(sd0) + 1) * 8)
|
||||
|
||||
#define PD_PRESENT(pd) (pd & 1)
|
||||
#define PD_MODIFIED(pd) ((pd >> 1) & 1)
|
||||
#define PD_LAST(pd) ((pd >> 2) & 1)
|
||||
#define PD_WFAULT(pd) ((pd >> 4) & 1)
|
||||
#define PD_REF(pd) ((pd >> 5) & 1)
|
||||
#define PD_ADDR(pd) (pd & 0xfffff800) /* Address portion of PD */
|
||||
#define PD_R_MASK 0x20
|
||||
#define PD_M_MASK 0x2
|
||||
#define PD_GOOD_MASK 0x1u
|
||||
#define PDCLH_USED_MASK 0x40u
|
||||
#define PDCXL_TAG(pdcxl) (pdcxl & 0xffff)
|
||||
|
||||
#define PD_LOC(sd1,va) SD_SEG_ADDR(sd1) + (PSL(va) * 4)
|
||||
|
||||
/* Page Descriptor Cache Entry
|
||||
*
|
||||
*/
|
||||
|
||||
/* Convert from pd to pd cache entry. Alwasy sets "Good" bit. */
|
||||
#define SD_TO_PDCXL(va,sd0) ((sd0 & 0xff000000)|PD_TAG(va))
|
||||
#define PD_TO_PDCXH(pd,sd0) ((pd & 0xfffff836)|(sd0 & 0x8)|1)
|
||||
|
||||
/* Always set 'present' to true on conversion */
|
||||
#define PDCXH_TO_PD(pdch) ((pdch & 0xfffff836)|1)
|
||||
#define PDCXL_TO_ACC(pdcl) (((pdcl & 0xff000000) >> 24) & 0xff)
|
||||
|
||||
/* Fault codes */
|
||||
#define MMU_FAULT(f) { \
|
||||
if (fc) { \
|
||||
mmu_state.fcode = ((((uint32)r_acc)<<7)| \
|
||||
(((uint32)(CPU_CM))<<5)|f); \
|
||||
mmu_state.faddr = va; \
|
||||
} \
|
||||
}
|
||||
|
||||
typedef struct _mmu_sec {
|
||||
uint32 addr;
|
||||
uint32 len;
|
||||
} mmu_sec;
|
||||
|
||||
typedef struct _mmu_state {
|
||||
t_bool enabled; /* Global enabled/disabled flag */
|
||||
|
||||
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
|
||||
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
|
||||
|
||||
uint32 pdcll[MMU_PDCS]; /* PDC low bits (left) (0-31) */
|
||||
uint32 pdclh[MMU_PDCS]; /* PDC high bits (left) (32-63) */
|
||||
|
||||
uint32 pdcrl[MMU_PDCS]; /* PDC low bits (right) (0-31) */
|
||||
uint32 pdcrh[MMU_PDCS]; /* PDC high bits (right) (32-63) */
|
||||
|
||||
uint32 sra[MMU_SRS]; /* Section RAM A */
|
||||
uint32 srb[MMU_SRS]; /* Section RAM B */
|
||||
|
||||
mmu_sec sec[MMU_SRS]; /* Section descriptors decoded from
|
||||
Section RAM A and B */
|
||||
|
||||
uint32 fcode; /* Fault Code Register */
|
||||
uint32 faddr; /* Fault Address Register */
|
||||
uint32 conf; /* Configuration Register */
|
||||
uint32 var; /* Virtual Address Register */
|
||||
|
||||
} MMU_STATE;
|
||||
|
||||
t_stat mmu_init(DEVICE *dptr);
|
||||
uint32 mmu_read(uint32 pa, size_t size);
|
||||
void mmu_write(uint32 pa, uint32 val, size_t size);
|
||||
CONST char *mmu_description(DEVICE *dptr);
|
||||
|
||||
/* Virtual memory translation */
|
||||
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
|
||||
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
|
||||
t_bool fc, uint32 *pa);
|
||||
|
||||
#define SHOULD_CACHE_PD(pd) \
|
||||
(fc && PD_PRESENT(pd))
|
||||
|
||||
#define SHOULD_CACHE_SD(sd) \
|
||||
(fc && SD_VALID(sd) && SD_PRESENT(sd))
|
||||
|
||||
#define SHOULD_UPDATE_SD_R_BIT(sd) \
|
||||
(MMU_CONF_R && !((sd) & SD_R_MASK))
|
||||
|
||||
#define SHOULD_UPDATE_SD_M_BIT(sd) \
|
||||
(MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK))
|
||||
|
||||
#define SHOULD_UPDATE_PD_R_BIT(pd) \
|
||||
(!((pd) & PD_R_MASK))
|
||||
|
||||
#define SHOULD_UPDATE_PD_M_BIT(pd) \
|
||||
(r_acc == ACC_W && !((pd) & PD_M_MASK))
|
||||
|
||||
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_ */
|
||||
/* 3b2_rev2_mmu.c: WE32101 MMU
|
||||
|
||||
Copyright (c) 2017-2022, 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_MMU_H_
|
||||
#define _3B2_REV2_MMU_H_
|
||||
|
||||
#include "sim_defs.h"
|
||||
|
||||
/************************************************************************
|
||||
*
|
||||
* Vocabulary
|
||||
* ----------
|
||||
*
|
||||
* PD: Page Descriptor (in main memory)
|
||||
* PDT: Page Descriptor Table (in main memory)
|
||||
* POT: Page Offset. Bits 0-10 of a Paged virtual address.
|
||||
* PSL: Page Select. Bits 11-16 of a Paged virtual address.
|
||||
* SD: Segment Descriptor (in main memory)
|
||||
* SDT: Segment Descriptor Table (in main memory)
|
||||
* SID: Section ID. Bits 30-31 of all virtual addresses
|
||||
* SOT: Segment Offset. Bits 0-16 of a Contiguous virtual address.
|
||||
* SSL: Segment Select. Bits 17-29 of all virtual addresses.
|
||||
*
|
||||
*
|
||||
* The WE32101 MMU divides the virtual address space into four
|
||||
* Sections with 8K Segments per section. Virtual address bits 30 and
|
||||
* 31 determine the section, bits 17-29 determine the Segment within
|
||||
* the section.
|
||||
*
|
||||
* There are two kinds of address translation: Contiguous Translation
|
||||
* and Paged Translation. Contiguous Translation just uses an offset
|
||||
* (bits 0-16 of the virtual address) into each Segment to find an
|
||||
* address, allowing for 128K bytes per Segment. Paged translation
|
||||
* further break Segments down into 64 Pages of 2K each.
|
||||
*
|
||||
* Details about how to do translation are held in main memory in
|
||||
* Segment Descriptors and Page Descriptors. These are located in
|
||||
* Segment Descriptor Tables and Page Descriptor Tables set up by the
|
||||
* computer before enabling the MMU.
|
||||
*
|
||||
* In addition to details in main memory, the MMU has a small cache
|
||||
* of both Segment Descriptors and Page Descriptors. This is NOT just
|
||||
* used for performance reasons! Various features of the cache,
|
||||
* such as updating R and M bits in Segment and Page Descriptors,
|
||||
* are used by various operating system features.
|
||||
*
|
||||
*
|
||||
* Virtual Address Fields
|
||||
* ----------------------
|
||||
*
|
||||
* 31 30 29 17 16 0
|
||||
* +-----+-------------------+-----------------------------+
|
||||
* Contig: | SID | SSL | SOT |
|
||||
* +-----+-------------------+-----------------------------+
|
||||
*
|
||||
* 31 30 29 17 16 11 10 0
|
||||
* +-----+-------------------+---------+-------------------+
|
||||
* Paged: | SID | SSL | PSL | POT |
|
||||
* +-----+-------------------+---------+-------------------+
|
||||
*
|
||||
*
|
||||
* Segment Descriptor Fields
|
||||
* -------------------------
|
||||
*
|
||||
* 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 |
|
||||
* +-------+---------+-----+---+---+---+---+---+---+---+---+
|
||||
*
|
||||
* +-----------------------------------------------+-------+
|
||||
* sd1: | Address (high-order 27 or 29 bits) | Soft |
|
||||
* +-----------------------------------------------+-------+
|
||||
*
|
||||
*
|
||||
* Segment Descriptor Cache Entry
|
||||
* ------------------------------
|
||||
*
|
||||
* 31 24 23 10 9 0
|
||||
* +-------+-------------------------+---------------------+
|
||||
* Low: | Acc | Max Off | Tag |
|
||||
* +-------+-------------------------+---------------------+
|
||||
*
|
||||
* 31 5 4 3 2 1 0
|
||||
* +-----------------------------------+---+---+---+---+---+
|
||||
* High: | Address | T | $ | C | M | G |
|
||||
* +-----------------------------------+---+---+---+---+---+
|
||||
*
|
||||
*
|
||||
* Page Descriptor Fields
|
||||
* ----------------------
|
||||
*
|
||||
* 31 11 10 8 7 6 5 4 3 2 1 0
|
||||
* +----------------+------+-----+---+---+-----+---+---+---+
|
||||
* | Page Address | Soft | Res | R | W | Res | L | M | P |
|
||||
* +----------------+------+-----+---+---+-----+---+---+---+
|
||||
*
|
||||
*
|
||||
* Page Descriptor Cache Entry
|
||||
* ---------------------------
|
||||
*
|
||||
* 31 24 23 16 15 0
|
||||
* +-----+------------------+------------------------------+
|
||||
* Low: | Acc | Res | Tag |
|
||||
* +-----+------------------+------------------------------+
|
||||
*
|
||||
* 31 11 10 7 6 5 4 3 2 1 0
|
||||
* +---------------------+-----+---+---+---+---+---+---+---+
|
||||
* High: | Address | Res | U | R | W | $ | L | M | G |
|
||||
* +---------------------+-----+---+---+---+---+---+---+---+
|
||||
*
|
||||
* "U" is only set in the left cache entry, and indicates
|
||||
* which slot (left or right) was most recently updated.
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#define MMUBASE 0x40000
|
||||
#define MMUSIZE 0x1000
|
||||
|
||||
#define MMU_SRS 0x04 /* Section RAM array size (words) */
|
||||
#define MMU_SDCS 0x20 /* Segment Descriptor Cache H/L array size
|
||||
(words) */
|
||||
#define MMU_PDCS 0x20 /* Page Descriptor Cache H/L array size
|
||||
(words) */
|
||||
|
||||
/* Register address offsets */
|
||||
#define MMU_SDCL 0
|
||||
#define MMU_SDCH 1
|
||||
#define MMU_PDCRL 2
|
||||
#define MMU_PDCRH 3
|
||||
#define MMU_PDCLL 4
|
||||
#define MMU_PDCLH 5
|
||||
#define MMU_SRAMA 6
|
||||
#define MMU_SRAMB 7
|
||||
#define MMU_FC 8
|
||||
#define MMU_FA 9
|
||||
#define MMU_CONF 10
|
||||
#define MMU_VAR 11
|
||||
|
||||
#define MMU_CONF_M (mmu_state.conf & 0x1)
|
||||
#define MMU_CONF_R (mmu_state.conf & 0x2)
|
||||
|
||||
/* Caching */
|
||||
#define NUM_SEC 4u /* Number of memory sections */
|
||||
#define NUM_SDCE 8 /* SD cache entries per section */
|
||||
#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 */
|
||||
|
||||
/* Cache Tag for SDs */
|
||||
#define SD_TAG(vaddr) ((vaddr >> 20) & 0x3ff)
|
||||
|
||||
/* Cache Tag for PDs */
|
||||
#define PD_TAG(vaddr) (((vaddr >> 13) & 0xf) | ((vaddr >> 14) & 0xfff0))
|
||||
|
||||
/* Index of entry in the SD cache */
|
||||
#define SD_IDX(vaddr) ((vaddr >> 17) & 7)
|
||||
|
||||
/* Index of entry in the PD cache */
|
||||
#define PD_IDX(vaddr) (((vaddr >> 11) & 3) | ((vaddr >> 15) & 4))
|
||||
|
||||
/* Shift and mask the flag bits for the current CPU mode */
|
||||
#define MMU_PERM(f) ((f >> ((3 - CPU_CM) * 2)) & 3)
|
||||
|
||||
/* Codes set in the MMU Fault register */
|
||||
#define MMU_F_SDTLEN 0x03
|
||||
#define MMU_F_PW 0x04
|
||||
#define MMU_F_PDTLEN 0x05
|
||||
#define MMU_F_INV_SD 0x06
|
||||
#define MMU_F_SEG_NOT_PRES 0x07
|
||||
#define MMU_F_OTRAP 0x08
|
||||
#define MMU_F_PDT_NOT_PRES 0x09
|
||||
#define MMU_F_PAGE_NOT_PRES 0x0a
|
||||
#define MMU_F_ACC 0x0d
|
||||
#define MMU_F_SEG_OFFSET 0x0e
|
||||
|
||||
/* Access Request types */
|
||||
#define ACC_MT 0 /* Move Translated */
|
||||
#define ACC_SPW 1 /* Support processor write */
|
||||
#define ACC_SPF 3 /* Support processor fetch */
|
||||
#define ACC_IR 7 /* Interlocked read */
|
||||
#define ACC_AF 8 /* Address fetch */
|
||||
#define ACC_OF 9 /* Operand fetch */
|
||||
#define ACC_W 10 /* Write */
|
||||
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */
|
||||
#define ACC_IF 13 /* Instruction fetch */
|
||||
|
||||
/* Pluck out Virtual Address fields */
|
||||
#define SID(va) (((va) >> 30) & 3)
|
||||
#define SSL(va) (((va) >> 17) & 0x1fff)
|
||||
#define SOT(va) (va & 0x1ffff)
|
||||
#define PSL(va) (((va) >> 11) & 0x3f)
|
||||
#define PSL_C(va) ((va) & 0x1f800)
|
||||
#define POT(va) (va & 0x7ff)
|
||||
|
||||
/* Get the maximum length of an SSL from SRAMB */
|
||||
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len + 1)
|
||||
|
||||
/* Pluck out Segment Descriptor fields */
|
||||
#define SD_PRESENT(sd0) ((sd0) & 1)
|
||||
#define SD_MODIFIED(sd0) (((sd0) >> 1) & 1)
|
||||
#define SD_CONTIG(sd0) (((sd0) >> 2) & 1)
|
||||
#define SD_PAGED(sd0) ((((sd0) >> 2) & 1) == 0)
|
||||
#define SD_CACHE(sd0) (((sd0) >> 3) & 1)
|
||||
#define SD_TRAP(sd0) (((sd0) >> 4) & 1)
|
||||
#define SD_REF(sd0) (((sd0) >> 5) & 1)
|
||||
#define SD_VALID(sd0) (((sd0) >> 6) & 1)
|
||||
#define SD_INDIRECT(sd0) (((sd0) >> 7) & 1)
|
||||
#define SD_SEG_ADDR(sd1) ((sd1) & 0xffffffe0)
|
||||
#define SD_MAX_OFF(sd0) (((sd0) >> 10) & 0x3fff)
|
||||
#define SD_ACC(sd0) (((sd0) >> 24) & 0xff)
|
||||
#define SD_R_MASK 0x20
|
||||
#define SD_M_MASK 0x2
|
||||
#define SD_GOOD_MASK 0x1u
|
||||
#define SDCE_TAG(sdcl) ((sdcl) & 0x3ff)
|
||||
|
||||
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
|
||||
|
||||
|
||||
/* Convert from sd to sd cache entry */
|
||||
#define SD_TO_SDCL(va,sd0) ((sd0 & 0xfffffc00)|SD_TAG(va))
|
||||
#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
|
||||
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. */
|
||||
|
||||
#define SDCE_TO_SD0(sdch,sdcl) ((sdcl & 0xfffffc00)|0x40|(sdch & 0x1e)|1)
|
||||
#define SDCE_TO_SD1(sdch) (sdch & 0xffffffe0)
|
||||
|
||||
/* Maximum size (in bytes) of a segment */
|
||||
#define MAX_OFFSET(sd0) ((SD_MAX_OFF(sd0) + 1) * 8)
|
||||
|
||||
#define PD_PRESENT(pd) (pd & 1)
|
||||
#define PD_MODIFIED(pd) ((pd >> 1) & 1)
|
||||
#define PD_LAST(pd) ((pd >> 2) & 1)
|
||||
#define PD_WFAULT(pd) ((pd >> 4) & 1)
|
||||
#define PD_REF(pd) ((pd >> 5) & 1)
|
||||
#define PD_ADDR(pd) (pd & 0xfffff800) /* Address portion of PD */
|
||||
#define PD_R_MASK 0x20
|
||||
#define PD_M_MASK 0x2
|
||||
#define PD_GOOD_MASK 0x1u
|
||||
#define PDCLH_USED_MASK 0x40u
|
||||
#define PDCXL_TAG(pdcxl) (pdcxl & 0xffff)
|
||||
|
||||
#define PD_LOC(sd1,va) SD_SEG_ADDR(sd1) + (PSL(va) * 4)
|
||||
|
||||
/* Page Descriptor Cache Entry
|
||||
*
|
||||
*/
|
||||
|
||||
/* Convert from pd to pd cache entry. Alwasy sets "Good" bit. */
|
||||
#define SD_TO_PDCXL(va,sd0) ((sd0 & 0xff000000)|PD_TAG(va))
|
||||
#define PD_TO_PDCXH(pd,sd0) ((pd & 0xfffff836)|(sd0 & 0x8)|1)
|
||||
|
||||
/* Always set 'present' to true on conversion */
|
||||
#define PDCXH_TO_PD(pdch) ((pdch & 0xfffff836)|1)
|
||||
#define PDCXL_TO_ACC(pdcl) (((pdcl & 0xff000000) >> 24) & 0xff)
|
||||
|
||||
/* Fault codes */
|
||||
#define MMU_FAULT(f) { \
|
||||
if (fc) { \
|
||||
mmu_state.fcode = ((((uint32)r_acc)<<7)| \
|
||||
(((uint32)(CPU_CM))<<5)|f); \
|
||||
mmu_state.faddr = va; \
|
||||
} \
|
||||
}
|
||||
|
||||
typedef struct _mmu_sec {
|
||||
uint32 addr;
|
||||
uint32 len;
|
||||
} mmu_sec;
|
||||
|
||||
typedef struct _mmu_state {
|
||||
t_bool enabled; /* Global enabled/disabled flag */
|
||||
|
||||
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
|
||||
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
|
||||
|
||||
uint32 pdcll[MMU_PDCS]; /* PDC low bits (left) (0-31) */
|
||||
uint32 pdclh[MMU_PDCS]; /* PDC high bits (left) (32-63) */
|
||||
|
||||
uint32 pdcrl[MMU_PDCS]; /* PDC low bits (right) (0-31) */
|
||||
uint32 pdcrh[MMU_PDCS]; /* PDC high bits (right) (32-63) */
|
||||
|
||||
uint32 sra[MMU_SRS]; /* Section RAM A */
|
||||
uint32 srb[MMU_SRS]; /* Section RAM B */
|
||||
|
||||
mmu_sec sec[MMU_SRS]; /* Section descriptors decoded from
|
||||
Section RAM A and B */
|
||||
|
||||
uint32 fcode; /* Fault Code Register */
|
||||
uint32 faddr; /* Fault Address Register */
|
||||
uint32 conf; /* Configuration Register */
|
||||
uint32 var; /* Virtual Address Register */
|
||||
|
||||
} MMU_STATE;
|
||||
|
||||
t_stat mmu_init(DEVICE *dptr);
|
||||
uint32 mmu_read(uint32 pa, size_t size);
|
||||
void mmu_write(uint32 pa, uint32 val, size_t size);
|
||||
CONST char *mmu_description(DEVICE *dptr);
|
||||
|
||||
/* Virtual memory translation */
|
||||
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
|
||||
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
|
||||
t_bool fc, uint32 *pa);
|
||||
|
||||
#define SHOULD_CACHE_PD(pd) \
|
||||
(fc && PD_PRESENT(pd))
|
||||
|
||||
#define SHOULD_CACHE_SD(sd) \
|
||||
(fc && SD_VALID(sd) && SD_PRESENT(sd))
|
||||
|
||||
#define SHOULD_UPDATE_SD_R_BIT(sd) \
|
||||
(MMU_CONF_R && !((sd) & SD_R_MASK))
|
||||
|
||||
#define SHOULD_UPDATE_SD_M_BIT(sd) \
|
||||
(MMU_CONF_M && r_acc == ACC_W && !((sd) & SD_M_MASK))
|
||||
|
||||
#define SHOULD_UPDATE_PD_R_BIT(pd) \
|
||||
(!((pd) & PD_R_MASK))
|
||||
|
||||
#define SHOULD_UPDATE_PD_M_BIT(pd) \
|
||||
(r_acc == ACC_W && !((pd) & PD_M_MASK))
|
||||
|
||||
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_ */
|
||||
|
|
|
@ -1,82 +1,82 @@
|
|||
/* 3b2_rev2_sys.c: Version 2 (3B2/400) System Definition
|
||||
|
||||
Copyright (c) 2017-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_ctc.h"
|
||||
#include "3b2_id.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_iu.h"
|
||||
#include "3b2_ni.h"
|
||||
#include "3b2_ports.h"
|
||||
#include "3b2_mau.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_timer.h"
|
||||
|
||||
char sim_name[] = "AT&T 3B2/400";
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&mmu_dev,
|
||||
&mau_dev,
|
||||
&timer_dev,
|
||||
&tod_dev,
|
||||
&nvram_dev,
|
||||
&csr_dev,
|
||||
&tti_dev,
|
||||
&tto_dev,
|
||||
&contty_dev,
|
||||
&iu_timer_dev,
|
||||
&dmac_dev,
|
||||
&if_dev,
|
||||
&id_dev,
|
||||
&ports_dev,
|
||||
&ctc_dev,
|
||||
&ni_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
void full_reset()
|
||||
{
|
||||
cpu_reset(&cpu_dev);
|
||||
mau_reset(&mau_dev);
|
||||
tti_reset(&tti_dev);
|
||||
contty_reset(&contty_dev);
|
||||
iu_timer_reset(&iu_timer_dev);
|
||||
timer_reset(&timer_dev);
|
||||
if_reset(&if_dev);
|
||||
id_reset(&id_dev);
|
||||
csr_reset(&csr_dev);
|
||||
ports_reset(&ports_dev);
|
||||
ctc_reset(&ctc_dev);
|
||||
ni_reset(&ni_dev);
|
||||
}
|
||||
/* 3b2_rev2_sys.c: Version 2 (3B2/400) System Definition
|
||||
|
||||
Copyright (c) 2017-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_ctc.h"
|
||||
#include "3b2_id.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_iu.h"
|
||||
#include "3b2_ni.h"
|
||||
#include "3b2_ports.h"
|
||||
#include "3b2_mau.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_timer.h"
|
||||
|
||||
char sim_name[] = "AT&T 3B2/400";
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&mmu_dev,
|
||||
&mau_dev,
|
||||
&timer_dev,
|
||||
&tod_dev,
|
||||
&nvram_dev,
|
||||
&csr_dev,
|
||||
&tti_dev,
|
||||
&tto_dev,
|
||||
&contty_dev,
|
||||
&iu_timer_dev,
|
||||
&dmac_dev,
|
||||
&if_dev,
|
||||
&id_dev,
|
||||
&ports_dev,
|
||||
&ctc_dev,
|
||||
&ni_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
void full_reset()
|
||||
{
|
||||
cpu_reset(&cpu_dev);
|
||||
mau_reset(&mau_dev);
|
||||
tti_reset(&tti_dev);
|
||||
contty_reset(&contty_dev);
|
||||
iu_timer_reset(&iu_timer_dev);
|
||||
timer_reset(&timer_dev);
|
||||
if_reset(&if_dev);
|
||||
id_reset(&id_dev);
|
||||
csr_reset(&csr_dev);
|
||||
ports_reset(&ports_dev);
|
||||
ctc_reset(&ctc_dev);
|
||||
ni_reset(&ni_dev);
|
||||
}
|
||||
|
|
|
@ -1,293 +1,293 @@
|
|||
/* 3b2_rev3_csr.c: CM518B System Board Control, Status & Error Register
|
||||
|
||||
Copyright (c) 2020-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_timer.h"
|
||||
#include "3b2_sys.h"
|
||||
|
||||
CSR_DATA csr_data;
|
||||
|
||||
BITFIELD csr_bits[] = {
|
||||
BIT(UTIM),
|
||||
BIT(PWDN),
|
||||
BIT(OI15),
|
||||
BIT(IUINT),
|
||||
BIT(IUDMA),
|
||||
BIT(PIR9),
|
||||
BIT(PIR8),
|
||||
BIT(IUTIM),
|
||||
|
||||
BIT(ISTY),
|
||||
BIT(IUBUS),
|
||||
BIT(IFLT),
|
||||
BIT(ISBER),
|
||||
BIT(IBUS),
|
||||
BIT(IBUB),
|
||||
BIT(FECC),
|
||||
BIT(THERM),
|
||||
|
||||
BIT(FLED),
|
||||
BIT(PSPWR),
|
||||
BIT(FLSPD),
|
||||
BIT(FLSD1),
|
||||
BIT(FLMOT),
|
||||
BIT(FLDEN),
|
||||
BIT(FLSZ),
|
||||
BIT(SBER),
|
||||
|
||||
BIT(MBER),
|
||||
BIT(UBFL),
|
||||
BIT(TIMO),
|
||||
BIT(FLTFR),
|
||||
BIT(DALGN),
|
||||
BIT(STTIM),
|
||||
BIT(ABRT),
|
||||
BIT(RSTR),
|
||||
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
UNIT csr_unit = {
|
||||
UDATA(NULL, UNIT_FIX, CSRSIZE)
|
||||
};
|
||||
|
||||
REG csr_reg[] = {
|
||||
{ HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE csr_dev = {
|
||||
"CSR", &csr_unit, csr_reg, NULL,
|
||||
1, 16, 8, 4, 16, 32,
|
||||
&csr_ex, &csr_dep, &csr_reset,
|
||||
NULL, NULL, NULL, NULL,
|
||||
DEV_DEBUG, 0, sys_deb_tab
|
||||
};
|
||||
|
||||
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_reset(DEVICE *dptr)
|
||||
{
|
||||
CSRBIT(CSRFECC, TRUE);
|
||||
CSRBIT(CSRTHERM, FALSE);
|
||||
CSRBIT(CSRITIM, TRUE);
|
||||
CSRBIT(CSRISTIM, TRUE);
|
||||
CSRBIT(CSRIBUB, TRUE);
|
||||
CSRBIT(CSRPWRSPDN, FALSE);
|
||||
CSRBIT(CSRFLPMO, TRUE);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 csr_read(uint32 pa, size_t size)
|
||||
{
|
||||
uint32 reg = (pa - CSRBASE) & 0xff;
|
||||
|
||||
switch (reg & 0xf0) {
|
||||
case 0x00:
|
||||
return csr_data & 0xff;
|
||||
case 0x20:
|
||||
return (csr_data >> 8) & 0xff;
|
||||
case 0x40:
|
||||
return (csr_data >> 16) & 0xff;
|
||||
case 0x60:
|
||||
return (csr_data >> 24) & 0xff;
|
||||
default:
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"CSR READ. Warning, unexpected register = %02x)\n",
|
||||
reg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_INT(flag, val) { \
|
||||
if (val) { \
|
||||
CPU_SET_INT(flag); \
|
||||
} else { \
|
||||
CPU_CLR_INT(flag); \
|
||||
} \
|
||||
}
|
||||
|
||||
void csr_write(uint32 pa, uint32 val, size_t size)
|
||||
{
|
||||
uint32 reg = pa - CSRBASE;
|
||||
|
||||
switch (reg) {
|
||||
|
||||
case 0x00:
|
||||
CSRBIT(CSRCLK, val);
|
||||
SET_INT(INT_CLOCK, val);
|
||||
break;
|
||||
case 0x04:
|
||||
CSRBIT(CSRPWRDN, val);
|
||||
SET_INT(INT_PWRDWN, val);
|
||||
break;
|
||||
case 0x08:
|
||||
CSRBIT(CSROPINT15, val);
|
||||
SET_INT(INT_BUS_OP, val);
|
||||
break;
|
||||
case 0x0c:
|
||||
CSRBIT(CSRUART, val);
|
||||
SET_INT(INT_UART, val);
|
||||
break;
|
||||
case 0x10:
|
||||
CSRBIT(CSRDMA, val);
|
||||
SET_INT(INT_UART_DMA, val);
|
||||
break;
|
||||
case 0x14:
|
||||
CSRBIT(CSRPIR9, val);
|
||||
SET_INT(INT_PIR9, val);
|
||||
break;
|
||||
case 0x18:
|
||||
CSRBIT(CSRPIR8, val);
|
||||
SET_INT(INT_PIR8, val);
|
||||
break;
|
||||
case 0x1c:
|
||||
CSRBIT(CSRITIM, val);
|
||||
timer_gate(TIMER_INTERVAL, CSR(CSRITIM));
|
||||
break;
|
||||
case 0x20:
|
||||
CSRBIT(CSRISTIM, val);
|
||||
timer_gate(TIMER_SANITY, CSR(CSRISTIM));
|
||||
break;
|
||||
case 0x24:
|
||||
CSRBIT(CSRITIMO, val);
|
||||
timer_gate(TIMER_BUS, CSR(CSRITIMO));
|
||||
break;
|
||||
case 0x28:
|
||||
CSRBIT(CSRICPUFLT, val);
|
||||
break;
|
||||
case 0x2c:
|
||||
CSRBIT(CSRISBERR, val);
|
||||
break;
|
||||
case 0x30:
|
||||
CSRBIT(CSRIIOBUS, val);
|
||||
break;
|
||||
case 0x34:
|
||||
CSRBIT(CSRIBUB, val);
|
||||
break;
|
||||
case 0x38:
|
||||
CSRBIT(CSRFECC, val);
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"CSR WRITE. Force ECC Syndrome = %d\n",
|
||||
val);
|
||||
break;
|
||||
case 0x3c:
|
||||
CSRBIT(CSRTHERM, val);
|
||||
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
|
||||
break;
|
||||
case 0x40:
|
||||
CSRBIT(CSRLED, val);
|
||||
break;
|
||||
case 0x44:
|
||||
CSRBIT(CSRPWRSPDN, val);
|
||||
if (!val) {
|
||||
/* Stop the simulator - power down */
|
||||
stop_reason = STOP_POWER;
|
||||
}
|
||||
break;
|
||||
case 0x48:
|
||||
CSRBIT(CSRFLPFST, val);
|
||||
break;
|
||||
case 0x4c: /* Floppy Side 1: Set when Cleared */
|
||||
if_state.side = (val & 1) ? 0 : 1;
|
||||
CSRBIT(CSRFLPS1, val & 1);
|
||||
break;
|
||||
case 0x50:
|
||||
CSRBIT(CSRFLPMO, val);
|
||||
break;
|
||||
case 0x54:
|
||||
CSRBIT(CSRFLPDEN, val);
|
||||
break;
|
||||
case 0x58:
|
||||
CSRBIT(CSRFLPSZ, val);
|
||||
break;
|
||||
case 0x5c:
|
||||
CSRBIT(CSRSBERR, val);
|
||||
if (val) {
|
||||
if (!(csr_data & CSRISBERR)) {
|
||||
SET_INT(INT_SBERR, TRUE);
|
||||
}
|
||||
} else {
|
||||
SET_INT(INT_SBERR, FALSE);
|
||||
}
|
||||
break;
|
||||
case 0x60:
|
||||
CSRBIT(CSRMBERR, val);
|
||||
SET_INT(INT_MBERR, val);
|
||||
break;
|
||||
case 0x64:
|
||||
CSRBIT(CSRUBUBF, val);
|
||||
SET_INT(INT_BUS_RXF, val);
|
||||
break;
|
||||
case 0x68:
|
||||
CSRBIT(CSRTIMO, val);
|
||||
if (val) {
|
||||
if (!(csr_data & CSRITIMO)) {
|
||||
SET_INT(INT_BUS_TMO, TRUE);
|
||||
}
|
||||
} else {
|
||||
SET_INT(INT_BUS_TMO, FALSE);
|
||||
}
|
||||
break;
|
||||
case 0x6c:
|
||||
CSRBIT(CSRFRF, val);
|
||||
break;
|
||||
case 0x70:
|
||||
CSRBIT(CSRALGN, val);
|
||||
break;
|
||||
case 0x74:
|
||||
CSRBIT(CSRSTIMO, val);
|
||||
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
|
||||
break;
|
||||
case 0x78:
|
||||
CSRBIT(CSRABRT, val);
|
||||
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
|
||||
break;
|
||||
case 0x7c:
|
||||
/* System reset request */
|
||||
full_reset();
|
||||
cpu_boot(0, &cpu_dev);
|
||||
break;
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* 3b2_rev3_csr.c: CM518B System Board Control, Status & Error Register
|
||||
|
||||
Copyright (c) 2020-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_timer.h"
|
||||
#include "3b2_sys.h"
|
||||
|
||||
CSR_DATA csr_data;
|
||||
|
||||
BITFIELD csr_bits[] = {
|
||||
BIT(UTIM),
|
||||
BIT(PWDN),
|
||||
BIT(OI15),
|
||||
BIT(IUINT),
|
||||
BIT(IUDMA),
|
||||
BIT(PIR9),
|
||||
BIT(PIR8),
|
||||
BIT(IUTIM),
|
||||
|
||||
BIT(ISTY),
|
||||
BIT(IUBUS),
|
||||
BIT(IFLT),
|
||||
BIT(ISBER),
|
||||
BIT(IBUS),
|
||||
BIT(IBUB),
|
||||
BIT(FECC),
|
||||
BIT(THERM),
|
||||
|
||||
BIT(FLED),
|
||||
BIT(PSPWR),
|
||||
BIT(FLSPD),
|
||||
BIT(FLSD1),
|
||||
BIT(FLMOT),
|
||||
BIT(FLDEN),
|
||||
BIT(FLSZ),
|
||||
BIT(SBER),
|
||||
|
||||
BIT(MBER),
|
||||
BIT(UBFL),
|
||||
BIT(TIMO),
|
||||
BIT(FLTFR),
|
||||
BIT(DALGN),
|
||||
BIT(STTIM),
|
||||
BIT(ABRT),
|
||||
BIT(RSTR),
|
||||
|
||||
ENDBITS
|
||||
};
|
||||
|
||||
UNIT csr_unit = {
|
||||
UDATA(NULL, UNIT_FIX, CSRSIZE)
|
||||
};
|
||||
|
||||
REG csr_reg[] = {
|
||||
{ HRDATADF(DATA, csr_data, 32, "CSR Data", csr_bits) },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
DEVICE csr_dev = {
|
||||
"CSR", &csr_unit, csr_reg, NULL,
|
||||
1, 16, 8, 4, 16, 32,
|
||||
&csr_ex, &csr_dep, &csr_reset,
|
||||
NULL, NULL, NULL, NULL,
|
||||
DEV_DEBUG, 0, sys_deb_tab
|
||||
};
|
||||
|
||||
t_stat csr_ex(t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_dep(t_value val, t_addr exta, UNIT *uptr, int32 sw)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat csr_reset(DEVICE *dptr)
|
||||
{
|
||||
CSRBIT(CSRFECC, TRUE);
|
||||
CSRBIT(CSRTHERM, FALSE);
|
||||
CSRBIT(CSRITIM, TRUE);
|
||||
CSRBIT(CSRISTIM, TRUE);
|
||||
CSRBIT(CSRIBUB, TRUE);
|
||||
CSRBIT(CSRPWRSPDN, FALSE);
|
||||
CSRBIT(CSRFLPMO, TRUE);
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
uint32 csr_read(uint32 pa, size_t size)
|
||||
{
|
||||
uint32 reg = (pa - CSRBASE) & 0xff;
|
||||
|
||||
switch (reg & 0xf0) {
|
||||
case 0x00:
|
||||
return csr_data & 0xff;
|
||||
case 0x20:
|
||||
return (csr_data >> 8) & 0xff;
|
||||
case 0x40:
|
||||
return (csr_data >> 16) & 0xff;
|
||||
case 0x60:
|
||||
return (csr_data >> 24) & 0xff;
|
||||
default:
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"CSR READ. Warning, unexpected register = %02x)\n",
|
||||
reg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define SET_INT(flag, val) { \
|
||||
if (val) { \
|
||||
CPU_SET_INT(flag); \
|
||||
} else { \
|
||||
CPU_CLR_INT(flag); \
|
||||
} \
|
||||
}
|
||||
|
||||
void csr_write(uint32 pa, uint32 val, size_t size)
|
||||
{
|
||||
uint32 reg = pa - CSRBASE;
|
||||
|
||||
switch (reg) {
|
||||
|
||||
case 0x00:
|
||||
CSRBIT(CSRCLK, val);
|
||||
SET_INT(INT_CLOCK, val);
|
||||
break;
|
||||
case 0x04:
|
||||
CSRBIT(CSRPWRDN, val);
|
||||
SET_INT(INT_PWRDWN, val);
|
||||
break;
|
||||
case 0x08:
|
||||
CSRBIT(CSROPINT15, val);
|
||||
SET_INT(INT_BUS_OP, val);
|
||||
break;
|
||||
case 0x0c:
|
||||
CSRBIT(CSRUART, val);
|
||||
SET_INT(INT_UART, val);
|
||||
break;
|
||||
case 0x10:
|
||||
CSRBIT(CSRDMA, val);
|
||||
SET_INT(INT_UART_DMA, val);
|
||||
break;
|
||||
case 0x14:
|
||||
CSRBIT(CSRPIR9, val);
|
||||
SET_INT(INT_PIR9, val);
|
||||
break;
|
||||
case 0x18:
|
||||
CSRBIT(CSRPIR8, val);
|
||||
SET_INT(INT_PIR8, val);
|
||||
break;
|
||||
case 0x1c:
|
||||
CSRBIT(CSRITIM, val);
|
||||
timer_gate(TIMER_INTERVAL, CSR(CSRITIM));
|
||||
break;
|
||||
case 0x20:
|
||||
CSRBIT(CSRISTIM, val);
|
||||
timer_gate(TIMER_SANITY, CSR(CSRISTIM));
|
||||
break;
|
||||
case 0x24:
|
||||
CSRBIT(CSRITIMO, val);
|
||||
timer_gate(TIMER_BUS, CSR(CSRITIMO));
|
||||
break;
|
||||
case 0x28:
|
||||
CSRBIT(CSRICPUFLT, val);
|
||||
break;
|
||||
case 0x2c:
|
||||
CSRBIT(CSRISBERR, val);
|
||||
break;
|
||||
case 0x30:
|
||||
CSRBIT(CSRIIOBUS, val);
|
||||
break;
|
||||
case 0x34:
|
||||
CSRBIT(CSRIBUB, val);
|
||||
break;
|
||||
case 0x38:
|
||||
CSRBIT(CSRFECC, val);
|
||||
sim_debug(WRITE_MSG, &csr_dev,
|
||||
"CSR WRITE. Force ECC Syndrome = %d\n",
|
||||
val);
|
||||
break;
|
||||
case 0x3c:
|
||||
CSRBIT(CSRTHERM, val);
|
||||
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
|
||||
break;
|
||||
case 0x40:
|
||||
CSRBIT(CSRLED, val);
|
||||
break;
|
||||
case 0x44:
|
||||
CSRBIT(CSRPWRSPDN, val);
|
||||
if (!val) {
|
||||
/* Stop the simulator - power down */
|
||||
stop_reason = STOP_POWER;
|
||||
}
|
||||
break;
|
||||
case 0x48:
|
||||
CSRBIT(CSRFLPFST, val);
|
||||
break;
|
||||
case 0x4c: /* Floppy Side 1: Set when Cleared */
|
||||
if_state.side = (val & 1) ? 0 : 1;
|
||||
CSRBIT(CSRFLPS1, val & 1);
|
||||
break;
|
||||
case 0x50:
|
||||
CSRBIT(CSRFLPMO, val);
|
||||
break;
|
||||
case 0x54:
|
||||
CSRBIT(CSRFLPDEN, val);
|
||||
break;
|
||||
case 0x58:
|
||||
CSRBIT(CSRFLPSZ, val);
|
||||
break;
|
||||
case 0x5c:
|
||||
CSRBIT(CSRSBERR, val);
|
||||
if (val) {
|
||||
if (!(csr_data & CSRISBERR)) {
|
||||
SET_INT(INT_SBERR, TRUE);
|
||||
}
|
||||
} else {
|
||||
SET_INT(INT_SBERR, FALSE);
|
||||
}
|
||||
break;
|
||||
case 0x60:
|
||||
CSRBIT(CSRMBERR, val);
|
||||
SET_INT(INT_MBERR, val);
|
||||
break;
|
||||
case 0x64:
|
||||
CSRBIT(CSRUBUBF, val);
|
||||
SET_INT(INT_BUS_RXF, val);
|
||||
break;
|
||||
case 0x68:
|
||||
CSRBIT(CSRTIMO, val);
|
||||
if (val) {
|
||||
if (!(csr_data & CSRITIMO)) {
|
||||
SET_INT(INT_BUS_TMO, TRUE);
|
||||
}
|
||||
} else {
|
||||
SET_INT(INT_BUS_TMO, FALSE);
|
||||
}
|
||||
break;
|
||||
case 0x6c:
|
||||
CSRBIT(CSRFRF, val);
|
||||
break;
|
||||
case 0x70:
|
||||
CSRBIT(CSRALGN, val);
|
||||
break;
|
||||
case 0x74:
|
||||
CSRBIT(CSRSTIMO, val);
|
||||
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
|
||||
break;
|
||||
case 0x78:
|
||||
CSRBIT(CSRABRT, val);
|
||||
cpu_nmi = val ? TRUE : FALSE; /* Immediate NMI */
|
||||
break;
|
||||
case 0x7c:
|
||||
/* System reset request */
|
||||
full_reset();
|
||||
cpu_boot(0, &cpu_dev);
|
||||
break;
|
||||
default:
|
||||
/* Do nothing */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
/* 3b2_rev3_csr.h: CM518B System Board Control, Status & Error Register
|
||||
|
||||
Copyright (c) 2020-2022, 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_400_CSR_H_
|
||||
#define _3B2_400_CSR_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
typedef uint32 CSR_DATA;
|
||||
|
||||
t_stat csr_svc(UNIT *uptr);
|
||||
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_reset(DEVICE *dptr);
|
||||
uint32 csr_read(uint32 pa, size_t size);
|
||||
void csr_write(uint32 pa, uint32 val, size_t size);
|
||||
|
||||
#endif
|
||||
/* 3b2_rev3_csr.h: CM518B System Board Control, Status & Error Register
|
||||
|
||||
Copyright (c) 2020-2022, 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_400_CSR_H_
|
||||
#define _3B2_400_CSR_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
typedef uint32 CSR_DATA;
|
||||
|
||||
t_stat csr_svc(UNIT *uptr);
|
||||
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_reset(DEVICE *dptr);
|
||||
uint32 csr_read(uint32 pa, size_t size);
|
||||
void csr_write(uint32 pa, uint32 val, size_t size);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,141 +1,141 @@
|
|||
/* 3b2_rev3_defs.h: Veresion 3 (3B2/700) Common Definitions
|
||||
|
||||
Copyright (c) 2021-2022, 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_DEFS_H_
|
||||
#define _3B2_REV3_DEFS_H_
|
||||
|
||||
#define NUM_REGISTERS 32
|
||||
|
||||
#define DEFMEMSIZE MSIZ_16M
|
||||
#define MAXMEMSIZE MSIZ_64M
|
||||
|
||||
#define HWORD_OP_COUNT 12
|
||||
#define CPU_VERSION 0x1F /* Version encoded in WE32200 */
|
||||
|
||||
/* CSR Flags */
|
||||
#define CSRCLK 1u /* UNIX Interval Timer Timeout */
|
||||
#define CSRPWRDN (1u << 1) /* Power Down Request */
|
||||
#define CSROPINT15 (1u << 2) /* Oper. Interrupt Level 15 */
|
||||
#define CSRUART (1u << 3) /* DUART Interrupt */
|
||||
#define CSRDMA (1u << 4) /* DUART DMA Complete Interrupt */
|
||||
#define CSRPIR9 (1u << 5) /* Programmed Interrupt 9 */
|
||||
#define CSRPIR8 (1u << 6) /* Programmed Interrupt 8 */
|
||||
#define CSRITIM (1u << 7) /* Inhibit UNIX Interval Timer */
|
||||
#define CSRISTIM (1u << 8) /* Inhibit System Sanity Timer */
|
||||
#define CSRITIMO (1u << 9) /* Inhibit Bus Timer */
|
||||
#define CSRICPUFLT (1u << 10) /* Inhibit Faults to CPU */
|
||||
#define CSRISBERR (1u << 11) /* Inhibit Single Bit Error Rpt */
|
||||
#define CSRIIOBUS (1u << 12) /* Inhibit Integral 3B2 I/O Bus */
|
||||
#define CSRIBUB (1u << 13) /* Inhibit 4 BUB Slots */
|
||||
#define CSRFECC (1u << 14) /* Force ECC Syndrome */
|
||||
#define CSRTHERM (1u << 15) /* Thermal Shutdown Request */
|
||||
#define CSRLED (1u << 16) /* Failure LED */
|
||||
#define CSRPWRSPDN (1u << 17) /* Power Down -- Power Supply */
|
||||
#define CSRFLPFST (1u << 18) /* Floppy Speed Fast */
|
||||
#define CSRFLPS1 (1u << 19) /* Floppy Side 1 */
|
||||
#define CSRFLPMO (1u << 20) /* Floppy Motor On */
|
||||
#define CSRFLPDEN (1u << 21) /* Floppy Density */
|
||||
#define CSRFLPSZ (1u << 22) /* Floppy Size */
|
||||
#define CSRSBERR (1u << 23) /* Single Bit Error */
|
||||
#define CSRMBERR (1u << 24) /* Multiple Bit Error */
|
||||
#define CSRUBUBF (1u << 25) /* Ubus/BUB Received Fail */
|
||||
#define CSRTIMO (1u << 26) /* Bus Timer Timeout */
|
||||
#define CSRFRF (1u << 27) /* Fault Registers Frozen */
|
||||
#define CSRALGN (1u << 28) /* Data Alignment Error */
|
||||
#define CSRSTIMO (1u << 29) /* Sanity Timer Timeout */
|
||||
#define CSRABRT (1u << 30) /* Abort Switch Activated */
|
||||
#define CSRRRST (1u << 31) /* System Reset Request */
|
||||
|
||||
/* Interrupt Sources */
|
||||
#define INT_CLOCK 0x0001 /* UNIX Interval Timer Timeout - 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_SBERR 0x0008 /* Single 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_TMO 0x0040 /* UBUS Timer Timeout - IPL 15 */
|
||||
#define INT_UART_DMA 0x0080 /* UART DMA Complete - IPL 13 */
|
||||
#define INT_UART 0x0100 /* UART Interrupt - IPL 13 */
|
||||
#define INT_FLOPPY_DMA 0x0200 /* Floppy DMA Complete - IPL 11 */
|
||||
#define INT_FLOPPY 0x0400 /* Floppy Interrupt - IPL 11 */
|
||||
#define INT_PIR9 0x0800 /* PIR-9 (from CSER) - IPL 9 */
|
||||
#define INT_PIR8 0x1000 /* PIR-8 (from CSER) - IPL 8 */
|
||||
|
||||
#define INT_MAP_LEN 0x2000
|
||||
|
||||
#define IFCSRBASE 0x40000
|
||||
#define IFCSRSIZE 0x100
|
||||
#define TIMERBASE 0x41000
|
||||
#define TIMERSIZE 0x20
|
||||
#define NVRBASE 0x42000
|
||||
#define NVRSIZE 0x2000
|
||||
#define CSRBASE 0x44000
|
||||
#define CSRSIZE 0x100
|
||||
#define DMAIFBASE 0x45000
|
||||
#define DMAIFSIZE 0x5
|
||||
#define DMAIUABASE 0x46000
|
||||
#define DMAIUASIZE 0x5
|
||||
#define DMAIUBBASE 0x47000
|
||||
#define DMAIUBSIZE 0x5
|
||||
#define DMACBASE 0x48000
|
||||
#define DMACSIZE 0x11
|
||||
#define IFBASE 0x4a000
|
||||
#define IFSIZE 0x10
|
||||
#define TODBASE 0x4e000
|
||||
#define TODSIZE 0x40
|
||||
#define MMUBASE 0x4f000
|
||||
#define MMUSIZE 0x1000
|
||||
#define FLTLBASE 0x4c000
|
||||
#define FLTLSIZE 0x1000
|
||||
#define FLTHBASE 0x4d000
|
||||
#define FLTHSIZE 0x1000
|
||||
|
||||
#define VCACHE_BOTTOM 0x1c00000
|
||||
#define VCACHE_TOP 0x2000000
|
||||
|
||||
#define BUB_BOTTOM 0x6000000
|
||||
#define BUB_TOP 0x1a000000
|
||||
|
||||
#define IF_STATUS_REG 0
|
||||
#define IF_CMD_REG 0
|
||||
#define IF_TRACK_REG 1
|
||||
#define IF_SECTOR_REG 2
|
||||
#define IF_DATA_REG 3
|
||||
|
||||
#define DMA_IF_CHAN 1
|
||||
#define DMA_IUA_CHAN 2
|
||||
#define DMA_IUB_CHAN 3
|
||||
|
||||
#define DMA_IF 0x45
|
||||
#define DMA_IUA 0x46
|
||||
#define DMA_IUB 0x47
|
||||
#define DMA_C 0x48
|
||||
|
||||
#endif
|
||||
/* 3b2_rev3_defs.h: Veresion 3 (3B2/700) Common Definitions
|
||||
|
||||
Copyright (c) 2021-2022, 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_DEFS_H_
|
||||
#define _3B2_REV3_DEFS_H_
|
||||
|
||||
#define NUM_REGISTERS 32
|
||||
|
||||
#define DEFMEMSIZE MSIZ_16M
|
||||
#define MAXMEMSIZE MSIZ_64M
|
||||
|
||||
#define HWORD_OP_COUNT 12
|
||||
#define CPU_VERSION 0x1F /* Version encoded in WE32200 */
|
||||
|
||||
/* CSR Flags */
|
||||
#define CSRCLK 1u /* UNIX Interval Timer Timeout */
|
||||
#define CSRPWRDN (1u << 1) /* Power Down Request */
|
||||
#define CSROPINT15 (1u << 2) /* Oper. Interrupt Level 15 */
|
||||
#define CSRUART (1u << 3) /* DUART Interrupt */
|
||||
#define CSRDMA (1u << 4) /* DUART DMA Complete Interrupt */
|
||||
#define CSRPIR9 (1u << 5) /* Programmed Interrupt 9 */
|
||||
#define CSRPIR8 (1u << 6) /* Programmed Interrupt 8 */
|
||||
#define CSRITIM (1u << 7) /* Inhibit UNIX Interval Timer */
|
||||
#define CSRISTIM (1u << 8) /* Inhibit System Sanity Timer */
|
||||
#define CSRITIMO (1u << 9) /* Inhibit Bus Timer */
|
||||
#define CSRICPUFLT (1u << 10) /* Inhibit Faults to CPU */
|
||||
#define CSRISBERR (1u << 11) /* Inhibit Single Bit Error Rpt */
|
||||
#define CSRIIOBUS (1u << 12) /* Inhibit Integral 3B2 I/O Bus */
|
||||
#define CSRIBUB (1u << 13) /* Inhibit 4 BUB Slots */
|
||||
#define CSRFECC (1u << 14) /* Force ECC Syndrome */
|
||||
#define CSRTHERM (1u << 15) /* Thermal Shutdown Request */
|
||||
#define CSRLED (1u << 16) /* Failure LED */
|
||||
#define CSRPWRSPDN (1u << 17) /* Power Down -- Power Supply */
|
||||
#define CSRFLPFST (1u << 18) /* Floppy Speed Fast */
|
||||
#define CSRFLPS1 (1u << 19) /* Floppy Side 1 */
|
||||
#define CSRFLPMO (1u << 20) /* Floppy Motor On */
|
||||
#define CSRFLPDEN (1u << 21) /* Floppy Density */
|
||||
#define CSRFLPSZ (1u << 22) /* Floppy Size */
|
||||
#define CSRSBERR (1u << 23) /* Single Bit Error */
|
||||
#define CSRMBERR (1u << 24) /* Multiple Bit Error */
|
||||
#define CSRUBUBF (1u << 25) /* Ubus/BUB Received Fail */
|
||||
#define CSRTIMO (1u << 26) /* Bus Timer Timeout */
|
||||
#define CSRFRF (1u << 27) /* Fault Registers Frozen */
|
||||
#define CSRALGN (1u << 28) /* Data Alignment Error */
|
||||
#define CSRSTIMO (1u << 29) /* Sanity Timer Timeout */
|
||||
#define CSRABRT (1u << 30) /* Abort Switch Activated */
|
||||
#define CSRRRST (1u << 31) /* System Reset Request */
|
||||
|
||||
/* Interrupt Sources */
|
||||
#define INT_CLOCK 0x0001 /* UNIX Interval Timer Timeout - 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_SBERR 0x0008 /* Single 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_TMO 0x0040 /* UBUS Timer Timeout - IPL 15 */
|
||||
#define INT_UART_DMA 0x0080 /* UART DMA Complete - IPL 13 */
|
||||
#define INT_UART 0x0100 /* UART Interrupt - IPL 13 */
|
||||
#define INT_FLOPPY_DMA 0x0200 /* Floppy DMA Complete - IPL 11 */
|
||||
#define INT_FLOPPY 0x0400 /* Floppy Interrupt - IPL 11 */
|
||||
#define INT_PIR9 0x0800 /* PIR-9 (from CSER) - IPL 9 */
|
||||
#define INT_PIR8 0x1000 /* PIR-8 (from CSER) - IPL 8 */
|
||||
|
||||
#define INT_MAP_LEN 0x2000
|
||||
|
||||
#define IFCSRBASE 0x40000
|
||||
#define IFCSRSIZE 0x100
|
||||
#define TIMERBASE 0x41000
|
||||
#define TIMERSIZE 0x20
|
||||
#define NVRBASE 0x42000
|
||||
#define NVRSIZE 0x2000
|
||||
#define CSRBASE 0x44000
|
||||
#define CSRSIZE 0x100
|
||||
#define DMAIFBASE 0x45000
|
||||
#define DMAIFSIZE 0x5
|
||||
#define DMAIUABASE 0x46000
|
||||
#define DMAIUASIZE 0x5
|
||||
#define DMAIUBBASE 0x47000
|
||||
#define DMAIUBSIZE 0x5
|
||||
#define DMACBASE 0x48000
|
||||
#define DMACSIZE 0x11
|
||||
#define IFBASE 0x4a000
|
||||
#define IFSIZE 0x10
|
||||
#define TODBASE 0x4e000
|
||||
#define TODSIZE 0x40
|
||||
#define MMUBASE 0x4f000
|
||||
#define MMUSIZE 0x1000
|
||||
#define FLTLBASE 0x4c000
|
||||
#define FLTLSIZE 0x1000
|
||||
#define FLTHBASE 0x4d000
|
||||
#define FLTHSIZE 0x1000
|
||||
|
||||
#define VCACHE_BOTTOM 0x1c00000
|
||||
#define VCACHE_TOP 0x2000000
|
||||
|
||||
#define BUB_BOTTOM 0x6000000
|
||||
#define BUB_TOP 0x1a000000
|
||||
|
||||
#define IF_STATUS_REG 0
|
||||
#define IF_CMD_REG 0
|
||||
#define IF_TRACK_REG 1
|
||||
#define IF_SECTOR_REG 2
|
||||
#define IF_DATA_REG 3
|
||||
|
||||
#define DMA_IF_CHAN 1
|
||||
#define DMA_IUA_CHAN 2
|
||||
#define DMA_IUB_CHAN 3
|
||||
|
||||
#define DMA_IF 0x45
|
||||
#define DMA_IUA 0x46
|
||||
#define DMA_IUB 0x47
|
||||
#define DMA_C 0x48
|
||||
|
||||
#endif
|
||||
|
|
2356
3B2/3b2_rev3_mmu.c
2356
3B2/3b2_rev3_mmu.c
File diff suppressed because it is too large
Load diff
|
@ -1,358 +1,358 @@
|
|||
/* 3b2_rev3_mmu.h: WE32201 MMU
|
||||
|
||||
Copyright (c) 2020-2022, 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_MMU_H_
|
||||
#define _3B2_REV3_MMU_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define MMU_SRS 4 /* Section RAM array size (words) */
|
||||
#define MMU_SDCS 8 /* SD Cache H/L array size */
|
||||
#define MMU_PDCS 64 /* PD Cache H/L array size */
|
||||
#define MMU_IDNCS 16 /* ID Number Cache array size */
|
||||
|
||||
/* Register address offsets */
|
||||
#define MMU_SDCL 0 /* SDC - Low Bits */
|
||||
#define MMU_SDCH 1 /* SDC - High Bits */
|
||||
#define MMU_PDCL 2 /* PDC - Low Bits */
|
||||
#define MMU_PDCH 3 /* PDC - High Bits */
|
||||
#define MMU_FDCR 4 /* Flush Data Cache Register */
|
||||
#define MMU_SRAMA 6 /* Section RAM A */
|
||||
#define MMU_SRAMB 7 /* Section RAM B */
|
||||
#define MMU_FC 8 /* Fault Code */
|
||||
#define MMU_FA 9 /* Fault Address */
|
||||
#define MMU_CONF 10 /* Configuration */
|
||||
#define MMU_VAR 11 /* Virtual Address Register */
|
||||
#define MMU_IDC 12 /* ID Number Cache */
|
||||
#define MMU_IDNR 13 /* ID Number Register */
|
||||
#define MMU_FIDNR 14 /* Flush ID Number Register */
|
||||
#define MMU_VR 15 /* Version Register */
|
||||
|
||||
#define MMU_REV3_VER 0x23 /* Version byte returned by WE32201 MMU */
|
||||
|
||||
#define MMU_CONF_M (mmu_state.conf & 0x1)
|
||||
#define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1)
|
||||
#define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1)
|
||||
#define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3)
|
||||
#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5)
|
||||
#define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6)
|
||||
|
||||
/* Shift and mask the flag bits for the current CPU mode */
|
||||
#define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3)
|
||||
|
||||
/* Codes set in the MMU Fault register */
|
||||
#define MMU_F_MISS_MEM 1
|
||||
#define MMU_F_RM_UPD 2
|
||||
#define MMU_F_SDTLEN 3
|
||||
#define MMU_F_PW 4
|
||||
#define MMU_F_PDTLEN 5
|
||||
#define MMU_F_INV_SD 6
|
||||
#define MMU_F_SEG_NOT_PRES 7
|
||||
#define MMU_F_PDT_NOT_PRES 9
|
||||
#define MMU_F_PAGE_NOT_PRES 10
|
||||
#define MMU_F_INDIRECT 11
|
||||
#define MMU_F_ACC 13
|
||||
#define MMU_F_SEG_OFFSET 14
|
||||
|
||||
/* Access Request types */
|
||||
#define ACC_MT 0 /* Move Translated */
|
||||
#define ACC_SPW 1 /* Support processor write */
|
||||
#define ACC_SPF 3 /* Support processor fetch */
|
||||
#define ACC_IR 7 /* Interlocked read */
|
||||
#define ACC_AF 8 /* Address fetch */
|
||||
#define ACC_OF 9 /* Operand fetch */
|
||||
#define ACC_W 10 /* Write */
|
||||
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */
|
||||
#define ACC_IF 13 /* Instruction fetch */
|
||||
|
||||
/* Pluck out Virtual Address fields */
|
||||
#define SID(va) (((va) >> 30) & 3)
|
||||
#define SSL(va) (((va) >> 17) & 0x1fff)
|
||||
#define SOT(va) (va & 0x1ffff)
|
||||
|
||||
/* PSL will be either:
|
||||
* - Bits 11-16 (2K pages: MMU_CONF_PS = 0)
|
||||
* - Bits 12-16 (4K pages: MMU_CONF_PS = 1)
|
||||
* - Bits 13-16 (8K pages: MMU_CONF_PS = 2)
|
||||
*/
|
||||
#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS))
|
||||
#define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS]))
|
||||
|
||||
/* POT will be either:
|
||||
* - Bits 0-10 (2K pages: MMU_CONF_PS = 0)
|
||||
* - Bits 0-11 (4K pages: MMU_CONF_PS = 1)
|
||||
* - Bits 0-12 (8K pages: MMU_CONF_PS = 2)
|
||||
*/
|
||||
#define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS))))
|
||||
|
||||
/* Get the maximum length of an SSL from SRAMB */
|
||||
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len)
|
||||
|
||||
/* Pluck out Segment Descriptor fields */
|
||||
#define SD_PRESENT(sd_lo) ((sd_lo) & 1)
|
||||
#define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1)
|
||||
#define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1)
|
||||
#define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1)
|
||||
#define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1)
|
||||
#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f)
|
||||
#define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff)
|
||||
|
||||
#define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u)
|
||||
|
||||
#define SD_P_MASK 0x1
|
||||
#define SD_M_MASK 0x2
|
||||
#define SD_C_MASK 0x4
|
||||
#define SD_CACHE_MASK 0x8
|
||||
#define SD_R_MASK 0x20
|
||||
#define SD_V_MASK 0x40
|
||||
#define SD_MAX_OFF_MASK 0xfc0000
|
||||
#define SD_ACC_MASK 0xff000000u
|
||||
#define SD_ADDR_MASK 0xfffffff8u
|
||||
#define SD_VADDR_MASK 0xfff00000u
|
||||
#define SD_RES_MASK 0xfffc00efu
|
||||
|
||||
#define SDC_VADDR_MASK 0xfff
|
||||
#define SDC_ACC_MASK 0xff000000u
|
||||
#define SDC_MAX_OFF_MASK 0x001f8000
|
||||
#define SDC_G_MASK 0x1
|
||||
#define SDC_C_MASK 0x2
|
||||
#define SDC_CACHE_MASK 0x4
|
||||
#define SDC_M_MASK 0x400000
|
||||
#define SDC_R_MASK 0x800000
|
||||
|
||||
#define PD_P_MASK 0x1
|
||||
#define PD_M_MASK 0x2
|
||||
#define PD_W_MASK 0x10
|
||||
#define PD_R_MASK 0x20
|
||||
#define PD_PADDR_MASK 0xfffff800u
|
||||
|
||||
#define PDC_PADDR_MASK 0x1fffff
|
||||
#define PDC_C_MASK 0x2
|
||||
#define PDC_W_MASK 0x200000
|
||||
#define PDC_M_MASK 0x400000
|
||||
#define PDC_R_MASK 0x800000
|
||||
#define PDC_G_MASK 0x40000000
|
||||
#define PDC_U_MASK 0x80000000u
|
||||
|
||||
#define MAX_INDIRECTS 3
|
||||
|
||||
#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS]))
|
||||
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
|
||||
|
||||
#define SDC_IDX(va) ((uint8)((va) >> 17) & 7)
|
||||
|
||||
/* Convert from sd to sd cache entry */
|
||||
#define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \
|
||||
((lo) & SD_C_MASK) >> 1 | \
|
||||
((lo) & SD_CACHE_MASK) >> 1 | \
|
||||
(SDC_G_MASK))
|
||||
#define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \
|
||||
((lo) & SD_MAX_OFF_MASK) >> 3 | \
|
||||
((lo) & SD_R_MASK) << 18 | \
|
||||
((lo) & SD_M_MASK) << 21 | \
|
||||
((va) & SD_VADDR_MASK) >> 20)
|
||||
|
||||
/* Convert from sd cache entry to sd */
|
||||
#define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK)
|
||||
#define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \
|
||||
((lo) & SDC_MAX_OFF_MASK) << 3 | \
|
||||
((lo) & SDC_R_MASK) >> 18 | \
|
||||
((lo) & SDC_M_MASK) >> 21 | \
|
||||
((hi) & SDC_C_MASK) << 1 | \
|
||||
((hi) & SDC_CACHE_MASK) << 1 | \
|
||||
SD_V_MASK | SD_P_MASK)
|
||||
|
||||
/* Convert from pd cache entry to pd */
|
||||
#define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \
|
||||
(((pdcl) & PDC_W_MASK) >> 17) | \
|
||||
(((pdcl) & PDC_M_MASK) >> 21) | \
|
||||
(((pdcl) & PDC_R_MASK) >> 18) | \
|
||||
PD_P_MASK)
|
||||
|
||||
/* Convert from pd to pd cache entry (low word) */
|
||||
#define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \
|
||||
(((pd) & PD_W_MASK) << 17) | \
|
||||
(((pd) & PD_M_MASK) << 21) | \
|
||||
(((pd) & PD_R_MASK) << 18) | \
|
||||
((sd_lo) & SD_ACC_MASK))
|
||||
|
||||
/* Convert from va to pd cache entry (high word / tag) */
|
||||
#define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \
|
||||
(mmu_state.cidnr[SID(va)] << 26) | \
|
||||
((va & 0xfffff800u) >> 6) | \
|
||||
((sd_lo & SD_CACHE_MASK) >> 1) | \
|
||||
((sd_lo & SD_C_MASK) >> 1))
|
||||
|
||||
/* Maximum offset (in bytes) of a paged segment */
|
||||
#define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1)
|
||||
|
||||
#define IDNC_TAG(val) ((val) & 0xfffffff8)
|
||||
#define IDNC_U(val) ((val) & 0x1)
|
||||
|
||||
/* Fault codes */
|
||||
#define MMU_FAULT(f) { \
|
||||
if (fc) { \
|
||||
mmu_state.fcode = ((((uint32)r_acc)<<7) | \
|
||||
(((uint32)(CPU_CM))<<5) | \
|
||||
(f & 0x1f)); \
|
||||
mmu_state.faddr = va; \
|
||||
} \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32 addr;
|
||||
uint32 len;
|
||||
} mmu_sec;
|
||||
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all
|
||||
* copied from the SD in main memory.
|
||||
* - "VAddr" holds bits 20-31 of the virtual address
|
||||
* - "Address" holds a pointer (word-aligned, so the top 30 bits) to
|
||||
* a page descriptor table in paged mode, or a segment in
|
||||
* contiguous segment mode.
|
||||
* - "Max Offset" holds the number of pages minus one in the
|
||||
* segment. Depending on current page size, various bits of this
|
||||
* field will be ignored:
|
||||
* o Bits 20-15 are used for 2K pages
|
||||
* o Bits 20-16 are used for 4K pages
|
||||
* 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 |
|
||||
* +-------+---+---+---+------------+------+--------------------------+
|
||||
*
|
||||
* High Word (bits 32-63)
|
||||
* ----------------------
|
||||
*
|
||||
* 31 3 2 1 0
|
||||
* +------------------------------------------------------+---+---+---+
|
||||
* | Address | $ | C | G |
|
||||
* +------------------------------------------------------+---+---+---+
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Depending on the current page size and access mode, various bits of
|
||||
* "VAddr" are ignored.
|
||||
*
|
||||
* o Multi-context mode, all ops except single-entry flush:
|
||||
* VAddr bits 29-11 are used.
|
||||
* o Multi-context mode, single-entry flush:
|
||||
* VAddr bits 31-11 are used.
|
||||
* o Single-context mode, all ops:
|
||||
* Vaddr bits 31-11 are used.
|
||||
* o In ALL CASES:
|
||||
* + 2KB Page Size: Bits 11-12 are used.
|
||||
* + 4KB Page Size: Bit 11 ignored, 12 used.
|
||||
* + 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 |
|
||||
* +-------+---+---+---+----------------------------------------------+
|
||||
*
|
||||
*
|
||||
* High Word (bits 32-63)
|
||||
* ----------------------
|
||||
*
|
||||
* 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 */
|
||||
|
||||
t_bool flush_u; /* If true, flush all but last cached entry */
|
||||
uint32 last_cached; /* The index of the last cached PDC entry */
|
||||
|
||||
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
|
||||
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
|
||||
|
||||
uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */
|
||||
uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */
|
||||
|
||||
uint32 sra[4]; /* Section RAM A */
|
||||
uint32 srb[4]; /* Section RAM B */
|
||||
|
||||
uint32 cidnr[4]; /* Current ID Number Registers */
|
||||
uint32 idnc[16]; /* ID Number Cache */
|
||||
|
||||
mmu_sec sec[4]; /* Section descriptors decoded from
|
||||
Section RAM A and B */
|
||||
|
||||
uint32 fcode; /* Fault Code Register */
|
||||
uint32 faddr; /* Fault Address Register */
|
||||
uint32 conf; /* Configuration Register */
|
||||
uint32 var; /* Virtual Address Register */
|
||||
|
||||
} MMU_STATE;
|
||||
|
||||
t_stat mmu_init(DEVICE *dptr);
|
||||
uint32 mmu_read(uint32 pa, size_t size);
|
||||
void mmu_write(uint32 pa, uint32 val, size_t size);
|
||||
CONST char *mmu_description(DEVICE *dptr);
|
||||
|
||||
/* Virtual memory translation */
|
||||
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
|
||||
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
|
||||
t_bool fc, uint32 *pa);
|
||||
|
||||
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
|
||||
void mmu_enable();
|
||||
void mmu_disable();
|
||||
|
||||
t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
|
||||
#endif /* _3B2_REV3_MMU_H_ */
|
||||
/* 3b2_rev3_mmu.h: WE32201 MMU
|
||||
|
||||
Copyright (c) 2020-2022, 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_MMU_H_
|
||||
#define _3B2_REV3_MMU_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#define MMU_SRS 4 /* Section RAM array size (words) */
|
||||
#define MMU_SDCS 8 /* SD Cache H/L array size */
|
||||
#define MMU_PDCS 64 /* PD Cache H/L array size */
|
||||
#define MMU_IDNCS 16 /* ID Number Cache array size */
|
||||
|
||||
/* Register address offsets */
|
||||
#define MMU_SDCL 0 /* SDC - Low Bits */
|
||||
#define MMU_SDCH 1 /* SDC - High Bits */
|
||||
#define MMU_PDCL 2 /* PDC - Low Bits */
|
||||
#define MMU_PDCH 3 /* PDC - High Bits */
|
||||
#define MMU_FDCR 4 /* Flush Data Cache Register */
|
||||
#define MMU_SRAMA 6 /* Section RAM A */
|
||||
#define MMU_SRAMB 7 /* Section RAM B */
|
||||
#define MMU_FC 8 /* Fault Code */
|
||||
#define MMU_FA 9 /* Fault Address */
|
||||
#define MMU_CONF 10 /* Configuration */
|
||||
#define MMU_VAR 11 /* Virtual Address Register */
|
||||
#define MMU_IDC 12 /* ID Number Cache */
|
||||
#define MMU_IDNR 13 /* ID Number Register */
|
||||
#define MMU_FIDNR 14 /* Flush ID Number Register */
|
||||
#define MMU_VR 15 /* Version Register */
|
||||
|
||||
#define MMU_REV3_VER 0x23 /* Version byte returned by WE32201 MMU */
|
||||
|
||||
#define MMU_CONF_M (mmu_state.conf & 0x1)
|
||||
#define MMU_CONF_R ((mmu_state.conf & 0x2) >> 1)
|
||||
#define MMU_CONF_C ((mmu_state.conf & 0x4) >> 1)
|
||||
#define MMU_CONF_PS ((mmu_state.conf & 0x18) >> 3)
|
||||
#define MMU_CONF_MCE ((mmu_state.conf & 0x20) >> 5)
|
||||
#define MMU_CONF_DCE ((mmu_state.conf & 0x40) >> 6)
|
||||
|
||||
/* Shift and mask the flag bits for the current CPU mode */
|
||||
#define MMU_PERM(f) ((f >> ((3 - (CPU_CM)) * 2)) & 3)
|
||||
|
||||
/* Codes set in the MMU Fault register */
|
||||
#define MMU_F_MISS_MEM 1
|
||||
#define MMU_F_RM_UPD 2
|
||||
#define MMU_F_SDTLEN 3
|
||||
#define MMU_F_PW 4
|
||||
#define MMU_F_PDTLEN 5
|
||||
#define MMU_F_INV_SD 6
|
||||
#define MMU_F_SEG_NOT_PRES 7
|
||||
#define MMU_F_PDT_NOT_PRES 9
|
||||
#define MMU_F_PAGE_NOT_PRES 10
|
||||
#define MMU_F_INDIRECT 11
|
||||
#define MMU_F_ACC 13
|
||||
#define MMU_F_SEG_OFFSET 14
|
||||
|
||||
/* Access Request types */
|
||||
#define ACC_MT 0 /* Move Translated */
|
||||
#define ACC_SPW 1 /* Support processor write */
|
||||
#define ACC_SPF 3 /* Support processor fetch */
|
||||
#define ACC_IR 7 /* Interlocked read */
|
||||
#define ACC_AF 8 /* Address fetch */
|
||||
#define ACC_OF 9 /* Operand fetch */
|
||||
#define ACC_W 10 /* Write */
|
||||
#define ACC_IFAD 12 /* Instruction fetch after discontinuity */
|
||||
#define ACC_IF 13 /* Instruction fetch */
|
||||
|
||||
/* Pluck out Virtual Address fields */
|
||||
#define SID(va) (((va) >> 30) & 3)
|
||||
#define SSL(va) (((va) >> 17) & 0x1fff)
|
||||
#define SOT(va) (va & 0x1ffff)
|
||||
|
||||
/* PSL will be either:
|
||||
* - Bits 11-16 (2K pages: MMU_CONF_PS = 0)
|
||||
* - Bits 12-16 (4K pages: MMU_CONF_PS = 1)
|
||||
* - Bits 13-16 (8K pages: MMU_CONF_PS = 2)
|
||||
*/
|
||||
#define PSL(va) (((va) >> (11 + MMU_CONF_PS)) & (0x3f >> MMU_CONF_PS))
|
||||
#define PSL_C(va) (((va) & pd_psl_masks[MMU_CONF_PS]))
|
||||
|
||||
/* POT will be either:
|
||||
* - Bits 0-10 (2K pages: MMU_CONF_PS = 0)
|
||||
* - Bits 0-11 (4K pages: MMU_CONF_PS = 1)
|
||||
* - Bits 0-12 (8K pages: MMU_CONF_PS = 2)
|
||||
*/
|
||||
#define POT(va) ((va) & (0x1fff >> (2 - (MMU_CONF_PS))))
|
||||
|
||||
/* Get the maximum length of an SSL from SRAMB */
|
||||
#define SRAMB_LEN(va) (mmu_state.sec[SID(va)].len)
|
||||
|
||||
/* Pluck out Segment Descriptor fields */
|
||||
#define SD_PRESENT(sd_lo) ((sd_lo) & 1)
|
||||
#define SD_MODIFIED(sd_lo) (((sd_lo) >> 1) & 1)
|
||||
#define SD_CONTIG(sd_lo) (((sd_lo) >> 2) & 1)
|
||||
#define SD_VALID(sd_lo) (((sd_lo) >> 6) & 1)
|
||||
#define SD_INDIRECT(sd_lo) (((sd_lo) >> 7) & 1)
|
||||
#define SD_MAX_OFF(sd_lo) (((sd_lo) >> 18) & 0x3f)
|
||||
#define SD_ACC(sd_lo) (((sd_lo) >> 24) & 0xff)
|
||||
|
||||
#define SD_SEG_ADDR(sd_hi) ((sd_hi) & 0xfffffff8u)
|
||||
|
||||
#define SD_P_MASK 0x1
|
||||
#define SD_M_MASK 0x2
|
||||
#define SD_C_MASK 0x4
|
||||
#define SD_CACHE_MASK 0x8
|
||||
#define SD_R_MASK 0x20
|
||||
#define SD_V_MASK 0x40
|
||||
#define SD_MAX_OFF_MASK 0xfc0000
|
||||
#define SD_ACC_MASK 0xff000000u
|
||||
#define SD_ADDR_MASK 0xfffffff8u
|
||||
#define SD_VADDR_MASK 0xfff00000u
|
||||
#define SD_RES_MASK 0xfffc00efu
|
||||
|
||||
#define SDC_VADDR_MASK 0xfff
|
||||
#define SDC_ACC_MASK 0xff000000u
|
||||
#define SDC_MAX_OFF_MASK 0x001f8000
|
||||
#define SDC_G_MASK 0x1
|
||||
#define SDC_C_MASK 0x2
|
||||
#define SDC_CACHE_MASK 0x4
|
||||
#define SDC_M_MASK 0x400000
|
||||
#define SDC_R_MASK 0x800000
|
||||
|
||||
#define PD_P_MASK 0x1
|
||||
#define PD_M_MASK 0x2
|
||||
#define PD_W_MASK 0x10
|
||||
#define PD_R_MASK 0x20
|
||||
#define PD_PADDR_MASK 0xfffff800u
|
||||
|
||||
#define PDC_PADDR_MASK 0x1fffff
|
||||
#define PDC_C_MASK 0x2
|
||||
#define PDC_W_MASK 0x200000
|
||||
#define PDC_M_MASK 0x400000
|
||||
#define PDC_R_MASK 0x800000
|
||||
#define PDC_G_MASK 0x40000000
|
||||
#define PDC_U_MASK 0x80000000u
|
||||
|
||||
#define MAX_INDIRECTS 3
|
||||
|
||||
#define PD_ADDR(pd) (pd & (pd_addr_masks[MMU_CONF_PS]))
|
||||
#define SD_ADDR(va) (mmu_state.sec[SID(va)].addr + (SSL(va) * 8))
|
||||
|
||||
#define SDC_IDX(va) ((uint8)((va) >> 17) & 7)
|
||||
|
||||
/* Convert from sd to sd cache entry */
|
||||
#define SD_TO_SDCH(hi,lo) (((hi) & SD_ADDR_MASK) | \
|
||||
((lo) & SD_C_MASK) >> 1 | \
|
||||
((lo) & SD_CACHE_MASK) >> 1 | \
|
||||
(SDC_G_MASK))
|
||||
#define SD_TO_SDCL(lo,va) (((lo) & SD_ACC_MASK) | \
|
||||
((lo) & SD_MAX_OFF_MASK) >> 3 | \
|
||||
((lo) & SD_R_MASK) << 18 | \
|
||||
((lo) & SD_M_MASK) << 21 | \
|
||||
((va) & SD_VADDR_MASK) >> 20)
|
||||
|
||||
/* Convert from sd cache entry to sd */
|
||||
#define SDCE_TO_SDH(hi) ((hi) & SD_ADDR_MASK)
|
||||
#define SDCE_TO_SDL(hi,lo) (((lo) & SDC_ACC_MASK) | \
|
||||
((lo) & SDC_MAX_OFF_MASK) << 3 | \
|
||||
((lo) & SDC_R_MASK) >> 18 | \
|
||||
((lo) & SDC_M_MASK) >> 21 | \
|
||||
((hi) & SDC_C_MASK) << 1 | \
|
||||
((hi) & SDC_CACHE_MASK) << 1 | \
|
||||
SD_V_MASK | SD_P_MASK)
|
||||
|
||||
/* Convert from pd cache entry to pd */
|
||||
#define PDCE_TO_PD(pdcl) ((((pdcl) & PDC_PADDR_MASK) << 11) | \
|
||||
(((pdcl) & PDC_W_MASK) >> 17) | \
|
||||
(((pdcl) & PDC_M_MASK) >> 21) | \
|
||||
(((pdcl) & PDC_R_MASK) >> 18) | \
|
||||
PD_P_MASK)
|
||||
|
||||
/* Convert from pd to pd cache entry (low word) */
|
||||
#define PD_TO_PDCL(pd, sd_lo) ((((pd) & PD_PADDR_MASK) >> 11) | \
|
||||
(((pd) & PD_W_MASK) << 17) | \
|
||||
(((pd) & PD_M_MASK) << 21) | \
|
||||
(((pd) & PD_R_MASK) << 18) | \
|
||||
((sd_lo) & SD_ACC_MASK))
|
||||
|
||||
/* Convert from va to pd cache entry (high word / tag) */
|
||||
#define VA_TO_PDCH(va, sd_lo) ((1 << 30) | \
|
||||
(mmu_state.cidnr[SID(va)] << 26) | \
|
||||
((va & 0xfffff800u) >> 6) | \
|
||||
((sd_lo & SD_CACHE_MASK) >> 1) | \
|
||||
((sd_lo & SD_C_MASK) >> 1))
|
||||
|
||||
/* Maximum offset (in bytes) of a paged segment */
|
||||
#define MAX_SEG_OFF(w) (((SD_MAX_OFF(w) + 1) * ((MMU_CONF_PS + 1) * 2048)) - 1)
|
||||
|
||||
#define IDNC_TAG(val) ((val) & 0xfffffff8)
|
||||
#define IDNC_U(val) ((val) & 0x1)
|
||||
|
||||
/* Fault codes */
|
||||
#define MMU_FAULT(f) { \
|
||||
if (fc) { \
|
||||
mmu_state.fcode = ((((uint32)r_acc)<<7) | \
|
||||
(((uint32)(CPU_CM))<<5) | \
|
||||
(f & 0x1f)); \
|
||||
mmu_state.faddr = va; \
|
||||
} \
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
uint32 addr;
|
||||
uint32 len;
|
||||
} mmu_sec;
|
||||
|
||||
|
||||
/*
|
||||
* 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:
|
||||
*
|
||||
* - "Acc", "R", "M", "Max Offset", "Address", "$", and "C" are all
|
||||
* copied from the SD in main memory.
|
||||
* - "VAddr" holds bits 20-31 of the virtual address
|
||||
* - "Address" holds a pointer (word-aligned, so the top 30 bits) to
|
||||
* a page descriptor table in paged mode, or a segment in
|
||||
* contiguous segment mode.
|
||||
* - "Max Offset" holds the number of pages minus one in the
|
||||
* segment. Depending on current page size, various bits of this
|
||||
* field will be ignored:
|
||||
* o Bits 20-15 are used for 2K pages
|
||||
* o Bits 20-16 are used for 4K pages
|
||||
* 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 |
|
||||
* +-------+---+---+---+------------+------+--------------------------+
|
||||
*
|
||||
* High Word (bits 32-63)
|
||||
* ----------------------
|
||||
*
|
||||
* 31 3 2 1 0
|
||||
* +------------------------------------------------------+---+---+---+
|
||||
* | Address | $ | C | G |
|
||||
* +------------------------------------------------------+---+---+---+
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Depending on the current page size and access mode, various bits of
|
||||
* "VAddr" are ignored.
|
||||
*
|
||||
* o Multi-context mode, all ops except single-entry flush:
|
||||
* VAddr bits 29-11 are used.
|
||||
* o Multi-context mode, single-entry flush:
|
||||
* VAddr bits 31-11 are used.
|
||||
* o Single-context mode, all ops:
|
||||
* Vaddr bits 31-11 are used.
|
||||
* o In ALL CASES:
|
||||
* + 2KB Page Size: Bits 11-12 are used.
|
||||
* + 4KB Page Size: Bit 11 ignored, 12 used.
|
||||
* + 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 |
|
||||
* +-------+---+---+---+----------------------------------------------+
|
||||
*
|
||||
*
|
||||
* High Word (bits 32-63)
|
||||
* ----------------------
|
||||
*
|
||||
* 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 */
|
||||
|
||||
t_bool flush_u; /* If true, flush all but last cached entry */
|
||||
uint32 last_cached; /* The index of the last cached PDC entry */
|
||||
|
||||
uint32 sdcl[MMU_SDCS]; /* SDC low bits (0-31) */
|
||||
uint32 sdch[MMU_SDCS]; /* SDC high bits (32-63) */
|
||||
|
||||
uint32 pdcl[MMU_PDCS]; /* PDC low bits (0-31) */
|
||||
uint32 pdch[MMU_PDCS]; /* PDC high bits (32-63) */
|
||||
|
||||
uint32 sra[4]; /* Section RAM A */
|
||||
uint32 srb[4]; /* Section RAM B */
|
||||
|
||||
uint32 cidnr[4]; /* Current ID Number Registers */
|
||||
uint32 idnc[16]; /* ID Number Cache */
|
||||
|
||||
mmu_sec sec[4]; /* Section descriptors decoded from
|
||||
Section RAM A and B */
|
||||
|
||||
uint32 fcode; /* Fault Code Register */
|
||||
uint32 faddr; /* Fault Address Register */
|
||||
uint32 conf; /* Configuration Register */
|
||||
uint32 var; /* Virtual Address Register */
|
||||
|
||||
} MMU_STATE;
|
||||
|
||||
t_stat mmu_init(DEVICE *dptr);
|
||||
uint32 mmu_read(uint32 pa, size_t size);
|
||||
void mmu_write(uint32 pa, uint32 val, size_t size);
|
||||
CONST char *mmu_description(DEVICE *dptr);
|
||||
|
||||
/* Virtual memory translation */
|
||||
uint32 mmu_xlate_addr(uint32 va, uint8 r_acc);
|
||||
t_stat mmu_decode_vaddr(uint32 vaddr, uint8 r_acc,
|
||||
t_bool fc, uint32 *pa);
|
||||
|
||||
t_stat mmu_decode_va(uint32 va, uint8 r_acc, t_bool fc, uint32 *pa);
|
||||
void mmu_enable();
|
||||
void mmu_disable();
|
||||
|
||||
t_stat mmu_show_sdt(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat mmu_show_sdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
t_stat mmu_show_pdc(FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
|
||||
#endif /* _3B2_REV3_MMU_H_ */
|
||||
|
|
|
@ -1,80 +1,80 @@
|
|||
/* 3b2_rev3_sys.c: Version 3 (3B2/700) System Definition
|
||||
|
||||
Copyright (c) 2020-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_iu.h"
|
||||
#include "3b2_mau.h"
|
||||
#include "3b2_ni.h"
|
||||
#include "3b2_ports.h"
|
||||
#include "3b2_scsi.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_timer.h"
|
||||
|
||||
char sim_name[] = "AT&T 3B2/700";
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&csr_dev,
|
||||
&flt_dev,
|
||||
&mmu_dev,
|
||||
&mau_dev,
|
||||
&timer_dev,
|
||||
&tod_dev,
|
||||
&nvram_dev,
|
||||
&tti_dev,
|
||||
&tto_dev,
|
||||
&contty_dev,
|
||||
&iu_timer_dev,
|
||||
&dmac_dev,
|
||||
&if_dev,
|
||||
&ha_dev,
|
||||
&ports_dev,
|
||||
&ni_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
void full_reset()
|
||||
{
|
||||
cpu_reset(&cpu_dev);
|
||||
mau_reset(&mau_dev);
|
||||
tti_reset(&tti_dev);
|
||||
contty_reset(&contty_dev);
|
||||
iu_timer_reset(&iu_timer_dev);
|
||||
timer_reset(&timer_dev);
|
||||
if_reset(&if_dev);
|
||||
ha_reset(&ha_dev);
|
||||
csr_reset(&csr_dev);
|
||||
ports_reset(&ports_dev);
|
||||
ni_reset(&ni_dev);
|
||||
}
|
||||
/* 3b2_rev3_sys.c: Version 3 (3B2/700) System Definition
|
||||
|
||||
Copyright (c) 2020-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_csr.h"
|
||||
#include "3b2_if.h"
|
||||
#include "3b2_iu.h"
|
||||
#include "3b2_mau.h"
|
||||
#include "3b2_ni.h"
|
||||
#include "3b2_ports.h"
|
||||
#include "3b2_scsi.h"
|
||||
#include "3b2_stddev.h"
|
||||
#include "3b2_timer.h"
|
||||
|
||||
char sim_name[] = "AT&T 3B2/700";
|
||||
|
||||
DEVICE *sim_devices[] = {
|
||||
&cpu_dev,
|
||||
&csr_dev,
|
||||
&flt_dev,
|
||||
&mmu_dev,
|
||||
&mau_dev,
|
||||
&timer_dev,
|
||||
&tod_dev,
|
||||
&nvram_dev,
|
||||
&tti_dev,
|
||||
&tto_dev,
|
||||
&contty_dev,
|
||||
&iu_timer_dev,
|
||||
&dmac_dev,
|
||||
&if_dev,
|
||||
&ha_dev,
|
||||
&ports_dev,
|
||||
&ni_dev,
|
||||
NULL
|
||||
};
|
||||
|
||||
void full_reset()
|
||||
{
|
||||
cpu_reset(&cpu_dev);
|
||||
mau_reset(&mau_dev);
|
||||
tti_reset(&tti_dev);
|
||||
contty_reset(&contty_dev);
|
||||
iu_timer_reset(&iu_timer_dev);
|
||||
timer_reset(&timer_dev);
|
||||
if_reset(&if_dev);
|
||||
ha_reset(&ha_dev);
|
||||
csr_reset(&csr_dev);
|
||||
ports_reset(&ports_dev);
|
||||
ni_reset(&ni_dev);
|
||||
}
|
||||
|
|
2904
3B2/3b2_scsi.c
2904
3B2/3b2_scsi.c
File diff suppressed because it is too large
Load diff
576
3B2/3b2_scsi.h
576
3B2/3b2_scsi.h
|
@ -1,288 +1,288 @@
|
|||
/* 3b2_scsi.h: CM195W SCSI Controller CIO Card
|
||||
|
||||
Copyright (c) 2020-2022, 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_SCSI_H_
|
||||
#define _3B2_SCSI_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
/* CIO Opcodes */
|
||||
#define HA_BOOT 0x0a
|
||||
#define HA_READ_BLK 0x0b
|
||||
#define HA_WRITE_BLK 0x0c
|
||||
#define HA_CNTRL 0x20
|
||||
#define HA_VERS 0x40
|
||||
#define HA_DL_EEDT 0x42
|
||||
#define HA_UL_EEDT 0x43
|
||||
#define HA_EDSD 0x44
|
||||
#define HA_RESET 0x45
|
||||
|
||||
#define HA_TESTRDY 0x00
|
||||
#define HA_FORMAT 0x04
|
||||
#define HA_WRITE 0x0a
|
||||
#define HA_INQUIRY 0x12
|
||||
#define HA_MODESEL 0x15
|
||||
#define HA_MODESNS 0x1a
|
||||
#define HA_RDCPCTY 0x25
|
||||
#define HA_READ 0x08
|
||||
#define HA_READEXT 0x28
|
||||
#define HA_WRTEXT 0x2a
|
||||
#define HA_VERIFY 0x2f
|
||||
|
||||
#define HA_PDLS_OFF 0x28
|
||||
|
||||
/* CIO Status */
|
||||
#define CIO_TIMEOUT 0x65
|
||||
|
||||
#define HA_BOOT_ADDR 0x2004000
|
||||
#define HA_PDINFO_ADDR 0x2004400
|
||||
|
||||
#define HA_ID 0x0100
|
||||
#define HA_IPL 12
|
||||
|
||||
#define HA_GOOD 0x00
|
||||
#define HA_CKCON 0x02
|
||||
|
||||
#define HA_DSD_DISK 0x100
|
||||
#define HA_DSD_TAPE 0x101
|
||||
|
||||
#define HA_VERSION 0x01
|
||||
|
||||
#define SCQRESIZE 24
|
||||
#define RAPP_LEN (SCQRESIZE - 8)
|
||||
#define SCQCESIZE 16
|
||||
#define CAPP_LEN (SCQCESIZE - 8)
|
||||
|
||||
#define FC_TC(x) (((x) >> 3) & 7)
|
||||
#define FC_LU(x) ((x) & 7)
|
||||
|
||||
#define HA_EDT_LEN 1024
|
||||
|
||||
#define HA_BLKSZ 512
|
||||
|
||||
#define HA_MAX_CMD 12
|
||||
#define INQUIRY_MAX 36
|
||||
|
||||
#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 4
|
||||
|
||||
/* Hardware Notes
|
||||
* ==============
|
||||
*
|
||||
* Disk Drives
|
||||
* -----------
|
||||
*
|
||||
* There are two emulated SCSI disk drives available.
|
||||
*
|
||||
* 1. 155 MB CDC Wren III (CDC 94161-9)
|
||||
* 2. 327 MB CDC Wren IV (CDC 94171-9)
|
||||
*
|
||||
* The CDC 94161-9 was also OEMed as the "AT&T KS23483,L3"
|
||||
* The CDC 94171-9 was also OEMed as the "AT&T KS23483,L25"
|
||||
*
|
||||
*
|
||||
* Tape Drive
|
||||
* ----------
|
||||
*
|
||||
* Wangtek 5125EN (AT&T Part number KS23417,L2)
|
||||
*
|
||||
* DC600A cartridge tape at 120MB (QIC-120 format)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Other SCSI hard disk types
|
||||
* ---------------------------
|
||||
*
|
||||
* These geometries are supported natively and automatically
|
||||
* by System V Release 3.2.3 UNIX.
|
||||
*
|
||||
* 1. CDC 94161-9 155 MB/148 MiB 512 B/s, 35 s/t, 9 head, 965 cyl
|
||||
* 2. AT&T KS23483 327 MB/312 MiB 512 B/s, 46 s/t, 9 head, 1547 cyl
|
||||
* (a.k.a CDC 94171-9)
|
||||
*
|
||||
* Also supported was a SCSI-to-ESDI bridge controller that used the
|
||||
* Emulex MD23/S2 SCSI-to-ESDI bridge. It allowed up to four ESDI
|
||||
* drives to be mapped as LUNs 0-3.
|
||||
*
|
||||
*/
|
||||
|
||||
/* AT&T 155 MB Hard Disk (35 sec/t, 9 hd, 964 cyl) */
|
||||
#define SD155_DTYPE 0
|
||||
#define SD155_PQUAL 0x00
|
||||
#define SD155_SCSI 1
|
||||
#define SD155_BLK 512
|
||||
#define SD155_LBN 303660
|
||||
#define SD155_MANU "AT&T"
|
||||
#define SD155_DESC "KS23483"
|
||||
#define SD155_REV "0000"
|
||||
|
||||
/* AT&T 300 MB Hard Disk (43 sec/t, 9 hd, 1514 cyl) */
|
||||
#define SD300_DTYPE 1
|
||||
#define SD300_PQUAL 0x00
|
||||
#define SD300_SCSI 1
|
||||
#define SD300_BLK 512
|
||||
#define SD300_LBN 585937
|
||||
#define SD300_MANU "AT&T"
|
||||
#define SD300_DESC "KS23483"
|
||||
#define SD300_REV "0000"
|
||||
|
||||
/* AT&T 327 MB Hard Disk (46 sec/t, 9 hd, 1547 cyl) */
|
||||
#define SD327_DTYPE 2
|
||||
#define SD327_PQUAL 0x00
|
||||
#define SD327_SCSI 1
|
||||
#define SD327_BLK 512
|
||||
#define SD327_LBN 640458
|
||||
#define SD327_MANU "AT&T"
|
||||
#define SD327_DESC "KS23483"
|
||||
#define SD327_REV "0000"
|
||||
|
||||
/* AT&T 630 MB Hard Disk (56 sec/t, 16 hd, 1447 cyl) */
|
||||
#define SD630_DTYPE 3
|
||||
#define SD630_PQUAL 0x00
|
||||
#define SD630_SCSI 1
|
||||
#define SD630_BLK 512
|
||||
#define SD630_LBN 1296512
|
||||
#define SD630_MANU "AT&T"
|
||||
#define SD630_DESC "KS23483"
|
||||
#define SD630_REV "0000"
|
||||
|
||||
/* Wangtek 120MB cartridge tape */
|
||||
#define ST120_DTYPE 4
|
||||
#define ST120_PQUAL 0x00
|
||||
#define ST120_SCSI 1
|
||||
#define ST120_BLK 512
|
||||
#define ST120_LBN 1
|
||||
#define ST120_MANU "WANGTEK"
|
||||
#define ST120_DESC "KS23465"
|
||||
#define ST120_REV "CX17"
|
||||
|
||||
#define UNIT_V_DTYPE (SCSI_V_UF + 0)
|
||||
#define UNIT_M_DTYPE 0x1f
|
||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||
|
||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||
#define HA_DISK(d) \
|
||||
{ SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \
|
||||
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
|
||||
|
||||
#define HA_TAPE(d) \
|
||||
{ SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \
|
||||
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
|
||||
|
||||
#define HA_SIZE(d) d##_LBN
|
||||
|
||||
#define HA_JOB_QUICK 0
|
||||
#define HA_JOB_EXPRESS 1
|
||||
#define HA_JOB_FULL 2
|
||||
|
||||
typedef uint8 ha_jobtype;
|
||||
|
||||
typedef struct {
|
||||
uint32 addr;
|
||||
uint32 len;
|
||||
} haddr;
|
||||
|
||||
/*
|
||||
* SCSI Command Request
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 op; /* Destructured from the cmd byte array */
|
||||
uint8 tc;
|
||||
uint8 lu;
|
||||
uint32 timeout;
|
||||
|
||||
uint8 dlen;
|
||||
haddr daddr[48]; /* Support up to 48 transfer addresses */
|
||||
|
||||
uint32 dma_lst;
|
||||
uint16 cmd_len;
|
||||
uint8 cmd[HA_MAX_CMD];
|
||||
} ha_req;
|
||||
|
||||
/*
|
||||
* SCSI Command Response
|
||||
*/
|
||||
typedef struct {
|
||||
ha_jobtype type; /* Job type */
|
||||
uint8 status; /* Result Status */
|
||||
uint8 op; /* Command Opcode */
|
||||
uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */
|
||||
uint8 ssb; /* SCSI Status Byte */
|
||||
uint32 addr; /* Response address */
|
||||
uint32 len; /* Response length */
|
||||
} ha_resp;
|
||||
|
||||
#define PUMP_NONE 0
|
||||
#define PUMP_SYSGEN 1
|
||||
#define PUMP_COMPLETE 2
|
||||
|
||||
/*
|
||||
* SCSI Target state
|
||||
*/
|
||||
typedef struct {
|
||||
t_bool pending; /* Service pending */
|
||||
ha_req req; /* SCSI job request */
|
||||
ha_resp rep; /* SCSI job reply */
|
||||
} ha_ts;
|
||||
|
||||
/*
|
||||
* 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_ */
|
||||
/* 3b2_scsi.h: CM195W SCSI Controller CIO Card
|
||||
|
||||
Copyright (c) 2020-2022, 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_SCSI_H_
|
||||
#define _3B2_SCSI_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
/* CIO Opcodes */
|
||||
#define HA_BOOT 0x0a
|
||||
#define HA_READ_BLK 0x0b
|
||||
#define HA_WRITE_BLK 0x0c
|
||||
#define HA_CNTRL 0x20
|
||||
#define HA_VERS 0x40
|
||||
#define HA_DL_EEDT 0x42
|
||||
#define HA_UL_EEDT 0x43
|
||||
#define HA_EDSD 0x44
|
||||
#define HA_RESET 0x45
|
||||
|
||||
#define HA_TESTRDY 0x00
|
||||
#define HA_FORMAT 0x04
|
||||
#define HA_WRITE 0x0a
|
||||
#define HA_INQUIRY 0x12
|
||||
#define HA_MODESEL 0x15
|
||||
#define HA_MODESNS 0x1a
|
||||
#define HA_RDCPCTY 0x25
|
||||
#define HA_READ 0x08
|
||||
#define HA_READEXT 0x28
|
||||
#define HA_WRTEXT 0x2a
|
||||
#define HA_VERIFY 0x2f
|
||||
|
||||
#define HA_PDLS_OFF 0x28
|
||||
|
||||
/* CIO Status */
|
||||
#define CIO_TIMEOUT 0x65
|
||||
|
||||
#define HA_BOOT_ADDR 0x2004000
|
||||
#define HA_PDINFO_ADDR 0x2004400
|
||||
|
||||
#define HA_ID 0x0100
|
||||
#define HA_IPL 12
|
||||
|
||||
#define HA_GOOD 0x00
|
||||
#define HA_CKCON 0x02
|
||||
|
||||
#define HA_DSD_DISK 0x100
|
||||
#define HA_DSD_TAPE 0x101
|
||||
|
||||
#define HA_VERSION 0x01
|
||||
|
||||
#define SCQRESIZE 24
|
||||
#define RAPP_LEN (SCQRESIZE - 8)
|
||||
#define SCQCESIZE 16
|
||||
#define CAPP_LEN (SCQCESIZE - 8)
|
||||
|
||||
#define FC_TC(x) (((x) >> 3) & 7)
|
||||
#define FC_LU(x) ((x) & 7)
|
||||
|
||||
#define HA_EDT_LEN 1024
|
||||
|
||||
#define HA_BLKSZ 512
|
||||
|
||||
#define HA_MAX_CMD 12
|
||||
#define INQUIRY_MAX 36
|
||||
|
||||
#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 4
|
||||
|
||||
/* Hardware Notes
|
||||
* ==============
|
||||
*
|
||||
* Disk Drives
|
||||
* -----------
|
||||
*
|
||||
* There are two emulated SCSI disk drives available.
|
||||
*
|
||||
* 1. 155 MB CDC Wren III (CDC 94161-9)
|
||||
* 2. 327 MB CDC Wren IV (CDC 94171-9)
|
||||
*
|
||||
* The CDC 94161-9 was also OEMed as the "AT&T KS23483,L3"
|
||||
* The CDC 94171-9 was also OEMed as the "AT&T KS23483,L25"
|
||||
*
|
||||
*
|
||||
* Tape Drive
|
||||
* ----------
|
||||
*
|
||||
* Wangtek 5125EN (AT&T Part number KS23417,L2)
|
||||
*
|
||||
* DC600A cartridge tape at 120MB (QIC-120 format)
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* Other SCSI hard disk types
|
||||
* ---------------------------
|
||||
*
|
||||
* These geometries are supported natively and automatically
|
||||
* by System V Release 3.2.3 UNIX.
|
||||
*
|
||||
* 1. CDC 94161-9 155 MB/148 MiB 512 B/s, 35 s/t, 9 head, 965 cyl
|
||||
* 2. AT&T KS23483 327 MB/312 MiB 512 B/s, 46 s/t, 9 head, 1547 cyl
|
||||
* (a.k.a CDC 94171-9)
|
||||
*
|
||||
* Also supported was a SCSI-to-ESDI bridge controller that used the
|
||||
* Emulex MD23/S2 SCSI-to-ESDI bridge. It allowed up to four ESDI
|
||||
* drives to be mapped as LUNs 0-3.
|
||||
*
|
||||
*/
|
||||
|
||||
/* AT&T 155 MB Hard Disk (35 sec/t, 9 hd, 964 cyl) */
|
||||
#define SD155_DTYPE 0
|
||||
#define SD155_PQUAL 0x00
|
||||
#define SD155_SCSI 1
|
||||
#define SD155_BLK 512
|
||||
#define SD155_LBN 303660
|
||||
#define SD155_MANU "AT&T"
|
||||
#define SD155_DESC "KS23483"
|
||||
#define SD155_REV "0000"
|
||||
|
||||
/* AT&T 300 MB Hard Disk (43 sec/t, 9 hd, 1514 cyl) */
|
||||
#define SD300_DTYPE 1
|
||||
#define SD300_PQUAL 0x00
|
||||
#define SD300_SCSI 1
|
||||
#define SD300_BLK 512
|
||||
#define SD300_LBN 585937
|
||||
#define SD300_MANU "AT&T"
|
||||
#define SD300_DESC "KS23483"
|
||||
#define SD300_REV "0000"
|
||||
|
||||
/* AT&T 327 MB Hard Disk (46 sec/t, 9 hd, 1547 cyl) */
|
||||
#define SD327_DTYPE 2
|
||||
#define SD327_PQUAL 0x00
|
||||
#define SD327_SCSI 1
|
||||
#define SD327_BLK 512
|
||||
#define SD327_LBN 640458
|
||||
#define SD327_MANU "AT&T"
|
||||
#define SD327_DESC "KS23483"
|
||||
#define SD327_REV "0000"
|
||||
|
||||
/* AT&T 630 MB Hard Disk (56 sec/t, 16 hd, 1447 cyl) */
|
||||
#define SD630_DTYPE 3
|
||||
#define SD630_PQUAL 0x00
|
||||
#define SD630_SCSI 1
|
||||
#define SD630_BLK 512
|
||||
#define SD630_LBN 1296512
|
||||
#define SD630_MANU "AT&T"
|
||||
#define SD630_DESC "KS23483"
|
||||
#define SD630_REV "0000"
|
||||
|
||||
/* Wangtek 120MB cartridge tape */
|
||||
#define ST120_DTYPE 4
|
||||
#define ST120_PQUAL 0x00
|
||||
#define ST120_SCSI 1
|
||||
#define ST120_BLK 512
|
||||
#define ST120_LBN 1
|
||||
#define ST120_MANU "WANGTEK"
|
||||
#define ST120_DESC "KS23465"
|
||||
#define ST120_REV "CX17"
|
||||
|
||||
#define UNIT_V_DTYPE (SCSI_V_UF + 0)
|
||||
#define UNIT_M_DTYPE 0x1f
|
||||
#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE)
|
||||
|
||||
#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE)
|
||||
#define HA_DISK(d) \
|
||||
{ SCSI_DISK, d##_PQUAL, d##_SCSI, FALSE, d##_BLK, \
|
||||
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
|
||||
|
||||
#define HA_TAPE(d) \
|
||||
{ SCSI_TAPE, d##_PQUAL, d##_SCSI, TRUE, d##_BLK, \
|
||||
d##_LBN, d##_MANU, d##_DESC, d##_REV, #d }
|
||||
|
||||
#define HA_SIZE(d) d##_LBN
|
||||
|
||||
#define HA_JOB_QUICK 0
|
||||
#define HA_JOB_EXPRESS 1
|
||||
#define HA_JOB_FULL 2
|
||||
|
||||
typedef uint8 ha_jobtype;
|
||||
|
||||
typedef struct {
|
||||
uint32 addr;
|
||||
uint32 len;
|
||||
} haddr;
|
||||
|
||||
/*
|
||||
* SCSI Command Request
|
||||
*/
|
||||
typedef struct {
|
||||
uint8 op; /* Destructured from the cmd byte array */
|
||||
uint8 tc;
|
||||
uint8 lu;
|
||||
uint32 timeout;
|
||||
|
||||
uint8 dlen;
|
||||
haddr daddr[48]; /* Support up to 48 transfer addresses */
|
||||
|
||||
uint32 dma_lst;
|
||||
uint16 cmd_len;
|
||||
uint8 cmd[HA_MAX_CMD];
|
||||
} ha_req;
|
||||
|
||||
/*
|
||||
* SCSI Command Response
|
||||
*/
|
||||
typedef struct {
|
||||
ha_jobtype type; /* Job type */
|
||||
uint8 status; /* Result Status */
|
||||
uint8 op; /* Command Opcode */
|
||||
uint8 subdev; /* XXTTTLLL; T=Target, L=LUN */
|
||||
uint8 ssb; /* SCSI Status Byte */
|
||||
uint32 addr; /* Response address */
|
||||
uint32 len; /* Response length */
|
||||
} ha_resp;
|
||||
|
||||
#define PUMP_NONE 0
|
||||
#define PUMP_SYSGEN 1
|
||||
#define PUMP_COMPLETE 2
|
||||
|
||||
/*
|
||||
* SCSI Target state
|
||||
*/
|
||||
typedef struct {
|
||||
t_bool pending; /* Service pending */
|
||||
ha_req req; /* SCSI job request */
|
||||
ha_resp rep; /* SCSI job reply */
|
||||
} ha_ts;
|
||||
|
||||
/*
|
||||
* 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_ */
|
||||
|
|
1630
3B2/3b2_stddev.c
1630
3B2/3b2_stddev.c
File diff suppressed because it is too large
Load diff
276
3B2/3b2_stddev.h
276
3B2/3b2_stddev.h
|
@ -1,138 +1,138 @@
|
|||
/* 3b2_stddev.h: Miscellaneous System Board Devices
|
||||
|
||||
Copyright (c) 2017-2022, 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_STDDEV_H_
|
||||
#define _3B2_STDDEV_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
/* NVRAM */
|
||||
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_reset(DEVICE *dptr);
|
||||
uint32 nvram_read(uint32 pa, size_t size);
|
||||
t_stat nvram_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat nvram_detach(UNIT *uptr);
|
||||
const char *nvram_description(DEVICE *dptr);
|
||||
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);
|
||||
|
||||
typedef struct tod_data {
|
||||
time_t time; /* System time */
|
||||
|
||||
uint8 ctrl; /* Control register (Rev 3 only) */
|
||||
uint8 flags; /* Data Changed & Interrutpt Flags (Rev 3 only) */
|
||||
uint8 clkset; /* Clock / Setting register (Rev 3 only) */
|
||||
|
||||
uint8 tsec; /* 1/100th seconds, 00-99 */
|
||||
uint8 sec; /* Seconds, 00-59 */
|
||||
uint8 min; /* Minutes, 00-59 */
|
||||
uint8 hour; /* Hours, 00-23 */
|
||||
uint8 day; /* Days, 00-27, 28, 29, or 30 */
|
||||
uint8 mon; /* Months, 00-11 */
|
||||
uint8 year; /* Years, 00-99 (Rev 3 only) */
|
||||
uint8 wday; /* Day of Week, 0-6 */
|
||||
uint8 lyear; /* Years since last leap year */
|
||||
} TOD_DATA;
|
||||
|
||||
#if defined(REV2)
|
||||
|
||||
#define TOD_TEST 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_WDAY 0x28
|
||||
#define TOD_1MON 0x2c
|
||||
#define TOD_10MON 0x30
|
||||
#define TOD_1YEAR 0x34
|
||||
#define TOD_STARTSTOP 0x38
|
||||
#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_ */
|
||||
/* 3b2_stddev.h: Miscellaneous System Board Devices
|
||||
|
||||
Copyright (c) 2017-2022, 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_STDDEV_H_
|
||||
#define _3B2_STDDEV_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
/* NVRAM */
|
||||
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_reset(DEVICE *dptr);
|
||||
uint32 nvram_read(uint32 pa, size_t size);
|
||||
t_stat nvram_attach(UNIT *uptr, CONST char *cptr);
|
||||
t_stat nvram_detach(UNIT *uptr);
|
||||
const char *nvram_description(DEVICE *dptr);
|
||||
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);
|
||||
|
||||
typedef struct tod_data {
|
||||
time_t time; /* System time */
|
||||
|
||||
uint8 ctrl; /* Control register (Rev 3 only) */
|
||||
uint8 flags; /* Data Changed & Interrutpt Flags (Rev 3 only) */
|
||||
uint8 clkset; /* Clock / Setting register (Rev 3 only) */
|
||||
|
||||
uint8 tsec; /* 1/100th seconds, 00-99 */
|
||||
uint8 sec; /* Seconds, 00-59 */
|
||||
uint8 min; /* Minutes, 00-59 */
|
||||
uint8 hour; /* Hours, 00-23 */
|
||||
uint8 day; /* Days, 00-27, 28, 29, or 30 */
|
||||
uint8 mon; /* Months, 00-11 */
|
||||
uint8 year; /* Years, 00-99 (Rev 3 only) */
|
||||
uint8 wday; /* Day of Week, 0-6 */
|
||||
uint8 lyear; /* Years since last leap year */
|
||||
} TOD_DATA;
|
||||
|
||||
#if defined(REV2)
|
||||
|
||||
#define TOD_TEST 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_WDAY 0x28
|
||||
#define TOD_1MON 0x2c
|
||||
#define TOD_10MON 0x30
|
||||
#define TOD_1YEAR 0x34
|
||||
#define TOD_STARTSTOP 0x38
|
||||
#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_ */
|
||||
|
|
384
3B2/3b2_sys.c
384
3B2/3b2_sys.c
|
@ -1,192 +1,192 @@
|
|||
/* 3b2_sys.c: Common System Definition
|
||||
|
||||
Copyright (c) 2021-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_sys.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_mem.h"
|
||||
|
||||
REG *sim_PC = &cpu_reg[NUM_PC];
|
||||
|
||||
/* 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 */
|
||||
int32 sim_emax = 20;
|
||||
|
||||
const char *sim_stop_messages[SCPE_BASE] = {
|
||||
"Unknown error",
|
||||
"Reserved Instruction",
|
||||
"Breakpoint",
|
||||
"Invalid Opcode",
|
||||
"IRQ",
|
||||
"Exception/Trap",
|
||||
"Exception Stack Too Deep",
|
||||
"Unimplemented MMU Feature",
|
||||
"System Powered Off",
|
||||
"Infinite Loop",
|
||||
"Simulator Error"
|
||||
};
|
||||
|
||||
/*
|
||||
* ROM and Binary loader
|
||||
*
|
||||
* -r load ROM
|
||||
* -o for memory, specify origin
|
||||
*
|
||||
*/
|
||||
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||
{
|
||||
t_stat r;
|
||||
int32 i;
|
||||
uint32 origin = 0, limit = 0;
|
||||
int32 cnt = 0;
|
||||
|
||||
if (flag) {
|
||||
return sim_messagef(SCPE_NOFNC, "Command not implemented.");
|
||||
}
|
||||
|
||||
if (sim_switches & SWMASK('R')) {
|
||||
origin = ROM_BASE;
|
||||
limit = ROM_BASE + ROM_SIZE;
|
||||
} else {
|
||||
origin = 0;
|
||||
limit = (uint32) cpu_unit.capac;
|
||||
if (sim_switches & SWMASK('O')) {
|
||||
origin = (uint32) get_uint(cptr, 16, 0xffffffff, &r);
|
||||
if (r != SCPE_OK) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((i = Fgetc (fileref)) != EOF) {
|
||||
if (origin >= limit) {
|
||||
return SCPE_NXM;
|
||||
}
|
||||
if (sim_switches & SWMASK('R')) {
|
||||
pwrite_b_rom(origin, (uint8)i);
|
||||
} else {
|
||||
pwrite_b(origin, (uint8)i, BUS_CPU);
|
||||
}
|
||||
origin++;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (sim_switches & SWMASK('R')) {
|
||||
rom_loaded = TRUE;
|
||||
sim_messagef(SCPE_OK, "%d bytes loaded into ROM\n", cnt);
|
||||
} else {
|
||||
sim_messagef(SCPE_OK, "%d bytes loaded at address 0x%08x\n", cnt, origin - cnt);
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
t_stat r;
|
||||
int32 k, num, vp;
|
||||
int32 len = 4;
|
||||
|
||||
if (sw & (int32) SWMASK ('B')) {
|
||||
len = 1;
|
||||
} else if (sw & (int32) SWMASK ('H')) {
|
||||
len = 2;
|
||||
} else if (sw & (int32) SWMASK ('W')) {
|
||||
len = 4;
|
||||
}
|
||||
|
||||
// Parse cptr
|
||||
num = (int32) get_uint(cptr, 16, WORD_MASK, &r);
|
||||
|
||||
if (r != SCPE_OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (uptr == NULL) {
|
||||
uptr = &cpu_unit;
|
||||
}
|
||||
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
|
||||
if (dptr == NULL) {
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
vp = 0;
|
||||
for (k = len - 1; k >= 0; k--) {
|
||||
val[vp++] = (num >> (k * 8)) & 0xff;
|
||||
}
|
||||
|
||||
return -(vp - 1);
|
||||
}
|
||||
|
||||
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
|
||||
{
|
||||
uint32 len = 4;
|
||||
int32 k, vp, num;
|
||||
unsigned int c;
|
||||
|
||||
num = 0;
|
||||
vp = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
/* 3b2_sys.c: Common System Definition
|
||||
|
||||
Copyright (c) 2021-2022, Seth J. Morabito
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
Except as contained in this notice, the name of the author shall
|
||||
not be used in advertising or otherwise to promote the sale, use or
|
||||
other dealings in this Software without prior written authorization
|
||||
from the author.
|
||||
*/
|
||||
|
||||
#include "3b2_sys.h"
|
||||
|
||||
#include "3b2_cpu.h"
|
||||
#include "3b2_mem.h"
|
||||
|
||||
REG *sim_PC = &cpu_reg[NUM_PC];
|
||||
|
||||
/* 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 */
|
||||
int32 sim_emax = 20;
|
||||
|
||||
const char *sim_stop_messages[SCPE_BASE] = {
|
||||
"Unknown error",
|
||||
"Reserved Instruction",
|
||||
"Breakpoint",
|
||||
"Invalid Opcode",
|
||||
"IRQ",
|
||||
"Exception/Trap",
|
||||
"Exception Stack Too Deep",
|
||||
"Unimplemented MMU Feature",
|
||||
"System Powered Off",
|
||||
"Infinite Loop",
|
||||
"Simulator Error"
|
||||
};
|
||||
|
||||
/*
|
||||
* ROM and Binary loader
|
||||
*
|
||||
* -r load ROM
|
||||
* -o for memory, specify origin
|
||||
*
|
||||
*/
|
||||
t_stat sim_load(FILE *fileref, CONST char *cptr, CONST char *fnam, int flag)
|
||||
{
|
||||
t_stat r;
|
||||
int32 i;
|
||||
uint32 origin = 0, limit = 0;
|
||||
int32 cnt = 0;
|
||||
|
||||
if (flag) {
|
||||
return sim_messagef(SCPE_NOFNC, "Command not implemented.");
|
||||
}
|
||||
|
||||
if (sim_switches & SWMASK('R')) {
|
||||
origin = ROM_BASE;
|
||||
limit = ROM_BASE + ROM_SIZE;
|
||||
} else {
|
||||
origin = 0;
|
||||
limit = (uint32) cpu_unit.capac;
|
||||
if (sim_switches & SWMASK('O')) {
|
||||
origin = (uint32) get_uint(cptr, 16, 0xffffffff, &r);
|
||||
if (r != SCPE_OK) {
|
||||
return SCPE_ARG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((i = Fgetc (fileref)) != EOF) {
|
||||
if (origin >= limit) {
|
||||
return SCPE_NXM;
|
||||
}
|
||||
if (sim_switches & SWMASK('R')) {
|
||||
pwrite_b_rom(origin, (uint8)i);
|
||||
} else {
|
||||
pwrite_b(origin, (uint8)i, BUS_CPU);
|
||||
}
|
||||
origin++;
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (sim_switches & SWMASK('R')) {
|
||||
rom_loaded = TRUE;
|
||||
sim_messagef(SCPE_OK, "%d bytes loaded into ROM\n", cnt);
|
||||
} else {
|
||||
sim_messagef(SCPE_OK, "%d bytes loaded at address 0x%08x\n", cnt, origin - cnt);
|
||||
}
|
||||
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat parse_sym(CONST char *cptr, t_addr exta, UNIT *uptr, t_value *val, int32 sw)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
t_stat r;
|
||||
int32 k, num, vp;
|
||||
int32 len = 4;
|
||||
|
||||
if (sw & (int32) SWMASK ('B')) {
|
||||
len = 1;
|
||||
} else if (sw & (int32) SWMASK ('H')) {
|
||||
len = 2;
|
||||
} else if (sw & (int32) SWMASK ('W')) {
|
||||
len = 4;
|
||||
}
|
||||
|
||||
// Parse cptr
|
||||
num = (int32) get_uint(cptr, 16, WORD_MASK, &r);
|
||||
|
||||
if (r != SCPE_OK) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (uptr == NULL) {
|
||||
uptr = &cpu_unit;
|
||||
}
|
||||
|
||||
dptr = find_dev_from_unit(uptr);
|
||||
|
||||
if (dptr == NULL) {
|
||||
return SCPE_IERR;
|
||||
}
|
||||
|
||||
vp = 0;
|
||||
for (k = len - 1; k >= 0; k--) {
|
||||
val[vp++] = (num >> (k * 8)) & 0xff;
|
||||
}
|
||||
|
||||
return -(vp - 1);
|
||||
}
|
||||
|
||||
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw)
|
||||
{
|
||||
uint32 len = 4;
|
||||
int32 k, vp, num;
|
||||
unsigned int c;
|
||||
|
||||
num = 0;
|
||||
vp = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
/* 3b2_sys.h: Common System Definition
|
||||
|
||||
Copyright (c) 2017-2022, 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_SYS_H_
|
||||
#define _3B2_SYS_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
void full_reset();
|
||||
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,
|
||||
int32 sw);
|
||||
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);
|
||||
|
||||
extern char sim_name[];
|
||||
extern REG *sim_PC;
|
||||
extern int32 sim_emax;
|
||||
|
||||
#endif /* _3B2_SYS_H_ */
|
||||
/* 3b2_sys.h: Common System Definition
|
||||
|
||||
Copyright (c) 2017-2022, 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_SYS_H_
|
||||
#define _3B2_SYS_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
void full_reset();
|
||||
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,
|
||||
int32 sw);
|
||||
t_stat fprint_sym(FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw);
|
||||
|
||||
extern char sim_name[];
|
||||
extern REG *sim_PC;
|
||||
extern int32 sim_emax;
|
||||
|
||||
#endif /* _3B2_SYS_H_ */
|
||||
|
|
1012
3B2/3b2_timer.c
1012
3B2/3b2_timer.c
File diff suppressed because it is too large
Load diff
156
3B2/3b2_timer.h
156
3B2/3b2_timer.h
|
@ -1,78 +1,78 @@
|
|||
/* 3b2_timer.h: 8253/82C54 Interval Timer
|
||||
|
||||
Copyright (c) 2021-2022, 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_TIMER_H_
|
||||
#define _3B2_TIMER_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#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
|
||||
|
||||
#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_ */
|
||||
/* 3b2_timer.h: 8253/82C54 Interval Timer
|
||||
|
||||
Copyright (c) 2021-2022, 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_TIMER_H_
|
||||
#define _3B2_TIMER_H_
|
||||
|
||||
#include "3b2_defs.h"
|
||||
|
||||
#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
|
||||
|
||||
#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_ */
|
||||
|
|
189
3B2/README.md
189
3B2/README.md
|
@ -1,135 +1,54 @@
|
|||
AT&T 3B2 Simulator
|
||||
==================
|
||||
|
||||
This module contains the source for two simulators:
|
||||
|
||||
1. A simulator for the AT&T 3B2/400 computer (3b2 or 3B2.EXE)
|
||||
2. A simulator for the AT&T 3B2/700 computer (3b2-700 or 3B2-700.EXE)
|
||||
|
||||
The 3B2/400 simulator is complete, usable, and robust. The 3B2/700
|
||||
simulator is under active development and is not yet considered
|
||||
stable.
|
||||
|
||||
Full documentation for the 3B2 simulator is available here:
|
||||
|
||||
- https://loomcom.com/3b2/emulator.html
|
||||
|
||||
3B2/400 Simulator Devices
|
||||
-------------------------
|
||||
|
||||
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)
|
||||
- WE32101 MMU (MMU)
|
||||
- PD8253 Interval Timer (TMR)
|
||||
- AM9517 DMA controller (DMAC)
|
||||
- SCN2681A Integrated DUART (IU)
|
||||
- TMS2793 Integrated Floppy Controller (IFLOPPY)
|
||||
- uPD7261A Integrated MFM Fixed Disk Controller (IDISK)
|
||||
- Non-Volatile Memory (NVRAM)
|
||||
- MM58174A Time Of Day Clock (TOD)
|
||||
- CM195A Ethernet Network Interface (NI)
|
||||
- CM195B 4-port Serial MUX (PORTS)
|
||||
- CM195H Cartridge Tape Controller (CTC)
|
||||
|
||||
3B2/400 Simulator Usage
|
||||
-----------------------
|
||||
|
||||
To boot the 3B2 simulator into firmware mode, simply type:
|
||||
|
||||
sim> BOOT
|
||||
|
||||
You will be greeted with the message:
|
||||
|
||||
FW ERROR 1-01: NVRAM SANITY FAILURE
|
||||
DEFAULT VALUES ASSUMED
|
||||
IF REPEATED, CHECK THE BATTERY
|
||||
|
||||
FW ERROR 1-02: DISK SANITY FAILURE
|
||||
EXECUTION HALTED
|
||||
|
||||
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE
|
||||
|
||||
NVRAM and Time of Day can be saved between boots by attaching both
|
||||
devices to files.
|
||||
|
||||
sim> ATTACH NVRAM <nvram-file>
|
||||
sim> ATTACH TOD <tod-file>
|
||||
|
||||
If you have no operating system installed on the hard drive, on
|
||||
subsequent boots you will instead see the message
|
||||
|
||||
SELF-CHECK
|
||||
|
||||
|
||||
FW ERROR 1-02: DISK SANITY FAILURE
|
||||
EXECUTION HALTED
|
||||
|
||||
SYSTEM FAILURE: CONSULT YOUR SYSTEM ADMINISTRATION UTILITIES GUIDE
|
||||
|
||||
|
||||
Once you see the `SYSTEM FAILURE` message, this is actually an
|
||||
invisible prompt. To access firmware mode, type the default 3B2
|
||||
firmware password `mcp`, then press Enter or carriage return.
|
||||
|
||||
You should then be prompted with:
|
||||
|
||||
Enter name of program to execute [ ]:
|
||||
|
||||
Here, you may type a question mark (?) and press Enter to see a list
|
||||
of available firmware programs.
|
||||
|
||||
Booting UNIX SVR3 on the 3B2/400
|
||||
--------------------------------
|
||||
|
||||
UNIX System V UNIX is the only operating system available for the 3B2.
|
||||
To boot UNIX, attach the first disk image from the 3B2 "Essential
|
||||
Utilities" distribution.
|
||||
|
||||
sim> ATTACH IFLOPPY <floppy-image>
|
||||
sim> BOOT
|
||||
|
||||
Once you reach the `SYSTEM FAILURE` message, type `mcp` to enter
|
||||
firmware mode. When prompted for the name of a program to boot, enter
|
||||
`unix`, and confirm the boot device is `FD5` by pressing Enter or
|
||||
carriage return.
|
||||
|
||||
Enter name of program to execute [ ]: unix
|
||||
Possible load devices are:
|
||||
|
||||
Option Number Slot Name
|
||||
---------------------------------------
|
||||
0 0 FD5
|
||||
|
||||
Enter Load Device Option Number [0 (FD5)]:
|
||||
|
||||
Installing SVR3 on the 3B2/400
|
||||
------------------------------
|
||||
|
||||
To install SVR3 to the first hard disk, first, attach a new image
|
||||
to the IDISK0 device:
|
||||
|
||||
sim> ATTACH IDISK0 <hd-image>
|
||||
|
||||
Then, boot the file `idtools` from the "3B2 Maintenance Utilities -
|
||||
Issue 4.0" floppy diskette.
|
||||
|
||||
From `idtools`, select the `formhard` option and low-level format
|
||||
integrated disk 0. Parameters for the default 72MB hard disk are:
|
||||
|
||||
Drive Id: 5
|
||||
Number cylinders: 925
|
||||
Number tracks/cyl: 9
|
||||
Number sectors/track: 18
|
||||
Number bytes/sector: 512
|
||||
|
||||
After low-level formatting integrated disk 0, boot the file `unix`
|
||||
from the first diskette of the 3B2 "Essential Utilities" distribution,
|
||||
and follow the prompts.
|
||||
|
||||
More information about installing AT&T System V Release 3.2 UNIX is
|
||||
available on the web:
|
||||
|
||||
- https://loomcom.com/3b2/installing_unix.html
|
||||
AT&T 3B2 Simulator
|
||||
==================
|
||||
|
||||
This module contains the source for two simulators:
|
||||
|
||||
1. A simulator for the AT&T 3B2/400 computer (3b2-400 or 3B2-400.EXE)
|
||||
2. A simulator for the AT&T 3B2/700 computer (3b2-700 or 3B2-700.EXE)
|
||||
|
||||
Full documentation for the 3B2 simulator is available here:
|
||||
|
||||
- https://loomcom.com/3b2/emulator.html
|
||||
|
||||
3B2/400 Simulator Devices
|
||||
-------------------------
|
||||
|
||||
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
|
||||
- Configuration and Status Register (CSR)
|
||||
- WE32100 CPU (CPU)
|
||||
- WE32101 MMU (MMU)
|
||||
- WE32106 Math Accelerator Unit (MAU)
|
||||
- PD8253 Interval Timer (TMR)
|
||||
- AM9517 DMA controller (DMAC)
|
||||
- SCN2681A Integrated DUART (IU)
|
||||
- TMS2793 Integrated Floppy Controller (IFLOPPY)
|
||||
- uPD7261A Integrated MFM Fixed Disk Controller (IDISK)
|
||||
- Non-Volatile Memory (NVRAM)
|
||||
- MM58174A Time Of Day Clock (TOD)
|
||||
- CM195A Ethernet Network Interface (NI)
|
||||
- CM195B 4-port Serial MUX (PORTS)
|
||||
- CM195H Cartridge Tape Controller (CTC)
|
||||
|
||||
3B2/700 Simulator Devices
|
||||
-------------------------
|
||||
|
||||
The following devices are simulated. The SIMH names for the simulated
|
||||
devices are given in parentheses:
|
||||
|
||||
- 3B2 Model 700 System Board with 8MB, 16MB, 32MB, or 64MB RAM
|
||||
- Configuration and Status Registers (CSR)
|
||||
- WE32200 CPU (CPU)
|
||||
- WE32201 MMU (MMU)
|
||||
- WE32106 Math Accelerator Unit (MAU)
|
||||
- PD8253 Interval Timer (TMR)
|
||||
- AM9517 DMA controller (DMAC)
|
||||
- SCN2681A Integrated DUART (IU)
|
||||
- TMS2793 Integrated Floppy Controller (IFLOPPY)
|
||||
- Non-Volatile Memory (NVRAM)
|
||||
- MM58274C Time Of Day Clock (TOD)
|
||||
- CM195W SCSI Host Adapter (SCSI)
|
||||
- CM195A Ethernet Network Interface (NI)
|
||||
- CM195B 4-port Serial MUX (PORTS)
|
||||
|
|
Loading…
Add table
Reference in a new issue