mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
fix issues with memory() function, rewrite examples to use it
This commit is contained in:
parent
7607d3d64a
commit
e17c18b653
@ -73,21 +73,18 @@ io_error:
|
||||
|
||||
sub list_files(ubyte drivenumber, uword pattern, ubyte suffixmatch, uword name_ptrs, ubyte max_names) -> ubyte {
|
||||
; -- fill the array 'name_ptrs' with (pointers to) the names of the files requested.
|
||||
ubyte[256] names_buffer
|
||||
ubyte[256] names_buffer1 ; to store a bit more names
|
||||
; TODO names_buffer = memory("filenames", 512)
|
||||
uword buf_ptr = &names_buffer
|
||||
names_buffer1[0] = 0 ; TODO force array to exist
|
||||
uword names_buffer = memory("filenames", 512)
|
||||
uword buffer_start = names_buffer
|
||||
ubyte files_found = 0
|
||||
if lf_start_list(drivenumber, pattern, suffixmatch) {
|
||||
while lf_next_entry() {
|
||||
@(name_ptrs) = lsb(buf_ptr)
|
||||
@(name_ptrs) = lsb(names_buffer)
|
||||
name_ptrs++
|
||||
@(name_ptrs) = msb(buf_ptr)
|
||||
@(name_ptrs) = msb(names_buffer)
|
||||
name_ptrs++
|
||||
buf_ptr += strcopy(diskio.list_filename, buf_ptr) + 1
|
||||
names_buffer += strcopy(diskio.list_filename, names_buffer) + 1
|
||||
files_found++
|
||||
if buf_ptr - &names_buffer > (len(names_buffer) + len(names_buffer1) - 18)
|
||||
if names_buffer - buffer_start > 512-18
|
||||
break
|
||||
if files_found == max_names
|
||||
break
|
||||
|
@ -697,7 +697,6 @@ class AsmGenInfo {
|
||||
var usedRegsaveY = false
|
||||
var usedFloatEvalResultVar1 = false
|
||||
var usedFloatEvalResultVar2 = false
|
||||
val removals = mutableListOf<Statement>()
|
||||
|
||||
class ArrayIndexerInfo(val name: String, val replaces: ArrayIndex)
|
||||
}
|
||||
|
@ -51,6 +51,7 @@ internal class AsmGen(private val program: Program,
|
||||
internal val loopEndLabels = ArrayDeque<String>()
|
||||
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||
internal val slabs = mutableMapOf<String, Int>()
|
||||
internal val removals = mutableListOf<Pair<Statement, INameScope>>()
|
||||
|
||||
override fun compileToAssembly(): IAssemblyProgram {
|
||||
assemblyLines.clear()
|
||||
@ -64,6 +65,12 @@ internal class AsmGen(private val program: Program,
|
||||
throw AssemblyError("first block should be 'main'")
|
||||
for(b in program.allBlocks())
|
||||
block2asm(b)
|
||||
|
||||
for(removal in removals.toList()) {
|
||||
removal.second.remove(removal.first)
|
||||
removals.remove(removal)
|
||||
}
|
||||
|
||||
slaballocations()
|
||||
footer()
|
||||
|
||||
@ -845,10 +852,12 @@ internal class AsmGen(private val program: Program,
|
||||
out("; statements")
|
||||
sub.statements.forEach{ translate(it) }
|
||||
|
||||
for(stmt in sub.asmGenInfo.removals) {
|
||||
sub.remove(stmt)
|
||||
for(removal in removals.toList()) {
|
||||
if(removal.second==sub) {
|
||||
removal.second.remove(removal.first)
|
||||
removals.remove(removal)
|
||||
}
|
||||
}
|
||||
sub.asmGenInfo.removals.clear()
|
||||
|
||||
out("; variables")
|
||||
out("; register saves")
|
||||
|
@ -35,25 +35,25 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
if(discardResult && resultToStack)
|
||||
throw AssemblyError("cannot both discard the result AND put it onto stack")
|
||||
|
||||
val scope = (fcall as Node).definingSubroutine()!!
|
||||
val sscope = (fcall as Node).definingSubroutine()
|
||||
when (func.name) {
|
||||
"msb" -> funcMsb(fcall, resultToStack)
|
||||
"lsb" -> funcLsb(fcall, resultToStack)
|
||||
"mkword" -> funcMkword(fcall, resultToStack)
|
||||
"abs" -> funcAbs(fcall, func, resultToStack, scope)
|
||||
"abs" -> funcAbs(fcall, func, resultToStack, sscope)
|
||||
"swap" -> funcSwap(fcall)
|
||||
"min", "max" -> funcMinMax(fcall, func, resultToStack)
|
||||
"sum" -> funcSum(fcall, resultToStack)
|
||||
"any", "all" -> funcAnyAll(fcall, func, resultToStack)
|
||||
"sin8", "sin8u", "sin16", "sin16u",
|
||||
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, scope)
|
||||
"sgn" -> funcSgn(fcall, func, resultToStack, scope)
|
||||
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, sscope)
|
||||
"sgn" -> funcSgn(fcall, func, resultToStack, sscope)
|
||||
"sin", "cos", "tan", "atan",
|
||||
"ln", "log2", "sqrt", "rad",
|
||||
"deg", "round", "floor", "ceil",
|
||||
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, scope)
|
||||
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, sscope)
|
||||
"rnd", "rndw" -> funcRnd(func, resultToStack)
|
||||
"sqrt16" -> funcSqrt16(fcall, func, resultToStack, scope)
|
||||
"sqrt16" -> funcSqrt16(fcall, func, resultToStack, sscope)
|
||||
"rol" -> funcRol(fcall)
|
||||
"rol2" -> funcRol2(fcall)
|
||||
"ror" -> funcRor(fcall)
|
||||
@ -80,21 +80,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
"clear_irqd" -> asmgen.out(" cli")
|
||||
"set_irqd" -> asmgen.out(" sei")
|
||||
"strlen" -> funcStrlen(fcall, resultToStack)
|
||||
"strcmp" -> funcStrcmp(fcall, func, resultToStack, scope)
|
||||
"strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope)
|
||||
"strcopy" -> {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
translateArguments(fcall.args, func, sscope)
|
||||
if(resultToStack)
|
||||
asmgen.out(" jsr prog8_lib.func_strcopy_to_stack")
|
||||
else
|
||||
asmgen.out(" jsr prog8_lib.func_strcopy")
|
||||
}
|
||||
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, scope)
|
||||
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, sscope)
|
||||
"substr", "leftstr", "rightstr" -> {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
translateArguments(fcall.args, func, sscope)
|
||||
asmgen.out(" jsr prog8_lib.func_${func.name}")
|
||||
}
|
||||
"exit" -> {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
translateArguments(fcall.args, func, sscope)
|
||||
asmgen.out(" jmp prog8_lib.func_exit")
|
||||
}
|
||||
"progend" -> {
|
||||
@ -138,14 +138,16 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
|
||||
// remove the variable for the name, it's not used as a variable only as a tag for the assembler.
|
||||
val nameDecl = scope.statements.single { it is VarDecl && it.name==nameRef.nameInSource.single() }
|
||||
(scope as Subroutine).asmGenInfo.removals.add(nameDecl)
|
||||
asmgen.removals.add(Pair(nameDecl, scope))
|
||||
asmgen.slabs[name] = size
|
||||
}
|
||||
|
||||
private fun funcMemSetCopy(fcall: IFunctionCall, func: FSignature, scope: Subroutine) {
|
||||
private fun funcMemSetCopy(fcall: IFunctionCall, func: FSignature, scope: Subroutine?) {
|
||||
if(CompilationTarget.instance is Cx16Target) {
|
||||
when(func.name) {
|
||||
"memset" -> {
|
||||
if(scope==null)
|
||||
throw AssemblyError("cannot call memset() outside of a subroutine scope")
|
||||
// use the ROM function of the Cx16
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0)
|
||||
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1)
|
||||
@ -164,6 +166,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
return
|
||||
}
|
||||
|
||||
if(scope==null)
|
||||
throw AssemblyError("cannot call memcopy() outside of a subroutine scope")
|
||||
|
||||
// use the ROM function of the Cx16
|
||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0)
|
||||
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1)
|
||||
@ -192,7 +197,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
|
||||
private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
if(resultToStack)
|
||||
asmgen.out(" jsr prog8_lib.func_strcmp_stack")
|
||||
@ -200,7 +205,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
asmgen.out(" jsr prog8_lib.func_strcmp")
|
||||
}
|
||||
|
||||
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
|
||||
private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
if(resultToStack)
|
||||
asmgen.out(" jsr prog8_lib.func_sqrt16_stack")
|
||||
@ -208,7 +213,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
asmgen.out(" jsr prog8_lib.func_sqrt16_into_A")
|
||||
}
|
||||
|
||||
private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
|
||||
private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
if(resultToStack)
|
||||
asmgen.out(" jsr prog8_lib.func_${func.name}_stack")
|
||||
@ -474,7 +479,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
asmgen.assignExpressionToVariable(indexerExpr, "prog8_lib.${operation}_array_u${dt}._arg_index", DataType.UBYTE, null)
|
||||
}
|
||||
|
||||
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
|
||||
private fun funcVariousFloatFuncs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
if(resultToStack)
|
||||
asmgen.out(" jsr floats.func_${func.name}_stack")
|
||||
@ -482,7 +487,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
asmgen.out(" jsr floats.func_${func.name}_fac1")
|
||||
}
|
||||
|
||||
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
|
||||
private fun funcSgn(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
val dt = fcall.args.single().inferType(program)
|
||||
if(resultToStack) {
|
||||
@ -972,7 +977,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine) {
|
||||
private fun funcAbs(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean, scope: Subroutine?) {
|
||||
translateArguments(fcall.args, func, scope)
|
||||
val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT)
|
||||
if(resultToStack) {
|
||||
@ -1070,7 +1075,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
""")
|
||||
}
|
||||
|
||||
private fun translateArguments(args: MutableList<Expression>, signature: FSignature, scope: Subroutine) {
|
||||
private fun translateArguments(args: MutableList<Expression>, signature: FSignature, scope: Subroutine?) {
|
||||
val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) })
|
||||
|
||||
fun getSourceForFloat(value: Expression): AsmAssignSource {
|
||||
@ -1083,6 +1088,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
||||
throw AssemblyError("float literals should have been converted into autovar")
|
||||
}
|
||||
else -> {
|
||||
if(scope==null)
|
||||
throw AssemblyError("cannot use float arguments outside of a subroutine scope")
|
||||
|
||||
scope.asmGenInfo.usedFloatEvalResultVar2 = true
|
||||
val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar2), value.position)
|
||||
val addr = AddressOf(variable, value.position)
|
||||
|
@ -13,17 +13,9 @@ bmp_module {
|
||||
ubyte bpp
|
||||
uword offsetx
|
||||
uword offsety
|
||||
ubyte[256] palette0
|
||||
ubyte[256] palette1
|
||||
ubyte[256] palette2
|
||||
ubyte[256] palette3
|
||||
uword palette = memory("palette", 256*4)
|
||||
uword total_read = 0
|
||||
|
||||
palette0[0] = 0
|
||||
palette1[0] = 0
|
||||
palette2[0] = 0
|
||||
palette3[0] = 0
|
||||
|
||||
if diskio.f_open(8, filenameptr) {
|
||||
size = diskio.f_read(header, $36)
|
||||
if size==$36 {
|
||||
@ -41,13 +33,13 @@ bmp_module {
|
||||
repeat skip_hdr
|
||||
void c64.CHRIN()
|
||||
total_read += skip_hdr
|
||||
size = diskio.f_read(&palette0, num_colors*4)
|
||||
size = diskio.f_read(palette, num_colors*4)
|
||||
if size==num_colors*4 {
|
||||
total_read += size
|
||||
repeat bm_data_offset - total_read
|
||||
void c64.CHRIN()
|
||||
gfx2.clear_screen()
|
||||
custompalette.set_bgra(&palette0, num_colors)
|
||||
custompalette.set_bgra(palette, num_colors)
|
||||
decode_bitmap()
|
||||
load_ok = true
|
||||
}
|
||||
|
@ -47,14 +47,9 @@
|
||||
; (doing it in chunks of 8 kb allows for sticking each chunk in one of the banked 8kb ram blocks, or even copy it directly to the screen)
|
||||
|
||||
ci_module {
|
||||
%option force_output
|
||||
ubyte[256] buffer
|
||||
ubyte[256] buffer2 ; add two more buffers to make enough space
|
||||
ubyte[256] buffer3 ; to store a 256 color palette
|
||||
ubyte[256] buffer4 ; .. and some more to be able to store 1280=
|
||||
ubyte[256] buffer5 ; two 640 bytes worth of bitmap scanline data
|
||||
|
||||
sub show_image(uword filename) -> ubyte {
|
||||
uword buffer = memory("buffer", 620*2) ; enough to store two scanlines of 640 bytes
|
||||
ubyte read_success = false
|
||||
uword bitmap_load_address = progend()
|
||||
; uword max_bitmap_size = $9eff - bitmap_load_address
|
||||
@ -62,18 +57,18 @@ ci_module {
|
||||
if(diskio.f_open(8, filename)) {
|
||||
uword size = diskio.f_read(buffer, 12) ; read the header
|
||||
if size==12 {
|
||||
if buffer[0]=='c' and buffer[1]=='i' and buffer[2] == 9 {
|
||||
uword width = mkword(buffer[4], buffer[3])
|
||||
uword height = mkword(buffer[6], buffer[5])
|
||||
ubyte bpp = buffer[7]
|
||||
if @(buffer+0)=='c' and @(buffer+1)=='i' and @(buffer+2) == 9 {
|
||||
uword width = mkword(@(buffer+4), @(buffer+3))
|
||||
uword height = mkword(@(buffer+6), @(buffer+5))
|
||||
ubyte bpp = @(buffer+7)
|
||||
uword num_colors = 2 ** bpp
|
||||
ubyte flags = buffer[8]
|
||||
ubyte flags = @(buffer+8)
|
||||
ubyte compression = flags & %00000011
|
||||
ubyte palette_format = (flags & %00000100) >> 2
|
||||
ubyte bitmap_format = (flags & %00001000) >> 3
|
||||
; ubyte hscale = (flags & %00010000) >> 4
|
||||
; ubyte vscale = (flags & %00100000) >> 5
|
||||
uword bitmap_size = mkword(buffer[10], buffer[9])
|
||||
uword bitmap_size = mkword(@(buffer+10), @(buffer+9))
|
||||
uword palette_size = num_colors*2
|
||||
if palette_format
|
||||
palette_size += num_colors ; 3
|
||||
|
@ -4,10 +4,7 @@
|
||||
%import diskio
|
||||
|
||||
iff_module {
|
||||
; TODO uword cmap = memory("palette", 768)
|
||||
ubyte[256] cmap
|
||||
ubyte[256] cmap1
|
||||
ubyte[256] cmap2
|
||||
uword cmap
|
||||
uword num_colors
|
||||
uword[16] cycle_rates
|
||||
uword[16] cycle_rate_ticks
|
||||
@ -33,10 +30,8 @@ iff_module {
|
||||
ubyte have_cmap = false
|
||||
ubyte cycle_crng = false
|
||||
ubyte cycle_ccrt = false
|
||||
cmap[0] = 0
|
||||
cmap1[0] = 0
|
||||
cmap2[0] = 0
|
||||
num_cycles = 0
|
||||
cmap = memory("palette", 256*4) ; only use 768 of these, but this allows re-use of the same block that the bmp module allocates
|
||||
|
||||
if diskio.f_open(8, filenameptr) {
|
||||
size = diskio.f_read(buffer, 12)
|
||||
@ -63,7 +58,7 @@ iff_module {
|
||||
}
|
||||
else if chunk_id == "cmap" {
|
||||
have_cmap = true
|
||||
diskio.f_read_exact(&cmap, chunk_size_lo)
|
||||
diskio.f_read_exact(cmap, chunk_size_lo)
|
||||
}
|
||||
else if chunk_id == "crng" {
|
||||
; DeluxePaint color cycle range
|
||||
@ -110,7 +105,7 @@ iff_module {
|
||||
height /= 2 ; interlaced: just skip every odd scanline later
|
||||
if camg & $0080 and have_cmap
|
||||
make_ehb_palette()
|
||||
palette.set_rgb8(&cmap, num_colors)
|
||||
palette.set_rgb8(cmap, num_colors)
|
||||
if compression
|
||||
decode_rle()
|
||||
else
|
||||
@ -154,7 +149,7 @@ iff_module {
|
||||
|
||||
sub make_ehb_palette() {
|
||||
; generate 32 additional Extra-Halfbrite colors in the cmap
|
||||
uword palletteptr = &cmap
|
||||
uword palletteptr = cmap
|
||||
uword ehbptr = palletteptr + 32*3
|
||||
repeat 32 {
|
||||
@(ehbptr) = @(palletteptr)>>1
|
||||
@ -320,7 +315,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1
|
||||
}
|
||||
|
||||
if changed
|
||||
palette.set_rgb8(&cmap, num_colors) ; set the new palette
|
||||
palette.set_rgb8(cmap, num_colors) ; set the new palette
|
||||
|
||||
sub do_cycle(uword low, uword high, ubyte reversed) {
|
||||
low *= 3
|
||||
@ -332,7 +327,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1
|
||||
ubyte blue
|
||||
|
||||
if reversed {
|
||||
cptr = &cmap + low
|
||||
cptr = cmap + low
|
||||
red = @(cptr)
|
||||
green = @(cptr+1)
|
||||
blue = @(cptr+2)
|
||||
@ -346,7 +341,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1
|
||||
cptr++
|
||||
@(cptr) = blue
|
||||
} else {
|
||||
cptr = &cmap + high
|
||||
cptr = cmap + high
|
||||
red = @(cptr)
|
||||
cptr++
|
||||
green = @(cptr)
|
||||
|
@ -98,9 +98,9 @@ main {
|
||||
}
|
||||
}
|
||||
; else if strcmp(extension, ".ci")==0 {
|
||||
; txt.print("loading ")
|
||||
; txt.print("ci\n")
|
||||
; if bmp_module.ci_module(filenameptr) {
|
||||
;; txt.print("loading ")
|
||||
;; txt.print("ci\n")
|
||||
; if ci_module.show_image(filenameptr) {
|
||||
; cx16.wait(180)
|
||||
; } else {
|
||||
; load_error(filenameptr)
|
||||
|
@ -5,38 +5,15 @@
|
||||
|
||||
main {
|
||||
|
||||
;uword cmap = memory("palette", 256*4) ; only use 768 of these, but this allows re-use of the same block that the bmp module allocates
|
||||
uword num_colors = rnd()
|
||||
|
||||
sub start () {
|
||||
|
||||
thing()
|
||||
thing()
|
||||
thing()
|
||||
thing()
|
||||
thing()
|
||||
txt.chrout('\n')
|
||||
txt.chrout('\n')
|
||||
test_stack.test()
|
||||
|
||||
sub thing() -> ubyte {
|
||||
uword buffer = memory("buffer", 512)
|
||||
uword buffer2 = memory("buffer", 512)
|
||||
uword buffer3 = memory("cache", 20)
|
||||
|
||||
txt.print_uwhex(buffer, true)
|
||||
txt.chrout('\n')
|
||||
txt.print_uwhex(buffer2, true)
|
||||
txt.chrout('\n')
|
||||
txt.print_uwhex(buffer3, true)
|
||||
txt.chrout('\n')
|
||||
buffer+=$1111
|
||||
buffer2+=$1111
|
||||
buffer3+=$1111
|
||||
txt.print_uwhex(buffer, true)
|
||||
txt.chrout('\n')
|
||||
txt.print_uwhex(buffer2, true)
|
||||
txt.chrout('\n')
|
||||
txt.print_uwhex(buffer3, true)
|
||||
txt.chrout('\n')
|
||||
txt.chrout('\n')
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user