git @ Cat's Eye Technologies linapple / fbf24b0
Merge remote-tracking branch 'blinkdog/master' T. Joseph Carter 3 years ago
88 changed file(s) with 164 addition(s) and 89 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
(No changes)
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)