mirror of
https://github.com/pruten/shoebill.git
synced 2024-06-11 09:29:30 +00:00
Compare commits
50 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
a9b2af09c0 | ||
|
2b4768daee | ||
|
3fd03263fa | ||
|
578d274ab0 | ||
|
bbb89edf8c | ||
|
70cf3734fb | ||
|
d26cbef0c1 | ||
|
0322e558b4 | ||
|
1ab8a6a988 | ||
|
7f8b393fcc | ||
|
c0439a2f57 | ||
|
2ffbc963d2 | ||
|
36fdd1a6d6 | ||
|
3bc6aed00a | ||
|
b936ace3eb | ||
|
a66ad6d9b4 | ||
|
476a8bb570 | ||
|
76f2b35170 | ||
|
9c3640cf48 | ||
|
aea23c6dfc | ||
|
9e91b8067a | ||
|
8142098fa1 | ||
|
f04e039dca | ||
|
c8e7ba594c | ||
|
7fa1e15257 | ||
|
c7a28b8520 | ||
|
0910915301 | ||
|
937a28a8bb | ||
|
db111528e8 | ||
|
df66c085da | ||
|
18c5a2b261 | ||
|
2d04c6c104 | ||
|
2790b03327 | ||
|
688199cf6d | ||
|
a155eb7734 | ||
|
7c96e7c101 | ||
|
16f1af72f8 | ||
|
78fbd8235f | ||
|
c9adc49a82 | ||
|
adc2e16ffd | ||
|
bb6d1e719f | ||
|
bb2ec0a27d | ||
|
a0810f55b9 | ||
|
b29c69453e | ||
|
4af4262993 | ||
|
fd31d642b0 | ||
|
20fedf386b | ||
|
ea23ef3ac6 | ||
|
df614785c9 | ||
|
4ac0c6c4b2 |
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -4,3 +4,5 @@
|
|||
*.xcworkspace
|
||||
xcuserdata
|
||||
/gui/build
|
||||
/debugger/debugger
|
||||
/debugger/debugger.dSYM
|
||||
|
|
31
README.md
31
README.md
|
@ -4,36 +4,43 @@ A Macintosh II emulator that runs A/UX (and A/UX only).
|
|||
|
||||
Shoebill is an all-new, BSD-licensed Macintosh II emulator designed from the ground up with the singular goal of running A/UX.
|
||||
|
||||
Shoebill requires OS X, a Macintosh II, IIx or IIcx ROM, and a disk image with A/UX installed.
|
||||
Shoebill requires a Macintosh II, IIx or IIcx ROM, and a disk image with A/UX installed.
|
||||
|
||||
[Download the latest release], and then see the [getting started] wiki.
|
||||
Also check out [screenshots].
|
||||
|
||||
__Update (May 24, 2014): [Shoebill 0.0.3 is available]__
|
||||
__Update (March 29, 2023): About issues/pull requests__
|
||||
|
||||
####Supports
|
||||
* A/UX 1.1.1 through 3.0.0 (but not 3.0.1 or higher, yet)
|
||||
__I just wanted to say that I appreciate some folks are still using Shoebill and submitting issues and pull requests. I wish I could continue working on this project, but there's a likely conflict of interest, and so I've mostly avoided pushing changes. I apologize for being unable to address the many, many bugs in this repo. (Also for anyone unaware, [Qemu is now able] now to run A/UX 3.x on its emulated Quadra 800.)__
|
||||
|
||||
####Currently Implements
|
||||
__Update (Sept 13, 2015): [Shoebill 0.0.5 is available]__
|
||||
|
||||
__This will probably be the last release. I won't be able to work on Shoebill going forward (by contractual obligation), so I wanted to race out one last release. Only an OS X binary is available, sorry, and it's very unpolished. But the SDL GUI should still build on linux/windows.__
|
||||
|
||||
|
||||
#### Supports
|
||||
* A/UX 1.1.1 through 3.1 (and 3.1.1 a little)
|
||||
|
||||
#### Currently Implements
|
||||
* 68020 CPU (mostly)
|
||||
* 68881 FPU (a little)
|
||||
* 68881 FPU (mostly)
|
||||
* 68851 PMMU (just enough to boot A/UX)
|
||||
* SCSI
|
||||
* ADB
|
||||
* A NuBus video card with 8-bit resolution
|
||||
* PRAM (as of v0.0.3)
|
||||
* PRAM
|
||||
* Ethernet (via emulated Apple EtherTalk/DP8390 card)
|
||||
* A NuBus video card with 24-bit depth.
|
||||
|
||||
#### Does not implement (yet)
|
||||
* Sound
|
||||
* Floppy
|
||||
* Serial ports
|
||||
* Ethernet
|
||||
* VIA timers
|
||||
* Support for multiple screens, or 16/24-bit resolutions
|
||||
|
||||
|
||||
[Download the latest release]:https://github.com/pruten/Shoebill/releases
|
||||
[getting started]:https://github.com/pruten/Shoebill/wiki/Getting-Started
|
||||
[screenshots]:https://github.com/pruten/Shoebill/wiki/Screenshots
|
||||
[Shoebill 0.0.3 is available]:https://github.com/pruten/Shoebill/releases
|
||||
[Shoebill 0.0.5 is available]:https://github.com/pruten/Shoebill/releases
|
||||
[The thread on emaculation.com]:http://www.emaculation.com/forum/viewtopic.php?f=7&t=8288
|
||||
[Qemu is now able]:https://virtuallyfun.com/2021/09/02/qemus-macintosh-quadra-in-alpha-usability-runs-a-ux/
|
||||
|
||||
|
|
|
@ -6,8 +6,8 @@ CFLAGS = -O3 -ggdb -flto -Wno-deprecated-declarations
|
|||
|
||||
DEPS = mc68851.h shoebill.h Makefile macro.pl
|
||||
NEED_DECODER = cpu dis
|
||||
NEED_PREPROCESSING = adb fpu mc68851 mem via floppy core_api
|
||||
NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet
|
||||
NEED_PREPROCESSING = adb mc68851 mem via floppy core_api fpu
|
||||
NEED_NOTHING = atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer sound ethernet SoftFloat/softfloat
|
||||
|
||||
# Object files that can be compiled directly from the source
|
||||
OBJ_NEED_NOTHING = $(patsubst %,$(TEMP)/%.o,$(NEED_NOTHING))
|
||||
|
@ -78,6 +78,7 @@ $(TEMP)/decoder_gen: decoder_gen.c $(DEPS)
|
|||
|
||||
$(TEMP):
|
||||
mkdir -p $(TEMP)
|
||||
mkdir -p $(TEMP)/SoftFloat
|
||||
|
||||
clean:
|
||||
rm -rf $(TEMP)
|
||||
|
|
68
core/SoftFloat/386-GCC.h
Normal file
68
core/SoftFloat/386-GCC.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
|
||||
/*----------------------------------------------------------------------------
|
||||
| One of the macros `BIGENDIAN' or `LITTLEENDIAN' must be defined.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define LITTLEENDIAN
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The macro `BITS64' can be defined to indicate that 64-bit integer types are
|
||||
| supported by the compiler.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define BITS64
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Each of the following `typedef's defines the most convenient type that holds
|
||||
| integers of at least as many bits as specified. For example, `uint8' should
|
||||
| be the most convenient type that can hold unsigned integers of as many as
|
||||
| 8 bits. The `flag' type must be able to hold either a 0 or 1. For most
|
||||
| implementations of C, `flag', `uint8', and `int8' should all be `typedef'ed
|
||||
| to the same as `int'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef char flag;
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
typedef int uint16;
|
||||
typedef int int16;
|
||||
typedef unsigned int uint32;
|
||||
typedef signed int int32;
|
||||
#ifdef BITS64
|
||||
typedef unsigned long long int uint64;
|
||||
typedef signed long long int int64;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Each of the following `typedef's defines a type that holds integers
|
||||
| of _exactly_ the number of bits specified. For instance, for most
|
||||
| implementation of C, `bits16' and `sbits16' should be `typedef'ed to
|
||||
| `unsigned short int' and `signed short int' (or `short int'), respectively.
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef unsigned char bits8;
|
||||
typedef signed char sbits8;
|
||||
typedef unsigned short int bits16;
|
||||
typedef signed short int sbits16;
|
||||
typedef unsigned int bits32;
|
||||
typedef signed int sbits32;
|
||||
#ifdef BITS64
|
||||
typedef unsigned long long int bits64;
|
||||
typedef signed long long int sbits64;
|
||||
#endif
|
||||
|
||||
#ifdef BITS64
|
||||
/*----------------------------------------------------------------------------
|
||||
| The `LIT64' macro takes as its argument a textual integer literal and
|
||||
| if necessary ``marks'' the literal as having a 64-bit integer type.
|
||||
| For example, the GNU C Compiler (`gcc') requires that 64-bit literals be
|
||||
| appended with the letters `LL' standing for `long long', which is `gcc's
|
||||
| name for the 64-bit integer type. Some compilers may allow `LIT64' to be
|
||||
| defined as the identity macro: `#define LIT64( a ) a'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define LIT64( a ) a##LL
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The macro `INLINE' can be used before functions that should be inlined. If
|
||||
| a compiler does not support explicit inlining, this macro should be defined
|
||||
| to be `static'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define INLINE static
|
||||
|
728
core/SoftFloat/softfloat-macros.h
Normal file
728
core/SoftFloat/softfloat-macros.h
Normal file
|
@ -0,0 +1,728 @@
|
|||
/*
|
||||
* SoftFloat with lots of fixes and modified for use by Shoebill.
|
||||
*
|
||||
* Based on SoftFloat 2b by John R. Hauser.
|
||||
* Modifications by Peter Rutenbar. (pruten@gmail.com)
|
||||
*/
|
||||
|
||||
/*============================================================================
|
||||
|
||||
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
|
||||
Arithmetic Package, Release 2b.
|
||||
|
||||
Written by John R. Hauser. This work was made possible in part by the
|
||||
International Computer Science Institute, located at Suite 600, 1947 Center
|
||||
Street, Berkeley, California 94704. Funding was partially provided by the
|
||||
National Science Foundation under grant MIP-9311980. The original version
|
||||
of this code was written as part of a project to build a fixed-point vector
|
||||
processor in collaboration with the University of California at Berkeley,
|
||||
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
|
||||
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
|
||||
arithmetic/SoftFloat.html'.
|
||||
|
||||
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
|
||||
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
|
||||
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
|
||||
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
|
||||
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
|
||||
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
|
||||
INSTITUTE (possibly via similar legal notice) AGAINST ALL LOSSES, COSTS, OR
|
||||
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
|
||||
|
||||
Derivative works are acceptable, even for commercial purposes, so long as
|
||||
(1) the source code for the derivative work includes prominent notice that
|
||||
the work is derivative, and (2) the source code includes prominent notice with
|
||||
these four paragraphs for those parts of this code that are retained.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts `a' right by the number of bits given in `count'. If any nonzero
|
||||
| bits are shifted off, they are ``jammed'' into the least significant bit of
|
||||
| the result by setting the least significant bit to 1. The value of `count'
|
||||
| can be arbitrarily large; in particular, if `count' is greater than 32, the
|
||||
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
|
||||
| The result is stored in the location pointed to by `zPtr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void shift32RightJamming( bits32 a, int16 count, bits32 *zPtr )
|
||||
{
|
||||
bits32 z;
|
||||
|
||||
if ( count == 0 ) {
|
||||
z = a;
|
||||
}
|
||||
else if ( count < 32 ) {
|
||||
z = ( a>>count ) | ( ( a<<( ( - count ) & 31 ) ) != 0 );
|
||||
}
|
||||
else {
|
||||
z = ( a != 0 );
|
||||
}
|
||||
*zPtr = z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts `a' right by the number of bits given in `count'. If any nonzero
|
||||
| bits are shifted off, they are ``jammed'' into the least significant bit of
|
||||
| the result by setting the least significant bit to 1. The value of `count'
|
||||
| can be arbitrarily large; in particular, if `count' is greater than 64, the
|
||||
| result will be either 0 or 1, depending on whether `a' is zero or nonzero.
|
||||
| The result is stored in the location pointed to by `zPtr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void shift64RightJamming( bits64 a, int16 count, bits64 *zPtr )
|
||||
{
|
||||
bits64 z;
|
||||
|
||||
if ( count == 0 ) {
|
||||
z = a;
|
||||
}
|
||||
else if ( count < 64 ) {
|
||||
z = ( a>>count ) | ( ( a<<( ( - count ) & 63 ) ) != 0 );
|
||||
}
|
||||
else {
|
||||
z = ( a != 0 );
|
||||
}
|
||||
*zPtr = z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by 64
|
||||
| _plus_ the number of bits given in `count'. The shifted result is at most
|
||||
| 64 nonzero bits; this is stored at the location pointed to by `z0Ptr'. The
|
||||
| bits shifted off form a second 64-bit result as follows: The _last_ bit
|
||||
| shifted off is the most-significant bit of the extra result, and the other
|
||||
| 63 bits of the extra result are all zero if and only if _all_but_the_last_
|
||||
| bits shifted off were all zero. This extra result is stored in the location
|
||||
| pointed to by `z1Ptr'. The value of `count' can be arbitrarily large.
|
||||
| (This routine makes more sense if `a0' and `a1' are considered to form
|
||||
| a fixed-point value with binary point between `a0' and `a1'. This fixed-
|
||||
| point value is shifted right by the number of bits given in `count', and
|
||||
| the integer part of the result is returned at the location pointed to by
|
||||
| `z0Ptr'. The fractional part of the result may be slightly corrupted as
|
||||
| described above, and is returned at the location pointed to by `z1Ptr'.)
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
shift64ExtraRightJamming(
|
||||
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
bits64 z0, z1;
|
||||
int8 negCount = ( - count ) & 63;
|
||||
|
||||
if ( count == 0 ) {
|
||||
z1 = a1;
|
||||
z0 = a0;
|
||||
}
|
||||
else if ( count < 64 ) {
|
||||
z1 = ( a0<<negCount ) | ( a1 != 0 );
|
||||
z0 = a0>>count;
|
||||
}
|
||||
else {
|
||||
if ( count == 64 ) {
|
||||
z1 = a0 | ( a1 != 0 );
|
||||
}
|
||||
else {
|
||||
z1 = ( ( a0 | a1 ) != 0 );
|
||||
}
|
||||
z0 = 0;
|
||||
}
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
|
||||
| number of bits given in `count'. Any bits shifted off are lost. The value
|
||||
| of `count' can be arbitrarily large; in particular, if `count' is greater
|
||||
| than 128, the result will be 0. The result is broken into two 64-bit pieces
|
||||
| which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
shift128Right(
|
||||
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
bits64 z0, z1;
|
||||
int8 negCount = ( - count ) & 63;
|
||||
|
||||
if ( count == 0 ) {
|
||||
z1 = a1;
|
||||
z0 = a0;
|
||||
}
|
||||
else if ( count < 64 ) {
|
||||
z1 = ( a0<<negCount ) | ( a1>>count );
|
||||
z0 = a0>>count;
|
||||
}
|
||||
else {
|
||||
// [shoebill] This is a bug, right? ( count < 64 ) can never be true
|
||||
// z1 = ( count < 64 ) ? ( a0>>( count & 63 ) ) : 0;
|
||||
z1 = ( count < 128 ) ? ( a0>>( count & 63 ) ) : 0;
|
||||
z0 = 0;
|
||||
}
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts the 128-bit value formed by concatenating `a0' and `a1' right by the
|
||||
| number of bits given in `count'. If any nonzero bits are shifted off, they
|
||||
| are ``jammed'' into the least significant bit of the result by setting the
|
||||
| least significant bit to 1. The value of `count' can be arbitrarily large;
|
||||
| in particular, if `count' is greater than 128, the result will be either
|
||||
| 0 or 1, depending on whether the concatenation of `a0' and `a1' is zero or
|
||||
| nonzero. The result is broken into two 64-bit pieces which are stored at
|
||||
| the locations pointed to by `z0Ptr' and `z1Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
shift128RightJamming(
|
||||
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
bits64 z0, z1;
|
||||
int8 negCount = ( - count ) & 63;
|
||||
|
||||
if ( count == 0 ) {
|
||||
z1 = a1;
|
||||
z0 = a0;
|
||||
}
|
||||
else if ( count < 64 ) {
|
||||
z1 = ( a0<<negCount ) | ( a1>>count ) | ( ( a1<<negCount ) != 0 );
|
||||
z0 = a0>>count;
|
||||
}
|
||||
else {
|
||||
if ( count == 64 ) {
|
||||
z1 = a0 | ( a1 != 0 );
|
||||
}
|
||||
else if ( count < 128 ) {
|
||||
z1 = ( a0>>( count & 63 ) ) | ( ( ( a0<<negCount ) | a1 ) != 0 );
|
||||
}
|
||||
else {
|
||||
z1 = ( ( a0 | a1 ) != 0 );
|
||||
}
|
||||
z0 = 0;
|
||||
}
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' right
|
||||
| by 64 _plus_ the number of bits given in `count'. The shifted result is
|
||||
| at most 128 nonzero bits; these are broken into two 64-bit pieces which are
|
||||
| stored at the locations pointed to by `z0Ptr' and `z1Ptr'. The bits shifted
|
||||
| off form a third 64-bit result as follows: The _last_ bit shifted off is
|
||||
| the most-significant bit of the extra result, and the other 63 bits of the
|
||||
| extra result are all zero if and only if _all_but_the_last_ bits shifted off
|
||||
| were all zero. This extra result is stored in the location pointed to by
|
||||
| `z2Ptr'. The value of `count' can be arbitrarily large.
|
||||
| (This routine makes more sense if `a0', `a1', and `a2' are considered
|
||||
| to form a fixed-point value with binary point between `a1' and `a2'. This
|
||||
| fixed-point value is shifted right by the number of bits given in `count',
|
||||
| and the integer part of the result is returned at the locations pointed to
|
||||
| by `z0Ptr' and `z1Ptr'. The fractional part of the result may be slightly
|
||||
| corrupted as described above, and is returned at the location pointed to by
|
||||
| `z2Ptr'.)
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
shift128ExtraRightJamming(
|
||||
bits64 a0,
|
||||
bits64 a1,
|
||||
bits64 a2,
|
||||
int16 count,
|
||||
bits64 *z0Ptr,
|
||||
bits64 *z1Ptr,
|
||||
bits64 *z2Ptr
|
||||
)
|
||||
{
|
||||
bits64 z0, z1, z2;
|
||||
int8 negCount = ( - count ) & 63;
|
||||
|
||||
if ( count == 0 ) {
|
||||
z2 = a2;
|
||||
z1 = a1;
|
||||
z0 = a0;
|
||||
}
|
||||
else {
|
||||
if ( count < 64 ) {
|
||||
z2 = a1<<negCount;
|
||||
z1 = ( a0<<negCount ) | ( a1>>count );
|
||||
z0 = a0>>count;
|
||||
}
|
||||
else {
|
||||
if ( count == 64 ) {
|
||||
z2 = a1;
|
||||
z1 = a0;
|
||||
}
|
||||
else {
|
||||
a2 |= a1;
|
||||
if ( count < 128 ) {
|
||||
z2 = a0<<negCount;
|
||||
z1 = a0>>( count & 63 );
|
||||
}
|
||||
else {
|
||||
z2 = ( count == 128 ) ? a0 : ( a0 != 0 );
|
||||
z1 = 0;
|
||||
}
|
||||
}
|
||||
z0 = 0;
|
||||
}
|
||||
z2 |= ( a2 != 0 );
|
||||
}
|
||||
*z2Ptr = z2;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts the 128-bit value formed by concatenating `a0' and `a1' left by the
|
||||
| number of bits given in `count'. Any bits shifted off are lost. The value
|
||||
| of `count' must be less than 64. The result is broken into two 64-bit
|
||||
| pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
shortShift128Left(
|
||||
bits64 a0, bits64 a1, int16 count, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
|
||||
*z1Ptr = a1<<count;
|
||||
*z0Ptr =
|
||||
( count == 0 ) ? a0 : ( a0<<count ) | ( a1>>( ( - count ) & 63 ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Shifts the 192-bit value formed by concatenating `a0', `a1', and `a2' left
|
||||
| by the number of bits given in `count'. Any bits shifted off are lost.
|
||||
| The value of `count' must be less than 64. The result is broken into three
|
||||
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
|
||||
| `z1Ptr', and `z2Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
shortShift192Left(
|
||||
bits64 a0,
|
||||
bits64 a1,
|
||||
bits64 a2,
|
||||
int16 count,
|
||||
bits64 *z0Ptr,
|
||||
bits64 *z1Ptr,
|
||||
bits64 *z2Ptr
|
||||
)
|
||||
{
|
||||
bits64 z0, z1, z2;
|
||||
int8 negCount;
|
||||
|
||||
z2 = a2<<count;
|
||||
z1 = a1<<count;
|
||||
z0 = a0<<count;
|
||||
if ( 0 < count ) {
|
||||
negCount = ( ( - count ) & 63 );
|
||||
z1 |= a2>>negCount;
|
||||
z0 |= a1>>negCount;
|
||||
}
|
||||
*z2Ptr = z2;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit
|
||||
| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so
|
||||
| any carry out is lost. The result is broken into two 64-bit pieces which
|
||||
| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
add128(
|
||||
bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
bits64 z1;
|
||||
|
||||
z1 = a1 + b1;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = a0 + b0 + ( z1 < a1 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Adds the 192-bit value formed by concatenating `a0', `a1', and `a2' to the
|
||||
| 192-bit value formed by concatenating `b0', `b1', and `b2'. Addition is
|
||||
| modulo 2^192, so any carry out is lost. The result is broken into three
|
||||
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr',
|
||||
| `z1Ptr', and `z2Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
add192(
|
||||
bits64 a0,
|
||||
bits64 a1,
|
||||
bits64 a2,
|
||||
bits64 b0,
|
||||
bits64 b1,
|
||||
bits64 b2,
|
||||
bits64 *z0Ptr,
|
||||
bits64 *z1Ptr,
|
||||
bits64 *z2Ptr
|
||||
)
|
||||
{
|
||||
bits64 z0, z1, z2;
|
||||
int8 carry0, carry1;
|
||||
|
||||
z2 = a2 + b2;
|
||||
carry1 = ( z2 < a2 );
|
||||
z1 = a1 + b1;
|
||||
carry0 = ( z1 < a1 );
|
||||
z0 = a0 + b0;
|
||||
z1 += carry1;
|
||||
z0 += ( z1 < carry1 );
|
||||
z0 += carry0;
|
||||
*z2Ptr = z2;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the
|
||||
| 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo
|
||||
| 2^128, so any borrow out (carry out) is lost. The result is broken into two
|
||||
| 64-bit pieces which are stored at the locations pointed to by `z0Ptr' and
|
||||
| `z1Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
sub128(
|
||||
bits64 a0, bits64 a1, bits64 b0, bits64 b1, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
|
||||
*z1Ptr = a1 - b1;
|
||||
*z0Ptr = a0 - b0 - ( a1 < b1 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Subtracts the 192-bit value formed by concatenating `b0', `b1', and `b2'
|
||||
| from the 192-bit value formed by concatenating `a0', `a1', and `a2'.
|
||||
| Subtraction is modulo 2^192, so any borrow out (carry out) is lost. The
|
||||
| result is broken into three 64-bit pieces which are stored at the locations
|
||||
| pointed to by `z0Ptr', `z1Ptr', and `z2Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
sub192(
|
||||
bits64 a0,
|
||||
bits64 a1,
|
||||
bits64 a2,
|
||||
bits64 b0,
|
||||
bits64 b1,
|
||||
bits64 b2,
|
||||
bits64 *z0Ptr,
|
||||
bits64 *z1Ptr,
|
||||
bits64 *z2Ptr
|
||||
)
|
||||
{
|
||||
bits64 z0, z1, z2;
|
||||
int8 borrow0, borrow1;
|
||||
|
||||
z2 = a2 - b2;
|
||||
borrow1 = ( a2 < b2 );
|
||||
z1 = a1 - b1;
|
||||
borrow0 = ( a1 < b1 );
|
||||
z0 = a0 - b0;
|
||||
z0 -= ( z1 < borrow1 );
|
||||
z1 -= borrow1;
|
||||
z0 -= borrow0;
|
||||
*z2Ptr = z2;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken
|
||||
| into two 64-bit pieces which are stored at the locations pointed to by
|
||||
| `z0Ptr' and `z1Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void mul64To128( bits64 a, bits64 b, bits64 *z0Ptr, bits64 *z1Ptr )
|
||||
{
|
||||
bits32 aHigh, aLow, bHigh, bLow;
|
||||
bits64 z0, zMiddleA, zMiddleB, z1;
|
||||
|
||||
aLow = a;
|
||||
aHigh = a>>32;
|
||||
bLow = b;
|
||||
bHigh = b>>32;
|
||||
z1 = ( (bits64) aLow ) * bLow;
|
||||
zMiddleA = ( (bits64) aLow ) * bHigh;
|
||||
zMiddleB = ( (bits64) aHigh ) * bLow;
|
||||
z0 = ( (bits64) aHigh ) * bHigh;
|
||||
zMiddleA += zMiddleB;
|
||||
z0 += ( ( (bits64) ( zMiddleA < zMiddleB ) )<<32 ) + ( zMiddleA>>32 );
|
||||
zMiddleA <<= 32;
|
||||
z1 += zMiddleA;
|
||||
z0 += ( z1 < zMiddleA );
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Multiplies the 128-bit value formed by concatenating `a0' and `a1' by
|
||||
| `b' to obtain a 192-bit product. The product is broken into three 64-bit
|
||||
| pieces which are stored at the locations pointed to by `z0Ptr', `z1Ptr', and
|
||||
| `z2Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
mul128By64To192(
|
||||
bits64 a0,
|
||||
bits64 a1,
|
||||
bits64 b,
|
||||
bits64 *z0Ptr,
|
||||
bits64 *z1Ptr,
|
||||
bits64 *z2Ptr
|
||||
)
|
||||
{
|
||||
bits64 z0, z1, z2, more1;
|
||||
|
||||
mul64To128( a1, b, &z1, &z2 );
|
||||
mul64To128( a0, b, &z0, &more1 );
|
||||
add128( z0, more1, 0, z1, &z0, &z1 );
|
||||
*z2Ptr = z2;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Multiplies the 128-bit value formed by concatenating `a0' and `a1' to the
|
||||
| 128-bit value formed by concatenating `b0' and `b1' to obtain a 256-bit
|
||||
| product. The product is broken into four 64-bit pieces which are stored at
|
||||
| the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE void
|
||||
mul128To256(
|
||||
bits64 a0,
|
||||
bits64 a1,
|
||||
bits64 b0,
|
||||
bits64 b1,
|
||||
bits64 *z0Ptr,
|
||||
bits64 *z1Ptr,
|
||||
bits64 *z2Ptr,
|
||||
bits64 *z3Ptr
|
||||
)
|
||||
{
|
||||
bits64 z0, z1, z2, z3;
|
||||
bits64 more1, more2;
|
||||
|
||||
mul64To128( a1, b1, &z2, &z3 );
|
||||
mul64To128( a1, b0, &z1, &more2 );
|
||||
add128( z1, more2, 0, z2, &z1, &z2 );
|
||||
mul64To128( a0, b0, &z0, &more1 );
|
||||
add128( z0, more1, 0, z1, &z0, &z1 );
|
||||
mul64To128( a0, b1, &more1, &more2 );
|
||||
add128( more1, more2, 0, z2, &more1, &z2 );
|
||||
add128( z0, z1, 0, more1, &z0, &z1 );
|
||||
*z3Ptr = z3;
|
||||
*z2Ptr = z2;
|
||||
*z1Ptr = z1;
|
||||
*z0Ptr = z0;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns an approximation to the 64-bit integer quotient obtained by dividing
|
||||
| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The
|
||||
| divisor `b' must be at least 2^63. If q is the exact quotient truncated
|
||||
| toward zero, the approximation returned lies between q and q + 2 inclusive.
|
||||
| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit
|
||||
| unsigned integer is returned.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static bits64 estimateDiv128To64( bits64 a0, bits64 a1, bits64 b )
|
||||
{
|
||||
bits64 b0, b1;
|
||||
bits64 rem0, rem1, term0, term1;
|
||||
bits64 z;
|
||||
|
||||
if ( b <= a0 ) return LIT64( 0xFFFFFFFFFFFFFFFF );
|
||||
b0 = b>>32;
|
||||
z = ( b0<<32 <= a0 ) ? LIT64( 0xFFFFFFFF00000000 ) : ( a0 / b0 )<<32;
|
||||
mul64To128( b, z, &term0, &term1 );
|
||||
sub128( a0, a1, term0, term1, &rem0, &rem1 );
|
||||
while ( ( (sbits64) rem0 ) < 0 ) {
|
||||
z -= LIT64( 0x100000000 );
|
||||
b1 = b<<32;
|
||||
add128( rem0, rem1, b0, b1, &rem0, &rem1 );
|
||||
}
|
||||
rem0 = ( rem0<<32 ) | ( rem1>>32 );
|
||||
z |= ( b0<<32 <= rem0 ) ? 0xFFFFFFFF : rem0 / b0;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns an approximation to the square root of the 32-bit significand given
|
||||
| by `a'. Considered as an integer, `a' must be at least 2^31. If bit 0 of
|
||||
| `aExp' (the least significant bit) is 1, the integer returned approximates
|
||||
| 2^31*sqrt(`a'/2^31), where `a' is considered an integer. If bit 0 of `aExp'
|
||||
| is 0, the integer returned approximates 2^31*sqrt(`a'/2^30). In either
|
||||
| case, the approximation returned lies strictly within +/-2 of the exact
|
||||
| value.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static bits32 estimateSqrt32( int16 aExp, bits32 a )
|
||||
{
|
||||
static const bits16 sqrtOddAdjustments[] = {
|
||||
0x0004, 0x0022, 0x005D, 0x00B1, 0x011D, 0x019F, 0x0236, 0x02E0,
|
||||
0x039C, 0x0468, 0x0545, 0x0631, 0x072B, 0x0832, 0x0946, 0x0A67
|
||||
};
|
||||
static const bits16 sqrtEvenAdjustments[] = {
|
||||
0x0A2D, 0x08AF, 0x075A, 0x0629, 0x051A, 0x0429, 0x0356, 0x029E,
|
||||
0x0200, 0x0179, 0x0109, 0x00AF, 0x0068, 0x0034, 0x0012, 0x0002
|
||||
};
|
||||
int8 index;
|
||||
bits32 z;
|
||||
|
||||
index = ( a>>27 ) & 15;
|
||||
if ( aExp & 1 ) {
|
||||
z = 0x4000 + ( a>>17 ) - sqrtOddAdjustments[ index ];
|
||||
z = ( ( a / z )<<14 ) + ( z<<15 );
|
||||
a >>= 1;
|
||||
}
|
||||
else {
|
||||
z = 0x8000 + ( a>>17 ) - sqrtEvenAdjustments[ index ];
|
||||
z = a / z + z;
|
||||
z = ( 0x20000 <= z ) ? 0xFFFF8000 : ( z<<15 );
|
||||
if ( z <= a ) return (bits32) ( ( (sbits32) a )>>1 );
|
||||
}
|
||||
return ( (bits32) ( ( ( (bits64) a )<<31 ) / z ) ) + ( z>>1 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the number of leading 0 bits before the most-significant 1 bit of
|
||||
| `a'. If `a' is zero, 32 is returned.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static int8 countLeadingZeros32( bits32 a )
|
||||
{
|
||||
static const int8 countLeadingZerosHigh[] = {
|
||||
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
int8 shiftCount;
|
||||
|
||||
shiftCount = 0;
|
||||
if ( a < 0x10000 ) {
|
||||
shiftCount += 16;
|
||||
a <<= 16;
|
||||
}
|
||||
if ( a < 0x1000000 ) {
|
||||
shiftCount += 8;
|
||||
a <<= 8;
|
||||
}
|
||||
shiftCount += countLeadingZerosHigh[ a>>24 ];
|
||||
return shiftCount;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the number of leading 0 bits before the most-significant 1 bit of
|
||||
| `a'. If `a' is zero, 64 is returned.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static int8 countLeadingZeros64( bits64 a )
|
||||
{
|
||||
int8 shiftCount;
|
||||
|
||||
shiftCount = 0;
|
||||
if ( a < ( (bits64) 1 )<<32 ) {
|
||||
shiftCount += 32;
|
||||
}
|
||||
else {
|
||||
a >>= 32;
|
||||
}
|
||||
shiftCount += countLeadingZeros32( a );
|
||||
return shiftCount;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1'
|
||||
| is equal to the 128-bit value formed by concatenating `b0' and `b1'.
|
||||
| Otherwise, returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE flag eq128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
|
||||
{
|
||||
|
||||
return ( a0 == b0 ) && ( a1 == b1 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
|
||||
| than or equal to the 128-bit value formed by concatenating `b0' and `b1'.
|
||||
| Otherwise, returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE flag le128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
|
||||
{
|
||||
|
||||
return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 <= b1 ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is less
|
||||
| than the 128-bit value formed by concatenating `b0' and `b1'. Otherwise,
|
||||
| returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE flag lt128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
|
||||
{
|
||||
|
||||
return ( a0 < b0 ) || ( ( a0 == b0 ) && ( a1 < b1 ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the 128-bit value formed by concatenating `a0' and `a1' is
|
||||
| not equal to the 128-bit value formed by concatenating `b0' and `b1'.
|
||||
| Otherwise, returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
INLINE flag ne128( bits64 a0, bits64 a1, bits64 b0, bits64 b1 )
|
||||
{
|
||||
|
||||
return ( a0 != b0 ) || ( a1 != b1 );
|
||||
|
||||
}
|
||||
|
464
core/SoftFloat/softfloat-specialize.h
Normal file
464
core/SoftFloat/softfloat-specialize.h
Normal file
|
@ -0,0 +1,464 @@
|
|||
|
||||
/*============================================================================
|
||||
|
||||
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
|
||||
Arithmetic Package, Release 2b.
|
||||
|
||||
Written by John R. Hauser. This work was made possible in part by the
|
||||
International Computer Science Institute, located at Suite 600, 1947 Center
|
||||
Street, Berkeley, California 94704. Funding was partially provided by the
|
||||
National Science Foundation under grant MIP-9311980. The original version
|
||||
of this code was written as part of a project to build a fixed-point vector
|
||||
processor in collaboration with the University of California at Berkeley,
|
||||
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
|
||||
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
|
||||
arithmetic/SoftFloat.html'.
|
||||
|
||||
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
|
||||
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
|
||||
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
|
||||
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
|
||||
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
|
||||
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
|
||||
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
|
||||
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
|
||||
|
||||
Derivative works are acceptable, even for commercial purposes, so long as
|
||||
(1) the source code for the derivative work includes prominent notice that
|
||||
the work is derivative, and (2) the source code includes prominent notice with
|
||||
these four paragraphs for those parts of this code that are retained.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Underflow tininess-detection mode, statically initialized to default value.
|
||||
| (The declaration in `softfloat.h' must match the `int8' type here.)
|
||||
*----------------------------------------------------------------------------*/
|
||||
int8 float_detect_tininess = float_tininess_after_rounding;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Raises the exceptions specified by `flags'. Floating-point traps can be
|
||||
| defined here if desired. It is currently not possible for such a trap
|
||||
| to substitute a result value. If traps are not implemented, this routine
|
||||
| should be simply `float_exception_flags |= flags;'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
void float_raise( int8 flags )
|
||||
{
|
||||
|
||||
float_exception_flags |= flags;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Internal canonical NaN format.
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef struct {
|
||||
flag sign;
|
||||
bits64 high, low;
|
||||
} commonNaNT;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated single-precision NaN.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define float32_default_nan 0xFFC00000
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the single-precision floating-point value `a' is a NaN;
|
||||
| otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float32_is_nan( float32 a )
|
||||
{
|
||||
|
||||
return ( 0xFF000000 < (bits32) ( a<<1 ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the single-precision floating-point value `a' is a signaling
|
||||
| NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float32_is_signaling_nan( float32 a )
|
||||
{
|
||||
|
||||
return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the single-precision floating-point NaN
|
||||
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
|
||||
| exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static commonNaNT float32ToCommonNaN( float32 a )
|
||||
{
|
||||
commonNaNT z;
|
||||
|
||||
if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
|
||||
z.sign = a>>31;
|
||||
z.low = 0;
|
||||
z.high = ( (bits64) a )<<41;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the canonical NaN `a' to the single-
|
||||
| precision floating-point format.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static float32 commonNaNToFloat32( commonNaNT a )
|
||||
{
|
||||
|
||||
return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes two single-precision floating-point values `a' and `b', one of which
|
||||
| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
|
||||
| signaling NaN, the invalid exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static float32 propagateFloat32NaN( float32 a, float32 b )
|
||||
{
|
||||
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
|
||||
|
||||
aIsNaN = float32_is_nan( a );
|
||||
aIsSignalingNaN = float32_is_signaling_nan( a );
|
||||
bIsNaN = float32_is_nan( b );
|
||||
bIsSignalingNaN = float32_is_signaling_nan( b );
|
||||
a |= 0x00400000;
|
||||
b |= 0x00400000;
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
|
||||
if ( aIsSignalingNaN ) {
|
||||
if ( bIsSignalingNaN ) goto returnLargerSignificand;
|
||||
return bIsNaN ? b : a;
|
||||
}
|
||||
else if ( aIsNaN ) {
|
||||
if ( bIsSignalingNaN | ! bIsNaN ) return a;
|
||||
returnLargerSignificand:
|
||||
if ( (bits32) ( a<<1 ) < (bits32) ( b<<1 ) ) return b;
|
||||
if ( (bits32) ( b<<1 ) < (bits32) ( a<<1 ) ) return a;
|
||||
return ( a < b ) ? a : b;
|
||||
}
|
||||
else {
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated double-precision NaN.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define float64_default_nan LIT64( 0xFFF8000000000000 )
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the double-precision floating-point value `a' is a NaN;
|
||||
| otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float64_is_nan( float64 a )
|
||||
{
|
||||
|
||||
return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the double-precision floating-point value `a' is a signaling
|
||||
| NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float64_is_signaling_nan( float64 a )
|
||||
{
|
||||
|
||||
return
|
||||
( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
|
||||
&& ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the double-precision floating-point NaN
|
||||
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
|
||||
| exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static commonNaNT float64ToCommonNaN( float64 a )
|
||||
{
|
||||
commonNaNT z;
|
||||
|
||||
if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
|
||||
z.sign = a>>63;
|
||||
z.low = 0;
|
||||
z.high = a<<12;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the canonical NaN `a' to the double-
|
||||
| precision floating-point format.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static float64 commonNaNToFloat64( commonNaNT a )
|
||||
{
|
||||
|
||||
return
|
||||
( ( (bits64) a.sign )<<63 )
|
||||
| LIT64( 0x7FF8000000000000 )
|
||||
| ( a.high>>12 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes two double-precision floating-point values `a' and `b', one of which
|
||||
| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
|
||||
| signaling NaN, the invalid exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static float64 propagateFloat64NaN( float64 a, float64 b )
|
||||
{
|
||||
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
|
||||
|
||||
aIsNaN = float64_is_nan( a );
|
||||
aIsSignalingNaN = float64_is_signaling_nan( a );
|
||||
bIsNaN = float64_is_nan( b );
|
||||
bIsSignalingNaN = float64_is_signaling_nan( b );
|
||||
a |= LIT64( 0x0008000000000000 );
|
||||
b |= LIT64( 0x0008000000000000 );
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
|
||||
if ( aIsSignalingNaN ) {
|
||||
if ( bIsSignalingNaN ) goto returnLargerSignificand;
|
||||
return bIsNaN ? b : a;
|
||||
}
|
||||
else if ( aIsNaN ) {
|
||||
if ( bIsSignalingNaN | ! bIsNaN ) return a;
|
||||
returnLargerSignificand:
|
||||
if ( (bits64) ( a<<1 ) < (bits64) ( b<<1 ) ) return b;
|
||||
if ( (bits64) ( b<<1 ) < (bits64) ( a<<1 ) ) return a;
|
||||
return ( a < b ) ? a : b;
|
||||
}
|
||||
else {
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#ifdef FLOATX80
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated extended double-precision NaN. The
|
||||
| `high' and `low' values hold the most- and least-significant bits,
|
||||
| respectively.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define floatx80_default_nan_high 0xFFFF
|
||||
#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the extended double-precision floating-point value `a' is a
|
||||
| NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag floatx80_is_nan( floatx80 a )
|
||||
{
|
||||
|
||||
return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the extended double-precision floating-point value `a' is a
|
||||
| signaling NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag floatx80_is_signaling_nan( floatx80 a )
|
||||
{
|
||||
bits64 aLow;
|
||||
|
||||
aLow = a.low & ~ LIT64( 0x4000000000000000 );
|
||||
return
|
||||
( ( a.high & 0x7FFF ) == 0x7FFF )
|
||||
&& (bits64) ( aLow<<1 )
|
||||
&& ( a.low == aLow );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the extended double-precision floating-
|
||||
| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
|
||||
| invalid exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static commonNaNT floatx80ToCommonNaN( floatx80 a )
|
||||
{
|
||||
commonNaNT z;
|
||||
|
||||
if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
|
||||
z.sign = a.high>>15;
|
||||
z.low = 0;
|
||||
z.high = a.low<<1;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the canonical NaN `a' to the extended
|
||||
| double-precision floating-point format.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static floatx80 commonNaNToFloatx80( commonNaNT a )
|
||||
{
|
||||
floatx80 z;
|
||||
|
||||
z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
|
||||
z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes two extended double-precision floating-point values `a' and `b', one
|
||||
| of which is a NaN, and returns the appropriate NaN result. If either `a' or
|
||||
| `b' is a signaling NaN, the invalid exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
|
||||
{
|
||||
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
|
||||
|
||||
aIsNaN = floatx80_is_nan( a );
|
||||
aIsSignalingNaN = floatx80_is_signaling_nan( a );
|
||||
bIsNaN = floatx80_is_nan( b );
|
||||
bIsSignalingNaN = floatx80_is_signaling_nan( b );
|
||||
a.low |= LIT64( 0xC000000000000000 );
|
||||
b.low |= LIT64( 0xC000000000000000 );
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
|
||||
if ( aIsSignalingNaN ) {
|
||||
if ( bIsSignalingNaN ) goto returnLargerSignificand;
|
||||
return bIsNaN ? b : a;
|
||||
}
|
||||
else if ( aIsNaN ) {
|
||||
if ( bIsSignalingNaN | ! bIsNaN ) return a;
|
||||
returnLargerSignificand:
|
||||
if ( a.low < b.low ) return b;
|
||||
if ( b.low < a.low ) return a;
|
||||
return ( a.high < b.high ) ? a : b;
|
||||
}
|
||||
else {
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef FLOAT128
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The pattern for a default generated quadruple-precision NaN. The `high' and
|
||||
| `low' values hold the most- and least-significant bits, respectively.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
|
||||
#define float128_default_nan_low LIT64( 0x0000000000000000 )
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
|
||||
| otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float128_is_nan( float128 a )
|
||||
{
|
||||
|
||||
return
|
||||
( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
|
||||
&& ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns 1 if the quadruple-precision floating-point value `a' is a
|
||||
| signaling NaN; otherwise returns 0.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
flag float128_is_signaling_nan( float128 a )
|
||||
{
|
||||
|
||||
return
|
||||
( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
|
||||
&& ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the quadruple-precision floating-point NaN
|
||||
| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
|
||||
| exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static commonNaNT float128ToCommonNaN( float128 a )
|
||||
{
|
||||
commonNaNT z;
|
||||
|
||||
if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
|
||||
z.sign = a.high>>63;
|
||||
shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Returns the result of converting the canonical NaN `a' to the quadruple-
|
||||
| precision floating-point format.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static float128 commonNaNToFloat128( commonNaNT a )
|
||||
{
|
||||
float128 z;
|
||||
|
||||
shift128Right( a.high, a.low, 16, &z.high, &z.low );
|
||||
z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Takes two quadruple-precision floating-point values `a' and `b', one of
|
||||
| which is a NaN, and returns the appropriate NaN result. If either `a' or
|
||||
| `b' is a signaling NaN, the invalid exception is raised.
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
static float128 propagateFloat128NaN( float128 a, float128 b )
|
||||
{
|
||||
flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
|
||||
|
||||
aIsNaN = float128_is_nan( a );
|
||||
aIsSignalingNaN = float128_is_signaling_nan( a );
|
||||
bIsNaN = float128_is_nan( b );
|
||||
bIsSignalingNaN = float128_is_signaling_nan( b );
|
||||
a.high |= LIT64( 0x0000800000000000 );
|
||||
b.high |= LIT64( 0x0000800000000000 );
|
||||
if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
|
||||
if ( aIsSignalingNaN ) {
|
||||
if ( bIsSignalingNaN ) goto returnLargerSignificand;
|
||||
return bIsNaN ? b : a;
|
||||
}
|
||||
else if ( aIsNaN ) {
|
||||
if ( bIsSignalingNaN | ! bIsNaN ) return a;
|
||||
returnLargerSignificand:
|
||||
if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
|
||||
if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
|
||||
return ( a.high < b.high ) ? a : b;
|
||||
}
|
||||
else {
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
5400
core/SoftFloat/softfloat.c
Normal file
5400
core/SoftFloat/softfloat.c
Normal file
File diff suppressed because it is too large
Load Diff
259
core/SoftFloat/softfloat.h
Normal file
259
core/SoftFloat/softfloat.h
Normal file
|
@ -0,0 +1,259 @@
|
|||
|
||||
/*============================================================================
|
||||
|
||||
This C header file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
|
||||
Package, Release 2b.
|
||||
|
||||
Written by John R. Hauser. This work was made possible in part by the
|
||||
International Computer Science Institute, located at Suite 600, 1947 Center
|
||||
Street, Berkeley, California 94704. Funding was partially provided by the
|
||||
National Science Foundation under grant MIP-9311980. The original version
|
||||
of this code was written as part of a project to build a fixed-point vector
|
||||
processor in collaboration with the University of California at Berkeley,
|
||||
overseen by Profs. Nelson Morgan and John Wawrzynek. More information
|
||||
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
|
||||
arithmetic/SoftFloat.html'.
|
||||
|
||||
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
|
||||
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
|
||||
RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
|
||||
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
|
||||
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
|
||||
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
|
||||
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
|
||||
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
|
||||
|
||||
Derivative works are acceptable, even for commercial purposes, so long as
|
||||
(1) the source code for the derivative work includes prominent notice that
|
||||
the work is derivative, and (2) the source code includes prominent notice with
|
||||
these four paragraphs for those parts of this code that are retained.
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| The macro `FLOATX80' must be defined to enable the extended double-precision
|
||||
| floating-point format `floatx80'. If this macro is not defined, the
|
||||
| `floatx80' type will not be defined, and none of the functions that either
|
||||
| input or output the `floatx80' type will be defined. The same applies to
|
||||
| the `FLOAT128' macro and the quadruple-precision format `float128'.
|
||||
*----------------------------------------------------------------------------*/
|
||||
#define FLOATX80
|
||||
#define FLOAT128
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point types.
|
||||
*----------------------------------------------------------------------------*/
|
||||
typedef unsigned int float32;
|
||||
typedef unsigned long long float64;
|
||||
#ifdef FLOATX80
|
||||
typedef struct {
|
||||
unsigned long long low;
|
||||
unsigned short high;
|
||||
} floatx80;
|
||||
#endif
|
||||
#ifdef FLOAT128
|
||||
typedef struct {
|
||||
unsigned long long low, high;
|
||||
} float128;
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point underflow tininess-detection mode.
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern signed char float_detect_tininess;
|
||||
enum {
|
||||
float_tininess_after_rounding = 0,
|
||||
float_tininess_before_rounding = 1
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point rounding mode.
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern signed char float_rounding_mode;
|
||||
enum {
|
||||
float_round_nearest_even = 0,
|
||||
float_round_down = 1,
|
||||
float_round_up = 2,
|
||||
float_round_to_zero = 3
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE floating-point exception flags.
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern signed char float_exception_flags;
|
||||
enum {
|
||||
float_flag_invalid = 1,
|
||||
float_flag_divbyzero = 4,
|
||||
float_flag_overflow = 8,
|
||||
float_flag_underflow = 16,
|
||||
float_flag_inexact = 32
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Routine to raise any or all of the software IEC/IEEE floating-point
|
||||
| exception flags.
|
||||
*----------------------------------------------------------------------------*/
|
||||
void float_raise( signed char );
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE integer-to-floating-point conversion routines.
|
||||
*----------------------------------------------------------------------------*/
|
||||
float32 int32_to_float32( int );
|
||||
float64 int32_to_float64( int );
|
||||
#ifdef FLOATX80
|
||||
floatx80 int32_to_floatx80( int );
|
||||
#endif
|
||||
#ifdef FLOAT128
|
||||
float128 int32_to_float128( int );
|
||||
#endif
|
||||
float32 int64_to_float32( long long );
|
||||
float64 int64_to_float64( long long );
|
||||
#ifdef FLOATX80
|
||||
floatx80 int64_to_floatx80( long long );
|
||||
#endif
|
||||
#ifdef FLOAT128
|
||||
float128 int64_to_float128( long long );
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE single-precision conversion routines.
|
||||
*----------------------------------------------------------------------------*/
|
||||
int float32_to_int32( float32 );
|
||||
int float32_to_int32_round_to_zero( float32 );
|
||||
long long float32_to_int64( float32 );
|
||||
long long float32_to_int64_round_to_zero( float32 );
|
||||
float64 float32_to_float64( float32 );
|
||||
#ifdef FLOATX80
|
||||
floatx80 float32_to_floatx80( float32 );
|
||||
#endif
|
||||
#ifdef FLOAT128
|
||||
float128 float32_to_float128( float32 );
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE single-precision operations.
|
||||
*----------------------------------------------------------------------------*/
|
||||
float32 float32_round_to_int( float32 );
|
||||
float32 float32_add( float32, float32 );
|
||||
float32 float32_sub( float32, float32 );
|
||||
float32 float32_mul( float32, float32 );
|
||||
float32 float32_div( float32, float32 );
|
||||
float32 float32_rem( float32, float32 );
|
||||
float32 float32_sqrt( float32 );
|
||||
char float32_eq( float32, float32 );
|
||||
char float32_le( float32, float32 );
|
||||
char float32_lt( float32, float32 );
|
||||
char float32_eq_signaling( float32, float32 );
|
||||
char float32_le_quiet( float32, float32 );
|
||||
char float32_lt_quiet( float32, float32 );
|
||||
char float32_is_signaling_nan( float32 );
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE double-precision conversion routines.
|
||||
*----------------------------------------------------------------------------*/
|
||||
int float64_to_int32( float64 );
|
||||
int float64_to_int32_round_to_zero( float64 );
|
||||
long long float64_to_int64( float64 );
|
||||
long long float64_to_int64_round_to_zero( float64 );
|
||||
float32 float64_to_float32( float64 );
|
||||
#ifdef FLOATX80
|
||||
floatx80 float64_to_floatx80( float64 );
|
||||
#endif
|
||||
#ifdef FLOAT128
|
||||
float128 float64_to_float128( float64 );
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE double-precision operations.
|
||||
*----------------------------------------------------------------------------*/
|
||||
float64 float64_round_to_int( float64 );
|
||||
float64 float64_add( float64, float64 );
|
||||
float64 float64_sub( float64, float64 );
|
||||
float64 float64_mul( float64, float64 );
|
||||
float64 float64_div( float64, float64 );
|
||||
float64 float64_rem( float64, float64 );
|
||||
float64 float64_sqrt( float64 );
|
||||
char float64_eq( float64, float64 );
|
||||
char float64_le( float64, float64 );
|
||||
char float64_lt( float64, float64 );
|
||||
char float64_eq_signaling( float64, float64 );
|
||||
char float64_le_quiet( float64, float64 );
|
||||
char float64_lt_quiet( float64, float64 );
|
||||
char float64_is_signaling_nan( float64 );
|
||||
|
||||
#ifdef FLOATX80
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE extended double-precision conversion routines.
|
||||
*----------------------------------------------------------------------------*/
|
||||
int floatx80_to_int32( floatx80 );
|
||||
int floatx80_to_int32_round_to_zero( floatx80 );
|
||||
long long floatx80_to_int64( floatx80 );
|
||||
long long floatx80_to_int64_round_to_zero( floatx80 );
|
||||
float32 floatx80_to_float32( floatx80 );
|
||||
float64 floatx80_to_float64( floatx80 );
|
||||
#ifdef FLOAT128
|
||||
float128 floatx80_to_float128( floatx80 );
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE extended double-precision rounding precision. Valid
|
||||
| values are 32, 64, and 80.
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern signed char floatx80_rounding_precision;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE extended double-precision operations.
|
||||
*----------------------------------------------------------------------------*/
|
||||
floatx80 floatx80_round_to_int( floatx80 );
|
||||
floatx80 floatx80_add( floatx80, floatx80 );
|
||||
floatx80 floatx80_sub( floatx80, floatx80 );
|
||||
floatx80 floatx80_mul( floatx80, floatx80 );
|
||||
floatx80 floatx80_div( floatx80, floatx80 );
|
||||
floatx80 floatx80_rem( floatx80, floatx80 );
|
||||
floatx80 floatx80_sqrt( floatx80 );
|
||||
char floatx80_eq( floatx80, floatx80 );
|
||||
char floatx80_le( floatx80, floatx80 );
|
||||
char floatx80_lt( floatx80, floatx80 );
|
||||
char floatx80_eq_signaling( floatx80, floatx80 );
|
||||
char floatx80_le_quiet( floatx80, floatx80 );
|
||||
char floatx80_lt_quiet( floatx80, floatx80 );
|
||||
char floatx80_is_signaling_nan( floatx80 );
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef FLOAT128
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE quadruple-precision conversion routines.
|
||||
*----------------------------------------------------------------------------*/
|
||||
int float128_to_int32( float128 );
|
||||
int float128_to_int32_round_to_zero( float128 );
|
||||
long long float128_to_int64( float128 );
|
||||
long long float128_to_int64_round_to_zero( float128 );
|
||||
float32 float128_to_float32( float128 );
|
||||
float64 float128_to_float64( float128 );
|
||||
#ifdef FLOATX80
|
||||
floatx80 float128_to_floatx80( float128 );
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
| Software IEC/IEEE quadruple-precision operations.
|
||||
*----------------------------------------------------------------------------*/
|
||||
float128 float128_round_to_int( float128 );
|
||||
float128 float128_add( float128, float128 );
|
||||
float128 float128_sub( float128, float128 );
|
||||
float128 float128_mul( float128, float128 );
|
||||
float128 float128_div( float128, float128 );
|
||||
float128 float128_rem( float128, float128 );
|
||||
float128 float128_sqrt( float128 );
|
||||
char float128_eq( float128, float128 );
|
||||
char float128_le( float128, float128 );
|
||||
char float128_lt( float128, float128 );
|
||||
char float128_eq_signaling( float128, float128 );
|
||||
char float128_le_quiet( float128, float128 );
|
||||
char float128_lt_quiet( float128, float128 );
|
||||
char float128_is_signaling_nan( float128 );
|
||||
|
||||
#endif
|
||||
|
|
@ -56,7 +56,8 @@ void shoebill_stop()
|
|||
pthread_join(shoe.via_thread_pid, NULL);
|
||||
pthread_mutex_destroy(&shoe.via_clock_thread_lock);
|
||||
|
||||
unstop_cpu_thread(); // wake up the CPU thread if it was STOPPED
|
||||
// wake up the CPU thread if it was STOPPED
|
||||
unstop_cpu_thread();
|
||||
|
||||
pthread_join(shoe.cpu_thread_pid, NULL);
|
||||
pthread_mutex_destroy(&shoe.cpu_thread_lock);
|
||||
|
@ -68,6 +69,11 @@ void shoebill_stop()
|
|||
|
||||
shoe.running = 0;
|
||||
|
||||
// Destroy all the nubus cards
|
||||
for (i=0; i<15; i++)
|
||||
if (shoe.slots[i].destroy_func)
|
||||
shoe.slots[i].destroy_func(i);
|
||||
|
||||
// Close all the SCSI disk images
|
||||
for (i=0; i<8; i++) {
|
||||
if (shoe.scsi_devices[i].f)
|
||||
|
@ -109,15 +115,15 @@ void *_cpu_thread (void *arg)
|
|||
pthread_mutex_lock(&shoe.cpu_thread_lock);
|
||||
|
||||
while (1) {
|
||||
if (shoe.cpu_thread_notifications) {
|
||||
if sunlikely(shoe.cpu_thread_notifications) {
|
||||
|
||||
// If there's an interrupt pending
|
||||
if (shoe.cpu_thread_notifications & 0xff) {
|
||||
if slikely(shoe.cpu_thread_notifications & 0xff) {
|
||||
// process_pending_interrupt() may clear SHOEBILL_STATE_STOPPED
|
||||
process_pending_interrupt();
|
||||
}
|
||||
|
||||
if (shoe.cpu_thread_notifications & SHOEBILL_STATE_RETURN) {
|
||||
if sunlikely(shoe.cpu_thread_notifications & SHOEBILL_STATE_RETURN) {
|
||||
pthread_mutex_unlock(&shoe.cpu_thread_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -165,7 +171,7 @@ struct __attribute__ ((__packed__)) kernel_info {
|
|||
// A series of DrvQEl (drive queue elements) follow this structure
|
||||
};
|
||||
|
||||
/* Inside Macintosh: Files 2-85 throughtfully provides this information
|
||||
/* Inside Macintosh: Files 2-85 thoughtfully provides this information
|
||||
* on the secret internal flags:
|
||||
*
|
||||
* The File Manager also maintains four flag bytes preceding each drive queue element.
|
||||
|
@ -548,6 +554,7 @@ uint32_t shoebill_install_video_card(shoebill_config_t *config, uint8_t slotnum,
|
|||
shoe.slots[slotnum].connected = 1;
|
||||
shoe.slots[slotnum].read_func = nubus_video_read_func;
|
||||
shoe.slots[slotnum].write_func = nubus_video_write_func;
|
||||
shoe.slots[slotnum].destroy_func = NULL;
|
||||
shoe.slots[slotnum].interrupts_enabled = 1;
|
||||
nubus_video_init(ctx, slotnum, width, height, scanline_width);
|
||||
return 1;
|
||||
|
@ -570,11 +577,34 @@ uint32_t shoebill_install_tfb_card(shoebill_config_t *config, uint8_t slotnum)
|
|||
shoe.slots[slotnum].connected = 1;
|
||||
shoe.slots[slotnum].read_func = nubus_tfb_read_func;
|
||||
shoe.slots[slotnum].write_func = nubus_tfb_write_func;
|
||||
shoe.slots[slotnum].destroy_func = NULL;
|
||||
shoe.slots[slotnum].interrupts_enabled = 1;
|
||||
nubus_tfb_init(ctx, slotnum);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t shoebill_install_ethernet_card(shoebill_config_t *config, uint8_t slotnum, uint8_t ethernet_addr[6], int tap_fd)
|
||||
{
|
||||
shoebill_card_ethernet_t *ctx;
|
||||
|
||||
if (shoe.slots[slotnum].card_type != card_none) {
|
||||
sprintf(config->error_msg, "This slot (%u) already has a card\n", slotnum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx = p_alloc(shoe.pool, sizeof(shoebill_card_ethernet_t));
|
||||
shoe.slots[slotnum].ctx = ctx;
|
||||
|
||||
shoe.slots[slotnum].card_type = card_shoebill_ethernet;
|
||||
shoe.slots[slotnum].connected = 1;
|
||||
shoe.slots[slotnum].read_func = nubus_ethernet_read_func;
|
||||
shoe.slots[slotnum].write_func = nubus_ethernet_write_func;
|
||||
shoe.slots[slotnum].destroy_func = nubus_ethernet_destroy_func;
|
||||
shoe.slots[slotnum].interrupts_enabled = 1;
|
||||
nubus_ethernet_init(ctx, slotnum, ethernet_addr, tap_fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
shoebill_video_frame_info_t shoebill_get_video_frame(uint8_t slotnum,
|
||||
_Bool just_params)
|
||||
{
|
||||
|
@ -621,7 +651,7 @@ uint32_t shoebill_initialize(shoebill_config_t *config)
|
|||
|
||||
shoe.pool = p_new_pool(NULL);
|
||||
|
||||
fpu_setup_jump_table();
|
||||
fpu_initialize();
|
||||
|
||||
// Try to load the ROM
|
||||
if (config->rom_path == NULL) {
|
||||
|
@ -707,7 +737,10 @@ uint32_t shoebill_initialize(shoebill_config_t *config)
|
|||
init_adb_state();
|
||||
init_scsi_bus_state();
|
||||
init_iwm_state();
|
||||
init_asc_state();
|
||||
|
||||
/* Invalidate the pc cache */
|
||||
invalidate_pccache();
|
||||
|
||||
set_sr(0x2000);
|
||||
shoe.pc = pc;
|
||||
|
@ -769,6 +802,9 @@ void shoebill_restart (void)
|
|||
// clear the pmmu cache
|
||||
memset(shoe.pmmu_cache, 0, sizeof(shoe.pmmu_cache));
|
||||
|
||||
// Invalidate the pc cache
|
||||
invalidate_pccache();
|
||||
|
||||
// Reset all CPU registers
|
||||
memset(shoe.d, 0, sizeof(shoe.d));
|
||||
memset(shoe.a, 0, sizeof(shoe.a));
|
||||
|
@ -783,6 +819,8 @@ void shoebill_restart (void)
|
|||
// Reset all pmmu registers
|
||||
shoe.crp = shoe.srp = shoe.drp = 0;
|
||||
shoe.tc = 0;
|
||||
shoe.tc_pagesize = shoe.tc_pagemask = 0;
|
||||
shoe.tc_ps = shoe.tc_is = shoe.tc_is_plus_ps = shoe.tc_enable = shoe.tc_sre = 0;
|
||||
shoe.pcsr = 0;
|
||||
shoe.ac = 0;
|
||||
memset(shoe.bad, 0, sizeof(shoe.bad));
|
||||
|
@ -793,11 +831,7 @@ void shoebill_restart (void)
|
|||
shoe.psr.word = 0;
|
||||
|
||||
// Reset all FPU registers
|
||||
shoe.fpiar = 0;
|
||||
shoe.fpcr.raw = 0;
|
||||
shoe.fpsr.raw = 0;
|
||||
memset(shoe.fp, 0, sizeof(shoe.fp));
|
||||
|
||||
fpu_reset();
|
||||
|
||||
// Free the old unix coff_file,
|
||||
coff_free(shoe.coff);
|
||||
|
@ -992,6 +1026,8 @@ void slog(const char *fmt, ...)
|
|||
va_start(args, fmt);
|
||||
vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
|
|
1183
core/cpu.c
1183
core/cpu.c
File diff suppressed because it is too large
Load Diff
|
@ -1493,14 +1493,8 @@ void begin_definitions()
|
|||
|
||||
/* --- FPU (68881) instructions --- */
|
||||
|
||||
{
|
||||
inst_t *inst = new_inst("fpu_decode", "2", 1);
|
||||
add_range(inst, "1111 001 xxx xxxxxx");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
/* { // all other fpu ops
|
||||
inst_t *inst = new_inst("fpu_decode", "2", 1);
|
||||
{ // all other fpu ops
|
||||
inst_t *inst = new_inst("fpu_other", "2", 1);
|
||||
add_range(inst, "1111 001 000 MMMMMM");
|
||||
ea_all(inst);
|
||||
}
|
||||
|
@ -1511,9 +1505,30 @@ void begin_definitions()
|
|||
ea_data_alterable(inst);
|
||||
}
|
||||
|
||||
{ // FDBcc
|
||||
inst_t *inst = new_inst("fdbcc", "2", 1);
|
||||
add_range(inst, "1111 001 001 001xxx");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
{ // FTRAPcc
|
||||
inst_t *inst = new_inst("ftrapcc", "2", 1);
|
||||
add_range(inst, "1111 001 001 111 010");
|
||||
add_range(inst, "1111 001 001 111 011");
|
||||
add_range(inst, "1111 001 001 111 100");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
{ // FBcc
|
||||
inst_t *inst = new_inst("fbcc", "2", 1);
|
||||
add_range(inst, "1111 001 01x xxxxxx");
|
||||
sub_range(inst, "1111 001 010 000000"); // fnop
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
{ // fnop
|
||||
inst_t *inst = new_inst("fnop", "2", 1);
|
||||
add_range(inst, "1111 001 010 000000");
|
||||
no_ea(inst);
|
||||
}
|
||||
|
||||
|
@ -1529,7 +1544,7 @@ void begin_definitions()
|
|||
add_range(inst, "1111 001 101 MMMMMM");
|
||||
ea_control(inst);
|
||||
ea_add_mode(inst, EA_011);
|
||||
}*/
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
278
core/dis.c
278
core/dis.c
|
@ -47,6 +47,12 @@ uint16_t dis_next_word (void)
|
|||
return next;
|
||||
}
|
||||
|
||||
uint32_t dis_next_long (void)
|
||||
{
|
||||
uint32_t next = dis_next_word();
|
||||
return (next << 16) | dis_next_word();
|
||||
}
|
||||
|
||||
//
|
||||
// EA decoder routines
|
||||
//
|
||||
|
@ -269,8 +275,13 @@ char* decode_ea_rw (uint8_t mr, uint8_t sz)
|
|||
} else if (sz == 2) {
|
||||
sprintf(str, "0x%04x", ext);
|
||||
} else {
|
||||
const uint16_t ext2 = dis_next_word();
|
||||
sprintf(str, "0x%04x%04x", ext, ext2);
|
||||
uint32_t i;
|
||||
assert((sz & 1) == 0);
|
||||
sprintf(str, "0x%04x", ext);
|
||||
for (i=2; i<sz; i+=2) {
|
||||
const uint16_t ext2 = dis_next_word();
|
||||
sprintf(str + strlen(str), "%04x", ext2);
|
||||
}
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
@ -290,7 +301,8 @@ char* decode_ea_addr (uint8_t mr)
|
|||
char *str = dis.ea_str_internal + dis.ea_last_pos_internal;
|
||||
dis.ea_last_pos_internal = (dis.ea_last_pos_internal+256) % 1024;
|
||||
switch (mode) {
|
||||
case 0 ... 1: { // Data/address register direct mode
|
||||
case 0:
|
||||
case 1: { // Data/address register direct mode
|
||||
sprintf(str, "???");
|
||||
return str;
|
||||
}
|
||||
|
@ -299,11 +311,11 @@ char* decode_ea_addr (uint8_t mr)
|
|||
return str;
|
||||
}
|
||||
case 3: { // address register indirect with postincrement mode
|
||||
sprintf(str, "???");
|
||||
sprintf(str, "(a%u)+", reg);
|
||||
return str;
|
||||
}
|
||||
case 4: { // address register indirect with predecrement mode
|
||||
sprintf(str, "???");
|
||||
sprintf(str, "-(a%u)", reg);
|
||||
return str;
|
||||
}
|
||||
case 5: { // address register indirect with displacement mode
|
||||
|
@ -537,7 +549,18 @@ void dis_eori_to_sr() {
|
|||
}
|
||||
|
||||
void dis_movep() {
|
||||
sprintf(dis.str, "movep???");
|
||||
const int16_t disp = dis_next_word();
|
||||
~decompose(dis_op, 0000 ddd 1 s r 001 aaa);
|
||||
|
||||
if (r) { // reg -> mem
|
||||
sprintf(dis.str, "movep.%c d%u,%s0x%x(a%u)", "wl"[s], d,
|
||||
(disp >= 0) ? "" : "-", abs(disp), a);
|
||||
}
|
||||
else { // mem -> reg
|
||||
sprintf(dis.str, "movep.%c %s0x%x(a%u),d%u", "wl"[s],
|
||||
(disp >= 0) ? "" : "-", abs(disp), a, d);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void dis_bfextu() {
|
||||
|
@ -754,7 +777,7 @@ void dis_long_div () {
|
|||
sprintf(dest, "d%u", R);
|
||||
if (Q != R)
|
||||
sprintf(dest+2, ":d%u", Q);
|
||||
sprintf(dis.str, "div%c%s.l %s,%s", "us"[u], s?"":"l", decode_ea_rw(M, 4), dest);
|
||||
sprintf(dis.str, "div%c%s.l %s,%s", "us"[u], s?"l":"", decode_ea_rw(M, 4), dest);
|
||||
}
|
||||
|
||||
void dis_cmpm () {
|
||||
|
@ -1093,11 +1116,16 @@ void dis_pea() {
|
|||
}
|
||||
|
||||
void dis_nbcd() {
|
||||
sprintf(dis.str, "nbcd???");
|
||||
~decompose(dis_op, 0100 1000 00 MMMMMM);
|
||||
sprintf(dis.str, "nbcd %s", decode_ea_rw(M, 1));
|
||||
}
|
||||
|
||||
void dis_sbcd() {
|
||||
sprintf(dis.str, "sbcd???");
|
||||
~decompose(dis_op, 1000 yyy 10000 r xxx);
|
||||
if (r)
|
||||
sprintf(dis.str, "sbcd d%u,d%u", x, y);
|
||||
else
|
||||
sprintf(dis.str, "sbcd -(a%u),-(a%u)", x, y);
|
||||
}
|
||||
|
||||
void dis_pack() {
|
||||
|
@ -1119,7 +1147,8 @@ void dis_divs() {
|
|||
}
|
||||
|
||||
void dis_bkpt() {
|
||||
sprintf(dis.str, "bkpt???");
|
||||
~decompose(dis_op, 0100 1000 0100 1 vvv);
|
||||
sprintf(dis.str, "bkpt %u", v);
|
||||
}
|
||||
|
||||
void dis_swap() {
|
||||
|
@ -1400,23 +1429,43 @@ void dis_move16 () {
|
|||
}
|
||||
|
||||
void dis_rtm () {
|
||||
sprintf(dis.str, "rtm???");
|
||||
~decompose(dis_op, 0000 0110 1100 d rrr);
|
||||
sprintf(dis.str, "rtm %c%u", "da"[d], r);
|
||||
}
|
||||
|
||||
void dis_tas () {
|
||||
sprintf(dis.str, "tas???");
|
||||
~decompose(dis_op, 1000 rrr 011 MMMMMM);
|
||||
sprintf(dis.str, "tas.b %s", decode_ea_rw(M, 1));
|
||||
}
|
||||
|
||||
void dis_trapcc() {
|
||||
sprintf(dis.str, "trapcc???");
|
||||
~decompose(dis_op, 0101 cccc 11111 ooo);
|
||||
|
||||
const char *condition_names[16] = {
|
||||
"t", "ra", "hi", "ls", "cc", "cs", "ne", "eq",
|
||||
"vc", "vs", "pl", "mi", "ge", "lt", "gt", "le"
|
||||
};
|
||||
|
||||
uint32_t data;
|
||||
switch (o) {
|
||||
case 2:
|
||||
data = dis_next_word();
|
||||
sprintf(dis.str, "trap%s.w 0x%04x", condition_names[c], data);
|
||||
break;
|
||||
case 3:
|
||||
data = dis_next_long();
|
||||
sprintf(dis.str, "trap%s.l 0x%08x", condition_names[c], data);
|
||||
break;
|
||||
case 4:
|
||||
sprintf(dis.str, "trap%s", condition_names[c]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void dis_trapv() {
|
||||
sprintf(dis.str, "trapv???");
|
||||
sprintf(dis.str, "trapv");
|
||||
}
|
||||
|
||||
|
||||
|
||||
void dis_mc68851_decode() {
|
||||
~decompose(dis_op, 1111 000 a b c MMMMMM);
|
||||
|
||||
|
@ -1484,6 +1533,203 @@ void dis_mc68851_decode() {
|
|||
assert(!"never get here");
|
||||
}
|
||||
|
||||
const char *_fcc_names[32] = {
|
||||
"f", "eq", "ogt", "oge", "olt", "ole", "ogl", "or",
|
||||
"un", "ueq", "ugt", "uge", "ult", "ule", "ne", "t",
|
||||
"sf", "seq", "gt", "ge", "lt", "le", "gl", "gle",
|
||||
"ngle", "ngl", "nle", "nlt", "nge", "ngt", "sne", "st"
|
||||
};
|
||||
|
||||
static void dis_fmove_to_mem(uint16_t ext)
|
||||
{
|
||||
const uint8_t _format_sizes[8] = {4, 4, 12, 12, 2, 8, 1, 12};
|
||||
~decompose(dis_op, 1111 001 000 MMMMMM);
|
||||
~decompose(ext, 011 fff sss kkkkkkk);
|
||||
|
||||
sprintf(dis.str, "fmove.%c", "lsxpwdbp"[f]);
|
||||
if (f == 3)
|
||||
sprintf(dis.str + strlen(dis.str), "{#%u}", k);
|
||||
else
|
||||
sprintf(dis.str + strlen(dis.str), "{d%u}", k >> 4);
|
||||
|
||||
sprintf(dis.str + strlen(dis.str), " fp%u,%s", s,
|
||||
decode_ea_rw(M, _format_sizes[f]));
|
||||
}
|
||||
|
||||
static void dis_fmovem_control(uint16_t ext)
|
||||
{
|
||||
~decompose(dis_op, 1111 001 000 MMMMMM);
|
||||
~decompose(ext, 10 d CSI 0000 000000);
|
||||
|
||||
sprintf(dis.str, "fmovem.l ");
|
||||
const uint16_t count = C + S + I;
|
||||
if (count == 0)
|
||||
sprintf(dis.str + strlen(dis.str), "0,");
|
||||
|
||||
if (C)
|
||||
sprintf(dis.str + strlen(dis.str), "fpcr%s", (count > 1)?"&":",");
|
||||
|
||||
if (S)
|
||||
sprintf(dis.str + strlen(dis.str), "fpsr%s", ((S+I) > 1)?"&":",");
|
||||
|
||||
if (I)
|
||||
sprintf(dis.str + strlen(dis.str), "fpiar,");
|
||||
|
||||
sprintf(dis.str + strlen(dis.str), "%s", decode_ea_rw(M, count * 4));
|
||||
}
|
||||
|
||||
static void dis_fmovem(uint16_t ext)
|
||||
{
|
||||
~decompose(dis_op, 1111 001 000 mmmrrr);
|
||||
~decompose(dis_op, 1111 001 000 MMMMMM);
|
||||
~decompose(ext, 11 d ps 000 LLLLLLLL); // Static register mask
|
||||
~decompose(ext, 11 0 00 000 0yyy0000); // Register for dynamic mode
|
||||
|
||||
if (s) { // if dynamic mode
|
||||
if (d) // mem -> reg
|
||||
sprintf(dis.str, "fmovem.x %s,a%u", decode_ea_rw(M, 4), y);
|
||||
else
|
||||
sprintf(dis.str, "fmovem.x a%u,%s", y, decode_ea_rw(M, 4));
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t i, count=0;
|
||||
char list[64] = "";
|
||||
uint8_t oldmask = L, mask = L;
|
||||
|
||||
// for predecrement mode, the mask is reversed
|
||||
if (m == 4) {
|
||||
for (i=0; i<8; i++) {
|
||||
mask <<= 1;
|
||||
mask |= (oldmask & 1);
|
||||
oldmask >>= 1;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<8; i++) {
|
||||
if (mask & 0x80)
|
||||
sprintf(list + strlen(list), "fp%u.", i);
|
||||
mask <<= 1;
|
||||
}
|
||||
|
||||
if (d) // mem -> reg
|
||||
sprintf(dis.str, "fmovem.x %s,%s", decode_ea_rw(M, 4), list);
|
||||
else // reg -> mem
|
||||
sprintf(dis.str, "fmovem.x %s,%s", list, decode_ea_rw(M, 4));
|
||||
}
|
||||
|
||||
void dis_fscc () {
|
||||
~decompose(dis_op, 1111 001 001 MMMMMM);
|
||||
const uint16_t ext = dis_next_word();
|
||||
~decompose(ext, 0000 0000 00 0ccccc);
|
||||
|
||||
sprintf(dis.str, "fs%s.b %s", _fcc_names[c], decode_ea_rw(M, 1));
|
||||
}
|
||||
|
||||
void dis_fbcc () {
|
||||
~decompose(dis_op, 1111 001 01s 0ccccc);
|
||||
|
||||
uint32_t new_pc = dis.orig_pc + 2;
|
||||
if (s == 0) {
|
||||
const int16_t tmp = dis_next_word();
|
||||
new_pc += tmp;
|
||||
}
|
||||
else
|
||||
new_pc += dis_next_long();
|
||||
|
||||
sprintf(dis.str, "fb%s.%c *0x%08x", _fcc_names[c], "wl"[s], new_pc);
|
||||
}
|
||||
|
||||
void dis_fsave () {
|
||||
~decompose(dis_op, 1111 001 100 MMMMMM);
|
||||
sprintf(dis.str, "fsave %s", decode_ea_addr(M));
|
||||
}
|
||||
|
||||
void dis_frestore () {
|
||||
~decompose(dis_op, 1111 001 101 MMMMMM);
|
||||
sprintf(dis.str, "frestore %s", decode_ea_addr(M));
|
||||
}
|
||||
|
||||
void dis_fpu_other () {
|
||||
~decompose(dis_op, 1111 001 000 MMMMMM);
|
||||
|
||||
const uint16_t ext = dis_next_word();
|
||||
~decompose(ext, ccc xxx yyy eeeeeee);
|
||||
|
||||
switch (c) {
|
||||
case 0: // Reg to reg
|
||||
dis_fmath(dis_op, ext, dis.str);
|
||||
return;
|
||||
|
||||
case 1: // unused
|
||||
sprintf(dis.str, "f???");
|
||||
return;
|
||||
|
||||
case 2: // Memory->reg & movec
|
||||
dis_fmath(dis_op, ext, dis.str);
|
||||
return;
|
||||
|
||||
case 3: // reg->mem
|
||||
dis_fmove_to_mem(ext);
|
||||
return;
|
||||
|
||||
case 4: // mem -> sys ctl registers
|
||||
case 5: // sys ctl registers -> mem
|
||||
dis_fmovem_control(ext);
|
||||
return;
|
||||
|
||||
case 6: // movem to fp registers
|
||||
case 7: // movem to memory
|
||||
dis_fmovem(ext);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void dis_fdbcc () {
|
||||
~decompose(dis_op, 1111 001 001 001 rrr);
|
||||
const uint16_t ext = dis_next_word();
|
||||
~decompose(ext, 0000 0000 00 0ccccc);
|
||||
const int16_t disp = dis_next_word();
|
||||
|
||||
// FIXME: 68kprm is helpfully unclear about which address
|
||||
// to add the displacement. Based on cpDBcc, dbcc, bcc, and fbcc,
|
||||
// I'm guessing it starts at the address *of* the displacement
|
||||
const uint32_t newpc = dis.orig_pc + 4 + disp;
|
||||
|
||||
sprintf(dis.str, "fdb%s d%u,0x%08x", _fcc_names[c], r, newpc);
|
||||
}
|
||||
|
||||
void dis_ftrapcc () {
|
||||
~decompose(dis_op, 1111 001 001 111 ooo);
|
||||
const uint16_t ext = dis_next_word();
|
||||
~decompose(ext, 0000 0000 00 0ccccc);
|
||||
uint32_t data;
|
||||
|
||||
switch (o) {
|
||||
case 2:
|
||||
data = dis_next_word();
|
||||
sprintf(dis.str, "ftrap%s.w 0x%04x", _fcc_names[c], data);
|
||||
break;
|
||||
case 3:
|
||||
data = dis_next_long();
|
||||
sprintf(dis.str, "ftrap%s.l 0x%08x", _fcc_names[c], data);
|
||||
break;
|
||||
case 4:
|
||||
sprintf(dis.str, "ftrap%s", _fcc_names[c]);
|
||||
break;
|
||||
default:
|
||||
sprintf(dis.str, "ftrap????");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dis_fnop () {
|
||||
const uint16_t ext = dis_next_word();
|
||||
sprintf(dis.str, "fnop");
|
||||
}
|
||||
|
||||
#include "dis_decoder_guts.c"
|
||||
|
||||
/*
|
||||
|
|
862
core/ethernet.c
862
core/ethernet.c
|
@ -0,0 +1,862 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Peter Rutenbar <pruten@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "shoebill.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
|
||||
#include "ethernet_rom/rom.c"
|
||||
|
||||
static uint32_t compute_nubus_crc(uint8_t *rom, uint32_t len)
|
||||
{
|
||||
uint32_t i, sum = 0;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
uint8_t byte = rom[i];
|
||||
|
||||
if (i==(len-9) || i==(len-10) || i==(len-11) || i==(len-12))
|
||||
byte = 0;
|
||||
|
||||
sum = (sum << 1) + (sum >> 31) + byte;
|
||||
}
|
||||
|
||||
rom[len-9] = sum & 0xff;
|
||||
rom[len-10] = (sum >> 8) & 0xff;
|
||||
rom[len-11] = (sum >> 16) & 0xff;
|
||||
rom[len-12] = (sum >> 24) & 0xff;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define ETHPAGE() (ctx->cr >> 6)
|
||||
const char *eth_r0_reg_names[16] = {
|
||||
"cr", "clda0", "clda1", "bnry",
|
||||
"tsr", "ncr", "fifo", "isr",
|
||||
"crda0", "crda1", "reserved1", "reserved2",
|
||||
"rsr", "cntr0", "cntr1", "cntr2"
|
||||
};
|
||||
const char *eth_1_reg_names[16] = {
|
||||
"cr", "par0", "par1", "par2",
|
||||
"par3", "par4", "par5", "curr",
|
||||
"mar0", "mar1", "mar2", "mar3",
|
||||
"mar4", "mar5", "mar6", "mar7"
|
||||
};
|
||||
const char *eth_w0_reg_names[16] = {
|
||||
"cr", "pstart", "pstop", "bnry",
|
||||
"tpsr", "tbcr0", "tbcr1", "isr",
|
||||
"rsar0", "rsar1", "rbcr0", "rbcr1",
|
||||
"rcr", "tcr", "dcr", "imr"
|
||||
};
|
||||
|
||||
// command register bit masks
|
||||
enum ether_cr_masks {
|
||||
cr_stp = 1<<0, // stop
|
||||
cr_sta = 1<<1, // start
|
||||
cr_txp = 1<<2, // transmit packet
|
||||
cr_rd0 = 1<<3, // remote dma command (0)
|
||||
cr_rd1 = 1<<4, // remote dma command (1)
|
||||
cr_rd2 = 1<<5, // remote dma command (2)
|
||||
cr_ps0 = 1<<6, // page select (0)
|
||||
cr_ps1 = 1<<7, // page select (1)
|
||||
};
|
||||
|
||||
// interrupt service register bit masks
|
||||
enum ether_isr_masks {
|
||||
isr_prx = 1<<0, // packet received
|
||||
isr_ptx = 1<<1, // packet transmitted
|
||||
isr_rxe = 1<<2, // receive error
|
||||
isr_txe = 1<<3, // transmit error
|
||||
isr_ovw = 1<<4, // overwrite warning
|
||||
isr_cnt = 1<<5, // counter overflow
|
||||
isr_rdc = 1<<6, // remote dma complete
|
||||
isr_rst = 1<<7, // reset status (not actually an interrupt)
|
||||
};
|
||||
|
||||
// interrupt mask register bit masks
|
||||
enum ether_imr_masks {
|
||||
imr_pxre = 1<<0, // packet received interrupt enable
|
||||
imr_ptxe = 1<<1, // packet transmitted interrupt enable
|
||||
imr_rxee = 1<<2, // receive error interrupt enable
|
||||
imr_txee = 1<<3, // transmit error interrupt enable
|
||||
imr_ovwe = 1<<4, // overwrite warning interrupt enable
|
||||
imr_cnte = 1<<5, // counter overflow interrupt enable
|
||||
imr_rdce = 1<<6, // dma complete
|
||||
};
|
||||
|
||||
// receive configuration register bit masks
|
||||
enum ether_rcr_masks {
|
||||
rcr_sep = 1<<0, // save error packets
|
||||
rcr_ar = 1<<1, // accept runt packets
|
||||
rcr_ab = 1<<2, // accept broadcast
|
||||
rcr_am = 1<<3, // accept multicast
|
||||
rcr_pro = 1<<4, // promiscuous physical
|
||||
rcr_mon = 1<<5, // monitor mode
|
||||
};
|
||||
|
||||
// transmit configuration register bit masks
|
||||
enum ether_tcr_masks {
|
||||
tcr_crc = 1<<0, // inhibit crc
|
||||
tcr_lb0 = 1<<1, // encoded loopback control (0)
|
||||
tcr_lb1 = 1<<2, // encoded loopback control (1)
|
||||
tcr_atd = 1<<3, // auto transmit disable
|
||||
tcr_ofst = 1<<4, // collision offset enable
|
||||
};
|
||||
|
||||
// data configuration register bit masks
|
||||
enum ether_dcr_masks {
|
||||
dcr_wts = 1<<0, // word transfer select
|
||||
dcr_bos = 1<<1, // byte order select
|
||||
dcr_las = 1<<2, // long address select
|
||||
dcr_ls = 1<<3, // loopback select
|
||||
dcr_arm = 1<<4, // auto-initialize remote
|
||||
dcr_ft0 = 1<<5, // fifo threshhold select (0)
|
||||
dcr_ft1 = 1<<6, // fifo threshhold select (1)
|
||||
};
|
||||
|
||||
// receive status register
|
||||
enum ether_rsr_masks {
|
||||
rsr_prx = 1<<0, // packet received intact
|
||||
rsr_crc = 1<<1, // crc error
|
||||
rsr_fae = 1<<2, // frame alignment error
|
||||
rsr_fo = 1<<3, // fifo overrun
|
||||
rsr_mpa = 1<<4, // missed packet
|
||||
rsr_phy = 1<<5, // physical/multicast address (0->phys, 1->multi)
|
||||
rsr_dis = 1<<6, // received disabled
|
||||
rsr_dfr = 1<<7, // deferring
|
||||
};
|
||||
|
||||
static void _nubus_interrupt(uint8_t slotnum)
|
||||
{
|
||||
shoe.via[1].rega_input &= 0x3f & ~(1 << (slotnum - 9));
|
||||
via_raise_interrupt(2, IFR_CA1);
|
||||
}
|
||||
|
||||
static void _clear_nubus_interrupt(uint8_t slotnum)
|
||||
{
|
||||
shoe.via[1].rega_input |= (1 << (slotnum - 9));
|
||||
}
|
||||
|
||||
/*
|
||||
* How many recv buffers (256-byte buffers) does the
|
||||
* given number of bytes require?
|
||||
*/
|
||||
#define eth_recv_required_bufs(a) ({ \
|
||||
const uint32_t sz = (a); \
|
||||
(sz >> 8) + ((sz & 0xff) != 0); \
|
||||
})
|
||||
|
||||
/*
|
||||
* The number of 256-byte buffers available for writing
|
||||
* in the receive buffer (between ctx->curr and ctx->bnry)
|
||||
*/
|
||||
#define eth_recv_free_bufs() ({ \
|
||||
const uint8_t boundary = (ctx->bnry >= ctx->pstop) ? ctx->pstart : ctx->bnry; \
|
||||
const uint8_t curr = (ctx->curr >= ctx->pstop) ? ctx->pstart : ctx->curr; \
|
||||
const uint8_t total_bufs = ctx->pstop - ctx->pstart; \
|
||||
uint8_t f; \
|
||||
if (curr == boundary) \
|
||||
f = 0; /* This shouldn't happen */ \
|
||||
else if (curr > boundary) \
|
||||
f = (ctx->pstop - curr) + (boundary- ctx->pstart) - 1; \
|
||||
else \
|
||||
f = boundary - curr - 1; \
|
||||
f; \
|
||||
})
|
||||
|
||||
|
||||
void *_ethernet_receiver_thread(void *arg)
|
||||
{
|
||||
const uint8_t multicast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
|
||||
shoebill_card_ethernet_t *ctx = (shoebill_card_ethernet_t*)arg;
|
||||
uint8_t *buf = malloc(4096);
|
||||
assert(buf);
|
||||
|
||||
// While nubus_ethernet_destroy() hasn't been called
|
||||
while (!ctx->teardown) {
|
||||
struct timeval tv;
|
||||
fd_set fdset;
|
||||
int ret;
|
||||
uint32_t i;
|
||||
|
||||
FD_ZERO(&fdset);
|
||||
FD_SET(ctx->tap_fd, &fdset);
|
||||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 100000;
|
||||
|
||||
ret = select(ctx->tap_fd + 1, &fdset, NULL, NULL, &tv);
|
||||
assert(ret != -1);
|
||||
|
||||
if (FD_ISSET(ctx->tap_fd, &fdset)) {
|
||||
FD_CLR(ctx->tap_fd, &fdset);
|
||||
|
||||
/*
|
||||
* Read in the next packet, leaving space for the 4 byte
|
||||
* header
|
||||
*/
|
||||
int actual_packet_length = read(ctx->tap_fd, buf + 4, 4092);
|
||||
|
||||
slog("ethernet: received packet bnry=%x curr=%x pstart=%x pstop=%x cr=%x ret=%d frame=0x%02x%02x\n",
|
||||
ctx->bnry, ctx->curr, ctx->pstart, ctx->pstop, ctx->cr, actual_packet_length,
|
||||
buf[0x10], buf[0x11]);
|
||||
|
||||
/*
|
||||
* If it's a bogus packet length, reject it
|
||||
* (what's the actual minimum allowable packet length?)
|
||||
*/
|
||||
if (actual_packet_length <= 12) {
|
||||
slog("ethernet: too small len\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* I'm sure A/UX can't handle > 2kb packets */
|
||||
if (actual_packet_length > 2048) {
|
||||
slog("ethernet: too high len\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If it's neither multicast nor addressed to us, reject it */
|
||||
if ((memcmp(buf + 4, ctx->ethernet_addr, 6) != 0) &&
|
||||
(memcmp(buf + 4, multicast_addr, 6) != 0)) {
|
||||
slog("ethernet: bad address\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* A/UX seems to expect a minimum packet length (60 bytes??) */
|
||||
if (actual_packet_length < 60)
|
||||
actual_packet_length = 60;
|
||||
|
||||
/* The number of bytes to write + the 4 byte header */
|
||||
const uint32_t received_bytes = actual_packet_length + 4;
|
||||
|
||||
pthread_mutex_lock(&ctx->lock);
|
||||
|
||||
/*
|
||||
* If the card isn't initialized yet, just drop the packet
|
||||
*/
|
||||
if (ctx->cr & cr_stp) {
|
||||
slog("ethernet: uninit\n");
|
||||
pthread_mutex_unlock(&ctx->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the receive-register state is bogus, just drop the
|
||||
* packet
|
||||
*/
|
||||
if ((ctx->pstop <= ctx->pstart) ||
|
||||
(ctx->curr < ctx->pstart) ||
|
||||
(ctx->bnry < ctx->pstart) ||
|
||||
(ctx->pstop > 0x40) ||
|
||||
(ctx->pstart == 0)) {
|
||||
// This shouldn't happen if the card is initialized
|
||||
assert(!"ethernet: receive register state is bogus");
|
||||
pthread_mutex_unlock(&ctx->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
slog("ethernet: success, req=%u free=%u\n", eth_recv_required_bufs(received_bytes), eth_recv_free_bufs());
|
||||
|
||||
/*
|
||||
* If there isn't enough buffer space to store the packet,
|
||||
* block until ctx->bnry is modified.
|
||||
*/
|
||||
const uint8_t required_bufs = eth_recv_required_bufs(received_bytes);
|
||||
while (eth_recv_free_bufs() < required_bufs) {
|
||||
pthread_mutex_unlock(&ctx->lock);
|
||||
|
||||
if (ctx->teardown)
|
||||
goto bail;
|
||||
|
||||
printf("ethernet: sleeping\n");
|
||||
usleep(50); // FIXME: use a cond variable here
|
||||
pthread_mutex_lock(&ctx->lock);
|
||||
}
|
||||
|
||||
/* Roll around ctx->curr if necessary */
|
||||
if (ctx->curr >= ctx->pstop)
|
||||
ctx->curr = ctx->pstart;
|
||||
|
||||
const uint8_t orig_curr = ctx->curr;
|
||||
|
||||
/* Copy the packet to card RAM */
|
||||
for (i = 0; i < required_bufs; i++) {
|
||||
assert(ctx->curr != ctx->bnry); // this can't happen if we did our math right earlier
|
||||
|
||||
uint8_t *ptr = &ctx->ram[ctx->curr * 256];
|
||||
memcpy(ptr, &buf[i * 256], 256);
|
||||
|
||||
ctx->curr++;
|
||||
if (ctx->curr >= ctx->pstop)
|
||||
ctx->curr = ctx->pstart;
|
||||
}
|
||||
assert(ctx->curr != ctx->bnry); // this can't happen if we did our math right earlier
|
||||
|
||||
/* The packet was received intact */
|
||||
ctx->rsr = rsr_prx;
|
||||
|
||||
/* Fill in the 4 byte packet header */
|
||||
ctx->ram[orig_curr * 256 + 0] = ctx->rsr;
|
||||
ctx->ram[orig_curr * 256 + 1] = ctx->curr;
|
||||
ctx->ram[orig_curr * 256 + 2] = received_bytes & 0xff; // low byte
|
||||
ctx->ram[orig_curr * 256 + 3] = (received_bytes >> 8) & 0xff; // high byte
|
||||
|
||||
/* If the prx interrupt is enabled, interrupt */
|
||||
if (ctx->imr & imr_pxre) {
|
||||
ctx->isr |= isr_prx;
|
||||
_nubus_interrupt(ctx->slotnum);
|
||||
}
|
||||
|
||||
slog("ethernet: received packet (len=%d)\n", ret);
|
||||
|
||||
pthread_mutex_unlock(&ctx->lock);
|
||||
}
|
||||
}
|
||||
|
||||
bail:
|
||||
|
||||
free(buf);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
_Bool sent_arp_response = 0;
|
||||
|
||||
const uint8_t arp_response[60] = {
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // router's MAC address
|
||||
0x22, 0x33, 0x55, 0x77, 0xbb, 0xdd, // card MAC address
|
||||
0x08, 0x06, // ARP frame
|
||||
0x00, 0x01, // Ethernet
|
||||
0x08, 0x00, // IP
|
||||
0x06, // MAC size
|
||||
0x04, // IP size
|
||||
0x00, 0x02, // reply
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, // router's MAC address
|
||||
192, 168, 2, 1, // router IP address
|
||||
0x22, 0x33, 0x55, 0x77, 0xbb, 0xdd, // card MAC address
|
||||
192, 168, 2, 100, // card IP address
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // padding
|
||||
};
|
||||
|
||||
void _test_write_packet(shoebill_card_ethernet_t *ctx)
|
||||
{
|
||||
slog("ethernet: writing packet to curr=0x%02x\n", ctx->curr);
|
||||
|
||||
uint8_t *ptr = &ctx->ram[ctx->curr * 256];
|
||||
|
||||
// The packet was received intact
|
||||
ctx->rsr = rsr_prx;
|
||||
|
||||
// The next packet address is the next 256 byte chunk
|
||||
ctx->curr += 1;
|
||||
|
||||
ptr[0] = ctx->rsr;
|
||||
ptr[1] = ctx->curr; // next packet ptr (8 bit)
|
||||
ptr[2] = 60; // low byte of the packet size
|
||||
ptr[3] = 0; // high byte of the packet size
|
||||
memcpy(ptr + 4, arp_response, 60); // the packet
|
||||
|
||||
if (ctx->imr & imr_pxre)
|
||||
ctx->isr |= isr_prx;
|
||||
|
||||
_nubus_interrupt(ctx->slotnum);
|
||||
}
|
||||
*/
|
||||
|
||||
void *_ethernet_sender_thread(void *arg)
|
||||
{
|
||||
shoebill_card_ethernet_t *ctx = (shoebill_card_ethernet_t*)arg;
|
||||
|
||||
slog("ethernet: ethernet_sender_thread starts...\n");
|
||||
|
||||
// While nubus_ethernet_destroy() hasn't been called
|
||||
while (!ctx->teardown) {
|
||||
struct timeval now;
|
||||
struct timespec later;
|
||||
int ret;
|
||||
|
||||
// Wait on the condition variable, with a timeout of 100ms
|
||||
// slog("ethernet: locking cond mutex...\n");
|
||||
pthread_mutex_lock(&ctx->sender_cond_mutex);
|
||||
// slog("ethernet: locked cond mutex...\n");
|
||||
gettimeofday(&now, NULL);
|
||||
later.tv_sec = now.tv_sec;
|
||||
later.tv_nsec = (now.tv_usec * 1000) + (1000000000 / 10);
|
||||
if (later.tv_nsec >= 1000000000) {
|
||||
later.tv_nsec -= 1000000000;
|
||||
later.tv_sec++;
|
||||
}
|
||||
|
||||
// slog("ethernet: waiting on cond...\n");
|
||||
pthread_cond_timedwait(&ctx->sender_cond,
|
||||
&ctx->sender_cond_mutex,
|
||||
&later);
|
||||
assert(pthread_mutex_unlock(&ctx->sender_cond_mutex) == 0);
|
||||
|
||||
// Only proceed if there's a packet ready to send
|
||||
if (!ctx->send_ready)
|
||||
continue;
|
||||
|
||||
slog("ethernet: sender thread wakes up...\n");
|
||||
|
||||
ctx->send_ready = 0;
|
||||
|
||||
// --- Send the packet here ---
|
||||
assert(ctx->tbcr <= 2048); // sanity check the packet len
|
||||
assert(ctx->tbcr >= 42);
|
||||
|
||||
ret = write(ctx->tap_fd, ctx->ram, ctx->tbcr);
|
||||
if (ret != ctx->tbcr) {
|
||||
slog("ethernet: write() returned %d, not %d errno=%d\n", ret, ctx->tbcr, errno);
|
||||
}
|
||||
|
||||
// Lock the ethernet context (we're going to manipulate the ethernet registers)
|
||||
pthread_mutex_lock(&ctx->lock);
|
||||
|
||||
// indicate that the packet has been sent
|
||||
ctx->cr &= ~cr_txp; // clear the command register txp bit
|
||||
ctx->isr |= isr_ptx; // interrupt status: packet transmitted with no errors
|
||||
|
||||
// the "packet transmitted" interrupt really should be enabled
|
||||
if (ctx->imr & imr_ptxe) {
|
||||
_nubus_interrupt(ctx->slotnum);
|
||||
slog("ethernet: sender: sending interrupt to slot %u\n", ctx->slotnum);
|
||||
}
|
||||
|
||||
assert(pthread_mutex_unlock(&ctx->lock) == 0);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void nubus_ethernet_init(void *_ctx, uint8_t slotnum, uint8_t ethernet_addr[6], int tap_fd)
|
||||
{
|
||||
shoebill_card_ethernet_t *ctx = (shoebill_card_ethernet_t*)_ctx;
|
||||
memset(ctx, 0, sizeof(shoebill_card_ethernet_t));
|
||||
memcpy(ctx->rom, _ethernet_rom, 4096);
|
||||
|
||||
memcpy(ctx->ethernet_addr, ethernet_addr, 6);
|
||||
memcpy(ctx->rom, ethernet_addr, 6);
|
||||
ctx->rom[6] = 0x00;
|
||||
ctx->rom[7] = 0x00;
|
||||
|
||||
ctx->slotnum = slotnum; // so the threads know which slot this is
|
||||
|
||||
pthread_mutex_init(&ctx->lock, NULL);
|
||||
pthread_cond_init(&ctx->sender_cond, NULL);
|
||||
pthread_mutex_init(&ctx->sender_cond_mutex, NULL);
|
||||
|
||||
pthread_create(&ctx->sender_pid, NULL, _ethernet_sender_thread, ctx);
|
||||
pthread_create(&ctx->receiver_pid, NULL, _ethernet_receiver_thread, ctx);
|
||||
|
||||
/*
|
||||
* The first 8 bytes contain the MAC address
|
||||
* and aren't part of the CRC
|
||||
*/
|
||||
compute_nubus_crc(&ctx->rom[8], 4096 - 8);
|
||||
|
||||
ctx->cr |= cr_stp; // "STP powers up high"
|
||||
ctx->isr |= isr_rst; // I presume ISR's RST powers up high too
|
||||
|
||||
/* Platform-specific tap code */
|
||||
ctx->tap_fd = tap_fd;
|
||||
}
|
||||
|
||||
void nubus_ethernet_destroy_func(uint8_t slotnum)
|
||||
{
|
||||
shoebill_card_ethernet_t *ctx = (shoebill_card_ethernet_t*)shoe.slots[slotnum].ctx;
|
||||
|
||||
ctx->teardown = 1;
|
||||
pthread_join(ctx->sender_pid, NULL);
|
||||
pthread_join(ctx->receiver_pid, NULL);
|
||||
|
||||
pthread_mutex_destroy(&ctx->lock);
|
||||
pthread_mutex_destroy(&ctx->sender_cond_mutex);
|
||||
pthread_cond_destroy(&ctx->sender_cond);
|
||||
}
|
||||
|
||||
uint32_t nubus_ethernet_read_func(const uint32_t rawaddr,
|
||||
const uint32_t size,
|
||||
const uint8_t slotnum)
|
||||
{
|
||||
shoebill_card_ethernet_t *ctx = (shoebill_card_ethernet_t*)shoe.slots[slotnum].ctx;
|
||||
uint32_t result = 0;
|
||||
|
||||
pthread_mutex_lock(&ctx->lock);
|
||||
|
||||
switch ((rawaddr >> 16) & 0xf) {
|
||||
case 0xd: { // ram
|
||||
const uint16_t addr = rawaddr & 0x3fff;
|
||||
uint8_t *ram = ctx->ram;
|
||||
|
||||
if (size == 1)
|
||||
result = ram[addr];
|
||||
else if (size == 2) {
|
||||
result = ram[addr] << 8;
|
||||
result |= ram[(addr+1) & 0x3fff];
|
||||
}
|
||||
else
|
||||
assert(!"read: bogus size");
|
||||
|
||||
// slog("ethernet: reading from ram addr 0x%x sz=%u ", addr, size);
|
||||
|
||||
goto done;
|
||||
}
|
||||
case 0xe: { // registers
|
||||
// For some reason, the register address bits are all inverted
|
||||
const uint8_t reg = 15 ^ ((rawaddr >> 2) & 15);
|
||||
assert(size == 1);
|
||||
|
||||
{
|
||||
const char *name = "???";
|
||||
if (ETHPAGE() == 0) name = eth_r0_reg_names[reg];
|
||||
else if (ETHPAGE() == 1) name = eth_1_reg_names[reg];
|
||||
slog("ethernet: reading from register %u (%s) (raw=0x%x) pc=0x%x ", reg, name, rawaddr, shoe.pc);
|
||||
}
|
||||
|
||||
if (reg == 0) { // command register (exists in all pages)
|
||||
result = ctx->cr;
|
||||
goto done;
|
||||
} else if (ETHPAGE() == 0) { // page 0
|
||||
switch (reg) {
|
||||
default:
|
||||
assert(!"never get here");
|
||||
goto done;
|
||||
case 1: // clda0 (current local dma address 0)
|
||||
goto done;
|
||||
|
||||
case 2: // clda1 (current local dma address 1)
|
||||
goto done;
|
||||
|
||||
case 3: // bnry (boundary pointer)
|
||||
result = ctx->bnry;
|
||||
goto done;
|
||||
|
||||
case 4: // tsr (transmit status)
|
||||
goto done;
|
||||
|
||||
case 5: // ncr (number of collisions)
|
||||
goto done;
|
||||
|
||||
case 6: // fifo
|
||||
goto done;
|
||||
|
||||
case 7: // isr (interrupt status register)
|
||||
result = ctx->isr;
|
||||
|
||||
// test test test
|
||||
// if we're reading isr_ptx for the first time,
|
||||
// send a test packet (but never again)
|
||||
/*if ((result & isr_ptx) && (!sent_arp_response)) {
|
||||
sent_arp_response = 1;
|
||||
_test_write_packet(ctx);
|
||||
}*/
|
||||
|
||||
goto done;
|
||||
|
||||
case 8: // crda0 (current remote DMA address 0)
|
||||
goto done;
|
||||
|
||||
case 9: // crda1 (current remote DMA address 1)
|
||||
goto done;
|
||||
|
||||
case 10: // reserved 1
|
||||
assert(!"read to reserved 1");
|
||||
goto done;
|
||||
|
||||
case 11: // reserved 2
|
||||
assert(!"read to reserved 2");
|
||||
goto done;
|
||||
|
||||
case 12: // rsr (receive status register)
|
||||
result = ctx->rsr;
|
||||
goto done;
|
||||
|
||||
case 13: // cntr0 (tally counter 0 (frame alignment errors))
|
||||
goto done;
|
||||
|
||||
case 14: // cntr1 (tally counter 1 (crc errors))
|
||||
goto done;
|
||||
|
||||
case 15: // cntr2 (tally counter 2 (missed packet errors))
|
||||
goto done;
|
||||
}
|
||||
} else if (ETHPAGE() == 1) { // page 1
|
||||
switch (reg) {
|
||||
default:
|
||||
assert(!"never get here");
|
||||
goto done;
|
||||
case 1: // par (physical address)
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
result = ctx->par[reg - 1];
|
||||
goto done;
|
||||
case 7: // curr (current page register)
|
||||
result = ctx->curr;
|
||||
goto done;
|
||||
case 8: // mar (multicast address)
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
result = ctx->mar[reg - 8];
|
||||
goto done;
|
||||
}
|
||||
} else
|
||||
assert(!"read: Somebody accessed page 2 or 3!");
|
||||
|
||||
assert(!"never get here");
|
||||
goto done;
|
||||
}
|
||||
case 0xf: { // rom
|
||||
// Byte lanes = 0101 (respond to shorts)
|
||||
// respond to (addr & 3 == 0) and (addr & 3 == 2)
|
||||
// xxxx00 xxxx10
|
||||
if ((rawaddr & 1) == 0)
|
||||
result = ctx->rom[(rawaddr >> 1) % 4096];
|
||||
|
||||
slog("ethernet: reading from rom addr=%x ", rawaddr);
|
||||
|
||||
goto done;
|
||||
}
|
||||
default: // Not sure what happens when you access a different addr
|
||||
assert(!"read: unknown ethernet register");
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
pthread_mutex_unlock(&ctx->lock);
|
||||
|
||||
slog("result = 0x%x\n", result);
|
||||
// slog("ethernet: reading 0x%x sz=%u from addr 0x%x\n", result, size, rawaddr);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void nubus_ethernet_write_func(const uint32_t rawaddr,
|
||||
const uint32_t size,
|
||||
const uint32_t data,
|
||||
const uint8_t slotnum)
|
||||
{
|
||||
shoebill_card_ethernet_t *ctx = (shoebill_card_ethernet_t*)shoe.slots[slotnum].ctx;
|
||||
uint32_t i;
|
||||
|
||||
pthread_mutex_lock(&ctx->lock);
|
||||
|
||||
switch ((rawaddr >> 16) & 0xf) {
|
||||
case 0xd: { // ram
|
||||
const uint16_t addr = rawaddr & 0x3fff;
|
||||
uint8_t *ram = ctx->ram;
|
||||
|
||||
if (size == 1)
|
||||
ram[addr] = data;
|
||||
else if (size == 2) {
|
||||
ram[addr] = data >> 8;
|
||||
ram[(addr+1) & 0x3fff] = data & 0xff;
|
||||
}
|
||||
else
|
||||
assert(!"write: bogus size");
|
||||
|
||||
// slog("ethernet: writing 0x%x sz=%u to ram addr 0x%x\n", data, size, addr);
|
||||
|
||||
goto done;
|
||||
}
|
||||
case 0xe: { // registers
|
||||
// For some reason, the register address bits are all inverted
|
||||
const uint8_t reg = 15 ^ ((rawaddr >> 2) & 15);
|
||||
assert(size == 1);
|
||||
|
||||
{
|
||||
const char *name = "???";
|
||||
if (ETHPAGE() == 0) name = eth_w0_reg_names[reg];
|
||||
else if (ETHPAGE() == 1) name = eth_1_reg_names[reg];
|
||||
slog("ethernet: writing 0x%02x to register %u (%s) (rawaddr=0x%x) pc=0x%x\n", data, reg, name, rawaddr, shoe.pc);
|
||||
}
|
||||
|
||||
if (reg == 0) { // command register (exists in all pages)
|
||||
|
||||
// If we're setting TXP, wake up the sender thread
|
||||
if (((ctx->cr & cr_txp) == 0) &&
|
||||
((data & cr_txp) != 0)) {
|
||||
ctx->send_ready = 1;
|
||||
assert(pthread_mutex_lock(&ctx->sender_cond_mutex) == 0);
|
||||
assert(pthread_cond_signal(&ctx->sender_cond) == 0);
|
||||
assert(pthread_mutex_unlock(&ctx->sender_cond_mutex) == 0);
|
||||
}
|
||||
|
||||
// if we're setting STA, clear isr_rst
|
||||
if (data & cr_sta)
|
||||
ctx->isr &= ~isr_rst;
|
||||
|
||||
// FIXME: if we're setting STP, then we probably need to set isr_rst
|
||||
|
||||
ctx->cr = data;
|
||||
goto done;
|
||||
} else if (ETHPAGE() == 0) { // page 0
|
||||
switch (reg) {
|
||||
default:
|
||||
assert(!"never get here");
|
||||
goto done;
|
||||
|
||||
case 1: // pstart (page start)
|
||||
ctx->pstart = data;
|
||||
goto done;
|
||||
|
||||
case 2: // pstop (page stop)
|
||||
ctx->pstop = data;
|
||||
goto done;
|
||||
|
||||
case 3: // bnry (boundary pointer)
|
||||
ctx->bnry = data;
|
||||
goto done;
|
||||
|
||||
case 4: // tpsr (transmit page start address)
|
||||
ctx->tpsr = data;
|
||||
goto done;
|
||||
|
||||
case 5: // tbcr0 (transmit byte count 0)
|
||||
ctx->tbcr = (ctx->tbcr & 0xff00) | data;
|
||||
goto done;
|
||||
|
||||
case 6: // tbcr1 (transmit byte count 1)
|
||||
ctx->tbcr = (ctx->tbcr & 0x00ff) | (data<<8);
|
||||
goto done;
|
||||
|
||||
case 7: { // isr (interrupt status)
|
||||
// writing 1's clears the bits in the ISR
|
||||
uint8_t mask = data & 0x7f; // but not the RST bit
|
||||
ctx->isr &= ~mask;
|
||||
|
||||
/*
|
||||
* If there are packets yet to be processed,
|
||||
* then continue to assert the isr_prx bit
|
||||
*/
|
||||
uint8_t inc_boundary = ctx->bnry + 1;
|
||||
if (inc_boundary >= ctx->pstop)
|
||||
inc_boundary = ctx->pstart;
|
||||
if (ctx->curr != inc_boundary)
|
||||
ctx->isr |= isr_prx;
|
||||
|
||||
/*
|
||||
* If prx and ptx are no longer asserted,
|
||||
* then we may clear the nubus interrupt.
|
||||
*/
|
||||
if (((ctx->isr & (isr_prx | isr_ptx)) == 0) &&
|
||||
((ctx->cr & cr_stp) == 0))
|
||||
_clear_nubus_interrupt(slotnum);
|
||||
|
||||
goto done;
|
||||
}
|
||||
case 8: // rsar0 (remote start address 0)
|
||||
goto done;
|
||||
|
||||
case 9: // rsar1 (remote start address 1)
|
||||
goto done;
|
||||
|
||||
case 10: // rbcr0 (remote byte count 0)
|
||||
goto done;
|
||||
|
||||
case 11: // rbcr1 (remote byte count 1)
|
||||
goto done;
|
||||
|
||||
case 12: // rcr (receive configuration)
|
||||
ctx->rcr = data;
|
||||
goto done;
|
||||
|
||||
case 13: // tcr (transmit configuration)
|
||||
ctx->tcr = data;
|
||||
goto done;
|
||||
|
||||
case 14: // dcr (data configuration)
|
||||
ctx->dcr = data;
|
||||
goto done;
|
||||
|
||||
case 15: // imr (interrupt mask)
|
||||
ctx->imr = data & 0x7f;
|
||||
goto done;
|
||||
}
|
||||
} else if (ETHPAGE() == 1) { // page 1
|
||||
switch (reg) {
|
||||
default:
|
||||
assert(!"never get here");
|
||||
goto done;
|
||||
case 1: // par (physical address)
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
case 6:
|
||||
ctx->par[reg - 1] = data;
|
||||
goto done;
|
||||
case 7: // curr (current page register)
|
||||
ctx->curr = data;
|
||||
goto done;
|
||||
case 8: // mar (multicast address)
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
ctx->mar[reg - 8] = data;
|
||||
goto done;
|
||||
}
|
||||
} else
|
||||
assert(!"write: Somebody accessed page 2 or 3!");
|
||||
|
||||
assert(!"never get here");
|
||||
goto done;
|
||||
}
|
||||
default:
|
||||
assert(!"write: unknown ethernet register");
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
pthread_mutex_unlock(&ctx->lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
core/ethernet_rom/rom.bin
Normal file
BIN
core/ethernet_rom/rom.bin
Normal file
Binary file not shown.
514
core/ethernet_rom/rom.c
Normal file
514
core/ethernet_rom/rom.c
Normal file
|
@ -0,0 +1,514 @@
|
|||
uint8_t _ethernet_rom[4096] = {
|
||||
0x77, 0x6f, 0x6f, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x77, 0x6f, 0x6f, 0x66, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x0c, 0x80, 0x00, 0x00, 0x64,
|
||||
0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x14,
|
||||
0x02, 0x00, 0x00, 0x18, 0x20, 0x00, 0x00, 0x08,
|
||||
0x24, 0x00, 0x00, 0x28, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x53, 0x68, 0x6f, 0x65, 0x62, 0x69, 0x6c, 0x6c,
|
||||
0x20, 0x50, 0x68, 0x6f, 0x6e, 0x79, 0x20, 0x45,
|
||||
0x74, 0x68, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x00,
|
||||
0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x14,
|
||||
0x04, 0x00, 0x00, 0x18, 0x53, 0x68, 0x6f, 0x65,
|
||||
0x62, 0x69, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
|
||||
0x52, 0x65, 0x76, 0x2d, 0x31, 0x00, 0x00, 0x00,
|
||||
0x42, 0x6f, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0x18,
|
||||
0x0a, 0x00, 0x00, 0x30, 0x80, 0xff, 0xff, 0x7c,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01, 0x4e, 0x65, 0x74, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x5f, 0x45, 0x74, 0x68, 0x65,
|
||||
0x72, 0x6e, 0x65, 0x74, 0x5f, 0x53, 0x68, 0x6f,
|
||||
0x65, 0x62, 0x69, 0x6c, 0x6c, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf0, 0x24,
|
||||
0x00, 0x00, 0x0f, 0xf8, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x01, 0x5a, 0x93, 0x2b, 0xc7, 0x00, 0xa5
|
||||
};
|
1
core/ethernet_rom/shoebill_ether.make
Executable file
1
core/ethernet_rom/shoebill_ether.make
Executable file
|
@ -0,0 +1 @@
|
|||
# File: shoebill_ether.make
# Target: shoebill_ether
# Sources: shoebill_ether_rom.a
OBJECTS = shoebill_ether_rom.a.o
shoebill_ether ÄÄ shoebill_ether.make {OBJECTS}
Link ¶
{OBJECTS} ¶
-o shoebill_ether
shoebill_ether_rom.a.o Ä shoebill_ether.make shoebill_ether_rom.a
Asm shoebill_ether_rom.a
|
1
core/ethernet_rom/shoebill_ether_rom.a
Executable file
1
core/ethernet_rom/shoebill_ether_rom.a
Executable file
|
@ -0,0 +1 @@
|
|||
MACHINE MC68020
STRING C
PRINT OFF ; What does this do?
INCLUDE 'SysErr.a'
INCLUDE 'SysEqu.a'
INCLUDE 'ROMEqu.a'
INCLUDE 'SlotEqu.a'
INCLUDE 'TimeEqu.a'
INCLUDE 'Traps.a'
INCLUDE 'VideoEqu.a'
INCLUDE 'QuickEqu.a'
PRINT ON
VideoDeclROM MAIN
WITH VDPageInfo,SlotIntQElement
; EtherAddr is placed here, before sResourceDir and out of the range of the CRC
; check, because I guess it was too difficult to recompute the CRC when they were
; burning EPROMs back in 1986.
; So there's some ugly offset-accounting to make the rom seem (4096-8) bytes long,
; but still access this MAC address.
myEtherAddr
dc.l 'woof'
dc.l 'woof'
FormatBlockSize EQU 20
ROMSize EQU 4096
MyBoardID EQU $0008 ; Apple EtherTalk board ID
; ---- sResource directory ----
CategoryBoard EQU 1
CategoryEther EQU 128
sResourceDir OSLstEntry CategoryBoard, sResourceBoard
OSLstEntry CategoryEther, sResourceEther
DatLstEntry endOfList,0
; ---- Board sResource ----
sResourceBoard
OSLstEntry sRsrcType, boardType
OSLstEntry sRsrcName, boardName
DatLstEntry boardID, MyBoardID
OSLstEntry vendorInfo, myVendorInfo
; No primary or secondary init needed (phew)
DatLstEntry endOfList, 0
boardType
DC.W CatBoard ; category
DC.W TypBoard ; type
DC.W 0 ; driver sw ?
DC.W 0 ; driver hw ?
STRING C
boardName DC.L 'Shoebill Phony Ethernet'
myVendorInfo OSLstEntry VendorId, myVendorID
OSLstEntry RevLevel, myRevLevel
OSLstEntry PartNum, myPartNum
myVendorID DC.L 'Shoebill'
myRevLevel DC.L 'Rev-1'
myPartNum DC.L 'Bort'
; ---- Ethernet sResource ----
sResourceEther
OSLstEntry sRsrcType, myEtherType
OSLstEntry sRsrcName, myEtherName
OSLstEntry MinorBaseOS, myMinorBaseOS
dc.w $80ff ; 80 -> MAC address, $FFFFxx relative address of the MAC address
dc.w -*+2
DatLstEntry endOfList, 0
myEtherType
dc.w CatNetwork
dc.w TypEtherNet
dc.w 0 ; drvrSw, doesn't matter
dc.w 1 ; drvrHw, this is DrHw3Com on Apple EtherTalk
myEtherName
dc.l 'Network_Ethernet_Shoebill'
myMinorBaseOS DC.L $D0000
STRING C
; ---- Format block ----
; Pad to align this structure with the end of the rom
ORG ROMSize-FormatBlockSize
; Offset to sResource directory
;OSLstEntry 0,sResourceDir
DC.L (sResourceDir-*)**$00FFFFFF
DC.L ROMSize-8
DC.L 0 ; CRC goes here
DC.B 1 ; Rom revision level
DC.B AppleFormat
DC.L TestPattern
DC.B 0 ; Reserved
DC.B $A5 ; Byte lanes 1010 0101 (LSB from CPU's perspective)
ENDP
END
|
|
@ -172,7 +172,7 @@ void throw_address_error()
|
|||
shoe.abort = 1;
|
||||
}
|
||||
|
||||
static void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num)
|
||||
void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num)
|
||||
{
|
||||
// set supervisor bit
|
||||
set_sr_s(1);
|
||||
|
|
4304
core/fpu.c
4304
core/fpu.c
File diff suppressed because it is too large
Load Diff
|
@ -83,6 +83,9 @@ void inst_mc68851_pflushr(uint16_t ext){
|
|||
// Just nuke the entire cache
|
||||
memset(shoe.pmmu_cache[0].valid_map, 0, PMMU_CACHE_SIZE/8);
|
||||
memset(shoe.pmmu_cache[1].valid_map, 0, PMMU_CACHE_SIZE/8);
|
||||
|
||||
/* Invalidate the pc cache */
|
||||
invalidate_pccache();
|
||||
}
|
||||
|
||||
void inst_mc68851_pflush(uint16_t ext){
|
||||
|
@ -91,6 +94,9 @@ void inst_mc68851_pflush(uint16_t ext){
|
|||
memset(shoe.pmmu_cache[0].valid_map, 0, PMMU_CACHE_SIZE/8);
|
||||
memset(shoe.pmmu_cache[1].valid_map, 0, PMMU_CACHE_SIZE/8);
|
||||
// slog("%s: Error, not implemented!\n", __func__);
|
||||
|
||||
/* Invalidate the pc cache */
|
||||
invalidate_pccache();
|
||||
}
|
||||
|
||||
void inst_mc68851_pmove(uint16_t ext){
|
||||
|
@ -100,6 +106,12 @@ void inst_mc68851_pmove(uint16_t ext){
|
|||
~decompose(shoe.op, 1111 000 000 MMMMMM);
|
||||
~decompose(ext, fff ppp w 0000 nnn 00);
|
||||
|
||||
/*
|
||||
* For simplicity, just blow away pccache whenever
|
||||
* the PMMU state changes at all
|
||||
*/
|
||||
if (!w)
|
||||
invalidate_pccache();
|
||||
|
||||
|
||||
// instruction format #1
|
||||
|
@ -119,7 +131,16 @@ void inst_mc68851_pmove(uint16_t ext){
|
|||
|
||||
switch (p) {
|
||||
case 0: // tc
|
||||
if (!w) shoe.tc = shoe.dat & 0x83FFFFFF;
|
||||
if (!w) {
|
||||
shoe.tc = shoe.dat & 0x83FFFFFF;
|
||||
shoe.tc_is = (shoe.tc >> 16) & 0xf;
|
||||
shoe.tc_ps = (shoe.tc >> 20) & 0xf;
|
||||
shoe.tc_pagesize = 1 << shoe.tc_ps;
|
||||
shoe.tc_pagemask = shoe.tc_pagesize - 1;
|
||||
shoe.tc_is_plus_ps = shoe.tc_is + shoe.tc_ps;
|
||||
shoe.tc_enable = (shoe.tc >> 31) & 1;
|
||||
shoe.tc_sre = (shoe.tc >> 25) & 1;
|
||||
}
|
||||
else {
|
||||
shoe.dat = shoe.tc;
|
||||
//if (!tc_fcl()) assert(!"pmove->tc: function codes not supported\n");
|
||||
|
@ -193,7 +214,7 @@ static int64_t ptest_search(const uint32_t _logical_addr, const uint64_t rootp)
|
|||
uint8_t i;
|
||||
uint64_t desc = rootp; // Initial descriptor is the root pointer descriptor
|
||||
uint8_t desc_size = 1; // And the root pointer descriptor is always 8 bytes (1==8 bytes, 0==4 bytes)
|
||||
uint8_t used_bits = tc_is(); // Keep track of how many bits will be the effective "page size"
|
||||
uint8_t used_bits = shoe.tc_is; // Keep track of how many bits will be the effective "page size"
|
||||
// (If the table search terminates early (before used_bits == ts_ps()),
|
||||
// then this will be the effective page size. That is, the number of bits
|
||||
// we or into the physical addr from the virtual addr)
|
||||
|
@ -315,7 +336,7 @@ void inst_mc68851_ptest(uint16_t ext){
|
|||
~decompose(shoe.op, 1111 0000 00 MMMMMM);
|
||||
~decompose(ext, 100 LLL R AAAA FFFFF); // Erata in 68kPRM - F is 6 bits, and A is 3
|
||||
|
||||
assert(tc_enable()); // XXX: Throws some exception if tc_enable isn't set
|
||||
assert(shoe.tc_enable); // XXX: Throws some exception if tc_enable isn't set
|
||||
assert(tc_fcl() == 0); // XXX: I can't handle function code lookups, and I don't want to
|
||||
assert(L == 7); // XXX: Not currently handling searching to a particular level
|
||||
|
||||
|
|
295
core/mem.c
295
core/mem.c
|
@ -34,17 +34,13 @@
|
|||
void _physical_get_ram (void)
|
||||
{
|
||||
uint64_t *addr;
|
||||
if (shoe.physical_addr < shoe.physical_mem_size)
|
||||
if slikely(shoe.physical_addr < shoe.physical_mem_size)
|
||||
addr = (uint64_t*)&shoe.physical_mem_base[shoe.physical_addr];
|
||||
else
|
||||
addr = (uint64_t*)&shoe.physical_mem_base[shoe.physical_addr % shoe.physical_mem_size];
|
||||
|
||||
const uint8_t bits = (8 - shoe.physical_size) * 8;
|
||||
shoe.physical_dat = ntohll(*addr) >> bits;
|
||||
|
||||
if ((shoe.physical_addr >= 256) && (shoe.physical_addr < 0x4000)) {
|
||||
slog("LOMEM get: *0x%08x = 0x%x\n", shoe.physical_addr, (uint32_t)shoe.physical_dat);
|
||||
}
|
||||
}
|
||||
|
||||
void _physical_get_rom (void)
|
||||
|
@ -81,7 +77,7 @@ void _physical_get_io (void)
|
|||
return ;
|
||||
case 0x50014000 ... 0x50015fff: // Sound
|
||||
// slog("physical_get: got read to sound\n");
|
||||
shoe.physical_dat = sound_dma_read_raw(shoe.physical_addr - 0x50014000, shoe.physical_size);
|
||||
shoe.physical_dat = sound_dma_read_raw(shoe.physical_addr & 0x1fff, shoe.physical_size);
|
||||
// slog("soundsound read : register 0x%04x sz=%u\n",
|
||||
//shoe.physical_addr - 0x50014000, shoe.physical_size);
|
||||
// shoe.physical_dat = 0;
|
||||
|
@ -99,7 +95,7 @@ void _physical_get_io (void)
|
|||
void _physical_get_super_slot (void)
|
||||
{
|
||||
const uint32_t slot = shoe.physical_addr >> 28;
|
||||
if (shoe.slots[slot].connected)
|
||||
if slikely(shoe.slots[slot].connected)
|
||||
shoe.physical_dat = shoe.slots[slot].read_func(shoe.physical_addr,
|
||||
shoe.physical_size,
|
||||
slot);
|
||||
|
@ -111,7 +107,7 @@ void _physical_get_super_slot (void)
|
|||
void _physical_get_standard_slot (void)
|
||||
{
|
||||
const uint32_t slot = (shoe.physical_addr >> 24) & 0xf;
|
||||
if (shoe.slots[slot].connected)
|
||||
if slikely(shoe.slots[slot].connected)
|
||||
shoe.physical_dat = shoe.slots[slot].read_func(shoe.physical_addr,
|
||||
shoe.physical_size,
|
||||
slot);
|
||||
|
@ -209,7 +205,7 @@ void _physical_set_io (void)
|
|||
scsi_dma_write(shoe.physical_dat);
|
||||
return ;
|
||||
case 0x50014000 ... 0x50015fff: // Sound
|
||||
sound_dma_write_raw(shoe.physical_addr - 0x50014000, shoe.physical_size, shoe.physical_dat);
|
||||
sound_dma_write_raw(shoe.physical_addr & 0x1fff, shoe.physical_size, shoe.physical_dat);
|
||||
// slog("soundsound write: register 0x%04x sz=%u dat=0x%x\n",
|
||||
// shoe.physical_addr - 0x50014000, shoe.physical_size, (uint32_t)shoe.physical_dat);
|
||||
// slog("physical_set: got write to sound\n");
|
||||
|
@ -293,33 +289,52 @@ const physical_set_ptr physical_set_jump_table[16] = {
|
|||
}
|
||||
|
||||
|
||||
static _Bool check_pmmu_cache(void)
|
||||
static _Bool check_pmmu_cache_write(void)
|
||||
{
|
||||
const _Bool use_srp = (tc_sre() && (shoe.logical_fc >= 4));
|
||||
const _Bool use_srp = (shoe.tc_sre && (shoe.logical_fc >= 5));
|
||||
|
||||
// logical addr [is]xxxxxxxxxxxx[ps] -> value xxxxxxxxxxxx
|
||||
const uint32_t value = (shoe.logical_addr << tc_is()) >> (tc_is() + tc_ps());
|
||||
const uint32_t value = (shoe.logical_addr << shoe.tc_is) >> shoe.tc_is_plus_ps;
|
||||
// value xxx[xxxxxxxxx] -> key xxxxxxxxx
|
||||
const uint32_t key = value & (PMMU_CACHE_SIZE-1); // low PMMU_CACHE_KEY_BITS bits
|
||||
const uint32_t key = value & (PMMU_CACHE_SIZE - 1); // low PMMU_CACHE_KEY_BITS bits
|
||||
|
||||
const pmmu_cache_entry_t entry = shoe.pmmu_cache[use_srp].entry[key];
|
||||
|
||||
const _Bool is_set = (shoe.pmmu_cache[use_srp].valid_map[key/8] >> (key & 7)) & 1;
|
||||
const _Bool values_match = (entry.logical_value == value);
|
||||
const _Bool first_modify = !(shoe.logical_is_write && !entry.modified);
|
||||
const _Bool not_write_protected = !(shoe.logical_is_write && entry.wp);
|
||||
const _Bool is_set = (shoe.pmmu_cache[use_srp].valid_map[key >> 3] >> (key & 7)) & 1;
|
||||
|
||||
const uint32_t ps_mask = 0xffffffff >> entry.used_bits;
|
||||
const uint32_t v_mask = ~~ps_mask;
|
||||
|
||||
shoe.physical_addr = ((entry.physical_addr<<8) & v_mask) | (shoe.logical_addr & ps_mask);
|
||||
return is_set && values_match && first_modify && not_write_protected;
|
||||
return is_set && (entry.logical_value == value) && entry.modified && !entry.wp;
|
||||
}
|
||||
|
||||
static _Bool check_pmmu_cache_read(void)
|
||||
{
|
||||
const _Bool use_srp = (shoe.tc_sre && (shoe.logical_fc >= 5));
|
||||
|
||||
// logical addr [is]xxxxxxxxxxxx[ps] -> value xxxxxxxxxxxx
|
||||
const uint32_t value = (shoe.logical_addr << shoe.tc_is) >> shoe.tc_is_plus_ps;
|
||||
// value xxx[xxxxxxxxx] -> key xxxxxxxxx
|
||||
const uint32_t key = value & (PMMU_CACHE_SIZE - 1); // low PMMU_CACHE_KEY_BITS bits
|
||||
|
||||
const pmmu_cache_entry_t entry = shoe.pmmu_cache[use_srp].entry[key];
|
||||
|
||||
const _Bool is_set = (shoe.pmmu_cache[use_srp].valid_map[key >> 3] >> (key & 7)) & 1;
|
||||
|
||||
const uint32_t ps_mask = 0xffffffff >> entry.used_bits;
|
||||
const uint32_t v_mask = ~~ps_mask;
|
||||
|
||||
shoe.physical_addr = ((entry.physical_addr<<8) & v_mask) | (shoe.logical_addr & ps_mask);
|
||||
return is_set && (entry.logical_value == value);
|
||||
}
|
||||
|
||||
|
||||
static void translate_logical_addr()
|
||||
{
|
||||
const uint8_t use_srp = (tc_sre() && (shoe.logical_fc >= 4));
|
||||
const uint8_t use_srp = (shoe.tc_sre && (shoe.logical_fc >= 5));
|
||||
assert((0x66 >> shoe.logical_fc) & 1); // we only support these FCs for now
|
||||
|
||||
uint64_t *rootp_ptr = (use_srp ? (&shoe.srp) : (&shoe.crp));
|
||||
const uint64_t rootp = *rootp_ptr;
|
||||
uint8_t desc_did_change = 0;
|
||||
|
@ -329,7 +344,7 @@ static void translate_logical_addr()
|
|||
uint8_t i;
|
||||
uint64_t desc = rootp; // Initial descriptor is the root pointer descriptor
|
||||
uint8_t desc_size = 1; // And the root pointer descriptor is always 8 bytes (1==8 bytes, 0==4 bytes)
|
||||
uint8_t used_bits = tc_is(); // Keep track of how many bits will be the effective "page size"
|
||||
uint8_t used_bits = shoe.tc_is; // Keep track of how many bits will be the effective "page size"
|
||||
// (If the table search terminates early (before used_bits == ts_ps()),
|
||||
// then (32 - used_bits) will be the effective page size. That is, the number of bits
|
||||
// we or into the physical addr from the virtual addr)
|
||||
|
@ -342,7 +357,7 @@ static void translate_logical_addr()
|
|||
// TODO: Check limit here
|
||||
|
||||
// If root descriptor is invalid, throw a bus error
|
||||
if (rp_dt(rootp) == 0) {
|
||||
if sunlikely(rp_dt(rootp) == 0) {
|
||||
throw_bus_error(shoe.logical_addr, shoe.logical_is_write);
|
||||
return ;
|
||||
}
|
||||
|
@ -377,7 +392,7 @@ static void translate_logical_addr()
|
|||
const uint8_t dt = desc_dt(desc, desc_size);
|
||||
|
||||
// If this descriptor is invalid, throw a bus error
|
||||
if (dt == 0) {
|
||||
if sunlikely(dt == 0) {
|
||||
throw_bus_error(shoe.logical_addr, shoe.logical_is_write);
|
||||
return ;
|
||||
}
|
||||
|
@ -395,7 +410,7 @@ static void translate_logical_addr()
|
|||
get_desc(desc & 0xfffffff0, (4 << desc_size));
|
||||
|
||||
// I think it's possible for an indirect descriptor to point to an invalid descriptor...
|
||||
if (desc_dt(desc, desc_size) == 0) {
|
||||
if sunlikely(desc_dt(desc, desc_size) == 0) {
|
||||
throw_bus_error(shoe.logical_addr, shoe.logical_is_write);
|
||||
return ;
|
||||
}
|
||||
|
@ -426,7 +441,7 @@ search_done:
|
|||
wp |= desc_wp(desc, desc_size); // or in the wp flag for this page descriptor
|
||||
|
||||
// And finally throw a bus error
|
||||
if (wp && shoe.logical_is_write) {
|
||||
if sunlikely(wp && shoe.logical_is_write) {
|
||||
throw_bus_error(shoe.logical_addr, shoe.logical_is_write);
|
||||
return ;
|
||||
}
|
||||
|
@ -447,7 +462,7 @@ search_done:
|
|||
/* --- insert this translation into pmmu_cache --- */
|
||||
|
||||
// logical addr [is]xxxxxxxxxxxx[ps] -> value xxxxxxxxxxxx
|
||||
const uint32_t value = (shoe.logical_addr << tc_is()) >> (tc_is() + tc_ps());
|
||||
const uint32_t value = (shoe.logical_addr << shoe.tc_is) >> shoe.tc_is_plus_ps;
|
||||
// value xxx[xxxxxxxxx] -> key xxxxxxxxx
|
||||
const uint32_t key = value & (PMMU_CACHE_SIZE-1); // low PMMU_CACHE_KEY_BITS bits
|
||||
|
||||
|
@ -467,11 +482,11 @@ void logical_get (void)
|
|||
{
|
||||
|
||||
// If address translation isn't enabled, this is a physical address
|
||||
if (!tc_enable()) {
|
||||
if sunlikely(!shoe.tc_enable) {
|
||||
shoe.physical_addr = shoe.logical_addr;
|
||||
shoe.physical_size = shoe.logical_size;
|
||||
physical_get();
|
||||
if (shoe.abort) {
|
||||
if sunlikely(shoe.abort) {
|
||||
shoe.abort = 0;
|
||||
throw_long_bus_error(shoe.logical_addr, 0);
|
||||
return ;
|
||||
|
@ -483,29 +498,26 @@ void logical_get (void)
|
|||
const uint32_t logical_size = shoe.logical_size;
|
||||
const uint32_t logical_addr = shoe.logical_addr;
|
||||
|
||||
const uint16_t ps = tc_ps(); // log2 of the page size
|
||||
const uint32_t pagesize = 1 << ps; // the page size
|
||||
const uint32_t pagemask = pagesize-1; // a mask of the page bits
|
||||
const uint32_t pagemask = shoe.tc_pagemask;
|
||||
const uint32_t pageoffset = logical_addr & pagemask;
|
||||
|
||||
shoe.logical_is_write = 0;
|
||||
|
||||
// Common case: the read is contained entirely within a page
|
||||
if (!((pageoffset + logical_size - 1) >> ps)) {
|
||||
if (!check_pmmu_cache()) {
|
||||
if slikely(!((pageoffset + logical_size - 1) >> shoe.tc_ps)) {
|
||||
if sunlikely(!check_pmmu_cache_read()) {
|
||||
shoe.logical_is_write = 0;
|
||||
translate_logical_addr();
|
||||
if (shoe.abort)
|
||||
if sunlikely(shoe.abort)
|
||||
return ;
|
||||
}
|
||||
|
||||
if (shoe.physical_addr < shoe.physical_mem_size) {
|
||||
if slikely(shoe.physical_addr < shoe.physical_mem_size) {
|
||||
// Fast path
|
||||
shoe.logical_dat = ntohll(*(uint64_t*)&shoe.physical_mem_base[shoe.physical_addr]) >> ((8-logical_size)*8);
|
||||
}
|
||||
else {
|
||||
shoe.physical_size = logical_size;
|
||||
physical_get();
|
||||
if (shoe.abort) {
|
||||
if sunlikely(shoe.abort) {
|
||||
shoe.abort = 0;
|
||||
throw_long_bus_error(logical_addr, 0);
|
||||
return ;
|
||||
|
@ -519,11 +531,13 @@ void logical_get (void)
|
|||
const uint32_t size_a = logical_size - size_b;
|
||||
const uint32_t addr_b = addr_a + size_a;
|
||||
|
||||
shoe.logical_is_write = 0;
|
||||
|
||||
shoe.logical_addr = addr_a;
|
||||
shoe.logical_size = size_a;
|
||||
if (!check_pmmu_cache()) {
|
||||
if sunlikely(!check_pmmu_cache_read()) {
|
||||
translate_logical_addr();
|
||||
if (shoe.abort)
|
||||
if sunlikely(shoe.abort)
|
||||
return ;
|
||||
}
|
||||
|
||||
|
@ -531,16 +545,16 @@ void logical_get (void)
|
|||
|
||||
shoe.logical_addr = addr_b;
|
||||
shoe.logical_size = size_b;
|
||||
if (!check_pmmu_cache()) {
|
||||
if sunlikely(!check_pmmu_cache_read()) {
|
||||
translate_logical_addr();
|
||||
if (shoe.abort)
|
||||
if sunlikely(shoe.abort)
|
||||
return ;
|
||||
}
|
||||
|
||||
const uint32_t p_addr_b = shoe.physical_addr;
|
||||
shoe.physical_size = size_b;
|
||||
physical_get();
|
||||
if (shoe.abort) {
|
||||
if sunlikely(shoe.abort) {
|
||||
shoe.abort = 0;
|
||||
throw_long_bus_error(shoe.logical_addr, 0);
|
||||
return ;
|
||||
|
@ -550,7 +564,7 @@ void logical_get (void)
|
|||
shoe.physical_addr = p_addr_a;
|
||||
shoe.physical_size = size_a;
|
||||
physical_get();
|
||||
if (shoe.abort) {
|
||||
if sunlikely(shoe.abort) {
|
||||
shoe.abort = 0;
|
||||
throw_long_bus_error(shoe.logical_addr, 0);
|
||||
return ;
|
||||
|
@ -563,7 +577,7 @@ void logical_get (void)
|
|||
void logical_set (void)
|
||||
{
|
||||
// If address translation isn't enabled, this is a physical address
|
||||
if (!tc_enable()) {
|
||||
if sunlikely(!shoe.tc_enable) {
|
||||
shoe.physical_addr = shoe.logical_addr;
|
||||
shoe.physical_size = shoe.logical_size;
|
||||
shoe.physical_dat = shoe.logical_dat;
|
||||
|
@ -574,20 +588,18 @@ void logical_set (void)
|
|||
const uint32_t logical_size = shoe.logical_size;
|
||||
const uint32_t logical_addr = shoe.logical_addr;
|
||||
|
||||
const uint16_t ps = tc_ps(); // log2 of the page size
|
||||
const uint32_t pagesize = 1 << ps; // the page size
|
||||
const uint32_t pagemask = pagesize-1; // a mask of the page bits
|
||||
const uint32_t pagemask = shoe.tc_pagemask;
|
||||
const uint32_t pageoffset = logical_addr & pagemask;
|
||||
|
||||
// Make the translate function fail if the page is write-protected
|
||||
shoe.logical_is_write = 1;
|
||||
|
||||
// Common case: this write is contained entirely in one page
|
||||
if (!((pageoffset + logical_size - 1) >> ps)) {
|
||||
if slikely(!((pageoffset + logical_size - 1) >> shoe.tc_ps)) {
|
||||
// Common case: the write is contained entirely within a page
|
||||
if (!check_pmmu_cache()) {
|
||||
if sunlikely(!check_pmmu_cache_write()) {
|
||||
translate_logical_addr();
|
||||
if (shoe.abort)
|
||||
if sunlikely(shoe.abort)
|
||||
return ;
|
||||
}
|
||||
|
||||
|
@ -605,18 +617,18 @@ void logical_set (void)
|
|||
|
||||
shoe.logical_addr = addr_a;
|
||||
shoe.logical_size = size_a;
|
||||
if (!check_pmmu_cache()) {
|
||||
if sunlikely(!check_pmmu_cache_write()) {
|
||||
translate_logical_addr();
|
||||
if (shoe.abort)
|
||||
if sunlikely(shoe.abort)
|
||||
return ;
|
||||
}
|
||||
const uint32_t p_addr_a = shoe.physical_addr;
|
||||
|
||||
shoe.logical_addr = addr_b;
|
||||
shoe.logical_size = size_b;
|
||||
if (!check_pmmu_cache()) {
|
||||
if sunlikely(!check_pmmu_cache_write()) {
|
||||
translate_logical_addr();
|
||||
if (shoe.abort)
|
||||
if sunlikely(shoe.abort)
|
||||
return ;
|
||||
}
|
||||
const uint32_t p_addr_b = shoe.physical_addr;
|
||||
|
@ -635,12 +647,163 @@ void logical_set (void)
|
|||
}
|
||||
}
|
||||
|
||||
/* --- PC cache routines --- */
|
||||
#pragma mark PC cache routines
|
||||
|
||||
static uint16_t pccache_miss(const uint32_t pc)
|
||||
{
|
||||
const uint32_t pagemask = shoe.tc_pagemask;
|
||||
const uint32_t pageoffset = pc & pagemask;
|
||||
uint32_t paddr;
|
||||
|
||||
/*
|
||||
* I think the instruction decoder uses these
|
||||
* these function codes:
|
||||
* 6 -> supervisor program space,
|
||||
* 2 -> user program space
|
||||
*/
|
||||
shoe.logical_fc = sr_s() ? 6 : 2;
|
||||
shoe.logical_addr = pc;
|
||||
if sunlikely(!check_pmmu_cache_read()) {
|
||||
shoe.logical_is_write = 0;
|
||||
translate_logical_addr();
|
||||
if sunlikely(shoe.abort)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
paddr = shoe.physical_addr ^ pageoffset;
|
||||
|
||||
shoe.pccache_use_srp = shoe.tc_sre && sr_s();
|
||||
shoe.pccache_logical_page = pc ^ pageoffset;
|
||||
|
||||
if (paddr < 0x40000000) {
|
||||
/* Address in RAM */
|
||||
|
||||
if sunlikely(paddr >= shoe.physical_mem_size)
|
||||
paddr %= shoe.physical_mem_size;
|
||||
|
||||
shoe.pccache_ptr = &shoe.physical_mem_base[paddr];
|
||||
return ntohs(*(uint16_t*)(shoe.pccache_ptr + pageoffset));
|
||||
}
|
||||
else if (paddr < 0x50000000) {
|
||||
/* Address in ROM */
|
||||
shoe.pccache_ptr = &shoe.physical_rom_base[paddr & (shoe.physical_rom_size - 1)];
|
||||
return ntohs(*(uint16_t*)(shoe.pccache_ptr + pageoffset));
|
||||
}
|
||||
|
||||
/*
|
||||
* For now, only supporting reads from RAM and ROM.
|
||||
* This could easily be supported by just calling
|
||||
* physical_get() and leaving the cache invalid,
|
||||
* but I don't think A/UX ever tries to execute outside
|
||||
* RAM/ROM.
|
||||
*/
|
||||
assert(!"pccache_miss: neither RAM nor ROM!\n");
|
||||
|
||||
fail:
|
||||
invalidate_pccache();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16_t pccache_nextword(const uint32_t pc)
|
||||
{
|
||||
if (sunlikely(pc & 1))
|
||||
goto odd_addr;
|
||||
|
||||
if slikely(shoe.tc_enable) {
|
||||
const uint32_t pc_offset = pc & shoe.tc_pagemask;
|
||||
const uint32_t pc_page = pc ^ pc_offset;
|
||||
const uint32_t use_srp = shoe.tc_sre && sr_s();
|
||||
|
||||
/* If the cache exists and is valid */
|
||||
if slikely((shoe.pccache_use_srp == use_srp) && (shoe.pccache_logical_page == pc_page)) {
|
||||
// printf("pccache_nextword: hit: pc=%x\n", pc);
|
||||
return ntohs(*(uint16_t*)(shoe.pccache_ptr + pc_offset));
|
||||
}
|
||||
// printf("pccache_nextword: miss: pc=%x\n", pc);
|
||||
|
||||
return pccache_miss(pc);
|
||||
}
|
||||
else {
|
||||
uint32_t paddr = pc;
|
||||
|
||||
if (paddr < 0x40000000) {
|
||||
/* Address in RAM */
|
||||
|
||||
if sunlikely(paddr >= shoe.physical_mem_size)
|
||||
paddr %= shoe.physical_mem_size;
|
||||
|
||||
return ntohs(*(uint16_t*)(&shoe.physical_mem_base[paddr]));
|
||||
}
|
||||
else if (paddr < 0x50000000) {
|
||||
/* Address in ROM */
|
||||
|
||||
return ntohs(*(uint16_t*)&shoe.physical_rom_base[paddr & (shoe.physical_rom_size - 1)]);
|
||||
}
|
||||
assert(!"!tc_enable: neither RAM nor RAM\n");
|
||||
}
|
||||
|
||||
odd_addr:
|
||||
assert(!"odd pc address!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t pccache_nextlong(const uint32_t pc)
|
||||
{
|
||||
if slikely(shoe.tc_enable) {
|
||||
const uint32_t lastpage = shoe.pccache_logical_page;
|
||||
const uint32_t pc_offset = pc & shoe.tc_pagemask;
|
||||
const uint32_t pc_page = pc ^ pc_offset;
|
||||
const uint32_t use_srp = shoe.tc_sre && sr_s();
|
||||
|
||||
|
||||
/* If the cache exists, is valid, and the read is contained entirely within 1 page */
|
||||
if slikely((shoe.pccache_use_srp == use_srp) && (lastpage == pc_page) && !((pc_offset + 3) >> shoe.tc_ps)) {
|
||||
const uint32_t result = ntohl(*(uint32_t*)(shoe.pccache_ptr + pc_offset));
|
||||
if (sunlikely(pc_offset & 1))
|
||||
goto odd_addr;
|
||||
return result;
|
||||
}
|
||||
|
||||
const uint32_t result_high = pccache_nextword(pc) << 16;
|
||||
if sunlikely(shoe.abort)
|
||||
return 0;
|
||||
|
||||
return result_high | pccache_nextword(pc + 2);
|
||||
}
|
||||
else {
|
||||
uint32_t paddr = pc;
|
||||
|
||||
if sunlikely(paddr & 1)
|
||||
goto odd_addr;
|
||||
|
||||
if (paddr < 0x40000000) {
|
||||
/* Address in RAM */
|
||||
|
||||
if sunlikely(paddr >= shoe.physical_mem_size)
|
||||
paddr %= shoe.physical_mem_size;
|
||||
|
||||
return ntohl(*(uint32_t*)(&shoe.physical_mem_base[paddr]));
|
||||
}
|
||||
else if (paddr < 0x50000000) {
|
||||
/* Address in ROM */
|
||||
|
||||
return ntohl(*(uint32_t*)&shoe.physical_rom_base[paddr & (shoe.physical_rom_size - 1)]);
|
||||
}
|
||||
assert(!"!tc_enable: neither RAM nor RAM\n");
|
||||
}
|
||||
|
||||
odd_addr:
|
||||
assert(!"odd pc address!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* --- EA routines --- */
|
||||
#pragma mark EA routines
|
||||
|
||||
#define nextword(pc) ({const uint16_t w=lget((pc),2);if (shoe.abort){return;}(pc)+=2; w;})
|
||||
#define nextlong(pc) ({const uint32_t L=lget((pc),4);if (shoe.abort){return;}(pc)+=4; L;})
|
||||
#define nextword(pc) ({const uint16_t w = pccache_nextword(pc); if sunlikely(shoe.abort) return; (pc) += 2; w;})
|
||||
#define nextlong(pc) ({const uint32_t L = pccache_nextlong(pc); if sunlikely(shoe.abort) return; (pc) += 4; L;})
|
||||
|
||||
// ea_decode_extended() - find the EA for those hiddeous 68020 addr modes
|
||||
static void ea_decode_extended()
|
||||
|
@ -760,7 +923,7 @@ static void ea_decode_extended()
|
|||
case ~b(1001): case ~b(1010): case ~b(1011): {
|
||||
// Indirect preindexed
|
||||
const uint32_t intermediate = lget(base_addr + base_disp + index_val, 4);
|
||||
if (shoe.abort) return ;
|
||||
if sunlikely(shoe.abort) return ;
|
||||
shoe.extended_addr = intermediate + outer_disp;
|
||||
shoe.extended_len = mypc - start_pc;
|
||||
// slog("addr=0x%x len=%u\n", shoe.extended_addr, shoe.extended_len);
|
||||
|
@ -770,7 +933,7 @@ static void ea_decode_extended()
|
|||
case ~b(0101): case ~b(0110): case ~b(0111): {
|
||||
// Indirect postindexed
|
||||
const uint32_t intermediate = lget(base_addr + base_disp, 4);
|
||||
if (shoe.abort) return ;
|
||||
if sunlikely(shoe.abort) return ;
|
||||
shoe.extended_addr = intermediate + index_val + outer_disp;
|
||||
shoe.extended_len = mypc - start_pc;
|
||||
return ;
|
||||
|
@ -847,7 +1010,7 @@ void _ea_011_write (void)
|
|||
const uint8_t delta = ((reg==7) && (shoe.sz==1)) ? 2 : shoe.sz;
|
||||
|
||||
lset(shoe.a[reg], shoe.sz, shoe.dat);
|
||||
if (!shoe.abort)
|
||||
if slikely(!shoe.abort)
|
||||
shoe.a[reg] += delta;
|
||||
}
|
||||
|
||||
|
@ -870,7 +1033,7 @@ void _ea_100_write (void)
|
|||
const uint8_t delta = ((reg==7) && (shoe.sz==1)) ? 2 : shoe.sz;
|
||||
|
||||
lset(shoe.a[reg] - delta, shoe.sz, shoe.dat);
|
||||
if (!shoe.abort)
|
||||
if slikely(!shoe.abort)
|
||||
shoe.a[reg] -= delta;
|
||||
}
|
||||
|
||||
|
@ -902,7 +1065,7 @@ void _ea_101_addr (void)
|
|||
void _ea_110_read (void)
|
||||
{
|
||||
ea_decode_extended();
|
||||
if (!shoe.abort)
|
||||
if slikely(!shoe.abort)
|
||||
shoe.dat = lget(shoe.extended_addr, shoe.sz);
|
||||
shoe.uncommitted_ea_read_pc = shoe.pc + shoe.extended_len;
|
||||
}
|
||||
|
@ -913,16 +1076,16 @@ void _ea_110_read_commit (void)
|
|||
void _ea_110_write (void)
|
||||
{
|
||||
ea_decode_extended();
|
||||
if (!shoe.abort) {
|
||||
if slikely(!shoe.abort) {
|
||||
lset(shoe.extended_addr, shoe.sz, shoe.dat);
|
||||
if (!shoe.abort)
|
||||
if slikely(!shoe.abort)
|
||||
shoe.pc += shoe.extended_len;
|
||||
}
|
||||
}
|
||||
void _ea_110_addr (void)
|
||||
{
|
||||
ea_decode_extended();
|
||||
if (!shoe.abort) {
|
||||
if slikely(!shoe.abort) {
|
||||
shoe.dat = shoe.extended_addr;
|
||||
shoe.pc += shoe.extended_len;
|
||||
}
|
||||
|
@ -998,7 +1161,7 @@ void _ea_111_010_addr (void)
|
|||
void _ea_111_011_read (void)
|
||||
{
|
||||
ea_decode_extended();
|
||||
if (!shoe.abort)
|
||||
if slikely(!shoe.abort)
|
||||
shoe.dat = lget(shoe.extended_addr, shoe.sz);
|
||||
shoe.uncommitted_ea_read_pc = shoe.pc + shoe.extended_len;
|
||||
}
|
||||
|
@ -1009,7 +1172,7 @@ void _ea_111_011_read_commit (void)
|
|||
void _ea_111_011_addr (void)
|
||||
{
|
||||
ea_decode_extended();
|
||||
if (!shoe.abort) {
|
||||
if slikely(!shoe.abort) {
|
||||
shoe.dat = shoe.extended_addr;
|
||||
shoe.pc += shoe.extended_len;
|
||||
}
|
||||
|
|
1539
core/oldfpu.c
Normal file
1539
core/oldfpu.c
Normal file
File diff suppressed because it is too large
Load Diff
121
core/scsi.c
121
core/scsi.c
|
@ -310,45 +310,21 @@ static void scsi_buf_set (uint8_t byte)
|
|||
switch_status_phase(0); // switch to the status phase, with a status byte of 0
|
||||
break;
|
||||
|
||||
case 0x15: // mode select (6)
|
||||
slog("scsi_buf_set: responding to mode-select\n");
|
||||
switch_status_phase(0);
|
||||
break;
|
||||
|
||||
case 0x25: // read capacity (10)
|
||||
slog("scsi_buf_set: responding to read-capacity\n");
|
||||
// bytes [0,3] -> BE number of blocks
|
||||
shoe.scsi.buf[0] = (dev->num_blocks >> 24) & 0xff;
|
||||
shoe.scsi.buf[1] = (dev->num_blocks >> 16) & 0xff;
|
||||
shoe.scsi.buf[2] = (dev->num_blocks >> 8) & 0xff;
|
||||
shoe.scsi.buf[3] = (dev->num_blocks) & 0xff;
|
||||
|
||||
// bytes [4,7] -> BE block size (needs to be 512)
|
||||
|
||||
shoe.scsi.buf[4] = (dev->block_size >> 24) & 0xff;
|
||||
shoe.scsi.buf[5] = (dev->block_size >> 16) & 0xff;
|
||||
shoe.scsi.buf[6] = (dev->block_size >> 8) & 0xff;
|
||||
shoe.scsi.buf[7] = (dev->block_size) & 0xff;
|
||||
|
||||
shoe.scsi.in_i = 0;
|
||||
shoe.scsi.in_len = 8;
|
||||
|
||||
switch_data_in_phase();
|
||||
break;
|
||||
|
||||
case 0x12: { // inquiry command (6)
|
||||
slog("scsi_buf_set: responding to inquiry\n");
|
||||
case 0x3: { // request sense (6)
|
||||
const uint8_t alloc_len = shoe.scsi.buf[4];
|
||||
const uint8_t control = shoe.scsi.buf[5];
|
||||
const _Bool desc = shoe.scsi.buf[1] & 1;
|
||||
|
||||
switch_status_phase(2); // CHECK_CONDITION
|
||||
|
||||
scsi_handle_inquiry_command(alloc_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x8: { // read (6)
|
||||
const uint32_t offset =
|
||||
(shoe.scsi.buf[1] << 16) |
|
||||
(shoe.scsi.buf[2] << 8 ) |
|
||||
(shoe.scsi.buf[3]);
|
||||
(shoe.scsi.buf[1] << 16) |
|
||||
(shoe.scsi.buf[2] << 8 ) |
|
||||
(shoe.scsi.buf[3]);
|
||||
const uint16_t len = (shoe.scsi.buf[4]==0) ? 0x100 : shoe.scsi.buf[4]; // len==0 -> 256 sectors
|
||||
|
||||
assert(dev->f);
|
||||
|
@ -374,12 +350,12 @@ static void scsi_buf_set (uint8_t byte)
|
|||
switch_data_in_phase();
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case 0xa: { // write (6)
|
||||
const uint32_t offset =
|
||||
(shoe.scsi.buf[1] << 16) |
|
||||
(shoe.scsi.buf[2] << 8 ) |
|
||||
(shoe.scsi.buf[3]);
|
||||
(shoe.scsi.buf[1] << 16) |
|
||||
(shoe.scsi.buf[2] << 8 ) |
|
||||
(shoe.scsi.buf[3]);
|
||||
const uint16_t len = (shoe.scsi.buf[4]==0) ? 0x100 : shoe.scsi.buf[4]; // len==0 -> 256 sectors
|
||||
|
||||
slog("scsi_buf_set: Responding to write at off=%u len=%u\n", offset, len);
|
||||
|
@ -394,9 +370,70 @@ static void scsi_buf_set (uint8_t byte)
|
|||
switch_data_out_phase();
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x12: { // inquiry command (6)
|
||||
slog("scsi_buf_set: responding to inquiry\n");
|
||||
const uint8_t alloc_len = shoe.scsi.buf[4];
|
||||
|
||||
scsi_handle_inquiry_command(alloc_len);
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x15: // mode select (6)
|
||||
slog("scsi_buf_set: responding to mode-select\n");
|
||||
switch_status_phase(0);
|
||||
break;
|
||||
|
||||
case 0x1a: { // mode sense (6)
|
||||
const _Bool dbd = (shoe.scsi.buf[1] >> 3) & 1;
|
||||
const uint8_t pc = (shoe.scsi.buf[2] >> 6) & 3;
|
||||
const uint8_t page_code = shoe.scsi.buf[2] & 0x3f;
|
||||
const uint8_t subpage_code = shoe.scsi.buf[3];
|
||||
const uint8_t alloc_len = shoe.scsi.buf[4];
|
||||
const uint8_t control = shoe.scsi.buf[6];
|
||||
|
||||
slog("scsi_bug_set: responding to mode-sense\n");
|
||||
slog("dbd=%u pc=%u page_code=%u subpage_code=%u alloc_len=%u control=%u\n",
|
||||
dbd, pc, page_code, subpage_code, alloc_len, control);
|
||||
|
||||
|
||||
// FIXME: set sense code!
|
||||
switch_status_phase(2); // CHECK_CONDITION
|
||||
}
|
||||
|
||||
case 0x25: // read capacity (10)
|
||||
slog("scsi_buf_set: responding to read-capacity\n");
|
||||
// bytes [0,3] -> BE number of blocks
|
||||
shoe.scsi.buf[0] = (dev->num_blocks >> 24) & 0xff;
|
||||
shoe.scsi.buf[1] = (dev->num_blocks >> 16) & 0xff;
|
||||
shoe.scsi.buf[2] = (dev->num_blocks >> 8) & 0xff;
|
||||
shoe.scsi.buf[3] = (dev->num_blocks) & 0xff;
|
||||
|
||||
// bytes [4,7] -> BE block size (needs to be 512)
|
||||
|
||||
shoe.scsi.buf[4] = (dev->block_size >> 24) & 0xff;
|
||||
shoe.scsi.buf[5] = (dev->block_size >> 16) & 0xff;
|
||||
shoe.scsi.buf[6] = (dev->block_size >> 8) & 0xff;
|
||||
shoe.scsi.buf[7] = (dev->block_size) & 0xff;
|
||||
|
||||
shoe.scsi.in_i = 0;
|
||||
shoe.scsi.in_len = 8;
|
||||
|
||||
switch_data_in_phase();
|
||||
break;
|
||||
|
||||
case 0x28: { // read (10)
|
||||
|
||||
// FIXME: set sense code!
|
||||
switch_status_phase(2); // CHECK_CONDITION
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assert(!"unknown commmand!");
|
||||
printf("unknown scsi command (0x%02x)\n", shoe.scsi.buf[0]);
|
||||
// FIXME: set sense code
|
||||
switch_status_phase(2); // CHECK_CONDITION
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -548,8 +585,14 @@ void scsi_reg_write ()
|
|||
assert(id != 8);
|
||||
shoe.scsi.target_id = id;
|
||||
slog("scsi_reg_write: selected target id %u\n", id);
|
||||
shoe.scsi.target_bsy = 1; // target asserts BSY to acknowledge being selected
|
||||
shoe.scsi.phase = SELECTION;
|
||||
|
||||
if (shoe.scsi_devices[shoe.scsi.target_id].f == NULL) {
|
||||
shoe.scsi.phase = BUS_FREE;
|
||||
}
|
||||
else {
|
||||
shoe.scsi.target_bsy = 1; // target asserts BSY to acknowledge being selected
|
||||
shoe.scsi.phase = SELECTION;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
228
core/shoebill.h
228
core/shoebill.h
|
@ -51,8 +51,9 @@
|
|||
|
||||
#include <machine/endian.h>
|
||||
#include <libkern/OSByteOrder.h>
|
||||
#ifndef ntohll
|
||||
#define ntohll(x) OSSwapBigToHostInt64(x)
|
||||
|
||||
#endif
|
||||
#else /* #if (defined __APPLE__) */
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
|
@ -78,6 +79,9 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define slikely(e) (__builtin_expect(!!(e), 1))
|
||||
#define sunlikely(e) (__builtin_expect(!!(e), 0))
|
||||
|
||||
/*
|
||||
* core_api.c stuff
|
||||
*/
|
||||
|
@ -133,6 +137,9 @@ uint32_t shoebill_install_video_card(shoebill_config_t *config, uint8_t slotnum,
|
|||
|
||||
uint32_t shoebill_install_tfb_card(shoebill_config_t *config, uint8_t slotnum);
|
||||
|
||||
/* Call this after shoebill_initialize() to add an ethernet card */
|
||||
uint32_t shoebill_install_ethernet_card(shoebill_config_t *config, uint8_t slotnum, uint8_t ethernet_addr[6], int tap_fd);
|
||||
|
||||
/* Get a video frame from a particular video card */
|
||||
shoebill_video_frame_info_t shoebill_get_video_frame(uint8_t slotnum, _Bool just_params);
|
||||
|
||||
|
@ -254,11 +261,11 @@ uint8_t* shoebill_extract_kernel(const char *disk_path, const char *kernel_path,
|
|||
#define set_sr_t1(b) {shoe.sr &= (~(1<<15)); shoe.sr |= (((b)!=0)<<15);}
|
||||
|
||||
// MMU
|
||||
#define tc_enable() (shoe.tc >> 31)
|
||||
#define tc_sre() ((shoe.tc >> 25) & 1)
|
||||
#define _tc_enable() (shoe.tc >> 31) // _tc_enable,sre,ps,is are all extracted in shoe.tc_*
|
||||
#define _tc_sre() ((shoe.tc >> 25) & 1)
|
||||
#define tc_fcl() ((shoe.tc >> 24) & 1)
|
||||
#define tc_ps() ((shoe.tc >> 20) & 0xf)
|
||||
#define tc_is() ((shoe.tc >> 16) & 0xf)
|
||||
#define _tc_ps() ((shoe.tc >> 20) & 0xf)
|
||||
#define _tc_is() ((shoe.tc >> 16) & 0xf)
|
||||
#define tc_tia() ((shoe.tc >> 12) & 0xf)
|
||||
#define tc_tib() ((shoe.tc >> 8) & 0xf)
|
||||
#define tc_tic() ((shoe.tc >> 4) & 0xf)
|
||||
|
@ -410,6 +417,27 @@ typedef struct {
|
|||
dbg_breakpoint_t *breakpoints;
|
||||
} debugger_state_t;
|
||||
|
||||
// Sound (Apple Sound Chip)
|
||||
void sound_dma_write_raw(uint16_t addr, uint8_t sz, uint32_t data);
|
||||
uint32_t sound_dma_read_raw(uint16_t addr, uint8_t sz);
|
||||
void init_asc_state(void);
|
||||
|
||||
typedef struct {
|
||||
uint8_t buf[0x800];
|
||||
uint8_t version; // read-only
|
||||
uint8_t asc_mode;
|
||||
uint8_t channel_ctrl;
|
||||
uint8_t fifo_ctrl;
|
||||
uint8_t fifo_intr; // read-only
|
||||
uint8_t unknown1;
|
||||
uint8_t volume_ctrl;
|
||||
uint8_t clock_ctrl;
|
||||
|
||||
|
||||
uint16_t left_ptr, right_ptr;
|
||||
} apple_sound_chip_registers_t;
|
||||
|
||||
|
||||
typedef enum {
|
||||
adb_talk,
|
||||
adb_listen,
|
||||
|
@ -593,19 +621,69 @@ typedef struct {
|
|||
} shoebill_card_tfb_t;
|
||||
|
||||
typedef struct {
|
||||
// Doesn't exist yet
|
||||
// Card ROM (4kb)
|
||||
uint8_t rom[0x1000];
|
||||
|
||||
// Card RAM (16kb buffer, apparently)
|
||||
uint8_t ram[0x4000];
|
||||
|
||||
// Card MAC address
|
||||
uint8_t ethernet_addr[6];
|
||||
|
||||
// Card slot number
|
||||
uint8_t slotnum;
|
||||
|
||||
// -- thread state --
|
||||
uint8_t recv_buf[4096], send_buf[4096];
|
||||
uint16_t recv_len, send_len;
|
||||
_Bool teardown, send_ready;
|
||||
|
||||
pthread_t sender_pid, receiver_pid;
|
||||
pthread_mutex_t lock, sender_cond_mutex;
|
||||
pthread_cond_t sender_cond;
|
||||
|
||||
// -- registers --
|
||||
|
||||
uint8_t cr; // command register, all pages, read/write
|
||||
|
||||
// Page 0 registers
|
||||
uint8_t isr; // interrupt status register, read/write
|
||||
uint8_t imr; // interrupt mask register, write
|
||||
|
||||
uint8_t dcr; // data configuration register (write)
|
||||
uint8_t tcr; // transmit configuration register (write)
|
||||
uint8_t rcr; // receive configuration register (write)
|
||||
|
||||
uint8_t pstart; // receive buffer start pointer (write)
|
||||
uint8_t pstop; // receive buffer boundary (write)
|
||||
uint8_t bnry; // a different kind of receive buffer boundary (read/write)
|
||||
|
||||
uint8_t tpsr; // transmit page start pointer (write)
|
||||
uint16_t tbcr; // transmit buffer count register (write)
|
||||
|
||||
uint8_t rsr; // receive status register (read)
|
||||
|
||||
|
||||
// Page 1 registers (read/write)
|
||||
uint8_t mar[8]; // multicast address
|
||||
uint8_t par[6]; // physical address
|
||||
uint8_t curr; // current page
|
||||
|
||||
|
||||
int tap_fd;
|
||||
} shoebill_card_ethernet_t;
|
||||
|
||||
typedef enum {
|
||||
card_none = 0, // Empty slot
|
||||
card_toby_frame_buffer, // Original Macintosh II video card
|
||||
card_shoebill_video, // Fancy 21st-century Shoebill video card
|
||||
card_shoebill_ethernet // FIXME: doesn't exist yet
|
||||
card_shoebill_ethernet // "Register-compatible" Apple EtherTalk card
|
||||
} card_names_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t (*read_func)(uint32_t, uint32_t, uint8_t);
|
||||
void (*write_func)(uint32_t, uint32_t, uint32_t, uint8_t);
|
||||
void (*destroy_func)(uint8_t);
|
||||
|
||||
uint8_t slotnum;
|
||||
_Bool connected;
|
||||
|
@ -681,6 +759,11 @@ typedef struct {
|
|||
_Bool logical_is_write; // <- boolean: true iff the operation is logical_set()
|
||||
uint8_t logical_fc; // logical function code
|
||||
|
||||
#define invalidate_pccache() do {shoe.pccache_use_srp = 2;} while (0)
|
||||
uint32_t pccache_use_srp; // 1 -> use srp, 0 -> use crp, other -> pccache is invalid
|
||||
uint32_t pccache_logical_page;
|
||||
uint8_t *pccache_ptr;
|
||||
|
||||
// -- PMMU caching structures ---
|
||||
#define PMMU_CACHE_KEY_BITS 10
|
||||
#define PMMU_CACHE_SIZE (1<<PMMU_CACHE_KEY_BITS)
|
||||
|
@ -716,6 +799,10 @@ typedef struct {
|
|||
// 68851 registers
|
||||
uint64_t crp, srp, drp; // user/supervisor/DMA root pointers
|
||||
uint32_t tc; // translation control
|
||||
|
||||
uint32_t tc_pagesize, tc_pagemask; // page size and page mask
|
||||
uint8_t tc_ps, tc_is, tc_is_plus_ps, tc_enable, tc_sre; // commonly read bits in shoe.tc
|
||||
|
||||
uint16_t pcsr; // PMMU cache status
|
||||
uint16_t ac; // access control
|
||||
uint16_t bad[8]; // breakpoint acknowledge data registers
|
||||
|
@ -740,61 +827,11 @@ typedef struct {
|
|||
} bits;
|
||||
} psr;
|
||||
|
||||
// FPU registers
|
||||
uint32_t fpiar; // FPU iaddr
|
||||
// fpu_state_t pointer
|
||||
// (declared here as a void*, to prevent other files
|
||||
// from needing to include SoftFloat/softfloat.h)
|
||||
void *fpu_state;
|
||||
|
||||
union { // fpcr, fpu control register
|
||||
struct {
|
||||
// Mode control byte
|
||||
uint16_t mc_zero : 4; // zero/dummy
|
||||
uint16_t mc_rnd : 2; // rounding mode
|
||||
uint16_t mc_prec : 2; // rounding precision
|
||||
// Exception enable byte
|
||||
uint16_t ee_inex1 : 1; // inexact decimal input
|
||||
uint16_t ee_inex2 : 1; // inxact operation
|
||||
uint16_t ee_dz : 1; // divide by zero
|
||||
uint16_t ee_unfl : 1; // underflow
|
||||
uint16_t ee_ovfl : 1; // overflow
|
||||
uint16_t ee_operr : 1; // operand error
|
||||
uint16_t ee_snan : 1; // signalling not a number
|
||||
uint16_t ee_bsun : 1; // branch/set on unordered
|
||||
} b;
|
||||
|
||||
uint16_t raw;
|
||||
} fpcr;
|
||||
|
||||
union { // fpsr, fpu status register
|
||||
struct {
|
||||
// Accrued exception byte
|
||||
uint32_t dummy1 : 3; // dummy/zero
|
||||
uint32_t ae_inex : 1; // inexact
|
||||
uint32_t ae_dz : 1; // divide by zero
|
||||
uint32_t ae_unfl : 1; // underflow
|
||||
uint32_t ae_ovfl : 1; // overflow
|
||||
uint32_t ae_iop : 1; // invalid operation
|
||||
// Exception status byte
|
||||
uint32_t es_inex1 : 1; // inexact decimal input
|
||||
uint32_t es_inex2 : 1; // inxact operation
|
||||
uint32_t es_dz : 1; // divide by zero
|
||||
uint32_t es_unfl : 1; // underflow
|
||||
uint32_t es_ovfl : 1; // overflow
|
||||
uint32_t es_operr : 1; // operand error
|
||||
uint32_t es_snan : 1; // signalling not a number
|
||||
uint32_t es_bsun : 1; // branch/set on unordered
|
||||
// Quotient byte
|
||||
uint32_t qu_quotient : 7;
|
||||
uint32_t qu_s : 1;
|
||||
// Condition code byte
|
||||
uint32_t cc_nan : 1; // not a number
|
||||
uint32_t cc_i : 1; // infinity
|
||||
uint32_t cc_z : 1; // zero
|
||||
uint32_t cc_n : 1; // negative
|
||||
uint32_t dummy2 : 4; // dummy/zero
|
||||
} b;
|
||||
uint32_t raw;
|
||||
} fpsr;
|
||||
|
||||
long double fp[8]; // 80 bit floating point general registers
|
||||
|
||||
// -- Interrupts/VIA chips --
|
||||
|
||||
|
@ -804,6 +841,7 @@ typedef struct {
|
|||
pram_state_t pram;
|
||||
keyboard_state_t key;
|
||||
mouse_state_t mouse;
|
||||
apple_sound_chip_registers_t asc;
|
||||
|
||||
iwm_state_t iwm;
|
||||
|
||||
|
@ -825,9 +863,27 @@ typedef struct {
|
|||
extern global_shoebill_context_t shoe; // declared in cpu.c
|
||||
|
||||
// fpu.c functions
|
||||
void inst_fpu_decode(void);
|
||||
void dis_fpu_decode(void);
|
||||
void fpu_setup_jump_table();
|
||||
void inst_fscc();
|
||||
void inst_fbcc();
|
||||
void inst_fsave();
|
||||
void inst_frestore();
|
||||
void inst_ftrapcc();
|
||||
void inst_fdbcc();
|
||||
void inst_fnop();
|
||||
void inst_fpu_other();
|
||||
|
||||
void dis_fscc();
|
||||
void dis_fbcc();
|
||||
void dis_fsave();
|
||||
void dis_frestore();
|
||||
void dis_ftrapcc();
|
||||
void dis_fdbcc();
|
||||
void dis_fnop();
|
||||
void dis_fpu_other();
|
||||
void dis_fmath (uint16_t op, uint16_t ext, char *output);
|
||||
|
||||
void fpu_initialize();
|
||||
void fpu_reset();
|
||||
|
||||
// cpu.c fuctions
|
||||
void cpu_step (void);
|
||||
|
@ -842,10 +898,14 @@ void throw_illegal_instruction();
|
|||
void throw_privilege_violation();
|
||||
void throw_divide_by_zero();
|
||||
void throw_frame_two (uint16_t sr, uint32_t next_pc, uint32_t vector_num, uint32_t orig_pc);
|
||||
void throw_frame_zero(uint16_t sr, uint32_t pc, uint16_t vector_num);
|
||||
|
||||
|
||||
// mem.c functions
|
||||
|
||||
uint16_t pccache_nextword(uint32_t pc);
|
||||
uint32_t pccache_nextlong(uint32_t pc);
|
||||
|
||||
//void physical_get (void);
|
||||
typedef void (*physical_get_ptr) (void);
|
||||
typedef void (*physical_set_ptr) (void);
|
||||
|
@ -853,7 +913,12 @@ extern const physical_get_ptr physical_get_jump_table[16];
|
|||
extern const physical_set_ptr physical_set_jump_table[16];
|
||||
|
||||
#define physical_set() physical_set_jump_table[shoe.physical_addr >> 28]()
|
||||
#define pset(addr, s, val) {shoe.physical_addr=(addr); shoe.physical_size=(s); shoe.physical_dat=(val); physical_set();}
|
||||
#define pset(addr, s, val) do { \
|
||||
shoe.physical_addr=(addr); \
|
||||
shoe.physical_size=(s); \
|
||||
shoe.physical_dat=(val); \
|
||||
physical_set(); \
|
||||
} while (0)
|
||||
|
||||
#define physical_get() physical_get_jump_table[shoe.physical_addr >> 28]()
|
||||
#define pget(addr, s) ({shoe.physical_addr=(addr); shoe.physical_size=(s); physical_get(); shoe.physical_dat;})
|
||||
|
@ -866,26 +931,17 @@ void logical_get (void);
|
|||
logical_get(); \
|
||||
shoe.logical_dat; \
|
||||
})
|
||||
|
||||
#define lget(addr, s) ({ \
|
||||
shoe.logical_addr=(addr); \
|
||||
shoe.logical_size=(s); \
|
||||
shoe.logical_fc = (sr_s() ? 5 : 1); \
|
||||
logical_get(); \
|
||||
shoe.logical_dat; \
|
||||
})
|
||||
#define lget(addr, s) lget_fc((addr), (s), (sr_s() ? 5 : 1))
|
||||
|
||||
void logical_set (void);
|
||||
#define lset_fc(addr, s, val, fc) {\
|
||||
#define lset_fc(addr, s, val, fc) do { \
|
||||
shoe.logical_addr=(addr); \
|
||||
shoe.logical_size=(s); \
|
||||
shoe.logical_dat=(val); \
|
||||
shoe.logical_fc = (fc); \
|
||||
logical_set();\
|
||||
}
|
||||
#define lset(addr, s, val) { \
|
||||
lset_fc((addr), (s), (val), sr_s() ? 5 : 1) \
|
||||
}
|
||||
} while (0)
|
||||
#define lset(addr, s, val) lset_fc((addr), (s), (val), sr_s() ? 5 : 1)
|
||||
|
||||
typedef void (*_ea_func) (void);
|
||||
extern const _ea_func ea_read_jump_table[64];
|
||||
|
@ -899,10 +955,10 @@ extern const _ea_func ea_addr_jump_table[64];
|
|||
#define ea_addr() ea_addr_jump_table[shoe.mr]()
|
||||
|
||||
|
||||
#define call_ea_read(M, s) {shoe.mr=(M);shoe.sz=(s);ea_read();if (shoe.abort) return;}
|
||||
#define call_ea_write(M, s) {shoe.mr=(M);shoe.sz=(s);ea_write();if (shoe.abort) return;}
|
||||
#define call_ea_read_commit(M, s) {shoe.mr=(M);shoe.sz=(s);ea_read_commit();if (shoe.abort) return;}
|
||||
#define call_ea_addr(M) {shoe.mr=(M);ea_addr();if (shoe.abort) return;}
|
||||
#define call_ea_read(M, s) {shoe.mr=(M);shoe.sz=(s);ea_read();if sunlikely(shoe.abort) return;}
|
||||
#define call_ea_write(M, s) {shoe.mr=(M);shoe.sz=(s);ea_write();if sunlikely(shoe.abort) return;}
|
||||
#define call_ea_read_commit(M, s) {shoe.mr=(M);shoe.sz=(s);ea_read_commit();if sunlikely(shoe.abort) return;}
|
||||
#define call_ea_addr(M) {shoe.mr=(M);ea_addr();if sunlikely(shoe.abort) return;}
|
||||
|
||||
#define push_a7(_dat, _sz) {shoe.a[7]-=(_sz);lset(shoe.a[7], (_sz), (_dat));}
|
||||
|
||||
|
@ -1024,8 +1080,10 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size,
|
|||
shoebill_video_frame_info_t nubus_video_get_frame(shoebill_card_video_t *ctx,
|
||||
_Bool just_params);
|
||||
|
||||
// Sound (Apple Sound Chip)
|
||||
void sound_dma_write_raw(uint16_t addr, uint8_t sz, uint32_t data);
|
||||
uint32_t sound_dma_read_raw(uint16_t addr, uint8_t sz);
|
||||
// Apple EtherTalk
|
||||
void nubus_ethernet_init(void *_ctx, uint8_t slotnum, uint8_t ethernet_addr[6], int tap_fd);
|
||||
uint32_t nubus_ethernet_read_func(uint32_t, uint32_t, uint8_t);
|
||||
void nubus_ethernet_write_func(uint32_t, uint32_t, uint32_t, uint8_t);
|
||||
void nubus_ethernet_destroy_func(uint8_t);
|
||||
|
||||
#endif // _SHOEBILL_H
|
||||
|
|
256
core/sound.c
256
core/sound.c
|
@ -1,30 +1,181 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Peter Rutenbar <pruten@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Props to MESS for their EASC register map: http://www.mess.org/mess/driver_info/easc
|
||||
* EASC's PCM mode is backwards compatible with ASC, so their registers are very similar.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "../core/shoebill.h"
|
||||
|
||||
#define r_ptr (0x400 + (asc->right_ptr & 0x3ff)) /* right buf ptr */
|
||||
#define l_ptr (asc->left_ptr & 0x3ff) /* left buf ptr */
|
||||
#define m_ptr (asc->left_ptr & 0x7ff) /* mono buf ptr */
|
||||
|
||||
void init_asc_state(void)
|
||||
{
|
||||
memset(&shoe.asc, 0, sizeof(shoe.asc));
|
||||
|
||||
shoe.asc.version = 0x00; // My Mac II's ASC reports 0x00 as its version.
|
||||
// From the ROM, it looks like other Mac II ASC masks have different version numbers
|
||||
}
|
||||
|
||||
static uint8_t sound_dma_read_byte(uint16_t addr)
|
||||
{
|
||||
if (addr == 0x804)
|
||||
return 0xff;
|
||||
apple_sound_chip_registers_t *asc = &shoe.asc;
|
||||
|
||||
if (addr < 0x800) {
|
||||
if (asc->asc_mode == 1) {
|
||||
// PCM mode (FIFO is append-only)
|
||||
if (asc->channel_ctrl & 2) {
|
||||
// stereo mode - return the byte referenced by the right pointer
|
||||
return asc->buf[r_ptr];
|
||||
}
|
||||
else {
|
||||
// mono mode - return the byte referenced by the left pointer
|
||||
return asc->buf[m_ptr];
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Off or wavetable mode (FIFO is random access)
|
||||
return asc->buf[addr];
|
||||
}
|
||||
}
|
||||
|
||||
switch (addr) {
|
||||
case 0x800: // Version
|
||||
return asc->version;
|
||||
|
||||
case 0x801: // ASC-mode
|
||||
return asc->asc_mode;
|
||||
|
||||
case 0x802: // Channel control
|
||||
return asc->channel_ctrl;
|
||||
|
||||
case 0x803: // FIFO control
|
||||
return asc->fifo_ctrl;
|
||||
|
||||
case 0x804: // FIFO interrupt
|
||||
//return asc->fifo_intr;
|
||||
return 0xff;
|
||||
|
||||
case 0x805: // Unknown (??)
|
||||
return asc->unknown1;
|
||||
|
||||
case 0x806: // Volume control
|
||||
return asc->volume_ctrl;
|
||||
|
||||
case 0x807: // Clock control
|
||||
return asc->clock_ctrl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sound_dma_write_byte(uint16_t addr, uint8_t data)
|
||||
{
|
||||
if (addr >= 0x800) {
|
||||
// registers
|
||||
}
|
||||
else if (addr >= 0x400) {
|
||||
// Buf B
|
||||
apple_sound_chip_registers_t *asc = &shoe.asc;
|
||||
|
||||
if (addr < 0x800) { // buf_a/b
|
||||
if (asc->asc_mode == 1) {
|
||||
// PCM mode (FIFO is append-only)
|
||||
if (asc->channel_ctrl & 2) {
|
||||
// stereo mode - each channel has its own buffer pointer
|
||||
if (addr < 0x400) {
|
||||
// left buffer
|
||||
asc->buf[l_ptr] = data;
|
||||
asc->left_ptr++;
|
||||
}
|
||||
else {
|
||||
// right buffer
|
||||
asc->buf[r_ptr] = data;
|
||||
asc->right_ptr++;
|
||||
}
|
||||
return ;
|
||||
|
||||
}
|
||||
else {
|
||||
// Mono mode
|
||||
asc->buf[m_ptr] = data;
|
||||
asc->left_ptr++;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Off or wavetable mode (FIFO is random access)
|
||||
asc->buf[addr] = data;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Buf A
|
||||
/*FILE *f = fopen("buf_a.dmp", "ab");
|
||||
if (f) {
|
||||
fwrite(&data, 1, 1, f);
|
||||
fclose(f);
|
||||
}*/
|
||||
switch (addr) {
|
||||
case 0x800: // Version
|
||||
// Version is read-only
|
||||
break;
|
||||
|
||||
case 0x801: // ASC-mode
|
||||
// ASC version 0x00 preserves the low 2 bits
|
||||
asc->asc_mode = data & 0x03;
|
||||
assert(asc->asc_mode != 3); // mode-3 produces noise, but isn't deterministic
|
||||
break;
|
||||
|
||||
case 0x802: // Channel control
|
||||
// ASC version 0x00 preserves the high bit and low 2 bits
|
||||
asc->channel_ctrl = data & 0x83;
|
||||
break;
|
||||
|
||||
case 0x803: // FIFO control
|
||||
// ASC version 0x00 preserves the low 2 bits
|
||||
asc->fifo_ctrl = data & 0x83;
|
||||
break;
|
||||
|
||||
case 0x804: // FIFO interrupt
|
||||
// FIFO interrupt is read-only
|
||||
break;
|
||||
|
||||
case 0x805: // unknown (???)
|
||||
// ASC version 0x00 preserves the high bit and low 4 bits
|
||||
// (But what does it do?)
|
||||
asc->unknown1 = data & 0x8f;
|
||||
break;
|
||||
|
||||
case 0x806: // Volume control
|
||||
// ASC version 0x00 preserves the high 6 bits
|
||||
asc->volume_ctrl = data & 0xfc;
|
||||
break;
|
||||
|
||||
case 0x807: // Clock control
|
||||
// ASC version 0x00 preserves the low 2 bits
|
||||
asc->clock_ctrl = data & 0x03;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -48,4 +199,81 @@ uint32_t sound_dma_read_raw(uint16_t addr, uint8_t sz)
|
|||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
ASC notes:
|
||||
|
||||
buf_a (0x000-0x3ff) -> left
|
||||
buf_b (0x400-0x7ff) -> right
|
||||
writing to any address in buf_a or buf_b appends to the end pointer in the ring buffer (ignoring the address)
|
||||
reading from any address returns... the currently-being-read byte? Or the about-to-be-overwritten byte?
|
||||
(def one or the other)
|
||||
- Update: MODE=0: You can do regular random read/write access to buf_a/b when MODE=0.
|
||||
MODE=1: Writing anywhere within the buffer automatically appends to the end of the ring buffer
|
||||
For stereo mode, writing between 0-0x3ff appends to buf_a, 0x400-0x7ff to buf_b
|
||||
Reading anywhere in the buffer is strange - it seems non-deterministic.
|
||||
Update 2: no wait, it's returning the byte at buf_b's ring pointer, does it always do that?
|
||||
Update 3: yes, it looks like reading anywhere returns the byte at buf_b's pointer in stereo mode,
|
||||
and buf_a's pointer in mono mode
|
||||
MODE=2: Same as MODE=0 (?)
|
||||
|
||||
- ASC maintains two distinct ring buffer pointers for stereo mode
|
||||
|
||||
|
||||
|
||||
|
||||
0x800 - Version (?) MacII only ever seems to TST.B it
|
||||
(READ ONLY)
|
||||
|
||||
$00 -> My Mac II's ASC's version
|
||||
|
||||
$?? -> Mac II's ROM is aware of other non-$00 ASC masks
|
||||
|
||||
$b0 -> EASC
|
||||
|
||||
————
|
||||
|
||||
0x801 - Mode (?) 0 == no output, 1 == PCM, 2 == wavetable, 3 == hissing static(??)
|
||||
- Preserves low 2 bits, ignores high 6 bits
|
||||
|
||||
0x802 - Channel selector
|
||||
Preserves mask 0x83 (high bit, low 2 bits)
|
||||
- High bit is set if “engine overflow” (according to MESS)
|
||||
- Low bits, 0x?2 -> stereo output (buf_a -> left, buf_b -> right)
|
||||
0x?0 -> Mono output (from buf_a)
|
||||
- Switching to stereo from mono produces a blip of sound in the right ear, unless the fifo has been cleared (buf_b), (or unless there was nothing in buf_b to start with)
|
||||
|
||||
0x803 - Fifo control (cycle 0x80 to reset the internal FIFO pointer (pointers?))
|
||||
Preserves mask 0x83 (high bit, low 2 bits)
|
||||
|
||||
0x804 - Fifo interrupt status
|
||||
(READ ONLY, doesn’t preserve any written bits (doesn’t acknowledge writes at all?))
|
||||
|
||||
0x805 - ???
|
||||
- Preserves bits at 0x8F, (high bit, low 4 bits), doesn't seem to do anything
|
||||
|
||||
0x806 - Volume control (high 3 bits)
|
||||
Preserves top 6 bits, ignores bottom 2 bits. (Only top 3 bits control volume)
|
||||
|
||||
0x807 - Clock rate select (0, 2, or 3, I think)
|
||||
0x00 -> 11127hz
|
||||
0x01 -> Illegal???
|
||||
0x02 -> 11025hz
|
||||
0x03 -> 22050hz
|
||||
Writes to fifo_a/b(?) seem to block for clock rates 0, 2, and 3, but not 1. The speaker clicks like the sound chip is turning off when you set clock to 0x01.
|
||||
|
||||
|
||||
|
||||
ASC has more registers past 0x807 for wave table control
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
|
59
core/via.c
59
core/via.c
|
@ -31,6 +31,7 @@
|
|||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include "../core/shoebill.h"
|
||||
|
||||
char *via_reg_str[16] = {
|
||||
|
@ -471,15 +472,21 @@ void init_via_state (uint8_t pram_data[256], shoebill_pram_callback_t callback,
|
|||
* Bit 5 - input - v2TM0A (nubus transfer what??)
|
||||
* Bit 4 - input - v2TM1A
|
||||
* Bit 3 - output - AMU/PMMU control
|
||||
* Bit 2 - output - v2PowerOff
|
||||
* Bit 2 - output - v2PowerOff (but leave this in input mode)
|
||||
* Bit 1 - output - v2BusLk
|
||||
* Bit 0 - output - v2cdis
|
||||
*/
|
||||
shoe.via[1].ddrb = ~b(10001111);
|
||||
shoe.via[1].ddrb = 0x00;
|
||||
shoe.via[1].ddrb = ~b(10001011);
|
||||
// FIXME: apparently via2/regb bit 7 is tied to VIA1, and driven by timer T1, to
|
||||
// generate 60.15hz (really 60.0hz) interrupts on VIA1
|
||||
// emulate this more accurately!
|
||||
|
||||
// The power unit is wired to bit 2, waiting for it to be set 0.
|
||||
// I guess we're supposed to leave it as an input, because the shutdown
|
||||
// routine first sets the bit to 0, *then* switches the direction to output.
|
||||
// FIXME: verify that this is correct
|
||||
|
||||
/* -- Initialize PRAM -- */
|
||||
|
||||
pram_state_t *pram = &shoe.pram;
|
||||
|
@ -498,6 +505,7 @@ void init_via_state (uint8_t pram_data[256], shoebill_pram_callback_t callback,
|
|||
}
|
||||
|
||||
#define E_CLOCK 783360
|
||||
#define V2POWEROFF_MASK 0x04
|
||||
|
||||
#define _via_get_delta_counter(last_set) ({ \
|
||||
const long double delta_t = now - (last_set); \
|
||||
|
@ -514,6 +522,12 @@ void init_via_state (uint8_t pram_data[256], shoebill_pram_callback_t callback,
|
|||
#define VIA_REGB_PINS(n) ((shoe.via[(n)-1].regb_output & shoe.via[(n)-1].ddrb) | \
|
||||
(shoe.via[(n)-1].regb_input & (~~shoe.via[(n)-1].ddrb)))
|
||||
|
||||
static void _via_poweroff(void)
|
||||
{
|
||||
slog("Poweroff!\n");
|
||||
// exit(0);
|
||||
}
|
||||
|
||||
static uint8_t via_read_reg(const uint8_t vianum, const uint8_t reg, const long double now)
|
||||
{
|
||||
via_state_t *via = &shoe.via[vianum - 1];
|
||||
|
@ -570,7 +584,32 @@ static uint8_t via_read_reg(const uint8_t vianum, const uint8_t reg, const long
|
|||
return via->ddra;
|
||||
|
||||
case VIA_T2C_HI: {
|
||||
const uint16_t counter = via->t2c - (uint16_t)_via_get_delta_counter(via->t2_last_set);
|
||||
uint16_t counter = via->t2c - (uint16_t)_via_get_delta_counter(via->t2_last_set);
|
||||
|
||||
/*
|
||||
* This is a hack to allow A/UX 3.x.x to boot on fast hosts.
|
||||
* The A/UX 3 kernel calls a function, SetUpTimeK, during boot
|
||||
* to run a giant drba-to-self loop and time it via T2C.
|
||||
* If the loop completes too quickly, (quicker than 0x492 E_CLOCK
|
||||
* ticks on 3.0.0), it rejects it and tries again.
|
||||
*
|
||||
* SetUpTimeK reads T2C twice and compares them to determine the
|
||||
* time elapsed. I don't want to count on getting the order correct,
|
||||
* however. Therefore, we will fake it out by randomly adding 0x500
|
||||
* to the the value of the clock whenever it's read by SetUpTimeK.
|
||||
* By the Monte Carlo method, we'll eventually get a case where
|
||||
* two sequential reads differ by at least 0x500.
|
||||
*
|
||||
* FIXME: optimize this better, stop using coff_find_func()
|
||||
*/
|
||||
if (sr_s()) {
|
||||
coff_symbol *symb = coff_find_func(shoe.coff, shoe.pc);
|
||||
if (symb && strcmp(symb->name, "SetUpTimeK") == 0) {
|
||||
if (random() & 1)
|
||||
counter += 0x500;
|
||||
}
|
||||
}
|
||||
|
||||
return counter >> 8;
|
||||
}
|
||||
case VIA_T2C_LO: {
|
||||
|
@ -641,6 +680,11 @@ static void via_write_reg(const uint8_t vianum, const uint8_t reg, const uint8_t
|
|||
handle_pram_state_change();
|
||||
}
|
||||
|
||||
if ((vianum == 2) &&
|
||||
(via->ddrb & V2POWEROFF_MASK) &&
|
||||
!(via->regb_output & V2POWEROFF_MASK))
|
||||
_via_poweroff();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -652,9 +696,14 @@ static void via_write_reg(const uint8_t vianum, const uint8_t reg, const uint8_t
|
|||
break;
|
||||
}
|
||||
|
||||
case VIA_DDRB:
|
||||
case VIA_DDRB: {
|
||||
via->ddrb = data;
|
||||
if ((vianum == 2) &&
|
||||
(via->ddrb & V2POWEROFF_MASK) &&
|
||||
!(via->regb_output & V2POWEROFF_MASK))
|
||||
_via_poweroff();
|
||||
break;
|
||||
}
|
||||
|
||||
case VIA_DDRA:
|
||||
via->ddra = data;
|
||||
|
@ -717,7 +766,7 @@ void via_write_raw (void)
|
|||
via_write_reg(vianum, reg+1, (uint8_t)shoe.physical_dat, now);
|
||||
}
|
||||
else
|
||||
assert("Writing multiple bytes to the same VIA register!");
|
||||
assert(!"Writing multiple bytes to the same VIA register!");
|
||||
|
||||
pthread_mutex_unlock(&shoe.via_cpu_lock);
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ uint32_t nubus_video_read_func(const uint32_t rawaddr, const uint32_t size,
|
|||
const uint32_t addr = rawaddr & 0x00ffffff;
|
||||
|
||||
// ROM and control registers
|
||||
if ((addr >> 20) == 0xf) {
|
||||
if sunlikely((addr >> 20) == 0xf) {
|
||||
|
||||
slog("nubus_video_read_func: got a read to 0x%08x sz=%u\n", rawaddr, size);
|
||||
|
||||
|
@ -172,7 +172,7 @@ uint32_t nubus_video_read_func(const uint32_t rawaddr, const uint32_t size,
|
|||
// Else, this is video ram
|
||||
|
||||
uint32_t i, result = 0;
|
||||
if (addr < (ctx->pixels * 4)) {
|
||||
if slikely(addr < (ctx->pixels * 4)) {
|
||||
for (i=0; i<size; i++)
|
||||
result = (result << 8) | ((uint8_t*)ctx->direct_buf)[addr + i];
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size,
|
|||
uint32_t i;
|
||||
|
||||
// ROM and control registers
|
||||
if ((addr >> 20) == 0xf) {
|
||||
if sunlikely((addr >> 20) == 0xf) {
|
||||
|
||||
slog("nubus_video_write_func: got a write to 0x%08x sz=%u data=0x%x\n", rawaddr, size, data);
|
||||
|
||||
|
@ -340,7 +340,7 @@ void nubus_video_write_func(const uint32_t rawaddr, const uint32_t size,
|
|||
|
||||
// Else, this is video ram
|
||||
|
||||
if (addr < (ctx->pixels * 4)) {
|
||||
if slikely(addr < (ctx->pixels * 4)) {
|
||||
uint32_t mydata, myaddr;
|
||||
for (myaddr = addr + size, mydata = data; addr < myaddr; ) {
|
||||
((uint8_t*)ctx->direct_buf)[--myaddr] = mydata & 0xff;
|
||||
|
|
|
@ -10,16 +10,16 @@ int main (int argc, char **argv)
|
|||
uint32_t i;
|
||||
|
||||
if (argc != 3) {
|
||||
printf("usage ./rom_to_c video_rom.bin video_rom.c\n");
|
||||
printf("usage ./rom_to_c video|ethernet rom.bin rom.c\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(in = fopen(argv[1], "rb"));
|
||||
assert(out = fopen(argv[2], "w"));
|
||||
assert(in = fopen(argv[2], "rb"));
|
||||
assert(out = fopen(argv[3], "w"));
|
||||
|
||||
assert(fread(rom, 4096, 1, in) == 1);
|
||||
|
||||
fprintf(out, "static uint8_t _video_rom[4096] = {\n\t");
|
||||
fprintf(out, "static uint8_t _%s_rom[4096] = {\n\t", argv[1]);
|
||||
for (i=0; i<4095; i++) {
|
||||
fprintf(out, "0x%02x, ", rom[i]);
|
||||
if ((i % 8) == 7)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
CC = clang
|
||||
CFLAGS = -O0 -ggdb -flto -Wno-deprecated-declarations
|
||||
CFLAGS = -O3 -ggdb -flto -Wno-deprecated-declarations
|
||||
LFLAGS = -L ../intermediates -lshoebill_core -framework GLUT -framework OpenGL -ledit
|
||||
|
||||
all: debugger
|
||||
|
|
|
@ -42,6 +42,7 @@ struct dbg_state_t {
|
|||
uint64_t breakpoint_counter;
|
||||
dbg_breakpoint_t *breakpoints;
|
||||
_Bool trace;
|
||||
uint32_t slow_factor;
|
||||
|
||||
char *ring;
|
||||
uint32_t ring_i, ring_len;
|
||||
|
@ -84,7 +85,7 @@ void printregs()
|
|||
print_mmu_rp(shoe.crp);
|
||||
|
||||
printf("tc: e=%u sre=%u fcl=%u ps=%u is=%u (tia=%u tib=%u tic=%u tid=%u)\n",
|
||||
tc_enable(), tc_sre(), tc_fcl(), tc_ps(), tc_is(), tc_tia(), tc_tib(), tc_tic(), tc_tid());
|
||||
_tc_enable(), _tc_sre(), tc_fcl(), _tc_ps(), _tc_is(), tc_tia(), tc_tib(), tc_tic(), tc_tid());
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -394,6 +395,8 @@ void verb_continue_handler (const char *line)
|
|||
{
|
||||
dbg_state.running = 1;
|
||||
while (dbg_state.running) {
|
||||
if (dbg_state.slow_factor)
|
||||
usleep(dbg_state.slow_factor);
|
||||
stepper();
|
||||
}
|
||||
print_pc();
|
||||
|
@ -412,6 +415,13 @@ void verb_reset_handler (const char *line)
|
|||
shoe.pool = NULL;
|
||||
}
|
||||
|
||||
void verb_slow_handler (const char *line)
|
||||
{
|
||||
const uint64_t usecs = strtoul(line, NULL, 0);
|
||||
printf("Slow factor %u -> %u\n", dbg_state.slow_factor, (uint32_t)usecs);
|
||||
dbg_state.slow_factor = usecs;
|
||||
}
|
||||
|
||||
struct verb_handler_table_t {
|
||||
const char *name;
|
||||
void (*func)(const char *);
|
||||
|
@ -430,6 +440,7 @@ struct verb_handler_table_t {
|
|||
{"trace", verb_trace_toggle_handler},
|
||||
{"x", verb_examine_handler},
|
||||
{"reset", verb_reset_handler},
|
||||
{"slow", verb_slow_handler},
|
||||
};
|
||||
|
||||
void execute_verb (const char *line)
|
||||
|
@ -839,19 +850,21 @@ int main (int argc, char **argv)
|
|||
*/
|
||||
config.debug_mode = 1;
|
||||
|
||||
config.aux_verbose = 1;
|
||||
config.aux_verbose = 0;
|
||||
config.ram_size = 16 * 1024 * 1024;
|
||||
config.aux_kernel_path = "/unix";
|
||||
config.rom_path = "../priv/macii.rom";
|
||||
config.rom_path = "../../../shoebill_priv/macii.rom";
|
||||
|
||||
|
||||
config.scsi_devices[0].path = "../priv/aux3.0.1.img";
|
||||
config.scsi_devices[0].path = "../../../shoebill_priv/root3.img";
|
||||
//config.scsi_devices[1].path = "../priv/marathon.img";
|
||||
|
||||
/*dbg_state.ring_len = 256 * 1024 * 1024;
|
||||
dbg_state.ring = malloc(dbg_state.ring_len);
|
||||
dbg_state.ring_i = 0;*/
|
||||
|
||||
shoebill_validate_or_zap_pram(config.pram, 1);
|
||||
|
||||
if (!shoebill_initialize(&config)) {
|
||||
printf("%s\n", config.error_msg);
|
||||
return 0;
|
||||
|
@ -864,6 +877,9 @@ int main (int argc, char **argv)
|
|||
640, // 1024,
|
||||
480); // 768,
|
||||
|
||||
// uint8_t ethernet_addr[6] = {0x22, 0x33, 0x55, 0x77, 0xbb, 0xdd};
|
||||
// shoebill_install_ethernet_card(&config, 13, ethernet_addr);
|
||||
|
||||
// Start the VIA timer thread
|
||||
shoebill_start();
|
||||
|
||||
|
|
|
@ -283,6 +283,7 @@
|
|||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
|
@ -322,6 +323,7 @@
|
|||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_OBJC_ARC = NO;
|
||||
CLANG_LINK_OBJC_RUNTIME = NO;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2013-2014 Peter Rutenbar</string>
|
||||
<string>Copyright © 2013-2015 Peter Rutenbar</string>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
|
@ -17,11 +17,11 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>0.0.4</string>
|
||||
<string>0.0.5</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>0.0.4</string>
|
||||
<string>0.0.5</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
|
||||
<key>NSMainNibFile</key>
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#import "shoeAppDelegate.h"
|
||||
#import "shoeApplication.h"
|
||||
#import "shoePreferencesWindowController.h"
|
||||
|
||||
@implementation shoeAppDelegate
|
||||
|
||||
|
@ -39,8 +40,8 @@
|
|||
[defaults setInteger:NSOnState forKey:@"verboseState"];
|
||||
[defaults setInteger:16 forKey:@"memorySize"];
|
||||
|
||||
[defaults setInteger:640 forKey:@"screenWidth"];
|
||||
[defaults setInteger:480 forKey:@"screenHeight"];
|
||||
// [defaults setInteger:640 forKey:@"screenWidth"];
|
||||
// [defaults setInteger:480 forKey:@"screenHeight"];
|
||||
|
||||
for (i=0; i<7; i++)
|
||||
[defaults setObject:@"" forKey:[NSString stringWithFormat:@"scsiPath%u", i]];
|
||||
|
@ -50,6 +51,7 @@
|
|||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
|
||||
{
|
||||
uint32_t i;
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
BOOL isInitialized = [defaults boolForKey:@"defaultsInitialized"];
|
||||
|
@ -57,13 +59,33 @@
|
|||
if (!isInitialized)
|
||||
[self createFirstTimeUserDefaults];
|
||||
|
||||
// Going from 0.0.1 to 0.0.2 leaves rootKernelPath uninitialized
|
||||
// < 0.0.2 leaves rootKernelPath uninitialized
|
||||
if ([defaults objectForKey:@"rootKernelPath"] == nil)
|
||||
[defaults setObject:@"/unix" forKey:@"rootKernelPath"];
|
||||
|
||||
// 0.0.1-2 leave pramData uninitialized
|
||||
// < 0.0.3 leaves pramData uninitialized
|
||||
if ([defaults objectForKey:@"pramData"] == nil)
|
||||
[((shoeApplication*)NSApp) zapPram:defaults ptr:nil];
|
||||
|
||||
// < 0.0.5 leaves ethernet settings uninitialized
|
||||
if ([defaults objectForKey:@"tapPathE"] == nil) {
|
||||
uint8_t mac[6];
|
||||
generateMACAddr(mac);
|
||||
[defaults setObject:[NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]]
|
||||
forKey:@"macAddressE"];
|
||||
[defaults setObject:@"/dev/tap0" forKey:@"tapPathE"];
|
||||
[defaults setInteger:0 forKey:@"ethernetEnabledE"];
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
[defaults setInteger:640 forKey:[NSString stringWithFormat:@"screenWidth%u", i]];
|
||||
[defaults setInteger:480 forKey:[NSString stringWithFormat:@"screenHeight%u", i]];
|
||||
[defaults setInteger:0 forKey:[NSString stringWithFormat:@"screenEnabled%u", i]];
|
||||
}
|
||||
[defaults setInteger:1 forKey:@"screenEnabled0"];
|
||||
}
|
||||
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -46,6 +46,14 @@ struct shoe_app_pram_data_t
|
|||
BOOL doCaptureMouse, doCaptureKeys;
|
||||
BOOL isRunning;
|
||||
shoebill_config_t config;
|
||||
|
||||
char *tapPath;
|
||||
uint8_t mac[6];
|
||||
int tap_fd;
|
||||
BOOL ethEnabled, tap_fd_valid;
|
||||
struct {
|
||||
uint16_t height, width, enabled;
|
||||
} screens[4];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#import "shoeApplication.h"
|
||||
#import "shoeScreenWindow.h"
|
||||
#import "shoeScreenWindowController.h"
|
||||
#import "shoePreferencesWindowController.h"
|
||||
#include <ctype.h>
|
||||
|
||||
@implementation shoeApplication
|
||||
|
@ -215,7 +216,7 @@
|
|||
}
|
||||
|
||||
|
||||
- (BOOL) fetchUserDefaults:(uint16_t*)height width:(uint16_t*)width
|
||||
- (BOOL) fetchUserDefaults
|
||||
{
|
||||
uint32_t i;
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
@ -239,14 +240,22 @@
|
|||
if ((memsize < 1) || (memsize > 1024))
|
||||
memsize = 8;
|
||||
|
||||
NSInteger screenHeightValue = [defaults integerForKey:@"screenHeight"];
|
||||
NSInteger screenWidthValue = [defaults integerForKey:@"screenWidth"];
|
||||
for (i=0; i<4; i++) {
|
||||
NSInteger height = [defaults integerForKey:[NSString stringWithFormat:@"screenHeight%u", i]];
|
||||
NSInteger width = [defaults integerForKey:[NSString stringWithFormat:@"screenWidth%u", i]];
|
||||
NSInteger enabled = [defaults integerForKey:[NSString stringWithFormat:@"screenEnabled%u", i]];
|
||||
|
||||
|
||||
if ((screenHeightValue < 342) || (screenHeightValue > 0xffff))
|
||||
screenHeightValue = 480;
|
||||
|
||||
if ((screenWidthValue < 512) || (screenWidthValue > 0xffff))
|
||||
screenWidthValue = 640;
|
||||
if ((height < 342) || (height > 0xffff))
|
||||
height = 480;
|
||||
|
||||
if ((width < 512) || (width > 0xffff))
|
||||
width = 640;
|
||||
|
||||
screens[i].width = (uint16_t)width;
|
||||
screens[i].height = (uint16_t)height;
|
||||
screens[i].enabled = (uint16_t)enabled;
|
||||
}
|
||||
|
||||
|
||||
for (i=0; i<7; i++) {
|
||||
|
@ -277,8 +286,23 @@
|
|||
if (memcmp(config.pram+0xc, "NuMc", 4) != 0)
|
||||
[self zapPram:defaults ptr:config.pram];
|
||||
|
||||
*width = screenWidthValue;
|
||||
*height = screenHeightValue;
|
||||
NSString *defaultTapPath = [defaults objectForKey:@"tapPathE"];
|
||||
NSString *defaultMacAddr = [defaults objectForKey:@"macAddressE"];
|
||||
ethEnabled = [defaults integerForKey:@"ethernetEnabledE"];
|
||||
if (ethEnabled) {
|
||||
if (tap_fd_valid && strcmp(tapPath, [defaultTapPath UTF8String]) != 0) {
|
||||
close(tap_fd);
|
||||
tap_fd_valid = 0;
|
||||
}
|
||||
if (tapPath)
|
||||
free(tapPath);
|
||||
tapPath = strdup([defaultTapPath UTF8String]);
|
||||
if (!(parseMACAddr([defaultMacAddr UTF8String], mac))) {
|
||||
[self complain:@"Bad MAC addr"];
|
||||
ethEnabled = 0;
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
@ -346,12 +370,12 @@ void pram_callback (void *param, const uint8_t addr, const uint8_t byte)
|
|||
if (isRunning)
|
||||
return;
|
||||
|
||||
uint16_t width, height;
|
||||
uint32_t i;
|
||||
|
||||
bzero(&config, sizeof(shoebill_config_t));
|
||||
|
||||
[self fetchUserDefaults:&height width:&width];
|
||||
if (![self fetchUserDefaults])
|
||||
return ;
|
||||
|
||||
self->pram = calloc(1, sizeof(struct shoe_app_pram_data_t));
|
||||
memcpy(self->pram, config.pram, 256);
|
||||
|
@ -371,7 +395,33 @@ void pram_callback (void *param, const uint8_t addr, const uint8_t byte)
|
|||
return ;
|
||||
}
|
||||
|
||||
[self createScreenWindow:9 height:height width:width];
|
||||
for (i=0; i<4; i++) {
|
||||
if (screens[i].enabled)
|
||||
[self createScreenWindow:(9+i) height:screens[i].height width:screens[i].width];
|
||||
}
|
||||
|
||||
if (ethEnabled) {
|
||||
if (!tap_fd_valid) {
|
||||
tap_fd = open(tapPath, O_RDWR | O_NOFOLLOW);
|
||||
if (tap_fd == -1) {
|
||||
NSAlert *theAlert = [NSAlert
|
||||
alertWithMessageText:nil
|
||||
defaultButton:nil
|
||||
alternateButton:nil
|
||||
otherButton:nil
|
||||
informativeTextWithFormat:@"Couldn't open tap device (errno = %d)", errno
|
||||
];
|
||||
[theAlert runModal];
|
||||
return ;
|
||||
}
|
||||
tap_fd_valid = 1;
|
||||
}
|
||||
if (!shoebill_install_ethernet_card(&config, 13, mac, tap_fd)) {
|
||||
[self complain:[NSString stringWithFormat:@"%s", config.error_msg]];
|
||||
return ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
shoebill_start();
|
||||
|
||||
|
|
|
@ -27,10 +27,17 @@
|
|||
|
||||
@interface shoePreferencesWindowController : NSWindowController {
|
||||
|
||||
IBOutlet __weak NSButton *apply, *cancel, *applyAndRun, *verbose;
|
||||
IBOutlet __weak NSButton *apply, *cancel, *applyAndRun, *verbose, *ethernetEnabled;
|
||||
IBOutlet __weak NSTextField *kernelPath, *romPath, *memorySize;
|
||||
IBOutlet __weak NSTextField *scsiPath0, *scsiPath1, *scsiPath2, *scsiPath3, *scsiPath4, *scsiPath5, *scsiPath6;
|
||||
IBOutlet __weak NSTextField *screenHeight, *screenWidth;
|
||||
IBOutlet __weak NSTextField *macAddress, *tapPath;
|
||||
|
||||
IBOutlet __weak NSTextField *screenHeight1, *screenWidth1;
|
||||
IBOutlet __weak NSTextField *screenHeight2, *screenWidth2;
|
||||
IBOutlet __weak NSTextField *screenHeight3, *screenWidth3;
|
||||
IBOutlet __weak NSTextField *screenHeight4, *screenWidth4;
|
||||
|
||||
IBOutlet __weak NSButton *enableScreen1, *enableScreen2, *enableScreen3, *enableScreen4;
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,3 +47,6 @@
|
|||
- (IBAction)browsePressed:(id)sender;
|
||||
|
||||
@end
|
||||
|
||||
void generateMACAddr (uint8_t *mac);
|
||||
_Bool parseMACAddr (const char *str, uint8_t *mac);
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#import "shoePreferencesWindowController.h"
|
||||
#import "shoeApplication.h"
|
||||
#include <ctype.h>
|
||||
|
||||
@implementation shoePreferencesWindowController
|
||||
|
||||
|
@ -35,6 +36,14 @@
|
|||
|
||||
- (void)windowDidLoad
|
||||
{
|
||||
uint32_t i;
|
||||
NSTextField *screenWidths[4] = {
|
||||
screenWidth1, screenWidth2, screenWidth3, screenWidth4};
|
||||
NSTextField *screenHeights[4] = {
|
||||
screenHeight1, screenHeight2, screenHeight3, screenHeight4};
|
||||
NSButton *screenEnableds[4] = {
|
||||
enableScreen1, enableScreen2, enableScreen3, enableScreen4};
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
NSString *rootKernelPathStr = [defaults objectForKey:@"rootKernelPath"];
|
||||
|
@ -71,21 +80,28 @@
|
|||
if (scsiPath5Str) [scsiPath5 setStringValue:scsiPath5Str];
|
||||
if (scsiPath6Str) [scsiPath6 setStringValue:scsiPath6Str];
|
||||
|
||||
NSInteger screenHeightValue = [defaults integerForKey:@"screenHeight"];
|
||||
NSInteger screenWidthValue = [defaults integerForKey:@"screenWidth"];
|
||||
|
||||
if ((screenHeightValue < 342) || (screenHeightValue > 0xffff)) {
|
||||
screenHeightValue = 480;
|
||||
[defaults setInteger:screenHeightValue forKey:@"screenHeight"];
|
||||
for (i=0; i<4; i++) {
|
||||
NSInteger height = [defaults integerForKey:[NSString stringWithFormat:@"screenHeight%u", i]];
|
||||
NSInteger width = [defaults integerForKey:[NSString stringWithFormat:@"screenWidth%u", i]];
|
||||
NSInteger enabled = [defaults integerForKey:[NSString stringWithFormat:@"screenEnabled%u", i]];
|
||||
|
||||
if ((height < 342) || (height > 0xffff))
|
||||
height = 480;
|
||||
if ((width < 342) || (width > 0xffff))
|
||||
width = 640;
|
||||
|
||||
[screenHeights[i] setStringValue:[NSString stringWithFormat:@"%u", (uint32_t)height]];
|
||||
[screenWidths[i] setStringValue:[NSString stringWithFormat:@"%u", (uint32_t)width]];
|
||||
[screenEnableds[i] setState:enabled];
|
||||
}
|
||||
|
||||
NSString *tapPathStr = [defaults objectForKey:@"tapPathE"];
|
||||
NSString *macAddressStr = [defaults objectForKey:@"macAddressE"];
|
||||
NSInteger ethernetEnabledState = [defaults integerForKey:@"ethernetEnabledE"];
|
||||
|
||||
if ((screenWidthValue < 512) || (screenWidthValue > 0xffff)) {
|
||||
screenWidthValue = 640;
|
||||
[defaults setInteger:screenWidthValue forKey:@"screenWidth"];
|
||||
}
|
||||
|
||||
[screenWidth setStringValue:[NSString stringWithFormat:@"%u", (uint32_t)screenWidthValue]];
|
||||
[screenHeight setStringValue:[NSString stringWithFormat:@"%u", (uint32_t)screenHeightValue]];
|
||||
[tapPath setStringValue:tapPathStr];
|
||||
[macAddress setStringValue:macAddressStr];
|
||||
[ethernetEnabled setIntegerValue:ethernetEnabledState];
|
||||
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
@ -134,8 +150,27 @@
|
|||
[field setStringValue: [url path]];
|
||||
}
|
||||
|
||||
- (void) complain:(NSString*)str
|
||||
{
|
||||
NSAlert *theAlert = [NSAlert
|
||||
alertWithMessageText:nil
|
||||
defaultButton:nil
|
||||
alternateButton:nil
|
||||
otherButton:nil
|
||||
informativeTextWithFormat:@"%@", str
|
||||
];
|
||||
[theAlert runModal];
|
||||
}
|
||||
|
||||
- (IBAction)applyPressed:(id)sender
|
||||
{
|
||||
uint32_t i;
|
||||
NSTextField *screenWidths[4] = {
|
||||
screenWidth1, screenWidth2, screenWidth3, screenWidth4};
|
||||
NSTextField *screenHeights[4] = {
|
||||
screenHeight1, screenHeight2, screenHeight3, screenHeight4};
|
||||
NSButton *screenEnableds[4] = {
|
||||
enableScreen1, enableScreen2, enableScreen3, enableScreen4};
|
||||
|
||||
NSString *rootKernelPathStr = [kernelPath stringValue];
|
||||
NSString *romPathStr = [romPath stringValue];
|
||||
|
@ -150,11 +185,21 @@
|
|||
NSString *scsiPath5Str = [scsiPath5 stringValue];
|
||||
NSString *scsiPath6Str = [scsiPath6 stringValue];
|
||||
|
||||
NSInteger screenHeightValue = [screenHeight integerValue];
|
||||
NSInteger screenWidthValue = [screenWidth integerValue];
|
||||
NSString *macAddressStr = [macAddress stringValue];
|
||||
NSString *tapPathStr = [tapPath stringValue];
|
||||
NSInteger ethernetEnabledState = [ethernetEnabled state];
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
uint8_t mac[6];
|
||||
if (!parseMACAddr ([macAddressStr UTF8String], mac)) {
|
||||
[self complain:@"Bad MAC address"];
|
||||
}
|
||||
else {
|
||||
[macAddress setStringValue:[NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]]];
|
||||
}
|
||||
|
||||
[defaults setObject:rootKernelPathStr forKey:@"rootKernelPath"];
|
||||
[defaults setObject:romPathStr forKey:@"romPath"];
|
||||
[defaults setInteger:verboseState forKey:@"verboseState"];
|
||||
|
@ -168,8 +213,24 @@
|
|||
[defaults setObject:scsiPath5Str forKey:@"scsiPath5"];
|
||||
[defaults setObject:scsiPath6Str forKey:@"scsiPath6"];
|
||||
|
||||
[defaults setInteger:screenHeightValue forKey:@"screenHeight"];
|
||||
[defaults setInteger:screenWidthValue forKey:@"screenWidth"];
|
||||
for (i=0; i<4; i++) {
|
||||
NSInteger height = [screenHeights[i] integerValue];
|
||||
NSInteger width = [screenWidths[i] integerValue];
|
||||
NSInteger enabled = [screenEnableds[i] state];
|
||||
|
||||
if ((height < 342) || (height > 0xffff))
|
||||
height = 480;
|
||||
if ((width < 342) || (width > 0xffff))
|
||||
width = 640;
|
||||
|
||||
[defaults setInteger:height forKey:[NSString stringWithFormat:@"screenHeight%u", i]];
|
||||
[defaults setInteger:width forKey:[NSString stringWithFormat:@"screenWidth%u", i]];
|
||||
[defaults setInteger:enabled forKey:[NSString stringWithFormat:@"screenEnabled%u", i]];
|
||||
}
|
||||
|
||||
[defaults setObject:macAddressStr forKey:@"macAddressE"];
|
||||
[defaults setObject:tapPathStr forKey:@"tapPathE"];
|
||||
[defaults setInteger:ethernetEnabledState forKey:@"ethernetEnabledE"];
|
||||
|
||||
[defaults synchronize];
|
||||
}
|
||||
|
@ -192,5 +253,63 @@
|
|||
[shoeApp zapPram:[NSUserDefaults standardUserDefaults] ptr:nil];
|
||||
}
|
||||
|
||||
void generateMACAddr (uint8_t *mac)
|
||||
{
|
||||
srandom((unsigned)(random() ^ time(NULL)));
|
||||
|
||||
/* Generate a MAC address in the range of the original EtherTalk card */
|
||||
|
||||
mac[0] = 0x02;
|
||||
mac[1] = 0x60;
|
||||
mac[2] = 0x8c;
|
||||
mac[3] = random() & 0x07;
|
||||
mac[4] = random() & 0xff;
|
||||
mac[5] = random() & 0xff;
|
||||
}
|
||||
|
||||
_Bool parseMACAddr (const char *str, uint8_t *mac)
|
||||
{
|
||||
uint32_t i, nibbles = 0;
|
||||
uint8_t allowed[256];
|
||||
|
||||
memset(allowed, 30, 256);
|
||||
for (i=0; i<256; i++)
|
||||
if (isspace(i))
|
||||
allowed[i] = 20;
|
||||
allowed[':'] = 20;
|
||||
allowed['-'] = 20;
|
||||
for (i=0; i<10; i++)
|
||||
allowed['0' + i] = i;
|
||||
for (i=0; i<6; i++) {
|
||||
allowed['a' + i] = 10 + i;
|
||||
allowed['A' + i] = 10 + i;
|
||||
}
|
||||
|
||||
for (i=0; str[i]; i++) {
|
||||
const uint8_t v = allowed[str[i]];
|
||||
|
||||
if (v == 30)
|
||||
return 0;
|
||||
else if (v == 20)
|
||||
continue;
|
||||
|
||||
if (nibbles >= 12)
|
||||
return 0;
|
||||
mac[nibbles/2] <<= 4;
|
||||
mac[nibbles/2] |= v;
|
||||
nibbles++;
|
||||
}
|
||||
return (nibbles == 12);
|
||||
}
|
||||
|
||||
-(IBAction)newMacAddrPressed:(id)sender
|
||||
{
|
||||
uint8_t mac[6];
|
||||
|
||||
generateMACAddr(mac);
|
||||
|
||||
[macAddress setStringValue:[NSString stringWithFormat:@"%02X:%02X:%02X:%02X:%02X:%02X",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,17 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13D65" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="7706" systemVersion="14F27" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||
<dependencies>
|
||||
<deployment defaultVersion="1080" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="7706"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="shoePreferencesWindowController">
|
||||
<connections>
|
||||
<outlet property="enableScreen1" destination="JSa-Bw-xDM" id="3Vr-kl-5To"/>
|
||||
<outlet property="enableScreen2" destination="QR4-Cc-AkE" id="An0-V4-7Gg"/>
|
||||
<outlet property="enableScreen3" destination="C6X-Zw-psD" id="Ipx-9O-5jD"/>
|
||||
<outlet property="enableScreen4" destination="isQ-0Q-gQ4" id="4rO-YL-FaT"/>
|
||||
<outlet property="ethernetEnabled" destination="GCJ-G0-drE" id="urw-x8-B7H"/>
|
||||
<outlet property="kernelPath" destination="zU0-5O-afD" id="Q3V-Ly-Y6B"/>
|
||||
<outlet property="macAddress" destination="UAs-x7-p28" id="PTo-JO-bHU"/>
|
||||
<outlet property="memorySize" destination="uvm-gd-pCd" id="zzI-jI-ZUW"/>
|
||||
<outlet property="romPath" destination="LoN-Nd-9cy" id="R3k-vY-TPo"/>
|
||||
<outlet property="screenHeight" destination="Wyt-jg-xmk" id="Sq6-IJ-xbQ"/>
|
||||
<outlet property="screenWidth" destination="EMf-gC-m9T" id="xxW-Ji-t7R"/>
|
||||
<outlet property="screenHeight1" destination="Wyt-jg-xmk" id="dCS-jW-MMh"/>
|
||||
<outlet property="screenHeight2" destination="IPj-pY-K2b" id="cnW-fh-y05"/>
|
||||
<outlet property="screenHeight3" destination="tqh-iM-5GM" id="sF2-HA-acz"/>
|
||||
<outlet property="screenHeight4" destination="3aP-6m-As4" id="fsH-cL-DLg"/>
|
||||
<outlet property="screenWidth1" destination="EMf-gC-m9T" id="GSA-cX-c70"/>
|
||||
<outlet property="screenWidth2" destination="B2c-pG-rIH" id="1BQ-0g-PMw"/>
|
||||
<outlet property="screenWidth3" destination="cQO-ri-LxM" id="fBQ-VU-X4L"/>
|
||||
<outlet property="screenWidth4" destination="VvE-c8-mBx" id="acc-3d-WMa"/>
|
||||
<outlet property="scsiPath0" destination="nhQ-gw-2di" id="Ayi-Wk-Nhf"/>
|
||||
<outlet property="scsiPath1" destination="8th-va-hXP" id="xTk-Kd-9v2"/>
|
||||
<outlet property="scsiPath2" destination="RTT-NZ-Tte" id="w7D-05-cvN"/>
|
||||
|
@ -19,34 +31,33 @@
|
|||
<outlet property="scsiPath4" destination="Biz-iI-IiP" id="gbh-Jl-dxV"/>
|
||||
<outlet property="scsiPath5" destination="GE2-3P-G1I" id="ohD-Fj-EX9"/>
|
||||
<outlet property="scsiPath6" destination="cy8-jg-woV" id="QoH-Z0-e8d"/>
|
||||
<outlet property="tapPath" destination="Wvc-cC-QWO" id="kuK-DA-ui3"/>
|
||||
<outlet property="verbose" destination="fkL-RE-iRz" id="uba-U2-Zkh"/>
|
||||
<outlet property="window" destination="rKy-wc-8AE" id="sYz-fH-ohd"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||
<customObject id="-3" userLabel="Application"/>
|
||||
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||
<window title="Preferences" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="rKy-wc-8AE">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="498" height="433"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="878"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1440" height="877"/>
|
||||
<view key="contentView" id="4Fm-p8-6h9">
|
||||
<rect key="frame" x="0.0" y="0.0" width="498" height="433"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<tabView fixedFrame="YES" drawsBackground="NO" initialItem="Ffn-1Z-2rp" translatesAutoresizingMaskIntoConstraints="NO" id="i29-bb-k7Y">
|
||||
<rect key="frame" x="13" y="33" width="472" height="394"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<tabViewItems>
|
||||
<tabViewItem label="General" identifier="1" id="Ffn-1Z-2rp">
|
||||
<view key="view" ambiguous="YES" id="BF8-Dm-rF5">
|
||||
<view key="view" id="BF8-Dm-rF5">
|
||||
<rect key="frame" x="10" y="33" width="452" height="348"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oVj-nA-5GP">
|
||||
<rect key="frame" x="11" y="314" width="81" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="Rom Path:" usesSingleLineMode="YES" id="7qD-i1-FXI">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -55,7 +66,6 @@
|
|||
</textField>
|
||||
<button identifier="romPathBrowse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="fjl-Jg-nIF">
|
||||
<rect key="frame" x="358" y="303" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ITb-nX-hmP">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -66,7 +76,6 @@
|
|||
</button>
|
||||
<textField identifier="romPath" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="LoN-Nd-9cy">
|
||||
<rect key="frame" x="98" y="292" width="258" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="macii.rom" drawsBackground="YES" id="IvC-yQ-qdn">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -75,7 +84,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RDI-wU-bdg">
|
||||
<rect key="frame" x="2" y="267" width="90" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="Memory (MB):" usesSingleLineMode="YES" id="8mu-le-9YC">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -84,61 +92,14 @@
|
|||
</textField>
|
||||
<textField identifier="memorySize" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uvm-gd-pCd">
|
||||
<rect key="frame" x="98" y="262" width="42" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="8" placeholderString="8" drawsBackground="YES" id="I5v-kb-eCo">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tgt-1x-QT0">
|
||||
<rect key="frame" x="2" y="210" width="90" height="42"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="right" title="Screen Resolution:" id="9bl-WA-bhb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JNe-0k-g4e">
|
||||
<rect key="frame" x="146" y="224" width="14" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="center" title="x" id="9cf-Xq-tuu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aSg-xG-o1t">
|
||||
<rect key="frame" x="223" y="223" width="59" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="left" title="pixels" id="D5V-Zm-Grd">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="widthBox" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EMf-gC-m9T">
|
||||
<rect key="frame" x="98" y="220" width="43" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="width" placeholderString="width" drawsBackground="YES" id="sbq-WW-C05">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="heightBox" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wyt-jg-xmk">
|
||||
<rect key="frame" x="168" y="220" width="49" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="height" placeholderString="height" drawsBackground="YES" id="qvE-Bk-NDl">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fNZ-zo-4uj">
|
||||
<rect key="frame" x="7" y="10" width="103" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Zap PRAM" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="EGV-fk-y4d">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -147,6 +108,223 @@
|
|||
<action selector="zapPramPressed:" target="-2" id="9N7-dY-Fl6"/>
|
||||
</connections>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0nJ-ho-P1P">
|
||||
<rect key="frame" x="11" y="235" width="81" height="17"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="Kernel Path:" usesSingleLineMode="YES" id="Wdx-2C-yGA">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="kernelPath" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zU0-5O-afD">
|
||||
<rect key="frame" x="98" y="232" width="325" height="22"/>
|
||||
<string key="toolTip">The path to the kernel on the root image. If you don't know what this is, just use "/unix" (Note: the root image needs to be at SCSI ID 0)</string>
|
||||
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="/unix" drawsBackground="YES" id="0MQ-1P-9gJ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button identifier="verbose" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fkL-RE-iRz">
|
||||
<rect key="frame" x="283" y="18" width="142" height="18"/>
|
||||
<string key="toolTip">Verbose mode causes A/UX to print diagnostic info during boot, and it will also run fsck to repair the root filesystem if necessary.</string>
|
||||
<buttonCell key="cell" type="check" title="A/UX Verbose Boot" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="htQ-zH-VRv">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Screens" identifier="" id="3o8-Ma-LAk">
|
||||
<view key="view" id="Zdy-ik-svz">
|
||||
<rect key="frame" x="10" y="33" width="452" height="348"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tgt-1x-QT0">
|
||||
<rect key="frame" x="186" y="312" width="125" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="right" title="Screen Resolution:" id="9bl-WA-bhb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ld1-xq-pdG">
|
||||
<rect key="frame" x="186" y="287" width="47" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="right" title="Width" id="QBW-rk-c7E">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JNe-0k-g4e">
|
||||
<rect key="frame" x="241" y="259" width="14" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="center" title="x" id="9cf-Xq-tuu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="aSg-xG-o1t">
|
||||
<rect key="frame" x="317" y="259" width="59" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="left" title="pixels" id="D5V-Zm-Grd">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="width1" toolTip="width" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="EMf-gC-m9T">
|
||||
<rect key="frame" x="192" y="256" width="43" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="width" placeholderString="width" drawsBackground="YES" id="sbq-WW-C05">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="height1" toolTip="height" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wyt-jg-xmk">
|
||||
<rect key="frame" x="262" y="256" width="49" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="height" placeholderString="height" drawsBackground="YES" id="qvE-Bk-NDl">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button identifier="verbose" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JSa-Bw-xDM">
|
||||
<rect key="frame" x="57" y="258" width="129" height="18"/>
|
||||
<string key="toolTip">Verbose mode causes A/UX to print diagnostic info during boot, and it will also run fsck to repair the root filesystem if necessary.</string>
|
||||
<buttonCell key="cell" type="check" title="Enable Screen 1" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="azN-j2-txA">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button identifier="verbose" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="QR4-Cc-AkE">
|
||||
<rect key="frame" x="57" y="228" width="129" height="18"/>
|
||||
<string key="toolTip">Verbose mode causes A/UX to print diagnostic info during boot, and it will also run fsck to repair the root filesystem if necessary.</string>
|
||||
<buttonCell key="cell" type="check" title="Enable Screen 2" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Zqf-mb-br4">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<button identifier="verbose" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="C6X-Zw-psD">
|
||||
<rect key="frame" x="57" y="198" width="129" height="18"/>
|
||||
<string key="toolTip">Verbose mode causes A/UX to print diagnostic info during boot, and it will also run fsck to repair the root filesystem if necessary.</string>
|
||||
<buttonCell key="cell" type="check" title="Enable Screen 3" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="Cfv-ZG-aBO">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="G8E-Jw-aPd">
|
||||
<rect key="frame" x="241" y="229" width="14" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="center" title="x" id="1RP-Cp-YFY">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8hd-at-UXU">
|
||||
<rect key="frame" x="317" y="229" width="59" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="left" title="pixels" id="2DF-kS-r5B">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="width2" toolTip="width" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="B2c-pG-rIH">
|
||||
<rect key="frame" x="192" y="226" width="43" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="width" placeholderString="width" drawsBackground="YES" id="DMe-fk-aJx">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="height2" toolTip="height" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="IPj-pY-K2b">
|
||||
<rect key="frame" x="262" y="226" width="49" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="height" placeholderString="height" drawsBackground="YES" id="3F9-jB-hfl">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="uAk-QS-Kpu">
|
||||
<rect key="frame" x="241" y="199" width="14" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="center" title="x" id="XrI-eJ-Xmq">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="a0D-DN-Abg">
|
||||
<rect key="frame" x="317" y="199" width="59" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="left" title="pixels" id="V3B-61-meh">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="width3" toolTip="width" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cQO-ri-LxM">
|
||||
<rect key="frame" x="192" y="196" width="43" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="width" placeholderString="width" drawsBackground="YES" id="5Rx-30-P1a">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="height3" toolTip="height" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="tqh-iM-5GM">
|
||||
<rect key="frame" x="262" y="196" width="49" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="height" placeholderString="height" drawsBackground="YES" id="PdC-tw-Mou">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="WMg-rd-urO">
|
||||
<rect key="frame" x="241" y="169" width="14" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="center" title="x" id="r21-SX-0ht">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="NDL-uY-GIk">
|
||||
<rect key="frame" x="317" y="169" width="59" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="left" title="pixels" id="gKj-k6-3XK">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="width4" toolTip="width" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="VvE-c8-mBx">
|
||||
<rect key="frame" x="192" y="166" width="43" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="width" placeholderString="width" drawsBackground="YES" id="rfI-7T-Vc2">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="height4" toolTip="height" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="3aP-6m-As4">
|
||||
<rect key="frame" x="262" y="166" width="49" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="height" placeholderString="height" drawsBackground="YES" id="56I-cY-cml">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="bgh-Ds-kMn">
|
||||
<rect key="frame" x="260" y="287" width="47" height="17"/>
|
||||
<textFieldCell key="cell" allowsUndo="NO" alignment="right" title="Height" id="Ato-zm-vpN">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button identifier="verbose" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="isQ-0Q-gQ4">
|
||||
<rect key="frame" x="57" y="168" width="129" height="18"/>
|
||||
<string key="toolTip">Verbose mode causes A/UX to print diagnostic info during boot, and it will also run fsck to repair the root filesystem if necessary.</string>
|
||||
<buttonCell key="cell" type="check" title="Enable Screen 4" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="dNj-R0-mIT">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
|
@ -157,7 +335,6 @@
|
|||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dA0-AE-SsA">
|
||||
<rect key="frame" x="1" y="321" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 0" usesSingleLineMode="YES" id="YYd-8o-kqe">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -166,7 +343,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath0Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="BUV-3F-sRD">
|
||||
<rect key="frame" x="353" y="310" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Ekq-OL-WH9">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -177,7 +353,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath0" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nhQ-gw-2di">
|
||||
<rect key="frame" x="79" y="299" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="4NZ-tu-sNu">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -186,7 +361,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Gjz-Nn-CkC">
|
||||
<rect key="frame" x="1" y="274" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 1" usesSingleLineMode="YES" id="oPB-iw-Fuy">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -195,7 +369,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath1Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="0OE-Ny-sRU">
|
||||
<rect key="frame" x="353" y="263" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="iRT-nY-bQx">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -206,7 +379,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath1" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="8th-va-hXP">
|
||||
<rect key="frame" x="79" y="252" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="wM4-Hu-6dD">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -215,7 +387,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="17i-H8-woP">
|
||||
<rect key="frame" x="1" y="227" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 2" usesSingleLineMode="YES" id="rWu-qs-tIH">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -224,7 +395,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath2Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="OS6-vm-18P">
|
||||
<rect key="frame" x="353" y="216" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="ojq-kT-7Hz">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -235,7 +405,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath2" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RTT-NZ-Tte">
|
||||
<rect key="frame" x="79" y="205" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="bx9-L2-52p">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -244,7 +413,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zeV-Os-yjZ">
|
||||
<rect key="frame" x="1" y="180" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 3" usesSingleLineMode="YES" id="4Ir-Qy-6TG">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -253,7 +421,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath3Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="hyG-x9-NBA">
|
||||
<rect key="frame" x="353" y="169" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Toc-PB-8FO">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -264,7 +431,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath3" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="pKG-3S-zID">
|
||||
<rect key="frame" x="79" y="158" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="Ksz-dn-t4g">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -273,7 +439,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Rpv-lh-1BC">
|
||||
<rect key="frame" x="1" y="133" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 4" usesSingleLineMode="YES" id="RSB-J8-WHv">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -282,7 +447,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath4Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="FUw-LT-FRg">
|
||||
<rect key="frame" x="353" y="122" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="CDZ-hc-2Kz">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -293,7 +457,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath4" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Biz-iI-IiP">
|
||||
<rect key="frame" x="79" y="111" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="j2E-vU-3LZ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -302,7 +465,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eGO-wX-v7I">
|
||||
<rect key="frame" x="1" y="86" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 5" usesSingleLineMode="YES" id="lVw-XZ-DkQ">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -311,7 +473,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath5Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="Ur1-2a-9nV">
|
||||
<rect key="frame" x="353" y="75" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="QW3-hO-eDz">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -322,7 +483,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath5" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GE2-3P-G1I">
|
||||
<rect key="frame" x="79" y="64" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="BrK-XM-gcx">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -331,7 +491,6 @@
|
|||
</textField>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="c4H-Kt-ANK">
|
||||
<rect key="frame" x="1" y="39" width="72" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="SCSI ID 6" usesSingleLineMode="YES" id="NS8-2m-U2B">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -340,7 +499,6 @@
|
|||
</textField>
|
||||
<button identifier="scsiPath6Browse" verticalHuggingPriority="750" fixedFrame="YES" tag="9" translatesAutoresizingMaskIntoConstraints="NO" id="Twn-Yd-cyf">
|
||||
<rect key="frame" x="353" y="28" width="97" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Browse..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="JNl-qq-v8p">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -351,7 +509,6 @@
|
|||
</button>
|
||||
<textField identifier="scsiPath6" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="cy8-jg-woV">
|
||||
<rect key="frame" x="79" y="17" width="272" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingMiddle" truncatesLastVisibleLine="YES" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="None" drawsBackground="YES" id="gZa-0y-cOt">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -361,35 +518,56 @@
|
|||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
<tabViewItem label="Booting" identifier="" id="3o8-Ma-LAk">
|
||||
<view key="view" id="Zdy-ik-svz">
|
||||
<tabViewItem label="Ethernet" identifier="" id="npc-ti-4lo">
|
||||
<view key="view" id="2Hm-kn-wCU">
|
||||
<rect key="frame" x="10" y="33" width="452" height="348"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="0nJ-ho-P1P">
|
||||
<rect key="frame" x="6" y="315" width="81" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="Kernel Path:" usesSingleLineMode="YES" id="Wdx-2C-yGA">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="oLm-yd-Ca2">
|
||||
<rect key="frame" x="15" y="272" width="93" height="17"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="MAC Address:" usesSingleLineMode="YES" id="vve-T4-Rce">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="kernelPath" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="zU0-5O-afD">
|
||||
<rect key="frame" x="93" y="310" width="342" height="22"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<string key="toolTip">The path to the kernel on the root image. If you don't know what this is, just use "/unix" (Note: the root image needs to be at SCSI ID 0)</string>
|
||||
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" placeholderString="/unix" drawsBackground="YES" id="0MQ-1P-9gJ">
|
||||
<textField identifier="macAddress" toolTip="The MAC address of the emulated ethernet card" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="UAs-x7-p28">
|
||||
<rect key="frame" x="114" y="269" width="160" height="22"/>
|
||||
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="AA:AA:AA:AA:AA:AA" placeholderString="01:02:03:04:05:06" drawsBackground="YES" id="2is-7Y-0d2">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button identifier="verbose" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fkL-RE-iRz">
|
||||
<rect key="frame" x="6" y="271" width="142" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<string key="toolTip">Verbose mode causes A/UX to print diagnostic info during boot, and it will also run fsck to repair the root filesystem if necessary.</string>
|
||||
<buttonCell key="cell" type="check" title="A/UX Verbose Boot" bezelStyle="regularSquare" imagePosition="left" state="on" inset="2" id="htQ-zH-VRv">
|
||||
<textField verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="vp5-0F-Hl5">
|
||||
<rect key="frame" x="30" y="302" width="78" height="17"/>
|
||||
<textFieldCell key="cell" lineBreakMode="truncatingTail" allowsUndo="NO" alignment="right" title="TAP Device:" usesSingleLineMode="YES" id="QWi-Fs-xtO">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField identifier="tapPath" toolTip="The path to the TAP device (/dev/tap0 should be fine)" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Wvc-cC-QWO">
|
||||
<rect key="frame" x="114" y="299" width="313" height="22"/>
|
||||
<textFieldCell key="cell" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" state="on" borderStyle="bezel" title="/dev/tap0" placeholderString="/dev/tap0" drawsBackground="YES" id="Sb8-nl-Q5r">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<button toolTip="Generate a new MAC address" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="gZ8-0N-f6V">
|
||||
<rect key="frame" x="276" y="263" width="157" height="32"/>
|
||||
<buttonCell key="cell" type="push" title="New MAC Address" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="04X-Ao-SYd">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="newMacAddrPressed:" target="-2" id="Lgm-OH-3ff"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button identifier="enableEthernet" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GCJ-G0-drE">
|
||||
<rect key="frame" x="15" y="218" width="142" height="18"/>
|
||||
<buttonCell key="cell" type="check" title="Enable Ethernet" bezelStyle="regularSquare" imagePosition="left" inset="2" id="03F-wY-3oH">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
|
@ -401,7 +579,6 @@
|
|||
</tabView>
|
||||
<button identifier="applyAndRun" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="r8k-B7-iXM">
|
||||
<rect key="frame" x="352" y="5" width="132" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Apply and Run" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="oR1-x8-VgY">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -412,7 +589,6 @@
|
|||
</button>
|
||||
<button identifier="cancel" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="T6y-kh-jgH">
|
||||
<rect key="frame" x="188" y="5" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Cancel" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Sk4-hr-Ot6">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
@ -426,7 +602,6 @@ Gw
|
|||
</button>
|
||||
<button identifier="apply" verticalHuggingPriority="750" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="ZDd-0H-a3B">
|
||||
<rect key="frame" x="270" y="5" width="82" height="32"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="push" title="Apply" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="bC6-3u-5Op">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
[[NSRunLoop currentRunLoop] addTimer:timer
|
||||
forMode:NSEventTrackingRunLoopMode];
|
||||
|
||||
[[self window] setTitle:[NSString stringWithFormat:@"Shoebill - Screen 1"]];
|
||||
[[self window] setTitle:[NSString stringWithFormat:@"Shoebill"]];
|
||||
[[self window] makeKeyAndOrderFront:nil];
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
shoeApplication *shoeApp = (shoeApplication*)NSApp;
|
||||
shoeApp->doCaptureMouse = NO;
|
||||
CGDisplayShowCursor(0);
|
||||
[self setTitle:@"Shoebill - Screen 1"];
|
||||
[self setTitle:@"Shoebill"];
|
||||
}
|
||||
|
||||
- (void) captureMouse
|
||||
|
@ -113,7 +113,7 @@
|
|||
shoeApp->doCaptureMouse = YES;
|
||||
CGDisplayHideCursor(0);
|
||||
[self warpToCenter];
|
||||
[self setTitle:@"Shoebill - Screen 1 (Ctrl-click to escape)"];
|
||||
[self setTitle:@"Shoebill (Ctrl-click to escape)"];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ for i in adb fpu mc68851 mem via floppy core_api cpu dis; do
|
|||
files="$files $i.post.c"
|
||||
done
|
||||
|
||||
for i in atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer ethernet sound; do
|
||||
for i in SoftFloat/softfloat atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer ethernet sound; do
|
||||
files="$files ../core/$i.c"
|
||||
done
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ for i in adb fpu mc68851 mem via floppy core_api cpu dis; do
|
|||
files="$files $i.post.c"
|
||||
done
|
||||
|
||||
for i in atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer ethernet sound; do
|
||||
for i in SoftFloat/softfloat atrap_tab coff exception macii_symbols redblack scsi video filesystem alloc_pool toby_frame_buffer ethernet sound; do
|
||||
files="$files ../core/$i.c"
|
||||
done
|
||||
|
||||
|
@ -17,6 +17,6 @@ $CC -O1 ../core/decoder_gen.c -o decoder_gen
|
|||
./decoder_gen dis .
|
||||
|
||||
|
||||
cmd="$CC -O3 -ggdb -flto $files sdl.c -framework OpenGL -framework SDL2 -o shoebill"
|
||||
cmd="$CC -F/Library/Frameworks -O3 -ggdb -flto $files sdl.c -framework OpenGL -framework SDL2 -o shoebill"
|
||||
echo $cmd
|
||||
$cmd
|
||||
|
|
|
@ -6,4 +6,4 @@ gcc -O1 ..\core\decoder_gen.c -o decoder_gen
|
|||
decoder_gen inst .
|
||||
decoder_gen dis .
|
||||
|
||||
gcc -O3 -flto -mno-ms-bitfields sdl.c adb.post.c fpu.post.c mc68851.post.c mem.post.c via.post.c floppy.post.c core_api.post.c cpu.post.c dis.post.c ..\core\atrap_tab.c ..\core\coff.c ..\core\exception.c ..\core\macii_symbols.c ..\core\redblack.c ..\core\scsi.c ..\core\video.c ..\core\filesystem.c ..\core\alloc_pool.c ..\core\toby_frame_buffer.c ..\core\ethernet.c ..\core\sound.c -lmingw32 -lopengl32 -lsdl2main -lsdl2 -o shoebill
|
||||
gcc -O3 -flto -mno-ms-bitfields sdl.c adb.post.c fpu.post.c mc68851.post.c mem.post.c via.post.c floppy.post.c core_api.post.c cpu.post.c dis.post.c ..\core\atrap_tab.c ..\core\coff.c ..\core\exception.c ..\core\macii_symbols.c ..\core\redblack.c ..\core\scsi.c ..\core\video.c ..\core\filesystem.c ..\core\alloc_pool.c ..\core\toby_frame_buffer.c ..\core\ethernet.c ..\core\sound.c ..\core\SoftFloat\softfloat.c -lmingw32 -lopengl32 -lsdl2main -lsdl2 -o shoebill
|
||||
|
|
Loading…
Reference in New Issue
Block a user