@@ -465,7 +465,7 @@ unsigned Machine::file_search(Word disc_id, Word file_name, bool write_mode)
465
465
// Return error code.
466
466
// In case of success return zero.
467
467
//
468
- unsigned Machine::file_mount (unsigned disk_unit, unsigned file_index, bool write_mode)
468
+ unsigned Machine::file_mount (unsigned disk_unit, unsigned file_index, bool write_mode, unsigned file_offset )
469
469
{
470
470
if (disk_unit < 030 || disk_unit >= 070 )
471
471
throw std::runtime_error (" Invalid disk unit " + to_octal (disk_unit) + " in file_mount()" );
@@ -492,7 +492,7 @@ unsigned Machine::file_mount(unsigned disk_unit, unsigned file_index, bool write
492
492
return E57_NO_ACCESS;
493
493
}
494
494
}
495
- disks[disk_unit - 030 ] = std::make_unique<Disk>(0 , memory, path, write_mode);
495
+ disks[disk_unit - 030 ] = std::make_unique<Disk>(0 , memory, path, write_mode, file_offset );
496
496
if (bin_created && !write_mode) {
497
497
// Remove binary image of the disk when finished.
498
498
disks[disk_unit - 030 ]->remove_when_finished ();
@@ -768,8 +768,9 @@ void Machine::boot_ms_dubna(const std::string &path)
768
768
769
769
//
770
770
// Check for binary program (overlay).
771
+ // Return file offset for shebang.
771
772
//
772
- bool Machine::is_overlay (const std::string &filename)
773
+ bool Machine::is_overlay (const std::string &filename, unsigned *file_offset_ptr )
773
774
{
774
775
// Open binary file.
775
776
std::ifstream file (filename, std::ios_base::binary);
@@ -778,17 +779,33 @@ bool Machine::is_overlay(const std::string &filename)
778
779
return false ;
779
780
}
780
781
782
+ // Check for shebang line.
783
+ std::string line (512 , ' \0 ' );
784
+ if (!file.read (&line[0 ], line.size ())) {
785
+ return false ;
786
+ }
787
+ *file_offset_ptr = 0 ;
788
+ if (line[0 ] == ' #' && line[1 ] == ' !' ) {
789
+ // Shebang found: determine offset to actual overlay binary.
790
+ auto newline = line.find (' \n ' );
791
+ if (newline == std::string::npos) {
792
+ // Too long line.
793
+ return false ;
794
+ }
795
+ *file_offset_ptr = newline + 1 ;
796
+ }
797
+
781
798
// Check file size.
782
799
file.seekg (0 , std::ios_base::end);
783
- auto nbytes = file.tellg ();
800
+ auto nbytes = file.tellg () - ( off_t )*file_offset_ptr ;
784
801
if (nbytes / PAGE_NBYTES < 2 || nbytes % PAGE_NBYTES != 0 ) {
785
802
// Must be a multiple of the page size.
786
803
return false ;
787
804
}
788
805
789
806
// Check magic word OVERLA at fixed offset.
790
807
std::string word (6 , ' \0 ' );
791
- file.seekg (01762 * 6 , std::ios_base::beg);
808
+ file.seekg (01762 * 6 + *file_offset_ptr , std::ios_base::beg);
792
809
if (!file.read (&word[0 ], word.size ())) {
793
810
return false ;
794
811
}
@@ -798,7 +815,7 @@ bool Machine::is_overlay(const std::string &filename)
798
815
}
799
816
800
817
// Check base address of the binary.
801
- file.seekg (6 , std::ios_base::beg);
818
+ file.seekg (6 + *file_offset_ptr , std::ios_base::beg);
802
819
if (!file.read (&word[0 ], word.size ())) {
803
820
return false ;
804
821
}
@@ -812,7 +829,7 @@ bool Machine::is_overlay(const std::string &filename)
812
829
//
813
830
// Load binary program (overlay).
814
831
//
815
- void Machine::boot_overlay (const std::string &filename, const std::string &path)
832
+ void Machine::boot_overlay (const std::string &filename, unsigned file_offset, const std::string &path)
816
833
{
817
834
// Mount tape 9/monsys as disk 30, read only.
818
835
disk_search_path = path;
@@ -823,7 +840,7 @@ void Machine::boot_overlay(const std::string &filename, const std::string &path)
823
840
824
841
// Open overlay as disk 60, read only.
825
842
file_paths.push_back (filename);
826
- file_mount (060 , file_paths.size (), false );
843
+ file_mount (060 , file_paths.size (), false , file_offset );
827
844
828
845
// clang-format off
829
846
memory.store (02000 , besm6_asm (" *70 3000, utc" )); // читаем таблицу резидентных программ для загрузчика
0 commit comments