Allow importing modules from subdirectories. Move platform definitions

This commit is contained in:
Karol Stasiak 2020-04-27 12:40:49 +02:00
parent c8492173ee
commit 78fe0e37bb
60 changed files with 115 additions and 23 deletions

View File

@ -3,6 +3,7 @@
## Adding a custom platform
Every platform is defined in an `.ini` file with an appropriate name.
The file is looked up in the directories on the include path, first directly, then in the `platform` subdirectory.
As an extension, multiline entries are supported:
if a line ends with a backslash character, the value continues to the next line.

View File

@ -218,7 +218,11 @@ is equivalent to:
import <module>
Adds a module to the program.
Adds a module to the program. The module name can be a valid identifier
or a sequence of identifiers separated by forward slashes:
import module1
import library1/module2
The module is looked up first in the current working directory, and then in the include directories.

View File

@ -6,7 +6,7 @@
#pragma zilog_syntax
import i80_math
import i80/i80_math
macro asm void poke(word const addr, byte register(a) value) {
! LD (addr), A

View File

@ -0,0 +1,27 @@
import random
#if not(ARCH_6809)
#warn random_6809 module should be only used on 6809-compatible targets
#endif
asm byte rand() {
? lda #8
? ldb rand_seed+0
__rand_loop:
aslb
? rolb rand_seed+1
bcc __no_eor
eorb #$2D
__no_eor:
deca
bne __rand_loop
? sta rand_seed+0
? rts
}
inline void init_rand_seed() {
// TODO: find a better source of randomness
rand_seed = 1
}

View File

@ -0,0 +1,51 @@
// target-independent things
#if not(ARCH_6809)
#warn stdlib_6809 module should be only used on 6809-compatible targets
#endif
word nmi_routine_addr @$FFFC
word reset_routine_addr @$FFFE
word irq_routine_addr @$FFF8
word swi_routine_addr @$FFFA
word firq_routine_addr @$FFF6
word swi2_routine_addr @$FFF4
word swi3_routine_addr @$FFF2
macro asm void poke(word const addr, byte register(b) value) {
! STB addr
}
macro asm byte peek(word const addr) {
! LDB addr
}
macro asm void disable_irq() {
ORCC #$30
}
macro asm void enable_irq() {
ANDCC #$CF
}
asm byte hi_nibble_to_hex(byte register(a) value) {
LSRB
LSRB
LSRB
LSRB
? JMP lo_nibble_to_hex
}
asm byte lo_nibble_to_hex(byte register(a) value) {
! ANDB #$F
ADDB #$30
CMPB #$3A
BCC _lo_nibble_to_hex_lbl
ADDB #$7 // carry is set
_lo_nibble_to_hex_lbl:
? RTS
}
macro asm void panic() {
? JSR _panic
}

View File

@ -2,12 +2,14 @@
word rand_seed
#if ARCH_6502
import random_6502
import m6502/random_6502
#elseif ARCH_I80
import random_i80
import i80/random_i80
#elseif ARCH_X86
#warn 8086 is a partially supported architecture
import random_i80
import m6502/random_i80
#elseif ARCH_6809
import m6809/random_6809
#else
#warn Unsupported architecture
#endif

View File

@ -12,9 +12,9 @@ alias scrstrzappend = strzappend
#else
#if ARCH_I80
import scrstring_fastpointers
import internal/scrstring_fastpointers
#else
import scrstring_fastindices
import internal/scrstring_fastindices
#endif
void scrstrzappend(pointer buffer, pointer str) {

View File

@ -1,12 +1,14 @@
// target-independent things
#if ARCH_6502
import stdlib_6502
import m6502/stdlib_6502
#elseif ARCH_I80
import stdlib_i80
import i80/stdlib_i80
#elseif ARCH_X86
#warn 8086 is a partially supported architecture
import stdlib_i80
import i80/stdlib_i80
#elseif ARCH_6809
import m6809/stdlib_6809
#endif
#if PAL && NTSC

View File

@ -1,9 +1,9 @@
import err
#if ARCH_I80
import string_fastpointers
import internal/string_fastpointers
#else
import string_fastindices
import internal/string_fastindices
#endif
void strzappend(pointer buffer, pointer str) {

View File

@ -211,7 +211,7 @@ object Main {
"zxspectrum", "zxspectrum_8080", "pc88", "cpc464", "msx_crt",
"cpm", "cpm_z80", "dos_com")
case Right(path) =>
Seq(new File(".").list(), new File(path).list())
Seq(new File(".").list(), new File(".", "platform").list(), new File(path).list(), new File(path, "platform").list())
.filter(_ ne null)
.flatMap(_.toSeq)
.filter(_.endsWith(".ini"))

View File

@ -71,8 +71,13 @@ object Platform {
if (file.exists()) {
return load(file)
}
val file2 = Paths.get(dir, "platform", platformName + ".ini").toFile
log.debug("Checking " + file2)
if (file2.exists()) {
return load(file2)
}
}
log.fatal(s"Platfom definition `$platformName` not found", None)
log.fatal(s"Platform definition `$platformName` not found", None)
}
def load(file: File)(implicit log: Logger): Platform = {

View File

@ -83,7 +83,7 @@ abstract class MfParser[T](fileId: String, input: String, currentDirectory: Stri
val continueStatement: P[Seq[ExecutableStatement]] = ("continue" ~ !letterOrDigit ~/ HWS ~ identifier.?).map(l => Seq(ContinueStatement(l.getOrElse(""))))
val importStatement: P[Seq[ImportStatement]] = ("import" ~ !letterOrDigit ~/ SWS ~/ identifier).map(x => Seq(ImportStatement(x)))
val importStatement: P[Seq[ImportStatement]] = ("import" ~ !letterOrDigit ~/ SWS ~/ identifier.rep(min = 1, sep = "/")).map(x => Seq(ImportStatement(x.mkString("/"))))
val forDirection: P[ForDirection.Value] =
("parallel" ~ HWS ~ "to").!.map(_ => ForDirection.ParallelTo) |

View File

@ -13,14 +13,14 @@ class MosSourceLoadingQueue(initialFilenames: List[String],
override def createParser(filename: String, src: String, parentDir: String, featureConstants: Map[String, Long], pragmas: Set[String]): MfParser[AssemblyLine] =
MosParser(filename, src, parentDir, options, featureConstants)
override def standardModules: IndexedSeq[String] = IndexedSeq("zp_reg", "bcd_6502")
override def standardModules: IndexedSeq[String] = IndexedSeq("m6502/zp_reg", "m6502/bcd_6502")
def enqueueStandardModules(): Unit = {
if (options.zpRegisterSize > 0) {
moduleQueue.enqueue(() => parseModule("zp_reg", includePath, Left(None)))
moduleQueue.enqueue(() => parseModule("m6502/zp_reg", includePath, Left(None)))
}
if (options.zpRegisterSize >= 4 && !options.flag(CompilationFlag.DecimalMode)) {
moduleQueue.enqueue(() => parseModule("bcd_6502", includePath, Left(None)))
moduleQueue.enqueue(() => parseModule("m6502/bcd_6502", includePath, Left(None)))
}
}

View File

@ -54,7 +54,7 @@ object EmuI86Run {
private def get(path: String): Program =
synchronized { cache.getOrElseUpdate(path, preload(path)).getOrElse(throw new IllegalStateException()) }
def cachedMath(): Program = get("include/i80_math.mfk") // TODO
def cachedMath(): Program = get("include/i80/i80_math.mfk") // TODO
def cachedStdio(): Program = get("src/test/resources/include/dummy_stdio.mfk")
val leakSaverCpu = new Intel8086()

View File

@ -187,7 +187,7 @@ class EmuRun(cpu: millfork.Cpu.Value, nodeOptimizations: List[NodeOptimization],
// prepare
val withLibraries = {
var tmp = unoptimized
if(source.contains("import zp_reg"))
if(source.contains("import zp_reg") || source.contains("import m6502/zp_reg"))
tmp += EmuRun.cachedZpreg
if(source.contains("import stdio"))
tmp += EmuRun.cachedStdio

View File

@ -56,7 +56,7 @@ object EmuZ80Run {
private def get(cpu: millfork.Cpu.Value, path: String): Program =
synchronized { cache.getOrElseUpdate(cpu->path, preload(cpu, path)).getOrElse(throw new IllegalStateException()) }
def cachedMath(cpu: millfork.Cpu.Value): Program = get(cpu, "include/i80_math.mfk")
def cachedMath(cpu: millfork.Cpu.Value): Program = get(cpu, "include/i80/i80_math.mfk")
def cachedStdio(cpu: millfork.Cpu.Value): Program = get(cpu, "src/test/resources/include/dummy_stdio.mfk")
}

View File

@ -49,8 +49,8 @@ object ShouldNotCompile extends Matchers {
else effectiveSource += "\nnoinline asm word call(word de) {\npush de\nret\n}\n"
}
}
if (source.contains("import zp_reg"))
effectiveSource += Files.readAllLines(Paths.get("include/zp_reg.mfk"), StandardCharsets.US_ASCII).asScala.mkString("\n", "\n", "")
if (source.contains("import zp_reg") || source.contains("import m6502/zp_reg"))
effectiveSource += Files.readAllLines(Paths.get("include/m6502/zp_reg.mfk"), StandardCharsets.US_ASCII).asScala.mkString("\n", "\n", "")
log.setSource(Some(effectiveSource.linesIterator.toIndexedSeq))
val PreprocessingResult(preprocessedSource, features, _) = Preprocessor.preprocessForTest(options, effectiveSource)
val parserF =