blob: b17238d21806c8c8ac7be01afa39954fd756489e [file] [log] [blame] [raw]
/* hp3000_mem.h: HP 3000 memory subsystem interface declarations
Copyright (c) 2016, J. David Bryan
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
AUTHOR 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.
10-Oct-16 JDB Created
This file contains declarations used by the CPU, I/O Processor, Multiplexer
Channel, and Selector Channel to interface with the HP 3000 memory subsystem.
*/
/* Debug flags.
Implementation notes:
1. Memory debug flags are allocated in descending order, as they may be used
by other modules (e.g., CPU) that allocate their own flags in ascending
order. No check is made for overlapping values.
*/
#define DEB_MDATA (1u << 31) /* trace memory reads and writes */
#define DEB_MFETCH (1u << 30) /* trace memory instruction fetches */
#define DEB_MOPND (1u << 29) /* trace memory operand accesses */
/* Architectural constants.
The type used to represent a main memory word value is defined. An array of
this type is used to simulate the CPU main memory.
Implementation notes:
1. The MEMORY_WORD type is a 16-bit unsigned type, corresponding with the
16-bit main memory in the HP 3000. Unlike the general data type, which
is a 32-bit type for speed, main memory does not benefit from the faster
32-bit execution on IA-32 processors, as only one instruction in the
cpu_read_memory and cpu_write_memory routines has an operand override
that invokes the slower instruction fetch path. There is a negligible
difference in the Memory Pattern Test diagnostic execution speeds for the
uint32 vs. uint16 definition, whereas the VM requirements are doubled for
the former.
*/
typedef uint16 MEMORY_WORD; /* HP 16-bit memory word representation */
/* Byte accessors.
The HP 3000 is a word-addressable machine. Byte addressing is implemented by
assuming that a memory of N physical words may be addressed as 2N bytes. The
"byte-capable" machine instructions use "relative byte addresses" that are
used to obtain absolute word addresses by dividing by two and then accessing
the upper or lower byte of the resulting word, depending on the LSB of the
byte address.
In simulation, this module provides a byte access structure and a set of
routines that read or write the next byte in ascending byte-offset order.
The structure is initialized with the starting byte offset from a specified
base register value and then is passed as a parameter to the other routines,
which update the fields accordingly for the access requested. This relieves
the caller from having to manage the continual logical-to-physical address
translation, word buffering, byte selection, etc.
Byte accessors are also used to provide debug traces of byte operands in
memory. Initializing an accessor sets a field containing the absolute byte
memory address; this address may be passed to the byte formatters to print
the operand.
In most cases, operands are defined by starting byte addresses and byte
counts. However, some operands (e.g., EDIT instruction operands) are
delineated only by the extents of the accesses. For these operands, byte
accessors maintain the lowest byte addresses and offsets actually accessed,
as well as the lengths of the extent of the accesses.
*/
typedef struct { /* byte access descriptor */
HP_WORD *byte_offset; /* relative byte offset of the next byte */
HP_WORD data_word; /* memory data word containing the current byte */
ACCESS_CLASS class; /* memory access classification */
uint32 word_address; /* logical word address containing the next byte */
t_bool write_needed; /* TRUE if the data word must be written to memory */
uint32 count; /* current count of bytes accessed */
uint32 length; /* (trace) length of extent of access */
uint32 initial_byte_address; /* (trace) initial absolute byte address */
uint32 initial_byte_offset; /* (trace) initial relative byte offset */
uint32 first_byte_address; /* (trace) lowest absolute byte address accessed */
uint32 first_byte_offset; /* (trace) lowest relative byte offset accessed */
} BYTE_ACCESS;
/* Memory global SCP support routines */
t_stat mem_examine (t_value *eval_array, t_addr address, UNIT *uptr, int32 switches);
t_stat mem_deposit (t_value value, t_addr address, UNIT *uptr, int32 switches);
/* Global memory functions.
mem_initialize : allocate main memory
mem_is_empty : check for a non-zero value within a range of memory locations
mem_fill : set all memory locations to a specified value
mem_read : read a word from main memory
mem_write : write a word to main memory
mem_init_byte : initialize a memory byte access structure
mem_set_byte : set the access structure to a new byte offset
mem_lookup_byte : return a byte at a specified index in a table
mem_read_byte : read the next byte from memory
mem_write_byte : write the next byte to memory
mem_modify_byte : replace the last byte written to memory
mem_post_byte : post the word containing the last byte modified in place to memory
mem_update_byte : rewrite the word containing the last byte written to memory
fmt_byte_operand : format a byte operand in memory into a character string
fmt_bcd_operand : format a BCD operand in memory into a character string
*/
extern t_bool mem_initialize (uint32 memory_size);
extern t_bool mem_is_empty (uint32 starting_address);
extern void mem_fill (uint32 starting_address, HP_WORD fill_value);
extern t_bool mem_read (DEVICE *dptr, ACCESS_CLASS classification, uint32 offset, HP_WORD *value);
extern t_bool mem_write (DEVICE *dptr, ACCESS_CLASS classification, uint32 offset, HP_WORD value);
extern void mem_init_byte (BYTE_ACCESS *bap, ACCESS_CLASS class, HP_WORD *byte_offset, uint32 block_length);
extern void mem_set_byte (BYTE_ACCESS *bap);
extern uint8 mem_lookup_byte (BYTE_ACCESS *bap, uint8 index);
extern uint8 mem_read_byte (BYTE_ACCESS *bap);
extern void mem_write_byte (BYTE_ACCESS *bap, uint8 byte);
extern void mem_modify_byte (BYTE_ACCESS *bap, uint8 byte);
extern void mem_post_byte (BYTE_ACCESS *bap);
extern void mem_update_byte (BYTE_ACCESS *bap);
extern char *fmt_byte_operand (uint32 byte_address, uint32 byte_count);
extern char *fmt_translated_byte_operand (uint32 byte_address, uint32 byte_count, uint32 table_address);
extern char *fmt_bcd_operand (uint32 byte_address, uint32 digit_count);