# HG changeset patch # User asheldon # Date 1162109310 25200 # Node ID c0b31cf2c7cd1f05811a5ffd973918a1d2d0847c # Parent 6d1f65117180db4f652d3c61f1fc7635ecea8da1 [svn] Atari XL SAP. This compiles anything but cleanly, but somehow still works. No one will notice anyway, though. What percentage of the population listens to Atari XL music? I don't have an answer to that, but I'd guess that Audacious' SAP plugin will be used by approximately 2 people. diff -r 6d1f65117180 -r c0b31cf2c7cd ChangeLog --- a/ChangeLog Sun Oct 29 01:38:56 2006 -0700 +++ b/ChangeLog Sun Oct 29 01:08:30 2006 -0700 @@ -1,3 +1,12 @@ +2006-10-29 08:38:56 +0000 Aaron Sheldon + revision [282] + The comment probably ought to say 'enable' since that's what the command + does + + trunk/configure.ac | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + + 2006-10-29 08:23:08 +0000 William Pitcock revision [280] - mplayer should be disabled by default due to the fact that it's only diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/Makefile Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,29 @@ +include ../../mk/rules.mk +include ../../mk/init.mk + +OBJECTIVE_LIBS = libsapplug$(SHARED_SUFFIX) + +SAPLIB = saplib/pokey0.o saplib/pokey1.o saplib/sapCpu.o saplib/sapEngine.o saplib/sapPokey.o + +LINKER_FLAGS = -shared -Wl,-soname -Wl,$(TARGET) \ + -Wl,-retain-symbols-file -Wl,syms + +TARGET = libsapplug.so + +LIBDIR = $(plugindir)/$(INPUT_PLUGIN_DIR) $(SAPLIB) + +LIBADD += $(GTK_LIBS) + +SOURCES = fileinfo.c sapfile.c sap_plug.c + +CFLAGS += $(GTK_CFLAGS) $(LINKER_FLAGS) -I../../intl -I../.. +CXXFLAGS += $(GTK_CFLAGS) $(LINKER_FLAGS) -I../../intl -I../.. + +OBJECTS = ${SOURCES:.c=.o} $(SAPLIB) + +all: library + +library: + cd saplib && make + +include ../../mk/objective.mk diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/doc/CHANGES --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/doc/CHANGES Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,24 @@ +0.1 - first release (nothing works except "play" :)) + +0.2 - added vis_plugin hooks (spectrum analyzer works now) ;-) + - some fixes + +0.3 - compiler optimizations + - Fixed some compiler warnings in saplib + - Makefile has install target now :) + - Made saplib-exported routines callable from within C code. + - No sapPlaySong on SAP load (sapEngine.cpp), caller should initialize song + - Corrected title display + - Can skip to subsongs if they exist. + - File info box + - Can edit and write SAP tags + - sourcetree reorganisation :) + - fixed compilation problems with gcc 3.x + - should compile on FreeBSD + +0.3f - merged a fix from Miloslaw Smyk for a bug with Crossfade output plugin + (song played twice as fast after some time, not seen using OSS output) + +0.31 - fix for segfault crash with file info (ctrl+3) + - works on FreeBSD out of the box + \ No newline at end of file diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/doc/COMPILATION --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/doc/COMPILATION Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,40 @@ +COMPILATION REQUIREMENTS +------------------------ + +To compile the plugin you need: + + - gcc/g++ and at least libc6 2.1.x with POSIX pthreads + and a linux or *BSD system + + TESTED: + linux/x86 (gcc 2.95.2 and glibc 2.1.3) - compiles cleanly, works OK + linux/x86 (gcc 2.95.4 and glibc 2.2.5) - compiles cleanly, works OK + linux/alpha (gcc 3.2.2 and glibc 2.2.5) - compiles cleanly, works OK + + - xmms (of course :)), libxmms,libxmms-devel + + TESTED: + xmms 1.2.7 - OK + REPORTED: + xmms 1.2.8 - OK + + - gtk,gtk-devel, glib,glib-devel + + TESTED: + gtk+ 1.2.10 glib 1.2.10 - OK + REPORTED + gtk+ 1.2.8 glib 1.2.8 - OK + + +COMPILATION INSTRUCTIONS +------------------------ + +NOTE: Since I cannot have access to as many platforms as linux runs on, I need the +information about copilation issues on different machines/oses/architectures. +Just compile it! If it fails drop me a line with info on your system, +compiler and glibc versions. +If it compiles OK, and you use something different than the software / platform +mentioned above as TESTED, I need the info even more. Please be helpful ;) + +To compile just do a 'make && make install' in the plugin source dir. +That's it. Enjoy! diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/doc/CREDITS --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/doc/CREDITS Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,16 @@ +AUTHORS +------- +Michal Szwaczko (mikey@scene.pl) + +This plugin wouldn't be possible without the work of +Adam 'SoTe' Bienias. Adam wrote saplib, a portable POKEY+6502 emulator library +that is used extensively by the plugin. Thanks Adam!. + +CONTRIBUTORS +------------ +Azbest (azbest@plasma.ath.cx) - bugreports, FTP space. +Miloslaw Smyk (thorgal@wfmh.org.pl) - bugfix for Crossfade output plugin. +Mattias Fenner (informix@web.de) - bugreports, XMMS pluginpack maintainer. +Daniel Kozminski (dely@scene.pl) - media support :) + +[This space is for you] diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/doc/README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/doc/README Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,43 @@ +SAPPLUG - an XMMS plugin for POKEY tunes +---------------------------------------- + +Sapplug is a POKEY tunes player plugin for X Multimedia System (xmms) +This is a beta release, after first alpha versions seem to work fine. + +This, however means that it's still a work-in-progress software, some +features are missing. If you find some bugs - firs look in TODO list +to check if I am already working on them, same with new features requests. + +!!! Check TODO before sending me hate-mail. !!! + +USAGE +----- + +Just fire up xmms as you would normally and load some SAP tunes. +In case of not being able to play check in the preferences if +the plugin is installed and active!!! +Do not hesitate to mail me if you have problems compiling the plugin, +hovewer, due to limited amount of time, I will not be able to answer any +mail concerning general use of xmms or general plugin installation. +Report problems with *compiling* or *using* *this* plugin !!! + +Some notes: + +The seekbar is used to switch subsongs within a multi-song SAP. +Just click on it and the player plays next subsong! +The number of songs in a SAP file is displayed in the main xmms window +as X kHz (where X is the number of songs within the SAP file) +This info is also available in the sapfile info box. + +File info box is brought up when you click "View file info" in XMMS :) +It gives you general information about SAP file and presents so called +SAP tag. It's a set of name, author and date of the song, similar to an mp3 tag. +You can also edit this SAP tag, i.e. change author, name or date of the song. +Click "Save" and the new tag gets written to the file. Also, you can remove +the tag from the SAPfile by clicking "Remove Tag" + +Enjoy!! +-- +mikey +New Generation // WireLabs + \ No newline at end of file diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/doc/README.audacious --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/doc/README.audacious Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,7 @@ +Audacious sapplug-xmms Port 0.31 + +Copyright (c) 2006 Aaron Sheldon + +This is a port of sapplug-xmms, an atari SAP music player. + +Refer to the README for more information diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/doc/TODO --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/doc/TODO Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,5 @@ +TODO list for SAP plugin. + +- Make plugin jump to next song in playlist when finished +- Seek within a song + diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/fileinfo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/fileinfo.c Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,328 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "version.h" +#include "fileinfo.h" +#include "saplib/sapLib.h" + +static void fail (gchar *error) { + + gchar *errorstring; + + errorstring = g_strdup_printf("An error occured:\n%s", error); + xmms_show_message("Error!",errorstring, "Ok", FALSE, NULL, NULL); + g_free(errorstring); + return; +} + + +static void write_tag (GtkWidget *w , gpointer data) { + + + gchar *author, *title, *date, *tmpfn, *original_filename; + FILE *outf; + + int ofd; + + /* tags taken from info_box (edited or not) */ + author = gtk_entry_get_text(GTK_ENTRY(performer_entry)); + title = gtk_entry_get_text(GTK_ENTRY(title_entry)); + date = gtk_entry_get_text(GTK_ENTRY(date_entry)); + original_filename = gtk_entry_get_text(GTK_ENTRY(filename_entry)); + + // prepare tmp file + tmpfn = g_strdup_printf("/tmp/sapplugXXXXXX"); + + if ((ofd = mkstemp( tmpfn )) < 0 ) { + + fail("Can't make tempfile"); + g_free(tmpfn); + return; + + } + + if ((outf = fdopen(ofd,"wb")) == NULL ) { + + g_free(tmpfn); + fail("Cant write to file"); + close(ofd); + return; + + } + + /* start writing header */ + + fprintf(outf,"SAP\r\n"); + + if (strlen(author) != 0) + + fprintf(outf, "AUTHOR \"%s\"\r\n",author); + + if (strlen(title) != 0) + + fprintf(outf,"NAME \"%s\"\r\n",title); + + if (strlen(date) != 0) + + fprintf(outf,"DATE \"%s\"\r\n",date); + + /* save original songtype */ + + fprintf(outf,"TYPE %c\r\n",type_h); + + /* save original TAGS */ + + if (is_stereo == 1) + + fprintf(outf,"STEREO\r\n"); + + if (fastplay != -1) + + fprintf(outf,"FASTPLAY %d\r\n",fastplay); + + if (songs != -1) + + fprintf(outf,"SONGS %d\r\n",songs); + + if (defsong != -1) + + fprintf(outf,"DEFSONG %d\r\n",defsong); + + if (ini_address != -1) + + fprintf(outf,"INIT %.4X\r\n",ini_address); + + if (msx_address != -1) + + fprintf(outf,"MUSIC %.4X\r\n",msx_address); + + if (plr_address != -1) + + fprintf(outf,"PLAYER %.4X\r\n",plr_address); + + /* header written - now append original SAP data */ + + fwrite(&buffer+headersize, 1, filesize-headersize,outf); + fclose(outf); + + /* and rename it */ + if (rename(tmpfn,original_filename) < 0) { + + remove(tmpfn); + g_free(tmpfn); + fail("Failed to write!"); + return; + } + + remove(tmpfn); + g_free(tmpfn); + gtk_widget_destroy(window); + +} + +static void remove_tag (void) { + + gtk_entry_set_text(GTK_ENTRY(performer_entry),""); + gtk_entry_set_text(GTK_ENTRY(title_entry),""); + gtk_entry_set_text(GTK_ENTRY(date_entry),""); + +} + +void sap_file_info_box(char *filename) { + + gchar *tmp; + gchar *info_text; + + static GtkWidget *info_frame, *info_box, *sap_info_label; + static GtkWidget *tag_frame; + + GtkWidget *hbox, *label, *filename_hbox, *vbox, *left_vbox; + GtkWidget *table, *bbox, *cancel_button; + GtkWidget *save_button, *remove_button; + + + if (filename != NULL) { + + /* dig info from the sapfile */ + if ((load_sap(filename)) < 0) return; + + if (!window) { + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_policy(GTK_WINDOW(window), FALSE, FALSE, FALSE); + gtk_signal_connect(GTK_OBJECT(window), "destroy", + GTK_SIGNAL_FUNC(gtk_widget_destroyed), &window); + gtk_container_set_border_width(GTK_CONTAINER(window), 10); + + vbox = gtk_vbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(window), vbox); + + filename_hbox = gtk_hbox_new(FALSE, 5); + gtk_box_pack_start(GTK_BOX(vbox), filename_hbox, FALSE, TRUE, 0); + + label = gtk_label_new("Filename:"); + gtk_box_pack_start(GTK_BOX(filename_hbox), label, FALSE, TRUE, 0); + filename_entry = gtk_entry_new(); + gtk_editable_set_editable(GTK_EDITABLE(filename_entry), FALSE); + gtk_box_pack_start(GTK_BOX(filename_hbox), filename_entry,TRUE, TRUE, 0); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, TRUE, 0); + + left_vbox = gtk_vbox_new(FALSE, 10); + gtk_box_pack_start(GTK_BOX(hbox), left_vbox, FALSE, FALSE, 0); + + tag_frame = gtk_frame_new("SAP Tag:"); + gtk_box_pack_start(GTK_BOX(left_vbox), tag_frame, FALSE, FALSE, 0); + + table = gtk_table_new(5, 5, FALSE); + gtk_container_set_border_width(GTK_CONTAINER(table), 5); + gtk_container_add(GTK_CONTAINER(tag_frame), table); + + label = gtk_label_new("Title:"); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1, + GTK_FILL, GTK_FILL, 5, 5); + + title_entry = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), title_entry, 1, 4, 0, 1, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); + + label = gtk_label_new("Artist:"); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2, + GTK_FILL, GTK_FILL, 5, 5); + + performer_entry = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), performer_entry, 1, 4, 1, 2, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); + + label = gtk_label_new("Date:"); + gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); + gtk_table_attach(GTK_TABLE(table), label, 0, 1, 4, 5, + GTK_FILL, GTK_FILL, 5, 5); + + date_entry = gtk_entry_new(); + gtk_table_attach(GTK_TABLE(table), date_entry, 1, 2, 4, 5, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, + GTK_FILL | GTK_EXPAND | GTK_SHRINK, 0, 5); + + + bbox = gtk_hbutton_box_new(); + gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), + GTK_BUTTONBOX_END); + gtk_button_box_set_spacing(GTK_BUTTON_BOX(bbox), 5); + gtk_box_pack_start(GTK_BOX(left_vbox), bbox, FALSE, FALSE, 0); + + save_button = gtk_button_new_with_label("Save"); + gtk_signal_connect(GTK_OBJECT(save_button), "clicked", + GTK_SIGNAL_FUNC(write_tag), NULL); + + GTK_WIDGET_SET_FLAGS(save_button, GTK_CAN_DEFAULT); + + gtk_box_pack_start(GTK_BOX(bbox), save_button, TRUE, TRUE, 0); + gtk_widget_grab_default(save_button); + + remove_button = gtk_button_new_with_label("Remove Tag"); + gtk_signal_connect_object(GTK_OBJECT(remove_button), + "clicked", + GTK_SIGNAL_FUNC(remove_tag), NULL); + + GTK_WIDGET_SET_FLAGS(remove_button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(bbox),remove_button, TRUE, TRUE, 0); + + cancel_button = gtk_button_new_with_label("Cancel"); + gtk_signal_connect_object(GTK_OBJECT(cancel_button), + "clicked", + GTK_SIGNAL_FUNC(gtk_widget_destroy), + GTK_OBJECT(window)); + GTK_WIDGET_SET_FLAGS(cancel_button, GTK_CAN_DEFAULT); + gtk_box_pack_start(GTK_BOX(bbox),cancel_button, TRUE, TRUE, 0); + + /* info frame */ + info_frame = gtk_frame_new("SAP Info:"); + gtk_box_pack_start(GTK_BOX(hbox), info_frame, FALSE, FALSE, 0); + + info_box = gtk_vbox_new(FALSE, 5); + gtk_container_add(GTK_CONTAINER(info_frame), info_box); + gtk_container_set_border_width(GTK_CONTAINER(info_box), 5); + gtk_box_set_spacing(GTK_BOX(info_box), 0); + + sap_info_label = gtk_label_new(""); + gtk_misc_set_alignment(GTK_MISC(sap_info_label), 0, 0); + gtk_label_set_justify(GTK_LABEL(sap_info_label), + GTK_JUSTIFY_LEFT); + gtk_box_pack_start(GTK_BOX(info_box), sap_info_label, FALSE, + FALSE, 0); + /* end info frame */ + + gtk_widget_show_all(window); + + } else + + gdk_window_raise(window->window); + gtk_widget_set_sensitive(tag_frame, TRUE); + + /* window drawn and displayed ... now - the code + + clear up entries */ + remove_tag(); + + /* show filename in the entrybox */ + gtk_entry_set_text(GTK_ENTRY(filename_entry),filename); + /* and in the window title ... */ + tmp = g_strdup_printf("File Info - [%s]", g_basename(filename)); + gtk_window_set_title(GTK_WINDOW(window), tmp); + + /* fill up entries with what we dug out from the sapfile */ + gtk_entry_set_text(GTK_ENTRY(performer_entry),author); + gtk_entry_set_position(GTK_ENTRY(performer_entry),0); + gtk_entry_set_text(GTK_ENTRY(title_entry),name); + gtk_entry_set_position(GTK_ENTRY(title_entry),0); + gtk_entry_set_text(GTK_ENTRY(date_entry),date); + gtk_entry_set_position(GTK_ENTRY(date_entry),0); + /* fill in sap_info_frame; */ + info_text = g_strdup_printf( + "Type: %s\nStereo: %s\nSpeed: %d / Frame\nSongs: %d\n\nSize: %ld\n", + + type, + (is_stereo > 0) ? "Yes" : "No", + times_per_frame, + (songs > 0) ? songs : 1, + filesize ); + + gtk_label_set_text(GTK_LABEL(sap_info_label),info_text); + + /* cleanup */ + g_free(info_text); + g_free(tmp); + + } + +} diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/fileinfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/fileinfo.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,43 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +static GtkWidget *title_entry, *performer_entry; +static GtkWidget *date_entry; +static GtkWidget *filename_entry; +static GtkWidget *window = NULL; + +extern int load_sap (char *); +extern unsigned char buffer; + +extern long filesize; +extern int headersize; +extern char author[]; +extern char name[]; +extern char date[]; +extern int is_stereo; +extern int fastplay; +extern char type_h; /* type as seen in SAP header; */ +extern char type[]; /* type in ascii; */ +extern int plr_address; +extern int msx_address; +extern int ini_address; +extern int songs; +extern int defsong; +extern int times_per_frame; diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/sap_plug.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/sap_plug.c Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,194 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sap_plug.h" +#include "version.h" + +InputPlugin sap_ip = { + + NULL, + NULL, + "SAP Plugin " VERSION, + NULL, + sap_about, + NULL, + sap_is_our_file, + NULL, + sap_play_file, + sap_stop, + sap_pause, + sap_seek, + NULL, + sap_get_time, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + sap_file_info_box, + NULL +}; + +InputPlugin *get_iplugin_info (void) { + return &sap_ip; +} + +static int sap_is_our_file (char *filename) { + + char *ext; + + ext = strrchr(filename, '.'); + + if (ext) + { + if (!strcmp(ext, ".SAP")) + return 1; + if (!strcmp(ext, ".sap")) + return 1; + } + + return 0; +} + +static void *play_loop (void *arg) { + + int datasize = N_RENDER << 2; + + while (going) { + + sapRenderBuffer(play_buf,N_RENDER); + /* for spectrum analyser */ + sap_ip.add_vis_pcm(sap_ip.output->written_time(), FMT_S16_NE, 2, N_RENDER, play_buf); + + while (sap_ip.output->buffer_free() < ( N_RENDER << 2 ) && going) + + xmms_usleep(30000); + + if (going) + + sap_ip.output->write_audio(play_buf, datasize); + + + } + + sap_ip.output->buffer_free(); + sap_ip.output->buffer_free(); + pthread_exit(NULL); + +} + +static void sap_play_file (char *filename) { + + GString *titstr; + + if ((currentFile = sapLoadMusicFile(filename)) == NULL) return; + + /* for tunes */ + tunes = currentFile->numOfSongs; + + if (tunes < 0) tunes = 1; + + /* we always start with 1st tune */ + currentSong = 0; + + sapPlaySong(currentSong); + + going = TRUE; + audio_error = FALSE; + + if (sap_ip.output->open_audio(FMT_S16_LE, OUTPUT_FREQ, 2) == 0) { + + audio_error = TRUE; + going = FALSE; + + return; + } + /* delete '.sap' from filename to display */ + titstr = g_string_new(g_basename(filename)); + g_string_truncate(titstr,titstr->len - 4); + + sap_ip.set_info(titstr->str, tunes, tunes*1024, OUTPUT_FREQ, 2); + + g_string_free(titstr,TRUE); + + pthread_create(&play_thread, NULL, play_loop, NULL); + + +} + +static void sap_stop (void) { + + if (going) { + + going = FALSE; + pthread_join(play_thread, NULL); + sap_ip.output->close_audio(); + } +} + +static void sap_seek(int time) { + + if (currentSong != tunes) { + + currentSong = (currentSong+1) % currentFile->numOfSongs; + sapPlaySong(currentSong); + sap_ip.output->flush(currentSong * 1000); + + } +} + +static void sap_pause(short paused) { + + sap_ip.output->pause(paused); + +} + +static int sap_get_time(void) { + + return sap_ip.output->output_time(); +} + +static void sap_about (void) { + + static GtkWidget *aboutbox; + + if (aboutbox != NULL) + return; + + aboutbox = xmms_show_message( + "About SAP Plugin", + "SAP Player plug-in v"VERSION"\nby Michal Szwaczko \n SAP library ver "SAP_VER" by Adam Bienias\n\n" + "Get more POKEY sound from ASMA at:\n[http://asma.musichall.cz]\n\nEnjoy!", + "Ok", FALSE, NULL, NULL); + + gtk_signal_connect(GTK_OBJECT(aboutbox), "destroy", + GTK_SIGNAL_FUNC(gtk_widget_destroyed), &aboutbox); +} diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/sap_plug.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/sap_plug.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,47 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include "saplib/sapLib.h" + +/* Default frequency */ +#define OUTPUT_FREQ 44100 +/* how many samples per one saprender() */ +#define N_RENDER 1024 + +/* functions */ +static int sap_is_our_file (char *); +static void sap_play_file(gchar *); +static void sap_stop(void); +static void sap_pause(short); +static void sap_seek(int); +static int sap_get_time(void); +static void sap_about(void); + +extern void sap_file_info_box(char *); + +static gboolean going; +static gboolean audio_error; +static pthread_t play_thread; + +int currentSong; +static int tunes; + +sapMUSICstrc *currentFile; + +signed short play_buf[N_RENDER << 2]; diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/sapfile.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/sapfile.c Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,364 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#include +#include +#include +#include +#include +#include +#include + +#include "version.h" +#include "sapfile.h" + +int load_sap (char *fname) { + + struct stat st; + int i, k; + + FILE *f; + + /* flush static buffers */ + + memset(author, 0, 2048); + memset(name, 0, 2048); + memset(date, 0, 2048); + memset(type, 0, 20); + + /* get filesize */ + + if (stat(fname, &st) < 0) + + return -1; + + filesize = st.st_size; + + /* open & read file into buffer */ + + f = fopen(fname, "rb"); + + if ( !f ) + + return -1; + + fread(buffer, 1, filesize, f); + + fclose(f); + + /* check if it is a sap file */ + + if (strncmp(buffer, "SAP", 3) != 0 ) + + return -1; + + /* set headersize */ + + for (i = 0; i < filesize; i++) { + + if (buffer[i] == '\xFF' ) { + + headersize = i; + break; + } + + if (buffer[i] != '\xFF' && i == filesize-1) + + return -1; + } + + /* sanity checking done - parse the info tags + please someone rewrite this !!! :) + this code sux0r ... */ + + /* check for author */ + + k = 0; + + for (i = 0;i < headersize; i++) { + + if (strncmp(buffer + i, "AUTHOR", 6) == 0 ) { + + i = i + 8; + + while (buffer[i] != '"' && buffer[i] != 0x0D && buffer[i] != 0x0A) { + + author[k] = buffer[i]; + k++; i++; + } + break; + } + /* notfound */ + sprintf(author, "%s", ""); + } + + /* check for name */ + + k = 0; + + for (i = 0;i < headersize; i++) { + + if ( strncmp(buffer + i, "NAME", 4) == 0 ) { + + i = i + 6; + + while (buffer[i] != '"' && buffer[i] != 0x0D && buffer[i] != 0x0A) { + + name[k] = buffer[i]; + k++; i++; + } + break; + } + /* notfound */ + sprintf(name, "%s", ""); + } + + /* check for date */ + + k = 0; + + for(i = 0;i < headersize; i++) { + + if (strncmp(buffer + i, "DATE", 4) == 0 ) { + + i = i + 6; + + while (buffer[i] != '"' && buffer[i] != 0x0D && buffer[i] != 0x0A) { + + date[k] = buffer[i]; + k++; i++; + } + break; + } + /* notfound */ + sprintf(date, "%s", ""); + } + + + /* check for stereo */ + + for (i = 0; i < headersize; i++) { + + if (strncmp(buffer + i, "STEREO", 6) == 0 ) { + + is_stereo = 1; + break; + } + /* notfound */ + is_stereo = -1; + } + + /* check fastplay; */ + + for (i = 0; i < headersize; i++) { + + if (strncmp(buffer + i, "FASTPLAY", 8) == 0 ) { + + k = strtol(&buffer[i + 1 + 8], NULL, 10); + + if ( k == 0 || k > 312 ) + + /* illegal fastplay value */ + return -1; + + else + + fastplay = k; + + switch (k) { + + case 156: + + times_per_frame = 2; + break; + + case 104: + + times_per_frame = 3; + break; + + case 78: + + times_per_frame = 4; + break; + + } + break; + } + /* notfound */ + fastplay = -1; + times_per_frame = 1; + } + + /* check songs */ + for (i = 0; i < headersize; i++) { + + if (strncmp(buffer + i, "SONGS", 5) == 0) { + + k = strtol(&buffer[i + 1 + 5], NULL, 10); + + if ( (k == 0) || (k > 0xffff) ) + /* illegal songs value */ + return -1; + else + + songs = k; + break; + } + /* notfound */ + songs = -1; + } + + /* check defsong */ + for (i = 0;i < headersize; i++) { + + if (strncmp(buffer + i, "DEFSONG", 7) == 0 ) { + + k = strtol(&buffer[i + 1 + 7], NULL, 10); + + if ( (k < 0) || (k > 0xffff) ) + /* illegal defsong value */ + return -1; + + else + + defsong = k; + break; + } + /* notfound */ + defsong = -1; + } + + + /* check songtype */ + for (i = 0;i < headersize; i++) { + + if (strncmp(buffer + i, "TYPE", 4) == 0 ) { + + i = i + 5; + + if (buffer[i] == 'B') { + /* SAP documentation says + "any player" */ + sprintf(type, "Standard"); + type_h = 'B'; + break; + } + + if (buffer[i] == 'S') { + + sprintf(type, "SoftSynth"); + type_h = 'S'; + break; + } + + if (buffer[i] == 'D') { + + sprintf(type, "DigiSynth"); + type_h = 'D'; + break; + } + + if (buffer[i] == 'C') { + + sprintf(type, "CMC Synth"); + type_h= 'C'; + break; + } + + if (buffer[i] == 'M') { + /* unsupported (?) */ + sprintf(type, "M-Type"); + type_h = 'M'; + break; + } + + if (buffer[i] == 'R') { + /* this is unsupported - perhaps we */ + /* should return -1 as for now */ + sprintf(type, "Regs"); + type_h = 'R'; + break; + } + /* unsupported songtype */ + return -1; + } + /* no type specified */ + if (i == headersize - 1) return -1; + + } + + /* msx_address */ + for (i = 0;i < headersize; i++) { + + if (strncmp(buffer + i, "MUSIC", 5) == 0 ) { + + k = strtol(&buffer[i + 1 + 5], NULL, 16); + + if ( (k == 0) || (k > 0xffff) ) + /* illegal address */ + return -1; + else + + msx_address = k; + break; + } + /* notfound */ + msx_address = -1; + } + + /* ini address */ + for (i = 0;i < headersize; i++) { + + if (strncmp(buffer + i, "INIT", 4) == 0 ) { + + k = strtol(&buffer[i + 1 + 4], NULL, 16); + + if ( (k == 0) || (k > 0xffff) ) + /* illegal address */ + return -1; + else + + ini_address = k; + break; + } + /* notfound */ + ini_address = -1; + } + /* player */ + for (i = 0; i < headersize; i++) { + + if (strncmp(buffer + i,"PLAYER", 6) == 0 ) { + + k = strtol(&buffer[i + 1 + 6], NULL, 16); + + if ( (k == 0) || (k > 0xffff) ) + /* illegal */ + return -1; + else + + plr_address = k; + break; + } + /* notfound */ + plr_address = -1; + } + + return 1; +} diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/sapfile.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/sapfile.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,39 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +char buffer[0x10000]; + +char author[2048]; +char name[2048]; +char date[2048]; +char type[20]; /* type in ascii */ +char type_h; /* type as seen in SAP header; */ + +long filesize; + +int headersize; +int is_stereo; +int fastplay; +int plr_address; +int msx_address; +int ini_address; +int songs; +int defsong; +int times_per_frame; /* times per frame */ diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/Makefile Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,14 @@ +CXX= g++ --no-exceptions + +CXXFLAGS=-Wall -fPIC -fpic -O2 -ffast-math \ + -funroll-all-loops \ + -fno-strength-reduce -finline-functions \ + -fomit-frame-pointer + +SRCS= pokey0.cpp pokey1.cpp sapCpu.cpp sapEngine.cpp sapPokey.cpp +OBJS= pokey0.o pokey1.o sapCpu.o sapEngine.o sapPokey.o + +all:$(OBJS) + +clean: + rm -f *.o core diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/legal.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/legal.txt Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,11 @@ + + Disclaimer. + +I, Adam Bienias, author of the SAP Library, I'm not responsible +for any kind of hardware or software damage caused by this library. +Use it on your risk. SAP Library is distributed as FREEWARE but +any changes in the library must be approved by me. If You use SAP +Library in Your program, then You must include information about +SAP library: "SAP Library ver.x.xx by Adam Bienias". + + For contact send email to: adam@nautilus.com.pl diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/pokey.png Binary file src/sap/saplib/pokey.png has changed diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/pokey0.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/pokey0.cpp Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,132 @@ +#include +#include +#include +#include +#include + +#include "sapGlobals.h" + +#define NAMESPACENAME POKEY0_NAMESPACE +#define POKEY_INIT_FUNC void pokeyInit0( void ) +#define POKEY_RESET_FUNC void pokeyReset0( void ) +#define POKEY_UPDATESOUND_FUNC void pokeyUpdateSound0( int n ) +#define POKEY_UPDATECOUNT_FUNC void pokeyUpdateSoundCounters0( void ) +#define POKEY_WRITE_FUNC void pokeyWriteByte0( short unsigned int address, BYTE value ) +#define POKEY_WRITE_2FUNC(a,v) pokeyWriteByte0(a,v) + +#include "pokeyNamespace.h" + +bool *generateIRQ0 = &POKEY0_NAMESPACE::generateIRQ0; + +POKEY_WRITE_FUNC +{ + address&=0x0F; + + switch( address ) + { + case 0x00: + divideByN_Latch[0] = value; + SetupChannels01; + break; + case 0x01: + audioControl_Latch[0] = value; + audioControl_Latch2[0] = value&15; + audioControl_Latch_Digi[0] = (value>>4)&1 ? 15:0; + Channel0Distortion = channelsDistorionTable0[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels01; + break; + case 0x02: + divideByN_Latch[1] = value; + SetupChannels01; + break; + case 0x03: + audioControl_Latch[1] = value; + audioControl_Latch2[1] = value&15; + audioControl_Latch_Digi[1] = (value>>4)&1 ? 15:0; + Channel1Distortion = channelsDistorionTable1[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels01; + break; + case 0x04: + divideByN_Latch[2] = value; + SetupChannels23; + break; + case 0x05: + audioControl_Latch[2] = value; + audioControl_Latch2[2] = value&15; + audioControl_Latch_Digi[2] = (value>>4)&1 ? 15:0; + Channel2Distortion = channelsDistorionTable2[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels23; + break; + case 0x06: + divideByN_Latch[3] = value; + SetupChannels23; + break; + case 0x07: + audioControl_Latch[3] = value; + audioControl_Latch2[3] = value&15; + audioControl_Latch_Digi[3] = (value>>4)&1 ? 15:0; + Channel3Distortion = channelsDistorionTable3[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels23; + break; + case 0x08: + { + BYTE prevAUDCTL; + prevAUDCTL = AUDCTL; + AUDCTL = value; + pcc1564 = value & 1 ? 112:28; + + noiseAND = AUDCTL & 128 ? 0x1FF:0x1FFFF; + + switch_J3_Q_stateAND[0] = AUDCTL&4 ? 15:0; + switch_J3_Q_stateAND[1] = AUDCTL&2 ? 15:0; + + SetupChannels01; + SetupChannels23; + + if( (prevAUDCTL^AUDCTL)&0x10 ) + divideByN[1] = 2; + if( (prevAUDCTL^AUDCTL)&0x8 ) + divideByN[3] = 2; + + break; + } + case 0x0D: + break; + case 0x0E: + // najpierw czyscimy status przerwan IRQ_ST. Tam gdzie we wpisywanej wartosci jest 0, + // status tego przerwania jest zerowany + IRQ_ST = IRQ_ST&value; + IRQ_EN = value; + // teraz sprawdzamy czy musimy ustawic linie IRQ + IRQ_line = ((IRQ_ST&IRQ_EN)!=0x00) ? 0x01:0x00; + break; + case 0x0F: + break; + } +} + +void pokeyGenerateCheckIRQline( void ) +{ + if( ((cpuFlag_I&1)==0) && IRQ_line ) + { + BYTE fl,lsb,msb; + atariMem[0x100 + cpuReg_S] = (cpuReg_PC>>8)&0xFF; cpuReg_S--; + atariMem[0x100 + cpuReg_S] = cpuReg_PC&0xFF; cpuReg_S--; + atariMem[0x100 + cpuReg_S] = fl = cpuGetFlags(); cpuReg_S--; + lsb = atariMem[0xFFFE]; msb = atariMem[0xFFFF]; + cpuReg_PC = ((WORD)lsb) + ((WORD)msb)*256; + } +} + +void pokeyGenerateIRQ( BYTE irqMask ) +{ + IRQ_ST |= irqMask; + IRQ_line = ((IRQ_ST&IRQ_EN)!=0x00) ? 0x01:0x00; + pokeyGenerateCheckIRQline(); +} + + diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/pokey1.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/pokey1.cpp Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include + +#include "sapGlobals.h" + +#define NAMESPACENAME POKEY1_NAMESPACE +#define POKEY_INIT_FUNC void pokeyInit1( void ) +#define POKEY_RESET_FUNC void pokeyReset1( void ) +#define POKEY_UPDATESOUND_FUNC void pokeyUpdateSound1( int n ) +#define POKEY_UPDATECOUNT_FUNC void pokeyUpdateSoundCounters1( void ) +#define POKEY_WRITE_FUNC void pokeyWriteByte1( short unsigned int address, BYTE value ) +#define POKEY_WRITE_2FUNC(a,v) pokeyWriteByte1(a,v) + +#include "pokeyNamespace.h" + +POKEY_WRITE_FUNC +{ + address&=0x0F; + + switch( address ) + { + case 0x00: + divideByN_Latch[0] = value; + SetupChannels01; + break; + case 0x01: + audioControl_Latch[0] = value; + audioControl_Latch2[0] = value&15; + audioControl_Latch_Digi[0] = (value>>4)&1 ? 15:0; + Channel0Distortion = channelsDistorionTable0[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels01; + break; + case 0x02: + divideByN_Latch[1] = value; + SetupChannels01; + break; + case 0x03: + audioControl_Latch[1] = value; + audioControl_Latch2[1] = value&15; + audioControl_Latch_Digi[1] = (value>>4)&1 ? 15:0; + Channel1Distortion = channelsDistorionTable1[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels01; + break; + case 0x04: + divideByN_Latch[2] = value; + SetupChannels23; + break; + case 0x05: + audioControl_Latch[2] = value; + audioControl_Latch2[2] = value&15; + audioControl_Latch_Digi[2] = (value>>4)&1 ? 15:0; + Channel2Distortion = channelsDistorionTable2[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels23; + break; + case 0x06: + divideByN_Latch[3] = value; + SetupChannels23; + break; + case 0x07: + audioControl_Latch[3] = value; + audioControl_Latch2[3] = value&15; + audioControl_Latch_Digi[3] = (value>>4)&1 ? 15:0; + Channel3Distortion = channelsDistorionTable3[ (value>>4)&15 ]; + if( !(value&0x10) ) + SetupChannels23; + break; + case 0x08: + { + BYTE prevAUDCTL; + prevAUDCTL = AUDCTL; + AUDCTL = value; + pcc1564 = value & 1 ? 112:28; + + noiseAND = AUDCTL & 128 ? 0x1FF:0x1FFFF; + + switch_J3_Q_stateAND[0] = AUDCTL&4 ? 15:0; + switch_J3_Q_stateAND[1] = AUDCTL&2 ? 15:0; + + SetupChannels01; + SetupChannels23; + + if( (prevAUDCTL^AUDCTL)&0x10 ) + divideByN[1] = 2; + if( (prevAUDCTL^AUDCTL)&0x8 ) + divideByN[3] = 2; + + break; + } + case 0x0D: + break; + case 0x0E: + break; + case 0x0F: + break; + } +} diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/pokeyNamespace.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/pokeyNamespace.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,665 @@ +// This is very funny piece of code :)). This is a "fake" pokey template. + +namespace NAMESPACENAME { + +BYTE IRQ_EN; +BYTE IRQ_ST; +BYTE IRQ_line; +bool generateIRQ0; + +const double cutFreq = 24000.0 / 44100.0; // cutoff frequency = 20000, sampling frequency = 44100 +const int samplerRate = 0x2836D6; // (1773447 / 44100) * 65536; +const int samplerRateOver = 0xA0DB5/2; // (1773447 / 176400) * 65536; + +//const double cutFreq2 = 26000.0 / 1773447.0; // cutoff frequency = 20000, sampling frequency = 44100 +const double cutFreq2 = 28000.0 / 176400; // cutoff frequency = 20000, sampling frequency = 44100 + +const int cutFreq2i = 650; + +#define MAKESAMPLE\ + {\ + ss-=0x10000;\ + if( ss<0 )\ + {\ + ss += samplerRateOver;\ + DWORD pomd; int pomi;\ + pomd = ((DWORD*)&switch_J3_Q_state[0])[0];\ + pomd &= ((DWORD*)&switch_J3_Q_stateAND[0])[0];\ + pomd ^= ((DWORD*)&signal_state_out[0])[0];\ + pomd &= ((DWORD*)&freq_sequre[0])[0];\ + pomd |= ((DWORD*)&audioControl_Latch_Digi[0])[0];\ + pomd &= ((DWORD*)&audioControl_Latch2[0])[0];\ + pomd = pomd + (pomd>>16);\ + pomi = (int)( pomd + (pomd>>8) ) & 255;\ + oldValI = oldValI + ((cutFreq2i*((pomi<<12) - oldValI))>>12);\ + delay++; if( (delay&7)==0 )\ + {\ + pomi = oldValI>>3;\ + if( pomi<-16384 ) pomi = -16384; else if( pomi>32767 ) pomi = 32767;\ + sndBuf[sndBufPtr] = (WORD)pomi;\ + sndBufPtr = (sndBufPtr+sampleStep)&16383;\ + }\ + }\ + } + +int sndBufPtrUpp; + +int oldValI = 0; +double oldVal=0.0; +int delay = 0; + +BYTE AUDCTL; +int pcc1564,noiseAND,pokeyClockCounter64k; + +DWORD pokeyClockCounter; +DWORD poly4Counter,poly5Counter,poly4_5Counter; + +BYTE poly17[0x20000]; +BYTE poly4_b[36000]; // minimum size is 312*114+15 +BYTE poly5_b[36000]; // minimum size is 312*114+31 +BYTE poly4_5_b[37000]; // minimum size is 312*114+465 + +BYTE poly4[15] = { +15, 15, 15, 15, 0, 0, 0, 15, 0, 0, 15, 15, 0, 15, 0 +}; + +BYTE poly5[31] = { +15, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 15, 0, 0, 0, 15, 0, 15, 0 +}; + +int divideByN[4]; +int divideByN_Latch[4]; +int divideByN_Latch2[4]; +BYTE switch_J2_signal_Q[4]; +BYTE signal_state_out[4]; +BYTE switch_J3_Q_state[4]; +BYTE switch_J3_Q_stateAND[4]; +BYTE audioControl_Latch[4]; +BYTE audioControl_Latch2[4]; +BYTE audioControl_Latch_Digi[4]; +BYTE freq_sequre[4]; + +void (*Channel0Distortion)(void); +void (*Channel1Distortion)(void); +void (*Channel2Distortion)(void); +void (*Channel3Distortion)(void); + +//--- +void channel0_0( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[0] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel0_2( void ) +{ + signal_state_out[0] = signal_state_out[0] ^ poly5_b[ poly5Counter + pokeyClockCounter ]; +} +void channel0_4( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[0] = poly4_b[ poly4Counter + pokeyClockCounter ]; +} +void channel0_8( void ) +{ + signal_state_out[0] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel0_A( void ) +{ + signal_state_out[0] = signal_state_out[0] ^ 15; +} +void channel0_C( void ) +{ + signal_state_out[0] = poly4_b[ pokeyClockCounter + poly4Counter ]; +} +//--- +void channel1_0( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[1] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel1_2( void ) +{ + signal_state_out[1] = signal_state_out[1] ^ poly5_b[ poly5Counter + pokeyClockCounter ]; +} +void channel1_4( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[1] = poly4_b[ poly4Counter + pokeyClockCounter ]; +} +void channel1_8( void ) +{ + signal_state_out[1] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel1_A( void ) +{ + signal_state_out[1] = signal_state_out[1] ^ 15; +} +void channel1_C( void ) +{ + signal_state_out[1] = poly4_b[ pokeyClockCounter + poly4Counter ]; +} +//--- +void channel2_0( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[2] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel2_2( void ) +{ + signal_state_out[2] = signal_state_out[2] ^ poly5_b[ poly5Counter + pokeyClockCounter ]; +} +void channel2_4( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[2] = poly4_b[ poly4Counter + pokeyClockCounter ]; +} +void channel2_8( void ) +{ + signal_state_out[2] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel2_A( void ) +{ + signal_state_out[2] = signal_state_out[2] ^ 15; +} +void channel2_C( void ) +{ + signal_state_out[2] = poly4_b[ pokeyClockCounter + poly4Counter ]; +} +//--- +void channel3_0( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[3] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel3_2( void ) +{ + signal_state_out[3] = signal_state_out[3] ^ poly5_b[ poly5Counter + pokeyClockCounter ]; +} +void channel3_4( void ) +{ + if( poly5_b[ poly5Counter + pokeyClockCounter ]!=0 ) + signal_state_out[3] = poly4_b[ poly4Counter + pokeyClockCounter ]; +} +void channel3_8( void ) +{ + signal_state_out[3] = poly17[ pokeyClockCounter & noiseAND ]; +} +void channel3_A( void ) +{ + signal_state_out[3] = signal_state_out[3] ^ 15; +} +void channel3_C( void ) +{ + signal_state_out[3] = poly4_b[ pokeyClockCounter + poly4Counter ]; +} + +void channel0_1( void ) +{ + signal_state_out[0] = 15; +} +void channel1_1( void ) +{ + signal_state_out[1] = 15; +} +void channel2_1( void ) +{ + signal_state_out[2] = 15; +} +void channel3_1( void ) +{ + signal_state_out[3] = 15; +} + +typedef void (*funcPoint)(void); +funcPoint channelsDistorionTable0[16]= + { &channel0_0, &channel0_1, &channel0_2, &channel0_1, &channel0_4, &channel0_1, &channel0_2, &channel0_1, &channel0_8, &channel0_1, &channel0_A, &channel0_1, &channel0_C, &channel0_1, &channel0_A, &channel0_1 }; +funcPoint channelsDistorionTable1[16]= + { &channel1_0, &channel1_1, &channel1_2, &channel1_1, &channel1_4, &channel1_1, &channel1_2, &channel1_1, &channel1_8, &channel1_1, &channel1_A, &channel1_1, &channel1_C, &channel1_1, &channel1_A, &channel1_1 }; +funcPoint channelsDistorionTable2[16]= + { &channel2_0, &channel2_1, &channel2_2, &channel2_1, &channel2_4, &channel2_1, &channel2_2, &channel2_1, &channel2_8, &channel2_1, &channel2_A, &channel2_1, &channel2_C, &channel2_1, &channel2_A, &channel2_1 }; +funcPoint channelsDistorionTable3[16]= + { &channel3_0, &channel3_1, &channel3_2, &channel3_1, &channel3_4, &channel3_1, &channel3_2, &channel3_1, &channel3_8, &channel3_1, &channel3_A, &channel3_1, &channel3_C, &channel3_1, &channel3_A, &channel3_1 }; + +void pus_zero( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + + i = n; + do + { + pokeyClockCounter++; + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; + +} + +void pus_2h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; +} + +void pus_23h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; +} + +void pus_0h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; +} + +void pus_01h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; + +} + +void pus_02h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; +} + +void pus_012h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; +} + +void pus_023h( int n ) +{ +unsigned int i; +unsigned int ch; +DWORD pp; +int ss; + + pp = pokeyClockCounter + (pcc1564 - pokeyClockCounter64k); + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + if( pokeyClockCounter>=pp ) + { + pp = pokeyClockCounter + pcc1564; + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; + pokeyClockCounter64k = pcc1564 + pokeyClockCounter - pp ; +} + +void pus_0123h( int n ) +{ +unsigned int i; +unsigned int ch; +int ss; + + ss = sndBufPtrUpp; + i = n; + do + { + pokeyClockCounter++; + ch = 0; { if( --divideByN[ch]==0 ) { generateIRQ0=true; divideByN[ch] = divideByN_Latch2[ch]; Channel0Distortion(); } } + ch = 1; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel1Distortion(); } } + ch = 2; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel2Distortion(); switch_J3_Q_state[0] = signal_state_out[0]; } } + ch = 3; { if( --divideByN[ch]==0 ) { divideByN[ch] = divideByN_Latch2[ch]; Channel3Distortion(); switch_J3_Q_state[1] = signal_state_out[1]; } } + MAKESAMPLE + } while(--i); + sndBufPtrUpp = ss; +} + +typedef void (*funcPoint2)(int n); + +funcPoint2 channelsGeneration[16]={ + &pus_zero, &pus_zero, &pus_zero, &pus_zero, + &pus_2h, &pus_23h, &pus_2h, &pus_23h, + &pus_0h, &pus_0h, &pus_01h, &pus_01h, + &pus_02h, &pus_023h, &pus_012h, &pus_0123h +}; + +}; // end of namespace POKEY_NAMESPACE + +using namespace NAMESPACENAME; + +POKEY_INIT_FUNC +{ +unsigned int i; +DWORD pol; +BYTE old; + + pol = 0x1FFFF; + for( i=0; i<0x20000; i++ ) + { + poly17[i] = (BYTE)(pol&1 ? 15:0); + pol = pol | (((pol&1) ^ ((pol>>5)&1)) << 17); + pol>>=1; + } + + for( i=0; i>3)&15 ](n); + +} + + +POKEY_UPDATECOUNT_FUNC +{ + + pokeyClockCounter = pokeyClockCounter & 0x7FFFFFFF; + poly4Counter = (int)(((DWORD)(poly4Counter+pokeyClockCounter)) % 15) - pokeyClockCounter; + poly5Counter = (int)(((DWORD)(poly5Counter+pokeyClockCounter)) % 31) - pokeyClockCounter; + poly4_5Counter = (int)(((DWORD)(poly4_5Counter+pokeyClockCounter)) % 465) - pokeyClockCounter; + +} + +#undef SetupChannels01 +#undef SetupChannels23 + +#define SetupChannels01\ + switch( AUDCTL&0x50 )\ + {\ + case 0x00:\ + divideByN_Latch2[0] = divideByN_Latch[0]+1;\ + if( ((audioControl_Latch[0]&0xA0)==0xA0) && (divideByN_Latch2[0]<3) )\ + freq_sequre[0] = 0;\ + else\ + freq_sequre[0] = 15;\ + divideByN_Latch2[1] = divideByN_Latch[1]+1;\ + if( ((audioControl_Latch[1]&0xA0)==0xA0) && (divideByN_Latch2[1]<3) )\ + freq_sequre[1] = 0;\ + else\ + freq_sequre[1] = 15;\ + break;\ + case 0x10:\ + divideByN_Latch2[0] = divideByN_Latch[0]+1;\ + if( ((audioControl_Latch[0]&0xA0)==0xA0) && (divideByN_Latch2[0]<3) )\ + freq_sequre[0] = 0;\ + else\ + freq_sequre[0] = 15;\ + divideByN_Latch2[1] = divideByN_Latch[1]*256+divideByN_Latch2[0];\ + if( ((audioControl_Latch[1]&0xA0)==0xA0) && (divideByN_Latch2[1]<3) )\ + freq_sequre[1] = 0;\ + else\ + freq_sequre[1] = 15;\ + break;\ + case 0x40:\ + divideByN_Latch2[0] = divideByN_Latch[0]+4;\ + if( ((audioControl_Latch[0]&0xA0)==0xA0) && (divideByN_Latch2[0]<0x50) )\ + freq_sequre[0] = 0;\ + else\ + freq_sequre[0] = 15;\ + divideByN_Latch2[1] = divideByN_Latch[1]+1;\ + if( ((audioControl_Latch[1]&0xA0)==0xA0) && (divideByN_Latch2[1]<3) )\ + freq_sequre[1] = 0;\ + else\ + freq_sequre[1] = 15;\ + break;\ + case 0x50:\ + divideByN_Latch2[0] = divideByN_Latch[0]+7;\ + freq_sequre[0] = 0;\ + divideByN_Latch2[1] = divideByN_Latch[1]*256+divideByN_Latch2[0];\ + if( ((audioControl_Latch[1]&0xA0)==0xA0) && (divideByN_Latch2[1]<0x50) )\ + freq_sequre[1] = 0;\ + else\ + freq_sequre[1] = 15;\ + break;\ + } + +#define SetupChannels23\ + switch( AUDCTL&0x28 )\ + {\ + case 0x00:\ + divideByN_Latch2[2] = divideByN_Latch[2]+1;\ + if( ((audioControl_Latch[2]&0xA0)==0xA0) && (divideByN_Latch2[2]<3) )\ + freq_sequre[2] = 0;\ + else\ + freq_sequre[2] = 15;\ + divideByN_Latch2[3] = divideByN_Latch[3]+1;\ + if( ((audioControl_Latch[3]&0xA0)==0xA0) && (divideByN_Latch2[3]<3) )\ + freq_sequre[3] = 0;\ + else\ + freq_sequre[3] = 15;\ + break;\ + case 0x08:\ + divideByN_Latch2[2] = divideByN_Latch[2]+1;\ + if( ((audioControl_Latch[2]&0xA0)==0xA0) && (divideByN_Latch2[2]<3) )\ + freq_sequre[2] = 0;\ + else\ + freq_sequre[2] = 15;\ + divideByN_Latch2[3] = divideByN_Latch[3]*256+divideByN_Latch2[2];\ + if( ((audioControl_Latch[3]&0xA0)==0xA0) && (divideByN_Latch2[3]<3) )\ + freq_sequre[3] = 0;\ + else\ + freq_sequre[3] = 15;\ + break;\ + case 0x20:\ + divideByN_Latch2[2] = divideByN_Latch[2]+4;\ + if( ((audioControl_Latch[2]&0xA0)==0xA0) && (divideByN_Latch2[2]<0x50) )\ + freq_sequre[2] = 0;\ + else\ + freq_sequre[2] = 15;\ + divideByN_Latch2[3] = divideByN_Latch[3]+1;\ + if( ((audioControl_Latch[3]&0xA0)==0xA0) && (divideByN_Latch2[3]<3) )\ + freq_sequre[3] = 0;\ + else\ + freq_sequre[3] = 15;\ + break;\ + case 0x28:\ + divideByN_Latch2[2] = divideByN_Latch[2]+7;\ + freq_sequre[2] = 0;\ + divideByN_Latch2[3] = divideByN_Latch[3]*256+divideByN_Latch2[2];\ + if( ((audioControl_Latch[3]&0xA0)==0xA0) && (divideByN_Latch2[3]<0x50) )\ + freq_sequre[3] = 0;\ + else\ + freq_sequre[3] = 15;\ + break;\ + } diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/sapCpu.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/sapCpu.cpp Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,1581 @@ +#include +#include +#include +#include + +#include "sapGlobals.h" + +void cpuInit( void ) +{ + cpuReg_PC = 0xFFFF; + cpuReg_S = 0xFF; + cpuReg_A = 0x00; + cpuReg_X = 0x00; + cpuReg_Y = 0x00; + cpuSetFlags( 0x20 ); +} + + +void cpuSetFlags( BYTE flags ) +{ + cpuFlag_N = flags; + cpuFlag_V = (flags>>6)&1; + cpuFlag_B = (flags>>4)&1; + cpuFlag_D = (flags>>3)&1; + cpuFlag_I = (flags>>2)&1; + cpuFlag_Z = (flags&2)==0 ? 1:0; + cpuFlag_C = flags&1; +} + + +BYTE cpuGetFlags( void ) +{ +BYTE flags; + + flags = (cpuFlag_N&0x80) | ((cpuFlag_V&1)<<6) | 0x20 | ((cpuFlag_B&1)<<4) | ((cpuFlag_D&1)<<3) | ((cpuFlag_I&1)<<2) | (cpuFlag_Z==0 ? 2:0) | (cpuFlag_C&1); + return flags; +} + +#define CPY {\ + cB ^= 255;\ + int cpuIntValue2;\ + cpuIntValue2 = ((int)cpuReg_Y) + ((int)cB) + 1;\ + cpuFlag_N = cpuFlag_Z = (BYTE)cpuIntValue2; cpuFlag_C = (BYTE)(cpuIntValue2>>8);\ + cpuFlag_V = (( ((cpuReg_Y^cB)^0x80) & (cpuReg_Y^cpuIntValue2) & 0x80))&0x80 ? 1:0;\ + } +#define CMP {\ + cB ^= 255;\ + int cpuIntValue2;\ + cpuIntValue2 = ((int)cpuReg_A) + ((int)cB) + 1;\ + cpuFlag_N = cpuFlag_Z = (BYTE)cpuIntValue2; cpuFlag_C = (BYTE)(cpuIntValue2>>8);\ + cpuFlag_V = (( ((cpuReg_A^cB)^0x80) & (cpuReg_A^cpuIntValue2) & 0x80))&0x80 ? 1:0;\ + } +#define CPX {\ + cB ^= 255;\ + int cpuIntValue2;\ + cpuIntValue2 = ((int)cpuReg_X) + ((int)cB) + 1;\ + cpuFlag_N = cpuFlag_Z = (BYTE)cpuIntValue2; cpuFlag_C = (BYTE)(cpuIntValue2>>8);\ + cpuFlag_V = (( ((cpuReg_X^cB)^0x80) & (cpuReg_X^cpuIntValue2) & 0x80))&0x80 ? 1:0;\ + } + +#define DECCMP {\ + cB--;\ + int cpuIntValue2;\ + cpuIntValue2 = ((int)cpuReg_A) + ((int)cB^255) + 1;\ + cpuFlag_N = cpuFlag_Z = (BYTE)cpuIntValue2; cpuFlag_C = (BYTE)(cpuIntValue2>>8);\ + cpuFlag_V = (( ((cpuReg_A^cB^255)^0x80) & (cpuReg_A^cpuIntValue2) & 0x80))&0x80 ? 1:0;\ + } +#define DEC { cB--; cpuFlag_N = cpuFlag_Z = cB; } +#define INC { cB++; cpuFlag_N = cpuFlag_Z = cB; } +#define AND { cpuReg_A &= cB; cpuFlag_N = cpuFlag_Z = cpuReg_A; } +#define ASL { cpuFlag_C = cB>>7; cB<<=1; cpuFlag_N = cpuFlag_Z = cB; } +#define EOR { cpuReg_A ^= cB; cpuFlag_N = cpuFlag_Z = cpuReg_A; } +#define ORA { cpuReg_A |= cB; cpuFlag_N = cpuFlag_Z = cpuReg_A; } +#define ADC {\ + if( cpuFlag_D&1 )\ + {\ + BYTE al,ah;\ + al = (cpuReg_A & 0x0f) + (cB & 0x0f) + (cpuFlag_C&1);\ + if (al > 9) al += 6;\ + ah = ((cpuReg_A >> 4)&0x0F) + ((cB >> 4)&0x0F); if (al > 0x0f) ah++;\ + cpuFlag_N = cpuFlag_Z = cpuReg_A + cB + (cpuFlag_C&1);\ + cpuFlag_V = (((ah << 4) ^ cpuReg_A) & 0x80) && !((cpuReg_A ^ cB) & 0x80) ? 1:0;\ + if (ah > 9) ah += 6; cpuFlag_C = (ah > 0x0f) ? 1:0; cpuReg_A = (ah << 4) | (al & 0x0f);\ + }\ + else\ + {\ + WORD te;\ + te = cpuReg_A + cB + (cpuFlag_C&1);\ + cpuFlag_C = (BYTE)(te>>8);\ + cpuFlag_V = (( ((cpuReg_A^cB)^0x80) & (cpuReg_A^te) & 0x80)) ? 1:0;\ + cpuFlag_N = cpuFlag_Z = cpuReg_A = (BYTE)te;\ + }\ + } +#define SBC {\ + if( cpuFlag_D&1 )\ + {\ + BYTE al,ah; unsigned int tmp; tmp = (DWORD)cpuReg_A - (DWORD)cB - (WORD)((cpuFlag_C&1)^1);\ + al = (cpuReg_A & 0x0f) - (cB & 0x0f) - ((cpuFlag_C&1)^1);\ + ah = ((cpuReg_A >> 4)&0x0F) - ((cB >> 4)&0x0F); if (al & 0x10) { al -= 6; ah--; } if (ah & 0x10) ah -= 6;\ + cpuFlag_C = (tmp < (unsigned int)0x100) ? 1:0; cpuFlag_N = cpuFlag_Z = (BYTE)tmp;\ + cpuFlag_V = (((cpuReg_A ^ tmp) & 0x80) && ((cpuReg_A ^ cB) & 0x80) ) ? 1:0;\ + cpuReg_A = (ah << 4) | (al & 0x0f);\ + }\ + else\ + {\ + WORD te;\ + te = cpuReg_A + (cB^255) + (cpuFlag_C&1);\ + cpuFlag_C = (BYTE)(te>>8);\ + cpuFlag_V = (( ((cpuReg_A^cB^255)^0x80) & (cpuReg_A^te) & 0x80)) ? 1:0;\ + cpuFlag_N = cpuFlag_Z = cpuReg_A = (BYTE)te;\ + }\ + } +#define INCSBC {\ + cB++;\ + if( cpuFlag_D&1 )\ + {\ + BYTE al,ah; unsigned int tmp; tmp = (DWORD)cpuReg_A - (DWORD)cB - (WORD)((cpuFlag_C&1)^1);\ + al = (cpuReg_A & 0x0f) - (cB & 0x0f) - ((cpuFlag_C&1)^1);\ + ah = ((cpuReg_A >> 4)&0x0F) - ((cB >> 4)&0x0F); if (al & 0x10) { al -= 6; ah--; } if (ah & 0x10) ah -= 6;\ + cpuFlag_C = (tmp < (unsigned int)0x100) ? 1:0; cpuFlag_N = cpuFlag_Z = (BYTE)tmp;\ + cpuFlag_V = (((cpuReg_A ^ tmp) & 0x80) && ((cpuReg_A ^ cB) & 0x80) ) ? 1:0;\ + cpuReg_A = (ah << 4) | (al & 0x0f);\ + }\ + else\ + {\ + WORD te;\ + te = cpuReg_A + (cB^255) + (cpuFlag_C&1);\ + cpuFlag_C = (BYTE)(te>>8);\ + cpuFlag_V = (( ((cpuReg_A^cB^255)^0x80) & (cpuReg_A^te) & 0x80)) ? 1:0;\ + cpuFlag_N = cpuFlag_Z = cpuReg_A = (BYTE)te;\ + }\ + } + +#define ROL { BYTE cFlag; cFlag = cB>>7; cB = (cB<<1) + (cpuFlag_C&1); cpuFlag_C = cFlag; cpuFlag_N = cpuFlag_Z = cB; } +#define ROR { BYTE cFlag; cFlag = cB; cB = (cB>>1) + (cpuFlag_C<<7); cpuFlag_C = cFlag; cpuFlag_N = cpuFlag_Z = cB; } +#define LSR { cpuFlag_C = cB; cB>>=1; cpuFlag_N = cpuFlag_Z = cB; } +#define ASLORA { cpuFlag_C = cB>>7; cB<<=1; cpuReg_A |= cB; cpuFlag_N = cpuFlag_Z = cpuReg_A; } +#define ROLAND { BYTE cFlag; cFlag = cB>>7; cB = (cB<<1) + (cpuFlag_C&1); cpuFlag_C = cFlag; cpuReg_A &= cB; cpuFlag_N = cpuFlag_Z = cpuReg_A; } +#define LSREOR { cpuFlag_C = cB; cB>>=1; cpuReg_A ^= cB; cpuFlag_N = cpuFlag_Z = cpuReg_A; } +#define RORADC {\ + BYTE cC = cB; cB = (cB>>1) + (cpuFlag_C<<7); cpuFlag_C = cC;\ + if( cpuFlag_D&1 )\ + {\ + BYTE al,ah;\ + al = (cpuReg_A & 0x0f) + (cB & 0x0f) + (cpuFlag_C&1);\ + if (al > 9) al += 6;\ + ah = ((cpuReg_A >> 4)&0x0F) + ((cB >> 4)&0x0F); if (al > 0x0f) ah++;\ + cpuFlag_N = cpuFlag_Z = cpuReg_A + cB + (cpuFlag_C&1);\ + cpuFlag_V = (((ah << 4) ^ cpuReg_A) & 0x80) && !((cpuReg_A ^ cB) & 0x80) ? 1:0;\ + if (ah > 9) ah += 6; cpuFlag_C = (ah > 0x0f) ? 1:0; cpuReg_A = (ah << 4) | (al & 0x0f);\ + }\ + else\ + {\ + WORD te;\ + te = cpuReg_A + cB + (cpuFlag_C&1);\ + cpuFlag_C = (BYTE)(te>>8);\ + cpuFlag_V = (( ((cpuReg_A^cB)^0x80) & (cpuReg_A^te) & 0x80)) ? 1:0;\ + cpuFlag_N = cpuFlag_Z = cpuReg_A = (BYTE)te;\ + }\ + } + +#define CondJump( a ) cpuReg_PC += (a) ? (WORD)(signed short int)(signed char)atariMem[cpuReg_PC+1]+2:2; + +//------- + +#define FREDDIEWRITEBYTE(ad,val)\ + {\ + if( (ad&0xFF00)==0xD200 )\ + {\ + if( isStereo==false )\ + pokeyWriteByte0( ad, val );\ + else if( (ad&0x10)==0 )\ + pokeyWriteByte0( ad, val );\ + else\ + pokeyWriteByte1( ad, val );\ + }\ + else if( ad==0xD40A )\ + holded = true;\ + else atariMem[ad] = val;\ + } + +#define Load_IMD(a) BYTE cB; { cB = atariMem[cpuReg_PC+1]; cpuReg_PC+=2; a; } +#define Load_ZP(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]; cB = atariMem[cA]; cpuReg_PC+=2; a; } +#define Load_ZPX(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]+cpuReg_X; cB = atariMem[cA]; cpuReg_PC+=2; a; } +#define Load_ZPY(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]+cpuReg_Y; cB = atariMem[cA]; cpuReg_PC+=2; a; } +#define Load_ABS(a) BYTE cB; { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0]; cB = freddieReadByte(cWA); cpuReg_PC+=3; a; } +#define Load_ABSX(a) BYTE cB; { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_X; cB = freddieReadByte(cWA); cpuReg_PC+=3; a; } +#define Load_ABSY(a) BYTE cB; { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_Y; cB = freddieReadByte(cWA); cpuReg_PC+=3; a; } +#define Load_PreX(a) BYTE cB; { BYTE cA=(atariMem[cpuReg_PC+1]+cpuReg_X)&255; WORD cWA = ((WORD*)&atariMem[cA])[0]; cB = freddieReadByte(cWA); cpuReg_PC+=2; a; } +#define Load_PostY(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]; WORD cWA = ((WORD*)&atariMem[cA])[0] + (WORD)cpuReg_Y; cB = freddieReadByte(cWA); cpuReg_PC+=2; a; } + +#define LoadReg_IMD(a) { a = cpuFlag_N = cpuFlag_Z = atariMem[cpuReg_PC+1]; cpuReg_PC+=2; } +#define LoadReg_ZP(a) { BYTE cA=atariMem[cpuReg_PC+1]; a = cpuFlag_N = cpuFlag_Z = atariMem[cA]; cpuReg_PC+=2; } +#define LoadReg_ZPX(a) { BYTE cA=atariMem[cpuReg_PC+1]+cpuReg_X; a = cpuFlag_N = cpuFlag_Z = atariMem[cA]; cpuReg_PC+=2; } +#define LoadReg_ZPY(a) { BYTE cA=atariMem[cpuReg_PC+1]+cpuReg_Y; a = cpuFlag_N = cpuFlag_Z = atariMem[cA]; cpuReg_PC+=2; } +#define LoadReg_ABS(a) { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0]; a = cpuFlag_N = cpuFlag_Z = freddieReadByte(cWA); cpuReg_PC+=3; } +#define LoadReg_ABSX(a) { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_X; a = cpuFlag_N = cpuFlag_Z = freddieReadByte(cWA); cpuReg_PC+=3; } +#define LoadReg_ABSY(a) { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_Y; a = cpuFlag_N = cpuFlag_Z = freddieReadByte(cWA); cpuReg_PC+=3; } +#define LoadReg_PreX(a) { BYTE cA=(atariMem[cpuReg_PC+1]+cpuReg_X)&255; WORD cWA = ((WORD*)&atariMem[cA])[0]; a = cpuFlag_N = cpuFlag_Z = freddieReadByte(cWA); cpuReg_PC+=2; } +#define LoadReg_PostY(a) { BYTE cA=atariMem[cpuReg_PC+1]; WORD cWA = ((WORD*)&atariMem[cA])[0] + (WORD)cpuReg_Y; a = cpuFlag_N = cpuFlag_Z = freddieReadByte(cWA); cpuReg_PC+=2; } + +#define Modify_ZP(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]; cB = atariMem[cA]; cpuReg_PC+=2; a; atariMem[cA] = cB; } +#define Modify_ZPX(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]+cpuReg_X; cB = atariMem[cA]; cpuReg_PC+=2; a; atariMem[cA] = cB; } +#define Modify_ABS(a) BYTE cB; { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0]; cB = freddieReadByte(cWA); cpuReg_PC+=3; a; FREDDIEWRITEBYTE(cWA,cB); } +#define Modify_ABSX(a) BYTE cB; { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_X; cB = freddieReadByte(cWA); cpuReg_PC+=3; a; FREDDIEWRITEBYTE(cWA,cB); } +#define Modify_ABSY(a) BYTE cB; { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_Y; cB = freddieReadByte(cWA); cpuReg_PC+=3; a; FREDDIEWRITEBYTE(cWA,cB); } +#define Modify_PreX(a) BYTE cB; { BYTE cA=(atariMem[cpuReg_PC+1]+cpuReg_X)&255; WORD cWA = ((WORD*)&atariMem[cA])[0]; cB = freddieReadByte(cWA); cpuReg_PC+=2; a; FREDDIEWRITEBYTE(cWA,cB); } +#define Modify_PostY(a) BYTE cB; { BYTE cA=atariMem[cpuReg_PC+1]; WORD cWA = ((WORD*)&atariMem[cA])[0] + (WORD)cpuReg_Y; cB = freddieReadByte(cWA); cpuReg_PC+=2; a; FREDDIEWRITEBYTE(cWA,cB); } + +#define Store_ZP(a) { BYTE cA=atariMem[cpuReg_PC+1]; cpuReg_PC+=2; atariMem[cA] = a; } +#define Store_ZPX(a) { BYTE cA=atariMem[cpuReg_PC+1]+cpuReg_X; cpuReg_PC+=2; atariMem[cA] = a; } +#define Store_ABS(a) { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0]; cpuReg_PC+=3; FREDDIEWRITEBYTE(cWA,a); } +#define Store_ABSX(a) { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_X; cpuReg_PC+=3; FREDDIEWRITEBYTE(cWA,a); } +#define Store_ABSY(a) { WORD cWA = ((WORD*)&atariMem[cpuReg_PC+1])[0] + (WORD)cpuReg_Y; cpuReg_PC+=3; FREDDIEWRITEBYTE(cWA,a); } +#define Store_PreX(a) { BYTE cA=(atariMem[cpuReg_PC+1]+cpuReg_X)&255; WORD cWA = ((WORD*)&atariMem[cA])[0]; cpuReg_PC+=2; FREDDIEWRITEBYTE(cWA,a); } +#define Store_PostY(a) { BYTE cA=atariMem[cpuReg_PC+1]; WORD cWA = ((WORD*)&atariMem[cA])[0] + (WORD)cpuReg_Y; cpuReg_PC+=2; FREDDIEWRITEBYTE(cWA,a); } + +int opcode_0x00(bool &holded) /* 0x00 - BRK 7 cycles */ +{ + cpuReg_PC++; + return 20; +} +int opcode_0x01(bool &holded) /* 0x01 - ORA (,X) 6 cycles */ +{ + Load_PreX( ORA ); + return 6; +} +int opcode_0x02(bool &holded) /* 0x02 - ... hang */ +{ + return 20; +} +int opcode_0x03(bool &holded) /* 0x03 - ASL:ORA (,X) 8 cycles */ +{ + Modify_PreX( ASLORA ); + return 8; +} +int opcode_0x04(bool &holded) /* 0x04 - NOP2 3 cycles */ +{ + cpuReg_PC+=2; + return 3; +} +int opcode_0x05(bool &holded) /* 0x05 - ORA ZP 3 cycles */ +{ + Load_ZP( ORA ); + return 3; +} +int opcode_0x06(bool &holded) /* 0x06 - ASL ZP 5 cycles */ +{ + Modify_ZP( ASL ) + return 5; +} +int opcode_0x07(bool &holded) /* 0x07 - ASL:ORA ZP 5 cycles */ +{ + Modify_ZP( ASLORA ) + return 5; +} +int opcode_0x08(bool &holded) /* 0x08 - PHP 3 cycles */ +{ +BYTE te; + cpuReg_PC++; + te = (cpuFlag_N&0x80) | ((cpuFlag_V&1)<<6) | 0x20 | ((cpuFlag_B&1)<<4) | ((cpuFlag_D&1)<<3) | ((cpuFlag_I&1)<<2) | (cpuFlag_Z==0 ? 2:0) | (cpuFlag_C&1); + atariMem[0x100 + cpuReg_S] = te; cpuReg_S--; + return 3; +} +int opcode_0x09(bool &holded) /* 0x09 - ORA # 2 cycles */ +{ + Load_IMD( ORA ); + return 2; +} +int opcode_0x0A(bool &holded) /* 0x0A - ASL @ 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_C = cpuReg_A>>7; cpuReg_A<<=1; cpuFlag_N = cpuFlag_Z = cpuReg_A; + return 2; +} +int opcode_0x0B(bool &holded) /* 0x0B - ???? */ +{ + return 20; +} +int opcode_0x0C(bool &holded) /* 0x0C - NOP3 4 cycles */ +{ + cpuReg_PC+=3; + return 4; +} +int opcode_0x0D(bool &holded) /* 0x0D - ORA ABS 4 cycles */ +{ + Load_ABS( ORA ); + return 4; +} +int opcode_0x0E(bool &holded) /* 0x0E - ASL ABS 6 cycles */ +{ + Modify_ABS( ASL ); + return 6; +} +int opcode_0x0F(bool &holded) /* 0x0F - ASL:ORA ABS 6 cycles */ +{ + Modify_ABS( ASLORA ); + return 6; +} +int opcode_0x10(bool &holded) /* 0x10 - BPL 2-4 cycles */ +{ + CondJump( (cpuFlag_N&0x80)==0 ); + return 3; +} +int opcode_0x11(bool &holded) /* 0x11 - ORA (),Y 5,6 cycles */ +{ + Load_PostY( ORA ); + return 5; +} +int opcode_0x12(bool &holded) /* 0x12 - ... hang */ +{ + return 20; +} +int opcode_0x13(bool &holded) /* 0x13 - ASL:ORA (),Y 8 cycles */ +{ + Modify_PostY( ASLORA ); + return 8; +} +int opcode_0x14(bool &holded) /* 0x14 - NOP2 */ +{ + cpuReg_PC+=2; + return 3; +} +int opcode_0x15(bool &holded) /* 0x15 - ORA ZP,X 4 cycles */ +{ + Load_ZPX( ORA ); + return 4; +} +int opcode_0x16(bool &holded) /* 0x16 - ASL ZP,X 6 cycles */ +{ + Modify_ZPX( ASL ); + return 6; +} +int opcode_0x17(bool &holded) /* 0x17 - ASL:ORA ZP,X 6 cycles */ +{ + Modify_ZPX( ASLORA ); + return 6; +} +int opcode_0x18(bool &holded) /* 0x18 - CLC 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_C = 0; + return 2; +} +int opcode_0x19(bool &holded) /* 0x19 - ORA ABS,Y 4,5 cycles */ +{ + Load_ABSY( ORA ); + return 4; +} +int opcode_0x1A(bool &holded) /* 0x1A - NOP1 2 cycles */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0x1B(bool &holded) /* 0x1B - ASL:ORA ABS,Y 7 cycles */ +{ + Modify_ABSY( ASLORA ); + return 7; +} +int opcode_0x1C(bool &holded) /* 0x1C - NOP3 7 cycles */ +{ + cpuReg_PC+=3; + return 7; +} +int opcode_0x1D(bool &holded) /* 0x1D - ORA ABS,X 4,5 cycles */ +{ + Load_ABSX( ORA ); + return 4; +} +int opcode_0x1E(bool &holded) /* 0x1E - ASL ABS,X 7 cycles */ +{ + Modify_ABSX( ASL ); + return 7; +} +int opcode_0x1F(bool &holded) /* 0x1F - ASL:ORA ABS,X 7 cycles */ +{ + Modify_ABSX( ASLORA ); + return 7; +} +int opcode_0x20(bool &holded) /* 0x20 - JSR ABS 6 cycles */ +{ + cpuReg_PC+=2; + atariMem[0x100 + cpuReg_S] = (cpuReg_PC>>8)&0xFF; cpuReg_S--; + atariMem[0x100 + cpuReg_S] = cpuReg_PC&0xFF; cpuReg_S--; + cpuReg_PC = ((WORD*)&atariMem[cpuReg_PC-1])[0]; + return 6; +} +int opcode_0x21(bool &holded) /* 0x21 - AND (,X) 6 cycles */ +{ + Load_PreX( AND ); + return 6; +} +int opcode_0x22(bool &holded) /* 0x22 - ... hang */ +{ + return 20; +} +int opcode_0x23(bool &holded) /* 0x23 - ROL:AND (,X) 8 cycles */ +{ + Modify_PreX( ROLAND ); + return 8; +} +int opcode_0x24(bool &holded) /* 0x24 - BIT ZP 3 cycles */ +{ +BYTE cb; + cb = atariMem[cpuReg_PC+1]; + cpuFlag_Z = cb&cpuReg_A; cpuFlag_N = cb; cpuFlag_V = cb>>6; + cpuReg_PC+=2; + return 3; +} +int opcode_0x25(bool &holded) /* 0x25 - AND ZP 3 cycles */ +{ + Load_ZP( AND ); + return 3; +} +int opcode_0x26(bool &holded) /* 0x26 - ROL ZP 5 cycles */ +{ + Modify_ZP( ROL ); + return 5; +} +int opcode_0x27(bool &holded) /* 0x27 - ROL:AND ZP 5 cycles */ +{ + Modify_ZP( ROLAND ); + return 5; +} +int opcode_0x28(bool &holded) /* 0x28 - PLP 4 cycles */ +{ +BYTE te; + cpuReg_PC++; cpuReg_S++; te = atariMem[0x100 + cpuReg_S]; + cpuFlag_N = te; cpuFlag_V = (te>>6)&1; cpuFlag_B = (te>>4)&1; cpuFlag_D = (te>>3)&1; cpuFlag_I = (te>>2)&1; cpuFlag_Z = (te&2)^2; cpuFlag_C = te&1; + pokeyGenerateCheckIRQline(); + return 4; +} +int opcode_0x29(bool &holded) /* 0x29 - AND # 2 cycles */ +{ + Load_IMD( AND ); + return 2; +} +int opcode_0x2A(bool &holded) /* 0x2A - ROL @ 2 cycles */ +{ +BYTE cC; + cpuReg_PC++; + cC = cpuReg_A>>7; cpuReg_A = (cpuReg_A<<1) + (cpuFlag_C&1); cpuFlag_C = cC; cpuFlag_N = cpuFlag_Z = cpuReg_A; + return 2; +} +int opcode_0x2B(bool &holded) /* 0x2B - ???? */ +{ + return 20; +} +int opcode_0x2C(bool &holded) /* 0x2C - BIT ABS 4 cycles */ +{ +BYTE cb; + cb = atariMem[((WORD*)&atariMem[cpuReg_PC+1])[0]]; + cpuFlag_Z = cb&cpuReg_A; cpuFlag_N = cb; cpuFlag_V = cb>>6; + cpuReg_PC+=3; + return 4; +} +int opcode_0x2D(bool &holded) /* 0x2D - AND ABS 4 cycles */ +{ + Load_ABS( AND ); + return 4; +} +int opcode_0x2E(bool &holded) /* 0x2E - ROL ABS 6 cycles */ +{ + Modify_ABS( ROL ); + return 6; +} +int opcode_0x2F(bool &holded) /* 0x2F - ROL:AND ABS 6 cycles */ +{ + Modify_ABS( ROLAND ); + return 6; +} +int opcode_0x30(bool &holded) /* 0x30 - BMI 2-4 cycles */ +{ + CondJump( (cpuFlag_N&0x80) ); + return 2; +} +int opcode_0x31(bool &holded) /* 0x31 - AND (),Y 5,6 cycles */ +{ + Load_PostY( AND ); + return 5; +} +int opcode_0x32(bool &holded) /* 0x32 - ... hang */ +{ + return 20; +} +int opcode_0x33(bool &holded) /* 0x33 - ROL:AND (),Y 8 cycles */ +{ + Modify_PostY( ROLAND ); + return 8; +} +int opcode_0x34(bool &holded) /* 0x34 - NOP2 */ +{ + cpuReg_PC+=2; + return 8; +} +int opcode_0x35(bool &holded) /* 0x35 - AND ZP,X 4 cycles */ +{ + Load_ZPX( AND ); + return 4; +} +int opcode_0x36(bool &holded) /* 0x36 - ROL ZP,X 6 cycles */ +{ + Modify_ZPX( ROL ); + return 6; +} +int opcode_0x37(bool &holded) /* 0x37 - ROL:AND ZP,X 6 cycles */ +{ + Modify_ZPX( ROLAND ); + return 6; +} +int opcode_0x38(bool &holded) /* 0x38 - SEC 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_C = 1; + return 2; +} +int opcode_0x39(bool &holded) /* 0x39 - AND ABS,Y 4,5 cycles */ +{ + Load_ABSY( AND ); + return 4; +} +int opcode_0x3A(bool &holded) /* 0x3A - NOP1 */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0x3B(bool &holded) /* 0x3B - ROL:AND ABS,Y 7 cycles */ +{ + Modify_ABSY( ROLAND ); + return 7; +} +int opcode_0x3C(bool &holded) /* 0x3C - NOP3 */ +{ + cpuReg_PC+=3; + return 4; +} +int opcode_0x3D(bool &holded) /* 0x3D - AND ABS,X 4,5 cycles */ +{ + Load_ABSX( AND ); + return 4; +} +int opcode_0x3E(bool &holded) /* 0x3E - ROL ABS,X 7 cycles */ +{ + Modify_ABSX( ROL ); + return 7; +} +int opcode_0x3F(bool &holded) /* 0x3F - ROL:AND ABS,X 7 cycles */ +{ + Modify_ABSX( ROLAND ); + return 7; +} +int opcode_0x40(bool &holded) /* 0x40 - RTI 6 cycles */ +{ +BYTE te; + cpuReg_PC++; + cpuReg_S++; te = atariMem[0x100 + cpuReg_S]; + cpuFlag_N = te; cpuFlag_V = (te>>6)&1; cpuFlag_B = (te>>4)&1; cpuFlag_D = (te>>3)&1; cpuFlag_I = (te>>2)&1; cpuFlag_Z = (te&2)^2; cpuFlag_C = te&1; + cpuReg_S++; cpuReg_PC = (WORD)atariMem[0x100 + cpuReg_S]; + cpuReg_S++; cpuReg_PC+= ((WORD)atariMem[0x100 + cpuReg_S])*256; + return 6; +} +int opcode_0x41(bool &holded) /* 0x41 - EOR (,X) 6 cycles */ +{ + Load_PreX( EOR ); + return 6; +} +int opcode_0x42(bool &holded) /* 0x42 - ... hang */ +{ + return 20; +} +int opcode_0x43(bool &holded) /* 0x43 - LSR:EOR (,X) 8 cycles */ +{ + Modify_PreX( LSREOR ); + return 8; +} +int opcode_0x44(bool &holded) /* 0x44 - NOP2 3 cycles */ +{ + cpuReg_PC+=2; + return 3; +} +int opcode_0x45(bool &holded) /* 0x45 - EOR ZP 3 cycles */ +{ + Load_ZP( EOR ); + return 3; +} +int opcode_0x46(bool &holded) /* 0x46 - LSR ZP 5 cycles */ +{ + Modify_ZP( LSR ); + return 5; +} +int opcode_0x47(bool &holded) /* 0x47 - LSR:EOR ZP 5 cycles */ +{ + Modify_ZP( LSREOR ); + return 5; +} +int opcode_0x48(bool &holded) /* 0x48 - PHA 3 cycles */ +{ + cpuReg_PC++; + atariMem[0x100 + cpuReg_S] = cpuReg_A; cpuReg_S--; + return 3; +} +int opcode_0x49(bool &holded) /* 0x49 - EOR # 2 cycles */ +{ + Load_IMD( EOR ); + return 2; +} +int opcode_0x4A(bool &holded) /* 0x4A - LSR @ 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_C = cpuReg_A; cpuReg_A>>=1; cpuFlag_N = cpuFlag_Z = cpuReg_A; + return 2; +} +int opcode_0x4B(bool &holded) /* 0x4B - ???? */ +{ + cpuReg_PC--; + return 20; +} +int opcode_0x4C(bool &holded) /* 0x4C - JMP 3 cycles */ +{ + cpuReg_PC = ((WORD*)&atariMem[cpuReg_PC+1])[0]; + return 3; +} +int opcode_0x4D(bool &holded) /* 0x4D - EOR ABS 4 cycles */ +{ + Load_ABS( EOR ); + return 4; +} +int opcode_0x4E(bool &holded) /* 0x4E - LSR ABS 6 cycles */ +{ + Modify_ABS( LSR ); + return 6; +} +int opcode_0x4F(bool &holded) /* 0x4F - LSR:EOR ABS 6 cycles */ +{ + Modify_ABS( LSREOR ); + return 6; +} + +int opcode_0x50(bool &holded) /* 0x50 - BVC 2-4 cycles */ +{ + CondJump( (cpuFlag_V&1)==0 ); + return 2; +} + +int opcode_0x51(bool &holded) /* 0x51 - EOR (),Y 5 cycles */ +{ + Load_PostY( EOR ); + return 5; +} +int opcode_0x52(bool &holded) /* 0x52 - ... hang */ +{ + return 20; +} +int opcode_0x53(bool &holded) /* 0x53 - LSR:EOR (),Y 8 cycles */ +{ + Modify_PostY( LSREOR ); + return 8; +} +int opcode_0x54(bool &holded) /* 0x54 - NOP2 */ +{ + cpuReg_PC+=2; + return 3; +} +int opcode_0x55(bool &holded) /* 0x55 - EOR ZP,X 4 cycles */ +{ + Load_ZPX( EOR ); + return 4; +} +int opcode_0x56(bool &holded) /* 0x56 - LSR ZP,X 6 cycles */ +{ + Modify_ZPX( LSR ); + return 6; +} +int opcode_0x57(bool &holded) /* 0x57 - LSR:EOR ZP,X 6 cycles */ +{ + Modify_ZPX( LSREOR ); + return 6; +} +int opcode_0x58(bool &holded) /* 0x58 - CLI 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_I = 0; + pokeyGenerateCheckIRQline(); + return 2; +} +int opcode_0x59(bool &holded) /* 0x59 - EOR ABS,Y 4,5 cycles */ +{ + Load_ABSY( EOR ); + return 4; +} +int opcode_0x5A(bool &holded) /* 0x5A - NOP1 2 cycles */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0x5B(bool &holded) /* 0x5B - LSR:EOR ABS,Y 7 cycles */ +{ + Modify_ABSY( EOR ); + return 7; +} +int opcode_0x5C(bool &holded) /* 0x5C - NOP3 7 cycles */ +{ + cpuReg_PC+=3; + return 7; +} +int opcode_0x5D(bool &holded) /* 0x5D - EOR ABS,X 4,5 cycles */ +{ + Load_ABSX( EOR ); + return 4; +} +int opcode_0x5E(bool &holded) /* 0x5E - LSR ABS,X 7 cycles */ +{ + Modify_ABSX( EOR ); + return 7; +} +int opcode_0x5F(bool &holded) /* 0x5F - LSR:EOR ABS,X 7 cycles */ +{ + Modify_ABSX( LSREOR ); + return 7; +} + +int opcode_0x60(bool &holded) /* 0x60 - RTS 6 cycles */ +{ + cpuReg_S++; cpuReg_PC = (WORD)atariMem[0x100 + cpuReg_S]; + cpuReg_S++; cpuReg_PC+= ((WORD)atariMem[0x100 + cpuReg_S])*256 + 1; + return 6; +} +int opcode_0x61(bool &holded) /* 0x61 - ADC (,X) 6 cycles */ +{ + Load_PreX( ADC ); + return 6; +} +int opcode_0x62(bool &holded) /* 0x62 - ... hang */ +{ + return 20; +} +int opcode_0x63(bool &holded) /* 0x63 - ROR:ADC (,X) 8 cycles */ +{ + Modify_PreX( RORADC ); + return 8; +} +int opcode_0x64(bool &holded) /* 0x64 - NOP2 3 cycles */ +{ + cpuReg_PC+=2; + return 3; +} +int opcode_0x65(bool &holded) /* 0x65 - ADC ZP 3 cycles */ +{ + Load_ZP( ADC ); + return 3; +} +int opcode_0x66(bool &holded) /* 0x66 - ROR ZP 5 cycles */ +{ + Modify_ZP( ROR ); + return 5; +} +int opcode_0x67(bool &holded) /* 0x67 - ROR:ADC ZP 5 cycles */ +{ + Modify_ZP( RORADC ); + return 5; +} +int opcode_0x68(bool &holded) /* 0x68 - PLA 4 cycles */ +{ + cpuReg_PC++; + cpuReg_S++; cpuFlag_N = cpuFlag_Z = cpuReg_A = atariMem[0x100 + cpuReg_S]; + return 4; +} +int opcode_0x69(bool &holded) /* 0x69 - ADC # 2 cycles */ +{ + Load_IMD( ADC ); + return 2; +} +int opcode_0x6A(bool &holded) /* 0x6A - ROR @ 2 cycles */ +{ +BYTE cC; + cpuReg_PC++; + cC = cpuReg_A; cpuReg_A = (cpuReg_A>>1) + (cpuFlag_C<<7); cpuFlag_C = cC; cpuFlag_N = cpuFlag_Z = cpuReg_A; + return 2; +} +int opcode_0x6B(bool &holded) /* 0x6B - ???? */ +{ + return 20; +} +int opcode_0x6C(bool &holded) /* 0x6C - JMP ( ) 6 cycles */ +{ + WORD wA = ((WORD*)&atariMem[cpuReg_PC+1])[0]; + wA = ((WORD*)&atariMem[wA])[0]; + cpuReg_PC = wA; + return 6; +} +int opcode_0x6D(bool &holded) /* 0x6D - ADC ABS 4 cycles */ +{ + Load_ABS( ADC ); + return 4; +} +int opcode_0x6E(bool &holded) /* 0x6E - ROR ABS 6 cycles */ +{ + Modify_ABS( ROR ); + return 6; +} +int opcode_0x6F(bool &holded) /* 0x6F - ROR:ADC ABS 6 cycles */ +{ + Modify_ABS( RORADC ); + return 6; +} +int opcode_0x70(bool &holded) /* 0x70 - BVS 2-4 cycles */ +{ + CondJump( (cpuFlag_V&1) ); + return 2; +} +int opcode_0x71(bool &holded) /* 0x71 - ADC ( ),Y 5,6 cycles */ +{ + Load_PostY( ADC ); + return 5; +} +int opcode_0x72(bool &holded) /* 0x72 - ... hang */ +{ + return 20; +} +int opcode_0x73(bool &holded) /* 0x73 - ROR:ADC ( ),Y 8 cycles */ +{ + Modify_PostY( RORADC ); + return 8; +} +int opcode_0x74(bool &holded) /* 0x74 - NOP2 4 cycles */ +{ + return 4; +} +int opcode_0x75(bool &holded) /* 0x75 - ADC ZP,X 4 cycles */ +{ + Load_ZPX( ADC ); + return 4; +} +int opcode_0x76(bool &holded) /* 0x76 - ROR ZP,X 6 cycles */ +{ + Modify_ZPX( ROR ); + return 6; +} +int opcode_0x77(bool &holded) /* 0x77 - ROR:ADC ZP,X 6 cycles */ +{ + Modify_ZPX( RORADC ); + return 6; +} +int opcode_0x78(bool &holded) /* 0x78 - SEI 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_I = 1; + return 2; +} +int opcode_0x79(bool &holded) /* 0x79 - ADC ABS,Y 4,5 cycles */ +{ + Load_ABSY( ADC ); + return 4; +} +int opcode_0x7A(bool &holded) /* 0x7A - NOP1 2 cycles */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0x7B(bool &holded) /* 0x7B - ROR:ADC ABS,Y 6 cycles */ +{ + Modify_ABSY( RORADC ); + return 6; +} +int opcode_0x7C(bool &holded) /* 0x7C - NOP3 7 cycles */ +{ + cpuReg_PC+=3; + return 7; +} +int opcode_0x7D(bool &holded) /* 0x7D - ADC ABS,X 4,5 cycles */ +{ + Load_ABSX( ADC ); + return 4; +} +int opcode_0x7E(bool &holded) /* 0x7E - ROR ABS,X 7 cycles */ +{ + Modify_ABSX( ROR ); + return 7; +} +int opcode_0x7F(bool &holded) /* 0x7F - ROR:ADC ABS,X 7 cycles */ +{ + Modify_ABSX( RORADC ); + return 7; +} + +int opcode_0x80(bool &holded) /* 0x80 - NOP2 2 cycles */ +{ + cpuReg_PC+=2; + return 2; +} +int opcode_0x81(bool &holded) /* 0x81 - STA ( ,X) 6 cycles */ +{ + Store_PreX( cpuReg_A ); + return 6; +} +int opcode_0x82(bool &holded) /* 0x82 - NOP2 2 cycles */ +{ + cpuReg_PC+=2; + return 2; +} +int opcode_0x83(bool &holded) /* 0x83 - STORE(A&X) (,X) 6 cycles */ +{ + Store_PreX( (cpuReg_A&cpuReg_X) ); + return 6; +} +int opcode_0x84(bool &holded) /* 0x84 - STY ZP 3 cycles */ +{ + atariMem[atariMem[cpuReg_PC+1]] = cpuReg_Y; + cpuReg_PC+=2; + return 3; +} +int opcode_0x85(bool &holded) /* 0x85 - STA ZP 3 cycles */ +{ + atariMem[atariMem[cpuReg_PC+1]] = cpuReg_A; + cpuReg_PC+=2; + return 3; +} +int opcode_0x86(bool &holded) /* 0x86 - STX ZP 3 cycles */ +{ + atariMem[atariMem[cpuReg_PC+1]] = cpuReg_X; + cpuReg_PC+=2; + return 3; +} +int opcode_0x87(bool &holded) /* 0x87 - STORE(A&X) ZP 3 cycles */ +{ + atariMem[atariMem[cpuReg_PC+1]] = cpuReg_A&cpuReg_X; + cpuReg_PC+=2; + return 3; +} +int opcode_0x88(bool &holded) /* 0x88 - DEY 2 cycles */ +{ + cpuReg_PC++; + cpuReg_Y--; + cpuFlag_N = cpuFlag_Z = cpuReg_Y; + return 2; +} +int opcode_0x89(bool &holded) /* 0x89 - NOP2 2 cycles */ +{ + cpuReg_PC+=2; + return 2; +} +int opcode_0x8A(bool &holded) /* 0x8A - TXA 2 cycles */ +{ + cpuReg_PC+=1; + cpuFlag_N = cpuFlag_Z = cpuReg_A = cpuReg_X; + return 2; +} +int opcode_0x8B(bool &holded) /* 0x8B - TXA:AND # 2 cycles */ +{ + cpuReg_A = cpuReg_X; + cpuFlag_N = cpuFlag_Z = cpuReg_A = cpuReg_A & atariMem[cpuReg_PC+1]; + cpuReg_PC+=2; + return 2; +} +int opcode_0x8C(bool &holded) /* 0x8C - STY ABS 4 cycles */ +{ + Store_ABS( cpuReg_Y ); + return 4; +} +int opcode_0x8D(bool &holded) /* 0x8D - STA ABS 4 cycles */ +{ + Store_ABS( cpuReg_A ); + return 4; +} +int opcode_0x8E(bool &holded) /* 0x8E - STX ABS 4 cycles */ +{ + Store_ABS( cpuReg_X ); + return 4; +} +int opcode_0x8F(bool &holded) /* 0x8F - STORE(A&X) ABS 4 cycles */ +{ + Store_ABS( (cpuReg_A&cpuReg_X) ); + return 4; +} +int opcode_0x90(bool &holded) /* 0x90 - BCC 2-4 cycles */ +{ + CondJump( (cpuFlag_C&1)==0 ); + return 2; +} +int opcode_0x91(bool &holded) /* 0x91 - STA ( ),Y 6 cycles */ +{ + Store_PostY( cpuReg_A ); + return 6; +} +int opcode_0x92(bool &holded) /* 0x92 - ... hang */ +{ + return 20; +} +int opcode_0x93(bool &holded) /* 0x93 - STORE(A&X) (),Y 4,5 cycles */ +{ + Store_PostY( (cpuReg_A&cpuReg_X) ); + return 6; +} +int opcode_0x94(bool &holded) /* 0x94 - STY ZP,X 4 cycles */ +{ + atariMem[(atariMem[cpuReg_PC+1]+cpuReg_X)&0xFF] = cpuReg_Y; + cpuReg_PC+=2; + return 4; +} +int opcode_0x95(bool &holded) /* 0x95 - STA ZP,X 4 cycles */ +{ + atariMem[(atariMem[cpuReg_PC+1]+cpuReg_X)&0xFF] = cpuReg_A; + cpuReg_PC+=2; + return 4; +} +int opcode_0x96(bool &holded) /* 0x96 - STX ZP,Y 4 cycles */ +{ + atariMem[(atariMem[cpuReg_PC+1]+cpuReg_Y)&0xFF] = cpuReg_X; + cpuReg_PC+=2; + return 4; +} +int opcode_0x97(bool &holded) /* 0x97 - STORE(A&X) ZP,Y 4 cycles */ +{ + atariMem[(atariMem[cpuReg_PC+1]+cpuReg_Y)&0xFF] = cpuReg_X&cpuReg_A; + cpuReg_PC+=2; + return 4; +} +int opcode_0x98(bool &holded) /* 0x98 - TYA 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_A = cpuReg_Y; + return 2; +} +int opcode_0x99(bool &holded) /* 0x99 - STA ABS,Y 5 cycles */ +{ + Store_ABSY( cpuReg_A ); + return 5; +} +int opcode_0x9A(bool &holded) /* 0x9A - TXS 2 cycles */ +{ + cpuReg_PC++; + cpuReg_S = cpuReg_X; + return 2; +} +int opcode_0x9B(bool &holded) /* 0x9B - ???? */ +{ + return 20; +} +int opcode_0x9C(bool &holded) /* 0x9C - ???? */ +{ + return 20; +} +int opcode_0x9D(bool &holded) /* 0x9D - STA ABS,X 5 cycles */ +{ + Store_ABSX( cpuReg_A ); + return 5; +} +int opcode_0x9E(bool &holded) /* 0x9E - ???? */ +{ + return 20; +} +int opcode_0x9F(bool &holded) /* 0x9F - ???? */ +{ + return 20; +} +int opcode_0xA0(bool &holded) /* 0xA0 - LDY # 2 cycles */ +{ + LoadReg_IMD( cpuReg_Y ); + return 2; +} +int opcode_0xA1(bool &holded) /* 0xA1 - LDA (,X) 6 cycles */ +{ + LoadReg_PreX( cpuReg_A ); + return 6; +} +int opcode_0xA2(bool &holded) /* 0xA2 - LDX # 2 cycles */ +{ + LoadReg_IMD( cpuReg_X ); + return 2; +} +int opcode_0xA3(bool &holded) /* 0xA3 - LDA:TAX (,X) 6 cycles */ +{ + LoadReg_IMD( cpuReg_A ); + cpuReg_X = cpuReg_A; + return 6; +} +int opcode_0xA4(bool &holded) /* 0xA4 - LDY ZP 3 cycles */ +{ + LoadReg_ZP( cpuReg_Y ); + return 3; +} +int opcode_0xA5(bool &holded) /* 0xA5 - LDA ZP 3 cycles */ +{ + LoadReg_ZP( cpuReg_A ); + return 3; +} +int opcode_0xA6(bool &holded) /* 0xA6 - LDX ZP 3 cycles */ +{ + LoadReg_ZP( cpuReg_X ); + return 3; +} +int opcode_0xA7(bool &holded) /* 0xA7 - LDA:TAX ZP 3 cycles */ +{ + LoadReg_ZP( cpuReg_A ); + cpuReg_X = cpuReg_A; + return 3; +} +int opcode_0xA8(bool &holded) /* 0xA8 - TAY 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_Y = cpuReg_A; + return 2; +} +int opcode_0xA9(bool &holded) /* 0xA9 - LDA # 2 cycles */ +{ + LoadReg_IMD( cpuReg_A ); + return 2; +} +int opcode_0xAA(bool &holded) /* 0xAA - TAX 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_X = cpuReg_A; + return 2; +} +int opcode_0xAB(bool &holded) /* 0xAB - AND #:TAX 2 cycles */ +{ + cpuFlag_N = cpuFlag_Z = cpuReg_A = cpuReg_X = cpuReg_A & atariMem[cpuReg_PC+1]; + cpuReg_PC+=2; + return 2; +} +int opcode_0xAC(bool &holded) /* 0xAC - LDY ABS 4 cycles */ +{ + LoadReg_ABS( cpuReg_Y ); + return 4; +} +int opcode_0xAD(bool &holded) /* 0xAD - LDA ABS 4 cycles */ +{ + LoadReg_ABS( cpuReg_A ); + return 4; +} +int opcode_0xAE(bool &holded) /* 0xAE - LDX ABS 4 cycles */ +{ + LoadReg_ABS( cpuReg_X ); + return 4; +} +int opcode_0xAF(bool &holded) /* 0xAF - LDA:TAX ABS 4 cycles */ +{ + LoadReg_ABS( cpuReg_A ); + cpuReg_X = cpuReg_A; + return 4; +} +int opcode_0xB0(bool &holded) /* 0xB0 - BCS 2-4 cycles */ +{ + CondJump( (cpuFlag_C&1) ); + return 2; +} +int opcode_0xB1(bool &holded) /* 0xB1 - LDA ( ),Y 5,6 cycles */ +{ + LoadReg_PostY( cpuReg_A ); + return 5; +} +int opcode_0xB2(bool &holded) /* 0xB2 - ... hang */ +{ + return 20; +} +int opcode_0xB3(bool &holded) /* 0xB3 - LDA:TAX ( ),Y 5,6 cycles */ +{ + LoadReg_PostY( cpuReg_A ); + cpuReg_X = cpuReg_A; + return 5; +} +int opcode_0xB4(bool &holded) /* 0xB4 - LDY ZP,X 4 cycles */ +{ + LoadReg_ZPX( cpuReg_Y ); + return 4; +} +int opcode_0xB5(bool &holded) /* 0xB5 - LDA ZP,X 4 cycles */ +{ + LoadReg_ZPX( cpuReg_A ); + return 4; +} +int opcode_0xB6(bool &holded) /* 0xB6 - LDX ZP,Y 4 cycles */ +{ + LoadReg_ZPY( cpuReg_X ); + return 4; +} +int opcode_0xB7(bool &holded) /* 0xB7 - LDA:TAX ZP,Y 4 cycles */ +{ + LoadReg_ZPY( cpuReg_X ); + cpuReg_A = cpuReg_X; + return 4; +} +int opcode_0xB8(bool &holded) /* 0xB8 - CLV 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_V = 0; + return 2; +} +int opcode_0xB9(bool &holded) /* 0xB9 - LDA ABS,Y 4,5 cycles */ +{ + LoadReg_ABSY( cpuReg_A ); + return 4; +} +int opcode_0xBA(bool &holded) /* 0xBA - TSX 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_X = cpuReg_S; + return 2; +} +int opcode_0xBB(bool &holded) /* 0xBB - ???? */ +{ + return 20; +} +int opcode_0xBC(bool &holded) /* 0xBC - LDY ABS,X 4,5 cycles */ +{ + LoadReg_ABSX( cpuReg_Y ); + return 4; +} +int opcode_0xBD(bool &holded) /* 0xBD - LDA ABS,X 4,5 cycles */ +{ + LoadReg_ABSX( cpuReg_A ); + return 4; +} +int opcode_0xBE(bool &holded) /* 0xBE - LDX ABS,Y 4,5 cycles */ +{ + LoadReg_ABSY( cpuReg_X ); + return 4; +} +int opcode_0xBF(bool &holded) /* 0xBF - LDA:TAX ABS,Y 4,5 cycles */ +{ + LoadReg_ABSY( cpuReg_X ); + cpuReg_A = cpuReg_X; + return 4; +} +int opcode_0xC0(bool &holded) /* 0xC0 - CPY # 2 cycles */ +{ + Load_IMD( CPY ); + return 2; +} +int opcode_0xC1(bool &holded) /* 0xC1 - CMP (,X) 6 cycles */ +{ + Load_PreX( CMP ); + return 6; +} +int opcode_0xC2(bool &holded) /* 0xC2 - NOP2 2 cycles */ +{ + cpuReg_PC+=2; + return 2; +} +int opcode_0xC3(bool &holded) /* 0xC3 - DEC:CMP (,X) 8 cycles */ +{ + Modify_PreX( DECCMP ); + return 8; +} +int opcode_0xC4(bool &holded) /* 0xC4 - CPY ZP 3 cycles */ +{ + Load_ZP( CPY ); + return 3; +} +int opcode_0xC5(bool &holded) /* 0xC5 - CMP ZP 3 cycles */ +{ + Load_ZP( CMP ); + return 3; +} +int opcode_0xC6(bool &holded) /* 0xC6 - DEC ZP 5 cycles */ +{ + Modify_ZP( DEC ); + return 5; +} +int opcode_0xC7(bool &holded) /* 0xC7 - DEC:CMP ZP 5 cycles */ +{ + Modify_ZP( DECCMP ); + return 8; +} +int opcode_0xC8(bool &holded) /* 0xC8 - INY 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_Y = cpuReg_Y+1; + return 2; +} +int opcode_0xC9(bool &holded) /* 0xC9 - CMP # 2 cycles */ +{ + Load_IMD( CMP ); + return 2; +} +int opcode_0xCA(bool &holded) /* 0xCA - DEX 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_X = cpuReg_X-1; + return 2; +} +int opcode_0xCB(bool &holded) /* 0xCB - ???? */ +{ + return 20; +} +int opcode_0xCC(bool &holded) /* 0xCC - CPY ABS 4 cycles */ +{ + Load_ABS( CPY ); + return 4; +} +int opcode_0xCD(bool &holded) /* 0xCD - CMP ABS 4 cycles */ +{ + Load_ABS( CMP ); + return 4; +} +int opcode_0xCE(bool &holded) /* 0xCE - DEC ABS 6 cycles */ +{ + Modify_ABS( DEC ); + return 6; +} +int opcode_0xCF(bool &holded) /* 0xCF - DEC:CMP ABS 6 cycles */ +{ + Modify_ABS( DECCMP ); + return 6; +} +int opcode_0xD0(bool &holded) /* 0xD0 - BNE 2-4 cycles */ +{ + CondJump( cpuFlag_Z ); + return 2; +} +int opcode_0xD1(bool &holded) /* 0xD1 - CMP (),Y 5,6 cycles */ +{ + Load_PostY( CMP ); + return 5; +} +int opcode_0xD2(bool &holded) /* 0xD2 - ... hang */ +{ + return 20; +} +int opcode_0xD3(bool &holded) /* 0xD3 - DEC:CMP (),Y 8 cycles */ +{ + Modify_PostY( DECCMP ); + return 8; +} +int opcode_0xD4(bool &holded) /* 0xD4 - NOP2 4 cycles */ +{ + cpuReg_PC+=2; + return 4; +} +int opcode_0xD5(bool &holded) /* 0xD5 - CMP ZP,X 4 cycles */ +{ + Load_ZPX( CMP ); + return 4; +} +int opcode_0xD6(bool &holded) /* 0xD6 - DEC ZP,X 6 cycles */ +{ + Modify_ZPX( DEC ); + return 6; +} +int opcode_0xD7(bool &holded) /* 0xD7 - DEC:CMP ZP,X 6 cycles */ +{ + Modify_ZPX( DECCMP ); + return 6; +} +int opcode_0xD8(bool &holded) /* 0xD8 - CLD 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_D = 0; + return 2; +} +int opcode_0xD9(bool &holded) /* 0xD9 - CMP ABS,Y 4,5 cycles */ +{ + Load_ABSY( CMP ); + return 4; +} +int opcode_0xDA(bool &holded) /* 0xDA - NOP1 2 cycles */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0xDB(bool &holded) /* 0xDB - DEC:CMP ABS,Y 7 cycles */ +{ + Modify_ABSY( DECCMP ); + return 7; +} +int opcode_0xDC(bool &holded) /* 0xDC - NOP3 4 cycles */ +{ + cpuReg_PC+=3; + return 4; +} +int opcode_0xDD(bool &holded) /* 0xDD - CMP ABS,X 4,5 cycles */ +{ + Load_ABSX( CMP ); + return 4; +} +int opcode_0xDE(bool &holded) /* 0xDE - DEC ABS,X 7 cycles */ +{ + Modify_ABSX( DEC ); + return 7; +} +int opcode_0xDF(bool &holded) /* 0xDF - DEC:CMP ABS,X 7 cycles */ +{ + Modify_ABSX( DECCMP ); + return 7; +} +int opcode_0xE0(bool &holded) /* 0xE0 - CPX # 2 cycles */ +{ + Load_IMD( CPX ); + return 2; +} +int opcode_0xE1(bool &holded) /* 0xE1 - SBC (,X) 6 cycles */ +{ + Load_PreX( SBC ); + return 6; +} +int opcode_0xE2(bool &holded) /* 0xE2 - NOP2 2 cycles */ +{ + cpuReg_PC+=2; + return 2; +} +int opcode_0xE3(bool &holded) /* 0xE3 - INC:SBC (,X) 8 cycles */ +{ + Modify_PreX( INCSBC ); + return 8; +} +int opcode_0xE4(bool &holded) /* 0xE4 - CPX ZP 3 cycles */ +{ + Load_ZP( CPX ); + return 3; +} +int opcode_0xE5(bool &holded) /* 0xE5 - SBC ZP 3 cycles */ +{ + Load_ZP( SBC ); + return 3; +} +int opcode_0xE6(bool &holded) /* 0xE6 - INC ZP 5 cycles */ +{ + Modify_ZP( INC ); + return 5; +} +int opcode_0xE7(bool &holded) /* 0xE7 - INC:SBC ZP 5 cycles */ +{ + Modify_ZP( INCSBC ); + return 5; +} +int opcode_0xE8(bool &holded) /* 0xE8 - INX 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_N = cpuFlag_Z = cpuReg_X = cpuReg_X+1; + return 2; +} +int opcode_0xE9(bool &holded) /* 0xE9 - SBC # 2 cycles */ +{ + Load_IMD( SBC ); + return 2; +} +int opcode_0xEA(bool &holded) /* 0xEA - NOP 2 cycles */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0xEB(bool &holded) /* 0xEB - ???? */ +{ + return 20; +} +int opcode_0xEC(bool &holded) /* 0xEC - CPX ABS 4 cycles */ +{ + Load_ABS( CPX ); + return 4; +} +int opcode_0xED(bool &holded) /* 0xED - SBC ABS 4 cycles */ +{ + Load_ABS( SBC ); + return 4; +} +int opcode_0xEE(bool &holded) /* 0xEE - INC ABS 6 cycles */ +{ + Modify_ABS( INC ); + return 6; +} +int opcode_0xEF(bool &holded) /* 0xEF - INC:SBC ABS 6 cycles */ +{ + Modify_ABS( INCSBC ); + return 6; +} +int opcode_0xF0(bool &holded) /* 0xF0 - BEQ 2-4 cycles */ +{ + CondJump( (cpuFlag_Z==0) ); + return 2; +} +int opcode_0xF1(bool &holded) /* 0xF1 - SBC (),Y 5,6 cycles */ +{ + Load_PostY( SBC ); + return 5; +} +int opcode_0xF2(bool &holded) /* 0xF2 - ... hang */ +{ + return 20; +} +int opcode_0xF3(bool &holded) /* 0xF3 - INC:SBC (),Y 8 cycles */ +{ + Modify_PostY( INCSBC ); + return 8; +} +int opcode_0xF4(bool &holded) /* 0xF4 - NOP2 4 cycles */ +{ + cpuReg_PC+=2; + return 4; +} +int opcode_0xF5(bool &holded) /* 0xF5 - SBC ZP,X 4 cycles */ +{ + Load_ZPX( SBC ); + return 4; +} +int opcode_0xF6(bool &holded) /* 0xF6 - INC ZP,X 6 cycles */ +{ + Modify_ZPX( INC ); + return 6; +} +int opcode_0xF7(bool &holded) /* 0xF7 - INC:SBC ZP,X 6 cycles */ +{ + Modify_ZPX( INCSBC ); + return 6; +} +int opcode_0xF8(bool &holded) /* 0xF8 - SED 2 cycles */ +{ + cpuReg_PC++; + cpuFlag_D = 1; + return 2; +} +int opcode_0xF9(bool &holded) /* 0xF9 - SBC ABS,Y 4,5 cycles */ +{ + Load_ABSY( SBC ); + return 4; +} +int opcode_0xFA(bool &holded) /* 0xFA - NOP1 2 cycles */ +{ + cpuReg_PC++; + return 2; +} +int opcode_0xFB(bool &holded) /* 0xFB - INC:SBC ABS,Y 7 cycles */ +{ + Modify_ABSY( INCSBC ); + return 7; +} +int opcode_0xFC(bool &holded) /* 0xDC - NOP3 4 cycles */ +{ + cpuReg_PC+=3; + return 4; +} +int opcode_0xFD(bool &holded) /* 0xFD - SBC ABS,X 4,5 cycles */ +{ + Load_ABSX( SBC ); + return 4; +} +int opcode_0xFE(bool &holded) /* 0xFE - INC ABS,X 7 cycles */ +{ + Modify_ABSX( INC ); + return 7; +} +int opcode_0xFF(bool &holded) /* 0xDF - INC:SBC ABS,X 7 cycles */ +{ + Modify_ABSX( INCSBC ); + return 7; +} + +opcodeFunc opcodes_0x00_0xFF[256]={ + &opcode_0x00, &opcode_0x01, &opcode_0x02, &opcode_0x03, &opcode_0x04, &opcode_0x05, &opcode_0x06, &opcode_0x07, + &opcode_0x08, &opcode_0x09, &opcode_0x0A, &opcode_0x0B, &opcode_0x0C, &opcode_0x0D, &opcode_0x0E, &opcode_0x0F, + &opcode_0x10, &opcode_0x11, &opcode_0x12, &opcode_0x13, &opcode_0x14, &opcode_0x15, &opcode_0x16, &opcode_0x17, + &opcode_0x18, &opcode_0x19, &opcode_0x1A, &opcode_0x1B, &opcode_0x1C, &opcode_0x1D, &opcode_0x1E, &opcode_0x1F, + &opcode_0x20, &opcode_0x21, &opcode_0x22, &opcode_0x23, &opcode_0x24, &opcode_0x25, &opcode_0x26, &opcode_0x27, + &opcode_0x28, &opcode_0x29, &opcode_0x2A, &opcode_0x2B, &opcode_0x2C, &opcode_0x2D, &opcode_0x2E, &opcode_0x2F, + &opcode_0x30, &opcode_0x31, &opcode_0x32, &opcode_0x33, &opcode_0x34, &opcode_0x35, &opcode_0x36, &opcode_0x37, + &opcode_0x38, &opcode_0x39, &opcode_0x3A, &opcode_0x2B, &opcode_0x3C, &opcode_0x3D, &opcode_0x3E, &opcode_0x3F, + &opcode_0x40, &opcode_0x41, &opcode_0x42, &opcode_0x43, &opcode_0x44, &opcode_0x45, &opcode_0x46, &opcode_0x47, + &opcode_0x48, &opcode_0x49, &opcode_0x4A, &opcode_0x4B, &opcode_0x4C, &opcode_0x4D, &opcode_0x4E, &opcode_0x4F, + &opcode_0x50, &opcode_0x51, &opcode_0x52, &opcode_0x53, &opcode_0x54, &opcode_0x55, &opcode_0x56, &opcode_0x57, + &opcode_0x58, &opcode_0x59, &opcode_0x5A, &opcode_0x5B, &opcode_0x5C, &opcode_0x5D, &opcode_0x5E, &opcode_0x5F, + &opcode_0x60, &opcode_0x61, &opcode_0x62, &opcode_0x63, &opcode_0x64, &opcode_0x65, &opcode_0x66, &opcode_0x67, + &opcode_0x68, &opcode_0x69, &opcode_0x6A, &opcode_0x6B, &opcode_0x6C, &opcode_0x6D, &opcode_0x6E, &opcode_0x6F, + &opcode_0x70, &opcode_0x71, &opcode_0x72, &opcode_0x73, &opcode_0x74, &opcode_0x75, &opcode_0x76, &opcode_0x77, + &opcode_0x78, &opcode_0x79, &opcode_0x7A, &opcode_0x7B, &opcode_0x7C, &opcode_0x7D, &opcode_0x7E, &opcode_0x7F, + &opcode_0x80, &opcode_0x81, &opcode_0x82, &opcode_0x83, &opcode_0x84, &opcode_0x85, &opcode_0x86, &opcode_0x87, + &opcode_0x88, &opcode_0x89, &opcode_0x8A, &opcode_0x8B, &opcode_0x8C, &opcode_0x8D, &opcode_0x8E, &opcode_0x8F, + &opcode_0x90, &opcode_0x91, &opcode_0x92, &opcode_0x93, &opcode_0x94, &opcode_0x95, &opcode_0x96, &opcode_0x97, + &opcode_0x98, &opcode_0x99, &opcode_0x9A, &opcode_0x9B, &opcode_0x9C, &opcode_0x9D, &opcode_0x9E, &opcode_0x9F, + &opcode_0xA0, &opcode_0xA1, &opcode_0xA2, &opcode_0xA3, &opcode_0xA4, &opcode_0xA5, &opcode_0xA6, &opcode_0xA7, + &opcode_0xA8, &opcode_0xA9, &opcode_0xAA, &opcode_0xAB, &opcode_0xAC, &opcode_0xAD, &opcode_0xAE, &opcode_0xAF, + &opcode_0xB0, &opcode_0xB1, &opcode_0xB2, &opcode_0xB3, &opcode_0xB4, &opcode_0xB5, &opcode_0xB6, &opcode_0xB7, + &opcode_0xB8, &opcode_0xB9, &opcode_0xBA, &opcode_0xBB, &opcode_0xBC, &opcode_0xBD, &opcode_0xBE, &opcode_0xBF, + &opcode_0xC0, &opcode_0xC1, &opcode_0xC2, &opcode_0xC3, &opcode_0xC4, &opcode_0xC5, &opcode_0xC6, &opcode_0xC7, + &opcode_0xC8, &opcode_0xC9, &opcode_0xCA, &opcode_0xCB, &opcode_0xCC, &opcode_0xCD, &opcode_0xCE, &opcode_0xCF, + &opcode_0xD0, &opcode_0xD1, &opcode_0xD2, &opcode_0xD3, &opcode_0xD4, &opcode_0xD5, &opcode_0xD6, &opcode_0xD7, + &opcode_0xD8, &opcode_0xD9, &opcode_0xDA, &opcode_0xDB, &opcode_0xDC, &opcode_0xDD, &opcode_0xDE, &opcode_0xDF, + &opcode_0xE0, &opcode_0xE1, &opcode_0xE2, &opcode_0xE3, &opcode_0xE4, &opcode_0xE5, &opcode_0xE6, &opcode_0xE7, + &opcode_0xE8, &opcode_0xE9, &opcode_0xEA, &opcode_0xEB, &opcode_0xEC, &opcode_0xED, &opcode_0xEE, &opcode_0xEF, + &opcode_0xF0, &opcode_0xF1, &opcode_0xF2, &opcode_0xF3, &opcode_0xF4, &opcode_0xF5, &opcode_0xF6, &opcode_0xF7, + &opcode_0xF8, &opcode_0xF9, &opcode_0xFA, &opcode_0xFB, &opcode_0xFC, &opcode_0xFD, &opcode_0xFE, &opcode_0xFF, +}; + diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/sapEngine.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/sapEngine.cpp Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,657 @@ +#include +#include +#include +#include + +#define __MAIN_DECLARATIONS__ + +#include "sapGlobals.h" + +#include "sapLib.h" + +namespace _SAP_internals_ { + +void playerCallSubroutine( WORD address ); +void playerProcessOneFrame( void ); + +volatile int prSbp; +volatile int musicAddress,playerAddress,playerInit,playerType,defSong,fastPlay; +volatile BOOL fileLoadStatus=FALSE; + +char inputBuffer[65536]; +char commentBuffer[65536]; + +sapMUSICstrc currentMusic; + +BYTE emulEmptyLine[]={ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +} + +using namespace _SAP_internals_; + +sapMUSICstrc *sapLoadMusicFile( char *fname ) +{ +BOOL formatKnown,binaryFile; int i; +int numOfSongs; + + fileLoadStatus = FALSE; + if( fname==NULL ) + return NULL; + + cpuInit( ); + pokeyInit( ); + pokeyReset( ); + prSbp = 0; + sndBufPtr = 0; + memset( sndBuf, 0, sizeof(sndBuf) ); + commentBuffer[0] = 0; + memset( atariMem, 0, sizeof(atariMem) ); + atariMem[0x0000] = 0xFF; // CMC bug. + atariMem[0xFEFF] = 0xFF; // CMC bug. +// atariMem[0xFFFE] = 0xFF; // CMC bug. +// atariMem[0xFFFF] = 0xFF; // CMC bug. + + isStereo = false; + sampleStep = 1; + formatKnown = FALSE; binaryFile = FALSE; + musicAddress = playerAddress = playerType = numOfSongs = defSong = fastPlay = -1; + FILE *inpf; + inpf = fopen( fname, "rb" ); + if( inpf!=NULL ) + { + BYTE blkHead[4]; WORD blkBegin = 0,blkEnd = 0; int blk; + + blk = 0; i = 0; + while( 1 ) + { + int val; val = fgetc( inpf ); + if( formatKnown==FALSE ) + { + if( (val==EOF) || (i>=4) ) + { + // error + break; + } + if( (val==0x0A) || (val==0x0D) ) + { + inputBuffer[i] = 0; + if( strcmp( inputBuffer, "SAP" )!=0 ) + { + // error + break; + } + // headerID is OK + i = 0; + formatKnown = TRUE; + continue;; + } + inputBuffer[i++] = (char)val; + } + else if( binaryFile==FALSE ) + { + if( val==EOF ) + { + // error + break; + } + if( val==0xFF ) + { + if( i!=0 ) + { + // error. There wasn't EOL in this line + break; + } + // so this is the end of header + binaryFile = TRUE; + blkHead[blk++] = (BYTE)val; + continue; + } + if( (val==0x0A) || (val==0x0D) ) + { + if( i==0 ) + continue; + inputBuffer[i++] = 0; + char *codes[]={ "PLAYER", "MUSIC", "INIT", "TYPE", "SONGS", "DEFSONG", "FASTPLAY", "STEREO", "TIME", NULL }; + int j,k,a; + for( j=0;; j++ ) + { + if( codes[j]==NULL ) + break; + k = 0; + while( 1 ) + { + if( k>=i ) + { + // not this code + i = 0; + break; + } + if( (codes[j][k]==0) && ((inputBuffer[k]==' ') || (inputBuffer[k]==0)) ) + { + // found + switch( j ) + { + case 0: // player address + a = strtol( &inputBuffer[k], NULL, 16 ); + if( (a==0) || (a>0xFFFF) ) + { + // error + i = 0; + goto cont; + } + playerAddress = a; + i = 0; + goto cont; + break; + case 1: // music address + a = strtol( &inputBuffer[k], NULL, 16 ); + if( (a==0) || (a>0xFFFF) ) + { + // error + i = 0; + goto cont; + } + musicAddress = a; + i = 0; + goto cont; + break; + case 2: // binary player init + a = strtol( &inputBuffer[k], NULL, 16 ); + if( (a==0) || (a>0xFFFF) ) + { + // error + i = 0; + goto cont; + } + playerInit = a; + i = 0; + goto cont; + break; + case 3: // player type + while( inputBuffer[k]!=0 ) + { + if( (inputBuffer[k]=='B') || (inputBuffer[k]=='b') ) + { + playerType = 'b'; + break; + } + if( (inputBuffer[k]=='C') || (inputBuffer[k]=='c') ) + { + playerType = 'c'; + break; + } + if( (inputBuffer[k]=='D') || (inputBuffer[k]=='d') ) + { + playerType = 'd'; + break; + } + if( (inputBuffer[k]=='S') || (inputBuffer[k]=='s') ) + { + playerType = 's'; + break; + } + if( !isspace(inputBuffer[k]) ) + { + i = 0; + goto cont; + } + k++; + } + i = 0; + goto cont; + break; + case 4: // num of songs + a = strtol( &inputBuffer[k], NULL, 10 ); + if( (a==0) || (a>0xFFFF) ) + { + // error + i = 0; + goto cont; + } + numOfSongs = a; + sprintf( &commentBuffer[ strlen(commentBuffer) ], "Number of songs = %d\n", numOfSongs ); + i = 0; + goto cont; + break; + case 5: // default songs + a = strtol( &inputBuffer[k], NULL, 10 ); + if( (a==0) || (a>0xFFFF) ) + { + // error + i = 0; + goto cont; + } + defSong = a; + i = 0; + goto cont; + break; + case 6: // fastPlay + a = strtol( &inputBuffer[k], NULL, 10 ); + if( (a==0) || (a>0xFFFF) ) + { + // error + i = 0; + goto cont; + } + fastPlay = a; + i = 0; + goto cont; + break; + case 7: // Stereo + isStereo = true; + sampleStep = 2; + sprintf( &commentBuffer[ strlen(commentBuffer) ], "In Stereo!\n" ); + i = 0; + goto cont; + break; + case 8: // Time + { + int min,sec; + min = sec = -1; + sscanf( &inputBuffer[k], "%d:%d", &min, &sec ); + if( min==-1 || sec==-1 ) + { + i = 0; + goto cont; + } + sprintf( &commentBuffer[ strlen(commentBuffer) ], "Time in sec %d\n", min*60+sec ); + i = 0; + goto cont; + break; + } + } + i = 0; + goto cont; + } + if( codes[j][k]==0 ) + break; // not this code + if( codes[j][k]!=inputBuffer[k] ) + break; // not this code + k++; + } + } + sprintf( &commentBuffer[ strlen(commentBuffer) ], "%s\n", inputBuffer ); + // not found + i = 0; + continue; + } + inputBuffer[i++] = (char)val; + } + else if( binaryFile==TRUE ) + { + if( val==EOF ) + { + if( blk==0 ) + { + fileLoadStatus = TRUE; + break; // OK + } + // error + break; + } + if( blk<4 ) + { + blkHead[blk++] = (BYTE)val; + if( blk==2 ) + { + if( (blkHead[0]&blkHead[1])==255 ) + blk = 0; + } + if( blk==4 ) + { + blkBegin = ((WORD)blkHead[0]) + ((WORD)blkHead[1])*256; + blkEnd = ((WORD)blkHead[2]) + ((WORD)blkHead[3])*256; + } + } + else + { + atariMem[blkBegin] = (BYTE)val; + if( blkBegin==blkEnd ) + { + blk = 0; + } + blkBegin++; + } + } + cont:; + + } + fclose( inpf ); + + } + if( playerType==-1 ) + return NULL; + fileLoadStatus = TRUE; + + currentMusic.defSong = defSong; + currentMusic.numOfSongs = numOfSongs; + + + currentMusic.commentBuffer = &commentBuffer[0]; + currentMusic.currentTimeIn50Sec = 0; + +// sapPlaySong( defSong ); + return ¤tMusic; +} + + +void sapPlaySong( int numOfSong ) +{ + + if( fileLoadStatus==FALSE ) + return; + + if( numOfSong==-1 ) + numOfSong = 0; + numOfSong &= 0xFF; + numOfSong = numOfSong % currentMusic.numOfSongs; + + sndBufPtr = prSbp = 0; + switch( playerType ) + { + case 'c': + if( (playerAddress==-1) || (musicAddress==-1) ) + { + fileLoadStatus = FALSE; + break; + } + cpuReg_S = 0xFF; + cpuReg_A = 0x70; + cpuReg_X = (musicAddress&0xFF); + cpuReg_Y = (musicAddress>>8)&0xFF; + playerCallSubroutine( playerAddress+3 ); + cpuReg_S = 0xFF; + cpuReg_A = 0x00; + cpuReg_X = numOfSong; + playerCallSubroutine( playerAddress+3 ); + break; + case 'b': + case 'm': + if( (playerInit==-1) || (playerAddress==-1) ) + { + fileLoadStatus = FALSE; + break; + } + cpuReg_S = 0xFF; + cpuReg_A = numOfSong; + playerCallSubroutine( playerInit ); + break; + case 'd': + if( (playerInit==-1) || (playerAddress==-1) ) + { + fileLoadStatus = FALSE; + break; + } + cpuReg_S = 0xFF; + cpuReg_PC = 0xFFFF; + cpuReg_PC--; + atariMem[0x100 + cpuReg_S] = (cpuReg_PC>>8)&0xFF; cpuReg_S--; + atariMem[0x100 + cpuReg_S] = cpuReg_PC&0xFF; cpuReg_S--; + cpuReg_PC = playerInit; + cpuReg_A = numOfSong; + cpuReg_X = 0; + cpuReg_Y = 0; + cpuSetFlags( 0x20 ); + break; + case 's': + if( (playerInit==-1) || (playerAddress==-1) ) + { + fileLoadStatus = FALSE; + break; + } + cpuReg_S = 0xFF; + cpuReg_PC = playerInit; + cpuReg_A = 0; + cpuReg_X = 0; + cpuReg_Y = 0; + cpuSetFlags( 0x20 ); + break; + } +} + + +void _SAP_internals_::playerCallSubroutine( WORD address ) +{ +int i,k; + + cpuReg_PC = 0xFFFF; + cpuReg_PC--; + atariMem[0x100 + cpuReg_S] = (cpuReg_PC>>8)&0xFF; cpuReg_S--; + atariMem[0x100 + cpuReg_S] = cpuReg_PC&0xFF; cpuReg_S--; + cpuReg_PC = address; + k = 0; + bool holded; + while(k<1000000) + { + BYTE opcode = atariMem[ cpuReg_PC ]; + i = opcodes_0x00_0xFF[opcode](holded); + k+=i; + if( i>10 ) + return; + if( cpuReg_PC==0xFFFF ) + break; + } + k++; +} + +extern bool *generateIRQ0; +int numsPerFrame; + +void _SAP_internals_::playerProcessOneFrame( void ) +{ +int ilp = 0; +BYTE oldFlags = 0,oldA = 0,oldX = 0,oldY = 0,oldS = 0; +WORD oldPC = 0; +BOOL notRestored = 0; +bool holded; +int cycleInLine,lineInFrame; + + numsPerFrame = 0; + + if( playerType=='d' ) + { + oldFlags = cpuGetFlags(); + oldA = cpuReg_A; + oldX = cpuReg_X; + oldY = cpuReg_Y; + oldPC = cpuReg_PC; + oldS = cpuReg_S; + notRestored = TRUE; + } + if( playerType=='s' ) + { + + } + + if( playerType!='s' ) + { + cpuReg_S = 0x8F; + cpuReg_PC = 0xFFFF; + cpuReg_PC--; + atariMem[0x100 + cpuReg_S] = (cpuReg_PC>>8)&0xFF; cpuReg_S--; + atariMem[0x100 + cpuReg_S] = cpuReg_PC&0xFF; cpuReg_S--; + } + + switch( playerType ) + { + case 'c': + cpuReg_PC = playerAddress+6; + break; + case 'b': + case 'd': + case 'm': + cpuReg_PC = playerAddress; + break; + } + cycleInLine = 0; + if( fastPlay!=-1 ) + lineInFrame = 0; + else if( playerType=='s' ) + lineInFrame = 0; + else + lineInFrame = 248; + holded = false; + pokeyUpdateSoundCounters(); + + while(1) + { + if( cpuReg_PC!=0xFFFF ) + { + BYTE opcode = atariMem[ cpuReg_PC ]; + ilp = opcodes_0x00_0xFF[opcode](holded); + if( ilp>10 ) + return; // not supported instruction has been executed + if( (playerType=='b') || (playerType=='c') ) + ilp = 1; + } + else + { + if( playerType=='d' ) + { + if( notRestored==TRUE ) + { + notRestored = FALSE; + cpuReg_PC = oldPC; + cpuReg_A = oldA; + cpuReg_X = oldX; + cpuReg_Y = oldY; + cpuSetFlags( oldFlags ); + cpuReg_S = oldS; + } + } + else + { + do { + pokeyUpdateSound(114); + lineInFrame++; + currentMusic.currentTimeIn50Sec++; + if( fastPlay!=-1 ) + { + if( lineInFrame==fastPlay ) + { + pokeyUpdateSoundCounters(); + goto bre; + } + } + else + { + if( lineInFrame==248 ) + { + pokeyUpdateSoundCounters(); + goto bre; + } + if( lineInFrame==312 ) + { + lineInFrame=0; + pokeyUpdateSoundCounters(); + } + } + } while(1); + } + } + again: + for(;ilp>0;ilp--) + { + if( cycleInLine>=103-9 ) + { + if( cycleInLine==103-9 ) + { + if( holded ) + { + ilp = 0; + holded = false; + } + } + if( cycleInLine==113-9 ) + { + pokeyUpdateSound(114); + cycleInLine = -1; + lineInFrame++; + currentMusic.currentTimeIn50Sec++; + if( fastPlay!=-1 ) + { + if( lineInFrame==fastPlay ) + { + pokeyUpdateSoundCounters(); + goto bre; + } + } + else if( playerType=='s' ) + { + if( lineInFrame==78 ) + { + pokeyUpdateSoundCounters(); + atariMem[0x45]--; + if( atariMem[0x45]==0 ) + atariMem[0xB07B]++; + goto bre; + } + } + else + { + if( lineInFrame==248 ) + { + pokeyUpdateSoundCounters(); + goto bre; + } + if( lineInFrame==312 ) + { + lineInFrame=0; + pokeyUpdateSoundCounters(); + } + } + ANTIC_VCOUNT_D40B = (BYTE)(lineInFrame / 2); + } + } + cycleInLine++; + } + if( holded ) + { + ilp=114-9; + goto again; + } + if( generateIRQ0[0] ) + { + generateIRQ0[0] = false; + pokeyGenerateIRQ(1); + numsPerFrame++; + } + } + bre:; +} + + +void sapRenderBuffer( short int *buffer, int number_of_samples ) +{ +int i; + + if( fileLoadStatus==FALSE ) + return; + + i = 0; + number_of_samples *= sampleStep; + while( i=number_of_samples ) + break; + i++; + } + } +} + diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/sapGlobals.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/sapGlobals.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,89 @@ +#ifdef __MAIN_DECLARATIONS__ +#define axeEXTERN +#else +#define axeEXTERN extern +#endif + +#ifndef BYTE +#define BYTE unsigned char +#endif +#ifndef WORD +#define WORD unsigned short int +#endif +#ifndef DWORD +#define DWORD unsigned long int +#endif +#ifndef BOOL +#define BOOL int +#endif +#define TRUE 1 +#define FALSE 0 + +axeEXTERN bool isStereo; +axeEXTERN int sampleStep; + +extern void pokeyGenerateCheckIRQline(void); +extern void pokeyGenerateIRQ( BYTE irqMask ); + +axeEXTERN BYTE atariMem[ 0x10000 ]; +axeEXTERN WORD sndBuf[16384]; +axeEXTERN int sndBufPtr; + +axeEXTERN BYTE ANTIC_VCOUNT_D40B; + +axeEXTERN WORD cpuReg_PC; +axeEXTERN BYTE cpuFlag_N,cpuFlag_Z,cpuFlag_C,cpuFlag_D,cpuFlag_B,cpuFlag_I,cpuFlag_V,cpuReg_A,cpuReg_X,cpuReg_Y,cpuReg_S; +// cpuFlag_N is valid only in last bit-7 +// cpuFlag_Z is set if whole cpuFlag_Z is not zero +// cpuFlag_C is valid only in first bit-0 +// cpuFlag_D is valid only in first bit-0 +// cpuFlag_B is valid only in first bit-0 +// cpuFlag_I is valid only in first bit-0 +// cpuFlag_V is valid only in first bit-0 + + +extern void cpuInit( void ); +extern int cpuExecuteOneOpcode( void ); +extern BYTE cpuGetFlags( void ); +extern void cpuSetFlags( BYTE flags ); + +extern void pokeyInit( void ); +extern void pokeyReset( void ); +extern BYTE pokeyReadByte( short unsigned int address ); +extern void pokeyWriteByte0( short unsigned int address, BYTE value ); +extern void pokeyWriteByte1( short unsigned int address, BYTE value ); +extern void pokeyUpdateSound( int n ); +extern void pokeyUpdateSoundCounters( void ); + +inline BYTE freddieReadByte( WORD ad ) +{ + if( (ad&0xF800)==0xD000 ) + { + if( (ad&0xFF00)==0xD200 ) + { + return pokeyReadByte( ad ); + } + if( (ad&0xFF0F)==0xD40B ) + return ANTIC_VCOUNT_D40B; + } + return atariMem[ad]; +} +inline BYTE freddieCPUReadByte( WORD ad ) +{ + return atariMem[ad]; +} + +inline void freddieWriteByte( WORD ad, BYTE val ) +{ + if( (ad&0xFF00)==0xD200 ) + { + if( ((ad&0x10)==0) || (isStereo==false) ) pokeyWriteByte0( ad, val ); + else pokeyWriteByte1( ad, val ); + return; + } + atariMem[ad] = val; +} + +typedef int (*opcodeFunc)(bool &holded); + +extern opcodeFunc opcodes_0x00_0xFF[256]; diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/sapLib.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/sapLib.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,19 @@ +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + int numOfSongs; + int defSong; + char *commentBuffer; + int currentTimeIn50Sec; +} sapMUSICstrc; + +sapMUSICstrc *sapLoadMusicFile( char *fname ); +void sapPlaySong( int numOfSong ); +void sapRenderBuffer( short int *buffer, int number_of_samples ); + +#ifdef __cplusplus +} +#endif + diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/saplib/sapPokey.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/saplib/sapPokey.cpp Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include + +#include "sapGlobals.h" + +extern void pokeyInit0( void ); +extern void pokeyInit1( void ); +extern void pokeyReset0( void ); +extern void pokeyReset1( void ); +extern void pokeyUpdateSound0( int n ); +extern void pokeyUpdateSound1( int n ); +extern void pokeyUpdateSoundCounters0( void ); +extern void pokeyUpdateSoundCounters1( void ); + +void pokeyInit( void ) +{ + pokeyInit0(); + pokeyInit1(); +} +void pokeyReset( void ) +{ + pokeyReset0(); + pokeyReset1(); +} + +void pokeyUpdateSound( int n ) +{ +int oldBufPtr = sndBufPtr; + pokeyUpdateSound0( n ); + if( isStereo ) + { + sndBufPtr = (oldBufPtr+1)&16383; + pokeyUpdateSound1( n ); + sndBufPtr = (sndBufPtr-1)&16383; + } +} + +void pokeyUpdateSoundCounters( void ) +{ + pokeyUpdateSoundCounters0(); + pokeyUpdateSoundCounters1(); +} + +BYTE pokeyReadByte( short unsigned int address) +{ +BYTE retVal; + + switch( address&0x0F ) + { + case 0x09: + return 0xFF; + case 0x0A: + retVal = (BYTE)((255*rand())/RAND_MAX); + return retVal; + case 0x0E: + return 0xFF; + case 0x0F: + return 0xFF; + } + return 0xFF; +} diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/scripts/gen_symbols --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/scripts/gen_symbols Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,4 @@ +#! /bin/sh +/usr/bin/nm -B $1 | sed -n -e 's/^.*[ ]\([ABCDGISTW][ABCDGISTW]*\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' | sed 's/.* //' | sort | uniq > symbols +egrep -e "get_.plugin_info" "symbols" > syms +rm -f symbols \ No newline at end of file diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/syms --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/syms Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,1 @@ +get_iplugin_info diff -r 6d1f65117180 -r c0b31cf2c7cd src/sap/version.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/sap/version.h Sun Oct 29 01:08:30 2006 -0700 @@ -0,0 +1,21 @@ +/* + * SAP xmms plug-in. + * Copyright 2002/2003 by Michal 'Mikey' Szwaczko + * + * SAP Library ver. 1.56 by Adam Bienias + * + * This is free software. You can modify it and distribute it under the terms + * of the GNU General Public License. The verbatim text of the license can + * be found in file named COPYING in the source directory. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ +#define VERSION "0.3F" +#define SAP_VER "1.56"