You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

mergerom.pl 2.8KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/perl -w
  2. #
  3. # Copyright (C) 2008 Michael Brown <mbrown@fensystems.co.uk>.
  4. #
  5. # This program is free software; you can redistribute it and/or
  6. # modify it under the terms of the GNU General Public License as
  7. # published by the Free Software Foundation; either version 2 of the
  8. # License, or any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful, but
  11. # WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. # General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program; if not, write to the Free Software
  17. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. use strict;
  19. use warnings;
  20. use FindBin;
  21. use lib "$FindBin::Bin";
  22. use Option::ROM qw ( :all );
  23. sub merge_entry_points {
  24. my $baserom_entry = \shift;
  25. my $rom_entry = \shift;
  26. my $offset = shift;
  27. if ( $$rom_entry ) {
  28. my $old_entry = $$baserom_entry;
  29. $$baserom_entry = ( $offset + $$rom_entry );
  30. $$rom_entry = $old_entry;
  31. }
  32. }
  33. my @romfiles = @ARGV;
  34. my @roms = map { my $rom = new Option::ROM; $rom->load($_); $rom } @romfiles;
  35. my $baserom = shift @roms;
  36. my $offset = $baserom->length;
  37. foreach my $rom ( @roms ) {
  38. # Update base length
  39. $baserom->{length} += $rom->{length};
  40. # Merge initialisation entry point
  41. merge_entry_points ( $baserom->{init}, $rom->{init}, $offset );
  42. # Merge BOFM header
  43. merge_entry_points ( $baserom->{bofm_header}, $rom->{bofm_header}, $offset );
  44. # Update PCI header, if present in both
  45. my $baserom_pci = $baserom->pci_header;
  46. my $rom_pci = $rom->pci_header;
  47. if ( $baserom_pci && $rom_pci ) {
  48. # Update PCI lengths
  49. $baserom_pci->{image_length} += $rom_pci->{image_length};
  50. if ( exists $baserom_pci->{runtime_length} ) {
  51. if ( exists $rom_pci->{runtime_length} ) {
  52. $baserom_pci->{runtime_length} += $rom_pci->{runtime_length};
  53. } else {
  54. $baserom_pci->{runtime_length} += $rom_pci->{image_length};
  55. }
  56. }
  57. # Merge CLP entry point
  58. if ( exists ( $baserom_pci->{clp_entry} ) &&
  59. exists ( $rom_pci->{clp_entry} ) ) {
  60. merge_entry_points ( $baserom_pci->{clp_entry}, $rom_pci->{clp_entry},
  61. $offset );
  62. }
  63. }
  64. # Update PnP header, if present in both
  65. my $baserom_pnp = $baserom->pnp_header;
  66. my $rom_pnp = $rom->pnp_header;
  67. if ( $baserom_pnp && $rom_pnp ) {
  68. merge_entry_points ( $baserom_pnp->{bcv}, $rom_pnp->{bcv}, $offset );
  69. merge_entry_points ( $baserom_pnp->{bdv}, $rom_pnp->{bdv}, $offset );
  70. merge_entry_points ( $baserom_pnp->{bev}, $rom_pnp->{bev}, $offset );
  71. }
  72. # Fix checksum for this ROM segment
  73. $rom->fix_checksum();
  74. $offset += $rom->length;
  75. }
  76. $baserom->pnp_header->fix_checksum() if $baserom->pnp_header;
  77. $baserom->fix_checksum();
  78. $baserom->save ( "-" );
  79. foreach my $rom ( @roms ) {
  80. $rom->save ( "-" );
  81. }