1 /**************************************************************************************\
2 * *
3 * The Lisa Emulator Project V1.2.6 DEV 2007.12.04 *
4 * http://lisaem.sunder.net *
5 * *
6 * Copyright (C) 1998, 2007 Ray A. Arachelian *
7 * All Rights Reserved *
8 * *
9 * This program is free software; you can redistribute it and/or *
10 * modify it under the terms of the GNU General Public License *
11 * as published by the Free Software Foundation; either version 2 *
12 * of the License, or (at your option) any later version. *
13 * *
14 * This program is distributed in the hope that it will be useful, *
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17 * GNU General Public License for more details. *
18 * *
19 * You should have received a copy of the GNU General Public License *
20 * along with this program; if not, write to the Free Software *
21 * Foundation, Inc., 59 Temple Place #330, Boston, MA 02111-1307, USA. *
22 * *
23 * or visit: http://www.gnu.org/licenses/gpl.html *
24 * *
25 * *
26 * *
27 * Global externed variables, macros, macro constants, and function prototypes. *
28 * *
29 * --------------------------------------------------------------------------------- *
30 * *
31 * Yes, this is ugly, yes, it's not quite standard practice, but there is madness to *
32 * method. ;-) (For the irony impaired, yes, that IS backwards) *
33 * *
34 * 1. Include all the needed include files. *
35 * 2. Define macro fn's and constants used elsewhere *
36 * 3. define type definitions *
37 * 4. define externed global variables *
38 * 5. define fn extern or local prototypes (self checking) *
39 * *
40 \**************************************************************************************/
41
42 // This should always be on, but we can cheat for a slight speedup to turn it off?
43 #define CHECKODDPOINTERS 1
44 #define DEBUGLEVEL 100
45
46 // If tracelog is enabled, also enable DEBUG code so that tracing can be done.
47 #ifdef TRACE
48 #ifndef DEBUG
49 #define DEBUG
50 #endif
51 #endif
52
53 //Enable to build a Lisa1 emulator instead of a Lisa2 emulator - not yet implemented - place holder.
54 //#define LISA1
55
56 // enables MMU cache vs mmu registers testing - this is VERY VERY SLOW, and no longer valid
57 //#define MMUVALIDATE 1
58
59
60 // If this is disabled the Generator CORE will calculate the status flags on every opcode
61 // hack for LisaEm to see if there are flag calculation issues.
62 #define NORMAL_GENERATOR_FLAGS 1
63
64 // This forces each executed opcode to have it's IPC re-created - used to see if IPC cache
65 // isn't working properly, or if we're hitting self-modifying code -- very slow, do not use
66 //#define EVALUATE_EACH_IPC 1
67
68 //enable a read after write to ensure we get back the same data we wrote - no longer supported
69 //#define VERIFY_WRITES 1
70 // If this is enabled, it's a little slower because extra checks are required.
71
72 //do not use this ever//#define ALLOW_1536K_RAM 1 -- no longer
73
74
75 // Enable this if you want all of the Lisa Status register bits to be set. - slower, but more acurate.
76 #define FULL_STATREG 1
77
78 // Enable this to disassemble skipped opcodes to the log that weren't executed - might be buggy!
79 //#define DISASM_SKIPPED_OPCODES 1
80
81 // Same as above, but specific to a single block of code instead of every chunk of code.
82 // //0xd27a-0xddff for LisaTest *REMOVE*
83 //#define LOOKAHEAD 1
84 //#define LOOKSTARTADDR 0x00b848d0
85 //#define LOOKENDADDR 0x00b849cc
86
87 // If enabled, what screenhash value to turn debugging on
88 //#define DEBUG_ON_SCREENHASH {0,0,0,0,0,0,0,0, 0x7f,0x19,0xcc,0x88,0x87,0x5f,0xca,0x64,0xff,0xfc,0xff,0x5c,0x00,0x00}
89 //#define DEBUG_OFF_SCREENHASH {0,0,0,0,0,0,0,0, 0xff,0xff,0x9b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xef,0xdf}
90
91 //{0x7f,0xcb,0xe7,0xbd,0xe0,0xf3,0x2b,0xcd,0x7f,0xf3,0xff,0x5d,0x00,0x00}
92
93 // If this is turned on, the VIA timers will no longer be tied to the CPU speed, rather,
94 // they'll be adjusted to match the throttle. So if the throttle is 10Mhz, these will take
95 // 2x CPU cycles they normally do. This is in the hopes of slowing down the blinking
96 // text cursor to a reasonable value so it doesn't flicker. It might not work with all
97 // OS's - will certainly cause LisaTest to complain if its run at throttle >5.0Mhz
98 //#define TIE_VIA_TIMER_TO_HOST 1
99 // above does not work and instead throws error 93 on the dual parallel slot's power on self test.
100
101
102
103 // How close do we need to be in order to declare a matching the screen hash?
104 #define SCREENHASH_LIMIT 16
105
106 // Do read-only memory violations cause bus errors?
107 #define ROMEMCAUSESBUSERROR 1
108
109 // Do physical memory over/underflows cause MMU exceptions?
110 //#define PHYS_UNDER_BUSERR 1
111 //#ifdef PHYS_OVERFLOW_BUSERR 1
112
113 // Enable this to avoid C compiler assumptions (noteably in the get_pending_vector() fn)
114 // it's safer to enable this if not using GCC, or you can't guarantee expression evaluation order is left to right
115 #define PARANOID 1
116
117 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
118 // The following options are only for DEBUG enabled compiles
119 #ifdef DEBUG
120
121 // If this is enabled, and debug log is enabled, it will attempt to suppress loop disassembly
122 // by keeping track of the last MAX_LOOP_REGS and will only output the changed registers.
123 #define SUPPRESS_LOOP_DISASM 1
124 #define MAX_LOOP_REGS 10
125
126 // switches to fn's that log memory calls, if undefined, these are macros, so they're much faster.
127 // only turn this on if you need it.
128 #define DEBUGMEMCALLS 1
129
130 // this enables the cpucoretester.c which is runs multiple cores in parallel and tests them
131 //#define CPU_CORE_TESTER 1
132
133 // If this is enabled, it will force the Instruction Parameter Cache to be invalidated on
134 // for that address on each write to memory. This is to correct problems with self-modifying code
135 // I'm not sure whether or not there are any such problems, but it is provided as a compile itme option.
136 //#define FORCE_MEMWRITE_TO_INVALIDATE_IPC 1
137
138 // If debugging is turned on, this option can be turned on to provide a dump of the
139 // instruction cache and also the current cpu clock value when debugging is enabled.
140 // useful for extra long opcodes, and the debuggng of the 68K core.
141 #define ICACHE_DEBUG 1
142
143 // Detect procedure entry into LisaOS
144 #define PROCNAME_DEBUG 1
145
146 #endif
147 // The above options are only for DEBUG enabled compiles
148 ///////////////////////////////////////////////////////////////////////////////////////////////////////////
149
150 //-----------------------------------------------------------------------------------------------------------------------------
151
152 #ifndef IN_VARS_H
153 #define IN_VARS_H 1
154
155 #define BIT0 1
156 #define BIT1 2
157 #define BIT2 4
158 #define BIT3 8
159 #define BIT4 16
160 #define BIT5 32
161 #define BIT6 64
162 #define BIT7 128
163 #define BIT8 256
164 #define BIT9 512
165 #define BIT10 1024
166 #define BIT11 2048
167 #define BIT12 4096
168 #define BIT13 8192
169 #define BIT14 16384
170 #define BIT15 32768
171
172
173 // Allow C to call C++
174
175 #ifdef __cplusplus
176 #define CPP2C "C"
177 #else
178 #define CPP2C
179 #endif
180
181
182 // Magic Macros - allows me to get around one of C's more annoying limits
183 // global variables are generally a big no-no, but in emulators, you want
184 // to get as much performance out of things as you can, so you bend the rules.
185 //
186 // Globals accessed by other .c files need extern declarations, which is
187 // fine and great. But externs stupidly don't ignore assignments, so you
188 // can't just use a global variable file, so you wind up with a .c and a .h
189 // if these get out of sync, all sorts of evil things can happen. i.e. you
190 // delcare a variable as a uint8 in one file and a uint16 in another. When
191 // you compile, the compiler has no knowledge that one .c file expencts a
192 // byte and the other expects a word - because the two .c files have a different
193 // view of things - one has the actual variable, the other has an extern
194 // delcaration - hence, very bad things happen.
195 //
196 // Solution: we fix this by putting all the global variables in a single file
197 // this one, but use C MACRO's to allow it to turn on extern in the case of
198 // the include, and assign in the value in the case of the globals vars.c file.
199 //
200 // Neat, no?
201 //
202 // The one caveat is that C Macro's can't handle missing parameters, so we need
203 // two versions - one for when we don't assign a value (DECLARE) and one for when
204 // we do (GLOBAL). Also, we can't do this: int a,b,c - need one GLOBAL per var now.
205 //- - - - - - - - - -
206
207 ///////////////////////////////////////////////////////////////////////////////////
208 // Are we assigning a value to the variable? (and alternate default value version)
209
210
211 //#define ASSIGN(TYPE, VAR, val...) TYPE VAR= ## val // ## causes gcc 3.x preprocessor to warn
212 #define ASSIGN(TYPE, VAR, val...) TYPE VAR = val
213 #define CASSIGN(MYTYPE, MYVAR, val...) const MYTYPE MYVAR = val
214 #define NOASSIGN(TYPE, VAR) TYPE VAR
215
216 // Are we defining an extern reference to the variable?
217 #define REFERENCE(TYPE, VAR, val...) extern TYPE VAR
218 #define CREFERENCE(TYPE, VAR, val...) extern const TYPE VAR
219
220 // Doesn't matter, we can use a single macro for both, but decide which one here.
221 #ifdef IN_VARS_C
222
223 #define GLOBAL(TYPE, VAR, val...) TYPE VAR = val
224 #define DECLARE(TYPE, VAR) TYPE VAR
225 #define AGLOBAL(MYTYPE, MYVAR, val...) const MYTYPE MYVAR = val
226 #define ACGLOBAL(TYPE, VAR, val...) const TYPE VAR = val
227
228 #else
229 #define AGLOBAL REFERENCE
230 #define ACGLOBAL REFERENCE
231 #define GLOBAL REFERENCE
232 #define DECLARE REFERENCE
233 #endif
234
235
236 /////////////////////////////////////////////////////////////////////////////////
237
238
239 // include all the includes we'll (might) need (and want)
240 #include <stdio.h>
241 #include <stdlib.h>
242 #include <string.h>
243 #include <sys/types.h>
244 #include <unistd.h>
245 #include <errno.h>
246 #include <time.h>
247
248 #ifndef __MSVCRT__
249 #include <sys/mman.h>
250 #endif
251
252
253 #include "built_by.h"
254 #include "generator.h"
255 #include "registers.h"
256
257
258 // disable this - dangerous to little-endian transforms??
259 #ifdef ALIGNLONGS
260 #undef ALIGNLONGS
261 #endif
262
263
264
265 #include "z8530_structs.h"
266 #include "libdc42.h"
267
268
269 // If the Host OS has this, use it.
270 #ifndef FILENAME_MAX
271 #define FILENAME_MAX 256
272 #endif
273
274
275 /*-------------------- 2003.07.08 17:23 ------------------------
276 * hack to fix endianness under CygWin. Might not be an
277 * actuall issue with cygwin, but rather with the configure
278 * scripts that I use... *NOTE* Modifications to these must
279 * also be reflected in registers.h and generator.h!
280 * ----------------------------------------------------------*/
281
282 #ifdef PROCESSOR_INTEL
283 #undef WORDS_BIGENDIAN
284 #undef BIG_ENDIAN
285 #ifndef LITTLE_ENDIAN
286 #define LITTLE_ENDIAN 1
287 #endif
288 #undef BYTESHIGHFIRST
289 #endif
290
291 #ifdef PROCESSOR_SPARC
292 #define WORDS_BIGENDIAN 1
293 #ifndef BIG_ENDIAN
294 #define BIG_ENDIAN 1
295 #endif
296 #undef LITTLE_ENDIAN
297 #define BYTESHIGHFIRST 1
298 #endif
299
300 #ifdef __POWERPC__
301 #define BYTES_HIGHFIRST 1
302 #define WORDS_BIGENDIAN 1
303 #endif
304 #ifdef __sparc__
305 #define BYTES_HIGHFIRST 1
306 #define WORDS_BIGENDIAN
307 #endif
308 #ifdef sparc
309 #define BYTES_HIGHFIRST 1
310 #define WORDS_BIGENDIAN 1
311 #endif
312
313
314
315 #ifdef __CYGWIN__
316 #undef WORDS_BIGENDIAN
317 #undef BIG_ENDIAN
318 #ifndef LITTLE_ENDIAN
319 #define LITTLE_ENDIAN 1
320 #endif
321 #undef BYTESHIGHFIRST
322 #endif
323
324
325
326 #ifndef MIN
327 #define MIN(x,y) ( (x)<(y) ? (x):(y) )
328 #endif
329
330 #ifndef MAX
331 #define MAX(x,y) ( (x)>(y) ? (x):(y) )
332 #endif
333
334
335 #ifdef CPU_CORE_TESTER
336 extern void corecpu_get_start_masterregs(void);
337 extern void corecpu_complete_opcode(int endmmucx);
338 #endif
339
340
341 // Utility tables
342 //
343 // These are here to make certain transformation operations faster, and easier.
344 //
345 // Doesn't look like I'm using most of these, but it may be worth having them around
346 //
347 //
348 //////////////////////////////////////////////////////////////////////////////////
349
350 // given a byte, find the bit# with the highest value. return ff for 0 since
351 // no bit is set (bit0=1, bit1=2, bit2=4, bit3=8, etc.)
highest_bit_num(uint8 v)352 static inline int highest_bit_num(uint8 v)
353 {
354 unsigned int s, r = 0;
355 if (v == 0) return 0xff;
356 s = ((v & 0xf0)!=0) << 2; v >>= s; r |= s;
357 s = ((v & 0x0c)!=0) << 1; v >>= s; r |= s;
358 s = ((v & 0x02)!=0) << 0; v >>= s; r |= s;
359 return r;
360 }
361
362 // same as above but instead, return the value of the highest bit, not it's #
363 ACGLOBAL(uint8,highest_bit_val[],
364 { 0x00,0x01,0x02,0x02,0x04,0x04,0x04,0x04,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,
365 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
366 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
367 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
368 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
369 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
370 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
371 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
372 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
373 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
374 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
375 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
376 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
377 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
378 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
379 0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80
380 });
381
382 // same as above but invert the result (to save an ^0xff operation on masks)
383 ACGLOBAL(uint8,highest_bit_val_inv[],
384 { 0xff,0xfe,0xfd,0xfd,0xfb,0xfb,0xfb,0xfb,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,0xf7,
385 0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,0xef,
386 0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,
387 0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,0xdf,
388 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
389 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
390 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
391 0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,0xbf,
392 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
393 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
394 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
395 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
396 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
397 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
398 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,
399 0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f
400 });
401
402
403
404
405
406 ///////////////////////////////////// Macro Constants ////////////////////////////////////////////////////////////////////////
407
408
409
410 //////
411 // Used to decode MMU SLR
412 // 8 4 2 1
413 #define FILTR 0xf00 //(2048+1024+512+256)
414 #define SLR_MASK 0xf00 //(2048+1024+512+256) // f
415 #define SLR_RO_STK 0x400 //( 1024 ) // 4
416 #define SLR_RO_MEM 0x500 //( 1024+ 256) // 5
417 #define SLR_RW_STK 0x600 //( 1024+512 ) // 6
418 #define SLR_RW_MEM 0x700 //( 1024+512+256) // 7
419 #define SLR_IO_SPACE 0x900 //(2048+ 256) // 8
420 #define SLR_UNUSED_PAGE 0xc00 //(2048+1024) // c 1100= IO+RO (Read Only + IO)
421 #define SLR_SIO_SPACE 0xf00 //(2048+1024+512+256) // f
422
423 #define SERIAL_PORT_A_DATA 0xFCD247
424 #define SERIAL_PORT_A_CONTROL 0xFCD243
425 #define SERIAL_PORT_B_DATA 0xFCD245
426 #define SERIAL_PORT_B_CONTROL 0xFCD241
427 #define IRQ_FLOPPY 1 // run of the mill floppy IRQ's.
428 #define IRQ_VIDEO 1 // not sure if this is correct
429 #define IRQ_FDIR_ON 40 // special cases. These are for floppy fdir=1, fdir=0
430 #define IRQ_FDIR_OFF 41
431 #define IRQ_GOBYTE_0 42 // zero gobyte after some time
432
433 #define IRQ_SCC 6 // Serial port
434 #define IRQ_VIA1 2 // Keyboard/Mouse/Clock (COPS controller)
435 #define IRQ_COPS 2 // Keyboard/Mouse/Clock (COPS controller)
436 #define IRQ_VIA2 1 // Parallel Port VIA
437 #define IRQ_SLOT0 5 // Expasion Slot IRQ's
438 #define IRQ_SLOT1 4
439 #define IRQ_SLOT2 3
440
441
442
443
444 /*
445 * 7 NMI - Highest Priority *
446 * 6 RS-232 Ports *
447 * 5 Expansion Slot 0 *
448 * 4 Expansion Slot 1 *
449 * 3 Expansion Slot 2 *
450 * 2 Keyboard *
451 * 1 All other internal interrupts -- lowest priority *
452 * *
453 * Reset: Initial SSP $000000 0 *
454 * Reset: Initial PC $000004 1 *
455 * Bus Error: $000008 2 *
456 * Address Error: $00000C 3 *
457 * Illegal Instruction: $000010 4 *
458 * Zero Divide: $000014 5 *
459 * CHK Instruction: $000018 6 *
460 * TRAPV Instruction: $00001C *
461 * Privilidge Violation: $000020 *
462 * Trace: $000024 *
463 * Unimplemented Instruction 1010 $000028 *
464 * Unimplemented Instruction 1111 $00002C *
465 * Reserved/Unassigned: $000030 - $00005F *
466 * Spurious Interrupt: $000060 24 *
467 * Other Internal Interrupt: $000064 *
468 * Keyboard Interrupt: $000068 1a/26 *
469 * Slot 2 Autovector: $00006C 1b/27 *
470 * Slot 1 Autovector: $000070 1c/28 *
471 * Slot 0 Autovector: $000074 1d/29 *
472 * RS-232 Interrupt $000078 1e/30 *
473 * Non-Maskable Interrupt: $00007C 1f/31 *
474 * Trap Instruction Vectors: $000080 - $000BF *
475 * Reserved, Unassigned: $0000C0 - $000Cf *
476 * User Interrupt Vectors: $000100 - $003FF *
477
478 */
479
480 // this must be a power of 2 under 65536 and huge! This is the size of the Interrupt Queue Ring buffer.
481 // since the lisa can shut off interrupts, we need this to be huge.
482 //////////////////////////////////////////////////////////////////////////////////////////////////////////
483 #define MAXIRQQUEUE 64
484
485
486 // *** WARNING Make sure you copy the above to vars.c as
487 // it does not include vars.h
488 #define PROFILE_IMG_HEADER_SIZE 2048
489
490 /* Defines for the Via 6522 code -- MMU needs these to decypher the register accessed. */
491 // Expansion Port Slots. PARPORTVER is the ROM version number.
492 #define PARPORTVER {0x00,01,00,07}
493 #define V0HVIA1BASE 0xFC2000
494 #define V0LVIA1BASE 0xFC2800
495 #define V1HVIA1BASE 0xFC4000
496 #define V1LVIA1BASE 0xFC4800
497 #define V2HVIA1BASE 0xFC8000
498 #define V2LVIA1BASE 0xFC8800
499
500 /* Definitions for VIA 1 -- COPS */
501 #define VIA1BASE 0xFCDD80 /* Base address of VIA 1 */
502
503 // VIA1 registers are on the odd addresses in increments of 2.
504 #define ORB1 ((0*2)+1) /* Port B output Register */
505 #define IRB1 ((0*2)+1)
506 #define ORA1 ((1*2)+1) /* Port A output Register */
507 #define IRA1 ((1*2)+1)
508 #define DDRB1 ((2*2)+1) /* Port B Data Direction Register */
509 #define DDRA1 ((3*2)+1) /* Port A Data Direction Register */
510 #define T1CL1 ((4*2)+1)
511 #define T1CH1 ((5*2)+1)
512 #define T1LL1 ((6*2)+1) /* Low Order T1 Latch */
513 #define T1LH1 ((7*2)+1) /* High Order T1 Latch */
514 #define T2CL1 ((8*2)+1) /* Low Order T2 Counter */
515 #define T2CH1 ((9*2)+1) /* Low Order T2 Counter */
516 #define SR1 ((10*2)+1)
517 #define ACR1 ((11*2)+1)
518 #define PCR1 ((12*2)+1)
519 #define IFR1 ((13*2)+1)
520 #define IER1 ((14*2)+1)
521 #define ORANH1 ((15*2)+1)
522 #define IRANH1 ((15*2)+1)
523
524
525 #define VVIA2BASE 0xFCD900 /* Base address of VIA 2 */
526
527 /* Definitions for VIA 2 -- Parallel Port */
528 // VIA2 registers are on the odd addresses in increments of 8.
529 #define ORB2 ((0*8)+1)
530 #define IRB2 ((0*8)+1)
531 #define ORA2 ((1*8)+1)
532 #define IRA2 ((1*8)+1)
533 #define DDRB2 ((2*8)+1)
534 #define DDRA2 ((3*8)+1)
535 #define T1CL2 ((4*8)+1)
536 #define T1CH2 ((5*8)+1)
537 #define T1LL2 ((6*8)+1)
538 #define T1LH2 ((7*8)+1)
539 #define T2CL2 ((8*8)+1)
540 #define T2CH2 ((9*8)+1)
541 #define SR2 ((10*8)+1)
542 #define ACR2 ((11*8)+1)
543 #define PCR2 ((12*8)+1)
544 #define IFR2 ((13*8)+1)
545 #define IER2 ((14*8)+1)
546 #define ORANH2 ((15*8)+1)
547 #define IRANH2 ((15*8)+1)
548
549
550 #define ORB 0
551 #define IRB 0
552 #define ORA 1
553 #define IRA 1
554 #define DDRB 2
555 #define DDRA 3
556 #define T1CL 4
557 #define T1CH 5
558 #define T1LL 6
559 #define T1LH 7
560 #define T2CL 8
561 #define T2CH 9
562 #define SHIFTREG 10
563 #define ACR 11
564 #define PCR 12
565 #define IFR 13
566 #define IER 14
567 #define ORANH 15
568 #define IRANH 15
569
570 // Shadow of T2
571 #define T2LL 16
572 #define T2LH 17
573
574 // Shadows of I/O regs
575 #define IRAA 18
576 #define ORAA 19
577 #define IRBB 20
578 #define ORBB 21
579
580
581 // Paralell port VIA PORT B bit definitions
582 #define OCDLine_BIT 1
583 #define BSYLine_BIT 2
584 #define DENLine_BIT 4
585 #define RRWLine_BIT 8
586 #define CMDLine_BIT 16
587 #define PARITY_BIT 32
588 #define DSK_DIAG_BIT 64
589 #define CTRL_RES_BIT 128
590
591 // if all are cleared, clear bit 7 else set it
592 //if (via[2].via[IER] & via[2].via[IFR] & 0x7f) via[2].via[IFR] |=0x80; // if any actively on, bit 7 is on.
593
594 #define FIX_VIA_IFR(vianum) { \
595 if ( via[vianum].via[IFR] & 127) via[vianum].via[IFR]|=128; \
596 else via[vianum].via[IFR]=0; \
597 }
598
599 #define FIX_VIAP_IFR() { \
600 if ( V->via[IFR] & 127) V->via[IFR]|=128; \
601 else V->via[IFR]=0; \
602 }
603
604 #define IS_PARALLEL_PORT_ENABLED(vianum) (profile_power & (1<<(vianum-2)) )
605
606
607 #define VIA_IRQ_BIT_CA2 1 // cleared by read/write of reg1 (ora) unless CA2/CB2 in PCR set as independent irq - only writing to ifr will then clear it
608 #define VIA_IRQ_BIT_CA1 2 // cleared by read or write reg 1
609 #define VIA_IRQ_BIT_SR 4 // cleared by read/write of shift register
610 #define VIA_IRQ_BIT_CB2 8 // cleared by read or write orb - except if PCR sets it as independent IRQ like ca2
611 #define VIA_IRQ_BIT_CB1 16 // cleared by read/write orb
612 #define VIA_IRQ_BIT_T2 32 // read t2 low or write t2 high clears it
613 #define VIA_IRQ_BIT_T1 64 // read t1 low or wite t1 high clears it
614 #define VIA_IRQ_BIT_SET_CLR_ANY 128 // only cleared when all other IRQ's are cleared.
615
616 /* Timer ID's */
617 #define CYCLE_TIMER_VIAn_T1_TIMER(x) ((x) )
618 #define CYCLE_TIMER_VIAn_T2_TIMER(x) ((x)+128)
619 #define CYCLE_TIMER_VIAn_SHIFTREG(x) ((x)+64 )
620
621
622 #define CYCLE_TIMER_VIA1_T1_TIMER (1 )
623 #define CYCLE_TIMER_VIA1_T2_TIMER (1+128)
624 #define CYCLE_TIMER_VIA1_SHIFTREG (1+64 )
625
626 #define CYCLE_TIMER_VIA2_T1_TIMER (2 )
627 #define CYCLE_TIMER_VIA2_T2_TIMER (2+128)
628 #define CYCLE_TIMER_VIA2_SHIFTREG (2+64 )
629
630 #define CYCLE_TIMER_VIA3_T1_TIMER (3 )
631 #define CYCLE_TIMER_VIA3_T2_TIMER (3+128)
632 #define CYCLE_TIMER_VIA3_SHIFTREG (3+64 )
633
634 #define CYCLE_TIMER_VIA4_T1_TIMER (4 )
635 #define CYCLE_TIMER_VIA4_T2_TIMER (4+128)
636 #define CYCLE_TIMER_VIA4_SHIFTREG (4+64 )
637
638 #define CYCLE_TIMER_VIA5_T1_TIMER (5 )
639 #define CYCLE_TIMER_VIA5_T2_TIMER (5+128)
640 #define CYCLE_TIMER_VIA5_SHIFTREG (5+64 )
641
642 #define CYCLE_TIMER_VIA6_T1_TIMER (6 )
643 #define CYCLE_TIMER_VIA6_T2_TIMER (6+128)
644 #define CYCLE_TIMER_VIA6_SHIFTREG (6+64 )
645
646 #define CYCLE_TIMER_VIA7_T1_TIMER (7 )
647 #define CYCLE_TIMER_VIA7_T2_TIMER (7+128)
648 #define CYCLE_TIMER_VIA7_SHIFTREG (7+64 )
649
650 #define CYCLE_TIMER_VIA8_T1_TIMER (8 )
651 #define CYCLE_TIMER_VIA8_T2_TIMER (8+128)
652 #define CYCLE_TIMER_VIA8_SHIFTREG (8+64 )
653
654 #define CYCLE_TIMER_VERTICAL_RETRACE (11 )
655 #define CYCLE_TIMER_COPS_MOUSE_IRQ (12 )
656 #define CYCLE_TIMER_COPS_CLOCK_DSEC (13 )
657 #define CYCLE_TIMER_FDIR (14 )
658
659 #define CYCLE_TIMER_Z8530 (15 )
660
661 #define CYCLE_TIMER_SCC_B_XMT_BUF_EMPTY (16+0 ) // Z8530 Channel B Transmit Buffer Empty
662 #define CYCLE_TIMER_SCC_B_EXT_STAT_CHG (16+1 ) // Z8530 Channel B External/Status Change
663 #define CYCLE_TIMER_SCC_B_RCVD_CHAR (16+2 ) // Z8530 Channel B Receive Character Avail
664 #define CYCLE_TIMER_SCC_B_SPECIAL (16+3 ) // Z8530 Channel B Special Receive Condition
665
666 #define CYCLE_TIMER_SCC_A_XMT_BUF_EMPTY (20+0 ) // Z8530 Channel A Transmit Buffer Empty
667 #define CYCLE_TIMER_SCC_A_EXT_STAT_CHG (20+1 ) // Z8530 Channel A External/Status Change
668 #define CYCLE_TIMER_SCC_A_RCVD_CHAR (20+2 ) // Z8530 Channel A Receive Character Avail
669 #define CYCLE_TIMER_SCC_A_SPECIAL (20+3 ) // Z8530 Channel A Special Receive Condition
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686 ///////////////////////////////////////////////// Type definitions /////////////////////////////////////////////////
687 //
688 // 64 bit values might not be available on all host systems. They seem to be define on modern ones, although I've
689 // noticed buggy/limited support for them when using shift operations. However, as long as addition/substraction
690 // and multiplication works, and they're built in to your CPU, they can be used to gain an advantage with the timer
691 // code. int32's can also be used by the timer code, however they will cause a slowdown every 5 minutes of guest
692 // runtime, and at every event as the timers are checked for overflow.
693 //
694 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
695 #ifndef int64
696 #define int64 int64_t
697 #define USE64BITTIMER 1
698 #endif
699 #define USE64BITTIMER 1
700
701
702 // HALF_CLK needs to be the highest bit we can go before the value becomes negative. i.e. for 32 bit values, bit 30.
703 // for 64 bit values, bit 62 (since the msb is the sign bit)
704 //
705 //------------------------------------------------------------------------------------------------------------------------
706 //
707 // I'd love to change these to int64's and HALF_CLK to (1<<62), however, it seems 64 bit shifts are a bit buggy at the moment
708 // on Linux IA32 with debian gcc 4.0.3-1
709
710 //#ifdef XXBROKENXX
711 #ifdef USE64BITTIMER
712 // 0123456789012345 - careful, want to use 1<<62 however, found bugs in shifting with gcc 4!
713 #define HALF_CLK (0x4000000000000000)
714 #define XTIMER int64
715 // #define prevent_clk_overflow_now(x) {1}
716 // #define prevent_clk_overflow(x) {1}
717 #define USING64BITTIMER 1
718
719 #else
720
721 #define HALF_CLK (1<<30)
722 #define XTIMER int32
723 #define CLKDIV2(x) ((x)>>=1)
724 //#define CLKDIV2(x) ((x)/=2)
725 extern void prevent_clk_overflow_now(void);
726
727 #endif
728
729 extern void init_ipct_allocator(void);
730
731 GLOBAL(uint8,*lisaram,NULL); // pointer to Lisa RAM
732
733
734
735 // this enables a hack that tricks the lisa into skipping the full ram test, thus speeding up
736 // the boot process - this sets a PRAM variable saying RAM test is done.
737 GLOBAL(int,cheat_ram_test,1);
738 GLOBAL(int,romless,0);
739
740 // othe globally saved defaults
741 GLOBAL(int,sound_effects_on,1);
742 GLOBAL(int,profile_power,127);
743 DECLARE(int,hide_host_mouse);
744 DECLARE(int,skins_on);
745 DECLARE(int,skins_on_next_run);
746 DECLARE(int,lisa_ui_video_mode);
747 DECLARE(uint32,refresh_rate);
748 DECLARE(uint32,refresh_rate_used);
749
750
751 typedef uint8 lisa_mem_t; /* type indicator for the above #defines for use with fn's */
752
753 typedef struct
754 {
755 uint32 size;
756 uint8 *buffer;
757 uint32 start;
758 uint32 end;
759 } FLIFLO_QUEUE_t;
760
761 typedef struct
762 {
763 int16 x;
764 int16 y;
765 int8 button; // 0=no click change, 1=down, -1=up.
766 } mousequeue_t;
767
768
769
770
771 typedef struct
772 {
773 int8 Command; // what command is the profile doing:
774 // -1=disabled, -2=idle, 1=read, 2=write, 3=write verify
775 //
776 uint8 StateMachineStep; // what step of Command is the state machine of this profile in?
777
778 uint8 DataBlock[4+8+532+8+2]; // 4 status bytes, command block, data block, 2 for good luck ;)
779
780 uint16 indexread; // indeces into the buffer for the Lisa to Read or Write
781 uint16 indexwrite;
782 uint32 blocktowrite; // used by the write command to store the block number to write
783
784 //uint32 numblocks; // (24 bit value!) size of this profile in blocks.
785 // (9728=5mb, 532 bytes/sector)
786 // We shouldn't make this more than 10Mb until we've tried it.
787
788 // Control Lines from 6522 (except OCDLine which is Command=-1)
789 uint8 CMDLine; // set by Lisa
790 uint8 BSYLine; // set by ProFile
791 uint8 DENLine; // set by Lisa (drive enabled)
792 uint8 RRWLine; // set by Lisa (read or write)
793
794 uint8 VIA_PA; // data to from VIA PortA (copied to/from V->via[0])
795 uint8 last_a_accs;
796 int32 last_reset_cpuclk; // last reset occured at what cpu clock?
797
798 DC42ImageType DC42; // actual storage container
799
800 // DC42 contains the ProFilename and file handler
801 //char ProFileFileName[FILENAME_MAX]; // the file name for this Profile disk image to open;
802
803 XTIMER clock_e; // used for timeouts - this is in relation to cpu68k_clocks
804 XTIMER alarm_len_e; // used for timeouts - how long was the delay set for in clock_e event expiration
805
806
807 int vianum;
808 int last_cmd;
809 } ProFileType;
810
811
812
813
814 typedef struct
815 {
816 uint8 active; // is this VIA active? (except via1 and via2 s/b always active)
817 // make sure that the initialization code sets these anyway!!!
818
819 uint8 vianum; // Which VIA is this?
820
821 uint8 via[22]; // standard via registers + timer 2 shadows and actual IRA/ORA/IRB/IRA shadows, etc.
822
823 int last_a_accs; // was the last access to port A a read or a write? (for DDRA flips from 00 to ff)
824 // I've seen some code that writes to port A, then sets DDRA to FF, only at that point
825 // is the data put on the port. I've seen other code that does the opposite, so I need
826 // some way to distinguish what the value in PORT A is from in order to output properly
827
828 int orapending; // there are many ways to output data. some OS's set DDRA=0, then write to ORA, then
829 // set DDRA=FF to output. Others set DDRA=FF 1st, then write to ORA. When DDRA=0 and
830 // a write is made to ora, the data cannot be placed on PA, but as soon as DDRA=FF, the
831 // PA gets data out and CA2 is set. So to avoid a bug where an extra ORA is made when
832 // DDRA=FF, ORA is written, DDRA=0, then DDRA=FF, this keeps track of the pending.
833
834 XTIMER t1_e; // e_clock trigger - at what point will the via clock expire vs cpu68k_clocks
835 XTIMER t1_fired;
836 XTIMER t2_e;
837 XTIMER t2_fired;
838 XTIMER sr_e;
839 XTIMER sr_fired;
840
841 XTIMER last_pa_write; // used to find the end of print jobs
842
843 //#ifdef DEBUG
844 XTIMER t1_set_cpuclk;
845 XTIMER t2_set_cpuclk;
846 XTIMER t1_fired_cpuclk;
847 XTIMER t2_fired_cpuclk;
848 //#endif
849
850 ProFileType *ProFile; // If there's a ProFile attached, this structure deals with it.
851 int ADMP; // If there's an Apple Dot Matrix Printer (same as IW, but parallel)
852
853 uint8 irqnum; // Interrupt number for this VIA
854 uint8 srcount;
855 uint8 ca1, ca2, cb1, cb2; // port A,B control lines
856
857 uint8 (*irb)(uint8 vianum, uint8 reg); // Function Pointers to the Handlers for what's connected to the VIA's.
858 void (*orb)(uint8 vianum,uint8 data, uint8 reg);
859 uint8 (*ira)(uint8 vianum, uint8 reg);
860 void (*ora)(uint8 vianum,uint8 data, uint8 reg);
861 } viatype;
862
863 // What can I say, I'm a lazy fuck, I don't like to worry about the case of these.
864 #define ViaType viatype
865 #define VIAType viatype
866 #define VIAtype viatype
867
868 GLOBAL(int32,video_scan,0);
869
870 GLOBAL(int,lisa_vid_size_x,720);
871 GLOBAL(int,lisa_vid_size_y,364);
872 GLOBAL(int,lisa_vid_size_xbytes,90);
873 GLOBAL(int,has_lisa_xl_screenmod,0);
874
875 // used by mouse routines to detect mouse acceleration undo strategy
876 #define LISA_ROM_RUNNING 0
877 #define LISA_OFFICE_RUNNING 1
878 #define LISA_TEST_RUNNING 2
879 #define LISA_MACWORKS_RUNNING 3
880 #define LISA_MONITOR_RUNNING 4
881 #define LISA_XENIX_RUNNING 5
882 #define UNKNOWN_OS_RUNNING 100
883
884 GLOBAL(int,running_lisa_os,LISA_ROM_RUNNING);
885 int check_running_lisa_os(void);
886 GLOBAL(int,mouse_x_tolerance,0);
887 GLOBAL(int,mouse_y_tolerance,0);
888
889 GLOBAL(int,mouse_x_halfing_tolerance,1);
890 GLOBAL(int,mouse_y_halfing_tolerance,1);
891
892 // can turn these into a pointer and several arrays for various OS's.
893 GLOBAL(int,anti_jitter_sample_dec1[],{64,32,16,8,4,2,0,0,0});
894 GLOBAL(int,anti_jitter_sample_dec2[],{1,2,4,16,32,64,0,0,0});
895
896 GLOBAL(int,anti_jitter_decellerate_xt[],{8,32,64,0});
897 GLOBAL(int,anti_jitter_decellerate_xn[],{1,2,4,0});
898 GLOBAL(int,anti_jitter_decellerate_yt[],{8,32,64,0});
899 GLOBAL(int,anti_jitter_decellerate_yn[],{1,2,3,0});
900
901 //GLOBAL(int,via_port_idx_bits[],{0, 2,1, 4,3, 6,5});
902 //2, 4,3, 6,5, 8,7
903 GLOBAL(uint32,lisa_os_mouse_x_ptr,0x486);
904 GLOBAL(uint32,lisa_os_mouse_y_ptr,0x488);
905 GLOBAL(uint32,lisa_os_boot_mouse_x_ptr,0x486);
906 GLOBAL(uint32,lisa_os_boot_mouse_y_ptr,0x488);
907 GLOBAL(int8,floppy_picked,1); //2006.06.11 - if 1 enable profile access immediately
908
909 typedef struct _lisa_clock
910 {
911 uint8 year;
912 uint8 days_h;
913 uint8 days_l; uint8 hours_h;
914 uint8 hours_l; uint8 mins_h;
915 uint8 mins_l; uint8 secs_h;
916 uint8 secs_l; uint8 tenths;
917 } t_lisa_clock;
918
919 DECLARE(t_lisa_clock,lisa_clock);
920
921 GLOBAL(int32,lisa_alarm,0);
922 GLOBAL(uint8,lisa_clock_set_idx,0);
923 GLOBAL(uint8,lisa_alarm_power,0);
924 GLOBAL(uint8,lisa_clock_on,1);
925 DECLARE(uint8,eparity[256]);
926 DECLARE(uint8,lisa_clock_set[8]);
927
928 // Instruction Parameter Cache
929 typedef struct _t_ipc {
930 void (*function)(struct _t_ipc *ipc); //8/4 // pointer to the function that executes this opcode
931 uint8 used; //1 // bitmap of XNZVC flags inspected
932 uint8 set; //1 // bitmap of XNZVC flags altered
933 uint16 opcode; //2 // absolutely necessary - the opcode itself i.e. 0x4e75=RTS
934
935 uint16 wordlen; //2 // might be able to delete this if we also add nextpc, but diss68k will need work as will
936 // lots of mods of cpu68.k To get it call iib->wordlen but the illegal instruction in
937 // there needs checking.
938
939 unsigned int :0; //3 // what's this here for? alignment I suspect?
940 uint32 src; //4
941 uint32 dst; //4
942
943 // // // // // // // // // // // // // // // these are extensions to the normal generator code in order to refine it, etc.
944
945 uint16 reg; //2 // for cpu68k-inline idx_val macros/inlines replacing the bug that causes the
946 // high octet in PC (bits 31-24) to be filled, then causes negative PC on sign ext.
947 uint8 clks; //1 // might be able to remove this if I can get this from iib without too much of a slowdown - maybe
948
949 struct _t_ipc *next; //8/4 // next ipc in chain. we could get rid of this, but then things would run slower
950 // and we'd need to do a whole lot of more work to get things to work.
951 // Need to get rid of this, but have to redo stuff in cpu68k.c to do it.
952 // // // // // // // // // // // // // // // /////////////////////////////////////////////////////////////////////////////
953 } t_ipc;
954
955
956 typedef struct _t_ipc_table
957 {
958 // Pointers to all the IPC's in this page. Since the min 68k opcode is 2 bytes in size
959 // the most you can have are 256 instructions per page. We thus no longer need a hash table
960 // nor any linked list of IPC's as this is a direct pointer to the IPC. Ain't life grand?
961
962 t_ipc ipc[256]; // only need this, the rest I think is junk
963
964 // These are merged together so that on machines with 32 bit architectures we can
965 // save four bytes. It will still save 2 bytes on 64 bit machines.
966 union t
967 { uint32 clocks; // can I get rid of this one? - it's used in cpu68k.c - but can be gotten rid of
968
969 // we still use the *next pointer to keep track of IPC's.
970 struct _t_ipc_table *next; // try to get rid of these as they're not really needed, only used for free list!
971 } t;
972
973
974 #ifdef PROCESSOR_ARM
975 void (*compiled)(struct _t_ipc *ipc);
976 //uint8 norepeat; // what's this do? this only gets written to, but not read. Maybe Arm needs it?
977 #endif
978 } t_ipc_table;
979
980 //////////////////////////////////////////////////////////
981 //
982 // MMU Translation Table for page. This provides function pointers to read/write handlers as well as address translation
983 // via the address offset (signed) integer which gets added to the address.
984 //
985 // The table is an array of 256's ipc's -- if NULL it hasn't been allocated for this page. The table is a pointer to
986 // an element of a linked list of IPC tables.
987 //
988 // For a 2MB (fully loaded non-XL 4MB hacked up Lisa) you have upto: 2097152 bytes of RAM + 16384ROM -> that's
989 // upto 2113536 bytes maximum of executable code (most of it won't be executable.)
990 //
991 // In terms of 512 byte MMU pages, this is: 4128 pages. Each ipc structure takes about 32 bytes * 256/page = 8K * 4128 pages
992 // we have a maximum of 32MB (it's much smaller than this since not all of the Lisa's memory will be IPC's.)
993 // Yup, this is one memory hungry emulator.... So we need decent memory management on the MMU+ipct's.
994 //
995 // Why 256 ipc's/page? Simple: smallest 68k opcode is 2 bytes, there are 512/page, so at most there are 256 ipc's/page.
996 // But because management of these is not trivial, we allocate 256 of them per page if they're used.
997 //
998 // Note that the IPC's point to the virtual, not physical pages.
999
1000 typedef struct _mmu_trans_t
1001 { int32 address; /* quick ea translation. Just add to lower bits - needs to be signed */
1002 //uint32 sor9;
1003 lisa_mem_t readfn; /* index to read and write fn's for that segment, that way I */
1004 lisa_mem_t writefn; /* can have read only segments without doing special checking. */
1005 t_ipc_table *table; /* Pointer to a table of IPC's or NULL if one hasn't been assigned. */
1006 } mmu_trans_t;
1007
1008
1009 // Lisa's MMU table. This get's converted to mmu_trans table above on a per/page basis.
1010 typedef struct
1011 {
1012 uint16 sor, slr; // real sor, slr
1013 //uint16 newsor, newslr; // used when updating - won't change to this until both are written to.
1014 uint8 changed; // this is a flag to let us know that an mmu segment has changed.
1015 // come back later to correct it. bit 0=newslr set, bit 1=newsor set.
1016 } mmu_t;
1017
1018
1019
1020
1021
1022
1023 GLOBAL(uint8,lastsflag,0);
1024
1025 GLOBAL(uint8,floppy_FDIR,0);
1026 GLOBAL(uint8,floppy_6504_wait,1);
1027 GLOBAL(uint8,floppy_irq_top,1);
1028 GLOBAL(uint8,floppy_irq_bottom,1); // interrupt settings (are floppies allowd to interrupt)
1029 DECLARE(uint8,floppy_ram[2048]);
1030
1031 GLOBAL(uint32,mmudirty,0);
1032 DECLARE(uint32,mmudirty_all[5]);
1033
1034
1035 DECLARE(uint8,lisarom[0x4000]); // space for the MC68000 ROM
1036 DECLARE(uint8,dualparallelrom[2048]); // rom space for the dual parallel card
1037
1038 DECLARE(uint8,dirtyvidram[32768]);
1039
1040 GLOBAL(uint32,segment1,0); // MMU related bits
1041 GLOBAL(uint32,segment2,0);
1042 GLOBAL(uint32,context,0);
1043 GLOBAL(uint32,lastcontext,0);
1044
1045 GLOBAL(uint32,address32,0); // not sure that this is needed anymore
1046 GLOBAL(uint32,address,0);
1047 GLOBAL(uint32,mmuseg,0);
1048 GLOBAL(uint32,mmucontext,0);
1049 GLOBAL(uint32,transaddress,0);
1050
1051 // special memory latches toggled by i/o space addresses in the lisa.
1052 GLOBAL(uint32,diag1,0);
1053 GLOBAL(uint32,diag2,0);
1054 GLOBAL(uint32,start,1);
1055 GLOBAL(uint32,softmem,0);
1056 GLOBAL(uint32,vertical,0);
1057 GLOBAL(uint32,verticallatch,0);
1058 GLOBAL(uint32,hardmem,0);
1059 GLOBAL(uint32,videolatch,0x2f);
1060 GLOBAL(uint32,lastvideolatch,0x2f);
1061 GLOBAL(uint32,videolatchaddress,(0x2f*32768));
1062 GLOBAL(uint32,lastvideolatchaddress,0x2f*32768);
1063 GLOBAL(uint32,statusregister,0);
1064 GLOBAL(uint32,videoramdirty,0);
1065 GLOBAL(uint32,videoximgdirty,0);
1066 GLOBAL(uint16,memerror,0);
1067
1068 // hack for intermediate RC2 version - stolen from LisaCanvas.cpp as an ugly quick and dirty hack
1069 GLOBAL(int,dirty_x_min,720);
1070 GLOBAL(int,dirty_x_max,0);
1071 GLOBAL(int,dirty_y_min,364);
1072 GLOBAL(int,dirty_y_max,0);
1073
1074 GLOBAL(int,e_dirty_x_min,720);
1075 GLOBAL(int,e_dirty_x_max,0);
1076 GLOBAL(int,e_dirty_y_min,500);
1077 GLOBAL(int,e_dirty_y_max,0);
1078
1079 // hack for intermediate RC2 version - stolen from LisaCanvas.cpp as an ugly quick and dirty hack
1080
1081
1082
1083 GLOBAL(uint8,contrast,0xff); // 0xff=black 0x80=visible 0x00=all white
1084 GLOBAL(uint8,volume,4); // 0x0e is the mask for this.
1085 GLOBAL(long,*dtc_rom_fseeks,NULL);
1086 GLOBAL(FILE,*rom_source_file,NULL);
1087
1088 GLOBAL(int,debug_log_enabled,0);
1089 GLOBAL(FILE,*buglog,NULL);
1090
1091 #ifdef DEBUG
1092 #ifdef DEBUG_ON_SCREENHASH
1093 GLOBAL(uint8,debug_hash[],DEBUG_ON_SCREENHASH);
1094 #endif
1095 #ifdef DEBUG_OFF_SCREENHASH
1096 GLOBAL(uint8,debug_hash_off[],DEBUG_OFF_SCREENHASH);
1097 #endif
1098 #endif
1099
1100
1101
1102
1103 // hexadecimal conversion table table.
1104 ACGLOBAL(char,*hex,"0123456789abcdef");
1105
1106
1107
1108 /****************** COPS.C definitions/vars visible to outside world... ************************************/
1109
1110 #define MAXCOPSQUEUE 512
1111 #define MAXMOUSEQUEUE 16
1112
1113 GLOBAL(int16,copsqueuelen,0);
1114 DECLARE(uint8,copsqueue[MAXCOPSQUEUE]);
1115 GLOBAL(uint8, NMIKEY,0);
1116 GLOBAL(uint8, cops_powerset,0);
1117 GLOBAL(uint8, cops_clocksetmode,0);
1118 GLOBAL(uint8, cops_timermode,0);
1119 GLOBAL( int8, mouse_pending,0);
1120 GLOBAL( int8, mouse_pending_x,0);
1121 GLOBAL( int8, mouse_pending_y,0);
1122 GLOBAL(int16, last_mouse_x,0);
1123 GLOBAL(int16, last_mouse_y,0);
1124 GLOBAL(int16, last_mouse_button,0);
1125 GLOBAL(int16, mousequeuelen,0);
1126 DECLARE(mousequeue_t,mousequeue[MAXMOUSEQUEUE]);
1127
1128
1129 // How many percent of the current IPCT's should we allocate. ** MUST MATCH WHAT'S IN vars.c!!!!!!! ***
1130 #define IPCT_ALLOC_PERCENT 20
1131
1132 // What's the maximum time's we'll call malloc?
1133 #define MAX_IPCT_MALLOCS 8
1134
1135 // we should never need to even do more than the initial malloc if initial_ipcts=4128.
1136 DECLARE(t_ipc_table,*ipct_mallocs[MAX_IPCT_MALLOCS]);
1137
1138 // size of each of the above mallocs - not really needed, but could be useful for debugging.
1139 DECLARE(uint32,sipct_mallocs[MAX_IPCT_MALLOCS]);
1140
1141 DECLARE(t_ipc_table,*ipct_mallocs[MAX_IPCT_MALLOCS]);
1142 DECLARE(uint32,sipct_mallocs[MAX_IPCT_MALLOCS]);
1143 GLOBAL(uint32,iipct_mallocs ,0);
1144 GLOBAL(uint32,ipcts_allocated,0);
1145 GLOBAL(uint32,ipcts_used,0);
1146 GLOBAL(uint32,ipcts_free,0);
1147 GLOBAL(t_ipc_table,*ipct_free_head,NULL);
1148 GLOBAL(t_ipc_table, *ipct_free_tail,NULL);
1149
1150 /* (2MB RAM max+ 16KROM)=2113536 bytes of potentially executable code divided by 512(bytes/mmu page) = 4128
1151 * ipc's page = maximum= 8256 ipct's is maximum - should not have to go above this ever.
1152 * this value is only for testing, until we test the LisaEM under heavy load to find the actual used number of ipct's
1153 * and lessen it to free things up. remember, each ipct holds 256 ipcs plus extra info. */
1154 GLOBAL(uint32,initial_ipcts,4128);
1155
1156 // 212,179 ->missing 18 lines! 18 lines is the entire retrace cycle!
1157
1158 #define CYCLES_PER_LINE (212) //was212 //213 /* (720+176)/(20.375Mhz/5Mhz) .. =219.87 was 224*/
1159 #define VISIBLE_LINE_CYCLES (179) //180
1160 #define FULL_FRAME_CYCLES (CYCLES_PER_LINE*364) //-4330) /* 364 lines visible -17 added 2005.04.14 10:51am */
1161 #define HALF_FRAME_CYCLES (FULL_FRAME_CYCLES/2)
1162 #define QUARTER_FRAME_CYCLES (FULL_FRAME_CYCLES/4)
1163 //#define VERT_RETRACE_ON (450) //450 //-VERT_RETRACE_ON-250
1164 #define VERT_RETRACE_CYCLES_X ((CYCLES_PER_LINE*(380-364))) //-VERT_RETRACE_ON) //-VERT_RETRACE_ON) //2005.05.04 - change it to 16 was 15 /* 15 retrace lines */
1165 #define VERT_RETRACE_ON (VERT_RETRACE_CYCLES_X/2)
1166 #define VERT_RETRACE_CYCLES (VERT_RETRACE_CYCLES_X/2)
1167
1168 #define ONE_SECOND 5000000
1169 //#define ONE_SECOND 5093750
1170
1171 #define COPS_IRQ_TIMER_FACTOR 20375 // was 20000
1172 #define THIRTY_SECONDS (ONE_SECOND*30)
1173 #define TWENTY_SECONDS (ONE_SECOND*20)
1174 #define FIFTEEN_SECONDS (ONE_SECOND*15)
1175 #define TEN_SECONDS (ONE_SECOND*10)
1176 #define FIVE_SECONDS (ONE_SECOND*5)
1177 #define MILLIONTH_OF_A_SECOND (ONE_SECOND/1000000)
1178 #define HUN_THOUSANDTH_OF_A_SEC (ONE_SECOND/100000)
1179 #define TEN_THOUSANDTH_OF_A_SEC (ONE_SECOND/10000)
1180 #define THOUSANDTH_OF_A_SECOND (ONE_SECOND/1000)
1181 #define HUNDREDTH_OF_A_SECOND (ONE_SECOND/100)
1182 #define TENTH_OF_A_SECOND (ONE_SECOND/10)
1183
1184 #define HALF_OF_A_SECOND (ONE_SECOND/2)
1185 #define THIRD_OF_A_SECOND (ONE_SECOND/3)
1186 #define QUARTER_OF_A_SECOND (ONE_SECOND/4)
1187 #define FIFTH_OF_A_SECOND (ONE_SECOND/5)
1188 #define EIGHTH_OF_A_SECOND (ONE_SECOND/8)
1189
1190 #define REFRESHRATE (ONE_SECOND/60)
1191
1192 // old versions of above - likely wrong
1193 //#define FULL_FRAME_CYCLES 65520
1194 //#define HALF_FRAME_CYCLES 32760
1195 //#define QUARTER_FRAME_CYCLES 16380
1196 //#define VERT_RETRACE_CYCLES 2700
1197 //#define COPS_IRQ_TIMER_FACTOR 20000
1198 //#define HUNDRETH_OF_A_SECOND 50000
1199 //#define TENTH_OF_A_SECOND 500000
1200 //#define ONE_SECOND 5000000
1201
1202 // number of CPU cycles between transmitting a character of the SCC and the count zero interrupt.
1203 #define Z8530_XMIT_DELAY 1000
1204
1205 GLOBAL(XTIMER,lastrefresh,0);
1206 GLOBAL(XTIMER,virq_start,FULL_FRAME_CYCLES);
1207 GLOBAL(XTIMER,fdir_timer,-1);
1208 GLOBAL(XTIMER,cpu68k_clocks_stop,ONE_SECOND);
1209 GLOBAL(XTIMER,cpu68k_clocks,0);
1210 GLOBAL(XTIMER,lasttenth,0);
1211 GLOBAL(XTIMER,clktest,0);
1212 GLOBAL(XTIMER,cops_event,-1);
1213 GLOBAL(XTIMER,tenth_sec_cycles,TENTH_OF_A_SECOND); // 10th of a second cycles. 5,000,000 cycles/sec so 500000 10ths/sec
1214 GLOBAL(XTIMER,z8530_event,-1);
1215 GLOBAL(XTIMER,cops_mouse,(COPS_IRQ_TIMER_FACTOR*4));
1216
1217
1218
1219 #define KBCOPSCYCLES 6350
1220 // if mouse is enabled, next clock event is cops_mouse.
1221 // if copsqueuelen - that means we have data, and either cops event is off, or it's further
1222 // away, then set it closer.
1223
1224
1225 #define SET_COPS_NEXT_EVENT(x) { cops_event=(cops_mouse ? (cpu68k_clocks+cops_mouse):-1); \
1226 if (copsqueuelen>0 && ((cops_event>(cpu68k_clocks+KBCOPSCYCLES)) || cops_event<0)) \
1227 cops_event=cpu68k_clocks+KBCOPSCYCLES; \
1228 DEBUG_LOG(0,"SET_COPS_NEXT:copsqueuelen:%d cops_mouse:%ld cops_event:%016llx cpu68k_clk:%016llx \n", \
1229 copsqueuelen,cops_mouse, cops_event, cpu68k_clocks); \
1230 }
1231
1232
1233 // ***** still need logic for when cops_event=-1 but there's now data to deal with
1234 // i.e. need to make sure timer is turned on. likely can change the send macro to check
1235 //
1236 //if (cops_event<0) SET_COPS_NEXT_EVENT(0);
1237
1238
1239 GLOBAL(uint32,via_clock_diff,2); // 2
1240
1241 // These should be external as they belong to generator
1242 #ifndef IN_CPU68K_C
1243 extern unsigned long cpu68k_frames;
1244 extern unsigned long cpu68k_frozen;
1245 extern int abort_opcode;
1246 #ifdef DEBUG
1247 extern int do_iib_check;
1248
1249 #endif
1250 #endif
1251
1252 // recheck these for correctness!
1253
1254 // 0x3100=12544
1255 // X = 100000/12544 [7.97193877551]
1256 // Hmmm, seems it's better to use 8 as a timing factor
1257 GLOBAL(float,via_throttle_factor,1.0);
1258
1259 // something is broken with the VIA timing, no matter what I do with it, the clock is still skewed.
1260 #ifdef TIE_VIA_TIMER_TO_HOST
1261
1262 #define LISA2ECLKFACTOR (XTIMER)((float)10*(via_throttle_factor)) // 10 //( 7.750950) //8.117647058825 //.11764705882=5,5 83=5,7 //.1176470588=5,5 .1176470589=5,7 .117647058[7|5]=5,5 585=5,5 57=5,5 9=5,7 //.117647055=5,5 .11764706[5|3|1]=5,7 .11764706=5,7 .11764707=5,7 .11764705=5,5 .1176471=5,7 72=5,7 .1176470=5,5 .117647[3|5]=5,7 //.117648=5,7 //.117647=5,5 //.117649=5,7 //117645=5,5 //1176[3/4]=5,5 //1165=5,7// 1176=5,5 //.1178/7=5,7 // 1175=5,5 //118=5,7 //117=5,5 //.119=5,7 // 8.113/114/115=5,5 // 8.11=5,5 // 8.12=5,7 // 8.16,14=5,7// 8.18=5,7 // 8.20=5,7 // 8.1=5,5 //8.0=5,5 // 8.3 5,7 // 8.25=5,7 // 8.2=5,7 // 8.1=7,5 // 9 5,7 //7.9=5,5 //8=5.5 //7.8=5.5 //8 // 10 // 8
1263 #define LISA1ECLKFACTOR (XTIMER)((float)4 *(via_throttle_factor)) //( 3.263358)
1264
1265 #else
1266
1267 #define LISA2ECLKFACTOR 10 // 10 //( 7.750950) //8.117647058825 //.11764705882=5,5 83=5,7 //.1176470588=5,5 .1176470589=5,7 .117647058[7|5]=5,5 585=5,5 57=5,5 9=5,7 //.117647055=5,5 .11764706[5|3|1]=5,7 .11764706=5,7 .11764707=5,7 .11764705=5,5 .1176471=5,7 72=5,7 .1176470=5,5 .117647[3|5]=5,7 //.117648=5,7 //.117647=5,5 //.117649=5,7 //117645=5,5 //1176[3/4]=5,5 //1165=5,7// 1176=5,5 //.1178/7=5,7 // 1175=5,5 //118=5,7 //117=5,5 //.119=5,7 // 8.113/114/115=5,5 // 8.11=5,5 // 8.12=5,7 // 8.16,14=5,7// 8.18=5,7 // 8.20=5,7 // 8.1=5,5 //8.0=5,5 // 8.3 5,7 // 8.25=5,7 // 8.2=5,7 // 8.1=7,5 // 9 5,7 //7.9=5,5 //8=5.5 //7.8=5.5 //8 // 10 // 8
1268 #define LISA1ECLKFACTOR 4 //( 3.263358)
1269
1270 #endif
1271 //#define LISA1ECLKFACTOR (24.117647058825) //24.117647058825 //.11764705882=5,5 83=5,7 //.1176470588=5,5 .1176470589=5,7 .117647058[7|5]=5,5 585=5,5 57=5,5 9=5,7 //.117647055=5,5 .11764706[5|3|1]=5,7 .11764706=5,7 .11764707=5,7 .11764705=5,5 .1176471=5,7 72=5,7 .1176470=5,5 .117647[3|5]=5,7 //.117648=5,7 //.117647=5,5 //.117649=5,7 //117645=5,5 //1176[3/4]=5,5 1165=5,7// 1176=5,5 //.1178/6=5,7 // 1175=5,5 //118=5,7 //117=5,5 // //24.113/114/115=5,5//24.11=,5 //24.12=5,7 //24.16,14=5,7 //24.18=5.7//24.20=5,7 //24.1=5,5 //24.0=5,5 24.3 5,7 //24.25=5,7 // 24.2=5,7 //24.1=7,5 //25 5,7 //23.9=5,5 //24=5.5 //23.8=5.5 //23.3=err 5 //23 // 25 // 20 needs to be 22.5 or 7.5
1272 // above might need to be fractional?
1273
1274
1275 // 5Mhz / 10 = 500Khz every 10 cpu cycles
1276 // 5Mhz /4 = 1.25Mhz every 4 cpu cycles
1277 //
1278 #define VIACLK_TO_CPUCLK(X) ( ((floppy_ram[0x18]&96)==32) ? ((X)*(XTIMER)(LISA2ECLKFACTOR)) :((X)*(XTIMER)(LISA1ECLKFACTOR)))
1279 #define CPUCLK_TO_VIACLK(X) ( ((floppy_ram[0x18]&96)==32) ? ((X)/(XTIMER)(LISA2ECLKFACTOR)) :((X)/(XTIMER)(LISA1ECLKFACTOR)))
1280
1281
1282 // How many microseconds should lisaem sleep between emulation cycles. This allows us to slow down the emulator
1283 // so that we can either get an acurate 5MHz clock, or be nice to the host OS. This is implemented using poll with
1284 // a null handle as per poll's man page. The value of microsleep_tix is global so that it may be adjusted elsewhere
1285 // in the code on the fly, as needed, perhaps it can be raised during I/O and idle mouse times.
1286 #ifdef DEBUG
1287 GLOBAL(int,microsleep_tix,0);
1288 #else
1289 GLOBAL(int,microsleep_tix,0);
1290 #endif
1291
1292 // Scotty: Captain, we din' can reference it!
1293 // Kirk: Analysis, Mr. Spock?
1294 // Spock: Captain, it doesn't appear in the symbol table.
1295 // Kirk: Then it's of external origin?
1296 // Spock: Affirmative.
1297 // Kirk: Mr. Sulu, go to pass two.
1298 // Sulu: Aye aye, sir, going to pass two.
1299
1300
1301
1302 /*
1303 * But wait, there is mad to my method and reason! Read on gentle hacker. Here's the explanation.
1304 *
1305 * For sooth, thou shalt learneth...
1306 *
1307 * You see, C depends on variable and prototype declarations to know whether they be externed, to know the proper number and
1308 * types of parameters and return type of said functions. If it does not know the proper types, it will warn, however, if the
1309 * prototype for a given function is incorrect, you can expect a maladjusted stack, and bad things will certainly happen.
1310 *
1311 * Having header files solves this - except it introduces another snag. Should your header file delcare parameters differently
1312 * (aka incorrectly) than your .c file, you can expect warnings neither from gcc, nor from ld, which cannot know that this has
1313 * occured.
1314 *
1315 * One way to test for this is to include your header file into your C file, *BUT* this will not work from extern'ed functions.
1316 * gcc will complain about "conflicting types for...." and "previous declaration..." indicating a bug. But you cannot use this
1317 * to self check your headers... so what to do? what to do?
1318 *
1319 * Another way is to use a program that automatically builds header files, but, meh - why would you want to have all your fn's
1320 * in a header file?
1321 *
1322 * Well, if you like Macro's, (and what good C programmer doesn't?) then the answer is clear. Define a Macro to resolve as
1323 * extern when it should, and null when it shouldn't. Easy as pie.
1324 *
1325 * I ran across this issue when I added several parameters to a function that I forgot was used externally in other code.
1326 * The program compiled just fine, and crashed beautifully. gdb was able to solve the issue, but I thought I'd kill it for
1327 * good. Always, always, always, program defensively.
1328 *
1329 *
1330 *
1331 */
1332
1333 #ifdef EXTERNX
1334 #undef EXTERNX
1335 #endif
1336 #ifndef IN_FLIFLO_QUEUE_C
1337 #define EXTERNX extern
1338 #else
1339 #define EXTERNX ;
1340 #endif
1341 EXTERNX int fliflo_buff_is_full(FLIFLO_QUEUE_t *b);
1342 EXTERNX int fliflo_buff_has_data(FLIFLO_QUEUE_t *b);
1343 EXTERNX int fliflo_buff_is_empty(FLIFLO_QUEUE_t *b);
1344 EXTERNX uint32 fliflo_buff_size(FLIFLO_QUEUE_t *b);
1345 EXTERNX uint32 fliflo_buff_percent_full(FLIFLO_QUEUE_t *b);
1346 EXTERNX int fliflo_buff_add(FLIFLO_QUEUE_t *b,uint8 data);
1347 EXTERNX uint8 fliflo_buff_pop(FLIFLO_QUEUE_t *b);
1348 EXTERNX uint8 fliflo_buff_get(FLIFLO_QUEUE_t *b);
1349 EXTERNX uint8 fliflo_buff_peek(FLIFLO_QUEUE_t *b);
1350 EXTERNX uint8 fliflo_buff_peek_end(FLIFLO_QUEUE_t *b);
1351 EXTERNX int fliflo_buff_create(FLIFLO_QUEUE_t *b, uint32 size);
1352 EXTERNX void fliflo_buff_destroy(FLIFLO_QUEUE_t *b);
1353
1354 //extern void alertlog(char *alert);
1355
1356 //#endif
1357
1358 #define UI_LOG( level, fmt, args... ) {fprintf(buglog,"%s:%s:%d: ",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog, fmt , ## args); fprintf(buglog,"\n");fflush(buglog);}
1359
1360 DECLARE(char,_msg_alert[1024]);
1361 DECLARE(char,_msg_alert2[1024]);
1362
1363
1364 #ifdef DEBUG
1365
1366 extern void dumpmmu(uint8 c, FILE *out);
1367 extern void dumpmmupage(uint8 c, uint8 i, FILE *out);
1368
1369
1370
1371
1372 /*define check_iib() {my_check_iib(__FILE__,__FUNCTION__,__LINE__);}
1373 ifndef IN_CPU68K_C
1374 extern void my_check_iib(char *filename, char *function, long line);
1375 endif
1376 */
1377 #define check_iib() {;}
1378
1379
1380 // do full iib sanity check
1381 //#define DEBUG_LOG( level, fmt, args... ) { if ( level <= DEBUGLEVEL ) {fprintf(buglog,"%s:%s:%d: ",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog, fmt , ## args); fprintf(buglog,"\n"); fflush(buglog);if (do_iib_check) my_check_iib(__FILE__,__FUNCTION__,__LINE__);} }
1382 // don't do iib sanity check - speed things up
1383
1384 #define DEBUG_LOG( level, fmt, args... ) { if ( (level <= DEBUGLEVEL) && debug_log_enabled) \
1385 {fprintf(buglog,"%s:%s:%d:",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog, fmt , ## args); \
1386 fprintf(buglog,"\n"); fflush(buglog); fflush(stdout);} }
1387
1388 /*
1389 if (mmu_trans!=mmu_trans_all[context] || mmu!=mmu_all[context] || (start && context))
1390 { fprintf(buglog,"\n\n\nBUGCHK: context:%d start:%d seg1/2:%d/%d\n",context,start,segment1,segment2);
1391 fprintf(buglog,"BUGCHK: mmu_trans=%p [0]=%p [1]=%p [2]=%p [3]=%p [4]=%p\n", mmu_trans,mmu_trans_all[0],mmu_trans_all[1],mmu_trans_all[2],mmu_trans_all[3],mmu_trans_all[4]);
1392 fprintf(buglog,"BUGCHK: mmu=%p mmu_all[0]=%p [1]=%p [2]=%p [3]=%p [4]=%p\n\n\n",mmu,mmu_all[0],mmu_all[1],mmu_all[2],mmu_all[3],mmu_all[4]);
1393 _EXIT(1); }
1394 }
1395
1396 fprintf(buglog,"context:%d videoram @ %08x\n",context,videolatchaddress); fflush(buglog);
1397 */
1398 #else
1399 #define DEBUG_LOG( level, fmt, args... ) {}
1400 #define check_iib() {}
1401 #endif
1402
1403 // this is needed because gdb doesn't tell you where your program quit from, just gives you the octal version of the exit
1404 // parameter which is chopped to 9 bits for some oddball reason.
1405 #define EXIT(x,cmd,fmt,args...) { char msg[1024], msg2[1024]; \
1406 snprintf(msg2,1024, fmt, ## args); \
1407 snprintf(msg,1024,"We've encountered a problem!\n%s\nStopped at %s:%s:%d with code :%d", \
1408 msg2, \
1409 __FILE__,__FUNCTION__,__LINE__,x); \
1410 if (!cmd) strncat(msg,"\nLisaEM will now quit.",1024); \
1411 fprintf(buglog,"%s:%s:%d: exit with code :%d\n%s\n",__FILE__,__FUNCTION__,__LINE__,x,msg2); \
1412 messagebox(msg,"Emulation aborted!"); \
1413 fflush(buglog); if (!cmd) exit(x); else return; \
1414 }
1415
1416 #define EXITR(x,cmd,fmt,args...) { char msg[1024], msg2[1024]; \
1417 snprintf(msg2, 1024, fmt, ## args); \
1418 snprintf(msg,1024,"I'm sorry, the emulation has aborted due to a fatal error\n%s\nStopped at %s:%s:%d with code :%d", \
1419 msg2, \
1420 __FILE__,__FUNCTION__,__LINE__,x); \
1421 if (!cmd) strncat(msg,"\nLisaEM will now quit.",1024); \
1422 fprintf(buglog,"%s:%s:%d: exit with code :%d\n%s\n",__FILE__,__FUNCTION__,__LINE__,x,msg2); \
1423 messagebox(msg,"Emulation aborted!"); \
1424 fflush(buglog); if (!cmd) exit(x); else return cmd-1; \
1425 }
1426
1427
1428
1429
1430
1431 #define ALERT_LOG( level, fmt, args... ) { if ( (level <= DEBUGLEVEL) ) \
1432 { \
1433 fprintf(stderr,"%s:%s:%d:",__FILE__,__FUNCTION__,__LINE__); fprintf(stderr, fmt , ## args); \
1434 fprintf(stderr,"\n"); fflush(stderr); \
1435 if (buglog && buglog!=stderr) { \
1436 fprintf(buglog,"%s:%s:%d:",__FILE__,__FUNCTION__,__LINE__); fprintf(buglog, fmt , ## args); \
1437 fprintf(buglog,"\n"); fflush(buglog); } \
1438 } }
1439
1440
1441 ///////// Memory access macros//////////////////////////////////////////////////////////////////////////////////////////////////
1442
1443
1444
1445
1446 /******* Memory/MMU related defines, protos and vars *******/
1447
1448
1449 // Context Selectors
1450 #define CXASEL (1+( segment1|segment2) )
1451 #define CXSEL (1+((segment1|segment2)&(lastsflag?0:3)))
1452 #define CXSASEL ((1+((segment1|segment2)&(lastsflag?0:3))) & (start?0:7) )
1453
1454
1455 // mmu cache coherency
1456 #define SET_MMU_DIRTY(x) {mmudirty=(x); mmudirty_all[CXASEL]=mmudirty;}
1457 #define GET_MMU_DIRTY(x) {mmudirty= mmudirty_all[CXASEL];}
1458 #define GET_MMUS_DIRTY(x) {mmudirty= mmudirty_all[CXSASEL];}
1459
1460 // are we trying to access a changed MMU block? If so rebuild it!
1461 #define CHECK_DIRTY_MMU(addr) {if (context && (mmu[((addr) & 0x00fe0000)>>17].changed)) {SET_MMU_DIRTY(0xdec0de); mmuflush(0);}}
1462
1463 // filter out segment # - i.e. keep page+offset
1464 #define MMUXXFILT 0x0001ffff
1465
1466 //#define SEGCHOP 1 /// bad - causes POST to get stuck
1467
1468 #ifdef SEGCHOP
1469 #define MMU_X_FIL 0x0001ffff
1470 #else
1471 #define MMU_X_FIL 0x00ffffff
1472 #endif
1473
1474 #define MMUSEGFILT 0x00fe0000
1475 #define MMUEPAGEFL 0x00fffe00
1476 //#define TWOMEGMLIM 0x001fffff
1477
1478 GLOBAL(uint32,TWOMEGMLIM,0x001fffff);
1479
1480
1481
1482
1483
1484
1485
1486
1487 #ifndef IN_REG68K_C /////////////////////////////////////////////////////////////////////////////////////////////////////////
1488 // __CYGWIN__ wrapper added by Ray Arachelian for LisaEm to prevent crashes in reg68k_ext exec
1489 #ifdef __CYGWIN__
1490 uint32 reg68k_pc;
1491 uint32 *reg68k_regs;
1492 t_sr reg68k_sr;
1493 #else
1494 //#if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) || defined(PROCESSOR_INTEL) ))
1495 #if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) )) //20051125
1496 uint32 reg68k_pc;
1497 uint32 *reg68k_regs;
1498 t_sr reg68k_sr;
1499 #endif
1500 #endif
1501
1502 #else
1503
1504
1505 #ifdef __CYGWIN__
1506 extern uint32 reg68k_pc;
1507 extern uint32 *reg68k_regs;
1508 extern t_sr reg68k_sr;
1509 #else
1510 #if (!(defined(PROCESSOR_ARM) || defined(PROCESSOR_SPARC) || defined(PROCESSOR_INTEL) ))
1511 extern uint32 reg68k_pc;
1512 extern uint32 *reg68k_regs;
1513 extern t_sr reg68k_sr;
1514 #endif
1515 #endif
1516
1517
1518 #endif
1519 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1520
1521
1522
1523 DECLARE(viatype,via[9]);
1524 GLOBAL(uint8,via_running,0); // If any VIA has a runing timer/SHIFTREG, then this is set (using bitmap of vianumber)
1525
1526 extern uint32 pc24;
1527 // Used for Exception processing in Address/BUS errors
1528 extern uint16 InstructionRegister;
1529 extern uint8 CPU_function_code;
1530 extern uint8 CPU_READ_MODE;
1531
1532
1533 extern void contrastchange(void);
1534
1535 extern uint8 get_next_timer_id(void);
1536
1537 extern void cops_reset(void);
1538 extern void disable_vidram(void);
1539 extern void enable_vidram(void);
1540 extern uint8 via1_ira(uint8 regnum);
1541 extern void via1_ora(uint8 data,uint8 regnum);
1542 extern void print_pc_and_regs(char *text);
1543
1544 extern uint8 viaX_ira(viatype *V,uint8 regnum);
1545 extern uint8 viaX_irb(viatype *V);
1546 extern void viaX_ora(viatype *V, uint8 data, uint8 regnum);
1547 extern void viaX_orb(viatype *V, uint8 data);
1548
1549 extern void reset_via(int i);
1550
1551 extern void set_crdy_line(void);
1552 extern void clr_crdy_line(void);
1553 extern int is_crdy_line(void);
1554 extern void set_kb_data_ready(void) ;
1555 extern int is_vector_available(int avno);
1556 extern void lisa_external_nmi_vector(uint32 addr);
1557 extern void reg68k_internal_autovector(int avno);
1558 extern int get_address_mmu_rfn_type(uint32 addr);
1559 extern void reg68k_sanity_check_bitorder(void);
1560
1561 extern char *mspace(lisa_mem_t fn);
1562 extern int floppy_insert(char *Image);
1563 extern void apple_1(void);
1564 extern void apple_2(void);
1565 extern void apple_3(void);
1566 extern void apple_dot(void);
1567 extern void apple_dot_down(void);
1568 extern void apple_dot_up(void);
1569 extern void send_nmi_key(void);
1570 extern void presspowerswitch(void);
1571
1572
1573 extern void shift_option_0(void);
1574 extern void shift_option_4(void);
1575 extern void shift_option_7(void);
1576
1577 extern void add_mouse_event(int16 x, int16 y, int8 button);
1578
1579 extern void mmuflush(uint16 opts);
1580 extern lisa_mem_t rmmuslr2fn(uint16 slr, uint32 a9);
1581 extern t_ipc_table *get_ipct(void);
1582 extern void checkcontext(uint8 c, char *text);
1583 extern void cpu68k_printipc(t_ipc * ipc);
1584 #ifdef DEBUG
1585 extern void dump_scc(void);
1586 #endif
1587 extern char *printslr(char *x, long size, uint16 slr);
1588 extern lisa_mem_t rmmuslr2fn(uint16 slr, uint32 a9);
1589 extern void get_slr_page_range(int cx,int seg, int16 *pagestart, int16 *pageend, lisa_mem_t *rfn, lisa_mem_t *wfn);
1590 extern lisa_mem_t rmmuslr2fn(uint16 slr, uint32 a9);
1591
1592
1593
1594 extern void dumpram(char *reason);
1595 extern void dumpvia(void);
1596 extern void fdumpvia1(FILE *out);
1597 extern void fdumpvia2(FILE *out);
1598 extern void fliflo_dump(FLIFLO_QUEUE_t *b,char *s);
1599
1600
1601 #ifdef DEBUG
1602 extern char *slrname(uint16 slr);
1603 #endif
1604
1605 #ifdef DEBUG
1606 extern void validate_mmu_segments(char *from);
1607 #endif
1608
1609
1610
1611 #ifdef EXTERNX
1612 #undef EXTERNX
1613 #endif
1614 #ifndef IN_ROM_C
1615 #define EXTERNX extern
1616 #else
1617 #define EXTERNX ;
1618 #endif
1619 EXTERNX int has_xl_screenmod(void);
1620 EXTERNX int16 read_dtc_rom( char *filename, uint8 *ROM);
1621 EXTERNX int16 read_split_rom(char *filename, uint8 *ROMMX);
1622 EXTERNX int16 read_rom( char *filename, uint8 *ROMMX);
1623 EXTERNX uint8 *decode_lisa_icon(uint8 *icon);
1624 EXTERNX int read_parallel_card_rom(char *filename);
1625
1626
1627
1628
1629 // not likely that these are needed, but could be useful elsewhere:
1630 EXTERNX uint8 ishex(char c);
1631 EXTERNX uint8 gethex(char c);
1632 EXTERNX uint8 brol(uint8 outdata, uint8 loop);
1633 EXTERNX uint16 wrol(uint16 outdata, uint8 loop);
1634 EXTERNX uint32 lrol(uint32 outdata, uint8 loop);
1635
1636
1637
1638 #ifdef EXTERNX
1639 #undef EXTERNX
1640 #endif
1641 #ifndef IN_MMU_C
1642 #define EXTERNX extern
1643 #else
1644 #define EXTERNX ;
1645 #endif
1646 EXTERNX void init_lisa_mmu(void);
1647 EXTERNX void checkcontext(uint8 c, char *text);
1648
1649 #ifdef EXTERNX
1650 #undef EXTERNX
1651 #endif
1652 #ifndef IN_UI_LOG_C
1653 #define EXTERNX extern
1654 #else
1655 #define EXTERNX ;
1656 #endif
1657 EXTERNX void ui_err(const char *text, ...);
1658 EXTERNX void ui_error(const char *text, ...);
1659 EXTERNX void ui_log(unsigned int loglevel, const char *text, ...);
1660 EXTERNX void ui_log_verbose(const char *text, ...);
1661 EXTERNX void ui_log_request(const char *text, ...);
1662 EXTERNX void ui_log_critical(const char *text, ...);
1663 EXTERNX void ui_log_debug3(const char *text, ...);
1664 EXTERNX void ui_log_debug2(const char *text, ...);
1665 EXTERNX void ui_log_debug1(const char *text, ...);
1666 EXTERNX void ui_log_user(const char *text, ...);
1667 EXTERNX void ui_log_normal(const char *text, ...);
1668
1669
1670 #ifdef EXTERNX
1671 #undef EXTERNX
1672 #endif
1673 #ifndef IN_VIA6522_C
1674 #define EXTERNX extern
1675 #else
1676 #define EXTERNX ;
1677 #endif
1678 EXTERNX void all_vias_run(void);
1679 EXTERNX void init_vias(void);
1680 EXTERNX void get_next_timer_event(void);
1681 EXTERNX void check_current_timer_irq(void);
1682 EXTERNX uint8 next_timer_id(void);
1683 EXTERNX void VIAProfileLoop(int vianum, ProFileType *P, int event);
1684
1685
1686
1687
1688
1689
1690 #ifndef IN_IRQ_C
1691 extern int8 IRQRingBufferAdd(uint8 irql, uint32 address);
1692 extern uint8 IRQRingGet(void);
1693 extern void init_IRQ(void);
1694 #endif
1695
1696
1697
1698
1699
1700
1701
1702 #ifndef IN_COPS_C
1703 extern void cops_keyboard_id(void);
1704 extern void set_keyboard_id(int32);
1705 extern void init_cops(void);
1706 #endif
1707
1708 #ifndef IN_FLOPPY_C
1709 extern void floppy_go6504(void);
1710 #endif
1711
1712 #ifndef IN_PROFILE_C
1713 extern void ProfileLoop(ProFileType *P, int event);
1714 extern void ProfileReset(ProFileType *P);
1715 extern void ProfileResetOff(ProFileType *P);
1716 extern void get_profile_spare_table(ProFileType *P);
1717
1718 #endif
1719
1720 #define PROLOOP_EV_IRB 0 // event=0 <- Read from IRB
1721 #define PROLOOP_EV_IRA 1 // event=1 <- Read from IRA
1722 #define PROLOOP_EV_ORA 2 // event=2 <- write to ORA
1723 #define PROLOOP_EV_ORB 3 // event=3 <- write to ORB
1724 #define PROLOOP_EV_NUL 4 // event=4 <- null event - called occasionally by event handling to allow timeouts
1725
1726
1727
1728 /****** Video ***********/
1729
1730 GLOBAL(uint8,bitdepth,0);
1731
1732 GLOBAL(uint8,softmemerror,0);
1733 GLOBAL(uint8,harderror,0);
1734 GLOBAL(uint8,videoirq,0);
1735 GLOBAL(uint8,bustimeout,0);
1736 GLOBAL(uint8,videobit,0);
1737 GLOBAL(uint8,serialnumshiftcount,0);
1738 GLOBAL(uint8,serialnumshift,0);
1739 DECLARE(uint8,serialnum[8]);
1740 DECLARE(uint8,serialnum240[32]);
1741
1742 #define MAXSOUNDS 10
1743
1744 GLOBAL(int,SoundLastOne,5);
1745 DECLARE(char,*SoundBuffer[MAXSOUNDS]);
1746 DECLARE(uint32,SoundBufSize[MAXSOUNDS]);
1747
1748 GLOBAL(int,z8530_last_irq_status_bits,0);
1749 DECLARE(char,*scc_a_port); DECLARE(char,scc_a_OPTIONS[1024]);
1750 DECLARE(char,*scc_b_port); DECLARE(char,scc_b_OPTIONS[1024]);
1751 DECLARE(int,scc_a_telnet_port);
1752 DECLARE(int,scc_b_telnet_port);
1753
1754
1755 GLOBAL(int,scc_a_IW,-1);
1756 GLOBAL(int,scc_b_IW,-1);
1757
1758 GLOBAL(uint8,serial_a,SCC_NOTHING);
1759 GLOBAL(uint8,serial_b,SCC_NOTHING);
1760
1761 GLOBAL(FILE,*scc_a_port_F,NULL);
1762 GLOBAL(FILE,*scc_b_port_F,NULL);
1763
1764 // USed by memory diag tests
1765 GLOBAL(uint8,*mem_parity_bits1,NULL);
1766 GLOBAL(uint8,*mem_parity_bits2,NULL);
1767 GLOBAL(uint32,last_bad_parity_adr,0);
1768
1769 GLOBAL(int,scc_running,0);
1770
1771
1772
1773 extern void sound_fork(void);
1774 extern void sound_play(uint16 freq);
1775 extern void sound_off(void);
1776
1777 //DECLARE(scc_func_t, scc_fn[2] );
1778
1779 // 5 sets of mmu registers, each of 128 segments.
1780 // (4 are real lisa mmu contexts, added an extra for easier START mode translation)
1781 DECLARE(mmu_t,mmu_all[5][128]);
1782
1783 // *mmu is in current context. i.e. mmu = mmu_all[4] sets context[4] (START mode). I do this so that I
1784
1785 // don't have to dereference the array every single memory access as that would add an unnecessary expense.
1786 // i.e. mmu_all[SEGMENT1+SEGMENT2|SETUP][(address>>17)&0x7f] is very expensive, but
1787 // mmu[(address>>17)&0x7f] is far less expensive.
1788 GLOBAL(mmu_t,*mmu,NULL);
1789
1790 DECLARE(mmu_trans_t,mmu_trans_all[5][32768]);
1791
1792 /* sadly if I used enums for lisa_mem_t.readfn/.writefn gcc would allocate 4 bytes for each so the total
1793 or this would be 12 bytes x 32768 pages/context x 5 = 1.85MB of ram for this table. Instead I used
1794 defines and uint8's for lisa_mem_t, so this should be 1.25M depending on how they're packed */
1795
1796 GLOBAL(mmu_trans_t,*mmu_trans,mmu_trans_all[0]); // ptr to current context, so I don't have to do expensive double array deref.
1797 // i.e. mmu_trans=mmu_trans_all[0] is context 0.
1798
1799 // Refs for Generator's mem68k.c
1800 // These are initialized by init_lisa_mmu.
1801
1802 // temp vars to play with, don't include these in vars.c
1803 DECLARE(mmu_t,m); // temp variable to play with
1804 DECLARE(mmu_trans_t,mt); // mmu translation - temporary var
1805 DECLARE(mmu_trans_t,*lastvideo_mt);
1806
1807 // result of mmu logical->physical translation
1808 GLOBAL(int32,physaddr,0);
1809
1810 // Lisa I/O Space types and other types of accesses.
1811
1812 // These used to be enums, but enums in gcc are 32 bits long, and unless you want to pass
1813 // the -fshort-enums which may break other things, I'd rather just set them up as #DEFINEs and
1814 // be done with it. Could have left them as enums, but that would bloat the mmu structures I use
1815 // as mmu_trans_all would grow huge. consts can't be used to set arrays, so #DEFINES they'll have
1816 // to be.
1817
1818
1819 // Note, these are the letters Ox not zero x, so they're perfectly legal symbol names
1820 // It makes for easier reading of addresses when reading the source. :)
1821
1822 // Regular (non-special) I/O address space. Subject to MMU mapping.
1823
1824 #define OxERROR 0 /* This should never be used - it indicates a bug in our code */
1825 #define OxUnused 1 /* unused I/O space address (only used in I/O space map) */
1826 #define Ox0000_slot1 2
1827 #define Ox2000_slot1 3
1828 #define Ox4000_slot2 4
1829 #define Ox6000_slot2 5
1830 #define Ox8000_slot3 6
1831 #define Oxa000_slot3 7
1832 #define Oxc000_flopmem 8
1833 #define Oxd000_ff_space 9
1834 #define Oxd200_sccz8530 10
1835 #define Oxd800_par_via2 11
1836 #define Oxdc00_cops_via1 12
1837 #define Oxe000_latches 13
1838 #define Oxe800_videlatch 14
1839 #define Oxf000_memerror 15
1840 #define Oxf800_statreg 16
1841
1842 // Real Lisa memory
1843 #define ram 17 /* Plain old RAM, or stack access. */
1844 #define vidram 18 /* same as ram, but flag on write that screen needs refreshing */
1845 #define ro_violn 19 /* Read only violation - what trap should I call? See schematic */
1846 #define bad_page 20 /* Bad page or unallocated segment - what trap here? */
1847
1848 // Special I/O space
1849 #define sio_rom 21 /* access to ROM via sio mode */
1850 #define sio_mrg 22 /* mmu register being accessed. Which depends on bit 3 of addr */
1851
1852 #define sio_mmu 23 /* access ram or other spaces via the mmu (bit14=1 in address) */
1853
1854
1855 // Disparcher to I/O space (dispatcher to the Ox????_ fn's list above)
1856 #define io 24 /* This is a dispatcher for I/O space when we don't know the address */
1857
1858 #define Oxd400_amd9512 25
1859
1860 #define OxVoid 26 /* Reserved mem fn's that do nothing, and return junk */
1861
1862 // 27-31 unused.
1863
1864 #define MAX_LISA_MFN 27 /* The last Lisa Memory function type we have */
1865
1866
1867 #define DEBUG_MFN_TRACE 32 // trap/trace fn's.
1868
1869
1870 // I/O Address Maps. These are used to initialize the fn pointers on the OUTPUT side of the mmu.
1871 GLOBAL(char,*memspaces[],
1872 {
1873 "00-OxERROR",
1874 "01-OxUnused",
1875 "02-Ox0000_slot1",
1876 "03-Ox2000_slot1",
1877 "04-Ox4000_slot2",
1878 "05-Ox6000_slot2",
1879 "06-Ox8000_slot3",
1880 "07-Oxa000_slot3",
1881 "08-Oxc000_flopmem",
1882 "09-0xd000_ff_space",
1883 "10-Oxd200_sccz8530",
1884 "11-Oxd800_par_via2",
1885 "12-Oxdc00_cops_via1",
1886 "13-Oxe000_latches",
1887 "14-Oxe800_videlatch",
1888 "15-Oxf000_memerror",
1889 "16-Oxf800_statreg",
1890 "17-ram",
1891 "18-vidram",
1892 "19-ro_violn",
1893 "20-bad_page",
1894 "21-sio_rom",
1895 "22-sio_mrg",
1896 "23-sio_mmu",
1897 "24-io",
1898 "25-Oxd400_amd9512",
1899 "26-OxVoid"
1900 });
1901
1902
1903 ACGLOBAL(lisa_mem_t,io_map[],
1904 { // +0 // +1 // +2 //+3
1905 /* +000 +200 +400 +600 */
1906 /* 0xfc0000 : */ Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, // 0
1907 /* 0xfc0800 : */ Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, // 4
1908 /* 0xfc1000 : */ Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, // 8
1909 /* 0xfc1800 : */ Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, Ox0000_slot1, // 12
1910 /* 0xfc2000 : */ Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, // 16
1911
1912 /* 0xfc2800 : */ Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, // 20
1913 /* 0xfc3000 : */ Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, // 24
1914 /* 0xfc3800 : */ Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, Ox2000_slot1, // 28
1915 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1916 /* 0xfc4000 : */ Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, // 32
1917 /* 0xfc4800 : */ Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, // 36
1918
1919 /* 0xfc5000 : */ Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, // 40
1920 /* 0xfc5800 : */ Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, Ox4000_slot2, // 44
1921 /* 0xfc6000 : */ Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, // 48
1922 /* 0xfc6800 : */ Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, // 52
1923 /* 0xfc7000 : */ Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, // 56
1924
1925 /* 0xfc7800 : */ Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, Ox6000_slot2, // 60
1926 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1927 /* 0xfc8000 : */ Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, // 74
1928 /* 0xfc8800 : */ Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, // 78
1929 /* 0xfc9000 : */ Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, // 82
1930 /* 0xfc9800 : */ Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, Ox8000_slot3, // 86
1931
1932 /* 0xfca000 : */ Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, // 90
1933 /* 0xfca800 : */ Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, // 94
1934 /* 0xfcb000 : */ Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, // 98
1935 /* 0xfcb800 : */ Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, Oxa000_slot3, // 102
1936 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1937
1938 /* 0xfcc000 : */ Oxc000_flopmem, Oxc000_flopmem, Oxc000_flopmem, Oxc000_flopmem, // 106
1939
1940 /* 0xfcc800 : */ Oxc000_flopmem, Oxc000_flopmem, Oxc000_flopmem, Oxc000_flopmem, // 110
1941
1942 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1943 /* 0xfcd000 : */ Oxd000_ff_space, Oxd200_sccz8530, Oxd400_amd9512, Oxd400_amd9512, // 114
1944 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1945 /* 0xfcd800 : */ Oxd800_par_via2, Oxd800_par_via2, Oxdc00_cops_via1, Oxdc00_cops_via1, // 118
1946 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1947 /* 0xfce000 : */ Oxe000_latches, OxUnused, OxUnused, OxUnused, // 122
1948 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1949 /* 0xfce800 : */ Oxe800_videlatch, Oxe800_videlatch, Oxe800_videlatch, Oxe800_videlatch, // 126
1950 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1951 /* 0xfcf000 : */ Oxf000_memerror, Oxf000_memerror, Oxf000_memerror, Oxf000_memerror, // 130
1952 ///////////////////////////////////////////////////////////////////////////////////////////////////////
1953 /* 0xfcf800 : */ Oxf800_statreg, Oxf800_statreg, Oxf800_statreg, Oxf800_statreg // 134
1954 /* +000 +200 +400 +600 */
1955 });
1956
1957
1958
1959 ACGLOBAL(lisa_mem_t,sio_map[], // danger! this is for use on pre-MMU addresses - lop off the top 17 bits of the address
1960 // as well as the low 9 bits ( address & 01fe00)
1961 {
1962 /* 000 200 400 600 800 a00 c00 e00 */
1963 /*000000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, // 8/line
1964 /*001000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1965 /*002000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1966 /*003000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1967 /*004000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1968 /*005000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1969 /*006000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1970 /*007000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1971 /*008000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1972 /*009000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1973 /*00a000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1974 /*00b000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1975 /*00c000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1976 /*00d000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1977 /*00e000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1978 /*00f000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1979 /*010000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1980 /*011000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1981 /*012000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1982 /*013000:*/ sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom, sio_rom,
1983 /*014000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1984 /*015000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1985 /*016000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1986 /*017000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1987 /*018000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1988 /*019000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1989 /*01a000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1990 /*01b000:*/ sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg, sio_mrg,
1991 /*01c000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1992 /*01d000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1993 /*01e000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu,
1994 /*01f000:*/ sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu, sio_mmu
1995 });
1996
1997
1998 GLOBAL(int,dispmemready,0);
1999
2000 // Status register in memory.c
2001 //------------------------------------------------------------------------------
2002 #define STATREG_SOFTMEM_ERR 1 /* lisa doesn't use this bit */
2003 #define STATREG_HARDMEM_ERR 2 /* Parity error bit 1=not set, 0=set */
2004 #define STATREG_VERTICALRTC 4
2005 #define STATREG_BUSTIMEOUT 8
2006 #define STATREG_VIDEOBIT 16
2007 #define STATREG_CSYNC 32
2008 #define STATREG_HORIZONTAL 32
2009 #define STATREG_INVBIT 64 /* lisa doesn't use this bit normally */
2010 #define STATREG_UNUSEDBIT 128 /* lisa doesn't use this bit */
2011
2012
2013
2014
2015
2016
2017 #ifndef IN_CPU68K_C
2018 extern void free_ipct(t_ipc_table *ipct);
2019 #endif
2020
2021 extern int diss68k_gettext(t_ipc * ipc, char *text);
2022
2023 // memory function definitions.
2024 uint8 *(*mem68k_memptr[MAX_LISA_MFN]) (uint32 addr);
2025 uint8 (*mem68k_fetch_byte[MAX_LISA_MFN]) (uint32 addr);
2026 uint16 (*mem68k_fetch_word[MAX_LISA_MFN]) (uint32 addr);
2027 uint32 (*mem68k_fetch_long[MAX_LISA_MFN]) (uint32 addr);
2028 void (*mem68k_store_byte[MAX_LISA_MFN]) (uint32 addr, uint8 data);
2029 void (*mem68k_store_word[MAX_LISA_MFN]) (uint32 addr, uint16 data);
2030 void (*mem68k_store_long[MAX_LISA_MFN]) (uint32 addr, uint32 data);
2031
2032 extern int get_exs2_pending_irq_empty(void);
2033 extern int get_exs1_pending_irq_empty(void);
2034 extern int get_exs0_pending_irq_empty(void);
2035
2036 extern int get_exs0_pending_irq_2xpar(void);
2037 extern int get_exs1_pending_irq_2xpar(void);
2038 extern int get_exs2_pending_irq_2xpar(void);
2039
2040 GLOBAL(int,(*get_exs0_pending_irq)(void),&get_exs0_pending_irq_empty);
2041 GLOBAL(int,(*get_exs1_pending_irq)(void),&get_exs1_pending_irq_empty);
2042 GLOBAL(int,(*get_exs2_pending_irq)(void),&get_exs2_pending_irq_empty);
2043
2044
2045 /* These macro "functions" are used by generator. I use the above macro's in here just to avoid
2046 macro soup insanity. Yeah, so they're probably not super duper optimized, but there's time
2047 for that once the emulator is debugged and working. -- RA */
2048 //define fetchaddr(addr) mem68k_memptr[RFN_MMU_TRANS](addr)
2049 //define fetchbyte(addr) mem68k_fetch_byte[RFN_MMU_TRANS](addr)
2050 //define fetchword(addr) mem68k_fetch_word[RFN_MMU_TRANS](addr)
2051 //define fetchlong(addr) mem68k_fetch_long[RFN_MMU_TRANS](addr)
2052 //define storebyte(addr,data) mem68k_store_byte[WFN_MMU_TRANS ](addr,data)
2053 //define storeword(addr,data) mem68k_store_word[WFN_MMU_TRANS ](addr,data)
2054 //define storelong(addr,data) mem68k_store_long[WFN_MMU_TRANS ](addr,data)
2055
2056 extern void lisa_ram_safe_setbyte(uint8 context, uint32 address,uint8 data);
2057 extern uint8 lisa_ram_safe_getbyte(uint8 context, uint32 address);
2058 extern uint16 lisa_ram_safe_getword(uint8 context, uint32 address);
2059 extern uint32 lisa_ram_safe_getlong(uint8 context, uint32 address);
2060
2061 #ifndef INMEMORYDOTC
2062 extern void *dmem68k_memptr( char *file, char *function, int line,uint32 a);
2063 extern uint8 dmem68k_fetch_byte(char *file, char *function, int line,uint32 a );
2064 extern uint16 dmem68k_fetch_word(char *file, char *function, int line,uint32 a );
2065 extern uint32 dmem68k_fetch_long(char *file, char *function, int line,uint32 a );
2066 extern void dmem68k_store_byte(char *file, char *function, int line,uint32 a, uint8 d);
2067 extern void dmem68k_store_word(char *file, char *function, int line,uint32 a, uint16 d);
2068 extern void dmem68k_store_long(char *file, char *function, int line,uint32 a, uint32 d);
2069 #endif
2070
2071
2072 #ifdef DEBUGMEMCALLS
2073
2074 #define fetchaddr(a) dmem68k_memptr( (char *)__FILE__,(char *)__FUNCTION__,__LINE__,a)
2075 #define fetchbyte(a) dmem68k_fetch_byte((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a))
2076 #define fetchword(a) dmem68k_fetch_word((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a))
2077 #define fetchlong(a) dmem68k_fetch_long((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a))
2078 #define storebyte(a,d) dmem68k_store_byte((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a),( uint8)(d))
2079 #define storeword(a,d) dmem68k_store_word((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a),(uint16)(d))
2080 #define storelong(a,d) dmem68k_store_long((char *)__FILE__,(char *)__FUNCTION__,__LINE__,(uint32)(a),(uint32)(d))
2081 #else
2082
2083 #define fetchaddr(a) mem68k_memptr[ (mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2084 #define fetchbyte(a) mem68k_fetch_byte[(mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2085 #define fetchword(a) mem68k_fetch_word[(mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2086 #define fetchlong(a) mem68k_fetch_long[(mmu_trans[((a) & 0x00fffe00)>>9].readfn)](a)
2087 #define storebyte(a,d) mem68k_store_byte[(mmu_trans[((a) & 0x00fffe00)>>9].writefn)]((a),( uint8)(d))
2088 #define storeword(a,d) mem68k_store_word[(mmu_trans[((a) & 0x00fffe00)>>9].writefn)]((a),(uint16)(d))
2089 #define storelong(a,d) mem68k_store_long[(mmu_trans[((a) & 0x00fffe00)>>9].writefn)]((a),(uint32)(d))
2090 #endif
2091
2092
2093
2094
2095 // As these are defined in memory.c, we cannot define them here as externs. like duh!
2096 #ifndef INMEMORYDOTC
2097 // fn protos
2098 extern uint8 *lisa_mptr_OxERROR(uint32 addr);
2099 extern uint8 lisa_rb_OxERROR(uint32 addr);
2100 extern uint16 lisa_rw_OxERROR(uint32 addr);
2101 extern uint32 lisa_rl_OxERROR(uint32 addr);
2102 extern void lisa_wb_OxERROR(uint32 addr, uint8 data);
2103 extern void lisa_ww_OxERROR(uint32 addr, uint16 data);
2104 extern void lisa_wl_OxERROR(uint32 addr, uint32 data);
2105
2106 extern uint8 *lisa_mptr_OxUnused(uint32 addr);
2107 extern uint8 lisa_rb_OxUnused(uint32 addr);
2108 extern uint16 lisa_rw_OxUnused(uint32 addr);
2109 extern uint32 lisa_rl_OxUnused(uint32 addr);
2110 extern void lisa_wb_OxUnused(uint32 addr, uint8 data);
2111 extern void lisa_ww_OxUnused(uint32 addr, uint16 data);
2112 extern void lisa_wl_OxUnused(uint32 addr, uint32 data);
2113
2114 extern uint8 *lisa_mptr_Ox0000_slot1(uint32 addr);
2115 extern uint8 lisa_rb_Ox0000_slot1(uint32 addr);
2116 extern uint16 lisa_rw_Ox0000_slot1(uint32 addr);
2117 extern uint32 lisa_rl_Ox0000_slot1(uint32 addr);
2118 extern void lisa_wb_Ox0000_slot1(uint32 addr, uint8 data);
2119 extern void lisa_ww_Ox0000_slot1(uint32 addr, uint16 data);
2120 extern void lisa_wl_Ox0000_slot1(uint32 addr, uint32 data);
2121
2122 extern uint8 *lisa_mptr_Ox2000_slot1(uint32 addr);
2123 extern uint8 lisa_rb_Ox2000_slot1(uint32 addr);
2124 extern uint16 lisa_rw_Ox2000_slot1(uint32 addr);
2125 extern uint32 lisa_rl_Ox2000_slot1(uint32 addr);
2126 extern void lisa_wb_Ox2000_slot1(uint32 addr, uint8 data);
2127 extern void lisa_ww_Ox2000_slot1(uint32 addr, uint16 data);
2128 extern void lisa_wl_Ox2000_slot1(uint32 addr, uint32 data);
2129
2130 extern uint8 *lisa_mptr_Ox4000_slot2(uint32 addr);
2131 extern uint8 lisa_rb_Ox4000_slot2(uint32 addr);
2132 extern uint16 lisa_rw_Ox4000_slot2(uint32 addr);
2133 extern uint32 lisa_rl_Ox4000_slot2(uint32 addr);
2134 extern void lisa_wb_Ox4000_slot2(uint32 addr, uint8 data);
2135 extern void lisa_ww_Ox4000_slot2(uint32 addr, uint16 data);
2136 extern void lisa_wl_Ox4000_slot2(uint32 addr, uint32 data);
2137
2138 extern uint8 *lisa_mptr_Ox6000_slot2(uint32 addr);
2139 extern uint8 lisa_rb_Ox6000_slot2(uint32 addr);
2140 extern uint16 lisa_rw_Ox6000_slot2(uint32 addr);
2141 extern uint32 lisa_rl_Ox6000_slot2(uint32 addr);
2142 extern void lisa_wb_Ox6000_slot2(uint32 addr, uint8 data);
2143 extern void lisa_ww_Ox6000_slot2(uint32 addr, uint16 data);
2144 extern void lisa_wl_Ox6000_slot2(uint32 addr, uint32 data);
2145
2146 extern uint8 *lisa_mptr_Ox8000_slot3(uint32 addr);
2147 extern uint8 lisa_rb_Ox8000_slot3(uint32 addr);
2148 extern uint16 lisa_rw_Ox8000_slot3(uint32 addr);
2149 extern uint32 lisa_rl_Ox8000_slot3(uint32 addr);
2150 extern void lisa_wb_Ox8000_slot3(uint32 addr, uint8 data);
2151 extern void lisa_ww_Ox8000_slot3(uint32 addr, uint16 data);
2152 extern void lisa_wl_Ox8000_slot3(uint32 addr, uint32 data);
2153
2154 extern uint8 *lisa_mptr_Oxa000_slot3(uint32 addr);
2155 extern uint8 lisa_rb_Oxa000_slot3(uint32 addr);
2156 extern uint16 lisa_rw_Oxa000_slot3(uint32 addr);
2157 extern uint32 lisa_rl_Oxa000_slot3(uint32 addr);
2158 extern void lisa_wb_Oxa000_slot3(uint32 addr, uint8 data);
2159 extern void lisa_ww_Oxa000_slot3(uint32 addr, uint16 data);
2160 extern void lisa_wl_Oxa000_slot3(uint32 addr, uint32 data);
2161
2162
2163 extern uint8 lisa_rb_ext_2par_via(viatype *V,uint32 addr);
2164 extern void lisa_wb_ext_2par_via(viatype *V,uint32 addr, uint8 xvalue);
2165
2166 extern uint8 *lisa_mptr_2x_parallel_l(uint32 addr);
2167 extern uint8 lisa_rb_2x_parallel_l(uint32 addr);
2168 extern uint16 lisa_rw_2x_parallel_l(uint32 addr);
2169 extern uint32 lisa_rl_2x_parallel_l(uint32 addr);
2170 extern void lisa_wb_2x_parallel_l(uint32 addr, uint8 data);
2171 extern void lisa_ww_2x_parallel_l(uint32 addr, uint16 data);
2172 extern void lisa_wl_2x_parallel_l(uint32 addr, uint32 data);
2173
2174
2175 extern uint8 *lisa_mptr_2x_parallel_h(uint32 addr);
2176 extern uint8 lisa_rb_2x_parallel_h(uint32 addr);
2177 extern uint16 lisa_rw_2x_parallel_h(uint32 addr);
2178 extern uint32 lisa_rl_2x_parallel_h(uint32 addr);
2179 extern void lisa_wb_2x_parallel_h(uint32 addr, uint8 data);
2180 extern void lisa_ww_2x_parallel_h(uint32 addr, uint16 data);
2181 extern void lisa_wl_2x_parallel_h(uint32 addr, uint32 data);
2182
2183
2184 extern uint8 *lisa_mptr_Oxc000_flopmem(uint32 addr);
2185 extern uint8 lisa_rb_Oxc000_flopmem(uint32 addr);
2186 extern uint16 lisa_rw_Oxc000_flopmem(uint32 addr);
2187 extern uint32 lisa_rl_Oxc000_flopmem(uint32 addr);
2188 extern void lisa_wb_Oxc000_flopmem(uint32 addr, uint8 data);
2189 extern void lisa_ww_Oxc000_flopmem(uint32 addr, uint16 data);
2190 extern void lisa_wl_Oxc000_flopmem(uint32 addr, uint32 data);
2191
2192 extern uint8 *lisa_mptr_Oxd200_sccz8530(uint32 addr);
2193 extern uint8 lisa_rb_Oxd200_sccz8530(uint32 addr);
2194 extern uint16 lisa_rw_Oxd200_sccz8530(uint32 addr);
2195 extern uint32 lisa_rl_Oxd200_sccz8530(uint32 addr);
2196 extern void lisa_wb_Oxd200_sccz8530(uint32 addr, uint8 data);
2197 extern void lisa_ww_Oxd200_sccz8530(uint32 addr, uint16 data);
2198 extern void lisa_wl_Oxd200_sccz8530(uint32 addr, uint32 data);
2199
2200 extern uint8 *lisa_mptr_Oxd800_par_via2(uint32 addr);
2201 extern uint8 lisa_rb_Oxd800_par_via2(uint32 addr);
2202 extern uint16 lisa_rw_Oxd800_par_via2(uint32 addr);
2203 extern uint32 lisa_rl_Oxd800_par_via2(uint32 addr);
2204 extern void lisa_wb_Oxd800_par_via2(uint32 addr, uint8 data);
2205 extern void lisa_ww_Oxd800_par_via2(uint32 addr, uint16 data);
2206 extern void lisa_wl_Oxd800_par_via2(uint32 addr, uint32 data);
2207
2208 extern uint8 *lisa_mptr_Oxdc00_cops_via1(uint32 addr);
2209 extern uint8 lisa_rb_Oxdc00_cops_via1(uint32 addr);
2210 extern uint16 lisa_rw_Oxdc00_cops_via1(uint32 addr);
2211 extern uint32 lisa_rl_Oxdc00_cops_via1(uint32 addr);
2212 extern void lisa_wb_Oxdc00_cops_via1(uint32 addr, uint8 data);
2213 extern void lisa_ww_Oxdc00_cops_via1(uint32 addr, uint16 data);
2214 extern void lisa_wl_Oxdc00_cops_via1(uint32 addr, uint32 data);
2215
2216 extern uint8 *lisa_mptr_Oxe000_latches(uint32 addr);
2217 extern uint8 lisa_rb_Oxe000_latches(uint32 addr);
2218
2219 extern uint16 lisa_rw_Oxe000_latches(uint32 addr);
2220 extern uint32 lisa_rl_Oxe000_latches(uint32 addr);
2221 extern void lisa_wb_Oxe000_latches(uint32 addr, uint8 data);
2222 extern void lisa_ww_Oxe000_latches(uint32 addr, uint16 data);
2223 extern void lisa_wl_Oxe000_latches(uint32 addr, uint32 data);
2224
2225 extern uint8 *lisa_mptr_Oxe800_videlatch(uint32 addr);
2226 extern uint8 lisa_rb_Oxe800_videlatch(uint32 addr);
2227 extern uint16 lisa_rw_Oxe800_videlatch(uint32 addr);
2228 extern uint32 lisa_rl_Oxe800_videlatch(uint32 addr);
2229 extern void lisa_wb_Oxe800_videlatch(uint32 addr, uint8 data);
2230 extern void lisa_ww_Oxe800_videlatch(uint32 addr, uint16 data);
2231 extern void lisa_wl_Oxe800_videlatch(uint32 addr, uint32 data);
2232
2233 extern uint8 *lisa_mptr_Oxf000_memerror(uint32 addr);
2234 extern uint8 lisa_rb_Oxf000_memerror(uint32 addr);
2235 extern uint16 lisa_rw_Oxf000_memerror(uint32 addr);
2236 extern uint32 lisa_rl_Oxf000_memerror(uint32 addr);
2237 extern void lisa_wb_Oxf000_memerror(uint32 addr, uint8 data);
2238 extern void lisa_ww_Oxf000_memerror(uint32 addr, uint16 data);
2239 extern void lisa_wl_Oxf000_memerror(uint32 addr, uint32 data);
2240
2241 extern uint8 *lisa_mptr_Oxf800_statreg(uint32 addr);
2242 extern uint8 lisa_rb_Oxf800_statreg(uint32 addr);
2243 extern uint16 lisa_rw_Oxf800_statreg(uint32 addr);
2244 extern uint32 lisa_rl_Oxf800_statreg(uint32 addr);
2245 extern void lisa_wb_Oxf800_statreg(uint32 addr, uint8 data);
2246 extern void lisa_ww_Oxf800_statreg(uint32 addr, uint16 data);
2247 extern void lisa_wl_Oxf800_statreg(uint32 addr, uint32 data);
2248
2249 extern uint8 *lisa_mptr_ram(uint32 addr);
2250 extern uint8 lisa_rb_ram(uint32 addr);
2251 extern uint16 lisa_rw_ram(uint32 addr);
2252 extern uint32 lisa_rl_ram(uint32 addr);
2253 extern void lisa_wb_ram(uint32 addr, uint8 data);
2254 extern void lisa_ww_ram(uint32 addr, uint16 data);
2255 extern void lisa_wl_ram(uint32 addr, uint32 data);
2256
2257 extern uint8 *lisa_mptr_ro_violn(uint32 addr);
2258 extern uint8 lisa_rb_ro_violn(uint32 addr);
2259 extern uint16 lisa_rw_ro_violn(uint32 addr);
2260 extern uint32 lisa_rl_ro_violn(uint32 addr);
2261 extern void lisa_wb_ro_violn(uint32 addr, uint8 data);
2262 extern void lisa_ww_ro_violn(uint32 addr, uint16 data);
2263 extern void lisa_wl_ro_violn(uint32 addr, uint32 data);
2264
2265 extern uint8 *lisa_mptr_bad_page(uint32 addr);
2266 extern uint8 lisa_rb_bad_page(uint32 addr);
2267 extern uint16 lisa_rw_bad_page(uint32 addr);
2268 extern uint32 lisa_rl_bad_page(uint32 addr);
2269 extern void lisa_wb_bad_page(uint32 addr, uint8 data);
2270 extern void lisa_ww_bad_page(uint32 addr, uint16 data);
2271 extern void lisa_wl_bad_page(uint32 addr, uint32 data);
2272
2273 extern uint8 *lisa_mptr_sio_rom(uint32 addr);
2274 extern uint8 lisa_rb_sio_rom(uint32 addr);
2275 extern uint16 lisa_rw_sio_rom(uint32 addr);
2276 extern uint32 lisa_rl_sio_rom(uint32 addr);
2277 extern void lisa_wb_sio_rom(uint32 addr, uint8 data);
2278 extern void lisa_ww_sio_rom(uint32 addr, uint16 data);
2279 extern void lisa_wl_sio_rom(uint32 addr, uint32 data);
2280
2281 extern uint8 *lisa_mptr_sio_mrg(uint32 addr);
2282 extern uint8 lisa_rb_sio_mrg(uint32 addr);
2283 extern uint16 lisa_rw_sio_mrg(uint32 addr);
2284 extern uint32 lisa_rl_sio_mrg(uint32 addr);
2285 extern void lisa_wb_sio_mrg(uint32 addr, uint8 data);
2286 extern void lisa_ww_sio_mrg(uint32 addr, uint16 data);
2287 extern void lisa_wl_sio_mrg(uint32 addr, uint32 data);
2288
2289 extern uint8 *lisa_mptr_sio_mmu(uint32 addr);
2290 extern uint8 lisa_rb_sio_mmu(uint32 addr);
2291 extern uint16 lisa_rw_sio_mmu(uint32 addr);
2292 extern uint32 lisa_rl_sio_mmu(uint32 addr);
2293 extern void lisa_wb_sio_mmu(uint32 addr, uint8 data);
2294 extern void lisa_ww_sio_mmu(uint32 addr, uint16 data);
2295 extern void lisa_wl_sio_mmu(uint32 addr, uint32 data);
2296
2297 extern uint8 *lisa_mptr_vidram(uint32 addr);
2298 extern uint8 lisa_rb_vidram(uint32 addr);
2299 extern uint16 lisa_rw_vidram(uint32 addr);
2300 extern uint32 lisa_rl_vidram(uint32 addr);
2301 extern void lisa_wb_vidram(uint32 addr, uint8 data);
2302 extern void lisa_ww_vidram(uint32 addr, uint16 data);
2303 extern void lisa_wl_vidram(uint32 addr, uint32 data);
2304
2305 extern void lisa_wb_xlvidram_parity(uint32 addr, uint8 data);
2306 extern void lisa_ww_xlvidram_parity(uint32 addr, uint16 data);
2307 extern void lisa_wl_xlvidram_parity(uint32 addr, uint32 data);
2308 extern void lisa_wb_xlvidram(uint32 addr, uint8 data);
2309 extern void lisa_ww_xlvidram(uint32 addr, uint16 data);
2310 extern void lisa_wl_xlvidram(uint32 addr, uint32 data);
2311
2312
2313
2314 extern uint8 *lisa_mptr_io(uint32 addr);
2315 extern uint8 lisa_rb_io(uint32 addr);
2316 extern uint16 lisa_rw_io(uint32 addr);
2317 extern uint32 lisa_rl_io(uint32 addr);
2318 extern void lisa_wb_io(uint32 addr, uint8 data);
2319 extern void lisa_ww_io(uint32 addr, uint16 data);
2320 extern void lisa_wl_io(uint32 addr, uint32 data);
2321
2322 extern uint8 lisa_rb_ram_parity(uint32 addr);
2323 extern uint16 lisa_rw_ram_parity(uint32 addr);
2324 extern uint32 lisa_rl_ram_parity(uint32 addr);
2325 extern void lisa_wb_ram_parity(uint32 addr, uint8 data);
2326 extern void lisa_ww_ram_parity(uint32 addr, uint16 data);
2327 extern void lisa_wl_ram_parity(uint32 addr, uint32 data);
2328
2329 extern uint8 lisa_rb_vidram_parity(uint32 addr);
2330 extern uint16 lisa_rw_vidram_parity(uint32 addr);
2331 extern uint32 lisa_rl_vidram_parity(uint32 addr);
2332 extern void lisa_wb_vidram_parity(uint32 addr, uint8 data);
2333 extern void lisa_ww_vidram_parity(uint32 addr, uint16 data);
2334 extern void lisa_wl_vidram_parity(uint32 addr, uint32 data);
2335
2336 extern uint8 *lisa_mptr_Oxd000_ff_space(uint32 addr);
2337 extern uint8 lisa_rb_Oxd000_ff_space(uint32 addr);
2338 extern uint16 lisa_rw_Oxd000_ff_space(uint32 addr);
2339 extern uint32 lisa_rl_Oxd000_ff_space(uint32 addr);
2340 extern void lisa_wb_Oxd000_ff_space(uint32 addr, uint8 data);
2341 extern void lisa_ww_Oxd000_ff_space(uint32 addr, uint16 data);
2342 extern void lisa_wl_Oxd000_ff_space(uint32 addr, uint32 data);
2343
2344
2345 // not implemented - for future AMD9512 FPU's
2346 extern uint8 *lisa_mptr_Oxd400_amd9512(uint32 addr);
2347 extern uint8 lisa_rb_Oxd400_amd9512(uint32 addr);
2348 extern uint16 lisa_rw_Oxd400_amd9512(uint32 addr);
2349 extern uint32 lisa_rl_Oxd400_amd9512(uint32 addr);
2350 extern void lisa_wb_Oxd400_amd9512(uint32 addr, uint8 data);
2351 extern void lisa_ww_Oxd400_amd9512(uint32 addr, uint16 data);
2352 extern void lisa_wl_Oxd400_amd9512(uint32 addr, uint32 data);
2353
2354 // reserved memory access for mmu pages out of scope that should not cause mmu_exception
2355 extern uint8 *lisa_mptr_OxVoid(uint32 addr);
2356 extern uint8 lisa_rb_OxVoid(uint32 addr);
2357 extern uint16 lisa_rw_OxVoid(uint32 addr);
2358 extern uint32 lisa_rl_OxVoid(uint32 addr);
2359 extern void lisa_wb_OxVoid(uint32 addr, uint8 data);
2360 extern void lisa_ww_OxVoid(uint32 addr, uint16 data);
2361 extern void lisa_wl_OxVoid(uint32 addr, uint32 data);
2362
2363
2364 #endif
2365
2366
2367 extern void keystroke_cops(unsigned char c);
2368 extern void send_cops_keycode(int k);
2369
2370 extern void apple_1(void);
2371 extern void apple_2(void);
2372 extern void apple_3(void);
2373 extern void apple_enternum(void);
2374 extern void apple_S(void); // for lisatest
2375 extern void apple_enter(void);
2376 extern void apple_renter(void);
2377
2378 extern void vidfixromchk(uint8 *s);
2379 extern void keystroke_cops(unsigned char c);
2380 extern void init_IRQ(void);
2381 extern void init_Profiles(void);
2382
2383 extern void profile_unmount(void);
2384
2385 extern void init_sounds(void);
2386 extern void initialize_scc(void);
2387 extern void init_telnet_serial_port(int portnum);
2388 extern uint16 crc16(uint16 crc, uint8 data);
2389 extern void seek_mouse_event(void);
2390 extern void init_floppy(long iorom);
2391
2392
2393 extern void lisa_addrerror(uint32 addr);
2394 extern void lisa_busrerror(uint32 addr);
2395 extern void lisa_mmu_exception(uint32 addr);
2396 extern void lisa_nmi_vector(uint32 addr);
2397
2398
2399 extern CPP2C void lisa_powered_off(void);
2400 extern CPP2C void lisa_rebooted(void);
2401 extern CPP2C void messagebox(char *s, char *t);
2402 extern CPP2C int yesnomessagebox(char *s, char *t);
2403 extern CPP2C void floppy_motor_sounds(int track);
2404 extern CPP2C void eject_floppy_animation(void);
2405 extern CPP2C void save_pram(void);
2406 extern CPP2C int pickprofilesize(char *filename);
2407
2408 //extern CPP2C char *getDocumentsDir(void);
2409 //extern CPP2C char *getResourcesDir(void);
2410 //extern CPP2C char *getExecutablePath(void);
2411
2412 extern CPP2C int ImageWriter_LisaEm_Init(int iwnum);
2413 extern CPP2C void iw_formfeed(int iw);
2414 extern CPP2C void ImageWriterLoop(int iw,uint8 c);
2415 extern CPP2C void gen_clock_diff_sleep(long diff);
2416
2417
2418
2419
2420
2421 void set_loram_clk(void);
2422
2423 extern void lisa_diag2_on_mem(void);
2424 extern void lisa_diag2_off_mem(void);
2425
2426 extern void lisa_buserror(uint32 addr);
2427 extern void mc68k_reset(void);
2428 extern uint8 lisa_rb_Oxd200_sccz8530(uint32 addr);
2429 extern uint8 lisa_rb_Oxd800_par_via2(uint32 addr);
2430 extern void lisa_wb_Oxd800_par_via2(uint32 addr, uint8 data);
2431 extern uint8 lisa_rb_Oxdc00_cops_via1(uint32 addr);
2432 extern void lisa_wb_Oxdc00_cops_via1(uint32 addr, uint8 data);
2433 extern void fixromchk(void);
2434 extern int checkromchksum(void);
2435
2436 #ifndef IN_ROMLESS_C
2437 extern void romless_vfychksum(void);
2438 extern void romless_proread(void);
2439 extern void romless_twgread(void);
2440 extern int romless_boot(int profileboot);
2441 extern int romless_entry(void);
2442 #endif
2443 extern void my_dump_cops(FILE *buglog);
2444 //extern char *dis_movem(char *out, uint16, opcode, uint16 msk);
2445
2446
2447 extern void get_next_timer_event(void);
2448 extern void FloppyIRQ_time_up(void);
2449
2450 extern void debug_on(char *reason);
2451 extern void debug_off(void);
2452 extern char *chk_mtmmu(uint32 a, uint8 write);
2453 extern void print_via_profile_state(char *s, uint8 data, viatype *V);
2454 extern int profile_mount(char *filename, ProFileType *P);
2455 extern void reg68k_external_autovector(int avno);
2456
2457 extern CPP2C void LisaScreenRefresh(void);
2458
2459
2460 extern uint8 is_lisa_mouse_on(void);
2461 extern void cops_timer_alarm(void);
2462 extern void flag_vert_retrace_irq(void);
2463
2464 extern int get_nmi_pending_irq(void);
2465 extern int get_scc_pending_irq(void);
2466 //extern int get_exs0_pending_irq(void);
2467 //extern int get_exs1_pending_irq(void);
2468 //extern int get_exs2_pending_irq(void);
2469 //extern int get_cops_pending_irq(void); made static inline and placed in reg68k.c for speedup
2470 extern int get_irq1_pending_irq(void);
2471 extern void reset_video_timing(void);
2472
2473 #ifdef DEBUG
2474 extern char *get_rom_label(uint32 pc24);
2475 extern char *getvector(int v);
2476 extern void lisaos_trap5(void);
2477 extern char *mac_aline_traps(uint16 opcode);
2478 #endif
2479
2480 extern uint32 getreg(uint8 regnum);
2481
2482 extern void printlisatime(FILE *out);
2483 extern void normalize_lisa_clock(void);
2484 extern void normalize_lisa_set_clock(void);
2485 extern void decisecond_clk_tick(void);
2486 extern void ascii_screendump(void);
2487 uint8 cmp_screen_hash(uint8 *hashtable1, uint8 *hashtable2);
2488
2489
2490
2491 #define GETSEG(a) (((a & MMUSEGFILT)>>17) & 0x7f)
2492 #define GETEPAGE(a) (((a & MMUEPAGEFL)>>9) & 0x7fff)
2493
2494 /* these are a bit too conservative perhaps, but they will prevent address overflows. 0x00fe0000*/
2495 //** DANGER ** REMOVE & TWOMEGLIM!!! ***
2496 #define CHK_MMU_REGST(addr) ( ((( mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) ))
2497 //#define RAM_MMU_REGST(addr) (lisaram+((( mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) & TWOMEGMLIM))
2498 #define CHK_MMU_A_REGST(c,addr) ( (((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) ))
2499 #define RAM_MMU_A_REGST(c,addr) (lisaram+(((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) ))
2500
2501 #define VALIDATE_MMU(addr) ( ((( mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) & TWOMEGMLIM))
2502
2503 // cheato
2504 //#define XCHK_MMU_TRANS(addr) ( ((( mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) & TWOMEGMLIM))
2505 //#define XRAM_MMU_TRANS(addr) (lisaram+((( mmu[(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) & TWOMEGMLIM))
2506 //#define XCHK_MMU_A_TRANS(c,addr) ( (((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) & TWOMEGMLIM))
2507 //#define XRAM_MMU_A_TRANS(c,addr) (lisaram+(((mmu_all[c][(addr & MMUSEGFILT)>>17].sor<<9) + (addr & MMUXXFILT)) & TWOMEGMLIM))
2508
2509
2510 // half way cheato
2511 //#define XXCHK_MMU_TRANS(addr) (( (((addr & 0xffffff)+mmu_trans[ (addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT) & TWOMEGMLIM)))
2512 //#define XXRAM_MMU_TRANS(addr) ((lisaram+(((addr & 0xffffff)+mmu_trans[ (addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT) & TWOMEGMLIM)))
2513 //#define XXCHK_MMU_A_TRANS(c,addr) (( (((addr & 0xffffff)+mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT) & TWOMEGMLIM)))
2514 //#define XXRAM_MMU_A_TRANS(c,addr) ((lisaram+(((addr & 0xffffff)+mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].sor9) + (addr & MMUXXFILT) & TWOMEGMLIM)))
2515
2516 // needs to be above fn def below
2517 GLOBAL(uint32,maxlisaram,2*1024*1024);
2518 GLOBAL(uint32,minlisaram,0);
2519
2520
2521 #define RAM512K ( 512*1024)
2522 #define RAM1024K (1024*1024)
2523 #define RAM1536K (1536*1024)
2524 #define RAM2048K (2048*1024)
2525
2526 #ifdef BULLSHYTE_ALLOW_1536K_RAM
RAMWARP(uint32 a,uint32 b,int c)2527 inline static uint32 RAMWARP(uint32 a, uint32 b, int c)
2528 {
2529
2530
2531 #ifdef OFFOFFOFFF20051205DEBUG
2532 uint32 sgn, usgn, xadd1, xadd2, slrchk;
2533
2534 sgn= ((int32)( (int32)(b & 0x00ffffff)+(int32)(mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address)) & 0x1fffff);
2535 usgn= ((uint32)( (b & 0x00ffffff)+ (mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address))) & 0x1FFFFF;
2536 xadd1=CHK_MMU_A_REGST(c,b);
2537 xadd2= 0x1FFFFF & (((mmu_all[c][b>>17].sor<<9) + (b & 0x1fe00))|(b &511));
2538 slrchk=0x1FFFFF & (((mmu_all[c][b>>17].slr & 0xff)<<9) + (b & 0x1fe00));
2539
2540 if (sgn!=usgn) ALERT_LOG(0,"DANGER - Signed MMU addition not the same as unsigned %d/%08x!=%08x(unsigned)",c,sgn,usgn);
2541 if (xadd1!=usgn) ALERT_LOG(0,"DANGER - Unsigned MMU addition not the same as CHK_MMU_A_REGST%d/%08x!=%08x(unsigned)",c,xadd1,usgn);
2542 if (xadd2!=usgn) ALERT_LOG(0,"DANGER - Unsigned MMU addition not the same HWG83 p 36 pdf %d/%08x!=%08x(unsigned)",c,xadd2,usgn);
2543 if (slrchk>0x1FFFFF) DEBUG_LOG(0,"SLR>1FFFFF");
2544
2545 //if (maxlisaram==RAM2048K) return a; // fast exit
2546
2547
2548 DEBUG_LOG(0," Current context=%d, context passed to me:%d slrchk:%08x >1FFFFF:%d",context,c,slrchk, (slrchk>0x1FFFFF));
2549 DEBUG_LOG(0," a=%08x inputaddr:%08x 2mblim s/b 001fffff:%08x mmu-delta:%d signed addition:%08x, normal addition:%08x via mmureg:%08x seg:%d sor:%04x slr:%04x",
2550 a,b,TWOMEGMLIM ,
2551 mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address,
2552 ( (int32)(b & 0x00ffffff)+(int32)(mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address)),
2553 ( (b & 0x00ffffff)+ (mmu_trans_all[c][(b & MMUEPAGEFL)>>9].address)),
2554
2555 CHK_MMU_A_REGST(c,b),
2556 ((b & MMUSEGFILT)>>17 ),
2557 mmu_all[c][(b & MMUSEGFILT)>>17].sor,
2558 mmu_all[c][(b & MMUSEGFILT)>>17].slr
2559 );
2560 #endif
2561
2562 #ifdef BULLSHYTE
2563 switch (maxlisaram)
2564 {
2565 case (RAM512K ): // single 1/2MB board
2566 if (a<RAM512K ) return a; // inside 512K
2567 //20051109 if (a<RAM1024K) return (a & (RAM512K-1)); // warp
2568 memset(&lisaram[maxlisaram],0xff,128);
2569 return maxlisaram; // above 1MB is junk - return highest and hope for best
2570
2571 case (RAM1024K): // two 1/2 MB boards //
2572 if (a<=RAM1024K) return a;
2573 else return maxlisaram;
2574 //20060106
2575 // if (a<RAM512K) {
2576 // DEBUG_LOG(0,"<512KB");
2577 // memset(&lisaram[maxlisaram],0xff,16); return maxlisaram;} //20051109
2578 // if (a>=RAM1536K) {
2579 // DEBUG_LOG(0,">1536KB");
2580 // memset(&lisaram[maxlisaram],0xff,16); return maxlisaram;} //20051109
2581 //
2582 // return a-RAM512K; // 1st board 1MB
2583 //20051109 return a-RAM1024K; // 2nd warp
2584
2585 case (RAM1536K): // one 1MB board and one 1/2mb board
2586 if (a<RAM1536K) return a; // first board 1.5M
2587 {memset(&lisaram[maxlisaram],0xff,128); return maxlisaram;} // 2nd board junk
2588
2589
2590 default: return (a & 0x00ffffff);
2591 }
2592 #endif
2593 return a;
2594 }
2595 //12345678
2596 #define RAM_MMU_TRANS(addr) ((lisaram+RAMWARP((((addr) & 0x00ffffff) +mmu_trans[ (addr & MMUEPAGEFL)>>9].address),addr,context)) )
2597 #define RAM_MMU_A_TRANS(c,addr) ((lisaram+RAMWARP((((addr) & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address),addr,c )) )
2598 #define CHK_MMU_TRANS(addr) (( RAMWARP((((addr) & 0x00ffffff) +mmu_trans[ (addr & MMUEPAGEFL)>>9].address),addr,context)) & (TWOMEGMLIM))
2599 #define CHK_MMU_A_TRANS(c,addr) (( RAMWARP((((addr) & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address),addr,c )) & (TWOMEGMLIM))
2600
2601 #else
2602
2603 // these first two are very dangerous! - need to deprecate their use!
2604 //12345678
2605 #define RAM_MMU_TRANS(addr) (lisaram+(((addr & 0x00ffffff) +mmu_trans[ (addr & MMUEPAGEFL)>>9].address) ))
2606 #define RAM_MMU_A_TRANS(c,addr) (lisaram+(((addr & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address) ))
2607 #define CHK_MMU_TRANS(addr) ( (((addr & 0x00ffffff) +mmu_trans[ (addr & MMUEPAGEFL)>>9].address) ))
2608 #define CHK_MMU_A_TRANS(c,addr) ( (((addr & 0x00ffffff) +mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address) ))
2609
2610 #endif
2611
2612
2613 #define RFN_MMU_TRANS(addr) (mmu_trans[ (addr & MMUEPAGEFL)>>9].readfn )
2614 #define WFN_MMU_TRANS(addr) (mmu_trans[ (addr & MMUEPAGEFL)>>9].writefn)
2615 #define RFN_MMU_A_TRANS(c,addr) (mmu_trans_all[c][ (addr & MMUEPAGEFL)>>9].readfn )
2616 #define WFN_MMU_A_TRANS(c,addr) (mmu_trans_all[c][ (addr & MMUEPAGEFL)>>9].writefn)
2617
2618
2619 // Memory checking macros
2620 // CHK- check only - no bus error
2621 // RCHK-Read check - call bus error
2622 // WCHK-Write check - call bus error
2623 // QCHK_RAM_LIMITS - check and quit emulator
2624
2625 // can call CHK_RAM_LIMITS, then check for -1, else do lisaram[physaddr] for a pointer
2626 #define CHK_RAM_LIMITS(addr) \
2627 { physaddr=( (((addr & 0x00ffffff)+mmu_trans[ (addr & MMUEPAGEFL)>>9].address) )); \
2628 if (physaddr<(signed)minlisaram) physaddr=-2; else if (physaddr>(signed)maxlisaram) physaddr=-1; \
2629 }
2630
2631 #define CHK_RAM_A_LIMITS(c,addr) \
2632 { physaddr=( (((addr & 0x00ffffff)+mmu_trans_all[c][(addr & MMUEPAGEFL)>>9].address) )); \
2633 if (physaddr<(signed)minlisaram) physaddr=-2; else if (physaddr>(signed)maxlisaram) physaddr=-1; \
2634 }
2635
2636
2637 // check, and quit if error
2638 #define QCHK_RAM_LIMITS(addr) \
2639 { physaddr=( (((addr & 0x00ffffff)+mmu_trans[ (addr & MMUEPAGEFL)>>9].address) )); \
2640 if (physaddr<0||physaddr>(signed)maxlisaram) \
2641 {fprintf(buglog,"*** %s:%s:%d:: mem out of range! @ %d/%08x :: @mmu=%08x\n\n", \
2642 __FILE__,__FUNCTION__,__LINE__,context,addr,physaddr); EXIT(2); } \
2643 }
2644
2645 // check and abort on read, or write
2646 // if (TWOMEGMLIM==0x001fffff && (physaddr<minlisaram||((uint32)(physaddr))>maxlisaram))
2647 //
2648 // if ((physaddr<minlisaram||((uint32)(physaddr))>maxlisaram))
2649
2650 #define RCHK_RAM_LIMITS(addr) \
2651 { physaddr=( ((addr+mmu_trans[ (addr & MMUEPAGEFL)>>9].address) )); \
2652 if (physaddr<minlisaram) return 0x75; else if (physaddr>(signed)maxlisaram) physaddr=-1; \
2653 if ((((uint32)(physaddr))>=maxlisaram)) \
2654 {fprintf(buglog,"*** %s:%s:%d:: mem out of range! @ %d/%08x :: @mmu=%08x\n\n", \
2655 __FILE__,__FUNCTION__,__LINE__,context,addr,physaddr); CPU_READ_MODE=1; lisa_mmu_exception(addr); return 0x93;} \
2656 } //lisa_mmu_exception(addr);
2657
2658
2659 #define WCHK_RAM_LIMITS(addr) \
2660 { physaddr=( ((addr+mmu_trans[ (addr & MMUEPAGEFL)>>9].address) )); \
2661 if (physaddr<minlisaram) return; else if (physaddr>(signed)maxlisaram) physaddr=-1; \
2662 if ((((uint32)(physaddr))>=maxlisaram)) \
2663 {fprintf(buglog,"*** %s:%s:%d:: mem out of range! @ %d/%08x :: @mmu=%08x\n\n", \
2664 __FILE__,__FUNCTION__,__LINE__,context,addr,physaddr); CPU_READ_MODE=0; lisa_mmu_exception(addr); return;} \
2665 } //lisa_mmu_exception(addr);
2666
2667
2668 #define XRCHK_RAM_LIMITS(addr) {}
2669 #define XWCHK_RAM_LIMITS(addr) {}
2670
2671 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2672
2673
2674 #endif
2675