mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +00:00
remove bankof(), documented msw() and lsw()
This commit is contained in:
parent
181f3e9eb1
commit
31ad8bdd8d
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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")) {
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
<keywords keywords="&;->;@;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" />
|
||||
|
@ -27,7 +27,7 @@
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte bool
long word uword
float
zp shared split requirezp nozp</Keywords>
|
||||
<Keywords name="Keywords2">%address
%asm
%ir
%asmbinary
%asminclude
%align
%breakpoint
%encoding
%import
%memtop
%launcher
%option
%output
%zeropage
%zpreserved
%zpallowed</Keywords>
|
||||
<Keywords name="Keywords3">inline sub asmsub extsub
clobbers
asm
if
when else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat unroll
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
not and or xor
as to downto |></Keywords>
|
||||
<Keywords name="Keywords6"></Keywords>
|
||||
<Keywords name="Keywords7"></Keywords>
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user