OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [sim/] [erc32/] [erc32.c] - Diff between revs 827 and 840

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 827 Rev 840
/*
/*
 * This file is part of SIS.
 * This file is part of SIS.
 *
 *
 * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler,
 * SIS, SPARC instruction simulator V2.5 Copyright (C) 1995 Jiri Gaisler,
 * European Space Agency
 * European Space Agency
 *
 *
 * This program is free software; you can redistribute it and/or modify it under
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free
 * the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 * any later version.
 *
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 * more details.
 *
 *
 * You should have received a copy of the GNU General Public License along with
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 675
 * this program; if not, write to the Free Software Foundation, Inc., 675
 * Mass Ave, Cambridge, MA 02139, USA.
 * Mass Ave, Cambridge, MA 02139, USA.
 *
 *
 */
 */
 
 
/* The control space devices */
/* The control space devices */
 
 
#include <sys/types.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdio.h>
#include <termios.h>
#include <termios.h>
#include <sys/fcntl.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/file.h>
#include <unistd.h>
#include <unistd.h>
#include "sis.h"
#include "sis.h"
#include "end.h"
#include "end.h"
#include "sim-config.h"
#include "sim-config.h"
 
 
extern int      ctrl_c;
extern int      ctrl_c;
extern int32    sis_verbose;
extern int32    sis_verbose;
extern int32    sparclite, sparclite_board;
extern int32    sparclite, sparclite_board;
extern int      rom8,wrp,uben;
extern int      rom8,wrp,uben;
extern char     uart_dev1[], uart_dev2[];
extern char     uart_dev1[], uart_dev2[];
 
 
int dumbio = 0; /* normal, smart, terminal oriented IO by default */
int dumbio = 0; /* normal, smart, terminal oriented IO by default */
 
 
/* MEC registers */
/* MEC registers */
#define MEC_START       0x01f80000
#define MEC_START       0x01f80000
#define MEC_END         0x01f80100
#define MEC_END         0x01f80100
 
 
/* Memory exception waitstates */
/* Memory exception waitstates */
#define MEM_EX_WS       1
#define MEM_EX_WS       1
 
 
/* ERC32 always adds one waitstate during RAM std */
/* ERC32 always adds one waitstate during RAM std */
#define STD_WS 1
#define STD_WS 1
 
 
#ifdef ERRINJ
#ifdef ERRINJ
extern int errmec;
extern int errmec;
#endif
#endif
 
 
/* The target's byte order is big-endian by default until we load a
/* The target's byte order is big-endian by default until we load a
   little-endian program.  */
   little-endian program.  */
 
 
int     current_target_byte_order = BIG_ENDIAN;
int     current_target_byte_order = BIG_ENDIAN;
 
 
#define MEC_WS  0                /* Waitstates per MEC access (0 ws) */
#define MEC_WS  0                /* Waitstates per MEC access (0 ws) */
#define MOK     0
#define MOK     0
 
 
/* MEC register addresses */
/* MEC register addresses */
 
 
#define MEC_MCR         0x000
#define MEC_MCR         0x000
#define MEC_SFR         0x004
#define MEC_SFR         0x004
#define MEC_PWDR        0x008
#define MEC_PWDR        0x008
#define MEC_MEMCFG      0x010
#define MEC_MEMCFG      0x010
#define MEC_IOCR        0x014
#define MEC_IOCR        0x014
#define MEC_WCR         0x018
#define MEC_WCR         0x018
 
 
#define MEC_MAR0        0x020
#define MEC_MAR0        0x020
#define MEC_MAR1        0x024
#define MEC_MAR1        0x024
 
 
#define MEC_SSA1        0x020
#define MEC_SSA1        0x020
#define MEC_SEA1        0x024
#define MEC_SEA1        0x024
#define MEC_SSA2        0x028
#define MEC_SSA2        0x028
#define MEC_SEA2        0x02C
#define MEC_SEA2        0x02C
#define MEC_ISR         0x044
#define MEC_ISR         0x044
#define MEC_IPR         0x048
#define MEC_IPR         0x048
#define MEC_IMR         0x04C
#define MEC_IMR         0x04C
#define MEC_ICR         0x050
#define MEC_ICR         0x050
#define MEC_IFR         0x054
#define MEC_IFR         0x054
#define MEC_WDOG        0x060
#define MEC_WDOG        0x060
#define MEC_TRAPD       0x064
#define MEC_TRAPD       0x064
#define MEC_RTC_COUNTER 0x080
#define MEC_RTC_COUNTER 0x080
#define MEC_RTC_RELOAD  0x080
#define MEC_RTC_RELOAD  0x080
#define MEC_RTC_SCALER  0x084
#define MEC_RTC_SCALER  0x084
#define MEC_GPT_COUNTER 0x088
#define MEC_GPT_COUNTER 0x088
#define MEC_GPT_RELOAD  0x088
#define MEC_GPT_RELOAD  0x088
#define MEC_GPT_SCALER  0x08C
#define MEC_GPT_SCALER  0x08C
#define MEC_TIMER_CTRL  0x098
#define MEC_TIMER_CTRL  0x098
#define MEC_SFSR        0x0A0
#define MEC_SFSR        0x0A0
#define MEC_FFAR        0x0A4
#define MEC_FFAR        0x0A4
#define MEC_ERSR        0x0B0
#define MEC_ERSR        0x0B0
#define MEC_DBG         0x0C0
#define MEC_DBG         0x0C0
#define MEC_TCR         0x0D0
#define MEC_TCR         0x0D0
 
 
#define MEC_BRK         0x0C4
#define MEC_BRK         0x0C4
#define MEC_WPR         0x0C8
#define MEC_WPR         0x0C8
 
 
#define MEC_UARTA       0x0E0
#define MEC_UARTA       0x0E0
#define MEC_UARTB       0x0E4
#define MEC_UARTB       0x0E4
#define MEC_UART_CTRL   0x0E8
#define MEC_UART_CTRL   0x0E8
#define SIM_LOAD        0x0F0
#define SIM_LOAD        0x0F0
 
 
/* Memory exception causes */
/* Memory exception causes */
#define PROT_EXC        0x3
#define PROT_EXC        0x3
#define UIMP_ACC        0x4
#define UIMP_ACC        0x4
#define MEC_ACC         0x6
#define MEC_ACC         0x6
#define WATCH_EXC       0xa
#define WATCH_EXC       0xa
#define BREAK_EXC       0xb
#define BREAK_EXC       0xb
 
 
/* Size of UART buffers (bytes) */
/* Size of UART buffers (bytes) */
#define UARTBUF 1024
#define UARTBUF 1024
 
 
/* Number of simulator ticks between flushing the UARTS.         */
/* Number of simulator ticks between flushing the UARTS.         */
/* For good performance, keep above 1000                         */
/* For good performance, keep above 1000                         */
#define UART_FLUSH_TIME   3000
#define UART_FLUSH_TIME   3000
 
 
/* MEC timer control register bits */
/* MEC timer control register bits */
#define TCR_GACR 1
#define TCR_GACR 1
#define TCR_GACL 2
#define TCR_GACL 2
#define TCR_GASE 4
#define TCR_GASE 4
#define TCR_GASL 8
#define TCR_GASL 8
#define TCR_TCRCR 0x100
#define TCR_TCRCR 0x100
#define TCR_TCRCL 0x200
#define TCR_TCRCL 0x200
#define TCR_TCRSE 0x400
#define TCR_TCRSE 0x400
#define TCR_TCRSL 0x800
#define TCR_TCRSL 0x800
 
 
/* New uart defines */
/* New uart defines */
#define UART_TX_TIME    1000
#define UART_TX_TIME    1000
#define UART_RX_TIME    1000
#define UART_RX_TIME    1000
#define UARTA_DR        0x1
#define UARTA_DR        0x1
#define UARTA_SRE       0x2
#define UARTA_SRE       0x2
#define UARTA_HRE       0x4
#define UARTA_HRE       0x4
#define UARTA_OR        0x40
#define UARTA_OR        0x40
#define UARTA_CLR       0x80
#define UARTA_CLR       0x80
#define UARTB_DR        0x10000
#define UARTB_DR        0x10000
#define UARTB_SRE       0x20000
#define UARTB_SRE       0x20000
#define UARTB_HRE       0x40000
#define UARTB_HRE       0x40000
#define UARTB_OR        0x400000
#define UARTB_OR        0x400000
#define UARTB_CLR       0x800000
#define UARTB_CLR       0x800000
 
 
#define UART_DR         0x100
#define UART_DR         0x100
#define UART_TSE        0x200
#define UART_TSE        0x200
#define UART_THE        0x400
#define UART_THE        0x400
 
 
/* MEC registers */
/* MEC registers */
 
 
static char     fname[256];
static char     fname[256];
static int32    find = 0;
static int32    find = 0;
static uint32   mec_ssa[2];     /* Write protection start address */
static uint32   mec_ssa[2];     /* Write protection start address */
static uint32   mec_sea[2];     /* Write protection end address */
static uint32   mec_sea[2];     /* Write protection end address */
static uint32   mec_wpr[2];     /* Write protection control fields */
static uint32   mec_wpr[2];     /* Write protection control fields */
static uint32   mec_sfsr;
static uint32   mec_sfsr;
static uint32   mec_ffar;
static uint32   mec_ffar;
static uint32   mec_ipr;
static uint32   mec_ipr;
static uint32   mec_imr;
static uint32   mec_imr;
static uint32   mec_isr;
static uint32   mec_isr;
static uint32   mec_icr;
static uint32   mec_icr;
static uint32   mec_ifr;
static uint32   mec_ifr;
static uint32   mec_mcr;        /* MEC control register */
static uint32   mec_mcr;        /* MEC control register */
static uint32   mec_memcfg;     /* Memory control register */
static uint32   mec_memcfg;     /* Memory control register */
static uint32   mec_wcr;        /* MEC waitstate register */
static uint32   mec_wcr;        /* MEC waitstate register */
static uint32   mec_iocr;       /* MEC IO control register */
static uint32   mec_iocr;       /* MEC IO control register */
static uint32   posted_irq;
static uint32   posted_irq;
static uint32   mec_ersr;       /* MEC error and status register */
static uint32   mec_ersr;       /* MEC error and status register */
static uint32   mec_tcr;        /* MEC test comtrol register */
static uint32   mec_tcr;        /* MEC test comtrol register */
 
 
static uint32   rtc_counter;
static uint32   rtc_counter;
static uint32   rtc_reload;
static uint32   rtc_reload;
static uint32   rtc_scaler;
static uint32   rtc_scaler;
static uint32   rtc_scaler_start;
static uint32   rtc_scaler_start;
static uint32   rtc_enabled;
static uint32   rtc_enabled;
static uint32   rtc_cr;
static uint32   rtc_cr;
static uint32   rtc_se;
static uint32   rtc_se;
 
 
static uint32   gpt_counter;
static uint32   gpt_counter;
static uint32   gpt_reload;
static uint32   gpt_reload;
static uint32   gpt_scaler;
static uint32   gpt_scaler;
static uint32   gpt_scaler_start;
static uint32   gpt_scaler_start;
static uint32   gpt_enabled;
static uint32   gpt_enabled;
static uint32   gpt_cr;
static uint32   gpt_cr;
static uint32   gpt_se;
static uint32   gpt_se;
 
 
static uint32   wdog_scaler;
static uint32   wdog_scaler;
static uint32   wdog_counter;
static uint32   wdog_counter;
static uint32   wdog_rst_delay;
static uint32   wdog_rst_delay;
static uint32   wdog_rston;
static uint32   wdog_rston;
 
 
enum wdog_type {
enum wdog_type {
    init, disabled, enabled, stopped
    init, disabled, enabled, stopped
};
};
 
 
static enum wdog_type wdog_status;
static enum wdog_type wdog_status;
 
 
 
 
/* ROM size 1024 Kbyte */
/* ROM size 1024 Kbyte */
#define ROM_SZ          0x100000
#define ROM_SZ          0x100000
#define ROM_MASK        0x0fffff
#define ROM_MASK        0x0fffff
 
 
/* RAM size 4 Mbyte */
/* RAM size 4 Mbyte */
#define RAM_START       0x02000000
#define RAM_START       0x02000000
#define RAM_END         0x02400000
#define RAM_END         0x02400000
#define RAM_MASK        0x003fffff
#define RAM_MASK        0x003fffff
 
 
/* SPARClite boards all seem to have RAM at the same place. */
/* SPARClite boards all seem to have RAM at the same place. */
#define RAM_START_SLITE 0x40000000
#define RAM_START_SLITE 0x40000000
#define RAM_END_SLITE   0x40400000
#define RAM_END_SLITE   0x40400000
#define RAM_MASK_SLITE  0x003fffff
#define RAM_MASK_SLITE  0x003fffff
 
 
/* Memory support variables */
/* Memory support variables */
 
 
static uint32   mem_ramr_ws;    /* RAM read waitstates */
static uint32   mem_ramr_ws;    /* RAM read waitstates */
static uint32   mem_ramw_ws;    /* RAM write waitstates */
static uint32   mem_ramw_ws;    /* RAM write waitstates */
static uint32   mem_romr_ws;    /* ROM read waitstates */
static uint32   mem_romr_ws;    /* ROM read waitstates */
static uint32   mem_romw_ws;    /* ROM write waitstates */
static uint32   mem_romw_ws;    /* ROM write waitstates */
static uint32   mem_ramstart;   /* RAM start */
static uint32   mem_ramstart;   /* RAM start */
static uint32   mem_ramend;     /* RAM end */
static uint32   mem_ramend;     /* RAM end */
static uint32   mem_rammask;    /* RAM address mask */
static uint32   mem_rammask;    /* RAM address mask */
static uint32   mem_ramsz;      /* RAM size */
static uint32   mem_ramsz;      /* RAM size */
static uint32   mem_romsz;      /* ROM size */
static uint32   mem_romsz;      /* ROM size */
static uint32   mem_accprot;    /* RAM write protection enabled */
static uint32   mem_accprot;    /* RAM write protection enabled */
static uint32   mem_blockprot;  /* RAM block write protection enabled */
static uint32   mem_blockprot;  /* RAM block write protection enabled */
 
 
static unsigned char    romb[ROM_SZ];
static unsigned char    romb[ROM_SZ];
static unsigned char    ramb[RAM_END - RAM_START];
static unsigned char    ramb[RAM_END - RAM_START];
 
 
 
 
/* UART support variables */
/* UART support variables */
 
 
static int32    fd1, fd2;       /* file descriptor for input file */
static int32    fd1, fd2;       /* file descriptor for input file */
static int32    Ucontrol;       /* UART status register */
static int32    Ucontrol;       /* UART status register */
static unsigned char aq[UARTBUF], bq[UARTBUF];
static unsigned char aq[UARTBUF], bq[UARTBUF];
static int32    anum, aind = 0;
static int32    anum, aind = 0;
static int32    bnum, bind = 0;
static int32    bnum, bind = 0;
static char     wbufa[UARTBUF], wbufb[UARTBUF];
static char     wbufa[UARTBUF], wbufb[UARTBUF];
static unsigned wnuma;
static unsigned wnuma;
static unsigned wnumb;
static unsigned wnumb;
static FILE    *f1in, *f1out, *f2in, *f2out;
static FILE    *f1in, *f1out, *f2in, *f2out;
static struct termios ioc1, ioc2, iocold1, iocold2;
static struct termios ioc1, ioc2, iocold1, iocold2;
static int      f1open = 0, f2open = 0;
static int      f1open = 0, f2open = 0;
 
 
static char     uarta_sreg, uarta_hreg, uartb_sreg, uartb_hreg;
static char     uarta_sreg, uarta_hreg, uartb_sreg, uartb_hreg;
static uint32   uart_stat_reg;
static uint32   uart_stat_reg;
static uint32   uarta_data, uartb_data;
static uint32   uarta_data, uartb_data;
 
 
#ifdef ERA
#ifdef ERA
int era = 0;
int era = 0;
int erareg;
int erareg;
#endif
#endif
 
 
/* Forward declarations */
/* Forward declarations */
 
 
static void     decode_ersr PARAMS ((void));
static void     decode_ersr PARAMS ((void));
#ifdef ERRINJ
#ifdef ERRINJ
static void     iucomperr PARAMS ((void));
static void     iucomperr PARAMS ((void));
#endif
#endif
static void     mecparerror PARAMS ((void));
static void     mecparerror PARAMS ((void));
static void     decode_memcfg PARAMS ((void));
static void     decode_memcfg PARAMS ((void));
static void     decode_wcr PARAMS ((void));
static void     decode_wcr PARAMS ((void));
static void     decode_mcr PARAMS ((void));
static void     decode_mcr PARAMS ((void));
static void     close_port PARAMS ((void));
static void     close_port PARAMS ((void));
static void     mec_reset PARAMS ((void));
static void     mec_reset PARAMS ((void));
static void     mec_intack PARAMS ((int32 level));
static void     mec_intack PARAMS ((int32 level));
static void     chk_irq PARAMS ((void));
static void     chk_irq PARAMS ((void));
static void     mec_irq PARAMS ((int32 level));
static void     mec_irq PARAMS ((int32 level));
static void     set_sfsr PARAMS ((uint32 fault, uint32 addr,
static void     set_sfsr PARAMS ((uint32 fault, uint32 addr,
                                  uint32 asi, uint32 read));
                                  uint32 asi, uint32 read));
