Backport SDL from GSplus

This commit is contained in:
David Schmidt 2019-02-09 15:34:41 -05:00
parent 3e26fb1ecd
commit e919ee8352
70 changed files with 29538 additions and 20006 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
/.project
/GSport.app
/gsport
.DS_Store

View File

@ -1,12 +1,12 @@
# GSport central makefile - you need a 'vars' file linked/copied from a 'vars_xxx' template to build.
OBJECTS1 = adb.o clock.o config.o dis.o engine_c.o scc.o iwm.o \
joystick_driver.o moremem.o paddles.o parallel.o printer.o \
sim65816.o smartport.o sound.o sound_driver.o video.o \
scc_socket_driver.o imagewriter.o scc_imagewriter.o scc_llap.o
OBJECTS1 = adb.o clock.o config.o debug.o dis.o engine_c.o scc.o iwm.o \
joystick_driver.o moremem.o paddles.o parallel.o printer.o sim65816.o \
smartport.o sound.o sound_driver.o video.o scc_socket_driver.o glog.o \
imagewriter.o scc_imagewriter.o scc_llap.o options.o
ATOBJ = atbridge/aarp.o atbridge/atbridge.o atbridge/elap.o atbridge/llap.o atbridge/port.o
PCAPOBJ = atbridge/pcap_delay.o
TFEOBJ = tfe/tfe.o tfe/tfearch.o tfe/tfesupp.o
FSTOBJ = unix_host_common.o host_common.o host_fst.o host_mli.o
include vars
@ -25,68 +25,51 @@ clean:
- rm -f compile_time.o
- rm -f 8inst_c.h
- rm -f 16inst_c.h
- rm -rf ../GSport.app
- rm -rf ../GSportDmg
specials: 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s
specials_clean:
rm -f 8inst_s 16inst_s 8size 16size 8inst_c 16inst_c size_c size_s
# Linux/OSX/RPi SDL builds
gsport: $(OBJECTS) compile_time.o
$(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS)
echo $(OBJECTS)
cp gsport ..
# Mac builds:
gsportmac: $(OBJECTS) compile_time.o
$(CC) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o gsport $(EXTRA_LIBS)
mkdir -p ../GSport.app/Contents/Resources/English.lproj/main.nib
mkdir -p ../GSport.app/Contents/MacOS
mv gsport ../GSport.app/Contents/MacOS/GSport
echo "APPL????" > ../GSport.app/Contents/PkgInfo
cp -f arch/mac/Info.plist ../GSport.app/Contents/
cp -f arch/mac/info.nib ../GSport.app/Contents/Resources/English.lproj/main.nib
cp -f arch/mac/classes.nib ../GSport.app/Contents/Resources/English.lproj/main.nib
cp -f arch/mac/objects.xib ../GSport.app/Contents/Resources/English.lproj/main.nib
cp -f arch/mac/gsporticon.icns ../GSport.app/Contents/Resources/
cp -f arch/mac/525.icns ../GSport.app/Contents/Resources/
cp -f arch/mac/2mg.icns ../GSport.app/Contents/Resources/
touch '../GSport.app/Icon?'
rm -rf ../GSportDmg
mkdir ../GSportDmg
mkdir ../GSportDmg/GSport
cp ../LICENSE ../GSportDmg/GSport
cp -f parallel.rom ../GSportDmg/GSport
cp -f ../lib/NoBoot.po ../GSportDmg/GSport
mv ../GSport.app ../GSportDmg/GSport
cp -f ../config.template ../GSportDmg/GSport/config.txt
cp ../GSport.html ../GSportDmg/GSport/GSport.html
arch/mac/makedmg.sh .. GSportDmg GSport GSport 7
# Linux for X builds:
# Linux/OSX XWindows builds
gsportx: $(OBJECTS) compile_time.o
$(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(XLIBS) $(EXTRA_LIBS) -lX11
echo $(OBJECTS)
mv gsportx ..
cp -f ../config.template ../config.txt
# NOT CURRENTLY SUPPORTED
# Linux framebuffer builds:
gsportfb: $(OBJECTS) compile_time.o
$(LD) $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS)
echo $(OBJECTS)
mv gsportfb ..
cp -f ../config.template ../config.txt
# Mingw32 (native windows) builds:
gsport.exe: $(OBJECTS) compile_time.o
# Mingw32 / Cygwin builds: The Win32 API version
gsport32.exe: $(OBJECTS) compile_time.o
g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32
mkdir -p ../GSport.app/lib
cp -f gsport.exe ../GSport.app/GSport.exe
cp -f ../config.template ../GSport.app/config.txt
cp -f ../lib/*.ttf ../GSport.app/lib
cp -f ../lib/arch/win32/*.dll ../GSport.app
cp -f ../lib/NoBoot.po ../GSport.app
cp -f GSport.bat ../GSport.app/GSport.bat
cp -f parallel.rom ../GSport.app
cp -f ../LICENSE ../GSport.app
cp -f ../GSport.html ../GSport.app
#mkdir -p ../GSport.app/lib
#cp -f gsport.exe ../GSport.app/GSport.exe
#cp -f ../config.template ../GSport.app/config.txt
#cp -f ../lib/*.ttf ../GSport.app/lib
#cp -f ../lib/arch/win32/*.dll ../GSport.app
#cp -f ../lib/NoBoot.po ../GSport.app
#cp -f GSport.bat ../GSport.app/GSport.bat
#cp -f parallel.rom ../GSport.app
#cp -f ../COPYING.txt ../GSport.app
cp gsport32.exe ..
# Mingw32 / Cygwin builds: The SDL version (builds, but non-functioning)
gsport.exe: $(OBJECTS) compile_time.o
#g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32
#g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -mwindows
g++ $(CCOPTS) $(LDOPTS) $(OBJECTS) compile_time.o $(LDFLAGS) -o $(NAME)$(SUFFIX) $(EXTRA_LIBS) -lwinmm -lgdi32 -ldsound -lcomctl32 -lws2_32 -lshell32
cp gsport.exe ..
8inst_c.h: instable.h
$(PERL) make_inst c 8 instable.h > 8inst_c.h

312
src/adb.c
View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2013 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -22,8 +23,10 @@
/* adb_mode bit 3 and bit 2 (faster repeats for arrows and space/del) not done*/
#include "adb.h"
#include "glog.h"
int g_fullscreen = 0;
int g_grabmouse = 0;
extern int Verbose;
extern word32 g_vbl_count;
@ -38,9 +41,9 @@ extern int g_invert_paddles;
extern int g_joystick_type;
extern int g_a2vid_palette;
extern int g_config_control_panel;
extern int g_screenshot_requested;
extern word32 g_cfg_vbl_count;
extern double g_cur_dcycs;
extern byte *g_slow_memory_ptr;
extern byte *g_memory_ptr;
extern word32 g_mem_size_total;
@ -112,9 +115,13 @@ STRUCT(Mouse_fifo) {
int x;
int y;
int buttons;
int delta_x;
int delta_y;
int dxrd;
int dyrd;
};
Mouse_fifo g_mouse_fifo[ADB_MOUSE_FIFO] = { { 0, 0, 0, 0 } };
Mouse_fifo g_mouse_fifo[ADB_MOUSE_FIFO] = { { 0, 0, 0, 0, 0, 0 ,0 ,0} };
int g_mouse_warp_x = 0;
int g_mouse_warp_y = 0;
@ -164,9 +171,7 @@ int g_kbd_reg3_16bit = 0x602; /* also set in adb_reset()! */
int g_adb_init = 0;
void
adb_init()
{
void adb_init() {
int keycode;
int i;
@ -178,8 +183,7 @@ adb_init()
for(i = 0; i < 128; i++) {
keycode = a2_key_to_ascii[i][0];
if(keycode != i) {
printf("ADB keycode lost/skipped: i=%x: keycode=%x\n",
i, keycode);
glogf("ADB keycode lost/skipped: i=%x: keycode=%x", i, keycode);
my_exit(1);
}
}
@ -198,14 +202,11 @@ adb_init()
}
// OG Added adb_shut()
void adb_shut()
{
void adb_shut() {
g_adb_init = 0;
}
void
adb_reset()
{
void adb_reset() {
g_c027_val = 0;
@ -243,9 +244,7 @@ STRUCT(Adb_log) {
Adb_log g_adb_log[LEN_ADB_LOG];
int g_adb_log_pos = 0;
void
adb_log(word32 addr, int val)
{
void adb_log(word32 addr, int val) {
int pos;
pos = g_adb_log_pos;
@ -259,9 +258,7 @@ adb_log(word32 addr, int val)
g_adb_log_pos = pos;
}
void
show_adb_log(void)
{
void show_adb_log(void) {
int pos;
int i;
@ -283,9 +280,7 @@ show_adb_log(void)
g_adb_state, g_adb_interrupt_byte);
}
void
adb_error(void)
{
void adb_error(void) {
halt_printf("Adb Error\n");
show_adb_log();
@ -293,9 +288,7 @@ adb_error(void)
void
adb_add_kbd_srq()
{
void adb_add_kbd_srq() {
if(g_kbd_reg3_16bit & 0x200) {
/* generate SRQ */
g_adb_interrupt_byte |= 0x08;
@ -305,47 +298,35 @@ adb_add_kbd_srq()
}
}
void
adb_clear_kbd_srq()
{
void adb_clear_kbd_srq() {
remove_irq(IRQ_PENDING_ADB_KBD_SRQ);
/* kbd SRQ's are the only ones to handle now, so just clean it out */
g_adb_interrupt_byte &= (~(0x08));
}
void
adb_add_data_int()
{
void adb_add_data_int() {
if(g_c027_val & ADB_C027_DATA_INT) {
add_irq(IRQ_PENDING_ADB_DATA);
}
}
void
adb_add_mouse_int()
{
void adb_add_mouse_int() {
if(g_c027_val & ADB_C027_MOUSE_INT) {
add_irq(IRQ_PENDING_ADB_MOUSE);
}
}
void
adb_clear_data_int()
{
void adb_clear_data_int() {
remove_irq(IRQ_PENDING_ADB_DATA);
}
void
adb_clear_mouse_int()
{
void adb_clear_mouse_int() {
remove_irq(IRQ_PENDING_ADB_MOUSE);
}
void
adb_send_bytes(int num_bytes, word32 val0, word32 val1, word32 val2)
{
void adb_send_bytes(int num_bytes, word32 val0, word32 val1, word32 val2) {
word32 val;
int shift_amount;
int i;
@ -374,9 +355,7 @@ adb_send_bytes(int num_bytes, word32 val0, word32 val1, word32 val2)
}
void
adb_send_1byte(word32 val)
{
void adb_send_1byte(word32 val) {
if(g_adb_data_pending != 0) {
halt_printf("g_adb_data_pending: %d\n", g_adb_data_pending);
@ -387,9 +366,7 @@ adb_send_1byte(word32 val)
void
adb_response_packet(int num_bytes, word32 val)
{
void adb_response_packet(int num_bytes, word32 val) {
if(g_adb_data_pending != 0) {
halt_printf("adb_response_packet, but pending: %d\n",
@ -415,9 +392,7 @@ adb_response_packet(int num_bytes, word32 val)
}
void
adb_kbd_reg0_data(int a2code, int is_up)
{
void adb_kbd_reg0_data(int a2code, int is_up) {
if(g_kbd_reg0_pos >= MAX_ADB_KBD_REG3) {
/* too many keys, toss */
halt_printf("Had to toss key: %02x, %d\n", a2code, is_up);
@ -434,9 +409,7 @@ adb_kbd_reg0_data(int a2code, int is_up)
adb_add_kbd_srq();
}
void
adb_kbd_talk_reg0()
{
void adb_kbd_talk_reg0() {
word32 val0, val1;
word32 reg;
int num_bytes;
@ -484,9 +457,7 @@ adb_kbd_talk_reg0()
}
}
void
adb_set_config(word32 val0, word32 val1, word32 val2)
{
void adb_set_config(word32 val0, word32 val1, word32 val2) {
int new_mouse;
int new_kbd;
int tmp1;
@ -494,14 +465,12 @@ adb_set_config(word32 val0, word32 val1, word32 val2)
new_mouse = val0 >> 4;
new_kbd = val0 & 0xf;
if(new_mouse != g_mouse_ctl_addr) {
printf("ADB config: mouse from %x to %x!\n",
g_mouse_ctl_addr, new_mouse);
glogf("ADB config: mouse from %x to %x!", g_mouse_ctl_addr, new_mouse);
adb_error();
g_mouse_ctl_addr = new_mouse;
}
if(new_kbd != g_kbd_ctl_addr) {
printf("ADB config: kbd from %x to %x!\n",
g_kbd_ctl_addr, new_kbd);
glogf("ADB config: kbd from %x to %x!", g_kbd_ctl_addr, new_kbd);
adb_error();
g_kbd_ctl_addr = new_kbd;
}
@ -560,11 +529,9 @@ adb_set_config(word32 val0, word32 val1, word32 val2)
}
void
adb_set_new_mode(word32 val)
{
void adb_set_new_mode(word32 val) {
if(val & 0x03) {
printf("Disabling keyboard/mouse:%02x!\n", val);
glogf("Disabling keyboard/mouse:%02x!", val);
}
if(val & 0xa2) {
@ -576,9 +543,7 @@ adb_set_new_mode(word32 val)
}
int
adb_read_c026()
{
int adb_read_c026() {
word32 ret;
int i;
@ -632,9 +597,7 @@ adb_read_c026()
}
void
adb_write_c026(int val)
{
void adb_write_c026(int val) {
word32 tmp;
int dev;
@ -835,9 +798,7 @@ adb_write_c026(int val)
return;
}
void
do_adb_cmd()
{
void do_adb_cmd() {
int dev;
int new_kbd;
int addr;
@ -969,9 +930,7 @@ do_adb_cmd()
}
int
adb_read_c027()
{
int adb_read_c027() {
word32 ret;
if(halt_on_all_c027) {
@ -1011,9 +970,7 @@ adb_read_c027()
return ret;
}
void
adb_write_c027(int val)
{
void adb_write_c027(int val) {
word32 old_val;
word32 new_int;
word32 old_int;
@ -1045,9 +1002,7 @@ adb_write_c027(int val)
return;
}
int
read_adb_ram(word32 addr)
{
int read_adb_ram(word32 addr) {
int val;
adb_printf("Reading adb ram addr: %02x\n", addr);
@ -1085,9 +1040,7 @@ read_adb_ram(word32 addr)
return val;
}
void
write_adb_ram(word32 addr, int val)
{
void write_adb_ram(word32 addr, int val) {
adb_printf("Writing adb_ram addr: %02x: %02x\n", addr, val);
@ -1099,9 +1052,7 @@ write_adb_ram(word32 addr, int val)
}
}
int
adb_get_keypad_xy(int get_y)
{
int adb_get_keypad_xy(int get_y) {
int x, y;
int key;
int num_keys;
@ -1135,9 +1086,21 @@ adb_get_keypad_xy(int get_y)
}
}
int
update_mouse(int x, int y, int button_states, int buttons_valid)
{
// stub in a wrapper to experiment with full delta movement
int g_delta_x = 0;
int g_delta_y = 0;
int update_mouse_w_delta(int x, int y, int button_states, int buttons_valid, int delta_x, int delta_y) {
g_delta_x = delta_x;
g_delta_y = delta_y;
//glogf("dx: %d dy: %d but: %02x", delta_x, delta_y, button_states);
int ret = 0;
ret = update_mouse(x,y,button_states,buttons_valid);
g_delta_x = 0;
g_delta_y = 0;
return ret;
}
int update_mouse(int x, int y, int button_states, int buttons_valid) {
double dcycs;
int button1_changed;
int mouse_moved;
@ -1210,29 +1173,32 @@ update_mouse(int x, int y, int button_states, int buttons_valid)
g_mouse_warp_x, g_mouse_warp_y, g_mouse_fifo[0].x,
g_mouse_fifo[0].y, g_mouse_a2_x, g_mouse_a2_y);
#endif
mouse_moved = (g_mouse_fifo[0].x != x) || (g_mouse_fifo[0].y != y);
if (!g_grabmouse) {
mouse_moved = ((g_mouse_fifo[0].x != x) || (g_mouse_fifo[0].y != y));
}
g_mouse_a2_x += g_mouse_warp_x;
g_mouse_a2_y += g_mouse_warp_y;
g_mouse_fifo[0].x = x;
g_mouse_fifo[0].y = y;
g_mouse_fifo[0].dcycs = dcycs;
g_mouse_fifo[0].delta_x = g_delta_x;
g_mouse_fifo[0].delta_y = g_delta_y;
g_mouse_warp_x = 0;
g_mouse_warp_y = 0;
button1_changed = (buttons_valid & 1) &&
((button_states & 1) != (g_mouse_fifo[0].buttons & 1));
((button_states & 1) != (g_mouse_fifo[0].buttons & 1)); //<- make sure fifo doesn't already have pending change to this state
if((button_states & 4) && !(g_mouse_fifo[0].buttons & 4) &&
(buttons_valid & 4)) {
/* right button pressed */
if((button_states & 4) && !(g_mouse_fifo[0].buttons & 4) && // fifo check why?
(buttons_valid & 4)) { // right button pressed
adb_increment_speed();
}
if((button_states & 2) && !(g_mouse_fifo[0].buttons & 2) &&
if((button_states & 2) && !(g_mouse_fifo[0].buttons & 2) && // fifo check why?
(buttons_valid & 2)) {
/* middle button pressed */
halt2_printf("Middle button pressed\n");
adb_increment_speed(); // middle button pressed
//halt2_printf("Middle button pressed\n");
}
pos = g_mouse_fifo_pos;
@ -1245,10 +1211,15 @@ update_mouse(int x, int y, int button_states, int buttons_valid)
g_mouse_fifo[i + 1] = g_mouse_fifo[i]; /* copy struct*/
}
g_mouse_fifo_pos = pos + 1;
}
}
g_mouse_fifo[0].buttons = (button_states & buttons_valid) |
(g_mouse_fifo[0].buttons & ~buttons_valid);
if (g_grabmouse) {
if (pos > 0) {
mouse_moved = (g_mouse_fifo[0].delta_x || g_mouse_fifo[0].delta_y );
}
}
if(mouse_moved || button1_changed) {
if( (g_mouse_ctl_addr == g_mouse_dev_addr) &&
@ -1261,9 +1232,8 @@ update_mouse(int x, int y, int button_states, int buttons_valid)
return mouse_moved;
}
int
mouse_read_c024(double dcycs)
{
int mouse_read_c024(double dcycs) {
word32 ret;
word32 tool_start;
int em_active;
@ -1289,6 +1259,10 @@ mouse_read_c024(double dcycs)
mouse_button = (g_mouse_fifo[pos].buttons & 1);
delta_x = target_x - g_mouse_a2_x;
delta_y = target_y - g_mouse_a2_y;
if (g_grabmouse) {
delta_x = g_mouse_fifo[pos].delta_x;
delta_y = g_mouse_fifo[pos].delta_y;
}
clamped = 0;
if(delta_x > 0x3f) {
@ -1316,9 +1290,13 @@ mouse_read_c024(double dcycs)
if(g_adb_mouse_coord) {
/* y coord */
delta_x = 0; /* clear unneeded x delta */
delta_x = 0; // clear unneeded x delta
g_mouse_fifo[pos].dyrd = 1; // flag y delta as read
g_mouse_fifo[pos].delta_y = 0; // clear y delta
} else {
delta_y = 0; /* clear unneeded y delta */
delta_y = 0; // clear unneeded y delta
g_mouse_fifo[pos].dxrd = 1; // flag x delta as read
g_mouse_fifo[pos].delta_x = 0; // clear x delta
}
@ -1392,10 +1370,17 @@ mouse_read_c024(double dcycs)
g_mouse_a2_x = a2_x;
g_mouse_a2_y = a2_y;
if(g_mouse_fifo_pos) {
if (!g_grabmouse) {
if((target_x == a2_x) && (target_y == a2_y) &&
(g_mouse_a2_button == mouse_button)) {
g_mouse_fifo_pos--;
}
} else {
if(g_mouse_fifo[pos].dxrd && g_mouse_fifo[pos].dyrd
&& (g_mouse_a2_button == mouse_button)) {
g_mouse_fifo_pos--;
}
}
}
@ -1408,20 +1393,27 @@ mouse_read_c024(double dcycs)
g_slow_memory_ptr[0x10190], g_slow_memory_ptr[0x10192],
g_slow_memory_ptr[0x10191], g_slow_memory_ptr[0x10193]);
if (g_grabmouse) {
if((g_mouse_fifo_pos == 0) && g_mouse_fifo[0].dxrd && g_mouse_fifo[0].dyrd
&& ((g_mouse_fifo[0].buttons & 1) == g_mouse_a2_button)) {
g_adb_mouse_valid_data = 0;
adb_clear_mouse_int();
}
} else {
if((g_mouse_fifo_pos == 0) && (g_mouse_fifo[0].x == a2_x) &&
(g_mouse_fifo[0].y == a2_y) &&
((g_mouse_fifo[0].buttons & 1) == g_mouse_a2_button)) {
g_adb_mouse_valid_data = 0;
adb_clear_mouse_int();
}
}
g_adb_mouse_coord = !g_adb_mouse_coord;
return ret;
}
void
mouse_compress_fifo(double dcycs)
{
void mouse_compress_fifo(double dcycs) {
int pos;
/* The mouse fifo exists so that fast button changes don't get lost */
@ -1442,9 +1434,7 @@ mouse_compress_fifo(double dcycs)
}
}
void
adb_key_event(int a2code, int is_up)
{
void adb_key_event(int a2code, int is_up) {
word32 special;
word32 vbl_count;
int key;
@ -1467,7 +1457,7 @@ adb_key_event(int a2code, int is_up)
/* ESC pressed, see if ctrl & cmd key down */
if(CTRL_DOWN && CMD_DOWN) {
/* Desk mgr int */
printf("Desk mgr int!\n");
glog("Desk mgr int!");
g_adb_interrupt_byte |= 0x20;
adb_add_data_int();
@ -1506,7 +1496,7 @@ adb_key_event(int a2code, int is_up)
special = (ascii >> 8) & 0xff;
if(ascii < 0) {
printf("ascii1: %d, a2code: %02x, pos: %d\n", ascii,a2code,pos);
glogf("ascii1: %d, a2code: %02x, pos: %d", ascii,a2code,pos);
ascii = 0;
special = 0;
}
@ -1556,9 +1546,7 @@ adb_key_event(int a2code, int is_up)
}
word32
adb_read_c000()
{
word32 adb_read_c000() {
word32 vbl_count;
if( ((g_kbd_buf[0] & 0x80) == 0) && (g_key_down == 0)) {
@ -1575,8 +1563,7 @@ adb_read_c000()
/* got one */
if((g_kbd_read_no_update++ > 5) && (g_kbd_chars_buffered > 1)) {
/* read 5 times, keys pending, let's move it along */
printf("Read %02x %d times, tossing\n", g_kbd_buf[0],
g_kbd_read_no_update);
glogf("Read %02x %d times, tossing", g_kbd_buf[0], g_kbd_read_no_update);
adb_access_c010();
}
} else {
@ -1595,9 +1582,7 @@ adb_read_c000()
return g_kbd_buf[0];
}
word32
adb_access_c010()
{
word32 adb_access_c010() {
int tmp;
int i;
@ -1619,27 +1604,19 @@ adb_access_c010()
return tmp;
}
word32
adb_read_c025()
{
word32 adb_read_c025() {
return g_c025_val;
}
int
adb_is_cmd_key_down()
{
int adb_is_cmd_key_down() {
return CMD_DOWN;
}
int
adb_is_option_key_down()
{
int adb_is_option_key_down() {
return OPTION_DOWN;
}
void
adb_increment_speed()
{
void adb_increment_speed() {
const char *str;
g_limit_speed++;
@ -1653,21 +1630,19 @@ adb_increment_speed()
str = "... as fast as possible!";
break;
case 1:
str = "...1.024MHz!";
str = "... 1.024MHz";
break;
case 2:
str = "...2.8MHz!";
str = "... 2.8MHz";
break;
case 3:
str = "...8.0MHz!";
str = "... 8.0MHz";
break;
}
printf("Toggling g_limit_speed to %d%s\n", g_limit_speed, str);
glogf("Setting g_limit_speed = %d %s", g_limit_speed, str);
}
void
adb_physical_key_update(int a2code, int is_up)
{
void adb_physical_key_update(int a2code, int is_up) {
int autopoll;
int special;
int ascii_and_type;
@ -1707,10 +1682,6 @@ adb_physical_key_update(int a2code, int is_up)
a2code = 0x3a;
special = 0;
break;
case 0x03: /* F3 - remap to escape for OS/2 */
a2code = 0x35;
special = 0;
break;
case 0x0c: /* F12 - remap to reset */
a2code = 0x7f;
special = 0;
@ -1728,19 +1699,19 @@ adb_physical_key_update(int a2code, int is_up)
/* Only process reset requests here */
if(is_up == 0 && a2code == 0x7f && CTRL_DOWN) {
/* Reset pressed! */
printf("Reset pressed since CTRL_DOWN: %d\n", CTRL_DOWN);
glogf("Reset pressed since CTRL_DOWN: %d", CTRL_DOWN);
do_reset();
return;
}
if(special && !is_up) {
switch(special) {
// OG Disabled special keys (but warp)
#ifndef ACTIVEGS
case 0x03: /* F3 - screenshot */
g_screenshot_requested = 1;
break;
case 0x04: /* F4 - emulator config panel */
if (CMD_DOWN)
{
printf("Quit!\n");
if (CMD_DOWN) {
glog("Alt-F4 Quit!");
iwm_shut();
my_exit(1);
}
@ -1750,7 +1721,16 @@ adb_physical_key_update(int a2code, int is_up)
}
break;
case 0x05: /* F5 - emulator clipboard paste */
if (SHIFT_DOWN) {
g_grabmouse = !g_grabmouse;
#ifdef HAVE_SDL
extern void x_grabmouse();
glogf("g_grabmouse = %d", g_grabmouse);
x_grabmouse();
#endif
} else {
clipboard_paste();
}
break;
case 0x06: /* F6 - emulator speed */
if(SHIFT_DOWN) {
@ -1761,27 +1741,23 @@ adb_physical_key_update(int a2code, int is_up)
break;
case 0x07: /* F7 - fast disk emul */
g_fast_disk_emul = !g_fast_disk_emul;
printf("g_fast_disk_emul is now %d\n",
g_fast_disk_emul);
glogf("g_fast_disk_emul is now %d", g_fast_disk_emul);
break;
#endif
case 0x08: /* F8 - warp pointer */
g_warp_pointer = !g_warp_pointer;
if(g_hide_pointer != g_warp_pointer) {
g_hide_pointer = g_warp_pointer;
x_hide_pointer(g_hide_pointer);
}
glogf("g_warp_pointer is now %d", g_warp_pointer);
break;
#ifndef ACTIVEGS
case 0x09: /* F9 - swap paddles */
if(SHIFT_DOWN) {
g_swap_paddles = !g_swap_paddles;
printf("Swap paddles is now: %d\n",
g_swap_paddles);
glogf("Swap paddles is now: %d", g_swap_paddles);
} else {
g_invert_paddles = !g_invert_paddles;
printf("Invert paddles is now: %d\n",
g_invert_paddles);
glogf("Invert paddles is now: %d", g_invert_paddles);
}
break;
case 0x0a: /* F10 - change a2vid paletter */
@ -1801,9 +1777,7 @@ adb_physical_key_update(int a2code, int is_up)
g_fullscreen = !g_fullscreen;
x_full_screen(g_fullscreen);
break;
#endif
}
return;
}
/* Handle Keypad Joystick here partly...if keypad key pressed */
@ -1865,9 +1839,7 @@ adb_physical_key_update(int a2code, int is_up)
}
}
void
adb_virtual_key_update(int a2code, int is_up)
{
void adb_virtual_key_update(int a2code, int is_up) {
int i;
int bitpos;
word32 mask;
@ -1898,9 +1870,7 @@ adb_virtual_key_update(int a2code, int is_up)
}
}
void
adb_all_keys_up()
{
void adb_all_keys_up() {
word32 mask;
int i, j;
@ -1915,8 +1885,6 @@ adb_all_keys_up()
}
}
void
adb_kbd_repeat_off()
{
void adb_kbd_repeat_off() {
g_key_down = 0;
}

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey

View File

@ -0,0 +1,5 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(atbridge aarp.c atbridge.c elap.c llap.c pcap_delay.c port.c)
target_compile_definitions(atbridge PUBLIC HAVE_ATBRIDGE)

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -50,13 +53,11 @@ static unsigned int retry_count;
static clock_t retry_timer;
void aarp_init()
{
void aarp_init() {
aarp_retry_reset();
}
void aarp_shutdown()
{
void aarp_shutdown() {
struct amt_entry_t* entry = amt;
while (entry)
{
@ -68,8 +69,7 @@ void aarp_shutdown()
////
static void aarp_send_packet(enum AARP_FUNCTION function, const struct at_addr_t* source_at_addr, const struct at_addr_t* dest_at_addr, const struct ether_addr_t* dest_hw_addr)
{
static void aarp_send_packet(enum AARP_FUNCTION function, const struct at_addr_t* source_at_addr, const struct at_addr_t* dest_at_addr, const struct ether_addr_t* dest_hw_addr) {
if (source_at_addr && dest_at_addr && dest_hw_addr)
{
struct aarp_header_t response;
@ -98,16 +98,14 @@ static void aarp_send_packet(enum AARP_FUNCTION function, const struct at_addr_t
}
}
void aarp_probe(const struct at_addr_t* addr)
{
void aarp_probe(const struct at_addr_t* addr) {
if (addr)
{
aarp_send_packet(AARP_FUNCTION_PROBE, addr, addr, &HW_ZERO);
}
}
static void aarp_request(const struct at_addr_t* addr)
{
static void aarp_request(const struct at_addr_t* addr) {
if (addr)
{
aarp_send_packet(AARP_FUNCTION_REQUEST, atbridge_get_addr(), addr, &HW_ZERO);
@ -116,8 +114,7 @@ static void aarp_request(const struct at_addr_t* addr)
////
static struct amt_entry_t* amt_lookup_entry_hardware(const struct ether_addr_t* hardware)
{
static struct amt_entry_t* amt_lookup_entry_hardware(const struct ether_addr_t* hardware) {
if (hardware)
{
struct amt_entry_t* entry = amt;
@ -131,8 +128,7 @@ static struct amt_entry_t* amt_lookup_entry_hardware(const struct ether_addr_t*
return 0;
}
static struct amt_entry_t* amt_lookup_entry_protocol(const struct at_addr_t* protocol)
{
static struct amt_entry_t* amt_lookup_entry_protocol(const struct at_addr_t* protocol) {
if (protocol)
{
struct amt_entry_t* entry = amt;
@ -146,8 +142,7 @@ static struct amt_entry_t* amt_lookup_entry_protocol(const struct at_addr_t* pro
return 0;
}
static void amt_delete_entry_protocol(const struct at_addr_t* protocol)
{
static void amt_delete_entry_protocol(const struct at_addr_t* protocol) {
if (protocol)
{
struct amt_entry_t* entry = amt;
@ -166,8 +161,7 @@ static void amt_delete_entry_protocol(const struct at_addr_t* protocol)
}
}
static void amt_add(const struct at_addr_t* protocol, const struct ether_addr_t* hardware)
{
static void amt_add(const struct at_addr_t* protocol, const struct ether_addr_t* hardware) {
// Does an entry matching one of the protocol or hardware addresses exist? If so, update it.
struct amt_entry_t* entry = amt_lookup_entry_protocol(protocol);
if (entry)
@ -191,8 +185,7 @@ static void amt_add(const struct at_addr_t* protocol, const struct ether_addr_t*
amt = entry;
}
const struct ether_addr_t* aarp_request_hardware(const struct at_addr_t* protocol)
{
const struct ether_addr_t* aarp_request_hardware(const struct at_addr_t* protocol) {
struct amt_entry_t* entry = amt_lookup_entry_protocol(protocol);
if (entry)
{
@ -217,8 +210,7 @@ const struct ether_addr_t* aarp_request_hardware(const struct at_addr_t* protoco
}
}
const struct at_addr_t* aarp_request_protocol(const struct ether_addr_t* hardware)
{
const struct at_addr_t* aarp_request_protocol(const struct ether_addr_t* hardware) {
struct amt_entry_t* entry = amt_lookup_entry_hardware(hardware);
if (entry)
return (const struct at_addr_t*)&entry->protocol;
@ -226,24 +218,20 @@ const struct at_addr_t* aarp_request_protocol(const struct ether_addr_t* hardwar
return 0;
}
bool aarp_retry()
{
bool aarp_retry() {
return retry_count > 0;
}
void aarp_retry_reset()
{
void aarp_retry_reset() {
retry_count = AARP_REQUEST_COUNT;
retry_timer = clock();
}
void aarp_glean(const struct at_addr_t* protocol, const struct ether_addr_t* hardware)
{
void aarp_glean(const struct at_addr_t* protocol, const struct ether_addr_t* hardware) {
amt_add(protocol, hardware);
}
bool aarp_address_used(const struct at_addr_t* protocol)
{
bool aarp_address_used(const struct at_addr_t* protocol) {
// reference 2-8
if (protocol)
{
@ -268,8 +256,7 @@ bool aarp_address_used(const struct at_addr_t* protocol)
////
void aarp_handle_packet(const struct aarp_header_t* aarp)
{
void aarp_handle_packet(const struct aarp_header_t* aarp) {
if (aarp &&
aarp->hardware_type == AARP_HARDWARE_ETHER &&
aarp->protocol_type == AARP_PROTOCOL_TYPE &&

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -49,8 +52,7 @@ static const at_node_t NODE_STARTUP_HIGH = 0xFE;
static void send_rtmp_request();
bool atbridge_init()
{
bool atbridge_init() {
// If the GS reboots, we may try to reinitialize the bridge. If this is the case, keep the old address and AMT.
if (local_address.network == 0)
{
@ -73,25 +75,21 @@ bool atbridge_init()
return true;
}
void atbridge_shutdown()
{
void atbridge_shutdown() {
llap_shutdown();
elap_shutdown();
aarp_shutdown();
}
void atbridge_set_diagnostics(bool enabled)
{
void atbridge_set_diagnostics(bool enabled) {
diagnostics = enabled;
}
bool atbridge_get_diagnostics()
{
bool atbridge_get_diagnostics() {
return diagnostics;
}
void atbridge_printf(const char *fmt, ...)
{
void atbridge_printf(const char *fmt, ...) {
if (atbridge_get_diagnostics())
{
va_list args;
@ -101,41 +99,34 @@ void atbridge_printf(const char *fmt, ...)
}
}
const struct at_addr_t* atbridge_get_addr()
{
const struct at_addr_t* atbridge_get_addr() {
return &local_address;
}
const at_network_t atbridge_get_net()
{
const at_network_t atbridge_get_net() {
return local_address.network;
}
const at_node_t atbridge_get_node()
{
const at_node_t atbridge_get_node() {
return local_address.node;
}
void atbridge_set_net(at_network_t net)
{
void atbridge_set_net(at_network_t net) {
local_address.network = net;
}
void atbridge_set_node(at_node_t node)
{
void atbridge_set_node(at_node_t node) {
local_address.node = node;
}
bool atbridge_address_used(const struct at_addr_t* addr)
{
bool atbridge_address_used(const struct at_addr_t* addr) {
if (!sent_rtmp_request)
send_rtmp_request();
return aarp_address_used(addr);
}
/* Calculate a DDP checksum, per Apple's documented algorithm in 4-17 of "Inside AppleTalk". */
static word16 get_checksum(size_t size, byte data[])
{
static word16 get_checksum(size_t size, byte data[]) {
word16 cksum = 0;
for (unsigned int i = 0; i < size; i++)
{
@ -147,8 +138,7 @@ static word16 get_checksum(size_t size, byte data[])
return cksum;
}
static void calculate_checksum(struct packet_t* packet)
{
static void calculate_checksum(struct packet_t* packet) {
if (packet && packet->data && (packet->size >= sizeof(struct DDP_LONG)) && (packet->type == LAP_DDP_LONG))
{
struct DDP_LONG* header = (struct DDP_LONG*)(packet->data);
@ -159,8 +149,7 @@ static void calculate_checksum(struct packet_t* packet)
}
/* Convert a long-form DDP header to a short-form header. This function only converts the headers. */
static word16 convert_ddp_header_to_short(const struct DDP_LONG* in, struct DDP_SHORT* out)
{
static word16 convert_ddp_header_to_short(const struct DDP_LONG* in, struct DDP_SHORT* out) {
word16 size;
if (!in || !out)
@ -181,8 +170,7 @@ static word16 convert_ddp_header_to_short(const struct DDP_LONG* in, struct DDP_
/* Convert a short-form DDP header to a long-form header. ELAP requires long-form, but LLAP often uses short-form. */
/* This function only converts the headers. */
static word16 convert_ddp_header_to_long(const struct at_addr_t dest, const struct at_addr_t source, const struct DDP_SHORT* in, struct DDP_LONG* out)
{
static word16 convert_ddp_header_to_long(const struct at_addr_t dest, const struct at_addr_t source, const struct DDP_SHORT* in, struct DDP_LONG* out) {
word16 size;
if (!in || !out)
@ -219,8 +207,7 @@ static word16 convert_ddp_header_to_long(const struct at_addr_t dest, const stru
/* Convert a short-form DDP packet to a long-form packet. */
/* This function converts an entire packet, not just the header. */
static void convert_ddp_packet_to_long(struct packet_t* packet)
{
static void convert_ddp_packet_to_long(struct packet_t* packet) {
if (packet && (packet->type == LAP_DDP_SHORT) && packet->data && (packet->size >= sizeof(struct DDP_SHORT)))
{
struct DDP_SHORT* header_short = (struct DDP_SHORT*)packet->data;
@ -247,8 +234,7 @@ static void convert_ddp_packet_to_long(struct packet_t* packet)
}
/* Convert a long-form DDP packet to short-form. */
static void convert_ddp_packet_to_short(struct packet_t* packet)
{
static void convert_ddp_packet_to_short(struct packet_t* packet) {
if (packet && (packet->type == LAP_DDP_LONG) && packet->data)
{
struct DDP_LONG* header_long = (struct DDP_LONG*)packet->data;
@ -311,8 +297,7 @@ static void convert_ddp_packet_to_short(struct packet_t* packet)
}
}*/
static void convert_rtmp_to_nonextended(struct packet_t* packet)
{
static void convert_rtmp_to_nonextended(struct packet_t* packet) {
if (packet && (packet->type == LAP_DDP_LONG) && packet->data)
{
struct DDP_LONG* header_long = (struct DDP_LONG*)packet->data;
@ -355,8 +340,7 @@ static void convert_rtmp_to_nonextended(struct packet_t* packet)
/* "Inside AppleTalk", section 4-8, describes this approach for non-extended networks.
Technically, we probably should be doing the more complicated extended network approach (also on 4-8),
but the easy approach using RTMP seems adequate for now. */
static void glean_net_from_rtmp(struct packet_t* packet)
{
static void glean_net_from_rtmp(struct packet_t* packet) {
if (packet && (packet->type == LAP_DDP_LONG) && packet->data)
{
struct DDP_LONG* header_long = (struct DDP_LONG*)packet->data;
@ -369,8 +353,7 @@ static void glean_net_from_rtmp(struct packet_t* packet)
}
}
static void send_rtmp_request()
{
static void send_rtmp_request() {
struct packet_t* packet = (struct packet_t*)malloc(sizeof(struct packet_t));
packet->type = LAP_DDP_LONG;
@ -402,8 +385,7 @@ static void send_rtmp_request()
sent_rtmp_request = true;
}
void atbridge_process()
{
void atbridge_process() {
elap_process();
//llap_process();

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -44,4 +47,3 @@ const at_node_t atbridge_get_node();
void atbridge_set_net(at_network_t net);
void atbridge_set_node(at_node_t node);
bool atbridge_address_used(const struct at_addr_t* addr);

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -38,13 +38,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v120</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v120</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -61,8 +64,7 @@ static struct ether_addr_t HW_LOCAL;
}
}*/
static void elap_clone_host_mac(pcap_if_t* device)
{
static void elap_clone_host_mac(pcap_if_t* device) {
if (!device)
return;
@ -112,6 +114,7 @@ static void elap_clone_host_mac(pcap_if_t* device)
free(addresses);
#else
#ifdef AF_PACKET
struct pcap_addr* address;
for (address = device->addresses; address != 0; address = address->next)
if (address->addr->sa_family == AF_PACKET)
@ -120,15 +123,14 @@ static void elap_clone_host_mac(pcap_if_t* device)
memcpy(&HW_LOCAL.mac, ll->sll_addr, sizeof(HW_LOCAL.mac));
}
#endif
#endif
}
const struct ether_addr_t* elap_get_mac()
{
const struct ether_addr_t* elap_get_mac() {
return &HW_LOCAL;
}
bool elap_init()
{
bool elap_init() {
port_init(&elap_port);
memcpy(&HW_LOCAL, &HW_LOCAL_DEFAULT, sizeof(HW_LOCAL));
@ -201,8 +203,7 @@ bool elap_init()
}
}
void elap_shutdown()
{
void elap_shutdown() {
port_shutdown(&elap_port);
if (pcap_session)
{
@ -212,18 +213,15 @@ void elap_shutdown()
pcapdelay_unload();
}
void elap_enqueue_out(struct packet_t* packet)
{
void elap_enqueue_out(struct packet_t* packet) {
enqueue_packet(&elap_port.out, packet);
}
struct packet_t* elap_dequeue_in()
{
struct packet_t* elap_dequeue_in() {
return dequeue(&elap_port.in);
}
void elap_send(const struct ether_addr_t* dest, const struct snap_discriminator_t* discriminator, size_t size, byte data[])
{
void elap_send(const struct ether_addr_t* dest, const struct snap_discriminator_t* discriminator, size_t size, byte data[]) {
if (pcap_session && dest && discriminator)
{
// Allocate heap space for the frame.
@ -259,8 +257,7 @@ void elap_send(const struct ether_addr_t* dest, const struct snap_discriminator_
}
}
static bool elap_send_one_queued()
{
static bool elap_send_one_queued() {
// Attempt to send one packet out the host network interface.
struct packet_t* packet = queue_peek(&elap_port.out);
if (packet)
@ -300,13 +297,11 @@ static bool elap_send_one_queued()
return false;
}
static void elap_send_all_queued()
{
static void elap_send_all_queued() {
while (elap_send_one_queued());
}
static bool elap_receive_one()
{
static bool elap_receive_one() {
if (!pcap_session)
return false;
@ -384,13 +379,11 @@ static bool elap_receive_one()
return false;
}
static void elap_receive_all()
{
static void elap_receive_all() {
while (elap_receive_one());
}
void elap_process()
{
void elap_process() {
elap_receive_all();
elap_send_all_queued();
}

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -51,22 +54,19 @@ static DIALOG_STATE dialog_state;
static double dialog_end_dcycs;
static double last_frame_dcycs;
void llap_init()
{
void llap_init() {
dialog_state = DIALOG_READY;
last_frame_dcycs = 0;
port_init(&llap_port);
}
void llap_shutdown()
{
void llap_shutdown() {
port_shutdown(&llap_port);
}
/** Queue one data packet out from the bridge's LLAP port and into the guest. **/
void llap_enqueue_out(struct packet_t* packet)
{
void llap_enqueue_out(struct packet_t* packet) {
// Generate the RTS.
struct packet_t* rts = (struct packet_t*)malloc(sizeof(struct packet_t));
rts->source.network = packet->source.network;
@ -82,13 +82,11 @@ void llap_enqueue_out(struct packet_t* packet)
enqueue_packet(&llap_port.out, packet);
}
struct packet_t* llap_dequeue_in()
{
struct packet_t* llap_dequeue_in() {
return dequeue(&llap_port.in);
}
static void llap_dump_packet(size_t size, byte data[])
{
static void llap_dump_packet(size_t size, byte data[]) {
if (size < LLAP_PACKET_MIN)
atbridge_printf("LLAP short packet.\n");
else if (size > LLAP_PACKET_MAX)
@ -134,8 +132,7 @@ static void llap_dump_packet(size_t size, byte data[])
}
/** Reply to a control packet from the GS **/
static void llap_reply_control(at_node_t dest, at_node_t source, LLAP_TYPES type)
{
static void llap_reply_control(at_node_t dest, at_node_t source, LLAP_TYPES type) {
struct at_addr_t dest_addr = { 0, dest };
struct at_addr_t source_addr = { 0, source };
@ -145,8 +142,7 @@ static void llap_reply_control(at_node_t dest, at_node_t source, LLAP_TYPES type
}
/** Accept a data packet from the GS. **/
static void llap_handle_data(size_t size, byte data[])
{
static void llap_handle_data(size_t size, byte data[]) {
at_node_t dest = data[0];
at_node_t source = data[1];
LLAP_TYPES type = (LLAP_TYPES)(data[2]);
@ -161,8 +157,7 @@ static void llap_handle_data(size_t size, byte data[])
}
/** Accept a control packet from the GS. **/
static void llap_handle_control(size_t size, byte data[])
{
static void llap_handle_control(size_t size, byte data[]) {
at_node_t dest = data[0];
at_node_t source = data[1];
LLAP_TYPES type = (LLAP_TYPES)(data[2]);
@ -197,8 +192,7 @@ static void llap_handle_control(size_t size, byte data[])
or, more likely, a bug in the SCC emulation. Regardless, when such a thing does occur, discard the
current, corrupted dialog. Link errors are routine in real LocalTalk networks, and LocalTalk will recover.
**/
static void llap_reset_dialog()
{
static void llap_reset_dialog() {
dialog_state = DIALOG_READY;
last_frame_dcycs = 0;
@ -220,8 +214,7 @@ static void llap_reset_dialog()
}
/** Transfer (send) one LLAP packet from the GS. **/
void llap_enqueue_in(double dcycs, size_t size, byte data[])
{
void llap_enqueue_in(double dcycs, size_t size, byte data[]) {
atbridge_printf("<%0.0f> TX: ", dcycs);
llap_dump_packet(size, data);
@ -256,8 +249,7 @@ void llap_enqueue_in(double dcycs, size_t size, byte data[])
}
/** Transfer (receive) one LLAP packet to the GS. **/
void llap_dequeue_out(double dcycs, size_t* size, byte* data[])
{
void llap_dequeue_out(double dcycs, size_t* size, byte* data[]) {
*size = 0;
// The LocalTalk protocol requires a minimum 400us gap between dialogs (called the IDG).

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -29,8 +32,7 @@ static void* module = 0;
#endif
bool pcapdelay_load()
{
bool pcapdelay_load() {
if (!pcapdelay_is_loaded())
{
#ifdef WIN32
@ -42,17 +44,16 @@ bool pcapdelay_load()
return pcapdelay_is_loaded();
}
bool pcapdelay_is_loaded()
{
bool pcapdelay_is_loaded() {
#ifdef WIN32
return module != NULL;
#elif __linux__
return module != 0;
#endif
return 0;
}
void pcapdelay_unload()
{
void pcapdelay_unload() {
if (pcapdelay_is_loaded())
{
#ifdef WIN32
@ -67,8 +68,7 @@ void pcapdelay_unload()
typedef void (*PFNVOID)();
static PFNVOID delay_load(const char* proc, PFNVOID* ppfn)
{
static PFNVOID delay_load(const char* proc, PFNVOID* ppfn) {
if (pcapdelay_load() && proc && ppfn && !*ppfn)
{
#ifdef WIN32
@ -83,16 +83,14 @@ static PFNVOID delay_load(const char* proc, PFNVOID* ppfn)
return 0;
}
void pcapdelay_freealldevs(pcap_if_t* a0)
{
void pcapdelay_freealldevs(pcap_if_t* a0) {
typedef void (*PFN)(pcap_if_t*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_freealldevs", (PFNVOID*)&pfn)))
(*pfn)(a0);
}
pcap_t* pcapdelay_open_live(const char* a0, int a1, int a2, int a3, char* a4)
{
pcap_t* pcapdelay_open_live(const char* a0, int a1, int a2, int a3, char* a4) {
typedef pcap_t* (*PFN)(const char*, int, int, int, char*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_open_live", (PFNVOID*)&pfn)))
@ -101,16 +99,14 @@ pcap_t* pcapdelay_open_live(const char* a0, int a1, int a2, int a3, char* a4)
return 0;
}
void pcapdelay_close(pcap_t* a0)
{
void pcapdelay_close(pcap_t* a0) {
typedef void (*PFN)(pcap_t*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_close", (PFNVOID*)&pfn)))
(*pfn)(a0);
}
int pcapdelay_findalldevs(pcap_if_t** a0, char* a1)
{
int pcapdelay_findalldevs(pcap_if_t** a0, char* a1) {
typedef int (*PFN)(pcap_if_t**, char*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_findalldevs", (PFNVOID*)&pfn)))
@ -119,8 +115,7 @@ int pcapdelay_findalldevs(pcap_if_t** a0, char* a1)
return 0;
}
int pcapdelay_datalink(pcap_t* a0)
{
int pcapdelay_datalink(pcap_t* a0) {
typedef int (*PFN)(pcap_t*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_datalink", (PFNVOID*)&pfn)))
@ -129,8 +124,7 @@ int pcapdelay_datalink(pcap_t* a0)
return 0;
}
int pcapdelay_setnonblock(pcap_t* a0, int a1, char* a2)
{
int pcapdelay_setnonblock(pcap_t* a0, int a1, char* a2) {
typedef int (*PFN)(pcap_t*, int, char*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_setnonblock", (PFNVOID*)&pfn)))
@ -139,8 +133,7 @@ int pcapdelay_setnonblock(pcap_t* a0, int a1, char* a2)
return 0;
}
int pcapdelay_sendpacket(pcap_t* a0, u_char* a1, int a2)
{
int pcapdelay_sendpacket(pcap_t* a0, u_char* a1, int a2) {
typedef int (*PFN)(pcap_t*, u_char*, int);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_sendpacket", (PFNVOID*)&pfn)))
@ -149,8 +142,7 @@ int pcapdelay_sendpacket(pcap_t* a0, u_char* a1, int a2)
return 0;
}
const u_char* pcapdelay_next(pcap_t* a0, struct pcap_pkthdr* a1)
{
const u_char* pcapdelay_next(pcap_t* a0, struct pcap_pkthdr* a1) {
typedef const u_char*(*PFN)(pcap_t*, struct pcap_pkthdr*);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_next", (PFNVOID*)&pfn)))
@ -159,8 +151,7 @@ const u_char* pcapdelay_next(pcap_t* a0, struct pcap_pkthdr* a1)
return 0;
}
int pcapdelay_dispatch(pcap_t* a0, int a1, pcap_handler a2, u_char* a3)
{
int pcapdelay_dispatch(pcap_t* a0, int a1, pcap_handler a2, u_char* a3) {
typedef const int (*PFN)(pcap_t *, int, pcap_handler, u_char *);
static PFN pfn = 0;
if ((pfn = (PFN)delay_load("pcap_dispatch", (PFNVOID*)&pfn)))

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -16,6 +19,7 @@ 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
*/
/*
This interface provides a thin, delay-loaded wrapper around the PCAP library so that
you may start GSport without intalling PCAP. Of course, some features that require
@ -29,6 +33,8 @@ Feel free to extend the wrapper.
#include "../arch/win32/pcap.h"
#elif __linux__
#include <pcap.h>
#elif __APPLE__
#include <pcap/pcap.h>
#endif
bool pcapdelay_load();

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
@ -23,8 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "atalk.h"
#include "port.h"
void port_init(struct packet_port_t* port)
{
void port_init(struct packet_port_t* port) {
if (port)
{
queue_init(&port->in);
@ -32,8 +34,7 @@ void port_init(struct packet_port_t* port)
}
}
void port_shutdown(struct packet_port_t* port)
{
void port_shutdown(struct packet_port_t* port) {
if (port)
{
queue_shutdown(&port->in);
@ -41,16 +42,14 @@ void port_shutdown(struct packet_port_t* port)
}
}
void queue_init(struct packet_queue_t* queue)
{
void queue_init(struct packet_queue_t* queue) {
if (queue)
{
queue->head = queue->tail = 0;
}
}
void queue_shutdown(struct packet_queue_t* queue)
{
void queue_shutdown(struct packet_queue_t* queue) {
if (queue)
{
struct packet_t* packet = dequeue(queue);
@ -64,8 +63,7 @@ void queue_shutdown(struct packet_queue_t* queue)
}
}
void enqueue(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_t source, byte type, size_t size, byte data[])
{
void enqueue(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_t source, byte type, size_t size, byte data[]) {
if (!queue)
return;
@ -80,8 +78,7 @@ void enqueue(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr
enqueue_packet(queue, packet);
}
void enqueue_packet(struct packet_queue_t* queue, struct packet_t* packet)
{
void enqueue_packet(struct packet_queue_t* queue, struct packet_t* packet) {
packet->next = 0;
if (queue->tail)
@ -91,8 +88,7 @@ void enqueue_packet(struct packet_queue_t* queue, struct packet_t* packet)
queue->tail = packet;
}
void insert(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_t source, byte type, size_t size, byte data[])
{
void insert(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_t source, byte type, size_t size, byte data[]) {
if (!queue)
return;
@ -107,16 +103,14 @@ void insert(struct packet_queue_t* queue, struct at_addr_t dest, struct at_addr_
insert_packet(queue, packet);
}
void insert_packet(struct packet_queue_t* queue, struct packet_t* packet)
{
void insert_packet(struct packet_queue_t* queue, struct packet_t* packet) {
packet->next = queue->head;
queue->head = packet;
if (!queue->tail)
queue->tail = queue->head;
}
struct packet_t* dequeue(struct packet_queue_t* queue)
{
struct packet_t* dequeue(struct packet_queue_t* queue) {
if (queue && queue->head)
{
struct packet_t* packet = queue->head;
@ -130,8 +124,7 @@ struct packet_t* dequeue(struct packet_queue_t* queue)
return 0;
}
struct packet_t* queue_peek(struct packet_queue_t* queue)
{
struct packet_t* queue_peek(struct packet_queue_t* queue) {
if (queue)
return queue->head;
else

View File

@ -1,6 +1,9 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2013-2014 by Peter Neubauer
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -22,9 +23,7 @@
#define CONF_BUF_LEN 1024
#define COPY_BUF_SIZE 4096
#define CFG_PRINTF_BUFSIZE 2048
#define CFG_PATH_MAX 1024
#define CFG_NUM_SHOWENTS 16
#define CFGTYPE_MENU 1
@ -33,6 +32,7 @@
#define CFGTYPE_FUNC 4
#define CFGTYPE_FILE 5
#define CFGTYPE_STR 6
#define CFGTYPE_DIR 7
/* CFGTYPE limited to just 4 bits: 0-15 */
/* Cfg_menu, Cfg_dirent and Cfg_listhdr are defined in defc.h */
@ -42,3 +42,33 @@ STRUCT(Cfg_defval) {
int intval;
char *strval;
};
int cfg_get_fd_size(char *filename);
int cfg_partition_read_block(FILE *file, void *buf, int blk, int blk_size);
int cfg_partition_find_by_name_or_num(FILE *file, const char *partnamestr, int part_num, Disk *dsk);
int cfg_maybe_insert_disk(int slot, int drive, const char *namestr);
int cfg_stat(char *path, struct stat *sb);
int cfg_partition_make_list(char *filename, FILE *file);
void cfg_htab_vtab(int x, int y);
void cfg_home(void);
void cfg_cleol(void);
void cfg_putchar(int c);
void cfg_printf(const char *fmt, ...);
void cfg_print_num(int num, int max_len);
void cfg_get_disk_name(char *outstr, int maxlen, int type_ext, int with_extras);
void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int change);
void cfg_get_base_path(char *pathptr, const char *inptr, int go_up);
void cfg_file_init(void);
void cfg_free_alldirents(Cfg_listhdr *listhdrptr);
void cfg_file_add_dirent(Cfg_listhdr *listhdrptr, const char *nameptr, int is_dir, int size, int image_start, int part_num);
int cfg_dirent_sortfn(const void *obj1, const void *obj2);
int cfg_str_match(const char *str1, const char *str2, int len);
void cfg_file_readdir(const char *pathptr);
char *cfg_shorten_filename(const char *in_ptr, int maxlen);
void cfg_fix_topent(Cfg_listhdr *listhdrptr);
void cfg_file_draw(void);
void cfg_partition_selected(void);
void cfg_file_update_ptr(char *str);
void cfg_file_selected(int);
void cfg_file_handle_key(int key);

45
src/config.txt Normal file
View File

@ -0,0 +1,45 @@
# GSport configuration file version 0.4
s5d1 =
s5d2 =
s6d1 =
s6d2 =
s7d1 =
bram1[00] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[10] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[20] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[30] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[40] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[50] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[60] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[70] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[80] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[90] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[a0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[b0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[c0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[d0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[e0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram1[f0] = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
bram3[00] = 00 00 00 01 00 00 0d 06 02 01 01 00 01 00 00 00
bram3[10] = 00 00 07 06 02 01 01 00 00 00 0f 06 06 00 05 06
bram3[20] = 01 00 00 00 00 00 00 01 00 00 00 00 05 02 02 00
bram3[30] = 00 00 2d 2d 00 00 00 00 00 00 02 02 02 06 08 00
bram3[40] = 01 02 03 04 05 06 07 0a 00 01 02 03 04 05 06 07
bram3[50] = 08 09 0a 0b 0c 0d 0e 0f 00 00 ff ff ff ff ff ff
bram3[60] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[70] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[80] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[90] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[a0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[b0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[c0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[d0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[e0] = ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
bram3[f0] = ff ff ff ff ff ff ff ff ff ff ff ff 36 2d 9c 87

1520
src/debug.c Normal file

File diff suppressed because it is too large Load Diff

30
src/debug.h Normal file
View File

@ -0,0 +1,30 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
extern void debug_init();
extern void debug_poll_only();
extern void debug_cpu_test();
// used in sim65816.c
void debug_server_poll();
int debug_events_waiting();
void debug_handle_event();

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -58,6 +59,7 @@ void U_STACK_TRACE();
#define DRECIP_DCYCS_IN_16MS (1.0 / (DCYCS_IN_16MS))
#ifdef GSPORT_LITTLE_ENDIAN
// @todo: look at using <byteswap.h> for fastest platform implementations
# define BIGEND(a) ((((a) >> 24) & 0xff) + \
(((a) >> 8) & 0xff00) + \
(((a) << 8) & 0xff0000) + \
@ -76,7 +78,7 @@ void U_STACK_TRACE();
# include <libc.h>
#endif
#if !defined(_WIN32) && !defined (__OS2__) && !defined(UNDER_CE) // OG
#if !defined(_WIN32) && !defined(UNDER_CE) // OG
# include <unistd.h>
# include <sys/ioctl.h>
# include <sys/wait.h>
@ -368,3 +370,6 @@ STRUCT(Emustate_word32list) {
#define JOYSTICK_TYPE_NATIVE_2 3
#define JOYSTICK_TYPE_NONE 4 // OG Added Joystick None
#define NB_JOYSTICK_TYPE 5
// starting window x/y position if Undefined
#define WINDOWPOS_UNDEFINED 0xFFFFFFFF

164
src/dis.c
View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -31,12 +32,13 @@ extern byte *g_memory_ptr;
extern byte *g_slow_memory_ptr;
extern int halt_sim;
extern int enter_debug;
extern int g_dbg_step; //debug.c
extern int timeout; //debug.c
extern int g_c068_statereg;
extern word32 stop_run_at;
extern int Verbose;
extern int Halt_on;
extern int g_testing_enabled;
extern int g_fullscreen;
extern int g_config_control_panel;
@ -64,19 +66,13 @@ int got_num;
// OG replaced by HALT_WANTTOQUIT
//int g_quit_sim_now = 0;
int
get_num()
{
int get_num() {
int tmp1;
a2 = 0;
got_num = 0;
while(1) {
if(mode == 0 && got_num != 0) {
/*
printf("In getnum, mode =0, setting a1,a3 = a2\n");
printf("a2: %x\n", a2);
*/
a3 = a2;
a3bank = a2bank;
a1 = a2;
@ -102,17 +98,15 @@ get_num()
}
}
void
debugger_help()
{
printf("GSport Debugger help (courtesy Fredric Devernay\n");
printf("General command syntax: [bank]/[address][command]\n");
printf("e.g. 'e1/0010B' to set a breakpoint at the interrupt jump pt\n");
printf("Enter all addresses using lower-case\n");
void debugger_help() {
printf("GSport Debugger Help (courtesy Fredric Devernay)\n\n");
printf("General command syntax:\n");
printf(" [bank]/[address][command]\n\n");
printf("Example: > e1/0010B Set a Breakpoint at the interrupt jump pt\n\n");
printf("Enter all addresses using lower-case.\n");
printf("As with the IIgs monitor, you can omit the bank number after\n");
printf("having set it: 'e1/0010B' followed by '14B' will set\n");
printf("breakpoints at e1/0010 and e1/0014\n");
printf("\n");
printf("having set it: 'e1/0010B' followed by '14B' will set breakpoints\n");
printf("at e1/0010 and e1/0014\n\n");
printf(" g Go\n");
printf(" [bank]/[addr]g Go from [bank]/[address]\n");
printf(" s Step one instruction\n");
@ -120,9 +114,8 @@ debugger_help()
printf(" [bank]/[addr]B Set breakpoint at [bank]/[address]\n");
printf(" B Show all breakpoints\n");
printf(" [bank]/[addr]D Delete breakpoint at [bank]/[address]\n");
printf("[bank]/[addr1].[addr2] View memory\n");
printf(" [bank]/[addr].[addr2] View memory\n");
printf(" [bank]/[addr]L Disassemble memory\n");
printf(" P Dump the trace to 'pc_log_out'\n");
printf(" Z Dump SCC state\n");
printf(" I Dump IWM state\n");
@ -149,12 +142,10 @@ debugger_help()
printf("[bank]/[addr1].[addr2]us[file] Save mem area to [file]\n");
printf("[bank]/[addr1].[addr2]ul[file] Load mem area from [file]\n");
printf(" v Show video information\n");
printf("q Exit Debugger (and GSport)\n");
printf(" q Quit Debugger (and GSport)\n");
}
void
do_debug_intfc()
{
void do_debug_intfc() {
char linebuf[LINE_SIZE];
int slot_drive;
int track;
@ -355,11 +346,7 @@ do_debug_intfc()
if(got_num) {
engine.kpc = (a2bank<<16) + (a2&0xffff);
}
if(ret_val == 'G' && g_testing_enabled) {
do_gen_test(got_num, a2);
} else {
do_go();
}
list_kpc = engine.kpc;
break;
case 'q':
@ -422,9 +409,7 @@ do_debug_intfc()
printf("Console closed.\n");
}
word32
dis_get_memory_ptr(word32 addr)
{
word32 dis_get_memory_ptr(word32 addr) {
word32 tmp1, tmp2, tmp3;
tmp1 = get_memory_c(addr, 0);
@ -434,9 +419,7 @@ dis_get_memory_ptr(word32 addr)
return (tmp3 << 16) + (tmp2 << 8) + tmp1;
}
void
show_one_toolset(FILE *toolfile, int toolnum, word32 addr)
{
void show_one_toolset(FILE *toolfile, int toolnum, word32 addr) {
word32 rout_addr;
int num_routs;
int i;
@ -451,9 +434,7 @@ show_one_toolset(FILE *toolfile, int toolnum, word32 addr)
}
}
void
show_toolset_tables(word32 a2bank, word32 addr)
{
void show_toolset_tables(word32 a2bank, word32 addr) {
FILE *toolfile;
word32 tool_addr;
int num_tools;
@ -479,18 +460,7 @@ show_toolset_tables(word32 a2bank, word32 addr)
fclose(toolfile);
}
#ifndef TEST65
void
do_gen_test(int got_num, int base_seed)
{
/* dummy */
}
#endif
void
set_bp(word32 addr)
{
void set_bp(word32 addr) {
int count;
printf("About to set BP at %06x\n", addr);
@ -505,9 +475,7 @@ set_bp(word32 addr)
fixup_brks();
}
void
show_bp()
{
void show_bp() {
int i;
printf("Showing breakpoints set\n");
@ -516,9 +484,7 @@ show_bp()
}
}
void
delete_bp(word32 addr)
{
void delete_bp(word32 addr) {
int count;
int hit;
int i;
@ -548,9 +514,7 @@ delete_bp(word32 addr)
show_bp();
}
void
do_blank()
{
void do_blank() {
int tmp, i;
switch(old_mode) {
@ -594,48 +558,43 @@ do_blank()
}
}
void
do_go()
{
/* also called by do_step */
/* also called by do_step */
void do_go() {
g_config_control_panel = 0;
clear_halt();
run_prog();
show_regs();
g_config_control_panel = 1;
}
void
do_step()
{
void do_step() {
int size;
int size_mem_imm, size_x_imm;
// run an instruction
do_go();
// check accumulator size
size_mem_imm = 2;
if(engine.psr & 0x20) {
size_mem_imm = 1;
}
// check xy size
size_x_imm = 2;
if(engine.psr & 0x10) {
size_x_imm = 1;
}
// then disassemble
size = do_dis(stdout, engine.kpc, size_mem_imm, size_x_imm, 0, 0);
}
void
xam_mem(int count)
{
void xam_mem(int count) {
show_hex_mem(a1bank, a1, a2bank, a2, count);
a1 = a2 + 1;
}
void
show_hex_mem(int startbank, word32 start, int endbank, word32 end, int count)
{
void show_hex_mem(int startbank, word32 start, int endbank, word32 end, int count) {
char ascii[MAXNUM_HEX_PER_LINE];
word32 i;
int val, offset;
@ -673,12 +632,10 @@ show_hex_mem(int startbank, word32 start, int endbank, word32 end, int count)
}
int
read_line(char *buf, int len)
{
int read_line(char *buf, int len) {
int space_left;
int ret;
#if !defined(_WIN32) && !defined (__OS2__)
#if !defined(_WIN32)
int flags, flags_save;
/* Unix */
@ -697,10 +654,9 @@ read_line(char *buf, int len)
buf[0] = 0;
ret = 0;
while(space_left > 0) {
#ifdef _WIN32
ret = win_nonblock_read_stdin(0, buf, 1);
#elif defined(__OS2__)
#if defined(_WIN32) && !defined(WIN_SDL)
ret = win_nonblock_read_stdin(0, buf, 1);
#else
/* Unix */
ret = read(0, buf, 1);
@ -726,16 +682,14 @@ read_line(char *buf, int len)
}
buf = &buf[ret];
}
#if !defined(_WIN32) && !defined (__OS2__)
#if !defined(_WIN32)
(void)fcntl(0, F_SETFL, flags_save);
#endif
return (len-space_left);
}
void
do_debug_list()
{
void do_debug_list() {
int i;
int size;
int size_mem_imm, size_x_imm;
@ -761,9 +715,7 @@ do_debug_list()
}
}
void
dis_do_memmove()
{
void dis_do_memmove() {
word32 val;
printf("Memory move from %02x/%04x.%04x to %02x/%04x\n", a1bank, a1, a2, g_a4bank, g_a4);
@ -777,15 +729,11 @@ dis_do_memmove()
g_a4 = g_a4 & 0xffff;
}
void
dis_do_pattern_search()
{
void dis_do_pattern_search() {
printf("Memory pattern search for %04x in %02x/%04x.%04x\n", g_a4, a1bank, a1, a2);
}
void
dis_do_compare()
{
void dis_do_compare() {
word32 val1, val2;
printf("Memory Compare from %02x/%04x.%04x with %02x/%04x\n", a1bank, a1, a2, g_a4bank, g_a4);
@ -802,10 +750,7 @@ dis_do_compare()
g_a4 = g_a4 & 0xffff;
}
void
do_debug_unix()
{
#ifndef __OS2__
void do_debug_unix() {
char localbuf[LINE_SIZE];
word32 offset, len;
int fd, ret;
@ -880,20 +825,15 @@ do_debug_unix()
printf("errno: %d\n", errno);
}
a1 = a1 + ret;
#endif
}
void
do_debug_load()
{
void do_debug_load() {
printf("Sorry, can't load now\n");
}
int
do_dis(FILE *outfile, word32 kpc, int accsize, int xsize,
int op_provided, word32 instr)
{
int do_dis(FILE *outfile, word32 kpc, int accsize, int xsize,
int op_provided, word32 instr) {
char buffer[150];
const char *out;
int args, type;
@ -1160,10 +1100,8 @@ do_dis(FILE *outfile, word32 kpc, int accsize, int xsize,
return(args+1);
}
void
show_line(FILE *outfile, word32 kaddr, word32 operand, int size,
char *string)
{
void show_line(FILE *outfile, word32 kaddr, word32 operand, int size,
char *string) {
int i;
int opcode;
@ -1181,9 +1119,7 @@ show_line(FILE *outfile, word32 kaddr, word32 operand, int size,
fprintf(outfile,"%s\n", string);
}
void
halt_printf(const char *fmt, ...)
{
void halt_printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);
@ -1193,9 +1129,7 @@ halt_printf(const char *fmt, ...)
set_halt(1);
}
void
halt2_printf(const char *fmt, ...)
{
void halt2_printf(const char *fmt, ...) {
va_list args;
va_start(args, fmt);

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -38,6 +39,7 @@
# define FCYCS_PTR_FCYCLES_ROUND_SLOW
#endif
extern int g_dbg_step;
extern int halt_sim;
extern int g_code_red;
extern int g_ignore_halts;
@ -365,24 +367,21 @@ extern word32 slow_mem_changed[];
ptr[2] = (val) >> 16; \
}
void
check_breakpoints(word32 addr)
{
void check_breakpoints(word32 addr) {
int count;
int i;
count = g_num_breakpoints;
for(i = 0; i < count; i++) {
if((g_breakpts[i] & 0xffffff) == addr) {
g_dbg_step = -2;
halt2_printf("Hit breakpoint at %06x\n", addr);
}
}
}
word32
get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr,
double fplus_x_m1)
{
word32 get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr,
double fplus_x_m1) {
double fcycles;
word32 wstat;
byte *ptr;
@ -402,10 +401,8 @@ get_memory8_io_stub(word32 addr, byte *stat, double *fcycs_ptr,
}
}
word32
get_memory16_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr,
Fplus *fplus_ptr, int in_bank)
{
word32 get_memory16_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr,
Fplus *fplus_ptr, int in_bank) {
byte *ptr;
double fcycles, fcycles_tmp1;
double fplus_1;
@ -428,10 +425,8 @@ get_memory16_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr,
return (ret << 8) + (tmp1);
}
word32
get_memory24_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr,
Fplus *fplus_ptr, int in_bank)
{
word32 get_memory24_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr,
Fplus *fplus_ptr, int in_bank) {
byte *ptr;
double fcycles, fcycles_tmp1;
double fplus_1;
@ -460,10 +455,8 @@ get_memory24_pieces_stub(word32 addr, byte *stat, double *fcycs_ptr,
return (ret << 16) + (tmp2 << 8) + tmp1;
}
void
set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr,
double fplus_x_m1)
{
void set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr,
double fplus_x_m1) {
double fcycles;
word32 setmem_tmp1;
word32 tmp1, tmp2;
@ -507,10 +500,8 @@ set_memory8_io_stub(word32 addr, word32 val, byte *stat, double *fcycs_ptr,
}
}
void
set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
double fplus_1, double fplus_x_m1, int in_bank)
{
void set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
double fplus_1, double fplus_x_m1, int in_bank) {
byte *ptr;
byte *stat;
double fcycles, fcycles_tmp1;
@ -527,10 +518,8 @@ set_memory16_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
*fcycs_ptr = fcycles;
}
void
set_memory24_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
Fplus *fplus_ptr, int in_bank)
{
void set_memory24_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
Fplus *fplus_ptr, int in_bank) {
byte *ptr;
byte *stat;
double fcycles, fcycles_tmp1;
@ -558,9 +547,7 @@ set_memory24_pieces_stub(word32 addr, word32 val, double *fcycs_ptr,
}
word32
get_memory_c(word32 addr, int cycs)
{
word32 get_memory_c(word32 addr, int cycs) {
byte *stat;
byte *ptr;
double fcycles, fcycles_tmp1;
@ -577,9 +564,7 @@ get_memory_c(word32 addr, int cycs)
return ret;
}
word32
get_memory16_c(word32 addr, int cycs)
{
word32 get_memory16_c(word32 addr, int cycs) {
double fcycs;
fcycs = 0;
@ -587,9 +572,7 @@ get_memory16_c(word32 addr, int cycs)
(get_memory_c(addr+1, (int)fcycs) << 8);
}
word32
get_memory24_c(word32 addr, int cycs)
{
word32 get_memory24_c(word32 addr, int cycs) {
double fcycs;
fcycs = 0;
@ -598,9 +581,22 @@ get_memory24_c(word32 addr, int cycs)
(get_memory_c(addr+2, (int)fcycs) << 16);
}
void
set_memory_c(word32 addr, word32 val, int cycs)
{
word32 get_memory32_c(word32 addr, int cycs) {
double fcycs;
fcycs = 0;
return get_memory_c(addr, (int)fcycs) +
(get_memory_c(addr+1, (int)fcycs) << 8) +
(get_memory_c(addr+2, (int)fcycs) << 16) +
(get_memory_c(addr+3, (int)fcycs) << 24);
}
void set_memory_c(word32 addr, word32 val, int cycs) {
byte *stat;
byte *ptr;
double fcycles, fcycles_tmp1;
@ -613,9 +609,7 @@ set_memory_c(word32 addr, word32 val, int cycs)
SET_MEMORY8(addr, val);
}
void
set_memory16_c(word32 addr, word32 val, int cycs)
{
void set_memory16_c(word32 addr, word32 val, int cycs) {
byte *stat;
byte *ptr;
double fcycles, fcycles_tmp1;
@ -630,17 +624,22 @@ set_memory16_c(word32 addr, word32 val, int cycs)
SET_MEMORY16(addr, val, 0);
}
void
set_memory24_c(word32 addr, word32 val, int cycs)
{
void set_memory24_c(word32 addr, word32 val, int cycs) {
set_memory_c(addr, val, 0);
set_memory_c(addr + 1, val >> 8, 0);
set_memory_c(addr + 2, val >> 16, 0);
}
word32
do_adc_sbc8(word32 in1, word32 in2, word32 psr, int sub)
{
void set_memory32_c(word32 addr, word32 val, int cycs) {
set_memory_c(addr, val, 0);
set_memory_c(addr + 1, val >> 8, 0);
set_memory_c(addr + 2, val >> 16, 0);
set_memory_c(addr + 3, val >> 24, 0);
}
word32 do_adc_sbc8(word32 in1, word32 in2, word32 psr, int sub) {
word32 sum, carry, overflow;
word32 zero;
int decimal;
@ -691,9 +690,7 @@ do_adc_sbc8(word32 in1, word32 in2, word32 psr, int sub)
return (psr << 16) + (sum & 0xff);
}
word32
do_adc_sbc16(word32 in1, word32 in2, word32 psr, int sub)
{
word32 do_adc_sbc16(word32 in1, word32 in2, word32 psr, int sub) {
word32 sum, carry, overflow;
word32 tmp1, tmp2;
word32 zero;
@ -742,9 +739,7 @@ int g_ret1;
int g_ret2;
void
fixed_memory_ptrs_init()
{
void fixed_memory_ptrs_init() {
/* set g_slow_memory_ptr, g_rom_fc_ff_ptr, g_dummy_memory1_ptr, */
/* and rom_cards_ptr */
@ -767,8 +762,7 @@ fixed_memory_ptrs_init()
}
// OG added fixed_memory_ptrs_shut
void fixed_memory_ptrs_shut()
{
void fixed_memory_ptrs_shut() {
free(g_slow_memory_ptr_allocated);
free(g_dummy_memory1_ptr_allocated);
@ -777,13 +771,12 @@ void fixed_memory_ptrs_shut()
g_slow_memory_ptr=g_slow_memory_ptr_allocated= NULL;
g_dummy_memory1_ptr = g_dummy_memory1_ptr_allocated = NULL;
g_rom_fc_ff_ptr = g_rom_fc_ff_ptr_allocated = NULL;
g_rom_cards_ptr = g_rom_cards_ptr = NULL;
// g_rom_cards_ptr = g_rom_cards_ptr = NULL; // a mistake?
g_rom_cards_ptr = NULL;
}
word32
get_itimer()
{
word32 get_itimer() {
#if defined(_WIN32)
LARGE_INTEGER count;
if (QueryPerformanceCounter(&count))
@ -816,9 +809,7 @@ get_itimer()
#endif
}
void
set_halt_act(int val)
{
void set_halt_act(int val) {
if(val == 1 && g_ignore_halts && !g_user_halt_bad) {
g_code_red++;
} else {
@ -827,15 +818,11 @@ set_halt_act(int val)
}
}
void
clr_halt_act()
{
void clr_halt_act() {
halt_sim = 0;
}
word32
get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fplus_ptr)
{
word32 get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fplus_ptr) {
byte *stat;
byte *ptr;
double fcycles, fcycles_tmp1;
@ -929,9 +916,7 @@ get_remaining_operands(word32 addr, word32 opcode, word32 psr, Fplus *fplus_ptr)
arg_ptr[3] = arg >> 16; \
}
int
enter_engine(Engine_reg *engine_ptr)
{
int enter_engine(Engine_reg *engine_ptr) {
register byte *ptr;
byte *arg_ptr;
Pc_log *tmp_pc_ptr;

47
src/fix_mac_menu.m Normal file
View File

@ -0,0 +1,47 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#import <Cocoa/Cocoa.h>
void fix_mac_menu(void) {
/*
* add an option-key modifier to all menu shortcuts
* eg, command-Q -> option+command-Q
*/
@autoreleasepool {
if (NSApp) {
NSMenu *menu = [NSApp mainMenu];
for (NSMenuItem *a in [menu itemArray]) {
for (NSMenuItem *b in [[a submenu] itemArray]) {
unsigned m = [b keyEquivalentModifierMask];
if (m & NSEventModifierFlagCommand)
[b setKeyEquivalentModifierMask: m | NSEventModifierFlagOption];
}
}
}
}
}

203
src/fst.h Normal file
View File

@ -0,0 +1,203 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
/* generated on Tue Oct 18 20:54:09 2016 */
#define GSString255_length 0
#define GSString255_text 2
#define GSString32_length 0
#define GSString32_text 2
#define ResultBuf255_bufSize 0
#define ResultBuf255_bufString 2
#define ResultBuf32_bufSize 0
#define ResultBuf32_bufString 2
#define TimeRec_second 0
#define TimeRec_minute 1
#define TimeRec_hour 2
#define TimeRec_year 3
#define TimeRec_day 4
#define TimeRec_month 5
#define TimeRec_extra 6
#define TimeRec_weekDay 7
#define CreateRecGS_pCount 0
#define CreateRecGS_pathname 2
#define CreateRecGS_access 6
#define CreateRecGS_fileType 8
#define CreateRecGS_auxType 10
#define CreateRecGS_storageType 14
#define CreateRecGS_eof 16
#define CreateRecGS_resourceEOF 20
#define CreateRec_pathname 0
#define CreateRec_fAccess 4
#define CreateRec_fileType 6
#define CreateRec_auxType 8
#define CreateRec_storageType 12
#define CreateRec_createDate 14
#define CreateRec_createTime 16
#define DirEntryRecGS_pCount 0
#define DirEntryRecGS_refNum 2
#define DirEntryRecGS_flags 4
#define DirEntryRecGS_base 6
#define DirEntryRecGS_displacement 8
#define DirEntryRecGS_name 10
#define DirEntryRecGS_entryNum 14
#define DirEntryRecGS_fileType 16
#define DirEntryRecGS_eof 18
#define DirEntryRecGS_blockCount 22
#define DirEntryRecGS_createDateTime 26
#define DirEntryRecGS_modDateTime 34
#define DirEntryRecGS_access 42
#define DirEntryRecGS_auxType 44
#define DirEntryRecGS_fileSysID 48
#define DirEntryRecGS_optionList 50
#define DirEntryRecGS_resourceEOF 54
#define DirEntryRecGS_resourceBlocks 58
#define DirEntryRec_refNum 0
#define DirEntryRec_flags 2
#define DirEntryRec_base 4
#define DirEntryRec_displacement 6
#define DirEntryRec_nameBuffer 8
#define DirEntryRec_entryNum 12
#define DirEntryRec_fileType 14
#define DirEntryRec_endOfFile 16
#define DirEntryRec_blockCount 20
#define DirEntryRec_createTime 24
#define DirEntryRec_modTime 32
#define DirEntryRec_access 40
#define DirEntryRec_auxType 42
#define DirEntryRec_fileSysID 46
#define FileInfoRecGS_pCount 0
#define FileInfoRecGS_pathname 2
#define FileInfoRecGS_access 6
#define FileInfoRecGS_fileType 8
#define FileInfoRecGS_auxType 10
#define FileInfoRecGS_storageType 14
#define FileInfoRecGS_createDateTime 16
#define FileInfoRecGS_modDateTime 24
#define FileInfoRecGS_optionList 32
#define FileInfoRecGS_eof 36
#define FileInfoRecGS_blocksUsed 40
#define FileInfoRecGS_resourceEOF 44
#define FileInfoRecGS_resourceBlocks 48
#define FileRec_pathname 0
#define FileRec_fAccess 4
#define FileRec_fileType 6
#define FileRec_auxType 8
#define FileRec_storageType 12
#define FileRec_createDate 14
#define FileRec_createTime 16
#define FileRec_modDate 18
#define FileRec_modTime 20
#define FileRec_blocksUsed 22
#define OpenRecGS_pCount 0
#define OpenRecGS_refNum 2
#define OpenRecGS_pathname 4
#define OpenRecGS_requestAccess 8
#define OpenRecGS_resourceNumber 10
#define OpenRecGS_access 12
#define OpenRecGS_fileType 14
#define OpenRecGS_auxType 16
#define OpenRecGS_storageType 20
#define OpenRecGS_createDateTime 22
#define OpenRecGS_modDateTime 30
#define OpenRecGS_optionList 38
#define OpenRecGS_eof 42
#define OpenRecGS_blocksUsed 46
#define OpenRecGS_resourceEOF 50
#define OpenRecGS_resourceBlocks 54
#define OpenRec_openRefNum 0
#define OpenRec_openPathname 2
#define OpenRec_ioBuffer 6
#define VolumeRecGS_pCount 0
#define VolumeRecGS_devName 2
#define VolumeRecGS_volName 6
#define VolumeRecGS_totalBlocks 10
#define VolumeRecGS_freeBlocks 14
#define VolumeRecGS_fileSysID 18
#define VolumeRecGS_blockSize 20
#define VolumeRecGS_characteristics 22
#define VolumeRecGS_deviceID 24
#define VolumeRec_deviceName 0
#define VolumeRec_volName 4
#define VolumeRec_totalBlocks 8
#define VolumeRec_freeBlocks 12
#define VolumeRec_fileSysID 16
#define JudgeNameRecGS_pCount 0
#define JudgeNameRecGS_fileSysID 2
#define JudgeNameRecGS_nameType 4
#define JudgeNameRecGS_syntax 6
#define JudgeNameRecGS_maxLen 10
#define JudgeNameRecGS_name 12
#define JudgeNameRecGS_nameFlags 16
#define PositionRecGS_pCount 0
#define PositionRecGS_refNum 2
#define PositionRecGS_position 4
#define MarkRec_markRefNum 0
#define MarkRec_position 2
#define EOFRecGS_pCount 0
#define EOFRecGS_refNum 2
#define EOFRecGS_eof 4
#define EOFRec_eofRefNum 0
#define EOFRec_eofPosition 2
#define IORecGS_pCount 0
#define IORecGS_refNum 2
#define IORecGS_dataBuffer 4
#define IORecGS_requestCount 8
#define IORecGS_transferCount 12
#define IORecGS_cachePriority 16
#define FileIORec_fileRefNum 0
#define FileIORec_dataBuffer 2
#define FileIORec_requestCount 6
#define FileIORec_transferCount 10
#define SetPositionRecGS_pCount 0
#define SetPositionRecGS_refNum 2
#define SetPositionRecGS_base 4
#define SetPositionRecGS_displacement 6
#define DevNumRecGS_pCount 0
#define DevNumRecGS_devName 2
#define DevNumRecGS_devNum 6
#define DevNumRec_devName 0
#define DevNumRec_devNum 4

63
src/glog.c Normal file
View File

@ -0,0 +1,63 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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 <stdio.h>
#include <time.h>
#include <stdarg.h>
#include "glog.h"
int glog(const char *s) {
time_t timer;
char buffer[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
printf("%s - %s\n", buffer, s);
return 0;
}
int glogf(const char *fmt, ...) {
time_t timer;
char buffer[26];
struct tm* tm_info;
time(&timer);
tm_info = localtime(&timer);
strftime(buffer, 26, "%Y-%m-%d %H:%M:%S", tm_info);
printf("%s - ", buffer);
va_list ap;
va_start(ap, fmt);
vprintf(fmt, ap);
va_end(ap);
fputc('\n', stdout);
return 0;
}

30
src/glog.h Normal file
View File

@ -0,0 +1,30 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#ifdef __cplusplus
extern "C" {
#endif
int glog(const char *s);
int glogf(const char *s, ...);
#ifdef __cplusplus
}
#endif

186
src/gsos.h Normal file
View File

@ -0,0 +1,186 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#define readEnableAllowWrite 0x0000
#define readEnable 0x0001
#define writeEnable 0x0002
#define readWriteEnable 0x0003
#define fileInvisible 0x0004 /* Invisible bit */
#define backupNeeded 0x0020 /* backup needed bit: CreateRec/ OpenRec access field. (Must be 0 in requestAccess field ) */
#define renameEnable 0x0040 /* rename enable bit: CreateRec/ OpenRec access and requestAccess fields */
#define destroyEnable 0x0080 /* destroy enable bit: CreateRec/ OpenRec access and requestAccess fields */
#define startPlus 0x0000 /* base -> setMark = displacement */
#define eofMinus 0x0001 /* base -> setMark = eof - displacement */
#define markPlus 0x0002 /* base -> setMark = mark + displacement */
#define markMinus 0x0003 /* base -> setMark = mark - displacement */
/* cachePriority Codes */
#define cacheOff 0x0000 /* do not cache blocks invloved in this read */
#define cacheOn 0x0001 /* cache blocks invloved in this read if possible */
/* Error Codes */
#define badSystemCall 0x0001 /* bad system call number */
#define invalidPcount 0x0004 /* invalid parameter count */
#define gsosActive 0x0007 /* GS/OS already active */
#ifndef devNotFound /* device not found */
#define devNotFound 0x0010
#endif
#define invalidDevNum 0x0011 /* invalid device number */
#define drvrBadReq 0x0020 /* bad request or command */
#define drvrBadCode 0x0021 /* bad control or status code */
#define drvrBadParm 0x0022 /* bad call parameter */
#define drvrNotOpen 0x0023 /* character device not open */
#define drvrPriorOpen 0x0024 /* character device already open */
#define irqTableFull 0x0025 /* interrupt table full */
#define drvrNoResrc 0x0026 /* resources not available */
#define drvrIOError 0x0027 /* I/O error */
#define drvrNoDevice 0x0028 /* device not connected */
#define drvrBusy 0x0029 /* call aborted; driver is busy */
#define drvrWrtProt 0x002B /* device is write protected */
#define drvrBadCount 0x002C /* invalid byte count */
#define drvrBadBlock 0x002D /* invalid block address */
#define drvrDiskSwitch 0x002E /* disk has been switched */
#define drvrOffLine 0x002F /* device off line/ no media present */
#define badPathSyntax 0x0040 /* invalid pathname syntax */
#define tooManyFilesOpen 0x0042 /* too many files open on server volume */
#define invalidRefNum 0x0043 /* invalid reference number */
#ifndef pathNotFound /* subdirectory does not exist */
#define pathNotFound 0x0044
#endif
#define volNotFound 0x0045 /* volume not found */
#ifndef fileNotFound /* file not found */
#define fileNotFound 0x0046
#endif
#define dupPathname 0x0047 /* create or rename with existing name */
#define volumeFull 0x0048 /* volume full error */
#define volDirFull 0x0049 /* volume directory full */
#define badFileFormat 0x004A /* version error (incompatible file format) */
#ifndef badStoreType /* unsupported (or incorrect) storage type */
#define badStoreType 0x004B
#endif
#ifndef eofEncountered /* end-of-file encountered */
#define eofEncountered 0x004C
#endif
#define outOfRange 0x004D /* position out of range */
#define invalidAccess 0x004E /* access not allowed */
#define buffTooSmall 0x004F /* buffer too small */
#define fileBusy 0x0050 /* file is already open */
#define dirError 0x0051 /* directory error */
#define unknownVol 0x0052 /* unknown volume type */
#ifndef paramRangeErr /* parameter out of range */
#define paramRangeErr 0x0053
#endif
#define outOfMem 0x0054 /* out of memory */
#define dupVolume 0x0057 /* duplicate volume name */
#define notBlockDev 0x0058 /* not a block device */
#ifndef invalidLevel /* specifield level outside legal range */
#define invalidLevel 0x0059
#endif
#define damagedBitMap 0x005A /* block number too large */
#define badPathNames 0x005B /* invalid pathnames for ChangePath */
#define notSystemFile 0x005C /* not an executable file */
#define osUnsupported 0x005D /* Operating System not supported */
#ifndef stackOverflow /* too many applications on stack */
#define stackOverflow 0x005F
#endif
#define dataUnavail 0x0060 /* Data unavailable */
#define endOfDir 0x0061 /* end of directory has been reached */
#define invalidClass 0x0062 /* invalid FST call class */
#define resForkNotFound 0x0063 /* file does not contain required resource */
#define invalidFSTID 0x0064 /* error - FST ID is invalid */
#define invalidFSTop 0x0065 /* invalid FST operation */
#define fstCaution 0x0066 /* FST handled call, but result is weird */
#define devNameErr 0x0067 /* device exists with same name as replacement name */
#define defListFull 0x0068 /* device list is full */
#define supListFull 0x0069 /* supervisor list is full */
#define fstError 0x006a /* generic FST error */
#define resExistsErr 0x0070 /* cannot expand file, resource already exists */
#define resAddErr 0x0071 /* cannot add resource fork to this type file */
#define networkError 0x0088 /* generic network error */
/* fileSys IDs */
#define proDOSFSID 0x0001 /* ProDOS/SOS */
#define dos33FSID 0x0002 /* DOS 3.3 */
#define dos32FSID 0x0003 /* DOS 3.2 */
#define dos31FSID 0x0003 /* DOS 3.1 */
#define appleIIPascalFSID 0x0004 /* Apple II Pascal */
#define mfsFSID 0x0005 /* Macintosh (flat file system) */
#define hfsFSID 0x0006 /* Macintosh (hierarchical file system) */
#define lisaFSID 0x0007 /* Lisa file system */
#define appleCPMFSID 0x0008 /* Apple CP/M */
#define charFSTFSID 0x0009 /* Character FST */
#define msDOSFSID 0x000A /* MS/DOS */
#define highSierraFSID 0x000B /* High Sierra */
#define iso9660FSID 0x000C /* ISO 9660 */
#define appleShareFSID 0x000D /* ISO 9660 */
/* FSTInfo.attributes Codes */
#define characterFST 0x4000 /* character FST */
#define ucFST 0x8000 /* SCM should upper case pathnames before passing them to the FST */
/* QuitRec.flags Codes */
#define onStack 0x8000 /* place state information about quitting program on the quit return stack */
#define restartable 0x4000 /* the quitting program is capable of being restarted from its dormant memory */
/* storageType Codes */
#define seedling 0x0001 /* standard file with seedling structure */
#define standardFile 0x0001 /* standard file type (no resource fork) */
#define sapling 0x0002 /* standard file with sapling structure */
#define tree 0x0003 /* standard file with tree structure */
#define pascalRegion 0x0004 /* UCSD Pascal region on a partitioned disk */
#define extendedFile 0x0005 /* extended file type (with resource fork) */
#define directoryFile 0x000D /* volume directory or subdirectory file */
/* version Codes */
#define minorRelNumMask 0x00FF /* minor release number */
#define majorRelNumMask 0x7F00 /* major release number */
#define finalRelNumMask 0x8000 /* final release number */
/* Other Constants */
#define isFileExtended 0x8000 /* GetDirEntryGS */
/* DControl Codes */
#define resetDevice 0x0000
#define formatDevice 0x0001
#define eject 0x0002
#define setConfigParameters 0x0003
#define setWaitStatus 0x0004
#define setFormatOptions 0x0005
#define assignPartitionOwner 0x0006
#define armSignal 0x0007
#define disarmSignal 0x0008
#define setPartitionMap 0x0009

BIN
src/gsport Executable file

Binary file not shown.

650
src/host_common.c Normal file
View File

@ -0,0 +1,650 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#define _BSD_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <libgen.h>
#include "defc.h"
#include "gsos.h"
#include "fst.h"
#ifdef _WIN32
#include <Windows.h>
#endif
#include "host_common.h"
char *host_root = NULL;
char *g_cfg_host_path = ""; // must not be null.
int g_cfg_host_read_only = 0;
int g_cfg_host_crlf = 1;
int g_cfg_host_merlin = 0;
/*
* simple malloc pool to simplify code. Should never need > 4 allocations.
*
*/
static void *gc[16];
static void **gc_ptr = &gc[0];
void *host_gc_malloc(size_t size) {
if (gc_ptr == &gc[16]) {
errno = ENOMEM;
return NULL;
}
void *ptr = malloc(size);
if (ptr) {
*gc_ptr++ = ptr;
}
return ptr;
}
void host_gc_free(void) {
while (gc_ptr > gc) free(*--gc_ptr);
}
char *host_gc_strdup(const char *src) {
if (!src) return "";
if (!*src) return "";
int len = strlen(src) + 1;
char *cp = host_gc_malloc(len);
memcpy(cp, src, len);
return cp;
}
char *host_gc_append_path(const char *a, const char *b) {
/* strip all leading /s from b) */
while (*b == '/') ++b;
int aa = strlen(a);
int bb = strlen(b);
char *cp = host_gc_malloc(aa + bb + 2);
if (!cp) return NULL;
memcpy(cp, a, aa);
int len = aa;
/* strip all trailing /s from b */
while (len > 2 && cp[len-1] == '/') --len;
cp[len++] = '/';
memcpy(cp + len, b, bb);
len += bb;
cp[len] = 0;
return cp;
}
char *host_gc_append_string(const char *a, const char *b) {
int aa = strlen(a);
int bb = strlen(b);
char *cp = host_gc_malloc(aa + bb + 2);
if (!cp) return NULL;
memcpy(cp, a, aa);
int len = aa;
memcpy(cp + len, b, bb);
len += bb;
cp[len] = 0;
return cp;
}
/*
* text conversion.
*/
void host_cr_to_lf(byte *buffer, size_t size) {
size_t i;
for (i = 0; i < size; ++i) {
if (buffer[i] == '\r') buffer[i] = '\n';
}
}
void host_lf_to_cr(byte *buffer, size_t size) {
size_t i;
for (i = 0; i < size; ++i) {
if (buffer[i] == '\n') buffer[i] = '\r';
}
}
void host_merlin_to_text(byte *buffer, size_t size) {
size_t i;
for (i = 0; i < size; ++i) {
byte b = buffer[i];
if (b == 0xa0) b = '\t';
b &= 0x7f;
if (b == '\r') b = '\n';
buffer[i] = b;
}
}
void host_text_to_merlin(byte *buffer, size_t size) {
size_t i;
for (i = 0; i < size; ++i) {
byte b = buffer[i];
if (b == '\t') b = 0xa0;
if (b == '\n') b = '\r';
if (b != ' ') b |= 0x80;
buffer[i] = b;
}
}
/*
* error remapping.
* NOTE - GS/OS errors are a superset of P8 errors
*/
static word32 enoent(const char *path) {
/*
some op on path return ENOENT. check if it's
fileNotFound or pathNotFound
*/
char *p = (char *)path;
for(;;) {
struct stat st;
p = dirname(p);
if (p == NULL) break;
if (p[0] == '.' && p[1] == 0) break;
if (p[0] == '/' && p[1] == 0) break;
if (stat(p, &st) < 0) return pathNotFound;
}
return fileNotFound;
}
word32 host_map_errno(int xerrno) {
switch(xerrno) {
case 0: return 0;
case EBADF:
return invalidAccess;
#ifdef EDQUOT
case EDQUOT:
#endif
case EFBIG:
return volumeFull;
case ENOENT:
return fileNotFound;
case ENOTDIR:
return pathNotFound;
case ENOMEM:
return outOfMem;
case EEXIST:
return dupPathname;
case ENOTEMPTY:
return invalidAccess;
default:
return drvrIOError;
}
}
word32 host_map_errno_path(int xerrno, const char *path) {
if (xerrno == ENOENT) return enoent(path);
return host_map_errno(xerrno);
}
const char *host_error_name(word16 error) {
static char *errors[] = {
"",
"badSystemCall",
"",
"",
"invalidPcount",
"",
"",
"gsosActive",
"",
"",
"",
"",
"",
"",
"",
"",
// 0x10
"devNotFound",
"invalidDevNum",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
// 0x20
"drvrBadReq",
"drvrBadCode",
"drvrBadParm",
"drvrNotOpen",
"drvrPriorOpen",
"irqTableFull",
"drvrNoResrc",
"drvrIOError",
"drvrNoDevice",
"drvrBusy",
"",
"drvrWrtProt",
"drvrBadCount",
"drvrBadBlock",
"drvrDiskSwitch",
"drvrOffLine",
// 0x30
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
// 0x40
"badPathSyntax",
"",
"tooManyFilesOpen",
"invalidRefNum",
"pathNotFound",
"volNotFound",
"fileNotFound",
"dupPathname",
"volumeFull",
"volDirFull",
"badFileFormat",
"badStoreType",
"eofEncountered",
"outOfRange",
"invalidAccess",
"buffTooSmall",
// 0x50
"fileBusy",
"dirError",
"unknownVol",
"paramRangeErr",
"outOfMem",
"",
"badBufferAddress", /* P8 MLI only */
"dupVolume",
"notBlockDev",
"invalidLevel",
"damagedBitMap",
"badPathNames",
"notSystemFile",
"osUnsupported",
"",
"stackOverflow",
// 0x60
"dataUnavail",
"endOfDir",
"invalidClass",
"resForkNotFound",
"invalidFSTID",
"invalidFSTop",
"fstCaution",
"devNameErr",
"defListFull",
"supListFull",
"fstError",
"",
"",
"",
"",
"",
//0x70
"resExistsErr",
"resAddErr",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
//0x80
"",
"",
"",
"",
"",
"",
"",
"",
"networkError"
};
if (error < sizeof(errors) / sizeof(errors[0]))
return errors[error];
return "";
}
/*
* File info.
*/
static int hex(byte c) {
if (c >= '0' && c <= '9') return c - '0';
if (c >= 'a' && c <= 'f') return c + 10 - 'a';
if (c >= 'A' && c <= 'F') return c + 10 - 'A';
return 0;
}
int host_finder_info_to_filetype(const byte *buffer, word16 *file_type, word32 *aux_type) {
if (!memcmp("pdos", buffer + 4, 4))
{
if (buffer[0] == 'p') {
*file_type = buffer[1];
*aux_type = (buffer[2] << 8) | buffer[3];
return 0;
}
if (!memcmp("PSYS", buffer, 4)) {
*file_type = 0xff;
*aux_type = 0x0000;
return 0;
}
if (!memcmp("PS16", buffer, 4)) {
*file_type = 0xb3;
*aux_type = 0x0000;
return 0;
}
// old mpw method for encoding.
if (!isxdigit(buffer[0]) && isxdigit(buffer[1]) && buffer[2] == ' ' && buffer[3] == ' ')
{
*file_type = (hex(buffer[0]) << 8) | hex(buffer[1]);
*aux_type = 0;
return 0;
}
}
if (!memcmp("TEXT", buffer, 4)) {
*file_type = 0x04;
*aux_type = 0x0000;
return 0;
}
if (!memcmp("BINA", buffer, 4)) {
*file_type = 0x00;
*aux_type = 0x0000;
return 0;
}
if (!memcmp("dImgdCpy", buffer, 8)) {
*file_type = 0xe0;
*aux_type = 0x0005;
return 0;
}
if (!memcmp("MIDI", buffer, 4)) {
*file_type = 0xd7;
*aux_type = 0x0000;
return 0;
}
if (!memcmp("AIFF", buffer, 4)) {
*file_type = 0xd8;
*aux_type = 0x0000;
return 0;
}
if (!memcmp("AIFC", buffer, 4)) {
*file_type = 0xd8;
*aux_type = 0x0001;
return 0;
}
return -1;
}
int host_file_type_to_finder_info(byte *buffer, word16 file_type, word32 aux_type) {
if (file_type > 0xff || aux_type > 0xffff) return -1;
if (!file_type && aux_type == 0x0000) {
memcpy(buffer, "BINApdos", 8);
return 0;
}
if (file_type == 0x04 && aux_type == 0x0000) {
memcpy(buffer, "TEXTpdos", 8);
return 0;
}
if (file_type == 0xff && aux_type == 0x0000) {
memcpy(buffer, "PSYSpdos", 8);
return 0;
}
if (file_type == 0xb3 && aux_type == 0x0000) {
memcpy(buffer, "PS16pdos", 8);
return 0;
}
if (file_type == 0xd7 && aux_type == 0x0000) {
memcpy(buffer, "MIDIpdos", 8);
return 0;
}
if (file_type == 0xd8 && aux_type == 0x0000) {
memcpy(buffer, "AIFFpdos", 8);
return 0;
}
if (file_type == 0xd8 && aux_type == 0x0001) {
memcpy(buffer, "AIFCpdos", 8);
return 0;
}
if (file_type == 0xe0 && aux_type == 0x0005) {
memcpy(buffer, "dImgdCpy", 8);
return 0;
}
memcpy(buffer, "p pdos", 8);
buffer[1] = (file_type) & 0xff;
buffer[2] = (aux_type >> 8) & 0xff;
buffer[3] = (aux_type) & 0xff;
return 0;
}
#undef _
#define _(a, b, c) { a, sizeof(a) - 1, b, c }
struct ftype_entry {
char *ext;
unsigned length;
unsigned file_type;
unsigned aux_type;
};
static struct ftype_entry suffixes[] = {
_("c", 0xb0, 0x0008),
_("cc", 0xb0, 0x0008),
_("h", 0xb0, 0x0008),
_("rez", 0xb0, 0x0015),
_("asm", 0xb0, 0x0003),
_("mac", 0xb0, 0x0003),
_("pas", 0xb0, 0x0005),
_("txt", 0x04, 0x0000),
_("text", 0x04, 0x0000),
_("s", 0x04, 0x0000),
{ 0, 0, 0, 0}
};
static struct ftype_entry prefixes[] = {
_("m16.", 0xb0, 0x0003),
_("e16.", 0xb0, 0x0003),
{ 0, 0, 0, 0}
};
#undef _
void host_synthesize_file_xinfo(const char *path, struct file_info *fi) {
/* guess the file type / auxtype based on extension */
int n;
const char *dot = NULL;
const char *slash = NULL;
for(n = 0;; ++n) {
char c = path[n];
if (c == 0) break;
else if (c == '/') { slash = path + n + 1; dot = NULL; }
else if (c == '.') dot = path + n + 1;
}
if (dot && *dot) {
for (n = 0; n < sizeof(suffixes) / sizeof(suffixes[0]); ++n) {
if (!suffixes[n].ext) break;
if (!strcasecmp(dot, suffixes[n].ext)) {
fi->file_type = suffixes[n].file_type;
fi->aux_type = suffixes[n].aux_type;
return;
}
}
}
return;
}
void host_hexdump(word32 address, int size) {
const char *HexMap = "0123456789abcdef";
char buffer1[16 * 3 + 1 + 1];
char buffer2[16 + 1];
unsigned i, j;
printf("\n");
while (size > 0) {
memset(buffer1, ' ', sizeof(buffer1));
memset(buffer2, ' ', sizeof(buffer2));
int linelen = size;
if (linelen > 16) linelen = 16;
for (i = 0, j = 0; i < linelen; i++) {
unsigned x = get_memory_c(address + i, 0);
buffer1[j++] = HexMap[x >> 4];
buffer1[j++] = HexMap[x & 0x0f];
j++;
if (i == 7) j++;
x &= 0x7f;
// isascii not part of std:: and may be a macro.
buffer2[i] = isascii(x) && isprint(x) ? x : '.';
}
buffer1[sizeof(buffer1) - 1] = 0;
buffer2[sizeof(buffer2) - 1] = 0;
printf("%06x:\t%s\t%s\n",
address, buffer1, buffer2);
address += 16;
size -= 16;
}
printf("\n");
}
void host_hexdump_native(void *data, unsigned address, int size) {
const char *HexMap = "0123456789abcdef";
char buffer1[16 * 3 + 1 + 1];
char buffer2[16 + 1];
unsigned i, j;
printf("\n");
while (size > 0) {
memset(buffer1, ' ', sizeof(buffer1));
memset(buffer2, ' ', sizeof(buffer2));
int linelen = size;
if (linelen > 16) linelen = 16;
for (i = 0, j = 0; i < linelen; i++) {
unsigned x = ((byte *)data)[address + i];
buffer1[j++] = HexMap[x >> 4];
buffer1[j++] = HexMap[x & 0x0f];
j++;
if (i == 7) j++;
x &= 0x7f;
// isascii not part of std:: and may be a macro.
buffer2[i] = isascii(x) && isprint(x) ? x : '.';
}
buffer1[sizeof(buffer1) - 1] = 0;
buffer2[sizeof(buffer2) - 1] = 0;
printf("%06x:\t%s\t%s\n",
address, buffer1, buffer2);
address += 16;
size -= 16;
}
printf("\n");
}
void host_free_directory(char **data, size_t count) {
for (int i = 0; i < count; ++i) free(data[i]);
free(data);
}

186
src/host_common.h Normal file
View File

@ -0,0 +1,186 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#ifdef _WIN32
#include <stdint.h>
#pragma pack(push, 2)
struct AFP_Info {
uint32_t magic;
uint32_t version;
uint32_t file_id;
uint32_t backup_date;
uint8_t finder_info[32];
uint16_t prodos_file_type;
uint32_t prodos_aux_type;
uint8_t reserved[6];
};
#pragma pack(pop)
void afp_init(struct AFP_Info *info, word16 file_type, word32 aux_type);
BOOL afp_verify(struct AFP_Info *info);
int afp_to_filetype(struct AFP_Info *info, word16 *file_type, word32 *aux_type);
enum { prefer_prodos, prefer_hfs };
void afp_synchronize(struct AFP_Info *info, int preference);
#endif
#ifdef _WIN32
typedef FILETIME host_time_t;
typedef struct AFP_Info host_finder_info_t;
#else
typedef time_t host_time_t;
typedef unsigned char host_finder_info_t[32];
#endif
enum {
file_non,
file_regular,
file_resource,
file_directory,
};
enum {
translate_none,
translate_crlf,
translate_merlin,
};
struct file_info {
host_time_t create_date;
host_time_t modified_date;
word16 access;
word16 storage_type;
word16 file_type;
word32 aux_type;
word32 eof;
word32 blocks;
word32 resource_eof;
word32 resource_blocks;
int has_fi;
#ifdef _WIN32
struct AFP_Info afp;
#else
byte finder_info[32];
#endif
};
extern Engine_reg engine;
#define SEC() engine.psr |= 0x01
#define CLC() engine.psr &= ~0x01
#define SEV() engine.psr |= 0x40
#define CLV() engine.psr &= ~0x40
#define SEZ() engine.psr |= 0x02
#define CLZ() engine.psr &= ~0x02
#define SEI() engine.psr |= 0x04
#define CLI() engine.psr &= ~0x04
enum {
C = 0x01,
Z = 0x02,
I = 0x04,
D = 0x08,
X = 0x10,
M = 0x20,
V = 0x40,
N = 0x80
};
extern char *g_cfg_host_path;
extern int g_cfg_host_read_only;
extern int g_cfg_host_crlf;
extern int g_cfg_host_merlin;
extern char *host_root;
unsigned host_startup(void);
void host_shutdown(void);
#ifdef _WIN32
int host_is_root(const BY_HANDLE_FILE_INFORMATION *info);
#else
int host_is_root(struct stat *);
#endif
/* garbage collected string routines */
void *host_gc_malloc(size_t size);
void host_gc_free(void);
char *host_gc_strdup(const char *src);
char *host_gc_append_path(const char *a, const char *b);
char *host_gc_append_string(const char *a, const char *b);
/* text conversion */
void host_cr_to_lf(byte *buffer, size_t size);
void host_lf_to_cr(byte *buffer, size_t size);
void host_merlin_to_text(byte *buffer, size_t size);
void host_text_to_merlin(byte *buffer, size_t size);
/* errno -> IIgs/mli error */
word32 host_map_errno(int xerrno);
word32 host_map_errno_path(int xerrno, const char *path);
const char *host_error_name(word16 error);
#ifdef _WIN32
word32 host_map_win32_error(DWORD);
word32 host_map_win32_error_path(DWORD, const char *path);
#endif
/* file info */
int host_finder_info_to_filetype(const byte *buffer, word16 *file_type, word32 *aux_type);
int host_file_type_to_finder_info(byte *buffer, word16 file_type, word32 aux_type);
void host_get_file_xinfo(const char *path, struct file_info *fi);
word32 host_get_file_info(const char *path, struct file_info *fi);
word32 host_set_file_info(const char *path, struct file_info *fi);
/* guesses filetype/auxtype from extension */
void host_synthesize_file_xinfo(const char *path, struct file_info *fi);
void host_set_date_time_rec(word32 ptr, host_time_t time);
void host_set_date_time(word32 ptr, host_time_t time);
host_time_t host_get_date_time(word32 ptr);
host_time_t host_get_date_time_rec(word32 ptr);
/* convert to prodos date/time */
word32 host_convert_date_time(host_time_t time);
/* scan a directory, return array of char * */
unsigned host_scan_directory(const char *path, char ***out, size_t *entries, unsigned p8);
void host_free_directory(char **data, size_t count);
/* 0x01, 0x0d, 0x0f, 0 on error */
unsigned host_storage_type(const char *path, word16 *error_ptr);
void host_hexdump(word32 address, int size);
void host_hexdump_native(void *data, unsigned address, int size);

1879
src/host_fst.c Normal file

File diff suppressed because it is too large Load Diff

1567
src/host_mli.c Normal file

File diff suppressed because it is too large Load Diff

2078
src/icongs.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2013 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -20,6 +21,7 @@
*/
#include "defc.h"
#include "glog.h"
#ifdef __linux__
# include <linux/joystick.h>
@ -32,9 +34,19 @@
# include <time.h>
#endif
#ifdef HAVE_SDL
# include "SDL.h"
//@todo: multiple joysticks/more buttons/button config
//static SDL_Joystick *joy0, *joy1;
SDL_Joystick *gGameController = NULL;
#endif
extern int g_joystick_native_type1; /* in paddles.c */
extern int g_joystick_native_type2; /* in paddles.c */
extern int g_joystick_native_type; /* in paddles.c */
extern int g_joystick_type;
extern int g_paddle_buttons;
extern int g_paddle_val[];
@ -45,13 +57,98 @@ const char *g_joystick_dev = "/dev/input/js0"; /* default joystick dev file */
int g_joystick_native_fd = -1;
int g_joystick_num_axes = 0;
int g_joystick_num_buttons = 0;
int g_joystick_number = 0; // SDL2
int g_joystick_x_axis = 0; // SDL2
int g_joystick_y_axis = 1; // SDL2
int g_joystick_button_0 = 0; // SDL2
int g_joystick_button_1 = 1; // SDL2
int g_joystick_x2_axis = 2; // SDL2
int g_joystick_y2_axis = 3; // SDL2
int g_joystick_button_2 = 2; // SDL2
int g_joystick_button_3 = 3; // SDL2
#define JOY2SUPPORT
#ifdef __linux__
#if defined(HAVE_SDL) && !defined(JOYSTICK_DEFINED)
# define JOYSTICK_DEFINED
void
joystick_init()
{
void joystick_init() {
int i;
if( SDL_Init( SDL_INIT_JOYSTICK ) < 0 ) {
glogf( "SDL could not initialize joystick! SDL Error: %s", SDL_GetError() );
} else {
glog("SDL2 joystick initialized");
}
if (SDL_NumJoysticks()<1) {
glog("No joysticks detected");
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
} else {
// @todo: make controller configurable
// @todo: add multiple controller support
gGameController = SDL_JoystickOpen( g_joystick_number );
if( gGameController == NULL ) {
glogf( "Warning: Unable to open game controller! SDL Error: %s", SDL_GetError() );
}
}
g_joystick_native_type = 2;
g_joystick_native_type1 = 2;
g_joystick_native_type2 = -1;
for(i = 0; i < 4; i++) {
g_paddle_val[i] = 180;
}
g_joystick_type = JOYSTICK_TYPE_NATIVE_1;
SDL_JoystickUpdate();
joystick_update(0.0);
}
void joystick_update(double dcycs) {
if (gGameController) {
SDL_JoystickUpdate();
g_paddle_val[0] = (int)SDL_JoystickGetAxis(gGameController, g_joystick_x_axis); // default is 0
g_paddle_val[1] = (int)SDL_JoystickGetAxis(gGameController, g_joystick_y_axis); // default is 1
g_paddle_val[2] = (int)SDL_JoystickGetAxis(gGameController, g_joystick_x2_axis); // default is 2
g_paddle_val[3] = (int)SDL_JoystickGetAxis(gGameController, g_joystick_y2_axis); // default is 3
if (SDL_JoystickGetButton(gGameController, g_joystick_button_0)) {
g_paddle_buttons = g_paddle_buttons | 1;
} else {
g_paddle_buttons = g_paddle_buttons & (~1);
}
if (SDL_JoystickGetButton(gGameController, g_joystick_button_1)) {
g_paddle_buttons = g_paddle_buttons | 2;
} else {
g_paddle_buttons = g_paddle_buttons & (~2);
}
if (SDL_JoystickGetButton(gGameController, g_joystick_button_2)) {
g_paddle_buttons = g_paddle_buttons | 4;
} else {
g_paddle_buttons = g_paddle_buttons & (~4);
}
if (SDL_JoystickGetButton(gGameController, g_joystick_button_3)) {
g_paddle_buttons = g_paddle_buttons | 8;
} else {
g_paddle_buttons = g_paddle_buttons & (~8);
}
paddle_update_trigger_dcycs(dcycs);
}
}
void joystick_update_buttons() {
}
void joystick_shut() {
SDL_JoystickClose( gGameController );
gGameController = NULL;
}
#endif
#if defined(__linux__) && !defined(JOYSTICK_DEFINED)
# define JOYSTICK_DEFINED
void joystick_init() {
char joy_name[MAX_JOY_NAME];
int version;
int fd;
@ -90,9 +187,7 @@ joystick_init()
/* joystick_update_linux() called from paddles.c. Update g_paddle_val[] */
/* and g_paddle_buttons with current information */
void
joystick_update(double dcycs)
{
void joystick_update(double dcycs) {
struct js_event js; /* the linux joystick event record */
int mask;
int val;
@ -134,17 +229,13 @@ joystick_update(double dcycs)
// }
}
void
joystick_update_buttons()
{
void joystick_update_buttons() {
}
#endif /* LINUX */
#ifdef _WIN32
#if defined(_WIN32) && !defined(JOYSTICK_DEFINED)
# define JOYSTICK_DEFINED
void
joystick_init()
{
void joystick_init() {
JOYINFO info;
JOYCAPS joycap;
MMRESULT ret1, ret2;
@ -152,7 +243,7 @@ joystick_init()
// Check that there is a joystick device
if(joyGetNumDevs() <= 0) {
printf("No joystick hardware detected\n");
glog("No joystick hardware detected");
g_joystick_native_type1 = -1;
g_joystick_native_type2 = -1;
return;
@ -180,7 +271,7 @@ joystick_init()
}
if (g_joystick_native_type1<0 && g_joystick_native_type2 <0) {
printf ("No joystick is attached\n");
glog("No joystick is attached");
return;
}
@ -192,9 +283,7 @@ joystick_init()
joystick_update(0.0);
}
void
joystick_update(double dcycs)
{
void joystick_update(double dcycs) {
JOYCAPS joycap;
JOYINFO info;
UINT id;
@ -205,10 +294,9 @@ joystick_update(double dcycs)
ret1 = joyGetDevCaps(id, &joycap, sizeof(joycap));
ret2 = joyGetPos(id, &info);
if(ret1 == JOYERR_NOERROR && ret2 == JOYERR_NOERROR) {
/* val should be -32767 to +32767 */
g_paddle_val[0] = -32767 + (info.wXpos - joycap.wXmin) * 65535 /
g_paddle_val[0] = (info.wXpos - joycap.wXmin) * 32768 /
(joycap.wXmax - joycap.wXmin);
g_paddle_val[1] = -32767 + (info.wYpos - joycap.wYmin) * 65535 /
g_paddle_val[1] = (info.wYpos - joycap.wYmin) * 32768 /
(joycap.wYmax - joycap.wYmin);
if(info.wButtons & JOY_BUTTON1) {
g_paddle_buttons = g_paddle_buttons | 1;
@ -224,9 +312,7 @@ joystick_update(double dcycs)
}
}
void
joystick_update_buttons()
{
void joystick_update_buttons() {
JOYINFOEX info;
UINT id;
@ -249,19 +335,19 @@ joystick_update_buttons()
}
#endif
#ifndef JOYSTICK_DEFINED
/* stubs for the routines */
void
joystick_init()
{
void joystick_init() {
g_joystick_native_type1 = -1;
g_joystick_native_type2 = -1;
g_joystick_native_type = -1;
}
void
joystick_update(double dcycs)
{
void joystick_update(double dcycs) {
int i;
for(i = 0; i < 4; i++) {
@ -270,13 +356,9 @@ joystick_update(double dcycs)
g_paddle_buttons = 0xc;
}
void
joystick_update_buttons()
{
void joystick_update_buttons() {
}
// OG
void joystick_shut()
{
void joystick_shut() {
}
#endif

View File

@ -1,860 +0,0 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2012 by GSport contributors
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#ifdef ACTIVEIPHONE
#include <CoreGraphics/CGContext.h>
#include <CoreGraphics/CGBitmapContext.h>
#include <CoreFoundation/CFURL.h>
#else
#include <CoreFoundation/CoreFoundation.h>
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>
#define ENABLEQD
#endif
#include "defc.h"
#include "protos_macdriver.h"
pascal OSStatus quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore);
pascal OSStatus my_cmd_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
pascal OSStatus my_win_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata);
pascal OSStatus dummy_event_handler(EventHandlerCallRef call_ref, EventRef in_event, void *ignore);
int g_quit_seen = 0;
#define MAX_STATUS_LINES 7
#define X_LINE_LENGTH 88
#define MAX_MAC_ARGS 128
int g_mac_argc = 0;
char *g_mac_argv[MAX_MAC_ARGS];
extern char g_argv0_path[];
extern char *g_status_ptrs[MAX_STATUS_LINES];
extern const char g_gsport_version_str[];
extern int g_warp_pointer;
extern WindowRef g_main_window;
WindowRef g_main_window_saved;
EventHandlerUPP g_quit_handler_UPP;
EventHandlerUPP g_dummy_event_handler_UPP;
RgnHandle g_event_rgnhandle = 0;
FMFontFamily g_status_font_family;
extern word32 g_red_mask;
extern word32 g_green_mask;
extern word32 g_blue_mask;
extern int g_red_left_shift;
extern int g_green_left_shift;
extern int g_blue_left_shift;
extern int g_red_right_shift;
extern int g_green_right_shift;
extern int g_blue_right_shift;
int g_ignore_next_click = 0;
int g_mainwin_active = 0;
int g_mac_mouse_x = 0;
int g_mac_mouse_y = 0;
extern int g_video_act_width;
extern int g_video_act_height;
extern int g_video_act_margin_left;
extern int g_video_act_margin_right;
extern int g_video_act_margin_top;
extern int g_video_act_margin_bottom;
extern int g_screen_depth;
extern int g_force_depth;
extern int g_screen_mdepth;
Ptr g_mac_fullscreen_state = 0;
Rect g_main_window_saved_rect;
extern char *g_fatal_log_strs[];
extern int g_fatal_log;
int
x_show_alert(int is_fatal, const char *str)
{
DialogRef alert;
DialogItemIndex out_item_hit;
CFStringRef cfstrref, cfstrref2;
CFStringRef okstrref;
AlertStdCFStringAlertParamRec alert_param;
OSStatus osstat;
char *bufptr, *buf2ptr;
int sum, len;
int i;
/* The dialog eats all events--including key-up events */
/* Call adb_all_keys_up() to prevent annoying key-repeat problems */
/* for instance, a key-down causes a dialog to appear--and the */
/* eats the key-up event...then as soon as the dialog goes, adb.c */
/* auto-repeat will repeat the key, and the dialog re-appears...*/
adb_all_keys_up();
sum = 20;
for(i = 0; i < g_fatal_log; i++) {
sum += strlen(g_fatal_log_strs[i]);
}
bufptr = (char*)malloc(sum);
buf2ptr = bufptr;
for(i = 0; i < g_fatal_log; i++) {
len = strlen(g_fatal_log_strs[i]);
len = MIN(len, sum);
len = MAX(len, 0);
memcpy(bufptr, g_fatal_log_strs[i], MIN(len, sum));
bufptr += len;
bufptr[0] = 0;
sum = sum - len;
}
cfstrref = CFStringCreateWithCString(NULL, buf2ptr,
kCFStringEncodingMacRoman);
printf("buf2ptr: :%s:\n", buf2ptr);
osstat = GetStandardAlertDefaultParams(&alert_param,
kStdCFStringAlertVersionOne);
if(str) {
// Provide an extra option--create a file
cfstrref2 = CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
CFSTR("Create ./%s"), str);
alert_param.otherText = cfstrref2;
}
okstrref = CFSTR("Click OK to continue");
if(is_fatal) {
okstrref = CFSTR("Click OK to exit GSport");
}
CreateStandardAlert(kAlertStopAlert, cfstrref, okstrref,
&alert_param, &alert);
out_item_hit = -1;
RunStandardAlert(alert, NULL, &out_item_hit);
printf("out_item_hit: %d\n", out_item_hit);
free(buf2ptr);
clear_fatal_logs(); /* free the fatal_log string memory */
return (out_item_hit >= 3);
}
pascal OSStatus
quit_event_handler(EventHandlerCallRef call_ref, EventRef event, void *ignore)
{
OSStatus err;
err = CallNextEventHandler(call_ref, event);
if(err == noErr) {
g_quit_seen = 1;
}
return err;
}
void
show_simple_alert(char *str1, char *str2, char *str3, int num)
{
char buf[256];
g_fatal_log_strs[0] = gsport_malloc_str(str1);
g_fatal_log_strs[1] = gsport_malloc_str(str2);
g_fatal_log_strs[2] = gsport_malloc_str(str3);
g_fatal_log = 3;
if(num != 0) {
snprintf(buf, 250, ": %d", num);
g_fatal_log_strs[g_fatal_log++] = gsport_malloc_str(buf);
}
x_show_alert(0, 0);
}
void
x_dialog_create_gsport_conf(const char *str)
{
char *path;
char tmp_buf[512];
int ret;
ret = x_show_alert(1, str);
if(ret) {
config_write_config_gsport_file();
}
}
pascal OSStatus
my_cmd_handler( EventHandlerCallRef handlerRef, EventRef event, void *userdata)
{
OSStatus osresult;
HICommand command;
word32 command_id;
osresult = eventNotHandledErr;
GetEventParameter(event, kEventParamDirectObject, typeHICommand, NULL,
sizeof(HICommand), NULL, &command);
command_id = (word32)command.commandID;
switch(command_id) {
case 'Kbep':
SysBeep(10);
osresult = noErr;
break;
case 'abou':
show_simple_alert("GSport v", (char *)g_gsport_version_str,
"\nCopyright 2010 - 2011 GSport Contributors\n"
"Latest version at http://gsport.sourceforge.net/\n", 0);
osresult = noErr;
break;
case 'KCFG':
#ifdef ACTIVEGS
#else
cfg_toggle_config_panel();
#endif
osresult = noErr;
break;
case 'quit':
break;
case 'swin':
/* not sure what this is, but Panther sends it */
break;
default:
printf("commandID %08x unknown\n", command_id);
SysBeep(90);
break;
}
return osresult;
}
pascal OSStatus
my_win_handler(EventHandlerCallRef handlerRef, EventRef event, void *userdata)
{
OSStatus os_result;
UInt32 event_kind;
os_result = eventNotHandledErr;
// SysBeep(1);
event_kind = GetEventKind(event);
// show_alert("win handler", event_kind);
if(event_kind == kEventWindowDrawContent)
{
update_window();
} if(event_kind == kEventWindowClose) {
// OG Use HALT_WANTTOQUIT pardigme
//g_quit_sim_now = 1;
set_halt_act(HALT_WANTTOQUIT);
#ifndef ACTIVEGS
g_quit_seen = 1;
my_exit(0);
#endif
} else {
//show_event(GetEventClass(event), event_kind, 0);
update_window();
}
return os_result;
}
pascal OSStatus
dummy_event_handler(EventHandlerCallRef call_ref, EventRef in_event,
void *ignore)
{
OSStatus err;
EventHandlerRef installed_handler;
EventTypeSpec event_spec = { kEventClassApplication, kEventAppQuit };
// From http://developer.apple.com/qa/qa2001/qa1061.html
// Trick to move main event queue to use ReceiveNextEvent in an event
// handler called by RunApplicationEventLoop
err = InstallApplicationEventHandler(g_quit_handler_UPP, 1, &event_spec,
NULL, &installed_handler);
gsportmain(g_mac_argc, g_mac_argv);
return noErr;
}
void
check_input_events()
{
OSStatus err;
EventTargetRef target;
EventRef event;
UInt32 event_class, event_kind;
byte mac_keycode;
UInt32 keycode;
UInt32 modifiers;
Point mouse_point, mouse_delta_point;
WindowRef window_ref;
int button, button_state;
EventMouseButton mouse_button;
int handled;
int mouse_events;
int is_up;
int in_win;
int ignore;
if(g_quit_seen) {
exit(0);
}
SetPortWindowPort(g_main_window);
mouse_events = 0;
target = GetEventDispatcherTarget();
while(1) {
err = ReceiveNextEvent(0, NULL, kEventDurationNoWait,
true, &event);
if(err == eventLoopTimedOutErr) {
break;
}
if(err != noErr) {
printf("ReceiveNextEvent err: %d\n", (int)err);
break;
}
event_class = GetEventClass(event);
event_kind = GetEventKind(event);
handled = 0;
switch(event_class) {
case kEventClassKeyboard:
handled = 1;
keycode = 0;
modifiers = 0;
GetEventParameter(event, kEventParamKeyMacCharCodes,
typeChar, NULL, sizeof(byte), NULL,
&mac_keycode);
GetEventParameter(event, kEventParamKeyCode,
typeUInt32, NULL, sizeof(UInt32), NULL,
&keycode);
GetEventParameter(event, kEventParamKeyModifiers,
typeUInt32, NULL, sizeof(UInt32), NULL,
&modifiers);
mac_update_modifiers((word32)modifiers);
// Key up/down event
is_up = -1;
switch(event_kind) {
case kEventRawKeyDown:
is_up = 0;
//printf("key down: %02x, %08x\n",
// (int)mac_keycode, (int)keycode);
break;
case kEventRawKeyUp:
is_up = 1;
//printf("key up: %02x, %08x\n",
// (int)mac_keycode, (int)keycode);
break;
case kEventRawKeyModifiersChanged:
is_up = -1;
//printf("key xxx: %08x\n", (int)modifiers);
break;
}
if(is_up >= 0) {
adb_physical_key_update((int)keycode, is_up);
}
break;
case kEventClassMouse:
handled = 2;
mouse_events++;
GetEventParameter(event, kEventParamMouseLocation,
typeQDPoint, NULL, sizeof(Point), NULL,
&mouse_point);
GetWindowRegion(g_main_window, kWindowContentRgn,
g_event_rgnhandle);
in_win = PtInRgn(mouse_point, g_event_rgnhandle);
// in_win = 1 if it was in the contect region of window
err = GetEventParameter(event, kEventParamMouseDelta,
typeQDPoint, NULL, sizeof(Point), NULL,
&mouse_delta_point);
button = 0;
button_state = -1;
switch(event_kind) {
case kEventMouseDown:
button_state = 7;
handled = 3;
break;
case kEventMouseUp:
button_state = 0;
handled = 3;
break;
}
if(button_state >= 0) {
GetEventParameter(event, kEventParamMouseButton,
typeMouseButton, NULL,
sizeof(EventMouseButton), NULL,
&mouse_button);
button = mouse_button;
if(button > 1) {
button = 4 - button;
button = 1 << button;
}
ignore = (button_state != 0) &&
(!in_win || g_ignore_next_click);
ignore = ignore || !g_mainwin_active;
if(ignore) {
// Outside of A2 window, ignore clicks
button = 0;
}
if(button_state == 0) {
g_ignore_next_click = 0;
}
}
GlobalToLocal(&mouse_point);
if(g_warp_pointer) {
if(err == 0) {
g_mac_mouse_x += mouse_delta_point.h;
g_mac_mouse_y += mouse_delta_point.v;
}
mac_warp_mouse();
} else {
g_mac_mouse_x = mouse_point.h -
g_video_act_margin_left;
g_mac_mouse_y = mouse_point.v -
g_video_act_margin_top;
}
#if 0
printf("Mouse %d at: %d,%d button:%d, button_st:%d\n",
mouse_events, g_mac_mouse_x, g_mac_mouse_y,
button, button_state);
printf("Mouse deltas: err:%d, %d,%d\n", (int)err,
mouse_delta_point.h, mouse_delta_point.v);
#endif
update_mouse(g_mac_mouse_x, g_mac_mouse_y,
button_state, button & 7);
if(g_warp_pointer) {
g_mac_mouse_x = A2_WINDOW_WIDTH/2;
g_mac_mouse_y = A2_WINDOW_HEIGHT/2;
update_mouse(g_mac_mouse_x, g_mac_mouse_y,0,-1);
}
break;
case kEventClassApplication:
switch(event_kind) {
case kEventAppActivated:
handled = 1;
g_mainwin_active = 1;
window_ref = 0;
GetEventParameter(event, kEventParamWindowRef,
typeWindowRef, NULL, sizeof(WindowRef),
NULL, &window_ref);
if(window_ref == g_main_window) {
g_ignore_next_click = 1;
}
break;
case kEventAppDeactivated:
handled = 1;
g_mainwin_active = 0;
g_ignore_next_click = 1;
break;
}
break;
}
// show_event(event_class, event_kind, handled);
if(handled != 1) {
(void)SendEventToEventTarget(event, target);
}
ReleaseEvent(event);
}
return;
}
void
temp_run_application_event_loop(void)
{
OSStatus err;
EventRef dummy_event;
EventHandlerRef install_handler;
EventTypeSpec event_spec = { 'KWIN', 'KWIN' };
// Create UPP for dummy_event_handler and for quit_event_handler
err = noErr;
dummy_event = 0;
g_dummy_event_handler_UPP = NewEventHandlerUPP(dummy_event_handler);
g_quit_handler_UPP = NewEventHandlerUPP(quit_event_handler);
if((g_dummy_event_handler_UPP == 0) || (g_quit_handler_UPP == 0)) {
err = memFullErr;
}
if(err == noErr) {
err = InstallApplicationEventHandler(g_dummy_event_handler_UPP,
1, &event_spec, 0, &install_handler);
if(err == noErr) {
err = MacCreateEvent(NULL, 'KWIN', 'KWIN',
GetCurrentEventTime(), kEventAttributeNone,
&dummy_event);
if(err == noErr) {
err = PostEventToQueue(GetMainEventQueue(),
dummy_event, kEventPriorityHigh);
}
if(err == noErr) {
RunApplicationEventLoop();
}
(void)RemoveEventHandler(install_handler);
}
}
if(dummy_event != NULL) {
ReleaseEvent(dummy_event);
}
}
int
#ifdef ACTIVEGS
macmain
#else
main
#endif
(int argc, char* argv[])
{
ProcessSerialNumber my_psn;
IBNibRef nibRef;
EventHandlerUPP handlerUPP;
EventTypeSpec cmd_event[3];
GDHandle g_gdhandle ;
Rect win_rect;
OSStatus err;
char *argptr;
int slash_cnt;
int i;
#ifndef ACTIVEGS
/* Prepare argv0 */
slash_cnt = 0;
argptr = argv[0];
for(i = strlen(argptr); i >= 0; i--) {
if(argptr[i] == '/') {
slash_cnt++;
if(slash_cnt == 3) {
strncpy(&(g_argv0_path[0]), argptr, i);
g_argv0_path[i] = 0;
}
}
}
printf("g_argv0_path is %s\n", g_argv0_path);
g_mac_argv[0] = argv[0];
g_mac_argc = 1;
i = 1;
while((i < argc) && (g_mac_argc < MAX_MAC_ARGS)) {
if(!strncmp(argv[i], "-psn", 4)) {
/* skip this argument */
} else {
g_mac_argv[g_mac_argc++] = argv[i];
}
i++;
}
#endif
InitCursor();
g_event_rgnhandle = NewRgn();
g_status_font_family = FMGetFontFamilyFromName("\pCourier");
SetRect(&win_rect, 0, 0, X_A2_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT
// OG Remove status line from ActiveGS window
#ifndef ACTIVEGS
+ MAX_STATUS_LINES*16 + 8
#endif
);
OffsetRect(&win_rect, 64, 50);
// Create a Nib reference passing the name of the nib file
// CreateNibReference only searches into the application bundle.
err = CreateNibReference(CFSTR("main"), &nibRef);
require_noerr( err, CantGetNibRef );
// Once the nib reference is created, set the menu bar.
err = SetMenuBarFromNib(nibRef, CFSTR("MenuBar"));
require_noerr( err, CantSetMenuBar );
#ifndef ACTIVEGS
err = CreateNewWindow(kDocumentWindowClass,
kWindowStandardDocumentAttributes |
kWindowStandardHandlerAttribute,
&win_rect, &g_main_window);
err = SetWindowTitleWithCFString(g_main_window, CFSTR("GSport"));
#else
err = CreateNewWindow(kDocumentWindowClass,
(kWindowCloseBoxAttribute /*| kWindowFullZoomAttribute */| kWindowCollapseBoxAttribute /*| kWindowResizableAttribute*/) /*kWindowStandardDocumentAttributes*/ |
kWindowStandardHandlerAttribute,
&win_rect, &g_main_window);
extern CFStringRef activeGSversionSTR;
err = SetWindowTitleWithCFString(g_main_window, activeGSversionSTR);
#endif
//printf("CreateNewWindow ret: %d, g_main_window: %p\n", (int)err, g_main_window);
// We don't need the nib reference anymore.
DisposeNibReference(nibRef);
SysBeep(120);
handlerUPP = NewEventHandlerUPP( my_cmd_handler );
cmd_event[0].eventClass = kEventClassCommand;
cmd_event[0].eventKind = kEventProcessCommand;
InstallWindowEventHandler(g_main_window, handlerUPP, 1, &cmd_event[0],
(void *)g_main_window, NULL);
handlerUPP = NewEventHandlerUPP(my_win_handler);
cmd_event[0].eventClass = kEventClassWindow;
cmd_event[0].eventKind = kEventWindowDrawContent;
cmd_event[1].eventClass = kEventClassWindow;
cmd_event[1].eventKind = kEventWindowUpdate;
cmd_event[2].eventClass = kEventClassWindow;
cmd_event[2].eventKind = kEventWindowClose;
err = InstallWindowEventHandler(g_main_window, handlerUPP, 3,
&cmd_event[0], (void *)g_main_window, NULL);
require_noerr(err, CantCreateWindow);
// Get screen depth
g_gdhandle = GetGDevice();
g_screen_mdepth = (**((**g_gdhandle).gdPMap)).pixelSize;
g_screen_depth = g_screen_mdepth;
if(g_screen_depth > 16) {
/* 32-bit display */
g_red_mask = 0xff;
g_green_mask = 0xff;
g_blue_mask = 0xff;
/*
if (macUsingCoreGraphics)
{
g_red_left_shift = 0;
g_green_left_shift = 8;
g_blue_left_shift = 16;
}
else
*/
{
g_red_left_shift = 16;
g_green_left_shift = 8;
g_blue_left_shift = 0;
}
g_red_right_shift = 0;
g_green_right_shift = 0;
g_blue_right_shift = 0;
} else if(g_screen_depth > 8) {
/* 16-bit display */
g_red_mask = 0x1f;
g_green_mask = 0x1f;
g_blue_mask = 0x1f;
g_red_left_shift = 10;
g_green_left_shift = 5;
g_blue_left_shift = 0;
g_red_right_shift = 3;
g_green_right_shift = 3;
g_blue_right_shift = 3;
}
// show_alert("About to show window", (int)g_main_window);
update_main_window_size();
update_window();
// The window was created hidden so show it.
ShowWindow( g_main_window );
BringToFront( g_main_window );
update_window();
// Make us pop to the front a different way
err = GetCurrentProcess(&my_psn);
if(err == noErr) {
(void)SetFrontProcess(&my_psn);
}
// Call the event loop
temp_run_application_event_loop();
CantCreateWindow:
CantSetMenuBar:
CantGetNibRef:
show_simple_alert("ending", "", "error code", err);
return err;
}
void
xdriver_end()
{
printf("xdriver_end\n");
if(g_fatal_log >= 0) {
x_show_alert(1, 0);
}
}
void
x_redraw_status_lines()
{
// OG Disable status line
#ifndef ACTIVEGS
Rect rect;
Pattern white_pattern;
char tmp_buf[256];
char *buf;
int len;
int line;
int height;
int margin;
SetPortWindowPort(g_main_window);
PenNormal();
height = 16;
margin = 0;
TextFont(g_status_font_family);
TextFace(normal);
TextSize(12);
SetRect(&rect, 0, X_A2_WINDOW_HEIGHT + margin, X_A2_WINDOW_WIDTH,
X_A2_WINDOW_HEIGHT + margin + MAX_STATUS_LINES*height);
GetQDGlobalsWhite(&white_pattern);
FillRect(&rect, &white_pattern);
for(line = 0; line < MAX_STATUS_LINES; line++) {
buf = g_status_ptrs[line];
if(buf == 0) {
/* skip it */
continue;
}
MoveTo(10, X_A2_WINDOW_HEIGHT + height*line + margin + height);
len = MIN(250, strlen(buf));
strncpy(&tmp_buf[1], buf, len);
tmp_buf[0] = len;
DrawString((const unsigned char*)&tmp_buf[0]);
}
#endif
}
void
x_full_screen(int do_full)
{
#if 0
WindowRef new_window;
short width, height;
OSErr ret;
width = 640;
height = 480;
if(do_full && (g_mac_fullscreen_state == 0)) {
g_main_window_saved = g_main_window;
GetWindowBounds(g_main_window, kWindowContentRgn,
&g_main_window_saved_rect);
ret = BeginFullScreen(&g_mac_fullscreen_state, 0,
&width, &height, &new_window, 0, 0);
printf("Ret beginfullscreen: %d\n", (int)ret);
printf("New width: %d, new height: %d\n", width, height);
if(ret == noErr) {
g_main_window = new_window;
} else {
g_mac_fullscreen_state = 0;
}
} else if(!do_full && (g_mac_fullscreen_state != 0)) {
ret = EndFullScreen(g_mac_fullscreen_state, 0);
printf("ret endfullscreen: %d\n", (int)ret);
g_main_window = g_main_window_saved;
g_mac_fullscreen_state = 0;
//InitCursor();
SetWindowBounds(g_main_window, kWindowContentRgn,
&g_main_window_saved_rect);
}
update_main_window_size();
ShowWindow(g_main_window);
BringToFront(g_main_window);
update_window();
#endif
}
void
x_push_done()
{
CGrafPtr window_port;
SetPortWindowPort(g_main_window);
window_port = GetWindowPort(g_main_window);
QDFlushPortBuffer(window_port, 0);
}
void
mac_warp_mouse()
{
#ifndef ACTIVEGS
Rect port_rect;
Point win_origin_pt;
CGPoint cgpoint;
CGDisplayErr cg_err;
GetPortBounds(GetWindowPort(g_main_window), &port_rect);
SetPt(&win_origin_pt, port_rect.left, port_rect.top);
LocalToGlobal(&win_origin_pt);
cgpoint = CGPointMake( (float)(win_origin_pt.h + X_A2_WINDOW_WIDTH/2),
(float)(win_origin_pt.v + X_A2_WINDOW_HEIGHT/2));
cg_err = CGDisplayMoveCursorToPoint(kCGDirectMainDisplay, cgpoint);
#endif
}

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2014 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -155,7 +156,7 @@ int transwarp_low_val = 0;
__declspec(align(256))
#endif
unsigned char transwarpcode[][32]
#if !defined(_WIN32) && !defined(__OS2__)
#if !defined(_WIN32)
__attribute__ ((aligned(256)))
#endif
={
@ -221,9 +222,12 @@ __attribute__ ((aligned(256)))
;
/* SLOT 7 DEVSEL RAM (used by HOST.MLI) */
static byte slot7_devsel[15] = { 0 };
// OG Added moremem_init()
void moremem_init()
{
void moremem_init() {
g_em_emubyte_cnt = 0;
g_paddle_buttons = 0;
g_irq_pending = 0;
@ -249,9 +253,7 @@ void moremem_init()
g_zipgs_reg_c05c = 0x00;
}
void
fixup_brks()
{
void fixup_brks() {
word32 page;
word32 tmp, tmp2;
Pg_info val;
@ -275,9 +277,7 @@ fixup_brks()
}
}
void
fixup_hires_on()
{
void fixup_hires_on() {
if((g_cur_a2_stat & ALL_STAT_ST80) == 0) {
return;
}
@ -286,9 +286,7 @@ fixup_hires_on()
fixup_brks();
}
void
fixup_bank0_2000_4000()
{
void fixup_bank0_2000_4000() {
byte *mem0rd;
byte *mem0wr;
@ -324,9 +322,7 @@ fixup_bank0_2000_4000()
fixup_any_bank_any_page(0x20, 0x20, mem0rd, mem0wr);
}
void
fixup_bank0_0400_0800()
{
void fixup_bank0_0400_0800() {
byte *mem0rd;
byte *mem0wr;
int shadow;
@ -356,10 +352,8 @@ fixup_bank0_0400_0800()
fixup_any_bank_any_page(0x4, 4, mem0rd, mem0wr);
}
void
fixup_any_bank_any_page(int start_page, int num_pages, byte *mem0rd,
byte *mem0wr)
{
void fixup_any_bank_any_page(int start_page, int num_pages, byte *mem0rd,
byte *mem0wr) {
int i;
for(i = 0; i < num_pages; i++) {
@ -374,9 +368,7 @@ fixup_any_bank_any_page(int start_page, int num_pages, byte *mem0rd,
}
void
fixup_intcx()
{
void fixup_intcx() {
byte *rom10000;
byte *rom_inc;
int no_io_shadow;
@ -444,9 +436,7 @@ fixup_intcx()
fixup_brks();
}
void
fixup_wrdefram(int new_wrdefram)
{
void fixup_wrdefram(int new_wrdefram) {
byte *mem0wr;
byte *wrptr;
int j;
@ -503,9 +493,7 @@ fixup_wrdefram(int new_wrdefram)
fixup_brks();
}
void
fixup_st80col(double dcycs)
{
void fixup_st80col(double dcycs) {
int cur_a2_stat;
cur_a2_stat = g_cur_a2_stat;
@ -525,9 +513,7 @@ fixup_st80col(double dcycs)
fixup_brks();
}
void
fixup_altzp()
{
void fixup_altzp() {
byte *mem0rd, *mem0wr;
int rdrom, c08x_wrdefram;
int altzp;
@ -590,9 +576,7 @@ fixup_altzp()
/* No need for fixup_brks since called from set_statereg() */
}
void
fixup_page2(double dcycs)
{
void fixup_page2(double dcycs) {
if((g_cur_a2_stat & ALL_STAT_ST80)) {
fixup_bank0_0400_0800();
if((g_cur_a2_stat & ALL_STAT_HIRES)) {
@ -603,9 +587,7 @@ fixup_page2(double dcycs)
}
}
void
fixup_ramrd()
{
void fixup_ramrd() {
byte *mem0rd;
int cur_a2_stat;
int j;
@ -639,9 +621,7 @@ fixup_ramrd()
/* No need for fixup_brks since only called from set_statereg() */
}
void
fixup_ramwrt()
{
void fixup_ramwrt() {
byte *mem0wr;
int cur_a2_stat;
int shadow;
@ -712,9 +692,7 @@ fixup_ramwrt()
/* No need for fixup_brks() since only called from set_statereg() */
}
void
fixup_lcbank2()
{
void fixup_lcbank2() {
byte *mem0rd, *mem0wr;
int lcbank2, c08x_wrdefram, rdrom;
int off;
@ -761,9 +739,7 @@ fixup_lcbank2()
/* or from other routines which will handle it */
}
void
fixup_rdrom()
{
void fixup_rdrom() {
byte *mem0rd;
int j, k;
@ -789,9 +765,7 @@ fixup_rdrom()
/* No need for fixup_brks() since only called from set_statereg() */
}
void
set_statereg(double dcycs, int val)
{
void set_statereg(double dcycs, int val) {
int _xor; // OG renamed xor to _xor
_xor = val ^ g_c068_statereg;
@ -845,9 +819,7 @@ set_statereg(double dcycs, int val)
}
}
void
fixup_shadow_txt1()
{
void fixup_shadow_txt1() {
byte *mem0wr;
int j;
@ -862,9 +834,7 @@ fixup_shadow_txt1()
}
}
void
fixup_shadow_txt2()
{
void fixup_shadow_txt2() {
byte *mem0wr;
int shadow;
int j;
@ -895,9 +865,7 @@ fixup_shadow_txt2()
}
}
void
fixup_shadow_hires1()
{
void fixup_shadow_hires1() {
byte *mem0wr;
int j;
@ -913,9 +881,7 @@ fixup_shadow_hires1()
}
}
void
fixup_shadow_hires2()
{
void fixup_shadow_hires2() {
byte *mem0wr;
int j;
@ -944,9 +910,7 @@ fixup_shadow_hires2()
}
}
void
fixup_shadow_shr()
{
void fixup_shadow_shr() {
byte *mem0wr;
int j;
@ -972,9 +936,7 @@ fixup_shadow_shr()
}
}
void
fixup_shadow_iolc()
{
void fixup_shadow_iolc() {
byte *mem0rd;
int k;
@ -1007,9 +969,7 @@ fixup_shadow_iolc()
}
}
void
update_shadow_reg(int val)
{
void update_shadow_reg(int val) {
int _xor;
if(g_c035_shadow_reg == val) {
@ -1050,9 +1010,7 @@ update_shadow_reg(int val)
}
}
void
fixup_shadow_all_banks()
{
void fixup_shadow_all_banks() {
byte *mem0rd;
int shadow;
int num_banks;
@ -1077,9 +1035,7 @@ fixup_shadow_all_banks()
fixup_brks();
}
void
setup_pageinfo()
{
void setup_pageinfo() {
byte *mem0rd;
word32 mem_size_pages;
@ -1142,9 +1098,7 @@ setup_pageinfo()
#endif
}
void
show_bankptrs_bank0rdwr()
{
void show_bankptrs_bank0rdwr() {
show_bankptrs(0);
show_bankptrs(1);
show_bankptrs(0xe0);
@ -1152,9 +1106,7 @@ show_bankptrs_bank0rdwr()
printf("statereg: %02x\n", g_c068_statereg);
}
void
show_bankptrs(int bnk)
{
void show_bankptrs(int bnk) {
int i;
Pg_info rd, wr;
byte *ptr_rd, *ptr_wr;
@ -1177,9 +1129,40 @@ show_bankptrs(int bnk)
}
}
void
show_addr(byte *ptr)
{
// function to get the pointer to memory where a gs page is located - db
unsigned char * get_page_ptr_rd(int addr) {
Pg_info rd;
byte *ptr_rd;
int bank = ( addr & 0xFF0000 ) >> 16; // unnecessary conversion that we throw away below w/ "*0x100"
int page = ( addr & 0x00FF00 ) >> 8;
rd = GET_PAGE_INFO_RD(bank*0x100 + page);
ptr_rd = (byte *)rd;
//printf("ADDR %06x at pageptr %p\n",addr, ptr_rd); // seems to be correct.
/* code */
return rd;
}
// function to get a byte from a 24bit address - db
int get_byte_at_address(int addr) {
unsigned char *page_ptr_rd = get_page_ptr_rd(addr);
int offset = addr & 0xff;
int mem_byte = page_ptr_rd[offset] & 0xff;
//printf("0x%06X = $%02X \t(dec) %d\n", addr, (int) mem_byte, (int) mem_byte);
return (int) mem_byte;
}
// function to set a byte from a 24bit address - db
void set_byte_at_address(int addr, int value) {
unsigned char *page_ptr_rd = get_page_ptr_rd(addr);
int offset = addr & 0xff;
page_ptr_rd[offset] = value;
}
void show_addr(byte *ptr) {
word32 mem_size;
mem_size = g_mem_size_total;
@ -1205,14 +1188,9 @@ show_addr(byte *ptr)
dcycs = g_last_vbl_dcycs + *cyc_ptr;
int
io_read(word32 loc, double *cyc_ptr)
{
int io_read(word32 loc, double *cyc_ptr) {
double dcycs;
word64 word64_tmp;
#if 0
double fcyc, new_fcyc;
#endif
word32 mask;
int new_lcbank2;
int new_wrdefram;
@ -1678,7 +1656,7 @@ io_read(word32 loc, double *cyc_ptr)
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
case 0xfc: case 0xfd: case 0xfe: case 0xff:
return 0;
return slot7_devsel[loc & 0x0f] /* 0 */;
default:
printf("loc: %04x bad\n", loc);
@ -1721,13 +1699,8 @@ io_read(word32 loc, double *cyc_ptr)
return 0xff;
}
void
io_write(word32 loc, int val, double *cyc_ptr)
{
void io_write(word32 loc, int val, double *cyc_ptr) {
double dcycs;
#if 0
double fcyc, new_fcyc;
#endif
int new_tmp;
int new_lcbank2;
int new_wrdefram;
@ -2424,7 +2397,9 @@ io_write(word32 loc, int val, double *cyc_ptr)
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
case 0xfc: case 0xfd: case 0xfe: case 0xff:
UNIMPL_WRITE;
slot7_devsel[loc & 0x0f] = val; /* UNIMPL_WRITE; */
return;
default:
printf("WRite loc: %x\n",loc);
exit(-300);
@ -2449,9 +2424,7 @@ io_write(word32 loc, int val, double *cyc_ptr)
#if 0
int
get_slow_mem(word32 loc, int duff_cycles)
{
int get_slow_mem(word32 loc, int duff_cycles) {
int val;
loc = loc & 0x1ffff;
@ -2475,9 +2448,7 @@ get_slow_mem(word32 loc, int duff_cycles)
return val;
}
int
set_slow_mem(word32 loc, int val, int duff_cycles)
{
int set_slow_mem(word32 loc, int val, int duff_cycles) {
int or_pos;
word32 or_val;
@ -2519,9 +2490,7 @@ set_slow_mem(word32 loc, int val, int duff_cycles)
/* vertical blanking engages on line 192, even if in super hires mode */
/* (Last 8 lines in SHR are drawn with vbl_active set */
word32
get_lines_since_vbl(double dcycs)
{
word32 get_lines_since_vbl(double dcycs) {
double dcycs_since_last_vbl;
double dlines_since_vbl;
double dcyc_line_start;
@ -2553,9 +2522,7 @@ get_lines_since_vbl(double dcycs)
}
int
in_vblank(double dcycs)
{
int in_vblank(double dcycs) {
int lines_since_vbl;
lines_since_vbl = get_lines_since_vbl(dcycs);
@ -2570,9 +2537,7 @@ in_vblank(double dcycs)
/* horizontal video counter goes from 0x00,0x40 - 0x7f, then 0x80,0xc0-0xff */
/* over 2*65 cycles. The last visible screen pos is 0x7f and 0xff */
/* This matches GSport starting line 0 at the border for line -1 */
int
read_vid_counters(int loc, double dcycs)
{
int read_vid_counters(int loc, double dcycs) {
word32 mask;
int lines_since_vbl;

453
src/options.c Normal file
View File

@ -0,0 +1,453 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "options.h"
#include "glog.h"
#include "defc.h"
// config is parsed in config.c :: config_parse_config_gsport_file()
// cli is parsed here. would be nice to reuse some code
// Halts on bad reads. Sets flags via engine_s.s:set_halt_act() function
extern int g_halt_on_bad_read; // defined in sim65816.c
// Ignore bad memory accesses.
extern int g_ignore_bad_acc; // defined in sim65816.c
// Ignore red alert halts.
extern int g_ignore_halts; // defined in sim65816.c
// Size of RAM memory expansion card in bytes (default = 8*1024*1024 = 8MB)
extern int g_mem_size_exp; // defined in sim65816.c
// Implemented in display drivers (not SDL2 though) ?
extern int g_screen_redraw_skip_amt; // defined in video.c, implemented in various driver files
// Using simple dhires color map
extern int g_use_dhr140; // defined in video.c
// Force B/W hires modes
extern int g_use_bw_hires; // defined in video.c
// Set starting X/Y positions
extern int g_startx; // defined in video.c
extern int g_starty; // defined in video.c
extern int g_startw; // defined in video.c
extern int g_starth; // defined in video.c
// Use High DPI (Retina) display - SDL2
extern int g_highdpi; // defined in video.c
// Create borderless window - SDL2
extern int g_borderless; // defined in video.c
// Allow window resizing, dragging to scale - SDL2
extern int g_resizeable; // defined in video.c
// Allow the window scaling to be free from aspect contraints - SDL2
extern int g_noaspect;
// Don't explicitly set vsync present flag on renderer - SDL2
extern int g_novsync; // defined in video.c
// Don't explicitly set HW accelerator flag on renderer - SDL2
extern int g_nohwaccel; // defined in video.c
// Use SDL_WINDOW_FULLSCREEN_DESKTOP for fullscreen instead of switching modes
extern int g_fullscreen_desktop;
// Enable Dagen's scanline simulator (SDL2)
extern int g_scanline_simulator; // defined in sim65816.c
// Ethernet (interface?)
extern int g_ethernet; // defined in sim65816.c
// Enable and set port for Dagen's debugger
extern int g_dbg_enable_port; // defined in debug.c
// Set preferred audio frequency
extern int g_preferred_rate; // defined in sound_driver.c, implemented in various driver files
// Enable/disable audio
extern int g_audio_enable; // defined in sound.c
// Start in fullscreen mode
extern int g_fullscreen; // defined in adb.c, because weird driver writing for x
// Specify the joystick - SDL2
extern int g_joystick_number; // defined in joystick_driver.c
extern int g_joystick_x_axis; // defined in joystick_driver.c
extern int g_joystick_y_axis; // defined in joystick_driver.c
extern int g_joystick_x2_axis; // defined in joystick_driver.c
extern int g_joystick_y2_axis; // defined in joystick_driver.c
extern int g_joystick_button_0; // defined in joystick_driver.c
extern int g_joystick_button_1; // defined in joystick_driver.c
extern int g_joystick_button_2; // defined in joystick_driver.c
extern int g_joystick_button_3; // defined in joystick_driver.c
// DEPRECATED: force bit depth (15/16/24) for X-Windows, might still work.
extern int g_force_depth; // defined in sim65816.c
// DEPRECATED: Use X shared memory (MIT-SHM)
extern int g_use_shmem; // defined in all the various drivers
// DEPRECATED: Set DISPLAY environment variable for X-Windows
extern char g_display_env[512]; // defined in sim65816.c
// DEPRECATED: Set VERBOSE flags for one or more subsystems as defined below
extern int Verbose; // defined in sim65816.c
// #define VERBOSE_DISK 0x001
// #define VERBOSE_IRQ 0x002
// #define VERBOSE_CLK 0x004
// #define VERBOSE_SHADOW 0x008
// #define VERBOSE_IWM 0x010
// #define VERBOSE_DOC 0x020
// #define VERBOSE_ADB 0x040
// #define VERBOSE_SCC 0x080
// #define VERBOSE_TEST 0x100
// #define VERBOSE_VIDEO 0x200
// #define VERBOSE_MAC
// This is deprecated because it is not well-defined or supported
// It should still work and some sort of system should be put in place
// to extend and fix this, or take it out.
extern const char *g_config_gsport_name_list[];
extern char g_config_gsport_screenshot_dir[];
extern char *final_arg;
static const char parse_log_prefix[] = "Option set [CLI]:";
// this is here because we need to flip a bit to force B/W modes
extern int g_cur_a2_stat;
void help_exit(); // displays the cli help text and exits with 1
int parse_int(const char *str1, int min, int max)
{
int tmp;
tmp = strtol(str1, 0, 0);
if (tmp > max) { tmp = max; }
if (tmp < min) { tmp = min; }
return tmp;
}
void parse_cli_options(int argc, char **argv) {
int i;
int tmp1;
int skip_amt;
char *final_arg = 0;
for(i = 1; i < argc; i++) {
if( (!strcmp("-?", argv[i])) || (!strcmp("-h", argv[i])) || (!strcmp("-help", argv[i]))) {
help_exit();
} else if(!strcmp("-badrd", argv[i])) {
glogf("%s Halting on bad reads", parse_log_prefix);
g_halt_on_bad_read = 2;
} else if(!strcmp("-fullscreen", argv[i])) {
glogf("%s Starting emulator in fullscreen", parse_log_prefix);
g_fullscreen = 1;
} else if(!strcmp("-highdpi", argv[i])) {
glogf("%s Creating window in High DPI mode", parse_log_prefix);
g_highdpi = 1;
} else if(!strcmp("-borderless", argv[i])) {
glogf("%s Creating borderless window", parse_log_prefix);
g_borderless = 1;
} else if(!strcmp("-resizeable", argv[i])) {
glogf("%s Window will be resizeable", parse_log_prefix);
g_resizeable = 1;
} else if(!strcmp("-noaspect", argv[i])) {
glogf("%s Window will scale freely, without locking the aspect ratio", parse_log_prefix);
g_noaspect = 1;
} else if(!strcmp("-novsync", argv[i])) {
glogf("%s Renderer skipping vsync flag", parse_log_prefix);
g_novsync = 1;
} else if(!strcmp("-nohwaccel", argv[i])) {
glogf("%s Renderer skipping HW accel flag", parse_log_prefix);
g_nohwaccel = 1;
} else if(!strcmp("-fulldesk", argv[i])) {
glogf("%s Using desktop fullscreen mode", parse_log_prefix);
g_fullscreen_desktop = 1;
} else if(!strcmp("-noignbadacc", argv[i])) {
glogf("%s Not ignoring bad memory accesses", parse_log_prefix);
g_ignore_bad_acc = 0;
} else if(!strcmp("-noignhalt", argv[i])) {
glogf("%s Not ignoring code red halts", parse_log_prefix);
g_ignore_halts = 0;
} else if(!strcmp("-mem", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-mem' missing argument", parse_log_prefix);
exit(1);
}
g_mem_size_exp = strtol(argv[i+1], 0, 0) & 0x00ff0000;
glogf("%s Using %d as memory size", parse_log_prefix, g_mem_size_exp);
i++;
} else if(!strcmp("-skip", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-skip' missing argument", parse_log_prefix);
exit(1);
}
skip_amt = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as skip_amt", parse_log_prefix, skip_amt);
g_screen_redraw_skip_amt = skip_amt;
i++;
} else if(!strcmp("-audio", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-audio' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as audio enable val", parse_log_prefix, tmp1);
g_audio_enable = tmp1;
i++;
} else if(!strcmp("-arate", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-arate' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as preferred audio rate", parse_log_prefix, tmp1);
g_preferred_rate = tmp1;
i++;
} else if(!strcmp("-v", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-v' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Setting Verbose = 0x%03x", parse_log_prefix, tmp1);
Verbose = tmp1;
i++;
} else if(!strcmp("-display", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-display' missing argument", parse_log_prefix);
exit(1);
}
glogf("%s Using %s as display", parse_log_prefix, argv[i+1]);
sprintf(g_display_env, "DISPLAY=%s", argv[i+1]);
putenv(&g_display_env[0]);
i++;
} else if(!strcmp("-noshm", argv[i])) {
glogf("%s Not using X shared memory", parse_log_prefix);
g_use_shmem = 0;
} else if(!strcmp("-joy", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick number %d", parse_log_prefix, tmp1);
g_joystick_number = tmp1;
i++;
} else if(!strcmp("-joy-x", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-x' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick X axis %d", parse_log_prefix, tmp1);
g_joystick_x_axis = tmp1;
i++;
} else if(!strcmp("-joy-y", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-y' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Y axis %d", parse_log_prefix, tmp1);
g_joystick_y_axis = tmp1;
i++;
} else if(!strcmp("-joy-x2", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-x2' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick X2 axis %d", parse_log_prefix, tmp1);
g_joystick_x2_axis = tmp1;
i++;
} else if(!strcmp("-joy-y2", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-y2' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Y2 axis %d", parse_log_prefix, tmp1);
g_joystick_y2_axis = tmp1;
i++;
} else if(!strcmp("-joy-b0", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-b0' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 0 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_0 = tmp1;
i++;
} else if(!strcmp("-joy-b1", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-b1' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 1 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_1 = tmp1;
i++;
} else if(!strcmp("-joy-b2", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-b2' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 2 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_2 = tmp1;
i++;
} else if(!strcmp("-joy-b3", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-joy-b3' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0); // no bounds check, not sure what ids we get
glogf("%s Setting joystick Button 3 to Gamepad %d", parse_log_prefix, tmp1);
g_joystick_button_3 = tmp1;
i++;
} else if(!strcmp("-dhr140", argv[i])) {
glogf("%s Using simple dhires color map", parse_log_prefix);
g_use_dhr140 = 1;
} else if(!strcmp("-bw", argv[i])) {
glogf("%s Forcing black-and-white hires modes", parse_log_prefix);
g_cur_a2_stat |= ALL_STAT_COLOR_C021;
g_use_bw_hires = 1;
} else if(!strcmp("-scanline", argv[i])) {
glogf("%s Enable scanline simulation", parse_log_prefix);
if((i+1) >= argc) {
glogf("%s Error, option '-scanline' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = parse_int(argv[i+1], 0, 100);
glogf("%s Setting scanline simulator darkness to %d%%", parse_log_prefix, tmp1);
g_scanline_simulator = tmp1;
i++;
} else if(!strcmp("-enet", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-enet' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as ethernet enable val", parse_log_prefix, tmp1);
g_ethernet = tmp1;
i++;
} else if(!strcmp("-x", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-x' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as x val", parse_log_prefix, tmp1);
g_startx = tmp1;
i++;
} else if(!strcmp("-y", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-y' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as y val", parse_log_prefix, tmp1);
g_starty = tmp1;
i++;
} else if(!strcmp("-sw", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-sw' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as width val", parse_log_prefix, tmp1);
g_startw = tmp1;
i++;
} else if(!strcmp("-sh", argv[i])) {
if((i+1) >= argc) {
glogf("%s Error, option '-sh' missing argument", parse_log_prefix);
exit(1);
}
tmp1 = strtol(argv[i+1], 0, 0);
glogf("%s Using %d as height val", parse_log_prefix, tmp1);
g_starth = tmp1;
i++;
} else if(!strcmp("-config", argv[i])) { // Config file passed
if((i+1) >= argc) {
glogf("%s Error, option '-config' missing argument", parse_log_prefix);
exit(1);
}
glogf("%s Using %s as configuration file", parse_log_prefix, argv[i+1]);
g_config_gsport_name_list[0] = argv[i+1]; // overwrite default list with passed item as sole option
g_config_gsport_name_list[1] = 0; // terminate string array
i++;
} else if (!strcmp("-ssdir", argv[i])) { // screenshot directory passed
strcpy(g_config_gsport_screenshot_dir, argv[i+1]);
struct stat path_stat;
stat(g_config_gsport_screenshot_dir, &path_stat); // (weakly) validate path
if (!S_ISDIR(path_stat.st_mode)) {
strcpy(g_config_gsport_screenshot_dir, "./");
}
glogf("%s Using %s for screenshot path", parse_log_prefix, g_config_gsport_screenshot_dir);
i++;
} else if(!strcmp("-debugport", argv[i])) { // Debug port passed
if((i+1) >= argc) {
glogf("%s Error, option '-debugport' missing argument", parse_log_prefix);
exit(1);
}
g_dbg_enable_port = strtol(argv[i+1], 0, 0);
glogf("%s Using %d for debug port", parse_log_prefix, g_dbg_enable_port);
i++;
} else {
if ((i == (argc - 1)) && (strncmp("-", argv[i], 1) != 0)) {
final_arg = argv[i];
} else {
glogf("%s Error, bad option: %s for debug port", parse_log_prefix, argv[i]);
exit(3);
}
}
}
}
void help_exit() {
printf(" USAGE: \n\n");
printf(" ./gsport # simple - uses default config.txt\n");
printf(" ./gsport -config games_hds.gsp # set custom config file\n\n");
printf(" You need to supply your own Apple IIgs Firmware ROM image.\n");
printf(" Press F4 when running gsport to enter config menu and select ROM image location.\n");
printf(" Or copy the ROM image to the gsport directory.\n");
printf(" It will search for: \"ROM\", \"ROM.01\", \"ROM.03\" \n\n\n");
printf(" Other command line options: \n\n");
printf(" -badrd Halt on bad reads\n");
printf(" -noignbadacc Dont ignore bad memory accesses\n");
printf(" -noignhalt Dont ignore code red halts\n");
printf(" -test Allow testing\n");
printf(" -joy Set joystick number\n");
printf(" -bw Force B/W modes\n");
printf(" -dhr140 Use simple double-hires color map\n");
printf(" -fullscreen Attempt to start emulator in fullscreen\n");
printf(" -highdpi Attempt to open window in high DPI\n");
printf(" -borderless Attempt to create borderless window\n");
printf(" -resizeable Allow you to resize window (non-integral scaling to pixel)\n");
printf(" -mem value Set memory size to value\n");
printf(" -skip value Set skip_amt to value\n");
printf(" -audio value Set audio enable to value\n");
printf(" -arate value Set preferred audio rate to value\n");
printf(" -enet value Set ethernet to value\n");
printf(" -config value Set config file to value\n");
printf(" -debugport value Set debugport to value\n");
printf(" -ssdir value Set screenshot save directory to value\n");
printf(" -scanline value Enable scanline simulator at value %%\n");
printf(" -x value Open emulator window at x value\n");
printf(" -y value Open emulator window at y value\n");
printf(" -sw value Scale window to sw pixels wide\n");
printf(" -sh value Scale window to sh pixels high\n");
printf(" -novsync Don't force emulator to sync each frame\n");
printf(" -fulldesk Use desktop 'fake' fullscreen mode\n");
//printf(" -v value Set verbose flags to value\n\n");
printf(" Note: The final argument, if not a flag, will be tried as a mountable device.\n\n");
exit(1);
}

29
src/options.h Normal file
View File

@ -0,0 +1,29 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#ifdef __cplusplus
extern "C" {
#endif
void parse_cli_options(int argc, char **argv);
#ifdef __cplusplus
}
#endif

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2012 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -45,9 +46,6 @@ void x_full_screen(int do_full);
void clipboard_paste(void);
int clipboard_get_char(void);
/* test65.c */
void do_gen_test(int got_num, int base_seed);
/* engine.s and engine_c.c */
void fixed_memory_ptrs_init();
@ -57,6 +55,7 @@ word32 get_itimer(void);
word32 get_memory_c(word32 addr, int cycs);
word32 get_memory16_c(word32 addr, int cycs);
word32 get_memory24_c(word32 addr, int cycs);
word32 get_memory32_c(word32 addr, int cycs);
int get_memory_asm(word32 addr, int cycs);
int get_memory16_asm(word32 addr, int cycs);
@ -67,6 +66,7 @@ int get_memory16_act_stub_asm(word32 addr, int cycs);
void set_memory_c(word32 addr, word32 val, int cycs);
void set_memory16_c(word32 addr, word32 val, int cycs);
void set_memory24_c(word32 addr, word32 val, int cycs);
void set_memory32_c(word32 addr, word32 val, int cycs);
int enter_engine(Engine_reg *ptr);
void clr_halt_act(void);
@ -121,6 +121,7 @@ int read_adb_ram(word32 addr);
void write_adb_ram(word32 addr, int val);
int adb_get_keypad_xy(int get_y);
int update_mouse(int x, int y, int button_states, int buttons_valid);
int update_mouse_w_delta(int x, int y, int button_states, int buttons_valid, int delta_x, int delta_y);
int mouse_read_c024(double dcycs);
void mouse_compress_fifo(double dcycs);
void adb_key_event(int a2code, int is_up);
@ -176,34 +177,6 @@ void insert_disk(int slot, int drive, const char *name, int ejected, int force_s
void eject_named_disk(Disk *dsk, const char *name, const char *partition_name);
void eject_disk_by_num(int slot, int drive);
void eject_disk(Disk *dsk);
int cfg_get_fd_size(char *filename);
int cfg_partition_read_block(FILE *file, void *buf, int blk, int blk_size);
int cfg_partition_find_by_name_or_num(FILE *file, const char *partnamestr, int part_num, Disk *dsk);
int cfg_maybe_insert_disk(int slot, int drive, const char *namestr);
int cfg_stat(char *path, struct stat *sb);
int cfg_partition_make_list(char *filename, FILE *file);
void cfg_htab_vtab(int x, int y);
void cfg_home(void);
void cfg_cleol(void);
void cfg_putchar(int c);
void cfg_printf(const char *fmt, ...);
void cfg_print_num(int num, int max_len);
void cfg_get_disk_name(char *outstr, int maxlen, int type_ext, int with_extras);
void cfg_parse_menu(Cfg_menu *menuptr, int menu_pos, int highlight_pos, int change);
void cfg_get_base_path(char *pathptr, const char *inptr, int go_up);
void cfg_file_init(void);
void cfg_free_alldirents(Cfg_listhdr *listhdrptr);
void cfg_file_add_dirent(Cfg_listhdr *listhdrptr, const char *nameptr, int is_dir, int size, int image_start, int part_num);
int cfg_dirent_sortfn(const void *obj1, const void *obj2);
int cfg_str_match(const char *str1, const char *str2, int len);
void cfg_file_readdir(const char *pathptr);
char *cfg_shorten_filename(const char *in_ptr, int maxlen);
void cfg_fix_topent(Cfg_listhdr *listhdrptr);
void cfg_file_draw(void);
void cfg_partition_selected(void);
void cfg_file_update_ptr(char *str);
void cfg_file_selected(void);
void cfg_file_handle_key(int key);
void config_control_panel(void);
@ -219,6 +192,7 @@ void show_bp(void);
void delete_bp(word32 addr);
void do_blank(void);
void do_go(void);
void do_go_debug(void); // socket debug ver
void do_step(void);
void xam_mem(int count);
void show_hex_mem(int startbank, word32 start, int endbank, word32 end, int count);

887
src/sdl2_driver.c Normal file
View File

@ -0,0 +1,887 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
// fps shiz
unsigned int lastTime = 0, currentTime, frames;
// @todo: mouse clip bugs.. great western shootout. Paint 8/16. still in win32
#include "SDL.h"
#include "SDL_image.h"
#include "glog.h"
#include <stdbool.h>
#include <time.h>
#include <stdlib.h>
#include <signal.h>
#include <libgen.h> // just for basename :P
#include <string.h>
#include "defc.h"
#ifdef HAVE_ICON // Currently a flag because not supported outside of SDL builds. Looking at full solution.
#include "icongs.h"
#endif
#ifdef _WIN32
#include <unistd.h>
#endif
// BITMASKS
#define ShiftMask 1
#define ControlMask 4
#define LockMask 2
int g_use_shmem = 0;
int g_num_check_input_calls = 0;
int g_check_input_flush_rate = 2;
int g_win_status_debug = 0; // Current visibility of status lines.
int g_win_status_debug_request = 0; // Desired visibility of status lines.
int g_screen_mdepth = 0;
int kb_shift_control_state = 0;
void debuginfo_renderer(SDL_Renderer *r);
void x_take_screenshot(); // screenshot stuff
void x_grabmouse();
int g_screenshot_requested = 0; // DB to know if we want to save a screenshot
extern char g_config_gsport_name[];
extern char g_config_gsport_screenshot_dir[];
int screenshot_index = 0; // allows us to save time by not scanning from 0 each time
char screenshot_filename[256];
extern int g_fullscreen; // only checked at start if set via CLI, otherwise it's set via function call x_full_screen()
extern int g_grabmouse;
extern int g_highdpi;
extern int g_borderless;
extern int g_resizeable;
extern int g_noaspect;
extern int g_novsync;
extern int g_nohwaccel;
extern int g_fullscreen_desktop;
extern int g_scanline_simulator;
extern int g_startx;
extern int g_starty;
extern int g_startw;
extern int g_starth;
extern int g_screen_depth;
extern int g_quit_sim_now;
extern int g_border_sides_refresh_needed;
extern int g_border_special_refresh_needed;
extern int g_status_refresh_needed;
extern int g_lores_colors[];
extern int g_a2vid_palette;
extern int g_installed_full_superhires_colormap;
extern char *g_status_ptrs[MAX_STATUS_LINES];
extern word32 g_a2_screen_buffer_changed;
extern word32 g_full_refresh_needed;
extern word32 g_palette_8to1624[256];
extern word32 g_a2palette_8to1624[256];
extern Kimage g_mainwin_kimage;
extern const char g_gsport_version_str[]; // version string for title bar
SDL_Window *window; // Declare a pointer
SDL_Renderer *renderer;
SDL_Texture *texture;
SDL_Texture *overlay_texture; // This is used for scanline simulation. Could be more in future (HUD).
Uint32 *overlay_pixels;
static char *g_clipboard = NULL; // clipboard variables
static size_t g_clipboard_pos = 0;
void dev_video_init_sdl();
void handle_sdl_key_event(SDL_Event event);
void check_input_events_sdl();
void handle_sdl_mouse_event(SDL_Event event);
int g_num_a2_keycodes = 0;
int a2_key_to_sdlkeycode[][3] = {
{ 0x35, SDLK_ESCAPE, 0 },
{ 0x7a, SDLK_F1, 0 },
{ 0x78, SDLK_F2, 0 },
{ 0x63, SDLK_F3, 0 },
{ 0x76, SDLK_F4, 0 },
{ 0x60, SDLK_F5, 0 },
{ 0x61, SDLK_F6, 0 },
{ 0x62, SDLK_F7, 0 },
{ 0x64, SDLK_F8, 0 },
{ 0x65, SDLK_F9, 0 },
{ 0x6d, SDLK_F10, 0 },
{ 0x67, SDLK_F11, 0 },
{ 0x6f, SDLK_F12, 0 },
{ 0x69, SDLK_F13, 0 },
{ 0x6b, SDLK_F14, 0 },
{ 0x71, SDLK_F15, 0 },
{ 0x7f, SDLK_PAUSE, 0 },
{ 0x32, SDLK_BACKQUOTE, '~' }, /* Key number 18? */
{ 0x12, SDLK_1, '!' },
{ 0x13, SDLK_2, '@' },
{ 0x14, SDLK_3, '#' },
{ 0x15, SDLK_4, '$' },
{ 0x17, SDLK_5, '%' },
{ 0x16, SDLK_6, '^' },
{ 0x1a, SDLK_7, '&' },
{ 0x1c, SDLK_8, '*' },
{ 0x19, SDLK_9, '(' },
{ 0x1d, SDLK_0, ')' },
{ 0x1b, SDLK_MINUS, SDLK_UNDERSCORE },
{ 0x18, SDLK_EQUALS, SDLK_PLUS },
{ 0x33, SDLK_BACKSPACE, 0 },
{ 0x72, SDLK_INSERT, 0 }, /* Help? XK_Help */
/* { 0x73, XK_Home, 0 }, alias XK_Home to be XK_KP_Equal! */
{ 0x74, SDLK_PAGEUP, 0 },
{ 0x47, SDLK_NUMLOCKCLEAR, 0 }, /* Clear, XK_Clear */
{ 0x51, SDLK_KP_EQUALS, 0 }, /* Note XK_Home alias! XK_Home */
{ 0x4b, SDLK_KP_DIVIDE, 0 },
{ 0x43, SDLK_KP_MULTIPLY, 0 },
{ 0x30, SDLK_TAB, 0 },
{ 0x0c, SDLK_q, 'Q' },
{ 0x0d, SDLK_w, 'W' },
{ 0x0e, SDLK_e, 'E' },
{ 0x0f, SDLK_r, 'R' },
{ 0x11, SDLK_t, 'T' },
{ 0x10, SDLK_y, 'Y' },
{ 0x20, SDLK_u, 'U' },
{ 0x22, SDLK_i, 'I' },
{ 0x1f, SDLK_o, 'O' },
{ 0x23, SDLK_p, 'P' },
{ 0x21, SDLK_RIGHTBRACKET, '{' },
{ 0x1e, SDLK_LEFTBRACKET, '}' },
{ 0x2a, SDLK_BACKSLASH, '|' }, /* backslash, bar */
{ 0x75, SDLK_DELETE, 0 },
{ 0x77, SDLK_END, 0 },
{ 0x79, SDLK_PAGEDOWN, 0 },
{ 0x59, SDLK_KP_7, SDLK_HOME },
{ 0x5b, SDLK_KP_8, SDLK_UP },
{ 0x5c, SDLK_KP_9, SDLK_PAGEUP },
{ 0x4e, SDLK_KP_MINUS, 0 },
{ 0x39, SDLK_CAPSLOCK, 0 },
{ 0x00, SDLK_a, 'A' },
{ 0x01, SDLK_s, 'S' },
{ 0x02, SDLK_d, 'D' },
{ 0x03, SDLK_f, 'F' },
{ 0x05, SDLK_g, 'G' },
{ 0x04, SDLK_h, 'H' },
{ 0x26, SDLK_j, 'J' },
{ 0x28, SDLK_k, 'K' },
{ 0x25, SDLK_l, 'L' },
{ 0x29, SDLK_SEMICOLON, SDLK_COLON },
{ 0x27, SDLK_QUOTE, SDLK_QUOTEDBL },
{ 0x24, SDLK_RETURN, 0 },
{ 0x56, SDLK_KP_4, SDLK_LEFT},
{ 0x57, SDLK_KP_5, 0 },
{ 0x58, SDLK_KP_6, SDLK_RIGHT },
{ 0x45, SDLK_KP_PLUS, 0 },
{ 0x38, SDLK_LSHIFT, SDLK_RSHIFT },
{ 0x06, SDLK_z, 'Z' },
{ 0x07, SDLK_x, 'X' },
{ 0x08, SDLK_c, 'C' },
{ 0x09, SDLK_v, 'V' },
{ 0x0b, SDLK_b, 'B' },
{ 0x2d, SDLK_n, 'N' },
{ 0x2e, SDLK_m, 'M' },
{ 0x2b, SDLK_COMMA, SDLK_LESS },
{ 0x2f, SDLK_PERIOD, SDLK_GREATER },
{ 0x2c, SDLK_SLASH, SDLK_QUESTION },
{ 0x3e, SDLK_UP, 0 },
{ 0x53, SDLK_KP_1, 0 },
{ 0x54, SDLK_KP_2, SDLK_DOWN },
{ 0x55, SDLK_KP_3, SDLK_PAGEDOWN },
{ 0x36, SDLK_RCTRL, SDLK_LCTRL },
#if defined(__APPLE__)
{ 0x3a, SDLK_LALT, SDLK_RALT }, /* Option */
{ 0x37, SDLK_LGUI, SDLK_RGUI }, /* Command */
#else
{ 0x3a, SDLK_LGUI, SDLK_RGUI }, /* Command */
{ 0x37, SDLK_LALT, SDLK_RALT }, /* Option */
#endif
{ 0x31, SDLK_SPACE, 0 },
{ 0x3b, SDLK_LEFT, 0 },
{ 0x3d, SDLK_DOWN, 0 },
{ 0x3c, SDLK_RIGHT, 0 },
{ 0x52, SDLK_KP_0, 0 },
{ 0x41, SDLK_KP_PERIOD, 0 },
{ 0x4c, SDLK_KP_ENTER, 0 },
{ -1, -1, -1 }
};
int main(int argc, char **argv) {
return gsportmain(argc, argv);
}
const char *byte_to_binary(int x) {
static char b[9];
b[0] = '\0';
int z;
for (z = 128; z > 0; z >>= 1)
{
strcat(b, ((x & z) == z) ? "1" : "0");
}
return b;
}
// Queries the Screen to see if set to Fullscreen or Not
// @return SDL_FALSE when windowed, SDL_TRUE when fullscreen
SDL_bool IsFullScreen(SDL_Window *win) {
Uint32 flags = SDL_GetWindowFlags(win);
if (flags & SDL_WINDOW_FULLSCREEN) {
return SDL_TRUE; // return SDL_TRUE if fullscreen
}
return SDL_FALSE; // Return SDL_FALSE if windowed
}
void dev_video_init() {
word32 lores_col;
// build keycode map ??
g_num_a2_keycodes = 0;
int i;
int keycode;
for(i = 0; i < 0x7f; i++) {
keycode = a2_key_to_sdlkeycode[i][0];
if(keycode < 0) {
g_num_a2_keycodes = i;
break;
} else if(keycode > 0x7f) {
glogf("a2_key_to_xsym[%d] = %02x!\n", i, keycode);
exit(2);
}
}
// This actually creates our window
dev_video_init_sdl();
// @todo DANGER DANGER. HARD CODING THESE.. there was logic for stepping values in xdriver
g_screen_depth = 24;
g_screen_mdepth =32;
video_get_kimages();
video_get_kimage(&g_mainwin_kimage, 0, g_screen_depth,g_screen_mdepth);
for(i = 0; i < 256; i++) {
//g_xcolor_a2vid_array[i].pixel = i;
lores_col = g_lores_colors[i & 0xf];
video_update_color_raw(i, lores_col);
g_a2palette_8to1624[i] = g_palette_8to1624[i];
}
}
void do_icon() {
#ifdef HAVE_ICON
//surface = SDL_CreateRGBSurfaceFrom(pixels,w,h,depth,pitch,rmask,gmask,bmask,amask);
int size = 256; // icon size
SDL_Surface *surface; // declare an SDL_Surface to be filled in with pixel data from an image file
surface = SDL_CreateRGBSurfaceFrom(icon_pixels,size,size,32,size*4,0xff000000,0x00ff0000,0x0000ff00,0x000000ff);
// The icon is attached to the window pointer
SDL_SetWindowIcon(window, surface);
// ...and the surface containing the icon pixel data is no longer required.
SDL_FreeSurface(surface);
#endif
}
// Initialize our SDL window and texture
void dev_video_init_sdl() {
SDL_Init(SDL_INIT_VIDEO); // Initialize SDL2
#if defined __APPLE__
extern void fix_mac_menu();
fix_mac_menu();
#endif
// Create an application window with the following settings:
char window_title[32];
sprintf(window_title, "GSport v%-6s", g_gsport_version_str);
int startx = SDL_WINDOWPOS_UNDEFINED;
int starty = SDL_WINDOWPOS_UNDEFINED;
if (g_startx != WINDOWPOS_UNDEFINED) { startx = g_startx; }
if (g_starty != WINDOWPOS_UNDEFINED) { starty = g_starty; }
int more_flags = 0;
// check for CLI fullscreen
if (g_fullscreen) {
more_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
if (g_highdpi) {
more_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
}
if (g_borderless) {
more_flags |= SDL_WINDOW_BORDERLESS;
}
if (g_resizeable) {
more_flags |= SDL_WINDOW_RESIZABLE;
}
window = SDL_CreateWindow(
window_title, // window title (GSport vX.X)
startx,
starty,
g_startw, // width, in pixels
g_starth, // height, in pixels
SDL_WINDOW_OPENGL // flags - see below
| more_flags
);
// Check that the window was successfully created
if (window == NULL) {
// In the case that the window could not be made...
glogf("Could not create window: %s", SDL_GetError());
//@todo die, i guess
} else {
glog("SDL2 graphics initialized");
}
// SET WINDOW ICON
do_icon();
int renderer_hints = 0;
if (!g_novsync) {
renderer_hints |= SDL_RENDERER_PRESENTVSYNC;
}
if (!g_nohwaccel) {
renderer_hints |= SDL_RENDERER_ACCELERATED;
}
renderer = SDL_CreateRenderer(window, -1, renderer_hints);
debuginfo_renderer(renderer);
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear"); // make the scaled rendering look smoother.
// SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best"); // make the scaled rendering look smoother.
if (!g_noaspect) {
SDL_RenderSetLogicalSize(renderer, BASE_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT);
}
texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
BASE_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT);
// The window is open: could enter program loop here (see SDL_PollEvent())
//overlay test
overlay_texture = SDL_CreateTexture(renderer,
SDL_PIXELFORMAT_ARGB8888,
SDL_TEXTUREACCESS_STREAMING,
BASE_WINDOW_WIDTH,
X_A2_WINDOW_HEIGHT);
SDL_SetTextureBlendMode(overlay_texture, SDL_BLENDMODE_BLEND);
overlay_pixels = malloc(BASE_WINDOW_WIDTH*X_A2_WINDOW_HEIGHT*sizeof(Uint32));
Uint32 pixelARGB = 0x33000000; // default "low grey"
if (overlay_pixels) {
if (g_scanline_simulator > 0) {
pixelARGB = (int)(g_scanline_simulator*2.56) << 24;
}
for (int y=0; y<X_A2_WINDOW_HEIGHT; y++) {
for (int x=0; x<BASE_WINDOW_WIDTH; x++) {
if (y%2 == 1) {
overlay_pixels[(y*BASE_WINDOW_WIDTH)+x] = pixelARGB;
}
}
}
}
SDL_Rect dstrect;
dstrect.x = 0;
dstrect.y = 0;
dstrect.w = BASE_WINDOW_WIDTH;
dstrect.h = X_A2_WINDOW_HEIGHT;
int pitch = BASE_WINDOW_WIDTH;
// UPDATE A RECT OF THE APPLE II SCREEN TEXTURE
SDL_UpdateTexture(overlay_texture, &dstrect, overlay_pixels, pitch*sizeof(Uint32) );
// Turn off host mouse cursor
SDL_ShowCursor(SDL_DISABLE);
}
// Copy a rect to our SDL window
void sdl_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy, int width, int height) {
byte *src_ptr;
int pixel_size = 4;
src_ptr = kimage_ptr->data_ptr + (srcy * kimage_ptr->width_act + srcx) * pixel_size;
SDL_Rect dstrect;
dstrect.x = destx;
dstrect.y = desty;
dstrect.w = width;
dstrect.h = height;
int pitch = 640;
if (width < 560) {
pitch = EFF_BORDER_WIDTH;
// seems to be the correct value, but would like clarification
pitch = BORDER_WIDTH+72;
}
SDL_UpdateTexture(texture, &dstrect, src_ptr, pitch*4 );
// We now call the render step seperately in sdl_present_buffer once per frame
// SDL picks up the buffer and waits for VBLANK to send it
}
void set_refresh_needed() {
g_a2_screen_buffer_changed = -1;
g_full_refresh_needed = -1;
g_border_sides_refresh_needed = 1;
g_border_special_refresh_needed = 1;
g_status_refresh_needed = 1;
}
void x_get_kimage(Kimage *kimage_ptr) {
byte *data;
int width;
int height;
int depth;
width = kimage_ptr->width_req;
height = kimage_ptr->height;
depth = kimage_ptr->depth;
// this might be too big!!! I had it at depth/3 but it segfaults
data = malloc(width*height*(depth/4));
kimage_ptr->data_ptr = data;
}
void check_input_events() {
check_input_events_sdl();
}
void check_input_events_sdl() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
/* Check all window events (mostly for Fullscreen) */
if (event.type == SDL_WINDOWEVENT) {
set_refresh_needed();
}
switch( event.type ) {
case SDL_KEYDOWN:
case SDL_KEYUP:
handle_sdl_key_event(event);
break;
case SDL_MOUSEMOTION:
case SDL_MOUSEBUTTONUP:
case SDL_MOUSEBUTTONDOWN:
handle_sdl_mouse_event(event);
break;
case SDL_QUIT:
xdriver_end();
my_exit(1);
break;
case SDL_DROPFILE:
{
char *file = event.drop.file;
cfg_inspect_maybe_insert_file(file, 0);
SDL_free(file);
}
break;
default:
break;
}
}
}
int sdl_keysym_to_a2code(int keysym, int is_up) {
int i;
if(keysym == 0) {
return -1;
}
if((keysym == SDLK_LSHIFT) || (keysym == SDLK_RSHIFT)) {
if(is_up) {
kb_shift_control_state &= ~ShiftMask;
} else {
kb_shift_control_state |= ShiftMask;
}
}
if(keysym == SDLK_CAPSLOCK) {
if(is_up) {
kb_shift_control_state &= ~LockMask;
} else {
kb_shift_control_state |= LockMask;
}
}
if((keysym == SDLK_LCTRL) || (keysym == SDLK_RCTRL)) {
if(is_up) {
kb_shift_control_state &= ~ControlMask;
} else {
kb_shift_control_state |= ControlMask;
}
}
/* Look up Apple 2 keycode */
for(i = g_num_a2_keycodes - 1; i >= 0; i--) {
if((keysym == a2_key_to_sdlkeycode[i][1]) ||
(keysym == a2_key_to_sdlkeycode[i][2])) {
return a2_key_to_sdlkeycode[i][0];
}
}
return -1;
}
void handle_sdl_key_event(SDL_Event event) {
int state_xor;
int state = 0;
int is_up;
int mod = event.key.keysym.mod;
// simulate xmask style here
// @todo: this can probably all be refactored now that X is gone
//state = state & (ControlMask | LockMask | ShiftMask);
// when mod key is first press, comes as event, otherwise just a modifier
if( mod & KMOD_LCTRL || mod & KMOD_RCTRL ||
event.type == (SDL_KEYDOWN && (event.key.keysym.sym == SDLK_LCTRL || event.key.keysym.sym == SDLK_RCTRL))) {
state = state | ControlMask;
}
if( (mod & KMOD_LSHIFT) || (mod & KMOD_RSHIFT) ||
event.type == (SDL_KEYDOWN && (event.key.keysym.sym == SDLK_LSHIFT || event.key.keysym.sym == SDLK_RSHIFT))) {
state = state | ShiftMask;
}
if( mod & KMOD_CAPS) {
state = state | LockMask;
}
state_xor = kb_shift_control_state ^ state;
is_up = 0;
if(state_xor & ControlMask) {
is_up = ((state & ControlMask) == 0);
adb_physical_key_update(0x36, is_up);
}
if(state_xor & LockMask) {
is_up = ((state & LockMask) == 0);
adb_physical_key_update(0x39, is_up);
}
if(state_xor & ShiftMask) {
is_up = ((state & ShiftMask) == 0);
adb_physical_key_update(0x38, is_up);
}
kb_shift_control_state = state;
is_up = 0;
int a2code;
if (event.type == SDL_KEYUP) {
is_up = 1;
}
switch( event.key.keysym.sym ) {
case SDLK_F11:
if (kb_shift_control_state & ShiftMask) { // SHIFT+F11
if (!is_up) {
if (g_scanline_simulator) {
glog("Enable scanline simulator");
g_scanline_simulator = 0;
} else {
glog("Disable scanline simulator");
g_scanline_simulator = 1;
}
set_refresh_needed(); // make sure user sees it right away
}
} else {
if (!is_up) {
if (!IsFullScreen(window)) {
glog("Enable fullscreen");
SDL_SetWindowGrab(window, true);
SDL_SetRelativeMouseMode(true);
Uint32 fullmode = g_fullscreen_desktop ? SDL_WINDOW_FULLSCREEN_DESKTOP : SDL_WINDOW_FULLSCREEN;
SDL_SetWindowFullscreen(window, fullmode);
} else {
glog("Disable fullscreen");
SDL_SetWindowFullscreen(window, 0);
SDL_SetWindowGrab(window, false);
SDL_SetWindowSize(window, g_startw, g_starth);
SDL_SetRelativeMouseMode(false);
}
}
}
break;
default:
a2code = sdl_keysym_to_a2code(event.key.keysym.sym, is_up);
if(a2code >= 0) {
adb_physical_key_update(a2code, is_up);
}
break;
}
}
void handle_sdl_mouse_event(SDL_Event event) {
int x, y;
int scaledmotion = 0;
if (scaledmotion) {
x = event.motion.x * A2_WINDOW_WIDTH / g_startw;
y = event.motion.y * A2_WINDOW_HEIGHT / g_starth;
} else {
x = event.motion.x - BASE_MARGIN_LEFT;
y = event.motion.y - BASE_MARGIN_TOP;
}
switch (event.type) {
case SDL_MOUSEMOTION:
update_mouse_w_delta(x, y, 0, 0, event.motion.xrel, event.motion.yrel);
break;
case SDL_MOUSEBUTTONUP:
update_mouse_w_delta(x, y, 0, event.motion.state &7, 0, 0);
break;
case SDL_MOUSEBUTTONDOWN:
update_mouse_w_delta(x, y, event.motion.state &7, event.motion.state &7 , 0, 0);
break;
}
}
void x_push_kimage(Kimage *kimage_ptr, int destx, int desty, int srcx, int srcy, int width, int height) {
sdl_push_kimage(kimage_ptr, destx, desty, srcx, srcy, width, height);
}
// called by src/sim65816.c
void x_dialog_create_gsport_conf(const char *str) {
// Just write the config file already...
config_write_config_gsport_file();
}
void x_full_screen(int do_full) {
if (do_full) {
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
} else {
SDL_SetWindowFullscreen(window, 0);
SDL_SetWindowSize(window, BASE_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT);
}
}
int file_exists(char *fname) {
if( access( fname, F_OK ) != -1 ) {
return 1; // file exists
} else {
return 0; // file does not exist
}
}
// This tries to determine the next screenshot name.
// It uses the config name as the basename.
void make_next_screenshot_filename() {
char filepart[256];
char filename[256];
int available_filename = 0;
while (!available_filename) {
char *bn = basename(g_config_gsport_name);
// get location of '.'
char *dotptr = strchr(bn, '.');
int index = dotptr - bn;
strncpy(filepart, bn, index);
filepart[index] = '\0'; //terminator
// handle trailing "/" vs no "/"
char tchar = g_config_gsport_screenshot_dir[strlen(g_config_gsport_screenshot_dir) - 1];
if (tchar == '/') {
sprintf(filename, "%s%s%04d.png",g_config_gsport_screenshot_dir,filepart,screenshot_index);
} else {
sprintf(filename, "%s/%s%04d.png",g_config_gsport_screenshot_dir,filepart,screenshot_index);
}
screenshot_index++;
if (!file_exists(filename)) {
available_filename = 1;
}
}
strcpy(screenshot_filename, filename);
}
// @todo: some error with writing data direct to png. output is empty/transparent?
// workaround is this horrible hack of saving the bmp -> load bmp -> save png
void x_take_screenshot() {
make_next_screenshot_filename();
glogf("Taking screenshot - %s", screenshot_filename);
SDL_Surface *sshot = SDL_CreateRGBSurface(0, BASE_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
SDL_LockSurface(sshot);
int read = SDL_RenderReadPixels(renderer, NULL, SDL_PIXELFORMAT_ARGB8888, sshot->pixels, sshot->pitch);
if (read != 0) {
printf("READPXL FAIL!\n%s\n", SDL_GetError());
}
SDL_SaveBMP(sshot, "screenshot.bmp");
SDL_UnlockSurface(sshot);
SDL_FreeSurface(sshot);
SDL_Surface *s = SDL_CreateRGBSurface(0, BASE_WINDOW_WIDTH, X_A2_WINDOW_HEIGHT, 32, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000);
if (s) {
SDL_Surface * image = SDL_LoadBMP("screenshot.bmp");
IMG_SavePNG(image, screenshot_filename);
SDL_FreeSurface(image);
}
SDL_FreeSurface(s);
}
void clipboard_paste(void) {
char *cp;
if (g_clipboard) {
free(g_clipboard);
g_clipboard = NULL;
g_clipboard_pos = 0;
}
cp = SDL_GetClipboardText();
if (!cp) return;
g_clipboard = strdup(cp);
g_clipboard_pos = 0;
SDL_free(cp);
}
int clipboard_get_char(void) {
char c;
if (!g_clipboard)
return 0;
/* skip utf-8 characters. */
do {
c = g_clipboard[g_clipboard_pos++];
} while (c & 0x80);
/* windows -- skip the \n in \r\n. */
if (c == '\r' && g_clipboard[g_clipboard_pos] == '\n')
g_clipboard_pos++;
/* everybody else -- convert \n to \r */
if (c == '\n') c = '\r';
if (c == 0) {
free(g_clipboard);
g_clipboard = NULL;
g_clipboard_pos = 0;
return 0;
}
return c | 0x80;
}
int x_show_alert(int is_fatal, const char *str) {
if (str) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "GSport Alert", str, NULL);
}
return 0;
}
void xdriver_end() {
SDL_DestroyWindow(window);
iwm_shut();
// Clean up
SDL_Quit();
}
// This will help us determine how well and which drivers are supported on
// different SDL platforms
void debuginfo_renderer(SDL_Renderer *r) {
int n = SDL_GetNumRenderDrivers();
glogf("**--- SDL DEBUG ------ (%i) drivers", n);
for(int i = 0; i < n; i++) {
SDL_RendererInfo info;
SDL_GetRenderDriverInfo(i, &info);
glogf("* '%s'", info.name);
}
SDL_RendererInfo info = {0};
if (SDL_GetRendererInfo(r,&info) == 0) {
glogf("* SDL_RENDERER_SOFTWARE: %d", (info.flags & SDL_RENDERER_SOFTWARE) > 0 );
glogf("* SDL_RENDERER_ACCELERATED: %d", (info.flags & SDL_RENDERER_ACCELERATED) > 0 );
glogf("* SDL_RENDERER_PRESENTVSYNC: %d", (info.flags & SDL_RENDERER_PRESENTVSYNC) > 0 );
glogf("* SDL_RENDERER_TARGETTEXTURE: %d", (info.flags & SDL_RENDERER_TARGETTEXTURE) > 0 );
glogf("* active renderer -> '%s'", info.name);
} else {
glog("NO Renderinfo");
}
}
// as this is triggered when new images were pushed to backing buffer,
// this is when we want to update frames.
// putting it in x_push_done means we can skip frames that weren't changed.
// the emulator will still run at whatever specified speed. but this way,
// when running in faster 8mhz/unlimited modes, it won't be slowed down by
// forcing every draw at 60FPS sync.
void x_push_done() {
void sdl_present_buffer();
sdl_present_buffer();
}
void sdl_present_buffer() {
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, texture, NULL, NULL);
if (g_scanline_simulator) {
SDL_RenderCopy(renderer, overlay_texture, NULL, NULL);
}
SDL_RenderPresent(renderer);
if (g_screenshot_requested) {
x_take_screenshot();
g_screenshot_requested = 0;
}
}
void x_grabmouse() {
SDL_SetWindowGrab(window, g_grabmouse);
SDL_SetRelativeMouseMode(g_grabmouse);
}
// BELOW ARE FUNCTIONS THAT ARE EITHER UNIMPLEMENTED, OR AR NOT RELEVANT TO
// THIS DRIVER.
// called by src/sim65816.c
void get_ximage(Kimage *kimage_ptr) { }
void x_toggle_status_lines() { }
void x_redraw_status_lines() { }
void x_hide_pointer(int do_hide) { }
void x_auto_repeat_on(int must) { }
void x_auto_repeat_off(int must) { }
void x_release_kimage(Kimage* kimage_ptr) { }
int x_calc_ratio(float x,float y) { return 1; }
void x_set_mask_and_shift(word32 x_mask, word32 *mask_ptr, int *shift_left_ptr, int *shift_right_ptr) { return; }
void x_update_color(int col_num, int red, int green, int blue, word32 rgb) { }
void x_update_physical_colormap() { }
void show_xcolor_array() { }

222
src/sdl2snd_driver.c Normal file
View File

@ -0,0 +1,222 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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 "SDL.h"
#include "defc.h"
#include "glog.h"
#include "sound.h"
#include <assert.h>
extern word32 *g_sound_shm_addr;
extern int g_sound_shm_pos;
extern int g_audio_enable;
extern int g_preferred_rate;
static byte *playbuf = 0;
static int g_playbuf_buffered = 0;
static SDL_AudioSpec spec;
static int snd_buf;
static int snd_write; /* write position into playbuf */
static /* volatile */ int snd_read = 0;
static int g_sound_paused;
static int g_zeroes_buffered;
static int g_zeroes_seen;
// newer SDL allows you to specify devices. for now, we use what it gives us,
// but this can be made configurable in the future
SDL_AudioDeviceID dev = 0;
void sdlsnd_init(word32 *shmaddr) {
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
glog("Could not initialize SDL2 audio");
g_audio_enable = 0;
} else {
glog("SDL2 audio initialized");
}
child_sound_loop(-1, -1, shmaddr);
return;
}
void sound_write_sdl(int real_samps, int size) {
#ifdef HAVE_SDL
int shm_read;
if (real_samps) {
shm_read = (g_sound_shm_pos - size + SOUND_SHM_SAMP_SIZE)%SOUND_SHM_SAMP_SIZE;
SDL_LockAudioDevice(dev);
while(size > 0) {
if(g_playbuf_buffered >= snd_buf) {
printf("sound_write_sdl failed @%d, %d buffered, %d samples skipped\n",snd_write,g_playbuf_buffered, size);
shm_read += size;
shm_read %= SOUND_SHM_SAMP_SIZE;
size = 0;
} else {
((word32*)playbuf)[snd_write/SAMPLE_CHAN_SIZE] = g_sound_shm_addr[shm_read];
shm_read++;
if (shm_read >= SOUND_SHM_SAMP_SIZE)
shm_read = 0;
snd_write += SAMPLE_CHAN_SIZE;
if (snd_write >= snd_buf)
snd_write = 0;
size--;
g_playbuf_buffered += SAMPLE_CHAN_SIZE;
}
}
assert((snd_buf+snd_write - snd_read)%snd_buf == g_playbuf_buffered%snd_buf);
assert(g_sound_shm_pos == shm_read);
SDL_UnlockAudioDevice(dev);
}
if(g_sound_paused && (g_playbuf_buffered > 0)) {
glogf("Unpausing sound, %d buffered",g_playbuf_buffered);
g_sound_paused = 0;
SDL_PauseAudioDevice(dev, 0);
}
if(!g_sound_paused && (g_playbuf_buffered <= 0)) {
glog("Pausing sound");
g_sound_paused = 1;
SDL_PauseAudioDevice(dev, 1);
}
#endif
}
#ifdef HAVE_SDL
/* Callback for sound */
static void _snd_callback(void* userdata, Uint8 *stream, int len) {
int i;
/* Slurp off the play buffer */
assert((snd_buf+snd_write - snd_read)%snd_buf == g_playbuf_buffered%snd_buf);
/*printf("slurp %d, %d buffered\n",len, g_playbuf_buffered);*/
for(i = 0; i < len; ++i) {
if(g_playbuf_buffered <= 0) {
stream[i] = 0;
} else {
stream[i] = playbuf[snd_read++];
if(snd_read == snd_buf)
snd_read = 0;
g_playbuf_buffered--;
}
}
#if 0
if (g_playbuf_buffered <= 0) {
printf("snd_callback: buffer empty, Pausing sound\n");
g_sound_paused = 1;
SDL_PauseAudio(1);
}
#endif
//printf("end slurp %d, %d buffered\n",len, g_playbuf_buffered);
}
#endif
long sound_init_device_sdl() {
#ifdef HAVE_SDL
long rate;
SDL_AudioSpec wanted;
if (SDL_Init(SDL_INIT_AUDIO) < 0) {
glogf("SDL2 Couldn't init SDL_INIT_AUDIO: %s!", SDL_GetError());
return 0;
}
/* Set the desired format */
wanted.freq = g_preferred_rate;
wanted.format = AUDIO_S16SYS;
wanted.channels = NUM_CHANNELS;
wanted.samples = 512;
wanted.callback = _snd_callback;
wanted.userdata = NULL;
/* Open audio, and get the real spec */
dev = SDL_OpenAudioDevice(NULL, 0, &wanted, &spec, 0);
if (dev == 0) {
glogf("SDL2 Couldn't open audio: %s!", SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_AUDIO);
return 0;
} else {
glogf("SDL2 opened audio device: %d", dev);
}
/* Check everything */
if(spec.channels != wanted.channels) {
glogf("SDL2 Warning, couldn't get stereo audio format!");
//goto snd_error;
}
if(spec.format != wanted.format) {
glog("SDL2 Warning, couldn't get a supported audio format!");
glogf("SDL2 wanted %X, got %X",wanted.format,spec.format);
//goto snd_error;
}
if(spec.freq != wanted.freq) {
glogf("SDL2 wanted rate = %d, got rate = %d", wanted.freq, spec.freq);
}
/* Set things as they really are */
rate = spec.freq;
snd_buf = SOUND_SHM_SAMP_SIZE*SAMPLE_CHAN_SIZE;
playbuf = (byte*) malloc(snd_buf);
if (!playbuf)
goto snd_error;
g_playbuf_buffered = 0;
glogf("SDL2 sound shared memory size=%d", SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE);
g_sound_shm_addr = malloc(SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE);
memset(g_sound_shm_addr,0,SOUND_SHM_SAMP_SIZE * SAMPLE_CHAN_SIZE);
/* It's all good! */
g_zeroes_buffered = 0;
g_zeroes_seen = 0;
/* Let's start playing sound */
g_sound_paused = 0;
SDL_PauseAudioDevice(dev, 0);
set_audio_rate(rate);
return rate;
snd_error:
/* Oops! Something bad happened, cleanup. */
SDL_CloseAudioDevice(dev);
SDL_QuitSubSystem(SDL_INIT_AUDIO);
if(playbuf)
free((void*)playbuf);
playbuf = 0;
snd_buf = 0;
return 0;
#else
return 0;
#endif
}
void sound_shutdown_sdl() {
#ifdef HAVE_SDL
SDL_CloseAudioDevice(dev);
if(playbuf)
free((void*)playbuf);
playbuf = 0;
#endif
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2012 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -21,10 +22,15 @@
#include "defc.h"
#include "sound.h"
#include "glog.h"
#ifdef HPUX
# include <sys/audio.h>
#endif
#ifdef HAVE_SDL
# include "SDL.h"
long sound_init_device_sdl();
#endif
#if defined(__linux__) || defined(OSS)
# include <sys/soundcard.h>
@ -65,18 +71,17 @@ void child_sound_init_linux();
void child_sound_init_hpdev();
void child_sound_initWIN_SOUND();
void child_sound_init_mac();
void child_sound_init_sdl();
long sound_init_device_sdl();
void
reliable_buf_write(word32 *shm_addr, int pos, int size)
{
void reliable_buf_write(word32 *shm_addr, int pos, int size) {
byte *ptr;
int ret;
int ret = 0;
if(size < 1 || pos < 0 || pos > SOUND_SHM_SAMP_SIZE ||
size > SOUND_SHM_SAMP_SIZE ||
(pos + size) > SOUND_SHM_SAMP_SIZE) {
printf("reliable_buf_write: pos: %04x, size: %04x\n",
pos, size);
printf("reliable_buf_write: pos: %04x, size: %04x\n", pos, size);
exit(1);
}
@ -84,14 +89,15 @@ reliable_buf_write(word32 *shm_addr, int pos, int size)
size = size * 4;
while(size > 0) {
#ifdef WIN_SOUND
#if defined(HAVE_SDL)
//ret = sdl_send_audio(ptr, size);
#elif defined(WIN_SOUND)
ret = win32_send_audio(ptr, size);
#else
# ifdef MAC
#elif defined(MAC) && !defined(HAVE_SDL)
ret = mac_send_audio(ptr, size);
#else
ret = write(g_audio_socket, ptr, size);
# endif
#endif
if(ret < 0) {
@ -105,9 +111,7 @@ reliable_buf_write(word32 *shm_addr, int pos, int size)
}
void
reliable_zero_write(int amt)
{
void reliable_zero_write(int amt) {
int len;
while(amt > 0) {
@ -118,17 +122,10 @@ reliable_zero_write(int amt)
}
void
child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
{
#ifdef HPUX
long status_return;
#endif
void child_sound_loop(int read_fd, int write_fd, word32 *shm_addr) {
word32 tmp;
int ret;
doc_printf("Child pipe fd: %d\n", read_fd);
g_audio_rate = g_preferred_rate;
g_zeroes_buffered = 0;
@ -139,21 +136,24 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
g_childsnd_vbl = 0;
g_childsnd_shm_addr = shm_addr;
#ifdef HPUX
child_sound_init_hpdev();
#endif
#if defined(__linux__) || defined(OSS)
#if defined(HAVE_SDL)
//child_sound_init_sdl();
sound_init_device_sdl(); // ignores long return value of sample rate
return;
#elif defined(__linux__) || defined(OSS)
child_sound_init_linux();
#endif
#ifdef WIN_SOUND
#elif HPUX
child_sound_init_hpdev();
#elif WIN_SOUND
child_sound_init_win32();
return;
#endif
#ifdef MAC
#elif defined(MAC) && !defined(HAVE_SDL)
child_sound_init_mac();
return;
#endif
doc_printf("Child pipe fd: %d\n", read_fd);
tmp = g_audio_rate;
ret = write(write_fd, &tmp, 4);
if(ret != 4) {
@ -185,15 +185,12 @@ child_sound_loop(int read_fd, int write_fd, word32 *shm_addr)
exit(0);
}
void
child_sound_playit(word32 tmp)
{
// called by sound.c:send_sound()
void child_sound_playit(word32 tmp) {
int size;
size = tmp & 0xffffff;
//printf("child_sound_playit: %08x\n", tmp);
if((tmp >> 24) == 0xa2) {
/* play sound here */
@ -212,6 +209,7 @@ child_sound_playit(word32 tmp)
g_zeroes_buffered = 0;
g_zeroes_seen = 0;
// only write up to end of buffer
if((size + g_childsnd_pos) > SOUND_SHM_SAMP_SIZE) {
reliable_buf_write(g_childsnd_shm_addr, g_childsnd_pos,
SOUND_SHM_SAMP_SIZE - g_childsnd_pos);
@ -222,7 +220,7 @@ child_sound_playit(word32 tmp)
reliable_buf_write(g_childsnd_shm_addr, g_childsnd_pos, size);
if(g_sound_paused) {
printf("Unpausing sound, zb: %d\n", g_zeroes_buffered);
glogf("Unpausing sound, zb: %d\n", g_zeroes_buffered);
g_sound_paused = 0;
}
@ -238,7 +236,7 @@ child_sound_playit(word32 tmp)
reliable_zero_write(size);
if(g_zeroes_seen >= ZERO_PAUSE_NUM_SAMPS) {
printf("Pausing sound\n");
glog("Pausing sound");
g_sound_paused = 1;
}
}
@ -255,24 +253,13 @@ child_sound_playit(word32 tmp)
g_childsnd_vbl++;
if(g_childsnd_vbl >= 60) {
g_childsnd_vbl = 0;
#if 0
printf("sound bytes written: %06x\n", g_bytes_written);
printf("Sample samples[0]: %08x %08x %08x %08x\n",
g_childsnd_shm_addr[0], g_childsnd_shm_addr[1],
g_childsnd_shm_addr[2], g_childsnd_shm_addr[3]);
printf("Sample samples[100]: %08x %08x %08x %08x\n",
g_childsnd_shm_addr[100], g_childsnd_shm_addr[101],
g_childsnd_shm_addr[102], g_childsnd_shm_addr[103]);
#endif
g_bytes_written = 0;
}
}
#ifdef HPUX
void
child_sound_init_hpdev()
{
void child_sound_init_hpdev() {
struct audio_describe audio_descr;
int output_channel;
char *str;
@ -363,9 +350,7 @@ child_sound_init_hpdev()
#endif /* HPUX */
#if defined(__linux__) || defined(OSS)
void
child_sound_init_linux()
{
void child_sound_init_linux() {
int stereo;
int sample_size;
int rate;

6
src/tfe/CMakeLists.txt Normal file
View File

@ -0,0 +1,6 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(tfe tfe.c tfearch.c tfesupp.c)
target_compile_definitions(tfe PUBLIC HAVE_TFE)

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey

View File

@ -26,8 +26,6 @@
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@ -316,8 +314,7 @@ static int rxevent_read_mask = 3; /* set if L and/or H byte was read in RXEVENT?
static int TfeDebugMaxFrameLengthToDump = 150;
static char *debug_outbuffer(const int length, const unsigned char * const buffer)
{
static char *debug_outbuffer(const int length, const unsigned char * const buffer) {
#define MAXLEN_DEBUG 1600
int i;
@ -344,8 +341,7 @@ static char *debug_outbuffer(const int length, const unsigned char * const buffe
/* ------------------------------------------------------------------------- */
/* initialization and deinitialization functions */
static void tfe_set_tx_status(int ready,int error)
{
static void tfe_set_tx_status(int ready,int error) {
word16 old_status = GET_PP_16(TFE_PP_ADDR_SE_BUSST);
/* mask out TxBidErr and Rdy4TxNOW */
@ -364,24 +360,21 @@ static void tfe_set_tx_status(int ready,int error)
}
}
static void tfe_set_receiver(int enabled)
{
static void tfe_set_receiver(int enabled) {
rx_enabled = enabled;
rx_state = TFE_RX_IDLE;
rxevent_read_mask = 3; /* was L or H byte read in RXEVENT? */
}
static void tfe_set_transmitter(int enabled)
{
static void tfe_set_transmitter(int enabled) {
tx_enabled = enabled;
tx_state = TFE_TX_IDLE;
tfe_set_tx_status(0,0);
}
void tfe_reset(void)
{
void tfe_reset(void) {
if (tfe_enabled && !should_activate)
{
int i;
@ -460,8 +453,7 @@ void tfe_reset(void)
}
#ifdef DOS_TFE
static void set_standard_tfe_interface(void)
{
static void set_standard_tfe_interface(void) {
char *dev, errbuf[PCAP_ERRBUF_SIZE];
dev = pcap_lookupdev(errbuf);
util_string_set(&tfe_interface, dev);
@ -469,8 +461,7 @@ static void set_standard_tfe_interface(void)
#endif
static
int tfe_activate_i(void)
{
int tfe_activate_i(void) {
assert( tfe == NULL );
assert( tfe_packetpage == NULL );
@ -528,8 +519,7 @@ int tfe_activate_i(void)
}
static
int tfe_deactivate_i(void)
{
int tfe_deactivate_i(void) {
#ifdef TFE_DEBUG
log_message( tfe_log, "tfe_deactivate_i()." );
#endif
@ -576,8 +566,7 @@ int tfe_deactivate(void) {
return 0;
}
void tfe_init(void)
{
void tfe_init(void) {
tfe_enabled = 1;
init_tfe_flag = 1;
should_activate = 1;
@ -595,8 +584,7 @@ void tfe_init(void)
}
}
void tfe_shutdown(void)
{
void tfe_shutdown(void) {
assert( (tfe && tfe_packetpage) || (!tfe && !tfe_packetpage));
if (tfe)
@ -645,8 +633,7 @@ TFE_PP_ADDR_MAC_ADDR 0x0158 * # RW - 4.6., p. 71 - 5.3., p. 86 *
necessary, which is the reason why its prototype is included here in tfearch.h.
*/
int tfe_should_accept(unsigned char *buffer, int length, int *phashed, int *phash_index,
int *pcorrect_mac, int *pbroadcast, int *pmulticast)
{
int *pcorrect_mac, int *pbroadcast, int *pmulticast) {
int hashreg; /* Hash Register (for hash computation) */
assert(length>=6); /* we need at least 6 octets since the DA has this length */
@ -729,8 +716,7 @@ int tfe_should_accept(unsigned char *buffer, int length, int *phashed, int *phas
#endif
static
word16 tfe_receive(void)
{
word16 tfe_receive(void) {
word16 ret_val = 0x0004;
byte buffer[MAX_RXLENGTH];
@ -855,8 +841,7 @@ word16 tfe_receive(void)
/* ------------------------------------------------------------------------- */
/* TX/RX buffer handling */
static void tfe_write_tx_buffer(byte value,int odd_address)
{
static void tfe_write_tx_buffer(byte value,int odd_address) {
/* write tx data only if valid buffer is ready */
if(tx_state != TFE_TX_READ_BUSST) {
#ifdef TFE_DEBUG_WARN_RXTX
@ -925,8 +910,7 @@ static void tfe_write_tx_buffer(byte value,int odd_address)
}
}
static byte tfe_read_rx_buffer(int odd_address)
{
static byte tfe_read_rx_buffer(int odd_address) {
if(rx_state != TFE_RX_GOT_FRAME) {
#ifdef TFE_DEBUG_WARN_RXTX
log_message(tfe_log, "WARNING! RX Read without frame available! (odd=%d)",
@ -995,8 +979,7 @@ static byte tfe_read_rx_buffer(int odd_address)
This is called *after* the relevant octets are written
*/
static
void tfe_sideeffects_write_pp(word16 ppaddress, int odd_address)
{
void tfe_sideeffects_write_pp(word16 ppaddress, int odd_address) {
// const char *on_off[2] = { "on","off" };
//#define on_off_str(x) ((x) ? on_off[0] : on_off[1])
word16 content = GET_PP_16( ppaddress );
@ -1197,8 +1180,7 @@ void tfe_sideeffects_write_pp(word16 ppaddress, int odd_address)
This is called *before* the relevant octets are read
*/
static
void tfe_sideeffects_read_pp(word16 ppaddress,int odd_address)
{
void tfe_sideeffects_read_pp(word16 ppaddress,int odd_address) {
switch (ppaddress)
{
case TFE_PP_ADDR_SE_RXEVENT:
@ -1266,8 +1248,7 @@ void tfe_sideeffects_read_pp(word16 ppaddress,int odd_address)
/* read/write from packet page register */
/* read a register from packet page */
static word16 tfe_read_register(word16 ppaddress)
{
static word16 tfe_read_register(word16 ppaddress) {
word16 value = GET_PP_16(ppaddress);
/* --- check the register address --- */
@ -1413,8 +1394,7 @@ static word16 tfe_read_register(word16 ppaddress)
return value;
}
void tfe_write_register(word16 ppaddress,word16 value)
{
void tfe_write_register(word16 ppaddress,word16 value) {
/* --- write bus interface register range --- */
if(ppaddress<0x100) {
int ignore = 0;
@ -1561,8 +1541,7 @@ void tfe_write_register(word16 ppaddress,word16 value)
#define PP_PTR_FLAG_MASK 0xf000 /* is always : x y 1 1 (with x=auto incr) */
#define PP_PTR_ADDR_MASK 0x0fff /* address portion of packet page pointer */
static void tfe_auto_incr_pp_ptr(void)
{
static void tfe_auto_incr_pp_ptr(void) {
/* perform auto increment of packet page pointer */
if((tfe_packetpage_ptr & PP_PTR_AUTO_INCR_FLAG)==PP_PTR_AUTO_INCR_FLAG) {
/* pointer is always increment by one on real HW */
@ -1581,8 +1560,7 @@ static void tfe_auto_incr_pp_ptr(void)
#define LOHI_WORD(x,y) ( (word16)(x) | ( ((word16)(y)) <<8 ) )
/* ----- read byte from I/O range in VICE ----- */
byte tfe_read(word16 io_address)
{
byte tfe_read(word16 io_address) {
byte retval,lo,hi;
word16 word_value;
word16 reg_base;
@ -1677,8 +1655,7 @@ byte tfe_read(word16 io_address)
}
/* ----- write byte to I/O range of VICE ----- */
void tfe_store(word16 io_address, byte var)
{
void tfe_store(word16 io_address, byte var) {
word16 reg_base;
word16 word_value;
assert( tfe );
@ -1786,8 +1763,7 @@ void tfe_store(word16 io_address, byte var)
/* ------------------------------------------------------------------------- */
/* resources support functions */
#if 0
static int set_tfe_disabled(int val, void *param)
{
static int set_tfe_disabled(int val, void *param) {
/* dummy function since we don't want "disabled" to be stored on disk */
return 0;
}
@ -1822,8 +1798,7 @@ static int set_tfe_disabled(int val, void *param)
return 0;
}*/
static int set_tfe_enabled(int val, void *param)
{
static int set_tfe_enabled(int val, void *param) {
if (!tfe_cannot_use) {
if (!val) {
/* TFE should be deactived */
@ -1850,8 +1825,7 @@ static int set_tfe_enabled(int val, void *param)
}
#endif /* 0 */
int set_tfe_interface(const char *name)
{
int set_tfe_interface(const char *name) {
if (tfe_interface != NULL && name != NULL
&& strcmp(name, tfe_interface) == 0)
return 0;
@ -1951,14 +1925,12 @@ static char snap_module_name[] = "TFE1764";
#define SNAP_MAJOR 0
#define SNAP_MINOR 0
int tfe_read_snapshot_module(struct snapshot_s *s)
{
int tfe_read_snapshot_module(struct snapshot_s *s) {
/* @SRT TODO: not yet implemented */
return -1;
}
int tfe_write_snapshot_module(struct snapshot_s *s)
{
int tfe_write_snapshot_module(struct snapshot_s *s) {
/* @SRT TODO: not yet implemented */
return -1;
}
@ -1968,8 +1940,7 @@ int tfe_write_snapshot_module(struct snapshot_s *s)
/* ------------------------------------------------------------------------- */
/* functions for selecting and querying available NICs */
int tfe_enumadapter_open(void)
{
int tfe_enumadapter_open(void) {
if (!tfe_arch_enumadapter_open()) {
tfe_cannot_use = 1;
return 0;
@ -1977,13 +1948,11 @@ int tfe_enumadapter_open(void)
return 1;
}
int tfe_enumadapter(char **ppname, char **ppdescription)
{
int tfe_enumadapter(char **ppname, char **ppdescription) {
return tfe_arch_enumadapter(ppname, ppdescription);
}
int tfe_enumadapter_close(void)
{
int tfe_enumadapter_close(void) {
return tfe_arch_enumadapter_close();
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@ -20,14 +20,14 @@
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v140</PlatformToolset>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">

View File

@ -60,8 +60,7 @@ static char TfePcapErrbuf[PCAP_ERRBUF_SIZE];
#ifdef TFE_DEBUG_PKTDUMP
static
void debug_output( const char *text, unsigned char *what, int count )
{
void debug_output( const char *text, unsigned char *what, int count ) {
char buffer[256];
char *p = buffer;
char *pbuffer1 = what;
@ -103,8 +102,7 @@ void debug_output( const char *text, unsigned char *what, int count )
TfeEnumAdapter() only fails if there is no more adpater; in this case,
* ppname and *ppdescription are not altered.
*/
int tfe_arch_enumadapter_open(void)
{
int tfe_arch_enumadapter_open(void) {
if (pcapdelay_findalldevs(&TfePcapAlldevs, TfePcapErrbuf) == -1)
{
#ifdef TFE_DEBUG_ARCH
@ -126,8 +124,7 @@ int tfe_arch_enumadapter_open(void)
return 1;
}
int tfe_arch_enumadapter(char **ppname, char **ppdescription)
{
int tfe_arch_enumadapter(char **ppname, char **ppdescription) {
if (!TfePcapNextDev || (TfePcapNextDev->name == NULL))
return 0;
@ -141,8 +138,7 @@ int tfe_arch_enumadapter(char **ppname, char **ppdescription)
return 1;
}
int tfe_arch_enumadapter_close(void)
{
int tfe_arch_enumadapter_close(void) {
if (TfePcapAlldevs) {
pcapdelay_freealldevs(TfePcapAlldevs);
TfePcapAlldevs = NULL;
@ -151,8 +147,7 @@ int tfe_arch_enumadapter_close(void)
}
static
int TfePcapOpenAdapter(const char *interface_name)
{
int TfePcapOpenAdapter(const char *interface_name) {
pcap_if_t *TfePcapDevice = NULL;
if (!tfe_enumadapter_open()) {
@ -221,29 +216,25 @@ int TfePcapOpenAdapter(const char *interface_name)
/* the architecture-dependend functions */
int tfe_arch_init(void)
{
int tfe_arch_init(void) {
//tfe_arch_log = log_open("TFEARCH");
return 1;
}
void tfe_arch_pre_reset( void )
{
void tfe_arch_pre_reset( void ) {
#ifdef TFE_DEBUG_ARCH
log_message( tfe_arch_log, "tfe_arch_pre_reset()." );
#endif
}
void tfe_arch_post_reset( void )
{
void tfe_arch_post_reset( void ) {
#ifdef TFE_DEBUG_ARCH
log_message( tfe_arch_log, "tfe_arch_post_reset()." );
#endif
}
int tfe_arch_activate(const char *interface_name)
{
int tfe_arch_activate(const char *interface_name) {
#ifdef TFE_DEBUG_ARCH
log_message( tfe_arch_log, "tfe_arch_activate()." );
#endif
@ -253,15 +244,13 @@ int tfe_arch_activate(const char *interface_name)
return 1;
}
void tfe_arch_deactivate( void )
{
void tfe_arch_deactivate( void ) {
#ifdef TFE_DEBUG_ARCH
log_message( tfe_arch_log, "tfe_arch_deactivate()." );
#endif
}
void tfe_arch_set_mac( const unsigned char mac[6] )
{
void tfe_arch_set_mac( const unsigned char mac[6] ) {
#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
log_message( tfe_arch_log, "New MAC address set: %02X:%02X:%02X:%02X:%02X:%02X.",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] );
@ -275,8 +264,7 @@ void tfe_arch_recv_ctl( int bBroadcast, /* broadcast */
int bCorrect, /* accept correct frames */
int bPromiscuous, /* promiscuous mode */
int bIAHash /* accept if IA passes the hash filter */
)
{
) {
#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
log_message( tfe_arch_log, "tfe_arch_recv_ctl() called with the following parameters:" );
log_message( tfe_arch_log, "\tbBroadcast = %s", bBroadcast ? "TRUE" : "FALSE" );
@ -288,8 +276,7 @@ void tfe_arch_recv_ctl( int bBroadcast, /* broadcast */
#endif
}
void tfe_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver )
{
void tfe_arch_line_ctl(int bEnableTransmitter, int bEnableReceiver ) {
#if defined(TFE_DEBUG_ARCH) || defined(TFE_DEBUG_FRAMES)
log_message( tfe_arch_log, "tfe_arch_line_ctl() called with the following parameters:" );
log_message( tfe_arch_log, "\tbEnableTransmitter = %s", bEnableTransmitter ? "TRUE" : "FALSE" );
@ -307,8 +294,7 @@ typedef struct TFE_PCAP_INTERNAL_tag {
/* Callback function invoked by libpcap for every incoming packet */
static
void TfePcapPacketHandler(unsigned char *param, const struct pcap_pkthdr *header, const unsigned char *pkt_data)
{
void TfePcapPacketHandler(unsigned char *param, const struct pcap_pkthdr *header, const unsigned char *pkt_data) {
TFE_PCAP_INTERNAL *pinternal = (TFE_PCAP_INTERNAL*)param;
/* determine the count of bytes which has been returned,
@ -331,8 +317,7 @@ void TfePcapPacketHandler(unsigned char *param, const struct pcap_pkthdr *header
At most 'len' bytes are copied.
*/
static
int tfe_arch_receive_frame(TFE_PCAP_INTERNAL *pinternal)
{
int tfe_arch_receive_frame(TFE_PCAP_INTERNAL *pinternal) {
int ret = -1;
/* check if there is something to receive */
@ -354,8 +339,7 @@ void tfe_arch_transmit(int force, /* FORCE: Delete waiting frames in trans
int tx_pad_dis, /* TXPADDIS: Disable padding to 60 Bytes */
int txlength, /* Frame length */
unsigned char *txframe /* Pointer to the frame to be transmitted */
)
{
) {
#ifdef TFE_DEBUG_ARCH
log_message( tfe_arch_log, "tfe_arch_transmit() called, with: "
"force = %s, onecoll = %s, inhibit_crc=%s, tx_pad_dis=%s, txlength=%u",
@ -412,8 +396,7 @@ int tfe_arch_receive(unsigned char *pbuffer , /* where to store a frame */
int *pcorrect_mac, /* set if dest. address is exactly our IA */
int *pbroadcast, /* set if dest. address is a broadcast address */
int *pcrc_error /* set if received frame had a CRC error */
)
{
) {
int len;
TFE_PCAP_INTERNAL internal = { *plen, pbuffer };

View File

@ -61,8 +61,7 @@
static unsigned long crc32_table[256];
static int crc32_is_initialized = 0;
void lib_free(void *ptr)
{
void lib_free(void *ptr) {
#ifdef LIB_DEBUG
lib_debug_free(ptr, 1, 1);
#endif
@ -74,18 +73,15 @@ void lib_free(void *ptr)
#endif
}
void *lib_malloc(size_t size)
{
void *lib_malloc(size_t size) {
#ifdef LIB_DEBUG
void *ptr = lib_debug_libc_malloc(size);
#else
void *ptr = malloc(size);
#endif
#ifndef __OS2__
if (ptr == NULL && size > 0)
exit(-1);
#endif
#ifdef LIB_DEBUG
lib_debug_alloc(ptr, size, 3);
#endif
@ -97,8 +93,7 @@ void *lib_malloc(size_t size)
/* Malloc enough space for `str', copy `str' into it and return its
address. */
char *lib_stralloc(const char *str)
{
char *lib_stralloc(const char *str) {
size_t size;
char *ptr;
@ -115,18 +110,15 @@ char *lib_stralloc(const char *str)
/* Like realloc, but abort if not enough memory is available. */
void *lib_realloc(void *ptr, size_t size)
{
void *lib_realloc(void *ptr, size_t size) {
#ifdef LIB_DEBUG
void *new_ptr = lib_debug_libc_realloc(ptr, size);
#else
void *new_ptr = realloc(ptr, size);
#endif
#ifndef __OS2__
if (new_ptr == NULL)
exit(-1);
#endif
#ifdef LIB_DEBUG
lib_debug_free(ptr, 1, 0);
lib_debug_alloc(new_ptr, size, 1);
@ -139,8 +131,7 @@ void *lib_realloc(void *ptr, size_t size)
/* Set a new value to the dynamically allocated string *str.
Returns `-1' if nothing has to be done. */
int util_string_set(char **str, const char *new_value)
{
int util_string_set(char **str, const char *new_value) {
if (*str == NULL) {
if (new_value != NULL)
*str = lib_stralloc(new_value);
@ -163,8 +154,7 @@ int util_string_set(char **str, const char *new_value)
// crc32 Stuff
unsigned long crc32_buf(const char *buffer, unsigned int len)
{
unsigned long crc32_buf(const char *buffer, unsigned int len) {
int i, j;
unsigned long crc, c;
const char *p;
@ -185,4 +175,3 @@ unsigned long crc32_buf(const char *buffer, unsigned int len)
return ~crc;
}

533
src/unix_host_common.c Normal file
View File

@ -0,0 +1,533 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
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
*/
#define _BSD_SOURCE
#include <ctype.h>
#include <dirent.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <time.h>
#if defined(__APPLE__)
#include <sys/xattr.h>
#include <sys/attr.h>
#include <sys/paths.h>
#endif
#ifdef __linux__
#include <sys/xattr.h>
#endif
#if defined(__FreeBSD__)
#include <sys/types.h>
#include <sys/extattr.h>
#endif
#if defined(_AIX)
#include <sys/ea.h>
#endif
#ifndef XATTR_FINDERINFO_NAME
#define XATTR_FINDERINFO_NAME "com.apple.FinderInfo"
#endif
#ifndef XATTR_RESOURCEFORK_NAME
#define XATTR_RESOURCEFORK_NAME "com.apple.ResourceFork"
#endif
#include "defc.h"
#include "gsos.h"
#include "host_common.h"
static ino_t root_ino = 0;
static dev_t root_dev = 0;
unsigned host_startup(void) {
struct stat st;
if (!g_cfg_host_path) return invalidFSTop;
if (!*g_cfg_host_path) return invalidFSTop;
if (host_root) free(host_root);
host_root = strdup(g_cfg_host_path);
if (stat(host_root, &st) < 0) {
fprintf(stderr, "%s does not exist\n", host_root);
return invalidFSTop;
}
if (!S_ISDIR(st.st_mode)) {
fprintf(stderr, "%s is not a directory\n", host_root);
return invalidFSTop;
}
root_ino = st.st_ino;
root_dev = st.st_dev;
return 0;
}
void host_shutdown(void) {
if (host_root) free(host_root);
host_root = NULL;
root_ino = 0;
root_dev = 0;
}
int host_is_root(struct stat *st) {
return st->st_ino == root_ino && st->st_dev == root_dev;
}
/*
* Date/time conversion
*/
/*
* converts time_t to a gs/os readhextime date/time record.
*/
void host_set_date_time_rec(word32 ptr, time_t time) {
if (time == 0) {
for (int i = 0; i < 8; ++i) set_memory_c(ptr++, 0, 0);
return;
}
struct tm *tm = localtime(&time);
if (tm->tm_sec == 60) tm->tm_sec = 59; /* leap second */
set_memory_c(ptr++, tm->tm_sec, 0);
set_memory_c(ptr++, tm->tm_min, 0);
set_memory_c(ptr++, tm->tm_hour, 0);
set_memory_c(ptr++, tm->tm_year, 0);
set_memory_c(ptr++, tm->tm_mday - 1, 0);
set_memory_c(ptr++, tm->tm_mon, 0);
set_memory_c(ptr++, 0, 0);
set_memory_c(ptr++, tm->tm_wday + 1, 0);
}
/*
* converts time_t to a prodos16 date/time record.
*/
void host_set_date_time(word32 ptr, time_t time) {
if (time == 0) {
for (int i = 0; i < 4; ++i) set_memory_c(ptr++, 0, 0);
return;
}
struct tm *tm = localtime(&time);
word16 tmp = 0;
tmp |= (tm->tm_year % 100) << 9;
tmp |= tm->tm_mon << 5;
tmp |= tm->tm_mday;
set_memory16_c(ptr, tmp, 0);
ptr += 2;
tmp = 0;
tmp |= tm->tm_hour << 8;
tmp |= tm->tm_min;
set_memory16_c(ptr, tmp, 0);
}
word32 host_convert_date_time(time_t time) {
if (time == 0) return 0;
struct tm *tm = localtime(&time);
word16 dd = 0;
dd |= (tm->tm_year % 100) << 9;
dd |= tm->tm_mon << 5;
dd |= tm->tm_mday;
word16 tt = 0;
tt |= tm->tm_hour << 8;
tt |= tm->tm_min;
return (tt << 16) | dd;
}
time_t host_get_date_time(word32 ptr) {
word16 a = get_memory16_c(ptr + 0, 0);
word16 b = get_memory16_c(ptr + 2, 0);
if (!a && !b) return 0;
struct tm tm;
memset(&tm, 0, sizeof(tm));
tm.tm_year = (a >> 9) & 0x7f;
tm.tm_mon = ((a >> 5) & 0x0f) - 1;
tm.tm_mday = (a >> 0) & 0x1f;
tm.tm_hour = (b >> 8) & 0x1f;
tm.tm_min = (b >> 0) & 0x3f;
tm.tm_sec = 0;
tm.tm_isdst = -1;
// 00 - 39 => 2000-2039
// 40 - 99 => 1940-1999
if (tm.tm_year < 40) tm.tm_year += 100;
return mktime(&tm);
}
time_t host_get_date_time_rec(word32 ptr) {
byte buffer[8];
for (int i = 0; i < 8; ++i) buffer[i] = get_memory_c(ptr++, 0);
if (!memcmp(buffer, "\x00\x00\x00\x00\x00\x00\x00\x00", 8)) return 0;
struct tm tm;
memset(&tm, 0, sizeof(tm));
tm.tm_sec = buffer[0];
tm.tm_min = buffer[1];
tm.tm_hour = buffer[2];
tm.tm_year = buffer[3];
tm.tm_mday = buffer[4] + 1;
tm.tm_mon = buffer[5];
tm.tm_isdst = -1;
return mktime(&tm);
}
#if defined(__APPLE__)
void host_get_file_xinfo(const char *path, struct file_info *fi) {
ssize_t tmp;
tmp = getxattr(path, XATTR_RESOURCEFORK_NAME, NULL, 0, 0, 0);
if (tmp < 0) tmp = 0;
fi->resource_eof = tmp;
fi->resource_blocks = (tmp + 511) / 512;
tmp = getxattr(path, XATTR_FINDERINFO_NAME, fi->finder_info, 32, 0, 0);
if (tmp == 16 || tmp == 32) {
fi->has_fi = 1;
host_finder_info_to_filetype(fi->finder_info, &fi->file_type, &fi->aux_type);
}
}
#elif defined(__sun)
void host_get_file_xinfo(const char *path, struct file_info *fi) {
struct stat st;
// can't stat an xattr directly?
int fd;
fd = attropen(path, XATTR_RESOURCEFORK_NAME, O_RDONLY);
if (fd >= 0) {
if (fstat(fd, &st) == 0) {
fi->resource_eof = st.st_size;
fi->resource_blocks = st.st_blocks;
}
close(fd);
}
fd = attropen(path, XATTR_FINDERINFO_NAME, O_RDONLY);
if (fd >= 0) {
int tmp = read(fd, fi->finder_info, 32);
if (tmp == 16 || tmp == 32) {
fi->has_fi = 1;
host_finder_info_to_filetype(fi->finder_info, &fi->file_type, &fi->aux_type);
}
close(fd);
}
}
#elif defined(__linux__)
void host_get_file_xinfo(const char *path, struct file_info *fi) {
ssize_t tmp;
tmp = getxattr(path, "user.com.apple.ResourceFork", NULL, 0);
if (tmp < 0) tmp = 0;
fi->resource_eof = tmp;
fi->resource_blocks = (tmp + 511) / 512;
tmp = getxattr(path, "user.com.apple.FinderInfo", fi->finder_info, 32);
if (tmp == 16 || tmp == 32) {
fi->has_fi = 1;
host_finder_info_to_filetype(fi->finder_info, &fi->file_type, &fi->aux_type);
}
}
#else
void host_get_file_xinfo(const char *path, struct file_info *fi) {
}
#endif
word32 host_get_file_info(const char *path, struct file_info *fi) {
struct stat st;
memset(fi, 0, sizeof(*fi));
int ok = stat(path, &st);
if (ok < 0) return host_map_errno(errno);
fi->eof = st.st_size;
fi->blocks = st.st_blocks;
fi->create_date = st.st_ctime;
fi->modified_date = st.st_mtime;
#if defined(__APPLE__)
fi->create_date = st.st_birthtime;
#endif
if (S_ISDIR(st.st_mode)) {
fi->storage_type = directoryFile;
fi->file_type = 0x0f;
if (host_is_root(&st))
fi->storage_type = 0x0f;
} else if (S_ISREG(st.st_mode)) {
fi->file_type = 0x06;
if (st.st_size < 0x200) fi->storage_type = seedling;
else if (st.st_size < 0x20000) fi->storage_type = sapling;
else fi->storage_type = tree;
} else {
fi->storage_type = st.st_mode & S_IFMT;
fi->file_type = 0;
}
// 0x01 = read enable
// 0x02 = write enable
// 0x04 = invisible
// 0x08 = reserved
// 0x10 = reserved
// 0x20 = backup needed
// 0x40 = rename enable
// 0x80 = destroy enable
fi->access = 0xc3; // placeholder...
if (S_ISREG(st.st_mode)) {
host_get_file_xinfo(path, fi);
if (!fi->has_fi) {
host_synthesize_file_xinfo(path, fi);
}
}
// get file type/aux type
if (fi->resource_eof) fi->storage_type = extendedFile;
return 0;
}
#if defined(__APPLE__)
word32 host_set_file_info(const char *path, struct file_info *fi) {
int ok;
struct attrlist list;
unsigned i = 0;
struct timespec dates[2];
if (fi->has_fi && fi->storage_type != 0x0d) {
ok = setxattr(path, XATTR_FINDERINFO_NAME, fi->finder_info, 32, 0, 0);
if (ok < 0) return host_map_errno(errno);
}
memset(&list, 0, sizeof(list));
memset(dates, 0, sizeof(dates));
list.bitmapcount = ATTR_BIT_MAP_COUNT;
list.commonattr = 0;
if (fi->create_date)
{
dates[i++].tv_sec = fi->create_date;
list.commonattr |= ATTR_CMN_CRTIME;
}
if (fi->modified_date)
{
dates[i++].tv_sec = fi->modified_date;
list.commonattr |= ATTR_CMN_MODTIME;
}
ok = 0;
if (i) ok = setattrlist(path, &list, dates, i * sizeof(struct timespec), 0);
return 0;
}
#elif defined(__sun)
word32 host_set_file_info(const char *path, struct file_info *fi) {
if (fi->has_fi && fi->storage_type != 0x0d) {
int fd = attropen(path, XATTR_FINDERINFO_NAME, O_WRONLY | O_CREAT, 0666);
if (fd < 0) return host_map_errno(errno);
write(fd, fi->finder_info, 32);
close(fd);
}
if (fi->modified_date) {
struct timeval times[2];
memset(times, 0, sizeof(times));
//times[0] = 0; // access
times[1].tv_sec = fi.modified_date; // modified
int ok = utimes(path, times);
if (ok < 0) return host_map_errno(errno);
}
return 0;
}
#elif defined(__linux__)
word32 host_set_file_info(const char *path, struct file_info *fi) {
if (fi->has_fi && fi->storage_type != 0x0d) {
int ok = setxattr(path, "user.apple.FinderInfo", fi->finder_info, 32, 0);
if (ok < 0) return host_map_errno(errno);
}
if (fi->modified_date) {
struct timeval times[2];
memset(times, 0, sizeof(times));
//times[0] = 0; // access
times[1].tv_sec = fi->modified_date; // modified
int ok = utimes(path, times);
if (ok < 0) return host_map_errno(errno);
}
return 0;
}
#else
word32 host_set_file_info(const char *path, struct file_info *fi) {
if (fi->modified_date) {
struct timeval times[2];
memset(times, 0, sizeof(times));
times[0] = 0; // access
times[1].tv_sec = fi->modified_date; // modified
int ok = utimes(path, times);
if (ok < 0) return host_map_errno(errno);
}
return 0;
}
#endif
static int qsort_callback(const void *a, const void *b) {
return strcasecmp(*(const char **)a, *(const char **)b);
}
unsigned host_scan_directory(const char *path, char ***out, size_t *entries, unsigned p8) {
DIR *dp;
char **data = NULL;
size_t capacity = 0;
size_t count = 0;
dp = opendir(path);
if (!dp) return host_map_errno_path(errno, path);
for(;;) {
struct dirent *d = readdir(dp);
if (!d) break;
const char *name = d->d_name;
if (name[0] == 0) continue;
if (name[0] == '.') continue;
if (p8) {
int ok = 1;
int n = strlen(name);
if (n > 15) continue;
/* check for invalid characters? */
for (int i = 0; i < n; ++i) {
unsigned char c = name[i];
if (isalpha(c) || isdigit(c) || c == '.') continue;
ok = 0;
break;
}
if (!ok) continue;
}
if (count == capacity) {
char **tmp;
tmp = realloc(data, (capacity + 100) * sizeof(char *));
if (!tmp) {
closedir(dp);
host_free_directory(data, count);
return outOfMem;
}
data = tmp;
for (int i = count; i < capacity; ++i) data[i] = 0;
capacity += 100;
}
data[count++] = strdup(name);
}
closedir(dp);
qsort(data, count, sizeof(char *), qsort_callback);
*entries = count;
*out = data;
return 0;
}
unsigned host_storage_type(const char *path, word16 *error) {
struct stat st;
if (!path) {
*error = badPathSyntax;
return 0;
}
if (stat(path, &st) < 0) {
*error = host_map_errno_path(errno, path);
return 0;
}
if (S_ISREG(st.st_mode)) {
return host_is_root(&st) ? 0x0f : directoryFile;
}
if (S_ISDIR(st.st_mode)) return standardFile;
*error = badStoreType;
return 0;
}

21
src/vars_osx_sdl2 Normal file
View File

@ -0,0 +1,21 @@
TARGET = gsport
NAME = gsport
PERL = perl
CC = clang
LD = clang++
AS = cc
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o fix_mac_menu.o
ARCHS = ppc, i386, ppc64, x86_64
# OPTIONS FOR COMPILING C SOURCE
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_ICON -DHAVE_SDL `sdl2-config --cflags`
# OPTIONS FOR COMPILING C++ SOURCE
CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL `freetype-config --cflags` `sdl2-config --cflags`
EXTRA_LIBS = -lSDL2_image
OPTS = -DGSPORT_LITTLE_ENDIAN
SUFFIX =
LDFLAGS = `sdl2-config --static-libs` `freetype-config --libs` -framework Cocoa
LDOPTS =
EXTRA_SPECIALS =

20
src/vars_osx_x11 Normal file
View File

@ -0,0 +1,20 @@
TARGET = gsportx
NAME = gsportx
PERL = perl
CC = clang
LD = g++
AS = cc
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) xdriver.o
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_SDL -DTOGGLE_STATUS -I/usr/local/include/SDL2 -I/usr/local/include/freetype2 -L/usr/X11/lib
CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -I/usr/local/include/freetype2 -I/usr/local/include/SDL2
OPTS = -DGSPORT_LITTLE_ENDIAN
SUFFIX =
LDFLAGS =
LDOPTS =
EXTRA_LIBS = -lX11 -lfreetype -lSDL2 -lpcap -lXext
EXTRA_SPECIALS =
XOPTS = -I/usr/X11/include

18
src/vars_rpilinux_fb Normal file
View File

@ -0,0 +1,18 @@
TARGET = gsportfb
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) fbdriver.o
CC = gcc
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=armv6
OPTS = -DGSPORT_LITTLE_ENDIAN -DHAVE_TFE -DHAVE_ATBRIDGE
SUFFIX =
NAME = gsportfb
LDFLAGS =
LDOPTS =
LD = g++
EXTRA_LIBS = -ldl
EXTRA_SPECIALS =
AS = cc
PERL = perl
XOPTS = -I/usr/X11R6/include

16
src/vars_rpilinux_sdl2 Normal file
View File

@ -0,0 +1,16 @@
TARGET = gsport
NAME = gsport
PERL = perl
CC = gcc
LD = g++
#LD = gcc
AS = cc
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=armv6
OPTS = -DGSPORT_LITTLE_ENDIAN -DHAVE_TFE -DHAVE_ATBRIDGE -DHAVE_SDL -I/usr/include/SDL2 -I/usr/include/freetype2
EXTRA_LIBS = -ldl -lfreetype -lSDL2 -lSDL2_image
XOPTS = -I/usr/X11R6/include

View File

@ -1,9 +1,13 @@
TARGET = gsport.exe
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) scc_windriver.o win32snd_driver.o win_console.o win_generic.o gsport32.o
TARGET = gsport32.exe
FSTOBJ = host_common.o win32_host_common.o host_mli.o win32_host_fst.o
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) scc_windriver.o win32snd_driver.o win_console.o win_generic.o gsport32.o
CCOPTS = -O2 -DGSPORT_LITTLE_ENDIAN -DHAVE_TFE -DWIN_SOUND -DTOGGLE_STATUS -DWIN32 -D_WIN32 -D__USE_W32_SOCKETS -D_WINSOCK2API_ -std=gnu99 -DHAVE_ATBRIDGE
CPPOPTS = -O2 -DGSPORT_LITTLE_ENDIAN -DHAVE_TFE -DTOGGLE_STATUS -DWIN32 -D_WIN32 -D__USE_W32_SOCKETS -D_WINSOCK2API_ -DHAVE_ATBRIDGE
SUFFIX = ".exe"
NAME = gsport
NAME = gsport32
EXTRA_LIBS = -Larch/win32 -lcomdlg32 -lShlwapi -lIPHlpApi
XOPTS = -Wall -fomit-frame-pointer -march=i686

View File

@ -1,11 +1,18 @@
TARGET = gsport.exe
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) scc_windriver.o win32snd_driver.o win_console.o win_generic.o gsport32.o
CCOPTS = -O2 -DGSPORT_LITTLE_ENDIAN -DHAVE_TFE -DWIN_SOUND -DHAVE_SDL -DTOGGLE_STATUS -DWIN32 -D_WIN32 -D__USE_W32_SOCKETS -D_WINSOCK2API_ -std=gnu99 -DHAVE_ATBRIDGE
CPPOPTS = -O2 -DGSPORT_LITTLE_ENDIAN -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -DWIN32 -D_WIN32 -D__USE_W32_SOCKETS -D_WINSOCK2API_ -DHAVE_ATBRIDGE -I /usr/include/freetype2 -I/usr/include/SDL
NAME = gsport
FSTOBJ = win32_host_fst.o
OBJECTS = sdl2_driver.o $(OBJECTS1) $(FSTOBJ) sdl2snd_driver.o
CCOPTS = -O2 -DGSPORT_LITTLE_ENDIAN -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I/usr/include/SDL2 -L/cygdrive/c/mingw/lib -I/cygdrive/c/mingw/include/SDL2/
CPPOPTS = -O2 -DGSPORT_LITTLE_ENDIAN -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I/usr/include/freetype2 -L/cygdrive/c/mingw/lib -I/cygdrive/c/mingw/include/SDL2/
SUFFIX = ".exe"
NAME = gsport
EXTRA_LIBS = -Larch/win32 -lSDL -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi
EXTRA_LIBS = -Larch/win32 -lSDL2main -lSDL2 -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -lcygwin
EXTRA_LIBS = -L/usr/local/lib -lcygwin -lSDL2main -lSDL2 -mwindows -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -L/usr/lib -lpthread -lSDL2_image -L/cygdrive/c/mingw/lib -I/cygdrive/c/mingw/include/SDL2/
XOPTS = -Wall -fomit-frame-pointer -march=i686
XLIBS =

21
src/vars_win32_sdl2 Normal file
View File

@ -0,0 +1,21 @@
TARGET = gsport.exe
NAME = gsport
MINGW_HOME = /cygdrive/c/mingw/i686-w64-mingw32
FSTOBJ = host_common.o win32_host_common.o host_mli.o win32_host_fst.o
OBJECTS = sdl2_driver.o $(OBJECTS1) $(FSTOBJ) sdl2snd_driver.o scc_windriver.o
CCOPTS = -O3 -DGSPORT_LITTLE_ENDIAN -DWIN32 -D_WIN32 -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I$(MINGW_HOME)/include/SDL2 -DWINSDL_BORDERHACK -D__USE_W32_SOCKETS -D_WINSOCK2API_
CPPOPTS = -O3 -DGSPORT_LITTLE_ENDIAN -DWIN32 -D_WIN32 -DHAVE_SDL -DWIN_SDL -DTOGGLE_STATUS -I/usr/include/freetype2 -I$(MINGW_HOME)/include/SDL2 -D__USE_W32_SOCKETS -D_WINSOCK2API_
SUFFIX = ".exe"
# working in cygwin
EXTRA_LIBS = -lcygwin -lSDL2main -lSDL2 -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -lpthread -lSDL2_image -L$(MINGW_HOME)/lib/
EXTRA_LIBS = -lcygwin -lSDL2main -lSDL2 -lfreetype -lcomdlg32 -lShlwapi -lIPHlpApi -lpthread -lSDL2_image -L$(MINGW_HOME)/lib/ -Larch/win32 -lshell32
#XOPTS = -Wall -fomit-frame-pointer -march=i686
XLIBS =

View File

@ -1,18 +1,24 @@
TARGET = gsportx
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) xdriver.o
TARGET = gsport
NAME = gsport
PERL = perl
CC = gcc
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=i686 -DHAVE_SDL -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -I/usr/include/SDL -I/usr/include/freetype2
CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -DHAVE_ATBRIDGE -I/usr/include/freetype2 -I/usr/include/SDL
LD = g++
AS = cc
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o
# C Compiler Options
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_SDL -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -I/usr/include/SDL2 -I/usr/include/freetype2
# C++ Compiler Options
CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -DHAVE_ATBRIDGE -I/usr/include/freetype2 -I/usr/include/SDL2
EXTRA_LIBS = -lfreetype -lSDL2 -lSDL2_image -ldl
OPTS = -DGSPORT_LITTLE_ENDIAN
SUFFIX =
NAME = gsportx
LDFLAGS =
LDOPTS =
LD = g++
EXTRA_LIBS = -lXext -lfreetype -lSDL
EXTRA_SPECIALS =
AS = cc
PERL = perl
XOPTS = -I/usr/X11R6/include

21
src/vars_x86linux_sdl2 Normal file
View File

@ -0,0 +1,21 @@
TARGET = gsport
NAME = gsport
PERL = perl
CC = gcc
LD = gcc
AS = cc
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) sdl2_driver.o sdl2snd_driver.o
# C Compiler Options
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_SDL -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS -I/usr/include/SDL2 -I/usr/include/freetype2
# C++ Compiler Options
CPPOPTS = -O2 -DHAVE_TFE -DHAVE_SDL -DTOGGLE_STATUS -DHAVE_ATBRIDGE -I/usr/include/freetype2 -I/usr/include/SDL2
EXTRA_LIBS = -lfreetype -lSDL2 -lSDL2_image -ldl -lm -lstdc++
OPTS = -DGSPORT_LITTLE_ENDIAN
SUFFIX =
LDFLAGS =
LDOPTS = -I.
EXTRA_SPECIALS =

21
src/vars_x86linux_x11 Normal file
View File

@ -0,0 +1,21 @@
TARGET = gsportx
NAME = gsportx
PERL = perl
CC = gcc
LD = g++
AS = cc
OBJECTS = $(OBJECTS1) $(TFEOBJ) $(ATOBJ) $(PCAPOBJ) $(FSTOBJ) xdriver.o
#-march=i686 is causing "error: CPU you selected does not support x86-64 instruction set" on ubuntu
#CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -march=i686 -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS
CCOPTS = -O2 -Wall -fomit-frame-pointer -std=gnu99 -DHAVE_TFE -DHAVE_ATBRIDGE -DTOGGLE_STATUS
OPTS = -DGSPORT_LITTLE_ENDIAN
SUFFIX =
LDFLAGS =
LDOPTS =
# added -ldl for ubuntu
EXTRA_LIBS = -lXext -ldl
EXTRA_SPECIALS =
XOPTS = -I/usr/X11R6/include

View File

@ -1,6 +1,6 @@
TARGET = gsportx
OBJECTS = $(OBJECTS1) xdriver.o
OBJECTS = $(OBJECTS1) $(FSTOBJ) xdriver.o
CC = gcc
CCOPTS = -O
OPTS = -DNDEBUG -DSOLARIS -DGSPORT_LITTLE_ENDIAN -DSOLARISSOUND

View File

@ -1,6 +1,7 @@
/*
GSport - an Apple //gs Emulator
Copyright (C) 2010 - 2012 by GSport contributors
Copyright (C) 2010 - 2019 by GSport contributors
Copyright (C) 2016 - 2018 Dagen Brock
Based on the KEGS emulator written by and Copyright (C) 2003 Kent Dickey
@ -22,6 +23,7 @@
#include <time.h>
#include "defc.h"
#include "glog.h"
extern int Verbose;
@ -102,6 +104,17 @@ int g_border_last_vbl_changes = 0;
int g_use_dhr140 = 0;
int g_use_bw_hires = 0;
int g_startx = WINDOWPOS_UNDEFINED;
int g_starty = WINDOWPOS_UNDEFINED;
int g_startw = BASE_WINDOW_WIDTH;
int g_starth = X_A2_WINDOW_HEIGHT;
int g_highdpi = 0;
int g_borderless = 0;
int g_resizeable = 0;
int g_noaspect = 0;
int g_novsync = 0;
int g_nohwaccel = 0;
int g_fullscreen_desktop = 0;
int g_a2_new_all_stat[200];
int g_a2_cur_all_stat[200];
@ -334,9 +347,7 @@ const word32 g_hires_convert[64] = {
};
void
video_init()
{
void video_init() {
word32 col[4];
Kimage *kimage_ptr;
word32 *ptr;
@ -547,9 +558,7 @@ video_init()
fflush(stdout);
}
void
show_a2_line_stuff()
{
void show_a2_line_stuff() {
int i;
for(i = 0; i < 200; i++) {
@ -571,9 +580,7 @@ show_a2_line_stuff()
int g_flash_count = 0;
void
video_reset()
{
void video_reset() {
int stat;
int i;
@ -606,8 +613,7 @@ word32 g_cycs_in_check_input = 0;
int g_needfullrefreshfornextframe = 1;
void video_update()
{
void video_update() {
int did_video;
// OG g_needfullrefreshfornextframe
@ -653,20 +659,10 @@ void video_update()
video_update_through_line(0);
}
// OG Notify host that video has been uodated
#if defined(ACTIVEGSPLUGIN) && defined(MAC)
{
extern void x_need2refresh();
x_need2refresh();
}
#endif
}
int
video_all_stat_to_line_stat(int line, int new_all_stat)
{
int video_all_stat_to_line_stat(int line, int new_all_stat) {
int page, color, dbl;
int st80, hires, annunc3, mix_t_gr;
int altchar, text_color, bg_color, flash_state;
@ -724,9 +720,7 @@ video_all_stat_to_line_stat(int line, int new_all_stat)
(color << 1) + dbl);
}
int *
video_update_kimage_ptr(int line, int new_stat)
{
int *video_update_kimage_ptr(int line, int new_stat) {
Kimage *kimage_ptr;
int *mode_ptr;
int page;
@ -770,9 +764,7 @@ video_update_kimage_ptr(int line, int new_stat)
return mode_ptr;
}
void
change_a2vid_palette(int new_palette)
{
void change_a2vid_palette(int new_palette) {
int i;
for(i = 0; i < 200; i++) {
@ -804,9 +796,7 @@ change_a2vid_palette(int new_palette)
int g_num_a2vid_palette_checks = 1;
int g_shr_palette_used[16];
void
check_a2vid_palette()
{
void check_a2vid_palette() {
int sum;
int min;
int val;
@ -845,9 +835,7 @@ check_a2vid_palette()
}
}
void
change_display_mode(double dcycs)
{
void change_display_mode(double dcycs) {
int line, tmp_line;
line = ((get_lines_since_vbl(dcycs) + 0xff) >> 8);
@ -865,9 +853,7 @@ change_display_mode(double dcycs)
/* otherwise, g_cur_a2_stat is covered at the end of vbl */
}
void
video_update_all_stat_through_line(int line)
{
void video_update_all_stat_through_line(int line) {
int start_line;
int prev_stat;
int max_line;
@ -897,9 +883,7 @@ int g_border_color = 0; // OG Expose border color
Border_changes g_border_changes[MAX_BORDER_CHANGES];
int g_num_border_changes = 0;
void
change_border_color(double dcycs, int val)
{
void change_border_color(double dcycs, int val) {
int pos;
g_border_color = val; // OG Expose border color
@ -919,9 +903,7 @@ change_border_color(double dcycs, int val)
extern int first;
void
update_border_info()
{
void update_border_info() {
double dlines_per_dcyc;
double dcycs, dline, dcyc_line_start;
int offset;
@ -1008,9 +990,7 @@ update_border_info()
g_vbl_border_color = (g_c034_val & 0xf);
}
void
update_border_line(int st_line_offset, int end_line_offset, int color)
{
void update_border_line(int st_line_offset, int end_line_offset, int color) {
word32 val;
int st_offset, end_offset;
int left, right;
@ -1109,10 +1089,8 @@ update_border_line(int st_line_offset, int end_line_offset, int color)
}
}
void
video_border_pixel_write(Kimage *kimage_ptr, int starty, int num_lines,
word32 val, int st_off, int end_off)
{
void video_border_pixel_write(Kimage *kimage_ptr, int starty, int num_lines,
word32 val, int st_off, int end_off) {
word32 *ptr;
int width;
int width_act;
@ -1183,11 +1161,9 @@ video_border_pixel_write(Kimage *kimage_ptr, int starty, int num_lines,
continue; \
}
void
redraw_changed_text_40(int start_offset, int start_line, int num_lines,
void redraw_changed_text_40(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int altcharset, int bg_val, int fg_val,
int pixels_per_line)
{
int pixels_per_line) {
register word32 start_time, end_time;
word32 *img_ptr, *img_ptr2;
word32 *save_img_ptr, *save_img_ptr2;
@ -1362,11 +1338,9 @@ redraw_changed_text_40(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
void
redraw_changed_text_80(int start_offset, int start_line, int num_lines,
void redraw_changed_text_80(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int altcharset, int bg_val, int fg_val,
int pixels_per_line)
{
int pixels_per_line) {
const word32 *font_ptr0, *font_ptr1, *font_ptr2, *font_ptr3;
word32 *ch_ptr;
word32 *img_ptr, *img_ptr2;
@ -1553,10 +1527,8 @@ redraw_changed_text_80(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
void
redraw_changed_gr(int start_offset, int start_line, int num_lines, int reparse,
byte *screen_data, int pixels_per_line)
{
void redraw_changed_gr(int start_offset, int start_line, int num_lines, int reparse,
byte *screen_data, int pixels_per_line) {
word32 *img_ptr;
word32 *save_img_ptr;
word32 *ch_ptr;
@ -1678,10 +1650,8 @@ redraw_changed_gr(int start_offset, int start_line, int num_lines, int reparse,
g_need_redraw = 0;
}
void
redraw_changed_dbl_gr(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_dbl_gr(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line) {
word32 *img_ptr;
word32 *save_img_ptr;
word32 *ch_ptr;
@ -1822,10 +1792,8 @@ redraw_changed_dbl_gr(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
void
redraw_changed_hires(int start_offset, int start_line, int num_lines,
int color, int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_hires(int start_offset, int start_line, int num_lines,
int color, int reparse, byte *screen_data, int pixels_per_line) {
if(!color) {
redraw_changed_hires_color(start_offset, start_line, num_lines,
reparse, screen_data, pixels_per_line);
@ -1835,10 +1803,8 @@ redraw_changed_hires(int start_offset, int start_line, int num_lines,
}
}
void
redraw_changed_hires_bw(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_hires_bw(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line) {
word32 *img_ptr, *img_ptr2;
word32 *ch_ptr;
byte *b_ptr;
@ -1953,10 +1919,8 @@ redraw_changed_hires_bw(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
void
redraw_changed_hires_color(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_hires_color(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line) {
word32 *img_ptr, *img_ptr2;
word32 *ch_ptr;
byte *b_ptr;
@ -2091,10 +2055,8 @@ redraw_changed_hires_color(int start_offset, int start_line, int num_lines,
}
void
redraw_changed_dbl_hires(int start_offset, int start_line, int num_lines,
int color, int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_dbl_hires(int start_offset, int start_line, int num_lines,
int color, int reparse, byte *screen_data, int pixels_per_line) {
if(!color) {
redraw_changed_dbl_hires_color(start_offset, start_line,
num_lines, reparse, screen_data, pixels_per_line);
@ -2105,10 +2067,8 @@ redraw_changed_dbl_hires(int start_offset, int start_line, int num_lines,
}
void
redraw_changed_dbl_hires_bw(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_dbl_hires_bw(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line) {
word32 *img_ptr, *img_ptr2;
word32 *ch_ptr;
byte *b_ptr;
@ -2225,10 +2185,8 @@ redraw_changed_dbl_hires_bw(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
void
redraw_changed_dbl_hires_color(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line)
{
void redraw_changed_dbl_hires_color(int start_offset, int start_line, int num_lines,
int reparse, byte *screen_data, int pixels_per_line) {
word32 *ch_ptr;
word32 *img_ptr, *img_ptr2;
byte *slow_mem_ptr;
@ -2359,9 +2317,7 @@ redraw_changed_dbl_hires_color(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
int
video_rebuild_super_hires_palette(word32 scan_info, int line, int reparse)
{
int video_rebuild_super_hires_palette(word32 scan_info, int line, int reparse) {
word32 *word_ptr;
word32 *ch_ptr;
byte *byte_ptr;
@ -2539,10 +2495,8 @@ video_rebuild_super_hires_palette(word32 scan_info, int line, int reparse)
void
redraw_changed_super_hires(int start_offset, int start_line, int num_lines,
int in_reparse, byte *screen_data)
{
void redraw_changed_super_hires(int start_offset, int start_line, int num_lines,
int in_reparse, byte *screen_data) {
word32 *ch_ptr;
word32 mask_per_line;
word32 all_checks;
@ -2739,15 +2693,11 @@ redraw_changed_super_hires(int start_offset, int start_line, int num_lines,
g_need_redraw = 0;
}
void
display_screen()
{
void display_screen() {
video_update_through_line(262);
}
void
video_update_event_line(int line)
{
void video_update_event_line(int line) {
int new_line;
video_update_through_line(line);
@ -2771,9 +2721,7 @@ video_update_event_line(int line)
}
}
void
video_check_input_events()
{
void video_check_input_events() {
word32 start_time, end_time;
g_video_dcycs_check_input = g_cur_dcycs + 4000.0;
@ -2785,9 +2733,7 @@ video_check_input_events()
g_cycs_in_check_input += (end_time - start_time);
}
void
video_update_through_line(int line)
{
void video_update_through_line(int line) {
register word32 start_time;
register word32 end_time;
int *mode_ptr;
@ -2899,9 +2845,7 @@ video_update_through_line(int line)
}
}
void
video_refresh_lines(int st_line, int num_lines, int must_reparse)
{
void video_refresh_lines(int st_line, int num_lines, int must_reparse) {
byte *ptr;
int line;
int stat;
@ -2998,19 +2942,15 @@ video_refresh_lines(int st_line, int num_lines, int must_reparse)
}
}
void
refresh_border()
{
void refresh_border() {
/**ZZZZ***/
}
// OG Added video_release_kimages proto
void video_release_kimages();
void
end_screen()
{
printf("In end_screen\n");
void end_screen() {
glog("Shutting down display");
// OG Free up allocated images
video_release_kimages();
@ -3021,9 +2961,7 @@ byte g_font_array[256][8] = {
#include "gsportfont.h"
};
void
read_a2_font()
{
void read_a2_font() {
byte *f40_e_ptr;
byte *f40_o_ptr;
byte *f80_0_ptr, *f80_1_ptr, *f80_2_ptr, *f80_3_ptr;
@ -3084,9 +3022,7 @@ read_a2_font()
/* Helper routine for the *driver.c files */
void
video_get_kimage(Kimage *kimage_ptr, int extend_info, int depth, int mdepth)
{
void video_get_kimage(Kimage *kimage_ptr, int extend_info, int depth, int mdepth) {
int width;
int height;
@ -3116,9 +3052,7 @@ video_get_kimage(Kimage *kimage_ptr, int extend_info, int depth, int mdepth)
x_get_kimage(kimage_ptr);
}
void
video_get_kimages()
{
void video_get_kimages() {
video_get_kimage(&g_kimage_text[0], 0, 8, 8);
video_get_kimage(&g_kimage_text[1], 0, 8, 8);
video_get_kimage(&g_kimage_hires[0], 0, 8, 8);
@ -3132,8 +3066,7 @@ video_get_kimages()
}
// OG Added video_release_kimages (to match video_get_kimages)
void video_release_kimages()
{
void video_release_kimages() {
extern void x_release_kimage(Kimage *kimage_ptr);
x_release_kimage(&g_kimage_text[0]);
@ -3146,10 +3079,8 @@ void video_release_kimages()
}
void
video_convert_kimage_depth(Kimage *kim_in, Kimage *kim_out, int startx,
int starty, int width, int height)
{
void video_convert_kimage_depth(Kimage *kim_in, Kimage *kim_out, int startx,
int starty, int width, int height) {
byte *indata, *inptr;
word32 *outdata32, *outptr32;
word16 *outdata16, *outptr16;
@ -3201,10 +3132,8 @@ video_convert_kimage_depth(Kimage *kim_in, Kimage *kim_out, int startx,
}
}
void
video_push_lines(Kimage *kimage_ptr, int start_line, int end_line, int left_pix,
int right_pix)
{
void video_push_lines(Kimage *kimage_ptr, int start_line, int end_line, int left_pix,
int right_pix) {
int mdepth_mismatch;
int srcy;
int center = 0; // OG added variable to center screen
@ -3248,10 +3177,8 @@ video_push_lines(Kimage *kimage_ptr, int start_line, int end_line, int left_pix,
(right_pix - left_pix), 2*(end_line - start_line));
}
void
video_push_border_sides_lines(int src_x, int dest_x, int width, int start_line,
int end_line)
{
void video_push_border_sides_lines(int src_x, int dest_x, int width, int start_line,
int end_line) {
Kimage *kimage_ptr;
int srcy;
@ -3293,9 +3220,7 @@ video_push_border_sides_lines(int src_x, int dest_x, int width, int start_line,
}
}
void
video_push_border_sides()
{
void video_push_border_sides() {
int old_width;
int prev_line;
int width;
@ -3352,9 +3277,7 @@ video_push_border_sides()
X_A2_WINDOW_WIDTH - old_width, old_width, prev_line, 200);
}
void
video_push_border_special()
{
void video_push_border_special() {
Kimage *kimage_ptr;
int width, height;
int src_x, src_y;
@ -3373,10 +3296,20 @@ video_push_border_special()
dest_x = 0;
src_x = BASE_MARGIN_LEFT - g_video_act_margin_left;
/*
glogf("width: %d", kimage_ptr->width_act);
for (int i = 600; i< 700; i++) {
kimage_ptr->data_ptr[i*4] = 0xFF;
kimage_ptr->data_ptr[i*4+1] = 0xFF;
kimage_ptr->data_ptr[i*4+2] = 0x00;
}
*/
if(width > 0 && height > 0) {
x_push_kimage(kimage_ptr, dest_x, dest_y, src_x, src_y,
width, height);
#ifdef WINSDL_BORDERHACK
x_push_kimage(kimage_ptr, dest_x+72, dest_y, src_x, src_y, width, height);
#endif
x_push_kimage(kimage_ptr, dest_x, dest_y, src_x, src_y, width, height);
// glogf("X:%d Y: %d SX:%d SY:%D W:%d H:%d\n",dest_x, dest_y, src_x, src_y, width, height);
}
// Then fix top border: dest_x from 0 to 640+LEFT+RIGHT and
@ -3387,17 +3320,17 @@ video_push_border_special()
dest_y = 0;
src_y = BASE_MARGIN_BOTTOM;
if(width > 0 && height > 0) {
x_push_kimage(kimage_ptr, dest_x, dest_y, src_x, src_y,
width, height);
#ifdef WINSDL_BORDERHACK
x_push_kimage(kimage_ptr, dest_x+72, dest_y, src_x, src_y, width, height);
#endif
x_push_kimage(kimage_ptr, dest_x, dest_y, src_x, src_y, width, height);
}
}
// OG Added window ratio support
extern int x_calc_ratio(float ratiox,float ratioy);
void
video_push_kimages()
{
void video_push_kimages() {
register word32 start_time;
register word32 end_time;
Kimage *last_kim, *cur_kim;
@ -3512,9 +3445,7 @@ video_push_kimages()
}
void
video_update_color_raw(int col_num, int a2_color)
{
void video_update_color_raw(int col_num, int a2_color) {
word32 tmp;
int red, green, blue;
int newred, newgreen, newblue;
@ -3538,9 +3469,7 @@ video_update_color_raw(int col_num, int a2_color)
x_update_color(col_num, red, green, blue, tmp);
}
void
video_update_color_array(int col_num, int a2_color)
{
void video_update_color_array(int col_num, int a2_color) {
int palette;
int full;
@ -3556,19 +3485,10 @@ video_update_color_array(int col_num, int a2_color)
return;
}
#if 0
if(g_screen_depth != 8) {
/* redraw whole superhires for now */
g_full_refresh_needed = -1;
}
#endif
video_update_color_raw(col_num, a2_color);
}
void
video_update_colormap()
{
void video_update_colormap() {
int palette;
int full;
int i;
@ -3584,9 +3504,7 @@ video_update_colormap()
}
}
void
video_update_status_line(int line, const char *string)
{
void video_update_status_line(int line, const char *string) {
char *buf;
const char *ptr;
int i;
@ -3610,9 +3528,7 @@ video_update_status_line(int line, const char *string)
buf[STATUS_LINE_LENGTH] = 0;
}
void
video_show_debug_info()
{
void video_show_debug_info() {
word32 tmp1;
printf("g_cur_dcycs: %f, last_vbl: %f\n", g_cur_dcycs,
@ -3622,9 +3538,7 @@ video_show_debug_info()
printf("Last line updated: %d\n", g_vid_update_last_line);
}
word32
float_bus(double dcycs)
{
word32 float_bus(double dcycs) {
word32 val;
int lines_since_vbl;
int line, eff_line, line24;