2929
3030#ifdef USE_RAM12
3131
32- #define REU_RAM_Bank_Size 0x2000
33- #define REU_Size (NumREU_Banks * REU_RAM_Bank_Size) //Dynamically allocated based on NumREU_Banks, each bank is 8k (0x2000)
32+ #define REU_Size (NumREU_Banks * RAM_Bank_Size) //Dynamically allocated based on NumREU_Banks, each bank is 8k (0x2000)
3433 #define REU_RAM_READ (a ,d ) d=REU_Bank[a>>13][a&0x1fff]
3534 #define REU_RAM_WRITE (a ,d ) REU_Bank[a>>13][a&0x1fff]=d
3635 #define MIN_REU_BANKS 16 // 128K, smallest real REU (1700)
@@ -76,11 +75,6 @@ stcIOHandlers IOHndlr_REU =
7675extern bool PerformDMA (DMA_Trans_RnW RnW , uint16_t StartAddr , uint8_t * Buffer , uint32_t Length , DMA_Addr_Mode FixC64Addr );
7776extern bool CloseDMA ();
7877extern void (* fSpecialBtnChange )(bool Up_nDn ); //Pointer to function called when Special Button Changes
79- extern void EEPreadStr (uint16_t addr , char * buf );
80- extern RegMenuTypes RegMenuTypeFromFileName (char * * ptrptrFileName );
81- extern bool SDFullInit ();
82- extern bool USBFileSystemWait ();
83- extern FS * FSfromSourceID (RegMenuTypes SourceID );
8478
8579//ref: https://codebase64.net/doku.php?id=base:reu_registers
8680//tests:
@@ -145,17 +139,11 @@ extern bool DMA_RnW, DMA_FixC64Addr;
145139extern uint32_t DMA_Length , DMA_Count , DMA_StartAddr ;
146140extern bool DMAByte (uint8_t * Data );
147141
148- extern void FreeDriveDirMenu ();
149- extern uint8_t RAM_Image [];
150- // CrtChips.h declares the main image's static table and count.
151142extern StructMenuItem * DriveDirMenu ;
152- extern uint8_t * ptrRAM_ImageEnd ; // points to end of CRT-used RAM1 buffer
153143
154144void FreeREU ()
155- { //free banks allocated in RAM2 and reset NumREUBanks
156- for (uint16_t cnt = 0 ; cnt < NumREU_Banks ; cnt ++ )
157- if ((uint32_t )REU_Bank [cnt ] >= 0x20200000 ) free (REU_Bank [cnt ]);
158- NumREU_Banks = 0 ;
145+ {
146+ FreeRAMBanks (REU_Bank , & NumREU_Banks );
159147}
160148
161149void DMAByte_BASkip (uint8_t * Data1 )
@@ -455,83 +443,12 @@ FLASHMEM void ReadWriteREU(bool RnW, uint32_t REUAddr, uint8_t *REUBuf, uint16_t
455443
456444FLASHMEM void Save_REU ()
457445{
458- if ( NumREU_Banks == 0 ) return ; // nothing to save: probably due to failure to allocate 128K
459-
460- //Create filename based on current. reu000.reu becomes reu001.reu, etc
446+ #ifndef USE_RAM12
447+ #error Save_REU saves RAM1/2 banks only
448+ #endif
461449 char Filename [MaxPathLength ];
462450 EEPreadStr (eepAdREUFilename , Filename );
463- char * ptrFileName = Filename ; //pointer to move past SD/USB/TR:
464- RegMenuTypes MenuSourceID = RegMenuTypeFromFileName (& ptrFileName );
465-
466- if (MenuSourceID == rmtSD ) SDFullInit (); // SD.begin(BUILTIN_SDCARD); with retry if presence detected
467- if (MenuSourceID == rmtUSBDrive ) USBFileSystemWait (); //wait up to 1.5 sec in case USB drive just changed or powered up
468- //rmtTeensy not allowed, no reu files in Teensy Mem
469-
470- FS * sourceFS = FSfromSourceID (MenuSourceID );
471-
472- char Extension [20 ];
473- char * pDot = strrchr (ptrFileName , '.' ); //find last dot
474- if (pDot == NULL ) pDot = ptrFileName + strlen (ptrFileName ); //if no extension, set to end of filename
475- strcpy (Extension , pDot ); //copy extension
476- * pDot = 0 ; //terminate at dot/extension
477-
478- bool IsNum = true; //are last 3digits of filename all numbers?
479- if (strlen (ptrFileName )>=3 )
480- {
481- for (char * charloc = pDot - 3 ; charloc < pDot ; charloc ++ )
482- {
483- if (* charloc < '0' || * charloc > '9' ) IsNum = false;
484- //Serial.printf("%08x: %c %02x\n", (uint32_t)charloc, *charloc, *charloc);
485- }
486- }
487- else IsNum = false;
488-
489-
490- uint16_t NewNum = 0 ;
491- if (IsNum )
492- { //find current number and then terminate it
493- NewNum = atoi (pDot - 3 );
494- * (pDot - 3 ) = 0 ; //terminate number
495- }
496-
497- //now see if the file exists, or itterate until it doesn't
498- char NewFilename [MaxPathLength ];
499-
500- do sprintf (NewFilename , "%s%03d%s" , ptrFileName , NewNum ++ , Extension );
501- while (sourceFS -> exists (NewFilename ));
502-
503- Serial .printf ("Saving REU: %s\n" , NewFilename );
504- File SaveFile = sourceFS -> open (NewFilename , FILE_WRITE );
505- if (!SaveFile )
506- {
507- Serial .println ("Unable to open!" );
508- return ;
509- }
510-
511- //uint32_t StartmS = millis();
512- uint8_t NextByte ;
513-
514- for (uint32_t CharNum = 0 ; CharNum < REU_Size ; CharNum ++ )
515- {
516- REU_RAM_READ (CharNum , NextByte );
517- SaveFile .write (NextByte );
518- }
519- //Serial.printf("Saved %lu KBytes in %lumS\n", REU_Size/1024, millis()-StartmS);
520- Serial .printf ("Saved %dKBytes\n" , REU_Size /1024 );
521- SaveFile .close ();
522-
523- //Flash LED to ack save
524- uint32_t LastmS = millis ();
525- bool LEDState = true;
526-
527- for (uint32_t FlashCount = 0 ; FlashCount < 20 ; FlashCount ++ )
528- {
529- while (millis ()- LastmS < 75 );
530- LastmS = millis ();
531- if ((LEDState = !LEDState )) SetLEDOn ;
532- else SetLEDOff ;
533- }
534-
451+ SaveRAMBanks (REU_Bank , NumREU_Banks , Filename );
535452}
536453
537454// This only applies to REU-Only mode.
@@ -559,59 +476,10 @@ FLASHMEM void InitHndlr_REU()
559476#endif
560477
561478#ifdef USE_RAM12
562- //Allocate full REU size in Ram 1 and 2
563- //FreeCrtChips(); //re-using CrtChips for this, free mem allocated in RAM2 and reset NumCrtChips
564- FreeDriveDirMenu (); //free/clear prev loaded directory to make space. Doing it regardless to preserve continuity
565- //Serial.printf("RAM2#x- %d\n", RAM2blocks());
566-
567- if (NumCrtChips == 0 ) ptrRAM_ImageEnd = RAM_Image ; //If no CRT loaded, RAM1 is entirely free for REU
568- uint8_t * pRAM_Image = ptrRAM_ImageEnd ; //start at end of any CRT-used RAM1
569-
570- //Serial.printf("%dk REU, (%d banks x %d bytes)\n", REU_Size/1024, REU_Size/REU_RAM_Bank_Size, REU_RAM_Bank_Size);
571-
572- //First use RAM_Image from RAM1:
573- while (((uint32_t )pRAM_Image - (uint32_t )RAM_Image + REU_RAM_Bank_Size <= RAM_ImageSize )
574- && (NumREU_Banks < MAX_REU_BANKS ))
575- {
576- //CrtChips[NumCrtChips].ChipROM = pRAM_Image;
577- REU_Bank [NumREU_Banks ] = pRAM_Image ;
578- pRAM_Image += REU_RAM_Bank_Size ;
579- NumREU_Banks ++ ;
580- }
581- Printf_dbg_reu ("Used %lu/%lu Bytes of RAM1 Image\n" , (uint32_t )NumREU_Banks * REU_RAM_Bank_Size , RAM_ImageSize );
582-
583- //allocate the rest from RAM2
584- while ((NumREU_Banks < MAX_REU_BANKS && // while NumREU_Banks < 64 (512k/8k)
585- (NULL != (REU_Bank [NumREU_Banks ] = (uint8_t * )malloc (REU_RAM_Bank_Size ))))) // and allocation of 8k succeeds
586- {
587- NumREU_Banks ++ ; // if allocation a success, increment NumREU_Banks
588- }
589-
590- // NumREU_Banks = number of banks allocated, one higher than the last index of REU_Bank[] that was allocated
591-
592- Printf_dbg_reu ("After parsing RAM2, %luK bytes allocated\n" , (uint32_t )NumREU_Banks * REU_RAM_Bank_Size / 1024 );
593-
594- //resize REU to a power of 2 if needed and free unused banks
595- if (NumREU_Banks & (NumREU_Banks - 1 )) //not a power of 2
596- {
597- uint8_t unused_bank ;
598- // largest power less than or equal to NumREU_Banks
599- uint8_t NewNumREU_Banks = 1 << (7 - (__builtin_clz (NumREU_Banks ) - 24 ));
600- Serial .printf ("Resizing REU from %d banks to %d banks\n" , NumREU_Banks , NewNumREU_Banks );
601-
602- for (unused_bank = NewNumREU_Banks ; unused_bank < NumREU_Banks ; unused_bank ++ )
603- if ((uint32_t )REU_Bank [unused_bank ] >= 0x20200000 )
604- free (REU_Bank [unused_bank ]);
605- NumREU_Banks = NewNumREU_Banks ;
606- }
607-
608- Printf_dbg_reu ("After resizing to power of 2, %luK bytes allocated\n" , (uint32_t )NumREU_Banks * REU_RAM_Bank_Size / 1024 );
609-
610- if (NumREU_Banks < MIN_REU_BANKS ) // If REU is not 128k or larger
479+ NumREU_Banks = AllocRAMBanks (REU_Bank , MAX_REU_BANKS , MIN_REU_BANKS );
480+ if (NumREU_Banks == 0 )
611481 {
612- Serial .printf ("Unable to allocate minimum REU size of 128K\n"
613- "REU is disabled\n" );
614- FreeREU ();
482+ Serial .printf ("REU is disabled\n" );
615483 return ;
616484 }
617485
@@ -622,37 +490,9 @@ uint8_t *pRAM_Image = ptrRAM_ImageEnd; //start at end of any CRT-used RAM1
622490 fSpecialBtnChange = & SpecialBtn_REU ; //REU RAM is ready; enable button now so a failed/missing preload below doesn't skip it
623491 Serial .printf ("REU Size: %luK bytes\n" , (uint32_t )REU_Size / 1024 );
624492
625- //pre-load REU into RAM here:
626493 char Filename [MaxPathLength ];
627494 EEPreadStr (eepAdREUFilename , Filename );
628- char * ptrFileName = Filename ; //pointer to move past SD/USB/TR:
629- Serial .printf ("Loading REU: %s\n" , Filename );
630- RegMenuTypes MenuSourceID = RegMenuTypeFromFileName (& ptrFileName );
631-
632- if (MenuSourceID == rmtSD ) SDFullInit (); // SD.begin(BUILTIN_SDCARD); with retry if presence detected
633- if (MenuSourceID == rmtUSBDrive ) USBFileSystemWait (); //wait up to 1.5 sec in case USB drive just changed or powered up
634- //rmtTeensy not allowed, no reu files in Teensy Mem
635-
636- FS * sourceFS = FSfromSourceID (MenuSourceID );
637- File LoadFile = sourceFS -> open (ptrFileName , FILE_READ );
638- if (!LoadFile )
639- {
640- Serial .println ("Not found!" );
641- return ;
642- }
643-
644- if (LoadFile .size () > REU_Size )
645- Serial .printf ("Too Large! Loading first %luK\n" , (uint32_t )REU_Size /1024 );
646-
647- //uint32_t StartmS = millis();
648- uint32_t CharNum = 0 ;
649- for (uint8_t Bank = 0 ; Bank < NumREU_Banks && LoadFile .available (); Bank ++ )
650- CharNum += LoadFile .read (REU_Bank [Bank ], REU_RAM_Bank_Size );
651- //Serial.printf("Read %lu Bytes in %lumS\n", CharNum, millis()-StartmS);
652- Serial .printf ("Read %lu Bytes into REU\n" , CharNum );
653- LoadFile .close ();
654- //delay(250);
655-
495+ LoadRAMBanks (REU_Bank , NumREU_Banks , Filename );
656496
657497#elif defined(USE_PSRAM )
658498 //higher clock speed and shorter CS setup/hold do help, but still not enough for NUVIEs w/ sound
0 commit comments