From f210c8b0db26ac591d0e522c8ec20f677fa51047 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 12 Jul 2026 22:09:40 +0200 Subject: [PATCH] amiga library calls --- .../src/prog8/code/target/Amiga500Target.kt | 42 +- codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt | 2 +- .../prog8/codegen/m68k/AssemblyProgramM68k.kt | 43 +- .../src/prog8/codegen/m68k/InstrControl.kt | 25 +- compiler/res/prog8lib/amiga500/conv.p8 | 351 +++++++++++- compiler/res/prog8lib/amiga500/dos.p8 | 170 ++++++ compiler/res/prog8lib/amiga500/exec.p8 | 124 +++++ compiler/res/prog8lib/amiga500/graphics.p8 | 172 ++++++ compiler/res/prog8lib/amiga500/icon.p8 | 33 ++ compiler/res/prog8lib/amiga500/intuition.p8 | 136 +++++ compiler/res/prog8lib/amiga500/prog8_lib.p8 | 12 +- compiler/res/prog8lib/amiga500/strings.p8 | 2 +- compiler/res/prog8lib/amiga500/syslib.p8 | 31 +- compiler/res/prog8lib/amiga500/textio.p8 | 182 ++++++- compiler/res/prog8lib/qemu68k/strings.p8 | 132 +---- .../prog8lib/shared_m68k_memory_routines.p8 | 2 +- compiler/res/prog8lib/shared_m68k_strings.p8 | 130 +++++ .../compiler/astprocessing/DeferProcessor.kt | 4 +- .../compiler/astprocessing/M68kAstChecker.kt | 19 +- .../astprocessing/SimplifiedAstMaker.kt | 5 +- examples/m68k/amigahello.p8 | 2 +- examples/test.p8 | 214 ++------ .../src/prog8/intermediate/IRInstructions.kt | 2 +- scripts/compilenew6502-noopt.sh | 10 - scripts/compilenew6502.sh | 10 - scripts/sfd2prog8.py | 501 ++++++++++++++++++ 26 files changed, 1972 insertions(+), 384 deletions(-) create mode 100644 compiler/res/prog8lib/amiga500/dos.p8 create mode 100644 compiler/res/prog8lib/amiga500/exec.p8 create mode 100644 compiler/res/prog8lib/amiga500/graphics.p8 create mode 100644 compiler/res/prog8lib/amiga500/icon.p8 create mode 100644 compiler/res/prog8lib/amiga500/intuition.p8 create mode 100644 compiler/res/prog8lib/shared_m68k_strings.p8 delete mode 100755 scripts/compilenew6502-noopt.sh delete mode 100755 scripts/compilenew6502.sh create mode 100755 scripts/sfd2prog8.py diff --git a/codeCore/src/prog8/code/target/Amiga500Target.kt b/codeCore/src/prog8/code/target/Amiga500Target.kt index 73233ac87..ca9ac0d4c 100644 --- a/codeCore/src/prog8/code/target/Amiga500Target.kt +++ b/codeCore/src/prog8/code/target/Amiga500Target.kt @@ -10,7 +10,7 @@ class Amiga500Target: ICompilationTarget, IMemSizer by NormalMemSizer(4, pointerSize = 4) { override val name = NAME - override val supportsBankedCalls = false + override val supportsBankedCalls = true override val defaultEncoding = Encoding.ISO override val libraryPath = null override val customLauncher = emptyList() @@ -20,6 +20,46 @@ class Amiga500Target: ICompilationTarget, companion object { const val NAME = "amiga500" + + /** needed to map bank numbers to libraries in extsub/CALLFAR library calls */ + val LibraryNumbers = mapOf( + 1 to "exec", + 2 to "dos", + 3 to "graphics", + 4 to "intuition", + 5 to "gadtools", + 6 to "layers", + 7 to "asl", + 8 to "console", + 9 to "utility", + 10 to "expansion", + 11 to "icon", + 12 to "wb", + 13 to "diskfont", + 14 to "iffparse", + 15 to "input", + 16 to "keymap", + 17 to "locale", + 18 to "timer", + 19 to "lowlevel", + 20 to "mathffp", + 21 to "mathieeesingbas", + 22 to "mathieeesingtrans", + 23 to "mathieeedoubbas", + 24 to "mathieeedoubtrans", + 25 to "mathtrans", + 26 to "nonvolatile", + 27 to "realtime", + 28 to "translator", + 29 to "rexxsyslib", + 30 to "commodities", + 31 to "datatypes", + 32 to "disk", + 33 to "amigaguide", + 34 to "arexx", + 35 to "battclock", + 36 to "battmem" + ) } override val cpu = CpuType.M68000 diff --git a/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt b/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt index 910bd19c5..b0af851e4 100644 --- a/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt +++ b/codeGenM68k/src/prog8/codegen/m68k/AsmGen.kt @@ -228,7 +228,7 @@ internal class AsmGen(val program: IRProgram, private val target: ICompilationTa emitRaw("; NOTE: M68k is BIG-ENDIAN — bytes within words/longs are MSB-first") emitRaw("; Motorola syntax rules:") emitRaw("; - Operations: mnemonic src,dst (src is first operand, dst is second)") - emitRaw("; - NOTE: vasm requires NO space after the comma between operands") + emitRaw("; - NOTE: vasm preferes NO space after the comma between operands (but with -spaces it allows it)") emitRaw("; - Addressing: Dn=datareg, An=addrreg, (An)=indirect, imm=#value") emitRaw("; - Labels: global = alphanumeric+underscore (add -ldots for dots in labels)") emitRaw("; local = prefix '.' or suffix '$', valid between two global labels") diff --git a/codeGenM68k/src/prog8/codegen/m68k/AssemblyProgramM68k.kt b/codeGenM68k/src/prog8/codegen/m68k/AssemblyProgramM68k.kt index 3353814da..8e88cd206 100644 --- a/codeGenM68k/src/prog8/codegen/m68k/AssemblyProgramM68k.kt +++ b/codeGenM68k/src/prog8/codegen/m68k/AssemblyProgramM68k.kt @@ -2,6 +2,7 @@ package prog8.codegen.m68k import prog8.code.assembly.IAssemblyProgram import prog8.code.core.* +import prog8.code.target.Amiga500Target import java.nio.file.Files import java.nio.file.Path @@ -61,6 +62,7 @@ class AssemblyProgramM68k(override val name: String, private val outputDir: Path "-Fbin", "-opt-speed", "-ldots", + "-spaces", "-join=0x${loadAddr.toString(16)}", "-o", rawFile.toString(), assemblyFile.toString() @@ -82,6 +84,7 @@ class AssemblyProgramM68k(override val name: String, private val outputDir: Path "-Felf", "-opt-speed", "-ldots", + "-spaces", "-o", objFile.toString(), assemblyFile.toString() ) @@ -114,16 +117,36 @@ class AssemblyProgramM68k(override val name: String, private val outputDir: Path OutputType.AMIGAHUNK -> { // Step 1: assemble directly to AmigaHunk executable file val exefile = outputDir.resolve(name) - val assembleCmd = mutableListOf( - "vasmm68k_mot", - "-m$cpu", - "-m68881", // enable FPU - "-Fhunkexe", - "-opt-speed", - "-ldots", - "-o", exefile.toString(), - assemblyFile.toString() - ) + val assembleCmd = when(options.compTarget) { + is Amiga500Target -> { + // amiga 500 with kickstart 1.3 + mutableListOf( + "vasmm68k_mot", + "-m$cpu", + "-Fhunkexe", + "-kick1hunks", // old hunk format compatible with AmigaDOS 1.3 + "-opt-speed", + "-ldots", + "-spaces", + "-o", exefile.toString(), + assemblyFile.toString() + ) + } + else -> { + // assume at least an amiga 1200 with 68020 and optional FPU + mutableListOf( + "vasmm68k_mot", + "-m$cpu", + "-m68881", // enable FPU + "-Fhunkexe", + "-opt-speed", + "-ldots", + "-spaces", + "-o", exefile.toString(), + assemblyFile.toString() + ) + } + } if (options.asmQuiet) assembleCmd.add("-quiet") if (!runProcess(assembleCmd, options.quiet, "vasm")) diff --git a/codeGenM68k/src/prog8/codegen/m68k/InstrControl.kt b/codeGenM68k/src/prog8/codegen/m68k/InstrControl.kt index 813e9582a..f71e3efda 100644 --- a/codeGenM68k/src/prog8/codegen/m68k/InstrControl.kt +++ b/codeGenM68k/src/prog8/codegen/m68k/InstrControl.kt @@ -18,6 +18,7 @@ package prog8.codegen.m68k import prog8.code.core.Statusflag import prog8.code.core.toHex +import prog8.code.target.Amiga500Target import prog8.intermediate.FunctionCallArgs import prog8.intermediate.IRDataType import prog8.intermediate.IRInstruction @@ -55,11 +56,31 @@ internal fun AsmGen.translateControl(insn: IRInstruction) { } Opcode.CALLFAR -> { - TODO("CALLFAR (not applicable to M68k)") + if(program.options.compTarget.name.contains("amiga")) { + val offset = insn.address!!.value.toInt() + require(offset<0) { "amiga libcall offsets should all be <0" } + val bank = insn.immediate!! + if(bank==1) { + // exec.library is always at 4.w + emitLine("move.l 4.w,a6") + } else { + val library = Amiga500Target.LibraryNumbers.getValue(bank) + val baseVar = "sys.${library.capitalize()}Base" + emitLine("move.l $baseVar,a6") + } + + val fcallArgs = insn.fcallArgs!! + for(arg in fcallArgs.arguments) + translateArgument(arg) + emitLine("jsr $offset(a6)") // do the actual call + for(ret in fcallArgs.returns) + translateReturnValue(ret) + } + else error("CALLFAR not applicable on this M68k") } Opcode.CALLFARVB -> { - TODO("CALLFARVB (not applicable to M68k)") + error("CALLFARVB not applicable on M68k") } Opcode.SYSCALL -> { diff --git a/compiler/res/prog8lib/amiga500/conv.p8 b/compiler/res/prog8lib/amiga500/conv.p8 index 29aba2b3a..22af52f8f 100644 --- a/compiler/res/prog8lib/amiga500/conv.p8 +++ b/compiler/res/prog8lib/amiga500/conv.p8 @@ -1 +1,350 @@ -; TODO +; Number conversions routines. + +%import strings + +conv { + +; ----- number conversions to decimal strings ---- + + %option ignore_unused + str string_out = "????????????????" ; result buffer for the string conversion routines + + +sub str_ub0(ubyte value) -> str { + ; ---- convert the ubyte in A in decimal string form, with left padding 0s (3 positions total) + ; TODO + return "todo" +} + +sub str_ub(ubyte value) -> str { + ; ---- convert the ubyte in A in decimal string form, without left padding 0s + ; TODO + return "todo" +} + +sub str_b(byte value) -> str { + ; ---- convert the byte in A in decimal string form, without left padding 0s + ; TODO + return "todo" +} + +private str hex_digits = "0123456789abcdef" + +sub str_ubhex (ubyte value) -> str { + ; ---- convert the ubyte in A in hex string form + string_out[0] = hex_digits[value>>4] + string_out[1] = hex_digits[value&15] + string_out[2] = 0 + return string_out +} + +sub str_ubbin (ubyte value) -> str { + ; ---- convert the ubyte in A in binary string form + ^^ubyte out_ptr = &string_out + repeat 8 { + rol(value) + if_cc + @(out_ptr) = '0' + else + @(out_ptr) = '1' + out_ptr++ + } + @(out_ptr) = 0 + return string_out +} + +sub str_uwbin (uword value) -> str { + ; ---- convert the uword in A/Y in binary string form + ^^ubyte out_ptr = &string_out + repeat 16 { + rol(value) + if_cc + @(out_ptr) = '0' + else + @(out_ptr) = '1' + out_ptr++ + } + @(out_ptr) = 0 + return string_out +} + +sub str_uwhex (uword value) -> str { + ; ---- convert the uword in hexadecimal string form (4 digits) + ubyte bits = msb(value) + string_out[0] = hex_digits[bits>>4] + string_out[1] = hex_digits[bits&15] + bits = lsb(value) + string_out[2] = hex_digits[bits>>4] + string_out[3] = hex_digits[bits&15] + string_out[4] = 0 + return string_out +} + +sub str_ulhex (long value) -> str { + ; ---- convert the long in hexadecimal string form (8 digits) + uword upperw = msw(value) + uword lowerw = lsw(value) + ubyte bits = msb(upperw) + string_out[0] = hex_digits[bits>>4] + string_out[1] = hex_digits[bits&15] + bits = lsb(upperw) + string_out[2] = hex_digits[bits>>4] + string_out[3] = hex_digits[bits&15] + bits = msb(lowerw) + string_out[4] = hex_digits[bits>>4] + string_out[5] = hex_digits[bits&15] + bits = lsb(lowerw) + string_out[6] = hex_digits[bits>>4] + string_out[7] = hex_digits[bits&15] + string_out[8] = 0 + return string_out +} + +sub str_uw0 (uword value) -> str { + ; ---- convert the uword in A/Y in decimal string form, with left padding 0s (5 positions total) + uword value2 = value/10 + ubyte digits = value-value2*10 as ubyte + uword value3 = value2/10 + ubyte tens = value2-value3*10 as ubyte + uword value4 = value3/10 + ubyte hundreds = value3-value4*10 as ubyte + uword value5 = value4/10 + ubyte thousands = value4-value5*10 as ubyte + uword value6 = value5/10 + ubyte tenthousands = value5-value6*10 as ubyte + string_out[0] = tenthousands+'0' + string_out[1] = thousands+'0' + string_out[2] = hundreds+'0' + string_out[3] = tens+'0' + string_out[4] = digits+'0' + string_out[5] = 0 + return string_out +} + +sub str_uw (uword value) -> str { + ; ---- convert the uword in A/Y in decimal string form, without left padding 0s + internal_str_uw(value, string_out) + return string_out +} + +sub str_w (word value) -> str { + ; ---- convert the (signed) word into decimal string form, without left padding 0's + ^^ubyte out_ptr = &string_out + if value<0 { + @(out_ptr) = '-' + out_ptr++ + value = -value + } + internal_str_uw(value as uword, out_ptr) + return string_out +} + +sub str_l (long value) -> str { + ; ---- convert the (signed) long into decimal string form + ^^ubyte out_ptr = &string_out + if value < 0 { + @(out_ptr) = '-' + out_ptr++ + value = -value + } + internal_str_uw(value as uword, out_ptr) + return string_out +} + +private sub internal_str_uw(uword value, str out_ptr) { + uword value2 = value/10 + ubyte digits = value-value2*10 as ubyte + uword value3 = value2/10 + ubyte tens = value2-value3*10 as ubyte + uword value4 = value3/10 + ubyte hundreds = value3-value4*10 as ubyte + uword value5 = value4/10 + ubyte thousands = value4-value5*10 as ubyte + uword value6 = value5/10 + ubyte tenthousands = value5-value6*10 as ubyte + if tenthousands!=0 + goto output_tenthousands + if thousands!=0 + goto output_thousands + if hundreds!=0 + goto output_hundreds + if tens!=0 + goto output_tens + goto output_ones +output_tenthousands: + @(out_ptr) = tenthousands+'0' + out_ptr++ +output_thousands: + @(out_ptr) = thousands+'0' + out_ptr++ +output_hundreds: + @(out_ptr) = hundreds+'0' + out_ptr++ +output_tens: + @(out_ptr) = tens+'0' + out_ptr++ +output_ones: + @(out_ptr) = digits+'0' + out_ptr++ + @(out_ptr) = 0 +} + + +; ---- string conversion to numbers ----- + +sub str2ubyte(str string) -> ubyte { + ; -- returns in A the unsigned byte value of the string number argument in AY + ; the number may NOT be preceded by a + sign and may NOT contain spaces + ; (any non-digit character will terminate the number string that is parsed) + return str2uword(string) as ubyte +} + +sub str2byte(str string) -> byte { + ; -- returns in A the signed byte value of the string number argument in AY + ; the number may be preceded by a + or - sign but may NOT contain spaces + ; (any non-digit character will terminate the number string that is parsed) + return str2word(string) as byte +} + +sub str2uword(str string) -> uword { + uword result + ubyte ii + while string[ii] >= '0' and string[ii] <= '9' { + result = result * 10 + (string[ii] - '0') as uword + ii++ + } + return result +} + +sub str2word(str string) -> word { + bool negative + ubyte ii + if string[0] == '-' { + negative = true + ii = 1 + } else { + if string[0] == '+' + ii = 1 + } + uword result + while string[ii] >= '0' and string[ii] <= '9' { + result = result * 10 + (string[ii] - '0') as uword + ii++ + } + if negative + return 0 - result as word + return result as word +} + +sub hex2uword(str string) -> uword { + ; -- hexadecimal string (with or without '$') to uword. + ; stops parsing at the first character that's not a hex digit (except leading $) + uword result + ubyte char + if @(string)=='$' + string++ + repeat { + char = strings.lowerchar(@(string)) + if strings.isxdigit(char) { + result <<= 4 + if char>='0' and char<='9' + result |= char-'0' + else + result |= char-'a'+10 + } else + return result + string++ + } +} + +sub hex2long(str string) -> long { + ; -- hexadecimal string (with or without '$') to long. + ; stops parsing at the first character that's not a hex digit (except leading $) + long result + ubyte char + if @(string)=='$' + string++ + repeat { + char = strings.lowerchar(@(string)) + if strings.isxdigit(char) { + result <<= 4 + if char>='0' and char<='9' + result |= char-'0' + else + result |= char-'a'+10 + } else + return result + string++ + } +} + +sub str2long(str string) -> long { + ; -- convert a decimal string (terminated with a zero byte) into a long. Clobbers R0 + long result = 0 + bool negative = string[0] == '-' + if negative or string[0]=='+' + string++ + repeat { + ubyte digit_char = @(string) + if strings.isdigit(digit_char) { + result = (result<<1) + (result<<3) ; multiply by 10 + result += digit_char - '0' ; add digit + } else { + break ; Invalid character, stop processing + } + string++ + } + + if negative + return -result + else + return result +} + +sub bin2uword(str string) -> uword { + ; -- binary string (with or without '%') to uword. + ; stops parsing at the first character that's not a 0 or 1. (except leading %) + uword result + ubyte char + if @(string)=='%' + string++ + repeat { + char = @(string) + if char=='0' { + result <<= 1 + } else if char=='1' { + result <<= 1 + result |= 1 + } else + return result + string++ + } +} + +sub any2uword(str string) -> uword, ubyte { + ; -- convert any number string (any prefix allowed) to uword. + ; returns the parsed word value, and the number of processed characters (including the prefix symbol) + ubyte count + when string[0] { + '$' -> { + count = 1 + while strings.isxdigit(string[count]) + count++ + return hex2uword(string), count + } + '%' -> { + count = 1 + while string[count]=='0' or string[count]=='1' + count++ + return bin2uword(string), count + } + else -> { + count = 0 + while strings.isdigit(string[count]) + count++ + return str2uword(string), count + } + } +} + +} diff --git a/compiler/res/prog8lib/amiga500/dos.p8 b/compiler/res/prog8lib/amiga500/dos.p8 new file mode 100644 index 000000000..dc40834ef --- /dev/null +++ b/compiler/res/prog8lib/amiga500/dos.p8 @@ -0,0 +1,170 @@ +;; Auto-generated from dos_lib.sfd and dos_lib.i +;; Library base: _DOSBase in prog8: sys.DOSBase +;; Bank: 2 +;; Functions: 161 + +dos { + extsub @bank 2 -30 = Open(str name @D1, long accessMode @D2) -> pointer @D0 + extsub @bank 2 -36 = Close(pointer file @D1) -> long @D0 + extsub @bank 2 -42 = Read(pointer file @D1, pointer buffer @D2, long length @D3) -> long @D0 + extsub @bank 2 -48 = Write(pointer file @D1, pointer buffer @D2, long length @D3) -> long @D0 + extsub @bank 2 -54 = Input() -> pointer @D0 + extsub @bank 2 -60 = Output() -> pointer @D0 + extsub @bank 2 -66 = Seek(pointer file @D1, long position @D2, long offset @D3) -> long @D0 + extsub @bank 2 -72 = DeleteFile(str name @D1) -> long @D0 + extsub @bank 2 -78 = Rename(str oldName @D1, str newName @D2) -> long @D0 + extsub @bank 2 -84 = Lock(str name @D1, long k_type @D2) -> pointer @D0 + extsub @bank 2 -90 = UnLock(pointer lock @D1) + extsub @bank 2 -96 = DupLock(pointer lock @D1) -> pointer @D0 + extsub @bank 2 -102 = Examine(pointer lock @D1, pointer fileInfoBlock @D2) -> long @D0 + extsub @bank 2 -108 = ExNext(pointer lock @D1, pointer fileInfoBlock @D2) -> long @D0 + extsub @bank 2 -114 = Info(pointer lock @D1, pointer parameterBlock @D2) -> long @D0 + extsub @bank 2 -120 = CreateDir(str name @D1) -> pointer @D0 + extsub @bank 2 -126 = CurrentDir(pointer lock @D1) -> pointer @D0 + extsub @bank 2 -132 = IoErr() -> long @D0 + extsub @bank 2 -138 = CreateProc(str name @D1, long pri @D2, pointer segList @D3, long stackSize @D4) -> pointer @D0 + extsub @bank 2 -144 = Exit(long returnCode @D1) + extsub @bank 2 -150 = LoadSeg(str name @D1) -> pointer @D0 + extsub @bank 2 -156 = UnLoadSeg(pointer seglist @D1) + extsub @bank 2 -174 = DeviceProc(str name @D1) -> pointer @D0 + extsub @bank 2 -180 = SetComment(str name @D1, str comment @D2) -> long @D0 + extsub @bank 2 -186 = SetProtection(str name @D1, long protect @D2) -> long @D0 + extsub @bank 2 -192 = DateStamp(pointer date @D1) -> pointer @D0 + extsub @bank 2 -198 = Delay(long timeout @D1) + extsub @bank 2 -204 = WaitForChar(pointer file @D1, long timeout @D2) -> long @D0 + extsub @bank 2 -210 = ParentDir(pointer lock @D1) -> pointer @D0 + extsub @bank 2 -216 = IsInteractive(pointer file @D1) -> long @D0 + extsub @bank 2 -222 = Execute(str string @D1, pointer file @D2, pointer file2 @D3) -> long @D0 + extsub @bank 2 -228 = AllocDosObject(long k_type @D1, pointer tags @D2) -> pointer @D0 + extsub @bank 2 -234 = FreeDosObject(long k_type @D1, pointer ptr @D2) + extsub @bank 2 -240 = DoPkt(pointer port @D1, long action @D2, long arg1 @D3, long arg2 @D4, long arg3 @D5, long arg4 @D6, long arg5 @D7) -> long @D0 + extsub @bank 2 -246 = SendPkt(pointer dp @D1, pointer port @D2, pointer replyport @D3) + extsub @bank 2 -252 = WaitPkt() -> pointer @D0 + extsub @bank 2 -258 = ReplyPkt(pointer dp @D1, long res1 @D2, long res2 @D3) + extsub @bank 2 -264 = AbortPkt(pointer port @D1, pointer pkt @D2) + extsub @bank 2 -270 = LockRecord(pointer fh @D1, long offset @D2, long length @D3, long mode @D4, long timeout @D5) -> bool @D0 + extsub @bank 2 -276 = LockRecords(pointer recArray @D1, long timeout @D2) -> bool @D0 + extsub @bank 2 -282 = UnLockRecord(pointer fh @D1, long offset @D2, long length @D3) -> bool @D0 + extsub @bank 2 -288 = UnLockRecords(pointer recArray @D1) -> bool @D0 + extsub @bank 2 -294 = SelectInput(pointer fh @D1) -> pointer @D0 + extsub @bank 2 -300 = SelectOutput(pointer fh @D1) -> pointer @D0 + extsub @bank 2 -306 = FGetC(pointer fh @D1) -> long @D0 + extsub @bank 2 -312 = FPutC(pointer fh @D1, long ch @D2) -> long @D0 + extsub @bank 2 -318 = UnGetC(pointer fh @D1, long character @D2) -> long @D0 + extsub @bank 2 -324 = FRead(pointer fh @D1, pointer block @D2, long blocklen @D3, long number @D4) -> long @D0 + extsub @bank 2 -330 = FWrite(pointer fh @D1, pointer block @D2, long blocklen @D3, long number @D4) -> long @D0 + extsub @bank 2 -336 = FGets(pointer fh @D1, str buf @D2, long buflen @D3) -> str @D0 + extsub @bank 2 -342 = FPuts(pointer fh @D1, str k_str @D2) -> long @D0 + extsub @bank 2 -348 = VFWritef(pointer fh @D1, str format @D2, pointer argarray @D3) + extsub @bank 2 -354 = VFPrintf(pointer fh @D1, str format @D2, pointer argarray @D3) -> long @D0 + extsub @bank 2 -360 = Flush(pointer fh @D1) -> long @D0 + extsub @bank 2 -366 = SetVBuf(pointer fh @D1, str buff @D2, long k_type @D3, long size @D4) -> long @D0 + extsub @bank 2 -372 = DupLockFromFH(pointer fh @D1) -> pointer @D0 + extsub @bank 2 -378 = OpenFromLock(pointer lock @D1) -> pointer @D0 + extsub @bank 2 -384 = ParentOfFH(pointer fh @D1) -> pointer @D0 + extsub @bank 2 -390 = ExamineFH(pointer fh @D1, pointer fib @D2) -> bool @D0 + extsub @bank 2 -396 = SetFileDate(str name @D1, pointer date @D2) -> long @D0 + extsub @bank 2 -402 = NameFromLock(pointer lock @D1, str buffer @D2, long len @D3) -> long @D0 + extsub @bank 2 -408 = NameFromFH(pointer fh @D1, str buffer @D2, long len @D3) -> long @D0 + extsub @bank 2 -414 = SplitName(str name @D1, ubyte separator @D2, str buf @D3, word oldpos @D4, long size @D5) -> word @D0 + extsub @bank 2 -420 = SameLock(pointer lock1 @D1, pointer lock2 @D2) -> long @D0 + extsub @bank 2 -426 = SetMode(pointer fh @D1, long mode @D2) -> long @D0 + extsub @bank 2 -432 = ExAll(pointer lock @D1, pointer buffer @D2, long size @D3, long data @D4, pointer control @D5) -> long @D0 + extsub @bank 2 -438 = ReadLink(pointer port @D1, pointer lock @D2, str path @D3, str buffer @D4, long size @D5) -> long @D0 + extsub @bank 2 -444 = MakeLink(str name @D1, long dest @D2, long soft @D3) -> long @D0 + extsub @bank 2 -450 = ChangeMode(long k_type @D1, pointer fh @D2, long newmode @D3) -> long @D0 + extsub @bank 2 -456 = SetFileSize(pointer fh @D1, long pos @D2, long mode @D3) -> long @D0 + extsub @bank 2 -462 = SetIoErr(long result @D1) -> long @D0 + extsub @bank 2 -468 = Fault(long code @D1, str header @D2, str buffer @D3, long len @D4) -> bool @D0 + extsub @bank 2 -474 = PrintFault(long code @D1, str header @D2) -> bool @D0 + extsub @bank 2 -480 = ErrorReport(long code @D1, long k_type @D2, long arg1 @D3, pointer device @D4) -> long @D0 + extsub @bank 2 -492 = Cli() -> pointer @D0 + extsub @bank 2 -498 = CreateNewProc(pointer tags @D1) -> pointer @D0 + extsub @bank 2 -504 = RunCommand(pointer seg @D1, long stack @D2, str paramptr @D3, long paramlen @D4) -> long @D0 + extsub @bank 2 -510 = GetConsoleTask() -> pointer @D0 + extsub @bank 2 -516 = SetConsoleTask(pointer task @D1) -> pointer @D0 + extsub @bank 2 -522 = GetFileSysTask() -> pointer @D0 + extsub @bank 2 -528 = SetFileSysTask(pointer task @D1) -> pointer @D0 + extsub @bank 2 -534 = GetArgStr() -> str @D0 + extsub @bank 2 -540 = SetArgStr(str string @D1) -> str @D0 + extsub @bank 2 -546 = FindCliProc(long num @D1) -> pointer @D0 + extsub @bank 2 -552 = MaxCli() -> long @D0 + extsub @bank 2 -558 = SetCurrentDirName(str name @D1) -> bool @D0 + extsub @bank 2 -564 = GetCurrentDirName(str buf @D1, long len @D2) -> bool @D0 + extsub @bank 2 -570 = SetProgramName(str name @D1) -> bool @D0 + extsub @bank 2 -576 = GetProgramName(str buf @D1, long len @D2) -> bool @D0 + extsub @bank 2 -582 = SetPrompt(str name @D1) -> bool @D0 + extsub @bank 2 -588 = GetPrompt(str buf @D1, long len @D2) -> bool @D0 + extsub @bank 2 -594 = SetProgramDir(pointer lock @D1) -> pointer @D0 + extsub @bank 2 -600 = GetProgramDir() -> pointer @D0 + extsub @bank 2 -606 = SystemTagList(str command @D1, pointer tags @D2) -> long @D0 + extsub @bank 2 -612 = AssignLock(str name @D1, pointer lock @D2) -> long @D0 + extsub @bank 2 -618 = AssignLate(str name @D1, str path @D2) -> bool @D0 + extsub @bank 2 -624 = AssignPath(str name @D1, str path @D2) -> bool @D0 + extsub @bank 2 -630 = AssignAdd(str name @D1, pointer lock @D2) -> bool @D0 + extsub @bank 2 -636 = RemAssignList(str name @D1, pointer lock @D2) -> long @D0 + extsub @bank 2 -642 = GetDeviceProc(str name @D1, pointer dp @D2) -> pointer @D0 + extsub @bank 2 -648 = FreeDeviceProc(pointer dp @D1) + extsub @bank 2 -654 = LockDosList(long flags @D1) -> pointer @D0 + extsub @bank 2 -660 = UnLockDosList(long flags @D1) + extsub @bank 2 -666 = AttemptLockDosList(long flags @D1) -> pointer @D0 + extsub @bank 2 -672 = RemDosEntry(pointer dlist @D1) -> bool @D0 + extsub @bank 2 -678 = AddDosEntry(pointer dlist @D1) -> long @D0 + extsub @bank 2 -684 = FindDosEntry(pointer dlist @D1, str name @D2, long flags @D3) -> pointer @D0 + extsub @bank 2 -690 = NextDosEntry(pointer dlist @D1, long flags @D2) -> pointer @D0 + extsub @bank 2 -696 = MakeDosEntry(str name @D1, long k_type @D2) -> pointer @D0 + extsub @bank 2 -702 = FreeDosEntry(pointer dlist @D1) + extsub @bank 2 -708 = IsFileSystem(str name @D1) -> bool @D0 + extsub @bank 2 -714 = Format(str filesystem @D1, str volumename @D2, long dostype @D3) -> bool @D0 + extsub @bank 2 -720 = Relabel(str drive @D1, str newname @D2) -> long @D0 + extsub @bank 2 -726 = Inhibit(str name @D1, long onoff @D2) -> long @D0 + extsub @bank 2 -732 = AddBuffers(str name @D1, long number @D2) -> long @D0 + extsub @bank 2 -738 = CompareDates(pointer date1 @D1, pointer date2 @D2) -> long @D0 + extsub @bank 2 -744 = DateToStr(pointer datetime @D1) -> long @D0 + extsub @bank 2 -750 = StrToDate(pointer datetime @D1) -> long @D0 + extsub @bank 2 -756 = InternalLoadSeg(pointer fh @D0, pointer table @A0, pointer funcarray @A1, long stack @A2) -> pointer @D0 + extsub @bank 2 -762 = InternalUnLoadSeg(pointer seglist @D1, pointer freefunc @A1) -> bool @D0 + extsub @bank 2 -768 = NewLoadSeg(str file @D1, pointer tags @D2) -> pointer @D0 + extsub @bank 2 -774 = AddSegment(str name @D1, pointer seg @D2, long system @D3) -> long @D0 + extsub @bank 2 -780 = FindSegment(str name @D1, pointer seg @D2, long system @D3) -> pointer @D0 + extsub @bank 2 -786 = RemSegment(pointer seg @D1) -> long @D0 + extsub @bank 2 -792 = CheckSignal(long mask @D1) -> long @D0 + extsub @bank 2 -798 = ReadArgs(str arg_template @D1, long array @D2, pointer args @D3) -> pointer @D0 + extsub @bank 2 -804 = FindArg(str keyword @D1, str arg_template @D2) -> long @D0 + extsub @bank 2 -810 = ReadItem(str name @D1, long maxchars @D2, pointer cSource @D3) -> long @D0 + extsub @bank 2 -816 = StrToLong(str string @D1, long value @D2) -> long @D0 + extsub @bank 2 -822 = MatchFirst(str pat @D1, pointer anchor @D2) -> long @D0 + extsub @bank 2 -828 = MatchNext(pointer anchor @D1) -> long @D0 + extsub @bank 2 -834 = MatchEnd(pointer anchor @D1) + extsub @bank 2 -840 = ParsePattern(str pat @D1, ubyte patbuf @D2, long patbuflen @D3) -> long @D0 + extsub @bank 2 -846 = MatchPattern(pointer patbuf @D1, str k_str @D2) -> bool @D0 + extsub @bank 2 -858 = FreeArgs(pointer args @D1) + extsub @bank 2 -870 = FilePart(str path @D1) -> str @D0 + extsub @bank 2 -876 = PathPart(str path @D1) -> str @D0 + extsub @bank 2 -882 = AddPart(str dirname @D1, str filename @D2, long size @D3) -> bool @D0 + extsub @bank 2 -888 = StartNotify(pointer notify @D1) -> bool @D0 + extsub @bank 2 -894 = EndNotify(pointer notify @D1) + extsub @bank 2 -900 = SetVar(str name @D1, str buffer @D2, long size @D3, long flags @D4) -> bool @D0 + extsub @bank 2 -906 = GetVar(str name @D1, str buffer @D2, long size @D3, long flags @D4) -> long @D0 + extsub @bank 2 -912 = DeleteVar(str name @D1, long flags @D2) -> long @D0 + extsub @bank 2 -918 = FindVar(str name @D1, long k_type @D2) -> pointer @D0 + extsub @bank 2 -930 = CliInitNewcli(pointer dp @A0) -> long @D0 + extsub @bank 2 -936 = CliInitRun(pointer dp @A0) -> long @D0 + extsub @bank 2 -942 = WriteChars(str buf @D1, long buflen @D2) -> long @D0 + extsub @bank 2 -948 = PutStr(str k_str @D1) -> long @D0 + extsub @bank 2 -954 = VPrintf(str format @D1, pointer argarray @D2) -> long @D0 + extsub @bank 2 -966 = ParsePatternNoCase(str pat @D1, ubyte patbuf @D2, long patbuflen @D3) -> long @D0 + extsub @bank 2 -972 = MatchPatternNoCase(pointer patbuf @D1, str k_str @D2) -> bool @D0 + extsub @bank 2 -984 = SameDevice(pointer lock1 @D1, pointer lock2 @D2) -> bool @D0 + extsub @bank 2 -990 = ExAllEnd(pointer lock @D1, pointer buffer @D2, long size @D3, long data @D4, pointer control @D5) + extsub @bank 2 -996 = SetOwner(str name @D1, long owner_info @D2) -> bool @D0 + extsub @bank 2 -1014 = VolumeRequestHook(str vol @D1) -> long @D0 + extsub @bank 2 -1026 = GetCurrentDir() -> pointer @D0 + extsub @bank 2 -1128 = PutErrStr(str k_str @D1) -> long @D0 + extsub @bank 2 -1134 = ErrorOutput() -> long @D0 + extsub @bank 2 -1140 = SelectError(pointer fh @D1) -> long @D0 + extsub @bank 2 -1152 = DoShellMethodTagList(long method @D0, pointer tags @A0) -> pointer @D0 + extsub @bank 2 -1158 = ScanStackToken(pointer seg @D1, long defaultstack @D2) -> long @D0 +} + +;; End of auto-generated dos_lib.sfd diff --git a/compiler/res/prog8lib/amiga500/exec.p8 b/compiler/res/prog8lib/amiga500/exec.p8 new file mode 100644 index 000000000..46fbbd41f --- /dev/null +++ b/compiler/res/prog8lib/amiga500/exec.p8 @@ -0,0 +1,124 @@ +;; Auto-generated from exec_lib.sfd and exec_lib.i +;; Library base: _SysBase in prog8: sys.SysBase +;; Bank: 1 +;; Functions: 115 + +exec { + extsub @bank 1 -30 = Supervisor(pointer userFunction @A5) -> long @D0 + extsub @bank 1 -72 = InitCode(long startClass @D0, long version @D1) + extsub @bank 1 -78 = InitStruct(pointer initTable @A1, pointer k_memory @A2, long size @D0) + extsub @bank 1 -84 = MakeLibrary(pointer funcInit @A0, pointer structInit @A1, pointer libInit @A2, long dataSize @D0, long segList @D1) -> pointer @D0 + extsub @bank 1 -90 = MakeFunctions(pointer target @A0, pointer functionArray @A1, long funcDispBase @A2) + extsub @bank 1 -96 = FindResident(str name @A1) -> pointer @D0 + extsub @bank 1 -102 = InitResident(pointer resident @A1, long segList @D1) -> pointer @D0 + extsub @bank 1 -108 = Alert(long alertNum @D7) + extsub @bank 1 -114 = Debug(long flags @D0) + extsub @bank 1 -120 = Disable() + extsub @bank 1 -126 = Enable() + extsub @bank 1 -132 = Forbid() + extsub @bank 1 -138 = Permit() + extsub @bank 1 -144 = SetSR(long newSR @D0, long mask @D1) -> long @D0 + extsub @bank 1 -150 = SuperState() -> pointer @D0 + extsub @bank 1 -156 = UserState(pointer sysStack @D0) + extsub @bank 1 -162 = SetIntVector(long intNumber @D0, pointer interrupt @A1) -> pointer @D0 + extsub @bank 1 -168 = AddIntServer(long intNumber @D0, pointer interrupt @A1) + extsub @bank 1 -174 = RemIntServer(long intNumber @D0, pointer interrupt @A1) + extsub @bank 1 -180 = Cause(pointer interrupt @A1) + extsub @bank 1 -186 = Allocate(pointer freeList @A0, long byteSize @D0) -> pointer @D0 + extsub @bank 1 -192 = Deallocate(pointer freeList @A0, pointer memoryBlock @A1, long byteSize @D0) + extsub @bank 1 -198 = AllocMem(long byteSize @D0, long requirements @D1) -> pointer @D0 + extsub @bank 1 -204 = AllocAbs(long byteSize @D0, pointer location @A1) -> pointer @D0 + extsub @bank 1 -210 = FreeMem(pointer memoryBlock @A1, long byteSize @D0) + extsub @bank 1 -216 = AvailMem(long requirements @D1) -> long @D0 + extsub @bank 1 -222 = AllocEntry(pointer entry @A0) -> pointer @D0 + extsub @bank 1 -228 = FreeEntry(pointer entry @A0) + extsub @bank 1 -234 = Insert(pointer list @A0, pointer node @A1, pointer pred @A2) + extsub @bank 1 -240 = AddHead(pointer list @A0, pointer node @A1) + extsub @bank 1 -246 = AddTail(pointer list @A0, pointer node @A1) + extsub @bank 1 -252 = Remove(pointer node @A1) + extsub @bank 1 -258 = RemHead(pointer list @A0) -> pointer @D0 + extsub @bank 1 -264 = RemTail(pointer list @A0) -> pointer @D0 + extsub @bank 1 -270 = Enqueue(pointer list @A0, pointer node @A1) + extsub @bank 1 -276 = FindName(pointer list @A0, str name @A1) -> pointer @D0 + extsub @bank 1 -282 = AddTask(pointer task @A1, pointer initPC @A2, pointer finalPC @A3) -> pointer @D0 + extsub @bank 1 -288 = RemTask(pointer task @A1) + extsub @bank 1 -294 = FindTask(str name @A1) -> pointer @D0 + extsub @bank 1 -300 = SetTaskPri(pointer task @A1, long priority @D0) -> byte @D0 + extsub @bank 1 -306 = SetSignal(long newSignals @D0, long signalSet @D1) -> long @D0 + extsub @bank 1 -312 = SetExcept(long newSignals @D0, long signalSet @D1) -> long @D0 + extsub @bank 1 -318 = Wait(long signalSet @D0) -> long @D0 + extsub @bank 1 -324 = Signal(pointer task @A1, long signalSet @D0) + extsub @bank 1 -330 = AllocSignal(byte signalNum @D0) -> byte @D0 + extsub @bank 1 -336 = FreeSignal(byte signalNum @D0) + extsub @bank 1 -342 = AllocTrap(long trapNum @D0) -> long @D0 + extsub @bank 1 -348 = FreeTrap(long trapNum @D0) + extsub @bank 1 -354 = AddPort(pointer port @A1) + extsub @bank 1 -360 = RemPort(pointer port @A1) + extsub @bank 1 -366 = PutMsg(pointer port @A0, pointer message @A1) + extsub @bank 1 -372 = GetMsg(pointer port @A0) -> pointer @D0 + extsub @bank 1 -378 = ReplyMsg(pointer message @A1) + extsub @bank 1 -384 = WaitPort(pointer port @A0) -> pointer @D0 + extsub @bank 1 -390 = FindPort(str name @A1) -> pointer @D0 + extsub @bank 1 -396 = AddLibrary(pointer library @A1) + extsub @bank 1 -402 = RemLibrary(pointer library @A1) + extsub @bank 1 -408 = OldOpenLibrary(str libName @A1) -> pointer @D0 + extsub @bank 1 -414 = CloseLibrary(pointer library @A1) + extsub @bank 1 -420 = SetFunction(pointer library @A1, long funcOffset @A0, pointer newFunction @D0) -> pointer @D0 + extsub @bank 1 -426 = SumLibrary(pointer library @A1) + extsub @bank 1 -432 = AddDevice(pointer device @A1) + extsub @bank 1 -438 = RemDevice(pointer device @A1) + extsub @bank 1 -444 = OpenDevice(str devName @A0, long unit @D0, pointer ioRequest @A1, long flags @D1) -> byte @D0 + extsub @bank 1 -450 = CloseDevice(pointer ioRequest @A1) + extsub @bank 1 -456 = DoIO(pointer ioRequest @A1) -> byte @D0 + extsub @bank 1 -462 = SendIO(pointer ioRequest @A1) + extsub @bank 1 -468 = CheckIO(pointer ioRequest @A1) -> pointer @D0 + extsub @bank 1 -474 = WaitIO(pointer ioRequest @A1) -> byte @D0 + extsub @bank 1 -480 = AbortIO(pointer ioRequest @A1) + extsub @bank 1 -486 = AddResource(pointer resource @A1) + extsub @bank 1 -492 = RemResource(pointer resource @A1) + extsub @bank 1 -498 = OpenResource(str resName @A1) -> pointer @D0 + extsub @bank 1 -522 = RawDoFmt(str formatString @A0, pointer dataStream @A1, pointer putChProc @A2, pointer putChData @A3) -> pointer @D0 + extsub @bank 1 -528 = GetCC() -> long @D0 + extsub @bank 1 -534 = TypeOfMem(pointer address @A1) -> long @D0 + extsub @bank 1 -540 = Procure(pointer sigSem @A0, pointer bidMsg @A1) -> long @D0 + extsub @bank 1 -546 = Vacate(pointer sigSem @A0, pointer bidMsg @A1) + extsub @bank 1 -552 = OpenLibrary(str libName @A1, long version @D0) -> pointer @D0 + extsub @bank 1 -558 = InitSemaphore(pointer sigSem @A0) + extsub @bank 1 -564 = ObtainSemaphore(pointer sigSem @A0) + extsub @bank 1 -570 = ReleaseSemaphore(pointer sigSem @A0) + extsub @bank 1 -576 = AttemptSemaphore(pointer sigSem @A0) -> long @D0 + extsub @bank 1 -582 = ObtainSemaphoreList(pointer sigSem @A0) + extsub @bank 1 -588 = ReleaseSemaphoreList(pointer sigSem @A0) + extsub @bank 1 -594 = FindSemaphore(str name @A1) -> pointer @D0 + extsub @bank 1 -600 = AddSemaphore(pointer sigSem @A1) + extsub @bank 1 -606 = RemSemaphore(pointer sigSem @A1) + extsub @bank 1 -612 = SumKickData() -> long @D0 + extsub @bank 1 -618 = AddMemList(long size @D0, long attributes @D1, long pri @D2, pointer base @A0, str name @A1) + extsub @bank 1 -624 = CopyMem(pointer source @A0, pointer dest @A1, long size @D0) + extsub @bank 1 -630 = CopyMemQuick(pointer source @A0, pointer dest @A1, long size @D0) + extsub @bank 1 -636 = CacheClearU() + extsub @bank 1 -642 = CacheClearE(pointer address @A0, long length @D0, long caches @D1) + extsub @bank 1 -648 = CacheControl(long cacheBits @D0, long cacheMask @D1) -> long @D0 + extsub @bank 1 -654 = CreateIORequest(pointer port @A0, long size @D0) -> pointer @D0 + extsub @bank 1 -660 = DeleteIORequest(pointer iorequest @A0) + extsub @bank 1 -666 = CreateMsgPort() -> pointer @D0 + extsub @bank 1 -672 = DeleteMsgPort(pointer port @A0) + extsub @bank 1 -678 = ObtainSemaphoreShared(pointer sigSem @A0) + extsub @bank 1 -684 = AllocVec(long byteSize @D0, long requirements @D1) -> pointer @D0 + extsub @bank 1 -690 = FreeVec(pointer memoryBlock @A1) + extsub @bank 1 -696 = CreatePool(long requirements @D0, long puddleSize @D1, long threshSize @D2) -> pointer @D0 + extsub @bank 1 -702 = DeletePool(pointer poolHeader @A0) + extsub @bank 1 -708 = AllocPooled(pointer poolHeader @A0, long memSize @D0) -> pointer @D0 + extsub @bank 1 -714 = FreePooled(pointer poolHeader @A0, pointer k_memory @A1, long memSize @D0) + extsub @bank 1 -720 = AttemptSemaphoreShared(pointer sigSem @A0) -> long @D0 + extsub @bank 1 -726 = ColdReboot() + extsub @bank 1 -732 = StackSwap(pointer newStack @A0) + extsub @bank 1 -762 = CachePreDMA(pointer address @A0, long length @A1, long flags @D0) -> pointer @D0 + extsub @bank 1 -768 = CachePostDMA(pointer address @A0, long length @A1, long flags @D0) + extsub @bank 1 -774 = AddMemHandler(pointer memhand @A1) + extsub @bank 1 -780 = RemMemHandler(pointer memhand @A1) + extsub @bank 1 -786 = ObtainQuickVector(pointer interruptCode @A0) -> long @D0 + extsub @bank 1 -828 = NewMinList(pointer minlist @A0) +} + +;; End of auto-generated exec_lib.sfd diff --git a/compiler/res/prog8lib/amiga500/graphics.p8 b/compiler/res/prog8lib/amiga500/graphics.p8 new file mode 100644 index 000000000..77a0ce77d --- /dev/null +++ b/compiler/res/prog8lib/amiga500/graphics.p8 @@ -0,0 +1,172 @@ +;; Auto-generated from graphics_lib.sfd and graphics_lib.i +;; Library base: _GfxBase in prog8: sys.GfxBase +;; Bank: 3 +;; Functions: 163 + +graphics { + extsub @bank 3 -30 = BltBitMap(pointer srcBitMap @A0, word xSrc @D0, word ySrc @D1, pointer destBitMap @A1, word xDest @D2, word yDest @D3, word xSize @D4, word ySize @D5, ubyte minterm @D6, ubyte mask @D7, pointer tempA @A2) -> long @D0 + extsub @bank 3 -36 = BltTemplate(long source @A0, word xSrc @D0, word srcMod @D1, pointer destRP @A1, word xDest @D2, word yDest @D3, word xSize @D4, word ySize @D5) + extsub @bank 3 -42 = ClearEOL(pointer rp @A1) + extsub @bank 3 -48 = ClearScreen(pointer rp @A1) + extsub @bank 3 -54 = TextLength(pointer rp @A1, str string @A0, uword count @D0) -> word @D0 + extsub @bank 3 -60 = Text(pointer rp @A1, str string @A0, uword count @D0) -> long @D0 + extsub @bank 3 -66 = SetFont(pointer rp @A1, pointer textFont @A0) -> long @D0 + extsub @bank 3 -72 = OpenFont(pointer textAttr @A0) -> pointer @D0 + extsub @bank 3 -78 = CloseFont(pointer textFont @A1) + extsub @bank 3 -84 = AskSoftStyle(pointer rp @A1) -> long @D0 + extsub @bank 3 -90 = SetSoftStyle(pointer rp @A1, long style @D0, long enable @D1) -> long @D0 + extsub @bank 3 -96 = AddBob(pointer bob @A0, pointer rp @A1) + extsub @bank 3 -102 = AddVSprite(pointer vSprite @A0, pointer rp @A1) + extsub @bank 3 -108 = DoCollision(pointer rp @A1) + extsub @bank 3 -114 = DrawGList(pointer rp @A1, pointer vp @A0) + extsub @bank 3 -120 = InitGels(pointer head @A0, pointer tail @A1, pointer gelsInfo @A2) + extsub @bank 3 -126 = InitMasks(pointer vSprite @A0) + extsub @bank 3 -132 = RemIBob(pointer bob @A0, pointer rp @A1, pointer vp @A2) + extsub @bank 3 -138 = RemVSprite(pointer vSprite @A0) + extsub @bank 3 -144 = SetCollision(long num @D0, pointer routine @A0, pointer gelB) @A1) + extsub @bank 3 -150 = SortGList(pointer rp @A1) + extsub @bank 3 -156 = AddAnimOb(pointer anOb @A0, pointer anKey @A1, pointer rp @A2) + extsub @bank 3 -162 = Animate(pointer anKey @A0, pointer rp @A1) + extsub @bank 3 -168 = GetGBuffers(pointer anOb @A0, pointer rp @A1, bool flag @D0) -> bool @D0 + extsub @bank 3 -174 = InitGMasks(pointer anOb @A0) + extsub @bank 3 -180 = DrawEllipse(pointer rp @A1, word xCenter @D0, word yCenter @D1, word a @D2, word b @D3) + extsub @bank 3 -186 = AreaEllipse(pointer rp @A1, word xCenter @D0, word yCenter @D1, word a @D2, word b @D3) -> long @D0 + extsub @bank 3 -192 = LoadRGB4(pointer vp @A0, pointer colors @A1, word count @D0) + extsub @bank 3 -198 = InitRastPort(pointer rp @A1) + extsub @bank 3 -204 = InitVPort(pointer vp @A0) + extsub @bank 3 -210 = MrgCop(pointer view @A1) -> long @D0 + extsub @bank 3 -216 = MakeVPort(pointer view @A0, pointer vp @A1) -> long @D0 + extsub @bank 3 -222 = LoadView(pointer view @A1) + extsub @bank 3 -228 = WaitBlit() + extsub @bank 3 -234 = SetRast(pointer rp @A1, ubyte pen @D0) + extsub @bank 3 -240 = Move(pointer rp @A1, word x @D0, word y @D1) + extsub @bank 3 -246 = Draw(pointer rp @A1, word x @D0, word y @D1) + extsub @bank 3 -252 = AreaMove(pointer rp @A1, word x @D0, word y @D1) -> long @D0 + extsub @bank 3 -258 = AreaDraw(pointer rp @A1, word x @D0, word y @D1) -> long @D0 + extsub @bank 3 -264 = AreaEnd(pointer rp @A1) -> long @D0 + extsub @bank 3 -270 = WaitTOF() + extsub @bank 3 -276 = QBlit(pointer blit @A1) + extsub @bank 3 -282 = InitArea(pointer areaInfo @A0, pointer vectorBuffer @A1, word maxVectors @D0) + extsub @bank 3 -288 = SetRGB4(pointer vp @A0, word index @D0, ubyte red @D1, ubyte green @D2, ubyte blue @D3) + extsub @bank 3 -294 = QBSBlit(pointer blit @A1) + extsub @bank 3 -300 = BltClear(pointer memBlock @A1, long byteCount @D0, long flags @D1) + extsub @bank 3 -306 = RectFill(pointer rp @A1, word xMin @D0, word yMin @D1, word xMax @D2, word yMax @D3) + extsub @bank 3 -312 = BltPattern(pointer rp @A1, long mask @A0, word xMin @D0, word yMin @D1, word xMax @D2, word yMax @D3, uword maskBPR @D4) + extsub @bank 3 -318 = ReadPixel(pointer rp @A1, word x @D0, word y @D1) -> long @D0 + extsub @bank 3 -324 = WritePixel(pointer rp @A1, word x @D0, word y @D1) -> long @D0 + extsub @bank 3 -330 = Flood(pointer rp @A1, long mode @D2, word x @D0, word y @D1) -> bool @D0 + extsub @bank 3 -336 = PolyDraw(pointer rp @A1, word count @D0, pointer polyTable @A0) + extsub @bank 3 -342 = SetAPen(pointer rp @A1, ubyte pen @D0) + extsub @bank 3 -348 = SetBPen(pointer rp @A1, ubyte pen @D0) + extsub @bank 3 -354 = SetDrMd(pointer rp @A1, ubyte drawMode @D0) + extsub @bank 3 -360 = InitView(pointer view @A1) + extsub @bank 3 -366 = CBump(pointer copList @A1) + extsub @bank 3 -372 = CMove(pointer copList @A1, pointer destination @D0, word data @D1) -> long @D0 + extsub @bank 3 -378 = CWait(pointer copList @A1, word v @D0, word h @D1) -> long @D0 + extsub @bank 3 -384 = VBeamPos() -> long @D0 + extsub @bank 3 -390 = InitBitMap(pointer bitMap @A0, byte depth @D0, word width @D1, word height @D2) + extsub @bank 3 -396 = ScrollRaster(pointer rp @A1, word dx @D0, word dy @D1, word xMin @D2, word yMin @D3, word xMax @D4, word yMax @D5) + extsub @bank 3 -402 = WaitBOVP(pointer vp @A0) + extsub @bank 3 -408 = GetSprite(pointer sprite @A0, word num @D0) -> word @D0 + extsub @bank 3 -414 = FreeSprite(word num @D0) + extsub @bank 3 -420 = ChangeSprite(pointer vp @A0, pointer sprite @A1, uword newData @A2) + extsub @bank 3 -426 = MoveSprite(pointer vp @A0, pointer sprite @A1, word x @D0, word y @D1) + extsub @bank 3 -432 = LockLayerRom(pointer layer @A5) + extsub @bank 3 -438 = UnlockLayerRom(pointer layer @A5) + extsub @bank 3 -444 = SyncSBitMap(pointer layer @A0) + extsub @bank 3 -450 = CopySBitMap(pointer layer @A0) + extsub @bank 3 -456 = OwnBlitter() + extsub @bank 3 -462 = DisownBlitter() + extsub @bank 3 -468 = InitTmpRas(pointer tmpRas @A0, pointer buffer @A1, long size @D0) -> pointer @D0 + extsub @bank 3 -474 = AskFont(pointer rp @A1, pointer textAttr @A0) + extsub @bank 3 -480 = AddFont(pointer textFont @A1) + extsub @bank 3 -486 = RemFont(pointer textFont @A1) + extsub @bank 3 -492 = AllocRaster(uword width @D0, uword height @D1) -> pointer @D0 + extsub @bank 3 -498 = FreeRaster(pointer p @A0, uword width @D0, uword height @D1) + extsub @bank 3 -504 = AndRectRegion(pointer region @A0, pointer rectangle @A1) + extsub @bank 3 -510 = OrRectRegion(pointer region @A0, pointer rectangle @A1) -> bool @D0 + extsub @bank 3 -516 = NewRegion() -> pointer @D0 + extsub @bank 3 -522 = ClearRectRegion(pointer region @A0, pointer rectangle @A1) -> bool @D0 + extsub @bank 3 -528 = ClearRegion(pointer region @A0) + extsub @bank 3 -534 = DisposeRegion(pointer region @A0) + extsub @bank 3 -540 = FreeVPortCopLists(pointer vp @A0) + extsub @bank 3 -546 = FreeCopList(pointer copList @A0) + extsub @bank 3 -552 = ClipBlit(pointer srcRP @A0, word xSrc @D0, word ySrc @D1, pointer destRP @A1, word xDest @D2, word yDest @D3, word xSize @D4, word ySize @D5, ubyte minterm @D6) + extsub @bank 3 -558 = XorRectRegion(pointer region @A0, pointer rectangle @A1) -> bool @D0 + extsub @bank 3 -564 = FreeCprList(pointer cprList @A0) + extsub @bank 3 -570 = GetColorMap(long entries @D0) -> pointer @D0 + extsub @bank 3 -576 = FreeColorMap(pointer colorMap @A0) + extsub @bank 3 -582 = GetRGB4(pointer colorMap @A0, long entry @D0) -> long @D0 + extsub @bank 3 -588 = ScrollVPort(pointer vp @A0) + extsub @bank 3 -594 = UCopperListInit(pointer uCopList @A0, word n @D0) -> pointer @D0 + extsub @bank 3 -600 = FreeGBuffers(pointer anOb @A0, pointer rp @A1, bool flag @D0) + extsub @bank 3 -606 = BltBitMapRastPort(pointer srcBitMap @A0, word xSrc @D0, word ySrc @D1, pointer destRP @A1, word xDest @D2, word yDest @D3, word xSize @D4, word ySize @D5, ubyte minterm @D6) + extsub @bank 3 -612 = OrRegionRegion(pointer srcRegion @A0, pointer destRegion @A1) -> bool @D0 + extsub @bank 3 -618 = XorRegionRegion(pointer srcRegion @A0, pointer destRegion @A1) -> bool @D0 + extsub @bank 3 -624 = AndRegionRegion(pointer srcRegion @A0, pointer destRegion @A1) -> bool @D0 + extsub @bank 3 -630 = SetRGB4CM(pointer colorMap @A0, word index @D0, ubyte red @D1, ubyte green @D2, ubyte blue @D3) + extsub @bank 3 -636 = BltMaskBitMapRastPort(pointer srcBitMap @A0, word xSrc @D0, word ySrc @D1, pointer destRP @A1, word xDest @D2, word yDest @D3, word xSize @D4, word ySize @D5, ubyte minterm @D6, long bltMask @A2) + extsub @bank 3 -654 = AttemptLockLayerRom(pointer layer @A5) -> bool @D0 + extsub @bank 3 -660 = GfxNew(long gfxNodeType @D0) -> pointer @D0 + extsub @bank 3 -666 = GfxFree(pointer gfxNodePtr @A0) + extsub @bank 3 -672 = GfxAssociate(pointer associateNode @A0, pointer gfxNodePtr @A1) + extsub @bank 3 -678 = BitMapScale(pointer bitScaleArgs @A0) + extsub @bank 3 -684 = ScalerDiv(uword factor @D0, uword numerator @D1, uword denominator @D2) -> uword @D0 + extsub @bank 3 -690 = TextExtent(pointer rp @A1, str string @A0, word count @D0, pointer textExtent @A2) -> word @D0 + extsub @bank 3 -696 = TextFit(pointer rp @A1, str string @A0, uword strLen @D0, pointer textExtent @A2, pointer constrainingExtent @A3, word strDirection @D1, uword constrainingBitWidth @D2, uword constrainingBitHeight @D3) -> long @D0 + extsub @bank 3 -702 = GfxLookUp(pointer associateNode @A0) -> pointer @D0 + extsub @bank 3 -708 = VideoControl(pointer colorMap @A0, pointer tagarray @A1) -> bool @D0 + extsub @bank 3 -714 = OpenMonitor(str monitorName @A1, long displayID @D0) -> pointer @D0 + extsub @bank 3 -720 = CloseMonitor(pointer monitorSpec @A0) -> bool @D0 + extsub @bank 3 -726 = FindDisplayInfo(long displayID @D0) -> pointer @D0 + extsub @bank 3 -732 = NextDisplayInfo(long displayID @D0) -> long @D0 + extsub @bank 3 -756 = GetDisplayInfoData(pointer handle @A0, pointer buf @A1, long size @D0, long tagID @D1, long displayID @D2) -> long @D0 + extsub @bank 3 -762 = FontExtent(pointer font @A0, pointer fontExtent @A1) + extsub @bank 3 -768 = ReadPixelLine8(pointer rp @A0, uword xstart @D0, uword ystart @D1, uword width @D2, ubyte array @A2, pointer tempRP @A1) -> long @D0 + extsub @bank 3 -774 = WritePixelLine8(pointer rp @A0, uword xstart @D0, uword ystart @D1, uword width @D2, ubyte array @A2, pointer tempRP @A1) -> long @D0 + extsub @bank 3 -780 = ReadPixelArray8(pointer rp @A0, uword xstart @D0, uword ystart @D1, uword xstop @D2, uword ystop @D3, ubyte array @A2, pointer temprp @A1) -> long @D0 + extsub @bank 3 -786 = WritePixelArray8(pointer rp @A0, uword xstart @D0, uword ystart @D1, uword xstop @D2, uword ystop @D3, ubyte array @A2, pointer temprp @A1) -> long @D0 + extsub @bank 3 -792 = GetVPModeID(pointer vp @A0) -> long @D0 + extsub @bank 3 -798 = ModeNotAvailable(long modeID @D0) -> long @D0 + extsub @bank 3 -804 = WeighTAMatch(pointer reqTextAttr @A0, pointer targetTextAttr @A1, pointer targetTags @A2) -> word @D0 + extsub @bank 3 -810 = EraseRect(pointer rp @A1, word xMin @D0, word yMin @D1, word xMax @D2, word yMax @D3) + extsub @bank 3 -816 = ExtendFont(pointer font @A0, pointer fontTags @A1) -> long @D0 + extsub @bank 3 -822 = StripFont(pointer font @A0) + extsub @bank 3 -828 = CalcIVG(pointer v @A0, pointer vp @A1) -> uword @D0 + extsub @bank 3 -834 = AttachPalExtra(pointer cm @A0, pointer vp @A1) -> long @D0 + extsub @bank 3 -840 = ObtainBestPenA(pointer cm @A0, long r @D1, long g @D2, long b @D3, pointer tags @A1) -> long @D0 + extsub @bank 3 -852 = SetRGB32(pointer vp @A0, long n @D0, long r @D1, long g @D2, long b @D3) + extsub @bank 3 -858 = GetAPen(pointer rp @A0) -> long @D0 + extsub @bank 3 -864 = GetBPen(pointer rp @A0) -> long @D0 + extsub @bank 3 -870 = GetDrMd(pointer rp @A0) -> long @D0 + extsub @bank 3 -876 = GetOutlinePen(pointer rp @A0) -> long @D0 + extsub @bank 3 -882 = LoadRGB32(pointer vp @A0, pointer table @A1) + extsub @bank 3 -888 = SetChipRev(long want @D0) -> long @D0 + extsub @bank 3 -894 = SetABPenDrMd(pointer rp @A1, long apen @D0, long bpen @D1, long drawmode @D2) + extsub @bank 3 -900 = GetRGB32(pointer cm @A0, long firstcolor @D0, long ncolors @D1, long table @A1) + extsub @bank 3 -918 = AllocBitMap(long sizex @D0, long sizey @D1, long depth @D2, long flags @D3, pointer friend_bitmap @A0) -> pointer @D0 + extsub @bank 3 -924 = FreeBitMap(pointer bm @A0) + extsub @bank 3 -930 = GetExtSpriteA(pointer ss @A2, pointer tags @A1) -> long @D0 + extsub @bank 3 -936 = CoerceMode(pointer vp @A0, long monitorid @D0, long flags @D1) -> long @D0 + extsub @bank 3 -942 = ChangeVPBitMap(pointer vp @A0, pointer bm @A1, pointer db @A2) + extsub @bank 3 -948 = ReleasePen(pointer cm @A0, long n @D0) + extsub @bank 3 -954 = ObtainPen(pointer cm @A0, long n @D0, long r @D1, long g @D2, long b @D3, long f @D4) -> long @D0 + extsub @bank 3 -960 = GetBitMapAttr(pointer bm @A0, long attrnum @D1) -> long @D0 + extsub @bank 3 -966 = AllocDBufInfo(pointer vp @A0) -> pointer @D0 + extsub @bank 3 -972 = FreeDBufInfo(pointer dbi @A1) + extsub @bank 3 -978 = SetOutlinePen(pointer rp @A0, long pen @D0) -> long @D0 + extsub @bank 3 -984 = SetWriteMask(pointer rp @A0, long msk @D0) -> long @D0 + extsub @bank 3 -990 = SetMaxPen(pointer rp @A0, long maxpen @D0) + extsub @bank 3 -996 = SetRGB32CM(pointer cm @A0, long n @D0, long r @D1, long g @D2, long b @D3) + extsub @bank 3 -1002 = ScrollRasterBF(pointer rp @A1, word dx @D0, word dy @D1, word xMin @D2, word yMin @D3, word xMax @D4, word yMax @D5) + extsub @bank 3 -1008 = FindColor(pointer cm @A3, long r @D1, long g @D2, long b @D3, long maxcolor @D4) -> long @D0 + extsub @bank 3 -1020 = AllocSpriteDataA(pointer bm @A2, pointer tags @A1) -> pointer @D0 + extsub @bank 3 -1026 = ChangeExtSpriteA(pointer vp @A0, pointer oldsprite @A1, pointer newsprite @A2, pointer tags @A3) -> long @D0 + extsub @bank 3 -1032 = FreeSpriteData(pointer sp @A2) + extsub @bank 3 -1038 = SetRPAttrsA(pointer rp @A0, pointer tags @A1) + extsub @bank 3 -1044 = GetRPAttrsA(pointer rp @A0, pointer tags @A1) + extsub @bank 3 -1050 = BestModeIDA(pointer tags @A0) -> long @D0 + extsub @bank 3 -1056 = WriteChunkyPixels(pointer rp @A0, uword xstart @D0, uword ystart @D1, uword xstop @D2, uword ystop @D3, ubyte array @A2, long bytesperrow @D4) +} + +;; End of auto-generated graphics_lib.sfd diff --git a/compiler/res/prog8lib/amiga500/icon.p8 b/compiler/res/prog8lib/amiga500/icon.p8 new file mode 100644 index 000000000..71201e189 --- /dev/null +++ b/compiler/res/prog8lib/amiga500/icon.p8 @@ -0,0 +1,33 @@ +;; Auto-generated from icon_lib.sfd and icon_lib.i +;; Library base: _IconBase in prog8: sys.IconBase +;; Bank: 11 +;; Functions: 24 + +icon { + extsub @bank 11 -54 = FreeFreeList(pointer freelist @A0) + extsub @bank 11 -72 = AddFreeList(pointer freelist @A0, pointer mem @A1, long size @A2) -> bool @D0 + extsub @bank 11 -78 = GetDiskObject(str name @A0) -> pointer @D0 + extsub @bank 11 -84 = PutDiskObject(str name @A0, pointer diskobj @A1) -> bool @D0 + extsub @bank 11 -90 = FreeDiskObject(pointer diskobj @A0) + extsub @bank 11 -96 = FindToolType(str toolTypeArray @A0, str typeName @A1) -> ubyte @D0 + extsub @bank 11 -102 = MatchToolValue(str typeString @A0, str value @A1) -> bool @D0 + extsub @bank 11 -108 = BumpRevision(str newname @A0, str oldname @A1) -> str @D0 + extsub @bank 11 -114 = FreeAlloc(pointer free @A0, long len @A1, long k_type @A2) -> pointer @D0 + extsub @bank 11 -120 = GetDefDiskObject(long k_type @D0) -> pointer @D0 + extsub @bank 11 -126 = PutDefDiskObject(pointer diskObject @A0) -> bool @D0 + extsub @bank 11 -132 = GetDiskObjectNew(str name @A0) -> pointer @D0 + extsub @bank 11 -138 = DeleteDiskObject(str name @A0) -> bool @D0 + extsub @bank 11 -144 = FreeFree(pointer fl @A0, pointer address @A1) + extsub @bank 11 -150 = DupDiskObjectA(pointer diskObject @A0, pointer tags @A1) -> pointer @D0 + extsub @bank 11 -156 = IconControlA(pointer icon @A0, pointer tags @A1) -> long @D0 + extsub @bank 11 -162 = DrawIconStateA(pointer rp @A0, pointer icon @A1, str label @A2, long leftOffset @D0, long topOffset @D1, long state @D2, pointer tags @A3) + extsub @bank 11 -168 = GetIconRectangleA(pointer rp @A0, pointer icon @A1, str label @A2, pointer rect @A3, pointer tags @A4) -> bool @D0 + extsub @bank 11 -174 = NewDiskObject(long k_type @D0) -> pointer @D0 + extsub @bank 11 -180 = GetIconTagList(str name @A0, pointer tags @A1) -> pointer @D0 + extsub @bank 11 -186 = PutIconTagList(str name @A0, pointer icon @A1, pointer tags @A2) -> bool @D0 + extsub @bank 11 -192 = LayoutIconA(pointer icon @A0, pointer screen @A1, pointer tags @A2) -> bool @D0 + extsub @bank 11 -198 = ChangeToSelectedIconColor(pointer cr @A0) + extsub @bank 11 -204 = BumpRevisionLength(str newname @A0, str oldname @A1, long maxLength @D0) -> str @D0 +} + +;; End of auto-generated icon_lib.sfd diff --git a/compiler/res/prog8lib/amiga500/intuition.p8 b/compiler/res/prog8lib/amiga500/intuition.p8 new file mode 100644 index 000000000..e431505b1 --- /dev/null +++ b/compiler/res/prog8lib/amiga500/intuition.p8 @@ -0,0 +1,136 @@ +;; Auto-generated from intuition_lib.sfd and intuition_lib.i +;; Library base: _IntuitionBase in prog8: sys.IntuitionBase +;; Bank: 4 +;; Functions: 127 + +intuition { + extsub @bank 4 -30 = OpenIntuition() + extsub @bank 4 -36 = Intuition(pointer iEvent @A0) + extsub @bank 4 -42 = AddGadget(pointer window @A0, pointer gadget @A1, uword position @D0) -> uword @D0 + extsub @bank 4 -48 = ClearDMRequest(pointer window @A0) -> bool @D0 + extsub @bank 4 -54 = ClearMenuStrip(pointer window @A0) + extsub @bank 4 -60 = ClearPointer(pointer window @A0) + extsub @bank 4 -66 = CloseScreen(pointer screen @A0) -> bool @D0 + extsub @bank 4 -72 = CloseWindow(pointer window @A0) + extsub @bank 4 -78 = CloseWorkBench() -> long @D0 + extsub @bank 4 -84 = CurrentTime(long seconds @A0, long micros @A1) + extsub @bank 4 -90 = DisplayAlert(long alertNumber @D0, str string @A0, uword height @D1) -> bool @D0 + extsub @bank 4 -96 = DisplayBeep(pointer screen @A0) + extsub @bank 4 -102 = DoubleClick(long sSeconds @D0, long sMicros @D1, long cSeconds @D2, long cMicros @D3) -> bool @D0 + extsub @bank 4 -108 = DrawBorder(pointer rp @A0, pointer border @A1, word leftOffset @D0, word topOffset @D1) + extsub @bank 4 -114 = DrawImage(pointer rp @A0, pointer image @A1, word leftOffset @D0, word topOffset @D1) + extsub @bank 4 -120 = EndRequest(pointer requester @A0, pointer window @A1) + extsub @bank 4 -126 = GetDefPrefs(pointer preferences @A0, word size @D0) -> pointer @D0 + extsub @bank 4 -132 = GetPrefs(pointer preferences @A0, word size @D0) -> pointer @D0 + extsub @bank 4 -138 = InitRequester(pointer requester @A0) + extsub @bank 4 -144 = ItemAddress(pointer menuStrip @A0, uword menuNumber @D0) -> pointer @D0 + extsub @bank 4 -150 = ModifyIDCMP(pointer window @A0, long flags @D0) -> bool @D0 + extsub @bank 4 -156 = ModifyProp(pointer gadget @A0, pointer window @A1, pointer requester @A2, uword flags @D0, uword horizPot @D1, uword vertPot @D2, uword horizBody @D3, uword vertBody @D4) + extsub @bank 4 -162 = MoveScreen(pointer screen @A0, word dx @D0, word dy @D1) + extsub @bank 4 -168 = MoveWindow(pointer window @A0, word dx @D0, word dy @D1) + extsub @bank 4 -174 = OffGadget(pointer gadget @A0, pointer window @A1, pointer requester @A2) + extsub @bank 4 -180 = OffMenu(pointer window @A0, uword menuNumber @D0) + extsub @bank 4 -186 = OnGadget(pointer gadget @A0, pointer window @A1, pointer requester @A2) + extsub @bank 4 -192 = OnMenu(pointer window @A0, uword menuNumber @D0) + extsub @bank 4 -198 = OpenScreen(pointer newScreen @A0) -> pointer @D0 + extsub @bank 4 -204 = OpenWindow(pointer newWindow @A0) -> pointer @D0 + extsub @bank 4 -210 = OpenWorkBench() -> long @D0 + extsub @bank 4 -216 = PrintIText(pointer rp @A0, pointer iText @A1, word left @D0, word top @D1) + extsub @bank 4 -222 = RefreshGadgets(pointer gadgets @A0, pointer window @A1, pointer requester @A2) + extsub @bank 4 -228 = RemoveGadget(pointer window @A0, pointer gadget @A1) -> uword @D0 + extsub @bank 4 -234 = ReportMouse(bool flag @D0, pointer window @A0) + extsub @bank 4 -240 = Request(pointer requester @A0, pointer window @A1) -> bool @D0 + extsub @bank 4 -246 = ScreenToBack(pointer screen @A0) + extsub @bank 4 -252 = ScreenToFront(pointer screen @A0) + extsub @bank 4 -258 = SetDMRequest(pointer window @A0, pointer requester @A1) -> bool @D0 + extsub @bank 4 -264 = SetMenuStrip(pointer window @A0, pointer menu @A1) -> bool @D0 + extsub @bank 4 -270 = SetPointer(pointer window @A0, uword k_pointer @A1, word height @D0, word width @D1, word xOffset @D2, word yOffset @D3) + extsub @bank 4 -276 = SetWindowTitles(pointer window @A0, str windowTitle @A1, str screenTitle @A2) + extsub @bank 4 -282 = ShowTitle(pointer screen @A0, bool showIt @D0) + extsub @bank 4 -288 = SizeWindow(pointer window @A0, word dx @D0, word dy @D1) + extsub @bank 4 -294 = ViewAddress() -> pointer @D0 + extsub @bank 4 -300 = ViewPortAddress(pointer window @A0) -> pointer @D0 + extsub @bank 4 -306 = WindowToBack(pointer window @A0) + extsub @bank 4 -312 = WindowToFront(pointer window @A0) + extsub @bank 4 -318 = WindowLimits(pointer window @A0, long widthMin @D0, long heightMin @D1, long widthMax @D2, long heightMax @D3) -> bool @D0 + extsub @bank 4 -324 = SetPrefs(pointer preferences @A0, long size @D0, bool inform @D1) -> pointer @D0 + extsub @bank 4 -330 = IntuiTextLength(pointer iText @A0) -> long @D0 + extsub @bank 4 -336 = WBenchToBack() -> bool @D0 + extsub @bank 4 -342 = WBenchToFront() -> bool @D0 + extsub @bank 4 -348 = AutoRequest(pointer window @A0, pointer body @A1, pointer posText @A2, pointer negText @A3, long pFlag @D0, long nFlag @D1, uword width @D2, uword height @D3) -> bool @D0 + extsub @bank 4 -354 = BeginRefresh(pointer window @A0) + extsub @bank 4 -360 = BuildSysRequest(pointer window @A0, pointer body @A1, pointer posText @A2, pointer negText @A3, long flags @D0, uword width @D1, uword height @D2) -> pointer @D0 + extsub @bank 4 -366 = EndRefresh(pointer window @A0, long complete @D0) + extsub @bank 4 -372 = FreeSysRequest(pointer window @A0) + extsub @bank 4 -378 = MakeScreen(pointer screen @A0) -> long @D0 + extsub @bank 4 -384 = RemakeDisplay() -> long @D0 + extsub @bank 4 -390 = RethinkDisplay() -> long @D0 + extsub @bank 4 -396 = AllocRemember(pointer rememberKey @A0, long size @D0, long flags @D1) -> pointer @D0 + extsub @bank 4 -402 = AlohaWorkbench(long wbport @A0) + extsub @bank 4 -408 = FreeRemember(pointer rememberKey @A0, bool reallyForget @D0) + extsub @bank 4 -414 = LockIBase(long dontknow @D0) -> long @D0 + extsub @bank 4 -420 = UnlockIBase(long ibLock @A0) + extsub @bank 4 -426 = GetScreenData(pointer buffer @A0, uword size @D0, uword k_type @D1, pointer screen @A1) -> long @D0 + extsub @bank 4 -432 = RefreshGList(pointer gadgets @A0, pointer window @A1, pointer requester @A2, word numGad @D0) + extsub @bank 4 -438 = AddGList(pointer window @A0, pointer gadget @A1, uword position @D0, word numGad @D1, pointer requester @A2) -> uword @D0 + extsub @bank 4 -444 = RemoveGList(pointer remPtr @A0, pointer gadget @A1, word numGad @D0) -> uword @D0 + extsub @bank 4 -450 = ActivateWindow(pointer window @A0) + extsub @bank 4 -456 = RefreshWindowFrame(pointer window @A0) + extsub @bank 4 -462 = ActivateGadget(pointer gadgets @A0, pointer window @A1, pointer requester @A2) -> bool @D0 + extsub @bank 4 -468 = NewModifyProp(pointer gadget @A0, pointer window @A1, pointer requester @A2, uword flags @D0, uword horizPot @D1, uword vertPot @D2, uword horizBody @D3, uword vertBody @D4, word numGad @D5) + extsub @bank 4 -474 = QueryOverscan(long displayID @A0, pointer rect @A1, word oScanType @D0) -> long @D0 + extsub @bank 4 -480 = MoveWindowInFrontOf(pointer window @A0, pointer behindWindow @A1) + extsub @bank 4 -486 = ChangeWindowBox(pointer window @A0, word left @D0, word top @D1, word width @D2, word height @D3) + extsub @bank 4 -492 = SetEditHook(pointer hook @A0) -> pointer @D0 + extsub @bank 4 -498 = SetMouseQueue(pointer window @A0, uword queueLength @D0) -> long @D0 + extsub @bank 4 -504 = ZipWindow(pointer window @A0) + extsub @bank 4 -510 = LockPubScreen(str name @A0) -> pointer @D0 + extsub @bank 4 -516 = UnlockPubScreen(str name @A0, pointer screen @A1) + extsub @bank 4 -522 = LockPubScreenList() -> pointer @D0 + extsub @bank 4 -528 = UnlockPubScreenList() + extsub @bank 4 -534 = NextPubScreen(pointer screen @A0, str namebuf @A1) -> str @D0 + extsub @bank 4 -540 = SetDefaultPubScreen(str name @A0) + extsub @bank 4 -546 = SetPubScreenModes(uword modes @D0) -> uword @D0 + extsub @bank 4 -552 = PubScreenStatus(pointer screen @A0, uword statusFlags @D0) -> uword @D0 + extsub @bank 4 -558 = ObtainGIRPort(pointer gInfo @A0) -> pointer @D0 + extsub @bank 4 -564 = ReleaseGIRPort(pointer rp @A0) + extsub @bank 4 -570 = GadgetMouse(pointer gadget @A0, pointer gInfo @A1, word mousePoint @A2) + extsub @bank 4 -582 = GetDefaultPubScreen(str nameBuffer @A0) + extsub @bank 4 -588 = EasyRequestArgs(pointer window @A0, pointer easyStruct @A1, long idcmpPtr @A2, pointer args @A3) -> long @D0 + extsub @bank 4 -594 = BuildEasyRequestArgs(pointer window @A0, pointer easyStruct @A1, long idcmp @D0, pointer args @A3) -> pointer @D0 + extsub @bank 4 -600 = SysReqHandler(pointer window @A0, long idcmpPtr @A1, bool waitInput @D0) -> long @D0 + extsub @bank 4 -606 = OpenWindowTagList(pointer newWindow @A0, pointer tagList @A1) -> pointer @D0 + extsub @bank 4 -612 = OpenScreenTagList(pointer newScreen @A0, pointer tagList @A1) -> pointer @D0 + extsub @bank 4 -618 = DrawImageState(pointer rp @A0, pointer image @A1, word leftOffset @D0, word topOffset @D1, long state @D2, pointer drawInfo @A2) + extsub @bank 4 -624 = PointInImage(long point @D0, pointer image @A0) -> bool @D0 + extsub @bank 4 -630 = EraseImage(pointer rp @A0, pointer image @A1, word leftOffset @D0, word topOffset @D1) + extsub @bank 4 -636 = NewObjectA(pointer classPtr @A0, str classID @A1, pointer tagList @A2) -> pointer @D0 + extsub @bank 4 -642 = DisposeObject(pointer object @A0) + extsub @bank 4 -648 = SetAttrsA(pointer object @A0, pointer tagList @A1) -> long @D0 + extsub @bank 4 -654 = GetAttr(long attrID @D0, pointer object @A0, long storagePtr @A1) -> long @D0 + extsub @bank 4 -660 = SetGadgetAttrsA(pointer gadget @A0, pointer window @A1, pointer requester @A2, pointer tagList @A3) -> long @D0 + extsub @bank 4 -666 = NextObject(pointer objectPtrPtr @A0) -> pointer @D0 + extsub @bank 4 -678 = MakeClass(str classID @A0, str superClassID @A1, pointer superClassPtr @A2, uword instanceSize @D0, long flags @D1) -> pointer @D0 + extsub @bank 4 -684 = AddClass(pointer classPtr @A0) + extsub @bank 4 -690 = GetScreenDrawInfo(pointer screen @A0) -> pointer @D0 + extsub @bank 4 -696 = FreeScreenDrawInfo(pointer screen @A0, pointer drawInfo @A1) + extsub @bank 4 -702 = ResetMenuStrip(pointer window @A0, pointer menu @A1) -> bool @D0 + extsub @bank 4 -708 = RemoveClass(pointer classPtr @A0) + extsub @bank 4 -714 = FreeClass(pointer classPtr @A0) -> bool @D0 + extsub @bank 4 -768 = AllocScreenBuffer(pointer sc @A0, pointer bm @A1, long flags @D0) -> pointer @D0 + extsub @bank 4 -774 = FreeScreenBuffer(pointer sc @A0, pointer sb @A1) + extsub @bank 4 -780 = ChangeScreenBuffer(pointer sc @A0, pointer sb @A1) -> long @D0 + extsub @bank 4 -786 = ScreenDepth(pointer screen @A0, long flags @D0, pointer reserved @A1) + extsub @bank 4 -792 = ScreenPosition(pointer screen @A0, long flags @D0, long x1 @D1, long y1 @D2, long x2 @D3, long y2 @D4) + extsub @bank 4 -798 = ScrollWindowRaster(pointer win @A1, word dx @D0, word dy @D1, word xMin @D2, word yMin @D3, word xMax @D4, word yMax @D5) + extsub @bank 4 -804 = LendMenus(pointer fromwindow @A0, pointer towindow @A1) + extsub @bank 4 -810 = DoGadgetMethodA(pointer gad @A0, pointer win @A1, pointer req @A2, long message @A3) -> long @D0 + extsub @bank 4 -816 = SetWindowPointerA(pointer win @A0, pointer taglist @A1) + extsub @bank 4 -822 = TimedDisplayAlert(long alertNumber @D0, str string @A0, uword height @D1, long time @A1) -> bool @D0 + extsub @bank 4 -828 = HelpControl(pointer win @A0, long flags @D0) + extsub @bank 4 -834 = ShowWindow(pointer window @A0, pointer other @A1) -> bool @D0 + extsub @bank 4 -840 = HideWindow(pointer window @A0) -> bool @D0 + extsub @bank 4 -1212 = IntuitionControlA(pointer object @A0, pointer taglist @A1) -> long @D0 +} + +;; End of auto-generated intuition_lib.sfd diff --git a/compiler/res/prog8lib/amiga500/prog8_lib.p8 b/compiler/res/prog8lib/amiga500/prog8_lib.p8 index bfd25f1c7..3157c0f5b 100644 --- a/compiler/res/prog8lib/amiga500/prog8_lib.p8 +++ b/compiler/res/prog8lib/amiga500/prog8_lib.p8 @@ -1,10 +1,15 @@ %option no_symbol_prefixing, ignore_unused +%import exec + p8_sys_startup { %option force_output sub init_system() { - ; TODO + sys.DOSBase = exec.OpenLibrary("dos.library",0) + sys.GfxBase = exec.OpenLibrary("graphics.library",0) + sys.IntuitionBase = exec.OpenLibrary("intuition.library",0) + sys.IconBase = exec.OpenLibrary("icon.library",0) } sub init_system_phase2() { @@ -29,6 +34,9 @@ p8_sys_startup { } sub cleanup_at_exit() { - ; TODO + if sys.IconBase != 0 exec.CloseLibrary(sys.IconBase) + if sys.IntuitionBase != 0 exec.CloseLibrary(sys.IntuitionBase) + if sys.GfxBase != 0 exec.CloseLibrary(sys.GfxBase) + if sys.DOSBase != 0 exec.CloseLibrary(sys.DOSBase) } } diff --git a/compiler/res/prog8lib/amiga500/strings.p8 b/compiler/res/prog8lib/amiga500/strings.p8 index 29aba2b3a..c73317b7e 100644 --- a/compiler/res/prog8lib/amiga500/strings.p8 +++ b/compiler/res/prog8lib/amiga500/strings.p8 @@ -1 +1 @@ -; TODO +%import shared_m68k_strings diff --git a/compiler/res/prog8lib/amiga500/syslib.p8 b/compiler/res/prog8lib/amiga500/syslib.p8 index dc4910ffc..920172a7f 100644 --- a/compiler/res/prog8lib/amiga500/syslib.p8 +++ b/compiler/res/prog8lib/amiga500/syslib.p8 @@ -3,6 +3,8 @@ %option no_symbol_prefixing, ignore_unused %import shared_m68k_memory_routines +%import dos + sys { ; ------- lowlevel system routines -------- @@ -29,17 +31,24 @@ sys { ; MIN_FLOAT and MAX_FLOAT are defined in the floats module if imported - sub reset_system() { - ; TODO - } + ; SysBase/ExecBase is always simply available at 4.w + pointer @shared DOSBase + pointer @shared GfxBase + pointer @shared IntuitionBase + pointer @shared IconBase - sub poweroff_system() { - ; TODO + + sub reset_system() { + %asm {{ + lea 2.l,a0 + reset + jmp (a0) + }} } sub wait(uword jiffies) { ; --- wait approximately the given number of jiffies (1/60th seconds) - ; TODO implement the wait + dos.Delay(jiffies) } sub exit(ubyte returnvalue) { @@ -47,7 +56,7 @@ sys { %asm {{ moveq.l #0,d0 move.b sys.exit.returnvalue,d0 - illegal ; TODO implement the exit + illegal ; TODO implement the exit by restoring the stack pointer and performing a RTS }} } @@ -66,14 +75,6 @@ sys { } - sub clear_irqd() { - ; TODO - } - - sub set_irqd() { - ; TODO - } - inline asmsub progstart() -> long @A0 { %asm {{ lea prog8_program_start,a0 diff --git a/compiler/res/prog8lib/amiga500/textio.p8 b/compiler/res/prog8lib/amiga500/textio.p8 index 29aba2b3a..c53d51d9e 100644 --- a/compiler/res/prog8lib/amiga500/textio.p8 +++ b/compiler/res/prog8lib/amiga500/textio.p8 @@ -1 +1,181 @@ -; TODO +%import dos +%import conv +%import strings +%option ignore_unused + +txt { + asmsub chrout(ubyte char @D0) { + %asm {{ + move.b d0,-(sp) ; 1. Push character onto the stack. A7 now points to it! + move.l sys.DOSBase,a6 + jsr -60(a6) ; Output() + move.l d0, d1 + move.l sp, d2 ; D2 = Pointer to our character (Current Stack Pointer) + moveq #1, d3 ; D3 = We only want to write exactly 1 byte + jsr -48(a6) ; Write() + addq.l #2, sp + rts + }} + } + + sub nl() { + chrout('\n') + } + + sub spc() { + chrout(' ') + } + + asmsub print(str text @A0) { + %asm {{ + move.l a0,d2 + jsr strings.length + move.l d0,d3 + move.l sys.DOSBase,a6 + jsr -60(a6) ; Output() + move.l d0,d1 + jmp -48(a6) ; Write() + }} + } + + sub print_ub(ubyte value) { + print(conv.str_ub(value)) + } + + sub print_ub0(ubyte value) { + print(conv.str_ub0(value)) + } + + sub print_b(byte value) { + print(conv.str_b(value)) + } + + sub print_uw(uword value) { + print(conv.str_uw(value)) + } + + sub print_uw0(uword value) { + print(conv.str_uw0(value)) + } + + sub print_w(word value) { + print(conv.str_w(value)) + } + + sub print_l(long value) { + print(conv.str_l(value)) + } + + sub print_ulhex(long value, bool prefix) { + if prefix + chrout('$') + print(conv.str_ulhex(value)) + } + + sub print_uwhex(uword value, bool prefix) { + if prefix + chrout('$') + print(conv.str_uwhex(value)) + } + + sub print_ubhex(ubyte value, bool prefix) { + if prefix + chrout('$') + print(conv.str_ubhex(value)) + } + + sub print_ubbin(ubyte value, bool prefix) { + if prefix + chrout('%') + print(conv.str_ubbin(value)) + } + + sub print_uwbin(uword value, bool prefix) { + if prefix + chrout('%') + print(conv.str_uwbin(value)) + } + + sub print_bool(bool value) { + if value + print("true") + else + print("false") + } + + sub iso() { + ; is the default + } + + sub lowercase() { + ; is the default + } + + sub cls() { + clear_screen() + } + + sub clear_screen() { + print("\x1b[2J\x1B[H") + } + + sub home() { + print("\x1b[H") + } + + sub column(ubyte col) { + chrout(27) + chrout('[') + print_ub(col+1) + chrout(';') + chrout('G') + } + + sub rvs_on() { + print("\x1b[7m") + } + + sub rvs_off() { + print("\x1b[0m") + } + + sub color (ubyte txtcol) { + print("\x1b[3") + chrout('0' + txtcol) + chrout('m') + } + + sub bell() { + chrout(7) + } + + sub width() -> ubyte { + ; TODO use console Query WIndow Size escape sequence + return 80 + } + + sub height() -> ubyte { + ; TODO use console Query WIndow Size escape sequence + return 25 + } + + sub size() -> ubyte, ubyte { + ; TODO use console Query WIndow Size escape sequence + return width(), height() + } + + sub plot(ubyte col, ubyte row) { + ; use ANSI escape sequence to position the cursor + chrout(27) + chrout('[') + print_ub(row) + chrout(';') + print_ub(col) + chrout('H') + } + + sub setchr(ubyte col, ubyte row, ubyte char) { + plot(col, row) + chrout(char) + } +} diff --git a/compiler/res/prog8lib/qemu68k/strings.p8 b/compiler/res/prog8lib/qemu68k/strings.p8 index 6f8b8bd5d..c73317b7e 100644 --- a/compiler/res/prog8lib/qemu68k/strings.p8 +++ b/compiler/res/prog8lib/qemu68k/strings.p8 @@ -1,131 +1 @@ -%option ignore_unused - -strings { - sub isdigit(ubyte char) -> bool { - return char >= '0' and char <= '9' - } - - sub isxdigit(ubyte char) -> bool { - return (char >= '0' and char <= '9') or (char >= 'a' and char <= 'f') or (char >= 'A' and char <= 'F') - } - - sub lowerchar(ubyte char) -> ubyte { - if char >= 'A' and char <= 'Z' - return char + 32 - return char - } - - sub upperchar(ubyte char) -> ubyte { - if char >= 'a' and char <= 'z' - return char - 32 - return char - } - - alias lowerchar_iso = strings.lowerchar - alias upperchar_iso = strings.upperchar - - - asmsub length(str string @D0) -> ubyte @D0 { - ; Returns the number of bytes in the string up to the first 0-terminator. - %asm {{ - movea.l d0,a0 - moveq #0,d0 - bra.s .enter -.loop: - addq.w #1,d0 -.enter: - tst.b (a0)+ - bne .loop - rts - }} - } - - asmsub compare(str st1 @D0, str st2 @D1) -> byte @D0 { - ; Compares two strings for sorting, case-sensitively. - ; Returns -1 (255 as byte), 0 or 1. - %asm {{ - movea.l d0,a0 - movea.l d1,a1 -.loop: - move.b (a0)+,d0 - move.b (a1)+,d1 - cmp.b d1,d0 - bne .diff - tst.b d0 - bne .loop - moveq #0,d0 - rts -.diff: - blo .less - moveq #1,d0 - rts -.less: - moveq #-1,d0 - rts - }} - } - - asmsub hash(str string @D0) -> ubyte @D0 { - ; 8-bit hashing function. - ; hashcode = 179; for each byte: ROL(hashcode) XOR byte - %asm {{ - movea.l d0,a0 - move.b #179,d0 - moveq #0,d1 - move.w d1,ccr ; clear flags (X=0 for roxl) - bra .enter -.loop: - roxl.b #1,d0 - eor.b d1,d0 -.enter: - move.b (a0)+,d1 - bne .loop - rts - }} - } - - asmsub copy(str source @D0, str target @D1) -> ubyte @D0 { - ; Copy a string to another, overwriting that one. - ; Returns the length of the string that was copied. - %asm {{ - movea.l d0,a0 - movea.l d1,a1 - moveq #0,d0 -.loop: - move.b (a0)+,d2 - move.b d2,(a1)+ - beq .done - addq.l #1,d0 - bra.s .loop -.done: - rts - }} - } - - asmsub ncopy(str source @D0, str target @D1, ubyte maxlength @D2) -> ubyte @D0 { - ; Copy a string to another, overwriting that one, but limited to the given length. - ; Always null-terminates the result. - ; Returns the length of the string that was copied. - %asm {{ - movea.l d0,a0 - movea.l d1,a1 - moveq #0,d0 - tst.b d2 - beq .zero -.loop: - move.b (a0)+,d1 - move.b d1,(a1)+ - beq .done - addq.l #1,d0 - subq.b #1,d2 - bne .loop - ; maxlength bytes reached - null-terminate - clr.b (a1) - rts -.zero: - clr.b (a1) -.done: - rts - }} - } -} +%import shared_m68k_strings diff --git a/compiler/res/prog8lib/shared_m68k_memory_routines.p8 b/compiler/res/prog8lib/shared_m68k_memory_routines.p8 index 840521c55..eef05d7c1 100644 --- a/compiler/res/prog8lib/shared_m68k_memory_routines.p8 +++ b/compiler/res/prog8lib/shared_m68k_memory_routines.p8 @@ -1,5 +1,5 @@ sys { - %option merge + %option merge, ignore_unused ; ------- memory routines -------- diff --git a/compiler/res/prog8lib/shared_m68k_strings.p8 b/compiler/res/prog8lib/shared_m68k_strings.p8 new file mode 100644 index 000000000..97b1a9717 --- /dev/null +++ b/compiler/res/prog8lib/shared_m68k_strings.p8 @@ -0,0 +1,130 @@ +strings { + %option no_symbol_prefixing, ignore_unused + + sub isdigit(ubyte char) -> bool { + return char >= '0' and char <= '9' + } + + sub isxdigit(ubyte char) -> bool { + return (char >= '0' and char <= '9') or (char >= 'a' and char <= 'f') or (char >= 'A' and char <= 'F') + } + + sub lowerchar(ubyte char) -> ubyte { + if char >= 'A' and char <= 'Z' + return char + 32 + return char + } + + sub upperchar(ubyte char) -> ubyte { + if char >= 'a' and char <= 'z' + return char - 32 + return char + } + + alias lowerchar_iso = strings.lowerchar + alias upperchar_iso = strings.upperchar + + + asmsub length(str string @A0) -> ubyte @D0 { + ; Returns the number of bytes in the string up to the first 0-terminator. + %asm {{ + moveq #0,d0 + bra.s .enter +.loop: + addq.w #1,d0 +.enter: + tst.b (a0)+ + bne .loop + rts + }} + } + + asmsub compare(str st1 @D0, str st2 @D1) -> byte @D0 { + ; Compares two strings for sorting, case-sensitively. + ; Returns -1 (255 as byte), 0 or 1. + %asm {{ + movea.l d0,a0 + movea.l d1,a1 +.loop: + move.b (a0)+,d0 + move.b (a1)+,d1 + cmp.b d1,d0 + bne .diff + tst.b d0 + bne .loop + moveq #0,d0 + rts +.diff: + blo .less + moveq #1,d0 + rts +.less: + moveq #-1,d0 + rts + }} + } + + asmsub hash(str string @D0) -> ubyte @D0 { + ; 8-bit hashing function. + ; hashcode = 179; for each byte: ROL(hashcode) XOR byte + %asm {{ + movea.l d0,a0 + move.b #179,d0 + moveq #0,d1 + move.w d1,ccr ; clear flags (X=0 for roxl) + bra .enter +.loop: + roxl.b #1,d0 + eor.b d1,d0 +.enter: + move.b (a0)+,d1 + bne .loop + rts + }} + } + + asmsub copy(str source @D0, str target @D1) -> ubyte @D0 { + ; Copy a string to another, overwriting that one. + ; Returns the length of the string that was copied. + %asm {{ + movea.l d0,a0 + movea.l d1,a1 + moveq #0,d0 +.loop: + move.b (a0)+,d2 + move.b d2,(a1)+ + beq .done + addq.l #1,d0 + bra.s .loop +.done: + rts + }} + } + + asmsub ncopy(str source @D0, str target @D1, ubyte maxlength @D2) -> ubyte @D0 { + ; Copy a string to another, overwriting that one, but limited to the given length. + ; Always null-terminates the result. + ; Returns the length of the string that was copied. + %asm {{ + movea.l d0,a0 + movea.l d1,a1 + moveq #0,d0 + tst.b d2 + beq .zero +.loop: + move.b (a0)+,d1 + move.b d1,(a1)+ + beq .done + addq.l #1,d0 + subq.b #1,d2 + bne .loop + ; maxlength bytes reached - null-terminate + clr.b (a1) + rts +.zero: + clr.b (a1) +.done: + rts + }} + } +} diff --git a/compiler/src/prog8/compiler/astprocessing/DeferProcessor.kt b/compiler/src/prog8/compiler/astprocessing/DeferProcessor.kt index bf149e632..d9a0b9143 100644 --- a/compiler/src/prog8/compiler/astprocessing/DeferProcessor.kt +++ b/compiler/src/prog8/compiler/astprocessing/DeferProcessor.kt @@ -31,7 +31,7 @@ internal object DeferProcessor { val maskType = if (target.cpu == CpuType.M68000 || target.cpu == CpuType.M68020) DataType.UWORD else DataType.UBYTE val defers = setDeferMasks(program, maskType, errors) if(errors.noErrors()) - integrateDefers(defers, program, st, maskType, target, errors) + integrateDefers(defers, program, st, maskType, target) } /** @@ -101,7 +101,7 @@ internal object DeferProcessor { /** * Second pass: integrate defer calls at exit points and generate handler routines. */ - private fun integrateDefers(subdefers: Map>, program: PtProgram, st: SymbolTable, maskType: DataType, target: ICompilationTarget, errors: IErrorReporter) { + private fun integrateDefers(subdefers: Map>, program: PtProgram, st: SymbolTable, maskType: DataType, target: ICompilationTarget) { val jumpsAndCallsToAugment = mutableListOf() val returnsToAugment = mutableListOf() val subEndsToAugment = mutableListOf() diff --git a/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt b/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt index d444d42b7..d4e4cb888 100644 --- a/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/M68kAstChecker.kt @@ -87,16 +87,15 @@ internal class M68kAstChecker(private val errors: IErrorReporter) : IAstVisitor } override fun visit(subroutine: Subroutine) { - if (subroutine.isAsmSubroutine) { - if (subroutine.asmAddress != null) { - errors.err("extsub is not available on the m68k target", subroutine.position) - } - return - } - for (param in subroutine.parameters) { - if (param.registerOrPair != null) { - if (param.registerOrPair in m68kRegisters) { - errors.err("register annotations on normal subroutine parameters are not available on the m68k target (only used in asmsub)", param.position) + if (!subroutine.isAsmSubroutine) { + for (param in subroutine.parameters) { + if (param.registerOrPair != null) { + if (param.registerOrPair in m68kRegisters) { + errors.err( + "register annotations on normal subroutine parameters are not available on the m68k target (only used in asmsub)", + param.position + ) + } } } } diff --git a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt index 5daf5e779..8546b9798 100644 --- a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt @@ -702,7 +702,10 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro val asmAddr = if(srcSub.asmAddress==null) null else { val constAddr = srcSub.asmAddress!!.address.constValue(program) ?: throw FatalAstException("extsub address should be a constant") - PtAsmSub.Address(srcSub.asmAddress!!.constbank, varbank, constAddr.number.toUInt()) + if(constAddr.number<0) { + require(compilationOptions.compTarget.name.contains("amiga")) { "extsub address should be positive" } + } + PtAsmSub.Address(srcSub.asmAddress!!.constbank, varbank, constAddr.number.toInt().toUInt()) } val sub = PtAsmSub(srcSub.name, asmAddr, diff --git a/examples/m68k/amigahello.p8 b/examples/m68k/amigahello.p8 index d156cd4b1..6c2ea834f 100644 --- a/examples/m68k/amigahello.p8 +++ b/examples/m68k/amigahello.p8 @@ -3,7 +3,7 @@ exec { %option no_symbol_prefixing, ignore_unused - const pointer ExecBase = 4 + &pointer ExecBase = 4 asmsub OpenLibrary(str libname @A1, long version @D0) -> pointer @D0 { %asm {{ diff --git a/examples/test.p8 b/examples/test.p8 index b55d1ddb1..f9f74acf2 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,190 +1,38 @@ -%import floats %import textio +%import dos +%import exec main { sub start() { - txt.print("\nHello from Prog8 in QEMU m68k!\n") - txt.print("raw qemu bootinfo dump:\n") - qemu.bootinfo_dump() - txt.print("\n\nparsed QEMU bootinfo:\n") - bootinfo_print() - txt.print("\nGoodbye!\n") + txt.nl() + txt.nl() + txt.spc() + txt.spc() + txt.spc() + txt.chrout('1') + txt.chrout('2') + txt.chrout('3') + txt.chrout('4') + txt.nl() + txt.print("Boiiiingggg! Hello from prog8.\n\n") +; long @shared avail = exec.AvailMem(0) +; pointer mem = exec.AllocMem(256, 0) +; if mem != 0 { +; void dos.PutStr("allocated 256 bytes\n") +; exec.FreeMem(mem, 256) +; void dos.PutStr("freed\n") +; } else { +; void dos.PutStr("alloc failed!\n") +; } +; +; ; dos calls +; void dos.WriteChars("via WriteChars\n", 16) +; +; sys.wait(100) +; ;dos.Delay(50) +; +; long @shared ioerr = dos.IoErr() +; void dos.PutStr("done.\n") } - - sub bootinfo_print() { - long ptr = qemu.bootinfo_ptr() - repeat { - uword tag = peekw(ptr) - uword size = peekw(ptr + 2) - if tag == qemu.BI_LAST - { - txt.print(" BI_LAST\n") - break - } - uword data_count = size - 4 - long payload = ptr + 4 - - ; -- address and tag name -- - txt.print_ulhex(ptr, true) - txt.print(": ") - when tag { - qemu.BI_MACHTYPE -> txt.print("BI_MACHTYPE") - qemu.BI_CPUTYPE -> txt.print("BI_CPUTYPE") - qemu.BI_FPUTYPE -> txt.print("BI_FPUTYPE") - qemu.BI_MMUTYPE -> txt.print("BI_MMUTYPE") - qemu.BI_MEMCHUNK -> txt.print("BI_MEMCHUNK") - qemu.BI_RAMDISK -> txt.print("BI_RAMDISK") - qemu.BI_COMMAND_LINE -> txt.print("BI_COMMAND_LINE") - qemu.BI_RNG_SEED -> txt.print("BI_RNG_SEED") - qemu.BI_VIRT_QEMU_VERSION -> txt.print("BI_VIRT_QEMU_VERSION") - qemu.BI_VIRT_GF_PIC_BASE -> txt.print("BI_VIRT_GF_PIC_BASE") - qemu.BI_VIRT_GF_RTC_BASE -> txt.print("BI_VIRT_GF_RTC_BASE") - qemu.BI_VIRT_GF_TTY_BASE -> txt.print("BI_VIRT_GF_TTY_BASE") - qemu.BI_VIRT_VIRTIO_BASE -> txt.print("BI_VIRT_VIRTIO_BASE") - qemu.BI_VIRT_CTRL_BASE -> txt.print("BI_VIRT_CTRL_BASE") - else -> { - txt.print("??? (tag=") - txt.print_uwhex(tag, true) - txt.print(")") - } - } - txt.nl() - - ; -- decode payload -- - when tag { - qemu.BI_MACHTYPE -> { - long mach = peekl(payload) - txt.print(" ") - when mach { - qemu.MACH_AMIGA -> txt.print("Amiga") - qemu.MACH_ATARI -> txt.print("Atari") - qemu.MACH_MAC -> txt.print("Mac") - qemu.MACH_APOLLO -> txt.print("Apollo") - qemu.MACH_SUN3 -> txt.print("Sun3") - qemu.MACH_MVME147 -> txt.print("MVME147") - qemu.MACH_MVME16x -> txt.print("MVME16x") - qemu.MACH_BVME6000 -> txt.print("BVME6000") - qemu.MACH_HP300 -> txt.print("HP300") - qemu.MACH_Q40 -> txt.print("Q40") - qemu.MACH_SUN3x -> txt.print("Sun3x") - qemu.MACH_M54xx -> txt.print("M54xx") - qemu.MACH_M5441x -> txt.print("M5441x") - qemu.MACH_VIRT -> txt.print("VIRT") - else -> txt.print("MACH_???") - } - txt.print(" (") - txt.print_ulhex(mach, false) - txt.print(")") - } - qemu.BI_CPUTYPE -> { - long cpu = peekl(payload) - txt.print(" CPU") - if cpu==0 - txt.print("_68000") - else - { - if (cpu & qemu.CPU_FEATURE_68020) != 0 - txt.print("+68020") - if (cpu & qemu.CPU_FEATURE_68030) != 0 - txt.print("+68030") - if (cpu & qemu.CPU_FEATURE_68040) != 0 - txt.print("+68040") - if (cpu & qemu.CPU_FEATURE_68060) != 0 - txt.print("+68060") - if (cpu & qemu.CPU_FEATURE_COLDFIRE) != 0 - txt.print("+ColdFire") - } - txt.print(" (") - txt.print_ulhex(cpu, false) - txt.print(")") - } - qemu.BI_FPUTYPE, qemu.BI_MMUTYPE -> { - txt.print(" ") - txt.print_ulhex(peekl(payload), false) - } - qemu.BI_MEMCHUNK -> { - long mem_base = peekl(payload) - long mem_size = peekl(payload + 4) - txt.print(" mem at ") - txt.print_ulhex(mem_base, true) - txt.print(" - ") - txt.print_ulhex(mem_base + mem_size, true) - txt.print(" size=") - txt.print_ulhex(mem_size, true) - } - qemu.BI_RAMDISK -> { - long r_addr = peekl(payload) - long r_size = peekl(payload + 4) - txt.print(" addr=") - txt.print_ulhex(r_addr, true) - txt.print(" size=") - txt.print_ulhex(r_size, true) - } - qemu.BI_COMMAND_LINE -> { - txt.print(" \"") - uword cl_idx=0 - repeat data_count { - ubyte c = @(payload + cl_idx) - if c == 0 - break - txt.chrout(c) - cl_idx++ - } - txt.print("\"") - } - qemu.BI_RNG_SEED -> { - txt.print(" ") - txt.print_ub(data_count as ubyte) - txt.print(" bytes: ") - uword rng_idx=0 - repeat data_count { - ubyte rng_b = @(payload + rng_idx) - txt.print_ubhex(rng_b, false) - rng_idx++ - } - } - qemu.BI_VIRT_QEMU_VERSION -> { - long ver = peekl(payload) - ubyte major = (ver >> 24) as ubyte - ubyte minor = ((ver >> 16) & 255) as ubyte - txt.print(" QEMU ") - txt.print_ub(major) - txt.print(".") - txt.print_ub(minor) - txt.print(" (") - txt.print_ulhex(ver, false) - txt.print(")") - } - qemu.BI_VIRT_GF_PIC_BASE, qemu.BI_VIRT_GF_RTC_BASE, - qemu.BI_VIRT_GF_TTY_BASE, qemu.BI_VIRT_VIRTIO_BASE, - qemu.BI_VIRT_CTRL_BASE -> { - long base = peekl(payload) - long count = peekl(payload + 4) - txt.print(" base=") - txt.print_ulhex(base, true) - txt.print(" count=") - txt.print_ulhex(count, true) - } - else -> { - uword hex_idx=0 - uword hex_col=0 - repeat data_count { - if hex_col == 4 - { - txt.print(" ") - hex_col = 0 - } - ubyte hex_b = @(payload + hex_idx) - txt.print_ubhex(hex_b, false) - hex_idx++ - hex_col++ - } - } - } - txt.nl() - ptr = qemu.bootinfo_next(ptr) - } - } - } diff --git a/intermediate/src/prog8/intermediate/IRInstructions.kt b/intermediate/src/prog8/intermediate/IRInstructions.kt index 4cbf88e9c..c650e025a 100644 --- a/intermediate/src/prog8/intermediate/IRInstructions.kt +++ b/intermediate/src/prog8/intermediate/IRInstructions.kt @@ -9,7 +9,7 @@ import prog8.code.core.toHex */ @JvmInline value class MemoryAddress(val value: UInt) { - init { require(value <= 0xffffu) { "address out of range: $value" } } + init { require(value <= 0xffffffffu) { "address out of range: $value" } } override fun toString(): String = "$" + value.toString(16).padStart(2, '0') fun toHex(): String = "$" + value.toString(16) operator fun plus(other: UInt): MemoryAddress = MemoryAddress(value + other) diff --git a/scripts/compilenew6502-noopt.sh b/scripts/compilenew6502-noopt.sh deleted file mode 100755 index 6302cb9f3..000000000 --- a/scripts/compilenew6502-noopt.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# This is a simple script to quickly attempt to compile the small test program using the new 6502 codegen backend -# It stops on the first failure. - -set -e - -prog8c -target cx16 -newcodegen -noopt examples/test.p8 -codeGenNew6502/build/install/codeGenNew6502/bin/prog8-newgen test.p8ir -x16emu -run -prg test.prg -echo iso - diff --git a/scripts/compilenew6502.sh b/scripts/compilenew6502.sh deleted file mode 100755 index 51f18466b..000000000 --- a/scripts/compilenew6502.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh -# This is a simple script to quickly attempt to compile the small test program using the new 6502 codegen backend -# It stops on the first failure. - -set -e - -prog8c -target cx16 -newcodegen examples/test.p8 -codeGenNew6502/build/install/codeGenNew6502/bin/prog8-newgen test.p8ir -x16emu -run -prg test.prg -echo iso - diff --git a/scripts/sfd2prog8.py b/scripts/sfd2prog8.py new file mode 100755 index 000000000..23c0656b6 --- /dev/null +++ b/scripts/sfd2prog8.py @@ -0,0 +1,501 @@ +#!/usr/bin/env python3 +""" +Convert Amiga NDK LVO and SFD files to Prog8 extsub definitions. + +Usage: python sfd2prog8.py /path/to/AmigaNDK_headers libraryname > output.p8 + +Parses the LVO file (Include_I/lvo/_lib.i) for exact LVO offsets, +and the SFD file (SFD/_lib.sfd) for function parameter types and register assignments. + +Examples: + python sfd2prog8.py /path/to/AmigaNDK_headers exec > exec.p8 + python sfd2prog8.py /path/to/AmigaNDK_headers dos > dos.p8 +""" + +import sys +import re +import os +import argparse + + +# Map Amiga system types to Prog8 types +TYPE_MAP = { + 'VOID': None, + 'void': None, + 'LONG': 'long', + 'ULONG': 'long', + 'WORD': 'word', + 'UWORD': 'uword', + 'BYTE': 'byte', + 'UBYTE': 'ubyte', + 'BOOL': 'bool', + 'FLOAT': 'float', + 'DOUBLE': 'float', + 'APTR': 'pointer', + 'CONST_APTR': 'pointer', + 'CPTR': 'pointer', + 'BPTR': 'pointer', + 'STRPTR': 'str', + 'CONST_STRPTR': 'str', + 'TEXT': 'str', + 'CONST_TEXT': 'str', + 'BSTR': 'str', + 'PLANEPTR': 'pointer', + 'DisplayInfoHandle': 'pointer', +} + +# Amiga library to Prog8 bank number mapping +# These are arbitrary assignments, starting with the most common libraries. +LIBRARY_BANK_MAP = { + 'exec': 1, + 'dos': 2, + 'graphics': 3, + 'intuition': 4, + 'gadtools': 5, + 'layers': 6, + 'asl': 7, + 'console': 8, + 'utility': 9, + 'expansion': 10, + 'icon': 11, + 'wb': 12, + 'diskfont': 13, + 'iffparse': 14, + 'input': 15, + 'keymap': 16, + 'locale': 17, + 'timer': 18, + 'lowlevel': 19, + 'mathffp': 20, + 'mathieeesingbas': 21, + 'mathieeesingtrans': 22, + 'mathieeedoubbas': 23, + 'mathieeedoubtrans': 24, + 'mathtrans': 25, + 'nonvolatile': 26, + 'realtime': 27, + 'translator': 28, + 'rexxsyslib': 29, + 'commodities': 30, + 'datatypes': 31, + 'disk': 32, + 'amigaguide': 33, + 'arexx': 34, + 'battclock': 35, + 'battmem': 36, + 'bevel': 37, + 'bitmap': 38, + 'bullet': 39, + 'button': 40, + 'cardres': 41, + 'checkbox': 42, + 'chooser': 43, + 'cia': 44, + 'clicktab': 45, + 'colorwheel': 46, + 'datebrowser': 47, + 'drawlist': 48, + 'dtclass': 49, + 'fuelgauge': 50, + 'getcolor': 51, + 'getfile': 52, + 'getfont': 53, + 'getscreenmode': 54, + 'glyph': 55, + 'integer': 56, + 'label': 57, + 'layout': 58, + 'listbrowser': 59, + 'misc': 60, + 'palette': 61, + 'penmap': 62, + 'potgo': 63, + 'radiobutton': 64, + 'ramdrive': 65, + 'requester': 66, + 'scroller': 67, + 'sketchboard': 68, + 'slider': 69, + 'space': 70, + 'speedbar': 71, + 'string': 72, + 'texteditor': 73, + 'trackfile': 74, + 'virtual': 75, + 'window': 76, +} + +# Keywords reserved in Prog8 that can't be used as parameter names +PROG8_KEYWORDS = { + 'str', 'end', 'type', 'class', 'for', 'while', 'repeat', 'if', 'else', + 'do', 'in', 'to', 'not', 'and', 'or', 'xor', 'as', 'is', 'sub', + 'return', 'break', 'continue', 'void', 'true', 'false', 'pointer', + 'memory', 'inline', 'private', 'step', 'alias', 'const', 'enum', + 'struct', 'then', 'until', 'downto', 'when', 'goto', 'defer', 'swap', +} + + +def parse_c_type(c_type: str) -> tuple: + """Parse a C parameter type and return (prog8_type, base_type_name).""" + c_type = c_type.strip() + + # Strip common C qualifiers + c_type = re.sub(r'\b(const|volatile|register|unsigned|signed)\b', '', c_type).strip() + while ' ' in c_type: + c_type = c_type.replace(' ', ' ') + + # Handle pointer types + is_ptr = '*' in c_type + c_type = c_type.replace('*', '').strip() + + # Handle struct/union tags + c_type = re.sub(r'\b(struct|union)\s+', '', c_type).strip() + + # Look up in type map, default based on pointer type + if c_type in TYPE_MAP: + return (TYPE_MAP[c_type], c_type) + + # Unknown types are likely struct pointers or other pointer types + if is_ptr: + return ('pointer', c_type) + + # Unknown types default to long (32-bit is standard on Amiga) + return ('long', c_type) + + +def parse_lvo(filepath: str) -> dict: + """Parse an LVO .i file to get exact LVO offsets for public functions. + Returns dict: name -> lvo_offset""" + lvos = {} + with open(filepath) as f: + for line in f: + m = re.match(r'^_LVO(\w+)\s+equ\s+(-?\d+)', line) + if m: + name = m.group(1) + offset = int(m.group(2)) + lvos[name] = offset + return lvos + + +def join_sfd_lines(filepath: str) -> list: + """Join continuation lines in an SFD file. + Lines starting with whitespace are continuations of the previous line.""" + joined = [] + with open(filepath) as f: + prev = None + for line in f: + line = line.rstrip('\n') + if prev is not None and (line.startswith('\t') or line.startswith(' ')): + prev += ' ' + line.lstrip() + else: + if prev is not None: + joined.append(prev) + prev = line + if prev is not None: + joined.append(prev) + return joined + + +def extract_last_paren_group(text: str): + """Find the last outermost balanced parenthesized group in text. + Returns (open_pos, close_pos, content) or None.""" + close_pos = -1 + for i in range(len(text) - 1, -1, -1): + if text[i] == ')': + close_pos = i + break + if close_pos < 0: + return None + + depth = 0 + open_pos = -1 + for i in range(close_pos, -1, -1): + if text[i] == ')': + depth += 1 + elif text[i] == '(': + depth -= 1 + if depth == 0: + open_pos = i + break + + if open_pos < 0: + return None + + return (open_pos, close_pos, text[open_pos + 1:close_pos].strip()) + + +def parse_sfd_param(param_str: str) -> tuple: + """Parse a single SFD parameter string into (prog8_type, name).""" + param_str = param_str.strip() + if not param_str: + return ('long', 'arg') + + # Handle function pointer params: TYPE (*name)(...) + fp_match = re.search(r'\(\*(\w+)\)', param_str) + if fp_match: + name = fp_match.group(1) + return ('pointer', name) + + # Normal param: split on last whitespace + parts = param_str.rsplit(None, 1) + if len(parts) == 2: + ptype_raw, pname = parts + else: + ptype_raw = parts[0] + pname = 'arg' + + # Handle leading * in name (pointer param) + while pname.startswith('*'): + ptype_raw += ' *' + pname = pname[1:] + + if not pname: + return ('long', 'arg') + + prog8_type = parse_c_type(ptype_raw)[0] + if prog8_type is None: + prog8_type = 'long' + if pname in PROG8_KEYWORDS: + pname = f'k_{pname}' + + return (prog8_type, pname) + + +def parse_sfd(filepath: str) -> dict: + """Parse an SFD file for function type information. + Returns dict: name -> {ret_type, params: [(type, name)], regs: [str]}""" + lines = join_sfd_lines(filepath) + funcs = {} + in_alias = False + libname = "" + + for line in lines: + stripped = line.strip() + + if not stripped or stripped.startswith('*'): + in_alias = False + continue + + if stripped.startswith('==') or stripped.startswith('##'): + directive = stripped.split()[0] if stripped.split() else '' + if directive in ('==alias', '##alias'): + in_alias = True + continue + in_alias = False + + m = re.match(r'==base\s+(\S+)', stripped) + if m: + libname = m.group(1) + continue + + if in_alias: + in_alias = False # Only skip the single alias function after ==alias + continue + + # Try to parse as function definition + info = parse_sfd_func_line(line) + if info: + funcs[info['name']] = info + + # Store libname so caller can access it + funcs['__libname'] = libname + return funcs + + +def parse_sfd_func_line(line: str): + """Parse a single (joined) SFD function definition line. + Returns dict with name, ret_type, params, regs, or None.""" + line = line.strip() + if not line: + return None + + # Find the register group (last outermost parenthesized group) + reg_group = extract_last_paren_group(line) + if reg_group is None: + return None + + reg_str = reg_group[2] + if not reg_str: + regs = [] + else: + regs = [r.strip() for r in reg_str.replace('/', ',').split(',') if r.strip()] + + # Signature is everything before the register group + sig = line[:reg_group[0]].strip() + if not sig: + return None + + # Now parse the signature: return_type name(params) + first_paren = sig.find('(') + if first_paren < 0: + return None + + # Find matching closing paren for params + depth = 0 + params_close = -1 + for i in range(first_paren, len(sig)): + if sig[i] == '(': + depth += 1 + elif sig[i] == ')': + depth -= 1 + if depth == 0: + params_close = i + break + + if params_close < 0: + return None + + params_str = sig[first_paren + 1:params_close].strip() + before = sig[:first_paren].strip() + + # Extract function name and return type + words = before.split() + if not words: + return None + + name_raw = words[-1] + name = name_raw.lstrip('*') + stars = len(name_raw) - len(name) + + ret_type_parts = words[:-1] + if stars > 0: + ret_type_parts.append('*' * stars) + ret_type = ' '.join(ret_type_parts).strip() if ret_type_parts else None + if not ret_type: + ret_type = None + # Determine if void + is_void = ret_type and ret_type.strip() in ('VOID', 'void') + + # Parse parameters + params = [] + if params_str: + for p in params_str.split(','): + p = p.strip() + if not p: + continue + params.append(parse_sfd_param(p)) + + return { + 'name': name, + 'ret_type': ret_type, + 'params': params, + 'regs': regs, + 'is_void': is_void, + } + + +def main(): + parser = argparse.ArgumentParser( + description="Convert Amiga NDK LVO and SFD files to Prog8 extsub definitions.") + parser.add_argument('ndk_path', nargs='?', help="Path to AmigaNDK_headers directory") + parser.add_argument('library_name', nargs='?', help="Library name (e.g. exec, dos, graphics)") + parser.add_argument('-m', '--mapping', action='store_true', + help="Print library bank mapping table to stderr") + args = parser.parse_args() + + if args.mapping and not args.library_name: + print_mapping(None) + return + + if not args.ndk_path or not args.library_name: + parser.print_help() + sys.exit(1) + + show_mapping = args.mapping + ndk_path = args.ndk_path.rstrip('/') + lib_name = args.library_name + + lvo_path = os.path.join(ndk_path, 'Include_I', 'lvo', f'{lib_name}_lib.i') + sfd_path = os.path.join(ndk_path, 'SFD', f'{lib_name}_lib.sfd') + + if not os.path.exists(lvo_path): + print(f"Error: LVO file not found: {lvo_path}") + sys.exit(1) + if not os.path.exists(sfd_path): + print(f"Error: SFD file not found: {sfd_path}") + sys.exit(1) + + lvos = parse_lvo(lvo_path) + sfd_funcs = parse_sfd(sfd_path) + + libname = sfd_funcs.pop('__libname', '') + basename = lib_name + + if lib_name in LIBRARY_BANK_MAP: + bank = LIBRARY_BANK_MAP[lib_name] + else: + print(f"Warning: unknown library '{lib_name}', no bank assigned. Add it to LIBRARY_BANK_MAP.", file=sys.stderr) + bank = None + + bank_tag = f"@bank {bank} " if bank is not None else "" + + print(f";; Auto-generated from {lib_name}_lib.sfd and {lib_name}_lib.i") + if libname: + prog8libname = f"sys.{libname[1:]}" + print(f";; Library base: {libname} in prog8: {prog8libname}") + if bank is not None: + print(f";; Bank: {bank}") + print(f";; Functions: {len(lvos)}") + print() + + print(f"{basename} {{") + + for name, lvo in sorted(lvos.items(), key=lambda x: x[1], reverse=True): + # LVO offsets are negative, reverse sort gives most negative first + info = sfd_funcs.get(name) + + if info: + params = info['params'] + regs = info['regs'] + ret_type = info['ret_type'] + is_void = info['is_void'] + else: + params = [] + regs = [] + ret_type = None + is_void = True + + # Build parameter list with register annotations + prog8_params = [] + param_idx = 0 + for reg in regs: + if param_idx < len(params): + ptype, pname = params[param_idx] + param_idx += 1 + else: + ptype = 'long' + pname = f'reg_{reg.lower()}' + prog8_params.append(f"{ptype} {pname} @{reg.upper()}") + + param_str = ", ".join(prog8_params) + + # Map return type to Prog8 type + if not is_void: + prog8_ret, _ = parse_c_type(ret_type) + if prog8_ret is None: + prog8_ret = 'long' + ret_suffix = f" -> {prog8_ret} @D0" + else: + ret_suffix = "" + print(f" extsub {bank_tag} {lvo} = {name}({param_str}){ret_suffix}") + + print(f"}}") + print() + print(f";; End of auto-generated {lib_name}_lib.sfd") + + if show_mapping: + print_mapping(lib_name) + + +def print_mapping(current_lib): + """Print the library bank mapping table to stderr.""" + print(file=sys.stderr) + print("Amiga library bank mapping:", file=sys.stderr) + print("==========================", file=sys.stderr) + for lib, bn in sorted(LIBRARY_BANK_MAP.items(), key=lambda x: x[1]): + marker = " <--" if lib == current_lib else "" + print(f" bank {bn:3d} = {lib}{marker}", file=sys.stderr) + + +if __name__ == '__main__': + main()