static int32    mec_read PARAMS ((uint32 addr, uint32 asi, uint32 *data));
static int32    mec_read PARAMS ((uint32 addr, uint32 asi, uint32 *data));
static int      mec_write PARAMS ((uint32 addr, uint32 data));
static int      mec_write PARAMS ((uint32 addr, uint32 data));
static void     port_init PARAMS ((void));
static void     port_init PARAMS ((void));
static uint32   read_uart PARAMS ((uint32 addr));
static uint32   read_uart PARAMS ((uint32 addr));
static void     write_uart PARAMS ((uint32 addr, uint32 data));
static void     write_uart PARAMS ((uint32 addr, uint32 data));
static void     flush_uart PARAMS ((void));
static void     flush_uart PARAMS ((void));
static void     uarta_tx PARAMS ((void));
static void     uarta_tx PARAMS ((void));
static void     uartb_tx PARAMS ((void));
static void     uartb_tx PARAMS ((void));
static void     uart_rx PARAMS ((caddr_t arg));
static void     uart_rx PARAMS ((caddr_t arg));
static void     uart_intr PARAMS ((caddr_t arg));
static void     uart_intr PARAMS ((caddr_t arg));
static void     uart_irq_start PARAMS ((void));
static void     uart_irq_start PARAMS ((void));
static void     wdog_intr PARAMS ((caddr_t arg));
static void     wdog_intr PARAMS ((caddr_t arg));
static void     wdog_start PARAMS ((void));
static void     wdog_start PARAMS ((void));
static void     rtc_intr PARAMS ((caddr_t arg));
static void     rtc_intr PARAMS ((caddr_t arg));
static void     rtc_start PARAMS ((void));
static void     rtc_start PARAMS ((void));
static uint32   rtc_counter_read PARAMS ((void));
static uint32   rtc_counter_read PARAMS ((void));
static void     rtc_scaler_set PARAMS ((uint32 val));
static void     rtc_scaler_set PARAMS ((uint32 val));
static void     rtc_reload_set PARAMS ((uint32 val));
static void     rtc_reload_set PARAMS ((uint32 val));
static void     gpt_intr PARAMS ((caddr_t arg));
static void     gpt_intr PARAMS ((caddr_t arg));
static void     gpt_start PARAMS ((void));
static void     gpt_start PARAMS ((void));
static uint32   gpt_counter_read PARAMS ((void));
static uint32   gpt_counter_read PARAMS ((void));
static void     gpt_scaler_set PARAMS ((uint32 val));
static void     gpt_scaler_set PARAMS ((uint32 val));
static void     gpt_reload_set PARAMS ((uint32 val));
static void     gpt_reload_set PARAMS ((uint32 val));
static void     timer_ctrl PARAMS ((uint32 val));
static void     timer_ctrl PARAMS ((uint32 val));
static unsigned char *
static unsigned char *
                get_mem_ptr PARAMS ((uint32 addr, uint32 size));
                get_mem_ptr PARAMS ((uint32 addr, uint32 size));
 
 
static void     fetch_bytes PARAMS ((int asi, unsigned char *mem,
static void     fetch_bytes PARAMS ((int asi, unsigned char *mem,
                                     uint32 *data, int sz));
                                     uint32 *data, int sz));
 
 
