From 66c264d6787978646c853f67780fc90023f133c8 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sat, 24 Mar 2012 15:30:27 -0700 Subject: [PATCH] RC2 of 3.9 After a frantic week of file exchanges, here is RC2. A lot has changed. 1. HP2100 updates completed, with new features and peripherals. 2. Many, many small file updates for nits found by compilers and static checkers. 3. A few genuine bugs fixed. 4. New makefile and MMS file. A note on the makefile. It has almost doubled in size and attempts to ferret out PCAP locales properly, as well as do serious optimizations if gcc is used. It needs to be tested in more environments. If you run into issues, please report them to Mark Pizzolato as well as me. The old makefile, updated for the extra files in the HP2100, is included as makefile_old. You can use that if the new makefile causes problems in your environment. I'm still targeting a May Day release, with a final RC around Tax Day (April 15). That leaves times for one more interim RC, if needed. At this point, I regard the release as feature-complete. Bug fixes are still fine. The actual release will have all incomplete and beta simulators in a separate zip file, including Alpha, Sigma, Sage (the microcomputers, not the 50s anti-aircraft computer), and SC1, the SiCortex MIPS simulator. There will be new releases of all the simulation tools as well. /Bob --- 0readme_39.txt | 10 +- ALTAIR/altair_cpu.c | 7 +- AltairZ80/altairZ80_sio.c | 6 +- AltairZ80/i8272.c | 4 +- AltairZ80/insnsa.c | 4443 ------------------------- AltairZ80/mfdc.c | 8 +- AltairZ80/s100_64fdc.c | 36 +- AltairZ80/s100_adcs6.c | 26 +- AltairZ80/vfdhd.c | 4 +- AltairZ80/wd179x.c | 13 +- GRI/gri_cpu.c | 2 +- GRI/gri_stddev.c | 2 +- GRI/gri_sys.c | 2 +- H316/h316_cpu.c | 10 +- H316/h316_dp.c | 8 +- H316/h316_fhd.c | 8 +- H316/h316_lp.c | 4 +- H316/h316_mt.c | 10 +- H316/h316_stddev.c | 10 +- I1401/i1401_cd.c | 6 +- I1401/i1401_cpu.c | 18 +- I1401/i1401_lp.c | 2 +- I1401/i1401_mt.c | 26 +- I1401/i1401_sys.c | 6 +- I1620/i1620_cd.c | 13 +- I1620/i1620_cpu.c | 10 +- I1620/i1620_dp.c | 2 +- I1620/i1620_fp.c | 2 +- I1620/i1620_pt.c | 5 +- I1620/i1620_sys.c | 10 +- I7094/i7094_cd.c | 5 +- I7094/i7094_com.c | 4 +- I7094/i7094_cpu.c | 2 +- I7094/i7094_cpu1.c | 2 +- I7094/i7094_drm.c | 88 +- I7094/i7094_dsk.c | 2 +- I7094/i7094_io.c | 10 +- I7094/i7094_lp.c | 2 +- I7094/i7094_mt.c | 7 +- Ibm1130/ibm1130_cr.c | 2 +- Ibm1130/ibm1130_sys.c | 10 +- Interdata/id16_cpu.c | 8 +- Interdata/id32_cpu.c | 8 +- Interdata/id32_dboot.c | 2 +- Interdata/id_fd.c | 10 +- Interdata/id_idc.c | 4 +- Interdata/id_io.c | 2 +- Interdata/id_lp.c | 2 +- Interdata/id_pas.c | 7 +- Interdata/id_pt.c | 2 +- LGP/lgp_cpu.c | 4 +- NOVA/nova_clk.c | 2 +- NOVA/nova_cpu.c | 6 +- NOVA/nova_dsk.c | 2 +- NOVA/nova_mta.c | 2 +- NOVA/nova_sys.c | 2 +- PDP1/pdp1_cpu.c | 9 +- PDP1/pdp1_stddev.c | 19 +- PDP11/pdp11_cis.c | 6 +- PDP11/pdp11_cpu.c | 29 +- PDP11/pdp11_cpumod.c | 6 +- PDP11/pdp11_dz.c | 2 +- PDP11/pdp11_fp.c | 2 +- PDP11/pdp11_hk.c | 5 +- PDP11/pdp11_io.c | 12 +- PDP11/pdp11_rf.c | 7 +- PDP11/pdp11_rh.c | 8 +- PDP11/pdp11_rk.c | 2 +- PDP11/pdp11_rl.c | 2418 +++++++------- PDP11/pdp11_rq.c | 12 +- PDP11/pdp11_rx.c | 2 +- PDP11/pdp11_ry.c | 6 +- PDP11/pdp11_stddev.c | 4 +- PDP11/pdp11_sys.c | 6 +- PDP11/pdp11_tc.c | 2 +- PDP11/pdp11_tm.c | 13 +- PDP11/pdp11_tq.c | 10 +- PDP11/pdp11_ts.c | 9 +- PDP11/pdp11_tu.c | 4 +- PDP11/pdp11_vh.c | 2161 ++++++------ PDP11/pdp11_xq.c | 36 +- PDP11/pdp11_xu.c | 39 +- PDP18B/pdp18b_cpu.c | 14 +- PDP18B/pdp18b_drm.c | 2 +- PDP18B/pdp18b_fpp.c | 11 +- PDP18B/pdp18b_lp.c | 2 +- PDP18B/pdp18b_rf.c | 2 +- PDP18B/pdp18b_stddev.c | 2 +- PDP18B/pdp18b_sys.c | 7 +- S3/s3_cd.c | 7 +- S3/s3_cpu.c | 16 +- S3/s3_lp.c | 7 +- S3/s3_sys.c | 6 +- SDS/sds_io.c | 9 +- SDS/sds_mt.c | 5 +- SDS/sds_sys.c | 7 +- VAX/vax780_sbi.c | 4 +- VAX/vax780_stddev.c | 2 +- VAX/vax780_syslist.c | 2 +- VAX/vax780_uba.c | 2 +- VAX/vax_cis.c | 4 +- VAX/vax_cmode.c | 2 +- VAX/vax_cpu.c | 85 +- VAX/vax_cpu1.c | 10 +- VAX/vax_fpa.c | 11 +- VAX/vax_io.c | 8 +- VAX/vax_mmu.c | 2 +- VAX/vax_octa.c | 4 +- VAX/vax_sys.c | 2 +- VAX/vax_syscm.c | 4 +- VAX/vax_sysdev.c | 8 +- VAX/vax_syslist.c | 2 +- alpha/alpha_500au_syslist.c | 49 - alpha/alpha_cpu.c | 1865 ----------- alpha/alpha_defs.h | 457 --- alpha/alpha_ev5_cons.c | 143 - alpha/alpha_ev5_defs.h | 428 --- alpha/alpha_ev5_pal.c | 961 ------ alpha/alpha_ev5_tlb.c | 566 ---- alpha/alpha_fpi.c | 776 ----- alpha/alpha_fpv.c | 457 --- alpha/alpha_io.c | 214 -- alpha/alpha_mmu.c | 308 -- alpha/alpha_sys.c | 814 ----- alpha/alpha_sys_defs.h | 43 - alpha/old_pal/alpha_pal_defs.h | 208 -- alpha/old_pal/alpha_pal_unix.c | 702 ---- alpha/old_pal/alpha_pal_vms.c | 1780 ---------- doc/simh_doc.doc | Bin 198144 -> 168448 bytes makefile | 53 +- makefile_old | 438 +++ scp.c | 104 +- sigma/Design Notes on the Sigma 7.doc | Bin 25088 -> 0 bytes sigma/sigma_bugs.txt | 149 - sigma/sigma_cis.c | 990 ------ sigma/sigma_coc.c | 620 ---- sigma/sigma_cpu.c | 2848 ---------------- sigma/sigma_defs.h | 478 --- sigma/sigma_dk.c | 470 --- sigma/sigma_doc.doc | Bin 90624 -> 0 bytes sigma/sigma_dp.c | 1278 ------- sigma/sigma_fp.c | 421 --- sigma/sigma_io.c | 1497 --------- sigma/sigma_io_defs.h | 276 -- sigma/sigma_lp.c | 529 --- sigma/sigma_map.c | 591 ---- sigma/sigma_mt.c | 645 ---- sigma/sigma_pt.c | 297 -- sigma/sigma_rad.c | 532 --- sigma/sigma_rtc.c | 267 -- sigma/sigma_sys.c | 613 ---- sigma/sigma_tt.c | 331 -- sim_console.c | 27 +- sim_defs.h | 1 + sim_ether.c | 3 +- sim_rev.h | 76 +- swtp/swtp_cpu.c | 92 +- swtp/swtp_defs.h | 2 +- swtp/swtp_dsk.c | 2 +- 159 files changed, 3557 insertions(+), 29832 deletions(-) delete mode 100644 AltairZ80/insnsa.c delete mode 100644 alpha/alpha_500au_syslist.c delete mode 100644 alpha/alpha_cpu.c delete mode 100644 alpha/alpha_defs.h delete mode 100644 alpha/alpha_ev5_cons.c delete mode 100644 alpha/alpha_ev5_defs.h delete mode 100644 alpha/alpha_ev5_pal.c delete mode 100644 alpha/alpha_ev5_tlb.c delete mode 100644 alpha/alpha_fpi.c delete mode 100644 alpha/alpha_fpv.c delete mode 100644 alpha/alpha_io.c delete mode 100644 alpha/alpha_mmu.c delete mode 100644 alpha/alpha_sys.c delete mode 100644 alpha/alpha_sys_defs.h delete mode 100644 alpha/old_pal/alpha_pal_defs.h delete mode 100644 alpha/old_pal/alpha_pal_unix.c delete mode 100644 alpha/old_pal/alpha_pal_vms.c create mode 100644 makefile_old delete mode 100644 sigma/Design Notes on the Sigma 7.doc delete mode 100644 sigma/sigma_bugs.txt delete mode 100644 sigma/sigma_cis.c delete mode 100644 sigma/sigma_coc.c delete mode 100644 sigma/sigma_cpu.c delete mode 100644 sigma/sigma_defs.h delete mode 100644 sigma/sigma_dk.c delete mode 100644 sigma/sigma_doc.doc delete mode 100644 sigma/sigma_dp.c delete mode 100644 sigma/sigma_fp.c delete mode 100644 sigma/sigma_io.c delete mode 100644 sigma/sigma_io_defs.h delete mode 100644 sigma/sigma_lp.c delete mode 100644 sigma/sigma_map.c delete mode 100644 sigma/sigma_mt.c delete mode 100644 sigma/sigma_pt.c delete mode 100644 sigma/sigma_rad.c delete mode 100644 sigma/sigma_rtc.c delete mode 100644 sigma/sigma_sys.c delete mode 100644 sigma/sigma_tt.c diff --git a/0readme_39.txt b/0readme_39.txt index d3c8fbc0..b4760f1e 100644 --- a/0readme_39.txt +++ b/0readme_39.txt @@ -20,11 +20,19 @@ Otherwise, you will get build errors. - added "SHOW SHOW" and "SHOW SHOW" commands (Mark Pizzolato) - added support for BREAK key on Windows (Mark Pizzolato) - 1.1.2 PDP-8 - floating point processor is now enabled +1.1.3 HP2100 (Dave Bryan) + + - added support for 12821A HP-IP disk controller, + 7906H/20H/25H disks + +1.1.4 IA64 VMS Ethernet Support + + - Identified compiler version issues and added IA64 support (Matt Burke) + 2. Bugs Fixed Please see the revision history on http://simh.trailing-edge.com or diff --git a/ALTAIR/altair_cpu.c b/ALTAIR/altair_cpu.c index 740d66f7..80fce7d6 100644 --- a/ALTAIR/altair_cpu.c +++ b/ALTAIR/altair_cpu.c @@ -1,6 +1,6 @@ /* altair_cpu.c: MITS Altair Intel 8080 CPU simulator - Copyright (c) 1997-2005, Charles E. Owen + Copyright (c) 1997-2012, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ cpu 8080 CPU + 19-Mar-12 RMS Fixed data type for breakpoint variables 08-Oct-02 RMS Tied off spurious compiler warnings The register state for the 8080 CPU is: @@ -107,7 +108,7 @@ int32 chip = 0; /* 0 = 8080 chip, 1 = z8 int32 PCX; /* External view of PC */ extern int32 sim_int_char; -extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ +extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ;/* breakpoint info */ /* function prototypes */ @@ -141,7 +142,7 @@ device addresses, if a device is plugged to a port it's routine address is here, 'nulldev' means no device is available */ struct idev { - int32 (*routine)(); + int32 (*routine)(int32, int32); }; struct idev dev_table[256] = { {&nulldev}, {&nulldev}, {&nulldev}, {&nulldev}, /* 000 */ diff --git a/AltairZ80/altairZ80_sio.c b/AltairZ80/altairZ80_sio.c index e83948ce..54447c58 100644 --- a/AltairZ80/altairZ80_sio.c +++ b/AltairZ80/altairZ80_sio.c @@ -132,7 +132,7 @@ static t_stat sio_attach(UNIT *uptr, char *cptr); static t_stat sio_detach(UNIT *uptr); static t_stat ptr_reset(DEVICE *dptr); static t_stat ptp_reset(DEVICE *dptr); -static t_stat toBool(char tf, int *result); +static t_stat toBool(char tf, int32 *result); static t_stat sio_dev_set_port(UNIT *uptr, int32 value, char *cptr, void *desc); static t_stat sio_dev_show_port(FILE *st, UNIT *uptr, int32 val, void *desc); static t_stat sio_dev_set_interrupton(UNIT *uptr, int32 value, char *cptr, void *desc); @@ -168,11 +168,11 @@ extern const t_bool rtc_avail; extern uint32 PCX; extern int32 sim_switches; extern int32 sim_quiet; -extern const char *scp_error_messages[]; extern int32 SR; extern UNIT cpu_unit; extern volatile int32 stop_cpu; extern int32 sim_interval; +extern const char *scp_error_messages[]; /* Debug Flags */ static DEBTAB generic_dt[] = { @@ -860,7 +860,7 @@ int32 sio1d(const int32 port, const int32 io, const int32 data) { return result; } -static t_stat toBool(char tf, int *result) { +static t_stat toBool(char tf, int32 *result) { if (tf == 'T') { *result = TRUE; return SCPE_OK; diff --git a/AltairZ80/i8272.c b/AltairZ80/i8272.c index b02fa450..bf7451da 100644 --- a/AltairZ80/i8272.c +++ b/AltairZ80/i8272.c @@ -476,8 +476,8 @@ static char *messages[0x20] = { uint8 I8272_Write(const uint32 Addr, uint8 cData) { I8272_DRIVE_INFO *pDrive; - unsigned int flags = 0; - unsigned int readlen; + uint32 flags = 0; + uint32 readlen; uint8 disk_read = 0; int32 i; diff --git a/AltairZ80/insnsa.c b/AltairZ80/insnsa.c deleted file mode 100644 index ba4d70d7..00000000 --- a/AltairZ80/insnsa.c +++ /dev/null @@ -1,4443 +0,0 @@ -/* This file auto-generated from insns.dat by insns.pl - don't edit it */ - -#include "nasm.h" -#include "insns.h" - -static struct itemplate instrux_AAA[] = { - {I_AAA, 0, {0,0,0}, "\1\x37", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_AAD[] = { - {I_AAD, 0, {0,0,0}, "\2\xD5\x0A", IF_8086}, - {I_AAD, 1, {IMMEDIATE,0,0}, "\1\xD5\24", IF_8086|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_AAM[] = { - {I_AAM, 0, {0,0,0}, "\2\xD4\x0A", IF_8086}, - {I_AAM, 1, {IMMEDIATE,0,0}, "\1\xD4\24", IF_8086|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_AAS[] = { - {I_AAS, 0, {0,0,0}, "\1\x3F", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADC[] = { - {I_ADC, 2, {MEMORY,REG8,0}, "\300\1\x10\101", IF_8086|IF_SM}, - {I_ADC, 2, {REG8,REG8,0}, "\1\x10\101", IF_8086}, - {I_ADC, 2, {MEMORY,REG16,0}, "\320\300\1\x11\101", IF_8086|IF_SM}, - {I_ADC, 2, {REG16,REG16,0}, "\320\1\x11\101", IF_8086}, - {I_ADC, 2, {MEMORY,REG32,0}, "\321\300\1\x11\101", IF_386|IF_SM}, - {I_ADC, 2, {REG32,REG32,0}, "\321\1\x11\101", IF_386}, - {I_ADC, 2, {REG8,MEMORY,0}, "\301\1\x12\110", IF_8086|IF_SM}, - {I_ADC, 2, {REG8,REG8,0}, "\1\x12\110", IF_8086}, - {I_ADC, 2, {REG16,MEMORY,0}, "\320\301\1\x13\110", IF_8086|IF_SM}, - {I_ADC, 2, {REG16,REG16,0}, "\320\1\x13\110", IF_8086}, - {I_ADC, 2, {REG32,MEMORY,0}, "\321\301\1\x13\110", IF_386|IF_SM}, - {I_ADC, 2, {REG32,REG32,0}, "\321\1\x13\110", IF_386}, - {I_ADC, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\202\15", IF_8086}, - {I_ADC, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\202\15", IF_386}, - {I_ADC, 2, {REG_AL,IMMEDIATE,0}, "\1\x14\21", IF_8086|IF_SM}, - {I_ADC, 2, {REG_AX,SBYTE,0}, "\320\1\x83\202\15", IF_8086|IF_SM}, - {I_ADC, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x15\31", IF_8086|IF_SM}, - {I_ADC, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\202\15", IF_386|IF_SM}, - {I_ADC, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x15\41", IF_386|IF_SM}, - {I_ADC, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\202\21", IF_8086|IF_SM}, - {I_ADC, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\202\131", IF_8086|IF_SM}, - {I_ADC, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\202\141", IF_386|IF_SM}, - {I_ADC, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\202\21", IF_8086|IF_SM}, - {I_ADC, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\202\131", IF_8086|IF_SM}, - {I_ADC, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\202\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADD[] = { - {I_ADD, 2, {MEMORY,REG8,0}, "\300\17\101", IF_8086|IF_SM}, - {I_ADD, 2, {REG8,REG8,0}, "\17\101", IF_8086}, - {I_ADD, 2, {MEMORY,REG16,0}, "\320\300\1\x01\101", IF_8086|IF_SM}, - {I_ADD, 2, {REG16,REG16,0}, "\320\1\x01\101", IF_8086}, - {I_ADD, 2, {MEMORY,REG32,0}, "\321\300\1\x01\101", IF_386|IF_SM}, - {I_ADD, 2, {REG32,REG32,0}, "\321\1\x01\101", IF_386}, - {I_ADD, 2, {REG8,MEMORY,0}, "\301\1\x02\110", IF_8086|IF_SM}, - {I_ADD, 2, {REG8,REG8,0}, "\1\x02\110", IF_8086}, - {I_ADD, 2, {REG16,MEMORY,0}, "\320\301\1\x03\110", IF_8086|IF_SM}, - {I_ADD, 2, {REG16,REG16,0}, "\320\1\x03\110", IF_8086}, - {I_ADD, 2, {REG32,MEMORY,0}, "\321\301\1\x03\110", IF_386|IF_SM}, - {I_ADD, 2, {REG32,REG32,0}, "\321\1\x03\110", IF_386}, - {I_ADD, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\200\15", IF_8086}, - {I_ADD, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\200\15", IF_386}, - {I_ADD, 2, {REG_AL,IMMEDIATE,0}, "\1\x04\21", IF_8086|IF_SM}, - {I_ADD, 2, {REG_AX,SBYTE,0}, "\320\1\x83\200\15", IF_8086|IF_SM}, - {I_ADD, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x05\31", IF_8086|IF_SM}, - {I_ADD, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\200\15", IF_386|IF_SM}, - {I_ADD, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x05\41", IF_386|IF_SM}, - {I_ADD, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\200\21", IF_8086|IF_SM}, - {I_ADD, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\200\131", IF_8086|IF_SM}, - {I_ADD, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\200\141", IF_386|IF_SM}, - {I_ADD, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\200\21", IF_8086|IF_SM}, - {I_ADD, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\200\131", IF_8086|IF_SM}, - {I_ADD, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\200\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADDPD[] = { - {I_ADDPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\x58\110", IF_WILLAMETTE|IF_SSE2}, - {I_ADDPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\x58\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADDPS[] = { - {I_ADDPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x58\110", IF_KATMAI|IF_SSE}, - {I_ADDPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x58\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADDSD[] = { - {I_ADDSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\x58\110", IF_WILLAMETTE|IF_SSE2}, - {I_ADDSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\x58\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADDSS[] = { - {I_ADDSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x58\110", IF_KATMAI|IF_SSE}, - {I_ADDSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x58\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADDSUBPD[] = { - {I_ADDSUBPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD0\110", IF_PRESCOTT|IF_SSE3|IF_SM}, - {I_ADDSUBPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD0\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ADDSUBPS[] = { - {I_ADDSUBPS, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\xD0\110", IF_PRESCOTT|IF_SSE3|IF_SM}, - {I_ADDSUBPS, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\xD0\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_AND[] = { - {I_AND, 2, {MEMORY,REG8,0}, "\300\1\x20\101", IF_8086|IF_SM}, - {I_AND, 2, {REG8,REG8,0}, "\1\x20\101", IF_8086}, - {I_AND, 2, {MEMORY,REG16,0}, "\320\300\1\x21\101", IF_8086|IF_SM}, - {I_AND, 2, {REG16,REG16,0}, "\320\1\x21\101", IF_8086}, - {I_AND, 2, {MEMORY,REG32,0}, "\321\300\1\x21\101", IF_386|IF_SM}, - {I_AND, 2, {REG32,REG32,0}, "\321\1\x21\101", IF_386}, - {I_AND, 2, {REG8,MEMORY,0}, "\301\1\x22\110", IF_8086|IF_SM}, - {I_AND, 2, {REG8,REG8,0}, "\1\x22\110", IF_8086}, - {I_AND, 2, {REG16,MEMORY,0}, "\320\301\1\x23\110", IF_8086|IF_SM}, - {I_AND, 2, {REG16,REG16,0}, "\320\1\x23\110", IF_8086}, - {I_AND, 2, {REG32,MEMORY,0}, "\321\301\1\x23\110", IF_386|IF_SM}, - {I_AND, 2, {REG32,REG32,0}, "\321\1\x23\110", IF_386}, - {I_AND, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\204\15", IF_8086}, - {I_AND, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\204\15", IF_386}, - {I_AND, 2, {REG_AL,IMMEDIATE,0}, "\1\x24\21", IF_8086|IF_SM}, - {I_AND, 2, {REG_AX,SBYTE,0}, "\320\1\x83\204\15", IF_8086|IF_SM}, - {I_AND, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x25\31", IF_8086|IF_SM}, - {I_AND, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\204\15", IF_386|IF_SM}, - {I_AND, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x25\41", IF_386|IF_SM}, - {I_AND, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\204\21", IF_8086|IF_SM}, - {I_AND, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\204\131", IF_8086|IF_SM}, - {I_AND, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\204\141", IF_386|IF_SM}, - {I_AND, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\204\21", IF_8086|IF_SM}, - {I_AND, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\204\131", IF_8086|IF_SM}, - {I_AND, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\204\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ANDNPD[] = { - {I_ANDNPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\x55\110", IF_WILLAMETTE|IF_SSE2}, - {I_ANDNPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\x55\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ANDNPS[] = { - {I_ANDNPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x55\110", IF_KATMAI|IF_SSE}, - {I_ANDNPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x55\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ANDPD[] = { - {I_ANDPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\x54\110", IF_WILLAMETTE|IF_SSE2}, - {I_ANDPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\x54\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ANDPS[] = { - {I_ANDPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x54\110", IF_KATMAI|IF_SSE}, - {I_ANDPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x54\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ARPL[] = { - {I_ARPL, 2, {MEMORY,REG16,0}, "\300\1\x63\101", IF_286|IF_PROT|IF_SM}, - {I_ARPL, 2, {REG16,REG16,0}, "\1\x63\101", IF_286|IF_PROT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BOUND[] = { - {I_BOUND, 2, {REG16,MEMORY,0}, "\320\301\1\x62\110", IF_186}, - {I_BOUND, 2, {REG32,MEMORY,0}, "\321\301\1\x62\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BSF[] = { - {I_BSF, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xBC\110", IF_386|IF_SM}, - {I_BSF, 2, {REG16,REG16,0}, "\320\2\x0F\xBC\110", IF_386}, - {I_BSF, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xBC\110", IF_386|IF_SM}, - {I_BSF, 2, {REG32,REG32,0}, "\321\2\x0F\xBC\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BSR[] = { - {I_BSR, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xBD\110", IF_386|IF_SM}, - {I_BSR, 2, {REG16,REG16,0}, "\320\2\x0F\xBD\110", IF_386}, - {I_BSR, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xBD\110", IF_386|IF_SM}, - {I_BSR, 2, {REG32,REG32,0}, "\321\2\x0F\xBD\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BSWAP[] = { - {I_BSWAP, 1, {REG32,0,0}, "\321\1\x0F\10\xC8", IF_486}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BT[] = { - {I_BT, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xA3\101", IF_386|IF_SM}, - {I_BT, 2, {REG16,REG16,0}, "\320\2\x0F\xA3\101", IF_386}, - {I_BT, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xA3\101", IF_386|IF_SM}, - {I_BT, 2, {REG32,REG32,0}, "\321\2\x0F\xA3\101", IF_386}, - {I_BT, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\2\x0F\xBA\204\25", IF_386|IF_SB}, - {I_BT, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\2\x0F\xBA\204\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BTC[] = { - {I_BTC, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xBB\101", IF_386|IF_SM}, - {I_BTC, 2, {REG16,REG16,0}, "\320\2\x0F\xBB\101", IF_386}, - {I_BTC, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xBB\101", IF_386|IF_SM}, - {I_BTC, 2, {REG32,REG32,0}, "\321\2\x0F\xBB\101", IF_386}, - {I_BTC, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\2\x0F\xBA\207\25", IF_386|IF_SB}, - {I_BTC, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\2\x0F\xBA\207\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BTR[] = { - {I_BTR, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xB3\101", IF_386|IF_SM}, - {I_BTR, 2, {REG16,REG16,0}, "\320\2\x0F\xB3\101", IF_386}, - {I_BTR, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xB3\101", IF_386|IF_SM}, - {I_BTR, 2, {REG32,REG32,0}, "\321\2\x0F\xB3\101", IF_386}, - {I_BTR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\2\x0F\xBA\206\25", IF_386|IF_SB}, - {I_BTR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\2\x0F\xBA\206\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_BTS[] = { - {I_BTS, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xAB\101", IF_386|IF_SM}, - {I_BTS, 2, {REG16,REG16,0}, "\320\2\x0F\xAB\101", IF_386}, - {I_BTS, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xAB\101", IF_386|IF_SM}, - {I_BTS, 2, {REG32,REG32,0}, "\321\2\x0F\xAB\101", IF_386}, - {I_BTS, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\2\x0F\xBA\205\25", IF_386|IF_SB}, - {I_BTS, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\2\x0F\xBA\205\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CALL[] = { - {I_CALL, 1, {IMMEDIATE,0,0}, "\322\1\xE8\64", IF_8086}, - {I_CALL, 1, {IMMEDIATE|NEAR,0,0}, "\322\1\xE8\64", IF_8086}, - {I_CALL, 1, {IMMEDIATE|FAR,0,0}, "\322\1\x9A\34\37", IF_8086}, - {I_CALL, 1, {IMMEDIATE|BITS16,0,0}, "\320\1\xE8\64", IF_8086}, - {I_CALL, 1, {IMMEDIATE|BITS16|NEAR,0,0}, "\320\1\xE8\64", IF_8086}, - {I_CALL, 1, {IMMEDIATE|BITS16|FAR,0,0}, "\320\1\x9A\34\37", IF_8086}, - {I_CALL, 1, {IMMEDIATE|BITS32,0,0}, "\321\1\xE8\64", IF_386}, - {I_CALL, 1, {IMMEDIATE|BITS32|NEAR,0,0}, "\321\1\xE8\64", IF_386}, - {I_CALL, 1, {IMMEDIATE|BITS32|FAR,0,0}, "\321\1\x9A\34\37", IF_386}, - {I_CALL, 2, {IMMEDIATE|COLON,IMMEDIATE,0}, "\322\1\x9A\35\30", IF_8086}, - {I_CALL, 2, {IMMEDIATE|BITS16|COLON,IMMEDIATE,0}, "\320\1\x9A\31\30", IF_8086}, - {I_CALL, 2, {IMMEDIATE|COLON,IMMEDIATE|BITS16,0}, "\320\1\x9A\31\30", IF_8086}, - {I_CALL, 2, {IMMEDIATE|BITS32|COLON,IMMEDIATE,0}, "\321\1\x9A\41\30", IF_386}, - {I_CALL, 2, {IMMEDIATE|COLON,IMMEDIATE|BITS32,0}, "\321\1\x9A\41\30", IF_386}, - {I_CALL, 1, {MEMORY|FAR,0,0}, "\322\300\1\xFF\203", IF_8086}, - {I_CALL, 1, {MEMORY|BITS16|FAR,0,0}, "\320\300\1\xFF\203", IF_8086}, - {I_CALL, 1, {MEMORY|BITS32|FAR,0,0}, "\321\300\1\xFF\203", IF_386}, - {I_CALL, 1, {MEMORY|NEAR,0,0}, "\322\300\1\xFF\202", IF_8086}, - {I_CALL, 1, {MEMORY|BITS16|NEAR,0,0}, "\320\300\1\xFF\202", IF_8086}, - {I_CALL, 1, {MEMORY|BITS32|NEAR,0,0}, "\321\300\1\xFF\202", IF_386}, - {I_CALL, 1, {REG16,0,0}, "\320\300\1\xFF\202", IF_8086}, - {I_CALL, 1, {REG32,0,0}, "\321\300\1\xFF\202", IF_386}, - {I_CALL, 1, {MEMORY,0,0}, "\322\300\1\xFF\202", IF_8086}, - {I_CALL, 1, {MEMORY|BITS16,0,0}, "\320\300\1\xFF\202", IF_8086}, - {I_CALL, 1, {MEMORY|BITS32,0,0}, "\321\300\1\xFF\202", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CBW[] = { - {I_CBW, 0, {0,0,0}, "\320\1\x98", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CDQ[] = { - {I_CDQ, 0, {0,0,0}, "\321\1\x99", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CLC[] = { - {I_CLC, 0, {0,0,0}, "\1\xF8", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CLD[] = { - {I_CLD, 0, {0,0,0}, "\1\xFC", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CLFLUSH[] = { - {I_CLFLUSH, 1, {MEMORY,0,0}, "\300\2\x0F\xAE\207", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CLI[] = { - {I_CLI, 0, {0,0,0}, "\1\xFA", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CLTS[] = { - {I_CLTS, 0, {0,0,0}, "\2\x0F\x06", IF_286|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMC[] = { - {I_CMC, 0, {0,0,0}, "\1\xF5", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMP[] = { - {I_CMP, 2, {MEMORY,REG8,0}, "\300\1\x38\101", IF_8086|IF_SM}, - {I_CMP, 2, {REG8,REG8,0}, "\1\x38\101", IF_8086}, - {I_CMP, 2, {MEMORY,REG16,0}, "\320\300\1\x39\101", IF_8086|IF_SM}, - {I_CMP, 2, {REG16,REG16,0}, "\320\1\x39\101", IF_8086}, - {I_CMP, 2, {MEMORY,REG32,0}, "\321\300\1\x39\101", IF_386|IF_SM}, - {I_CMP, 2, {REG32,REG32,0}, "\321\1\x39\101", IF_386}, - {I_CMP, 2, {REG8,MEMORY,0}, "\301\1\x3A\110", IF_8086|IF_SM}, - {I_CMP, 2, {REG8,REG8,0}, "\1\x3A\110", IF_8086}, - {I_CMP, 2, {REG16,MEMORY,0}, "\320\301\1\x3B\110", IF_8086|IF_SM}, - {I_CMP, 2, {REG16,REG16,0}, "\320\1\x3B\110", IF_8086}, - {I_CMP, 2, {REG32,MEMORY,0}, "\321\301\1\x3B\110", IF_386|IF_SM}, - {I_CMP, 2, {REG32,REG32,0}, "\321\1\x3B\110", IF_386}, - {I_CMP, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\207\15", IF_8086}, - {I_CMP, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\207\15", IF_386}, - {I_CMP, 2, {REG_AL,IMMEDIATE,0}, "\1\x3C\21", IF_8086|IF_SM}, - {I_CMP, 2, {REG_AX,SBYTE,0}, "\320\1\x83\207\15", IF_8086|IF_SM}, - {I_CMP, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x3D\31", IF_8086|IF_SM}, - {I_CMP, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\207\15", IF_386|IF_SM}, - {I_CMP, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x3D\41", IF_386|IF_SM}, - {I_CMP, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\207\21", IF_8086|IF_SM}, - {I_CMP, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\207\131", IF_8086|IF_SM}, - {I_CMP, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\207\141", IF_386|IF_SM}, - {I_CMP, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\207\21", IF_8086|IF_SM}, - {I_CMP, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\207\131", IF_8086|IF_SM}, - {I_CMP, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\207\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPEQPD[] = { - {I_CMPEQPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x00", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPEQPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x00", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPEQPS[] = { - {I_CMPEQPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x00", IF_KATMAI|IF_SSE}, - {I_CMPEQPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x00", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPEQSD[] = { - {I_CMPEQSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x00", IF_WILLAMETTE|IF_SSE2}, - {I_CMPEQSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x00", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPEQSS[] = { - {I_CMPEQSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x00", IF_KATMAI|IF_SSE}, - {I_CMPEQSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x00", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLEPD[] = { - {I_CMPLEPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x02", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPLEPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x02", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLEPS[] = { - {I_CMPLEPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x02", IF_KATMAI|IF_SSE}, - {I_CMPLEPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x02", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLESD[] = { - {I_CMPLESD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x02", IF_WILLAMETTE|IF_SSE2}, - {I_CMPLESD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x02", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLESS[] = { - {I_CMPLESS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x02", IF_KATMAI|IF_SSE}, - {I_CMPLESS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x02", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLTPD[] = { - {I_CMPLTPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x01", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPLTPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x01", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLTPS[] = { - {I_CMPLTPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x01", IF_KATMAI|IF_SSE}, - {I_CMPLTPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x01", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLTSD[] = { - {I_CMPLTSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x01", IF_WILLAMETTE|IF_SSE2}, - {I_CMPLTSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x01", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPLTSS[] = { - {I_CMPLTSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x01", IF_KATMAI|IF_SSE}, - {I_CMPLTSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x01", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNEQPD[] = { - {I_CMPNEQPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x04", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPNEQPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x04", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNEQPS[] = { - {I_CMPNEQPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x04", IF_KATMAI|IF_SSE}, - {I_CMPNEQPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x04", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNEQSD[] = { - {I_CMPNEQSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x04", IF_WILLAMETTE|IF_SSE2}, - {I_CMPNEQSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x04", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNEQSS[] = { - {I_CMPNEQSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x04", IF_KATMAI|IF_SSE}, - {I_CMPNEQSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x04", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLEPD[] = { - {I_CMPNLEPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x06", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPNLEPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x06", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLEPS[] = { - {I_CMPNLEPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x06", IF_KATMAI|IF_SSE}, - {I_CMPNLEPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x06", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLESD[] = { - {I_CMPNLESD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x06", IF_WILLAMETTE|IF_SSE2}, - {I_CMPNLESD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x06", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLESS[] = { - {I_CMPNLESS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x06", IF_KATMAI|IF_SSE}, - {I_CMPNLESS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x06", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLTPD[] = { - {I_CMPNLTPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x05", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPNLTPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x05", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLTPS[] = { - {I_CMPNLTPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x05", IF_KATMAI|IF_SSE}, - {I_CMPNLTPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x05", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLTSD[] = { - {I_CMPNLTSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x05", IF_WILLAMETTE|IF_SSE2}, - {I_CMPNLTSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x05", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPNLTSS[] = { - {I_CMPNLTSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x05", IF_KATMAI|IF_SSE}, - {I_CMPNLTSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x05", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPORDPD[] = { - {I_CMPORDPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x07", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPORDPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x07", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPORDPS[] = { - {I_CMPORDPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x07", IF_KATMAI|IF_SSE}, - {I_CMPORDPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x07", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPORDSD[] = { - {I_CMPORDSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x07", IF_WILLAMETTE|IF_SSE2}, - {I_CMPORDSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x07", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPORDSS[] = { - {I_CMPORDSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x07", IF_KATMAI|IF_SSE}, - {I_CMPORDSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x07", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPPD[] = { - {I_CMPPD, 3, {XMMREG,XMMREG,IMMEDIATE}, "\331\3\x66\x0F\xC2\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_CMPPD, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\331\3\x66\x0F\xC2\110\26", IF_WILLAMETTE|IF_SSE2|IF_SM2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPPS[] = { - {I_CMPPS, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\331\2\x0F\xC2\110\26", IF_KATMAI|IF_SSE|IF_SB|IF_AR2}, - {I_CMPPS, 3, {XMMREG,XMMREG,IMMEDIATE}, "\331\2\x0F\xC2\110\26", IF_KATMAI|IF_SSE|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPSB[] = { - {I_CMPSB, 0, {0,0,0}, "\332\1\xA6", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPSD[] = { - {I_CMPSD, 0, {0,0,0}, "\332\321\1\xA7", IF_386}, - {I_CMPSD, 3, {XMMREG,XMMREG,IMMEDIATE}, "\331\3\xF2\x0F\xC2\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_CMPSD, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\331\3\xF2\x0F\xC2\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPSS[] = { - {I_CMPSS, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\333\2\x0F\xC2\110\26", IF_KATMAI|IF_SSE|IF_SB|IF_AR2}, - {I_CMPSS, 3, {XMMREG,XMMREG,IMMEDIATE}, "\333\2\x0F\xC2\110\26", IF_KATMAI|IF_SSE|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPSW[] = { - {I_CMPSW, 0, {0,0,0}, "\332\320\1\xA7", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPUNORDPD[] = { - {I_CMPUNORDPD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\xC2\110\1\x03", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_CMPUNORDPD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\xC2\110\1\x03", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPUNORDPS[] = { - {I_CMPUNORDPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\xC2\110\1\x03", IF_KATMAI|IF_SSE}, - {I_CMPUNORDPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\xC2\110\1\x03", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPUNORDSD[] = { - {I_CMPUNORDSD, 2, {XMMREG,MEMORY,0}, "\301\331\3\xF2\x0F\xC2\110\1\x03", IF_WILLAMETTE|IF_SSE2}, - {I_CMPUNORDSD, 2, {XMMREG,XMMREG,0}, "\331\3\xF2\x0F\xC2\110\1\x03", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPUNORDSS[] = { - {I_CMPUNORDSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xC2\110\1\x03", IF_KATMAI|IF_SSE}, - {I_CMPUNORDSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xC2\110\1\x03", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPXCHG[] = { - {I_CMPXCHG, 2, {MEMORY,REG8,0}, "\300\2\x0F\xB0\101", IF_PENT|IF_SM}, - {I_CMPXCHG, 2, {REG8,REG8,0}, "\2\x0F\xB0\101", IF_PENT}, - {I_CMPXCHG, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xB1\101", IF_PENT|IF_SM}, - {I_CMPXCHG, 2, {REG16,REG16,0}, "\320\2\x0F\xB1\101", IF_PENT}, - {I_CMPXCHG, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xB1\101", IF_PENT|IF_SM}, - {I_CMPXCHG, 2, {REG32,REG32,0}, "\321\2\x0F\xB1\101", IF_PENT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPXCHG486[] = { - {I_CMPXCHG486, 2, {MEMORY,REG8,0}, "\300\2\x0F\xA6\101", IF_486|IF_SM|IF_UNDOC}, - {I_CMPXCHG486, 2, {REG8,REG8,0}, "\2\x0F\xA6\101", IF_486|IF_UNDOC}, - {I_CMPXCHG486, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xA7\101", IF_486|IF_SM|IF_UNDOC}, - {I_CMPXCHG486, 2, {REG16,REG16,0}, "\320\2\x0F\xA7\101", IF_486|IF_UNDOC}, - {I_CMPXCHG486, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xA7\101", IF_486|IF_SM|IF_UNDOC}, - {I_CMPXCHG486, 2, {REG32,REG32,0}, "\321\2\x0F\xA7\101", IF_486|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMPXCHG8B[] = { - {I_CMPXCHG8B, 1, {MEMORY,0,0}, "\300\2\x0F\xC7\201", IF_PENT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_COMISD[] = { - {I_COMISD, 2, {XMMREG,XMMREG,0}, "\331\3\x66\x0F\x2F\110", IF_WILLAMETTE|IF_SSE2}, - {I_COMISD, 2, {XMMREG,MEMORY,0}, "\301\331\3\x66\x0F\x2F\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_COMISS[] = { - {I_COMISS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x2F\110", IF_KATMAI|IF_SSE}, - {I_COMISS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x2F\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CPUID[] = { - {I_CPUID, 0, {0,0,0}, "\2\x0F\xA2", IF_PENT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTDQ2PD[] = { - {I_CVTDQ2PD, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\xE6\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTDQ2PD, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\xE6\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTDQ2PS[] = { - {I_CVTDQ2PS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x5B\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTDQ2PS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x5B\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPD2DQ[] = { - {I_CVTPD2DQ, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\xE6\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTPD2DQ, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\xE6\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPD2PI[] = { - {I_CVTPD2PI, 2, {MMXREG,XMMREG,0}, "\3\x66\x0F\x2D\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTPD2PI, 2, {MMXREG,MEMORY,0}, "\301\3\x66\x0F\x2D\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPD2PS[] = { - {I_CVTPD2PS, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTPD2PS, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPI2PD[] = { - {I_CVTPI2PD, 2, {XMMREG,MMXREG,0}, "\3\x66\x0F\x2A\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTPI2PD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x2A\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPI2PS[] = { - {I_CVTPI2PS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x2A\110", IF_KATMAI|IF_SSE|IF_MMX}, - {I_CVTPI2PS, 2, {XMMREG,MMXREG,0}, "\331\2\x0F\x2A\110", IF_KATMAI|IF_SSE|IF_MMX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPS2DQ[] = { - {I_CVTPS2DQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x5B\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTPS2DQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x5B\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPS2PD[] = { - {I_CVTPS2PD, 2, {XMMREG,XMMREG,0}, "\2\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTPS2PD, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTPS2PI[] = { - {I_CVTPS2PI, 2, {MMXREG,MEMORY,0}, "\301\331\2\x0F\x2D\110", IF_KATMAI|IF_SSE|IF_MMX}, - {I_CVTPS2PI, 2, {MMXREG,XMMREG,0}, "\331\2\x0F\x2D\110", IF_KATMAI|IF_SSE|IF_MMX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTSD2SI[] = { - {I_CVTSD2SI, 2, {REG32,XMMREG,0}, "\3\xF2\x0F\x2D\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTSD2SI, 2, {REG32,MEMORY,0}, "\301\3\xF2\x0F\x2D\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTSD2SS[] = { - {I_CVTSD2SS, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTSD2SS, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTSI2SD[] = { - {I_CVTSI2SD, 2, {XMMREG,REG32,0}, "\3\xF2\x0F\x2A\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTSI2SD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x2A\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTSI2SS[] = { - {I_CVTSI2SS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x2A\110", IF_KATMAI|IF_SSE|IF_SD|IF_AR1}, - {I_CVTSI2SS, 2, {XMMREG,REG32,0}, "\333\2\x0F\x2A\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTSS2SD[] = { - {I_CVTSS2SD, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTSS2SD, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x5A\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTSS2SI[] = { - {I_CVTSS2SI, 2, {REG32,MEMORY,0}, "\301\333\2\x0F\x2D\110", IF_KATMAI|IF_SSE}, - {I_CVTSS2SI, 2, {REG32,XMMREG,0}, "\333\2\x0F\x2D\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTTPD2DQ[] = { - {I_CVTTPD2DQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE6\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTTPD2DQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE6\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTTPD2PI[] = { - {I_CVTTPD2PI, 2, {MMXREG,XMMREG,0}, "\3\x66\x0F\x2C\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTTPD2PI, 2, {MMXREG,MEMORY,0}, "\301\3\x66\x0F\x2C\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTTPS2DQ[] = { - {I_CVTTPS2DQ, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x5B\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTTPS2DQ, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x5B\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTTPS2PI[] = { - {I_CVTTPS2PI, 2, {MMXREG,MEMORY,0}, "\301\331\2\x0F\x2C\110", IF_KATMAI|IF_SSE|IF_MMX}, - {I_CVTTPS2PI, 2, {MMXREG,XMMREG,0}, "\331\2\x0F\x2C\110", IF_KATMAI|IF_SSE|IF_MMX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTTSD2SI[] = { - {I_CVTTSD2SI, 2, {REG32,XMMREG,0}, "\3\xF2\x0F\x2C\110", IF_WILLAMETTE|IF_SSE2}, - {I_CVTTSD2SI, 2, {REG32,MEMORY,0}, "\301\3\xF2\x0F\x2C\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CVTTSS2SI[] = { - {I_CVTTSS2SI, 2, {REG32,MEMORY,0}, "\301\333\2\x0F\x2C\110", IF_KATMAI|IF_SSE}, - {I_CVTTSS2SI, 2, {REG32,XMMREG,0}, "\333\2\x0F\x2C\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CWD[] = { - {I_CWD, 0, {0,0,0}, "\320\1\x99", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CWDE[] = { - {I_CWDE, 0, {0,0,0}, "\321\1\x98", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DAA[] = { - {I_DAA, 0, {0,0,0}, "\1\x27", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DAS[] = { - {I_DAS, 0, {0,0,0}, "\1\x2F", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DB[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_DD[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_DEC[] = { - {I_DEC, 1, {REG16,0,0}, "\320\10\x48", IF_8086}, - {I_DEC, 1, {REG32,0,0}, "\321\10\x48", IF_386}, - {I_DEC, 1, {REGMEM|BITS8,0,0}, "\300\1\xFE\201", IF_8086}, - {I_DEC, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xFF\201", IF_8086}, - {I_DEC, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xFF\201", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DIV[] = { - {I_DIV, 1, {REGMEM|BITS8,0,0}, "\300\1\xF6\206", IF_8086}, - {I_DIV, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xF7\206", IF_8086}, - {I_DIV, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xF7\206", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DIVPD[] = { - {I_DIVPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x5E\110", IF_WILLAMETTE|IF_SSE2}, - {I_DIVPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x5E\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DIVPS[] = { - {I_DIVPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x5E\110", IF_KATMAI|IF_SSE}, - {I_DIVPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x5E\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DIVSD[] = { - {I_DIVSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x5E\110", IF_WILLAMETTE|IF_SSE2}, - {I_DIVSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x5E\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DIVSS[] = { - {I_DIVSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x5E\110", IF_KATMAI|IF_SSE}, - {I_DIVSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x5E\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_DQ[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_DT[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_DW[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_EMMS[] = { - {I_EMMS, 0, {0,0,0}, "\2\x0F\x77", IF_PENT|IF_MMX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ENTER[] = { - {I_ENTER, 2, {IMMEDIATE,IMMEDIATE,0}, "\1\xC8\30\25", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_EQU[] = { - {I_EQU, 1, {IMMEDIATE,0,0}, "\0", IF_8086}, - {I_EQU, 2, {IMMEDIATE|COLON,IMMEDIATE,0}, "\0", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_F2XM1[] = { - {I_F2XM1, 0, {0,0,0}, "\2\xD9\xF0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FABS[] = { - {I_FABS, 0, {0,0,0}, "\2\xD9\xE1", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FADD[] = { - {I_FADD, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\200", IF_8086|IF_FPU}, - {I_FADD, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\200", IF_8086|IF_FPU}, - {I_FADD, 1, {FPUREG|TO,0,0}, "\1\xDC\10\xC0", IF_8086|IF_FPU}, - {I_FADD, 1, {FPUREG,0,0}, "\1\xD8\10\xC0", IF_8086|IF_FPU}, - {I_FADD, 2, {FPUREG,FPU0,0}, "\1\xDC\10\xC0", IF_8086|IF_FPU}, - {I_FADD, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xC0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FADDP[] = { - {I_FADDP, 1, {FPUREG,0,0}, "\1\xDE\10\xC0", IF_8086|IF_FPU}, - {I_FADDP, 2, {FPUREG,FPU0,0}, "\1\xDE\10\xC0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FBLD[] = { - {I_FBLD, 1, {MEMORY|BITS80,0,0}, "\300\1\xDF\204", IF_8086|IF_FPU}, - {I_FBLD, 1, {MEMORY,0,0}, "\300\1\xDF\204", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FBSTP[] = { - {I_FBSTP, 1, {MEMORY|BITS80,0,0}, "\300\1\xDF\206", IF_8086|IF_FPU}, - {I_FBSTP, 1, {MEMORY,0,0}, "\300\1\xDF\206", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCHS[] = { - {I_FCHS, 0, {0,0,0}, "\2\xD9\xE0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCLEX[] = { - {I_FCLEX, 0, {0,0,0}, "\3\x9B\xDB\xE2", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVB[] = { - {I_FCMOVB, 1, {FPUREG,0,0}, "\1\xDA\10\xC0", IF_P6|IF_FPU}, - {I_FCMOVB, 2, {FPU0,FPUREG,0}, "\1\xDA\11\xC0", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVBE[] = { - {I_FCMOVBE, 1, {FPUREG,0,0}, "\1\xDA\10\xD0", IF_P6|IF_FPU}, - {I_FCMOVBE, 2, {FPU0,FPUREG,0}, "\1\xDA\11\xD0", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVE[] = { - {I_FCMOVE, 1, {FPUREG,0,0}, "\1\xDA\10\xC8", IF_P6|IF_FPU}, - {I_FCMOVE, 2, {FPU0,FPUREG,0}, "\1\xDA\11\xC8", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVNB[] = { - {I_FCMOVNB, 1, {FPUREG,0,0}, "\1\xDB\10\xC0", IF_P6|IF_FPU}, - {I_FCMOVNB, 2, {FPU0,FPUREG,0}, "\1\xDB\11\xC0", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVNBE[] = { - {I_FCMOVNBE, 1, {FPUREG,0,0}, "\1\xDB\10\xD0", IF_P6|IF_FPU}, - {I_FCMOVNBE, 2, {FPU0,FPUREG,0}, "\1\xDB\11\xD0", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVNE[] = { - {I_FCMOVNE, 1, {FPUREG,0,0}, "\1\xDB\10\xC8", IF_P6|IF_FPU}, - {I_FCMOVNE, 2, {FPU0,FPUREG,0}, "\1\xDB\11\xC8", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVNU[] = { - {I_FCMOVNU, 1, {FPUREG,0,0}, "\1\xDB\10\xD8", IF_P6|IF_FPU}, - {I_FCMOVNU, 2, {FPU0,FPUREG,0}, "\1\xDB\11\xD8", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCMOVU[] = { - {I_FCMOVU, 1, {FPUREG,0,0}, "\1\xDA\10\xD8", IF_P6|IF_FPU}, - {I_FCMOVU, 2, {FPU0,FPUREG,0}, "\1\xDA\11\xD8", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCOM[] = { - {I_FCOM, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\202", IF_8086|IF_FPU}, - {I_FCOM, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\202", IF_8086|IF_FPU}, - {I_FCOM, 1, {FPUREG,0,0}, "\1\xD8\10\xD0", IF_8086|IF_FPU}, - {I_FCOM, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xD0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCOMI[] = { - {I_FCOMI, 1, {FPUREG,0,0}, "\1\xDB\10\xF0", IF_P6|IF_FPU}, - {I_FCOMI, 2, {FPU0,FPUREG,0}, "\1\xDB\11\xF0", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCOMIP[] = { - {I_FCOMIP, 1, {FPUREG,0,0}, "\1\xDF\10\xF0", IF_P6|IF_FPU}, - {I_FCOMIP, 2, {FPU0,FPUREG,0}, "\1\xDF\11\xF0", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCOMP[] = { - {I_FCOMP, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\203", IF_8086|IF_FPU}, - {I_FCOMP, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\203", IF_8086|IF_FPU}, - {I_FCOMP, 1, {FPUREG,0,0}, "\1\xD8\10\xD8", IF_8086|IF_FPU}, - {I_FCOMP, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xD8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCOMPP[] = { - {I_FCOMPP, 0, {0,0,0}, "\2\xDE\xD9", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FCOS[] = { - {I_FCOS, 0, {0,0,0}, "\2\xD9\xFF", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FDECSTP[] = { - {I_FDECSTP, 0, {0,0,0}, "\2\xD9\xF6", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FDISI[] = { - {I_FDISI, 0, {0,0,0}, "\3\x9B\xDB\xE1", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FDIV[] = { - {I_FDIV, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\206", IF_8086|IF_FPU}, - {I_FDIV, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\206", IF_8086|IF_FPU}, - {I_FDIV, 1, {FPUREG|TO,0,0}, "\1\xDC\10\xF8", IF_8086|IF_FPU}, - {I_FDIV, 2, {FPUREG,FPU0,0}, "\1\xDC\10\xF8", IF_8086|IF_FPU}, - {I_FDIV, 1, {FPUREG,0,0}, "\1\xD8\10\xF0", IF_8086|IF_FPU}, - {I_FDIV, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xF0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FDIVP[] = { - {I_FDIVP, 2, {FPUREG,FPU0,0}, "\1\xDE\10\xF8", IF_8086|IF_FPU}, - {I_FDIVP, 1, {FPUREG,0,0}, "\1\xDE\10\xF8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FDIVR[] = { - {I_FDIVR, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\207", IF_8086|IF_FPU}, - {I_FDIVR, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\207", IF_8086|IF_FPU}, - {I_FDIVR, 1, {FPUREG|TO,0,0}, "\1\xDC\10\xF0", IF_8086|IF_FPU}, - {I_FDIVR, 2, {FPUREG,FPU0,0}, "\1\xDC\10\xF0", IF_8086|IF_FPU}, - {I_FDIVR, 1, {FPUREG,0,0}, "\1\xD8\10\xF8", IF_8086|IF_FPU}, - {I_FDIVR, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xF8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FDIVRP[] = { - {I_FDIVRP, 1, {FPUREG,0,0}, "\1\xDE\10\xF0", IF_8086|IF_FPU}, - {I_FDIVRP, 2, {FPUREG,FPU0,0}, "\1\xDE\10\xF0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FEMMS[] = { - {I_FEMMS, 0, {0,0,0}, "\2\x0F\x0E", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FENI[] = { - {I_FENI, 0, {0,0,0}, "\3\x9B\xDB\xE0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FFREE[] = { - {I_FFREE, 1, {FPUREG,0,0}, "\1\xDD\10\xC0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FFREEP[] = { - {I_FFREEP, 1, {FPUREG,0,0}, "\1\xDF\10\xC0", IF_286|IF_FPU|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FIADD[] = { - {I_FIADD, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\200", IF_8086|IF_FPU}, - {I_FIADD, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\200", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FICOM[] = { - {I_FICOM, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\202", IF_8086|IF_FPU}, - {I_FICOM, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\202", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FICOMP[] = { - {I_FICOMP, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\203", IF_8086|IF_FPU}, - {I_FICOMP, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\203", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FIDIV[] = { - {I_FIDIV, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\206", IF_8086|IF_FPU}, - {I_FIDIV, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\206", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FIDIVR[] = { - {I_FIDIVR, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\207", IF_8086|IF_FPU}, - {I_FIDIVR, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\207", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FILD[] = { - {I_FILD, 1, {MEMORY|BITS32,0,0}, "\300\1\xDB\200", IF_8086|IF_FPU}, - {I_FILD, 1, {MEMORY|BITS16,0,0}, "\300\1\xDF\200", IF_8086|IF_FPU}, - {I_FILD, 1, {MEMORY|BITS64,0,0}, "\300\1\xDF\205", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FIMUL[] = { - {I_FIMUL, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\201", IF_8086|IF_FPU}, - {I_FIMUL, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\201", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FINCSTP[] = { - {I_FINCSTP, 0, {0,0,0}, "\2\xD9\xF7", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FINIT[] = { - {I_FINIT, 0, {0,0,0}, "\3\x9B\xDB\xE3", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FIST[] = { - {I_FIST, 1, {MEMORY|BITS32,0,0}, "\300\1\xDB\202", IF_8086|IF_FPU}, - {I_FIST, 1, {MEMORY|BITS16,0,0}, "\300\1\xDF\202", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FISTP[] = { - {I_FISTP, 1, {MEMORY|BITS32,0,0}, "\300\1\xDB\203", IF_8086|IF_FPU}, - {I_FISTP, 1, {MEMORY|BITS16,0,0}, "\300\1\xDF\203", IF_8086|IF_FPU}, - {I_FISTP, 1, {MEMORY|BITS64,0,0}, "\300\1\xDF\207", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FISTTP[] = { - {I_FISTTP, 1, {MEMORY|BITS32,0,0}, "\300\1\xDD\201", IF_PRESCOTT|IF_FPU}, - {I_FISTTP, 1, {MEMORY|BITS16,0,0}, "\300\1\xDB\201", IF_PRESCOTT|IF_FPU}, - {I_FISTTP, 1, {MEMORY|BITS64,0,0}, "\300\1\xDF\201", IF_PRESCOTT|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FISUB[] = { - {I_FISUB, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\204", IF_8086|IF_FPU}, - {I_FISUB, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\204", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FISUBR[] = { - {I_FISUBR, 1, {MEMORY|BITS32,0,0}, "\300\1\xDA\205", IF_8086|IF_FPU}, - {I_FISUBR, 1, {MEMORY|BITS16,0,0}, "\300\1\xDE\205", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLD[] = { - {I_FLD, 1, {MEMORY|BITS32,0,0}, "\300\1\xD9\200", IF_8086|IF_FPU}, - {I_FLD, 1, {MEMORY|BITS64,0,0}, "\300\1\xDD\200", IF_8086|IF_FPU}, - {I_FLD, 1, {MEMORY|BITS80,0,0}, "\300\1\xDB\205", IF_8086|IF_FPU}, - {I_FLD, 1, {FPUREG,0,0}, "\1\xD9\10\xC0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLD1[] = { - {I_FLD1, 0, {0,0,0}, "\2\xD9\xE8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDCW[] = { - {I_FLDCW, 1, {MEMORY,0,0}, "\300\1\xD9\205", IF_8086|IF_FPU|IF_SW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDENV[] = { - {I_FLDENV, 1, {MEMORY,0,0}, "\300\1\xD9\204", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDL2E[] = { - {I_FLDL2E, 0, {0,0,0}, "\2\xD9\xEA", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDL2T[] = { - {I_FLDL2T, 0, {0,0,0}, "\2\xD9\xE9", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDLG2[] = { - {I_FLDLG2, 0, {0,0,0}, "\2\xD9\xEC", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDLN2[] = { - {I_FLDLN2, 0, {0,0,0}, "\2\xD9\xED", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDPI[] = { - {I_FLDPI, 0, {0,0,0}, "\2\xD9\xEB", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FLDZ[] = { - {I_FLDZ, 0, {0,0,0}, "\2\xD9\xEE", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FMUL[] = { - {I_FMUL, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\201", IF_8086|IF_FPU}, - {I_FMUL, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\201", IF_8086|IF_FPU}, - {I_FMUL, 1, {FPUREG|TO,0,0}, "\1\xDC\10\xC8", IF_8086|IF_FPU}, - {I_FMUL, 2, {FPUREG,FPU0,0}, "\1\xDC\10\xC8", IF_8086|IF_FPU}, - {I_FMUL, 1, {FPUREG,0,0}, "\1\xD8\10\xC8", IF_8086|IF_FPU}, - {I_FMUL, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xC8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FMULP[] = { - {I_FMULP, 1, {FPUREG,0,0}, "\1\xDE\10\xC8", IF_8086|IF_FPU}, - {I_FMULP, 2, {FPUREG,FPU0,0}, "\1\xDE\10\xC8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNCLEX[] = { - {I_FNCLEX, 0, {0,0,0}, "\2\xDB\xE2", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNDISI[] = { - {I_FNDISI, 0, {0,0,0}, "\2\xDB\xE1", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNENI[] = { - {I_FNENI, 0, {0,0,0}, "\2\xDB\xE0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNINIT[] = { - {I_FNINIT, 0, {0,0,0}, "\2\xDB\xE3", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNOP[] = { - {I_FNOP, 0, {0,0,0}, "\2\xD9\xD0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNSAVE[] = { - {I_FNSAVE, 1, {MEMORY,0,0}, "\300\1\xDD\206", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNSTCW[] = { - {I_FNSTCW, 1, {MEMORY,0,0}, "\300\1\xD9\207", IF_8086|IF_FPU|IF_SW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNSTENV[] = { - {I_FNSTENV, 1, {MEMORY,0,0}, "\300\1\xD9\206", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FNSTSW[] = { - {I_FNSTSW, 1, {MEMORY,0,0}, "\300\1\xDD\207", IF_8086|IF_FPU|IF_SW}, - {I_FNSTSW, 1, {REG_AX,0,0}, "\2\xDF\xE0", IF_286|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FPATAN[] = { - {I_FPATAN, 0, {0,0,0}, "\2\xD9\xF3", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FPREM[] = { - {I_FPREM, 0, {0,0,0}, "\2\xD9\xF8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FPREM1[] = { - {I_FPREM1, 0, {0,0,0}, "\2\xD9\xF5", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FPTAN[] = { - {I_FPTAN, 0, {0,0,0}, "\2\xD9\xF2", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FRNDINT[] = { - {I_FRNDINT, 0, {0,0,0}, "\2\xD9\xFC", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FRSTOR[] = { - {I_FRSTOR, 1, {MEMORY,0,0}, "\300\1\xDD\204", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSAVE[] = { - {I_FSAVE, 1, {MEMORY,0,0}, "\300\2\x9B\xDD\206", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSCALE[] = { - {I_FSCALE, 0, {0,0,0}, "\2\xD9\xFD", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSETPM[] = { - {I_FSETPM, 0, {0,0,0}, "\2\xDB\xE4", IF_286|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSIN[] = { - {I_FSIN, 0, {0,0,0}, "\2\xD9\xFE", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSINCOS[] = { - {I_FSINCOS, 0, {0,0,0}, "\2\xD9\xFB", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSQRT[] = { - {I_FSQRT, 0, {0,0,0}, "\2\xD9\xFA", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FST[] = { - {I_FST, 1, {MEMORY|BITS32,0,0}, "\300\1\xD9\202", IF_8086|IF_FPU}, - {I_FST, 1, {MEMORY|BITS64,0,0}, "\300\1\xDD\202", IF_8086|IF_FPU}, - {I_FST, 1, {FPUREG,0,0}, "\1\xDD\10\xD0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSTCW[] = { - {I_FSTCW, 1, {MEMORY,0,0}, "\300\2\x9B\xD9\207", IF_8086|IF_FPU|IF_SW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSTENV[] = { - {I_FSTENV, 1, {MEMORY,0,0}, "\300\2\x9B\xD9\206", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSTP[] = { - {I_FSTP, 1, {MEMORY|BITS32,0,0}, "\300\1\xD9\203", IF_8086|IF_FPU}, - {I_FSTP, 1, {MEMORY|BITS64,0,0}, "\300\1\xDD\203", IF_8086|IF_FPU}, - {I_FSTP, 1, {MEMORY|BITS80,0,0}, "\300\1\xDB\207", IF_8086|IF_FPU}, - {I_FSTP, 1, {FPUREG,0,0}, "\1\xDD\10\xD8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSTSW[] = { - {I_FSTSW, 1, {MEMORY,0,0}, "\300\2\x9B\xDD\207", IF_8086|IF_FPU|IF_SW}, - {I_FSTSW, 1, {REG_AX,0,0}, "\3\x9B\xDF\xE0", IF_286|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSUB[] = { - {I_FSUB, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\204", IF_8086|IF_FPU}, - {I_FSUB, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\204", IF_8086|IF_FPU}, - {I_FSUB, 1, {FPUREG|TO,0,0}, "\1\xDC\10\xE8", IF_8086|IF_FPU}, - {I_FSUB, 2, {FPUREG,FPU0,0}, "\1\xDC\10\xE8", IF_8086|IF_FPU}, - {I_FSUB, 1, {FPUREG,0,0}, "\1\xD8\10\xE0", IF_8086|IF_FPU}, - {I_FSUB, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xE0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSUBP[] = { - {I_FSUBP, 1, {FPUREG,0,0}, "\1\xDE\10\xE8", IF_8086|IF_FPU}, - {I_FSUBP, 2, {FPUREG,FPU0,0}, "\1\xDE\10\xE8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSUBR[] = { - {I_FSUBR, 1, {MEMORY|BITS32,0,0}, "\300\1\xD8\205", IF_8086|IF_FPU}, - {I_FSUBR, 1, {MEMORY|BITS64,0,0}, "\300\1\xDC\205", IF_8086|IF_FPU}, - {I_FSUBR, 1, {FPUREG|TO,0,0}, "\1\xDC\10\xE0", IF_8086|IF_FPU}, - {I_FSUBR, 2, {FPUREG,FPU0,0}, "\1\xDC\10\xE0", IF_8086|IF_FPU}, - {I_FSUBR, 1, {FPUREG,0,0}, "\1\xD8\10\xE8", IF_8086|IF_FPU}, - {I_FSUBR, 2, {FPU0,FPUREG,0}, "\1\xD8\11\xE8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FSUBRP[] = { - {I_FSUBRP, 1, {FPUREG,0,0}, "\1\xDE\10\xE0", IF_8086|IF_FPU}, - {I_FSUBRP, 2, {FPUREG,FPU0,0}, "\1\xDE\10\xE0", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FTST[] = { - {I_FTST, 0, {0,0,0}, "\2\xD9\xE4", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FUCOM[] = { - {I_FUCOM, 1, {FPUREG,0,0}, "\1\xDD\10\xE0", IF_386|IF_FPU}, - {I_FUCOM, 2, {FPU0,FPUREG,0}, "\1\xDD\11\xE0", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FUCOMI[] = { - {I_FUCOMI, 1, {FPUREG,0,0}, "\1\xDB\10\xE8", IF_P6|IF_FPU}, - {I_FUCOMI, 2, {FPU0,FPUREG,0}, "\1\xDB\11\xE8", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FUCOMIP[] = { - {I_FUCOMIP, 1, {FPUREG,0,0}, "\1\xDF\10\xE8", IF_P6|IF_FPU}, - {I_FUCOMIP, 2, {FPU0,FPUREG,0}, "\1\xDF\11\xE8", IF_P6|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FUCOMP[] = { - {I_FUCOMP, 1, {FPUREG,0,0}, "\1\xDD\10\xE8", IF_386|IF_FPU}, - {I_FUCOMP, 2, {FPU0,FPUREG,0}, "\1\xDD\11\xE8", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FUCOMPP[] = { - {I_FUCOMPP, 0, {0,0,0}, "\2\xDA\xE9", IF_386|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FWAIT[] = { - {I_FWAIT, 0, {0,0,0}, "\1\x9B", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FXAM[] = { - {I_FXAM, 0, {0,0,0}, "\2\xD9\xE5", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FXCH[] = { - {I_FXCH, 0, {0,0,0}, "\2\xD9\xC9", IF_8086|IF_FPU}, - {I_FXCH, 1, {FPUREG,0,0}, "\1\xD9\10\xC8", IF_8086|IF_FPU}, - {I_FXCH, 2, {FPUREG,FPU0,0}, "\1\xD9\10\xC8", IF_8086|IF_FPU}, - {I_FXCH, 2, {FPU0,FPUREG,0}, "\1\xD9\11\xC8", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FXRSTOR[] = { - {I_FXRSTOR, 1, {MEMORY,0,0}, "\300\2\x0F\xAE\201", IF_P6|IF_SSE|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FXSAVE[] = { - {I_FXSAVE, 1, {MEMORY,0,0}, "\300\2\x0F\xAE\200", IF_P6|IF_SSE|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FXTRACT[] = { - {I_FXTRACT, 0, {0,0,0}, "\2\xD9\xF4", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FYL2X[] = { - {I_FYL2X, 0, {0,0,0}, "\2\xD9\xF1", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_FYL2XP1[] = { - {I_FYL2XP1, 0, {0,0,0}, "\2\xD9\xF9", IF_8086|IF_FPU}, - ITEMPLATE_END -}; - -static struct itemplate instrux_HADDPD[] = { - {I_HADDPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x7C\110", IF_PRESCOTT|IF_SSE3|IF_SM}, - {I_HADDPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x7C\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_HADDPS[] = { - {I_HADDPS, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x7C\110", IF_PRESCOTT|IF_SSE3|IF_SM}, - {I_HADDPS, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x7C\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_HLT[] = { - {I_HLT, 0, {0,0,0}, "\1\xF4", IF_8086|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_HSUBPD[] = { - {I_HSUBPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x7D\110", IF_PRESCOTT|IF_SSE3|IF_SM}, - {I_HSUBPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x7D\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_HSUBPS[] = { - {I_HSUBPS, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x7D\110", IF_PRESCOTT|IF_SSE3|IF_SM}, - {I_HSUBPS, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x7D\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IBTS[] = { - {I_IBTS, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xA7\101", IF_386|IF_SW|IF_UNDOC}, - {I_IBTS, 2, {REG16,REG16,0}, "\320\2\x0F\xA7\101", IF_386|IF_UNDOC}, - {I_IBTS, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xA7\101", IF_386|IF_SD|IF_UNDOC}, - {I_IBTS, 2, {REG32,REG32,0}, "\321\2\x0F\xA7\101", IF_386|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ICEBP[] = { - {I_ICEBP, 0, {0,0,0}, "\1\xF1", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IDIV[] = { - {I_IDIV, 1, {REGMEM|BITS8,0,0}, "\300\1\xF6\207", IF_8086}, - {I_IDIV, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xF7\207", IF_8086}, - {I_IDIV, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xF7\207", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IMUL[] = { - {I_IMUL, 1, {REGMEM|BITS8,0,0}, "\300\1\xF6\205", IF_8086}, - {I_IMUL, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xF7\205", IF_8086}, - {I_IMUL, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xF7\205", IF_386}, - {I_IMUL, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xAF\110", IF_386|IF_SM}, - {I_IMUL, 2, {REG16,REG16,0}, "\320\2\x0F\xAF\110", IF_386}, - {I_IMUL, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xAF\110", IF_386|IF_SM}, - {I_IMUL, 2, {REG32,REG32,0}, "\321\2\x0F\xAF\110", IF_386}, - {I_IMUL, 3, {REG16,MEMORY,IMMEDIATE|BITS8}, "\320\301\1\x6B\110\16", IF_186|IF_SM}, - {I_IMUL, 3, {REG16,MEMORY,SBYTE}, "\320\301\1\x6B\110\16", IF_186|IF_SM}, - {I_IMUL, 3, {REG16,MEMORY,IMMEDIATE|BITS16}, "\320\301\1\x69\110\32", IF_186|IF_SM}, - {I_IMUL, 3, {REG16,MEMORY,IMMEDIATE}, "\320\301\135\1\x69\110\132", IF_186|IF_SM}, - {I_IMUL, 3, {REG16,REG16,IMMEDIATE|BITS8}, "\320\1\x6B\110\16", IF_186}, - {I_IMUL, 3, {REG16,REG16,SBYTE}, "\320\1\x6B\110\16", IF_186|IF_SM}, - {I_IMUL, 3, {REG16,REG16,IMMEDIATE|BITS16}, "\320\1\x69\110\32", IF_186}, - {I_IMUL, 3, {REG16,REG16,IMMEDIATE}, "\320\135\1\x69\110\132", IF_186|IF_SM}, - {I_IMUL, 3, {REG32,MEMORY,IMMEDIATE|BITS8}, "\321\301\1\x6B\110\16", IF_386|IF_SM}, - {I_IMUL, 3, {REG32,MEMORY,SBYTE}, "\321\301\1\x6B\110\16", IF_386|IF_SM}, - {I_IMUL, 3, {REG32,MEMORY,IMMEDIATE|BITS32}, "\321\301\1\x69\110\42", IF_386|IF_SM}, - {I_IMUL, 3, {REG32,MEMORY,IMMEDIATE}, "\321\301\145\1\x69\110\142", IF_386|IF_SM}, - {I_IMUL, 3, {REG32,REG32,IMMEDIATE|BITS8}, "\321\1\x6B\110\16", IF_386}, - {I_IMUL, 3, {REG32,REG32,SBYTE}, "\321\1\x6B\110\16", IF_386|IF_SM}, - {I_IMUL, 3, {REG32,REG32,IMMEDIATE|BITS32}, "\321\1\x69\110\42", IF_386}, - {I_IMUL, 3, {REG32,REG32,IMMEDIATE}, "\321\145\1\x69\110\142", IF_386|IF_SM}, - {I_IMUL, 2, {REG16,IMMEDIATE|BITS8,0}, "\320\1\x6B\100\15", IF_186}, - {I_IMUL, 2, {REG16,SBYTE,0}, "\320\1\x6B\100\15", IF_186|IF_SM}, - {I_IMUL, 2, {REG16,IMMEDIATE|BITS16,0}, "\320\1\x69\100\31", IF_186}, - {I_IMUL, 2, {REG16,IMMEDIATE,0}, "\320\134\1\x69\100\131", IF_186|IF_SM}, - {I_IMUL, 2, {REG32,IMMEDIATE|BITS8,0}, "\321\1\x6B\100\15", IF_386}, - {I_IMUL, 2, {REG32,SBYTE,0}, "\321\1\x6B\100\15", IF_386|IF_SM}, - {I_IMUL, 2, {REG32,IMMEDIATE|BITS32,0}, "\321\1\x69\100\41", IF_386}, - {I_IMUL, 2, {REG32,IMMEDIATE,0}, "\321\144\1\x69\100\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IN[] = { - {I_IN, 2, {REG_AL,IMMEDIATE,0}, "\1\xE4\25", IF_8086|IF_SB}, - {I_IN, 2, {REG_AX,IMMEDIATE,0}, "\320\1\xE5\25", IF_8086|IF_SB}, - {I_IN, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\xE5\25", IF_386|IF_SB}, - {I_IN, 2, {REG_AL,REG_DX,0}, "\1\xEC", IF_8086}, - {I_IN, 2, {REG_AX,REG_DX,0}, "\320\1\xED", IF_8086}, - {I_IN, 2, {REG_EAX,REG_DX,0}, "\321\1\xED", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INC[] = { - {I_INC, 1, {REG16,0,0}, "\320\10\x40", IF_8086}, - {I_INC, 1, {REG32,0,0}, "\321\10\x40", IF_386}, - {I_INC, 1, {REGMEM|BITS8,0,0}, "\300\1\xFE\200", IF_8086}, - {I_INC, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xFF\200", IF_8086}, - {I_INC, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xFF\200", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INCBIN[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_INSB[] = { - {I_INSB, 0, {0,0,0}, "\1\x6C", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INSD[] = { - {I_INSD, 0, {0,0,0}, "\321\1\x6D", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INSW[] = { - {I_INSW, 0, {0,0,0}, "\320\1\x6D", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INT[] = { - {I_INT, 1, {IMMEDIATE,0,0}, "\1\xCD\24", IF_8086|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INT01[] = { - {I_INT01, 0, {0,0,0}, "\1\xF1", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INT03[] = { - {I_INT03, 0, {0,0,0}, "\1\xCC", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INT1[] = { - {I_INT1, 0, {0,0,0}, "\1\xF1", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INT3[] = { - {I_INT3, 0, {0,0,0}, "\1\xCC", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INTO[] = { - {I_INTO, 0, {0,0,0}, "\1\xCE", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INVD[] = { - {I_INVD, 0, {0,0,0}, "\2\x0F\x08", IF_486|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_INVLPG[] = { - {I_INVLPG, 1, {MEMORY,0,0}, "\300\2\x0F\x01\207", IF_486|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IRET[] = { - {I_IRET, 0, {0,0,0}, "\322\1\xCF", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IRETD[] = { - {I_IRETD, 0, {0,0,0}, "\321\1\xCF", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_IRETW[] = { - {I_IRETW, 0, {0,0,0}, "\320\1\xCF", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_JCXZ[] = { - {I_JCXZ, 1, {IMMEDIATE,0,0}, "\310\1\xE3\50", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_JECXZ[] = { - {I_JECXZ, 1, {IMMEDIATE,0,0}, "\311\1\xE3\50", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_JMP[] = { - {I_JMP, 1, {IMMEDIATE|SHORT,0,0}, "\1\xEB\50", IF_8086}, - {I_JMP, 1, {IMMEDIATE,0,0}, "\371\1\xEB\50", IF_8086}, - {I_JMP, 1, {IMMEDIATE,0,0}, "\322\1\xE9\64", IF_8086}, - {I_JMP, 1, {IMMEDIATE|NEAR,0,0}, "\322\1\xE9\64", IF_8086}, - {I_JMP, 1, {IMMEDIATE|FAR,0,0}, "\322\1\xEA\34\37", IF_8086}, - {I_JMP, 1, {IMMEDIATE|BITS16,0,0}, "\320\1\xE9\64", IF_8086}, - {I_JMP, 1, {IMMEDIATE|BITS16|NEAR,0,0}, "\320\1\xE9\64", IF_8086}, - {I_JMP, 1, {IMMEDIATE|BITS16|FAR,0,0}, "\320\1\xEA\34\37", IF_8086}, - {I_JMP, 1, {IMMEDIATE|BITS32,0,0}, "\321\1\xE9\64", IF_386}, - {I_JMP, 1, {IMMEDIATE|BITS32|NEAR,0,0}, "\321\1\xE9\64", IF_386}, - {I_JMP, 1, {IMMEDIATE|BITS32|FAR,0,0}, "\321\1\xEA\34\37", IF_386}, - {I_JMP, 2, {IMMEDIATE|COLON,IMMEDIATE,0}, "\322\1\xEA\35\30", IF_8086}, - {I_JMP, 2, {IMMEDIATE|BITS16|COLON,IMMEDIATE,0}, "\320\1\xEA\31\30", IF_8086}, - {I_JMP, 2, {IMMEDIATE|COLON,IMMEDIATE|BITS16,0}, "\320\1\xEA\31\30", IF_8086}, - {I_JMP, 2, {IMMEDIATE|BITS32|COLON,IMMEDIATE,0}, "\321\1\xEA\41\30", IF_386}, - {I_JMP, 2, {IMMEDIATE|COLON,IMMEDIATE|BITS32,0}, "\321\1\xEA\41\30", IF_386}, - {I_JMP, 1, {MEMORY|FAR,0,0}, "\322\300\1\xFF\205", IF_8086}, - {I_JMP, 1, {MEMORY|BITS16|FAR,0,0}, "\320\300\1\xFF\205", IF_8086}, - {I_JMP, 1, {MEMORY|BITS32|FAR,0,0}, "\321\300\1\xFF\205", IF_386}, - {I_JMP, 1, {MEMORY|NEAR,0,0}, "\322\300\1\xFF\204", IF_8086}, - {I_JMP, 1, {MEMORY|BITS16|NEAR,0,0}, "\320\300\1\xFF\204", IF_8086}, - {I_JMP, 1, {MEMORY|BITS32|NEAR,0,0}, "\321\300\1\xFF\204", IF_386}, - {I_JMP, 1, {REG16,0,0}, "\320\300\1\xFF\204", IF_8086}, - {I_JMP, 1, {REG32,0,0}, "\321\300\1\xFF\204", IF_386}, - {I_JMP, 1, {MEMORY,0,0}, "\322\300\1\xFF\204", IF_8086}, - {I_JMP, 1, {MEMORY|BITS16,0,0}, "\320\300\1\xFF\204", IF_8086}, - {I_JMP, 1, {MEMORY|BITS32,0,0}, "\321\300\1\xFF\204", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_JMPE[] = { - {I_JMPE, 1, {IMMEDIATE,0,0}, "\322\2\x0F\xB8\64", IF_IA64}, - {I_JMPE, 1, {IMMEDIATE|BITS16,0,0}, "\320\2\x0F\xB8\64", IF_IA64}, - {I_JMPE, 1, {IMMEDIATE|BITS32,0,0}, "\321\2\x0F\xB8\64", IF_IA64}, - {I_JMPE, 1, {REGMEM|BITS16,0,0}, "\320\2\x0F\x00\206", IF_IA64}, - {I_JMPE, 1, {REGMEM|BITS32,0,0}, "\321\2\x0F\x00\206", IF_IA64}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LAHF[] = { - {I_LAHF, 0, {0,0,0}, "\1\x9F", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LAR[] = { - {I_LAR, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\x02\110", IF_286|IF_PROT|IF_SM}, - {I_LAR, 2, {REG16,REG16,0}, "\320\2\x0F\x02\110", IF_286|IF_PROT}, - {I_LAR, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\x02\110", IF_386|IF_PROT|IF_SM}, - {I_LAR, 2, {REG32,REG32,0}, "\321\2\x0F\x02\110", IF_386|IF_PROT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LDDQU[] = { - {I_LDDQU, 2, {XMMREG,MEMORY,0}, "\3\xF2\x0F\xF0\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LDMXCSR[] = { - {I_LDMXCSR, 1, {MEMORY,0,0}, "\300\2\x0F\xAE\202", IF_KATMAI|IF_SSE|IF_SD}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LDS[] = { - {I_LDS, 2, {REG16,MEMORY,0}, "\320\301\1\xC5\110", IF_8086}, - {I_LDS, 2, {REG32,MEMORY,0}, "\321\301\1\xC5\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LEA[] = { - {I_LEA, 2, {REG16,MEMORY,0}, "\320\301\1\x8D\110", IF_8086}, - {I_LEA, 2, {REG32,MEMORY,0}, "\321\301\1\x8D\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LEAVE[] = { - {I_LEAVE, 0, {0,0,0}, "\1\xC9", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LES[] = { - {I_LES, 2, {REG16,MEMORY,0}, "\320\301\1\xC4\110", IF_8086}, - {I_LES, 2, {REG32,MEMORY,0}, "\321\301\1\xC4\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LFENCE[] = { - {I_LFENCE, 0, {0,0,0}, "\3\x0F\xAE\xE8", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LFS[] = { - {I_LFS, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xB4\110", IF_386}, - {I_LFS, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xB4\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LGDT[] = { - {I_LGDT, 1, {MEMORY,0,0}, "\300\2\x0F\x01\202", IF_286|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LGS[] = { - {I_LGS, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xB5\110", IF_386}, - {I_LGS, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xB5\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LIDT[] = { - {I_LIDT, 1, {MEMORY,0,0}, "\300\2\x0F\x01\203", IF_286|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LLDT[] = { - {I_LLDT, 1, {MEMORY,0,0}, "\300\1\x0F\17\202", IF_286|IF_PROT|IF_PRIV}, - {I_LLDT, 1, {MEMORY|BITS16,0,0}, "\300\1\x0F\17\202", IF_286|IF_PROT|IF_PRIV}, - {I_LLDT, 1, {REG16,0,0}, "\1\x0F\17\202", IF_286|IF_PROT|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LMSW[] = { - {I_LMSW, 1, {MEMORY,0,0}, "\300\2\x0F\x01\206", IF_286|IF_PRIV}, - {I_LMSW, 1, {MEMORY|BITS16,0,0}, "\300\2\x0F\x01\206", IF_286|IF_PRIV}, - {I_LMSW, 1, {REG16,0,0}, "\2\x0F\x01\206", IF_286|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOADALL[] = { - {I_LOADALL, 0, {0,0,0}, "\2\x0F\x07", IF_386|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOADALL286[] = { - {I_LOADALL286, 0, {0,0,0}, "\2\x0F\x05", IF_286|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LODSB[] = { - {I_LODSB, 0, {0,0,0}, "\1\xAC", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LODSD[] = { - {I_LODSD, 0, {0,0,0}, "\321\1\xAD", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LODSW[] = { - {I_LODSW, 0, {0,0,0}, "\320\1\xAD", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOOP[] = { - {I_LOOP, 1, {IMMEDIATE,0,0}, "\312\1\xE2\50", IF_8086}, - {I_LOOP, 2, {IMMEDIATE,REG_CX,0}, "\310\1\xE2\50", IF_8086}, - {I_LOOP, 2, {IMMEDIATE,REG_ECX,0}, "\311\1\xE2\50", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOOPE[] = { - {I_LOOPE, 1, {IMMEDIATE,0,0}, "\312\1\xE1\50", IF_8086}, - {I_LOOPE, 2, {IMMEDIATE,REG_CX,0}, "\310\1\xE1\50", IF_8086}, - {I_LOOPE, 2, {IMMEDIATE,REG_ECX,0}, "\311\1\xE1\50", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOOPNE[] = { - {I_LOOPNE, 1, {IMMEDIATE,0,0}, "\312\1\xE0\50", IF_8086}, - {I_LOOPNE, 2, {IMMEDIATE,REG_CX,0}, "\310\1\xE0\50", IF_8086}, - {I_LOOPNE, 2, {IMMEDIATE,REG_ECX,0}, "\311\1\xE0\50", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOOPNZ[] = { - {I_LOOPNZ, 1, {IMMEDIATE,0,0}, "\312\1\xE0\50", IF_8086}, - {I_LOOPNZ, 2, {IMMEDIATE,REG_CX,0}, "\310\1\xE0\50", IF_8086}, - {I_LOOPNZ, 2, {IMMEDIATE,REG_ECX,0}, "\311\1\xE0\50", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LOOPZ[] = { - {I_LOOPZ, 1, {IMMEDIATE,0,0}, "\312\1\xE1\50", IF_8086}, - {I_LOOPZ, 2, {IMMEDIATE,REG_CX,0}, "\310\1\xE1\50", IF_8086}, - {I_LOOPZ, 2, {IMMEDIATE,REG_ECX,0}, "\311\1\xE1\50", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LSL[] = { - {I_LSL, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\x03\110", IF_286|IF_PROT|IF_SM}, - {I_LSL, 2, {REG16,REG16,0}, "\320\2\x0F\x03\110", IF_286|IF_PROT}, - {I_LSL, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\x03\110", IF_386|IF_PROT|IF_SM}, - {I_LSL, 2, {REG32,REG32,0}, "\321\2\x0F\x03\110", IF_386|IF_PROT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LSS[] = { - {I_LSS, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xB2\110", IF_386}, - {I_LSS, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xB2\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_LTR[] = { - {I_LTR, 1, {MEMORY,0,0}, "\300\1\x0F\17\203", IF_286|IF_PROT|IF_PRIV}, - {I_LTR, 1, {MEMORY|BITS16,0,0}, "\300\1\x0F\17\203", IF_286|IF_PROT|IF_PRIV}, - {I_LTR, 1, {REG16,0,0}, "\1\x0F\17\203", IF_286|IF_PROT|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MASKMOVDQU[] = { - {I_MASKMOVDQU, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF7\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MASKMOVQ[] = { - {I_MASKMOVQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF7\110", IF_KATMAI|IF_MMX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MAXPD[] = { - {I_MAXPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x5F\110", IF_WILLAMETTE|IF_SSE2}, - {I_MAXPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x5F\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MAXPS[] = { - {I_MAXPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x5F\110", IF_KATMAI|IF_SSE}, - {I_MAXPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x5F\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MAXSD[] = { - {I_MAXSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x5F\110", IF_WILLAMETTE|IF_SSE2}, - {I_MAXSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x5F\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MAXSS[] = { - {I_MAXSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x5F\110", IF_KATMAI|IF_SSE}, - {I_MAXSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x5F\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MFENCE[] = { - {I_MFENCE, 0, {0,0,0}, "\3\x0F\xAE\xF0", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MINPD[] = { - {I_MINPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x5D\110", IF_WILLAMETTE|IF_SSE2}, - {I_MINPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x5D\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MINPS[] = { - {I_MINPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x5D\110", IF_KATMAI|IF_SSE}, - {I_MINPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x5D\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MINSD[] = { - {I_MINSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x5D\110", IF_WILLAMETTE|IF_SSE2}, - {I_MINSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x5D\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MINSS[] = { - {I_MINSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x5D\110", IF_KATMAI|IF_SSE}, - {I_MINSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x5D\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MONITOR[] = { - {I_MONITOR, 0, {0,0,0}, "\3\x0F\x01\xC8", IF_PRESCOTT}, - {I_MONITOR, 3, {REG_EAX,REG_ECX,REG_EDX}, "\3\x0F\x01\xC8", IF_PRESCOTT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOV[] = { - {I_MOV, 2, {MEMORY,REG_SREG,0}, "\300\1\x8C\101", IF_8086|IF_SM}, - {I_MOV, 2, {REG16,REG_SREG,0}, "\320\1\x8C\101", IF_8086}, - {I_MOV, 2, {REG32,REG_SREG,0}, "\321\1\x8C\101", IF_386}, - {I_MOV, 2, {REG_SREG,MEMORY,0}, "\301\1\x8E\110", IF_8086|IF_SM}, - {I_MOV, 2, {REG_SREG,REG16,0}, "\1\x8E\110", IF_8086}, - {I_MOV, 2, {REG_SREG,REG32,0}, "\1\x8E\110", IF_386}, - {I_MOV, 2, {REG_AL,MEM_OFFS,0}, "\301\1\xA0\45", IF_8086|IF_SM}, - {I_MOV, 2, {REG_AX,MEM_OFFS,0}, "\301\320\1\xA1\45", IF_8086|IF_SM}, - {I_MOV, 2, {REG_EAX,MEM_OFFS,0}, "\301\321\1\xA1\45", IF_386|IF_SM}, - {I_MOV, 2, {MEM_OFFS,REG_AL,0}, "\300\1\xA2\44", IF_8086|IF_SM}, - {I_MOV, 2, {MEM_OFFS,REG_AX,0}, "\300\320\1\xA3\44", IF_8086|IF_SM}, - {I_MOV, 2, {MEM_OFFS,REG_EAX,0}, "\300\321\1\xA3\44", IF_386|IF_SM}, - {I_MOV, 2, {REG32,REG_CREG,0}, "\2\x0F\x20\101", IF_386|IF_PRIV}, - {I_MOV, 2, {REG32,REG_DREG,0}, "\2\x0F\x21\101", IF_386|IF_PRIV}, - {I_MOV, 2, {REG32,REG_TREG,0}, "\2\x0F\x24\101", IF_386|IF_PRIV}, - {I_MOV, 2, {REG_CREG,REG32,0}, "\2\x0F\x22\110", IF_386|IF_PRIV}, - {I_MOV, 2, {REG_DREG,REG32,0}, "\2\x0F\x23\110", IF_386|IF_PRIV}, - {I_MOV, 2, {REG_TREG,REG32,0}, "\2\x0F\x26\110", IF_386|IF_PRIV}, - {I_MOV, 2, {MEMORY,REG8,0}, "\300\1\x88\101", IF_8086|IF_SM}, - {I_MOV, 2, {REG8,REG8,0}, "\1\x88\101", IF_8086}, - {I_MOV, 2, {MEMORY,REG16,0}, "\320\300\1\x89\101", IF_8086|IF_SM}, - {I_MOV, 2, {REG16,REG16,0}, "\320\1\x89\101", IF_8086}, - {I_MOV, 2, {MEMORY,REG32,0}, "\321\300\1\x89\101", IF_386|IF_SM}, - {I_MOV, 2, {REG32,REG32,0}, "\321\1\x89\101", IF_386}, - {I_MOV, 2, {REG8,MEMORY,0}, "\301\1\x8A\110", IF_8086|IF_SM}, - {I_MOV, 2, {REG8,REG8,0}, "\1\x8A\110", IF_8086}, - {I_MOV, 2, {REG16,MEMORY,0}, "\320\301\1\x8B\110", IF_8086|IF_SM}, - {I_MOV, 2, {REG16,REG16,0}, "\320\1\x8B\110", IF_8086}, - {I_MOV, 2, {REG32,MEMORY,0}, "\321\301\1\x8B\110", IF_386|IF_SM}, - {I_MOV, 2, {REG32,REG32,0}, "\321\1\x8B\110", IF_386}, - {I_MOV, 2, {REG8,IMMEDIATE,0}, "\10\xB0\21", IF_8086|IF_SM}, - {I_MOV, 2, {REG16,IMMEDIATE,0}, "\320\10\xB8\31", IF_8086|IF_SM}, - {I_MOV, 2, {REG32,IMMEDIATE,0}, "\321\10\xB8\41", IF_386|IF_SM}, - {I_MOV, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC6\200\21", IF_8086|IF_SM}, - {I_MOV, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC7\200\31", IF_8086|IF_SM}, - {I_MOV, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC7\200\41", IF_386|IF_SM}, - {I_MOV, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\xC6\200\21", IF_8086|IF_SM}, - {I_MOV, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\1\xC7\200\31", IF_8086|IF_SM}, - {I_MOV, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\1\xC7\200\41", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVAPD[] = { - {I_MOVAPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x28\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVAPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x29\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVAPD, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x29\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_MOVAPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x28\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVAPS[] = { - {I_MOVAPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x28\110", IF_KATMAI|IF_SSE}, - {I_MOVAPS, 2, {MEMORY,XMMREG,0}, "\300\2\x0F\x29\101", IF_KATMAI|IF_SSE}, - {I_MOVAPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x28\110", IF_KATMAI|IF_SSE}, - {I_MOVAPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x29\101", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVD[] = { - {I_MOVD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x6E\110", IF_PENT|IF_MMX|IF_SD}, - {I_MOVD, 2, {MMXREG,REG32,0}, "\2\x0F\x6E\110", IF_PENT|IF_MMX}, - {I_MOVD, 2, {MEMORY,MMXREG,0}, "\300\2\x0F\x7E\101", IF_PENT|IF_MMX|IF_SD}, - {I_MOVD, 2, {REG32,MMXREG,0}, "\2\x0F\x7E\101", IF_PENT|IF_MMX}, - {I_MOVD, 2, {XMMREG,REG32,0}, "\3\x66\x0F\x6E\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVD, 2, {REG32,XMMREG,0}, "\3\x66\x0F\x7E\101", IF_WILLAMETTE|IF_SSE2}, - {I_MOVD, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x7E\101", IF_WILLAMETTE|IF_SSE2}, - {I_MOVD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x6E\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVDDUP[] = { - {I_MOVDDUP, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x12\110", IF_PRESCOTT|IF_SSE3}, - {I_MOVDDUP, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x12\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVDQ2Q[] = { - {I_MOVDQ2Q, 2, {MMXREG,XMMREG,0}, "\3\xF2\x0F\xD6\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVDQA[] = { - {I_MOVDQA, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x6F\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVDQA, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x7F\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_MOVDQA, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x6F\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_MOVDQA, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x7F\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVDQU[] = { - {I_MOVDQU, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x6F\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVDQU, 2, {MEMORY,XMMREG,0}, "\333\300\2\x0F\x7F\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_MOVDQU, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x6F\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_MOVDQU, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x7F\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVHLPS[] = { - {I_MOVHLPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x12\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVHPD[] = { - {I_MOVHPD, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x17\101", IF_WILLAMETTE|IF_SSE2}, - {I_MOVHPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x16\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVHPS[] = { - {I_MOVHPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x16\110", IF_KATMAI|IF_SSE}, - {I_MOVHPS, 2, {MEMORY,XMMREG,0}, "\300\2\x0F\x17\101", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVLHPS[] = { - {I_MOVLHPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x16\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVLPD[] = { - {I_MOVLPD, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x13\101", IF_WILLAMETTE|IF_SSE2}, - {I_MOVLPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x12\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVLPS[] = { - {I_MOVLPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x12\110", IF_KATMAI|IF_SSE}, - {I_MOVLPS, 2, {MEMORY,XMMREG,0}, "\300\2\x0F\x13\101", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVMSKPD[] = { - {I_MOVMSKPD, 2, {REG32,XMMREG,0}, "\3\x66\x0F\x50\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVMSKPS[] = { - {I_MOVMSKPS, 2, {REG32,XMMREG,0}, "\2\x0F\x50\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVNTDQ[] = { - {I_MOVNTDQ, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\xE7\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVNTI[] = { - {I_MOVNTI, 2, {MEMORY,REG32,0}, "\300\2\x0F\xC3\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVNTPD[] = { - {I_MOVNTPD, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x2B\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVNTPS[] = { - {I_MOVNTPS, 2, {MEMORY,XMMREG,0}, "\300\2\x0F\x2B\101", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVNTQ[] = { - {I_MOVNTQ, 2, {MEMORY,MMXREG,0}, "\300\2\x0F\xE7\101", IF_KATMAI|IF_MMX|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVQ[] = { - {I_MOVQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x6F\110", IF_PENT|IF_MMX|IF_SM}, - {I_MOVQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\x6F\110", IF_PENT|IF_MMX}, - {I_MOVQ, 2, {MEMORY,MMXREG,0}, "\300\2\x0F\x7F\101", IF_PENT|IF_MMX|IF_SM}, - {I_MOVQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\x7F\101", IF_PENT|IF_MMX}, - {I_MOVQ, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x7E\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD6\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVQ, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\xD6\101", IF_WILLAMETTE|IF_SSE2}, - {I_MOVQ, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x7E\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVQ2DQ[] = { - {I_MOVQ2DQ, 2, {XMMREG,MMXREG,0}, "\333\2\x0F\xD6\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSB[] = { - {I_MOVSB, 0, {0,0,0}, "\1\xA4", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSD[] = { - {I_MOVSD, 0, {0,0,0}, "\321\1\xA5", IF_386}, - {I_MOVSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x10\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x11\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVSD, 2, {MEMORY,XMMREG,0}, "\300\3\xF2\x0F\x11\101", IF_WILLAMETTE|IF_SSE2}, - {I_MOVSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x10\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSHDUP[] = { - {I_MOVSHDUP, 2, {XMMREG,MEMORY,0}, "\301\3\xF3\x0F\x16\110", IF_PRESCOTT|IF_SSE3}, - {I_MOVSHDUP, 2, {XMMREG,XMMREG,0}, "\3\xF3\x0F\x16\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSLDUP[] = { - {I_MOVSLDUP, 2, {XMMREG,MEMORY,0}, "\301\3\xF3\x0F\x12\110", IF_PRESCOTT|IF_SSE3}, - {I_MOVSLDUP, 2, {XMMREG,XMMREG,0}, "\3\xF3\x0F\x12\110", IF_PRESCOTT|IF_SSE3}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSS[] = { - {I_MOVSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x10\110", IF_KATMAI|IF_SSE}, - {I_MOVSS, 2, {MEMORY,XMMREG,0}, "\300\333\2\x0F\x11\101", IF_KATMAI|IF_SSE}, - {I_MOVSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x10\110", IF_KATMAI|IF_SSE}, - {I_MOVSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x11\101", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSW[] = { - {I_MOVSW, 0, {0,0,0}, "\320\1\xA5", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVSX[] = { - {I_MOVSX, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xBE\110", IF_386|IF_SB}, - {I_MOVSX, 2, {REG16,REG8,0}, "\320\2\x0F\xBE\110", IF_386}, - {I_MOVSX, 2, {REG32,REGMEM|BITS8,0}, "\321\301\2\x0F\xBE\110", IF_386}, - {I_MOVSX, 2, {REG32,REGMEM|BITS16,0}, "\321\301\2\x0F\xBF\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVUPD[] = { - {I_MOVUPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x10\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVUPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x11\110", IF_WILLAMETTE|IF_SSE2}, - {I_MOVUPD, 2, {MEMORY,XMMREG,0}, "\300\3\x66\x0F\x11\101", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_MOVUPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x10\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVUPS[] = { - {I_MOVUPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x10\110", IF_KATMAI|IF_SSE}, - {I_MOVUPS, 2, {MEMORY,XMMREG,0}, "\300\331\2\x0F\x11\101", IF_KATMAI|IF_SSE}, - {I_MOVUPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x10\110", IF_KATMAI|IF_SSE}, - {I_MOVUPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x11\101", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MOVZX[] = { - {I_MOVZX, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xB6\110", IF_386|IF_SB}, - {I_MOVZX, 2, {REG16,REG8,0}, "\320\2\x0F\xB6\110", IF_386}, - {I_MOVZX, 2, {REG32,REGMEM|BITS8,0}, "\321\301\2\x0F\xB6\110", IF_386}, - {I_MOVZX, 2, {REG32,REGMEM|BITS16,0}, "\321\301\2\x0F\xB7\110", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MUL[] = { - {I_MUL, 1, {REGMEM|BITS8,0,0}, "\300\1\xF6\204", IF_8086}, - {I_MUL, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xF7\204", IF_8086}, - {I_MUL, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xF7\204", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MULPD[] = { - {I_MULPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x59\110", IF_WILLAMETTE|IF_SSE2}, - {I_MULPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x59\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MULPS[] = { - {I_MULPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x59\110", IF_KATMAI|IF_SSE}, - {I_MULPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x59\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MULSD[] = { - {I_MULSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x59\110", IF_WILLAMETTE|IF_SSE2}, - {I_MULSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x59\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MULSS[] = { - {I_MULSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x59\110", IF_KATMAI|IF_SSE}, - {I_MULSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x59\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_MWAIT[] = { - {I_MWAIT, 0, {0,0,0}, "\3\x0F\x01\xC9", IF_PRESCOTT}, - {I_MWAIT, 2, {REG_EAX,REG_ECX,0}, "\3\x0F\x01\xC9", IF_PRESCOTT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_NEG[] = { - {I_NEG, 1, {REGMEM|BITS8,0,0}, "\300\1\xF6\203", IF_8086}, - {I_NEG, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xF7\203", IF_8086}, - {I_NEG, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xF7\203", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_NOP[] = { - {I_NOP, 0, {0,0,0}, "\1\x90", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_NOT[] = { - {I_NOT, 1, {REGMEM|BITS8,0,0}, "\300\1\xF6\202", IF_8086}, - {I_NOT, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xF7\202", IF_8086}, - {I_NOT, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xF7\202", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_OR[] = { - {I_OR, 2, {MEMORY,REG8,0}, "\300\1\x08\101", IF_8086|IF_SM}, - {I_OR, 2, {REG8,REG8,0}, "\1\x08\101", IF_8086}, - {I_OR, 2, {MEMORY,REG16,0}, "\320\300\1\x09\101", IF_8086|IF_SM}, - {I_OR, 2, {REG16,REG16,0}, "\320\1\x09\101", IF_8086}, - {I_OR, 2, {MEMORY,REG32,0}, "\321\300\1\x09\101", IF_386|IF_SM}, - {I_OR, 2, {REG32,REG32,0}, "\321\1\x09\101", IF_386}, - {I_OR, 2, {REG8,MEMORY,0}, "\301\1\x0A\110", IF_8086|IF_SM}, - {I_OR, 2, {REG8,REG8,0}, "\1\x0A\110", IF_8086}, - {I_OR, 2, {REG16,MEMORY,0}, "\320\301\1\x0B\110", IF_8086|IF_SM}, - {I_OR, 2, {REG16,REG16,0}, "\320\1\x0B\110", IF_8086}, - {I_OR, 2, {REG32,MEMORY,0}, "\321\301\1\x0B\110", IF_386|IF_SM}, - {I_OR, 2, {REG32,REG32,0}, "\321\1\x0B\110", IF_386}, - {I_OR, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\201\15", IF_8086}, - {I_OR, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\201\15", IF_386}, - {I_OR, 2, {REG_AL,IMMEDIATE,0}, "\1\x0C\21", IF_8086|IF_SM}, - {I_OR, 2, {REG_AX,SBYTE,0}, "\320\1\x83\201\15", IF_8086|IF_SM}, - {I_OR, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x0D\31", IF_8086|IF_SM}, - {I_OR, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\201\15", IF_386|IF_SM}, - {I_OR, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x0D\41", IF_386|IF_SM}, - {I_OR, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\201\21", IF_8086|IF_SM}, - {I_OR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\201\131", IF_8086|IF_SM}, - {I_OR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\201\141", IF_386|IF_SM}, - {I_OR, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\201\21", IF_8086|IF_SM}, - {I_OR, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\201\131", IF_8086|IF_SM}, - {I_OR, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\201\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ORPD[] = { - {I_ORPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x56\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_ORPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x56\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ORPS[] = { - {I_ORPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x56\110", IF_KATMAI|IF_SSE}, - {I_ORPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x56\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_OUT[] = { - {I_OUT, 2, {IMMEDIATE,REG_AL,0}, "\1\xE6\24", IF_8086|IF_SB}, - {I_OUT, 2, {IMMEDIATE,REG_AX,0}, "\320\1\xE7\24", IF_8086|IF_SB}, - {I_OUT, 2, {IMMEDIATE,REG_EAX,0}, "\321\1\xE7\24", IF_386|IF_SB}, - {I_OUT, 2, {REG_DX,REG_AL,0}, "\1\xEE", IF_8086}, - {I_OUT, 2, {REG_DX,REG_AX,0}, "\320\1\xEF", IF_8086}, - {I_OUT, 2, {REG_DX,REG_EAX,0}, "\321\1\xEF", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_OUTSB[] = { - {I_OUTSB, 0, {0,0,0}, "\1\x6E", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_OUTSD[] = { - {I_OUTSD, 0, {0,0,0}, "\321\1\x6F", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_OUTSW[] = { - {I_OUTSW, 0, {0,0,0}, "\320\1\x6F", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PACKSSDW[] = { - {I_PACKSSDW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x6B\110", IF_PENT|IF_MMX|IF_SM}, - {I_PACKSSDW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x6B\110", IF_PENT|IF_MMX}, - {I_PACKSSDW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x6B\110", IF_WILLAMETTE|IF_SSE2}, - {I_PACKSSDW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x6B\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PACKSSWB[] = { - {I_PACKSSWB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x63\110", IF_PENT|IF_MMX|IF_SM}, - {I_PACKSSWB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x63\110", IF_PENT|IF_MMX}, - {I_PACKSSWB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x63\110", IF_WILLAMETTE|IF_SSE2}, - {I_PACKSSWB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x63\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PACKUSWB[] = { - {I_PACKUSWB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x67\110", IF_PENT|IF_MMX|IF_SM}, - {I_PACKUSWB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x67\110", IF_PENT|IF_MMX}, - {I_PACKUSWB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x67\110", IF_WILLAMETTE|IF_SSE2}, - {I_PACKUSWB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x67\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDB[] = { - {I_PADDB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xFC\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xFC\110", IF_PENT|IF_MMX}, - {I_PADDB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xFC\110", IF_WILLAMETTE|IF_SSE2}, - {I_PADDB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xFC\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDD[] = { - {I_PADDD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xFE\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDD, 2, {MMXREG,MMXREG,0}, "\2\x0F\xFE\110", IF_PENT|IF_MMX}, - {I_PADDD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xFE\110", IF_WILLAMETTE|IF_SSE2}, - {I_PADDD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xFE\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDQ[] = { - {I_PADDQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD4\110", IF_WILLAMETTE|IF_SSE2}, - {I_PADDQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD4\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PADDQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD4\110", IF_WILLAMETTE|IF_SSE2}, - {I_PADDQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD4\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDSB[] = { - {I_PADDSB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xEC\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDSB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xEC\110", IF_PENT|IF_MMX}, - {I_PADDSB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xEC\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PADDSB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xEC\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDSIW[] = { - {I_PADDSIW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x51\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - {I_PADDSIW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x51\110", IF_PENT|IF_MMX|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDSW[] = { - {I_PADDSW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xED\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDSW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xED\110", IF_PENT|IF_MMX}, - {I_PADDSW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xED\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PADDSW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xED\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDUSB[] = { - {I_PADDUSB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xDC\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDUSB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xDC\110", IF_PENT|IF_MMX}, - {I_PADDUSB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xDC\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PADDUSB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xDC\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDUSW[] = { - {I_PADDUSW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xDD\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDUSW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xDD\110", IF_PENT|IF_MMX}, - {I_PADDUSW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xDD\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PADDUSW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xDD\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PADDW[] = { - {I_PADDW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xFD\110", IF_PENT|IF_MMX|IF_SM}, - {I_PADDW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xFD\110", IF_PENT|IF_MMX}, - {I_PADDW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xFD\110", IF_WILLAMETTE|IF_SSE2}, - {I_PADDW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xFD\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PAND[] = { - {I_PAND, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xDB\110", IF_PENT|IF_MMX|IF_SM}, - {I_PAND, 2, {MMXREG,MMXREG,0}, "\2\x0F\xDB\110", IF_PENT|IF_MMX}, - {I_PAND, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xDB\110", IF_WILLAMETTE|IF_SSE2}, - {I_PAND, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xDB\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PANDN[] = { - {I_PANDN, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xDF\110", IF_PENT|IF_MMX|IF_SM}, - {I_PANDN, 2, {MMXREG,MMXREG,0}, "\2\x0F\xDF\110", IF_PENT|IF_MMX}, - {I_PANDN, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xDF\110", IF_WILLAMETTE|IF_SSE2}, - {I_PANDN, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xDF\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PAUSE[] = { - {I_PAUSE, 0, {0,0,0}, "\333\1\x90", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PAVEB[] = { - {I_PAVEB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x50\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - {I_PAVEB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x50\110", IF_PENT|IF_MMX|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PAVGB[] = { - {I_PAVGB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE0\110", IF_KATMAI|IF_MMX}, - {I_PAVGB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE0\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PAVGB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE0\110", IF_WILLAMETTE|IF_SSE2}, - {I_PAVGB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE0\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PAVGUSB[] = { - {I_PAVGUSB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xBF", IF_PENT|IF_3DNOW|IF_SM}, - {I_PAVGUSB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xBF", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PAVGW[] = { - {I_PAVGW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE3\110", IF_KATMAI|IF_MMX}, - {I_PAVGW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE3\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PAVGW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE3\110", IF_WILLAMETTE|IF_SSE2}, - {I_PAVGW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE3\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PCMPEQB[] = { - {I_PCMPEQB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x74\110", IF_PENT|IF_MMX|IF_SM}, - {I_PCMPEQB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x74\110", IF_PENT|IF_MMX}, - {I_PCMPEQB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x74\110", IF_WILLAMETTE|IF_SSE2}, - {I_PCMPEQB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x74\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PCMPEQD[] = { - {I_PCMPEQD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x76\110", IF_PENT|IF_MMX|IF_SM}, - {I_PCMPEQD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x76\110", IF_PENT|IF_MMX}, - {I_PCMPEQD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x76\110", IF_WILLAMETTE|IF_SSE2}, - {I_PCMPEQD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x76\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PCMPEQW[] = { - {I_PCMPEQW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x75\110", IF_PENT|IF_MMX|IF_SM}, - {I_PCMPEQW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x75\110", IF_PENT|IF_MMX}, - {I_PCMPEQW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x75\110", IF_WILLAMETTE|IF_SSE2}, - {I_PCMPEQW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x75\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PCMPGTB[] = { - {I_PCMPGTB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x64\110", IF_PENT|IF_MMX|IF_SM}, - {I_PCMPGTB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x64\110", IF_PENT|IF_MMX}, - {I_PCMPGTB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x64\110", IF_WILLAMETTE|IF_SSE2}, - {I_PCMPGTB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x64\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PCMPGTD[] = { - {I_PCMPGTD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x66\110", IF_PENT|IF_MMX|IF_SM}, - {I_PCMPGTD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x66\110", IF_PENT|IF_MMX}, - {I_PCMPGTD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x66\110", IF_WILLAMETTE|IF_SSE2}, - {I_PCMPGTD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x66\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PCMPGTW[] = { - {I_PCMPGTW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x65\110", IF_PENT|IF_MMX|IF_SM}, - {I_PCMPGTW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x65\110", IF_PENT|IF_MMX}, - {I_PCMPGTW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x65\110", IF_WILLAMETTE|IF_SSE2}, - {I_PCMPGTW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x65\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PDISTIB[] = { - {I_PDISTIB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x54\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PEXTRW[] = { - {I_PEXTRW, 3, {REG32,MMXREG,IMMEDIATE}, "\2\x0F\xC5\110\26", IF_KATMAI|IF_MMX|IF_SB|IF_AR2}, - {I_PEXTRW, 3, {REG32,XMMREG,IMMEDIATE}, "\3\x66\x0F\xC5\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PF2ID[] = { - {I_PF2ID, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x1D", IF_PENT|IF_3DNOW|IF_SM}, - {I_PF2ID, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x1D", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PF2IW[] = { - {I_PF2IW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x1C", IF_PENT|IF_3DNOW|IF_SM}, - {I_PF2IW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x1C", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFACC[] = { - {I_PFACC, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xAE", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFACC, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xAE", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFADD[] = { - {I_PFADD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x9E", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFADD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x9E", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFCMPEQ[] = { - {I_PFCMPEQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xB0", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFCMPEQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xB0", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFCMPGE[] = { - {I_PFCMPGE, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x90", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFCMPGE, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x90", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFCMPGT[] = { - {I_PFCMPGT, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xA0", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFCMPGT, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xA0", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFMAX[] = { - {I_PFMAX, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xA4", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFMAX, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xA4", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFMIN[] = { - {I_PFMIN, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x94", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFMIN, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x94", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFMUL[] = { - {I_PFMUL, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xB4", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFMUL, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xB4", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFNACC[] = { - {I_PFNACC, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x8A", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFNACC, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x8A", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFPNACC[] = { - {I_PFPNACC, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x8E", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFPNACC, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x8E", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFRCP[] = { - {I_PFRCP, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x96", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFRCP, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x96", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFRCPIT1[] = { - {I_PFRCPIT1, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xA6", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFRCPIT1, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xA6", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFRCPIT2[] = { - {I_PFRCPIT2, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xB6", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFRCPIT2, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xB6", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFRSQIT1[] = { - {I_PFRSQIT1, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xA7", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFRSQIT1, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xA7", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFRSQRT[] = { - {I_PFRSQRT, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x97", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFRSQRT, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x97", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFSUB[] = { - {I_PFSUB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x9A", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFSUB, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x9A", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PFSUBR[] = { - {I_PFSUBR, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xAA", IF_PENT|IF_3DNOW|IF_SM}, - {I_PFSUBR, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xAA", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PI2FD[] = { - {I_PI2FD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x0D", IF_PENT|IF_3DNOW|IF_SM}, - {I_PI2FD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x0D", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PI2FW[] = { - {I_PI2FW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\x0C", IF_PENT|IF_3DNOW|IF_SM}, - {I_PI2FW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\x0C", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PINSRW[] = { - {I_PINSRW, 3, {MMXREG,REG16,IMMEDIATE}, "\2\x0F\xC4\110\26", IF_KATMAI|IF_MMX|IF_SB|IF_AR2}, - {I_PINSRW, 3, {MMXREG,REG32,IMMEDIATE}, "\2\x0F\xC4\110\26", IF_KATMAI|IF_MMX|IF_SB|IF_AR2}, - {I_PINSRW, 3, {MMXREG,MEMORY,IMMEDIATE}, "\301\2\x0F\xC4\110\26", IF_KATMAI|IF_MMX|IF_SB|IF_AR2}, - {I_PINSRW, 3, {MMXREG,MEMORY|BITS16,IMMEDIATE}, "\301\2\x0F\xC4\110\26", IF_KATMAI|IF_MMX|IF_SB|IF_AR2}, - {I_PINSRW, 3, {XMMREG,REG16,IMMEDIATE}, "\3\x66\x0F\xC4\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_PINSRW, 3, {XMMREG,REG32,IMMEDIATE}, "\3\x66\x0F\xC4\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_PINSRW, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\3\x66\x0F\xC4\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_PINSRW, 3, {XMMREG,MEMORY|BITS16,IMMEDIATE}, "\301\3\x66\x0F\xC4\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMACHRIW[] = { - {I_PMACHRIW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x5E\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMADDWD[] = { - {I_PMADDWD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF5\110", IF_PENT|IF_MMX|IF_SM}, - {I_PMADDWD, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF5\110", IF_PENT|IF_MMX}, - {I_PMADDWD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF5\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PMADDWD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF5\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMAGW[] = { - {I_PMAGW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x52\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - {I_PMAGW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x52\110", IF_PENT|IF_MMX|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMAXSW[] = { - {I_PMAXSW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xEE\110", IF_KATMAI|IF_MMX}, - {I_PMAXSW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xEE\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PMAXSW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xEE\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMAXSW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xEE\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMAXUB[] = { - {I_PMAXUB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xDE\110", IF_KATMAI|IF_MMX}, - {I_PMAXUB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xDE\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PMAXUB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xDE\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMAXUB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xDE\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMINSW[] = { - {I_PMINSW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xEA\110", IF_KATMAI|IF_MMX}, - {I_PMINSW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xEA\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PMINSW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xEA\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMINSW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xEA\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMINUB[] = { - {I_PMINUB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xDA\110", IF_KATMAI|IF_MMX}, - {I_PMINUB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xDA\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PMINUB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xDA\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMINUB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xDA\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMOVMSKB[] = { - {I_PMOVMSKB, 2, {REG32,MMXREG,0}, "\2\x0F\xD7\110", IF_KATMAI|IF_MMX}, - {I_PMOVMSKB, 2, {REG32,XMMREG,0}, "\3\x66\x0F\xD7\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULHRIW[] = { - {I_PMULHRIW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x5D\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - {I_PMULHRIW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x5D\110", IF_PENT|IF_MMX|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULHRWA[] = { - {I_PMULHRWA, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\1\xB7", IF_PENT|IF_3DNOW|IF_SM}, - {I_PMULHRWA, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\1\xB7", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULHRWC[] = { - {I_PMULHRWC, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x59\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - {I_PMULHRWC, 2, {MMXREG,MMXREG,0}, "\2\x0F\x59\110", IF_PENT|IF_MMX|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULHUW[] = { - {I_PMULHUW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE4\110", IF_KATMAI|IF_MMX}, - {I_PMULHUW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE4\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PMULHUW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE4\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMULHUW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE4\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULHW[] = { - {I_PMULHW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE5\110", IF_PENT|IF_MMX|IF_SM}, - {I_PMULHW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE5\110", IF_PENT|IF_MMX}, - {I_PMULHW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE5\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PMULHW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE5\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULLW[] = { - {I_PMULLW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD5\110", IF_PENT|IF_MMX|IF_SM}, - {I_PMULLW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD5\110", IF_PENT|IF_MMX}, - {I_PMULLW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD5\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PMULLW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD5\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMULUDQ[] = { - {I_PMULUDQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF4\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMULUDQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF4\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PMULUDQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF4\110", IF_WILLAMETTE|IF_SSE2}, - {I_PMULUDQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF4\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMVGEZB[] = { - {I_PMVGEZB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x5C\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMVLZB[] = { - {I_PMVLZB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x5B\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMVNZB[] = { - {I_PMVNZB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x5A\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PMVZB[] = { - {I_PMVZB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x58\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POP[] = { - {I_POP, 1, {REG16,0,0}, "\320\10\x58", IF_8086}, - {I_POP, 1, {REG32,0,0}, "\321\10\x58", IF_386}, - {I_POP, 1, {REGMEM|BITS16,0,0}, "\320\300\1\x8F\200", IF_8086}, - {I_POP, 1, {REGMEM|BITS32,0,0}, "\321\300\1\x8F\200", IF_386}, - {I_POP, 1, {REG_CS,0,0}, "\1\x0F", IF_8086|IF_UNDOC}, - {I_POP, 1, {REG_DESS,0,0}, "\4", IF_8086}, - {I_POP, 1, {REG_FSGS,0,0}, "\1\x0F\5", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POPA[] = { - {I_POPA, 0, {0,0,0}, "\322\1\x61", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POPAD[] = { - {I_POPAD, 0, {0,0,0}, "\321\1\x61", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POPAW[] = { - {I_POPAW, 0, {0,0,0}, "\320\1\x61", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POPF[] = { - {I_POPF, 0, {0,0,0}, "\322\1\x9D", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POPFD[] = { - {I_POPFD, 0, {0,0,0}, "\321\1\x9D", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POPFW[] = { - {I_POPFW, 0, {0,0,0}, "\320\1\x9D", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_POR[] = { - {I_POR, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xEB\110", IF_PENT|IF_MMX|IF_SM}, - {I_POR, 2, {MMXREG,MMXREG,0}, "\2\x0F\xEB\110", IF_PENT|IF_MMX}, - {I_POR, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xEB\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_POR, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xEB\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PREFETCH[] = { - {I_PREFETCH, 1, {MEMORY,0,0}, "\2\x0F\x0D\200", IF_PENT|IF_3DNOW|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PREFETCHNTA[] = { - {I_PREFETCHNTA, 1, {MEMORY,0,0}, "\300\2\x0F\x18\200", IF_KATMAI}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PREFETCHT0[] = { - {I_PREFETCHT0, 1, {MEMORY,0,0}, "\300\2\x0F\x18\201", IF_KATMAI}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PREFETCHT1[] = { - {I_PREFETCHT1, 1, {MEMORY,0,0}, "\300\2\x0F\x18\202", IF_KATMAI}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PREFETCHT2[] = { - {I_PREFETCHT2, 1, {MEMORY,0,0}, "\300\2\x0F\x18\203", IF_KATMAI}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PREFETCHW[] = { - {I_PREFETCHW, 1, {MEMORY,0,0}, "\2\x0F\x0D\201", IF_PENT|IF_3DNOW|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSADBW[] = { - {I_PSADBW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF6\110", IF_KATMAI|IF_MMX}, - {I_PSADBW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF6\110", IF_KATMAI|IF_MMX|IF_SM}, - {I_PSADBW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF6\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSADBW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF6\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSHUFD[] = { - {I_PSHUFD, 3, {XMMREG,XMMREG,IMMEDIATE}, "\3\x66\x0F\x70\110\22", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_PSHUFD, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\3\x66\x0F\x70\110\22", IF_WILLAMETTE|IF_SSE2|IF_SM2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSHUFHW[] = { - {I_PSHUFHW, 3, {XMMREG,XMMREG,IMMEDIATE}, "\333\2\x0F\x70\110\22", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_PSHUFHW, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\333\2\x0F\x70\110\22", IF_WILLAMETTE|IF_SSE2|IF_SM2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSHUFLW[] = { - {I_PSHUFLW, 3, {XMMREG,XMMREG,IMMEDIATE}, "\3\xF2\x0F\x70\110\22", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_PSHUFLW, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\3\xF2\x0F\x70\110\22", IF_WILLAMETTE|IF_SSE2|IF_SM2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSHUFW[] = { - {I_PSHUFW, 3, {MMXREG,MMXREG,IMMEDIATE}, "\2\x0F\x70\110\22", IF_KATMAI|IF_MMX|IF_SB|IF_AR2}, - {I_PSHUFW, 3, {MMXREG,MEMORY,IMMEDIATE}, "\301\2\x0F\x70\110\22", IF_KATMAI|IF_MMX|IF_SM2|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSLLD[] = { - {I_PSLLD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF2\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSLLD, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF2\110", IF_PENT|IF_MMX}, - {I_PSLLD, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x72\206\25", IF_PENT|IF_MMX}, - {I_PSLLD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF2\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSLLD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF2\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSLLD, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x72\206\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSLLDQ[] = { - {I_PSLLDQ, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x73\207\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSLLQ[] = { - {I_PSLLQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF3\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSLLQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF3\110", IF_PENT|IF_MMX}, - {I_PSLLQ, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x73\206\25", IF_PENT|IF_MMX}, - {I_PSLLQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF3\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSLLQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF3\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSLLQ, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x73\206\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSLLW[] = { - {I_PSLLW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF1\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSLLW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF1\110", IF_PENT|IF_MMX}, - {I_PSLLW, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x71\206\25", IF_PENT|IF_MMX}, - {I_PSLLW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF1\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSLLW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF1\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSLLW, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x71\206\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSRAD[] = { - {I_PSRAD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE2\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSRAD, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE2\110", IF_PENT|IF_MMX}, - {I_PSRAD, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x72\204\25", IF_PENT|IF_MMX}, - {I_PSRAD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE2\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSRAD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE2\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSRAD, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x72\204\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSRAW[] = { - {I_PSRAW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE1\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSRAW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE1\110", IF_PENT|IF_MMX}, - {I_PSRAW, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x71\204\25", IF_PENT|IF_MMX}, - {I_PSRAW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE1\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSRAW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE1\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSRAW, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x71\204\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSRLD[] = { - {I_PSRLD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD2\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSRLD, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD2\110", IF_PENT|IF_MMX}, - {I_PSRLD, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x72\202\25", IF_PENT|IF_MMX}, - {I_PSRLD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD2\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSRLD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD2\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSRLD, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x72\202\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSRLDQ[] = { - {I_PSRLDQ, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x73\203\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSRLQ[] = { - {I_PSRLQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD3\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSRLQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD3\110", IF_PENT|IF_MMX}, - {I_PSRLQ, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x73\202\25", IF_PENT|IF_MMX}, - {I_PSRLQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD3\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSRLQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD3\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSRLQ, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x73\202\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSRLW[] = { - {I_PSRLW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD1\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSRLW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD1\110", IF_PENT|IF_MMX}, - {I_PSRLW, 2, {MMXREG,IMMEDIATE,0}, "\2\x0F\x71\202\25", IF_PENT|IF_MMX}, - {I_PSRLW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD1\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSRLW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD1\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSRLW, 2, {XMMREG,IMMEDIATE,0}, "\3\x66\x0F\x71\202\25", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR1}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBB[] = { - {I_PSUBB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF8\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF8\110", IF_PENT|IF_MMX}, - {I_PSUBB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF8\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF8\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBD[] = { - {I_PSUBD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xFA\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBD, 2, {MMXREG,MMXREG,0}, "\2\x0F\xFA\110", IF_PENT|IF_MMX}, - {I_PSUBD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xFA\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xFA\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBQ[] = { - {I_PSUBQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\xFB\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSUBQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xFB\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xFB\110", IF_WILLAMETTE|IF_SSE2}, - {I_PSUBQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xFB\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBSB[] = { - {I_PSUBSB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE8\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBSB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE8\110", IF_PENT|IF_MMX}, - {I_PSUBSB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE8\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBSB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE8\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBSIW[] = { - {I_PSUBSIW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x55\110", IF_PENT|IF_MMX|IF_SM|IF_CYRIX}, - {I_PSUBSIW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x55\110", IF_PENT|IF_MMX|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBSW[] = { - {I_PSUBSW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xE9\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBSW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xE9\110", IF_PENT|IF_MMX}, - {I_PSUBSW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xE9\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBSW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xE9\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBUSB[] = { - {I_PSUBUSB, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD8\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBUSB, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD8\110", IF_PENT|IF_MMX}, - {I_PSUBUSB, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD8\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBUSB, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD8\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBUSW[] = { - {I_PSUBUSW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xD9\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBUSW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xD9\110", IF_PENT|IF_MMX}, - {I_PSUBUSW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xD9\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBUSW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xD9\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSUBW[] = { - {I_PSUBW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xF9\110", IF_PENT|IF_MMX|IF_SM}, - {I_PSUBW, 2, {MMXREG,MMXREG,0}, "\2\x0F\xF9\110", IF_PENT|IF_MMX}, - {I_PSUBW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xF9\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PSUBW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xF9\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PSWAPD[] = { - {I_PSWAPD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x0F\110\01\xBB", IF_PENT|IF_3DNOW|IF_SM}, - {I_PSWAPD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x0F\110\01\xBB", IF_PENT|IF_3DNOW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKHBW[] = { - {I_PUNPCKHBW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x68\110", IF_PENT|IF_MMX|IF_SM}, - {I_PUNPCKHBW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x68\110", IF_PENT|IF_MMX}, - {I_PUNPCKHBW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x68\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PUNPCKHBW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x68\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKHDQ[] = { - {I_PUNPCKHDQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x6A\110", IF_PENT|IF_MMX|IF_SM}, - {I_PUNPCKHDQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\x6A\110", IF_PENT|IF_MMX}, - {I_PUNPCKHDQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x6A\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PUNPCKHDQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x6A\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKHQDQ[] = { - {I_PUNPCKHQDQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x6D\110", IF_WILLAMETTE|IF_SSE2}, - {I_PUNPCKHQDQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x6D\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKHWD[] = { - {I_PUNPCKHWD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x69\110", IF_PENT|IF_MMX|IF_SM}, - {I_PUNPCKHWD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x69\110", IF_PENT|IF_MMX}, - {I_PUNPCKHWD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x69\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PUNPCKHWD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x69\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKLBW[] = { - {I_PUNPCKLBW, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x60\110", IF_PENT|IF_MMX|IF_SM}, - {I_PUNPCKLBW, 2, {MMXREG,MMXREG,0}, "\2\x0F\x60\110", IF_PENT|IF_MMX}, - {I_PUNPCKLBW, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x60\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PUNPCKLBW, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x60\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKLDQ[] = { - {I_PUNPCKLDQ, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x62\110", IF_PENT|IF_MMX|IF_SM}, - {I_PUNPCKLDQ, 2, {MMXREG,MMXREG,0}, "\2\x0F\x62\110", IF_PENT|IF_MMX}, - {I_PUNPCKLDQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x62\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PUNPCKLDQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x62\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKLQDQ[] = { - {I_PUNPCKLQDQ, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x6C\110", IF_WILLAMETTE|IF_SSE2}, - {I_PUNPCKLQDQ, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x6C\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUNPCKLWD[] = { - {I_PUNPCKLWD, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\x61\110", IF_PENT|IF_MMX|IF_SM}, - {I_PUNPCKLWD, 2, {MMXREG,MMXREG,0}, "\2\x0F\x61\110", IF_PENT|IF_MMX}, - {I_PUNPCKLWD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x61\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PUNPCKLWD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x61\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSH[] = { - {I_PUSH, 1, {REG16,0,0}, "\320\10\x50", IF_8086}, - {I_PUSH, 1, {REG32,0,0}, "\321\10\x50", IF_386}, - {I_PUSH, 1, {REGMEM|BITS16,0,0}, "\320\300\1\xFF\206", IF_8086}, - {I_PUSH, 1, {REGMEM|BITS32,0,0}, "\321\300\1\xFF\206", IF_386}, - {I_PUSH, 1, {REG_CS,0,0}, "\6", IF_8086}, - {I_PUSH, 1, {REG_DESS,0,0}, "\6", IF_8086}, - {I_PUSH, 1, {REG_FSGS,0,0}, "\1\x0F\7", IF_386}, - {I_PUSH, 1, {IMMEDIATE|BITS8,0,0}, "\1\x6A\14", IF_186}, - {I_PUSH, 1, {SBYTE,0,0}, "\1\x6A\14", IF_186}, - {I_PUSH, 1, {IMMEDIATE|BITS16,0,0}, "\320\133\1\x68\130", IF_186}, - {I_PUSH, 1, {IMMEDIATE|BITS32,0,0}, "\321\143\1\x68\140", IF_386}, - {I_PUSH, 1, {IMMEDIATE,0,0}, "\1\x68\34", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSHA[] = { - {I_PUSHA, 0, {0,0,0}, "\322\1\x60", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSHAD[] = { - {I_PUSHAD, 0, {0,0,0}, "\321\1\x60", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSHAW[] = { - {I_PUSHAW, 0, {0,0,0}, "\320\1\x60", IF_186}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSHF[] = { - {I_PUSHF, 0, {0,0,0}, "\322\1\x9C", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSHFD[] = { - {I_PUSHFD, 0, {0,0,0}, "\321\1\x9C", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PUSHFW[] = { - {I_PUSHFW, 0, {0,0,0}, "\320\1\x9C", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_PXOR[] = { - {I_PXOR, 2, {MMXREG,MEMORY,0}, "\301\2\x0F\xEF\110", IF_PENT|IF_MMX|IF_SM}, - {I_PXOR, 2, {MMXREG,MMXREG,0}, "\2\x0F\xEF\110", IF_PENT|IF_MMX}, - {I_PXOR, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\xEF\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - {I_PXOR, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\xEF\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RCL[] = { - {I_RCL, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\202", IF_8086}, - {I_RCL, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\202", IF_8086}, - {I_RCL, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\202\25", IF_186|IF_SB}, - {I_RCL, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\202", IF_8086}, - {I_RCL, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\202", IF_8086}, - {I_RCL, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\202\25", IF_186|IF_SB}, - {I_RCL, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\202", IF_386}, - {I_RCL, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\202", IF_386}, - {I_RCL, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\202\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RCPPS[] = { - {I_RCPPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x53\110", IF_KATMAI|IF_SSE}, - {I_RCPPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x53\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RCPSS[] = { - {I_RCPSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x53\110", IF_KATMAI|IF_SSE}, - {I_RCPSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x53\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RCR[] = { - {I_RCR, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\203", IF_8086}, - {I_RCR, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\203", IF_8086}, - {I_RCR, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\203\25", IF_186|IF_SB}, - {I_RCR, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\203", IF_8086}, - {I_RCR, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\203", IF_8086}, - {I_RCR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\203\25", IF_186|IF_SB}, - {I_RCR, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\203", IF_386}, - {I_RCR, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\203", IF_386}, - {I_RCR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\203\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RDMSR[] = { - {I_RDMSR, 0, {0,0,0}, "\2\x0F\x32", IF_PENT|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RDPMC[] = { - {I_RDPMC, 0, {0,0,0}, "\2\x0F\x33", IF_P6}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RDSHR[] = { - {I_RDSHR, 1, {REGMEM|BITS32,0,0}, "\321\300\2\x0F\x36\200", IF_P6|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RDTSC[] = { - {I_RDTSC, 0, {0,0,0}, "\2\x0F\x31", IF_PENT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RESB[] = { - {I_RESB, 1, {IMMEDIATE,0,0}, "\340", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RESD[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_RESQ[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_REST[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_RESW[] = { - ITEMPLATE_END -}; - -static struct itemplate instrux_RET[] = { - {I_RET, 0, {0,0,0}, "\1\xC3", IF_8086}, - {I_RET, 1, {IMMEDIATE,0,0}, "\1\xC2\30", IF_8086|IF_SW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RETF[] = { - {I_RETF, 0, {0,0,0}, "\1\xCB", IF_8086}, - {I_RETF, 1, {IMMEDIATE,0,0}, "\1\xCA\30", IF_8086|IF_SW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RETN[] = { - {I_RETN, 0, {0,0,0}, "\1\xC3", IF_8086}, - {I_RETN, 1, {IMMEDIATE,0,0}, "\1\xC2\30", IF_8086|IF_SW}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ROL[] = { - {I_ROL, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\200", IF_8086}, - {I_ROL, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\200", IF_8086}, - {I_ROL, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\200\25", IF_186|IF_SB}, - {I_ROL, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\200", IF_8086}, - {I_ROL, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\200", IF_8086}, - {I_ROL, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\200\25", IF_186|IF_SB}, - {I_ROL, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\200", IF_386}, - {I_ROL, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\200", IF_386}, - {I_ROL, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\200\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_ROR[] = { - {I_ROR, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\201", IF_8086}, - {I_ROR, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\201", IF_8086}, - {I_ROR, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\201\25", IF_186|IF_SB}, - {I_ROR, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\201", IF_8086}, - {I_ROR, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\201", IF_8086}, - {I_ROR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\201\25", IF_186|IF_SB}, - {I_ROR, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\201", IF_386}, - {I_ROR, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\201", IF_386}, - {I_ROR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\201\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RSDC[] = { - {I_RSDC, 2, {REG_SREG,MEMORY|BITS80,0}, "\301\2\x0F\x79\110", IF_486|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RSLDT[] = { - {I_RSLDT, 1, {MEMORY|BITS80,0,0}, "\300\2\x0F\x7B\200", IF_486|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RSM[] = { - {I_RSM, 0, {0,0,0}, "\2\x0F\xAA", IF_PENT|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RSQRTPS[] = { - {I_RSQRTPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x52\110", IF_KATMAI|IF_SSE}, - {I_RSQRTPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x52\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RSQRTSS[] = { - {I_RSQRTSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x52\110", IF_KATMAI|IF_SSE}, - {I_RSQRTSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x52\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_RSTS[] = { - {I_RSTS, 1, {MEMORY|BITS80,0,0}, "\300\2\x0F\x7D\200", IF_486|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SAHF[] = { - {I_SAHF, 0, {0,0,0}, "\1\x9E", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SAL[] = { - {I_SAL, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\204", IF_8086}, - {I_SAL, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\204", IF_8086}, - {I_SAL, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\204\25", IF_186|IF_SB}, - {I_SAL, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\204", IF_8086}, - {I_SAL, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\204", IF_8086}, - {I_SAL, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\204\25", IF_186|IF_SB}, - {I_SAL, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\204", IF_386}, - {I_SAL, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\204", IF_386}, - {I_SAL, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\204\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SALC[] = { - {I_SALC, 0, {0,0,0}, "\1\xD6", IF_8086|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SAR[] = { - {I_SAR, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\207", IF_8086}, - {I_SAR, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\207", IF_8086}, - {I_SAR, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\207\25", IF_186|IF_SB}, - {I_SAR, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\207", IF_8086}, - {I_SAR, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\207", IF_8086}, - {I_SAR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\207\25", IF_186|IF_SB}, - {I_SAR, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\207", IF_386}, - {I_SAR, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\207", IF_386}, - {I_SAR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\207\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SBB[] = { - {I_SBB, 2, {MEMORY,REG8,0}, "\300\1\x18\101", IF_8086|IF_SM}, - {I_SBB, 2, {REG8,REG8,0}, "\1\x18\101", IF_8086}, - {I_SBB, 2, {MEMORY,REG16,0}, "\320\300\1\x19\101", IF_8086|IF_SM}, - {I_SBB, 2, {REG16,REG16,0}, "\320\1\x19\101", IF_8086}, - {I_SBB, 2, {MEMORY,REG32,0}, "\321\300\1\x19\101", IF_386|IF_SM}, - {I_SBB, 2, {REG32,REG32,0}, "\321\1\x19\101", IF_386}, - {I_SBB, 2, {REG8,MEMORY,0}, "\301\1\x1A\110", IF_8086|IF_SM}, - {I_SBB, 2, {REG8,REG8,0}, "\1\x1A\110", IF_8086}, - {I_SBB, 2, {REG16,MEMORY,0}, "\320\301\1\x1B\110", IF_8086|IF_SM}, - {I_SBB, 2, {REG16,REG16,0}, "\320\1\x1B\110", IF_8086}, - {I_SBB, 2, {REG32,MEMORY,0}, "\321\301\1\x1B\110", IF_386|IF_SM}, - {I_SBB, 2, {REG32,REG32,0}, "\321\1\x1B\110", IF_386}, - {I_SBB, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\203\15", IF_8086}, - {I_SBB, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\203\15", IF_386}, - {I_SBB, 2, {REG_AL,IMMEDIATE,0}, "\1\x1C\21", IF_8086|IF_SM}, - {I_SBB, 2, {REG_AX,SBYTE,0}, "\320\1\x83\203\15", IF_8086|IF_SM}, - {I_SBB, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x1D\31", IF_8086|IF_SM}, - {I_SBB, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\203\15", IF_386|IF_SM}, - {I_SBB, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x1D\41", IF_386|IF_SM}, - {I_SBB, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\203\21", IF_8086|IF_SM}, - {I_SBB, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\203\131", IF_8086|IF_SM}, - {I_SBB, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\203\141", IF_386|IF_SM}, - {I_SBB, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\203\21", IF_8086|IF_SM}, - {I_SBB, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\203\131", IF_8086|IF_SM}, - {I_SBB, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\203\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SCASB[] = { - {I_SCASB, 0, {0,0,0}, "\332\1\xAE", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SCASD[] = { - {I_SCASD, 0, {0,0,0}, "\332\321\1\xAF", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SCASW[] = { - {I_SCASW, 0, {0,0,0}, "\332\320\1\xAF", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SFENCE[] = { - {I_SFENCE, 0, {0,0,0}, "\3\x0F\xAE\xF8", IF_KATMAI}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SGDT[] = { - {I_SGDT, 1, {MEMORY,0,0}, "\300\2\x0F\x01\200", IF_286}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SHL[] = { - {I_SHL, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\204", IF_8086}, - {I_SHL, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\204", IF_8086}, - {I_SHL, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\204\25", IF_186|IF_SB}, - {I_SHL, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\204", IF_8086}, - {I_SHL, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\204", IF_8086}, - {I_SHL, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\204\25", IF_186|IF_SB}, - {I_SHL, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\204", IF_386}, - {I_SHL, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\204", IF_386}, - {I_SHL, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\204\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SHLD[] = { - {I_SHLD, 3, {MEMORY,REG16,IMMEDIATE}, "\300\320\2\x0F\xA4\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHLD, 3, {REG16,REG16,IMMEDIATE}, "\320\2\x0F\xA4\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHLD, 3, {MEMORY,REG32,IMMEDIATE}, "\300\321\2\x0F\xA4\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHLD, 3, {REG32,REG32,IMMEDIATE}, "\321\2\x0F\xA4\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHLD, 3, {MEMORY,REG16,REG_CL}, "\300\320\2\x0F\xA5\101", IF_386|IF_SM}, - {I_SHLD, 3, {REG16,REG16,REG_CL}, "\320\2\x0F\xA5\101", IF_386}, - {I_SHLD, 3, {MEMORY,REG32,REG_CL}, "\300\321\2\x0F\xA5\101", IF_386|IF_SM}, - {I_SHLD, 3, {REG32,REG32,REG_CL}, "\321\2\x0F\xA5\101", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SHR[] = { - {I_SHR, 2, {REGMEM|BITS8,UNITY,0}, "\300\1\xD0\205", IF_8086}, - {I_SHR, 2, {REGMEM|BITS8,REG_CL,0}, "\300\1\xD2\205", IF_8086}, - {I_SHR, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xC0\205\25", IF_186|IF_SB}, - {I_SHR, 2, {REGMEM|BITS16,UNITY,0}, "\320\300\1\xD1\205", IF_8086}, - {I_SHR, 2, {REGMEM|BITS16,REG_CL,0}, "\320\300\1\xD3\205", IF_8086}, - {I_SHR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xC1\205\25", IF_186|IF_SB}, - {I_SHR, 2, {REGMEM|BITS32,UNITY,0}, "\321\300\1\xD1\205", IF_386}, - {I_SHR, 2, {REGMEM|BITS32,REG_CL,0}, "\321\300\1\xD3\205", IF_386}, - {I_SHR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xC1\205\25", IF_386|IF_SB}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SHRD[] = { - {I_SHRD, 3, {MEMORY,REG16,IMMEDIATE}, "\300\320\2\x0F\xAC\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHRD, 3, {REG16,REG16,IMMEDIATE}, "\320\2\x0F\xAC\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHRD, 3, {MEMORY,REG32,IMMEDIATE}, "\300\321\2\x0F\xAC\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHRD, 3, {REG32,REG32,IMMEDIATE}, "\321\2\x0F\xAC\101\26", IF_386|IF_SM2|IF_SB|IF_AR2}, - {I_SHRD, 3, {MEMORY,REG16,REG_CL}, "\300\320\2\x0F\xAD\101", IF_386|IF_SM}, - {I_SHRD, 3, {REG16,REG16,REG_CL}, "\320\2\x0F\xAD\101", IF_386}, - {I_SHRD, 3, {MEMORY,REG32,REG_CL}, "\300\321\2\x0F\xAD\101", IF_386|IF_SM}, - {I_SHRD, 3, {REG32,REG32,REG_CL}, "\321\2\x0F\xAD\101", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SHUFPD[] = { - {I_SHUFPD, 3, {XMMREG,XMMREG,IMMEDIATE}, "\3\x66\x0F\xC6\110\26", IF_WILLAMETTE|IF_SSE2|IF_SB|IF_AR2}, - {I_SHUFPD, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\3\x66\x0F\xC6\110\26", IF_WILLAMETTE|IF_SSE2|IF_SM|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SHUFPS[] = { - {I_SHUFPS, 3, {XMMREG,MEMORY,IMMEDIATE}, "\301\2\x0F\xC6\110\26", IF_KATMAI|IF_SSE|IF_SB|IF_AR2}, - {I_SHUFPS, 3, {XMMREG,XMMREG,IMMEDIATE}, "\2\x0F\xC6\110\26", IF_KATMAI|IF_SSE|IF_SB|IF_AR2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SIDT[] = { - {I_SIDT, 1, {MEMORY,0,0}, "\300\2\x0F\x01\201", IF_286}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SLDT[] = { - {I_SLDT, 1, {MEMORY,0,0}, "\300\1\x0F\17\200", IF_286}, - {I_SLDT, 1, {MEMORY|BITS16,0,0}, "\300\1\x0F\17\200", IF_286}, - {I_SLDT, 1, {REG16,0,0}, "\320\1\x0F\17\200", IF_286}, - {I_SLDT, 1, {REG32,0,0}, "\321\1\x0F\17\200", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SMI[] = { - {I_SMI, 0, {0,0,0}, "\1\xF1", IF_386|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SMINT[] = { - {I_SMINT, 0, {0,0,0}, "\2\x0F\x38", IF_P6|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SMINTOLD[] = { - {I_SMINTOLD, 0, {0,0,0}, "\2\x0F\x7E", IF_486|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SMSW[] = { - {I_SMSW, 1, {MEMORY,0,0}, "\300\2\x0F\x01\204", IF_286}, - {I_SMSW, 1, {MEMORY|BITS16,0,0}, "\300\2\x0F\x01\204", IF_286}, - {I_SMSW, 1, {REG16,0,0}, "\320\2\x0F\x01\204", IF_286}, - {I_SMSW, 1, {REG32,0,0}, "\321\2\x0F\x01\204", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SQRTPD[] = { - {I_SQRTPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x51\110", IF_WILLAMETTE|IF_SSE2}, - {I_SQRTPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x51\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SQRTPS[] = { - {I_SQRTPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x51\110", IF_KATMAI|IF_SSE}, - {I_SQRTPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x51\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SQRTSD[] = { - {I_SQRTSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x51\110", IF_WILLAMETTE|IF_SSE2}, - {I_SQRTSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x51\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SQRTSS[] = { - {I_SQRTSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x51\110", IF_KATMAI|IF_SSE}, - {I_SQRTSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x51\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STC[] = { - {I_STC, 0, {0,0,0}, "\1\xF9", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STD[] = { - {I_STD, 0, {0,0,0}, "\1\xFD", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STI[] = { - {I_STI, 0, {0,0,0}, "\1\xFB", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STMXCSR[] = { - {I_STMXCSR, 1, {MEMORY,0,0}, "\300\2\x0F\xAE\203", IF_KATMAI|IF_SSE|IF_SD}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STOSB[] = { - {I_STOSB, 0, {0,0,0}, "\1\xAA", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STOSD[] = { - {I_STOSD, 0, {0,0,0}, "\321\1\xAB", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STOSW[] = { - {I_STOSW, 0, {0,0,0}, "\320\1\xAB", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_STR[] = { - {I_STR, 1, {MEMORY,0,0}, "\300\1\x0F\17\201", IF_286|IF_PROT}, - {I_STR, 1, {MEMORY|BITS16,0,0}, "\300\1\x0F\17\201", IF_286|IF_PROT}, - {I_STR, 1, {REG16,0,0}, "\320\1\x0F\17\201", IF_286|IF_PROT}, - {I_STR, 1, {REG32,0,0}, "\321\1\x0F\17\201", IF_386|IF_PROT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SUB[] = { - {I_SUB, 2, {MEMORY,REG8,0}, "\300\1\x28\101", IF_8086|IF_SM}, - {I_SUB, 2, {REG8,REG8,0}, "\1\x28\101", IF_8086}, - {I_SUB, 2, {MEMORY,REG16,0}, "\320\300\1\x29\101", IF_8086|IF_SM}, - {I_SUB, 2, {REG16,REG16,0}, "\320\1\x29\101", IF_8086}, - {I_SUB, 2, {MEMORY,REG32,0}, "\321\300\1\x29\101", IF_386|IF_SM}, - {I_SUB, 2, {REG32,REG32,0}, "\321\1\x29\101", IF_386}, - {I_SUB, 2, {REG8,MEMORY,0}, "\301\1\x2A\110", IF_8086|IF_SM}, - {I_SUB, 2, {REG8,REG8,0}, "\1\x2A\110", IF_8086}, - {I_SUB, 2, {REG16,MEMORY,0}, "\320\301\1\x2B\110", IF_8086|IF_SM}, - {I_SUB, 2, {REG16,REG16,0}, "\320\1\x2B\110", IF_8086}, - {I_SUB, 2, {REG32,MEMORY,0}, "\321\301\1\x2B\110", IF_386|IF_SM}, - {I_SUB, 2, {REG32,REG32,0}, "\321\1\x2B\110", IF_386}, - {I_SUB, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\205\15", IF_8086}, - {I_SUB, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\205\15", IF_386}, - {I_SUB, 2, {REG_AL,IMMEDIATE,0}, "\1\x2C\21", IF_8086|IF_SM}, - {I_SUB, 2, {REG_AX,SBYTE,0}, "\320\1\x83\205\15", IF_8086|IF_SM}, - {I_SUB, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x2D\31", IF_8086|IF_SM}, - {I_SUB, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\205\15", IF_386|IF_SM}, - {I_SUB, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x2D\41", IF_386|IF_SM}, - {I_SUB, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\205\21", IF_8086|IF_SM}, - {I_SUB, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\205\131", IF_8086|IF_SM}, - {I_SUB, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\205\141", IF_386|IF_SM}, - {I_SUB, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\205\21", IF_8086|IF_SM}, - {I_SUB, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\205\131", IF_8086|IF_SM}, - {I_SUB, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\205\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SUBPD[] = { - {I_SUBPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x5C\110", IF_WILLAMETTE|IF_SSE2}, - {I_SUBPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x5C\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SUBPS[] = { - {I_SUBPS, 2, {XMMREG,MEMORY,0}, "\301\331\2\x0F\x5C\110", IF_KATMAI|IF_SSE}, - {I_SUBPS, 2, {XMMREG,XMMREG,0}, "\331\2\x0F\x5C\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SUBSD[] = { - {I_SUBSD, 2, {XMMREG,XMMREG,0}, "\3\xF2\x0F\x5C\110", IF_WILLAMETTE|IF_SSE2}, - {I_SUBSD, 2, {XMMREG,MEMORY,0}, "\301\3\xF2\x0F\x5C\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SUBSS[] = { - {I_SUBSS, 2, {XMMREG,MEMORY,0}, "\301\333\2\x0F\x5C\110", IF_KATMAI|IF_SSE}, - {I_SUBSS, 2, {XMMREG,XMMREG,0}, "\333\2\x0F\x5C\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SVDC[] = { - {I_SVDC, 2, {MEMORY|BITS80,REG_SREG,0}, "\300\2\x0F\x78\101", IF_486|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SVLDT[] = { - {I_SVLDT, 1, {MEMORY|BITS80,0,0}, "\300\2\x0F\x7A\200", IF_486|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SVTS[] = { - {I_SVTS, 1, {MEMORY|BITS80,0,0}, "\300\2\x0F\x7C\200", IF_486|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SYSCALL[] = { - {I_SYSCALL, 0, {0,0,0}, "\2\x0F\x05", IF_P6|IF_AMD}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SYSENTER[] = { - {I_SYSENTER, 0, {0,0,0}, "\2\x0F\x34", IF_P6}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SYSEXIT[] = { - {I_SYSEXIT, 0, {0,0,0}, "\2\x0F\x35", IF_P6|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SYSRET[] = { - {I_SYSRET, 0, {0,0,0}, "\2\x0F\x07", IF_P6|IF_PRIV|IF_AMD}, - ITEMPLATE_END -}; - -static struct itemplate instrux_TEST[] = { - {I_TEST, 2, {MEMORY,REG8,0}, "\300\1\x84\101", IF_8086|IF_SM}, - {I_TEST, 2, {REG8,REG8,0}, "\1\x84\101", IF_8086}, - {I_TEST, 2, {MEMORY,REG16,0}, "\320\300\1\x85\101", IF_8086|IF_SM}, - {I_TEST, 2, {REG16,REG16,0}, "\320\1\x85\101", IF_8086}, - {I_TEST, 2, {MEMORY,REG32,0}, "\321\300\1\x85\101", IF_386|IF_SM}, - {I_TEST, 2, {REG32,REG32,0}, "\321\1\x85\101", IF_386}, - {I_TEST, 2, {REG8,MEMORY,0}, "\301\1\x84\110", IF_8086|IF_SM}, - {I_TEST, 2, {REG16,MEMORY,0}, "\320\301\1\x85\110", IF_8086|IF_SM}, - {I_TEST, 2, {REG32,MEMORY,0}, "\321\301\1\x85\110", IF_386|IF_SM}, - {I_TEST, 2, {REG_AL,IMMEDIATE,0}, "\1\xA8\21", IF_8086|IF_SM}, - {I_TEST, 2, {REG_AX,IMMEDIATE,0}, "\320\1\xA9\31", IF_8086|IF_SM}, - {I_TEST, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\xA9\41", IF_386|IF_SM}, - {I_TEST, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\xF6\200\21", IF_8086|IF_SM}, - {I_TEST, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\1\xF7\200\31", IF_8086|IF_SM}, - {I_TEST, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\1\xF7\200\41", IF_386|IF_SM}, - {I_TEST, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\xF6\200\21", IF_8086|IF_SM}, - {I_TEST, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\1\xF7\200\31", IF_8086|IF_SM}, - {I_TEST, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\1\xF7\200\41", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UCOMISD[] = { - {I_UCOMISD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x2E\110", IF_WILLAMETTE|IF_SSE2}, - {I_UCOMISD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x2E\110", IF_WILLAMETTE|IF_SSE2}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UCOMISS[] = { - {I_UCOMISS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x2E\110", IF_KATMAI|IF_SSE}, - {I_UCOMISS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x2E\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UD0[] = { - {I_UD0, 0, {0,0,0}, "\2\x0F\xFF", IF_286|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UD1[] = { - {I_UD1, 0, {0,0,0}, "\2\x0F\xB9", IF_286|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UD2[] = { - {I_UD2, 0, {0,0,0}, "\2\x0F\x0B", IF_286}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UMOV[] = { - {I_UMOV, 2, {MEMORY,REG8,0}, "\300\2\x0F\x10\101", IF_386|IF_UNDOC|IF_SM}, - {I_UMOV, 2, {REG8,REG8,0}, "\2\x0F\x10\101", IF_386|IF_UNDOC}, - {I_UMOV, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\x11\101", IF_386|IF_UNDOC|IF_SM}, - {I_UMOV, 2, {REG16,REG16,0}, "\320\2\x0F\x11\101", IF_386|IF_UNDOC}, - {I_UMOV, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\x11\101", IF_386|IF_UNDOC|IF_SM}, - {I_UMOV, 2, {REG32,REG32,0}, "\321\2\x0F\x11\101", IF_386|IF_UNDOC}, - {I_UMOV, 2, {REG8,MEMORY,0}, "\301\2\x0F\x12\110", IF_386|IF_UNDOC|IF_SM}, - {I_UMOV, 2, {REG8,REG8,0}, "\2\x0F\x12\110", IF_386|IF_UNDOC}, - {I_UMOV, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\x13\110", IF_386|IF_UNDOC|IF_SM}, - {I_UMOV, 2, {REG16,REG16,0}, "\320\2\x0F\x13\110", IF_386|IF_UNDOC}, - {I_UMOV, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\x13\110", IF_386|IF_UNDOC|IF_SM}, - {I_UMOV, 2, {REG32,REG32,0}, "\321\2\x0F\x13\110", IF_386|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UNPCKHPD[] = { - {I_UNPCKHPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x15\110", IF_WILLAMETTE|IF_SSE2}, - {I_UNPCKHPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x15\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UNPCKHPS[] = { - {I_UNPCKHPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x15\110", IF_KATMAI|IF_SSE}, - {I_UNPCKHPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x15\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UNPCKLPD[] = { - {I_UNPCKLPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x14\110", IF_WILLAMETTE|IF_SSE2}, - {I_UNPCKLPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x14\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_UNPCKLPS[] = { - {I_UNPCKLPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x14\110", IF_KATMAI|IF_SSE}, - {I_UNPCKLPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x14\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_VERR[] = { - {I_VERR, 1, {MEMORY,0,0}, "\300\1\x0F\17\204", IF_286|IF_PROT}, - {I_VERR, 1, {MEMORY|BITS16,0,0}, "\300\1\x0F\17\204", IF_286|IF_PROT}, - {I_VERR, 1, {REG16,0,0}, "\1\x0F\17\204", IF_286|IF_PROT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_VERW[] = { - {I_VERW, 1, {MEMORY,0,0}, "\300\1\x0F\17\205", IF_286|IF_PROT}, - {I_VERW, 1, {MEMORY|BITS16,0,0}, "\300\1\x0F\17\205", IF_286|IF_PROT}, - {I_VERW, 1, {REG16,0,0}, "\1\x0F\17\205", IF_286|IF_PROT}, - ITEMPLATE_END -}; - -static struct itemplate instrux_WAIT[] = { - {I_WAIT, 0, {0,0,0}, "\1\x9B", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_WBINVD[] = { - {I_WBINVD, 0, {0,0,0}, "\2\x0F\x09", IF_486|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_WRMSR[] = { - {I_WRMSR, 0, {0,0,0}, "\2\x0F\x30", IF_PENT|IF_PRIV}, - ITEMPLATE_END -}; - -static struct itemplate instrux_WRSHR[] = { - {I_WRSHR, 1, {REGMEM|BITS32,0,0}, "\321\300\2\x0F\x37\200", IF_P6|IF_CYRIX|IF_SMM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XADD[] = { - {I_XADD, 2, {MEMORY,REG8,0}, "\300\2\x0F\xC0\101", IF_486|IF_SM}, - {I_XADD, 2, {REG8,REG8,0}, "\2\x0F\xC0\101", IF_486}, - {I_XADD, 2, {MEMORY,REG16,0}, "\320\300\2\x0F\xC1\101", IF_486|IF_SM}, - {I_XADD, 2, {REG16,REG16,0}, "\320\2\x0F\xC1\101", IF_486}, - {I_XADD, 2, {MEMORY,REG32,0}, "\321\300\2\x0F\xC1\101", IF_486|IF_SM}, - {I_XADD, 2, {REG32,REG32,0}, "\321\2\x0F\xC1\101", IF_486}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XBTS[] = { - {I_XBTS, 2, {REG16,MEMORY,0}, "\320\301\2\x0F\xA6\110", IF_386|IF_SW|IF_UNDOC}, - {I_XBTS, 2, {REG16,REG16,0}, "\320\2\x0F\xA6\110", IF_386|IF_UNDOC}, - {I_XBTS, 2, {REG32,MEMORY,0}, "\321\301\2\x0F\xA6\110", IF_386|IF_SD|IF_UNDOC}, - {I_XBTS, 2, {REG32,REG32,0}, "\321\2\x0F\xA6\110", IF_386|IF_UNDOC}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XCHG[] = { - {I_XCHG, 2, {REG_AX,REG16,0}, "\320\11\x90", IF_8086}, - {I_XCHG, 2, {REG_EAX,REG32,0}, "\321\11\x90", IF_386}, - {I_XCHG, 2, {REG16,REG_AX,0}, "\320\10\x90", IF_8086}, - {I_XCHG, 2, {REG32,REG_EAX,0}, "\321\10\x90", IF_386}, - {I_XCHG, 2, {REG8,MEMORY,0}, "\301\1\x86\110", IF_8086|IF_SM}, - {I_XCHG, 2, {REG8,REG8,0}, "\1\x86\110", IF_8086}, - {I_XCHG, 2, {REG16,MEMORY,0}, "\320\301\1\x87\110", IF_8086|IF_SM}, - {I_XCHG, 2, {REG16,REG16,0}, "\320\1\x87\110", IF_8086}, - {I_XCHG, 2, {REG32,MEMORY,0}, "\321\301\1\x87\110", IF_386|IF_SM}, - {I_XCHG, 2, {REG32,REG32,0}, "\321\1\x87\110", IF_386}, - {I_XCHG, 2, {MEMORY,REG8,0}, "\300\1\x86\101", IF_8086|IF_SM}, - {I_XCHG, 2, {REG8,REG8,0}, "\1\x86\101", IF_8086}, - {I_XCHG, 2, {MEMORY,REG16,0}, "\320\300\1\x87\101", IF_8086|IF_SM}, - {I_XCHG, 2, {REG16,REG16,0}, "\320\1\x87\101", IF_8086}, - {I_XCHG, 2, {MEMORY,REG32,0}, "\321\300\1\x87\101", IF_386|IF_SM}, - {I_XCHG, 2, {REG32,REG32,0}, "\321\1\x87\101", IF_386}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XLAT[] = { - {I_XLAT, 0, {0,0,0}, "\1\xD7", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XLATB[] = { - {I_XLATB, 0, {0,0,0}, "\1\xD7", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XOR[] = { - {I_XOR, 2, {MEMORY,REG8,0}, "\300\1\x30\101", IF_8086|IF_SM}, - {I_XOR, 2, {REG8,REG8,0}, "\1\x30\101", IF_8086}, - {I_XOR, 2, {MEMORY,REG16,0}, "\320\300\1\x31\101", IF_8086|IF_SM}, - {I_XOR, 2, {REG16,REG16,0}, "\320\1\x31\101", IF_8086}, - {I_XOR, 2, {MEMORY,REG32,0}, "\321\300\1\x31\101", IF_386|IF_SM}, - {I_XOR, 2, {REG32,REG32,0}, "\321\1\x31\101", IF_386}, - {I_XOR, 2, {REG8,MEMORY,0}, "\301\1\x32\110", IF_8086|IF_SM}, - {I_XOR, 2, {REG8,REG8,0}, "\1\x32\110", IF_8086}, - {I_XOR, 2, {REG16,MEMORY,0}, "\320\301\1\x33\110", IF_8086|IF_SM}, - {I_XOR, 2, {REG16,REG16,0}, "\320\1\x33\110", IF_8086}, - {I_XOR, 2, {REG32,MEMORY,0}, "\321\301\1\x33\110", IF_386|IF_SM}, - {I_XOR, 2, {REG32,REG32,0}, "\321\1\x33\110", IF_386}, - {I_XOR, 2, {REGMEM|BITS16,IMMEDIATE|BITS8,0}, "\320\300\1\x83\206\15", IF_8086}, - {I_XOR, 2, {REGMEM|BITS32,IMMEDIATE|BITS8,0}, "\321\300\1\x83\206\15", IF_386}, - {I_XOR, 2, {REG_AL,IMMEDIATE,0}, "\1\x34\21", IF_8086|IF_SM}, - {I_XOR, 2, {REG_AX,SBYTE,0}, "\320\1\x83\206\15", IF_8086|IF_SM}, - {I_XOR, 2, {REG_AX,IMMEDIATE,0}, "\320\1\x35\31", IF_8086|IF_SM}, - {I_XOR, 2, {REG_EAX,SBYTE,0}, "\321\1\x83\206\15", IF_386|IF_SM}, - {I_XOR, 2, {REG_EAX,IMMEDIATE,0}, "\321\1\x35\41", IF_386|IF_SM}, - {I_XOR, 2, {REGMEM|BITS8,IMMEDIATE,0}, "\300\1\x80\206\21", IF_8086|IF_SM}, - {I_XOR, 2, {REGMEM|BITS16,IMMEDIATE,0}, "\320\300\134\1\x81\206\131", IF_8086|IF_SM}, - {I_XOR, 2, {REGMEM|BITS32,IMMEDIATE,0}, "\321\300\144\1\x81\206\141", IF_386|IF_SM}, - {I_XOR, 2, {MEMORY,IMMEDIATE|BITS8,0}, "\300\1\x80\206\21", IF_8086|IF_SM}, - {I_XOR, 2, {MEMORY,IMMEDIATE|BITS16,0}, "\320\300\134\1\x81\206\131", IF_8086|IF_SM}, - {I_XOR, 2, {MEMORY,IMMEDIATE|BITS32,0}, "\321\300\144\1\x81\206\141", IF_386|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XORPD[] = { - {I_XORPD, 2, {XMMREG,XMMREG,0}, "\3\x66\x0F\x57\110", IF_WILLAMETTE|IF_SSE2}, - {I_XORPD, 2, {XMMREG,MEMORY,0}, "\301\3\x66\x0F\x57\110", IF_WILLAMETTE|IF_SSE2|IF_SM}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XORPS[] = { - {I_XORPS, 2, {XMMREG,MEMORY,0}, "\301\2\x0F\x57\110", IF_KATMAI|IF_SSE}, - {I_XORPS, 2, {XMMREG,XMMREG,0}, "\2\x0F\x57\110", IF_KATMAI|IF_SSE}, - ITEMPLATE_END -}; - -static struct itemplate instrux_XSTORE[] = { - {I_XSTORE, 0, {0,0,0}, "\3\x0F\xA7\xC0", IF_P6|IF_CYRIX}, - ITEMPLATE_END -}; - -static struct itemplate instrux_CMOVcc[] = { - {I_CMOVcc, 2, {REG16,MEMORY,0}, "\320\301\1\x0F\330\x40\110", IF_P6|IF_SM}, - {I_CMOVcc, 2, {REG16,REG16,0}, "\320\1\x0F\330\x40\110", IF_P6}, - {I_CMOVcc, 2, {REG32,MEMORY,0}, "\321\301\1\x0F\330\x40\110", IF_P6|IF_SM}, - {I_CMOVcc, 2, {REG32,REG32,0}, "\321\1\x0F\330\x40\110", IF_P6}, - ITEMPLATE_END -}; - -static struct itemplate instrux_Jcc[] = { - {I_Jcc, 1, {IMMEDIATE|NEAR,0,0}, "\322\1\x0F\330\x80\64", IF_386}, - {I_Jcc, 1, {IMMEDIATE|BITS16|NEAR,0,0}, "\320\1\x0F\330\x80\64", IF_386}, - {I_Jcc, 1, {IMMEDIATE|BITS32|NEAR,0,0}, "\321\1\x0F\330\x80\64", IF_386}, - {I_Jcc, 1, {IMMEDIATE|SHORT,0,0}, "\330\x70\50", IF_8086}, - {I_Jcc, 1, {IMMEDIATE,0,0}, "\370\330\x70\50", IF_8086}, - {I_Jcc, 1, {IMMEDIATE,0,0}, "\1\x0F\330\x80\64", IF_386}, - {I_Jcc, 1, {IMMEDIATE,0,0}, "\330\x71\373\1\xE9\64", IF_8086}, - {I_Jcc, 1, {IMMEDIATE,0,0}, "\330\x70\50", IF_8086}, - ITEMPLATE_END -}; - -static struct itemplate instrux_SETcc[] = { - {I_SETcc, 1, {MEMORY,0,0}, "\300\1\x0F\330\x90\200", IF_386|IF_SB}, - {I_SETcc, 1, {REG8,0,0}, "\300\1\x0F\330\x90\200", IF_386}, - ITEMPLATE_END -}; - -struct itemplate *nasm_instructions[] = { - instrux_AAA, - instrux_AAD, - instrux_AAM, - instrux_AAS, - instrux_ADC, - instrux_ADD, - instrux_ADDPD, - instrux_ADDPS, - instrux_ADDSD, - instrux_ADDSS, - instrux_ADDSUBPD, - instrux_ADDSUBPS, - instrux_AND, - instrux_ANDNPD, - instrux_ANDNPS, - instrux_ANDPD, - instrux_ANDPS, - instrux_ARPL, - instrux_BOUND, - instrux_BSF, - instrux_BSR, - instrux_BSWAP, - instrux_BT, - instrux_BTC, - instrux_BTR, - instrux_BTS, - instrux_CALL, - instrux_CBW, - instrux_CDQ, - instrux_CLC, - instrux_CLD, - instrux_CLFLUSH, - instrux_CLI, - instrux_CLTS, - instrux_CMC, - instrux_CMP, - instrux_CMPEQPD, - instrux_CMPEQPS, - instrux_CMPEQSD, - instrux_CMPEQSS, - instrux_CMPLEPD, - instrux_CMPLEPS, - instrux_CMPLESD, - instrux_CMPLESS, - instrux_CMPLTPD, - instrux_CMPLTPS, - instrux_CMPLTSD, - instrux_CMPLTSS, - instrux_CMPNEQPD, - instrux_CMPNEQPS, - instrux_CMPNEQSD, - instrux_CMPNEQSS, - instrux_CMPNLEPD, - instrux_CMPNLEPS, - instrux_CMPNLESD, - instrux_CMPNLESS, - instrux_CMPNLTPD, - instrux_CMPNLTPS, - instrux_CMPNLTSD, - instrux_CMPNLTSS, - instrux_CMPORDPD, - instrux_CMPORDPS, - instrux_CMPORDSD, - instrux_CMPORDSS, - instrux_CMPPD, - instrux_CMPPS, - instrux_CMPSB, - instrux_CMPSD, - instrux_CMPSS, - instrux_CMPSW, - instrux_CMPUNORDPD, - instrux_CMPUNORDPS, - instrux_CMPUNORDSD, - instrux_CMPUNORDSS, - instrux_CMPXCHG, - instrux_CMPXCHG486, - instrux_CMPXCHG8B, - instrux_COMISD, - instrux_COMISS, - instrux_CPUID, - instrux_CVTDQ2PD, - instrux_CVTDQ2PS, - instrux_CVTPD2DQ, - instrux_CVTPD2PI, - instrux_CVTPD2PS, - instrux_CVTPI2PD, - instrux_CVTPI2PS, - instrux_CVTPS2DQ, - instrux_CVTPS2PD, - instrux_CVTPS2PI, - instrux_CVTSD2SI, - instrux_CVTSD2SS, - instrux_CVTSI2SD, - instrux_CVTSI2SS, - instrux_CVTSS2SD, - instrux_CVTSS2SI, - instrux_CVTTPD2DQ, - instrux_CVTTPD2PI, - instrux_CVTTPS2DQ, - instrux_CVTTPS2PI, - instrux_CVTTSD2SI, - instrux_CVTTSS2SI, - instrux_CWD, - instrux_CWDE, - instrux_DAA, - instrux_DAS, - instrux_DB, - instrux_DD, - instrux_DEC, - instrux_DIV, - instrux_DIVPD, - instrux_DIVPS, - instrux_DIVSD, - instrux_DIVSS, - instrux_DQ, - instrux_DT, - instrux_DW, - instrux_EMMS, - instrux_ENTER, - instrux_EQU, - instrux_F2XM1, - instrux_FABS, - instrux_FADD, - instrux_FADDP, - instrux_FBLD, - instrux_FBSTP, - instrux_FCHS, - instrux_FCLEX, - instrux_FCMOVB, - instrux_FCMOVBE, - instrux_FCMOVE, - instrux_FCMOVNB, - instrux_FCMOVNBE, - instrux_FCMOVNE, - instrux_FCMOVNU, - instrux_FCMOVU, - instrux_FCOM, - instrux_FCOMI, - instrux_FCOMIP, - instrux_FCOMP, - instrux_FCOMPP, - instrux_FCOS, - instrux_FDECSTP, - instrux_FDISI, - instrux_FDIV, - instrux_FDIVP, - instrux_FDIVR, - instrux_FDIVRP, - instrux_FEMMS, - instrux_FENI, - instrux_FFREE, - instrux_FFREEP, - instrux_FIADD, - instrux_FICOM, - instrux_FICOMP, - instrux_FIDIV, - instrux_FIDIVR, - instrux_FILD, - instrux_FIMUL, - instrux_FINCSTP, - instrux_FINIT, - instrux_FIST, - instrux_FISTP, - instrux_FISTTP, - instrux_FISUB, - instrux_FISUBR, - instrux_FLD, - instrux_FLD1, - instrux_FLDCW, - instrux_FLDENV, - instrux_FLDL2E, - instrux_FLDL2T, - instrux_FLDLG2, - instrux_FLDLN2, - instrux_FLDPI, - instrux_FLDZ, - instrux_FMUL, - instrux_FMULP, - instrux_FNCLEX, - instrux_FNDISI, - instrux_FNENI, - instrux_FNINIT, - instrux_FNOP, - instrux_FNSAVE, - instrux_FNSTCW, - instrux_FNSTENV, - instrux_FNSTSW, - instrux_FPATAN, - instrux_FPREM, - instrux_FPREM1, - instrux_FPTAN, - instrux_FRNDINT, - instrux_FRSTOR, - instrux_FSAVE, - instrux_FSCALE, - instrux_FSETPM, - instrux_FSIN, - instrux_FSINCOS, - instrux_FSQRT, - instrux_FST, - instrux_FSTCW, - instrux_FSTENV, - instrux_FSTP, - instrux_FSTSW, - instrux_FSUB, - instrux_FSUBP, - instrux_FSUBR, - instrux_FSUBRP, - instrux_FTST, - instrux_FUCOM, - instrux_FUCOMI, - instrux_FUCOMIP, - instrux_FUCOMP, - instrux_FUCOMPP, - instrux_FWAIT, - instrux_FXAM, - instrux_FXCH, - instrux_FXRSTOR, - instrux_FXSAVE, - instrux_FXTRACT, - instrux_FYL2X, - instrux_FYL2XP1, - instrux_HADDPD, - instrux_HADDPS, - instrux_HLT, - instrux_HSUBPD, - instrux_HSUBPS, - instrux_IBTS, - instrux_ICEBP, - instrux_IDIV, - instrux_IMUL, - instrux_IN, - instrux_INC, - instrux_INCBIN, - instrux_INSB, - instrux_INSD, - instrux_INSW, - instrux_INT, - instrux_INT01, - instrux_INT03, - instrux_INT1, - instrux_INT3, - instrux_INTO, - instrux_INVD, - instrux_INVLPG, - instrux_IRET, - instrux_IRETD, - instrux_IRETW, - instrux_JCXZ, - instrux_JECXZ, - instrux_JMP, - instrux_JMPE, - instrux_LAHF, - instrux_LAR, - instrux_LDDQU, - instrux_LDMXCSR, - instrux_LDS, - instrux_LEA, - instrux_LEAVE, - instrux_LES, - instrux_LFENCE, - instrux_LFS, - instrux_LGDT, - instrux_LGS, - instrux_LIDT, - instrux_LLDT, - instrux_LMSW, - instrux_LOADALL, - instrux_LOADALL286, - instrux_LODSB, - instrux_LODSD, - instrux_LODSW, - instrux_LOOP, - instrux_LOOPE, - instrux_LOOPNE, - instrux_LOOPNZ, - instrux_LOOPZ, - instrux_LSL, - instrux_LSS, - instrux_LTR, - instrux_MASKMOVDQU, - instrux_MASKMOVQ, - instrux_MAXPD, - instrux_MAXPS, - instrux_MAXSD, - instrux_MAXSS, - instrux_MFENCE, - instrux_MINPD, - instrux_MINPS, - instrux_MINSD, - instrux_MINSS, - instrux_MONITOR, - instrux_MOV, - instrux_MOVAPD, - instrux_MOVAPS, - instrux_MOVD, - instrux_MOVDDUP, - instrux_MOVDQ2Q, - instrux_MOVDQA, - instrux_MOVDQU, - instrux_MOVHLPS, - instrux_MOVHPD, - instrux_MOVHPS, - instrux_MOVLHPS, - instrux_MOVLPD, - instrux_MOVLPS, - instrux_MOVMSKPD, - instrux_MOVMSKPS, - instrux_MOVNTDQ, - instrux_MOVNTI, - instrux_MOVNTPD, - instrux_MOVNTPS, - instrux_MOVNTQ, - instrux_MOVQ, - instrux_MOVQ2DQ, - instrux_MOVSB, - instrux_MOVSD, - instrux_MOVSHDUP, - instrux_MOVSLDUP, - instrux_MOVSS, - instrux_MOVSW, - instrux_MOVSX, - instrux_MOVUPD, - instrux_MOVUPS, - instrux_MOVZX, - instrux_MUL, - instrux_MULPD, - instrux_MULPS, - instrux_MULSD, - instrux_MULSS, - instrux_MWAIT, - instrux_NEG, - instrux_NOP, - instrux_NOT, - instrux_OR, - instrux_ORPD, - instrux_ORPS, - instrux_OUT, - instrux_OUTSB, - instrux_OUTSD, - instrux_OUTSW, - instrux_PACKSSDW, - instrux_PACKSSWB, - instrux_PACKUSWB, - instrux_PADDB, - instrux_PADDD, - instrux_PADDQ, - instrux_PADDSB, - instrux_PADDSIW, - instrux_PADDSW, - instrux_PADDUSB, - instrux_PADDUSW, - instrux_PADDW, - instrux_PAND, - instrux_PANDN, - instrux_PAUSE, - instrux_PAVEB, - instrux_PAVGB, - instrux_PAVGUSB, - instrux_PAVGW, - instrux_PCMPEQB, - instrux_PCMPEQD, - instrux_PCMPEQW, - instrux_PCMPGTB, - instrux_PCMPGTD, - instrux_PCMPGTW, - instrux_PDISTIB, - instrux_PEXTRW, - instrux_PF2ID, - instrux_PF2IW, - instrux_PFACC, - instrux_PFADD, - instrux_PFCMPEQ, - instrux_PFCMPGE, - instrux_PFCMPGT, - instrux_PFMAX, - instrux_PFMIN, - instrux_PFMUL, - instrux_PFNACC, - instrux_PFPNACC, - instrux_PFRCP, - instrux_PFRCPIT1, - instrux_PFRCPIT2, - instrux_PFRSQIT1, - instrux_PFRSQRT, - instrux_PFSUB, - instrux_PFSUBR, - instrux_PI2FD, - instrux_PI2FW, - instrux_PINSRW, - instrux_PMACHRIW, - instrux_PMADDWD, - instrux_PMAGW, - instrux_PMAXSW, - instrux_PMAXUB, - instrux_PMINSW, - instrux_PMINUB, - instrux_PMOVMSKB, - instrux_PMULHRIW, - instrux_PMULHRWA, - instrux_PMULHRWC, - instrux_PMULHUW, - instrux_PMULHW, - instrux_PMULLW, - instrux_PMULUDQ, - instrux_PMVGEZB, - instrux_PMVLZB, - instrux_PMVNZB, - instrux_PMVZB, - instrux_POP, - instrux_POPA, - instrux_POPAD, - instrux_POPAW, - instrux_POPF, - instrux_POPFD, - instrux_POPFW, - instrux_POR, - instrux_PREFETCH, - instrux_PREFETCHNTA, - instrux_PREFETCHT0, - instrux_PREFETCHT1, - instrux_PREFETCHT2, - instrux_PREFETCHW, - instrux_PSADBW, - instrux_PSHUFD, - instrux_PSHUFHW, - instrux_PSHUFLW, - instrux_PSHUFW, - instrux_PSLLD, - instrux_PSLLDQ, - instrux_PSLLQ, - instrux_PSLLW, - instrux_PSRAD, - instrux_PSRAW, - instrux_PSRLD, - instrux_PSRLDQ, - instrux_PSRLQ, - instrux_PSRLW, - instrux_PSUBB, - instrux_PSUBD, - instrux_PSUBQ, - instrux_PSUBSB, - instrux_PSUBSIW, - instrux_PSUBSW, - instrux_PSUBUSB, - instrux_PSUBUSW, - instrux_PSUBW, - instrux_PSWAPD, - instrux_PUNPCKHBW, - instrux_PUNPCKHDQ, - instrux_PUNPCKHQDQ, - instrux_PUNPCKHWD, - instrux_PUNPCKLBW, - instrux_PUNPCKLDQ, - instrux_PUNPCKLQDQ, - instrux_PUNPCKLWD, - instrux_PUSH, - instrux_PUSHA, - instrux_PUSHAD, - instrux_PUSHAW, - instrux_PUSHF, - instrux_PUSHFD, - instrux_PUSHFW, - instrux_PXOR, - instrux_RCL, - instrux_RCPPS, - instrux_RCPSS, - instrux_RCR, - instrux_RDMSR, - instrux_RDPMC, - instrux_RDSHR, - instrux_RDTSC, - instrux_RESB, - instrux_RESD, - instrux_RESQ, - instrux_REST, - instrux_RESW, - instrux_RET, - instrux_RETF, - instrux_RETN, - instrux_ROL, - instrux_ROR, - instrux_RSDC, - instrux_RSLDT, - instrux_RSM, - instrux_RSQRTPS, - instrux_RSQRTSS, - instrux_RSTS, - instrux_SAHF, - instrux_SAL, - instrux_SALC, - instrux_SAR, - instrux_SBB, - instrux_SCASB, - instrux_SCASD, - instrux_SCASW, - instrux_SFENCE, - instrux_SGDT, - instrux_SHL, - instrux_SHLD, - instrux_SHR, - instrux_SHRD, - instrux_SHUFPD, - instrux_SHUFPS, - instrux_SIDT, - instrux_SLDT, - instrux_SMI, - instrux_SMINT, - instrux_SMINTOLD, - instrux_SMSW, - instrux_SQRTPD, - instrux_SQRTPS, - instrux_SQRTSD, - instrux_SQRTSS, - instrux_STC, - instrux_STD, - instrux_STI, - instrux_STMXCSR, - instrux_STOSB, - instrux_STOSD, - instrux_STOSW, - instrux_STR, - instrux_SUB, - instrux_SUBPD, - instrux_SUBPS, - instrux_SUBSD, - instrux_SUBSS, - instrux_SVDC, - instrux_SVLDT, - instrux_SVTS, - instrux_SYSCALL, - instrux_SYSENTER, - instrux_SYSEXIT, - instrux_SYSRET, - instrux_TEST, - instrux_UCOMISD, - instrux_UCOMISS, - instrux_UD0, - instrux_UD1, - instrux_UD2, - instrux_UMOV, - instrux_UNPCKHPD, - instrux_UNPCKHPS, - instrux_UNPCKLPD, - instrux_UNPCKLPS, - instrux_VERR, - instrux_VERW, - instrux_WAIT, - instrux_WBINVD, - instrux_WRMSR, - instrux_WRSHR, - instrux_XADD, - instrux_XBTS, - instrux_XCHG, - instrux_XLAT, - instrux_XLATB, - instrux_XOR, - instrux_XORPD, - instrux_XORPS, - instrux_XSTORE, - instrux_CMOVcc, - instrux_Jcc, - instrux_SETcc, -}; diff --git a/AltairZ80/mfdc.c b/AltairZ80/mfdc.c index e697660d..7438039c 100644 --- a/AltairZ80/mfdc.c +++ b/AltairZ80/mfdc.c @@ -417,8 +417,8 @@ static uint8 MFDC_Read(const uint32 Addr) if(mfdc_info->datacount == 0) { unsigned int i, checksum; unsigned long sec_offset; - unsigned int flags; - unsigned int readlen; + uint32 flags; + uint32 readlen; /* Clear out unused portion of sector. */ memset(&sdata.u.unused[0], 0x00, 10); @@ -516,8 +516,8 @@ static uint8 MFDC_Read(const uint32 Addr) static uint8 MFDC_Write(const uint32 Addr, uint8 cData) { unsigned int sec_offset; - unsigned int flags = 0; - unsigned int writelen; + uint32 flags = 0; + uint32 writelen; MFDC_DRIVE_INFO *pDrive; pDrive = &mfdc_info->drive[mfdc_info->sel_drive]; diff --git a/AltairZ80/s100_64fdc.c b/AltairZ80/s100_64fdc.c index 7cbc7783..03c4f395 100644 --- a/AltairZ80/s100_64fdc.c +++ b/AltairZ80/s100_64fdc.c @@ -86,7 +86,7 @@ typedef struct { uint8 ipend; /* Interrupt Pending Register */ } CROMFDC_INFO; -extern WD179X_INFO_PUB *wd179x_info; +extern WD179X_INFO_PUB *wd179x_infop; static CROMFDC_INFO cromfdc_info_data = { { 0xC000, CROMFDC_ROM_SIZE, 0x3, 2 } }; static CROMFDC_INFO *cromfdc_info = &cromfdc_info_data; @@ -1580,28 +1580,28 @@ static int32 cromfdc_control(const int32 port, const int32 io, const int32 data) if(io) { /* I/O Write */ switch(data & 0x0F) { case 0: - wd179x_info->sel_drive = 0xFF; + wd179x_infop->sel_drive = 0xFF; break; case CROMFDC_CTRL_DS1: - wd179x_info->sel_drive = 0; + wd179x_infop->sel_drive = 0; break; case CROMFDC_CTRL_DS2: - wd179x_info->sel_drive = 1; + wd179x_infop->sel_drive = 1; break; case CROMFDC_CTRL_DS3: - wd179x_info->sel_drive = 2; + wd179x_infop->sel_drive = 2; break; case CROMFDC_CTRL_DS4: - wd179x_info->sel_drive = 3; + wd179x_infop->sel_drive = 3; break; default: sim_debug(STATUS_MSG, &cromfdc_dev, "CROMFDC: " ADDRESS_FORMAT " WR CTRL = 0x%02x: Invalid drive selected.\n", PCX, data & 0xFF); break; } if(data & CROMFDC_CTRL_MAXI) { - wd179x_info->drivetype = 8; + wd179x_infop->drivetype = 8; } else { - wd179x_info->drivetype = 5; + wd179x_infop->drivetype = 5; } if(data & CROMFDC_CTRL_MTRON) { @@ -1613,10 +1613,10 @@ static int32 cromfdc_control(const int32 port, const int32 io, const int32 data) if(crofdc_type == 4) { /* 4FDC */ sim_debug(DRIVE_MSG, &cromfdc_dev, "CROMFDC: " ADDRESS_FORMAT " WR CTRL: Cannot set double density on 4FDC\n", PCX); } else { - wd179x_info->ddens = 1; + wd179x_infop->ddens = 1; } } else { - wd179x_info->ddens = 0; + wd179x_infop->ddens = 0; } if(data & CROMFDC_CTRL_AUTOWAIT) { cromfdc_info->autowait = 1; @@ -1624,11 +1624,11 @@ static int32 cromfdc_control(const int32 port, const int32 io, const int32 data) cromfdc_info->autowait = 0; } - sim_debug(DRIVE_MSG, &cromfdc_dev, "CROMFDC: " ADDRESS_FORMAT " WR CTRL: sel_drive=%d, drivetype=%d, motor=%d, dens=%d, aw=%d\n", PCX, wd179x_info->sel_drive, wd179x_info->drivetype, cromfdc_info->motor_on, wd179x_info->ddens, cromfdc_info->autowait); + sim_debug(DRIVE_MSG, &cromfdc_dev, "CROMFDC: " ADDRESS_FORMAT " WR CTRL: sel_drive=%d, drivetype=%d, motor=%d, dens=%d, aw=%d\n", PCX, wd179x_infop->sel_drive, wd179x_infop->drivetype, cromfdc_info->motor_on, wd179x_infop->ddens, cromfdc_info->autowait); } else { /* I/O Read */ result = (crofdc_boot) ? 0 : CROMFDC_FLAG_BOOT; - result |= (wd179x_info->intrq) ? CROMFDC_FLAG_EOJ : 0; - result |= (wd179x_info->drq) ? CROMFDC_FLAG_DRQ : 0; + result |= (wd179x_infop->intrq) ? CROMFDC_FLAG_EOJ : 0; + result |= (wd179x_infop->drq) ? CROMFDC_FLAG_DRQ : 0; if(crofdc_type != 50) { /* Cromemco Controller */ result |= (motor_timeout < MOTOR_TO_LIMIT) ? CROMFDC_FLAG_SEL_REQ : 0; if(crofdc_type > 4) { /* 16, 64FDC */ @@ -1639,7 +1639,7 @@ static int32 cromfdc_control(const int32 port, const int32 io, const int32 data) result |= 0x1E; /* Make unused bits '1' on 4FDC */ } } else { /* CCS 2422 Controller */ - switch(wd179x_info->sel_drive) { + switch(wd179x_infop->sel_drive) { case 1: result |= 0x02; break; @@ -1677,10 +1677,10 @@ static int32 cromfdc_ext(const int32 port, const int32 io, const int32 data) if(crofdc_type == 4) { /* 4FDC */ sim_debug(DRIVE_MSG, &cromfdc_dev, "CROMFDC: " ADDRESS_FORMAT " WR CTRL: Cannot set side 1 on 4FDC\n", PCX); } else { - wd179x_info->fdc_head = 1; + wd179x_infop->fdc_head = 1; } } else { - wd179x_info->fdc_head = 0; + wd179x_infop->fdc_head = 0; } #if 0 /* hharte - nothing implemented for these */ if((data & CROMFDC_AUX_EJECT) == 0) { @@ -1700,9 +1700,9 @@ static int32 cromfdc_ext(const int32 port, const int32 io, const int32 data) } } else { /* CCS 2422 Controller */ if((data & CCSFDC_CMD_SIDE) == 0) { - wd179x_info->fdc_head = 1; + wd179x_infop->fdc_head = 1; } else { - wd179x_info->fdc_head = 0; + wd179x_infop->fdc_head = 0; } } diff --git a/AltairZ80/s100_adcs6.c b/AltairZ80/s100_adcs6.c index 8592256a..353b92e6 100644 --- a/AltairZ80/s100_adcs6.c +++ b/AltairZ80/s100_adcs6.c @@ -88,7 +88,7 @@ typedef struct { uint8 s100_addr_u; /* A23:16 of S-100 bus */ } ADCS6_INFO; -extern WD179X_INFO_PUB *wd179x_info; +extern WD179X_INFO_PUB *wd179x_infop; static ADCS6_INFO adcs6_info_data = { { 0xF000, ADCS6_ROM_SIZE, 0x3, 2 } }; static ADCS6_INFO *adcs6_info = &adcs6_info_data; @@ -524,26 +524,26 @@ static int32 adcs6_control(const int32 port, const int32 io, const int32 data) { int32 result = 0; if(io) { /* I/O Write */ - wd179x_info->sel_drive = data & 0x03; + wd179x_infop->sel_drive = data & 0x03; if(data & ADCS6_CTRL_MINI) { - wd179x_info->drivetype = 5; + wd179x_infop->drivetype = 5; } else { - wd179x_info->drivetype = 8; + wd179x_infop->drivetype = 8; } if(data & ADCS6_CTRL_HDS) { adcs6_info->head_sel = 1; - wd179x_info->fdc_head = 1; + wd179x_infop->fdc_head = 1; } else { adcs6_info->head_sel = 0; - wd179x_info->fdc_head = 0; + wd179x_infop->fdc_head = 0; } if(data & ADCS6_CTRL_DDENS) { - wd179x_info->ddens = 1; + wd179x_infop->ddens = 1; } else { - wd179x_info->ddens = 0; + wd179x_infop->ddens = 0; } if(data & ADCS6_CTRL_AUTOWAIT) { adcs6_info->autowait = 1; @@ -553,12 +553,12 @@ static int32 adcs6_control(const int32 port, const int32 io, const int32 data) sim_debug(DRIVE_MSG, &adcs6_dev, "ADCS6: " ADDRESS_FORMAT " WR CTRL: sel_drive=%d, drivetype=%d, head_sel=%d, dens=%d, aw=%d\n", - PCX, wd179x_info->sel_drive, - wd179x_info->drivetype, adcs6_info->head_sel, - wd179x_info->ddens, adcs6_info->autowait); + PCX, wd179x_infop->sel_drive, + wd179x_infop->drivetype, adcs6_info->head_sel, + wd179x_infop->ddens, adcs6_info->autowait); } else { /* I/O Read */ - result = wd179x_info->drq ? 0xFF : 0; - if (wd179x_info->intrq) + result = wd179x_infop->drq ? 0xFF : 0; + if (wd179x_infop->intrq) result &= 0x7F; } diff --git a/AltairZ80/vfdhd.c b/AltairZ80/vfdhd.c index bc03ed44..a8879cb0 100644 --- a/AltairZ80/vfdhd.c +++ b/AltairZ80/vfdhd.c @@ -534,7 +534,7 @@ static void VFDHD_Command(void) if(vfdhd_info->read == 1) { /* Perform a Read operation */ unsigned int i, checksum; - unsigned int readlen; + uint32 readlen; sim_debug(RD_DATA_MSG, &vfdhd_dev, "VFDHD: " ADDRESS_FORMAT " RD: Drive=%d, Track=%d, Head=%d, Sector=%d\n", PCX, vfdhd_info->sel_drive, pDrive->track, vfdhd_info->head, vfdhd_info->sector); @@ -601,7 +601,7 @@ static void VFDHD_Command(void) } } else { /* Perform a Write operation */ - unsigned int writelen; + uint32 writelen; sim_debug(WR_DATA_MSG, &vfdhd_dev, "VFDHD: " ADDRESS_FORMAT " WR: Drive=%d, Track=%d, Head=%d, Sector=%d\n", PCX, vfdhd_info->sel_drive, pDrive->track, vfdhd_info->head, vfdhd_info->sector); diff --git a/AltairZ80/wd179x.c b/AltairZ80/wd179x.c index 0d3a8f21..f3992603 100644 --- a/AltairZ80/wd179x.c +++ b/AltairZ80/wd179x.c @@ -199,6 +199,7 @@ uint8 floorlog2(unsigned int n); WD179X_INFO wd179x_info_data = { { 0x0, 0, 0x30, 4 } }; WD179X_INFO *wd179x_info = &wd179x_info_data; +WD179X_INFO_PUB *wd179x_infop = (WD179X_INFO_PUB *)&wd179x_info_data; static UNIT wd179x_unit[] = { { UDATA (&wd179x_svc, UNIT_FIX + UNIT_ATTABLE + UNIT_DISABLE + UNIT_ROABLE, WD179X_CAPACITY), 58200 }, @@ -443,8 +444,8 @@ uint8 WD179X_Read(const uint32 Addr) { uint8 cData; WD179X_DRIVE_INFO *pDrive; - unsigned int flags = 0; - unsigned int readlen; + uint32 flags = 0; + uint32 readlen; int status; if(wd179x_info->sel_drive >= WD179X_MAX_DRIVES) { @@ -570,8 +571,8 @@ static uint8 Do1793Command(uint8 cCommand) { uint8 result = 0; WD179X_DRIVE_INFO *pDrive; - unsigned int flags = 0; - unsigned int readlen; + uint32 flags = 0; + uint32 readlen; int status; if(wd179x_info->sel_drive >= WD179X_MAX_DRIVES) { @@ -951,8 +952,8 @@ uint8 WD179X_Write(const uint32 Addr, uint8 cData) { WD179X_DRIVE_INFO *pDrive; /* uint8 disk_read = 0; */ - unsigned int flags = 0; - unsigned int writelen; + uint32 flags = 0; + uint32 writelen; if(wd179x_info->sel_drive >= WD179X_MAX_DRIVES) { return 0xFF; diff --git a/GRI/gri_cpu.c b/GRI/gri_cpu.c index 547b2139..3eb3fa2e 100644 --- a/GRI/gri_cpu.c +++ b/GRI/gri_cpu.c @@ -27,7 +27,7 @@ 14-Jan-08 RMS Added GRI-99 support 28-Apr-07 RMS Removed clock initialization - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 18-Jul-04 RMS Fixed missing ao_update calls in AX, AY write 17-Jul-04 RMS Revised MSR, EAO based on additional documentation 14-Mar-03 RMS Fixed bug in SC queue tracking diff --git a/GRI/gri_stddev.c b/GRI/gri_stddev.c index 412cc200..53a3b13d 100644 --- a/GRI/gri_stddev.c +++ b/GRI/gri_stddev.c @@ -29,7 +29,7 @@ hsp S42-006 high speed punch rtc real time clock - 31-May-08 RMS Fixed declarations (found by Peter Schorn) + 31-May-08 RMS Fixed declarations (Peter Schorn) 30-Sep-06 RMS Fixed handling of non-printable characters in KSR mode 22-Nov-05 RMS Revised for new terminal processing routines 29-Dec-03 RMS Added support for console backpressure diff --git a/GRI/gri_sys.c b/GRI/gri_sys.c index 5bb5c227..42e793d2 100644 --- a/GRI/gri_sys.c +++ b/GRI/gri_sys.c @@ -24,7 +24,7 @@ in this Software without prior written authorization from Robert M Supnik. 14-Jan-08 RMS Added GRI-99 support - 18-Oct-02 RMS Fixed bug in symbolic decode (found by Hans Pufal) + 18-Oct-02 RMS Fixed bug in symbolic decode (Hans Pufal) */ #include "gri_defs.h" diff --git a/H316/h316_cpu.c b/H316/h316_cpu.c index e8576105..b1ba29bb 100644 --- a/H316/h316_cpu.c +++ b/H316/h316_cpu.c @@ -25,12 +25,12 @@ cpu H316/H516 CPU - 19-Nov-11 RMS Fixed XR behavior (from Adrian Wise) - 19-Nov-11 RMS Fixed bugs in double precision, normalization, SC (from Adrian Wise) - 10-Jan-10 RMS Fixed bugs in LDX, STX introduced in 3.8-1 (from Theo Engel) + 19-Nov-11 RMS Fixed XR behavior (Adrian Wise) + 19-Nov-11 RMS Fixed bugs in double precision, normalization, SC (Adrian Wise) + 10-Jan-10 RMS Fixed bugs in LDX, STX introduced in 3.8-1 (Theo Engel) 28-Apr-07 RMS Removed clock initialization - 03-Apr-06 RMS Fixed bugs in LLL, LRL (from Theo Engel) - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 03-Apr-06 RMS Fixed bugs in LLL, LRL (Theo Engel) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 15-Feb-05 RMS Added start button interrupt 01-Dec-04 RMS Fixed bug in DIV diff --git a/H316/h316_dp.c b/H316/h316_dp.c index 0a8df9af..40468675 100644 --- a/H316/h316_dp.c +++ b/H316/h316_dp.c @@ -1,6 +1,6 @@ /* h316_dp.c: Honeywell 4623, 4651, 4720 disk simulator - Copyright (c) 2003-2008, Robert M. Supnik + Copyright (c) 2003-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,7 +27,8 @@ 4651 disk subsystem 4720 disk subsystem - 04-Sep-05 RMS Fixed missing return (found by Peter Schorn) + 19-Mar-12 RMS Fixed declaration of chan_req (Mark Pizzolato) + 04-Sep-05 RMS Fixed missing return (Peter Schorn) 15-Jul-05 RMS Fixed bug in attach routine 01-Dec-04 RMS Fixed bug in skip on !seeking @@ -215,7 +216,8 @@ static struct drvtyp dp_tab[] = { { DP_DRV (4720) } }; -extern int32 dev_int, dev_enb, chan_req; +extern int32 dev_int, dev_enb; +extern uint32 chan_req; extern int32 stop_inst; extern uint32 dma_ad[DMA_MAX]; extern int32 sim_switches; diff --git a/H316/h316_fhd.c b/H316/h316_fhd.c index df2c9aac..4f20a45a 100644 --- a/H316/h316_fhd.c +++ b/H316/h316_fhd.c @@ -1,6 +1,6 @@ /* h316_fhd.c: H316/516 fixed head simulator - Copyright (c) 2003-2008, Robert M. Supnik + Copyright (c) 2003-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,7 +25,8 @@ fhd 516-4400 fixed head disk - 15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein) + 19-Mar-12 RMS Fixed declaration of chan_req (Mark Pizzolato) + 15-May-06 RMS Fixed bug in autosize attach (David Gesswein) 04-Jan-04 RMS Changed sim_fsize calling sequence These head-per-track devices are buffered in memory, to minimize overhead. @@ -72,7 +73,8 @@ #define OTA_CW1 1 /* expecting CW1 */ #define OTA_CW2 2 /* expecting CW2 */ -extern int32 dev_int, dev_enb, chan_req; +extern int32 dev_int, dev_enb; +extern uint32 chan_req; extern int32 stop_inst; extern uint32 dma_ad[DMA_MAX]; diff --git a/H316/h316_lp.c b/H316/h316_lp.c index 809e3b3c..46151911 100644 --- a/H316/h316_lp.c +++ b/H316/h316_lp.c @@ -25,9 +25,9 @@ lpt line printer - 09-Jun-07 RMS Fixed lost last print line (from Theo Engel) + 09-Jun-07 RMS Fixed lost last print line (Theo Engel) 19-Jan-06 RMS Added UNIT_TEXT flag - 03-Apr-06 RMS Fixed bug in blanks backscanning (from Theo Engel) + 03-Apr-06 RMS Fixed bug in blanks backscanning (Theo Engel) 01-Dec-04 RMS Fixed bug in DMA/DMC support 24-Oct-03 RMS Added DMA/DMC support 25-Apr-03 RMS Revised for extended file support diff --git a/H316/h316_mt.c b/H316/h316_mt.c index 5ca516f4..125945a9 100644 --- a/H316/h316_mt.c +++ b/H316/h316_mt.c @@ -1,6 +1,6 @@ /* h316_mt.c: H316/516 magnetic tape simulator - Copyright (c) 2003-2008, Robert M. Supnik + Copyright (c) 2003-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,10 +25,11 @@ mt 516-4100 seven track magnetic tape - 09-Jun-07 RMS Fixed bug in write without stop (from Theo Engel) + 19-Mar-12 RMS Fixed declaration of chan_req (Mark Pizzolato) + 09-Jun-07 RMS Fixed bug in write without stop (Theo Engel) 16-Feb-06 RMS Added tape capacity checking 26-Aug-05 RMS Revised to use API for write lock check - 08-Feb-05 RMS Fixed error reporting from OCP (found by Philipp Hachtmann) + 08-Feb-05 RMS Fixed error reporting from OCP (Philipp Hachtmann) 01-Dec-04 RMS Fixed bug in DMA/DMC support Magnetic tapes are represented as a series of variable records @@ -82,7 +83,8 @@ #define STA_BOT 0000002 /* beg of tape */ #define STA_EOT 0000001 /* end of tape */ -extern int32 dev_int, dev_enb, chan_req; +extern int32 dev_int, dev_enb; +extern uint32 chan_req; extern int32 stop_inst; uint32 mt_buf = 0; /* data buffer */ diff --git a/H316/h316_stddev.c b/H316/h316_stddev.c index 456df262..c358841e 100644 --- a/H316/h316_stddev.c +++ b/H316/h316_stddev.c @@ -28,13 +28,13 @@ tty 316/516-33 teleprinter clk/options 316/516-12 real time clocks/internal options - 09-Jun-07 RMS Fixed bug in clock increment (found by Theo Engel) + 09-Jun-07 RMS Fixed bug in clock increment (Theo Engel) 30-Sep-06 RMS Fixed handling of non-printable characters in KSR mode - 03-Apr-06 RMS Fixed bugs in punch state handling (from Theo Engel) + 03-Apr-06 RMS Fixed bugs in punch state handling (Theo Engel) 22-Nov-05 RMS Revised for new terminal processing routines - 05-Feb-05 RMS Fixed bug in OCP '0001 (found by Philipp Hachtmann) - 31-Jan-05 RMS Fixed bug in TTY print (found by Philipp Hachtmann) - 01-Dec-04 RMS Fixed problem in SKS '104 (reported by Philipp Hachtmann) + 05-Feb-05 RMS Fixed bug in OCP '0001 (Philipp Hachtmann) + 31-Jan-05 RMS Fixed bug in TTY print (Philipp Hachtmann) + 01-Dec-04 RMS Fixed problem in SKS '104 (Philipp Hachtmann) Fixed bug in SKS '504 Added PTR detach routine, stops motion Added PTR/PTP ASCII file support diff --git a/I1401/i1401_cd.c b/I1401/i1401_cd.c index f1912cf7..0c7eaa5b 100644 --- a/I1401/i1401_cd.c +++ b/I1401/i1401_cd.c @@ -36,16 +36,16 @@ This allows cards to be created and edited as normal files. 24-Mar-09 RMS Fixed read stacker operation in column binary mode - Fixed punch stacker operation (from Van Snyder) + Fixed punch stacker operation (Van Snyder) 28-Jun-07 RMS Added support for SS overlap modifiers 19-Jan-07 RMS Added UNIT_TEXT flag 20-Sep-05 RMS Revised for new code tables, compatible colbinary treatment 30-Aug-05 RMS Fixed read, punch to ignore modifier on 1,4 char inst - (reported by Van Snyder) + (Van Snyder) 14-Nov-04 WVS Added column binary support 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b - 30-Jan-02 RMS New zero footprint card bootstrap from Van Snyder + 30-Jan-02 RMS New zero footprint card bootstrap (Van Snyder) 29-Nov-01 RMS Added read only unit support 13-Apr-01 RMS Revised for register arrays */ diff --git a/I1401/i1401_cpu.c b/I1401/i1401_cpu.c index 71d49610..6868556b 100644 --- a/I1401/i1401_cpu.c +++ b/I1401/i1401_cpu.c @@ -24,21 +24,21 @@ in this Software without prior written authorization from Robert M Supnik. 19-Mar-11 RMS Reverted multiple tape indicator implementation - 20-Jan-11 RMS Fixed branch on EOT indicator per hardware (from Van Snyder) + 20-Jan-11 RMS Fixed branch on EOT indicator per hardware (Van Snyder) 07-Nov-10 RMS Fixed divide not to clear word marks in quotient - 24-Apr-10 RMS Revised divide algorithm (from Van Snyder) - 11-Jul-08 RMS Added missing A magtape modifier (from Van Snyder) - Fixed tape indicator implementation (from Bob Abeles) - Fixed bug in ZA and ZS (from Bob Abeles) + 24-Apr-10 RMS Revised divide algorithm (Van Snyder) + 11-Jul-08 RMS Added missing A magtape modifier (Van Snyder) + Fixed tape indicator implementation (Bob Abeles) + Fixed bug in ZA and ZS (Bob Abeles) 07-Jul-07 RMS Removed restriction on load-mode binary tape 28-Jun-07 RMS Added support for SS overlap modifiers - 22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn) - 06-Mar-06 RMS Fixed bug in divide (found by Van Snyder) - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-May-06 RMS Fixed format error in CPU history (Peter Schorn) + 06-Mar-06 RMS Fixed bug in divide (Van Snyder) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 01-Sep-05 RMS Removed error stops in MCE 16-Aug-05 RMS Fixed C++ declaration and cast problems 02-Jun-05 RMS Fixed SSB-SSG clearing on RESET - (reported by Ralph Reinke) + (Ralph Reinke) 14-Nov-04 WVS Added column binary support, debug support 06-Nov-04 RMS Added instruction history 12-Jul-03 RMS Moved ASCII/BCD tables to included file diff --git a/I1401/i1401_lp.c b/I1401/i1401_lp.c index f15ab913..a7906b91 100644 --- a/I1401/i1401_lp.c +++ b/I1401/i1401_lp.c @@ -26,7 +26,7 @@ lpt 1403 line printer 19-Jan-07 RMS Added UNIT_TEXT flag - 07-Mar-05 RMS Fixed bug in write_line (reported by Van Snyder) + 07-Mar-05 RMS Fixed bug in write_line (Van Snyder) 25-Apr-03 RMS Revised for extended file support 30-May-02 RMS Widened POS to 32b 13-Apr-01 RMS Revised for register arrays diff --git a/I1401/i1401_mt.c b/I1401/i1401_mt.c index 56b3cba0..fcd2dea1 100644 --- a/I1401/i1401_mt.c +++ b/I1401/i1401_mt.c @@ -27,21 +27,21 @@ 19-Mar-11 RMS Restored lost edit to insert EOF in memory on read EOF Reverted multiple tape indicator implementation - 20-Jan-11 RMS Fixed branch on END indicator per hardware (from Van Snyder) - 26-Jun-10 RMS Fixed backspace over tapemark not to set EOR (from Van Snyder) - 11-Jul-08 RMS Added -n (no rewind) option to BOOT (from Van Snyder) - Added tape mark detect to diagnostic read (from Bob Abeles) - Added tape mark detect in multi-character records (from Bob Abeles) - Fixed memory leak in tape rewind-unload op (from Bob Abeles) - Fixed bug, BOOT ignores GM+WM in memory (from Bob Abeles) - Fixed handling of indicators (from Bob Abeles) - Fixed bug to mask input to 6b on read (from Bob Abeles) + 20-Jan-11 RMS Fixed branch on END indicator per hardware (Van Snyder) + 26-Jun-10 RMS Fixed backspace over tapemark not to set EOR (Van Snyder) + 11-Jul-08 RMS Added -n (no rewind) option to BOOT (Van Snyder) + Added tape mark detect to diagnostic read (Bob Abeles) + Added tape mark detect in multi-character records (Bob Abeles) + Fixed memory leak in tape rewind-unload op (Bob Abeles) + Fixed bug, BOOT ignores GM+WM in memory (Bob Abeles) + Fixed handling of indicators (Bob Abeles) + Fixed bug to mask input to 6b on read (Bob Abeles) 07-Jul-07 RMS Removed restriction on load-mode binary tape 28-Jun-07 RMS Revised read tape mark behavior based on real hardware - (found by Van Snyder) + (Van Snyder) 16-Feb-06 RMS Added tape capacity checking 15-Sep-05 RMS Yet another fix to load read group mark plus word mark - Added debug printouts (from Van Snyder) + Added debug printouts (Van Snyder) 26-Aug-05 RMS Revised to use API for write lock check 16-Aug-03 RMS End-of-record on load read works like move read (verified on real 1401) @@ -55,11 +55,11 @@ 30-Sep-02 RMS Revamped error handling 28-Aug-02 RMS Added end of medium support 12-Jun-02 RMS End-of-record on move read preserves old WM under GM - (found by Van Snyder) + (Van Snyder) 03-Jun-02 RMS Modified for 1311 support 30-May-02 RMS Widened POS to 32b 22-Apr-02 RMS Added protection against bad record lengths - 30-Jan-02 RMS New zero footprint tape bootstrap from Van Snyder + 30-Jan-02 RMS New zero footprint tape bootstrap (Van Snyder) 20-Jan-02 RMS Changed write enabled modifier 29-Nov-01 RMS Added read only unit support 18-Apr-01 RMS Changed to rewind tape before boot diff --git a/I1401/i1401_sys.c b/I1401/i1401_sys.c index 43387338..3b9dc881 100644 --- a/I1401/i1401_sys.c +++ b/I1401/i1401_sys.c @@ -28,10 +28,10 @@ 14-Nov-04 WVS Added data printout support 16-Mar-03 RMS Fixed mnemonic for MCS 03-Jun-02 RMS Added 1311 support - 18-May-02 RMS Added -D feature from Van Snyder - 26-Jan-02 RMS Fixed H, NOP with no trailing wm (found by Van Snyder) + 18-May-02 RMS Added -D feature (Van Snyder) + 26-Jan-02 RMS Fixed H, NOP with no trailing wm (Van Snyder) 17-Sep-01 RMS Removed multiconsole support - 13-Jul-01 RMS Fixed bug in symbolic output (found by Peter Schorn) + 13-Jul-01 RMS Fixed bug in symbolic output (Peter Schorn) 27-May-01 RMS Added multiconsole support 14-Mar-01 RMS Revised load/dump interface (again) 30-Oct-00 RMS Added support for examine to file diff --git a/I1620/i1620_cd.c b/I1620/i1620_cd.c index d7e7cb7a..ebb9ccc5 100644 --- a/I1620/i1620_cd.c +++ b/I1620/i1620_cd.c @@ -1,6 +1,6 @@ /* i1620_cd.c: IBM 1622 card reader/punch - Copyright (c) 2002-2008, Robert M. Supnik + Copyright (c) 2002-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,9 +26,10 @@ cdr 1622 card reader cdp 1622 card punch + 19-Mar-12 RMS Fixed declarations of saved_pc, io_stop (Mark Pizzolato) 19-Jan-07 RMS Set UNIT_TEXT flag - 13-Jul-06 RMS Fixed card reader fgets call (from Tom McBride) - Fixed card reader boot sequence (from Tom McBride) + 13-Jul-06 RMS Fixed card reader fgets call (Tom McBride) + Fixed card reader boot sequence (Tom McBride) 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 25-Apr-03 RMS Revised for extended file support @@ -43,7 +44,7 @@ extern uint8 M[MAXMEMSIZE]; extern uint8 ind[NUM_IND]; extern UNIT cpu_unit; -extern int32 io_stop; +extern uint32 io_stop; char cdr_buf[CD_LEN + 2]; char cdp_buf[CD_LEN + 2]; @@ -332,8 +333,8 @@ return SCPE_OK; t_stat cdr_boot (int32 unitno, DEVICE *dptr) { t_stat r; -int32 old_io_stop; -extern int32 saved_PC; +uint32 old_io_stop; +extern uint32 saved_PC; old_io_stop = io_stop; io_stop = 1; diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index bf3d761e..4bf36b49 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -26,15 +26,15 @@ This CPU module incorporates code and comments from the 1620 simulator by Geoff Kuenning, with his permission. - 28-May-06 RMS Fixed bug in cpu history (found by Peter Schorn) - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 28-May-06 RMS Fixed bug in cpu history Peter Schorn) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 07-Nov-04 RMS Added instruction history 26-Mar-04 RMS Fixed warnings with -std=c99 - 02-Nov-03 RMS Fixed bug in branch digit (found by Dave Babcock) - 21-Aug-03 RMS Fixed bug in immediate index add (found by Michael Short) + 02-Nov-03 RMS Fixed bug in branch digit (Dave Babcock) + 21-Aug-03 RMS Fixed bug in immediate index add (Michael Short) 25-Apr-03 RMS Changed t_addr to uint32 throughout - 18-Oct-02 RMS Fixed bugs in invalid result testing (found by Hans Pufal) + 18-Oct-02 RMS Fixed bugs in invalid result testing (Hans Pufal) The simulated register state for the IBM 1620 is: diff --git a/I1620/i1620_dp.c b/I1620/i1620_dp.c index 7dde5d31..1f8390cb 100644 --- a/I1620/i1620_dp.c +++ b/I1620/i1620_dp.c @@ -35,7 +35,7 @@ to mean the implied sector number that would be in place if the disk pack had been formatted with sequential sector numbers. - 18-Oct-02 RMS Fixed bug in error testing (found by Hans Pufal) + 18-Oct-02 RMS Fixed bug in error testing (Hans Pufal) */ #include "i1620_defs.h" diff --git a/I1620/i1620_fp.c b/I1620/i1620_fp.c index d9d9b510..2b82a0fc 100644 --- a/I1620/i1620_fp.c +++ b/I1620/i1620_fp.c @@ -31,7 +31,7 @@ where S represents flag bits if the mantissa or exponent are negative. - 31-May-2008 RMS Fixed add_field call (found by Peter Schorn) + 31-May-2008 RMS Fixed add_field call (Peter Schorn) */ #include "i1620_defs.h" diff --git a/I1620/i1620_pt.c b/I1620/i1620_pt.c index dff4ac06..42a1ac63 100644 --- a/I1620/i1620_pt.c +++ b/I1620/i1620_pt.c @@ -1,6 +1,6 @@ /* i1620_pt.c: IBM 1621/1624 paper tape reader/punch simulator - Copyright (c) 2002-2008, Robert M Supnik + Copyright (c) 2002-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ ptr 1621 paper tape reader ptp 1624 paper tape punch + 19-Mar-12 RMS Fixed declaration of io_stop (Mark Pizzolato) 21-Sep-05 RMS Revised translation tables for 7094/1401 compatibility 25-Apr-03 RMS Revised for extended file support */ @@ -363,7 +364,7 @@ const static uint8 boot_rom[] = { t_stat ptr_boot (int32 unitno, DEVICE *dptr) { int32 i; -extern int32 saved_PC; +extern uint32 saved_PC; for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i]; diff --git a/I1620/i1620_sys.c b/I1620/i1620_sys.c index 40ec70d3..df247342 100644 --- a/I1620/i1620_sys.c +++ b/I1620/i1620_sys.c @@ -22,6 +22,8 @@ Except as contained in this notice, the name of Robert M Supnik shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + + 19-Mar-12 RMS Fixed declaration of CCT (Mark Pizzolato) */ #include "i1620_defs.h" @@ -122,9 +124,11 @@ const char *sim_stop_messages[] = { t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) { -int32 col, rpt, ptr, mask, cctbuf[CCT_LNT]; +uint32 col, mask, cctbuf[CCT_LNT]; +int32 ptr, rpt; t_stat r; -extern int32 cct_lnt, cct_ptr, cct[CCT_LNT]; +extern int32 cct_lnt, cct_ptr; +extern uint32 cct[CCT_LNT]; char cbuf[CBUFSIZE], gbuf[CBUFSIZE]; if ((*cptr != 0) || (flag != 0)) @@ -390,7 +394,7 @@ if (opcode[i].str == NULL) if (I_GETQP (opfl) == I_M_QNP) /* Q no print? */ qmp = 0; -fprintf (of, opcode[i].str); /* print opcode */ +fprintf (of, "%s", opcode[i].str); /* print opcode */ if (I_GETPP (opfl) == I_M_PP) /* P required? */ fprint_addr (of, ' ', &val[I_P], I_M_QX); else if ((I_GETPP (opfl) == I_M_PCP) && (pmp || qmp)) /* P opt & needed? */ diff --git a/I7094/i7094_cd.c b/I7094/i7094_cd.c index 88a15ebe..cbdcf458 100644 --- a/I7094/i7094_cd.c +++ b/I7094/i7094_cd.c @@ -1,6 +1,6 @@ /* i7094_cd.c: IBM 711/721 card reader/punch - Copyright (c) 2003-2008, Robert M. Supnik + Copyright (c) 2003-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -26,6 +26,7 @@ cdr 711 card reader cdp 721 card punch + 19-Mar-12 RMS Fixed declaration of sim_switches (Mark Pizzolato) 19-Jan-07 RMS Added UNIT_TEXT 13-Jul-06 RMS Fixed problem with 80 column full cards @@ -87,7 +88,7 @@ t_stat cd_attach (UNIT *uptr, char *cptr); t_stat cd_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc); char colbin_to_bcd (uint32 cb); -extern uint32 sim_switches; +extern int32 sim_switches; extern uint32 PC; extern uint32 ind_ioc; extern char bcd_to_ascii_a[64]; diff --git a/I7094/i7094_com.c b/I7094/i7094_com.c index 2fd5cf24..b5c7b29d 100644 --- a/I7094/i7094_com.c +++ b/I7094/i7094_com.c @@ -26,8 +26,8 @@ com 7750 controller coml 7750 lines - 12-Aug-2010 RMS Major rewrite for CTSS (from Dave Pitts) - 19-Nov-2008 RMS Revised for common TMXR show routines + 12-Aug-10 RMS Major rewrite for CTSS (Dave Pitts) + 19-Nov-08 RMS Revised for common TMXR show routines This module implements an abstract simulator for the IBM 7750 communications computer as used by the CTSS system. The 7750 supports up to 112 lines; diff --git a/I7094/i7094_cpu.c b/I7094/i7094_cpu.c index 3719999b..f1d46462 100644 --- a/I7094/i7094_cpu.c +++ b/I7094/i7094_cpu.c @@ -28,7 +28,7 @@ 31-Dec-11 RMS Select traps have priority over protect traps Added SRI, SPI Fixed user mode and relocation from CTSS RPQ documentation - 16-Jul-10 RMS Fixed user mode protection (found by Dave Pitts) + 16-Jul-10 RMS Fixed user mode protection (Dave Pitts) Fixed issues in storage nullification mode 28-Apr-07 RMS Removed clock initialization 29-Oct-06 RMS Added additional expanded core instructions diff --git a/I7094/i7094_cpu1.c b/I7094/i7094_cpu1.c index 1b682eb0..1e3bd402 100644 --- a/I7094/i7094_cpu1.c +++ b/I7094/i7094_cpu1.c @@ -26,7 +26,7 @@ 31-Dec-11 RMS Refined PSE and MSE user-mode protection based on CTSS RPQ specification Select traps have priority over protection traps - 16-Jul-10 RMS Fixed PSE and MSE user-mode protection (from Dave Pitts) + 16-Jul-10 RMS Fixed PSE and MSE user-mode protection (Dave Pitts) Added SPUx, SPTx, SPRx */ diff --git a/I7094/i7094_drm.c b/I7094/i7094_drm.c index d7d91da9..50b24c35 100644 --- a/I7094/i7094_drm.c +++ b/I7094/i7094_drm.c @@ -25,6 +25,7 @@ drm 7289/7320A "fast" drum + 23-Mar-12 RMS Corrected disk addressing and logical disk crossing 25-Mar-11 RMS Updated based on RPQ This simulator implements a subset of the functionality of the 7289, as @@ -47,7 +48,7 @@ Limitations in this simulator: - Chain mode is not implemented. - - Write protect switches are not implemented. + - LPCR is not implemented. For speed, the entire drum is buffered in memory. */ @@ -55,10 +56,12 @@ #include "i7094_defs.h" #include -#define DRM_NUMDR 8 /* drums/controller */ +#define DRM_NUMDR 4 /* drums/controller */ /* Drum geometry */ +#define DRM_NUMWDG 1024 /* words/group */ +#define DRM_GPMASK (DRM_NUMWDG - 1) /* group mask */ #define DRM_NUMWDS 2048 /* words/sector */ #define DRM_SCMASK (DRM_NUMWDS - 1) /* sector mask */ #define DRM_NUMSC 16 /* sectors/log drum */ @@ -68,6 +71,7 @@ #define DRM_SIZE (DRM_NUMLD * DRM_NUMWDL) /* words/phys drum */ #define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \ ((double) DRM_NUMWDS))) +#define GET_PROT(x) ((x[drm_phy] >> (drm_log - 1)) & 1) /* Drum address from channel */ @@ -80,7 +84,7 @@ #define DRM_GETPHY(x) (((uint32) ((x) >> DRM_V_PHY)) & DRM_M_PHY) #define DRM_GETLOG(x) ((((uint32) (x)) >> DRM_V_LOG) & DRM_M_LOG) #define DRM_GETWDA(x) ((((uint32) (x)) >> DRM_V_WDA) & DRM_M_WDA) -#define DRM_GETDA(x) (((DRM_GETLOG(x) - 1) * DRM_NUMWDL) + DRM_GETWDA(x)) +#define DRM_GETDA(l,x) ((((l) - 1) * DRM_NUMWDL) + (x)) /* SCD word */ @@ -88,9 +92,7 @@ #define DRMS_V_INV 33 /* invalid command */ #define DRMS_V_PHY 31 /* physical drum */ #define DRMS_V_LOG 28 /* logical drum */ -#define DRMS_V_HWDA 24 /* high word addr */ -#define DRMS_M_HWDA 017 -#define DRMS_V_GRP 23 /* group */ +#define DRMS_V_WDA 13 /* disk address */ #define DRMS_V_WRP 22 /* write protect */ #define DRMS_V_LPCR 18 /* LPRCR */ #define DRMS_M_LPCR 017 @@ -106,10 +108,12 @@ uint32 drm_ch = CH_G; /* drum channel */ uint32 drm_da = 0; /* drum address */ uint32 drm_phy = 0; /* physical drum */ +uint32 drm_log = 0; /* logical drum */ uint32 drm_sta = 0; /* state */ uint32 drm_op = 0; /* operation */ t_uint64 drm_chob = 0; /* output buf */ uint32 drm_chob_v = 0; /* valid */ +uint32 drm_prot[DRM_NUMDR] = { 0 }; /* drum protect sw */ int32 drm_time = 10; /* inter-word time */ extern uint32 ind_ioc; @@ -138,23 +142,20 @@ UNIT drm_unit[] = { UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }, { UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }, - { UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }, - { UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }, - { UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }, - { UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, DRM_SIZE) }, }; REG drm_reg[] = { { ORDATA (STATE, drm_sta, 3) }, - { ORDATA (DA, drm_da, 18) }, + { ORDATA (UNIT,drm_phy, 2), REG_RO }, + { ORDATA (LOG, drm_log, 3), REG_RO }, + { ORDATA (DA, drm_da, 15) }, { FLDATA (OP, drm_op, 0) }, - { ORDATA (UNIT,drm_phy, 3) }, { ORDATA (CHOB, drm_chob, 36) }, { FLDATA (CHOBV, drm_chob_v, 0) }, + { ORDATA (PROT0, drm_prot[0], 6) }, + { ORDATA (PROT1, drm_prot[1], 6) }, + { ORDATA (PROT2, drm_prot[2], 6) }, + { ORDATA (PROT3, drm_prot[3], 6) }, { DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT }, { DRDATA (CHAN, drm_ch, 3), REG_HRO }, { NULL } @@ -199,24 +200,38 @@ switch (sel) { /* case on cmd */ return SCPE_OK; } +/* Channel diagnostic store routine */ + +t_uint64 drm_sdc (uint32 ch) +{ +t_uint64 val; + + +val = (((t_uint64) ind_ioc) << DRMS_V_IOC) | + (((t_uint64) drm_phy) << DRMS_V_PHY) | + (((t_uint64) drm_log) << DRMS_V_LOG) | + (((t_uint64) (drm_da & ~ DRM_GPMASK)) << DRMS_V_WDA) | + (((t_uint64) GET_PROT(drm_prot)) << DRMS_V_WRP); +return val; +} + /* Channel write routine */ t_stat drm_chwr (uint32 ch, t_uint64 val, uint32 flags) { -uint32 l; int32 cp, dp; if (drm_sta == DRM_1ST) { drm_phy = DRM_GETPHY (val); /* get unit */ - l = DRM_GETLOG (val); /* get logical address */ - if ((drm_phy >= DRM_NUMDR) || /* invalid unit? */ - (drm_unit[drm_phy].flags & UNIT_DIS) || /* disabled unit? */ - (l == 0) || (l > DRM_NUMLD)) { /* invalid log drum? */ + drm_log = DRM_GETLOG (val); /* get logical disk */ + drm_da = DRM_GETWDA (val); /* get drum word addr */ + if ((drm_unit[drm_phy].flags & UNIT_DIS) || /* disabled unit? */ + (drm_log == 0) || (drm_log > DRM_NUMLD) || /* invalid log drum? */ + ((drm_op != 0) && (GET_PROT (drm_prot) != 0))) { /* write to prot drum? */ ch6_err_disc (ch, U_DRM, CHF_TRC); /* disconnect */ drm_sta = DRM_IDLE; return SCPE_OK; } - drm_da = DRM_GETDA (val); /* get drum addr */ cp = GET_POS (drm_time); /* current pos in sec */ dp = (drm_da & DRM_SCMASK) - cp; /* delta to desired pos */ if (dp <= 0) /* if neg, add rev */ @@ -243,23 +258,19 @@ t_stat drm_svc (UNIT *uptr) { uint32 i; t_uint64 *fbuf = (t_uint64 *) uptr->filebuf; +uint32 da = DRM_GETDA (drm_log, drm_da); if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? */ ch6_err_disc (drm_ch, U_DRM, CHF_TRC); /* set TRC, disc */ drm_sta = DRM_IDLE; /* drum is idle */ return SCPE_UNATT; } -if (drm_da >= DRM_SIZE) { /* nx logical drum? */ - ch6_err_disc (drm_ch, U_DRM, CHF_EOF); /* set EOF, disc */ - drm_sta = DRM_IDLE; /* drum is idle */ - return SCPE_OK; - } switch (drm_sta) { /* case on state */ - case DRM_FILL: /* write, clr sector */ - for (i = drm_da & ~DRM_SCMASK; i <= (drm_da | DRM_SCMASK); i++) - fbuf[i] = 0; /* clear sector */ + case DRM_FILL: /* write, clr group */ + for (i = da & ~DRM_GPMASK; i <= (da | DRM_GPMASK); i++) + fbuf[i] = 0; /* clear group */ if (i >= uptr-> hwmark) uptr->hwmark = i + 1; drm_sta = DRM_DATA; /* now data */ @@ -270,14 +281,14 @@ switch (drm_sta) { /* case on state */ drm_chob_v = 0; else if (ch6_qconn (drm_ch, U_DRM)) /* no, chan conn? */ ind_ioc = 1; /* io check */ - fbuf[drm_da] = drm_chob; /* get data */ - if (drm_da >= uptr->hwmark) - uptr->hwmark = drm_da + 1; - if (!drm_da_incr ()) + fbuf[da] = drm_chob; /* get data */ + if (da >= uptr->hwmark) + uptr->hwmark = da + 1; + if (!drm_da_incr ()) /* room for more? */ ch6_req_wr (drm_ch, U_DRM); } else{ /* read */ - ch6_req_rd (drm_ch, U_DRM, fbuf[drm_da], 0); /* send word to channel */ + ch6_req_rd (drm_ch, U_DRM, fbuf[da], 0); /* send word to channel */ drm_da_incr (); } sim_activate (uptr, drm_time); /* next word */ @@ -293,12 +304,12 @@ switch (drm_sta) { /* case on state */ return SCPE_OK; } -/* Increment drum address - return true, set new state if end of sector */ +/* Increment drum address - return true, set new state if end of logical disk */ t_bool drm_da_incr (void) { -drm_da = (drm_da & ~DRM_LDMASK) | ((drm_da + 1) & DRM_LDMASK); -if ((drm_da & DRM_LDMASK) != 0) +drm_da = (drm_da + 1) & DRM_LDMASK; +if (drm_da != 0) return FALSE; drm_sta = DRM_EOD; return TRUE; @@ -311,6 +322,7 @@ t_stat drm_reset (DEVICE *dptr) uint32 i; drm_phy = 0; +drm_log = 0; drm_da = 0; drm_op = 0; drm_sta = DRM_IDLE; diff --git a/I7094/i7094_dsk.c b/I7094/i7094_dsk.c index 710725f1..4c605c81 100644 --- a/I7094/i7094_dsk.c +++ b/I7094/i7094_dsk.c @@ -1151,9 +1151,9 @@ if (uptr == NULL) if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; dptr = find_dev_from_unit (uptr); -u = uptr - dptr->units; if (dptr == NULL) return SCPE_IERR; +u = uptr - dptr->units; dtyp = GET_DTYPE (uptr->flags); if ((dtyp == TYPE_7320) || (dtyp == TYPE_1301)) diff --git a/I7094/i7094_io.c b/I7094/i7094_io.c index 655e7b7f..e4e81d13 100644 --- a/I7094/i7094_io.c +++ b/I7094/i7094_io.c @@ -1,6 +1,6 @@ /* i7094_io.c: IBM 7094 I/O subsystem (channels) - Copyright (c) 2003-2006, Robert M. Supnik + Copyright (c) 2003-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ chana..chanh I/O channels + 19-Mar-12 RMS Fixed declaration of breakpoint variables (Mark Pizzolato) + Notes on channels and CTSS. - CTSS B-core is supported by the addition of a 16th bit to the current @@ -86,7 +88,7 @@ extern DEVICE mt_dev[NUM_CHAN]; extern DEVICE drm_dev; extern DEVICE dsk_dev; extern DEVICE com_dev; -extern int32 sim_brk_summ; +extern uint32 sim_brk_summ; t_stat ch_reset (DEVICE *dptr); t_stat ch6_svc (UNIT *uptr); @@ -834,10 +836,12 @@ return SCPE_OK; t_stat ch_op_store_diag (uint32 ch, t_uint64 *dat) { +extern t_uint64 drm_sdc (uint32 ch); + if ((ch >= NUM_CHAN) || (ch_dev[ch].flags & DEV_DIS)) return STOP_NXCHN; if (ch_flags[ch] & DEV_7289) - *dat = ind_ioc? SIGN: 0; + *dat = drm_sdc (ch); else if (ch_flags[ch] & DEV_7909) *dat = (((t_uint64) (ch_lcc[ch] & CHF_M_LCC)) << CHF_V_LCC) | (ch_flags[ch] & CHF_SDC_7909); diff --git a/I7094/i7094_lp.c b/I7094/i7094_lp.c index 9f7f8ef2..f6aca08c 100644 --- a/I7094/i7094_lp.c +++ b/I7094/i7094_lp.c @@ -1,6 +1,6 @@ /* i7094_lp.c: IBM 716 line printer simulator - Copyright (c) 2003-2008, Robert M. Supnik + Copyright (c) 2003-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), diff --git a/I7094/i7094_mt.c b/I7094/i7094_mt.c index 18c34942..edf1d06b 100644 --- a/I7094/i7094_mt.c +++ b/I7094/i7094_mt.c @@ -1,6 +1,6 @@ /* i7094_mt.c: IBM 7094 magnetic tape simulator - Copyright (c) 2003-2008, Robert M Supnik + Copyright (c) 2003-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,7 +25,8 @@ mt magtape simulator - 16-Jul-10 RMS Fixed handling of BSR, BSF (from Dave Pitts) + 19-Mar-12 RMS Fixed declaration of sel_name (Mark Pizzolato) + 16-Jul-10 RMS Fixed handling of BSR, BSF (Dave Pitts) */ #include "i7094_defs.h" @@ -72,7 +73,7 @@ extern uint32 PC; extern uint32 cpu_model; extern uint32 ind_ioc; extern FILE *sim_deb; -extern char *sel_name[]; +extern const char *sel_name[]; t_stat mt_chsel (uint32 ch, uint32 sel, uint32 unit); t_stat mt_chwr (uint32 ch, t_uint64 val, uint32 flags); diff --git a/Ibm1130/ibm1130_cr.c b/Ibm1130/ibm1130_cr.c index 61014b71..e5efa22a 100644 --- a/Ibm1130/ibm1130_cr.c +++ b/Ibm1130/ibm1130_cr.c @@ -944,7 +944,7 @@ t_stat load_cr_boot (int drvno, int switches) #ifdef GUI_SUPPORT remark_cmd(msg); #else - printf(msg); + printf("%s", msg); #endif } diff --git a/Ibm1130/ibm1130_sys.c b/Ibm1130/ibm1130_sys.c index 22cce803..2fefc52c 100644 --- a/Ibm1130/ibm1130_sys.c +++ b/Ibm1130/ibm1130_sys.c @@ -455,14 +455,13 @@ t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) #ifndef _WIN32 -int strnicmp (const char *a, const char *b, int n) +int strnicmp (const char *a, const char *b, size_t n) { int ca, cb; - for (;;) { - if (--n < 0) /* still equal after n characters? quit now */ - return 0; + if (n == 0) return 0; /* zero length compare is equal */ + for (;;) { if ((ca = *a) == 0) /* get character, stop on null terminator */ return *b ? -1 : 0; @@ -477,6 +476,9 @@ int strnicmp (const char *a, const char *b, int n) return ca; a++, b++; + + if (--n == 0) /* still equal after n characters? quit now */ + return 0; } } diff --git a/Interdata/id16_cpu.c b/Interdata/id16_cpu.c index fdf38ae5..f3ec00ad 100644 --- a/Interdata/id16_cpu.c +++ b/Interdata/id16_cpu.c @@ -28,15 +28,15 @@ 28-Apr-07 RMS Removed clock initialization 27-Oct-06 RMS Added idle support Removed separate PASLA clock - 06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger) - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 06-Feb-06 RMS Fixed bug in DH (Mark Hittinger) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 25-Aug-05 RMS Fixed DH integer overflow cases 16-Aug-05 RMS Fixed C++ declaration and cast problems - 10-Mar-05 RMS Fixed bug in show history routine (from Mark Hittinger) + 10-Mar-05 RMS Fixed bug in show history routine (Mark Hittinger) Revised examine/deposit to do words rather than bytes 07-Nov-04 RMS Added instruction history 22-Sep-03 RMS Added additional instruction decode types - 07-Feb-03 RMS Fixed bug in SETM, SETMR (found by Mark Pizzolato) + 07-Feb-03 RMS Fixed bug in SETM, SETMR (Mark Pizzolato) The register state for the Interdata 16b CPU is: diff --git a/Interdata/id32_cpu.c b/Interdata/id32_cpu.c index 969b954b..7af43c61 100644 --- a/Interdata/id32_cpu.c +++ b/Interdata/id32_cpu.c @@ -29,13 +29,13 @@ 27-Oct-06 RMS Added idle support Removed separate PASLA clock 09-Mar-06 RMS Added 8 register bank support for 8/32 - 06-Feb-06 RMS Fixed bug in DH (found by Mark Hittinger) - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 06-Feb-06 RMS Fixed bug in DH (Mark Hittinger) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 10-Mar-05 RMS Fixed bug in initial memory allocation - RMS Fixed bug in show history routine (from Mark Hittinger) + RMS Fixed bug in show history routine (Mark Hittinger) RMS Revised examine/deposit to do words rather than bytes - 18-Feb-05 RMS Fixed branches to mask new PC (from Greg Johnson) + 18-Feb-05 RMS Fixed branches to mask new PC (Greg Johnson) 06-Nov-04 RMS Added =n to SHOW HISTORY 25-Jan-04 RMS Revised for device debug support 31-Dec-03 RMS Fixed bug in cpu_set_hist diff --git a/Interdata/id32_dboot.c b/Interdata/id32_dboot.c index 081a3c4b..40ee4167 100644 --- a/Interdata/id32_dboot.c +++ b/Interdata/id32_dboot.c @@ -23,7 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 17-Jul-06 RMS Fixed transcription errors (found by Davis Johnson) + 17-Jul-06 RMS Fixed transcription errors (Davis Johnson) 17-Feb-03 RMS Fixed for UNIX bootstrap, upper platter bootstrap */ diff --git a/Interdata/id_fd.c b/Interdata/id_fd.c index 12654c9c..a016436c 100644 --- a/Interdata/id_fd.c +++ b/Interdata/id_fd.c @@ -1,6 +1,6 @@ /* id_fd.c: Interdata floppy disk simulator - Copyright (c) 2001-2008, Robert M Supnik + Copyright (c) 2001-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,8 @@ fd M46-630 floppy disk + 19-Mar-12 RMS Fixed macro naming conflict (Mark Pizzolato) + A diskette consists of 77 tracks, each with 26 sectors of 128B. The Interdata floppy uses a logical record numbering scheme from 1 to 2002. Physical tracks are numbered 0-76, physical sectors 1-26. @@ -75,11 +77,11 @@ #define STA_WRP 0x80 /* *write prot */ #define STA_DEF 0x40 /* def track NI */ -#define STA_DEL 0x20 /* del record */ +#define STA_DLR 0x20 /* del record */ #define STA_ERR 0x10 /* error */ #define STA_IDL 0x02 /* idle */ #define STA_OFL 0x01 /* fault */ -#define STA_MASK (STA_DEF|STA_DEL|STA_ERR|STA_BSY|STA_IDL) +#define STA_MASK (STA_DEF|STA_DLR|STA_ERR|STA_BSY|STA_IDL) #define SET_EX (STA_ERR) /* set EX */ /* Extended status, 6 bytes, * = dynamic */ @@ -329,7 +331,7 @@ switch (fnc) { /* case on function */ for (i = 0; i < FD_NUMBY; i++) /* read sector */ fdxb[i] = fbuf[da + i]; if (fbuf[FD_SIZE + uptr->LRN - 1]) { /* deleted? set err */ - fd_sta = fd_sta | STA_DEL; + fd_sta = fd_sta | STA_DLR; fd_es[u][0] = fd_es[u][0] | ES0_DEL; } fd_es[u][2] = GET_SEC (uptr->LRN); /* set ext sec/trk */ diff --git a/Interdata/id_idc.c b/Interdata/id_idc.c index e2ac7003..38854d1c 100644 --- a/Interdata/id_idc.c +++ b/Interdata/id_idc.c @@ -25,8 +25,8 @@ idc MSM/IDC disk controller - 03-Apr-06 RMS Fixed WD/WH handling (found by Davis Johnson) - 30-Mar-06 RMS Fixed bug, nop command should be ignored (found by Davis Johnson) + 03-Apr-06 RMS Fixed WD/WH handling (Davis Johnson) + 30-Mar-06 RMS Fixed bug, nop command should be ignored (Davis Johnson) 25-Apr-03 RMS Revised for extended file support 16-Feb-03 RMS Fixed read to test transfer ok before selch operation diff --git a/Interdata/id_io.c b/Interdata/id_io.c index 98ce4a1d..86228eda 100644 --- a/Interdata/id_io.c +++ b/Interdata/id_io.c @@ -23,7 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 30-Mar-06 RMS Fixed bug, GO preserves EXA and SSTA (found by Davis Johnson) + 30-Mar-06 RMS Fixed bug, GO preserves EXA and SSTA (Davis Johnson) 21-Jun-03 RMS Changed subroutine argument for ARM compiler conflict Interdata I/O devices are defined by a device information block: diff --git a/Interdata/id_lp.c b/Interdata/id_lp.c index e1136a42..fcb1c09b 100644 --- a/Interdata/id_lp.c +++ b/Interdata/id_lp.c @@ -25,7 +25,7 @@ lpt M46-206 line printer - 27-May-08 RMS Fixed bug in printing test (from Davis Johnson) + 27-May-08 RMS Fixed bug in printing test (Davis Johnson) 19-Jan-07 RMS Added UNIT_TEXT flag 25-Apr-03 RMS Revised for extended file support */ diff --git a/Interdata/id_pas.c b/Interdata/id_pas.c index 15ccf7e3..7ce00973 100644 --- a/Interdata/id_pas.c +++ b/Interdata/id_pas.c @@ -1,6 +1,6 @@ /* id_pas.c: Interdata programmable async line adapter simulator - Copyright (c) 2001-2008, Robert M Supnik + Copyright (c) 2001-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ pas Programmable asynchronous line adapter(s) + 21-Mar-12 RMS Fixed TT_GET_MODE test to use TTUF_MODE_x (Michael Bloom) 19-Nov-08 RMS Revised for common TMXR show routines 18-Jun-07 RMS Added UNIT_IDLE flag 18-Oct-06 RMS Synced PASLA to clock @@ -345,7 +346,7 @@ for (ln = 0; ln < PAS_ENAB; ln++) { /* loop thru lines */ else { /* normal */ out = c & 0x7F; /* echo is 7b */ c = sim_tt_inpcvt (c, TT_GET_MODE (pasl_unit[ln].flags)); - if (TT_GET_MODE (pasl_unit[ln].flags) != TT_MODE_8B) + if (TT_GET_MODE (pasl_unit[ln].flags) != TTUF_MODE_8B) c = pas_par (pas_cmd[ln], c); /* apply parity */ pas_rbuf[ln] = c; /* save char */ pas_rchp[ln] = 1; /* char pending */ @@ -378,7 +379,7 @@ uint32 ln = uptr - pasl_unit; /* line # */ if (pas_ldsc[ln].conn) { /* connected? */ if (pas_ldsc[ln].xmte) { /* xmt enabled? */ TMLN *lp = &pas_ldsc[ln]; /* get line */ - if (TT_GET_MODE (pasl_unit[ln].flags) == TT_MODE_8B) + if (TT_GET_MODE (pasl_unit[ln].flags) == TTUF_MODE_8B) c = pas_par (pas_cmd[ln], pas_xbuf[ln]); /* apply parity */ else c = sim_tt_outcvt (pas_xbuf[ln], TT_GET_MODE (pasl_unit[ln].flags)); if (c >= 0) { diff --git a/Interdata/id_pt.c b/Interdata/id_pt.c index 27cc0c85..0dc89bfd 100644 --- a/Interdata/id_pt.c +++ b/Interdata/id_pt.c @@ -26,7 +26,7 @@ pt paper tape reader and punch 25-Apr-03 RMS Revised for extended file support - 10-Apr-03 RMS Fixed type problem in ptr service (from Mark Pizzolato) + 10-Apr-03 RMS Fixed type problem in ptr service (Mark Pizzolato) */ #include "id_defs.h" diff --git a/LGP/lgp_cpu.c b/LGP/lgp_cpu.c index 87e040e8..6b969306 100644 --- a/LGP/lgp_cpu.c +++ b/LGP/lgp_cpu.c @@ -25,8 +25,8 @@ cpu LGP-30 [LGP-21] CPU - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) - 04-Sep-05 RMS Fixed missing returns (found by Peter Schorn) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) + 04-Sep-05 RMS Fixed missing returns (Peter Schorn) 04-Jan-05 RMS Modified VM pointer setup The system state for the LGP-30 [LGP-21] is: diff --git a/NOVA/nova_clk.c b/NOVA/nova_clk.c index d0c888cd..0f9bbdb3 100644 --- a/NOVA/nova_clk.c +++ b/NOVA/nova_clk.c @@ -33,7 +33,7 @@ 17-Sep-01 RMS Added terminal multiplexor support 17-Mar-01 RMS Moved function prototype 05-Mar-01 RMS Added clock calibration - 24-Sep-97 RMS Fixed bug in unit service (found by Charles Owen) + 24-Sep-97 RMS Fixed bug in unit service (Charles Owen) */ #include "nova_defs.h" diff --git a/NOVA/nova_cpu.c b/NOVA/nova_cpu.c index 136163aa..a1caf573 100644 --- a/NOVA/nova_cpu.c +++ b/NOVA/nova_cpu.c @@ -34,10 +34,10 @@ 'ind_max' changed from 16 to 65536 for better unmapped system compatibility, INT_TRAP added for Nova 3, 4 trap instruction handling, 28-Apr-07 RMS Removed clock initialization - 06-Feb-06 RMS Fixed bug in DIVS (found by Mark Hittinger) - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 06-Feb-06 RMS Fixed bug in DIVS (Mark Hittinger) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 25-Aug-05 RMS Fixed DIVS case 2^31 / - 1 - 14-Jan-04 RMS Fixed device enable/disable support (found by Bruce Ray) + 14-Jan-04 RMS Fixed device enable/disable support (Bruce Ray) 19-Jan-03 RMS Changed CMASK to CDMASK for Apple Dev Kit conflict 03-Oct-02 RMS Added DIB infrastructure 30-Dec-01 RMS Added old PC queue diff --git a/NOVA/nova_dsk.c b/NOVA/nova_dsk.c index f01063fc..b1cfff3e 100644 --- a/NOVA/nova_dsk.c +++ b/NOVA/nova_dsk.c @@ -29,7 +29,7 @@ DEV_xxx macros now used for consistency, added secret DG DIC function, fixed boot info table size calculation - 15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein) + 15-May-06 RMS Fixed bug in autosize attach (David Gesswein) 04-Jan-04 RMS Changed sim_fsize calling sequence 26-Jul-03 RMS Fixed bug in set size routine 14-Mar-03 RMS Fixed variable capacity interaction with save/restore diff --git a/NOVA/nova_mta.c b/NOVA/nova_mta.c index 2cd7fe49..787c37ab 100644 --- a/NOVA/nova_mta.c +++ b/NOVA/nova_mta.c @@ -46,7 +46,7 @@ 24-Nov-01 RMS Changed POS, USTAT, FLG to an array 26-Apr-01 RMS Added device enable/disable support 18-Apr-01 RMS Changed to rewind tape before boot - 10-Dec-00 RMS Added Eclipse support from Charles Owen + 10-Dec-00 RMS Added Eclipse support (Charles Owen) 15-Oct-00 RMS Editorial changes 11-Nov-98 CEO Removed clear of mta_ma on iopC 04-Oct-98 RMS V2.4 magtape format diff --git a/NOVA/nova_sys.c b/NOVA/nova_sys.c index 0dab680b..ce4036b1 100644 --- a/NOVA/nova_sys.c +++ b/NOVA/nova_sys.c @@ -41,7 +41,7 @@ 15-Oct-00 RMS Added stack, byte, trap instructions 14-Apr-99 RMS Changed t_addr to unsigned 27-Oct-98 RMS V2.4 load interface - 24-Sep-97 RMS Fixed bug in device name table (found by Charles Owen) + 24-Sep-97 RMS Fixed bug in device name table (Charles Owen) */ #include "nova_defs.h" diff --git a/PDP1/pdp1_cpu.c b/PDP1/pdp1_cpu.c index 40e2a910..7be63f73 100644 --- a/PDP1/pdp1_cpu.c +++ b/PDP1/pdp1_cpu.c @@ -1,6 +1,6 @@ /* pdp1_cpu.c: PDP-1 CPU simulator - Copyright (c) 1993-2008, Robert M. Supnik + Copyright (c) 1993-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,10 +25,11 @@ cpu PDP-1 central processor - 30-May-07 RMS Fixed typo in SBS clear (from Norm Lastovica) + 210Mar-12 RMS Fixed & vs && in Ea_ch (Michael Bloom) + 30-May-07 RMS Fixed typo in SBS clear (Norm Lastovica) 28-Dec-06 RMS Added 16-channel SBS support, PDP-1D support 28-Jun-06 RMS Fixed bugs in MUS and DIV - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 09-Nov-04 RMS Added instruction history 07-Sep-03 RMS Added additional explanation on I/O simulation @@ -1406,7 +1407,7 @@ else { /* multi-level */ return STOP_IND; } /* end else !extm */ if (IR & IA) { /* automatic mode? */ - if (rm & !sbs_act & ((MB & 0607777) == 0607777)) /* page cross? */ + if (rm && !sbs_act && ((MB & 0607777) == 0607777)) /* page cross? */ return set_rmv (RTB_CHR); MB = inc_bp (MB); /* incr byte ptr */ Write (); /* rewrite */ diff --git a/PDP1/pdp1_stddev.c b/PDP1/pdp1_stddev.c index c5c9f6bc..1d1586dc 100644 --- a/PDP1/pdp1_stddev.c +++ b/PDP1/pdp1_stddev.c @@ -1,6 +1,6 @@ /* pdp1_stddev.c: PDP-1 standard devices - Copyright (c) 1993-2008, Robert M. Supnik + Copyright (c) 1993-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -28,16 +28,17 @@ tti keyboard tto teleprinter + 21-Mar-12 RMS Fixed unitialized variable in tto_svc (Michael Bloom) 21-Dec-06 RMS Added 16-channel sequence break support - 29-Oct-03 RMS Added PTR FIODEC-to-ASCII translation (from Phil Budne) + 29-Oct-03 RMS Added PTR FIODEC-to-ASCII translation (Phil Budne) 07-Sep-03 RMS Changed ioc to ios 30-Aug-03 RMS Revised PTR to conform to Maintenance Manual; added deadlock prevention on errors 23-Jul-03 RMS Revised to detect I/O wait hang 25-Apr-03 RMS Revised for extended file support 22-Dec-02 RMS Added break support - 29-Nov-02 RMS Fixed output flag initialization (found by Derek Peschel) - 21-Nov-02 RMS Changed typewriter to half duplex (found by Derek Peschel) + 29-Nov-02 RMS Fixed output flag initialization (Derek Peschel) + 21-Nov-02 RMS Changed typewriter to half duplex (Derek Peschel) 06-Oct-02 RMS Revised for V2.10 30-May-02 RMS Widened POS to 32b 29-Nov-01 RMS Added read only unit support @@ -591,7 +592,6 @@ return SCPE_OK; t_stat tto_svc (UNIT *uptr) { -int32 c; t_stat r; if (tty_buf == FIODEC_UC) /* upper case? */ @@ -599,11 +599,16 @@ if (tty_buf == FIODEC_UC) /* upper case? */ else if (tty_buf == FIODEC_LC) /* lower case? */ tty_uc = 0; else { + int32 c; c = fiodec_to_ascii[tty_buf | tty_uc]; /* translate */ if (c && ((r = sim_putchar_s (c)) != SCPE_OK)) { /* output; error? */ sim_activate (uptr, uptr->wait); /* retry */ return ((r == SCPE_STALL)? SCPE_OK: r); } + if (c == '\r') { /* cr? add lf */ + sim_putchar ('\n'); + uptr->pos = uptr->pos + 1; + } } if (cpls & CPLS_TTO) { /* completion pulse? */ ios = 1; /* restart */ @@ -612,10 +617,6 @@ if (cpls & CPLS_TTO) { /* completion pulse? */ iosta = iosta | IOS_TTO; /* set flag */ dev_req_int (tto_sbs); /* req interrupt */ uptr->pos = uptr->pos + 1; -if (c == '\r') { /* cr? add lf */ - sim_putchar ('\n'); - uptr->pos = uptr->pos + 1; - } return SCPE_OK; } diff --git a/PDP11/pdp11_cis.c b/PDP11/pdp11_cis.c index 9c7fe51b..24dd0168 100644 --- a/PDP11/pdp11_cis.c +++ b/PDP11/pdp11_cis.c @@ -29,12 +29,12 @@ Fixed bug in DIVx (LntDstr calculation) 30-May-06 RMS Added interrupt tests to character instructions Added 11/44 stack probe test to MOVCx (only) - 22-May-06 RMS Fixed bug in decode table (found by John Dundas) - Fixed bug in ASHP (reported by John Dundas) + 22-May-06 RMS Fixed bug in decode table (John Dundas) + Fixed bug in ASHP (John Dundas) Fixed bug in write decimal string with mmgt enabled Fixed bug in 0-length strings in multiply/divide 16-Sep-04 RMS Fixed bug in CMPP/N of negative strings - 17-Oct-02 RMS Fixed compiler warning (found by Hans Pufal) + 17-Oct-02 RMS Fixed compiler warning (Hans Pufal) 08-Oct-02 RMS Fixed macro definitions The commercial instruction set consists of three instruction formats: diff --git a/PDP11/pdp11_cpu.c b/PDP11/pdp11_cpu.c index 670a37ca..0ee91143 100644 --- a/PDP11/pdp11_cpu.c +++ b/PDP11/pdp11_cpu.c @@ -1,6 +1,6 @@ /* pdp11_cpu.c: PDP-11 CPU simulator - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,19 +25,20 @@ cpu PDP-11 CPU - 29-Dec-08 RMS Fixed failure to clear cpu_bme on RESET (found by Walter Mueller) - 22-Apr-08 RMS Fixed MMR0 treatment in RESET (found by Walter Mueller) - 02-Feb-08 RMS Fixed DMA memory address limit test (found by John Dundas) + 19-Mar-12 RMS Fixed declaration of sim_switches (Mark Pizzolato) + 29-Dec-08 RMS Fixed failure to clear cpu_bme on RESET (Walter Mueller) + 22-Apr-08 RMS Fixed MMR0 treatment in RESET (Walter Mueller) + 02-Feb-08 RMS Fixed DMA memory address limit test (John Dundas) 28-Apr-07 RMS Removed clock initialization 27-Oct-06 RMS Added idle support 18-Oct-06 RMS Fixed bug in ASH -32 C value 24-May-06 RMS Added instruction history 03-May-06 RMS Fixed XOR operand fetch order for 11/70-style systems - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 19-May-05 RMS Replaced WAIT clock queue check with API call - 19-Jan-05 RMS Fixed bug(s) in RESET for 11/70 (reported by Tim Chapman) - 22-Dec-04 RMS Fixed WAIT to work in all modes (from John Dundas) + 19-Jan-05 RMS Fixed bug(s) in RESET for 11/70 (Tim Chapman) + 22-Dec-04 RMS Fixed WAIT to work in all modes (John Dundas) 02-Oct-04 RMS Added model emulation 25-Jan-04 RMS Removed local debug logging support 29-Dec-03 RMS Formalized 18b Qbus support @@ -47,19 +48,19 @@ 01-Feb-03 RMS Changed R display to follow PSW, added SP display 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 05-Jan-03 RMS Added memory size restore support - 17-Oct-02 RMS Fixed bug in examine/deposit (found by Hans Pufal) + 17-Oct-02 RMS Fixed bug in examine/deposit (Hans Pufal) 08-Oct-02 RMS Revised to build dib_tab dynamically Added SHOW IOSPACE 09-Sep-02 RMS Added KW11P support 14-Jul-02 RMS Fixed bug in MMR0 error status load 03-Jun-02 RMS Fixed relocation add overflow, added PS<15:12> = 1111 special case logic to MFPI and removed it from MTPI - (found by John Dundas) - 29-Apr-02 RMS More fixes to DIV and ASH/ASHC (found by John Dundas) + (John Dundas) + 29-Apr-02 RMS More fixes to DIV and ASH/ASHC (John Dundas) 28-Apr-02 RMS Fixed bugs in illegal instruction 000010 and in - write-only memory pages (found by Wolfgang Helbig) + write-only memory pages (Wolfgang Helbig) 21-Apr-02 RMS Fixed bugs in DIV by zero, DIV overflow, TSTSET, RTS, - ASHC -32, and red zone trap (found by John Dundas) + ASHC -32, and red zone trap (John Dundas) 04-Mar-02 RMS Changed double operand evaluation order for M+ 23-Feb-02 RMS Fixed bug in MAINT, CPUERR, MEMERR read 28-Jan-02 RMS Revised for multiple timers; fixed calc_MMR1 macros @@ -81,7 +82,7 @@ 05-Apr-01 RMS Added TS11/TSV05 support 05-Mar-01 RMS Added clock calibration support 11-Feb-01 RMS Added DECtape support - 25-Jan-01 RMS Fixed 4M memory definition (found by Eric Smith) + 25-Jan-01 RMS Fixed 4M memory definition (Eric Smith) 14-Apr-99 RMS Changed t_addr to unsigned 18-Aug-98 RMS Added CIS support 09-May-98 RMS Fixed bug in DIV overflow test @@ -304,7 +305,7 @@ t_addr cpu_memsize = INIMEMSIZE; /* last mem addr */ extern int32 CPUERR, MAINT; extern int32 sim_interval; extern int32 sim_int_char; -extern uint32 sim_switches; +extern int32 sim_switches; extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ extern t_bool sim_idle_enab; extern DEVICE *sim_devices[]; diff --git a/PDP11/pdp11_cpumod.c b/PDP11/pdp11_cpumod.c index c30d5a88..80a52dc4 100644 --- a/PDP11/pdp11_cpumod.c +++ b/PDP11/pdp11_cpumod.c @@ -27,12 +27,12 @@ 20-May-08 RMS Added JCSR default for KDJ11B, KDJ11E 22-Apr-08 RMS Fixed write behavior of 11/70 MBRK, LOSIZE, HISIZE - (found by Walter Mueller) + (Walter Mueller) 29-Apr-07 RMS Don't run bus setup routine during RESTORE 30-Aug-05 RMS Added additional 11/60 registers 16-Aug-05 RMS Fixed C++ declaration and cast problems - 15-Feb-05 RMS Fixed bug in SHOW MODEL (from Sergey Okhapkin) - 19-Jan-05 RMS Added variable SYSID, MBRK write (from Tim Chapman) + 15-Feb-05 RMS Fixed bug in SHOW MODEL (Sergey Okhapkin) + 19-Jan-05 RMS Added variable SYSID, MBRK write (Tim Chapman) This module includes CPU- and system-specific registers, such as the Unibus map and control registers on 22b Unibus systems, the board registers for the diff --git a/PDP11/pdp11_dz.c b/PDP11/pdp11_dz.c index a8a20535..b001c37c 100644 --- a/PDP11/pdp11_dz.c +++ b/PDP11/pdp11_dz.c @@ -25,7 +25,7 @@ dz DZ11 terminal multiplexor - 29-Dec-08 RMS Added MTAB_NC to SET LOG command (found by Walter Mueller) + 29-Dec-08 RMS Added MTAB_NC to SET LOG command (Walter Mueller) 19-Nov-08 RMS Revised for common TMXR show routines 18-Jun-07 RMS Added UNIT_IDLE flag 29-Oct-06 RMS Synced poll and clock diff --git a/PDP11/pdp11_fp.c b/PDP11/pdp11_fp.c index 1f18ac9a..2d1db393 100644 --- a/PDP11/pdp11_fp.c +++ b/PDP11/pdp11_fp.c @@ -23,7 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 04-Oct-04 RMS Added FIS instructions 19-Jan-03 RMS Changed mode definitions for Apple Dev Kit conflict 08-Oct-02 RMS Fixed macro definitions diff --git a/PDP11/pdp11_hk.c b/PDP11/pdp11_hk.c index 0e25886a..72aa9cfd 100644 --- a/PDP11/pdp11_hk.c +++ b/PDP11/pdp11_hk.c @@ -1,6 +1,6 @@ /* pdp11_hk.c - RK611/RK06/RK07 disk controller - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ hk RK611/RK06/RK07 disk + 19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato) 29-Apr-07 RMS NOP and DCLR (at least) do not check drive type MR2 and MR3 only updated on NOP 17-Nov-05 RMS Removed unused variable @@ -60,7 +61,7 @@ #else /* PDP-11 version */ #include "pdp11_defs.h" -extern int32 cpu_opt; +extern uint32 cpu_opt; #endif extern uint16 *M; diff --git a/PDP11/pdp11_io.c b/PDP11/pdp11_io.c index 1e687530..e5909413 100644 --- a/PDP11/pdp11_io.c +++ b/PDP11/pdp11_io.c @@ -1,6 +1,6 @@ /* pdp11_io.c: PDP-11 I/O simulator - Copyright (c) 1993-2011, Robert M Supnik + Copyright (c) 1993-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,19 +23,20 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato) 12-Dec-11 RMS Fixed Qbus interrupts to treat all IO devices as BR4 19-Nov-08 RMS Moved I/O support routines to I/O library 16-May-08 RMS Added multiple DC11 support Renamed DL11 in autoconfigure - 02-Feb-08 RMS Fixed DMA memory address limit test (found by John Dundas) + 02-Feb-08 RMS Fixed DMA memory address limit test (John Dundas) 06-Jul-06 RMS Added multiple KL11/DL11 support 15-Oct-05 RMS Fixed bug in autoconfiguration (missing XU) 25-Jul-05 RMS Revised autoconfiguration algorithm and interface 30-Sep-04 RMS Revised Unibus interface - 28-May-04 RMS Revised I/O dispatching (from John Dundas) + 28-May-04 RMS Revised I/O dispatching (John Dundas) 25-Jan-04 RMS Removed local debug logging support 21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls - 21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner) + 21-Nov-03 RMS Added check for interrupt slot conflict (Dave Hittner) 12-Mar-03 RMS Added logical name support 08-Oct-02 RMS Trimmed I/O bus addresses Added support for dynamic tables @@ -52,7 +53,8 @@ extern uint16 *M; extern int32 int_req[IPL_HLVL]; extern int32 ub_map[UBM_LNT_LW]; -extern int32 cpu_opt, cpu_bme; +extern uint32 cpu_opt; +extern int32 cpu_bme; extern int32 trap_req, ipl; extern int32 cpu_log; extern int32 autcon_enb; diff --git a/PDP11/pdp11_rf.c b/PDP11/pdp11_rf.c index cd2055ed..439fa7b2 100644 --- a/PDP11/pdp11_rf.c +++ b/PDP11/pdp11_rf.c @@ -1,6 +1,6 @@ /* pdp11_rf.c: RF11 fixed head disk simulator - Copyright (c) 2006-2008, Robert M Supnik + Copyright (c) 2006-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,7 +25,8 @@ rf RF11 fixed head disk - 25-Dec-06 RMS Fixed bug in unit mask (found by John Dundas) + 19-Mar-12 RMS Fixed bug in updating mem addr extension (Peter Schorn) + 25-Dec-06 RMS Fixed bug in unit mask (John Dundas) 26-Jun-06 RMS Cloned from RF08 simulator The RF11 is a head-per-track disk. To minimize overhead, the entire RF11 @@ -377,7 +378,7 @@ do { } while ((rf_wc != 0) && (rf_burst != 0)); /* brk if wc, no brst */ rf_da = da & DMASK; /* split da */ -rf_dae = (rf_dae & ~RFDAE_DAE) | ((rf_da >> 16) && RFDAE_DAE); +rf_dae = (rf_dae & ~RFDAE_DAE) | ((rf_da >> 16) & RFDAE_DAE); rf_cma = ma & DMASK; /* split ma */ rf_cs = (rf_cs & ~RFCS_MEX) | ((ma >> (16 - RFCS_V_MEX)) & RFCS_MEX); if ((rf_wc != 0) && ((rf_cs & RFCS_ERR) == 0)) /* more to do? */ diff --git a/PDP11/pdp11_rh.c b/PDP11/pdp11_rh.c index 8e632683..efc7c043 100644 --- a/PDP11/pdp11_rh.c +++ b/PDP11/pdp11_rh.c @@ -1,6 +1,6 @@ /* pdp11_rh.c: PDP-11 Massbus adapter simulator - Copyright (c) 2005-2008, Robert M Supnik + Copyright (c) 2005-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,7 +25,8 @@ rha, rhb RH11/RH70 Massbus adapter - 02-Feb-08 RMS Fixed DMA memory address limit test (found by John Dundas) + 19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato) + 02-Feb-08 RMS Fixed DMA memory address limit test (John Dundas) 17-May-07 RMS Moved CS1 drive enable to devices 21-Nov-05 RMS Added enable/disable routine 07-Jul-05 RMS Removed extraneous externs @@ -158,7 +159,8 @@ typedef struct { MBACTX massbus[MBA_NUM]; -extern int32 cpu_opt, cpu_bme; +extern uint32 cpu_opt; +extern int32 cpu_bme; extern uint16 *M; extern int32 int_req[IPL_HLVL]; extern t_addr cpu_memsize; diff --git a/PDP11/pdp11_rk.c b/PDP11/pdp11_rk.c index 2b7c089c..5e37d54d 100644 --- a/PDP11/pdp11_rk.c +++ b/PDP11/pdp11_rk.c @@ -25,7 +25,7 @@ rk RK11/RKV11/RK05 cartridge disk - 20-Mar-09 RMS Fixed bug in read header (from Walter F Mueller) + 20-Mar-09 RMS Fixed bug in read header (Walter F Mueller) 16-Aug-05 RMS Fixed C++ declaration and cast problems 07-Jul-05 RMS Removed extraneous externs 30-Sep-04 RMS Revised Unibus interface diff --git a/PDP11/pdp11_rl.c b/PDP11/pdp11_rl.c index 84e0ba11..ef338bf5 100644 --- a/PDP11/pdp11_rl.c +++ b/PDP11/pdp11_rl.c @@ -1,1209 +1,1209 @@ -/* pdp11_rl.c: RL11 (RLV12) cartridge disk simulator - - Copyright (c) 1993-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - rl RL11(RLV12)/RL01/RL02 cartridge disk - - 24-Mar-11 JAD Various changes to support diagnostics, including: - - distinguish between RLV11 & 12 - - more complete drive state - - improved head position tracking - - implement MAINT command of RLV11/12 - - always respect unit disable flag - New commands added: - SHOW RLn DSTATE - SET RLn LOAD/UNLOAD - SET RLn OPEN/CLOSED - SET RLn BRUSH/NOBRUSH - SET RLn ONLINE/OFFLINE - SET RL RLV11/RLV12 (PDP-11 only) - SET RL DEBUG/NODEBUG - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) - 16-Aug-05 RMS Fixed C++ declaration and cast problems - 07-Jul-05 RMS Removed extraneous externs - 30-Sep-04 RMS Revised Unibus interface - 04-Jan-04 RMS Changed sim_fsize calling sequence - 19-May-03 RMS Revised for new conditional compilation scheme - 25-Apr-03 RMS Revised for extended file support - 29-Sep-02 RMS Added variable address support to bootstrap - Added vector change/display support - Revised mapping nomenclature - New data structures - 26-Jan-02 RMS Revised bootstrap to conform to M9312 - 06-Jan-02 RMS Revised enable/disable support - 30-Nov-01 RMS Added read only, extended SET/SHOW support - 26-Nov-01 RMS Fixed per-drive error handling - 24-Nov-01 RMS Converted FLG, CAPAC to arrays - 19-Nov-01 RMS Fixed signed/unsigned mismatch in write check - 09-Nov-01 RMS Added bus map, VAX support - 07-Sep-01 RMS Revised device disable and interrupt mechanisms - 20-Aug-01 RMS Added bad block option in attach - 17-Jul-01 RMS Fixed warning from VC++ 6.0 - 26-Apr-01 RMS Added device enable/disable support - 25-Mar-01 RMS Fixed block fill calculation - 15-Feb-01 RMS Corrected bootstrap string - 12-Nov-97 RMS Added bad block table command - 25-Nov-96 RMS Default units to autosize - 29-Jun-96 RMS Added unit disable support - - The RL11 is a four drive cartridge disk subsystem. An RL01 drive - consists of 256 cylinders, each with 2 surfaces containing 40 sectors - of 256 bytes. An RL02 drive has 512 cylinders. The RLV12 is a - controller variant which supports 22b direct addressing. - - The most complicated part of the RL11 controller is the way it does - seeks. Seeking is relative to the current disk address; this requires - keeping accurate track of the current cylinder. The RL11 will not - switch heads or cross cylinders during transfers. - - The RL11 functions in three environments: - - - PDP-11 Q22 systems - the I/O map is one for one, so it's safe to - go through the I/O map - - PDP-11 Unibus 22b systems - the RL11 behaves as an 18b Unibus - peripheral and must go through the I/O map - - VAX Q22 systems - the RL11 must go through the I/O map -*/ - -#if defined (VM_PDP10) /* PDP10 version */ -#error "RL11 is not supported on the PDP-10!" - -#elif defined (VM_VAX) /* VAX version */ -#include "vax_defs.h" - -#else /* PDP-11 version */ -#include "pdp11_defs.h" -extern uint32 cpu_opt; -extern UNIT cpu_unit; -#endif - -/* Constants */ - -#define RL_NUMWD (128) /* words/sector */ -#define RL_NUMSC (40) /* sectors/surface */ -#define RL_NUMSF (2) /* surfaces/cylinder */ -#define RL_NUMCY (256) /* cylinders/drive */ -#define RL_NUMDR (4) /* drives/controller */ -#define RL_MAXFR (RL_NUMSC * RL_NUMWD) /* max transfer */ -#define RL01_SIZE (RL_NUMCY * RL_NUMSF * RL_NUMSC * RL_NUMWD) /* words/drive */ -#define RL02_SIZE (RL01_SIZE * 2) /* words/drive */ - -/* Device flags */ - -#define DEV_V_RLV11 (DEV_V_UF + 7) /* RLV11 */ -#define DEV_RLV11 (1u << DEV_V_RLV11) - -/* Flags in the unit flags word */ - -#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */ -#define UNIT_V_RL02 (UNIT_V_UF + 1) /* RL01 vs RL02 */ -#define UNIT_V_AUTO (UNIT_V_UF + 2) /* autosize enable */ -#define UNIT_V_DUMMY (UNIT_V_UF + 3) /* dummy flag, for SET BADBLOCK */ -#define UNIT_V_OFFL (UNIT_V_UF + 4) /* unit off line */ -#define UNIT_V_BRUSH (UNIT_V_UF + 5) /* unit has brushes */ -#define UNIT_BRUSH (1u << UNIT_V_BRUSH) -#define UNIT_OFFL (1u << UNIT_V_OFFL) -#define UNIT_DUMMY (1u << UNIT_V_DUMMY) -#define UNIT_WLK (1u << UNIT_V_WLK) -#define UNIT_RL02 (1u << UNIT_V_RL02) -#define UNIT_AUTO (1u << UNIT_V_AUTO) -#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protected */ - -/* Parameters in the unit descriptor */ - -#define TRK u3 /* current track:head:sector */ -#define STAT u4 /* status */ -#define FNC u5 /* function */ - -/* RLDS, NI = not implemented, * = kept in STAT, ^ = kept in TRK , ! = kept in uptr */ - -#define RLDS_M_STATE (07) -#define RLDS_LOAD (0) /* no cartridge */ -#define RLDS_SPIN (1) /* spin-up */ -#define RLDS_BRUSH (2) /* brush cycle *! */ -#define RLDS_HLOAD (3) /* load heads */ -#define RLDS_SEEK (4) /* drive seeking * */ -#define RLDS_LOCK (5) /* lock on * */ -#define RLDS_UNL (6) /* unload heads */ -#define RLDS_DOWN (7) /* spin-down */ -#define RLDS_BHO (0000010) /* brushes home * */ -#define RLDS_HDO (0000020) /* heads out * */ -#define RLDS_CVO (0000040) /* cover open * */ -#define RLDS_HD (0000100) /* head select ^ */ -#define RLDS_RL02 (0000200) /* RL02 ! */ -#define RLDS_DSE (0000400) /* drv sel err */ -#define RLDS_VCK (0001000) /* vol check * */ -#define RLDS_WGE (0002000) /* wr gate err * */ -#define RLDS_SPE (0004000) /* spin err * */ -#define RLDS_STO (0010000) /* seek time out * */ -#define RLDS_WLK (0020000) /* wr locked ! */ -#define RLDS_HCE (0040000) /* hd curr err NI */ -#define RLDS_WDE (0100000) /* wr data err NI */ -#define RLDS_ERR (RLDS_WDE|RLDS_HCE|RLDS_STO|RLDS_SPE|RLDS_WGE| \ - RLDS_VCK|RLDS_DSE) /* errors bits */ - -/* RLCS */ - -#define RLCS_DRDY (0000001) /* drive ready */ -#define RLCS_M_FUNC (0000007) /* function */ -#define RLCS_NOP (0) -#define RLCS_WCHK (1) -#define RLCS_GSTA (2) -#define RLCS_SEEK (3) -#define RLCS_RHDR (4) -#define RLCS_WRITE (5) -#define RLCS_READ (6) -#define RLCS_RNOHDR (7) -#define RLCS_SPECIAL (8) /* internal function, drive state */ -#define RLCS_V_FUNC (1) -#define RLCS_M_MEX (03) /* memory extension */ -#define RLCS_V_MEX (4) -#define RLCS_MEX (RLCS_M_MEX << RLCS_V_MEX) -#define RLCS_M_DRIVE (03) -#define RLCS_V_DRIVE (8) -#define RLCS_INCMP (0002000) /* incomplete */ -#define RLCS_CRC (0004000) /* CRC error */ -#define RLCS_HCRC (RLCS_CRC|RLCS_INCMP) /* header CRC error */ -#define RLCS_DLT (0010000) /* data late */ -#define RLCS_HDE (RLCS_DLT|RLCS_INCMP) /* header not found error */ -#define RLCS_NXM (0020000) /* non-exist memory */ -#define RLCS_PAR (RLCS_NXM|RLCS_INCMP) /* parity error */ -#define RLCS_DRE (0040000) /* drive error */ -#define RLCS_ERR (0100000) /* error summary */ -#define RLCS_ALLERR (RLCS_ERR|RLCS_DRE|RLCS_NXM|RLCS_HDE|RLCS_CRC|RLCS_INCMP) -#define RLCS_RW (0001776) /* read/write */ -#define GET_FUNC(x) (((x) >> RLCS_V_FUNC) & RLCS_M_FUNC) -#define GET_DRIVE(x) (((x) >> RLCS_V_DRIVE) & RLCS_M_DRIVE) - -/* RLDA */ - -#define RLDA_GS (0000002) /* get status */ -#define RLDA_SK_DIR (0000004) /* direction */ -#define RLDA_GS_CLR (0000010) /* clear errors */ -#define RLDA_SK_HD (0000020) /* head select */ - -#define RLDA_V_SECT (0) /* sector */ -#define RLDA_M_SECT (077) -#define RLDA_V_TRACK (6) /* track */ -#define RLDA_M_TRACK (01777) -#define RLDA_HD0 (0 << RLDA_V_TRACK) -#define RLDA_HD1 (1u << RLDA_V_TRACK) -#define RLDA_V_CYL (7) /* cylinder */ -#define RLDA_M_CYL (0777) -#define RLDA_TRACK (RLDA_M_TRACK << RLDA_V_TRACK) -#define RLDA_CYL (RLDA_M_CYL << RLDA_V_CYL) -#define GET_SECT(x) (((x) >> RLDA_V_SECT) & RLDA_M_SECT) -#define GET_CYL(x) (((x) >> RLDA_V_CYL) & RLDA_M_CYL) -#define GET_TRACK(x) (((x) >> RLDA_V_TRACK) & RLDA_M_TRACK) -#define GET_DA(x) ((GET_TRACK (x) * RL_NUMSC) + GET_SECT (x)) - -/* RLBA */ - -#define RLBA_IMP (0177777) /* implemented */ - -/* RLBAE */ - -#define RLBAE_IMP (0000077) /* implemented */ - -extern int32 int_req[IPL_HLVL]; -extern FILE *sim_deb; - -uint16 *rlxb = NULL; /* xfer buffer */ -int32 rlcs = 0; /* control/status */ -int32 rlba = 0; /* memory address */ -int32 rlbae = 0; /* mem addr extension */ -int32 rlda = 0; /* disk addr */ -int32 rlmp = 0, rlmp1 = 0, rlmp2 = 0; /* mp register queue */ -int32 rl_swait = 10; /* seek wait */ -int32 rl_rwait = 10; /* rotate wait */ -int32 rl_stopioe = 1; /* stop on error */ - -/* forward references */ -DEVICE rl_dev; -t_stat rl_rd (int32 *data, int32 PA, int32 access); -t_stat rl_wr (int32 data, int32 PA, int32 access); -t_stat rl_svc (UNIT *uptr); -t_stat rl_reset (DEVICE *dptr); -void rl_set_done (int32 error); -t_stat rl_boot (int32 unitno, DEVICE *dptr); -t_stat rl_attach (UNIT *uptr, char *cptr); -t_stat rl_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat rl_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc); -static void rlv_maint (void); -t_stat rl_detach (UNIT *uptr); -t_stat rl_set_cover (UNIT *, int32, char *, void *); -t_stat rl_show_cover (FILE *, UNIT *, int, void *); -t_stat rl_set_load (UNIT *, int32, char *, void *); -t_stat rl_show_load (FILE *, UNIT *, int, void *); -t_stat rl_show_dstate (FILE *, UNIT *, int, void *); -#if defined (VM_PDP11) -t_stat rl_set_ctrl (UNIT *uptr, int32 val, char *cptr, void *desc); -#endif -t_stat rl_show_ctrl (FILE *st, UNIT *uptr, int val, void *desc); - -/* RL11 data structures - - rl_dev RL device descriptor - rl_unit RL unit list - rl_reg RL register list - rl_mod RL modifier list -*/ - -static DIB rl_dib = { - IOBA_RL, IOLN_RL, &rl_rd, &rl_wr, - 1, IVCL (RL), VEC_RL, { NULL } }; - -static UNIT rl_unit[] = { - { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) }, - { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) }, - { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) }, - { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ - UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) } - }; - -static const REG rl_reg[] = { - { GRDATA (RLCS, rlcs, DEV_RDX, 16, 0) }, - { GRDATA (RLDA, rlda, DEV_RDX, 16, 0) }, - { GRDATA (RLBA, rlba, DEV_RDX, 16, 0) }, - { GRDATA (RLBAE, rlbae, DEV_RDX, 6, 0) }, - { GRDATA (RLMP, rlmp, DEV_RDX, 16, 0) }, - { GRDATA (RLMP1, rlmp1, DEV_RDX, 16, 0) }, - { GRDATA (RLMP2, rlmp2, DEV_RDX, 16, 0) }, - { FLDATA (INT, IREQ (RL), INT_V_RL) }, - { FLDATA (ERR, rlcs, CSR_V_ERR) }, - { FLDATA (DONE, rlcs, CSR_V_DONE) }, - { FLDATA (IE, rlcs, CSR_V_IE) }, - { DRDATA (STIME, rl_swait, 24), PV_LEFT }, - { DRDATA (RTIME, rl_rwait, 24), PV_LEFT }, - { URDATA (CAPAC, rl_unit[0].capac, 10, T_ADDR_W, 0, - RL_NUMDR, PV_LEFT + REG_HRO) }, - { FLDATA (STOP_IOE, rl_stopioe, 0) }, - { GRDATA (DEVADDR, rl_dib.ba, DEV_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, rl_dib.vec, DEV_RDX, 16, 0), REG_HRO }, - { NULL } - }; - -static const MTAB rl_mod[] = { -#if defined (VM_PDP11) - { MTAB_XTD|MTAB_VDV, (DEV_RLV11|DEV_Q18), "", "RLV11", &rl_set_ctrl, &rl_show_ctrl, NULL}, - { MTAB_XTD|MTAB_VDV, 0, NULL, "RLV12", &rl_set_ctrl, NULL, NULL}, -#endif - { UNIT_OFFL, 0, "on line", "ONLINE", NULL, NULL }, - { UNIT_OFFL, UNIT_OFFL, "off line", "OFFLINE", NULL, NULL }, - { UNIT_BRUSH, 0, NULL, "NOBRUSH", NULL, NULL }, - { UNIT_BRUSH, UNIT_BRUSH, "has brushes", "BRUSH", NULL, NULL }, - - { MTAB_XTD|MTAB_VUN|MTAB_NMO, RLDS_CVO, "open", "OPEN", &rl_set_cover, &rl_show_cover, NULL }, - { MTAB_XTD|MTAB_VUN, 0, NULL, "CLOSED", &rl_set_cover, NULL, NULL }, - { MTAB_XTD|MTAB_VUN|MTAB_NMO, 0, "load", "LOAD", &rl_set_load, &rl_show_load, NULL }, - { MTAB_XTD|MTAB_VUN, 1, NULL, "UNLOAD", &rl_set_load, NULL, NULL }, - { MTAB_XTD|MTAB_VUN|MTAB_NMO, 0, "DSTATE", NULL, NULL, &rl_show_dstate, NULL }, - - { UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL }, - { UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL }, - { UNIT_DUMMY, 0, NULL, "BADBLOCK", &rl_set_bad }, - { (UNIT_RL02+UNIT_ATT), UNIT_ATT, "RL01", NULL, NULL }, - { (UNIT_RL02+UNIT_ATT), (UNIT_RL02+UNIT_ATT), "RL02", NULL, NULL }, - { (UNIT_AUTO+UNIT_RL02+UNIT_ATT), 0, "RL01", NULL, NULL }, - { (UNIT_AUTO+UNIT_RL02+UNIT_ATT), UNIT_RL02, "RL02", NULL, NULL }, - { (UNIT_AUTO+UNIT_ATT), UNIT_AUTO, "autosize", NULL, NULL }, - { UNIT_AUTO, UNIT_AUTO, NULL, "AUTOSIZE", NULL }, - { (UNIT_AUTO+UNIT_RL02), 0, NULL, "RL01", &rl_set_size }, - { (UNIT_AUTO+UNIT_RL02), UNIT_RL02, NULL, "RL02", &rl_set_size }, - { MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS", - &set_addr, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", - &set_vec, &show_vec, NULL }, - { 0 } - }; - -DEVICE rl_dev = { - "RL", (UNIT *) &rl_unit, (REG *) rl_reg, (MTAB *) rl_mod, - RL_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16, - NULL, NULL, &rl_reset, - &rl_boot, &rl_attach, &rl_detach, - &rl_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG - }; - -/* Drive states */ -static const char * const state[] = { - "Load Cartridge", "Spin Up", "Brush", "Load Heads", - "Seek", "Lock On", "Unload Heads", "Spin Down" -}; - -/* I/O dispatch routines, I/O addresses 17774400 - 17774411 - - 17774400 RLCS read/write - 17774402 RLBA read/write - 17774404 RLDA read/write - 17774406 RLMP read/write - 17774410 RLBAE read/write -*/ - -t_stat rl_rd (int32 *data, int32 PA, int32 access) -{ -UNIT *uptr; - -switch ((PA >> 1) & 07) { /* decode PA<2:1> */ - - case 0: /* RLCS */ - rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); -/* -The DRDY signal is sent by the selected drive to indicate that it -is ready to read or write or seek. It is sent when the heads are -not moving and are locked onto a cylinder. This is continuously -monitored by the drive and controller. [EK-0RL11-TD-001, p. 3-8] -Use the DS bits to determine if the drive has any outstanding I/O -operations and set DRDY as appropriate. - -This seems to imply that only a Seek operation (not Read/Write) -causes ready to be false. -*/ - uptr = rl_dev.units + GET_DRIVE (rlcs); - if ((uptr->flags & UNIT_OFFL) || (uptr->STAT & RLDS_VCK)) { - rlcs |= RLCS_DRE; - rlcs &= ~RLCS_DRDY; - } else if (sim_is_active (uptr) || (uptr->flags & UNIT_DIS) || - ((uptr->STAT & RLDS_M_STATE) != RLDS_LOCK)) - rlcs &= ~RLCS_DRDY; - else - rlcs |= RLCS_DRDY; /* see if ready */ -/* -Make sure the error summary bit properly reflects the sum of other -errors. -*/ - if (rlcs & RLCS_ALLERR) - rlcs |= RLCS_ERR; - *data = rlcs; - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL rd: RLCS %06o\n", rlcs); - break; - - case 1: /* RLBA */ - *data = rlba & RLBA_IMP; - break; - - case 2: /* RLDA */ - *data = rlda; - break; - - case 3: /* RLMP */ - *data = rlmp; - rlmp = rlmp1; /* ripple data */ - rlmp1 = rlmp2; - break; - - case 4: /* RLBAE */ - if (UNIBUS || (rl_dev.flags & DEV_RLV11)) /* not in RL11/RLV11 */ - return SCPE_NXM; - *data = rlbae & RLBAE_IMP; - break; - - default: - return (SCPE_NXM); - } /* end switch */ - -return SCPE_OK; -} - -t_stat rl_wr (int32 data, int32 PA, int32 access) -{ -int32 curr, offs, newc, maxc, tim; -UNIT *uptr; - -switch ((PA >> 1) & 07) { /* decode PA<2:1> */ - - case 0: /* RLCS */ - rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); - uptr = rl_dev.units + GET_DRIVE (data); /* get new drive */ - if (access == WRITEB) - data = (PA & 1)? (rlcs & 0377) | (data << 8): (rlcs & ~0377) | data; - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL wr: RLCS %06o new %06o\n", rlcs, data); - rlcs = (rlcs & ~RLCS_RW) | (data & RLCS_RW); - rlbae = (rlbae & ~RLCS_M_MEX) | ((rlcs >> RLCS_V_MEX) & RLCS_M_MEX); -/* -Commands to the controller are only executed with the CRDY (DONE) -bit is cleared by software. If set, check for interrupts and return. -*/ - if (data & CSR_DONE) { /* ready set? */ - if ((data & CSR_IE) == 0) - CLR_INT (RL); - else if ((rlcs & (CSR_DONE + CSR_IE)) == CSR_DONE) - SET_INT (RL); - return SCPE_OK; - } - - CLR_INT (RL); /* clear interrupt */ - rlcs &= ~RLCS_ALLERR; /* clear errors */ - switch (GET_FUNC (rlcs)) { /* case on RLCS<3:1> */ - case RLCS_NOP: /* nop */ - if (!UNIBUS) /* RLV1x has MAINT command */ - rlv_maint (); - rl_set_done (0); - break; - case RLCS_SEEK: /* seek */ - if ((uptr->flags & (UNIT_DIS|UNIT_OFFL)) || (!(uptr->flags & UNIT_ATT))) { - rl_set_done (RLCS_ERR | RLCS_INCMP); - uptr->STAT |= RLDS_STO; - break; - } - curr = GET_CYL (uptr->TRK); /* current cylinder */ - offs = GET_CYL (rlda); /* offset */ - if (rlda & RLDA_SK_DIR) { /* in or out? */ - newc = curr + offs; /* out */ - maxc = (uptr->flags & UNIT_RL02)? - RL_NUMCY * 2: RL_NUMCY; - if (newc >= maxc) - newc = maxc - 1; - } else { - newc = curr - offs; /* in */ - if (newc < 0) - newc = 0; - } - /* enter velocity mode? only if a different cylinder */ - if (newc != curr) - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_SEEK; /* move the positioner */ -/* TBD: if a head switch, sector should be RL_NUMSC/2? */ - uptr->TRK = (newc << RLDA_V_CYL) | /* put on track */ - ((rlda & RLDA_SK_HD)? RLDA_HD1: RLDA_HD0); -/* -Real timing: -min 6.5ms, max 15ms for head switch, -max 17ms for 1 track seek w/head switch -55ms avg seek -100ms max seek -*/ - tim = abs (newc - curr); - if (tim == 0) - tim++; - tim *= rl_swait; - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL SEEK: drv %d, dist %d, head sw %d, tim %d\n", - (int32) (uptr - rl_dev.units), - abs (newc - curr), (rlda & RLDA_SK_HD), tim); - uptr->FNC = RLCS_SEEK; - sim_activate (uptr, tim); /* must be > 0 */ - rl_set_done (0); /* ctrlr is ready */ - break; - case RLCS_GSTA: - if (!(rlda & RLDA_GS)) { /* GS bit must be set */ - rl_set_done (RLCS_ERR | RLCS_INCMP); /* OPI; request error */ - return (SCPE_OK); - } - if (rlda & RLDA_GS_CLR) /* reset errors? */ - uptr->STAT &= ~RLDS_ERR; - /* develop drive state */ - rlmp = uptr->STAT | (uptr->TRK & RLDS_HD); - if (uptr->flags & UNIT_RL02) - rlmp |= RLDS_RL02; - if (uptr->flags & UNIT_WPRT) - rlmp |= RLDS_WLK; - if (uptr->flags & (UNIT_DIS | UNIT_OFFL)) { - rlmp |= RLDS_DSE; - rl_set_done (RLCS_DRE | RLCS_INCMP); - } - rlmp2 = rlmp1 = rlmp; - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL GSTA: rlds=%06o drv=%ld\n", - rlmp, uptr - rl_dev.units); - rl_set_done (0); /* done */ - break; - default: /* data transfer */ - if ((uptr->flags & (UNIT_DIS|UNIT_OFFL)) || (!(uptr->flags & UNIT_ATT))) { - rl_set_done (RLCS_INCMP); - break; - } -/* -EK-0RL11-TD-001, p2-3: "If the CPU software initiates another -operation on a drive that is busy seeking, the controller will -suspend the operation until the seek is completed." - -Check for the condition where there is an outstanding operation but -the program is requesting another operation without waiting for -drive ready. If so, remove the previous queue entry, complete the -operation now, and queue the next operation. -*/ - if (sim_is_active (uptr)) { - sim_cancel (uptr); - rl_svc (uptr); - } - uptr->FNC = GET_FUNC (rlcs); - sim_activate (uptr, rl_swait); /* activate unit */ - break; - } /* end switch func */ - break; /* end case RLCS */ -/* -Contrary to what the RL01/RL02 User Guide (EK-RL012-UG-006, p.4-5) -says, bit 0 can be written and read (as 1) on an RLV12 (verified -2011-01-05). Not sure about the RLV11. -*/ - case 1: /* RLBA */ - if (access == WRITEB) - data = (PA & 1)? (rlba & 0377) | (data << 8): (rlba & ~0377) | data; - rlba = data & (UNIBUS ? 0177776 : 0177777); - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL wr: RLBA %06o\n", rlba); - break; - - case 2: /* RLDA */ - if (access == WRITEB) - data = (PA & 1)? (rlda & 0377) | (data << 8): (rlda & ~0377) | data; - rlda = data; - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL wr: RLDA %06o\n", rlda); - break; - - case 3: /* RLMP */ - if (access == WRITEB) - data = (PA & 1)? (rlmp & 0377) | (data << 8): (rlmp & ~0377) | data; - rlmp = rlmp1 = rlmp2 = data; - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL wr: RLMP %06o\n", rlmp); - break; - - case 4: /* RLBAE */ - if (UNIBUS || (rl_dev.flags & DEV_RLV11)) /* not in RL11/RLV11 */ - return SCPE_NXM; - if (PA & 1) - return SCPE_OK; - rlbae = data & RLBAE_IMP; - rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL wr: RLBAE %06o\n", rlbae); - break; - default: - return (SCPE_NXM); - } /* end switch */ - -return SCPE_OK; -} - -/* CRC16 as implemented by the DEC 9401 chip */ -static uint32 calcCRC (const int wc, const uint16 *data) -{ - uint32 crc, j, d; - int32 i; - - crc = 0; - for (i = 0; i < wc; i++) { - d = *data++; - /* cribbed from KG11-A */ - for (j = 0; j < 16; j++) { - crc = (crc & ~01) | ((crc & 01) ^ (d & 01)); - crc = (crc & 01) ? (crc >> 1) ^ 0120001 : crc >> 1; - d >>= 1; - } - } - return (crc); -} - -/* -Perform the maintenance function of the RLV1x; this is fully described -on pages 4-14 and 4-15 of EK-RL012-UG-006. Note that the description -of this in EK-RLV12-UG-002 (p.5-3) contains a typo, the constant -for -511 is incorrect. -*/ -static void rlv_maint (void) -{ - int32 i; - uint32 ma; - uint16 w; - - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL maint: RLDA %06o\n", rlda); - /* 1: check internal logic */ - rlda = (rlda & ~0377) | ((rlda + 1) & 0377); - - /* 2: check internal logic */ - rlda = (rlda & ~0377) | ((rlda + 1) & 0377); - - /* 3: check DMA transfers */ - ma = (rlbae << 16) | rlba; /* get mem addr */ - /* xfer 256 words to FIFO */ - if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL maint: RLMP %06o\n", rlmp); - if (rlmp != 0177001) { /* must be exactly -511 */ - rlcs |= RLCS_ERR | RLCS_HDE; /* HNF error */ - return; - } - for (i = 0; i < 256; i++) { - if (Map_ReadW (ma, 2, &rlxb[i])) { /* mem wd */ - rlcs |= RLCS_ERR | RLCS_NXM; /* nxm */ - break; - } - ma += 2; - rlmp++; - } - /* xfer 255 words from FIFO */ - for (i = 0; i < 255; i++) { - if (Map_WriteW (ma, 2, &rlxb[i])) { /* store buffer */ - rlcs |= RLCS_ERR | RLCS_NXM; /* nxm */ - break; - } - ma += 2; - rlmp++; - } - rlda = (rlda & ~0377) | ((rlda + 1) & 0377); - rlbae = (ma >> 16) & RLBAE_IMP; /* upper 6b */ - rlba = ma & RLBA_IMP; /* lower 16b */ - - /* 4: check the CRC of (DAR + 3) */ - w = rlda; - rlxb[0] = calcCRC (1, &w); /* calculate CRC */ - rlda = (rlda & ~0377) | ((rlda + 1) & 0377); - - /* 5: check the CRC of (DAR + 4) */ - w = rlda; - rlxb[1] = calcCRC (1, &w); /* calculate CRC */ - rlda = (rlda & ~0377) | ((rlda + 1) & 0377); - - /* 6: check the CRC of (CRC of DAR + 4) */ - w = rlxb[1]; - rlxb[1] = calcCRC (1, &w); /* calculate CRC */ - rlmp = rlxb[0]; - rlmp1 = rlxb[1]; - rlda = (rlda & ~0377) | ((rlda + 1) & 0377); -} - -/* Service unit timeout - - If seek in progress, complete seek command - Else complete data transfer command - - The unit control block contains the function and cylinder for - the current command. -*/ - -t_stat rl_svc (UNIT *uptr) -{ -int32 err, wc, maxwc, t; -int32 i, da, awc; -uint32 ma; -uint16 comp; -static const char * const funcname[] = { - "NOP", "WCK", "GSTA", "SEEK", - "RHDR", "WT", "RD", "RNOHDR", "SPECIAL", -}; - -if (DEBUG_PRS (rl_dev)) { - if (uptr->FNC == RLCS_SPECIAL) - fprintf (sim_deb, ">>RL svc: func=SPECIAL(%s) drv=%d\n", - state[uptr->STAT & RLDS_M_STATE], (int32) (uptr - rl_dev.units)); - else - fprintf (sim_deb, ">>RL svc: func=%s drv=%d rlda=%06o\n", - funcname[uptr->FNC], (int32) (uptr - rl_dev.units), rlda); -} - -/* really shouldn't happen... */ -if ((uptr->FNC == RLCS_GSTA) || (uptr->FNC == RLCS_NOP)) { - rl_set_done (0); - return (SCPE_OK); - } - -/* -This situation occurs when the drive (not controller) state needs -to transition from one state to another. The state bits indicate -the state the drive is currently in. -*/ - -if (uptr->FNC == RLCS_SPECIAL) { - switch (uptr->STAT & RLDS_M_STATE) { -/* -The LOAD state is a little different. We can stay in LOAD until -the user hits the RUN (LOAD) button, at which time we should come -here to transition to the next state and begin the startup process. -*/ - case RLDS_LOAD: - /* load pressed, spinning up */ - if (!(uptr->STAT & RLDS_CVO)) { - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_SPIN; - /* actual time is 45-50 seconds from press to Lock */ - sim_activate (uptr, 200 * rl_swait); - uptr->STAT &= ~RLDS_HDO; - uptr->STAT |= RLDS_BHO; - } - break; -/* -Original RL01 drives would transition to the Brush Cycle, but this -was removed in a later ECO. -*/ - case RLDS_SPIN: /* spun up, load brushes or heads */ - if (uptr->flags & UNIT_BRUSH) { - uptr->STAT &= ~RLDS_BHO; - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_BRUSH; - } else { - uptr->STAT |= RLDS_BHO; - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_HLOAD; - } - sim_activate (uptr, 200 * rl_swait); - break; - case RLDS_BRUSH: - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_HLOAD; - uptr->STAT |= RLDS_BHO; - sim_activate (uptr, 200 * rl_swait); - break; - case RLDS_HLOAD: /* heads loaded, seek to home */ - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_SEEK; - sim_activate (uptr, 200 * rl_swait); - uptr->STAT |= RLDS_BHO | RLDS_HDO; - uptr->TRK = 0; - break; - case RLDS_SEEK: /* home found, lock on */ - /* enter postion mode */ - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOCK; - /* sim_activate (uptr, rl_swait); */ - break; - case RLDS_LOCK: /* tracking, nothing to do */ - /* illuminate ready lamp */ - break; -/* -Initiated by depressing the Run (LOAD) switch. -*/ - case RLDS_UNL: /* unload pressed, heads unloaded, spin down */ - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_DOWN; - uptr->STAT &= ~RLDS_HDO; /* retract heads */ - /* actual time is ~30 seconds */ - sim_activate (uptr, 200 * rl_swait); - break; - case RLDS_DOWN: /* OK to open cover */ - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOAD; - uptr->STAT |= RLDS_BHO | RLDS_VCK; - break; - default: - ; /* can't happen */ - } - return (SCPE_OK); -} - -if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */ - uptr->STAT |= RLDS_SPE; /* spin error */ - rl_set_done (RLCS_ERR | RLCS_INCMP); /* flag error */ - return IORETURN (rl_stopioe, SCPE_UNATT); - } - -if ((uptr->FNC == RLCS_WRITE) && (uptr->flags & UNIT_WPRT)) { - uptr->STAT |= RLDS_WGE; /* write and locked */ - rl_set_done (RLCS_ERR | RLCS_DRE); - return SCPE_OK; - } - -if (uptr->FNC == RLCS_SEEK) { /* seek? */ - /* enter position mode */ - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOCK; /* heads locked on cyl */ - return (SCPE_OK); - } - -if (uptr->FNC == RLCS_RHDR) { /* read header? */ - uint16 hdr[2]; - hdr[0] = rlmp = uptr->TRK & 0177777; - hdr[1] = rlmp1 = 0; - rlmp2 = calcCRC (2, &hdr[0]); /* calculate header CRC */ - rl_set_done (0); /* done */ - /* simulate sequential rotation about the current track */ - uptr->TRK = (uptr->TRK & ~RLDA_M_SECT) | - ((uptr->TRK + 1) & RLDA_M_SECT); - if (GET_SECT (uptr->TRK) >= RL_NUMSC) /* end of track? */ - uptr->TRK &= ~RLDA_M_SECT; /* wrap to 0 */ - return (SCPE_OK); - } - -if (uptr->FNC == RLCS_RNOHDR) { - if (GET_SECT (uptr->TRK) >= RL_NUMSC) { - rl_set_done (RLCS_ERR | RLCS_HDE); /* wrong cylinder? */ - return (SCPE_OK); - } - da = GET_DA (uptr->TRK) * RL_NUMWD; /* get disk addr */ - maxwc = (RL_NUMSC - GET_SECT (uptr->TRK)) * RL_NUMWD; /* max transfer */ -} else { - /* bad cyl or sector? */ - if (((uptr->TRK & RLDA_CYL) != (rlda & RLDA_CYL)) || (GET_SECT (rlda) >= RL_NUMSC)) { - rl_set_done (RLCS_ERR | RLCS_HDE | RLCS_INCMP); /* wrong cylinder? */ - return (SCPE_OK); - } - da = GET_DA (rlda) * RL_NUMWD; /* get disk addr */ - maxwc = (RL_NUMSC - GET_SECT (rlda)) * RL_NUMWD; /* max transfer */ -} - -ma = (rlbae << 16) | rlba; /* get mem addr */ -wc = 0200000 - rlmp; /* get true wc */ - -if (wc > maxwc) /* track overrun? */ - wc = maxwc; -err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); - -if (DEBUG_PRS (rl_dev)) - fprintf (sim_deb, ">>RL svc: cyl %d, sect %d, wc %d, maxwc %d, err %d\n", - GET_CYL (rlda), GET_SECT (rlda), wc, maxwc, err); - - if ((uptr->FNC >= RLCS_READ) && (err == 0)) { /* read (no hdr)? */ - i = fxread (rlxb, sizeof (int16), wc, uptr->fileref); - err = ferror (uptr->fileref); - for ( ; i < wc; i++) /* fill buffer */ - rlxb[i] = 0; - if ((t = Map_WriteW (ma, wc << 1, rlxb))) { /* store buffer */ - rlcs = rlcs | RLCS_ERR | RLCS_NXM; /* nxm */ - wc = wc - t; /* adjust wc */ - } - } /* end read */ - -else -if ((uptr->FNC == RLCS_WRITE) && (err == 0)) { /* write? */ - if ((t = Map_ReadW (ma, wc << 1, rlxb))) { /* fetch buffer */ - rlcs = rlcs | RLCS_ERR | RLCS_NXM; /* nxm */ - wc = wc - t; /* adj xfer lnt */ - } - if (wc) { /* any xfer? */ - awc = (wc + (RL_NUMWD - 1)) & ~(RL_NUMWD - 1); /* clr to */ - for (i = wc; i < awc; i++) /* end of blk */ - rlxb[i] = 0; - fxwrite (rlxb, sizeof (int16), awc, uptr->fileref); - err = ferror (uptr->fileref); - } - } /* end write */ - -else -if ((uptr->FNC == RLCS_WCHK) && (err == 0)) { /* write check? */ - i = fxread (rlxb, sizeof (int16), wc, uptr->fileref); - err = ferror (uptr->fileref); - for ( ; i < wc; i++) /* fill buffer */ - rlxb[i] = 0; - awc = wc; /* save wc */ - for (wc = 0; (err == 0) && (wc < awc); wc++) { /* loop thru buf */ - if (Map_ReadW (ma + (wc << 1), 2, &comp)) { /* mem wd */ - rlcs = rlcs | RLCS_ERR | RLCS_NXM; /* nxm */ - break; - } - if (comp != rlxb[wc]) /* check to buf */ - rlcs = rlcs | RLCS_ERR | RLCS_CRC; - } /* end for */ - } /* end wcheck */ - -/* Complete Write Check, Write, Read, Read no header */ -rlmp = (rlmp + wc) & 0177777; /* final word count */ -if (rlmp != 0) /* completed? */ - rlcs |= RLCS_ERR | RLCS_INCMP | RLCS_HDE; - -ma += (wc << 1); /* final byte addr */ -rlbae = (ma >> 16) & RLBAE_IMP; /* upper 6b */ -rlba = ma & RLBA_IMP; /* lower 16b */ -rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); - -/* -If we ran off the end of the track, return 40 in rlda, but keep -track over a legitimate sector (0)? -*/ -rlda += ((wc + (RL_NUMWD - 1)) / RL_NUMWD); -/* update head pos */ -if (uptr->FNC == RLCS_RNOHDR) - uptr->TRK = (uptr->TRK & ~RLDA_M_SECT) | - ((uptr->TRK + ((wc + (RL_NUMWD - 1)) / RL_NUMWD)) & RLDA_M_SECT); -else - uptr->TRK = rlda; -if (GET_SECT (uptr->TRK) >= RL_NUMSC) - uptr->TRK &= ~RLDA_M_SECT; /* wrap to 0 */ - -rl_set_done (0); - -if (err != 0) { /* error? */ - perror ("RL I/O error"); - clearerr (uptr->fileref); - return SCPE_IOERR; - } -return SCPE_OK; -} - -/* Set done and possibly errors */ - -void rl_set_done (int32 status) -{ -rlcs |= status | CSR_DONE; /* set done */ -if (rlcs & CSR_IE) - SET_INT (RL); -else CLR_INT (RL); -} - -/* Device reset - - Note that the RL11 does NOT recalibrate its drives on RESET -*/ - -t_stat rl_reset (DEVICE *dptr) -{ -int32 i; -UNIT *uptr; - -rlcs = CSR_DONE; -rlda = rlba = rlbae = rlmp = rlmp1 = rlmp2 = 0; -CLR_INT (RL); -for (i = 0; i < RL_NUMDR; i++) { - uptr = rl_dev.units + i; - sim_cancel (uptr); - uptr->STAT &= ~RLDS_ERR; - } -if (rlxb == NULL) - rlxb = (uint16 *) calloc (RL_MAXFR, sizeof (uint16)); -if (rlxb == NULL) - return SCPE_MEM; -return SCPE_OK; -} - -/* Attach routine */ - -t_stat rl_attach (UNIT *uptr, char *cptr) -{ -uint32 p; -t_stat r; - -uptr->capac = (uptr->flags & UNIT_RL02)? RL02_SIZE: RL01_SIZE; -r = attach_unit (uptr, cptr); /* attach unit */ -if (r != SCPE_OK) /* error? */ - return r; -/* -For compatibility with existing SIMH behavior, set the drive state -as if the load procedure had already executed. -*/ -uptr->TRK = 0; /* cylinder 0 */ -uptr->STAT = RLDS_HDO | RLDS_BHO | RLDS_VCK | RLDS_LOCK; /* new volume */ -if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */ - if (uptr->flags & UNIT_RO) /* if ro, done */ - return SCPE_OK; - return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD); - } -if ((uptr->flags & UNIT_AUTO) == 0) /* autosize? */ - return SCPE_OK; -if (p > (RL01_SIZE * sizeof (int16))) { - uptr->flags = uptr->flags | UNIT_RL02; - uptr->capac = RL02_SIZE; - } -else { - uptr->flags = uptr->flags & ~UNIT_RL02; - uptr->capac = RL01_SIZE; - } -return SCPE_OK; -} - -t_stat rl_detach (UNIT *uptr) -{ -t_stat stat; - -sim_cancel (uptr); -stat = detach_unit (uptr); -uptr->STAT = RLDS_BHO | RLDS_LOAD; -return (stat); -} - -/* Set size routine */ - -t_stat rl_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -if (uptr->flags & UNIT_ATT) - return SCPE_ALATT; -uptr->capac = (val & UNIT_RL02)? RL02_SIZE: RL01_SIZE; -return SCPE_OK; -} - -/* Set bad block routine */ - -t_stat rl_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD); -} - -t_stat rl_set_cover (UNIT *uptr, int32 val, char *cptr, void *desc) -{ - /* allowed only if in LOAD state */ - if ((uptr->STAT & RLDS_M_STATE) != RLDS_LOAD) - return (SCPE_NOFNC); - uptr->STAT = (uptr->STAT & ~RLDS_CVO) | val; - return (SCPE_OK); -} - -t_stat rl_show_cover (FILE *st, UNIT *uptr, int val, void *desc) -{ - fprintf (st, "cover %s", (uptr->STAT & RLDS_CVO) ? "open" : "closed"); - return (SCPE_OK); -} - -/* simulate the LOAD button on the drive */ -t_stat rl_set_load (UNIT *uptr, int32 val, char *cptr, void *desc) -{ - if (val == 0) { /* LOAD */ - if (uptr->STAT & RLDS_CVO) /* cover open? */ - return (SCPE_NOFNC); - /* spin error if no cartridge loaded */ - if (!(uptr->flags & UNIT_ATT)) { - uptr->STAT |= RLDS_SPE; - return (SCPE_NOFNC); - } - /* state load? */ - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOAD; - } else { /* UNLOAD */ - if ((uptr->STAT & RLDS_M_STATE) != RLDS_LOCK) - return (SCPE_OK); - uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_UNL; - } - uptr->FNC = RLCS_SPECIAL; - sim_activate (uptr, 10 * rl_swait); - return (SCPE_OK); -} - -t_stat rl_show_load (FILE *st, UNIT *uptr, int val, void *desc) -{ - fprintf (st, "load %s", - ((uptr->STAT & RLDS_M_STATE) != RLDS_LOAD) ? "set" : "reset"); - return (SCPE_OK); -} - -t_stat rl_show_dstate (FILE *st, UNIT *uptr, int val, void *desc) -{ - int32 cnt; - - fprintf (st, "drive state: %s\n", state[(uptr->STAT & RLDS_M_STATE)]); - fprintf (st, "brushes: %s, heads: %s, cover: %s\n", - (uptr->STAT & RLDS_BHO) ? "home" : "out", - (uptr->STAT & RLDS_HDO) ? "out" : "in", - (uptr->STAT & RLDS_CVO) ? "open" : "closed"); - fprintf (st, "vck:%c, wge:%c, spe:%c\n", - (uptr->STAT & RLDS_VCK) ? '1' : '0', - (uptr->STAT & RLDS_WGE) ? '1' : '0', - (uptr->STAT & RLDS_SPE) ? '1' : '0'); - if (uptr->flags & UNIT_ATT) { - if ((cnt = sim_is_active (uptr)) != 0) - fprintf (st, "FNC: %d, %d\n", uptr->FNC, cnt); - else - fputs ("FNC: none\n", st); - fprintf (st, "TRK: track=%d, cyl=%d, hd=%c, sect=%d\n", - GET_TRACK (uptr->TRK), GET_CYL (uptr->TRK), - (uptr->TRK & RLDA_HD1) ? '1' : '0', - GET_SECT (uptr->TRK)); - } - return (SCPE_OK); -} - -#if defined (VM_PDP11) - -/* Handle SET RL RLV12|RLV11 */ -t_stat rl_set_ctrl (UNIT *uptr, int32 val, char *cptr, void *desc) -{ - if (UNIBUS) - return (SCPE_NOFNC); - if ((val & DEV_RLV11) && (MEMSIZE > UNIMEMSIZE)) - return (SCPE_NOFNC); - rl_dev.flags = (rl_dev.flags & ~(DEV_RLV11|DEV_Q18)) | val; - return (SCPE_OK); -} - -#endif - -/* SHOW RL will display the controller type */ -t_stat rl_show_ctrl (FILE *st, UNIT *uptr, int val, void *desc) -{ - char *s = "RLV12"; - - if (UNIBUS) - s = "RL11"; - else if (rl_dev.flags & DEV_RLV11) - s = "RLV11"; - fputs (s, st); - return (SCPE_OK); -} - -/* Device bootstrap */ - -#if defined (VM_PDP11) - -#define BOOT_START 02000 /* start */ -#define BOOT_ENTRY (BOOT_START + 002) /* entry */ -#define BOOT_UNIT (BOOT_START + 010) /* unit number */ -#define BOOT_CSR (BOOT_START + 020) /* CSR */ -#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16)) - -static const uint16 boot_rom[] = { - 0042114, /* "LD" */ - 0012706, BOOT_START, /* MOV #boot_start, SP */ - 0012700, 0000000, /* MOV #unit, R0 */ - 0010003, /* MOV R0, R3 */ - 0000303, /* SWAB R3 */ - 0012701, 0174400, /* MOV #RLCS, R1 ; csr */ - 0012761, 0000013, 0000004, /* MOV #13, 4(R1) ; clr err */ - 0052703, 0000004, /* BIS #4, R3 ; unit+gstat */ - 0010311, /* MOV R3, (R1) ; issue cmd */ - 0105711, /* TSTB (R1) ; wait */ - 0100376, /* BPL .-2 */ - 0105003, /* CLRB R3 */ - 0052703, 0000010, /* BIS #10, R3 ; unit+rdhdr */ - 0010311, /* MOV R3, (R1) ; issue cmd */ - 0105711, /* TSTB (R1) ; wait */ - 0100376, /* BPL .-2 */ - 0016102, 0000006, /* MOV 6(R1), R2 ; get hdr */ - 0042702, 0000077, /* BIC #77, R2 ; clr sector */ - 0005202, /* INC R2 ; magic bit */ - 0010261, 0000004, /* MOV R2, 4(R1) ; seek to 0 */ - 0105003, /* CLRB R3 */ - 0052703, 0000006, /* BIS #6, R3 ; unit+seek */ - 0010311, /* MOV R3, (R1) ; issue cmd */ - 0105711, /* TSTB (R1) ; wait */ - 0100376, /* BPL .-2 */ - 0005061, 0000002, /* CLR 2(R1) ; clr ba */ - 0005061, 0000004, /* CLR 4(R1) ; clr da */ - 0012761, 0177000, 0000006, /* MOV #-512., 6(R1) ; set wc */ - 0105003, /* CLRB R3 */ - 0052703, 0000014, /* BIS #14, R3 ; unit+read */ - 0010311, /* MOV R3, (R1) ; issue cmd */ - 0105711, /* TSTB (R1) ; wait */ - 0100376, /* BPL .-2 */ - 0042711, 0000377, /* BIC #377, (R1) */ - 0005002, /* CLR R2 */ - 0005003, /* CLR R3 */ - 0012704, BOOT_START+020, /* MOV #START+20, R4 */ - 0005005, /* CLR R5 */ - 0005007 /* CLR PC */ - }; - -t_stat rl_boot (int32 unitno, DEVICE *dptr) -{ -int32 i; -extern uint16 *M; -extern int32 saved_PC; - -for (i = 0; i < BOOT_LEN; i++) - M[(BOOT_START >> 1) + i] = boot_rom[i]; -M[BOOT_UNIT >> 1] = unitno & RLCS_M_DRIVE; -M[BOOT_CSR >> 1] = rl_dib.ba & 0177777; -saved_PC = BOOT_ENTRY; -return SCPE_OK; -} - -#else - -t_stat rl_boot (int32 unitno, DEVICE *dptr) -{ -return SCPE_NOFNC; -} - -#endif +/* pdp11_rl.c: RL11 (RLV12) cartridge disk simulator + + Copyright (c) 1993-2008, Robert M Supnik + + 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 + ROBERT M SUPNIK 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 Robert M Supnik shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from Robert M Supnik. + + rl RL11(RLV12)/RL01/RL02 cartridge disk + + 24-Mar-11 JAD Various changes to support diagnostics, including: + - distinguish between RLV11 & 12 + - more complete drive state + - improved head position tracking + - implement MAINT command of RLV11/12 + - always respect unit disable flag + New commands added: + SHOW RLn DSTATE + SET RLn LOAD/UNLOAD + SET RLn OPEN/CLOSED + SET RLn BRUSH/NOBRUSH + SET RLn ONLINE/OFFLINE + SET RL RLV11/RLV12 (PDP-11 only) + SET RL DEBUG/NODEBUG + 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 16-Aug-05 RMS Fixed C++ declaration and cast problems + 07-Jul-05 RMS Removed extraneous externs + 30-Sep-04 RMS Revised Unibus interface + 04-Jan-04 RMS Changed sim_fsize calling sequence + 19-May-03 RMS Revised for new conditional compilation scheme + 25-Apr-03 RMS Revised for extended file support + 29-Sep-02 RMS Added variable address support to bootstrap + Added vector change/display support + Revised mapping nomenclature + New data structures + 26-Jan-02 RMS Revised bootstrap to conform to M9312 + 06-Jan-02 RMS Revised enable/disable support + 30-Nov-01 RMS Added read only, extended SET/SHOW support + 26-Nov-01 RMS Fixed per-drive error handling + 24-Nov-01 RMS Converted FLG, CAPAC to arrays + 19-Nov-01 RMS Fixed signed/unsigned mismatch in write check + 09-Nov-01 RMS Added bus map, VAX support + 07-Sep-01 RMS Revised device disable and interrupt mechanisms + 20-Aug-01 RMS Added bad block option in attach + 17-Jul-01 RMS Fixed warning from VC++ 6.0 + 26-Apr-01 RMS Added device enable/disable support + 25-Mar-01 RMS Fixed block fill calculation + 15-Feb-01 RMS Corrected bootstrap string + 12-Nov-97 RMS Added bad block table command + 25-Nov-96 RMS Default units to autosize + 29-Jun-96 RMS Added unit disable support + + The RL11 is a four drive cartridge disk subsystem. An RL01 drive + consists of 256 cylinders, each with 2 surfaces containing 40 sectors + of 256 bytes. An RL02 drive has 512 cylinders. The RLV12 is a + controller variant which supports 22b direct addressing. + + The most complicated part of the RL11 controller is the way it does + seeks. Seeking is relative to the current disk address; this requires + keeping accurate track of the current cylinder. The RL11 will not + switch heads or cross cylinders during transfers. + + The RL11 functions in three environments: + + - PDP-11 Q22 systems - the I/O map is one for one, so it's safe to + go through the I/O map + - PDP-11 Unibus 22b systems - the RL11 behaves as an 18b Unibus + peripheral and must go through the I/O map + - VAX Q22 systems - the RL11 must go through the I/O map +*/ + +#if defined (VM_PDP10) /* PDP10 version */ +#error "RL11 is not supported on the PDP-10!" + +#elif defined (VM_VAX) /* VAX version */ +#include "vax_defs.h" + +#else /* PDP-11 version */ +#include "pdp11_defs.h" +extern uint32 cpu_opt; +extern UNIT cpu_unit; +#endif + +/* Constants */ + +#define RL_NUMWD (128) /* words/sector */ +#define RL_NUMSC (40) /* sectors/surface */ +#define RL_NUMSF (2) /* surfaces/cylinder */ +#define RL_NUMCY (256) /* cylinders/drive */ +#define RL_NUMDR (4) /* drives/controller */ +#define RL_MAXFR (RL_NUMSC * RL_NUMWD) /* max transfer */ +#define RL01_SIZE (RL_NUMCY * RL_NUMSF * RL_NUMSC * RL_NUMWD) /* words/drive */ +#define RL02_SIZE (RL01_SIZE * 2) /* words/drive */ + +/* Device flags */ + +#define DEV_V_RLV11 (DEV_V_UF + 7) /* RLV11 */ +#define DEV_RLV11 (1u << DEV_V_RLV11) + +/* Flags in the unit flags word */ + +#define UNIT_V_WLK (UNIT_V_UF + 0) /* hwre write lock */ +#define UNIT_V_RL02 (UNIT_V_UF + 1) /* RL01 vs RL02 */ +#define UNIT_V_AUTO (UNIT_V_UF + 2) /* autosize enable */ +#define UNIT_V_DUMMY (UNIT_V_UF + 3) /* dummy flag, for SET BADBLOCK */ +#define UNIT_V_OFFL (UNIT_V_UF + 4) /* unit off line */ +#define UNIT_V_BRUSH (UNIT_V_UF + 5) /* unit has brushes */ +#define UNIT_BRUSH (1u << UNIT_V_BRUSH) +#define UNIT_OFFL (1u << UNIT_V_OFFL) +#define UNIT_DUMMY (1u << UNIT_V_DUMMY) +#define UNIT_WLK (1u << UNIT_V_WLK) +#define UNIT_RL02 (1u << UNIT_V_RL02) +#define UNIT_AUTO (1u << UNIT_V_AUTO) +#define UNIT_WPRT (UNIT_WLK | UNIT_RO) /* write protected */ + +/* Parameters in the unit descriptor */ + +#define TRK u3 /* current track:head:sector */ +#define STAT u4 /* status */ +#define FNC u5 /* function */ + +/* RLDS, NI = not implemented, * = kept in STAT, ^ = kept in TRK , ! = kept in uptr */ + +#define RLDS_M_STATE (07) +#define RLDS_LOAD (0) /* no cartridge */ +#define RLDS_SPIN (1) /* spin-up */ +#define RLDS_BRUSH (2) /* brush cycle *! */ +#define RLDS_HLOAD (3) /* load heads */ +#define RLDS_SEEK (4) /* drive seeking * */ +#define RLDS_LOCK (5) /* lock on * */ +#define RLDS_UNL (6) /* unload heads */ +#define RLDS_DOWN (7) /* spin-down */ +#define RLDS_BHO (0000010) /* brushes home * */ +#define RLDS_HDO (0000020) /* heads out * */ +#define RLDS_CVO (0000040) /* cover open * */ +#define RLDS_HD (0000100) /* head select ^ */ +#define RLDS_RL02 (0000200) /* RL02 ! */ +#define RLDS_DSE (0000400) /* drv sel err */ +#define RLDS_VCK (0001000) /* vol check * */ +#define RLDS_WGE (0002000) /* wr gate err * */ +#define RLDS_SPE (0004000) /* spin err * */ +#define RLDS_STO (0010000) /* seek time out * */ +#define RLDS_WLK (0020000) /* wr locked ! */ +#define RLDS_HCE (0040000) /* hd curr err NI */ +#define RLDS_WDE (0100000) /* wr data err NI */ +#define RLDS_ERR (RLDS_WDE|RLDS_HCE|RLDS_STO|RLDS_SPE|RLDS_WGE| \ + RLDS_VCK|RLDS_DSE) /* errors bits */ + +/* RLCS */ + +#define RLCS_DRDY (0000001) /* drive ready */ +#define RLCS_M_FUNC (0000007) /* function */ +#define RLCS_NOP (0) +#define RLCS_WCHK (1) +#define RLCS_GSTA (2) +#define RLCS_SEEK (3) +#define RLCS_RHDR (4) +#define RLCS_WRITE (5) +#define RLCS_READ (6) +#define RLCS_RNOHDR (7) +#define RLCS_SPECIAL (8) /* internal function, drive state */ +#define RLCS_V_FUNC (1) +#define RLCS_M_MEX (03) /* memory extension */ +#define RLCS_V_MEX (4) +#define RLCS_MEX (RLCS_M_MEX << RLCS_V_MEX) +#define RLCS_M_DRIVE (03) +#define RLCS_V_DRIVE (8) +#define RLCS_INCMP (0002000) /* incomplete */ +#define RLCS_CRC (0004000) /* CRC error */ +#define RLCS_HCRC (RLCS_CRC|RLCS_INCMP) /* header CRC error */ +#define RLCS_DLT (0010000) /* data late */ +#define RLCS_HDE (RLCS_DLT|RLCS_INCMP) /* header not found error */ +#define RLCS_NXM (0020000) /* non-exist memory */ +#define RLCS_PAR (RLCS_NXM|RLCS_INCMP) /* parity error */ +#define RLCS_DRE (0040000) /* drive error */ +#define RLCS_ERR (0100000) /* error summary */ +#define RLCS_ALLERR (RLCS_ERR|RLCS_DRE|RLCS_NXM|RLCS_HDE|RLCS_CRC|RLCS_INCMP) +#define RLCS_RW (0001776) /* read/write */ +#define GET_FUNC(x) (((x) >> RLCS_V_FUNC) & RLCS_M_FUNC) +#define GET_DRIVE(x) (((x) >> RLCS_V_DRIVE) & RLCS_M_DRIVE) + +/* RLDA */ + +#define RLDA_GS (0000002) /* get status */ +#define RLDA_SK_DIR (0000004) /* direction */ +#define RLDA_GS_CLR (0000010) /* clear errors */ +#define RLDA_SK_HD (0000020) /* head select */ + +#define RLDA_V_SECT (0) /* sector */ +#define RLDA_M_SECT (077) +#define RLDA_V_TRACK (6) /* track */ +#define RLDA_M_TRACK (01777) +#define RLDA_HD0 (0 << RLDA_V_TRACK) +#define RLDA_HD1 (1u << RLDA_V_TRACK) +#define RLDA_V_CYL (7) /* cylinder */ +#define RLDA_M_CYL (0777) +#define RLDA_TRACK (RLDA_M_TRACK << RLDA_V_TRACK) +#define RLDA_CYL (RLDA_M_CYL << RLDA_V_CYL) +#define GET_SECT(x) (((x) >> RLDA_V_SECT) & RLDA_M_SECT) +#define GET_CYL(x) (((x) >> RLDA_V_CYL) & RLDA_M_CYL) +#define GET_TRACK(x) (((x) >> RLDA_V_TRACK) & RLDA_M_TRACK) +#define GET_DA(x) ((GET_TRACK (x) * RL_NUMSC) + GET_SECT (x)) + +/* RLBA */ + +#define RLBA_IMP (0177777) /* implemented */ + +/* RLBAE */ + +#define RLBAE_IMP (0000077) /* implemented */ + +extern int32 int_req[IPL_HLVL]; +extern FILE *sim_deb; + +uint16 *rlxb = NULL; /* xfer buffer */ +int32 rlcs = 0; /* control/status */ +int32 rlba = 0; /* memory address */ +int32 rlbae = 0; /* mem addr extension */ +int32 rlda = 0; /* disk addr */ +int32 rlmp = 0, rlmp1 = 0, rlmp2 = 0; /* mp register queue */ +int32 rl_swait = 10; /* seek wait */ +int32 rl_rwait = 10; /* rotate wait */ +int32 rl_stopioe = 1; /* stop on error */ + +/* forward references */ +DEVICE rl_dev; +t_stat rl_rd (int32 *data, int32 PA, int32 access); +t_stat rl_wr (int32 data, int32 PA, int32 access); +t_stat rl_svc (UNIT *uptr); +t_stat rl_reset (DEVICE *dptr); +void rl_set_done (int32 error); +t_stat rl_boot (int32 unitno, DEVICE *dptr); +t_stat rl_attach (UNIT *uptr, char *cptr); +t_stat rl_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); +t_stat rl_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc); +static void rlv_maint (void); +t_stat rl_detach (UNIT *uptr); +t_stat rl_set_cover (UNIT *, int32, char *, void *); +t_stat rl_show_cover (FILE *, UNIT *, int32, void *); +t_stat rl_set_load (UNIT *, int32, char *, void *); +t_stat rl_show_load (FILE *, UNIT *, int32, void *); +t_stat rl_show_dstate (FILE *, UNIT *, int32, void *); +#if defined (VM_PDP11) +t_stat rl_set_ctrl (UNIT *uptr, int32 val, char *cptr, void *desc); +#endif +t_stat rl_show_ctrl (FILE *st, UNIT *uptr, int32 val, void *desc); + +/* RL11 data structures + + rl_dev RL device descriptor + rl_unit RL unit list + rl_reg RL register list + rl_mod RL modifier list +*/ + +static DIB rl_dib = { + IOBA_RL, IOLN_RL, &rl_rd, &rl_wr, + 1, IVCL (RL), VEC_RL, { NULL } }; + +static UNIT rl_unit[] = { + { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ + UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) }, + { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ + UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) }, + { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ + UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) }, + { UDATA (&rl_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+ + UNIT_ROABLE+UNIT_AUTO, RL01_SIZE) } + }; + +static const REG rl_reg[] = { + { GRDATA (RLCS, rlcs, DEV_RDX, 16, 0) }, + { GRDATA (RLDA, rlda, DEV_RDX, 16, 0) }, + { GRDATA (RLBA, rlba, DEV_RDX, 16, 0) }, + { GRDATA (RLBAE, rlbae, DEV_RDX, 6, 0) }, + { GRDATA (RLMP, rlmp, DEV_RDX, 16, 0) }, + { GRDATA (RLMP1, rlmp1, DEV_RDX, 16, 0) }, + { GRDATA (RLMP2, rlmp2, DEV_RDX, 16, 0) }, + { FLDATA (INT, IREQ (RL), INT_V_RL) }, + { FLDATA (ERR, rlcs, CSR_V_ERR) }, + { FLDATA (DONE, rlcs, CSR_V_DONE) }, + { FLDATA (IE, rlcs, CSR_V_IE) }, + { DRDATA (STIME, rl_swait, 24), PV_LEFT }, + { DRDATA (RTIME, rl_rwait, 24), PV_LEFT }, + { URDATA (CAPAC, rl_unit[0].capac, 10, T_ADDR_W, 0, + RL_NUMDR, PV_LEFT + REG_HRO) }, + { FLDATA (STOP_IOE, rl_stopioe, 0) }, + { GRDATA (DEVADDR, rl_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, rl_dib.vec, DEV_RDX, 16, 0), REG_HRO }, + { NULL } + }; + +static const MTAB rl_mod[] = { +#if defined (VM_PDP11) + { MTAB_XTD|MTAB_VDV, (DEV_RLV11|DEV_Q18), "", "RLV11", &rl_set_ctrl, &rl_show_ctrl, NULL}, + { MTAB_XTD|MTAB_VDV, 0, NULL, "RLV12", &rl_set_ctrl, NULL, NULL}, +#endif + { UNIT_OFFL, 0, "on line", "ONLINE", NULL, NULL }, + { UNIT_OFFL, UNIT_OFFL, "off line", "OFFLINE", NULL, NULL }, + { UNIT_BRUSH, 0, NULL, "NOBRUSH", NULL, NULL }, + { UNIT_BRUSH, UNIT_BRUSH, "has brushes", "BRUSH", NULL, NULL }, + + { MTAB_XTD|MTAB_VUN|MTAB_NMO, RLDS_CVO, "open", "OPEN", &rl_set_cover, &rl_show_cover, NULL }, + { MTAB_XTD|MTAB_VUN, 0, NULL, "CLOSED", &rl_set_cover, NULL, NULL }, + { MTAB_XTD|MTAB_VUN|MTAB_NMO, 0, "load", "LOAD", &rl_set_load, &rl_show_load, NULL }, + { MTAB_XTD|MTAB_VUN, 1, NULL, "UNLOAD", &rl_set_load, NULL, NULL }, + { MTAB_XTD|MTAB_VUN|MTAB_NMO, 0, "DSTATE", NULL, NULL, &rl_show_dstate, NULL }, + + { UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL }, + { UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL }, + { UNIT_DUMMY, 0, NULL, "BADBLOCK", &rl_set_bad }, + { (UNIT_RL02+UNIT_ATT), UNIT_ATT, "RL01", NULL, NULL }, + { (UNIT_RL02+UNIT_ATT), (UNIT_RL02+UNIT_ATT), "RL02", NULL, NULL }, + { (UNIT_AUTO+UNIT_RL02+UNIT_ATT), 0, "RL01", NULL, NULL }, + { (UNIT_AUTO+UNIT_RL02+UNIT_ATT), UNIT_RL02, "RL02", NULL, NULL }, + { (UNIT_AUTO+UNIT_ATT), UNIT_AUTO, "autosize", NULL, NULL }, + { UNIT_AUTO, UNIT_AUTO, NULL, "AUTOSIZE", NULL }, + { (UNIT_AUTO+UNIT_RL02), 0, NULL, "RL01", &rl_set_size }, + { (UNIT_AUTO+UNIT_RL02), UNIT_RL02, NULL, "RL02", &rl_set_size }, + { MTAB_XTD|MTAB_VDV, 010, "ADDRESS", "ADDRESS", + &set_addr, &show_addr, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR", + &set_vec, &show_vec, NULL }, + { 0 } + }; + +DEVICE rl_dev = { + "RL", (UNIT *) &rl_unit, (REG *) rl_reg, (MTAB *) rl_mod, + RL_NUMDR, DEV_RDX, 24, 1, DEV_RDX, 16, + NULL, NULL, &rl_reset, + &rl_boot, &rl_attach, &rl_detach, + &rl_dib, DEV_DISABLE | DEV_UBUS | DEV_QBUS | DEV_DEBUG + }; + +/* Drive states */ +static const char * const state[] = { + "Load Cartridge", "Spin Up", "Brush", "Load Heads", + "Seek", "Lock On", "Unload Heads", "Spin Down" +}; + +/* I/O dispatch routines, I/O addresses 17774400 - 17774411 + + 17774400 RLCS read/write + 17774402 RLBA read/write + 17774404 RLDA read/write + 17774406 RLMP read/write + 17774410 RLBAE read/write +*/ + +t_stat rl_rd (int32 *data, int32 PA, int32 access) +{ +UNIT *uptr; + +switch ((PA >> 1) & 07) { /* decode PA<2:1> */ + + case 0: /* RLCS */ + rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); +/* +The DRDY signal is sent by the selected drive to indicate that it +is ready to read or write or seek. It is sent when the heads are +not moving and are locked onto a cylinder. This is continuously +monitored by the drive and controller. [EK-0RL11-TD-001, p. 3-8] +Use the DS bits to determine if the drive has any outstanding I/O +operations and set DRDY as appropriate. + +This seems to imply that only a Seek operation (not Read/Write) +causes ready to be false. +*/ + uptr = rl_dev.units + GET_DRIVE (rlcs); + if ((uptr->flags & UNIT_OFFL) || (uptr->STAT & RLDS_VCK)) { + rlcs |= RLCS_DRE; + rlcs &= ~RLCS_DRDY; + } else if (sim_is_active (uptr) || (uptr->flags & UNIT_DIS) || + ((uptr->STAT & RLDS_M_STATE) != RLDS_LOCK)) + rlcs &= ~RLCS_DRDY; + else + rlcs |= RLCS_DRDY; /* see if ready */ +/* +Make sure the error summary bit properly reflects the sum of other +errors. +*/ + if (rlcs & RLCS_ALLERR) + rlcs |= RLCS_ERR; + *data = rlcs; + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL rd: RLCS %06o\n", rlcs); + break; + + case 1: /* RLBA */ + *data = rlba & RLBA_IMP; + break; + + case 2: /* RLDA */ + *data = rlda; + break; + + case 3: /* RLMP */ + *data = rlmp; + rlmp = rlmp1; /* ripple data */ + rlmp1 = rlmp2; + break; + + case 4: /* RLBAE */ + if (UNIBUS || (rl_dev.flags & DEV_RLV11)) /* not in RL11/RLV11 */ + return SCPE_NXM; + *data = rlbae & RLBAE_IMP; + break; + + default: + return (SCPE_NXM); + } /* end switch */ + +return SCPE_OK; +} + +t_stat rl_wr (int32 data, int32 PA, int32 access) +{ +int32 curr, offs, newc, maxc, tim; +UNIT *uptr; + +switch ((PA >> 1) & 07) { /* decode PA<2:1> */ + + case 0: /* RLCS */ + rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); + uptr = rl_dev.units + GET_DRIVE (data); /* get new drive */ + if (access == WRITEB) + data = (PA & 1)? (rlcs & 0377) | (data << 8): (rlcs & ~0377) | data; + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL wr: RLCS %06o new %06o\n", rlcs, data); + rlcs = (rlcs & ~RLCS_RW) | (data & RLCS_RW); + rlbae = (rlbae & ~RLCS_M_MEX) | ((rlcs >> RLCS_V_MEX) & RLCS_M_MEX); +/* +Commands to the controller are only executed with the CRDY (DONE) +bit is cleared by software. If set, check for interrupts and return. +*/ + if (data & CSR_DONE) { /* ready set? */ + if ((data & CSR_IE) == 0) + CLR_INT (RL); + else if ((rlcs & (CSR_DONE + CSR_IE)) == CSR_DONE) + SET_INT (RL); + return SCPE_OK; + } + + CLR_INT (RL); /* clear interrupt */ + rlcs &= ~RLCS_ALLERR; /* clear errors */ + switch (GET_FUNC (rlcs)) { /* case on RLCS<3:1> */ + case RLCS_NOP: /* nop */ + if (!UNIBUS) /* RLV1x has MAINT command */ + rlv_maint (); + rl_set_done (0); + break; + case RLCS_SEEK: /* seek */ + if ((uptr->flags & (UNIT_DIS|UNIT_OFFL)) || (!(uptr->flags & UNIT_ATT))) { + rl_set_done (RLCS_ERR | RLCS_INCMP); + uptr->STAT |= RLDS_STO; + break; + } + curr = GET_CYL (uptr->TRK); /* current cylinder */ + offs = GET_CYL (rlda); /* offset */ + if (rlda & RLDA_SK_DIR) { /* in or out? */ + newc = curr + offs; /* out */ + maxc = (uptr->flags & UNIT_RL02)? + RL_NUMCY * 2: RL_NUMCY; + if (newc >= maxc) + newc = maxc - 1; + } else { + newc = curr - offs; /* in */ + if (newc < 0) + newc = 0; + } + /* enter velocity mode? only if a different cylinder */ + if (newc != curr) + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_SEEK; /* move the positioner */ +/* TBD: if a head switch, sector should be RL_NUMSC/2? */ + uptr->TRK = (newc << RLDA_V_CYL) | /* put on track */ + ((rlda & RLDA_SK_HD)? RLDA_HD1: RLDA_HD0); +/* +Real timing: +min 6.5ms, max 15ms for head switch, +max 17ms for 1 track seek w/head switch +55ms avg seek +100ms max seek +*/ + tim = abs (newc - curr); + if (tim == 0) + tim++; + tim *= rl_swait; + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL SEEK: drv %d, dist %d, head sw %d, tim %d\n", + (int32) (uptr - rl_dev.units), + abs (newc - curr), (rlda & RLDA_SK_HD), tim); + uptr->FNC = RLCS_SEEK; + sim_activate (uptr, tim); /* must be > 0 */ + rl_set_done (0); /* ctrlr is ready */ + break; + case RLCS_GSTA: + if (!(rlda & RLDA_GS)) { /* GS bit must be set */ + rl_set_done (RLCS_ERR | RLCS_INCMP); /* OPI; request error */ + return (SCPE_OK); + } + if (rlda & RLDA_GS_CLR) /* reset errors? */ + uptr->STAT &= ~RLDS_ERR; + /* develop drive state */ + rlmp = uptr->STAT | (uptr->TRK & RLDS_HD); + if (uptr->flags & UNIT_RL02) + rlmp |= RLDS_RL02; + if (uptr->flags & UNIT_WPRT) + rlmp |= RLDS_WLK; + if (uptr->flags & (UNIT_DIS | UNIT_OFFL)) { + rlmp |= RLDS_DSE; + rl_set_done (RLCS_DRE | RLCS_INCMP); + } + rlmp2 = rlmp1 = rlmp; + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL GSTA: rlds=%06o drv=%ld\n", + rlmp, (long)(uptr - rl_dev.units)); + rl_set_done (0); /* done */ + break; + default: /* data transfer */ + if ((uptr->flags & (UNIT_DIS|UNIT_OFFL)) || (!(uptr->flags & UNIT_ATT))) { + rl_set_done (RLCS_INCMP); + break; + } +/* +EK-0RL11-TD-001, p2-3: "If the CPU software initiates another +operation on a drive that is busy seeking, the controller will +suspend the operation until the seek is completed." + +Check for the condition where there is an outstanding operation but +the program is requesting another operation without waiting for +drive ready. If so, remove the previous queue entry, complete the +operation now, and queue the next operation. +*/ + if (sim_is_active (uptr)) { + sim_cancel (uptr); + rl_svc (uptr); + } + uptr->FNC = GET_FUNC (rlcs); + sim_activate (uptr, rl_swait); /* activate unit */ + break; + } /* end switch func */ + break; /* end case RLCS */ +/* +Contrary to what the RL01/RL02 User Guide (EK-RL012-UG-006, p.4-5) +says, bit 0 can be written and read (as 1) on an RLV12 (verified +2011-01-05). Not sure about the RLV11. +*/ + case 1: /* RLBA */ + if (access == WRITEB) + data = (PA & 1)? (rlba & 0377) | (data << 8): (rlba & ~0377) | data; + rlba = data & (UNIBUS ? 0177776 : 0177777); + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL wr: RLBA %06o\n", rlba); + break; + + case 2: /* RLDA */ + if (access == WRITEB) + data = (PA & 1)? (rlda & 0377) | (data << 8): (rlda & ~0377) | data; + rlda = data; + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL wr: RLDA %06o\n", rlda); + break; + + case 3: /* RLMP */ + if (access == WRITEB) + data = (PA & 1)? (rlmp & 0377) | (data << 8): (rlmp & ~0377) | data; + rlmp = rlmp1 = rlmp2 = data; + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL wr: RLMP %06o\n", rlmp); + break; + + case 4: /* RLBAE */ + if (UNIBUS || (rl_dev.flags & DEV_RLV11)) /* not in RL11/RLV11 */ + return SCPE_NXM; + if (PA & 1) + return SCPE_OK; + rlbae = data & RLBAE_IMP; + rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL wr: RLBAE %06o\n", rlbae); + break; + default: + return (SCPE_NXM); + } /* end switch */ + +return SCPE_OK; +} + +/* CRC16 as implemented by the DEC 9401 chip */ +static uint32 calcCRC (const int wc, const uint16 *data) +{ + uint32 crc, j, d; + int32 i; + + crc = 0; + for (i = 0; i < wc; i++) { + d = *data++; + /* cribbed from KG11-A */ + for (j = 0; j < 16; j++) { + crc = (crc & ~01) | ((crc & 01) ^ (d & 01)); + crc = (crc & 01) ? (crc >> 1) ^ 0120001 : crc >> 1; + d >>= 1; + } + } + return (crc); +} + +/* +Perform the maintenance function of the RLV1x; this is fully described +on pages 4-14 and 4-15 of EK-RL012-UG-006. Note that the description +of this in EK-RLV12-UG-002 (p.5-3) contains a typo, the constant +for -511 is incorrect. +*/ +static void rlv_maint (void) +{ + int32 i; + uint32 ma; + uint16 w; + + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL maint: RLDA %06o\n", rlda); + /* 1: check internal logic */ + rlda = (rlda & ~0377) | ((rlda + 1) & 0377); + + /* 2: check internal logic */ + rlda = (rlda & ~0377) | ((rlda + 1) & 0377); + + /* 3: check DMA transfers */ + ma = (rlbae << 16) | rlba; /* get mem addr */ + /* xfer 256 words to FIFO */ + if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL maint: RLMP %06o\n", rlmp); + if (rlmp != 0177001) { /* must be exactly -511 */ + rlcs |= RLCS_ERR | RLCS_HDE; /* HNF error */ + return; + } + for (i = 0; i < 256; i++) { + if (Map_ReadW (ma, 2, &rlxb[i])) { /* mem wd */ + rlcs |= RLCS_ERR | RLCS_NXM; /* nxm */ + break; + } + ma += 2; + rlmp++; + } + /* xfer 255 words from FIFO */ + for (i = 0; i < 255; i++) { + if (Map_WriteW (ma, 2, &rlxb[i])) { /* store buffer */ + rlcs |= RLCS_ERR | RLCS_NXM; /* nxm */ + break; + } + ma += 2; + rlmp++; + } + rlda = (rlda & ~0377) | ((rlda + 1) & 0377); + rlbae = (ma >> 16) & RLBAE_IMP; /* upper 6b */ + rlba = ma & RLBA_IMP; /* lower 16b */ + + /* 4: check the CRC of (DAR + 3) */ + w = rlda; + rlxb[0] = calcCRC (1, &w); /* calculate CRC */ + rlda = (rlda & ~0377) | ((rlda + 1) & 0377); + + /* 5: check the CRC of (DAR + 4) */ + w = rlda; + rlxb[1] = calcCRC (1, &w); /* calculate CRC */ + rlda = (rlda & ~0377) | ((rlda + 1) & 0377); + + /* 6: check the CRC of (CRC of DAR + 4) */ + w = rlxb[1]; + rlxb[1] = calcCRC (1, &w); /* calculate CRC */ + rlmp = rlxb[0]; + rlmp1 = rlxb[1]; + rlda = (rlda & ~0377) | ((rlda + 1) & 0377); +} + +/* Service unit timeout + + If seek in progress, complete seek command + Else complete data transfer command + + The unit control block contains the function and cylinder for + the current command. +*/ + +t_stat rl_svc (UNIT *uptr) +{ +int32 err, wc, maxwc, t; +int32 i, da, awc; +uint32 ma; +uint16 comp; +static const char * const funcname[] = { + "NOP", "WCK", "GSTA", "SEEK", + "RHDR", "WT", "RD", "RNOHDR", "SPECIAL", +}; + +if (DEBUG_PRS (rl_dev)) { + if (uptr->FNC == RLCS_SPECIAL) + fprintf (sim_deb, ">>RL svc: func=SPECIAL(%s) drv=%d\n", + state[uptr->STAT & RLDS_M_STATE], (int32) (uptr - rl_dev.units)); + else + fprintf (sim_deb, ">>RL svc: func=%s drv=%d rlda=%06o\n", + funcname[uptr->FNC], (int32) (uptr - rl_dev.units), rlda); +} + +/* really shouldn't happen... */ +if ((uptr->FNC == RLCS_GSTA) || (uptr->FNC == RLCS_NOP)) { + rl_set_done (0); + return (SCPE_OK); + } + +/* +This situation occurs when the drive (not controller) state needs +to transition from one state to another. The state bits indicate +the state the drive is currently in. +*/ + +if (uptr->FNC == RLCS_SPECIAL) { + switch (uptr->STAT & RLDS_M_STATE) { +/* +The LOAD state is a little different. We can stay in LOAD until +the user hits the RUN (LOAD) button, at which time we should come +here to transition to the next state and begin the startup process. +*/ + case RLDS_LOAD: + /* load pressed, spinning up */ + if (!(uptr->STAT & RLDS_CVO)) { + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_SPIN; + /* actual time is 45-50 seconds from press to Lock */ + sim_activate (uptr, 200 * rl_swait); + uptr->STAT &= ~RLDS_HDO; + uptr->STAT |= RLDS_BHO; + } + break; +/* +Original RL01 drives would transition to the Brush Cycle, but this +was removed in a later ECO. +*/ + case RLDS_SPIN: /* spun up, load brushes or heads */ + if (uptr->flags & UNIT_BRUSH) { + uptr->STAT &= ~RLDS_BHO; + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_BRUSH; + } else { + uptr->STAT |= RLDS_BHO; + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_HLOAD; + } + sim_activate (uptr, 200 * rl_swait); + break; + case RLDS_BRUSH: + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_HLOAD; + uptr->STAT |= RLDS_BHO; + sim_activate (uptr, 200 * rl_swait); + break; + case RLDS_HLOAD: /* heads loaded, seek to home */ + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_SEEK; + sim_activate (uptr, 200 * rl_swait); + uptr->STAT |= RLDS_BHO | RLDS_HDO; + uptr->TRK = 0; + break; + case RLDS_SEEK: /* home found, lock on */ + /* enter postion mode */ + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOCK; + /* sim_activate (uptr, rl_swait); */ + break; + case RLDS_LOCK: /* tracking, nothing to do */ + /* illuminate ready lamp */ + break; +/* +Initiated by depressing the Run (LOAD) switch. +*/ + case RLDS_UNL: /* unload pressed, heads unloaded, spin down */ + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_DOWN; + uptr->STAT &= ~RLDS_HDO; /* retract heads */ + /* actual time is ~30 seconds */ + sim_activate (uptr, 200 * rl_swait); + break; + case RLDS_DOWN: /* OK to open cover */ + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOAD; + uptr->STAT |= RLDS_BHO | RLDS_VCK; + break; + default: + ; /* can't happen */ + } + return (SCPE_OK); +} + +if ((uptr->flags & UNIT_ATT) == 0) { /* attached? */ + uptr->STAT |= RLDS_SPE; /* spin error */ + rl_set_done (RLCS_ERR | RLCS_INCMP); /* flag error */ + return IORETURN (rl_stopioe, SCPE_UNATT); + } + +if ((uptr->FNC == RLCS_WRITE) && (uptr->flags & UNIT_WPRT)) { + uptr->STAT |= RLDS_WGE; /* write and locked */ + rl_set_done (RLCS_ERR | RLCS_DRE); + return SCPE_OK; + } + +if (uptr->FNC == RLCS_SEEK) { /* seek? */ + /* enter position mode */ + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOCK; /* heads locked on cyl */ + return (SCPE_OK); + } + +if (uptr->FNC == RLCS_RHDR) { /* read header? */ + uint16 hdr[2]; + hdr[0] = rlmp = uptr->TRK & 0177777; + hdr[1] = rlmp1 = 0; + rlmp2 = calcCRC (2, &hdr[0]); /* calculate header CRC */ + rl_set_done (0); /* done */ + /* simulate sequential rotation about the current track */ + uptr->TRK = (uptr->TRK & ~RLDA_M_SECT) | + ((uptr->TRK + 1) & RLDA_M_SECT); + if (GET_SECT (uptr->TRK) >= RL_NUMSC) /* end of track? */ + uptr->TRK &= ~RLDA_M_SECT; /* wrap to 0 */ + return (SCPE_OK); + } + +if (uptr->FNC == RLCS_RNOHDR) { + if (GET_SECT (uptr->TRK) >= RL_NUMSC) { + rl_set_done (RLCS_ERR | RLCS_HDE); /* wrong cylinder? */ + return (SCPE_OK); + } + da = GET_DA (uptr->TRK) * RL_NUMWD; /* get disk addr */ + maxwc = (RL_NUMSC - GET_SECT (uptr->TRK)) * RL_NUMWD; /* max transfer */ +} else { + /* bad cyl or sector? */ + if (((uptr->TRK & RLDA_CYL) != (rlda & RLDA_CYL)) || (GET_SECT (rlda) >= RL_NUMSC)) { + rl_set_done (RLCS_ERR | RLCS_HDE | RLCS_INCMP); /* wrong cylinder? */ + return (SCPE_OK); + } + da = GET_DA (rlda) * RL_NUMWD; /* get disk addr */ + maxwc = (RL_NUMSC - GET_SECT (rlda)) * RL_NUMWD; /* max transfer */ +} + +ma = (rlbae << 16) | rlba; /* get mem addr */ +wc = 0200000 - rlmp; /* get true wc */ + +if (wc > maxwc) /* track overrun? */ + wc = maxwc; +err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET); + +if (DEBUG_PRS (rl_dev)) + fprintf (sim_deb, ">>RL svc: cyl %d, sect %d, wc %d, maxwc %d, err %d\n", + GET_CYL (rlda), GET_SECT (rlda), wc, maxwc, err); + + if ((uptr->FNC >= RLCS_READ) && (err == 0)) { /* read (no hdr)? */ + i = fxread (rlxb, sizeof (int16), wc, uptr->fileref); + err = ferror (uptr->fileref); + for ( ; i < wc; i++) /* fill buffer */ + rlxb[i] = 0; + if ((t = Map_WriteW (ma, wc << 1, rlxb))) { /* store buffer */ + rlcs = rlcs | RLCS_ERR | RLCS_NXM; /* nxm */ + wc = wc - t; /* adjust wc */ + } + } /* end read */ + +else +if ((uptr->FNC == RLCS_WRITE) && (err == 0)) { /* write? */ + if ((t = Map_ReadW (ma, wc << 1, rlxb))) { /* fetch buffer */ + rlcs = rlcs | RLCS_ERR | RLCS_NXM; /* nxm */ + wc = wc - t; /* adj xfer lnt */ + } + if (wc) { /* any xfer? */ + awc = (wc + (RL_NUMWD - 1)) & ~(RL_NUMWD - 1); /* clr to */ + for (i = wc; i < awc; i++) /* end of blk */ + rlxb[i] = 0; + fxwrite (rlxb, sizeof (int16), awc, uptr->fileref); + err = ferror (uptr->fileref); + } + } /* end write */ + +else +if ((uptr->FNC == RLCS_WCHK) && (err == 0)) { /* write check? */ + i = fxread (rlxb, sizeof (int16), wc, uptr->fileref); + err = ferror (uptr->fileref); + for ( ; i < wc; i++) /* fill buffer */ + rlxb[i] = 0; + awc = wc; /* save wc */ + for (wc = 0; (err == 0) && (wc < awc); wc++) { /* loop thru buf */ + if (Map_ReadW (ma + (wc << 1), 2, &comp)) { /* mem wd */ + rlcs = rlcs | RLCS_ERR | RLCS_NXM; /* nxm */ + break; + } + if (comp != rlxb[wc]) /* check to buf */ + rlcs = rlcs | RLCS_ERR | RLCS_CRC; + } /* end for */ + } /* end wcheck */ + +/* Complete Write Check, Write, Read, Read no header */ +rlmp = (rlmp + wc) & 0177777; /* final word count */ +if (rlmp != 0) /* completed? */ + rlcs |= RLCS_ERR | RLCS_INCMP | RLCS_HDE; + +ma += (wc << 1); /* final byte addr */ +rlbae = (ma >> 16) & RLBAE_IMP; /* upper 6b */ +rlba = ma & RLBA_IMP; /* lower 16b */ +rlcs = (rlcs & ~RLCS_MEX) | ((rlbae & RLCS_M_MEX) << RLCS_V_MEX); + +/* +If we ran off the end of the track, return 40 in rlda, but keep +track over a legitimate sector (0)? +*/ +rlda += ((wc + (RL_NUMWD - 1)) / RL_NUMWD); +/* update head pos */ +if (uptr->FNC == RLCS_RNOHDR) + uptr->TRK = (uptr->TRK & ~RLDA_M_SECT) | + ((uptr->TRK + ((wc + (RL_NUMWD - 1)) / RL_NUMWD)) & RLDA_M_SECT); +else + uptr->TRK = rlda; +if (GET_SECT (uptr->TRK) >= RL_NUMSC) + uptr->TRK &= ~RLDA_M_SECT; /* wrap to 0 */ + +rl_set_done (0); + +if (err != 0) { /* error? */ + perror ("RL I/O error"); + clearerr (uptr->fileref); + return SCPE_IOERR; + } +return SCPE_OK; +} + +/* Set done and possibly errors */ + +void rl_set_done (int32 status) +{ +rlcs |= status | CSR_DONE; /* set done */ +if (rlcs & CSR_IE) + SET_INT (RL); +else CLR_INT (RL); +} + +/* Device reset + + Note that the RL11 does NOT recalibrate its drives on RESET +*/ + +t_stat rl_reset (DEVICE *dptr) +{ +int32 i; +UNIT *uptr; + +rlcs = CSR_DONE; +rlda = rlba = rlbae = rlmp = rlmp1 = rlmp2 = 0; +CLR_INT (RL); +for (i = 0; i < RL_NUMDR; i++) { + uptr = rl_dev.units + i; + sim_cancel (uptr); + uptr->STAT &= ~RLDS_ERR; + } +if (rlxb == NULL) + rlxb = (uint16 *) calloc (RL_MAXFR, sizeof (uint16)); +if (rlxb == NULL) + return SCPE_MEM; +return SCPE_OK; +} + +/* Attach routine */ + +t_stat rl_attach (UNIT *uptr, char *cptr) +{ +uint32 p; +t_stat r; + +uptr->capac = (uptr->flags & UNIT_RL02)? RL02_SIZE: RL01_SIZE; +r = attach_unit (uptr, cptr); /* attach unit */ +if (r != SCPE_OK) /* error? */ + return r; +/* +For compatibility with existing SIMH behavior, set the drive state +as if the load procedure had already executed. +*/ +uptr->TRK = 0; /* cylinder 0 */ +uptr->STAT = RLDS_HDO | RLDS_BHO | RLDS_VCK | RLDS_LOCK; /* new volume */ +if ((p = sim_fsize (uptr->fileref)) == 0) { /* new disk image? */ + if (uptr->flags & UNIT_RO) /* if ro, done */ + return SCPE_OK; + return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD); + } +if ((uptr->flags & UNIT_AUTO) == 0) /* autosize? */ + return SCPE_OK; +if (p > (RL01_SIZE * sizeof (int16))) { + uptr->flags = uptr->flags | UNIT_RL02; + uptr->capac = RL02_SIZE; + } +else { + uptr->flags = uptr->flags & ~UNIT_RL02; + uptr->capac = RL01_SIZE; + } +return SCPE_OK; +} + +t_stat rl_detach (UNIT *uptr) +{ +t_stat stat; + +sim_cancel (uptr); +stat = detach_unit (uptr); +uptr->STAT = RLDS_BHO | RLDS_LOAD; +return (stat); +} + +/* Set size routine */ + +t_stat rl_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +if (uptr->flags & UNIT_ATT) + return SCPE_ALATT; +uptr->capac = (val & UNIT_RL02)? RL02_SIZE: RL01_SIZE; +return SCPE_OK; +} + +/* Set bad block routine */ + +t_stat rl_set_bad (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +return pdp11_bad_block (uptr, RL_NUMSC, RL_NUMWD); +} + +t_stat rl_set_cover (UNIT *uptr, int32 val, char *cptr, void *desc) +{ + /* allowed only if in LOAD state */ + if ((uptr->STAT & RLDS_M_STATE) != RLDS_LOAD) + return (SCPE_NOFNC); + uptr->STAT = (uptr->STAT & ~RLDS_CVO) | val; + return (SCPE_OK); +} + +t_stat rl_show_cover (FILE *st, UNIT *uptr, int32 val, void *desc) +{ + fprintf (st, "cover %s", (uptr->STAT & RLDS_CVO) ? "open" : "closed"); + return (SCPE_OK); +} + +/* simulate the LOAD button on the drive */ +t_stat rl_set_load (UNIT *uptr, int32 val, char *cptr, void *desc) +{ + if (val == 0) { /* LOAD */ + if (uptr->STAT & RLDS_CVO) /* cover open? */ + return (SCPE_NOFNC); + /* spin error if no cartridge loaded */ + if (!(uptr->flags & UNIT_ATT)) { + uptr->STAT |= RLDS_SPE; + return (SCPE_NOFNC); + } + /* state load? */ + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_LOAD; + } else { /* UNLOAD */ + if ((uptr->STAT & RLDS_M_STATE) != RLDS_LOCK) + return (SCPE_OK); + uptr->STAT = (uptr->STAT & ~RLDS_M_STATE) | RLDS_UNL; + } + uptr->FNC = RLCS_SPECIAL; + sim_activate (uptr, 10 * rl_swait); + return (SCPE_OK); +} + +t_stat rl_show_load (FILE *st, UNIT *uptr, int32 val, void *desc) +{ + fprintf (st, "load %s", + ((uptr->STAT & RLDS_M_STATE) != RLDS_LOAD) ? "set" : "reset"); + return (SCPE_OK); +} + +t_stat rl_show_dstate (FILE *st, UNIT *uptr, int32 val, void *desc) +{ + int32 cnt; + + fprintf (st, "drive state: %s\n", state[(uptr->STAT & RLDS_M_STATE)]); + fprintf (st, "brushes: %s, heads: %s, cover: %s\n", + (uptr->STAT & RLDS_BHO) ? "home" : "out", + (uptr->STAT & RLDS_HDO) ? "out" : "in", + (uptr->STAT & RLDS_CVO) ? "open" : "closed"); + fprintf (st, "vck:%c, wge:%c, spe:%c\n", + (uptr->STAT & RLDS_VCK) ? '1' : '0', + (uptr->STAT & RLDS_WGE) ? '1' : '0', + (uptr->STAT & RLDS_SPE) ? '1' : '0'); + if (uptr->flags & UNIT_ATT) { + if ((cnt = sim_is_active (uptr)) != 0) + fprintf (st, "FNC: %d, %d\n", uptr->FNC, cnt); + else + fputs ("FNC: none\n", st); + fprintf (st, "TRK: track=%d, cyl=%d, hd=%c, sect=%d\n", + GET_TRACK (uptr->TRK), GET_CYL (uptr->TRK), + (uptr->TRK & RLDA_HD1) ? '1' : '0', + GET_SECT (uptr->TRK)); + } + return (SCPE_OK); +} + +#if defined (VM_PDP11) + +/* Handle SET RL RLV12|RLV11 */ +t_stat rl_set_ctrl (UNIT *uptr, int32 val, char *cptr, void *desc) +{ + if (UNIBUS) + return (SCPE_NOFNC); + if ((val & DEV_RLV11) && (MEMSIZE > UNIMEMSIZE)) + return (SCPE_NOFNC); + rl_dev.flags = (rl_dev.flags & ~(DEV_RLV11|DEV_Q18)) | val; + return (SCPE_OK); +} + +#endif + +/* SHOW RL will display the controller type */ +t_stat rl_show_ctrl (FILE *st, UNIT *uptr, int32 val, void *desc) +{ + char *s = "RLV12"; + + if (UNIBUS) + s = "RL11"; + else if (rl_dev.flags & DEV_RLV11) + s = "RLV11"; + fputs (s, st); + return (SCPE_OK); +} + +/* Device bootstrap */ + +#if defined (VM_PDP11) + +#define BOOT_START 02000 /* start */ +#define BOOT_ENTRY (BOOT_START + 002) /* entry */ +#define BOOT_UNIT (BOOT_START + 010) /* unit number */ +#define BOOT_CSR (BOOT_START + 020) /* CSR */ +#define BOOT_LEN (sizeof (boot_rom) / sizeof (int16)) + +static const uint16 boot_rom[] = { + 0042114, /* "LD" */ + 0012706, BOOT_START, /* MOV #boot_start, SP */ + 0012700, 0000000, /* MOV #unit, R0 */ + 0010003, /* MOV R0, R3 */ + 0000303, /* SWAB R3 */ + 0012701, 0174400, /* MOV #RLCS, R1 ; csr */ + 0012761, 0000013, 0000004, /* MOV #13, 4(R1) ; clr err */ + 0052703, 0000004, /* BIS #4, R3 ; unit+gstat */ + 0010311, /* MOV R3, (R1) ; issue cmd */ + 0105711, /* TSTB (R1) ; wait */ + 0100376, /* BPL .-2 */ + 0105003, /* CLRB R3 */ + 0052703, 0000010, /* BIS #10, R3 ; unit+rdhdr */ + 0010311, /* MOV R3, (R1) ; issue cmd */ + 0105711, /* TSTB (R1) ; wait */ + 0100376, /* BPL .-2 */ + 0016102, 0000006, /* MOV 6(R1), R2 ; get hdr */ + 0042702, 0000077, /* BIC #77, R2 ; clr sector */ + 0005202, /* INC R2 ; magic bit */ + 0010261, 0000004, /* MOV R2, 4(R1) ; seek to 0 */ + 0105003, /* CLRB R3 */ + 0052703, 0000006, /* BIS #6, R3 ; unit+seek */ + 0010311, /* MOV R3, (R1) ; issue cmd */ + 0105711, /* TSTB (R1) ; wait */ + 0100376, /* BPL .-2 */ + 0005061, 0000002, /* CLR 2(R1) ; clr ba */ + 0005061, 0000004, /* CLR 4(R1) ; clr da */ + 0012761, 0177000, 0000006, /* MOV #-512., 6(R1) ; set wc */ + 0105003, /* CLRB R3 */ + 0052703, 0000014, /* BIS #14, R3 ; unit+read */ + 0010311, /* MOV R3, (R1) ; issue cmd */ + 0105711, /* TSTB (R1) ; wait */ + 0100376, /* BPL .-2 */ + 0042711, 0000377, /* BIC #377, (R1) */ + 0005002, /* CLR R2 */ + 0005003, /* CLR R3 */ + 0012704, BOOT_START+020, /* MOV #START+20, R4 */ + 0005005, /* CLR R5 */ + 0005007 /* CLR PC */ + }; + +t_stat rl_boot (int32 unitno, DEVICE *dptr) +{ +int32 i; +extern uint16 *M; +extern int32 saved_PC; + +for (i = 0; i < BOOT_LEN; i++) + M[(BOOT_START >> 1) + i] = boot_rom[i]; +M[BOOT_UNIT >> 1] = unitno & RLCS_M_DRIVE; +M[BOOT_CSR >> 1] = rl_dib.ba & 0177777; +saved_PC = BOOT_ENTRY; +return SCPE_OK; +} + +#else + +t_stat rl_boot (int32 unitno, DEVICE *dptr) +{ +return SCPE_NOFNC; +} + +#endif diff --git a/PDP11/pdp11_rq.c b/PDP11/pdp11_rq.c index c1aa19e6..2b17c44b 100644 --- a/PDP11/pdp11_rq.c +++ b/PDP11/pdp11_rq.c @@ -30,20 +30,20 @@ 18-Jun-07 RMS Added UNIT_IDLE flag to timer thread 31-Oct-05 RMS Fixed address width for large files 16-Aug-05 RMS Fixed C++ declaration and cast problems - 22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn) + 22-Jul-05 RMS Fixed warning from Solaris C (Doug Gwyn) 17-Jan-05 RMS Added more RA and RD disks 31-Oct-04 RMS Added -L switch (LBNs) to RAUSER size specification 01-Oct-04 RMS Revised Unibus interface Changed to identify as UDA50 in Unibus configurations Changed width to be 16b in all configurations Changed default timing for VAX - 24-Jul-04 RMS VAX controllers luns start with 0 (from Andreas Cejna) + 24-Jul-04 RMS VAX controllers luns start with 0 (Andreas Cejna) 05-Feb-04 RMS Revised for file I/O library 25-Jan-04 RMS Revised for device debug support - 12-Jan-04 RMS Fixed bug in interrupt control (found by Tom Evans) + 12-Jan-04 RMS Fixed bug in interrupt control (Tom Evans) 07-Oct-03 RMS Fixed problem with multiple RAUSER drives 17-Sep-03 RMS Fixed MB to LBN conversion to be more accurate - 11-Jul-03 RMS Fixed bug in user disk size (found by Chaskiel M Grundman) + 11-Jul-03 RMS Fixed bug in user disk size (Chaskiel M Grundman) 19-May-03 RMS Revised for new conditional compilation scheme 25-Apr-03 RMS Revised for extended file support 14-Mar-03 RMS Fixed variable size interaction with save/restore @@ -57,7 +57,7 @@ Fixed status code in HBE error log Consolidated MSCP/TMSCP header file New data structures - 16-Aug-02 RMS Removed unused variables (found by David Hittner) + 16-Aug-02 RMS Removed unused variables (David Hittner) 04-May-02 RMS Fixed bug in polling loop for queued operations 26-Mar-02 RMS Fixed bug, reset routine cleared UF_WPH 09-Mar-02 RMS Adjusted delays for M+ timing bugs @@ -86,7 +86,7 @@ extern int32 fault_PC; #define RQ_XTIME 500 #define OLDPC MMR2 extern int32 MMR2; -extern int32 cpu_opt; +extern uint32 cpu_opt; #endif #if !defined (RQ_NUMCT) diff --git a/PDP11/pdp11_rx.c b/PDP11/pdp11_rx.c index 67335d22..f4267b61 100644 --- a/PDP11/pdp11_rx.c +++ b/PDP11/pdp11_rx.c @@ -130,7 +130,7 @@ t_stat rx_wr (int32 data, int32 PA, int32 access); t_stat rx_svc (UNIT *uptr); t_stat rx_reset (DEVICE *dptr); t_stat rx_boot (int32 unitno, DEVICE *dptr); -void rx_done (int esr_flags, int new_ecode); +void rx_done (int32 esr_flags, int32 new_ecode); /* RX11 data structures diff --git a/PDP11/pdp11_ry.c b/PDP11/pdp11_ry.c index 7310cf80..a973e2e0 100644 --- a/PDP11/pdp11_ry.c +++ b/PDP11/pdp11_ry.c @@ -25,9 +25,9 @@ ry RX211/RXV21/RX02 floppy disk - 15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein) + 15-May-06 RMS Fixed bug in autosize attach (David Gesswein) 07-Jul-05 RMS Removed extraneous externs - 18-Feb-05 RMS Fixed bug in boot code (reported by Graham Toal) + 18-Feb-05 RMS Fixed bug in boot code (Graham Toal) 30-Sep-04 RMS Revised Unibus interface 21-Mar-04 RMS Added VAX support 29-Dec-03 RMS Added RXV21 support @@ -161,7 +161,7 @@ t_stat ry_wr (int32 data, int32 PA, int32 access); t_stat ry_svc (UNIT *uptr); t_stat ry_reset (DEVICE *dptr); t_stat ry_boot (int32 unitno, DEVICE *dptr); -void ry_done (int esr_flags, int new_ecode); +void ry_done (int32 esr_flags, int32 new_ecode); t_stat ry_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat ry_attach (UNIT *uptr, char *cptr); diff --git a/PDP11/pdp11_stddev.c b/PDP11/pdp11_stddev.c index ed6ce6e1..d68199b3 100644 --- a/PDP11/pdp11_stddev.c +++ b/PDP11/pdp11_stddev.c @@ -32,7 +32,7 @@ Added clock coscheduling support 05-Jul-06 RMS Added UC only support for early DOS/RSTS 22-Nov-05 RMS Revised for new terminal processing routines - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 07-Jul-05 RMS Removed extraneous externs 11-Oct-04 RMS Added clock model dependencies 28-May-04 RMS Removed SET TTI CTRL-C @@ -46,7 +46,7 @@ Split DL11 dibs 30-May-02 RMS Widened POS to 32b 26-Jan-02 RMS Revised for multiple timers - 09-Jan-02 RMS Fixed bugs in KW11L (found by John Dundas) + 09-Jan-02 RMS Fixed bugs in KW11L (John Dundas) 06-Jan-02 RMS Split I/O address routines, revised enable/disable support 29-Nov-01 RMS Added read only unit support 09-Nov-01 RMS Added RQDX3 support diff --git a/PDP11/pdp11_sys.c b/PDP11/pdp11_sys.c index 17ac0423..16ca83b4 100644 --- a/PDP11/pdp11_sys.c +++ b/PDP11/pdp11_sys.c @@ -30,13 +30,13 @@ 25-Jan-08 RMS Added RC11, KG11A support from John Dundas 10-Sep-07 RMS Cleaned up binary loader 20-Dec-06 RMS Added TA11 support - 12-Nov-06 RMS Fixed operand order in EIS instructions (found by W.F.J. Mueller) + 12-Nov-06 RMS Fixed operand order in EIS instructions (W.F.J. Mueller) 14-Jul-06 RMS Reordered device list 06-Jul-06 RMS Added multiple KL11/DL11 support 26-Jun-06 RMS Added RF11 support - 17-May-06 RMS Added CR11/CD11 support (from John Dundas) + 17-May-06 RMS Added CR11/CD11 support (John Dundas) 16-Aug-05 RMS Fixed C++ declaration and cast problems - 22-Jul-05 RMS Fixed missing , in initializer (from Doug Gwyn) + 22-Jul-05 RMS Fixed missing , in initializer (Doug Gwyn) 22-Dec-03 RMS Added second DEUNA/DELUA support 18-Oct-03 RMS Added DECtape off reel message 06-May-03 RMS Added support for second DEQNA/DELQA diff --git a/PDP11/pdp11_tc.c b/PDP11/pdp11_tc.c index 1b67b4ce..f1451776 100644 --- a/PDP11/pdp11_tc.c +++ b/PDP11/pdp11_tc.c @@ -26,7 +26,7 @@ tc TC11/TU56 DECtape 23-Jun-06 RMS Fixed switch conflict in ATTACH - 10-Feb-06 RMS READ sets extended data bits in TCST (found by Alan Frisbie) + 10-Feb-06 RMS READ sets extended data bits in TCST (Alan Frisbie) 16-Aug-05 RMS Fixed C++ declaration and cast problems 07-Jul-05 RMS Removed extraneous externs 30-Sep-04 RMS Revised Unibus interface diff --git a/PDP11/pdp11_tm.c b/PDP11/pdp11_tm.c index e6af932c..ee4f2ba6 100644 --- a/PDP11/pdp11_tm.c +++ b/PDP11/pdp11_tm.c @@ -46,23 +46,22 @@ 28-Aug-02 RMS Added end of medium support 30-May-02 RMS Widened POS to 32b 22-Apr-02 RMS Fixed max record length, first block bootstrap - (found by Jonathan Engdahl) + (Jonathan Engdahl) 26-Jan-02 RMS Revised bootstrap to conform to M9312 06-Jan-02 RMS Revised enable/disable support 30-Nov-01 RMS Added read only unit, extended SET/SHOW support 24-Nov-01 RMS Converted UST, POS, FLG to arrays 09-Nov-01 RMS Added bus map support - 18-Oct-01 RMS Added stub diagnostic register (found by Thord Nilson) + 18-Oct-01 RMS Added stub diagnostic register (Thord Nilson) 07-Sep-01 RMS Revised device disable and interrupt mechanisms 26-Apr-01 RMS Added device enable/disable support 18-Apr-01 RMS Changed to rewind tape before boot 14-Apr-99 RMS Changed t_addr to unsigned 04-Oct-98 RMS V2.4 magtape format - 10-May-98 RMS Fixed bug with non-zero unit operation (from Steven Schultz) - 09-May-98 RMS Fixed problems in bootstrap (from Steven Schultz) - 10-Apr-98 RMS Added 2nd block bootstrap (from John Holden, - University of Sydney) - 31-Jul-97 RMS Added bootstrap (from Ethan Dicks, Ohio State) + 10-May-98 RMS Fixed bug with non-zero unit operation (Steven Schultz) + 09-May-98 RMS Fixed problems in bootstrap (Steven Schultz) + 10-Apr-98 RMS Added 2nd block bootstrap (John Holden) + 31-Jul-97 RMS Added bootstrap (Ethan Dicks) 22-Jan-97 RMS V2.3 magtape format 18-Jan-97 RMS Fixed double interrupt, error flag bugs 29-Jun-96 RMS Added unit disable support diff --git a/PDP11/pdp11_tq.c b/PDP11/pdp11_tq.c index fc5a1346..9ac8840e 100644 --- a/PDP11/pdp11_tq.c +++ b/PDP11/pdp11_tq.c @@ -44,10 +44,10 @@ 16-Feb-06 RMS Revised for new magtape capacity checking 31-Oct-05 RMS Fixed address width for large files 16-Aug-05 RMS Fixed C++ declaration and cast problems - 22-Jul-05 RMS Fixed warning from Solaris C (from Doug Gwyn) + 22-Jul-05 RMS Fixed warning from Solaris C (Doug Gwyn) 30-Sep-04 RMS Revised Unibus interface - 12-Jun-04 RMS Fixed bug in reporting write protect (reported by Lyle Bickley) - 18-Apr-04 RMS Fixed TQK70 media ID and model byte (found by Robert Schaffrath) + 12-Jun-04 RMS Fixed bug in reporting write protect (Lyle Bickley) + 18-Apr-04 RMS Fixed TQK70 media ID and model byte (Robert Schaffrath) 26-Mar-04 RMS Fixed warnings with -std=c99 25-Jan-04 RMS Revised for device debug support 19-May-03 RMS Revised for new conditional compilation scheme @@ -58,7 +58,7 @@ 22-Feb-03 RMS Fixed ordering bug in queue process Fixed flags table to allow MD_CSE everywhere 09-Jan-03 RMS Fixed bug in transfer end packet status - 17-Oct-02 RMS Fixed bug in read reverse (found by Hans Pufal) + 17-Oct-02 RMS Fixed bug in read reverse (Hans Pufal) */ #if defined (VM_PDP10) /* PDP10 version */ @@ -78,7 +78,7 @@ #include "pdp11_defs.h" #define INIT_TYPE TQ5_TYPE #define INIT_CAP TQ5_CAP -extern int32 cpu_opt; +extern uint32 cpu_opt; #endif #include "pdp11_uqssp.h" diff --git a/PDP11/pdp11_ts.c b/PDP11/pdp11_ts.c index 01a5b0fe..11ab6f11 100644 --- a/PDP11/pdp11_ts.c +++ b/PDP11/pdp11_ts.c @@ -1,6 +1,6 @@ /* pdp11_ts.c: TS11/TSV05 magnetic tape simulator - Copyright (c) 1993-2010, Robert M Supnik + Copyright (c) 1993-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,8 +25,9 @@ ts TS11/TSV05 magtape + 19-Mar-12 RMS Fixed declaration of cpu_opt (Mark Pizzolato) 22-May-10 RMS Fixed t_addr printouts for 64b big-endian systems - (found by Mark Pizzolato) + (Mark Pizzolato) 16-Feb-06 RMS Added tape capacity checking 31-Oct-05 RMS Fixed address width for large files 16-Aug-05 RMS Fixed C++ declaration and cast problems @@ -59,7 +60,7 @@ 19-Sep-01 RMS Fixed bug in bootstrap 15-Sep-01 RMS Fixed bug in NXM test 07-Sep-01 RMS Revised device disable and interrupt mechanism - 13-Jul-01 RMS Fixed bug in space reverse (found by Peter Schorn) + 13-Jul-01 RMS Fixed bug in space reverse (Peter Schorn) Magnetic tapes are represented as a series of variable 8b records of the form: @@ -96,7 +97,7 @@ #else /* PDP-11 version */ #include "pdp11_defs.h" #define TS_DIS DEV_DIS /* off by default */ -extern int32 cpu_opt; +extern uint32 cpu_opt; #endif #include "sim_tape.h" diff --git a/PDP11/pdp11_tu.c b/PDP11/pdp11_tu.c index f4b2144f..9175b996 100644 --- a/PDP11/pdp11_tu.c +++ b/PDP11/pdp11_tu.c @@ -1,6 +1,6 @@ /* pdp11_tu.c - PDP-11 TM02/TU16 TM03/TU45/TU77 Massbus magnetic tape controller - Copyright (c) 1993-2008, Robert M Supnik + Copyright (c) 1993-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,7 +27,7 @@ 18-Apr-11 MP Fixed t_addr printouts for 64b big-endian systems 17-May-07 RMS CS1 DVA resides in device, not MBA - 29-Apr-07 RMS Fixed bug in setting FCE on TMK (found by Naoki Hamada) + 29-Apr-07 RMS Fixed bug in setting FCE on TMK Naoki Hamada) 16-Feb-06 RMS Added tape capacity checking 12-Nov-05 RMS Changed default formatter to TM03 (for VMS) 31-Oct-05 RMS Fixed address width for large files diff --git a/PDP11/pdp11_vh.c b/PDP11/pdp11_vh.c index dd5d97e2..d4ae0a63 100644 --- a/PDP11/pdp11_vh.c +++ b/PDP11/pdp11_vh.c @@ -1,6 +1,6 @@ /* pdp11_vh.c: DHQ11 asynchronous terminal multiplexor simulator - Copyright (c) 2004-2010, John A. Dundas III + Copyright (c) 2004-2012, John A. Dundas III Portions derived from work by Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a @@ -24,266 +24,286 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from the Author. - vh DHQ11 asynch multiplexor for SIMH + vh DHQ11 asynch multiplexor for SIMH + 02-Jun-11 MP Added debugging support to trace register, interrupt + and data traffic (SET VH DEBUG[=REG;INT;XMT;RCV]) + Added SET LOG and SET NOLOG support for logging mux + traffic + Fixed SET VH LINES=n to correctly adjust the number + of lines available to be 8, 16, 24, or 32. + Fixed performance issue avoiding redundant polling 03-Jan-10 JAD Eliminate gcc warnings 19-Nov-08 RMS Revised for common TMXR show routines 18-Jun-07 RMS Added UNIT_IDLE flag 29-Oct-06 RMS Synced poll and clock - 07-Jul-05 RMS Removed extraneous externs - 15-Jun-05 RMS Revised for new autoconfigure interface - Fixed bug in vector display routine - 12-Jun-04 RMS Repair MS2SIMH macro to avoid divide by 0 bug - 08-Jun-04 JAD Repair vh_dev initialization; remove unused - variables, cast to avoid conversion confusion - 07-Jun-04 JAD Complete function prototypes of forward declarations. - Repair broken prototypes of vh_rd() and vh_wr() - Explicitly size integer declarations - 4-Jun-04 JAD Preliminary code: If operating in a PDP-11 Unibus - environment, force DHU mode - 29-May-04 JAD Make certain RX.TIMER is within allowable range - 25-May-04 JAD All time-based operations are scaled by tmxr_poll units - 23-May-04 JAD Change to fifo_get() and dq_tx_report() to avoid - gratuitous stack manipulation - 20-May-04 JAD Made modem control and auto-hangup unit flags - 19-May-04 JAD Fix problem with modem status where the line number - was not being included - 12-May-04 JAD Revised for updated tmxr interfaces - 28-Jan-04 JAD Original creation and testing + 07-Jul-05 RMS Removed extraneous externs + 15-Jun-05 RMS Revised for new autoconfigure interface + Fixed bug in vector display routine + 12-Jun-04 RMS Repair MS2SIMH macro to avoid divide by 0 bug + 08-Jun-04 JAD Repair vh_dev initialization; remove unused + variables, cast to avoid conversion confusion + 07-Jun-04 JAD Complete function prototypes of forward declarations. + Repair broken prototypes of vh_rd() and vh_wr() + Explicitly size integer declarations + 4-Jun-04 JAD Preliminary code: If operating in a PDP-11 Unibus + environment, force DHU mode + 29-May-04 JAD Make certain RX.TIMER is within allowable range + 25-May-04 JAD All time-based operations are scaled by tmxr_poll units + 23-May-04 JAD Change to fifo_get() and dq_tx_report() to avoid + gratuitous stack manipulation + 20-May-04 JAD Made modem control and auto-hangup unit flags + 19-May-04 JAD Fix problem with modem status where the line number + was not being included + 12-May-04 JAD Revised for updated tmxr interfaces + 28-Jan-04 JAD Original creation and testing I/O Page Registers -CSR 17 760 440 (float) +CSR 17 760 440 (float) -Vector: 300 (float) +Vector: 300 (float) -Priority: BR4 +Priority: BR4 -Rank: 32 +Rank: 32 */ /* MANY constants needed! */ -#if defined (VM_VAX) +#if defined (VM_VAX) #include "vax_defs.h" -extern int32 int_req[IPL_HLVL]; +extern int32 int_req[IPL_HLVL]; #endif -#if defined (VM_PDP11) +#if defined (VM_PDP11) #include "pdp11_defs.h" -extern int32 int_req[IPL_HLVL]; -extern int32 cpu_opt; +extern int32 int_req[IPL_HLVL]; +extern uint32 cpu_opt; #endif #include "sim_sock.h" #include "sim_tmxr.h" /* imports from pdp11_stddev.c: */ -extern int32 tmxr_poll, clk_tps; +extern int32 tmxr_poll, clk_tps; /* convert ms to SIMH time units based on tmxr_poll polls per second */ -#define MS2SIMH(ms) (((ms) * clk_tps) / 1000) -extern FILE *sim_log; +#define MS2SIMH(ms) (((ms) * clk_tps) / 1000) -#ifndef VH_MUXES -#define VH_MUXES (4) +#ifndef VH_MUXES +#define VH_MUXES (4) #endif -#define VH_MNOMASK (VH_MUXES - 1) +#define VH_MNOMASK (VH_MUXES - 1) -#define VH_LINES (8) +#define VH_LINES (8) -#define UNIT_V_MODEDHU (UNIT_V_UF + 0) -#define UNIT_V_FASTDMA (UNIT_V_UF + 1) -#define UNIT_V_MODEM (UNIT_V_UF + 2) -#define UNIT_V_HANGUP (UNIT_V_UF + 3) -#define UNIT_MODEDHU (1 << UNIT_V_MODEDHU) -#define UNIT_FASTDMA (1 << UNIT_V_FASTDMA) -#define UNIT_MODEM (1 << UNIT_V_MODEM) -#define UNIT_HANGUP (1 << UNIT_V_HANGUP) +#define UNIT_V_MODEDHU (UNIT_V_UF + 0) +#define UNIT_V_FASTDMA (UNIT_V_UF + 1) +#define UNIT_V_MODEM (UNIT_V_UF + 2) +#define UNIT_V_HANGUP (UNIT_V_UF + 3) +#define UNIT_MODEDHU (1 << UNIT_V_MODEDHU) +#define UNIT_FASTDMA (1 << UNIT_V_FASTDMA) +#define UNIT_MODEM (1 << UNIT_V_MODEM) +#define UNIT_HANGUP (1 << UNIT_V_HANGUP) /* VHCSR - 160440 - Control and Status Register */ -#define CSR_M_IND_ADDR (017) -#define CSR_SKIP (1 << 4) -#define CSR_MASTER_RESET (1 << 5) -#define CSR_RXIE (1 << 6) -#define CSR_RX_DATA_AVAIL (1 << 7) -#define CSR_M_TX_LINE (017) -#define CSR_V_TX_LINE (8) -#define CSR_TX_DMA_ERR (1 << 12) -#define CSR_DIAG_FAIL (1 << 13) -#define CSR_TXIE (1 << 14) -#define CSR_TX_ACTION (1 << 15) -#define CSR_GETCHAN(x) ((x) & CSR_M_IND_ADDR) -#define CSR_RW \ - (CSR_TXIE|CSR_RXIE|CSR_SKIP|CSR_M_IND_ADDR|CSR_MASTER_RESET) -#define RESET_ABORT (052525) +#define CSR_M_IND_ADDR (017) +#define CSR_SKIP (1 << 4) +#define CSR_MASTER_RESET (1 << 5) +#define CSR_RXIE (1 << 6) +#define CSR_RX_DATA_AVAIL (1 << 7) +#define CSR_M_TX_LINE (017) +#define CSR_V_TX_LINE (8) +#define CSR_TX_DMA_ERR (1 << 12) +#define CSR_DIAG_FAIL (1 << 13) +#define CSR_TXIE (1 << 14) +#define CSR_TX_ACTION (1 << 15) +#define CSR_GETCHAN(x) ((x) & CSR_M_IND_ADDR) +#define CSR_RW \ + (CSR_TXIE|CSR_RXIE|CSR_SKIP|CSR_M_IND_ADDR|CSR_MASTER_RESET) +#define RESET_ABORT (052525) /* Receive Buffer (RBUF) */ -#define FIFO_SIZE (256) -#define FIFO_ALARM (191) -#define FIFO_HALF (FIFO_SIZE / 2) -#define RBUF_M_RX_CHAR (0377) -#define RBUF_M_RX_LINE (07) -#define RBUF_V_RX_LINE (8) -#define RBUF_PARITY_ERR (1 << 12) -#define RBUF_FRAME_ERR (1 << 13) -#define RBUF_OVERRUN_ERR (1 << 14) -#define RBUF_DATA_VALID (1 << 15) -#define RBUF_GETLINE(x) (((x) >> RBUF_V_RX_LINE) & RBUF_M_RX_LINE) -#define RBUF_PUTLINE(x) ((x) << RBUF_V_RX_LINE) -#define RBUF_DIAG \ - (RBUF_PARITY_ERR|RBUF_FRAME_ERR|RBUF_OVERRUN_ERR) -#define XON (021) -#define XOFF (023) +#define FIFO_SIZE (256) +#define FIFO_ALARM (191) +#define FIFO_HALF (FIFO_SIZE / 2) +#define RBUF_M_RX_CHAR (0377) +#define RBUF_M_RX_LINE (07) +#define RBUF_V_RX_LINE (8) +#define RBUF_PARITY_ERR (1 << 12) +#define RBUF_FRAME_ERR (1 << 13) +#define RBUF_OVERRUN_ERR (1 << 14) +#define RBUF_DATA_VALID (1 << 15) +#define RBUF_GETLINE(x) (((x) >> RBUF_V_RX_LINE) & RBUF_M_RX_LINE) +#define RBUF_PUTLINE(x) ((x) << RBUF_V_RX_LINE) +#define RBUF_DIAG \ + (RBUF_PARITY_ERR|RBUF_FRAME_ERR|RBUF_OVERRUN_ERR) +#define XON (021) +#define XOFF (023) /* Transmit Character Register (TXCHAR) */ -#define TXCHAR_M_CHAR (0377) -#define TXCHAR_TX_DATA_VALID (1 << 15) +#define TXCHAR_M_CHAR (0377) +#define TXCHAR_TX_DATA_VALID (1 << 15) /* Receive Timer Register (RXTIMER) */ -#define RXTIMER_M_RX_TIMER (0377) +#define RXTIMER_M_RX_TIMER (0377) /* Line-Parameter Register (LPR) */ -#define LPR_DISAB_XRPT (1 << 0) /* not impl. in real DHU */ -#define LPR_V_DIAG (1) -#define LPR_M_DIAG (03) -#define LPR_V_CHAR_LGTH (3) -#define LPR_M_CHAR_LGTH (03) -#define LPR_PARITY_ENAB (1 << 5) -#define LPR_EVEN_PARITY (1 << 6) -#define LPR_STOP_CODE (1 << 7) -#define LPR_V_RX_SPEED (8) -#define LPR_M_RX_SPEED (017) -#define LPR_V_TX_SPEED (12) -#define LPR_M_TX_SPEED (017) +#define LPR_DISAB_XRPT (1 << 0) /* not impl. in real DHU */ +#define LPR_V_DIAG (1) +#define LPR_M_DIAG (03) +#define LPR_V_CHAR_LGTH (3) +#define LPR_M_CHAR_LGTH (03) +#define LPR_PARITY_ENAB (1 << 5) +#define LPR_EVEN_PARITY (1 << 6) +#define LPR_STOP_CODE (1 << 7) +#define LPR_V_RX_SPEED (8) +#define LPR_M_RX_SPEED (017) +#define LPR_V_TX_SPEED (12) +#define LPR_M_TX_SPEED (017) -#define RATE_50 (0) -#define RATE_75 (1) -#define RATE_110 (2) -#define RATE_134 (3) -#define RATE_150 (4) -#define RATE_300 (5) -#define RATE_600 (6) -#define RATE_1200 (7) -#define RATE_1800 (8) -#define RATE_2000 (9) -#define RATE_2400 (10) -#define RATE_4800 (11) -#define RATE_7200 (12) -#define RATE_9600 (13) -#define RATE_19200 (14) -#define RATE_38400 (15) +#define RATE_50 (0) +#define RATE_75 (1) +#define RATE_110 (2) +#define RATE_134 (3) +#define RATE_150 (4) +#define RATE_300 (5) +#define RATE_600 (6) +#define RATE_1200 (7) +#define RATE_1800 (8) +#define RATE_2000 (9) +#define RATE_2400 (10) +#define RATE_4800 (11) +#define RATE_7200 (12) +#define RATE_9600 (13) +#define RATE_19200 (14) +#define RATE_38400 (15) /* Line-Status Register (STAT) */ -#define STAT_DHUID (1 << 8) /* mode: 0=DHV, 1=DHU */ -#define STAT_MDL (1 << 9) /* always 0, has modem support */ -#define STAT_CTS (1 << 11) /* CTS from modem */ -#define STAT_DCD (1 << 12) /* DCD from modem */ -#define STAT_RI (1 << 13) /* RI from modem */ -#define STAT_DSR (1 << 15) /* DSR from modem */ +#define STAT_DHUID (1 << 8) /* mode: 0=DHV, 1=DHU */ +#define STAT_MDL (1 << 9) /* always 0, has modem support */ +#define STAT_CTS (1 << 11) /* CTS from modem */ +#define STAT_DCD (1 << 12) /* DCD from modem */ +#define STAT_RI (1 << 13) /* RI from modem */ +#define STAT_DSR (1 << 15) /* DSR from modem */ /* FIFO Size Register (FIFOSIZE) */ -#define FIFOSIZE_M_SIZE (0377) +#define FIFOSIZE_M_SIZE (0377) /* FIFO Data Register (FIFODATA) */ -#define FIFODATA_W0 (0377) -#define FIFODATA_V_W1 (8) -#define FIFODATA_M_W1 (0377) +#define FIFODATA_W0 (0377) +#define FIFODATA_V_W1 (8) +#define FIFODATA_M_W1 (0377) /* Line-Control Register (LNCTRL) */ -#define LNCTRL_TX_ABORT (1 << 0) -#define LNCTRL_IAUTO (1 << 1) -#define LNCTRL_RX_ENA (1 << 2) -#define LNCTRL_BREAK (1 << 3) -#define LNCTRL_OAUTO (1 << 4) -#define LNCTRL_FORCE_XOFF (1 << 5) -#define LNCTRL_V_MAINT (6) -#define LNCTRL_M_MAINT (03) -#define LNCTRL_LINK_TYPE (1 << 8) /* 0=data leads only, 1=modem */ -#define LNCTRL_DTR (1 << 9) /* DTR to modem */ -#define LNCTRL_RTS (1 << 12) /* RTS to modem */ +#define LNCTRL_TX_ABORT (1 << 0) +#define LNCTRL_IAUTO (1 << 1) +#define LNCTRL_RX_ENA (1 << 2) +#define LNCTRL_BREAK (1 << 3) +#define LNCTRL_OAUTO (1 << 4) +#define LNCTRL_FORCE_XOFF (1 << 5) +#define LNCTRL_V_MAINT (6) +#define LNCTRL_M_MAINT (03) +#define LNCTRL_LINK_TYPE (1 << 8) /* 0=data leads only, 1=modem */ +#define LNCTRL_DTR (1 << 9) /* DTR to modem */ +#define LNCTRL_RTS (1 << 12) /* RTS to modem */ /* Transmit Buffer Address Register Number 1 (TBUFFAD1) */ /* Transmit Buffer Address Register Number 2 (TBUFFAD2) */ -#define TB2_M_TBUFFAD (077) -#define TB2_TX_DMA_START (1 << 7) -#define TB2_TX_ENA (1 << 15) +#define TB2_M_TBUFFAD (077) +#define TB2_TX_DMA_START (1 << 7) +#define TB2_TX_ENA (1 << 15) /* Transmit DMA Buffer Counter (TBUFFCT) */ /* Self-Test Error Codes */ -#define SELF_NULL (0201) -#define SELF_SKIP (0203) -#define SELF_OCT (0211) -#define SELF_RAM (0225) -#define SELF_RCD (0231) -#define SELF_DRD (0235) +#define SELF_NULL (0201) +#define SELF_SKIP (0203) +#define SELF_OCT (0211) +#define SELF_RAM (0225) +#define SELF_RCD (0231) +#define SELF_DRD (0235) -#define BMP_OK (0305) -#define BMP_BAD (0307) +#define BMP_OK (0305) +#define BMP_BAD (0307) /* Loopback types */ -#define LOOP_NONE (0) -#define LOOP_H325 (1) -#define LOOP_H3101 (2) /* p.2-13 DHQ manual */ +#define LOOP_NONE (0) +#define LOOP_H325 (1) +#define LOOP_H3101 (2) /* p.2-13 DHQ manual */ /* Local storage */ -static uint16 vh_csr[VH_MUXES] = { 0 }; /* CSRs */ -static uint16 vh_timer[VH_MUXES] = { 1 }; /* controller timeout */ -static uint16 vh_mcount[VH_MUXES] = { 0 }; -static uint32 vh_timeo[VH_MUXES] = { 0 }; -static uint32 vh_ovrrun[VH_MUXES] = { 0 }; /* line overrun bits */ +static uint16 vh_csr[VH_MUXES] = { 0 }; /* CSRs */ +static uint16 vh_timer[VH_MUXES] = { 1 }; /* controller timeout */ +static uint16 vh_mcount[VH_MUXES] = { 0 }; +static uint32 vh_timeo[VH_MUXES] = { 0 }; +static uint32 vh_ovrrun[VH_MUXES] = { 0 }; /* line overrun bits */ /* XOFF'd channels, one bit/channel */ -static uint32 vh_stall[VH_MUXES] = { 0 }; -static uint16 vh_loop[VH_MUXES] = { 0 }; /* loopback status */ +static uint32 vh_stall[VH_MUXES] = { 0 }; +static uint16 vh_loop[VH_MUXES] = { 0 }; /* loopback status */ /* One bit per controller: */ -static uint32 vh_rxi = 0; /* rcv interrupts */ -static uint32 vh_txi = 0; /* xmt interrupts */ -static uint32 vh_crit = 0; /* FIFO.CRIT */ +static uint32 vh_rxi = 0; /* rcv interrupts */ +static uint32 vh_txi = 0; /* xmt interrupts */ +static uint32 vh_crit = 0; /* FIFO.CRIT */ static const int32 bitmask[4] = { 037, 077, 0177, 0377 }; /* RX FIFO state */ -static int32 rbuf_idx[VH_MUXES] = { 0 };/* index into vh_rbuf */ +static int32 rbuf_idx[VH_MUXES] = { 0 };/* index into vh_rbuf */ static uint32 vh_rbuf[VH_MUXES][FIFO_SIZE] = { { 0 } }; /* TXQ state */ -#define TXQ_SIZE (16) -static int32 txq_idx[VH_MUXES] = { 0 }; -static uint32 vh_txq[VH_MUXES][TXQ_SIZE] = { { 0 } }; +#define TXQ_SIZE (16) +static int32 txq_idx[VH_MUXES] = { 0 }; +static uint32 vh_txq[VH_MUXES][TXQ_SIZE] = { { 0 } }; /* Need to extend the TMLN structure */ typedef struct { - TMLN *tmln; - uint16 lpr; /* line parameters */ - uint16 lnctrl; /* line control */ - uint16 lstat; /* line modem status */ - uint16 tbuffct; /* remaining character count */ - uint16 tbuf1; - uint16 tbuf2; - uint16 txchar; /* single character I/O */ + TMLN *tmln; + uint16 lpr; /* line parameters */ + uint16 lnctrl; /* line control */ + uint16 lstat; /* line modem status */ + uint16 tbuffct; /* remaining character count */ + uint16 tbuf1; + uint16 tbuf2; + uint16 txchar; /* single character I/O */ } TMLX; static TMLN vh_ldsc[VH_MUXES * VH_LINES] = { { 0 } }; static TMXR vh_desc = { VH_MUXES * VH_LINES, 0, 0, vh_ldsc }; static TMLX vh_parm[VH_MUXES * VH_LINES] = { { 0 } }; +/* debugging bitmaps */ +#define DBG_REG 0x0001 /* trace read/write registers */ +#define DBG_INT 0x0002 /* display transfer requests */ +/* #define DBG_XMT TMXR_DBG_XMT /* display Transmitted Data */ +/* #define DBG_RCV TMXR_DBG_RCV /* display Received Data */ + +DEBTAB vh_debug[] = { + {"REG", DBG_REG}, + {"INT", DBG_INT}, +// {"XMT", DBG_XMT}, +// {"RCV", DBG_RCV}, + {0} +}; + /* Forward references */ static t_stat vh_rd (int32 *data, int32 PA, int32 access); static t_stat vh_wr (int32 data, int32 PA, int32 access); @@ -294,842 +314,869 @@ static t_stat vh_clear (int32 vh, t_bool flag); static t_stat vh_reset (DEVICE *dptr); static t_stat vh_attach (UNIT *uptr, char *cptr); static t_stat vh_detach (UNIT *uptr); -static t_stat vh_show_debug (FILE *st, UNIT *uptr, int32 val, void *desc); +static t_stat vh_show_detail (FILE *st, UNIT *uptr, int32 val, void *desc); static t_stat vh_show_rbuf (FILE *st, UNIT *uptr, int32 val, void *desc); static t_stat vh_show_txq (FILE *st, UNIT *uptr, int32 val, void *desc); static t_stat vh_putc (int32 vh, TMLX *lp, int32 chan, int32 data); static void doDMA (int32 vh, int32 chan); +static t_stat vh_setnl (UNIT *uptr, int32 val, char *cptr, void *desc); +static t_stat vh_set_log (UNIT *uptr, int32 val, char *cptr, void *desc); +static t_stat vh_set_nolog (UNIT *uptr, int32 val, char *cptr, void *desc); +static t_stat vh_show_log (FILE *st, UNIT *uptr, int32 val, void *desc); int32 tmxr_send_buffered_data (TMLN *lp); /* SIMH I/O Structures */ static DIB vh_dib = { - IOBA_VH, - IOLN_VH * VH_MUXES, - &vh_rd, /* read */ - &vh_wr, /* write */ - 2, /* # of vectors */ - IVCL (VHRX), - VEC_VHRX, - { &vh_rxinta, &vh_txinta } /* int. ack. routines */ + IOBA_VH, + IOLN_VH * VH_MUXES, + &vh_rd, /* read */ + &vh_wr, /* write */ + 2, /* # of vectors */ + IVCL (VHRX), + VEC_VHRX, + { &vh_rxinta, &vh_txinta } /* int. ack. routines */ }; static UNIT vh_unit[VH_MUXES] = { - { UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, - { UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, - { UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, - { UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, + { UDATA (&vh_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, }; static const REG vh_reg[] = { - { BRDATA (CSR, vh_csr, DEV_RDX, 16, VH_MUXES) }, - { GRDATA (DEVADDR, vh_dib.ba, DEV_RDX, 32, 0), REG_HRO }, - { GRDATA (DEVVEC, vh_dib.vec, DEV_RDX, 16, 0), REG_HRO }, - { NULL } + { BRDATA (CSR, vh_csr, DEV_RDX, 16, VH_MUXES) }, + { GRDATA (DEVADDR, vh_dib.ba, DEV_RDX, 32, 0), REG_HRO }, + { GRDATA (DEVVEC, vh_dib.vec, DEV_RDX, 16, 0), REG_HRO }, + { NULL } }; static const MTAB vh_mod[] = { - { UNIT_MODEDHU, 0, "DHV mode", "DHV", NULL }, - { UNIT_MODEDHU, UNIT_MODEDHU, "DHU mode", "DHU", NULL }, - { UNIT_FASTDMA, 0, NULL, "NORMAL", NULL }, - { UNIT_FASTDMA, UNIT_FASTDMA, "fast DMA", "FASTDMA", NULL }, - { UNIT_MODEM, 0, NULL, "NOMODEM", NULL }, - { UNIT_MODEM, UNIT_MODEM, "modem", "MODEM", NULL }, - { UNIT_HANGUP, 0, NULL, "NOHANGUP", NULL }, - { UNIT_HANGUP, UNIT_HANGUP, "hangup", "HANGUP", NULL }, - { MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS", - &set_addr, &show_addr, NULL }, - { MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE", - &set_addr_flt, NULL, NULL }, + { UNIT_MODEDHU, 0, "DHV mode", "DHV", NULL }, + { UNIT_MODEDHU, UNIT_MODEDHU, "DHU mode", "DHU", NULL }, + { UNIT_FASTDMA, 0, NULL, "NORMAL", NULL }, + { UNIT_FASTDMA, UNIT_FASTDMA, "fast DMA", "FASTDMA", NULL }, + { UNIT_MODEM, 0, NULL, "NOMODEM", NULL }, + { UNIT_MODEM, UNIT_MODEM, "modem", "MODEM", NULL }, + { UNIT_HANGUP, 0, NULL, "NOHANGUP", NULL }, + { UNIT_HANGUP, UNIT_HANGUP, "hangup", "HANGUP", NULL }, + { MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS", + &set_addr, &show_addr, NULL }, { MTAB_XTD|MTAB_VDV, VH_LINES, "VECTOR", "VECTOR", - &set_vec, &show_vec_mux, (void *) &vh_desc }, - /* this one is dangerous, don't use yet */ - { MTAB_XTD|MTAB_VDV, 0, "LINES", "LINES", - NULL, &tmxr_show_lines, (void *) &vh_desc }, - { UNIT_ATT, UNIT_ATT, "summary", NULL, + &set_vec, &show_vec_mux, (void *) &vh_desc }, + { MTAB_XTD|MTAB_VDV, 0, NULL, "AUTOCONFIGURE", + &set_addr_flt, NULL, NULL }, + { MTAB_XTD|MTAB_VDV, 0, "LINES", "LINES", + &vh_setnl, &tmxr_show_lines, (void *) &vh_desc }, + { UNIT_ATT, UNIT_ATT, "summary", NULL, NULL, &tmxr_show_summ, (void *) &vh_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, - NULL, &tmxr_show_cstat, (void *) &vh_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, - NULL, &tmxr_show_cstat, (void *) &vh_desc }, - { MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT", - &tmxr_dscln, NULL, &vh_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "DEBUG", NULL, - NULL, &vh_show_debug, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "RBUF", NULL, - NULL, &vh_show_rbuf, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "TXQ", NULL, - NULL, &vh_show_txq, NULL }, - { 0 } + { MTAB_XTD|MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, + NULL, &tmxr_show_cstat, (void *) &vh_desc }, + { MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, + NULL, &tmxr_show_cstat, (void *) &vh_desc }, + { MTAB_XTD|MTAB_VDV, 1, NULL, "DISCONNECT", + &tmxr_dscln, NULL, &vh_desc }, + { MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "DETAIL", NULL, + NULL, &vh_show_detail, NULL }, + { MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "RBUF", NULL, + NULL, &vh_show_rbuf, NULL }, + { MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "TXQ", NULL, + NULL, &vh_show_txq, NULL }, + { MTAB_XTD|MTAB_VDV | MTAB_NC, 0, NULL, "LOG", + &vh_set_log, NULL, &vh_desc }, + { MTAB_XTD|MTAB_VDV | MTAB_NC, 0, NULL, "NOLOG", + &vh_set_nolog, NULL, &vh_desc }, + { MTAB_XTD|MTAB_VDV | MTAB_NMO, 0, "LOG", NULL, + NULL, &vh_show_log, &vh_desc }, + { 0 } }; DEVICE vh_dev = { - "VH", /* name */ - vh_unit, /* units */ - (REG *)vh_reg, /* registers */ - (MTAB *)vh_mod, /* modifiers */ - VH_MUXES, /* # units */ - DEV_RDX, /* address radix */ - 8, /* address width */ - 1, /* address increment */ - DEV_RDX, /* data radix */ - 8, /* data width */ - NULL, /* examine routine */ - NULL, /* deposit routine */ - &vh_reset, /* reset routine */ - NULL, /* boot routine */ - &vh_attach, /* attach routine */ - &vh_detach, /* detach routine */ - (void *)&vh_dib, /* context */ - DEV_FLTA | DEV_DISABLE | DEV_DIS |DEV_NET | DEV_QBUS | DEV_UBUS, /* flags */ + "VH", /* name */ + vh_unit, /* units */ + (REG *)vh_reg, /* registers */ + (MTAB *)vh_mod, /* modifiers */ + VH_MUXES, /* # units */ + DEV_RDX, /* address radix */ + 8, /* address width */ + 1, /* address increment */ + DEV_RDX, /* data radix */ + 8, /* data width */ + NULL, /* examine routine */ + NULL, /* deposit routine */ + &vh_reset, /* reset routine */ + NULL, /* boot routine */ + &vh_attach, /* attach routine */ + &vh_detach, /* detach routine */ + (void *)&vh_dib,/* context */ + DEV_FLTA | DEV_DISABLE | DEV_DIS |DEV_NET | DEV_QBUS | DEV_UBUS | DEV_DEBUG, /* flags */ + 0, vh_debug }; +/* Register names for Debug tracing */ +static char *vh_rd_dhv_regs[] = + {"CSR ", "RBUF ", "LPR ", "STAT ", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" }; +static char *vh_wr_dhv_regs[] = + {"CSR ", "TXCHAR", "LPR ", "STAT ", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" }; +static char *vh_rd_dhu_regs[] = + {"CSR ", "RBUF ", "LPR ", "FIFOSZ", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" }; +static char *vh_wr_dhu_regs[] = + {"CSR ", "RXTIMR", "LPR ", "FIFODT", "LNCTRL", "TBFAD1", "TBFAD2", "TBFCNT" }; + /* Interrupt routines */ -static void vh_clr_rxint ( int32 vh ) +static void vh_clr_rxint ( int32 vh ) { - vh_rxi &= ~(1 << vh); - if (vh_rxi == 0) - CLR_INT (VHRX); - else - SET_INT (VHRX); + vh_rxi &= ~(1 << vh); + if (vh_rxi == 0) + CLR_INT (VHRX); + else + SET_INT (VHRX); } -static void vh_set_rxint ( int32 vh ) +static void vh_set_rxint ( int32 vh ) { - vh_rxi |= (1 << vh); - SET_INT (VHRX); + vh_rxi |= (1 << vh); + SET_INT (VHRX); } /* RX interrupt ack. (bus cycle) */ static int32 vh_rxinta (void) { - int32 vh; + int32 vh; - for (vh = 0; vh < VH_MUXES; vh++) { - if (vh_rxi & (1 << vh)) { - vh_clr_rxint (vh); - return (vh_dib.vec + (vh * 010)); - } - } - return (0); + for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) { + if (vh_rxi & (1 << vh)) { + sim_debug(DBG_INT, &vh_dev, "vh_rzinta(vh=%d)\n", vh); + vh_clr_rxint (vh); + return (vh_dib.vec + (vh * 010)); + } + } + return (0); } -static void vh_clr_txint ( int32 vh ) +static void vh_clr_txint ( int32 vh ) { - vh_txi &= ~(1 << vh); - if (vh_txi == 0) - CLR_INT (VHTX); - else - SET_INT (VHTX); + vh_txi &= ~(1 << vh); + if (vh_txi == 0) + CLR_INT (VHTX); + else + SET_INT (VHTX); } -static void vh_set_txint ( int32 vh ) +static void vh_set_txint ( int32 vh ) { - vh_txi |= (1 << vh); - SET_INT (VHTX); + vh_txi |= (1 << vh); + SET_INT (VHTX); } /* TX interrupt ack. (bus cycle) */ static int32 vh_txinta (void) { - int32 vh; + int32 vh; - for (vh = 0; vh < VH_MUXES; vh++) { - if (vh_txi & (1 << vh)) { - vh_clr_txint (vh); - return (vh_dib.vec + 4 + (vh * 010)); - } - } - return (0); + for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) { + if (vh_txi & (1 << vh)) { + sim_debug(DBG_INT, &vh_dev, "vh_txinta(vh=%d)\n", vh); + vh_clr_txint (vh); + return (vh_dib.vec + 4 + (vh * 010)); + } + } + return (0); } /* RX FIFO get/put routines */ /* return 0 on success, -1 on FIFO overflow */ -static int32 fifo_put ( int32 vh, - TMLX *lp, - int32 data ) +static int32 fifo_put ( int32 vh, + TMLX *lp, + int32 data ) { - int32 status = 0; + int32 status = 0; - if (lp == NULL) - goto override; - /* this might have to move to vh_getc() */ - if ((lp->lnctrl & LNCTRL_OAUTO) && ((data & RBUF_DIAG) == 0)) { - TMLX *l0p; - /* implement transmitted data flow control */ - switch (data & 0377) { - case XON: - lp->tbuf2 |= TB2_TX_ENA; - goto common; - case XOFF: - lp->tbuf2 &= ~TB2_TX_ENA; - common: - /* find line 0 for this controller */ - l0p = &vh_parm[vh * VH_LINES]; - if (l0p->lpr & LPR_DISAB_XRPT) - return (0); - break; - default: - break; - } - } + if (lp == NULL) + goto override; + /* this might have to move to vh_getc() */ + if ((lp->lnctrl & LNCTRL_OAUTO) && ((data & RBUF_DIAG) == 0)) { + TMLX *l0p; + /* implement transmitted data flow control */ + switch (data & 0377) { + case XON: + lp->tbuf2 |= TB2_TX_ENA; + goto common; + case XOFF: + lp->tbuf2 &= ~TB2_TX_ENA; + common: + /* find line 0 for this controller */ + l0p = &vh_parm[vh * VH_LINES]; + if (l0p->lpr & LPR_DISAB_XRPT) + return (0); + break; + default: + break; + } + } /* BUG: which of the following 2 is correct? */ - /* if ((data & RBUF_DIAG) == RBUF_DIAG) */ - if (data & RBUF_DIAG) - goto override; - if (((lp->lnctrl >> LNCTRL_V_MAINT) & LNCTRL_M_MAINT) == 2) - goto override; - if (!(lp->lnctrl & LNCTRL_RX_ENA)) - return (0); + /* if ((data & RBUF_DIAG) == RBUF_DIAG) */ + if (data & RBUF_DIAG) + goto override; + if (((lp->lnctrl >> LNCTRL_V_MAINT) & LNCTRL_M_MAINT) == 2) + goto override; + if (!(lp->lnctrl & LNCTRL_RX_ENA)) + return (0); override: - vh_csr[vh] |= CSR_RX_DATA_AVAIL; - if (rbuf_idx[vh] < FIFO_SIZE) { - vh_rbuf[vh][rbuf_idx[vh]] = data; - rbuf_idx[vh] += 1; - } else { - vh_ovrrun[vh] |= (1 << RBUF_GETLINE (data)); - status = -1; - } - if (vh_csr[vh] & CSR_RXIE) { - if (vh_unit[vh].flags & UNIT_MODEDHU) { - /* was it a modem status change? */ - if ((data & RBUF_DIAG) == RBUF_DIAG) - vh_set_rxint (vh); - /* look for FIFO alarm @ 3/4 full */ - else if (rbuf_idx[vh] == FIFO_ALARM) - vh_set_rxint (vh); - else if (vh_timer[vh] == 0) - ; /* nothing, infinite timeout */ - else if (vh_timer[vh] == 1) - vh_set_rxint (vh); - else if (vh_timeo[vh] == 0) - vh_timeo[vh] = MS2SIMH (vh_timer[vh]) + 1; - } else { - /* Interrupt on transition _from_ an empty FIFO */ - if (rbuf_idx[vh] == 1) - vh_set_rxint (vh); - } - } - if (rbuf_idx[vh] > FIFO_ALARM) - vh_crit |= (1 << vh); - /* Implement RX FIFO-level flow control */ - if (lp != NULL) { - if ((lp->lnctrl & LNCTRL_FORCE_XOFF) || - ((vh_crit & (1 << vh)) && (lp->lnctrl & LNCTRL_IAUTO))) { - int32 chan = RBUF_GETLINE(data); - vh_stall[vh] ^= (1 << chan); - /* send XOFF every other character received */ - if (vh_stall[vh] & (1 << chan)) - vh_putc (vh, lp, chan, XOFF); - } - } - return (status); + vh_csr[vh] |= CSR_RX_DATA_AVAIL; + if (rbuf_idx[vh] < FIFO_SIZE) { + vh_rbuf[vh][rbuf_idx[vh]] = data; + rbuf_idx[vh] += 1; + } else { + vh_ovrrun[vh] |= (1 << RBUF_GETLINE (data)); + status = -1; + } + if (vh_csr[vh] & CSR_RXIE) { + if (vh_unit[vh].flags & UNIT_MODEDHU) { + /* was it a modem status change? */ + if ((data & RBUF_DIAG) == RBUF_DIAG) + vh_set_rxint (vh); + /* look for FIFO alarm @ 3/4 full */ + else if (rbuf_idx[vh] == FIFO_ALARM) + vh_set_rxint (vh); + else if (vh_timer[vh] == 0) + ; /* nothing, infinite timeout */ + else if (vh_timer[vh] == 1) + vh_set_rxint (vh); + else if (vh_timeo[vh] == 0) + vh_timeo[vh] = MS2SIMH (vh_timer[vh]) + 1; + } else { + /* Interrupt on transition _from_ an empty FIFO */ + if (rbuf_idx[vh] == 1) + vh_set_rxint (vh); + } + } + if (rbuf_idx[vh] > FIFO_ALARM) + vh_crit |= (1 << vh); + /* Implement RX FIFO-level flow control */ + if (lp != NULL) { + if ((lp->lnctrl & LNCTRL_FORCE_XOFF) || + ((vh_crit & (1 << vh)) && (lp->lnctrl & LNCTRL_IAUTO))) { + int32 chan = RBUF_GETLINE(data); + vh_stall[vh] ^= (1 << chan); + /* send XOFF every other character received */ + if (vh_stall[vh] & (1 << chan)) + vh_putc (vh, lp, chan, XOFF); + } + } + return (status); } -static int32 fifo_get ( int32 vh ) +static int32 fifo_get ( int32 vh ) { - int32 data, i; + int32 data, i; - if (rbuf_idx[vh] == 0) { - vh_csr[vh] &= ~CSR_RX_DATA_AVAIL; - return (0); - } - /* pick off the first character, mark valid */ - data = vh_rbuf[vh][0] | RBUF_DATA_VALID; - /* move the remainder up */ - rbuf_idx[vh] -= 1; - for (i = 0; i < rbuf_idx[vh]; i++) - vh_rbuf[vh][i] = vh_rbuf[vh][i + 1]; - /* rbuf_idx[vh] -= 1; */ - /* look for any previous overruns */ - if (vh_ovrrun[vh]) { - for (i = 0; i < VH_LINES; i++) { - if (vh_ovrrun[vh] & (1 << i)) { - fifo_put (vh, NULL, RBUF_OVERRUN_ERR | - RBUF_PUTLINE (i)); - vh_ovrrun[vh] &= ~(1 << i); - break; - } - } - } - /* recompute FIFO alarm condition */ - if ((rbuf_idx[vh] < FIFO_HALF) && (vh_crit & (1 << vh))) { - vh_crit &= ~(1 << vh); - /* send XON to all XOFF'd channels on this controller */ - for (i = 0; i < VH_LINES; i++) { - TMLX *lp = &vh_parm[(vh * VH_LINES) + i]; - if (lp->lnctrl & LNCTRL_FORCE_XOFF) - continue; - if (vh_stall[vh] & (1 << i)) { - vh_putc (vh, NULL, i, XON); - vh_stall[vh] &= ~(1 << i); - } - } - } - return (data & 0177777); + if (rbuf_idx[vh] == 0) { + vh_csr[vh] &= ~CSR_RX_DATA_AVAIL; + return (0); + } + /* pick off the first character, mark valid */ + data = vh_rbuf[vh][0] | RBUF_DATA_VALID; + /* move the remainder up */ + rbuf_idx[vh] -= 1; + for (i = 0; i < rbuf_idx[vh]; i++) + vh_rbuf[vh][i] = vh_rbuf[vh][i + 1]; + /* rbuf_idx[vh] -= 1; */ + /* look for any previous overruns */ + if (vh_ovrrun[vh]) { + for (i = 0; i < VH_LINES; i++) { + if (vh_ovrrun[vh] & (1 << i)) { + fifo_put (vh, NULL, RBUF_OVERRUN_ERR | + RBUF_PUTLINE (i)); + vh_ovrrun[vh] &= ~(1 << i); + break; + } + } + } + /* recompute FIFO alarm condition */ + if ((rbuf_idx[vh] < FIFO_HALF) && (vh_crit & (1 << vh))) { + vh_crit &= ~(1 << vh); + /* send XON to all XOFF'd channels on this controller */ + for (i = 0; i < VH_LINES; i++) { + TMLX *lp = &vh_parm[(vh * VH_LINES) + i]; + if (lp->lnctrl & LNCTRL_FORCE_XOFF) + continue; + if (vh_stall[vh] & (1 << i)) { + vh_putc (vh, NULL, i, XON); + vh_stall[vh] &= ~(1 << i); + } + } + } + return (data & 0177777); } /* TX Q manipulation */ -static int32 dq_tx_report ( int32 vh ) +static int32 dq_tx_report ( int32 vh ) { - int32 data, i; + int32 data, i; - if (txq_idx[vh] == 0) - return (0); - data = vh_txq[vh][0]; - txq_idx[vh] -= 1; - for (i = 0; i < txq_idx[vh]; i++) - vh_txq[vh][i] = vh_txq[vh][i + 1]; - /* txq_idx[vh] -= 1; */ - return (data & 0177777); + if (txq_idx[vh] == 0) + return (0); + data = vh_txq[vh][0]; + txq_idx[vh] -= 1; + for (i = 0; i < txq_idx[vh]; i++) + vh_txq[vh][i] = vh_txq[vh][i + 1]; + /* txq_idx[vh] -= 1; */ + return (data & 0177777); } -static void q_tx_report ( int32 vh, - int32 data ) +static void q_tx_report ( int32 vh, + int32 data ) { - if (vh_csr[vh] & CSR_TXIE) - vh_set_txint (vh); - if (txq_idx[vh] >= TXQ_SIZE) { + if (vh_csr[vh] & CSR_TXIE) + vh_set_txint (vh); + if (txq_idx[vh] >= TXQ_SIZE) { /* BUG: which of the following 2 is correct? */ - dq_tx_report (vh); - /* return; */ - } - vh_txq[vh][txq_idx[vh]] = CSR_TX_ACTION | data; - txq_idx[vh] += 1; + dq_tx_report (vh); + /* return; */ + } + vh_txq[vh][txq_idx[vh]] = CSR_TX_ACTION | data; + txq_idx[vh] += 1; } /* Channel get/put routines */ -static void HangupModem ( int32 vh, - TMLX *lp, - int32 chan ) +static void HangupModem ( int32 vh, + TMLX *lp, + int32 chan ) { - if (vh_unit[vh].flags & UNIT_MODEM) - lp->lstat &= ~(STAT_DCD|STAT_DSR|STAT_CTS|STAT_RI); - if (lp->lnctrl & LNCTRL_LINK_TYPE) - /* RBUF<0> = 0 for modem status */ - fifo_put (vh, lp, RBUF_DIAG | - RBUF_PUTLINE (chan) | - ((lp->lstat >> 8) & 0376)); - /* BUG: check for overflow above */ + if (vh_unit[vh].flags & UNIT_MODEM) + lp->lstat &= ~(STAT_DCD|STAT_DSR|STAT_CTS|STAT_RI); + if (lp->lnctrl & LNCTRL_LINK_TYPE) + /* RBUF<0> = 0 for modem status */ + fifo_put (vh, lp, RBUF_DIAG | + RBUF_PUTLINE (chan) | + ((lp->lstat >> 8) & 0376)); + /* BUG: check for overflow above */ } /* TX a character on a line, regardless of the TX enable state */ -static t_stat vh_putc ( int32 vh, - TMLX *lp, - int32 chan, - int32 data ) +static t_stat vh_putc ( int32 vh, + TMLX *lp, + int32 chan, + int32 data ) { - int32 val; - t_stat status = SCPE_OK; + int32 val; + t_stat status = SCPE_OK; - /* truncate to desired character length */ - data &= bitmask[(lp->lpr >> LPR_V_CHAR_LGTH) & LPR_M_CHAR_LGTH]; - switch ((lp->lnctrl >> LNCTRL_V_MAINT) & LNCTRL_M_MAINT) { - case 0: /* normal */ -#if 0 - /* check for (external) loopback setting */ - switch (vh_loop[vh]) { - default: - case LOOP_NONE: - break; - } + /* truncate to desired character length */ + data &= bitmask[(lp->lpr >> LPR_V_CHAR_LGTH) & LPR_M_CHAR_LGTH]; + switch ((lp->lnctrl >> LNCTRL_V_MAINT) & LNCTRL_M_MAINT) { + case 0: /* normal */ +#if 0 + /* check for (external) loopback setting */ + switch (vh_loop[vh]) { + default: + case LOOP_NONE: + break; + } #endif - status = tmxr_putc_ln (lp->tmln, data); - if (status == SCPE_LOST) { - tmxr_reset_ln (lp->tmln); - HangupModem (vh, lp, chan); - } else if (status == SCPE_STALL) { - /* let's flush and try again */ - tmxr_send_buffered_data (lp->tmln); - status = tmxr_putc_ln (lp->tmln, data); - } - break; - case 1: /* auto echo */ - break; - case 2: /* local loopback */ - if (lp->lnctrl & LNCTRL_BREAK) - val = fifo_put (vh, lp, - RBUF_FRAME_ERR | RBUF_PUTLINE (chan)); - else - val = fifo_put (vh, lp, - RBUF_PUTLINE (chan) | data); - status = (val < 0) ? SCPE_TTMO : SCPE_OK; - break; - default: /* remote loopback */ - break; - } - return (status); + status = tmxr_putc_ln (lp->tmln, data); + if (status == SCPE_LOST) { + tmxr_reset_ln (lp->tmln); + HangupModem (vh, lp, chan); + } else if (status == SCPE_STALL) { + /* let's flush and try again */ + tmxr_send_buffered_data (lp->tmln); + status = tmxr_putc_ln (lp->tmln, data); + } + break; + case 1: /* auto echo */ + break; + case 2: /* local loopback */ + if (lp->lnctrl & LNCTRL_BREAK) + val = fifo_put (vh, lp, + RBUF_FRAME_ERR | RBUF_PUTLINE (chan)); + else + val = fifo_put (vh, lp, + RBUF_PUTLINE (chan) | data); + status = (val < 0) ? SCPE_TTMO : SCPE_OK; + break; + default: /* remote loopback */ + break; + } + return (status); } /* Retrieve all stored input from TMXR and place in RX FIFO */ -static void vh_getc ( int32 vh ) +static void vh_getc ( int32 vh ) { - uint32 i, c; - TMLX *lp; + uint32 i, c; + TMLX *lp; - for (i = 0; i < VH_LINES; i++) { - lp = &vh_parm[(vh * VH_LINES) + i]; - while ((c = tmxr_getc_ln (lp->tmln)) != 0) { - if (c & SCPE_BREAK) { - fifo_put (vh, lp, - RBUF_FRAME_ERR | RBUF_PUTLINE (i)); - /* BUG: check for overflow above */ - } else { - c &= bitmask[(lp->lpr >> LPR_V_CHAR_LGTH) & - LPR_M_CHAR_LGTH]; - fifo_put (vh, lp, RBUF_PUTLINE (i) | c); - /* BUG: check for overflow above */ - } - } - } + for (i = 0; i < VH_LINES; i++) { + lp = &vh_parm[(vh * VH_LINES) + i]; + while ((c = tmxr_getc_ln (lp->tmln)) != 0) { + if (c & SCPE_BREAK) { + fifo_put (vh, lp, + RBUF_FRAME_ERR | RBUF_PUTLINE (i)); + /* BUG: check for overflow above */ + } else { + c &= bitmask[(lp->lpr >> LPR_V_CHAR_LGTH) & + LPR_M_CHAR_LGTH]; + fifo_put (vh, lp, RBUF_PUTLINE (i) | c); + /* BUG: check for overflow above */ + } + } + } } /* I/O dispatch routines */ -static t_stat vh_rd ( int32 *data, - int32 PA, - int32 access ) +static t_stat vh_rd ( int32 *data, + int32 PA, + int32 access ) { - int32 vh = ((PA - vh_dib.ba) >> 4) & VH_MNOMASK, line; - TMLX *lp; + int32 vh = ((PA - vh_dib.ba) >> 4) & VH_MNOMASK, line; + TMLX *lp; - switch ((PA >> 1) & 7) { - case 0: /* CSR */ - *data = vh_csr[vh] | dq_tx_report (vh); - vh_csr[vh] &= ~0117400; /* clear the read-once bits */ - break; - case 1: /* RBUF */ - *data = fifo_get (vh); - break; - case 2: /* LPR */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { - *data = 0; - break; - } - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - *data = lp->lpr; - break; - case 3: /* STAT/FIFOSIZE */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { - *data = 0; - break; - } - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - *data = (lp->lstat & ~0377) | /* modem status */ -#if 0 - (64 - tmxr_tqln (lp->tmln)); + switch ((PA >> 1) & 7) { + case 0: /* CSR */ + *data = vh_csr[vh] | dq_tx_report (vh); + vh_csr[vh] &= ~0117400; /* clear the read-once bits */ + break; + case 1: /* RBUF */ + *data = fifo_get (vh); + break; + case 2: /* LPR */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { + *data = 0; + break; + } + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + *data = lp->lpr; + break; + case 3: /* STAT/FIFOSIZE */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { + *data = 0; + break; + } + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + *data = (lp->lstat & ~0377) | /* modem status */ +#if 0 + (64 - tmxr_tqln (lp->tmln)); fprintf (stderr, "\rtqln %d\n", 64 - tmxr_tqln (lp->tmln)); #else - 64; + 64; #endif - break; - case 4: /* LNCTRL */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { - *data = 0; - break; - } - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - *data = lp->lnctrl; - break; - case 5: /* TBUFFAD1 */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { - *data = 0; - break; - } - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - *data = lp->tbuf1; - break; - case 6: /* TBUFFAD2 */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { - *data = 0; - break; - } - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - *data = lp->tbuf2; - break; - case 7: /* TBUFFCT */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { - *data = 0; - break; - } - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - *data = lp->tbuffct; - break; - default: - /* can't happen */ - break; - } - return (SCPE_OK); + break; + case 4: /* LNCTRL */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { + *data = 0; + break; + } + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + *data = lp->lnctrl; + break; + case 5: /* TBUFFAD1 */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { + *data = 0; + break; + } + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + *data = lp->tbuf1; + break; + case 6: /* TBUFFAD2 */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { + *data = 0; + break; + } + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + *data = lp->tbuf2; + break; + case 7: /* TBUFFCT */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) { + *data = 0; + break; + } + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + *data = lp->tbuffct; + break; + default: + /* can't happen */ + break; + } + + sim_debug(DBG_REG, &vh_dev, "vh_rd(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, + ((vh_unit[vh].flags & UNIT_MODEDHU) ? vh_rd_dhu_regs : vh_rd_dhv_regs)[(PA >> 1) & 07], access, data); + + return (SCPE_OK); } -static t_stat vh_wr ( int32 data, - int32 PA, - int32 access ) +static t_stat vh_wr ( int32 data, + int32 PA, + int32 access ) { - int32 vh = ((PA - vh_dib.ba) >> 4) & VH_MNOMASK, line; - TMLX *lp; + int32 vh = ((PA - vh_dib.ba) >> 4) & VH_MNOMASK, line; + TMLX *lp; - switch ((PA >> 1) & 7) { - case 0: /* CSR, but no read-modify-write */ - if (access == WRITEB) - data = (PA & 1) ? - (vh_csr[vh] & 0377) | (data << 8) : - (vh_csr[vh] & ~0377) | (data & 0377); - if (data & CSR_MASTER_RESET) { - if ((vh_unit[vh].flags & UNIT_MODEDHU) && (data & CSR_SKIP)) - data &= ~CSR_MASTER_RESET; - sim_activate (&vh_unit[vh], clk_cosched (tmxr_poll)); - /* vh_mcount[vh] = 72; */ /* 1.2 seconds */ - vh_mcount[vh] = MS2SIMH (1200); /* 1.2 seconds */ - } - if ((data & CSR_RXIE) == 0) - vh_clr_rxint (vh); - /* catch the RXIE transition if the FIFO is not empty */ - else if (((vh_csr[vh] & CSR_RXIE) == 0) && - (rbuf_idx[vh] != 0)) { - if (vh_unit[vh].flags & UNIT_MODEDHU) { - if (rbuf_idx[vh] > FIFO_ALARM) - vh_set_rxint (vh); - else if (vh_timer[vh] == 0) - ; - else if (vh_timer[vh] == 1) - vh_set_rxint (vh); - else if (vh_timeo[vh] == 0) - vh_timeo[vh] = MS2SIMH (vh_timer[vh]) + 1; - } else { - vh_set_rxint (vh); - } - } - if ((data & CSR_TXIE) == 0) - vh_clr_txint (vh); - else if (((vh_csr[vh] & CSR_TXIE) == 0) && - (txq_idx[vh] != 0)) - vh_set_txint (vh); - vh_csr[vh] = (vh_csr[vh] & ~((uint16) CSR_RW)) | (data & (uint16) CSR_RW); - break; - case 1: /* TXCHAR/RXTIMER */ - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (vh_unit[vh].flags & UNIT_MODEDHU) { - if (CSR_GETCHAN (vh_csr[vh]) != 0) - break; - if (access == WRITEB) - data = (PA & 1) ? - (vh_timer[vh] & 0377) | (data << 8) : - (vh_timer[vh] & ~0377) | (data & 0377); - vh_timer[vh] = data & 0377; -#if 0 - if (vh_csr[vh] & CSR_RXIE) { - if (rbuf_idx[vh] > FIFO_ALARM) - vh_set_rxint (vh); - else if (vh_timer[vh] == 0) - ; - else if (vh_timer[vh] == 1) - vh_set_rxint (vh); - else if (vh_timeo[vh] == 0) - vh_timeo[vh] = MS2SIMH (vh_timer[vh]) + 1; - } + sim_debug(DBG_REG, &vh_dev, "vh_wr(PA=0x%08X [%s], access=%d, data=0x%X)\n", PA, + ((vh_unit[vh].flags & UNIT_MODEDHU) ? vh_wr_dhu_regs : vh_wr_dhv_regs)[(PA >> 1) & 07], access, data); + + switch ((PA >> 1) & 7) { + case 0: /* CSR, but no read-modify-write */ + if (access == WRITEB) + data = (PA & 1) ? + (vh_csr[vh] & 0377) | (data << 8) : + (vh_csr[vh] & ~0377) | (data & 0377); + if (data & CSR_MASTER_RESET) { + if ((vh_unit[vh].flags & UNIT_MODEDHU) && (data & CSR_SKIP)) + data &= ~CSR_MASTER_RESET; + if (vh == 0) /* Only start unit service on the first unit. Units are polled there */ + sim_activate (&vh_unit[vh], clk_cosched (tmxr_poll)); + /* vh_mcount[vh] = 72; */ /* 1.2 seconds */ + vh_mcount[vh] = MS2SIMH (1200); /* 1.2 seconds */ + } + if ((data & CSR_RXIE) == 0) + vh_clr_rxint (vh); + /* catch the RXIE transition if the FIFO is not empty */ + else if (((vh_csr[vh] & CSR_RXIE) == 0) && + (rbuf_idx[vh] != 0)) { + if (vh_unit[vh].flags & UNIT_MODEDHU) { + if (rbuf_idx[vh] > FIFO_ALARM) + vh_set_rxint (vh); + else if (vh_timer[vh] == 0) + ; + else if (vh_timer[vh] == 1) + vh_set_rxint (vh); + else if (vh_timeo[vh] == 0) + vh_timeo[vh] = MS2SIMH (vh_timer[vh]) + 1; + } else { + vh_set_rxint (vh); + } + } + if ((data & CSR_TXIE) == 0) + vh_clr_txint (vh); + else if (((vh_csr[vh] & CSR_TXIE) == 0) && + (txq_idx[vh] != 0)) + vh_set_txint (vh); + vh_csr[vh] = (vh_csr[vh] & ~((uint16) CSR_RW)) | (data & (uint16) CSR_RW); + break; + case 1: /* TXCHAR/RXTIMER */ + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (vh_unit[vh].flags & UNIT_MODEDHU) { + if (CSR_GETCHAN (vh_csr[vh]) != 0) + break; + if (access == WRITEB) + data = (PA & 1) ? + (vh_timer[vh] & 0377) | (data << 8) : + (vh_timer[vh] & ~0377) | (data & 0377); + vh_timer[vh] = data & 0377; +#if 0 + if (vh_csr[vh] & CSR_RXIE) { + if (rbuf_idx[vh] > FIFO_ALARM) + vh_set_rxint (vh); + else if (vh_timer[vh] == 0) + ; + else if (vh_timer[vh] == 1) + vh_set_rxint (vh); + else if (vh_timeo[vh] == 0) + vh_timeo[vh] = MS2SIMH (vh_timer[vh]) + 1; + } #endif - } else { - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (access == WRITEB) - data = (PA & 1) ? - (lp->txchar & 0377) | (data << 8) : - (lp->txchar & ~0377) | (data & 0377); - lp->txchar = data; /* TXCHAR */ - if (lp->txchar & TXCHAR_TX_DATA_VALID) { - if (lp->tbuf2 & TB2_TX_ENA) - vh_putc (vh, lp, - CSR_GETCHAN (vh_csr[vh]), - lp->txchar); - q_tx_report (vh, - CSR_GETCHAN (vh_csr[vh]) << CSR_V_TX_LINE); - lp->txchar &= ~TXCHAR_TX_DATA_VALID; - } - } - break; - case 2: /* LPR */ - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (access == WRITEB) - data = (PA & 1) ? - (lp->lpr & 0377) | (data << 8) : - (lp->lpr & ~0377) | (data & 0377); - /* Modify only if CSR<3:0> == 0 */ - if (CSR_GETCHAN (vh_csr[vh]) != 0) - data &= ~LPR_DISAB_XRPT; - lp->lpr = data; - if (((lp->lpr >> LPR_V_DIAG) & LPR_M_DIAG) == 1) { - fifo_put (vh, lp, - RBUF_DIAG | - RBUF_PUTLINE (CSR_GETCHAN (vh_csr[vh])) | - BMP_OK); - /* BUG: check for overflow above */ - lp->lpr &= ~(LPR_M_DIAG << LPR_V_DIAG); - } - break; - case 3: /* STAT/FIFODATA */ - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (vh_unit[vh].flags & UNIT_MODEDHU) { - /* high byte writes not allowed */ - if (PA & 1) - break; - /* transmit 1 or 2 characters */ - if (!(lp->tbuf2 & TB2_TX_ENA)) - break; - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), data); - q_tx_report (vh, CSR_GETCHAN (vh_csr[vh]) << CSR_V_TX_LINE); - if (access != WRITEB) - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), - data >> 8); - } - break; - case 4: /* LNCTRL */ - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (access == WRITEB) - data = (PA & 1) ? - (lp->lnctrl & 0377) | (data << 8) : - (lp->lnctrl & ~0377) | (data & 0377); - /* catch the abort TX transition */ - if (!(lp->lnctrl & LNCTRL_TX_ABORT) && - (data & LNCTRL_TX_ABORT)) { - if ((lp->tbuf2 & TB2_TX_ENA) && - (lp->tbuf2 & TB2_TX_DMA_START)) { - lp->tbuf2 &= ~TB2_TX_DMA_START; - q_tx_report (vh, CSR_GETCHAN (vh_csr[vh]) << CSR_V_TX_LINE); - } - } - /* Implement program-initiated flow control */ - if ( (data & LNCTRL_FORCE_XOFF) && - !(lp->lnctrl & LNCTRL_FORCE_XOFF) ) { - if (!(lp->lnctrl & LNCTRL_IAUTO)) - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XOFF); - } else if ( !(data & LNCTRL_FORCE_XOFF) && - (lp->lnctrl & LNCTRL_FORCE_XOFF) ) { - if (!(lp->lnctrl & LNCTRL_IAUTO)) - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XON); - else if (!(vh_crit & (1 << vh)) && - (vh_stall[vh] & (1 << CSR_GETCHAN (vh_csr[vh])))) - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XON); - } - if ( (data & LNCTRL_IAUTO) && /* IAUTO 0->1 */ - !(lp->lnctrl & LNCTRL_IAUTO) ) { - if (!(lp->lnctrl & LNCTRL_FORCE_XOFF)) { - if (vh_crit & (1 << vh)) { - vh_putc (vh, lp, - CSR_GETCHAN (vh_csr[vh]), XOFF); - vh_stall[vh] |= (1 << CSR_GETCHAN (vh_csr[vh])); - } - } else { - /* vh_stall[vh] |= (1 << CSR_GETCHAN (vh_csr[vh])) */; - } - } else if ( !(data & LNCTRL_IAUTO) && - (lp->lnctrl & LNCTRL_IAUTO) ) { - if (!(lp->lnctrl & LNCTRL_FORCE_XOFF)) - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XON); - } - /* check modem control bits */ - if ( !(data & LNCTRL_DTR) && /* DTR 1->0 */ - (lp->lnctrl & LNCTRL_DTR)) { - if ((lp->tmln->conn) && (vh_unit[vh].flags & UNIT_HANGUP)) { - tmxr_linemsg (lp->tmln, "\r\nLine hangup\r\n"); - tmxr_reset_ln (lp->tmln); - } - HangupModem (vh, lp, CSR_GETCHAN (vh_csr[vh])); - } - lp->lnctrl = data; - lp->tmln->rcve = (data & LNCTRL_RX_ENA) ? 1 : 0; - tmxr_poll_rx (&vh_desc); - vh_getc (vh); - if (lp->lnctrl & LNCTRL_BREAK) - vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), 0); - break; - case 5: /* TBUFFAD1 */ - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (access == WRITEB) - data = (PA & 1) ? - (lp->tbuf1 & 0377) | (data << 8) : - (lp->tbuf1 & ~0377) | (data & 0377); - lp->tbuf1 = data; - break; - case 6: /* TBUFFAD2 */ - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (access == WRITEB) - data = (PA & 1) ? - (lp->tbuf2 & 0377) | (data << 8) : - (lp->tbuf2 & ~0377) | (data & 0377); - lp->tbuf2 = data; - /* if starting a DMA, clear DMA_ERR */ - if (vh_unit[vh].flags & UNIT_FASTDMA) { - doDMA (vh, CSR_GETCHAN (vh_csr[vh])); - tmxr_send_buffered_data (lp->tmln); - } - break; - case 7: /* TBUFFCT */ - if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { - vh_mcount[vh] = 1; - break; - } - if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) - break; - line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); - lp = &vh_parm[line]; - if (access == WRITEB) - data = (PA & 1) ? - (lp->tbuffct & 0377) | (data << 8) : - (lp->tbuffct & ~0377) | (data & 0377); - lp->tbuffct = data; - break; - default: - /* can't happen */ - break; - } - return (SCPE_OK); + } else { + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (access == WRITEB) + data = (PA & 1) ? + (lp->txchar & 0377) | (data << 8) : + (lp->txchar & ~0377) | (data & 0377); + lp->txchar = data; /* TXCHAR */ + if (lp->txchar & TXCHAR_TX_DATA_VALID) { + if (lp->tbuf2 & TB2_TX_ENA) + vh_putc (vh, lp, + CSR_GETCHAN (vh_csr[vh]), + lp->txchar); + q_tx_report (vh, + CSR_GETCHAN (vh_csr[vh]) << CSR_V_TX_LINE); + lp->txchar &= ~TXCHAR_TX_DATA_VALID; + } + } + break; + case 2: /* LPR */ + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (access == WRITEB) + data = (PA & 1) ? + (lp->lpr & 0377) | (data << 8) : + (lp->lpr & ~0377) | (data & 0377); + /* Modify only if CSR<3:0> == 0 */ + if (CSR_GETCHAN (vh_csr[vh]) != 0) + data &= ~LPR_DISAB_XRPT; + lp->lpr = data; + if (((lp->lpr >> LPR_V_DIAG) & LPR_M_DIAG) == 1) { + fifo_put (vh, lp, + RBUF_DIAG | + RBUF_PUTLINE (CSR_GETCHAN (vh_csr[vh])) | + BMP_OK); + /* BUG: check for overflow above */ + lp->lpr &= ~(LPR_M_DIAG << LPR_V_DIAG); + } + break; + case 3: /* STAT/FIFODATA */ + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (vh_unit[vh].flags & UNIT_MODEDHU) { + /* high byte writes not allowed */ + if (PA & 1) + break; + /* transmit 1 or 2 characters */ + if (!(lp->tbuf2 & TB2_TX_ENA)) + break; + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), data); + q_tx_report (vh, CSR_GETCHAN (vh_csr[vh]) << CSR_V_TX_LINE); + if (access != WRITEB) + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), + data >> 8); + } + break; + case 4: /* LNCTRL */ + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (access == WRITEB) + data = (PA & 1) ? + (lp->lnctrl & 0377) | (data << 8) : + (lp->lnctrl & ~0377) | (data & 0377); + /* catch the abort TX transition */ + if (!(lp->lnctrl & LNCTRL_TX_ABORT) && + (data & LNCTRL_TX_ABORT)) { + if ((lp->tbuf2 & TB2_TX_ENA) && + (lp->tbuf2 & TB2_TX_DMA_START)) { + lp->tbuf2 &= ~TB2_TX_DMA_START; + q_tx_report (vh, CSR_GETCHAN (vh_csr[vh]) << CSR_V_TX_LINE); + } + } + /* Implement program-initiated flow control */ + if ( (data & LNCTRL_FORCE_XOFF) && + !(lp->lnctrl & LNCTRL_FORCE_XOFF) ) { + if (!(lp->lnctrl & LNCTRL_IAUTO)) + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XOFF); + } else if ( !(data & LNCTRL_FORCE_XOFF) && + (lp->lnctrl & LNCTRL_FORCE_XOFF) ) { + if (!(lp->lnctrl & LNCTRL_IAUTO)) + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XON); + else if (!(vh_crit & (1 << vh)) && + (vh_stall[vh] & (1 << CSR_GETCHAN (vh_csr[vh])))) + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XON); + } + if ( (data & LNCTRL_IAUTO) && /* IAUTO 0->1 */ + !(lp->lnctrl & LNCTRL_IAUTO) ) { + if (!(lp->lnctrl & LNCTRL_FORCE_XOFF)) { + if (vh_crit & (1 << vh)) { + vh_putc (vh, lp, + CSR_GETCHAN (vh_csr[vh]), XOFF); + vh_stall[vh] |= (1 << CSR_GETCHAN (vh_csr[vh])); + } + } else { + /* vh_stall[vh] |= (1 << CSR_GETCHAN (vh_csr[vh])) */; + } + } else if ( !(data & LNCTRL_IAUTO) && + (lp->lnctrl & LNCTRL_IAUTO) ) { + if (!(lp->lnctrl & LNCTRL_FORCE_XOFF)) + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), XON); + } + /* check modem control bits */ + if ( !(data & LNCTRL_DTR) && /* DTR 1->0 */ + (lp->lnctrl & LNCTRL_DTR)) { + if ((lp->tmln->conn) && (vh_unit[vh].flags & UNIT_HANGUP)) { + tmxr_linemsg (lp->tmln, "\r\nLine hangup\r\n"); + tmxr_reset_ln (lp->tmln); + } + HangupModem (vh, lp, CSR_GETCHAN (vh_csr[vh])); + } + lp->lnctrl = data; + lp->tmln->rcve = (data & LNCTRL_RX_ENA) ? 1 : 0; + tmxr_poll_rx (&vh_desc); + vh_getc (vh); + if (lp->lnctrl & LNCTRL_BREAK) + vh_putc (vh, lp, CSR_GETCHAN (vh_csr[vh]), 0); + break; + case 5: /* TBUFFAD1 */ + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (access == WRITEB) + data = (PA & 1) ? + (lp->tbuf1 & 0377) | (data << 8) : + (lp->tbuf1 & ~0377) | (data & 0377); + lp->tbuf1 = data; + break; + case 6: /* TBUFFAD2 */ + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (access == WRITEB) + data = (PA & 1) ? + (lp->tbuf2 & 0377) | (data << 8) : + (lp->tbuf2 & ~0377) | (data & 0377); + lp->tbuf2 = data; + /* if starting a DMA, clear DMA_ERR */ + if (vh_unit[vh].flags & UNIT_FASTDMA) { + doDMA (vh, CSR_GETCHAN (vh_csr[vh])); + tmxr_send_buffered_data (lp->tmln); + } + break; + case 7: /* TBUFFCT */ + if ((data == RESET_ABORT) && (vh_csr[vh] & CSR_MASTER_RESET)) { + vh_mcount[vh] = 1; + break; + } + if (CSR_GETCHAN (vh_csr[vh]) >= VH_LINES) + break; + line = (vh * VH_LINES) + CSR_GETCHAN (vh_csr[vh]); + lp = &vh_parm[line]; + if (access == WRITEB) + data = (PA & 1) ? + (lp->tbuffct & 0377) | (data << 8) : + (lp->tbuffct & ~0377) | (data & 0377); + lp->tbuffct = data; + break; + default: + /* can't happen */ + break; + } + return (SCPE_OK); } -static void doDMA ( int32 vh, - int32 chan ) +static void doDMA ( int32 vh, + int32 chan ) { - int32 line, status; - uint32 pa; - TMLX *lp; + int32 line, status; + uint32 pa; + TMLX *lp; - line = (vh * VH_LINES) + chan; - lp = &vh_parm[line]; - if ((lp->tbuf2 & TB2_TX_ENA) && (lp->tbuf2 & TB2_TX_DMA_START)) { + line = (vh * VH_LINES) + chan; + lp = &vh_parm[line]; + if ((lp->tbuf2 & TB2_TX_ENA) && (lp->tbuf2 & TB2_TX_DMA_START)) { /* BUG: should compare against available xmit buffer space */ - pa = lp->tbuf1; - pa |= (lp->tbuf2 & TB2_M_TBUFFAD) << 16; - status = chan << CSR_V_TX_LINE; - while (lp->tbuffct) { - uint8 buf; - if (Map_ReadB (pa, 1, &buf)) { - status |= CSR_TX_DMA_ERR; - lp->tbuffct = 0; - break; - } - if (vh_putc (vh, lp, chan, buf) != SCPE_OK) - break; - /* pa = (pa + 1) & PAMASK; */ - pa = (pa + 1) & ((1 << 22) - 1); - lp->tbuffct--; - } - lp->tbuf1 = pa & 0177777; - lp->tbuf2 = (lp->tbuf2 & ~TB2_M_TBUFFAD) | - ((pa >> 16) & TB2_M_TBUFFAD); - if (lp->tbuffct == 0) { - lp->tbuf2 &= ~TB2_TX_DMA_START; - q_tx_report (vh, status); - } - } + pa = lp->tbuf1; + pa |= (lp->tbuf2 & TB2_M_TBUFFAD) << 16; + status = chan << CSR_V_TX_LINE; + while (lp->tbuffct) { + uint8 buf; + if (Map_ReadB (pa, 1, &buf)) { + status |= CSR_TX_DMA_ERR; + lp->tbuffct = 0; + break; + } + if (vh_putc (vh, lp, chan, buf) != SCPE_OK) + break; + /* pa = (pa + 1) & PAMASK; */ + pa = (pa + 1) & ((1 << 22) - 1); + lp->tbuffct--; + } + lp->tbuf1 = pa & 0177777; + lp->tbuf2 = (lp->tbuf2 & ~TB2_M_TBUFFAD) | + ((pa >> 16) & TB2_M_TBUFFAD); + if (lp->tbuffct == 0) { + lp->tbuf2 &= ~TB2_TX_DMA_START; + q_tx_report (vh, status); + } + } } /* Perform many of the functions of PROC2 */ -static t_stat vh_svc ( UNIT *uptr ) +static t_stat vh_svc ( UNIT *uptr ) { - int32 vh, newln, i; + int32 vh, newln, i; - /* scan all muxes for countdown reset */ - for (vh = 0; vh < VH_MUXES; vh++) { - if (vh_csr[vh] & CSR_MASTER_RESET) { - if (vh_mcount[vh] != 0) - vh_mcount[vh] -= 1; - else - vh_clear (vh, FALSE); - } - } - /* sample every 10ms for modem changes (new connections) */ - newln = tmxr_poll_conn (&vh_desc); - if (newln >= 0) { - TMLX *lp; - int32 line; - vh = newln / VH_LINES; /* determine which mux */ - line = newln - (vh * VH_LINES); - lp = &vh_parm[newln]; - lp->lstat |= STAT_DSR | STAT_DCD | STAT_CTS; - if (!(lp->lnctrl & LNCTRL_DTR)) - lp->lstat |= STAT_RI; - if (lp->lnctrl & LNCTRL_LINK_TYPE) - fifo_put (vh, lp, RBUF_DIAG | - RBUF_PUTLINE (line) | - ((lp->lstat >> 8) & 0376)); - /* BUG: should check for overflow above */ - } - /* scan all muxes, lines for DMA to complete; start every 3.12ms */ - for (vh = 0; vh < VH_MUXES; vh++) { - for (i = 0; i < VH_LINES; i++) - doDMA (vh, i); - } - /* interrupt driven in a real DHQ */ - tmxr_poll_rx (&vh_desc); - for (vh = 0; vh < VH_MUXES; vh++) - vh_getc (vh); - tmxr_poll_tx (&vh_desc); - /* scan all DHU-mode muxes for RX FIFO timeout */ - for (vh = 0; vh < VH_MUXES; vh++) { - if (vh_unit[vh].flags & UNIT_MODEDHU) { - if (vh_timeo[vh] && (vh_csr[vh] & CSR_RXIE)) { - vh_timeo[vh] -= 1; - if ((vh_timeo[vh] == 0) && rbuf_idx[vh]) - vh_set_rxint (vh); - } - } - } - sim_activate (uptr, tmxr_poll); /* requeue ourselves */ - return (SCPE_OK); + /* scan all muxes for countdown reset */ + for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) { + if (vh_csr[vh] & CSR_MASTER_RESET) { + if (vh_mcount[vh] != 0) + vh_mcount[vh] -= 1; + else + vh_clear (vh, FALSE); + } + } + /* sample every 10ms for modem changes (new connections) */ + newln = tmxr_poll_conn (&vh_desc); + if (newln >= 0) { + TMLX *lp; + int32 line; + vh = newln / VH_LINES; /* determine which mux */ + line = newln - (vh * VH_LINES); + lp = &vh_parm[newln]; + lp->lstat |= STAT_DSR | STAT_DCD | STAT_CTS; + if (!(lp->lnctrl & LNCTRL_DTR)) + lp->lstat |= STAT_RI; + if (lp->lnctrl & LNCTRL_LINK_TYPE) + fifo_put (vh, lp, RBUF_DIAG | + RBUF_PUTLINE (line) | + ((lp->lstat >> 8) & 0376)); + /* BUG: should check for overflow above */ + } + /* scan all muxes, lines for DMA to complete; start every 3.12ms */ + for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) { + for (i = 0; i < VH_LINES; i++) + doDMA (vh, i); + } + /* interrupt driven in a real DHQ */ + tmxr_poll_rx (&vh_desc); + for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) + vh_getc (vh); + tmxr_poll_tx (&vh_desc); + /* scan all DHU-mode muxes for RX FIFO timeout */ + for (vh = 0; vh < vh_desc.lines/VH_LINES; vh++) { + if (vh_unit[vh].flags & UNIT_MODEDHU) { + if (vh_timeo[vh] && (vh_csr[vh] & CSR_RXIE)) { + vh_timeo[vh] -= 1; + if ((vh_timeo[vh] == 0) && rbuf_idx[vh]) + vh_set_rxint (vh); + } + } + } + sim_activate (uptr, tmxr_poll); /* requeue ourselves */ + return (SCPE_OK); } /* init a channel on a controller */ @@ -1155,175 +1202,257 @@ auto-flow reports enabled FIFO size set to 64 */ -static void vh_init_chan ( int32 vh, - int32 chan ) +static void vh_init_chan ( int32 vh, + int32 chan ) { - int32 line; - TMLX *lp; + int32 line; + TMLX *lp; - line = (vh * VH_LINES) + chan; - lp = &vh_parm[line]; - lp->lpr = (RATE_9600 << LPR_V_TX_SPEED) | - (RATE_9600 << LPR_V_RX_SPEED) | - (03 << LPR_V_CHAR_LGTH); - lp->lnctrl = 0; - lp->lstat &= ~(STAT_MDL | STAT_DHUID | STAT_RI); - if (vh_unit[vh].flags & UNIT_MODEDHU) - lp->lstat |= STAT_DHUID | 64; - if (!(vh_unit[vh].flags & UNIT_MODEM)) - lp->lstat |= STAT_DSR | STAT_DCD | STAT_CTS; - lp->tmln->xmte = 1; - lp->tmln->rcve = 0; - lp->tbuffct = 0; - lp->tbuf1 = 0; - lp->tbuf2 = TB2_TX_ENA; - lp->txchar = 0; + line = (vh * VH_LINES) + chan; + lp = &vh_parm[line]; + lp->lpr = (RATE_9600 << LPR_V_TX_SPEED) | + (RATE_9600 << LPR_V_RX_SPEED) | + (03 << LPR_V_CHAR_LGTH); + lp->lnctrl = 0; + lp->lstat &= ~(STAT_MDL | STAT_DHUID | STAT_RI); + if (vh_unit[vh].flags & UNIT_MODEDHU) + lp->lstat |= STAT_DHUID | 64; + if (!(vh_unit[vh].flags & UNIT_MODEM)) + lp->lstat |= STAT_DSR | STAT_DCD | STAT_CTS; + lp->tmln->xmte = 1; + lp->tmln->rcve = 0; + lp->tbuffct = 0; + lp->tbuf1 = 0; + lp->tbuf2 = TB2_TX_ENA; + lp->txchar = 0; } /* init a controller; flag true if BINIT, false if master.reset */ -static t_stat vh_clear ( int32 vh, - t_bool flag ) +static t_stat vh_clear ( int32 vh, + t_bool flag ) { - int32 i; + int32 i; - txq_idx[vh] = 0; - rbuf_idx[vh] = 0; - /* put 8 diag bytes in FIFO: 6 SELF_x, 2 circuit revision codes */ - if (vh_csr[vh] & CSR_SKIP) { - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(0) | SELF_SKIP); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(1) | SELF_SKIP); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(2) | SELF_SKIP); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(3) | SELF_SKIP); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(4) | SELF_SKIP); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(5) | SELF_SKIP); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(6) | 0107); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(7) | 0105); - } else { - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(0) | SELF_NULL); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(1) | SELF_NULL); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(2) | SELF_NULL); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(3) | SELF_NULL); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(4) | SELF_NULL); - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(5) | SELF_NULL); - /* PROC2 ver. 1 */ - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(6) | 0107); - /* PROC1 ver. 1 */ - fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(7) | 0105); - } - vh_csr[vh] &= ~(CSR_TX_ACTION|CSR_DIAG_FAIL|CSR_MASTER_RESET); - if (flag) - vh_csr[vh] &= ~(CSR_TXIE|CSR_RXIE|CSR_SKIP); - vh_csr[vh] |= CSR_TX_DMA_ERR | (CSR_M_TX_LINE << CSR_V_TX_LINE); - vh_clr_rxint (vh); - vh_clr_txint (vh); - vh_timer[vh] = 1; - vh_timeo[vh] = 0; - vh_ovrrun[vh] = 0; - for (i = 0; i < VH_LINES; i++) - vh_init_chan (vh, i); - vh_crit &= ~(1 << vh); - vh_stall[vh] = 0; - vh_loop[vh] = LOOP_NONE; - return (SCPE_OK); + txq_idx[vh] = 0; + rbuf_idx[vh] = 0; + /* put 8 diag bytes in FIFO: 6 SELF_x, 2 circuit revision codes */ + if (vh_csr[vh] & CSR_SKIP) { + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(0) | SELF_SKIP); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(1) | SELF_SKIP); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(2) | SELF_SKIP); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(3) | SELF_SKIP); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(4) | SELF_SKIP); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(5) | SELF_SKIP); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(6) | 0107); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(7) | 0105); + } else { + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(0) | SELF_NULL); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(1) | SELF_NULL); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(2) | SELF_NULL); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(3) | SELF_NULL); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(4) | SELF_NULL); + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(5) | SELF_NULL); + /* PROC2 ver. 1 */ + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(6) | 0107); + /* PROC1 ver. 1 */ + fifo_put (vh, NULL, RBUF_DIAG | RBUF_PUTLINE(7) | 0105); + } + vh_csr[vh] &= ~(CSR_TX_ACTION|CSR_DIAG_FAIL|CSR_MASTER_RESET); + if (flag) + vh_csr[vh] &= ~(CSR_TXIE|CSR_RXIE|CSR_SKIP); + vh_csr[vh] |= CSR_TX_DMA_ERR | (CSR_M_TX_LINE << CSR_V_TX_LINE); + vh_clr_rxint (vh); + vh_clr_txint (vh); + vh_timer[vh] = 1; + vh_timeo[vh] = 0; + vh_ovrrun[vh] = 0; + for (i = 0; i < VH_LINES; i++) + vh_init_chan (vh, i); + vh_crit &= ~(1 << vh); + vh_stall[vh] = 0; + vh_loop[vh] = LOOP_NONE; + return (SCPE_OK); } /* Reset all controllers. Used by BINIT and RESET. */ -static t_stat vh_reset ( DEVICE *dptr ) +static t_stat vh_reset ( DEVICE *dptr ) { - int32 i; + int32 i; - for (i = 0; i < (VH_MUXES * VH_LINES); i++) - vh_parm[i].tmln = &vh_ldsc[i]; - for (i = 0; i < VH_MUXES; i++) { + for (i = 0; i < vh_desc.lines; i++) + vh_parm[i].tmln = &vh_ldsc[i]; + for (i = 0; i < vh_desc.lines/VH_LINES; i++) { #if defined (VM_PDP11) - /* if Unibus, force DHU mode */ - if (UNIBUS) - vh_unit[i].flags |= UNIT_MODEDHU; + /* if Unibus, force DHU mode */ + if (UNIBUS) + vh_unit[i].flags |= UNIT_MODEDHU; #endif - vh_clear (i, TRUE); - } - vh_rxi = vh_txi = 0; - CLR_INT (VHRX); - CLR_INT (VHTX); - for (i = 0; i < VH_MUXES; i++) - sim_cancel (&vh_unit[i]); - return (auto_config (dptr->name, (dptr->flags & DEV_DIS) ? 0 : VH_MUXES)); + vh_clear (i, TRUE); + } + vh_rxi = vh_txi = 0; + CLR_INT (VHRX); + CLR_INT (VHTX); + sim_cancel (&vh_unit[0]); + return (auto_config (dptr->name, (dptr->flags & DEV_DIS) ? 0 : vh_desc.lines/VH_LINES)); } -static t_stat vh_attach ( UNIT *uptr, - char *cptr ) +static t_stat vh_attach ( UNIT *uptr, + char *cptr ) { - if (uptr == &vh_unit[0]) - return (tmxr_attach (&vh_desc, uptr, cptr)); - return (SCPE_NOATT); + if (uptr == &vh_unit[0]) + return (tmxr_attach (&vh_desc, uptr, cptr)); + return (SCPE_NOATT); } -static t_stat vh_detach ( UNIT *uptr ) +static t_stat vh_detach ( UNIT *uptr ) { - return (tmxr_detach (&vh_desc, uptr)); + return (tmxr_detach (&vh_desc, uptr)); } -static void debug_line ( FILE *st, - int32 vh, - int32 chan ) +static void vh_detail_line ( FILE *st, + int32 vh, + int32 chan ) { - int32 line; - TMLX *lp; + int32 line; + TMLX *lp; - line = (vh * VH_LINES) + chan; - lp = &vh_parm[line]; - fprintf (st, "\tline %d\tlpr %06o, lnctrl %06o, lstat %06o\n", - chan, lp->lpr, lp->lnctrl, lp->lstat); - fprintf (st, "\t\ttbuffct %06o, tbuf1 %06o, tbuf2 %06o, txchar %06o\n", - lp->tbuffct, lp->tbuf1, lp->tbuf2, lp->txchar); - fprintf (st, "\t\ttmln rcve %d xmte %d\n", - lp->tmln->rcve, lp->tmln->xmte); + line = (vh * VH_LINES) + chan; + lp = &vh_parm[line]; + fprintf (st, "\tline %d\tlpr %06o, lnctrl %06o, lstat %06o\n", + chan, lp->lpr, lp->lnctrl, lp->lstat); + fprintf (st, "\t\ttbuffct %06o, tbuf1 %06o, tbuf2 %06o, txchar %06o\n", + lp->tbuffct, lp->tbuf1, lp->tbuf2, lp->txchar); + fprintf (st, "\t\ttmln rcve %d xmte %d\n", + lp->tmln->rcve, lp->tmln->xmte); } -static t_stat vh_show_debug ( FILE *st, - UNIT *uptr, - int32 val, - void *desc ) +static t_stat vh_show_detail ( FILE *st, + UNIT *uptr, + int32 val, + void *desc ) { - int32 i, j; + int32 i, j; - fprintf (st, "VH:\trxi %d, txi %d\n", vh_rxi, vh_txi); - for (i = 0; i < VH_MUXES; i++) { - fprintf (st, "VH%d:\tmode %s, crit %d\n", i, - vh_unit[i].flags & UNIT_MODEDHU ? "DHU" : "DHV", - vh_crit & (1 << i)); - fprintf (st, "\tCSR %06o, mcount %d, rbuf_idx %d, txq_idx %d\n", - vh_csr[i], vh_mcount[i], rbuf_idx[i], txq_idx[i]); - for (j = 0; j < VH_LINES; j++) - debug_line (st, i, j); - } - return (SCPE_OK); + fprintf (st, "VH:\trxi %d, txi %d\n", vh_rxi, vh_txi); + for (i = 0; i < vh_desc.lines/VH_LINES; i++) { + fprintf (st, "VH%d:\tmode %s, crit %d\n", i, + vh_unit[i].flags & UNIT_MODEDHU ? "DHU" : "DHV", + vh_crit & (1 << i)); + fprintf (st, "\tCSR %06o, mcount %d, rbuf_idx %d, txq_idx %d\n", + vh_csr[i], vh_mcount[i], rbuf_idx[i], txq_idx[i]); + for (j = 0; j < VH_LINES; j++) + vh_detail_line (st, i, j); + } + return (SCPE_OK); } -static t_stat vh_show_rbuf ( FILE *st, - UNIT *uptr, - int32 val, - void *desc ) +static t_stat vh_show_rbuf ( FILE *st, + UNIT *uptr, + int32 val, + void *desc ) { - int32 i; + int32 i; - for (i = 0; i < rbuf_idx[0]; i++) - fprintf (st, "%03d: %06o\n", i, vh_rbuf[0][i]); - return (SCPE_OK); + for (i = 0; i < rbuf_idx[0]; i++) + fprintf (st, "%03d: %06o\n", i, vh_rbuf[0][i]); + return (SCPE_OK); } -static t_stat vh_show_txq ( FILE *st, - UNIT *uptr, - int32 val, - void *desc ) +static t_stat vh_show_txq ( FILE *st, + UNIT *uptr, + int32 val, + void *desc ) { - int32 i; + int32 i; - for (i = 0; i < txq_idx[0]; i++) - fprintf (st, "%02d: %06o\n\r", i, vh_txq[0][i]); - return (SCPE_OK); + for (i = 0; i < txq_idx[0]; i++) + fprintf (st, "%02d: %06o\n\r", i, vh_txq[0][i]); + return (SCPE_OK); } +/* SET LINES processor */ + +static t_stat vh_setnl (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +int32 newln, i, t, ndev; +t_stat r; + +if (cptr == NULL) + return SCPE_ARG; +newln = (int32) get_uint (cptr, 10, (VH_MUXES * VH_LINES), &r); +if ((r != SCPE_OK) || (newln == vh_desc.lines)) + return r; +if ((newln == 0) || (newln % VH_LINES)) + return SCPE_ARG; +if (newln < vh_desc.lines) { + for (i = newln, t = 0; i < vh_desc.lines; i++) + t = t | vh_ldsc[i].conn; + if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) + return SCPE_OK; + for (i = newln; i < vh_desc.lines; i++) { + if (vh_ldsc[i].conn) { + tmxr_linemsg (&vh_ldsc[i], "\r\nOperator disconnected line\r\n"); + tmxr_reset_ln (&vh_ldsc[i]); /* reset line */ + } + if ((i % VH_LINES) == (VH_LINES - 1)) + vh_clear (i / VH_LINES, TRUE); /* reset mux */ + } + } +vh_dib.lnt = (newln / VH_LINES) * IOLN_VH; /* set length */ +vh_desc.lines = newln; +ndev = ((vh_dev.flags & DEV_DIS)? 0: (vh_desc.lines / VH_LINES)); +vh_dev.numunits = (newln / VH_LINES); +return auto_config (vh_dev.name, ndev); /* auto config */ +} + +/* SET LOG processor */ + +static t_stat vh_set_log (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +char *tptr; +t_stat r; +int32 ln; + +if (cptr == NULL) + return SCPE_ARG; +tptr = strchr (cptr, '='); +if ((tptr == NULL) || (*tptr == 0)) + return SCPE_ARG; +*tptr++ = 0; +ln = (int32) get_uint (cptr, 10, (VH_MUXES * VH_LINES), &r); +if ((r != SCPE_OK) || (ln >= vh_desc.lines)) + return SCPE_ARG; +return tmxr_set_log (NULL, ln, tptr, desc); +} + +/* SET NOLOG processor */ + +static t_stat vh_set_nolog (UNIT *uptr, int32 val, char *cptr, void *desc) +{ +t_stat r; +int32 ln; + +if (cptr == NULL) + return SCPE_ARG; +ln = (int32) get_uint (cptr, 10, (VH_MUXES * VH_LINES), &r); +if ((r != SCPE_OK) || (ln >= vh_desc.lines)) + return SCPE_ARG; +return tmxr_set_nolog (NULL, ln, NULL, desc); +} + +/* SHOW LOG processor */ + +static t_stat vh_show_log (FILE *st, UNIT *uptr, int32 val, void *desc) +{ +int32 i; + +for (i = 0; i < vh_desc.lines; i++) { + fprintf (st, "line %d: ", i); + tmxr_show_log (st, NULL, i, desc); + fprintf (st, "\n"); + } +return SCPE_OK; +} diff --git a/PDP11/pdp11_xq.c b/PDP11/pdp11_xq.c index f3b3ce1f..9233550c 100644 --- a/PDP11/pdp11_xq.c +++ b/PDP11/pdp11_xq.c @@ -1132,7 +1132,6 @@ t_stat xq_process_setup(CTLR* xq) int i,j; int count = 0; float secs; - t_stat status; uint32 saved_debug = xq->dev->dctrl; ETH_MAC zeros = {0, 0, 0, 0, 0, 0}; ETH_MAC filters[XQ_FILTER_MAX + 1]; @@ -1225,11 +1224,11 @@ t_stat xq_process_setup(CTLR* xq) for (i = 0; i < XQ_FILTER_MAX; i++) if (memcmp(zeros, &xq->var->setup.macs[i], sizeof(ETH_MAC))) memcpy (filters[count++], xq->var->setup.macs[i], sizeof(ETH_MAC)); - status = eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous); + eth_filter (xq->var->etherface, count, filters, xq->var->setup.multicast, xq->var->setup.promiscuous); /* process MOP information */ if (xq->var->write_buffer.msg[0]) - status = xq_process_mop(xq); + xq_process_mop(xq); /* mark setup block valid */ xq->var->setup.valid = 1; @@ -1366,7 +1365,6 @@ t_stat xq_dispatch_rbdl(CTLR* xq) { int i; int32 rstatus, wstatus; - t_stat status; sim_debug(DBG_TRC, xq->dev, "xq_dispatch_rbdl()\n"); @@ -1394,7 +1392,7 @@ t_stat xq_dispatch_rbdl(CTLR* xq) /* process any waiting packets in receive queue */ if (xq->var->ReadQ.count) - status = xq_process_rbdl(xq); + xq_process_rbdl(xq); return SCPE_OK; } @@ -2250,7 +2248,6 @@ t_stat xq_wr_icr(CTLR* xq, int32 data) t_stat xq_wr(int32 data, int32 PA, int32 access) { - t_stat status; CTLR* xq = xq_pa2ctlr(PA); int index = (PA >> 1) & 07; /* word index */ @@ -2266,19 +2263,19 @@ t_stat xq_wr(int32 data, int32 PA, int32 access) xq->var->iba = (xq->var->iba & 0xFFFF) | ((data & 0xFFFF) << 16); break; case 2: /* ICR */ - status = xq_wr_icr(xq, data); + xq_wr_icr(xq, data); break; case 3: break; case 4: /* SRQR */ - status = xq_wr_srqr(xq, data); + xq_wr_srqr(xq, data); break; case 5: break; case 6: break; case 7: /* ARQR */ - status = xq_wr_arqr(xq, data); + xq_wr_arqr(xq, data); break; } break; @@ -2304,20 +2301,20 @@ t_stat xq_wr(int32 data, int32 PA, int32 access) break; case 3: /* receive bdl high bits */ xq->var->rbdl[1] = data; - status = xq_dispatch_rbdl(xq); /* start receive operation */ + xq_dispatch_rbdl(xq); /* start receive operation */ break; case 4: /* transmit bdl low bits */ xq->var->xbdl[0] = data; break; case 5: /* transmit bdl high bits */ xq->var->xbdl[1] = data; - status = xq_dispatch_xbdl(xq); /* start transmit operation */ + xq_dispatch_xbdl(xq); /* start transmit operation */ break; case 6: /* vector address register */ - status = xq_wr_var(xq, data); + xq_wr_var(xq, data); break; case 7: /* control and status register */ - status = xq_wr_csr(xq, data); + xq_wr_csr(xq, data); break; } break; @@ -2582,7 +2579,10 @@ t_stat xq_attach(UNIT* uptr, char* cptr) strcpy(tptr, cptr); xq->var->etherface = (ETH_DEV *) malloc(sizeof(ETH_DEV)); - if (!xq->var->etherface) return SCPE_MEM; + if (!xq->var->etherface) { + free(tptr); + return SCPE_MEM; + } status = eth_open(xq->var->etherface, cptr, xq->dev, DBG_ETH); if (status != SCPE_OK) { @@ -2611,6 +2611,7 @@ t_stat xq_attach(UNIT* uptr, char* cptr) printf("%s: MAC Address Conflict on LAN for address %s, change the MAC address to a unique value\n", xq->dev->name, buf); if (sim_log) fprintf (sim_log, "%s: MAC Address Conflict on LAN for address %s, change the MAC address to a unique value\n", xq->dev->name, buf); eth_close(xq->var->etherface); + free(tptr); free(xq->var->etherface); xq->var->etherface = NULL; return SCPE_NOATT; @@ -2623,8 +2624,13 @@ t_stat xq_attach(UNIT* uptr, char* cptr) /* init read queue (first time only) */ status = ethq_init(&xq->var->ReadQ, XQ_QUE_MAX); - if (status != SCPE_OK) + if (status != SCPE_OK) { + eth_close(xq->var->etherface); + free(tptr); + free(xq->var->etherface); + xq->var->etherface = NULL; return status; + } if (xq->var->mode == XQ_T_DELQA_PLUS) eth_filter_hash (xq->var->etherface, 1, &xq->var->init.phys, 0, xq->var->init.mode & XQ_IN_MO_PRO, &xq->var->init.hash_filter); diff --git a/PDP11/pdp11_xu.c b/PDP11/pdp11_xu.c index 05bccaed..83920b7d 100644 --- a/PDP11/pdp11_xu.c +++ b/PDP11/pdp11_xu.c @@ -553,7 +553,6 @@ t_stat xu_system_id (CTLR* xu, const ETH_MAC dest, uint16 receipt_id) t_stat xu_svc(UNIT* uptr) { int queue_size; - t_stat status; CTLR* xu = xu_unit2ctlr(uptr); const ETH_MAC mop_multicast = {0xAB, 0x00, 0x00, 0x02, 0x00, 0x00}; const int one_second = clk_tps * tmr_poll; @@ -568,7 +567,7 @@ t_stat xu_svc(UNIT* uptr) { queue_size = xu->var->ReadQ.count; /* read a packet from the ethernet - processing is via the callback */ - status = eth_read (xu->var->etherface, &xu->var->read_buffer, xu->var->rcallback); + eth_read (xu->var->etherface, &xu->var->read_buffer, xu->var->rcallback); } while (queue_size != xu->var->ReadQ.count); /* Now pump any still queued packets into the system */ @@ -578,7 +577,7 @@ t_stat xu_svc(UNIT* uptr) /* send identity packet when timer expires */ if (--xu->var->idtmr <= 0) { if ((xu->var->mode & MODE_DMNT) == 0) /* if maint msg is not disabled */ - status = xu_system_id(xu, mop_multicast, 0); /* then send ID packet */ + xu_system_id(xu, mop_multicast, 0); /* then send ID packet */ xu->var->idtmr = XU_ID_TIMER_VAL * one_second; /* reset timer */ } @@ -627,7 +626,6 @@ void xu_setclrint(CTLR* xu, int32 bits) t_stat xu_sw_reset (CTLR* xu) { - t_stat status; int i; sim_debug(DBG_TRC, xu->dev, "xu_sw_reset()\n"); @@ -668,9 +666,9 @@ t_stat xu_sw_reset (CTLR* xu) xu->var->setup.macs[1][i] = 0xff; /* Broadcast Address */ xu->var->setup.mac_count = 2; if (xu->var->etherface) - status = eth_filter (xu->var->etherface, xu->var->setup.mac_count, - xu->var->setup.macs, xu->var->setup.multicast, - xu->var->setup.promiscuous); + eth_filter (xu->var->etherface, xu->var->setup.mac_count, + xu->var->setup.macs, xu->var->setup.multicast, + xu->var->setup.promiscuous); /* activate device if not disabled */ if ((xu->dev->flags & DEV_DIS) == 0) { @@ -708,7 +706,7 @@ int32 xu_command(CTLR* xu) uint32 udbb; int fnc, mtlen, i, j; uint16 value, pltlen; - t_stat status, rstatus, wstatus, wstatus2, wstatus3; + t_stat rstatus, wstatus, wstatus2, wstatus3; struct xu_stats* stats = &xu->var->stats; uint16* udb = xu->var->udb; uint16* mac_w = (uint16*) xu->var->mac; @@ -795,9 +793,9 @@ int32 xu_command(CTLR* xu) rstatus = Map_ReadB(udbb, mtlen * 6, (uint8*) &xu->var->setup.macs[2]); if (rstatus == 0) { xu->var->setup.mac_count = mtlen + 2; - status = eth_filter (xu->var->etherface, xu->var->setup.mac_count, - xu->var->setup.macs, xu->var->setup.multicast, - xu->var->setup.promiscuous); + eth_filter (xu->var->etherface, xu->var->setup.mac_count, + xu->var->setup.macs, xu->var->setup.multicast, + xu->var->setup.promiscuous); } else { xu->var->pcsr0 |= PCSR0_PCEI; } @@ -922,9 +920,9 @@ int32 xu_command(CTLR* xu) /* if promiscuous or multicast flags changed, change filter */ if ((value ^ xu->var->mode) & (MODE_PROM | MODE_ENAL)) - status = eth_filter (xu->var->etherface, xu->var->setup.mac_count, - xu->var->setup.macs, xu->var->setup.multicast, - xu->var->setup.promiscuous); + eth_filter (xu->var->etherface, xu->var->setup.mac_count, + xu->var->setup.macs, xu->var->setup.multicast, + xu->var->setup.promiscuous); break; case FC_RSTAT: /* read extended status */ @@ -1339,7 +1337,6 @@ void xu_port_command (CTLR* xu) char* msg; int command = xu->var->pcsr0 & PCSR0_PCMD; int state = xu->var->pcsr1 & PCSR1_STATE; - int bits; static char* commands[] = { "NO-OP", "GET PCBB", @@ -1368,7 +1365,7 @@ void xu_port_command (CTLR* xu) break; case CMD_GETCMD: /* GET COMMAND */ - bits = xu_command(xu); + xu_command(xu); xu->var->pcsr0 |= PCSR0_DNI; break; @@ -1571,7 +1568,10 @@ t_stat xu_attach(UNIT* uptr, char* cptr) strcpy(tptr, cptr); xu->var->etherface = (ETH_DEV *) malloc(sizeof(ETH_DEV)); - if (!xu->var->etherface) return SCPE_MEM; + if (!xu->var->etherface) { + free(tptr); + return SCPE_MEM; + } status = eth_open(xu->var->etherface, cptr, xu->dev, DBG_ETH); if (status != SCPE_OK) { @@ -1587,6 +1587,8 @@ t_stat xu_attach(UNIT* uptr, char* cptr) printf("%s: MAC Address Conflict on LAN for address %s\n", xu->dev->name, buf); if (sim_log) fprintf (sim_log, "%s: MAC Address Conflict on LAN for address %s\n", xu->dev->name, buf); eth_close(xu->var->etherface); + free(tptr); + xu->var->etherface = 0; return SCPE_NOATT; } uptr->filename = tptr; @@ -1603,12 +1605,11 @@ t_stat xu_attach(UNIT* uptr, char* cptr) t_stat xu_detach(UNIT* uptr) { - t_stat status; CTLR* xu = xu_unit2ctlr(uptr); sim_debug(DBG_TRC, xu->dev, "xu_detach()\n"); if (uptr->flags & UNIT_ATT) { - status = eth_close (xu->var->etherface); + eth_close (xu->var->etherface); free(xu->var->etherface); xu->var->etherface = 0; free(uptr->filename); diff --git a/PDP18B/pdp18b_cpu.c b/PDP18B/pdp18b_cpu.c index cfce154c..d9473ac3 100644 --- a/PDP18B/pdp18b_cpu.c +++ b/PDP18B/pdp18b_cpu.c @@ -26,7 +26,7 @@ cpu PDP-4/7/9/15 central processor 28-Apr-07 RMS Removed clock initialization - 26-Dec-06 RMS Fixed boundary test in KT15/XVM (reported by Andrew Warkentin) + 26-Dec-06 RMS Fixed boundary test in KT15/XVM (Andrew Warkentin) 30-Oct-06 RMS Added idle and infinite loop detection 08-Oct-06 RMS Added RDCLK instruction Fixed bug, PC off by one on fetch mem mmgt error @@ -34,7 +34,7 @@ PDP-15 sets API 4 on CAL only if 0-3 inactive CAF clears memory management mode register 27-Jun-06 RMS Reset clears AC, L, and MQ - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 22-Jul-05 RMS Removed AAS, error in V1 reference manual 06-Nov-04 RMS Added =n to SHOW HISTORY @@ -56,14 +56,14 @@ Fixed memory protect/skip interaction Fixed CAF not to reset CPU 12-Mar-03 RMS Added logical name support - 18-Feb-03 RMS Fixed three EAE bugs (found by Hans Pufal) + 18-Feb-03 RMS Fixed three EAE bugs (Hans Pufal) 05-Oct-02 RMS Added DIBs, device number support 25-Jul-02 RMS Added DECtape support for PDP-4 06-Jan-02 RMS Revised enable/disable support 30-Dec-01 RMS Added old PC queue 30-Nov-01 RMS Added extended SET/SHOW support 25-Nov-01 RMS Revised interrupt structure - 19-Sep-01 RMS Fixed bug in EAE (found by Dave Conroy) + 19-Sep-01 RMS Fixed bug in EAE (Dave Conroy) 17-Sep-01 RMS Fixed typo in conditional 10-Aug-01 RMS Removed register from declarations 17-Jul-01 RMS Moved function prototype @@ -1989,7 +1989,7 @@ else *ea = (PC & BLKMASK) | (t & IAMASK); /* within 32K */ return sta; } -t_stat Incr_addr (int32 ma) +int32 Incr_addr (int32 ma) { if (memm) return ((ma & B_EPCMASK) | ((ma + 1) & B_DAMASK)); @@ -2132,7 +2132,7 @@ if (usmd && (sw & SWMASK ('V'))) { addr = RelocXVM (addr, REL_C); else if (RELOC) addr = Reloc15 (addr, REL_C); - if ((int32) addr < 0) + if (((int32) addr) < 0) return STOP_MME; } #endif @@ -2153,7 +2153,7 @@ if (usmd && (sw & SWMASK ('V'))) { addr = RelocXVM (addr, REL_C); else if (RELOC) addr = Reloc15 (addr, REL_C); - if ((int32) addr < 0) + if (((int32) addr) < 0) return STOP_MME; } #endif diff --git a/PDP18B/pdp18b_drm.c b/PDP18B/pdp18b_drm.c index 0ae13f2c..c65990b1 100644 --- a/PDP18B/pdp18b_drm.c +++ b/PDP18B/pdp18b_drm.c @@ -30,7 +30,7 @@ 05-Dec-02 RMS Updated from Type 24 documentation 22-Nov-02 RMS Added PDP-4 support 05-Feb-02 RMS Added DIB, device number support - 03-Feb-02 RMS Fixed bug in reset routine (found by Robert Alan Byer) + 03-Feb-02 RMS Fixed bug in reset routine (Robert Alan Byer) 06-Jan-02 RMS Revised enable/disable support 25-Nov-01 RMS Revised interrupt structure 10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware diff --git a/PDP18B/pdp18b_fpp.c b/PDP18B/pdp18b_fpp.c index becbbe24..d1a098a6 100644 --- a/PDP18B/pdp18b_fpp.c +++ b/PDP18B/pdp18b_fpp.c @@ -1,6 +1,6 @@ /* pdp18b_fpp.c: FP15 floating point processor simulator - Copyright (c) 2003-2008, Robert M Supnik + Copyright (c) 2003-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ fpp PDP-15 floating point processor + 19-Mar-12 RMS Fixed declaration of pc queue (Mark Pizzolato) 06-Jul-06 RMS Fixed bugs in left shift, multiply 31-Oct-04 RMS Fixed URFST to mask low 9b of fraction Fixed exception PC setting @@ -143,7 +144,11 @@ static UFP fmb; /* FMB */ static UFP fmq; /* FMQ - hi,lo only */ extern int32 M[MAXMEMSIZE]; -extern int32 pcq[PCQ_SIZE]; +#if defined (PDP15) +extern int32 pcq[PCQ_SIZE]; /* PC queue */ +#else +extern int16 pcq[PCQ_SIZE]; /* PC queue */ +#endif extern int32 pcq_p; extern int32 PC; extern int32 trap_pending, usmd; @@ -159,7 +164,7 @@ t_stat fp15_fmul (int32 ir, UFP *a, UFP *b); t_stat fp15_fdiv (int32 ir, UFP *a, UFP *b); t_stat fp15_fix (int32 ir, UFP *a); t_stat fp15_norm (int32 ir, UFP *a, UFP *b, t_bool rnd); -t_stat fp15_exc (int32 sta); +t_stat fp15_exc (t_stat sta); void fp15_asign (int32 ir, UFP *a); void dp_add (UFP *a, UFP *b); void dp_sub (UFP *a, UFP *b); diff --git a/PDP18B/pdp18b_lp.c b/PDP18B/pdp18b_lp.c index e04698c3..801f05f1 100644 --- a/PDP18B/pdp18b_lp.c +++ b/PDP18B/pdp18b_lp.c @@ -36,7 +36,7 @@ 05-Feb-03 RMS Added LP09, fixed conditionalization 05-Oct-02 RMS Added DIB, device number support 30-May-02 RMS Widened POS to 32b - 03-Feb-02 RMS Fixed typo (found by Robert Alan Byer) + 03-Feb-02 RMS Fixed typo (Robert Alan Byer) 25-Nov-01 RMS Revised interrupt structure 19-Sep-01 RMS Fixed bug in 647 13-Feb-01 RMS Revised for register arrays diff --git a/PDP18B/pdp18b_rf.c b/PDP18B/pdp18b_rf.c index 65a90383..51e6ecd9 100644 --- a/PDP18B/pdp18b_rf.c +++ b/PDP18B/pdp18b_rf.c @@ -27,7 +27,7 @@ (PDP-15) RF15/RS09 04-Oct-06 RMS Fixed bug, DSCD does not clear function register - 15-May-06 RMS Fixed bug in autosize attach (reported by David Gesswein) + 15-May-06 RMS Fixed bug in autosize attach (David Gesswein) 14-Jan-04 RMS Revised IO device call interface Changed sim_fsize calling sequence 26-Oct-03 RMS Cleaned up buffer copy code diff --git a/PDP18B/pdp18b_stddev.c b/PDP18B/pdp18b_stddev.c index c93b4cf8..c2e5c827 100644 --- a/PDP18B/pdp18b_stddev.c +++ b/PDP18B/pdp18b_stddev.c @@ -53,7 +53,7 @@ 22-Dec-02 RMS Added break support 01-Nov-02 RMS Added 7B/8B support to terminal 05-Oct-02 RMS Added DIBs, device number support, IORS call - 14-Jul-02 RMS Added ASCII reader/punch support (from Hans Pufal) + 14-Jul-02 RMS Added ASCII reader/punch support (Hans Pufal) 30-May-02 RMS Widened POS to 32b 29-Nov-01 RMS Added read only unit support 25-Nov-01 RMS Revised interrupt structure diff --git a/PDP18B/pdp18b_sys.c b/PDP18B/pdp18b_sys.c index c843e949..97adc3cf 100644 --- a/PDP18B/pdp18b_sys.c +++ b/PDP18B/pdp18b_sys.c @@ -34,12 +34,12 @@ 30-Jul-03 RMS Fixed FPM class mask 18-Jul-03 RMS Added FP15 support 02-Mar-03 RMS Split loaders apart for greater flexibility - 09-Feb-03 RMS Fixed bug in FMTASC (found by Hans Pufal) + 09-Feb-03 RMS Fixed bug in FMTASC (Hans Pufal) 31-Jan-03 RMS Added support for RB09 05-Oct-02 RMS Added variable device number support 25-Jul-02 RMS Added PDP-4 DECtape support 10-Feb-02 RMS Added PDP-7 DECtape IOT's - 03-Feb-02 RMS Fixed typo (found by Robert Alan Byer) + 03-Feb-02 RMS Fixed typo (Robert Alan Byer) 17-Sep-01 RMS Removed multiconsole support 27-May-01 RMS Added second Teletype support 18-May-01 RMS Added PDP-9,-15 API IOT's @@ -49,8 +49,7 @@ 30-Nov-00 RMS Added PDP-9,-15 RIM/BIN loader format 30-Oct-00 RMS Added support for examine to file 27-Oct-98 RMS V2.4 load interface - 20-Oct-97 RMS Fixed endian dependence in RIM loader - (found by Michael Somos) + 20-Oct-97 RMS Fixed endian dependence in RIM loader (Michael Somos) */ #include "pdp18b_defs.h" diff --git a/S3/s3_cd.c b/S3/s3_cd.c index 5221c775..7ec0e2ab 100644 --- a/S3/s3_cd.c +++ b/S3/s3_cd.c @@ -1,6 +1,6 @@ /* s3_cd.c: IBM 1442 card reader/punch - Copyright (c) 2001-2005, Charles E. Owen + Copyright (c) 2001-2012, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -27,6 +27,7 @@ cdp card punch cdp2 card punch stacker 2 + 19-Mar-12 RMS Fixed declaration of conversion tables (Mark Pizzolato) 25-Apr-03 RMS Revised for extended file support 08-Oct-02 RMS Added impossible function catcher @@ -40,8 +41,8 @@ #include extern uint8 M[]; -extern char ebcdic_to_ascii[256]; -extern char ascii_to_ebcdic[256]; +extern unsigned char ebcdic_to_ascii[]; +extern unsigned char ascii_to_ebcdic[]; int32 s1sel, s2sel; char rbuf[CBUFSIZE]; /* > CDR_WIDTH */ t_stat cdr_svc (UNIT *uptr); diff --git a/S3/s3_cpu.c b/S3/s3_cpu.c index 4655773f..b4696484 100644 --- a/S3/s3_cpu.c +++ b/S3/s3_cpu.c @@ -1,6 +1,6 @@ /* s3_cpu.c: IBM System/3 CPU simulator - Copyright (c) 2001-2005, Charles E. Owen + Copyright (c) 2001-2012, Charles E. Owen HPL & SLC instruction code Copyright (c) 2001 by Henk Stegeman Decimal Arithmetic Copyright (c) 2000 by Roger Bowler @@ -29,6 +29,8 @@ cpu System/3 (models 10 and 15) central processor + 19-Mar-12 RMS Changed int to int32 in declarations (Mark Pizzolato) + The IBM System/3 was a popular small-business computing system introduced in 1969 as an entry-level system for businesses that could not afford the lowest rungs of the System/360. Its architecture is inspired by and @@ -381,7 +383,7 @@ int32 debug_reg = 0; /* set for debug/trace * int32 debug_flag = 0; /* 1 when trace.log open */ FILE *trace; extern int32 sim_int_char; -extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ +extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ;/* breakpoint info */ t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); @@ -398,13 +400,13 @@ extern t_stat sim_activate (UNIT *uptr, int32 delay); extern int32 fprint_sym (FILE *of, int32 addr, uint32 *val, UNIT *uptr, int32 sw); int32 nulldev (int32 opcode, int32 m, int32 n, int32 data); -int add_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2); +int32 add_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2); int32 subtract_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2); static int32 compare(int32 byte1, int32 byte2, int32 cond); static int32 condition(int32 qbyte); static void store_decimal (int32 addr, int32 len, uint8 *dec, int sign); -static void load_decimal (int32 addr, int32 len, uint8 *result, int32 *count, int32 *sign); -static void add_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int32 *count); +static void load_decimal (int32 addr, int32 len, uint8 *result, int *count, int *sign); +static void add_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count); static void subtract_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count, int *sign); int32 GetMem(int32 addr); int32 PutMem(int32 addr, int32 data); @@ -1541,7 +1543,7 @@ int sign1, sign2, sign3; /* Sign of operands & result */ /* This field is set to zero if the result is all zero, */ /* or to MAX_DECIMAL_DIGITS+1 if overflow occurred. */ /*-------------------------------------------------------------------*/ -static void add_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int32 *count) +static void add_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count) { int d; /* Decimal digit */ int i; /* Array subscript */ @@ -1684,7 +1686,7 @@ uint8 *lower; /* -> Lower value operand */ /* exception, or if the operand causes a data exception */ /* because of invalid decimal digits or sign. */ /*-------------------------------------------------------------------*/ -static void load_decimal (int32 addr, int32 len, uint8 *result, int32 *count, int32 *sign) +static void load_decimal (int32 addr, int32 len, uint8 *result, int *count, int *sign) { int h; /* Hexadecimal digit */ int i, j; /* Array subscripts */ diff --git a/S3/s3_lp.c b/S3/s3_lp.c index cf21a127..99f85af4 100644 --- a/S3/s3_lp.c +++ b/S3/s3_lp.c @@ -1,6 +1,6 @@ /* s3_lp.c: IBM 1403 line printer simulator - Copyright (c) 2001-2005, Charles E. Owen + Copyright (c) 2001-2012, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ lpt 1403 line printer + 19-Mar-12 RMS Fixed declaration of conversion tables (Mark Pizzolato) 25-Apr-03 RMS Revised for extended file support 08-Oct-02 RMS Added impossible function catcher */ @@ -41,7 +42,7 @@ t_stat lpt_attach (UNIT *uptr, char *cptr); t_stat write_line (int32 ilnt, int32 mod); t_stat space (int32 lines, int32 lflag); t_stat carriage_control (int32 action, int32 mod); -extern unsigned char ebcdic_to_ascii[256]; +extern unsigned char ebcdic_to_ascii[]; #define UNIT_V_PCHAIN (UNIT_V_UF + 0) #define UNIT_M_PCHAIN 03 @@ -114,7 +115,7 @@ int32 lpt (int32 op, int32 m, int32 n, int32 data) switch (op) { case 0: /* SIO 1403 */ iodata = 0; - printf("\0"); +// printf("\0"); switch (n) { case 0x00: /* Spacing only */ if (data > 0 && data < 4) diff --git a/S3/s3_sys.c b/S3/s3_sys.c index 0fa2c1ee..39cec895 100644 --- a/S3/s3_sys.c +++ b/S3/s3_sys.c @@ -1,6 +1,6 @@ /* s3_sys.c: IBM System/3 system interface - Copyright (c) 2001-2005, Charles E. Owen + Copyright (c) 2001-2012, Charles E. Owen Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,8 @@ Except as contained in this notice, the name of Charles E. Owen shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Charles E. Owen. + + 19-Mar-12 RMS Fixed declaration of conversion tables (Mark Pizzolato) */ #include @@ -41,7 +43,7 @@ extern UNIT cpu_unit; extern REG cpu_reg[]; extern unsigned char M[]; extern int32 saved_PC, IAR[]; -extern char ebcdic_to_ascii[256]; +extern unsigned char ebcdic_to_ascii[]; char *parse_addr(char *cptr, char *gbuf, int32 *addr, int32 *addrtype); int32 printf_sym (FILE *of, char *strg, int32 addr, uint32 *val, diff --git a/SDS/sds_io.c b/SDS/sds_io.c index 241d7ce7..4e4dd22b 100644 --- a/SDS/sds_io.c +++ b/SDS/sds_io.c @@ -1,6 +1,6 @@ /* sds_io.c: SDS 940 I/O simulator - Copyright (c) 2001-2008, Robert M. Supnik + Copyright (c) 2001-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,8 @@ Except as contained in this notice, the name of Robert M Supnik shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + + 19-Mar-2012 RMS Fixed various declarations (Mark Pizzolato) */ #include "sds_defs.h" @@ -79,9 +81,10 @@ extern uint32 int_req; /* int req */ extern uint32 xfr_req; /* xfer req */ extern uint32 alert; /* pin/pot alert */ extern uint32 X, EM2, EM3, OV, ion, bpt; -extern uint32 nml_mode, usr_mode, rtc_pie; +extern uint32 nml_mode, usr_mode; +extern int32 rtc_pie; extern int32 stop_invins, stop_invdev, stop_inviop; -extern int32 mon_usr_trap; +extern uint32 mon_usr_trap; extern UNIT cpu_unit; extern FILE *sim_log; extern DEVICE *sim_devices[]; diff --git a/SDS/sds_mt.c b/SDS/sds_mt.c index f7590eec..163d7d23 100644 --- a/SDS/sds_mt.c +++ b/SDS/sds_mt.c @@ -1,6 +1,6 @@ /* sds_mt.c: SDS 940 magnetic tape simulator - Copyright (c) 2001-2008, Robert M. Supnik + Copyright (c) 2001-2012, Robert M. Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,6 +25,7 @@ mt 7 track magnetic tape + 19-Mar-12 RMS Fixed bug in scan function decode (Peter Schorn) 16-Feb-06 RMS Added tape capacity checking 07-Dec-04 RMS Added read-only file support 25-Apr-03 RMS Revised for extended file support @@ -209,7 +210,7 @@ switch (fnc) { /* case function */ (inst & CHC_REV)) /* rw & rev? */ return STOP_INVIOP; mt_inst = inst; /* save inst */ - if ((inst & DEV_MTS) && !(inst && DEV_OUT)) /* scanning? */ + if ((inst & DEV_MTS) && !(inst & DEV_OUT)) /* scanning? */ chan_set_flag (mt_dib.chan, CHF_SCAN); /* set chan flg */ xfr_req = xfr_req & ~XFR_MT0; /* clr xfr flag */ sim_activate (uptr, mt_gtime); /* start timer */ diff --git a/SDS/sds_sys.c b/SDS/sds_sys.c index cd87ea82..44f98173 100644 --- a/SDS/sds_sys.c +++ b/SDS/sds_sys.c @@ -1,6 +1,6 @@ /* sds_sys.c: SDS 940 simulator interface - Copyright (c) 2001-2008, Robert M Supnik + Copyright (c) 2001-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -22,6 +22,8 @@ Except as contained in this notice, the name of Robert M Supnik shall not be used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + + 19-Mar-12 RMS Fixed declarations of CCT arrays (Mark Pizzolato) */ #include "sds_defs.h" @@ -154,7 +156,8 @@ t_stat sim_load_cct (FILE *fileref) { int32 col, rpt, ptr, mask, cctbuf[CCT_LNT]; t_stat r; -extern int32 lpt_ccl, lpt_ccp, lpt_cct[CCT_LNT]; +extern int32 lpt_ccl, lpt_ccp; +extern uint8 lpt_cct[CCT_LNT]; char *cptr, cbuf[CBUFSIZE], gbuf[CBUFSIZE]; ptr = 0; diff --git a/VAX/vax780_sbi.c b/VAX/vax780_sbi.c index df49c22c..c33204eb 100644 --- a/VAX/vax780_sbi.c +++ b/VAX/vax780_sbi.c @@ -27,8 +27,8 @@ sbi bus controller - 21-Mar-2011 RMS Added autoreboot capability (from Mark Pizzalato) - 31-May-2008 RMS Fixed machine_check calling sequence (found by Peter Schorn) + 21-Mar-2011 RMS Added autoreboot capability (Mark Pizzalato) + 31-May-2008 RMS Fixed machine_check calling sequence (Peter Schorn) 03-May-2006 RMS Fixed writes to ACCS 28-May-2008 RMS Inlined physical memory routines */ diff --git a/VAX/vax780_stddev.c b/VAX/vax780_stddev.c index ae5da61c..f96fecd4 100644 --- a/VAX/vax780_stddev.c +++ b/VAX/vax780_stddev.c @@ -36,7 +36,7 @@ Synced keyboard to clock for idling 11-May-06 RMS Revised timer logic for EVKAE 22-Nov-05 RMS Revised for new terminal processing routines - 10-Mar-05 RMS Fixed bug in timer schedule routine (from Mark Hittinger) + 10-Mar-05 RMS Fixed bug in timer schedule routine (Mark Hittinger) 08-Sep-04 RMS Cloned from vax_stddev.c, vax_sysdev.c, and pdp11_rx.c The console floppy protocol is based on the description in the 1982 VAX diff --git a/VAX/vax780_syslist.c b/VAX/vax780_syslist.c index d35eb932..aad58dbd 100644 --- a/VAX/vax780_syslist.c +++ b/VAX/vax780_syslist.c @@ -23,7 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 17-May-06 RMS Added CR11/CD11 support (from John Dundas) + 17-May-06 RMS Added CR11/CD11 support (John Dundas) 01-Oct-04 RMS Cloned from vax_sys.c */ diff --git a/VAX/vax780_uba.c b/VAX/vax780_uba.c index 16e2e910..98acc15c 100644 --- a/VAX/vax780_uba.c +++ b/VAX/vax780_uba.c @@ -27,7 +27,7 @@ 19-Nov-08 RMS Moved I/O support routines to I/O library 28-May-08 RMS Inlined physical memory routines - 25-Jan-08 RMS Fixed declarations (from Mark Pizzolato) + 25-Jan-08 RMS Fixed declarations (Mark Pizzolato) */ #include "vax_defs.h" diff --git a/VAX/vax_cis.c b/VAX/vax_cis.c index e77680e4..e75a53b8 100644 --- a/VAX/vax_cis.c +++ b/VAX/vax_cis.c @@ -29,7 +29,7 @@ 16-Oct-08 RMS Fixed bug in ASHP left overflow calc (Word/NibbleLShift) Fixed bug in DIVx (LntDstr calculation) 28-May-08 RMS Inlined physical memory routines - 16-May-06 RMS Fixed bug in length calculation (found by Tim Stark) + 16-May-06 RMS Fixed bug in length calculation (Tim Stark) 03-May-06 RMS Fixed MOVTC, MOVTUC to preserve cc's through page faults Fixed MOVTUC to stop on translated == escape Fixed CVTPL to set registers before destination reg write @@ -38,7 +38,7 @@ Fixed EDITPC EO$BLANK_ZERO count, cc test Fixed EDITPC EO$INSERT to insert fill instead of blank Fixed EDITPC EO$LOAD_PLUS/MINUS to skip character - (all reported by Tim Stark) + (Tim Stark) 12-Apr-04 RMS Cloned from pdp11_cis.c and vax_cpu1.c Zero length decimal strings require either zero bytes (trailing) or one byte diff --git a/VAX/vax_cmode.c b/VAX/vax_cmode.c index 8af75a03..24c7f8ac 100644 --- a/VAX/vax_cmode.c +++ b/VAX/vax_cmode.c @@ -27,7 +27,7 @@ On a subset VAX, this module forces a fault if REI attempts to set PSL. 28-May-08 RMS Inlined physical memory routines - 25-Jan-08 RMS Fixed declaration (from Mark Pizzolato) + 25-Jan-08 RMS Fixed declaration (Mark Pizzolato) 03-May-06 RMS Fixed omission of SXT Fixed order of operand fetching in XOR 24-Aug-04 RMS Cloned from PDP-11 CPU diff --git a/VAX/vax_cpu.c b/VAX/vax_cpu.c index 6a46a7fb..a0aa2466 100644 --- a/VAX/vax_cpu.c +++ b/VAX/vax_cpu.c @@ -1,6 +1,6 @@ /* vax_cpu.c: VAX CPU - Copyright (c) 1998-2011, Robert M Supnik + Copyright (c) 1998-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -25,9 +25,19 @@ cpu VAX central processor + 20-Sep-11 MP Fixed idle conditions for various versions of Ultrix, + Quasijarus-4.3BSD, NetBSD and OpenBSD. + Note: Since NetBSD and OpenBSD are still actively + developed operating systems, new versions of + these OSes are moving targets with regard to + providing idle detection. At this time, recent versions + of OpenBSD have veered from the traditional OS idle + approach taken in the other BSD derived OSes. + Determining a reasonable idle detection pattern does + not seem possible for these versions. 13-Sep-11 RMS Fixed XFC, BPT to clear PSL before exception - (found by Camiel Vanderhoeven) - 23-Mar-11 RMS Revised for new idle design (from Mark Pizzolato) + (Camiel Vanderhoeven) + 23-Mar-11 RMS Revised for new idle design (Mark Pizzolato) 24-Apr-10 RMS Added OLDVMS idle timer option Fixed bug in SET CPU IDLE 21-May-08 RMS Removed inline support @@ -35,7 +45,7 @@ 13-Aug-07 RMS Fixed bug in read access g-format indexed specifiers 28-Apr-07 RMS Removed clock initialization 29-Oct-06 RMS Added idle support - 22-May-06 RMS Fixed format error in CPU history (found by Peter Schorn) + 22-May-06 RMS Fixed format error in CPU history (Peter Schorn) 10-May-06 RMS Added -kesu switches for virtual addressing modes Fixed bugs in examine virtual Rewrote history function for greater usability @@ -45,32 +55,31 @@ Fixed ACBD/G to test correct operand Fixed access checking on modify-class specifiers Fixed branch displacements in history buffer - (all reported by Tim Stark) + (Tim Stark) 17-Nov-05 RMS Fixed CVTfi with integer overflow to trap if PSW set 13-Nov-05 RMS Fixed breakpoint test with 64b addresses 25-Oct-05 RMS Removed cpu_extmem - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 16-Aug-05 RMS Fixed C++ declaration and cast problems 13-Jan-05 RMS Fixed initial state of cpu_extmem 06-Nov-04 RMS Added =n to SHOW HISTORY 30-Sep-04 RMS Added octaword specifier decodes and instructions Moved model-specific routines to system module 02-Sep-04 RMS Fixed bug in EMODD/G, second word of quad dst not probed - 28-Jun-04 RMS Fixed bug in DIVBx, DIVWx (reported by Peter Trimmel) + 28-Jun-04 RMS Fixed bug in DIVBx, DIVWx (Peter Trimmel) 18-Apr-04 RMS Added octaword macros 25-Jan-04 RMS Removed local debug logging support RMS,MP Added extended physical memory support 31-Dec-03 RMS Fixed bug in set_cpu_hist 21-Dec-03 RMS Added autoconfiguration controls - 29-Oct-03 RMS Fixed WriteB declaration (found by Mark Pizzolato) + 29-Oct-03 RMS Fixed WriteB declaration (Mark Pizzolato) 23-Sep-03 RMS Revised instruction history for dynamic sizing 17-May-03 RMS Fixed operand order in EMODx 23-Apr-03 RMS Revised for 32b/64b t_addr 05-Jan-02 RMS Added memory size restore support - 25-Dec-02 RMS Added instruction history (from Mark Pizzolato) + 25-Dec-02 RMS Added instruction history (Mark Pizzolato) 29-Sep-02 RMS Revised to build dib_tab dynamically - 14-Jul-02 RMS Added halt to console, infinite loop detection - (from Mark Pizzolato) + 14-Jul-02 RMS Added halt to console, infinite loop detection (Mark Pizzolato) 02-May-02 RMS Fixed bug in indexed autoincrement register logging 30-Apr-02 RMS Added TODR powerup routine 18-Apr-02 RMS Cleanup ambiguous signed left shifts @@ -178,9 +187,10 @@ #define UNIT_CONH (1u << UNIT_V_CONH) #define UNIT_MSIZE (1u << UNIT_V_MSIZE) #define GET_CUR acc = ACC_MASK (PSL_GETCUR (PSL)) -#define VAX_IDLE_VMS 0x1 -#define VAX_IDLE_ULT 0x2 -#define VAX_IDLE_QUAD 0x4 +#define VAX_IDLE_VMS 0x01 +#define VAX_IDLE_ULT 0x02 +#define VAX_IDLE_ULTOLD 0x04 +#define VAX_IDLE_QUAD 0x08 #define OPND_SIZE 16 #define INST_SIZE 52 @@ -450,6 +460,7 @@ REG cpu_reg[] = { { FLDATA (HLTPIN, hlt_pin, 0) }, { HRDATA (IDLE_MASK, cpu_idle_mask, 16), REG_HIDDEN }, { DRDATA (IDLE_INDX, cpu_idle_type, 4), REG_HRO }, + { DRDATA (IDLE_ENAB, sim_idle_enab, 4), REG_HRO }, { BRDATA (PCQ, pcq, 16, 32, PCQ_SIZE), REG_RO+REG_CIRC }, { HRDATA (PCQP, pcq_p, 6), REG_HRO }, { HRDATA (BADABO, badabo, 32), REG_HRO }, @@ -498,7 +509,7 @@ DEVICE cpu_dev = { t_stat sim_instr (void) { volatile int32 opc, cc; /* used by setjmp */ -int32 acc; /* set by setjmp */ +volatile int32 acc; /* set by setjmp */ int abortval; t_stat r; @@ -1574,16 +1585,13 @@ for ( ;; ) { case TSTL: CC_IIZZ_L (op0); /* set cc's */ if ((cc == CC_Z) && /* zero result and */ - ((mapen == 0)? /* physical mode? */ - (fault_PC == 0x20043619): /* cons prompt loop? */ - ((((PSL & PSL_IS) != 0) && /* on IS? */ - (PSL_GETIPL (PSL) == 0x1) && /* at IPL 1? */ - ((cpu_idle_mask & VAX_IDLE_ULT) != 0))|| /* running Ultrix or friends? */ - ((PSL_GETIPL (PSL) == 0x0) && /* at IPL 0? */ - ((fault_PC & 0x80000000) != 0) && /* in system space? */ - ((PC - fault_PC) == 6) && /* 6 byte instruction? */ - ((fault_PC & 0x7fffffff) < 0x4000) && /* in low system space? */ - ((cpu_idle_mask & VAX_IDLE_QUAD) != 0))))) /* running Quad or friends? */ + ((((cpu_idle_mask & VAX_IDLE_ULTOLD) && /* running Old Ultrix or friends? */ + (PSL_GETIPL (PSL) == 0x1)) || /* at IPL 1? */ + ((cpu_idle_mask & VAX_IDLE_QUAD) && /* running Quasijarus or friends? */ + (PSL_GETIPL (PSL) == 0x0))) && /* at IPL 0? */ + (fault_PC & 0x80000000) && /* in system space? */ + ((PC - fault_PC) == 6) && /* 6 byte instruction? */ + ((fault_PC & 0x7fffffff) < 0x4000))) /* in low system space? */ cpu_idle(); /* idle loop */ break; @@ -1791,6 +1799,14 @@ for ( ;; ) { case BITL: r = op1 & op0; /* calc result */ CC_IIZP_L (r); /* set cc's */ + if ((cc == CC_Z) && + (cpu_idle_mask & VAX_IDLE_ULT) && /* running Ultrix or friends? */ + ((PSL & PSL_IS) != 0) && /* on IS? */ + (PSL_GETIPL (PSL) == 0x18) && /* at IPL 18? */ + (fault_PC & 0x80000000) && /* in system space? */ + ((PC - fault_PC) == 8) && /* 8 byte instruction? */ + ((fault_PC & 0x7fffffff) < 0x6000)) /* in low system space? */ + cpu_idle(); /* idle loop */ break; /* Integer operates, 2 operand read/write, and 3 operand, also MOVQ @@ -2167,8 +2183,13 @@ for ( ;; ) { break; case BEQL: - if (cc & CC_Z) /* br if Z = 1 */ + if (cc & CC_Z) { /* br if Z = 1 */ BRANCHB (brdisp); + if (((PSL & PSL_IS) != 0) && /* on IS? */ + (PSL_GETIPL (PSL) == 0x1F) && /* at IPL 31 */ + (fault_PC == 0x2004361B)) /* Boot ROM Character Prompt */ + cpu_idle(); + } break; case BVC: @@ -3405,11 +3426,13 @@ struct os_idle { static struct os_idle os_tab[] = { { "VMS", VAX_IDLE_VMS }, - { "NETBSD", VAX_IDLE_ULT }, + { "NETBSD", VAX_IDLE_ULTOLD }, { "ULTRIX", VAX_IDLE_ULT }, + { "ULTRIXOLD", VAX_IDLE_ULTOLD }, { "OPENBSD", VAX_IDLE_QUAD }, + { "QUASIJARUS", VAX_IDLE_QUAD }, { "32V", VAX_IDLE_QUAD }, - { "ALL", VAX_IDLE_VMS|VAX_IDLE_ULT|VAX_IDLE_QUAD }, + { "ALL", VAX_IDLE_VMS|VAX_IDLE_ULTOLD|VAX_IDLE_ULT|VAX_IDLE_QUAD }, { NULL, 0 } }; @@ -3434,8 +3457,10 @@ return sim_set_idle (uptr, val, cptr, desc); t_stat cpu_show_idle (FILE *st, UNIT *uptr, int32 val, void *desc) { -if (sim_idle_enab && (cpu_idle_type != 0)) - fprintf (st, "idle enabled=%s", os_tab[cpu_idle_type - 1].name); +if (sim_idle_enab && (cpu_idle_type != 0)) { + fprintf (st, "idle=%s, ", os_tab[cpu_idle_type - 1].name); + sim_show_idle (st, uptr, val, desc); + } else fprintf (st, "idle disabled"); return SCPE_OK; } diff --git a/VAX/vax_cpu1.c b/VAX/vax_cpu1.c index 4dcc2f91..8d02ca17 100644 --- a/VAX/vax_cpu1.c +++ b/VAX/vax_cpu1.c @@ -23,14 +23,14 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 15-Mar-12 RMS Fixed potential integer overflow in LDPCTX (from Mark Pizzolato) + 15-Mar-12 RMS Fixed potential integer overflow in LDPCTX (Mark Pizzolato) 25-Nov-11 RMS Added VEC_QBUS test in interrupt handler - 23-Mar-11 RMS Revised idle design (from Mark Pizzolato) + 23-Mar-11 RMS Revised idle design (Mark Pizzolato) 28-May-08 RMS Inlined physical memory routines 29-Apr-07 RMS Separated base register access checks for 11/780 10-May-06 RMS Added access check on system PTE for 11/780 Added mbz check in LDPCTX for 11/780 - 22-Sep-06 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-06 RMS Fixed declarations (Sterling Garwood) 30-Sep-04 RMS Added conditionals for full VAX Moved emulation to vax_cis.c Moved model-specific IPRs to system module @@ -38,8 +38,8 @@ Fixed EXTxV, INSV double register PC reference fault 30-Apr-02 RMS Fixed interrupt/exception handler to clear traps 17-Apr-02 RMS Fixed pos > 31 test in bit fields (should be unsigned) - 14-Apr-02 RMS Fixed prv_mode handling for interrupts (found by Tim Stark) - Fixed PROBEx to mask mode to 2b (found by Kevin Handy) + 14-Apr-02 RMS Fixed prv_mode handling for interrupts (Tim Stark) + Fixed PROBEx to mask mode to 2b (Kevin Handy) This module contains the instruction simulators for diff --git a/VAX/vax_fpa.c b/VAX/vax_fpa.c index 222e52f0..1b15c179 100644 --- a/VAX/vax_fpa.c +++ b/VAX/vax_fpa.c @@ -1,6 +1,6 @@ /* vax_fpa.c - VAX f_, d_, g_floating instructions - Copyright (c) 1998-2011, Robert M Supnik + Copyright (c) 1998-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,9 +23,10 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 23-Mar-12 RMS Fixed missing arguments in 32b floating add (Mark Pizzolato) 15-Sep-11 RMS Fixed integer overflow bug in EMODx Fixed POLYx normalizing before add mask bug - (both from Camiel Vanderhoeven) + (Camiel Vanderhoeven) 28-May-08 RMS Inlined physical memory routines 16-May-06 RMS Fixed bug in 32b floating multiply routine Fixed bug in 64b extended modulus routine @@ -37,8 +38,8 @@ Fixed POLYF, POLYD, POLYG to mask mul reslt to 31b/63b/63b Fixed fp add routine to test for zero via fraction to support "denormal" argument from POLYF, POLYD, POLYG - (all reported by Tim Stark) - 27-Sep-05 RMS Fixed bug in 32b structure definitions (from Jason Stevens) + (Tim Stark) + 27-Sep-05 RMS Fixed bug in 32b structure definitions (Jason Stevens) 30-Sep-04 RMS Comment and formating changes based on vax_octa.c 18-Apr-04 RMS Moved format definitions to vax_defs.h 19-Jun-03 RMS Simplified add algorithm @@ -906,7 +907,7 @@ return rpackg (&a, flo); /* return frac */ /* Floating add */ -void vax_fadd (UFP *a, UFP *b) +void vax_fadd (UFP *a, UFP *b, uint32 mhi, uint32 mlo) { int32 ediff; UFP t; diff --git a/VAX/vax_io.c b/VAX/vax_io.c index a52d93ea..592c039c 100644 --- a/VAX/vax_io.c +++ b/VAX/vax_io.c @@ -26,7 +26,7 @@ qba Qbus adapter 28-May-08 RMS Inlined physical memory routines - 25-Jan-08 RMS Fixed declarations (from Mark Pizzolato) + 25-Jan-08 RMS Fixed declarations (Mark Pizzolato) 03-Dec-05 RMS Added SHOW QBA VIRT and ex/dep via map 05-Oct-05 RMS Fixed bug in autoconfiguration (missing XU) 25-Jul-05 RMS Revised autoconfiguration algorithm and interface @@ -34,11 +34,11 @@ Moved mem_err, crd_err interrupts here from vax_cpu.c 09-Sep-04 RMS Integrated powerup into RESET (with -p) 05-Sep-04 RMS Added CRD interrupt handling - 28-May-04 RMS Revised I/O dispatching (from John Dundas) + 28-May-04 RMS Revised I/O dispatching (John Dundas) 21-Mar-04 RMS Added RXV21 support 21-Dec-03 RMS Fixed bug in autoconfigure vector assignment; added controls - 21-Nov-03 RMS Added check for interrupt slot conflict (found by Dave Hittner) - 29-Oct-03 RMS Fixed WriteX declaration (found by Mark Pizzolato) + 21-Nov-03 RMS Added check for interrupt slot conflict (Dave Hittner) + 29-Oct-03 RMS Fixed WriteX declaration (Mark Pizzolato) 19-Apr-03 RMS Added optimized byte and word DMA routines 12-Mar-03 RMS Added logical name support 22-Dec-02 RMS Added console halt support diff --git a/VAX/vax_mmu.c b/VAX/vax_mmu.c index 1733d311..177b61e8 100644 --- a/VAX/vax_mmu.c +++ b/VAX/vax_mmu.c @@ -26,7 +26,7 @@ 21-Jul-08 RMS Removed inlining support 28-May-08 RMS Inlined physical memory routines 29-Apr-07 RMS Added address masking for system page table reads - 22-Sep-05 RMS Fixed declarations (from Sterling Garwood) + 22-Sep-05 RMS Fixed declarations (Sterling Garwood) 30-Sep-04 RMS Comment and formating changes 19-Sep-03 RMS Fixed upper/lower case linkage problems on VMS 01-Jun-03 RMS Fixed compilation problem with USE_ADDR64 diff --git a/VAX/vax_octa.c b/VAX/vax_octa.c index b4e0fd3e..efb1a99c 100644 --- a/VAX/vax_octa.c +++ b/VAX/vax_octa.c @@ -27,7 +27,7 @@ 15-Sep-11 RMS Fixed integer overflow bug in EMODH Fixed POLYH normalizing before add mask bug - (both from Camiel Vanderhoeven) + (Camiel Vanderhoeven) 28-May-08 RMS Inlined physical memory routines 10-May-06 RMS Fixed bug in reported VA on faulting cross-page write 03-May-06 RMS Fixed MNEGH to test negated sign, clear C @@ -40,7 +40,7 @@ Fixed fp add routine to test for zero via fraction to support "denormal" argument from POLYH Fixed EMODH to concatenate 15b of 16b extension - (all reported by Tim Stark) + (Tim Stark) 15-Jul-04 RMS Cloned from 32b VAX floating point implementation */ diff --git a/VAX/vax_sys.c b/VAX/vax_sys.c index b9f2b95c..149f67d9 100644 --- a/VAX/vax_sys.c +++ b/VAX/vax_sys.c @@ -26,7 +26,7 @@ 21-Mar-11 RMS Modified string for STOP_BOOT message 19-Nov-08 RMS Moved bad block routine to I/O library 03-Nov-05 RMS Added 780 stop codes - 04-Sep-05 RMS Fixed missing assignment (found by Peter Schorn) + 04-Sep-05 RMS Fixed missing assignment (Peter Schorn) 16-Aug-05 RMS Fixed C++ declaration and cast problems 15-Sep-04 RMS Fixed bugs in character display and parse 30-Sep-04 RMS Fixed bugs in parsing indirect displacement modes diff --git a/VAX/vax_syscm.c b/VAX/vax_syscm.c index edc17edf..40cec63b 100644 --- a/VAX/vax_syscm.c +++ b/VAX/vax_syscm.c @@ -24,8 +24,8 @@ in this Software without prior written authorization from Robert M Supnik. 22-May-10 RMS Fixed t_addr printouts for 64b big-endian systems - (found by Mark Pizzolato) - 12-Nov-06 RMS Fixed operand order in EIS instructions (found by W.F.J. Mueller) + (Mark Pizzolato) + 12-Nov-06 RMS Fixed operand order in EIS instructions (W.F.J. Mueller) 27-Sep-05 RMS Fixed warnings compiling with 64b addresses 15-Sep-04 RMS Cloned from pdp11_sys.c */ diff --git a/VAX/vax_sysdev.c b/VAX/vax_sysdev.c index 169456d9..67741e3e 100644 --- a/VAX/vax_sysdev.c +++ b/VAX/vax_sysdev.c @@ -32,10 +32,10 @@ cso console storage output sysd system devices (SSC miscellany) - 23-Dec-10 RMS Added power clear call to boot routine (from Mark Pizzolato) + 23-Dec-10 RMS Added power clear call to boot routine (Mark Pizzolato) 25-Oct-05 RMS Automated CMCTL extended memory 16-Aug-05 RMS Fixed C++ declaration and cast problems - 10-Mar-05 RMS Fixed bug in timer schedule routine (from Mark Hittinger) + 10-Mar-05 RMS Fixed bug in timer schedule routine (Mark Hittinger) 30-Sep-04 RMS Moved CADR, MSER, CONPC, CONPSL, machine_check, cpu_boot, con_halt here from vax_cpu.c Moved model-specific IPR's here from vax_cpu1.c @@ -46,10 +46,10 @@ Fixed calibration problems interval timer (Mark Pizzolato) 12-May-03 RMS Fixed compilation warnings from VC.Net 23-Apr-03 RMS Revised for 32b/64b t_addr - 19-Aug-02 RMS Removed unused variables (found by David Hittner) + 19-Aug-02 RMS Removed unused variables (David Hittner) Allowed NVR to be attached to file 30-May-02 RMS Widened POS to 32b - 28-Feb-02 RMS Fixed bug, missing end of table (found by Lars Brinkhoff) + 28-Feb-02 RMS Fixed bug, missing end of table (Lars Brinkhoff) */ #include "vax_defs.h" diff --git a/VAX/vax_syslist.c b/VAX/vax_syslist.c index aba7119c..054c5e43 100644 --- a/VAX/vax_syslist.c +++ b/VAX/vax_syslist.c @@ -24,7 +24,7 @@ in this Software without prior written authorization from Robert M Supnik. 17-Oct-06 RMS Re-ordered device list - 17-May-06 RMS Added CR11/CD11 support (from John Dundas) + 17-May-06 RMS Added CR11/CD11 support (John Dundas) 01-Oct-2004 RMS Cloned from vax_sys.c */ diff --git a/alpha/alpha_500au_syslist.c b/alpha/alpha_500au_syslist.c deleted file mode 100644 index 5acdc997..00000000 --- a/alpha/alpha_500au_syslist.c +++ /dev/null @@ -1,49 +0,0 @@ -/* alpha_500au_syslist.c: Alpha device list for 500au - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "alpha_defs.h" - -extern DEVICE cpu_dev; -extern DEVICE tlb_dev; -extern DEVICE ev5pal_dev; -extern DEVICE rom_dev; - -/* SCP data structures and interface routines - - sim_name simulator name - sim_devices array of pointers to simulated devices -*/ - -char sim_name[] = "Alpha"; - -DEVICE *sim_devices[] = { - &cpu_dev, - &tlb_dev, - &ev5pal_dev, - &rom_dev, - NULL - }; - diff --git a/alpha/alpha_cpu.c b/alpha/alpha_cpu.c deleted file mode 100644 index 7cacf0ea..00000000 --- a/alpha/alpha_cpu.c +++ /dev/null @@ -1,1865 +0,0 @@ -/* alpha_cpu.c: Alpha CPU simulator - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Alpha architecturally-defined CPU state: - - PC<63:0> program counter - R[0:31]<63:0> integer registers - F[0:31]<63:0> floating registers - FPCR<63:0> floating point control register - (only left 32b are implemented) - PCC<63:0> hardware cycle counter - trap_summ<6:0> arithmetic trap summary - trap_mask<63:0> arithmetic trap register mask - lock_flag load_locked flag - vax_flag<0> VAX compatibility interrupt flag - FEN<0> floating point enable flag - - The Alpha CPU privileged state is "soft" and varies significantly from - operating system to operating system. Alpha provides an intermediate layer - of software (called PALcode) that implements the privileged state as well - as a library of complex instruction functions. PALcode implementations - are chip specific and system specific, as well as OS specific. - - Alpha memory management is also "soft" and supported a variety of mapping - schemes. VMS and Unix use a three level page table and directly expose - the underlying 64b hardware PTE. NT uses a condensed 32b PTE. - - All Alpha instructions are 32b wide. There are five basic formats: PALcall, - branch, memory reference, integer operate, and floating operate. - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | - | opcode | PAL function | PAL - | | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | - | opcode | Ra | branch displacement | branch - | | | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | - | opcode | Ra | Rb | address displacement | memory - | | | | | reference - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | | | | - | opcode | Ra | Rb |0 0 0|0| function | Rc | integer - | | | | | | | | operate - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | - | literal |1| - | | | - +-+-+-+-+-+-+-+-+-+ - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | | | | - | opcode | Ra | Rb | trap|rnd| function | Rc | floating - | | | | | | | | operate - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - Memory reference format is also used for some two-operand operates; - the address displacement is the function code. - - This routine is the instruction decode routine for the Alpha. It - is called from the simulator control program to execute instructions - in simulated memory, starting at the simulated PC. It runs until an - enabled exception is encountered. - - General notes: - - 1. Traps and interrupts. Variable trap_summ summarizes the outstanding - trap requests (if any). Variable intr_summ summarizes the outstanding - interrupt requests (if any). - - 2. Interrupt requests are maintained in the int_req array, one word per - interrupt level, one bit per device. - - 3. Adding I/O devices. These modules must be modified: - - alpha_defs.h add device address and interrupt definitions - alpha_sys.c add sim_devices table entry -*/ - -#include "alpha_defs.h" - -#define UNIT_V_CONH (UNIT_V_UF + 0) /* halt to console */ -#define UNIT_V_MSIZE (UNIT_V_UF + 1) -#define UNIT_CONH (1 << UNIT_V_CONH) -#define UNIT_MSIZE (1 << UNIT_V_MSIZE) - -#define HIST_PC 0x2 -#define HIST_MIN 64 -#define HIST_MAX (1 << 18) - -typedef struct { - t_uint64 pc; - uint32 ir; - uint32 filler; - t_uint64 ra; - t_uint64 rb; - } InstHistory; - -#define H_A 0x01 -#define H_B 0x02 -#define H_B_LIT 0x04 -#define H_EA 0x08 -#define H_EA_B 0x10 -#define H_EA_L16 0x20 -#define H_MRF (H_A|H_B|H_EA) -#define H_BRA (H_A|H_EA|H_EA_B) -#define H_IOP (H_A|H_B|H_B_LIT) -#define H_FOP (H_A|H_B) -#define H_PAL (H_A|H_EA|H_EA_L16) -#define H_JMP (H_A|H_B|H_EA|H_EA_L16) - -t_uint64 *M = 0; /* memory */ -t_uint64 R[32]; /* integer reg */ -t_uint64 FR[32]; /* floating reg */ -t_uint64 PC; /* PC, <1:0> MBZ */ -uint32 pc_align = 0; /* PC<1:0> */ -t_uint64 trap_mask = 0; /* trap reg mask */ -uint32 trap_summ = 0; /* trap summary */ -uint32 fpcr = 0; /* fp ctrl reg */ -uint32 pcc_l = 0; /* rpcc high */ -uint32 pcc_h = 0; /* rpcc low */ -uint32 pcc_enb = 0; -uint32 arch_mask = AMASK_BWX | AMASK_PRC; /* arch mask */ -uint32 impl_ver = IMPLV_EV5; /* impl version */ -uint32 lock_flag = 0; /* load lock flag */ -uint32 vax_flag = 0; /* vax intr flag */ -uint32 intr_summ = 0; /* interrupt summary */ -uint32 pal_mode = 1; /* PAL mode */ -uint32 pal_type = PAL_UNDF; /* PAL type */ -uint32 dmapen = 0; /* data mapping enable */ -uint32 fpen = 0; /* flt point enabled */ -uint32 ir = 0; /* instruction register */ -t_uint64 p1 = 0; /* exception parameter */ -uint32 int_req[IPL_HLVL] = { 0 }; /* interrupt requests */ -REG *pcq_r = NULL; /* PC queue reg ptr */ -t_uint64 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ -int32 pcq_p = 0; /* PC queue ptr */ -uint32 cpu_astop = 0; -uint32 hst_p = 0; /* history pointer */ -uint32 hst_lnt = 0; /* history length */ -InstHistory *hst = NULL; /* instruction history */ -jmp_buf save_env; - -const t_uint64 byte_mask[8] = { - 0x00000000000000FF, 0x000000000000FF00, - 0x0000000000FF0000, 0x00000000FF000000, - 0x000000FF00000000, 0x0000FF0000000000, - 0x00FF000000000000, 0xFF00000000000000 - }; - -const t_uint64 word_mask[4] = { - 0x000000000000FFFF, 0x00000000FFFF0000, - 0x0000FFFF00000000, 0xFFFF000000000000 - }; - -extern int32 sim_interval; -extern int32 sim_int_char; -extern FILE *sim_deb; -extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ - -t_uint64 uemul64 (t_uint64 a, t_uint64 b, t_uint64 *hi); -t_uint64 byte_zap (t_uint64 op, uint32 mask); -t_stat cpu_reset (DEVICE *dptr); -t_stat cpu_boot (int32 unitno, DEVICE *dptr); -t_stat cpu_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); -t_stat cpu_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw); -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat cpu_show_virt (FILE *of, UNIT *uptr, int32 val, void *desc); -t_stat cpu_fprint_one_inst (FILE *st, uint32 ir, t_uint64 pc, t_uint64 ra, t_uint64 rb); - -extern t_uint64 op_ldf (t_uint64 op); -extern t_uint64 op_ldg (t_uint64 op); -extern t_uint64 op_lds (t_uint64 op); -extern t_uint64 op_stf (t_uint64 op); -extern t_uint64 op_stg (t_uint64 op); -extern t_uint64 op_sts (t_uint64 op); -extern t_uint64 vax_sqrt (uint32 ir, t_bool dp); -extern t_uint64 ieee_sqrt (uint32 ir, t_bool dp); -extern void vax_fop (uint32 ir); -extern void ieee_fop (uint32 ir); -extern t_stat pal_19 (uint32 ir); -extern t_stat pal_1b (uint32 ir); -extern t_stat pal_1d (uint32 ir); -extern t_stat pal_1e (uint32 ir); -extern t_stat pal_1f (uint32 ir); -extern t_uint64 trans_c (t_uint64 va); -extern t_stat cpu_show_tlb (FILE *of, UNIT *uptr, int32 val, void *desc); -extern t_stat pal_eval_intr (uint32 flag); -extern t_stat pal_proc_excp (uint32 type); -extern t_stat pal_proc_trap (uint32 type); -extern t_stat pal_proc_intr (uint32 type); -extern t_stat pal_proc_inst (uint32 fnc); -extern uint32 tlb_set_cm (int32 cm); - -/* CPU data structures - - cpu_dev CPU device descriptor - cpu_unit CPU unit - cpu_reg CPU register list - cpu_mod CPU modifier list -*/ - -UNIT cpu_unit = { UDATA (NULL, UNIT_FIX + UNIT_BINK, INITMEMSIZE) }; - -REG cpu_reg[] = { - { HRDATA (PC, PC, 64), PV_LEFT }, - { HRDATA (PCALG, pc_align, 3) }, - { HRDATA (R0, R[0], 64) }, - { HRDATA (R1, R[1], 64) }, - { HRDATA (R2, R[2], 64) }, - { HRDATA (R3, R[3], 64) }, - { HRDATA (R4, R[4], 64) }, - { HRDATA (R5, R[5], 64) }, - { HRDATA (R6, R[6], 64) }, - { HRDATA (R7, R[7], 64) }, - { HRDATA (R8, R[8], 64) }, - { HRDATA (R9, R[9], 64) }, - { HRDATA (R10, R[10], 64) }, - { HRDATA (R11, R[11], 64) }, - { HRDATA (R12, R[12], 64) }, - { HRDATA (R13, R[13], 64) }, - { HRDATA (R14, R[14], 64) }, - { HRDATA (R15, R[15], 64) }, - { HRDATA (R16, R[16], 64) }, - { HRDATA (R17, R[17], 64) }, - { HRDATA (R18, R[18], 64) }, - { HRDATA (R19, R[19], 64) }, - { HRDATA (R20, R[20], 64) }, - { HRDATA (R21, R[21], 64) }, - { HRDATA (R22, R[22], 64) }, - { HRDATA (R23, R[23], 64) }, - { HRDATA (R24, R[24], 64) }, - { HRDATA (R25, R[25], 64) }, - { HRDATA (R26, R[26], 64) }, - { HRDATA (R27, R[27], 64) }, - { HRDATA (R28, R[28], 64) }, - { HRDATA (R29, R[29], 64) }, - { HRDATA (R30, R[30], 64) }, - { HRDATA (R31, R[31], 64), REG_RO }, - { HRDATA (F0, FR[0], 64) }, - { HRDATA (F1, FR[1], 64) }, - { HRDATA (F2, FR[2], 64) }, - { HRDATA (F3, FR[3], 64) }, - { HRDATA (F4, FR[4], 64) }, - { HRDATA (F5, FR[5], 64) }, - { HRDATA (F6, FR[6], 64) }, - { HRDATA (F7, FR[7], 64) }, - { HRDATA (F8, FR[8], 64) }, - { HRDATA (F9, FR[9], 64) }, - { HRDATA (F10, FR[10], 64) }, - { HRDATA (F11, FR[11], 64) }, - { HRDATA (F12, FR[12], 64) }, - { HRDATA (F13, FR[13], 64) }, - { HRDATA (F14, FR[14], 64) }, - { HRDATA (F15, FR[15], 64) }, - { HRDATA (F16, FR[16], 64) }, - { HRDATA (F17, FR[17], 64) }, - { HRDATA (F18, FR[18], 64) }, - { HRDATA (F19, FR[19], 64) }, - { HRDATA (F20, FR[20], 64) }, - { HRDATA (F21, FR[21], 64) }, - { HRDATA (F22, FR[22], 64) }, - { HRDATA (F23, FR[23], 64) }, - { HRDATA (F24, FR[24], 64) }, - { HRDATA (F25, FR[25], 64) }, - { HRDATA (F26, FR[26], 64) }, - { HRDATA (F27, FR[27], 64) }, - { HRDATA (F28, FR[28], 64) }, - { HRDATA (F29, FR[29], 64) }, - { HRDATA (F30, FR[30], 64) }, - { HRDATA (F31, FR[31], 64), REG_RO }, - { HRDATA (FPCR, fpcr, 32) }, - { FLDATA (FEN, fpen, 0) }, - { HRDATA (TRAPS, trap_summ, 8) }, - { HRDATA (TRAPM, trap_mask, 64) }, - { HRDATA (PCCH, pcc_h, 32) }, - { HRDATA (PCCL, pcc_l, 32) }, - { FLDATA (LOCK, lock_flag, 0) }, - { FLDATA (VAXF, vax_flag, 0) }, - { FLDATA (PALMODE, pal_mode, 0) }, - { HRDATA (PALTYPE, pal_type, 2), REG_HRO }, - { HRDATA (DMAPEN, dmapen, 0) }, - { HRDATA (AMASK, arch_mask, 13), REG_RO }, - { HRDATA (IMPLV, impl_ver, 2), REG_RO }, - { BRDATA (PCQ, pcq, 16, 32, PCQ_SIZE), REG_RO+REG_CIRC }, - { HRDATA (PCQP, pcq_p, 6), REG_HRO }, - { HRDATA (WRU, sim_int_char, 8) }, - { NULL } - }; - -MTAB cpu_mod[] = { - { UNIT_MSIZE, (1u << 25), NULL, "32M", &cpu_set_size }, - { UNIT_MSIZE, (1u << 26), NULL, "64M", &cpu_set_size }, - { UNIT_MSIZE, (1u << 27), NULL, "128M", &cpu_set_size }, - { UNIT_MSIZE, (1u << 28), NULL, "256M", &cpu_set_size }, - { UNIT_MSIZE, (1u << 29), NULL, "512M", &cpu_set_size }, - { UNIT_CONH, 0, "HALT to SIMH", "SIMHALT", NULL }, - { UNIT_CONH, UNIT_CONH, "HALT to console", "CONHALT", NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "VIRTUAL", NULL, - NULL, &cpu_show_virt }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "ITLB", NULL, - NULL, &cpu_show_tlb }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 1, "DTLB", NULL, - NULL, &cpu_show_tlb }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY", - &cpu_set_hist, &cpu_show_hist }, - { 0 } - }; - -DEVICE cpu_dev = { - "CPU", &cpu_unit, cpu_reg, cpu_mod, - 1, 16, 48, 8, 16, 64, - &cpu_ex, &cpu_dep, &cpu_reset, - &cpu_boot, NULL, NULL, - NULL, DEV_DYNM|DEV_DEBUG, 0, - NULL, &cpu_set_size, NULL - }; - -t_stat sim_instr (void) -{ -t_stat reason; -int abortval; -t_bool tracing; - -PC = PC | pc_align; /* put PC together */ -abortval = setjmp (save_env); /* set abort hdlr */ -if (abortval != 0) { /* exception? */ - if (abortval < 0) { /* SCP stop? */ - pcc_l = pcc_l & M32; - pcq_r->qptr = pcq_p; /* update pc q ptr */ - pc_align = ((uint32) PC) & 3; /* separate PC<1:0> */ - PC = PC & 0xFFFFFFFFFFFFFFFC; - return -abortval; - } - reason = pal_proc_excp (abortval); /* pal processing */ - } -else reason = 0; -tlb_set_cm (-1); /* resync cm */ -tracing = ((hst_lnt != 0) || DEBUG_PRS (cpu_dev)); - -intr_summ = pal_eval_intr (1); /* eval interrupts */ - -/* Main instruction loop */ - -while (reason == 0) { - - int32 i; - uint32 op, ra, rb, rc, fnc, sc, s32, t32, sgn; - t_int64 s1, s2, sr; - t_uint64 ea, dsp, rbv, res, s64, t64; - - if (cpu_astop) { /* debug stop? */ - cpu_astop = 0; /* clear */ - reason = SCPE_STOP; /* stop simulation */ - break; - } - - if (sim_interval <= 0) { /* chk clock queue */ - if (reason = sim_process_event ()) break; - intr_summ = pal_eval_intr (1); /* eval interrupts */ - } - - if (intr_summ && !pal_mode) { /* interrupt pending? */ - reason = pal_proc_intr (intr_summ); /* pal processing */ - intr_summ = pal_eval_intr (1); /* eval interrupts */ - continue; - } - - if (sim_brk_summ && sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */ - reason = STOP_IBKPT; /* stop simulation */ - break; - } - - sim_interval = sim_interval - 1; /* count instr */ - pcc_l = pcc_l + pcc_enb; - ir = ReadI (PC); /* get instruction */ - op = I_GETOP (ir); /* get opcode */ - ra = I_GETRA (ir); /* get ra */ - rb = I_GETRB (ir); /* get rb */ - - if (tracing) { /* trace or history? */ - if (hst_lnt) { /* history enabled? */ - hst_p = (hst_p + 1); /* next entry */ - if (hst_p >= hst_lnt) hst_p = 0; - hst[hst_p].pc = PC | pc_align | HIST_PC; /* save PC */ - hst[hst_p].ir = ir; /* save ir */ - hst[hst_p].ra = R[ra]; /* save Ra */ - hst[hst_p].rb = R[rb]; /* save Rb */ - } - if (DEBUG_PRS (cpu_dev)) /* trace enabled? */ - cpu_fprint_one_inst (sim_deb, ir, PC | pc_align, R[ra], R[rb]); - } - - PC = (PC + 4) & M64; /* advance PC */ - switch (op) { - -/* Memory reference instructions */ - - case OP_LDA: /* LDA */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - R[ra] = ea; - } - break; - - case OP_LDAH: /* LDAH */ - if (ra != 31) { - dsp = I_GETMDSP (ir) << 16; - ea = (R[rb] + SEXT_L_Q (dsp)) & M64; - R[ra] = ea; - } - break; - - case OP_LDBU: /* LDBU */ - if (!(arch_mask & AMASK_BWX)) ABORT (EXC_RSVI); /* EV56 or later */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - R[ra] = ReadB (ea); - } - break; - - case OP_LDQ_U: /* LDQ_U */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - R[ra] = ReadQ (ea & ~7); /* ignore ea<2:0> */ - } - break; - - case OP_LDWU: /* LDWU */ - if (!(arch_mask & AMASK_BWX)) ABORT (EXC_RSVI); /* EV56 or later */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - R[ra] = ReadW (ea); - } - break; - - case OP_STW: /* STW */ - if (!(arch_mask & AMASK_BWX)) ABORT (EXC_RSVI); /* EV56 or later */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteW (ea, R[ra]); - break; - - case OP_STB: /* STB */ - if (!(arch_mask & AMASK_BWX)) ABORT (EXC_RSVI); /* EV56 or later */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteB (ea, R[ra]); - break; - - case OP_STQ_U: /* STQ_U */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteQ (ea & ~7, R[ra]); /* ignore ea<2:0> */ - break; - - case OP_LDF: /* LDF */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - FR[ra] = op_ldf (ReadL (ea)); /* swizzle bits */ - } - break; - - case OP_LDG: /* LDG */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - FR[ra] = op_ldg (ReadQ (ea)); /* swizzle bits */ - } - break; - - case OP_LDS: /* LDS */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - FR[ra] = op_lds (ReadL (ea)); /* swizzle bits */ - } - break; - - case OP_LDT: /* LDT */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - FR[ra] = ReadQ (ea); /* no swizzling needed */ - } - break; - - case OP_STF: /* STF */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteL (ea, op_stf (FR[ra])); /* swizzle bits */ - break; - - case OP_STG: /* STG */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteQ (ea, op_stg (FR[ra])); /* swizzle bits */ - break; - - case OP_STS: /* STS */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteL (ea, op_sts (FR[ra])); /* swizzle bits */ - break; - - case OP_STT: /* STT */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteQ (ea, FR[ra]); /* no swizzling needed */ - break; - - case OP_LDL: /* LDL */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - res = ReadL (ea); - R[ra] = SEXT_L_Q (res); - } - break; - - case OP_LDQ: /* LDQ */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - R[ra] = ReadQ (ea); - } - break; - - case OP_LDL_L: /* LDL_L */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - res = ReadL (ea); - R[ra] = SEXT_L_Q (res); - lock_flag = 1; /* set lock flag */ - } - break; - - case OP_LDQ_L: /* LDQ_L */ - if (ra != 31) { - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - R[ra] = ReadQ (ea); - lock_flag = 1; /* set lock flag */ - } - break; - - case OP_STL: /* STL */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteL (ea, R[ra]); - break; - - case OP_STQ: /* STQ */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - WriteQ (ea, R[ra]); - break; - - case OP_STL_C: /* STL_C */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - if (lock_flag) WriteL (ea, R[ra]); /* unlocking? ok */ - else R[ra] = 0; /* write fails */ - lock_flag = 0; /* clear lock */ - break; - - case OP_STQ_C: /* STQ_C */ - dsp = I_GETMDSP (ir); - ea = (R[rb] + SEXT_MDSP (dsp)) & M64; - if (lock_flag) WriteQ (ea, R[ra]); /* unlocking? ok */ - else R[ra] = 0; /* write fails */ - lock_flag = 0; /* clear lock */ - break; - -/* Control instructions */ - - case OP_JMP: /* JMP */ - PCQ_ENTRY; - rbv = R[rb]; /* in case Ra = Rb */ - if (ra != 31) R[ra] = PC; /* save PC */ - PC = rbv; /* jump */ - break; - - case OP_BR: /* BR, BSR */ - case OP_BSR: - PCQ_ENTRY; - if (ra != 31) R[ra] = PC; /* save PC */ - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; /* branch */ - break; - - case OP_FBEQ: /* FBEQ */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if ((FR[ra] & ~FPR_SIGN) == 0) { /* +0 or - 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_FBLT: /* FBLT */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (FR[ra] > FPR_SIGN) { /* -0 to -n? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_FBLE: /* FBLE */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if ((FR[ra] & FPR_SIGN) || (FR[ra] == 0)) { /* - or 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_FBNE: /* FBNE */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if ((FR[ra] & ~FPR_SIGN) != 0) { /* not +0 or -0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_FBGE: /* FBGE */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (FR[ra] <= FPR_SIGN) { /* +0 to +n? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_FBGT: /* FBGT */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - if (!(FR[ra] & FPR_SIGN) && (FR[ra] != 0)) { /* not - and not 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BLBC: /* BLBC */ - if ((R[ra] & 1) == 0) { /* R<0> == 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BEQ: /* BEQ */ - if (R[ra] == 0) { /* R == 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BLT: /* BLT */ - if (R[ra] & Q_SIGN) { /* R<63> == 1? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BLE: /* BLE */ - if ((R[ra] == 0) || (R[ra] & Q_SIGN)) { /* R == 0 || R<63> == 1? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BLBS: /* BLBS */ - if ((R[ra] & 1) != 0) { /* R<0> == 1? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BNE: /* BNE */ - if (R[ra] != 0) { /* R != 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BGE: /* BGE */ - if (!(R[ra] & Q_SIGN)) { /* R<63> == 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - - case OP_BGT: /* BGT */ - if ((R[ra] != 0) && !(R[ra] & Q_SIGN)) { /* R != 0 && R<63> == 0? */ - PCQ_ENTRY; - dsp = I_GETBDSP (ir); - PC = (PC + (SEXT_BDSP (dsp) << 2)) & M64; - } - break; - -/* Integer arithmetic operates (10) */ - - case OP_IALU: /* integer arith opr */ - rc = I_GETRC (ir); /* get rc */ - if (ir & I_ILIT) rbv = I_GETLIT8 (ir); /* literal? rbv = lit */ - else rbv = R[rb]; /* no, rbv = R[rb] */ - fnc = I_GETIFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x00: /* ADDL */ - res = SEXT_L_Q (R[ra] + rbv); - break; - - case 0x02: /* S4ADDL */ - res = SEXT_L_Q ((R[ra] << 2) + rbv); - break; - - case 0x09: /* SUBL */ - res = SEXT_L_Q (R[ra] - rbv); - break; - - case 0x0B: /* S4SUBL */ - res = SEXT_L_Q ((R[ra] << 2) - rbv); - break; - - case 0x0F: /* CMPBGE */ - for (i = 0, res = 0; i < 8; i++) { - if ((R[ra] & byte_mask[i]) >= (rbv & byte_mask[i])) - res = res | ((t_uint64) 1u << i); - } - break; - - case 0x12: /* S8ADDL */ - res = SEXT_L_Q ((R[ra] << 3) + rbv); - break; - - case 0x1B: /* S8SUBL */ - res = SEXT_L_Q ((R[ra] << 3) - rbv); - break; - - case 0x1D: /* CMPULT */ - res = (R[ra] < rbv); - break; - - case 0x20: /* ADDQ */ - res = R[ra] + rbv; - break; - - case 0x22: /* S4ADDQ */ - res = (R[ra] << 2) + rbv; - break; - - case 0x29: /* SUBQ */ - res = R[ra] - rbv; - break; - - case 0x2B: /* S4SUBQ */ - res = (R[ra] << 2) - rbv; - break; - - case 0x2D: /* CMPEQ */ - res = (R[ra] == rbv); - break; - - case 0x32: /* S8ADDQ */ - res = (R[ra] << 3) + rbv; - break; - - case 0x3B: /* S8SUBQ */ - res = (R[ra] << 3) - rbv; - break; - - case 0x3D: /* CMPULE */ - res = (R[ra] <= rbv); - break; - - case 0x40: /* ADDL/V */ - res = SEXT_L_Q (R[ra] + rbv); - if (((~R[ra] ^ rbv) & (R[ra] ^ res)) & L_SIGN) - arith_trap (TRAP_IOV, ir); - break; - - case 0x49: /* SUBL/V */ - res = SEXT_L_Q (R[ra] - rbv); - if (((R[ra] ^ rbv) & (~rbv ^ res)) & L_SIGN) - arith_trap (TRAP_IOV, ir); - break; - - case 0x4D: /* CMPLT */ - sgn = Q_GETSIGN (R[ra]); /* get Ra sign */ - if (sgn ^ Q_GETSIGN (rbv)) res = sgn; /* signs diff? */ - else res = sgn ^ (R[ra] < rbv); - break; - - case 0x60: /* ADDQ/V */ - res = R[ra] + rbv; - if (((~R[ra] ^ rbv) & (R[ra] ^ res)) & Q_SIGN) - arith_trap (TRAP_IOV, ir); - break; - - case 0x69: /* SUBQ/V */ - res = R[ra] - rbv; - if (((R[ra] ^ rbv) & (~rbv ^ res)) & Q_SIGN) - arith_trap (TRAP_IOV, ir); - break; - - case 0x6D: /* CMPLE */ - if (R[ra] == rbv) res = 1; - else { - sgn = Q_GETSIGN (R[ra]); /* get Ra sign */ - if (sgn ^ Q_GETSIGN (rbv)) res = sgn; /* signs diff? */ - else res = sgn ^ (R[ra] < rbv); - } - - break; - default: - res = R[rc]; - break; - } - - if (rc != 31) R[rc] = res & M64; - break; - -/* Integer logical operates (11) */ - - case OP_ILOG: /* integer logic opr */ - rc = I_GETRC (ir); /* get rc */ - if (ir & I_ILIT) rbv = I_GETLIT8 (ir); /* literal? rbv = lit */ - else rbv = R[rb]; /* no, rbv = R[rb] */ - fnc = I_GETIFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x00: /* AND */ - res = R[ra] & rbv; - break; - - case 0x08: /* BIC */ - res = R[ra] & ~rbv; - break; - - case 0x14: /* CMOVLBS */ - if ((R[ra] & 1) != 0) res = rbv; - else res = R[rc]; - break; - - case 0x16: /* CMOVLBC */ - if ((R[ra] & 1) == 0) res = rbv; - else res = R[rc]; - break; - - case 0x20: /* BIS */ - res = R[ra] | rbv; - break; - - case 0x24: /* CMOVEQ */ - if (R[ra] == 0) res = rbv; - else res = R[rc]; - break; - - case 0x26: /* CMOVNE */ - if (R[ra] != 0) res = rbv; - else res = R[rc]; - break; - - case 0x28: /* ORNOT */ - res = R[ra] | ~rbv; - break; - - case 0x40: /* XOR */ - res = R[ra] ^ rbv; - break; - - case 0x44: /* CMOVLT */ - if (R[ra] & Q_SIGN) res = rbv; - else res = R[rc]; - break; - - case 0x46: /* CMOVGE */ - if (!(R[ra] & Q_SIGN)) res = rbv; - else res = R[rc]; - break; - - case 0x48: /* EQV */ - res = R[ra] ^ ~rbv; - break; - - case 0x61: /* AMASK */ - res = rbv & ~arch_mask; - break; - - case 0x64: /* CMOVLE */ - if ((R[ra] & Q_SIGN) || (R[ra] == 0)) res = rbv; - else res = R[rc]; - break; - - case 0x66: /* CMOVGT */ - if (!(R[ra] & Q_SIGN) && (R[ra] != 0)) res = rbv; - else res = R[rc]; - break; - - case 0x6C: /* IMPLVER */ - res = impl_ver; - break; - - default: - res = R[rc]; - break; - } - - if (rc != 31) R[rc] = res & M64; - break; - -/* Integer logical shifts (12) */ - - case OP_ISHFT: /* integer shifts */ - rc = I_GETRC (ir); /* get rc */ - if (ir & I_ILIT) rbv = I_GETLIT8 (ir); /* literal? rbv = lit */ - else rbv = R[rb]; /* no, rbv = R[rb] */ - fnc = I_GETIFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x02: /* MSKBL */ - sc = ((uint32) rbv) & 7; - res = byte_zap (R[ra], 0x1 << sc); - break; - - case 0x06: /* EXTBL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = (R[ra] >> sc) & M8; - break; - - case 0x0B: /* INSBL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = (R[ra] & M8) << sc; - break; - - case 0x12: /* MSKWL */ - sc = ((uint32) rbv) & 7; - res = byte_zap (R[ra], 0x3 << sc); - break; - - case 0x16: /* EXTWL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = (R[ra] >> sc) & M16; - break; - - case 0x1B: /* INSWL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = (R[ra] & M16) << sc; - break; - - case 0x22: /* MSKLL */ - sc = ((uint32) rbv) & 7; - res = byte_zap (R[ra], 0xF << sc); - break; - - case 0x26: /* EXTLL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = (R[ra] >> sc) & M32; - break; - - case 0x2B: /* INSLL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = (R[ra] & M32) << sc; - break; - - case 0x30: /* ZAP */ - res = byte_zap (R[ra], (uint32) rbv); - break; - - case 0x31: /* ZAPNOT */ - res = byte_zap (R[ra], ~((uint32) rbv)); - break; - - case 0x32: /* MSKQL */ - sc = ((uint32) rbv) & 7; - res = byte_zap (R[ra], 0xFF << sc); - break; - - case 0x34: /* SRL */ - sc = ((uint32) rbv) & 0x3F; - res = R[ra] >> sc; - break; - - case 0x36: /* EXTQL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = R[ra] >> sc; - break; - - case 0x39: /* SLL */ - sc = ((uint32) rbv) & 0x3F; - res = R[ra] << sc; - break; - - case 0x3B: /* INSQL */ - sc = (((uint32) rbv) << 3) & 0x3F; - res = R[ra] << sc; - break; - - case 0x3C: /* SRA */ - sc = ((uint32) rbv) & 0x3F; - res = (R[ra] >> sc); - if (sc && (R[ra] & Q_SIGN)) res = res | - (((t_uint64) M64) << (64 - sc)); - break; - - case 0x52: /* MSKWH */ - sc = 8 - (((uint32) rbv) & 7); - res = byte_zap (R[ra], 0x3 >> sc); - break; - - case 0x57: /* EXTWH */ - sc = (64 - (((uint32) rbv) << 3)) & 0x3F; - res = (R[ra] << sc) & M16; - break; - - case 0x5A: /* INSWH */ - sc = (64 - (((uint32) rbv) << 3)) & 0x3F; - res = (R[ra] & M16) >> sc; - break; - - case 0x62: /* MSKLH */ - sc = 8 - (((uint32) rbv) & 7); - res = byte_zap (R[ra], 0xF >> sc); - break; - - case 0x67: /* EXTLH */ - sc = (64 - (((uint32) rbv) << 3)) & 0x3F; - res = (R[ra] << sc) & M32; - break; - - case 0x6A: /* INSLH */ - sc = (64 - (((uint32) rbv) << 3)) & 0x3F; - res = (R[ra] & M32) >> sc; - break; - - case 0x72: /* MSKQH */ - sc = 8 - (((uint32) rbv) & 7); - res = byte_zap (R[ra], 0xFF >> sc); - break; - - case 0x77: /* EXTQH */ - sc = (64 - (((uint32) rbv) << 3)) & 0x3F; - res = R[ra] << sc; - break; - - case 0x7A: /* INSQH */ - sc = (64 - (((uint32) rbv) << 3)) & 0x3F; - res = R[ra] >> sc; - break; - - default: - res = R[rc]; - break; - } - - if (rc != 31) R[rc] = res & M64; - break; - -/* Integer multiply (13) */ - - case OP_IMUL: /* integer multiply */ - rc = I_GETRC (ir); /* get rc */ - if (ir & I_ILIT) rbv = I_GETLIT8 (ir); /* literal? rbv = lit */ - else rbv = R[rb]; /* no, rbv = R[rb] */ - fnc = I_GETIFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x00: /* MULL */ - s1 = SEXT_L_Q (R[ra]); - s2 = SEXT_L_Q (rbv); - sr = s1 * s2; - res = SEXT_L_Q (sr); - break; - - case 0x20: /* MULQ */ - res = uemul64 (R[ra], rbv, NULL); /* low 64b invariant */ - break; /* with sign/unsigned */ - - case 0x30: /* UMULH */ - uemul64 (R[ra], rbv, &res); - break; - - case 0x40: /* MULL/V */ - s1 = SEXT_L_Q (R[ra]); - s2 = SEXT_L_Q (rbv); - sr = s1 * s2; - res = SEXT_L_Q (sr); - if (((sr ^ res) & M64) != 0) /* overflow? */ - arith_trap (TRAP_IOV, ir); - break; - - case 0x60: /* MULQ/V */ - res = uemul64 (R[ra], rbv, &t64); - if (Q_GETSIGN(R[ra])) - t64 = (t64 - rbv) & M64; - if (Q_GETSIGN(rbv)) - t64 = (t64 - R[ra]) & M64; - if (Q_GETSIGN (res)? (t64 != M64): (t64 != 0)) - arith_trap (TRAP_IOV, ir); - break; - - default: - res = R[rc]; - break; - } - - if (rc != 31) R[rc] = res & M64; - break; - -/* FIX optional floating point set (14) */ - - case OP_IFLT: /* int to flt */ - if (!(arch_mask & AMASK_FIX)) ABORT (EXC_RSVI); /* EV56 or later */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - rc = I_GETRC (ir); /* get rc */ - fnc = I_GETFFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x04: /* ITOFS */ - if (ir & (I_FRND|I_FTRP)) ABORT (EXC_RSVI); - t32 = ((uint32) R[ra]) & M32; - res = op_lds (t32); - break; - - case 0x0A: /* SQRTF */ - if (ir & I_F_VAXRSV) ABORT (EXC_RSVI); - res = vax_sqrt (ir, DT_F); - break; - - case 0x0B: /* SQRTS */ - res = ieee_sqrt (ir, DT_S); - break; - - case 0x14: /* ITOFF */ - if (ir & (I_FRND|I_FTRP)) ABORT (EXC_RSVI); - t32 = ((uint32) R[ra]) & M32; - res = op_ldf (SWAP_VAXF (t32)); - break; - - case 0x24: /* ITOFT */ - if (ir & (I_FRND|I_FTRP)) ABORT (EXC_RSVI); - res = R[ra]; - break; - - case 0x2A: /* SQRTG */ - if (ir & I_F_VAXRSV) ABORT (EXC_RSVI); - res = vax_sqrt (ir, DT_G); - break; - - case 0x2B: /* SQRTT */ - res = ieee_sqrt (ir, DT_T); - break; - - default: - ABORT (EXC_RSVI); - } - - if (rc != 31) FR[rc] = res & M64; - break; - -/* VAX and IEEE floating point operates - done externally */ - - case OP_VAX: /* VAX fp opr */ - if (ir & I_F_VAXRSV) ABORT (EXC_RSVI); /* reserved */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - vax_fop (ir); - break; - - case OP_IEEE: /* IEEE fp opr */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - ieee_fop (ir); - break; - -/* Data type independent floating point (17) */ - - case OP_FP: /* other fp */ - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - rc = I_GETRC (ir); /* get rc */ - fnc = I_GETFFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x10: /* CVTLQ */ - res = ((FR[rb] >> 32) & 0xC0000000) | ((FR[rb] >> 29) & 0x3FFFFFFF); - res = SEXT_L_Q (res); - break; - - case 0x20: /* CPYS */ - res = (FR[ra] & FPR_SIGN) | (FR[rb] & ~FPR_SIGN); - break; - - case 0x21: /* CPYSN */ - res = ((FR[ra] & FPR_SIGN) ^ FPR_SIGN) | (FR[rb] & ~FPR_SIGN); - break; - - case 0x22: /* CPYSE */ - res = (FR[ra] & (FPR_SIGN|FPR_EXP)) | (FR[rb] & ~(FPR_SIGN|FPR_EXP)); - break; - - case 0x24: /* MT_FPCR */ - fpcr = ((uint32) (FR[ra] >> 32)) & ~FPCR_RAZ; - res = FR[rc]; - break; - - case 0x25: /* MF_FPCR */ - res = ((t_uint64) fpcr) << 32; - break; - - case 0x2A: /* FCMOVEQ */ - if ((FR[ra] & ~FPR_SIGN) == 0) res = FR[rb]; - else res = FR[rc]; - break; - - case 0x2B: /* FCMOVNE */ - if ((FR[ra] & ~FPR_SIGN) != 0) res = FR[rb]; - else res = FR[rc]; - break; - - case 0x2C: /* FCMOVLT */ - if (FR[ra] > FPR_SIGN) res = FR[rb]; - else res = FR[rc]; - break; - - case 0x2D: /* FCMOVGE */ - if (FR[ra] <= FPR_SIGN) res = FR[rb]; - else res = FR[rc]; - break; - - case 0x2E: /* FCMOVLE */ - if (FPR_GETSIGN (FR[ra]) || (FR[ra] == 0)) res = FR[rb]; - else res = FR[rc]; - break; - - case 0x2F: /* FCMOVGT */ - if (!FPR_GETSIGN (FR[ra]) && (FR[ra] != 0)) res = FR[rb]; - else res = FR[rc]; - break; - - case 0x30: /* CVTQL */ - res = ((FR[rb] & 0xC0000000) << 32) | ((FR[rb] & 0x3FFFFFFF) << 29); - if (FPR_GETSIGN (FR[rb])? - (FR[rb] < 0xFFFFFFFF80000000): - (FR[rb] > 0x000000007FFFFFFF)) { - fpcr = fpcr | FPCR_IOV | FPCR_INE | FPCR_SUM; - if (ir & I_FTRP_V) arith_trap (TRAP_IOV, ir); - } - break; - - default: - res = FR[rc]; - break; - } - - if (rc != 31) FR[rc] = res & M64; - break; - -/* Barriers and misc (18) - - Alpha has a weak memory ordering model and an imprecise exception model; - together, they require a wide variety of barrier instructions to guarantee - memory coherency in multiprocessor systems, as well as backward compatible - exception instruction semantics. - - The simulator is uniprocessor only, and has ordered memory accesses and - precise exceptions. Therefore, the barriers are all NOP's. */ - - case OP_MISC: /* misc */ - fnc = I_GETMDSP (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0xC000: /* RPCC */ - pcc_l = pcc_l & M32; - if (ra != 31) R[ra] = (((t_uint64) pcc_h) << 32) | ((t_uint64) pcc_l); - break; - - case 0xE000: /* RC */ - if (ra != 31) R[ra] = vax_flag; - vax_flag = 0; - break; - - case 0xF000: /* RS */ - if (ra != 31) R[ra] = vax_flag; - vax_flag = 1; - break; - - default: - break; - } - - break; - -/* Optional instruction sets (1C) */ - - case OP_FLTI: /* float to int */ - rc = I_GETRC (ir); /* get rc */ - if (ir & I_ILIT) rbv = I_GETLIT8 (ir); /* literal? rbv = lit */ - else rbv = R[rb]; /* no, rbv = R[rb] */ - fnc = I_GETIFNC (ir); /* get function */ - switch (fnc) { /* case on function */ - - case 0x00: /* SEXTB */ - if (!(arch_mask & AMASK_BWX)) ABORT (EXC_RSVI); - res = SEXT_B_Q (rbv); - break; - - case 0x01: /* SEXTW */ - if (!(arch_mask & AMASK_BWX)) ABORT (EXC_RSVI); - res = SEXT_W_Q (rbv); - break; - - case 0x30: /* CTPOP */ - if (!(arch_mask & AMASK_CIX)) ABORT (EXC_RSVI); - for (res = 0; rbv != 0; res++) { - rbv = rbv & ~(rbv & NEG_Q (rbv)); - } - break; - - case 0x31: /* PERR */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 64; i = i + 8) { - s32 = (uint32) (R[ra] >> i) & M8; - t32 = (uint32) (rbv >> i) & M8; - res = res + ((t_uint64) (s32 >= t32)? (s32 - t32): (t32 - s32)); - } - break; - - case 0x32: /* CTLZ */ - if (!(arch_mask & AMASK_CIX)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 64; i++) { - if ((rbv >> (63 - i)) & 1) break; - res = res + 1; - } - break; - - case 0x33: /* CTTZ */ - if (!(arch_mask & AMASK_CIX)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 64; i++) { - if ((rbv >> i) & 1) break; - res = res + 1; - } - break; - - case 0x34: /* UNPKBL */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - res = ((rbv & 0xFF00) << 24) | (rbv & 0xFF); - break; - - case 0x35: /* UNPKBW */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - res = ((rbv & 0xFF000000) << 24) | ((rbv & 0xFF0000) << 16) | - ((rbv & 0xFF00) << 8) | (rbv & 0xFF); - break; - - case 0x36: /* PKWB */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - res = ((rbv >> 24) & 0xFF000000) | ((rbv >> 16) & 0xFF0000) | - ((rbv >> 8) & 0xFF00) | (rbv & 0xFF); - break; - - case 0x37: /* PKLB */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - res = ((rbv >> 24) & 0xFF00) | (rbv & 0xFF); - break; - - case 0x38: /* MINSB8 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i++) { - s1 = SEXT_B_Q (R[ra] >> (i << 3)); - s2 = SEXT_B_Q (rbv >> (i << 3)); - res = res | (((s1 <= s2)? R[ra]: rbv) & byte_mask[i]); - } - break; - - case 0x39: /* MINSW4 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i = i++) { - s1 = SEXT_W_Q (R[ra] >> (i << 4)); - s2 = SEXT_W_Q (rbv >> (i << 4)); - res = res | (((s1 <= s2)? R[ra]: rbv) & word_mask[i]); - } - break; - - case 0x3A: /* MINUB8 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i++) { - s64 = R[ra] & byte_mask[i]; - t64 = rbv & byte_mask[i]; - res = res | ((s64 <= t64)? s64: t64); - } - break; - - case 0x3B: /* MINUW4 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i = i++) { - s64 = R[ra] & word_mask[i]; - t64 = rbv & word_mask[i]; - res = res | ((s64 <= t64)? s64: t64); - } - break; - - case 0x3C: /* MAXUB8 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i++) { - s64 = R[ra] & byte_mask[i]; - t64 = rbv & byte_mask[i]; - res = res | ((s64 >= t64)? s64: t64); - } - break; - - case 0x3D: /* MAXUW4 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i = i++) { - s64 = R[ra] & word_mask[i]; - t64 = rbv & word_mask[i]; - res = res | ((s64 >= t64)? s64: t64); - } - break; - - case 0x3E: /* MAXSB8 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i++) { - s1 = SEXT_B_Q (R[ra] >> (i << 3)); - s2 = SEXT_B_Q (rbv >> (i << 3)); - res = res | (((s1 >= s2)? R[ra]: rbv) & byte_mask[i]); - } - break; - - case 0x3F: /* MAXSW4 */ - if (!(arch_mask & AMASK_MVI)) ABORT (EXC_RSVI); - for (i = 0, res = 0; i < 8; i = i++) { - s1 = SEXT_W_Q (R[ra] >> (i << 4)); - s2 = SEXT_W_Q (rbv >> (i << 4)); - res = res | (((s1 >= s2)? R[ra]: rbv) & word_mask[i]); - } - break; - - case 0x70: /* FTOIS */ - if (!(arch_mask & AMASK_FIX)) ABORT (EXC_RSVI); - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - res = op_sts (FR[ra]); - break; - - case 0x78: /* FTOIT */ - if (!(arch_mask & AMASK_FIX)) ABORT (EXC_RSVI); - if (fpen == 0) ABORT (EXC_FPDIS); /* flt point disabled? */ - res = FR[ra]; - break; - - default: - ABORT (EXC_RSVI); - } - - if (rc != 31) R[rc] = res & M64; - break; - -/* PAL hardware functions */ - - case OP_PAL19: - reason = pal_19 (ir); - intr_summ = pal_eval_intr (1); /* eval interrupts */ - break; - - case OP_PAL1B: - reason = pal_1b (ir); - intr_summ = pal_eval_intr (1); /* eval interrupts */ - break; - - case OP_PAL1D: - reason = pal_1d (ir); - intr_summ = pal_eval_intr (1); /* eval interrupts */ - break; - - case OP_PAL1E: - reason = pal_1e (ir); - intr_summ = pal_eval_intr (1); /* eval interrupts */ - break; - - case OP_PAL1F: - reason = pal_1f (ir); - intr_summ = pal_eval_intr (1); /* eval interrupts */ - break; - - case OP_PAL: /* PAL code */ - fnc = I_GETPAL (ir); /* get function code */ - if ((fnc & 0x40) || (fnc >= 0xC0)) /* out of range? */ - ABORT (EXC_RSVI); - reason = pal_proc_inst (fnc); /* processed externally */ - intr_summ = pal_eval_intr (1); /* eval interrupts */ - break; - - default: - ABORT (EXC_RSVI); - } /* end case */ - if (trap_summ) { /* any traps? */ - reason = pal_proc_trap (trap_summ); /* process trap */ - trap_summ = 0; /* clear trap reg */ - trap_mask = 0; - intr_summ = pal_eval_intr (1); /* eval interrupts */ - } - } /* end while */ -pcc_l = pcc_l & M32; -pcq_r->qptr = pcq_p; /* update pc q ptr */ -pc_align = ((uint32) PC) & 3; /* separate PC<1:0> */ -PC = PC & 0xFFFFFFFFFFFFFFFC; -return reason; -} - -/* Utility routines */ - -/* Byte zap function */ - -t_uint64 byte_zap (t_uint64 op, uint32 m) -{ -int32 i; - -m = m & 0xFF; /* 8 bit mask */ -for (i = 0; m != 0; m = m >> 1, i++) { - if (m & 1) op = op & ~byte_mask[i]; - } -return op; -} - -/* 64b * 64b unsigned multiply */ - -t_uint64 uemul64 (t_uint64 a, t_uint64 b, t_uint64 *hi) -{ -t_uint64 ahi, alo, bhi, blo, rhi, rmid1, rmid2, rlo; - -ahi = (a >> 32) & M32; -alo = a & M32; -bhi = (b >> 32) & M32; -blo = b & M32; -rhi = ahi * bhi; -rmid1 = ahi * blo; -rmid2 = alo * bhi; -rlo = alo * blo; -rhi = rhi + ((rmid1 >> 32) & M32) + ((rmid2 >> 32) & M32); -rmid1 = (rmid1 << 32) & M64; -rmid2 = (rmid2 << 32) & M64; -rlo = (rlo + rmid1) & M64; -if (rlo < rmid1) rhi = rhi + 1; -rlo = (rlo + rmid2) & M64; -if (rlo < rmid2) rhi = rhi + 1; -if (hi) *hi = rhi & M64; -return rlo; -} - -/* 64b / 64b unsigned fraction divide */ - -t_uint64 ufdiv64 (t_uint64 dvd, t_uint64 dvr, uint32 prec, uint32 *sticky) -{ -t_uint64 quo; -uint32 i; - -quo = 0; /* clear quotient */ -for (i = 0; (i < prec) && dvd; i++) { /* divide loop */ - quo = quo << 1; /* shift quo */ - if (dvd >= dvr) { /* div step ok? */ - dvd = dvd - dvr; /* subtract */ - quo = quo + 1; /* quo bit = 1 */ - } - dvd = dvd << 1; /* shift divd */ - } -quo = quo << (UF_V_NM - i + 1); /* shift quo */ -if (sticky) *sticky = (dvd? 1: 0); /* set sticky bit */ -return quo; /* return quotient */ -} - -/* Set arithmetic trap */ - -void arith_trap (uint32 mask, uint32 ir) -{ -uint32 rc = I_GETRC (ir); - -trap_summ = trap_summ | mask; -if (ir & I_FTRP_S) trap_summ = trap_summ | TRAP_SWC; -if ((mask & TRAP_IOV) == 0) rc = rc + 32; -trap_mask = trap_mask | ((t_uint64) 1u << rc); -return; -} - -/* Reset */ - -t_stat cpu_reset (DEVICE *dptr) -{ -R[31] = 0; -FR[31] = 0; -pal_mode = 1; -dmapen = 0; -fpen = 1; -vax_flag = 0; -lock_flag = 0; -trap_summ = 0; -trap_mask = 0; -if (M == NULL) M = (t_uint64 *) calloc (((uint32) MEMSIZE) >> 3, sizeof (t_uint64)); -if (M == NULL) return SCPE_MEM; -pcq_r = find_reg ("PCQ", NULL, dptr); -if (pcq_r) pcq_r->qptr = 0; -else return SCPE_IERR; -sim_brk_types = sim_brk_dflt = SWMASK ('E'); -return SCPE_OK; -} - -/* Bootstrap */ - -t_stat cpu_boot (int32 unitno, DEVICE *dptr) -{ -return SCPE_ARG; -} - -/* Memory examine */ - -t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) -{ -if (vptr == NULL) return SCPE_ARG; -if (sw & SWMASK ('V') && dmapen) { - addr = trans_c (addr); - if (addr == M64) return STOP_MME; - } -if (ADDR_IS_MEM (addr)) { - *vptr = ReadPQ (addr); - return SCPE_OK; - } -return SCPE_NXM; -} - -/* Memory deposit */ - -t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) -{ -if (sw & SWMASK ('V') && dmapen) { - addr = trans_c (addr); - if (addr == M64) return STOP_MME; - } -if (ADDR_IS_MEM (addr)) { - WritePQ (addr, val); - return SCPE_OK; - } -return SCPE_NXM; -} - -/* Memory allocation */ - -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -t_uint64 mc = 0; -uint32 i, clim; -t_uint64 *nM = NULL; - -for (i = val; i < MEMSIZE; i = i + 8) mc = mc | M[i >> 3]; -if ((mc != 0) && !get_yn ("Really truncate memory [N]?", FALSE)) - return SCPE_OK; -nM = (t_uint64 *) calloc (val >> 3, sizeof (t_uint64)); -if (nM == NULL) return SCPE_MEM; -clim = (uint32) ((((uint32) val) < MEMSIZE)? val: MEMSIZE); -for (i = 0; i < clim; i = i + 8) nM[i >> 3] = M[i >>3]; -free (M); -M = nM; -MEMSIZE = val; -return SCPE_OK; -} - -/* Show virtual address */ - -t_stat cpu_show_virt (FILE *of, UNIT *uptr, int32 val, void *desc) -{ -t_stat r; -char *cptr = (char *) desc; -t_uint64 va, pa; - -if (cptr) { - DEVICE *dptr = find_dev_from_unit (uptr); - if (dptr == NULL) return SCPE_IERR; - va = get_uint (cptr, 16, M64, &r); - if (r == SCPE_OK) { - pa = trans_c (va); - if (pa == M64) { - fprintf (of, "Translation error\n"); - return SCPE_OK; - } - fputs ("Virtual ", of); - fprint_val (of, va, 16, 64, PV_LEFT); - fputs (" = physical ", of); - fprint_val (of, pa, 16, 64, PV_LEFT); - fputc ('\n', of); - return SCPE_OK; - } - } -fprintf (of, "Invalid argument\n"); -return SCPE_OK; -} - -/* Set history */ - -t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 i, lnt; -t_stat r; - -if (cptr == NULL) { - for (i = 0; i < hst_lnt; i++) hst[i].pc = 0; - hst_p = 0; - return SCPE_OK; - } -lnt = (uint32) get_uint (cptr, 10, HIST_MAX, &r); -if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) return SCPE_ARG; -hst_p = 0; -if (hst_lnt) { - free (hst); - hst_lnt = 0; - hst = NULL; - } -if (lnt) { - hst = (InstHistory *) calloc (lnt, sizeof (InstHistory)); - if (hst == NULL) return SCPE_MEM; - hst_lnt = lnt; - } -return SCPE_OK; -} - -/* Print instruction trace */ - -t_stat cpu_fprint_one_inst (FILE *st, uint32 ir, t_uint64 pc, t_uint64 ra, t_uint64 rb) -{ -uint32 op; -t_value sim_val; -extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val, - UNIT *uptr, int32 sw); - -static const h_fmt[64] = { - 0, 0, 0, 0, 0, 0, 0, 0, - H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, - H_IOP, H_IOP, H_IOP, H_IOP, H_FOP, H_FOP, H_FOP, H_FOP, - 0, H_PAL, H_JMP, H_PAL, H_FOP, H_PAL, H_PAL, H_PAL, - H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, - H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, H_MRF, - H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, - H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, H_BRA, H_BRA - }; - -pc = pc & ~HIST_PC; -fprint_val (st, pc, 16, 64, PV_RZRO); -fputc (' ', st); -op = I_GETOP (ir); /* get opcode */ -if (h_fmt[op] & H_A) fprint_val (st, ra, 16, 64, PV_RZRO); -else fputs (" ", st); -fputc (' ', st); -if (h_fmt[op] & H_B) { /* Rb? */ - t_uint64 rbv; - if ((h_fmt[op] & H_B_LIT) && (ir & I_ILIT)) - rbv = I_GETLIT8 (ir); /* literal? rbv = lit */ - else rbv = rb; /* no, rbv = R[rb] */ - fprint_val (st, rbv, 16, 64, PV_RZRO); - } -else fputs (" ", st); -fputc (' ', st); -if (h_fmt[op] & H_EA) { /* ea? */ - t_uint64 ea; - if (h_fmt[op] & H_EA_L16) ea = ir & M16; - else if (h_fmt[op] & H_EA_B) - ea = (pc + (SEXT_BDSP (I_GETBDSP (ir)) << 2)) & M64; - else ea = (rb + SEXT_MDSP (I_GETMDSP (ir))) & M64; - fprint_val (st, ea, 16, 64, PV_RZRO); - } -else fputs (" ", st); -fputc (' ', st); -if (pc & 4) sim_val = ((t_uint64) ir) << 32; -else sim_val = ir; -if ((fprint_sym (st, pc & ~03, &sim_val, &cpu_unit, SWMASK ('M'))) > 0) - fprintf (st, "(undefined) %08X", ir); -fputc ('\n', st); /* end line */ -return SCPE_OK; -} - -/* Show history */ - -t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -uint32 k, di, lnt; -char *cptr = (char *) desc; -t_stat r; -InstHistory *h; - -if (hst_lnt == 0) return SCPE_NOFNC; /* enabled? */ -if (cptr) { - lnt = (int32) get_uint (cptr, 10, hst_lnt, &r); - if ((r != SCPE_OK) || (lnt == 0)) return SCPE_ARG; - } -else lnt = hst_lnt; -di = hst_p - lnt; /* work forward */ -if (di < 0) di = di + hst_lnt; -fprintf (st, "PC Ra Rb IR\n\n"); -for (k = 0; k < lnt; k++) { /* print specified */ - h = &hst[(++di) % hst_lnt]; /* entry pointer */ - if (h->pc & HIST_PC) { /* instruction? */ - cpu_fprint_one_inst (st, h->ir, h->pc, h->ra, h->rb); - } /* end if */ - } /* end for */ -return SCPE_OK; -} diff --git a/alpha/alpha_defs.h b/alpha/alpha_defs.h deleted file mode 100644 index 6f1ee907..00000000 --- a/alpha/alpha_defs.h +++ /dev/null @@ -1,457 +0,0 @@ -/* alpha_defs.h: Alpha architecture definitions file - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Respectfully dedicated to the great people of the Alpha chip, systems, and - software development projects; and to the memory of Peter Conklin, of the - Alpha Program Office. -*/ - -#ifndef _ALPHA_DEFS_H_ -#define _ALPHA_DEFS_H_ 0 - -#include "sim_defs.h" -#include - -#if defined (__GNUC__) -#define INLINE inline -#else -#define INLINE -#endif - -/* Configuration */ - -#define INITMEMSIZE (1 << 24) /* !!debug!! */ -#define MEMSIZE (cpu_unit.capac) -#define ADDR_IS_MEM(x) ((x) < MEMSIZE) -#define DEV_DIB (1u << (DEV_V_UF + 0)) /* takes a DIB */ - -/* Simulator stops */ - -#define STOP_HALT 1 /* halt */ -#define STOP_IBKPT 2 /* breakpoint */ -#define STOP_NSPAL 3 /* non-supported PAL */ -#define STOP_KSNV 4 /* kernel stk inval */ -#define STOP_INVABO 5 /* invalid abort code */ -#define STOP_MME 6 /* console mem mgt error */ - -/* Bit patterns */ - -#define M8 0xFF -#define M16 0xFFFF -#define M32 0xFFFFFFFF -#define M64 0xFFFFFFFFFFFFFFFF -#define B_SIGN 0x80 -#define W_SIGN 0x8000 -#define L_SIGN 0x80000000 -#define Q_SIGN 0x8000000000000000 -#define Q_GETSIGN(x) (((uint32) ((x) >> 63)) & 1) - -/* Architectural variants */ - -#define AMASK_BWX 0x0001 /* byte/word */ -#define AMASK_FIX 0x0002 /* sqrt/flt-int moves */ -#define AMASK_CIX 0x0004 /* counts */ -#define AMASK_MVI 0x0100 /* multimedia */ -#define AMASK_PRC 0x0200 /* precise exceptions */ -#define AMASK_PFM 0x1000 /* prefetch w modify */ - -#define IMPLV_EV4 0x0 /* EV4 (21064) */ -#define IMPLV_EV5 0x1 /* EV5 (21164) */ -#define IMPLV_EV6 0x2 /* EV6 (21264) */ -#define IMPLV_EV7 0x3 /* EV7 (21364) */ - -/* Instruction formats */ - -#define I_V_OP 26 /* opcode */ -#define I_M_OP 0x3F -#define I_OP (I_M_OP << I_V_OP) -#define I_V_RA 21 /* Ra */ -#define I_M_RA 0x1F -#define I_V_RB 16 /* Rb */ -#define I_M_RB 0x1F -#define I_V_FTRP 13 /* floating trap mode */ -#define I_M_FTRP 0x7 -#define I_FTRP (I_M_FTRP << I_V_FTRP) -#define I_F_VAXRSV 0x4800 /* VAX reserved */ -#define I_FTRP_V 0x2000 /* /V trap */ -#define I_FTRP_U 0x2000 /* /U trap */ -#define I_FTRP_S 0x8000 /* /S trap */ -#define I_FTRP_SUI 0xE000 /* /SUI trap */ -#define I_FTRP_SVI 0xE000 /* /SVI trap */ -#define I_V_FRND 11 /* floating round mode */ -#define I_M_FRND 0x3 -#define I_FRND (I_M_FRND << I_V_FRND) -#define I_FRND_C 0 /* chopped */ -#define I_FRND_M 1 /* to minus inf */ -#define I_FRND_N 2 /* normal */ -#define I_FRND_D 3 /* dynamic */ -#define I_FRND_P 3 /* in FPCR: plus inf */ -#define I_V_FSRC 9 /* floating source */ -#define I_M_FSRC 0x3 -#define I_FSRC (I_M_FSRC << I_V_FSRC) -#define I_FSRC_X 0x0200 /* data type X */ -#define I_V_FFNC 5 /* floating function */ -#define I_M_FFNC 0x3F -#define I_V_LIT8 13 /* integer 8b literal */ -#define I_M_LIT8 0xFF -#define I_V_ILIT 12 /* literal flag */ -#define I_ILIT (1u << I_V_ILIT) -#define I_V_IFNC 5 /* integer function */ -#define I_M_IFNC 0x3F -#define I_V_RC 0 /* Rc */ -#define I_M_RC 0x1F -#define I_V_MDSP 0 /* memory displacement */ -#define I_M_MDSP 0xFFFF -#define I_V_BDSP 0 -#define I_M_BDSP 0x1FFFFF /* branch displacement */ -#define I_V_PALOP 0 -#define I_M_PALOP 0x3FFFFFF /* PAL subopcode */ -#define I_GETOP(x) (((x) >> I_V_OP) & I_M_OP) -#define I_GETRA(x) (((x) >> I_V_RA) & I_M_RA) -#define I_GETRB(x) (((x) >> I_V_RB) & I_M_RB) -#define I_GETLIT8(x) (((x) >> I_V_LIT8) & I_M_LIT8) -#define I_GETIFNC(x) (((x) >> I_V_IFNC) & I_M_IFNC) -#define I_GETFRND(x) (((x) >> I_V_FRND) & I_M_FRND) -#define I_GETFFNC(x) (((x) >> I_V_FFNC) & I_M_FFNC) -#define I_GETRC(x) (((x) >> I_V_RC) & I_M_RC) -#define I_GETMDSP(x) (((x) >> I_V_MDSP) & I_M_MDSP) -#define I_GETBDSP(x) (((x) >> I_V_BDSP) & I_M_BDSP) -#define I_GETPAL(x) (((x) >> I_V_PALOP) & I_M_PALOP) - -/* Floating point types */ - -#define DT_F 0 /* type F */ -#define DT_G 1 /* type G */ -#define DT_S 0 /* type S */ -#define DT_T 1 /* type T */ - -/* Floating point memory format (VAX F) */ - -#define F_V_SIGN 15 -#define F_SIGN (1u << F_V_SIGN) -#define F_V_EXP 7 -#define F_M_EXP 0xFF -#define F_BIAS 0x80 -#define F_EXP (F_M_EXP << F_V_EXP) -#define F_V_FRAC 29 -#define F_GETEXP(x) ((uint32) (((x) >> F_V_EXP) & F_M_EXP)) -#define SWAP_VAXF(x) ((((x) >> 16) & 0xFFFF) | (((x) & 0xFFFF) << 16)) - -/* Floating point memory format (VAX G) */ - -#define G_V_SIGN 15 -#define G_SIGN (1u << F_V_SIGN) -#define G_V_EXP 4 -#define G_M_EXP 0x7FF -#define G_BIAS 0x400 -#define G_EXP (G_M_EXP << G_V_EXP) -#define G_GETEXP(x) ((uint32) (((x) >> G_V_EXP) & G_M_EXP)) -#define SWAP_VAXG(x) ((((x) & 0x000000000000FFFF) << 48) | \ - (((x) & 0x00000000FFFF0000) << 16) | \ - (((x) >> 16) & 0x00000000FFFF0000) | \ - (((x) >> 48) & 0x000000000000FFFF)) - -/* Floating memory format (IEEE S) */ - -#define S_V_SIGN 31 -#define S_SIGN (1u << S_V_SIGN) -#define S_V_EXP 23 -#define S_M_EXP 0xFF -#define S_BIAS 0x7F -#define S_NAN 0xFF -#define S_EXP (S_M_EXP << S_V_EXP) -#define S_V_FRAC 29 -#define S_GETEXP(x) ((uint32) (((x) >> S_V_EXP) & S_M_EXP)) - -/* Floating point memory format (IEEE T) */ - -#define T_V_SIGN 63 -#define T_SIGN 0x8000000000000000 -#define T_V_EXP 52 -#define T_M_EXP 0x7FF -#define T_BIAS 0x3FF -#define T_NAN 0x7FF -#define T_EXP 0x7FF0000000000000 -#define T_FRAC 0x000FFFFFFFFFFFFF -#define T_GETEXP(x) ((uint32) (((uint32) ((x) >> T_V_EXP)) & T_M_EXP)) - -/* Floating point register format (all except VAX D) */ - -#define FPR_V_SIGN 63 -#define FPR_SIGN 0x8000000000000000 -#define FPR_V_EXP 52 -#define FPR_M_EXP 0x7FF -#define FPR_NAN 0x7FF -#define FPR_EXP 0x7FF0000000000000 -#define FPR_HB 0x0010000000000000 -#define FPR_FRAC 0x000FFFFFFFFFFFFF -#define FPR_GUARD (UF_V_NM - FPR_V_EXP) -#define FPR_GETSIGN(x) (((uint32) ((x) >> FPR_V_SIGN)) & 1) -#define FPR_GETEXP(x) (((uint32) ((x) >> FPR_V_EXP)) & FPR_M_EXP) -#define FPR_GETFRAC(x) ((x) & FPR_FRAC) - -#define FP_TRUE 0x4000000000000000 /* 0.5/2.0 in reg */ - -/* Floating point register format (VAX D) */ - -#define FDR_V_SIGN 63 -#define FDR_SIGN 0x8000000000000000 -#define FDR_V_EXP 55 -#define FDR_M_EXP 0xFF -#define FDR_EXP 0x7F80000000000000 -#define FDR_HB 0x0080000000000000 -#define FDR_FRAC 0x007FFFFFFFFFFFFF -#define FDR_GUARD (UF_V_NM - FDR_V_EXP) -#define FDR_GETSIGN(x) (((uint32) ((x) >> FDR_V_SIGN)) & 1) -#define FDR_GETEXP(x) (((uint32) ((x) >> FDR_V_EXP)) & FDR_M_EXP) -#define FDR_GETFRAC(x) ((x) & FDR_FRAC) - -#define D_BIAS 0x80 - -/* Unpacked floating point number */ - -typedef struct { - uint32 sign; - int32 exp; - t_uint64 frac; - } UFP; - -#define UF_V_NM 63 -#define UF_NM 0x8000000000000000 /* normalized */ - -/* IEEE control register (left 32b only) */ - -#define FPCR_SUM 0x80000000 /* summary */ -#define FPCR_INED 0x40000000 /* inexact disable */ -#define FPCR_UNFD 0x20000000 /* underflow disable */ -#define FPCR_UNDZ 0x10000000 /* underflow to 0 */ -#define FPCR_V_RMOD 26 /* rounding mode */ -#define FPCR_M_RMOD 0x3 -#define FPCR_IOV 0x02000000 /* integer overflow */ -#define FPCR_INE 0x01000000 /* inexact */ -#define FPCR_UNF 0x00800000 /* underflow */ -#define FPCR_OVF 0x00400000 /* overflow */ -#define FPCR_DZE 0x00200000 /* div by zero */ -#define FPCR_INV 0x00100000 /* invalid operation */ -#define FPCR_OVFD 0x00080000 /* overflow disable */ -#define FPCR_DZED 0x00040000 /* div by zero disable */ -#define FPCR_INVD 0x00020000 /* invalid op disable */ -#define FPCR_DNZ 0x00010000 /* denormal to zero */ -#define FPCR_DNOD 0x00008000 /* denormal disable */ -#define FPCR_RAZ 0x00007FFF /* zero */ -#define FPCR_ERR (FPCR_IOV|FPCR_INE|FPCR_UNF|FPCR_OVF|FPCR_DZE|FPCR_INV) -#define FPCR_GETFRND(x) (((x) >> FPCR_V_RMOD) & FPCR_M_RMOD) - -/* PTE - hardware format */ - -#define PTE_V_PFN 32 /* PFN */ -#define PFN_MASK 0xFFFFFFFF -#define PTE_V_UWE 15 /* write enables */ -#define PTE_V_SWE 14 -#define PTE_V_EWE 13 -#define PTE_V_KWE 12 -#define PTE_V_URE 11 /* read enables */ -#define PTE_V_SRE 10 -#define PTE_V_ERE 9 -#define PTE_V_KRE 8 -#define PTE_V_GH 5 /* granularity hint */ -#define PTE_M_GH 0x3 -#define PTE_GH (PTE_M_GH << PTE_V_GH) -#define PTE_V_ASM 4 /* address space match */ -#define PTE_V_FOE 3 /* fault on execute */ -#define PTE_V_FOW 2 /* fault on write */ -#define PTE_V_FOR 1 /* fault on read */ -#define PTE_V_V 0 /* valid */ -#define PTE_UWE (1u << PTE_V_UWE) -#define PTE_SWE (1u << PTE_V_SWE) -#define PTE_EWE (1u << PTE_V_EWE) -#define PTE_KWE (1u << PTE_V_KWE) -#define PTE_URE (1u << PTE_V_URE) -#define PTE_SRE (1u << PTE_V_SRE) -#define PTE_ERE (1u << PTE_V_ERE) -#define PTE_KRE (1u << PTE_V_KRE) -#define PTE_ASM (1u << PTE_V_ASM) -#define PTE_FOE (1u << PTE_V_FOE) -#define PTE_FOW (1u << PTE_V_FOW) -#define PTE_FOR (1u << PTE_V_FOR) -#define PTE_V (1u << PTE_V_V) -#define PTE_MASK 0xFF7F -#define PTE_GETGH(x) ((((uint32) (x)) >> PTE_V_GH) & PTE_M_GH) -#define VPN_GETLVL1(x) (((x) >> ((2 * VA_N_LVL) - 3)) & (VA_M_LVL << 3)) -#define VPN_GETLVL2(x) (((x) >> (VA_N_LVL - 3)) & (VA_M_LVL << 3)) -#define VPN_GETLVL3(x) (((x) << 3) & (VA_M_LVL << 3)) - -#define ACC_E(m) ((PTE_KRE << (m)) | PTE_FOE | PTE_V) -#define ACC_R(m) ((PTE_KRE << (m)) | PTE_FOR | PTE_V) -#define ACC_W(m) ((PTE_KWE << (m)) | PTE_FOW | PTE_V) -#define ACC_M(m) (((PTE_KRE|PTE_KWE) << (m)) | PTE_FOR | PTE_FOW | PTE_V) - -/* Exceptions */ - -#define ABORT(x) longjmp (save_env, (x)) -#define ABORT1(x,y) { p1 = (x); longjmp (save_env, (y)); } - -#define EXC_RSVI 0x01 /* reserved instruction */ -#define EXC_RSVO 0x02 /* reserved operand */ -#define EXC_ALIGN 0x03 /* operand alignment */ -#define EXC_FPDIS 0x04 /* flt point disabled */ -#define EXC_TBM 0x08 /* TLB miss */ -#define EXC_FOX 0x10 /* fault on r/w/e */ -#define EXC_ACV 0x14 /* access control viol */ -#define EXC_TNV 0x18 /* translation not valid */ -#define EXC_BVA 0x1C /* bad address format */ -#define EXC_E 0x00 /* offset for execute */ -#define EXC_R 0x01 /* offset for read */ -#define EXC_W 0x02 /* offset for write */ - -/* Traps - corresponds to arithmetic trap summary register */ - -#define TRAP_SWC 0x001 /* software completion */ -#define TRAP_INV 0x002 /* invalid operand */ -#define TRAP_DZE 0x004 /* divide by zero */ -#define TRAP_OVF 0x008 /* overflow */ -#define TRAP_UNF 0x010 /* underflow */ -#define TRAP_INE 0x020 /* inexact */ -#define TRAP_IOV 0x040 /* integer overflow */ -#define TRAP_SUMM_RW 0x07F - -/* PALcode */ - -#define SP R[30] /* stack pointer */ -#define MODE_K 0 /* kernel */ -#define MODE_E 1 /* executive (UNIX user) */ -#define MODE_S 2 /* supervisor */ -#define MODE_U 3 /* user */ - -#define PAL_UNDF 0 /* undefined */ -#define PAL_VMS 1 /* VMS */ -#define PAL_UNIX 2 /* UNIX */ -#define PAL_NT 3 /* Windows NT */ - -/* Machine check error summary register */ - -#define MCES_INP 0x01 /* in progress */ -#define MCES_SCRD 0x02 /* sys corr in prog */ -#define MCES_PCRD 0x04 /* proc corr in prog */ -#define MCES_DSCRD 0x08 /* disable system corr */ -#define MCES_DPCRD 0x10 /* disable proc corr */ -#define MCES_W1C (MCES_INP|MCES_SCRD|MCES_PCRD) -#define MCES_DIS (MCES_DSCRD|MCES_DPCRD) - -/* I/O devices */ - -#define L_BYTE 0 /* IO request lengths */ -#define L_WORD 1 -#define L_LONG 2 -#define L_QUAD 3 - -/* Device information block */ - -typedef struct { /* device info block */ - t_uint64 low; /* low addr */ - t_uint64 high; /* high addr */ - t_bool (*read)(t_uint64 pa, t_uint64 *val, uint32 lnt); - t_bool (*write)(t_uint64 pa, t_uint64 val, uint32 lnt); - uint32 ipl; - } DIB; - -/* Interrupt system - 6 levels in EV4 and EV6, 4 in EV5 - software expects 4 */ - -#define IPL_HMAX 0x17 /* highest hwre level */ -#define IPL_HMIN 0x14 /* lowest hwre level */ -#define IPL_HLVL (IPL_HMAX - IPL_HMIN + 1) /* # hardware levels */ -#define IPL_SMAX 0x0F /* highest swre level */ - -/* Macros */ - -#define PCQ_SIZE 64 /* must be 2**n */ -#define PCQ_MASK (PCQ_SIZE - 1) -#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = (PC - 4) & M64 - -#define SEXT_B_Q(x) (((x) & B_SIGN)? ((x) | ~((t_uint64) M8)): ((x) & M8)) -#define SEXT_W_Q(x) (((x) & W_SIGN)? ((x) | ~((t_uint64) M16)): ((x) & M16)) -#define SEXT_L_Q(x) (((x) & L_SIGN)? ((x) | ~((t_uint64) M32)): ((x) & M32)) -#define NEG_Q(x) ((~(x) + 1) & M64) -#define ABS_Q(x) (((x) & Q_SIGN)? NEG_Q (x): (x)) - -#define SIGN_BDSP 0x100000 -#define SIGN_MDSP 0x008000 -#define SEXT_MDSP(x) (((x) & SIGN_MDSP)? \ - ((x) | ~((t_uint64) I_M_MDSP)): ((x) & I_M_MDSP)) -#define SEXT_BDSP(x) (((x) & SIGN_BDSP)? \ - ((x) | ~((t_uint64) I_M_BDSP)): ((x) & I_M_BDSP)) - -/* Opcodes */ - -enum opcodes { - OP_PAL, OP_OPC01, OP_OPC02, OP_OPC03, - OP_OPC04, OP_OPC05, OP_OPC06, OP_OPC07, - OP_LDA, OP_LDAH, OP_LDBU, OP_LDQ_U, - OP_LDWU, OP_STW, OP_STB, OP_STQ_U, - OP_IALU, OP_ILOG, OP_ISHFT, OP_IMUL, - OP_IFLT, OP_VAX, OP_IEEE, OP_FP, - OP_MISC, OP_PAL19, OP_JMP, OP_PAL1B, - OP_FLTI, OP_PAL1D, OP_PAL1E, OP_PAL1F, - OP_LDF, OP_LDG, OP_LDS, OP_LDT, - OP_STF, OP_STG, OP_STS, OP_STT, - OP_LDL, OP_LDQ, OP_LDL_L, OP_LDQ_L, - OP_STL, OP_STQ, OP_STL_C, OP_STQ_C, - OP_BR, OP_FBEQ, OP_FBLT, OP_FBLE, - OP_BSR, OP_FBNE, OP_FBGE, OP_FBGT, - OP_BLBC, OP_BEQ, OP_BLT, OP_BLE, - OP_BLBS, OP_BNE, OP_BGE, OP_BGT - }; - -/* Function prototypes */ - -uint32 ReadI (t_uint64 va); -t_uint64 ReadB (t_uint64 va); -t_uint64 ReadW (t_uint64 va); -t_uint64 ReadL (t_uint64 va); -t_uint64 ReadQ (t_uint64 va); -t_uint64 ReadAccL (t_uint64 va, uint32 acc); -t_uint64 ReadAccQ (t_uint64 va, uint32 acc); -INLINE t_uint64 ReadPB (t_uint64 pa); -INLINE t_uint64 ReadPW (t_uint64 pa); -INLINE t_uint64 ReadPL (t_uint64 pa); -INLINE t_uint64 ReadPQ (t_uint64 pa); -t_bool ReadIO (t_uint64 pa, t_uint64 *val, uint32 lnt); -void WriteB (t_uint64 va, t_uint64 dat); -void WriteW (t_uint64 va, t_uint64 dat); -void WriteL (t_uint64 va, t_uint64 dat); -void WriteQ (t_uint64 va, t_uint64 dat); -void WriteAccL (t_uint64 va, t_uint64 dat, uint32 acc); -void WriteAccQ (t_uint64 va, t_uint64 dat, uint32 acc); -INLINE void WritePB (t_uint64 pa, t_uint64 dat); -INLINE void WritePW (t_uint64 pa, t_uint64 dat); -INLINE void WritePL (t_uint64 pa, t_uint64 dat); -INLINE void WritePQ (t_uint64 pa, t_uint64 dat); -t_bool WriteIO (t_uint64 pa, t_uint64 val, uint32 lnt); -uint32 mmu_set_cm (uint32 mode); -void mmu_set_icm (uint32 mode); -void mmu_set_dcm (uint32 mode); -void arith_trap (uint32 trap, uint32 ir); - -#endif diff --git a/alpha/alpha_ev5_cons.c b/alpha/alpha_ev5_cons.c deleted file mode 100644 index fb576705..00000000 --- a/alpha/alpha_ev5_cons.c +++ /dev/null @@ -1,143 +0,0 @@ -/* alpha_ev5_cons.c - Alpha console support routines for EV5 - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "alpha_defs.h" -#include "alpha_ev5_defs.h" - -t_uint64 srm_ptbr = 1; - -extern uint32 dtlb_spage; -extern uint32 pal_type; -extern uint32 ev5_mcsr; -extern t_uint64 *M; -extern t_uint64 ev5_mvptbr; -extern UNIT cpu_unit; - -/* Local quadword physical read - exceptions or IO space lookups */ - -t_stat l_ReadPQ (t_uint64 pa, t_uint64 *dat) -{ -if (ADDR_IS_MEM (pa)) { - *dat = M[pa >> 3]; - return TRUE; - } -return FALSE; -} - -/* "SRM" 3-level pte lookup - - Inputs: - va = virtual address - *pte = pointer to pte to be returned - Output: - status = 0 for successful fill - EXC_ACV for ACV on intermediate level - EXC_TNV for TNV on intermediate level -*/ - -uint32 cons_find_pte_srm (t_uint64 va, t_uint64 *l3pte) -{ -t_uint64 vptea, l1ptea, l2ptea, l3ptea, l1pte, l2pte; -uint32 vpte_vpn; -TLBENT *vpte_p; - -vptea = FMT_MVA_VMS (va); /* try virt lookup */ -vpte_vpn = VA_GETVPN (vptea); /* get vpte vpn */ -vpte_p = dtlb_lookup (vpte_vpn); /* get vpte tlb ptr */ -if (vpte_p && ((vpte_p->pte & (PTE_KRE|PTE_V)) == (PTE_KRE|PTE_V))) - l3ptea = PHYS_ADDR (vpte_p->pfn, vptea); -else { - uint32 vpn = VA_GETVPN (va); - if (srm_ptbr & 1) return 1; /* uninitialized? */ - l1ptea = srm_ptbr + VPN_GETLVL1 (vpn); - if (!l_ReadPQ (l1ptea, &l1pte)) return 1; - if ((l1pte & PTE_V) == 0) - return ((l1pte & PTE_KRE)? EXC_TNV: EXC_ACV); - l2ptea = (l1pte & PFN_MASK) >> (PTE_V_PFN - VA_N_OFF); - l2ptea = l2ptea + VPN_GETLVL2 (vpn); - if (!l_ReadPQ (l2ptea, &l2pte)) return 1; - if ((l2pte & PTE_V) == 0) - return ((l2pte & PTE_KRE)? EXC_TNV: EXC_ACV); - l3ptea = (l2pte & PFN_MASK) >> (PTE_V_PFN - VA_N_OFF); - l3ptea = l3ptea + VPN_GETLVL3 (vpn); - } -if (!l_ReadPQ (l3ptea, l3pte)) return 1; -return 0; -} - -/* NT 2-level pte lookup - - Inputs: - va = virtual address - *pte = pointer to pte to be returned - Output: - status = 0 for successful fill - EXC_ACV for ACV on intermediate level - EXC_TNV for TNV on intermediate level -*/ - -uint32 cons_find_pte_nt (t_uint64 va, t_uint64 *l3pte) -{ -t_uint64 vptea, l3ptea; -uint32 vpte_vpn; -TLBENT *vpte_p; - -vptea = FMT_MVA_NT (va); /* try virt lookup */ -vpte_vpn = VA_GETVPN (vptea); /* get vpte vpn */ -vpte_p = dtlb_lookup (vpte_vpn); /* get vpte tlb ptr */ -if (vpte_p && ((vpte_p->pte & (PTE_KRE|PTE_V)) == (PTE_KRE|PTE_V))) - l3ptea = PHYS_ADDR (vpte_p->pfn, vptea); -else { - return 1; /* for now */ - } -if (!l_ReadPQ (l3ptea, l3pte)) return 1; -return 0; -} - -/* Translate address for console access */ - -t_uint64 trans_c (t_uint64 va) -{ -uint32 va_sext = VA_GETSEXT (va); -uint32 vpn = VA_GETVPN (va); -TLBENT *tlbp; -t_uint64 pte64; -uint32 exc, pfn; - -if ((va_sext != 0) && (va_sext != VA_M_SEXT)) /* invalid virt addr? */ - return M64; -if ((dtlb_spage & SPEN_43) && (VPN_GETSP43 (vpn) == 2)) - return (va & SP43_MASK); /* 43b superpage? */ -if ((dtlb_spage & SPEN_32) && (VPN_GETSP32 (vpn) == 0x1FFE)) - return (va & SP32_MASK); /* 32b superpage? */ -if (tlbp = dtlb_lookup (vpn)) /* try TLB */ - return PHYS_ADDR (tlbp->pfn, va); /* found it */ -if (ev5_mcsr & MCSR_NT) exc = cons_find_pte_nt (va, &pte64); -else exc = cons_find_pte_srm (va, &pte64); -if (exc || ((pte64 & PTE_V) == 0)) return M64; /* check valid */ -pfn = (uint32) (pte64 >> 32) & M32; -return PHYS_ADDR (pfn, va); /* return phys addr */ -} diff --git a/alpha/alpha_ev5_defs.h b/alpha/alpha_ev5_defs.h deleted file mode 100644 index cba29614..00000000 --- a/alpha/alpha_ev5_defs.h +++ /dev/null @@ -1,428 +0,0 @@ -/* alpha_ev5_defs.h: Alpha EV5 chip definitions file - - Copyright (c) 2003-2005, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Respectfully dedicated to the great people of the Alpha chip, systems, and - software development projects; and to the memory of Peter Conklin, of the - Alpha Program Office. -*/ - -#ifndef _ALPHA_EV5_DEFS_H_ -#define _ALPHA_EV5_DEFS_H_ 0 - -/* Address limits */ - -#define VA_SIZE 43 /* VA size */ -#define NTVA_WIDTH 32 /* VA width for NT */ -#define VA_MASK 0x000007FFFFFFFFFF -#define EV5_PA_SIZE 40 /* PA size */ -#define EV5_PA_MASK 0x000000FFFFFFFFFF - -/* Virtual address */ - -#define VA_N_OFF 13 /* offset size */ -#define VA_PAGSIZE (1u << VA_N_OFF) /* page size */ -#define VA_M_OFF ((1u << VA_N_OFF) - 1) /* offset mask */ -#define VA_N_LVL 10 /* width per level */ -#define VA_M_LVL ((1u << VA_N_LVL) - 1) /* level mask */ -#define VA_V_VPN VA_N_OFF /* vpn start */ -#define VA_N_VPN (VA_N_LVL * 3) /* vpn size */ -#define VA_M_VPN ((1u << VA_N_VPN) - 1) /* vpn mask */ -#define VA_WIDTH (VA_N_VPN + VA_N_OFF) /* total VA size */ -#define VA_V_SEXT (VA_WIDTH - 1) /* sext start */ -#define VA_M_SEXT ((1u << (64 - VA_V_SEXT)) - 1) /* sext mask */ -#define VA_GETOFF(x) (((uint32) (x)) & VA_M_OFF) -#define VA_GETVPN(x) (((uint32) ((x) >> VA_V_VPN)) & VA_M_VPN) -#define VA_GETSEXT(x) (((uint32) ((x) >> VA_V_SEXT)) & VA_M_SEXT) -#define PHYS_ADDR(p,v) ((((t_uint64) (p)) < VA_N_OFF) | VA_GETOFF (v)) - -/* 43b and 32b superpages - present in all implementations */ - -#define SPEN_43 0x2 -#define SPEN_32 0x1 -#define SP43_MASK 0x000001FFFFFFFFFF -#define SP32_MASK 0x000000003FFFFFFF -#define VPN_GETSP43(x) ((uint32) (((x) >> (VA_WIDTH - VA_N_OFF - 2)) & 3)) -#define VPN_GETSP32(x) ((uint32) (((x) >> (NTVA_WIDTH - VA_N_OFF - 2)) & 0x1FFF)) - -/* TLBs */ - -#define INV_TAG M32 -#define ITLB_SIZE 48 -#define DTLB_SIZE 64 -#define ITLB_WIDTH 6 -#define DTLB_WIDTH 6 - -#define TLB_CI 0x1 /* clear I */ -#define TLB_CD 0x2 /* clear D */ -#define TLB_CA 0x4 /* clear all */ - -typedef struct { - uint32 tag; /* tag */ - uint8 asn; /* addr space # */ - uint8 idx; /* entry # */ - uint16 gh_mask; /* gh mask */ - uint32 pfn; /* pfn */ - uint32 pte; /* swre/pte */ - } TLBENT; - -/* Register shadow */ - -#define PALSHAD_SIZE 8 -#define PAL_USE_SHADOW \ - ev5_palsave[0] = R[8]; ev5_palsave[1] = R[9]; \ - ev5_palsave[2] = R[10]; ev5_palsave[3] = R[11]; \ - ev5_palsave[4] = R[12]; ev5_palsave[5] = R[13]; \ - ev5_palsave[6] = R[14]; ev5_palsave[7] = R[25]; \ - R[8] = ev5_palshad[0]; R[9] = ev5_palshad[1]; \ - R[10] = ev5_palshad[2]; R[11] = ev5_palshad[3]; \ - R[12] = ev5_palshad[4]; R[13] = ev5_palshad[5]; \ - R[14] = ev5_palshad[6]; R[25] = ev5_palshad[7] -#define PAL_USE_MAIN \ - ev5_palshad[0] = R[8]; ev5_palshad[1] = R[9]; \ - ev5_palshad[2] = R[10]; ev5_palshad[3] = R[11]; \ - ev5_palshad[4] = R[12]; ev5_palshad[5] = R[13]; \ - ev5_palshad[6] = R[14]; ev5_palshad[7] = R[25]; \ - R[8] = ev5_palsave[0]; R[9] = ev5_palsave[1]; \ - R[10] = ev5_palsave[2]; R[11] = ev5_palsave[3]; \ - R[12] = ev5_palsave[4]; R[13] = ev5_palsave[5]; \ - R[14] = ev5_palsave[6]; R[25] = ev5_palsave[7] - -/* PAL instructions */ - -#define HW_MFPR 0x19 -#define HW_LD 0x1B -#define HW_MTPR 0x1D -#define HW_REI 0x1E -#define HW_ST 0x1F - -#define HW_LD_V 0x8000 -#define HW_LD_ALT 0x4000 -#define HW_LD_WCH 0x2000 -#define HW_LD_Q 0x1000 -#define HW_LD_PTE 0x0800 -#define HW_LD_LCK 0x0400 -#define HW_LD_DSP 0x03FF -#define SIGN_HW_LD_DSP 0x0200 -#define HW_LD_GETDSP(x) ((x) & HW_LD_DSP) -#define SEXT_HW_LD_DSP(x) (((x) & SIGN_HW_LD_DSP)? \ - ((x) | ~((t_uint64) HW_LD_DSP)): ((x) & HW_LD_DSP)) - -#define HW_REI_S 0x4000 - -/* PAL entry offsets */ - -#define PALO_RESET 0x0000 -#define PALO_IACV 0x0080 -#define PALO_INTR 0x0100 -#define PALO_ITBM 0x0180 -#define PALO_DTBM 0x0200 -#define PALO_DTBM_D 0x0280 -#define PALO_ALGN 0x0300 -#define PALO_DFLT 0x0380 -#define PALO_MCHK 0x0400 -#define PALO_RSVI 0x0480 -#define PALO_TRAP 0x0500 -#define PALO_FDIS 0x0580 -#define PALO_CALLPR 0x2000 -#define PALO_CALLUNPR 0x3000 - -/* Special (above 1F) and normal interrupt levels */ - -#define IPL_HALT 0x40 -#define IPL_SLI 0x20 -#define IPL_1F 0x1F /* highest level */ -#define IPL_CRD 0x1F /* corrected read data */ -#define IPL_PWRFL 0x1E /* power fail */ -#define IPL_AST 0x02 /* AST interrupt level */ - -/* Internal registers */ - -#define PALTEMP_SIZE 24 - -enum ev5_internal_reg { - ISR = 0x100, ITB_TAG, ITB_PTE, ITB_ASN, - ITB_PTE_TEMP, ITB_IA, ITB_IAP, ITB_IS, - SIRR, ASTRR, ASTEN, EXC_ADDR, - EXC_SUMM, EXC_MASK, PAL_BASE, ICM, - IPLR, INTID, IFAULT_VA_FORM, IVPTBR, - HWINT_CLR = 0x115, SL_XMIT, SL_RCV, - ICSR, IC_FLUSH_CTL, ICPERR_STAT, PMCTR = 0x11C, - PALTEMP = 0x140, - DTB_ASN = 0x200, DTB_CM, DTB_TAG, DTB_PTE, - DTB_PTE_TEMP, MM_STAT, VA, VA_FORM, - MVPTBR, DTB_IAP, DTB_IA, DTB_IS, - ALTMODE, CC, CC_CTL, MCSR, - DC_FLUSH, DC_PERR_STAT = 0x212, DC_TEST_CTL, - DC_TEST_TAG, DC_TEST_TAG_TEMP, DC_MODE, MAF_MODE - }; - -/* Ibox registers */ -/* ISR - instruction summary register - read only */ - -#define ISR_V_AST 0 -#define ISR_V_SIRR 4 -#define ISR_V_ATR 19 -#define ISR_V_IRQ0 20 -#define ISR_V_IRQ1 21 -#define ISR_V_IRQ2 22 -#define ISR_V_IRQ3 23 -#define ISR_V_PFL 30 -#define ISR_V_MCHK 31 -#define ISR_V_CRD 32 -#define ISR_V_SLI 33 -#define ISR_V_HALT 34 - -#define ISR_ATR (((t_uint64) 1u) << ISR_V_ATR) -#define ISR_IRQ0 (((t_uint64) 1u) << ISR_V_IRQ0) -#define ISR_IRQ1 (((t_uint64) 1u) << ISR_V_IRQ1) -#define ISR_IRQ2 (((t_uint64) 1u) << ISR_V_IRQ2) -#define ISR_IRQ3 (((t_uint64) 1u) << ISR_V_IRQ3) -#define ISR_HALT (((t_uint64) 1u) << ISR_V_HALT) - -/* ITB_TAG - ITLB tag - write only - stores VPN (tag) of faulting address */ - -/* ITB_PTE - ITLB pte - read and write in different formats */ - -#define ITBR_PTE_V_ASM 13 -#define ITBR_PTE_ASM (1u << ITBR_PTE_V_ASM) -#define ITBR_PTE_V_KRE 18 -#define ITBR_PTE_GH0 0x00000000 -#define ITBR_PTE_GH1 0x20000000 -#define ITBR_PTE_GH2 0x60000000 -#define ITBR_PTE_GH3 0xE0000000 - -/* ITB_ASN - ITLB ASN - read write */ - -#define ITB_ASN_V_ASN 4 -#define ITB_ASN_M_ASN 0x7F -#define ITB_ASN_WIDTH 7 - -/* ITB_PTE_TEMP - ITLB PTE readout - read only */ - -/* ITB_IA, ITB_IAP, ITB_IS - ITLB invalidates - write only */ - -/* SIRR - software interrupt request register - read/write */ - -#define SIRR_V_SIRR 4 -#define SIRR_M_SIRR 0x7FFF - -/* ASTRR, ASTEN - AST request, enable registers - read/write */ - -#define AST_MASK 0xF /* AST bits */ - -/* EXC_ADDR - read/write */ - -/* EXC_SUMM - read/cleared on write */ - -/* EXC_MASK - read only */ - -/* PAL_BASE - read/write */ - -#define PAL_BASE_RW 0x000000FFFFFFFFC000 - -/* ICM - ITLB current mode - read/write */ - -#define ICM_V_CM 3 -#define ICM_M_CM 0x3 - -/* IPLR - interrupt priority level - read/write */ - -#define IPLR_V_IPL 0 -#define IPLR_M_IPL 0x1F - -/* INTID - interrupt ID - read only */ - -#define INTID_MASK 0x1F - -/* IFAULT_VA_FORM - formated fault VA - read only */ - -/* IVPTBR - virtual page table base - read/write */ - -#define IVPTBR_VMS 0xFFFFFFF800000000 -#define IVPTBR_NT 0xFFFFFFFFC0000000 -#define FMT_IVA_VMS(x) (ev5_ivptbr | (((x) >> (VA_N_OFF - 3)) & 0x1FFFFFFF8)) -#define FMT_IVA_NT(x) (ev5_ivptbr | (((x) >> (VA_N_OFF - 3)) & 0x0003FFFF8)) - -/* HWINT_CLR - hardware interrupt clear - write only */ - -#define HWINT_CLR_W1C 0x00000003C8000000 - -/* SL_XMIT - serial line transmit - write only */ - -/* SL_RCV - real line receive - read only */ - -/* ICSR - Ibox control/status - read/write */ - -#define ICSR_V_PME 8 -#define ICSR_M_PME 0x3 -#define ICSR_V_BSE 17 -#define ICSR_V_MSK0 20 -#define ICSR_V_MSK1 21 -#define ICSR_V_MSK2 22 -#define ICSR_V_MSK3 23 -#define ICSR_V_TMM 24 -#define ICSR_V_TMD 25 -#define ICSR_V_FPE 26 -#define ICSR_V_HWE 27 -#define ICSR_V_SPE 28 -#define ICSR_M_SPE 0x3 -#define ICSR_V_SDE 30 -#define ICSR_V_CRDE 32 -#define ICSR_V_SLE 33 -#define ICSR_V_FMS 34 -#define ICSR_V_FBT 35 -#define ICSR_V_FBD 36 -#define ICSR_V_BIST 38 -#define ICSR_V_TEST 39 - -#define ICSR_NT (((t_uint64) 1u) << ICSR_V_SPE) -#define ICSR_BSE (((t_uint64) 1u) << ICSR_V_BSE) -#define ICSR_MSK0 (((t_uint64) 1u) << ICSR_V_MSK0) -#define ICSR_MSK1 (((t_uint64) 1u) << ICSR_V_MSK1) -#define ICSR_MSK2 (((t_uint64) 1u) << ICSR_V_MSK2) -#define ICSR_MSK3 (((t_uint64) 1u) << ICSR_V_MSK3) -#define ICSR_HWE (((t_uint64) 1u) << ICSR_V_HWE) -#define ICSR_SDE (((t_uint64) 1u) << ICSR_V_SDE) -#define ICSR_CRDE (((t_uint64) 1u) << ICSR_V_CRDE) -#define ICSR_SLE (((t_uint64) 1u) << ICSR_V_SLE) - -#define ICSR_RW 0x0000009F4BF00300 -#define ICSR_MBO 0x0000006000000000 - -/* IC_FLUSH_CTL - Icache flush control - write only */ - -/* ICPERR_STAT - Icache parity status - read/write 1 to clear */ - -#define ICPERR_V_DPE 11 -#define ICPERR_V_TPE 12 -#define ICPERR_V_TMO 13 - -#define ICPERR_DPE (1u << ICPERR_V_DPE) -#define ICPERR_TPE (1u << ICPERR_V_TPE) -#define ICPERR_TMO (1u << ICPERR_V_TMO) - -#define ICPERR_W1C (ICPERR_DPE|ICPERR_TPE|ICPERR_TMO) - -/* Mbox registers */ -/* DTB_ASN - DTLB ASN - write only */ - -#define DTB_ASN_V_ASN 57 -#define DTB_ASN_M_ASN 0x7F -#define DTB_ASN_WIDTH 7 - -/* DTB_CM - DTLB current mode - write only */ - -#define DCM_V_CM 3 -#define DCM_M_CM 0x3 - -/* DTB_TAG - DTLB tag and update - write only */ - -/* DTB_PTE - DTLB PTE - read/write */ - -/* DTB_PTE_TEMP - DTLB PTE read out register - read only */ - -/* MM_STAT - data fault status register - read only */ - -#define MM_STAT_WR 0x00001 -#define MM_STAT_ACV 0x00002 -#define MM_STAT_FOR 0x00004 -#define MM_STAT_FOW 0x00008 -#define MM_STAT_TBM 0x00010 -#define MM_STAT_BVA 0x00020 -#define MM_STAT_V_RA 6 -#define MM_STAT_IMASK 0x1FFC0 - -/* VA - data fault virtual address - read only */ - -/* VA_FORM - data fault formated virtual address - read only */ - -#define FMT_MVA_VMS(x) (ev5_mvptbr | (((x) >> (VA_N_OFF - 3)) & 0x1FFFFFFF8)) -#define FMT_MVA_NT(x) (ev5_mvptbr | (((x) >> (VA_N_OFF - 3)) & 0x0003FFFF8)) - -/* MVPTBR - DTB virtual page table base - write only */ - -#define MVPTBR_MBZ ((t_uint64) 0x3FFFFFFF) - -/* DTB_IAP, DTB_IA, DTB_IS - DTB invalidates - write only */ - -/* ALT_MODE - DTLB current mode - write only */ - -#define ALT_V_CM 3 -#define ALT_M_CM 0x3 - -/* CC - cycle counter - upper half is RW, lower half is RO */ - -/* CC_CTL - cycle counter control - write only */ - -#define CC_CTL_ENB 0x100000000 -#define CC_CTL_MBZ 0xF - -/* MCSR - Mbox control/status register - read/write */ - -#define MCSR_RW 0x11 -#define MCSR_V_SPE 1 -#define MCSR_M_SPE 0x3 -#define MCSR_NT 0x02 - -/* DC_PERR_STAT - data cache parity error status - read/write */ - -#define DC_PERR_W1C 0x3 -#define DC_PERR_ERR 0x1C - -/* DC_MODE - data cache mode - read/write */ - -#define DC_MODE_RW 0xF - -/* MAF_MODE - miss address file mode - read/write */ - -#define MAF_MODE_RW 0xFF - -/* DC_TEST_CTL - data cache test control - read/write */ - -#define DC_TEST_CTL_RW 0x1FFFB - -/* DC_TEST_TAG - data cache test tag - read/write */ - -#define DC_TEST_TAG_RW 0x0000007FFFFFFF04 - -/* Function prototypes (TLB interface) */ - -void tlb_ia (uint32 flags); -void tlb_is (t_uint64 va, uint32 flags); -void itlb_set_asn (uint32 asn); -void itlb_set_cm (uint32 mode); -void itlb_set_spage (uint32 spage); -TLBENT *itlb_lookup (uint32 vpn); -TLBENT *itlb_load (uint32 vpn, t_uint64 pte); -t_uint64 itlb_read (void); -void dtlb_set_asn (uint32 asn); -void dtlb_set_cm (uint32 mode); -void dtlb_set_spage (uint32 spage); -TLBENT *dtlb_lookup (uint32 vpn); -TLBENT *dtlb_load (uint32 vpn, t_uint64 pte); -t_uint64 dtlb_read (void); - -#endif - diff --git a/alpha/alpha_ev5_pal.c b/alpha/alpha_ev5_pal.c deleted file mode 100644 index 4910b0ce..00000000 --- a/alpha/alpha_ev5_pal.c +++ /dev/null @@ -1,961 +0,0 @@ -/* alpha_ev5_pal.c - Alpha EV5 PAL mode simulator - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - EV5 was the second generation Alpha CPU. It was a four-way, in order issue - CPU with onchip primary instruction and data caches, an onchip second level - cache, and support for an offchip third level cache. EV56 was a shrink, with - added support for byte and word operations. PCA56 was a version of EV56 - without the onchip second level cache. PCA57 was a shrink of PCA56. - - EV5 includes the usual five PALcode instructions: - - HW_LD PALcode load - HW_ST PALcode store - HW_MTPR PALcode move to internal processor register - HW_MFPR PALcode move from internal processor register - HW_REI PALcode return - - PALcode instructions can only be issued in PALmode, or in kernel mode - if the appropriate bit is set in ICSR. - - EV5 implements 8 "PAL shadow" registers, which replace R8-R14, R25 in - PALmode without save/restore; and 24 "PAL temporary" registers. - - Internal registers fall into three groups: IBox IPRs, MBox IPRs, and - PAL temporaries. -*/ - -#include "alpha_defs.h" -#include "alpha_ev5_defs.h" - -t_uint64 ev5_palshad[PALSHAD_SIZE] = { 0 }; /* PAL shadow reg */ -t_uint64 ev5_palsave[PALSHAD_SIZE] = { 0 }; /* PAL save main */ -t_uint64 ev5_paltemp[PALTEMP_SIZE] = { 0 }; /* PAL temps */ -t_uint64 ev5_palbase = 0; /* PALcode base */ -t_uint64 ev5_excaddr = 0; /* exception address */ -t_uint64 ev5_isr = 0; /* intr summary */ -t_uint64 ev5_icsr = 0; /* IBox control */ -t_uint64 ev5_itb_pte = 0; /* ITLB pte */ -t_uint64 ev5_itb_pte_temp = 0; /* ITLB readout */ -t_uint64 ev5_ivptbr = 0; /* IBox virt ptbl */ -t_uint64 ev5_iva_form = 0; /* Ibox fmt'd VA */ -t_uint64 ev5_va = 0; /* Mbox VA */ -t_uint64 ev5_mvptbr = 0; /* Mbox virt ptbl */ -t_uint64 ev5_va_form = 0; /* Mbox fmt'd VA */ -t_uint64 ev5_dtb_pte = 0; /* DTLB pte */ -t_uint64 ev5_dtb_pte_temp = 0; /* DTLB readout */ -t_uint64 ev5_dc_test_tag = 0; /* Dcache test tag */ -t_uint64 ev5_dc_test_tag_temp = 0; /* Dcache tag readout */ -uint32 ev5_itb_tag = 0; /* ITLB tag (vpn) */ -uint32 ev5_dtb_tag = 0; /* DTLB tag (vpn) */ -uint32 ev5_icperr = 0; /* Icache par err */ -uint32 ev5_mm_stat = 0; /* MBox fault code */ -uint32 ev5_mcsr = 0; /* MBox control */ -uint32 ev5_alt_mode = 0; /* MBox alt mode */ -uint32 ev5_dc_mode = 0; /* Dcache mode */ -uint32 ev5_dcperr = 0; /* Dcache par err */ -uint32 ev5_dc_test_ctl = 0; /* Dcache test ctrl */ -uint32 ev5_maf_mode = 0; /* MAF mode */ -uint32 ev5_va_lock = 0; /* VA lock flag */ -uint32 ev5_mchk = 0; /* machine check pin */ -uint32 ev5_sli = 0; /* serial line intr */ -uint32 ev5_crd = 0; /* corr read data pin */ -uint32 ev5_pwrfl = 0; /* power fail pin */ -uint32 ev5_ipl = 0; /* ipl */ -uint32 ev5_sirr = 0; /* software int req */ -uint32 ev5_astrr = 0; /* AST requests */ -uint32 ev5_asten = 0; /* AST enables */ -const uint32 ast_map[4] = { 0x1, 0x3, 0x7, 0xF }; - -t_stat ev5_palent (t_uint64 fpc, uint32 off); -t_stat ev5_palent_d (t_uint64 fpc, uint32 off, uint32 sta); -t_stat pal_proc_reset_hwre (DEVICE *dptr); -t_stat pal_proc_intr_ev5 (uint32 lvl); -uint32 pal_eval_intr_ev5 (uint32 flag); - -extern t_uint64 R[32]; -extern t_uint64 PC; -extern t_uint64 trap_mask; -extern t_uint64 p1; -extern uint32 ir; -extern uint32 vax_flag, lock_flag; -extern uint32 fpen; -extern uint32 pcc_h, pcc_l, pcc_enb; -extern uint32 trap_summ; -extern uint32 arch_mask; -extern uint32 pal_mode, pal_type; -extern uint32 int_req[IPL_HLVL]; -extern uint32 itlb_cm, dtlb_cm; -extern uint32 itlb_asn, dtlb_asn; -extern uint32 itlb_spage, dtlb_spage; -extern jmp_buf save_env; -extern uint32 pal_type; -extern t_uint64 pcq[PCQ_SIZE]; /* PC queue */ -extern int32 pcq_p; /* PC queue ptr */ - -extern int32 parse_reg (char *cptr); - -/* EV5PAL data structures - - ev5pal_dev device descriptor - ev5pal_unit unit - ev5pal_reg register list -*/ - -UNIT ev5pal_unit = { UDATA (NULL, 0, 0) }; - -REG ev5pal_reg[] = { - { BRDATA (PALSHAD, ev5_palshad, 16, 64, PALSHAD_SIZE) }, - { BRDATA (PALSAVE, ev5_palsave, 16, 64, PALSHAD_SIZE) }, - { BRDATA (PALTEMP, ev5_paltemp, 16, 64, PALTEMP_SIZE) }, - { HRDATA (PALBASE, ev5_palbase, 64) }, - { HRDATA (EXCADDR, ev5_excaddr, 64) }, - { HRDATA (IPL, ev5_ipl, 5) }, - { HRDATA (SIRR, ev5_sirr, 15) }, - { HRDATA (ASTRR, ev5_astrr, 4) }, - { HRDATA (ASTEN, ev5_asten, 4) }, - { HRDATA (ISR, ev5_isr, 35) }, - { HRDATA (ICSR, ev5_icsr, 40) }, - { HRDATA (ITB_TAG, ev5_itb_tag, 32) }, - { HRDATA (ITB_PTE, ev5_itb_pte, 64) }, - { HRDATA (ITB_PTE_TEMP, ev5_itb_pte_temp, 64) }, - { HRDATA (IVA_FORM, ev5_iva_form, 64) }, - { HRDATA (IVPTBR, ev5_ivptbr, 64) }, - { HRDATA (ICPERR_STAT, ev5_icperr, 14) }, - { HRDATA (VA, ev5_va, 64) }, - { HRDATA (VA_FORM, ev5_va_form, 64) }, - { HRDATA (MVPTBR, ev5_mvptbr, 64) }, - { HRDATA (MM_STAT, ev5_mm_stat, 17) }, - { HRDATA (MCSR, ev5_mcsr, 6) }, - { HRDATA (DTB_TAG, ev5_dtb_tag, 32) }, - { HRDATA (DTB_PTE, ev5_dtb_pte, 64) }, - { HRDATA (DTB_PTE_TEMP, ev5_dtb_pte_temp, 64) }, - { HRDATA (DC_MODE, ev5_dc_mode, 4) }, - { HRDATA (DC_PERR_STAT, ev5_dcperr, 6) }, - { HRDATA (DC_TEST_CTL, ev5_dc_test_ctl, 13) }, - { HRDATA (DC_TEST_TAG, ev5_dc_test_tag, 39) }, - { HRDATA (DC_TEST_TAG_TEMP, ev5_dc_test_tag_temp, 39) }, - { HRDATA (MAF_MODE, ev5_maf_mode, 8) }, - { FLDATA (VA_LOCK, ev5_va_lock, 0) }, - { FLDATA (MCHK, ev5_mchk, 0) }, - { FLDATA (CRD, ev5_crd, 0) }, - { FLDATA (PWRFL, ev5_pwrfl, 0) }, - { FLDATA (SLI, ev5_sli, 0) }, - { NULL } - }; - -DEVICE ev5pal_dev = { - "EV5PAL", &ev5pal_unit, ev5pal_reg, NULL, - 1, 16, 1, 1, 16, 8, - NULL, NULL, &pal_proc_reset_hwre, - NULL, NULL, NULL, - NULL, DEV_DIS - }; - -/* EV5 interrupt dispatch - reached from top of instruction loop - - dispatch to PALcode */ - -t_stat pal_proc_intr (uint32 lvl) -{ -return ev5_palent (PC, PALO_INTR); -} - -/* EV5 trap dispatch - reached from bottom of instruction loop - - trap_mask and trap_summ are set up correctly - dispatch to PALcode */ - -t_stat pal_proc_trap (uint32 summ) -{ -return ev5_palent (PC, PALO_TRAP); -} - -/* EV5 exception dispatch - reached from ABORT handler - - set up any exception-specific registers - dispatch to PALcode */ - -t_stat pal_proc_excp (uint32 abval) -{ -switch (abval) { - - case EXC_RSVI: /* reserved instruction */ - return ev5_palent (PC, PALO_RSVI); - - case EXC_ALIGN: /* unaligned */ - return ev5_palent (PC, PALO_ALGN); - - case EXC_FPDIS: /* fp disabled */ - return ev5_palent (PC, PALO_FDIS); - - case EXC_FOX+EXC_R: /* FOR */ - return ev5_palent_d (PC, PALO_DFLT, MM_STAT_FOR); - - case EXC_FOX+EXC_W: /* FOW */ - return ev5_palent_d (PC, PALO_DFLT, MM_STAT_FOR|MM_STAT_WR); - - case EXC_BVA+EXC_E: /* instr bad VA */ - case EXC_ACV+EXC_E: /* instr ACV */ - ev5_itb_tag = VA_GETVPN (PC); /* fault VPN */ - if (ev5_icsr & ICSR_NT) /* formatted addr */ - ev5_iva_form = ev5_ivptbr | FMT_IVA_NT (PC); - else ev5_iva_form = ev5_ivptbr | FMT_IVA_VMS (PC); - return ev5_palent (PC, PALO_IACV); - - case EXC_ACV+EXC_R: /* data read ACV */ - return ev5_palent_d (PC, PALO_DFLT, MM_STAT_ACV); - - case EXC_ACV+EXC_W: /* data write ACV */ - return ev5_palent_d (PC, PALO_DFLT, MM_STAT_ACV|MM_STAT_WR); - - case EXC_BVA+EXC_R: /* data read bad addr */ - return ev5_palent_d (PC, PALO_DFLT, MM_STAT_BVA); - - case EXC_BVA+EXC_W: /* data write bad addr */ - return ev5_palent_d (PC, PALO_DFLT, MM_STAT_BVA|MM_STAT_WR); - - case EXC_TBM + EXC_E: /* TLB miss */ - ev5_itb_tag = VA_GETVPN (PC); /* fault VPN */ - if (ev5_icsr & ICSR_NT) /* formatted addr */ - ev5_iva_form = ev5_ivptbr | FMT_IVA_NT (PC); - else ev5_iva_form = ev5_ivptbr | FMT_IVA_VMS (PC); - return ev5_palent (PC, PALO_ITBM); - - case EXC_TBM + EXC_R: /* data TB miss read */ - if ((I_GETOP (ir) == HW_LD) && (ir & HW_LD_PTE)) - return ev5_palent_d (PC, PALO_DTBM_D, MM_STAT_TBM); - return ev5_palent_d (PC, PALO_DTBM, MM_STAT_TBM); - - case EXC_TBM + EXC_W: /* data TB miss write */ - if ((I_GETOP (ir) == HW_LD) && (ir & HW_LD_PTE)) - return ev5_palent_d (PC, PALO_DTBM_D, MM_STAT_TBM|MM_STAT_WR); - return ev5_palent_d (PC, PALO_DTBM, MM_STAT_TBM|MM_STAT_WR); - - case EXC_RSVO: /* reserved operand */ - case EXC_TNV+EXC_E: /* instr TNV */ - case EXC_TNV+EXC_R: /* data read TNV */ - case EXC_TNV+EXC_W: /* data write TNV */ - case EXC_FOX+EXC_E: /* FOE */ - return SCPE_IERR; /* should never get here */ - - default: - return STOP_INVABO; - } - -return SCPE_OK; -} - -/* EV5 call PAL - reached from instruction decoder - - compute offset from function code - dispatch to PALcode */ - -t_stat pal_proc_inst (uint32 fnc) -{ -uint32 off = (fnc & 0x3F) << 6; - -if (fnc & 0x80) return ev5_palent (PC, PALO_CALLUNPR + off); -if (itlb_cm != MODE_K) ABORT (EXC_RSVI); -return ev5_palent (PC, PALO_CALLPR + off); -} - -/* EV5 evaluate interrupts - returns highest outstanding - interrupt level about target ipl - plus nonmaskable flags - - flag = 1: evaluate for real interrupt capability - flag = 0: evaluate as though IPL = 0, normal mode */ - -uint32 pal_eval_intr (uint32 flag) -{ -uint32 i, req = 0; -uint32 lvl = flag? ev5_ipl: 0; - -if (flag && pal_mode) return 0; -if (ev5_mchk) req = IPL_1F; -else if (ev5_crd && (ICSR & ICSR_CRDE)) req = IPL_CRD; -else if (ev5_pwrfl) req = IPL_PWRFL; -else if (int_req[3] && !(ICSR & ICSR_MSK3)) req = IPL_HMIN + 3; -else if (int_req[2] && !(ICSR & ICSR_MSK2)) req = IPL_HMIN + 2; -else if (int_req[1] && !(ICSR & ICSR_MSK1)) req = IPL_HMIN + 1; -else if (int_req[0] && !(ICSR & ICSR_MSK0)) req = IPL_HMIN + 0; -else if (ev5_sirr) { - for (i = IPL_SMAX; i > 0; i--) { /* check swre int */ - if ((ev5_sirr >> (i - 1)) & 1) { /* req != 0? int */ - req = i; - break; - } - } - } -if ((req < IPL_AST) && (ev5_astrr & ev5_asten & ast_map[itlb_cm])) - req = IPL_AST; -if (req <= lvl) req = 0; -if (ev5_sli && (ICSR & ICSR_SLE)) req = req | IPL_SLI; -if (ev5_isr & ISR_HALT) req = req | IPL_HALT; -return req; -} - -/* EV5 enter PAL, data TLB miss/memory management flows - - set Mbox registers - dispatch to PALcode */ - -t_stat ev5_palent_d (t_uint64 fpc, uint32 off, uint32 sta) -{ -if (!ev5_va_lock) { /* not locked? */ - ev5_mm_stat = sta | /* merge IR<31:21> */ - ((ir >> (I_V_RA - MM_STAT_V_RA)) & MM_STAT_IMASK); - ev5_va = p1; /* fault address */ - if (ev5_mcsr & MCSR_NT) /* formatted VA */ - ev5_va_form = ev5_mvptbr | FMT_MVA_NT (p1); - else ev5_va_form = ev5_mvptbr | FMT_MVA_VMS (p1); - ev5_va_lock = 1; /* lock registers */ - } -return ev5_palent (fpc, off); -} - -/* EV5 enter PAL */ - -t_stat ev5_palent (t_uint64 fpc, uint32 off) -{ -ev5_excaddr = fpc | pal_mode; /* save exc addr */ -PCQ_ENTRY; /* save PC */ -PC = ev5_palbase + off; /* new PC */ -if (!pal_mode && (ev5_icsr & ICSR_SDE)) { /* entering PALmode? */ - PAL_USE_SHADOW; /* swap in shadows */ - } -pal_mode = 1; /* in PAL mode */ -return SCPE_OK; -} - -/* PAL instructions */ - -/* 1B: HW_LD */ - -t_stat pal_1b (uint32 ir) -{ -t_uint64 dsp, ea, res; -uint32 ra, rb, acc, mode; - -if (!pal_mode && (!(itlb_cm == MODE_K) || /* pal mode, or kernel */ - !(ev5_icsr & ICSR_HWE))) ABORT (EXC_RSVI); /* and enabled? */ -ra = I_GETRA (ir); /* get ra */ -rb = I_GETRB (ir); /* get rb */ -dsp = HW_LD_GETDSP (ir); /* get displacement */ -ea = (R[rb] + (SEXT_HW_LD_DSP (dsp))) & M64; /* eff address */ -if (ir & HW_LD_V) { /* virtual? */ - mode = (ir & HW_LD_ALT)? ev5_alt_mode: dtlb_cm; /* access mode */ - acc = (ir & HW_LD_WCH)? ACC_W (mode): ACC_R (mode); - if (ir & HW_LD_Q) res = ReadAccQ (ea, acc); /* quad? */ - else { /* long, sext */ - res = ReadAccL (ea, acc); - res = SEXT_L_Q (res); - } - } -else if (ir & HW_LD_Q) R[ra] = ReadPQ (ea); /* physical, quad? */ -else { - res = ReadPL (ea); /* long, sext */ - res = SEXT_L_Q (res); - } -if (ir & HW_LD_LCK) lock_flag = 1; /* lock? set flag */ -if (ra != 31) R[ra] = res; /* if not R31, store */ -return SCPE_OK; -} - -/* 1F: HW_ST */ - -t_stat pal_1f (uint32 ir) -{ -t_uint64 dsp, ea; -uint32 ra, rb, acc, mode; - -if (!pal_mode && (!(itlb_cm == MODE_K) || /* pal mode, or kernel */ - !(ev5_icsr & ICSR_HWE))) ABORT (EXC_RSVI); /* and enabled? */ -ra = I_GETRA (ir); /* get ra */ -rb = I_GETRB (ir); /* get rb */ -dsp = HW_LD_GETDSP (ir); /* get displacement */ -ea = (R[rb] + (SEXT_HW_LD_DSP (dsp))) & M64; /* eff address */ -if ((ir & HW_LD_LCK) && !lock_flag) R[ra] = 0; /* lock fail? */ -else { - if (ir & HW_LD_V) { /* virtual? */ - mode = (ir & HW_LD_ALT)? ev5_alt_mode: dtlb_cm; /* access mode */ - acc = ACC_W (mode); - if (ir & HW_LD_Q) WriteAccQ (ea, R[ra], acc); /* quad? */ - else WriteAccL (ea, R[ra], acc); /* long */ - } - else if (ir & HW_LD_Q) WritePQ (ea, R[ra]); /* physical, quad? */ - else WritePL (ea, R[ra]); /* long */ - if (ir & HW_LD_LCK) lock_flag = 0; /* unlock? clr flag */ - } -return SCPE_OK; -} - -/* 1E: HW_REI */ - -t_stat pal_1e (uint32 ir) -{ -uint32 new_pal = ((uint32) ev5_excaddr) & 1; - -if (!pal_mode && (!(itlb_cm == MODE_K) || /* pal mode, or kernel */ - !(ev5_icsr & ICSR_HWE))) ABORT (EXC_RSVI); /* and enabled? */ -PCQ_ENTRY; -PC = ev5_excaddr; -if (pal_mode && !new_pal && (ev5_icsr & ICSR_SDE)) { /* leaving PAL mode? */ - PAL_USE_MAIN; /* swap out shadows */ - } -pal_mode = new_pal; -return SCPE_OK; -} - -/* PAL move from processor registers */ - -t_stat pal_19 (uint32 ir) -{ -t_uint64 res; -uint32 fnc, ra; -static const uint32 itbr_map_gh[4] = { - ITBR_PTE_GH0, ITBR_PTE_GH1, ITBR_PTE_GH2, ITBR_PTE_GH3 }; - -if (!pal_mode && (!(itlb_cm == MODE_K) || /* pal mode, or kernel */ - !(ev5_icsr & ICSR_HWE))) ABORT (EXC_RSVI); /* and enabled? */ -fnc = I_GETMDSP (ir); -ra = I_GETRA (ir); -switch (fnc) { - - case ISR: /* intr summary */ - res = ev5_isr | ((ev5_astrr & ev5_asten) << ISR_V_AST) | - ((ev5_sirr & SIRR_M_SIRR) << ISR_V_SIRR) | - (int_req[0] && !(ev5_icsr & ICSR_MSK0)? ISR_IRQ0: 0) | - (int_req[1] && !(ev5_icsr & ICSR_MSK1)? ISR_IRQ1: 0) | - (int_req[2] && !(ev5_icsr & ICSR_MSK2)? ISR_IRQ2: 0) | - (int_req[3] && !(ev5_icsr & ICSR_MSK3)? ISR_IRQ3: 0); - if (ev5_astrr & ev5_asten & ast_map[itlb_cm]) res = res | ISR_ATR; - break; - - case ITB_PTE: - res = itlb_read (); - ev5_itb_pte_temp = (res & PFN_MASK) | - ((res & PTE_ASM)? ITBR_PTE_ASM: 0) | - ((res & (PTE_KRE|PTE_ERE|PTE_SRE|PTE_URE)) << - (ITBR_PTE_V_KRE - PTE_V_KRE)) | - itbr_map_gh[PTE_GETGH (res)]; - res = 0; - break; - - case ITB_ASN: - res = (itlb_asn & ITB_ASN_M_ASN) << ITB_ASN_V_ASN; - break; - - case ITB_PTE_TEMP: - res = ev5_itb_pte_temp; - break; - - case SIRR: - res = (ev5_sirr & SIRR_M_SIRR) << SIRR_V_SIRR; - break; - - case ASTRR: - res = ev5_astrr & AST_MASK; - break; - - case ASTEN: - res = ev5_asten & AST_MASK; - break; - - case EXC_ADDR: - res = ev5_excaddr; - break; - - case EXC_SUMM: - res = trap_summ & TRAP_SUMM_RW; - break; - - case EXC_MASK: - res = trap_mask; - break; - - case PAL_BASE: - res = ev5_palbase & PAL_BASE_RW; - break; - - case ICM: - res = (itlb_cm & ICM_M_CM) << ICM_V_CM; - break; - - case IPLR: - res = (ev5_ipl & IPLR_M_IPL) << IPLR_V_IPL; - break; - - case INTID: - res = pal_eval_intr (0) & INTID_MASK; - break; - - case IFAULT_VA_FORM: - res = ev5_iva_form; - break; - - case IVPTBR: - res = ev5_ivptbr; - break; - - case ICSR: - res = (ev5_icsr & ICSR_RW) | ICSR_MBO | - ((itlb_spage & ICSR_M_SPE) << ICSR_V_SPE) | - ((fpen & 1) << ICSR_V_FPE) | - ((arch_mask & AMASK_BWX)? ICSR_BSE: 0); - break; - - case PALTEMP+0x00: case PALTEMP+0x01: case PALTEMP+0x02: case PALTEMP+0x03: - case PALTEMP+0x04: case PALTEMP+0x05: case PALTEMP+0x06: case PALTEMP+0x07: - case PALTEMP+0x08: case PALTEMP+0x09: case PALTEMP+0x0A: case PALTEMP+0x0B: - case PALTEMP+0x0C: case PALTEMP+0x0D: case PALTEMP+0x0E: case PALTEMP+0x0F: - case PALTEMP+0x10: case PALTEMP+0x11: case PALTEMP+0x12: case PALTEMP+0x13: - case PALTEMP+0x14: case PALTEMP+0x15: case PALTEMP+0x16: case PALTEMP+0x17: - res = ev5_paltemp[fnc - PALTEMP]; - break; - - case DTB_PTE: - ev5_dtb_pte_temp = dtlb_read (); - res = 0; - break; - - case DTB_PTE_TEMP: - res = ev5_dtb_pte_temp; - break; - - case MM_STAT: - res = ev5_mm_stat; - break; - - case VA: - res = ev5_va; - ev5_va_lock = 0; - break; - - case VA_FORM: - res = ev5_va_form; - break; - - case DC_PERR_STAT: - res = ev5_dcperr; - break; - - case MCSR: - res = (ev5_mcsr & MCSR_RW) | ((dtlb_spage & MCSR_M_SPE) << MCSR_V_SPE); - break; - - case DC_MODE: - res = ev5_dc_mode & DC_MODE_RW; - break; - - case MAF_MODE: - res = ev5_maf_mode & MAF_MODE_RW; - break; - - case CC: - res = (((t_uint64) pcc_h) << 32) | ((t_uint64) pcc_l); - break; - - case DC_TEST_CTL: - res = ev5_dc_test_ctl & DC_TEST_CTL_RW; - break; - - case DC_TEST_TAG: - // to be determined - res = 0; - break; - - case DC_TEST_TAG_TEMP: - res = ev5_dc_test_tag_temp & DC_TEST_TAG_RW; - break; - - default: - res = 0; - break; - } - -if (ra != 31) R[ra] = res & M64; -return SCPE_OK; -} - -/* PAL move to processor registers */ - -t_stat pal_1d (uint32 ir) -{ -uint32 fnc = I_GETMDSP (ir); -uint32 ra = I_GETRA (ir); -t_uint64 val = R[ra]; - -if (!pal_mode && (!(itlb_cm == MODE_K) || /* pal mode, or kernel */ - !(ev5_icsr & ICSR_HWE))) ABORT (EXC_RSVI); /* and enabled? */ -switch (fnc) { - - case ITB_TAG: - ev5_itb_tag = VA_GETVPN (val); - break; - - case ITB_PTE: - ev5_itb_pte = (val | PTE_V) & (PFN_MASK | ((t_uint64) (PTE_ASM | PTE_GH | - PTE_KRE | PTE_ERE | PTE_SRE | PTE_URE))); - itlb_load (ev5_itb_tag, ev5_itb_pte); - break; - - case ITB_ASN: - itlb_set_asn ((((uint32) val) >> ITB_ASN_V_ASN) & ITB_ASN_M_ASN); - break; - - case ITB_IA: - tlb_ia (TLB_CI | TLB_CA); - break; - - case ITB_IAP: - tlb_ia (TLB_CI); - break; - - case ITB_IS: - tlb_is (val, TLB_CI); - break; - - case SIRR: - ev5_sirr = (((uint32) val) >> SIRR_V_SIRR) & SIRR_M_SIRR; - break; - - case ASTRR: - ev5_astrr = ((uint32) val) & AST_MASK; - break; - - case ASTEN: - ev5_asten = ((uint32) val) & AST_MASK; - break; - - case EXC_ADDR: - ev5_excaddr = val; - break; - - case EXC_SUMM: - trap_summ = 0; - trap_mask = 0; - break; - - case PAL_BASE: - ev5_palbase = val & PAL_BASE_RW; - break; - - case ICM: - itlb_set_cm ((((uint32) val) >> ICM_V_CM) & ICM_M_CM); - break; - - case IPLR: - ev5_ipl = (((uint32) val) >> IPLR_V_IPL) & IPLR_M_IPL; - break; - - case IVPTBR: - if (ev5_icsr & ICSR_NT) ev5_ivptbr = val & IVPTBR_NT; - else ev5_ivptbr = val & IVPTBR_VMS; - break; - - case HWINT_CLR: - ev5_isr = ev5_isr & ~(val & HWINT_CLR_W1C); - break; - - case ICSR: - if (pal_mode && ((val ^ ev5_icsr) & ICSR_SDE)) { - if (val & ICSR_SDE) { PAL_USE_SHADOW; } - else { PAL_USE_MAIN; } - } - ev5_icsr = val & ICSR_RW; - itlb_set_spage ((((uint32) val) >> ICSR_V_SPE) & ICSR_M_SPE); - fpen = (((uint32) val) >> ICSR_V_FPE) & 1; - if (val & ICSR_BSE) arch_mask = arch_mask | AMASK_BWX; - else arch_mask = arch_mask & ~AMASK_BWX; - break; - - case ICPERR_STAT: - ev5_icperr = ev5_icperr & ~(((uint32) val) & ICPERR_W1C); - break; - - case PALTEMP+0x00: case PALTEMP+0x01: case PALTEMP+0x02: case PALTEMP+0x03: - case PALTEMP+0x04: case PALTEMP+0x05: case PALTEMP+0x06: case PALTEMP+0x07: - case PALTEMP+0x08: case PALTEMP+0x09: case PALTEMP+0x0A: case PALTEMP+0x0B: - case PALTEMP+0x0C: case PALTEMP+0x0D: case PALTEMP+0x0E: case PALTEMP+0x0F: - case PALTEMP+0x10: case PALTEMP+0x11: case PALTEMP+0x12: case PALTEMP+0x13: - case PALTEMP+0x14: case PALTEMP+0x15: case PALTEMP+0x16: case PALTEMP+0x17: - ev5_paltemp[fnc - PALTEMP] = val; - break; - - case DTB_ASN: - dtlb_set_asn (((uint32) (val >> DTB_ASN_V_ASN)) & DTB_ASN_M_ASN); - break; - - case DTB_CM: - dtlb_set_cm (((uint32) (val >> ICM_V_CM)) & ICM_M_CM); - break; - - case DTB_TAG: - ev5_dtb_tag = VA_GETVPN (val); - val = (val | PTE_V) & (PFN_MASK | ((t_uint64) (PTE_MASK & ~PTE_FOE))); - dtlb_load (ev5_dtb_tag, val); - break; - - case DTB_PTE: - ev5_dtb_pte = val; - break; - - case MVPTBR: - ev5_mvptbr = val & ~MVPTBR_MBZ; - break; - - case DC_PERR_STAT: - ev5_dcperr = ev5_dcperr & ~(((uint32) val) & DC_PERR_W1C); - if ((ev5_dcperr & DC_PERR_W1C) == 0) ev5_dcperr = 0; - break; - - case DTB_IA: - tlb_ia (TLB_CD | TLB_CA); - break; - - case DTB_IAP: - tlb_ia (TLB_CD); - break; - - case DTB_IS: - tlb_is (val, TLB_CD); - break; - - case MCSR: - ev5_mcsr = ((uint32) val) & MCSR_RW; - dtlb_set_spage ((((uint32) val) >> MCSR_V_SPE) & MCSR_M_SPE); - if (ev5_mcsr & MCSR_NT) pal_type = PAL_NT; - break; - - case DC_MODE: - ev5_dc_mode = ((uint32) val) & DC_MODE_RW; - break; - - case MAF_MODE: - ev5_maf_mode = ((uint32) val) & MAF_MODE_RW; - break; - - case CC: - pcc_h = (uint32) ((val >> 32) & M32); - break; - - case CC_CTL: - pcc_l = ((uint32) val) & (M32 & ~CC_CTL_MBZ); - if (val & CC_CTL_ENB) pcc_enb = 1; - else pcc_enb = 0; - break; - - case DC_TEST_CTL: - ev5_dc_test_ctl = ((uint32) val) & DC_TEST_CTL_RW; - break; - - case DC_TEST_TAG: - ev5_dc_test_tag = val & DC_TEST_TAG_RW; - break; - - default: - break; - } - -return SCPE_OK; -} - -/* EV5 PALcode reset */ - -t_stat pal_proc_reset_hwre (DEVICE *dptr) -{ -ev5_palbase = 0; -ev5_mchk = 0; -ev5_pwrfl = 0; -ev5_crd = 0; -ev5_sli = 0; -itlb_set_cm (MODE_K); -itlb_set_asn (0); -itlb_set_spage (0); -dtlb_set_cm (MODE_K); -dtlb_set_asn (0); -dtlb_set_spage (0); -return SCPE_OK; -} - -/* EV5 PAL instruction print and parse routines */ - -static const char *pal_inam[] = { - "HW_MFPR", "HW_LD", "HW_MTPR", "HW_REI", "HW_ST", NULL - }; - -static const uint32 pal_ival[] = { - 0x64000000, 0x6C000000, 0x74000000, 0x7BFF8000, 0x7C000000 - }; - -struct pal_opt { - uint32 mask; /* bit mask */ - char let; /* matching letter */ - }; - -static struct pal_opt ld_st_opt[] = { - { HW_LD_V, 'V' }, - { HW_LD_ALT, 'A' }, - { HW_LD_WCH, 'W' }, - { HW_LD_Q, 'Q' }, - { HW_LD_PTE, 'P' }, - { HW_LD_LCK, 'L' }, - { 0 } - }; - -static struct pal_opt rei_opt[] = { - { HW_REI_S, 'S' }, - { 0 } - }; - -/* Print options for hardware PAL instruction */ - -void fprint_opt_ev5 (FILE *of, uint32 inst, struct pal_opt opt[]) -{ -uint32 i; - -for (i = 0; opt[i].mask != 0; i++) { - if (inst & opt[i].mask) { - fprintf (of, "/%c", opt[i].let); - inst = inst & ~opt[i].mask; - } - } -return; -} - -/* Parse options for hardware PAL instruction */ - -char *parse_opt_ev5 (char *cptr, uint32 *val, struct pal_opt opt[]) -{ -uint32 i; -char *tptr, gbuf[CBUFSIZE]; - -if (*(cptr - 1) != '/') return cptr; -cptr = get_glyph (cptr - 1, tptr = gbuf, 0); -while (*tptr == '/') { - tptr++; - for (i = 0; opt[i].mask != 0; i++) { - if (*tptr == opt[i].let) { - *val = *val | opt[i].mask; - break; - } - } - if (opt[i].mask == 0) return NULL; - tptr++; - } -if (*tptr != 0) return NULL; -return cptr; -} - -/* Print PAL hardware opcode symbolically */ - -t_stat fprint_pal_hwre (FILE *of, uint32 inst) -{ -uint32 op, ra, rb; - -op = I_GETOP (inst); -ra = I_GETRA (inst); -rb = I_GETRB (inst); -switch (op) { - - case OP_PAL19: /* HW_MFPR */ - case OP_PAL1D: /* HW_MTPR */ - fputs ((op == OP_PAL19)? "HW_MFPR": "HW_MTPR", of); - fprintf (of, " R%d,%X", ra, inst & M16); - break; - - case OP_PAL1B: /* HW_LD */ - case OP_PAL1F: /* HW_ST */ - fputs ((op == OP_PAL1B)? "HW_LD": "HW_ST", of); - fprint_opt_ev5 (of, inst, ld_st_opt); - fprintf (of, " R%d,%X", ra, inst & HW_LD_DSP); - if (rb != 31) fprintf (of, "(R%d)", rb); - break; - - case OP_PAL1E: /* HW_REI */ - fputs ("HW_REI", of); - fprint_opt_ev5 (of, inst, rei_opt); - break; - - default: - return SCPE_ARG; - } - -return -3; -} - -/* Parse PAL hardware opcode symbolically */ - -t_stat parse_pal_hwre (char *cptr, t_value *inst) -{ -uint32 i, d, val = 0; -int32 reg; -char *tptr, gbuf[CBUFSIZE]; -t_stat r; - -cptr = get_glyph (cptr, gbuf, '/'); -for (i = 0; pal_inam[i] != NULL; i++) { - if (strcmp (gbuf, pal_inam[i]) == 0) val = pal_ival[i]; - } -if (val == 0) return SCPE_ARG; -switch (I_GETOP (val)) { - - case OP_PAL19: /* HW_MFPR */ - case OP_PAL1D: /* HW_MTPR */ - if (*(cptr - 1) == '/') return SCPE_ARG; - cptr = get_glyph (cptr, gbuf, ','); /* get reg */ - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - val = val | (reg << I_V_RA) | (reg << I_V_RB); - cptr = get_glyph (cptr, gbuf, 0); /* get ipr */ - d = (uint32) get_uint (gbuf, 16, M16, &r); - if (r != SCPE_OK) return r; - val = val | d; - break; - - case OP_PAL1B: /* HW_LD */ - case OP_PAL1F: /* HW_ST */ - cptr = parse_opt_ev5 (cptr, &val, ld_st_opt); - if (cptr == NULL) return SCPE_ARG; - cptr = get_glyph (cptr, gbuf, ','); /* get reg */ - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - val = val | (reg << I_V_RA); - cptr = get_glyph (cptr, gbuf, 0); - d = (uint32) strtotv (gbuf, &tptr, 16); - if ((gbuf == tptr) || (d > HW_LD_DSP)) return SCPE_ARG; - val = val | d; - if (*tptr == '(') { - tptr = get_glyph (tptr + 1, gbuf, ')'); - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - val = val | (reg << I_V_RB); - } - else val = val | (31 << I_V_RB); - break; - - case OP_PAL1E: /* HW_REI */ - cptr = parse_opt_ev5 (cptr, &val, rei_opt); - if (cptr == NULL) return SCPE_ARG; - break; - - default: - return SCPE_ARG; - } - -*inst = val; -if (*cptr != 0) return SCPE_ARG; -return -3; -} - diff --git a/alpha/alpha_ev5_tlb.c b/alpha/alpha_ev5_tlb.c deleted file mode 100644 index 9cfded4a..00000000 --- a/alpha/alpha_ev5_tlb.c +++ /dev/null @@ -1,566 +0,0 @@ -/* alpha_ev5_tlb.c - Alpha EV5 TLB simulator - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - EV5 was the second generation Alpha CPU. It was a four-way, in order issue - CPU with onchip primary instruction and data caches, an onchip second level - cache, and support for an offchip third level cache. EV56 was a shrink, with - added support for byte and word operations. EV56PC was a version of EV56 - without the onchip second level cache. - - This module contains the routines for - - itlb_lookup lookup vpn in instruction TLB - itlb_load load pte into instruction TLB - itlb_read read pte from instruction TLB using NLU pointer - itlb_set_asn set iasn - itlb_set_cm set icm - itlb_set_spage set ispage - dtlb_lookup lookup vpn in data TLB - dtlb_load load pte into data TLB - dtlb_read read pte from data TLB using NLU pointer - dtlb_set_asn set dasn - dtlb_set_cm set dcm - dtlb_set_spage set dspage - tlb_ia TLB invalidate all - tlb_is TLB invalidate single - tlb_set_cm TLB set current mode -*/ - -#include "alpha_defs.h" -#include "alpha_ev5_defs.h" - -#define ITLB_SORT qsort (itlb, ITLB_SIZE, sizeof (TLBENT), &tlb_comp); -#define DTLB_SORT qsort (dtlb, DTLB_SIZE, sizeof (TLBENT), &tlb_comp); -#define TLB_ESIZE (sizeof (TLBENT)/sizeof (uint32)) -#define MM_RW(x) (((x) & PTE_FOW)? EXC_W: EXC_R) - -uint32 itlb_cm = 0; /* current modes */ -uint32 itlb_spage = 0; /* superpage enables */ -uint32 itlb_asn = 0; -uint32 itlb_nlu = 0; -TLBENT i_mini_tlb; -TLBENT itlb[ITLB_SIZE]; -uint32 dtlb_cm = 0; -uint32 dtlb_spage = 0; -uint32 dtlb_asn = 0; -uint32 dtlb_nlu = 0; -TLBENT d_mini_tlb; -TLBENT dtlb[DTLB_SIZE]; - -uint32 cm_eacc = ACC_E (MODE_K); /* precomputed */ -uint32 cm_racc = ACC_R (MODE_K); /* access checks */ -uint32 cm_wacc = ACC_W (MODE_K); -uint32 cm_macc = ACC_M (MODE_K); - -extern t_uint64 p1; -extern jmp_buf save_env; - -uint32 mm_exc (uint32 macc); -void tlb_inval (TLBENT *tlbp); -t_stat itlb_reset (void); -t_stat dtlb_reset (void); -int tlb_comp (const void *e1, const void *e2); -t_stat tlb_reset (DEVICE *dptr); - -/* TLB data structures - - tlb_dev pager device descriptor - tlb_unit pager units - tlb_reg pager register list -*/ - -UNIT tlb_unit = { UDATA (NULL, 0, 0) }; - -REG tlb_reg[] = { - { HRDATA (ICM, itlb_cm, 2) }, - { HRDATA (ISPAGE, itlb_spage, 2), REG_HRO }, - { HRDATA (IASN, itlb_asn, ITB_ASN_WIDTH) }, - { HRDATA (INLU, itlb_nlu, ITLB_WIDTH) }, - { BRDATA (IMINI, &i_mini_tlb, 16, 32, TLB_ESIZE) }, - { BRDATA (ITLB, itlb, 16, 32, ITLB_SIZE*TLB_ESIZE) }, - { HRDATA (DCM, dtlb_cm, 2) }, - { HRDATA (DSPAGE, dtlb_spage, 2), REG_HRO }, - { HRDATA (DASN, dtlb_asn, DTB_ASN_WIDTH) }, - { HRDATA (DNLU, dtlb_nlu, DTLB_WIDTH) }, - { BRDATA (DMINI, &d_mini_tlb, 16, 32, TLB_ESIZE) }, - { BRDATA (DTLB, dtlb, 16, 32, DTLB_SIZE*TLB_ESIZE) }, - { NULL } - }; - -DEVICE tlb_dev = { - "TLB", &tlb_unit, tlb_reg, NULL, - 1, 0, 0, 1, 0, 0, - NULL, NULL, &tlb_reset, - NULL, NULL, NULL - }; - -/* Translate address, instruction, data, and console - - Inputs: - va = virtual address - acc = (VAX only) access mode - Outputs: - pa = translation buffer index -*/ - -t_uint64 trans_i (t_uint64 va) -{ -uint32 va_sext = VA_GETSEXT (va); -uint32 vpn = VA_GETVPN (va); -TLBENT *tlbp; - -if ((va_sext != 0) && (va_sext != VA_M_SEXT)) /* invalid virt addr? */ - ABORT1 (va, EXC_BVA + EXC_E); -if ((itlb_spage & SPEN_43) && VPN_GETSP43 (vpn) == 2) { /* 43b superpage? */ - if (itlb_cm != MODE_K) ABORT1 (va, EXC_ACV + EXC_E); - return (va & SP43_MASK); - } -if ((itlb_spage & SPEN_32) && (VPN_GETSP32 (vpn) == 0x1FFE)) { - if (itlb_cm != MODE_K) ABORT1 (va, EXC_ACV + EXC_E); - return (va & SP32_MASK); /* 32b superpage? */ - } -if (!(tlbp = itlb_lookup (vpn))) /* lookup vpn; miss? */ - ABORT1 (va, EXC_TBM + EXC_E); /* abort reference */ -if (cm_eacc & ~tlbp->pte) /* check access */ - ABORT1 (va, mm_exc (cm_eacc & ~tlbp->pte) | EXC_E); -return PHYS_ADDR (tlbp->pfn, va); /* return phys addr */ -} - -t_uint64 trans_d (t_uint64 va, uint32 acc) -{ -uint32 va_sext = VA_GETSEXT (va); -uint32 vpn = VA_GETVPN (va); -TLBENT *tlbp; - -if ((va_sext != 0) && (va_sext != VA_M_SEXT)) /* invalid virt addr? */ - ABORT1 (va, EXC_BVA + MM_RW (acc)); -if ((dtlb_spage & SPEN_43) && (VPN_GETSP43 (vpn) == 2)) { - if (dtlb_cm != MODE_K) ABORT1 (va, EXC_ACV + MM_RW (acc)); - return (va & SP43_MASK); /* 43b superpage? */ - } -if ((dtlb_spage & SPEN_32) && (VPN_GETSP32 (vpn) == 0x1FFE)) { - if (dtlb_cm != MODE_K) ABORT1 (va, EXC_ACV + MM_RW (acc)); - return (va & SP32_MASK); /* 32b superpage? */ - } -if (!(tlbp = dtlb_lookup (vpn))) /* lookup vpn; miss? */ - ABORT1 (va, EXC_TBM + MM_RW (acc)); /* abort reference */ -if (acc & ~tlbp->pte) /* check access */ - ABORT1 (va, mm_exc (acc & ~tlbp->pte) | MM_RW (acc)); -return PHYS_ADDR (tlbp->pfn, va); /* return phys addr */ -} - -/* Generate a memory management error code, based on the access check bits not - set in PTE - - - If the access check bits, without FOx and V, fail, then ACV - - If FOx set, then FOx - - Otherwise, TNV */ - -uint32 mm_exc (uint32 not_set) -{ -uint32 tacc; - -tacc = not_set & ~(PTE_FOR | PTE_FOW | PTE_FOE | PTE_V); -if (tacc) return EXC_ACV; -tacc = not_set & (PTE_FOR | PTE_FOW | PTE_FOE); -if (tacc) return EXC_FOX; -return EXC_TNV; -} - -/* TLB invalidate single */ - -void tlb_is (t_uint64 va, uint32 flags) -{ -uint32 va_sext = VA_GETSEXT (va); -uint32 vpn = VA_GETVPN (va); -TLBENT *itlbp, *dtlbp; - -if ((va_sext != 0) && (va_sext != VA_M_SEXT)) return; -if ((flags & TLB_CI) && (itlbp = itlb_lookup (vpn))) { - tlb_inval (itlbp); - tlb_inval (&i_mini_tlb); - ITLB_SORT; - } -if ((flags & TLB_CD) && (dtlbp = dtlb_lookup (vpn))) { - tlb_inval (dtlbp); - tlb_inval (&d_mini_tlb); - DTLB_SORT; - } -return; -} - -/* TLB invalidate all */ - -void tlb_ia (uint32 flags) -{ -uint32 i; - -if (flags & TLB_CA) { - if (flags & TLB_CI) itlb_reset (); - if (flags & TLB_CD) dtlb_reset (); - return; - } -if (flags & TLB_CI) { - for (i = 0; i < ITLB_SIZE; i++) { - if (!(itlb[i].pte & PTE_ASM)) tlb_inval (&itlb[i]); - } - tlb_inval (&i_mini_tlb); - ITLB_SORT; - } -if (flags & TLB_CD) { - for (i = 0; i < DTLB_SIZE; i++) { - if (!(dtlb[i].pte & PTE_ASM)) tlb_inval (&dtlb[i]); - } - tlb_inval (&d_mini_tlb); - DTLB_SORT; - } -return; -} - -/* TLB lookup */ - -TLBENT *itlb_lookup (uint32 vpn) -{ -int32 p, hi, lo; - -if (vpn == i_mini_tlb.tag) return &i_mini_tlb; -lo = 0; /* initial bounds */ -hi = ITLB_SIZE - 1; -do { - p = (lo + hi) >> 1; /* probe */ - if ((itlb_asn == itlb[p].asn) && - (((vpn ^ itlb[p].tag) & - ~((uint32) itlb[p].gh_mask)) == 0)) { /* match to TLB? */ - i_mini_tlb.tag = vpn; - i_mini_tlb.pte = itlb[p].pte; - i_mini_tlb.pfn = itlb[p].pfn; - itlb_nlu = itlb[p].idx + 1; - if (itlb_nlu >= ITLB_SIZE) itlb_nlu = 0; - return &i_mini_tlb; - } - if ((itlb_asn < itlb[p].asn) || - ((itlb_asn == itlb[p].asn) && (vpn < itlb[p].tag))) - hi = p - 1; /* go down? p is upper */ - else lo = p + 1; /* go up? p is lower */ - } -while (lo <= hi); -return NULL; -} - -TLBENT *dtlb_lookup (uint32 vpn) -{ -int32 p, hi, lo; - -if (vpn == d_mini_tlb.tag) return &d_mini_tlb; -lo = 0; /* initial bounds */ -hi = DTLB_SIZE - 1; -do { - p = (lo + hi) >> 1; /* probe */ - if ((dtlb_asn == dtlb[p].asn) && - (((vpn ^ dtlb[p].tag) & - ~((uint32) dtlb[p].gh_mask)) == 0)) { /* match to TLB? */ - d_mini_tlb.tag = vpn; - d_mini_tlb.pte = dtlb[p].pte; - d_mini_tlb.pfn = dtlb[p].pfn; - dtlb_nlu = dtlb[p].idx + 1; - if (dtlb_nlu >= DTLB_SIZE) dtlb_nlu = 0; - return &d_mini_tlb; - } - if ((dtlb_asn < dtlb[p].asn) || - ((dtlb_asn == dtlb[p].asn) && (vpn < dtlb[p].tag))) - hi = p - 1; /* go down? p is upper */ - else lo = p + 1; /* go up? p is lower */ - } -while (lo <= hi); -return NULL; -} - -/* Load TLB entry at NLU pointer, advance NLU pointer */ - -TLBENT *itlb_load (uint32 vpn, t_uint64 l3pte) -{ -uint32 i, gh; - -for (i = 0; i < ITLB_SIZE; i++) { - if (itlb[i].idx == itlb_nlu) { - TLBENT *tlbp = itlb + i; - itlb_nlu = itlb_nlu + 1; - if (itlb_nlu >= ITLB_SIZE) itlb_nlu = 0; - tlbp->tag = vpn; - tlbp->pte = (uint32) (l3pte & PTE_MASK) ^ (PTE_FOR|PTE_FOR|PTE_FOE); - tlbp->pfn = ((uint32) (l3pte >> PTE_V_PFN)) & PFN_MASK; - tlbp->asn = itlb_asn; - gh = PTE_GETGH (tlbp->pte); - tlbp->gh_mask = (1u << (3 * gh)) - 1; - tlb_inval (&i_mini_tlb); - ITLB_SORT; - return tlbp; - } - } -fprintf (stderr, "%%ITLB entry not found, itlb_nlu = %d\n", itlb_nlu); -ABORT (-SCPE_IERR); -return NULL; -} - -TLBENT *dtlb_load (uint32 vpn, t_uint64 l3pte) -{ -uint32 i, gh; - -for (i = 0; i < DTLB_SIZE; i++) { - if (dtlb[i].idx == dtlb_nlu) { - TLBENT *tlbp = dtlb + i; - dtlb_nlu = dtlb_nlu + 1; - if (dtlb_nlu >= ITLB_SIZE) dtlb_nlu = 0; - tlbp->tag = vpn; - tlbp->pte = (uint32) (l3pte & PTE_MASK) ^ (PTE_FOR|PTE_FOR|PTE_FOE); - tlbp->pfn = ((uint32) (l3pte >> PTE_V_PFN)) & PFN_MASK; - tlbp->asn = dtlb_asn; - gh = PTE_GETGH (tlbp->pte); - tlbp->gh_mask = (1u << (3 * gh)) - 1; - tlb_inval (&d_mini_tlb); - DTLB_SORT; - return tlbp; - } - } -fprintf (stderr, "%%DTLB entry not found, dtlb_nlu = %d\n", dtlb_nlu); -ABORT (-SCPE_IERR); -return NULL; -} - -/* Read TLB entry at NLU pointer, advance NLU pointer */ - -t_uint64 itlb_read (void) -{ -uint8 i; - -for (i = 0; i < ITLB_SIZE; i++) { - if (itlb[i].idx == itlb_nlu) { - TLBENT *tlbp = itlb + i; - itlb_nlu = itlb_nlu + 1; - if (itlb_nlu >= ITLB_SIZE) itlb_nlu = 0; - return (((t_uint64) tlbp->pfn) << PTE_V_PFN) | - ((tlbp->pte ^ (PTE_FOR|PTE_FOR|PTE_FOE)) & PTE_MASK); - } - } -fprintf (stderr, "%%ITLB entry not found, itlb_nlu = %d\n", itlb_nlu); -ABORT (-SCPE_IERR); -return 0; -} - -t_uint64 dtlb_read (void) -{ -uint8 i; - -for (i = 0; i < DTLB_SIZE; i++) { - if (dtlb[i].idx == dtlb_nlu) { - TLBENT *tlbp = dtlb + i; - dtlb_nlu = dtlb_nlu + 1; - if (dtlb_nlu >= DTLB_SIZE) dtlb_nlu = 0; - return (((t_uint64) tlbp->pfn) << PTE_V_PFN) | - ((tlbp->pte ^ (PTE_FOR|PTE_FOR|PTE_FOE)) & PTE_MASK); - } - } -fprintf (stderr, "%%DTLB entry not found, dtlb_nlu = %d\n", dtlb_nlu); -ABORT (-SCPE_IERR); -return 0; -} - -/* Set ASN - rewrite TLB globals with correct ASN */ - -void itlb_set_asn (uint32 asn) -{ -int32 i; - -itlb_asn = asn; -for (i = 0; i < ITLB_SIZE; i++) { - if (itlb[i].pte & PTE_ASM) itlb[i].asn = asn; - } -tlb_inval (&i_mini_tlb); -ITLB_SORT; -return; -} - -void dtlb_set_asn (uint32 asn) -{ -int32 i; - -dtlb_asn = asn; -for (i = 0; i < DTLB_SIZE; i++) { - if (dtlb[i].pte & PTE_ASM) dtlb[i].asn = asn; - } -tlb_inval (&d_mini_tlb); -DTLB_SORT; -return; -} - -/* Set superpage */ - -void itlb_set_spage (uint32 spage) -{ -itlb_spage = spage; -return; -} - -void dtlb_set_spage (uint32 spage) -{ -dtlb_spage = spage; -return; -} - -/* Set current mode */ - -void itlb_set_cm (uint32 mode) -{ -itlb_cm = mode; -cm_eacc = ACC_E (mode); -return; -} - -void dtlb_set_cm (uint32 mode) -{ -dtlb_cm = mode; -cm_racc = ACC_R (mode); -cm_wacc = ACC_W (mode); -return; -} - -uint32 tlb_set_cm (int32 cm) -{ -if (cm >= 0) { - itlb_set_cm (cm); - dtlb_set_cm (cm); - return cm; - } -itlb_set_cm (itlb_cm); -dtlb_set_cm (dtlb_cm); -return dtlb_cm; -} - -/* Invalidate TLB entry */ - -void tlb_inval (TLBENT *tlbp) -{ -tlbp->tag = INV_TAG; -tlbp->pte = 0; -tlbp->pfn = 0; -tlbp->asn = tlbp->idx; -tlbp->gh_mask = 0; -return; -} - -/* Compare routine for qsort */ - -int tlb_comp (const void *e1, const void *e2) -{ -TLBENT *t1 = (TLBENT *) e1; -TLBENT *t2 = (TLBENT *) e2; - -if (t1->asn > t2->asn) return +1; -if (t1->asn < t2->asn) return -1; -if (t1->tag > t2->tag) return +1; -if (t1->tag < t2->tag) return -1; -return 0; -} - -/* ITLB reset */ - -t_stat itlb_reset (void) -{ -int32 i; - -itlb_nlu = 0; -for (i = 0; i < ITLB_SIZE; i++) { - itlb[i].tag = INV_TAG; - itlb[i].pte = 0; - itlb[i].pfn = 0; - itlb[i].asn = i; - itlb[i].gh_mask = 0; - itlb[i].idx = i; - } -tlb_inval (&i_mini_tlb); -return SCPE_OK; -} -/* DTLB reset */ - -t_stat dtlb_reset (void) -{ -int32 i; - -dtlb_nlu = 0; -for (i = 0; i < DTLB_SIZE; i++) { - dtlb[i].tag = INV_TAG; - dtlb[i].pte = 0; - dtlb[i].pfn = 0; - dtlb[i].asn = i; - dtlb[i].gh_mask = 0; - dtlb[i].idx = i; - } -tlb_inval (&d_mini_tlb); -return SCPE_OK; -} - -/* SimH reset */ - -t_stat tlb_reset (DEVICE *dptr) -{ -itlb_reset (); -dtlb_reset (); -return SCPE_OK; -} - -/* Show TLB entry or entries */ - -t_stat cpu_show_tlb (FILE *of, UNIT *uptr, int32 val, void *desc) -{ -t_addr lo, hi; -uint32 lnt; -TLBENT *tlbp; -DEVICE *dptr; -char *cptr = (char *) desc; - -lnt = (val)? DTLB_SIZE: ITLB_SIZE; -dptr = find_dev_from_unit (uptr); -if (dptr == NULL) return SCPE_IERR; -if (cptr) { - cptr = get_range (dptr, cptr, &lo, &hi, 10, lnt, 0); - if ((cptr == NULL) || (*cptr != 0)) return SCPE_ARG; - } -else { - lo = 0; - hi = lnt - 1; - } -tlbp = (val)? dtlb + lo: itlb + lo; - -do { - fprintf (of, "TLB %02d\tTAG=%02X/%08X, ", (uint32) lo, tlbp->asn, tlbp->tag); - fprintf (of, "MASK=%X, INDX=%d, ", tlbp->gh_mask, tlbp->idx); - fprintf (of, "PTE=%04X, PFN=%08X\n", tlbp->pte, tlbp->pfn); - tlbp++; - lo++; - } while (lo <= hi); - -return SCPE_OK; -} - diff --git a/alpha/alpha_fpi.c b/alpha/alpha_fpi.c deleted file mode 100644 index 62c7b459..00000000 --- a/alpha/alpha_fpi.c +++ /dev/null @@ -1,776 +0,0 @@ -/* alpha_fpi.c - Alpha IEEE floating point simulator - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - This module contains the instruction simulators for - - - single precision floating point, S - - double precision floating point, T - - Portions of this module (specifically, the convert floating to integer - routine and the square root routine) are a derivative work from SoftFloat, - written by John Hauser. SoftFloat includes the following license terms: - - Written by John R. Hauser. This work 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. More information - is available through the Web page 'http://www.cs.berkeley.edu/~jhauser/ - arithmetic/SoftFloat.html'. - - 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 TAKE FULL RESPONSIBILITY FOR ALL LOSSES, - COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE - EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE - INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR - OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE. - - Derivative works are acceptable, even for commercial purposes, so long as - (1) the source code for the derivative work includes prominent notice that - the work is derivative, and (2) the source code includes prominent notice with - these four paragraphs for those parts of this code that are retained. -*/ - -#include "alpha_defs.h" - -#define UFT_ZERO 0 /* unpacked: zero */ -#define UFT_FIN 1 /* finite */ -#define UFT_DENORM 2 /* denormal */ -#define UFT_INF 3 /* infinity */ -#define UFT_NAN 4 /* not a number */ - -#define Q_FINITE(x) ((x) <= UFT_FIN) /* finite */ -#define Q_SUI(x) (((x) & I_FTRP) == I_FTRP_SVI) - -/* Register format constants */ - -#define QNAN 0x0008000000000000 /* quiet NaN flag */ -#define CQNAN 0xFFF8000000000000 /* canonical quiet NaN */ -#define FPZERO 0x0000000000000000 /* plus zero (fp) */ -#define FMZERO 0x8000000000000000 /* minus zero (fp) */ -#define FPINF 0x7FF0000000000000 /* plus infinity (fp) */ -#define FMINF 0xFFF0000000000000 /* minus infinity (fp) */ -#define FPMAX 0x7FEFFFFFFFFFFFFF /* plus MAX (fp) */ -#define FMMAX 0xFFEFFFFFFFFFFFFF /* minus MAX (fp) */ -#define IPMAX 0x7FFFFFFFFFFFFFFF /* plus MAX (int) */ -#define IMMAX 0x8000000000000000 /* minus MAX (int) */ - -/* Unpacked rounding constants */ - -#define UF_SRND 0x0000008000000000 /* S normal round */ -#define UF_SINF 0x000000FFFFFFFFFF /* S infinity round */ -#define UF_TRND 0x0000000000000400 /* T normal round */ -#define UF_TINF 0x00000000000007FF /* T infinity round */ - -extern t_uint64 FR[32]; -extern uint32 fpcr; -extern jmp_buf save_env; - -t_bool ieee_unpack (t_uint64 op, UFP *r, uint32 ir); -void ieee_norm (UFP *r); -t_uint64 ieee_rpack (UFP *r, uint32 ir, uint32 dp); -void ieee_trap (uint32 trap, uint32 instenb, uint32 fpcrdsb, uint32 ir); -int32 ieee_fcmp (t_uint64 a, t_uint64 b, uint32 ir, uint32 signal_nan); -t_uint64 ieee_cvtst (t_uint64 op, uint32 ir); -t_uint64 ieee_cvtts (t_uint64 op, uint32 ir); -t_uint64 ieee_cvtif (t_uint64 val, uint32 ir, uint32 dp); -t_uint64 ieee_cvtfi (t_uint64 op, uint32 ir); -t_uint64 ieee_fadd (t_uint64 a, t_uint64 b, uint32 ir, uint32 dp, t_bool sub); -t_uint64 ieee_fmul (t_uint64 a, t_uint64 b, uint32 ir, uint32 dp); -t_uint64 ieee_fdiv (t_uint64 a, t_uint64 b, uint32 ir, uint32 dp); -uint32 estimateSqrt32 (uint32 exp, uint32 a); -t_uint64 estimateDiv128 (t_uint64 hi, t_uint64 lo, t_uint64 dvr); - -extern t_uint64 uemul64 (t_uint64 a, t_uint64 b, t_uint64 *hi); -extern t_uint64 ufdiv64 (t_uint64 dvd, t_uint64 dvr, uint32 prec, uint32 *sticky); -t_uint64 fsqrt64 (t_uint64 frac, int32 exp); - -/* IEEE S load */ - -t_uint64 op_lds (t_uint64 op) -{ -uint32 exp = S_GETEXP (op); /* get exponent */ - -if (exp == S_NAN) exp = FPR_NAN; /* inf or NaN? */ -else if (exp != 0) exp = exp + T_BIAS - S_BIAS; /* zero or denorm? */ -return (((t_uint64) (op & S_SIGN))? FPR_SIGN: 0) | /* reg format */ - (((t_uint64) exp) << FPR_V_EXP) | - (((t_uint64) (op & ~(S_SIGN|S_EXP))) << S_V_FRAC); -} - -/* IEEE S store */ - -t_uint64 op_sts (t_uint64 op) -{ -uint32 sign = FPR_GETSIGN (op)? S_SIGN: 0; -uint32 frac = ((uint32) (op >> S_V_FRAC)) & M32; -uint32 exp = FPR_GETEXP (op); - -if (exp == FPR_NAN) exp = S_NAN; /* inf or NaN? */ -else if (exp != 0) exp = exp + S_BIAS - T_BIAS; /* non-zero? */ -exp = (exp & S_M_EXP) << S_V_EXP; -return (t_uint64) (sign | exp | (frac & ~(S_SIGN|S_EXP))); -} - -/* IEEE floating operate */ - -void ieee_fop (uint32 ir) -{ -UFP a, b; -uint32 ftpa, ftpb, fnc, ra, rb, rc; -t_uint64 res; - -fnc = I_GETFFNC (ir); /* get function */ -ra = I_GETRA (ir); /* get registers */ -rb = I_GETRB (ir); -rc = I_GETRC (ir); -switch (fnc) { /* case on func */ - - case 0x00: /* ADDS */ - res = ieee_fadd (FR[ra], FR[rb], ir, DT_S, 0); - break; - - case 0x01: /* SUBS */ - res = ieee_fadd (FR[ra], FR[rb], ir, DT_S, 1); - break; - - case 0x02: /* MULS */ - res = ieee_fmul (FR[ra], FR[rb], ir, DT_S); - break; - - case 0x03: /* DIVS */ - res = ieee_fdiv (FR[ra], FR[rb], ir, DT_S); - break; - - case 0x20: /* ADDT */ - res = ieee_fadd (FR[ra], FR[rb], ir, DT_T, 0); - break; - - case 0x21: /* SUBT */ - res = ieee_fadd (FR[ra], FR[rb], ir, DT_T, 1); - break; - - case 0x22: /* MULT */ - res = ieee_fmul (FR[ra], FR[rb], ir, DT_T); - break; - - case 0x23: /* DIVT */ - res = ieee_fdiv (FR[ra], FR[rb], ir, DT_T); - break; - - case 0x24: /* CMPTUN */ - ftpa = ieee_unpack (FR[ra], &a, ir); /* unpack */ - ftpb = ieee_unpack (FR[rb], &b, ir); - if ((ftpa == UFT_NAN) || (ftpb == UFT_NAN)) /* if NaN, T */ - res = FP_TRUE; - else res = 0; - break; - - case 0x25: /* CMPTEQ */ - if (ieee_fcmp (FR[ra], FR[rb], ir, 0) == 0) res = FP_TRUE; - else res = 0; - break; - - case 0x26: /* CMPTLT */ - if (ieee_fcmp (FR[ra], FR[rb], ir, 1) < 0) res = FP_TRUE; - else res = 0; - break; - - case 0x27: /* CMPTLE */ - if (ieee_fcmp (FR[ra], FR[rb], ir, 1) <= 0) res = FP_TRUE; - else res = 0; - break; - - case 0x2C: /* CVTST, CVTTS */ - if (ir & 0x2000) res = ieee_cvtst (FR[rb], ir); /* CVTST */ - else res = ieee_cvtts (FR[rb], ir); /* CVTTS */ - break; - - case 0x2F: /* CVTTQ */ - res = ieee_cvtfi (FR[rb], ir); - break; - - case 0x3C: /* CVTQS */ - res = ieee_cvtif (FR[rb], ir, DT_S); - break; - - case 0x3E: /* CVTQT */ - res = ieee_cvtif (FR[rb], ir, DT_T); - break; - - default: - if ((ir & I_FSRC) == I_FSRC_X) ABORT (EXC_RSVI); - res = FR[rc]; - break; - } - -if (rc != 31) FR[rc] = res & M64; -return; -} - -/* IEEE S to T convert - LDS doesn't handle denorms correctly */ - -t_uint64 ieee_cvtst (t_uint64 op, uint32 ir) -{ -UFP b; -uint32 ftpb; - -ftpb = ieee_unpack (op, &b, ir); /* unpack; norm dnorm */ -if (ftpb == UFT_DENORM) { /* denormal? */ - b.exp = b.exp + T_BIAS - S_BIAS; /* change 0 exp to T */ - return ieee_rpack (&b, ir, DT_T); /* round, pack */ - } -else return op; /* identity */ -} - -/* IEEE T to S convert */ - -t_uint64 ieee_cvtts (t_uint64 op, uint32 ir) -{ -UFP b; -uint32 ftpb; - -ftpb = ieee_unpack (op, &b, ir); /* unpack */ -if (Q_FINITE (ftpb)) return ieee_rpack (&b, ir, DT_S); /* finite? round, pack */ -if (ftpb == UFT_NAN) return (op | QNAN); /* nan? cvt to quiet */ -if (ftpb == UFT_INF) return op; /* inf? unchanged */ -return 0; /* denorm? 0 */ -} - -/* IEEE floating compare - - - Take care of NaNs - - Force -0 to +0 - - Then normal compare will work (even on inf and denorms) */ - -int32 ieee_fcmp (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 trap_nan) -{ -UFP a, b; -uint32 ftpa, ftpb; - -ftpa = ieee_unpack (s1, &a, ir); -ftpb = ieee_unpack (s2, &b, ir); -if ((ftpa == UFT_NAN) || (ftpb == UFT_NAN)) { /* NaN involved? */ - if (trap_nan) ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); - return +1; /* force failure */ - } -if (ftpa == UFT_ZERO) a.sign = 0; /* only +0 allowed */ -if (ftpb == UFT_ZERO) b.sign = 0; -if (a.sign != b.sign) return (a.sign? -1: +1); /* unequal signs? */ -if (a.exp != b.exp) return ((a.sign ^ (a.exp < b.exp))? -1: +1); -if (a.frac != b.frac) return ((a.sign ^ (a.frac < b.frac))? -1: +1); -return 0; -} - -/* IEEE integer to floating convert */ - -t_uint64 ieee_cvtif (t_uint64 val, uint32 ir, uint32 dp) -{ -UFP a; - -if (val == 0) return 0; /* 0? return +0 */ -if (val & FPR_SIGN) { /* < 0? */ - a.sign = 1; /* set sign */ - val = NEG_Q (val); /* |val| */ - } -else a.sign = 0; -a.exp = 63 + T_BIAS; /* set exp */ -a.frac = val; /* set frac */ -ieee_norm (&a); /* normalize */ -return ieee_rpack (&a, ir, dp); /* round and pack */ -} - -/* IEEE floating to integer convert - rounding code from SoftFloat - The Alpha architecture specifies return of the low order bits of - the true result, whereas the IEEE standard specifies the return - of the maximum plus or minus value */ - -t_uint64 ieee_cvtfi (t_uint64 op, uint32 ir) -{ -UFP a; -t_uint64 sticky; -uint32 rndm, ftpa, ovf; -int32 ubexp; - -ftpa = ieee_unpack (op, &a, ir); /* unpack */ -if (!Q_FINITE (ftpa)) { /* inf, NaN, dnorm? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* inv operation */ - return 0; - } -if (ftpa == UFT_ZERO) return 0; /* zero? */ -ovf = 0; /* assume no ovflo */ -ubexp = a.exp - T_BIAS; /* unbiased exp */ -if (ubexp < 0) { /* < 1? */ - if (ubexp == -1) sticky = a.frac; /* [.5,1)? */ - else sticky = 1; /* (0,.5) */ - a.frac = 0; - } -else if (ubexp < UF_V_NM) { /* in range? */ - sticky = (a.frac << (64 - (UF_V_NM - ubexp))) & M64; - a.frac = a.frac >> (UF_V_NM - ubexp); /* result */ - } -else if (ubexp == UF_V_NM) sticky = 0; /* at limit of range? */ -else { - if ((ubexp - UF_V_NM) > 63) a.frac = 0; /* out of range */ - else a.frac = (a.frac << (ubexp - UF_V_NM)) & M64; - ovf = 1; /* overflow */ - sticky = 0; /* no rounding */ - } -rndm = I_GETFRND (ir); /* get round mode */ -if (((rndm == I_FRND_N) && (sticky & Q_SIGN)) || /* nearest? */ - ((rndm == I_FRND_P) && !a.sign && sticky) || /* +inf and +? */ - ((rndm == I_FRND_M) && a.sign && sticky)) { /* -inf and -? */ - a.frac = (a.frac + 1) & M64; - if (a.frac == 0) ovf = 1; /* overflow? */ - if ((rndm == I_FRND_N) && (sticky == Q_SIGN)) /* round nearest hack */ - a.frac = a.frac & ~1; - } -if (a.frac > (a.sign? IMMAX: IPMAX)) ovf = 1; /* overflow? */ -if (ovf) ieee_trap (TRAP_IOV, ir & I_FTRP_V, 0, 0); /* overflow trap */ -if (ovf || sticky) /* ovflo or round? */ - ieee_trap (TRAP_INE, Q_SUI (ir), FPCR_INED, ir); -return (a.sign? NEG_Q (a.frac): a.frac); -} - -/* IEEE floating add - - - Take care of NaNs and infinites - - Test for zero (fast exit) - - Sticky logic for floating add - > If result normalized, sticky in right place - > If result carries out, renormalize, retain sticky - - Sticky logic for floating subtract - > If shift < guard, no sticky bits; 64b result is exact - If shift <= 1, result may require extensive normalization, - but there are no sticky bits to worry about - > If shift >= guard, there is a sticky bit, - but normalization is at most 1 place, sticky bit is retained - for rounding purposes (but not in low order bit) */ - -t_uint64 ieee_fadd (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 dp, t_bool sub) -{ -UFP a, b, t; -uint32 ftpa, ftpb; -uint32 sticky, rndm; -int32 ediff; - -ftpa = ieee_unpack (s1, &a, ir); /* unpack operands */ -ftpb = ieee_unpack (s2, &b, ir); -if (ftpb == UFT_NAN) return s2 | QNAN; /* B = NaN? quiet B */ -if (ftpa == UFT_NAN) return s1 | QNAN; /* A = NaN? quiet A */ -if (sub) b.sign = b.sign ^ 1; /* sign of B */ -if (ftpb == UFT_INF) { /* B = inf? */ - if ((ftpa == UFT_INF) && (a.sign ^ b.sign)) { /* eff sub of inf? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* inv op trap */ - return CQNAN; /* canonical NaN */ - } - return (sub? (s2 ^ FPR_SIGN): s2); /* return B */ - } -if (ftpa == UFT_INF) return s1; /* A = inf? ret A */ -rndm = I_GETFRND (ir); /* inst round mode */ -if (rndm == I_FRND_D) rndm = FPCR_GETFRND (fpcr); /* dynamic? use FPCR */ -if (ftpa == UFT_ZERO) { /* A = 0? */ - if (ftpb != UFT_ZERO) a = b; /* B != 0? result is B */ - else if (a.sign != b.sign) /* both 0, subtract? */ - a.sign = (rndm == I_FRND_M); /* +0 unless RM */ - } -else if (ftpb != UFT_ZERO) { /* s2 != 0? */ - if ((a.exp < b.exp) || /* s1 < s2? swap */ - ((a.exp == b.exp) && (a.frac < b.frac))) { - t = a; - a = b; - b = t; - } - ediff = a.exp - b.exp; /* exp diff */ - if (ediff > 63) b.frac = 1; /* >63? retain sticky */ - else if (ediff) { /* [1,63]? shift */ - sticky = ((b.frac << (64 - ediff)) & M64)? 1: 0; /* lost bits */ - b.frac = ((b.frac >> ediff) & M64) | sticky; - } - if (a.sign ^ b.sign) { /* eff sub? */ - a.frac = (a.frac - b.frac) & M64; /* subtract fractions */ - if (a.frac == 0) { /* result 0? */ - a.exp = 0; - a.sign = (rndm == I_FRND_M); /* +0 unless RM */ - } - else ieee_norm (&a); /* normalize */ - } - else { /* eff add */ - a.frac = (a.frac + b.frac) & M64; /* add frac */ - if (a.frac < b.frac) { /* chk for carry */ - a.frac = UF_NM | (a.frac >> 1) | /* shift in carry */ - (a.frac & 1); /* retain sticky */ - a.exp = a.exp + 1; /* skip norm */ - } - } - } /* end else if */ -return ieee_rpack (&a, ir, dp); /* round and pack */ -} - -/* IEEE floating multiply - - - Take care of NaNs and infinites - - Test for zero operands (fast exit) - - 64b x 64b fraction multiply, yielding 128b result - - Normalize (at most 1 bit) - - Insert "sticky" bit in low order fraction, for rounding - - Because IEEE fractions have a range of [1,2), the result can have a range - of [1,4). Results in the range of [1,2) appear to be denormalized by one - place, when in fact they are correct. Results in the range of [2,4) appear - to be in correct, when in fact they are 2X larger. This problem is taken - care of in the result exponent calculation. */ - -t_uint64 ieee_fmul (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 dp) -{ -UFP a, b; -uint32 ftpa, ftpb; -t_uint64 resl; - -ftpa = ieee_unpack (s1, &a, ir); /* unpack operands */ -ftpb = ieee_unpack (s2, &b, ir); -if (ftpb == UFT_NAN) return s2 | QNAN; /* B = NaN? quiet B */ -if (ftpa == UFT_NAN) return s1 | QNAN; /* A = NaN? quiet A */ -a.sign = a.sign ^ b.sign; /* sign of result */ -if ((ftpa == UFT_ZERO) || (ftpb == UFT_ZERO)) { /* zero operand? */ - if ((ftpa == UFT_INF) || (ftpb == UFT_INF)) { /* 0 * inf? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* inv op trap */ - return CQNAN; /* canonical NaN */ - } - return (a.sign? FMZERO: FPZERO); /* return signed 0 */ - } -if (ftpb == UFT_INF) return (a.sign? FMINF: FPINF); /* B = inf? */ -if (ftpa == UFT_INF) return (a.sign? FMINF: FPINF); /* A = inf? */ -a.exp = a.exp + b.exp + 1 - T_BIAS; /* add exponents */ -resl = uemul64 (a.frac, b.frac, &a.frac); /* multiply fracs */ -ieee_norm (&a); /* normalize */ -a.frac = a.frac | (resl? 1: 0); /* sticky bit */ -return ieee_rpack (&a, ir, dp); /* round and pack */ -} - -/* Floating divide - - - Take care of NaNs and infinites - - Check for zero cases - - Divide fractions (55b to develop a rounding bit) - - Set sticky bit if remainder non-zero - - Because IEEE fractions have a range of [1,2), the result can have a range - of (.5,2). Results in the range of [1,2) are correct. Results in the - range of (.5,1) need to be normalized by one place. */ - -t_uint64 ieee_fdiv (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 dp) -{ -UFP a, b; -uint32 ftpa, ftpb, sticky; - -ftpa = ieee_unpack (s1, &a, ir); -ftpb = ieee_unpack (s2, &b, ir); -if (ftpb == UFT_NAN) return s2 | QNAN; /* B = NaN? quiet B */ -if (ftpa == UFT_NAN) return s1 | QNAN; /* A = NaN? quiet A */ -a.sign = a.sign ^ b.sign; /* sign of result */ -if (ftpb == UFT_INF) { /* B = inf? */ - if (ftpa == UFT_INF) { /* inf/inf? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* inv op trap */ - return CQNAN; /* canonical NaN */ - } - return (a.sign? FMZERO: FPZERO); /* !inf/inf, ret 0 */ - } -if (ftpa == UFT_INF) /* A = inf? */ - return (a.sign? FMINF: FPINF); /* return inf */ -if (ftpb == UFT_ZERO) { /* B = 0? */ - if (ftpa == UFT_ZERO) { /* 0/0? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* inv op trap */ - return CQNAN; /* canonical NaN */ - } - ieee_trap (TRAP_DZE, 1, FPCR_DZED, ir); /* div by 0 trap */ - return (a.sign? FMINF: FPINF); /* return inf */ - } -if (ftpa == UFT_ZERO) return (a.sign? FMZERO: FPZERO); /* A = 0? */ -a.exp = a.exp - b.exp + T_BIAS; /* unbiased exp */ -a.frac = a.frac >> 1; /* allow 1 bit left */ -b.frac = b.frac >> 1; -a.frac = ufdiv64 (a.frac, b.frac, 55, &sticky); /* divide */ -ieee_norm (&a); /* normalize */ -a.frac = a.frac | sticky; /* insert sticky */ -return ieee_rpack (&a, ir, dp); /* round and pack */ -} - -/* IEEE floating square root - - - Take care of NaNs, +infinite, zero - - Check for negative operand - - Compute result exponent - - Compute sqrt of fraction */ - -t_uint64 ieee_sqrt (uint32 ir, uint32 dp) -{ -t_uint64 op; -uint32 ftpb; -UFP b; - -op = FR[I_GETRB (ir)]; /* get F[rb] */ -ftpb = ieee_unpack (op, &b, ir); /* unpack */ -if (ftpb == UFT_NAN) return op | QNAN; /* NaN? */ -if ((ftpb == UFT_ZERO) || /* zero? */ - ((ftpb == UFT_INF) && !b.sign)) return op; /* +infinity? */ -if (b.sign) { /* minus? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* signal inv op */ - return CQNAN; - } -b.exp = ((b.exp - T_BIAS) >> 1) + T_BIAS - 1; /* result exponent */ -b.frac = fsqrt64 (b.frac, b.exp); /* result fraction */ -return ieee_rpack (&b, ir, dp); /* round and pack */ -} - -/* Support routines */ - -t_bool ieee_unpack (t_uint64 op, UFP *r, uint32 ir) -{ -r->sign = FPR_GETSIGN (op); /* get sign */ -r->exp = FPR_GETEXP (op); /* get exponent */ -r->frac = FPR_GETFRAC (op); /* get fraction */ -if (r->exp == 0) { /* exponent = 0? */ - if (r->frac == 0) return UFT_ZERO; /* frac = 0? then true 0 */ - if (fpcr & FPCR_DNZ) { /* denorms to 0? */ - r->frac = 0; /* clear fraction */ - return UFT_ZERO; - } - r->frac = r->frac << FPR_GUARD; /* guard fraction */ - ieee_norm (r); /* normalize dnorm */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* signal inv op */ - return UFT_DENORM; - } -if (r->exp == FPR_NAN) { /* exponent = max? */ - if (r->frac == 0) return UFT_INF; /* frac = 0? then inf */ - if (!(r->frac & QNAN)) /* signaling NaN? */ - ieee_trap (TRAP_INV, 1, FPCR_INVD, ir); /* signal inv op */ - return UFT_NAN; - } -r->frac = (r->frac | FPR_HB) << FPR_GUARD; /* ins hidden bit, guard */ -return UFT_FIN; /* finite */ -} - -/* Normalize - input must be zero, finite, or denorm */ - -void ieee_norm (UFP *r) -{ -int32 i; -static t_uint64 normmask[5] = { - 0xc000000000000000, 0xf000000000000000, 0xff00000000000000, - 0xffff000000000000, 0xffffffff00000000 - }; -static int32 normtab[6] = { 1, 2, 4, 8, 16, 32 }; - -r->frac = r->frac & M64; -if (r->frac == 0) { /* if fraction = 0 */ - r->sign = 0; - r->exp = 0; /* result is 0 */ - return; - } -while ((r->frac & UF_NM) == 0) { /* normalized? */ - for (i = 0; i < 5; i++) { /* find first 1 */ - if (r->frac & normmask[i]) break; - } - r->frac = r->frac << normtab[i]; /* shift frac */ - r->exp = r->exp - normtab[i]; /* decr exp */ - } -return; -} - -/* Round and pack - - Much of the treachery of the IEEE standard is buried here - - Rounding modes (chopped, +infinity, nearest, -infinity) - - Inexact (set if there are any rounding bits, regardless of rounding) - - Overflow (result is infinite if rounded, max if not) - - Underflow (no denorms!) - - Underflow handling is particularly complicated - - Result is always 0 - - UNF and INE are always set in FPCR - - If /U is set, - o If /S is clear, trap - o If /S is set, UNFD is set, but UNFZ is clear, ignore UNFD and - trap, because the hardware cannot produce denormals - o If /S is set, UNFD is set, and UNFZ is set, do not trap - - If /SUI is set, and INED is clear, trap */ - -t_uint64 ieee_rpack (UFP *r, uint32 ir, uint32 dp) -{ -static const t_uint64 stdrnd[2] = { UF_SRND, UF_TRND }; -static const t_uint64 infrnd[2] = { UF_SINF, UF_TINF }; -static const int32 expmax[2] = { T_BIAS - S_BIAS + S_M_EXP - 1, T_M_EXP - 1 }; -static const int32 expmin[2] = { T_BIAS - S_BIAS, 0 }; -t_uint64 rndadd, rndbits, res; -uint32 rndm; - -if (r->frac == 0) /* result 0? */ - return ((t_uint64) r->sign << FPR_V_SIGN); -rndm = I_GETFRND (ir); /* inst round mode */ -if (rndm == I_FRND_D) rndm = FPCR_GETFRND (fpcr); /* dynamic? use FPCR */ -rndbits = r->frac & infrnd[dp]; /* isolate round bits */ -if (rndm == I_FRND_N) rndadd = stdrnd[dp]; /* round to nearest? */ -else if (((rndm == I_FRND_P) && !r->sign) || /* round to inf and */ - ((rndm == I_FRND_M) && r->sign)) /* right sign? */ - rndadd = infrnd[dp]; -else rndadd = 0; -r->frac = (r->frac + rndadd) & M64; /* round */ -if ((r->frac & UF_NM) == 0) { /* carry out? */ - r->frac = (r->frac >> 1) | UF_NM; /* renormalize */ - r->exp = r->exp + 1; - } -if (rndbits) /* inexact? */ - ieee_trap (TRAP_INE, Q_SUI (ir), FPCR_INED, ir); /* set inexact */ -if (r->exp > expmax[dp]) { /* ovflo? */ - ieee_trap (TRAP_OVF, 1, FPCR_OVFD, ir); /* set overflow trap */ - ieee_trap (TRAP_INE, Q_SUI (ir), FPCR_INED, ir); /* set inexact */ - if (rndadd) /* did we round? */ - return (r->sign? FMINF: FPINF); /* return infinity */ - return (r->sign? FMMAX: FPMAX); /* no, return max */ - } -if (r->exp <= expmin[dp]) { /* underflow? */ - ieee_trap (TRAP_UNF, ir & I_FTRP_U, /* set underflow trap */ - (fpcr & FPCR_UNDZ)? FPCR_UNFD: 0, ir); /* (dsbl only if UNFZ set) */ - ieee_trap (TRAP_INE, Q_SUI (ir), FPCR_INED, ir); /* set inexact */ - return 0; /* underflow to +0 */ - } -res = (((t_uint64) r->sign) << FPR_V_SIGN) | /* form result */ - (((t_uint64) r->exp) << FPR_V_EXP) | - ((r->frac >> FPR_GUARD) & FPR_FRAC); -if ((rndm == I_FRND_N) && (rndbits == stdrnd[dp])) /* nearest and halfway? */ - res = res & ~1; /* clear lo bit */ -return res; -} - -/* IEEE arithmetic trap - only one can be set at a time! */ - -void ieee_trap (uint32 trap, uint32 instenb, uint32 fpcrdsb, uint32 ir) -{ -fpcr = fpcr | (trap << 19); /* FPCR to trap summ offset */ -if ((instenb == 0) || /* not enabled in inst? ignore */ - ((ir & I_FTRP_S) && (fpcr & fpcrdsb))) return; /* /S and disabled? ignore */ -arith_trap (trap, ir); /* set Alpha trap */ -return; -} - -/* Fraction square root routine - code from SoftFloat */ - -t_uint64 fsqrt64 (t_uint64 asig, int32 exp) -{ -t_uint64 zsig, remh, reml, t; -uint32 sticky = 0; - -zsig = estimateSqrt32 (exp, (uint32) (asig >> 32)); - -/* Calculate the final answer in two steps. First, do one iteration of - Newton's approximation. The divide-by-2 is accomplished by clever - positioning of the operands. Then, check the bits just below the - (double precision) rounding bit to see if they are close to zero - (that is, the rounding bits are close to midpoint). If so, make - sure that the result^2 is the input operand */ - -asig = asig >> ((exp & 1)? 3: 2); /* leave 2b guard */ -zsig = estimateDiv128 (asig, 0, zsig << 32) + (zsig << 30 ); -if ((zsig & 0x1FF) <= 5) { /* close to even? */ - reml = uemul64 (zsig, zsig, &remh); /* result^2 */ - remh = asig - remh - (reml? 1:0); /* arg - result^2 */ - reml = NEG_Q (reml); - while (Q_GETSIGN (remh) != 0) { /* if arg < result^2 */ - zsig = zsig - 1; /* decr result */ - t = (zsig << 1) | 1; /* incr result^2 */ - reml = reml + t; /* and retest */ - remh = remh + (zsig >> 63) + ((reml < t)? 1: 0); - } - if ((remh | reml) != 0 ) sticky = 1; /* not exact? */ - } -return zsig; -} - -/* Estimate 32b SQRT - - Calculate an approximation to the square root of the 32-bit significand given - by 'a'. Considered as an integer, 'a' must be at least 2^31. If bit 0 of - 'exp' (the least significant bit) is 1, the integer returned approximates - 2^31*sqrt('a'/2^31), where 'a' is considered an integer. If bit 0 of 'exp' - is 0, the integer returned approximates 2^31*sqrt('a'/2^30). In either - case, the approximation returned lies strictly within +/-2 of the exact - value. */ - -uint32 estimateSqrt32 (uint32 exp, uint32 a) -{ -uint32 index, z; -static const uint32 sqrtOdd[] = { - 0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0, - 0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67 - }; -static const uint32 sqrtEven[] = { - 0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E, - 0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002 - }; - -index = (a >> 27) & 0xF; /* bits<30:27> */ -if (exp & 1) { /* odd exp? */ - z = 0x4000 + (a >> 17) - sqrtOdd[index]; /* initial guess */ - z = ((a / z) << 14) + (z << 15); /* Newton iteration */ - a = a >> 1; - } -else { - z = 0x8000 + (a >> 17) - sqrtEven[index]; /* initial guess */ - z = (a / z) + z; /* Newton iteration */ - z = (z >= 0x20000) ? 0xFFFF8000: (z << 15); - if (z <= a) z = (a >> 1) | 0x80000000; - } -return (uint32) ((((((t_uint64) a) << 31) / ((t_uint64) z)) + (z >> 1)) & M32); -} - -/* Estimate 128b unsigned divide */ - -t_uint64 estimateDiv128 (t_uint64 a0, t_uint64 a1, t_uint64 b) -{ -t_uint64 b0, b1; -t_uint64 rem0, rem1, term0, term1; -t_uint64 z; - -if (b <= a0) return 0xFFFFFFFFFFFFFFFF; -b0 = b >> 32; -z = ((b0 << 32) <= a0)? 0xFFFFFFFF00000000: ((a0 / b0) << 32); -term1 = uemul64 (b, z, &term0); -rem0 = a0 - term0 - (a1 < term1); -rem1 = a1 - term1; -while (Q_GETSIGN (rem0)) { - z = z - ((t_uint64) 0x100000000); - b1 = b << 32; - rem1 = b1 + rem1; - rem0 = b0 + rem0 + (rem1 < b1); - } -rem0 = (rem0 << 32) | (rem1 >> 32); -z |= (((b0 << 32) <= rem0)? 0xFFFFFFFF : (rem0 / b0)); -return z; -} diff --git a/alpha/alpha_fpv.c b/alpha/alpha_fpv.c deleted file mode 100644 index 67fca723..00000000 --- a/alpha/alpha_fpv.c +++ /dev/null @@ -1,457 +0,0 @@ -/* alpha_fpv.c - Alpha VAX floating point simulator - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - This module contains the instruction simulators for - - - single precision floating point, F - - double precision floating point, G -*/ - -#include "alpha_defs.h" - -#define IPMAX 0x7FFFFFFFFFFFFFFF /* plus MAX (int) */ -#define IMMAX 0x8000000000000000 /* minus MAX (int) */ - -/* Unpacked rounding constants */ - -#define UF_FRND 0x0000008000000000 /* F round */ -#define UF_DRND 0x0000000000000080 /* D round */ -#define UF_GRND 0x0000000000000400 /* G round */ - -extern t_uint64 FR[32]; -extern jmp_buf save_env; - -t_bool vax_unpack (t_uint64 op, UFP *a, uint32 ir); -t_bool vax_unpack_d (t_uint64 op, UFP *a, uint32 ir); -void vax_norm (UFP *a); -t_uint64 vax_rpack (UFP *a, uint32 ir, uint32 dp); -t_uint64 vax_rpack_d (UFP *a, uint32 ir); -int32 vax_fcmp (t_uint64 a, t_uint64 b, uint32 ir); -t_uint64 vax_cvtif (t_uint64 val, uint32 ir, uint32 dp); -t_uint64 vax_cvtfi (t_uint64 op, uint32 ir); -t_uint64 vax_fadd (t_uint64 a, t_uint64 b, uint32 ir, uint32 dp, t_bool sub); -t_uint64 vax_fmul (t_uint64 a, t_uint64 b, uint32 ir, uint32 dp); -t_uint64 vax_fdiv (t_uint64 a, t_uint64 b, uint32 ir, uint32 dp); - -extern t_uint64 uemul64 (t_uint64 a, t_uint64 b, t_uint64 *hi); -extern t_uint64 ufdiv64 (t_uint64 dvd, t_uint64 dvr, uint32 prec, uint32 *sticky); -extern t_uint64 fsqrt64 (t_uint64 frac, int32 exp); - -/* VAX floating point loads and stores */ - -t_uint64 op_ldf (t_uint64 op) -{ -uint32 exp = F_GETEXP (op); - -if (exp != 0) exp = exp + G_BIAS - F_BIAS; /* zero? */ -return (((t_uint64) (op & F_SIGN))? FPR_SIGN: 0) | /* finite non-zero */ - (((t_uint64) exp) << FPR_V_EXP) | - (((t_uint64) SWAP_VAXF (op & ~(F_SIGN|F_EXP))) << F_V_FRAC); -} - -t_uint64 op_ldg (t_uint64 op) -{ -return SWAP_VAXG (op); /* swizzle bits */ -} - -t_uint64 op_stf (t_uint64 op) -{ -uint32 sign = FPR_GETSIGN (op)? F_SIGN: 0; -uint32 frac = (uint32) (op >> F_V_FRAC); -uint32 exp = FPR_GETEXP (op); - -if (exp != 0) exp = exp + F_BIAS - G_BIAS; /* zero? */ -exp = (exp & F_M_EXP) << F_V_EXP; -return (t_uint64) (sign | exp | (SWAP_VAXF (frac) & ~(F_SIGN|F_EXP))); -} - -t_uint64 op_stg (t_uint64 op) -{ -return SWAP_VAXG (op); /* swizzle bits */ -} - -/* VAX floating point operate */ - -void vax_fop (uint32 ir) -{ -UFP b; -t_uint64 res; -uint32 fnc, ra, rb, rc; - -fnc = I_GETFFNC (ir); /* get function */ -ra = I_GETRA (ir); /* get registers */ -rb = I_GETRB (ir); -rc = I_GETRC (ir); -switch (fnc) { /* case on func */ - - case 0x00: /* ADDF */ - res = vax_fadd (FR[ra], FR[rb], ir, DT_F, 0); - break; - - case 0x01: /* SUBF */ - res = vax_fadd (FR[ra], FR[rb], ir, DT_F, 1); - break; - - case 0x02: /* MULF */ - res = vax_fmul (FR[ra], FR[rb], ir, DT_F); - break; - - case 0x03: /* DIVF */ - res = vax_fdiv (FR[ra], FR[rb], ir, DT_F); - break; - - case 0x20: /* ADDG */ - res = vax_fadd (FR[ra], FR[rb], ir, DT_G, 0); - break; - - case 0x21: /* SUBG */ - res = vax_fadd (FR[ra], FR[rb], ir, DT_G, 1); - break; - - case 0x22: /* MULG */ - res = vax_fmul (FR[ra], FR[rb], ir, DT_G); - break; - - case 0x23: /* DIVG */ - res = vax_fdiv (FR[ra], FR[rb], ir, DT_G); - break; - - case 0x25: /* CMPGEQ */ - if (vax_fcmp (FR[ra], FR[rb], ir) == 0) res = FP_TRUE; - else res = 0; - break; - - case 0x26: /* CMPGLT */ - if (vax_fcmp (FR[ra], FR[rb], ir) < 0) res = FP_TRUE; - else res = 0; - break; - - case 0x27: /* CMPGLE */ - if (vax_fcmp (FR[ra], FR[rb], ir) <= 0) res = FP_TRUE; - else res = 0; - break; - - case 0x1E: /* CVTDG */ - if (vax_unpack_d (FR[rb], &b, ir)) res = 0; - else res = vax_rpack (&b, ir, DT_G); - break; - - case 0x2C: /* CVTGF */ - if (vax_unpack (FR[rb], &b, ir)) res = 0; - else res = vax_rpack (&b, ir, DT_F); - break; - - case 0x2D: /* CVTGD */ - if (vax_unpack (FR[rb], &b, ir)) res = 0; - else res = vax_rpack_d (&b, ir); - break; - - case 0x2F: /* CVTGQ */ - res = vax_cvtfi (FR[rb], ir); - break; - - case 0x3C: /* CVTQF */ - res = vax_cvtif (FR[rb], ir, DT_F); - break; - - case 0x3E: /* CVTQG */ - res = vax_cvtif (FR[rb], ir, DT_G); - break; - - default: - res = FR[rc]; - break; - } - -if (rc != 31) FR[rc] = res & M64; -return; -} - -/* VAX floating compare */ - -int32 vax_fcmp (t_uint64 s1, t_uint64 s2, uint32 ir) -{ -UFP a, b; - -if (vax_unpack (s1, &a, ir)) return +1; /* unpack, rsv? */ -if (vax_unpack (s2, &b, ir)) return +1; /* unpack, rsv? */ -if (s1 == s2) return 0; /* equal? */ -if (a.sign != b.sign) return (a.sign? -1: +1); /* opp signs? */ -return (((s1 < s2) ^ a.sign)? -1: +1); /* like signs */ -} - -/* VAX integer to floating convert */ - -t_uint64 vax_cvtif (t_uint64 val, uint32 ir, uint32 dp) -{ -UFP a; - -if (val == 0) return 0; /* 0? return +0 */ -if (val < 0) { /* < 0? */ - a.sign = 1; /* set sign */ - val = NEG_Q (val); /* |val| */ - } -else a.sign = 0; -a.exp = 64 + G_BIAS; /* set exp */ -a.frac = val; /* set frac */ -vax_norm (&a); /* normalize */ -return vax_rpack (&a, ir, dp); /* round and pack */ -} - -/* VAX floating to integer convert - note that rounding cannot cause a - carry unless the fraction has been shifted right at least FP_GUARD - places; in which case a carry out is impossible */ - -t_uint64 vax_cvtfi (t_uint64 op, uint32 ir) -{ -UFP a; -uint32 rndm = I_GETFRND (ir); -int32 ubexp; - -if (vax_unpack (op, &a, ir)) return 0; /* unpack, rsv? */ -ubexp = a.exp - G_BIAS; /* unbiased exp */ -if (ubexp < 0) return 0; /* zero or too small? */ -if (ubexp <= UF_V_NM) { /* in range? */ - a.frac = a.frac >> (UF_V_NM - ubexp); /* leave rnd bit */ - if (rndm) a.frac = a.frac + 1; /* not chopped, round */ - a.frac = a.frac >> 1; /* now justified */ - if ((a.frac > (a.sign? IMMAX: IPMAX)) && /* out of range? */ - (ir & I_FTRP_V)) /* trap enabled? */ - arith_trap (TRAP_IOV, ir); /* set overflow */ - } -else { - if (ubexp > (UF_V_NM + 64)) a.frac = 0; /* out of range */ - else a.frac = (a.frac << (ubexp - UF_V_NM - 1)) & M64; /* no rnd bit */ - if (ir & I_FTRP_V) /* trap enabled? */ - arith_trap (TRAP_IOV, ir); /* set overflow */ - } -return (a.sign? NEG_Q (a.frac): a.frac); -} - -/* VAX floating add */ - -t_uint64 vax_fadd (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 dp, t_bool sub) -{ -UFP a, b, t; -uint32 sticky; -int32 ediff; - -if (vax_unpack (s1, &a, ir)) return 0; /* unpack, rsv? */ -if (vax_unpack (s2, &b, ir)) return 0; /* unpack, rsv? */ -if (sub) b.sign = b.sign ^ 1; /* sub? invert b sign */ -if (a.exp == 0) a = b; /* s1 = 0? */ -else if (b.exp) { /* s2 != 0? */ - if ((a.exp < b.exp) || /* |s1| < |s2|? swap */ - ((a.exp == b.exp) && (a.frac < b.frac))) { - t = a; - a = b; - b = t; - } - ediff = a.exp - b.exp; /* exp diff */ - if (a.sign ^ b.sign) { /* eff sub? */ - if (ediff > 63) b.frac = 1; /* >63? retain sticky */ - else if (ediff) { /* [1,63]? shift */ - sticky = ((b.frac << (64 - ediff)) & M64)? 1: 0; /* lost bits */ - b.frac = (b.frac >> ediff) | sticky; - } - a.frac = (a.frac - b.frac) & M64; /* subtract fractions */ - vax_norm (&a); /* normalize */ - } - else { /* eff add */ - if (ediff > 63) b.frac = 0; /* >63? b disappears */ - else if (ediff) b.frac = b.frac >> ediff; /* denormalize */ - a.frac = (a.frac + b.frac) & M64; /* add frac */ - if (a.frac < b.frac) { /* chk for carry */ - a.frac = UF_NM | (a.frac >> 1); /* shift in carry */ - a.exp = a.exp + 1; /* skip norm */ - } - } - } /* end else if */ -return vax_rpack (&a, ir, dp); /* round and pack */ -} - -/* VAX floating multiply */ - -t_uint64 vax_fmul (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 dp) -{ -UFP a, b; - -if (vax_unpack (s1, &a, ir)) return 0; /* unpack, rsv? */ -if (vax_unpack (s2, &b, ir)) return 0; /* unpack, rsv? */ -if ((a.exp == 0) || (b.exp == 0)) return 0; /* zero argument? */ -a.sign = a.sign ^ b.sign; /* sign of result */ -a.exp = a.exp + b.exp - G_BIAS; /* add exponents */ -uemul64 (a.frac, b.frac, &a.frac); /* mpy fractions */ -vax_norm (&a); /* normalize */ -return vax_rpack (&a, ir, dp); /* round and pack */ -} - -/* VAX floating divide - Needs to develop at least one rounding bit. Since the first - divide step can fail, develop 2 more bits than the precision of - the fraction. */ - -t_uint64 vax_fdiv (t_uint64 s1, t_uint64 s2, uint32 ir, uint32 dp) -{ -UFP a, b; - -if (vax_unpack (s1, &a, ir)) return 0; /* unpack, rsv? */ -if (vax_unpack (s2, &b, ir)) return 0; /* unpack, rsv? */ -if (b.exp == 0) { /* divr = 0? */ - arith_trap (TRAP_DZE, ir); /* dze trap */ - return 0; - } -if (a.exp == 0) return 0; /* divd = 0? */ -a.sign = a.sign ^ b.sign; /* result sign */ -a.exp = a.exp - b.exp + G_BIAS + 1; /* unbiased exp */ -a.frac = a.frac >> 1; /* allow 1 bit left */ -b.frac = b.frac >> 1; -a.frac = ufdiv64 (a.frac, b.frac, 55, NULL); /* divide */ -vax_norm (&a); /* normalize */ -return vax_rpack (&a, ir, dp); /* round and pack */ -} - -/* VAX floating square root */ - -t_uint64 vax_sqrt (uint32 ir, uint32 dp) -{ -t_uint64 op; -UFP b; - -op = FR[I_GETRB (ir)]; /* get F[rb] */ -if (vax_unpack (op, &b, ir)) return 0; /* unpack, rsv? */ -if (b.exp == 0) return 0; /* zero? */ -if (b.sign) { /* minus? */ - arith_trap (TRAP_INV, ir); /* invalid operand */ - return 0; - } -b.exp = ((b.exp + 1 - G_BIAS) >> 1) + G_BIAS; /* result exponent */ -b.frac = fsqrt64 (b.frac, b.exp); /* result fraction */ -return vax_rpack (&b, ir, dp); /* round and pack */ -} - -/* Support routines */ - -t_bool vax_unpack (t_uint64 op, UFP *r, uint32 ir) -{ -r->sign = FPR_GETSIGN (op); /* get sign */ -r->exp = FPR_GETEXP (op); /* get exponent */ -r->frac = FPR_GETFRAC (op); /* get fraction */ -if (r->exp == 0) { /* exp = 0? */ - if (op != 0) arith_trap (TRAP_INV, ir); /* rsvd op? */ - r->frac = r->sign = 0; - return TRUE; - } -r->frac = (r->frac | FPR_HB) << FPR_GUARD; /* ins hidden bit, guard */ -return FALSE; -} - -t_bool vax_unpack_d (t_uint64 op, UFP *r, uint32 ir) -{ -r->sign = FDR_GETSIGN (op); /* get sign */ -r->exp = FDR_GETEXP (op); /* get exponent */ -r->frac = FDR_GETFRAC (op); /* get fraction */ -if (r->exp == 0) { /* exp = 0? */ - if (op != 0) arith_trap (TRAP_INV, ir); /* rsvd op? */ - r->frac = r->sign = 0; - return TRUE; - } -r->exp = r->exp + G_BIAS - D_BIAS; /* change to G bias */ -r->frac = (r->frac | FDR_HB) << FDR_GUARD; /* ins hidden bit, guard */ -return FALSE; -} - -/* VAX normalize */ - -void vax_norm (UFP *r) -{ -int32 i; -static t_uint64 normmask[5] = { - 0xc000000000000000, 0xf000000000000000, 0xff00000000000000, - 0xffff000000000000, 0xffffffff00000000 - }; -static int32 normtab[6] = { 1, 2, 4, 8, 16, 32 }; - -r->frac = r->frac & M64; -if (r->frac == 0) { /* if fraction = 0 */ - r->sign = r->exp = 0; /* result is 0 */ - return; - } -while ((r->frac & UF_NM) == 0) { /* normalized? */ - for (i = 0; i < 5; i++) { /* find first 1 */ - if (r->frac & normmask[i]) break; - } - r->frac = r->frac << normtab[i]; /* shift frac */ - r->exp = r->exp - normtab[i]; /* decr exp */ - } -return; -} - -/* VAX round and pack */ - -t_uint64 vax_rpack (UFP *r, uint32 ir, uint32 dp) -{ -uint32 rndm = I_GETFRND (ir); -static const t_uint64 roundbit[2] = { UF_FRND, UF_GRND }; -static const int32 expmax[2] = { G_BIAS - F_BIAS + F_M_EXP, G_M_EXP }; -static const int32 expmin[2] = { G_BIAS - F_BIAS, 0 }; - -if (r->frac == 0) return 0; /* result 0? */ -if (rndm) { /* round? */ - r->frac = (r->frac + roundbit[dp]) & M64; /* add round bit */ - if ((r->frac & UF_NM) == 0) { /* carry out? */ - r->frac = (r->frac >> 1) | UF_NM; /* renormalize */ - r->exp = r->exp + 1; - } - } -if (r->exp > expmax[dp]) { /* ovflo? */ - arith_trap (TRAP_OVF, ir); /* set trap */ - r->exp = expmax[dp]; /* return max */ - } -if (r->exp <= expmin[dp]) { /* underflow? */ - if (ir & I_FTRP_V) arith_trap (TRAP_UNF, ir); /* enabled? set trap */ - return 0; /* underflow to 0 */ - } -return (((t_uint64) r->sign) << FPR_V_SIGN) | - (((t_uint64) r->exp) << FPR_V_EXP) | - ((r->frac >> FPR_GUARD) & FPR_FRAC); -} - -t_uint64 vax_rpack_d (UFP *r, uint32 ir) -{ -if (r->frac == 0) return 0; /* result 0? */ -r->exp = r->exp + D_BIAS - G_BIAS; /* rebias */ -if (r->exp > FDR_M_EXP) { /* ovflo? */ - arith_trap (TRAP_OVF, ir); /* set trap */ - r->exp = FDR_M_EXP; /* return max */ - } -if (r->exp <= 0) { /* underflow? */ - if (ir & I_FTRP_V) arith_trap (TRAP_UNF, ir); /* enabled? set trap */ - return 0; /* underflow to 0 */ - } -return (((t_uint64) r->sign) << FDR_V_SIGN) | - (((t_uint64) r->exp) << FDR_V_EXP) | - ((r->frac >> FDR_GUARD) & FDR_FRAC); -} diff --git a/alpha/alpha_io.c b/alpha/alpha_io.c deleted file mode 100644 index aa021d41..00000000 --- a/alpha/alpha_io.c +++ /dev/null @@ -1,214 +0,0 @@ -/* alpha_io.c: Alpha I/O and miscellaneous devices - - Copyright (c) 2006, Robert M. Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - rom boot ROM -*/ - -#include "alpha_defs.h" -#include "alpha_sys_defs.h" - -t_uint64 *rom = NULL; /* boot ROM */ - -extern DEVICE *sim_devices[]; - -t_bool rom_rd (t_uint64 pa, t_uint64 *val, uint32 lnt); -t_bool rom_wr (t_uint64 pa, t_uint64 val, uint32 lnt); -t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw); -t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw); -t_stat rom_reset (DEVICE *dptr); - -/* ROM data structures - - rom_dev ROM device descriptor - rom_unit ROM units - rom_reg ROM register list -*/ - -DIB rom_dib = { - ROMBASE, ROMBASE + ROMSIZE, &rom_rd, &rom_wr, 0 - }; - -UNIT rom_unit = { - UDATA (NULL, UNIT_FIX+UNIT_BINK, ROMSIZE) - }; - -REG rom_reg[] = { - { NULL } - }; - -DEVICE rom_dev = { - "ROM", &rom_unit, rom_reg, NULL, - 1, 16, 24, 8, 16, 64, - &rom_ex, &rom_dep, &rom_reset, - NULL, NULL, NULL, - &rom_dib, DEV_DIB - }; - -/* ReadIO - read IO space - - Inputs: - pa = physical address - *dat = pointer to data - lnt = length (BWLQ) - Output: - TRUE if read succeeds, else FALSE -*/ - -t_bool ReadIO (t_uint64 pa, t_uint64 *dat, uint32 lnt) -{ -DEVICE *dptr; -uint32 i; - -for (i = 0; sim_devices[i] != NULL; i++) { - dptr = sim_devices[i]; - if (dptr->flags & DEV_DIB) { - DIB *dibp = (DIB *) dptr->ctxt; - if ((pa >= dibp->low) && (pa < dibp->high)) - return dibp->read (pa, dat, lnt); - } - } -return FALSE; -} - -/* WriteIO - write register space - - Inputs: - ctx = CPU context - pa = physical address - val = data to write, right justified in 64b quadword - lnt = length (BWLQ) - Output: - TRUE if write succeeds, else FALSE -*/ - -t_bool WriteIO (t_uint64 pa, t_uint64 dat, uint32 lnt) -{ -DEVICE *dptr; -uint32 i; - -for (i = 0; sim_devices[i] != NULL; i++) { - dptr = sim_devices[i]; - if (dptr->flags & DEV_DIB) { - DIB *dibp = (DIB *) dptr->ctxt; - if ((pa >= dibp->low) && (pa < dibp->high)) - return dibp->write (pa, dat, lnt); - } - } -return FALSE; -} - -/* Boot ROM read */ - -t_bool rom_rd (t_uint64 pa, t_uint64 *val, uint32 lnt) -{ -uint32 sc, rg = ((uint32) ((pa - ROMBASE) & (ROMSIZE - 1))) >> 3; - -switch (lnt) { - - case L_BYTE: - sc = (((uint32) pa) & 7) * 8; - *val = (rom[rg] >> sc) & M8; - break; - - case L_WORD: - sc = (((uint32) pa) & 6) * 8; - *val = (rom[rg] >> sc) & M16; - break; - - case L_LONG: - if (pa & 4) *val = (rom[rg] >> 32) & M32; - else *val = rom[rg] & M32; - break; - - case L_QUAD: - *val = rom[rg]; - break; - } - -return TRUE; -} - -/* Boot ROM write */ - -t_bool rom_wr (t_uint64 pa, t_uint64 val, uint32 lnt) -{ -uint32 sc, rg = ((uint32) ((pa - ROMBASE) & (ROMSIZE - 1))) >> 3; - -switch (lnt) { - - case L_BYTE: - sc = (((uint32) pa) & 7) * 8; - rom[rg] = (rom[rg] & ~(((t_uint64) M8) << sc)) | (((t_uint64) (val & M8)) << sc); - break; - - case L_WORD: - sc = (((uint32) pa) & 6) * 8; - rom[rg] = (rom[rg] & ~(((t_uint64) M16) << sc)) | (((t_uint64) (val & M16)) << sc); - break; - - case L_LONG: - if (pa & 4) rom[rg] = ((t_uint64) (rom[rg] & M32)) | (((t_uint64) (val & M32)) << 32); - else rom[rg] = (rom[rg] & ~((t_uint64) M32)) | ((t_uint64) val & M32); - break; - - case L_QUAD: - rom[rg] = val; - break; - } - -return TRUE; -} - -/* ROM examine */ - -t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw) -{ -uint32 addr = (uint32) exta; - -if (vptr == NULL) return SCPE_ARG; -if (addr >= ROMSIZE) return SCPE_NXM; -*vptr = rom[addr >> 3]; -return SCPE_OK; -} - -/* ROM deposit */ - -t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw) -{ -uint32 addr = (uint32) exta; - -if (addr >= ROMSIZE) return SCPE_NXM; -rom[addr >> 3] = val; -return SCPE_OK; -} - -/* ROM reset */ - -t_stat rom_reset (DEVICE *dptr) -{ -if (rom == NULL) rom = (t_uint64 *) calloc (ROMSIZE >> 3, sizeof (t_uint64)); -if (rom == NULL) return SCPE_MEM; -return SCPE_OK; -} diff --git a/alpha/alpha_mmu.c b/alpha/alpha_mmu.c deleted file mode 100644 index 8d000b09..00000000 --- a/alpha/alpha_mmu.c +++ /dev/null @@ -1,308 +0,0 @@ -/* alpha_mmu.c - Alpha memory management simulator - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - This module contains the routines for - - ReadB,W,L,Q - read aligned virtual - ReadAccL,Q - read aligned virtual, special access check - ReadPB,W,L,Q - read aligned physical - WriteB,W,L,Q - write aligned virtual - WriteAccL,Q - write aligned virtual, special access check - WritePB,W,L,Q - write aligned physical - - The TLB is organized for optimum lookups and is broken up into three fields: - - tag VA<42:13> for an 8KB page system - pte PTE<31:0>, <31:16> are zero; FOE, FOR, FOW stored inverted - pfn PFN<31:0> left shifted by page size - - The inversion of FOE, FOR, FOW means that all checked bits must be one - for a reference to proceed. - - All Alpha implementations provide support for a 43b superpage for Unix, - and a 32b superpage for NT: - - 43b superpage 0xFFFFFC0000000000:0xFFFFFDFFFFFFFFFF - 32b superpage 0xFFFFFFFF80000000:0xFFFFFFFFBFFFFFFF -*/ - -#include "alpha_defs.h" - -extern t_uint64 trans_i (t_uint64 va); -extern t_uint64 trans_d (t_uint64 va, uint32 acc); - -extern t_uint64 *M; -extern t_uint64 p1; -extern uint32 pal_mode, dmapen; -extern uint32 cm_eacc, cm_racc, cm_wacc; -extern jmp_buf save_env; -extern UNIT cpu_unit; - -/* Read virtual aligned - - Inputs: - va = virtual address - Output: - returned data, right justified -*/ - -t_uint64 ReadB (t_uint64 va) -{ -t_uint64 pa; - -if (dmapen) pa = trans_d (va, cm_racc); /* mapping on? */ -else pa = va; -return ReadPB (pa); -} - -t_uint64 ReadW (t_uint64 va) -{ -t_uint64 pa; - -if (va & 1) ABORT1 (va, EXC_ALIGN); /* must be W aligned */ -if (dmapen) pa = trans_d (va, cm_racc); /* mapping on? */ -else pa = va; -return ReadPW (pa); -} - -t_uint64 ReadL (t_uint64 va) -{ -t_uint64 pa; - -if (va & 3) ABORT1 (va, EXC_ALIGN); /* must be L aligned */ -if (dmapen) pa = trans_d (va, cm_racc); /* mapping on? */ -else pa = va; -return ReadPL (pa); -} - -t_uint64 ReadQ (t_uint64 va) -{ -t_uint64 pa; - -if (va & 7) ABORT1 (va, EXC_ALIGN); /* must be Q aligned */ -if (dmapen) pa = trans_d (va, cm_racc); /* mapping on? */ -else pa = va; -return ReadPQ (pa); -} - -/* Read with generalized access controls - used by PALcode */ - -t_uint64 ReadAccL (t_uint64 va, uint32 acc) -{ -t_uint64 pa; - -if (va & 3) ABORT1 (va, EXC_ALIGN); /* must be L aligned */ -if (dmapen) pa = trans_d (va, acc); /* mapping on? */ -else pa = va; -return ReadPL (pa); -} - -t_uint64 ReadAccQ (t_uint64 va, uint32 acc) -{ -t_uint64 pa; - -if (va & 7) ABORT1 (va, EXC_ALIGN); /* must be Q aligned */ -if (dmapen) pa = trans_d (va, acc); /* mapping on? */ -else pa = va; -return ReadPQ (pa); -} - -/* Read instruction */ - -uint32 ReadI (t_uint64 va) -{ -t_uint64 pa; - -if (!pal_mode) pa = trans_i (va); /* mapping on? */ -else pa = va; -return (uint32) ReadPL (pa); -} - -/* Write virtual aligned - - Inputs: - va = virtual address - val = data to be written, right justified in 32b or 64b - Output: - none -*/ - -void WriteB (t_uint64 va, t_uint64 dat) -{ -t_uint64 pa; - -if (dmapen) pa = trans_d (va, cm_wacc); /* mapping on? */ -else pa = va; -WritePB (pa, dat); -return; -} - -void WriteW (t_uint64 va, t_uint64 dat) -{ -t_uint64 pa; - -if (va & 1) ABORT1 (va, EXC_ALIGN); /* must be W aligned */ -if (dmapen) pa = trans_d (va, cm_wacc); /* mapping on? */ -else pa = va; -WritePW (pa, dat); -return; -} - -void WriteL (t_uint64 va, t_uint64 dat) -{ -t_uint64 pa; - -if (va & 3) ABORT1 (va, EXC_ALIGN); /* must be L aligned */ -if (dmapen) pa = trans_d (va, cm_wacc); /* mapping on? */ -else pa = va; -WritePL (pa, dat); -return; -} - -void WriteQ (t_uint64 va, t_uint64 dat) -{ -t_uint64 pa; - -if (va & 7) ABORT1 (va, EXC_ALIGN); /* must be Q aligned */ -if (dmapen) pa = trans_d (va, cm_wacc); /* mapping on? */ -else pa = va; -WritePQ (pa, dat); -return; -} - -/* Write with generalized access controls - used by PALcode */ - -void WriteAccL (t_uint64 va, t_uint64 dat, uint32 acc) -{ -t_uint64 pa; - -if (va & 3) ABORT1 (va, EXC_ALIGN); /* must be L aligned */ -if (dmapen) pa = trans_d (va, acc); /* mapping on? */ -else pa = va; -WritePL (pa, dat); -return; -} - -void WriteAccQ (t_uint64 va, t_uint64 dat, uint32 acc) -{ -t_uint64 pa; - -if (va & 7) ABORT1 (va, EXC_ALIGN); /* must be Q aligned */ -if (dmapen) pa = trans_d (va, acc); /* mapping on? */ -else pa = va; -WritePQ (pa, dat); -return; -} - -/* Read and write physical aligned - access point to I/O */ - -INLINE t_uint64 ReadPB (t_uint64 pa) -{ -t_uint64 val; - -if (ADDR_IS_MEM (pa)) { - uint32 bo = ((uint32) pa) & 07; - return (((M[pa >> 3] >> (bo << 3))) & M8); - } -if (ReadIO (pa, &val, L_BYTE)) return val; -return 0; -} - -INLINE t_uint64 ReadPW (t_uint64 pa) -{ -t_uint64 val; - -if (ADDR_IS_MEM (pa)) { - uint32 bo = ((uint32) pa) & 06; - return (((M[pa >> 3] >> (bo << 3))) & M16); - } -if (ReadIO (pa, &val, L_WORD)) return val; -return 0; -} - -INLINE t_uint64 ReadPL (t_uint64 pa) -{ -t_uint64 val; - -if (ADDR_IS_MEM (pa)) { - if (pa & 4) return (((M[pa >> 3] >> 32)) & M32); - return ((M[pa >> 3]) & M32); - } -if (ReadIO (pa, &val, L_LONG)) return val; -return 0; -} - -INLINE t_uint64 ReadPQ (t_uint64 pa) -{ -t_uint64 val; - -if (ADDR_IS_MEM (pa)) return M[pa >> 3]; -if (ReadIO (pa, &val, L_QUAD)) return val; -return 0; -} - -INLINE void WritePB (t_uint64 pa, t_uint64 dat) -{ -dat = dat & M8; -if (ADDR_IS_MEM (pa)) { - uint32 bo = ((uint32) pa) & 07; - M[pa >> 3] = (M[pa >> 3] & ~(((t_uint64) M8) << (bo << 3))) | - (dat << (bo << 3)); - } -else WriteIO (pa, dat, L_BYTE); -return; -} - -INLINE void WritePW (t_uint64 pa, t_uint64 dat) -{ -dat = dat & M16; -if (ADDR_IS_MEM (pa)) { - uint32 bo = ((uint32) pa) & 07; - M[pa >> 3] = (M[pa >> 3] & ~(((t_uint64) M16) << (bo << 3))) | - (dat << (bo << 3)); - } -else WriteIO (pa, dat, L_WORD); -return; -} - -INLINE void WritePL (t_uint64 pa, t_uint64 dat) -{ -dat = dat & M32; -if (ADDR_IS_MEM (pa)) { - if (pa & 4) M[pa >> 3] = (M[pa >> 3] & M32) | - (dat << 32); - else M[pa >> 3] = (M[pa >> 3] & ~((t_uint64) M32)) | dat; - } -else WriteIO (pa, dat, L_LONG); -return; -} - -INLINE void WritePQ (t_uint64 pa, t_uint64 dat) -{ -if (ADDR_IS_MEM (pa)) M[pa >> 3] = dat; -else WriteIO (pa, dat, L_QUAD); -return; -} - diff --git a/alpha/alpha_sys.c b/alpha/alpha_sys.c deleted file mode 100644 index 630f9df5..00000000 --- a/alpha/alpha_sys.c +++ /dev/null @@ -1,814 +0,0 @@ -/* alpha_sys.c: Alpha simulator interface - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "alpha_defs.h" -#include - -extern UNIT cpu_unit; -extern REG cpu_reg[]; -extern int32 sim_switches; -extern uint32 pal_type; - -t_stat fprint_sym_m (FILE *of, t_addr addr, uint32 inst); -t_stat parse_sym_m (char *cptr, t_addr addr, t_value *inst); -int32 parse_reg (char *cptr); - -extern t_stat fprint_pal_hwre (FILE *of, uint32 inst); -extern t_stat parse_pal_hwre (char *cptr, t_value *inst); -extern t_bool rom_wr (t_uint64 pa, t_uint64 val, uint32 lnt); - -/* SCP data structures and interface routines - - sim_PC pointer to saved PC register descriptor - sim_emax number of words for examine - sim_stop_messages array of pointers to stop messages - sim_load binary loader -*/ - -REG *sim_PC = &cpu_reg[0]; - -int32 sim_emax = 1; - -const char *sim_stop_messages[] = { - "Unknown error", - "HALT instruction", - "Breakpoint", - "Unsupported PAL variation", - "Kernel stack not valid", - "Unknown abort code", - "Memory management error" - }; - -/* Binary loader - - The binary loader handles absolute system images, that is, system - images linked /SYSTEM. These are simply a byte stream, with no - origin or relocation information. - - -r load ROM - -o specify origin -*/ - -t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) -{ -t_stat r; -int32 i; -t_uint64 origin; - -if (flag) return SCPE_ARG; /* dump? */ -origin = 0; /* memory */ -if (sim_switches & SWMASK ('O')) { /* origin? */ - origin = get_uint (cptr, 16, 0xFFFFFFFF, &r); - if (r != SCPE_OK) return SCPE_ARG; - } - -while ((i = getc (fileref)) != EOF) { /* read byte stream */ - if (sim_switches & SWMASK ('R')) { /* ROM? */ - if (!rom_wr (origin, i, L_BYTE)) - return SCPE_NXM; - } - else if (ADDR_IS_MEM (origin)) /* valid memory? */ - WritePB (origin, i); - else return SCPE_NXM; - origin = origin + 1; - } -return SCPE_OK; -} - -/* Opcode mnemonics table */ - -#define CL_NO 0 /* no operand */ -#define CL_BR 1 /* branch */ -#define CL_MR 2 /* memory reference */ -#define CL_IO 3 /* integer opr */ -#define CL_FO 4 /* floating opr */ -#define CL_MO 5 /* memory opr */ -#define CL_JP 6 /* jump */ -#define CL_HW 7 /* hardware */ -#define CL_M_PAL 0x00F0 -#define CL_V_PAL 4 -#define CL_VMS (1u << (PAL_VMS + CL_V_PAL)) -#define CL_UNIX (1u << (PAL_UNIX + CL_V_PAL)) -#define CL_NT (1u << (PAL_NT + CL_V_PAL)) -#define FL_RA 0x0100 -#define FL_RB 0x0200 -#define FL_RC 0x0400 -#define FL_RBI 0x0800 -#define FL_MDP 0x1000 -#define FL_BDP 0x2000 -#define FL_JDP 0x4000 -#define FL_LIT 0x8000 -#define CL_CLASS 0x000F -#define PAL_MASK(x) (1u << (pal_type + CL_V_PAL)) - -#define C_NO CL_NO -#define C_PCM CL_NO | CL_VMS | CL_UNIX | CL_NT -#define C_PVM CL_NO | CL_VMS -#define C_PUN CL_NO | CL_UNIX -#define C_PNT CL_NO | CL_NT -#define C_BR CL_BR | FL_RA | FL_BDP -#define C_MR CL_MR | FL_RA | FL_RB | FL_RBI | FL_MDP -#define C_FE CL_MO | FL_RB | FL_RBI -#define C_RV CL_MO | FL_RA -#define C_MO CL_MO | FL_RA | FL_RB -#define C_IO CL_IO | FL_RA | FL_RB | FL_RC | FL_LIT -#define C_IAC CL_IO | FL_RA | FL_RC -#define C_IBC CL_IO | FL_RB | FL_RC | FL_LIT -#define C_FO CL_FO | FL_RA | FL_RB | FL_RC -#define C_FAC CL_FO | FL_RA | FL_RC -#define C_FBC CL_FO | FL_RB | FL_RC -#define C_JP CL_JP | FL_RA | FL_RB | FL_RBI | FL_JDP -#define C_HW CL_HW - -uint32 masks[8] = { - 0xFFFFFFFF, 0xFC000000, - 0xFC000000, 0xFC000FE0, - 0xFC00FFE0, 0xFC00FFFF, - 0xFC00C000, 0xFC000000 - }; - -const char *opcode[] = { - "HALT", "DRAINA", "CFLUSH", "LDQP", /* VMS PALcode */ - "STQP", "SWPCTX", "MFPR_ASN", "MTPR_ASTEN", - "MTPR_ASTSR", "CSERVE", "SWPPAL", "MFPR_FEN", - "MTPR_FEN", "MTPR_IPIR", "MFPR_IPL", "MTPR_IPL", - "MFPR_MCES", "MTPR_MCES", "MFPR_PCBB", "MFPR_PRBR", - "MTPR_PRBR", "MFPR_PTBR", "MFPR_SCBB", "MTPR_SCBB", - "MTPR_SIRR", "MFPR_SISR", "MFPR_TBCHK", "MTPR_TBIA", - "MTPR_TBIAP", "MTPR_TBIS", "MFPR_ESP", "MTPR_ESP", - "MFPR_SSP", "MTPR_SSP", "MFPR_USP", "MTPR_USP", - "MTPR_TBISD", "MTPR_TBISI", "MFPR_ASTEN", "MFPR_ASTSR", - "MFPR_VTBR", "MTPR_VTBR", "MTPR_PERFMON", "MTPR_DATFX", - "MFPR_VIRBND", "MTPR_VIRBND", "MFPR_SYSPTBR", "MTPR_SYSPTBR", - "WTINT", "MFPR_WHAMI", - "BPT", "BUGCHK", "CHME", "CHMK", - "CHMS", "CHMU", "IMB", "INSQHIL", - "INSQTIL", "INSQHIQ", "INSQTIQ", "INSQUEL", - "INSQUEQ", "INSQUEL/D", "INSQUEQ/D", "PROBER", - "PROBEW", "RD_PS", "REI", "REMQHIL", - "REMQTIL", "REMQHIQ", "REMQTIQ", "REMQUEL", - "REMQUEQ", "REMQUEL/D", "REMQUEQ/D", "SWASTEN", - "WR_PS_SW", "RSCC", "RD_UNQ", "WR_UNQ", - "AMOVRR", "AMOVRM", "INSQHILR", "INSQTILR", - "INSQHIQR", "INSQTIQR", "REMQHILR", "REMQTILR", - "REMQHIQR", "REMQTIQR", "GENTRAP", "CLRFEN", - "RDMCES", "WRMCES", "WRVIRBND", "WRSYSPTBR", /* UNIX PALcode */ - "WRFEN", "WRVPTPTR", "WRASN", - "SWPCTX", "WRVAL", "RDVAL", "TBI", - "WRENT", "SWPIPL", "RDPS", "WRKGP", - "WRUSP", "WRPERFMON", "RDUSP", - "WHAMI", "RETSYS", "RTI", - "URTI", "RDUNIQUE", "WRUNIQUE", - "LDA", "LDAH", "LDBU", "LDQ_U", - "LDWU", "STW", "STB", "STQ_U", - "ADDL", "S4ADDL", "SUBL", "S4SUBL", - "CMPBGE", "S8ADDL", "S8SUBL", "CMPULT", - "ADDQ", "S4ADDQ", "SUBQ", "S4SUBQ", - "CMPEQ", "S8ADDQ", "S8SUBQ", "CMPULE", - "ADDL/V", "SUBL/V", "CMPLT", - "ADDQ/V", "SUBQ/V", "CMPLE", - "AND", "BIC", "CMOVLBS", "CMOVLBC", - "BIS", "CMOVEQ", "CMOVNE", "ORNOT", - "XOR", "CMOVLT", "CMOVGE", "EQV", - "CMOVLE", "CMOVGT", - "MSKBL", "EXTBL", "INSBL", - "MSKWL", "EXTWL", "INSWL", - "MSKLL", "EXTLL", "INSLL", - "ZAP", "ZAPNOT", "MSKQL", "SRL", - "EXTQL", "SLL", "INSQL", "SRA", - "MSKWQ", "EXTWQ", "INSWQ", - "MSKLQ", "EXTLQ", "INSLQ", - "MSKQH", "EXTQH", "INSQH", - "MULL", "MULQ", "UMULH", - "MULL/V", "MULLQ/V", - "ITOFS", "ITOFF", "ITOFT", - "SQRTF/C", "SQRTF", "SQRTF/UC", "SQRTF/U", - "SQRTF/SC", "SQRTF/S", "SQRTF/SUC", "SQRTF/SU", - "SQRTG/C", "SQRTG", "SQRTG/UC", "SQRTG/U", - "SQRTG/SC", "SQRTG/S", "SQRTG/SUC", "SQRTG/SU", - "SQRTS/C", "SQRTS/M", "SQRTS", "SQRTS/D", - "SQRTS/UC", "SQRTS/UM", "SQRTS/U", "SQRTS/UD", - "SQRTS/SUC", "SQRTS/SUM", "SQRTS/SU", "SQRTS/SUD", - "SQRTS/SUIC", "SQRTS/SUIM", "SQRTS/SUI", "SQRTS/SUID", - "SQRTT/C", "SQRTT/M", "SQRTT", "SQRTT/D", - "SQRTT/UC", "SQRTT/UM", "SQRTT/U", "SQRTT/UD", - "SQRTT/SUC", "SQRTT/SUM", "SQRTT/SU", "SQRTT/SUD", - "SQRTT/SUIC", "SQRTT/SUIM", "SQRTT/SUI", "SQRTT/SUID", - "ADDF/C", "ADDF", "ADDF/UC", "ADDF/U", - "ADDF/SC", "ADDF/S", "ADDF/SUC", "ADDF/SU", - "SUBF/C", "SUBF", "SUBF/UC", "SUBF/U", - "SUBF/SC", "SUBF/S", "SUBF/SUC", "SUBF/SU", - "MULF/C", "MULF", "MULF/UC", "MULF/U", - "MULF/SC", "MULF/S", "MULF/SUC", "MULF/SU", - "DIVF/C", "DIVF", "DIVF/UC", "DIVF/U", - "DIVF/SC", "DIVF/S", "DIVF/SUC", "DIVF/SU", - "ADDG/C", "ADDG", "ADDG/UC", "ADDG/U", - "ADDG/SC", "ADDG/S", "ADDG/SUC", "ADDG/SU", - "SUBG/C", "SUBG", "SUBG/UC", "SUBG/U", - "SUBG/SC", "SUBG/S", "SUBG/SUC", "SUBG/SU", - "MULG/C", "MULG", "MULG/UC", "MULG/U", - "MULG/SC", "MULG/S", "MULG/SUC", "MULG/SU", - "DIVG/C", "DIVG", "DIVG/UC", "DIVG/U", - "DIVG/SC", "DIVG/S", "DIVG/SUC", "DIVG/SU", - "CVTDG/C", "CVTDG", "CVTDG/UC", "CVTDG/U", - "CVTDG/SC", "CVTDG/S", "CVTDG/SUC", "CVTDG/SU", - "CVTGF/C", "CVTGF", "CVTGF/UC", "CVTGF/U", - "CVTGF/SC", "CVTGF/S", "CVTGF/SUC", "CVTGF/SU", - "CVTGD/C", "CVTGD", "CVTGD/UC", "CVTGD/U", - "CVTGD/SC", "CVTGD/S", "CVTGD/SUC", "CVTGD/SU", - "CVTGQ/C", "CVTGQ", "CVTGQ/VC", "CVTGQ/V", - "CVTGQ/SC", "CVTGQ/S", "CVTGQ/SVC", "CVTGQ/SV", - "CVTQF/C", "CVTQF", "CVTQG/C", "CVTQG", - "CMPGEQ/C", "CMPGEQ/SC", "CMPGLT/C", "CMPGLT/SC", - "CMPGLE/C", "CMPGLE/SC", - "ADDS/C", "ADDS/M", "ADDS", "ADDS/D", - "ADDS/UC", "ADDS/UM", "ADDS/U", "ADDS/UD", - "ADDS/SUC", "ADDS/SUM", "ADDS/SU", "ADDS/SUD", - "ADDS/SUIC", "ADDS/SUIM", "ADDS/SUI", "ADDS/SUID", - "SUBS/C", "SUBS/M", "SUBS", "SUBS/D", - "SUBS/UC", "SUBS/UM", "SUBS/U", "SUBS/UD", - "SUBS/SUC", "SUBS/SUM", "SUBS/SU", "SUBS/SUD", - "SUBS/SUIC", "SUBS/SUIM", "SUBS/SUI", "SUBS/SUID", - "MULS/C", "MULS/M", "MULS", "MULS/D", - "MULS/UC", "MULS/UM", "MULS/U", "MULS/UD", - "MULS/SUC", "MULS/SUM", "MULS/SU", "MULS/SUD", - "MULS/SUIC", "MULS/SUIM", "MULS/SUI", "MULS/SUID", - "DIVS/C", "DIVS/M", "DIVS", "DIVS/D", - "DIVS/UC", "DIVS/UM", "DIVS/U", "DIVS/UD", - "DIVS/SUC", "DIVS/SUM", "DIVS/SU", "DIVS/SUD", - "DIVS/SUIC", "DIVS/SUIM", "DIVS/SUI", "DIVS/SUID", - "ADDT/C", "ADDT/M", "ADDT", "ADDT/D", - "ADDT/UC", "ADDT/UM", "ADDT/U", "ADDT/UD", - "ADDT/SUC", "ADDT/SUM", "ADDT/SU", "ADDT/SUD", - "ADDT/SUIC", "ADDT/SUIM", "ADDT/SUI", "ADDT/SUID", - "SUBT/C", "SUBT/M", "SUBT", "SUBT/D", - "SUBT/UC", "SUBT/UM", "SUBT/U", "SUBT/UD", - "SUBT/SUC", "SUBT/SUM", "SUBT/SU", "SUBT/SUD", - "SUBT/SUIC", "SUBT/SUIM", "SUBT/SUI", "SUBT/SUID", - "MULT/C", "MULT/M", "MULT", "MULT/D", - "MULT/UC", "MULT/UM", "MULT/U", "MULT/UD", - "MULT/SUC", "MULT/SUM", "MULT/SU", "MULT/SUD", - "MULT/SUIC", "MULT/SUIM", "MULT/SUI", "MULT/SUID", - "DIVT/C", "DIVT/M", "DIVT", "DIVT/D", - "DIVT/UC", "DIVT/UM", "DIVT/U", "DIVT/UD", - "DIVT/SUC", "DIVT/SUM", "DIVT/SU", "DIVT/SUD", - "DIVT/SUIC", "DIVT/SUIM", "DIVT/SUI", "DIVT/SUID", - "CVTTS/C", "CVTTS/M", "CVTTS", "CVTTS/D", - "CVTTS/UC", "CVTTS/UM", "CVTTS/U", "CVTTS/UD", - "CVTTS/SUC", "CVTTS/SUM", "CVTTS/SU", "CVTTS/SUD", - "CVTTS/SUIC", "CVTTS/SUIM", "CVTTS/SUI", "CVTTS/SUID", - "CVTTQ/C", "CVTTQ/M", "CVTTQ", "CVTTQ/D", - "CVTTQ/VC", "CVTTQ/VM", "CVTTQ/V", "CVTTQ/VD", - "CVTTQ/SVC", "CVTTQ/SVM", "CVTTQ/SV", "CVTTQ/SVD", - "CVTTQ/SVIC", "CVTTQ/SVIM", "CVTTQ/SVI", "CVTTQ/SVID", - "CVTQS/C", "CVTQS/M", "CVTQS", "CVTQS/D", - "CVTQS/SUIC", "CVTQS/SUIM", "CVTQS/SUI", "CVTQS/SUID", - "CVTQT/C", "CVTQT/M", "CVTQT", "CVTQT/D", - "CVTQT/SUIC", "CVTQT/SUIM", "CVTQT/SUI", "CVTQT/SUID", - "CMPTUN/C", "CMPTUN/S", "CMPTEQ/C", "CMPTEQ/S", - "CMPTLT/C", "CMPTLT/S", "CMPTLE/C", "CMPTLE/S", - "CVTLQ", "CPYS", "CPYSN", "CPYSE", - "MT_FPCR", "MF_FPCR", - "FCMOVEQ", "FCMOVNE", "FCMOVLT", - "FCMOVGE", "FCMOVLE", "FCMOVGT", - "CVTQL", "CVTQL/V", "CVTQL/SV", - "TRAPB", "EXCB", "MB", "WMB", - "FETCH", "FETCH_M", "RPCC", - "RC", "RS", - "JMP", "JSR", "RET", "JSR_COROUTINE", - "SEXTB", "SEXTW", - "CTPOP", "PERR", "CTLZ", "CTTZ", - "UNPKBW", "UNPKBL", "PKWB", "PKLB", - "MINSB8", "MINSW4", "MINUB8", "MINUW4", - "MAXSB8", "MAXSW4", "MAXUB8", "MAXUW4", - "FTOIT", "FTOIS", - "LDF", "LDG", "LDS", "LDT", - "STS", "STG", "STS", "STT", - "LDL", "LDQ", "LDL_L", "LDQ_L", - "STL", "STQ", "STL_L", "STQ_L", - "BR", "FBEQ", "FBLT", "FBLE", - "BSR", "FBNE", "BFGE", "FBGT", - "BLBC", "BEQ", "BLT", "BLE", - "BLBS", "BNE", "BGE", "BGT", - NULL - }; - -const uint32 opval[] = { - 0x00000000, C_PCM, 0x00000001, C_PCM, 0x00000002, C_PCM, 0x00000003, C_PVM, - 0x00000004, C_PVM, 0x00000005, C_PVM, 0x00000006, C_PVM, 0x00000007, C_PVM, - 0x00000008, C_PVM, 0x00000009, C_PCM, 0x0000000A, C_PCM, 0x0000000B, C_PVM, - 0x0000000C, C_PVM, 0x0000000D, C_PVM, 0x0000000E, C_PVM, 0x0000000F, C_PVM, - 0x00000010, C_PVM, 0x00000011, C_PVM, 0x00000012, C_PVM, 0x00000013, C_PVM, - 0x00000014, C_PVM, 0x00000015, C_PVM, 0x00000016, C_PVM, 0x00000017, C_PVM, - 0x00000018, C_PVM, 0x00000019, C_PVM, 0x0000001A, C_PVM, 0x0000001B, C_PVM, - 0x0000001C, C_PVM, 0x0000001D, C_PVM, 0x0000001E, C_PVM, 0x0000001F, C_PVM, - 0x00000020, C_PVM, 0x00000021, C_PVM, 0x00000022, C_PVM, 0x00000023, C_PVM, - 0x00000024, C_PVM, 0x00000025, C_PVM, 0x00000026, C_PVM, 0x00000027, C_PVM, - 0x00000029, C_PVM, 0x0000002A, C_PVM, 0x0000002B, C_PVM, 0x0000002E, C_PVM, - 0x00000030, C_PVM, 0x00000031, C_PVM, 0x00000032, C_PVM, 0x00000033, C_PVM, - 0x0000003E, C_PCM, 0x0000003F, C_PVM, - 0x00000080, C_PCM, 0x00000081, C_PCM, 0x00000082, C_PVM, 0x00000083, C_PVM, - 0x00000084, C_PVM, 0x00000085, C_PVM, 0x00000086, C_PCM, 0x00000087, C_PVM, - 0x00000088, C_PVM, 0x00000089, C_PVM, 0x0000008A, C_PVM, 0x0000008B, C_PVM, - 0x0000008C, C_PVM, 0x0000008D, C_PVM, 0x0000008E, C_PVM, 0x0000008F, C_PVM, - 0x00000090, C_PVM, 0x00000091, C_PVM, 0x00000092, C_PVM, 0x00000093, C_PVM, - 0x00000094, C_PVM, 0x00000095, C_PVM, 0x00000096, C_PVM, 0x00000097, C_PVM, - 0x00000098, C_PVM, 0x00000099, C_PVM, 0x0000009A, C_PVM, 0x0000009B, C_PVM, - 0x0000009C, C_PVM, 0x0000009D, C_PVM, 0x0000009E, C_PVM, 0x0000009F, C_PVM, - 0x000000A0, C_PVM, 0x000000A1, C_PVM, 0x000000A2, C_PVM, 0x000000A3, C_PVM, - 0x000000A4, C_PVM, 0x000000A5, C_PVM, 0x000000A6, C_PVM, 0x000000A7, C_PVM, - 0x000000A8, C_PVM, 0x000000A9, C_PVM, 0x000000AA, C_PCM, 0x000000AE, C_PCM, - 0x00000010, C_PUN, 0x00000011, C_PUN, 0x00000013, C_PUN, 0x00000014, C_PUN, - 0x0000002B, C_PUN, 0x0000002D, C_PUN, 0x0000002E, C_PUN, - 0x00000030, C_PUN, 0x00000031, C_PUN, 0x00000032, C_PUN, 0x00000033, C_PUN, - 0x00000034, C_PUN, 0x00000035, C_PUN, 0x00000036, C_PUN, 0x00000037, C_PUN, - 0x00000038, C_PUN, 0x00000039, C_PUN, 0x0000003A, C_PUN, - 0x0000003C, C_PUN, 0x0000003D, C_PUN, 0x0000003F, C_PUN, - 0x00000092, C_PUN, 0x0000009E, C_PUN, 0x0000009F, C_PUN, - 0x20000000, C_MR, 0x24000000, C_MR, 0x28000000, C_MR, 0x2C000000, C_MR, - 0x30000000, C_MR, 0x34000000, C_MR, 0x38000000, C_MR, 0x3C000000, C_MR, - 0x40000000, C_IO, 0x40000040, C_IO, 0x40000120, C_IO, 0x40000160, C_IO, - 0x400001C0, C_IO, 0x40000240, C_IO, 0x40000360, C_IO, 0x400003A0, C_IO, - 0x40000400, C_IO, 0x40000440, C_IO, 0x40000520, C_IO, 0x40000560, C_IO, - 0x400005A0, C_IO, 0x40000640, C_IO, 0x40000760, C_IO, 0x400007A0, C_IO, - 0x40000800, C_IO, 0x40000920, C_IO, 0x400009A0, C_IO, - 0x40000C00, C_IO, 0x40000D20, C_IO, 0x40000DA0, C_IO, - 0x44000000, C_IO, 0x44000100, C_IO, 0x44000280, C_IO, 0x440002C0, C_IO, - 0x44000400, C_IO, 0x44000480, C_IO, 0x440004C0, C_IO, 0x44000500, C_IO, - 0x44000800, C_IO, 0x44000880, C_IO, 0x440008C0, C_IO, 0x44000900, C_IO, - 0x44000C80, C_IO, 0x44000CC0, C_IO, - 0x48000040, C_IO, 0x480000C0, C_IO, 0x48000160, C_IO, - 0x48000240, C_IO, 0x480002C0, C_IO, 0x48000360, C_IO, - 0x48000440, C_IO, 0x480004C0, C_IO, 0x48000560, C_IO, - 0x48000600, C_IO, 0x48000620, C_IO, 0x48000640, C_IO, 0x48000680, C_IO, - 0x480006C0, C_IO, 0x48000720, C_IO, 0x48000760, C_IO, 0x48000780, C_IO, - 0x48000A40, C_IO, 0x48000AE0, C_IO, 0x48000B40, C_IO, - 0x48000C40, C_IO, 0x48000CE0, C_IO, 0x48000D40, C_IO, - 0x48000E40, C_IO, 0x48000EE0, C_IO, 0x48000F40, C_IO, - 0x4C000000, C_IO, 0x4C000400, C_IO, 0x4C000600, C_IO, - 0x4C000800, C_IO, 0x4C000C00, C_IO, - 0x501F0080, C_FAC, 0x501F0280, C_FAC, 0x501F0480, C_FAC, - 0x53E00140, C_FBC, 0x53E01140, C_FBC, 0x53E02140, C_FBC, 0x53E03140, C_FBC, - 0x53E08140, C_FBC, 0x53E09140, C_FBC, 0x53E0A140, C_FBC, 0x53E0B140, C_FBC, - 0x53E00540, C_FBC, 0x53E01540, C_FBC, 0x53E02540, C_FBC, 0x53E03540, C_FBC, - 0x53E08540, C_FBC, 0x53E09540, C_FBC, 0x53E0A540, C_FBC, 0x53E0B540, C_FBC, - 0x53E00160, C_FBC, 0x53E00960, C_FBC, 0x53E01160, C_FBC, 0x53E01960, C_FBC, - 0x53E02160, C_FBC, 0x53E02960, C_FBC, 0x53E03160, C_FBC, 0x53E03960, C_FBC, - 0x53E0A160, C_FBC, 0x53E0A960, C_FBC, 0x53E0B160, C_FBC, 0x53E0B960, C_FBC, - 0x53E0E160, C_FBC, 0x53E0E960, C_FBC, 0x53E0F160, C_FBC, 0x53E0F960, C_FBC, - 0x53E00560, C_FBC, 0x53E00D60, C_FBC, 0x53E01560, C_FBC, 0x53E01D60, C_FBC, - 0x53E02560, C_FBC, 0x53E02D60, C_FBC, 0x53E03560, C_FBC, 0x53E03D60, C_FBC, - 0x53E0A560, C_FBC, 0x53E0AD60, C_FBC, 0x53E0B560, C_FBC, 0x53E0BD60, C_FBC, - 0x53E0E560, C_FBC, 0x53E0ED60, C_FBC, 0x53E0F560, C_FBC, 0x53E0FD60, C_FBC, - 0x54000000, C_FO, 0x54001000, C_FO, 0x54002000, C_FO, 0x54003000, C_FO, - 0x54008000, C_FO, 0x54009000, C_FO, 0x5400A000, C_FO, 0x5400B000, C_FO, - 0x54000020, C_FO, 0x54001020, C_FO, 0x54002020, C_FO, 0x54003020, C_FO, - 0x54008020, C_FO, 0x54009020, C_FO, 0x5400A020, C_FO, 0x5400B020, C_FO, - 0x54000040, C_FO, 0x54001040, C_FO, 0x54002040, C_FO, 0x54003040, C_FO, - 0x54008040, C_FO, 0x54009040, C_FO, 0x5400A040, C_FO, 0x5400B040, C_FO, - 0x54000060, C_FO, 0x54001060, C_FO, 0x54002060, C_FO, 0x54003060, C_FO, - 0x54008060, C_FO, 0x54009060, C_FO, 0x5400A060, C_FO, 0x5400B060, C_FO, - 0x54000400, C_FO, 0x54001400, C_FO, 0x54002400, C_FO, 0x54003400, C_FO, - 0x54008400, C_FO, 0x54009400, C_FO, 0x5400A400, C_FO, 0x5400B400, C_FO, - 0x54000420, C_FO, 0x54001420, C_FO, 0x54002420, C_FO, 0x54003420, C_FO, - 0x54008420, C_FO, 0x54009420, C_FO, 0x5400A420, C_FO, 0x5400B420, C_FO, - 0x54000440, C_FO, 0x54001440, C_FO, 0x54002440, C_FO, 0x54003440, C_FO, - 0x54008440, C_FO, 0x54009440, C_FO, 0x5400A440, C_FO, 0x5400B440, C_FO, - 0x54000460, C_FO, 0x54001460, C_FO, 0x54002460, C_FO, 0x54003460, C_FO, - 0x54008460, C_FO, 0x54009460, C_FO, 0x5400A460, C_FO, 0x5400B460, C_FO, - 0x57E003C0, C_FBC, 0x57E013C0, C_FBC, 0x57E023C0, C_FBC, 0x57E033C0, C_FBC, - 0x57E083C0, C_FBC, 0x57E093C0, C_FBC, 0x57E0A3C0, C_FBC, 0x57E0B3C0, C_FBC, - 0x57E00580, C_FBC, 0x57E01580, C_FBC, 0x57E02580, C_FBC, 0x57E03580, C_FBC, - 0x57E08580, C_FBC, 0x57E09580, C_FBC, 0x57E0A580, C_FBC, 0x57E0B580, C_FBC, - 0x57E005A0, C_FBC, 0x57E015A0, C_FBC, 0x57E025A0, C_FBC, 0x57E035A0, C_FBC, - 0x57E085A0, C_FBC, 0x57E095A0, C_FBC, 0x57E0A5A0, C_FBC, 0x57E0B5A0, C_FBC, - 0x57E005E0, C_FBC, 0x57E015E0, C_FBC, 0x57E025E0, C_FBC, 0x57E035E0, C_FBC, - 0x57E085E0, C_FBC, 0x57E095E0, C_FBC, 0x57E0A5E0, C_FBC, 0x57E0B5E0, C_FBC, - 0x57E00780, C_FBC, 0x57E01780, C_FBC, 0x57E007C0, C_FBC, 0x57E017C0, C_FBC, - 0x540014A0, C_FO, 0x540094A0, C_FO, 0x540014C0, C_FO, 0x540094C0, C_FO, - 0x540014E0, C_FO, 0x540094E0, C_FO, - 0x58000000, C_FO, 0x58000800, C_FO, 0x58001000, C_FO, 0x58001800, C_FO, - 0x58002000, C_FO, 0x58002800, C_FO, 0x58003000, C_FO, 0x58003800, C_FO, - 0x5800A000, C_FO, 0x5800A800, C_FO, 0x5800B000, C_FO, 0x5800B800, C_FO, - 0x5800E000, C_FO, 0x5800E800, C_FO, 0x5800F000, C_FO, 0x5800F800, C_FO, - 0x58000020, C_FO, 0x58000820, C_FO, 0x58001020, C_FO, 0x58001820, C_FO, - 0x58002020, C_FO, 0x58002820, C_FO, 0x58003020, C_FO, 0x58003820, C_FO, - 0x5800A020, C_FO, 0x5800A820, C_FO, 0x5800B020, C_FO, 0x5800B820, C_FO, - 0x5800E020, C_FO, 0x5800E820, C_FO, 0x5800F020, C_FO, 0x5800F820, C_FO, - 0x58000040, C_FO, 0x58000840, C_FO, 0x58001040, C_FO, 0x58001840, C_FO, - 0x58002040, C_FO, 0x58002840, C_FO, 0x58003040, C_FO, 0x58003840, C_FO, - 0x5800A040, C_FO, 0x5800A840, C_FO, 0x5800B040, C_FO, 0x5800B840, C_FO, - 0x5800E040, C_FO, 0x5800E840, C_FO, 0x5800F040, C_FO, 0x5800F840, C_FO, - 0x58000060, C_FO, 0x58000860, C_FO, 0x58001060, C_FO, 0x58001860, C_FO, - 0x58002060, C_FO, 0x58002860, C_FO, 0x58003060, C_FO, 0x58003860, C_FO, - 0x5800A060, C_FO, 0x5800A860, C_FO, 0x5800B060, C_FO, 0x5800B860, C_FO, - 0x5800E060, C_FO, 0x5800E860, C_FO, 0x5800F060, C_FO, 0x5800F860, C_FO, - 0x58000400, C_FO, 0x58000C00, C_FO, 0x58001400, C_FO, 0x58001C00, C_FO, - 0x58002400, C_FO, 0x58002C00, C_FO, 0x58003400, C_FO, 0x58003C00, C_FO, - 0x5800A400, C_FO, 0x5800AC00, C_FO, 0x5800B400, C_FO, 0x5800BC00, C_FO, - 0x5800E400, C_FO, 0x5800EC00, C_FO, 0x5800F400, C_FO, 0x5800FC00, C_FO, - 0x58000420, C_FO, 0x58000C20, C_FO, 0x58001420, C_FO, 0x58001C20, C_FO, - 0x58002420, C_FO, 0x58002C20, C_FO, 0x58003420, C_FO, 0x58003C20, C_FO, - 0x5800A420, C_FO, 0x5800AC20, C_FO, 0x5800B420, C_FO, 0x5800BC20, C_FO, - 0x5800E420, C_FO, 0x5800EC20, C_FO, 0x5800F420, C_FO, 0x5800FC20, C_FO, - 0x58000440, C_FO, 0x58000C40, C_FO, 0x58001440, C_FO, 0x58001C40, C_FO, - 0x58002440, C_FO, 0x58002C40, C_FO, 0x58003440, C_FO, 0x58003C40, C_FO, - 0x5800A440, C_FO, 0x5800AC40, C_FO, 0x5800B440, C_FO, 0x5800BC40, C_FO, - 0x5800E440, C_FO, 0x5800EC40, C_FO, 0x5800F440, C_FO, 0x5800FC40, C_FO, - 0x58000460, C_FO, 0x58000C60, C_FO, 0x58001460, C_FO, 0x58001C60, C_FO, - 0x58002460, C_FO, 0x58002C60, C_FO, 0x58003460, C_FO, 0x58003C60, C_FO, - 0x5800A460, C_FO, 0x5800AC60, C_FO, 0x5800B460, C_FO, 0x5800BC60, C_FO, - 0x5800E460, C_FO, 0x5800EC60, C_FO, 0x5800F460, C_FO, 0x5800FC60, C_FO, - 0x5BE00580, C_FBC, 0x5BE00D80, C_FBC, 0x5BE01580, C_FBC, 0x5BE01D80, C_FBC, - 0x5BE02580, C_FBC, 0x5BE02D80, C_FBC, 0x5BE03580, C_FBC, 0x5BE03D80, C_FBC, - 0x5BE0A580, C_FBC, 0x5BE0AD80, C_FBC, 0x5BE0B580, C_FBC, 0x5BE0BD80, C_FBC, - 0x5BE0E580, C_FBC, 0x5BE0ED80, C_FBC, 0x5BE0F580, C_FBC, 0x5BE0FD80, C_FBC, - 0x5BE005E0, C_FBC, 0x5BE00DE0, C_FBC, 0x5BE015E0, C_FBC, 0x5BE01DE0, C_FBC, - 0x5BE025E0, C_FBC, 0x5BE02DE0, C_FBC, 0x5BE035E0, C_FBC, 0x5BE03DE0, C_FBC, - 0x5BE0A5E0, C_FBC, 0x5BE0ADE0, C_FBC, 0x5BE0B5E0, C_FBC, 0x5BE0BDE0, C_FBC, - 0x5BE0E5E0, C_FBC, 0x5BE0EDE0, C_FBC, 0x5BE0F5E0, C_FBC, 0x5BE0FDE0, C_FBC, - 0x5BE00780, C_FBC, 0x5BE00F80, C_FBC, 0x5BE01780, C_FBC, 0x5BE01F80, C_FBC, - 0x5BE0E780, C_FBC, 0x5BE0EF80, C_FBC, 0x5BE0F780, C_FBC, 0x5BE0FF80, C_FBC, - 0x5BE007C0, C_FBC, 0x5BE00FC0, C_FBC, 0x5BE017C0, C_FBC, 0x5BE01FC0, C_FBC, - 0x5BE0E7C0, C_FBC, 0x5BE0EFC0, C_FBC, 0x5BE0F7C0, C_FBC, 0x5BE0FFC0, C_FBC, - 0x58001480, C_FO, 0x58009480, C_FO, 0x580014A0, C_FO, 0x580094A0, C_FO, - 0x580014C0, C_FO, 0x580094C0, C_FO, 0x580014E0, C_FO, 0x580094E0, C_FO, - 0x5FE00200, C_IBC, 0x5C000400, C_IO, 0x5C000420, C_IO, 0x5C000440, C_IO, - 0x5C000480, C_IO, 0x5C0004A0, C_IO, - 0x5C000540, C_IO, 0x5C000560, C_IO, 0x5C000580, C_IO, - 0x5C0005A0, C_IO, 0x5C0005C0, C_IO, 0x5C0005E0, C_IO, - 0x5FE00060, C_IBC, 0x5FE00260, C_IBC, 0x5FE00A60, C_IBC, - 0x60000000, C_NO, 0x60000400, C_NO, 0x60004000, C_NO, 0x60004400, C_NO, - 0x60008000, C_FE, 0x6000A000, C_FE, 0x6000C000, C_NO, - 0x6000E000, C_RV, 0x6000F000, C_RV, - 0x68000000, C_JP, 0x68004000, C_JP, 0x68008000, C_JP, 0x6800C000, C_JP, - 0x73E00000, C_IBC, 0x73E00020, C_IBC, - 0x73E00600, C_IBC, 0x70000620, C_IO, 0x73E00640, C_IBC, 0x73E00660, C_IBC, - 0x73E00680, C_IBC, 0x73E006A0, C_IBC, 0x73E006C0, C_IBC, 0x73E006E0, C_IBC, - 0x70000700, C_IO, 0x70000720, C_IO, 0x70000740, C_IO, 0x70000780, C_IO, - 0x70000780, C_IO, 0x700007A0, C_IO, 0x700007C0, C_IO, 0x700007E0, C_IO, - 0x701F0E00, C_IAC, 0x701F0F00, C_IAC, - 0x80000000, C_MR, 0x84000000, C_MR, 0x88000000, C_MR, 0x8C000000, C_MR, - 0x90000000, C_MR, 0x94000000, C_MR, 0x98000000, C_MR, 0x9C000000, C_MR, - 0xA0000000, C_MR, 0xA4000000, C_MR, 0xA8000000, C_MR, 0xAC000000, C_MR, - 0xB0000000, C_MR, 0xB4000000, C_MR, 0xB8000000, C_MR, 0xBC000000, C_MR, - 0xC0000000, C_BR, 0xC4000000, C_BR, 0xC8000000, C_BR, 0xCC000000, C_BR, - 0xD0000000, C_BR, 0xD4000000, C_BR, 0xD8000000, C_BR, 0xDC000000, C_BR, - 0xE0000000, C_BR, 0xE4000000, C_BR, 0xE8000000, C_BR, 0xEC000000, C_BR, - 0xF0000000, C_BR, 0xF4000000, C_BR, 0xF8000000, C_BR, 0xFC000000, C_BR, - M32, 0 - }; - -/* Symbolic decode - - Inputs: - *of = output stream - addr = current PC - *val = values to decode - *uptr = pointer to unit - sw = switches - Outputs: - return = if >= 0, error code - if < 0, number of extra bytes retired -*/ - -t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, - UNIT *uptr, int32 sw) -{ -uint32 c, sc, rdx; -t_stat r; -DEVICE *dptr; - -if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */ -else if (uptr != &cpu_unit) return SCPE_ARG; /* CPU only */ -dptr = find_dev_from_unit (uptr); /* find dev */ -if (dptr == NULL) return SCPE_IERR; -if (sw & SWMASK ('D')) rdx = 10; /* get radix */ -else if (sw & SWMASK ('O')) rdx = 8; -else if (sw & SWMASK ('H')) rdx = 16; -else rdx = dptr->dradix; - -if (sw & SWMASK ('A')) { /* ASCII? */ - sc = (uint32) (addr & 0x7) * 8; /* shift count */ - c = (uint32) (val[0] >> sc) & 0x7F; - fprintf (of, (c < 0x20)? "<%02X>": "%c", c); - return 0; - } -if (sw & SWMASK ('B')) { /* byte? */ - sc = (uint32) (addr & 0x7) * 8; /* shift count */ - c = (uint32) (val[0] >> sc) & M8; - fprintf (of, "%02X", c); - return 0; - } -if (sw & SWMASK ('W')) { /* word? */ - sc = (uint32) (addr & 0x6) * 8; /* shift count */ - c = (uint32) (val[0] >> sc) & M16; - fprintf (of, "%04X", c); - return -1; - } -if (sw & SWMASK ('L')) { /* long? */ - if (addr & 4) c = (uint32) (val[0] >> 32) & M32; - else c = (uint32) val[0] & M32; - fprintf (of, "%08X", c); - return -3; - } -if (sw & SWMASK ('C')) { /* char format? */ - for (sc = 0; sc < 64; sc = sc + 8) { /* print string */ - c = (uint32) (val[0] >> sc) & 0x7F; - fprintf (of, (c < 0x20)? "<%02X>": "%c", c); - } - return -7; /* return # chars */ - } -if (sw & SWMASK ('M')) { /* inst format? */ - if (addr & 4) c = (uint32) (val[0] >> 32) & M32; - else c = (uint32) val[0] & M32; - r = fprint_sym_m (of, addr, c); /* decode inst */ - if (r <= 0) return r; - } - -fprint_val (of, val[0], rdx, 64, PV_RZRO); -return -7; -} - -/* Symbolic decode for -m - - Inputs: - of = output stream - addr = current PC - inst = instruction to decode - Outputs: - return = if >= 0, error code - if < 0, number of extra bytes retired (-3) -*/ - -t_stat fprint_sym_m (FILE *of, t_addr addr, uint32 inst) -{ -uint32 i, j, k, fl, ra, rb, rc, md, bd, jd, lit8, any; -t_stat r; - -if ((r = fprint_pal_hwre (of, inst)) < 0) return r; /* PAL instruction? */ -for (i = 0; opval[i] != M32; i = i + 2) { /* loop thru ops */ - fl = opval[i + 1]; /* flags */ - j = fl & CL_CLASS; /* get class */ - k = i >> 1; - if (((opval[i] & masks[j]) == (inst & masks[j])) && /* match? */ - ((j != CL_NO) || (fl & PAL_MASK (pal_type)))) { - ra = I_GETRA (inst); /* all fields */ - rb = I_GETRB (inst); - rc = I_GETRC (inst); - lit8 = I_GETLIT8 (inst); - md = I_GETMDSP (inst); - bd = I_GETBDSP (inst); - jd = inst & 0x3FFF; - any = 0; - fprintf (of, "%s", opcode[k]); /* opcode */ - if (fl & FL_RA) /* ra? */ - any = fprintf (of, " R%d", ra); - if (fl & FL_BDP) { /* branch? */ - addr = (addr + (SEXT_BDSP (bd) << 2) + 4) & M64; - any = fprintf (of, (any? ",": " ")); - fprint_val (of, addr, 16, 64, PV_LEFT); - } - else if (fl & FL_MDP) { /* mem ref? */ - if ((fl & FL_RBI) && (rb != 31)) - any = fprintf (of, (any? ",%X(R%d)": " %X(R%d)"), md, rb); - else any = fprintf (of, (any? ",%X": " %X"), md); - } - else if (fl & FL_RB) { /* rb? */ - if (fl & FL_RBI) - any = fprintf (of, (any? ",(R%d)": " (R%d)"), rb); - else if ((fl & FL_LIT) && (inst & I_ILIT)) - any = fprintf (of, (any? ",#%X": " #%X"), lit8); - else any = fprintf (of, (any? ",R%d": " R%d"), rb); - } - if ((fl & FL_JDP) && jd) /* jmp? */ - any = fprintf (of, (any? ",%X": " %X"), jd); - else if (fl & FL_RC) /* rc? */ - any = fprintf (of, (any? ",R%d": " R%d"), rc); - return -3; - } /* end if */ - } /* end for */ -return SCPE_ARG; -} - -/* Symbolic input - - Inputs: - *cptr = pointer to input string - addr = current PC - *uptr = pointer to unit - *val = pointer to output values - sw = switches - Outputs: - status = > 0 error code - <= 0 -number of extra words -*/ - -t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) -{ -t_value num; -uint32 i, sc, rdx; -t_stat r; -DEVICE *dptr; - -if (uptr == NULL) uptr = &cpu_unit; /* anon = CPU */ -else if (uptr != &cpu_unit) return SCPE_ARG; /* CPU only */ -dptr = find_dev_from_unit (uptr); /* find dev */ -if (dptr == NULL) return SCPE_IERR; -if (sw & SWMASK ('D')) rdx = 10; /* get radix */ -else if (sw & SWMASK ('O')) rdx = 8; -else if (sw & SWMASK ('H')) rdx = 16; -else rdx = dptr->dradix; - -if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ - if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */ - sc = (uint32) (addr & 0x7) * 8; /* shift count */ - val[0] = (val[0] & ~(((t_uint64) M8) << sc)) | - (((t_uint64) cptr[0]) << sc); - return 0; - } -if (sw & SWMASK ('B')) { /* byte? */ - num = get_uint (cptr, rdx, M8, &r); /* get byte */ - if (r != SCPE_OK) return SCPE_ARG; - sc = (uint32) (addr & 0x7) * 8; /* shift count */ - val[0] = (val[0] & ~(((t_uint64) M8) << sc)) | - (num << sc); - return 0; - } -if (sw & SWMASK ('W')) { /* word? */ - num = get_uint (cptr, rdx, M16, &r); /* get word */ - if (r != SCPE_OK) return SCPE_ARG; - sc = (uint32) (addr & 0x6) * 8; /* shift count */ - val[0] = (val[0] & ~(((t_uint64) M16) << sc)) | - (num << sc); - return -1; - } -if (sw & SWMASK ('L')) { /* longword? */ - num = get_uint (cptr, rdx, M32, &r); /* get longword */ - if (r != SCPE_OK) return SCPE_ARG; - sc = (uint32) (addr & 0x4) * 8; /* shift count */ - val[0] = (val[0] & ~(((t_uint64) M32) << sc)) | - (num << sc); - return -3; - } -if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII chars? */ - if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */ - for (i = 0; i < 8; i++) { - if (cptr[i] == 0) break; - sc = i * 8; - val[0] = (val[0] & ~(((t_uint64) M8) << sc)) | - (((t_uint64) cptr[i]) << sc); - } - return -7; - } - -if ((addr & 3) == 0) { /* aligned only */ - r = parse_sym_m (cptr, addr, &num); /* try to parse inst */ - if (r <= 0) { /* ok? */ - sc = (uint32) (addr & 0x4) * 8; /* shift count */ - val[0] = (val[0] & ~(((t_uint64) M32) << sc)) | - (num << sc); - return -3; - } - } - -val[0] = get_uint (cptr, rdx, M64, &r); /* get number */ -if (r != SCPE_OK) return r; -return -7; -} - -/* Symbolic input - - Inputs: - *cptr = pointer to input string - addr = current PC - *val = pointer to output values - Outputs: - status = > 0 error code - <= 0 -number of extra words -*/ - -t_stat parse_sym_m (char *cptr, t_addr addr, t_value *inst) -{ -t_uint64 bra, df, db; -uint32 i, k, lit8, fl; -int32 reg; -t_stat r; -char *tptr, gbuf[CBUFSIZE]; - -if ((r = parse_pal_hwre (cptr, inst)) < 0) return r; /* PAL hardware? */ -cptr = get_glyph (cptr, gbuf, 0); /* get opcode */ -for (i = 0; opcode[i] != NULL; i++) { /* loop thru opcodes */ - if (strcmp (opcode[i], gbuf) == 0) { /* string match? */ - k = i << 1; /* index to opval */ - fl = opval[k + 1]; /* get flags */ - if (((fl & CL_CLASS) != CL_NO) || /* not PAL or */ - (fl & PAL_MASK (pal_type))) break; /* PAL type match? */ - } - } -if (opcode[i] == NULL) return SCPE_ARG; -*inst = opval[k]; /* save base op */ - -if (fl & FL_RA) { /* need Ra? */ - cptr = get_glyph (cptr, gbuf, ','); /* get reg */ - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - *inst = *inst | (reg << I_V_RA); - } -if (fl & FL_BDP) { /* need branch disp? */ - cptr = get_glyph (cptr, gbuf, 0); - bra = get_uint (gbuf, 16, M64, &r); - if ((r != SCPE_OK) || (bra & 3)) return SCPE_ARG; - df = ((bra - (addr + 4)) >> 2) & I_M_BDSP; - db = ((addr + 4 - bra) >> 2) & I_M_BDSP; - if (bra == ((addr + 4 + (SEXT_BDSP (df) << 2)) & M64)) - *inst = *inst | (uint32) df; - else if (bra == ((addr + 4 + (SEXT_BDSP (db) << 2)) & M64)) - *inst = *inst | (uint32) db; - else return SCPE_ARG; - } -else if (fl & FL_MDP) { /* need mem disp? */ - cptr = get_glyph (cptr, gbuf, 0); - df = strtotv (gbuf, &tptr, 16); - if ((gbuf == tptr) || (df > I_M_MDSP)) return SCPE_ARG; - *inst = *inst | (uint32) df; - if (*tptr == '(') { - tptr = get_glyph (tptr + 1, gbuf, ')'); - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - *inst = *inst | (reg << I_V_RB); - } - else *inst = *inst | (31 << I_V_RB); - if (*tptr != 0) return SCPE_ARG; - } -else if (fl & FL_RBI) { /* indexed? */ - cptr = get_glyph (cptr, gbuf, ','); - if (gbuf[0] != '(') return SCPE_ARG; - tptr = get_glyph (gbuf + 1, gbuf, ')'); - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - *inst = *inst | (reg << I_V_RB); - if (*tptr != 0) return SCPE_ARG; - } -else if (fl & FL_RB) { - cptr = get_glyph (cptr, gbuf, ','); /* get reg/lit */ - if ((gbuf[0] == '#') && (fl & FL_LIT)) { /* literal? */ - lit8 = (uint32) get_uint (gbuf + 1, 16, I_M_LIT8, &r); - if (r != SCPE_OK) return r; - *inst = *inst | I_ILIT | (lit8 << I_V_LIT8); - } - else { /* rb */ - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - *inst = *inst | (reg << I_V_RB); - } - } -if (fl & FL_JDP) { /* jmp? */ - cptr = get_glyph (cptr, gbuf, 0); /* get disp */ - df = get_uint (gbuf, 16, 0x3FFF, &r); - if (r != SCPE_OK) return r; - *inst = *inst | df; - } -else if (fl & FL_RC) { /* rc? */ - cptr = get_glyph (cptr, gbuf, ','); /* get reg */ - if ((reg = parse_reg (gbuf)) < 0) return SCPE_ARG; - *inst = *inst | (reg << I_V_RC); - } - -if (*cptr != 0) return SCPE_ARG; /* any leftovers? */ -return -3; -} - -/* Parse a register */ - -int32 parse_reg (char *cptr) -{ -t_stat r; -int32 reg; - -if ((*cptr == 'R') || (*cptr == 'r') || - (*cptr == 'F') || (*cptr == 'f')) cptr++; -reg = (int32) get_uint (cptr, 10, 31, &r); -if (r != SCPE_OK) return -1; -return reg; -} - diff --git a/alpha/alpha_sys_defs.h b/alpha/alpha_sys_defs.h deleted file mode 100644 index 7af5a908..00000000 --- a/alpha/alpha_sys_defs.h +++ /dev/null @@ -1,43 +0,0 @@ -/* alpha_system_defs.h: Alpha system definitions file - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Respectfully dedicated to the great people of the Alpha chip, systems, and - software development projects; and to the memory of Peter Conklin, of the - Alpha Program Office. - - This is a STUB! -*/ - -#ifndef _ALPHA_SYS_DEFS_H_ -#define _ALPHA_SYS_DEFS_H_ 0 - -#define PA_SIZE 36 /* PA size */ -#define PA_MASK 0x0000000FFFFFFFFF - -#define ROMBASE 0x000000FFFC000000 -#define ROMSIZE 0x0000000004000000 - -#endif - diff --git a/alpha/old_pal/alpha_pal_defs.h b/alpha/old_pal/alpha_pal_defs.h deleted file mode 100644 index 6471e36b..00000000 --- a/alpha/old_pal/alpha_pal_defs.h +++ /dev/null @@ -1,208 +0,0 @@ -/* alpha_pal_defs.h: Alpha architecture PAL definitions file - - Copyright (c) 2003-2006, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Respectfully dedicated to the great people of the Alpha chip, systems, and - software development projects; and to the memory of Peter Conklin, of the - Alpha Program Office. -*/ - -#ifndef _ALPHA_PAL_DEFS_H_ -#define _ALPHA_PAL_DEFS_H_ 0 - -/* VA - NT software format */ - -#define NTVA_N_PDE (VA_N_OFF - 2) /* PDE width */ -#define NTVA_M_PDE ((1u << NTVA_N_PDE) - 1) /* PDE mask */ -#define NTVA_N_PTD (32 - VA_N_OFF - NTVA_N_PDE) /* PTD width */ -#define NTVA_M_PTD ((1u << NTVA_N_PTD) - 1) /* PTD mask */ -#define NTVA_M_VPN (M32 >> VA_N_OFF) /* 32b VPN mask */ -#define NTVPN_N_SEXT (VA_WIDTH - 32 + 1) /* VPN sext size */ -#define NTVPN_V_SEXT (VA_N_VPN - NTVPN_N_SEXT) /* VPN sext start */ -#define NTVPN_M_SEXT ((1u << NTVPN_N_SEXT) - 1) /* VPN sext mask */ -#define NTVPN_GETSEXT(x) (((x) >> NTVPN_V_SEXT) & NTVPN_M_SEXT) - -/* PTE - NT software format */ - -#define NT_VPTB 0xFFFFFFFFC0000000 /* virt page tbl base */ -#define NTP_V_PFN 9 /* PFN */ -#define NTP_M_PFN 0x7FFFFF -#define NTP_PFN (NTP_M_PFN << NTP_V_PFN) -#define NTP_V_GH 5 -#define NTP_M_GH 0x3 -#define NTP_V_GBL 4 /* global = ASM */ -#define NTP_V_DIRTY 2 /* dirty = !FOW */ -#define NTP_V_OWNER 1 /* owner */ -#define NTP_V_V 0 /* valid */ -#define NTP_GBL (1u << NTP_V_GBL) -#define NTP_DIRTY (1u << NTP_V_DIRTY) -#define NTP_OWNER (1u << NTP_V_OWNER) -#define NTP_V (1u << NTP_V_V) -#define NT_VPNPTD(x) (((x) >> (NTVA_N_PDE - 2)) & (NTVA_M_PTD << 2)) -#define NT_VPNPDE(x) (((x) << 2) & (NTVA_M_PDE << 2)) - -/* VMS PALcode */ - -#define PSV_V_SPA 56 /* VMS PS: stack align */ -#define PSV_M_SPA 0x3F -#define PSV_V_IPL 8 /* interrupt priority */ -#define PSV_M_IPL 0x1F -#define PSV_V_VMM 7 /* virt machine monitor */ -#define PSV_V_CM 3 /* current mode */ -#define PSV_M_CM 0x3 -#define PSV_V_IP 2 /* intr in progress */ -#define PSV_V_SW 0 /* software */ -#define PSV_M_SW 0x3 -#define PSV_VMM (1u << PSV_V_VMM) -#define PSV_IP (1u << PSV_V_IP) -#define PSV_MASK (PSV_VMM | PSV_IP | PSV_M_SW) -#define PSV_MBZ 0xC0FFFFFFFFFFE0E4 /* must be zero */ - -#define PCBV_FLAGS 56 /* PCB flags word */ - -#define SISR_MASK 0xFFFE /* SISR bits */ - -#define IPL_SMAX 0x0F /* highest swre level */ - -#define SCB_FDIS 0x010 /* SCB offsets */ -#define SCB_ACV 0x080 -#define SCB_TNV 0x090 -#define SCB_FOR 0x0A0 -#define SCB_FOW 0x0B0 -#define SCB_FOE 0x0C0 -#define SCB_ARITH 0x200 -#define SCB_KAST 0x240 -#define SCB_EAST 0x250 -#define SCB_SAST 0x260 -#define SCB_UAST 0x270 -#define SCB_ALIGN 0x280 -#define SCB_BPT 0x400 -#define SCB_BUG 0x410 -#define SCB_RSVI 0x420 -#define SCB_RSVO 0x430 -#define SCB_GENTRAP 0x440 -#define SCB_CHMK 0x480 -#define SCB_CHME 0x490 -#define SCB_CHMS 0x4A0 -#define SCB_CHMU 0x4B0 -#define SCB_SISR0 0x500 -#define SCB_CLOCK 0x600 -#define SCB_IPIR 0x610 -#define SCB_SCRD 0x620 -#define SCB_PCRD 0x630 -#define SCB_POWER 0x640 -#define SCB_PERFM 0x650 -#define SCB_SMCHK 0x660 -#define SCB_PMCHK 0x670 -#define SCB_PASVR 0x6F0 -#define SCB_IO 0x800 - -#define VMS_L_STKF (8 * 8) /* stack frame length */ -#define VMS_MME_E 0x0000000000000001 /* mem mgt error flags */ -#define VMS_MME_R 0x0000000000000000 -#define VMS_MME_W 0x8000000000000000 - -/* VAX compatible data length definitions (for ReadUna, WriteUna) */ - -#define L_BYTE 1 -#define L_WORD 2 -#define L_LONG 4 -#define L_QUAD 8 - -/* Unix PALcode */ - -#define PSU_V_CM 3 /* Unix PS: curr mode */ -#define PSU_M_CM 0x1 -#define PSU_CM (PSU_M_CM << PSU_V_CM) -#define PSU_V_IPL 0 /* IPL */ -#define PSU_M_IPL 0x7 -#define PSU_IPL (PSU_M_IPL << PSU_V_IPL) - -#define PCBU_FLAGS 40 /* PCB flags word */ - -#define UNIX_L_STKF (6 * 8) /* kernel stack frame */ -#define UNIX_IF_BPT 0 /* entIF a0 values */ -#define UNIX_IF_BUG 1 -#define UNIX_IF_GEN 2 -#define UNIX_IF_FDIS 3 -#define UNIX_IF_RSVI 4 -#define UNIX_INT_IPIR 0 /* entInt a0 values */ -#define UNIX_INT_CLK 1 -#define UNIX_INT_MCRD 2 -#define UNIX_INT_IO 3 -#define UNIX_INT_PERF 4 -#define UNIX_MMCSR_TNV 0 /* entMM a1 values */ -#define UNIX_MMCSR_ACV 1 -#define UNIX_MMCSR_FOR 2 -#define UNIX_MMCSR_FOW 3 -#define UNIX_MMCSR_FOE 4 -#define UNIX_MME_E M64 /* entMM a2 values */ -#define UNIX_MME_R 0 -#define UNIX_MME_W 1 - -enum vms_pal_opcodes { - OP_HALT, OP_DRAINA, OP_CFLUSH, OP_LDQP, - OP_STQP, OP_SWPCTX, MF_ASN, MT_ASTEN, - MT_ASTSR, OP_CSERVE, OP_SWPPAL, MF_FEN, - MT_FEN, MT_IPIR, MF_IPL, MT_IPL, - MF_MCES, MT_MCES, MF_PCBB, MF_PRBR, - MT_PRBR, MF_PTBR, MF_SCBB, MT_SCBB, - MT_SIRR, MF_SISR, MF_TBCHK, MT_TBIA, - MT_TBIAP, MT_TBIS, MF_ESP, MT_ESP, - MF_SSP, MT_SSP, MF_USP, MT_USP, - MT_TBISD, MT_TBISI, MF_ASTEN, MF_ASTSR, - MF_VTBR = 0x29, MT_VTBR,MT_PERFMON, MT_DATFX = 0x2E, - MF_VIRBND = 0x30, MT_VIRBND, MF_SYSPTBR, MT_SYSPTBR, - OP_WTINT = 0x3E, MF_WHAMI = 0x3F, - OP_BPT = 0x80, OP_BUGCHK, OP_CHME, OP_CHMK, - OP_CHMS, OP_CHMU, OP_IMB, OP_INSQHIL, - OP_INSQTIL, OP_INSQHIQ, OP_INSQTIQ, OP_INSQUEL, - OP_INSQUEQ, OP_INSQUELD,OP_INSQUEQD,OP_PROBER, - OP_PROBEW, OP_RD_PS, OP_REI, OP_REMQHIL, - OP_REMQTIL, OP_REMQHIQ, OP_REMQTIQ, OP_REMQUEL, - OP_REMQUEQ, OP_REMQUELD,OP_REMQUEQD,OP_SWASTEN, - OP_WR_PS_SW,OP_RSCC, OP_RD_UNQ, OP_WR_UNQ, - OP_AMOVRR, OP_AMOVRM, OP_INSQHILR,OP_INSQTILR, - OP_INSQHIQR,OP_INSQTIQR,OP_REMQHILR,OP_REMQTILR, - OP_REMQHIQR,OP_REMQTIQR,OP_GENTRAP, - OP_CLRFEN = 0xAE - }; - -enum unix_pal_opcodes { - OP_halt, OP_draina, OP_cflush, - OP_cserve = 0x9, OP_swppal, - OP_rdmces = 0x10, OP_wrmces, - OP_wrvirbnd = 0x13, OP_wrsysptbr = 0x14, - OP_wrfen = 0x2B, OP_wrvptptr = 0x2D, OP_wrasn, - OP_swpctx = 0x30, OP_wrval, OP_rdval, OP_tbi, - OP_wrent, OP_swpipl, OP_rdps, OP_wrkgp, - OP_wrusp, OP_wrperfmon, OP_rdusp, - OP_whami = 0x3C, OP_retsys, OP_wtint, OP_rti, - OP_bpt = 0x80, OP_bugchk, OP_syscall = 0x83, - OP_imb = 0x86, - OP_urti = 0x92, OP_rdunique = 0x9E, OP_wrunique, - OP_gentrap = 0xAA, OP_clrfen = 0xAE - }; - -#endif diff --git a/alpha/old_pal/alpha_pal_unix.c b/alpha/old_pal/alpha_pal_unix.c deleted file mode 100644 index 73fa8011..00000000 --- a/alpha/old_pal/alpha_pal_unix.c +++ /dev/null @@ -1,702 +0,0 @@ -/* alpha_pal_unix.c - Alpha Unix PAL code simulator - - Copyright (c) 2003-2005, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - This module contains the PALcode implementation for Alpha Unix, except for - the console, which is always done in hardware mode. - - Alpha Unix/Linux requires the following privileged state: - - ps<3:0> processor status - cm<0> current mode - in base - ipl<2:0> interrupt level - in base - ksp<63:0> kernel stack pointer - kgp<63:0> kernel global pointer - usp<63:0> user stack pointer - pcbb<63:0> process control block base - ptptr<63:0> page table base - vptptr<63:0> virtual page table base - virbnd<63:0> virtual address boundary - sysptbr<63:0> system page table base register - sysval<63:0> processor base (sysvalue) - unique<63:0> thread-unique value - entArith<63:0> entry vector, arithmetic trap - entIF<63:0> entry vector, instruction - entInt<63:0> entry vector, interrupt - entSys<63:0> entry vector, system call - entMM<63:0> entry vector, memory management fault - entUna<63:0> entry vector, unaligned - - Unix maps kernel/user to the hardware's kernel/executive. It maps the - 8 IPL's to the hardware IPL's as follows: - - 0 0 - 1 1 - 2 2 - 3 IPL_HMIN - 4 IPL_HMIN+1 - 5 IPL_HMIN+2 - 6 IPL_HMIN+3 - 7 IPL_1F -*/ - -#include "alpha_defs.h" - -#define GET_PSU (((unix_cm & PSU_M_CM) << PSU_V_CM) | \ - ((unix_ipl & PSU_M_IPL) << PSU_V_IPL)) - -// kludge for debugging... -#define io_get_vec(x) 0 - -#define ksp unix_stkp[MODE_K] -#define usp unix_stkp[MODE_E] -#define entInt unix_entVec[0] -#define entArith unix_entVec[1] -#define entMM unix_entVec[2] -#define entIF unix_entVec[3] -#define entUna unix_entVec[4] -#define entSys unix_entVec[5] -#define v0 R[0] -#define a0 R[16] -#define a1 R[17] -#define a2 R[18] -#define a3 R[19] -#define at R[28] -#define gp R[29] - -t_uint64 unix_ptptr = 0; /* page table base */ -t_uint64 unix_vptptr = 0; /* virt page table base */ -t_uint64 unix_virbnd = M64; /* virtual boundary */ -t_uint64 unix_sysptbr = 0; /* system page table base */ -t_uint64 unix_hwpcb = 0; /* hardware PCB */ -t_uint64 unix_unique = 0; /* thread unique */ -t_uint64 unix_sysval = 0; /* processor unique */ -t_uint64 unix_mces = 0; /* machine check err summ */ -t_uint64 unix_stkp[2] = { 0 }; -t_uint64 unix_entVec[6] = { 0 }; -t_uint64 unix_kgp = 0; -uint32 unix_ipl = 0; -uint32 unix_cm = 0; - -static const uint32 map_ipl[8] = { - 0, 1, 2, IPL_HMIN, IPL_HMIN + 1, IPL_HMIN + 2, IPL_HMIN + 3, IPL_1F - }; - -extern t_uint64 R[32]; -extern t_uint64 PC, trap_mask; -extern t_uint64 p1; -extern uint32 vax_flag, lock_flag; -extern uint32 fpen; -extern uint32 ir, pcc_h, pcc_l, pcc_enb; -extern uint32 cm_racc, cm_wacc; -extern uint32 mmu_ispage, mmu_dspage; -extern jmp_buf save_env; -extern uint32 int_req[IPL_HLVL]; - -t_stat unix_syscall (void); -t_stat unix_retsys (void); -t_stat unix_rti (void); -void unix_urti (void); -void unix_swpctx (void); -t_stat unix_intexc (t_uint64 vec, t_uint64 arg); -t_stat unix_mm_intexc (t_uint64 par1, t_uint64 par2); -t_stat pal_proc_reset_unix (DEVICE *dptr); -uint32 pal_find_pte_unix (uint32 vpn, t_uint64 *l3pte); - -extern t_stat (*pal_eval_intr) (uint32 ipl); -extern t_stat (*pal_proc_excp) (uint32 type); -extern t_stat (*pal_proc_trap) (uint32 type); -extern t_stat (*pal_proc_intr) (uint32 type); -extern t_stat (*pal_proc_inst) (uint32 fnc); -extern uint32 (*pal_find_pte) (uint32 vpn, t_uint64 *pte); -extern uint32 Test (t_uint64 va, uint32 acc, t_uint64 *pa); - -/* UNIXPAL data structures - - unixpal_dev device descriptor - unixpal_unit unit - unixpal_reg register list -*/ - -UNIT unixpal_unit = { UDATA (NULL, 0, 0) }; - -REG unixpal_reg[] = { - { HRDATA (KSP, ksp, 64) }, - { HRDATA (USP, usp, 64) }, - { HRDATA (ENTARITH, entArith, 64) }, - { HRDATA (ENTIF, entIF, 64) }, - { HRDATA (ENTINT, entInt, 64) }, - { HRDATA (ENTMM, entMM, 64) }, - { HRDATA (ENTSYS, entSys, 64) }, - { HRDATA (ENTUNA, entUna, 64) }, - { HRDATA (KGP, unix_kgp, 64) }, - { HRDATA (PTPTR, unix_ptptr, 64) }, - { HRDATA (VPTPTR, unix_vptptr, 64) }, - { HRDATA (VIRBND, unix_virbnd, 64) }, - { HRDATA (SYSPTBR, unix_sysptbr, 64) }, - { HRDATA (UNIQUE, unix_unique, 64) }, - { HRDATA (SYSVAL, unix_sysval, 64) }, - { HRDATA (HWPCB, unix_hwpcb, 64) }, - { HRDATA (MCES, unix_mces, 64) }, - { HRDATA (IPL, unix_ipl, 3) }, - { HRDATA (CM, unix_cm, 0) }, - { NULL } - }; - -DEVICE unixpal_dev = { - "UNIXPAL", &unixpal_unit, unixpal_reg, NULL, - 1, 16, 1, 1, 16, 8, - NULL, NULL, &pal_proc_reset_unix, - NULL, NULL, NULL, - NULL, DEV_DIS - }; - -/* Unix interrupt evaluator - returns IPL of highest priority interrupt */ - -uint32 pal_eval_intr_unix (uint32 lvl) -{ -uint32 i; -uint32 mipl = map_ipl[lvl & PSU_M_IPL]; - -for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */ - if (i <= mipl) return 0; /* at ipl? no int */ - if (int_req[i - IPL_HMIN]) return i; /* req != 0? int */ - } -return 0; -} - -/* Unix interrupt dispatch - reached from top of execute loop */ - -t_stat pal_proc_intr_unix (uint32 lvl) -{ -t_stat r; - -if (lvl > IPL_HMAX) return SCPE_IERR; /* above max? */ -else if (lvl >= IPL_HMIN) a1 = io_get_vec (lvl); /* hwre? get vector */ -else return SCPE_IERR; /* bug */ -r = unix_intexc (entInt, UNIX_INT_IO); /* do interrupt */ -if (a1 == SCB_CLOCK) a0 = UNIX_INT_CLK; -if (a1 == SCB_IPIR) a0 = UNIX_INT_IPIR; -unix_ipl = lvl; -return r; -} - -/* Unix trap dispatch - reached synchronously from bottom of execute loop */ - -t_stat pal_proc_trap_unix (uint32 tsum) -{ -t_stat r; - -r = unix_intexc (entArith, tsum); /* arithmetic trap */ -a1 = trap_mask; /* set parameter */ -return r; -} - -/* Unix exception dispatch - reached from the ABORT handler */ - -t_stat pal_proc_excp_unix (uint32 abval) -{ -t_stat r; - -switch (abval) { - - case EXC_RSVI: /* reserved instruction */ - return unix_intexc (entIF, UNIX_IF_RSVI); /* trap */ - - case EXC_RSVO: /* reserved operand */ - return unix_intexc (entIF, UNIX_IF_RSVI); /* trap */ - - case EXC_ALIGN: /* unaligned */ - PC = (PC - 4) & M64; /* back up PC */ - r = unix_intexc (entUna, PC); /* fault */ - a1 = I_GETOP (ir); /* get opcode */ - a2 = I_GETRA (ir); /* get ra */ - return r; - - case EXC_FPDIS: /* fp disabled */ - PC = (PC - 4) & M64; /* backup PC */ - return unix_intexc (entIF, UNIX_IF_FDIS); /* fault */ - - case EXC_FOX+EXC_E: /* FOE */ - tlb_is (p1, TLB_CI); - return unix_mm_intexc (UNIX_MMCSR_FOE, UNIX_MME_E); - - case EXC_FOX+EXC_R: /* FOR */ - PC = (PC - 4) & M64; /* back up PC */ - return unix_mm_intexc (UNIX_MMCSR_FOR, UNIX_MME_R); - - case EXC_FOX+EXC_W: /* FOW */ - PC = (PC - 4) & M64; /* back up PC */ - return unix_mm_intexc (UNIX_MMCSR_FOW, UNIX_MME_W); - - case EXC_BVA+EXC_E: - case EXC_ACV+EXC_E: /* instr ACV */ - return unix_mm_intexc (UNIX_MMCSR_ACV, UNIX_MME_E); - - case EXC_BVA+EXC_R: - case EXC_ACV+EXC_R: /* data read ACV */ - PC = (PC - 4) & M64; /* back up PC */ - return unix_mm_intexc (UNIX_MMCSR_ACV, UNIX_MME_R); - - case EXC_BVA+EXC_W: - case EXC_ACV+EXC_W: /* data write ACV */ - PC = (PC - 4) & M64; /* back up PC */ - return unix_mm_intexc (UNIX_MMCSR_ACV, UNIX_MME_W); - - case EXC_TNV+EXC_E: /* instr TNV */ - tlb_is (p1, TLB_CI); - return unix_mm_intexc (UNIX_MMCSR_TNV, UNIX_MME_E); - - case EXC_TNV+EXC_R: /* data read TNV */ - tlb_is (p1, TLB_CD); - PC = (PC - 4) & M64; /* back up PC */ - return unix_mm_intexc (UNIX_MMCSR_TNV, UNIX_MME_R); - - case EXC_TNV+EXC_W: /* data write TNV */ - tlb_is (p1, TLB_CD); - PC = (PC - 4) & M64; /* back up PC */ - return unix_mm_intexc (UNIX_MMCSR_TNV, UNIX_MME_W); - - case EXC_TBM + EXC_E: /* TLB miss */ - case EXC_TBM + EXC_R: - case EXC_TBM + EXC_W: - return SCPE_IERR; /* should not occur */ - - default: - return STOP_INVABO; - } -return SCPE_OK; -} - -/* PALcode instruction dispatcher - function code verified in CPU */ - -t_stat pal_proc_inst_unix (uint32 fnc) -{ -uint32 arg32 = (uint32) a0; - -if ((fnc < 0x40) && (unix_cm != MODE_K)) ABORT (EXC_RSVI); -switch (fnc) { - - case OP_halt: - return STOP_HALT; - - case OP_cflush: - case OP_draina: - break; - - case OP_cserve: - //tbd - break; - - case OP_swppal: - v0 = 0; - break; - - case OP_rdmces: - v0 = unix_mces; - break; - - case OP_wrmces: - unix_mces = (unix_mces | (arg32 & MCES_DIS)) & ~(arg32 & MCES_W1C); - break; - - case OP_wrvirbnd: - unix_virbnd = a0; - break; - - case OP_wrsysptbr: - unix_sysptbr = a0; - break; - - case OP_wrfen: - fpen = arg32 & 1; - arg32 = ReadPL (unix_hwpcb + PCBU_FLAGS); - arg32 = (arg32 & ~1) | fpen; - WritePL (unix_hwpcb + PCBU_FLAGS, arg32); - break; - - case OP_wrvptptr: - unix_vptptr = a0; - break; - - case OP_wrasn: - itlb_set_asn (arg32 & M16); - dtlb_set_asn (arg32 & M16); - WritePL (unix_hwpcb + 28, arg32 & M16); - break; - - case OP_swpctx: - unix_swpctx (); - break; - - case OP_wrval: - unix_sysval = a0; - break; - - case OP_rdval: - v0 = unix_sysval; - break; - - case OP_tbi: - switch (a0 + 2) { - case 0: /* -2 = tbia */ - tlb_ia (TLB_CI | TLB_CD | TLB_CA); - break; - case 1: /* -1 = tbiap */ - tlb_ia (TLB_CI | TLB_CD); - break; - case 3: /* +1 = tbis */ - tlb_is (a1, TLB_CI | TLB_CD); - break; - case 4: /* +2 = tbisd */ - tlb_is (a1, TLB_CD); - break; - case 5: /* +3 = tbisi */ - tlb_is (a1, TLB_CI); - break; - default: - break; - } - break; - - case OP_wrent: - if (a0 <= 5) unix_entVec[arg32] = a0; - break; - - case OP_swpipl: - v0 = unix_ipl; - unix_ipl = arg32 & PSU_M_IPL; - break; - - case OP_rdps: - v0 = GET_PSU; - break; - - case OP_wrkgp: - unix_kgp = a0; - break; - - case OP_wrusp: - usp = a0; - break; - - case OP_wrperfmon: - // tbd - break; - - case OP_rdusp: - v0 = usp; - break; - - case OP_whami: - v0 = 0; - break; - - case OP_retsys: - unix_retsys (); - break; - - case OP_wtint: - v0 = 0; - break; - - case OP_rti: - unix_rti (); - break; - -/* Non-privileged */ - - case OP_bpt: - return unix_intexc (entIF, UNIX_IF_BPT); - - case OP_bugchk: - return unix_intexc (entIF, UNIX_IF_BUG); - - case OP_syscall: - if (unix_cm == MODE_K) { - //tbd - } - return unix_syscall (); - - case OP_imb: - break; - - case OP_urti: - if (unix_cm == MODE_K) { - //tbd - } - unix_urti (); - break; - - case OP_rdunique: - v0 = unix_unique; - break; - - case OP_wrunique: - unix_unique = a0; - break; - - case OP_gentrap: - return unix_intexc (entIF, UNIX_IF_GEN); - - case OP_clrfen: - fpen = 0; - arg32 = ReadPL (unix_hwpcb + PCBU_FLAGS); - arg32 = arg32 & ~1; - WritePL (unix_hwpcb + PCBU_FLAGS, arg32); - break; - - default: - ABORT (EXC_RSVI); - } - -return SCPE_OK; -} - -/* Swap privileged context */ - -void unix_swpctx (void) -{ -t_uint64 val; -uint32 tmp1; - -WritePQ (unix_hwpcb + 0, SP); /* save stack ptrs */ -WritePQ (unix_hwpcb + 8, usp); -tmp1 = (pcc_h + pcc_l) & M32; /* elapsed time */ -WritePL (unix_hwpcb + 24, tmp1); /* save PCC */ -WritePQ (unix_hwpcb + 32, unix_unique); /* save unique */ -v0 = unix_hwpcb; /* return curr PCBB */ -unix_hwpcb = a0; /* new PCBB */ -SP = ksp = ReadPQ (unix_hwpcb + 0); /* read stack ptrs */ -usp = ReadPQ (unix_hwpcb + 8); -val = ReadPQ (unix_hwpcb + 16) << VA_N_OFF; /* read new PTBR */ -if (val != unix_ptptr) tlb_ia (TLB_CI | TLB_CD); /* ptbr change? zap TLB */ -unix_ptptr = val; -tmp1 = ReadPL (unix_hwpcb + 24); /* restore PCC */ -pcc_h = (tmp1 - pcc_l) & M32; -tmp1 = ReadPL (unix_hwpcb + 28) & M16; /* read ASN */ -itlb_set_asn (tmp1); -dtlb_set_asn (tmp1); -unix_unique = ReadPQ (unix_hwpcb + 32); /* read unique */ -fpen = ReadPL (unix_hwpcb + PCBU_FLAGS) & 1; /* read FEN */ -return; -} - -/* Unix interrupt or exception - always to kernel mode - - Inputs: - vec = entry vector - arg = argument for a0 - Outputs: - reason = possible processor halt -*/ - -t_stat unix_intexc (t_uint64 vec, t_uint64 arg) -{ -t_uint64 sav_ps = GET_PSU; /* old PS */ - -if ((unix_cm & PSU_M_CM) != MODE_K) { /* not kernel? */ - usp = SP; /* save SP */ - SP = ksp; /* load new SP */ - unix_cm = mmu_set_cm (MODE_K); /* PS = 0 */ - unix_ipl = 0; - } -SP = (SP - UNIX_L_STKF) & M64; /* decr stack */ -if (Test (SP, cm_wacc, NULL)) return STOP_KSNV; /* validate writes */ -if (Test (SP + UNIX_L_STKF - 8, cm_wacc, NULL) < 0) return STOP_KSNV; -WriteQ (SP, sav_ps); /* save PS, PC, gp */ -WriteQ (SP + 8, PC); -WriteQ (SP + 16, gp); -WriteQ (SP + 24, a0); /* save a0-a2 */ -WriteQ (SP + 32, a1); -WriteQ (SP + 40, a2); -PC = vec; /* new PC */ -gp = unix_kgp; /* kernel GP */ -a0 = arg; /* argument */ -return SCPE_OK; -} - -/* Memory management fault */ - -t_stat unix_mm_intexc (t_uint64 par1, t_uint64 par2) -{ -t_stat r; - -r = unix_intexc (entMM, p1); /* do exception */ -a1 = par1; /* set arguments */ -a2 = par2; -tlb_is (p1, TLB_CI | TLB_CD); /* zap TLB entry */ -return r; -} - -/* System call - always user to kernel, abbreviated stack frame, no arguments */ - -t_stat unix_syscall (void) -{ -t_uint64 sav_ps = GET_PSU; /* save PS */ - -usp = SP; /* save user SP */ -SP = ksp; /* load kernel SP */ -unix_cm = mmu_set_cm (MODE_K); /* PS = 0 */ -unix_ipl = 0; -SP = (SP - UNIX_L_STKF) & M64; /* decr stack */ -if (Test (SP, cm_wacc, NULL)) return STOP_KSNV; /* validate writes */ -if (Test (SP + UNIX_L_STKF - 8, cm_wacc, NULL)) return STOP_KSNV; -WriteQ (SP, sav_ps); /* save PS, PC, gp */ -WriteQ (SP + 8, PC); -WriteQ (SP + 16, gp); -PC = entSys; /* new PC */ -gp = unix_kgp; /* kernel GP */ -return SCPE_OK; -} - -/* Return from trap or interrupt - always from kernel */ - -t_stat unix_rti (void) -{ -t_uint64 tpc; -uint32 tps, newm; - -if (Test (SP, cm_racc, NULL)) return STOP_KSNV; /* validate reads */ -if (Test (SP + UNIX_L_STKF - 8, cm_racc, NULL)) return STOP_KSNV; -tps = (uint32) ReadQ (SP); /* read PS, PC */ -tpc = ReadQ (SP + 8); -gp = ReadQ (SP + 16); /* restore gp, a0-a2 */ -a0 = ReadQ (SP + 24); -a1 = ReadQ (SP + 32); -a2 = ReadQ (SP + 40); -SP = (SP + UNIX_L_STKF); /* incr stack */ -newm = (tps >> PSU_V_CM) & PSU_M_CM; -unix_cm = mmu_set_cm (newm); /* new current mode */ -if (newm) { /* to user? */ - ksp = SP; /* save kernel stack */ - SP = usp; /* load user stack */ - unix_ipl = 0; /* ipl = 0 */ - } -else unix_ipl = (tps >> PSU_V_IPL) & PSU_V_IPL; /* restore ipl */ -PC = tpc; /* restore PC */ -vax_flag = 0; /* clear VAX, lock flags */ -lock_flag = 0; -return SCPE_OK; -} - -/* Return from system call - always from kernel to user */ - -t_stat unix_retsys (void) -{ -t_uint64 tpc; - -if (Test (SP + 8, cm_racc, NULL)) return STOP_KSNV; /* validate reads */ -if (Test (SP + 16, cm_racc, NULL)) return STOP_KSNV; -tpc = ReadQ (SP + 8); /* read PC */ -gp = ReadQ (SP + 16); /* restore GP */ -ksp = (SP + UNIX_L_STKF); /* update kernel stack */ -SP = usp; /* restore user stack */ -unix_cm = mmu_set_cm (MODE_E); /* PS = 8 */ -unix_ipl = 0; -PC = tpc; /* restore PC */ -vax_flag = 0; /* clear VAX, lock flags */ -lock_flag = 0; -return SCPE_OK; -} - -/* Return from user mode trap - always from user to user */ - -void unix_urti (void) -{ -t_uint64 tsp, tpc; -uint32 tps; - -if (SP & 0x3F) ABORT (EXC_RSVO); /* not aligned? */ -tps = ReadL (SP + 16); /* read PS */ -if (!(tps & PSU_CM) || (tps & PSU_IPL)) ABORT (EXC_RSVO); -at = ReadQ (SP + 0); /* restore at */ -tsp = ReadQ (SP + 8); /* read SP, PC */ -tpc = ReadQ (SP + 24); -gp = ReadQ (SP + 32); /* restore gp, a0-a2 */ -a0 = ReadQ (SP + 40); -a1 = ReadQ (SP + 48); -a2 = ReadQ (SP + 56); -SP = tsp; /* restore SP */ -PC = tpc; /* restore PC */ -vax_flag = 0; /* clear VAX, lock flags */ -lock_flag = 0; -return; -} - -/* Unix 3-level PTE lookup - - Inputs: - vpn = virtual page number (30b, sext) - *pte = pointer to pte to be returned - Output: - status = 0 for successful fill - EXC_ACV for ACV on intermediate level - EXC_TNV for TNV on intermediate level -*/ - -uint32 pal_find_pte_unix (uint32 vpn, t_uint64 *l3pte) -{ -t_uint64 vptea, l1ptea, l2ptea, l3ptea, l1pte, l2pte; -uint32 vpte_vpn; -TLBENT *vpte_p; - -vptea = unix_vptptr | (((t_uint64) (vpn & VA_M_VPN)) << 3); /* try virtual lookup */ -vpte_vpn = VA_GETVPN (vptea); /* get vpte vpn */ -vpte_p = dtlb_lookup (vpte_vpn); /* get vpte tlb ptr */ -if (vpte_p && ((vpte_p->pte & (PTE_KRE|PTE_V)) == (PTE_KRE|PTE_V))) - l3ptea = vpte_p->pfn | VA_GETOFF (vptea); -else { - l1ptea = unix_ptptr + VPN_GETLVL1 (vpn); - l1pte = ReadPQ (l1ptea); - if ((l1pte & PTE_V) == 0) - return ((l1pte & PTE_KRE)? EXC_TNV: EXC_ACV); - l2ptea = (l1pte & PFN_MASK) >> (PTE_V_PFN - VA_N_OFF); - l2ptea = l2ptea + VPN_GETLVL2 (vpn); - l2pte = ReadPQ (l2ptea); - if ((l2pte & PTE_V) == 0) - return ((l2pte & PTE_KRE)? EXC_TNV: EXC_ACV); - l3ptea = (l2pte & PFN_MASK) >> (PTE_V_PFN - VA_N_OFF); - l3ptea = l3ptea + VPN_GETLVL3 (vpn); - } -*l3pte = ReadPQ (l3ptea); -return 0; -} - -/* Unix PALcode reset */ - -t_stat pal_proc_reset_unix (DEVICE *dptr) -{ -mmu_ispage = mmu_dspage = SPEN_43; -unix_ipl = PSU_M_IPL; -unix_cm = mmu_set_cm (MODE_K); -pcc_enb = 1; -pal_eval_intr = &pal_eval_intr_unix; -pal_proc_intr = &pal_proc_intr_unix; -pal_proc_trap = &pal_proc_trap_unix; -pal_proc_excp = &pal_proc_excp_unix; -pal_proc_inst = &pal_proc_inst_unix; -pal_find_pte = &pal_find_pte_unix; -return SCPE_OK; -} diff --git a/alpha/old_pal/alpha_pal_vms.c b/alpha/old_pal/alpha_pal_vms.c deleted file mode 100644 index df0612da..00000000 --- a/alpha/old_pal/alpha_pal_vms.c +++ /dev/null @@ -1,1780 +0,0 @@ -/* alpha_pal_vms.c - Alpha VMS PAL code simulator - - Copyright (c) 2003-2005, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - This module contains the PALcode implementation for Alpha VMS, except for - the console, which is always done in hardware mode. - - Alpha VMS requires a complex privileged state, modelled after the VAX: - - PS<12:0> processor status - IPL<4:0> interrupt level - in base - VMM<0> virtual machine mode - CM<1:0> current mode - in base - IP<0> interrupt in progress - SW<1:0> software controlled - KSP<63:0> kernel stack pointer - ESP<63:0> executive stack pointer - SSP<63:0> supervisor stack pointer - USP<63:0> user stack pointer - SSC<63:0> system cycle counter - PCBB<63:0> process control block base - SCBB<63:0> system control block base - PTBR<63:0> page table base - VTBR<63:0> virtual page table base - VIRBND<63:0> virtual address boundary - SYSPTBR<63:0> system page table base register - PRBR<63:0> processor base register - THREAD<63:0> thread-unique value - SIRR<15:1> software interrupt requests - ASTEN<3:0> AST enables - ASTRQ<3:0> AST requests - FEN<0> floating enable - DATFX<0> data alignment trap enable - - Note that some of this state exists in the hardware implementations and - so is declared in the base CPU. -*/ - -#include "alpha_defs.h" - -/* Alignment table */ - -#define ALG_W 1 /* word inst */ -#define ALG_L 2 /* long inst */ -#define ALG_Q 3 /* quad inst */ -#define ALG_ST 0x10 /* store */ -#define ALG_INV -1 /* invalid inst */ -#define ALG_ERR 0 /* internal error */ -#define ALG_GETLNT(x) ((x) & 3) - -#define GET_PSV ((vms_ipl << PSV_V_IPL) | (vms_cm << PSV_V_CM) | \ - (vms_ps & PSV_MASK)) -#define AST_TST(l) (((l) < IPL_AST) && (vms_asten & vms_astsr & ast_map[vms_cm])) -#define MOST_PRIV(m1,m2) (((m1) < (m2))? (m1): (m2)) - -#define ksp vms_stkp[MODE_K] -#define esp vms_stkp[MODE_E] -#define ssp vms_stkp[MODE_S] -#define usp vms_stkp[MODE_U] - -// kludge for debugging... -#define io_get_vec(x) 0 - -t_uint64 vms_ptbr = 0; /* page table base */ -t_uint64 vms_vtbr = 0; /* virt page table base */ -t_uint64 vms_virbnd = M64; /* virtual boundary */ -t_uint64 vms_sysptbr = 0; /* system page table base */ -t_uint64 vms_hwpcb = 0; /* hardware PCB */ -t_uint64 vms_thread = 0; /* thread unique */ -t_uint64 vms_prbr = 0; /* processor unique */ -t_uint64 vms_stkp[4]; /* stack pointers */ -t_uint64 vms_scbb = 0; /* SCB base */ -t_uint64 vms_scc = 0; /* system cycle ctr */ -t_uint64 vms_mces = 0; /* machine check err summ */ -uint32 vms_ipl = 0; /* hardware IPL */ -uint32 vms_cm = 0; /* inst current mode */ -uint32 vms_sisr = 0; /* software int req */ -uint32 vms_asten = 0; /* AST enables */ -uint32 vms_astsr = 0; /* AST requests */ -uint32 vms_last_pcc = 0; /* last pcc_l */ -uint32 vms_datfx = 0; /* data alignment */ -uint32 vms_ps = 0; /* static PS */ - -const uint32 ast_map[4] = { 0x1, 0x3, 0x7, 0xF }; -const uint32 ast_pri[16] = { - 0, MODE_K, MODE_E, MODE_K, MODE_S, MODE_K, MODE_E, MODE_K, - MODE_U, MODE_K, MODE_E, MODE_K, MODE_S, MODE_K, MODE_E, MODE_K - }; -static const uint32 lnt_map[4] = { L_BYTE, L_WORD, L_LONG, L_QUAD }; -static const int8 alg_map[64] = { - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_W, ALG_W|ALG_ST, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_L, ALG_Q, ALG_L, ALG_Q, - ALG_L|ALG_ST, ALG_Q|ALG_ST, ALG_L|ALG_ST, ALG_Q|ALG_ST, - ALG_L, ALG_Q, ALG_INV, ALG_INV, - ALG_L|ALG_ST, ALG_Q|ALG_ST, ALG_INV, ALG_INV, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR, - ALG_ERR, ALG_ERR, ALG_ERR, ALG_ERR - }; - -extern t_uint64 R[32]; -extern t_uint64 PC, trap_mask; -extern t_uint64 p1; -extern uint32 vax_flag, lock_flag; -extern uint32 fpen; -extern uint32 ir, pcc_h, pcc_l, pcc_enb; -extern uint32 cm_racc, cm_wacc, cm_macc; -extern uint32 mmu_ispage, mmu_dspage; -extern jmp_buf save_env; -extern uint32 int_req[IPL_HLVL]; - -t_int64 vms_insqhil (void); -t_int64 vms_insqtil (void); -t_int64 vms_insqhiq (void); -t_int64 vms_insqtiq (void); -t_int64 vms_insquel (uint32 defer); -t_int64 vms_insqueq (uint32 defer); -t_int64 vms_remqhil (void); -t_int64 vms_remqtil (void); -t_int64 vms_remqhiq (void); -t_int64 vms_remqtiq (void); -t_int64 vms_remquel (uint32 defer); -t_int64 vms_remqueq (uint32 defer); -t_int64 vms_insqhilr (void); -t_int64 vms_insqtilr (void); -t_int64 vms_insqhiqr (void); -t_int64 vms_insqtiqr (void); -t_int64 vms_remqhilr (void); -t_int64 vms_remqtilr (void); -t_int64 vms_remqhiqr (void); -t_int64 vms_remqtiqr (void); -uint32 vms_probe (uint32 acc); -uint32 vms_amovrr (void); -uint32 vms_amovrm (void); -t_stat vms_rei (void); -void vms_swpctx (void); -t_stat vms_intexc (uint32 vec, uint32 newmode, uint32 newipl); -t_stat vms_mm_intexc (uint32 vec, t_uint64 par2); -t_stat pal_proc_reset_vms (DEVICE *dptr); -t_uint64 ReadUna (t_uint64 va, uint32 lnt, uint32 acc); -void WriteUna (t_uint64 va, t_uint64 val, uint32 lnt, uint32 acc); -uint32 tlb_check (t_uint64 va); -uint32 Test (t_uint64 va, uint32 acc, t_uint64 *pa); - -extern t_stat (*pal_eval_intr) (uint32 ipl); -extern t_stat (*pal_proc_excp) (uint32 type); -extern t_stat (*pal_proc_trap) (uint32 type); -extern t_stat (*pal_proc_intr) (uint32 type); -extern t_stat (*pal_proc_inst) (uint32 fnc); -extern uint32 (*pal_find_pte) (uint32 vpn, t_uint64 *pte); - -/* VMSPAL data structures - - vmspal_dev device descriptor - vmspal_unit unit - vmspal_reg register list -*/ - -UNIT vmspal_unit = { UDATA (NULL, 0, 0) }; - -REG vmspal_reg[] = { - { HRDATA (KSP, ksp, 64) }, - { HRDATA (ESP, esp, 64) }, - { HRDATA (SSP, ssp, 64) }, - { HRDATA (USP, usp, 64) }, - { HRDATA (PTBR, vms_ptbr, 64) }, - { HRDATA (VTBR, vms_vtbr, 64) }, - { HRDATA (VIRBND, vms_virbnd, 64) }, - { HRDATA (SYSPTBR, vms_sysptbr, 64) }, - { HRDATA (THREAD, vms_thread, 64) }, - { HRDATA (PRBR, vms_prbr, 64) }, - { HRDATA (HWPCB, vms_hwpcb, 64) }, - { HRDATA (SCBB, vms_scbb, 64) }, - { HRDATA (SCC, vms_scc, 64) }, - { HRDATA (LASTPCC, vms_last_pcc, 32), REG_HRO }, - { HRDATA (MCES, vms_mces, 64) }, - { HRDATA (PS, vms_ps, 13) }, - { HRDATA (IPL, vms_ipl, 5) }, - { HRDATA (CM, vms_cm, 2) }, - { HRDATA (SISR, vms_sisr, 16) }, - { HRDATA (ASTEN, vms_asten, 4) }, - { HRDATA (ASTSR, vms_astsr, 4) }, - { FLDATA (DATFX, vms_datfx, 0) }, - { NULL } - }; - -DEVICE vmspal_dev = { - "VMSPAL", &vmspal_unit, vmspal_reg, NULL, - 1, 16, 1, 1, 16, 8, - NULL, NULL, &pal_proc_reset_vms, - NULL, NULL, NULL, - NULL, 0 - }; - -/* VMS interrupt evaluator - returns IPL of highest priority interrupt */ - -uint32 pal_eval_intr_vms (uint32 lvl) -{ -uint32 i; -static const int32 sw_int_mask[32] = { - 0xFFFE, 0xFFFC, 0xFFF8, 0xFFF0, /* 0 - 3 */ - 0xFFE0, 0xFFC0, 0xFF80, 0xFF00, /* 4 - 7 */ - 0xFE00, 0xFC00, 0xF800, 0xF000, /* 8 - B */ - 0xE000, 0xC000, 0x8000, 0x0000, /* C - F */ - 0x0000, 0x0000, 0x0000, 0x0000, /* 10+ */ - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000 - }; - -vms_scc = vms_scc + ((pcc_l - vms_last_pcc) & M32); /* update scc */ -vms_last_pcc = pcc_l; -for (i = IPL_HMAX; i >= IPL_HMIN; i--) { /* chk hwre int */ - if (i <= lvl) return 0; /* at ipl? no int */ - if (int_req[i - IPL_HMIN]) return i; /* req != 0? int */ - } -if (vms_sisr & sw_int_mask[lvl]) { /* swre interrupt? */ - for (i = IPL_SMAX; i > lvl; i--) { /* check swre int */ - if ((vms_sisr >> i) & 1) /* req != 0? int */ - return (AST_TST (i)? IPL_AST: i); /* check for AST */ - } - } -return (AST_TST (lvl)? IPL_AST: 0); /* no swre, check AST */ -} - -/* VMS interrupt dispatch - reached from top of execute loop */ - -t_stat pal_proc_intr_vms (uint32 lvl) -{ -uint32 vec; -t_stat r; - -if (lvl > IPL_HMAX) return SCPE_IERR; /* above max? */ -else if (lvl >= IPL_HMIN) vec = io_get_vec (lvl); /* hwre? get vector */ -else if (lvl > IPL_SMAX) return SCPE_IERR; /* above swre max? */ -else if (lvl > 0) { /* swre int? */ - if ((lvl == IPL_AST) && (vms_asten & vms_astsr & ast_map[vms_cm])) { - uint32 astm = ast_pri[vms_astsr & 0xF]; /* get AST priority */ - vms_astsr = vms_astsr & ~(1u << astm); /* clear hi pri */ - vec = SCB_KAST + (astm << 4); - } - else { /* swre int */ - vms_sisr = vms_sisr & ~(1u << lvl); - vec = SCB_SISR0 + (lvl << 4); - } - } -else return SCPE_IERR; /* bug */ -if (vec == 0) vec = SCB_PASVR; /* passive release? */ -r = vms_intexc (vec, MODE_K, lvl); /* do interrupt */ -vms_ps = vms_ps | PSV_IP; /* set int in prog */ -return r; -} - -/* VMS trap dispatch - reached synchronously from bottom of execute loop */ - -t_stat pal_proc_trap_vms (uint32 tsum) -{ -t_stat r; - -r = vms_intexc (SCB_ARITH, MODE_K, vms_ipl); /* arithmetic trap */ -R[4] = trap_mask; /* set parameters */ -R[5] = tsum; -return r; -} - -/* VMS exception dispatch - reached from the ABORT handler */ - -t_stat pal_proc_excp_vms (uint32 abval) -{ -uint32 op, ra, lntc; -int8 fl; -t_stat r; - -switch (abval) { - - case EXC_RSVI: /* reserved instr */ - return vms_intexc (SCB_RSVI, MODE_K, vms_ipl); /* trap */ - - case EXC_RSVO: /* reserved operand */ - return vms_intexc (SCB_RSVO, MODE_K, vms_ipl); /* trap */ - - case EXC_ALIGN: /* unaligned */ - op = I_GETOP (ir); /* get opcode */ - ra = I_GETRA (ir); /* get RA */ - fl = alg_map[op]; /* get alignment map */ - if (fl == ALG_ERR) return SCPE_IERR; /* impossible? */ - if (fl == ALG_INV) return (SCB_RSVI, MODE_K, vms_ipl); /* conditional? */ - lntc = ALG_GETLNT (fl); /* get length code */ - if (fl & ALG_ST) /* store? */ - WriteUna (p1, R[ra], lnt_map[lntc], cm_wacc); - else if (ra != 31) - R[ra] = ReadUna (p1, lnt_map[lntc], cm_racc); - if (vms_datfx) break; /* trap? */ - r = vms_intexc (SCB_ALIGN, MODE_K, vms_ipl); /* do trap */ - R[4] = p1; /* R4 = va */ - R[5] = (fl & ALG_ST)? 1: 0; /* R5 = load/store */ - return r; - - case EXC_FPDIS: /* fp disabled */ - PC = (PC - 4) & M64; /* back up PC */ - return vms_intexc (SCB_FDIS, MODE_K, vms_ipl); /* fault */ - - case EXC_FOX+EXC_E: /* FOE */ - tlb_is (p1, TLB_CI); - return vms_mm_intexc (SCB_FOE, VMS_MME_E); - - case EXC_FOX+EXC_R: /* FOR */ - PC = (PC - 4) & M64; /* back up PC */ - return vms_mm_intexc (SCB_FOR, VMS_MME_R); - - case EXC_FOX+EXC_W: /* FOW */ - PC = (PC - 4) & M64; /* back up PC */ - return vms_mm_intexc (SCB_FOW, VMS_MME_W); - - case EXC_BVA+EXC_E: - case EXC_ACV+EXC_E: /* instr ACV */ - return vms_mm_intexc (SCB_ACV, VMS_MME_E); - - case EXC_BVA+EXC_R: - case EXC_ACV+EXC_R: /* data read ACV */ - PC = (PC - 4) & M64; /* back up PC */ - return vms_mm_intexc (SCB_ACV, VMS_MME_R); - - case EXC_BVA+EXC_W: - case EXC_ACV+EXC_W: /* data write ACV */ - PC = (PC - 4) & M64; /* back up PC */ - return vms_mm_intexc (SCB_ACV, VMS_MME_W); - - case EXC_TNV+EXC_E: /* instr TNV */ - tlb_is (p1, TLB_CI); - return vms_mm_intexc (SCB_TNV, VMS_MME_E); - - case EXC_TNV+EXC_R: /* data read TNV */ - tlb_is (p1, TLB_CD); - PC = (PC - 4) & M64; /* back up PC */ - return vms_mm_intexc (SCB_TNV, VMS_MME_R); - - case EXC_TNV+EXC_W: /* data write TNV */ - tlb_is (p1, TLB_CD); - PC = (PC - 4) & M64; /* back up PC */ - return vms_mm_intexc (SCB_TNV, VMS_MME_W); - - case EXC_TBM + EXC_E: /* TLB miss */ - case EXC_TBM + EXC_R: - case EXC_TBM + EXC_W: - return SCPE_IERR; /* should not occur */ - - default: - return STOP_INVABO; - } - -return SCPE_OK; -} - -/* PALcode instruction dispatcher - function code verified in CPU */ - -t_stat pal_proc_inst_vms (uint32 fnc) -{ -t_uint64 val; -uint32 arg32 = (uint32) R[16]; - -if ((fnc < 0x40) && (vms_cm != MODE_K)) ABORT (EXC_RSVI); -switch (fnc) { - - case OP_HALT: - return STOP_HALT; - - case OP_CFLUSH: - case OP_DRAINA: - break; - - case OP_LDQP: - R[0] = ReadPQ (R[16]); - break; - - case OP_STQP: - WritePQ (R[16], R[17]); - break; - - case OP_SWPCTX: - vms_swpctx (); - break; - - case MF_ASN: - R[0] = itlb_read_asn (); - break; - - case MT_ASTEN: - R[0] = vms_asten & AST_MASK; - vms_asten = ((vms_asten & arg32) | (arg32 >> 4)) & AST_MASK; - break; - - case MT_ASTSR: - R[0] = vms_astsr & AST_MASK; - vms_astsr = ((vms_astsr & arg32) | (arg32 >> 4)) & AST_MASK; - break; - - case OP_CSERVE: - // tbd - break; - - case OP_SWPPAL: - R[0] = 0; - break; - - case MF_FEN: - R[0] = fpen & 1; - break; - - case MT_FEN: - fpen = arg32 & 1; - arg32 = ReadPL (vms_hwpcb + PCBV_FLAGS); - arg32 = (arg32 & ~1) | fpen; - WritePL (vms_hwpcb + PCBV_FLAGS, arg32); - break; - - case MT_IPIR: - //tbd - break; - - case MF_IPL: - R[0] = vms_ipl & PSV_M_IPL; - break; - - case MT_IPL: - R[0] = vms_ipl & PSV_M_IPL; - vms_ipl = arg32 & PSV_M_IPL; - break; - - case MF_MCES: - R[0] = vms_mces; - break; - - case MT_MCES: - vms_mces = (vms_mces | (arg32 & MCES_DIS)) & ~(arg32 & MCES_W1C); - break; - - case MF_PCBB: - R[0] = vms_hwpcb; - break; - - case MF_PRBR: - R[0] = vms_prbr; - break; - - case MT_PRBR: - vms_prbr = R[16]; - break; - - case MF_PTBR: - R[0] = (vms_ptbr >> VA_N_OFF); /* PFN only */ - break; - - case MF_SCBB: - R[0] = vms_scbb; - break; - - case MT_SCBB: - vms_scbb = R[16]; - break; - - case MF_SISR: - R[0] = vms_sisr & SISR_MASK; - break; - - case MT_SIRR: - vms_sisr = (vms_sisr | (1u << (arg32 & 0xF))) & SISR_MASK; - break; - - case MF_TBCHK: - if (tlb_check (R[16])) R[0] = Q_SIGN + 1; - else R[0] = Q_SIGN; - break; - - case MT_TBIA: - tlb_ia (TLB_CI | TLB_CD | TLB_CA); - break; - - case MT_TBIAP: - tlb_ia (TLB_CI | TLB_CD); - break; - - case MT_TBIS: - tlb_is (R[16], TLB_CI | TLB_CD | TLB_CA); - break; - - case MF_ESP: - R[0] = esp; - break; - - case MT_ESP: - esp = R[16]; - break; - - case MF_SSP: - R[0] = ssp; - break; - - case MT_SSP: - ssp = R[16]; - break; - - case MF_USP: - R[0] = usp; - break; - - case MT_USP: - usp = R[16]; - break; - - case MT_TBISI: - tlb_is (R[16], TLB_CI | TLB_CA); - break; - - case MT_TBISD: - tlb_is (R[16], TLB_CD | TLB_CA); - break; - - case MF_ASTEN: - R[0] = vms_asten & AST_MASK; - break; - - case MF_ASTSR: - R[0] = vms_astsr & AST_MASK; - break; - - case MF_VTBR: - R[0] = vms_vtbr; - break; - - case MT_VTBR: - vms_vtbr = R[16]; - break; - - case MT_PERFMON: - // tbd - break; - - case MT_DATFX: - vms_datfx = arg32 & 1; - val = ReadPQ (vms_hwpcb + PCBV_FLAGS); - val = (val & ~0x8000000000000000) | (((t_uint64) vms_datfx) << 63); - WritePQ (vms_hwpcb + PCBV_FLAGS, val); - break; - - case MF_VIRBND: - R[0] = vms_virbnd; - break; - - case MT_VIRBND: - vms_virbnd = R[16]; - break; - - case MF_SYSPTBR: - R[0] = vms_sysptbr; - break; - - case MT_SYSPTBR: - vms_sysptbr = R[16]; - break; - - case OP_WTINT: - R[0] = 0; - break; - - case MF_WHAMI: - R[0] = 0; - break; - -/* Non-privileged */ - - case OP_BPT: - return vms_intexc (SCB_BPT, MODE_K, vms_ipl); - - case OP_BUGCHK: - return vms_intexc (SCB_BUG, MODE_K, vms_ipl); - - case OP_CHME: - return vms_intexc (SCB_CHME, MOST_PRIV (MODE_E, vms_cm), vms_ipl); - - case OP_CHMK: - return vms_intexc (SCB_CHMK, MODE_K, vms_ipl); - - case OP_CHMS: - return vms_intexc (SCB_CHMS, MOST_PRIV (MODE_S, vms_cm), vms_ipl); - - case OP_CHMU: - return vms_intexc (SCB_CHMU, vms_cm, vms_ipl); - break; - - case OP_IMB: - break; - - case OP_INSQHIL: - R[0] = vms_insqhil (); - break; - - case OP_INSQTIL: - R[0] = vms_insqtil (); - break; - - case OP_INSQHIQ: - R[0] = vms_insqhiq (); - break; - - case OP_INSQTIQ: - R[0] = vms_insqtiq (); - break; - - case OP_INSQUEL: - R[0] = vms_insquel (0); - break; - - case OP_INSQUEQ: - R[0] = vms_insqueq (0); - break; - - case OP_INSQUELD: - R[0] = vms_insquel (1); - break; - - case OP_INSQUEQD: - R[0] = vms_insqueq (1); - break; - - case OP_PROBER: - R[0] = vms_probe (PTE_KRE); - break; - - case OP_PROBEW: - R[0] = vms_probe (PTE_KRE|PTE_KWE); - break; - - case OP_RD_PS: - R[0] = GET_PSV; - break; - - case OP_REI: - return vms_rei (); - - case OP_REMQHIL: - R[0] = vms_insqhil (); - break; - - case OP_REMQTIL: - R[0] = vms_remqtil (); - break; - - case OP_REMQHIQ: - R[0] = vms_remqhiq (); - break; - - case OP_REMQTIQ: - R[0] = vms_remqtiq (); - break; - - case OP_REMQUEL: - R[0] = vms_remquel (0); - break; - - case OP_REMQUEQ: - R[0] = vms_remqueq (0); - break; - - case OP_REMQUELD: - R[0] = vms_remquel (1); - break; - - case OP_REMQUEQD: - R[0] = vms_remqueq (1); - break; - - case OP_SWASTEN: - R[0] = (vms_asten >> vms_cm) & 1; - vms_asten = (vms_asten & ~(1u << vms_cm)) | ((arg32 & 1) << vms_cm); - break; - - case OP_WR_PS_SW: - vms_ps = (vms_ps & ~PSV_M_SW) | (arg32 & PSV_M_SW); - break; - - case OP_RSCC: - vms_scc = vms_scc + ((pcc_l - vms_last_pcc) & M32); /* update scc */ - vms_last_pcc = pcc_l; - R[0] = vms_scc; - break; - - case OP_RD_UNQ: - R[0] = vms_thread; - break; - - case OP_WR_UNQ: - vms_thread = R[16]; - break; - - case OP_AMOVRR: - R[18] = vms_amovrr (); - break; - - case OP_AMOVRM: - R[18] = vms_amovrm (); - break; - - case OP_INSQHILR: - R[0] = vms_insqhilr (); - break; - - case OP_INSQTILR: - R[0] = vms_insqtilr (); - break; - - case OP_INSQHIQR: - R[0] = vms_insqhiqr (); - break; - - case OP_INSQTIQR: - R[0] = vms_insqtiqr (); - break; - - case OP_REMQHILR: - R[0] = vms_insqhilr (); - break; - - case OP_REMQTILR: - R[0] = vms_remqtilr (); - break; - - case OP_REMQHIQR: - R[0] = vms_remqhiqr (); - break; - - case OP_REMQTIQR: - R[0] = vms_remqtiqr (); - break; - - case OP_GENTRAP: - return vms_intexc (SCB_GENTRAP, MODE_K, vms_ipl); - - case OP_CLRFEN: - fpen = 0; - arg32 = ReadPL (vms_hwpcb + PCBV_FLAGS); - arg32 = arg32 & ~1; - WritePL (vms_hwpcb + PCBV_FLAGS, arg32); - break; - - default: - ABORT (EXC_RSVI); - } - -return SCPE_OK; -} - -/* Interlocked insert instructions - - R[16] = entry - R[17] = header - - Pictorially: - - BEFORE AFTER INSQHI AFTER INSQTI - - H: A-H H: D-H W H: A-H W for interlock - H+4/8: C-H H+4/8: C-H H+4/8: D-H W - - A: B-A A: B-A A: B-A - A+4/8: H-A A+4/8: D-A W A+4/8: H-A - - B: C-B B: C-B B: C-B - B+4/8: A-B B+4/8: A-B B+4/8: A-B - - C: H-C C: H-C C: D-C W - C+4/8: B-C C+4/8: B-C C+4/8: B-C - - D: --- D: A-D W D: H-D W - D+4/8: --- D+4/8: H-D W D+4/8: C-D W - - Note that the queue header, the entry to be inserted, and all - the intermediate entries that are "touched" in any way must be - QUAD(OCTA)WORD aligned. In addition, the header and the entry - must not be equal. - - Note that the offset arithmetic (+4, +8) cannot overflow 64b, - because the entries are quad or octa aligned. -*/ - -t_int64 vms_insqhil (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, a; - -if ((h == d) || ((h | d) & 07) || /* h, d quad align? */ - ((SEXT_L_Q (h) & M64) != h) || - ((SEXT_L_Q (d) & M64) != d)) ABORT (EXC_RSVO); -ReadAccQ (d, cm_wacc); /* wchk (d) */ -ar = ReadQ (h); /* a <- (h) */ -if (ar & 06) ABORT (EXC_RSVO); /* a quad align? */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* get interlock */ -a = (SEXT_L_Q (ar + h)) & M64; /* abs addr of a */ -if (Test (a, cm_wacc, NULL)) WriteQ (h, ar); /* wtst a, rls if err */ -WriteL (a + 4, (uint32) (d - a)); /* (a+4) <- d-a, flt ok */ -WriteL (d, (uint32) (a - d)); /* (d) <- a-d */ -WriteL (d + 4, (uint32) (h - d)); /* (d+4) <- h-d */ -WriteL (h, (uint32) (d - h)); /* (h) <- d-h, rls int */ -return ((ar & M32) == 0)? 0: +1; /* ret 0 if q was empty */ -} - -t_int64 vms_insqhilr (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, a; - -ar = ReadQ (h); /* a <- (h) */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* get interlock */ -a = (SEXT_L_Q (ar + h)) & M64; /* abs addr of a */ -WriteL (a + 4, (uint32) (d - a)); /* (a+4) <- d-a, flt ok */ -WriteL (d, (uint32) (a - d)); /* (d) <- a-d */ -WriteL (d + 4, (uint32) (h - d)); /* (d+4) <- h-d */ -WriteL (h, (uint32) (d - h)); /* (h) <- d-h, rls int */ -return ((ar & M32) == 0)? 0: +1; /* ret 0 if q was empty */ -} - -t_int64 vms_insqhiq (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, a; - -if ((h == d) || ((h | d) & 0xF)) ABORT (EXC_RSVO); /* h, d octa align? */ -ReadAccQ (d, cm_wacc); /* wchk (d) */ -ar = ReadQ (h); /* a <- (h) */ -if (ar & 0xE) ABORT (EXC_RSVO); /* a octa align? */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* get interlock */ -a = (ar + h) & M64; /* abs addr of a */ -if (Test (a, cm_wacc, NULL)) WriteQ (h, ar); /* wtst a, rls if err */ -WriteQ (a + 8, (d - a) & M64); /* (a+8) <- d-a, flt ok */ -WriteQ (d, (a - d) & M64); /* (d) <- a-d */ -WriteQ (d + 8, (h - d) & M64); /* (d+8) <- h-d */ -WriteQ (h, (d - h) & M64); /* (h) <- d-h, rls int */ -return (ar == 0)? 0: +1; /* ret 0 if q was empty */ -} - -t_int64 vms_insqhiqr (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, a; - -ar = ReadQ (h); /* a <- (h) */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* get interlock */ -a = (ar + h) & M64; /* abs addr of a */ -WriteQ (a + 8, (d - a) & M64); /* (a+8) <- d-a, flt ok */ -WriteQ (d, (a - d) & M64); /* (d) <- a-d */ -WriteQ (d + 8, (h - d) & M64); /* (d+8) <- h-d */ -WriteQ (h, (d - h) & M64); /* (h) <- d-h, rls int */ -return (ar == 0)? 0: +1; /* ret 0 if q was empty */ -} - -t_int64 vms_insqtil (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, c; - -if ((h == d) || ((h | d) & 07) || /* h, d quad align? */ - ((SEXT_L_Q (h) & M64) != h) || - ((SEXT_L_Q (d) & M64) != d)) ABORT (EXC_RSVO); -ReadAccQ (d, cm_wacc); /* wchk (d) */ -ar = ReadQ (h); /* a <- (h) */ -if ((ar & M32) == 0) return vms_insqhil (); /* if empty, ins hd */ -if (ar & 06) ABORT (EXC_RSVO); /* a quad align? */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ar >> 32; /* c <- (h+4) */ -c = (SEXT_L_Q (c + h)) & M64; /* abs addr of c */ -if (c & 07) { /* c quad aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (Test (c, cm_wacc, NULL)) WriteQ (h, ar); /* wtst c, rls if err */ -WriteL (c, (uint32) (d - c)); /* (c) <- d-c, flt ok */ -WriteL (d, (uint32) (h - d)); /* (d) <- h-d */ -WriteL (d + 4, (uint32) (c - d)); /* (d+4) <- c-d */ -WriteL (h + 4, (uint32) (d - h)); /* (h+4) <- d-h */ -WriteL (h, (uint32) ar); /* release interlock */ -return 0; /* q was not empty */ -} - -t_int64 vms_insqtilr (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, c; - -ar = ReadQ (h); /* a <- (h) */ -if ((ar & M32) == 0) return vms_insqhilr (); /* if empty, ins hd */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ar >> 32; /* c <- (h+4) */ -c = (SEXT_L_Q (c + h)) & M64; /* abs addr of c */ -WriteL (c, (uint32) (d - c)); /* (c) <- d-c */ -WriteL (d, (uint32) (h - d)); /* (d) <- h-d */ -WriteL (d + 4, (uint32) (c - d)); /* (d+4) <- c-d */ -WriteL (h + 4, (uint32) (d - h)); /* (h+4) <- d-h */ -WriteL (h, (uint32) ar); /* release interlock */ -return 0; /* q was not empty */ -} - -t_int64 vms_insqtiq (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, c; - -if ((h == d) || ((h | d) & 0xF)) ABORT (EXC_RSVO); /* h, d octa align? */ -ReadAccQ (d, cm_wacc); /* wchk ent */ -ar = ReadQ (h); /* a <- (h) */ -if (ar == 0) return vms_insqhiq (); /* if empty, ins hd */ -if (ar & 0xE) ABORT (EXC_RSVO); /* a octa align? */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ReadQ (h + 8); /* c <- (h+8) */ -c = (c + h) & M64; /* abs addr of C */ -if (c & 0xF) { /* c octa aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (Test (c, cm_wacc, NULL)) WriteQ (h, ar); /* wtst c, rls if err */ -WriteQ (c, (d - c) & M64); /* (c) <- d-c, flt ok */ -WriteQ (d, (h - d) & M64); /* (d) <- h-d */ -WriteQ (d + 8, (c - d) & M64); /* (d+8) <- c-d */ -WriteQ (h + 8, (d - h) & M64); /* (h+8) <- d-h */ -WriteQ (h, ar); /* release interlock */ -return 0; /* q was not empty */ -} - -t_int64 vms_insqtiqr (void) -{ -t_uint64 h = R[16]; -t_uint64 d = R[17]; -t_uint64 ar, c; - -ar = ReadQ (h); /* a <- (h) */ -if (ar == 0) return vms_insqhiqr (); /* if empty, ins hd */ -if (ar & 01) return -1; /* busy, ret -1 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ReadQ (h + 8); /* c <- (h+8) */ -c = (c + h) & M64; /* abs addr of C */ -WriteQ (c, (d - c) & M64); /* (c) <- d-c */ -WriteQ (d, (h - d) & M64); /* (d) <- h-d */ -WriteQ (d + 8, (c - d) & M64); /* (d+8) <- c-d */ -WriteQ (h + 8, (d - h) & M64); /* (h+8) <- d-h */ -WriteQ (h, ar); /* release interlock */ -return 0; /* q was not empty */ -} - -/* Interlocked remove instructions - - R[16] = header (hdr.aq) - R[1] ] = receives destination address - - Pictorially: - - BEFORE AFTER REMQHI AFTER REMQTI - - H: A-H H: B-H W H: A-H W for interlock - H+4/8: C-H H+4/8: C-H H+4/8: B-H W - - A: B-A A: B-A R A: B-A - A+4/8: H-A A+4/8: H-A A+4/8: H-A - - B: C-B B: C-B B: H-B W - B+4/8: A-B B+4/8: H-B W B+4/8: A-B - - C: H-C C: H-C C: H-C - C+4/8: B-C C+4/8: B-C C+4/8: B-C R - - Note that the queue header and all the entries that are - "touched" in any way must be QUAD(OCTA)WORD aligned. -*/ - -t_int64 vms_remqhil (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, a, b; - -if ((h & 07) || ((SEXT_L_Q (h) & M64) != h)) /* h quad aligned? */ - ABORT (EXC_RSVO); -ar = ReadQ (h); /* ar <- (h) */ -if (ar & 06) ABORT (EXC_RSVO); /* a quad aligned? */ -if (ar & 01) return -1; /* busy, ret -1 */ -if ((ar & M32) == 0) return 0; /* queue empty? */ -WriteQ (h, ar | 1); /* acquire interlock */ -a = (SEXT_L_Q (ar + h)) & M64; /* abs addr of a */ -if (Test (a, cm_racc, NULL)) WriteQ (h, ar); /* rtst a, rls if err */ -b = ReadL (a); /* b <- (a), flt ok */ -b = (SEXT_L_Q (b + a)) & M64; /* abs addr of b */ -if (b & 07) { /* b quad aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (Test (b, cm_wacc, NULL)) WriteQ (h, ar); /* wtst b, rls if err */ -WriteL (b + 4, (uint32) (h - b)); /* (b+4) <- h-b, flt ok */ -WriteL (h, (uint32) (b - h)); /* (h) <- b-h, rls int */ -R[1] = a; /* address of entry */ -return ((b & M32) == (h & M32))? +2: +1; /* if b = h, q empty */ -} - -t_int64 vms_remqhilr (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, a, b; - -ar = ReadQ (h); /* ar <- (h) */ -if (ar & 01) return -1; /* busy, ret -1 */ -if ((ar & M32) == 0) return 0; /* queue empty? */ -WriteQ (h, ar | 1); /* acquire interlock */ -a = (SEXT_L_Q (ar + h)) & M64; /* abs addr of a */ -b = ReadL (a); /* b <- (a), flt ok */ -b = (SEXT_L_Q (b + a)) & M64; /* abs addr of b */ -WriteL (b + 4, (uint32) (h - b)); /* (b+4) <- h-b, flt ok */ -WriteL (h, (uint32) (b - h)); /* (h) <- b-h, rls int */ -R[1] = a; /* address of entry */ -return ((b & M32) == (h & M32))? +2: +1; /* if b = h, q empty */ -} - -t_int64 vms_remqhiq (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, a, b; - -if (h & 0xF) ABORT (EXC_RSVO); /* h octa aligned? */ -ar = ReadQ (h); /* ar <- (h) */ -if (ar & 0xE) ABORT (EXC_RSVO); /* a octa aligned? */ -if (ar & 01) return -1; /* busy, ret -1 */ -if (ar == 0) return 0; /* queue empty? */ -WriteQ (h, ar | 1); /* acquire interlock */ -a = (ar + h) & M64; /* abs addr of a */ -if (Test (a, cm_racc, NULL)) WriteQ (h, ar); /* rtst a, rls if err */ -b = ReadQ (a); /* b <- (a), flt ok */ -b = (b + a) & M64; /* abs addr of b */ -if (b & 0xF) { /* b octa aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (Test (b, cm_wacc, NULL)) WriteQ (h, ar); /* wtst b, rls if err */ -WriteQ (b + 8, (h - b) & M64); /* (b+8) <- h-b, flt ok */ -WriteQ (h, (b - h) & M64); /* (h) <- b-h, rls int */ -R[1] = a; /* address of entry */ -return (b == h)? +2: +1; /* if b = h, q empty */ -} - -t_int64 vms_remqhiqr (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, a, b; - -ar = ReadQ (h); /* ar <- (h) */ -if (ar & 01) return -1; /* busy, ret -1 */ -if (ar == 0) return 0; /* queue empty? */ -WriteQ (h, ar | 1); /* acquire interlock */ -a = (ar + h) & M64; /* abs addr of a */ -b = ReadQ (a); /* b <- (a) */ -b = (b + a) & M64; /* abs addr of b */ -WriteQ (b + 8, (h - b) & M64); /* (b+8) <- h-b, flt ok */ -WriteQ (h, (b - h) & M64); /* (h) <- b-h, rls int */ -R[1] = a; /* address of entry */ -return (b == h)? +2: +1; /* if b = h, q empty */ -} - -t_int64 vms_remqtil (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, b, c; - -if ((h & 07) || ((SEXT_L_Q (h) & M64) != h)) /* h quad aligned? */ - ABORT (EXC_RSVO); -ar = ReadQ (h); /* a <- (h) */ -if (ar & 06) ABORT (EXC_RSVO); /* a quad aligned? */ -if (ar & 01) return -1; /* busy, return - 1*/ -if ((ar & M32) == 0) return 0; /* empty, return 0 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ar >> 32; /* c <- (h+4) */ -if (c & 07) { /* c quad aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if ((ar & M32) == (c & M32)) { /* single entry? */ - WriteQ (h, ar); /* release interlock */ - return vms_remqhil (); /* treat as remqhil */ - } -c = (SEXT_L_Q (c + h)) & M64; /* abs addr of c */ -if (Test (c + 4, cm_racc, NULL)) WriteQ (h, ar); /* rtst c+4, rls if err */ -b = ReadL (c + 4); /* b <- (c+4), flt ok */ -b = (SEXT_L_Q (b + c)) & M64; /* abs addr of b */ -if (b & 07) { /* b quad aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (Test (b, cm_wacc, NULL)) WriteQ (h, ar); /* wtst b, rls if err */ -WriteL (b, (uint32) (h - b)); /* (b) <- h-b, flt ok */ -WriteL (h + 4, (uint32) (b - h)); /* (h+4) <- b-h */ -WriteL (h, (uint32) ar); /* release interlock */ -R[1] = c; /* store result */ -return +1; /* q can't be empty */ -} - -t_int64 vms_remqtilr (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, b, c; - -ar = ReadQ (h); /* a <- (h) */ -if (ar & 01) return -1; /* busy, return - 1*/ -if ((ar & M32) == 0) return 0; /* emtpy, return 0 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ar >> 32; /* c <- (h+4) */ -if ((ar & M32) == (c & M32)) { /* single entry? */ - WriteQ (h, ar); /* release interlock */ - return vms_remqhilr (); /* treat as remqhil */ - } -c = (SEXT_L_Q (c + h)) & M64; /* abs addr of c */ -b = ReadL (c + 4); /* b <- (c+4) */ -b = (SEXT_L_Q (b) + c) & M64; /* abs addr of b */ -WriteL (b, (uint32) (h - b)); /* (b) <- h-b */ -WriteL (h + 4, (uint32) (b - h)); /* (h+4) <- b-h */ -WriteL (h, (uint32) ar); /* release interlock */ -R[1] = c; /* store result */ -return +1; /* q can't be empty */ -} - -t_int64 vms_remqtiq (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, b, c; - -if (h & 0xF) ABORT (EXC_RSVO); /* h octa aligned? */ -ar = ReadQ (h); /* a <- (h) */ -if (ar & 0xE) ABORT (EXC_RSVO); /* a quad aligned? */ -if (ar & 01) return -1; /* busy, return - 1*/ -if (ar == 0) return 0; /* emtpy, return 0 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ReadQ (h + 8); /* c <- (h+8) */ -if (c & 0xF) { /* c octa aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (ar == c) { /* single entry? */ - WriteQ (h, ar); /* release interlock */ - return vms_remqhiq (); /* treat as remqhil */ - } -c = (c + h) & M64; /* abs addr of c */ -if (Test (c + 8, cm_racc, NULL)) WriteQ (h, ar); /* rtst c+8, rls if err */ -b = ReadQ (c + 8); /* b <- (c+8), flt ok */ -b = (b + c) & M64; /* abs addr of b */ -if (b & 0xF) { /* b octa aligned? */ - WriteQ (h, ar); /* release interlock */ - ABORT (EXC_RSVO); /* fault */ - } -if (Test (b, cm_wacc, NULL)) WriteQ (h, ar); /* wtst b, rls if err */ -WriteQ (b, (h - b) & M64); /* (b) <- h-b, flt ok */ -WriteQ (h + 8, (b - h) & M64); /* (h+8) <- b-h */ -WriteQ (h, ar); /* release interlock */ -R[1] = c; /* store result */ -return +1; /* q can't be empty */ -} - -t_int64 vms_remqtiqr (void) -{ -t_uint64 h = R[16]; -t_uint64 ar, b, c; - -ar = ReadQ (h); /* a <- (h) */ -if (ar & 01) return -1; /* busy, return - 1*/ -if (ar == 0) return 0; /* emtpy, return 0 */ -WriteQ (h, ar | 1); /* acquire interlock */ -c = ReadQ (h + 8); /* c <- (h+8) */ -if (ar == c) { /* single entry? */ - WriteQ (h, ar); /* release interlock */ - return vms_remqhiq (); /* treat as remqhil */ - } -c = (c + h) & M64; /* abs addr of c */ -b = ReadQ (c + 8); /* b <- (c+8) */ -b = (b + c) & M64; /* abs addr of b */ -WriteQ (b, (h - b) & M64); /* (b) <- h-b */ -WriteQ (h + 8, (b - h) & M64); /* (h+8) <- b-h */ -WriteQ (h, ar); /* release interlock */ -R[1] = c; /* store result */ -return +1; /* q can't be empty */ -} - -/* INSQUE - - R[16] = predecessor address - R[17] = entry address - - All writes must be checked before any writes are done. - - Pictorially: - - BEFORE AFTER - - P: S P: E W - P+4/8: (n/a) P+4/8: (n/a) - - E: --- E: S W - E+4/8: --- E+4/8: P W - - S: (n/a) S: (n/a) - S+4/8: P S+4/8: E W - - For longword queues, operands can be misaligned. - Quadword queues must be octaword aligned, and the - address addition cannot overflow 64b. - Note that WriteUna masks data to its proper length. -*/ - -t_int64 vms_insquel (uint32 defer) -{ -t_uint64 p = SEXT_L_Q (R[16]) & M64; -t_uint64 e = SEXT_L_Q (R[17]) & M64; -t_uint64 s; - -if (defer) { /* defer? */ - p = ReadUna (p, L_LONG, cm_racc); /* get address */ - p = SEXT_L_Q (p) & M64; /* make 64b */ - } -s = ReadUna (p, L_LONG, cm_macc); /* s <- (p), wchk */ -s = SEXT_L_Q (s) & M64; /* make 64b */ -ReadUna ((s + 4) & M64, L_LONG, cm_wacc); /* wchk s+4 */ -ReadUna ((e + 4) & M64, L_LONG, cm_wacc); /* wchk e+4 */ -WriteUna (e, s, L_LONG, cm_wacc); /* (e) <- s, last unchecked */ -WriteUna ((e + 4) & M64, p, L_LONG, cm_wacc); /* (e+4) <- p */ -WriteUna ((s + 4) & M64, e, L_LONG, cm_wacc); /* (s+4) <- ent */ -WriteUna (p, e, L_LONG, cm_wacc); /* (p) <- e */ -return (((s & M32) == (p & M32))? +1: 0); /* return status */ -} - -t_int64 vms_insqueq (uint32 defer) -{ -t_uint64 p = R[16]; -t_uint64 e = R[17]; -t_uint64 s; - -if (defer) { /* defer? */ - if (p & 07) ABORT (EXC_RSVO); - p = ReadQ (p); - } -if ((e | p) & 0xF) ABORT (EXC_RSVO); /* p, e octa aligned? */ -s = ReadAccQ (p, cm_macc); /* s <- (p), wchk */ -if (s & 0xF) ABORT (EXC_RSVO); /* s octa aligned? */ -ReadAccQ (s + 8, cm_wacc); /* wchk s+8 */ -ReadAccQ (e + 8, cm_wacc); /* wchk e+8 */ -WriteQ (e, s); /* (e) <- s */ -WriteQ (e + 8, p); /* (e+8) <- p */ -WriteQ (s + 8, e); /* (s+8) <- ent */ -WriteQ (p, e); /* (p) <- e */ -return ((s == p)? +1: 0); /* return status */ -} - -/* REMQUE - - R[16] = entry address - - All writes must be checked before any writes are done. - - Pictorially: - - BEFORE AFTER - - P: E P: S W - P+4/8: (n/a) P+4/8: (n/a) - - E: S W E: S - E+4/8: P W E+4/8: P - - S: (n/a) S: (n/a) - S+4/8: E W S+4/8: P - -*/ - -t_int64 vms_remquel (uint32 defer) -{ -t_uint64 e = SEXT_L_Q (R[16]) & M64; -t_uint64 s, p; - -if (defer) { /* defer? */ - e = ReadUna (e, L_LONG, cm_racc); /* get address */ - e = SEXT_L_Q (e) & M64; /* make 64b */ - } -s = ReadUna (e, L_LONG, cm_racc); /* s <- (e) */ -p = ReadUna ((e + 4) & M64, L_LONG, cm_racc); /* p <- (e+4) */ -s = SEXT_L_Q (s) & M64; -p = SEXT_L_Q (p) & M64; -if (e == p) return -1; /* queue empty? */ -ReadUna ((s + 4) & M64, L_LONG, cm_wacc); /* wchk (s+4) */ -WriteUna (p, s, L_LONG, cm_wacc); /* (p) <- s */ -WriteUna ((s + 4) & M64, p, L_LONG, cm_wacc); /* (s+4) <- p */ -return ((s == p)? 0: +1); -} - -t_int64 vms_remqueq (uint32 defer) -{ -t_uint64 e = R[16]; -t_uint64 s, p; - -if (defer) { /* defer? */ - if (e & 07) ABORT (EXC_RSVO); - e = ReadQ (e); - } -if (e & 0xF) ABORT (EXC_RSVO); /* e octa aligned? */ -s = ReadQ (e); /* s <- (e) */ -p = ReadQ (e + 8); /* p <- (e+8) */ -if ((s | p) & 0xF) ABORT (EXC_RSVO); /* s, p octa aligned? */ -if (e == p) return -1; /* queue empty? */ -ReadAccQ (s + 8, cm_wacc); /* wchk (s+8) */ -WriteQ (p, s); /* (p) <- s */ -WriteQ (s + 8, p); /* (s+8) <- p */ -return ((s == p)? 0: +1); -} - -/* Probe */ - -uint32 vms_probe (uint32 acc) -{ -uint32 pm = ((uint32) R[18]) & 3; - -if (pm <= vms_cm) pm = vms_cm; /* least privileged */ -acc = (acc << pm) | PTE_V; /* access test - no FOR/W */ -if (Test (R[16], acc, NULL)) return 0; /* test start */ -if (Test ((R[16] + R[17]) & M64, acc, NULL)) return 0; /* test end */ -return 1; -} - -/* VMS TIE support instructions */ - -uint32 vms_amovrr (void) -{ -uint32 lnt1 = ((uint32) R[18]) & 3; -uint32 lnt2 = ((uint32) R[21]) & 3; - -if (vax_flag == 0) return 0; /* stop if !vax_flag */ -vax_flag = 0; /* clear vax_flag */ -ReadUna (R[17], lnt_map[lnt1], cm_wacc); /* verify writes */ -ReadUna (R[20], lnt_map[lnt2], cm_wacc); -WriteUna (R[17], R[16], lnt_map[lnt1], cm_wacc); /* do both writes */ -WriteUna (R[20], R[21], lnt_map[lnt2], cm_wacc); /* WriteUna masks data */ -return 1; -} - -uint32 vms_amovrm (void) -{ -t_uint64 va, va1; -uint32 lnt1 = ((uint32) R[18]) & 3; -uint32 lnt2 = ((uint32) R[21]) & 0x3F; -uint32 i, dat; - -if (vax_flag == 0) return 0; /* stop if !vax_flag */ -vax_flag = 0; /* clear vax_flag */ -if (lnt2 && ((R[19] | R[20]) & 3)) ABORT (EXC_RSVO); /* lw aligned? */ -ReadUna (R[17], lnt_map[lnt1], cm_wacc); /* verify first write */ -if (lnt2) { /* if second length */ - va = (R[19] + (lnt2 << 2) - 4) & M64; - va1 = (R[20] + (lnt2 << 2) - 4) & M64; - ReadL (R[19]); /* verify source */ - ReadL (va); - ReadAccL (R[20], cm_wacc); /* verify destination */ - ReadAccL (va1, cm_wacc); - } -WriteUna (R[17], R[16], lnt_map[lnt1], cm_wacc); /* do first write */ -for (i = 0, va = R[19], va1 = R[20]; i < lnt2; i++) { /* move data */ - dat = ReadL (va); - WriteL (va1, dat); - va = (va + 4) & M64; - va1 = (va1 + 4) & M64; - } -return 1; -} - -/* Swap privileged context */ - -void vms_swpctx (void) -{ -t_uint64 val; -uint32 tmp; - -if (R[16] & 0x7F) ABORT (EXC_RSVO); /* must be 128B aligned */ -WritePQ (vms_hwpcb + 0, SP); /* save stack ptrs */ -WritePQ (vms_hwpcb + 8, esp); -WritePQ (vms_hwpcb + 16, ssp); -WritePQ (vms_hwpcb + 24, usp); -WritePQ (vms_hwpcb + 48, (vms_astsr << 4) | vms_asten); /* save AST */ -WritePQ (vms_hwpcb + 64, (pcc_h + pcc_l) & M32); /* save PCC */ -WritePQ (vms_hwpcb + 72, vms_thread); /* save UNIQUE */ -vms_hwpcb = R[16]; /* new PCB */ -SP = ksp = ReadPQ (vms_hwpcb + 0); /* read stack ptrs */ -esp = ReadPQ (vms_hwpcb + 8); -ssp = ReadPQ (vms_hwpcb + 16); -usp = ReadPQ (vms_hwpcb + 24); -val = ReadPQ (vms_hwpcb + 32) << VA_N_OFF; /* read PTBR */ -if (val != vms_ptbr) tlb_ia (TLB_CI | TLB_CD); /* if changed, zap TLB */ -vms_ptbr = val; -tmp = ReadPL (vms_hwpcb + 40) & M16; /* read ASN */ -itlb_set_asn (tmp); -dtlb_set_asn (tmp); -tmp = ReadPL (vms_hwpcb + 48); /* read AST */ -vms_astsr = (tmp >> 4) & AST_MASK; /* separate ASTSR, ASTEN */ -vms_asten = tmp & AST_MASK; -val = ReadPQ (vms_hwpcb + PCBV_FLAGS); /* read flags */ -fpen = ((uint32) val) & 1; /* set FEN */ -vms_datfx = ((uint32) (val >> 63)) & 1; /* set DATFX */ -tmp = ReadL (vms_hwpcb + 64); -pcc_h = (tmp - pcc_l) & M32; -vms_thread = ReadPQ (vms_hwpcb + 72); /* read UNIQUE */ -return; -} - -/* VMS interrupt or exception - - Inputs: - vec = SCB vector - newmode = new mode (usually kernel) - newipl = new IPL - Outputs: - reason = possible processor halt -*/ - -t_stat vms_intexc (uint32 vec, uint32 newmode, uint32 newipl) -{ -t_uint64 pa = (vms_scbb + vec) & ~0xF; /* vector */ -t_uint64 sav_ps = GET_PSV; /* old PS */ -uint32 wacc = ACC_W (newmode); -uint32 exc; - -vms_stkp[vms_cm] = SP; /* save SP */ -SP = vms_stkp[newmode]; /* load new SP */ -sav_ps = sav_ps | ((SP & PSV_M_SPA) << PSV_V_SPA); /* save SP align */ -SP = SP & ~PSV_M_SPA; /* align SP */ -SP = (SP - VMS_L_STKF) & M64; -if (exc = Test (SP, wacc, NULL)) { /* check writes */ - if (newmode == MODE_K) return STOP_KSNV; /* error? stop if kernel */ - ABORT1 (SP, exc + EXC_W); /* else, force fault */ - } -if (exc = Test (SP + VMS_L_STKF - 8, wacc, NULL)) { - if (newmode == MODE_K) return STOP_KSNV; - ABORT1 (SP + VMS_L_STKF - 8, exc + EXC_W); - } -vms_cm = mmu_set_cm (newmode); /* switch mode */ -WriteQ (SP, R[2]); /* save R2-R7 */ -WriteQ (SP + 8, R[3]); -WriteQ (SP + 16, R[4]); -WriteQ (SP + 24, R[5]); -WriteQ (SP + 32, R[6]); -WriteQ (SP + 40, R[7]); -WriteQ (SP + 48, PC); /* save PC */ -WriteQ (SP + 56, sav_ps); /* save PS */ -PC = R[2] = ReadPQ (pa); /* set new PC */ -R[3] = ReadPQ (pa + 8); /* set argument */ -vms_ipl = newipl; /* change IPL */ -vms_ps = vms_ps & ~PSV_M_SW; -return SCPE_OK; -} - -/* Memory management fault */ - -t_stat vms_mm_intexc (uint32 vec, t_uint64 par2) -{ -t_stat r; - -r = vms_intexc (vec, MODE_K, vms_ipl); /* take exception */ -R[4] = p1; /* R[4] = va */ -R[5] = par2; /* R[5] = MME */ -tlb_is (p1, TLB_CI | TLB_CD); /* zap TLB entry */ -return r; -} - -/* Return from exception of interrupt */ - -t_stat vms_rei (void) -{ -t_uint64 t1, t2, t3, t4, t5, t6, t7, t8; -uint32 newmode; - -if (SP & PSV_M_SPA) ABORT (EXC_RSVO); /* check alignment */ -if (vms_cm == MODE_K) { /* in kernel mode? */ - if (Test (SP, cm_racc, NULL)) return STOP_KSNV; /* must be accessible */ - if (Test (SP + VMS_L_STKF - 8, cm_racc, NULL)) return STOP_KSNV; - } -t1 = ReadQ (SP); /* pop stack */ -t2 = ReadQ (SP + 8); -t3 = ReadQ (SP + 16); -t4 = ReadQ (SP + 24); -t5 = ReadQ (SP + 32); -t6 = ReadQ (SP + 40); -t7 = ReadQ (SP + 48); -t8 = ReadQ (SP + 56); -newmode = (((uint32) t8) >> PSV_V_CM) && PSV_M_CM; /* get new mode */ -if ((vms_cm != MODE_K) && /* not kernel? check new PS */ - ((newmode < vms_cm) || (t8 & PSV_MBZ))) ABORT (EXC_RSVO); -SP = (SP + VMS_L_STKF) | ((t8 >> PSV_V_SPA) & PSV_M_SPA); -vms_stkp[vms_cm] = SP; /* save SP */ -SP = vms_stkp[newmode]; /* load new SP */ -R[2] = t1; /* restore R2-R7 */ -R[3] = t2; -R[4] = t3; -R[5] = t4; -R[6] = t5; -R[7] = t6; -PC = t7 & ~3; /* restore PC */ -vms_ps = ((uint32) t8) & PSV_MASK; /* restore PS */ -vms_cm = mmu_set_cm (newmode); /* switch modes */ -vms_ipl = (((uint32) t8) >> PSV_V_IPL) & PSV_M_IPL; /* new IPL */ -vax_flag = 0; /* clear vax, lock flags */ -lock_flag = 0; -return SCPE_OK; -} - -/* Unaligned read virtual - for VMS PALcode only - - Inputs: - va = virtual address - lnt = length code (BWLQ) - acc = access code (includes FOR, FOW) - Output: - returned data, right justified -*/ - -t_uint64 ReadUna (t_uint64 va, uint32 lnt, uint32 acc) -{ -t_uint64 pa, pa1, wl, wh; -uint32 exc, bo, sc; - -if (exc = Test (va, acc, &pa)) /* test, translate */ - ABORT1 (va, exc + EXC_R); -if ((pa & (lnt - 1)) == 0) { /* aligned? */ - if (lnt == L_QUAD) return ReadPQ (pa); /* quad? */ - if (lnt == L_LONG) return ReadPL (pa); /* long? */ - if (lnt == L_WORD) return ReadPW (pa); /* word? */ - return ReadPB (pa); /* byte */ - } -if ((VA_GETOFF (va) + lnt) > VA_PAGSIZE) { /* cross page? */ - if (exc = Test (va + 8, acc, &pa1)) /* test, translate */ - ABORT1 (va + 8, exc + EXC_R); - } -else pa1 = (pa + 8) & PA_MASK; /* not cross page */ -bo = ((uint32) pa) & 7; /* byte in qw */ -sc = bo << 3; /* shift count */ -wl = ReadPQ (pa); /* get low qw */ -if (lnt == L_QUAD) { /* qw unaligned? */ - wh = ReadPQ (pa1); /* get high qw */ - return ((((wl >> sc) & (((t_uint64) M64) >> sc)) | - (wh << (64 - sc))) & M64); /* extract data */ - } -if (lnt == L_LONG) { /* lw unaligned? */ - if (bo <= 4) return ((wl >> sc) & M32); /* all in one qw? */ - wh = ReadPQ (pa1); /* get high qw */ - return ((((wl >> sc) & (M32 >> (sc - 32))) | - (wh << (64 - sc))) & M32); - } -if (bo < 7) return ((wl >> sc) & M16); /* wd, all in one qw? */ -wh = ReadPQ (pa1); /* get hi qw, extract */ -return (((wl >> 56) & 0xFF) | ((wh & 0xFF) << 8)); -} - -/* Unaligned write virtual - for VMS PALcode only - - Inputs: - va = virtual address - val = data to be written, right justified in 64b - lnt = length code (BWLQ) - acc = access code (includes FOW) - Output: - none -*/ - -void WriteUna (t_uint64 va, t_uint64 val, uint32 lnt, uint32 acc) -{ -t_uint64 pa, pa1, wl, wh, mask; -uint32 exc, bo, sc; - -if (exc = Test (va, acc, &pa)) /* test, translate */ - ABORT1 (va, exc + EXC_W); -if ((pa & (lnt - 1)) == 0) { /* aligned? */ - if (lnt == L_QUAD) WritePQ (pa, val); /* quad? */ - else if (lnt == L_LONG) WritePL (pa, (uint32) val); /* long? */ - else if (lnt == L_WORD) WritePW (pa, (uint32) val); /* word? */ - else WritePB (pa, (uint32) val); /* byte */ - return; - } -if ((VA_GETOFF (va) + lnt) > VA_PAGSIZE) { /* cross page? */ - if (exc = Test (va + 8, acc, &pa1)) /* test, translate */ - ABORT1 (va + 8, exc + EXC_W); - } -else pa1 = (pa + 8) & PA_MASK; /* not cross page */ -bo = ((uint32) pa) & 7; /* byte in qw */ -sc = bo << 3; /* shift count */ -wl = ReadPQ (pa); /* get low qw */ -if (lnt == L_QUAD) { /* qw unaligned? */ - val = val & M64; /* mask data */ - mask = ((t_uint64) M64) << sc; /* low qw mask */ - wl = (wl & ~mask) | ((val << sc) & mask); /* insert low */ - wh = ReadPQ (pa1); /* hi qw */ - mask = ((t_uint64) M64) >> (64 - sc); /* hi qw mask */ - wh = (wh & ~mask) | ((val >> (64 - sc)) & mask); - WritePQ (pa, wl); /* write low */ - WritePQ (pa, wh); /* write high */ - } -else if (lnt == L_LONG) { /* lw unaligned? */ - val = val & M32; - mask = ((t_uint64) M32) << sc; /* low qw mask */ - wl = (wl & ~mask) | (val << sc); /* insert low */ - WritePQ (pa, wl); /* write low */ - if (bo >= 4) { /* 2nd qw? */ - wh = ReadPQ (pa1); /* read hi qw */ - mask = ((t_uint64) M32) >> (sc - 32); /* hi qw mask */ - wh = (wh & ~mask) | (val >> (sc - 32)); /* insert high */ - WritePQ (pa1, wh); /* write hi */ - } - } -else { - val = val & M16; /* mask data */ - mask = ((t_uint64) M16) << sc; /* word, low qw mask */ - wl = (wl & ~mask) | ((val & M16) << sc); /* insert low */ - WritePQ (pa, wl); /* write low */ - if (bo >= 7) { /* 2nd qw? */ - wh = ReadPQ (pa1); /* read hi */ - mask = 0xFF; /* hi qw mask */ - wh = (wh & ~mask) | (val >> 8); /* insert high */ - WritePQ (pa1, wh); /* write hi */ - } - } -return; -} - -/* Test the accessibility of an address (VMS and UNIX PALcode only) - - - In VMS, superpage is always 0 - - In Unix, current mode is always kernel - - Hence, superpages are always accessible */ - -uint32 Test (t_uint64 va, uint32 acc, t_uint64 *pa) -{ -uint32 va_sext = VA_GETSEXT (va); -uint32 vpn = VA_GETVPN (va); -t_uint64 pte; -uint32 exc; -TLBENT *tlbp; - -if (!dmapen) { /* mapping off? */ - if (pa) *pa = va & PA_MASK; /* pa = va */ - return 0; - } -if ((va_sext != 0) && (va_sext != VA_M_SEXT)) /* invalid virt addr? */ - return EXC_BVA; -if ((mmu_dspage & SPEN_43) && (VPN_GETSP43 (vpn) == 2)) { - if (pa) *pa = va & SP43_MASK; /* 43b superpage? */ - return 0; - } -if ((mmu_dspage & SPEN_32) && (VPN_GETSP32 (vpn) == 0x1FFE)) { - if (pa) *pa = va & SP32_MASK; /* 32b superpage? */ - return 0; - } -if (!(tlbp = dtlb_lookup (vpn))) { /* lookup vpn; miss? */ - if (exc = pal_find_pte (vpn, &pte)) return exc; /* fetch pte; error? */ - tlbp = dtlb_load (vpn, pte); /* load new entry */ - } -if (acc & ~tlbp->pte) return mm_exc (acc & ~tlbp->pte); /* check access */ -if (pa) *pa = PHYS_ADDR (tlbp->pfn, va); /* return phys addr */ -return 0; /* ok */ -} - -/* TLB check - VMS PALcode only */ - -uint32 tlb_check (t_uint64 va) -{ -uint32 va_sext = VA_GETSEXT (va); -uint32 vpn = VA_GETVPN (va); - -if ((va_sext != 0) && (va_sext != VA_M_SEXT)) return 0; -if (itlb_lookup (vpn)) return 1; -if (dtlb_lookup (vpn)) return 1; -return 0; -} - -/* VMS 3-level PTE lookup - - Inputs: - vpn = virtual page number (30b, sext) - *pte = pointer to pte to be returned - Output: - status = 0 for successful fill - EXC_ACV for ACV on intermediate level - EXC_TNV for TNV on intermediate level -*/ - -uint32 pal_find_pte_vms (uint32 vpn, t_uint64 *l3pte) -{ -t_uint64 vptea, l1ptea, l2ptea, l3ptea, l1pte, l2pte; -uint32 vpte_vpn; -TLBENT *vpte_p; - -vptea = vms_vtbr | (((t_uint64) (vpn & VA_M_VPN)) << 3);/* try virtual lookup */ -vpte_vpn = VA_GETVPN (vptea); /* get vpte vpn */ -vpte_p = dtlb_lookup (vpte_vpn); /* get vpte tlb ptr */ -if ((vpte_p->tag == vpte_vpn) && /* TLB hit? */ - ((vpte_p->pte & (PTE_KRE|PTE_V)) == (PTE_KRE|PTE_V))) - l3ptea = vpte_p->pfn | VA_GETOFF (vptea); -else { - l1ptea = vms_ptbr + VPN_GETLVL1 (vpn); - l1pte = ReadPQ (l1ptea); - if ((l1pte & PTE_V) == 0) - return ((l1pte & PTE_KRE)? EXC_TNV: EXC_ACV); - l2ptea = (l1pte & PFN_MASK) >> (PTE_V_PFN - VA_N_OFF); - l2ptea = l2ptea + VPN_GETLVL2 (vpn); - l2pte = ReadPQ (l2ptea); - if ((l2pte & PTE_V) == 0) - return ((l2pte & PTE_KRE)? EXC_TNV: EXC_ACV); - l3ptea = (l2pte & PFN_MASK) >> (PTE_V_PFN - VA_N_OFF); - l3ptea = l3ptea + VPN_GETLVL3 (vpn); - } -*l3pte = ReadPQ (l3ptea); -return 0; -} - -/* VMS PALcode reset */ - -t_stat pal_proc_reset_vms (DEVICE *dptr) -{ -mmu_ispage = mmu_dspage = 0; -vms_cm = mmu_set_cm (MODE_K); -vms_ipl = IPL_1F; -vms_ps = 0; -vms_datfx = 0; -vms_scbb = 0; -vms_prbr = 0; -vms_scc = 0; -vms_last_pcc = pcc_l; -pcc_enb = 1; -pal_eval_intr = &pal_eval_intr_vms; -pal_proc_intr = &pal_proc_intr_vms; -pal_proc_trap = &pal_proc_trap_vms; -pal_proc_excp = &pal_proc_excp_vms; -pal_proc_inst = &pal_proc_inst_vms; -pal_find_pte = &pal_find_pte_vms; -return SCPE_OK; -} diff --git a/doc/simh_doc.doc b/doc/simh_doc.doc index aaa7d367d200afefc014e167bbe25f806f487530..10021950c596a59b47ce8b2305371a315d3c9ccc 100644 GIT binary patch delta 33842 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%0AI31(L)ez>C}0-(VdEW`?2 z!A*2XVL9eOvxKMp5O;39#CzCZWw?YqD1cgMfPv5;3D@xkY0zGyu5kg$xQrY4<2u!c zg;;?TI0u&-3>v^KQ5vZu6SZy<>4-#s9Ks1?zs0Z@n-GrILT1nLoByE}sioWNgDj{t5(>AFx3RiGXTN_jF5qNA=2>ykte_}MFsuA`mh zO^6`2GG}M-tjYltg?%_w;iE4VfT(ID1b6&sR2WPr8;xU4NC`!tiu`ng-3V=_f{kZB~Tra=#8nEg*Y6>JA8y~Yjy%ZG(qm) z=>t&>HIT96Kd52mVcf$5*tVsjPy@Bl4S`sIC5Xp%6ll*0GL(*tRWY;^4G`*)!X|+2 zAgKqrM|?05gNsPQ<`5DO&6!YQ74Pr?USaf!=+%qdVl2jE4(8!HZsG$z;kPITj0o?; z`VfDlejMWlah`))gQ+gqL{sM|2zOK(K?gm8`WJ_volp-!qyAurn1HERjO7?Uk&R;h zB>F;Ro5DB;jnNF2QyJW1$SiscJe|*x1uly@QlQ2XdJ_!6NKCDGKAPmD=Y{FeU!F&7-n`Ip6Q3yp*8PzmAH9~U)A{c`) z3^AC6)mVo=aTd4n5Z24tAZnmKTA>|6ApX#C1jb+v79tj#a2UsN8Jg=nJ;z&^ub`_y zad@E`>YzQkU<@Wfi@8{ZSct!*+>6sVj}+X*3%r5RO16z$a7GanM~#(I9jP`GEzlMf z*E6C++$F}nNJykgusWGRHxAMXpG3edN($nh(L!L%9G|VS(ovy0b=TD-M_!#!5StN) zdw2kG$tF4%A?u(gPTvNh^iZM+&Eb#Huoy=6unWb9b7=<^(>35#45X6B>y2N=_u_w0 zF`Kak;j8q6lEC}ABx*bQD8;m)K8lO2v1BBfNp4cp4j;|tw~n5nwXLb-)cVv^ytUJ6 zD$UJX@G&%nIVr7t`Z5*t0S>8&~Pi$?an3~OKqtuLF*GbuLstq5Y zG}fMOsgzvNxQC)_Wq~5*)sLSYsf@S(x;UQ2_hjw-p^Brn>PDqh{KTnB4&ADatNf+R8_i#j+c}>{#D4ElsSc-FQ@q(xx3%3TgA6RNNHi>^jCA-ZY4Rc3c@G z>n8PUX#P|p^l!!DFP~~4=GD^}u{mRy;||1w?MdQ)78bu)Cw{L$JjA71^`uM|%YEc% zSy%C*^2I}(F00e(t75BPru+CzI(Es2kBZZ5D!zpj$}h~FQ7Yy(<9+QslbNk3rbZ^l zCW?_UC)?M3`$>DVXtigQ5^^5x(KAZf2A;Z=EKQ9S@zAYQU96P88{L+f_T`SPAW476 zR_)4@z-9gIIxu6ni*wL6cfex>lU?B&MHOZtlAxC zm5Nn;^@%e!A#tWg?3Zm&6V=jpD=iQ?;!&M_hH&SYe($bQL*7S8f!gP173ZoWVvNkz z4m@m{M`CC$ZOG3t>=0dn#PNbEFtT07M!uaZ=7>i=BmUn??nAC1yB0QCXtG7x!q1A7 zDxqJfKEI@8zr073RIwKosDBvOAKpa#pO@xWD0Qxn@b|KH7%FhMOii?ShpzGM%}svbqR276&BHz`96^LhuyMQ zr)LHpwm*GT*3JKvuc6zkL;C5J%ZHRSIVFoG>kRQK;zhiQNHU7wcS)(5l|P*|7U|=M z{!H#FN1R0viB&|HiB}OP;+27d_Ss#;q-CJ?km-YecNNzCJT zBVEQ7q=4g&B-V%@^j@hUR~D0{*gk7I^w}ripUW>*Vi^YqF6Ce pV#XWAIL_GUlRU%N$i>N(4SuaRQDLqX%6stjTj_XDW258p{{x(dU}XRR literal 198144 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 sY^MReyY%UAJ11<=OzvrBmaQ_E_u<;-;gQO SHOW" commands 06-Jan-12 JDB Fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan) 13-Jan-11 MP Added "SHOW SHOW" and "SHOW SHOW" commands 05-Jan-11 RMS Fixed bug in deposit stride for numeric input (John Dundas) @@ -189,9 +190,8 @@ #include #include -#if defined(HAVE_READLINE) -#include -#include +#if defined(HAVE_DLOPEN) /* Dynamic Readline support */ +#include #endif #define EX_D 0 /* deposit */ @@ -1057,6 +1057,7 @@ C1TAB *ctbr, *glbr; static CTAB set_glob_tab[] = { { "CONSOLE", &sim_set_console, 0 }, { "BREAK", &brk_cmd, SSH_ST }, + { "NOBREAK", &brk_cmd, SSH_CL }, { "TELNET", &sim_set_telnet, 0 }, /* deprecated */ { "NOTELNET", &sim_set_notelnet, 0 }, /* deprecated */ { "LOG", &sim_set_logon, 0 }, /* deprecated */ @@ -1454,7 +1455,7 @@ return SCPE_OK; t_stat show_unit (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag) { -int32 u = uptr - dptr->units; +int32 u = (int32)(uptr - dptr->units); if (flag > 1) fprintf (st, " %s%d", sim_dname (dptr), u); @@ -1575,8 +1576,8 @@ for (uptr = sim_clock_queue; uptr != NULL; uptr = uptr->next) { fprintf (st, " Step timer"); else if ((dptr = find_dev_from_unit (uptr)) != NULL) { fprintf (st, " %s", sim_dname (dptr)); - if (dptr->numunits > 1) fprintf (st, " unit %d", - (int32) (uptr - dptr->units)); + if (dptr->numunits > 1) + fprintf (st, " unit %d", (int32) (uptr - dptr->units)); } else fprintf (st, " Unknown"); fprintf (st, " at %d\n", accum + uptr->time); @@ -1742,21 +1743,39 @@ return SCPE_OK; t_stat show_dev_show_commands (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr) { -int32 any, enb; +int32 any = 0; MTAB *mptr; -any = enb = 0; if (dptr->modifiers) { + any = 0; for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) { if ((!mptr->disp) || (!mptr->pstring)) continue; + if (('\0' == *mptr->pstring) || + (0 == (mptr->mask & MTAB_XTD)) || + (0 == (mptr->mask & MTAB_VDV))) /* Device Option */ + continue; if (any++) fprintf (st, ", %s", mptr->pstring); - else fprintf (st, "SHOW %s\t%s", sim_dname (dptr), mptr->pstring); + else fprintf (st, "sh{ow} %s\t%s", sim_dname (dptr), mptr->pstring); } + if (any) + fprintf (st, "\n"); + any = 0; + for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) { + if ((!mptr->disp) || (!mptr->pstring)) + continue; + if (('\0' == *mptr->pstring) || + (0 == (mptr->mask & MTAB_XTD)) || + (0 == (mptr->mask & MTAB_VUN))) /* Unit Option */ + continue; + if (any++) + fprintf (st, ", %s", mptr->pstring); + else fprintf (st, "sh{ow} %sn\t%s", sim_dname (dptr), mptr->pstring); + } + if (any) + fprintf (st, "\n"); } -if (any) - fprintf (st, "\n"); return SCPE_OK; } @@ -2043,7 +2062,7 @@ if (uptr->flags & UNIT_BUFABLE) { /* buffer? */ if (uptr->filebuf == NULL) /* no buffer? */ return attach_err (uptr, SCPE_MEM); /* error */ if (!sim_quiet) printf ("%s: buffering file in memory\n", sim_dname (dptr)); - uptr->hwmark = sim_fread (uptr->filebuf, /* read file */ + uptr->hwmark = (uint32)sim_fread (uptr->filebuf, /* read file */ SZ_D (dptr), cap, uptr->fileref); uptr->flags = uptr->flags | UNIT_BUF; /* set buffered */ } @@ -2738,8 +2757,8 @@ t_stat r = 0; t_addr k; t_value pcval; -if (v >= SCPE_BASE) fprintf (st, "\n%s, %s: ", - scp_error_messages[v - SCPE_BASE], pc->name); +if (v >= SCPE_BASE) + fprintf (st, "\n%s, %s: ", scp_error_messages[v - SCPE_BASE], pc->name); else fprintf (st, "\n%s, %s: ", sim_stop_messages[v], pc->name); pcval = get_rval (pc, 0); if (sim_vm_fprint_addr) @@ -3253,7 +3272,7 @@ for (i = 0, j = addr; i < sim_emax; i++, j = j + dptr->aincr) { SZ_LOAD (sz, sim_eval[i], uptr->filebuf, loc); } else { - sim_fseek (uptr->fileref, sz * loc, SEEK_SET); + sim_fseek (uptr->fileref, (t_addr)(sz * loc), SEEK_SET); sim_fread (&sim_eval[i], sz, 1, uptr->fileref); if ((feof (uptr->fileref)) && !(uptr->flags & UNIT_FIX)) { @@ -3344,7 +3363,7 @@ for (i = 0, j = addr; i < count; i++, j = j + dptr->aincr) { uptr->hwmark = (uint32) loc + 1; } else { - sim_fseek (uptr->fileref, sz * loc, SEEK_SET); + sim_fseek (uptr->fileref, (t_addr)(sz * loc), SEEK_SET); sim_fwrite (&sim_eval[i], sz, 1, uptr->fileref); if (ferror (uptr->fileref)) { clearerr (uptr->fileref); @@ -3428,15 +3447,40 @@ return read_line_p (NULL, cptr, size, stream); char *read_line_p (char *prompt, char *cptr, int32 size, FILE *stream) { char *tptr; +#if defined(HAVE_DLOPEN) +static int initialized = 0; +static char *(*p_readline)(const char *) = NULL; +static void (*p_add_history)(const char *) = NULL; -#if defined(HAVE_READLINE) +if (!initialized) { + initialized = 1; + void *handle; + +#define __STR_QUOTE(tok) #tok +#define __STR(tok) __STR_QUOTE(tok) + handle = dlopen("libncurses." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL); + handle = dlopen("libcurses." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL); + handle = dlopen("libreadline." __STR(HAVE_DLOPEN), RTLD_NOW|RTLD_GLOBAL); + if (!handle) + handle = dlopen("libreadline." __STR(HAVE_DLOPEN) ".6", RTLD_NOW|RTLD_GLOBAL); + if (handle) { + p_readline = dlsym(handle, "readline"); + p_add_history = dlsym(handle, "add_history"); + } + } if (prompt) { /* interactive? */ - char *tmpc = readline (prompt); /* get cmd line */ - if (tmpc == NULL) /* bad result? */ - cptr = NULL; + if (p_readline) { + char *tmpc = p_readline (prompt); /* get cmd line */ + if (tmpc == NULL) /* bad result? */ + cptr = NULL; + else { + strncpy (cptr, tmpc, size); /* copy result */ + free (tmpc) ; /* free temp */ + } + } else { - strncpy (cptr, tmpc, size); /* copy result */ - free (tmpc) ; /* free temp */ + printf ("%s", prompt); /* display prompt */ + cptr = fgets (cptr, size, stream); /* get cmd line */ } } else cptr = fgets (cptr, size, stream); /* get cmd line */ @@ -3462,9 +3506,9 @@ while (isspace (*cptr)) /* trim leading spc */ if (*cptr == ';') /* ignore comment */ *cptr = 0; -#if defined (HAVE_READLINE) -if (prompt) - add_history (cptr); +#if defined (HAVE_DLOPEN) +if (prompt && p_add_history && *cptr) /* Save non blank lines in history */ + p_add_history (cptr); #endif return cptr; @@ -3841,7 +3885,7 @@ REG *find_reg (char *cptr, char **optr, DEVICE *dptr) { char *tptr; REG *rptr; -uint32 slnt; +size_t slnt; if ((cptr == NULL) || (dptr == NULL) || (dptr->registers == NULL)) return NULL; @@ -4036,14 +4080,14 @@ if (*cptr == 0) /* check for clause */ return NULL; for (logop = cmpop = -1; c = *cptr++; ) { /* loop thru clauses */ if (sptr = strchr (logstr, c)) { /* check for mask */ - logop = sptr - logstr; + logop = (int32)(sptr - logstr); logval = strtotv (cptr, &tptr, radix); if (cptr == tptr) return NULL; cptr = tptr; } else if (sptr = strchr (cmpstr, c)) { /* check for boolop */ - cmpop = sptr - cmpstr; + cmpop = (int32)(sptr - cmpstr); if (*cptr == '=') { cmpop = cmpop + strlen (cmpstr); cptr++; @@ -4814,7 +4858,7 @@ if (sim_deb && (dptr->dctrl & dbits)) { #if defined (_WIN32) #define vsnprintf _vsnprintf #endif -#if defined (__DECC) && defined (__VMS) +#if defined (__DECC) && defined (__VMS) && (defined (__VAX) || (__CRTL_VER <= 70311000)) #define NO_vsnprintf #endif #if defined( NO_vsnprintf) diff --git a/sigma/Design Notes on the Sigma 7.doc b/sigma/Design Notes on the Sigma 7.doc deleted file mode 100644 index fa42bb907269a3017409252d18009152d170e991..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25088 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, instead of > 0. -5. CPU: PSD change instructions were not saving old PC in PC queue. -6. CPU: illegal register pointer does not stop the system on the Sigma 5-7; - instead, registers read as 0's, and writes are ignored. -7. CPU: traps were setting the Sigma 9 vector field unconditionally. -8. CPU: CH does not SEXT Rn<16:31>. -9. CPU: MTW and MTH overflow traps not implemented. -10. CPU: MTH condition code calculations not implemented correctly. -11. CPU: illegal shift opcodes on the Sigma 5-7 are treated as arithmetic - single (according to the AUTO diagnostic). -12. FP: SF did not calculate condition codes correctly. -13. FP: SF left did not detect normalized if the count reached zero. -14. FP: SF right was retaining a guard digit incorrectly. -15. FP: SF right test was not taking into account single/double precision. -16. FP: fp_unpack killed the operand sign before testing it. -17. FP: fp_pack did not recomplement a negative operand. -18. CPU: DW overflow test was incorrect. -19. IO: device status bit field was incorrectly defined. -20. IO: AIO was testing for == 0 instead of != 0. -21. TT: input keyboard character mappings were incorrect. -22. SYS: shifts were not displaying or accepting an index register. -23. CPU: mapping from pulse interrupt number to counter interrupt number - was incorrect. -24. CPU, CIS: handling of instructions aborts was incorrect. -25. CPU: CC2,4 set incorrectly on aborted stack instruction. -26. CPU: CC2,4 set incorrectly on MSP,0 instruction. -27. CPU: PLW not converting operand address to byte address. -28. CPU: PSM, PLM not converting limit operand address to byte address correctly. -29. CPU: PLM wrote registers in inverse order. -30. Definitions: number of virtual, physical pages derived incorrectly. -31. MAP: MMC control set wrap incorrect. -32. MAP: MMC register update of Rn|1 incorrect. -33. CPU: CBS set CC's incorrectly on unequal. -34. CPU: TTBS set CC's incorrectly on early exit. -35. IO: chan_proc_epilog and four other routines extracted device address incorrectly. -36. CPU: DW was fetching halfwords instead of words. -37. CPU: multiples were not setting condition codes on 0 operands. -38. FP: floating add zero test on second operand was inverted. -39. FP: floating add zero cases failed to set the result variable. -40. FP: floating add zero cases failed to go through postnormalization logic. -41. FP: double precision add macro lost high carry out. -42. FP: double precision add macro had an undocumented restriction about operands. -43. FP: all double precision instructions unpacked the wrong low order memory operand. -44. FP: normalization failed to decrement the exponent. -45. FP: in single precision, removing the guard digit created a spurious low-order digit. -46. FP: denormalization failed to clear the low word (single precision). -47. FP: denormalization failed to clear the guard digit (double precision). -48. FP: add/subtract failed to treat abnormal 0's as normal numbers. -49. CIS: WriteDecA set local rather than global condition codes. -50. CIS: Illegal digit check missed byte 0. -51. CIS: Overflow check set wrong condition codes. -52. CIS: NibbleLShift routine overflow check was (also broken in VAX, PDP11). -53. CIS: WordLShift routine overflow check was wrong (also broken in VAX, PDP11). -54. CIS: WordLShift had signed/unsigned variable conflict in compare. -55. CIS: WriteDecA not setting correct condition codes for -0. -55. CIS: WriteDECA not clearing CC3/4 before setting. -56. CIS: DM shift-and-test loop did 14 iterations instead of 15. -57. CIS: DM final shift of 16 done outside non-zero case instead of inside. -58. CIS: DD put quotient and remainder in wrong registers. -59. CIS: DD did not shift remainder to proper place, based on dividend/divisor widths. -60. CIS: DD overflow test missed exact 16 digit quotient case. -61. CIS: algorithm to compute length of operand failed for certain lengths (also broken - in VAX, PDP11). -62. CIS: DM and DD answer was wrong on restart cases. [NOT FIXED YET] -63. CIS: EBS fetched pattern from wrong address pointer. -64. CIS: EBS field separator wrote wrong byte. -65. MAP: Access codes defined incorrectly for access protection check. -66. CPU: LPSD fetching operands with write check rather than read check. -67. CPU: Illegal instruction stop (and other trap stops) weren't rolling back the PC. -68. CPU: History routine merged CC's into history array incorrectly. -69. CPU: History routine stored incremented rather than actualy PC. -70. CPU: History reporting routine printed wrong operand value, due to colliding declarations. -71. IO: Power up/down interrupts should not be implemented. -72. IO: WD was not recalculating int_hiact. -73. IO: Interrupt chain was not linked at powerup. -74. IO: Interrupt chain link algorithm was wrong. -75. IO: WD processing was spanning [beg,end) rather than [beg,end]. -76. RTC: RTC interrupts were happening at the wrong level. -77. PTR: leader skip was testing for channel end. -78. PTR: leader skip was testing per command instead of per reel/file. -79. PTR: end of file was treated as fatal error instead of channel end + length error. -80. PTR, PTP: units were not marked UNIT_SEQ. -81. LPT: unit was not marked UNIT_SEQ. -82. IO: device address set/show updated/displayed wrong field in single unit devices. -83. CPU: address calculation for MTx in interrupt location used incorrect length. -84. LPT: print, format opcode definitions inverted. -85. LPT: wrong index used to count buffer fill loop. -86. IO: CPU/IOP communications through 20/21 were not modelled. -87. CIS: Multiply algorithm incorrect, multiply restart not modelled. -88. CIS: Divide algorithm incorrect, divide restart not modelled. -89. IO: WD .44 not recognized as effective NOP. -90. CPU: Sigma 5 (uniquely) does not implement CVA or CVS. -91. IO: AIO merging status incorrectly. -92. IO: system for returning status byte from IO was muddled; rewrite required. -93. RAD: 7232 track shift offset was incorrectly defined. -94. CPU: MTX for interrupts returned wrong value. -95. CPU: Counter overflow trigger equation was incorrect. -96. CPU: MTX interrupts not recalculating interrupt summary values. -97. RTC: SET/SHOW C1-C4 routines were broken. -98. DP: comparison for sector field overflow was incorrect. -99. DP: cross-cylinder incorrectly set on read to end of cylinder. -100. DP: seek never executed. -101. DP: seek followon state codes set incorrectly. -102. DP: cylinder offset defined incorrectly. -103. DP: SIO not initing unit thread properly for non-zero units. -104. MUX: Line enable must be remembered for lines that are not currently connected. -105. RAD: write check was reading words off disk instead of bytes. -106. RAD: end of transfer routine checking for address error incorrectly. -107. DK: end of transfer routine checking for address error incorrectly. - - -Diagnostic Notes ----------------- - -1. PATTERN paper tape (SA = 60, end pass = 1AC), SET CPU RBLKS=32. - Break at 60 is triggered once during loading process. -2. VERIFY paper tape (SA = 140, end pass = 8E6). -3. AUTO paper tape (SA = 105), SET CPU LASLMS to suppress spurious error message. - AUTO magtape runs correctly with no messages. -4. SUFFIX magtape (SA = 100, end pass = 115), no printouts. -5. FLOAT magtape. -6. DECIMAL paper tape (SA = EE). -7. PROTECT paper tape (SA = F9), long runtime until printout. -8. MAP paper tape (SA = 7C). -9. MEDIC paper tape (SA = 68), set SSW2 after breakpoint, long runtime. -10. INT magtape, stops after M6, set SSW2 and continue, - enters pattern generator and loops forever, as expected. -11. RTC paper tape, clocks must be 500Mhz, reports clocks as "too slow" due - to faster simulation speed. - Runs correctly with SET THROTTLE 500K. - - - - - - - - - - - - - - - diff --git a/sigma/sigma_cis.c b/sigma/sigma_cis.c deleted file mode 100644 index 3205ac05..00000000 --- a/sigma/sigma_cis.c +++ /dev/null @@ -1,990 +0,0 @@ -/* sigma_cis.c: Sigma decimal instructions - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - Questions: - - 1. On the Sigma 9, in ASCII mode, is an ASCII blank used in EBS? -*/ - -#include "sigma_defs.h" - -/* Decimal string structure */ - -#define DSTRLNT 4 /* words per dec string */ -#define DECA 12 /* first dec accum reg */ - -/* Standard characters */ - -#define ZONE_E 0xF0 /* EBCDIC zone bits */ -#define ZONE_A 0x30 /* ASCII zone bits */ -#define ZONE ((PSW1 & PSW1_AS)? ZONE_A: ZONE_E) -#define PKPLUS_E 0xC /* EBCDIC preferred plus */ -#define PKPLUS_A 0xA /* ASCII preferred plus */ -#define PKPLUS ((PSW1 & PSW1_AS)? PKPLUS_A: PKPLUS_E) -#define BLANK_E 0x40 /* EBCDIC blank */ -#define BLANK_A 0x20 /* ASCII blank */ -#define BLANK ((PSW1 & PSW1_AS)? BLANK_A: BLANK_E) - -/* Edit special characters */ - -#define ED_DS 0x20 /* digit select */ -#define ED_SS 0x21 /* start significance */ -#define ED_FS 0x22 /* field separator */ -#define ED_SI 0x23 /* immediate significance */ - -/* Decimal strings run low order (word 0/R15) to high order (word 3/R12) */ - -typedef struct { - uint32 sign; - uint32 val[DSTRLNT]; - } dstr_t; - -/* Copy decimal accumulator to decimal string, no validation or sign separation */ - -#define ReadDecA(src) for (i = 0; i < DSTRLNT; i++) \ - src.val[DSTRLNT - 1 - i] = R[DECA + i]; - -static dstr_t Dstr_zero = { 0, 0, 0, 0, 0 }; - -extern uint32 *R; -extern uint32 CC; -extern uint32 PSW1; -extern uint32 bvamqrx; -extern uint32 cpu_model; - -uint32 ReadDstr (uint32 lnt, uint32 addr, dstr_t *dec); -uint32 WriteDstr (uint32 lnt, uint32 addr, dstr_t *dec); -void WriteDecA (dstr_t *dec, t_bool cln); -void SetCC2Dstr (uint32 lnt, dstr_t *dst); -uint32 TestDstrValid (dstr_t *src); -uint32 DstrInvd (void); -uint32 AddDstr (dstr_t *src1, dstr_t *src2, dstr_t *dst, uint32 cin); -void SubDstr (dstr_t *src1, dstr_t *src2, dstr_t *dst); -int32 CmpDstr (dstr_t *src1, dstr_t *src2); -uint32 LntDstr (dstr_t *dsrc); -uint32 NibbleLshift (dstr_t *dsrc, uint32 sc, uint32 cin); -uint32 NibbleRshift (dstr_t *dsrc, uint32 sc, uint32 cin); -t_bool GenLshift (dstr_t *dsrc, uint32 sc); -void GenRshift (dstr_t *dsrc, uint32 sc); -uint32 ed_getsrc (uint32 sa, uint32 *c, uint32 *d); -void ed_advsrc (uint32 rn, uint32 c); -t_bool cis_test_int (dstr_t *src1, uint32 *kint); -void cis_dm_int (dstr_t *src, dstr_t *dst, uint32 kint); -void cis_dd_int (dstr_t *src, dstr_t *dst, uint32 t, uint32 *kint); - -/* Decimal instructions */ - -uint32 cis_dec (uint32 op, uint32 lnt, uint32 bva) -{ -dstr_t src1, src2, src2x, dst; -uint32 i, t, kint, ldivr, ldivd, ad, c, d, end; -int32 sc; -uint32 tr; - -if (lnt == 0) /* adjust length */ - lnt = 16; -CC &= ~(CC1|CC2); /* clear CC1, CC2 */ - -switch (op) { /* case on opcode */ - - case OP_DL: /* decimal load */ - if ((tr = ReadDstr (lnt, bva, &dst)) != 0) /* read mem string */ - return tr; - WriteDecA (&dst, FALSE); /* store result */ - break; - - case OP_DST: /* decimal store */ - ReadDecA (dst); /* read dec accum */ - if ((tr = TestDstrValid (&dst)) != 0) /* valid? */ - return tr; - if ((tr = WriteDstr (lnt, bva, &dst)) != 0) /* write to mem */ - return tr; - break; - - case OP_DS: /* decimal subtract */ - case OP_DA: /* decimal add */ - ReadDecA (src1); /* read dec accum */ - if ((tr = TestDstrValid (&src1)) != 0) /* valid? */ - return tr; - if ((tr = ReadDstr (lnt, bva, &src2)) != 0) /* read mem string */ - return tr; - if (op == OP_DS) /* sub? invert sign */ - src2.sign = src2.sign ^ 1; - if (src1.sign ^ src2.sign) { /* opp signs? sub */ - if (CmpDstr (&src1, &src2) < 0) { /* src1 < src2? */ - SubDstr (&src1, &src2, &dst); /* src2 - src1 */ - dst.sign = src2.sign; /* sign = src2 */ - } - else { - SubDstr (&src2, &src1, &dst); /* src1 - src2 */ - dst.sign = src1.sign; /* sign = src1 */ - } - } - else { /* addition */ - if (AddDstr (&src1, &src2, &dst, 0)) { /* add, overflow? */ - CC |= CC2; /* set CC2 */ - return (PSW1 & PSW1_DM)? TR_DEC: 0; /* trap if enabled */ - } - dst.sign = src1.sign; /* set result sign */ - } - WriteDecA (&dst, TRUE); /* store result */ - break; - - case OP_DC: /* decimal compare */ - ReadDecA ( src1); /* read dec accum */ - if ((tr = TestDstrValid (&src1)) != 0) /* valid? */ - return tr; - if ((tr = ReadDstr (lnt, bva, &src2)) != 0) /* read mem string */ - return tr; - LntDstr (&src1); /* clean -0 */ - LntDstr (&src2); - if (src1.sign ^ src2.sign) /* signs differ? */ - CC = src1.sign? CC4: CC3; /* set < or > */ - else { /* same signs */ - t = CmpDstr (&src1, &src2); /* compare strings */ - if (t < 0) - CC = (src1.sign? CC3: CC4); - else if (t > 0) - CC = (src1.sign? CC4: CC3); - else CC = 0; - } - break; - -/* Decimal multiply - algorithm from George Plue. - - The Sigma does decimal multiply one digit at a time, using the multiplicand - and a doubled copy of the multiplicand. Multiplying by digits 1-5 is - synthesized by 1-3 adds; multiplying by digits 6-9 is synthesized by 1-2 - subtractions, and adding 1 to the next multiplier digit. (That is, - multiplying by 7 is done by multiplying by "10 - 3".) This requires at - most one extra add to fixup the last digit, and minimizes the overall - number of adds (average 1.5 adds per multiplier digit). Note that - multiplication proceeds from right to left. - - The Sigma 5-9 allowed decimal multiply to be interrupted; the 5X0 series - did not. An interrupted multiply uses a sign digit in R12 and R13 as the - divider between the remaining multiplier (to the left of the sign, and - in the low-order digit of R15) and the partial product (to the right of - the sign). Because the partial product may be negative, leading 0x99's - may have been stripped and need to be restored. - - The real Sigma's probably didn't run a validty test after separation of - the partial product and multiplier, but it doesn't hurt, and prevents - certain corner cases from causing errors. */ - - case OP_DM: /* decimal multiply */ - if (lnt >= 9) /* invalid length? */ - return DstrInvd (); - ReadDecA (src1); /* get dec accum */ - if ((tr = ReadDstr (lnt, bva, &src2)) != 0) /* read mem string */ - return tr; - dst = Dstr_zero; /* clear result */ - kint = 0; /* assume no int */ - if (!QCPU_5X0 && /* S5-9? */ - (cis_test_int (&src1, &kint))) /* interrupted? */ - cis_dm_int (&src1, &dst, kint); /* restore */ - else if ((tr = TestDstrValid (&src1)) != 0) /* mpyr valid? */ - return tr; - if (LntDstr (&src1) && LntDstr (&src2)) { /* both opnds != 0? */ - dst.sign = src1.sign ^ src2.sign; /* sign of result */ - AddDstr (&src2, &src2, &src2x, 0); /* get 2*mplcnd */ - for (i = 1; i <= 16; i++) { /* 16 iterations */ - if (i >= kint) { /* past int point? */ - NibbleRshift (&src1, 1, 0); /* mpyr right 4 */ - d = src1.val[0] & 0xF; /* get digit */ - switch (d) { /* case */ - case 5: /* + 2 + 2 + 1 */ - AddDstr (&src2x, &dst, &dst, 0); - case 3: /* + 2 + 1 */ - AddDstr (&src2x, &dst, &dst, 0); - case 1: /* + 1 */ - AddDstr (&src2, &dst, &dst, 0); - case 0: - break; - case 4: /* + 2 + 2 */ - AddDstr (&src2x, &dst, &dst, 0); - case 2: /* + 2 */ - AddDstr (&src2x, &dst, &dst, 0); - break; - case 6: /* - 2 - 2 + 10 */ - SubDstr (&src2x, &dst, &dst); - case 8: /* - 2 + 10 */ - SubDstr (&src2x, &dst, &dst); - src1.val[0] += 0x10; /* + 10 */ - break; - case 7: /* -2 - 1 + 10 */ - SubDstr (&src2x, &dst, &dst); - case 9: /* -1 + 10 */ - SubDstr (&src2, &dst, &dst); - default: /* + 10 */ - src1.val[0] += 0x10; - } /* end switch */ - } /* end if >= kint */ - NibbleLshift (&src2, 1, 0); /* shift mplcnds */ - NibbleLshift (&src2x, 1, 0); - } /* end for */ - } /* end if != 0 */ - WriteDecA (&dst, TRUE); /* store result */ - break; - -/* Decimal divide overflow calculation - if the dividend has true length d, - and the divisor true length r, then the quotient will have (d - r) or - (d - r + 1) digits. Therefore, if (d - r) > 15, the quotient will not - fit. However, if (d - r) == 15, it may or may not fit, depending on - whether the first subtract succeeds. Therefore, it's necessary to test - after the divide to see if the quotient has one extra digit. */ - - case OP_DD: /* decimal divide */ - if (lnt >= 9) /* invalid length? */ - return DstrInvd (); - ReadDecA (src1); /* read dec accum */ - if ((tr = ReadDstr (lnt, bva, &src2)) != 0) /* read mem string */ - return tr; - dst = Dstr_zero; /* clear result */ - kint = 0; /* no interrupt */ - if (!QCPU_5X0 && /* S5-9? */ - (cis_test_int (&src1, &t))) { /* interrupted? */ - cis_dd_int (&src1, &dst, t, &kint); /* restore */ - t = t - 1; - } - else { /* normal start? */ - if ((tr = TestDstrValid (&src1)) != 0) /* divd valid? */ - return tr; - ldivr = LntDstr (&src2); /* divr lnt */ - ldivd = LntDstr (&src1); /* divd lnt */ - if ((ldivr == 0) || /* div by zero? */ - (ldivd > (ldivr + 15))) { /* quo too big? */ - CC |= CC2; /* divide check */ - return (PSW1 & PSW1_DM)? TR_DEC: 0; /* trap if enabled */ - } - if (CmpDstr (&src1, &src2) < 0) { /* no divide? */ - R[12] = src1.val[1]; /* remainder */ - R[13] = src1.val[0] | (PKPLUS + src1.sign); - R[14] = 0; /* quotient */ - R[15] = PKPLUS; - CC = 0; - return SCPE_OK; - } - t = ldivd - ldivr; - } - dst.sign = src1.sign ^ src2.sign; /* calculate sign */ - GenLshift (&src2, t); /* align */ - for (i = 0; i <= t; i++) { /* divide loop */ - for (d = kint; /* find digit */ - (d < 10) && (CmpDstr (&src1, &src2) >= 0); - d++) - SubDstr (&src2, &src1, &src1); - dst.val[0] = (dst.val[0] & ~0xF) | d; /* insert quo dig */ - NibbleLshift (&dst, 1, 0); /* shift quotient */ - NibbleRshift (&src2, 1, 0); /* shift divisor */ - kint = 0; /* no more int */ - } /* end divide loop */ - if (dst.val[2]) { /* quotient too big? */ - CC |= CC2; /* divide check */ - return (PSW1 & PSW1_DM)? TR_DEC: 0; /* trap if enabled */ - } - CC = dst.sign? CC4: CC3; /* set CC's */ - R[12] = src1.val[1]; /* remainder */ - R[13] = src1.val[0] | (PKPLUS + src1.sign); - R[14] = dst.val[1]; /* quotient */ - R[15] = dst.val[0] | (PKPLUS + dst.sign); - break; - - case OP_DSA: /* decimal shift */ - ReadDecA (dst); /* read dec accum */ - if ((tr = TestDstrValid (&dst)) != 0) /* valid? */ - return tr; - CC = 0; /* clear CC's */ - sc = SEXT_H_W (bva >> 2); /* shift count */ - if (sc > 31) /* sc in [-31,31] */ - sc = 31; - if (sc < -31) - sc = -31; - if (sc < 0) { /* right shift? */ - sc = -sc; /* |shift| */ - GenRshift (&dst, sc); /* do shift */ - dst.val[0] = dst.val[0] & ~0xF; /* clear sign */ - } /* end right shift */ - else if (sc) { /* left shift? */ - if (GenLshift (&dst, sc)) /* do shift */ - CC |= CC2; - } /* end left shift */ - WriteDecA (&dst, FALSE); /* store result */ - break; - - case OP_PACK: /* zoned to packed */ - dst = Dstr_zero; /* clear result */ - end = (2 * lnt) - 1; /* zoned length */ - for (i = 1; i <= end; i++) { /* loop thru char */ - ad = (bva + end - i) & bvamqrx; /* zoned character */ - if ((tr = ReadB (ad, &c, VR)) != 0) /* read char */ - return tr; - if (i == 1) { /* sign + digit? */ - uint32 s; - s = (c >> 4) & 0xF; /* get sign */ - if (s < 0xA) - return DstrInvd (); - if ((s == 0xB) || (s == 0xD)) /* negative */ - dst.sign = 1; - } - d = c & 0xF; /* get digit */ - if (d > 0x9) - return DstrInvd (); - dst.val[i / 8] = dst.val[i / 8] | (d << ((i % 8) * 4)); - } - WriteDecA (&dst, FALSE); /* write result */ - break; - - case OP_UNPK: /* packed to zoned */ - ReadDecA (dst); /* read dec accum */ - if ((tr = TestDstrValid (&dst)) != 0) /* valid? */ - return tr; - end = (2 * lnt) - 1; /* zoned length */ - if ((tr = ReadB (bva, &c, VW)) != 0) /* prove writeable */ - return tr; - for (i = 1; i <= end; i++) { /* loop thru chars */ - c = (dst.val[i / 8] >> ((i % 8) * 4)) & 0xF; /* get digit */ - if (i == 1) /* first? */ - c |= ((PKPLUS + dst.sign) << 4); /* or in sign */ - else c |= ZONE; /* no, or in zone */ - ad = (bva + end - i) & bvamqrx; - if ((tr = WriteB (ad, c, VW)) != 0) /* write to memory */ - return tr; - } - SetCC2Dstr (lnt, &dst); /* see if too long */ - break; - } -return 0; -} - -/* Test for interrupted multiply or divide */ - -t_bool cis_test_int (dstr_t *src, uint32 *kint) -{ -int32 i; -uint32 wd, sc, d; - -for (i = 15; i >= 1; i--) { /* test 15 nibbles */ - wd = (DSTRLNT/2) + (i / 8); - sc = (i % 8) * 4; - d = (src->val[wd] >> sc) & 0xF; - if (d >= 0xA) { - *kint = (uint32) i; - return TRUE; - } - } -return FALSE; -} - -/* Resume interrupted multiply - - The sign that was found is the "fence" between the the remaining multiplier - and the partial product: - R val - +--+--+--+--+--+--+--+--+ - | mpyer |sn|pp| 12 3 - +--+--+--+--+--+--+--+--+ - | partial product | 13 2 - +--+--+--+--+--+--+--+--+ - | partial product | 14 1 - +--+--+--+--+--+--+--+--+ - | partial product |mp| 15 0 - +--+--+--+--+--+--+--+--+ - - This routine separates the multiplier and partial product, returns the - multiplier as a valid decimal string in src, and the partial product - as a value with no sign in dst */ - -void cis_dm_int (dstr_t *src, dstr_t *dst, uint32 kint) -{ -uint32 ppneg, wd, sc, d, curd; -int32 k; - -*dst = *src; /* copy input */ -wd = (DSTRLNT/2) + (kint / 8); -sc = (kint % 8) * 4; -d = (src->val[wd] >> sc) & 0xF; /* get sign fence */ -ppneg = ((d >> 2) & 1) ^ 1; /* partial prod neg? */ -curd = (src->val[0] & 0xF) + ppneg; /* bias cur digit */ -src->val[wd] = (src->val[wd] & ~(0xF << sc)) | /* replace sign */ - (curd << sc); /* with digit */ -GenRshift (src, kint + 15); /* right justify */ -src->sign = ((d == 0xB) || (d == 0xD))? 1: 0; /* set mpyr sign */ -src->val[0] = src->val[0] & ~0xF; /* clear sign pos */ - -/* Mask out multiplier */ - -for (k = DSTRLNT - 1; k >= (int32) wd; k--) /* words hi to lo */ - dst->val[k] &= ~(0xFFFFFFFFu << - ((k > (int32) wd)? 0: sc)); - -/* Recreate missing high order digits for negative partial product */ - -if (ppneg) { /* negative? */ - for (k = (DSTRLNT * 4) - 1; k != 0; k--) { /* bytes hi to lo */ - wd = k / 4; - sc = (k % 4) * 8; - if (((dst->val[wd] >> sc) & 0xFF) != 0) - break; - dst->val[wd] |= (0x99 << sc); /* repl 00 with 99 */ - } /* end for */ - } -dst->val[0] &= ~0xF; /* clear pp sign */ -return; -} - -/* Resume interrupted divide - - The sign that was found is the "fence" between the the quotient and the - remaining dividend product: - R val - +--+--+--+--+--+--+--+--+ - | quotient |sn|dv| 12 3 - +--+--+--+--+--+--+--+--+ - | dividend | 13 2 - +--+--+--+--+--+--+--+--+ - | dividend | 14 1 - +--+--+--+--+--+--+--+--+ - | dividend |qu| 15 0 - +--+--+--+--+--+--+--+--+ - - This routine separates the quotient and the remaining dividend, returns - the dividend as a valid decimal string, the quotient as a decimal string - without sign, and kint is the partial value of the last quotient digit. */ - -void cis_dd_int (dstr_t *src, dstr_t *dst, uint32 nib, uint32 *kint) -{ -uint32 wd, sc, d, curd; -int32 k; - -wd = (DSTRLNT/2) + (nib / 8); -sc = (nib % 8) * 4; -curd = src->val[0] & 0xF; /* last quo digit */ -*dst = *src; /* copy input */ -GenRshift (dst, nib + 16); /* right justify quo */ -d = dst->val[0] & 0xF; /* get sign fence */ -dst->val[0] = (dst->val[0] & ~0xF) | curd; /* repl with digit */ -*kint = curd; - -/* Mask out quotient */ - -for (k = DSTRLNT - 1; k >= (int32) wd; k--) /* words hi to lo */ - src->val[k] &= ~(0xFFFFFFFFu << - ((k > (int32) wd)? 0: sc)); -src->sign = ((d == 0xB) || (d == 0xD))? 1: 0; /* set divd sign */ -src->val[0] = src->val[0] & ~0xF; /* clr sign digit */ -return; -} - -/* Get packed decimal string from memory - - Arguments: - lnt = decimal string length - adr = decimal string address - src = decimal string structure - Output: - trap or abort signal - - Per the Sigma spec, bad digits or signs cause a fault or abort */ - -uint32 ReadDstr (uint32 lnt, uint32 adr, dstr_t *src) -{ -uint32 i, c, bva; -uint32 tr; - -*src = Dstr_zero; /* clear result */ -for (i = 0; i < lnt; i++) { /* loop thru string */ - bva = (adr + lnt - i - 1) & bvamqrx; /* from low to high */ - if ((tr = ReadB (bva, &c, VR)) != 0) /* read byte */ - return tr; - src->val[i / 4] = src->val[i / 4] | (c << ((i % 4) * 8)); - } /* end for */ -return TestDstrValid (src); -} - -/* Separate sign, validate sign and digits of decimal string */ - -uint32 TestDstrValid (dstr_t *src) -{ -uint32 i, j, s, t; - -s = src->val[0] & 0xF; /* get sign */ -if (s < 0xA) /* valid? */ - return DstrInvd (); -if ((s == 0xB) || (s == 0xD)) /* negative? */ - src->sign = 1; -else src->sign = 0; -src->val[0] &= ~0xF; /* clear sign */ - -for (i = 0; i < DSTRLNT; i++) { /* check 4 words */ - for (j = 0; j < 8; j++) { /* 8 digit/word */ - t = (src->val[i] >> (28 - (j * 4))) & 0xF; /* get digit */ - if (t > 0x9) /* invalid digit? */ - return DstrInvd (); /* exception */ - } - } -return 0; -} - -/* Invalid digit or sign: set CC1, trap or abort instruction */ - -uint32 DstrInvd (void) -{ -CC |= CC1; /* set CC1 */ -if (PSW1 & PSW1_DM) /* if enabled, trap */ - return TR_DEC; -return WSIGN; /* otherwise, abort */ -} - -/* Store decimal string - - Arguments: - lnt = decimal string length - adr = decimal string address - dst = decimal string structure - - Returns memory management traps (if any) - Bad digits and invalid sign are impossible -*/ - -uint32 WriteDstr (uint32 lnt, uint32 adr, dstr_t *dst) -{ -uint32 i, bva, c; -uint32 tr; - -dst->val[0] = dst->val[0] | (PKPLUS + dst->sign); /* set sign */ -if ((tr = ReadB (adr, &c, VW)) != 0) /* prove writeable */ - return tr; -for (i = 0; i < lnt; i++) { /* loop thru bytes */ - c = (dst->val[i / 4] >> ((i % 4) * 8)) & 0xFF; /* from low to high */ - bva = (adr + lnt - i - 1) & bvamqrx; - if ((tr = WriteB (bva, c, VW)) != 0) /* store byte */ - return tr; - } /* end for */ -SetCC2Dstr (lnt, dst); /* check overflow */ -return 0; -} - -/* Store result in decimal accumulator - - Arguments: - dst = decimal string structure - cln = clean -0 if true - - Sets condition codes CC3 and CC4 - Bad digits and invalid sign are impossible */ - -void WriteDecA (dstr_t *dst, t_bool cln) -{ -uint32 i, nz; - -CC &= ~(CC3|CC4); /* assume zero */ -for (i = 0, nz = 0; i < DSTRLNT; i++) { /* save 32 digits */ - R[DECA + i] = dst->val[DSTRLNT - 1 - i]; - nz |= dst->val[DSTRLNT - 1 - i]; - } -if (nz) /* non-zero? */ - CC |= (dst->sign)? CC4: CC3; /* set CC3 or CC4 */ -else if (cln) /* zero, clean? */ - dst->sign = 0; /* clear sign */ -R[DECA + DSTRLNT - 1] |= (PKPLUS + dst->sign); /* or in sign */ -return; -} - -/* Set CC2 for decimal string store - - Arguments: - lnt = string length - dst = decimal string structure - Output: - sets CC2 if information won't fit */ - -void SetCC2Dstr (uint32 lnt, dstr_t *dst) -{ -uint32 i, limit, mask; -static uint32 masktab[8] = { - 0xFFFFFFF0, 0xFFFFFF00, 0xFFFFF000, 0xFFFF0000, - 0xFFF00000, 0xFF000000, 0xF0000000, 0x00000000 - }; - -lnt = (lnt * 2) - 1; /* number of digits */ -mask = 0; /* can't ovflo */ -limit = lnt / 8; /* limit for test */ -for (i = 0; i < DSTRLNT; i++) { /* loop thru value */ - if (i == limit) /* @limit, get mask */ - mask = masktab[lnt % 8]; - else if (i > limit) /* >limit, test all */ - mask = 0xFFFFFFFF; - if (dst->val[i] & mask) /* test for ovflo */ - CC |= CC2; - } -return; -} - -/* Add decimal string magnitudes - - Arguments: - s1 = src1 decimal string - s2 = src2 decimal string - ds = dest decimal string - cy = carry in - Output: - 1 if carry, 0 if no carry - - This algorithm courtesy Anton Chernoff, circa 1992 or even earlier. - - We trace the history of a pair of adjacent digits to see how the - carry is fixed; each parenthesized item is a 4b digit. - - Assume we are adding: - - (a)(b) I - + (x)(y) J - - First compute I^J: - - (a^x)(b^y) TMP - - Note that the low bit of each digit is the same as the low bit of - the sum of the digits, ignoring the carry, since the low bit of the - sum is the xor of the bits. - - Now compute I+J+66 to get decimal addition with carry forced left - one digit: - - (a+x+6+carry mod 16)(b+y+6 mod 16) SUM - - Note that if there was a carry from b+y+6, then the low bit of the - left digit is different from the expected low bit from the xor. - If we xor this SUM into TMP, then the low bit of each digit is 1 - if there was a carry, and 0 if not. We need to subtract 6 from each - digit that did not have a carry, so take ~(SUM ^ TMP) & 0x11, shift - it right 4 to the digits that are affected, and subtract 6*adjustment - (actually, shift it right 3 and subtract 3*adjustment). -*/ - -uint32 AddDstr (dstr_t *s1, dstr_t *s2, dstr_t *ds, uint32 cy) -{ -uint32 i; -uint32 sm1, sm2, tm1, tm2, tm3, tm4; - -for (i = 0; i < DSTRLNT; i++) { /* loop low to high */ - tm1 = s1->val[i] ^ (s2->val[i] + cy); /* xor operands */ - sm1 = s1->val[i] + (s2->val[i] + cy); /* sum operands */ - sm2 = sm1 + 0x66666666; /* force carry out */ - cy = ((sm1 < s1->val[i]) || (sm2 < sm1)); /* check for ovflo */ - tm2 = tm1 ^ sm2; /* get carry flags */ - tm3 = (tm2 >> 3) | (cy << 29); /* compute adjust */ - tm4 = 0x22222222 & ~tm3; /* clrr where carry */ - ds->val[i] = (sm2 - (3 * tm4)) & WMASK; /* final result */ - } -return cy; -} - -/* Subtract decimal string magnitudes - - Arguments: - s1 = src1 decimal string - s2 = src2 decimal string - ds = dest decimal string - - Note: the routine assumes that s1 <= s2 - -*/ - -void SubDstr (dstr_t *s1, dstr_t *s2, dstr_t *ds) -{ -uint32 i; -dstr_t compl; - -for (i = 0; i < DSTRLNT; i++) /* 9's comp s2 */ - compl.val[i] = 0x99999999 - s1->val[i]; -AddDstr (&compl, s2, ds, 1); /* s1 + ~s2 + 1 */ -return; -} - -/* Compare decimal string magnitudes - - Arguments: - s1 = src1 decimal string - s2 = src2 decimal string - Output: - 1 if >, 0 if =, -1 if < -*/ - -int32 CmpDstr (dstr_t *s1, dstr_t *s2) -{ -int32 i; - -for (i = DSTRLNT - 1; i >=0; i--) { - if (s1->val[i] > s2->val[i]) - return 1; - if (s1->val[i] < s2->val[i]) - return -1; - } -return 0; -} - -/* Get exact length of decimal string, clean -0 - - Arguments: - dst = decimal string structure - Output: - number of non-zero digits -*/ - -uint32 LntDstr (dstr_t *dst) -{ -int32 nz, i; - -for (nz = DSTRLNT - 1; nz >= 0; nz--) { - if (dst->val[nz]) { - for (i = 7; i >= 0; i--) { - if ((dst->val[nz] >> (i * 4)) & 0xF) - return (nz * 8) + i; - } - } - } -dst->sign = 0; -return 0; -} - -/* Word shift right - - Arguments: - dsrc = decimal string structure - sc = shift count in nibbles -*/ - -void GenRshift (dstr_t *dsrc, uint32 cnt) -{ -uint32 i, sc, sc1; - -sc = cnt / 8; -sc1 = cnt % 8; -if (sc) { - for (i = 0; i < DSTRLNT; i++) { - if ((i + sc) < DSTRLNT) - dsrc->val[i] = dsrc->val[i + sc]; - else dsrc->val[i] = 0; - } - } -if (sc1) - NibbleRshift (dsrc, sc1, 0); -return; -} - -/* General shift left - - Arguments: - dsrc = decimal string structure - cnt = shift count in nibbles -*/ - -t_bool GenLshift (dstr_t *dsrc, uint32 cnt) -{ -t_bool i, c, sc, sc1; - -c = 0; -sc = cnt / 8; -sc1 = cnt % 8; -if (sc) { - for (i = DSTRLNT - 1; (int32) i >= 0; i--) { - if (i >= sc) - dsrc->val[i] = dsrc->val[i - sc]; - else { - c |= dsrc->val[i]; - dsrc->val[i] = 0; - } - } - } -if (sc1) - c |= NibbleLshift (dsrc, sc1, 0); -return (c? TRUE: FALSE); -} - -/* Nibble shift right - - Arguments: - dsrc = decimal string structure - sc = shift count in nibbles - cin = carry in -*/ - -uint32 NibbleRshift (dstr_t *dsrc, uint32 sc, uint32 cin) -{ -int32 i; -uint32 s, nc; - -if (s = sc * 4) { - for (i = DSTRLNT - 1; (int32) i >= 0; i--) { - nc = (dsrc->val[i] << (32 - s)) & WMASK; - dsrc->val[i] = ((dsrc->val[i] >> s) | - cin) & WMASK; - cin = nc; - } - return cin; - } -return 0; -} - -/* Nibble shift left - - Arguments: - dsrc = decimal string structure - sc = shift count in nibbles - cin = carry in -*/ - -uint32 NibbleLshift (dstr_t *dsrc, uint32 sc, uint32 cin) -{ -uint32 i, s, nc; - -if (s = sc * 4) { - for (i = 0; i < DSTRLNT; i++) { - nc = dsrc->val[i] >> (32 - s); - dsrc->val[i] = ((dsrc->val[i] << s) | - cin) & WMASK; - cin = nc; - } - return cin; - } -return 0; -} -/* Edit instruction */ - -uint32 cis_ebs (uint32 rn, uint32 disp) -{ -uint32 sa, da, c, d, dst, fill, pat; -uint32 tr; - -disp = SEXT_LIT_W (disp) & WMASK; /* sext operand */ -fill = S_GETMCNT (R[rn]); /* fill char */ -while (S_GETMCNT (R[rn|1])) { /* while pattern */ - sa = (disp + R[rn]) & bvamqrx; /* dec str addr */ - da = R[rn|1] & bvamqrx; /* pattern addr */ - if ((tr = ReadB (da, &pat, VR)) != 0) /* get pattern byte */ - return tr; - switch (pat) { /* case on pattern */ - - case ED_DS: /* digit select */ - if ((tr = ed_getsrc (sa, &c, &d)) != 0) /* get src digit */ - return tr; - if (CC & CC4) /* signif? unpack */ - dst = ZONE | d; - else if (d) { /* non-zero? */ - R[1] = da; /* save addr */ - dst = ZONE | d; /* unpack */ - CC |= CC4; /* set signif */ - } - else dst = fill; /* otherwise fill */ - if ((tr = WriteB (da, dst, VW)) != 0) /* overwrite dst */ - return tr; - ed_advsrc (rn, c); /* next src digit */ - break; - - case ED_SS: /* signif start */ - if ((tr = ed_getsrc (sa, &c, &d)) != 0) /* get src digit */ - return tr; - if (CC & CC4) /* signif? unpack */ - dst = ZONE | d; - else if (d) { /* non-zero? */ - R[1] = da; /* save addr */ - dst = ZONE | d; /* unpack */ - } - else { /* otherwise */ - R[1] = da + 1; /* save next */ - dst = fill; /* fill */ - } - CC |= CC4; /* set signif */ - if ((tr = WriteB (da, dst, VW)) != 0) /* overwrite dst */ - return tr; - ed_advsrc (rn, c); /* next src digit */ - break; - - case ED_SI: /* signif immediate */ - if ((tr = ed_getsrc (sa, &c, &d)) != 0) /* get src digit */ - return tr; - R[1] = da; /* save addr */ - dst = ZONE | d; /* unpack */ - CC |= CC4; /* set signif */ - if ((tr = WriteB (da, dst, VW)) != 0) /* overwrite dst */ - return tr; - ed_advsrc (rn, c); /* next src digit */ - break; - - case ED_FS: /* field separator */ - CC &= ~(CC1|CC3|CC4); /* clr all exc CC2 */ - if ((tr = WriteB (da, fill, VW)) != 0) /* overwrite dst */ - return tr; - break; - - default: /* all others */ - if ((CC & CC4) == 0) { /* signif off? */ - dst = (CC & CC1)? BLANK: fill; /* blank or fill */ - if ((tr = WriteB (da, dst, VW)) != 0) /* overwrite dst */ - return tr; - } - break; - } /* end switch dst */ - R[rn|1] = (R[rn|1] + S_ADDRINC) & WMASK; /* next pattern */ - } /* end while */ -return 0; -} - -/* Routine to get and validate the next source digit */ - -uint32 ed_getsrc (uint32 sa, uint32 *c, uint32 *d) -{ -uint32 tr; - -if ((tr = ReadB (sa, c, VR)) != 0) /* read source byte */ - return tr; -*d = ((CC & CC2)? *c: *c >> 4) & 0xF; /* isolate digit */ -if (*d > 0x9) /* invalid? */ - return TR_DEC; -if (*d) /* non-zero? */ - CC |= CC3; -return 0; -} - -/* Routine to advance source string */ - -void ed_advsrc (uint32 rn, uint32 c) -{ -c = c & 0xF; /* get low digit */ -if (((CC & CC2) == 0) && (c > 0x9)) { /* sel left, with sign? */ - if ((c == 0xB) || (c == 0xD)) /* minus? */ - CC = CC | (CC1|CC4); /* CC1, CC4 */ - else CC = (CC | CC1) & ~CC4; /* no, CC1, ~CC4 */ - R[rn] = R[rn] + 1; /* skip two digits */ - } -else { /* adv 1 digit */ - if (CC & CC2) - R[rn] = R[rn] + 1; - CC = CC ^ CC2; - } -return; -} diff --git a/sigma/sigma_coc.c b/sigma/sigma_coc.c deleted file mode 100644 index d7af5c9b..00000000 --- a/sigma/sigma_coc.c +++ /dev/null @@ -1,620 +0,0 @@ -/* sigma_coc.c: Sigma character-oriented communications subsystem simulator - - Copyright (c) 2007-2008, Robert M Supnik - - 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 substanXIAl 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - coc 7611 communications multiplexor - -*/ - -#include "sigma_io_defs.h" -#include "sim_sock.h" -#include "sim_tmxr.h" -#include - -/* Constants */ - -#define MUX_LINES 64 /* max lines */ -#define MUX_LINES_DFLT 8 /* default lines */ -#define MUX_INIT_POLL 8000 -#define MUXL_WAIT 500 -#define MUX_NUMLIN mux_desc.lines /* curr # lines */ - -#define MUXC 0 /* channel thread */ -#define MUXI 1 /* input thread */ - -/* Line status */ - -#define MUXL_XIA 0x01 /* xmt intr armed */ -#define MUXL_XIR 0x02 /* xmt intr req */ -#define MUXL_REP 0x04 /* rcv enable pend */ -#define MUXL_RBP 0x10 /* rcv break pend */ - -/* Channel state */ - -#define MUXC_IDLE 0 /* idle */ -#define MUXC_INIT 1 /* init */ -#define MUXC_RCV 2 /* receive */ -#define MUXC_END 3 /* end */ - -/* DIO address */ - -#define MUXDIO_V_FNC 0 /* function */ -#define MUXDIO_M_FNC 0xF -#define MUXDIO_V_COC 4 /* ctlr num */ -#define MUXDIO_M_COC 0xF -#define MUXDIO_GETFNC(x) (((x) >> MUXDIO_V_FNC) & MUXDIO_M_FNC) -#define MUXDIO_GETCOC(x) (((x) >> MUXDIO_V_COC) & MUXDIO_M_COC) - -#define MUXDAT_V_LIN 0 /* line num */ -#define MUXDAT_M_LIN (MUX_LINES - 1) -#define MUXDAT_V_CHR 8 /* output char */ -#define MUXDAT_M_CHR 0xFF -#define MUXDAT_GETLIN(x) (((x) >> MUXDAT_V_LIN) & MUXDAT_M_LIN) -#define MUXDAT_GETCHR(x) (((x) >> MUXDAT_V_CHR) & MUXDAT_M_CHR) - -uint8 mux_rbuf[MUX_LINES]; /* rcv buf */ -uint8 mux_xbuf[MUX_LINES]; /* xmt buf */ -uint8 mux_sta[MUX_LINES]; /* status */ -uint32 mux_tps = RTC_HZ_50; /* polls/second */ -uint32 mux_scan = 0; /* scanner */ -uint32 mux_slck = 0; /* scanner locked */ -uint32 muxc_cmd = MUXC_IDLE; /* channel state */ -uint32 mux_rint = INTV (INTG_E2, 0); -uint32 mux_xint = INTV (INTG_E2, 1); - -TMLN mux_ldsc[MUX_LINES] = { 0 }; /* line descrs */ -TMXR mux_desc = { MUX_LINES_DFLT, 0, 0, mux_ldsc }; /* mux descrr */ - -extern uint32 chan_ctl_time; -extern uint32 CC; -extern uint32 *R; - -uint32 mux_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 mux_dio (uint32 op, uint32 rn, uint32 ad); -uint32 mux_tio_status (void); -t_stat mux_chan_err (uint32 st); -t_stat muxc_svc (UNIT *uptr); -t_stat muxo_svc (UNIT *uptr); -t_stat muxi_rtc_svc (UNIT *uptr); -t_stat mux_reset (DEVICE *dptr); -t_stat mux_attach (UNIT *uptr, char *cptr); -t_stat mux_detach (UNIT *uptr); -t_stat mux_vlines (UNIT *uptr, int32 val, char *cptr, void *desc); -void mux_reset_ln (int32 ln); -void mux_scan_next (t_bool clr); -t_stat muxi_put_char (uint32 c, uint32 ln); - -/* MUX data structures - - mux_dev MUX device descriptor - mux_unit MUX unit descriptor - mux_reg MUX register list - mux_mod MUX modifiers list -*/ - -dib_t mux_dib = { DVA_MUX, &mux_disp, DIO_MUX, &mux_dio }; - -UNIT mux_unit[] = { - { UDATA (&muxc_svc, UNIT_ATTABLE, 0) }, - { UDATA (&muxi_rtc_svc, UNIT_DIS, 0) } - }; - -REG mux_reg[] = { - { BRDATA (STA, mux_sta, 16, 8, MUX_LINES) }, - { BRDATA (RBUF, mux_rbuf, 16, 8, MUX_LINES) }, - { BRDATA (XBUF, mux_xbuf, 16, 8, MUX_LINES) }, - { DRDATA (SCAN, mux_scan, 6) }, - { FLDATA (SLCK, mux_slck, 0) }, - { DRDATA (CMD, muxc_cmd, 2) }, - { DRDATA (TPS, mux_tps, 8), REG_HRO }, - { NULL } - }; - -MTAB mux_mod[] = { - { MTAB_XTD | MTAB_VDV, 1, NULL, "DISCONNECT", - &tmxr_dscln, NULL, &mux_desc }, - { UNIT_ATT, UNIT_ATT, "summary", NULL, - NULL, &tmxr_show_summ, (void *) &mux_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", NULL, - NULL, &tmxr_show_cstat, (void *) &mux_desc }, - { MTAB_XTD | MTAB_VDV | MTAB_NMO, 0, "STATISTICS", NULL, - NULL, &tmxr_show_cstat, (void *) &mux_desc }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "LINES", "LINES", - &mux_vlines, &tmxr_show_lines, (void *) &mux_desc }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, RTC_COC, "POLL", "POLL", - &rtc_set_tps, &rtc_show_tps, (void *) &mux_tps }, - { 0 } - }; - -DEVICE mux_dev = { - "MUX", mux_unit, mux_reg, mux_mod, - 2, 10, 31, 1, 16, 8, - &tmxr_ex, &tmxr_dep, &mux_reset, - NULL, &mux_attach, &mux_detach, - &mux_dib, DEV_NET | DEV_DISABLE - }; - -/* MUXL data structures - - muxl_dev MUXL device descriptor - muxl_unit MUXL unit descriptor - muxl_reg MUXL register list - muxl_mod MUXL modifiers list -*/ - -UNIT muxl_unit[] = { - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT }, - { UDATA (&muxo_svc, TT_MODE_UC|UNIT_DIS, 0), MUXL_WAIT } - }; - -MTAB muxl_mod[] = { - { TT_MODE, TT_MODE_UC, "UC", "UC", NULL }, - { TT_MODE, TT_MODE_7B, "7b", "7B", NULL }, - { TT_MODE, TT_MODE_8B, "8b", "8B", NULL }, - { TT_MODE, TT_MODE_7P, "7p", "7P", NULL }, - { MTAB_XTD|MTAB_VUN, 0, NULL, "DISCONNECT", - &tmxr_dscln, NULL, &mux_desc }, - { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, "LOG", "LOG", - &tmxr_set_log, &tmxr_show_log, &mux_desc }, - { MTAB_XTD|MTAB_VUN|MTAB_NC, 0, NULL, "NOLOG", - &tmxr_set_nolog, NULL, &mux_desc }, - { 0 } - }; - -REG muxl_reg[] = { - { URDATA (TIME, muxl_unit[0].wait, 10, 24, 0, - MUX_LINES, REG_NZ + PV_LEFT) }, - { NULL } - }; - -DEVICE muxl_dev = { - "MUXL", muxl_unit, muxl_reg, muxl_mod, - MUX_LINES, 10, 31, 1, 8, 8, - NULL, NULL, &mux_reset, - NULL, NULL, NULL, - NULL, 0 - }; - -/* MUX: IO dispatch routine */ - -uint32 mux_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = mux_tio_status (); /* get status */ - if ((*dvst & DVS_CST) == 0) { /* ctrl idle? */ - muxc_cmd = MUXC_INIT; /* start dev thread */ - sim_activate (&mux_unit[MUXC], chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = mux_tio_status (); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = 0; /* no status */ - break; - - case OP_HIO: /* halt I/O */ - *dvst = mux_tio_status (); /* get status */ - muxc_cmd = MUXC_IDLE; /* stop dev thread */ - sim_cancel (&mux_unit[MUXC]); - io_sclr_req (mux_rint, 0); /* clr rcv int */ - io_sclr_req (mux_xint, 0); - break; - - case OP_AIO: /* acknowledge int */ - *dvst = 0; /* no status */ - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* MUX: DIO dispatch routine */ - -uint32 mux_dio (uint32 op, uint32 rn, uint32 ad) -{ -int32 ln; -uint32 fnc = MUXDIO_GETFNC (ad); -uint32 coc = MUXDIO_GETCOC (ad); - -if (op == OP_RD) { /* read direct */ - if (coc != 0) /* nx COC? */ - return 0; - R[rn] = mux_scan | 0x40; /* return line num */ - mux_sta[mux_scan] &= ~MUXL_XIR; /* clear int req */ - return 0; - } -ln = MUXDAT_GETLIN (R[rn]); /* get line num */ -if (fnc & 0x4) { /* transmit */ - if ((coc != 0) || /* nx COC or */ - (ln >= MUX_NUMLIN)) { /* nx line? */ - CC |= CC4; - return 0; - } - if ((fnc & 0x7) == 0x5) { /* send char? */ - if (fnc & 0x8) /* space? */ - mux_xbuf[ln] = 0; - else mux_xbuf[ln] = MUXDAT_GETCHR (R[rn]); /* no, get char */ - sim_activate (&muxl_unit[ln], muxl_unit[ln].wait); - mux_sta[ln] = (mux_sta[ln] | MUXL_XIA) & ~MUXL_XIR; - mux_scan_next (1); /* unlock scanner */ - } - else if (fnc == 0x06) { /* stop transmit */ - mux_sta[ln] &= ~MUXL_XIA|MUXL_XIR; /* disable int */ - mux_scan_next (1); /* unlock scanner */ - } - else if (fnc == 0x07) { /* disconnect */ - tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */ - mux_reset_ln (ln); /* reset state */ - } - CC = (sim_is_active (&muxl_unit[ln])? 0: CC4) | - (mux_ldsc[ln].conn? CC3: 0); - } -else { /* receive */ - if ((coc != 0) || /* nx COC or */ - (ln >= MUX_NUMLIN)) /* nx line */ - return 0; - if (fnc == 0x01) { /* set rcv enable */ - if (mux_ldsc[ln].conn) /* connected? */ - mux_ldsc[ln].rcve = 1; /* just enable */ - else mux_sta[ln] |= MUXL_REP; /* enable pending */ - } - else if (fnc == 0x02) { /* clr rcv enable */ - mux_ldsc[ln].rcve = 0; - mux_sta[ln] &= ~MUXL_REP; - } - else if (fnc == 0x03) { /* disconnect */ - tmxr_reset_ln (&mux_ldsc[ln]); /* reset line */ - mux_reset_ln (ln); /* reset state */ - } - if (mux_sta[ln] & MUXL_RBP) /* break pending? */ - CC = CC3|CC4; - else CC = mux_ldsc[ln].rcve? CC4: CC3; - } -return 0; -} - -/* Unit service - channel overhead */ - -t_stat muxc_svc (UNIT *uptr) -{ -uint32 st; -uint32 cmd; - -if (muxc_cmd == MUXC_INIT) { /* init state? */ - st = chan_get_cmd (mux_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - mux_chan_err (st); /* go idle */ - else muxc_cmd = MUXC_RCV; /* no, receive */ - } -else if (muxc_cmd == MUXC_END) { /* end state? */ - st = chan_end (mux_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - mux_chan_err (st); /* go idle */ - else if (st == CHS_CCH) { /* command chain? */ - muxc_cmd = MUXC_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); /* schedule soon */ - } - else muxc_cmd = MUXC_IDLE; /* else idle */ - } -return SCPE_OK; -} - -/* Unit service - polled input - called from rtc scheduler - - Poll for new connections - Poll all connected lines for input -*/ - -t_stat muxi_rtc_svc (UNIT *uptr) -{ -t_stat r; -int32 newln, ln, c; - -if ((mux_unit[MUXC].flags & UNIT_ATT) == 0) /* attached? */ - return SCPE_OK; -newln = tmxr_poll_conn (&mux_desc); /* look for connect */ -if ((newln >= 0) && (mux_sta[newln] & MUXL_REP)) { /* rcv enb pending? */ - mux_ldsc[newln].rcve = 1; /* enable rcv */ - mux_sta[newln] &= ~MUXL_REP; /* clr pending */ - } -tmxr_poll_rx (&mux_desc); /* poll for input */ -for (ln = 0; ln < MUX_NUMLIN; ln++) { /* loop thru lines */ - if (mux_ldsc[ln].conn) { /* connected? */ - if (c = tmxr_getc_ln (&mux_ldsc[ln])) { /* get char */ - if (c & SCPE_BREAK) /* break? */ - mux_sta[ln] |= MUXL_RBP; /* set rcv brk */ - else { /* normal char */ - mux_sta[ln] &= ~MUXL_RBP; /* clr rcv brk */ - c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags)); - mux_rbuf[ln] = c; /* save char */ - if ((muxc_cmd == MUXC_RCV) && /* chan active? */ - (r = muxi_put_char (c, ln))) /* char to chan */ - return r; - } /* end else char */ - } /* end if char */ - } /* end if conn */ - else mux_sta[ln] &= ~MUXL_RBP; /* disconnected */ - } /* end for */ -return SCPE_OK; -} - -/* Put character and line number in memory via channel */ - -t_stat muxi_put_char (uint32 c, uint32 ln) -{ -uint32 st; - -st = chan_WrMemB (mux_dib.dva, c); /* write char */ -if (CHS_IFERR (st)) /* channel error? */ - return mux_chan_err (st); -st = chan_WrMemB (mux_dib.dva, ln); /* write line */ -if (CHS_IFERR (st)) /* channel error? */ - return mux_chan_err (st); -if (st == CHS_ZBC) { /* bc == 0? */ - muxc_cmd = MUXC_END; /* end state */ - sim_activate (&mux_unit[MUXC], chan_ctl_time); /* quick schedule */ - } -io_sclr_req (mux_rint, 1); /* req ext intr */ -return SCPE_OK; -} - -/* Channel error */ - -t_stat mux_chan_err (uint32 st) -{ -chan_uen (mux_dib.dva); /* uend */ -muxc_cmd = MUXC_IDLE; /* go idle */ -if (st < CHS_ERR) - return st; -return 0; -} - -/* Unit service - transmit side */ - -t_stat muxo_svc (UNIT *uptr) -{ -int32 c; -uint32 ln = uptr - muxl_unit; /* line # */ - -if (mux_ldsc[ln].conn) { /* connected? */ - if (mux_ldsc[ln].xmte) { /* xmt enabled? */ - c = sim_tt_outcvt (mux_xbuf[ln], TT_GET_MODE (muxl_unit[ln].flags)); - if (c >= 0) - tmxr_putc_ln (&mux_ldsc[ln], c); /* output char */ - tmxr_poll_tx (&mux_desc); /* poll xmt */ - if (mux_sta[ln] & MUXL_XIA) { /* armed? */ - mux_sta[ln] |= MUXL_XIR; /* req intr */ - mux_scan_next (0); /* kick scanner */ - } - } - else { /* buf full */ - tmxr_poll_tx (&mux_desc); /* poll xmt */ - sim_activate (uptr, muxl_unit[ln].wait); /* wait */ - return SCPE_OK; - } - } -return SCPE_OK; -} - -/* MUX status routine */ - -uint32 mux_tio_status (void) -{ -if (muxc_cmd == MUXC_IDLE) /* idle? */ - return DVS_AUTO; -else return (DVS_AUTO|DVS_CBUSY|DVS_DBUSY|(CC2 << DVT_V_CC)); -} - -/* Kick scanner */ - -void mux_scan_next (t_bool clr) -{ -int32 i; - -if (clr) /* unlock? */ - mux_slck = 0; -else if (mux_slck) /* locked? */ - return; -for (i = 0; i < MUX_NUMLIN; i++) { /* scan lines */ - mux_scan = mux_scan + 1; /* next line */ - if (mux_scan >= (uint32) MUX_NUMLIN) - mux_scan = 0; - if (mux_sta[mux_scan] & MUXL_XIR) { /* flag set? */ - mux_slck = 1; /* lock scanner */ - io_sclr_req (mux_xint, 1); /* req ext int */ - return; - } - } -return; -} - -/* Reset routine */ - -t_stat mux_reset (DEVICE *dptr) -{ -int32 i; - -if (mux_dev.flags & DEV_DIS) /* master disabled? */ - muxl_dev.flags = muxl_dev.flags | DEV_DIS; /* disable lines */ -else muxl_dev.flags = muxl_dev.flags & ~DEV_DIS; -if (mux_unit[MUXC].flags & UNIT_ATT) /* master att? */ - rtc_register (RTC_COC, mux_tps, &mux_unit[MUXI]); /* register timer */ -else rtc_register (RTC_COC, RTC_HZ_OFF, NULL); /* else dereg */ -for (i = 0; i < MUX_LINES; i++) /* reset lines */ - mux_reset_ln (i); -return SCPE_OK; -} - -/* Attach master unit */ - -t_stat mux_attach (UNIT *uptr, char *cptr) -{ -t_stat r; - -r = tmxr_attach (&mux_desc, uptr, cptr); /* attach */ -if (r != SCPE_OK) /* error */ - return r; -rtc_register (RTC_COC, mux_tps, &mux_unit[MUXC]); /* register timer */ -return SCPE_OK; -} - -/* Detach master unit */ - -t_stat mux_detach (UNIT *uptr) -{ -int32 i; -t_stat r; - -r = tmxr_detach (&mux_desc, uptr); /* detach */ -for (i = 0; i < MUX_LINES; i++) /* disable rcv */ - mux_reset_ln (i); -rtc_register (RTC_COC, RTC_HZ_OFF, NULL); /* dereg */ -return r; -} - - -/* Change number of lines */ - -t_stat mux_vlines (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 newln, i, t; -t_stat r; - -if (cptr == NULL) - return SCPE_ARG; -newln = get_uint (cptr, 10, MUX_LINES, &r); -if ((r != SCPE_OK) || (newln == MUX_NUMLIN)) - return r; -if (newln == 0) return SCPE_ARG; -if (newln < MUX_NUMLIN) { - for (i = newln, t = 0; i < MUX_NUMLIN; i++) t = t | mux_ldsc[i].conn; - if (t && !get_yn ("This will disconnect users; proceed [N]?", FALSE)) - return SCPE_OK; - for (i = newln; i < MUX_NUMLIN; i++) { - if (mux_ldsc[i].conn) { - tmxr_linemsg (&mux_ldsc[i], "\r\nOperator disconnected line\r\n"); - tmxr_reset_ln (&mux_ldsc[i]); /* reset line */ - } - muxl_unit[i].flags = muxl_unit[i].flags | UNIT_DIS; - mux_reset_ln (i); - } - } -else { - for (i = MUX_NUMLIN; i < newln; i++) { - muxl_unit[i].flags = muxl_unit[i].flags & ~UNIT_DIS; - mux_reset_ln (i); - } - } -MUX_NUMLIN = newln; -return SCPE_OK; -} - -/* Reset an individual line */ - -void mux_reset_ln (int32 ln) -{ -sim_cancel (&muxl_unit[ln]); -mux_sta[ln] = 0; -mux_rbuf[ln] = 0; -mux_xbuf[ln] = 0; -mux_ldsc[ln].rcve = 0; -return; -} diff --git a/sigma/sigma_cpu.c b/sigma/sigma_cpu.c deleted file mode 100644 index 22e1a44a..00000000 --- a/sigma/sigma_cpu.c +++ /dev/null @@ -1,2848 +0,0 @@ -/* sigma_cpu.c: XDS Sigma CPU simulator - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - cpu central processor - - The system state for the Sigma CPU is as follows: - - RF[0:15][0:31]<0:31> register blocks - PSW1<0:31> processor status word 1 - CC<0:3> condition codes - PC<0:17> program counter (called IA in Sigma documentation) - PSW2<0:31> processor status word 2 - PSW2_WLK<0:3> write key (2b on S5-9) - PSW4<0:31> processor status word 4 (5X0 only) - MAP[0:511]<0:10> memory map (8b on S5-8) - WLK[0:2047]<0:3> write locks (256 2b entries on S5-9) - SSW<0:3> sense switches - PDF processor detected fault flag (S8-9, 5X0 only) - - Notes on features not documented in the Reference Manuals: - - 1. Memory mapping was available for the Sigma 5 (see map diagnostic). - 2. The Sigma 6/7 were field retrofitted with the LAS/LMS instructions - (see auto diagnostic). - 3. The Sigma 8/9 returned different results for WD .45 (see Telefile - System exerciser). - 4. Expanded memory beyond 128KB was retrofitted to the Sigma 5/6/7, - creating the so-called "Big 5/6/7." As a minimum, these systems - also included the "mode altered" feature and the 11b relocation map. - - The Sigma CPU has two instruction formats, memory reference and immediate. - The memory reference format is: - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - |I| | | | | - |N| opcode | R | X | address | memory - |D| | | | | reference - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - where - - IND = indirect flag - opcode = operation code - R = source/destination register - X = index register (0 if none) - address = operand address - - The immediate format is: - - 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 - 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - | | | | | - |0| opcode | R | immediate | immediate - | | | | | - +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - - This routine is the instruction decode routine for the Sigma CPU. - It is called from the simulator control program to execute - instructions in simulated memory, starting at the simulated PC. - It runs until 'reason' is set non-zero. - - General notes: - - 1. Reasons to stop. The simulator can be stopped by: - - HALT instruction - breakpoint encountered - invalid instruction and stop_op flag set - I/O error in I/O simulator - EXU loop exceeding limit - illegal interrupt or trap instruction - illegal register pointer - illegal vector - - 2. Interrupts. The interrupt structure consists of the following: - Each interrupt is part of a group that determines its priority. - The interrupt group is either controlled by a PSW inhibit or is - unconditional. Interrupts can be armed or disarmed (which controls - whether they are recognized at all) and enabled or disabled (which - controls whether they occur). See the sigma_io.c module for details. - - 3. Channels. The Sigma system has a channel-based I/O structure. Each - channel is represented by a set of registers. Channels test the - I/O transfer requests from devices. - - 4. Non-existent memory. On the Sigma, accesses to non-existent memory - trap. - - 5. Adding I/O devices. These modules must be modified: - - sigma_defs.h add definitions - sigma_io.c add dispatches - sigma_sys.c add pointer to data structures to sim_devices -*/ - -#include "sigma_io_defs.h" - -#define CPUF_V_MODEL (UNIT_V_UF + 6) /* CPU model */ -#define CPUF_M_MODEL 0x7 -#define CPUF_MODEL (CPUF_M_MODEL << CPUF_V_MODEL) -#define CPUF_S5 (CPU_V_S5 << CPUF_V_MODEL) -#define CPUF_S6 (CPU_V_S6 << CPUF_V_MODEL) -#define CPUF_S7 (CPU_V_S7 << CPUF_V_MODEL) -#define CPUF_S8 (CPU_V_S8 << CPUF_V_MODEL) -#define CPUF_S7B (CPU_V_S7B << CPUF_V_MODEL) -#define CPUF_S9 (CPU_V_S9 << CPUF_V_MODEL) -#define CPUF_550 (CPU_V_550 << CPUF_V_MODEL) -#define CPUF_560 (CPU_V_560 << CPUF_V_MODEL) -#define CPUF_GETMOD(x) (((x) >> CPUF_V_MODEL) & CPUF_M_MODEL) - -#define PCQ_SIZE 64 /* must be 2**n */ -#define PCQ_MASK (PCQ_SIZE - 1) -#define PCQ_ENTRY pcq[pcq_p = (pcq_p - 1) & PCQ_MASK] = real_pc; - -#define HIST_MIN 64 -#define HIST_MAX (1u << 20) -#define H_INST 0x00800000 -#define H_CHAN 0x00400000 -#define H_ITRP 0x00200000 -#define H_ABRT 0x00100000 - -typedef struct { - uint32 typ_cc_pc; - uint32 ir; - uint32 rn; - uint32 rn1; - uint32 x; /* unused */ - uint32 ea; - uint32 op; - uint32 op1; - } InstHistory; - -uint32 cpu_model = CPU_V_S7; /* CPU model */ -uint32 *M; /* memory */ -uint32 rf[RF_NBLK * RF_NUM] = { 0 }; /* register files */ -uint32 *R = rf; /* cur reg file */ -uint32 PSW1 = PSW1_DFLT; /* PSD */ -uint32 PSW2 = PSW2_DFLT; -uint32 PSW4 = 0; /* 5X0 only */ -uint32 CC; -uint32 PC; -uint32 PSW2_WLK = 0; /* write lock key */ -uint32 PSW_QRX9; /* Sigma 9 real extended */ -uint32 bvamqrx = BVAMASK; /* BVA mask, 17b/20b */ -uint32 SSW = 0; /* sense switches */ -uint32 cpu_pdf = 0; /* proc detected fault */ -uint32 cons_alarm = 0; /* console alarm */ -uint32 cons_alarm_enb = 0; /* alarm enable */ -uint32 cons_pcf = 0; -uint32 rf_bmax = 4; /* num reg blocks */ -uint32 exu_lim = 32; /* nested EXU limit */ -uint32 stop_op = 0; /* stop on ill op */ -uint32 cpu_astop = 0; /* address stop */ -uint32 pcq[PCQ_SIZE] = { 0 }; /* PC queue */ -int32 pcq_p = 0; /* PC queue ptr */ -REG *pcq_r = NULL; /* PC queue reg ptr */ -int32 hst_p = 0; /* history pointer */ -int32 hst_lnt = 0; /* history length */ -InstHistory *hst = NULL; /* inst history */ - -extern int32 sim_int_char; -extern int32 sim_interval; -extern int32 sim_switches; -extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ -extern uint32 int_hiact; /* highest act int */ -extern uint32 int_hireq; /* highest int req */ - -t_stat cpu_svc (UNIT *uptr); -t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); -t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); -t_stat cpu_reset (DEVICE *dptr); -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_set_type (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_clr_opt (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_set_rblks (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_show_rblks (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat cpu_set_alarm (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_show_alarm (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat cpu_show_addr (FILE *st, UNIT *uptr, int32 val, void *desc); -void set_rf_display (uint32 *rfbase); -void inst_hist (uint32 ir, uint32 pc, uint32 typ); -uint32 cpu_one_inst (uint32 real_pc, uint32 IR); -uint32 ImmOp (uint32 ir, uint32 *imm); -uint32 EaP20 (uint32 IR, uint32 *bva, uint32 lnt); -uint32 EaSh (uint32 ir, uint32 *stype, uint32 *sc); -uint32 Add32 (uint32 s1, uint32 s2, uint32 cin); -uint32 SMul64 (uint32 a, uint32 b, uint32 *lo); -t_bool SDiv64 (uint32 dvdh, uint32 dvdl, uint32 dvr, uint32 *res, uint32 *rem); -uint32 Cmp32 (uint32 a, uint32 b); -uint32 Shift (uint32 rn, uint32 stype, uint32 sc); -uint32 TestSP1 (uint32 sp1, int32 mod); -uint32 ModWrSP (uint32 bva, uint32 sp, uint32 sp1, int32 mod); -uint32 cpu_int_mtx (uint32 vec, uint32 *cc); -uint32 cpu_trap_or_int (uint32 vec); -uint32 cpu_xpsd (uint32 ir, uint32 bva, uint32 ra); -uint32 cpu_pss (uint32 ir, uint32 bva, uint32 acc); -uint32 cpu_pls (uint32 IR); -void cpu_assemble_PSD (void); -uint32 cpu_new_PSD (uint32 lrp, uint32 p1, uint32 p2); -uint32 cpu_new_RP (uint32 rp); -uint32 cpu_new_PC (uint32 bva); -uint32 cpu_add_PC (uint32 pc, uint32 val); -t_stat cpu_bad_rblk (UNIT *uptr); -void cpu_fprint_one_inst (FILE *st, uint32 tcp, uint32 ir, uint32 rn, - uint32 rn1, uint32 ea, uint32 op, uint32 op1); - -extern uint32 fp (uint32 op, uint32 rn, uint32 bva); -extern uint32 cis_dec (uint32 op, uint32 rn, uint32 bva); -extern uint32 cis_ebs (uint32 rn, uint32 disp); -extern void ShiftF (uint32 rn, uint32 stype, uint32 sc); -extern uint32 map_mmc (uint32 rn, uint32 map); -extern uint32 map_lra (uint32 rn, uint32 inst); -extern uint32 map_las (uint32 rn, uint32 bva); -extern uint32 map_lms (uint32 rn, uint32 bva); -extern t_stat io_init (void); -extern uint32 io_eval_int (void); -extern uint32 io_actv_int (void); -extern t_bool io_poss_int (void); -extern uint32 io_ackn_int (uint32 hireq); -extern uint32 io_rels_int (uint32 hiact, t_bool arm); -extern uint32 io_rwd (uint32 op, uint32 rn, uint32 bva); -extern uint32 io_sio (uint32 rn, uint32 bva); -extern uint32 io_tio (uint32 rn, uint32 bva); -extern uint32 io_tdv (uint32 rn, uint32 bva); -extern uint32 io_hio (uint32 rn, uint32 bva); -extern uint32 io_aio (uint32 rn, uint32 bva); -extern uint32 int_reset (DEVICE *dev); -extern void io_set_eimax (uint32 lnt); -extern void io_sclr_req (uint32 inum, uint32 val); -extern void io_sclr_arm (uint32 inum, uint32 val); -extern t_stat io_set_nchan (UNIT *uptr, int32 val, char *cptr, void *desc); -extern t_stat io_show_nchan (FILE *st, UNIT *uptr, int32 val, void *desc); - -/* CPU data structures - - cpu_dev CPU device descriptor - cpu_unit CPU unit - cpu_reg CPU register list - cpu_mod CPU modifier list -*/ - -UNIT cpu_unit = { - UDATA (&cpu_svc, UNIT_FIX+CPUF_S7+CPUF_ALLOPT+UNIT_BINK, MAXMEMSIZE), - }; - -UNIT cpu_rblk_unit = { - UDATA (&cpu_bad_rblk, UNIT_DIS, 0) - }; - -REG cpu_reg[] = { - { GRDATA (PC, PSW1, 16, VASIZE, PSW1_V_PC) }, - { HRDATA (R0, rf[0], 32) }, /* addr in memory */ - { HRDATA (R1, rf[1], 32) }, /* modified at exit */ - { HRDATA (R2, rf[2], 32) }, /* to SCP */ - { HRDATA (R3, rf[3], 32) }, - { HRDATA (R4, rf[4], 32) }, - { HRDATA (R5, rf[5], 32) }, - { HRDATA (R6, rf[6], 32) }, - { HRDATA (R7, rf[7], 32) }, - { HRDATA (R8, rf[8], 32) }, - { HRDATA (R9, rf[9], 32) }, - { HRDATA (R10, rf[10], 32) }, - { HRDATA (R11, rf[11], 32) }, - { HRDATA (R12, rf[12], 32) }, - { HRDATA (R13, rf[13], 32) }, - { HRDATA (R14, rf[14], 32) }, - { HRDATA (R15, rf[15], 32) }, - { HRDATA (PSW1, PSW1, 32) }, - { HRDATA (PSW2, PSW2, 32) }, - { HRDATA (PSW4, PSW4, 32) }, - { GRDATA (CC, PSW1, 16, 4, PSW1_V_CC) }, - { GRDATA (RP, PSW2, 16, 4, PSW2_V_RP) }, - { FLDATA (SSW1, SSW, 3) }, - { FLDATA (SSW2, SSW, 2) }, - { FLDATA (SSW3, SSW, 1) }, - { FLDATA (SSW4, SSW, 0) }, - { FLDATA (PDF, cpu_pdf, 0) }, - { FLDATA (ALARM, cons_alarm, 0) }, - { FLDATA (ALENB, cons_alarm_enb, 0), REG_HRO }, - { FLDATA (PCF, cons_pcf, 0) }, - { DRDATA (EXULIM, exu_lim, 8), PV_LEFT + REG_NZ }, - { FLDATA (STOP_ILL, stop_op, 0) }, - { BRDATA (REG, rf, 16, 32, RF_NUM * RF_NBLK) }, - { DRDATA (RBLKS, rf_bmax, 5), REG_HRO }, - { BRDATA (PCQ, pcq, 16, VASIZE, PCQ_SIZE), REG_RO+REG_CIRC }, - { DRDATA (PCQP, pcq_p, 6), REG_HRO }, - { HRDATA (WRU, sim_int_char, 8) }, - { NULL } - }; - -MTAB cpu_mod[] = { - { CPUF_MODEL, CPUF_S5, "Sigma 5", "SIGMA5", &cpu_set_type }, - { CPUF_MODEL, CPUF_S6, "Sigma 6", "SIGMA6", &cpu_set_type }, - { CPUF_MODEL, CPUF_S7, "Sigma 7", "SIGMA7", &cpu_set_type }, -// { CPUF_MODEL, CPUF_S8, "Sigma 8", "SIGMA8", &cpu_set_type }, -// { CPUF_MODEL, CPUF_S9, "Sigma 9", "SIGMA9", &cpu_set_type }, -// { CPUF_MODEL, CPUF_550, "550", "550", &cpu_set_type }, -// { CPUF_MODEL, CPUF_560, "560", "560", &cpu_set_type }, - { MTAB_XTD|MTAB_VDV, 0, "register blocks", "RBLKS", - &cpu_set_rblks, &cpu_show_rblks }, - { MTAB_XTD|MTAB_VDV, 0, "channels", "CHANNELS", - &io_set_nchan, &io_show_nchan }, - { CPUF_FP, CPUF_FP, "floating point", "FP", &cpu_set_opt }, - { CPUF_FP, 0, "no floating point", NULL }, - { MTAB_XTD|MTAB_VDV, CPUF_FP, NULL, "NOFP", &cpu_clr_opt }, - { CPUF_DEC, CPUF_DEC, "decimal", "DECIMAL", &cpu_set_opt }, - { CPUF_DEC, 0, "no decimal", NULL }, - { MTAB_XTD|MTAB_VDV, CPUF_DEC, NULL, "NODECIMAL", &cpu_clr_opt }, - { CPUF_LAMS, CPUF_LAMS, "LAS/LMS", "LASLMS", &cpu_set_opt }, - { CPUF_LAMS, 0, "no LAS/LMS", NULL }, - { MTAB_XTD|MTAB_VDV, CPUF_LAMS, NULL, "NOLASLMS", &cpu_clr_opt }, - { CPUF_MAP, CPUF_MAP, "map", "MAP", &cpu_set_opt }, - { CPUF_MAP, 0, "no map", NULL }, - { MTAB_XTD|MTAB_VDV, CPUF_MAP, NULL, "NOMAP", &cpu_clr_opt }, - { CPUF_WLK, CPUF_WLK, "write lock", "WRITELOCK", &cpu_set_opt }, - { CPUF_WLK, 0, "no write lock", NULL }, - { MTAB_XTD|MTAB_VDV, CPUF_WLK, NULL, "NOWRITELOCK", &cpu_clr_opt }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 1, "ALARM", "ALON", &cpu_set_alarm, &cpu_show_alarm }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, NULL, "ALOFF", & cpu_set_alarm }, - { CPUF_MSIZE, (1u << 15), NULL, "32K", &cpu_set_size }, - { CPUF_MSIZE, (1u << 16), NULL, "64K", &cpu_set_size }, - { CPUF_MSIZE, (1u << 17), NULL, "128K", &cpu_set_size }, - { CPUF_MSIZE, (1u << 18), NULL, "256K", &cpu_set_size }, - { CPUF_MSIZE, (1u << 19), NULL, "512K", &cpu_set_size }, - { CPUF_MSIZE, (1u << 20), NULL, "1M", &cpu_set_size }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, BY, "BA", NULL, - NULL, &cpu_show_addr }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, HW, "HA", NULL, - NULL, &cpu_show_addr }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, WD, "WA", NULL, - NULL, &cpu_show_addr }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, DW, "DA", NULL, - NULL, &cpu_show_addr }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_SHP, 0, "HISTORY", "HISTORY", - &cpu_set_hist, &cpu_show_hist }, - { 0 } - }; - -DEVICE cpu_dev = { - "CPU", &cpu_unit, cpu_reg, cpu_mod, - 1, 16, 20, 1, 16, 32, - &cpu_ex, &cpu_dep, &cpu_reset, - NULL, NULL, NULL, - }; - -static uint8 anlz_tab[128] = { - 0x9, 0x9, 0x9, 0x9, 0x8, 0x8, 0x8, 0x8, /* 00 - 0F */ - 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, - 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, /* 10 - 1F */ - 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, 0xC, - 0x9, 0x9, 0x9, 0x9, 0x8, 0x8, 0x8, 0x8, /* 20 - 2F */ - 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, /* 30 - 3F */ - 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x1, 0x1, 0x1, 0x1, 0x8, 0x8, 0x8, 0x8, /* 40 - 4F */ - 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, /* 50 - 5F */ - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x1, 0x1, 0x1, 0x1, 0x8, 0x8, 0x8, 0x8, /* 60 - 6F */ - 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, /* 70 - 7F */ - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 - }; - -cpu_var_t cpu_tab[] = { - -/* psw1_mbz psw2_mbz m_map1 pamask eint chan - cc standard optional */ - { 0x080E0000, 0xC8FFFE0F, 0x0FC, PAMASK17, 14, 8, /* S5 */ - CC1|CC2, 0, CPUF_MAP|CPUF_WLK|CPUF_FP }, - { 0x080E0000, 0xC8FFFE0F, 0x0FC, PAMASK17, 14, 8, /* S6 */ - CC1|CC2, CPUF_STR|CPUF_MAP|CPUF_WLK|CPUF_DEC, CPUF_FP|CPUF_LAMS }, - { 0x080E0000, 0xC8FFFE0F, 0x0FC, PAMASK17, 14, 8, /* S7 */ - CC1|CC2, CPUF_STR|CPUF_MAP|CPUF_WLK, CPUF_FP|CPUF_DEC|CPUF_LAMS }, - { 0x084E0000, 0xC8FF00C7, 0x0FC, PAMASK17, 14, 8, /* S8 */ - CC1|CC2|CC3, CPUF_STR|CPUF_FP|CPUF_WLK|CPUF_LAMS, 0 }, - { 0x08060000, 0xC8400007, 0x0FC, PAMASK22, 14, 8, /* S9 */ - CC1|CC2|CC3, CPUF_STR|CPUF_MAP|CPUF_WLK|CPUF_DEC|CPUF_FP|CPUF_LAMS, 0 }, - { 0x002E0000, 0x080FFFC3, 0x7FE, PAMASK20, 4, 4, /* 550 */ - CC1|CC2|CC3|CC4, CPUF_MAP|CPUF_WLK|CPUF_LAMS, CPUF_FP }, - { 0x000E0000, 0x080FFFC3, 0x7FE, PAMASK20, 4, 4, /* 560 */ - CC1|CC2|CC3|CC4, CPUF_STR|CPUF_MAP|CPUF_WLK|CPUF_DEC|CPUF_FP|CPUF_LAMS, 0 } - }; - -/* Simulation loop */ - -t_stat sim_instr (void) -{ -uint32 ir, rpc, old_PC; -t_stat reason, tr, tr2; - -/* Restore register state */ - -if (io_init ()) /* init IO; conflict? */ - return STOP_INVIOC; -reason = 0; -if (cpu_new_PSD (1, PSW1, PSW2)) /* restore PSD, RP etc */ - return STOP_INVPSD; -int_hireq = io_eval_int (); - -/* Main instruction fetch/decode loop */ - -while (reason == 0) { /* loop until stop */ - - PSW2 &= ~PSW2_RA; /* clr reg altered */ - if (cpu_astop) { /* debug stop? */ - cpu_astop = 0; - return STOP_ASTOP; - } - - if (sim_interval <= 0) { /* event queue? */ - if (reason = sim_process_event ()) /* process */ - break; - int_hireq = io_eval_int (); /* re-evaluate intr */ - } - sim_interval = sim_interval - 1; /* count down */ - - if (int_hireq < NO_INT) { /* interrupt req? */ - uint32 sav_hi, vec, wd, op; - - vec = io_ackn_int (sav_hi = int_hireq); /* get vector */ - if (vec == 0) { /* illegal vector? */ - reason = STOP_ILLVEC; /* something wrong */ - break; - } - ReadPW (vec, &wd); /* read vector */ - op = I_GETOP (wd); /* get opcode */ - if ((op == OP_MTB) || (op == OP_MTH) || (op == OP_MTW)) { - uint32 res; - tr2 = cpu_int_mtx (vec, &res); /* do single cycle */ - io_sclr_req (sav_hi, 0); /* clear request */ - io_sclr_arm (sav_hi, 1); /* set armed */ - if ((res == 0) && /* count overflow */ - ((vec >= VEC_C1P) || (vec <= VEC_C4P))) /* on clock? */ - io_sclr_req (INTV (INTG_CTR, vec - VEC_C1P), 1); - int_hiact = io_actv_int (); /* re-eval active */ - int_hireq = io_eval_int (); /* re-eval intr */ - } - else tr2 = cpu_trap_or_int (vec); /* XPSD/PSS intr */ - if (tr2 & TR_FL) { /* trap? */ - if (QCPU_S89_5X0) /* S89 or 5X0? */ - tr2 = cpu_trap_or_int (tr2); /* try again */ - reason = (tr2 == TR_INVTRP)? STOP_ILLTRP: STOP_TRPT; - } - else reason = tr2; /* normal status code */ - } - else { /* normal instruction */ - if (sim_brk_summ && - sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */ - reason = STOP_IBKPT; /* stop simulation */ - break; - } - if (PSW_QRX9 && (PC & PSW1_XA)) /* S9 real ext && ext? */ - rpc = (PSW2 & PSW2_EA) | (PC & ~PSW1_XA); /* 22b phys address */ - else rpc = PC; /* standard 17b PC */ - PC = cpu_add_PC (old_PC = PC, 1); /* increment PC */ - if (((tr = ReadW (rpc << 2, &ir, VI)) != 0) || /* fetch inst, err? */ - ((tr = cpu_one_inst (rpc, ir)) != 0)) { /* exec inst, error? */ - if (tr & TR_FL) { /* trap? */ - PC = old_PC; /* roll back PC */ - tr2 = cpu_trap_or_int (tr); /* do trap */ - if (tr2 & TR_FL) { /* trap? */ - if (QCPU_S89_5X0) /* S89 or 5X0? */ - tr2 = cpu_trap_or_int (tr2); /* try again */ - reason = (tr2 == TR_INVTRP)? STOP_ILLTRP: STOP_TRPT; - } /* end if trap-in-trap */ - else reason = tr2; /* normal status */ - } /* end if trap */ - else reason = tr; /* normal status */ - if ((reason >= STOP_ROLLBACK) && /* roll back PC? */ - (reason <= STOP_MAX)) - PC = old_PC; - } /* end if abnormal status */ - } /* end else normal */ - } /* end while */ - -/* Simulation halted */ - -pcq_r->qptr = pcq_p; /* update pc q ptr */ -cpu_assemble_PSD (); /* visible PSD */ -set_rf_display (R); /* visible registers */ -return reason; -} - -/* Execute one instruction */ - -uint32 cpu_one_inst (uint32 real_pc, uint32 IR) -{ -uint32 op, rn, bva, opnd, opnd1, opnd2, t; -uint32 res, res1, tr, stype, sc, cnt; -uint32 sa, da, mask, c, c1, i, lim, aop, exu_cnt; -int32 sop, sop1; -t_bool mprot; - -exu_cnt = 0; /* init EXU count */ -EXU_LOOP: -if (hst_lnt) /* history? record */ - inst_hist (IR, real_pc, H_INST); -op = I_GETOP (IR); /* get opcode */ -rn = I_GETRN (IR); /* get reg num */ -switch (op) { - -/* Loads and stores */ - - case OP_LI: /* load immediate */ - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sext to 32b */ - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_LB: /* load byte */ - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadB (bva, &opnd, VR)) != 0) /* read byte */ - return tr; - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_LH: /* load halfword */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - opnd = SEXT_H_W (opnd) & WMASK; /* sext to 32b */ - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_LCH: /* load comp hw */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - opnd = SEXT_H_W (opnd); /* sext to 32b */ - opnd = NEG_W (opnd); /* negate */ - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_LAH: /* load abs hw */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - if (opnd & HSIGN) /* negative? */ - opnd = NEG_W (opnd) & HMASK; /* negate */ - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_LW: /* load word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_LCW: /* load comp word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - opnd = NEG_W (opnd); /* negate */ - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - if (opnd == WSIGN) { /* overflow? */ - CC |= CC2; /* set CC2 */ - if (PSW1 & PSW1_AM) /* trap if enabled */ - return TR_FIX; - } - else CC &= ~CC2; /* no, clear CC2 */ - break; - - case OP_LAW: /* load abs word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - if (opnd & WSIGN) /* negative? */ - opnd = NEG_W (opnd); /* take abs value */ - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - if (opnd == WSIGN) { /* overflow? */ - CC |= CC2; /* set CC2 */ - if (PSW1 & PSW1_AM) /* trap if enabled */ - return TR_FIX; - } - else CC &= ~CC2; /* no, clear CC2 */ - break; - - case OP_LS: /* load selective */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - res = (R[rn] & ~R[rn|1]) | (opnd & R[rn|1]); /* load under mask */ - CC34_W (res); /* set cc's */ - R[rn] = res; /* store result */ - break; - - case OP_LAS: /* load and set */ - if ((cpu_unit.flags & CPUF_LAMS) == 0) /* not included? */ - return TR_NXI; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = map_las (rn, bva)) != 0) /* do instruction */ - return tr; - CC34_W (R[rn]); /* set CC's */ - break; - - case OP_LVAW: /* load virt addr */ - if (!QCPU_5X0) /* 5X0 only */ - return TR_NXI; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - R[rn] = bva >> 2; /* store */ - break; - - case OP_LD: /* load doubleword */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read doubleword */ - return tr; - if ((opnd == 0) && (opnd1 != 0)) /* 0'non-zero? */ - CC = (CC & ~CC4) | CC3; /* set CC3 */ - else CC34_W (opnd); /* else hi sets CC */ - R[rn|1] = opnd1; /* store result */ - R[rn] = opnd; - break; - - case OP_LCD: /* load comp double */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read doubleword */ - return tr; - NEG_D (opnd, opnd1); /* negate */ - if ((opnd == 0) && (opnd1 != 0)) /* 0'non-zero? */ - CC = (CC & ~CC4) | CC3; /* set CC3 */ - else CC34_W (opnd); /* else hi sets CC */ - R[rn|1] = opnd1; /* store result */ - R[rn] = opnd; - if ((opnd == WSIGN) && (opnd1 == 0)) { /* overflow? */ - CC |= CC2; /* set CC2 */ - if (PSW1 & PSW1_AM) /* trap if enabled */ - return TR_FIX; - } - else CC &= ~CC2; /* no, clear CC2 */ - break; - - case OP_LAD: /* load abs double */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read doubleword */ - return tr; - if (opnd & WSIGN) /* negative? */ - NEG_D (opnd, opnd1); /* take abs value */ - if ((opnd == 0) && (opnd1 != 0)) /* 0'non-zero? */ - CC = (CC & ~CC4) | CC3; /* set CC3 */ - else CC34_W (opnd); /* else hi sets CC */ - R[rn|1] = opnd1; /* store result */ - R[rn] = opnd; - if ((opnd == WSIGN) && (opnd1 == 0)) { /* overflow? */ - CC |= CC2; /* set CC2 */ - if (PSW1 & PSW1_AM) /* trap if enabled */ - return TR_FIX; - } - else CC &= ~CC2; /* no, clear CC2 */ - break; - -/* Note: the Sigma 7 does not prove the instruction can execute successfully - before starting to load registers; the Sigma 9 (and the simulator) do. */ - - case OP_LM: /* load multiple */ - lim = CC? CC: 16; /* CC sets count */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW ((bva + ((lim - 1) << 2)) & bvamqrx, &opnd, VR)) != 0) - return tr; /* test readability */ - for (i = 0; i < lim; i++) { /* loop thru reg */ - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read next */ - return tr; - R[rn] = opnd; /* store in reg */ - bva = (bva + 4) & bvamqrx; /* next word */ - rn = (rn + 1) & RNMASK; /* next reg */ - PSW2 |= PSW2_RA; /* reg altered */ - } - break; - - case OP_LCFI: /* load cc, flt immed */ - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - if (IR & IRB(10)) /* load CC's? */ - CC = (opnd >> 4) & 0xF; - if (IR & IRB(11)) /* load FP ctrls? */ - PSW1 = ((PSW1 & ~PSW1_FPC) | /* set ctrls */ - ((opnd & PSW1_M_FPC) << PSW1_V_FPC)) & - ~cpu_tab[cpu_model].psw1_mbz; /* clear mbz */ - break; - - case OP_LCF: /* load cc, flt */ - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadB (bva, &opnd, VR)) != 0) /* get byte */ - return tr; - if (IR & IRB(10)) /* load CC's? */ - CC = (opnd >> 4) & 0xF; - if (IR & IRB(11)) /* load FP ctrls? */ - PSW1 = ((PSW1 & ~PSW1_FPC) | /* set ctrls */ - ((opnd & PSW1_M_FPC) << PSW1_V_FPC)) & - ~cpu_tab[cpu_model].psw1_mbz; /* clear mbz */ - break; - - case OP_XW: /* exchange word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - if ((tr = WriteW (bva, R[rn], VW)) != 0) /* write reg */ - return tr; - CC34_W (opnd); /* set cc's */ - R[rn] = opnd; /* store result */ - break; - - case OP_STB: /* store byte */ - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - if ((tr = WriteB (bva, R[rn], VW)) != 0) /* store */ - return tr; - break; - - case OP_STH: /* store halfword */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = WriteH (bva, R[rn], VW)) != 0) /* store */ - return tr; - if (R[rn] == (SEXT_H_W (R[rn]) & WMASK)) /* rn a sext hw? */ - CC &= ~CC2; /* yes, clr CC2 */ - else CC |= CC2; - break; - - case OP_STW: /* store word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = WriteW (bva, R[rn], VW)) != 0) /* store */ - return tr; - break; - - case OP_STD: /* store doubleword */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = WriteD (bva, R[rn], R[rn|1], VW)) != 0) /* store */ - return tr; - break; - - case OP_STS: /* store selective */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - res = (opnd & ~R[rn|1]) | (R[rn] & R[rn|1]); /* set under mask */ - if ((tr = WriteW (bva, res, VW)) != 0) /* store */ - return tr; - break; - -/* Note: the Sigma 7 does not prove the instruction can execute successfully - before starting to store registers; the Sigma 9 (and the simulator) do. */ - - case OP_STM: /* store multiple */ - lim = CC? CC: 16; /* CC sets count */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW ((bva + ((lim - 1) << 2)) & bvamqrx, &opnd, VW)) != 0) - return tr; /* test writeability */ - for (i = 0; i < lim; i++) { /* loop thru reg */ - if ((tr = WriteW (bva, R[rn], VW)) != 0) /* write reg */ - return tr; - bva = (bva + 4) & bvamqrx; /* next address */ - rn = (rn + 1) & RNMASK; /* next register */ - } - break; - - case OP_STCF: /* store cc, flt */ - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - res = (CC << 4) | ((PSW1 >> PSW1_V_FPC) & PSW1_M_FPC); - if ((tr = WriteB (bva, res, VW)) != 0) /* store */ - return tr; - break; - -/* Analyze: Sigma 9 uses <5:7> for trap codes, the 5X0 uses <1:3> */ - - case OP_ANLZ: /* analyze */ - mprot = ((PSW1 & (PSW1_MS|PSW1_MM)) == PSW1_MM) && - ((PSW2 & (PSW2_MA9|PSW2_MA5X0)) != 0); /* mstr prot */ - sc = QCPU_5X0? 4: 0; /* 5X0 vs S9 */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) { /* get eff address */ - if (mprot && QCPU_S9) { /* S9 mprot? */ - R[rn] = 0x07000000 | (bva >> 2); /* show failure */ - break; - } - return tr; /* others trap */ - } - if ((tr = ReadW (bva, &opnd, VR)) != 0) { /* get word */ - if (mprot) { /* trap, mprot? */ - R[rn] = (0x30000000 >> sc) | (bva >> 2); /* show failure */ - break; - } - return tr; /* others trap */ - } - aop = I_GETOP (opnd); /* get opcode */ - CC = anlz_tab[aop] & (CC1|CC2|CC4); /* set CC1,CC2,CC4 */ - if (TST_IND (opnd)) /* indirect? */ - CC |= CC3; /* set CC3 */ - if ((anlz_tab[aop] & CC4) == 0) { /* mem ref? */ - uint32 aln = anlz_tab[aop] >> 2; /* get length */ - if ((tr = Ea (opnd, &bva, VR, aln)) != 0) { /* get eff addr */ - if (mprot) { /* trap, mprot? */ - R[rn] = (0x10000000 >> sc) | (bva >> 2); /* show failure */ - break; - } - return tr; /* others trap */ - } - R[rn] = bva >> aln; /* cvt addr */ - } - break; - -/* Interpret */ - - case OP_INT: /* interpret */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* get word */ - return tr; - CC = (opnd >> 28) & 0xF; /* <0:3> -> CC */ - R[rn] = (opnd >> 16) & 0xFFF; /* <4:15> -> Rn */ - R[rn|1] = opnd & 0xFFFF; /* <16:31> -> Rn|1 */ - break; - -/* Arithmetic */ - - case OP_AI: /* add immediate */ - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sext to 32b */ - res = Add32 (R[rn], opnd, 0); /* add, set CC's */ - R[rn] = res; /* store result */ - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovfo, enabled? */ - return TR_FIX; - break; - - case OP_AH: /* add halfword */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - opnd = SEXT_H_W (opnd) & WMASK; /* sext to 32b */ - res = Add32 (R[rn], opnd, 0); /* add, set CC's */ - R[rn] = res; /* store result */ - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_AW: /* add word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - res = Add32 (R[rn], opnd, 0); /* add, set CC's */ - R[rn] = res; /* store result */ - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_AD: /* add doubleword */ - if (QCPU_S89_5X0 && (rn & 1)) /* invalid reg? */ - return TR_INVREG; - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read doubleword */ - return tr; - res1 = Add32 (R[rn|1], opnd1, 0); /* add low, high */ - res = Add32 (R[rn], opnd, (CC & CC1) != 0); - if ((res == 0) && (res1 != 0)) /* 0'non-zero? */ - CC = (CC & ~CC4) | CC3; /* set CC3 */ - R[rn|1] = res1; /* store */ - R[rn] = res; - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_AWM: /* add word to memory */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - res = Add32 (R[rn], opnd, 0); /* add, set CC's */ - if ((tr = WriteW (bva, res, VW)) != 0) /* store */ - return tr; - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_SH: /* subtract halfword */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - opnd = SEXT_H_W (opnd) & WMASK; /* sext to 32b */ - res = Add32 (R[rn], opnd ^ WMASK, 1); /* subtract, set CC's */ - R[rn] = res; /* store */ - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_SW: /* subtract word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - res = Add32 (R[rn], opnd ^ WMASK, 1); /* subtract */ - R[rn] = res; /* store */ - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_SD: /* subtract doubleword */ - if (QCPU_S89_5X0 && (rn & 1)) /* invalid reg? */ - return TR_INVREG; - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read doubleword */ - return tr; - res1 = Add32 (R[rn|1], opnd1 ^ WMASK, 1); /* sub low, high */ - res = Add32 (R[rn], opnd ^ WMASK, (CC & CC1) != 0); - if ((res == 0) && (res1 != 0)) /* 0'non-zero? */ - CC = (CC & ~CC4) | CC3; /* set CC3 */ - R[rn|1] = res1; /* store */ - R[rn] = res; - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_MI: /* multiply immed */ - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sext to 32b */ - res = SMul64 (R[rn|1], opnd, &res1); /* 64b product */ - R[rn] = res; /* store */ - R[rn|1] = res1; - break; - - case OP_MH: /* multiply half */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - sop = (int32) SEXT_H_W (R[rn]); /* sext operands */ - sop1 = (int32) SEXT_H_W (opnd); - res = (uint32) ((sop * sop1) & WMASK); /* product */ - CC34_W (res); /* set CC's */ - R[rn|1] = res; /* store */ - break; - - case OP_MW: /* multiply word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - res = SMul64 (R[rn|1], opnd, &res1); /* 64b product */ - R[rn] = res; /* store */ - R[rn|1] = res1; - break; - - case OP_DH: /* divide halfword */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - sop = (int32) R[rn]; /* sext operands */ - sop1 = (int32) SEXT_H_W (opnd); - if ((opnd == 0) || /* div by zero? */ - ((R[rn] == WSIGN) && /* -2^31 / -1? */ - (opnd == HMASK))) { - CC |= CC2; /* overflow */ - if (PSW1 & PSW1_AM) /* trap if enabled */ - return TR_FIX; - } - else { - res = (uint32) ((sop / sop1) & WMASK); /* quotient */ - CC &= ~CC2; /* no overflow */ - CC34_W (res); /* set CC's */ - R[rn] = res; /* store */ - } - break; - - case OP_DW: /* divide word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd2, VR)) != 0) /* get divisor */ - return tr; - if (rn & 1) /* odd reg? */ - opnd = (R[rn] & WSIGN)? WMASK: 0; /* high is sext low */ - else opnd = R[rn]; - opnd1 = R[rn|1]; /* low divd */ - if (SDiv64 (opnd, opnd1, opnd2, &res, &res1)) { /* 64b/32b divide */ - CC |= CC2; /* overflow, set CC2 */ - if (PSW1 & PSW1_AM) /* trap if enabled */ - return TR_FIX; - } - else { - CC &= ~CC2; /* clear CC2 */ - CC34_W (res); /* set CC's from quo */ - R[rn] = res1; /* store */ - R[rn|1] = res; - } - break; - - case OP_MTB: /* mod and test byte */ - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadB (bva, &opnd, VR)) != 0) /* read byte */ - return tr; - opnd1 = SEXT_RN_W (rn) & BMASK; /* mod is sext rn */ - res = (opnd + opnd1) & BMASK; /* do zext add */ - if (res < opnd) /* carry out? */ - CC = CC1; - else CC = 0; - CC34_W (res); /* set cc's */ - if (rn && /* any mod? */ - ((tr = WriteB (bva, res, VW)) != 0)) /* rewrite */ - return tr; - break; - - case OP_MTH: /* mod and test half */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - opnd = opnd & HMASK; /* 16 operands */ - opnd1 = SEXT_RN_W (rn) & HMASK; /* mod is sext rn */ - res = opnd + opnd1; /* 16b add */ - if ((res & HMASK) == 0) /* 16b CC tests */ - CC = 0; - else if (res & HSIGN) - CC = CC4; - else CC = CC3; - if ((res & ~HMASK) != 0) /* carry? */ - CC |= CC1; - if (((opnd ^ ~opnd1) & (opnd ^ res)) & HSIGN) /* set overflow */ - CC |= CC2; - if (rn && /* any mod? */ - ((tr = WriteH (bva, res, VW)) != 0)) /* rewrite */ - return tr; - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - - case OP_MTW: /* mod and test word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* get word */ - return tr; - opnd1 = SEXT_RN_W (rn) & WMASK; /* mod is sext rn */ - res = Add32 (opnd, opnd1, 0); /* do add */ - if (rn && /* any mod? */ - ((tr = WriteW (bva, res, VW)) != 0)) /* rewrite */ - return tr; - if ((CC & CC2) && (PSW1 & PSW1_AM)) /* ovflo, enabled? */ - return TR_FIX; - break; - -/* Logical */ - - case OP_AND: /* and */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* get word */ - return tr; - res = R[rn] & opnd; - CC34_W (res); /* set CC's */ - R[rn] = res; /* store */ - break; - - case OP_OR: /* or */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* get word */ - return tr; - res = R[rn] | opnd; - CC34_W (res); /* set CC's */ - R[rn] = res; /* store */ - break; - - case OP_EOR: /* xor */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* get word */ - return tr; - res = R[rn] ^ opnd; - CC34_W (res); /* set CC's */ - R[rn] = res; /* store */ - break; - -/* Compares */ - - case OP_CI: /* compare immed */ - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sext to 32b */ - CC234_CMP (R[rn], opnd); /* set CC's */ - break; - - case OP_CB: /* compare byte */ - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadB (bva, &opnd, VR)) != 0) /* read byte */ - return tr; - opnd1 = R[rn] & BMASK; /* zext operand */ - CC234_CMP (opnd1, opnd); /* set CC's */ - break; - - case OP_CH: /* compare halfword */ - if ((tr = Ea (IR, &bva, VR, HW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadH (bva, &opnd, VR)) != 0) /* read halfword */ - return tr; - opnd = SEXT_H_W (opnd) & WMASK; /* sext to 32b */ - CC234_CMP (R[rn], opnd); /* set CC's */ - break; - - case OP_CW: /* compare word */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - CC234_CMP (R[rn], opnd); /* set CC's */ - break; - - case OP_CD: /* compare double */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read doubleword */ - return tr; - CC &= ~(CC3|CC4); - if (R[rn] != opnd) /* hi unequal? */ - CC |= Cmp32 (R[rn], opnd); - else if (R[rn|1] != opnd1) /* low unequal? */ - CC |= (R[rn|1] < opnd1)? CC4: CC3; /* like signs */ - break; - - case OP_CS: /* compare select */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - opnd1 = R[rn] & R[rn|1]; /* mask operands */ - opnd = opnd & R[rn|1]; - if (opnd1 < opnd) /* unsigned compare */ - CC = (CC & ~CC3) | CC4; - else if (opnd1 > opnd) - CC = (CC & ~CC4) | CC3; - else CC &= ~(CC3|CC4); - break; - - case OP_CLR: /* compare limit reg */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - CC = Cmp32 (R[rn], opnd) | /* compare high reg */ - (Cmp32 (R[rn|1], opnd) << 2); /* compare low reg */ - break; - - case OP_CLM: /* compare limit mem */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* get doubleword */ - return tr; - CC = Cmp32 (R[rn], opnd) | /* compare high mem */ - (Cmp32 (R[rn], opnd1) << 2); /* compare low mem */ - break; - -/* Shift and convert instructions */ - - case OP_S: /* shift */ - if ((tr = EaSh (IR, &stype, &sc)) != 0) /* get type, count */ - return tr; - if ((stype >= 0x6) && QCPU_S567) /* invalid, S5-7? */ - stype = 0x4; /* treat as arith */ - CC = (CC & ~(CC1|CC2|CC4)) | /* shift, set CC's */ - Shift (rn, stype, sc); - break; - - case OP_SF: /* shift floating */ - if ((tr = EaSh (IR, &stype, &sc)) != 0) /* get type, count */ - return tr; - ShiftF (rn, stype & 1, sc); /* shift, set CC's */ - break; - - case OP_CVA: /* cvt by addition */ - if (QCPU_S5) /* not on Sigma 5 */ - return TR_NXI; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - CC &= ~CC1; /* clear CC1 (carry) */ - for (i = 0, res = 0; i < 32; i++) { /* 32 iterations */ - if ((R[rn|1] >> (31 - i)) & 1) { /* bit set? */ - uint32 ad = (bva + (i << 2)) & bvamqrx; /* table offset */ - if ((tr = ReadW (ad, &opnd, VR)) != 0) - return tr; /* read table word */ - res = (res + opnd) & WMASK; /* add into result */ - if (res < opnd) /* carry? set CC1 */ - CC |= CC1; - } /* end bit set */ - } /* end for */ - CC34_W (res); /* set CC's */ - R[rn] = res; /* store */ - break; - - case OP_CVS: /* cvt by subtraction */ - if (QCPU_S5) /* not on Sigma 5 */ - return TR_NXI; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - for (i = 0, res = R[rn], res1 = 0; i < 32; i++) { /* 32 iterations */ - uint32 ad = (bva + (i << 2)) & bvamqrx; /* table offset */ - if ((tr = ReadW (ad, &opnd, VR)) != 0) /* read table word */ - return tr; - if (opnd <= res) { /* residue >= entry? */ - res = (res - opnd) & WMASK; /* subtract entry */ - res1 |= 1u << (31 - i); /* set bit */ - } - } - CC34_W (res1); /* set CC's */ - R[rn] = res; /* store */ - R[rn|1] = res1; - break; - -/* Push down instructions */ - - case OP_PSW: /* push word */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VW)) != 0) /* read stack ptr */ - return tr; - if ((tr = TestSP1 (opnd1, 1)) != 0) /* will push work? */ - return ((tr & WSIGN)? 0: tr); - if ((tr = WriteW (((opnd + 1) << 2) & bvamqrx, R[rn], VW)) != 0) - return tr; /* push word */ - if ((tr = ModWrSP (bva, opnd, opnd1, 1)) != 0) /* mod, rewrite sp */ - return tr; - break; - - case OP_PLW: /* pull word */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VW)) != 0) /* read stack ptr */ - return tr; - if ((tr = TestSP1 (opnd1, -1)) != 0) /* will pull work? */ - return ((tr & WSIGN)? 0: tr); - if ((tr = ReadW (opnd << 2, &res, VR)) != 0) /* pull word */ - return tr; - if ((tr = ModWrSP (bva, opnd, opnd1, -1)) != 0) /* mod, rewrite sp */ - return tr; - R[rn] = res; - break; - - case OP_PSM: /* push multiple */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VW)) != 0) /* read stack ptr */ - return tr; - lim = CC? CC: 16; /* words to push */ - if ((tr = TestSP1 (opnd1, lim)) != 0) /* will push work? */ - return ((tr & WSIGN)? 0: tr); - if ((tr = ReadW (((opnd + lim) << 2) & bvamqrx, &res, VW)) != 0) - return tr; /* will last work? */ - for (i = 0; i < lim; i++) { /* loop thru reg */ - if ((tr = WriteW (((opnd + i + 1) << 2) & bvamqrx, R[rn], VW)) != 0) - return tr; /* push word */ - rn = (rn + 1) & RNMASK; - } - if ((tr = ModWrSP (bva, opnd, opnd1, lim)) != 0) /* mod, rewrite sp */ - return tr; - break; - - case OP_PLM: /* pull multiple */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VW)) != 0) /* read stack ptr */ - return tr; - lim = CC? CC: 16; /* words to pull */ - if ((tr = TestSP1 (opnd1, -((int32)lim))) != 0) /* will pull work? */ - return ((tr & WSIGN)? 0: tr); - rn = (rn + lim - 1) & RNMASK; - if ((tr = ReadW (((opnd - (lim - 1)) << 2) & bvamqrx, &res, VR)) != 0) - return tr; /* will last work? */ - for (i = 0; i < lim; i++) { /* loop thru reg */ - if ((tr = ReadW (((opnd - i) << 2) & bvamqrx, &res, VR)) != 0) - return tr; /* pull word */ - R[rn] = res; - rn = (rn - 1) & RNMASK; - } - if ((tr = ModWrSP (bva, opnd, opnd1, -((int32) lim))) != 0) - return tr; - break; - - case OP_MSP: /* modify stack ptr */ - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VW)) != 0) /* read stack ptr */ - return tr; - sop = SEXT_H_W (R[rn]); /* get modifier */ - if ((tr = TestSP1 (opnd1, sop)) != 0) /* will mod work? */ - return ((tr & WSIGN)? 0: tr); - if ((tr = ModWrSP (bva, opnd, opnd1, sop)) != 0) /* mod, rewrite sp */ - return tr; - break; - -/* Control instructions */ - - case OP_EXU: /* execute */ - if (exu_cnt++ > exu_lim) /* too many? */ - return STOP_EXULIM; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - IR = opnd; /* new instruction */ - goto EXU_LOOP; - - case OP_BCS: /* branch cond set */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((CC & rn) != 0) { /* branch taken? */ - if ((tr = ReadW (bva, &opnd, VI)) != 0) /* new PC readable? */ - return tr; - PCQ_ENTRY; - PC = cpu_new_PC (bva); /* branch */ - } - break; - - case OP_BCR: /* branch cond reset */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((CC & rn) == 0) { /* branch taken? */ - if ((tr = ReadW (bva, &opnd, VI)) != 0) /* new PC readable? */ - return tr; - PCQ_ENTRY; - PC = cpu_new_PC (bva); /* branch */ - } - break; - - case OP_BIR: /* branch incr reg */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - res = (R[rn] + 1) & WMASK; /* ++R[rn] */ - if ((res & WSIGN) != 0) { /* < 0? */ - if ((tr = ReadW (bva, &opnd, VI)) != 0) /* new PC readable? */ - return tr; - PCQ_ENTRY; - PC = cpu_new_PC (bva); /* branch */ - } - R[rn] = res; /* actual increment */ - break; - - case OP_BDR: /* branch decr reg */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - res = (R[rn] - 1) & WMASK; /* --R[rn] */ - if (((res & WSIGN) == 0) && (res != 0)) { /* > 0? */ - if ((tr = ReadW (bva, &opnd, VI)) != 0) /* new PC readable? */ - return tr; - PCQ_ENTRY; - PC = cpu_new_PC (bva); /* branch */ - } - R[rn] = res; /* actual decrement */ - break; - - case OP_BAL: /* branch and link */ - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VI)) != 0) /* new PC readable? */ - return tr; - R[rn] = cpu_add_PC (real_pc, 1); /* save incr PC */ - PCQ_ENTRY; - PC = cpu_new_PC (bva); /* branch */ - break; - - case OP_CAL1: /* CALL 1 */ - return TR_C1 (rn); - - case OP_CAL2: /* CALL 2 */ - return TR_C2 (rn); - - case OP_CAL3: /* CALL 3 */ - return TR_C3 (rn); - - case OP_CAL4: /* CALL 4 */ - return TR_C4 (rn); - -/* Privileged instructions */ - - case OP_MMC: /* MMC */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if (TST_IND (IR) && /* indirect? */ - ((tr = ReadW (I_GETADDR (IR) << 2, &opnd, VNT)) != 0)) - return tr; - return map_mmc (rn, I_GETXR (IR)); - - case OP_LPSD: /* load PSD */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadD (bva, &opnd, &opnd1, VR)) != 0) /* read stack ptr */ - return tr; - if ((tr = cpu_new_PSD (IR & IRB (8), opnd, opnd1)) != 0) - return tr; - PCQ_ENTRY; /* no traps, upd PCQ */ - if (IR & IRB (10)) /* clr hi pri int? */ - int_hireq = io_rels_int (int_hiact, IR & IRB (11)); - else if (IR & IRB (11)) /* clr PDF flag? */ - cpu_pdf = 0; - break; - - case OP_XPSD: /* exchange PSD */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = cpu_xpsd (IR & ~IRB (11), bva, VR)) != 0) /* do XPSD */ - return tr; - PCQ_ENTRY; /* no traps, upd PCQ */ - break; - - case OP_LRP: - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = ReadW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - return cpu_new_RP (opnd); /* update RP */ - - case OP_RD: /* direct I/O */ - case OP_WD: - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = io_rwd (op, rn, bva)) != 0) /* do direct I/O */ - return tr; - int_hiact = io_actv_int (); /* re-eval active */ - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_WAIT: /* wait for int */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if (!io_poss_int ()) /* intr possible? */ - return STOP_WAITNOINT; /* machine is hung */ -// put idle here - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_AIO: /* acknowledge int */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = io_aio (rn, bva)) != 0) /* do AIO */ - return tr; - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_SIO: /* start IO */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = io_sio (rn, bva)) != 0) /* do SIO */ - return tr; - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_HIO: /* halt IO */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = io_hio (rn, bva)) != 0) /* do HIO */ - return tr; - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_TIO: /* test IO */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = io_tio (rn, bva)) != 0) /* do AIO */ - return tr; - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_TDV: /* test device */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if ((tr = io_tdv (rn, bva)) != 0) /* do I/O */ - return tr; - int_hireq = io_eval_int (); /* re-eval intr */ - break; - - case OP_LRA: /* load real addr */ - if (QCPU_S89_5X0) { /* late models only */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - return map_lra (rn, IR); /* in map */ - } - return (PSW1 & PSW1_MS)? TR_NXI|TR_PRV: TR_NXI; - - case OP_LMS: /* load mem system */ - if ((cpu_unit.flags & CPUF_LAMS) == 0) /* implemented? */ - return (PSW1 & PSW1_MS)? TR_NXI|TR_PRV: TR_NXI; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - if (QCPU_S567) /* old CPU? */ - R[rn] = IR; /* loads inst to IR */ - else if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - else return map_lms (rn, bva); /* in map */ - break; - - case OP_PSS: /* push status */ - if (QCPU_5X0) { /* 5X0 only */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - if ((tr = cpu_pss (IR, bva, VR)) != 0) /* push status */ - return tr; - PCQ_ENTRY; - break; - } - return (PSW1 & PSW1_MS)? TR_NXI|TR_PRV: TR_NXI; - - case OP_PLS: /* pull status */ - if (QCPU_5X0) { /* 5X0 only */ - if (PSW1 & PSW1_MS) /* slave mode? */ - return TR_PRV; - if ((tr = cpu_pls (IR)) != 0) /* pull status */ - return tr; - PCQ_ENTRY; - break; - } - return (PSW1 & PSW1_MS)? TR_NXI|TR_PRV: TR_NXI; - -/* String instructions */ - - case OP_MBS: /* move byte string */ - if ((cpu_unit.flags & CPUF_STR) == 0) /* not implemented? */ - return TR_UNI; - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sign extend */ - if ((cnt = S_GETMCNT (R[rn|1])) != 0) { /* any move? */ - sa = (opnd + (rn? R[rn] + cnt - 1: 0)) & bvamqrx; /* last src addr */ - da = (R[rn|1] + cnt - 1) & bvamqrx; /* last dst addr */ - if (((tr = ReadB (sa, &c, VR)) != 0) || /* test last bytes */ - ((tr = ReadB (da, &c, VW)) != 0)) - return tr; - } - while (S_GETMCNT (R[rn|1])) { /* while count */ - sa = (opnd + (rn? R[rn]: 0)) & bvamqrx; /* src addr */ - da = R[rn|1] & bvamqrx; /* dst addr */ - if ((tr = ReadB (sa, &c, VR)) != 0) /* read src */ - return tr; - if ((tr = WriteB (da, c, VW)) != 0) /* write dst */ - return tr; - if (rn && !(rn & 1)) /* rn even, > 0? */ - R[rn] = (R[rn] + 1) & WMASK; /* inc saddr */ - R[rn|1] = (R[rn|1] + S_ADDRINC) & WMASK; /* inc daddr, dec cnt */ - } - break; - - case OP_CBS: /* compare byte str */ - if ((cpu_unit.flags & CPUF_STR) == 0) /* not implemented? */ - return TR_UNI; - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sign extend */ - if ((cnt = S_GETMCNT (R[rn|1])) != 0) { /* any compare? */ - sa = (opnd + (rn? R[rn] + cnt - 1: 0)) & bvamqrx; /* last src addr */ - da = (R[rn|1] + cnt - 1) & bvamqrx; /* last dst addr */ - if (((tr = ReadB (sa, &c, VR)) != 0) || /* test last bytes */ - ((tr = ReadB (da, &c, VR)) != 0)) - return tr; - } - CC = CC & ~(CC3|CC4); /* assume equal */ - while (S_GETMCNT (R[rn|1])) { /* while count */ - sa = (opnd + (rn? R[rn]: 0)) & bvamqrx; /* src addr */ - da = R[rn|1] & bvamqrx; /* dst addr */ - if ((tr = ReadB (sa, &c, VR)) != 0) /* read src */ - return tr; - if ((tr = ReadB (da, &c1, VR)) != 0) /* read dst */ - return tr; - if (c != c1) { /* not a match */ - CC |= ((c < c1)? CC4: CC3); - break; /* set CC's, done */ - } - if (rn && !(rn & 1)) /* rn even, > 0? */ - R[rn] = (R[rn] + 1) & WMASK; /* inc saddr */ - R[rn|1] = (R[rn|1] + S_ADDRINC) & WMASK; /* inc daddr, dec cnt */ - } - break; - - case OP_TBS: /* xlate byte string */ - if ((cpu_unit.flags & CPUF_STR) == 0) /* not implemented? */ - return TR_UNI; - if (QCPU_S89_5X0 && (rn & 1)) /* invalid reg? */ - return TR_INVREG; - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sign extend */ - if ((cnt = S_GETMCNT (R[rn|1])) != 0) { /* any translate? */ - da = (R[rn] + cnt - 1) & bvamqrx; /* last dst addr */ - if ((tr = ReadB (da, &c, VW)) != 0) /* test last byte */ - return tr; - } - while (S_GETMCNT (R[rn|1])) { /* while count */ - sa = (opnd + (rn? R[rn]: 0)) & bvamqrx; /* src addr */ - da = R[rn|1] & bvamqrx; /* dst addr */ - if ((tr = ReadB (da, &c, VR)) != 0) /* read dst */ - return tr; - if ((tr = ReadB ((sa + c) & bvamqrx, &c1, VR)) != 0) - return tr; /* translate byte */ - if ((tr = WriteB (da, c1, VW)) != 0) /* write dst */ - return tr; - R[rn|1] = (R[rn|1] + S_ADDRINC) & WMASK; /* inc daddr, dec cnt */ - } - break; - - case OP_TTBS: /* xlate, test string */ - if ((cpu_unit.flags & CPUF_STR) == 0) /* not implemented? */ - return TR_UNI; - if (QCPU_S89_5X0 && (rn & 1)) /* invalid reg? */ - return TR_INVREG; - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - opnd = SEXT_LIT_W (opnd) & WMASK; /* sign extend */ - mask = rn? S_GETMCNT (R[rn]): 0xFF; /* get mask */ - if ((cnt = S_GETMCNT (R[rn|1])) != 0) { /* any translate? */ - da = (R[rn] + cnt - 1) & bvamqrx; /* last dst addr */ - if ((tr = ReadB (da, &c, VR)) != 0) /* test last byte */ - return tr; - } - CC &= ~CC4; /* clear CC4 */ - while (S_GETMCNT (R[rn|1])) { /* while count */ - sa = (opnd + (rn? R[rn]: 0)) & bvamqrx; /* src addr */ - da = R[rn|1] & bvamqrx; /* dst addr */ - if ((tr = ReadB (da, &c, VR)) != 0) /* read dst */ - return tr; - if ((tr = ReadB ((sa + c) & bvamqrx, &c1, VR)) != 0) - return tr; /* translate byte */ - if ((t = c1 & mask) != 0) { /* byte & mask != 0? */ - if (rn) /* if !r0, repl mask */ - R[rn] = (R[rn] & ~S_MCNT) | (t << S_V_MCNT); - CC |= CC4; /* set CC4, stop */ - break; - } - R[rn|1] = (R[rn|1] + S_ADDRINC) & WMASK; /* inc daddr, dec cnt */ - } - break; - -/* Optional floating point instructions */ - - case OP_FAS: - case OP_FSS: - case OP_FMS: - case OP_FDS: /* short fp */ - if((cpu_unit.flags & CPUF_FP) == 0) /* option present? */ - return TR_UNI; - if ((tr = Ea (IR, &bva, VR, WD)) != 0) /* get eff addr */ - return tr; - return fp (op, rn, bva); /* go process */ - - case OP_FAL: - case OP_FSL: - case OP_FML: - case OP_FDL: /* long fp */ - if (QCPU_S89_5X0 && (rn & 1)) /* invalid reg? */ - return TR_INVREG; - if((cpu_unit.flags & CPUF_FP) == 0) /* option present? */ - return TR_UNI; - if ((tr = Ea (IR, &bva, VR, DW)) != 0) /* get eff addr */ - return tr; - return fp (op, rn, bva); /* go process */ - -/* Optional decimal instructions */ - - case OP_DL: - case OP_DST: - case OP_DA: - case OP_DS: - case OP_DM: - case OP_DD: - case OP_DC: - case OP_DSA: - case OP_PACK: - case OP_UNPK: /* decimal */ - if((cpu_unit.flags & CPUF_DEC) == 0) /* option present? */ - return TR_UNI; - if ((tr = Ea (IR, &bva, VR, BY)) != 0) /* get eff addr */ - return tr; - if ((tr = cis_dec (op, rn, bva)) & WSIGN) /* process, abort? */ - return 0; - else return tr; - - case OP_EBS: /* edit byte string */ - if ((tr = ImmOp (IR, &opnd)) != 0) /* get immed opnd */ - return tr; - if ((cpu_unit.flags & CPUF_DEC) == 0) /* option present? */ - return TR_UNI; - if (QCPU_S89_5X0 && ((rn == 0) || (rn & 1))) /* invalid reg? */ - return TR_INVREG; - if ((tr = cis_ebs (rn, opnd)) & WSIGN) /* process, abort? */ - return 0; - else return tr; - - default: /* undefined inst */ - return (stop_op? STOP_ILLEG: TR_NXI); - } -return 0; -} - -/* Execute MTx in an interrupt location - - Sigma 5/6/7/8 - 17b virtual or real addressing - Sigma 9/5X0 - 17b virtual or 20b real addressing, no indexing - - acc is either PH (physical) or VNT (no traps) - Memory map traps are suppressed, NXM's cause undefined behavior - (returns a nested trap fault) */ - -uint32 cpu_int_mtx (uint32 vec, uint32 *res) -{ -uint32 IR, bva, wd, op, rn, lnt, acc; - -ReadPW (vec, &IR); /* get instruction */ -op = I_GETOP (IR); /* get op */ -lnt = 3 - (op >> 5); /* 73, 53, 33 */ -acc = (vec == VEC_C4P)? VNT: PH; /* access */ -rn = I_GETRN (IR); /* register */ -if (hst_lnt) /* if history */ - inst_hist (IR, PC, H_ITRP); /* record inst */ -if ((acc || QCPU_S567)? /* virt or S5-7? */ - (Ea (IR, &bva, acc, lnt) != 0): /* get eff addr */ - (EaP20 (IR, &bva, lnt) != 0)) /* get real addr */ - return TR_NESTED; - - switch (lnt) { - case BY: - if (ReadB (bva, &wd, acc) != 0) /* read byte */ - return TR_NESTED; - wd = (wd + SEXT_RN_W (rn)) & BMASK; /* modify */ - if (rn && (WriteB (bva, wd, acc) != 0)) /* if mod, rewrite */ - return TR_NESTED; - break; - case HW: - if (ReadH (bva, &wd, acc) != 0) /* read halfword */ - return TR_NESTED; - wd = (wd + SEXT_RN_W (rn)) & HMASK; /* modify */ - if (rn && (WriteB (bva, wd, acc) != 0)) /* if mod, rewrite */ - return TR_NESTED; - break; - case WD: - if (ReadW (bva, &wd, acc) != 0) /* read word */ - return TR_NESTED; - wd = (wd + SEXT_RN_W (rn)) & WMASK; /* modify */ - if (rn && (WriteW (bva, wd, acc) != 0)) /* if mod, rewrite */ - return TR_NESTED; - break; - } - -*res = wd; -return 0; -} - -/* Execute XSPD or PSS in trap or interrupt location */ - -uint32 cpu_trap_or_int (uint32 vec) -{ -uint32 IR, op, bva, acc, cc; - -ReadPW (TR_GETVEC (vec), &IR); /* read vector */ -op = I_GETOP (IR); /* get op */ -if (hst_lnt) { /* if history */ - if (vec & TR_FL) /* trap? */ - hst[hst_p].typ_cc_pc |= H_ABRT; /* mark prev abt */ - inst_hist (IR, PC, H_ITRP); /* record inst */ - } -if (vec & TR_FL) { /* trap? */ - if (QCPU_S89) /* Sigma 89? */ - PSW2 = (PSW2 & ~PSW2_TSF) | ((vec & PSW2_M_TSF) << PSW2_V_TSF); - if (vec == TR_INVRPN) /* non-trap reg ptr? */ - vec = TR_INVRPT; /* cvt to trapped */ - if (vec & TR_PDF) /* trap sets PDF? */ - cpu_pdf = 1; - } -if (op == OP_XPSD) { /* XPSD? */ - acc = (IR & IRB (10))? VNT: PH; /* virt vs phys */ - if ((acc || QCPU_S567)? /* virt or S5-7? */ - (Ea (IR, &bva, acc, DW) != 0): /* get eff addr */ - (EaP20 (IR, &bva, DW) != 0)) /* get real addr */ - return TR_NESTED; - if (cpu_xpsd (IR, bva, acc) != 0) /* do XPSD */ - return TR_NESTED; - if ((cc = TR_GETCC (vec)) != 0) { /* modify CC's? */ - CC = CC | cc; /* modify new CC's */ - if (IR & IRB (9)) /* and maybe new PC */ - PC = cpu_add_PC (PC, cc); - } - return 0; - } -if (QCPU_5X0 && (op == OP_PSS)) { /* 5X0 PSS? */ - if (EaP20 (IR, &bva, DW) != 0) /* get real addr */ - return TR_NESTED; - if (cpu_pss (IR, bva, PH)) /* do PSS */ - return TR_NESTED; - } -return TR_INVTRP; -} - -/* Immediate operand */ - -uint32 ImmOp (uint32 IR, uint32 *imm) -{ -if (TST_IND (IR)) /* indirect traps */ - return TR_NXI; -*imm = I_GETLIT (IR); -if (hst_lnt) /* record history */ - hst[hst_p].ea = hst[hst_p].op = *imm; -return 0; -} - -/* Calculate effective address for normal instructions - Note that in the event of a failure reading the ind addr, - Ea must return that value in bva (for ANLZ) */ - -uint32 Ea (uint32 IR, uint32 *bva, uint32 acc, uint32 lnt) -{ -uint32 ad, xr, wd; -uint32 tr; - -xr = I_GETXR (IR); /* get index reg */ -ad = I_GETADDR (IR) << 2; /* get byte address */ -if (TST_IND (IR)) { /* indirect */ - if ((tr = ReadW (ad, &wd, acc)) != 0) { /* read ind word */ - *bva = ad; /* err? return addr */ - return tr; - } - if (PSW_QRX9 && (wd & WSIGN)) { /* S9 real ext special? */ - wd = wd & VAMASK; /* use only 17b */ - ad = (wd & PSW1_XA)? /* extended word? */ - (PSW2 & PSW2_EA) | (wd & ~PSW1_XA): wd; - ad = ad << 2; - } - else ad = (wd & bvamqrx) << 2; /* get byte address */ - } -*bva = (ad + (xr? (R[xr] << lnt): 0)) & bvamqrx; /* index, mask */ -if (hst_lnt) { /* history? */ - hst[hst_p].ea = *bva; - ReadHist (*bva, &hst[hst_p].op, &hst[hst_p].op1, acc? VNT: PH, lnt); - } -return 0; -} - -/* Calculate effective address for 20b interrupt/trap instructions */ - -uint32 EaP20 (uint32 IR, uint32 *bva, uint32 lnt) -{ -uint32 pa, wd; - -pa = I_GETADDR20 (IR); /* get 20b ref addr */ -if (TST_IND (IR)) { /* indirect? */ - if (ReadPW (pa, &wd)) { /* valid? */ - *bva = pa << 2; - return TR_NXM; - } - pa = wd & cpu_tab[cpu_model].pamask; /* get indirect */ - } -*bva = pa << 2; -if (hst_lnt) { /* history? */ - hst[hst_p].ea = *bva; - ReadHist (*bva, &hst[hst_p].op, &hst[hst_p].op1, PH, lnt); - } -return 0; -} - -/* Calculate effective address for shift */ - -uint32 EaSh (uint32 IR, uint32 *stype, uint32 *sc) -{ -uint32 ad, xr, wd, tr; - -xr = I_GETXR (IR); /* get index reg */ -ad = I_GETADDR (IR); /* get word addr */ -if (TST_IND (IR)) { /* indirect? */ - if ((tr = ReadW (ad << 2, &wd, VR)) != 0) /* read ind word */ - return tr; - ad = I_GETADDR (wd); /* get word addr */ - } -if (xr) - ad = (ad & ~SHF_M_SC) | ((ad + R[xr]) & SHF_M_SC); /* indexing? */ -*stype = SHF_GETSOP (ad); /* extract type */ -*sc = SHF_GETSC (ad); /* extract count */ -if (hst_lnt) { - hst[hst_p].ea = ad << 2; - hst[hst_p].op = ad; - } -return 0; -} - -/* Shift routines */ - -uint32 Shift (uint32 rn, uint32 stype, uint32 sc) -{ -uint32 i, opnd, opnd1, t, cc; - -opnd = R[rn]; /* get operand(s) */ -opnd1 = R[rn|1]; -cc = CC & CC4; - -if (sc & SCSIGN) { /* right? */ - sc = SHF_M_SC + 1 - sc; - switch (stype) { - - case 0x0: /* right log sgl */ - if (sc > 31) /* >31? res = 0 */ - R[rn] = 0; - else R[rn] = R[rn] >> sc; - break; - - case 0x1: /* right log dbl */ - if (sc > 63) /* >63? res = 0 */ - opnd = opnd1 = 0; - else if (sc > 31) { /* >31? */ - sc = sc - 32; - opnd1 = opnd >> sc; - opnd = 0; - } - else { - opnd1 = ((opnd1 >> sc) | (opnd << (32 - sc))) & WMASK; - opnd = opnd >> sc; - } - R[rn|1] = opnd1; - R[rn] = opnd; - break; - - case 0x2: /* right circ sgl */ - sc = sc % 32; /* mod 32 */ - R[rn] = ((R[rn] >> sc) | (R[rn] << (32 - sc))) & WMASK; - break; - - case 0x3: /* right circ dbl */ - sc = sc % 64; /* mod 64 */ - t = opnd; - if (sc > 31) { /* >31? */ - sc = sc - 32; - opnd = ((opnd1 >> sc) | (opnd << (32 - sc))) & WMASK; - opnd1 = ((t >> sc) | (opnd1 << (32 - sc))) & WMASK; - } - else { - opnd = ((opnd >> sc) | (opnd1 << (32 - sc))) & WMASK; - opnd1 = ((opnd1 >> sc) | (t << (32 - sc))) & WMASK; - } - R[rn|1] = opnd1; - R[rn] = opnd; - break; - - case 0x4: /* right arith sgl */ - t = (R[rn] & WSIGN)? WMASK: 0; - if (sc > 31) /* >31? res = sign */ - R[rn] = t; - else R[rn] = ((R[rn] >> sc) | (t << (32 - sc))) & WMASK; - break; - - case 0x5: /* right arith dbl */ - t = (R[rn] & WSIGN)? WMASK: 0; - if (sc > 63) /* >63? res = sign */ - opnd = opnd1 = t; - else if (sc > 31) { /* >31? */ - sc = sc - 32; - opnd1 = ((opnd >> sc) | (t << (32 - sc))) & WMASK; - opnd = t; - } - else { - opnd1 = ((opnd1 >> sc) | (opnd << (32 - sc))) & WMASK; - opnd = ((opnd >> sc) | (t << (32 - sc))) & WMASK; - } - R[rn|1] = opnd1; - R[rn] = opnd; - break; - - case 0x6: /* right search sgl */ - for (i = 0; (i < sc) && !(opnd & WSIGN); i++) { - opnd = ((opnd >> 1) | (opnd << 31)) & WMASK; - } - cc = (opnd & WSIGN)? (cc | CC4): (cc & ~CC4); - R[rn] = opnd; - R[1] = sc - i; - break; - - case 0x7: /* right search dbl */ - for (i = 0; (i < sc) & !(opnd & WSIGN); i++) { - t = opnd; - opnd = ((opnd >> 1) | (opnd1 << 31)) & WMASK; - opnd1 = ((opnd1 >> 1) | (t << 31)) & WMASK; - } - cc = (opnd & WSIGN)? (cc | CC4): (cc & ~CC4); - R[rn|1] = opnd1; - R[rn] = opnd; - R[1] = sc - i; - break; - } - } /* end if */ - -else { /* left shift */ - switch (stype) { /* switch on type */ - - case 0x0: /* left log sgl */ - case 0x4: /* left arith sgl */ - for (i = 0; i < sc; i++) { - if (opnd & WSIGN) /* count 1's */ - cc = cc ^ CC1; - opnd = (opnd << 1) & WMASK; - if ((opnd ^ R[rn]) & WSIGN) /* sign change? */ - cc |= CC2; - } - R[rn] = opnd; - break; - - case 0x1: /* left log dbl */ - case 0x5: /* left arith dbl */ - for (i = 0; i < sc; i++) { - if (opnd & WSIGN) /* count 1's */ - cc = cc ^ CC1; - opnd = ((opnd << 1) | (opnd1 >> 31)) & WMASK; - opnd1 = (opnd1 << 1) & WMASK; - if ((opnd ^ R[rn]) & WSIGN) /* sign change? */ - cc |= CC2; - } - R[rn|1] = opnd1; - R[rn] = opnd; - break; - - case 0x2: /* left circ sgl */ - for (i = 0; i < sc; i++) { - if (opnd & WSIGN) /* count 1's */ - cc = cc ^ CC1; - opnd = ((opnd << 1) | (opnd >> 31)) & WMASK; - if ((opnd ^ R[rn]) & WSIGN) /* sign change? */ - cc |= CC2; - } - R[rn] = opnd; - break; - - case 0x3: /* left circ dbl */ - for (i = 0; i < sc; i++) { - if ((t = opnd & WSIGN) != 0) /* count 1's */ - cc = cc ^ CC1; - opnd = ((opnd << 1) | (opnd1 >> 31)) & WMASK; - opnd1 = ((opnd1 << 1) | (t >> 31)) & WMASK; - if ((opnd ^ R[rn]) & WSIGN) /* sign change? */ - cc |= CC2; - } - R[rn|1] = opnd1; - R[rn] = opnd; - break; - - case 0x6: /* left search sgl */ - for (i = 0; (i < sc) & !(opnd & WSIGN); i++) { - opnd = ((opnd << 1) | (opnd >> 31)) & WMASK; - if ((opnd ^ R[rn]) & WSIGN) /* sign change? */ - cc |= CC2; - } - cc = (opnd & WSIGN)? (cc | CC4): (cc & ~CC4); - R[rn] = opnd; - R[1] = sc - i; - break; - - case 0x7: /* left search dbl */ - for (i = 0; (i < sc) & !(opnd & WSIGN); i++) { - t = opnd; - opnd = ((opnd << 1) | (opnd1 >> 31)) & WMASK; - opnd1 = ((opnd1 << 1) | (t >> 31)) & WMASK; - if ((opnd ^ R[rn]) & WSIGN) /* sign change? */ - cc |= CC2; - } - cc = (opnd & WSIGN)? (cc | CC4): (cc & ~CC4); - R[rn|1] = opnd1; - R[rn] = opnd; - R[1] = sc - i; - break; - } /* end switch */ - } /* end else */ -return cc; -} - -/* Arithmetic routines */ - -uint32 Add32 (uint32 s1, uint32 s2, uint32 cin) -{ -uint32 t = (s1 + s2 + cin) & WMASK; /* add + carry in */ - -if (t & WSIGN) /* set CC34 */ - CC = CC4; -else if (t != 0) - CC = CC3; -else CC = 0; -if (cin? (t <= s1): (t < s1)) /* set carry out */ - CC |= CC1; -if (((s1 ^ ~s2) & (s1 ^ t)) & WSIGN) /* set overflow */ - CC |= CC2; -return t; -} - -uint32 SMul64 (uint32 a, uint32 b, uint32 *lo) -{ -uint32 ah, bh, al, bl, rhi, rlo, rmid1, rmid2, sign; - -CC &= CC1; /* clr CC2-4 */ -if ((a == 0) || (b == 0)) { /* zero argument? */ - *lo = 0; /* result is zero */ - return 0; - } -sign = a ^ b; /* sign of result */ -if (a & WSIGN) /* |a|, |b| */ - a = NEG_W (a); -if (b & WSIGN) - b = NEG_W (b); -ah = (a >> 16) & HMASK; /* split operands */ -bh = (b >> 16) & HMASK; /* into 16b chunks */ -al = a & HMASK; -bl = b & HMASK; -rhi = ah * bh; /* high result */ -rmid1 = ah * bl; -rmid2 = al * bh; -rlo = al * bl; -rhi = rhi + ((rmid1 >> 16) & HMASK) + ((rmid2 >> 16) & HMASK); -rmid1 = (rlo + (rmid1 << 16)) & WMASK; /* add mid1 to lo */ -if (rmid1 < rlo) /* carry? incr hi */ - rhi = rhi + 1; -rmid2 = (rmid1 + (rmid2 << 16)) & WMASK; /* add mid2 to to */ -if (rmid2 < rmid1) /* carry? incr hi */ - rhi = rhi + 1; -rhi = rhi & WMASK; -if (sign & WSIGN) /* neg result? */ - NEG_D (rhi, rmid2); -if (rhi & WSIGN) /* < 0, set CC4 */ - CC |= CC4; -else if (rhi || rmid2) /* > 0, set CC3 */ - CC |= CC3; -if (rhi != ((rmid2 & WSIGN)? WMASK: 0)) /* fit in 32b? */ - CC |= CC2; /* set CC2 */ -*lo = rmid2; -return rhi; -} - -t_bool SDiv64 (uint32 dvdh, uint32 dvdl, uint32 dvr, uint32 *res, uint32 *rem) -{ -uint32 i, quo, quos, rems; - -quos = dvdh ^ dvr; -rems = dvdh; -if (dvdh & WSIGN) { /* |dividend| */ - NEG_D (dvdh, dvdl); - } -if (dvr & WSIGN) /* |divisor| */ - dvr = NEG_W (dvr); -if (dvdh >= dvr) /* divide work? */ - return TRUE; -for (i = quo = 0; i < 32; i++) { /* 32 iterations */ - quo = (quo << 1) & WMASK; /* shift quotient */ - dvdh = ((dvdh << 1) | (dvdl >> 31)) & WMASK; /* shift dividend */ - dvdl = (dvdl << 1) & WMASK; - if (dvdh >= dvr) { /* step work? */ - dvdh = (dvdh - dvr) & WMASK; /* subtract dvr */ - quo = quo + 1; - } - } -if (quo & WSIGN) /* quotient ovflo? */ - return TRUE; -*rem = (rems & WSIGN)? NEG_W (dvdh): dvdh; /* sign of rem */ -*res = (quos & WSIGN)? NEG_W (quo): quo; -return FALSE; /* no overflow */ -} - -uint32 Cmp32 (uint32 a, uint32 b) -{ -if (a == b) /* ==? */ - return 0; -if ((a ^ b) & WSIGN) /* unlike signs? */ - return (a & WSIGN)? CC4: CC3; -return (a < b)? CC4: CC3; /* like signs */ -} - -/* Test stack pointer space/words to see if it can be modified - - returns special abort status (WSIGN) */ - -uint32 TestSP1 (uint32 sp1, int32 mod) -{ -int32 spc, wds; -uint32 cc; - -cc = 0; -spc = (int32) SP_GETSPC (sp1); /* get space */ -wds = (int32) SP_GETWDS (sp1); /* get words */ -if (((wds + mod) > SP_M_WDS) || ((wds + mod) < 0)) { /* words overflow? */ - if ((sp1 & SP_TW) == 0) /* trap if enabled */ - return TR_PSH; - cc |= CC3; - } -if (((spc - mod) > SP_M_WDS) || ((spc - mod) < 0)) { /* space overflow? */ - if ((sp1 & SP_TS) == 0) /* trap if enabled */ - return TR_PSH; - cc |= CC1; - } -CC = cc; -if (cc || (mod == 0)) { /* mod fails? */ - CC |= ((spc? 0: CC2) | (wds? 0: CC4)); - return WSIGN; - } -return 0; -} - -/* Actually modify stack pointer space/words and set CC's, - used by PSW/PLW/PSM/PLM */ - -uint32 ModWrSP (uint32 bva, uint32 sp, uint32 sp1, int32 mod) -{ -uint32 tr; - -sp = (sp + mod) & WMASK; -sp1 = (sp1 & (SP_TS|SP_TW)) | - (((SP_GETSPC (sp1) - mod) & SP_M_SPC) << SP_V_SPC) | - (((SP_GETWDS (sp1) + mod) & SP_M_WDS) << SP_V_WDS); -if ((tr = WriteD (bva, sp, sp1, VW)) != 0) - return tr; -if ((mod > 0) && SP_GETSPC (sp1) == 0) - CC |= CC2; -if ((mod < 0) && SP_GETWDS (sp1) == 0) - CC |= CC4; -return 0; -} - -/* XPSD instruction */ - -uint32 cpu_xpsd (uint32 IR, uint32 bva, uint32 ra) -{ -uint32 wa, wd, wd1, wd3; -uint32 tr; - -if (ra == VR) /* virtual? */ - wa = VW; /* set write virt */ -else wa = ra; /* no, phys */ -cpu_assemble_PSD (); -wd = PSW1; /* no more changes */ -wd1 = PSW2; -wd3 = PSW4; -if ((tr = WriteD (bva, wd, wd1, wa)) != 0) /* write curr PSD */ - return tr; -bva = bva + 8; -if (QCPU_5X0 && (IR & IRB (11))) { /* extra words? */ - if ((tr = WriteW (bva | 4, wd3, VW)) != 0) - return tr; - bva = bva + 8; - } -if ((tr = ReadD (bva, &wd, &wd1, ra)) != 0) /* read new PSD */ - return tr; -wd1 = (wd1 & ~(cpu_tab[cpu_model].psw2_mbz)) | /* merge inhibits */ - (PSW2 & PSW2_ALLINH); -if ((tr = cpu_new_PSD (IR & IRB (8), wd, wd1)) != 0) /* update PSD */ - return tr; -return 0; -} - -/* PSS instruction */ - -uint32 cpu_pss (uint32 IR, uint32 bva, uint32 acc) -{ -uint32 i, wd, wd1, tos, swc; -uint32 tr; - -cpu_assemble_PSD (); /* get old PSD */ -if ((tr = ReadD (bva, &wd, &wd1, acc)) != 0) /* read new PSD */ - return tr; -ReadPW (SSP_TOS, &tos); /* read system SP */ -ReadPW (SSP_SWC, &swc); -for (i = 0; i < RF_NUM; i++) { /* push registers */ - if (WritePW (tos + SSP_FR_RN + i + 1, R[i])) - return TR_NXM; - } -if (WritePW (tos + SSP_FR_PSW1 + 1, PSW1) || /* push PSD */ - WritePW (tos + SSP_FR_PSW2 + 1, PSW2)) - return TR_NXM; -WritePW (SSP_TOS, (tos + SSP_FR_LNT) & WMASK); /* tos + 28 */ -swc = (swc & (SP_TS|SP_TW)) | /* spc-28, wds+28 */ - (((SP_GETWDS (swc) + SSP_FR_LNT) & SP_M_WDS) << SP_V_WDS) | - (((SP_GETSPC (swc) - SSP_FR_LNT) & SP_M_SPC) << SP_V_SPC); -if (SP_GETWDS (swc) < SSP_FR_LNT) /* wds overflow? */ - swc |= SP_TW; /* set sticky bit */ -WritePW (SSP_SWC, swc); -wd1 = (wd1 & ~(cpu_tab[cpu_model].psw2_mbz)) | /* merge inhibits */ - (PSW2 & PSW2_ALLINH); -if ((tr = cpu_new_PSD (IR & IRB (8), wd, wd1)) != 0) /* update PSD */ - return tr; -return 0; -} - -/* PLS instruction */ - -uint32 cpu_pls (uint32 IR) -{ -uint32 i, wd, wd1, tos, swc, spc; -uint32 tr; - -ReadPW (SSP_TOS, &tos); /* read system SP */ -ReadPW (SSP_SWC, &swc); -spc = SP_GETSPC (swc); /* space left */ -if (spc == 0) { /* none? */ - ReadPW (SSP_DFLT_PSW1, &wd); /* use default PSD */ - ReadPW (SSP_DFLT_PSW2, &wd1); - } -else if (spc < SSP_FR_LNT) /* not enough? */ - return TR_INVSSP; -else { - tos = (tos - SSP_FR_LNT) & WMASK; /* modify TOS */ - for (i = 0; i < RF_NUM; i++) { /* pull registers */ - if (ReadPW (tos + SSP_FR_RN + i + 1, &wd)) - return TR_NXM; - R[i] = wd; - } - if (ReadPW (tos + SSP_FR_PSW1 + 1, &wd) || /* pull new PSD */ - ReadPW (tos + SSP_FR_PSW2 + 1, &wd1)) - return TR_NXM; - WritePW (SSP_TOS, tos); /* rewrite SP */ - swc = (swc & (SP_TS|SP_TW)) | /* spc+28, wds-28 */ - (((SP_GETWDS (swc) - SSP_FR_LNT) & SP_M_WDS) << SP_V_WDS) | - (((SP_GETSPC (swc) + SSP_FR_LNT) & SP_M_SPC) << SP_V_SPC); - if (SP_GETSPC (swc) < SSP_FR_LNT) /* spc overflow? */ - swc |= SP_TS; /* set sticky bit */ - WritePW (SSP_SWC, swc); - } -wd1 = (wd1 & ~(cpu_tab[cpu_model].psw2_mbz)) | /* merge inhibits */ - (PSW2 & PSW2_ALLINH); -if ((tr = cpu_new_PSD (IR & IRB (8), wd, wd1)) != 0) /* update PSD */ - return tr; -if (IR & IRB (10)) /* clr hi pri int? */ - int_hireq = io_rels_int (int_hiact, IR & IRB (11)); -else if (IR & IRB (11)) /* clr PDF flag? */ - cpu_pdf = 0; - -return 0; -} - -/* Load new PSD */ - -uint32 cpu_new_PSD (uint32 lrp, uint32 p1, uint32 p2) -{ -uint32 tr; - -PSW1 = p1 & ~cpu_tab[cpu_model].psw1_mbz; /* clear mbz bits */ -PSW2 = ((p2 & ~PSW2_RP) | (PSW2 & PSW2_RP)) & /* save reg ptr */ - ~cpu_tab[cpu_model].psw2_mbz; -if (lrp && /* load reg ptr? */ - ((tr = cpu_new_RP (p2)) != 0)) /* invalid? */ - return tr; /* trap */ -CC = PSW1_GETCC (PSW1); /* extract CC's */ -PC = PSW1_GETPC (PSW1); /* extract PC */ -PSW2_WLK = PSW2_GETWLK (PSW2); /* extract lock */ -int_hireq = io_eval_int (); /* update intr */ -if ((PSW1 & PSW1_MM) || /* mapped or */ - ((PSW2 & (PSW2_MA9|PSW2_MA5X0)) == 0)) { /* not real ext? */ - bvamqrx = BVAMASK; /* 17b masks */ - PSW_QRX9 = 0; - } -else { /* phys real ext */ - if ((PSW_QRX9 = PSW2 & PSW2_MA9) != 0) /* Sigma 9? */ - bvamqrx = BPAMASK22; /* yes, 22b masks */ - else bvamqrx = BPAMASK20; /* no, 20b masks */ - } -return 0; -} - -/* Load new RP */ - -uint32 cpu_new_RP (uint32 rp) -{ -uint32 rp1, j; - -PSW2 = (PSW2 & ~PSW2_RP) | (rp & PSW2_RP); /* merge to PSW2 */ -PSW2 = PSW2 & ~cpu_tab[cpu_model].psw2_mbz; /* clear nx bits */ -rp1 = PSW2_GETRP (rp); -if (rp1 >= rf_bmax) { /* nx reg file? */ - if (QCPU_S89) - return TR_INVRPN; - if (QCPU_5X0) - return TR_INVREG; - for (j = 0; j < RF_NUM; j++) /* clear nx set */ - rf[(rp1 * RF_NUM) + j] = 0; - sim_activate (&cpu_rblk_unit, 1); /* sched cleaner */ - } -R = rf + (rp1 * RF_NUM); -return 0; -} - -/* This routine is scheduled if the current registr block doesn't exist */ - -t_stat cpu_bad_rblk (UNIT *uptr) -{ -uint32 rp1, j; - -rp1 = PSW2_GETRP (PSW2); /* get reg ptr */ -if (rp1 >= rf_bmax) { /* still bad? */ - for (j = 0; j < RF_NUM; j++) /* clear nx set */ - rf[(rp1 * RF_NUM) + j] = 0; - sim_activate (uptr, 1); /* sched again */ - } -return SCPE_OK; -} - -/* Load new PC for branch instruction */ - -uint32 cpu_new_PC (uint32 bva) -{ -uint32 npc = bva >> 2; - -if (PSW_QRX9 && (npc & PSW1_XA)) /* S9 real ext, XA? */ - PSW2 = (PSW2 & ~PSW2_EA) | (npc & PSW2_EA); /* change PSW2 EA */ -return npc & BVAMASK; -} - -/* Add value to PC for fetch, BAL, trap */ - -uint32 cpu_add_PC (uint32 pc, uint32 inc) -{ -if (PSW_QRX9) /* S9 real ext? */ - return ((pc & ~(PSW1_M_PC & ~PSW1_XA)) | /* modulo 16b inc */ - ((pc + inc) & (PSW1_M_PC & ~PSW1_XA))); -return ((pc + inc) & BVAMASK); /* no, mod 17b inc */ -} - -/* Assemble PSD */ - -void cpu_assemble_PSD (void) -{ -PSW1 = (PSW1 & ~(PSW1_CCMASK|PSW1_PCMASK|cpu_tab[cpu_model].psw1_mbz)) | - (CC << PSW1_V_CC) | (PC << PSW1_V_PC); -PSW2 = (PSW2 & ~(PSW2_WLKMASK|cpu_tab[cpu_model].psw2_mbz)) | - (PSW2_WLK << PSW2_V_WLK); -return; -} - -/* Reset routine */ - -t_stat cpu_reset (DEVICE *dptr) -{ -cpu_new_PSD (1, PSW1_DFLT | (PSW1 & PSW1_PCMASK), PSW2_DFLT); -cpu_pdf = 0; -cons_alarm = 0; -cons_pcf = 0; -set_rf_display (R); -if (M == NULL) - M = (uint32 *) calloc (MAXMEMSIZE, sizeof (uint32)); -if (M == NULL) - return SCPE_MEM; -pcq_r = find_reg ("PCQ", NULL, dptr); -if (pcq_r) pcq_r->qptr = 0; -else return SCPE_IERR; -sim_brk_types = sim_brk_dflt = SWMASK ('E'); -rtc_register (RTC_ALARM, RTC_HZ_2, &cpu_unit); -return int_reset (dptr); -} - -/* Memory examine */ - -t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) -{ -uint32 lnt; - -if (sw & SWMASK ('C')) - lnt = 2; -else if ((sw & SWMASK ('B')) || (sw & SWMASK ('A')) || (sw & SWMASK ('E'))) - lnt = 0; -else if (sw & SWMASK ('H')) - lnt = 1; -else lnt = 2; -if (sw & SWMASK ('V')) { - if (ReadW (addr << lnt, vptr, VNT) != 0) - return SCPE_REL; - } -else if (ReadW (addr << lnt, vptr, PH) != 0) - return SCPE_NXM; -return SCPE_OK; -} - -/* Memory deposit */ - -t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) -{ -uint32 lnt; - -if (sw & SWMASK ('C')) - lnt = 2; -else if ((sw & SWMASK ('B')) || (sw & SWMASK ('A')) || (sw & SWMASK ('E'))) - lnt = 0; -else if (sw & SWMASK ('H')) - lnt = 1; -else lnt = 2; -if (sw & SWMASK ('V')) { - if (WriteW (addr << lnt, val, VNT) != 0) - return SCPE_REL; - } -else if (WriteW (addr << lnt, val, PH) != 0) - return SCPE_NXM; -return SCPE_OK; -} - -/* CPU configuration management - - These routines (for type, memory size, options, number of reg blocks, - number of external int blocks) must generate a consistent result. - To assure this, all changes (except memory size) reset the CPU. */ - -/* Set CPU type */ - -t_stat cpu_set_type (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 model = CPUF_GETMOD (val); - -if (model == cpu_model) /* no change? */ - return SCPE_OK; -cpu_reset (&cpu_dev); -if (MEMSIZE > (cpu_tab[cpu_model].pamask + 1)) - cpu_set_size (uptr, cpu_tab[cpu_model].pamask + 1, NULL, (void *) uptr); -cpu_model = model; -cpu_unit.flags = (cpu_unit.flags | cpu_tab[model].std) & ~cpu_tab[model].opt; -rf_bmax = RF_DFLT; -io_set_eimax (EIGRP_DFLT); -return SCPE_OK; -} - -/* Set memory size */ - -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 mc = 0; -uint32 i; - -if ((val <= 0) || (val > (int32)(cpu_tab[cpu_model].pamask + 1))) - return SCPE_ARG; -if (!desc) { /* force trunc? */ - for (i = val; i < MEMSIZE; i++) - mc = mc | M[i]; - if ((mc != 0) && (!get_yn ("Really truncate memory [N]?", FALSE))) - return SCPE_OK; - } -MEMSIZE = val; -for (i = MEMSIZE; i < MAXMEMSIZE; i++) - M[i] = 0; -return SCPE_OK; -} - -/* Set and clear options */ - -t_stat cpu_set_opt (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -if ((val & (cpu_tab[cpu_model].std | cpu_tab[cpu_model].opt)) == 0) - return SCPE_NOFNC; -cpu_unit.flags |= val; -return SCPE_OK; -} - -t_stat cpu_clr_opt (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -if (val & cpu_tab[cpu_model].std) - return SCPE_NOFNC; -cpu_unit.flags &= ~val; -return SCPE_OK; -} - -/* Set/show register blocks */ - -t_stat cpu_set_rblks (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 invmask, lnt, i, j; -t_stat r; - -if (QCPU_5X0) /* 5X0 fixed */ - return SCPE_NOFNC; -if (cptr == NULL) - return SCPE_ARG; -invmask = PSW2_GETRP (cpu_tab[cpu_model].psw2_mbz); -if (QCPU_S89) - invmask |= 0x10; -lnt = (int32) get_uint (cptr, 10, RF_NBLK, &r); -if ((r != SCPE_OK) || (lnt == 0) || (lnt & invmask)) - return SCPE_ARG; -cpu_reset (&cpu_dev); -rf_bmax = lnt; -for (i = rf_bmax; i < RF_NBLK; i++) { /* zero unused */ - for (j = 0; j < RF_NUM; j++) - rf[(i * RF_NUM) + j] = 0; - } -return SCPE_OK; -} - -t_stat cpu_show_rblks (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -fprintf (st, "register blocks=%d", rf_bmax); -return SCPE_OK; -} - -/* Set current register file pointers for SCP */ - -void set_rf_display (uint32 *rfbase) -{ -extern REG *find_reg (char *cptr, char **optr, DEVICE *dptr); -REG *rptr; -uint32 i; - -rptr = find_reg ("R0", NULL, &cpu_dev); -if (rptr == NULL) return; -for (i = 0; i < RF_NUM; i++, rptr++) - rptr->loc = (void *) (rfbase + i); -return; -} - -/* Front panael alarm */ - -t_stat cpu_set_alarm (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -cons_alarm_enb = val; -return SCPE_OK; -} - -t_stat cpu_show_alarm (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -fputs (cons_alarm_enb? "alarm enabled\n": "alarm disabled\n", st); -return SCPE_OK; -} - -t_stat cpu_svc (UNIT *uptr) -{ -if (cons_alarm && cons_alarm_enb) - sim_putchar ('\a'); -return SCPE_OK; -} - -/* Address converter and display */ - -/* Virtual address translation */ - -t_stat cpu_show_addr (FILE *of, UNIT *uptr, int32 val, void *desc) -{ -t_stat r; -char *cptr = (char *) desc; -uint32 ad, bpa, dlnt, virt; -static const char *lnt_str[] = { - "byte", - "halfword", - "word", - "doubleword", - }; -extern uint32 map_reloc (uint32 bva, uint32 acc, uint32 *bpa); - -if ((val < 0) || (val > DW)) - return SCPE_IERR; -virt = (sim_switches & SWMASK ('V'))? 1: 0; -if (cptr) { - ad = (uint32) get_uint (cptr, 16, virt? VAMASK: PAMASK22, &r); - if (r == SCPE_OK) { - if (sim_switches & SWMASK ('B')) - dlnt = 0; - else if (sim_switches & SWMASK ('H')) - dlnt = 1; - else if (sim_switches & SWMASK ('D')) - dlnt = 3; - else dlnt = 2; - bpa = ad << val; - if (virt && map_reloc (bpa, VNT, &bpa)) - fprintf (of, "Virtual address %-X: memory management error\n"); - else fprintf (of, "%s %s %-X: physical %s %-X\n", - ((virt)? "Virtual": "Physical"), lnt_str[val], ad, lnt_str[dlnt], bpa >> dlnt); - return SCPE_OK; - } - } -fprintf (of, "Invalid argument\n"); -return SCPE_OK; -} - -/* Record history */ - -void inst_hist (uint32 ir, uint32 pc, uint32 tp) -{ -uint32 rn = I_GETRN (ir); - -hst_p = (hst_p + 1); /* next entry */ -if (hst_p >= hst_lnt) - hst_p = 0; -hst[hst_p].typ_cc_pc = (CC << PSW1_V_CC) | pc | tp; -hst[hst_p].ir = ir; -hst[hst_p].rn = R[rn]; -hst[hst_p].rn1 = R[rn|1]; -return; -} - -/* Set history */ - -t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 i, lnt; -t_stat r; - -if (cptr == NULL) { - for (i = 0; i < hst_lnt; i++) - hst[i].typ_cc_pc = 0; - hst_p = 0; - return SCPE_OK; - } -lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r); -if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) - return SCPE_ARG; -hst_p = 0; -if (hst_lnt) { - free (hst); - hst_lnt = 0; - hst = NULL; - } -if (lnt) { - hst = (InstHistory *) calloc (lnt, sizeof (InstHistory)); - if (hst == NULL) - return SCPE_MEM; - hst_lnt = lnt; - } -return SCPE_OK; -} - -/* Print one instruction */ - -void cpu_fprint_one_inst (FILE *st, uint32 tcp, uint32 ir, uint32 rn, uint32 rn1, - uint32 ea, uint32 opnd, uint32 opnd1) -{ -t_value sim_val; -extern t_stat fprint_sym (FILE *ofile, t_addr addr, t_value *val, - UNIT *uptr, int32 sw); - -if (tcp & (H_INST|H_ITRP)) { /* instr or trap? */ - uint32 op = I_GETOP (ir); - uint32 cc = PSW1_GETCC (tcp); - uint32 pc = tcp & PAMASK20; - uint8 fl = anlz_tab[op]; - - fprintf (st, "%c %05X %X %08X %08X ", /* standard fields */ - ((tcp & H_INST)? ' ': 'T'), pc, cc, rn, rn1); - if (tcp & H_ABRT) /* aborted? */ - fputs ("aborted ", st); - else { - if (fl & CC4) /* immediate? */ - fprintf (st, "%05X ", ea); - else if ((fl >> 2) != DW) /* byte/half/word? */ - fprintf (st, "%05X %08X ", ea >> 2, opnd); - else fprintf (st, "%05X %08X %08X ", ea >> 2, opnd, opnd1); - } - sim_val = ir; - if ((fprint_sym (st, pc, &sim_val, NULL, SWMASK ('M'))) > 0) - fprintf (st, "(undefined) %08X", ir); - fputc ('\n', st); /* end line */ - } -return; -} - -/* Show history */ - -t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -int32 k, di, lnt; -t_stat r; -char *cptr = (char *) desc; -InstHistory *h; - -if (hst_lnt == 0) /* enabled? */ - return SCPE_NOFNC; -if (cptr) { - lnt = (int32) get_uint (cptr, 10, hst_lnt, &r); - if ((r != SCPE_OK) || (lnt == 0)) return SCPE_ARG; - } -else lnt = hst_lnt; -di = hst_p - lnt; /* work forward */ -if (di < 0) di = di + hst_lnt; -fprintf (st, " PC CC Rn Rn|1 EA operand operand1 IR\n\n"); -for (k = 0; k < lnt; k++) { /* print specified */ - h = &hst[(++di) % hst_lnt]; /* entry pointer */ - if (h->typ_cc_pc) /* instruction? */ - cpu_fprint_one_inst (st, h->typ_cc_pc, h->ir, h->rn, h->rn1, h->ea, h->op, h->op1); - } /* end for */ -return SCPE_OK; -} diff --git a/sigma/sigma_defs.h b/sigma/sigma_defs.h deleted file mode 100644 index 5c6951ee..00000000 --- a/sigma/sigma_defs.h +++ /dev/null @@ -1,478 +0,0 @@ -/* sigma_defs.h: XDS Sigma simulator definitions - - Copyright (c) 2007-2010, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - The author gratefullly acknowledges the help of George Plue, who provided - answers to many puzzling questions about how the Sigma series worked. - - 22-May-10 RMS Added check for 64b definitions -*/ - -#ifndef _SIGMA_DEFS_H_ -#define _SIGMA_DEFS_H_ 0 - -#include "sim_defs.h" /* simulator defns */ - -#if defined(USE_INT64) || defined(USE_ADDR64) -#error "Sigma 32b does not support 64b values!" -#endif - -/* Simulator stops */ - -#define STOP_INVIOC 1 /* invalid IO config */ -#define STOP_IBKPT 2 /* breakpoint */ -#define STOP_ASTOP 3 /* address stop */ -#define STOP_WAITNOINT 4 /* WAIT, no intr */ -#define STOP_INVPSD 5 /* invalid PSD */ -#define STOP_ROLLBACK 6 /* >= here, rollback PC */ -#define STOP_EXULIM 6 /* EXU loop */ -#define STOP_ILLEG 7 /* illegal instr */ -#define STOP_ILLTRP 8 /* illegal trap inst */ -#define STOP_ILLVEC 9 /* illegal vector */ -#define STOP_TRPT 10 /* trap inside int/trap */ -#define STOP_MAX 15 /* <= here for all stops */ - -/* Timers */ - -#define TMR_RTC 0 /* clocks */ - -/* Architectural constants */ - -#define PASIZE17 17 /* phys addr width, S5-8 */ -#define PASIZE20 20 /* phys addr width, 5X0 */ -#define PASIZE22 22 /* phys addr width, S9 */ -#define PAMASK17 ((1u << PASIZE17) - 1) -#define BPAMASK17 ((1u << (PASIZE17 + 2)) - 1) -#define PAMASK20 ((1u << PASIZE20) - 1) -#define BPAMASK20 ((1u << (PASIZE20 + 2)) - 1) -#define PAMASK22 ((1u << PASIZE22) - 1) -#define BPAMASK22 ((1u << (PASIZE22 + 2)) - 1) -#define MAXMEMSIZE (1u << PASIZE20) /* maximum memory */ -#define MEMSIZE (cpu_unit.capac) -#define MEM_IS_NXM(x) ((x) >= MEMSIZE) -#define BPA_IS_NXM(x) (((x) >> 2) >= MEMSIZE) -#define VASIZE 17 /* virtual addr width */ -#define VAMASK ((1u << VASIZE) - 1) /* virtual addr mask */ -#define BVAMASK ((1u << (VASIZE + 2)) - 1) /* byte virtual addr mask */ -#define RF_NUM 16 /* number of registers */ -#define RF_NBLK 32 /* max number reg blocks */ -#define RF_DFLT 4 /* default reg blocks */ - -/* CPU models, options, and variable data */ - -#define CPUF_STR (1u << (UNIT_V_UF + 0)) /* byte string */ -#define CPUF_DEC (1u << (UNIT_V_UF + 1)) /* decimal */ -#define CPUF_FP (1u << (UNIT_V_UF + 2)) /* floating point */ -#define CPUF_MAP (1u << (UNIT_V_UF + 3)) /* memory map */ -#define CPUF_WLK (1u << (UNIT_V_UF + 4)) /* write lock protect */ -#define CPUF_LAMS (1u << (UNIT_V_UF + 5)) /* LAS/LMS */ -#define CPUF_ALLOPT (CPUF_STR|CPUF_DEC|CPUF_FP|CPUF_MAP|CPUF_WLK|CPUF_LAMS) -#define CPUF_MSIZE (1u << (UNIT_V_UF + 6)) /* dummy for memory */ - -#define CPU_V_S5 0 -#define CPU_V_S6 1 -#define CPU_V_S7 2 -#define CPU_V_S8 3 /* not supported */ -#define CPU_V_S9 4 /* not supported */ -#define CPU_V_550 5 /* not supported */ -#define CPU_V_560 6 /* not supported */ -#define CPU_S5 (1u << CPU_V_S5) -#define CPU_S6 (1u << CPU_V_S6) -#define CPU_S7 (1u << CPU_V_S7) -#define CPU_S7B (1u << CPU_V_S7B) -#define CPU_S8 (1u << CPU_V_S8) -#define CPU_S9 (1u << CPU_V_S9) -#define CPU_550 (1u << CPU_V_550) -#define CPU_560 (1u << CPU_V_560) - -#define QCPU_S5 (cpu_model == CPU_V_S5) -#define QCPU_S9 (cpu_model == CPU_V_S9) -#define QCPU_5X0 ((1u << cpu_model) & (CPU_550|CPU_560)) -#define QCPU_S567 ((1u << cpu_model) & (CPU_S5|CPU_S6|CPU_S7)) -#define QCPU_S89 ((1u << cpu_model) & (CPU_S8|CPU_S9)) -#define QCPU_S89_5X0 ((1u << cpu_model) & (CPU_S8|CPU_S9|CPU_550|CPU_560)) -#define QCPU_BIGM ((1u << cpu_model) & (CPU_S9|CPU_550|CPU_560)) - -#define CPU_MUNIT_SIZE (1u << 15) /* mem unit size */ - -typedef struct { - uint32 psw1_mbz; /* PSW1 mbz */ - uint32 psw2_mbz; /* PSW2 mbz */ - uint32 mmc_cm_map1; /* MMC mode 1 cmask */ - uint32 pamask; /* physical addr mask */ - uint32 eigrp_max; /* max num ext int groups */ - uint32 chan_max; /* max num channels */ - uint32 iocc; /* IO instr CC bits */ - uint32 std; /* required options */ - uint32 opt; /* variable options */ - } cpu_var_t; - -/* Instruction format */ - -#define INST_V_IND 31 /* indirect */ -#define INST_IND (1u << INST_V_IND) -#define INST_V_OP 24 /* opcode */ -#define INST_M_OP 0x7F -#define INST_V_RN 20 /* register */ -#define INST_M_RN 0xF -#define INST_V_XR 17 /* index */ -#define INST_M_XR 0x7 -#define INST_V_ADDR 0 /* 17b addr */ -#define INST_M_ADDR 0x1FFFF -#define INST_V_LIT 0 /* 20b literal or addr */ -#define INST_M_LIT 0xFFFFF -#define TST_IND(x) ((x) & INST_IND) -#define I_GETOP(x) (((x) >> INST_V_OP) & INST_M_OP) -#define I_GETRN(x) (((x) >> INST_V_RN) & INST_M_RN) -#define I_GETXR(x) (((x) >> INST_V_XR) & INST_M_XR) -#define I_GETADDR(x) (((x) >> INST_V_ADDR) & INST_M_ADDR) -#define I_GETADDR20(x) (((x) >> INST_V_ADDR) & PAMASK20) -#define I_GETLIT(x) (((x) >> INST_V_LIT) & INST_M_LIT) -#define IRB(x) (1u << (31 - (x))) - -/* Shift instructions */ - -#define SHF_V_SOP 8 /* shift operation */ -#define SHF_M_SOP 0x7 -#define SHF_V_SC 0 /* shift count */ -#define SHF_M_SC 0x7F -#define SCSIGN 0x40 -#define SHF_GETSOP(x) (((x) >> SHF_V_SOP) & SHF_M_SOP) -#define SHF_GETSC(x) (((x) >> SHF_V_SC) & SHF_M_SC) - -/* String instructions */ - -#define S_V_MCNT 24 /* string mask/count */ -#define S_M_MCNT 0xFF -#define S_MCNT (S_M_MCNT << S_V_MCNT) -#define S_GETMCNT(x) (((x) >> S_V_MCNT) & S_M_MCNT) -#define S_ADDRINC (S_MCNT + 1) - -/* Data types */ - -#define WMASK 0xFFFFFFFF /* word */ -#define WSIGN 0x80000000 /* word sign */ -#define LITMASK (INST_M_LIT) /* literal */ -#define LITSIGN 0x80000 /* literal sign */ -#define HMASK 0xFFFF /* halfword mask */ -#define HSIGN 0x8000 /* halfword sign */ -#define BMASK 0xFF /* byte */ -#define BSIGN 0x80 /* byte sign */ -#define RNMASK (INST_M_RN) /* reg lit */ -#define RNSIGN 0x08 /* reg lit sign */ - -#define FP_V_SIGN 31 /* sign */ -#define FP_SIGN (1u << FP_V_SIGN) -#define FP_V_EXP 24 /* exponent */ -#define FP_M_EXP 0x7F -#define FP_BIAS 0x40 /* exponent bias */ -#define FP_V_FRHI 0 /* high fraction */ -#define FP_M_FRHI 0x00FFFFFF -#define FP_NORM 0x00F00000 -#define FP_M_FRLO 0xFFFFFFFF /* low fraction */ -#define FP_GETSIGN(x) (((x) >> FP_V_SIGN) & 1) -#define FP_GETEXP(x) (((x) >> FP_V_EXP) & FP_M_EXP) -#define FP_GETFRHI(x) (((x) >> FP_V_FRHI) & FP_M_FRHI) -#define FP_GETFRLO(x) ((x) & FP_M_FRLO) - -/* PSW1 fields */ - -#define PSW1_V_CC 28 /* cond codes */ -#define PSW1_M_CC 0xF -#define CC1 0x8 -#define CC2 0x4 -#define CC3 0x2 -#define CC4 0x1 -#define PSW1_V_FR 27 /* fp mode controls */ -#define PSW1_V_FS 26 -#define PSW1_V_FZ 25 -#define PSW1_V_FN 24 -#define PSW1_V_FPC 24 /* as a group */ -#define PSW1_M_FPC 0xF -#define PSW1_FPC (PSW1_M_FPC << PSW1_V_FPC) -#define PSW1_V_MS 23 /* master/slave */ -#define PSW1_V_MM 22 /* memory map */ -#define PSW1_V_DM 21 /* decimal trap */ -#define PSW1_V_AM 20 /* arithmetic trap */ -#define PSW1_V_AS 19 /* EBCDIC/ASCII, S9 */ -#define PSW1_V_XA 15 /* ext addr flag, S9 */ -#define PSW1_V_PC 0 /* PC */ -#define PSW1_M_PC (VAMASK) -#define PSW1_FR (1u << PSW1_V_FR) -#define PSW1_FS (1u << PSW1_V_FS) -#define PSW1_FZ (1u << PSW1_V_FZ) -#define PSW1_FN (1u << PSW1_V_FN) -#define PSW1_MS (1u << PSW1_V_MS) -#define PSW1_MM (1u << PSW1_V_MM) -#define PSW1_DM (1u << PSW1_V_DM) -#define PSW1_AM (1u << PSW1_V_AM) -#define PSW1_AS (1u << PSW1_V_AS) -#define PSW1_XA (1u << PSW1_V_XA) -#define PSW1_CCMASK (PSW1_M_CC << PSW1_V_CC) -#define PSW1_PCMASK (PSW1_M_PC << PSW1_V_PC) -#define PSW1_GETCC(x) (((x) >> PSW1_V_CC) & PSW1_M_CC) -#define PSW1_GETPC(x) (((x) >> PSW1_V_PC) & PSW1_M_PC) -#define PSW1_DFLT 0 - -/* PSW2 fields */ - -#define PSW2_V_WLK 28 /* write key */ -#define PSW2_M_WLK 0xF -#define PSW2_V_CI 26 /* counter int inhibit */ -#define PSW2_V_II 25 /* IO int inhibit */ -#define PSW2_V_EI 24 /* external int inhibit */ -#define PSW2_V_INH (PSW2_V_EI) /* inhibits as a group */ -#define PSW2_M_INH 0x7 -#define PSW2_V_MA9 23 /* mode altered, S9 */ -#define PSW2_V_EA 16 /* ext addr, S9 */ -#define PSW2_M_EA 0x3F -#define PSW2_EA (PSW2_M_EA << PSW2_V_EA) -#define PSW2_V_TSF 8 /* trapped status, S9 */ -#define PSW2_M_TSF 0xFF -#define PSW2_TSF (PSW2_M_TSF << PSW2_V_TSF) -#define PSW2_V_RP 4 /* register block ptr */ -#define PSW2_M_RP5B 0x1F -#define PSW2_M_RP4B 0xF -#define PSW2_RP ((QCPU_S567? PSW2_M_RP5B: PSW2_M_RP4B) << PSW2_V_RP) -#define PSW2_V_RA 3 /* reg altered, 9,5X0 */ -#define PSW2_V_MA5X0 2 /* mode altered, 5X0 */ -#define PSW2_CI (1u << PSW2_V_CI) -#define PSW2_II (1u << PSW2_V_II) -#define PSW2_EI (1u << PSW2_V_EI) -#define PSW2_ALLINH (PSW2_CI|PSW2_II|PSW2_EI) /* all inhibits */ -#define PSW2_MA9 (1u << PSW2_V_MA9) -#define PSW2_RA (1u << PSW2_V_RA) -#define PSW2_MA5X0 (1u << PSW2_V_MA5X0) -#define PSW2_WLKMASK (PSW2_M_WLK << PSW2_V_WLK) -#define PSW2_RPMASK (PSW2_M_RP << PSW2_V_RP) -#define PSW2_GETINH(x) (((x) >> PSW2_V_INH) & PSW2_M_INH); -#define PSW2_GETWLK(x) (((x) >> PSW2_V_WLK) & PSW2_M_WLK) -#define PSW2_GETRP(x) (((x) & PSW2_RP) >> PSW2_V_RP) -#define PSW2_DFLT 0 - -/* Stack pointers */ - -#define SP_V_TS 31 /* space trap enable */ -#define SP_TS (1u << SP_V_TS) -#define SP_V_SPC 16 /* space */ -#define SP_M_SPC 0x7FFF -#define SP_V_TW 15 /* words trap enable */ -#define SP_TW (1u << SP_V_TW) -#define SP_V_WDS 0 /* words */ -#define SP_M_WDS 0x7FFF -#define SP_GETSPC(x) (((x) >> SP_V_SPC) & SP_M_SPC) -#define SP_GETWDS(x) (((x) >> SP_V_WDS) & SP_M_WDS) - -/* System stack pointer (5X0 only) */ - -#define SSP_TOS 0 /* system stack */ -#define SSP_SWC 1 /* space/word count */ -#define SSP_DFLT_PSW1 2 /* default PSD */ -#define SSP_DFLT_PSW2 3 -#define SSP_FR_LNT 28 /* frame length */ -#define SSP_FR_RN 0 /* registers */ -#define SSP_FR_PSW1 24 /* PSD */ -#define SSP_FR_PSW2 25 -#define SSP_FR_PSW4 27 - -/* The Sigma series had word addressable memory, but byte addressable - data. Virtual addresses in the simulator are BYTE addresses, and - these definitions are in terms of a byte address (word << 2). */ - -#define VA_NUM_PAG (1 << (VASIZE - (BVA_V_PAG - 2))) -#define PA_NUM_PAG (1 << (PASIZE22 - (BVA_V_PAG - 2))) -#define BVA_V_OFF 0 /* offset */ -#define BVA_M_OFF 0x7FF -#define BVA_V_PAG 11 /* page */ -#define BVA_M_PAG 0xFF -#define BVA_GETOFF(x) (((x) >> BVA_V_OFF) & BVA_M_OFF) -#define BVA_GETPAG(x) (((x) >> BVA_V_PAG) & BVA_M_PAG) -#define BPA_V_PAG (BVA_V_PAG) /* phys page */ -#define BPA_M_PAG 0x1FFF -#define BPA_GETPAG(x) (((x) >> BPA_V_PAG) & BPA_M_PAG) - -/* Memory maps */ - -#define MMC_V_CNT 24 /* count */ -#define MMC_M_CNT 0xFF -#define MMC_CNT (MMC_M_CNT << MMC_V_CNT) -#define MMC_V_CS 9 /* start of page */ -/* /* map 1: 2b locks, per model */ -#define MMC_M_CS2 0xFC /* map 2: access controls */ -#define MMC_M_CS3 0x7FE /* map 3: 4b locks */ -#define MMC_M_CS4 0xFF /* map 4: 8b relocation */ -#define MMC_M_CS5 0xFF /* map 5: 13b relocation */ -#define MMC_GETCNT(x) (((x) >> MMC_V_CNT) & MMC_M_CNT) -#define MMC_L_CS1 (VA_NUM_PAG) /* map lengths */ -#define MMC_L_CS2 (VA_NUM_PAG) -#define MMC_L_CS3 (PA_NUM_PAG) -#define MMC_L_CS4 (VA_NUM_PAG) -#define MMC_L_CS5 (VA_NUM_PAG) - -/* Trap codes */ - -#define TR_V_FL 17 /* trap flag */ -#define TR_FL (1u << TR_V_FL) -#define TR_V_PDF 16 /* proc detected fault */ -#define TR_PDF (1u << TR_V_FL) -#define TR_V_CC 12 /* or'd to CC/addr offset */ -#define TR_M_CC 0xF -#define TR_V_VEC 0 /* trap address */ -#define TR_M_VEC 0xFFF -#define TR_GETVEC(x) (((x) >> TR_V_VEC) & TR_M_VEC) -#define TR_GETCC(x) (((x) >> TR_V_CC) & TR_M_CC) - -#define TR_NXI (TR_FL|0x8040) /* non-existent inst */ -#define TR_NXM (TR_FL|0x4040) /* non-existent memory */ -#define TR_PRV (TR_FL|0x2040) /* privileged inst */ -#define TR_MPR (TR_FL|0x1040) /* mem protect violation */ -#define TR_WLK (TR_FL|0x3040) /* write lock (5x0 only) */ -#define TR_UNI (TR_FL|0x0041) /* unimplemented inst */ -#define TR_PSH (TR_FL|0x0042) /* pushdown overflow */ -#define TR_FIX (TR_FL|0x0043) /* fixed point arith */ -#define TR_FLT (TR_FL|0x0044) /* floating point arith */ -#define TR_DEC (TR_FL|0x0045) /* decimal arithmetic */ -#define TR_WAT (TR_FL|0x0046) /* watchdog timer */ -#define TR_47 (TR_FL|0x0047) /* 5X0 - WD trap */ -#define TR_C1(x) (TR_FL|0x0048|((x) << TR_V_CC)) /* call instruction */ -#define TR_C2(x) (TR_FL|0x0049|((x) << TR_V_CC)) /* call instruction */ -#define TR_C3(x) (TR_FL|0x004A|((x) << TR_V_CC)) /* call instruction */ -#define TR_C4(x) (TR_FL|0x004B|((x) << TR_V_CC)) /* call instruction */ -#define TR_NESTED (TR_FL|TR_PDF|0xF04D) /* 9,5X0 - fault in inv/trap */ -#define TR_INVTRP (TR_FL|TR_PDF|0xC04D) /* 9,5X0 - inv int/trap inst */ -#define TR_INVRPT (TR_FL|TR_PDF|0x804D) /* 9 - inv new RP in trap */ -#define TR_INVSSP (TR_FL|TR_PDF|0x404D) /* 5X0 - inv SSP for PLS */ -#define TR_INVMMC (TR_FL|TR_PDF|0x204D) /* 9,5X0 - inv MMC config */ -#define TR_INVREG (TR_FL|0x104D) /* 9,5x0 - inv reg num */ -#define TR_INVRPN (TR_FL|TR_PDF|0x004D) /* 9 - inv new RP, non-trap */ - -/* Effective address and memory access routines interface - - The access types are defined to make the following equation work: - - trap if ((access_type != 0) && (access_control >= access_type)) - - The length codes are defined so that length in bytes = 1 << length_code */ - -#define PH 0x0 /* physical */ -#define VW 0x1 /* write */ -#define VI 0x2 /* instruction */ -#define VR 0x3 /* read */ -#define VNT 0x4 /* no traps */ - -#define BY 0x0 /* byte */ -#define HW 0x1 /* halfword */ -#define WD 0x2 /* word */ -#define DW 0x3 /* doubleword */ - -/* Interrupt groups - the Sigma's have flexibly configured interrupt groups - of various widths that map non-uniformly to control register bits */ - -typedef struct { - uint32 psw2_inh; /* PSW2 inhibit */ - uint32 nbits; /* number of bits */ - uint32 vecbase; /* vector base */ - uint32 rwgroup; /* RWdirect group */ - uint32 regbit; /* RWdirect reg bit */ - } int_grp_t; - -#define INTG_MAX 17 /* max # int groups */ -#define EIGRP_DFLT 1 /* dflt # ei groups */ -#define INTG_OVR 0 /* override group */ -#define INTG_CTR 1 /* counter group */ -#define INTG_IO 2 /* I/O group */ -#define INTGIO_IO 0x2 /* I/O interrupt */ -#define INTGIO_PANEL 0x1 /* panel interrupt */ -#define INTG_E2 3 /* ext group 2 */ -#define INTG_E3 4 /* ext group 3 */ - -#define INT_V_GRP 4 /* interrupt group */ -#define INT_M_GRP 0x1F -#define INT_V_BIT 0 /* interrupt bit */ -#define INT_M_BIT 0xF -#define INT_GETGRP(x) (((x) >> INT_V_GRP) & INT_M_GRP) -#define INT_GETBIT(x) (((x) >> INT_V_BIT) & INT_M_BIT) -#define INTV(x,y) (((x) << INT_V_GRP) | ((y) << INT_V_BIT)) -#define NO_INT (INTV (INTG_MAX, 0)) - -#define VEC_C1P 0x52 /* clock pulse vectors */ -#define VEC_C4P 0x55 -#define VEC_C1Z 0x58 /* clock zero vector */ - -/* Integer data operations and condition codes */ - -#define SEXT_RN_W(x) (((x) & RNSIGN)? ((x) | ~RNMASK): ((x) & RNMASK)) -#define SEXT_H_W(x) (((x) & HSIGN)? ((x) | ~HMASK): ((x) & HMASK)) -#define SEXT_LIT_W(x) (((x) & LITSIGN)? ((x) | ~LITMASK): ((x) & LITMASK)) -#define NEG_W(x) ((~(x) + 1) & WMASK) -#define NEG_D(x,y) do { y = NEG_W(y); x = (~(x) + ((y) == 0)) & WMASK; } while (0) -#define CC34_W(x) CC = (((x) & WSIGN)? \ - ((CC & ~CC3) | CC4): \ - (((x) != 0)? \ - ((CC & ~CC4) | CC3): \ - (CC & ~(CC3|CC4)))) -#define CC234_CMP(x,y) CC = (CC & CC1) | Cmp32 ((x), (y)) | \ - (((x) & (y))? CC2: 0) - -/* Instructions */ - -enum opcodes { - OP_00, OP_01, OP_LCFI, OP_03, OP_CAL1, OP_CAL2, OP_CAL3, OP_CAL4, - OP_PLW, OP_PSW, OP_PLM, OP_PSM, OP_PLS, OP_PSS, OP_LPSD, OP_XPSD, - OP_AD, OP_CD, OP_LD, OP_MSP, OP_14, OP_STD, OP_16, OP_17, - OP_SD, OP_CLM, OP_LCD, OP_LAD, OP_FSL, OP_FAL, OP_FDL, OP_FML, - OP_AI, OP_CI, OP_LI, OP_MI, OP_SF, OP_S, OP_LAS, OP_27, - OP_CVS, OP_CVA, OP_LM, OP_STM, OP_LRA, OP_LMS, OP_WAIT, OP_LRP, - OP_AW, OP_CW, OP_LW, OP_MTW, OP_LVAW, OP_STW, OP_DW, OP_MW, - OP_SW, OP_CLR, OP_LCW, OP_LAW, OP_FSS, OP_FAS, OP_FDS, OP_FMS, - OP_TTBS, OP_TBS, OP_42, OP_43, OP_ANLZ, OP_CS, OP_XW, OP_STS, - OP_EOR, OP_OR, OP_LS, OP_AND, OP_SIO, OP_TIO, OP_TDV, OP_HIO, - OP_AH, OP_CH, OP_LH, OP_MTH, OP_54, OP_STH, OP_DH, OP_MH, - OP_SH, OP_59, OP_LCH, OP_LAH, OP_5C, OP_5D, OP_5E, OP_5F, - OP_CBS, OP_MBS, OP_62, OP_EBS, OP_BDR, OP_BIR, OP_AWM, OP_EXU, - OP_BCR, OP_BCS, OP_BAL, OP_INT, OP_RD, OP_WD, OP_AIO, OP_MMC, - OP_LCF, OP_CB, OP_LB, OP_MTB, OP_STCF, OP_STB, OP_PACK, OP_UNPK, - OP_DS, OP_DA, OP_DD, OP_DM, OP_DSA, OP_DC, OP_DL, OP_DST - }; - -/* Function prototypes */ - -uint32 Ea (uint32 ir, uint32 *bva, uint32 acc, uint32 lnt); -uint32 ReadB (uint32 bva, uint32 *dat, uint32 acc); -uint32 ReadH (uint32 bva, uint32 *dat, uint32 acc); -uint32 ReadW (uint32 bva, uint32 *dat, uint32 acc); -uint32 ReadD (uint32 bva, uint32 *dat, uint32 *dat1, uint32 acc); -uint32 WriteB (uint32 bva, uint32 dat, uint32 acc); -uint32 WriteH (uint32 bva, uint32 dat, uint32 acc); -uint32 WriteW (uint32 bva, uint32 dat, uint32 acc); -uint32 WriteD (uint32 bva, uint32 dat, uint32 dat1, uint32 acc); -uint32 ReadMemVW (uint32 bva, uint32 *dat, uint32 acc); -uint32 WriteMemVW (uint32 bva, uint32 dat, uint32 acc); -uint32 ReadPB (uint32 ba, uint32 *dat); -uint32 WritePB (uint32 ba, uint32 dat); -uint32 ReadPW (uint32 pa, uint32 *dat); -uint32 WritePW (uint32 pa, uint32 dat); -uint32 ReadHist (uint32 bva, uint32 *dat, uint32 *dat1, uint32 acc, uint32 lnt); - -#endif \ No newline at end of file diff --git a/sigma/sigma_dk.c b/sigma/sigma_dk.c deleted file mode 100644 index e732465b..00000000 --- a/sigma/sigma_dk.c +++ /dev/null @@ -1,470 +0,0 @@ -/* sigma_dk.c: 7250/7251-7252 cartridge disk simulator - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - dk 7250/7251-7252 cartridge disk - - Transfers are always done a sector at a time. -*/ - -#include "sigma_io_defs.h" -#include - -#define UNIT_V_HWLK (UNIT_V_UF + 0) /* hwre write lock */ -#define UNIT_HWLK (1u << UNIT_V_HWLK) -#define UNIT_WPRT (UNIT_HWLK|UNIT_RO) /* write prot */ -#define UTRK u3 /* current track */ - -/* Constants */ - -#define DK_NUMDR 8 /* drives/ctlr */ -#define DK_WDSC 90 /* words/sector */ -#define DK_SCTK 16 /* sectors/track */ -#define DK_TKUN 408 /* tracks/unit */ -#define DK_WDUN (DK_WDSC*DK_SCTK*DK_TKUN) /* words/unit */ - -/* Address bytes */ - -#define DKA_V_TK 4 /* track offset */ -#define DKA_M_TK 0x1FF -#define DKA_V_SC 0 /* sector offset */ -#define DKA_M_SC 0xF -#define DKA_GETTK(x) (((x) >> DKA_V_TK) & DKA_M_TK) -#define DKA_GETSC(x) (((x) >> DKA_V_SC) & DKA_M_SC) - -/* Status byte 3 is current sector */ - -#define DKS_NBY 3 - -/* Device state */ - -#define DKS_INIT 0x101 -#define DKS_END 0x102 -#define DKS_WRITE 0x01 -#define DKS_READ 0x02 -#define DKS_SEEK 0x03 -#define DKS_SEEK2 0x103 -#define DKS_SENSE 0x04 -#define DKS_CHECK 0x05 -#define DKS_RDEES 0x12 -#define DKS_TEST 0x13 - -/* Device status */ - -#define DKV_OVR 0x80 /* overrun - NI */ -#define DKV_BADS 0x20 /* bad track */ -#define DKV_WPE 0x10 - -#define GET_PSC(x) ((int32) fmod (sim_gtime() / ((double) (x * DK_WDSC)), \ - ((double) DK_SCTK))) - -uint32 dk_cmd = 0; /* state */ -uint32 dk_flags = 0; /* status flags */ -uint32 dk_ad = 0; /* disk address */ -uint32 dk_time = 5; /* inter-word time */ -uint32 dk_stime = 20; /* inter-track time */ -uint32 dk_stopioe = 1; /* stop on I/O error */ - -extern uint32 chan_ctl_time; - -uint32 dk_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 dk_tio_status (uint32 un); -uint32 dk_tdv_status (uint32 un); -t_stat dk_chan_err (uint32 st); -t_stat dk_svc (UNIT *uptr); -t_stat dk_reset (DEVICE *dptr); -t_bool dk_inv_ad (uint32 *da); -t_bool dk_inc_ad (void); -t_bool dk_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st); - -/* DK data structures - - dk_dev DK device descriptor - dk_unit DK unit descriptor - dk_reg DK register list -*/ - -dib_t dk_dib = { DVA_DK, &dk_disp }; - -UNIT dk_unit[] = { - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) }, - { UDATA (&dk_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_BUFABLE+UNIT_MUSTBUF, DK_WDUN) } - }; - -REG dk_reg[] = { - { HRDATA (CMD, dk_cmd, 9) }, - { HRDATA (FLAGS, dk_flags, 8) }, - { HRDATA (ADDR, dk_ad, 8) }, - { DRDATA (TIME, dk_time, 24), PV_LEFT+REG_NZ }, - { DRDATA (STIME, dk_stime, 24), PV_LEFT+REG_NZ }, - { FLDATA (STOPIOE, dk_stopioe, 0) }, - { HRDATA (DEVNO, dk_dib.dva, 12), REG_HRO }, - { NULL } - }; - -MTAB dk_mod[] = { - { UNIT_HWLK, 0, "write enabled", "WRITEENABLED", NULL }, - { UNIT_HWLK, UNIT_HWLK, "write locked", "LOCKED", NULL }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE dk_dev = { - "DK", dk_unit, dk_reg, dk_mod, - DK_NUMDR, 16, 22, 1, 16, 32, - NULL, NULL, &dk_reset, - NULL, NULL, NULL, - &dk_dib, DEV_DISABLE - }; - -/* DK: IO dispatch routine */ - -uint32 dk_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -uint32 i; -uint32 un = DVA_GETUNIT (dva); -UNIT *uptr; - -if ((un >= DK_NUMDR) || /* inv unit num? */ - (dk_unit[un].flags & UNIT_DIS)) /* disabled unit? */ - return DVT_NODEV; -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = dk_tio_status (un); /* get status */ - if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ - dk_cmd = DKS_INIT; /* start dev thread */ - sim_activate (&dk_unit[un], chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = dk_tio_status (un); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = dk_tdv_status (un); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - chan_clr_chi (dk_dib.dva); /* clr int */ - *dvst = dk_tio_status (un); /* get status */ - if ((*dvst & DVS_CST) != 0) { /* ctrl busy? */ - for (i = 0; i < DK_NUMDR; i++) { /* find busy unit */ - uptr = &dk_unit[i]; - if (sim_is_active (uptr)) { /* active? */ - sim_cancel (uptr); /* stop */ - chan_uen (dk_dib.dva); /* uend */ - } /* end if active */ - } /* end for */ - } - break; - - case OP_AIO: /* acknowledge int */ - chan_clr_chi (dk_dib.dva); /* clr int */ - *dvst = dk_tdv_status (un); /* status like TDV */ - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Unit service */ - -t_stat dk_svc (UNIT *uptr) -{ -uint32 i, sc, da, wd, wd1, cmd, c[3]; -uint32 *fbuf = (uint32 *) uptr->filebuf; -int32 t, dc; -uint32 st; - -switch (dk_cmd) { - - case DKS_INIT: /* init state */ - st = chan_get_cmd (dk_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return dk_chan_err (st); - if ((cmd == 0) || /* invalid cmd? */ - ((cmd > DKS_CHECK) && (cmd != DKS_RDEES) && (cmd != DKS_TEST))) { - chan_uen (dk_dib.dva); /* uend */ - return SCPE_OK; - } - dk_flags = 0; /* clear status */ - dk_cmd = cmd & 0x17; /* next state */ - if ((cmd == DKS_SEEK) || /* fast cmd? */ - (cmd == DKS_SENSE) || - (cmd == DKS_TEST)) - sim_activate (uptr, chan_ctl_time); /* schedule soon */ - else { /* data transfer */ - sc = DKA_GETSC (dk_ad); /* new sector */ - t = sc - GET_PSC (dk_time); /* delta to new */ - if (t < 0) /* wrap around? */ - t = t + DK_SCTK; - sim_activate (uptr, t * dk_time * DK_WDSC); /* schedule op */ - } - return SCPE_OK; - - case DKS_END: /* end state */ - st = chan_end (dk_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return dk_chan_err (st); - if (st == CHS_CCH) { /* command chain? */ - dk_cmd = DKS_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - return SCPE_OK; /* done */ - - case DKS_SEEK: /* seek */ - c[0] = c[1] = 0; - for (i = 0, st = 0; (i < 2) && (st != CHS_ZBC); i++) { - st = chan_RdMemB (dk_dib.dva, &c[i]); /* get byte */ - if (CHS_IFERR (st)) /* channel error? */ - return dk_chan_err (st); - } - dk_ad = ((c[0] & 0x7F) << 8) | c[1]; /* new address */ - if (((i != 2) || (st != CHS_ZBC)) && /* length error? */ - chan_set_chf (dk_dib.dva, CHF_LNTE)) /* care? */ - return SCPE_OK; - dc = DKA_GETTK (dk_ad); /* desired track */ - t = abs (uptr->UTRK - dc); /* get track diff */ - if (t == 0) - t = 1; - sim_activate (uptr, t * dk_stime); - uptr->UTRK = dc; /* put on track */ - dk_cmd = DKS_SEEK2; - return SCPE_OK; - - case DKS_SEEK2: /* seek complete */ - if (uptr->UTRK >= DK_TKUN) { - dk_flags |= DKV_BADS; - chan_uen (dk_dib.dva); - return SCPE_OK; - } - break; /* seek done */ - - case DKS_SENSE: /* sense */ - c[0] = ((dk_ad >> 8) & 0x7F) | ((uptr->flags & UNIT_RO)? 0x80: 0); - c[1] = dk_ad & 0xFF; /* address */ - c[2] = GET_PSC (dk_time); /* curr sector */ - for (i = 0, st = 0; (i < DKS_NBY) && (st != CHS_ZBC); i++) { - st = chan_WrMemB (dk_dib.dva, c[i]); /* store char */ - if (CHS_IFERR (st)) /* channel error? */ - return dk_chan_err (st); - } - if (((i != DKS_NBY) || (st != CHS_ZBC)) && - chan_set_chf (dk_dib.dva, CHF_LNTE)) /* length error? */ - return SCPE_OK; - break; - - case DKS_WRITE: /* write */ - if (uptr->flags & UNIT_RO) { /* write locked? */ - dk_flags |= DKV_WPE; /* set status */ - chan_uen (dk_dib.dva); /* uend */ - return SCPE_OK; - } - if (dk_inv_ad (&da)) { /* invalid addr? */ - chan_uen (dk_dib.dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; i < DK_WDSC; da++, i++) { /* sector loop */ - if (st != CHS_ZBC) { /* chan not done? */ - st = chan_RdMemW (dk_dib.dva, &wd); /* read word */ - if (CHS_IFERR (st)) { /* channel error? */ - dk_inc_ad (); /* da increments */ - return dk_chan_err (st); - } - } - else wd = 0; - fbuf[da] = wd; /* store in buffer */ - if (da >= uptr->hwmark) /* update length */ - uptr->hwmark = da + 1; - } - if (dk_end_sec (uptr, i, DK_WDSC, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - -/* Must be done by bytes to get precise miscompare */ - - case DKS_CHECK: /* write check */ - if (dk_inv_ad (&da)) { /* invalid addr? */ - chan_uen (dk_dib.dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; (i < (DK_WDSC * 4)) && (st != CHS_ZBC); ) { - st = chan_RdMemB (dk_dib.dva, &wd); /* read byte */ - if (CHS_IFERR (st)) { /* channel error? */ - dk_inc_ad (); /* da increments */ - return dk_chan_err (st); - } - wd1 = (fbuf[da] >> (24 - ((i % 4) * 8))) & 0xFF; /* byte */ - if (wd != wd1) { /* check error? */ - dk_inc_ad (); /* da increments */ - chan_set_chf (dk_dib.dva, CHF_XMDE); /* set xmt err flag */ - chan_uen (dk_dib.dva); /* force uend */ - return SCPE_OK; - } - da = da + ((++i % 4) == 0); /* every 4th byte */ - } - if (dk_end_sec (uptr, i, DK_WDSC * 4, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - - case DKS_READ: /* read */ - if (dk_inv_ad (&da)) { /* invalid addr? */ - chan_uen (dk_dib.dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; (i < DK_WDSC) && (st != CHS_ZBC); da++, i++) { - st = chan_WrMemW (dk_dib.dva, fbuf[da]); /* store in mem */ - if (CHS_IFERR (st)) { /* channel error? */ - dk_inc_ad (); /* da increments */ - return dk_chan_err (st); - } - } - if (dk_end_sec (uptr, i, DK_WDSC, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - } - -dk_cmd = DKS_END; /* op done, next state */ -sim_activate (uptr, chan_ctl_time); -return SCPE_OK; -} - -/* Common read/write sector end routine - - case 1 - more to transfer, not end disk - reschedule, return TRUE - case 2 - more to transfer, end disk - uend, return TRUE - case 3 - transfer done, length error - uend, return TRUE - case 4 - transfer done, no length error - return FALSE (sched end state) -*/ - -t_bool dk_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st) -{ -if (st != CHS_ZBC) { /* end record? */ - if (dk_inc_ad ()) /* inc addr, ovf? */ - chan_uen (dk_dib.dva); /* uend */ - else sim_activate (uptr, dk_time * 16); /* no, next sector */ - return TRUE; - } -dk_inc_ad (); /* just incr addr */ -if ((lnt != exp) && /* length error? */ - chan_set_chf (dk_dib.dva, CHF_LNTE)) /* do we care? */ - return TRUE; -return FALSE; /* cmd done */ -} - -/* DK status routine */ - -uint32 dk_tio_status (uint32 un) -{ -uint32 i; - -for (i = 0; i < DK_NUMDR; i++) { /* loop thru units */ - if (sim_is_active (&dk_unit[i])) /* active? */ - return (DVS_AUTO | DVS_CBUSY | (CC2 << DVT_V_CC) | - ((i == un)? DVS_DBUSY: 0)); - } -return DVS_AUTO; -} - -uint32 dk_tdv_status (uint32 un) -{ -return dk_flags | (dk_inv_ad (NULL)? DKV_BADS: 0); -} - -/* Validate disk address */ - -t_bool dk_inv_ad (uint32 *da) -{ -uint32 tk = DKA_GETTK (dk_ad); -uint32 sc = DKA_GETSC (dk_ad); - -if (tk >= DK_TKUN) /* badtrk? */ - return TRUE; -if (da) /* return word addr */ - *da = ((tk * DK_SCTK) + sc) * DK_WDSC; -return FALSE; -} - -/* Increment disk address */ - -t_bool dk_inc_ad (void) -{ -uint32 tk = DKA_GETTK (dk_ad); -uint32 sc = DKA_GETSC (dk_ad); - -sc = sc + 1; /* sector++ */ -if (sc >= DK_SCTK) { /* overflow? */ - sc = 0; /* wrap sector */ - tk = tk + 1; /* track++ */ - } -dk_ad = ((tk << DKA_V_TK) | /* rebuild dk_ad */ - (sc << DKA_V_SC)); -if (tk >= DK_TKUN) /* invalid addr? */ - return TRUE; -return FALSE; -} - -/* Channel error */ - -t_stat dk_chan_err (uint32 st) -{ -chan_uen (dk_dib.dva); /* uend */ -if (st < CHS_ERR) - return st; -return SCPE_OK; -} - -/* Reset routine */ - -t_stat dk_reset (DEVICE *dptr) -{ -uint32 i; - -for (i = 0; i < DK_NUMDR; i++) { - sim_cancel (&dk_unit[i]); /* stop dev thread */ - dk_unit[i].UTRK = 0; - } -dk_cmd = 0; -dk_flags = 0; -dk_ad = 0; -chan_reset_dev (dk_dib.dva); /* clr int, active */ -return SCPE_OK; -} diff --git a/sigma/sigma_doc.doc b/sigma/sigma_doc.doc deleted file mode 100644 index 0cfb805c4d2bd5fe73bd0967e8f8b2610a545fd7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 90624 zcmeI531C#!*|2XGmH`K$Aj+cNqQ#&gWU>%YP_jV+*~}uK2uzYmGLp>1nFNS_w%Fp* z)&+6jT5YY?T9wjPt6j9#+Qqf*)-Kvl|5_Er6|GhN=RN1%nLCr25JZgqoY9Awd+*to z_q^vl=iEH<@VMu${n6y-jkwRzMuzdxPM0y*zWYaYH|8H#=0s!K zJ%(}7HJYO4n8*DtcJACaaxd9$+d-%LVGh&R^6mUBcN1Mt(9YGr1(x4U^YqO`-#t9a zoNpMv;M;cp%JGJA3eEZf?jJ{!pSFO9e5Ngse-nS-hx?a`4PztEJ4+0sjPH{O2k%BF z-|`vE_o2A+tsrlBJYyy4;Cd7O_mcqPK6d`M5MQFtv<3RE{cXFmza?DxtgqAGc6j#p zv<3RU{jYufJ^W4NrtL5OTf+ZGMznrxfAQf;`8YpzIL>>6`EBRN4o|{4j@E03_fVr@ z97#aKi7%UPJ014-VB$#R#*S~=0{!%E+RHxt+_I(fR%6*8(xg4DD5CzX_P2SVVca*u zF!D&pDD6f4Ylri5?&oqx+Mj&p@two>PTGNdmeuHXVPD(+?0nko*Z#Kim+U*;ct%1k zYcL!9?Ok3oKd+fzUA>*&o?ysq3VYjq?p)8zGGEKg+&ONyyR^1$d41)gibk`hwz0Cb z-0g1c@R@DF&d%UEf1urL33m5|{Ouh*W+2$(Z}FMl?(R;%FKqS%%^qAfR907*;b3p5 z#g}b1`vcxkU$*HDw3@BKmfkL3pvT+e4+f5OyK4!B$DM@O>NC50n>+pC4qvP3515|0 zbMt5B<>t=GHrIvxJw3jF+1zK=2b+DN9<$nP=p*SJd~DamS?;q(*l&|T*Xb@{_# z;x+wYv%?qi5nOx78|d-1W}9sxpU(`onJpdOP&&8dkHT#pJtoCld{Q@l9|?E`It6CMbhdc^W;{QnjP3W ze@{oSx5o_m!aX5>iayf1*RL5+_JMn?s}WUJyg7(vhNOtRDAK-%pv}Yayv&?d+`#p;Y;$R4V?}LKqlt_9;+n?gX6-_=xMsPzq_UXk)D@5n4f2mg8@sSzTUVT0zLg zC6!f`jmxvmg_Vsp66QhzEjH_l>*=0NRmJsYT~mEsZ9_THml14DWzE8RVkxgKuW8IN ziI$sY`EgvC4Hd;zRc3u{NqK#vbfl)bn#v_+NjWJgE~zTlL6eEns^ZG(Y_qJmx_FVK zrrxY2f%VFnm71j$rm>#OY;r{;w%4VV4dvNpaeZZj6u`pz zT7sA2!-ten4RWWZrd)?2MXL%VQUf@V0%{_Yc7SGCd2tnCQ5`kvVWhsOzVh`gzV04+ zB{h%4@dtEMP|ZfS6?z~|Ea2@@T|Z7@n7Se1QW_IoN=YSe>ssWGKP>%_ei9^r&^mwE zCr!CK6zmH2@RLBp-cEWGz9Ozn>FRh3>+Vj^uzOUbLwAS#glS7VZ!c0HbS9F*wPBABpH!GIcmDf`^OUxCW=CoCf!InHv;hfyr z`MG)1%(Mv}S9AbaDDufQp60ZuyuN&)8RJ+&Oq-Cu-+siDJWOIvn~>*<9by*xygj`L zu_Qs~4=(5e6?BfrRm#8-qRZBWf-OE|ZOF_jt!tW*B=iCudciIdUZ_LQb5;Agf}uXM z+S_erRTtMK3${=PTeyp0XX{||U6qV4p-?Xkv7s;A*?$EnOTiV zGcZR-P_&B-%+(RhCW6_yW}O!)ZZ`6-S?}|<@;j?8X$*69408sK!IP_FC~_4Q6y!=D zEGj6>HLDN;G#|gziJ4WEtdc#sgNwwYBbnnO*_|^R{m7Bh&S1+LGpoL_G)WzJJUZ;T zyU2j*q69Ssh#}Qm=w4GRyqoHPSG8Lg<9(NM=@9T`^-tT}iU&t>_%*w|j`58Y}gN&{JC5eeqEe4npo=-3;#SJZPHxFmIT;Z1PoDMhN{;pMw$s$!E*R8&`aO9%RAB_AC z`PN2$qhGIyT=XC?q8D_&Q1q&6y>&s1Epaj0*Aj{STLo-isDL9ED&WYK1l*$Y6K)O9 zA}h?NRyh(cm;PYvmp*yseH$p&nt!scxcyJdhD}EOOS~c_1xxfM+=boku`-B<-XOoRwj<3 zd}W1aNRyD+s4vXqv#!bIa%d8T+2-tQvnbnSCWs)PtNxW33y}}pD4d<^R>NOTjvD-2 zm9uJP9;Ze|bg*vG&E~l48VOa6H{EKyky>VkCF9Mk?%qI4hr3a`KnPfkGcx44tLntF zb0|TTW5TM35;x+W=LFU{vqwgO78wQH2xIQbj8e;QlsPTGTVmz6Oh=Ubc9$)YXhiO{ zMC2YbwKZzSqD8z+{_H%Nts(zfiVWGS{2{If<+=pdTBav=?kTiGN9L)}6H3T7B_TUx zOpvhL)v65h^Ol)&XQHej)w*n{rV2b!^4-nwt7v&EDRoJ%#6v^nqUz#8sv_*`Q8!e8(zvxzr!dax?Bq^o z$2l!Z?zAY*=^TgCYROSF0dwM<&UHAAOY7XIQ+hG(`e%y!4o9<-IHK=I3TUBpQkQNl zW?N?v^$2~XJBYf6`J~PCuJ!smr6onZ)YK|ZR%1)#N!O;gGwP?TytJ~qxGEY|tFOi1 z<)vzq#S!&kN96R9)!jGE-xGA3e4^d0w;+JM=go{j;*P9^*z;ZK()0t7c?=>oY|{(k+t}nZutQ zSG>Rek=2(}Eoqn^AS&r1f!;1`g<{tU`Pwme@w-{Y8qL0p7YW?kgGbb1ex77N1#4wl zb=LVIYssaes?n)dW9s%6wnrmGvq)vTZHZY& z476I_uf;-ypfNEs($*~tYIKM|6Iv%0R=%Y?rQn!IIl_|iktb@Vs;mcELy+-6R3@oM zMhmnHMlD7l)FxM*=pY_MIq_iE?jqP;ndrJ*^|?7Y^&W^*FU_dtoW>(>PbT=)$N+sQRpcJ(2mxQ;X z)wt?KHj!#OiMsoWZJL2RNWL0Ka83^Y;+vF*#e{8!(GprZ#D87cLIU7HG&gPD-p(Fs z-P`VV6=OD)9)SZ}-}82QLtXNuyhe1S_$OA?6LP5)vhC5TLD5%eQr&J>`LZSqyDk^Q zr83j279YT#j|-k{CV35wwRNj1s~AX#2RZ1$F5VODrdZ7005b~9U>Onl6iE3ZDG}zY zabq zR@mG}BhJFE-X_g}^%(UpO|&)0(t%GdXGB8ro!skRi}f?mBkkThIM05WjoLxvn6*lU z!f4ORh3*E9$F_!ujNoA?*xTM=%Z8ATuByZUGYnTlMeS1a)R|J-;nS4HbZSX)c13aa z(&Fs0;?w3^`F6XxYjPXgyO_I8Q50D;A#g8C6si|GqesB#TxFXB7KxpmINj4U8wpY+ zN>oir=*+d$SWFSf%xSGZ)YB`9$INCPvmPXg;J&I2JMFHS9Wf8>6xosEdtHnJ)sgKQ z&!U-0k3fZ(*&5?4TCa@f~Ztjt0 zw|z?`y8uT@_m(y&n!f0|GH6hwSQ+TmeYUjhl1V|x$GTKcXCLwUT3Dr zZGu8^bU>E%q|$7)xuTMeR=-?N5Tr#&)b>qV=~wx&^la-H#nIB~^M)enYVK`o6KNV3 z@O;rsZ5_qRLw`r2lvw(Y3?K(azfZA&M)2 zgu+}#x2Ee!XtqyP=3U1u>;VToMOIx@Yf|gxb5vrm zK-ij)ZHAC*><~KcNEB*xXGn^KC(SI`@LgYCbwciug&xm|3t|3|TD64ddAS8e1jDfCP?~9E^|>eH=kY*>_{3Q@Wj{CtAQ5>>*F6F;I+r-?{`p$E>_*8$x=-WaP%_W z#3Dl*wJp*#a&7syhX~*LZfXXp!GNaiKzVru4%aGr!l1!8Qb~OeuF_nU6_u=Vx?Ie3 zJJ=4v@J_2%>QyvFDh{_etuH?|#wj9QmZ8;}e$;)40hEC7fqUxGQz#9B$$UR2RCgtc zN@6#*%|s0}I7HV;>=2DdX)O$rRQ=pl4K*?+loq0EajqE-c)P*Q1R% z-F2~bLeziTnS@ukEO!+dSw!6Vv}|$CEnNk&?<3;Y%<2uuBI^v@f}-<T{s^dwI=47>eUb3sI0Fu=O3^k`cea<7e@DyXE(a%V_GVSzZ* z(>GIOT9!4Fn4v=>eN0;zwPb?Gl7s{konn{Wh?RhLWg9~WqTx%iu{9{x!fQ=G!fxw_$xeI-yO-K zPF9}UGJ`daDhdQq0j#RlPdzi@-RHY~Sh3xu$reQ^D98RMEoo5U!j@?8sSQoB#$z;O ze|td9ZqW@(vdvO7M0R$t5hL4Nq{o2@rG~Io#oGQOJB*rrJ?nhzSn^tCO_g1wpH7-& z$kMOrdbYkIW4ktLidn*L9LlHCWG#c|amDtdh!R$ffePN0 zgX4T#`%2W1oykvNXjP_?c@n|VcKk?b*+ykrcga*VhYYsVmM)+Kp^>Wj^CVUM1Jid^ zV4c2pdbYJvVCBK?ELNW9my%U_mCot>f@sDi!PzSJcBzy&3Zg)Z8B70-R1AeceXAL@ znz2cTii#pjT`yCXYJ2hB4?N4T~&9|NPJe;i(D(? zy@;niM45_G6yiS9qiWMi$_cqAW-C3n&pg3%qVow;a1kLUTdVA>MISy#X?2lY1^|kW{9(ePG?q4 zSdaDm((NiKw%z10q&R1eW|mwLT}ezDl@pb&m>5L=uv1_u$(CYKT2X07A*r>J5glP7 z&KeRWH`=$fyW|^AbW3Cy>%SL;atwq~4fR$@nxcGM9huKtD0xCEGQ3k zv#TIhByVJjXZxM(|3{eZI33xQ%PWG;_f7^Jht%Ib20lPXlpi)vOP z0~Oja7EqaC$p{=NbYw_zO}VU4=ql0CQcPGUW!4uz?yA|L@)A|CEXl|eCMe}A_Q{!b zXv(tjRc(jEO2lTMSOcaGIFeD!`^sV=t7*QLj-apgC=!Vc%qzxZJJ|T-NQG(Zq*{4X ziLq788FRD_XP1}^q-s#pvmgRf61!M* zHA^0Pa@+&#!_tX#teIP_fo(rAlcs+Cj!j%B)K>3v_>b*?xbn=fTBQ`JS|zr7qO~IcmeIrA zUUp0HoDHbn06(L7mAfi^3`LFP$5GTts%o(FTQwHZl$qW}h9Ny=kvL@>U@5icc(v}J z8@yWeaW+_VVD`$A-r~l_;?fE+>PJLlcQB0j5}SX! z&sZQHwROD~xrr^swyQflV!Mzf1SxKED3UrpIjT%e%kHX^QrP_ysX&RQh?-lB0jJzP#3h5 zdbRIG$IBEb&?-BVrLWSh^lp6FqvKNPa+%i0QKr_4it2~B69Mn-=|NdTswvx*OxdmA zWu_;YMR2-Y7)vQpCAI0)5(Q6@V^Y4VszSa&d!=7T3eUA(EM|$ky6a?f&u(VbQDL84 zRtK5hcuDT)&vp;lwM;KWraQMQ_1pQXWrcGWlWd4>oT0X#BW-2rR%9VFSX<00xyAlj z@)41)daYzP1nWRDa5qGs8d=%#mmnJ-Ph~^v-j$>)X%ZFIqx5-}Syc(yivo4U4I)Qq z`;jrfn{n67(zT#hIxA}`v>Sh*!{3ZmHagd%ewVHqPUlSs*!cB}Um#j1ur?8l-_ATsTKpnn(U+7^VWI`xRM(R(6LznIkq z)lF?wP%fg|lXN`F1$&c}w6^UB`VsQej)aEE95PXja93?`W9NZbrla#>tQbT{b=mUW zkx=f=pC>Z%Xi_UaBVori3|X(x4s`-$F@{x4Y7u=qadI4!CuNk!K5t6-%1Vlwf2+cl z_NO*?ka~OP4Pv01U2LS6d8|yS+4pFjlj%lV3s4x?581C7SfR6x_*-dmL(K#eFrLm5>da<{otJ%gjy;;4;5>wGbWuiEW#X_5t`jvtu z!mQo&Qt0!VJH3H5st}~Su|29G+wICKoWV6FY+XRQ^6ba5<-n6&m@S*>=#46^EU9Ii zY+x;#ql56Z5{M^v2I>YM&KanJ*5O!1kQa4{G~r|2_eAc;v^=R`8Mr+vD6Fu7cH8p7 zBt{BP6|BmDY-Dtoi{dlrF+bWFKY?*jjbxPX#~cV_I=#|W#8^jL5^g5Se$S8G2t>Oe)lu2E0 z3=%mXY-^)AeG#0Lv-80ml0taZrH+wcy2Z zRi(?R$b8C3CYzM(Bv~o*ww^>6QA(Oqs}p-EJC@B;OFh}8dD*4;r_Gn}v=~%dmrc*C zyjl5DuJ-uOz7{)5OR(6NlHL9(h*%0^^hsruj)^+EwBR%%?qKo25%a79XLO}{|CL7- z6RUuFnk%VO<*EFI&3yH^KyFh~)s&@9s6;2_p;m-dL?WZrQ2!bl_2+Rw_8O#}1TEf3rxhqttMq^QDY4?2A!Kwp}l*z0en1gX@?j z$-++Hu8&Mshf z(1$J^3I>8~2~#<0V_J%YSEHB=g0kyO8H=oj8rj>f7FuLY&3Z1UhK@AZBCqEDs!FIO z_N3|Fz=NvD6F+OD>{gOuum`3_>W~En*7vw+4_oUQ@v$L@NVIHhs!dqxh`m>cb8H;5 zq1R&;VeFFx1=yyb<%n0#Y=&k=o4rgati0$cEbi5+U8HO1L0?ThXnWRKQE4%jd&%QG zc`Rdz2n&jnW9}FNL?p-qw_7iys4zsZ(Z z>f*|1N~e+9nGv0sDsdTUTe3q#b|pxXq)AZCO{HR*16I&P*3Bs)ExT!;lXXU#tsD;& z)miP$VN zX^|PU*?^=)MTof>c^;5M6SZP;l144P$udl+mZt=beNs)HGP+7X)ZM@-NOTvCtR0Am zP~t*t?J|I9IrPH5{UgdrhlI<%EoNtlq9fb%4st*?Fw_^ceH6lbD}ofS&no=h*pO*F>C0@g>^ucBi)>gb&hG|b8wq{mwxV_HZICGYi%Fs=XzPJYliwjSYD=)#Cbz$aSi=k7U8Vo z4eP;DrGgYzsRI_w7b5r324yr*h6QcgV9p^@Le^{TAuM9WRZ|L`BPl6_`^U4Q$YkFx zE45r@XH3+Vm{Q2M)|L|v;;lh?kqm5>h~jk$l%@22EWB(I_0e03QQTD5a5NURMj)pH zWM_iaPa~Z@+`)b;t!$BROE|RpwAGRTy6#2$Te8udNZ=Qva=qiMCCk0n27ZmBgrLwW1)hgYD*W#9tlsjy|@8Qe-7U zZ@pLY#tJo7y=P)kR(EP~cFAcfBATqEfh`AS7DXWxK zBuMH+1fPV)K@J_h7USZ_5&`k~jf{C(r`6jDl!a5DrL;;=UD&fJs~qjsM&gXx7F02a zOvFa+s#Yc>v6h$i(V0+H!j|dWRENl;S7w7c!oaZ&@mG{rkQZ?{JMv5a$jgnr!QM{G zQ;{d~WLKUFNq}b&)gVaWb}faWc*cnzf#+z$3@3lD^Og@)PhYH&Msr0!IhqAozk`BNtv9swdGf|2};;; z>svZAvF>9>CPoCk(2I^JlPWBW90FNKO!bimVRr7TbINL(DmL?i6V*_G{gU@0FzG>y zL+w%7k(o)dJ=zPaiWiBQU##uX4Ct*ZuCmI7>Qs=7(pLAUAIX^kS#(3-Evdw-?4-eT z(@T_LpKpzxMawp7tcQ)|4eb3=PMC*rI1qVa@8l^iE34Nj*Q=GbBA|MzwO@p3~Y#1Bh9bT+fC$rP(X(LyShsJ>!oocjNkF*fXsGERj-C zDvPkz)(l2A(Rvs;)l4RV3c?BYsB2L{cKOm2OF+cFV8GFw<;5z|PN~PqIabTcG0T=% z=6taeL=QZAoBf@BY@Z02E-w}at0C$ZVDCjo5=5JXFS75sY>CVHeN&fG(U|3Y zQQV@ZojKjlw6pvK&a5QpnBx+ja8y^uK~W%B4A)YD(-ebJ7IqoOz+Lzg>Z)>XI&oj+ ztkpmR-EMT{Az745&>yARm6X{l9kO4KjBh@J=!dz|4|nz2EZuNoUp(XJ?vY;ToCB&B ziq^zkTSR(<+`$+WR6U)E&mIc0e?UDs=ZiG-S0NRI3s zq?XyR2lXoHMmc3w(5be}39)exEPs+sA}rINEaIFfih!+ATVo$P^6MH!N03)J=;2Vm z!$!^?msHiL8A9}t-ll{7aVf{g@I`>u^djWrUClC(Vq&u=7z1b*(e)cUL8$n=i#4+K z+%_KCn=I8*q(rRUh`G;-QqKdL8f1HtoI@o|TBWmXrMC^ea^-E)!@y&Q~s2xoC+= zo)}R%ff}F2#9l=h+lh3%48iOQaA2R8f+q6iu2g%fG5n}i*?u)70#m<1z##>&>L@jw zal+n&MeFTXiHFEQA~hM8@kF(^S=?Si-s7{H$g!&G4qiB6FNP@4%kJ*3Hi8ff1bh|^Mb=Sqw2`%8fzC%tDki^3wC0bG4@e3k${#d0i5lz$zs(L}ObWC1uu5Eh%ML{0*4;MG-xm z@~|zUh{P~2+>!TSTKPa6m+QBwDD!L8(rjiLhqEIro6)PdGTXy|I+K;fs?vp(^ezl* z#g&b6UavlzHvq|-R9q!Bwa1|-5<_)D3GK^7biN5SJR!*~Logs0#Yconw6YcPsGUpX4~0XK|+ zec>QD7)&@4-hAQNho61m*}I;->xbXk{H^sr?AY9Ke1-MbEt8ebAsHvhqj4iouU(vO z91Be&(^m4;RbgZXpm${2WXIFEN5;XqizgZ4wQg~S@*d|PFMZ_cI*Q>V(~dqot>p0Z zBoTFY@V7S&qBHilUBrbo#g0po8Taf^9f{LL|BM)uv@2(NEmxV6eq&;xE(bd^D@L9! z@fc&BKGdDbxGY_4#$?@gt)FEjdN$FZz7GPa{~2JnfqDGi3>U)V@F9EzxAF&}x4d)} z4d%>!jf_LnyoaV4lcoOU?>v9xj4<{4b5R26X=!O9r;mbpFdvSFV?g?EF_gecSOu%W z3(e31eQ*k#3KzpAa4B2{m%|kxGT8t#BQ;nhDs@aH>jzT?|BfBTF(dT;K1;Li_u zBX@Sc;HN8zzK*}ZjYPL4bplyCxRF7`(%?sifkuF2qsHJyhJnVo!Hki*R8G^mNnR>b zr9OTRzks{oZg>iwhG*a{cpKhl*fHKLgb8u4+QZ{gQ5>gDYd>vnwTxL!`_{f(u5$ zXxInbFb4L8BOn`QLJoK!52~OVYM=xBa1yM6PUwOF1fd(wfpcMR$p7W&qyx*0!PV?v zhV4$P`s~)MZttsfZj!h6snSQ?)QQy7BT(ozj0<4Y7{mBFyaOkpGCl!?W6>4C4=2GX za4MVym%??h1%3g4fG6Pvcmv)C*Eq%w=Kwz>7jHOI@cQ5`whhkNAVb@W&YbB?V<14= zkDU|5&KHa+(jU)*^Il<;(OP7UV)3v_l7c6}|==;Y>IS&ITDnz5(Ba8{qq}H^%>?7{>;d8H20YUooE< ze5)ErrXaI_EJU|=nZXZODpRFCZiFAeEpRJ53Xj3#@EW`h+u==k3*H9N z3*LntFdp4t0_+D9VKPjCMNk2i&;qS682K+_#ek`{W&m3mV?LR>(xp|X!y7<445s7< zs<~usVpnZ*aBW79ia*mmVQ{i(iqwe@+MxsdAo|`K=!CQ3>+lWuCY%qOU@QC>egY4{ z!|(_^3Xj3#AUfld@D#iSZ^JwAF6@B!;0x%5<6#2iz~JTo^|ZXf*S@Y{kzxb4tXdV85gR#d!;43}W#jpgt5Qfv?e7G8Z z0Jp=v@F(~iybABbaN5QMm9KX*2X+Ix2%RhB7=mPoRW0afIi{rO7H#DY7 zeOwPWz_aiXnB!R!fa9SXz5~y|2>N*uw1UWh%V9MAdmpg-dlSEZ3exYNhkYjE2b$qr z*b47E67t`3vBR0_L0-J`G5icN=s`MjBp?m*wygdQ+t-j4LA4qX7xv!f!$3{$Js5@E#mI)i6pS)$NC< z45AG}+QNZS7wvEf+zOAt>oDd(=6z5JYv4S%8(st%$1~wIu*dUBjOUkHv8fbT8blBK57@fc0!tq| z1D)(DxEg)~{|g5C*mo)-zvWE98_tWECwnn% z$&(Wk=^&Fs4$@HL)8soU|HmQ!SIcgYsZt-ez@zX1Ohcz$3?UHx`ulJNI`)J9UG5j9J9D%I| z3bL{N!MEW%@MBmu(=dLOgFY~exnVA225k0VAId{7gvkZy6R;7kDP&#&zlX=*S@6up zUI0^z&{N@c7&C|QXD;{P7`X39GIkU)2fhX0hphR817A8CyED86u4B+)7ci#5>2N#D zFUB9-4^}q5Gtoj1VIfEzuLduyhx6fj_$536+aQxVp9<0z3gKFiwy+hXJuIa?NSoM;O+FR$ zK*dYDvOa43m%0c-H(U=7!ke%keRdW!!m03GkbZm@)X|rvKX-s1Ho@)iGDshv47b7U zunnZoA3&d<1dE^zhQ5+Mu**Tdhdw!wl`$$3^gScnBT_8E<#M6vkQ^cT1rR*1(tHD4PcMQ z`!Xg!0Z&2(W3r6TQ@|dhPvG|k_%?i&%j@H$ZAcpGAQQT)`j`567~X+H(4%Ug7p@1< zt9}PA^eNG=vO#pLS_nW8w!)9$b=VGv&DXkDG2hK_CTs!G#r^=p(8GqqhtY(kE~G3z ztpbUbyBhzcE)E6Jlb1jhgyAeW8*T-s{yYjDdiVmZM_2G&2^-*axE+25Z@`-{4}IF! zuWKDT_D7;?8;;MATzue2z-J&ipKKW<&z#P+E&mUcx(GPtJ6G~MojFeioCh-hxdZNm z*I+Vpp}Eirm%#5q=0`8WD#!fjQhvV-ufRQvkS)xW4uuMkxzi_`-Bf6UF41VKSN&h= zq7QC^S793*#GF>lJR=_vl4tNIM1DW$qg-TcqUTB6*aDiMeVT}kbhgDU~8{u5I z6W))eVW5j0PG_H=ix>@bkF)J4L%Yw%tp7+oO8rT_*>xs$CH1tT+AvN8qXroP|E#5L z)Nv1juog~%uflckeVB2qVSKNiwIA5fz#IZzfRT;p{_r{+(S%M3Z7}LM_Lac}aLiKV z3fu&b!A_`NhK(7%3pc>6@EVL;j(rC1gfAYCo&qmJ=mhqv!h>-53S<;q3OB<~;Ae0* zY=bx8KahDM`2+VV_PE0@A!9Xpg-!5pFY}&e!}xOxd2eN(8(i&U-y-aITmARa(>tEF zep)xw*VFpK{x@>@;O`%dacw(z+ZZW(5cJ-IggX*;WfMwvVl>H~g<7fSpTq00-BITk zQSTSSA7Q7X4FqWi*TW6)7dV7AaT06=X&*1afwTj=ovh^dPvEDJMca_}vB%PShvE2q zoQs$ge4GG2j-QxFKdlQ#LGg2V%p7oEM7Y$)0w{)+@MX9LegSX7Vf5o#XoE9A`u6p3 zFGwGM1zv^m^zj*RI4p%_@D&glVE2C)eSfnh2R^O*|DTR0xt5na+qyy6W5IzUlYa#w zm$$>=$YhbvC1A_wukri4@G!g#BC|)s3=r8}2gkyC5IMdXY+2s5ls!WrGW{+Pxt=_6 zd;DaFv%T+eXhRafJD+G49Dz~i{rkVv$K&u3$ap)Qu~o+08u$@xg>7JuxjBrtwGaRq zf3Ji)K*r(c;CUFyI4ooGG_c3zSNMH0W3r6TLsG0Uk?wF5%V!`tF=bE_^V*&xcL$8+Zi{MmMg7 zufx3{y7C9mh`ua3^XYI4JOv}spG%+*KCSG=#PfmS_{2Q<{9Nb~u=jr+D0Oi&$lT^x zSi#&z<~U!q<~bKI$Jq>5fy{Ysg4^IO_$~Yi{t7Y|`WMV@L&b#8Pk|0Hr;e8Q8Tl#w ze?O@=sjrw3@iUUZR5Cv466m*MB+WEDn>x}C-tx#SbIWt{zqsYFVbkD{P1g)N6uz|O zlTJY@yw6q%oJMlW_Ap5!ANj+}eed7-(71EHYW%=ha^vW90vrirV3pBm1dSFW&+r(9 z#vCKpm~G_qZywJ+pONPeWzL5*@`9nv`H)6lIFvab(#U5IWzL5*@}i;4`H)6FXDD+% zq>;}Z%A5~j= zA*0Li8lAY1$^8LFDX+&^Rgsn{TUEL$T$y3$f#Z#|1!=fB9-l6w!tmj%mCyr5yMe6< zzxxy0@I%woNwhR${B_%n3D?at7EEW)h+)0Nd`X3=-nt?0RkvPZ?plz94|~5n)JH~xEM8kSZrv#DomwnqE6LBTFD3%j6)5o%rlA?yt(sQzV|UEVioflZM5EAT73`gr;gttXjlJs8y(zR zNY4oH)cKib9KRsVcvFQk3SXW0k@jz52=f{1mFskRo1{TrE)#pa?;vA5zSHRoZfdg8 zs5MIQDg7qh7|XxYjS1@c^qA+;_D31xc(22DV~gJyj}io1juw`Lw|SDmPQ%-;ciRjN)UIG61bDL zGKv)KyYZS~D?!{%PT)>j#wb#>@5W8TSAw{klE9s`fKjAq-;EnatOU++8chqnV_cAy zW3{+Gqnla@QA<)sYjD4hpeB#*XF}w zSOQ)M!|5RJcDx#X0Jp=v@F(~iybABbaO}PlU>eAK0_Vfg&;-Z9IdCq>8@%M5fX~85 zV6q@}6dVuT@Ev#tc!Q~W?`$jIm%-&QdK@(c^Pmx$;HPjKJP-SP0YA_T@{XIW@Dz+1 zPg)=V*MPj&X4C}Ua{_DNT6h{<`>~$^mcs_P0Um}OaPUOZ3U&Ll?+Jbj_rYJ`Z}1)* zd;t3#pdBuOTj3FS9mY(e?LZ~0f%D*Qco8xt)7IcMcpVOy!Wlfc6fT3?;c<8ercPyF z1}uPTsDWlU3(kfE52T&KLXdZOTnWF158ywLLnA&07Qn`X+1CMA!PW2^_+LQy7>7X( z_@E8uev$HmW8r_`7I+loJrUEU(QY6FH^BGdibIGSo`z>2a47qSVLf~uu7y9rKj5E` z_9dhp$U6xhgXiH@cprvMr+vZi;P>zpya+oW{V>WF_JxJ82v&m^*2DR5J^T`$fNhXT zC!PugPzdragYUpr_%SS{gD-<1bi?)VAiN3t(eYjHB z43n}sM*+9N?XV4Ag9B#r3>HBfY=#SAN)Bxq=DShv-RZCPN4}l!d7?%#(UV) z34L%4TnnS}=r@oH9#{s;VFO$U7s1crA$S!Q;Fs6XA zhbQ1k$S9!ujv>u(1zZW~3n&{n56*`>;7)iACKuDcpc5{E-@^;= zBCIN*J;Nn%DZC7?z&)juVHtUY3aErWxD8%~ZE#RIG6`lw5v+i3z#Z@mya!VjQcq9` zi@^)cun8`Z>qW>QxExkhkQO)>?u4Ji>#!ZO8RU%;DiSPgXmZEyyB4`k2!z3^Lj z1zv^mwS)zS!%|oVUx5wq0*tJq9l&O|5Pk)(!*)3QSoX<636w$`d=0(}55vnas-FG^ zGvIKjgJWSmTmYNlmaaui+|q03L)H%Sbc$;S#tMj$TfBp$laH=NWJ& z+yM8$Um)#xmqkKt@0|%!E=XgC6LG^I;SG5`G2gE9fV15F8BW!zTC* zyaETGNS@*Aa4-BDK7huR#1E&#E$|eKTt!_$AKVOohG${LYT6il6}|=+c&Qh-3a*Bm z;5N7mehYtszrsuKFPPm-e}&5oWM3}-$Y+C)x+6uwXM?bJOJi)mlJ9?KTt7GeSMT)C z`|h_)=H+HuOo?rx8l&OJ-}y-0p-AMjAypcmUfa+uGtDY_DgD@XC^OB}9bG)ehP_)F z2c)H$>A4b@#M3`6nVrYhMe2^Tr=&_FRT`?NZb-F+R7=>?mY}7vjEuH47Oh+D%#rU6 zV(*hXQT@=q6YC~cVvCzk^N!9%I_XTDiyAY2wq@Um=0fhorunmYC$@GH=VEWVNjGCl z>@q{{*qW72kKB>E;IkomC!^n;%zk%6<>Cp#@3EleN%UIff*Z8rQsY4Ql$}J z8oD=0k4xN}WE~>5H>K`4%kYyd4P6%^>k`+6tlh-c#ooUYmFjj}{qICAIkubB9V&4{ zsx+KEMM^`r@Zm{YxUBrew(z}wC)%F(eq7Ohk&4UNHd3WAl%=72<%p!cQr56zd*$c- zjxMp0NlQ#t>|;wTb;sGlQ>BqA4LT1x(x=@LbkB7q?YXiqCAQ~&R_{dh7CVKX)Sal7 z@=1rh_fptD&8a)mzw8=JmB#LrhL#eel1d5L(G@EtKC5@4J?^ub!f4CfyD8LlIyz~c z%I>+?I{p0JiME!{SKf8oU>i~r%bVxr})E#G? zrb^?#uQUvnwT?uIyAzf$@Q*;ip9{He_JXs=?EBEVFZa3sktlyB zPySY#{Jkvsn@RF_bL4NQ$luS9cj(J|)a6~;@;+sGr>?wLRo<;B>6%9rC14$aFgV`8 ziBZ2(Q9O3~i%eG{_monNSUWSOc9P=Niw0Tj73q5FP?K>$n{zFy+sM zJje$*|JVfGa1NXY=YyPy{1LnanY5b`FcRdPcJ8FBaoRZfi~N#5%OAjB!2r(+2Y5DnfM-PmJexDXv$;v1$-9M;<)}?|3O|Qm!SCUIcmke=|Aqet+u<#E4?cjABzQDTfc@c%a46(}2j;;sPziE2 zx*i%~HMBqodSL^64bFoL;41hw+z3B}+u#oP4crHhz+>=Ncn)5H*Wf+)0C?$wF%rhZ zMED{c3bP;&=0U;!lq;M)iE#{$nap?x^{@i|2R6d_a5>aZVO#+p1mOjE6|$#NA5c0S z|F9fRgiUY}Tn|5hw!@H(a2lKr7r|w46Wj{Ff#1Qi@OO9<-i1+Fvz1L zc||4|e@C>u3i5`8M-ef0kC&c)4oFYG3Z$ps2-4Gk3ewYm4bsye0_o|`g7ox%fwQN7 z#I^MFF(5sCGDuH945X(Qfb{edke*%x(!)DIdiW_IJ^XBt9)1Z(55EqihyMtqhyMzs zhu;sK>;5|49scr zydmH#a4p;j@|J*SK;9JaBD?|b%Qd6Ozu@1HhGcpZ-i7yICuE4!f#pb<6X9g&g&W`| zcnBVax8Plv$cQuva-jg4U^)B`oDTIzpq;~8uoGU-<~LN%q^-b|T*?XZ@~AgB9!`Xd z;WC(-PrHJ0sDNRGjGV9l%HR=r98P1laRwYdm->XW;T)KLB+?S9p$^8+BfW4QTng&c z`O(znF`SHsO$(6DupQoksm0VKgrFDhDWwd+ET_%E9GC|uLNk05Ho>pqX;`w585FcY z2l$Y}9k3ZLhQq5FG2xeR54;6CU{(#~0r$cEuno4u5ojAZkj*qG7jA;v;fQ*!p&puG zZ4sA5zd4y@FREz{tTm6(Z9hSK~CZK zMz{rj3M*GLs=|x#I$YzWf59#ABlrV60MEn!f*yJDk;W-Ly)ux|FICkVpqJ62lGfM|cokhSy*xRGZ967!l;1FTX&d3!9MGKN899K@tmj*pNW<(rl2w zVc!GG7io^?`viC%$@T_JM3PMh`5TDB4oI)l?|G1SJsjPj>Ev7ZCY%rQP6v6P!y(5p z9fGgGeXtoxbqU-J_rgCx{*KmLNGdS|+3z06U?%q8#R%S`HGxcw!Y&pxnhg`XS1)hk z3h)-LHO7Hh?T#da4P5EB4)$;r=Biy?JAbd@?Sk^>1#+zK#38m?A(kn(y@cW;t{%cP zc{^JGzmftUcY4%&z}k7Tf^>x)sakbRFDUcGbQ`2WTlRrUELPyXlSJLLU@A}@zwxf+4h%7r9KgZ;}j@j*uJU2EH#B*Z_;<>TAosli$BSCB#PY_$i?{-EuOpFAv zVIo0nn7G>+shboDqHYpF)J;l~5#7L|Z9{%#sHU|gZQRB>-L$r(Nk-CEbFJEg?I|rI z)}we$qg5`TRo?xfYLyG5RW6`a-u)q7#eEKqNw?v&4D_&=PsRbffK)Z=TTlAB0KqkR# zCz!E1nC%kGc7hoz!H8pLFgf&EM^K}q0ZEw*Bd86T<2G*iK&5CyCP8h;T+KB>iQD*~ za>%MPIJYCbj01)f+*o?;_J6D3#!9apORwGjZ-Nu2iGs^Pro;q^erta+4j4g@A_!LN zAR~fcwFD_HlLeVWiN*$tK5Tt54j4(Wxx>e8eB^zV(%j*sG`X} z(Xr)|Zp&bK>FNS3V)D<-bmhj^w`m(XPa`EK%s!v^swe$Kj%h zn+PgBeR#&O%wg#nnP;71nB3lAhod6mMk5NCD2bvV*6_WK?|R~uK{LSfLc&Qmh7C(g zPa82jeVE-j?8M{3*dYHjpx$+%NCr_Gnfy#wv5y{}nJ%BCu@|Ej`iV*WEE=~dZNn&1 z?8;0ZHZp?(md}Wh(Ws;nn9vZHsT9xv%4G*Jvgo=qf2V1TX*;kT^IM^cdqjpSJ$+bu zX41Gz@!6~57vy(}cF9ILn-|3s5v<#;J6mzRCpFZ~YVcpBaII>?^fU0 zx$_Iwqy1^cWvV65Wg#?|_NOO-@)B;DWXV*@L=MP=shxhQKO^F%YKbR-mgCfyvjjdu zSR%!ox72UxXwRMT?Kj`A?HGI01tX0k4*T&lv=svpu0|Ajz6r$VWgsfY&ma@-1<@fM z2NAl@fk?<#K{W+D%g8=~Z>e~b?@@fu<9i>zEBKc2wUKXRg0Y%!85~7$NT=`SdpzIk z`Ih)!AW}>|yyqK%Th?ICEyy(+{9V1B-kxB{YzlkZed@WSO+MmQ($O65?GE_Y^n2!X zC+VpPhPu3+IjzAS?N{!V1e?tU?LFc@51WyMEtZXHe@iGB4z~4}OM{_Sb8ZfWw}AV` z5APFGmHs_u@lQv-^V>9af6URFjAegNsvg-=dU1X3lCDuIt%0?Fq8GOtd5;=w1b%9%3u!b_R|XTN_-8TW?8-K%1< zIuc|~Ec4b5khyv{hz(#Phz;Nz5KHt$z(z#lDiD+Wbs%&4AA-#3e*zQX7a%r(dqKi} z37m6%x!2$?4TgGr>-nkX#}bCjlf`@}-(t*??~#YNR9yT_`h5_Ikn|5^L)Zs5k_MUM zOP(72J)J%kgZRXPPKG5u`IsPg=YaTG0CFwACGD%~D$7cn&`s0O{ zYs`%cZ~7jFXO~w2y;aK1+{5sSEdO?RllL&ZX#ddZ6MNvtuisqtw|{l})8R>9-;?m7 z{X>T*w$MEZFWNtJcp~HWBs^)qsZXi|QYDZofm8{kN+4ANsS-$)z}_hVdrm6)8dFd; zx0Jc9tk;WPDC_jHHZOB^nYYTET=Y+w<1-yrb9!0Bm$|#>x%+|4-(`+3b7|RBBKq_c zmQw^>71xA8rJB{-MRq z*0tOdQlC950ol|Tq~(~jd^r&#=TUa&Gm+gxb_z1^INX)4yx*+@k**Z^Y`S#)t+L1E zR_<)D?%HQ(B93a$3B@%{)cmG7z{T562i25xLJ#&aZli+rz{J-OfKMlz*+j_f^=*@=I z%X6;N5Jlsza5i~RnCL;FrG+X6e&OW&qP|Eo%dw%+x^b|c7`r(Hzh}%CHVRJ zoks0vjM8m4UUnZq+lbr8SQc#Q?eYbBlulUPAbT6Rr8=|x&at28%rV}cyH%8v)aNr@ G0{ - -#define UNIT_V_HWLK (UNIT_V_UF + 0) /* hwre write lock */ -#define UNIT_HWLK (1u << UNIT_V_HWLK) -#define UNIT_WPRT (UNIT_HWLK|UNIT_RO) /* write prot */ -#define UNIT_V_AUTO (UNIT_V_UF + 1) /* autosize */ -#define UNIT_AUTO (1u << UNIT_V_AUTO) -#define UNIT_V_DTYPE (UNIT_V_UF + 2) /* drive type */ -#define UNIT_M_DTYPE 0x7 -#define UNIT_DTYPE (UNIT_M_DTYPE << UNIT_V_DTYPE) -#define UDA u3 /* disk addr */ -#define UCMD u4 /* current command */ -#define UCTX u5 /* ctrl/ctx index */ -#define GET_DTYPE(x) (((x) >> UNIT_V_DTYPE) & UNIT_M_DTYPE) - -/* Constants */ - -#define DP_NUMCTL 2 /* number of controllers */ -#define DP_C7270 0 /* 7270 ctrl */ -#define DP_C3281 1 /* 3281 ctrl */ -#define DP_NUMDR_7270 8 /* drives/ctrl */ -#define DP_NUMDR_3281 15 -#define DP_CONT DP_NUMDR_3281 /* ctrl's drive # */ -#define DP_WDSC 256 /* words/sector */ -#define DP_BYHD 8 /* byte/header */ -#define DP_NUMDR ((uint32) ((ctx->dp_ctype == DP_C7270)? DP_NUMDR_7270: DP_NUMDR_3281)) -#define DP_SEEK (DP_CONT + 1) - -/* Address bytes */ - -#define DPA_V_CY 16 /* cylinder offset */ -#define DPA_M_CY 0x3FF -#define DPA_V_HD 8 /* head offset */ -#define DPA_M_HD 0x1F -#define DPA_V_SC 0 /* sector offset */ -#define DPA_M_SC 0x1F -#define DPA_GETCY(x) (((x) >> DPA_V_CY) & DPA_M_CY) -#define DPA_GETHD(x) (((x) >> DPA_V_HD) & DPA_M_HD) -#define DPA_GETSC(x) (((x) >> DPA_V_SC) & DPA_M_SC) - -/* Sense order */ - -#define DPS_NBY_7270 10 -#define DPS_NBY_3281 16 -#define DPS_NBY ((uint32) ((ctx->dp_ctype == DP_C7270)? DPS_NBY_7270: DPS_NBY_3281)) - -/* Test mode */ - -#define DPT_NBY_7270 1 /* bytes/test mode spec */ -#define DPT_NBY_3281 2 -#define DPT_NBY ((uint32) ((ctx->dp_ctype == DP_C7270)? DPT_NBY_7270: DPT_NBY_3281)) - -/* Commands */ - -#define DPS_INIT 0x100 -#define DPS_END 0x101 -#define DPS_WRITE 0x01 -#define DPS_READ 0x02 -#define DPS_SEEK 0x03 -#define DPS_SEEKI 0x83 -#define DPS_SENSE 0x04 -#define DPS_CHECK 0x05 -#define DPS_RSRV 0x07 -#define DPS_WHDR 0x09 -#define DPS_RHDR 0x0A -#define DPS_CRIOF 0x0F -#define DPS_RDEES 0x12 -#define DPS_TEST 0x13 -#define DPS_RLS 0x17 -#define DPS_CRION 0x1F -#define DPS_RLSA 0x23 -#define DPS_RECAL 0x33 -#define DPS_RECALI 0xB3 - -/* Seek completion states */ - -#define DSC_SEEK 0x00 /* seeking */ -#define DSC_SEEKI 0x80 /* seeking, then int */ -#define DSC_SEEKW 0x01 /* waiting to int */ - -/* Device status - note that these are device independent */ - -#define DPF_V_WCHK 0 -#define DPF_V_DPE 1 -#define DPF_V_SNZ 2 -#define DPF_V_EOC 3 -#define DPF_V_IVA 4 -#define DPF_V_PGE 5 -#define DPF_V_WPE 6 -#define DPF_V_AIM 7 -#define DPF_WCHK (1u << DPF_V_WCHK) /* wrt chk error */ -#define DPF_DPE (1u << DPF_V_DPE) /* data error */ -#define DPF_SNZ (1u << DPF_V_SNZ) /* sec# != 0 */ -#define DPF_EOC (1u << DPF_V_EOC) /* end cylinder */ -#define DPF_IVA (1u << DPF_V_IVA) /* invalid addr */ -#define DPF_PGE (1u << DPF_V_PGE) /* prog error */ -#define DPF_WPE (1u << DPF_V_WPE) /* wrt prot err */ -#define DPF_AIM (1u << DPF_V_AIM) /* arm in motion */ -#define DPF_V_DIFF 16 -#define DPF_M_DIFF 0xFFFFu -#define DPF_DIFF (DPF_M_DIFF << DPF_V_DIFF) - -/* Drive types */ - -/* These controllers support many different disk drive types: - - type #sectors/ #surfaces/ #cylinders/ - surface cylinder drive - - 7242 6 20 204 - 7261 11 20 204 - 7271 6 20 408 - 3288 17 5 823 =67MB - 7275 11 19 411 =88MB - 7276 11 19 815 =176MB - 3283 17 18 815 - - In theory, each drive can be a different type. The size field in - each unit selects the drive capacity for each drive and thus the - drive type. DISKS MUST BE DECLARED IN ASCENDING SIZE. -*/ - -#define DP_SZ(x) ((DPCY_##x) * (DPHD_##x) * (DPSC_##x) * DP_WDSC) -#define DP_ENT(x,y) (DP_##x), (DPCY_##x), (DPHD_##x), (DPSC_##x), (DP_C##y), (DPSZ_##x) - -#define DP_7242 0 -#define DPCY_7242 204 -#define DPHD_7242 20 -#define DPSC_7242 6 -#define DPSZ_7242 DP_SZ(7242) - -#define DP_7261 1 -#define DPCY_7261 204 -#define DPHD_7261 20 -#define DPSC_7261 11 -#define DPSZ_7261 DP_SZ(7261) - -#define DP_7271 2 -#define DPCY_7271 408 -#define DPHD_7271 20 -#define DPSC_7271 6 -#define DPSZ_7271 DP_SZ(7271) - -#define DP_3288 3 -#define DPCY_3288 822 -#define DPHD_3288 5 -#define DPSC_3288 17 -#define DPSZ_3288 DP_SZ(3288) - -#define DP_7275 4 -#define DPCY_7275 411 -#define DPHD_7275 19 -#define DPSC_7275 11 -#define DPSZ_7275 DP_SZ(7275) - -#define DP_7276 5 -#define DPCY_7276 815 -#define DPHD_7276 19 -#define DPSC_7276 11 -#define DPSZ_7276 DP_SZ(7276) - -#define DP_3283 6 -#define DPCY_3283 815 -#define DPHD_3283 19 -#define DPSC_3283 17 -#define DPSZ_3283 DP_SZ(3283) - -#define GET_PSC(x,s) ((int32) fmod (sim_gtime() / ((double) (x * DP_WDSC)), \ - ((double) (s)))) - -typedef struct { - uint32 dp_ctype; /* controller type */ - uint32 dp_flags; /* status flags */ - uint32 dp_ski; /* seek interrupts */ - uint32 dp_time; /* inter-word time */ - uint32 dp_stime; /* inter-track time */ - uint32 dp_stopioe; /* stop on I/O error */ - uint32 dp_test; /* test mode */ - } DP_CTX; - -typedef struct { - uint32 dtype; /* drive type */ - uint32 cy; /* cylinders */ - uint32 hd; /* heads */ - uint32 sc; /* sectors */ - uint32 ctype; /* controller */ - uint32 capac; /* capacity */ - } DP_TYPE; - -typedef struct { - uint32 byte; /* offset in array */ - uint32 mask; /* test mask */ - uint32 fpos; /* from position */ - uint32 tpos; /* to position */ - } DP_SNSTAB; - -static uint32 dp_buf[DP_WDSC]; - -extern uint32 chan_ctl_time; - -uint32 dpa_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 dpb_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 dp_disp (uint32 cidx, uint32 op, uint32 dva, uint32 *dvst); -uint32 dp_tio_status (uint32 cidx, uint32 un); -uint32 dp_tdv_status (uint32 cidx, uint32 un); -uint32 dp_aio_status (uint32 cidx, uint32 un); -void dp_set_sense (UNIT *uptr, uint32 *c); -t_stat dp_chan_err (uint32 dva, uint32 st); -t_stat dp_svc (UNIT *uptr); -t_stat dps_svc (UNIT *uptr); -t_stat dp_reset (DEVICE *dptr); -t_bool dp_inv_ad (UNIT *uptr, uint32 *da); -t_bool dp_inc_ad (UNIT *uptr); -t_stat dp_read (UNIT *uptr, uint32 da); -t_stat dp_write (UNIT *uptr, uint32 da); -t_stat dp_ioerr (UNIT *uptr); -t_bool dp_test_mode (uint32 cidx); -t_bool dp_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st); -int32 dp_clr_int (uint32 cidx); -void dp_set_ski (uint32 cidx, uint32 un); -void dp_clr_ski (uint32 cidx, uint32 un); -t_stat dp_attach (UNIT *uptr, char *cptr); -t_stat dp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat dp_set_ctl (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat dp_show_ctl (FILE *st, UNIT *uptr, int32 val, void *desc); - -static DP_TYPE dp_tab[] = { - { DP_ENT (7242, 7270) }, - { DP_ENT (7261, 3281) }, - { DP_ENT (7271, 7270) }, - { DP_ENT (3288, 3281) }, - { DP_ENT (7275, 3281) }, - { DP_ENT (7276, 3281) }, - { DP_ENT (3283, 3281) }, - { 0, 0, 0, 0, 0, 0 }, - }; - -static DP_SNSTAB dp_sense_7270[] = { - { 8, DPF_WCHK, DPF_V_WCHK, 6 }, - { 8, DPF_SNZ, DPF_V_SNZ, 2 }, - { 9, 0x01000000, 24, 0 }, - { 0, 0, 0, 0 } - }; - -static DP_SNSTAB dp_sense_3281[] = { - { 8, DPF_WCHK, DPF_V_WCHK, 7 }, - { 8, DPF_EOC, DPF_V_EOC, 3}, - { 8, DPF_AIM, DPF_V_AIM, 2}, - { 14, 0xFF000000, 24, 0 }, - { 15, 0x00FF0000, 16, 0 }, - { 0, 0, 0, 0 } - }; - -/* Command table, indexed by command */ - -#define C_7270 (1u << DP_C7270) -#define C_3281 (1u << DP_C3281) -#define C_B (C_7270|C_3281) -#define C_F (1u << 2) /* fast */ -#define C_C (1u << 3) /* ctrl cmd */ - -static uint8 dp_cmd[256] = { - 0, C_B, C_B, C_B, C_B|C_F, C_B, 0, C_3281|C_F, - 0, C_B, C_B, 0, 0, 0, 0, C_3281|C_F|C_C, - 0, 0, C_B, C_B|C_F, 0, 0, 0, C_3281|C_F, - 0, 0, 0, 0, 0, 0, 0, C_3281|C_F|C_C, - 0, 0, 0, C_7270|C_F, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, C_B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, C_B, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, C_3281, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0 - }; - -/* DP data structures - - dp_dev DP device descriptor - dp_unit DP unit descriptor - dp_reg DP register list -*/ - -dib_t dp_dib[] = { - { DVA_DPA, &dpa_disp }, - { DVA_DPB, &dpb_disp } - }; - -DP_CTX dp_ctx[] = { - { DP_C7270 }, - { DP_C3281 } - }; - -UNIT dpa_unit[] = { - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, (DP_7271 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DIS, DPSZ_7271) }, - { UDATA (&dp_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - }; - -UNIT dpb_unit[] = { - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, (DP_7276 << UNIT_V_DTYPE)+UNIT_FIX+UNIT_ATTABLE+UNIT_DISABLE+UNIT_DIS, DPSZ_7276) }, - { UDATA (&dp_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - { UDATA (&dps_svc, UNIT_DIS, 0) }, - }; - -REG dpa_reg[] = { - { HRDATA (CTYPE, dp_ctx[0].dp_ctype, 1), REG_HRO }, - { HRDATA (FLAGS, dp_ctx[0].dp_flags, 8) }, - { GRDATA (DIFF, dp_ctx[0].dp_flags, 16, 16, 16) }, - { HRDATA (SKI, dp_ctx[0].dp_ski, 16) }, - { HRDATA (TEST, dp_ctx[0].dp_test, 16) }, - { URDATA (ADDR, dpa_unit[0].UDA, 16, 32, 0, DP_NUMDR_3281, 0) }, - { URDATA (CMD, dpa_unit[0].UCMD, 16, 10, 0, DP_NUMDR_3281, 0) }, - { DRDATA (TIME, dp_ctx[0].dp_time, 24), PV_LEFT+REG_NZ }, - { DRDATA (STIME, dp_ctx[0].dp_stime, 24), PV_LEFT+REG_NZ }, - { FLDATA (STOP_IOE, dp_ctx[0].dp_stopioe, 0) }, - { HRDATA (DEVNO, dp_dib[0].dva, 12), REG_HRO }, - { NULL } - }; - -REG dpb_reg[] = { - { HRDATA (CTYPE, dp_ctx[1].dp_ctype, 1), REG_HRO }, - { HRDATA (FLAGS, dp_ctx[1].dp_flags, 8) }, - { GRDATA (DIFF, dp_ctx[1].dp_flags, 16, 16, 16) }, - { HRDATA (SKI, dp_ctx[1].dp_ski, 16) }, - { HRDATA (TEST, dp_ctx[1].dp_test, 16) }, - { URDATA (ADDR, dpa_unit[1].UDA, 16, 32, 0, DP_NUMDR_3281, 0) }, - { URDATA (CMD, dpa_unit[1].UCMD, 16, 10, 0, DP_NUMDR_3281, 0) }, - { DRDATA (TIME, dp_ctx[1].dp_time, 24), PV_LEFT+REG_NZ }, - { DRDATA (STIME, dp_ctx[1].dp_stime, 24), PV_LEFT+REG_NZ }, - { FLDATA (STOP_IOE, dp_ctx[1].dp_stopioe, 0) }, - { HRDATA (DEVNO, dp_dib[1].dva, 12), REG_HRO }, - { NULL } - }; - -MTAB dp_mod[] = { - { MTAB_XTD|MTAB_VDV, DP_C7270, "C7270", "C7270", - &dp_set_ctl, &dp_show_ctl, NULL }, - { MTAB_XTD|MTAB_VDV, DP_C3281, "C3281", "C3281", - &dp_set_ctl, &dp_show_ctl, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_7242 << UNIT_V_DTYPE) + UNIT_ATT, - "7242", NULL, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_7261 << UNIT_V_DTYPE) + UNIT_ATT, - "7261", NULL, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_7271 << UNIT_V_DTYPE) + UNIT_ATT, - "7271", NULL, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_3288 << UNIT_V_DTYPE) + UNIT_ATT, - "3288", NULL, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_7275 << UNIT_V_DTYPE) + UNIT_ATT, - "7275", NULL, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_7276 << UNIT_V_DTYPE) + UNIT_ATT, - "7276", NULL, NULL }, - { (UNIT_DTYPE+UNIT_ATT), (DP_3283 << UNIT_V_DTYPE) + UNIT_ATT, - "3283", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_7242 << UNIT_V_DTYPE), - "7242", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_7261 << UNIT_V_DTYPE), - "7261", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_7271 << UNIT_V_DTYPE), - "7271", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_3288 << UNIT_V_DTYPE), - "3288", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_7275 << UNIT_V_DTYPE), - "7275", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_7276 << UNIT_V_DTYPE), - "7276", NULL, NULL }, - { (UNIT_AUTO+UNIT_DTYPE+UNIT_ATT), (DP_3283 << UNIT_V_DTYPE), - "3283", NULL, NULL }, - { (UNIT_AUTO+UNIT_ATT), UNIT_AUTO, "autosize", NULL, NULL }, - { UNIT_AUTO, UNIT_AUTO, NULL, "AUTOSIZE", NULL }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_7242 << UNIT_V_DTYPE), - NULL, "7242", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_7261 << UNIT_V_DTYPE), - NULL, "7261", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_7271 << UNIT_V_DTYPE), - NULL, "7271", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_3288 << UNIT_V_DTYPE), - NULL, "3288", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_7275 << UNIT_V_DTYPE), - NULL, "7275", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_7276 << UNIT_V_DTYPE), - NULL, "7276", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_7276 << UNIT_V_DTYPE), - NULL, "3282", &dp_set_size }, - { (UNIT_AUTO+UNIT_DTYPE), (DP_3283 << UNIT_V_DTYPE), - NULL, "3283", &dp_set_size }, - { UNIT_HWLK, 0, "write enabled", "WRITEENABLED", NULL }, - { UNIT_HWLK, UNIT_HWLK, "write locked", "LOCKED", NULL }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE dp_dev[] = { - { - "DPA", dpa_unit, dpa_reg, dp_mod, - (2 * DP_NUMDR_3281) + 1, 16, 28, 1, 16, 32, - NULL, NULL, &dp_reset, - &io_boot, &dp_attach, NULL, - &dp_dib[0], DEV_DISABLE - }, - { - "DPB", dpb_unit, dpb_reg, dp_mod, - (2 * DP_NUMDR_3281) + 1, 16, 28, 1, 16, 32, - NULL, NULL, &dp_reset, - &io_boot, &dp_attach, NULL, - &dp_dib[1], DEV_DISABLE - } - }; - -/* DP: IO dispatch routine */ - -uint32 dpa_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -return dp_disp (0, op, dva, dvst); -} - -uint32 dpb_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -return dp_disp (1, op, dva, dvst); -} - -uint32 dp_disp (uint32 cidx, uint32 op, uint32 dva, uint32 *dvst) -{ -uint32 un = DVA_GETUNIT (dva); -UNIT *dp_unit = dp_dev[cidx].units; -UNIT *uptr = dp_unit + un; -int32 iu; -uint32 i; -DP_CTX *ctx; - -if (cidx >= DP_NUMCTL) /* inv ctrl num? */ - return DVT_NODEV; -ctx = &dp_ctx[cidx]; -if ((un >= DP_NUMDR) || /* inv unit num? */ - ((uptr->flags & UNIT_DIS) && /* disabled unit? */ - ((un != 0xF) || (ctx->dp_ctype != C_3281)))) /* not 3281 unit F? */ - return DVT_NODEV; - -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = dp_tio_status (cidx, un); /* get status */ - if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ - uptr->UCMD = DPS_INIT; /* start dev thread */ - sim_activate (uptr, chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = dp_tio_status (cidx, un); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = dp_tdv_status (cidx, un); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - *dvst = dp_tio_status (cidx, un); /* return status */ - if (un != 0xF) { /* not controller */ - if ((int32) un == chan_chk_chi (dva)) /* halt active ctlr int? */ - chan_clr_chi (dva); /* clear ctlr int */ - if (sim_is_active (uptr)) { /* chan active? */ - sim_cancel (uptr); /* stop unit */ - chan_uen (dva); /* uend */ - } - dp_clr_ski (cidx, un); /* clear seek int */ - sim_cancel (uptr + DP_SEEK); /* cancel seek compl */ - } - else { - for (i = 0; i < DP_NUMDR; i++) { /* do every unit */ - if (sim_is_active (&dp_unit[i])) { /* chan active? */ - sim_cancel (&dp_unit[i]); /* cancel */ - chan_uen (dva); /* uend */ - } - dp_clr_ski (cidx, i); /* clear seek int */ - sim_cancel (&dp_unit[i] + DP_SEEK); /* cancel seek compl */ - } - chan_clr_chi (dva); /* clear chan int */ - } - break; - - case OP_AIO: /* acknowledge int */ - iu = dp_clr_int (cidx); /* clear int */ - *dvst = dp_aio_status (cidx, iu) | /* get status */ - (iu << DVT_V_UN); - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Unit service */ - -t_stat dp_svc (UNIT *uptr) -{ -uint32 i, da, wd, wd1, c[DPS_NBY_3281]; -uint32 cidx = uptr->UCTX; -uint32 dva = dp_dib[cidx].dva; -uint32 dtype = GET_DTYPE (uptr->flags); -UNIT *dp_unit = dp_dev[cidx].units; -uint32 un = uptr - dp_unit; -DP_CTX *ctx = &dp_ctx[cidx]; -int32 t, dc; -uint32 st, cmd, sc; -t_stat r; - -if (uptr->UCMD == DPS_INIT) { /* init state? */ - st = chan_get_cmd (dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return dp_chan_err (dva, st); - ctx->dp_flags = 0; /* clear status */ - if (!(dp_cmd[cmd] & (1u << ctx->dp_ctype))) { /* cmd valid for dev? */ - ctx->dp_flags |= DPF_PGE; - chan_uen (dva); /* uend */ - return SCPE_OK; - } - if ((un == 0xF) && /* to controller? */ - !(dp_cmd[cmd] & C_C)) { /* not valid? */ - ctx->dp_flags |= DPF_PGE; - chan_uen (dva); /* uend */ - return SCPE_OK; - } - uptr->UCMD = cmd; /* save state */ - if (dp_cmd[cmd] & C_F) /* fast command? */ - sim_activate_abs (uptr, chan_ctl_time); /* schedule soon */ - else { /* data transfer */ - sc = DPA_GETSC (uptr->UDA); /* new sector */ - t = sc - GET_PSC (ctx->dp_time, dp_tab[dtype].sc); /* delta to new */ - if (t < 0) /* wrap around? */ - t = t + dp_tab[dtype].sc; - sim_activate_abs (uptr, t * ctx->dp_time * DP_WDSC); /* schedule op */ - } - sim_cancel (uptr + DP_SEEK); /* cancel rest of seek */ - return SCPE_OK; - } -else if (uptr->UCMD == DPS_END) { /* end state? */ - st = chan_end (dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return dp_chan_err (dva, st); - if (st == CHS_CCH) { /* command chain? */ - uptr->UCMD = DPS_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - return SCPE_OK; /* done */ - } - -da = 0; -dc = 0; -switch (uptr->UCMD) { - - case DPS_SEEK: /* seek */ - case DPS_SEEKI: - for (i = 0; i < 4; i++) - c[i] = 0; - for (i = 0, st = 0; (i < 4) && (st != CHS_ZBC); i++) { - st = chan_RdMemB (dva, &c[i]); /* get byte */ - if (CHS_IFERR (st)) /* channel error? */ - return dp_chan_err (dva, st); - } - da = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; - if (c[0] & 0xFC) /* hi 6b non-zero? */ - ctx->dp_flags |= DPF_PGE; /* set prog err */ - if (((i != 4) || (st != CHS_ZBC)) && /* length error? */ - chan_set_chf (dva, CHF_LNTE)) { /* care? */ - ctx->dp_flags |= DPF_PGE; /* set prog err */ - return SCPE_OK; - } - if (i < 4) { /* at least 4? */ - chan_uen (dva); - return SCPE_OK; - } - dc = DPA_GETCY (da); /* desired cyl */ - case DPS_RECAL: - case DPS_RECALI: - t = DPA_GETCY (uptr->UDA) - dc; /* get cyl diff */ - ctx->dp_flags = (ctx->dp_flags & ~DPF_DIFF) | - ((t & DPF_M_DIFF) << DPF_V_DIFF); /* save difference */ - if (t == 0) - t = 1; - else t = abs (t); - uptr->UDA = da; /* save addr */ - sim_activate (uptr + DP_SEEK, t * ctx->dp_stime); - dp_unit[un + DP_SEEK].UCMD = /* sched seek */ - (chan_tst_cmf (dva, CMF_CCH)? DSC_SEEK: uptr->UCMD & 0x80); - break; /* sched end */ - - case DPS_SENSE: /* sense */ - for (i = 0; i < DPS_NBY_3281; i++) - c[i] = 0; - c[0] = (uptr->UDA >> 24) & 0xFF; - c[1] = (uptr->UDA >> 16) & 0xFF; - c[2] = (uptr->UDA >> 8) & 0xFF; - c[3] = uptr->UDA & 0xFF; - c[4] = GET_PSC (ctx->dp_time, dp_tab[dtype].sc) | /* curr sector */ - ((sim_is_active (uptr) && ((uptr->UCMD & 0x7F) == DPS_SEEK))? 0x80: 0); - if (ctx->dp_ctype == DP_C3281) { - c[5] = c[7] = un; - c[10] = (ctx->dp_ski >> 8) & 0xFF; - c[11] = ctx->dp_ski & 0xFF; - } - dp_set_sense (uptr, &c[0]); - for (i = 0, st = 0; (i < DPS_NBY) && (st != CHS_ZBC); i++) { - st = chan_WrMemB (dva, c[i]); /* store char */ - if (CHS_IFERR (st)) /* channel error? */ - return dp_chan_err (dva, st); - } - if ((i != DPS_NBY) || (st != CHS_ZBC)) { /* length error? */ - ctx->dp_flags |= DPF_PGE; /* set prog err */ - if (chan_set_chf (dva, CHF_LNTE)) /* do we care? */ - return SCPE_OK; - } - break; - - case DPS_WRITE: /* write */ - if (uptr->flags & UNIT_RO) { /* write locked? */ - ctx->dp_flags |= DPF_WPE; - chan_uen (dva); /* uend */ - return SCPE_OK; - } - if (dp_inv_ad (uptr, &da)) { /* invalid addr? */ - chan_uen (dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; i < DP_WDSC; i++) { /* sector loop */ - if (st != CHS_ZBC) { /* chan not done? */ - st = chan_RdMemW (dva, &wd); /* read word */ - if (CHS_IFERR (st)) { /* channel error? */ - dp_inc_ad (uptr); /* da increments */ - return dp_chan_err (dva, st); - } - } - else wd = 0; - dp_buf[i] = wd; /* store in buffer */ - } - if (r = dp_write (uptr, da)) /* write buf, err? */ - return r; - if (dp_end_sec (uptr, DP_WDSC, DP_WDSC, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - -/* Write header "writes" eight bytes per sector and throws them in the bit bucket */ - - case DPS_WHDR: - if (uptr->flags & UNIT_RO) { /* write locked? */ - ctx->dp_flags |= DPF_WPE; - chan_uen (dva); /* uend */ - return SCPE_OK; - } - if (dp_inv_ad (uptr, &da)) { /* invalid addr? */ - chan_uen (dva); /* uend */ - return SCPE_OK; - } - if (DPA_GETSC (uptr->UDA) != 0) { - ctx->dp_flags |= DPF_SNZ; - chan_uen (dva); - return SCPE_OK; - } - for (i = 0, st = 0; (i < 8) && (st != CHS_ZBC); i++) { /* sector loop */ - if (st != CHS_ZBC) { /* chan not done? */ - st = chan_RdMemB (dva, &wd); /* read word */ - if (CHS_IFERR (st)) { /* channel error? */ - dp_inc_ad (uptr); /* da increments */ - return dp_chan_err (dva, st); - } - } - } - if (dp_end_sec (uptr, i, 8, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - -/* Write check must be done by bytes to get precise miscompare */ - - case DPS_CHECK: /* write check */ - if (dp_inv_ad (uptr, &da)) { /* invalid addr? */ - chan_uen (dva); /* uend */ - return SCPE_OK; - } - if (r = dp_read (uptr, da)) /* read buf, error? */ - return r; - for (i = 0, st = 0; (i < (DP_WDSC * 4)) && (st != CHS_ZBC); i++) { - st = chan_RdMemB (dva, &wd); /* read byte */ - if (CHS_IFERR (st)) { /* channel error? */ - dp_inc_ad (uptr); /* da increments */ - return dp_chan_err (dva, st); - } - wd1 = (dp_buf[i >> 2] >> (24 - ((i % 4) * 8))) & 0xFF; /* byte */ - if (wd != wd1) { /* check error? */ - dp_inc_ad (uptr); /* da increments */ - ctx->dp_flags |= DPF_WCHK; /* set status */ - chan_uen (dva); /* force uend */ - return SCPE_OK; - } - } - if (dp_end_sec (uptr, i, DP_WDSC * 4, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - - case DPS_READ: /* read */ - if (dp_inv_ad (uptr, &da)) { /* invalid addr? */ - chan_uen (dva); /* uend */ - return SCPE_OK; - } - if (r = dp_read (uptr, da)) /* read buf, error? */ - return r; - for (i = 0, st = 0; (i < DP_WDSC) && (st != CHS_ZBC); i++) { - st = chan_WrMemW (dva, dp_buf[i]); /* store in mem */ - if (CHS_IFERR (st)) { /* channel error? */ - dp_inc_ad (uptr); /* da increments */ - return dp_chan_err (dva, st); - } - } - if (dp_end_sec (uptr, i, DP_WDSC, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - -/* Read header reads 8 bytes per sector */ - - case DPS_RHDR: /* read header */ - if (dp_inv_ad (uptr, &da)) { /* invalid addr? */ - chan_uen (dva); /* uend */ - return SCPE_OK; - } - c[0] = c[5] = c[6] = c[7] = 0; - wd = DPA_GETCY (uptr->UDA); - c[1] = (wd >> 8) & 0xFF; - c[2] = wd & 0xFF; - c[3] = DPA_GETHD (uptr->UDA); - c[4] = DPA_GETSC (uptr->UDA); - for (i = 0, st = 0; (i < 8) && (st != CHS_ZBC); i++) { - st = chan_WrMemB (dva, c[i]); /* store in mem */ - if (CHS_IFERR (st)) { /* channel error? */ - dp_inc_ad (uptr); /* da increments */ - return dp_chan_err (dva, st); - } - } - if (dp_end_sec (uptr, i, 8, st)) /* transfer done? */ - return SCPE_OK; /* err or cont */ - break; - -/* Test mode is not really implemented */ - - case DPS_TEST: /* test mode */ - if (!dp_test_mode (cidx)) /* enter test mode */ - return SCPE_OK; - break; - - case DPS_RSRV: /* reserve */ - case DPS_RLS: /* release */ - case DPS_RLSA: /* release */ - break; /* nop */ - } - -uptr->UCMD = DPS_END; /* op done, next state */ -sim_activate (uptr, chan_ctl_time); -return SCPE_OK; -} - -/* Seek completion service */ - -t_stat dps_svc (UNIT *uptr) -{ -uint32 cidx = uptr->UCTX; -DP_CTX *ctx = &dp_ctx[cidx]; -UNIT *dp_unit = dp_dev[cidx].units; -uint32 un = uptr - dp_unit - DP_SEEK; -uint32 dtype = GET_DTYPE (dp_unit[un].flags); - -if (uptr->UCMD != DSC_SEEK) { /* int? */ - if (chan_chk_chi (dp_dib[cidx].dva) >= 0) { /* ctl int pending? */ - sim_activate (uptr, ctx->dp_time * dp_tab[dtype].sc); - uptr->UCMD = DSC_SEEKW; - } - else dp_set_ski (cidx, un); - } -return SCPE_OK; -} - -/* Common read/write sector end routine - - case 1 - more to transfer, not end cylinder - reschedule, return TRUE - case 2 - more to transfer, end cylinder - uend, return TRUE - case 3 - transfer done, length error - uend, return TRUE - case 4 - transfer done, no length error - return FALSE (sched end state) -*/ - -t_bool dp_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st) -{ -uint32 cidx = uptr->UCTX; -uint32 dva = dp_dib[cidx].dva; -uint32 dtype = GET_DTYPE (uptr->flags); -DP_CTX *ctx = &dp_ctx[cidx]; - -if (st != CHS_ZBC) { /* end record? */ - if (dp_inc_ad (uptr)) { /* inc addr, cross cyl? */ - ctx->dp_flags |= (DPF_IVA | DPF_EOC); - chan_uen (dva); /* uend */ - } - else sim_activate (uptr, ctx->dp_time * 16); /* no, next sector */ - return TRUE; - } -dp_inc_ad (uptr); /* just incr addr */ -if (lnt != exp) { /* length error at end? */ - if (exp == 8) /* hdr op? */ - ctx->dp_flags |= DPF_PGE; /* set PGE */ - if (chan_set_chf (dva, CHF_LNTE)) /* do we care? */ - return TRUE; - } -return FALSE; /* cmd done */ -} - -/* DP status routine */ - -uint32 dp_tio_status (uint32 cidx, uint32 un) -{ -uint32 i; -DP_CTX *ctx = &dp_ctx[cidx]; -UNIT *dp_unit = dp_dev[cidx].units; - -for (i = 0; i < DP_NUMDR; i++) { - if (sim_is_active (&dp_unit[i])) - return (DVS_AUTO|DVS_CBUSY|DVS_DBUSY|(CC2 << DVT_V_CC)); - } -for (i = 0; i < DP_NUMDR; i++) { - if (sim_is_active (&dp_unit[i + DP_SEEK]) && - (dp_unit[i + DP_SEEK].UCMD != DSC_SEEKW)) - return (DVS_AUTO|DVS_DBUSY|(CC2 << DVT_V_CC)); - } -return DVS_AUTO; -} - -uint32 dp_tdv_status (uint32 cidx, uint32 un) -{ -uint32 st; -DP_CTX *ctx = &dp_ctx[cidx]; -UNIT *dp_unit = dp_dev[cidx].units; -t_bool on_cyl; - -st = 0; -on_cyl = !sim_is_active (&dp_unit[un + DP_SEEK]) || - (dp_unit[un + DP_SEEK].UCMD == DSC_SEEKW); -if (dp_ctx[cidx].dp_ctype == DP_C7270) - st = ((dp_ctx[cidx].dp_flags & DPF_IVA)? 0x20: 0) | - (on_cyl? 0x04: 0); -else st = ((dp_ctx[cidx].dp_flags & DPF_PGE)? 0x20: 0) | - ((dp_ctx[cidx].dp_flags & DPF_WPE)? 0x08: 0); -return st; -} - -uint32 dp_aio_status (uint32 cidx, uint32 un) -{ -uint32 st; -DP_CTX *ctx = &dp_ctx[cidx]; -UNIT *dp_unit = dp_dev[cidx].units; -t_bool on_cyl; - -st = 0; -on_cyl = !sim_is_active (&dp_unit[un + DP_SEEK]) || - (dp_unit[un + DP_SEEK].UCMD == DSC_SEEKW); -if ((dp_ctx[cidx].dp_ctype == DP_C7270) && on_cyl) - st |= 0x04; -if (chan_chk_chi (dp_dib[cidx].dva) < 0) - st |= 0x08; -return st; -} - -/* Set sense status */ - -void dp_set_sense (UNIT *uptr, uint32 *c) -{ -uint32 cidx = uptr->UCTX; -UNIT *sptr = uptr + DP_SEEK; -DP_CTX *ctx = &dp_ctx[cidx]; -uint8 data; -DP_SNSTAB *tptr; - -if (sim_is_active (sptr) && - (sptr->UCMD != DSC_SEEKW)) - ctx->dp_flags |= DPF_AIM; -else ctx->dp_flags &= ~DPF_AIM; -if (ctx->dp_ctype == DP_C7270) - tptr = dp_sense_7270; -else tptr = dp_sense_3281; -while (tptr->byte != 0) { - if (ctx->dp_flags & tptr->mask) { - data = (uint8) ((ctx->dp_flags & tptr->mask) >> tptr->fpos); - c[tptr->byte] |= (data << tptr->tpos); - } - } -return; -} - -/* Validate disk address */ - -t_bool dp_inv_ad (UNIT *uptr, uint32 *da) -{ -uint32 dtype = GET_DTYPE (uptr->flags); -uint32 cy = DPA_GETCY (uptr->UDA); -uint32 hd = DPA_GETHD (uptr->UDA); -uint32 sc = DPA_GETSC (uptr->UDA); - -if ((cy >= dp_tab[dtype].cy) || - (hd >= dp_tab[dtype].hd) || - (sc >= dp_tab[dtype].sc)) - return TRUE; -if (da) /* return word addr */ - *da = ((((cy * dp_tab[dtype].hd) + hd) * dp_tab[dtype].sc) + sc) * DP_WDSC; -return FALSE; -} - -/* Increment disk address */ - -t_bool dp_inc_ad (UNIT *uptr) -{ -uint32 dtype = GET_DTYPE (uptr->flags); -uint32 cy = DPA_GETCY (uptr->UDA); -uint32 hd = DPA_GETHD (uptr->UDA); -uint32 sc = DPA_GETSC (uptr->UDA); - -sc = sc + 1; /* sector++ */ -if (sc >= dp_tab[dtype].sc) { /* overflow? */ - sc = 0; /* wrap sector */ - hd = hd + 1; /* head++ */ - if (hd >= dp_tab[dtype].hd) /* overflow? */ - hd = 0; /* wrap heads */ - } -uptr->UDA = (cy << DPA_V_CY) | (hd << DPA_V_HD) | (sc << DPA_V_SC); -if ((hd == 0) && (sc == 0)) - return TRUE; -return FALSE; -} - -/* Read and write sector */ - -t_stat dp_read (UNIT *uptr, uint32 da) -{ -int32 err, awc; - -err = fseek (uptr->fileref, da * sizeof (int32), SEEK_SET); -if (err == 0) { - awc = fxread (dp_buf, sizeof (uint32), DP_WDSC, uptr->fileref); - err = ferror (uptr->fileref); - for (; awc < DP_WDSC; awc++) /* fill buf */ - dp_buf[awc] = 0; - } -if (err != 0) - return dp_ioerr (uptr); -return SCPE_OK; -} - -t_stat dp_write (UNIT *uptr, uint32 da) -{ -int32 err; - -err = fseek (uptr->fileref, da * sizeof (int32), SEEK_SET); -if (err == 0) { - fxwrite (dp_buf, sizeof (uint32), DP_WDSC, uptr->fileref); - err = ferror (uptr->fileref); - } -if (err != 0) - return dp_ioerr (uptr); -return SCPE_OK; -} - -t_stat dp_ioerr (UNIT *uptr) -{ -uint32 cidx = uptr->UCTX; -uint32 dva = dp_dib[cidx].dva; - -perror ("DP I/O error"); -clearerr (uptr->fileref); -dp_ctx[cidx].dp_flags |= DPF_DPE; /* set DPE flag */ -chan_set_chf (dva, CHF_XMDE); -chan_uen (dva); /* force uend */ -return SCPE_IOERR; -} - -/* Test mode */ - -t_bool dp_test_mode (uint32 cidx) -{ -DP_CTX *ctx = &dp_ctx[cidx]; -uint32 dva = dp_dib[cidx].dva; -uint32 i, st, wd; - -ctx->dp_test = 0; -for (i = 0, st = 0; i < DPT_NBY; i++) { /* sector loop */ - if (st != CHS_ZBC) { /* chan not done? */ - st = chan_RdMemB (dva, &wd); /* read word */ - if (CHS_IFERR (st)) { - dp_chan_err (dva, st); - return FALSE; - } - } - else wd = 0; - ctx->dp_test |= (wd & 0xFF) << (i * 8); - } -return TRUE; -} - -/* Channel error */ - -t_stat dp_chan_err (uint32 dva, uint32 st) -{ -chan_uen (dva); /* uend */ -if (st < CHS_ERR) return st; -return SCPE_OK; -} - -/* Clear controller/device interrupt */ - -int32 dp_clr_int (uint32 cidx) -{ -int32 iu; -DP_CTX *ctx = &dp_ctx[cidx]; - -if ((iu = chan_clr_chi (dp_dib[cidx].dva)) >= 0) { /* chan int? clear */ - if (ctx->dp_ski != 0) /* more int? */ - chan_set_dvi (dp_dib[cidx].dva); /* set INP */ - return iu; - } -for (iu = 0; iu < (int32) DP_NUMDR; iu++) { /* seek int? */ - if (ctx->dp_ski & (1u << iu)) { - dp_clr_ski (cidx, iu); /* clear */ - return iu; - } - } -return 0; -} - -/* Set seek interrupt */ - -void dp_set_ski (uint32 cidx, uint32 un) -{ -dp_ctx[cidx].dp_ski |= (1u << un); -chan_set_dvi (dp_dib[cidx].dva); /* set INP */ -return; -} - -/* Clear seek interrupt */ - -void dp_clr_ski (uint32 cidx, uint32 un) -{ -dp_ctx[cidx].dp_ski &= ~(1u << un); /* clear */ -if (dp_ctx[cidx].dp_ski != 0) /* more int? */ - chan_set_dvi (dp_dib[cidx].dva); /* set INP */ -else if (chan_chk_chi (dp_dib[cidx].dva) < 0) /* any int? */ - chan_clr_chi (dp_dib[cidx].dva); /* clr INP */ -return; -} - -/* Reset routine */ - -t_stat dp_reset (DEVICE *dptr) -{ -uint32 i; -uint32 cidx = dptr - dp_dev; -UNIT *dp_unit; -DP_CTX *ctx; - -if (cidx >= DP_NUMCTL) - return SCPE_IERR; -dp_unit = dptr->units; -ctx = &dp_ctx[cidx]; -for (i = 0; i < DP_NUMDR; i++) { - sim_cancel (&dp_unit[i]); /* stop dev thread */ - dp_unit[i].UDA = 0; - dp_unit[i].UCMD = 0; - dp_unit[i].UCTX = cidx; - } -ctx->dp_flags = 0; -ctx->dp_ski = 0; -ctx->dp_test = 0; -chan_reset_dev (dp_dib[cidx].dva); /* clr int, active */ -return SCPE_OK; -} - -/* Device attach */ - -t_stat dp_attach (UNIT *uptr, char *cptr) -{ -uint32 i, p; -t_stat r; - -uptr->capac = dp_tab[GET_DTYPE (uptr->flags)].capac; -r = attach_unit (uptr, cptr); /* attach unit */ -if (r != SCPE_OK) /* error? */ - return r; -if ((uptr->flags & UNIT_AUTO) == 0) /* autosize? */ - return SCPE_OK; -p = sim_fsize (uptr->fileref); -for (i = 0; dp_tab[i].sc != 0; i++) { - if (p <= (dp_tab[i].capac * (uint32) sizeof (int32))) { - uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE); - uptr->capac = dp_tab[i].capac; - return SCPE_OK; - } - } -return SCPE_OK; -} - -/* Set drive type command validation routine */ - -t_stat dp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 dtype = GET_DTYPE (val); -uint32 cidx = uptr->UCTX; - -if (cidx >= DP_NUMCTL) /* valid ctrl idx? */ - return SCPE_IERR; -if (uptr->flags & UNIT_ATT) /* unattached? */ - return SCPE_ALATT; -if (dp_tab[dtype].ctype != dp_ctx[cidx].dp_ctype) /* valid for curr ctrl? */ - return SCPE_NOFNC; -uptr->capac = dp_tab[dtype].capac; -return SCPE_OK; -} - -/* Set controller type command validation routine */ - -t_stat dp_set_ctl (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 i, cidx = uptr->UCTX; -DP_CTX *ctx = &dp_ctx[cidx]; -UNIT *dp_unit = dp_dev[cidx].units; - -if ((cidx >= DP_NUMCTL) || (val >= DP_NUMCTL)) /* valid ctrl idx? */ - return SCPE_IERR; -if (val == dp_ctx[cidx].dp_ctype) - return SCPE_OK; -for (i = 0; i < DP_NUMDR; i++) { /* all units detached? */ - if (dp_unit[i].flags & UNIT_ATT) - return SCPE_ALATT; - } -for (i = 0; i < DP_NUMDR; i++) { - if (val == DP_C7270) { /* changing to 7270? */ - dp_unit[i].flags = (dp_unit[i].flags & ~UNIT_DTYPE) | - (DP_7271 << UNIT_V_DTYPE); - dp_unit[i].capac = DPSZ_7271; - if (i >= DP_NUMDR_7270) - dp_unit[i].flags = (dp_unit[i].flags | UNIT_DIS) & ~UNIT_DISABLE; - } - else { - dp_unit[i].flags = (dp_unit[i].flags & ~UNIT_DTYPE) | - (DP_7275 << UNIT_V_DTYPE); - dp_unit[i].capac = DPSZ_7275; - if (i >= DP_NUMDR_7270) - dp_unit[i].flags = dp_unit[i].flags | UNIT_DISABLE; - } - } -return SCPE_OK; -} - -t_stat dp_show_ctl (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -uint32 cidx = uptr->UCTX; - -if (cidx >= DP_NUMCTL) /* valid ctrl idx? */ - return SCPE_IERR; -if (dp_ctx[cidx].dp_ctype == DP_C7270) - fprintf (st, "7270 controller"); -else fprintf (st, "3281 controller"); -return SCPE_OK; -} diff --git a/sigma/sigma_fp.c b/sigma/sigma_fp.c deleted file mode 100644 index a82f6516..00000000 --- a/sigma/sigma_fp.c +++ /dev/null @@ -1,421 +0,0 @@ -/* sigma_fp.c: XDS Sigma floating point simulator - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "sigma_defs.h" - -#define UFP_V_GUARD 4 -#define UFP_NORM (FP_NORM << UFP_V_GUARD) -#define UFP_CARRY (UFP_NORM << 4) -#define UFP_FRHI (UFP_CARRY|UFP_NORM|FP_M_FRHI) -#define UFP_FRLO 0xFFFFFFFF - -/* Double precision fraction add/subtract/compare */ -/* Note: UFP_ADD (s, r, r) will not work!!! */ - -#define UFP_ADD(s1,s2,d) do { \ - d.l = (s1.l + s2.l) & UFP_FRLO; \ - d.h = (s1.h + s2.h + (d.l < s2.l)) & UFP_FRHI; \ - } while (0) - -#define UFP_SUB(s1,s2,d) do { \ - d.h = (s1.h - s2.h - (s1.l < s2.l)) & UFP_FRHI; \ - d.l = (s1.l - s2.l) & UFP_FRLO; \ - } while (0) - -#define UFP_GE(s1,s2) ((s1.h > s2.h) || \ - ((s1.h == s2.h) && (s1.l >= s2.l))) - -/* Variable and constant shifts; for constants, 0 < k < 32 */ - -#define UFP_RSH_V(v,s) do { \ - if ((s) < 32) { \ - v.l = ((v.l >> (s)) | \ - ( v.h << (32 - (s)))) & UFP_FRLO; \ - v.h = v.h >> (s); \ - } \ - else if ((s) < 64) { \ - v.l = v.h >> ((s) - 32); \ - v.h = 0; \ - } \ - else v.l = v.h = 0; \ - } while (0) - -#define UFP_RSH_K(v,s) do { \ - v.l = ((v.l >> (s)) | \ - (v.h << (32 - (s)))) & UFP_FRLO; \ - v.h = v.h >> (s); \ - } while (0) - -#define UFP_LSH_K(v,s) do { \ - v.h = ((v.h << (s)) | \ - (v.l >> (32 - (s)))) & UFP_FRHI; \ - v.l = (v.l << (s)) & UFP_FRLO; \ - } while (0) - -#define UFP_RSH_KP(v,s) do { \ - v->l = ((v->l >> (s)) | \ - (v->h << (32 - (s)))) & UFP_FRLO; \ - v->h = v->h >> (s); \ - } while (0) - -#define UFP_LSH_KP(v,s) do { \ - v->h = ((v->h << (s)) | \ - (v->l >> (32 - (s)))) & UFP_FRHI; \ - v->l = (v->l << (s)) & UFP_FRLO; \ - } while (0) - -typedef struct { - uint32 sign; - int32 exp; - uint32 h; - uint32 l; - } ufp_t; - -extern uint32 *R; -extern uint32 PSW1; -extern uint32 CC; - -void fp_unpack (uint32 hi, uint32 lo, ufp_t *dst); -t_bool fp_clnzro (ufp_t *src, t_bool abnorm); -uint32 fp_pack (ufp_t *src, uint32 rn, t_bool dbl, t_bool rndtrap); -uint32 fp_norm (ufp_t *src); - -uint32 fp (uint32 op, uint32 rn, uint32 bva) -{ -uint32 rh, rl, mh, ml, i, ediff, nsh; -t_bool s1nz, s2nz; -t_bool dbl = ((op & 0x20) == 0); -ufp_t fop1, fop2, t; -ufp_t res = { 0, 0, 0, 0 }; -uint32 tr; - -if (dbl) { /* double prec? */ - rh = R[rn]; /* get reg operands */ - rl = R[rn|1]; - if ((tr = ReadD (bva, &mh, &ml, VR)) != 0) /* get mem word */ - return tr; - } -else { /* single precision */ - rh = R[rn]; /* pad to double */ - rl = 0; - if ((tr = ReadW (bva, &mh, VR)) != 0) - return tr; - ml = 0; - } -fp_unpack (rh, rl, &fop1); /* unpack, test */ -fp_unpack (mh, ml, &fop2); -CC = 0; - -switch (op) { /* case on opcode */ - - case OP_FSS: /* subtract */ - case OP_FSL: - fop2.sign = fop2.sign ^ 1; /* invert mem sign */ - /* fall through */ - case OP_FAS: /* add */ - case OP_FAL: - s1nz = fp_clnzro (&fop1, TRUE); /* test, clean op1 */ - s2nz = fp_clnzro (&fop2, TRUE); - if (!s1nz) /* op1 = 0? res = op2 */ - res = fop2; - else if (!s2nz) /* op2 = 0? res = op1 */ - res = fop1; - else { /* both non-zero */ - if (fop1.exp < fop2.exp) { /* exp1 < exp2? */ - t = fop2; /* swap operands */ - fop2 = fop1; - fop1 = t; - } - ediff = fop1.exp - fop2.exp; /* exp difference */ - res.sign = fop1.sign; /* result sign, exp */ - res.exp = fop1.exp; - if (ediff) { /* any difference? */ - UFP_RSH_V (fop2, ediff * 4); /* shift frac */ - if (dbl) { /* double? */ - if ((PSW1 & PSW1_FR) == 0) /* rounding off? */ - fop2.l &= ~0xF; /* no guard */ - } - else fop2.l = 0; /* single? clr lo */ - } - if (fop1.sign ^ fop2.sign) { /* eff subtract */ - if (UFP_GE (fop1, fop2)) { /* fop1 >= fop2? */ - UFP_SUB (fop1, fop2, res); /* sub fractions */ - } - else { /* fop2 > fop1 */ - UFP_SUB (fop2, fop1, res); /* rev subtract */ - res.sign = fop2.sign; /* change signs */ - } - } /* end subtract */ - else { /* eff add */ - UFP_ADD (fop1, fop2, res); /* add fractions */ - if (res.h & UFP_CARRY) { /* carry out? */ - UFP_RSH_K (res, 4); /* renormalize */ - res.exp = res.exp + 1; /* incr exp */ - } - } /* end add */ - } /* end nz operands */ - if (!dbl) /* single? clr lo */ - res.l = 0; - if ((PSW1 & PSW1_FN) == 0) { /* postnormalize? */ - if ((res.h | res.l) == 0) { /* result zero? */ - CC = CC1; /* set signif flag */ - if (PSW1 & PSW1_FS) /* trap enabled? */ - return TR_FLT; - return fp_pack (&res, rn, dbl, FALSE); /* pack up */ - } - nsh = fp_norm (&res); /* normalize */ - if ((res.exp < 0) && /* underflow? */ - !(PSW1 & PSW1_FZ) && /* !FN */ - (PSW1 & PSW1_FS) && /* FS */ - (nsh > 2)) { /* shifts > 2? */ - CC = CC1 | (res.sign? CC4: CC3); /* signif CC's */ - return TR_FLT; /* trap */ - } /* end if underflow */ - else if (nsh > 2) { /* shifts > 2? */ - CC |= CC1 | (res.sign? CC4: CC3); /* set CC1 */ - if (PSW1 & PSW1_FS) /* trap enabled? */ - return TR_FLT; - } - } /* end if postnorm */ - return fp_pack (&res, rn, dbl, TRUE); /* pack result */ - - case OP_FMS: - case OP_FML: /* floating multiply */ - s1nz = fp_clnzro (&fop1, FALSE); /* test, clean op1 */ - s2nz = fp_clnzro (&fop2, FALSE); - if (s1nz && s2nz) { /* both non-zero? */ - fp_norm (&fop1); /* prenormalize */ - fp_norm (&fop2); - UFP_RSH_K (fop2, 4); /* undo guard */ - res.sign = fop1.sign ^ fop2.sign; /* result sign */ - res.exp = fop1.exp + fop2.exp - FP_BIAS; /* result exp */ - if (!dbl) { /* 24b x 24b? */ - for (i = 0; i < 24; i++) { /* 24 iterations */ - if (fop2.h & 1) - res.h = res.h + fop1.h; /* add hi only */ - UFP_RSH_K (res, 1); /* shift dp res */ - fop2.h = fop2.h >> 1; - } - res.l = 0; /* single prec */ - } - else { /* some low 0's */ - for (i = 0; i < 56; i++) { /* 56 iterations */ - if (fop2.l & 1) { - UFP_ADD (res, fop1, res); - } - UFP_RSH_K (res, 1); - UFP_RSH_K (fop2, 1); - } - } - fp_norm (&res); /* normalize result */ - } - return fp_pack (&res, rn, dbl, TRUE); /* pack result */ - - case OP_FDS: - case OP_FDL: /* floating divide */ - s1nz = fp_clnzro (&fop1, FALSE); /* test, clean op1 */ - s2nz = fp_clnzro (&fop2, FALSE); - if (!s2nz) { /* divide by zero? */ - CC = CC2; /* set CC2 */ - return TR_FLT; /* trap */ - } - if (s1nz) { /* divd non-zero? */ - fp_norm (&fop1); /* prenormalize */ - fp_norm (&fop2); - res.sign = fop1.sign ^ fop2.sign; /* result sign */ - res.exp = fop1.exp - fop2.exp + FP_BIAS; /* result exp */ - if (!UFP_GE (fop1, fop2)) { - UFP_LSH_K (fop1, 4); /* ensure success */ - } - else res.exp = res.exp + 1; /* incr exponent */ - for (i = 0; i < (uint32)(dbl? 15: 7); i++) {/* 7/15 hex digits */ - UFP_LSH_K (res, 4); /* shift quotient */ - while (UFP_GE (fop1, fop2)) { /* while sub works */ - UFP_SUB (fop1, fop2, fop1); /* decrement */ - res.l = res.l + 1; /* add quo bit */ - } - UFP_LSH_K (fop1, 4); /* shift divd */ - } /* end hex loop */ - if (!dbl) { /* single? */ - res.h = res.l; /* move quotient */ - res.l = 0; - } - fp_norm (&res); /* normalize result */ - } - return fp_pack (&res, rn, dbl, TRUE); /* pack result */ - } /* end case */ - -return SCPE_IERR; -} - -void ShiftF (uint32 rn, uint32 stype, uint32 sc) -{ -uint32 opnd, opnd1; -ufp_t src; - -opnd = R[rn]; /* get operands */ -opnd1 = stype? R[rn|1]: 0; /* zextend single */ -fp_unpack (opnd, opnd1, &src); /* unpack */ - -CC = 0; -if (sc & SCSIGN) { /* right? */ - sc = SHF_M_SC + 1 - sc; - while (sc > 0) { /* while count */ - UFP_RSH_K (src, 4); /* shift right hex */ - if (stype) /* zero guard */ - src.l &= ~0xF; - else src.h &= ~0xF; - src.exp++; /* incr exp */ - sc--; - if (src.exp > FP_M_EXP) { /* overflow? */ - CC |= CC2; /* set CC2, stop */ - break; - } - } /* end while */ - if ((src.h | src.l) == 0) { /* result 0? */ - if (stype) /* result is true 0 */ - R[rn|1] = 0; - R[rn] = 0; - CC = 0; - return; - } - } -else { /* left */ - if ((src.h | src.l) == 0) { /* fraction 0? */ - if (stype) /* result is true 0 */ - R[rn|1] = 0; - R[rn] = 0; - CC = CC1; - return; - } - while ((sc > 0) && ((src.h & UFP_NORM) == 0)) { /* while count & !norm */ - UFP_LSH_K (src, 4); /* hex shift left */ - src.exp--; /* decr exp */ - sc--; - if (src.exp < 0) { /* underflow? */ - CC |= CC2; /* set CC2, stop */ - break; - } - } /* end while */ - if (src.h & UFP_NORM) /* normalized? */ - CC |= CC1; /* set CC1 */ - } -fp_pack (&src, rn, stype, FALSE); /* pack result */ -return; -} - -void fp_unpack (uint32 hi, uint32 lo, ufp_t *dst) -{ -dst->sign = FP_GETSIGN (hi); /* get sign */ -if (dst->sign) /* negative? */ - NEG_D (hi, lo); /* 2's compl */ -dst->h = FP_GETFRHI (hi); /* get fraction */ -dst->l = FP_GETFRLO (lo); -dst->exp = FP_GETEXP (hi); /* get exp */ -UFP_LSH_KP (dst, 4); /* guard result */ -return; -} - -/* Test for and clean a floating point zero - abnorm defines whether to allow "abnormal" zeros */ - -t_bool fp_clnzro (ufp_t *src, t_bool abnorm) -{ -if (((src->h | src->l) == 0) && /* frac zero and */ - (!abnorm || (src->exp == 0))) { /* exp zero or !ab */ - src->sign = 0; /* true zero */ - src->exp = 0; - return FALSE; - } -return TRUE; /* non-zero */ -} - -uint32 fp_pack (ufp_t *src, uint32 rn, t_bool dbl, t_bool rndtrap) -{ -static ufp_t fp_zero = { 0, 0, 0, 0}; -uint32 opnd, opnd1; - -if (src->h || (dbl && src->l)) { /* result != 0? */ - CC |= (src->sign? CC4: CC3); /* set CC's */ - if (rndtrap) { /* round, trap? */ - if (PSW1 & PSW1_FR) { /* round? */ - if (dbl) { /* double prec? */ - src->l = (src->l + 0x8) & UFP_FRLO; - src->h = src->h + (src->l < 0x8); - } - else src->h = src->h + 0x8; /* no, single */ - if (src->h & UFP_CARRY) { /* carry out? */ - UFP_RSH_KP (src, 4); /* renormalize */ - src->exp = src->exp + 1; - } - } /* end if round */ - if (src->exp > FP_M_EXP) { /* overflow? */ - CC |= CC2; /* flag */ - return TR_FLT; - } - else if (src->exp < 0) { /* underflow? */ - if (PSW1 & PSW1_FZ) { /* trap enabled? */ - CC |= CC1 | CC2; /* flag */ - return TR_FLT; - } - *src = fp_zero; /* result 0 */ - CC = CC1|CC2; /* special CC's */ - } - } /* end rnd trap */ - UFP_RSH_KP (src, 4); /* remove guard */ - if (!dbl) /* single? lose lower */ - src->l = 0; - if ((src->h | src->l) == 0) /* result now 0? */ - src->exp = src->sign = 0; - } -else *src = fp_zero; -opnd = ((src->exp & FP_M_EXP) << FP_V_EXP) | /* repack */ - ((src->h & FP_M_FRHI) << FP_V_FRHI); -opnd1 = src->l & FP_M_FRLO; -if (src->sign) /* negative? */ - NEG_D (opnd, opnd1); -R[rn] = opnd; /* store result */ -if (dbl && ((rn & 1) == 0)) - R[rn|1] = opnd1; -return 0; -} - -uint32 fp_norm (ufp_t *src) -{ -uint32 nsh; - -nsh = 0; -src->h &= UFP_FRHI; -if (src->h || src->l) { /* if non-zero */ - while ((src->h & UFP_NORM) == 0) { /* until normalized */ - UFP_LSH_KP (src, 4); /* hex shift left */ - src->exp--; /* decr exponent */ - nsh++; /* count shifts */ - } - } -return nsh; -} - diff --git a/sigma/sigma_io.c b/sigma/sigma_io.c deleted file mode 100644 index f1193069..00000000 --- a/sigma/sigma_io.c +++ /dev/null @@ -1,1497 +0,0 @@ -/* sigma_io.c: XDS Sigma IO simulator - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "sigma_io_defs.h" - -#define VALID_DVA(c,d) \ - (((c) < chan_num) && ((d) < CHAN_N_DEV) && (chan[c].disp[d] != NULL)) - -uint32 int_hiact = NO_INT; /* hi act int */ -uint32 int_hireq = NO_INT; /* hi int req */ -uint32 chan_ctl_time = 5; -uint32 ei_bmax = EIGRP_DFLT; /* ext int grps */ -uint32 s9_snap = 0; -uint32 s9_marg = 0; -uint32 chan_num = CHAN_DFLT; /* num chan */ -uint32 s5x0_ireg[] = { 0 }; -uint16 int_arm[INTG_MAX]; /* int grps: arm */ -uint16 int_enb[INTG_MAX]; /* enable */ -uint16 int_req[INTG_MAX]; /* request */ -uint8 int_lnk[INTG_MAX] = { /* pri chain */ - INTG_OVR, INTG_CTR, INTG_IO, 0 - }; - -/* Interrupt group priority chain templates */ - -#define I_STD 0x80 - -static uint8 igrp_dflt_5x0[] = { - I_STD|INTG_OVR, I_STD|INTG_CTR, I_STD|INTG_IO, INTG_E2, - INTG_E3, INTG_E3+1, INTG_E3+2, 0 - }; - -static uint8 igrp_dflt_S56789[] = { - I_STD|INTG_OVR, I_STD|INTG_CTR, I_STD|INTG_IO, INTG_E2, - INTG_E3, INTG_E3+1, INTG_E3+2, INTG_E3+3, - INTG_E3+4, INTG_E3+5, INTG_E3+6, INTG_E3+7, - INTG_E3+9, INTG_E3+9, INTG_E3+10, INTG_E3+11, - INTG_E3+12, 0 - }; - -chan_t chan[CHAN_N_CHAN]; -uint32 (*dio_disp[DIO_N_MOD])(uint32, uint32, uint32); - -int_grp_t int_tab[INTG_MAX] = { -/* PSW inh #bits vec grp regbit */ - { 0, 6, 0x052, 0x0, 16 }, - { PSW2_CI, 4, 0x058, 0x0, 22 }, - { PSW2_II, 2, 0x05C, 0x0, 26 }, - { PSW2_EI, 16, 0x060, 0x2, 16 }, - { PSW2_EI, 16, 0x070, 0x3, 16 }, - { PSW2_EI, 16, 0x080, 0x4, 16 }, - { PSW2_EI, 16, 0x090, 0x5, 16 }, - { PSW2_EI, 16, 0x0A0, 0x6, 16 }, - { PSW2_EI, 16, 0x0B0, 0x7, 16 }, - { PSW2_EI, 16, 0x0C0, 0x8, 16 }, - { PSW2_EI, 16, 0x0D0, 0x9, 16 }, - { PSW2_EI, 16, 0x0E0, 0xA, 16 }, - { PSW2_EI, 16, 0x0F0, 0xB, 16 }, - { PSW2_EI, 16, 0x100, 0xC, 16 }, - { PSW2_EI, 16, 0x110, 0xD, 16 }, - { PSW2_EI, 16, 0x120, 0xE, 16 }, - { PSW2_EI, 16, 0x130, 0xF, 16 } - }; - -extern uint32 *R; -extern uint32 PSW1, PSW2; -extern uint32 CC, SSW; -extern uint32 stop_op; -extern uint32 cpu_model; -extern uint32 cons_alarm, cons_pcf; -extern UNIT cpu_unit; -extern cpu_var_t cpu_tab[]; -extern DEVICE *sim_devices[]; -extern FILE *sim_log; - -void io_eval_ioint (void); -t_bool io_init_inst (uint32 ad, uint32 rn, uint32 ch, uint32 dev, uint32 r0); -uint32 io_set_status (uint32 rn, uint32 ch, uint32 dev, uint32 dvst, t_bool tdv); -uint32 io_rwd_m0 (uint32 op, uint32 rn, uint32 ad); -uint32 io_rwd_m1 (uint32 op, uint32 rn, uint32 ad); -t_stat io_set_eiblks (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat io_show_eiblks (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat int_reset (DEVICE *dptr); -t_stat chan_reset (DEVICE *dptr); -uint32 chan_new_cmd (uint32 ch, uint32 dev, uint32 clc); -void io_set_eimax (uint32 max); -uint32 chan_proc_prolog (uint32 dva, uint32 *ch, uint32 *dev); -uint32 chan_proc_epilog (uint32 dva, int32 cnt); - -extern uint32 cpu_new_PSD (uint32 lrp, uint32 p1, uint32 p2); - -/* IO data structures - - io_dev IO device descriptor - io_unit IO unit - io_reg IO register list - io_mod IO modifier list -*/ - -dib_t int_dib = { 0, NULL, 1, io_rwd_m1 }; - -UNIT int_unit = { UDATA (NULL, 0, 0) }; - -REG int_reg[] = { - { HRDATA (IHIACT, int_hiact, 9) }, - { HRDATA (IHIREQ, int_hireq, 9) }, - { BRDATA (IREQ, int_req, 16, 16, INTG_MAX) }, - { BRDATA (IENB, int_enb, 16, 16, INTG_MAX) }, - { BRDATA (IARM, int_arm, 16, 16, INTG_MAX) }, - { BRDATA (ILNK, int_lnk, 10, 8, INTG_MAX), REG_HRO }, - { DRDATA (EIBLKS, ei_bmax, 4), REG_HRO }, - { HRDATA (S9_SNAP, s9_snap, 32) }, - { HRDATA (S9_MARG, s9_marg, 32) }, - { BRDATA (S5X0_IREG, s5x0_ireg, 16, 32, 32) }, - { NULL } - }; - -MTAB int_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "EIBLKS", "EIBLKS", - &io_set_eiblks, &io_show_eiblks }, - { 0 } - }; - -DEVICE int_dev = { - "INT", &int_unit, int_reg, int_mod, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &int_reset, - NULL, NULL, NULL, - &int_dib, 0 - }; - -/* Channel data structures */ - -UNIT chan_unit[] = { - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) }, - { UDATA (NULL, 0, 0) } - }; - -REG chana_reg[] = { - { BRDATA (CLC, chan[0].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[0].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[0].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[0].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[0].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[0].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[0].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[0].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chanb_reg[] = { - { BRDATA (CLC, chan[1].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[1].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[1].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[1].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[1].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[1].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[1].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[1].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chanc_reg[] = { - { BRDATA (CLC, chan[2].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[2].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[2].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[2].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[2].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[2].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[2].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[2].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chand_reg[] = { - { BRDATA (CLC, chan[3].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[3].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[3].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[3].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[3].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[3].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[3].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[3].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chane_reg[] = { - { BRDATA (CLC, chan[4].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[4].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[4].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[4].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[4].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[4].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[4].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[4].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chanf_reg[] = { - { BRDATA (CLC, chan[5].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[5].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[5].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[5].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[5].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[5].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[5].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[5].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chang_reg[] = { - { BRDATA (CLC, chan[6].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[6].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[6].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[6].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[6].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[6].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[6].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[6].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -REG chanh_reg[] = { - { BRDATA (CLC, chan[7].clc, 16, 20, CHAN_N_DEV) }, - { BRDATA (CMD, chan[7].cmd, 16, 8, CHAN_N_DEV) }, - { BRDATA (CMF, chan[7].cmf, 16, 8, CHAN_N_DEV) }, - { BRDATA (BA, chan[7].ba, 16, 24, CHAN_N_DEV) }, - { BRDATA (BC, chan[7].bc, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHF, chan[7].chf, 16, 16, CHAN_N_DEV) }, - { BRDATA (CHI, chan[7].chi, 16, 8, CHAN_N_DEV) }, - { BRDATA (CHSF, chan[7].chsf, 16, 8, CHAN_N_DEV) }, - { NULL } - }; - -DEVICE chan_dev[] = { - { - "CHANA", &chan_unit[0], chana_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_MIOP, 0 - }, - { - "CHANB", &chan_unit[1], chanb_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_MIOP, 0 - }, - { - "CHANC", &chan_unit[2], chanc_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_SIOP, 0 - }, - { - "CHAND", &chan_unit[3], chand_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_SIOP, 0 - }, - { - "CHANE", &chan_unit[4], chane_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_SIOP|DEV_DIS, 0 - }, - { - "CHANF", &chan_unit[5], chanf_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_SIOP|DEV_DIS, 0 - }, - { - "CHANG", &chan_unit[6], chang_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_SIOP|DEV_DIS, 0 - }, - { - "CHANH", &chan_unit[7], chanh_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &chan_reset, - NULL, NULL, NULL, - NULL, CHAN_SIOP|DEV_DIS, 0 - } - }; - - -/* Read direct */ - -uint32 io_rwd (uint32 op, uint32 rn, uint32 bva) -{ -uint32 ad = bva >> 2; -uint32 mode = DIO_GETMOD (ad); /* mode */ - -if (dio_disp[mode] != NULL) /* if defined */ - return dio_disp[mode] (op, rn, ad); /* dispatch */ -return (stop_op)? STOP_ILLEG: 0; /* ill inst */ -} - -/* Start IO */ - -uint32 io_sio (uint32 rn, uint32 bva) -{ -uint32 ad = bva >> 2; -uint32 ch, dev, dvst; -uint32 st; - -CC &= ~cpu_tab[cpu_model].iocc; /* clear CC's */ -ch = DVA_GETCHAN (ad); /* get chan, dev */ -dev = DVA_GETDEV (ad); -if (!io_init_inst (rn, ad, ch, dev, R[0])) { /* valid inst? */ - CC |= CC1|CC2; - return 0; - } -if (chan[ch].chf[dev] & CHF_INP) { /* int pending? */ - chan[ch].disp[dev] (OP_TIO, ad, &dvst); /* get status */ - CC |= (CC2 | io_set_status (rn, ch, dev, dvst, 0)); /* set status */ - return 0; - } -st = chan[ch].disp[dev] (OP_SIO, ad, &dvst); /* start I/O */ -CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */ -if (CC & cpu_tab[cpu_model].iocc) /* error? */ - return 0; -chan[ch].chf[dev] = 0; /* clear flags */ -chan[ch].chi[dev] = 0; /* clear intrs */ -chan[ch].chsf[dev] |= CHSF_ACT; /* set chan active */ -chan_new_cmd (ch, dev, R[0]); /* new command */ -return st; -} - -/* Test IO */ - -uint32 io_tio (uint32 rn, uint32 bva) -{ -uint32 ad = bva >> 2; -uint32 ch, dev, dvst; -uint32 st; - -CC &= ~cpu_tab[cpu_model].iocc; /* clear CC's */ -ch = DVA_GETCHAN (ad); /* get chan, dev */ -dev = DVA_GETDEV (ad); -if (!io_init_inst (rn, ad, ch, dev, 0)) { /* valid inst? */ - CC |= CC1|CC2; - return 0; - } -st = chan[ch].disp[dev] (OP_TIO, ad, &dvst); /* test status */ -CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */ -return st; -} - -/* Test device status */ - -uint32 io_tdv (uint32 rn, uint32 bva) -{ -uint32 ad = bva >> 2; -uint32 ch, dev, dvst; -uint32 st; - -CC &= ~cpu_tab[cpu_model].iocc; /* clear CC's */ -ch = DVA_GETCHAN (ad); /* get chan, dev */ -dev = DVA_GETDEV (ad); -if (!io_init_inst (rn, ad, ch, dev, 0)) { /* valid inst? */ - CC |= CC1|CC2; - return 0; - } -st = chan[ch].disp[dev] (OP_TDV, ad, &dvst); /* test status */ -CC |= io_set_status (rn, ch, dev, dvst, 1); /* set status */ -return st; -} - -/* Halt IO */ - -uint32 io_hio (uint32 rn, uint32 bva) -{ -uint32 ad = bva >> 2; -uint32 ch, dev, subop, dvst; -uint32 st; - -CC &= ~cpu_tab[cpu_model].iocc; -ad = bva >> 2; -ch = DVA_GETCHAN (ad); /* get chan, dev */ -dev = DVA_GETDEV (ad); -subop = (ad >> 13) & 0x7; -if (subop) { /* extended fnc? */ - if (!QCPU_S89_5X0 || (subop > 3)) /* S9, 5X0 only */ - return (stop_op? STOP_ILLEG: 0); - if (ch >= chan_num) { /* valid channel? */ - CC |= CC1|CC2; - return 0; - } - switch (subop) { - - case 1: /* reset channel */ - chan_reset (&chan_dev[ch]); - break; - - case 2: case 3: /* poll processor */ - if (rn) /* NI */ - R[rn] = 0; - break; - } - } -else { /* normal HIO */ - if (!io_init_inst (rn, ad, ch, dev, 0)) { /* valid inst? */ - CC |= CC1|CC2; - return 0; - } - st = chan[ch].disp[dev] (OP_HIO, ad, &dvst); /* halt IO */ - CC |= io_set_status (rn, ch, dev, dvst, 0); /* set status */ - } -return st; -} - -/* Acknowledge interrupt (ignores device address) */ - -uint32 io_aio (uint32 rn, uint32 bva) -{ -uint32 i, j, dva, dvst; -uint32 st; - -if (DVA_GETCHAN (bva >> 2) != 0) /* non std I/O addr? */ - return (stop_op? STOP_ILLEG: 0); -CC = CC & ~cpu_tab[cpu_model].iocc; /* clear CC's */ -for (i = 0; i < chan_num; i++) { /* loop thru chan */ - for (j = 0; j < CHAN_N_DEV; j++) { /* loop thru dev */ - if (chan[i].chf[j] & CHF_INP) { /* intr pending? */ - if (chan[i].disp[j] == NULL) { /* false interrupt? */ - chan[i].chf[j] &= ~CHF_INP; /* clear intr */ - continue; - } - dva = (i << DVA_V_CHAN) | /* chan number */ - ((chan[i].chsf[j] & CHSF_MU)? /* device number */ - ((j << DVA_V_DEVMU) | DVA_MU): - (j << DVA_V_DEVSU)); - st = chan[i].disp[j] (OP_AIO, dva, &dvst); /* get AIO status */ - dva |= DVT_GETUN (dvst); /* finish dev addr */ - if (rn) /* want status? */ - R[rn] = (DVT_GETDVS (dvst) << 24) | /* device status */ - ((uint32) ((chan[i].chf[j] & (CHF_LNTE|CHF_XMDE)) | - CHI_GETINT (chan[i].chi[j])) << 16) | dva; - if (chan[i].chi[j] & CHI_UEN) /* unusual end? */ - CC |= CC2; /* set CC2 */ - return st; - } - } /* end for dev */ - } /* end for chan */ -CC |= CC1|CC2; /* no recognition */ -return 0; -} - -/* Initiate I/O instruction */ - -t_bool io_init_inst (uint32 rn, uint32 ad, uint32 ch, uint32 dev, uint32 r0) -{ -uint32 loc20; - -if (ch >= chan_num) /* bad chan? */ - return FALSE; -loc20 = ((ad & 0xFF) << 24) | /* <0:7> = dev ad */ - ((rn & 1) | (rn? 3: 0) << 22) | /* <8:9> = reg ind */ - (r0 & (cpu_tab[cpu_model].pamask >> 1)); /* <14/16:31> = r0 */ -WritePW (0x20, loc20); -return (chan[ch].disp[dev] != NULL)? TRUE: FALSE; -} - -/* Set status for I/O instruction */ - -uint32 io_set_status (uint32 rn, uint32 ch, uint32 dev, uint32 dvst, t_bool tdv) -{ -uint32 mrgst; -uint32 odd = rn & 1; - -if ((rn != 0) && !(dvst & DVT_NOST)) { /* return status? */ - if (tdv) - mrgst = (DVT_GETDVS (dvst) << 8) | (chan[ch].chf[dev] & 0xFF); - else mrgst = ((DVT_GETDVS(dvst) << 8) & ~CHF_ALL) | (chan[ch].chf[dev] & CHF_ALL); - R[rn] = chan[ch].clc[dev]; /* even reg */ - if (!odd) /* even pair? */ - WritePW (0x20, R[rn]); /* write to 20 */ - R[rn|1] = (mrgst << 16) | chan[ch].bc[dev]; /* odd reg */ - WritePW (0x20 + odd, R[rn|1]); /* write to 20/21 */ - } -return DVT_GETCC (dvst); -} - -/* Channel support routines */ - -/* Get new command */ - -uint32 chan_get_cmd (uint32 dva, uint32 *cmd) -{ -uint32 ch, dev; -t_stat st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -*cmd = chan[ch].cmd[dev]; /* return cmd */ -return 0; -} - -/* Channel end */ - -uint32 chan_end (uint32 dva) -{ -uint32 ch, dev; -uint32 st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -if (chan[ch].cmf[dev] & CMF_ICE) /* int on chan end? */ - chan_set_chi (dva, CHI_END); -if ((chan[ch].cmf[dev] & CMF_CCH) && /* command chain? */ - !chan_new_cmd (ch, dev, chan[ch].clc[dev] + 1)) /* next command? */ - return CHS_CCH; -else chan[ch].chsf[dev] &= ~CHSF_ACT; /* channel inactive */ -return 0; -} - -/* Channel error */ - -uint32 chan_set_chf (uint32 dva, uint32 fl) -{ -uint32 ch, dev; - -ch = DVA_GETCHAN (dva); /* get chan, dev */ -dev = DVA_GETDEV (dva); -if (!VALID_DVA (ch, dev)) /* valid? */ - return SCPE_IERR; -fl &= ~CHF_INP; /* ignore int pend */ -chan[ch].chf[dev] |= fl; -if ((fl & CHF_LNTE) && /* length error */ - ((chan[ch].cmf[dev] & CMF_SIL) || /* suppressed? */ - !(chan[ch].cmf[dev] & CMF_HTE))) /* or don't stop? */ - fl &= ~CHF_LNTE; /* ignore it */ -if ((fl & CHF_XMDE) && /* data error? */ - !(chan[ch].cmf[dev] & CMF_HTE)) /* don't stop? */ - fl &= ~CHF_XMDE; /* ignore it */ -if ((fl & CHF_XMME) && /* memory error? */ - !(chan[ch].cmf[dev] & CMF_HTE)) /* don't stop? */ - fl &= ~CHF_XMME; /* ignore it */ -if (fl) /* fatal error? */ - return chan_uen (dva); /* unusual end */ -return 0; -} - -/* Channel test command flags */ - -t_bool chan_tst_cmf (uint32 dva, uint32 fl) -{ -uint32 ch, dev; - -ch = DVA_GETCHAN (dva); /* get chan, dev */ -dev = DVA_GETDEV (dva); -if (VALID_DVA (ch, dev) && /* valid? */ - (chan[ch].cmf[dev] & fl)) - return TRUE; -return FALSE; -} - -/* Channel unusual end */ - -uint32 chan_uen (uint32 dva) -{ -uint32 ch, dev; - -ch = DVA_GETCHAN (dva); /* get chan, dev */ -dev = DVA_GETDEV (dva); -if (!VALID_DVA (ch, dev)) /* valid? */ - return SCPE_IERR; -if (chan[ch].cmf[dev] & CMF_IUE) /* int on uend? */ - chan_set_chi (dva, CHI_UEN); -chan[ch].chf[dev] |= CHF_UEN; /* flag uend */ -chan[ch].chsf[dev] &= ~CHSF_ACT; -return CHS_INACTV; /* done */ -} - -/* Channel read processes */ - -uint32 chan_RdMemB (uint32 dva, uint32 *dat) -{ -uint32 ch, dev; -uint32 st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -if (chan[ch].cmf[dev] & CMF_SKP) /* skip? */ - *dat = 0; -else if (ReadPB (chan[ch].ba[dev], dat)) { /* read data, nxm? */ - chan[ch].chf[dev] |= CHF_XMAE; /* addr error */ - return CHS_NXM; /* dev will uend */ - } -return chan_proc_epilog (dva, 1); /* adjust counts */ -} - -uint32 chan_RdMemW (uint32 dva, uint32 *dat) -{ -uint32 ch, dev; -uint32 st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -if (chan[ch].cmf[dev] & CMF_SKP) /* skip? */ - *dat = 0; -else if ((chan[ch].bc[dev] < 4) || /* unaligned? */ - ((chan[ch].ba[dev] & 0x3) != 0)) { - uint32 i, wd; - for (i = 0, *dat = 0, wd = 0; i < 4; i++) { /* up to 4 bytes */ - st = chan_RdMemB (dva, &wd); /* get byte */ - *dat |= ((wd & 0xFF) << (24 - (i * 8))); /* pack */ - if (st != 0) /* stop if error */ - return st; - } - return 0; - } -else if (ReadPW (chan[ch].ba[dev] >> 2, dat)) { /* read word, nxm? */ - chan[ch].chf[dev] |= CHF_XMAE; /* addr error */ - return CHS_NXM; /* dev will uend */ - } -return chan_proc_epilog (dva, 4); /* adjust counts */ -} - -/* Channel write processes */ - -uint32 chan_WrMemB (uint32 dva, uint32 dat) -{ -uint32 ch, dev; -uint32 st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -if (((chan[ch].cmf[dev] & CMF_SKP) == 0) && /* skip? */ - WritePB (chan[ch].ba[dev], dat)) { /* write data, nxm? */ - chan[ch].chf[dev] |= CHF_XMAE; /* addr error */ - return CHS_NXM; /* dev will uend */ - } -return chan_proc_epilog (dva, 1); /* adjust counts */ -} - -uint32 chan_WrMemBR (uint32 dva, uint32 dat) -{ -uint32 ch, dev; -uint32 st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -if (((chan[ch].cmf[dev] & CMF_SKP) == 0) && /* skip? */ - WritePB (chan[ch].ba[dev], dat)) { /* write data, nxm? */ - chan[ch].chf[dev] |= CHF_XMAE; /* addr error */ - return CHS_NXM; /* dev will uend */ - } -return chan_proc_epilog (dva, -1); /* adjust counts */ -} - -uint32 chan_WrMemW (uint32 dva, uint32 dat) -{ -uint32 ch, dev; -uint32 st; - -if ((st = chan_proc_prolog (dva, &ch, &dev)) != 0) /* valid, active? */ - return st; -if ((chan[ch].bc[dev] < 4) || /* unaligned? */ - ((chan[ch].ba[dev] & 0x3) != 0)) { - uint32 i, wd; - for (i = 0; i < 4; i++) { /* up to 4 bytes */ - wd = (dat >> (24 - (i * 8))) & 0xFF; /* get byte */ - if ((st = chan_WrMemB (dva, wd)) != 0) /* write */ - return st; /* stop if error */ - } - return 0; - } -if (((chan[ch].cmf[dev] & CMF_SKP) == 0) && /* skip? */ - WritePW (chan[ch].ba[dev] >> 2, dat)) { /* write word, nxm? */ - chan[ch].chf[dev] |= CHF_XMAE; /* addr error */ - return CHS_NXM; /* dev will uend */ - } -return chan_proc_epilog (dva, 4); /* adjust counts */ -} - -/* Channel process common code */ - -uint32 chan_proc_prolog (uint32 dva, uint32 *ch, uint32 *dev) -{ -*ch = DVA_GETCHAN (dva); /* get chan, dev */ -*dev = DVA_GETDEV (dva); -if (!VALID_DVA (*ch, *dev)) /* valid? */ - return SCPE_IERR; -if ((chan[*ch].chsf[*dev] & CHSF_ACT) == 0) /* active? */ - return CHS_INACTV; -return 0; -} - -uint32 chan_proc_epilog (uint32 dva, int32 cnt) -{ -uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */ -uint32 dev = DVA_GETDEV (dva); - -chan[ch].ba[dev] = (chan[ch].ba[dev] + cnt) & CHBA_MASK; -chan[ch].bc[dev] = (chan[ch].bc[dev] - abs (cnt)) & CHBC_MASK; -if (chan[ch].bc[dev] != 0) /* more to do? */ - return 0; -if (chan[ch].cmf[dev] & CMF_IZC) /* int on zero?*/ - chan_set_chi (dva, CHI_ZBC); -if (chan[ch].cmf[dev] & CMF_DCH) { /* data chaining? */ - if (chan_new_cmd (ch, dev, chan[ch].clc[dev] + 1)) - return CHS_ZBC; - return 0; - } -return CHS_ZBC; -} - -/* New channel command */ - -uint32 chan_new_cmd (uint32 ch, uint32 dev, uint32 clc) -{ -uint32 i, ccw1, ccw2, cmd; - -for (i = 0; i < 2; i++) { /* max twice */ - clc = clc & (cpu_tab[cpu_model].pamask >> 1); /* mask clc */ - chan[ch].clc[dev] = clc; /* and save */ - if (ReadPW (clc << 1, &ccw1)) { /* get ccw1, nxm? */ - chan[ch].chf[dev] |= CHF_IOME; /* memory error */ - chan[ch].chsf[dev] &= ~CHSF_ACT; /* stop channel */ - return CHS_INACTV; - } - ReadPW ((clc << 1) + 1, &ccw2); /* get ccw2 */ - cmd = CCW1_GETCMD (ccw1); /* get chan cmd */ - if ((cmd & 0xF) == CMD_TIC) /* transfer? */ - clc = ccw1; /* try again */ - else { - chan[ch].cmd[dev] = cmd; /* decompose CCW */ - chan[ch].ba[dev] = CCW1_GETBA (ccw1); - chan[ch].cmf[dev] = CCW2_GETCMF (ccw2); - chan[ch].bc[dev] = CCW2_GETBC (ccw2); - return 0; - } - } -chan[ch].chf[dev] |= CHF_IOCE; /* control error */ -chan[ch].chsf[dev] &= ~CHSF_ACT; /* stop channel */ -return CHS_INACTV; -} - -/* Set, clear, test channel interrupt */ - -void chan_set_chi (uint32 dva, uint32 fl) -{ -uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */ -uint32 dev = DVA_GETDEV (dva); -uint32 un = DVA_GETUNIT (dva); /* get unit */ - -chan[ch].chf[dev] |= CHF_INP; /* int pending */ -chan[ch].chi[dev] = (chan[ch].chi[dev] & CHI_FLAGS) | /* update status */ - fl | CHI_CTL | un; /* save unit */ -return; -} - -int32 chan_clr_chi (uint32 dva) -{ -uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */ -uint32 dev = DVA_GETDEV (dva); -uint32 old_chi = chan[ch].chi[dev]; - -chan[ch].chf[dev] &= ~CHF_INP; /* clr int pending */ -chan[ch].chi[dev] &= CHI_FLAGS; /* clr ctl int */ -if (old_chi & CHI_CTL) - return CHI_GETUN (old_chi); -else return -1; -} - -int32 chan_chk_chi (uint32 dva) -{ -uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */ -uint32 dev = DVA_GETDEV (dva); - -if (chan[ch].chi[dev] & CHI_CTL) /* ctl int pending? */ - return CHI_GETUN (chan[ch].chi[dev]); -else return -1; -} - -/* Set device interrupt */ - -void chan_set_dvi (uint32 dva) -{ -uint32 ch = DVA_GETCHAN (dva); /* get ch, dev */ -uint32 dev = DVA_GETDEV (dva); - -chan[ch].chf[dev] |= CHF_INP; /* int pending */ -return; -} - -/* Called by device reset to reset channel registers */ - -t_stat chan_reset_dev (uint32 dva) -{ -uint32 ch, dev; - -ch = DVA_GETCHAN (dva); /* get chan, dev */ -dev = DVA_GETDEV (dva); -if (!VALID_DVA (ch, dev)) /* valid? */ - return SCPE_IERR; -chan[ch].chf[dev] &= ~CHF_INP; /* clear intr */ -chan[ch].chsf[dev] &= ~CHSF_ACT; /* clear active */ -return SCPE_OK; -} - -/* Find highest priority pending interrupt - Question: must an interrupt be armed to be recognized? - Answer: yes; req'arm = 11 signifies waiting state */ - -uint32 io_eval_int (void) -{ -uint32 i, j, t, curr, mask, newi; - -if (int_arm[INTG_IO] & INTGIO_IO) /* I/O armed? */ - io_eval_ioint (); /* eval I/O interrupt */ -for (i = 0, curr = 0; i < INTG_MAX; i++) { /* loop thru groups */ - t = int_req[curr] & int_arm[curr] & int_enb[curr]; /* req, armed, enb */ - if ((t != 0) && /* any waiting req? */ - ((PSW2 & int_tab[curr].psw2_inh) == 0)) { /* group not inh? */ - for (j = 0; j < int_tab[curr].nbits; j++) { /* loop thru reqs */ - mask = 1u << (int_tab[curr].nbits - j - 1); - if (t & mask) { /* request active? */ - newi = INTV (curr, j); /* get int number */ - if (newi < int_hiact) /* higher priority? */ - return newi; /* new highest actv */ - return NO_INT; /* no pending intr */ - } - } - printf ("%%int eval consistency error = %X\r\n", t); - int_req[curr] = 0; /* "impossible" */ - } - if (curr == INT_GETGRP (int_hiact)) /* at active group? */ - return NO_INT; /* no pending intr */ - curr = int_lnk[curr]; /* next group */ - if (curr == 0) /* end of list? */ - return NO_INT; /* no pending intr */ - } -printf ("%%int eval consistency error, list end not found\r\n"); -return NO_INT; -} - -/* See if any interrupt is possible (used by WAIT) */ - -t_bool io_poss_int (void) -{ -uint32 i, curr; - -for (i = 0, curr = 0; i < INTG_MAX; i++) { /* loop thru groups */ - if (((int_arm[curr] & int_enb[curr]) != 0) && - ((PSW2 & int_tab[curr].psw2_inh) == 0)) /* group not inh? */ - return TRUE; /* int can occur */ - curr = int_lnk[curr]; /* next group */ - if (curr == 0) /* end of list? */ - return FALSE; /* no int possible */ - } -printf ("%%int possible consistency error, list end not found\r\n"); -return FALSE; -} - -/* Evaluate I/O interrupts */ - -void io_eval_ioint (void) -{ -uint32 i, j; - -for (i = 0; i < chan_num; i++) { /* loop thru chan */ - for (j = 0; j < CHAN_N_DEV; j++) { /* loop thru dev */ - if (chan[i].chf[j] & CHF_INP) { /* intr pending? */ - int_req[INTG_IO] |= INTGIO_IO; /* set I/O intr */ - return; - } /* end if int pend */ - } /* end for dev */ - } /* end for chan */ -return; -} - -/* Find highest priority active interrupt - Question: is an inhibited or disabled interrupt recognized? - Answer: yes; req'arm = 10 signifies active state */ - -uint32 io_actv_int (void) -{ -uint32 i, j, t, curr, mask; - -for (i = 0, curr = 0; i < INTG_MAX; i++) { /* loop thru groups */ - if ((t = int_req[curr] & ~int_arm[curr]) != 0) { /* req active? */ - for (j = 0; j < int_tab[curr].nbits; j++) { /* loop thru reqs */ - mask = 1u << (int_tab[curr].nbits - j - 1); - if (t & mask) /* req active? */ - return INTV (curr, j); /* return int num */ - } - printf ("%%int actv consistency error = %X\r\n", t); - int_req[curr] = 0; /* "impossible" */ - } - curr = int_lnk[curr]; /* next group */ - if (curr == 0) /* end of list? */ - return NO_INT; /* no pending interupt */ - } -printf ("%%int actv consistency error, list end not found\r\n"); -return NO_INT; -} - -/* Acknowledge interrupt and get vector */ - -uint32 io_ackn_int (uint32 hireq) -{ -uint32 grp, bit, mask; - -if (hireq >= NO_INT) /* none pending? */ - return 0; -grp = INT_GETGRP (hireq); /* get grp, bit */ -bit = INT_GETBIT (hireq); -if (bit >= int_tab[grp].nbits) { /* validate bit */ - printf ("%%int ack consistency error, hireq=%X\r\n", hireq); - return 0; - } -mask = 1u << (int_tab[grp].nbits - bit - 1); -int_arm[grp] &= ~mask; /* clear armed */ -int_hiact = hireq; /* now active */ -int_hireq = io_eval_int (); /* paranoia */ -if (int_hireq != NO_INT) - printf ("%%int ack consistency error, post iack req=%X\r\n", int_hireq); -return int_tab[grp].vecbase + bit; -} - -/* Release interrupt and set new armed/disarmed state */ - -extern uint32 io_rels_int (uint32 hiact, t_bool arm) -{ -uint32 grp, bit, mask; - -if (hiact < NO_INT) { /* intr active? */ - grp = INT_GETGRP (hiact); /* get grp, bit */ - bit = INT_GETBIT (hiact); - if (bit >= int_tab[grp].nbits) { /* validate bit */ - printf ("%%int release consistency error, hiact=%X\r\n", hiact); - return 0; - } - mask = 1u << (int_tab[grp].nbits - bit - 1); - int_req[grp] &= ~mask; /* clear req */ - if (arm) /* rearm? */ - int_arm[grp] |= mask; - else int_arm[grp] &= ~mask; - } -int_hiact = io_actv_int (); /* new highest actv */ -return io_eval_int (); /* new request */ -} - -/* Set panel interrupt */ - -t_stat io_set_pint (void) -{ -int_req[INTG_IO] |= INTGIO_PANEL; -return SCPE_OK; -} - -/* Set or clear interrupt status flags */ - -void io_sclr_req (uint32 inum, uint32 val) -{ -uint32 grp, bit, mask; - -if (inum < NO_INT) { /* valid? */ - grp = INT_GETGRP (inum); /* get grp, bit */ - bit = INT_GETBIT (inum); - if (bit >= int_tab[grp].nbits) { /* validate bit */ - printf ("%%intreq set/clear consistency error, inum=%X\r\n", inum); - return; - } - mask = 1u << (int_tab[grp].nbits - bit - 1); - if (val) { /* set req? */ - if (int_arm[grp] & mask) /* must be armed */ - int_req[grp] |= mask; - } - else int_req[grp] &= ~mask; /* clr req */ - } -return; -} - -void io_sclr_arm (uint32 inum, uint32 val) -{ -uint32 grp, bit, mask; - -if (inum < NO_INT) { /* valid? */ - grp = INT_GETGRP (inum); /* get grp, bit */ - bit = INT_GETBIT (inum); - if (bit >= int_tab[grp].nbits) { /* validate bit */ - printf ("%%intarm set/clear consistency error, inum=%X\r\n", inum); - return; - } - mask = 1u << (int_tab[grp].nbits - bit - 1); - if (val) /* set or clr arm */ - int_arm[grp] |= mask; - else int_arm[grp] &= ~mask; - } -return; -} - -/* Read/write direct mode 0 - processor miscellaneous */ - -uint32 io_rwd_m0 (uint32 op, uint32 rn, uint32 ad) -{ -uint32 wd; -uint32 fnc = DIO_GET0FNC (ad); -uint32 dat = rn? R[rn]: 0; - -if (op == OP_RD) { /* read direct? */ - if (fnc == 0x000) { /* copy SSW to SC */ - CC = SSW; - } - else if (fnc == 0x010) { /* read mem fault */ - if (rn) - R[rn] = 0; - CC = SSW; - } - else if (QCPU_S89_5X0 && (fnc == 0x040)) { /* S89, 5X0 only */ - if (rn) /* read inhibits */ - R[rn] = PSW2_GETINH (PSW2); - } - else if (QCPU_S89 && (fnc == 0x045)) { /* S89 only */ - if (rn) - R[rn] = s9_marg & 0x00C00000 | /* <8,9> = margins */ - (QCPU_S9? 0x00100000: 0x00200000); /* S8 sets 10, S9 11 */ - } - else if (QCPU_S89 && (fnc == 0x049)) { /* S89 only */ - if (rn) /* read snapshot */ - R[rn] = s9_snap; - } - else if (QCPU_5X0 && ((fnc & 0xFC0) == 0x100)) { /* 5X0 only */ - ReadPW (fnc & 0x1F, &wd); /* read low mem */ - if (rn) - R[rn] = wd; - } - else if (QCPU_5X0 && ((fnc & 0xFC0) == 0x300)) { /* 5X0 only */ - if (rn) /* read int reg */ - R[rn] = s5x0_ireg[fnc & 0x1F]; - } - else return (stop_op)? STOP_ILLEG: 0; - } -else { /* write direct */ - if (QCPU_5X0 && (fnc == 0x000)) /* 5X0 only */ - SSW = dat & 0xF; /* write SSW */ - else if (QCPU_5X0 && (fnc == 0x002)) /* 5X0 only */ - return TR_47; /* trap to 47 */ - else if ((fnc & 0xFF0) == 0x020) /* bit clear inh */ - PSW2 &= ~((ad & PSW2_M_INH) << PSW2_V_INH); - else if ((fnc & 0xFF0) == 0x030) /* bit set inh */ - PSW2 |= ((ad & PSW2_M_INH) << PSW2_V_INH); - else if (fnc == 0x040) /* alarm off */ - cons_alarm = 0; - else if (fnc == 0x041) /* alarm on */ - cons_alarm = 1; - else if (fnc == 0x042) { /* toggle freq */ - cons_alarm = 0; - cons_pcf ^= 1; - } - else if (fnc == 0x044) ; /* S5 reset IIOP */ - else if (QCPU_S89 && (fnc == 0x045)) /* S89 only */ - s9_marg = dat; /* write margins */ - else if (QCPU_S89_5X0 && (fnc == 0x046)) /* S89, 5X0 only */ - PSW2 &= ~(PSW2_MA9|PSW2_MA5X0); /* clr mode altered */ - else if (QCPU_S9 && (fnc == 0x047)) /* S9 set mode alt */ - PSW2 |= PSW2_MA9; - else if (QCPU_5X0 && (fnc == 0x047)) /* 5X0 set mode alt */ - PSW2 |= PSW2_MA5X0; - else if (QCPU_S89 && (fnc == 0x049)) /* S9 only */ - s9_snap = dat; /* write snapshot */ - else if (QCPU_5X0 && ((fnc & 0xFC0) == 0x100)) /* 5X0 only */ - WritePW (fnc & 0x1F, dat); /* write low mem */ - else if (QCPU_5X0 && ((fnc & 0xFC0) == 0x300)) /* 5X0 only */ - s5x0_ireg[fnc & 0x1F] = dat; /* write int reg */ - else return (stop_op)? STOP_ILLEG: 0; - } -return 0; -} - -/* Read/write direct mode 1 - interrupt flags - This is the only routine that has to map between architecturally - defined interrupts groups and the internal representation. */ - -uint32 io_rwd_m1 (uint32 op, uint32 rn, uint32 ad) -{ -uint32 i, beg, end, mask, sc; -uint32 grp = DIO_GET1GRP (ad); -uint32 fnc = DIO_GET1FNC (ad); - -if (grp == 0) { /* overrides? */ - beg = INTG_OVR; - end = INTG_IO; - } -else if (grp == 1) /* group 1? */ - return 0; /* not there */ -else beg = end = grp + 1; - -if (op == OP_RD) { /* read direct? */ - if (!QCPU_S89_5X0) /* S89, 5X0 only */ - return (stop_op? STOP_ILLEG: 0); - if (rn == 0) /* want result? */ - return 0; - R[rn] = 0; /* clear reg */ - } -for (i = beg; i <= end; i++) { /* loop thru grps */ - mask = (1u << int_tab[i].nbits) - 1; - sc = 32 - int_tab[i].regbit - int_tab[i].nbits; - if (op == OP_RD) { /* read direct? */ - if (fnc & 0x1) - R[rn] |= ((mask & int_arm[i]) << sc); - if (fnc & 0x2) - R[rn] |= ((mask & int_req[i]) << sc); - if (fnc & 0x4) - R[rn] |= ((mask & int_enb[i]) << sc); - } - else { /* write direct */ - mask = (R[rn] >> sc) & mask; - switch (fnc) { - - case 0x0: /* armed||wait->act */ - if (QCPU_S89_5X0) { - int_req[i] |= (mask & int_arm[i]); - int_arm[i] &= mask; - } - else return (stop_op? STOP_ILLEG: 0); - break; - - case 0x1: /* disarm, clr req */ - int_arm[i] &= ~mask; - int_req[i] &= ~mask; - break; - - case 0x2: /* arm, enb, clr req */ - int_arm[i] |= mask; - int_enb[i] |= mask; - int_req[i] &= ~mask; - break; - - case 0x3: /* arm, dsb, clr req */ - int_arm[i] |= mask; - int_enb[i] &= ~mask; - int_req[i] &= ~mask; - break; - - case 0x4: /* enable */ - int_enb[i] |= mask; - break; - - case 0x5: /* disable */ - int_enb[i] &= ~mask; - break; - - case 0x6: /* direct set enb */ - int_enb[i] = mask; - break; - - case 0x7: /* armed->waiting */ - int_req[i] |= (mask & int_arm[i]); - } - } - } -return 0; -} - -/* Reset routines */ - -t_stat int_reset (DEVICE *dptr) -{ -uint32 i; - -if (int_lnk[0] == 0) /* int chain not set up? */ - io_set_eimax (ei_bmax); -for (i = 0; i < INTG_MAX; i++) { - int_arm[i] = 0; - int_enb[i] = 0; - int_req[i] = 0; - } -int_hiact = NO_INT; -int_hireq = NO_INT; -return SCPE_OK; -} - -t_stat chan_reset (DEVICE *dptr) -{ -uint32 ch = dptr - &chan_dev[0]; -uint32 i, j; -DEVICE *devp; - -if (ch >= CHAN_N_CHAN) - return SCPE_IERR; -for (i = 0; i < CHAN_N_DEV; i++) { - chan[ch].clc[i] = 0; - chan[ch].cmd[i] = 0; - chan[ch].cmf[i] = 0; - chan[ch].ba[i] = 0; - chan[ch].bc[i] = 0; - chan[ch].chf[i] = 0; - chan[ch].chi[i] = 0; - chan[ch].chsf[i] &= ~CHSF_ACT; - for (j = 0; (devp = sim_devices[j]) != NULL; j++) { /* loop thru dev */ - if (devp->ctxt != NULL) { - dib_t *dibp = (dib_t *) devp->ctxt; - if ((DVA_GETCHAN (dibp->dva) == ch) && (devp->reset)) - devp->reset (devp); - } - } - } -return SCPE_OK; -} - -/* Universal boot routine */ - -static uint32 boot_rom[] = { - 0x00000000, 0x00000000, 0x020000A8, 0x0E000058, - 0x00000011, 0x00000000, 0x32000024, 0xCC000025, - 0xCD000025, 0x69C00028, 0x00000000, 0x00000000 - }; - -t_stat io_boot (int32 u, DEVICE *dptr) -{ -uint32 i; -dib_t *dibp = (dib_t *) dptr->ctxt; - -for (i = 0; i < MEMSIZE; i++) /* boot clrs mem */ - WritePW (i, 0); -if ((dibp == NULL) || - ((u != 0) && - ((dibp->dva & DVA_MU) == 0))) - return SCPE_ARG; -for (i = 0; i < BOOT_LNT; i++) - WritePW (BOOT_SA + i, boot_rom[i]); -WritePW (BOOT_DEV, dibp->dva | u); -cpu_new_PSD (1, BOOT_PC, 0); -return SCPE_OK; -} - -/* I/O table initialization routine */ - -t_stat io_init (void) -{ -uint32 i, j, ch, dev, dio; -DEVICE *dptr; -dib_t *dibp; - -for (i = 0; i < CHAN_N_CHAN; i++) { - for (j = 0; j < CHAN_N_DEV; j++) { - chan[i].chsf[j] &= ~CHSF_MU; - chan[i].disp[j] = NULL; - } - } -dio_disp[0] = &io_rwd_m0; -for (i = 1; i < DIO_N_MOD; i++) - dio_disp[i] = NULL; - -for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { - if ((dibp = (dib_t *) dptr->ctxt) != NULL) { - ch = DVA_GETCHAN (dibp->dva); - dev = DVA_GETDEV (dibp->dva); - dio = dibp->dio; - if ((ch >= chan_num) || - (dev >= CHAN_N_DEV) || - (dio >= DIO_N_MOD)) { - printf ("%s: invalid device address, chan = %d, dev = %X, dio = %X\n", - sim_dname (dptr), ch, DVA_GETDEV (dibp->dva), dio); - if (sim_log) - fprintf (sim_log, "%s: invalid device address, chan = %d, dev = %X, dio = %X\n", - sim_dname (dptr), ch, DVA_GETDEV (dibp->dva), dio); - return SCPE_STOP; - } - if ((dibp->disp != NULL) && (chan[ch].disp[dev] != NULL)) { - printf ("%s: device address conflict, chan = %d, dev = %X\n", - sim_dname (dptr), ch, DVA_GETDEV (dibp->dva)); - if (sim_log) - fprintf (sim_log, "%s: device address conflict, chan = %d, dev = %X\n", - sim_dname (dptr), ch, DVA_GETDEV (dibp->dva)); - return SCPE_STOP; - } - if ((dibp->dio_disp != NULL) && (dio_disp[dio] != NULL)) { - printf ("%s: direct I/O address conflict, dio = %X\n", - sim_dname (dptr), dio); - if (sim_log) - fprintf (sim_log, "%s: direct I/O address conflict, dio = %X\n", - sim_dname (dptr), dio); - return SCPE_STOP; - } - if (dibp->disp) - chan[ch].disp[dev] = dibp->disp; - if (dibp->dio_disp) - dio_disp[dio] = dibp->dio_disp; - if (dibp->dva & DVA_MU) - chan[ch].chsf[dev] |= CHSF_MU; - } - } -return SCPE_OK; -} - -/* Set/show external interrupt blocks */ - -t_stat io_set_eiblks (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 lnt; -t_stat r; - -if (cptr == NULL) - return SCPE_ARG; -lnt = (int32) get_uint (cptr, 10, cpu_tab[cpu_model].eigrp_max, &r); -if ((r != SCPE_OK) || (lnt == 0)) - return SCPE_ARG; -int_reset (&int_dev); -io_set_eimax (lnt); -return SCPE_OK; -} - -t_stat io_show_eiblks (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -fprintf (st, "eiblks=%d", ei_bmax); -return SCPE_OK; -} - -/* Change the number of external I/O blocks, and restore the default - chain configuration */ - -void io_set_eimax (uint32 max) -{ -uint32 i, curr, ngrp; -uint8 *dflt_p; - -ei_bmax = max; -if (QCPU_5X0) - dflt_p = igrp_dflt_5x0; -else dflt_p = igrp_dflt_S56789; -curr = dflt_p[0] & ~I_STD; -for (i = 1, ngrp = 0; dflt_p[i] != 0; i++) { - if (dflt_p[i] & I_STD) { - int_lnk[curr] = dflt_p[i] & ~I_STD; - curr = int_lnk[curr]; - } - else if (ngrp < ei_bmax) { - int_lnk[curr] = dflt_p[i]; - curr = int_lnk[curr]; - ngrp++; - } - else int_lnk[curr] = 0; - } -return; -} - -/* Set or show number of channels */ - -t_stat io_set_nchan (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 i, num; -t_stat r; - -if (cptr == NULL) - return SCPE_ARG; -num = (int32) get_uint (cptr, 10, cpu_tab[cpu_model].chan_max, &r); -if ((r != SCPE_OK) || (num == 0)) - return SCPE_ARG; -chan_num = num; -for (i = 0; i < CHAN_N_CHAN; i++) { - if (i < num) - chan_dev[i].flags &= ~DEV_DIS; - else chan_dev[i].flags |= DEV_DIS; - chan_reset (&chan_dev[i]); - } -return SCPE_OK; -} - -t_stat io_show_nchan (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -fprintf (st, "channels=%d", chan_num); -return SCPE_OK; -} - -/* Set or show device channel assignment */ - -t_stat io_set_dvc (UNIT* uptr, int32 val, char *cptr, void *desc) -{ -int32 num; -DEVICE *dptr; -dib_t *dibp; - -if (((dptr = find_dev_from_unit (uptr)) == NULL) || - ((dibp = (dib_t *) dptr->ctxt) == NULL)) - return SCPE_IERR; -if ((cptr == NULL) || (*cptr == 0) || (*(cptr + 1) != 0)) - return SCPE_ARG; -num = *cptr - 'A'; -if ((num < 0) || (num >= (int32) chan_num)) - return SCPE_ARG; -dibp->dva = (dibp->dva & ~DVA_CHAN) | (num << DVA_V_CHAN); -return SCPE_OK; -} - -t_stat io_show_dvc (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -DEVICE *dptr; -dib_t *dibp; - -if (((dptr = find_dev_from_unit (uptr)) == NULL) || - ((dibp = (dib_t *) dptr->ctxt) == NULL)) - return SCPE_IERR; -fprintf (st, "channel=%c", DVA_GETCHAN (dibp->dva) + 'A'); -return SCPE_OK; -} - -/* Set or show device address */ - -t_stat io_set_dva (UNIT* uptr, int32 val, char *cptr, void *desc) -{ -int32 num; -DEVICE *dptr; -dib_t *dibp; -t_stat r; - -if (((dptr = find_dev_from_unit (uptr)) == NULL) || - ((dibp = (dib_t *) dptr->ctxt) == NULL)) - return SCPE_IERR; -if (cptr == NULL) - return SCPE_ARG; -num = (int32) get_uint (cptr, 16, CHAN_N_DEV, &r); -if (r != SCPE_OK) - return SCPE_ARG; -if (dibp->dva & DVA_MU) - dibp->dva = (dibp->dva & ~DVA_DEVMU) | ((num & DVA_M_DEVMU) << DVA_V_DEVMU); -else dibp->dva = (dibp->dva & ~DVA_DEVSU) | ((num & DVA_M_DEVSU) << DVA_V_DEVSU); -return SCPE_OK; -} - -t_stat io_show_dva (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -DEVICE *dptr; -dib_t *dibp; - -if (((dptr = find_dev_from_unit (uptr)) == NULL) || - ((dibp = (dib_t *) dptr->ctxt) == NULL)) - return SCPE_IERR; -fprintf (st, "address=%02X", DVA_GETDEV (dibp->dva)); -return SCPE_OK; -} - -/* Show channel state */ - -t_stat io_show_cst (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -DEVICE *dptr; -dib_t *dibp; -uint32 ch, dva; - -if (((dptr = find_dev_from_unit (uptr)) == NULL) || - ((dibp = (dib_t *) dptr->ctxt) == NULL)) - return SCPE_IERR; -ch = DVA_GETCHAN (dibp->dva); -dva = DVA_GETDEV (dibp->dva); -fprintf (st, "Status for device %s, channel=%02X, address=%02X:\n", - sim_dname(dptr), ch, dva); -fprintf (st, "CLC:\t%06X\nBA:\t%06X\nBC:\t%04X\nCMD:\t%02X\n", - chan[ch].clc[dva], chan[ch].ba[dva], - chan[ch].bc[dva], chan[ch].cmd[dva]); -fprintf (st, "CMF:\t%02X\nCHF\t%04X\nCHI:\t%02X\nCHSF:\t%02X\n", - chan[ch].cmf[dva], chan[ch].chf[dva], - chan[ch].chi[dva], chan[ch].chsf[dva]); -return SCPE_OK; -} diff --git a/sigma/sigma_io_defs.h b/sigma/sigma_io_defs.h deleted file mode 100644 index a44c4f91..00000000 --- a/sigma/sigma_io_defs.h +++ /dev/null @@ -1,276 +0,0 @@ -/* sigma_io_defs.h: XDS Sigma I/O device simulator definitions - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#ifndef _SIGMA_IO_DEFS_H_ -#define _SIGMA_IO_DEFS_H_ 0 - -#include "sim_defs.h" /* simulator defns */ -#include "sigma_defs.h" - -/* Channel constants */ - -#define CHAN_N_CHAN 8 /* max # channels */ -#define CHAN_DFLT 4 /* default # chan */ -#define CHAN_N_DEV 32 /* max dev per chan */ -#define CHAN_V_IOPT (DEV_V_UF + 0) /* channel type */ -#define CHAN_MIOP (0 << CHAN_V_IOPT) -#define CHAN_SIOP (1 << CHAN_V_IOPT) - -/* I/O device definition block */ - -typedef struct { - uint32 dva; /* dev addr (chan+dev) */ - uint32 (*disp)(uint32 op, uint32 dva, uint32 *dvst); - uint32 dio; /* dev addr (direct IO) */ - uint32 (*dio_disp)(uint32 op, uint32 rn, uint32 dva); - } dib_t; - -/* Channel data structure */ - -typedef struct { - uint32 clc[CHAN_N_DEV]; /* location counter */ - uint32 ba[CHAN_N_DEV]; /* mem addr */ - uint16 bc[CHAN_N_DEV]; /* byte count */ - uint8 cmd[CHAN_N_DEV]; /* command */ - uint8 cmf[CHAN_N_DEV]; /* command flags */ - uint16 chf[CHAN_N_DEV]; /* channel flags */ - uint8 chi[CHAN_N_DEV]; /* interrupts */ - uint8 chsf[CHAN_N_DEV]; /* simulator flags */ - uint32 (*disp[CHAN_N_DEV])(uint32 op, uint32 dva, uint32 *dvst); - } chan_t; - -/* Channel command words */ - -#define CCW1_V_CMD 24 /* command */ -#define CCW1_M_CMD 0xFF -#define CCW1_V_BA 0 -#define CCW1_M_BA ((cpu_tab[cpu_model].pamask << 2) | 0x3) -#define CHBA_MASK (CCW1_M_BA << CCW1_V_BA) -#define CCW2_V_CMF 24 /* cmd flags */ -#define CCW2_M_CMF 0xFF -#define CCW2_V_BC 0 -#define CCW2_M_BC 0xFFFF -#define CHBC_MASK (CCW2_M_BC << CCW2_V_BC) -#define CCW1_GETCMD(x) (((x) >> CCW1_V_CMD) & CCW1_M_CMD) -#define CCW1_GETBA(x) (((x) >> CCW1_V_BA) & CCW1_M_BA) -#define CCW2_GETCMF(x) (((x) >> CCW2_V_CMF) & CCW2_M_CMF) -#define CCW2_GETBC(x) (((x) >> CCW2_V_BC) & CCW2_M_BC) - -/* Channel commands */ - -#define CMD_TIC 0x8 /* transfer */ - -/* Channel command flags */ - -#define CMF_DCH 0x80 /* data chain */ -#define CMF_IZC 0x40 /* int on zero cnt */ -#define CMF_CCH 0x20 /* command chain */ -#define CMF_ICE 0x10 /* int on chan end */ -#define CMF_HTE 0x08 /* hlt on xmit err */ -#define CMF_IUE 0x04 /* int on uend */ -#define CMF_SIL 0x02 /* suppress lnt err */ -#define CMF_SKP 0x01 /* skip */ - -/* Channel flags */ - -#define CHF_INP 0x8000 /* int pending */ -#define CHF_UEN 0x0400 /* unusual end */ -#define CHF_LNTE 0x0080 /* length error */ -#define CHF_XMDE 0x0040 /* xmit data error */ -#define CHF_XMME 0x0020 /* xmit mem error */ -#define CHF_XMAE 0x0010 /* xmit addr error */ -#define CHF_IOME 0x0008 /* IOP mem error */ -#define CHF_IOCE 0x0004 /* IOP ctrl error */ -#define CHF_IOHE 0x0002 /* IOP halted */ -#define CHF_ALL (CHF_INP|CHF_UEN|0xFF) - -/* Channel interrupts */ - -#define CHI_F_SHF 1 /* flag shift */ -#define CHI_CTL (0x40 << CHI_F_SHF) /* ctl int (fake) */ -#define CHI_ZBC (0x20 << CHI_F_SHF) /* zero by cnt int */ -#define CHI_END (0x10 << CHI_F_SHF) /* channel end int */ -#define CHI_UEN (0x08 << CHI_F_SHF) /* unusual end int */ -#define CHI_FLAGS (CHI_ZBC|CHI_END|CHI_UEN) -#define CHI_V_UN 0 -#define CHI_M_UN 0xF -#define CHI_GETUN(x) (((x) >> CHI_V_UN) & CHI_M_UN) -#define CHI_GETINT(x) (((x) & CHI_FLAGS) >> CHI_F_SHF) - -/* Internal simulator flags */ - -#define CHSF_ACT 0x0001 /* channel active */ -#define CHSF_MU 0x0002 /* multi-unit dev */ - -/* Dispatch routine status return value */ - -#define DVT_V_UN 24 /* unit addr (AIO only) */ -#define DVT_M_UN 0xF -#define DVT_V_CC 16 /* cond codes */ -#define DVT_M_CC 0xF -#define DVT_V_DVS 0 /* device status */ -#define DVT_M_DVS 0xFF -#define DVS_V_DST 5 /* device status */ -#define DVS_M_DST 0x3 -#define DVS_DST (DVS_M_DST << DVS_V_DST) -#define DVS_DOFFL (0x1 << DVS_V_DST) -#define DVS_DBUSY (0x3 << DVS_V_DST) -#define DVS_AUTO 0x10 /* manual/automatic */ -#define DVS_V_CST 1 /* ctrl status */ -#define DVS_M_CST 0x3 -#define DVS_CBUSY (0x3 << DVS_V_CST) -#define DVS_CST (DVS_M_CST << DVS_V_CST) -#define DVT_GETUN(x) (((x) >> DVT_V_UN) & DVT_M_UN) -#define DVT_GETCC(x) (((x) >> DVT_V_CC) & DVT_M_CC) -#define DVT_GETDVS(x) (((x) >> DVT_V_DVS) & DVT_M_DVS) -#define DVT_NOST (CC1 << DVT_V_CC) /* no status */ -#define DVT_NODEV ((CC1|CC2) < DVT_V_CC) /* no device */ - -/* Read and write direct address format */ - -#define DIO_V_MOD 12 /* mode */ -#define DIO_M_MOD 0xF -#define DIO_V_0FNC 0 /* mode 0 func */ -#define DIO_M_0FNC 0xFFF -#define DIO_V_1FNC 8 /* mode 1 int func */ -#define DIO_M_1FNC 0x7 -#define DIO_V_1GRP 0 /* int group */ -#define DIO_M_1GRP 0xF -#define DIO_GETMOD(x) (((x) >> DIO_V_MOD) & DIO_M_MOD) -#define DIO_GET0FNC(x) (((x) >> DIO_V_0FNC) & DIO_M_0FNC) -#define DIO_GET1FNC(x) (((x) >> DIO_V_1FNC) & DIO_M_1FNC) -#define DIO_GET1GRP(x) (((x) >> DIO_V_1GRP) & DIO_M_1GRP) -#define DIO_N_MOD (DIO_M_MOD + 1) /* # DIO "modes" */ - -/* I/O instruction address format */ - -#define DVA_V_CHAN 8 /* channel */ -#define DVA_M_CHAN (CHAN_N_CHAN - 1) -#define DVA_CHAN (DVA_M_CHAN << DVA_V_CHAN) -#define DVA_V_DEVSU 0 /* dev, 1 unit */ -#define DVA_M_DEVSU 0x7F -#define DVA_DEVSU (DVA_M_DEVSU << DVA_V_DEVSU) -#define DVA_MU 0x80 /* multi-unit flg */ -#define DVA_V_DEVMU 4 /* dev, multi */ -#define DVA_M_DEVMU 0x7 -#define DVA_DEVMU (DVA_M_DEVMU << DVA_V_DEVMU) -#define DVA_V_UNIT 0 /* unit number */ -#define DVA_M_UNIT 0xF -#define DVA_GETCHAN(x) (((x) >> DVA_V_CHAN) & DVA_M_CHAN) -#define DVA_GETDEV(x) (((x) & DVA_MU)? \ - (((x) >> DVA_V_DEVMU) & DVA_M_DEVMU): \ - (((x) >> DVA_V_DEVSU) & DVA_M_DEVSU)) -#define DVA_GETUNIT(x) (((x) & DVA_MU)? \ - (((x) >> DVA_V_UNIT) & DVA_M_UNIT): 0) - -/* Default I/O device addresses */ - -#define DVA_TT 0x001 -#define DVA_LP 0x002 -#define DVA_CR 0x003 -#define DVA_CP 0x004 -#define DVA_PT 0x005 -#define DVA_MUX 0x006 -#define DIO_MUX 0x3 -#define DVA_MT 0x080 -#define DVA_RAD 0x180 -#define DVA_DK 0x190 -#define DVA_DPA 0x280 -#define DVA_DPB 0x380 - -/* Channel routine status codes */ - -#define CHS_ERR 0x4000 /* any error */ -#define CHS_INF 0x8000 /* information */ -#define CHS_IFERR(x) (((x) != 0) && ((x) < CHS_INF)) - -#define CHS_INACTV (CHS_ERR + 0) -#define CHS_NXM (CHS_ERR + 1) -#define CHS_SEQ (CHS_ERR + 2) - -#define CHS_ZBC (CHS_INF + 1) /* zero byte count */ -#define CHS_CCH (CHS_INF + 2) /* command chain */ - -/* Boot ROM */ - -#define BOOT_SA 0x20 -#define BOOT_LNT 12 -#define BOOT_DEV 0x25 -#define BOOT_PC 0x26 - -/* Internal real-time scheduler */ - -#define RTC_C1 0 -#define RTC_C2 1 -#define RTC_C3 2 -#define RTC_C4 3 -#define RTC_NUM_CNTRS 4 -#define RTC_TTI (RTC_NUM_CNTRS + 0) -#define RTC_COC (RTC_NUM_CNTRS + 1) -#define RTC_ALARM (RTC_NUM_CNTRS + 2) -#define RTC_NUM_EVNTS (RTC_NUM_CNTRS + 3) - -#define RTC_HZ_OFF 0 -#define RTC_HZ_500 1 -#define RTC_HZ_50 2 -#define RTC_HZ_60 3 -#define RTC_HZ_100 4 -#define RTC_HZ_2 5 -#define RTC_NUM_HZ 6 - -/* Function prototypes */ - -uint32 chan_get_cmd (uint32 dva, uint32 *cmd); -uint32 chan_set_chf (uint32 dva, uint32 fl); -t_bool chan_tst_cmf (uint32 dva, uint32 fl); -void chan_set_chi (uint32 dva, uint32 fl); -void chan_set_dvi (uint32 dva); -int32 chan_clr_chi (uint32 dva); -int32 chan_chk_chi (uint32 dva); -uint32 chan_end (uint32 dva); -uint32 chan_uen (uint32 dva); -uint32 chan_RdMemB (uint32 dva, uint32 *dat); -uint32 chan_WrMemB (uint32 dva, uint32 dat); -uint32 chan_WrMemBR (uint32 dva, uint32 dat); -uint32 chan_RdMemW (uint32 dva, uint32 *dat); -uint32 chan_WrMemW (uint32 dva, uint32 dat); -t_stat chan_reset_dev (uint32 dva); -void io_sclr_req (uint32 inum, uint32 val); -void io_sclr_arm (uint32 inum, uint32 val); -t_stat io_set_dvc (UNIT* uptr, int32 val, char *cptr, void *desc); -t_stat io_show_dvc (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat io_set_dva (UNIT* uptr, int32 val, char *cptr, void *desc); -t_stat io_show_dva (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat io_show_cst (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat io_boot (int32 u, DEVICE *dptr); - -/* Internal real-time event scheduler */ - -t_stat rtc_set_tps (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat rtc_show_tps (FILE *of, UNIT *uptr, int32 val, void *desc); -t_stat rtc_register (uint32 tm, uint32 idx, UNIT *uptr); - -#endif \ No newline at end of file diff --git a/sigma/sigma_lp.c b/sigma/sigma_lp.c deleted file mode 100644 index 70261e4d..00000000 --- a/sigma/sigma_lp.c +++ /dev/null @@ -1,529 +0,0 @@ -/* sigma_lp.c: Sigma 7440/7450 line printer - - Copyright (c) 2007-2008, Robert M. Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - lp 7440/7445 or 7450 line printer -*/ - -#include "sigma_io_defs.h" - -/* Device definitions */ - -#define CCT_LNT 256 /* carriage ctl max */ -#define BUF_LNT4 132 /* line lengths */ -#define BUF_LNT5 128 - -#define LP_7440 0 /* models */ -#define LP_7450 1 - -/* Device states */ - -#define LPS_INIT 0x101 -#define LPS_END 0x102 -#define LPS_PRI 0x1 -#define LPS_FMT 0x3 -#define LPS_FMTP 0x5 -#define LPS_INT 0x40 - -/* Device status */ - -#define LPDV_ODD 0x40 /* odd */ -#define LPDV_TOF 0x10 /* top of form */ -#define LPDV_MOV 0x08 /* paper moving */ -#define LPDV_V_RUN 2 /* runaway CCT */ -#define LPDV_RUN (1u << LPDV_V_RUN) -#define LPDV_WT2 0x02 /* waiting for 2nd */ - -/* Format characters */ - -#define FMT_INH 0x60 -#define FMT_SPC 0xC0 -#define FMT_SKP 0xF0 - -#define FMT_MSPC4 15 /* max space cmd */ -#define FMT_MSPC5 7 -#define SPC_MASK ((lp_model == LP_7440)? FMT_MSPC4: FMT_MSPC5) -#define FMT_MCH4 7 /* max CCT channel */ -#define FMT_MCH5 1 -#define CCH_MASK ((lp_model == LP_7440)? FMT_MCH5: FMT_MCH4) - -#define CH_BOF 0 /* CCT bot of form */ -#define CH_TOF 1 /* CCT top of form */ - -#define CHP(ch,val) ((val) & (1 << (ch))) - -uint32 lp_cmd = 0; -uint32 lp_stopioe = 1; -uint32 lp_cctp = 0; /* CCT position */ -uint32 lp_cctl = 1; /* CCT length */ -uint32 lp_lastcmd = 0; /* last command */ -uint32 lp_pass = 0; /* 7450 print pass */ -uint32 lp_inh = 0; /* space inhibit */ -uint32 lp_run = 0; /* CCT runaway */ -uint32 lp_model = LP_7440; -uint8 lp_buf[BUF_LNT4]; /* print buffer */ -uint8 lp_cct[CCT_LNT] = { 0xFF }; /* carriage ctl tape */ -uint8 lp_to_ascii[64] = { - ' ', 'A', 'B', 'C', 'D', 'E', 'F', 'G', - 'H', 'I', '`', '.', '<', '(', '+', '|', - '&', 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', '!', '$', '*', ')', ';', '~', - '-', '/', 'S', 'T', 'U', 'V', 'W', 'X', - 'Y', 'Z', '^', ',', '%', '_', '>', '?', - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', ':', '#', '@', '\'', '=', '"' - }; - -extern uint32 chan_ctl_time; - -uint32 lp_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 lp_tio_status (void); -uint32 lp_tdv_status (void); -t_stat lp_chan_err (uint32 st); -t_stat lp_svc (UNIT *uptr); -t_stat lp_reset (DEVICE *dptr); -t_stat lp_attach (UNIT *uptr, char *cptr); -t_stat lp_settype (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat lp_showtype (FILE *st, UNIT *uptr, int32 val, void *desc); -t_stat lp_load_cct (UNIT *uptr, int32 val, char *cptr, void *desc); -uint32 lp_fmt (UNIT *uptr); -uint32 lp_skip (UNIT *uptr, uint32 ch); -uint32 lp_space (UNIT *uptr, uint32 lines, t_bool skp); -uint32 lp_print (UNIT *uptr); - -/* LP data structures - - lp_dev LP device descriptor - lp_unit LP unit descriptors - lp_reg LP register list - lp_mod LP modifiers list -*/ - -dib_t lp_dib = { DVA_LP, lp_disp, 0, NULL }; - -UNIT lp_unit = { UDATA (&lp_svc, UNIT_ATTABLE+UNIT_SEQ, 0), SERIAL_OUT_WAIT }; - -REG lp_reg[] = { - { HRDATA (CMD, lp_cmd, 9) }, - { BRDATA (BUF, lp_buf, 16, 7, BUF_LNT4) }, - { FLDATA (PASS, lp_pass, 0) }, - { FLDATA (INH, lp_inh, 0) }, - { FLDATA (RUNAWAY, lp_run, LPDV_V_RUN) }, - { BRDATA (CCT, lp_cct, 8, 8, CCT_LNT) }, - { DRDATA (CCTP, lp_cctp, 8), PV_LEFT }, - { DRDATA (CCTL, lp_cctl, 8), PV_LEFT + REG_HRO + REG_NZ }, - { DRDATA (POS, lp_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TIME, lp_unit.wait, 24), PV_LEFT }, - { FLDATA (STOP_IOE, lp_stopioe, 0) }, - { HRDATA (LASTC, lp_lastcmd, 8), REG_HIDDEN }, - { FLDATA (MODEL, lp_model, 0), REG_HRO }, - { HRDATA (DEVNO, lp_dib.dva, 12), REG_HRO }, - { NULL } - }; - -MTAB lp_mod[] = { - { MTAB_XTD | MTAB_VDV, LP_7440, NULL, "7440", - &lp_settype, NULL, NULL }, - { MTAB_XTD | MTAB_VDV, LP_7450, NULL, "7450", - &lp_settype, NULL, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "TYPE", NULL, - NULL, &lp_showtype, NULL }, - { MTAB_XTD | MTAB_VDV | MTAB_NC, 0, NULL, "CCT", - &lp_load_cct, NULL, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE lp_dev = { - "LP", &lp_unit, lp_reg, lp_mod, - 1, 10, 31, 1, 16, 8, - NULL, NULL, &lp_reset, - NULL, &lp_attach, NULL, - &lp_dib, 0 - }; - -/* Line printer: IO dispatch routine */ - -uint32 lp_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = lp_tio_status (); /* get status */ - if ((*dvst & DVS_DST) == 0) { /* idle? */ - lp_cmd = LPS_INIT; /* start dev thread */ - sim_activate (&lp_unit, chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = lp_tio_status (); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = lp_tdv_status (); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - chan_clr_chi (lp_dib.dva); /* clear int */ - *dvst = lp_tio_status (); /* get status */ - if ((*dvst & DVS_DST) != 0) { /* busy? */ - sim_cancel (&lp_unit); /* stop dev thread */ - chan_uen (lp_dib.dva); /* uend */ - } - break; - - case OP_AIO: /* acknowledge int */ - chan_clr_chi (lp_dib.dva); /* clear int */ - *dvst = lp_lastcmd & LPS_INT; /* int requested */ - lp_lastcmd = 0; - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Service routine */ - -t_stat lp_svc (UNIT *uptr) -{ -uint32 cmd; -uint32 st; - -switch (lp_cmd) { /* case on state */ - - case LPS_INIT: /* I/O init */ - st = chan_get_cmd (lp_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return lp_chan_err (st); - lp_inh = 0; /* clear inhibit, */ - lp_run = 0; /* runaway */ - lp_cmd = lp_lastcmd = cmd; /* save command */ - sim_activate (uptr, chan_ctl_time); /* continue thread */ - break; - - case LPS_FMT: - case LPS_FMT|LPS_INT: /* format only */ - sim_activate (uptr, uptr->wait); /* continue thread */ - if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ - return lp_stopioe? SCPE_UNATT: SCPE_OK; - st = lp_fmt (uptr); /* format */ - if (CHS_IFERR (st)) /* error? */ - return lp_chan_err (st); - if ((lp_model == LP_7440) && /* 7440? lnt chk */ - (st != CHS_ZBC) && - chan_set_chf (lp_dib.dva, CHF_LNTE)) /* not ignored? */ - return lp_chan_err (SCPE_OK); /* force uend */ - lp_cmd = LPS_END; /* actual print */ - break; - - case LPS_FMTP: - case LPS_FMTP|LPS_INT: /* format and print */ - sim_activate (uptr, uptr->wait); /* continue thread */ - if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ - return lp_stopioe? SCPE_UNATT: SCPE_OK; - st = lp_fmt (uptr); /* format */ - if (CHS_IFERR (st)) /* error? */ - return lp_chan_err (st); - if (st == CHS_ZBC) { /* command done? */ - if ((lp_model == LP_7440) && /* 7440? lnt err */ - chan_set_chf (lp_dib.dva, CHF_LNTE)) /* not ignored? */ - return lp_chan_err (SCPE_OK); - } - else { /* more to do */ - st = lp_print (uptr); /* print */ - if (CHS_IFERR (st)) /* error */ - return lp_chan_err (st); - } - break; - - case LPS_PRI: - case LPS_PRI|LPS_INT: /* print only */ - sim_activate (uptr, uptr->wait); /* continue thread */ - if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ - return lp_stopioe? SCPE_UNATT: SCPE_OK; - st = lp_print (uptr); /* print */ - if (CHS_IFERR (st)) /* error? */ - return lp_chan_err (st); - break; - - case LPS_END: /* command done */ - if ((lp_lastcmd & LPS_INT) && !lp_pass) /* int requested? */ - chan_set_chi (lp_dib.dva, 0); - st = chan_end (lp_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return lp_chan_err (st); - if (st == CHS_CCH) { /* command chain? */ - lp_cmd = LPS_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - break; - - default: /* invalid cmd */ - chan_uen (lp_dib.dva); /* uend */ - break; - } - -return SCPE_OK; -} - -/* Format routine */ - -uint32 lp_fmt (UNIT *uptr) -{ -uint32 c, i; -uint32 st; - -st = chan_RdMemB (lp_dib.dva, &c); /* get char */ -if (CHS_IFERR (st)) /* channel error? */ - return st; /* caller handles */ -if (lp_pass) /* only on pass 1 */ - return 0; -if ((c & 0x7F) == FMT_INH) /* inhibit? */ - lp_inh = 1; -else if ((c & ~(((lp_model == LP_7450)? 0x20: 0) | SPC_MASK)) == FMT_SPC) { - c = c & SPC_MASK; /* space? */ - for (i = 1; i <= c; i++) { /* look for BOF */ - if (CHP (CH_BOF, lp_cct[(lp_cctp + i) % lp_cctl])) - return lp_skip (uptr, CH_TOF); /* found, TOF */ - } - return lp_space (uptr, c, FALSE); /* space */ - } -else if ((c & ~CCH_MASK) == FMT_SKP) /* skip? */ - return lp_skip (uptr, c & CCH_MASK); /* skip to chan */ -return 0; -} - -/* Skip to channel */ - -uint32 lp_skip (UNIT *uptr, uint32 ch) -{ -uint32 i; - -for (i = 1; i < (lp_cctl + 1); i++) { /* sweep thru CCT */ - if (CHP (ch, lp_cct[(lp_cctp + i) % lp_cctl])) /* channel punched? */ - return lp_space (uptr, i, TRUE); /* space to chan */ - } -lp_run = LPDV_RUN; /* runaway CCT */ -return lp_space (uptr, lp_cctl, TRUE); /* space max */ -} - -/* Space routine */ - -uint32 lp_space (UNIT *uptr, uint32 cnt, t_bool skp) -{ -uint32 i; - -lp_cctp = (lp_cctp + cnt) % lp_cctl; /* adv cct, mod lnt */ -if (skp && CHP (CH_TOF, lp_cct[lp_cctp])) /* skip, TOF? */ - fputs ("\f", uptr->fileref); /* ff */ - else { /* space */ - for (i = 0; i < cnt; i++) - fputc ('\n', uptr->fileref); - } -uptr->pos = ftell (uptr->fileref); /* update position */ -if (ferror (uptr->fileref)) { /* error? */ - perror ("Line printer I/O error"); - clearerr (uptr->fileref); - chan_set_chf (lp_dib.dva, CHF_XMDE); - return SCPE_IOERR; - } -return 0; -} - -/* Print routine */ - -uint32 lp_print (UNIT *uptr) -{ -uint32 i, bp, c; -uint32 max = (lp_model == LP_7440)? BUF_LNT4: BUF_LNT5; -uint32 st; - -if (lp_pass == 0) { /* pass 1? clr buf */ - for (i = 0; i < BUF_LNT4; i++) lp_buf[i] = ' '; - } -for (bp = 0, st = 0; (bp < max) && !st; bp++) { /* fill buffer */ - st = chan_RdMemB (lp_dib.dva, &c); /* get char */ - if (CHS_IFERR (st)) /* channel error? */ - return st; /* caller handles */ - if ((lp_model == LP_7440) || /* 7440 or */ - ((bp & 1) == lp_pass)) /* correct pass? */ - lp_buf[bp] = lp_to_ascii[c & 0x3F]; - } -if ((lp_model == LP_7440) || lp_pass) { /* ready to print? */ - lp_pass = 0; - for (i = BUF_LNT4; (i > 0) && (lp_buf[i - 1] == ' '); i--) ; /* trim */ - if (i) /* write line */ - sim_fwrite (lp_buf, 1, i, uptr->fileref); - fputc (lp_inh? '\r': '\n', uptr->fileref); /* cr or nl */ - uptr->pos = ftell (uptr->fileref); /* update position */ - if (ferror (uptr->fileref)) { /* error? */ - perror ("Line printer I/O error"); - clearerr (uptr->fileref); - chan_set_chf (lp_dib.dva, CHF_XMDE); - return SCPE_IOERR; - } - if ((lp_model == LP_7440) && /* 7440? */ - ((bp != BUF_LNT4) || (st != CHS_ZBC)) && /* check lnt err */ - chan_set_chf (lp_dib.dva, CHF_LNTE)) - return CHS_INACTV; /* stop if asked */ - } -else lp_pass = 1; /* 7450 pass 2 */ -lp_cmd = LPS_END; /* end state */ -return 0; -} - -/* LP status routine */ - -uint32 lp_tio_status (void) -{ -uint32 st; - -st = (lp_unit.flags & UNIT_ATT)? DVS_AUTO: 0; /* auto? */ -if (sim_is_active (&lp_unit)) /* busy? */ - st |= (DVS_CBUSY | DVS_DBUSY | (CC2 << DVT_V_CC)); -return st; -} - -uint32 lp_tdv_status (void) -{ -uint32 st; - -st = lp_run; /* runaway flag */ -if ((lp_unit.flags & UNIT_ATT) == 0) /* fault? */ - st |= (CC2 << DVT_V_CC); -if (lp_cmd == LPS_END) /* end state? */ - st |= LPDV_MOV; /* printing */ -if (lp_pass && (lp_model == LP_7450)) { /* 7450 pass 2? */ - st |= LPDV_ODD; /* odd state */ - if (lp_cmd == LPS_INIT) /* wait for cmd? */ - st |= LPDV_WT2; - } -return st; -} - -/* Channel error */ - -t_stat lp_chan_err (uint32 st) -{ -sim_cancel (&lp_unit); /* stop dev thread */ -chan_uen (lp_dib.dva); /* uend */ -if (st < CHS_ERR) - return st; -return SCPE_OK; -} - -/* Reset routine */ - -t_stat lp_reset (DEVICE *dptr) -{ -sim_cancel (&lp_unit); /* stop dev thread */ -lp_cmd = 0; -lp_lastcmd = 0; -lp_pass = 0; -lp_inh = 0; -lp_run = 0; -chan_reset_dev (lp_dib.dva); /* clr int, active */ -return SCPE_OK; -} - -/* Attach routine */ - -t_stat lp_attach (UNIT *uptr, char *cptr) -{ -lp_cctp = 0; /* clear cct ptr */ -lp_pass = 0; -return attach_unit (uptr, cptr); -} - -/* Set carriage control tape */ - -t_stat lp_load_cct (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 col, rpt, ptr, mask; -uint8 cctbuf[CCT_LNT]; -t_stat r; -char cbuf[CBUFSIZE], gbuf[CBUFSIZE]; -FILE *cfile; - -if ((cptr == NULL) || (*cptr == 0)) return SCPE_ARG; -if ((cfile = fopen (cptr, "r")) == NULL) - return SCPE_OPENERR; -ptr = 0; -for ( ; (cptr = fgets (cbuf, CBUFSIZE, cfile)) != NULL; ) { - mask = 0; - if (*cptr == '(') { /* repeat count? */ - cptr = get_glyph (cptr + 1, gbuf, ')'); /* get 1st field */ - rpt = get_uint (gbuf, 10, CCT_LNT, &r); /* repeat count */ - if (r != SCPE_OK) - return SCPE_FMT; - } - else rpt = 1; - while (*cptr != 0) { /* get col no's */ - cptr = get_glyph (cptr, gbuf, ','); /* get next field */ - col = get_uint (gbuf, 10, FMT_MCH4, &r); /* column number */ - if (r != SCPE_OK) - return SCPE_FMT; - mask = mask | (1 << col); /* set bit */ - } - for ( ; rpt > 0; rpt--) { /* store vals */ - if (ptr >= CCT_LNT) - return SCPE_FMT; - cctbuf[ptr++] = mask; - } - } -if (ptr == 0) - return SCPE_FMT; -lp_cctl = ptr; -lp_cctp = 0; -for (rpt = 0; rpt < lp_cctl; rpt++) - lp_cct[rpt] = cctbuf[rpt]; -return SCPE_OK; -} - -/* Set controller type */ - -t_stat lp_settype (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -lp_model = val; -lp_reset (&lp_dev); -return SCPE_OK; -} - -/* Show controller type */ - -t_stat lp_showtype (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -fprintf (st, lp_model? "7450": "7440"); -return SCPE_OK; -} diff --git a/sigma/sigma_map.c b/sigma/sigma_map.c deleted file mode 100644 index 898de7bb..00000000 --- a/sigma/sigma_map.c +++ /dev/null @@ -1,591 +0,0 @@ -/* sigma_map.c: XDS Sigma memory access routines - - Copyright (c) 2007, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "sigma_defs.h" - -#define BVA_REG (RF_NUM << 2) -#define BPAMASK ((cpu_tab[cpu_model].pamask << 2) | 0x3) -#define NUM_MUNITS (MAXMEMSIZE / CPU_MUNIT_SIZE) - -/* Sigma 8-9 memory status words */ - -#define S89_SR0_BADLMS 0x00800000 /* bad LMS */ -#define S89_SR0_RD (S89_SR0_BADLMS) -#define S89_SR0_V_PORTS 12 - -#define S89_SR1_FIXED 0x50C40000 /* always 1 */ -#define S89_SR1_M_MEMU 0xF /* mem unit */ -#define S89_SR1_V_MEMU 24 -#define S89_SR1_MARG 0x00F80000 /* margin write */ -#define S89_SR1_MAROFF 2 /* offset to read */ - -/* 5X0 memory status words */ - -#define S5X0_SR0_FIXED 0x40000000 -#define S5X0_SR0_BADLMS 0x00000004 /* bad LMS */ -#define S5X0_SR0_RD (S5X0_SR0_BADLMS) -#define S5X0_SR0_V_PORTS 21 - -#define S5X0_SR1_FIXED 0xB0000000 /* fixed */ -#define S5X0_SR1_M_MEMU 0x7 /* mem unit */ -#define S5X0_SR1_V_MEMU 25 -#define S5X0_SR1_V_SA 18 /* start addr */ - -#define S8 - -typedef struct { - uint32 width; /* item width */ - uint32 dmask; /* data mask */ - uint32 cmask; /* control start mask */ - uint32 lnt; /* array length */ - uint32 opt; /* option control */ - } mmc_ctl_t; - -uint16 mmc_rel[VA_NUM_PAG]; -uint8 mmc_acc[VA_NUM_PAG]; -uint8 mmc_wlk[PA_NUM_PAG]; - -uint32 mem_sr0[NUM_MUNITS]; -uint32 mem_sr1[NUM_MUNITS]; - -mmc_ctl_t mmc_tab[8] = { - { 0, 0, 0, 0 }, - { 2, 0x003, 0, MMC_L_CS1, CPUF_WLK }, /* map 1: 2b locks */ - { 2, 0x003, MMC_M_CS2, MMC_L_CS2, CPUF_MAP }, /* map 2: 2b access ctls */ - { 4, 0x00F, MMC_M_CS3, MMC_L_CS3, CPUF_WLK }, /* map 3: 4b locks */ - { 8, 0x0FF, MMC_M_CS4, MMC_L_CS4, CPUF_MAP }, /* map 4: 8b relocation */ - { 16, 0x7FF, MMC_M_CS5, MMC_L_CS5, CPUF_MAP }, /* map 5: 16b relocation */ - { 0, 0, 0, 0 }, - { 0, 0, 0, 0 } - }; - -extern uint32 *R; -extern uint32 *M; -extern uint32 PSW1, PSW2, PSW4; -extern uint32 CC, PSW2_WLK; -extern uint32 stop_op; -extern uint32 cpu_model; -extern uint32 chan_num; -extern UNIT cpu_unit; -extern cpu_var_t cpu_tab[]; - -uint32 map_reloc (uint32 bva, uint32 acc, uint32 *bpa); -uint32 map_viol (uint32 bva, uint32 bpa, uint32 tr); -t_stat map_reset (DEVICE *dptr); -uint32 map_las (uint32 rn, uint32 bva); - -/* Map data structures - - map_dev map device descriptor - map_unit map units - map_reg map register list -*/ - -UNIT map_unit = { UDATA (NULL, 0, 0) }; - -REG map_reg[] = { - { BRDATA (REL, mmc_rel, 16, 13, VA_NUM_PAG) }, - { BRDATA (ACC, mmc_acc, 16, 2, VA_NUM_PAG) }, - { BRDATA (WLK, mmc_wlk, 16, 4, PA_NUM_PAG) }, - { BRDATA (SR0, mem_sr0, 16, 32, NUM_MUNITS) }, - { BRDATA (SR1, mem_sr1, 16, 32, NUM_MUNITS) }, - { NULL } - }; - -DEVICE map_dev = { - "MAP", &map_unit, map_reg, NULL, - 1, 16, 16, 1, 16, 32, - NULL, NULL, &map_reset, - NULL, NULL, NULL, - NULL, 0 - }; - -/* Read and write virtual routines - per length */ - -uint32 ReadB (uint32 bva, uint32 *dat, uint32 acc) -{ -uint32 bpa, sc, tr; - -sc = 24 - ((bva & 3) << 3); -if (bva < BVA_REG) /* register access */ - *dat = (R[bva >> 2] >> sc) & BMASK; -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - *dat = (M[bpa >> 2] >> sc) & BMASK; - } /* end else memory */ -return 0; -} - -uint32 ReadH (uint32 bva, uint32 *dat, uint32 acc) -{ -uint32 bpa, tr; - -if (bva < BVA_REG) { /* register access */ - if (bva & 2) - *dat = R[bva >> 2] & HMASK; - else *dat = (R[bva >> 2] >> 16) & HMASK; - } -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - if (bva & 2) - *dat = M[bpa >> 2] & HMASK; - else *dat = (M[bpa >> 2] >> 16) & HMASK; - } /* end else memory */ -return 0; -} - -uint32 ReadW (uint32 bva, uint32 *dat, uint32 acc) -{ -uint32 bpa, tr; - -if (bva < BVA_REG) /* register access */ - *dat = R[bva >> 2]; -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - *dat = M[bpa >> 2]; - } /* end else memory */ -return 0; -} - -uint32 ReadD (uint32 bva, uint32 *dat, uint32 *dat1, uint32 acc) -{ -uint32 bpa, tr; - -if (bva < BVA_REG) { /* register access */ - *dat = R[(bva >> 2) & ~1]; /* force alignment */ - *dat1 = R[(bva >> 2) | 1]; - } -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - *dat = M[(bpa >> 2) & ~1]; /* force alignment */ - *dat1 = M[(bpa >> 2) | 1]; - } /* end else memory */ - -return 0; -} - -uint32 WriteB (uint32 bva, uint32 dat, uint32 acc) -{ -uint32 bpa, sc, tr; - -sc = 24 - ((bva & 3) << 3); -if (bva < BVA_REG) /* register access */ - R[bva >> 2] = (R[bva >> 2] & ~(BMASK << sc)) | ((dat & BMASK) << sc); -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - M[bpa >> 2] = (M[bpa >> 2] & ~(BMASK << sc)) | ((dat & BMASK) << sc); - } /* end else memory */ -PSW2 |= PSW2_RA; /* state altered */ -return 0; -} - -uint32 WriteH (uint32 bva, uint32 dat, uint32 acc) -{ -uint32 bpa, tr; - -if (bva < BVA_REG) { /* register access */ - if (bva & 2) - R[bva >> 2] = (R[bva >> 2] & ~HMASK) | (dat & HMASK); - else R[bva >> 2] = (R[bva >> 2] & HMASK) | ((dat & HMASK) << 16); - } /* end if register */ -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - if (bva & 2) - M[bpa >> 2] = (M[bpa >> 2] & ~HMASK) | (dat & HMASK); - else M[bpa >> 2] = (M[bpa >> 2] & HMASK) | ((dat & HMASK) << 16); - } /* end else memory */ -PSW2 |= PSW2_RA; /* state altered */ -return 0; -} - -uint32 WriteW (uint32 bva, uint32 dat, uint32 acc) -{ -uint32 bpa, tr; - -if (bva < BVA_REG) /* register access */ - R[bva >> 2] = dat & WMASK; -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - M[bpa >> 2] = dat & WMASK; - } /* end else memory */ -PSW2 |= PSW2_RA; /* state altered */ -return 0; -} - -uint32 WriteD (uint32 bva, uint32 dat, uint32 dat1, uint32 acc) -{ -uint32 bpa, tr; - -if (bva < BVA_REG) { /* register access */ - R[(bva >> 2) & ~1] = dat & WMASK; /* force alignment */ - R[(bva >> 2) | 1] = dat1 & WMASK; - } -else { /* memory access */ - if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; - M[(bpa >> 2) & ~1] = dat & WMASK; /* force alignment */ - M[(bpa >> 2) | 1] = dat1 & WMASK; - } /* end else memory */ -PSW2 |= PSW2_RA; /* state altered */ -return 0; -} - -/* General virtual read for instruction history */ - -uint32 ReadHist (uint32 bva, uint32 *dat, uint32 *dat1, uint32 acc, uint32 lnt) -{ -switch (lnt) { /* case on length */ - - case BY: /* byte */ - return ReadB (bva, dat, acc); - - case HW: /* halfword */ - return ReadH (bva, dat, acc); - - case WD: /* word */ - return ReadW (bva, dat, acc); - - case DW: /* doubleword first */ - return ReadD (bva, dat, dat1, acc); - } /* end case length */ - -return SCPE_IERR; -} - -/* Specialized virtual read and write word routines - - treats all addresses as memory addresses */ - -uint32 ReadMemVW (uint32 bva, uint32 *dat, uint32 acc) -{ -uint32 bpa; -uint32 tr; - -if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; -*dat = M[bpa >> 2] & WMASK; -return 0; -} - -uint32 WriteMemVW (uint32 bva, uint32 dat, uint32 acc) -{ -uint32 bpa; -uint32 tr; - -if ((tr = map_reloc (bva, acc, &bpa)) != 0) /* relocate addr */ - return tr; -M[bpa >> 2] = dat & WMASK; -return 0; -} - -/* Relocation routine */ - -uint32 map_reloc (uint32 bva, uint32 acc, uint32 *bpa) -{ -if ((acc != 0) && (PSW1 & PSW1_MM)) { /* virt, map on? */ - uint32 vpag = BVA_GETPAG (bva); /* virt page num */ - *bpa = ((mmc_rel[vpag] << BVA_V_PAG) + BVA_GETOFF (bva)) & BPAMASK; - if (((PSW1 & PSW1_MS) || /* slave mode? */ - (PSW2 & (PSW2_MA9|PSW2_MA5X0))) && /* master prot? */ - (mmc_acc[vpag] >= acc)) /* access viol? */ - return map_viol (bva, *bpa, TR_MPR); - } -else *bpa = bva; /* no, physical */ -if ((acc == VW) && PSW2_WLK) { /* write check? */ - uint32 ppag = BPA_GETPAG (*bpa); /* phys page num */ - if (PSW2_WLK && mmc_wlk[ppag] && /* lock, key != 0 */ - (PSW2_WLK != mmc_wlk[ppag])) /* lock != key? */ - return map_viol (bva, *bpa, TR_WLK); - } -if (BPA_IS_NXM (*bpa)) /* memory exist? */ - return TR_NXM; /* don't set TSF */ -return 0; -} - -/* Memory management error */ - -uint32 map_viol (uint32 bva, uint32 bpa, uint32 tr) -{ -uint32 vpag = BVA_GETPAG (bva); /* virt page num */ - -if (QCPU_S9) /* Sigma 9? */ - PSW2 = (PSW2 & ~PSW2_TSF) | (vpag << PSW2_V_TSF); /* save address */ -PSW4 = bva >> 2; /* 5X0 address */ -if ((tr == TR_WLK) && !QCPU_5X0) /* wlock on S5-9? */ - tr = TR_MPR; /* mem prot trap */ -if (BPA_IS_NXM (bpa)) /* also check NXM */ - tr |= TR_NXM; /* on MPR or WLK */ -return tr; -} - -/* Physical byte access routines */ - -uint32 ReadPB (uint32 ba, uint32 *wd) -{ -uint32 sc; - -ba = ba & BPAMASK; -if (BPA_IS_NXM (ba)) - return TR_NXM; -sc = 24 - ((ba & 3) << 3); -*wd = (M[ba >> 2] >> sc) & BMASK; -return 0; -} - -uint32 WritePB (uint32 ba, uint32 wd) -{ -uint32 sc; - -ba = ba & BPAMASK; -if (BPA_IS_NXM (ba)) - return TR_NXM; -sc = 24 - ((ba & 3) << 3); -M[ba >> 2] = (M[ba >> 2] & ~(BMASK << sc)) | ((wd & BMASK) << sc); -return 0; -} - -/* Physical word access routines */ - -uint32 ReadPW (uint32 pa, uint32 *wd) -{ -pa = pa & cpu_tab[cpu_model].pamask; -if (MEM_IS_NXM (pa)) - return TR_NXM; -*wd = M[pa]; -return 0; -} - -uint32 WritePW (uint32 pa, uint32 wd) -{ -pa = pa & cpu_tab[cpu_model].pamask; -if (MEM_IS_NXM (pa)) - return TR_NXM; -M[pa] = wd; -return 0; -} - -/* LRA - load real address (extended memory systems only) */ - -uint32 map_lra (uint32 rn, uint32 IR) -{ -uint32 lnt, bva, bpa, vpag, ppag; -uint32 tr; - -lnt = CC >> 2; /* length */ -CC = 0; /* clear */ -if ((tr = Ea (IR, &bva, VR, lnt)) != 0) { /* get eff addr */ - if (tr == TR_NXM) /* NXM trap? */ - CC = CC1|CC2; - R[rn] = bva >> 2; /* fails */ - } -else if (bva < BVA_REG) { /* reg ref? */ - CC = CC1|CC2; - R[rn] = bva >> 2; /* fails */ - } -else { - vpag = BVA_GETPAG (bva); /* virt page num */ - bpa = ((mmc_rel[vpag] << BVA_V_PAG) + BVA_GETOFF (bva)) & BPAMASK; - ppag = BPA_GETPAG (bpa); /* phys page num */ - if (MEM_IS_NXM (bpa)) /* NXM? */ - CC = CC1|CC2; - R[rn] = (QCPU_S9? (mmc_wlk[ppag] << 24): 0) | /* result */ - (bpa >> lnt); - CC |= mmc_acc[vpag]; /* access prot */ - } -return 0; -} - -/* MMC - load memory map control */ - -uint32 map_mmc (uint32 rn, uint32 map) -{ -uint32 tr; -uint32 wd, i, map_width, maps_per_word, map_cmask, cs; - -map_width = mmc_tab[map].width; /* width in bits */ -maps_per_word = 32 / map_width; -if (map != 1) /* maps 2-7? */ - map_cmask = mmc_tab[map].cmask; /* std ctl mask */ -else map_cmask = cpu_tab[cpu_model].mmc_cm_map1; /* model based */ -if ((map_width == 0) || /* validate map */ - ((cpu_unit.flags & mmc_tab[map].opt) == 0) || - ((map == 3) && !QCPU_5X0) || - ((map == 5) && !QCPU_BIGM)) { - if (QCPU_S89_5X0) /* S89, 5X0 trap */ - return TR_INVMMC; - return stop_op? STOP_ILLEG: 0; - } -do { - cs = (R[rn|1] >> MMC_V_CS) & map_cmask; /* ptr into map */ - if ((tr = ReadW ((R[rn] << 2) & BVAMASK, &wd, VR)) != 0) - return tr; - for (i = 0; i < maps_per_word; i++) { /* loop thru word */ - wd = ((wd << map_width) | (wd >> (32 - map_width))) & WMASK; - switch (map) { - - case 1: case 3: /* write locks */ - mmc_wlk[cs] = wd & mmc_tab[map].dmask; - break; - - case 2: /* access ctls */ - mmc_acc[cs] = wd & mmc_tab[map].dmask; - break; - - case 4: case 5: /* relocation */ - mmc_rel[cs] = wd & mmc_tab[map].dmask; - break; - }; - cs = (cs + 1) % mmc_tab[map].lnt; /* incr mod lnt */ - } /* end for */ - R[rn] = (R[rn] + 1) & WMASK; /* incr mem ptr */ - R[rn|1] = (R[rn|1] & ~(MMC_CNT | (map_cmask << MMC_V_CS))) | - (((MMC_GETCNT (R[rn|1]) - 1) & MMC_M_CNT) << MMC_V_CNT) | - ((cs & map_cmask) << MMC_V_CS); - } while (MMC_GETCNT (R[rn|1]) != 0); -return SCPE_OK; -} - -/* LAS instruction (reused by LMS), without condition code settings */ - -uint32 map_las (uint32 rn, uint32 bva) -{ -uint32 opnd, tr; - -if ((bva < (RF_NUM << 2)) && QCPU_5X0) /* on 5X0, reg */ - ReadW (bva, &opnd, VR); /* refs ignored */ -else { /* go to mem */ - if ((tr = ReadMemVW (bva, &opnd, VR)) != 0) /* read word */ - return tr; - if ((tr = WriteMemVW (bva, opnd | WSIGN, VW)) != 0) /* set bit */ - return tr; - } -R[rn] = opnd; /* store */ -return 0; -} - -/* Load memory status */ - -uint32 map_lms (uint32 rn, uint32 bva) -{ -uint32 tr, wd, low, ppag; -uint32 memu = (bva >> 2) / CPU_MUNIT_SIZE; - -if (CC == 0) /* LAS */ - return map_las (rn, bva); -if (CC == 1) { /* read no par */ - if ((tr = ReadW (bva, &wd, PH)) != 0) - return tr; - R[rn] = wd; - for (CC = CC3; wd != 0; CC ^= CC3) { /* calc odd par */ - low = wd & -((int32) wd); - wd = wd & ~low; - } - return 0; - } - -ppag = BPA_GETPAG (bva); /* phys page num */ -wd = mem_sr0[memu]; /* save sr0 */ -if (QCPU_S89) - switch (CC) { /* Sigma 8-9 */ - case 0x2: /* read bad par */ - if ((tr = ReadW (bva, &wd, VR)) != 0) - return tr; - R[rn] = wd; - break; - case 0x7: /* set margins */ - mem_sr1[memu] = S89_SR1_FIXED | - ((memu & S89_SR1_M_MEMU) << S89_SR1_V_MEMU) | - ((R[rn] & S89_SR1_MARG) >> S89_SR1_MAROFF); - break; - case 0xB: /* read sr0, clr */ - mem_sr0[memu] = mem_sr1[memu] = 0; - case 0x8: /* read sr0 */ - R[rn] = (wd & S89_SR0_RD) | - (((1u << (chan_num + 1)) - 1) << (S89_SR0_V_PORTS - (chan_num + 1))); - break; - case 0x9: /* read sr1 */ - R[rn] = mem_sr1[memu]; - break; - case 0xA: case 0xE: /* read sr2 */ - R[rn] = 0; - break; - case 0xF: /* clear word */ - return WriteW (bva, 0, VW); - break; - default: - mem_sr0[memu] |= S89_SR0_BADLMS; - break; - } -else switch (CC) { /* 5X0 */ - case 0x2: /* clear word */ - return WriteW (bva, 0, VW); - case 0x6: /* read wlk */ - R[rn] = (mmc_wlk[ppag & ~1] << 4) | mmc_wlk[ppag | 1]; - break; - case 0x7: /* write wlk */ - mmc_wlk[ppag & ~1] = (R[rn] >> 4) & 0xF; - mmc_wlk[ppag | 1] = R[rn] & 0xF; - break; - case 0xC: /* read sr0, clr */ - mem_sr0[memu] = 0; - case 0x8: /* read sr0 */ - R[rn] = S5X0_SR0_FIXED | (wd & S5X0_SR0_RD) | - (((1u << (chan_num + 1)) - 1) << (S5X0_SR0_V_PORTS - (chan_num + 1))); - break; - case 0xA: /* read sr1 */ - R[rn] = S5X0_SR1_FIXED | - ((memu & S5X0_SR1_M_MEMU) << S5X0_SR1_V_MEMU) | - (memu << S5X0_SR1_V_SA); - break; - case 0xE: /* trash mem */ - return WriteW (bva, R[rn] & ~0xFF, VW); - default: - mem_sr0[memu] |= S5X0_SR0_BADLMS; - break; - } -return 0; -} - -/* Device reset */ - -t_stat map_reset (DEVICE *dptr) -{ -uint32 i; - -for (i = 0; i < VA_NUM_PAG; i++) { /* clear mmc arrays */ - mmc_rel[i] = 0; - mmc_acc[i] = 0; - } -for (i = 0; i < PA_NUM_PAG; i++) - mmc_wlk[i] = 0; -return SCPE_OK; -} diff --git a/sigma/sigma_mt.c b/sigma/sigma_mt.c deleted file mode 100644 index 7e3e9f35..00000000 --- a/sigma/sigma_mt.c +++ /dev/null @@ -1,645 +0,0 @@ -/* sigma_mt.c: Sigma 732X 9-track magnetic tape - - Copyright (c) 2007-2008, Robert M. Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - mt 7320 and 7322/7323 magnetic tape - - Magnetic tapes are represented as a series of variable records - of the form: - - 32b byte count - byte 0 - byte 1 - : - byte n-2 - byte n-1 - 32 byte count - - If the byte count is odd, the record is padded with an extra byte - of junk. File marks are represented by a byte count of 0. -*/ - -#include "sigma_io_defs.h" -#include "sim_tape.h" - -/* Device definitions */ - -#define MT_NUMDR 8 /* #drives */ -#define MT_REW (MT_NUMDR) /* rewind threads */ -#define UST u3 /* unit status */ -#define UCMD u4 /* unit command */ -#define MT_MAXFR (1 << 16) /* max record lnt */ - -/* Unit commands */ - -#define MCM_INIT 0x100 -#define MCM_END 0x101 -#define MCM_WRITE 0x01 -#define MCM_READ 0x02 -#define MCM_SETC 0x03 -#define MCM_SENSE 0x04 -#define MCM_RDBK 0x0C -#define MCM_RWI 0x13 -#define MCM_RWU 0x23 -#define MCM_REW 0x33 -#define MCM_SFWR 0x43 -#define MCM_SBKR 0x4B -#define MCM_SFWF 0x53 -#define MCM_SBKF 0x5B -#define MCM_ERS 0x63 -#define MCM_WTM 0x73 - -/* Command flags */ - -#define O_ATT 0x01 /* req attached */ -#define O_WRE 0x02 /* req write enb */ -#define O_REV 0x04 /* reverse oper */ -#define O_NMT 0x10 /* no motion */ - -/* Device status in UST, ^ = dynamic */ - -#define MTDV_OVR 0x80 /* overrun - NI */ -#define MTDV_WRE 0x40 /* write enabled^ */ -#define MTDV_WLE 0x20 /* write lock err */ -#define MTDV_EOF 0x10 /* end of file */ -#define MTDV_DTE 0x08 /* data error */ -#define MTDV_BOT 0x04 /* begin of tape */ -#define MTDV_EOT 0x02 /* end of tape^ */ -#define MTDV_REW 0x01 /* rewinding^ */ - -#define MTAI_MASK (MTDV_OVR|MTDV_WLE|MTDV_EOF|MTDV_DTE) -#define MTAI_V_INT 6 -#define MTAI_INT (1u << MTAI_V_INT) - -uint32 mt_stopioe = 1; -int32 mt_rwtime = 10000; /* rewind latency */ -int32 mt_ctime = 100; /* command latency */ -int32 mt_time = 10; /* record latency */ -uint32 mt_rwi = 0; /* rewind interrupts */ -t_mtrlnt mt_bptr; -t_mtrlnt mt_blim; -uint8 mt_xb[MT_MAXFR]; /* transfer buffer */ -uint8 mt_op[128] = { - 0, O_ATT|O_WRE, O_ATT, O_NMT, O_NMT, 0, 0, 0, /* wr, rd, set, sense */ - 0, 0, 0, 0, O_ATT|O_REV, 0, 0, 0, /* rd rev */ - 0, 0, 0, O_ATT, 0, 0, 0, 0, /* rewind & int */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, O_ATT, 0, 0, 0, 0, /* rewind offline */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, O_ATT, 0, 0, 0, 0, /* rewind */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, O_ATT, 0, 0, 0, 0, /* space fwd rec */ - 0, 0, 0, O_ATT|O_REV, 0, 0, 0, 0, /* space bk rec */ - 0, 0, 0, O_ATT, 0, 0, 0, 0, /* space fwd file */ - 0, 0, 0, O_ATT|O_REV, 0, 0, 0, 0, /* space bk file */ - 0, 0, 0, O_NMT, 0, 0, 0, 0, /* set erase */ - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, O_ATT|O_WRE, 0, 0, 0, 0, /* write tmk */ - 0, 0, 0, 0, 0, 0, 0, 0 - }; - -extern uint32 chan_ctl_time; -extern uint8 ascii_to_ebcdic[128]; -extern uint8 ebcdic_to_ascii[256]; - -uint32 mt_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 mt_tio_status (uint32 un); -uint32 mt_tdv_status (uint32 un); -t_stat mt_chan_err (uint32 st); -t_stat mtu_svc (UNIT *uptr); -t_stat mtr_svc (UNIT *uptr); -t_stat mt_reset (DEVICE *dptr); -t_stat mt_attach (UNIT *uptr, char *cptr); -t_stat mt_detach (UNIT *uptr); -t_stat mt_flush_buf (uptr); -t_stat mt_map_err (UNIT *uptr, t_stat r); -int32 mt_clr_int (uint32 dva); -void mt_set_rwi (uint32 un); -void mt_clr_rwi (uint32 un); - -/* MT data structures - - mt_dev MT device descriptor - mt_unit MT unit descriptors - mt_reg MT register list - mt_mod MT modifiers list -*/ - -dib_t mt_dib = { DVA_MT, mt_disp }; - -/* First 'n' units are tape drives; second 'n' are rewind threads */ - -UNIT mt_unit[] = { - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtu_svc, UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) }, - { UDATA (&mtr_svc, UNIT_DIS, 0) } - }; - -REG mt_reg[] = { - { BRDATA (BUF, mt_xb, 16, 8, MT_MAXFR) }, - { DRDATA (BPTR, mt_bptr, 17) }, - { DRDATA (BLNT, mt_blim, 17) }, - { HRDATA (RWINT, mt_rwi, MT_NUMDR) }, - { DRDATA (TIME, mt_time, 24), PV_LEFT+REG_NZ }, - { DRDATA (CTIME, mt_ctime, 24), PV_LEFT+REG_NZ }, - { DRDATA (RWTIME, mt_rwtime, 24), PV_LEFT+REG_NZ }, - { URDATA (UST, mt_unit[0].UST, 16, 8, 0, MT_NUMDR, 0) }, - { URDATA (UCMD, mt_unit[0].UCMD, 16, 8, 0, 2 * MT_NUMDR, 0) }, - { URDATA (POS, mt_unit[0].pos, 10, T_ADDR_W, 0, - MT_NUMDR, PV_LEFT | REG_RO) }, - { FLDATA (STOP_IOE, mt_stopioe, 0) }, - { HRDATA (DEVNO, mt_dib.dva, 12), REG_HRO }, - { NULL } - }; - -MTAB mt_mod[] = { - { MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL }, - { MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL }, - { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", - &sim_tape_set_fmt, &sim_tape_show_fmt, NULL }, - { MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY", - &sim_tape_set_capac, &sim_tape_show_capac, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE mt_dev = { - "MT", mt_unit, mt_reg, mt_mod, - MT_NUMDR * 2, 10, T_ADDR_W, 1, 16, 8, - NULL, NULL, &mt_reset, - &io_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_DISABLE - }; - -/* Magtape: IO dispatch routine */ - -uint32 mt_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -uint32 un = DVA_GETUNIT (dva); -UNIT *uptr = &mt_unit[un]; - -if ((un >= MT_NUMDR) || /* inv unit num? */ - (uptr-> flags & UNIT_DIS)) /* disabled unit? */ - return DVT_NODEV; -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = mt_tio_status (un); /* get status */ - if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ - uptr->UCMD = MCM_INIT; /* start dev thread */ - sim_activate (uptr, chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = mt_tio_status (un); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = mt_tdv_status (un); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - *dvst = mt_tio_status (un); /* get status */ - if ((int32) un == chan_chk_chi (dva)) /* halt active ctlr int? */ - chan_clr_chi (dva); /* clear ctlr int */ - if (sim_is_active (uptr)) { /* chan active? */ - sim_cancel (uptr); /* stop unit */ - chan_uen (dva); /* uend */ - } - mt_clr_rwi (un); /* clear rewind int */ - sim_cancel (uptr + MT_REW); /* cancel rewind */ - break; - - case OP_AIO: /* acknowledge int */ - un = mt_clr_int (mt_dib.dva); /* clr int, get unit */ - *dvst = (mt_tdv_status (un) & MTAI_MASK) | /* device status */ - (un & MTAI_INT) | /* device int flag */ - ((un & DVA_M_UNIT) << DVT_V_UN); /* unit number */ - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Unit service */ - -t_stat mtu_svc (UNIT *uptr) -{ -uint32 cmd = uptr->UCMD; -uint32 un = uptr - mt_unit; -uint32 c; -uint32 st; -int32 t; -t_mtrlnt tbc; -t_stat r; - -if (cmd == MCM_INIT) { /* init state */ - if ((t = sim_is_active (uptr + MT_REW)) != 0) { /* rewinding? */ - sim_activate (uptr, t); /* retry later */ - return SCPE_OK; - } - st = chan_get_cmd (mt_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return mt_chan_err (st); - if ((cmd & 0x80) || /* invalid cmd? */ - (mt_op[cmd] == 0)) { - uptr->UCMD = MCM_END; /* end state */ - sim_activate (uptr, chan_ctl_time); /* resched ctlr */ - return SCPE_OK; - } - else { /* valid cmd */ - if ((mt_op[cmd] & O_REV) && /* reverse op */ - (mt_unit[un].UST & MTDV_BOT)) { /* at load point? */ - chan_uen (mt_dib.dva); /* channel end */ - return SCPE_OK; - } - uptr->UCMD = cmd; /* unit state */ - if (!(mt_op[cmd] & O_NMT)) /* motion? */ - uptr->UST = 0; /* clear status */ - } - mt_blim = 0; /* no buffer yet */ - sim_activate (uptr, chan_ctl_time); /* continue thread */ - return SCPE_OK; /* done */ - } - -if (cmd == MCM_END) { /* end state */ - st = chan_end (mt_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return mt_chan_err (st); - if (st == CHS_CCH) { /* command chain? */ - uptr->UCMD = MCM_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - else uptr->UCMD = 0; /* ctlr idle */ - return SCPE_OK; /* done */ - } - -if ((mt_op[cmd] & O_ATT) && /* op req att and */ - ((uptr->flags & UNIT_ATT) == 0)) { /* not attached? */ - sim_activate (uptr, mt_ctime); /* retry */ - return mt_stopioe? SCPE_UNATT: SCPE_OK; - } -if ((mt_op[cmd] & O_WRE) && /* write op and */ - sim_tape_wrp (uptr)) { /* write protected? */ - uptr->UST |= MTDV_WLE; /* set status */ - chan_uen (mt_dib.dva); /* unusual end */ - return SCPE_OK; - } - -r = SCPE_OK; -switch (cmd) { /* case on command */ - - case MCM_SFWR: /* space forward */ - if (r = sim_tape_sprecf (uptr, &tbc)) /* spc rec fwd, err? */ - r = mt_map_err (uptr, r); /* map error */ - break; - - case MCM_SBKR: /* space reverse */ - if (r = sim_tape_sprecr (uptr, &tbc)) /* spc rec rev, err? */ - r = mt_map_err (uptr, r); /* map error */ - break; - - case MCM_SFWF: /* space fwd file */ - while ((r = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ; - if (r != MTSE_TMK) /* stopped by tmk? */ - r = mt_map_err (uptr, r); /* no, map error */ - else r = SCPE_OK; - break; - - case MCM_SBKF: /* space rev file */ - while ((r = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ; - if (r != MTSE_TMK) /* stopped by tmk? */ - r = mt_map_err (uptr, r); /* no, map error */ - else r = SCPE_OK; - break; - - case MCM_WTM: /* write eof */ - if (r = sim_tape_wrtmk (uptr)) /* write tmk, err? */ - r = mt_map_err (uptr, r); /* map error */ - uptr->UST |= MTDV_EOF; /* set eof */ - break; - - case MCM_RWU: /* rewind unload */ - r = detach_unit (uptr); - break; - - case MCM_REW: /* rewind */ - case MCM_RWI: /* rewind and int */ - if (r = sim_tape_rewind (uptr)) /* rewind */ - r = mt_map_err (uptr, r); /* map error */ - mt_unit[un + MT_REW].UCMD = uptr->UCMD; /* copy command */ - sim_activate (uptr + MT_REW, mt_rwtime); /* sched compl */ - break; - - case MCM_READ: /* read */ - if (mt_blim == 0) { /* first read? */ - r = sim_tape_rdrecf (uptr, mt_xb, &mt_blim, MT_MAXFR); - if (r != MTSE_OK) { /* tape error? */ - r = mt_map_err (uptr, r); /* map error */ - break; - } - mt_bptr = 0; /* init rec ptr */ - } - c = mt_xb[mt_bptr++]; /* get char */ - st = chan_WrMemB (mt_dib.dva, c); /* write to memory */ - if (CHS_IFERR (st)) /* channel error? */ - return mt_chan_err (st); - if ((st != CHS_ZBC) && (mt_bptr != mt_blim)) { /* not done? */ - sim_activate (uptr, mt_time); /* continue thread */ - return SCPE_OK; - } - if (((st == CHS_ZBC) ^ (mt_bptr == mt_blim)) && /* length err? */ - chan_set_chf (mt_dib.dva, CHF_LNTE)) /* uend taken? */ - return SCPE_OK; /* finished */ - break; /* normal end */ - - case MCM_RDBK: /* read reverse */ - if (mt_blim == 0) { /* first read? */ - r = sim_tape_rdrecr (uptr, mt_xb, &mt_blim, MT_MAXFR); - if (r != MTSE_OK) { /* tape error? */ - r = mt_map_err (uptr, r); /* map error */ - break; - } - mt_bptr = mt_blim; /* init rec ptr */ - } - c = mt_xb[--mt_bptr]; /* get char */ - st = chan_WrMemBR (mt_dib.dva, c); /* write mem rev */ - if (CHS_IFERR (st)) /* channel error? */ - return mt_chan_err (st); - if ((st != CHS_ZBC) && (mt_bptr != 0)) { /* not done? */ - sim_activate (uptr, mt_time); /* continue thread */ - return SCPE_OK; - } - if (((st == CHS_ZBC) ^ (mt_bptr == 0)) && /* length err? */ - chan_set_chf (mt_dib.dva, CHF_LNTE)) /* uend taken? */ - return SCPE_OK; /* finished */ - break; /* normal end */ - - case MCM_WRITE: /* write */ - st = chan_RdMemB (mt_dib.dva, &c); /* read char */ - if (CHS_IFERR (st)) { /* channel error? */ - mt_flush_buf (uptr); /* flush buffer */ - return mt_chan_err (st); - } - mt_xb[mt_blim++] = c; /* store in buffer */ - if (st != CHS_ZBC) { /* end record? */ - sim_activate (uptr, mt_time); /* continue thread */ - return SCPE_OK; - } - r = mt_flush_buf (uptr); /* flush buffer */ - break; - } - -if (r != SCPE_OK) /* error? abort */ - return CHS_IFERR(r)? SCPE_OK: r; -uptr->UCMD = MCM_END; /* end state */ -sim_activate (uptr, mt_ctime); /* sched ctlr */ -return SCPE_OK; -} - -/* Rewind completion - set BOT, interrupt if desired */ - -t_stat mtr_svc (UNIT *uptr) -{ -uint32 un = uptr - mt_unit - MT_REW; - -mt_unit[un].UST |= MTDV_BOT; /* set BOT */ -if (uptr->UCMD == MCM_RWI) /* int wanted? */ - mt_set_rwi (un); /* interrupt */ -return SCPE_OK; -} - -t_stat mt_flush_buf (UNIT *uptr) -{ -t_stat st; - -if (mt_blim == 0) /* any output? */ - return SCPE_OK; -if (st = sim_tape_wrrecf (uptr, mt_xb, mt_blim)) /* write, err? */ - return mt_map_err (uptr, st); /* map error */ -return SCPE_OK; -} - -/* Map tape error status - returns chan error or SCP status */ - -t_stat mt_map_err (UNIT *uptr, t_stat st) -{ -int32 u = uptr - mt_dev.units; - -switch (st) { - - case MTSE_FMT: /* illegal fmt */ - case MTSE_UNATT: /* not attached */ - case MTSE_WRP: /* write protect */ - chan_set_chf (mt_dib.dva, CHF_XMME); - case MTSE_OK: /* no error */ - chan_uen (mt_dib.dva); /* uend */ - return SCPE_IERR; - - case MTSE_TMK: /* end of file */ - uptr->UST |= MTDV_EOF; /* set eof flag */ - chan_uen (mt_dib.dva); /* uend */ - return CHS_INACTV; - - case MTSE_IOERR: /* IO error */ - uptr->UST |= MTDV_DTE; /* set DTE flag */ - chan_set_chf (mt_dib.dva, CHF_XMDE); - chan_uen (mt_dib.dva); /* force uend */ - return SCPE_IOERR; - - case MTSE_INVRL: /* invalid rec lnt */ - uptr->UST |= MTDV_DTE; /* set DTE flag */ - chan_set_chf (mt_dib.dva, CHF_XMDE); - chan_uen (mt_dib.dva); /* force uend */ - return SCPE_MTRLNT; - - case MTSE_RECE: /* record in error */ - case MTSE_EOM: /* end of medium */ - uptr->UST |= MTDV_DTE; /* set DTE flag */ - return chan_set_chf (mt_dib.dva, CHF_XMDE); /* possible error */ - - case MTSE_BOT: /* reverse into BOT */ - uptr->UST |= MTDV_BOT; /* set BOT */ - chan_uen (mt_dib.dva); /* uend */ - return CHS_INACTV; - } /* end switch */ - -return SCPE_OK; -} - -/* MT status routine */ - -uint32 mt_tio_status (uint32 un) -{ -uint32 i, st; -UNIT *uptr = &mt_unit[un]; - -st = (uptr->flags & UNIT_ATT)? DVS_AUTO: 0; /* AUTO */ -if (sim_is_active (uptr) || /* unit busy */ - sim_is_active (uptr + MT_REW)) /* or rewinding? */ - st |= DVS_DBUSY; -for (i = 0; i < MT_NUMDR; i++) { /* loop thru units */ - if (sim_is_active (&mt_unit[i])) { /* active? */ - st |= (DVS_CBUSY | (CC2 << DVT_V_CC)); /* ctrl is busy */ - } - } -return st; -} - -uint32 mt_tdv_status (uint32 un) -{ -uint32 st; -UNIT *uptr = &mt_unit[un]; - -if (uptr->flags & UNIT_ATT) { /* attached? */ - st = uptr->UST; /* unit stat */ - if (sim_tape_eot (uptr)) /* at EOT? */ - st |= MTDV_EOT; - if (!sim_tape_wrp (uptr)) /* not wlock? */ - st |= MTDV_WRE; - } -else st = (CC2 << DVT_V_CC); -if (sim_is_active (uptr + MT_REW)) /* unit rewinding? */ - st |= (MTDV_REW | (CC2 << DVT_V_CC)); -return st; -} - - -/* Channel error */ - -t_stat mt_chan_err (uint32 st) -{ -chan_uen (mt_dib.dva); /* uend */ -if (st < CHS_ERR) - return st; -return SCPE_OK; -} - -/* Clear controller/device interrupt, return active unit */ - -int32 mt_clr_int (uint32 dva) -{ -int32 iu; - -if ((iu = chan_clr_chi (dva)) >= 0) { /* chan int? clear */ - if (mt_rwi != 0) /* dev ints? */ - chan_set_dvi (dva); /* set them */ - return iu; - } -for (iu = 0; iu < MT_NUMDR; iu++) { /* rewind int? */ - if (mt_rwi & (1u << iu)) { - mt_clr_rwi ((uint32) iu); - return (iu | MTAI_INT); - } - } -return 0; -} - -/* Set rewind interrupt */ - -void mt_set_rwi (uint32 un) -{ -mt_rwi |= (1u << un); -chan_set_dvi (mt_dib.dva); /* set INP */ -return; -} - -/* Clear rewind interrupt */ - -void mt_clr_rwi (uint32 un) -{ -mt_rwi &= ~(1u << un); /* clear */ -if (mt_rwi != 0) /* more? */ - chan_set_dvi (mt_dib.dva); -else if (chan_chk_chi (mt_dib.dva) < 0) /* any int? */ - chan_clr_chi (mt_dib.dva); /* clr INP */ -return; -} - -/* Reset routine */ - -t_stat mt_reset (DEVICE *dptr) -{ -uint32 i; - -for (i = 0; i < MT_NUMDR; i++) { - sim_cancel (&mt_unit[i]); /* stop unit */ - sim_cancel (&mt_unit[i + MT_REW]); /* stop rewind */ - mt_unit[i].UST = 0; - mt_unit[i].UCMD = 0; - } -mt_rwi = 0; -mt_bptr = 0; -mt_blim = 0; -chan_reset_dev (mt_dib.dva); /* clr int, active */ -for (i = 0; i < MT_MAXFR; i++) - mt_xb[i] = 0; -return SCPE_OK; -} - -/* Attach routine */ - -t_stat mt_attach (UNIT *uptr, char *cptr) -{ -t_stat r; - -r = sim_tape_attach (uptr, cptr); -if (r != SCPE_OK) return r; -uptr->UST = MTDV_BOT; -return r; -} - -/* Detach routine */ - -t_stat mt_detach (UNIT* uptr) -{ -uint32 un = uptr - mt_dev.units; - -uptr->UST = 0; -sim_cancel (uptr + MT_REW); -return sim_tape_detach (uptr); -} \ No newline at end of file diff --git a/sigma/sigma_pt.c b/sigma/sigma_pt.c deleted file mode 100644 index f5507f6b..00000000 --- a/sigma/sigma_pt.c +++ /dev/null @@ -1,297 +0,0 @@ -/* sigma_pt.c: Sigma 7060 paper tape reader/punch - - Copyright (c) 2007-2008, Robert M. Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - pt 7060 paper-tape reader/punch -*/ - -#include "sigma_io_defs.h" - -/* Device definitions */ - -#define PTR 0 -#define PTP 1 - -/* Device states */ - -#define PTS_INIT 0x101 -#define PTS_END 0x102 -#define PTS_WRITE 0x1 -#define PTS_READ 0x2 -#define PTS_READI 0x82 - -/* Device status */ - -#define PTDV_PMAN 0x20 -#define PTDV_RMAN 0x10 - -uint32 pt_cmd = 0; -uint32 ptr_nzc = 0; -uint32 ptr_stopioe = 1; -uint32 ptp_stopioe = 1; - -extern uint32 chan_ctl_time; -extern uint8 ascii_to_ebcdic[128]; -extern uint8 ebcdic_to_ascii[256]; - -uint32 pt_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 pt_tio_status (void); -uint32 pt_tdv_status (void); -t_stat pt_chan_err (uint32 st); -t_stat pt_svc (UNIT *uptr); -t_stat pt_reset (DEVICE *dptr); -t_stat pt_attach (UNIT *uptr, char *cptr); - -/* PT data structures - - pt_dev PT device descriptor - pt_unit PT unit descriptors - pt_reg PT register list - pt_mod PT modifiers list -*/ - -dib_t pt_dib = { DVA_PT, pt_disp }; - -UNIT pt_unit[] = { - { UDATA (&pt_svc, UNIT_ATTABLE+UNIT_SEQ+UNIT_ROABLE, 0), SERIAL_IN_WAIT }, - { UDATA (&pt_svc, UNIT_ATTABLE+UNIT_SEQ, 0), SERIAL_OUT_WAIT } - }; - -REG pt_reg[] = { - { HRDATA (CMD, pt_cmd, 9) }, - { FLDATA (NZC, ptr_nzc,0) }, - { DRDATA (RPOS, pt_unit[PTR].pos, T_ADDR_W), PV_LEFT }, - { DRDATA (RTIME, pt_unit[PTR].wait, 24), PV_LEFT }, - { FLDATA (RSTOP_IOE, ptr_stopioe, 0) }, - { DRDATA (PPOS, pt_unit[PTP].pos, T_ADDR_W), PV_LEFT }, - { DRDATA (PTIME, pt_unit[PTP].wait, 24), REG_NZ + PV_LEFT }, - { FLDATA (PSTOP_IOE, ptp_stopioe, 0) }, - { HRDATA (DEVNO, pt_dib.dva, 12), REG_HRO }, - { NULL } - }; - -MTAB pt_mod[] = { - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE pt_dev = { - "PT", pt_unit, pt_reg, pt_mod, - 2, 10, 31, 1, 16, 8, - NULL, NULL, &pt_reset, - &io_boot, &pt_attach, NULL, - &pt_dib, DEV_DISABLE - }; - -/* Reader/punch: IO dispatch routine */ - -uint32 pt_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = pt_tio_status (); /* get status */ - if ((*dvst & DVS_DST) == 0) { /* idle? */ - pt_cmd = PTS_INIT; /* start dev thread */ - sim_activate (&pt_unit[PTR], chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = pt_tio_status (); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = pt_tdv_status (); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - chan_clr_chi (pt_dib.dva); /* clr int*/ - *dvst = pt_tio_status (); /* get status */ - if ((*dvst & DVS_DST) != 0) { /* busy? */ - sim_cancel (&pt_unit[PTR]); /* stop dev thread */ - chan_uen (pt_dib.dva); /* uend */ - } - break; - - case OP_AIO: /* acknowledge int */ - chan_clr_chi (pt_dib.dva); /* clr int*/ - *dvst = 0; /* no status */ - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Service routine */ - -t_stat pt_svc (UNIT *uptr) -{ -int32 c; -uint32 cmd; -uint32 st; - -switch (pt_cmd) { /* case on state */ - - case PTS_INIT: /* I/O init */ - st = chan_get_cmd (pt_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return pt_chan_err (st); - if ((cmd == PTS_WRITE) || /* valid command? */ - ((cmd & 0x7F) == PTS_READ)) - pt_cmd = cmd; /* next state */ - else pt_cmd = PTS_END; /* no, end state */ - sim_activate (uptr, chan_ctl_time); /* continue thread */ - break; - - case PTS_READ: - case PTS_READI: - sim_activate (uptr, uptr->wait); /* continue thread */ - if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ - return ptr_stopioe? SCPE_UNATT: SCPE_OK; - if ((c = getc (uptr->fileref)) == EOF) { /* read char */ - if (feof (uptr->fileref)) { /* end of file? */ - chan_set_chf (pt_dib.dva, CHF_LNTE); /* length error */ - pt_cmd = PTS_END; /* end state */ - break; - } - else { /* real error */ - perror ("PTR I/O error"); - clearerr (uptr->fileref); - chan_set_chf (pt_dib.dva, CHF_XMDE); /* data error */ - return pt_chan_err (SCPE_IOERR); /* force uend */ - } - } - uptr->pos = uptr->pos + 1; - if (c != 0) /* leader done? */ - ptr_nzc = 1; /* set flag */ - if ((pt_cmd == PTS_READI) || ptr_nzc) { - st = chan_WrMemB (pt_dib.dva, c); /* write to memory */ - if (CHS_IFERR (st)) /* channel error? */ - return pt_chan_err (st); - if (st == CHS_ZBC) /* bc == 0? */ - pt_cmd = PTS_END; /* end state */ - } - break; - - case PTS_WRITE: /* write */ - sim_activate (uptr, pt_unit[PTP].wait); /* continue thread */ - if ((pt_unit[PTP].flags & UNIT_ATT) == 0) /* not attached? */ - return ptp_stopioe? SCPE_UNATT: SCPE_OK; - st = chan_RdMemB (pt_dib.dva, &c); /* read from channel */ - if (CHS_IFERR (st)) /* channel error? */ - return pt_chan_err (st); - if (putc (c, pt_unit[PTP].fileref) == EOF) { - perror ("PTP I/O error"); - clearerr (pt_unit[PTP].fileref); - chan_set_chf (pt_dib.dva, CHF_XMDE); /* data error */ - return pt_chan_err (SCPE_IOERR); /* force uend */ - } - pt_unit[PTP].pos = pt_unit[PTP].pos + 1; - if (st == CHS_ZBC) /* bc == 0? */ - pt_cmd = PTS_END; /* end state */ - break; - - case PTS_END: /* command done */ - st = chan_end (pt_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return pt_chan_err (st); - if (st == CHS_CCH) { /* command chain? */ - pt_cmd = PTS_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - break; - } - -return SCPE_OK; -} - -/* PT status routine */ - -uint32 pt_tio_status (void) -{ -uint32 st; - -if (((pt_unit[PTR].flags & UNIT_ATT) == 0) || /* rdr not att? */ - ((pt_unit[PTP].flags & UNIT_ATT) == 0)) /* pun not att? */ - st = 0; -else st = DVS_AUTO; /* otherwise ok */ -if (sim_is_active (&pt_unit[PTR])) /* dev busy? */ - st |= (DVS_CBUSY | DVS_DBUSY | (CC2 << DVT_V_CC)); -return st; -} - -uint32 pt_tdv_status (void) -{ -uint32 st; - -st = 0; -if ((pt_unit[PTR].flags & UNIT_ATT) == 0) /* rdr not att? */ - st |= PTDV_RMAN; -if ((pt_unit[PTP].flags & UNIT_ATT) == 0) /* pun not att? */ - st |= PTDV_PMAN; -return st; -} - -/* Channel error */ - -t_stat pt_chan_err (uint32 st) -{ -sim_cancel (&pt_unit[PTR]); /* stop dev thread */ -chan_uen (pt_dib.dva); /* uend */ -if (st < CHS_ERR) - return st; -return SCPE_OK; -} - -/* Reset routine */ - -t_stat pt_reset (DEVICE *dptr) -{ -sim_cancel (&pt_unit[PTR]); /* stop dev thread */ -pt_cmd = 0; -chan_reset_dev (pt_dib.dva); /* clr int, active */ -return SCPE_OK; -} - -/* Attach routine */ - -t_stat pt_attach (UNIT *uptr, char *cptr) -{ -t_stat st; - -st = attach_unit (uptr, cptr); -if ((uptr == &pt_unit[PTR]) && (st == SCPE_OK)) - ptr_nzc = 0; -return st; -} \ No newline at end of file diff --git a/sigma/sigma_rad.c b/sigma/sigma_rad.c deleted file mode 100644 index 8ecdbd71..00000000 --- a/sigma/sigma_rad.c +++ /dev/null @@ -1,532 +0,0 @@ -/* sigma_rad.c: Sigma 7211/7212 or 7231/7232 fixed head disk simulator - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - rad 7211/7212 or 7231/7232 fixed head disk - - The RAD is a head-per-track disk. To minimize overhead, the entire RAD - is buffered in memory. - - Transfers are always done a sector at a time. -*/ - -#include "sigma_io_defs.h" -#include - -/* Constants */ - -#define RAD_7212 0 /* ctlr type */ -#define RAD_7232 1 -#define RAD_NUMDR 4 /* drives/ctlr */ -#define RAD_WDSC 256 /* words/sector */ -#define RAD_WDMASK (RAD_WDSC - 1) -#define RAD_SCTK1 82 /* sectors/track */ -#define RAD_SCTK3 12 -#define RAD_TKUN1 64 /* tracks/unit */ -#define RAD_TKUN3 512 -#define RAD_WDUNDF (RAD_WDSC*RAD_SCTK1*RAD_TKUN1) /* dflt words/unit */ -#define RAD_WDUN (RAD_WDSC*rad_tab[rad_model].sctk*rad_tab[rad_model].tkun) -#define RAD_N_WLK 16 /* num wlk switches */ - -/* Address bytes */ - -#define RADA_V_TK1 7 /* track offset */ -#define RADA_M_TK1 0xFF -#define RADA_V_SC1 0 /* sector offset */ -#define RADA_M_SC1 0x7F -#define RADA_V_TK3 4 -#define RADA_M_TK3 0x3FF -#define RADA_V_SC3 0 -#define RADA_M_SC3 0xF -#define RADA_GETTK(x) (((x) >> rad_tab[rad_model].tk_v) & rad_tab[rad_model].tk_m) -#define RADA_GETSC(x) (((x) >> rad_tab[rad_model].sc_v) & rad_tab[rad_model].sc_m) - -/* Address bad flag */ - -#define RADA_INV 0x80 - -/* Status byte 3 is current sector */ -/* Status byte 4 (7212 only) is failing sector */ - -#define RADS_NBY1 4 /* num status bytes */ -#define RADS_NBY3 3 - -/* Device state */ - -#define RADS_INIT 0x101 -#define RADS_END 0x102 -#define RADS_WRITE 0x01 -#define RADS_READ 0x02 -#define RADS_SEEK 0x03 -#define RADS_SENSE 0x04 -#define RADS_CHECK 0x05 -#define RADS_RDEES 0x12 - -/* Device status */ - -#define RADV_OVR 0x80 /* overrun - NI */ -#define RADV_BADS 0x20 /* bad sector */ -#define RADV_WPE 0x10 - -#define GET_PSC(x) ((int32) fmod (sim_gtime() / ((double) (x * RAD_WDSC)), \ - ((double) rad_tab[rad_model].sctk))) - -/* Model table */ - -typedef struct { - uint32 tk_v; /* track extract */ - uint32 tk_m; - uint32 sc_v; /* sector extract */ - uint32 sc_m; - uint32 sctk; /* sectors/track */ - uint32 tkun; /* tracks/unit */ - uint32 nbys; /* bytes of status */ - } rad_t; - -static rad_t rad_tab[] = { - { RADA_V_TK1, RADA_M_TK1, RADA_V_SC1, RADA_M_SC1, RAD_SCTK1, RAD_TKUN1, RADS_NBY1 }, - { RADA_V_TK3, RADA_M_TK3, RADA_V_SC3, RADA_M_SC3, RAD_SCTK3, RAD_TKUN3, RADS_NBY3 } - }; - -uint32 rad_model = RAD_7212; /* model */ -uint32 rad_cmd = 0; /* state */ -uint32 rad_flags = 0; /* status flags */ -uint32 rad_ad = 0; /* rad address */ -uint32 rad_wlk = 0; /* write lock */ -uint32 rad_time = 2; /* inter-word time */ - -extern uint32 chan_ctl_time; - -uint32 rad_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 rad_tio_status (uint32 un); -uint32 rad_tdv_status (uint32 un); -t_stat rad_chan_err (uint32 st); -t_stat rad_svc (UNIT *uptr); -t_stat rad_reset (DEVICE *dptr); -t_stat rad_settype (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat rad_showtype (FILE *st, UNIT *uptr, int32 val, void *desc); -t_bool rad_inv_ad (uint32 *da); -t_bool rad_inc_ad (void); -t_bool rad_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st); - -/* RAD data structures - - rad_dev RAD device descriptor - rad_unit RAD unit descriptor - rad_reg RAD register list -*/ - -dib_t rad_dib = { DVA_RAD, &rad_disp }; - -UNIT rad_unit[] = { - { UDATA (&rad_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE, RAD_WDUNDF) }, - { UDATA (&rad_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, RAD_WDUNDF) }, - { UDATA (&rad_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, RAD_WDUNDF) }, - { UDATA (&rad_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+ - UNIT_MUSTBUF+UNIT_DISABLE+UNIT_DIS, RAD_WDUNDF) } - }; - -REG rad_reg[] = { - { HRDATA (CMD, rad_cmd, 9) }, - { HRDATA (FLAGS, rad_flags, 8) }, - { HRDATA (ADDR, rad_ad, 15) }, - { HRDATA (WLK, rad_wlk, RAD_N_WLK) }, - { DRDATA (TIME, rad_time, 24), PV_LEFT }, - { FLDATA (MODEL, rad_model, 0), REG_HRO }, - { HRDATA (DEVNO, rad_dib.dva, 12), REG_HRO }, - { NULL } - }; - -MTAB rad_mod[] = { - { MTAB_XTD | MTAB_VDV, RAD_7212, NULL, "7211", - &rad_settype, NULL, NULL }, - { MTAB_XTD | MTAB_VDV, RAD_7212, NULL, "7212", - &rad_settype, NULL, NULL }, - { MTAB_XTD | MTAB_VDV, RAD_7232, NULL, "7231", - &rad_settype, NULL, NULL }, - { MTAB_XTD | MTAB_VDV, RAD_7232, NULL, "7232", - &rad_settype, NULL, NULL }, - { MTAB_XTD | MTAB_VDV, 0, "TYPE", NULL, - NULL, &rad_showtype, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE rad_dev = { - "RAD", rad_unit, rad_reg, rad_mod, - RAD_NUMDR, 16, 21, 1, 16, 32, - NULL, NULL, &rad_reset, - &io_boot, NULL, NULL, - &rad_dib, DEV_DISABLE - }; - -/* RAD: IO dispatch routine */ - -uint32 rad_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -uint32 i; -uint32 un = DVA_GETUNIT (dva); -UNIT *uptr; - -if ((un >= RAD_NUMDR) || /* inv unit num? */ - (rad_unit[un].flags & UNIT_DIS)) /* disabled unit? */ - return DVT_NODEV; -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = rad_tio_status (un); /* get status */ - if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ - rad_cmd = RADS_INIT; /* start dev thread */ - sim_activate (&rad_unit[un], chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = rad_tio_status (un); /* return status */ - break; - - case OP_TDV: /* test status */ - *dvst = rad_tdv_status (un); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - chan_clr_chi (rad_dib.dva); /* clr int*/ - *dvst = rad_tio_status (un); /* get status */ - if ((*dvst & DVS_CST) != 0) { /* ctrl busy? */ - for (i = 0; i < RAD_NUMDR; i++) { /* find busy unit */ - uptr = &rad_unit[i]; - if (sim_is_active (uptr)) { /* active? */ - sim_cancel (uptr); /* stop */ - chan_uen (rad_dib.dva); /* uend */ - } /* end if active */ - } /* end for */ - } - break; - - case OP_AIO: /* acknowledge int */ - chan_clr_chi (rad_dib.dva); /* clr int */ - *dvst = rad_tdv_status (0); /* status like TDV */ - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Unit service - this code assumes the entire disk is buffered */ - -t_stat rad_svc (UNIT *uptr) -{ -uint32 i, sc, da, cmd, wd, wd1, c[4], gp; -uint32 *fbuf = (uint32 *) uptr->filebuf; -uint32 st; -int32 t; - -switch (rad_cmd) { - - case RADS_INIT: /* init state */ - st = chan_get_cmd (rad_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return rad_chan_err (st); - if ((cmd == 0) || /* invalid cmd? */ - ((cmd > RADS_CHECK) && (cmd != RADS_RDEES))) { - chan_uen (rad_dib.dva); /* uend */ - return SCPE_OK; - } - rad_flags = 0; /* clear status */ - rad_cmd = cmd & 0x7; /* next state */ - if ((cmd == RADS_SEEK) || (cmd == RADS_SENSE)) /* seek or sense? */ - sim_activate (uptr, chan_ctl_time); /* schedule soon */ - else { /* data transfer */ - sc = RADA_GETSC (rad_ad); /* new sector */ - t = sc - GET_PSC (rad_time); /* delta to new */ - if (t < 0) /* wrap around? */ - t = t + rad_tab[rad_model].sctk; - sim_activate (uptr, t * rad_time * RAD_WDSC); /* schedule op */ - } - return SCPE_OK; - - case RADS_END: /* end state */ - st = chan_end (rad_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return rad_chan_err (st); - if (st == CHS_CCH) { /* command chain? */ - rad_cmd = RADS_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - return SCPE_OK; /* done */ - - case RADS_SEEK: /* seek */ - c[0] = c[1] = 0; - for (i = 0, st = 0; (i < 2) && (st != CHS_ZBC); i++) { - st = chan_RdMemB (rad_dib.dva, &c[i]); /* get byte */ - if (CHS_IFERR (st)) /* channel error? */ - return rad_chan_err (st); - } - rad_ad = ((c[0] & 0x7F) << 8) | c[1]; /* new address */ - if (((i != 2) || (st != CHS_ZBC)) && /* length error? */ - chan_set_chf (rad_dib.dva, CHF_LNTE)) /* care? */ - return SCPE_OK; - break; - - case RADS_SENSE: /* sense */ - c[0] = ((rad_ad >> 8) & 0x7F) | (rad_inv_ad (NULL)? RADA_INV: 0); - c[1] = rad_ad & 0xFF; /* address */ - c[2] = GET_PSC (rad_time); /* curr sector */ - c[3] = 0; - for (i = 0, st = 0; (i < rad_tab[rad_model].nbys) && (st != CHS_ZBC); i++) { - st = chan_WrMemB (rad_dib.dva, c[i]); /* store char */ - if (CHS_IFERR (st)) /* channel error? */ - return rad_chan_err (st); - } - if (((i != rad_tab[rad_model].nbys) || (st != CHS_ZBC)) && - chan_set_chf (rad_dib.dva, CHF_LNTE)) /* length error? */ - return SCPE_OK; - break; - - case RADS_WRITE: /* write */ - gp = (RADA_GETSC (rad_ad) * RAD_N_WLK) / /* write lock group */ - rad_tab[rad_model].tkun; - if ((rad_wlk >> gp) & 1) { /* write lock set? */ - rad_flags |= RADV_WPE; /* set status */ - chan_uen (rad_dib.dva); /* uend */ - return SCPE_OK; - } /* fall through */ - if (rad_inv_ad (&da)) { /* invalid addr? */ - chan_uen (rad_dib.dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; i < RAD_WDSC; da++, i++) { /* write */ - if (st != CHS_ZBC) { /* chan active? */ - st = chan_RdMemW (rad_dib.dva, &wd); /* get data */ - if (CHS_IFERR (st)) { /* channel error? */ - rad_inc_ad (); /* da increments */ - return rad_chan_err (st); - } - } - else wd = 0; - fbuf[da] = wd; /* store in buffer */ - if (da >= uptr->hwmark) /* update length */ - uptr->hwmark = da + 1; - } - if (rad_end_sec (uptr, i, RAD_WDSC, st)) /* transfer done? */ - return SCPE_OK; - break; - -/* Must be done by bytes to get precise miscompare */ - - case RADS_CHECK: /* write check */ - if (rad_inv_ad (&da)) { /* invalid addr? */ - chan_uen (rad_dib.dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; (i < (RAD_WDSC * 4)) && (st != CHS_ZBC); ) { - st = chan_RdMemB (rad_dib.dva, &wd); /* read sector */ - if (CHS_IFERR (st)) { /* channel error? */ - rad_inc_ad (); /* da increments */ - return rad_chan_err (st); - } - wd1 = (fbuf[da] >> (24 - ((i % 4) * 8))) & 0xFF; /* byte */ - if (wd != wd1) { /* check error? */ - rad_inc_ad (); /* da increments */ - chan_set_chf (rad_dib.dva, CHF_XMDE); /* set xmt err flag */ - chan_uen (rad_dib.dva); /* force uend */ - return SCPE_OK; - } - da = da + ((++i % 4) == 0); /* every 4th byte */ - } - if (rad_end_sec (uptr, i, RAD_WDSC * 4, st)) /* transfer done? */ - return SCPE_OK; - break; - - case RADS_READ: /* read */ - if (rad_inv_ad (&da)) { /* invalid addr? */ - chan_uen (rad_dib.dva); /* uend */ - return SCPE_OK; - } - for (i = 0, st = 0; (i < RAD_WDSC) && (st != CHS_ZBC); da++, i++) { - st = chan_WrMemW (rad_dib.dva, fbuf[da]); /* store in mem */ - if (CHS_IFERR (st)) { /* channel error? */ - rad_inc_ad (); /* da increments */ - return rad_chan_err (st); - } - } - if (rad_end_sec (uptr, i, RAD_WDSC, st)) /* transfer done? */ - return SCPE_OK; - break; - } - -rad_cmd = RADS_END; /* op done, next state */ -sim_activate (uptr, chan_ctl_time); -return SCPE_OK; -} - -/* Common read/write sector end routine - - case 1 - more to transfer, not end disk - reschedule, return TRUE - case 2 - more to transfer, end disk - uend, return TRUE - case 3 - transfer done, length error - uend, return TRUE - case 4 - transfer done, no length error - return FALSE (sched end state) -*/ - -t_bool rad_end_sec (UNIT *uptr, uint32 lnt, uint32 exp, uint32 st) -{ -if (st != CHS_ZBC) { /* end record? */ - if (rad_inc_ad ()) /* inc addr, ovf? */ - chan_uen (rad_dib.dva); /* uend */ - else sim_activate (uptr, rad_time * 16); /* no, next sector */ - return TRUE; - } -rad_inc_ad (); /* just incr addr */ -if ((lnt != exp) && /* length error? */ - chan_set_chf (rad_dib.dva, CHF_LNTE)) /* do we care? */ - return TRUE; -return FALSE; /* cmd done */ -} - -/* RAD status routine */ - -uint32 rad_tio_status (uint32 un) -{ -uint32 i, st; - -st = DVS_AUTO; /* flags */ -if (sim_is_active (&rad_unit[un])) /* active => busy */ - st |= DVS_DBUSY; -else if ((rad_unit[un].flags & UNIT_ATT) == 0) /* not att => offl */ - st |= DVS_DOFFL; -for (i = 0; i < RAD_NUMDR; i++) { /* loop thru units */ - if (sim_is_active (&rad_unit[i])) { /* active? */ - st |= (DVS_CBUSY |(CC2 << DVT_V_CC)); /* ctrl is busy */ - return st; - } - } -return st; -} - -uint32 rad_tdv_status (uint32 un) -{ -uint32 st; - -st = rad_flags; -if (rad_inv_ad (NULL)) /* bad address? */ - st |= RADV_BADS; -return st; -} - -/* Validate disk address */ - -t_bool rad_inv_ad (uint32 *da) -{ -uint32 tk = RADA_GETTK (rad_ad); -uint32 sc = RADA_GETSC (rad_ad); - -if ((tk >= rad_tab[rad_model].tkun) || /* bad sec or trk? */ - (sc >= rad_tab[rad_model].sctk)) { - return TRUE; - } -if (da) /* return word addr */ - *da = ((tk * rad_tab[rad_model].sctk) + sc) * RAD_WDSC; -return FALSE; -} - -/* Increment disk address */ - -t_bool rad_inc_ad (void) -{ -uint32 tk = RADA_GETTK (rad_ad); -uint32 sc = RADA_GETSC (rad_ad); - -sc = sc + 1; /* sector++ */ -if (sc >= rad_tab[rad_model].sctk) { /* overflow? */ - sc = 0; /* wrap sector */ - tk = tk + 1; /* track++ */ - } -rad_ad = ((tk << rad_tab[rad_model].tk_v) | /* rebuild rad_ad */ - (sc << rad_tab[rad_model].sc_v)); -if (tk >= rad_tab[rad_model].tkun) /* overflow? */ - return TRUE; -return FALSE; -} - -/* Channel error */ - -t_stat rad_chan_err (uint32 st) -{ -chan_uen (rad_dib.dva); /* uend */ -if (st < CHS_ERR) - return st; -return SCPE_OK; -} - -/* Reset routine */ - -t_stat rad_reset (DEVICE *dptr) -{ -uint32 i; - -for (i = 0; i < RAD_NUMDR; i++) - sim_cancel (&rad_unit[i]); /* stop dev thread */ -rad_cmd = 0; -rad_flags = 0; -rad_ad = 0; -chan_reset_dev (rad_dib.dva); /* clr int, active */ -return SCPE_OK; -} - -/* Set controller type */ - -t_stat rad_settype (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 i; - -for (i = 0; i < RAD_NUMDR; i++) { /* all units unatt? */ - if (rad_unit[i].flags & UNIT_ATT) - return SCPE_ALATT; - } -rad_model = val; /* update model */ -rad_reset (&rad_dev); /* reset */ -for (i = 0; i < RAD_NUMDR; i++) /* update capacity */ - rad_unit[i].capac = RAD_WDUN; -return SCPE_OK; -} - -/* Show controller type */ - -t_stat rad_showtype (FILE *st, UNIT *uptr, int32 val, void *desc) -{ -fprintf (st, (rad_model == RAD_7212)? "7211/7212": "7231/7232"); -return SCPE_OK; -} diff --git a/sigma/sigma_rtc.c b/sigma/sigma_rtc.c deleted file mode 100644 index 34982fa3..00000000 --- a/sigma/sigma_rtc.c +++ /dev/null @@ -1,267 +0,0 @@ -/* sigma_rtc.c: Sigma clocks - - Copyright (c) 2007, Robert M. Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - rtc clocks - - The real-time clock includes an internal scheduler for events which need to - be driven at multiples of the clock frequency, such as console and multiplexor - polling. Other devices can "register" with the clock module to receive service - callbacks at a timed interval. This replaces the standard SimH event queue - mechanism for real-time synchronous events. -*/ - -#include "sigma_io_defs.h" - -#define RTC_HZ_BASE 500 -#define RTC_TICKS_DFLT 500 - -/* Timed events data structures */ - -uint8 rtc_indx[RTC_NUM_EVNTS]; /* index into rtc_tab */ -uint8 rtc_cntr[RTC_NUM_EVNTS]; /* timer ticks left */ -uint8 rtc_xtra[RTC_NUM_EVNTS]; /* extra counter */ -UNIT *rtc_usrv[RTC_NUM_EVNTS]; /* unit servers */ - -/* Real-time clock counter frequencies */ - -uint16 rtc_tps[RTC_NUM_CNTRS] = { - RTC_HZ_OFF, RTC_HZ_OFF, RTC_HZ_500, RTC_HZ_500 - }; - -/* Frequency descriptors. The base clock runs at 500Hz. To get submultiples, - an event uses a tick counter. If the frequency is not an even submultiple, the - event can specify an "extra" counter. Every "extra" ticks of the event counter, - the event counter is increased by one. Thus, 60Hz counts as 8-8-9, providing - 3 clock ticks for every 25 base timer ticks. */ - -typedef struct { - uint32 hz; - uint32 cntr_reset; - uint32 xtra_reset; - } rtcdef_t; - -static rtcdef_t rtc_tab[RTC_NUM_HZ] = { - { 0, 0, 0 }, - { 500, 1, 0 }, - { 50, 10, 0 }, - { 60, 8, 3 }, - { 100, 5, 0 }, - { 2, 250, 0 }, - }; - -t_stat rtc_svc (UNIT *uptr); -t_stat rtc_cntr_svc (UNIT *uptr); -t_stat rtc_reset (DEVICE *dptr); -t_stat rtc_show_events (FILE *of, UNIT *uptr, int32 val, void *desc); - -/* Clock data structures - - rtc_dev RTC device descriptor - rtc_unit RTC unit - rtc_reg RTC register list -*/ - -UNIT rtc_unit = { UDATA (&rtc_svc, 0, 0), RTC_TICKS_DFLT }; - -UNIT rtc_cntr_unit[RTC_NUM_CNTRS] = { - { UDATA (&rtc_cntr_svc, 0, 0) }, - { UDATA (&rtc_cntr_svc, 0, 0) }, - { UDATA (&rtc_cntr_svc, 0, 0) }, - { UDATA (&rtc_cntr_svc, 0, 0) } - }; - -REG rtc_reg[] = { - { BRDATA (TPS, rtc_tps, 10, 10, RTC_NUM_CNTRS), REG_HRO }, - { BRDATA (INDX, rtc_indx, 10, 4, RTC_NUM_EVNTS), REG_HRO }, - { BRDATA (CNTR, rtc_cntr, 10, 6, RTC_NUM_EVNTS), REG_HRO }, - { BRDATA (XTRA, rtc_xtra, 10, 6, RTC_NUM_EVNTS), REG_HRO }, - { NULL } - }; - -MTAB rtc_mod[] = { - { MTAB_XTD|MTAB_VDV|MTAB_NMO, RTC_C1, "C1", "C1", - &rtc_set_tps, &rtc_show_tps, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, RTC_C2, "C2", "C2", - &rtc_set_tps, &rtc_show_tps, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, RTC_C3, "C3", "C3", - &rtc_set_tps, &rtc_show_tps, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, RTC_C4, "C4", NULL, - NULL, &rtc_show_tps, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "EVENTS", NULL, - NULL, &rtc_show_events, NULL }, - { 0 } - }; - -DEVICE rtc_dev = { - "RTC", &rtc_unit, rtc_reg, rtc_mod, - 1, 16, 8, 1, 16, 8, - NULL, NULL, &rtc_reset, - NULL, NULL, NULL - }; - -/* Master timer service routine */ - -t_stat rtc_svc (UNIT *uptr) -{ -uint32 i, idx; -int32 t; -t_stat st; - -t = sim_rtcn_calb (RTC_HZ_BASE, TMR_RTC); /* calibrate clock */ -sim_activate (uptr, t); /* reactivate unit */ -for (i = 0; i < RTC_NUM_EVNTS; i++) { /* loop thru events */ - if (rtc_cntr[i] != 0) { /* event active? */ - rtc_cntr[i] = rtc_cntr[i] - 1; /* decrement */ - if (rtc_cntr[i] == 0) { /* expired? */ - idx = rtc_indx[i]; - rtc_cntr[i] = rtc_tab[idx].cntr_reset; /* reset counter */ - if (rtc_xtra[i] != 0) { /* fudge factor? */ - rtc_xtra[i] = rtc_xtra[i] - 1; /* decr fudge cntr */ - if (rtc_xtra[i] == 0) { /* expired? */ - rtc_cntr[i]++; /* extra tick */ - rtc_xtra[i] = rtc_tab[idx].xtra_reset; /* reset fudge cntr */ - } /* end fudge = 0 */ - } /* end fudge active */ - if ((rtc_usrv[i] == NULL) || /* registered? */ - (rtc_usrv[i]->action == NULL)) - return SCPE_IERR; /* should be */ - st = rtc_usrv[i]->action (rtc_usrv[i]); /* callback */ - if (st != SCPE_OK) /* error */ - return st; - } /* end cntr = 0 */ - } /* end event active */ - } /* end event loop */ -return SCPE_OK; -} - -/* Callback for a system timer */ - -t_stat rtc_cntr_svc (UNIT *uptr) -{ -uint32 cn = uptr - rtc_cntr_unit; - -io_sclr_req (INTV (INTG_OVR, cn), 1); /* set cntr intr */ -return SCPE_OK; -} - -/* Register a timer */ - -t_stat rtc_register (uint32 tm, uint32 idx, UNIT *uptr) -{ -if ((tm >= RTC_NUM_EVNTS) || /* validate params */ - (idx >= RTC_NUM_HZ) || - (uptr == NULL) || - (uptr->action == NULL)) - return SCPE_IERR; -rtc_usrv[tm] = uptr; -rtc_indx[tm] = idx; -rtc_cntr[tm] = rtc_tab[idx].cntr_reset; /* init event */ -rtc_xtra[tm] = rtc_tab[idx].xtra_reset; -return SCPE_OK; -} - -/* Set timer ticks */ - -t_stat rtc_set_tps (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -uint32 newval, i; -t_stat r; - -if (val >= RTC_NUM_EVNTS) /* validate params */ - return SCPE_IERR; -if (cptr == NULL) /* must have arg */ - return SCPE_ARG; -newval = get_uint (cptr, 10, 10000, &r); -if ((r != SCPE_OK) || /* error? */ - ((newval == 0) && (val >= 2))) /* can't turn off 3,4 */ - return SCPE_ARG; -for (i = 0; i < RTC_NUM_HZ; i++) { /* loop thru freqs */ - if (newval == rtc_tab[i].hz) { /* found freq? */ - rtc_tps[val] = i; - rtc_indx[val] = i; /* save event vals */ - rtc_cntr[val] = rtc_tab[i].cntr_reset; - rtc_xtra[val] = rtc_tab[i].xtra_reset; - return SCPE_OK; - } - } -return SCPE_ARG; -} - -/* Show timer ticks */ - -t_stat rtc_show_tps (FILE *of, UNIT *uptr, int32 val, void *desc) -{ -uint32 idx; - -if (val >= RTC_NUM_EVNTS) - return SCPE_IERR; -idx = rtc_tps[val]; /* ptr to clk defs */ -if (rtc_tab[idx].hz == 0) - fprintf (of, "off\n"); -else fprintf (of, "%dHz\n", rtc_tab[idx].hz); -return SCPE_OK; -} - - -/* Reset routine */ - -t_stat rtc_reset (DEVICE *dptr) -{ -uint32 i; - -sim_rtcn_init (rtc_unit.wait, TMR_RTC); /* init base clock */ -sim_activate_abs (&rtc_unit, rtc_unit.wait); /* activate unit */ - -for (i = 0; i < RTC_NUM_EVNTS; i++) { /* clear counters */ - if (i < RTC_NUM_CNTRS) { - rtc_cntr[i] = 0; - rtc_xtra[i] = 0; - rtc_indx[i] = 0; - rtc_usrv[i] = NULL; - if (rtc_register (i, rtc_tps[i], &rtc_cntr_unit[i]) != SCPE_OK) - return SCPE_IERR; - } - else if ((rtc_usrv[i] != NULL) && - (rtc_register (i, rtc_indx[i], rtc_usrv[i]) != SCPE_OK)) - return SCPE_IERR; - } -return SCPE_OK; -} - -/* Show events */ - -t_stat rtc_show_events (FILE *of, UNIT *uptr, int32 val, void *desc) -{ -uint32 i; - -fprintf (of, "Event Status Frequency Ticks Extra\n"); -for (i = 0; i < RTC_NUM_EVNTS; i++) { - if (rtc_cntr[i]) - fprintf (of, " %d on %3dHz %3d %d\n", - i, rtc_tab[rtc_indx[i]].hz, rtc_cntr[i], rtc_xtra[i]); - else fprintf (of, " %d off\n", i); - } -return SCPE_OK; -} \ No newline at end of file diff --git a/sigma/sigma_sys.c b/sigma/sigma_sys.c deleted file mode 100644 index 53aeb6dd..00000000 --- a/sigma/sigma_sys.c +++ /dev/null @@ -1,613 +0,0 @@ -/* sigma_sys.c: Sigma system interface - - Copyright (c) 2007-2008, Robert M Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. -*/ - -#include "sigma_defs.h" -#include - -#define FMTASC(x) ((x) < 0x20)? "<%02X>": "%c", (x) - -extern DEVICE cpu_dev; -extern DEVICE map_dev; -extern DEVICE int_dev; -extern DEVICE chan_dev[]; -extern DEVICE rtc_dev; -extern DEVICE tt_dev; -extern DEVICE pt_dev; -extern DEVICE lp_dev; -extern DEVICE rad_dev; -extern DEVICE dk_dev; -extern DEVICE dp_dev[]; -extern DEVICE mt_dev; -extern DEVICE mux_dev, muxl_dev; -extern REG cpu_reg[]; -extern uint32 *M; -extern UNIT cpu_unit; - -t_stat fprint_sym_m (FILE *of, uint32 inst); -t_stat parse_sym_m (char *cptr, t_value *val); -void fprint_ebcdic (FILE *of, uint32 c); - -/* SCP data structures and interface routines - - sim_name simulator name string - sim_PC pointer to saved PC register descriptor - sim_emax number of words for examine - sim_devices array of pointers to simulated devices - sim_stop_messages array of pointers to stop messages - sim_load binary loader -*/ - -char sim_name[] = "XDS Sigma"; - -REG *sim_PC = &cpu_reg[0]; - -int32 sim_emax = 1; - -DEVICE *sim_devices[] = { - &cpu_dev, - &map_dev, - &int_dev, - &chan_dev[0], - &chan_dev[1], - &chan_dev[2], - &chan_dev[3], - &chan_dev[4], - &chan_dev[5], - &chan_dev[6], - &chan_dev[7], - &rtc_dev, /* must be first */ - &tt_dev, - &pt_dev, - &lp_dev, - &mt_dev, - &rad_dev, - &dk_dev, - &dp_dev[0], - &dp_dev[1], - &mux_dev, - &muxl_dev, - NULL - }; - -const char *sim_stop_messages[] = { - "Unknown error", - "Invalid I/O configuration", - "Breakpoint", - "Address stop", - "Wait, interrupts off", - "Invalid PSD", - "Nested EXU's exceed limit", - "Undefined instruction", - "Illegal trap or interrupt instruction", - "Invalid interrupt vector", - "Nested traps", - }; - -/* Character conversion tables (from Sigma 7 manual) */ - -uint8 ascii_to_ebcdic[128] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x06, 0x07, /* 00 - 1F */ - 0x08, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, /* 20 - 3F */ - 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61, - 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, - 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F, - 0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, /* 40 - 5F */ - 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, - 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, - 0xE7, 0xE8, 0xE9, 0xB4, 0xB1, 0xB5, 0x6A, 0x6D, - 0x4A, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60- 7F */ - 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, - 0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, - 0xA7, 0xA8, 0xA9, 0xB2, 0x4F, 0xB3, 0x5F, 0xFF - }; - -uint8 ebcdic_to_ascii[256] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x09, 0x06, 0x07, /* 00 - 1F */ - 0x08, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x0A, 0x16, 0x17, - 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 20 - 3F */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 40 - 5F */ - 0x00, 0x00, '`', '.', '<', '(', '+', '|', - '&', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, '!', '$', '*', ')', ';', '~', - '-', '/', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 60 - 7F */ - 0x00, 0x00, '^', ',', '%', '_', '>', '?', - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, ':', '#', '@', '\'', '=', '"', - 0x00, 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 80 - 9F */ - 'h', 'i', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 'j', 'k', 'l', 'm', 'n', 'o', 'p', - 'q', 'r', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 's', 't', 'u', 'v', 'w', 'x', /* A0 - BF */ - 'y', 'z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, '\\', '{', '}', '[', ']', 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 'A', 'B', 'C', 'D', 'E', 'F', 'G', /* C0 - DF */ - 'H', 'I', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 'J', 'K', 'L', 'M', 'N', 'O', 'P', - 'Q', 'R', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 'S', 'T', 'U', 'V', 'W', 'X', /* E0 - FF */ - 'Y', 'Z', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, - }; - -/* Binary loader */ - -t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) -{ -return SCPE_NOFNC; -} - -/* Symbol and format tables */ - -#define IC_V_CL 17 /* class */ -#define IC_M_CL 0x1F -#define IC_V_RN 16 /* takes rn */ -#define IC_RN (1u << IC_V_RN) -#define IC_V_IND 15 /* takes ind */ -#define IC_IND (1u << IC_V_IND) -#define IC_V_XR 13 /* takes xr */ -#define IC_M_XR 0x3 -#define IC_NONE 0 -#define IC_XR 1 -#define IC_CTL 2 -#define IC_V_AW 7 /* addr width */ -#define IC_M_AW 0x3F -#define IC_V_AP 2 /* addr position */ -#define IC_M_AP 0x1F -#define IC_V_SGN 1 /* sign allowed */ -#define IC_SGN (1u << IC_V_SGN) -#define IC_V_AOP 0 /* addr optional */ -#define IC_AOP (1u << IC_V_AOP) - -#define ID1_07 0 /* decode 1-7 */ -#define ID1_11 1 /* decode 1-11 */ -#define IDSHFT 2 /* shift */ -#define IDSHFF 3 /* shift floating */ -#define IDMMCX 4 /* MMC ext */ - -#define I_C(c,r,i,w,s,x,sn,ao) \ - (((c) << IC_V_CL) | ((r) << IC_V_RN) | ((i) << IC_V_IND)|\ - ((w) << IC_V_AW) | ((s) << IC_V_AP) | ((x) << IC_V_XR) |\ - ((sn) << IC_V_SGN) | ((ao) << IC_V_AOP)) - -/* decode R I wd ps x sn ao */ -#define IC_MRF I_C(ID1_07,1,1,17, 0,1, 0, 0) /* mem ref */ -#define IC_IMM I_C(ID1_07,1,0,20, 0,0, 1, 0) /* immediate */ -#define IC_LCFI I_C(ID1_07,0,0, 8, 0,2, 0, 0) /* LCFI */ -#define IC_LFI I_C(ID1_11,0,0, 4, 0,0, 0, 0) /* LFI */ -#define IC_LCI I_C(ID1_11,0,0, 4, 4,0, 0, 0) /* LCI */ -#define IC_SHFT I_C(IDSHFT,1,0, 7, 0,1, 1, 0) /* shift */ -#define IC_SHFF I_C(IDSHFF,1,0, 7, 0,1, 1, 0) /* floating shift */ -#define IC_MNOR I_C(ID1_07,0,1,17, 0,1, 0, 0) /* mem ref, no reg */ -#define IC_MNOX I_C(ID1_11,0,1,17, 0,1, 0, 0) /* mef ref ext */ -#define IC_NOP I_C(ID1_07,1,0, 0, 0,0, 0, 0) /* no operand */ -#define IC_NOPX I_C(ID1_11,1,0, 0, 0,0, 0, 0) /* no operand ext */ -#define IC_MMC I_C(ID1_07,1,1, 3,17,0, 0, 0) /* MMC */ -#define IC_MMCX I_C(IDMMCX,1,0, 0, 0,0, 0, 0) /* MMC extended */ -#define IC_MNRI I_C(ID1_11,0,0, 0, 0,0, 0, 0) /* no operands */ -#define IC_MNRO I_C(ID1_07,0,1,17, 0,1, 0, 1) /* mem ref, addr opt */ - -#define IC_GETCL(x) (((x) >> IC_V_CL) & IC_M_CL) -#define IC_GETXR(x) (((x) >> IC_V_XR) & IC_M_XR) -#define IC_GETAW(x) (((x) >> IC_V_AW) & IC_M_AW) -#define IC_GETAP(x) (((x) >> IC_V_AP) & IC_M_AP) - -static const uint32 masks[] = { - 0x7F000000, 0x7FF00000, 0x7F000700, 0x7F000100, - 0x7F0E0000 - }; - -/* Opcode tables - extended mnemonics must precede standard mnemonics */ - -static const uint32 opc_val[] = { - 0x02100000, IC_LFI, 0x02200000, IC_LCI, 0x70100000, IC_MNOX, 0x70200000, IC_MNOX, - 0x25000000, IC_SHFT, 0x25000100, IC_SHFT, 0x25000200, IC_SHFT, 0x25000000, IC_SHFT, - 0x25000400, IC_SHFT, 0x25000500, IC_SHFT, 0x25000600, IC_SHFT, 0x25000700, IC_SHFT, - 0x24000000, IC_SHFT, 0x24000100, IC_SHFT, - 0x68000000, IC_MNOX, 0x68100000, IC_MNOX, 0x68200000, IC_MNOX, 0x68300000, IC_MNOX, - 0x68400000, IC_MNOX, 0x68800000, IC_MNOX, - 0x69000000, IC_MNOX, 0x69100000, IC_MNOX, 0x69200000, IC_MNOX, 0x69300000, IC_MNOX, - 0x69400000, IC_MNOX, 0x69800000, IC_MNOX, - 0x6F020000, IC_MMCX, 0x6F040000, IC_MMCX, 0x6F060000, IC_MMCX, 0x6F080000, IC_MMCX, - 0x6F080000, IC_MMCX, 0x02000000, IC_MNRI, - - 0x02000000, IC_LCFI, - 0x04000000, IC_MRF, 0x05000000, IC_MRF, 0x06000000, IC_MRF, 0x07000000, IC_MRF, - 0x08000000, IC_MRF, 0x09000000, IC_MRF, 0x0A000000, IC_MRF, 0x0B000000, IC_MRF, - 0x0C000000, IC_MRF, 0x0D000000, IC_NOP, 0x0E000000, IC_MRF, 0x0F000000, IC_MRF, - 0x10000000, IC_MRF, 0x11000000, IC_MRF, 0x12000000, IC_MRF, 0x13000000, IC_MRF, - 0x15000000, IC_MRF, - 0x18000000, IC_MRF, 0x19000000, IC_MRF, 0x1A000000, IC_MRF, 0x1B000000, IC_MRF, - 0x1C000000, IC_MRF, 0x1D000000, IC_MRF, 0x1E000000, IC_MRF, 0x1F000000, IC_MRF, - 0x20000000, IC_IMM, 0x21000000, IC_IMM, 0x22000000, IC_IMM, 0x23000000, IC_IMM, - 0x24000000, IC_MRF, 0x25000000, IC_MRF, 0x26000000, IC_MRF, - 0x28000000, IC_MRF, 0x29000000, IC_MRF, 0x2A000000, IC_MRF, 0x2B000000, IC_MRF, - 0x2C000000, IC_MRF, 0x2D000000, IC_MRF, 0x2E000000, IC_MNRO, 0x2F000000, IC_MRF, - 0x30000000, IC_MRF, 0x31000000, IC_MRF, 0x32000000, IC_MRF, 0x33000000, IC_MRF, - 0x34000000, IC_MRF, 0x35000000, IC_MRF, 0x36000000, IC_MRF, 0x37000000, IC_MRF, - 0x38000000, IC_MRF, 0x39000000, IC_MRF, 0x3A000000, IC_MRF, 0x3B000000, IC_MRF, - 0x3C000000, IC_MRF, 0x3D000000, IC_MRF, 0x3E000000, IC_MRF, 0x3F000000, IC_MRF, - 0x40000000, IC_IMM, 0x41000000, IC_IMM, - 0x44000000, IC_MRF, 0x45000000, IC_MRF, 0x46000000, IC_MRF, 0x47000000, IC_MRF, - 0x48000000, IC_MRF, 0x49000000, IC_MRF, 0x4A000000, IC_MRF, 0x4B000000, IC_MRF, - 0x4C000000, IC_MRF, 0x4D000000, IC_MRF, 0x4E000000, IC_MRF, 0x4F000000, IC_MRF, - 0x50000000, IC_MRF, 0x51000000, IC_MRF, 0x52000000, IC_MRF, 0x53000000, IC_MRF, - 0x55000000, IC_MRF, 0x56000000, IC_MRF, 0x57000000, IC_MRF, - 0x58000000, IC_MRF, 0x5A000000, IC_MRF, 0x5B000000, IC_MRF, - - 0x60000000, IC_IMM, 0x61000000, IC_IMM, 0x63000000, IC_IMM, - 0x64000000, IC_MRF, 0x65000000, IC_MRF, 0x66000000, IC_MRF, 0x67000000, IC_MNOR, - 0x68000000, IC_MRF, 0x69000000, IC_MRF, 0x6A000000, IC_MRF, 0x6B000000, IC_MRF, - 0x6C000000, IC_MRF, 0x6D000000, IC_MRF, 0x6E000000, IC_MRF, 0x6F000000, IC_MMC, - 0x70000000, IC_MRF, 0x71000000, IC_MRF, 0x72000000, IC_MRF, 0x73000000, IC_MRF, - 0x74000000, IC_MNOR, 0x75000000, IC_MRF, 0x76000000, IC_MRF, 0x77000000, IC_MRF, - 0x78000000, IC_MRF, 0x79000000, IC_MRF, 0x7A000000, IC_MRF, 0x7B000000, IC_MRF, - 0x7C000000, IC_MNOR, 0x7D000000, IC_MRF, 0x7E000000, IC_MRF, 0x7F000000, IC_MRF, - 0xFFFFFFFF, 0 - }; - -static const char *opcode[] = { - "LFI", "LCI", "LF", "LC", /* extended mmenomics */ - "SLS", "SLD", "SCS", "SCD", - "SAS", "SAD", "SSS", "SSD", - "SFS", "SFL", - "B", "BGE", "BLE", "BE", - "BNOV", "BNC", - "BNVR", "BL", "BG", "BNE", - "BOV", "BC", - "LLOCKS", "LPC", "LLOCKSE", "LMAP", - "LMAPRE", "NOP", - - "LCFI", /* 00 */ - "CAL1", "CAL2", "CAL3", "CAL4", - "PLW", "PSW", "PLM", "PSM", - "PLS", "PSS", "LPSD", "XPSD", - "AD", "CD", "LD", "MSP", /* 10 */ - "STD", - "SD", "CLM", "LCD", "LAD", - "FSL", "FAL", "FDL", "FML", - "AI", "CI", "LI", "MI", /* 20 */ - "SF", "S", "LAS", - "CVS", "CVA", "LM", "STM", - "LRA", "LMS", "WAIT", "LRP", - "AW", "CW", "LW", "MTW", /* 30 */ - "LVAW", "STW", "DW", "MW", - "SW", "CLR", "LCW", "LAW", - "FSS", "FAS", "FDS", "FMS", - "TTBS", "TBS", /* 40 */ - "ANLZ", "CS", "XW", "STS", - "EOR", "OR", "LS", "AND", - "SIO", "TIO", "TDV", "HIO", - "AH", "CH", "LH", "MTH", /* 50 */ - "STH", "DH", "MH", - "SH", "LCH", "LAH", - - "CBS", "MBS", "EBS", /* 60 */ - "BDR", "BIR", "AWM", "EXU", - "BCR", "BCS", "BAL", "INT", - "RD", "WD", "AIO", "MMC", - "LCF", "CB", "LB", "MTB", /* 70 */ - "STCF", "STB", "PACK", "UNPK", - "DS", "DA", "DD", "DM", - "DSA", "DC", "DL", "DST", - NULL - }; - -/* Symbolic decode - - Inputs: - *of = output stream - addr = current PC - *val = pointer to values - *uptr = pointer to unit - sw = switches - Outputs: - return = status code -*/ - -t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, - UNIT *uptr, int32 sw) -{ -uint32 inst, sc, rdx, c; -DEVICE *dptr; - -inst = val[0]; /* get inst */ -if (uptr == NULL) /* anon = CPU */ - uptr = &cpu_unit; -else if (uptr != &cpu_unit) /* CPU only */ - return SCPE_ARG; -dptr = find_dev_from_unit (uptr); /* find dev */ -if (dptr == NULL) - return SCPE_IERR; -if (sw & SWMASK ('D')) /* get radix */ - rdx = 10; -else if (sw & SWMASK ('O')) - rdx = 8; -else if (sw & SWMASK ('X')) - rdx = 16; -else rdx = dptr->dradix; - -if (sw & SWMASK ('C')) { /* char format? */ - for (sc = 0; sc < 32; sc = sc + 8) { /* print string */ - c = (inst >> (24 - sc)) & BMASK; - if (sw & SWMASK ('A')) - fprintf (of, FMTASC (c & 0x7F)); - else fprint_ebcdic (of, c); - } - return 0; /* return # chars */ - } -if (sw & SWMASK ('A')) { /* ASCII? */ - sc = 24 - ((addr & 0x3) * 8); /* shift count */ - c = (inst >> sc) & 0x7F; - fprintf (of, "%c", FMTASC (c)); - return 0; - } -if (sw & SWMASK ('E')) { /* EBCDIC? */ - sc = 24 - ((addr & 0x3) * 8); /* shift count */ - c = (inst >> sc) & BMASK; - fprint_ebcdic (of, c); - return 0; - } -if (sw & SWMASK ('B')) { /* byte? */ - sc = 24 - ((addr & 0x3) * 8); /* shift count */ - c = (inst >> sc) & BMASK; - fprintf (of, "%02X", c); - return 0; - } -if (sw & SWMASK ('H')) { /* halfword? */ - c = ((addr & 1)? inst: inst >> 16) & HMASK; - fprintf (of, "%04X", c); - return 0; - } -if ((sw & SWMASK ('M')) && /* inst format? */ - !fprint_sym_m (of, inst)) /* decode inst */ - return 0; - -fprint_val (of, inst, rdx, 32, PV_RZRO); -return 0; -} - -/* Instruction decode */ - -t_stat fprint_sym_m (FILE *of, uint32 inst) -{ -uint32 i, j; - -for (i = 0; opc_val[i] < 0xFFFFFFFF; i = i + 2) { /* loop thru ops */ - j = IC_GETCL (opc_val[i + 1]); /* get class */ - if (opc_val[i] == (inst & masks[j])) { /* match? */ - uint32 fl = opc_val[i + 1]; /* get format */ - uint32 aw = IC_GETAW (fl); - uint32 ap = IC_GETAP (fl); - uint32 xr = IC_GETXR (fl); - uint32 rn = I_GETRN (inst); /* get fields */ - uint32 xn = I_GETXR (inst); - uint32 mask = (1u << aw) - 1; - uint32 ad = (inst >> ap) & mask; - - fprintf (of, "%s", opcode[i >> 1]); /* opcode */ - if (fl & IC_RN) /* rn? */ - fprintf (of, ",%d", rn); - if (TST_IND (inst) || aw || xr) { /* anything else? */ - fputs (TST_IND (inst)? " *": " ", of); /* space{*} */ - if (aw) { /* any value? */ - if ((fl & IC_SGN) && /* signed and */ - (ad & (1u << (aw - 1)))) /* negative? */ - fprintf (of, "-%X", (mask + 1) - ad); - else fprintf (of, "%X", ad); - if ((xr == IC_XR) && xn) /* any index? */ - fprintf (of, ",%d", xn); - else if (xr == IC_CTL) /* or control? */ - fprintf (of, ",%X", rn); - } - } - return SCPE_OK; - } - } -return SCPE_ARG; -} - -void fprint_ebcdic (FILE *of, uint32 c) -{ -uint32 cv = ebcdic_to_ascii[c]; -if ((cv < 0040) || (cv >= 0177)) - fprintf (of, "<%02X>", c); -else fputc (cv, of); -return; -} - -/* Symbolic input - - Inputs: - *cptr = pointer to input string - addr = current PC - uptr = pointer to unit - *val = pointer to output values - sw = switches - Outputs: - status = error status -*/ - -t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) -{ -t_value num; -uint32 i, sc, rdx, c; -t_stat r; -DEVICE *dptr; - -if (uptr == NULL) /* anon = CPU */ - uptr = &cpu_unit; -else if (uptr != &cpu_unit) /* CPU only */ - return SCPE_ARG; -dptr = find_dev_from_unit (uptr); /* find dev */ -if (dptr == NULL) - return SCPE_IERR; -if (sw & SWMASK ('D')) /* get radix */ - rdx = 10; -else if (sw & SWMASK ('O')) - rdx = 8; -else if (sw & SWMASK ('X')) - rdx = 16; -else rdx = dptr->dradix; - -if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* chars? */ - if (cptr[0] == 0) /* must have 1 char */ - return SCPE_ARG; - for (i = 0; i < 4; i++) { - if (cptr[i] == 0) - break; - sc = 24 - (i * 8); - c = (sw & SWMASK ('A'))? - cptr[i] & 0x7F: - ascii_to_ebcdic[cptr[i]]; - val[0] = (val[0] & ~(BMASK << sc)) | (c << sc); - } - return 0; - } -if ((sw & SWMASK ('A')) || ((*cptr == '#') && cptr++)) { /* ASCII char? */ - if (cptr[0] == 0) /* must have 1 char */ - return SCPE_ARG; - sc = 24 - (addr & 0x3) * 8; /* shift count */ - val[0] = (val[0] & ~(BMASK << sc)) | (cptr[0] << sc); - return 0; - } -if ((sw & SWMASK ('E')) || ((*cptr == '\'') && cptr++)) { /* EBCDIC char? */ - if (cptr[0] == 0) /* must have 1 char */ - return SCPE_ARG; - sc = 24 - (addr & 0x3) * 8; /* shift count */ - val[0] = (val[0] & ~(BMASK << sc)) | (ascii_to_ebcdic[cptr[0]] << sc); - return 0; - } -if (sw & SWMASK ('B')) { /* byte? */ - num = get_uint (cptr, rdx, BMASK, &r); /* get byte */ - if (r != SCPE_OK) - return SCPE_ARG; - sc = 24 - (addr & 0x3) * 8; /* shift count */ - val[0] = (val[0] & ~(BMASK << sc)) | (num << sc); - return 0; - } -if (sw & SWMASK ('H')) { /* halfword? */ - num = get_uint (cptr, rdx, HMASK, &r); /* get half word */ - if (r != SCPE_OK) - return SCPE_ARG; - sc = addr & 1? 0: 16; - val[0] = (val[0] & ~(HMASK << sc)) | (num << sc); - return 0; - } -if (!parse_sym_m (cptr, val)) - return 0; - -val[0] = get_uint (cptr, rdx, WMASK, &r); /* get number */ -if (r != SCPE_OK) - return r; -return 0; -} - -t_stat parse_sym_m (char *cptr, t_value *val) -{ -uint32 i, sgn; -t_stat r; -char *sep; -char gbuf[CBUFSIZE]; - -cptr = get_glyph (cptr, gbuf, 0); /* get opcode+reg*/ -if (sep = strchr (gbuf, ',')) /* , in middle? */ - *sep++ = 0; /* split strings */ -for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */ - if (strcmp (opcode[i], gbuf) == 0) { /* string match? */ - uint32 rn, xn, ad; - uint32 k = i << 1; /* index to opval */ - uint32 fl = opc_val[k + 1]; - uint32 aw = IC_GETAW (fl); - uint32 ap = IC_GETAP (fl); - uint32 xr = IC_GETXR (fl); - uint32 mask = (1u << aw) - 1; - - val[0] = opc_val[k]; - if (fl & IC_RN) { /* need rn? */ - if (sep == NULL) - return SCPE_ARG; - rn = get_uint (sep, 10, INST_M_RN, &r); - if (r != SCPE_OK) - return SCPE_ARG; - val[0] |= rn << INST_V_RN; - } - else if (sep) /* rn & not wanted */ - return SCPE_ARG; - if (aw) { /* more? */ - if (*cptr == 0) - return (fl & IC_AOP)? SCPE_OK: SCPE_ARG; - if ((fl & IC_IND) && (*cptr == '*')) { /* indirect? */ - val[0] |= INST_IND; - cptr++; - } - if ((fl & IC_SGN) && /* signed val? */ - strchr ("+-", *cptr) && /* with sign? */ - (*cptr++ == '-')) /* and minus? */ - sgn = 1; - else sgn = 0; /* else + */ - cptr = get_glyph (cptr, gbuf, 0); /* get rest */ - if (sep = strchr (gbuf, ',')) /* , in middle? */ - *sep++ = 0; /* split strings */ - ad = get_uint (gbuf, 16, mask, &r); - if (r != SCPE_OK) - return r; - if (sgn && ad) /* negative, nz? */ - ad = (mask + 1) - ad; /* complement */ - val[0] |= (ad << ap); - if ((xr == IC_XR) && sep) { /* index? */ - xn = get_uint (sep, 10, 7, &r); - if (r != SCPE_OK) - return r; - val[0] |= (xn << INST_V_XR); - } - else if (xr == IC_CTL) { /* control? */ - if (sep == NULL) - return SCPE_ARG; - xn = get_uint (gbuf, 16, INST_M_RN, &r); - if (r != SCPE_OK) - return r; - val[0] |= (xn << INST_V_RN); - } - else if (sep) - return SCPE_ARG; - } - if (*cptr != 0) - return SCPE_ARG; - return SCPE_OK; - } - } -return SCPE_ARG; -} diff --git a/sigma/sigma_tt.c b/sigma/sigma_tt.c deleted file mode 100644 index 97d32d3c..00000000 --- a/sigma/sigma_tt.c +++ /dev/null @@ -1,331 +0,0 @@ -/* sigma_tt.c: Sigma 7012 console teletype - - Copyright (c) 2007-2008, Robert M. Supnik - - 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 - ROBERT M SUPNIK 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 Robert M Supnik shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Robert M Supnik. - - tt 7012 console - - The 7012 has the following special cases on input and output: - - CR input, mapped to NEWLINE and echoes CR-LF - ^H input, mapped to EOM and not echoed - HT input or output, simulates tabbing with fixed 8 character stops -*/ - -#include "sigma_io_defs.h" -#include - -/* Device definitions */ - -#define TTI 0 -#define TTO 1 - -/* Device states */ - -#define TTS_IDLE 0x0 -#define TTS_INIT 0x1 -#define TTS_END 0x2 -#define TTS_WRITE 0x5 -#define TTS_READ 0x6 -#define TTS_READS 0x86 - -/* EBCDIC special characters for input */ - -#define E_EOM 0x08 /* end of medium */ -#define E_HT 0x05 /* tab */ -#define E_NL 0x15 /* new line */ - -uint32 tt_cmd = TTS_IDLE; -uint32 tti_tps = RTC_HZ_100; -uint32 tti_panel = 020; /* panel int char */ -uint32 tto_pos = 0; /* char position */ - -extern uint32 chan_ctl_time; -extern uint8 ascii_to_ebcdic[128]; -extern uint8 ebcdic_to_ascii[256]; - -uint32 tt_disp (uint32 op, uint32 dva, uint32 *dvst); -uint32 tt_tio_status (void); -t_stat tt_chan_err (uint32 st); -t_stat tti_rtc_svc (uint32 tm); -t_stat tti_svc (UNIT *uptr); -t_stat tto_svc (UNIT *uptr); -t_stat tt_reset (DEVICE *dptr); -t_stat tt_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc); -void tto_echo (int32 c); - -extern t_stat io_set_pint (void); - -/* TT data structures - - tt_dev TT device descriptor - tt_unit TT unit descriptors - tt_reg TT register list - tt_mod TT modifiers list -*/ - -dib_t tt_dib = { DVA_TT, tt_disp }; - -UNIT tt_unit[] = { - { UDATA (&tti_svc, TT_MODE_UC, 0), 0 }, - { UDATA (&tto_svc, TT_MODE_UC, 0), SERIAL_OUT_WAIT } - }; - -REG tt_reg[] = { - { HRDATA (CMD, tt_cmd, 9) }, - { DRDATA (KPOS, tt_unit[TTI].pos, T_ADDR_W), PV_LEFT }, - { DRDATA (KTPS, tti_tps, 8), REG_HRO }, - { DRDATA (TPOS, tt_unit[TTO].pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TTIME, tt_unit[TTO].wait, 24), REG_NZ + PV_LEFT }, - { HRDATA (PANEL, tti_panel, 8) }, - { HRDATA (DEVNO, tt_dib.dva, 12), REG_HRO }, - { NULL } - }; - -MTAB tt_mod[] = { - { TT_MODE, TT_MODE_UC, "UC", "UC", &tt_set_mode }, - { TT_MODE, TT_MODE_7P, "7p", "7P", &tt_set_mode }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, RTC_TTI, "POLL", "POLL", - &rtc_set_tps, &rtc_show_tps, (void *) &tti_tps }, - { MTAB_XTD|MTAB_VDV, 0, "CHAN", "CHAN", - &io_set_dvc, &io_show_dvc, NULL }, - { MTAB_XTD|MTAB_VDV, 0, "DVA", "DVA", - &io_set_dva, &io_show_dva, NULL }, - { MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, "CSTATE", NULL, - NULL, &io_show_cst, NULL }, - { 0 } - }; - -DEVICE tt_dev = { - "TT", tt_unit, tt_reg, tt_mod, - 2, 10, 31, 1, 16, 8, - NULL, NULL, &tt_reset, - NULL, NULL, NULL, - &tt_dib, 0 - }; - -/* Terminal: IO dispatch routine */ - -uint32 tt_disp (uint32 op, uint32 dva, uint32 *dvst) -{ -switch (op) { /* case on op */ - - case OP_SIO: /* start I/O */ - *dvst = tt_tio_status (); /* get status */ - if ((*dvst & DVS_DST) == 0) { /* idle? */ - tt_cmd = TTS_INIT; /* start dev thread */ - sim_activate (&tt_unit[TTO], chan_ctl_time); - } - break; - - case OP_TIO: /* test status */ - *dvst = tt_tio_status (); /* return status */ - break; - - case OP_HIO: /* halt I/O */ - chan_clr_chi (tt_dib.dva); /* clr int*/ - *dvst = tt_tio_status (); /* get status */ - if ((*dvst & DVS_DST) != 0) { /* busy? */ - sim_cancel (&tt_unit[TTO]); /* stop dev thread */ - tt_cmd = TTS_IDLE; - chan_uen (tt_dib.dva); /* uend */ - } - break; - - case OP_AIO: /* acknowledge int */ - chan_clr_chi (tt_dib.dva); /* clr int*/ - case OP_TDV: /* test status */ - *dvst = 0; /* no status */ - break; - - default: - *dvst = 0; - return SCPE_IERR; - } - -return 0; -} - -/* Timed input service routine - runs continuously - Only accepts input in TTS_READx state */ - -t_stat tti_svc (UNIT *uptr) -{ -int32 c, ebcdic; -uint32 st; - -if ((c = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or err? */ - return c; -if (c & SCPE_BREAK) { /* break? */ - if (tt_cmd == TTS_WRITE) { /* during write? */ - tt_cmd = TTS_IDLE; - sim_cancel (&tt_unit[TTO]); /* cancel write */ - chan_uen (tt_dib.dva); /* uend */ - } - return SCPE_OK; - } -c = c & 0x7F; -if (c == tti_panel) /* panel interrupt? */ - return io_set_pint (); -uptr->pos = uptr->pos + 1; /* incr count */ -if (c == '\r') /* map CR to NL */ - c = '\n'; -if (c == 0x7F) /* map ^H back */ - c = 0x08; -c = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags)); /* input conversion */ -ebcdic = ascii_to_ebcdic[c]; /* then to EBCDIC */ -tto_echo (c); /* echo character */ -if ((tt_cmd & 0x7F) == TTS_READ) { /* waiting for input? */ - st = chan_WrMemB (tt_dib.dva, ebcdic); /* write to memory */ - if (CHS_IFERR (st)) /* channel error? */ - return tt_chan_err (st); - if ((st == CHS_ZBC) || (ebcdic == E_EOM) || /* channel end? */ - ((tt_cmd == TTS_READS) && ((ebcdic == E_HT) || (ebcdic == E_NL)))) { - tt_cmd = TTS_END; /* new state */ - sim_activate (&tt_unit[TTO], chan_ctl_time); /* start dev thread */ - } - } -return SCPE_OK; -} - -/* Output service routine - also acts as overall device thread - Because of possible retry, channel status and converted character - must be preserved across calls. */ - -t_stat tto_svc (UNIT *uptr) -{ -int32 c, cmd; -uint32 st; - -switch (tt_cmd) { /* case on state */ - - case TTS_INIT: /* I/O init */ - st = chan_get_cmd (tt_dib.dva, &cmd); /* get command */ - if (CHS_IFERR (st)) /* channel error? */ - return tt_chan_err (st); - if ((cmd == TTS_WRITE) || /* valid command? */ - ((cmd & 0x7F) == TTS_READ)) - tt_cmd = cmd; /* next state */ - else tt_cmd = TTS_END; /* no, end state */ - sim_activate (uptr, chan_ctl_time); /* continue thread */ - break; - - case TTS_WRITE: /* char output */ - st = chan_RdMemB (tt_dib.dva, &c); /* get char */ - if (CHS_IFERR (st)) /* channel error? */ - return tt_chan_err (st); - c = ebcdic_to_ascii[c & 0xFF]; /* convert to ASCII */ - tto_echo (c); /* echo character */ - sim_activate (uptr, uptr->wait); /* continue thread */ - if (st == CHS_ZBC) /* st = zbc? */ - tt_cmd = TTS_END; /* next is end */ - else tt_cmd = TTS_WRITE; /* next is write */ - break; - - case TTS_END: /* command done */ - st = chan_end (tt_dib.dva); /* set channel end */ - if (CHS_IFERR (st)) /* channel error? */ - return tt_chan_err (st); - if (st == CHS_CCH) { /* command chain? */ - tt_cmd = TTS_INIT; /* restart thread */ - sim_activate (uptr, chan_ctl_time); - } - else tt_cmd = TTS_IDLE; /* all done */ - break; - } - -return SCPE_OK; -} - -/* Actual tty output routines; simulates horizontal tabs */ - -void tto_echo (int32 c) -{ -uint32 cnt; - -cnt = 1; -if (c == '\r') - tto_pos = 0; -else if (c == '\n') { - tto_pos = 0; - sim_putchar ('\r'); - tt_unit[TTO].pos = tt_unit[TTO].pos + 1; - } -else if (c == '\t') { - c = ' '; - cnt = 8 - (tto_pos % 8); - } -else c = sim_tt_outcvt (c, TT_GET_MODE (tt_unit[TTO].flags)); -if (c >= 0) { - while (cnt-- > 0) { - sim_putchar (c); - tto_pos++; - tt_unit[TTO].pos = tt_unit[TTO].pos + 1; - } - } -return; -} - -/* TTY status routine */ - -uint32 tt_tio_status (void) -{ -if (tt_cmd == TTS_IDLE) - return DVS_AUTO; -return (CC2 << DVT_V_CC) | DVS_DBUSY | DVS_CBUSY | DVS_AUTO; -} - -/* Channel error */ - -t_stat tt_chan_err (uint32 st) -{ -tt_cmd = TTS_IDLE; -sim_cancel (&tt_unit[TTO]); /* stop dev thread */ -chan_uen (tt_dib.dva); /* uend */ -if (st < CHS_ERR) - return st; -return SCPE_OK; -} - -/* Reset routine */ - -t_stat tt_reset (DEVICE *dptr) -{ -rtc_register (RTC_TTI, tti_tps, &tt_unit[TTI]); /* register timer */ -sim_cancel (&tt_unit[TTO]); /* stop dev thread */ -tt_cmd = TTS_IDLE; /* idle */ -chan_reset_dev (tt_dib.dva); /* clr int, active */ -tto_pos = 0; -return SCPE_OK; -} - -/* Make mode flags uniform */ - -t_stat tt_set_mode (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -tt_unit[TTO].flags = (tt_unit[TTO].flags & ~TT_MODE) | val; -if (val == TT_MODE_7P) - val = TT_MODE_7B; -tt_unit[TTI].flags = (tt_unit[TTI].flags & ~TT_MODE) | val; -return SCPE_OK; -} diff --git a/sim_console.c b/sim_console.c index 0d1d19ee..91bfc0c3 100644 --- a/sim_console.c +++ b/sim_console.c @@ -1,6 +1,6 @@ /* sim_console.c: simulator console I/O library - Copyright (c) 1993-2011, Robert M Supnik + Copyright (c) 1993-2012, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,6 +23,7 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. + 18-Mar-12 RMS Removed unused reference to sim_switches (Dave Bryan) 20-Jan-11 MP Added support for BREAK key on Windows 30-Sep-06 RMS Fixed non-printable characters in KSR mode 22-Jun-06 RMS Implemented SET/SHOW PCHAR @@ -30,27 +31,26 @@ 22-Nov-05 RMS Added central input/output conversion support 05-Nov-04 RMS Moved SET/SHOW DEBUG under CONSOLE hierarchy 28-Oct-04 JDB Fixed SET CONSOLE to allow comma-separated parameters - 20-Aug-04 RMS Added OS/2 EMX fixes (from Holger Veit) - 14-Jul-04 RMS Revised Windows console code (from Dave Bryan) + 20-Aug-04 RMS Added OS/2 EMX fixes (Holger Veit) + 14-Jul-04 RMS Revised Windows console code (Dave Bryan) 28-May-04 RMS Added SET/SHOW CONSOLE RMS Added break, delete character maps 02-Jan-04 RMS Removed timer routines, added Telnet console routines RMS Moved console logging to OS-independent code - 25-Apr-03 RMS Added long seek support from Mark Pizzolato - Added Unix priority control from Mark Pizzolato + 25-Apr-03 RMS Added long seek support (Mark Pizzolato) + Added Unix priority control (Mark Pizzolato) 24-Sep-02 RMS Removed VT support, added Telnet console support - Added CGI support (from Brian Knittel) - Added MacOS sleep (from Peter Schorn) - 14-Jul-02 RMS Added Windows priority control from Mark Pizzolato - 20-May-02 RMS Added Windows VT support from Fischer Franz + Added CGI support (Brian Knittel) + Added MacOS sleep (Peter Schorn) + 14-Jul-02 RMS Added Windows priority control (Mark Pizzolato) + 20-May-02 RMS Added Windows VT support (Fischer Franz) 01-Feb-02 RMS Added VAX fix from Robert Alan Byer - 19-Sep-01 RMS More Mac changes + 19-Sep-01 RMS More MacOS changes 31-Aug-01 RMS Changed int64 to t_int64 for Windoze - 20-Jul-01 RMS Added Macintosh support (from Louis Chretien, Peter Schorn, - and Ben Supnik) + 20-Jul-01 RMS Added MacOS support (Louis Chretien, Peter Schorn, Ben Supnik) 15-May-01 RMS Added logging support 05-Mar-01 RMS Added clock calibration support - 08-Dec-00 BKR Added OS/2 support (from Bruce Ray) + 08-Dec-00 BKR Added OS/2 support (Bruce Ray) 18-Aug-98 RMS Added BeOS support 13-Oct-97 RMS Added NetBSD terminal support 25-Jan-97 RMS Added POSIX terminal I/O support @@ -739,7 +739,6 @@ t_stat sim_os_poll_kbd (void) int c = -1; DWORD nkbevents, nkbevent; INPUT_RECORD rec; -extern int32 sim_switches; if (!GetNumberOfConsoleInputEvents(std_input, &nkbevents)) return SCPE_TTYERR; diff --git a/sim_defs.h b/sim_defs.h index 66f67d44..598a5068 100644 --- a/sim_defs.h +++ b/sim_defs.h @@ -244,6 +244,7 @@ typedef uint32 t_addr; #define SCPE_AFAIL (SCPE_BASE + 42) /* assert failed */ #define SCPE_KFLAG 0010000 /* tti data flag */ #define SCPE_BREAK 0020000 /* tti break flag */ +#define SCPE_DOFAILED 0040000 /* fail in DO, not subproc */ /* Print value format codes */ diff --git a/sim_ether.c b/sim_ether.c index 78cf7fc4..0b4dcfec 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -1713,12 +1713,13 @@ t_stat eth_close(ETH_DEV* dev) { char* msg = "Eth: closed %s\r\n"; pcap_t *pcap; -int pcap_fd = dev->fd_handle; +int pcap_fd; /* make sure device exists */ if (!dev) return SCPE_UNATT; /* close the device */ +pcap_fd = dev->fd_handle; /* save handle to possibly close later */ pcap = (pcap_t *)dev->handle; dev->handle = NULL; dev->fd_handle = 0; diff --git a/sim_rev.h b/sim_rev.h index 35abe360..f3fefd3e 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -38,8 +38,8 @@ patch date module(s) and fix(es) 0 xx-yyy-1 scp.c: - added *nix READLINE support (Mark Pizzolato) - - fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan) - fixed handling of DO with no arguments (Dave Bryan) + - fixed "SHOW DEVICE" with only one enabled unit (Dave Bryan) - clarified some help messages (Mark Pizzolato) - added "SHOW SHOW" and "SHOW SHOW" commands (Mark Pizzolato) - fixed bug in deposit stride for numeric input (John Dundas) @@ -51,8 +51,7 @@ patch date module(s) and fix(es) - major revision (Dave Hittner and Mark Pizzolato) sim_tmxr.c: - - made telnet option negotiation more reliable. - VAX works with PuTTY. (Mark Pizzolato) + - made option negotiation more reliable (Mark Pizzolato) h316_cpu.c: - fixed bugs in MPY, DIV introduced in 3.8-1 (from Theo Engel) @@ -97,14 +96,14 @@ patch date module(s) and fix(es) hp2100_cpu7.c (Dave Bryan): - Corrected "opsize" parameter type in vis_abs - hp2100_defs.h (Dave Bryan): + hp2100_defs.h (Dave Bryan): - Added hp_setsc, hp_showsc functions to support SC modifier - DMA channels renamed from 0,1 to 1,2 to match documentation - Revised I/O signal enum values for concurrent signals - Revised I/O macros for new signal handling - Added DA and DC device select code assignments - hp2100_di.c (Dave Bryan): + hp2100_di.c, hp2100_di.h (Dave Bryan): - Implemented 12821A HP-IB Disc Interface hp2100_di_da.c (Dave Bryan): @@ -112,8 +111,8 @@ patch date module(s) and fix(es) hp2100_dp.c (Dave Bryan): - Added CNTLR_TYPE cast to dp_settype - - hp2100_ds.c (Dave Bryan): + + hp2100_ds.c (Dave Bryan): - Rewritten to use the MAC/ICD disc controller library - ioIOO now notifies controller service of parameter output - Corrected SRQ generation and FIFO under/overrun detection @@ -138,25 +137,25 @@ patch date module(s) and fix(es) - Revised for new multi-card paradigm hp2100_lps.c (Dave Bryan): - - Revised detection of CLC at last DMA cycle + - Revised detection of CLC at last DMA cycle - Corrected 12566B (DIAG mode) jumper settings hp2100_ms.c (Dave Bryan): - Added CNTLR_TYPE cast to ms_settype - + hp2100_mt.c (Dave Bryan): - Fixed command scanning error in mtcio ioIOO handler hp2100_stddev.c (Dave Bryan): - Add TBG as a logical name for the CLK device - + hp2100_sys.c (Dave Bryan): - - Add TBG as a logical name for the CLK device + - Deprecated DEVNO in favor of SC - Added hp_setsc, hp_showsc functions to support SC modifier - Added DA and dummy DC devices - DMA channels renamed from 0,1 to 1,2 to match documentation - Changed DIB access for revised signal model - + hp_disclib.c, hp_disclib.h (Dave Bryan) - Created MAC/ICD disc controller library @@ -164,6 +163,9 @@ patch date module(s) and fix(es) - fixed read stacker operation in column binary mode - fixed punch stacker operation (Van Snyder) + id_pas.c: + - fixed TT_GET_MODE test to use TTUF_MODE_x (Michael Bloom) + 1401_cpu.c: - reverted multiple tape indicator implementation - fixed EOT indicator test not to clear indicator (Van Snyder) @@ -176,12 +178,21 @@ patch date module(s) and fix(es) - fixed backspace over tapemark not to set EOR (Van Snyder) - added no rewind option (Van Snyder) + pdp1_cpu.c: + - fixed misuse of & instead of && in Ea_ch (Michael Bloom) + + pdp1_stddev.c: + - fixed unitialized variable in tty output service (Michael Bloom) + pdp11_defs.h: - fixed priority of PIRQ vs IO; added INT_INTERNALn pdp11_io.c: - fixed Qbus interrupts to treat all IO devices as BR4 + ppd11_rf.c + - fixed bug in updating mem addr extension (Peter Schorn) + pdp11_rk.c: - fixed bug in read header (Walter F Mueller) @@ -191,7 +202,7 @@ patch date module(s) and fix(es) pdp11_rq.c: - added RD32 support - pdp11_tq.c: + pdp11_tq.c: (Mark Pizzolato) - set UNIT_SXC flag when a tape mark is encountered during forward motion read operations - fixed logic which clears UNIT_SXC to check command modifier @@ -201,51 +212,52 @@ patch date module(s) and fix(es) - fixed debug output of tape file positions when they are 64b - added more debug output after positioning operations - added textual display of the command being performed - (all of the above from Mark Pizzolato) - fixed comments about register addresses pdp11_ts.c: - - fixed t_addr printouts for 64b big-endian systems - (from Mark Pizzolato) + - fixed t_addr printouts for 64b big-endian systems (Mark Pizzolato) - pdp8_fpp.c: - - many bug fixes (all from Rick Murphy); now functional + pdp8_fpp.c: (Rick Murphy) + - many bug fixes; now functional pdp8_sys.c: - added link to FPP pdp8_td.c: - - fixed SDLC to clear AC (from Dave Gesswein) + - fixed SDLC to clear AC (Dave Gesswein) + + sds_mt.c: + - fixed bug in scan function decode (Peter Schorn) vax_cpu.c: - - revised idle design (from Mark Pizzolato) + - revised idle design Mark Pizzolato) - fixed bug in SET CPU IDLE - fixed failure to clear PSL in BPT, XFC vax_cpu1.c: - - revised idle design (from Mark Pizzolato) + - revised idle design Mark Pizzolato) - added VEC_QMODE test in interrupt handler - vax_fpa.c - - fixed integer overflow bug in EMODx (from Camiel Vanderhoeven) - - fixed POLYx normalizing before add mask bug (from Camiel Vanderhoeven) + vax_fpa.c: + - fixed integer overflow bug in EMODx (Camiel Vanderhoeven) + - fixed POLYx normalizing before add mask bug (Camiel Vanderhoeven) + - fixed missing arguments in 32b floating add (Mark Pizzolato) - vax_octa.c - - fixed integer overflow bug in EMODH (from Camiel Vanderhoeven) - - fixed POLYH normalizing before add mask bug (from Camiel Vanderhoeven) + vax_octa.c (Camiel Vanderhoeven) + - fixed integer overflow bug in EMODH + - fixed POLYH normalizing before add mask bug vax_syscm.c: - - fixed t_addr printouts for 64b big-endian systems - (from Mark Pizzolato) + - fixed t_addr printouts for 64b big-endian systems (Mark Pizzolato) vax_sysdev.c: - - added power clear call to boot routine (from Mark Pizzolato) + - added power clear call to boot routine (Mark Pizzolato) vax780_sbi.c: - - added AUTORESTART switch support (from Mark Pizzolato) + - added AUTORESTART switch support (Mark Pizzolato) vax780_stddev.c - - added REBOOT support (from Mark Pizzolato) + - added REBOOT support (Mark Pizzolato) vaxmod_def.h - moved all Qbus devices to BR4; deleted RP definitions diff --git a/swtp/swtp_cpu.c b/swtp/swtp_cpu.c index 09cdaa83..e93797f9 100644 --- a/swtp/swtp_cpu.c +++ b/swtp/swtp_cpu.c @@ -109,7 +109,7 @@ int32 int_req = 0; /* Interrupt request */ int32 mem_fault = 0; /* memory fault flag */ extern int32 sim_int_char; -extern int32 sim_brk_types, sim_brk_dflt, sim_brk_summ; /* breakpoint info */ +extern uint32 sim_brk_types, sim_brk_dflt, sim_brk_summ;/* breakpoint info */ /* function prototypes */ @@ -161,7 +161,7 @@ address is here, 'nulldev' means no device is available */ struct idev { - int32 (*routine)(); + int32 (*routine)(int32, int32); }; struct idev dev_table[32] = { @@ -405,7 +405,7 @@ int32 sim_instr (void) } */ IR = OP = mem_get_byte(PC); /* fetch instruction */ - PC = ++PC & ADDRMASK; /* increment PC */ + PC = (PC + 1) & ADDRMASK; /* increment PC */ sim_interval--; /* The Big Instruction Decode Switch */ @@ -421,11 +421,11 @@ int32 sim_instr (void) A = get_psw(); break; case 0x08: /* INX */ - IX = ++IX & ADDRMASK; + IX = (IX + 1) & ADDRMASK; condevalZ(IX); break; case 0x09: /* DEX */ - IX = --IX & ADDRMASK; + IX = (IX - 1) & ADDRMASK; condevalZ(IX); break; case 0x0A: /* CLV */ @@ -558,60 +558,60 @@ int32 sim_instr (void) IX = (SP + 1) & ADDRMASK; break; case 0x31: /* INS */ - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; break; case 0x32: /* PUL A */ - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; A = mem_get_byte(SP); break; case 0x33: /* PUL B */ - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; B = mem_get_byte(SP); break; case 0x34: /* DES */ - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; break; case 0x35: /* TXS */ SP = (IX - 1) & ADDRMASK; break; case 0x36: /* PSH A */ mem_put_byte(SP, A); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; break; case 0x37: /* PSH B */ mem_put_byte(SP, B); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; break; case 0x39: /* RTS */ - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; PC = mem_get_word(SP) & ADDRMASK; - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; break; case 0x3B: /* RTI */ - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; set_psw(mem_get_byte(SP)); - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; B = mem_get_byte(SP); - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; A = mem_get_byte(SP); - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; IX = mem_get_word(SP); - SP = (SP += 2) & ADDRMASK; + SP = (SP + 2) & ADDRMASK; PC = mem_get_word(SP) & ADDRMASK; - SP = ++SP & ADDRMASK; + SP = (SP + 1) & ADDRMASK; break; case 0x3E: /* WAI */ - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_word(SP, PC); - SP = (SP -= 2) & ADDRMASK; + SP = (SP - 2) & ADDRMASK; mem_put_word(SP, IX); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_byte(SP, A); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_byte(SP, B); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_byte(SP, get_psw()); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; if (I) { reason = STOP_HALT; continue; @@ -621,17 +621,17 @@ int32 sim_instr (void) } break; case 0x3F: /* SWI */ - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_word(SP, PC); - SP = (SP -= 2) & ADDRMASK; + SP = (SP - 2) & ADDRMASK; mem_put_word(SP, IX); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_byte(SP, A); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_byte(SP, B); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_byte(SP, get_psw()); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; I = 0x10000; PC = mem_get_word(0xFFFB) & ADDRMASK; break; @@ -720,7 +720,7 @@ int32 sim_instr (void) V = 0; if (A == 0x80) V = 0x10000; - A = --A & 0xFF; + A = (A - 1) & 0xFF; condevalN(A); condevalZ(A); break; @@ -728,7 +728,7 @@ int32 sim_instr (void) V = 0; if (A == 0x7F) V = 0x10000; - A = ++A & 0xFF; + A = (A + 1) & 0xFF; condevalN(A); condevalZ(A); break; @@ -829,7 +829,7 @@ int32 sim_instr (void) V = 0; if (B == 0x80) V = 0x10000; - B = --B & 0xFF; + B = (B - 1) & 0xFF; condevalN(B); condevalZ(B); break; @@ -837,7 +837,7 @@ int32 sim_instr (void) V = 0; if (B == 0x7F) V = 0x10000; - B = ++B & 0xFF; + B = (B + 1) & 0xFF; condevalN(B); condevalZ(B); break; @@ -957,7 +957,7 @@ int32 sim_instr (void) V = 0; if (lo == 0x80) V = 0x10000; - lo = --lo & 0xFF; + lo = (lo - 1) & 0xFF; mem_put_byte(DAR, lo); condevalN(lo); condevalZ(lo); @@ -968,7 +968,7 @@ int32 sim_instr (void) V = 0; if (lo == 0x7F) V = 0x10000; - lo = ++lo & 0xFF; + lo = (lo + 1) & 0xFF; mem_put_byte(DAR, lo); condevalN(lo); condevalZ(lo); @@ -1094,7 +1094,7 @@ int32 sim_instr (void) V = 0; if (lo == 0x80) V = 0x10000; - lo = --lo & 0xFF; + lo = (lo - 1) & 0xFF; mem_put_byte(DAR, lo); condevalN(lo); condevalZ(lo); @@ -1105,7 +1105,7 @@ int32 sim_instr (void) V = 0; if (lo == 0x7F) V = 0x10000; - lo = ++lo & 0xFF; + lo = (lo + 1) & 0xFF; mem_put_byte(DAR, lo); condevalN(lo); condevalZ(lo); @@ -1215,9 +1215,9 @@ int32 sim_instr (void) break; case 0x8D: /* BSR rel */ lo = get_rel_addr(); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_word(SP, PC); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; PC = PC + lo; PC &= ADDRMASK; break; @@ -1429,9 +1429,9 @@ int32 sim_instr (void) break; case 0xAD: /* JSR ind */ DAR = get_indir_addr(); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_word(SP, PC); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; PC = DAR; break; case 0xAE: /* LDS ind */ @@ -1542,9 +1542,9 @@ int32 sim_instr (void) break; case 0xBD: /* JSR ext */ DAR = get_ext_addr(); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; mem_put_word(SP, PC); - SP = --SP & ADDRMASK; + SP = (SP - 1) & ADDRMASK; PC = DAR; break; case 0xBE: /* LDS ext */ @@ -2010,7 +2010,7 @@ int32 get_dir_addr() int32 temp; temp = mem_get_byte(PC); - PC = ++PC & ADDRMASK; + PC = (PC + 1) & ADDRMASK; return temp & 0xFF; } diff --git a/swtp/swtp_defs.h b/swtp/swtp_defs.h index 9e946c18..42bb2e3a 100644 --- a/swtp/swtp_defs.h +++ b/swtp/swtp_defs.h @@ -27,7 +27,7 @@ Copyright (c) 2005, 2007, William Beech */ -#include "../sim_defs.h" // simulator defs +#include "sim_defs.h" // simulator defs /* Memory */ diff --git a/swtp/swtp_dsk.c b/swtp/swtp_dsk.c index 3a636279..9c8c7d38 100644 --- a/swtp/swtp_dsk.c +++ b/swtp/swtp_dsk.c @@ -408,7 +408,7 @@ int32 fdccmd(int32 io, int32 data) #endif break; default: - printf("Unknown FDC command %02H\n\r", data); + printf("Unknown FDC command %02XH\n\r", data); } } else { /* read status from fdc */ val = cur_flg[cur_dsk]; /* set return value */