remove bankof(), documented msw() and lsw()

This commit is contained in:
Irmen de Jong 2024-12-01 21:24:26 +01:00
parent 181f3e9eb1
commit 31ad8bdd8d
20 changed files with 29 additions and 54 deletions

View File

@ -92,7 +92,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
is PtBinaryExpression -> false
is PtBuiltinFunctionCall -> {
when (name) {
in arrayOf("msb", "lsb", "msw", "lsw", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple() }
in arrayOf("msb", "lsb", "msw", "lsw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple() }
else -> false
}
}

View File

@ -113,7 +113,6 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
"lsw" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UWORD),
"msb" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
"msw" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UWORD),
"bankof" to FSignature(true, listOf(FParam("value", arrayOf(DataType.UWORD, DataType.WORD, DataType.LONG))), DataType.UBYTE),
"mkword" to FSignature(true, listOf(FParam("msb", arrayOf(DataType.UBYTE)), FParam("lsb", arrayOf(DataType.UBYTE))), DataType.UWORD),
"clamp" to FSignature(true, listOf(FParam("value", arrayOf(DataType.BYTE)), FParam("minimum", arrayOf(DataType.BYTE)), FParam("maximum", arrayOf(DataType.BYTE))), null),
"clamp__byte" to FSignature(true, listOf(FParam("value", arrayOf(DataType.BYTE)), FParam("minimum", arrayOf(DataType.BYTE)), FParam("maximum", arrayOf(DataType.BYTE))), DataType.BYTE),

View File