static void     store_bytes PARAMS ((unsigned char *mem, uint32 *data, int sz));
static void     store_bytes PARAMS ((unsigned char *mem, uint32 *data, int sz));
 
 
extern int      ext_irl;
extern int      ext_irl;
 
 
 
 
/* One-time init */
/* One-time init */
 
 
void
void
init_sim()
init_sim()
{
{
    port_init();
    port_init();
}
}
 
 
/* Power-on reset init */
/* Power-on reset init */
 
 
void
void
reset()
reset()
{
{
    mec_reset();
    mec_reset();
    uart_irq_start();
    uart_irq_start();
    wdog_start();
    wdog_start();
}
}
 
 
static void
static void
decode_ersr()
decode_ersr()
{
{
    if (mec_ersr & 0x01) {
    if (mec_ersr & 0x01) {
        if (!(mec_mcr & 0x20)) {
        if (!(mec_mcr & 0x20)) {
            if (mec_mcr & 0x40) {
            if (mec_mcr & 0x40) {
                sys_reset();
                sys_reset();
                mec_ersr = 0x8000;
                mec_ersr = 0x8000;
                if (sis_verbose)
                if (sis_verbose)
                    printf("Error manager reset - IU in error mode\n");
                    printf("Error manager reset - IU in error mode\n");
            } else {
            } else {
                sys_halt();
                sys_halt();
                mec_ersr |= 0x2000;
                mec_ersr |= 0x2000;
                if (sis_verbose)
                if (sis_verbose)
                    printf("Error manager halt - IU in error mode\n");
                    printf("Error manager halt - IU in error mode\n");
            }
            }
        } else
        } else
            mec_irq(1);
            mec_irq(1);
    }
    }
    if (mec_ersr & 0x04) {
    if (mec_ersr & 0x04) {
        if (!(mec_mcr & 0x200)) {
        if (!(mec_mcr & 0x200)) {
            if (mec_mcr & 0x400) {
            if (mec_mcr & 0x400) {
                sys_reset();
                sys_reset();
                mec_ersr = 0x8000;
                mec_ersr = 0x8000;
                if (sis_verbose)
                if (sis_verbose)
                    printf("Error manager reset - IU comparison error\n");
                    printf("Error manager reset - IU comparison error\n");
            } else {
            } else {
                sys_halt();
                sys_halt();
                mec_ersr |= 0x2000;
                mec_ersr |= 0x2000;
                if (sis_verbose)
                if (sis_verbose)
                    printf("Error manager halt - IU comparison error\n");
                    printf("Error manager halt - IU comparison error\n");
            }
            }
        } else
        } else
            mec_irq(1);
            mec_irq(1);
    }
    }
    if (mec_ersr & 0x20) {
    if (mec_ersr & 0x20) {
        if (!(mec_mcr & 0x2000)) {
        if (!(mec_mcr & 0x2000)) {
            if (mec_mcr & 0x4000) {
            if (mec_mcr & 0x4000) {
                sys_reset();
                sys_reset();
                mec_ersr = 0x8000;
                mec_ersr = 0x8000;
                if (sis_verbose)
                if (sis_verbose)
                    printf("Error manager reset - MEC hardware error\n");
                    printf("Error manager reset - MEC hardware error\n");
            } else {
            } else {
                sys_halt();
                sys_halt();
                mec_ersr |= 0x2000;
                mec_ersr |= 0x2000;
                if (sis_verbose)
                if (sis_verbose)
                    printf("Error manager halt - MEC hardware error\n");
                    printf("Error manager halt - MEC hardware error\n");
            }
            }
        } else
        } else
            mec_irq(1);
            mec_irq(1);
    }
    }
}
}
 
 
#ifdef ERRINJ
#ifdef ERRINJ
static void
static void
iucomperr()
iucomperr()
{
{
    mec_ersr |= 0x04;
    mec_ersr |= 0x04;
    decode_ersr();
    decode_ersr();
}
}
#endif
#endif
 
 
static void
static void
mecparerror()
mecparerror()
{
{
    mec_ersr |= 0x20;
    mec_ersr |= 0x20;
    decode_ersr();
    decode_ersr();
}
}
 
 
 
 
/* IU error mode manager */
/* IU error mode manager */
 
 
void
void
error_mode(pc)
error_mode(pc)
    uint32          pc;
    uint32          pc;
{
{
 
 
    mec_ersr |= 0x1;
    mec_ersr |= 0x1;
    decode_ersr();
    decode_ersr();
}
}
 
 
 
 
/* Check memory settings */
/* Check memory settings */
 
 
static void
static void
decode_memcfg()
decode_memcfg()
{
{
    if (rom8) mec_memcfg &= ~0x20000;
    if (rom8) mec_memcfg &= ~0x20000;
    else mec_memcfg |= 0x20000;
    else mec_memcfg |= 0x20000;
 
 
    mem_ramsz = (256 * 1024) << ((mec_memcfg >> 10) & 7);
    mem_ramsz = (256 * 1024) << ((mec_memcfg >> 10) & 7);
    mem_romsz = (128 * 1024) << ((mec_memcfg >> 18) & 7);
    mem_romsz = (128 * 1024) << ((mec_memcfg >> 18) & 7);
 
 
    if (sparclite_board) {
    if (sparclite_board) {
        mem_ramstart = RAM_START_SLITE;
        mem_ramstart = RAM_START_SLITE;
        mem_ramend = RAM_END_SLITE;
        mem_ramend = RAM_END_SLITE;
        mem_rammask = RAM_MASK_SLITE;
        mem_rammask = RAM_MASK_SLITE;
    }
    }
    else {
    else {
        mem_ramstart = RAM_START;
        mem_ramstart = RAM_START;
        mem_ramend = RAM_END;
        mem_ramend = RAM_END;
        mem_rammask = RAM_MASK;
        mem_rammask = RAM_MASK;
    }
    }
    if (sis_verbose)
    if (sis_verbose)
        printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
        printf("RAM start: 0x%x, RAM size: %d K, ROM size: %d K\n",
               mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10);
               mem_ramstart, mem_ramsz >> 10, mem_romsz >> 10);
}
}
 
 
static void
static void
decode_wcr()
decode_wcr()
{
{
    mem_ramr_ws = mec_wcr & 3;
    mem_ramr_ws = mec_wcr & 3;
    mem_ramw_ws = (mec_wcr >> 2) & 3;
    mem_ramw_ws = (mec_wcr >> 2) & 3;
    mem_romr_ws = (mec_wcr >> 4) & 0x0f;
    mem_romr_ws = (mec_wcr >> 4) & 0x0f;
    if (rom8) {
    if (rom8) {
        if (mem_romr_ws > 0 )  mem_romr_ws--;
        if (mem_romr_ws > 0 )  mem_romr_ws--;
        mem_romr_ws = 5 + (4*mem_romr_ws);
        mem_romr_ws = 5 + (4*mem_romr_ws);
    }
    }
    mem_romw_ws = (mec_wcr >> 8) & 0x0f;
    mem_romw_ws = (mec_wcr >> 8) & 0x0f;
    if (sis_verbose)
    if (sis_verbose)
        printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n",
        printf("Waitstates = RAM read: %d, RAM write: %d, ROM read: %d, ROM write: %d\n",
               mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws);
               mem_ramr_ws, mem_ramw_ws, mem_romr_ws, mem_romw_ws);
}
}
 
 
static void
static void
decode_mcr()
decode_mcr()
{
{
    mem_accprot = (mec_wpr[0] | mec_wpr[1]);
    mem_accprot = (mec_wpr[0] | mec_wpr[1]);
    mem_blockprot = (mec_mcr >> 3) & 1;
    mem_blockprot = (mec_mcr >> 3) & 1;
    if (sis_verbose && mem_accprot)
    if (sis_verbose && mem_accprot)
        printf("Memory block write protection enabled\n");
        printf("Memory block write protection enabled\n");
    if (mec_mcr & 0x08000) {
    if (mec_mcr & 0x08000) {
        mec_ersr |= 0x20;
        mec_ersr |= 0x20;
        decode_ersr();
        decode_ersr();
    }
    }
    if (sis_verbose && (mec_mcr & 2))
    if (sis_verbose && (mec_mcr & 2))
        printf("Software reset enabled\n");
        printf("Software reset enabled\n");
    if (sis_verbose && (mec_mcr & 1))
    if (sis_verbose && (mec_mcr & 1))
        printf("Power-down mode enabled\n");
        printf("Power-down mode enabled\n");
}
}
 
 
/* Flush ports when simulator stops */
/* Flush ports when simulator stops */
 
 
void
void
sim_halt()
sim_halt()
{
{
#ifdef FAST_UART
#ifdef FAST_UART
    flush_uart();
    flush_uart();
#endif
#endif
}
}
 
 
int
int
sim_stop(SIM_DESC sd)
sim_stop(SIM_DESC sd)
{
{
  ctrl_c = 1;
  ctrl_c = 1;
  return 1;
  return 1;
}
}
 
 
static void
static void
close_port()
close_port()
{
{
    if (f1open && f1in != stdin)
    if (f1open && f1in != stdin)
        fclose(f1in);
        fclose(f1in);
    if (f2open && f2in != stdin)
    if (f2open && f2in != stdin)
        fclose(f2in);
        fclose(f2in);
}
}
 
 
void
void
exit_sim()
exit_sim()
{
{
    close_port();
    close_port();
}
}
 
 
static void
static void
mec_reset()
mec_reset()
{
{
    int             i;
    int             i;
 
 
    find = 0;
    find = 0;
    for (i = 0; i < 2; i++)
    for (i = 0; i < 2; i++)
        mec_ssa[i] = mec_sea[i] = mec_wpr[i] = 0;
        mec_ssa[i] = mec_sea[i] = mec_wpr[i] = 0;
    mec_mcr = 0x01350014;
    mec_mcr = 0x01350014;
    mec_iocr = 0;
    mec_iocr = 0;
    mec_sfsr = 0x078;
    mec_sfsr = 0x078;
    mec_ffar = 0;
    mec_ffar = 0;
    mec_ipr = 0;
    mec_ipr = 0;
    mec_imr = 0x7ffe;
    mec_imr = 0x7ffe;
    mec_isr = 0;
    mec_isr = 0;
    mec_icr = 0;
    mec_icr = 0;
    mec_ifr = 0;
    mec_ifr = 0;
    mec_memcfg = 0x10000;
    mec_memcfg = 0x10000;
    mec_wcr = -1;
    mec_wcr = -1;
    mec_ersr = 0;                /* MEC error and status register */
    mec_ersr = 0;                /* MEC error and status register */
    mec_tcr = 0;         /* MEC test comtrol register */
    mec_tcr = 0;         /* MEC test comtrol register */
 
 
    decode_memcfg();
    decode_memcfg();
    decode_wcr();
    decode_wcr();
    decode_mcr();
    decode_mcr();
 
 
    posted_irq = 0;
    posted_irq = 0;
    wnuma = wnumb = 0;
    wnuma = wnumb = 0;
    anum = aind = bnum = bind = 0;
    anum = aind = bnum = bind = 0;
 
 
    uart_stat_reg = UARTA_SRE | UARTA_HRE | UARTB_SRE | UARTB_HRE;
    uart_stat_reg = UARTA_SRE | UARTA_HRE | UARTB_SRE | UARTB_HRE;
    uarta_data = uartb_data = UART_THE | UART_TSE;
    uarta_data = uartb_data = UART_THE | UART_TSE;
 
 
    rtc_counter = 0xffffffff;
    rtc_counter = 0xffffffff;
    rtc_reload = 0xffffffff;
    rtc_reload = 0xffffffff;
    rtc_scaler = 0xff;
    rtc_scaler = 0xff;
    rtc_enabled = 0;
    rtc_enabled = 0;
    rtc_cr = 0;
    rtc_cr = 0;
    rtc_se = 0;
    rtc_se = 0;
 
 
    gpt_counter = 0xffffffff;
    gpt_counter = 0xffffffff;
    gpt_reload = 0xffffffff;
    gpt_reload = 0xffffffff;
    gpt_scaler = 0xffff;
    gpt_scaler = 0xffff;
    gpt_enabled = 0;
    gpt_enabled = 0;
    gpt_cr = 0;
    gpt_cr = 0;
    gpt_se = 0;
    gpt_se = 0;
 
 
    wdog_scaler = 255;
    wdog_scaler = 255;
    wdog_rst_delay = 255;
    wdog_rst_delay = 255;
    wdog_counter = 0xffff;
    wdog_counter = 0xffff;
    wdog_rston = 0;
    wdog_rston = 0;
    wdog_status = init;
    wdog_status = init;
 
 
#ifdef ERA
#ifdef ERA
    erareg = 0;
    erareg = 0;
#endif
#endif
 
 
}
}
 
 
 
 
 
 
static void
static void
mec_intack(level)
mec_intack(level)
    int32           level;
    int32           level;
{
{
    int             irq_test;
    int             irq_test;
 
 
    if (sis_verbose)
    if (sis_verbose)
        printf("interrupt %d acknowledged\n", level);
        printf("interrupt %d acknowledged\n", level);
    irq_test = mec_tcr & 0x80000;
    irq_test = mec_tcr & 0x80000;
    if ((irq_test) && (mec_ifr & (1 << level)))
    if ((irq_test) && (mec_ifr & (1 << level)))
        mec_ifr &= ~(1 << level);
        mec_ifr &= ~(1 << level);
    else
    else
        mec_ipr &= ~(1 << level);
        mec_ipr &= ~(1 << level);
   chk_irq();
   chk_irq();
}
}
 
 
static void
static void
chk_irq()
chk_irq()
{
{
    int32           i;
    int32           i;
    uint32          itmp;
    uint32          itmp;
    int             old_irl;
    int             old_irl;
 
 
    old_irl = ext_irl;
    old_irl = ext_irl;
    if (mec_tcr & 0x80000) itmp = mec_ifr;
    if (mec_tcr & 0x80000) itmp = mec_ifr;
    else itmp  = 0;
    else itmp  = 0;
    itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe;
    itmp = ((mec_ipr | itmp) & ~mec_imr) & 0x0fffe;
    ext_irl = 0;
    ext_irl = 0;
    if (itmp != 0) {
    if (itmp != 0) {
        for (i = 15; i > 0; i--) {
        for (i = 15; i > 0; i--) {
            if (((itmp >> i) & 1) != 0) {
            if (((itmp >> i) & 1) != 0) {
                if ((sis_verbose) && (i > old_irl))
                if ((sis_verbose) && (i > old_irl))
                    printf("IU irl: %d\n", i);
                    printf("IU irl: %d\n", i);
                ext_irl = i;
                ext_irl = i;
                set_int(i, mec_intack, i);
                set_int(i, mec_intack, i);
                break;
                break;
            }
            }
        }
        }
    }
    }
}
}
 
 
static void
static void
mec_irq(level)
mec_irq(level)
    int32           level;
    int32           level;
{
{
    mec_ipr |= (1 << level);
    mec_ipr |= (1 << level);
    chk_irq();
    chk_irq();
}
}
 
 
static void
static void
set_sfsr(fault, addr, asi, read)
set_sfsr(fault, addr, asi, read)
    uint32          fault;
    uint32          fault;
    uint32          addr;
    uint32          addr;
    uint32          asi;
    uint32          asi;
    uint32          read;
    uint32          read;
{
{
    if ((asi == 0xa) || (asi == 0xb)) {
    if ((asi == 0xa) || (asi == 0xb)) {
        mec_ffar = addr;
        mec_ffar = addr;
        mec_sfsr = (fault << 3) | (!read << 15);
        mec_sfsr = (fault << 3) | (!read << 15);
        mec_sfsr |= ((mec_sfsr & 1) ^ 1) | (mec_sfsr & 1);
        mec_sfsr |= ((mec_sfsr & 1) ^ 1) | (mec_sfsr & 1);
        switch (asi) {
        switch (asi) {
        case 0xa:
        case 0xa:
            mec_sfsr |= 0x0004;
            mec_sfsr |= 0x0004;
            break;
            break;
        case 0xb:
        case 0xb:
            mec_sfsr |= 0x1004;
            mec_sfsr |= 0x1004;
            break;
            break;
        }
        }
    }
    }
}
}
 
 
static int32
static int32
mec_read(addr, asi, data)
mec_read(addr, asi, data)
    uint32          addr;
    uint32          addr;
    uint32          asi;
    uint32          asi;
    uint32         *data;
    uint32         *data;
{
{
 
 
    switch (addr & 0x0ff) {
    switch (addr & 0x0ff) {
 
 
    case MEC_MCR:               /* 0x00 */
    case MEC_MCR:               /* 0x00 */
        *data = mec_mcr;
        *data = mec_mcr;
        break;
        break;
 
 
    case MEC_MEMCFG:            /* 0x10 */
    case MEC_MEMCFG:            /* 0x10 */
        *data = mec_memcfg;
        *data = mec_memcfg;
        break;
        break;
 
 
    case MEC_IOCR:
    case MEC_IOCR:
        *data = mec_iocr;       /* 0x14 */
        *data = mec_iocr;       /* 0x14 */
        break;
        break;
 
 
    case MEC_SSA1:              /* 0x20 */
    case MEC_SSA1:              /* 0x20 */
        *data = mec_ssa[0] | (mec_wpr[0] << 23);
        *data = mec_ssa[0] | (mec_wpr[0] << 23);
        break;
        break;
    case MEC_SEA1:              /* 0x24 */
    case MEC_SEA1:              /* 0x24 */
        *data = mec_sea[0];
        *data = mec_sea[0];
        break;
        break;
    case MEC_SSA2:              /* 0x28 */
    case MEC_SSA2:              /* 0x28 */
        *data = mec_ssa[1] | (mec_wpr[1] << 23);
        *data = mec_ssa[1] | (mec_wpr[1] << 23);
        break;
        break;
    case MEC_SEA2:              /* 0x2c */
    case MEC_SEA2:              /* 0x2c */
        *data = mec_sea[1];
        *data = mec_sea[1];
        break;
        break;
 
 
    case MEC_ISR:               /* 0x44 */
    case MEC_ISR:               /* 0x44 */
        *data = mec_isr;
        *data = mec_isr;
        break;
        break;
 
 
    case MEC_IPR:               /* 0x48 */
    case MEC_IPR:               /* 0x48 */
        *data = mec_ipr;
        *data = mec_ipr;
        break;
        break;
 
 
    case MEC_IMR:               /* 0x4c */
    case MEC_IMR:               /* 0x4c */
        *data = mec_imr;
        *data = mec_imr;
        break;
        break;
 
 
    case MEC_IFR:               /* 0x54 */
    case MEC_IFR:               /* 0x54 */
        *data = mec_ifr;
        *data = mec_ifr;
        break;
        break;
 
 
    case MEC_RTC_COUNTER:       /* 0x80 */
    case MEC_RTC_COUNTER:       /* 0x80 */
        *data = rtc_counter_read();
        *data = rtc_counter_read();
        break;
        break;
    case MEC_RTC_SCALER:        /* 0x84 */
    case MEC_RTC_SCALER:        /* 0x84 */
        if (rtc_enabled)
        if (rtc_enabled)
            *data = rtc_scaler - (now() - rtc_scaler_start);
            *data = rtc_scaler - (now() - rtc_scaler_start);
        else
        else
            *data = rtc_scaler;
            *data = rtc_scaler;
        break;
        break;
 
 
    case MEC_GPT_COUNTER:       /* 0x88 */
    case MEC_GPT_COUNTER:       /* 0x88 */
        *data = gpt_counter_read();
        *data = gpt_counter_read();
        break;
        break;
 
 
    case MEC_GPT_SCALER:        /* 0x8c */
    case MEC_GPT_SCALER:        /* 0x8c */
        if (rtc_enabled)
        if (rtc_enabled)
            *data = gpt_scaler - (now() - gpt_scaler_start);
            *data = gpt_scaler - (now() - gpt_scaler_start);
        else
        else
            *data = gpt_scaler;
            *data = gpt_scaler;
        break;
        break;
 
 
 
 
    case MEC_SFSR:              /* 0xA0 */
    case MEC_SFSR:              /* 0xA0 */
        *data = mec_sfsr;
        *data = mec_sfsr;
        break;
        break;
 
 
    case MEC_FFAR:              /* 0xA4 */
    case MEC_FFAR:              /* 0xA4 */
        *data = mec_ffar;
        *data = mec_ffar;
        break;
        break;
 
 
    case SIM_LOAD:
    case SIM_LOAD:
        fname[find] = 0;
        fname[find] = 0;
        if (find == 0)
        if (find == 0)
            strcpy(fname, "simload");
            strcpy(fname, "simload");
        find = bfd_load(fname);
        find = bfd_load(fname);
        if (find == -1)
        if (find == -1)
            *data = 0;
            *data = 0;
        else
        else
            *data = 1;
            *data = 1;
        find = 0;
        find = 0;
        break;
        break;
 
 
    case MEC_ERSR:              /* 0xB0 */
    case MEC_ERSR:              /* 0xB0 */
        *data = mec_ersr;
        *data = mec_ersr;
        break;
        break;
 
 
    case MEC_TCR:               /* 0xD0 */
    case MEC_TCR:               /* 0xD0 */
        *data = mec_tcr;
        *data = mec_tcr;
        break;
        break;
 
 
    case MEC_UARTA:             /* 0xE0 */
    case MEC_UARTA:             /* 0xE0 */
    case MEC_UARTB:             /* 0xE4 */
    case MEC_UARTB:             /* 0xE4 */
        if (asi != 0xb) {
        if (asi != 0xb) {
            set_sfsr(MEC_ACC, addr, asi, 1);
            set_sfsr(MEC_ACC, addr, asi, 1);
            return (1);
            return (1);
        }
        }
        *data = read_uart(addr);
        *data = read_uart(addr);
        break;
        break;
 
 
    case MEC_UART_CTRL:         /* 0xE8 */
    case MEC_UART_CTRL:         /* 0xE8 */
 
 
        *data = read_uart(addr);
        *data = read_uart(addr);
        break;
        break;
 
 
    default:
    default:
        set_sfsr(MEC_ACC, addr, asi, 1);
        set_sfsr(MEC_ACC, addr, asi, 1);
        return (1);
        return (1);
        break;
        break;
    }
    }
    return (MOK);
    return (MOK);
}
}
 
 
static int
static int
mec_write(addr, data)
mec_write(addr, data)
    uint32          addr;
    uint32          addr;
    uint32          data;
    uint32          data;
{
{
    if (sis_verbose > 1)
    if (sis_verbose > 1)
        printf("MEC write a: %08x, d: %08x\n",addr,data);
        printf("MEC write a: %08x, d: %08x\n",addr,data);
    switch (addr & 0x0ff) {
    switch (addr & 0x0ff) {
 
 
    case MEC_MCR:
    case MEC_MCR:
        mec_mcr = data;
        mec_mcr = data;
        decode_mcr();
        decode_mcr();
        if (mec_mcr & 0x08000) mecparerror();
        if (mec_mcr & 0x08000) mecparerror();
        break;
        break;
 
 
    case MEC_SFR:
    case MEC_SFR:
        if (mec_mcr & 0x2) {
        if (mec_mcr & 0x2) {
            sys_reset();
            sys_reset();
            mec_ersr = 0x4000;
            mec_ersr = 0x4000;
            if (sis_verbose)
            if (sis_verbose)
                printf(" Software reset issued\n");
                printf(" Software reset issued\n");
        }
        }
        break;
        break;
 
 
    case MEC_IOCR:
    case MEC_IOCR:
        mec_iocr = data;
        mec_iocr = data;
        if (mec_iocr & 0xC0C0C0C0) mecparerror();
        if (mec_iocr & 0xC0C0C0C0) mecparerror();
        break;
        break;
 
 
    case MEC_SSA1:              /* 0x20 */
    case MEC_SSA1:              /* 0x20 */
        if (data & 0xFE000000) mecparerror();
        if (data & 0xFE000000) mecparerror();
        mec_ssa[0] = data & 0x7fffff;
        mec_ssa[0] = data & 0x7fffff;
        mec_wpr[0] = (data >> 23) & 0x03;
        mec_wpr[0] = (data >> 23) & 0x03;
        mem_accprot = mec_wpr[0] || mec_wpr[1];
        mem_accprot = mec_wpr[0] || mec_wpr[1];
        if (sis_verbose && mec_wpr[0])
        if (sis_verbose && mec_wpr[0])
            printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n",
            printf("Segment 1 memory protection enabled (0x02%06x - 0x02%06x)\n",
                   mec_ssa[0] << 2, mec_sea[0] << 2);
                   mec_ssa[0] << 2, mec_sea[0] << 2);
        break;
        break;
    case MEC_SEA1:              /* 0x24 */
    case MEC_SEA1:              /* 0x24 */
        if (data & 0xFF800000) mecparerror();
        if (data & 0xFF800000) mecparerror();
        mec_sea[0] = data & 0x7fffff;
        mec_sea[0] = data & 0x7fffff;
        break;
        break;
    case MEC_SSA2:              /* 0x28 */
    case MEC_SSA2:              /* 0x28 */
        if (data & 0xFE000000) mecparerror();
        if (data & 0xFE000000) mecparerror();
        mec_ssa[1] = data & 0x7fffff;
        mec_ssa[1] = data & 0x7fffff;
        mec_wpr[1] = (data >> 23) & 0x03;
        mec_wpr[1] = (data >> 23) & 0x03;
        mem_accprot = mec_wpr[0] || mec_wpr[1];
        mem_accprot = mec_wpr[0] || mec_wpr[1];
        if (sis_verbose && mec_wpr[1])
        if (sis_verbose && mec_wpr[1])
            printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n",
            printf("Segment 2 memory protection enabled (0x02%06x - 0x02%06x)\n",
                   mec_ssa[1] << 2, mec_sea[1] << 2);
                   mec_ssa[1] << 2, mec_sea[1] << 2);
        break;
        break;
    case MEC_SEA2:              /* 0x2c */
    case MEC_SEA2:              /* 0x2c */
        if (data & 0xFF800000) mecparerror();
        if (data & 0xFF800000) mecparerror();
        mec_sea[1] = data & 0x7fffff;
        mec_sea[1] = data & 0x7fffff;
        break;
        break;
 
 
    case MEC_UARTA:
    case MEC_UARTA:
    case MEC_UARTB:
    case MEC_UARTB:
        if (data & 0xFFFFFF00) mecparerror();
        if (data & 0xFFFFFF00) mecparerror();
    case MEC_UART_CTRL:
    case MEC_UART_CTRL:
        if (data & 0xFF00FF00) mecparerror();
        if (data & 0xFF00FF00) mecparerror();
        write_uart(addr, data);
        write_uart(addr, data);
        break;
        break;
 
 
    case MEC_GPT_RELOAD:
    case MEC_GPT_RELOAD:
        gpt_reload_set(data);
        gpt_reload_set(data);
        break;
        break;
 
 
    case MEC_GPT_SCALER:
    case MEC_GPT_SCALER:
        if (data & 0xFFFF0000) mecparerror();
        if (data & 0xFFFF0000) mecparerror();
        gpt_scaler_set(data);
        gpt_scaler_set(data);
        break;
        break;
 
 
    case MEC_TIMER_CTRL:
    case MEC_TIMER_CTRL:
        if (data & 0xFFFFF0F0) mecparerror();
        if (data & 0xFFFFF0F0) mecparerror();
        timer_ctrl(data);
        timer_ctrl(data);
        break;
        break;
 
 
    case MEC_RTC_RELOAD:
    case MEC_RTC_RELOAD:
        rtc_reload_set(data);
        rtc_reload_set(data);
        break;
        break;
 
 
    case MEC_RTC_SCALER:
    case MEC_RTC_SCALER:
        if (data & 0xFFFFFF00) mecparerror();
        if (data & 0xFFFFFF00) mecparerror();
        rtc_scaler_set(data);
        rtc_scaler_set(data);
        break;
        break;
 
 
    case MEC_SFSR:              /* 0xA0 */
    case MEC_SFSR:              /* 0xA0 */
        if (data & 0xFFFF0880) mecparerror();
        if (data & 0xFFFF0880) mecparerror();
        mec_sfsr = 0x78;
        mec_sfsr = 0x78;
        break;
        break;
 
 
    case MEC_ISR:
    case MEC_ISR:
        if (data & 0xFFFFE000) mecparerror();
        if (data & 0xFFFFE000) mecparerror();
        mec_isr = data;
        mec_isr = data;
        break;
        break;
 
 
    case MEC_IMR:               /* 0x4c */
    case MEC_IMR:               /* 0x4c */
 
 
        if (data & 0xFFFF8001) mecparerror();
        if (data & 0xFFFF8001) mecparerror();
        mec_imr = data & 0x7ffe;
        mec_imr = data & 0x7ffe;
        chk_irq();
        chk_irq();
        break;
        break;
 
 
    case MEC_ICR:               /* 0x50 */
    case MEC_ICR:               /* 0x50 */
 
 
        if (data & 0xFFFF0001) mecparerror();
        if (data & 0xFFFF0001) mecparerror();
        mec_ipr &= ~data & 0x0fffe;
        mec_ipr &= ~data & 0x0fffe;
        chk_irq();
        chk_irq();
        break;
        break;
 
 
    case MEC_IFR:               /* 0x54 */
    case MEC_IFR:               /* 0x54 */
 
 
        if (mec_tcr & 0x080000) {
        if (mec_tcr & 0x080000) {
            if (data & 0xFFFF0001) mecparerror();
            if (data & 0xFFFF0001) mecparerror();
            mec_ifr = data & 0xfffe;
            mec_ifr = data & 0xfffe;
            chk_irq();
            chk_irq();
        }
        }
        break;
        break;
    case SIM_LOAD:
    case SIM_LOAD:
        fname[find++] = (char) data;
        fname[find++] = (char) data;
        break;
        break;
 
 
 
 
    case MEC_MEMCFG:            /* 0x10 */
    case MEC_MEMCFG:            /* 0x10 */
        if (data & 0xC0E08000) mecparerror();
        if (data & 0xC0E08000) mecparerror();
        mec_memcfg = data;
        mec_memcfg = data;
        decode_memcfg();
        decode_memcfg();
        if (mec_memcfg & 0xc0e08000)
        if (mec_memcfg & 0xc0e08000)
            mecparerror();
            mecparerror();
        break;
        break;
 
 
    case MEC_WCR:               /* 0x18 */
    case MEC_WCR:               /* 0x18 */
        mec_wcr = data;
        mec_wcr = data;
        decode_wcr();
        decode_wcr();
        break;
        break;
 
 
    case MEC_ERSR:              /* 0xB0 */
    case MEC_ERSR:              /* 0xB0 */
        if (mec_tcr & 0x100000)
        if (mec_tcr & 0x100000)
            if (data & 0xFFFFEFC0) mecparerror();
            if (data & 0xFFFFEFC0) mecparerror();
            mec_ersr = data & 0x103f;
            mec_ersr = data & 0x103f;
        break;
        break;
 
 
    case MEC_TCR:               /* 0xD0 */
    case MEC_TCR:               /* 0xD0 */
        if (data & 0xFFE1FFC0) mecparerror();
        if (data & 0xFFE1FFC0) mecparerror();
        mec_tcr = data & 0x1e003f;
        mec_tcr = data & 0x1e003f;
        break;
        break;
 
 
    case MEC_WDOG:              /* 0x60 */
    case MEC_WDOG:              /* 0x60 */
        wdog_scaler = (data >> 16) & 0x0ff;
        wdog_scaler = (data >> 16) & 0x0ff;
        wdog_counter = data & 0x0ffff;
        wdog_counter = data & 0x0ffff;
        wdog_rst_delay = data >> 24;
        wdog_rst_delay = data >> 24;
        wdog_rston = 0;
        wdog_rston = 0;
        if (wdog_status == stopped)
        if (wdog_status == stopped)
            wdog_start();
            wdog_start();
        wdog_status = enabled;
        wdog_status = enabled;
        break;
        break;
 
 
    case MEC_TRAPD:             /* 0x64 */
    case MEC_TRAPD:             /* 0x64 */
        if (wdog_status == init) {
        if (wdog_status == init) {
            wdog_status = disabled;
            wdog_status = disabled;
            if (sis_verbose)
            if (sis_verbose)
                printf("Watchdog disabled\n");
                printf("Watchdog disabled\n");
        }
        }
        break;
        break;
 
 
    case MEC_PWDR:
    case MEC_PWDR:
        if (mec_mcr & 1)
        if (mec_mcr & 1)
            wait_for_irq();
            wait_for_irq();
        break;
        break;
 
 
    default:
    default:
        set_sfsr(MEC_ACC, addr, 0xb, 0);
        set_sfsr(MEC_ACC, addr, 0xb, 0);
        return (1);
        return (1);
        break;
        break;
    }
    }
    return (MOK);
    return (MOK);
}
}
 
 
 
 
/* MEC UARTS */
/* MEC UARTS */
 
 
static int      ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1;
static int      ifd1 = -1, ifd2 = -1, ofd1 = -1, ofd2 = -1;
 
 
void
void
init_stdio()
init_stdio()
{
{
    if (dumbio)
    if (dumbio)
        return; /* do nothing */
        return; /* do nothing */
    if (!ifd1)
    if (!ifd1)
        tcsetattr(0, TCSANOW, &ioc1);
        tcsetattr(0, TCSANOW, &ioc1);
    if (!ifd2)
    if (!ifd2)
        tcsetattr(0, TCSANOW, &ioc2);
        tcsetattr(0, TCSANOW, &ioc2);
}
}
 
 
void
void
restore_stdio()
restore_stdio()
{
{
    if (dumbio)
    if (dumbio)
        return; /* do nothing */
        return; /* do nothing */
    if (!ifd1)
    if (!ifd1)
        tcsetattr(0, TCSANOW, &iocold1);
        tcsetattr(0, TCSANOW, &iocold1);
    if (!ifd2)
    if (!ifd2)
        tcsetattr(0, TCSANOW, &iocold2);
        tcsetattr(0, TCSANOW, &iocold2);
}
}
 
 
#define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
#define DO_STDIO_READ( _fd_, _buf_, _len_ )          \
             ( dumbio                                \
             ( dumbio                                \
               ? (0) /* no bytes read, no delay */   \
               ? (0) /* no bytes read, no delay */   \
               : read( _fd_, _buf_, _len_ ) )
               : read( _fd_, _buf_, _len_ ) )
 
 
 
 
