Fix cartridge targets

This commit is contained in:
Karol Stasiak 2019-08-16 01:09:03 +02:00
parent 1d530d896a
commit 785eb0780b
12 changed files with 66 additions and 34 deletions

View File

@ -2,7 +2,7 @@
#warn loader_0401 module should be only used on Commodore targets
#endif
array _basic_loader @$401 = [
const array _basic_loader @$401 = [
$0b,
4,
10,

View File

@ -2,7 +2,7 @@
#warn loader_0801 module should be only used on Commodore targets
#endif
array _basic_loader @$801 = [
const array _basic_loader @$801 = [
$0b,
$08,
10,

View File

@ -2,7 +2,7 @@
#warn loader_0801_16bit module should be only used on Commodore targets
#endif
array _basic_loader @$801 = [
const array _basic_loader @$801 = [
$0b,
$08,
10,

View File

@ -2,7 +2,7 @@
#warn loader_1001 module should be only used on Commodore targets
#endif
array _basic_loader @$1001 = [
const array _basic_loader @$1001 = [
$0b,
$10,
10,

View File

@ -2,7 +2,7 @@
#warn loader_1201 module should be only used on Commodore targets
#endif
array _basic_loader @$1201 = [
const array _basic_loader @$1201 = [
$0b,
$12,
10,

View File

@ -2,7 +2,7 @@
#warn loader_1c01 module should be only used on Commodore targets
#endif
array _basic_loader @$1C01 = [
const array _basic_loader @$1C01 = [
$0b,
$1C,
10,

View File

@ -7,4 +7,4 @@ const array __vectors @$A000 = [
]
segment(prgrom)
array __boot_signature @$A004 = [$41, $30, $C3, $C2, $CD]
const array __boot_signature @$A004 = [$41, $30, $C3, $C2, $CD]

View File

@ -7,4 +7,4 @@ const array __vectors @$8000 = [
]
segment(prgrom)
array __boot_signature @$8004 = [$C3, $C2, $CD, $38, $30]
const array __boot_signature @$8004 = [$C3, $C2, $CD, $38, $30]

View File

@ -1,4 +1,4 @@
array __header[16] @$4000 = [
const array __header[16] @$4000 = [
"AB" ascii,
@word [main.addr, 0, 0, 0],
0,0, 0,0, 0,0

View File

@ -213,10 +213,20 @@ class AbstractExpressionCompiler[T <: AbstractCode] {
object AbstractExpressionCompiler {
@inline
def getExpressionType(ctx: CompilationContext, expr: Expression): Type = {
getExpressionType(ctx.env, ctx.log, expr)
getExpressionTypeImpl(ctx.env, ctx.log, expr, loosely = false)
}
@inline
def getExpressionTypeLoosely(ctx: CompilationContext, expr: Expression): Type = {
getExpressionTypeImpl(ctx.env, ctx.log, expr, loosely = true)
}
def getExpressionType(env: Environment, log: Logger, expr: Expression): Type = {
@inline
def getExpressionType(env: Environment, log: Logger, expr: Expression): Type = getExpressionTypeImpl(env, log, expr, loosely = false)
@inline
def getExpressionTypeLoosely(env: Environment, log: Logger, expr: Expression): Type = getExpressionTypeImpl(env, log, expr, loosely = true)
def getExpressionTypeImpl(env: Environment, log: Logger, expr: Expression, loosely: Boolean): Type = {
if (expr.typeCache ne null) expr.typeCache
val b = env.get[Type]("byte")
val bool = env.get[Type]("bool$")
@ -235,7 +245,7 @@ object AbstractExpressionCompiler {
mask = (1L << (8 * maxSize)) - 1
signMask = ~mask
signTest = if (signMask == 0) Long.MaxValue else signMask >> 1
types = exprs.map(e => getExpressionType(env, log, e))
types = exprs.map(e => getExpressionTypeImpl(env, log, e, loosely))
if types.forall(_.size.<(8))
signednesses = types.flatMap {
case d: DerivedPlainType => Some(d.isSigned)
@ -249,7 +259,7 @@ object AbstractExpressionCompiler {
}
def toAllBooleanConstants(exprs: List[Expression]): Option[List[Boolean]] = {
for {
types <- Some(exprs.map(e => getExpressionType(env, log, e)))
types <- Some(exprs.map(e => getExpressionTypeImpl(env, log, e, loosely)))
if types.forall(_.isInstanceOf[ConstantBooleanType])
bools = types.map(_.asInstanceOf[ConstantBooleanType].value)
if bools.nonEmpty
@ -283,9 +293,24 @@ object AbstractExpressionCompiler {
case GeneratedConstantExpression(_, typ) => typ
case TextLiteralExpression(_) => env.get[Type]("pointer")
case VariableExpression(name) =>
env.get[TypedThing](name, expr.position).typ
if (loosely) {
env.maybeGet[TypedThing](name) match {
case Some(t) => t.typ
case None =>
if (name.endsWith(".lo") || name.endsWith(".hi")) {
b
} else if (name.endsWith(".addr")) {
env.get[Type]("pointer")
} else {
log.error(s"TypedThing `$name` is not defined", expr.position)
b
}
}
} else {
env.get[TypedThing](name, expr.position).typ
}
case HalfWordExpression(param, _) =>
getExpressionType(env, log, param)
getExpressionTypeImpl(env, log, param, loosely)
b
case IndexedExpression(name, _) =>
env.getPointy(name).elementType
@ -299,9 +324,9 @@ object AbstractExpressionCompiler {
case Some(a: MfArray) =>
env.get[Type]("pointer." + a.elementType)
case _ =>
getExpressionType(env, log, inner)
getExpressionTypeImpl(env, log, inner, loosely)
}
case _ => getExpressionType(env, log, inner)
case _ => getExpressionTypeImpl(env, log, inner, loosely)
}
var ok = true
for(_ <- firstIndices) {
@ -370,10 +395,10 @@ object AbstractExpressionCompiler {
}
if (ok) currentType else b
case SeparateBytesExpression(hi, lo) =>
if (getExpressionType(env, log, hi).size > 1) log.error("Hi byte too large", hi.position)
if (getExpressionType(env, log, lo).size > 1) log.error("Lo byte too large", lo.position)
if (getExpressionTypeImpl(env, log, hi, loosely).size > 1) log.error("Hi byte too large", hi.position)
if (getExpressionTypeImpl(env, log, lo, loosely).size > 1) log.error("Lo byte too large", lo.position)
w
case SumExpression(params, _) => params.map { case (_, e) => getExpressionType(env, log, e).size }.max match {
case SumExpression(params, _) => params.map { case (_, e) => getExpressionTypeImpl(env, log, e, loosely).size }.max match {
case 1 => b
case 2 => w
case _ => log.error("Adding values bigger than words", expr.position); w
@ -387,7 +412,7 @@ object AbstractExpressionCompiler {
case f@FunctionCallExpression("call", params) =>
params match {
case List(fp) =>
getExpressionType(env, log, fp) match {
getExpressionTypeImpl(env, log, fp, loosely) match {
case fpt@FunctionPointerType(_, _, _, Some(v), Some(r)) =>
if (v.name != "void"){
log.error(s"Invalid function pointer type: $fpt", fp.position)
@ -398,9 +423,9 @@ object AbstractExpressionCompiler {
v
}
case List(fp, pp) =>
getExpressionType(env, log, fp) match {
getExpressionTypeImpl(env, log, fp, loosely) match {
case fpt@FunctionPointerType(_, _, _, Some(p), Some(r)) =>
if (!getExpressionType(env, log, pp).isAssignableTo(p)){
if (!getExpressionTypeImpl(env, log, pp, loosely).isAssignableTo(p)){
log.error(s"Invalid function pointer type: $fpt", fp.position)
}
r
@ -414,29 +439,29 @@ object AbstractExpressionCompiler {
}
case FunctionCallExpression("hi", _) => b
case FunctionCallExpression("lo", _) => b
case FunctionCallExpression("sin", params) => if (params.size < 2) b else getExpressionType(env, log, params(1))
case FunctionCallExpression("cos", params) => if (params.size < 2) b else getExpressionType(env, log, params(1))
case FunctionCallExpression("tan", params) => if (params.size < 2) b else getExpressionType(env, log, params(1))
case FunctionCallExpression("sin", params) => if (params.size < 2) b else getExpressionTypeImpl(env, log, params(1), loosely)
case FunctionCallExpression("cos", params) => if (params.size < 2) b else getExpressionTypeImpl(env, log, params(1), loosely)
case FunctionCallExpression("tan", params) => if (params.size < 2) b else getExpressionTypeImpl(env, log, params(1), loosely)
case FunctionCallExpression("sizeof", params) => env.evalSizeof(params.head).requiredSize match {
case 1 => b
case 2 => w
}
case FunctionCallExpression("%%", params) => params.map { e => getExpressionType(env, log, e).size } match {
case FunctionCallExpression("%%", params) => params.map { e => getExpressionTypeImpl(env, log, e, loosely).size } match {
case List(1, 1) | List(2, 1) => b
case List(1, 2) | List(2, 2) => w
case _ => log.error("Combining values bigger than words", expr.position); w
}
case FunctionCallExpression("*" | "|" | "&" | "^" | "/", params) => params.map { e => getExpressionType(env, log, e).size }.max match {
case FunctionCallExpression("*" | "|" | "&" | "^" | "/", params) => params.map { e => getExpressionTypeImpl(env, log, e, loosely).size }.max match {
case 1 => b
case 2 => w
case _ => log.error("Combining values bigger than words", expr.position); w
}
case FunctionCallExpression("<<", List(a1, a2)) =>
if (getExpressionType(env, log, a2).size > 1) log.error("Shift amount too large", a2.position)
getExpressionType(env, log, a1)
if (getExpressionTypeImpl(env, log, a2, loosely).size > 1) log.error("Shift amount too large", a2.position)
getExpressionTypeImpl(env, log, a1, loosely)
case FunctionCallExpression(">>", List(a1, a2)) =>
if (getExpressionType(env, log, a2).size > 1) log.error("Shift amount too large", a2.position)
getExpressionType(env, log, a1)
if (getExpressionTypeImpl(env, log, a2, loosely).size > 1) log.error("Shift amount too large", a2.position)
getExpressionTypeImpl(env, log, a1, loosely)
case FunctionCallExpression("<<'", _) => b
case FunctionCallExpression(">>'", _) => b
case FunctionCallExpression(">>>>", _) => b
@ -529,6 +554,13 @@ object AbstractExpressionCompiler {
}
}
def checkAssignmentTypeLoosely(env: Environment, source: Expression, targetType: Type): Unit = {
val sourceType = getExpressionTypeLoosely(env, env.log, source)
if (!sourceType.isAssignableTo(targetType)) {
env.log.error(s"Cannot assign `$sourceType` to `$targetType`", source.position)
}
}
def checkAssignmentType(env: Environment, source: Expression, targetType: Type): Unit = {
val sourceType = getExpressionType(env, env.log, source)
if (!sourceType.isAssignableTo(targetType)) {

View File

@ -1567,7 +1567,7 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
val alignment = stmt.alignment.getOrElse(defaultArrayAlignment(options, length))
val address = stmt.address.map(a => eval(a).getOrElse(errorConstant(s"Array `${stmt.name}` has non-constant address", stmt.position)))
for (element <- contents) {
AbstractExpressionCompiler.checkAssignmentType(this, element, e)
AbstractExpressionCompiler.checkAssignmentTypeLoosely(this, element, e)
}
val array = InitializedArray(arrayName + ".array", address, contents, declaredBank = stmt.bank, indexType, e, readOnly = stmt.const, alignment)
if (!stmt.const && options.platform.ramInitialValuesBank.isDefined && array.bank(options) != "default") {

View File

@ -429,7 +429,7 @@ abstract class AbstractAssembler[T <: AbstractCode](private val program: Program
labelMap(name) = bank0.index -> index
if (!readOnlyPass) {
rwDataStart = rwDataStart.min(index)
rwDataEnd = rwDataEnd.min(index + thing.sizeInBytes)
rwDataEnd = rwDataEnd.max(index + thing.sizeInBytes)
}
assembly.append("* = $" + index.toHexString)
assembly.append(name + ":")