@ -24,7 +24,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
val sscope = fcall.definingISub()
when (fcall.name) {
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
"msb" -> funcMsb(fcall, resultRegister)

View File

@ -177,7 +177,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
private fun usesOtherRegistersWhileEvaluating(arg: PtExpression): Boolean {
return when(arg) {
is PtBuiltinFunctionCall -> {
if (arg.name in arrayOf("lsb", "msb", "lsw", "msw", "bankof"))
if (arg.name in arrayOf("lsb", "msb", "lsw", "msw"))
return usesOtherRegistersWhileEvaluating(arg.args[0])
if (arg.name == "mkword")
return usesOtherRegistersWhileEvaluating(arg.args[0]) || usesOtherRegistersWhileEvaluating(arg.args[1])

View File

@ -924,7 +924,7 @@ internal class AssignmentAsmGen(
is PtIdentifier -> true
is PtIrRegister -> true
is PtNumber -> true
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb", "lsw", "msw", "bankof")
is PtBuiltinFunctionCall -> expr.name in arrayOf("lsb", "msb")
else -> false
}
}

View File

@ -19,7 +19,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
"callfar" -> funcCallfar(call)
"callfar2" -> funcCallfar2(call)
"call" -> funcCall(call)
"bankof" -> throw AssemblyError("bankof() should have been replaced by a const value (either the bank number of a long const, or zero for any other smaller value)")
"lsw" -> throw AssemblyError("lsw() should have been removed or replaced by a const value")
"msw" -> throw AssemblyError("msw() should have been removed or replaced by a const value")
"msb" -> funcMsb(call)

View File

@ -23,7 +23,6 @@ internal val constEvaluatorsForBuiltinFuncs: Map<String, ConstExpressionCaller>
"lsw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x and 65535).toDouble() } },
"msb" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 8 and 255).toDouble()} },
"msw" to { a, p, prg -> oneIntArgOutputInt(a, p, prg, true) { x: Int -> (x ushr 16 and 65535).toDouble()} },
"bankof" to ::builtinBankof,
"mkword" to ::builtinMkword,
"clamp__ubyte" to ::builtinClampUByte,
"clamp__byte" to ::builtinClampByte,
@ -153,15 +152,6 @@ private fun builtinLen(args: List<Expression>, position: Position, program: Prog
}
}
private fun builtinBankof(args: List<Expression>, position: Position, program: Program): NumericLiteral {
if (args.size != 1)
throw SyntaxError("bankof requires one argument", position)
val const = args[0].constValue(program)?.number?.toInt() ?: throw NotConstArgumentException()
if(const > 0xffffff)
throw SyntaxError("integer overflow, bank exceeds 255", position)
return NumericLiteral(DataType.UBYTE, (const ushr 16 and 255).toDouble(), position)
}
private fun builtinMkword(args: List<Expression>, position: Position, program: Program): NumericLiteral {
if (args.size != 2)
throw SyntaxError("mkword requires msb and lsb arguments", position)

View File

@ -1517,7 +1517,7 @@ internal class AstChecker(private val program: Program,
else if(arg.value is FunctionCallExpression) {
val fcall = arg.value as FunctionCallExpression
val name = fcall.target.nameInSource
if(name==listOf("lsb") || name==listOf("msb") || name==listOf("bankof") || name==listOf("msw") || name==listOf("lsw"))
if(name==listOf("lsb") || name==listOf("msb") || name==listOf("msw") || name==listOf("lsw"))
ident = fcall.args[0] as? IdentifierReference
}
if(ident!=null && ident.nameInSource[0] == "cx16" && ident.nameInSource[1].startsWith("r")) {

View File

@ -118,7 +118,7 @@ private fun integrateDefers(subdefers: Map<PtSub, List<PtDefer>>, program: PtPro
is PtAddressOf -> value.arrayIndexExpr == null || notComplex(value.arrayIndexExpr!!)
is PtBuiltinFunctionCall -> {
when (value.name) {
in arrayOf("msb", "lsb", "msw", "lsw", "bankof", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) }
in arrayOf("msb", "lsb", "msw", "lsw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> value.args.all { notComplex(it) }
else -> false
}
}

View File

@ -367,13 +367,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
val name = functionCallExpr.target.nameInSource
if(name==listOf("bankof")) {
val valueDt = functionCallExpr.args[0].inferType(program)
if(valueDt.isWords || valueDt.isBytes) {
val zero = NumericLiteral(DataType.UBYTE, 0.0, functionCallExpr.position)
return listOf(IAstModification.ReplaceNode(functionCallExpr, zero, parent))
}
} else if(name==listOf("msw")) {
if(name==listOf("msw")) {
val valueDt = functionCallExpr.args[0].inferType(program)
if(valueDt.isWords || valueDt.isBytes) {
val zero = NumericLiteral(DataType.UWORD, 0.0, functionCallExpr.position)

View File

@ -91,21 +91,23 @@ cmp (x,y)
Normally you should just use a comparison expression (``x < y``)
lsb (x)
Get the least significant (or 'lower') byte of the value x. Equivalent to the cast "x as ubyte".
Get the least significant (lower) byte of the value x. Equivalent to ``x & 255``.
lsw (x)
Get the least significant (lower) word of the value x. Equivalent to ``x & 65535``.
msb (x)
Get the most significant (or 'higher') byte of the word value x.
Get the most significant (higher) byte of the word value x.
If x is a value greater than a word, it will not actually return the *highest* byte of this value,
but it will only look a the lower word part of this value and return the higher byte from that.
More accurately, you'll get bits 8-16 of the value x. So msb($1234) is $12, whereas msb($123456) is $34.
If you want to extract the actual highest byte from a long value, we call that the 'bank' byte and you
can do that using ``bankof(x)``.
So you're always getting bits 8-16 of the value x: ``msb($1234)`` is $12, whereas ``msb($123456)`` is $34.
bankof (x)
Get the 'bank' byte from the value x. This means bits 16-24 of that value: bankof($123456) = $12.
(To get the 16 bit address out of a value simply use ``x & $ffff``)
If x is a word or smaller, bankof(x) will always be zero.
You can consider this function equivalent to the expression ``lsb(x >> 16)``.
msw (x)
Get the most significant (higher) word of the value x. For all word and byte numbers this will always result in 0.
For a long integer though, it returns the upper 16 bits of x as an uword.
If x is not greater than a 24 bit number ($ffffff), ``msw(x)`` will actually give you the bank byte of x (bits 16 to 23).
You can treat this as an ubyte value, even if the function is normally returning a uword:
``msw($123456)`` is $0012, which you can treat as an ubyte. ``msw($12345678)`` is $1234, an uword.
mkword (msb, lsb)
Efficiently create a word value from two bytes (the msb and the lsb). Avoids multiplication and shifting.

View File

@ -3,10 +3,6 @@ TODO
make a compiler switch to disable footgun warnings
-> added bankof() to get the bank byte of a large integer
-> added msw() and lsw() . note: msw() on a 24 bits constant can ALSO be used to get the bank byte because the value, while a word type, will be <=255
-> TODO document whatever remains of these! (and add to syntax files)
...

View File

@ -18,7 +18,7 @@ main {
word balloon_y = 120
; clear the screen (including all the tiles outside of the visible area)
cx16.vaddr(bankof(txt.VERA_TEXTMATRIX), txt.VERA_TEXTMATRIX & $ffff, 0, 1)
cx16.vaddr(msw(txt.VERA_TEXTMATRIX), txt.VERA_TEXTMATRIX & $ffff, 0, 1)
repeat 128 * txt.DEFAULT_HEIGHT {
cx16.VERA_DATA0 = sc:' '
cx16.VERA_DATA0 = $00

View File

@ -16,12 +16,12 @@ main {
txt.print("there be dragons!")
; load the sprite data and color palette directly into Vera ram
void diskio.vload_raw("dragonsprite.bin", bankof(SPRITE_DATA), SPRITE_DATA & $ffff)
void diskio.vload_raw("dragonsprite.bin", msw(SPRITE_DATA), SPRITE_DATA & $ffff)
void diskio.vload_raw("dragonsprite.pal", 1, $fa00 + SPRITE_PALETTE_OFFSET*16*2)
; initialize the dragon sprites
sprites.init(1, bankof(SPRITE_DATA), SPRITE_DATA & $ffff, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16, SPRITE_PALETTE_OFFSET)
sprites.init(2, bankof(SPRITE_DATA), (SPRITE_DATA & $ffff) + 64*64/2, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16,SPRITE_PALETTE_OFFSET)
sprites.init(1, msw(SPRITE_DATA), SPRITE_DATA & $ffff, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16, SPRITE_PALETTE_OFFSET)
sprites.init(2, msw(SPRITE_DATA), (SPRITE_DATA & $ffff) + 64*64/2, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16,SPRITE_PALETTE_OFFSET)
ubyte tt = 0
word xpos = -64

View File

@ -20,14 +20,14 @@ main {
txt.print("there be many dragons!")
; load the sprite data and color palette directly into Vera ram
void diskio.vload_raw("dragonsprite.bin", bankof(SPRITE_DATA), SPRITE_DATA & $ffff)
void diskio.vload_raw("dragonsprite.bin", msw(SPRITE_DATA), SPRITE_DATA & $ffff)
void diskio.vload_raw("dragonsprite.pal", 1, $fa00 + SPRITE_PALETTE_OFFSET*16*2)
; initialize the dragon sprites (every dragon needs 2 sprites, top and bottom half)
ubyte sprite_num
for sprite_num in 0 to NUM_DRAGONS*2-2 step 2 {
sprites.init(sprite_num+1, bankof(SPRITE_DATA), SPRITE_DATA & $ffff, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16, SPRITE_PALETTE_OFFSET)
sprites.init(sprite_num+2, bankof(SPRITE_DATA), (SPRITE_DATA & $ffff) + 64*64/2, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16, SPRITE_PALETTE_OFFSET)
sprites.init(sprite_num+1, msw(SPRITE_DATA), SPRITE_DATA & $ffff, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16, SPRITE_PALETTE_OFFSET)
sprites.init(sprite_num+2, msw(SPRITE_DATA), (SPRITE_DATA & $ffff) + 64*64/2, sprites.SIZE_64, sprites.SIZE_64, sprites.COLORS_16, SPRITE_PALETTE_OFFSET)
xpositions[sprite_num] = math.rndw() % (640-64) as word
xpositions[sprite_num+1] = xpositions[sprite_num]

View File

@ -7,15 +7,11 @@ main {
txt.print_ubhex($123456>>16, true)
txt.spc()
txt.print_ubhex(msw($123456), true)
txt.spc()
txt.print_ubhex(bankof($123456), true)
txt.nl()
txt.print_uwhex($123456 & $ffff, true)
txt.spc()
txt.print_uwhex(lsw($123456), true)
txt.spc()
txt.print_uwhex($123456 & $ffff, true)
txt.nl()
}
}

View File

@ -14,7 +14,7 @@
<keywords keywords="&amp;;-&gt;;@;alias;and;as;asmsub;break;clobbers;continue;do;downto;else;extsub;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
<keywords2 keywords="%address;%align;%asm;%asmbinary;%asminclude;%breakpoint;%encoding;%import;%ir;%launcher;%memtop;%option;%output;%zeropage;%zpallowed;%zpreserved;@align64;@alignpage;@alignword;@bank;@dirty;@nozp;@requirezp;@shared;@split;@zp;atascii:;cp437:;default:;iso16:;iso5:;iso:;kata:;petscii:;sc:" />
<keywords3 keywords="bool;byte;const;float;long;str;ubyte;uword;void;word" />
<keywords4 keywords="abs;bankof;call;callfar;callfar2;clamp;cmp;defer;divmod;len;lsb;max;memory;min;mkword;msb;peek;peekf;peekw;poke;pokef;pokew;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt" />
<keywords4 keywords="abs;call;callfar;callfar2;clamp;cmp;defer;divmod;len;lsb;lsw;max;memory;min;mkword;msb;msw;peek;peekf;peekw;poke;pokef;pokew;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sqrt" />
</highlighting>
<extensionMap>
<mapping ext="p8" />

View File

@ -27,7 +27,7 @@
<Keywords name="Keywords1">void const&#x000D;&#x000A;str&#x000D;&#x000A;byte ubyte bool&#x000D;&#x000A;long word uword&#x000D;&#x000A;float&#x000D;&#x000A;zp shared split requirezp nozp</Keywords>
<Keywords name="Keywords2">%address&#x000D;&#x000A;%asm&#x000D;&#x000A;%ir&#x000D;&#x000A;%asmbinary&#x000D;&#x000A;%asminclude&#x000D;&#x000A;%align&#x000D;&#x000A;%breakpoint&#x000D;&#x000A;%encoding&#x000D;&#x000A;%import&#x000D;&#x000A;%memtop&#x000D;&#x000A;%launcher&#x000D;&#x000A;%option&#x000D;&#x000A;%output&#x000D;&#x000A;%zeropage&#x000D;&#x000A;%zpreserved&#x000D;&#x000A;%zpallowed</Keywords>
<Keywords name="Keywords3">inline sub asmsub extsub&#x000D;&#x000A;clobbers&#x000D;&#x000A;asm&#x000D;&#x000A;if&#x000D;&#x000A;when else&#x000D;&#x000A;if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z&#x000D;&#x000A;for in step do while repeat unroll&#x000D;&#x000A;break continue return goto</Keywords>
<Keywords name="Keywords4">alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsl lsr memory mkword min max msb bankof peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sqrtw</Keywords>
<Keywords name="Keywords4">alias abs call callfar callfar2 clamp cmp defer divmod len lsb lsw lsl lsr memory mkword min max msb msw peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sqrtw</Keywords>
<Keywords name="Keywords5">true false&#x000D;&#x000A;not and or xor&#x000D;&#x000A;as to downto |&gt;</Keywords>
<Keywords name="Keywords6"></Keywords>
<Keywords name="Keywords7"></Keywords>

View File

@ -154,7 +154,7 @@ contexts:
- match: (\b(const)\b)
scope: storage.modifier.prog8
support:
- match: (\b(abs|atan|ceil|cos|cos8u|cos8|cos16u|cos16|deg|floor|ln|log2|rad|round|sin|sgn|sin8u|sin8|sin16u|sin16|sqrt16|sqrt|tan|any|all|len|max|min|reverse|sum|sort|memcopy|memset|memsetw|leftstr|rightstr|strlen|strcmp|substr|exit|lsb|msb|bankof|mkword|rnd|rndw|rndf|rol|rol2|ror|ror2|rsave|rrestore|read_flags|sizeof|set_carry|clear_carry|set_irqd|clear_irqd|swap)\b)
- match: (\b(abs|atan|ceil|cos|cos8u|cos8|cos16u|cos16|deg|floor|ln|log2|rad|round|sin|sgn|sin8u|sin8|sin16u|sin16|sqrt16|sqrt|tan|any|all|len|max|min|reverse|sum|sort|memcopy|memset|memsetw|leftstr|rightstr|strlen|strcmp|substr|exit|lsb|msb|lsw|msw|mkword|rnd|rndw|rndf|rol|rol2|ror|ror2|rsave|rrestore|read_flags|sizeof|set_carry|clear_carry|set_irqd|clear_irqd|swap)\b)
scope: support.function.prog8
variable:
- match: (\b\w+\b)

View File

@ -13,7 +13,7 @@ syn keyword prog8BuiltInFunc sgn sqrtw
syn keyword prog8BuiltInFunc len
" Miscellaneous functions
syn keyword prog8BuiltInFunc cmp divmod lsb msb bankof mkword min max peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex
syn keyword prog8BuiltInFunc cmp divmod lsb msb lsw msw mkword min max peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex
syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof setlsb setmsb
syn keyword prog8BuiltInFunc memory call callfar callfar2 clamp defer alias