static void
static void
port_init()
port_init()
{
{
 
 
    if (uben) {
    if (uben) {
    f2in = stdin;
    f2in = stdin;
    f1in = NULL;
    f1in = NULL;
    f2out = stdout;
    f2out = stdout;
    f1out = NULL;
    f1out = NULL;
    } else {
    } else {
    f1in = stdin;
    f1in = stdin;
    f2in = NULL;
    f2in = NULL;
    f1out = stdout;
    f1out = stdout;
    f2out = NULL;
    f2out = NULL;
    }
    }
    if (uart_dev1[0] != 0)
    if (uart_dev1[0] != 0)
        if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) {
        if ((fd1 = open(uart_dev1, O_RDWR | O_NONBLOCK)) < 0) {
            printf("Warning, couldn't open output device %s\n", uart_dev1);
            printf("Warning, couldn't open output device %s\n", uart_dev1);
        } else {
        } else {
            if (sis_verbose)
            if (sis_verbose)
                printf("serial port A on %s\n", uart_dev1);
                printf("serial port A on %s\n", uart_dev1);
            f1in = f1out = fdopen(fd1, "r+");
            f1in = f1out = fdopen(fd1, "r+");
            setbuf(f1out, NULL);
            setbuf(f1out, NULL);
            f1open = 1;
            f1open = 1;
        }
        }
    if (f1in) ifd1 = fileno(f1in);
    if (f1in) ifd1 = fileno(f1in);
    if (ifd1 == 0) {
    if (ifd1 == 0) {
        if (sis_verbose)
        if (sis_verbose)
            printf("serial port A on stdin/stdout\n");
            printf("serial port A on stdin/stdout\n");
        if (!dumbio) {
        if (!dumbio) {
            tcgetattr(ifd1, &ioc1);
            tcgetattr(ifd1, &ioc1);
            iocold1 = ioc1;
            iocold1 = ioc1;
            ioc1.c_lflag &= ~(ICANON | ECHO);
            ioc1.c_lflag &= ~(ICANON | ECHO);
            ioc1.c_cc[VMIN] = 0;
            ioc1.c_cc[VMIN] = 0;
            ioc1.c_cc[VTIME] = 0;
            ioc1.c_cc[VTIME] = 0;
        }
        }
        f1open = 1;
        f1open = 1;
    }
    }
 
 
    if (f1out) {
    if (f1out) {
        ofd1 = fileno(f1out);
        ofd1 = fileno(f1out);
        if (!dumbio && ofd1 == 1) setbuf(f1out, NULL);
        if (!dumbio && ofd1 == 1) setbuf(f1out, NULL);
    }
    }
 
 
    if (uart_dev2[0] != 0)
    if (uart_dev2[0] != 0)
        if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) {
        if ((fd2 = open(uart_dev2, O_RDWR | O_NONBLOCK)) < 0) {
            printf("Warning, couldn't open output device %s\n", uart_dev2);
            printf("Warning, couldn't open output device %s\n", uart_dev2);
        } else {
        } else {
            if (sis_verbose)
            if (sis_verbose)
                printf("serial port B on %s\n", uart_dev2);
                printf("serial port B on %s\n", uart_dev2);
            f2in = f2out = fdopen(fd2, "r+");
            f2in = f2out = fdopen(fd2, "r+");
            setbuf(f2out, NULL);
            setbuf(f2out, NULL);
            f2open = 1;
            f2open = 1;
        }
        }
    if (f2in)  ifd2 = fileno(f2in);
    if (f2in)  ifd2 = fileno(f2in);
    if (ifd2 == 0) {
    if (ifd2 == 0) {
        if (sis_verbose)
        if (sis_verbose)
            printf("serial port B on stdin/stdout\n");
            printf("serial port B on stdin/stdout\n");
        if (!dumbio) {
        if (!dumbio) {
            tcgetattr(ifd2, &ioc2);
            tcgetattr(ifd2, &ioc2);
            iocold2 = ioc2;
            iocold2 = ioc2;
            ioc2.c_lflag &= ~(ICANON | ECHO);
            ioc2.c_lflag &= ~(ICANON | ECHO);
            ioc2.c_cc[VMIN] = 0;
            ioc2.c_cc[VMIN] = 0;
            ioc2.c_cc[VTIME] = 0;
            ioc2.c_cc[VTIME] = 0;
        }
        }
        f2open = 1;
        f2open = 1;
    }
    }
 
 
    if (f2out) {
    if (f2out) {
        ofd2 = fileno(f2out);
        ofd2 = fileno(f2out);
        if (!dumbio && ofd2 == 1) setbuf(f2out, NULL);
        if (!dumbio && ofd2 == 1) setbuf(f2out, NULL);
    }
    }
 
 
    wnuma = wnumb = 0;
    wnuma = wnumb = 0;
 
 
}
}
 
 
static uint32
static uint32
read_uart(addr)
read_uart(addr)
    uint32          addr;
    uint32          addr;
{
{
 
 
    unsigned        tmp;
    unsigned        tmp;
 
 
    tmp = 0;
    tmp = 0;
    switch (addr & 0xff) {
    switch (addr & 0xff) {
 
 
    case 0xE0:                  /* UART 1 */
    case 0xE0:                  /* UART 1 */
#ifndef _WIN32
#ifndef _WIN32
#ifdef FAST_UART
#ifdef FAST_UART
 
 
        if (aind < anum) {
        if (aind < anum) {
            if ((aind + 1) < anum)
            if ((aind + 1) < anum)
                mec_irq(4);
                mec_irq(4);
            return (0x700 | (uint32) aq[aind++]);
            return (0x700 | (uint32) aq[aind++]);
        } else {
        } else {
            if (f1open) {
            if (f1open) {
                anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
                anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
            }
            }
            if (anum > 0) {
            if (anum > 0) {
                aind = 0;
                aind = 0;
                if ((aind + 1) < anum)
                if ((aind + 1) < anum)
                    mec_irq(4);
                    mec_irq(4);
                return (0x700 | (uint32) aq[aind++]);
                return (0x700 | (uint32) aq[aind++]);
            } else {
            } else {
                return (0x600 | (uint32) aq[aind]);
                return (0x600 | (uint32) aq[aind]);
            }
            }
 
 
        }
        }
#else
#else
        tmp = uarta_data;
        tmp = uarta_data;
        uarta_data &= ~UART_DR;
        uarta_data &= ~UART_DR;
        uart_stat_reg &= ~UARTA_DR;
        uart_stat_reg &= ~UARTA_DR;
        return tmp;
        return tmp;
#endif
#endif
#else
#else
        return(0);
        return(0);
#endif
#endif
        break;
        break;
 
 
    case 0xE4:                  /* UART 2 */
    case 0xE4:                  /* UART 2 */
#ifndef _WIN32
#ifndef _WIN32
#ifdef FAST_UART
#ifdef FAST_UART
        if (bind < bnum) {
        if (bind < bnum) {
            if ((bind + 1) < bnum)
            if ((bind + 1) < bnum)
                mec_irq(5);
                mec_irq(5);
            return (0x700 | (uint32) bq[bind++]);
            return (0x700 | (uint32) bq[bind++]);
        } else {
        } else {
            if (f2open) {
            if (f2open) {
                bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
                bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
            }
            }
            if (bnum > 0) {
            if (bnum > 0) {
                bind = 0;
                bind = 0;
                if ((bind + 1) < bnum)
                if ((bind + 1) < bnum)
                    mec_irq(5);
                    mec_irq(5);
                return (0x700 | (uint32) bq[bind++]);
                return (0x700 | (uint32) bq[bind++]);
            } else {
            } else {
                return (0x600 | (uint32) bq[bind]);
                return (0x600 | (uint32) bq[bind]);
            }
            }
 
 
        }
        }
#else
#else
        tmp = uartb_data;
        tmp = uartb_data;
        uartb_data &= ~UART_DR;
        uartb_data &= ~UART_DR;
        uart_stat_reg &= ~UARTB_DR;
        uart_stat_reg &= ~UARTB_DR;
        return tmp;
        return tmp;
#endif
#endif
#else
#else
        return(0);
        return(0);
#endif
#endif
        break;
        break;
 
 
    case 0xE8:                  /* UART status register  */
    case 0xE8:                  /* UART status register  */
#ifndef _WIN32
#ifndef _WIN32
#ifdef FAST_UART
#ifdef FAST_UART
 
 
        Ucontrol = 0;
        Ucontrol = 0;
        if (aind < anum) {
        if (aind < anum) {
            Ucontrol |= 0x00000001;
            Ucontrol |= 0x00000001;
        } else {
        } else {
            if (f1open) {
            if (f1open) {
                anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
                anum = DO_STDIO_READ(ifd1, aq, UARTBUF);
            }
            }
            if (anum > 0) {
            if (anum > 0) {
                Ucontrol |= 0x00000001;
                Ucontrol |= 0x00000001;
                aind = 0;
                aind = 0;
                mec_irq(4);
                mec_irq(4);
            }
            }
        }
        }
        if (bind < bnum) {
        if (bind < bnum) {
            Ucontrol |= 0x00010000;
            Ucontrol |= 0x00010000;
        } else {
        } else {
            if (f2open) {
            if (f2open) {
                bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
                bnum = DO_STDIO_READ(ifd2, bq, UARTBUF);
            }
            }
            if (bnum > 0) {
            if (bnum > 0) {
                Ucontrol |= 0x00010000;
                Ucontrol |= 0x00010000;
                bind = 0;
                bind = 0;
                mec_irq(5);
                mec_irq(5);
            }
            }
        }
        }
 
 
        Ucontrol |= 0x00060006;
        Ucontrol |= 0x00060006;
        return (Ucontrol);
        return (Ucontrol);
#else
#else
        return (uart_stat_reg);
        return (uart_stat_reg);
#endif
#endif
#else
#else
        return(0x00060006);
        return(0x00060006);
#endif
#endif
        break;
        break;
    default:
    default:
        if (sis_verbose)
        if (sis_verbose)
            printf("Read from unimplemented MEC register (%x)\n", addr);
            printf("Read from unimplemented MEC register (%x)\n", addr);
 
 
    }
    }
    return (0);
    return (0);
}
}
 
 
static void
static void
write_uart(addr, data)
write_uart(addr, data)
    uint32          addr;
    uint32          addr;
    uint32          data;
    uint32          data;
{
{
    unsigned char   c;
    unsigned char   c;
 
 
    c = (unsigned char) data;
    c = (unsigned char) data;
    switch (addr & 0xff) {
    switch (addr & 0xff) {
 
 
    case 0xE0:                  /* UART A */
    case 0xE0:                  /* UART A */
#ifdef FAST_UART
#ifdef FAST_UART
        if (f1open) {
        if (f1open) {
            if (wnuma < UARTBUF)
            if (wnuma < UARTBUF)
                wbufa[wnuma++] = c;
                wbufa[wnuma++] = c;
            else {
            else {
                while (wnuma)
                while (wnuma)
                    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
                    wnuma -= fwrite(wbufa, 1, wnuma, f1out);
                wbufa[wnuma++] = c;
                wbufa[wnuma++] = c;
            }
            }
        }
        }
        mec_irq(4);
        mec_irq(4);
#else
#else
        if (uart_stat_reg & UARTA_SRE) {
        if (uart_stat_reg & UARTA_SRE) {
            uarta_sreg = c;
            uarta_sreg = c;
            uart_stat_reg &= ~UARTA_SRE;
            uart_stat_reg &= ~UARTA_SRE;
            event(uarta_tx, 0, UART_TX_TIME);
            event(uarta_tx, 0, UART_TX_TIME);
        } else {
        } else {
            uarta_hreg = c;
            uarta_hreg = c;
            uart_stat_reg &= ~UARTA_HRE;
            uart_stat_reg &= ~UARTA_HRE;
        }
        }
#endif
#endif
        break;
        break;
 
 
    case 0xE4:                  /* UART B */
    case 0xE4:                  /* UART B */
#ifdef FAST_UART
#ifdef FAST_UART
        if (f2open) {
        if (f2open) {
            if (wnumb < UARTBUF)
            if (wnumb < UARTBUF)
                wbufb[wnumb++] = c;
                wbufb[wnumb++] = c;
            else {
            else {
                while (wnumb)
                while (wnumb)
                    wnumb -= fwrite(wbufb, 1, wnumb, f2out);
                    wnumb -= fwrite(wbufb, 1, wnumb, f2out);
                wbufb[wnumb++] = c;
                wbufb[wnumb++] = c;
            }
            }
        }
        }
        mec_irq(5);
        mec_irq(5);
#else
#else
        if (uart_stat_reg & UARTB_SRE) {
        if (uart_stat_reg & UARTB_SRE) {
            uartb_sreg = c;
            uartb_sreg = c;
            uart_stat_reg &= ~UARTB_SRE;
            uart_stat_reg &= ~UARTB_SRE;
            event(uartb_tx, 0, UART_TX_TIME);
            event(uartb_tx, 0, UART_TX_TIME);
        } else {
        } else {
            uartb_hreg = c;
            uartb_hreg = c;
            uart_stat_reg &= ~UARTB_HRE;
            uart_stat_reg &= ~UARTB_HRE;
        }
        }
#endif
#endif
        break;
        break;
    case 0xE8:                  /* UART status register */
    case 0xE8:                  /* UART status register */
#ifndef FAST_UART
#ifndef FAST_UART
        if (data & UARTA_CLR) {
        if (data & UARTA_CLR) {
            uart_stat_reg &= 0xFFFF0000;
            uart_stat_reg &= 0xFFFF0000;
            uart_stat_reg |= UARTA_SRE | UARTA_HRE;
            uart_stat_reg |= UARTA_SRE | UARTA_HRE;
        }
        }
        if (data & UARTB_CLR) {
        if (data & UARTB_CLR) {
            uart_stat_reg &= 0x0000FFFF;
            uart_stat_reg &= 0x0000FFFF;
            uart_stat_reg |= UARTB_SRE | UARTB_HRE;
            uart_stat_reg |= UARTB_SRE | UARTB_HRE;
        }
        }
#endif
#endif
        break;
        break;
    default:
    default:
        if (sis_verbose)
        if (sis_verbose)
            printf("Write to unimplemented MEC register (%x)\n", addr);
            printf("Write to unimplemented MEC register (%x)\n", addr);
 
 
    }
    }
}
}
 
 
static void
static void
flush_uart()
flush_uart()
{
{
    while (wnuma && f1open)
    while (wnuma && f1open)
        wnuma -= fwrite(wbufa, 1, wnuma, f1out);
        wnuma -= fwrite(wbufa, 1, wnuma, f1out);
    while (wnumb && f2open)
    while (wnumb && f2open)
        wnumb -= fwrite(wbufb, 1, wnumb, f2out);
        wnumb -= fwrite(wbufb, 1, wnumb, f2out);
}
}
 
 
 
 
 
 
static void
static void
uarta_tx()
uarta_tx()
{
{
 
 
    while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1);
    while (f1open && fwrite(&uarta_sreg, 1, 1, f1out) != 1);
    if (uart_stat_reg & UARTA_HRE) {
    if (uart_stat_reg & UARTA_HRE) {
        uart_stat_reg |= UARTA_SRE;
        uart_stat_reg |= UARTA_SRE;
    } else {
    } else {
        uarta_sreg = uarta_hreg;
        uarta_sreg = uarta_hreg;
        uart_stat_reg |= UARTA_HRE;
        uart_stat_reg |= UARTA_HRE;
        event(uarta_tx, 0, UART_TX_TIME);
        event(uarta_tx, 0, UART_TX_TIME);
    }
    }
    mec_irq(4);
    mec_irq(4);
}
}
 
 
static void
static void
uartb_tx()
uartb_tx()
{
{
    while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1);
    while (f2open && fwrite(&uartb_sreg, 1, 1, f2out) != 1);
    if (uart_stat_reg & UARTB_HRE) {
    if (uart_stat_reg & UARTB_HRE) {
        uart_stat_reg |= UARTB_SRE;
        uart_stat_reg |= UARTB_SRE;
    } else {
    } else {
        uartb_sreg = uartb_hreg;
        uartb_sreg = uartb_hreg;
        uart_stat_reg |= UARTB_HRE;
        uart_stat_reg |= UARTB_HRE;
        event(uartb_tx, 0, UART_TX_TIME);
        event(uartb_tx, 0, UART_TX_TIME);
    }
    }
    mec_irq(5);
    mec_irq(5);
}
}
 
 
static void
static void
uart_rx(arg)
uart_rx(arg)
    caddr_t         arg;
    caddr_t         arg;
{
{
    int32           rsize;
    int32           rsize;
    char            rxd;
    char            rxd;
 
 
 
 
    rsize = 0;
    rsize = 0;
    if (f1open)
    if (f1open)
        rsize = DO_STDIO_READ(ifd1, &rxd, 1);
        rsize = DO_STDIO_READ(ifd1, &rxd, 1);
    if (rsize > 0) {
    if (rsize > 0) {
        uarta_data = UART_DR | rxd;
        uarta_data = UART_DR | rxd;
        if (uart_stat_reg & UARTA_HRE)
        if (uart_stat_reg & UARTA_HRE)
            uarta_data |= UART_THE;
            uarta_data |= UART_THE;
        if (uart_stat_reg & UARTA_SRE)
        if (uart_stat_reg & UARTA_SRE)
            uarta_data |= UART_TSE;
            uarta_data |= UART_TSE;
        if (uart_stat_reg & UARTA_DR) {
        if (uart_stat_reg & UARTA_DR) {
            uart_stat_reg |= UARTA_OR;
            uart_stat_reg |= UARTA_OR;
            mec_irq(7);         /* UART error interrupt */
            mec_irq(7);         /* UART error interrupt */
        }
        }
        uart_stat_reg |= UARTA_DR;
        uart_stat_reg |= UARTA_DR;
        mec_irq(4);
        mec_irq(4);
    }
    }
    rsize = 0;
    rsize = 0;
    if (f2open)
    if (f2open)
        rsize = DO_STDIO_READ(ifd2, &rxd, 1);
        rsize = DO_STDIO_READ(ifd2, &rxd, 1);
    if (rsize) {
    if (rsize) {
        uartb_data = UART_DR | rxd;
        uartb_data = UART_DR | rxd;
        if (uart_stat_reg & UARTB_HRE)
        if (uart_stat_reg & UARTB_HRE)
            uartb_data |= UART_THE;
            uartb_data |= UART_THE;
        if (uart_stat_reg & UARTB_SRE)
        if (uart_stat_reg & UARTB_SRE)
            uartb_data |= UART_TSE;
            uartb_data |= UART_TSE;
        if (uart_stat_reg & UARTB_DR) {
        if (uart_stat_reg & UARTB_DR) {
            uart_stat_reg |= UARTB_OR;
            uart_stat_reg |= UARTB_OR;
            mec_irq(7);         /* UART error interrupt */
            mec_irq(7);         /* UART error interrupt */
        }
        }
        uart_stat_reg |= UARTB_DR;
        uart_stat_reg |= UARTB_DR;
        mec_irq(5);
        mec_irq(5);
    }
    }
    event(uart_rx, 0, UART_RX_TIME);
    event(uart_rx, 0, UART_RX_TIME);
}
}
 
 
static void
static void
uart_intr(arg)
uart_intr(arg)
    caddr_t         arg;
    caddr_t         arg;
{
{
    read_uart(0xE8);            /* Check for UART interrupts every 1000 clk */
    read_uart(0xE8);            /* Check for UART interrupts every 1000 clk */
    flush_uart();               /* Flush UART ports      */
    flush_uart();               /* Flush UART ports      */
    event(uart_intr, 0, UART_FLUSH_TIME);
    event(uart_intr, 0, UART_FLUSH_TIME);
}
}
 
 
 
 
static void
static void
uart_irq_start()
uart_irq_start()
{
{
#ifdef FAST_UART
#ifdef FAST_UART
    event(uart_intr, 0, UART_FLUSH_TIME);
    event(uart_intr, 0, UART_FLUSH_TIME);
#else
#else
#ifndef _WIN32
#ifndef _WIN32
    event(uart_rx, 0, UART_RX_TIME);
    event(uart_rx, 0, UART_RX_TIME);
#endif
#endif
#endif
#endif
}
}
 
 
/* Watch-dog */
/* Watch-dog */
 
 
static void
static void
wdog_intr(arg)
wdog_intr(arg)
    caddr_t         arg;
    caddr_t         arg;
{
{
    if (wdog_status == disabled) {
    if (wdog_status == disabled) {
        wdog_status = stopped;
        wdog_status = stopped;
    } else {
    } else {
 
 
        if (wdog_counter) {
        if (wdog_counter) {
            wdog_counter--;
            wdog_counter--;
            event(wdog_intr, 0, wdog_scaler + 1);
            event(wdog_intr, 0, wdog_scaler + 1);
        } else {
        } else {
            if (wdog_rston) {
            if (wdog_rston) {
                printf("Watchdog reset!\n");
                printf("Watchdog reset!\n");
                sys_reset();
                sys_reset();
                mec_ersr = 0xC000;
                mec_ersr = 0xC000;
            } else {
            } else {
                mec_irq(15);
                mec_irq(15);
                wdog_rston = 1;
                wdog_rston = 1;
                wdog_counter = wdog_rst_delay;
                wdog_counter = wdog_rst_delay;
                event(wdog_intr, 0, wdog_scaler + 1);
                event(wdog_intr, 0, wdog_scaler + 1);
            }
            }
        }
        }
    }
    }
}
}
 
 
static void
static void
wdog_start()
wdog_start()
{
{
    event(wdog_intr, 0, wdog_scaler + 1);
    event(wdog_intr, 0, wdog_scaler + 1);
    if (sis_verbose)
    if (sis_verbose)
        printf("Watchdog started, scaler = %d, counter = %d\n",
        printf("Watchdog started, scaler = %d, counter = %d\n",
               wdog_scaler, wdog_counter);
               wdog_scaler, wdog_counter);
}
}
 
 
 
 
/* MEC timers */
/* MEC timers */
 
 
 
 
static void
static void
rtc_intr(arg)
rtc_intr(arg)
    caddr_t         arg;
    caddr_t         arg;
{
{
    if (rtc_counter == 0) {
    if (rtc_counter == 0) {
 
 
        mec_irq(13);
        mec_irq(13);
        if (rtc_cr)
        if (rtc_cr)
            rtc_counter = rtc_reload;
            rtc_counter = rtc_reload;
        else
        else
            rtc_se = 0;
            rtc_se = 0;
    } else
    } else
        rtc_counter -= 1;
        rtc_counter -= 1;
    if (rtc_se) {
    if (rtc_se) {
        event(rtc_intr, 0, rtc_scaler + 1);
        event(rtc_intr, 0, rtc_scaler + 1);
        rtc_scaler_start = now();
        rtc_scaler_start = now();
        rtc_enabled = 1;
        rtc_enabled = 1;
    } else {
    } else {
        if (sis_verbose)
        if (sis_verbose)
            printf("RTC stopped\n\r");
            printf("RTC stopped\n\r");
        rtc_enabled = 0;
        rtc_enabled = 0;
    }
    }
}
}
 
 
static void
static void
rtc_start()
rtc_start()
{
{
    if (sis_verbose)
    if (sis_verbose)
        printf("RTC started (period %d)\n\r", rtc_scaler + 1);
        printf("RTC started (period %d)\n\r", rtc_scaler + 1);
    event(rtc_intr, 0, rtc_scaler + 1);
    event(rtc_intr, 0, rtc_scaler + 1);
    rtc_scaler_start = now();
    rtc_scaler_start = now();
    rtc_enabled = 1;
    rtc_enabled = 1;
}
}
 
 
static uint32
static uint32
rtc_counter_read()
rtc_counter_read()
{
{
    return (rtc_counter);
    return (rtc_counter);
}
}
 
 
static void
static void
rtc_scaler_set(val)
rtc_scaler_set(val)
    uint32          val;
    uint32          val;
{
{
    rtc_scaler = val & 0x0ff;   /* eight-bit scaler only */
    rtc_scaler = val & 0x0ff;   /* eight-bit scaler only */
}
}
 
 
static void
static void
rtc_reload_set(val)
rtc_reload_set(val)
    uint32          val;
    uint32          val;
{
{
    rtc_reload = val;
    rtc_reload = val;
}
}
 
 
static void
static void
gpt_intr(arg)
gpt_intr(arg)
    caddr_t         arg;
    caddr_t         arg;
{
{
    if (gpt_counter == 0) {
    if (gpt_counter == 0) {
        mec_irq(12);
        mec_irq(12);
        if (gpt_cr)
        if (gpt_cr)
            gpt_counter = gpt_reload;
            gpt_counter = gpt_reload;
        else
        else
            gpt_se = 0;
            gpt_se = 0;
    } else
    } else
        gpt_counter -= 1;
        gpt_counter -= 1;
    if (gpt_se) {
    if (gpt_se) {
        event(gpt_intr, 0, gpt_scaler + 1);
        event(gpt_intr, 0, gpt_scaler + 1);
        gpt_scaler_start = now();
        gpt_scaler_start = now();
        gpt_enabled = 1;
        gpt_enabled = 1;
    } else {
    } else {
        if (sis_verbose)
        if (sis_verbose)
            printf("GPT stopped\n\r");
            printf("GPT stopped\n\r");
        gpt_enabled = 0;
        gpt_enabled = 0;
    }
    }
}
}
 
 
static void
static void
gpt_start()
gpt_start()
{
{
    if (sis_verbose)
    if (sis_verbose)
        printf("GPT started (period %d)\n\r", gpt_scaler + 1);
        printf("GPT started (period %d)\n\r", gpt_scaler + 1);
    event(gpt_intr, 0, gpt_scaler + 1);
    event(gpt_intr, 0, gpt_scaler + 1);
    gpt_scaler_start = now();
    gpt_scaler_start = now();
    gpt_enabled = 1;
    gpt_enabled = 1;
}
}
 
 
static uint32
static uint32
gpt_counter_read()
gpt_counter_read()
{
{
    return (gpt_counter);
    return (gpt_counter);
}
}
 
 
static void
static void
gpt_scaler_set(val)
gpt_scaler_set(val)
    uint32          val;
    uint32          val;
{
{
    gpt_scaler = val & 0x0ffff; /* 16-bit scaler */
    gpt_scaler = val & 0x0ffff; /* 16-bit scaler */
}
}
 
 
static void
static void
gpt_reload_set(val)
gpt_reload_set(val)
    uint32          val;
    uint32          val;
{
{
    gpt_reload = val;
    gpt_reload = val;
}
}
 
 
static void
static void
timer_ctrl(val)
timer_ctrl(val)
    uint32          val;
    uint32          val;
{
{
 
 
    rtc_cr = ((val & TCR_TCRCR) != 0);
    rtc_cr = ((val & TCR_TCRCR) != 0);
    if (val & TCR_TCRCL) {
    if (val & TCR_TCRCL) {
        rtc_counter = rtc_reload;
        rtc_counter = rtc_reload;
    }
    }
    if (val & TCR_TCRSL) {
    if (val & TCR_TCRSL) {
    }
    }
    rtc_se = ((val & TCR_TCRSE) != 0);
    rtc_se = ((val & TCR_TCRSE) != 0);
    if (rtc_se && (rtc_enabled == 0))
    if (rtc_se && (rtc_enabled == 0))
        rtc_start();
        rtc_start();
 
 
    gpt_cr = (val & TCR_GACR);
    gpt_cr = (val & TCR_GACR);
    if (val & TCR_GACL) {
    if (val & TCR_GACL) {
        gpt_counter = gpt_reload;
        gpt_counter = gpt_reload;
    }
    }
    if (val & TCR_GACL) {
    if (val & TCR_GACL) {
    }
    }
    gpt_se = (val & TCR_GASE) >> 2;
    gpt_se = (val & TCR_GASE) >> 2;
    if (gpt_se && (gpt_enabled == 0))
    if (gpt_se && (gpt_enabled == 0))
        gpt_start();
        gpt_start();
}
}
 
 
 
 
/* Retrieve data from target memory.  MEM points to location from which
/* Retrieve data from target memory.  MEM points to location from which
   to read the data; DATA points to words where retrieved data will be
   to read the data; DATA points to words where retrieved data will be
   stored in host byte order.  SZ contains log(2) of the number of bytes
   stored in host byte order.  SZ contains log(2) of the number of bytes
   to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word),
   to retrieve, and can be 0 (1 byte), 1 (one half-word), 2 (one word),
   or 3 (two words). */
   or 3 (two words). */
 
 
