xref: /netbsd-src/external/gpl3/gdb.old/dist/sim/m32c/mem.c (revision 8b657b0747480f8989760d71343d6dd33f8d4cf9)
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