git @ Cat's Eye Technologies linapple / b3b95da
Merge pull request #2 from iKarith/master timob branch changes pulled into 2b David Baucum authored 3 years ago GitHub committed 3 years ago
88 changed file(s) with 174 addition(s) and 99 deletion(s). Raw diff Collapse all Expand all
0 /linapple
1 /src/linapple
2 *.o
(No changes)
(No changes)
(No changes)
Binary diff not shown
(No changes)
(No changes)
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
150150 # HDV Starting Directory is the starting directory for choose HDV disk images
151151 # Default: your home directory (if not set)
152152
153 HDV Starting Directory =
153 HDV Starting Directory =
154154
155155 # And you may also predefine hard disk images here, for 1 and 2 correspondingly.
156156 # Please, use Shift+F3 and Shift+F4 in emulator for change them in real time.
157157 # Remember, that values given here will be rewritten if you change them in emulator.
158158 # Default - do not use any HDV images
159159
160 Harddisk Image 1 =
161 Harddisk Image 2 =
160 Harddisk Image 1 =
161 Harddisk Image 2 =
162162
163163 ##########################################################################
164164 #
167167 #
168168 # Default: your home directory (if not set)
169169
170 Slot 6 Directory = /home/justy/Asimov.NET/action/bubble_bobble
170 Slot 6 Directory =
171171
172172 # You may also provide images to be inserted in 1 and 2 drive (D1 or D2) of Slot 6 at startup
173173 # Default: do not use, starting with image named Master.dsk in current directory
174174
175175 # To get access to the disk in second drive(D2), use something like '] CATALOG,D2' at Applesoft DOS(tm) prompt.
176176
177 Disk Image 1 = /home/justy/Asimov.NET/action/bubble_bobble/bubble_bobble2.dsk.gz
178 Disk Image 2 =
177 Disk Image 1 =
178 Disk Image 2 =
179179
180180 # The next parameter defines if you wish to auto-load these disk images in drives at startup!
181181 # Default value is 0 (Off), suggested: 1 (On)
187187 # Save State Filename - file name for saving/loading state with keys F11 and F12 in emulator.
188188 # Default is none. Note: you can choose it at runtime by pressing F11 (for saving) or F12 (for loading)
189189
190 Save State Filename =
190 Save State Filename =
191191
192192 # SaveSate Directory is a directory where current states will be saved by using F11,F12 (or ALT+F11, ALT+F12 keys, or Ctrl+0..9, Ctrl+Shift+0..9)
193193 #Default is none, which means your home directory
194194
195 Save State Directory =
195 Save State Directory =
196196
197197 # Define if you wish to save state on exit and restore it at startup by the next parameter:
198198 # Possible values are 0 - off, and 1 - on. When On, save state will be saved in Save State Filename at exit,
225225 # !!! Warning: FTP Local Dir should be existing directory with write access either FTP won't work
226226 # Note : FTP Server MUST end with '/' sign either it won't work! FTP Local Dir should not end with '/'
227227
228 FTP Server = ftp://ftp.apple.asimov.net/pub/apple_II/images/games/action/
228 FTP Server = ftp://ftp.apple.asimov.net/pub/apple_II/images/games/
229229 FTP ServerHDD = ftp://ftp.apple.asimov.net/pub/apple_II/images/
230230 FTP UserPass = anonymous:my-mail@mail.com
231 FTP Local Dir =
231 FTP Local Dir =
232232
233233 ##########################################################################
234234 #
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
Binary diff not shown
(No changes)
(No changes)
6262 //
6363 ///////////////////////////////////////////////////////////
6464
65 #define MAX_OUTPUT 0x7fff
65 // GPH Changed from 0x7fff: we want some headroom to add in the Apple speaker
66 // in the mixing phase and can avoid an unnecessary divide with the
67 // associated problems by simply picking smaller values.
68 // Note also this number can theoretically go as high as 0x3fff without
69 // causing post-mix clipping, but even that sounds too loud...
70 #define MAX_OUTPUT 0x0fff
6671
6772 // See AY8910_set_clock() for definition of STEP
6873 #define STEP 0x8000
(No changes)
(No changes)
(No changes)
123123 //static signed long g_uInternalExecutedCycles;
124124 // TODO: Use IRQ_CHECK_TIMEOUT=128 when running at full-speed else with IRQ_CHECK_TIMEOUT=1
125125 // - What about when running benchmark?
126 static const int IRQ_CHECK_TIMEOUT = 128;
126 // GPH Dropped to IRQ_CHECK_TIMOUT=16 - Mockingboard-intensive applications sound
127 // "jerky" at 128. Does not show appreciable CPU impact in top CPU profiler.
128 static const int IRQ_CHECK_TIMEOUT = 16;
127129 static signed int g_nIrqCheckTimeout = IRQ_CHECK_TIMEOUT;
128130
129131 //
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
155155 }
156156 #else
157157 /* Windows specific functions of reading directory structure */
158 /* Find subdirs: */
158 /* Find subdirs: */
159159 if(strcmp(incoming_dir, "/")) {
160160 // we are not in upper direcory
161161 tmp = new char[3];
167167 B = 1;
168168 }
169169 else B = 0; // for sorting dirs
170
170
171171
172172 WIN32_FIND_DATA finfo;
173173 HANDLE h;
174174
175
176
175
176
177177 h=FindFirstFile(incoming_dir,&finfo);
178178
179179 if (h!=INVALID_HANDLE_VALUE) {
197197 strcpy(tmp, "<DIR>");
198198 sizes.Add(tmp); // add sign of directory
199199 }
200 } /* while */
201 } /* if */
200 } /* while */
201 } /* if */
202202
203203 #endif
204204 // sort directories. Please, don't laugh at my bubble sorting - it the simplest thing I've ever seen --bb
240240 (void) closedir (dp);
241241 #else
242242 /* Windows specific functions of reading directory structure */
243 /* Find files: */
243 /* Find files: */
244244
245245 h=FindFirstFile(incoming_dir,&finfo);
246246
252252 strcpy(tmp,finfo.cFileName);
253253 files.Add(tmp);
254254 tmp = new char[10]; // 1400000KB
255 snprintf(tmp, 9, "%dKB",
255 snprintf(tmp, 9, "%dKB",
256256 ((finfo.nFileSizeHigh * (MAXDWORD+1)) + finfo.nFileSizeLow));
257257 sizes.Add(tmp); // add this size to list
258258 }
263263 strcpy(tmp,finfo.cFileName);
264264 files.Add(tmp);
265265 tmp = new char[10]; // 1400000KB
266 snprintf(tmp, 9, "%dKB",
266 snprintf(tmp, 9, "%dKB",
267267 ((finfo.nFileSizeHigh * (MAXDWORD+1)) + finfo.nFileSizeLow));
268268 sizes.Add(tmp); // add this size to list
269269 }
270 } /* while */
271 } /* if */
270 } /* while */
271 } /* if */
272272
273273 #endif
274274 // do sorting for files
308308 }
309309 else tempSurface = g_origscreen;
310310
311 if(tempSurface == NULL)
311 if(tempSurface == NULL)
312312 tempSurface = screen; // use screen, if none available
313
313
314314 my_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, tempSurface->w, tempSurface->h, tempSurface->format->BitsPerPixel, 0, 0, 0, 0);
315315 if(tempSurface->format->palette && my_screen->format->palette)
316316 SDL_SetColors(my_screen, tempSurface->format->palette->colors,
358358 SDL_Rect r;
359359 r.x= 2;
360360 r.y= TOPX + (i-first_file) * 15 * facy - 1;
361 if(strlen(tmp) > 46) r.w = 46 * 6 * 1.7 * facx + 2;
362 else r.w= strlen(tmp) * 6 * 1.7 * facx + 2; // 6- FONT_SIZE_X
361 if(strlen(tmp) > 46) r.w = 46 * FONT_SIZE_X /* 6 */ * 1.7 * facx + 2;
362 else r.w= strlen(tmp) * FONT_SIZE_X /* 6 */ * 1.7 * facx + 2; // 6- FONT_SIZE_X
363363 r.h= 9 * 1.5 * facy;
364364 SDL_FillRect(screen, &r, SDL_MapRGB(screen->format,255,0,0));// in RED
365365 } /* if */
398398
399399 // control cursor
400400 keyboard = SDL_GetKeyState(NULL); // get current state of pressed (and not pressed) keys
401
401402 if (keyboard[SDLK_UP] || keyboard[SDLK_LEFT]) {
402403 if (act_file>0) act_file--; // up one position
403404 if (act_file<first_file) first_file=act_file;
(No changes)
549549 char *
550550 md5str (const char *input)
551551 {
552 static char result[16 * 3 +1];
552 char result[16 * 3 +1];
553553 unsigned char* digest = (unsigned char*)md5 (input);
554554 int i;
555555
(No changes)
(No changes)
(No changes)
3636
3737 // for stat in FrameSaveBMP function
3838 #include <sys/stat.h>
39
40 // for usleep()
41 #include <unistd.h>
3942
4043
4144 #define ENABLE_MENU 0
388391 0, 256);
389392 // Uint32 myblack = SDL_MapRGB(screen->format, 0, 0, 0); // black color
390393 // SDL_SetColorKey(g_hStatusSurface,SDL_SRCCOLORKEY/* | SDL_RLEACCEL*/, myblack);
391
394
392395 if (drawflags & DRAW_BACKGROUND)
393396 {
394397 /* Code moved to Video.cpp in CreateDIBSections()
490493 "Conf file is linapple.conf in current directory by default",
491494 "Hugest archive of Apple][ stuff you can find at ftp.apple.asimov.net",
492495 " F1 - This help",
493 " F2 - Cold reset, Shift+F2 - Reload conf file and restart",
496 " Ctrl+Shift+F2 - Cold reset",
497 " Shift+F2 - Reload conf file and restart",
494498 " F3, F4 - Choose an image file name for floppy disk",
495499 " in Slot 6 drive 1 or 2 respectively",
496500 " Shift+F3, Shift+F4 - The same thing for Apple hard disks",
939943 break;
940944
941945 case BTN_RUN: // F2 - Run that thing! Or Shift+2 ReloadConfig and run it anyway!
942 if(mod & KMOD_SHIFT) {
946 if((mod & (KMOD_LCTRL|KMOD_LSHIFT)) == (KMOD_LCTRL|KMOD_LSHIFT) ||
947 (mod & (KMOD_RCTRL|KMOD_RSHIFT)) == (KMOD_RCTRL|KMOD_RSHIFT)) {
948 if (g_nAppMode == MODE_LOGO)
949 DiskBoot();
950 else if (g_nAppMode == MODE_RUNNING)
951 ResetMachineState();
952 if ((g_nAppMode == MODE_DEBUG) || (g_nAppMode == MODE_STEPPING))
953 DebugEnd();
954 g_nAppMode = MODE_RUNNING;
955 DrawStatusArea(/*(HDC)0,*/DRAW_TITLE);
956 VideoRedrawScreen();
957 g_bResetTiming = true;
958 }
959 else if(mod & KMOD_SHIFT) {
943960 restart = 1; // keep up flag of restarting
944961 qe.type = SDL_QUIT;
945962 SDL_PushEvent(&qe);// push quit event
946 }
947 else {
948 if (g_nAppMode == MODE_LOGO)
949 DiskBoot();
950 else if (g_nAppMode == MODE_RUNNING)
951 ResetMachineState();
952 if ((g_nAppMode == MODE_DEBUG) || (g_nAppMode == MODE_STEPPING))
953 DebugEnd();
954 g_nAppMode = MODE_RUNNING;
955 DrawStatusArea(/*(HDC)0,*/DRAW_TITLE);
956 VideoRedrawScreen();
957 g_bResetTiming = true;
958 }
963 }
959964 break;
960965
961966 case BTN_DRIVE1:
962967 case BTN_DRIVE2:
963968 if (mod & KMOD_SHIFT) {
969 if(mod & KMOD_ALT)
970 HD_FTP_Select(button - BTN_DRIVE1);// select HDV image through FTP
971 else
972 HD_Select(button - BTN_DRIVE1); // select HDV image from local disk
973 } else {
964974 if(mod & KMOD_ALT)
965 HD_FTP_Select(button - BTN_DRIVE1);// select HDV image through FTP
966 else HD_Select(button - BTN_DRIVE1); // select HDV image from local disk
967 }
968 else {
969 if(mod & KMOD_ALT) Disk_FTP_SelectImage(button - BTN_DRIVE1);//select through FTP
970 else DiskSelect(button - BTN_DRIVE1); // select image file for appropriate disk drive(#1 or #2)
975 Disk_FTP_SelectImage(button - BTN_DRIVE1);//select through FTP
976 else
977 DiskSelect(button - BTN_DRIVE1); // select image file for appropriate disk drive(#1 or #2)
971978 }
972979 /* if (!fullscreen)
973980 DrawButton((HDC)0,button);*/
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
182182
183183 static const DWORD g_dwDSBufferSize = 16 * 1024 * sizeof(short) * g_nMB_NumChannels;
184184
185 static const SHORT nWaveDataMin = (SHORT)0x8000;
186 static const SHORT nWaveDataMax = (SHORT)0x7FFF;
185 static const SHORT nWaveDataMin = (SHORT)0xF000;
186 static const SHORT nWaveDataMax = (SHORT)0x0FFF;
187187
188188 static short g_nMixBuffer[g_dwDSBufferSize / sizeof(short)];
189189
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
5252 // for terminal structure and funcs
5353 #include <termios.h>
5454 #include <fcntl.h>
55
56 // for read() and write()
57 #include <unistd.h>
5558
5659 char SSC_rom[] =
5760 "\x20\x9B\xC9\xA9\x16\x48\xA9\x00\x9D\xB8\x04\x9D\xB8\x03\x9D\x38"
(No changes)
130130 //std::cerr << "DEBUG wanted: " << wantedSamples
131131 // << " actual: " << audioSpec.size / 4 << std::endl;
132132 frequency = audioSpec.freq;
133 bufferSize = 4 * (audioSpec.size / sizeof(short));
133 bufferSize = 8 * (audioSpec.size / sizeof(short));
134134 // bufferSize = SPKR_SAMPLE_RATE * 2 * sizeof(short); // 1 second of stereo short data
135135
136136 /*
249249 //////////////////////////////////////////////////////////////////////
250250 //////////////////////////////////////////////////////////////////////
251251
252
253 // GPH this is called on IRQ to refresh the audio at regular intervals.
254 // We'll mix the buffers here keeping in mind the need for speed.
255 //
252256 void audioCallback(short* stream, unsigned len)
253257 {
254258 int i;
255259 static short lastvalue = 0;
256
257260 assert((len & 1) == 0); // stereo
261
258262 unsigned len1, len2;
259263 unsigned available = getBufferFilled();
260
261 //std::cerr << "DEBUG callback: " << available << std::endl;
262264 unsigned num = std::min(len, available);
263265 if ((readIdx + num) < bufferSize) {
266 // No split in source (mixBuffer); perform straight-up copy.
267 //
268 // |--------------------|
269 // ^ (mixBuffer) $
270 //
271 // |--------------------|
272 // ^ (stream)
264273 memcpy(stream, &mixBuffer[readIdx], num * sizeof(short));
265274 readIdx += num;
266275 } else {
276 // Handle split in source
277 //
278 // |--------------------|
279 // (mixBuffer) ^
280 //
281 // |--------------------|
282 // ^ (stream)
267283 len1 = bufferSize - readIdx;
268284 memcpy(stream, &mixBuffer[readIdx], len1 * sizeof(short));
269285 len2 = num - len1;
271287 readIdx = len2;
272288 }
273289
290 // Fill the remainer of the buffer with last value to prevent potential
291 // clicks and pops.
274292 if (available != 0) {
275293 if (readIdx != 0)
276294 lastvalue = mixBuffer[readIdx-1];
279297 }
280298
281299 for (i = num; i < len; i++) {
282 stream[i] = lastvalue;
300 stream[i] = lastvalue;
283301 }
284
285 /* Note: cleared at the begininng of the func
286
287 int missing = len - available;
288 if (missing > 0) {
289 // buffer underrun
290 //std::cerr << "DEBUG underrun: " << missing << std::endl;
291 memset(&stream[available], 0, missing * sizeof(short));
292 }
293 */
302 /* GPH please don't do this in an IRQ handler!
294303 unsigned target = (5 * bufferSize) / 8;
295304 double factor = double(available) / target;
296305 filledStat = (63 * filledStat + factor) / 64;
297 //std::cerr << "DEBUG filledStat: " << filledStat << std::endl;
306 */
307
298308 #ifdef MOCKINGBOARD
299 // And add Mockingboard sound data to the stream
309 // And add Mockingboard sound data to the stream
310 // GPH: We are going to add the Mockingboard and speaker samples.
311 // Their independent maximum amplitudes have been selected to eliminate
312 // any possibility of wave peak clipping. This speeds up the timing-sensitive
313 // operation here (since we're in an IRQ handler) and eliminates the
314 // need for a potentially expensive divide.
300315 available = getBuffer2Filled();
301316 //std::cerr << "DEBUG callback: " << available << std::endl;
302317 num = std::min(len, available);
318 const short *pSrc;
319 short *pDest = stream;
303320 if ((readIdx2 + num) < bufferSize) {
304 // memcpy(stream, &mixBuffer[readIdx], num * sizeof(short));
305 for(i = 0; i < num; i++)
306 stream[i] |= mockBuffer[readIdx2 + i];
307 readIdx2 += num;
321 if( num ) {
322 pSrc = &mockBuffer[readIdx2];
323 readIdx2 += num;
324 while(num--) {
325 *pDest += *pSrc;
326 pDest++; pSrc++;
327 }
328 }
308329 } else {
309 len1 = bufferSize - readIdx2;
310 // memcpy(stream, &mixBuffer[readIdx], len1 * sizeof(short));
311 for(i = 0; i < len1; i++)
312 stream[i] |= mockBuffer[readIdx2 + i];
330 // We crossed the "seam" on the circular mockBuffer.
331 // We will therefore perform two copies, the segmentation being determined
332 // by the split in the source buffer (mockBuffer).
333 //
334 // |--------------------|
335 // (mockBuffer) ^
336 //
337 //
338 // |--------------------|
339 // ^ (stream)
340 len1 = bufferSize - readIdx2;
313341 len2 = num - len1;
314 // memcpy(&stream[len1], mixBuffer, len2 * sizeof(short));
315 for(i = 0; i < len2; i++)
316 stream[len1 + i] |= mockBuffer[i];
342 if(len1) {
343 pSrc = &mockBuffer[readIdx2];
344 while(len1--) {
345 *pDest += *pSrc;
346 pDest++; pSrc++;
347 }
348 }
317349 readIdx2 = len2;
318 }
319 #endif
350 if(len2) {
351 pSrc = mockBuffer;
352 while(len2--) {
353 *pDest += *pSrc;
354 pDest++; pSrc++;
355 }
356 }
357
358 }
359 #endif // #ifdef MOCKINGBOARD
320360 // normalization
361 // GPH TODO: Rather than do this in this handler, we should
362 // perform it efficiently by changing the values of
363 // MAX_OUTPUT (AY8910.cpp) and SPKR_DATA_INIT (Speaker.cpp),
364 // making them variables and making the appropriate access functions
365 // to call from Frame.cpp
321366 /* const short MY_MAX_VOLUME = (short)SDL_MIX_MAXVOLUME / 2;
322367 for(unsigned k=0;k<len;k+=2)
323368 if((short)stream[k] > MY_MAX_VOLUME)
(No changes)
4949 //-------------------------------------
5050
5151 // Globals (SOUND_WAVE)
52 const short SPKR_DATA_INIT = (short)0x8000; // data written to speakers buffer
53
54 static short g_nSpeakerData = SPKR_DATA_INIT;
52 // GPH This "INIT" value is the actual sample data written to the speaker when
53 // it gets whapped with a BIT $C030. Note the output is always digital.
54 // The Apple II had no notion of volume or of looping waves, only the single
55 // "click" of the speaker. We set this to a value well under the maximum to
56 // provide headroom for mixing Mockingboard sound without causing peak clipping.
57 const short SPKR_DATA_INIT = (short)0x2000; // data written to speakers buffer
58
59 static short g_nSpeakerData = 0x0000; //SPKR_DATA_INIT;
5560 static short *g_pSpeakerBuffer = NULL;
56 static UINT g_nBufferIdx = 0;
61 static UINT g_nBufferIdx = 0;
5762
5863 static short *g_pStereoBuffer = NULL; // buffer for stereo samples
5964
60
6165 static short *g_pRemainderBuffer = NULL; // Remainder buffer
62 static UINT g_nRemainderBufferSize; // Setup in SpkrInitialize()
63 static UINT g_nRemainderBufferIdx; // Setup in SpkrInitialize()
64
66 static UINT g_nRemainderBufferSize; // Setup in SpkrInitialize()
67 static UINT g_nRemainderBufferIdx; // Setup in SpkrInitialize()
6568
6669 // Application-wide globals:
67 DWORD soundtype = SOUND_WAVE; //default
70 DWORD soundtype = SOUND_WAVE; //default
6871 double g_fClksPerSpkrSample; // Setup in SetClksPerSpkrSample()
6972
7073 // Globals
300303 }
301304
302305 g_nSpkrLastCycle = g_nCumulativeCycles;
303 }
304
305 //=============================================================================
306
307 // Called by emulation code when Speaker I/O reg is accessed
306
307 // GPH Added - simulate decoupling capacitor - use approximate value
308 g_nSpeakerData = (short)((double) g_nSpeakerData * 0.995);
309 }
310
311 //=============================================================================
312
313 // Called by emulation code when Speaker I/O reg (0xC030) is accessed
308314 BYTE SpkrToggle (WORD, WORD, BYTE, BYTE, ULONG nCyclesLeft)
309315 {
310316 g_bSpkrToggleFlag = true;
326332
327333 UpdateSpkr();
328334
329 g_nSpeakerData = ~g_nSpeakerData;
335 g_nSpeakerData = g_nSpeakerData ^ SPKR_DATA_INIT;
330336 }
331337
332338 return MemReadFloatingBus(nCyclesLeft); // reading from $C030..$C03F retrurns unpredictable value?
(No changes)
(No changes)
4343
4444 // for Assertion
4545 #include <assert.h>
46
47 // for usleep()
48 #include <unistd.h>
4649
4750 #ifndef _WIN32
4851 //===============================================================================//
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
(No changes)
8585 /* ---------------------- FONT routines ---------------------------*/
8686 /* ----------------------------------------------------------------*/
8787
88 #define FONT_SIZE_X 6
88 #define FONT_SIZE_X 7
8989 #define FONT_SIZE_Y 8
9090 // chars in row in font bitmap
91 #define CHARS_IN_ROW 45
91 #define CHARS_IN_ROW 39
9292 extern SDL_Surface *font_sfc;
9393
9494 bool fonts_initialization(void);
(No changes)
(No changes)
(No changes)