blob: fd490761e2bcae1f3ccf87c1bbaec8f67ce6023e [file] [log] [blame]
Kevin O'Connorf076a3e2008-02-25 22:25:15 -05001#!/usr/bin/env python
2# Script to merge a rom32.bin file into a rom16.bin file.
3#
4# Copyright (C) 2008 Kevin O'Connor <kevin@koconnor.net>
5#
6# This file may be distributed under the terms of the GNU GPLv3 license.
7
8import sys
9import struct
10
11ROM16='out/rom16.bin'
12ROM32='out/rom32.bin'
13OFFSETS16='out/rom16.offset.auto.h'
14OFFSETS32='out/rom32.offset.auto.h'
15OUT='out/rom.bin'
16
17def align(v, a):
18 return (v + a - 1) // a * a
19
20def scanconfig(file):
21 f = open(file, 'rb')
22 opts = {}
23 for l in f.readlines():
24 parts = l.split()
25 if len(parts) != 3:
26 continue
27 if parts[0] != '#define':
28 continue
29 opts[parts[1]] = parts[2]
30 return opts
31
32def alteraddr(data, offset, ptr):
33 rel = struct.pack("<i", ptr)
34 return data[:offset] + rel + data[offset+4:]
35
36
37def main():
38 # Read in files
39 f = open(ROM16, 'rb')
40 data16 = f.read()
41 f = open(ROM32, 'rb')
42 data32 = f.read()
43
44 if len(data16) != 65536:
45 print "16bit code is not 65536 bytes long"
46 sys.exit(1)
47
48 # Get config options
49 o16 = scanconfig(OFFSETS16)
50 o32 = scanconfig(OFFSETS32)
51
52 # Inject 32bit code
53 spos = align(int(o16['OFFSET_bios16c_end'], 16), 16)
54 epos = int(o16['OFFSET_post16'], 16)
55 size32 = len(data32)
56 freespace = epos - spos
57 if size32 > freespace:
58 print "32bit code too large (%d vs %d)" % (size32, freespace)
59 sys.exit(1)
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050060 if data16[spos:spos+size32] != '\0'*size32:
61 print "Non zero data in 16bit freespace (%d to %d)" % (
62 spos, spos+size32)
63 sys.exit(1)
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050064 outrom = data16[:spos] + data32 + data16[spos+size32:]
65
66 # Fixup initial jump to 32 bit code
67 jmppos = int(o16['OFFSET_set_entry32'], 16)
68 start32 = int(o32['OFFSET__start'], 16)
69 outrom = alteraddr(outrom, jmppos+2, start32)
70
Kevin O'Connorbdce35f2008-02-26 21:33:14 -050071 print "Writing output rom %s" % OUT
72 print " 16bit C-code size: %d" % spos
73 print " 32bit C-code size: %d" % size32
74 print " Total C-code size: %d" % (spos+size32)
75
Kevin O'Connorf076a3e2008-02-25 22:25:15 -050076 # Write output rom
77 f = open(OUT, 'wb')
78 f.write(outrom)
79 f.close()
80
81if __name__ == '__main__':
82 main()