static void
static void
fetch_bytes (asi, mem, data, sz)
fetch_bytes (asi, mem, data, sz)
    int             asi;
    int             asi;
    unsigned char  *mem;
    unsigned char  *mem;
    uint32         *data;
    uint32         *data;
    int             sz;
    int             sz;
{
{
    if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
    if (CURRENT_TARGET_BYTE_ORDER == BIG_ENDIAN
        || asi == 8 || asi == 9) {
        || asi == 8 || asi == 9) {
        switch (sz) {
        switch (sz) {
        case 3:
        case 3:
            data[1] =  (((uint32) mem[7]) & 0xff) |
            data[1] =  (((uint32) mem[7]) & 0xff) |
                      ((((uint32) mem[6]) & 0xff) <<  8) |
                      ((((uint32) mem[6]) & 0xff) <<  8) |
                      ((((uint32) mem[5]) & 0xff) << 16) |
                      ((((uint32) mem[5]) & 0xff) << 16) |
                      ((((uint32) mem[4]) & 0xff) << 24);
                      ((((uint32) mem[4]) & 0xff) << 24);
            /* Fall through to 2 */
            /* Fall through to 2 */
        case 2:
        case 2:
            data[0] =  (((uint32) mem[3]) & 0xff) |
            data[0] =  (((uint32) mem[3]) & 0xff) |
                      ((((uint32) mem[2]) & 0xff) <<  8) |
                      ((((uint32) mem[2]) & 0xff) <<  8) |
                      ((((uint32) mem[1]) & 0xff) << 16) |
                      ((((uint32) mem[1]) & 0xff) << 16) |
                      ((((uint32) mem[0]) & 0xff) << 24);
                      ((((uint32) mem[0]) & 0xff) << 24);
            break;
            break;
        case 1:
        case 1:
            data[0] =  (((uint32) mem[1]) & 0xff) |
            data[0] =  (((uint32) mem[1]) & 0xff) |
                      ((((uint32) mem[0]) & 0xff) << 8);
                      ((((uint32) mem[0]) & 0xff) << 8);
            break;
            break;
        case 0:
        case 0:
            data[0] = mem[0] & 0xff;
            data[0] = mem[0] & 0xff;
            break;
            break;
 
 
        }
        }
    } else {
    } else {
        switch (sz) {
        switch (sz) {
        case 3:
        case 3:
            data[1] = ((((uint32) mem[7]) & 0xff) << 24) |
            data[1] = ((((uint32) mem[7]) & 0xff) << 24) |
                      ((((uint32) mem[6]) & 0xff) << 16) |
                      ((((uint32) mem[6]) & 0xff) << 16) |
                      ((((uint32) mem[5]) & 0xff) <<  8) |
                      ((((uint32) mem[5]) & 0xff) <<  8) |
                       (((uint32) mem[4]) & 0xff);
                       (((uint32) mem[4]) & 0xff);
            /* Fall through to 4 */
            /* Fall through to 4 */
        case 2:
        case 2:
            data[0] = ((((uint32) mem[3]) & 0xff) << 24) |
            data[0] = ((((uint32) mem[3]) & 0xff) << 24) |
                      ((((uint32) mem[2]) & 0xff) << 16) |
                      ((((uint32) mem[2]) & 0xff) << 16) |
                      ((((uint32) mem[1]) & 0xff) <<  8) |
                      ((((uint32) mem[1]) & 0xff) <<  8) |
                       (((uint32) mem[0]) & 0xff);
                       (((uint32) mem[0]) & 0xff);
            break;
            break;
        case 1:
        case 1:
            data[0] = ((((uint32) mem[1]) & 0xff) <<  8) |
            data[0] = ((((uint32) mem[1]) & 0xff) <<  8) |
                       (((uint32) mem[0]) & 0xff);
                       (((uint32) mem[0]) & 0xff);
            break;
            break;
        case 0:
        case 0:
            data[0] = mem[0] & 0xff;
            data[0] = mem[0] & 0xff;
            break;
            break;
        }
        }
    }
    }
}
}
 
 
 
 
/* Store data in target byte order.  MEM points to location to store data;
/* Store data in target byte order.  MEM points to location to store data;
   DATA points to words in host byte order to be stored.  SZ contains log(2)
   DATA points to words in host byte order to be stored.  SZ contains log(2)
   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
   of the number of bytes to retrieve, and can be 0 (1 byte), 1 (one half-word),
   2 (one word), or 3 (two words). */
   2 (one word), or 3 (two words). */
 
 
