Example program for the Cidco MailStation Z80 computer
1#/usr/bin/env ruby
2#
3# link, figure out header/code/data sizes, then relink with them packed tightly
4# Copyright (c) 2021 joshua stein <jcs@jcs.org>
5#
6# Permission to use, copy, modify, and distribute this software for any
7# purpose with or without fee is hereby granted, provided that the above
8# copyright notice and this permission notice appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17#
18
19def get_size(area)
20 File.open(ENV["PROG_MAP"], "r") do |f|
21 while f && !f.eof?
22 line = f.gets
23 # _HEADER0 00000000 000000F9 = 249. bytes (ABS,CON)
24 if m = line.match(/^#{area} .* (\d+)\. *bytes/)
25 return m[1].to_i
26 end
27 end
28 end
29
30 raise "can't find #{area} in #{ENV["PROG_MAP"]}"
31end
32
33def sdcc(code_start, data_start)
34 s = "#{ENV["SDCC"]} --code-loc #{sprintf("0x%04x", code_start)} " +
35 "--data-loc #{sprintf("0x%04x", data_start)} -o #{ENV["TARGET"]} " +
36 "#{ARGV.join(" ")}"
37 puts s
38 system(s)
39end
40
41base_addr = ENV["BASE_ADDR"].to_i(16)
42header_size = 0x1000
43code_start = base_addr + header_size
44data_start = base_addr + 0x4000
45
46# link once at a large offset data-loc
47sdcc(code_start, data_start)
48
49header_size = get_size("_HEADER0")
50printf "header: %d bytes (0x%04x)\n", header_size, header_size
51
52code_size = get_size("_CODE")
53printf "code: %d bytes (0x%04x)\n", code_size, code_size
54
55data_size = get_size("_DATA")
56printf "data: %d bytes (0x%04x)\n", data_size, data_size
57
58printf "total: %d bytes (0x%04x)\n", header_size + code_size + data_size,
59 header_size + code_size + data_size
60
61code_start = base_addr + header_size
62data_start = code_start + code_size
63printf "relinking with base: 0x%04x code: 0x%04x data:0x%04x\n",
64 base_addr, code_start, data_start
65
66sdcc(code_start, data_start)