mirror of
https://github.com/irmen/prog8.git
synced 2024-10-16 18:23:59 +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 {
|
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.
|
; -- fill the array 'name_ptrs' with (pointers to) the names of the files requested.
|
||||||
ubyte[256] names_buffer
|
uword names_buffer = memory("filenames", 512)
|
||||||
ubyte[256] names_buffer1 ; to store a bit more names
|
uword buffer_start = names_buffer
|
||||||
; TODO names_buffer = memory("filenames", 512)
|
|
||||||
uword buf_ptr = &names_buffer
|
|
||||||
names_buffer1[0] = 0 ; TODO force array to exist
|
|
||||||
ubyte files_found = 0
|
ubyte files_found = 0
|
||||||
if lf_start_list(drivenumber, pattern, suffixmatch) {
|
if lf_start_list(drivenumber, pattern, suffixmatch) {
|
||||||
while lf_next_entry() {
|
while lf_next_entry() {
|
||||||
@(name_ptrs) = lsb(buf_ptr)
|
@(name_ptrs) = lsb(names_buffer)
|
||||||
name_ptrs++
|
name_ptrs++
|
||||||
@(name_ptrs) = msb(buf_ptr)
|
@(name_ptrs) = msb(names_buffer)
|
||||||
name_ptrs++
|
name_ptrs++
|
||||||
buf_ptr += strcopy(diskio.list_filename, buf_ptr) + 1
|
names_buffer += strcopy(diskio.list_filename, names_buffer) + 1
|
||||||
files_found++
|
files_found++
|
||||||
if buf_ptr - &names_buffer > (len(names_buffer) + len(names_buffer1) - 18)
|
if names_buffer - buffer_start > 512-18
|
||||||
break
|
break
|
||||||
if files_found == max_names
|
if files_found == max_names
|
||||||
break
|
break
|
||||||
|
@ -697,7 +697,6 @@ class AsmGenInfo {
|
|||||||
var usedRegsaveY = false
|
var usedRegsaveY = false
|
||||||
var usedFloatEvalResultVar1 = false
|
var usedFloatEvalResultVar1 = false
|
||||||
var usedFloatEvalResultVar2 = false
|
var usedFloatEvalResultVar2 = false
|
||||||
val removals = mutableListOf<Statement>()
|
|
||||||
|
|
||||||
class ArrayIndexerInfo(val name: String, val replaces: ArrayIndex)
|
class ArrayIndexerInfo(val name: String, val replaces: ArrayIndex)
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
internal val loopEndLabels = ArrayDeque<String>()
|
internal val loopEndLabels = ArrayDeque<String>()
|
||||||
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()
|
private val blockLevelVarInits = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||||
internal val slabs = mutableMapOf<String, Int>()
|
internal val slabs = mutableMapOf<String, Int>()
|
||||||
|
internal val removals = mutableListOf<Pair<Statement, INameScope>>()
|
||||||
|
|
||||||
override fun compileToAssembly(): IAssemblyProgram {
|
override fun compileToAssembly(): IAssemblyProgram {
|
||||||
assemblyLines.clear()
|
assemblyLines.clear()
|
||||||
@ -64,6 +65,12 @@ internal class AsmGen(private val program: Program,
|
|||||||
throw AssemblyError("first block should be 'main'")
|
throw AssemblyError("first block should be 'main'")
|
||||||
for(b in program.allBlocks())
|
for(b in program.allBlocks())
|
||||||
block2asm(b)
|
block2asm(b)
|
||||||
|
|
||||||
|
for(removal in removals.toList()) {
|
||||||
|
removal.second.remove(removal.first)
|
||||||
|
removals.remove(removal)
|
||||||
|
}
|
||||||
|
|
||||||
slaballocations()
|
slaballocations()
|
||||||
footer()
|
footer()
|
||||||
|
|
||||||
@ -845,10 +852,12 @@ internal class AsmGen(private val program: Program,
|
|||||||
out("; statements")
|
out("; statements")
|
||||||
sub.statements.forEach{ translate(it) }
|
sub.statements.forEach{ translate(it) }
|
||||||
|
|
||||||
for(stmt in sub.asmGenInfo.removals) {
|
for(removal in removals.toList()) {
|
||||||
sub.remove(stmt)
|
if(removal.second==sub) {
|
||||||
|
removal.second.remove(removal.first)
|
||||||
|
removals.remove(removal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sub.asmGenInfo.removals.clear()
|
|
||||||
|
|
||||||
out("; variables")
|
out("; variables")
|
||||||
out("; register saves")
|
out("; register saves")
|
||||||
|
@ -35,25 +35,25 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
if(discardResult && resultToStack)
|
if(discardResult && resultToStack)
|
||||||
throw AssemblyError("cannot both discard the result AND put it onto stack")
|
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) {
|
when (func.name) {
|
||||||
"msb" -> funcMsb(fcall, resultToStack)
|
"msb" -> funcMsb(fcall, resultToStack)
|
||||||
"lsb" -> funcLsb(fcall, resultToStack)
|
"lsb" -> funcLsb(fcall, resultToStack)
|
||||||
"mkword" -> funcMkword(fcall, resultToStack)
|
"mkword" -> funcMkword(fcall, resultToStack)
|
||||||
"abs" -> funcAbs(fcall, func, resultToStack, scope)
|
"abs" -> funcAbs(fcall, func, resultToStack, sscope)
|
||||||
"swap" -> funcSwap(fcall)
|
"swap" -> funcSwap(fcall)
|
||||||
"min", "max" -> funcMinMax(fcall, func, resultToStack)
|
"min", "max" -> funcMinMax(fcall, func, resultToStack)
|
||||||
"sum" -> funcSum(fcall, resultToStack)
|
"sum" -> funcSum(fcall, resultToStack)
|
||||||
"any", "all" -> funcAnyAll(fcall, func, resultToStack)
|
"any", "all" -> funcAnyAll(fcall, func, resultToStack)
|
||||||
"sin8", "sin8u", "sin16", "sin16u",
|
"sin8", "sin8u", "sin16", "sin16u",
|
||||||
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, scope)
|
"cos8", "cos8u", "cos16", "cos16u" -> funcSinCosInt(fcall, func, resultToStack, sscope)
|
||||||
"sgn" -> funcSgn(fcall, func, resultToStack, scope)
|
"sgn" -> funcSgn(fcall, func, resultToStack, sscope)
|
||||||
"sin", "cos", "tan", "atan",
|
"sin", "cos", "tan", "atan",
|
||||||
"ln", "log2", "sqrt", "rad",
|
"ln", "log2", "sqrt", "rad",
|
||||||
"deg", "round", "floor", "ceil",
|
"deg", "round", "floor", "ceil",
|
||||||
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, scope)
|
"rndf" -> funcVariousFloatFuncs(fcall, func, resultToStack, sscope)
|
||||||
"rnd", "rndw" -> funcRnd(func, resultToStack)
|
"rnd", "rndw" -> funcRnd(func, resultToStack)
|
||||||
"sqrt16" -> funcSqrt16(fcall, func, resultToStack, scope)
|
"sqrt16" -> funcSqrt16(fcall, func, resultToStack, sscope)
|
||||||
"rol" -> funcRol(fcall)
|
"rol" -> funcRol(fcall)
|
||||||
"rol2" -> funcRol2(fcall)
|
"rol2" -> funcRol2(fcall)
|
||||||
"ror" -> funcRor(fcall)
|
"ror" -> funcRor(fcall)
|
||||||
@ -80,21 +80,21 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
"clear_irqd" -> asmgen.out(" cli")
|
"clear_irqd" -> asmgen.out(" cli")
|
||||||
"set_irqd" -> asmgen.out(" sei")
|
"set_irqd" -> asmgen.out(" sei")
|
||||||
"strlen" -> funcStrlen(fcall, resultToStack)
|
"strlen" -> funcStrlen(fcall, resultToStack)
|
||||||
"strcmp" -> funcStrcmp(fcall, func, resultToStack, scope)
|
"strcmp" -> funcStrcmp(fcall, func, resultToStack, sscope)
|
||||||
"strcopy" -> {
|
"strcopy" -> {
|
||||||
translateArguments(fcall.args, func, scope)
|
translateArguments(fcall.args, func, sscope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" jsr prog8_lib.func_strcopy_to_stack")
|
asmgen.out(" jsr prog8_lib.func_strcopy_to_stack")
|
||||||
else
|
else
|
||||||
asmgen.out(" jsr prog8_lib.func_strcopy")
|
asmgen.out(" jsr prog8_lib.func_strcopy")
|
||||||
}
|
}
|
||||||
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, scope)
|
"memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func, sscope)
|
||||||
"substr", "leftstr", "rightstr" -> {
|
"substr", "leftstr", "rightstr" -> {
|
||||||
translateArguments(fcall.args, func, scope)
|
translateArguments(fcall.args, func, sscope)
|
||||||
asmgen.out(" jsr prog8_lib.func_${func.name}")
|
asmgen.out(" jsr prog8_lib.func_${func.name}")
|
||||||
}
|
}
|
||||||
"exit" -> {
|
"exit" -> {
|
||||||
translateArguments(fcall.args, func, scope)
|
translateArguments(fcall.args, func, sscope)
|
||||||
asmgen.out(" jmp prog8_lib.func_exit")
|
asmgen.out(" jmp prog8_lib.func_exit")
|
||||||
}
|
}
|
||||||
"progend" -> {
|
"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.
|
// 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() }
|
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
|
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) {
|
if(CompilationTarget.instance is Cx16Target) {
|
||||||
when(func.name) {
|
when(func.name) {
|
||||||
"memset" -> {
|
"memset" -> {
|
||||||
|
if(scope==null)
|
||||||
|
throw AssemblyError("cannot call memset() outside of a subroutine scope")
|
||||||
// use the ROM function of the Cx16
|
// use the ROM function of the Cx16
|
||||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0)
|
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0)
|
||||||
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1)
|
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1)
|
||||||
@ -164,6 +166,9 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(scope==null)
|
||||||
|
throw AssemblyError("cannot call memcopy() outside of a subroutine scope")
|
||||||
|
|
||||||
// use the ROM function of the Cx16
|
// use the ROM function of the Cx16
|
||||||
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0)
|
asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.R0)
|
||||||
asmgen.assignExpressionToRegister(fcall.args[1], RegisterOrPair.R1)
|
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)
|
translateArguments(fcall.args, func, scope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" jsr prog8_lib.func_strcmp_stack")
|
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")
|
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)
|
translateArguments(fcall.args, func, scope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" jsr prog8_lib.func_sqrt16_stack")
|
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")
|
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)
|
translateArguments(fcall.args, func, scope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" jsr prog8_lib.func_${func.name}_stack")
|
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)
|
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)
|
translateArguments(fcall.args, func, scope)
|
||||||
if(resultToStack)
|
if(resultToStack)
|
||||||
asmgen.out(" jsr floats.func_${func.name}_stack")
|
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")
|
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)
|
translateArguments(fcall.args, func, scope)
|
||||||
val dt = fcall.args.single().inferType(program)
|
val dt = fcall.args.single().inferType(program)
|
||||||
if(resultToStack) {
|
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)
|
translateArguments(fcall.args, func, scope)
|
||||||
val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT)
|
val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT)
|
||||||
if(resultToStack) {
|
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) })
|
val callConv = signature.callConvention(args.map { it.inferType(program).typeOrElse(DataType.STRUCT) })
|
||||||
|
|
||||||
fun getSourceForFloat(value: Expression): AsmAssignSource {
|
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")
|
throw AssemblyError("float literals should have been converted into autovar")
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
|
if(scope==null)
|
||||||
|
throw AssemblyError("cannot use float arguments outside of a subroutine scope")
|
||||||
|
|
||||||
scope.asmGenInfo.usedFloatEvalResultVar2 = true
|
scope.asmGenInfo.usedFloatEvalResultVar2 = true
|
||||||
val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar2), value.position)
|
val variable = IdentifierReference(listOf(subroutineFloatEvalResultVar2), value.position)
|
||||||
val addr = AddressOf(variable, value.position)
|
val addr = AddressOf(variable, value.position)
|
||||||
|
@ -13,17 +13,9 @@ bmp_module {
|
|||||||
ubyte bpp
|
ubyte bpp
|
||||||
uword offsetx
|
uword offsetx
|
||||||
uword offsety
|
uword offsety
|
||||||
ubyte[256] palette0
|
uword palette = memory("palette", 256*4)
|
||||||
ubyte[256] palette1
|
|
||||||
ubyte[256] palette2
|
|
||||||
ubyte[256] palette3
|
|
||||||
uword total_read = 0
|
uword total_read = 0
|
||||||
|
|
||||||
palette0[0] = 0
|
|
||||||
palette1[0] = 0
|
|
||||||
palette2[0] = 0
|
|
||||||
palette3[0] = 0
|
|
||||||
|
|
||||||
if diskio.f_open(8, filenameptr) {
|
if diskio.f_open(8, filenameptr) {
|
||||||
size = diskio.f_read(header, $36)
|
size = diskio.f_read(header, $36)
|
||||||
if size==$36 {
|
if size==$36 {
|
||||||
@ -41,13 +33,13 @@ bmp_module {
|
|||||||
repeat skip_hdr
|
repeat skip_hdr
|
||||||
void c64.CHRIN()
|
void c64.CHRIN()
|
||||||
total_read += skip_hdr
|
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 {
|
if size==num_colors*4 {
|
||||||
total_read += size
|
total_read += size
|
||||||
repeat bm_data_offset - total_read
|
repeat bm_data_offset - total_read
|
||||||
void c64.CHRIN()
|
void c64.CHRIN()
|
||||||
gfx2.clear_screen()
|
gfx2.clear_screen()
|
||||||
custompalette.set_bgra(&palette0, num_colors)
|
custompalette.set_bgra(palette, num_colors)
|
||||||
decode_bitmap()
|
decode_bitmap()
|
||||||
load_ok = true
|
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)
|
; (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 {
|
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 {
|
sub show_image(uword filename) -> ubyte {
|
||||||
|
uword buffer = memory("buffer", 620*2) ; enough to store two scanlines of 640 bytes
|
||||||
ubyte read_success = false
|
ubyte read_success = false
|
||||||
uword bitmap_load_address = progend()
|
uword bitmap_load_address = progend()
|
||||||
; uword max_bitmap_size = $9eff - bitmap_load_address
|
; uword max_bitmap_size = $9eff - bitmap_load_address
|
||||||
@ -62,18 +57,18 @@ ci_module {
|
|||||||
if(diskio.f_open(8, filename)) {
|
if(diskio.f_open(8, filename)) {
|
||||||
uword size = diskio.f_read(buffer, 12) ; read the header
|
uword size = diskio.f_read(buffer, 12) ; read the header
|
||||||
if size==12 {
|
if size==12 {
|
||||||
if buffer[0]=='c' and buffer[1]=='i' and buffer[2] == 9 {
|
if @(buffer+0)=='c' and @(buffer+1)=='i' and @(buffer+2) == 9 {
|
||||||
uword width = mkword(buffer[4], buffer[3])
|
uword width = mkword(@(buffer+4), @(buffer+3))
|
||||||
uword height = mkword(buffer[6], buffer[5])
|
uword height = mkword(@(buffer+6), @(buffer+5))
|
||||||
ubyte bpp = buffer[7]
|
ubyte bpp = @(buffer+7)
|
||||||
uword num_colors = 2 ** bpp
|
uword num_colors = 2 ** bpp
|
||||||
ubyte flags = buffer[8]
|
ubyte flags = @(buffer+8)
|
||||||
ubyte compression = flags & %00000011
|
ubyte compression = flags & %00000011
|
||||||
ubyte palette_format = (flags & %00000100) >> 2
|
ubyte palette_format = (flags & %00000100) >> 2
|
||||||
ubyte bitmap_format = (flags & %00001000) >> 3
|
ubyte bitmap_format = (flags & %00001000) >> 3
|
||||||
; ubyte hscale = (flags & %00010000) >> 4
|
; ubyte hscale = (flags & %00010000) >> 4
|
||||||
; ubyte vscale = (flags & %00100000) >> 5
|
; 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
|
uword palette_size = num_colors*2
|
||||||
if palette_format
|
if palette_format
|
||||||
palette_size += num_colors ; 3
|
palette_size += num_colors ; 3
|
||||||
|
@ -4,10 +4,7 @@
|
|||||||
%import diskio
|
%import diskio
|
||||||
|
|
||||||
iff_module {
|
iff_module {
|
||||||
; TODO uword cmap = memory("palette", 768)
|
uword cmap
|
||||||
ubyte[256] cmap
|
|
||||||
ubyte[256] cmap1
|
|
||||||
ubyte[256] cmap2
|
|
||||||
uword num_colors
|
uword num_colors
|
||||||
uword[16] cycle_rates
|
uword[16] cycle_rates
|
||||||
uword[16] cycle_rate_ticks
|
uword[16] cycle_rate_ticks
|
||||||
@ -33,10 +30,8 @@ iff_module {
|
|||||||
ubyte have_cmap = false
|
ubyte have_cmap = false
|
||||||
ubyte cycle_crng = false
|
ubyte cycle_crng = false
|
||||||
ubyte cycle_ccrt = false
|
ubyte cycle_ccrt = false
|
||||||
cmap[0] = 0
|
|
||||||
cmap1[0] = 0
|
|
||||||
cmap2[0] = 0
|
|
||||||
num_cycles = 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) {
|
if diskio.f_open(8, filenameptr) {
|
||||||
size = diskio.f_read(buffer, 12)
|
size = diskio.f_read(buffer, 12)
|
||||||
@ -63,7 +58,7 @@ iff_module {
|
|||||||
}
|
}
|
||||||
else if chunk_id == "cmap" {
|
else if chunk_id == "cmap" {
|
||||||
have_cmap = true
|
have_cmap = true
|
||||||
diskio.f_read_exact(&cmap, chunk_size_lo)
|
diskio.f_read_exact(cmap, chunk_size_lo)
|
||||||
}
|
}
|
||||||
else if chunk_id == "crng" {
|
else if chunk_id == "crng" {
|
||||||
; DeluxePaint color cycle range
|
; DeluxePaint color cycle range
|
||||||
@ -110,7 +105,7 @@ iff_module {
|
|||||||
height /= 2 ; interlaced: just skip every odd scanline later
|
height /= 2 ; interlaced: just skip every odd scanline later
|
||||||
if camg & $0080 and have_cmap
|
if camg & $0080 and have_cmap
|
||||||
make_ehb_palette()
|
make_ehb_palette()
|
||||||
palette.set_rgb8(&cmap, num_colors)
|
palette.set_rgb8(cmap, num_colors)
|
||||||
if compression
|
if compression
|
||||||
decode_rle()
|
decode_rle()
|
||||||
else
|
else
|
||||||
@ -154,7 +149,7 @@ iff_module {
|
|||||||
|
|
||||||
sub make_ehb_palette() {
|
sub make_ehb_palette() {
|
||||||
; generate 32 additional Extra-Halfbrite colors in the cmap
|
; generate 32 additional Extra-Halfbrite colors in the cmap
|
||||||
uword palletteptr = &cmap
|
uword palletteptr = cmap
|
||||||
uword ehbptr = palletteptr + 32*3
|
uword ehbptr = palletteptr + 32*3
|
||||||
repeat 32 {
|
repeat 32 {
|
||||||
@(ehbptr) = @(palletteptr)>>1
|
@(ehbptr) = @(palletteptr)>>1
|
||||||
@ -320,7 +315,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1
|
|||||||
}
|
}
|
||||||
|
|
||||||
if changed
|
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) {
|
sub do_cycle(uword low, uword high, ubyte reversed) {
|
||||||
low *= 3
|
low *= 3
|
||||||
@ -332,7 +327,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1
|
|||||||
ubyte blue
|
ubyte blue
|
||||||
|
|
||||||
if reversed {
|
if reversed {
|
||||||
cptr = &cmap + low
|
cptr = cmap + low
|
||||||
red = @(cptr)
|
red = @(cptr)
|
||||||
green = @(cptr+1)
|
green = @(cptr+1)
|
||||||
blue = @(cptr+2)
|
blue = @(cptr+2)
|
||||||
@ -346,7 +341,7 @@ _masks .byte 128, 64, 32, 16, 8, 4, 2, 1
|
|||||||
cptr++
|
cptr++
|
||||||
@(cptr) = blue
|
@(cptr) = blue
|
||||||
} else {
|
} else {
|
||||||
cptr = &cmap + high
|
cptr = cmap + high
|
||||||
red = @(cptr)
|
red = @(cptr)
|
||||||
cptr++
|
cptr++
|
||||||
green = @(cptr)
|
green = @(cptr)
|
||||||
|
@ -98,9 +98,9 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
; else if strcmp(extension, ".ci")==0 {
|
; else if strcmp(extension, ".ci")==0 {
|
||||||
; txt.print("loading ")
|
;; txt.print("loading ")
|
||||||
; txt.print("ci\n")
|
;; txt.print("ci\n")
|
||||||
; if bmp_module.ci_module(filenameptr) {
|
; if ci_module.show_image(filenameptr) {
|
||||||
; cx16.wait(180)
|
; cx16.wait(180)
|
||||||
; } else {
|
; } else {
|
||||||
; load_error(filenameptr)
|
; load_error(filenameptr)
|
||||||
|
@ -5,38 +5,15 @@
|
|||||||
|
|
||||||
main {
|
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 () {
|
sub start () {
|
||||||
|
|
||||||
thing()
|
txt.chrout('\n')
|
||||||
thing()
|
txt.chrout('\n')
|
||||||
thing()
|
|
||||||
thing()
|
|
||||||
thing()
|
|
||||||
test_stack.test()
|
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…
Reference in New Issue
Block a user