static void
static void
store_bytes (mem, data, sz)
store_bytes (mem, data, sz)
    unsigned char  *mem;
    unsigned char  *mem;
    uint32         *data;
    uint32         *data;
    int             sz;
    int             sz;
{
{
    if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) {
    if (CURRENT_TARGET_BYTE_ORDER == LITTLE_ENDIAN) {
        switch (sz) {
        switch (sz) {
        case 3:
        case 3:
            mem[7] = (data[1] >> 24) & 0xff;
            mem[7] = (data[1] >> 24) & 0xff;
            mem[6] = (data[1] >> 16) & 0xff;
            mem[6] = (data[1] >> 16) & 0xff;
            mem[5] = (data[1] >>  8) & 0xff;
            mem[5] = (data[1] >>  8) & 0xff;
            mem[4] = data[1] & 0xff;
            mem[4] = data[1] & 0xff;
            /* Fall through to 2 */
            /* Fall through to 2 */
        case 2:
        case 2:
            mem[3] = (data[0] >> 24) & 0xff;
            mem[3] = (data[0] >> 24) & 0xff;
            mem[2] = (data[0] >> 16) & 0xff;
            mem[2] = (data[0] >> 16) & 0xff;
            /* Fall through to 1 */
            /* Fall through to 1 */
        case 1:
        case 1:
            mem[1] = (data[0] >>  8) & 0xff;
            mem[1] = (data[0] >>  8) & 0xff;
            /* Fall through to 0 */
            /* Fall through to 0 */
        case 0:
        case 0:
            mem[0] = data[0] & 0xff;
            mem[0] = data[0] & 0xff;
            break;
            break;
        }
        }
    } else {
    } else {
        switch (sz) {
        switch (sz) {
        case 3:
        case 3:
            mem[7] = data[1] & 0xff;
            mem[7] = data[1] & 0xff;
            mem[6] = (data[1] >>  8) & 0xff;
            mem[6] = (data[1] >>  8) & 0xff;
            mem[5] = (data[1] >> 16) & 0xff;
            mem[5] = (data[1] >> 16) & 0xff;
            mem[4] = (data[1] >> 24) & 0xff;
            mem[4] = (data[1] >> 24) & 0xff;
            /* Fall through to 2 */
            /* Fall through to 2 */
        case 2:
        case 2:
            mem[3] = data[0] & 0xff;
            mem[3] = data[0] & 0xff;
            mem[2] = (data[0] >>  8) & 0xff;
            mem[2] = (data[0] >>  8) & 0xff;
            mem[1] = (data[0] >> 16) & 0xff;
            mem[1] = (data[0] >> 16) & 0xff;
            mem[0] = (data[0] >> 24) & 0xff;
            mem[0] = (data[0] >> 24) & 0xff;
            break;
            break;
        case 1:
        case 1:
            mem[1] = data[0] & 0xff;
            mem[1] = data[0] & 0xff;
            mem[0] = (data[0] >> 8) & 0xff;
            mem[0] = (data[0] >> 8) & 0xff;
            break;
            break;
        case 0:
        case 0:
            mem[0] = data[0] & 0xff;
            mem[0] = data[0] & 0xff;
            break;
            break;
 
 
        }
        }
    }
    }
}
}
 
 
 
 
/* Memory emulation */
/* Memory emulation */
 
 
int
int
memory_read(asi, addr, data, sz, ws)
memory_read(asi, addr, data, sz, ws)
    int32           asi;
    int32           asi;
    uint32          addr;
    uint32          addr;
    uint32         *data;
    uint32         *data;
    int32           sz;
    int32           sz;
    int32          *ws;
    int32          *ws;
{
{
    int32           mexc;
    int32           mexc;
 
 
#ifdef ERRINJ
#ifdef ERRINJ
    if (errmec) {
    if (errmec) {
        if (sis_verbose)
        if (sis_verbose)
            printf("Inserted MEC error %d\n",errmec);
            printf("Inserted MEC error %d\n",errmec);
        set_sfsr(errmec, addr, asi, 1);
        set_sfsr(errmec, addr, asi, 1);
        if (errmec == 5) mecparerror();
        if (errmec == 5) mecparerror();
        if (errmec == 6) iucomperr();
        if (errmec == 6) iucomperr();
        errmec = 0;
        errmec = 0;
        return(1);
        return(1);
    }
    }
#endif;
#endif;
 
 
    if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
    if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
        fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz);
        fetch_bytes (asi, &ramb[addr & mem_rammask], data, sz);
        *ws = mem_ramr_ws;
        *ws = mem_ramr_ws;
        return (0);
        return (0);
    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
        mexc = mec_read(addr, asi, data);
        mexc = mec_read(addr, asi, data);
        if (mexc) {
        if (mexc) {
            set_sfsr(MEC_ACC, addr, asi, 1);
            set_sfsr(MEC_ACC, addr, asi, 1);
            *ws = MEM_EX_WS;
            *ws = MEM_EX_WS;
        } else {
        } else {
            *ws = 0;
            *ws = 0;
        }
        }
        return (mexc);
        return (mexc);
 
 
#ifdef ERA
#ifdef ERA
 
 
    } else if (era) {
    } else if (era) {
        if ((addr < 0x100000) ||
        if ((addr < 0x100000) ||
            ((addr>= 0x80000000) && (addr < 0x80100000))) {
            ((addr>= 0x80000000) && (addr < 0x80100000))) {
            fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz);
            fetch_bytes (asi, &romb[addr & ROM_MASK], data, sz);
            *ws = 4;
            *ws = 4;
            return (0);
            return (0);
        } else if ((addr >= 0x10000000) &&
        } else if ((addr >= 0x10000000) &&
                   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
                   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
                   (mec_iocr & 0x10))  {
                   (mec_iocr & 0x10))  {
            *data = erareg;
            *data = erareg;
            return (0);
            return (0);
        }
        }
 
 
    } else  if (addr < mem_romsz) {
    } else  if (addr < mem_romsz) {
            fetch_bytes (asi, &romb[addr], data, sz);
            fetch_bytes (asi, &romb[addr], data, sz);
            *ws = mem_romr_ws;
            *ws = mem_romr_ws;
            return (0);
            return (0);
 
 
#else
#else
    } else if (addr < mem_romsz) {
    } else if (addr < mem_romsz) {
        fetch_bytes (asi, &romb[addr], data, sz);
        fetch_bytes (asi, &romb[addr], data, sz);
        *ws = mem_romr_ws;
        *ws = mem_romr_ws;
        return (0);
        return (0);
#endif
#endif
 
 
    }
    }
 
 
    printf("Memory exception at %x (illegal address)\n", addr);
    printf("Memory exception at %x (illegal address)\n", addr);
    set_sfsr(UIMP_ACC, addr, asi, 1);
    set_sfsr(UIMP_ACC, addr, asi, 1);
    *ws = MEM_EX_WS;
    *ws = MEM_EX_WS;
    return (1);
    return (1);
}
}
 
 
int
int
memory_write(asi, addr, data, sz, ws)
memory_write(asi, addr, data, sz, ws)
    int32           asi;
    int32           asi;
    uint32          addr;
    uint32          addr;
    uint32         *data;
    uint32         *data;
    int32           sz;
    int32           sz;
    int32          *ws;
    int32          *ws;
{
{
    uint32          byte_addr;
    uint32          byte_addr;
    uint32          byte_mask;
    uint32          byte_mask;
    uint32          waddr;
    uint32          waddr;
    uint32         *ram;
    uint32         *ram;
    int32           mexc;
    int32           mexc;
    int             i;
    int             i;
    int             wphit[2];
    int             wphit[2];
 
 
#ifdef ERRINJ
#ifdef ERRINJ
    if (errmec) {
    if (errmec) {
        if (sis_verbose)
        if (sis_verbose)
            printf("Inserted MEC error %d\n",errmec);
            printf("Inserted MEC error %d\n",errmec);
        set_sfsr(errmec, addr, asi, 0);
        set_sfsr(errmec, addr, asi, 0);
        if (errmec == 5) mecparerror();
        if (errmec == 5) mecparerror();
        if (errmec == 6) iucomperr();
        if (errmec == 6) iucomperr();
        errmec = 0;
        errmec = 0;
        return(1);
        return(1);
    }
    }
#endif;
#endif;
 
 
    if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
    if ((addr >= mem_ramstart) && (addr < (mem_ramstart + mem_ramsz))) {
        if (mem_accprot) {
        if (mem_accprot) {
 
 
            waddr = (addr & 0x7fffff) >> 2;
            waddr = (addr & 0x7fffff) >> 2;
            for (i = 0; i < 2; i++)
            for (i = 0; i < 2; i++)
                wphit[i] =
                wphit[i] =
                    (((asi == 0xa) && (mec_wpr[i] & 1)) ||
                    (((asi == 0xa) && (mec_wpr[i] & 1)) ||
                     ((asi == 0xb) && (mec_wpr[i] & 2))) &&
                     ((asi == 0xb) && (mec_wpr[i] & 2))) &&
                    ((waddr >= mec_ssa[i]) && ((waddr | (sz == 3)) < mec_sea[i]));
                    ((waddr >= mec_ssa[i]) && ((waddr | (sz == 3)) < mec_sea[i]));
 
 
            if (((mem_blockprot) && (wphit[0] || wphit[1])) ||
            if (((mem_blockprot) && (wphit[0] || wphit[1])) ||
                ((!mem_blockprot) &&
                ((!mem_blockprot) &&
                 !((mec_wpr[0] && wphit[0]) || (mec_wpr[1] && wphit[1]))
                 !((mec_wpr[0] && wphit[0]) || (mec_wpr[1] && wphit[1]))
                 )) {
                 )) {
                if (sis_verbose)
                if (sis_verbose)
                    printf("Memory access protection error at 0x%08x\n", addr);
                    printf("Memory access protection error at 0x%08x\n", addr);
                set_sfsr(PROT_EXC, addr, asi, 0);
                set_sfsr(PROT_EXC, addr, asi, 0);
                *ws = MEM_EX_WS;
                *ws = MEM_EX_WS;
                return (1);
                return (1);
            }
            }
        }
        }
 
 
        store_bytes (&ramb[addr & mem_rammask], data, sz);
        store_bytes (&ramb[addr & mem_rammask], data, sz);
 
 
        switch (sz) {
        switch (sz) {
        case 0:
        case 0:
        case 1:
        case 1:
            *ws = mem_ramw_ws + 3;
            *ws = mem_ramw_ws + 3;
            break;
            break;
        case 2:
        case 2:
            *ws = mem_ramw_ws;
            *ws = mem_ramw_ws;
            break;
            break;
        case 3:
        case 3:
            *ws = 2 * mem_ramw_ws + STD_WS;
            *ws = 2 * mem_ramw_ws + STD_WS;
            break;
            break;
        }
        }
        return (0);
        return (0);
    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
    } else if ((addr >= MEC_START) && (addr < MEC_END)) {
        if ((sz != 2) || (asi != 0xb)) {
        if ((sz != 2) || (asi != 0xb)) {
            set_sfsr(MEC_ACC, addr, asi, 0);
            set_sfsr(MEC_ACC, addr, asi, 0);
            *ws = MEM_EX_WS;
            *ws = MEM_EX_WS;
            return (1);
            return (1);
        }
        }
        mexc = mec_write(addr, *data);
        mexc = mec_write(addr, *data);
        if (mexc) {
        if (mexc) {
            set_sfsr(MEC_ACC, addr, asi, 0);
            set_sfsr(MEC_ACC, addr, asi, 0);
            *ws = MEM_EX_WS;
            *ws = MEM_EX_WS;
        } else {
        } else {
            *ws = 0;
            *ws = 0;
        }
        }
        return (mexc);
        return (mexc);
 
 
#ifdef ERA
#ifdef ERA
 
 
    } else if (era) {
    } else if (era) {
        if ((erareg & 2) &&
        if ((erareg & 2) &&
        ((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) {
        ((addr < 0x100000) || ((addr >= 0x80000000) && (addr < 0x80100000)))) {
            addr &= ROM_MASK;
            addr &= ROM_MASK;
            *ws = sz == 3 ? 8 : 4;
            *ws = sz == 3 ? 8 : 4;
            store_bytes (&romb[addr], data, sz);
            store_bytes (&romb[addr], data, sz);
            return (0);
            return (0);
        } else if ((addr >= 0x10000000) &&
        } else if ((addr >= 0x10000000) &&
                   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
                   (addr < (0x10000000 + (512 << (mec_iocr & 0x0f)))) &&
                   (mec_iocr & 0x10))  {
                   (mec_iocr & 0x10))  {
            erareg = *data & 0x0e;
            erareg = *data & 0x0e;
            return (0);
            return (0);
        }
        }
 
 
    } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
    } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
               (((mec_memcfg & 0x20000) && (sz > 1)) ||
               (((mec_memcfg & 0x20000) && (sz > 1)) ||
                (!(mec_memcfg & 0x20000) && (sz == 0)))) {
                (!(mec_memcfg & 0x20000) && (sz == 0)))) {
 
 
        *ws = mem_romw_ws + 1;
        *ws = mem_romw_ws + 1;
        if (sz == 3)
        if (sz == 3)
            *ws += mem_romw_ws + STD_WS;
            *ws += mem_romw_ws + STD_WS;
        store_bytes (&romb[addr], data, sz);
        store_bytes (&romb[addr], data, sz);
        return (0);
        return (0);
 
 
#else
#else
    } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
    } else if ((addr < mem_romsz) && (mec_memcfg & 0x10000) && (wrp) &&
               (((mec_memcfg & 0x20000) && (sz > 1)) ||
               (((mec_memcfg & 0x20000) && (sz > 1)) ||
                (!(mec_memcfg & 0x20000) && (sz == 0)))) {
                (!(mec_memcfg & 0x20000) && (sz == 0)))) {
 
 
        *ws = mem_romw_ws + 1;
        *ws = mem_romw_ws + 1;
        if (sz == 3)
        if (sz == 3)
            *ws += mem_romw_ws + STD_WS;
            *ws += mem_romw_ws + STD_WS;
        store_bytes (&romb[addr], data, sz);
        store_bytes (&romb[addr], data, sz);
        return (0);
        return (0);
 
 
#endif
#endif
 
 
    }
    }
 
 
    *ws = MEM_EX_WS;
    *ws = MEM_EX_WS;
    set_sfsr(UIMP_ACC, addr, asi, 0);
    set_sfsr(UIMP_ACC, addr, asi, 0);
    return (1);
    return (1);
}
}
 
 
static unsigned char  *
static unsigned char  *
get_mem_ptr(addr, size)
get_mem_ptr(addr, size)
    uint32          addr;
    uint32          addr;
    uint32          size;
    uint32          size;
{
{
    if ((addr + size) < ROM_SZ) {
    if ((addr + size) < ROM_SZ) {
        return (&romb[addr]);
        return (&romb[addr]);
    } else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) {
    } else if ((addr >= mem_ramstart) && ((addr + size) < mem_ramend)) {
        return (&ramb[addr & mem_rammask]);
        return (&ramb[addr & mem_rammask]);
    }
    }
 
 
#ifdef ERA
#ifdef ERA
      else if ((era) && ((addr <0x100000) ||
      else if ((era) && ((addr <0x100000) ||
        ((addr >= (unsigned) 0x80000000) && ((addr + size) < (unsigned) 0x80100000)))) {
        ((addr >= (unsigned) 0x80000000) && ((addr + size) < (unsigned) 0x80100000)))) {
        return (&romb[addr & ROM_MASK]);
        return (&romb[addr & ROM_MASK]);
    }
    }
#endif
#endif
 
 
    return ((char *) -1);
    return ((char *) -1);
}
}
 
 
int
int
sis_memory_write(addr, data, length)
sis_memory_write(addr, data, length)
    uint32          addr;
    uint32          addr;
    char           *data;
    char           *data;
    uint32          length;
    uint32          length;
{
{
    char           *mem;
    char           *mem;
 
 
    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
        return (0);
        return (0);
 
 
    memcpy(mem, data, length);
    memcpy(mem, data, length);
    return (length);
    return (length);
}
}
 
 
int
int
sis_memory_read(addr, data, length)
sis_memory_read(addr, data, length)
    uint32          addr;
    uint32          addr;
    char           *data;
    char           *data;
    uint32          length;
    uint32          length;
{
{
    char           *mem;
    char           *mem;
 
 
    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
    if ((mem = get_mem_ptr(addr, length)) == ((char *) -1))
        return (0);
        return (0);
 
 
    memcpy(data, mem, length);
    memcpy(data, mem, length);
    return (length);
    return (length);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.