-- Copyright (c) 2023 Adrian "asie" Siekierka
--
-- Licensed under the Apache License, Version 2.0 with LLVM Exceptions,                                   
-- See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license                             
-- information.

local args = {...}

local SCD = args[1] == "scd"
local IPL = args[1] == "ipl"
local BANK_START = 0x68
local BANK_ALLOC_START = 0x80
local BANK_END = 0x87
local BANK_KB = 8
local BANK_BYTES = BANK_KB * 1024
if SCD then
	BANK_ALLOC_START = 0x68
end

function bank_not_in_binary(b)
	return ((not SCD) and (b < 0x80)) or (IPL and (b > 0x84))
end

function printf(...)
	print(string.format(table.unpack({...})))
end

print("/* Automatically generated by generate-sections.lua. */\n")

-- calculate ROM sizes first, to pad the physical banks
for i = BANK_START,BANK_END do
	if i >= BANK_ALLOC_START and (i - BANK_ALLOC_START) < 5 then
		printf("PROVIDE(__ram_bank%d = 0x%04x);", i, (0x4000 + ((i - BANK_ALLOC_START) * BANK_BYTES)))
	else
		printf("PROVIDE(__ram_bank%d = 0xc000);", i)
	end
end

-- Define _bank symbols.
printf("")
for i = BANK_START,BANK_END do
	printf("__ram_bank%d_bank = %d;", i, i)
end

-- Define memory sections.
printf("")
printf("MEMORY {")
for i = BANK_START,BANK_END do
	local attrs = "rwxa"
	if bank_not_in_binary(i) then
		attrs = "rwx"
	end
	printf("  ram_bank%d (%s) : ORIGIN = (0x%08x + __ram_bank%d), LENGTH = 0x2000", i, attrs, (i << 16) + 0x01000000, i)
end
printf("}")

printf("")
printf("SECTIONS {")
for i = BANK_START,BANK_END do
	local attrs = ""
	if bank_not_in_binary(i) then
		attrs = "(NOLOAD) "
	end
	printf("  .ram_bank%d %s: { *(.ram_bank%d .ram_bank%d.*) } >ram_bank%d", i, attrs, i, i, i)
end
printf("}")
