1bb16d227Schristos /* mem.c --- memory for M32C simulator. 2bb16d227Schristos 3*8b657b07Schristos Copyright (C) 2005-2023 Free Software Foundation, Inc. 4bb16d227Schristos Contributed by Red Hat, Inc. 5bb16d227Schristos 6bb16d227Schristos This file is part of the GNU simulators. 7bb16d227Schristos 8bb16d227Schristos This program is free software; you can redistribute it and/or modify 9bb16d227Schristos it under the terms of the GNU General Public License as published by 10bb16d227Schristos the Free Software Foundation; either version 3 of the License, or 11bb16d227Schristos (at your option) any later version. 12bb16d227Schristos 13bb16d227Schristos This program is distributed in the hope that it will be useful, 14bb16d227Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 15bb16d227Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16bb16d227Schristos GNU General Public License for more details. 17bb16d227Schristos 18bb16d227Schristos You should have received a copy of the GNU General Public License 19bb16d227Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 20bb16d227Schristos 21*8b657b07Schristos /* This must come before any other includes. */ 22*8b657b07Schristos #include "defs.h" 23bb16d227Schristos 24*8b657b07Schristos #include <errno.h> 25bb16d227Schristos #include <stdio.h> 26bb16d227Schristos #include <stdlib.h> 27bb16d227Schristos #include <string.h> 28bb16d227Schristos #include <ctype.h> 29bb16d227Schristos #include <sys/time.h> 30bb16d227Schristos #include <sys/types.h> 31bb16d227Schristos #include <unistd.h> 32bb16d227Schristos #include <sys/select.h> 33bb16d227Schristos #ifdef HAVE_TERMIOS_H 34bb16d227Schristos #include <termios.h> 35bb16d227Schristos #endif 36bb16d227Schristos 37bb16d227Schristos #include "mem.h" 38bb16d227Schristos #include "cpu.h" 39bb16d227Schristos #include "syscalls.h" 40bb16d227Schristos #include "misc.h" 41bb16d227Schristos #ifdef TIMER_A 42bb16d227Schristos #include "int.h" 43bb16d227Schristos #include "timer_a.h" 44bb16d227Schristos #endif 45bb16d227Schristos 46bb16d227Schristos #define L1_BITS (10) 47bb16d227Schristos #define L2_BITS (10) 48bb16d227Schristos #define OFF_BITS (12) 49bb16d227Schristos 50bb16d227Schristos #define L1_LEN (1 << L1_BITS) 51bb16d227Schristos #define L2_LEN (1 << L2_BITS) 52bb16d227Schristos #define OFF_LEN (1 << OFF_BITS) 53bb16d227Schristos 54bb16d227Schristos static unsigned char **pt[L1_LEN]; 55bb16d227Schristos 56bb16d227Schristos #ifdef HAVE_TERMIOS_H 57bb16d227Schristos int m32c_console_ifd = 0; 58bb16d227Schristos #endif 59bb16d227Schristos int m32c_console_ofd = 1; 60bb16d227Schristos #ifdef HAVE_TERMIOS_H 61bb16d227Schristos int m32c_use_raw_console = 0; 62bb16d227Schristos #endif 63bb16d227Schristos 64bb16d227Schristos #ifdef TIMER_A 65bb16d227Schristos Timer_A timer_a; 66bb16d227Schristos #endif 67bb16d227Schristos 68bb16d227Schristos /* [ get=0/put=1 ][ byte size ] */ 69bb16d227Schristos static unsigned int mem_counters[2][5]; 70bb16d227Schristos 71bb16d227Schristos #define COUNT(isput,bytes) \ 72bb16d227Schristos if (verbose && enable_counting) mem_counters[isput][bytes]++ 73bb16d227Schristos 74bb16d227Schristos void 75bb16d227Schristos init_mem (void) 76bb16d227Schristos { 77bb16d227Schristos int i, j; 78bb16d227Schristos 79bb16d227Schristos for (i = 0; i < L1_LEN; i++) 80bb16d227Schristos if (pt[i]) 81bb16d227Schristos { 82bb16d227Schristos for (j = 0; j < L2_LEN; j++) 83bb16d227Schristos if (pt[i][j]) 84bb16d227Schristos free (pt[i][j]); 85bb16d227Schristos free (pt[i]); 86bb16d227Schristos } 87bb16d227Schristos memset (pt, 0, sizeof (pt)); 88bb16d227Schristos memset (mem_counters, 0, sizeof (mem_counters)); 89bb16d227Schristos } 90bb16d227Schristos 91bb16d227Schristos static unsigned char * 92bb16d227Schristos mem_ptr (int address) 93bb16d227Schristos { 94bb16d227Schristos static int recursing = 0; 95bb16d227Schristos int pt1 = (address >> (L2_BITS + OFF_BITS)) & ((1 << L1_BITS) - 1); 96bb16d227Schristos int pt2 = (address >> OFF_BITS) & ((1 << L2_BITS) - 1); 97bb16d227Schristos int pto = address & ((1 << OFF_BITS) - 1); 98bb16d227Schristos 99bb16d227Schristos if (address == 0 && !recursing) 100bb16d227Schristos { 101bb16d227Schristos recursing = 1; 102bb16d227Schristos put_reg (pc, m32c_opcode_pc); 103bb16d227Schristos printf ("NULL pointer dereference at pc=0x%x\n", get_reg (pc)); 104bb16d227Schristos step_result = M32C_MAKE_HIT_BREAK (); 105bb16d227Schristos #if 0 106bb16d227Schristos /* This code can be re-enabled to help diagnose NULL pointer 107bb16d227Schristos bugs that aren't debuggable in GDB. */ 108bb16d227Schristos m32c_dump_all_registers (); 109bb16d227Schristos exit (1); 110bb16d227Schristos #endif 111bb16d227Schristos } 112bb16d227Schristos 113bb16d227Schristos if (pt[pt1] == 0) 114bb16d227Schristos pt[pt1] = (unsigned char **) calloc (L2_LEN, sizeof (char **)); 115bb16d227Schristos if (pt[pt1][pt2] == 0) 116bb16d227Schristos { 117bb16d227Schristos pt[pt1][pt2] = (unsigned char *) malloc (OFF_LEN); 118bb16d227Schristos memset (pt[pt1][pt2], 0, OFF_LEN); 119bb16d227Schristos } 120bb16d227Schristos 121bb16d227Schristos return pt[pt1][pt2] + pto; 122bb16d227Schristos } 123bb16d227Schristos 124bb16d227Schristos static void 125bb16d227Schristos used (int rstart, int i, int j) 126bb16d227Schristos { 127bb16d227Schristos int rend = i << (L2_BITS + OFF_BITS); 128bb16d227Schristos rend += j << OFF_BITS; 129bb16d227Schristos if (rstart == 0xe0000 && rend == 0xe1000) 130bb16d227Schristos return; 131bb16d227Schristos printf ("mem: %08x - %08x (%dk bytes)\n", rstart, rend - 1, 132bb16d227Schristos (rend - rstart) / 1024); 133bb16d227Schristos } 134bb16d227Schristos 135bb16d227Schristos static char * 136bb16d227Schristos mcs (int isput, int bytes) 137bb16d227Schristos { 138bb16d227Schristos return comma (mem_counters[isput][bytes]); 139bb16d227Schristos } 140bb16d227Schristos 141bb16d227Schristos void 142bb16d227Schristos mem_usage_stats (void) 143bb16d227Schristos { 144bb16d227Schristos int i, j; 145bb16d227Schristos int rstart = 0; 146bb16d227Schristos int pending = 0; 147bb16d227Schristos 148bb16d227Schristos for (i = 0; i < L1_LEN; i++) 149bb16d227Schristos if (pt[i]) 150bb16d227Schristos { 151bb16d227Schristos for (j = 0; j < L2_LEN; j++) 152bb16d227Schristos if (pt[i][j]) 153bb16d227Schristos { 154bb16d227Schristos if (!pending) 155bb16d227Schristos { 156bb16d227Schristos pending = 1; 157bb16d227Schristos rstart = (i << (L2_BITS + OFF_BITS)) + (j << OFF_BITS); 158bb16d227Schristos } 159bb16d227Schristos } 160bb16d227Schristos else if (pending) 161bb16d227Schristos { 162bb16d227Schristos pending = 0; 163bb16d227Schristos used (rstart, i, j); 164bb16d227Schristos } 165bb16d227Schristos } 166bb16d227Schristos else 167bb16d227Schristos { 168bb16d227Schristos if (pending) 169bb16d227Schristos { 170bb16d227Schristos pending = 0; 171bb16d227Schristos used (rstart, i, 0); 172bb16d227Schristos } 173bb16d227Schristos } 174bb16d227Schristos /* mem foo: 123456789012 123456789012 123456789012 123456789012 175bb16d227Schristos 123456789012 */ 176bb16d227Schristos printf (" byte short pointer long" 177bb16d227Schristos " fetch\n"); 178bb16d227Schristos printf ("mem get: %12s %12s %12s %12s %12s\n", mcs (0, 1), mcs (0, 2), 179bb16d227Schristos mcs (0, 3), mcs (0, 4), mcs (0, 0)); 180bb16d227Schristos printf ("mem put: %12s %12s %12s %12s\n", mcs (1, 1), mcs (1, 2), 181bb16d227Schristos mcs (1, 3), mcs (1, 4)); 182bb16d227Schristos } 183bb16d227Schristos 184bb16d227Schristos static int tpr = 0; 185bb16d227Schristos static void 186bb16d227Schristos s (int address, char *dir) 187bb16d227Schristos { 188bb16d227Schristos if (tpr == 0) 189bb16d227Schristos printf ("MEM[%0*x] %s", membus_mask == 0xfffff ? 5 : 6, address, dir); 190bb16d227Schristos tpr++; 191bb16d227Schristos } 192bb16d227Schristos 193bb16d227Schristos #define S(d) if (trace) s(address, d) 194bb16d227Schristos static void 195bb16d227Schristos e (void) 196bb16d227Schristos { 197bb16d227Schristos if (!trace) 198bb16d227Schristos return; 199bb16d227Schristos tpr--; 200bb16d227Schristos if (tpr == 0) 201bb16d227Schristos printf ("\n"); 202bb16d227Schristos } 203bb16d227Schristos 204bb16d227Schristos #define E() if (trace) e() 205bb16d227Schristos 206bb16d227Schristos extern int m32c_disassemble; 207bb16d227Schristos 208bb16d227Schristos static void 209bb16d227Schristos mem_put_byte (int address, unsigned char value) 210bb16d227Schristos { 211bb16d227Schristos unsigned char *m; 212bb16d227Schristos address &= membus_mask; 213bb16d227Schristos m = mem_ptr (address); 214bb16d227Schristos if (trace) 215bb16d227Schristos printf (" %02x", value); 216bb16d227Schristos *m = value; 217bb16d227Schristos switch (address) 218bb16d227Schristos { 219bb16d227Schristos case 0x00e1: 220bb16d227Schristos { 221bb16d227Schristos static int old_led = -1; 222bb16d227Schristos static char *led_on[] = 223bb16d227Schristos { "\033[31m O ", "\033[32m O ", "\033[34m O " }; 224bb16d227Schristos static char *led_off[] = { "\033[0m � ", "\033[0m � ", "\033[0m � " }; 225bb16d227Schristos int i; 226bb16d227Schristos if (old_led != value) 227bb16d227Schristos { 228bb16d227Schristos fputs (" ", stdout); 229bb16d227Schristos for (i = 0; i < 3; i++) 230bb16d227Schristos if (value & (1 << i)) 231bb16d227Schristos fputs (led_off[i], stdout); 232bb16d227Schristos else 233bb16d227Schristos fputs (led_on[i], stdout); 234bb16d227Schristos fputs ("\033[0m\r", stdout); 235bb16d227Schristos fflush (stdout); 236bb16d227Schristos old_led = value; 237bb16d227Schristos } 238bb16d227Schristos } 239bb16d227Schristos break; 240bb16d227Schristos #ifdef TIMER_A 241bb16d227Schristos /* M32C Timer A */ 242bb16d227Schristos case 0x346: /* TA0low */ 243bb16d227Schristos timer_a.count = (timer_a.count & 0xff00) | value; 244bb16d227Schristos timer_a.reload = timer_a.count; 245bb16d227Schristos break; 246bb16d227Schristos case 0x347: /* TA0high */ 247bb16d227Schristos timer_a.count = (timer_a.count & 0x00ff) | (value << 8); 248bb16d227Schristos timer_a.reload = timer_a.count; 249bb16d227Schristos break; 250bb16d227Schristos case 0x340: /* TABSR */ 251bb16d227Schristos timer_a.bsr = value; 252bb16d227Schristos break; 253bb16d227Schristos case 0x356: /* TA0MR */ 254bb16d227Schristos timer_a.mode = value; 255bb16d227Schristos break; 256bb16d227Schristos case 0x35f: /* TCSPR */ 257bb16d227Schristos timer_a.tcspr = value; 258bb16d227Schristos break; 259bb16d227Schristos case 0x006c: /* TA0IC */ 260bb16d227Schristos timer_a.ic = value; 261bb16d227Schristos break; 262bb16d227Schristos 263bb16d227Schristos /* R8C Timer RA */ 264bb16d227Schristos case 0x100: /* TRACR */ 265bb16d227Schristos timer_a.bsr = value; 266bb16d227Schristos break; 267bb16d227Schristos case 0x102: /* TRAMR */ 268bb16d227Schristos timer_a.mode = value; 269bb16d227Schristos break; 270bb16d227Schristos case 0x104: /* TRA */ 271bb16d227Schristos timer_a.count = value; 272bb16d227Schristos timer_a.reload = value; 273bb16d227Schristos break; 274bb16d227Schristos case 0x103: /* TRAPRE */ 275bb16d227Schristos timer_a.tcspr = value; 276bb16d227Schristos break; 277bb16d227Schristos case 0x0056: /* TA0IC */ 278bb16d227Schristos timer_a.ic = value; 279bb16d227Schristos break; 280bb16d227Schristos #endif 281bb16d227Schristos 282bb16d227Schristos case 0x2ea: /* m32c uart1tx */ 283bb16d227Schristos case 0x3aa: /* m16c uart1tx */ 284bb16d227Schristos { 285bb16d227Schristos static int pending_exit = 0; 286bb16d227Schristos if (value == 0) 287bb16d227Schristos { 288bb16d227Schristos if (pending_exit) 289bb16d227Schristos { 290bb16d227Schristos step_result = M32C_MAKE_EXITED (value); 291bb16d227Schristos return; 292bb16d227Schristos } 293bb16d227Schristos pending_exit = 1; 294bb16d227Schristos } 295bb16d227Schristos else 296bb16d227Schristos { 297*8b657b07Schristos if (write (m32c_console_ofd, &value, 1) != 1) 298*8b657b07Schristos printf ("write console failed: %s\n", strerror (errno)); 299bb16d227Schristos } 300bb16d227Schristos } 301bb16d227Schristos break; 302bb16d227Schristos 303bb16d227Schristos case 0x400: 304bb16d227Schristos m32c_syscall (value); 305bb16d227Schristos break; 306bb16d227Schristos 307bb16d227Schristos case 0x401: 308bb16d227Schristos putchar (value); 309bb16d227Schristos break; 310bb16d227Schristos 311bb16d227Schristos case 0x402: 312bb16d227Schristos printf ("SimTrace: %06lx %02x\n", regs.r_pc, value); 313bb16d227Schristos break; 314bb16d227Schristos 315bb16d227Schristos case 0x403: 316bb16d227Schristos printf ("SimTrap: %06lx %02x\n", regs.r_pc, value); 317bb16d227Schristos abort (); 318bb16d227Schristos } 319bb16d227Schristos } 320bb16d227Schristos 321bb16d227Schristos void 322bb16d227Schristos mem_put_qi (int address, unsigned char value) 323bb16d227Schristos { 324bb16d227Schristos S ("<="); 325bb16d227Schristos mem_put_byte (address, value & 0xff); 326bb16d227Schristos E (); 327bb16d227Schristos COUNT (1, 1); 328bb16d227Schristos } 329bb16d227Schristos 330bb16d227Schristos void 331bb16d227Schristos mem_put_hi (int address, unsigned short value) 332bb16d227Schristos { 333bb16d227Schristos if (address == 0x402) 334bb16d227Schristos { 335bb16d227Schristos printf ("SimTrace: %06lx %04x\n", regs.r_pc, value); 336bb16d227Schristos return; 337bb16d227Schristos } 338bb16d227Schristos S ("<="); 339bb16d227Schristos mem_put_byte (address, value & 0xff); 340bb16d227Schristos mem_put_byte (address + 1, value >> 8); 341bb16d227Schristos E (); 342bb16d227Schristos COUNT (1, 2); 343bb16d227Schristos } 344bb16d227Schristos 345bb16d227Schristos void 346bb16d227Schristos mem_put_psi (int address, unsigned long value) 347bb16d227Schristos { 348bb16d227Schristos S ("<="); 349bb16d227Schristos mem_put_byte (address, value & 0xff); 350bb16d227Schristos mem_put_byte (address + 1, (value >> 8) & 0xff); 351bb16d227Schristos mem_put_byte (address + 2, value >> 16); 352bb16d227Schristos E (); 353bb16d227Schristos COUNT (1, 3); 354bb16d227Schristos } 355bb16d227Schristos 356bb16d227Schristos void 357bb16d227Schristos mem_put_si (int address, unsigned long value) 358bb16d227Schristos { 359bb16d227Schristos S ("<="); 360bb16d227Schristos mem_put_byte (address, value & 0xff); 361bb16d227Schristos mem_put_byte (address + 1, (value >> 8) & 0xff); 362bb16d227Schristos mem_put_byte (address + 2, (value >> 16) & 0xff); 363bb16d227Schristos mem_put_byte (address + 3, (value >> 24) & 0xff); 364bb16d227Schristos E (); 365bb16d227Schristos COUNT (1, 4); 366bb16d227Schristos } 367bb16d227Schristos 368bb16d227Schristos void 369bb16d227Schristos mem_put_blk (int address, const void *bufptr, int nbytes) 370bb16d227Schristos { 371*8b657b07Schristos const unsigned char *buf = bufptr; 372*8b657b07Schristos 373bb16d227Schristos S ("<="); 374bb16d227Schristos if (enable_counting) 375bb16d227Schristos mem_counters[1][1] += nbytes; 376bb16d227Schristos while (nbytes--) 377*8b657b07Schristos mem_put_byte (address++, *buf++); 378bb16d227Schristos E (); 379bb16d227Schristos } 380bb16d227Schristos 381bb16d227Schristos unsigned char 382bb16d227Schristos mem_get_pc (void) 383bb16d227Schristos { 384bb16d227Schristos unsigned char *m = mem_ptr (regs.r_pc & membus_mask); 385bb16d227Schristos COUNT (0, 0); 386bb16d227Schristos return *m; 387bb16d227Schristos } 388bb16d227Schristos 389bb16d227Schristos #ifdef HAVE_TERMIOS_H 390bb16d227Schristos static int console_raw = 0; 391bb16d227Schristos static struct termios oattr; 392bb16d227Schristos 393bb16d227Schristos static int 394bb16d227Schristos stdin_ready (void) 395bb16d227Schristos { 396bb16d227Schristos fd_set ifd; 397bb16d227Schristos int n; 398bb16d227Schristos struct timeval t; 399bb16d227Schristos 400bb16d227Schristos t.tv_sec = 0; 401bb16d227Schristos t.tv_usec = 0; 402bb16d227Schristos FD_ZERO (&ifd); 403bb16d227Schristos FD_SET (m32c_console_ifd, &ifd); 404bb16d227Schristos n = select (1, &ifd, 0, 0, &t); 405bb16d227Schristos return n > 0; 406bb16d227Schristos } 407bb16d227Schristos 408bb16d227Schristos void 409bb16d227Schristos m32c_sim_restore_console (void) 410bb16d227Schristos { 411bb16d227Schristos if (console_raw) 412bb16d227Schristos tcsetattr (m32c_console_ifd, TCSANOW, &oattr); 413bb16d227Schristos console_raw = 0; 414bb16d227Schristos } 415bb16d227Schristos #endif 416bb16d227Schristos 417bb16d227Schristos static unsigned char 418bb16d227Schristos mem_get_byte (int address) 419bb16d227Schristos { 420bb16d227Schristos unsigned char *m; 421bb16d227Schristos address &= membus_mask; 422bb16d227Schristos m = mem_ptr (address); 423bb16d227Schristos switch (address) 424bb16d227Schristos { 425bb16d227Schristos #ifdef HAVE_TERMIOS_H 426bb16d227Schristos case 0x2ed: /* m32c uart1c1 */ 427bb16d227Schristos case 0x3ad: /* m16c uart1c1 */ 428bb16d227Schristos 429bb16d227Schristos if (!console_raw && m32c_use_raw_console) 430bb16d227Schristos { 431bb16d227Schristos struct termios attr; 432bb16d227Schristos tcgetattr (m32c_console_ifd, &attr); 433bb16d227Schristos tcgetattr (m32c_console_ifd, &oattr); 434bb16d227Schristos /* We want each key to be sent as the user presses them. */ 435bb16d227Schristos attr.c_lflag &= ~(ICANON | ECHO | ECHOE); 436bb16d227Schristos tcsetattr (m32c_console_ifd, TCSANOW, &attr); 437bb16d227Schristos console_raw = 1; 438bb16d227Schristos atexit (m32c_sim_restore_console); 439bb16d227Schristos } 440bb16d227Schristos 441bb16d227Schristos if (stdin_ready ()) 442bb16d227Schristos return 0x02; /* tx empty and rx full */ 443bb16d227Schristos else 444bb16d227Schristos return 0x0a; /* transmitter empty */ 445bb16d227Schristos 446bb16d227Schristos case 0x2ee: /* m32c uart1 rx */ 447bb16d227Schristos { 448bb16d227Schristos char c; 449*8b657b07Schristos if (read (m32c_console_ifd, &c, 1) != 1) 450*8b657b07Schristos return 0; 451bb16d227Schristos if (m32c_console_ifd == 0 && c == 3) /* Ctrl-C */ 452bb16d227Schristos { 453bb16d227Schristos printf ("Ctrl-C!\n"); 454bb16d227Schristos exit (0); 455bb16d227Schristos } 456bb16d227Schristos 457bb16d227Schristos if (m32c_console_ifd != 1) 458bb16d227Schristos { 459bb16d227Schristos if (isgraph (c)) 460bb16d227Schristos printf ("\033[31m%c\033[0m", c); 461bb16d227Schristos else 462bb16d227Schristos printf ("\033[31m%02x\033[0m", c); 463bb16d227Schristos } 464bb16d227Schristos return c; 465bb16d227Schristos } 466bb16d227Schristos #endif 467bb16d227Schristos 468bb16d227Schristos #ifdef TIMER_A 469bb16d227Schristos case 0x346: /* TA0low */ 470bb16d227Schristos return timer_a.count & 0xff; 471bb16d227Schristos case 0x347: /* TA0high */ 472bb16d227Schristos return (timer_a.count >> 8) & 0xff; 473bb16d227Schristos case 0x104: /* TRA */ 474bb16d227Schristos return timer_a.count; 475bb16d227Schristos #endif 476bb16d227Schristos 477bb16d227Schristos default: 478bb16d227Schristos /* In case both cases above are not included. */ 479bb16d227Schristos ; 480bb16d227Schristos } 481bb16d227Schristos 482bb16d227Schristos S ("=>"); 483bb16d227Schristos if (trace) 484bb16d227Schristos printf (" %02x", *m); 485bb16d227Schristos E (); 486bb16d227Schristos return *m; 487bb16d227Schristos } 488bb16d227Schristos 489bb16d227Schristos unsigned char 490bb16d227Schristos mem_get_qi (int address) 491bb16d227Schristos { 492bb16d227Schristos unsigned char rv; 493bb16d227Schristos S ("=>"); 494bb16d227Schristos rv = mem_get_byte (address); 495bb16d227Schristos COUNT (0, 1); 496bb16d227Schristos E (); 497bb16d227Schristos return rv; 498bb16d227Schristos } 499bb16d227Schristos 500bb16d227Schristos unsigned short 501bb16d227Schristos mem_get_hi (int address) 502bb16d227Schristos { 503bb16d227Schristos unsigned short rv; 504bb16d227Schristos S ("=>"); 505bb16d227Schristos rv = mem_get_byte (address); 506bb16d227Schristos rv |= mem_get_byte (address + 1) * 256; 507bb16d227Schristos COUNT (0, 2); 508bb16d227Schristos E (); 509bb16d227Schristos return rv; 510bb16d227Schristos } 511bb16d227Schristos 512bb16d227Schristos unsigned long 513bb16d227Schristos mem_get_psi (int address) 514bb16d227Schristos { 515bb16d227Schristos unsigned long rv; 516bb16d227Schristos S ("=>"); 517bb16d227Schristos rv = mem_get_byte (address); 518bb16d227Schristos rv |= mem_get_byte (address + 1) * 256; 519bb16d227Schristos rv |= mem_get_byte (address + 2) * 65536; 520bb16d227Schristos COUNT (0, 3); 521bb16d227Schristos E (); 522bb16d227Schristos return rv; 523bb16d227Schristos } 524bb16d227Schristos 525bb16d227Schristos unsigned long 526bb16d227Schristos mem_get_si (int address) 527bb16d227Schristos { 528bb16d227Schristos unsigned long rv; 529bb16d227Schristos S ("=>"); 530bb16d227Schristos rv = mem_get_byte (address); 531bb16d227Schristos rv |= mem_get_byte (address + 1) << 8; 532bb16d227Schristos rv |= mem_get_byte (address + 2) << 16; 533bb16d227Schristos rv |= mem_get_byte (address + 3) << 24; 534bb16d227Schristos COUNT (0, 4); 535bb16d227Schristos E (); 536bb16d227Schristos return rv; 537bb16d227Schristos } 538bb16d227Schristos 539bb16d227Schristos void 540bb16d227Schristos mem_get_blk (int address, void *bufptr, int nbytes) 541bb16d227Schristos { 542*8b657b07Schristos char *buf = bufptr; 543*8b657b07Schristos 544bb16d227Schristos S ("=>"); 545bb16d227Schristos if (enable_counting) 546bb16d227Schristos mem_counters[0][1] += nbytes; 547bb16d227Schristos while (nbytes--) 548*8b657b07Schristos *buf++ = mem_get_byte (address++); 549bb16d227Schristos E (); 550bb16d227Schristos } 551bb16d227Schristos 552bb16d227Schristos int 553bb16d227Schristos sign_ext (int v, int bits) 554bb16d227Schristos { 555bb16d227Schristos if (bits < 32) 556bb16d227Schristos { 557bb16d227Schristos v &= (1 << bits) - 1; 558bb16d227Schristos if (v & (1 << (bits - 1))) 559bb16d227Schristos v -= (1 << bits); 560bb16d227Schristos } 561bb16d227Schristos return v; 562bb16d227Schristos } 563bb16d227Schristos 564bb16d227Schristos #if TIMER_A 565bb16d227Schristos void 566bb16d227Schristos update_timer_a (void) 567bb16d227Schristos { 568bb16d227Schristos if (timer_a.bsr & 1) 569bb16d227Schristos { 570bb16d227Schristos timer_a.prescale--; 571bb16d227Schristos if (timer_a.prescale < 0) 572bb16d227Schristos { 573bb16d227Schristos if (A24) 574bb16d227Schristos { 575bb16d227Schristos switch (timer_a.mode & 0xc0) 576bb16d227Schristos { 577bb16d227Schristos case 0x00: 578bb16d227Schristos timer_a.prescale = 0; 579bb16d227Schristos break; 580bb16d227Schristos case 0x40: 581bb16d227Schristos timer_a.prescale = 8; 582bb16d227Schristos break; 583bb16d227Schristos case 0x80: 584bb16d227Schristos timer_a.prescale = timer_a.tcspr & 0x0f; 585bb16d227Schristos break; 586bb16d227Schristos case 0xc0: 587bb16d227Schristos timer_a.prescale = 32; 588bb16d227Schristos break; 589bb16d227Schristos } 590bb16d227Schristos } 591bb16d227Schristos else 592bb16d227Schristos { 593bb16d227Schristos timer_a.prescale = timer_a.tcspr; 594bb16d227Schristos } 595bb16d227Schristos timer_a.count--; 596bb16d227Schristos if (timer_a.count < 0) 597bb16d227Schristos { 598bb16d227Schristos timer_a.count = timer_a.reload; 599bb16d227Schristos if (timer_a.ic & 7) 600bb16d227Schristos { 601bb16d227Schristos if (A24) 602bb16d227Schristos mem_put_qi (0x6c, timer_a.ic | 0x08); 603bb16d227Schristos else 604bb16d227Schristos mem_put_qi (0x56, timer_a.ic | 0x08); 605bb16d227Schristos } 606bb16d227Schristos } 607bb16d227Schristos } 608bb16d227Schristos } 609bb16d227Schristos 610bb16d227Schristos if (regs.r_flags & FLAGBIT_I /* interrupts enabled */ 611bb16d227Schristos && timer_a.ic & 0x08 /* timer A interrupt triggered */ 612bb16d227Schristos && (timer_a.ic & 0x07) > ((regs.r_flags >> 12) & 0x07)) 613bb16d227Schristos { 614bb16d227Schristos if (A24) 615bb16d227Schristos trigger_peripheral_interrupt (12, 0x06c); 616bb16d227Schristos else 617bb16d227Schristos trigger_peripheral_interrupt (22, 0x056); 618bb16d227Schristos } 619bb16d227Schristos } 620bb16d227Schristos #endif 621