mirror of
https://github.com/david-schmidt/gsport.git
synced 2024-06-28 22:29:38 +00:00
Backport SDL from GSplus
This commit is contained in:
parent
3e26fb1ecd
commit
e919ee8352
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,2 +1,4 @@
|
|||
/.project
|
||||
/GSport.app
|
||||
/gsport
|
||||
.DS_Store
|
79
src/Makefile
79
src/Makefile
|
@ -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
312
src/adb.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
5
src/atbridge/CMakeLists.txt
Normal file
5
src/atbridge/CMakeLists.txt
Normal 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)
|
|
@ -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 &&
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
662
src/config.c
662
src/config.c
File diff suppressed because it is too large
Load Diff
36
src/config.h
36
src/config.h
|
@ -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
45
src/config.txt
Normal 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
1520
src/debug.c
Normal file
File diff suppressed because it is too large
Load Diff
30
src/debug.h
Normal file
30
src/debug.h
Normal 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();
|
|
@ -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
164
src/dis.c
|
@ -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);
|
||||
|
|
131
src/engine_c.c
131
src/engine_c.c
|
@ -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
47
src/fix_mac_menu.m
Normal 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
203
src/fst.h
Normal 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
63
src/glog.c
Normal 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
30
src/glog.h
Normal 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
186
src/gsos.h
Normal 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
BIN
src/gsport
Executable file
Binary file not shown.
650
src/host_common.c
Normal file
650
src/host_common.c
Normal 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
186
src/host_common.h
Normal 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
1879
src/host_fst.c
Normal file
File diff suppressed because it is too large
Load Diff
1567
src/host_mli.c
Normal file
1567
src/host_mli.c
Normal file
File diff suppressed because it is too large
Load Diff
2078
src/icongs.h
Normal file
2078
src/icongs.h
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
195
src/moremem.c
195
src/moremem.c
|
@ -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
453
src/options.c
Normal 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 Don’t ignore bad memory accesses\n");
|
||||
printf(" -noignhalt Don’t 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
29
src/options.h
Normal 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
|
38
src/protos.h
38
src/protos.h
|
@ -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
887
src/sdl2_driver.c
Normal 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
222
src/sdl2snd_driver.c
Normal 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
|
||||
}
|
684
src/sim65816.c
684
src/sim65816.c
File diff suppressed because it is too large
Load Diff
|
@ -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
6
src/tfe/CMakeLists.txt
Normal 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)
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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 };
|
||||
|
|
|
@ -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
533
src/unix_host_common.c
Normal 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
21
src/vars_osx_sdl2
Normal 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
20
src/vars_osx_x11
Normal 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
18
src/vars_rpilinux_fb
Normal 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
16
src/vars_rpilinux_sdl2
Normal 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
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
21
src/vars_win32_sdl2
Normal 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 =
|
|
@ -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
21
src/vars_x86linux_sdl2
Normal 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
21
src/vars_x86linux_x11
Normal 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
|
|
@ -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
|
||||
|
|
278
src/video.c
278
src/video.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue
Block a user