mirror of
https://github.com/kanjitalk755/macemu.git
synced 2025-02-16 14:30:34 +00:00
Merge remote-tracking branch 'cebix/master' into windows_build_script_test_merge
This commit is contained in:
commit
83ea8b0779
@ -125,7 +125,7 @@ void add_path_component(char *path, const char *component)
|
||||
path[l] = '/';
|
||||
path[l+1] = 0;
|
||||
}
|
||||
strncat(path, component, MAX_PATH_LENGTH-1);
|
||||
strlcat(path, component, MAX_PATH_LENGTH);
|
||||
}
|
||||
|
||||
|
||||
@ -185,11 +185,11 @@ static void make_finf_path(const char *src, char *dest, bool only_dir = false)
|
||||
dest[last_part-src] = 0;
|
||||
|
||||
// Add additional component
|
||||
strncat(dest, ".finf/", MAX_PATH_LENGTH-1);
|
||||
strlcat(dest, ".finf/", MAX_PATH_LENGTH);
|
||||
|
||||
// Add last component
|
||||
if (!only_dir)
|
||||
strncat(dest, last_part, MAX_PATH_LENGTH-1);
|
||||
strlcat(dest, last_part, MAX_PATH_LENGTH);
|
||||
}
|
||||
|
||||
static int create_finf_dir(const char *path)
|
||||
|
@ -215,7 +215,7 @@ static void CustomApplicationMain (int argc, char **argv)
|
||||
#endif /* SDL_USE_CPS */
|
||||
|
||||
/* Set up the menubar */
|
||||
[NSApp setMainMenu:[[NSMenu alloc] init]];
|
||||
[NSApp setMainMenu:[[[NSMenu alloc] init] autorelease]];
|
||||
setApplicationMenu();
|
||||
setupWindowMenu();
|
||||
|
||||
|
@ -216,6 +216,27 @@ static inline void vm_release_framebuffer(void *fb, uint32 size)
|
||||
vm_release(fb, size);
|
||||
}
|
||||
|
||||
static inline int get_customized_color_depth(int default_depth)
|
||||
{
|
||||
int display_color_depth = PrefsFindInt32("displaycolordepth");
|
||||
|
||||
D(bug("Get displaycolordepth %d\n", display_color_depth));
|
||||
|
||||
if(0 == display_color_depth)
|
||||
return default_depth;
|
||||
else{
|
||||
switch (display_color_depth) {
|
||||
case 8:
|
||||
return VIDEO_DEPTH_8BIT;
|
||||
case 15: case 16:
|
||||
return VIDEO_DEPTH_16BIT;
|
||||
case 24: case 32:
|
||||
return VIDEO_DEPTH_32BIT;
|
||||
default:
|
||||
return default_depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Windows message handler
|
||||
@ -322,12 +343,6 @@ static void ErrorAlert(int error)
|
||||
{
|
||||
ErrorAlert(GetString(error));
|
||||
}
|
||||
|
||||
// Display warning alert
|
||||
static void WarningAlert(int warning)
|
||||
{
|
||||
WarningAlert(GetString(warning));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@ -366,26 +381,6 @@ static int palette_size(int mode)
|
||||
}
|
||||
}
|
||||
|
||||
// Return bytes per pixel for requested depth
|
||||
static inline int bytes_per_pixel(int depth)
|
||||
{
|
||||
int bpp;
|
||||
switch (depth) {
|
||||
case 8:
|
||||
bpp = 1;
|
||||
break;
|
||||
case 15: case 16:
|
||||
bpp = 2;
|
||||
break;
|
||||
case 24: case 32:
|
||||
bpp = 4;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return bpp;
|
||||
}
|
||||
|
||||
// Map video_mode depth ID to numerical depth value
|
||||
static int mac_depth_of_video_depth(int video_depth)
|
||||
{
|
||||
@ -669,7 +664,7 @@ void driver_base::init()
|
||||
|
||||
// Check whether we can initialize the VOSF subsystem and it's profitable
|
||||
if (!video_vosf_init(monitor)) {
|
||||
WarningAlert(STR_VOSF_INIT_ERR);
|
||||
WarningAlert(GetString(STR_VOSF_INIT_ERR));
|
||||
use_vosf = false;
|
||||
}
|
||||
else if (!video_vosf_profitable()) {
|
||||
@ -1144,8 +1139,12 @@ bool VideoInit(bool classic)
|
||||
}
|
||||
#endif
|
||||
|
||||
int color_depth = get_customized_color_depth(default_depth);
|
||||
|
||||
D(bug("Return get_customized_color_depth %d\n", color_depth));
|
||||
|
||||
// Create SDL_monitor_desc for this (the only) display
|
||||
SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)default_depth, default_id);
|
||||
SDL_monitor_desc *monitor = new SDL_monitor_desc(VideoModes, (video_depth)color_depth, default_id);
|
||||
VideoMonitors.push_back(monitor);
|
||||
|
||||
// Open display
|
||||
|
@ -20,6 +20,7 @@
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
@ -27,10 +28,10 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <mach/vm_prot.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <mach-o/fat.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
static const char progname[] = "lowmem";
|
||||
static const char *filename;
|
||||
|
47
BasiliskII/src/Unix/Linux/NetDriver/README.md
Normal file
47
BasiliskII/src/Unix/Linux/NetDriver/README.md
Normal file
@ -0,0 +1,47 @@
|
||||
# What
|
||||
|
||||
sheep_net is a character virtual device that bridge between BasiliskII and Physical Ethernet card(P)
|
||||
|
||||
Here is logical diagram:
|
||||
|
||||
Guest Mac OS in emulation (G) <==> Basilisk II (B) <==> /dev/sheep_net (S) <==> Physical Ethernet card on host (P)
|
||||
|
||||
sheep_net module masquerade and de-masquerade MAC address on Ethernet frame so that Guest OS and host share the same MAC address with different IP.
|
||||
|
||||
See details in [IP aliasing](https://en.wikipedia.org/wiki/IP_aliasing)
|
||||
|
||||
# How
|
||||
## How it works
|
||||
|
||||
Sample Setting:
|
||||
|
||||
Guest Mac OS IP: 192.168.2.2, Fake MAC address: 84:38:35:5e:c5:5b
|
||||
|
||||
Host OS Physical Ethernet car IP: 192.168.2.3, physical MAC address: 84:38:35:5e:c5:5a
|
||||
|
||||
From outside, we see 192.168.2.2 and 192.168.2.3 share the same physical MAC address: 84:38:35:5e:c5:5a
|
||||
|
||||
From insides, sheep_net module masquerade and de-masquerade MAC address of Ethernet packet between Basilisk and
|
||||
|
||||
```
|
||||
B ==> S ==> P: de-masquerade MAC, convert Fake to Physical
|
||||
B <== S <== P: masquerade MAC, convert Physical to Fake
|
||||
```
|
||||
|
||||
## How to compile
|
||||
```
|
||||
cd Linux/NetDriver
|
||||
make
|
||||
//create sheep_net device node
|
||||
sudo make dev
|
||||
sudo chown [user account] /dev/sheep_net
|
||||
sudo make install
|
||||
sudo modprobe sheep_net
|
||||
```
|
||||
|
||||
## How to use
|
||||
1. Disable IP forwarding on host (Recommended: By disabling it, guest OS won't receive duplicate IP packet from host again.)
|
||||
2. Disable firewall on host (Recommended: host may send ICMP host unreachable to gateway. Or you can disable ICMP sending from host by changing iptables.)
|
||||
3. sudo modprobe sheep_net
|
||||
4. sudo chown [user account] /dev/sheep_net
|
||||
5. Launch BasiliskII, choose your physical Ethernet card interface in network tab
|
@ -23,6 +23,15 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/init.h>
|
||||
|
||||
/* wrap up socket object allocation */
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 00)
|
||||
#define compat_sk_alloc(_net, _family, _priority, _proto) \
|
||||
sk_alloc(_net, _family, _priority, _proto, 0)
|
||||
#else
|
||||
#define compat_sk_alloc(_net, _family, _priority, _proto) \
|
||||
sk_alloc(_net, _family, _priority, _proto)
|
||||
#endif
|
||||
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,15,0)
|
||||
#define LINUX_3_15
|
||||
#endif
|
||||
@ -214,7 +223,7 @@ int init_module(void)
|
||||
|
||||
/* Register driver */
|
||||
ret = misc_register(&sheep_net_device);
|
||||
D(bug("Sheep net driver installed\n"));
|
||||
printk("sheep net: driver installed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -227,7 +236,7 @@ void cleanup_module(void)
|
||||
{
|
||||
/* Unregister driver */
|
||||
misc_deregister(&sheep_net_device);
|
||||
D(bug("Sheep net driver removed\n"));
|
||||
printk("sheep net: driver removed\n");
|
||||
}
|
||||
|
||||
|
||||
@ -491,7 +500,8 @@ static ssize_t sheep_net_write(struct file *f, const char *buf, size_t count, lo
|
||||
netif_rx(skb);
|
||||
return count;
|
||||
}
|
||||
if (skb->data[0] & ETH_ADDR_MULTICAST) {
|
||||
/* Relay multicast for host process except ARP packet */
|
||||
if ((skb->data[0] & ETH_ADDR_MULTICAST) && (eth_hdr(skb)->h_proto != htons(ETH_P_ARP))) {
|
||||
/* We can't clone the skb since we will manipulate the data below */
|
||||
struct sk_buff *lskb = skb_copy(skb, GFP_ATOMIC);
|
||||
if (lskb) {
|
||||
@ -587,7 +597,7 @@ static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int cod
|
||||
|
||||
/* Allocate socket */
|
||||
#ifdef LINUX_26
|
||||
v->skt = sk_alloc(dev_net(v->ether), GFP_USER, 1, &sheep_proto);
|
||||
v->skt = compat_sk_alloc(dev_net(v->ether), GFP_USER, 1, &sheep_proto);
|
||||
#else
|
||||
v->skt = sk_alloc(0, GFP_USER, 1);
|
||||
#endif
|
||||
@ -597,10 +607,16 @@ static int sheep_net_ioctl(struct inode *inode, struct file *f, unsigned int cod
|
||||
}
|
||||
skt_set_dead(v->skt);
|
||||
|
||||
/*initialize ipfilter*/
|
||||
v->ipfilter = 0;
|
||||
|
||||
/* Attach packet handler */
|
||||
v->pt.type = htons(ETH_P_ALL);
|
||||
v->pt.dev = v->ether;
|
||||
v->pt.func = sheep_net_receiver;
|
||||
#ifdef LINUX_26
|
||||
v->pt.af_packet_priv = v;
|
||||
#endif
|
||||
dev_add_pack(&v->pt);
|
||||
#ifndef LINUX_24
|
||||
dev_unlock_list();
|
||||
@ -706,7 +722,11 @@ static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struc
|
||||
static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
|
||||
#endif
|
||||
{
|
||||
#ifdef LINUX_26
|
||||
struct SheepVars *v = (struct SheepVars *)pt->af_packet_priv;
|
||||
#else
|
||||
struct SheepVars *v = (struct SheepVars *)pt;
|
||||
#endif
|
||||
struct sk_buff *skb2;
|
||||
int fake;
|
||||
int multicast;
|
||||
@ -730,8 +750,25 @@ static int sheep_net_receiver(struct sk_buff *skb, struct net_device *dev, struc
|
||||
/* Apply any filters here (if fake is true, then we *know* we want this packet) */
|
||||
if (!fake) {
|
||||
if ((skb->protocol == htons(ETH_P_IP))
|
||||
&& (!v->ipfilter || (ntohl(ipip_hdr(skb)->daddr) != v->ipfilter && !multicast)))
|
||||
&& (!v->ipfilter || (ntohl(ip_hdr(skb)->daddr) != v->ipfilter && !multicast))) {
|
||||
#if DEBUG
|
||||
char source[16];
|
||||
snprintf(source, 16, "%pI4", &ip_hdr(skb)->saddr);
|
||||
D(bug("sheep_net: drop incoming IP packet %s for filter %d.%d.%d.%d\n",
|
||||
source,
|
||||
(v->ipfilter >> 24) & 0xff, (v->ipfilter >> 16) & 0xff, (v->ipfilter >> 8) & 0xff, v->ipfilter & 0xff));
|
||||
#endif
|
||||
goto drop;
|
||||
}
|
||||
#if DEBUG
|
||||
else{
|
||||
if(!multicast){
|
||||
char source[16];
|
||||
snprintf(source, 16, "%pI4", &ip_hdr(skb)->saddr);
|
||||
D(bug("sheep_net: retain incoming unicast IP packet %s\n", source));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Masquerade (we are typically a clone - best to make a real copy) */
|
||||
|
@ -799,9 +799,9 @@ static uint8 *fill_buffer(int stream_len)
|
||||
#ifdef USE_SDL_AUDIO
|
||||
void MixAudio_bincue(uint8 *stream, int stream_len)
|
||||
{
|
||||
uint8 *buf;
|
||||
if (audio_enabled && (player.audiostatus == CDROM_AUDIO_PLAY)) {
|
||||
if (buf = fill_buffer(stream_len))
|
||||
uint8 *buf = fill_buffer(stream_len);
|
||||
if (buf)
|
||||
SDL_MixAudio(stream, buf, stream_len, SDL_MIX_MAXVOLUME);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "extfs.h"
|
||||
@ -256,6 +257,14 @@ void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
|
||||
|
||||
void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
|
||||
{
|
||||
struct utimbuf times;
|
||||
times.actime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlCrDat));
|
||||
times.modtime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlMdDat));
|
||||
|
||||
if (utime(path, ×) < 0) {
|
||||
D(bug("utime failed on %s\n", path));
|
||||
}
|
||||
|
||||
// Open Finder info file
|
||||
int fd = open_finf(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
|
@ -64,8 +64,6 @@
|
||||
#define pthread_cancel(th)
|
||||
#define pthread_join(th, ret)
|
||||
#define pthread_testcancel()
|
||||
#define pthread_create(th, attr, start, arg) dummy_thread_create()
|
||||
static inline int dummy_thread_create(void) { errno = ENOSYS; return -1; }
|
||||
|
||||
#undef pthread_mutex_t
|
||||
#define pthread_mutex_t volatile int
|
||||
@ -433,7 +431,9 @@ static struct {
|
||||
int last;
|
||||
int count;
|
||||
} g_message_descriptors = { NULL, 0, 0 };
|
||||
#ifdef USE_THREADS
|
||||
static pthread_mutex_t g_message_descriptors_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
#endif
|
||||
|
||||
// Add a user-defined marshaler
|
||||
static int rpc_message_add_callback(const rpc_message_descriptor_t *desc)
|
||||
|
@ -77,7 +77,7 @@ $IPTABLES -L -n -t nat > /dev/null || exit 1
|
||||
#########################################################
|
||||
|
||||
{
|
||||
$IPTABLES -t nat -D POSTROUTING -s $TUN_NET -d ! $TUN_NET -j MASQUERADE
|
||||
$IPTABLES -t nat -D POSTROUTING -s $TUN_NET ! -d $TUN_NET -j MASQUERADE
|
||||
} >& /dev/null
|
||||
|
||||
#########################################################
|
||||
@ -96,7 +96,7 @@ $IPTABLES -L -n -t nat > /dev/null || exit 1
|
||||
$IFCONFIG $TUN_DEV $TUN_HOST
|
||||
|
||||
# masquerade the tun network
|
||||
$IPTABLES -t nat -A POSTROUTING -s $TUN_NET -d ! $TUN_NET -j MASQUERADE
|
||||
$IPTABLES -t nat -A POSTROUTING -s $TUN_NET ! -d $TUN_NET -j MASQUERADE
|
||||
}
|
||||
|
||||
exit 0
|
||||
|
@ -269,6 +269,14 @@ void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
|
||||
|
||||
void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
|
||||
{
|
||||
struct my_utimbuf times;
|
||||
times.actime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlCrDat));
|
||||
times.modtime = MacTimeToTime(ReadMacInt32(finfo - ioFlFndrInfo + ioFlMdDat));
|
||||
|
||||
if (utime(path, ×) < 0) {
|
||||
D(bug("utime failed on %s, error %d\n", path, GetLastError()));
|
||||
}
|
||||
|
||||
// Open Finder info file
|
||||
int fd = open_finf(path, O_RDWR);
|
||||
if (fd < 0)
|
||||
|
@ -1123,3 +1123,28 @@ int my_write( int fd, const void *buffer, unsigned int count )
|
||||
D(bug("write(%ld,%08x,%ld) = %d\n", fd, buffer, count, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
static FILETIME get_file_time(time_t time) {
|
||||
FILETIME ft;
|
||||
unsigned long long result = 11644473600LL;
|
||||
result += time;
|
||||
result *= 10000000LL;
|
||||
ft.dwHighDateTime = (result >> 32);
|
||||
ft.dwLowDateTime = (result & 0xFFFFFFFF);
|
||||
return ft;
|
||||
}
|
||||
|
||||
int my_utime( const char *path, struct my_utimbuf * my_times )
|
||||
{
|
||||
auto tpath = tstr(path);
|
||||
LPCTSTR p = MRP(tpath.get());
|
||||
HANDLE f = CreateFile(p, FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (f != INVALID_HANDLE_VALUE) {
|
||||
FILETIME crTime = get_file_time(my_times->actime);
|
||||
FILETIME modTime = get_file_time(my_times->modtime);
|
||||
SetFileTime(f, &crTime, NULL, &modTime);
|
||||
CloseHandle(f);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -73,6 +73,7 @@ int my_read( int fd, void *, unsigned int);
|
||||
int my_write( int fd, const void *, unsigned int);
|
||||
int my_chsize( int fd, unsigned int size );
|
||||
int my_locking( int fd, int mode, long nbytes );
|
||||
int my_utime( const char *path, struct my_utimbuf * );
|
||||
|
||||
extern int my_errno;
|
||||
|
||||
@ -92,6 +93,7 @@ extern int my_errno;
|
||||
#define write my_write
|
||||
#define ftruncate my_chsize
|
||||
#define locking my_locking
|
||||
#define utime my_utime
|
||||
|
||||
#undef errno
|
||||
#define errno my_errno
|
||||
@ -116,6 +118,12 @@ struct my_stat {
|
||||
time_t st_ctime;
|
||||
};
|
||||
|
||||
struct my_utimbuf
|
||||
{
|
||||
time_t actime; // access time
|
||||
time_t modtime; // modification time
|
||||
};
|
||||
|
||||
// Your compiler may have different "struct stat" -> edit "struct my_stat"
|
||||
#define validate_stat_struct ( sizeof(struct my_stat) == sizeof(struct stat) )
|
||||
|
||||
|
@ -265,6 +265,7 @@ extern void MountVolume(void *fh); // Mount volume with given file handle (s
|
||||
extern void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size); // Calculate disk image file layout given file size and first 256 data bytes
|
||||
extern uint32 DebugUtil(uint32 Selector); // DebugUtil() Replacement
|
||||
extern uint32 TimeToMacTime(time_t t); // Convert time_t value to MacOS time
|
||||
extern time_t MacTimeToTime(uint32 t); // Convert MacOS time to time_t value
|
||||
|
||||
// Construct four-character-code
|
||||
#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d))
|
||||
|
@ -144,3 +144,13 @@ uint32 TimeToMacTime(time_t t)
|
||||
uint32 days = local->tm_yday + 365 * (local->tm_year - 4) + intervening_leap_days;
|
||||
return local->tm_sec + 60 * (local->tm_min + 60 * (local->tm_hour + 24 * days));
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert MacOS time to time_t (seconds since 1.1.1970)
|
||||
*/
|
||||
|
||||
time_t MacTimeToTime(uint32 t)
|
||||
{
|
||||
// simply subtract number of seconds between 1.1.1904 and 1.1.1970
|
||||
return t - 2082826800;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
// Except for "disk", "floppy", "cdrom", "scsiX", "screen", "rom" and "ether",
|
||||
// these are guaranteed to be in the prefs.
|
||||
prefs_desc common_prefs_items[] = {
|
||||
{"displaycolordepth", TYPE_INT32, false, "display color depth"},
|
||||
{"disk", TYPE_STRING, true, "device/file name of Mac volume"},
|
||||
{"floppy", TYPE_STRING, true, "device/file name of Mac floppy drive"},
|
||||
{"cdrom", TYPE_STRING, true, "device/file names of Mac CD-ROM drive"},
|
||||
@ -86,6 +87,7 @@ void AddPrefsDefaults(void)
|
||||
PrefsAddInt32("frameskip", 6);
|
||||
PrefsAddInt32("modelid", 5); // Mac IIci
|
||||
PrefsAddInt32("cpu", 3); // 68030
|
||||
PrefsAddInt32("displaycolordepth", 0);
|
||||
PrefsAddBool("fpu", false);
|
||||
PrefsAddBool("nocdrom", false);
|
||||
PrefsAddBool("nosound", false);
|
||||
|
@ -77,7 +77,7 @@ icmp_input(m, hlen)
|
||||
|
||||
DEBUG_CALL("icmp_input");
|
||||
DEBUG_ARG("m = %lx", (long )m);
|
||||
DEBUG_ARG("m_len = %d", m->m_len);
|
||||
DEBUG_ARG("m_len = %zu", m->m_len);
|
||||
|
||||
icmpstat.icps_received++;
|
||||
|
||||
@ -201,12 +201,12 @@ end_error:
|
||||
|
||||
#define ICMP_MAXDATALEN (IP_MSS-28)
|
||||
void
|
||||
icmp_error(msrc, type, code, minsize, message)
|
||||
struct mbuf *msrc;
|
||||
u_char type;
|
||||
u_char code;
|
||||
int minsize;
|
||||
char *message;
|
||||
icmp_error(
|
||||
struct mbuf *msrc,
|
||||
u_char type,
|
||||
u_char code,
|
||||
int minsize,
|
||||
char *message)
|
||||
{
|
||||
unsigned hlen, shlen, s_ip_len;
|
||||
register struct ip *ip;
|
||||
@ -215,7 +215,7 @@ icmp_error(msrc, type, code, minsize, message)
|
||||
|
||||
DEBUG_CALL("icmp_error");
|
||||
DEBUG_ARG("msrc = %lx", (long )msrc);
|
||||
DEBUG_ARG("msrc_len = %d", msrc->m_len);
|
||||
DEBUG_ARG("msrc_len = %zu", msrc->m_len);
|
||||
|
||||
if(type!=ICMP_UNREACH && type!=ICMP_TIMXCEED) goto end_error;
|
||||
|
||||
|
@ -72,7 +72,7 @@ ip_input(m)
|
||||
|
||||
DEBUG_CALL("ip_input");
|
||||
DEBUG_ARG("m = %lx", (long)m);
|
||||
DEBUG_ARG("m_len = %d", m->m_len);
|
||||
DEBUG_ARG("m_len = %zu", m->m_len);
|
||||
|
||||
ipstat.ips_total++;
|
||||
|
||||
|
@ -71,7 +71,7 @@ void sbappend(struct socket *so, struct mbuf *m)
|
||||
DEBUG_CALL("sbappend");
|
||||
DEBUG_ARG("so = %lx", (long)so);
|
||||
DEBUG_ARG("m = %lx", (long)m);
|
||||
DEBUG_ARG("m->m_len = %d", m->m_len);
|
||||
DEBUG_ARG("m->m_len = %zu", m->m_len);
|
||||
|
||||
/* Shouldn't happen, but... e.g. foreign host closes connection */
|
||||
if (m->m_len <= 0) {
|
||||
|
@ -84,7 +84,7 @@ static int get_dns_addr(struct in_addr *pdns_addr)
|
||||
static int get_dns_addr(struct in_addr *pdns_addr)
|
||||
{
|
||||
char buff[512];
|
||||
char buff2[256];
|
||||
char buff2[256+1];
|
||||
FILE *f;
|
||||
int found = 0;
|
||||
struct in_addr tmp_addr;
|
||||
|
@ -454,7 +454,7 @@ sorecvfrom(so)
|
||||
|
||||
m->m_len = recvfrom(so->s, m->m_data, len, 0,
|
||||
(struct sockaddr *)&addr, &addrlen);
|
||||
DEBUG_MISC((dfd, " did recvfrom %d, errno = %d-%s\n",
|
||||
DEBUG_MISC((dfd, " did recvfrom %zu, errno = %d-%s\n",
|
||||
m->m_len, errno,strerror(errno)));
|
||||
if(m->m_len<0) {
|
||||
u_char code=ICMP_UNREACH_PORT;
|
||||
|
@ -66,7 +66,7 @@ u_char tcp_outflags[TCP_NSTATES] = {
|
||||
int tcp_output(register struct tcpcb *tp)
|
||||
{
|
||||
register struct socket *so = tp->t_socket;
|
||||
register u_long len, win;
|
||||
register long len, win;
|
||||
int off, flags, error;
|
||||
register struct mbuf *m;
|
||||
register struct tcpiphdr *ti;
|
||||
@ -199,12 +199,12 @@ again:
|
||||
* taking into account that we are limited by
|
||||
* TCP_MAXWIN << tp->rcv_scale.
|
||||
*/
|
||||
u_int adv = min(win, (u_int)TCP_MAXWIN << tp->rcv_scale) -
|
||||
long adv = min(win, TCP_MAXWIN << tp->rcv_scale) -
|
||||
(tp->rcv_adv - tp->rcv_nxt);
|
||||
|
||||
if (adv >= (u_int)(2 * tp->t_maxseg))
|
||||
if (adv >= (long)(2 * tp->t_maxseg))
|
||||
goto send;
|
||||
if (2 * adv >= so->so_rcv.sb_datalen)
|
||||
if (2 * adv >= (long)so->so_rcv.sb_datalen)
|
||||
goto send;
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,6 @@ static int tftp_send_error(struct tftp_session *spt,
|
||||
struct sockaddr_in saddr, daddr;
|
||||
struct mbuf *m;
|
||||
struct tftp_t *tp;
|
||||
int nobytes;
|
||||
|
||||
m = m_get();
|
||||
|
||||
@ -152,8 +151,6 @@ static int tftp_send_error(struct tftp_session *spt,
|
||||
daddr.sin_addr = spt->client_ip;
|
||||
daddr.sin_port = spt->client_port;
|
||||
|
||||
nobytes = 2;
|
||||
|
||||
m->m_len = sizeof(struct tftp_t) - 514 + 3 + strlen(msg) -
|
||||
sizeof(struct ip) - sizeof(struct udphdr);
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
}
|
||||
|
||||
-(NSString*)description {
|
||||
return [NSString stringWithFormat:@"DiskType, path:%@ isCDROM:%@", _path, _isCDROM];
|
||||
return [NSString stringWithFormat:@"DiskType, path:%@ isCDROM:%hhd", _path, _isCDROM];
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -110,7 +110,7 @@ static NSString *getStringFromPrefs(const char *key)
|
||||
const char *dsk;
|
||||
int index = 0;
|
||||
while ((dsk = PrefsFindString("disk", index++)) != NULL) {
|
||||
DiskType *disk = [[DiskType alloc] init];
|
||||
DiskType *disk = [[[DiskType alloc] init] autorelease];
|
||||
[disk setPath:[NSString stringWithUTF8String: dsk ]];
|
||||
[disk setIsCDROM:NO];
|
||||
|
||||
@ -120,7 +120,7 @@ static NSString *getStringFromPrefs(const char *key)
|
||||
/* Fetch all CDROMs */
|
||||
index = 0;
|
||||
while ((dsk = PrefsFindString("cdrom", index++)) != NULL) {
|
||||
DiskType *disk = [[DiskType alloc] init];
|
||||
DiskType *disk = [[[DiskType alloc] init] autorelease];
|
||||
[disk setPath:[NSString stringWithUTF8String: dsk ]];
|
||||
[disk setIsCDROM:YES];
|
||||
|
||||
@ -266,7 +266,7 @@ static NSString *makeRelativeIfNecessary(NSString *path)
|
||||
- (void) _addDiskEnd: (NSOpenPanel *) open returnCode: (int) theReturnCode contextInfo: (void *) theContextInfo
|
||||
{
|
||||
if (theReturnCode == NSOKButton) {
|
||||
DiskType *d = [[DiskType alloc] init];
|
||||
DiskType *d = [[[DiskType alloc] init] autorelease];
|
||||
[d setPath:makeRelativeIfNecessary([open filename])];
|
||||
|
||||
[d setIsCDROM:([isCDROMcheckbox state] == NSOnState)];
|
||||
@ -307,7 +307,7 @@ static NSString *makeRelativeIfNecessary(NSString *path)
|
||||
snprintf(cmd, sizeof(cmd), "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", [[save filename] UTF8String], [diskSaveSizeField intValue]);
|
||||
int ret = system(cmd);
|
||||
if (ret == 0) {
|
||||
DiskType *d = [[DiskType alloc] init];
|
||||
DiskType *d = [[[DiskType alloc] init] autorelease];
|
||||
[d setPath:makeRelativeIfNecessary([save filename])];
|
||||
[d setIsCDROM:NO];
|
||||
|
||||
|
1469
SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj
Normal file
1469
SheepShaver/src/MacOSX/SheepShaver_Xcode8.xcodeproj/project.pbxproj
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ under newer versions of Xcode or Mac OS X.
|
||||
To use it, you need the following:
|
||||
|
||||
1. A complete 'macemu' git checkout of SheepShaver and BasiliskII.
|
||||
2. SDL installed as a framework in /Library/Frameworks/SDL.framework.
|
||||
2. SDL 1.2 installed as a framework in /Library/Frameworks/SDL.framework.
|
||||
3. You do not need to run autogen.sh / configure to use the Xcode
|
||||
project. If you've done so already, you should remove or temporarily
|
||||
move/rename src/Unix/config.h, as the presence of that file currently
|
||||
@ -24,3 +24,17 @@ and build SheepShaver, resulting in a UB build containing SDL as a
|
||||
private framework in the bundle. The result will be located in either
|
||||
SheepShaver/src/MacOSX/build/Debug or SheepShaver/src/MacOSX/build/Release
|
||||
directories, depending if you do a Debug or Release build.
|
||||
|
||||
|
||||
There is also an Xcode 8 project file for use with Xcode 8 and newer
|
||||
(e.g. 8.2 on 10.11 or 10.12). The main differences are:
|
||||
|
||||
1. This builds a i386 version of SheepShaver instead of Universal Binary.
|
||||
This is because since PPC is not supported by Xcode 8 and newer versions of
|
||||
OS X disallow having memory mapped at page zero for 64-bit applications,
|
||||
which SheepShaver requires.
|
||||
|
||||
2. Since the SheepShaver JIT-generation compilation does not support Clang,
|
||||
this build uses prebuilt and checked-in dyngen source files, rather than
|
||||
building dyngen and generating them with it, as is done normally during the
|
||||
SheepShaver build process.
|
||||
|
1666
SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops-x86_32.hpp
Normal file
1666
SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops-x86_32.hpp
Normal file
File diff suppressed because it is too large
Load Diff
1694
SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops-x86_64.hpp
Normal file
1694
SheepShaver/src/Unix/dyngen_precompiled/basic-dyngen-ops-x86_64.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
#if defined(__x86_64__)
|
||||
#include "basic-dyngen-ops-x86_64.hpp"
|
||||
#elif defined(__i386__)
|
||||
#include "basic-dyngen-ops-x86_32.hpp"
|
||||
#else
|
||||
#error Unknown platform
|
||||
#endif
|
11187
SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_32.hpp
Normal file
11187
SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_32.hpp
Normal file
File diff suppressed because it is too large
Load Diff
11116
SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_64.hpp
Normal file
11116
SheepShaver/src/Unix/dyngen_precompiled/ppc-dyngen-ops-x86_64.hpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,7 @@
|
||||
#if defined(__x86_64__)
|
||||
#include "ppc-dyngen-ops-x86_64.hpp"
|
||||
#elif defined(__i386__)
|
||||
#include "ppc-dyngen-ops-x86_32.hpp"
|
||||
#else
|
||||
#error Unknown platform
|
||||
#endif
|
305
SheepShaver/src/Unix/dyngen_precompiled/ppc-execute-impl.cpp
Normal file
305
SheepShaver/src/Unix/dyngen_precompiled/ppc-execute-impl.cpp
Normal file
@ -0,0 +1,305 @@
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_RB, operand_NONE, CA_BIT_0, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_RB, operand_NONE, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_RB, operand_XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_or_0, operand_SIMM, operand_NONE, CA_BIT_0, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_SIMM, operand_NONE, CA_BIT_1, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_SIMM, operand_NONE, CA_BIT_1, OE_BIT_0, RC_BIT_1>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_or_0, operand_SIMM_shifted, operand_NONE, CA_BIT_0, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_MINUS_ONE, operand_XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA, operand_ZERO, operand_XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_and, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_andc, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_and, operand_RA, operand_RS, operand_UIMM, operand_NONE, OE_BIT_0, RC_BIT_1>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_and, operand_RA, operand_RS, operand_UIMM_shifted, operand_NONE, OE_BIT_0, RC_BIT_1>(uint32);
|
||||
template void powerpc_cpu::execute_branch<operand_PC, immediate_value<(((0) ? 0 : 16) | ((0) ? 8 : 0) | ((0) ? 0 : 4) | ((0) ? 2 : 0))>, operand_LI, AA_BIT_G, LK_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_branch<operand_PC, operand_BO, operand_BD, AA_BIT_G, LK_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_branch<operand_CTR, operand_BO, operand_ZERO, AA_BIT_0, LK_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_branch<operand_LR, operand_BO, operand_ZERO, AA_BIT_0, LK_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_compare<operand_RB, int32>(uint32);
|
||||
template void powerpc_cpu::execute_compare<operand_SIMM, int32>(uint32);
|
||||
template void powerpc_cpu::execute_compare<operand_RB, uint32>(uint32);
|
||||
template void powerpc_cpu::execute_compare<operand_UIMM, uint32>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_cntlzw, operand_RA, operand_RS, operand_NONE, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_and>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_andc>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_eqv>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_nand>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_nor>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_or>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_orc>(uint32);
|
||||
template void powerpc_cpu::execute_cr_op<op_xor>(uint32);
|
||||
template void powerpc_cpu::execute_dcbz<operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_divide<true, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_divide<false, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_eqv, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_sign_extend_8_32, operand_RA, operand_RS, operand_NONE, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_sign_extend_16_32, operand_RA, operand_RS, operand_NONE, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fabs, operand_fp_RD, operand_fp_RB, operand_fp_NONE, operand_fp_NONE, RC_BIT_G, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fadd, operand_fp_RD, operand_fp_RA, operand_fp_RB, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<float, op_fadd, operand_fp_RD, operand_fp_RA, operand_fp_RB, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_compare<true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_compare<false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_int_convert<operand_FPSCR_RN, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_fp_int_convert<operand_ONE, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fdiv, operand_fp_RD, operand_fp_RA, operand_fp_RB, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<float, op_fdiv, operand_fp_RD, operand_fp_RA, operand_fp_RB, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fmadd, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<float, op_fmadd, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fnop, operand_fp_RD, operand_fp_RB, operand_fp_NONE, operand_fp_NONE, RC_BIT_G, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fmsub, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<float, op_fmsub, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fmul, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<float, op_fmul, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fnabs, operand_fp_RD, operand_fp_RB, operand_fp_NONE, operand_fp_NONE, RC_BIT_G, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fneg, operand_fp_RD, operand_fp_RB, operand_fp_NONE, operand_fp_NONE, RC_BIT_G, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fnmadd, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fnmadds, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fnmsub, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fnmsubs, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_round<RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fsel, operand_fp_RD, operand_fp_RA, operand_fp_RC, operand_fp_RB, RC_BIT_G, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<double, op_fsub, operand_fp_RD, operand_fp_RA, operand_fp_RB, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_arith<float, op_fsub, operand_fp_RD, operand_fp_RA, operand_fp_RB, operand_fp_NONE, RC_BIT_G, true>(uint32);
|
||||
template void powerpc_cpu::execute_icbi<operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_D, true, 1, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_D, true, 1, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_RB, true, 1, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, true, 1, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_D, true, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_D, true, true, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_RB, true, true, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_RB, true, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_D, true, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_D, true, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_RB, true, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_RB, true, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_sign_extend_16_32, operand_RA_or_0, operand_D, true, 2, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_sign_extend_16_32, operand_RA, operand_D, true, 2, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_sign_extend_16_32, operand_RA, operand_RB, true, 2, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_sign_extend_16_32, operand_RA_or_0, operand_RB, true, 2, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, true, 2, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_D, true, 2, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_D, true, 2, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_RB, true, 2, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, true, 2, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore_multiple<operand_RA_or_0, operand_D, true>(uint32);
|
||||
template void powerpc_cpu::execute_load_string<operand_RA_or_0, true, operand_NB>(uint32);
|
||||
template void powerpc_cpu::execute_load_string<operand_RA_or_0, false, operand_XER_COUNT>(uint32);
|
||||
template void powerpc_cpu::execute_vector_load<operand_vD_V16QIm, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_load<operand_vD_V8HIm, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_load<operand_vD_V4SI, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_load_for_shift<1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_load_for_shift<0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_load<operand_vD_V2DI, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_lwarx<operand_RA_or_0>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, true, 4, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_D, true, 4, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_D, true, 4, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_RB, true, 4, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, true, 4, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_nop, operand_RD, operand_CR, operand_NONE, operand_NONE, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_mffs<RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_mfspr<operand_SPR>(uint32);
|
||||
template void powerpc_cpu::execute_mftbr<operand_TBR>(uint32);
|
||||
template void powerpc_cpu::execute_mtfsb<immediate_value<0>, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_mtfsb<immediate_value<1>, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_mtfsf<operand_FM, operand_fp_dw_RB, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_mtfsfi<operand_IMM, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_mtspr<operand_SPR>(uint32);
|
||||
template void powerpc_cpu::execute_multiply<true, true, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_multiply<true, false, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_smul, operand_RD, operand_RA, operand_SIMM, operand_NONE, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_multiply<false, true, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_nand, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_neg, operand_RD, operand_RA, operand_NONE, operand_NONE, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_nor, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_or, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_orc, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_or, operand_RA, operand_RS, operand_UIMM, operand_NONE, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_or, operand_RA, operand_RS, operand_UIMM_shifted, operand_NONE, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_rlwimi<operand_SH, operand_MASK, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_ppc_rlwinm, operand_RA, operand_RS, operand_SH, operand_MASK, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_ppc_rlwnm, operand_RA, operand_RS, operand_RB, operand_MASK, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_shift<op_shll, operand_RA, operand_RS, operand_RB, op_andi<0x3f>, CA_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_shift<op_shra, operand_RA, operand_RS, operand_RB, op_andi<0x3f>, CA_BIT_1, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_shift<op_shra, operand_RA, operand_RS, operand_SH, op_andi<0x1f>, CA_BIT_1, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_shift<op_shrl, operand_RA, operand_RS, operand_RB, op_andi<0x3f>, CA_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_D, false, 1, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_D, false, 1, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_RB, false, 1, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, false, 1, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_D, false, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_D, false, true, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_RB, false, true, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_RB, false, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_D, false, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_D, false, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA, operand_RB, false, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_fp_loadstore<operand_RA_or_0, operand_RB, false, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_D, false, 2, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, false, 2, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_D, false, 2, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_RB, false, 2, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, false, 2, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore_multiple<operand_RA_or_0, operand_D, false>(uint32);
|
||||
template void powerpc_cpu::execute_store_string<operand_RA_or_0, true, operand_NB>(uint32);
|
||||
template void powerpc_cpu::execute_store_string<operand_RA_or_0, false, operand_XER_COUNT>(uint32);
|
||||
template void powerpc_cpu::execute_vector_store<operand_vD_V16QIm, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_store<operand_vD_V8HIm, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_store<operand_vD_V4SI, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_store<operand_vD_V2DI, operand_RA_or_0, operand_RB>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_D, false, 4, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, false, 4, false, true>(uint32);
|
||||
template void powerpc_cpu::execute_stwcx<operand_RA_or_0>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_D, false, 4, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA, operand_RB, false, 4, true, false>(uint32);
|
||||
template void powerpc_cpu::execute_loadstore<op_nop, operand_RA_or_0, operand_RB, false, 4, false, false>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_compl, operand_RB, operand_ONE, CA_BIT_0, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_compl, operand_RB, operand_ONE, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_compl, operand_RB, operand_XER_CA, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_compl, operand_SIMM, operand_ONE, CA_BIT_1, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_compl, operand_XER_CA, operand_MINUS_ONE, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_addition<operand_RA_compl, operand_XER_CA, operand_ZERO, CA_BIT_1, OE_BIT_G, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_xor, operand_RA, operand_RS, operand_RB, operand_NONE, OE_BIT_0, RC_BIT_G>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_xor, operand_RA, operand_RS, operand_UIMM, operand_NONE, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_generic_arith<op_xor, operand_RA, operand_RS, operand_UIMM_shifted, operand_NONE, OE_BIT_0, RC_BIT_0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_addcuw, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_fadds, operand_vD_V4SF, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V16QI_SAT<int8>, operand_vA_V16QI_SAT<int8>, operand_vB_V16QI_SAT<int8>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V8HI_SAT<int16>, operand_vA_V8HI_SAT<int16>, operand_vB_V8HI_SAT<int16>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add_64, operand_vD_V4SI_SAT<int32>, operand_vA_V4SI_SAT<int32>, operand_vB_V4SI_SAT<int32>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V16QI_SAT<uint8>, operand_vA_V16QI_SAT<uint8>, operand_vB_V16QI_SAT<uint8>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V8HI_SAT<uint16>, operand_vA_V8HI_SAT<uint16>, operand_vB_V8HI_SAT<uint16>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_add_64, operand_vD_V4SI_SAT<uint32>, operand_vA_V4SI_SAT<uint32>, operand_vB_V4SI_SAT<uint32>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_and_64, operand_vD_V2DI, operand_vA_V2DI, operand_vB_V2DI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_andc_64, operand_vD_V2DI, operand_vA_V2DI, operand_vB_V2DI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_avgsb, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_avgsh, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_avgsw, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_avgub, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_avguh, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_avguw, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cvt_si2fp<int32>, operand_vD_V4SF, operand_vA_UIMM, operand_vB_V4SIs, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cvt_si2fp<uint32>, operand_vD_V4SF, operand_vA_UIMM, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmpbfp, operand_vD_V4SI, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, vRC_BIT_G, 0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_eq<float>, operand_vD_V4SI, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_eq<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_eq<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_eq<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_ge<float>, operand_vD_V4SI, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<float>, operand_vD_V4SI, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<int8>, operand_vD_V16QI, operand_vA_V16QIs, operand_vB_V16QIs, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<int16>, operand_vD_V8HI, operand_vA_V8HIs, operand_vB_V8HIs, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<int32>, operand_vD_V4SI, operand_vA_V4SIs, operand_vB_V4SIs, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cmp_gt<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, vRC_BIT_G, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cvt_fp2si, operand_vD_V4SI_SAT<int32>, operand_vA_UIMM, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_cvt_fp2si, operand_vD_V4SI_SAT<uint32>, operand_vA_UIMM, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_exp2, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_log2, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vmaddfp, operand_vD_V4SF, operand_vA_V4SF, operand_vB_V4SF, operand_vC_V4SF, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<float>, operand_vD_V4SF, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<int8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<int16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<int32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_max<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_mhraddsh<0>, operand_vD_V8HI_SAT<int16>, operand_vA_V8HI_SAT<int16>, operand_vB_V8HI_SAT<int16>, operand_vC_V8HI_SAT<int16>, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_mhraddsh<0x4000>, operand_vD_V8HI_SAT<int16>, operand_vA_V8HI_SAT<int16>, operand_vB_V8HI_SAT<int16>, operand_vC_V8HI_SAT<int16>, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<float>, operand_vD_V4SF, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<int8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<int16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<int32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_min<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_mladduh, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_V8HI, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_merge<operand_vD_V16QIm, operand_vA_V16QIm, operand_vB_V16QIm, 0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_merge<operand_vD_V8HIm, operand_vA_V8HIm, operand_vB_V8HIm, 0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_merge<operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, 0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_merge<operand_vD_V16QIm, operand_vA_V16QIm, operand_vB_V16QIm, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_merge<operand_vD_V8HIm, operand_vA_V8HIm, operand_vB_V8HIm, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_merge<operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, 1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_mixed<op_smul, operand_vD_V4SI, operand_vA_V16QI_SAT<int8>, operand_vB_V16QI_SAT<uint8>, operand_vC_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_mixed<op_smul, operand_vD_V4SI, operand_vA_V8HI_SAT<int16>, operand_vB_V8HI_SAT<int16>, operand_vC_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_mixed<op_smul_64, operand_vD_V4SI_SAT<int32>, operand_vA_V8HI_SAT<int16>, operand_vB_V8HI_SAT<int16>, operand_vC_V4SIs>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_mixed<op_mul, operand_vD_V4SI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_mixed<op_mul, operand_vD_V4SI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_mixed<op_mul, operand_vD_V4SI_SAT<uint32>, operand_vA_V8HI, operand_vB_V8HI, operand_vC_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<0, op_smul, operand_vD_V8HIm, operand_vA_V16QIm_SAT<int8>, operand_vB_V16QIm_SAT<int8>, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<0, op_smul, operand_vD_V4SI, operand_vA_V8HIm_SAT<int16>, operand_vB_V8HIm_SAT<int16>, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<0, op_mul, operand_vD_V8HIm, operand_vA_V16QIm, operand_vB_V16QIm, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<0, op_mul, operand_vD_V4SI, operand_vA_V8HIm, operand_vB_V8HIm, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<1, op_smul, operand_vD_V8HIm, operand_vA_V16QIm_SAT<int8>, operand_vB_V16QIm_SAT<int8>, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<1, op_smul, operand_vD_V4SI, operand_vA_V8HIm_SAT<int16>, operand_vB_V8HIm_SAT<int16>, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<1, op_mul, operand_vD_V8HIm, operand_vA_V16QIm, operand_vB_V16QIm, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith_odd<1, op_mul, operand_vD_V4SI, operand_vA_V8HIm, operand_vB_V8HIm, operand_vC_NONE>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vnmsubfp, operand_vD_V4SF, operand_vA_V4SF, operand_vB_V4SF, operand_vC_V4SF, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_nor_64, operand_vD_V2DI, operand_vA_V2DI, operand_vB_V2DI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_or_64, operand_vD_V2DI, operand_vA_V2DI, operand_vB_V2DI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V16QIm_SAT<int8>, operand_vA_V8HIm, operand_vB_V8HIm>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V16QIm_SAT<uint8>, operand_vA_V8HIm, operand_vB_V8HIm>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V8HIm_SAT<int16>, operand_vA_V4SI, operand_vB_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V8HIm_SAT<uint16>, operand_vA_V4SI, operand_vB_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V16QIm, operand_vA_V8HIm, operand_vB_V8HIm>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V16QIm_USAT<uint8>, operand_vA_V8HIm, operand_vB_V8HIm>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V8HIm, operand_vA_V4SI, operand_vB_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_pack<operand_vD_V8HIm_USAT<uint16>, operand_vA_V4SI, operand_vB_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_fres, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_frsim, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_frsin, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_frsip, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_frsiz, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vrl<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vrl<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vrl<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_frsqrt, operand_vD_V4SF, operand_vA_NONE, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsel, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_V4SI, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_shift<-1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsl<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_shift_octet<-1, operand_vD_V16QIm, operand_vA_V16QIm, operand_vB_V16QIm, operand_SHB>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsl<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_shift_octet<-1, operand_vD_V16QIm, operand_vA_V16QIm, operand_vB_NONE, operand_SHBO>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsl<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_splat<op_nop, operand_vD_V16QI, operand_vB_V16QIm, false>(uint32);
|
||||
template void powerpc_cpu::execute_vector_splat<op_nop, operand_vD_V8HI, operand_vB_V8HIm, false>(uint32);
|
||||
template void powerpc_cpu::execute_vector_splat<op_sign_extend_5_32, operand_vD_V16QI, operand_vB_UIMM, true>(uint32);
|
||||
template void powerpc_cpu::execute_vector_splat<op_sign_extend_5_32, operand_vD_V8HI, operand_vB_UIMM, true>(uint32);
|
||||
template void powerpc_cpu::execute_vector_splat<op_sign_extend_5_32, operand_vD_V4SI, operand_vB_UIMM, true>(uint32);
|
||||
template void powerpc_cpu::execute_vector_splat<op_nop, operand_vD_V4SI, operand_vB_V4SI, false>(uint32);
|
||||
template void powerpc_cpu::execute_vector_shift<+1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsr<int8>, operand_vD_V16QI, operand_vA_V16QIs, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsr<int16>, operand_vD_V8HI, operand_vA_V8HIs, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsr<int32>, operand_vD_V4SI, operand_vA_V4SIs, operand_vB_V4SIs, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsr<uint8>, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsr<uint16>, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_shift_octet<+1, operand_vD_V16QIm, operand_vA_V16QIm, operand_vB_NONE, operand_SHBO>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_vsr<uint32>, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_subcuw, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_fsubs, operand_vD_V4SF, operand_vA_V4SF, operand_vB_V4SF, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V16QI_SAT<int8>, operand_vA_V16QI_SAT<int8>, operand_vB_V16QI_SAT<int8>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V8HI_SAT<int16>, operand_vA_V8HI_SAT<int16>, operand_vB_V8HI_SAT<int16>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub_64, operand_vD_V4SI_SAT<int32>, operand_vA_V4SI_SAT<int32>, operand_vB_V4SI_SAT<int32>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V16QI, operand_vA_V16QI, operand_vB_V16QI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V16QI_SAT<uint8>, operand_vA_V16QI_SAT<uint8>, operand_vB_V16QI_SAT<uint8>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V8HI, operand_vA_V8HI, operand_vB_V8HI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V8HI_SAT<uint16>, operand_vA_V8HI_SAT<uint16>, operand_vB_V8HI_SAT<uint16>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub, operand_vD_V4SI, operand_vA_V4SI, operand_vB_V4SI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_sub_64, operand_vD_V4SI_SAT<uint32>, operand_vA_V4SI_SAT<uint32>, operand_vB_V4SI_SAT<uint32>, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
||||
template void powerpc_cpu::execute_vector_sum<1, operand_vD_V4SI_SAT<int32>, operand_vA_V4SIs, operand_vB_V4SIs>(uint32);
|
||||
template void powerpc_cpu::execute_vector_sum<2, operand_vD_V4SI_SAT<int32>, operand_vA_V4SIs, operand_vB_V4SIs>(uint32);
|
||||
template void powerpc_cpu::execute_vector_sum<4, operand_vD_V4SI_SAT<int32>, operand_vA_V16QIs, operand_vB_V4SIs>(uint32);
|
||||
template void powerpc_cpu::execute_vector_sum<4, operand_vD_V4SI_SAT<int32>, operand_vA_V8HIs, operand_vB_V4SIs>(uint32);
|
||||
template void powerpc_cpu::execute_vector_sum<4, operand_vD_V4SI_SAT<uint32>, operand_vA_V16QI, operand_vB_V4SI>(uint32);
|
||||
template void powerpc_cpu::execute_vector_unpack_pixel<0>(uint32);
|
||||
template void powerpc_cpu::execute_vector_unpack<0, operand_vD_V8HIms, operand_vB_V16QIms>(uint32);
|
||||
template void powerpc_cpu::execute_vector_unpack<0, operand_vD_V4SIs, operand_vB_V8HIms>(uint32);
|
||||
template void powerpc_cpu::execute_vector_unpack_pixel<1>(uint32);
|
||||
template void powerpc_cpu::execute_vector_unpack<1, operand_vD_V8HIms, operand_vB_V16QIms>(uint32);
|
||||
template void powerpc_cpu::execute_vector_unpack<1, operand_vD_V4SIs, operand_vB_V8HIms>(uint32);
|
||||
template void powerpc_cpu::execute_vector_arith<op_xor_64, operand_vD_V2DI, operand_vA_V2DI, operand_vB_V2DI, operand_vC_NONE, fake_bit_field< bool, false >, 0 >(uint32);
|
@ -357,6 +357,7 @@ extern uint32 FindLibSymbol(const char *lib, const char *sym); // Find symbol in
|
||||
extern void InitCallUniversalProc(void); // Init CallUniversalProc()
|
||||
extern long CallUniversalProc(void *upp, uint32 info); // CallUniversalProc()
|
||||
extern uint32 TimeToMacTime(time_t t); // Convert time_t value to MacOS time
|
||||
extern time_t MacTimeToTime(uint32 t); // Convert MacOS time to time_t value
|
||||
extern uint32 Mac_sysalloc(uint32 size); // Allocate block in MacOS system heap zone
|
||||
extern void Mac_sysfree(uint32 addr); // Release block occupied by the nonrelocatable block p
|
||||
|
||||
|
@ -417,7 +417,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
cg_context.done_compile = true;
|
||||
status = COMPILE_EPILOGUE_OK;
|
||||
break;
|
||||
#endif
|
||||
#else
|
||||
// Invoke NativeOp handler
|
||||
if (!FN_field::test(opcode)) {
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32);
|
||||
@ -429,6 +429,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
// Otherwise, let it generate a call to execute_sheep() which
|
||||
// will cause necessary updates to the program counter
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
default: { // EMUL_OP
|
||||
@ -441,7 +442,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
cg_context.done_compile = true;
|
||||
status = COMPILE_EPILOGUE_OK;
|
||||
break;
|
||||
#endif
|
||||
#else
|
||||
// Invoke EmulOp handler
|
||||
typedef void (*func_t)(dyngen_cpu_base, uint32);
|
||||
func_t func = (func_t)nv_mem_fun(&sheepshaver_cpu::execute_emul_op).ptr();
|
||||
@ -449,6 +450,7 @@ int sheepshaver_cpu::compile1(codegen_context_t & cg_context)
|
||||
cg_context.done_compile = false;
|
||||
status = COMPILE_CODE_OK;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return status;
|
||||
@ -772,7 +774,7 @@ sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip)
|
||||
const uint32 pc = cpu->pc();
|
||||
|
||||
// Fault in Mac ROM or RAM?
|
||||
bool mac_fault = (pc >= ROMBase) && (pc < (ROMBase + ROM_AREA_SIZE)) || (pc >= RAMBase) && (pc < (RAMBase + RAMSize)) || (pc >= DR_CACHE_BASE && pc < (DR_CACHE_BASE + DR_CACHE_SIZE));
|
||||
bool mac_fault = (pc >= ROMBase && pc < (ROMBase + ROM_AREA_SIZE)) || (pc >= RAMBase && pc < (RAMBase + RAMSize)) || (pc >= DR_CACHE_BASE && pc < (DR_CACHE_BASE + DR_CACHE_SIZE));
|
||||
if (mac_fault) {
|
||||
|
||||
// "VM settings" during MacOS 8 installation
|
||||
@ -815,7 +817,7 @@ sigsegv_return_t sigsegv_handler(sigsegv_info_t *sip)
|
||||
fprintf(stderr, " pc %p\n", sigsegv_get_fault_instruction_address(sip));
|
||||
fprintf(stderr, " ea %p\n", sigsegv_get_fault_address(sip));
|
||||
dump_registers();
|
||||
ppc_cpu->dump_log();
|
||||
dump_log();
|
||||
dump_disassembly(pc, 8, 8);
|
||||
|
||||
enter_mon();
|
||||
|
@ -147,9 +147,9 @@ basic_dyngen::gen_align(int align)
|
||||
f32_1, f32_2, f32_3, f32_4, f32_5, f32_6, f32_7, f32_8,
|
||||
f32_9, f32_10, f32_11, f32_12, f32_13, f32_14, f32_15
|
||||
};
|
||||
static const uint8 prefixes[4] = { 0x66, 0x66, 0x66, 0x66 };
|
||||
|
||||
#if defined(__x86_64__)
|
||||
static const uint8 prefixes[4] = { 0x66, 0x66, 0x66, 0x66 };
|
||||
/* The recommended way to pad 64bit code is to use NOPs preceded by
|
||||
maximally four 0x66 prefixes. Balance the size of nops. */
|
||||
int i;
|
||||
|
@ -77,7 +77,6 @@ basic_jit_cache::init_translation_cache(uint32 size)
|
||||
return false;
|
||||
}
|
||||
|
||||
done:
|
||||
D(bug("basic_jit_cache: Translation cache: %d KB at %p\n", cache_size / 1024, tcode_start));
|
||||
code_start = tcode_start;
|
||||
code_p = code_start;
|
||||
|
@ -548,7 +548,6 @@ void *powerpc_cpu::compile_chain_block(block_info *sbi)
|
||||
// which is aligned at least on 4-byte boundaries
|
||||
const int n = ((uintptr)sbi) & 3;
|
||||
sbi = (block_info *)(((uintptr)sbi) & ~3L);
|
||||
const uint32 bpc = sbi->pc;
|
||||
|
||||
const uint32 tpc = sbi->li[n].jmp_pc;
|
||||
block_info *tbi = my_block_cache.find(tpc);
|
||||
@ -603,7 +602,6 @@ void powerpc_cpu::execute(uint32 entry)
|
||||
// Compile new block
|
||||
bi = compile_block(pc());
|
||||
}
|
||||
goto return_site;
|
||||
}
|
||||
#endif
|
||||
#if PPC_DECODE_CACHE
|
||||
@ -704,9 +702,9 @@ void powerpc_cpu::execute(uint32 entry)
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto return_site;
|
||||
#endif
|
||||
#else
|
||||
goto do_interpret;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
do_interpret:
|
||||
|
@ -92,16 +92,6 @@ static inline int ppc_to_native_rounding_mode(int round)
|
||||
}
|
||||
}
|
||||
|
||||
static inline int native_to_ppc_rounding_mode(int round)
|
||||
{
|
||||
switch (round) {
|
||||
case FE_TONEAREST: return 0;
|
||||
case FE_TOWARDZERO: return 1;
|
||||
case FE_UPWARD: return 2;
|
||||
case FE_DOWNWARD: return 3;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper class to compute the overflow/carry condition
|
||||
*
|
||||
@ -1241,7 +1231,7 @@ template< class TBR >
|
||||
void powerpc_cpu::execute_mftbr(uint32 opcode)
|
||||
{
|
||||
uint32 tbr = TBR::get(this, opcode);
|
||||
uint32 d;
|
||||
uint32 d = 0;
|
||||
switch (tbr) {
|
||||
case 268: d = (uint32)get_tb_ticks(); break;
|
||||
case 269: d = (get_tb_ticks() >> 32); break;
|
||||
@ -1638,7 +1628,6 @@ void powerpc_cpu::execute_vector_shift_octet(uint32 opcode)
|
||||
typename VA::type const & vA = VA::const_ref(this, opcode);
|
||||
typename VB::type const & vB = VB::const_ref(this, opcode);
|
||||
typename VD::type & vD = VD::ref(this, opcode);
|
||||
const int n_elements = 16 / VD::element_size;
|
||||
|
||||
const int sh = SH::get(this, opcode);
|
||||
if (SD < 0) {
|
||||
|
@ -880,8 +880,7 @@ powerpc_cpu::compile_block(uint32 entry_point)
|
||||
case PPC_I(SUBFIC):
|
||||
dg.gen_subfc_T0_im(val);
|
||||
break;
|
||||
defautl:
|
||||
abort();
|
||||
default: abort();
|
||||
}
|
||||
dg.gen_store_T0_GPR(rD_field::extract(opcode));
|
||||
break;
|
||||
|
@ -339,6 +339,17 @@ uint32 TimeToMacTime(time_t t)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert MacOS time to time_t (seconds since 1.1.1970)
|
||||
*/
|
||||
|
||||
time_t MacTimeToTime(uint32 t)
|
||||
{
|
||||
// simply subtract number of seconds between 1.1.1904 and 1.1.1970
|
||||
return t - 2082826800;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Memory allocators in MacOS system heap zone
|
||||
*/
|
||||
|
@ -664,23 +664,6 @@ static const uint8 adbop_patch[] = { // Call ADBOp() completion procedure
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Copy PowerPC code to ROM image and reverse bytes if necessary
|
||||
*/
|
||||
|
||||
static inline void memcpy_powerpc_code(void *dst, const void *src, size_t len)
|
||||
{
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
(void)memcpy(dst, src, len);
|
||||
#else
|
||||
uint32 *d = (uint32 *)dst;
|
||||
uint32 *s = (uint32 *)src;
|
||||
for (int i = 0; i < len/4; i++)
|
||||
d[i] = htonl(s[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Install ROM patches (RAMBase and KernelDataAddr must be set)
|
||||
*/
|
||||
|
26
cxmon/.gitignore
vendored
Normal file
26
cxmon/.gitignore
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
# Object files
|
||||
*.o
|
||||
|
||||
# Executables and libraries
|
||||
src/cxmon
|
||||
src/disass/libdisass.a
|
||||
|
||||
# Autoconf generated files
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
cxmon.spec
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
stamp-h1
|
8
cxmon/AUTHORS
Normal file
8
cxmon/AUTHORS
Normal file
@ -0,0 +1,8 @@
|
||||
'mon' was written by
|
||||
Christian Bauer <www.cebix.net>
|
||||
Marc Hellwig <Marc.Hellwig@uni-mainz.de>
|
||||
|
||||
with contributions from
|
||||
Gwenolé Beauchesne (64-bit support and PPC extensions)
|
||||
|
||||
The 680x0 and 80x86 disassemblers are taken from GNU binutils.
|
340
cxmon/COPYING
Normal file
340
cxmon/COPYING
Normal file
@ -0,0 +1,340 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
20
cxmon/ChangeLog
Normal file
20
cxmon/ChangeLog
Normal file
@ -0,0 +1,20 @@
|
||||
V3.2 - 64-bit fixes to 680x0 disassembler, added AltiVec instructions to PPC
|
||||
disassembler, fixes to Z80 disassembler (hl->ix/iy and relative jumps)
|
||||
V3.1 - Make LowMem globals as predefined variables, fix 64-bit support, enable
|
||||
x86-64 disassembler with "d8664" command, removed input line length
|
||||
restrictions
|
||||
V3.0 - Replaced 680x0 and 80x86 disassemblers with the ones from GNU binutils,
|
||||
added symbolic display of MacOS low memory globals to PPC disassembler,
|
||||
MacOS features in PPC disassembler are controlled by "-m" argument,
|
||||
real memory mode is entered by "-r" argument, extended 8080 disassembler
|
||||
to Z80, name changed from "mon" to "cxmon"
|
||||
V2.2 - Switched to autoconf/automake, fixed some minor bugs in the PPC
|
||||
disassembler, commands made modular, added binary dump (b) command
|
||||
V2.1 - Compiled for BeOS R4, opens Terminal window when started from Tracker,
|
||||
implemented 8080 disassembler, included Unix makefile
|
||||
V2.0 - Unified PPC and x86 release
|
||||
V1.5 - Non-interactive mode, real mode
|
||||
V1.4 - Implemented 6502 and 680x0 disassemblers
|
||||
V1.3 - Now uses libreadline
|
||||
Disassembler: prints SPR names instead of numbers, fixed bugs
|
||||
V1.0 - Initial release
|
182
cxmon/INSTALL
Normal file
182
cxmon/INSTALL
Normal file
@ -0,0 +1,182 @@
|
||||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
The `configure' shell script attempts to guess correct values for
|
||||
various system-dependent variables used during compilation. It uses
|
||||
those values to create a `Makefile' in each directory of the package.
|
||||
It may also create one or more `.h' files containing system-dependent
|
||||
definitions. Finally, it creates a shell script `config.status' that
|
||||
you can run in the future to recreate the current configuration, a file
|
||||
`config.cache' that saves the results of its tests to speed up
|
||||
reconfiguring, and a file `config.log' containing compiler output
|
||||
(useful mainly for debugging `configure').
|
||||
|
||||
If you need to do unusual things to compile the package, please try
|
||||
to figure out how `configure' could check whether to do them, and mail
|
||||
diffs or instructions to the address given in the `README' so they can
|
||||
be considered for the next release. If at some point `config.cache'
|
||||
contains results you don't want to keep, you may remove or edit it.
|
||||
|
||||
The file `configure.in' is used to create `configure' by a program
|
||||
called `autoconf'. You only need `configure.in' if you want to change
|
||||
it or regenerate `configure' using a newer version of `autoconf'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
1. `cd' to the directory containing the package's source code and type
|
||||
`./configure' to configure the package for your system. If you're
|
||||
using `csh' on an old version of System V, you might need to type
|
||||
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||
`configure' itself.
|
||||
|
||||
Running `configure' takes awhile. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Optionally, type `make check' to run any self-tests that come with
|
||||
the package.
|
||||
|
||||
4. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
5. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'. To also remove the
|
||||
files that `configure' created (so you can compile the package for
|
||||
a different kind of computer), type `make distclean'. There is
|
||||
also a `make maintainer-clean' target, but that is intended mainly
|
||||
for the package's developers. If you use it, you may have to get
|
||||
all sorts of other programs in order to regenerate files that came
|
||||
with the distribution.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
Some systems require unusual options for compilation or linking that
|
||||
the `configure' script does not know about. You can give `configure'
|
||||
initial values for variables by setting them in the environment. Using
|
||||
a Bourne-compatible shell, you can do that on the command line like
|
||||
this:
|
||||
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
You can compile the package for more than one kind of computer at the
|
||||
same time, by placing the object files for each architecture in their
|
||||
own directory. To do this, you must use a version of `make' that
|
||||
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||
directory where you want the object files and executables to go and run
|
||||
the `configure' script. `configure' automatically checks for the
|
||||
source code in the directory that `configure' is in and in `..'.
|
||||
|
||||
If you have to use a `make' that does not supports the `VPATH'
|
||||
variable, you have to compile the package for one architecture at a time
|
||||
in the source code directory. After you have installed the package for
|
||||
one architecture, use `make distclean' before reconfiguring for another
|
||||
architecture.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
By default, `make install' will install the package's files in
|
||||
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||
installation prefix other than `/usr/local' by giving `configure' the
|
||||
option `--prefix=PATH'.
|
||||
|
||||
You can specify separate installation prefixes for
|
||||
architecture-specific files and architecture-independent files. If you
|
||||
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||
PATH as the prefix for installing programs and libraries.
|
||||
Documentation and other data files will still use the regular prefix.
|
||||
|
||||
In addition, if you use an unusual directory layout you can give
|
||||
options like `--bindir=PATH' to specify different values for particular
|
||||
kinds of files. Run `configure --help' for a list of the directories
|
||||
you can set and what kinds of files go in them.
|
||||
|
||||
If the package supports it, you can cause programs to be installed
|
||||
with an extra prefix or suffix on their names by giving `configure' the
|
||||
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
|
||||
|
||||
Optional Features
|
||||
=================
|
||||
|
||||
Some packages pay attention to `--enable-FEATURE' options to
|
||||
`configure', where FEATURE indicates an optional part of the package.
|
||||
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
|
||||
is something like `gnu-as' or `x' (for the X Window System). The
|
||||
`README' should mention any `--enable-' and `--with-' options that the
|
||||
package recognizes.
|
||||
|
||||
For packages that use the X Window System, `configure' can usually
|
||||
find the X include and library files automatically, but if it doesn't,
|
||||
you can use the `configure' options `--x-includes=DIR' and
|
||||
`--x-libraries=DIR' to specify their locations.
|
||||
|
||||
Specifying the System Type
|
||||
==========================
|
||||
|
||||
There may be some features `configure' can not figure out
|
||||
automatically, but needs to determine by the type of host the package
|
||||
will run on. Usually `configure' can figure that out, but if it prints
|
||||
a message saying it can not guess the host type, give it the
|
||||
`--host=TYPE' option. TYPE can either be a short name for the system
|
||||
type, such as `sun4', or a canonical name with three fields:
|
||||
CPU-COMPANY-SYSTEM
|
||||
|
||||
See the file `config.sub' for the possible values of each field. If
|
||||
`config.sub' isn't included in this package, then this package doesn't
|
||||
need to know the host type.
|
||||
|
||||
If you are building compiler tools for cross-compiling, you can also
|
||||
use the `--target=TYPE' option to select the type of system they will
|
||||
produce code for and the `--build=TYPE' option to select the type of
|
||||
system on which you are compiling the package.
|
||||
|
||||
Sharing Defaults
|
||||
================
|
||||
|
||||
If you want to set default values for `configure' scripts to share,
|
||||
you can create a site shell script called `config.site' that gives
|
||||
default values for variables like `CC', `cache_file', and `prefix'.
|
||||
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||
`CONFIG_SITE' environment variable to the location of the site script.
|
||||
A warning: not all `configure' scripts look for a site script.
|
||||
|
||||
Operation Controls
|
||||
==================
|
||||
|
||||
`configure' recognizes the following options to control how it
|
||||
operates.
|
||||
|
||||
`--cache-file=FILE'
|
||||
Use and save the results of the tests in FILE instead of
|
||||
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
|
||||
debugging `configure'.
|
||||
|
||||
`--help'
|
||||
Print a summary of the options to `configure', and exit.
|
||||
|
||||
`--quiet'
|
||||
`--silent'
|
||||
`-q'
|
||||
Do not print messages saying which checks are being made. To
|
||||
suppress all normal output, redirect it to `/dev/null' (any error
|
||||
messages will still be shown).
|
||||
|
||||
`--srcdir=DIR'
|
||||
Look for the package's source code in directory DIR. Usually
|
||||
`configure' can determine that directory automatically.
|
||||
|
||||
`--version'
|
||||
Print the version of Autoconf used to generate the `configure'
|
||||
script, and exit.
|
||||
|
||||
`configure' also accepts some other, not widely useful, options.
|
17
cxmon/Makefile.am
Normal file
17
cxmon/Makefile.am
Normal file
@ -0,0 +1,17 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
SUBDIRS = src
|
||||
|
||||
# Manpages
|
||||
man_MANS = cxmon.1
|
||||
|
||||
EXTRA_DIST = cxmon.1 bootstrap
|
||||
|
||||
dist-hook: cxmon.spec
|
||||
cp cxmon.spec $(distdir)
|
||||
|
||||
# Rule to build tar-gzipped distribution package
|
||||
$(PACKAGE)-$(VERSION).tar.gz: dist
|
||||
|
||||
# Rule to build RPM distribution package
|
||||
rpm: $(PACKAGE)-$(VERSION).tar.gz
|
||||
rpm -ta --clean $(PACKAGE)-$(VERSION).tar.gz
|
437
cxmon/README
Normal file
437
cxmon/README
Normal file
@ -0,0 +1,437 @@
|
||||
|
||||
cxmon, Version 3.2
|
||||
A command-line file manipulation tool and disassembler
|
||||
|
||||
Copyright (C) 1997-2007 Christian Bauer, Marc Hellwig
|
||||
GNU binutils disassemblers Copyright (C) 1988, 89, 91, 93, 94, 95, 96, 97, 1998
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
cxmon is available under the terms of the GNU General Public License. See the
|
||||
file "COPYING" that is included in the distribution for details.
|
||||
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
cxmon is an interactive command-driven file manipulation tool that is
|
||||
inspired by the "Amiga Monitor" by Timo Rossi. It has commands and features
|
||||
similar to a machine code monitor/debugger, but it lacks any functions for
|
||||
running/tracing code. There are, however, built-in PowerPC, 680x0, 80x86,
|
||||
x86-64, 6502 and Z80 disassemblers and special support for disassembling
|
||||
MacOS code. By default, cxmon operates on a fixed-size (but adjustable)
|
||||
memory buffer with adresses starting at 0.
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
Please consult the file "INSTALL" for installation instructions.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
cxmon can be started from the Shell or from the Tracker (BeOS), but command
|
||||
line history doesn't work when started from the Tracker.
|
||||
|
||||
Options:
|
||||
-m enables symbolic MacOS A-Trap and low memory globals display in the
|
||||
680x0 disassembler
|
||||
-r makes cxmon operate in real (virtual) memory space instead of an
|
||||
allocated buffer
|
||||
|
||||
If no additional command line arguments are given, cxmon enters interactive
|
||||
mode. Otherwise, all remaining arguments are interpreted and executed as cxmon
|
||||
commands.
|
||||
|
||||
The default buffer size is 1MB.
|
||||
|
||||
The cxmon command prompt looks like this:
|
||||
|
||||
[00000000]->
|
||||
|
||||
The number in brackets is the value of "." (the "current address", see the
|
||||
section on expressions). You can get a short command overview by entering
|
||||
"h".
|
||||
|
||||
Commands that create a longer output can be interrupted with Ctrl-C.
|
||||
|
||||
To quit cxmon, enter the command "x".
|
||||
|
||||
|
||||
Constants, variables and expressions
|
||||
------------------------------------
|
||||
|
||||
The default number base is hexadecimal. Decimal numbers must be prefixed with
|
||||
"_". Hexadecimal numbers may also be prefixed with "$" for clarity. Numbers
|
||||
can also be entered as ASCII characters enclosed in single quotes (e.g. 'BAPP'
|
||||
is the same as $42415050). All numbers are 32-bit values (one word).
|
||||
|
||||
With the "set" command, variables can be defined that hold 32-bit integer
|
||||
values. A variable is referred to by its name. Variable names may be arbitrary
|
||||
combinations of digits and letters (they may also start with a digit) that
|
||||
are not also valid hexadecimal numbers. Names are case-sensitive.
|
||||
|
||||
cxmon accepts expressions in all places where you have to specify a number.
|
||||
The following operators are available and have the same meaning and
|
||||
precedence as in the C programming language:
|
||||
|
||||
~ complement
|
||||
+ unary plus
|
||||
- unary minus
|
||||
* multiplication
|
||||
/ integer division
|
||||
% modulo
|
||||
+ addition
|
||||
- subtraction
|
||||
<< shift left
|
||||
>> shift right
|
||||
& bitwise AND
|
||||
^ bitwise exclusive OR
|
||||
| bitwise inclusive OR
|
||||
|
||||
Parentheses may be used to change the evaluation order of sub-expressions.
|
||||
|
||||
There are two special symbols that can be used in expressions:
|
||||
|
||||
. represents the "current address" (the value of "." is also displayed in
|
||||
the command prompt). What exactly the current address is, depends on the
|
||||
command last executed. The display commands set "." to the address after
|
||||
the last address displayed, the "hunt" commands sets "." to the address
|
||||
of the first found occurence of the search string, etc.
|
||||
: is used by the "apply" ("y") command and holds the value of the byte/
|
||||
half-word/word at the current address.
|
||||
|
||||
The "modify" (":"), "fill" ("f") and "hunt" ("h") commands require you to
|
||||
specify a byte string. Byte strings consist of an arbitrary number of byte
|
||||
values and ASCII strings separated by commas. Examples:
|
||||
|
||||
"string"
|
||||
12,34,56,78,9a,bc,de,f0
|
||||
"this",0a,"is a string",0a,"with","newlines",_10
|
||||
|
||||
|
||||
The buffer
|
||||
----------
|
||||
|
||||
Those cxmon commands that operate on "memory" operate on a buffer allocated
|
||||
by cxmon whose size is adjustable with the "@" command. The default buffer
|
||||
size is 1MB. The buffer is an array of bytes where each byte has a 32-bit
|
||||
integer address. Addresses start at 0 and are taken modulo the buffer size
|
||||
(i.e. for the default 1MB buffer, addresses 0 and 100000 refer to the same
|
||||
byte).
|
||||
|
||||
The buffer is the working area of cxmon where you load files into, manipulate
|
||||
them, and write files back from. Arbitraty portions of the buffer may be used
|
||||
as scratch space.
|
||||
|
||||
|
||||
Commands
|
||||
--------
|
||||
|
||||
The following commands are available in cxmon ('[]' marks a parameter than
|
||||
can be left out):
|
||||
|
||||
|
||||
x Quit cxmon
|
||||
|
||||
quits cxmon and returns to the shell.
|
||||
|
||||
|
||||
h Show help text
|
||||
|
||||
displays a short overview of commands.
|
||||
|
||||
|
||||
?? Show list of commands
|
||||
|
||||
displays a short list of available commands.
|
||||
|
||||
|
||||
ver Show version
|
||||
|
||||
shows the version number of cxmon.
|
||||
|
||||
|
||||
? expression Calculate expression
|
||||
|
||||
displays the value of the given expression in hex, decimal, and ASCII
|
||||
characters. If the value is negative, it is displayed as a signed and unsigned
|
||||
number.
|
||||
|
||||
|
||||
@ [size] Reallocate buffer
|
||||
|
||||
changes the size of the buffer to the given number of bytes while preserving
|
||||
the contents of the buffer. If the "size" argument is omitted, the current
|
||||
buffer size is displayed.
|
||||
|
||||
|
||||
i [start [end]] ASCII memory dump
|
||||
|
||||
displays the buffer contents from address "start" to address "end" as ASCII
|
||||
characters. Entering "i" without arguments is equivalent to "i .". The value
|
||||
of "." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
b [start [end]] Binary memory dump
|
||||
|
||||
displays the buffer contents from address "start" to address "end" in a binary
|
||||
format. Entering "b" without arguments is equivalent to "b .". The value of
|
||||
"." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
m [start [end]] Hex/ASCII memory dump
|
||||
|
||||
displays the buffer contents from address "start" to address "end" as hex
|
||||
words and ASCII characters. Entering "m" without arguments is equivalent to
|
||||
"m .". The value of "." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
d [start [end]] Disassemble PowerPC code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d" without arguments is equivalent to "d .". The value of "." is
|
||||
set to the address after the last address displayed.
|
||||
|
||||
|
||||
d65 [start [end]] Disassemble 6502 code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d65" without arguments is equivalent to "d65 .". The value of
|
||||
"." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
d68 [start [end]] Disassemble 680x0 code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d68" without arguments is equivalent to "d68 .". The value of
|
||||
"." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
d80 [start [end]] Disassemble Z80 code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d80" without arguments is equivalent to "d80 .". The value of
|
||||
"." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
d86 [start [end]] Disassemble 80x86 (32-bit) code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d86" without arguments is equivalent to "d86 .". The value of
|
||||
"." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
d8086 [start [end]] Disassemble 80x86 (16-bit) code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d8086" without arguments is equivalent to "d8086 .". The value
|
||||
of "." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
d8664 [start [end]] Disassemble x86-64 code
|
||||
|
||||
disassembles the buffer contents from address "start" to address "end".
|
||||
Entering "d8086" without arguments is equivalent to "d8086 .". The value
|
||||
of "." is set to the address after the last address displayed.
|
||||
|
||||
|
||||
: start string Modify memory
|
||||
|
||||
puts the specified byte string at the address "start" into the buffer. The
|
||||
value of "." is set to the address after the last address modified.
|
||||
|
||||
|
||||
f start end string Fill memory
|
||||
|
||||
fill the buffer in the range from "start" to (and including) "end" with the
|
||||
given byte string.
|
||||
|
||||
|
||||
y[b|h|w] start end expr Apply expression to memory
|
||||
|
||||
works like the "fill" ("f") command, but it doesn't fill with a byte string
|
||||
but with the value of an expression that is re-evaluated for each buffer
|
||||
location to be filled. The command comes in three flavors: "y"/"yb" works on
|
||||
bytes (8-bit), "yh" on half-words (16-bit) and "yw" on words (32-bit). The
|
||||
value of "." is the current address to be modified, the value of ":" holds
|
||||
the contents of this address before modification.
|
||||
|
||||
Examples:
|
||||
yw 0 fff :<<8 shifts all words in the address range 0..fff to the left
|
||||
by 8 bits (you can use this to convert bitmap data from
|
||||
ARGB to RGBA format, for example)
|
||||
y 0 1234 ~: inverts all bytes in the address range 0..1234
|
||||
yh 2 ff 20000/. creates a table of the fractional parts of the reciprocals
|
||||
of 1..7f
|
||||
|
||||
|
||||
t start end dest Transfer memory
|
||||
|
||||
transfers the buffer contents from "start" to (and including) "end" to "dest".
|
||||
Source and destination may overlap.
|
||||
|
||||
|
||||
c start end dest Compare memory
|
||||
|
||||
compares the buffer contents in the range from "start" to (and including)
|
||||
"end" with the contents at "dest". The addresses of all different bytes and
|
||||
the total number of differences (decimal) are printed.
|
||||
|
||||
|
||||
h start end string Search for byte string
|
||||
|
||||
searches for the given byte string in the buffer starting at "start" up to
|
||||
(and including) "end". The addresses and the total number of occurrences are
|
||||
displayed. The value of "." is set to the address of the first occurrence.
|
||||
|
||||
|
||||
\ "command" Execute shell command
|
||||
|
||||
executes the given shell command which must be enclosed in quotes.
|
||||
|
||||
|
||||
ls [args] List directory contents
|
||||
|
||||
works as the shell command "ls".
|
||||
|
||||
|
||||
rm [args] Remove file(s)
|
||||
|
||||
works as the shell command "rm".
|
||||
|
||||
|
||||
cp [args] Copy file(s)
|
||||
|
||||
works as the shell command "cp".
|
||||
|
||||
|
||||
mv [args] Move file(s)
|
||||
|
||||
works as the shell command "mv".
|
||||
|
||||
|
||||
cd directory Change current directory
|
||||
|
||||
works as the shell command "cd". The name of the directory doesn't have to be
|
||||
enclosed in quotes.
|
||||
|
||||
|
||||
o ["file"] Redirect output
|
||||
|
||||
When a file name is specified, all following output is redirected to this
|
||||
file. The file name must be enclosed in quotation marks even if it contains
|
||||
no spaces. Entering "o" without parameters closes the file and directs the
|
||||
output into the terminal window again.
|
||||
|
||||
|
||||
[ start "file" Load data from file
|
||||
|
||||
loads the contents of the specified file into the buffer starting from address
|
||||
"start". The file name must be enclosed in quotation marks even if it contains
|
||||
no spaces. The value of "." is set to the address after the last address
|
||||
affected by the load.
|
||||
|
||||
|
||||
] start size "file" Save data to file
|
||||
|
||||
writes "size" number of bytes of the buffer from "start" to the specified file.
|
||||
The file name must be enclosed in quotation marks even if it contains no spaces.
|
||||
|
||||
|
||||
set [var[=value]] Set/clear/show variables
|
||||
|
||||
If no arguments are given, all currently defined variables are displayed.
|
||||
Otherwise, the value of "var" is set to the specified value. If "=value"
|
||||
is omitted, the variable "var" is cleared.
|
||||
|
||||
|
||||
cv Clear all variables
|
||||
|
||||
clears all currently defined variables.
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Here are some simple examples for what is possible with cxmon.
|
||||
|
||||
Join "file1" and "file2" to "file3":
|
||||
|
||||
[ 0 "file1"
|
||||
[ . "file2"
|
||||
] 0 . "file3"
|
||||
|
||||
Remove the first 24 bytes (e.g. an unneeded header) of a file:
|
||||
|
||||
[ 0 "file"
|
||||
] 18 .-18 "file"
|
||||
|
||||
Load the cxmon executable and search for PowerPC "nop" commands:
|
||||
|
||||
[ 0 "cxmon"
|
||||
h 0 . 60,00,00,00
|
||||
|
||||
Create a modified version of cxmon so that the prompt has " $" instead of
|
||||
"->":
|
||||
|
||||
[ 0 "cxmon"
|
||||
set size=.
|
||||
h 0 . "->"
|
||||
: . " $"
|
||||
] 0 size "cxmon1"
|
||||
|
||||
Convert a binary file which contains 16-bit numbers in little-endian format
|
||||
to big-endian format (or vice-versa):
|
||||
|
||||
[ 0 "file"
|
||||
yh 0 .-1 :>>8|:<<8
|
||||
] 0 . "file"
|
||||
|
||||
Load a BeBox boot ROM image and start disassembling the system reset handler:
|
||||
|
||||
[ 0 "bootnub.image"
|
||||
d 100
|
||||
|
||||
|
||||
Using cxmon in your own programs
|
||||
--------------------------------
|
||||
|
||||
cxmon provides a simple interface for integration in other programs. It can,
|
||||
for example, be used as a monitor/debugger for an emulator (it is used in
|
||||
Basilisk II in this way).
|
||||
|
||||
Here's how to do it (all functions are defined in the mon.h header file):
|
||||
|
||||
1. Link all the cxmon object files, except main.o, to your program.
|
||||
2. In your program, call mon_init() before using any other cxmon functions.
|
||||
3. After calling mon_init(), set the mon_read_byte and mon_write_byte
|
||||
function pointers to the routines used for accessing memory.
|
||||
4. You can use mon_add_command() to add new commands to cxmon by specifying
|
||||
the command name, function and help text. From within your command
|
||||
function, you can use mon_get_token() and mon_expression() to parse the
|
||||
arguments and the mon_read/write_*() functions to access memory.
|
||||
5. To enter cxmon, call the mon() function like this:
|
||||
|
||||
char *args[3] = {"mon", "-r", NULL};
|
||||
mon(2, args);
|
||||
|
||||
6. If you're done with cxmon, call mon_exit().
|
||||
|
||||
|
||||
History
|
||||
-------
|
||||
|
||||
Please consult the file "ChangeLog" for the release history.
|
||||
|
||||
|
||||
Christian Bauer
|
||||
www.cebix.net
|
||||
|
||||
Marc Hellwig
|
||||
<Marc.Hellwig@uni-mainz.de>
|
2
cxmon/bootstrap
Executable file
2
cxmon/bootstrap
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
autoreconf --install
|
47
cxmon/configure.ac
Normal file
47
cxmon/configure.ac
Normal file
@ -0,0 +1,47 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
dnl Written by Christian Bauer
|
||||
|
||||
AC_PREREQ(2.69)
|
||||
AC_INIT([cxmon], [3.2], [cb@cebix.net], [cxmon])
|
||||
AC_CONFIG_SRCDIR([src/mon.cpp])
|
||||
AM_INIT_AUTOMAKE([1.12 foreign])
|
||||
|
||||
AM_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CPP
|
||||
AC_PROG_CXX
|
||||
AC_PROG_CXXCPP
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_RANLIB
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS(unistd.h readline.h history.h readline/readline.h readline/history.h)
|
||||
|
||||
dnl Checks for typedefs, structures, and compiler characteristics.
|
||||
AC_CHECK_SIZEOF(short, 2)
|
||||
AC_CHECK_SIZEOF(int, 4)
|
||||
AC_CHECK_SIZEOF(long, 4)
|
||||
AC_CHECK_SIZEOF(long long, 8)
|
||||
AC_CHECK_SIZEOF(void *, 4)
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_SEARCH_LIBS([tgetent], [ncurses termcap termlib terminfo Hcurses curses], [], [
|
||||
AC_MSG_ERROR([unable to find the tgetent() function])
|
||||
])
|
||||
AC_SEARCH_LIBS([readline], [readline], [], [
|
||||
AC_MSG_ERROR([unable to find the readline() function])
|
||||
])
|
||||
|
||||
dnl Generate Makefile.
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
cxmon.spec
|
||||
src/Makefile
|
||||
src/disass/Makefile
|
||||
])
|
||||
|
||||
dnl Print summary.
|
||||
echo "Configuration done. Now type \"make\"."
|
56
cxmon/cxmon.1
Normal file
56
cxmon/cxmon.1
Normal file
@ -0,0 +1,56 @@
|
||||
.TH cxmon 1 "January, 2007"
|
||||
.SH NAME
|
||||
cxmon \- a command-line file manipulation tool and disassembler
|
||||
.SH SYNOPSIS
|
||||
.B cxmon
|
||||
[\-m] [\-r]
|
||||
.RI [ commands\&... ]
|
||||
.SH DESCRIPTION
|
||||
.B cxmon
|
||||
is an interactive command-driven file manipulation tool that is inspired by
|
||||
the "Amiga Monitor" by Timo Rossi. It has commands and features similar to a
|
||||
machine code monitor/debugger, but it lacks any functions for running/tracing
|
||||
code. There are, however, built-in PowerPC, 680x0, 80x86, 6502 and Z80
|
||||
disassemblers and special support for disassembling MacOS code. By default,
|
||||
cxmon operates on a fixed-size (but adjustable) memory buffer with adresses
|
||||
starting at 0.
|
||||
.PP
|
||||
Type "h" to get a list of supported commands.
|
||||
.PP
|
||||
For more information, see the included "README" file.
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-m
|
||||
enables symbolic MacOS A-Trap and low memory globals display in the 680x0
|
||||
disassembler
|
||||
.TP
|
||||
.B \-r
|
||||
makes cxmon operate in real (virtual) memory space instead of an allocated
|
||||
buffer
|
||||
.PP
|
||||
If no additional command line arguments are given, cxmon enters interactive
|
||||
mode. Otherwise, all remaining arguments are interpreted and executed as cxmon
|
||||
commands.
|
||||
.SH AUTHORS
|
||||
Christian Bauer <www.cebix.net>
|
||||
.br
|
||||
Marc Hellwig <Marc.Hellwig@uni-mainz.de>
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 1997-2007 Christian Bauer, Marc Hellwig
|
||||
.br
|
||||
GNU binutils disassemblers Copyright \(co 1988, 89, 91, 93, 94, 95, 96, 97, 1998
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
42
cxmon/cxmon.spec.in
Normal file
42
cxmon/cxmon.spec.in
Normal file
@ -0,0 +1,42 @@
|
||||
%define name @PACKAGE@
|
||||
%define version @VERSION@
|
||||
%define release 1
|
||||
|
||||
Summary: Command-line file manipulation tool and disassembler
|
||||
Name: %{name}
|
||||
Version: %{version}
|
||||
Release: %{release}
|
||||
License: GPL
|
||||
Group: Utilities/File
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
URL: http://cxmon.cebix.net/
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
Prefix: %{_prefix}
|
||||
|
||||
%description
|
||||
cxmon is an interactive command-driven file manipulation tool that is
|
||||
inspired by the "Amiga Monitor" by Timo Rossi. It has commands and features
|
||||
similar to a machine code monitor/debugger, but it lacks any functions for
|
||||
running/tracing code. There are, however, built-in PowerPC, 680x0, 80x86,
|
||||
x86-64, 6502 and Z80 disassemblers and special support for disassembling
|
||||
MacOS code.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%configure
|
||||
make
|
||||
|
||||
%install
|
||||
rm -rf ${RPM_BUILD_ROOT}
|
||||
%makeinstall
|
||||
|
||||
%clean
|
||||
rm -rf ${RPM_BUILD_ROOT}
|
||||
|
||||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc AUTHORS ChangeLog COPYING README
|
||||
%{_bindir}/*
|
||||
%{_mandir}/man1/*
|
10
cxmon/src/Makefile.am
Normal file
10
cxmon/src/Makefile.am
Normal file
@ -0,0 +1,10 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = disass
|
||||
|
||||
bin_PROGRAMS = cxmon
|
||||
cxmon_SOURCES = main.cpp mon.cpp mon.h mon_6502.cpp mon_z80.cpp mon_atraps.h \
|
||||
mon_cmd.cpp mon_cmd.h mon_disass.cpp mon_disass.h mon_lowmem.cpp mon_lowmem.h \
|
||||
mon_ppc.cpp sysdeps.h
|
||||
|
||||
cxmon_LDADD = disass/libdisass.a
|
8
cxmon/src/disass/Makefile.am
Normal file
8
cxmon/src/disass/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
noinst_LIBRARIES = libdisass.a
|
||||
libdisass_a_SOURCES = ansidecl.h bfd.h dis-asm.h floatformat.c floatformat.h \
|
||||
i386-dis.c m68k-dis.c m68k-opc.c m68k.h opintl.h
|
||||
|
||||
# Extra includes, for <sysdeps.h>
|
||||
CPPFLAGS = -I$(srcdir)/..
|
295
cxmon/src/disass/ansidecl.h
Normal file
295
cxmon/src/disass/ansidecl.h
Normal file
@ -0,0 +1,295 @@
|
||||
/* ANSI and traditional C compatability macros
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
/* ANSI and traditional C compatibility macros
|
||||
|
||||
ANSI C is assumed if __STDC__ is #defined.
|
||||
|
||||
Macro ANSI C definition Traditional C definition
|
||||
----- ---- - ---------- ----------- - ----------
|
||||
ANSI_PROTOTYPES 1 not defined
|
||||
PTR `void *' `char *'
|
||||
PTRCONST `void *const' `char *'
|
||||
LONG_DOUBLE `long double' `double'
|
||||
const not defined `'
|
||||
volatile not defined `'
|
||||
signed not defined `'
|
||||
VA_START(ap, var) va_start(ap, var) va_start(ap)
|
||||
|
||||
Note that it is safe to write "void foo();" indicating a function
|
||||
with no return value, in all K+R compilers we have been able to test.
|
||||
|
||||
For declaring functions with prototypes, we also provide these:
|
||||
|
||||
PARAMS ((prototype))
|
||||
-- for functions which take a fixed number of arguments. Use this
|
||||
when declaring the function. When defining the function, write a
|
||||
K+R style argument list. For example:
|
||||
|
||||
char *strcpy PARAMS ((char *dest, char *source));
|
||||
...
|
||||
char *
|
||||
strcpy (dest, source)
|
||||
char *dest;
|
||||
char *source;
|
||||
{ ... }
|
||||
|
||||
|
||||
VPARAMS ((prototype, ...))
|
||||
-- for functions which take a variable number of arguments. Use
|
||||
PARAMS to declare the function, VPARAMS to define it. For example:
|
||||
|
||||
int printf PARAMS ((const char *format, ...));
|
||||
...
|
||||
int
|
||||
printf VPARAMS ((const char *format, ...))
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
For writing functions which take variable numbers of arguments, we
|
||||
also provide the VA_OPEN, VA_CLOSE, and VA_FIXEDARG macros. These
|
||||
hide the differences between K+R <varargs.h> and C89 <stdarg.h> more
|
||||
thoroughly than the simple VA_START() macro mentioned above.
|
||||
|
||||
VA_OPEN and VA_CLOSE are used *instead of* va_start and va_end.
|
||||
Immediately after VA_OPEN, put a sequence of VA_FIXEDARG calls
|
||||
corresponding to the list of fixed arguments. Then use va_arg
|
||||
normally to get the variable arguments, or pass your va_list object
|
||||
around. You do not declare the va_list yourself; VA_OPEN does it
|
||||
for you.
|
||||
|
||||
Here is a complete example:
|
||||
|
||||
int
|
||||
printf VPARAMS ((const char *format, ...))
|
||||
{
|
||||
int result;
|
||||
|
||||
VA_OPEN (ap, format);
|
||||
VA_FIXEDARG (ap, const char *, format);
|
||||
|
||||
result = vfprintf (stdout, format, ap);
|
||||
VA_CLOSE (ap);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
You can declare variables either before or after the VA_OPEN,
|
||||
VA_FIXEDARG sequence. Also, VA_OPEN and VA_CLOSE are the beginning
|
||||
and end of a block. They must appear at the same nesting level,
|
||||
and any variables declared after VA_OPEN go out of scope at
|
||||
VA_CLOSE. Unfortunately, with a K+R compiler, that includes the
|
||||
argument list. You can have multiple instances of VA_OPEN/VA_CLOSE
|
||||
pairs in a single function in case you need to traverse the
|
||||
argument list more than once.
|
||||
|
||||
For ease of writing code which uses GCC extensions but needs to be
|
||||
portable to other compilers, we provide the GCC_VERSION macro that
|
||||
simplifies testing __GNUC__ and __GNUC_MINOR__ together, and various
|
||||
wrappers around __attribute__. Also, __extension__ will be #defined
|
||||
to nothing if it doesn't work. See below.
|
||||
|
||||
This header also defines a lot of obsolete macros:
|
||||
CONST, VOLATILE, SIGNED, PROTO, EXFUN, DEFUN, DEFUN_VOID,
|
||||
AND, DOTS, NOARGS. Don't use them. */
|
||||
|
||||
#ifndef _ANSIDECL_H
|
||||
#define _ANSIDECL_H 1
|
||||
|
||||
/* Every source file includes this file,
|
||||
so they will all get the switch for lint. */
|
||||
/* LINTLIBRARY */
|
||||
|
||||
/* Using MACRO(x,y) in cpp #if conditionals does not work with some
|
||||
older preprocessors. Thus we can't define something like this:
|
||||
|
||||
#define HAVE_GCC_VERSION(MAJOR, MINOR) \
|
||||
(__GNUC__ > (MAJOR) || (__GNUC__ == (MAJOR) && __GNUC_MINOR__ >= (MINOR)))
|
||||
|
||||
and then test "#if HAVE_GCC_VERSION(2,7)".
|
||||
|
||||
So instead we use the macro below and test it against specific values. */
|
||||
|
||||
/* This macro simplifies testing whether we are using gcc, and if it
|
||||
is of a particular minimum version. (Both major & minor numbers are
|
||||
significant.) This macro will evaluate to 0 if we are not using
|
||||
gcc at all. */
|
||||
#ifndef GCC_VERSION
|
||||
#define GCC_VERSION (__GNUC__ * 1000 + __GNUC_MINOR__)
|
||||
#endif /* GCC_VERSION */
|
||||
|
||||
#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(_WIN32)
|
||||
/* All known AIX compilers implement these things (but don't always
|
||||
define __STDC__). The RISC/OS MIPS compiler defines these things
|
||||
in SVR4 mode, but does not define __STDC__. */
|
||||
|
||||
#define ANSI_PROTOTYPES 1
|
||||
#define PTR void *
|
||||
#define PTRCONST void *const
|
||||
#define LONG_DOUBLE long double
|
||||
|
||||
#define PARAMS(ARGS) ARGS
|
||||
#define VPARAMS(ARGS) ARGS
|
||||
#define VA_START(VA_LIST, VAR) va_start(VA_LIST, VAR)
|
||||
|
||||
/* variadic function helper macros */
|
||||
/* "struct Qdmy" swallows the semicolon after VA_OPEN/VA_FIXEDARG's
|
||||
use without inhibiting further decls and without declaring an
|
||||
actual variable. */
|
||||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP, VAR); { struct Qdmy
|
||||
#define VA_CLOSE(AP) } va_end(AP); }
|
||||
#define VA_FIXEDARG(AP, T, N) struct Qdmy
|
||||
|
||||
#undef const
|
||||
#undef volatile
|
||||
#undef signed
|
||||
|
||||
/* inline requires special treatment; it's in C99, and GCC >=2.7 supports
|
||||
it too, but it's not in C89. */
|
||||
#undef inline
|
||||
#if __STDC_VERSION__ > 199901L
|
||||
/* it's a keyword */
|
||||
#else
|
||||
# if GCC_VERSION >= 2007
|
||||
# define inline __inline__ /* __inline__ prevents -pedantic warnings */
|
||||
# else
|
||||
# define inline /* nothing */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* These are obsolete. Do not use. */
|
||||
#ifndef IN_GCC
|
||||
#define CONST const
|
||||
#define VOLATILE volatile
|
||||
#define SIGNED signed
|
||||
|
||||
#define PROTO(type, name, arglist) type name arglist
|
||||
#define EXFUN(name, proto) name proto
|
||||
#define DEFUN(name, arglist, args) name(args)
|
||||
#define DEFUN_VOID(name) name(void)
|
||||
#define AND ,
|
||||
#define DOTS , ...
|
||||
#define NOARGS void
|
||||
#endif /* ! IN_GCC */
|
||||
|
||||
#else /* Not ANSI C. */
|
||||
|
||||
#undef ANSI_PROTOTYPES
|
||||
#define PTR char *
|
||||
#define PTRCONST PTR
|
||||
#define LONG_DOUBLE double
|
||||
|
||||
#define PARAMS(args) ()
|
||||
#define VPARAMS(args) (va_alist) va_dcl
|
||||
#define VA_START(va_list, var) va_start(va_list)
|
||||
|
||||
#define VA_OPEN(AP, VAR) { va_list AP; va_start(AP); { struct Qdmy
|
||||
#define VA_CLOSE(AP) } va_end(AP); }
|
||||
#define VA_FIXEDARG(AP, TYPE, NAME) TYPE NAME = va_arg(AP, TYPE)
|
||||
|
||||
/* some systems define these in header files for non-ansi mode */
|
||||
#undef const
|
||||
#undef volatile
|
||||
#undef signed
|
||||
#undef inline
|
||||
#define const
|
||||
#define volatile
|
||||
#define signed
|
||||
#define inline
|
||||
|
||||
#ifndef IN_GCC
|
||||
#define CONST
|
||||
#define VOLATILE
|
||||
#define SIGNED
|
||||
|
||||
#define PROTO(type, name, arglist) type name ()
|
||||
#define EXFUN(name, proto) name()
|
||||
#define DEFUN(name, arglist, args) name arglist args;
|
||||
#define DEFUN_VOID(name) name()
|
||||
#define AND ;
|
||||
#define DOTS
|
||||
#define NOARGS
|
||||
#endif /* ! IN_GCC */
|
||||
|
||||
#endif /* ANSI C. */
|
||||
|
||||
/* Define macros for some gcc attributes. This permits us to use the
|
||||
macros freely, and know that they will come into play for the
|
||||
version of gcc in which they are supported. */
|
||||
|
||||
#if (GCC_VERSION < 2007)
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
/* Attribute __malloc__ on functions was valid as of gcc 2.96. */
|
||||
#ifndef ATTRIBUTE_MALLOC
|
||||
# if (GCC_VERSION >= 2096)
|
||||
# define ATTRIBUTE_MALLOC __attribute__ ((__malloc__))
|
||||
# else
|
||||
# define ATTRIBUTE_MALLOC
|
||||
# endif /* GNUC >= 2.96 */
|
||||
#endif /* ATTRIBUTE_MALLOC */
|
||||
|
||||
/* Attributes on labels were valid as of gcc 2.93. */
|
||||
#ifndef ATTRIBUTE_UNUSED_LABEL
|
||||
# if (GCC_VERSION >= 2093)
|
||||
# define ATTRIBUTE_UNUSED_LABEL ATTRIBUTE_UNUSED
|
||||
# else
|
||||
# define ATTRIBUTE_UNUSED_LABEL
|
||||
# endif /* GNUC >= 2.93 */
|
||||
#endif /* ATTRIBUTE_UNUSED_LABEL */
|
||||
|
||||
#ifndef ATTRIBUTE_UNUSED
|
||||
#define ATTRIBUTE_UNUSED __attribute__ ((__unused__))
|
||||
#endif /* ATTRIBUTE_UNUSED */
|
||||
|
||||
#ifndef ATTRIBUTE_NORETURN
|
||||
#define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
||||
#endif /* ATTRIBUTE_NORETURN */
|
||||
|
||||
#ifndef ATTRIBUTE_PRINTF
|
||||
#define ATTRIBUTE_PRINTF(m, n) __attribute__ ((__format__ (__printf__, m, n)))
|
||||
#define ATTRIBUTE_PRINTF_1 ATTRIBUTE_PRINTF(1, 2)
|
||||
#define ATTRIBUTE_PRINTF_2 ATTRIBUTE_PRINTF(2, 3)
|
||||
#define ATTRIBUTE_PRINTF_3 ATTRIBUTE_PRINTF(3, 4)
|
||||
#define ATTRIBUTE_PRINTF_4 ATTRIBUTE_PRINTF(4, 5)
|
||||
#define ATTRIBUTE_PRINTF_5 ATTRIBUTE_PRINTF(5, 6)
|
||||
#endif /* ATTRIBUTE_PRINTF */
|
||||
|
||||
/* We use __extension__ in some places to suppress -pedantic warnings
|
||||
about GCC extensions. This feature didn't work properly before
|
||||
gcc 2.8. */
|
||||
#if GCC_VERSION < 2008
|
||||
#define __extension__
|
||||
#endif
|
||||
|
||||
/* Bootstrap support: Adjust certain macros defined by Autoconf,
|
||||
which are only valid for the stage1 compiler. If we detect
|
||||
a modern version of GCC, we are probably in stage2 or beyond,
|
||||
so unconditionally reset the values. Note that const, inline,
|
||||
etc. have been dealt with above. */
|
||||
#if (GCC_VERSION >= 2007)
|
||||
# ifndef HAVE_LONG_DOUBLE
|
||||
# define HAVE_LONG_DOUBLE 1
|
||||
# endif
|
||||
#endif /* GCC >= 2.7 */
|
||||
|
||||
#endif /* ansidecl.h */
|
66
cxmon/src/disass/bfd.h
Normal file
66
cxmon/src/disass/bfd.h
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* bfd.h - Dummy bfd library header file
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
#include "ansidecl.h"
|
||||
|
||||
enum bfd_flavour {
|
||||
bfd_target_unknown_flavour
|
||||
};
|
||||
|
||||
enum bfd_endian {
|
||||
BFD_ENDIAN_BIG,
|
||||
BFD_ENDIAN_LITTLE,
|
||||
BFD_ENDIAN_UNKNOWN
|
||||
};
|
||||
|
||||
enum bfd_architecture {
|
||||
bfd_arch_unknown,
|
||||
bfd_arch_m68k,
|
||||
#define bfd_mach_m68000 1
|
||||
#define bfd_mach_m68008 2
|
||||
#define bfd_mach_m68010 3
|
||||
#define bfd_mach_m68020 4
|
||||
#define bfd_mach_m68030 5
|
||||
#define bfd_mach_m68040 6
|
||||
#define bfd_mach_m68060 7
|
||||
bfd_arch_i386
|
||||
#define bfd_mach_i386_i386 0
|
||||
#define bfd_mach_i386_i8086 1
|
||||
#define bfd_mach_i386_i386_intel_syntax 2
|
||||
#define bfd_mach_x86_64 3
|
||||
#define bfd_mach_x86_64_intel_syntax 4
|
||||
};
|
||||
|
||||
typedef struct symbol_cache_entry {
|
||||
CONST char *name;
|
||||
} asymbol;
|
||||
|
||||
typedef uint64 bfd_vma;
|
||||
typedef int64 bfd_signed_vma;
|
||||
typedef unsigned char bfd_byte;
|
||||
|
||||
typedef struct _bfd bfd;
|
||||
struct _bfd;
|
||||
|
||||
#if SIZEOF_LONG == 8
|
||||
#define BFD_HOST_64BIT_LONG 1
|
||||
#endif
|
||||
|
||||
// 64-bit vma
|
||||
#define BFD64
|
||||
|
||||
#ifndef fprintf_vma
|
||||
#if BFD_HOST_64BIT_LONG
|
||||
#define sprintf_vma(s,x) sprintf (s, "%016lx", x)
|
||||
#define fprintf_vma(f,x) fprintf (f, "%016lx", x)
|
||||
#else
|
||||
#define _bfd_int64_low(x) ((unsigned long) (((x) & 0xffffffff)))
|
||||
#define _bfd_int64_high(x) ((unsigned long) (((x) >> 32) & 0xffffffff))
|
||||
#define fprintf_vma(s,x) \
|
||||
fprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
|
||||
#define sprintf_vma(s,x) \
|
||||
sprintf ((s), "%08lx%08lx", _bfd_int64_high (x), _bfd_int64_low (x))
|
||||
#endif
|
||||
#endif
|
315
cxmon/src/disass/dis-asm.h
Normal file
315
cxmon/src/disass/dis-asm.h
Normal file
@ -0,0 +1,315 @@
|
||||
/* Interface between the opcode library and its callers.
|
||||
|
||||
Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA.
|
||||
|
||||
Written by Cygnus Support, 1993.
|
||||
|
||||
The opcode library (libopcodes.a) provides instruction decoders for
|
||||
a large variety of instruction sets, callable with an identical
|
||||
interface, for making instruction-processing programs more independent
|
||||
of the instruction set being processed. */
|
||||
|
||||
#ifndef DIS_ASM_H
|
||||
#define DIS_ASM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include "bfd.h"
|
||||
|
||||
typedef int (*fprintf_ftype) PARAMS((PTR, const char*, ...));
|
||||
|
||||
enum dis_insn_type {
|
||||
dis_noninsn, /* Not a valid instruction */
|
||||
dis_nonbranch, /* Not a branch instruction */
|
||||
dis_branch, /* Unconditional branch */
|
||||
dis_condbranch, /* Conditional branch */
|
||||
dis_jsr, /* Jump to subroutine */
|
||||
dis_condjsr, /* Conditional jump to subroutine */
|
||||
dis_dref, /* Data reference instruction */
|
||||
dis_dref2 /* Two data references in instruction */
|
||||
};
|
||||
|
||||
/* This struct is passed into the instruction decoding routine,
|
||||
and is passed back out into each callback. The various fields are used
|
||||
for conveying information from your main routine into your callbacks,
|
||||
for passing information into the instruction decoders (such as the
|
||||
addresses of the callback functions), or for passing information
|
||||
back from the instruction decoders to their callers.
|
||||
|
||||
It must be initialized before it is first passed; this can be done
|
||||
by hand, or using one of the initialization macros below. */
|
||||
|
||||
typedef struct disassemble_info {
|
||||
fprintf_ftype fprintf_func;
|
||||
PTR stream;
|
||||
PTR application_data;
|
||||
|
||||
/* Target description. We could replace this with a pointer to the bfd,
|
||||
but that would require one. There currently isn't any such requirement
|
||||
so to avoid introducing one we record these explicitly. */
|
||||
/* The bfd_flavour. This can be bfd_target_unknown_flavour. */
|
||||
enum bfd_flavour flavour;
|
||||
/* The bfd_arch value. */
|
||||
enum bfd_architecture arch;
|
||||
/* The bfd_mach value. */
|
||||
unsigned long mach;
|
||||
/* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */
|
||||
enum bfd_endian endian;
|
||||
/* An arch/mach-specific bitmask of selected instruction subsets, mainly
|
||||
for processors with run-time-switchable instruction sets. The default,
|
||||
zero, means that there is no constraint. CGEN-based opcodes ports
|
||||
may use ISA_foo masks. */
|
||||
unsigned long insn_sets;
|
||||
|
||||
/* An array of pointers to symbols either at the location being disassembled
|
||||
or at the start of the function being disassembled. The array is sorted
|
||||
so that the first symbol is intended to be the one used. The others are
|
||||
present for any misc. purposes. This is not set reliably, but if it is
|
||||
not NULL, it is correct. */
|
||||
asymbol **symbols;
|
||||
/* Number of symbols in array. */
|
||||
int num_symbols;
|
||||
|
||||
/* For use by the disassembler.
|
||||
The top 16 bits are reserved for public use (and are documented here).
|
||||
The bottom 16 bits are for the internal use of the disassembler. */
|
||||
unsigned long flags;
|
||||
#define INSN_HAS_RELOC 0x80000000
|
||||
PTR private_data;
|
||||
|
||||
/* Function used to get bytes to disassemble. MEMADDR is the
|
||||
address of the stuff to be disassembled, MYADDR is the address to
|
||||
put the bytes in, and LENGTH is the number of bytes to read.
|
||||
INFO is a pointer to this struct.
|
||||
Returns an errno value or 0 for success. */
|
||||
int (*read_memory_func)
|
||||
PARAMS ((bfd_vma memaddr, bfd_byte *myaddr, unsigned int length,
|
||||
struct disassemble_info *info));
|
||||
|
||||
/* Function which should be called if we get an error that we can't
|
||||
recover from. STATUS is the errno value from read_memory_func and
|
||||
MEMADDR is the address that we were trying to read. INFO is a
|
||||
pointer to this struct. */
|
||||
void (*memory_error_func)
|
||||
PARAMS ((int status, bfd_vma memaddr, struct disassemble_info *info));
|
||||
|
||||
/* Function called to print ADDR. */
|
||||
void (*print_address_func)
|
||||
PARAMS ((bfd_vma addr, struct disassemble_info *info));
|
||||
|
||||
/* Function called to determine if there is a symbol at the given ADDR.
|
||||
If there is, the function returns 1, otherwise it returns 0.
|
||||
This is used by ports which support an overlay manager where
|
||||
the overlay number is held in the top part of an address. In
|
||||
some circumstances we want to include the overlay number in the
|
||||
address, (normally because there is a symbol associated with
|
||||
that address), but sometimes we want to mask out the overlay bits. */
|
||||
int (* symbol_at_address_func)
|
||||
PARAMS ((bfd_vma addr, struct disassemble_info * info));
|
||||
|
||||
/* These are for buffer_read_memory. */
|
||||
bfd_byte *buffer;
|
||||
bfd_vma buffer_vma;
|
||||
unsigned int buffer_length;
|
||||
|
||||
/* This variable may be set by the instruction decoder. It suggests
|
||||
the number of bytes objdump should display on a single line. If
|
||||
the instruction decoder sets this, it should always set it to
|
||||
the same value in order to get reasonable looking output. */
|
||||
int bytes_per_line;
|
||||
|
||||
/* the next two variables control the way objdump displays the raw data */
|
||||
/* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */
|
||||
/* output will look like this:
|
||||
00: 00000000 00000000
|
||||
with the chunks displayed according to "display_endian". */
|
||||
int bytes_per_chunk;
|
||||
enum bfd_endian display_endian;
|
||||
|
||||
/* Number of octets per incremented target address
|
||||
Normally one, but some DSPs have byte sizes of 16 or 32 bits. */
|
||||
unsigned int octets_per_byte;
|
||||
|
||||
/* Results from instruction decoders. Not all decoders yet support
|
||||
this information. This info is set each time an instruction is
|
||||
decoded, and is only valid for the last such instruction.
|
||||
|
||||
To determine whether this decoder supports this information, set
|
||||
insn_info_valid to 0, decode an instruction, then check it. */
|
||||
|
||||
char insn_info_valid; /* Branch info has been set. */
|
||||
char branch_delay_insns; /* How many sequential insn's will run before
|
||||
a branch takes effect. (0 = normal) */
|
||||
char data_size; /* Size of data reference in insn, in bytes */
|
||||
enum dis_insn_type insn_type; /* Type of instruction */
|
||||
bfd_vma target; /* Target address of branch or dref, if known;
|
||||
zero if unknown. */
|
||||
bfd_vma target2; /* Second target address for dref2 */
|
||||
|
||||
/* Command line options specific to the target disassembler. */
|
||||
char * disassembler_options;
|
||||
|
||||
} disassemble_info;
|
||||
|
||||
|
||||
/* Standard disassemblers. Disassemble one instruction at the given
|
||||
target address. Return number of octets processed. */
|
||||
typedef int (*disassembler_ftype)
|
||||
PARAMS((bfd_vma, disassemble_info *));
|
||||
|
||||
extern int print_insn_big_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_mips PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i386 PARAMS ((bfd_vma, disassemble_info *));
|
||||
extern int print_insn_i386_att PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i386_intel PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_ia64 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i370 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m68hc11 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m68hc12 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m68k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_z8001 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_z8002 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300h PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8300s PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_h8500 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_alpha PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_arm PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_arm PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sparc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_a29k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_avr PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_d10v PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_d30v PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_dlx PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_fr30 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_hppa PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i860 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_i960 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m32r PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_m88k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_mcore PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_mmix PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_mn10200 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_mn10300 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_ns32k PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_openrisc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_or32 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_or32 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_pdp11 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_pj PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_big_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_little_powerpc PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_rs6000 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_s390 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sh PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_tic30 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_tic54x PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_tic80 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_v850 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_vax PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_w65 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_xstormy16 PARAMS ((bfd_vma, disassemble_info*));
|
||||
extern int print_insn_sh64 PARAMS ((bfd_vma, disassemble_info *));
|
||||
extern int print_insn_sh64x_media PARAMS ((bfd_vma, disassemble_info *));
|
||||
extern int print_insn_frv PARAMS ((bfd_vma, disassemble_info *));
|
||||
|
||||
extern disassembler_ftype arc_get_disassembler PARAMS ((void *));
|
||||
extern disassembler_ftype cris_get_disassembler PARAMS ((bfd *));
|
||||
|
||||
extern void print_arm_disassembler_options PARAMS ((FILE *));
|
||||
extern void parse_arm_disassembler_option PARAMS ((char *));
|
||||
extern int get_arm_regname_num_options PARAMS ((void));
|
||||
extern int set_arm_regname_option PARAMS ((int));
|
||||
extern int get_arm_regnames PARAMS ((int, const char **, const char **, const char ***));
|
||||
|
||||
/* Fetch the disassembler for a given BFD, if that support is available. */
|
||||
extern disassembler_ftype disassembler PARAMS ((bfd *));
|
||||
|
||||
/* Document any target specific options available from the disassembler. */
|
||||
extern void disassembler_usage PARAMS ((FILE *));
|
||||
|
||||
|
||||
/* This block of definitions is for particular callers who read instructions
|
||||
into a buffer before calling the instruction decoder. */
|
||||
|
||||
/* Here is a function which callers may wish to use for read_memory_func.
|
||||
It gets bytes from a buffer. */
|
||||
extern int buffer_read_memory
|
||||
PARAMS ((bfd_vma, bfd_byte *, unsigned int, struct disassemble_info *));
|
||||
|
||||
/* This function goes with buffer_read_memory.
|
||||
It prints a message using info->fprintf_func and info->stream. */
|
||||
extern void perror_memory PARAMS ((int, bfd_vma, struct disassemble_info *));
|
||||
|
||||
|
||||
/* Just print the address in hex. This is included for completeness even
|
||||
though both GDB and objdump provide their own (to print symbolic
|
||||
addresses). */
|
||||
extern void generic_print_address
|
||||
PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
/* Always true. */
|
||||
extern int generic_symbol_at_address
|
||||
PARAMS ((bfd_vma, struct disassemble_info *));
|
||||
|
||||
/* Macro to initialize a disassemble_info struct. This should be called
|
||||
by all applications creating such a struct. */
|
||||
#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \
|
||||
(INFO).flavour = bfd_target_unknown_flavour, \
|
||||
(INFO).arch = bfd_arch_unknown, \
|
||||
(INFO).mach = 0, \
|
||||
(INFO).insn_sets = 0, \
|
||||
(INFO).endian = BFD_ENDIAN_UNKNOWN, \
|
||||
(INFO).octets_per_byte = 1, \
|
||||
INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC)
|
||||
|
||||
/* Call this macro to initialize only the internal variables for the
|
||||
disassembler. Architecture dependent things such as byte order, or machine
|
||||
variant are not touched by this macro. This makes things much easier for
|
||||
GDB which must initialize these things separately. */
|
||||
|
||||
#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \
|
||||
(INFO).fprintf_func = (fprintf_ftype)(FPRINTF_FUNC), \
|
||||
(INFO).stream = (PTR)(STREAM), \
|
||||
(INFO).symbols = NULL, \
|
||||
(INFO).num_symbols = 0, \
|
||||
(INFO).private_data = NULL, \
|
||||
(INFO).buffer = NULL, \
|
||||
(INFO).buffer_vma = 0, \
|
||||
(INFO).buffer_length = 0, \
|
||||
(INFO).read_memory_func = buffer_read_memory, \
|
||||
(INFO).memory_error_func = perror_memory, \
|
||||
(INFO).print_address_func = generic_print_address, \
|
||||
(INFO).symbol_at_address_func = generic_symbol_at_address, \
|
||||
(INFO).flags = 0, \
|
||||
(INFO).bytes_per_line = 0, \
|
||||
(INFO).bytes_per_chunk = 0, \
|
||||
(INFO).display_endian = BFD_ENDIAN_UNKNOWN, \
|
||||
(INFO).disassembler_options = NULL, \
|
||||
(INFO).insn_info_valid = 0
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif /* ! defined (DIS_ASM_H) */
|
401
cxmon/src/disass/floatformat.c
Normal file
401
cxmon/src/disass/floatformat.c
Normal file
@ -0,0 +1,401 @@
|
||||
/* IEEE floating point support routines, for GDB, the GNU Debugger.
|
||||
Copyright (C) 1991, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "floatformat.h"
|
||||
#include <math.h> /* ldexp */
|
||||
#ifdef __STDC__
|
||||
#include <stddef.h>
|
||||
extern void *memcpy (void *s1, const void *s2, size_t n);
|
||||
extern void *memset (void *s, int c, size_t n);
|
||||
#else
|
||||
extern char *memcpy ();
|
||||
extern char *memset ();
|
||||
#endif
|
||||
|
||||
/* The odds that CHAR_BIT will be anything but 8 are low enough that I'm not
|
||||
going to bother with trying to muck around with whether it is defined in
|
||||
a system header, what we do if not, etc. */
|
||||
#define FLOATFORMAT_CHAR_BIT 8
|
||||
|
||||
/* floatformats for IEEE single and double, big and little endian. */
|
||||
const struct floatformat floatformat_ieee_single_big =
|
||||
{
|
||||
floatformat_big, 32, 0, 1, 8, 127, 255, 9, 23, floatformat_intbit_no
|
||||
};
|
||||
const struct floatformat floatformat_ieee_single_little =
|
||||
{
|
||||
floatformat_little, 32, 0, 1, 8, 127, 255, 9, 23, floatformat_intbit_no
|
||||
};
|
||||
const struct floatformat floatformat_ieee_double_big =
|
||||
{
|
||||
floatformat_big, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no
|
||||
};
|
||||
const struct floatformat floatformat_ieee_double_little =
|
||||
{
|
||||
floatformat_little, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no
|
||||
};
|
||||
|
||||
/* floatformat for IEEE double, little endian byte order, with big endian word
|
||||
ordering, as on the ARM. */
|
||||
|
||||
const struct floatformat floatformat_ieee_double_littlebyte_bigword =
|
||||
{
|
||||
floatformat_littlebyte_bigword, 64, 0, 1, 11, 1023, 2047, 12, 52, floatformat_intbit_no
|
||||
};
|
||||
|
||||
const struct floatformat floatformat_i387_ext =
|
||||
{
|
||||
floatformat_little, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
|
||||
floatformat_intbit_yes
|
||||
};
|
||||
const struct floatformat floatformat_m68881_ext =
|
||||
{
|
||||
/* Note that the bits from 16 to 31 are unused. */
|
||||
floatformat_big, 96, 0, 1, 15, 0x3fff, 0x7fff, 32, 64, floatformat_intbit_yes
|
||||
};
|
||||
const struct floatformat floatformat_i960_ext =
|
||||
{
|
||||
/* Note that the bits from 0 to 15 are unused. */
|
||||
floatformat_little, 96, 16, 17, 15, 0x3fff, 0x7fff, 32, 64,
|
||||
floatformat_intbit_yes
|
||||
};
|
||||
const struct floatformat floatformat_m88110_ext =
|
||||
{
|
||||
#ifdef HARRIS_FLOAT_FORMAT
|
||||
/* Harris uses raw format 128 bytes long, but the number is just an ieee
|
||||
double, and the last 64 bits are wasted. */
|
||||
floatformat_big,128, 0, 1, 11, 0x3ff, 0x7ff, 12, 52,
|
||||
floatformat_intbit_no
|
||||
#else
|
||||
floatformat_big, 80, 0, 1, 15, 0x3fff, 0x7fff, 16, 64,
|
||||
floatformat_intbit_yes
|
||||
#endif /* HARRIS_FLOAT_FORMAT */
|
||||
};
|
||||
const struct floatformat floatformat_arm_ext =
|
||||
{
|
||||
/* Bits 1 to 16 are unused. */
|
||||
floatformat_big, 96, 0, 17, 15, 0x3fff, 0x7fff, 32, 64,
|
||||
floatformat_intbit_yes
|
||||
};
|
||||
|
||||
static unsigned long get_field PARAMS ((unsigned char *,
|
||||
enum floatformat_byteorders,
|
||||
unsigned int,
|
||||
unsigned int,
|
||||
unsigned int));
|
||||
|
||||
/* Extract a field which starts at START and is LEN bytes long. DATA and
|
||||
TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
|
||||
static unsigned long
|
||||
get_field (data, order, total_len, start, len)
|
||||
unsigned char *data;
|
||||
enum floatformat_byteorders order;
|
||||
unsigned int total_len;
|
||||
unsigned int start;
|
||||
unsigned int len;
|
||||
{
|
||||
unsigned long result;
|
||||
unsigned int cur_byte;
|
||||
int cur_bitshift;
|
||||
|
||||
/* Start at the least significant part of the field. */
|
||||
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
|
||||
if (order == floatformat_little)
|
||||
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
|
||||
cur_bitshift =
|
||||
((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
|
||||
result = *(data + cur_byte) >> (-cur_bitshift);
|
||||
cur_bitshift += FLOATFORMAT_CHAR_BIT;
|
||||
if (order == floatformat_little)
|
||||
++cur_byte;
|
||||
else
|
||||
--cur_byte;
|
||||
|
||||
/* Move towards the most significant part of the field. */
|
||||
while (cur_bitshift < len)
|
||||
{
|
||||
if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
|
||||
/* This is the last byte; zero out the bits which are not part of
|
||||
this field. */
|
||||
result |=
|
||||
(*(data + cur_byte) & ((1 << (len - cur_bitshift)) - 1))
|
||||
<< cur_bitshift;
|
||||
else
|
||||
result |= *(data + cur_byte) << cur_bitshift;
|
||||
cur_bitshift += FLOATFORMAT_CHAR_BIT;
|
||||
if (order == floatformat_little)
|
||||
++cur_byte;
|
||||
else
|
||||
--cur_byte;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* Convert from FMT to a double.
|
||||
FROM is the address of the extended float.
|
||||
Store the double in *TO. */
|
||||
|
||||
void
|
||||
floatformat_to_double (fmt, from, to)
|
||||
const struct floatformat *fmt;
|
||||
char *from;
|
||||
double *to;
|
||||
{
|
||||
unsigned char *ufrom = (unsigned char *)from;
|
||||
double dto;
|
||||
long exponent;
|
||||
unsigned long mant;
|
||||
unsigned int mant_bits, mant_off;
|
||||
int mant_bits_left;
|
||||
int special_exponent; /* It's a NaN, denorm or zero */
|
||||
|
||||
exponent = get_field (ufrom, fmt->byteorder, fmt->totalsize,
|
||||
fmt->exp_start, fmt->exp_len);
|
||||
/* Note that if exponent indicates a NaN, we can't really do anything useful
|
||||
(not knowing if the host has NaN's, or how to build one). So it will
|
||||
end up as an infinity or something close; that is OK. */
|
||||
|
||||
mant_bits_left = fmt->man_len;
|
||||
mant_off = fmt->man_start;
|
||||
dto = 0.0;
|
||||
|
||||
special_exponent = exponent == 0 || exponent == fmt->exp_nan;
|
||||
|
||||
/* Don't bias zero's, denorms or NaNs. */
|
||||
if (!special_exponent)
|
||||
exponent -= fmt->exp_bias;
|
||||
|
||||
/* Build the result algebraically. Might go infinite, underflow, etc;
|
||||
who cares. */
|
||||
|
||||
/* If this format uses a hidden bit, explicitly add it in now. Otherwise,
|
||||
increment the exponent by one to account for the integer bit. */
|
||||
|
||||
if (!special_exponent)
|
||||
if (fmt->intbit == floatformat_intbit_no)
|
||||
dto = ldexp (1.0, exponent);
|
||||
else
|
||||
exponent++;
|
||||
|
||||
while (mant_bits_left > 0)
|
||||
{
|
||||
mant_bits = min (mant_bits_left, 32);
|
||||
|
||||
mant = get_field (ufrom, fmt->byteorder, fmt->totalsize,
|
||||
mant_off, mant_bits);
|
||||
|
||||
dto += ldexp ((double)mant, exponent - mant_bits);
|
||||
exponent -= mant_bits;
|
||||
mant_off += mant_bits;
|
||||
mant_bits_left -= mant_bits;
|
||||
}
|
||||
|
||||
/* Negate it if negative. */
|
||||
if (get_field (ufrom, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1))
|
||||
dto = -dto;
|
||||
*to = dto;
|
||||
}
|
||||
|
||||
static void put_field PARAMS ((unsigned char *, enum floatformat_byteorders,
|
||||
unsigned int,
|
||||
unsigned int,
|
||||
unsigned int,
|
||||
unsigned long));
|
||||
|
||||
/* Set a field which starts at START and is LEN bytes long. DATA and
|
||||
TOTAL_LEN are the thing we are extracting it from, in byteorder ORDER. */
|
||||
static void
|
||||
put_field (data, order, total_len, start, len, stuff_to_put)
|
||||
unsigned char *data;
|
||||
enum floatformat_byteorders order;
|
||||
unsigned int total_len;
|
||||
unsigned int start;
|
||||
unsigned int len;
|
||||
unsigned long stuff_to_put;
|
||||
{
|
||||
unsigned int cur_byte;
|
||||
int cur_bitshift;
|
||||
|
||||
/* Start at the least significant part of the field. */
|
||||
cur_byte = (start + len) / FLOATFORMAT_CHAR_BIT;
|
||||
if (order == floatformat_little)
|
||||
cur_byte = (total_len / FLOATFORMAT_CHAR_BIT) - cur_byte - 1;
|
||||
cur_bitshift =
|
||||
((start + len) % FLOATFORMAT_CHAR_BIT) - FLOATFORMAT_CHAR_BIT;
|
||||
*(data + cur_byte) &=
|
||||
~(((1 << ((start + len) % FLOATFORMAT_CHAR_BIT)) - 1) << (-cur_bitshift));
|
||||
*(data + cur_byte) |=
|
||||
(stuff_to_put & ((1 << FLOATFORMAT_CHAR_BIT) - 1)) << (-cur_bitshift);
|
||||
cur_bitshift += FLOATFORMAT_CHAR_BIT;
|
||||
if (order == floatformat_little)
|
||||
++cur_byte;
|
||||
else
|
||||
--cur_byte;
|
||||
|
||||
/* Move towards the most significant part of the field. */
|
||||
while (cur_bitshift < len)
|
||||
{
|
||||
if (len - cur_bitshift < FLOATFORMAT_CHAR_BIT)
|
||||
{
|
||||
/* This is the last byte. */
|
||||
*(data + cur_byte) &=
|
||||
~((1 << (len - cur_bitshift)) - 1);
|
||||
*(data + cur_byte) |= (stuff_to_put >> cur_bitshift);
|
||||
}
|
||||
else
|
||||
*(data + cur_byte) = ((stuff_to_put >> cur_bitshift)
|
||||
& ((1 << FLOATFORMAT_CHAR_BIT) - 1));
|
||||
cur_bitshift += FLOATFORMAT_CHAR_BIT;
|
||||
if (order == floatformat_little)
|
||||
++cur_byte;
|
||||
else
|
||||
--cur_byte;
|
||||
}
|
||||
}
|
||||
|
||||
/* The converse: convert the double *FROM to an extended float
|
||||
and store where TO points. Neither FROM nor TO have any alignment
|
||||
restrictions. */
|
||||
|
||||
void
|
||||
floatformat_from_double (fmt, from, to)
|
||||
CONST struct floatformat *fmt;
|
||||
double *from;
|
||||
char *to;
|
||||
{
|
||||
double dfrom;
|
||||
int exponent;
|
||||
double mant;
|
||||
unsigned int mant_bits, mant_off;
|
||||
int mant_bits_left;
|
||||
unsigned char *uto = (unsigned char *)to;
|
||||
|
||||
memcpy (&dfrom, from, sizeof (dfrom));
|
||||
memset (uto, 0, fmt->totalsize / FLOATFORMAT_CHAR_BIT);
|
||||
if (dfrom == 0)
|
||||
return; /* Result is zero */
|
||||
if (dfrom != dfrom)
|
||||
{
|
||||
/* From is NaN */
|
||||
put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start,
|
||||
fmt->exp_len, fmt->exp_nan);
|
||||
/* Be sure it's not infinity, but NaN value is irrel */
|
||||
put_field (uto, fmt->byteorder, fmt->totalsize, fmt->man_start,
|
||||
32, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If negative, set the sign bit. */
|
||||
if (dfrom < 0)
|
||||
{
|
||||
put_field (uto, fmt->byteorder, fmt->totalsize, fmt->sign_start, 1, 1);
|
||||
dfrom = -dfrom;
|
||||
}
|
||||
|
||||
/* How to tell an infinity from an ordinary number? FIXME-someday */
|
||||
|
||||
mant = frexp (dfrom, &exponent);
|
||||
put_field (uto, fmt->byteorder, fmt->totalsize, fmt->exp_start, fmt->exp_len,
|
||||
exponent + fmt->exp_bias - 1);
|
||||
|
||||
mant_bits_left = fmt->man_len;
|
||||
mant_off = fmt->man_start;
|
||||
while (mant_bits_left > 0)
|
||||
{
|
||||
unsigned long mant_long;
|
||||
mant_bits = mant_bits_left < 32 ? mant_bits_left : 32;
|
||||
|
||||
mant *= 4294967296.0;
|
||||
mant_long = (unsigned long)mant;
|
||||
mant -= mant_long;
|
||||
|
||||
/* If the integer bit is implicit, then we need to discard it.
|
||||
If we are discarding a zero, we should be (but are not) creating
|
||||
a denormalized number which means adjusting the exponent
|
||||
(I think). */
|
||||
if (mant_bits_left == fmt->man_len
|
||||
&& fmt->intbit == floatformat_intbit_no)
|
||||
{
|
||||
mant_long &= 0x7fffffff;
|
||||
mant_bits -= 1;
|
||||
}
|
||||
else if (mant_bits < 32)
|
||||
{
|
||||
/* The bits we want are in the most significant MANT_BITS bits of
|
||||
mant_long. Move them to the least significant. */
|
||||
mant_long >>= 32 - mant_bits;
|
||||
}
|
||||
|
||||
put_field (uto, fmt->byteorder, fmt->totalsize,
|
||||
mant_off, mant_bits, mant_long);
|
||||
mant_off += mant_bits;
|
||||
mant_bits_left -= mant_bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef IEEE_DEBUG
|
||||
|
||||
/* This is to be run on a host which uses IEEE floating point. */
|
||||
|
||||
void
|
||||
ieee_test (n)
|
||||
double n;
|
||||
{
|
||||
double result;
|
||||
char exten[16];
|
||||
|
||||
floatformat_to_double (&floatformat_ieee_double_big, &n, &result);
|
||||
if (n != result)
|
||||
printf ("Differ(to): %.20g -> %.20g\n", n, result);
|
||||
floatformat_from_double (&floatformat_ieee_double_big, &n, &result);
|
||||
if (n != result)
|
||||
printf ("Differ(from): %.20g -> %.20g\n", n, result);
|
||||
|
||||
floatformat_from_double (&floatformat_m68881_ext, &n, exten);
|
||||
floatformat_to_double (&floatformat_m68881_ext, exten, &result);
|
||||
if (n != result)
|
||||
printf ("Differ(to+from): %.20g -> %.20g\n", n, result);
|
||||
|
||||
#if IEEE_DEBUG > 1
|
||||
/* This is to be run on a host which uses 68881 format. */
|
||||
{
|
||||
long double ex = *(long double *)exten;
|
||||
if (ex != n)
|
||||
printf ("Differ(from vs. extended): %.20g\n", n);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
ieee_test (0.5);
|
||||
ieee_test (256.0);
|
||||
ieee_test (0.12345);
|
||||
ieee_test (234235.78907234);
|
||||
ieee_test (-512.0);
|
||||
ieee_test (-0.004321);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
111
cxmon/src/disass/floatformat.h
Normal file
111
cxmon/src/disass/floatformat.h
Normal file
@ -0,0 +1,111 @@
|
||||
/* IEEE floating point support declarations, for GDB, the GNU Debugger.
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
|
||||
#if !defined (FLOATFORMAT_H)
|
||||
#define FLOATFORMAT_H 1
|
||||
|
||||
#include "ansidecl.h"
|
||||
|
||||
/* A floatformat consists of a sign bit, an exponent and a mantissa. Once the
|
||||
bytes are concatenated according to the byteorder flag, then each of those
|
||||
fields is contiguous. We number the bits with 0 being the most significant
|
||||
(i.e. BITS_BIG_ENDIAN type numbering), and specify which bits each field
|
||||
contains with the *_start and *_len fields. */
|
||||
|
||||
/* What is the order of the bytes. */
|
||||
|
||||
enum floatformat_byteorders {
|
||||
|
||||
/* Standard little endian byte order.
|
||||
EX: 1.2345678e10 => 00 00 80 c5 e0 fe 06 42 */
|
||||
|
||||
floatformat_little,
|
||||
|
||||
/* Standard big endian byte order.
|
||||
EX: 1.2345678e10 => 42 06 fe e0 c5 80 00 00 */
|
||||
|
||||
floatformat_big,
|
||||
|
||||
/* Little endian byte order but big endian word order.
|
||||
EX: 1.2345678e10 => e0 fe 06 42 00 00 80 c5 */
|
||||
|
||||
floatformat_littlebyte_bigword
|
||||
|
||||
};
|
||||
|
||||
enum floatformat_intbit { floatformat_intbit_yes, floatformat_intbit_no };
|
||||
|
||||
struct floatformat
|
||||
{
|
||||
enum floatformat_byteorders byteorder;
|
||||
unsigned int totalsize; /* Total size of number in bits */
|
||||
|
||||
/* Sign bit is always one bit long. 1 means negative, 0 means positive. */
|
||||
unsigned int sign_start;
|
||||
|
||||
unsigned int exp_start;
|
||||
unsigned int exp_len;
|
||||
/* Amount added to "true" exponent. 0x3fff for many IEEE extendeds. */
|
||||
unsigned int exp_bias;
|
||||
/* Exponent value which indicates NaN. This is the actual value stored in
|
||||
the float, not adjusted by the exp_bias. This usually consists of all
|
||||
one bits. */
|
||||
unsigned int exp_nan;
|
||||
|
||||
unsigned int man_start;
|
||||
unsigned int man_len;
|
||||
|
||||
/* Is the integer bit explicit or implicit? */
|
||||
enum floatformat_intbit intbit;
|
||||
};
|
||||
|
||||
/* floatformats for IEEE single and double, big and little endian. */
|
||||
|
||||
extern const struct floatformat floatformat_ieee_single_big;
|
||||
extern const struct floatformat floatformat_ieee_single_little;
|
||||
extern const struct floatformat floatformat_ieee_double_big;
|
||||
extern const struct floatformat floatformat_ieee_double_little;
|
||||
|
||||
/* floatformat for ARM IEEE double, little endian bytes and big endian words */
|
||||
|
||||
extern const struct floatformat floatformat_ieee_double_littlebyte_bigword;
|
||||
|
||||
/* floatformats for various extendeds. */
|
||||
|
||||
extern const struct floatformat floatformat_i387_ext;
|
||||
extern const struct floatformat floatformat_m68881_ext;
|
||||
extern const struct floatformat floatformat_i960_ext;
|
||||
extern const struct floatformat floatformat_m88110_ext;
|
||||
extern const struct floatformat floatformat_arm_ext;
|
||||
|
||||
/* Convert from FMT to a double.
|
||||
FROM is the address of the extended float.
|
||||
Store the double in *TO. */
|
||||
|
||||
extern void
|
||||
floatformat_to_double PARAMS ((const struct floatformat *, char *, double *));
|
||||
|
||||
/* The converse: convert the double *FROM to FMT
|
||||
and store where TO points. */
|
||||
|
||||
extern void
|
||||
floatformat_from_double PARAMS ((const struct floatformat *,
|
||||
double *, char *));
|
||||
|
||||
#endif /* defined (FLOATFORMAT_H) */
|
4146
cxmon/src/disass/i386-dis.c
Normal file
4146
cxmon/src/disass/i386-dis.c
Normal file
File diff suppressed because it is too large
Load Diff
1248
cxmon/src/disass/m68k-dis.c
Normal file
1248
cxmon/src/disass/m68k-dis.c
Normal file
File diff suppressed because it is too large
Load Diff
2066
cxmon/src/disass/m68k-opc.c
Normal file
2066
cxmon/src/disass/m68k-opc.c
Normal file
File diff suppressed because it is too large
Load Diff
315
cxmon/src/disass/m68k.h
Normal file
315
cxmon/src/disass/m68k.h
Normal file
@ -0,0 +1,315 @@
|
||||
/* Opcode table header for m680[01234]0/m6888[12]/m68851.
|
||||
Copyright 1989, 91, 92, 93, 94, 95, 96, 1997 Free Software Foundation.
|
||||
|
||||
This file is part of GDB, GAS, and the GNU binutils.
|
||||
|
||||
GDB, GAS, and the GNU binutils are free software; you can redistribute
|
||||
them and/or modify them under the terms of the GNU General Public
|
||||
License as published by the Free Software Foundation; either version
|
||||
1, or (at your option) any later version.
|
||||
|
||||
GDB, GAS, and the GNU binutils are distributed in the hope that they
|
||||
will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
|
||||
the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this file; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
/* These are used as bit flags for the arch field in the m68k_opcode
|
||||
structure. */
|
||||
#define _m68k_undef 0
|
||||
#define m68000 0x001
|
||||
#define m68008 m68000 /* synonym for -m68000. otherwise unused. */
|
||||
#define m68010 0x002
|
||||
#define m68020 0x004
|
||||
#define m68030 0x008
|
||||
#define m68ec030 m68030 /* similar enough to -m68030 to ignore differences;
|
||||
gas will deal with the few differences. */
|
||||
#define m68040 0x010
|
||||
/* there is no 68050 */
|
||||
#define m68060 0x020
|
||||
#define m68881 0x040
|
||||
#define m68882 m68881 /* synonym for -m68881. otherwise unused. */
|
||||
#define m68851 0x080
|
||||
#define cpu32 0x100 /* e.g., 68332 */
|
||||
#define mcf5200 0x200
|
||||
|
||||
/* handy aliases */
|
||||
#define m68040up (m68040 | m68060)
|
||||
#define m68030up (m68030 | m68040up)
|
||||
#define m68020up (m68020 | m68030up)
|
||||
#define m68010up (m68010 | cpu32 | m68020up)
|
||||
#define m68000up (m68000 | m68010up)
|
||||
|
||||
#define mfloat (m68881 | m68882 | m68040 | m68060)
|
||||
#define mmmu (m68851 | m68030 | m68040 | m68060)
|
||||
|
||||
/* The structure used to hold information for an opcode. */
|
||||
|
||||
struct m68k_opcode
|
||||
{
|
||||
/* The opcode name. */
|
||||
const char *name;
|
||||
/* The opcode itself. */
|
||||
unsigned long opcode;
|
||||
/* The mask used by the disassembler. */
|
||||
unsigned long match;
|
||||
/* The arguments. */
|
||||
const char *args;
|
||||
/* The architectures which support this opcode. */
|
||||
unsigned int arch;
|
||||
};
|
||||
|
||||
/* The structure used to hold information for an opcode alias. */
|
||||
|
||||
struct m68k_opcode_alias
|
||||
{
|
||||
/* The alias name. */
|
||||
const char *alias;
|
||||
/* The instruction for which this is an alias. */
|
||||
const char *primary;
|
||||
};
|
||||
|
||||
/* We store four bytes of opcode for all opcodes because that is the
|
||||
most any of them need. The actual length of an instruction is
|
||||
always at least 2 bytes, and is as much longer as necessary to hold
|
||||
the operands it has.
|
||||
|
||||
The match field is a mask saying which bits must match particular
|
||||
opcode in order for an instruction to be an instance of that
|
||||
opcode.
|
||||
|
||||
The args field is a string containing two characters for each
|
||||
operand of the instruction. The first specifies the kind of
|
||||
operand; the second, the place it is stored. */
|
||||
|
||||
/* Kinds of operands:
|
||||
Characters used: AaBCcDdFfIJkLlMmnOopQqRrSsTtUVvWXYZ0123|*~%;@!&$?/<>#^+-
|
||||
|
||||
D data register only. Stored as 3 bits.
|
||||
A address register only. Stored as 3 bits.
|
||||
a address register indirect only. Stored as 3 bits.
|
||||
R either kind of register. Stored as 4 bits.
|
||||
r either kind of register indirect only. Stored as 4 bits.
|
||||
At the moment, used only for cas2 instruction.
|
||||
F floating point coprocessor register only. Stored as 3 bits.
|
||||
O an offset (or width): immediate data 0-31 or data register.
|
||||
Stored as 6 bits in special format for BF... insns.
|
||||
+ autoincrement only. Stored as 3 bits (number of the address register).
|
||||
- autodecrement only. Stored as 3 bits (number of the address register).
|
||||
Q quick immediate data. Stored as 3 bits.
|
||||
This matches an immediate operand only when value is in range 1 .. 8.
|
||||
M moveq immediate data. Stored as 8 bits.
|
||||
This matches an immediate operand only when value is in range -128..127
|
||||
T trap vector immediate data. Stored as 4 bits.
|
||||
|
||||
k K-factor for fmove.p instruction. Stored as a 7-bit constant or
|
||||
a three bit register offset, depending on the field type.
|
||||
|
||||
# immediate data. Stored in special places (b, w or l)
|
||||
which say how many bits to store.
|
||||
^ immediate data for floating point instructions. Special places
|
||||
are offset by 2 bytes from '#'...
|
||||
B pc-relative address, converted to an offset
|
||||
that is treated as immediate data.
|
||||
d displacement and register. Stores the register as 3 bits
|
||||
and stores the displacement in the entire second word.
|
||||
|
||||
C the CCR. No need to store it; this is just for filtering validity.
|
||||
S the SR. No need to store, just as with CCR.
|
||||
U the USP. No need to store, just as with CCR.
|
||||
|
||||
I Coprocessor ID. Not printed if 1. The Coprocessor ID is always
|
||||
extracted from the 'd' field of word one, which means that an extended
|
||||
coprocessor opcode can be skipped using the 'i' place, if needed.
|
||||
|
||||
s System Control register for the floating point coprocessor.
|
||||
|
||||
J Misc register for movec instruction, stored in 'j' format.
|
||||
Possible values:
|
||||
0x000 SFC Source Function Code reg [60, 40, 30, 20, 10]
|
||||
0x001 DFC Data Function Code reg [60, 40, 30, 20, 10]
|
||||
0x002 CACR Cache Control Register [60, 40, 30, 20]
|
||||
0x003 TC MMU Translation Control [60, 40]
|
||||
0x004 ITT0 Instruction Transparent
|
||||
Translation reg 0 [60, 40]
|
||||
0x005 ITT1 Instruction Transparent
|
||||
Translation reg 1 [60, 40]
|
||||
0x006 DTT0 Data Transparent
|
||||
Translation reg 0 [60, 40]
|
||||
0x007 DTT1 Data Transparent
|
||||
Translation reg 1 [60, 40]
|
||||
0x008 BUSCR Bus Control Register [60]
|
||||
0x800 USP User Stack Pointer [60, 40, 30, 20, 10]
|
||||
0x801 VBR Vector Base reg [60, 40, 30, 20, 10]
|
||||
0x802 CAAR Cache Address Register [ 30, 20]
|
||||
0x803 MSP Master Stack Pointer [ 40, 30, 20]
|
||||
0x804 ISP Interrupt Stack Pointer [ 40, 30, 20]
|
||||
0x805 MMUSR MMU Status reg [ 40]
|
||||
0x806 URP User Root Pointer [60, 40]
|
||||
0x807 SRP Supervisor Root Pointer [60, 40]
|
||||
0x808 PCR Processor Configuration reg [60]
|
||||
0xC00 ROMBAR ROM Base Address Register [520X]
|
||||
0xC04 RAMBAR0 RAM Base Address Register 0 [520X]
|
||||
0xC05 RAMBAR1 RAM Base Address Register 0 [520X]
|
||||
0xC0F MBAR0 RAM Base Address Register 0 [520X]
|
||||
|
||||
L Register list of the type d0-d7/a0-a7 etc.
|
||||
(New! Improved! Can also hold fp0-fp7, as well!)
|
||||
The assembler tries to see if the registers match the insn by
|
||||
looking at where the insn wants them stored.
|
||||
|
||||
l Register list like L, but with all the bits reversed.
|
||||
Used for going the other way. . .
|
||||
|
||||
c cache identifier which may be "nc" for no cache, "ic"
|
||||
for instruction cache, "dc" for data cache, or "bc"
|
||||
for both caches. Used in cinv and cpush. Always
|
||||
stored in position "d".
|
||||
|
||||
The remainder are all stored as 6 bits using an address mode and a
|
||||
register number; they differ in which addressing modes they match.
|
||||
|
||||
* all (modes 0-6,7.0-4)
|
||||
~ alterable memory (modes 2-6,7.0,7.1)
|
||||
(not 0,1,7.2-4)
|
||||
% alterable (modes 0-6,7.0,7.1)
|
||||
(not 7.2-4)
|
||||
; data (modes 0,2-6,7.0-4)
|
||||
(not 1)
|
||||
@ data, but not immediate (modes 0,2-6,7.0-3)
|
||||
(not 1,7.4)
|
||||
! control (modes 2,5,6,7.0-3)
|
||||
(not 0,1,3,4,7.4)
|
||||
& alterable control (modes 2,5,6,7.0,7.1)
|
||||
(not 0,1,7.2-4)
|
||||
$ alterable data (modes 0,2-6,7.0,7.1)
|
||||
(not 1,7.2-4)
|
||||
? alterable control, or data register (modes 0,2,5,6,7.0,7.1)
|
||||
(not 1,3,4,7.2-4)
|
||||
/ control, or data register (modes 0,2,5,6,7.0-3)
|
||||
(not 1,3,4,7.4)
|
||||
> *save operands (modes 2,4,5,6,7.0,7.1)
|
||||
(not 0,1,3,7.2-4)
|
||||
< *restore operands (modes 2,3,5,6,7.0-3)
|
||||
(not 0,1,4,7.4)
|
||||
|
||||
coldfire move operands:
|
||||
m (modes 0-4)
|
||||
n (modes 5,7.2)
|
||||
o (modes 6,7.0,7.1,7.3,7.4)
|
||||
p (modes 0-5)
|
||||
|
||||
coldfire bset/bclr/btst operands:
|
||||
q (modes 0,2-5)
|
||||
v (modes 0,2-5,7.0,7.1)
|
||||
*/
|
||||
|
||||
/* For the 68851: */
|
||||
/*
|
||||
I didn't use much imagination in choosing the
|
||||
following codes, so many of them aren't very
|
||||
mnemonic. -rab
|
||||
|
||||
0 32 bit pmmu register
|
||||
Possible values:
|
||||
000 TC Translation Control Register (68030, 68851)
|
||||
|
||||
1 16 bit pmmu register
|
||||
111 AC Access Control (68851)
|
||||
|
||||
2 8 bit pmmu register
|
||||
100 CAL Current Access Level (68851)
|
||||
101 VAL Validate Access Level (68851)
|
||||
110 SCC Stack Change Control (68851)
|
||||
|
||||
3 68030-only pmmu registers (32 bit)
|
||||
010 TT0 Transparent Translation reg 0
|
||||
(aka Access Control reg 0 -- AC0 -- on 68ec030)
|
||||
011 TT1 Transparent Translation reg 1
|
||||
(aka Access Control reg 1 -- AC1 -- on 68ec030)
|
||||
|
||||
W wide pmmu registers
|
||||
Possible values:
|
||||
001 DRP Dma Root Pointer (68851)
|
||||
010 SRP Supervisor Root Pointer (68030, 68851)
|
||||
011 CRP Cpu Root Pointer (68030, 68851)
|
||||
|
||||
f function code register (68030, 68851)
|
||||
0 SFC
|
||||
1 DFC
|
||||
|
||||
V VAL register only (68851)
|
||||
|
||||
X BADx, BACx (16 bit)
|
||||
100 BAD Breakpoint Acknowledge Data (68851)
|
||||
101 BAC Breakpoint Acknowledge Control (68851)
|
||||
|
||||
Y PSR (68851) (MMUSR on 68030) (ACUSR on 68ec030)
|
||||
Z PCSR (68851)
|
||||
|
||||
| memory (modes 2-6, 7.*)
|
||||
|
||||
t address test level (68030 only)
|
||||
Stored as 3 bits, range 0-7.
|
||||
Also used for breakpoint instruction now.
|
||||
|
||||
*/
|
||||
|
||||
/* Places to put an operand, for non-general operands:
|
||||
s source, low bits of first word.
|
||||
d dest, shifted 9 in first word
|
||||
1 second word, shifted 12
|
||||
2 second word, shifted 6
|
||||
3 second word, shifted 0
|
||||
4 third word, shifted 12
|
||||
5 third word, shifted 6
|
||||
6 third word, shifted 0
|
||||
7 second word, shifted 7
|
||||
8 second word, shifted 10
|
||||
9 second word, shifted 5
|
||||
D store in both place 1 and place 3; for divul and divsl.
|
||||
B first word, low byte, for branch displacements
|
||||
W second word (entire), for branch displacements
|
||||
L second and third words (entire), for branch displacements
|
||||
(also overloaded for move16)
|
||||
b second word, low byte
|
||||
w second word (entire) [variable word/long branch offset for dbra]
|
||||
W second word (entire) (must be signed 16 bit value)
|
||||
l second and third word (entire)
|
||||
g variable branch offset for bra and similar instructions.
|
||||
The place to store depends on the magnitude of offset.
|
||||
t store in both place 7 and place 8; for floating point operations
|
||||
c branch offset for cpBcc operations.
|
||||
The place to store is word two if bit six of word one is zero,
|
||||
and words two and three if bit six of word one is one.
|
||||
i Increment by two, to skip over coprocessor extended operands. Only
|
||||
works with the 'I' format.
|
||||
k Dynamic K-factor field. Bits 6-4 of word 2, used as a register number.
|
||||
Also used for dynamic fmovem instruction.
|
||||
C floating point coprocessor constant - 7 bits. Also used for static
|
||||
K-factors...
|
||||
j Movec register #, stored in 12 low bits of second word.
|
||||
|
||||
Places to put operand, for general operands:
|
||||
d destination, shifted 6 bits in first word
|
||||
b source, at low bit of first word, and immediate uses one byte
|
||||
w source, at low bit of first word, and immediate uses two bytes
|
||||
l source, at low bit of first word, and immediate uses four bytes
|
||||
s source, at low bit of first word.
|
||||
Used sometimes in contexts where immediate is not allowed anyway.
|
||||
f single precision float, low bit of 1st word, immediate uses 4 bytes
|
||||
F double precision float, low bit of 1st word, immediate uses 8 bytes
|
||||
x extended precision float, low bit of 1st word, immediate uses 12 bytes
|
||||
p packed float, low bit of 1st word, immediate uses 12 bytes
|
||||
*/
|
||||
|
||||
extern const struct m68k_opcode m68k_opcodes[];
|
||||
extern const struct m68k_opcode_alias m68k_opcode_aliases[];
|
||||
|
||||
extern const int m68k_numopcodes, m68k_numaliases;
|
||||
|
||||
/* end of m68k-opcode.h */
|
34
cxmon/src/disass/opintl.h
Normal file
34
cxmon/src/disass/opintl.h
Normal file
@ -0,0 +1,34 @@
|
||||
/* opintl.h - opcodes specific header for gettext code.
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
This file is part of the opcodes library used by GAS and the GNU binutils.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GAS; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA. */
|
||||
|
||||
#ifdef ENABLE_NLS
|
||||
# include <libintl.h>
|
||||
# define _(String) dgettext (PACKAGE, String)
|
||||
# ifdef gettext_noop
|
||||
# define N_(String) gettext_noop (String)
|
||||
# else
|
||||
# define N_(String) (String)
|
||||
# endif
|
||||
#else
|
||||
/* Stubs that do something close enough. */
|
||||
# define textdomain(String) (String)
|
||||
# define gettext(String) (String)
|
||||
# define dgettext(Domain,Message) (Message)
|
||||
# define dcgettext(Domain,Message,Type) (Message)
|
||||
# define bindtextdomain(Domain,Directory) (Domain)
|
||||
# define _(String) (String)
|
||||
# define N_(String) (String)
|
||||
/* In this case we don't care about the value. */
|
||||
# ifndef LC_MESSAGES
|
||||
# define LC_MESSAGES 0
|
||||
# endif
|
||||
#endif
|
118
cxmon/src/main.cpp
Normal file
118
cxmon/src/main.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* main.cpp - Wrapper program for standalone cxmon
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "mon.h"
|
||||
|
||||
|
||||
#ifdef __BEOS__
|
||||
#include <AppKit.h>
|
||||
#include <KernelKit.h>
|
||||
#include <StorageKit.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Detect if program was launched from Shell or Tracker
|
||||
static bool launched_from_tracker(void)
|
||||
{
|
||||
char *cmd = getenv("_");
|
||||
if (cmd == NULL || strlen(cmd) < 7)
|
||||
return false;
|
||||
return !strcmp(cmd + strlen(cmd) - 7 , "Tracker");
|
||||
}
|
||||
|
||||
// Open Terminal window with given title for stdio, returns false on error
|
||||
static bool open_stdio(const char *title)
|
||||
{
|
||||
// Create key
|
||||
char key_name[64];
|
||||
bigtime_t t = system_time();
|
||||
sprintf(key_name, "%Ld", t);
|
||||
|
||||
// Make pipe names
|
||||
char out_pipe_name[64], in_pipe_name[64];
|
||||
sprintf(out_pipe_name, "/pipe/debug_out_%s", key_name);
|
||||
sprintf(in_pipe_name, "/pipe/debug_in_%s", key_name);
|
||||
|
||||
// Create semaphore
|
||||
char sem_name[B_OS_NAME_LENGTH], sem_id_str[B_OS_NAME_LENGTH];
|
||||
sprintf(sem_name, "debug_glue_%s", key_name);
|
||||
sem_id glue_sem = create_sem(0, sem_name);
|
||||
sprintf(sem_id_str, "%d", glue_sem);
|
||||
|
||||
// Make path for "Terminal" app
|
||||
char term_path[B_PATH_NAME_LENGTH];
|
||||
find_directory(B_BEOS_APPS_DIRECTORY, -1, false, term_path, 1024);
|
||||
strcat(term_path, "/Terminal");
|
||||
|
||||
// Load "Terminal"
|
||||
const char *t_argv[6];
|
||||
t_argv[0] = term_path;
|
||||
t_argv[1] = "-t";
|
||||
t_argv[2] = (char *)title;
|
||||
t_argv[3] = "/bin/debug_glue";
|
||||
t_argv[4] = key_name;
|
||||
t_argv[5] = sem_id_str;
|
||||
thread_id th = load_image(6, t_argv, (const char **)environ);
|
||||
if (th < 0) {
|
||||
delete_sem(glue_sem);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start "Terminal"
|
||||
resume_thread(th);
|
||||
status_t err = acquire_sem_etc(glue_sem, 1, B_TIMEOUT, 5000000);
|
||||
delete_sem(glue_sem);
|
||||
if (err)
|
||||
return false;
|
||||
|
||||
// Open input/output pipes
|
||||
FILE *in = freopen(in_pipe_name, "rb", stdin);
|
||||
if (in == NULL)
|
||||
return false;
|
||||
FILE *out = freopen(out_pipe_name, "wb", stdout);
|
||||
if (out == NULL) {
|
||||
fclose(in);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set buffer modes
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Main program
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifdef __BEOS__
|
||||
// Launched from Tracker? Then open terminal window
|
||||
if (launched_from_tracker()) {
|
||||
if (!open_stdio("mon"))
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Execute mon
|
||||
mon_init();
|
||||
mon(argc, argv);
|
||||
mon_exit();
|
||||
return 0;
|
||||
}
|
1255
cxmon/src/mon.cpp
Normal file
1255
cxmon/src/mon.cpp
Normal file
File diff suppressed because it is too large
Load Diff
100
cxmon/src/mon.h
Normal file
100
cxmon/src/mon.h
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* mon.h - cxmon main program
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MON_H
|
||||
#define MON_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/*
|
||||
* Initialization, deinitialization and invocation
|
||||
*/
|
||||
|
||||
void mon_init();
|
||||
void mon_exit();
|
||||
void mon(int argc, char **argv);
|
||||
|
||||
|
||||
/*
|
||||
* Definitions for adding commands to mon
|
||||
*/
|
||||
|
||||
// Input tokens
|
||||
enum Token {
|
||||
T_NULL, // Invalid token
|
||||
T_END, // End of line
|
||||
T_NUMBER, // Hexadecimal/decimal number (uint32)
|
||||
T_STRING, // String enclosed in ""
|
||||
T_NAME, // Variable name
|
||||
T_DOT, // '.'
|
||||
T_COLON, // ':'
|
||||
T_COMMA, // ','
|
||||
T_LPAREN, // '('
|
||||
T_RPAREN, // ')'
|
||||
T_PLUS, // '+'
|
||||
T_MINUS, // '-'
|
||||
T_MUL, // '*'
|
||||
T_DIV, // '/'
|
||||
T_MOD, // '%'
|
||||
T_AND, // '&'
|
||||
T_OR, // '|'
|
||||
T_EOR, // '^'
|
||||
T_SHIFTL, // '<<'
|
||||
T_SHIFTR, // '>>'
|
||||
T_NOT, // '~'
|
||||
T_ASSIGN // '='
|
||||
};
|
||||
|
||||
// Scanner variables
|
||||
extern enum Token mon_token; // Last token read
|
||||
extern uintptr mon_number; // Contains the number if mon_token==T_NUMBER
|
||||
extern char *mon_string; // Contains the string if mon_token==T_STRING
|
||||
extern char *mon_name; // Contains the variable name if mon_token==T_NAME
|
||||
|
||||
// Streams for input, output and error messages
|
||||
extern FILE *monin, *monout, *monerr;
|
||||
|
||||
// Current address, value of '.' in expressions
|
||||
extern uintptr mon_dot_address;
|
||||
|
||||
extern bool mon_use_real_mem; // Flag: mon is using real memory
|
||||
extern uint32 mon_mem_size; // Size of mon buffer (if mon_use_real_mem = false)
|
||||
|
||||
extern bool mon_macos_mode; // Flag: enable features in the disassembler for working with MacOS code
|
||||
|
||||
// Add command to mon
|
||||
extern void mon_add_command(const char *name, void (*func)(), const char *help_text);
|
||||
|
||||
// Functions for commands
|
||||
extern void mon_error(const char *s); // Print error message
|
||||
extern enum Token mon_get_token(); // Get next token
|
||||
extern bool mon_expression(uintptr *number); // Parse expression
|
||||
extern bool mon_aborted(); // Check if Ctrl-C was pressed
|
||||
|
||||
// Memory access
|
||||
extern uint32 (*mon_read_byte)(uintptr adr);
|
||||
extern void (*mon_write_byte)(uintptr adr, uint32 b);
|
||||
extern uint32 mon_read_half(uintptr adr);
|
||||
extern void mon_write_half(uintptr adr, uint32 w);
|
||||
extern uint32 mon_read_word(uintptr adr);
|
||||
extern void mon_write_word(uintptr adr, uint32 l);
|
||||
|
||||
#endif
|
232
cxmon/src/mon_6502.cpp
Normal file
232
cxmon/src/mon_6502.cpp
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* mon_6502.cpp - 6502 disassembler
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "mon.h"
|
||||
#include "mon_disass.h"
|
||||
|
||||
|
||||
// Addressing modes
|
||||
enum AddrMode {
|
||||
A_IMPL,
|
||||
A_ACCU, // A
|
||||
A_IMM, // #zz
|
||||
A_REL, // Branches
|
||||
A_ZERO, // zz
|
||||
A_ZEROX, // zz,x
|
||||
A_ZEROY, // zz,y
|
||||
A_ABS, // zzzz
|
||||
A_ABSX, // zzzz,x
|
||||
A_ABSY, // zzzz,y
|
||||
A_IND, // (zzzz)
|
||||
A_INDX, // (zz,x)
|
||||
A_INDY // (zz),y
|
||||
};
|
||||
|
||||
// Mnemonics
|
||||
enum Mnemonic {
|
||||
M_ADC, M_AND, M_ASL, M_BCC, M_BCS, M_BEQ, M_BIT, M_BMI, M_BNE, M_BPL,
|
||||
M_BRK, M_BVC, M_BVS, M_CLC, M_CLD, M_CLI, M_CLV, M_CMP, M_CPX, M_CPY,
|
||||
M_DEC, M_DEX, M_DEY, M_EOR, M_INC, M_INX, M_INY, M_JMP, M_JSR, M_LDA,
|
||||
M_LDX, M_LDY, M_LSR, M_NOP, M_ORA, M_PHA, M_PHP, M_PLA, M_PLP, M_ROL,
|
||||
M_ROR, M_RTI, M_RTS, M_SBC, M_SEC, M_SED, M_SEI, M_STA, M_STX, M_STY,
|
||||
M_TAX, M_TAY, M_TSX, M_TXA, M_TXS, M_TYA,
|
||||
|
||||
M_ILLEGAL, // Undocumented opcodes start here
|
||||
|
||||
M_IANC, M_IANE, M_IARR, M_IASR, M_IDCP, M_IISB, M_IJAM, M_INOP, M_ILAS,
|
||||
M_ILAX, M_ILXA, M_IRLA, M_IRRA, M_ISAX, M_ISBC, M_ISBX, M_ISHA, M_ISHS,
|
||||
M_ISHX, M_ISHY, M_ISLO, M_ISRE,
|
||||
|
||||
M_MAXIMUM // Highest element
|
||||
};
|
||||
|
||||
// Mnemonic for each opcode
|
||||
static const Mnemonic mnemonic[256] = {
|
||||
M_BRK , M_ORA , M_IJAM, M_ISLO, M_INOP, M_ORA, M_ASL , M_ISLO, // 00
|
||||
M_PHP , M_ORA , M_ASL , M_IANC, M_INOP, M_ORA, M_ASL , M_ISLO,
|
||||
M_BPL , M_ORA , M_IJAM, M_ISLO, M_INOP, M_ORA, M_ASL , M_ISLO, // 10
|
||||
M_CLC , M_ORA , M_INOP, M_ISLO, M_INOP, M_ORA, M_ASL , M_ISLO,
|
||||
M_JSR , M_AND , M_IJAM, M_IRLA, M_BIT , M_AND, M_ROL , M_IRLA, // 20
|
||||
M_PLP , M_AND , M_ROL , M_IANC, M_BIT , M_AND, M_ROL , M_IRLA,
|
||||
M_BMI , M_AND , M_IJAM, M_IRLA, M_INOP, M_AND, M_ROL , M_IRLA, // 30
|
||||
M_SEC , M_AND , M_INOP, M_IRLA, M_INOP, M_AND, M_ROL , M_IRLA,
|
||||
M_RTI , M_EOR , M_IJAM, M_ISRE, M_INOP, M_EOR, M_LSR , M_ISRE, // 40
|
||||
M_PHA , M_EOR , M_LSR , M_IASR, M_JMP , M_EOR, M_LSR , M_ISRE,
|
||||
M_BVC , M_EOR , M_IJAM, M_ISRE, M_INOP, M_EOR, M_LSR , M_ISRE, // 50
|
||||
M_CLI , M_EOR , M_INOP, M_ISRE, M_INOP, M_EOR, M_LSR , M_ISRE,
|
||||
M_RTS , M_ADC , M_IJAM, M_IRRA, M_INOP, M_ADC, M_ROR , M_IRRA, // 60
|
||||
M_PLA , M_ADC , M_ROR , M_IARR, M_JMP , M_ADC, M_ROR , M_IRRA,
|
||||
M_BVS , M_ADC , M_IJAM, M_IRRA, M_INOP, M_ADC, M_ROR , M_IRRA, // 70
|
||||
M_SEI , M_ADC , M_INOP, M_IRRA, M_INOP, M_ADC, M_ROR , M_IRRA,
|
||||
M_INOP, M_STA , M_INOP, M_ISAX, M_STY , M_STA, M_STX , M_ISAX, // 80
|
||||
M_DEY , M_INOP, M_TXA , M_IANE, M_STY , M_STA, M_STX , M_ISAX,
|
||||
M_BCC , M_STA , M_IJAM, M_ISHA, M_STY , M_STA, M_STX , M_ISAX, // 90
|
||||
M_TYA , M_STA , M_TXS , M_ISHS, M_ISHY, M_STA, M_ISHX, M_ISHA,
|
||||
M_LDY , M_LDA , M_LDX , M_ILAX, M_LDY , M_LDA, M_LDX , M_ILAX, // a0
|
||||
M_TAY , M_LDA , M_TAX , M_ILXA, M_LDY , M_LDA, M_LDX , M_ILAX,
|
||||
M_BCS , M_LDA , M_IJAM, M_ILAX, M_LDY , M_LDA, M_LDX , M_ILAX, // b0
|
||||
M_CLV , M_LDA , M_TSX , M_ILAS, M_LDY , M_LDA, M_LDX , M_ILAX,
|
||||
M_CPY , M_CMP , M_INOP, M_IDCP, M_CPY , M_CMP, M_DEC , M_IDCP, // c0
|
||||
M_INY , M_CMP , M_DEX , M_ISBX, M_CPY , M_CMP, M_DEC , M_IDCP,
|
||||
M_BNE , M_CMP , M_IJAM, M_IDCP, M_INOP, M_CMP, M_DEC , M_IDCP, // d0
|
||||
M_CLD , M_CMP , M_INOP, M_IDCP, M_INOP, M_CMP, M_DEC , M_IDCP,
|
||||
M_CPX , M_SBC , M_INOP, M_IISB, M_CPX , M_SBC, M_INC , M_IISB, // e0
|
||||
M_INX , M_SBC , M_NOP , M_ISBC, M_CPX , M_SBC, M_INC , M_IISB,
|
||||
M_BEQ , M_SBC , M_IJAM, M_IISB, M_INOP, M_SBC, M_INC , M_IISB, // f0
|
||||
M_SED , M_SBC , M_INOP, M_IISB, M_INOP, M_SBC, M_INC , M_IISB
|
||||
};
|
||||
|
||||
// Addressing mode for each opcode
|
||||
static const AddrMode adr_mode[256] = {
|
||||
A_IMPL, A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 00
|
||||
A_IMPL, A_IMM , A_ACCU, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 10
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
|
||||
A_ABS , A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 20
|
||||
A_IMPL, A_IMM , A_ACCU, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 30
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
|
||||
A_IMPL, A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 40
|
||||
A_IMPL, A_IMM , A_ACCU, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 50
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
|
||||
A_IMPL, A_INDX, A_IMPL, A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 60
|
||||
A_IMPL, A_IMM , A_ACCU, A_IMM , A_IND , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // 70
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
|
||||
A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // 80
|
||||
A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROY, A_ZEROY, // 90
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSY , A_ABSY,
|
||||
A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // a0
|
||||
A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROY, A_ZEROY, // b0
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSY , A_ABSY,
|
||||
A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // c0
|
||||
A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // d0
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX,
|
||||
A_IMM , A_INDX, A_IMM , A_INDX, A_ZERO , A_ZERO , A_ZERO , A_ZERO, // e0
|
||||
A_IMPL, A_IMM , A_IMPL, A_IMM , A_ABS , A_ABS , A_ABS , A_ABS,
|
||||
A_REL , A_INDY, A_IMPL, A_INDY, A_ZEROX, A_ZEROX, A_ZEROX, A_ZEROX, // f0
|
||||
A_IMPL, A_ABSY, A_IMPL, A_ABSY, A_ABSX , A_ABSX , A_ABSX , A_ABSX
|
||||
};
|
||||
|
||||
// Chars for each mnemonic
|
||||
static const char mnem_1[] = "aaabbbbbbbbbbcccccccdddeiiijjllllnopppprrrrssssssstttttt?aaaadijnlllrrsssssssss";
|
||||
static const char mnem_2[] = "dnscceimnprvvllllmppeeeonnnmsdddsorhhlloottbeeetttaasxxy?nnrscsaoaaxlrabbhhhhlr";
|
||||
static const char mnem_3[] = "cdlcsqtielkcscdivpxycxyrcxypraxyrpaapaplrisccdiaxyxyxasa?cerrpbmpsxaaaxcxasxyoe";
|
||||
|
||||
// Instruction length for each addressing mode
|
||||
static const int adr_length[] = {1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2};
|
||||
|
||||
|
||||
/*
|
||||
* Disassemble one instruction, return number of bytes
|
||||
*/
|
||||
|
||||
int disass_6502(FILE *f, uint32 adr, uint8 op, uint8 lo, uint8 hi)
|
||||
{
|
||||
AddrMode mode = adr_mode[op];
|
||||
Mnemonic mnem = mnemonic[op];
|
||||
|
||||
// Display instruction bytes in hex
|
||||
switch (adr_length[mode]) {
|
||||
case 1:
|
||||
fprintf(f, "%02x\t\t", op);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
fprintf(f, "%02x %02x\t\t", op, lo);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
fprintf(f, "%02x %02x %02x\t", op, lo, hi);
|
||||
break;
|
||||
}
|
||||
|
||||
// Tag undocumented opcodes with an asterisk
|
||||
if (mnem > M_ILLEGAL)
|
||||
fputc('*', f);
|
||||
else
|
||||
fputc(' ', f);
|
||||
|
||||
// Print mnemonic
|
||||
fprintf(f, "%c%c%c ", mnem_1[mnem], mnem_2[mnem], mnem_3[mnem]);
|
||||
|
||||
// Print argument
|
||||
switch (mode) {
|
||||
case A_IMPL:
|
||||
break;
|
||||
|
||||
case A_ACCU:
|
||||
fprintf(f, "a");
|
||||
break;
|
||||
|
||||
case A_IMM:
|
||||
fprintf(f, "#$%02x", lo);
|
||||
break;
|
||||
|
||||
case A_REL:
|
||||
fprintf(f, "$%04x", (adr + 2) + (int8)lo);
|
||||
break;
|
||||
|
||||
case A_ZERO:
|
||||
fprintf(f, "$%02x", lo);
|
||||
break;
|
||||
|
||||
case A_ZEROX:
|
||||
fprintf(f, "$%02x,x", lo);
|
||||
break;
|
||||
|
||||
case A_ZEROY:
|
||||
fprintf(f, "$%02x,y", lo);
|
||||
break;
|
||||
|
||||
case A_ABS:
|
||||
fprintf(f, "$%04x", (hi << 8) | lo);
|
||||
break;
|
||||
|
||||
case A_ABSX:
|
||||
fprintf(f, "$%04x,x", (hi << 8) | lo);
|
||||
break;
|
||||
|
||||
case A_ABSY:
|
||||
fprintf(f, "$%04x,y", (hi << 8) | lo);
|
||||
break;
|
||||
|
||||
case A_IND:
|
||||
fprintf(f, "($%04x)", (hi << 8) | lo);
|
||||
break;
|
||||
|
||||
case A_INDX:
|
||||
fprintf(f, "($%02x,x)", lo);
|
||||
break;
|
||||
|
||||
case A_INDY:
|
||||
fprintf(f, "($%02x),y", lo);
|
||||
break;
|
||||
}
|
||||
|
||||
fputc('\n', f);
|
||||
return adr_length[mode];
|
||||
}
|
1212
cxmon/src/mon_atraps.h
Normal file
1212
cxmon/src/mon_atraps.h
Normal file
File diff suppressed because it is too large
Load Diff
669
cxmon/src/mon_cmd.cpp
Normal file
669
cxmon/src/mon_cmd.cpp
Normal file
@ -0,0 +1,669 @@
|
||||
/*
|
||||
* mon_cmd.cpp - cxmon standard commands
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mon.h"
|
||||
#include "mon_cmd.h"
|
||||
#include "mon_disass.h"
|
||||
|
||||
#ifndef VERSION
|
||||
#define VERSION "3"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* range_args = [expression] [[COMMA] expression] END
|
||||
*
|
||||
* Read start address to "adr", end address to "end_adr".
|
||||
* "adr" defaults to '.', "end_adr" defaults to '.'+def_range
|
||||
*
|
||||
* true: OK, false: Error
|
||||
*/
|
||||
|
||||
static bool range_args(uintptr *adr, uintptr *end_adr, uint32 def_range)
|
||||
{
|
||||
*adr = mon_dot_address;
|
||||
*end_adr = mon_dot_address + def_range;
|
||||
|
||||
if (mon_token == T_END)
|
||||
return true;
|
||||
else {
|
||||
if (!mon_expression(adr))
|
||||
return false;
|
||||
*end_adr = *adr + def_range;
|
||||
if (mon_token == T_END)
|
||||
return true;
|
||||
else {
|
||||
if (mon_token == T_COMMA) mon_get_token();
|
||||
if (!mon_expression(end_adr))
|
||||
return false;
|
||||
return mon_token == T_END;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* byte_string = (expression | STRING) {COMMA (expression | STRING)} END
|
||||
*/
|
||||
|
||||
static bool byte_string(uint8 *&str, uintptr &len)
|
||||
{
|
||||
uintptr value;
|
||||
|
||||
static const int GRANULARITY = 16; // must be a power of 2
|
||||
str = NULL;
|
||||
len = 0;
|
||||
goto start;
|
||||
|
||||
for (;;) {
|
||||
if (mon_token == T_COMMA) {
|
||||
mon_get_token();
|
||||
|
||||
start:
|
||||
if (mon_token == T_STRING) {
|
||||
unsigned n = strlen(mon_string);
|
||||
str = (uint8 *)realloc(str, (len + n - 1 + GRANULARITY) & ~(GRANULARITY - 1));
|
||||
assert(str != NULL);
|
||||
memcpy(str + len, mon_string, n);
|
||||
len += n;
|
||||
mon_get_token();
|
||||
} else if (mon_expression(&value)) {
|
||||
str = (uint8 *)realloc(str, (len + GRANULARITY) & ~(GRANULARITY - 1));
|
||||
assert(str != NULL);
|
||||
str[len] = value;
|
||||
len++;
|
||||
} else {
|
||||
if (str)
|
||||
free(str);
|
||||
return false;
|
||||
}
|
||||
|
||||
} else if (mon_token == T_END) {
|
||||
return true;
|
||||
} else {
|
||||
mon_error("',' expected");
|
||||
if (str)
|
||||
free(str);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Convert character to printable character
|
||||
*/
|
||||
|
||||
static inline uint8 char2print(uint8 c)
|
||||
{
|
||||
return (c >= 0x20 && c <= 0x7e) ? c : '.';
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Show version
|
||||
* ver
|
||||
*/
|
||||
|
||||
void version(void)
|
||||
{
|
||||
fprintf(monout, "cxmon V" VERSION "\n");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Redirect output
|
||||
* o [file]
|
||||
*/
|
||||
|
||||
void redir_output(void)
|
||||
{
|
||||
// Close old file
|
||||
if (monout != monerr) {
|
||||
fclose(monout);
|
||||
monout = monerr;
|
||||
return;
|
||||
}
|
||||
|
||||
// No argument given?
|
||||
if (mon_token == T_END)
|
||||
return;
|
||||
|
||||
// Otherwise open file
|
||||
if (mon_token == T_STRING) {
|
||||
mon_get_token();
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
if (!(monout = fopen(mon_string, "w")))
|
||||
mon_error("Unable to open file");
|
||||
} else
|
||||
mon_error("'\"' around file name expected");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compute and display expression
|
||||
* ? expression
|
||||
*/
|
||||
|
||||
void print_expr(void)
|
||||
{
|
||||
uintptr val;
|
||||
|
||||
if (!mon_expression(&val))
|
||||
return;
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
if (val > 0x7fffffff) {
|
||||
fprintf(monout, "Hex unsigned: $%08x\n"
|
||||
"Hex signed : -$%08x\n"
|
||||
"Dec unsigned: %u\n"
|
||||
"Dec signed : %d\n", val, -val, val, val);
|
||||
fprintf(monout, "Char : '%c%c%c%c'\n", char2print(val >> 24), char2print(val >> 16), char2print(val >> 8), char2print(val));
|
||||
} else {
|
||||
fprintf(monout, "Hex : $%08x\n"
|
||||
"Dec : %d\n", val, val);
|
||||
fprintf(monout, "Char: '%c%c%c%c'\n", char2print(val >> 24), char2print(val >> 16), char2print(val >> 8), char2print(val));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Execute shell command
|
||||
* \ "command"
|
||||
*/
|
||||
|
||||
void shell_command(void)
|
||||
{
|
||||
if (mon_token != T_STRING) {
|
||||
mon_error("'\"' around command expected");
|
||||
return;
|
||||
}
|
||||
mon_get_token();
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
system(mon_string);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Memory dump
|
||||
* m [start [end]]
|
||||
*/
|
||||
|
||||
#define MEMDUMP_BPL 16 // Bytes per line
|
||||
|
||||
void memory_dump(void)
|
||||
{
|
||||
uintptr adr, end_adr;
|
||||
uint8 mem[MEMDUMP_BPL + 1];
|
||||
|
||||
mem[MEMDUMP_BPL] = 0;
|
||||
|
||||
if (!range_args(&adr, &end_adr, 16 * MEMDUMP_BPL - 1)) // 16 lines unless end address specified
|
||||
return;
|
||||
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx:", int(2 * sizeof(adr)), mon_use_real_mem ? adr: adr % mon_mem_size);
|
||||
for (int i=0; i<MEMDUMP_BPL; i++, adr++) {
|
||||
if (i % 4 == 0)
|
||||
fprintf(monout, " %08x", mon_read_word(adr));
|
||||
mem[i] = char2print(mon_read_byte(adr));
|
||||
}
|
||||
fprintf(monout, " '%s'\n", mem);
|
||||
}
|
||||
|
||||
mon_dot_address = adr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ASCII dump
|
||||
* i [start [end]]
|
||||
*/
|
||||
|
||||
#define ASCIIDUMP_BPL 64 // Bytes per line
|
||||
|
||||
void ascii_dump(void)
|
||||
{
|
||||
uintptr adr, end_adr;
|
||||
uint8 str[ASCIIDUMP_BPL + 1];
|
||||
|
||||
str[ASCIIDUMP_BPL] = 0;
|
||||
|
||||
if (!range_args(&adr, &end_adr, 16 * ASCIIDUMP_BPL - 1)) // 16 lines unless end address specified
|
||||
return;
|
||||
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx:", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
for (int i=0; i<ASCIIDUMP_BPL; i++, adr++)
|
||||
str[i] = char2print(mon_read_byte(adr));
|
||||
fprintf(monout, " '%s'\n", str);
|
||||
}
|
||||
|
||||
mon_dot_address = adr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Binary dump
|
||||
* b [start [end]]
|
||||
*/
|
||||
|
||||
void binary_dump(void)
|
||||
{
|
||||
uintptr adr, end_adr;
|
||||
uint8 str[9];
|
||||
|
||||
str[8] = 0;
|
||||
|
||||
if (!range_args(&adr, &end_adr, 7)) // 8 lines unless end address specified
|
||||
return;
|
||||
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx:", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
uint8 b = mon_read_byte(adr);
|
||||
for (int m=0x80, i=0; i<8; m>>=1, i++)
|
||||
str[i] = (b & m) ? '*' : '.';
|
||||
fprintf(monout, " '%s'\n", str);
|
||||
adr++;
|
||||
}
|
||||
|
||||
mon_dot_address = adr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disassemble
|
||||
* d [start [end]]
|
||||
* d65 [start [end]]
|
||||
* d68 [start [end]]
|
||||
* d80 [start [end]]
|
||||
* d86 [start [end]]
|
||||
* d8086 [start [end]]
|
||||
*/
|
||||
|
||||
enum CPUType {
|
||||
CPU_PPC,
|
||||
CPU_6502,
|
||||
CPU_680x0,
|
||||
CPU_Z80,
|
||||
CPU_80x86_32,
|
||||
CPU_80x86_16,
|
||||
CPU_x86_64
|
||||
};
|
||||
|
||||
static void disassemble(CPUType type)
|
||||
{
|
||||
uintptr adr, end_adr;
|
||||
|
||||
if (!range_args(&adr, &end_adr, 16 * 4 - 1)) // 16 lines unless end address specified
|
||||
return;
|
||||
|
||||
switch (type) {
|
||||
case CPU_PPC:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
uint32 w = mon_read_word(adr);
|
||||
fprintf(monout, "%0*lx: %08x\t", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size, w);
|
||||
disass_ppc(monout, mon_use_real_mem ? adr : adr % mon_mem_size, w);
|
||||
adr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_6502:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
uint8 op = mon_read_byte(adr);
|
||||
uint8 lo = mon_read_byte(adr + 1);
|
||||
uint8 hi = mon_read_byte(adr + 2);
|
||||
fprintf(monout, "%0*lx: ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
adr += disass_6502(monout, mon_use_real_mem ? adr : adr % mon_mem_size, op, lo, hi);
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_680x0:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx: ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
adr += disass_68k(monout, mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_Z80:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx: ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
adr += disass_z80(monout, mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_x86_64:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx: ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
adr += disass_x86(monout, mon_use_real_mem ? adr : adr % mon_mem_size, 64);
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_80x86_32:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx: ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
adr += disass_x86(monout, mon_use_real_mem ? adr : adr % mon_mem_size, 32);
|
||||
}
|
||||
break;
|
||||
|
||||
case CPU_80x86_16:
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
fprintf(monout, "%0*lx: ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
adr += disass_x86(monout, mon_use_real_mem ? adr : adr % mon_mem_size, 16);
|
||||
}
|
||||
}
|
||||
|
||||
mon_dot_address = adr;
|
||||
}
|
||||
|
||||
void disassemble_ppc(void)
|
||||
{
|
||||
disassemble(CPU_PPC);
|
||||
}
|
||||
|
||||
void disassemble_6502(void)
|
||||
{
|
||||
disassemble(CPU_6502);
|
||||
}
|
||||
|
||||
void disassemble_680x0(void)
|
||||
{
|
||||
disassemble(CPU_680x0);
|
||||
}
|
||||
|
||||
void disassemble_z80(void)
|
||||
{
|
||||
disassemble(CPU_Z80);
|
||||
}
|
||||
|
||||
void disassemble_80x86_32(void)
|
||||
{
|
||||
disassemble(CPU_80x86_32);
|
||||
}
|
||||
|
||||
void disassemble_80x86_16(void)
|
||||
{
|
||||
disassemble(CPU_80x86_16);
|
||||
}
|
||||
|
||||
void disassemble_x86_64(void)
|
||||
{
|
||||
disassemble(CPU_x86_64);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Modify memory
|
||||
* : addr bytestring
|
||||
*/
|
||||
|
||||
void modify(void)
|
||||
{
|
||||
uintptr adr, len, src_adr = 0;
|
||||
uint8 *str;
|
||||
|
||||
if (!mon_expression(&adr))
|
||||
return;
|
||||
if (!byte_string(str, len))
|
||||
return;
|
||||
|
||||
while (src_adr < len)
|
||||
mon_write_byte(adr++, str[src_adr++]);
|
||||
mon_dot_address = adr;
|
||||
|
||||
free(str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill
|
||||
* f start end bytestring
|
||||
*/
|
||||
|
||||
void fill(void)
|
||||
{
|
||||
uintptr adr, end_adr, len, src_adr = 0;
|
||||
uint8 *str;
|
||||
|
||||
if (!mon_expression(&adr))
|
||||
return;
|
||||
if (!mon_expression(&end_adr))
|
||||
return;
|
||||
if (!byte_string(str, len))
|
||||
return;
|
||||
|
||||
while (adr <= end_adr)
|
||||
mon_write_byte(adr++, str[src_adr++ % len]);
|
||||
|
||||
free(str);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Transfer memory
|
||||
* t start end dest
|
||||
*/
|
||||
|
||||
void transfer(void)
|
||||
{
|
||||
uintptr adr, end_adr, dest;
|
||||
int num;
|
||||
|
||||
if (!mon_expression(&adr))
|
||||
return;
|
||||
if (!mon_expression(&end_adr))
|
||||
return;
|
||||
if (!mon_expression(&dest))
|
||||
return;
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
num = end_adr - adr + 1;
|
||||
|
||||
if (dest < adr)
|
||||
for (int i=0; i<num; i++)
|
||||
mon_write_byte(dest++, mon_read_byte(adr++));
|
||||
else {
|
||||
dest += end_adr - adr;
|
||||
for (int i=0; i<num; i++)
|
||||
mon_write_byte(dest--, mon_read_byte(end_adr--));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Compare
|
||||
* c start end dest
|
||||
*/
|
||||
|
||||
void compare(void)
|
||||
{
|
||||
uintptr adr, end_adr, dest;
|
||||
int num = 0;
|
||||
|
||||
if (!mon_expression(&adr))
|
||||
return;
|
||||
if (!mon_expression(&end_adr))
|
||||
return;
|
||||
if (!mon_expression(&dest))
|
||||
return;
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
while (adr <= end_adr && !mon_aborted()) {
|
||||
if (mon_read_byte(adr) != mon_read_byte(dest)) {
|
||||
fprintf(monout, "%0*lx ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
num++;
|
||||
if (!(num & 7))
|
||||
fputc('\n', monout);
|
||||
}
|
||||
adr++; dest++;
|
||||
}
|
||||
|
||||
if (num & 7)
|
||||
fputc('\n', monout);
|
||||
fprintf(monout, "%d byte(s) different\n", num);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Search for byte string
|
||||
* h start end bytestring
|
||||
*/
|
||||
|
||||
void hunt(void)
|
||||
{
|
||||
uintptr adr, end_adr, len;
|
||||
uint8 *str;
|
||||
int num = 0;
|
||||
|
||||
if (!mon_expression(&adr))
|
||||
return;
|
||||
if (!mon_expression(&end_adr))
|
||||
return;
|
||||
if (!byte_string(str, len))
|
||||
return;
|
||||
|
||||
while ((adr+len-1) <= end_adr && !mon_aborted()) {
|
||||
uint32 i;
|
||||
|
||||
for (i=0; i<len; i++)
|
||||
if (mon_read_byte(adr + i) != str[i])
|
||||
break;
|
||||
|
||||
if (i == len) {
|
||||
fprintf(monout, "%0*lx ", int(2 * sizeof(adr)), mon_use_real_mem ? adr : adr % mon_mem_size);
|
||||
num++;
|
||||
if (num == 1)
|
||||
mon_dot_address = adr;
|
||||
if (!(num & 7))
|
||||
fputc('\n', monout);
|
||||
}
|
||||
adr++;
|
||||
}
|
||||
|
||||
free(str);
|
||||
|
||||
if (num & 7)
|
||||
fputc('\n', monout);
|
||||
fprintf(monout, "Found %d occurrences\n", num);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Load data
|
||||
* [ start "file"
|
||||
*/
|
||||
|
||||
void load_data(void)
|
||||
{
|
||||
uintptr start_adr;
|
||||
FILE *file;
|
||||
int fc;
|
||||
|
||||
if (!mon_expression(&start_adr))
|
||||
return;
|
||||
if (mon_token == T_END) {
|
||||
mon_error("Missing file name");
|
||||
return;
|
||||
}
|
||||
if (mon_token != T_STRING) {
|
||||
mon_error("'\"' around file name expected");
|
||||
return;
|
||||
}
|
||||
mon_get_token();
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(file = fopen(mon_string, "rb")))
|
||||
mon_error("Unable to open file");
|
||||
else {
|
||||
uintptr adr = start_adr;
|
||||
|
||||
while ((fc = fgetc(file)) != EOF)
|
||||
mon_write_byte(adr++, fc);
|
||||
fclose(file);
|
||||
|
||||
fprintf(monerr, "%08x bytes read from %0*lx to %0*lx\n", adr - start_adr, int(2 * sizeof(adr)), mon_use_real_mem ? start_adr : start_adr % mon_mem_size, int(2 * sizeof(adr)), mon_use_real_mem ? adr-1 : (adr-1) % mon_mem_size);
|
||||
mon_dot_address = adr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Save data
|
||||
* ] start size "file"
|
||||
*/
|
||||
|
||||
void save_data(void)
|
||||
{
|
||||
uintptr start_adr, size;
|
||||
FILE *file;
|
||||
|
||||
if (!mon_expression(&start_adr))
|
||||
return;
|
||||
if (!mon_expression(&size))
|
||||
return;
|
||||
if (mon_token == T_END) {
|
||||
mon_error("Missing file name");
|
||||
return;
|
||||
}
|
||||
if (mon_token != T_STRING) {
|
||||
mon_error("'\"' around file name expected");
|
||||
return;
|
||||
}
|
||||
mon_get_token();
|
||||
if (mon_token != T_END) {
|
||||
mon_error("Too many arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(file = fopen(mon_string, "wb")))
|
||||
mon_error("Unable to create file");
|
||||
else {
|
||||
uintptr adr = start_adr, end_adr = start_adr + size - 1;
|
||||
|
||||
while (adr <= end_adr)
|
||||
fputc(mon_read_byte(adr++), file);
|
||||
fclose(file);
|
||||
|
||||
fprintf(monerr, "%08x bytes written from %0*lx to %0*lx\n", size, int(2 * sizeof(adr)), mon_use_real_mem ? start_adr : start_adr % mon_mem_size, int(2 * sizeof(adr)), mon_use_real_mem ? end_adr : end_adr % mon_mem_size);
|
||||
}
|
||||
}
|
46
cxmon/src/mon_cmd.h
Normal file
46
cxmon/src/mon_cmd.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* mon_cmd.h - cxmon standard commands
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MON_CMD_H
|
||||
#define MON_CMD_H
|
||||
|
||||
extern void version(void);
|
||||
extern void redir_output(void);
|
||||
extern void print_expr(void);
|
||||
extern void shell_command(void);
|
||||
extern void memory_dump(void);
|
||||
extern void ascii_dump(void);
|
||||
extern void binary_dump(void);
|
||||
extern void disassemble_ppc(void);
|
||||
extern void disassemble_6502(void);
|
||||
extern void disassemble_680x0(void);
|
||||
extern void disassemble_z80(void);
|
||||
extern void disassemble_80x86_32(void);
|
||||
extern void disassemble_80x86_16(void);
|
||||
extern void disassemble_x86_64(void);
|
||||
extern void modify(void);
|
||||
extern void fill(void);
|
||||
extern void transfer(void);
|
||||
extern void compare(void);
|
||||
extern void hunt(void);
|
||||
extern void load_data(void);
|
||||
extern void save_data(void);
|
||||
|
||||
#endif
|
204
cxmon/src/mon_disass.cpp
Normal file
204
cxmon/src/mon_disass.cpp
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* mon_disass.cpp - Disassemblers
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "mon.h"
|
||||
#include "mon_disass.h"
|
||||
|
||||
#include "mon_atraps.h"
|
||||
#include "mon_lowmem.h"
|
||||
|
||||
|
||||
// Flag: enable MacOS A-Trap and LM globals lookup in 68k disassembler
|
||||
bool mon_macos_mode = false;
|
||||
|
||||
|
||||
/*
|
||||
* GNU disassembler callbacks
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
#include "disass/dis-asm.h"
|
||||
|
||||
int buffer_read_memory(bfd_vma from, bfd_byte *to, unsigned int length, struct disassemble_info *info)
|
||||
{
|
||||
while (length--)
|
||||
*to++ = mon_read_byte(from++);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void perror_memory(int status, bfd_vma memaddr, struct disassemble_info *info)
|
||||
{
|
||||
info->fprintf_func(info->stream, "Unknown error %d\n", status);
|
||||
}
|
||||
|
||||
bool lookup_lowmem;
|
||||
|
||||
void generic_print_address(bfd_vma addr, struct disassemble_info *info)
|
||||
{
|
||||
if (lookup_lowmem && addr >= 0x100 && addr < 0x3000) {
|
||||
if (((addr >= 0x400 && addr < 0x800) || (addr >= 0xe00 && addr < 0x1e00)) && ((addr & 3) == 0)) {
|
||||
// Look for address in A-Trap table
|
||||
uint16 opcode = (addr < 0xe00 ? 0xa000 + (addr - 0x400) / 4 : 0xa800 + (addr - 0xe00) / 4);
|
||||
uint16 mask = (addr < 0xe00 ? 0xf8ff : 0xffff);
|
||||
const atrap_info *p = atraps;
|
||||
while (p->word) {
|
||||
if ((p->word & mask) == opcode) {
|
||||
info->fprintf_func(info->stream, p->name);
|
||||
return;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
// Look for address in low memory globals table
|
||||
const lowmem_info *p = lowmem;
|
||||
while (p->name) {
|
||||
if (addr >= p[0].addr && addr < p[1].addr) {
|
||||
if (addr == p[0].addr)
|
||||
info->fprintf_func(info->stream, "%s", p->name);
|
||||
else
|
||||
info->fprintf_func(info->stream, "%s+%d", p->name, addr - p->addr);
|
||||
return;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addr >= UVAL64(0x100000000))
|
||||
info->fprintf_func(info->stream, "$%08x%08x", (uint32)(addr >> 32), (uint32)addr);
|
||||
else
|
||||
info->fprintf_func(info->stream, "$%08x", (uint32)addr);
|
||||
}
|
||||
|
||||
int generic_symbol_at_address(bfd_vma addr, struct disassemble_info *info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void print_68k_invalid_opcode(unsigned long opcode, struct disassemble_info *info)
|
||||
{
|
||||
if (mon_macos_mode) {
|
||||
// Look for MacOS A-Trap
|
||||
const atrap_info *p = atraps;
|
||||
while (p->word) {
|
||||
if (p->word == opcode) {
|
||||
info->fprintf_func(info->stream, p->name);
|
||||
return;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
info->fprintf_func(info->stream, "?");
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* sprintf into a "stream"
|
||||
*/
|
||||
|
||||
struct SFILE {
|
||||
char *buffer;
|
||||
char *current;
|
||||
};
|
||||
|
||||
static int mon_sprintf(SFILE *f, const char *format, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf(f->current, format, args);
|
||||
f->current += n = strlen(f->current);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disassemble one instruction, return number of bytes
|
||||
*/
|
||||
|
||||
int disass_68k(FILE *f, uint32 adr)
|
||||
{
|
||||
// Initialize info for GDB disassembler
|
||||
disassemble_info info;
|
||||
char buf[1024];
|
||||
SFILE sfile = {buf, buf};
|
||||
sfile.buffer = buf;
|
||||
sfile.current = buf;
|
||||
INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
|
||||
|
||||
// Disassemble instruction
|
||||
lookup_lowmem = mon_macos_mode;
|
||||
int num = print_insn_m68k(adr, &info);
|
||||
|
||||
for (int i=0; i<6; i+=2) {
|
||||
if (num > i)
|
||||
fprintf(f, "%04x ", mon_read_half(adr + i));
|
||||
else
|
||||
fprintf(f, " ");
|
||||
}
|
||||
if (num == 8)
|
||||
fprintf(f, "%04x\t%s\n", mon_read_half(adr + 6), buf);
|
||||
else if (num > 8)
|
||||
fprintf(f, "...\t%s\n", buf);
|
||||
else
|
||||
fprintf(f, " \t%s\n", buf);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
int disass_x86(FILE *f, uint32 adr, uint32 bits)
|
||||
{
|
||||
// Initialize info for GDB disassembler
|
||||
disassemble_info info;
|
||||
char buf[1024];
|
||||
SFILE sfile = {buf, buf};
|
||||
sfile.buffer = buf;
|
||||
sfile.current = buf;
|
||||
INIT_DISASSEMBLE_INFO(info, (FILE *)&sfile, (fprintf_ftype)mon_sprintf);
|
||||
if (bits == 16)
|
||||
info.mach = bfd_mach_i386_i8086;
|
||||
else if (bits == 64)
|
||||
info.mach = bfd_mach_x86_64;
|
||||
|
||||
// Disassemble instruction
|
||||
lookup_lowmem = false;
|
||||
int num = print_insn_i386_att(adr, &info);
|
||||
|
||||
for (int i=0; i<6; i++) {
|
||||
if (num > i)
|
||||
fprintf(f, "%02x ", mon_read_byte(adr + i));
|
||||
else
|
||||
fprintf(f, " ");
|
||||
}
|
||||
if (num == 7)
|
||||
fprintf(f, "%02x\t%s\n", mon_read_byte(adr + 7), buf);
|
||||
else if (num > 7)
|
||||
fprintf(f, "..\t%s\n", buf);
|
||||
else
|
||||
fprintf(f, " \t%s\n", buf);
|
||||
|
||||
return num;
|
||||
}
|
30
cxmon/src/mon_disass.h
Normal file
30
cxmon/src/mon_disass.h
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* mon_disass.h - Disassemblers
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MON_DISASS_H
|
||||
#define MON_DISASS_H
|
||||
|
||||
extern void disass_ppc(FILE *f, unsigned int adr, unsigned int w);
|
||||
extern int disass_68k(FILE *f, uint32 adr);
|
||||
extern int disass_x86(FILE *f, uint32 adr, uint32 bits = 32);
|
||||
extern int disass_6502(FILE *f, uint32 adr, uint8 op, uint8 lo, uint8 hi);
|
||||
extern int disass_z80(FILE *f, uint32 adr);
|
||||
|
||||
#endif
|
579
cxmon/src/mon_lowmem.cpp
Normal file
579
cxmon/src/mon_lowmem.cpp
Normal file
@ -0,0 +1,579 @@
|
||||
/*
|
||||
* mon_lowmem.cpp - MacOS low memory globals definitions
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include "mon_lowmem.h"
|
||||
|
||||
// Array of low memory globals in ascending order
|
||||
const lowmem_info lowmem[] = {
|
||||
{"MonkeyLives" , 0x100},
|
||||
{"ScrVRes" , 0x102},
|
||||
{"ScrHRes" , 0x104},
|
||||
{"ScreenRow" , 0x106},
|
||||
{"MemTop" , 0x108},
|
||||
{"BufPtr" , 0x10C},
|
||||
{"StkLowPt" , 0x110},
|
||||
{"HeapEnd" , 0x114},
|
||||
{"TheZone" , 0x118},
|
||||
{"UTableBase" , 0x11C},
|
||||
{"MacJump" , 0x120},
|
||||
{"DskRtnAdr" , 0x124},
|
||||
{"PollRtnAdr" , 0x128},
|
||||
{"DskVerify" , 0x12C},
|
||||
{"LoadTrap" , 0x12D},
|
||||
{"MmInOK" , 0x12E},
|
||||
{"CPUFlag" , 0x12F},
|
||||
{"ApplLimit" , 0x130},
|
||||
{"SonyVars" , 0x134},
|
||||
{"PWMValue" , 0x138},
|
||||
{"PollStack" , 0x13A},
|
||||
{"PollProc" , 0x13E},
|
||||
{"DskErr" , 0x142},
|
||||
{"SysEvtMask" , 0x144},
|
||||
{"SysEvtBuf" , 0x146},
|
||||
{"EventQueue" , 0x14A},
|
||||
{"EvtBufCnt" , 0x154},
|
||||
{"RndSeed" , 0x156},
|
||||
{"SysVersion" , 0x15A},
|
||||
{"SEvtEnb" , 0x15C},
|
||||
{"DSWndUpdate" , 0x15D},
|
||||
{"FontFlag" , 0x15E},
|
||||
{"IntFlag" , 0x15F},
|
||||
{"VBLQueue" , 0x160},
|
||||
{"Ticks" , 0x16A},
|
||||
{"MBTicks" , 0x16E},
|
||||
{"MBState" , 0x172},
|
||||
{"Tocks" , 0x173},
|
||||
{"KeyMap" , 0x174},
|
||||
{"KeypadMap" , 0x17C},
|
||||
{"KeyLast" , 0x184},
|
||||
{"KeyTime" , 0x186},
|
||||
{"KeyRepTime" , 0x18A},
|
||||
{"KeyThresh" , 0x18E},
|
||||
{"KeyRepThresh" , 0x190},
|
||||
{"Lvl1DT" , 0x192},
|
||||
{"Lvl2DT" , 0x1B2},
|
||||
{"UnitNtryCnt" , 0x1D2},
|
||||
{"VIA" , 0x1D4},
|
||||
{"SCCRd" , 0x1D8},
|
||||
{"SCCWr" , 0x1DC},
|
||||
{"IWM" , 0x1E0},
|
||||
{"GetParam" , 0x1E4},
|
||||
{"SysParam" , 0x1F8},
|
||||
{"SPValid" , 0x1F8},
|
||||
{"SPATalkA" , 0x1F9},
|
||||
{"SPATalkB" , 0x1FA},
|
||||
{"SPConfig" , 0x1FB},
|
||||
{"SPPortA" , 0x1FC},
|
||||
{"SPPortB" , 0x1FE},
|
||||
{"SPAlarm" , 0x200},
|
||||
{"SPFont" , 0x204},
|
||||
{"SPKbd" , 0x206},
|
||||
{"SPPrint" , 0x207},
|
||||
{"SPVolCtl" , 0x208},
|
||||
{"SPClikCaret" , 0x209},
|
||||
{"SPMisc1" , 0x20A},
|
||||
{"SPMisc2" , 0x20B},
|
||||
{"Time" , 0x20C},
|
||||
{"BootDrive" , 0x210},
|
||||
{"JShell" , 0x212},
|
||||
{"SFSaveDisk" , 0x214},
|
||||
{"KbdVars" , 0x216},
|
||||
{"KbdLast" , 0x218},
|
||||
{"JKybdTask" , 0x21A},
|
||||
{"KbdType" , 0x21E},
|
||||
{"AlarmState" , 0x21F},
|
||||
{"MemErr" , 0x220},
|
||||
{"JFigTrkSpd" , 0x222},
|
||||
{"JDiskPrime" , 0x226},
|
||||
{"JRdAddr" , 0x22A},
|
||||
{"JRdData" , 0x22E},
|
||||
{"JWrData" , 0x232},
|
||||
{"JSeek" , 0x236},
|
||||
{"JSetupPoll" , 0x23A},
|
||||
{"JRecal" , 0x23E},
|
||||
{"JControl" , 0x242},
|
||||
{"JWakeUp" , 0x246},
|
||||
{"JReSeek" , 0x24A},
|
||||
{"JMakeSpdTbl" , 0x24E},
|
||||
{"JAdrDisk" , 0x252},
|
||||
{"JSetSpeed" , 0x256},
|
||||
{"NiblTbl" , 0x25A},
|
||||
{"FlEvtMask" , 0x25E},
|
||||
{"SdVolume" , 0x260},
|
||||
{"SdEnable/Finder" , 0x261},
|
||||
{"SoundVars" , 0x262},
|
||||
{"SoundBase" , 0x266},
|
||||
{"SoundVBL" , 0x26A},
|
||||
{"SoundDCE" , 0x27A},
|
||||
{"SoundActive" , 0x27E},
|
||||
{"SoundLevel" , 0x27F},
|
||||
{"CurPitch" , 0x280},
|
||||
{"Switcher" , 0x282},
|
||||
{"SwitcherTPtr" , 0x286},
|
||||
{"RSDHndl" , 0x28A},
|
||||
{"ROM85" , 0x28E},
|
||||
{"PortAUse" , 0x290},
|
||||
{"PortBUse" , 0x291},
|
||||
{"ScreenVars" , 0x292},
|
||||
{"JGNEFilter" , 0x29A},
|
||||
{"Key1Trans" , 0x29E},
|
||||
{"Key2Trans" , 0x2A2},
|
||||
{"SysZone" , 0x2A6},
|
||||
{"ApplZone" , 0x2AA},
|
||||
{"ROMBase" , 0x2AE},
|
||||
{"RAMBase" , 0x2B2},
|
||||
{"ExpandMem" , 0x2B6},
|
||||
{"DSAlertTab" , 0x2BA},
|
||||
{"ExtStsDT" , 0x2BE},
|
||||
{"SCCASts" , 0x2CE},
|
||||
{"SCCBSts" , 0x2CF},
|
||||
{"SerialVars" , 0x2D0},
|
||||
{"ABusVars" , 0x2D8},
|
||||
{"ABusDCE" , 0x2DC},
|
||||
{"FinderName" , 0x2E0},
|
||||
{"DoubleTime" , 0x2F0},
|
||||
{"CaretTime" , 0x2F4},
|
||||
{"ScrDmpEnb" , 0x2F8},
|
||||
{"ScrDmpType" , 0x2F9},
|
||||
{"TagData" , 0x2FA},
|
||||
{"BufTgFNum" , 0x2FC},
|
||||
{"BufTgFFlg" , 0x300},
|
||||
{"BufTgFBkNum" , 0x302},
|
||||
{"BufTgDate" , 0x304},
|
||||
{"DrvQHdr" , 0x308},
|
||||
{"PWMBuf2" , 0x312},
|
||||
{"HpChk/MacPgm" , 0x316},
|
||||
{"Lo3Bytes" , 0x31A},
|
||||
{"MinStack" , 0x31E},
|
||||
{"DefltStack" , 0x322},
|
||||
{"MMDefFlags" , 0x326},
|
||||
{"GZRootHnd" , 0x328},
|
||||
{"GZRootPtr" , 0x32C},
|
||||
{"GZMoveHnd" , 0x330},
|
||||
{"DSDrawProc" , 0x334},
|
||||
{"EjectNotify" , 0x338},
|
||||
{"IAZNotify" , 0x33C},
|
||||
{"CurDB" , 0x340},
|
||||
{"NxtDB" , 0x342},
|
||||
{"MaxDB" , 0x344},
|
||||
{"FlushOnly" , 0x346},
|
||||
{"RegRsrc" , 0x347},
|
||||
{"FLckUnlck" , 0x348},
|
||||
{"FrcSync" , 0x349},
|
||||
{"NewMount" , 0x34A},
|
||||
{"NoEject" , 0x34B},
|
||||
{"DrMstrBlk" , 0x34C},
|
||||
{"FCBSPtr" , 0x34E},
|
||||
{"DefVCBPtr" , 0x352},
|
||||
{"VCBQHdr" , 0x356},
|
||||
{"FSQHdr" , 0x360},
|
||||
{"FSQHead" , 0x362},
|
||||
{"FSQTail" , 0x366},
|
||||
{"HFSStkTop" , 0x36A},
|
||||
{"HFSStkPtr" , 0x36E},
|
||||
{"WDCBsPtr" , 0x372},
|
||||
{"HFSFlags" , 0x376},
|
||||
{"CacheFlag" , 0x377},
|
||||
{"SysBMCPtr" , 0x378},
|
||||
{"SysVolCPtr" , 0x37C},
|
||||
{"SysCtlCPtr" , 0x380},
|
||||
{"DefVRefNum" , 0x384},
|
||||
{"PMSPPtr" , 0x386},
|
||||
{"HFSTagData" , 0x38A},
|
||||
{"HFSDSErr" , 0x392},
|
||||
{"CacheVars" , 0x394},
|
||||
{"CurDirStore" , 0x398},
|
||||
{"CacheCom" , 0x39C},
|
||||
{"FmtDefaults" , 0x39E},
|
||||
{"ErCode" , 0x3A2},
|
||||
{"Params" , 0x3A4},
|
||||
{"FSTemp8" , 0x3D6},
|
||||
{"FSIOErr" , 0x3DE},
|
||||
{"FSQueueHook" , 0x3E2},
|
||||
{"ExtFSHook" , 0x3E6},
|
||||
{"DskSwtchHook" , 0x3EA},
|
||||
{"ReqstVol" , 0x3EE},
|
||||
{"ToExtFS" , 0x3F2},
|
||||
{"FSFCBLen" , 0x3F6},
|
||||
{"DSAlertRect" , 0x3F8},
|
||||
{"JHideCrsr" , 0x800},
|
||||
{"JShowCrsr" , 0x804},
|
||||
{"JShieldCrsr" , 0x808},
|
||||
{"JScrnAddr" , 0x80C},
|
||||
{"JScrnSize" , 0x810},
|
||||
{"JInitCrsr" , 0x814},
|
||||
{"JSetCrsr" , 0x818},
|
||||
{"JCrsrObscure" , 0x81C},
|
||||
{"JUpdateProc" , 0x820},
|
||||
{"ScrnBase" , 0x824},
|
||||
{"MTemp" , 0x828},
|
||||
{"RawMouse" , 0x82C},
|
||||
{"Mouse" , 0x830},
|
||||
{"CrsrPin" , 0x834},
|
||||
{"CrsrRect" , 0x83C},
|
||||
{"TheCrsr" , 0x844},
|
||||
{"CrsrAddr" , 0x888},
|
||||
{"JAllocCrsr" , 0x88C},
|
||||
{"JSetCCrsr" , 0x890},
|
||||
{"JOpcodeProc" , 0x894},
|
||||
{"CrsrBase" , 0x898},
|
||||
{"CrsrDevice" , 0x89C},
|
||||
{"SrcDevice" , 0x8A0},
|
||||
{"MainDevice" , 0x8A4},
|
||||
{"DeviceList" , 0x8A8},
|
||||
{"CrsrRow" , 0x8AC},
|
||||
{"QDColors" , 0x8B0},
|
||||
{"CrsrVis" , 0x8CC},
|
||||
{"CrsrBusy" , 0x8CD},
|
||||
{"CrsrNew" , 0x8CE},
|
||||
{"CrsrCouple" , 0x8CF},
|
||||
{"CrsrState" , 0x8D0},
|
||||
{"CrsrObscure" , 0x8D2},
|
||||
{"CrsrScale" , 0x8D3},
|
||||
{"MouseMask" , 0x8D6},
|
||||
{"MouseOffset" , 0x8DA},
|
||||
{"JournalFlag" , 0x8DE},
|
||||
{"JSwapFont" , 0x8E0},
|
||||
{"JFontInfo" , 0x8E4},
|
||||
{"JournalRef" , 0x8E8},
|
||||
{"CrsrThresh" , 0x8EC},
|
||||
{"JCrsrTask" , 0x8EE},
|
||||
{"WWExist" , 0x8F2},
|
||||
{"QDExist" , 0x8F3},
|
||||
{"JFetch" , 0x8F4},
|
||||
{"JStash" , 0x8F8},
|
||||
{"JIODone" , 0x8FC},
|
||||
{"CurApRefNum" , 0x900},
|
||||
{"LaunchFlag" , 0x902},
|
||||
{"FondState" , 0x903},
|
||||
{"CurrentA5" , 0x904},
|
||||
{"CurStackBase" , 0x908},
|
||||
{"LoadFiller" , 0x90C},
|
||||
{"CurApName" , 0x910},
|
||||
{"SaveSegHandle" , 0x930},
|
||||
{"CurJTOffset" , 0x934},
|
||||
{"CurPageOption" , 0x936},
|
||||
{"HiliteMode" , 0x938},
|
||||
{"LoaderPBlock" , 0x93A},
|
||||
{"PrintErr" , 0x944},
|
||||
{"ChooserBits" , 0x946},
|
||||
{"PrFlags" , 0x946},
|
||||
{"PrType" , 0x947},
|
||||
{"PrRefNum" , 0x952},
|
||||
{"LastPGlobal" , 0x954},
|
||||
{"ScrapSize" , 0x960},
|
||||
{"ScrapHandle" , 0x964},
|
||||
{"ScrapCount" , 0x968},
|
||||
{"ScrapState" , 0x96A},
|
||||
{"ScrapName" , 0x96C},
|
||||
{"ScrapTag" , 0x970},
|
||||
{"RomFont0" , 0x980},
|
||||
{"AppFontID" , 0x984},
|
||||
{"SaveFondFlags" , 0x986},
|
||||
{"FMDefaultSize" , 0x987},
|
||||
{"CurFMFamily" , 0x988},
|
||||
{"CurFMSize" , 0x98A},
|
||||
{"CurFMFace" , 0x98C},
|
||||
{"CurFMNeedBits" , 0x98D},
|
||||
{"CurFMDevice" , 0x98E},
|
||||
{"CurFMNumer" , 0x990},
|
||||
{"CurFMDenom" , 0x994},
|
||||
{"FOutError" , 0x998},
|
||||
{"FOutFontHandle" , 0x99A},
|
||||
{"FOutBold" , 0x99E},
|
||||
{"FOutItalic" , 0x99F},
|
||||
{"FOutULOffset" , 0x9A0},
|
||||
{"FOutULShadow" , 0x9A1},
|
||||
{"FOutULThick" , 0x9A2},
|
||||
{"FOutShadow" , 0x9A3},
|
||||
{"FOutExtra" , 0x9A4},
|
||||
{"FOutAscent" , 0x9A5},
|
||||
{"FOutDescent" , 0x9A6},
|
||||
{"FOutWidMax" , 0x9A7},
|
||||
{"FOutLeading" , 0x9A8},
|
||||
{"FOutUnused" , 0x9A9},
|
||||
{"FOutNumer" , 0x9AA},
|
||||
{"FOutDenom" , 0x9AE},
|
||||
{"FMDotsPerInch" , 0x9B2},
|
||||
{"FMStyleTab" , 0x9B6},
|
||||
{"ToolScratch" , 0x9CE},
|
||||
{"WindowList" , 0x9D6},
|
||||
{"SaveUpdate" , 0x9DA},
|
||||
{"PaintWhite" , 0x9DC},
|
||||
{"WMgrPort" , 0x9DE},
|
||||
{"DeskPort" , 0x9E2},
|
||||
{"OldStructure" , 0x9E6},
|
||||
{"OldContent" , 0x9EA},
|
||||
{"GrayRgn" , 0x9EE},
|
||||
{"SaveVisRgn" , 0x9F2},
|
||||
{"DragHook" , 0x9F6},
|
||||
{"TempRect" , 0x9FA},
|
||||
{"OneOne" , 0xA02},
|
||||
{"MinusOne" , 0xA06},
|
||||
{"TopMenuItem" , 0xA0A},
|
||||
{"AtMenuBottom" , 0xA0C},
|
||||
{"IconBitmap" , 0xA0E},
|
||||
{"MenuList" , 0xA1C},
|
||||
{"MBarEnable" , 0xA20},
|
||||
{"CurDeKind" , 0xA22},
|
||||
{"MenuFlash" , 0xA24},
|
||||
{"TheMenu" , 0xA26},
|
||||
{"SavedHandle" , 0xA28},
|
||||
{"MBarHook" , 0xA2C},
|
||||
{"MenuHook" , 0xA30},
|
||||
{"DragPattern" , 0xA34},
|
||||
{"DeskPattern" , 0xA3C},
|
||||
{"DragFlag" , 0xA44},
|
||||
{"CurDragAction" , 0xA46},
|
||||
{"FPState" , 0xA4A},
|
||||
{"TopMapHndl" , 0xA50},
|
||||
{"SysMapHndl" , 0xA54},
|
||||
{"SysMap" , 0xA58},
|
||||
{"CurMap" , 0xA5A},
|
||||
{"ResReadOnly" , 0xA5C},
|
||||
{"ResLoad" , 0xA5E},
|
||||
{"ResErr" , 0xA60},
|
||||
{"TaskLock" , 0xA62},
|
||||
{"FScaleDisable" , 0xA63},
|
||||
{"CurActivate" , 0xA64},
|
||||
{"CurDeactive" , 0xA68},
|
||||
{"DeskHook" , 0xA6C},
|
||||
{"TEDoText" , 0xA70},
|
||||
{"TERecal" , 0xA74},
|
||||
{"ApplScratch" , 0xA78},
|
||||
{"GhostWindow" , 0xA84},
|
||||
{"CloseOrnHook" , 0xA88},
|
||||
{"ResumeProc" , 0xA8C},
|
||||
{"RestProc" , 0xA8C},
|
||||
{"SaveProc" , 0xA90},
|
||||
{"SaveSP" , 0xA94},
|
||||
{"ANumber" , 0xA98},
|
||||
{"ACount" , 0xA9A},
|
||||
{"DABeeper" , 0xA9C},
|
||||
{"DAStrings" , 0xAA0},
|
||||
{"TEScrpLength" , 0xAB0},
|
||||
{"TEScrpHandle" , 0xAB4},
|
||||
{"AppPacks" , 0xAB8},
|
||||
{"SysResName" , 0xAD8},
|
||||
{"SoundGlue" , 0xAE8},
|
||||
{"AppParmHandle" , 0xAEC},
|
||||
{"DSErrCode" , 0xAF0},
|
||||
{"ResErrProc" , 0xAF2},
|
||||
{"TEWdBreak" , 0xAF6},
|
||||
{"DlgFont" , 0xAFA},
|
||||
{"LastTGlobal" , 0xAFC},
|
||||
{"TrapAgain" , 0xB00},
|
||||
{"KeyMVars" , 0xB04},
|
||||
{"ROMMapHndl" , 0xB06},
|
||||
{"PWMBuf1" , 0xB0A},
|
||||
{"BootMask" , 0xB0E},
|
||||
{"WidthPtr" , 0xB10},
|
||||
{"ATalkHk1" , 0xB14},
|
||||
{"LAPMgrPtr" , 0xB18},
|
||||
{"FourDHack" , 0xB1C},
|
||||
{"UnSwitchedFlags" , 0xB20},
|
||||
{"SwitchedFlags" , 0xB21},
|
||||
{"HWCfgFlags" , 0xB22},
|
||||
{"TimeSCSIDB" , 0xB24},
|
||||
{"Top2MenuItem" , 0xB26},
|
||||
{"At2MenuBottom" , 0xB28},
|
||||
{"WidthTabHandle" , 0xB2A},
|
||||
{"SCSIDrvrs" , 0xB2E},
|
||||
{"TimeVars" , 0xB30},
|
||||
{"BtDskRfn" , 0xB34},
|
||||
{"BootTmp8" , 0xB36},
|
||||
{"NTSC" , 0xB3E},
|
||||
{"T1Arbitrate" , 0xB3F},
|
||||
{"JDiskSel" , 0xB40},
|
||||
{"JSendCmd" , 0xB44},
|
||||
{"JDCDReset" , 0xB48},
|
||||
{"LastSPExtra" , 0xB4C},
|
||||
{"FileShareVars" , 0xB50},
|
||||
{"MenuDisable" , 0xB54},
|
||||
{"MBDFHndl" , 0xB58},
|
||||
{"MBSaveLoc" , 0xB5C},
|
||||
{"BNMQHdr" , 0xB60},
|
||||
{"BackgrounderVars" , 0xB64},
|
||||
{"MenuLayer" , 0xB68},
|
||||
{"OmegaSANE" , 0xB6C},
|
||||
{"CarlByte" , 0xB72},
|
||||
{"SystemInfo" , 0xB73},
|
||||
{"VMGlobals" , 0xB78},
|
||||
{"Twitcher2" , 0xB7C},
|
||||
{"RMgrHiVars" , 0xB80},
|
||||
{"HSCHndl" , 0xB84},
|
||||
{"PadRsrc" , 0xB88},
|
||||
{"ResOneDeep" , 0xB9A},
|
||||
{"PadRsrc2" , 0xB9C},
|
||||
{"RomMapInsert" , 0xB9E},
|
||||
{"TmpResLoad" , 0xB9F},
|
||||
{"IntlSpec" , 0xBA0},
|
||||
{"RMgrPerm" , 0xBA4},
|
||||
{"WordRedraw" , 0xBA5},
|
||||
{"SysFontFam" , 0xBA6},
|
||||
{"DefFontSize" , 0xBA8},
|
||||
{"MBarHeight" , 0xBAA},
|
||||
{"TESysJust" , 0xBAC},
|
||||
{"HiHeapMark" , 0xBAE},
|
||||
{"SegHiEnable" , 0xBB2},
|
||||
{"FDevDisable" , 0xBB3},
|
||||
{"CommToolboxGlob" , 0xBB4},
|
||||
{"CMVector" , 0xBB4},
|
||||
{"ShutDwnQHdr" , 0xBBC},
|
||||
{"NewUnused" , 0xBC0},
|
||||
{"LastFOND" , 0xBC2},
|
||||
{"FONDID" , 0xBC6},
|
||||
{"App2Packs" , 0xBC8},
|
||||
{"MAErrProc" , 0xBE8},
|
||||
{"MASuperTab" , 0xBEC},
|
||||
{"MimeGlobs" , 0xBF0},
|
||||
{"FractEnable" , 0xBF4},
|
||||
{"UsedFWidth" , 0xBF5},
|
||||
{"FScaleHFact" , 0xBF6},
|
||||
{"FScaleVFact" , 0xBFA},
|
||||
{"SCCIOPFlag" , 0xBFE},
|
||||
{"MacJmpFlag" , 0xBFF},
|
||||
{"SCSIBase" , 0xC00},
|
||||
{"SCSIDMA" , 0xC04},
|
||||
{"SCSIHsk" , 0xC08},
|
||||
{"SCSIGlobals" , 0xC0C},
|
||||
{"RGBBlack" , 0xC10},
|
||||
{"RGBWhite" , 0xC16},
|
||||
{"FMSynth" , 0xC1C},
|
||||
{"RowBits" , 0xC20},
|
||||
{"ColLines" , 0xC22},
|
||||
{"ScreenBytes" , 0xC24},
|
||||
{"IOPMgrVars" , 0xC28},
|
||||
{"NMIFlag" , 0xC2C},
|
||||
{"VidType" , 0xC2D},
|
||||
{"VidMode" , 0xC2E},
|
||||
{"SCSIPoll" , 0xC2F},
|
||||
{"SEVarBase" , 0xC30},
|
||||
{"MacsBugSP" , 0xC6C},
|
||||
{"MacsBugPC" , 0xC70},
|
||||
{"MacsBugSR" , 0xC74},
|
||||
{"MMUFlags" , 0xCB0},
|
||||
{"MMUType" , 0xCB1},
|
||||
{"MMU32bit" , 0xCB2},
|
||||
{"MachineType" , 0xCB3},
|
||||
{"MMUTbl24" , 0xCB4},
|
||||
{"MMUTbl32" , 0xCB8},
|
||||
{"SInfoPtr" , 0xCBC},
|
||||
{"ASCBase" , 0xCC0},
|
||||
{"SMGlobals" , 0xCC4},
|
||||
{"TheGDevice" , 0xCC8},
|
||||
{"CQDGlobals" , 0xCCC},
|
||||
{"AuxWinHead" , 0xCD0},
|
||||
{"AuxCtlHead" , 0xCD4},
|
||||
{"DeskCPat" , 0xCD8},
|
||||
{"SetOSDefKey" , 0xCDC},
|
||||
{"LastBinPat" , 0xCE0},
|
||||
{"DeskPatEnable" , 0xCE8},
|
||||
{"TimeVIADB" , 0xCEA},
|
||||
{"VIA2Base" , 0xCEC},
|
||||
{"VMVectors" , 0xCF0},
|
||||
{"ADBBase" , 0xCF8},
|
||||
{"WarmStart" , 0xCFC},
|
||||
{"TimeDBRA" , 0xD00},
|
||||
{"TimeSCCDB" , 0xD02},
|
||||
{"SlotQDT" , 0xD04},
|
||||
{"SlotPrTbl" , 0xD08},
|
||||
{"SlotVBLQ" , 0xD0C},
|
||||
{"ScrnVBLPtr" , 0xD10},
|
||||
{"SlotTICKS" , 0xD14},
|
||||
{"PowerMgrVars" , 0xD18},
|
||||
{"AGBHandle" , 0xD1C},
|
||||
{"TableSeed" , 0xD20},
|
||||
{"SRsrcTblPtr" , 0xD24},
|
||||
{"JVBLTask" , 0xD28},
|
||||
{"WMgrCPort" , 0xD2C},
|
||||
{"VertRRate" , 0xD30},
|
||||
{"SynListHandle" , 0xD32},
|
||||
{"LastFore" , 0xD36},
|
||||
{"LastBG" , 0xD3A},
|
||||
{"LastMode" , 0xD3E},
|
||||
{"LastDepth" , 0xD40},
|
||||
{"FMExist" , 0xD42},
|
||||
{"SavedHilite" , 0xD43},
|
||||
{"ShieldDepth" , 0xD4C},
|
||||
{"MenuCInfo" , 0xD50},
|
||||
{"MBProcHndl" , 0xD54},
|
||||
{"MBFlash" , 0xD5C},
|
||||
{"ChunkyDepth" , 0xD60},
|
||||
{"CrsrPtr" , 0xD62},
|
||||
{"PortList" , 0xD66},
|
||||
{"MickeyBytes" , 0xD6A},
|
||||
{"QDErr" , 0xD6E},
|
||||
{"VIA2DT" , 0xD70},
|
||||
{"SInitFlags" , 0xD90},
|
||||
{"DTQueue" , 0xD92},
|
||||
{"DTQFlags" , 0xD92},
|
||||
{"DTskQHdr" , 0xD94},
|
||||
{"DTskQTail" , 0xD98},
|
||||
{"JDTInstall" , 0xD9C},
|
||||
{"HiliteRGB" , 0xDA0},
|
||||
{"OldTimeSCSIDB" , 0xDA6},
|
||||
{"DSCtrAdj" , 0xDA8},
|
||||
{"IconTLAddr" , 0xDAC},
|
||||
{"VideoInfoOK" , 0xDB0},
|
||||
{"EndSRTPtr" , 0xDB4},
|
||||
{"SDMJmpTblPtr" , 0xDB8},
|
||||
{"JSwapMMU" , 0xDBC},
|
||||
{"SdmBusErr" , 0xDC0},
|
||||
{"LastTxGDevice" , 0xDC4},
|
||||
{"PMgrHandle" , 0xDC8},
|
||||
{"LayerPalette" , 0xDCC},
|
||||
{"AddrMapFlags" , 0xDD0},
|
||||
{"UnivROMFlags" , 0xDD4},
|
||||
{"UniversalInfoPtr" , 0xDD8},
|
||||
{"BootGlobPtr" , 0xDDC},
|
||||
{"EgretGlobals" , 0xDE0},
|
||||
{"SaneTrapAddr" , 0xDE4},
|
||||
{"Warhol" , 0xDE8},
|
||||
{"MemVectors24" , 0x1E00},
|
||||
{"Mem2Vectors24" , 0x1EE0},
|
||||
{"Phys2Log" , 0x1EF0},
|
||||
{"RealMemTop" , 0x1EF4},
|
||||
{"PhysMemTop" , 0x1EF8},
|
||||
{"MMFlags" , 0x1EFC},
|
||||
{"MemVectors32" , 0x1F00},
|
||||
{"DrawCrsrVector" , 0x1FB8},
|
||||
{"EraseCrsrVector" , 0x1FBC},
|
||||
{"PSCIntTbl" , 0x1FC0},
|
||||
{"DSPGlobals" , 0x1FC4},
|
||||
{"FP040Vects" , 0x1FC8},
|
||||
{"FPBSUNVec" , 0x1FCC},
|
||||
{"FPUNFLVec" , 0x1FD0},
|
||||
{"FPOPERRVec" , 0x1FD4},
|
||||
{"FPOVFLVec" , 0x1FD8},
|
||||
{"FPSNANVec" , 0x1FDC},
|
||||
{"Mem2Vectors32" , 0x1FE0},
|
||||
{"SCSI2Base" , 0x1FF0},
|
||||
{"LockMemCt" , 0x1FF4},
|
||||
{"DockingGlobals" , 0x1FF8},
|
||||
{"VectorPtr" , 0x2000},
|
||||
{"BasesValid1" , 0x2400},
|
||||
{"BasesValid2" , 0x2404},
|
||||
{"ExtValid1" , 0x2408},
|
||||
{"ExtValid2" , 0x240C},
|
||||
{NULL , 0xFFFF}
|
||||
};
|
32
cxmon/src/mon_lowmem.h
Normal file
32
cxmon/src/mon_lowmem.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* mon_lowmem.h - MacOS low memory globals definitions
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef MON_LOWMEM_H
|
||||
#define MON_LOWMEM_H
|
||||
|
||||
struct lowmem_info {
|
||||
const char *name;
|
||||
uint16 addr;
|
||||
};
|
||||
|
||||
// Array of low memory globals in ascending order
|
||||
extern const lowmem_info lowmem[];
|
||||
|
||||
#endif
|
1129
cxmon/src/mon_ppc.cpp
Normal file
1129
cxmon/src/mon_ppc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
604
cxmon/src/mon_z80.cpp
Normal file
604
cxmon/src/mon_z80.cpp
Normal file
@ -0,0 +1,604 @@
|
||||
/*
|
||||
* mon_z80.cpp - Z80 disassembler
|
||||
*
|
||||
* cxmon (C) 1997-2007 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "sysdeps.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "mon.h"
|
||||
#include "mon_disass.h"
|
||||
|
||||
|
||||
// Addressing modes
|
||||
enum AddrMode {
|
||||
A_IMPL,
|
||||
A_IMM8, // xx
|
||||
A_IMM16, // xxxx
|
||||
A_ABS8, // (xx)
|
||||
A_ABS16, // (xxxx)
|
||||
A_REL, // relative
|
||||
A_A, // a
|
||||
A_HL, // hl or ix or iy
|
||||
A_SP, // sp
|
||||
A_REG1, // 8-bit register (bits 0..2 of opcode) or (hl)/(ix+d)/(iy+d)
|
||||
A_REG1X, // 8-bit register (bits 0..2 of opcode) or (hl)/(ix+d)/(iy+d), don't substitute h or l on prefixes
|
||||
A_REG2, // 8-bit register (bits 3..5 of opcode) or (hl)/(ix+d)/(iy+d)
|
||||
A_REG2X, // 8-bit register (bits 3..5 of opcode) or (hl)/(ix+d)/(iy+d), don't substitute h or l on prefixes
|
||||
A_REG3, // 16-bit register (bits 4..5 of opcode) bc/de/hl/sp
|
||||
A_REG4, // 16-bit register (bits 4..5 of opcode) bc/de/hl/af
|
||||
A_COND, // condition code (bits 3..5 of opcode)
|
||||
A_COND2, // condition code (bits 3..4 of opcode)
|
||||
A_BIT, // bit number (bits 3..5 of opcode)
|
||||
A_BIT_REG1, // bit number (bits 3..5 of opcode) followed by 8-bit register (bits 0..2 of opcode)
|
||||
A_RST, // restart
|
||||
A_BC_IND, // (bc)
|
||||
A_DE_IND, // (de)
|
||||
A_HL_IND, // (hl) or (ix) or (iy)
|
||||
A_XY_IND, // (ix+d) or (iy+d)
|
||||
A_SP_IND, // (sp)
|
||||
A_DE_HL, // de,hl
|
||||
A_AF_AF, // af,af'
|
||||
};
|
||||
|
||||
// Mnemonics
|
||||
enum Mnemonic {
|
||||
M_ADC, M_ADD, M_AND, M_BIT, M_CALL, M_CCF, M_CP, M_CPD, M_CPDR, M_CPI,
|
||||
M_CPIR, M_CPL, M_DAA, M_DEC, M_DI, M_DJNZ, M_EI, M_EX, M_EXX, M_HALT,
|
||||
M_IM0, M_IM1, M_IM2, M_IN, M_INC, M_IND, M_INDR, M_INI, M_INIR, M_JP,
|
||||
M_JR, M_LD, M_LDD, M_LDDR, M_LDI, M_LDIR, M_NEG, M_NOP, M_OR, M_OTDR,
|
||||
M_OTIR, M_OUT, M_OUTD, M_OUTI, M_POP, M_PUSH, M_RES, M_RET, M_RETI,
|
||||
M_RETN, M_RL, M_RLA, M_RLC, M_RLCA, M_RLD, M_RR, M_RRA, M_RRC, M_RRCA,
|
||||
M_RRD, M_RST, M_SBC, M_SCF, M_SET, M_SL1, M_SLA, M_SRA, M_SRL, M_SUB,
|
||||
M_XOR,
|
||||
M_ILLEGAL,
|
||||
|
||||
M_MAXIMUM
|
||||
};
|
||||
|
||||
// Chars for each mnemonic
|
||||
static const char mnem_1[] = "aaabccccccccddddeeehiiiiiiiiijjlllllnnoooooopprrrrrrrrrrrrrrrssssssssx?";
|
||||
static const char mnem_2[] = "ddniacppppppaeijixxammmnnnnnnprdddddeorttuuuoueeeelllllrrrrrsbcellrruo ";
|
||||
static const char mnem_3[] = "cddtlf ddiilac n xl cddii ddiigp ditttpssttt accd accdtcft1aalbr ";
|
||||
static const char mnem_4[] = " l r r z t012 r r r r rr di h in a a ";
|
||||
|
||||
// Mnemonic for each opcode
|
||||
static const Mnemonic mnemonic[256] = {
|
||||
M_NOP , M_LD , M_LD , M_INC , M_INC , M_DEC , M_LD , M_RLCA, // 00
|
||||
M_EX , M_ADD, M_LD , M_DEC , M_INC , M_DEC , M_LD , M_RRCA,
|
||||
M_DJNZ, M_LD , M_LD , M_INC , M_INC , M_DEC , M_LD , M_RLA , // 10
|
||||
M_JR , M_ADD, M_LD , M_DEC , M_INC , M_DEC , M_LD , M_RRA ,
|
||||
M_JR , M_LD , M_LD , M_INC , M_INC , M_DEC , M_LD , M_DAA , // 20
|
||||
M_JR , M_ADD, M_LD , M_DEC , M_INC , M_DEC , M_LD , M_CPL ,
|
||||
M_JR , M_LD , M_LD , M_INC , M_INC , M_DEC , M_LD , M_SCF , // 30
|
||||
M_JR , M_ADD, M_LD , M_DEC , M_INC , M_DEC , M_LD , M_CCF ,
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , // 40
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD ,
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , // 50
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD ,
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , // 60
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD ,
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_HALT, M_LD , // 70
|
||||
M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD , M_LD ,
|
||||
M_ADD , M_ADD, M_ADD, M_ADD , M_ADD , M_ADD , M_ADD , M_ADD , // 80
|
||||
M_ADC , M_ADC, M_ADC, M_ADC , M_ADC , M_ADC , M_ADC , M_ADC ,
|
||||
M_SUB , M_SUB, M_SUB, M_SUB , M_SUB , M_SUB , M_SUB , M_SUB , // 90
|
||||
M_SBC , M_SBC, M_SBC, M_SBC , M_SBC , M_SBC , M_SBC , M_SBC ,
|
||||
M_AND , M_AND, M_AND, M_AND , M_AND , M_AND , M_AND , M_AND , // a0
|
||||
M_XOR , M_XOR, M_XOR, M_XOR , M_XOR , M_XOR , M_XOR , M_XOR ,
|
||||
M_OR , M_OR , M_OR , M_OR , M_OR , M_OR , M_OR , M_OR , // b0
|
||||
M_CP , M_CP , M_CP , M_CP , M_CP , M_CP , M_CP , M_CP ,
|
||||
M_RET , M_POP, M_JP , M_JP , M_CALL, M_PUSH , M_ADD , M_RST , // c0
|
||||
M_RET , M_RET, M_JP , M_ILLEGAL, M_CALL, M_CALL , M_ADC , M_RST ,
|
||||
M_RET , M_POP, M_JP , M_OUT , M_CALL, M_PUSH , M_SUB , M_RST , // d0
|
||||
M_RET , M_EXX, M_JP , M_IN , M_CALL, M_ILLEGAL, M_SBC , M_RST ,
|
||||
M_RET , M_POP, M_JP , M_EX , M_CALL, M_PUSH , M_AND , M_RST , // e0
|
||||
M_RET , M_JP , M_JP , M_EX , M_CALL, M_ILLEGAL, M_XOR , M_RST ,
|
||||
M_RET , M_POP, M_JP , M_DI , M_CALL, M_PUSH , M_OR , M_RST , // f0
|
||||
M_RET , M_LD , M_JP , M_EI , M_CALL, M_ILLEGAL, M_CP , M_RST
|
||||
};
|
||||
|
||||
// Source/destination addressing modes for each opcode
|
||||
#define A(d,s) (((A_ ## d) << 8) | (A_ ## s))
|
||||
|
||||
static const int adr_mode[256] = {
|
||||
A(IMPL,IMPL) , A(REG3,IMM16) , A(BC_IND,A) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , // 00
|
||||
A(AF_AF,IMPL) , A(HL,REG3) , A(A,BC_IND) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,
|
||||
A(REL,IMPL) , A(REG3,IMM16) , A(DE_IND,A) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , // 10
|
||||
A(REL,IMPL) , A(HL,REG3) , A(A,DE_IND) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,
|
||||
A(COND2,REL) , A(REG3,IMM16) , A(ABS16,HL) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , // 20
|
||||
A(COND2,REL) , A(HL,REG3) , A(HL,ABS16) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,
|
||||
A(COND2,REL) , A(REG3,IMM16) , A(ABS16,A) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) , // 30
|
||||
A(COND2,REL) , A(HL,REG3) , A(A,ABS16) , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) , // 40
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) ,
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) , // 50
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) ,
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) , // 60
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) ,
|
||||
A(REG2,REG1X) , A(REG2,REG1X) , A(REG2,REG1X), A(REG2,REG1X), A(REG2,REG1X), A(REG2,REG1X), A(IMPL,IMPL) , A(REG2,REG1X), // 70
|
||||
A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2,REG1) , A(REG2X,REG1), A(REG2,REG1) ,
|
||||
A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , // 80
|
||||
A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) ,
|
||||
A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , // 90
|
||||
A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) , A(A,REG1) ,
|
||||
A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , // a0
|
||||
A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) ,
|
||||
A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , // b0
|
||||
A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) , A(REG1,IMPL) ,
|
||||
A(COND,IMPL) , A(REG4,IMPL) , A(COND,IMM16), A(IMM16,IMPL), A(COND,IMM16), A(REG4,IMPL) , A(A,IMM8) , A(RST,IMPL) , // c0
|
||||
A(COND,IMPL) , A(IMPL,IMPL) , A(COND,IMM16), A(IMPL,IMPL) , A(COND,IMM16), A(IMM16,IMPL), A(A,IMM8) , A(RST,IMPL) ,
|
||||
A(COND,IMPL) , A(REG4,IMPL) , A(COND,IMM16), A(ABS8,A) , A(COND,IMM16), A(REG4,IMPL) , A(IMM8,IMPL) , A(RST,IMPL) , // d0
|
||||
A(COND,IMPL) , A(IMPL,IMPL) , A(COND,IMM16), A(A,ABS8) , A(COND,IMM16), A(IMPL,IMPL) , A(A,IMM8) , A(RST,IMPL) ,
|
||||
A(COND,IMPL) , A(REG4,IMPL) , A(COND,IMM16), A(SP_IND,HL) , A(COND,IMM16), A(REG4,IMPL) , A(IMM8,IMPL) , A(RST,IMPL) , // e0
|
||||
A(COND,IMPL) , A(HL_IND,IMPL), A(COND,IMM16), A(DE_HL,IMPL), A(COND,IMM16), A(IMPL,IMPL) , A(IMM8,IMPL) , A(RST,IMPL) ,
|
||||
A(COND,IMPL) , A(REG4,IMPL) , A(COND,IMM16), A(IMPL,IMPL) , A(COND,IMM16), A(REG4,IMPL) , A(IMM8,IMPL) , A(RST,IMPL) , // f0
|
||||
A(COND,IMPL) , A(SP,HL) , A(COND,IMM16), A(IMPL,IMPL) , A(COND,IMM16), A(IMPL,IMPL) , A(IMM8,IMPL) , A(RST,IMPL)
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* sprintf into a "stream"
|
||||
*/
|
||||
|
||||
struct SFILE {
|
||||
char *buffer;
|
||||
char *current;
|
||||
};
|
||||
|
||||
static int mon_sprintf(SFILE *f, const char *format, ...)
|
||||
{
|
||||
int n;
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
vsprintf(f->current, format, args);
|
||||
f->current += n = strlen(f->current);
|
||||
va_end(args);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Disassemble one instruction, return number of bytes
|
||||
*/
|
||||
|
||||
static const char *reg_name[] = {"b", "c", "d", "e", "h", "l", "*", "a"};
|
||||
static const char *reg_name_ix[] = {"b", "c", "d", "e", "hx", "lx", "*", "a"}; // undoc
|
||||
static const char *reg_name_iy[] = {"b", "c", "d", "e", "hy", "ly", "*", "a"}; // undoc
|
||||
static const char *reg_name_16[] = {"bc", "de", "hl", "sp"};
|
||||
static const char *reg_name_16_2[] = {"bc", "de", "hl", "af"};
|
||||
static const char *cond_name[] = {"nz", "z", "nc", "c", "po", "pe", "p", "m"};
|
||||
|
||||
static void operand(SFILE *f, char mode, uint32 &adr, uint8 op, bool ix, bool iy)
|
||||
{
|
||||
switch (mode) {
|
||||
case A_IMPL:
|
||||
break;
|
||||
|
||||
case A_IMM8:
|
||||
mon_sprintf(f, "$%02x", mon_read_byte(adr)); adr++;
|
||||
break;
|
||||
|
||||
case A_IMM16:
|
||||
mon_sprintf(f, "$%04x", (mon_read_byte(adr + 1) << 8) | mon_read_byte(adr)); adr += 2;
|
||||
break;
|
||||
|
||||
case A_ABS8:
|
||||
mon_sprintf(f, "($%02x)", mon_read_byte(adr)); adr++;
|
||||
break;
|
||||
|
||||
case A_ABS16:
|
||||
mon_sprintf(f, "($%04x)", (mon_read_byte(adr + 1) << 8) | mon_read_byte(adr)); adr += 2;
|
||||
break;
|
||||
|
||||
case A_REL:
|
||||
mon_sprintf(f, "$%04x", (adr + 1 + (int8)mon_read_byte(adr)) & 0xffff); adr++;
|
||||
break;
|
||||
|
||||
case A_A:
|
||||
mon_sprintf(f, "a");
|
||||
break;
|
||||
|
||||
case A_HL:
|
||||
mon_sprintf(f, ix ? "ix" : (iy ? "iy" : "hl"));
|
||||
break;
|
||||
|
||||
case A_SP:
|
||||
mon_sprintf(f, "sp");
|
||||
break;
|
||||
|
||||
case A_REG1:
|
||||
case A_REG1X: {
|
||||
int reg = op & 7;
|
||||
if (reg == 6) {
|
||||
if (ix || iy) {
|
||||
mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++;
|
||||
} else {
|
||||
mon_sprintf(f, "(hl)");
|
||||
}
|
||||
} else if (mode == A_REG1) {
|
||||
mon_sprintf(f, "%s", ix ? reg_name_ix[reg] : (iy ? reg_name_iy[reg] : reg_name[reg]));
|
||||
} else {
|
||||
mon_sprintf(f, "%s", reg_name[reg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case A_REG2:
|
||||
case A_REG2X: {
|
||||
int reg = (op >> 3) & 7;
|
||||
if (reg == 6) {
|
||||
if (ix || iy) {
|
||||
mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++;
|
||||
} else {
|
||||
mon_sprintf(f, "(hl)");
|
||||
}
|
||||
} else if (mode == A_REG2) {
|
||||
mon_sprintf(f, "%s", ix ? reg_name_ix[reg] : (iy ? reg_name_iy[reg] : reg_name[reg]));
|
||||
} else {
|
||||
mon_sprintf(f, "%s", reg_name[reg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case A_REG3: {
|
||||
int reg = (op >> 4) & 3;
|
||||
if (reg == 2 && (ix || iy)) {
|
||||
mon_sprintf(f, ix ? "ix" : "iy");
|
||||
} else {
|
||||
mon_sprintf(f, reg_name_16[reg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case A_REG4: {
|
||||
int reg = (op >> 4) & 3;
|
||||
if (reg == 2 && (ix || iy)) {
|
||||
mon_sprintf(f, ix ? "ix" : "iy");
|
||||
} else {
|
||||
mon_sprintf(f, reg_name_16_2[reg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case A_COND:
|
||||
mon_sprintf(f, cond_name[(op >> 3) & 7]);
|
||||
break;
|
||||
|
||||
case A_COND2:
|
||||
mon_sprintf(f, cond_name[(op >> 3) & 3]);
|
||||
break;
|
||||
|
||||
case A_BIT:
|
||||
mon_sprintf(f, "%d", (op >> 3) & 7);
|
||||
break;
|
||||
|
||||
case A_BIT_REG1: { // undoc
|
||||
int reg = op & 7;
|
||||
if (reg == 6) {
|
||||
mon_sprintf(f, "%d", (op >> 3) & 7);
|
||||
} else {
|
||||
mon_sprintf(f, "%d,%s", (op >> 3) & 7, reg_name[reg]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case A_RST:
|
||||
mon_sprintf(f, "$%02x", op & 0x38);
|
||||
break;
|
||||
|
||||
case A_BC_IND:
|
||||
mon_sprintf(f, "(bc)");
|
||||
break;
|
||||
|
||||
case A_DE_IND:
|
||||
mon_sprintf(f, "(de)");
|
||||
break;
|
||||
|
||||
case A_HL_IND:
|
||||
mon_sprintf(f, ix ? "(ix)" : (iy ? "(iy)" : "(hl)"));
|
||||
break;
|
||||
|
||||
case A_XY_IND: // undoc
|
||||
mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++;
|
||||
break;
|
||||
|
||||
case A_SP_IND:
|
||||
mon_sprintf(f, "(sp)");
|
||||
break;
|
||||
|
||||
case A_DE_HL:
|
||||
mon_sprintf(f, "de,hl");
|
||||
break;
|
||||
|
||||
case A_AF_AF:
|
||||
mon_sprintf(f, "af,af'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int print_instr(SFILE *f, Mnemonic mnem, AddrMode dst_mode, AddrMode src_mode, uint32 adr, uint8 op, bool ix, bool iy)
|
||||
{
|
||||
uint32 orig_adr = adr;
|
||||
|
||||
// Print mnemonic
|
||||
mon_sprintf(f, "%c%c%c%c ", mnem_1[mnem], mnem_2[mnem], mnem_3[mnem], mnem_4[mnem]);
|
||||
|
||||
// Print destination operand
|
||||
operand(f, dst_mode, adr, op, ix, iy);
|
||||
|
||||
// Print source operand
|
||||
if (src_mode != A_IMPL)
|
||||
mon_sprintf(f, ",");
|
||||
operand(f, src_mode, adr, op, ix, iy);
|
||||
|
||||
return adr - orig_adr;
|
||||
}
|
||||
|
||||
static int disass_cb(SFILE *f, uint32 adr, bool ix, bool iy)
|
||||
{
|
||||
int num;
|
||||
|
||||
// Fetch opcode
|
||||
uint8 op;
|
||||
if (ix || iy) {
|
||||
op = mon_read_byte(adr + 1);
|
||||
num = 2;
|
||||
} else {
|
||||
op = mon_read_byte(adr);
|
||||
num = 1;
|
||||
}
|
||||
|
||||
// Decode mnemonic and addressing modes
|
||||
Mnemonic mnem = M_ILLEGAL;
|
||||
AddrMode dst_mode = A_IMPL, src_mode = A_IMPL;
|
||||
|
||||
switch (op & 0xc0) {
|
||||
case 0x00:
|
||||
dst_mode = A_REG1X;
|
||||
if ((ix || iy) && ((op & 7) != 6))
|
||||
src_mode = A_XY_IND;
|
||||
switch ((op >> 3) & 7) {
|
||||
case 0: mnem = M_RLC; break;
|
||||
case 1: mnem = M_RRC; break;
|
||||
case 2: mnem = M_RL; break;
|
||||
case 3: mnem = M_RR; break;
|
||||
case 4: mnem = M_SLA; break;
|
||||
case 5: mnem = M_SRA; break;
|
||||
case 6: mnem = M_SL1; break; // undoc
|
||||
case 7: mnem = M_SRL; break;
|
||||
}
|
||||
break;
|
||||
case 0x40:
|
||||
mnem = M_BIT; dst_mode = A_BIT;
|
||||
if (ix || iy)
|
||||
src_mode = A_XY_IND;
|
||||
else
|
||||
src_mode = A_REG1;
|
||||
break;
|
||||
case 0x80:
|
||||
mnem = M_RES;
|
||||
if (ix || iy) {
|
||||
dst_mode = A_BIT_REG1;
|
||||
src_mode = A_XY_IND;
|
||||
} else {
|
||||
dst_mode = A_BIT;
|
||||
src_mode = A_REG1;
|
||||
}
|
||||
break;
|
||||
case 0xc0:
|
||||
mnem = M_SET;
|
||||
if (ix || iy) {
|
||||
dst_mode = A_BIT_REG1;
|
||||
src_mode = A_XY_IND;
|
||||
} else {
|
||||
dst_mode = A_BIT;
|
||||
src_mode = A_REG1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Print instruction
|
||||
print_instr(f, mnem, dst_mode, src_mode, adr, op, ix, iy);
|
||||
return num;
|
||||
}
|
||||
|
||||
static int disass_ed(SFILE *f, uint32 adr)
|
||||
{
|
||||
// Fetch opcode
|
||||
uint8 op = mon_read_byte(adr);
|
||||
|
||||
// Decode mnemonic and addressing modes
|
||||
Mnemonic mnem;
|
||||
AddrMode dst_mode = A_IMPL, src_mode = A_IMPL;
|
||||
|
||||
switch (op) {
|
||||
case 0x40:
|
||||
case 0x48:
|
||||
case 0x50:
|
||||
case 0x58:
|
||||
case 0x60:
|
||||
case 0x68:
|
||||
case 0x78:
|
||||
mon_sprintf(f, "in %s,(c)", reg_name[(op >> 3) & 7]);
|
||||
return 1;
|
||||
case 0x70:
|
||||
mon_sprintf(f, "in (c)");
|
||||
return 1;
|
||||
|
||||
case 0x41:
|
||||
case 0x49:
|
||||
case 0x51:
|
||||
case 0x59:
|
||||
case 0x61:
|
||||
case 0x69:
|
||||
case 0x79:
|
||||
mon_sprintf(f, "out (c),%s", reg_name[(op >> 3) & 7]);
|
||||
return 1;
|
||||
case 0x71: // undoc
|
||||
mon_sprintf(f, "out (c),0");
|
||||
return 1;
|
||||
|
||||
case 0x42:
|
||||
case 0x52:
|
||||
case 0x62:
|
||||
case 0x72:
|
||||
mnem = M_SBC; dst_mode = A_HL; src_mode = A_REG3;
|
||||
break;
|
||||
|
||||
case 0x43:
|
||||
case 0x53:
|
||||
case 0x63:
|
||||
case 0x73:
|
||||
mnem = M_LD; dst_mode = A_ABS16; src_mode = A_REG3;
|
||||
break;
|
||||
|
||||
case 0x4a:
|
||||
case 0x5a:
|
||||
case 0x6a:
|
||||
case 0x7a:
|
||||
mnem = M_ADC; dst_mode = A_HL; src_mode = A_REG3;
|
||||
break;
|
||||
|
||||
case 0x4b:
|
||||
case 0x5b:
|
||||
case 0x6b:
|
||||
case 0x7b:
|
||||
mnem = M_LD; dst_mode = A_REG3; src_mode = A_ABS16;
|
||||
break;
|
||||
|
||||
case 0x44:
|
||||
case 0x4c: // undoc
|
||||
case 0x54: // undoc
|
||||
case 0x5c: // undoc
|
||||
case 0x64: // undoc
|
||||
case 0x6c: // undoc
|
||||
case 0x74: // undoc
|
||||
case 0x7c: // undoc
|
||||
mnem = M_NEG;
|
||||
break;
|
||||
|
||||
case 0x45:
|
||||
case 0x55: // undoc
|
||||
case 0x5d: // undoc
|
||||
case 0x65: // undoc
|
||||
case 0x6d: // undoc
|
||||
case 0x75: // undoc
|
||||
case 0x7d: // undoc
|
||||
mnem = M_RETN;
|
||||
break;
|
||||
case 0x4d: mnem = M_RETI; break;
|
||||
|
||||
case 0x46:
|
||||
case 0x4e: // undoc
|
||||
case 0x66: // undoc
|
||||
case 0x6e: // undoc
|
||||
mnem = M_IM0;
|
||||
break;
|
||||
case 0x56:
|
||||
case 0x76: // undoc
|
||||
mnem = M_IM1;
|
||||
break;
|
||||
case 0x5e:
|
||||
case 0x7e: // undoc
|
||||
mnem = M_IM2;
|
||||
break;
|
||||
|
||||
case 0x47:
|
||||
mon_sprintf(f, "ld i,a");
|
||||
return 1;
|
||||
case 0x4f:
|
||||
mon_sprintf(f, "ld r,a");
|
||||
return 1;
|
||||
case 0x57:
|
||||
mon_sprintf(f, "ld a,i");
|
||||
return 1;
|
||||
case 0x5f:
|
||||
mon_sprintf(f, "ld a,r");
|
||||
return 1;
|
||||
|
||||
case 0x67: mnem = M_RRD; break;
|
||||
case 0x6f: mnem = M_RLD; break;
|
||||
|
||||
case 0xa0: mnem = M_LDI; break;
|
||||
case 0xa1: mnem = M_CPI; break;
|
||||
case 0xa2: mnem = M_INI; break;
|
||||
case 0xa3: mnem = M_OUTI; break;
|
||||
case 0xa8: mnem = M_LDD; break;
|
||||
case 0xa9: mnem = M_CPD; break;
|
||||
case 0xaa: mnem = M_IND; break;
|
||||
case 0xab: mnem = M_OUTD; break;
|
||||
case 0xb0: mnem = M_LDIR; break;
|
||||
case 0xb1: mnem = M_CPIR; break;
|
||||
case 0xb2: mnem = M_INIR; break;
|
||||
case 0xb3: mnem = M_OTIR; break;
|
||||
case 0xb8: mnem = M_LDDR; break;
|
||||
case 0xb9: mnem = M_CPDR; break;
|
||||
case 0xba: mnem = M_INDR; break;
|
||||
case 0xbb: mnem = M_OTDR; break;
|
||||
|
||||
default:
|
||||
mnem = M_NOP;
|
||||
break;
|
||||
}
|
||||
|
||||
// Print instruction
|
||||
return print_instr(f, mnem, dst_mode, src_mode, adr + 1, op, false, false) + 1;
|
||||
}
|
||||
|
||||
static int disass(SFILE *f, uint32 adr, bool ix, bool iy)
|
||||
{
|
||||
uint8 op = mon_read_byte(adr);
|
||||
if (op == 0xcb)
|
||||
return disass_cb(f, adr + 1, ix, iy) + 1;
|
||||
else
|
||||
return print_instr(f, mnemonic[op], AddrMode(adr_mode[op] >> 8), AddrMode(adr_mode[op] & 0xff), adr + 1, op, ix, iy) + 1;
|
||||
}
|
||||
|
||||
int disass_z80(FILE *f, uint32 adr)
|
||||
{
|
||||
int num;
|
||||
char buf[64];
|
||||
SFILE sfile = {buf, buf};
|
||||
|
||||
switch (mon_read_byte(adr)) {
|
||||
case 0xdd: // ix prefix
|
||||
num = disass(&sfile, adr + 1, true, false) + 1;
|
||||
break;
|
||||
case 0xed:
|
||||
num = disass_ed(&sfile, adr + 1) + 1;
|
||||
break;
|
||||
case 0xfd: // iy prefix
|
||||
num = disass(&sfile, adr + 1, false, true) + 1;
|
||||
break;
|
||||
default:
|
||||
num = disass(&sfile, adr, false, false);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i=0; i<4; i++) {
|
||||
if (num > i)
|
||||
fprintf(f, "%02x ", mon_read_byte(adr + i));
|
||||
else
|
||||
fprintf(f, " ");
|
||||
}
|
||||
|
||||
fprintf(f, "\t%s\n", buf);
|
||||
return num;
|
||||
}
|
96
cxmon/src/sysdeps.h
Normal file
96
cxmon/src/sysdeps.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* sysdeps.h - System dependent definitions
|
||||
*
|
||||
* cxmon (C) 1997-2004 Christian Bauer, Marc Hellwig
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SYSDEPS_H
|
||||
#define SYSDEPS_H
|
||||
|
||||
#ifndef __STDC__
|
||||
#error "Your compiler is not ANSI. Get a real one."
|
||||
#endif
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef STDC_HEADERS
|
||||
#error "You don't have ANSI C header files."
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <sys/types.h>
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/* Data types */
|
||||
|
||||
#ifdef __BEOS__
|
||||
|
||||
#include <support/ByteOrder.h>
|
||||
|
||||
#else
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef signed char int8;
|
||||
#if SIZEOF_SHORT == 2
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
#elif SIZEOF_INT == 2
|
||||
typedef unsigned int uint16;
|
||||
typedef int int16;
|
||||
#else
|
||||
#error "No 2 byte type, you lose."
|
||||
#endif
|
||||
#if SIZEOF_INT == 4
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
#elif SIZEOF_LONG == 4
|
||||
typedef unsigned long uint32;
|
||||
typedef long int32;
|
||||
#else
|
||||
#error "No 4 byte type, you lose."
|
||||
#endif
|
||||
#if SIZEOF_LONG == 8
|
||||
typedef unsigned long uint64;
|
||||
typedef long int64;
|
||||
#define VAL64(a) (a ## l)
|
||||
#define UVAL64(a) (a ## ul)
|
||||
#elif SIZEOF_LONG_LONG == 8
|
||||
typedef unsigned long long uint64;
|
||||
typedef long long int64;
|
||||
#define VAL64(a) (a ## LL)
|
||||
#define UVAL64(a) (a ## uLL)
|
||||
#else
|
||||
#error "No 8 byte type, you lose."
|
||||
#endif
|
||||
#if SIZEOF_VOID_P == 4
|
||||
typedef uint32 uintptr;
|
||||
typedef int32 intptr;
|
||||
#elif SIZEOF_VOID_P == 8
|
||||
typedef uint64 uintptr;
|
||||
typedef int64 intptr;
|
||||
#else
|
||||
#error "Unsupported size of pointer"
|
||||
#endif
|
||||
|
||||
#endif // def __BEOS__
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user