From cd61d997688c71e8eeecf39e4ce9d77a08872d7b Mon Sep 17 00:00:00 2001 From: Shamus Hammons Date: Mon, 25 Aug 2003 18:15:38 +0000 Subject: [PATCH] Changes for upcoming 1.0.5 release --- INSTALL | 30 +++---- docs/README | 48 ++++++----- docs/TODO | 23 +++-- docs/WHATSNEW | 22 +++++ src/dsp.cpp | 4 +- src/gui.cpp | 173 +++++++++++++++++++++++++++++++++++++ src/include/gui.h | 2 + src/include/jaguar.h | 2 +- src/include/tom.h | 28 +++--- src/jaguar.cpp | 131 ++++++---------------------- src/objectp.cpp | 8 -- src/tom.cpp | 166 +++++++++++++++++------------------- src/vj.cpp | 199 +++++-------------------------------------- 13 files changed, 388 insertions(+), 448 deletions(-) diff --git a/INSTALL b/INSTALL index a1ef2ea..ab1456b 100644 --- a/INSTALL +++ b/INSTALL @@ -1,30 +1,28 @@ -Virtual Jaguar v1.0.4 GCC/SDL release INSTALL +Virtual Jaguar v1.0.5 GCC/SDL release INSTALL --------------------------------------------- -- Requirements : +REQUIREMENTS: To compile Virtual Jaguar you need to check if you have the minimum -requirements for compiling the sources : +requirements for compiling the sources: - GCC v2.95 of v3.x; - SDL v1.2.5 or higher; -- nasm v0.98.x or higher; -- supported OS (BeOS, Linux, FreeBSD and WIN32 through mingw); - other OS' may work to but you may need to change some items - in the Makefile(s). +- ZLIB v1.1.4 +- supported OS (BeOS, Linux, FreeBSD and WIN32 through mingw); other OS' may + work to but you may need to change some items in the Makefile(s). -Optionally you need a Atari Jaguar (CD) boot ROM which is available -on the Internet. We can't include the boot ROM since it's still -copyrighted. +Optionally you need a Atari Jaguar (CD) boot ROM which is available on the +Internet. We can't include the boot ROM since it's still copyrighted. -Also, I would recommend that you have at least 20MB of free space. -The .o's can be quite big and the binary is likely to be about a -1.5MB in size (with UPX or strip this could downsize to about 800K). +Also, I would recommend that you have at least 20MB of free space. The .o's +can be quite big and the binary is likely to be about a 1.5MB in size (with +UPX or strip this could downsize to about 800K). -- Compiling : +COMPILING: If you sure you have the minimum software requirements, you can safely -compile Virtual Jaguar v1.0.4 GCC/SDL release by doing the following : +compile Virtual Jaguar v1.0.4 GCC/SDL release by doing the following: 1) Compile: @@ -40,6 +38,6 @@ That's it! You're done! You can now start the emulator with ./vj. See the output for more details or consult the docs/README for more info. For more info, go to http://sdlemu.ngemu.com or send use an e-mail to the -following e-mail address : sdlemu AT ngemu DOT com. +following e-mail address: sdlemu AT ngemu DOT com. SDLEMU diff --git a/docs/README b/docs/README index 163514b..869e1be 100644 --- a/docs/README +++ b/docs/README @@ -1,14 +1,16 @@ -Virtual Jaguar v1.0.0 GCC/SDL release README +Virtual Jaguar v1.0.5 GCC/SDL release README -------------------------------------------- - DISCLAIMER - +Or, "O liability, I do disclaim thee!" + Ported by SDLEMU (Niels Wagenaar & Caz) and is based upon the original work from Potato Emulation. For requirements please consult the INSTALL file for -more information about supported OS' and software requirements. +more information about supported OS's and software requirements. The use of this software is entirely at your own risk. We can't be held -responsible for damage done to you hard- and/or software. This software +responsible for damage done to you hardware and/or software. This software requires the use of the Atari Jaguar (CD) boot ROM and/or Commercial ROM images. You may only use the ROM images if you own the cartridges itself. The use of Commercial ROM's without owning the original cartridge is @@ -18,26 +20,26 @@ This software is released under the GPL license. For more information I should direct you to the GPL.TXT. You may hack/change the code anyway you like. You may not commercially sell this software. -If you make changes, release the sourcecode to the public and send us the +If you make changes, release the source code to the public and send us the changes you made to the original authors. The products and brands used in these documents and/or sourcecode are owned -but the desired company in question. +by the desired company in question. - What is Virtual Jaguar GCC/SDL? Virtual Jaguar is software dedicated to emulate the Atari Jaguar hardware on you standard P.C. The software was originally developed by Potato Emulation -(http://potato.emu-france.com) and was released under the GPL license on -25 June 2003. +(http://potato.emu-france.com) by Cal2 and was released under the GPL license +on 25 June 2003. Virtual Jaguar GCC/SDL is a port of the MS Visual C++/SDL sourcecode so that we can enjoy Atari Jaguar emulation on every platform which uses the GCC -compiler and what can make use of the Simple Directmedia Layer library (SDL). +compiler and that can make use of the Simple Directmedia Layer library (SDL). -Currently Virtual Jaguar GCC/SDL compiles on WIN32, using mingw, and several +Currently Virtual Jaguar GCC/SDL compiles on WIN32 using mingw, and several UN*X based systems (BeOS, Linux and FreeBSD). It may run on other systems -as well but we can not garantee that. +as well but we can not guarantee that. The port was done by the SDLEMU crew (http://sdlemu.ngemu.com) and especially by Niels Wagenaar and Caz. You may contact us by e-mail (sdlemu@ngemu.com) or @@ -50,36 +52,36 @@ More information about SDL can be found at http://www.libsdl.org. After compiling the binary (see INSTALL) you can now run original Atari Jaguar games. These games are distributed on cartridges and can there for not be used on a P.C. To use these games on Virtual Jaguar GCC/SDL you need to get ROM -images. Besides that ROM imgaes from Commercial games you must also obtain the +images. Besides that ROM images from Commercial games you must also obtain the Atari Jaguar (CD) boot ROM which you must copy to the BIOS directory. For legal issues concerning ROM images please consult the DISCLAIMER at the beginning of this file. -After obaining the Atari Jaguar (CD) boot ROM and several ROM's you can now -use Virtual Jaguar using the following command : +After obtaining the Atari Jaguar (CD) boot ROM and several ROM's you can now +use Virtual Jaguar using the following command: -./vj romfile -switch +./vj [romfile] [-switches] The context of ROMFILE is the filename of the an Atari Jaguar ROM dump (can be either compressed or uncompressed). You can also use switches. By just typing -./vj you get an overview of the options you can use. WIN32 users should look -into the stdout.txt for that information. +./vj -? you get an overview of the options you can use. WIN32 users should look +into the stdout.txt for that information. If you have a directory full of ROM +files, then you can type + +./vj [directory with ROM files] [-switches] -If you succesfully start the emulator with the game you should see a window -(or fullscreen) which shows the game. If the game doesn't comply to a CRC -check the game will display a black screen, this means that the game is -probably a hack or a new game which isn't supported. You may add the CRC -check to the sources yourself (src/crc32.cpp). +and Virtual Jaguar will pull up a simple file selector to allow you to choose +which ROM file you want to use. This emulator also emulates the Atari Jaguar Analog gamepads. By using the -following keyboard or joystick settings you can (possibly) play the game : +following keyboard or joystick settings you can (possibly) play the game: Atari Button C : Z or joystick button 3 Atari Button B : X or joystick button 2 Atari Button A : C or joystick button 1 Atari Buttons 1 - 10 : Keypad 0 - 9 (0 = 10) Atari Start/Pause : ENTER -Atari Select : TAB +Atari Select : ' Atari UP : UP or joystick UP Atari DOWN : DOWN or joystick DOWN Atari LEFT : LEFT or joystick LEFT diff --git a/docs/TODO b/docs/TODO index aa9687d..e3ddacd 100644 --- a/docs/TODO +++ b/docs/TODO @@ -1,8 +1,8 @@ Stuff to add/fix for the next release of Virtual Jaguar ------------------------------------------------------- -- Would be nice to have a GUI for ROM selection, perhaps even for things - that are set on the command line. [Shamus] +- Would be nice to have a GUI for things that are set on the command line. + [Shamus] - Would also be nice to be able to dynamically change the keybindings for the various keys on the emulated Jaguar controller while inside the emulator. [Shamus] @@ -12,17 +12,22 @@ Stuff to add/fix for the next release of Virtual Jaguar - We need a comprehensive way of determining what gets written where and by whom (i.e., blitter wrote to range $F03000-$F03230) in order to figure out the remaining problems with various ROMs. [Shamus] -- Sound needs a rewrite. With SDL, this shouldn't be much of a problem. - Of course, whoever does this should realize that the PCM outs are probably - not being used for a majority of the ROMs out there--according to the JTRM, - you're supposed to use the I2S interface to output sound since the PCM outs - aren't even physically hooked up in the console! [Shamus] - There is a bug either with the GPU or the blitter (most likely the latter) which causes the spinning "A"s in the BIOS startup code to be corrupted when they are showing their backsides. [Shamus] -- Need to rewrite the main Jaguar execution loop to increment the VC by one - instead of by two, which is how the real Jaguar works. [Shamus] +- We need to have an external configuration file for remembering a user's + preferences, such as key bindings, etc. [Shamus] +- We need to come up with a way to fix the aspect ratio for pixel modes that + aren't square (PWIDTH != 4). [Shamus] Stuff that was added/fixed -------------------------- +- GUI for ROM selection [Shamus] [DONE--Shamus] +- Need to rewrite the main Jaguar execution loop to increment the VC by one + instead of by two, which is how the real Jaguar works. [Shamus] [DONE--Shamus] +- Sound needs a rewrite. With SDL, this shouldn't be much of a problem. + Of course, whoever does this should realize that the PCM outs are probably + not being used for a majority of the ROMs out there--according to the JTRM, + you're supposed to use the I2S interface to output sound since the PCM outs + aren't even physically hooked up in the console! [Shamus] [DONE--Shamus] diff --git a/docs/WHATSNEW b/docs/WHATSNEW index 88359bb..af69546 100644 --- a/docs/WHATSNEW +++ b/docs/WHATSNEW @@ -1,3 +1,23 @@ +Virtual Jaguar v1.0.5 GCC/SDL +----------------------------- + +* Added a simple file selector so that typing in long filenames in order + to run the emulator is no longer necessary. :-) To use it, instead of + supplying a ROM name, simple put in the name of the directory where your + ROMs live. [Shamus] +* Removed all the assembly language code from the DSP, so it should be a + little less buggy now. Also, removed some brain-dead timeslice releasing + that was causing a bunch of problems with various ROMs. [Shamus] +* Added sound support! In order to hear any sound, you probably have to + start VJ with the -dspon switch. Also, unless you have a very fast computer + the sound is going to be choppy. Hopefully future optimizations will cure + this. ;-) [Shamus] +* Added GUI support. You can see the results by hitting the TAB key while the + emulator is running. ;-) [Shamus] +* Lots of cleanups to the source code including the ability to trace who + writes what to where. [Shamus] + + Virtual Jaguar v1.0.4 GCC/SDL - source only release --------------------------------------------------- @@ -63,6 +83,8 @@ NOTE: Tested only on WIN32 platform! 1.0.1 - 1.0.2 - Unreleased, mostly for testing/finding bugs ----------------------------------------------------------- +* Lots of stuff happened, but we can't remember any of it. :-) + Virtual Jaguar v1.0.0 GCC/SDL - initial source release ------------------------------------------------------ diff --git a/src/dsp.cpp b/src/dsp.cpp index de54c3e..710b90a 100644 --- a/src/dsp.cpp +++ b/src/dsp.cpp @@ -639,10 +639,10 @@ void DSPWriteLong(uint32 offset, uint32 data, uint32 who/*=UNKNOWN*/) // WriteLog("dsp: writing %.8x at 0x%.8x\n",data,offset); if (offset >= DSP_WORK_RAM_BASE && offset <= DSP_WORK_RAM_BASE + 0x1FFF) { -if (offset == 0xF1BE2C) +/*if (offset == 0xF1BE2C) { WriteLog("DSP: %s is writing %08X at location 0xF1BE2C (DSP_PC: %08X)...\n", whoName[who], data, dsp_pc - 2); -} +}//*/ offset -= DSP_WORK_RAM_BASE; SET32(dsp_ram_8, offset, data); return; diff --git a/src/gui.cpp b/src/gui.cpp index db683ab..29f626d 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -6,11 +6,18 @@ // #include +#include +#include #include "types.h" #include "tom.h" #include "font1.h" #include "gui.h" +// Private function prototypes + +uint32 CountROMFiles(char * path); + + void InitGUI(void) { } @@ -19,6 +26,33 @@ void GUIDone(void) { } +// +// Render the backbuffer to the primary screen surface +// +void BlitBackbuffer(void) +{ + extern SDL_Surface * surface, * mainSurface; + extern int16 * backbuffer; + + if (SDL_MUSTLOCK(surface)) + while (SDL_LockSurface(surface) < 0) + SDL_Delay(10); + + memcpy(surface->pixels, backbuffer, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2); + + if (SDL_MUSTLOCK(surface)) + SDL_UnlockSurface(surface); + + SDL_Rect srcrect, dstrect; + srcrect.x = srcrect.y = 0, srcrect.w = surface->w, srcrect.h = surface->h; + dstrect.x = dstrect.y = 0, dstrect.w = surface->w, dstrect.h = surface->h; + SDL_BlitSurface(surface, &srcrect, mainSurface, &dstrect); + SDL_Flip(mainSurface); +} + +// +// Draw text at the given x/y coordinates. Can invert text as well. +// void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...) { char string[4096]; @@ -48,3 +82,142 @@ void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text address += 8; } } + +// +// Very very crude GUI file selector +// +bool UserSelectFile(char * path, char * filename) +{ + extern int16 * backbuffer; + uint32 numFiles = CountROMFiles(path); + + if (numFiles == 0) + return false; + + char * names = (char *)malloc(numFiles * 2048); + + if (names == NULL) + { + WriteLog("Could not allocate memory for %u files!\nAborting!\n", numFiles); + return false; + } + + int i = 0; + DIR * dp = opendir(path); + dirent * de; + + while ((de = readdir(dp)) != NULL) + { + char * ext = strrchr(de->d_name, '.'); + if (ext != NULL) + if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0) + strcpy(&names[i++ * 2048], de->d_name); + } + + closedir(dp); + + // Main GUI selection loop + + uint32 cursor = 0, startFile = 0; + + if (numFiles > 1) // Only go GUI if more than one possibility! + { + bool done = false; + uint32 limit = (numFiles > 24 ? 24 : numFiles); + SDL_Event event; + + while (!done) + { + while (SDL_PollEvent(&event)) + { + // Draw the GUI... + memset(backbuffer, 0x11, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2); + + for(uint32 i=0; id_name, '.'); + if (ext != NULL) + if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0) + numFiles++; + } + + closedir(dp); + } + + return numFiles; +} diff --git a/src/include/gui.h b/src/include/gui.h index 9259796..9efd8a2 100644 --- a/src/include/gui.h +++ b/src/include/gui.h @@ -7,6 +7,8 @@ #ifndef __GUI_H__ #define __GUI_H__ +void BlitBackbuffer(void); void DrawText(int16 * screen, uint32 x, uint32 y, bool invert, const char * text, ...); +bool UserSelectFile(char * path, char * filename); #endif // __GUI_H__ diff --git a/src/include/jaguar.h b/src/include/jaguar.h index 0963500..4318471 100644 --- a/src/include/jaguar.h +++ b/src/include/jaguar.h @@ -31,7 +31,7 @@ extern char * whoName[9]; void jaguar_init(void); void jaguar_reset(void); -void jaguar_reset_handler(void); +//void jaguar_reset_handler(void); void jaguar_done(void); uint8 JaguarReadByte(uint32 offset, uint32 who = UNKNOWN); diff --git a/src/include/tom.h b/src/include/tom.h index be51f63..a98aadf 100644 --- a/src/include/tom.h +++ b/src/include/tom.h @@ -7,15 +7,14 @@ #include "jaguar.h" -//#define TOM_VBLANK_DURATION_IN_SCANLINES 25 - #define VIDEO_MODE_16BPP_CRY 0 #define VIDEO_MODE_24BPP_RGB 1 #define VIDEO_MODE_16BPP_DIRECT 2 #define VIDEO_MODE_16BPP_RGB 3 -extern uint32 tom_width; -extern uint32 tom_height; +// 68000 Interrupt bit positions (enabled at $F000E0) + +enum { IRQ_VBLANK = 0, IRQ_GPU, IRQ_OPFLAG, IRQ_TIMER, IRQ_DSP }; void tom_init(void); void tom_reset(void); @@ -33,24 +32,14 @@ uint8 tom_getVideoMode(void); uint8 * tom_get_ram_pointer(void); uint16 tom_get_hdb(void); uint16 tom_get_vdb(void); -uint16 tom_get_scanline(void); -uint32 tom_getHBlankWidthInPixels(void); - -// 68000 Interrupt bit positions (enabled at $F000E0) - -/*#define IRQ_VBLANK 0 -#define IRQ_GPU 1 -#define IRQ_HBLANK 2 -#define IRQ_OPFLAG IRQ_HBLANK -#define IRQ_TIMER 3 -#define IRQ_DSP 4*/ -enum { IRQ_VBLANK = 0, IRQ_GPU, IRQ_OPFLAG, IRQ_TIMER, IRQ_DSP }; +//uint16 tom_get_scanline(void); +//uint32 tom_getHBlankWidthInPixels(void); int tom_irq_enabled(int irq); uint16 tom_irq_control_reg(void); void tom_set_irq_latch(int irq, int enabled); void tom_pit_exec(uint32 cycles); -void tom_set_pending_puck_int(void); +void tom_set_pending_jerry_int(void); void tom_set_pending_timer_int(void); void tom_set_pending_object_int(void); void tom_set_pending_gpu_int(void); @@ -59,4 +48,9 @@ void tom_reset_timer(void); uint32 TOMGetSDLScreenPitch(void); +// Exported variables + +extern uint32 tom_width; +extern uint32 tom_height; + #endif // __TOM_H__ diff --git a/src/jaguar.cpp b/src/jaguar.cpp index cb280ec..35f53b9 100644 --- a/src/jaguar.cpp +++ b/src/jaguar.cpp @@ -1,7 +1,7 @@ // // JAGUAR.CPP // -// by cal2 +// by Cal2 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Caz (BeOS) // Cleanups and endian wrongness amelioration by James L. Hammons // Note: Endian wrongness probably stems from the MAME origins of this emu and @@ -40,11 +40,6 @@ uint32 jaguar_active_memory_dumps = 0; uint32 jaguar_mainRom_crc32; -static uint32 m68k_cycles_per_scanline; -static uint32 gpu_cycles_per_scanline; -static uint32 dsp_cycles_per_scanline; -static uint32 jaguar_screen_scanlines; - /*static*/ uint8 * jaguar_mainRam = NULL; /*static*/ uint8 * jaguar_bootRom = NULL; /*static*/ uint8 * jaguar_mainRom = NULL; @@ -211,9 +206,6 @@ void m68k_write_memory_16(unsigned int address, unsigned int value) //if (address >= 0x0E75D0 && address <= 0x0E75E7) // WriteLog("M68K: Writing %04X at %08X, M68K PC=%08X\n", value, address, m68k_get_reg(NULL, M68K_REG_PC)); /*extern uint32 totalFrames; -extern bool suppressOutput; -if (totalFrames >= 59) - suppressOutput = false;//*/ /*if (address == 0xF02114) WriteLog("M68K: Writing to GPU_CTRL (frame:%u)... [M68K PC:%08X]\n", totalFrames, m68k_get_reg(NULL, M68K_REG_PC)); if (address == 0xF02110) @@ -524,17 +516,6 @@ void jaguar_init(void) // cd_bios_boot("C:\\ftp\\jaguar\\cd\\primalrage.cdi"); // cd_bios_boot("C:\\ftp\\jaguar\\cd\\Dragons Lair.cdi"); - // Should these be hardwired or read from VP? - jaguar_screen_scanlines = (hardwareTypeNTSC ? 524 : 624); -//Should the divisor be 50 for PAL??? Let's try it! - m68k_cycles_per_scanline = (hardwareTypeNTSC ? M68K_CLOCK_RATE_NTSC : M68K_CLOCK_RATE_PAL) / (jaguar_screen_scanlines * (hardwareTypeNTSC ? 60 : 50)); - gpu_cycles_per_scanline = dsp_cycles_per_scanline - = (hardwareTypeNTSC ? RISC_CLOCK_RATE_NTSC : RISC_CLOCK_RATE_PAL) / (jaguar_screen_scanlines * (hardwareTypeNTSC ? 60 : 50)); - -//#ifdef SOUND_OUTPUT -// ws_audio_init(); -//#endif - m68k_set_cpu_type(M68K_CPU_TYPE_68000); gpu_init(); DSPInit(); @@ -573,9 +554,7 @@ void jaguar_done(void) WriteLog("Jaguar: VBL interrupt is %s\n", ((tom_irq_enabled(IRQ_VBLANK)) && (jaguar_interrupt_handler_is_valid(64))) ? "enabled" : "disabled"); M68K_show_context(); //#endif -//#ifdef SOUND_OUTPUT -// ws_audio_done(); -//#endif + cd_bios_done(); cdrom_done(); gpu_done(); @@ -621,77 +600,19 @@ void jaguar_reset(void) WriteLog("\t68K PC=%06X SP=%08X\n", m68k_get_reg(NULL, M68K_REG_PC), m68k_get_reg(NULL, M68K_REG_A7)); } +/*unused void jaguar_reset_handler(void) { -} - -void jaguar_exec(int16 * backbuffer, bool render) -{ - uint32 i, vblank_duration = tom_get_vdb(); - - // vblank - if (tom_irq_enabled(IRQ_VBLANK) && jaguar_interrupt_handler_is_valid(64)) - { - if (JaguarReadWord(0xF0004E) != 0x07FF) // VI (11 bits wide!) - { - tom_set_pending_video_int(); -// s68000interrupt(7, IRQ_VBLANK+64); -// s68000flushInterrupts(); - m68k_set_irq(7); // IRQ_VBLANK+64??? Not autovectored??? No. -// Could set a global variable here, to signal that this is a VBLANK interrupt... -// Then again, since IRQ_VBLANK is set to zero, this would not be necessary in this case. - } - } - - for(i=0; i= vdb && i < vde)//vbb) { if (!(i & 0x01)) // Execute OP only on even lines (non-interlaced only!) @@ -751,10 +676,6 @@ if (effect_start) } } } - -//#ifdef SOUND_OUTPUT -// system_sound_update(); -//#endif } // Temp debugging stuff diff --git a/src/objectp.cpp b/src/objectp.cpp index 747e672..9c7f4e6 100644 --- a/src/objectp.cpp +++ b/src/objectp.cpp @@ -311,14 +311,6 @@ extern int op_start_log; // char * condition_to_str[8] = // { "==", "<", ">", "(opflag set)", "(second half line)", "?", "?", "?" }; -// If jaguar_exec() is working right, we should *never* have to check for this -// condition... -/* if (scanline < tom_get_vdb()) - return; - - if (scanline >= 525)//tom_getVideoModeHeight()+tom_get_vdb()) - return;//*/ - op_pointer = op_get_list_pointer(); objectp_stop_reading_list = false; diff --git a/src/tom.cpp b/src/tom.cpp index add3e44..377533b 100644 --- a/src/tom.cpp +++ b/src/tom.cpp @@ -245,7 +245,6 @@ // ------------------------------------------------------------ #include -//#include "SDLptc.h" #include "tom.h" #include "gpu.h" #include "objectp.h" @@ -260,8 +259,8 @@ #define VMODE 0x28 #define MODE 0x0006 // Line buffer to video generator mode #define BGEN 0x0080 // Background enable (CRY & RGB16 only) -#define VARMOD 0x0100 // Mixed CRY/RGB16 mode -#define PWIDTH 0x0E00 // Pixel width in video clock cycles +#define VARMOD 0x0100 // Mixed CRY/RGB16 mode (only works in MODE 0!) +#define PWIDTH 0x0E00 // Pixel width in video clock cycles (value written + 1) #define HP 0x2E // Values range from 1 - 1024 (value written + 1) #define HBB 0x30 #define HBE 0x32 @@ -276,14 +275,13 @@ #define VDE 0x48 #define VI 0x4E #define BG 0x58 +#define INT1 0xE0 //This can be defined in the makefile as well... //(It's easier to do it here, though...) //#define TOM_DEBUG extern uint32 jaguar_mainRom_crc32; -//extern Console console; -//extern Surface * surface; extern uint8 objectp_running; static uint8 * tom_ram_8; @@ -291,18 +289,15 @@ uint32 tom_width, tom_height, tom_real_internal_width; static uint32 tom_timer_prescaler; static uint32 tom_timer_divider; static int32 tom_timer_counter; -uint32 tom_scanline; -uint32 hblankWidthInPixels = 0; -uint16 tom_puck_int_pending; -uint16 tom_timer_int_pending; -uint16 tom_object_int_pending; -uint16 tom_gpu_int_pending; -uint16 tom_video_int_pending; +//uint32 tom_scanline; +//uint32 hblankWidthInPixels = 0; +uint16 tom_jerry_int_pending, tom_timer_int_pending, tom_object_int_pending, + tom_gpu_int_pending, tom_video_int_pending; uint16 * tom_cry_rgb_mix_lut; static char * videoMode_to_str[8] = - { "16 bpp CRY", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB", - "Mixed mode", "24 bpp RGB", "16 bpp DIRECT", "16 bpp RGB" }; + { "16 BPP CRY", "24 BPP RGB", "16 BPP DIRECT", "16 BPP RGB", + "Mixed mode", "24 BPP RGB", "16 BPP DIRECT", "16 BPP RGB" }; typedef void (render_xxx_scanline_fn)(int16 *); @@ -329,7 +324,7 @@ render_xxx_scanline_fn * scanline_render_normal[]= tom_render_16bpp_cry_rgb_mix_scanline, tom_render_24bpp_scanline, tom_render_16bpp_direct_scanline, - tom_render_16bpp_rgb_scanline, + tom_render_16bpp_rgb_scanline }; render_xxx_scanline_fn * scanline_render_stretch[]= @@ -374,9 +369,9 @@ void tom_calc_cry_rgb_mix_lut(void) } } -void tom_set_pending_puck_int(void) +void tom_set_pending_jerry_int(void) { - tom_puck_int_pending = 1; + tom_jerry_int_pending = 1; } void tom_set_pending_timer_int(void) @@ -410,19 +405,10 @@ uint8 tom_getVideoMode(void) return ((vmode & VARMOD) >> 6) | ((vmode & MODE) >> 1); } -uint16 tom_get_scanline(void) -{ - return tom_scanline; -} - -/*uint16 tom_get_hdb(void) -{ - return GET16(tom_ram_8, HDB); -}*/ - +//Used in only one place (and for debug purposes): OBJECTP.CPP uint16 tom_get_vdb(void) { - // This in NOT VDB!!! +// This in NOT VDB!!! // return GET16(tom_ram_8, VBE); return GET16(tom_ram_8, VDB); } @@ -489,6 +475,8 @@ void tom_render_24bpp_scanline(int16 * backbuffer) } } +//Seems to me that this is NOT a valid mode--the JTRM seems to imply that you would need +//extra hardware outside of the Jaguar console to support this! // // 16 BPP direct mode rendering // @@ -655,24 +643,17 @@ void tom_render_16bpp_rgb_stretch_scanline(int16 *backbuffer) // void tom_exec_scanline(int16 * backbuffer, int32 scanline, bool render) { - tom_scanline = scanline; - - // Increment the horizontal count (why? RNG?) -// TOMWriteWord(0xF00004, TOMReadWord(0xF00004) + 1); - if (render) { uint8 * current_line_buffer = (uint8 *)&tom_ram_8[0x1800]; - uint8 bgHI = tom_ram_8[BG], bgLO = tom_ram_8[BG+1]; + uint8 bgHI = tom_ram_8[BG], bgLO = tom_ram_8[BG + 1]; // Clear line buffer with BG if (GET16(tom_ram_8, VMODE) & BGEN) // && (CRY or RGB16)... for(uint32 i=0; i<720; i++) *current_line_buffer++ = bgHI, *current_line_buffer++ = bgLO; -// op_process_list(backbuffer, scanline, render); OPProcessList(scanline, render); - scanline_render[tom_getVideoMode()](backbuffer); } } @@ -714,55 +695,55 @@ void tom_done(void) memory_free(tom_ram_8); } -uint32 tom_getHBlankWidthInPixels(void) +/*uint32 tom_getHBlankWidthInPixels(void) { return hblankWidthInPixels; -} +}*/ uint32 tom_getVideoModeWidth(void) { - uint16 vmode = GET16(tom_ram_8, VMODE); - uint16 hdb1 = GET16(tom_ram_8, HDB1); -// uint16 hde = GET16(tom_ram_8, HDE); -// uint16 hbb = GET16(tom_ram_8, HBB); -// uint16 hbe = GET16(tom_ram_8, HBE); + //These widths are pretty bogus. Should use HDB1/2 & HDE/HBB & PWIDTH to calc the width... + uint32 width[8] = { 1330, 665, 443, 332, 266, 222, 190, 166 }; +//Temporary, for testing Doom... +// uint32 width[8] = { 1330, 665, 443, 332, 266, 222, 190, 332 }; + + // Note that the following PWIDTH values have the following pixel aspect ratios: + // PWIDTH = 1 -> 0.25:1 pixels (X:Y ratio) + // PWIDTH = 2 -> 0.50:1 pixels + // PWIDTH = 3 -> 0.75:1 pixels + // PWIDTH = 4 -> 1.00:1 pixels + // PWIDTH = 5 -> 1.25:1 pixels + // PWIDTH = 6 -> 1.50:1 pixels + // PWIDTH = 7 -> 1.75:1 pixels + // PWIDTH = 8 -> 2.00:1 pixels - // NOTE: PWIDTH is value + 1...! - int pwidth = ((vmode & PWIDTH) >> 9) + 1; // Also note that the JTRM says that PWIDTH of 4 gives pixels that are "about" square-- // this implies that the other modes have pixels that are *not* square! - - uint32 width = 640; - switch (pwidth) - { -/* case 1: width = 640; break; - case 2: width = 640; break; - case 3: width = 448; break; - case 4: width = 320; break; - case 5: width = 256; break; - case 6: width = 256; break; - case 7: width = 256; break; - case 8: width = 320; break;//*/ - case 1: width = 1330; break; // 0.25:1 pixels (X:Y ratio) - case 2: width = 665; break; // 0.50:1 pixels - case 3: width = 443; break; // 0.75:1 pixels - case 4: width = 332; break; // 1.00:1 pixels - case 5: width = 266; break; // 1.25:1 pixels - case 6: width = 222; break; // 1.50:1 pixels - case 7: width = 190; break; // 1.75:1 pixels - case 8: width = 166; break; // 2.00:1 pixels -//Temporary, for testing Doom... -// case 8: width = 332; break; // 2.00:1 pixels -//*/ - } - - if (hdb1 == 123) - hblankWidthInPixels = 16; - else - hblankWidthInPixels = 0; - -// WriteLog("TOM: HDB1=%i HBE=%i\n", hdb1, hbe); - return width; + // Also, I seriously doubt that you will see any games that use PWIDTH = 1! + + // NOTE: Even though the PWIDTH value is + 1, here we're using a zero-based index and + // so we don't bother to add one... +// return width[(GET16(tom_ram_8, VMODE) & PWIDTH) >> 9]; + + // Now, we just calculate it... + uint16 hdb1 = GET16(tom_ram_8, HDB1), hde = GET16(tom_ram_8, HDE), + hbb = GET16(tom_ram_8, HBB), pwidth = ((GET16(tom_ram_8, VMODE) & PWIDTH) >> 9) + 1; + return ((hbb < hde ? hbb : hde) - hdb1) / pwidth; + +// More speculating... +// According to the JTRM, the number of potential pixels across is given by the +// Horizontal Period (HP - in NTSC this is 845). The Horizontal Count counts from +// zero to this value twice per scanline (the high bit is set on the second count). +// HBE and HBB define the absolute "black" limits of the screen, while HDB1/2 and +// HDE determine the extent of the OP "on" time. I.e., when the OP is turned on by +// HDB1, it starts fetching the line from position 0 in LBUF. + +// The trick, it would seem, is to figure out how long the typical visible scanline +// of a TV is in HP ticks and limit the visible area to that (divided by PWIDTH, of +// course). Using that length, we can establish an "absolute left display limit" with +// which to measure HBB & HDB1/2 against when rendering LBUF (i.e., if HDB1 is 20 ticks +// to the right of the ALDL and PWIDTH is 4, then start writing the LBUF starting at +// backbuffer + 5 pixels). } // *** SPECULATION *** @@ -790,13 +771,13 @@ uint32 tom_getVideoModeHeight(void) // return ((vde > vp ? vp : vde) - vdb) >> 1; // return ((vde > vbb ? vbb : vde) - vdb) >> 1; //Let's try from the Vertical Blank interval... - return (vbb - vbe) >> 1; +//Seems to work OK! + return (vbb - vbe) >> 1; // Again, doesn't take interlacing into account... } // // TOM reset code -// NOTE: Should set up PAL values here when in PAL mode (use BIOS to find default values) -// for when user starts with -nobios -pal flags... [DONE] +// Now PAL friendly! // void tom_reset(void) { @@ -812,7 +793,7 @@ void tom_reset(void) { SET16(tom_ram_8, MEMCON1, 0x1861); SET16(tom_ram_8, MEMCON2, 0x35CC); - SET16(tom_ram_8, HP, 844); // Horizontal Period + SET16(tom_ram_8, HP, 844); // Horizontal Period (1-based; HP=845) SET16(tom_ram_8, HBB, 1713); // Horizontal Blank Begin SET16(tom_ram_8, HBE, 125); // Horizontal Blank End SET16(tom_ram_8, HDE, 1665); // Horizontal Display End @@ -845,11 +826,12 @@ void tom_reset(void) tom_width = tom_real_internal_width = 0; tom_height = 0; - tom_scanline = 0; +// tom_scanline = 0; - hblankWidthInPixels = GET16(tom_ram_8, HDB1) >> 1; +//This is WRONG +// hblankWidthInPixels = GET16(tom_ram_8, HDB1) >> 1; - tom_puck_int_pending = 0; + tom_jerry_int_pending = 0; tom_timer_int_pending = 0; tom_object_int_pending = 0; tom_gpu_int_pending = 0; @@ -911,13 +893,13 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) if (offset == 0xF000E0) { - uint16 data = (tom_puck_int_pending << 4) | (tom_timer_int_pending << 3) + uint16 data = (tom_jerry_int_pending << 4) | (tom_timer_int_pending << 3) | (tom_object_int_pending << 2) | (tom_gpu_int_pending << 1) | (tom_video_int_pending << 0); //WriteLog("tom: interrupt status is 0x%.4x \n",data); return data; } -//Shoud be handled by the jaguar main loop now... +//Shoud be handled by the jaguar main loop now... And it is! ;-) /* else if (offset == 0xF00006) // VC // What if we're in interlaced mode? // According to docs, in non-interlace mode VC is ALWAYS even... @@ -1072,7 +1054,7 @@ if (offset >= 0xF02000 && offset <= 0xF020FF) if (data & 0x0800) tom_timer_int_pending = 0; if (data & 0x1000) - tom_puck_int_pending = 0; + tom_jerry_int_pending = 0; } else if ((offset >= 0xF02200) && (offset <= 0xF0229F)) { @@ -1110,7 +1092,7 @@ if (offset == HDB1) if (offset == HDE) WriteLog("TOM: Horizontal Display End written by %s: %u\n", whoName[who], data); if (offset == HP) - WriteLog("TOM: Horizontal Period written by %s: %u\n", whoName[who], data); + WriteLog("TOM: Horizontal Period written by %s: %u (+1*2 = %u)\n", whoName[who], data, (data + 1) * 2); if (offset == VBB) WriteLog("TOM: Vertical Blank Begin written by %s: %u\n", whoName[who], data); if (offset == VBE) @@ -1124,7 +1106,11 @@ if (offset == HBB) if (offset == HBE) WriteLog("TOM: Horizontal Blank End written by %s: %u\n", whoName[who], data); if (offset == VMODE) - WriteLog("TOM: Video Mode written by %s: %04X (PWIDTH = %u, VC = %u)\n", whoName[who], data, ((data >> 9) & 0x07) + 1, GET16(tom_ram_8, VC)); + WriteLog("TOM: Video Mode written by %s: %04X. PWIDTH = %u, MODE = %s, flags:%s%s (VC = %u)\n", whoName[who], data, ((data >> 9) & 0x07) + 1, videoMode_to_str[(data & MODE) >> 1], (data & BGEN ? " BGEN" : ""), (data & VARMOD ? " VARMOD" : ""), GET16(tom_ram_8, VC)); +/*#define MODE 0x0006 // Line buffer to video generator mode +#define BGEN 0x0080 // Background enable (CRY & RGB16 only) +#define VARMOD 0x0100 // Mixed CRY/RGB16 mode +#define PWIDTH 0x0E00 // Pixel width in video clock cycles (value written + 1)*/ // detect screen resolution changes //This may go away in the future, if we do the virtualized screen thing... @@ -1178,7 +1164,7 @@ int tom_irq_enabled(int irq) { // This is the correct byte in big endian... D'oh! // return jaguar_byte_read(0xF000E1) & (1 << irq); - return tom_ram_8[0xE1] & (1 << irq); + return tom_ram_8[INT1 + 1/*0xE1*/] & (1 << irq); } //unused diff --git a/src/vj.cpp b/src/vj.cpp index 21d8ffb..9dbfe02 100644 --- a/src/vj.cpp +++ b/src/vj.cpp @@ -47,6 +47,7 @@ char * jaguar_eeproms_path = "./eeproms/"; char jaguar_boot_dir[1024]; SDL_Surface * surface, * mainSurface; +int16 * backbuffer = NULL; SDL_Joystick * joystick; Uint32 mainSurfaceFlags = SDL_SWSURFACE; @@ -57,30 +58,11 @@ bool hardwareTypeNTSC = true; // Set to false for PAL bool useJoystick = false; bool showGUI = false; -int16 * backbuffer = NULL; - // Added/changed by SDLEMU http://sdlemu.ngemu.com -uint32 totalFrames;//so we can grab this from elsewhere... +uint32 totalFrames;//temp, so we can grab this from elsewhere... int main(int argc, char * argv[]) { - -/*DIR * dp = opendir("../../ROMs/"); -if (dp == NULL) - printf("Could not open directory!\n"); -else -{ - dirent * de; - while ((de = readdir(dp)) != NULL) - { - char * ext = strrchr(de->d_name, '.'); - if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0) - printf("--> %s\n", de->d_name); - } - - closedir(dp); -}*/ - uint32 startTime;//, totalFrames;//, endTime;//, w, h; uint32 nNormalLast = 0; int32 nNormalFrac = 0; @@ -298,9 +280,7 @@ else // GUI stuff here... if (showGUI) { - extern uint32 gpu_pc; - extern uint32 dsp_pc; - DrawText(backbuffer, 8, 0, true, "Friendly GUI brought to you by JLH ;-)"); + extern uint32 gpu_pc, dsp_pc; DrawText(backbuffer, 8, 8, false, "GPU PC: %08X", gpu_pc); DrawText(backbuffer, 8, 16, false, "DSP PC: %08X", dsp_pc); } @@ -308,20 +288,7 @@ else // Simple frameskip if (nFrame == nFrameskip) { - if (SDL_MUSTLOCK(surface)) - while (SDL_LockSurface(surface) < 0) - SDL_Delay(10); - - memcpy(surface->pixels, backbuffer, tom_width * tom_height * 2); - - if (SDL_MUSTLOCK(surface)) - SDL_UnlockSurface(surface); - - SDL_Rect srcrect, dstrect; - srcrect.x = srcrect.y = 0, srcrect.w = surface->w, srcrect.h = surface->h; - dstrect.x = dstrect.y = 0, dstrect.w = surface->w, dstrect.h = surface->h; - SDL_BlitSurface(surface, &srcrect, mainSurface, &dstrect); - SDL_Flip(mainSurface); + BlitBackbuffer(); nFrame = 0; } else @@ -351,140 +318,6 @@ else return 0; } -// -// Very very crude GUI file selector -// -uint32 DoROMFind(uint8 * mem, char * path) -{ - char cartName[2048]; // Really, should be MAX_PATH or something like it - uint32 numFiles = 0; - DIR * dp = opendir(path); - - if (dp == NULL) - { - WriteLog("VJ: Could not open directory \"%s\"!\nAborting!\n", path); - log_done(); - exit(0); - } - else - { - dirent * de; - while ((de = readdir(dp)) != NULL) - { - char * ext = strrchr(de->d_name, '.'); - if (ext != NULL) - if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0) - numFiles++; - } - closedir(dp); - } - - if (numFiles == 0) - { - WriteLog("Found no ROM files!\nAborting!\n"); - log_done(); - exit(0); - } - - char * names = (char *)malloc(numFiles * 2048); - if (names == NULL) - { - WriteLog("Could not allocate memory for %u files!\nAborting!\n", numFiles); - log_done(); - exit(0); - } - - int i = 0; - dp = opendir(path); - dirent * de; - while ((de = readdir(dp)) != NULL) - { - char * ext = strrchr(de->d_name, '.'); - if (ext != NULL) - if (strcmpi(ext, ".zip") == 0 || strcmpi(ext, ".jag") == 0) - strcpy(&names[i++ * 2048], de->d_name); - } - closedir(dp); - - // Main GUI selection loop - - uint32 cursor = 0; - - if (numFiles > 1) // Only go GUI if more than one possibility! - { - bool done = false; - uint32 limit = (numFiles > 24 ? 24 : numFiles); - SDL_Event event; - while (!done) - - while (SDL_PollEvent(&event)) - { - // Draw the GUI... - memset(backbuffer, 0x11, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2); - uint32 startFile = (cursor >= limit ? cursor - limit + 1 : 0); - for(uint32 i=0; ipixels, backbuffer, tom_width * tom_height * 2); - memcpy(surface->pixels, backbuffer, tom_getVideoModeWidth() * tom_getVideoModeHeight() * 2); - - if (SDL_MUSTLOCK(surface)) - SDL_UnlockSurface(surface); - - SDL_Rect srcrect, dstrect; - srcrect.x = srcrect.y = 0, srcrect.w = surface->w, srcrect.h = surface->h; - dstrect.x = dstrect.y = 0, dstrect.w = surface->w, dstrect.h = surface->h; - SDL_BlitSurface(surface, &srcrect, mainSurface, &dstrect); - SDL_Flip(mainSurface); - - - if (event.type == SDL_KEYDOWN) - { - switch (event.key.keysym.sym) - { - case SDLK_UP: - if (cursor != 0) - cursor--; - break; - case SDLK_DOWN: - if (cursor != numFiles - 1) - cursor++; - break; - case SDLK_RETURN: - done = true; - break; - } - } - } - } - - strcpy(cartName, path); - if (path[strlen(path) - 1] != '/') - strcat(cartName, "/"); - strcat(cartName, &names[cursor * 2048]); - free(names); - - uint32 romSize = JaguarLoadROM(mem, cartName); - if (romSize == 0) - { - log_done(); - exit(0); - } - return romSize; -} - // // Generic ROM loading // @@ -505,8 +338,6 @@ uint32 JaguarLoadROM(uint8 * rom, char * path) if (load_zipped_file(0, 0, path, NULL, &rom, &romSize) == -1) { WriteLog("Failed!\n"); -// log_done(); -// exit(0); return 0; } } @@ -517,8 +348,6 @@ uint32 JaguarLoadROM(uint8 * rom, char * path) if (fp == NULL) { WriteLog("Failed!\n"); -// log_done(); -// exit(0); return 0; } @@ -544,11 +373,27 @@ void JaguarLoadCart(uint8 * mem, char * path) if (romSize == 0) { + char newPath[2048]; WriteLog("VJ: Trying GUI...\n"); - romSize = DoROMFind(mem, path); + + if (!UserSelectFile(path, newPath)) + { + WriteLog("VJ: Could not find valid ROM in directory \"%s\"...\nAborting!\n", path); + log_done(); + exit(0); + } + + romSize = JaguarLoadROM(mem, newPath); + + if (romSize == 0) + { + WriteLog("VJ: Could not load ROM from file \"%s\"...\nAborting!\n", newPath); + log_done(); + exit(0); + } } jaguar_mainRom_crc32 = crc32_calcCheckSum(jaguar_mainRom, romSize); - WriteLog( "CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32); + WriteLog("CRC: %08X\n", (unsigned int)jaguar_mainRom_crc32); eeprom_init(); } -- 2.37.2