mirror of
https://github.com/irmen/prog8.git
synced 2025-01-23 00:31:14 +00:00
initial neo6502 target
This commit is contained in:
parent
688dce6145
commit
a50400b7d1
@ -27,6 +27,7 @@ val CompilationTargets = listOf(
|
||||
Cx16Target.NAME,
|
||||
PETTarget.NAME,
|
||||
AtariTarget.NAME,
|
||||
Neo6502Target.NAME,
|
||||
VMTarget.NAME
|
||||
)
|
||||
|
||||
@ -37,5 +38,6 @@ fun getCompilationTargetByName(name: String) = when(name.lowercase()) {
|
||||
PETTarget.NAME -> PETTarget()
|
||||
AtariTarget.NAME -> AtariTarget()
|
||||
VMTarget.NAME -> VMTarget()
|
||||
Neo6502Target.NAME -> Neo6502Target()
|
||||
else -> throw IllegalArgumentException("invalid compilation target")
|
||||
}
|
||||
}
|
||||
|
30
codeCore/src/prog8/code/target/Neo6502Target.kt
Normal file
30
codeCore/src/prog8/code/target/Neo6502Target.kt
Normal file
@ -0,0 +1,30 @@
|
||||
package prog8.code.target
|
||||
|
||||
import prog8.code.core.*
|
||||
import prog8.code.target.neo6502.Neo6502MachineDefinition
|
||||
|
||||
|
||||
class Neo6502Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer {
|
||||
override val name = NAME
|
||||
override val machine = Neo6502MachineDefinition()
|
||||
override val defaultEncoding = Encoding.ISO
|
||||
|
||||
companion object {
|
||||
const val NAME = "neo"
|
||||
}
|
||||
|
||||
override fun memorySize(dt: DataType): Int {
|
||||
return when(dt) {
|
||||
in ByteDatatypesWithBoolean -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> machine.FLOAT_MEM_SIZE
|
||||
else -> throw IllegalArgumentException("invalid datatype")
|
||||
}
|
||||
}
|
||||
|
||||
override fun memorySize(arrayDt: DataType, numElements: Int) =
|
||||
if(arrayDt== DataType.UWORD)
|
||||
numElements // pointer to bytes.
|
||||
else
|
||||
memorySize(ArrayToElementTypes.getValue(arrayDt)) * numElements
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package prog8.code.target.neo6502
|
||||
|
||||
import prog8.code.core.*
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
class Neo6502MachineDefinition: IMachineDefinition {
|
||||
|
||||
override val cpu = CpuType.CPU65c02
|
||||
|
||||
override val FLOAT_MAX_POSITIVE = 9.999999999e97
|
||||
override val FLOAT_MAX_NEGATIVE = -9.999999999e97
|
||||
override val FLOAT_MEM_SIZE = 6
|
||||
override val PROGRAM_LOAD_ADDRESS = 0x0800u
|
||||
|
||||
override val BSSHIGHRAM_START = 0u // TODO
|
||||
override val BSSHIGHRAM_END = 0u // TODO
|
||||
override val BSSGOLDENRAM_START = 0u // TODO
|
||||
override val BSSGOLDENRAM_END = 0u // TODO
|
||||
|
||||
override lateinit var zeropage: Zeropage
|
||||
override lateinit var golden: GoldenRam
|
||||
|
||||
override fun getFloatAsmBytes(num: Number) = TODO("atari float asm bytes from number")
|
||||
override fun convertFloatToBytes(num: Double): List<UByte> = TODO("atari float to bytes")
|
||||
override fun convertBytesToFloat(bytes: List<UByte>): Double = TODO("atari bytes to float")
|
||||
|
||||
override fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List<String> {
|
||||
return listOf("syslib")
|
||||
}
|
||||
|
||||
override fun launchEmulator(selectedEmulator: Int, programNameWithPath: Path) {
|
||||
if(selectedEmulator!=1) {
|
||||
System.err.println("The neo target only supports the main emulator (neo).")
|
||||
return
|
||||
}
|
||||
|
||||
val cmdline = listOf("neo", "${programNameWithPath}.bin@800", "cold")
|
||||
|
||||
println("\nStarting Neo6502 emulator...")
|
||||
val processb = ProcessBuilder(cmdline).inheritIO()
|
||||
val process: Process = processb.start()
|
||||
process.waitFor()
|
||||
}
|
||||
|
||||
override fun isIOAddress(address: UInt): Boolean = address in 0xff00u..0xff0fu
|
||||
|
||||
override fun initializeMemoryAreas(compilerOptions: CompilationOptions) {
|
||||
zeropage = Neo6502Zeropage(compilerOptions)
|
||||
golden = GoldenRam(compilerOptions, UIntRange.EMPTY)
|
||||
}
|
||||
}
|
48
codeCore/src/prog8/code/target/neo6502/Neo6502Zeropage.kt
Normal file
48
codeCore/src/prog8/code/target/neo6502/Neo6502Zeropage.kt
Normal file
@ -0,0 +1,48 @@
|
||||
package prog8.code.target.neo6502
|
||||
|
||||
import prog8.code.core.*
|
||||
|
||||
class Neo6502Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||
|
||||
override val SCRATCH_B1 = 0xfau // temp storage for a single byte
|
||||
override val SCRATCH_REG = 0xfbu // temp storage for a register, must be B1+1
|
||||
override val SCRATCH_W1 = 0xfcu // temp storage 1 for a word $fc+$fd
|
||||
override val SCRATCH_W2 = 0xfeu // temp storage 2 for a word $fe+$ff
|
||||
|
||||
init {
|
||||
if (options.floats) {
|
||||
throw InternalCompilerException("Neo6502 target doesn't support floating point routines")
|
||||
}
|
||||
|
||||
when (options.zeropage) {
|
||||
ZeropageType.DONTUSE -> {
|
||||
free.clear() // don't use zeropage at all
|
||||
}
|
||||
else -> {
|
||||
free.addAll(0x22u..0xffu)
|
||||
}
|
||||
}
|
||||
|
||||
val distinctFree = free.distinct()
|
||||
free.clear()
|
||||
free.addAll(distinctFree)
|
||||
|
||||
removeReservedFromFreePool()
|
||||
allocateCx16VirtualRegisters()
|
||||
retainAllowed()
|
||||
}
|
||||
|
||||
override fun allocateCx16VirtualRegisters() {
|
||||
// Note: the 16 virtual registers R0-R15 are not regular allocated variables, they're *memory mapped* elsewhere to fixed addresses.
|
||||
// However, to be able for the compiler to "see" them as zero page variables, we have to register them here as well.
|
||||
// This is important because the compiler sometimes treats ZP variables more efficiently (for example if it's a pointer)
|
||||
for(reg in 0..15) {
|
||||
allocatedVariables["cx16.r${reg}"] = VarAllocation((2+reg*2).toUInt(), DataType.UWORD, 2) // cx16.r0 .. cx16.r15
|
||||
allocatedVariables["cx16.r${reg}s"] = VarAllocation((2+reg*2).toUInt(), DataType.WORD, 2) // cx16.r0s .. cx16.r15s
|
||||
allocatedVariables["cx16.r${reg}L"] = VarAllocation((2+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0L .. cx16.r15L
|
||||
allocatedVariables["cx16.r${reg}H"] = VarAllocation((3+reg*2).toUInt(), DataType.UBYTE, 1) // cx16.r0H .. cx16.r15H
|
||||
allocatedVariables["cx16.r${reg}sL"] = VarAllocation((2+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sL .. cx16.r15sL
|
||||
allocatedVariables["cx16.r${reg}sH"] = VarAllocation((3+reg*2).toUInt(), DataType.BYTE, 1) // cx16.r0sH .. cx16.r15sH
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import prog8.code.core.*
|
||||
import prog8.code.target.AtariTarget
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.Neo6502Target
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
@ -16,6 +18,7 @@ internal class AssemblyProgram(
|
||||
private val binFile = outputDir.resolve("$name.bin")
|
||||
private val viceMonListFile = outputDir.resolve(C64Target.viceMonListName(name))
|
||||
private val listFile = outputDir.resolve("$name.list")
|
||||
private val targetWithoutBreakpointsForEmulator = setOf(AtariTarget.NAME, Neo6502Target.NAME)
|
||||
|
||||
override fun assemble(options: CompilationOptions, errors: IErrorReporter): Boolean {
|
||||
|
||||
@ -96,12 +99,47 @@ internal class AssemblyProgram(
|
||||
command.addAll(listOf("--output", outFile.toString(), assemblyFile.toString()))
|
||||
assemblerCommand = command
|
||||
}
|
||||
"neo" -> {
|
||||
// Neo6502 raw program generation.
|
||||
|
||||
if(options.output!=OutputType.RAW || options.loadAddress!=0x0800u || options.launcher!=CbmPrgLauncherType.NONE) {
|
||||
throw AssemblyError("invalid program compilation options. Neo6502 requires %output raw, %launcher none, %address $0800")
|
||||
}
|
||||
|
||||
// TODO are these options okay for neo?
|
||||
val command = mutableListOf("64tass", "--case-sensitive", "--long-branch",
|
||||
"-Wall", // "-Werror", "-Wno-strict-bool"
|
||||
"--no-monitor"
|
||||
)
|
||||
|
||||
if(options.warnSymbolShadowing)
|
||||
command.add("-Wshadow")
|
||||
else
|
||||
command.add("-Wno-shadow")
|
||||
|
||||
if(options.asmQuiet)
|
||||
command.add("--quiet")
|
||||
|
||||
if(options.asmListfile)
|
||||
command.add("--list=$listFile")
|
||||
|
||||
val outFile = when (options.output) {
|
||||
OutputType.RAW -> {
|
||||
command.add("--nostart")
|
||||
println("\nCreating raw binary for target ${compTarget.name}.")
|
||||
binFile
|
||||
}
|
||||
else -> throw AssemblyError("invalid output type, need 'raw'")
|
||||
}
|
||||
command.addAll(listOf("--output", outFile.toString(), assemblyFile.toString()))
|
||||
assemblerCommand = command
|
||||
}
|
||||
else -> throw AssemblyError("invalid compilation target")
|
||||
}
|
||||
|
||||
val proc = ProcessBuilder(assemblerCommand).inheritIO().start()
|
||||
val result = proc.waitFor()
|
||||
if (result == 0 && compTarget.name!="atari") {
|
||||
if (result == 0 && compTarget.name !in targetWithoutBreakpointsForEmulator) {
|
||||
removeGeneratedLabelsFromMonlist()
|
||||
generateBreakpointList()
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ atari {
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 8 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 8 = atari800XL
|
||||
const ubyte target = 8 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
const ubyte sizeof_bool = 1
|
||||
const ubyte sizeof_byte = 1
|
||||
|
@ -402,7 +402,7 @@ asmsub x16jsrfar() {
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 128 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16.
|
||||
const ubyte target = 128 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
const ubyte sizeof_bool = 1
|
||||
const ubyte sizeof_byte = 1
|
||||
|
@ -432,7 +432,7 @@ _jmpfar jmp $0000 ; modified
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 64 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16.
|
||||
const ubyte target = 64 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
const ubyte sizeof_bool = 1
|
||||
const ubyte sizeof_byte = 1
|
||||
|
@ -332,7 +332,7 @@ cx16 {
|
||||
&ubyte VERA_FX_X_POS_S = VERA_BASE + $0009
|
||||
&ubyte VERA_FX_Y_POS_S = VERA_BASE + $000a
|
||||
&ubyte VERA_FX_POLY_FILL_L = VERA_BASE + $000b
|
||||
&ubyte VERA_FX_POLY_FILL_H = VERA_BASE + $000c
|
||||
&ubyte VERA_FX_POLY_FILL_H = VERA_BASE + $000cF
|
||||
&uword VERA_FX_POLY_FILL = VERA_BASE + $000b
|
||||
&ubyte VERA_FX_CACHE_L = VERA_BASE + $0009
|
||||
&ubyte VERA_FX_CACHE_M = VERA_BASE + $000a
|
||||
@ -1372,7 +1372,7 @@ _continue iny
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 16 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16.
|
||||
const ubyte target = 16 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
const ubyte sizeof_bool = 1
|
||||
const ubyte sizeof_byte = 1
|
||||
|
500
compiler/res/prog8lib/neo/neo6502.asm
Normal file
500
compiler/res/prog8lib/neo/neo6502.asm
Normal file
@ -0,0 +1,500 @@
|
||||
; Convenience macros for Neo6502 applications programming
|
||||
; SPDX-License-Identifier: CC0-1.0
|
||||
; obtained from https://github.com/paulscottrobson/neo6502-firmware
|
||||
|
||||
;-----------------------------------------------------;
|
||||
; Neo6502 Kernel jump vectors (see kernel/kernel.asm) ;
|
||||
;-----------------------------------------------------;
|
||||
|
||||
ChainBasicOnlyProgram = $ffdf
|
||||
ChainBasicProgram = $ffe2
|
||||
WriteCharacterInline = $ffe5
|
||||
LoadExtended = $ffe8
|
||||
ReadLine = $FFEB
|
||||
ReadCharacter = $FFEE
|
||||
WriteCharacter = $FFF1
|
||||
WaitMessage = $FFF4
|
||||
SendMessage = $FFF7
|
||||
|
||||
|
||||
;--------------------------------------;
|
||||
; Neo6502 Kernel API control addresses ;
|
||||
;--------------------------------------;
|
||||
|
||||
ControlPort = $FF00
|
||||
API_COMMAND = ControlPort + 0 ; function group address
|
||||
API_FUNCTION = ControlPort + 1 ; function address
|
||||
API_ERROR = ControlPort + 2 ; function error codes
|
||||
API_STATUS = ControlPort + 3 ; misc hardware status codes (bit-field)
|
||||
API_PARAMETERS = ControlPort + 4 ; function parameters base address (+0-7)
|
||||
|
||||
|
||||
;------------------------------------------------;
|
||||
; Neo6502 Kernel API control codes (see api.pdf) ;
|
||||
;------------------------------------------------;
|
||||
|
||||
; Status Information
|
||||
API_ERROR_NONE = #$00 ; error code
|
||||
API_STATUS_ESC = #$07 ; flag
|
||||
|
||||
; System functions (Group 1)
|
||||
API_GROUP_SYSTEM = #$01 ; API function group
|
||||
API_FN_TIMER = #$01 ; API function
|
||||
API_FN_KEY_STATUS = #$02 ; API function
|
||||
API_FN_BASIC = #$03 ; API function
|
||||
API_FN_CREDITS = #$04 ; API function
|
||||
API_FN_SERIAL_STATUS = #$05 ; API function
|
||||
API_FN_LOCALE = #$06 ; API function
|
||||
API_FN_RESET = #$07 ; API function
|
||||
API_FN_MOS = #$08 ; API function
|
||||
API_FN_SWEET16 = #$09 ; API function
|
||||
|
||||
; Console functions (Group 2)
|
||||
API_GROUP_CONSOLE = #$02 ; API function group
|
||||
API_FN_READ_CHAR = #$01 ; API function
|
||||
API_FN_CONSOLE_STATUS = #$02 ; API function
|
||||
API_FN_READ_LINE = #$03 ; API function
|
||||
API_FN_DEFINE_HOTKEY = #$04 ; API function
|
||||
API_FN_DEFINE_CHAR = #$05 ; API function
|
||||
API_FN_WRITE_CHAR = #$06 ; API function
|
||||
API_FN_SET_CURSOR_POS = #$07 ; API function
|
||||
API_FN_LIST_HOTKEYS = #$08 ; API function
|
||||
API_FN_SCREEN_SIZE = #$09 ; API function
|
||||
API_FN_INSERT_LINE = #$0A ; API function
|
||||
API_FN_DELETE_LINE = #$0B ; API function
|
||||
API_FN_CLEAR_SCREEN = #$0C ; API function
|
||||
API_FN_CURSOR_POS = #$0D ; API function
|
||||
API_FN_CLEAR_REGIION = #$0E ; API function
|
||||
API_FN_SET_TEXT_COLOR = #$0F ; API function
|
||||
API_FN_CURSOR_INVERSE = #$10 ; API function
|
||||
|
||||
; Console results (Group 2 Function 2)
|
||||
API_QUEUE_EMPTY = #$FF ; API result (status code)
|
||||
|
||||
; File I/O functions (Group 3)
|
||||
API_GROUP_FILEIO = #$03 ; API function group
|
||||
API_FN_LIST_DIRECTORY = #$01 ; API function
|
||||
API_FN_LOAD_FILENAME = #$02 ; API function
|
||||
API_FN_STORE_FILENAME = #$03 ; API function
|
||||
API_FN_FILE_OPEN = #$04 ; API function
|
||||
API_FN_FILE_CLOSE = #$05 ; API function
|
||||
API_FN_FILE_SEEK = #$06 ; API function
|
||||
API_FN_FILE_TELL = #$07 ; API function
|
||||
API_FN_FILE_READ = #$08 ; API function
|
||||
API_FN_FILE_WRITE = #$09 ; API function
|
||||
API_FN_FILE_SIZE = #$0A ; API function
|
||||
API_FN_FILE_SET_SIZE = #$0B ; API function
|
||||
API_FN_FILE_RENAME = #$0C ; API function
|
||||
API_FN_FILE_DELETE = #$0D ; API function
|
||||
API_FN_DIR_CHDIR = #$0E ; API function
|
||||
API_FN_DIR_MKDIR = #$0F ; API function
|
||||
API_FN_FILE_STAT = #$10 ; API function
|
||||
API_FN_DIR_OPEN = #$11 ; API function
|
||||
API_FN_DIR_READ = #$12 ; API function
|
||||
API_FN_DIR_CLOSE = #$13 ; API function
|
||||
API_FN_FILE_COPY = #$14 ; API function
|
||||
API_FN_SET_ATTR = #$15 ; API function
|
||||
API_FN_LIST_FILTERED = #$20 ; API function
|
||||
|
||||
; File I/O parameters (Group 3 Function 2)
|
||||
API_FILE_TO_SCREEN = #$FFFF ; API parameter
|
||||
|
||||
; Mathematics functions (Group 4)
|
||||
API_GROUP_MATH = #$04 ; API function group
|
||||
API_FN_ADD = #$00 ; API function
|
||||
API_FN_SUB = #$01 ; API function
|
||||
API_FN_MUL = #$02 ; API function
|
||||
API_FN_DIV_DEC = #$03 ; API function
|
||||
API_FN_DIV_INT = #$04 ; API function
|
||||
API_FN_MOD = #$05 ; API function
|
||||
API_FN_COMP = #$06 ; API function
|
||||
API_FN_NEG = #$10 ; API function
|
||||
API_FN_FLOOR = #$11 ; API function
|
||||
API_FN_SQRT = #$12 ; API function
|
||||
API_FN_SINE = #$13 ; API function
|
||||
API_FN_COS = #$14 ; API function
|
||||
API_FN_TAN = #$15 ; API function
|
||||
API_FN_ATAN = #$16 ; API function
|
||||
API_FN_EXP = #$17 ; API function
|
||||
API_FN_LOG = #$18 ; API function
|
||||
API_FN_ABS = #$19 ; API function
|
||||
API_FN_SIGN = #$1A ; API function
|
||||
API_FN_RND_DEC = #$1B ; API function
|
||||
API_FN_RND_INT = #$1C ; API function
|
||||
API_FN_INT_TO_DEC = #$20 ; API function
|
||||
API_FN_STR_TO_NUM = #$21 ; API function
|
||||
API_FN_NUM_TO_STR = #$22 ; API function
|
||||
API_FN_SET_DEG_RAD_MODE = #$23 ; API function
|
||||
|
||||
; Graphics functions (Group 5)
|
||||
API_GROUP_GRAPHICS = #$05 ; API function group
|
||||
API_FN_SET_GFX = #$01 ; API function
|
||||
API_FN_DRAW_LINE = #$02 ; API function
|
||||
API_FN_DRAW_RECT = #$03 ; API function
|
||||
API_FN_DRAW_ELLIPSE = #$04 ; API function
|
||||
API_FN_DRAW_PIXEL = #$05 ; API function
|
||||
API_FN_DRAW_TEXT = #$06 ; API function
|
||||
API_FN_DRAW_IMG = #$07 ; API function
|
||||
API_FN_DRAW_TILEMAP = #$08 ; API function
|
||||
API_FN_SET_PALETTE = #$20 ; API function
|
||||
API_FN_READ_PIXEL = #$21 ; API function
|
||||
API_FN_RESET_PALETTE = #$22 ; API function
|
||||
API_FN_SET_TILEMAP = #$23 ; API function
|
||||
API_FN_READ_SPRITE_PXL = #$24 ; API function
|
||||
API_FN_FRAME_COUNT = #$25 ; API function
|
||||
API_FN_GET_PALETTE = #$26 ; API function
|
||||
API_FN_WRITE_PIXEL = #$27 ; API function
|
||||
API_FN_SET_COLOR = #$40 ; API function
|
||||
API_FN_SET_SOLID = #$41 ; API function
|
||||
API_FN_SET_DRAW_SIZE = #$42 ; API function
|
||||
API_FN_SET_FLIP = #$43 ; API function
|
||||
|
||||
; Graphics parameters (Group 5, Function 1 - Group 6, Function 2)
|
||||
API_FLIP_HORZ = #$00 ; API parameter (flag)
|
||||
API_FLIP_VERT = #$01 ; API parameter (flag)
|
||||
|
||||
; Graphics results (Group 5, Functions 33,36)
|
||||
API_PIXEL_TRANSPARENT = #$00 ; API result (flag)
|
||||
|
||||
; Sprites functions (Group 6)
|
||||
API_GROUP_SPRITES = #$06 ; API function group
|
||||
API_FN_SPRITE_RESET = #$01 ; API function
|
||||
API_FN_SPRITE_SET = #$02 ; API function
|
||||
API_FN_SPRITE_HIDE = #$03 ; API function
|
||||
API_FN_SPRITE_COLLISION = #$04 ; API function
|
||||
API_FN_SPRITE_POS = #$05 ; API function
|
||||
|
||||
; Sprites parameters (Group 6, Function 2)
|
||||
API_SPRITE_TURTLE = #$00 ; API parameter (sprite index)
|
||||
API_SPRITE_32BIT = #$40 ; API parameter (bit-mask)
|
||||
API_SPRITE_CLEAR = #$80 ; API parameter (bit-mask)
|
||||
API_ANCHOR_BL = #$01 ; API parameter (anchor position)
|
||||
API_ANCHOR_B = #$02 ; API parameter (anchor position)
|
||||
API_ANCHOR_BR = #$03 ; API parameter (anchor position)
|
||||
API_ANCHOR_L = #$04 ; API parameter (anchor position)
|
||||
API_ANCHOR_C = #$05 ; API parameter (anchor position)
|
||||
API_ANCHOR_R = #$06 ; API parameter (anchor position)
|
||||
API_ANCHOR_TL = #$07 ; API parameter (anchor position)
|
||||
API_ANCHOR_T = #$08 ; API parameter (anchor position)
|
||||
API_ANCHOR_TR = #$09 ; API parameter (anchor position)
|
||||
|
||||
; Sprites results (Group 6, Function 4)
|
||||
API_COLLISION_NONE = #$00 ; API result (flag)
|
||||
|
||||
; Controller functions (Group 7)
|
||||
API_GROUP_CONTROLLER = #$07 ; API function group
|
||||
API_FN_READ_DEFAULT_CONTROLLER = #$01 ; API function
|
||||
API_FN_READ_CONTROLLER_COUNT = #$02 ; API function
|
||||
API_FN_READ_CONTROLLER = #$03 ; API function
|
||||
|
||||
; Controller results (Group 7, Function 1)
|
||||
API_CONTROLLER_LEFT = #$01 ; API result (status bit-mask)
|
||||
API_CONTROLLER_RIGHT = #$02 ; API result (status bit-mask)
|
||||
API_CONTROLLER_UP = #$04 ; API result (status bit-mask)
|
||||
API_CONTROLLER_DOWN = #$08 ; API result (status bit-mask)
|
||||
API_CONTROLLER_BTNA = #$10 ; API result (status bit-mask)
|
||||
API_CONTROLLER_BTNB = #$20 ; API result (status bit-mask)
|
||||
|
||||
; Sound functions (Group 8)
|
||||
API_GROUP_SOUND = #$08 ; API function group
|
||||
API_FN_RESET_SOUND = #$01 ; API function
|
||||
API_FN_RESET_CHANNEL = #$02 ; API function
|
||||
API_FN_BEEP = #$03 ; API function
|
||||
API_FN_QUEUE_SOUND = #$04 ; API function
|
||||
API_FN_PLAY_SOUND = #$05 ; API function
|
||||
API_FN_SOUND_STATUS = #$06 ; API function
|
||||
|
||||
; Sound parameters (Group 8, Functions 2,4,5)
|
||||
API_SOUND_CH_00 = #$00 ; API parameter (channel index)
|
||||
|
||||
; Sound parameters (Group 8, Function 4)
|
||||
API_NOTE_REST = #$0000 ; API parameter (musical rest)
|
||||
API_NOTE_C0 = #$0010 ; API parameter (musical note)
|
||||
API_NOTE_Cs0 = #$0011 ; API parameter (musical note)
|
||||
API_NOTE_Df0 = #$0011 ; API parameter (musical note)
|
||||
API_NOTE_D0 = #$0012 ; API parameter (musical note)
|
||||
API_NOTE_Ds0 = #$0013 ; API parameter (musical note)
|
||||
API_NOTE_Ef0 = #$0013 ; API parameter (musical note)
|
||||
API_NOTE_E0 = #$0015 ; API parameter (musical note)
|
||||
API_NOTE_F0 = #$0016 ; API parameter (musical note)
|
||||
API_NOTE_Fs0 = #$0017 ; API parameter (musical note)
|
||||
API_NOTE_Gf0 = #$0017 ; API parameter (musical note)
|
||||
API_NOTE_G0 = #$0018 ; API parameter (musical note)
|
||||
API_NOTE_Af0 = #$001A ; API parameter (musical note)
|
||||
API_NOTE_Gs0 = #$001A ; API parameter (musical note)
|
||||
API_NOTE_A0 = #$001C ; API parameter (musical note)
|
||||
API_NOTE_As0 = #$001D ; API parameter (musical note)
|
||||
API_NOTE_Bf0 = #$001D ; API parameter (musical note)
|
||||
API_NOTE_B0 = #$001F ; API parameter (musical note)
|
||||
API_NOTE_C1 = #$0021 ; API parameter (musical note)
|
||||
API_NOTE_Cs1 = #$0023 ; API parameter (musical note)
|
||||
API_NOTE_Df1 = #$0023 ; API parameter (musical note)
|
||||
API_NOTE_D1 = #$0025 ; API parameter (musical note)
|
||||
API_NOTE_Ds1 = #$0027 ; API parameter (musical note)
|
||||
API_NOTE_Ef1 = #$0027 ; API parameter (musical note)
|
||||
API_NOTE_E1 = #$0029 ; API parameter (musical note)
|
||||
API_NOTE_F1 = #$002C ; API parameter (musical note)
|
||||
API_NOTE_Fs1 = #$002E ; API parameter (musical note)
|
||||
API_NOTE_Gf1 = #$002E ; API parameter (musical note)
|
||||
API_NOTE_G1 = #$0031 ; API parameter (musical note)
|
||||
API_NOTE_Af1 = #$0034 ; API parameter (musical note)
|
||||
API_NOTE_Gs1 = #$0034 ; API parameter (musical note)
|
||||
API_NOTE_A1 = #$0037 ; API parameter (musical note)
|
||||
API_NOTE_As1 = #$003A ; API parameter (musical note)
|
||||
API_NOTE_Bf1 = #$003A ; API parameter (musical note)
|
||||
API_NOTE_B1 = #$003E ; API parameter (musical note)
|
||||
API_NOTE_C2 = #$0041 ; API parameter (musical note)
|
||||
API_NOTE_Cs2 = #$0045 ; API parameter (musical note)
|
||||
API_NOTE_Df2 = #$0045 ; API parameter (musical note)
|
||||
API_NOTE_D2 = #$0049 ; API parameter (musical note)
|
||||
API_NOTE_Ds2 = #$004E ; API parameter (musical note)
|
||||
API_NOTE_Ef2 = #$004E ; API parameter (musical note)
|
||||
API_NOTE_E2 = #$0052 ; API parameter (musical note)
|
||||
API_NOTE_F2 = #$0057 ; API parameter (musical note)
|
||||
API_NOTE_Fs2 = #$005C ; API parameter (musical note)
|
||||
API_NOTE_Gf2 = #$005C ; API parameter (musical note)
|
||||
API_NOTE_G2 = #$0062 ; API parameter (musical note)
|
||||
API_NOTE_Af2 = #$0068 ; API parameter (musical note)
|
||||
API_NOTE_Gs2 = #$0068 ; API parameter (musical note)
|
||||
API_NOTE_A2 = #$006E ; API parameter (musical note)
|
||||
API_NOTE_As2 = #$0075 ; API parameter (musical note)
|
||||
API_NOTE_Bf2 = #$0075 ; API parameter (musical note)
|
||||
API_NOTE_B2 = #$007B ; API parameter (musical note)
|
||||
API_NOTE_C3 = #$0083 ; API parameter (musical note)
|
||||
API_NOTE_Cs3 = #$008B ; API parameter (musical note)
|
||||
API_NOTE_Df3 = #$008B ; API parameter (musical note)
|
||||
API_NOTE_D3 = #$0093 ; API parameter (musical note)
|
||||
API_NOTE_Ds3 = #$009C ; API parameter (musical note)
|
||||
API_NOTE_Ef3 = #$009C ; API parameter (musical note)
|
||||
API_NOTE_E3 = #$00A5 ; API parameter (musical note)
|
||||
API_NOTE_F3 = #$00AF ; API parameter (musical note)
|
||||
API_NOTE_Fs3 = #$00B9 ; API parameter (musical note)
|
||||
API_NOTE_Gf3 = #$00B9 ; API parameter (musical note)
|
||||
API_NOTE_G3 = #$00C4 ; API parameter (musical note)
|
||||
API_NOTE_Af3 = #$00D0 ; API parameter (musical note)
|
||||
API_NOTE_Gs3 = #$00D0 ; API parameter (musical note)
|
||||
API_NOTE_A3 = #$00DC ; API parameter (musical note)
|
||||
API_NOTE_As3 = #$00E9 ; API parameter (musical note)
|
||||
API_NOTE_Bf3 = #$00E9 ; API parameter (musical note)
|
||||
API_NOTE_B3 = #$00F7 ; API parameter (musical note)
|
||||
API_NOTE_C4 = #$0106 ; API parameter (musical note)
|
||||
API_NOTE_Cs4 = #$0115 ; API parameter (musical note)
|
||||
API_NOTE_Df4 = #$0115 ; API parameter (musical note)
|
||||
API_NOTE_D4 = #$0126 ; API parameter (musical note)
|
||||
API_NOTE_Ds4 = #$0137 ; API parameter (musical note)
|
||||
API_NOTE_Ef4 = #$0137 ; API parameter (musical note)
|
||||
API_NOTE_E4 = #$014A ; API parameter (musical note)
|
||||
API_NOTE_F4 = #$015D ; API parameter (musical note)
|
||||
API_NOTE_Fs4 = #$0172 ; API parameter (musical note)
|
||||
API_NOTE_Gf4 = #$0172 ; API parameter (musical note)
|
||||
API_NOTE_G4 = #$0188 ; API parameter (musical note)
|
||||
API_NOTE_Af4 = #$019F ; API parameter (musical note)
|
||||
API_NOTE_Gs4 = #$019F ; API parameter (musical note)
|
||||
API_NOTE_A4 = #$01B8 ; API parameter (musical note)
|
||||
API_NOTE_As4 = #$01D2 ; API parameter (musical note)
|
||||
API_NOTE_Bf4 = #$01D2 ; API parameter (musical note)
|
||||
API_NOTE_B4 = #$01EE ; API parameter (musical note)
|
||||
API_NOTE_C5 = #$020B ; API parameter (musical note)
|
||||
API_NOTE_Cs5 = #$022A ; API parameter (musical note)
|
||||
API_NOTE_Df5 = #$022A ; API parameter (musical note)
|
||||
API_NOTE_D5 = #$024B ; API parameter (musical note)
|
||||
API_NOTE_Ds5 = #$026E ; API parameter (musical note)
|
||||
API_NOTE_Ef5 = #$026E ; API parameter (musical note)
|
||||
API_NOTE_E5 = #$0293 ; API parameter (musical note)
|
||||
API_NOTE_F5 = #$02BA ; API parameter (musical note)
|
||||
API_NOTE_Fs5 = #$02E4 ; API parameter (musical note)
|
||||
API_NOTE_Gf5 = #$02E4 ; API parameter (musical note)
|
||||
API_NOTE_G5 = #$0310 ; API parameter (musical note)
|
||||
API_NOTE_Af5 = #$033F ; API parameter (musical note)
|
||||
API_NOTE_Gs5 = #$033F ; API parameter (musical note)
|
||||
API_NOTE_A5 = #$0370 ; API parameter (musical note)
|
||||
API_NOTE_As5 = #$03A4 ; API parameter (musical note)
|
||||
API_NOTE_Bf5 = #$03A4 ; API parameter (musical note)
|
||||
API_NOTE_B5 = #$03DC ; API parameter (musical note)
|
||||
API_NOTE_C6 = #$0417 ; API parameter (musical note)
|
||||
API_NOTE_Cs6 = #$0455 ; API parameter (musical note)
|
||||
API_NOTE_Df6 = #$0455 ; API parameter (musical note)
|
||||
API_NOTE_D6 = #$0497 ; API parameter (musical note)
|
||||
API_NOTE_Ds6 = #$04DD ; API parameter (musical note)
|
||||
API_NOTE_Ef6 = #$04DD ; API parameter (musical note)
|
||||
API_NOTE_E6 = #$0527 ; API parameter (musical note)
|
||||
API_NOTE_F6 = #$0575 ; API parameter (musical note)
|
||||
API_NOTE_Fs6 = #$05C8 ; API parameter (musical note)
|
||||
API_NOTE_Gf6 = #$05C8 ; API parameter (musical note)
|
||||
API_NOTE_G6 = #$0620 ; API parameter (musical note)
|
||||
API_NOTE_Af6 = #$067D ; API parameter (musical note)
|
||||
API_NOTE_Gs6 = #$067D ; API parameter (musical note)
|
||||
API_NOTE_A6 = #$06E0 ; API parameter (musical note)
|
||||
API_NOTE_As6 = #$0749 ; API parameter (musical note)
|
||||
API_NOTE_Bf6 = #$0749 ; API parameter (musical note)
|
||||
API_NOTE_B6 = #$07B8 ; API parameter (musical note)
|
||||
API_NOTE_C7 = #$082D ; API parameter (musical note)
|
||||
API_NOTE_Cs7 = #$08A9 ; API parameter (musical note)
|
||||
API_NOTE_Df7 = #$08A9 ; API parameter (musical note)
|
||||
API_NOTE_D7 = #$092D ; API parameter (musical note)
|
||||
API_NOTE_Ds7 = #$09B9 ; API parameter (musical note)
|
||||
API_NOTE_Ef7 = #$09B9 ; API parameter (musical note)
|
||||
API_NOTE_E7 = #$0A4D ; API parameter (musical note)
|
||||
API_NOTE_F7 = #$0AEA ; API parameter (musical note)
|
||||
API_NOTE_Fs7 = #$0B90 ; API parameter (musical note)
|
||||
API_NOTE_Gf7 = #$0B90 ; API parameter (musical note)
|
||||
API_NOTE_G7 = #$0C40 ; API parameter (musical note)
|
||||
API_NOTE_Af7 = #$0CFA ; API parameter (musical note)
|
||||
API_NOTE_Gs7 = #$0CFA ; API parameter (musical note)
|
||||
API_NOTE_A7 = #$0DC0 ; API parameter (musical note)
|
||||
API_NOTE_As7 = #$0E91 ; API parameter (musical note)
|
||||
API_NOTE_Bf7 = #$0E91 ; API parameter (musical note)
|
||||
API_NOTE_B7 = #$0F6F ; API parameter (musical note)
|
||||
API_NOTE_C8 = #$105A ; API parameter (musical note)
|
||||
API_NOTE_Cs8 = #$1153 ; API parameter (musical note)
|
||||
API_NOTE_Df8 = #$1153 ; API parameter (musical note)
|
||||
API_NOTE_D8 = #$125B ; API parameter (musical note)
|
||||
API_NOTE_Ds8 = #$1372 ; API parameter (musical note)
|
||||
API_NOTE_Ef8 = #$1372 ; API parameter (musical note)
|
||||
API_NOTE_E8 = #$149A ; API parameter (musical note)
|
||||
API_NOTE_F8 = #$15D4 ; API parameter (musical note)
|
||||
API_NOTE_Fs8 = #$1720 ; API parameter (musical note)
|
||||
API_NOTE_Gf8 = #$1720 ; API parameter (musical note)
|
||||
API_NOTE_G8 = #$1880 ; API parameter (musical note)
|
||||
API_NOTE_Af8 = #$19F5 ; API parameter (musical note)
|
||||
API_NOTE_Gs8 = #$19F5 ; API parameter (musical note)
|
||||
API_NOTE_A8 = #$1B80 ; API parameter (musical note)
|
||||
API_NOTE_As8 = #$1D23 ; API parameter (musical note)
|
||||
API_NOTE_Bf8 = #$1D23 ; API parameter (musical note)
|
||||
API_NOTE_B8 = #$1EDE ; API parameter (musical note)
|
||||
API_NOTE_C9 = #$20B4 ; API parameter (musical note)
|
||||
API_NOTE_Cs9 = #$22A6 ; API parameter (musical note)
|
||||
API_NOTE_Df9 = #$22A6 ; API parameter (musical note)
|
||||
API_NOTE_D9 = #$24B5 ; API parameter (musical note)
|
||||
API_NOTE_Ds9 = #$26E4 ; API parameter (musical note)
|
||||
API_NOTE_Ef9 = #$26E4 ; API parameter (musical note)
|
||||
API_NOTE_E9 = #$2934 ; API parameter (musical note)
|
||||
API_NOTE_F9 = #$2BA7 ; API parameter (musical note)
|
||||
API_NOTE_Fs9 = #$2E40 ; API parameter (musical note)
|
||||
API_NOTE_Gf9 = #$2E40 ; API parameter (musical note)
|
||||
API_NOTE_G9 = #$3100 ; API parameter (musical note)
|
||||
API_NOTE_Af9 = #$33EA ; API parameter (musical note)
|
||||
API_NOTE_Gs9 = #$33EA ; API parameter (musical note)
|
||||
API_NOTE_A9 = #$3700 ; API parameter (musical note)
|
||||
API_NOTE_As9 = #$3A45 ; API parameter (musical note)
|
||||
API_NOTE_Bf9 = #$3A45 ; API parameter (musical note)
|
||||
API_NOTE_B9 = #$3DBC ; API parameter (musical note)
|
||||
API_NOTE_C10 = #$4168 ; API parameter (musical note)
|
||||
API_NOTE_Cs10 = #$454C ; API parameter (musical note)
|
||||
API_NOTE_Df10 = #$454C ; API parameter (musical note)
|
||||
API_NOTE_D10 = #$496B ; API parameter (musical note)
|
||||
API_NOTE_Ds10 = #$4DC8 ; API parameter (musical note)
|
||||
API_NOTE_Ef10 = #$4DC8 ; API parameter (musical note)
|
||||
API_TEMPO_60 = #$0064 ; API parameter (musical note duration, 60BPM)
|
||||
API_TEMPO_80 = #$004B ; API parameter (musical note duration, 80BPM)
|
||||
API_TEMPO_90 = #$0042 ; API parameter (musical note duration, 90BPM)
|
||||
API_TEMPO_120 = #$0032 ; API parameter (musical note duration, 120BPM)
|
||||
API_SLIDE_NONE = #$0000 ; API parameter (slide value)
|
||||
API_SLIDE_SLOW = #$0004 ; API parameter (slide range)
|
||||
API_SLIDE_MED = #$0008 ; API parameter (slide range)
|
||||
API_SLIDE_FAST = #$0010 ; API parameter (slide range)
|
||||
API_SOUND_SRC_BEEP = #$00 ; API parameter (sound generator)
|
||||
|
||||
; Sound parameters (Group 8, Function 5)
|
||||
API_SFX_POSITIVE = #$00 ; API parameter (sound effect)
|
||||
API_SFX_NEGATIVE = #$01 ; API parameter (sound effect)
|
||||
API_SFX_ERROR = #$02 ; API parameter (sound effect)
|
||||
API_SFX_CONFIRM = #$03 ; API parameter (sound effect)
|
||||
API_SFX_REJECT = #$04 ; API parameter (sound effect)
|
||||
API_SFX_SWEEP = #$05 ; API parameter (sound effect)
|
||||
API_SFX_COIN = #$06 ; API parameter (sound effect)
|
||||
API_SFX_LASER_LONG = #$07 ; API parameter (sound effect)
|
||||
API_SFX_POWERUP = #$08 ; API parameter (sound effect)
|
||||
API_SFX_VICTORY = #$09 ; API parameter (sound effect)
|
||||
API_SFX_DEFEAT = #$0A ; API parameter (sound effect)
|
||||
API_SFX_FANFARE = #$0B ; API parameter (sound effect)
|
||||
API_SFX_ALARM1 = #$0C ; API parameter (sound effect)
|
||||
API_SFX_ALARM2 = #$0D ; API parameter (sound effect)
|
||||
API_SFX_ALARM3 = #$0E ; API parameter (sound effect)
|
||||
API_SFX_RING1 = #$0F ; API parameter (sound effect)
|
||||
API_SFX_RING2 = #$10 ; API parameter (sound effect)
|
||||
API_SFX_RING3 = #$11 ; API parameter (sound effect)
|
||||
API_SFX_DANGER = #$12 ; API parameter (sound effect)
|
||||
API_SFX_EXPL_LONG = #$13 ; API parameter (sound effect)
|
||||
API_SFX_EXPL_MEDIUM = #$14 ; API parameter (sound effect)
|
||||
API_SFX_EXPL_SHORT = #$15 ; API parameter (sound effect)
|
||||
API_SFX_LASER_MEDIUM = #$16 ; API parameter (sound effect)
|
||||
API_SFX_LASER_SHORT = #$17 ; API parameter (sound effect)
|
||||
|
||||
; Turtle Graphics functions (Group 9)
|
||||
API_GROUP_TURTLE = #$09 ; API function group
|
||||
API_FN_TURTLE_INIT = #$01 ; API function
|
||||
API_FN_TURTLE_TURN = #$02 ; API function
|
||||
API_FN_TURTLE_MOVE = #$03 ; API function
|
||||
API_FN_TURTLE_HIDE = #$04 ; API function
|
||||
API_FN_TURTLE_HOME = #$05 ; API function
|
||||
|
||||
; Turtle Graphics parameters (Group 9, Function 2)
|
||||
API_TURTLE_LEFT = #$010E ; API parameter (turn -90 degrees)
|
||||
API_TURTLE_RIGHT = #$005A ; API parameter (turn +90 degrees)
|
||||
API_TURTLE_FLIP = #$00B4 ; API parameter (turn 180 degrees)
|
||||
|
||||
; Turtle Graphics parameters (Group 9, Function 3)
|
||||
API_PEN_UP = #$00 ; API parameter (turtle tracks on)
|
||||
API_PEN_DOWN = #$01 ; API parameter (turtle tracks off)
|
||||
|
||||
; UExt functions (Group 10)
|
||||
API_GROUP_UEXT = #$09 ; API function group
|
||||
API_FN_UEXT_INIT = #$01 ; API function
|
||||
API_FN_GPIO_WRITE = #$02 ; API function
|
||||
API_FN_GPIO_READ = #$03 ; API function
|
||||
API_FN_SET_PORT_DIR = #$04 ; API function
|
||||
API_FN_I2C_WRITE = #$05 ; API function
|
||||
API_FN_I2C_READ = #$06 ; API function
|
||||
API_FN_ANALOG_READ = #$07 ; API function
|
||||
API_FN_I2C_STATUS = #$08 ; API function
|
||||
API_FN_I2C_READ_BLOCK = #$09 ; API function
|
||||
API_FN_I2C_WRITE_BLCOK = #$0a ; API function
|
||||
API_FN_SPI_READ_BLOCK = #$0b ; API function
|
||||
API_FN_SPI_WRITE_BLOCK = #$0c ; API function
|
||||
API_FN_UART_READ_BLOCK = #$0d ; API function
|
||||
API_FN_UART_WRITE_BLOPCK= #$0e ; API function
|
||||
API_FN_UART_SET_SPEED = #$0f ; API function
|
||||
API_FN_UART_WRITE = #$10 ; API function
|
||||
API_FN_UART_READ = #$11 ; API function
|
||||
API_FN_UART_CHECK_BYTE_AVAILABLE = #$12 ; API function
|
||||
|
||||
; TODO group 11 MOUSE
|
||||
; TODO group 12 BLITTER
|
||||
; TODO group 13 EDITOR
|
||||
|
||||
|
||||
;--------;
|
||||
; colors ;
|
||||
;--------;
|
||||
|
||||
COLOR_BLACK = #$80
|
||||
COLOR_RED = #$81
|
||||
COLOR_GREEN = #$82
|
||||
COLOR_YELLOW = #$83
|
||||
COLOR_BLUE = #$84
|
||||
COLOR_MAGENTA = #$85
|
||||
COLOR_CYAN = #$86
|
||||
COLOR_WHITE = #$87
|
||||
COLOR_ALT_BLACK = #$88
|
||||
COLOR_DARK_GREY = #$89
|
||||
COLOR_DARK_GREEN = #$8A
|
||||
COLOR_ORANGE = #$8B
|
||||
COLOR_DARK_ORANGE = #$8C
|
||||
COLOR_BROWN = #$8D
|
||||
COLOR_PINK = #$8E
|
||||
COLOR_LIGHT_GREY = #$8F
|
||||
|
||||
|
||||
;---------------------------------;
|
||||
; limited-case convenience macros ;
|
||||
;---------------------------------;
|
||||
|
||||
DoSendMessage .macro
|
||||
jsr neo.SendMessage
|
||||
.endm
|
||||
|
||||
DoWaitMessage .macro
|
||||
jsr neo.WaitMessage
|
||||
.endm
|
||||
|
439
compiler/res/prog8lib/neo/syslib.p8
Normal file
439
compiler/res/prog8lib/neo/syslib.p8
Normal file
@ -0,0 +1,439 @@
|
||||
; Prog8 definitions for the Neo6502
|
||||
|
||||
%option no_symbol_prefixing, ignore_unused
|
||||
|
||||
neo {
|
||||
&uword NMI_VEC = $FFFA ; 6502 nmi vector, determined by the kernal if banked in
|
||||
&uword RESET_VEC = $FFFC ; 6502 reset vector, determined by the kernal if banked in
|
||||
&uword IRQ_VEC = $FFFE ; 6502 interrupt vector, determined by the kernal if banked in
|
||||
|
||||
%asminclude "library:neo/neo6502.asm"
|
||||
}
|
||||
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 7 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
asmsub init_system() {
|
||||
; Initializes the machine to a sane starting state.
|
||||
; Called automatically by the loader program logic.
|
||||
%asm {{
|
||||
sei
|
||||
cld
|
||||
clc
|
||||
; TODO reset screen mode etc etc?
|
||||
clv
|
||||
; TODO what about IRQ handler? cli
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub init_system_phase2() {
|
||||
%asm {{
|
||||
rts ; no phase 2 steps on the Neo6502
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub reset_system() {
|
||||
; Soft-reset the system back to initial power-on status
|
||||
; TODO
|
||||
%asm {{
|
||||
sei
|
||||
jmp (neo.RESET_VEC)
|
||||
}}
|
||||
}
|
||||
|
||||
sub wait(uword jiffies) {
|
||||
; --- wait approximately the given number of jiffies (1/60th seconds)
|
||||
; TODO
|
||||
}
|
||||
|
||||
asmsub waitvsync() clobbers(A) {
|
||||
; --- busy wait till the next vsync has occurred (approximately), without depending on custom irq handling.
|
||||
; TODO
|
||||
%asm {{
|
||||
nop
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub internal_stringcopy(uword source @R0, uword target @AY) clobbers (A,Y) {
|
||||
; Called when the compiler wants to assign a string value to another string.
|
||||
%asm {{
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda cx16.r0
|
||||
ldy cx16.r0+1
|
||||
jmp prog8_lib.strcpy
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memcopy(uword source @R0, uword target @R1, uword count @AY) clobbers(A,X,Y) {
|
||||
; note: only works for NON-OVERLAPPING memory regions!
|
||||
; note: can't be inlined because is called from asm as well
|
||||
%asm {{
|
||||
ldx cx16.r0
|
||||
stx P8ZP_SCRATCH_W1 ; source in ZP
|
||||
ldx cx16.r0+1
|
||||
stx P8ZP_SCRATCH_W1+1
|
||||
ldx cx16.r1
|
||||
stx P8ZP_SCRATCH_W2 ; target in ZP
|
||||
ldx cx16.r1+1
|
||||
stx P8ZP_SCRATCH_W2+1
|
||||
cpy #0
|
||||
bne _longcopy
|
||||
|
||||
; copy <= 255 bytes
|
||||
tay
|
||||
bne _copyshort
|
||||
rts ; nothing to copy
|
||||
|
||||
_copyshort
|
||||
dey
|
||||
beq +
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
dey
|
||||
bne -
|
||||
+ lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
rts
|
||||
|
||||
_longcopy
|
||||
sta P8ZP_SCRATCH_B1 ; lsb(count) = remainder in last page
|
||||
tya
|
||||
tax ; x = num pages (1+)
|
||||
ldy #0
|
||||
- lda (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W2),y
|
||||
iny
|
||||
bne -
|
||||
inc P8ZP_SCRATCH_W1+1
|
||||
inc P8ZP_SCRATCH_W2+1
|
||||
dex
|
||||
bne -
|
||||
ldy P8ZP_SCRATCH_B1
|
||||
bne _copyshort
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memset(uword mem @R0, uword numbytes @R1, ubyte value @A) clobbers(A,X,Y) {
|
||||
%asm {{
|
||||
ldy cx16.r0
|
||||
sty P8ZP_SCRATCH_W1
|
||||
ldy cx16.r0+1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
ldx cx16.r1
|
||||
ldy cx16.r1+1
|
||||
jmp prog8_lib.memset
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub memsetw(uword mem @R0, uword numwords @R1, uword value @AY) clobbers(A,X,Y) {
|
||||
%asm {{
|
||||
ldx cx16.r0
|
||||
stx P8ZP_SCRATCH_W1
|
||||
ldx cx16.r0+1
|
||||
stx P8ZP_SCRATCH_W1+1
|
||||
ldx cx16.r1
|
||||
stx P8ZP_SCRATCH_W2
|
||||
ldx cx16.r1+1
|
||||
stx P8ZP_SCRATCH_W2+1
|
||||
jmp prog8_lib.memsetw
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub read_flags() -> ubyte @A {
|
||||
%asm {{
|
||||
php
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub clear_carry() {
|
||||
%asm {{
|
||||
clc
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub set_carry() {
|
||||
%asm {{
|
||||
sec
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub clear_irqd() {
|
||||
%asm {{
|
||||
cli
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub set_irqd() {
|
||||
%asm {{
|
||||
sei
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub irqsafe_set_irqd() {
|
||||
%asm {{
|
||||
php
|
||||
sei
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub irqsafe_clear_irqd() {
|
||||
%asm {{
|
||||
plp
|
||||
}}
|
||||
}
|
||||
|
||||
sub disable_caseswitch() {
|
||||
; no-op
|
||||
}
|
||||
|
||||
sub enable_caseswitch() {
|
||||
; no-op
|
||||
}
|
||||
|
||||
asmsub save_prog8_internals() {
|
||||
%asm {{
|
||||
lda P8ZP_SCRATCH_B1
|
||||
sta save_SCRATCH_ZPB1
|
||||
lda P8ZP_SCRATCH_REG
|
||||
sta save_SCRATCH_ZPREG
|
||||
lda P8ZP_SCRATCH_W1
|
||||
sta save_SCRATCH_ZPWORD1
|
||||
lda P8ZP_SCRATCH_W1+1
|
||||
sta save_SCRATCH_ZPWORD1+1
|
||||
lda P8ZP_SCRATCH_W2
|
||||
sta save_SCRATCH_ZPWORD2
|
||||
lda P8ZP_SCRATCH_W2+1
|
||||
sta save_SCRATCH_ZPWORD2+1
|
||||
rts
|
||||
save_SCRATCH_ZPB1 .byte 0
|
||||
save_SCRATCH_ZPREG .byte 0
|
||||
save_SCRATCH_ZPWORD1 .word 0
|
||||
save_SCRATCH_ZPWORD2 .word 0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub restore_prog8_internals() {
|
||||
%asm {{
|
||||
lda save_prog8_internals.save_SCRATCH_ZPB1
|
||||
sta P8ZP_SCRATCH_B1
|
||||
lda save_prog8_internals.save_SCRATCH_ZPREG
|
||||
sta P8ZP_SCRATCH_REG
|
||||
lda save_prog8_internals.save_SCRATCH_ZPWORD1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda save_prog8_internals.save_SCRATCH_ZPWORD1+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda save_prog8_internals.save_SCRATCH_ZPWORD2
|
||||
sta P8ZP_SCRATCH_W2
|
||||
lda save_prog8_internals.save_SCRATCH_ZPWORD2+1
|
||||
sta P8ZP_SCRATCH_W2+1
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub exit(ubyte returnvalue @A) {
|
||||
; -- immediately exit the program with a return code in the A register
|
||||
; TODO where to store A as exit code?
|
||||
%asm {{
|
||||
ldx prog8_lib.orig_stackpointer
|
||||
txs
|
||||
rts ; return to original caller
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub exit2(ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y) {
|
||||
; -- immediately exit the program with result values in the A, X and Y registers.
|
||||
; TODO where to store A,X,Y as exit code?
|
||||
%asm {{
|
||||
jmp exit
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub exit3(ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y, bool carry @Pc) {
|
||||
; -- immediately exit the program with result values in the A, X and Y registers, and the Carry flag in the status register.
|
||||
; TODO where to store A,X,Y,Carry as exit code?
|
||||
%asm {{
|
||||
jmp exit
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub progend() -> uword @AY {
|
||||
%asm {{
|
||||
lda #<prog8_program_end
|
||||
ldy #>prog8_program_end
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cx16 {
|
||||
; the sixteen virtual 16-bit registers that the CX16 has defined in the zeropage
|
||||
; the sixteen virtual 16-bit registers in both normal unsigned mode and signed mode (s)
|
||||
&uword r0 = $0002
|
||||
&uword r1 = $0004
|
||||
&uword r2 = $0006
|
||||
&uword r3 = $0008
|
||||
&uword r4 = $000a
|
||||
&uword r5 = $000c
|
||||
&uword r6 = $000e
|
||||
&uword r7 = $0010
|
||||
&uword r8 = $0012
|
||||
&uword r9 = $0014
|
||||
&uword r10 = $0016
|
||||
&uword r11 = $0018
|
||||
&uword r12 = $001a
|
||||
&uword r13 = $001c
|
||||
&uword r14 = $001e
|
||||
&uword r15 = $0020
|
||||
|
||||
&word r0s = $0002
|
||||
&word r1s = $0004
|
||||
&word r2s = $0006
|
||||
&word r3s = $0008
|
||||
&word r4s = $000a
|
||||
&word r5s = $000c
|
||||
&word r6s = $000e
|
||||
&word r7s = $0010
|
||||
&word r8s = $0012
|
||||
&word r9s = $0014
|
||||
&word r10s = $0016
|
||||
&word r11s = $0018
|
||||
&word r12s = $001a
|
||||
&word r13s = $001c
|
||||
&word r14s = $001e
|
||||
&word r15s = $0020
|
||||
|
||||
&ubyte r0L = $0002
|
||||
&ubyte r1L = $0004
|
||||
&ubyte r2L = $0006
|
||||
&ubyte r3L = $0008
|
||||
&ubyte r4L = $000a
|
||||
&ubyte r5L = $000c
|
||||
&ubyte r6L = $000e
|
||||
&ubyte r7L = $0010
|
||||
&ubyte r8L = $0012
|
||||
&ubyte r9L = $0014
|
||||
&ubyte r10L = $0016
|
||||
&ubyte r11L = $0018
|
||||
&ubyte r12L = $001a
|
||||
&ubyte r13L = $001c
|
||||
&ubyte r14L = $001e
|
||||
&ubyte r15L = $0020
|
||||
|
||||
&ubyte r0H = $0003
|
||||
&ubyte r1H = $0005
|
||||
&ubyte r2H = $0007
|
||||
&ubyte r3H = $0009
|
||||
&ubyte r4H = $000b
|
||||
&ubyte r5H = $000d
|
||||
&ubyte r6H = $000f
|
||||
&ubyte r7H = $0011
|
||||
&ubyte r8H = $0013
|
||||
&ubyte r9H = $0015
|
||||
&ubyte r10H = $0017
|
||||
&ubyte r11H = $0019
|
||||
&ubyte r12H = $001b
|
||||
&ubyte r13H = $001d
|
||||
&ubyte r14H = $001f
|
||||
&ubyte r15H = $0021
|
||||
|
||||
&byte r0sL = $0002
|
||||
&byte r1sL = $0004
|
||||
&byte r2sL = $0006
|
||||
&byte r3sL = $0008
|
||||
&byte r4sL = $000a
|
||||
&byte r5sL = $000c
|
||||
&byte r6sL = $000e
|
||||
&byte r7sL = $0010
|
||||
&byte r8sL = $0012
|
||||
&byte r9sL = $0014
|
||||
&byte r10sL = $0016
|
||||
&byte r11sL = $0018
|
||||
&byte r12sL = $001a
|
||||
&byte r13sL = $001c
|
||||
&byte r14sL = $001e
|
||||
&byte r15sL = $0020
|
||||
|
||||
&byte r0sH = $0003
|
||||
&byte r1sH = $0005
|
||||
&byte r2sH = $0007
|
||||
&byte r3sH = $0009
|
||||
&byte r4sH = $000b
|
||||
&byte r5sH = $000d
|
||||
&byte r6sH = $000f
|
||||
&byte r7sH = $0011
|
||||
&byte r8sH = $0013
|
||||
&byte r9sH = $0015
|
||||
&byte r10sH = $0017
|
||||
&byte r11sH = $0019
|
||||
&byte r12sH = $001b
|
||||
&byte r13sH = $001d
|
||||
&byte r14sH = $001f
|
||||
&byte r15sH = $0021
|
||||
|
||||
asmsub save_virtual_registers() clobbers(A,Y) {
|
||||
%asm {{
|
||||
ldy #31
|
||||
- lda cx16.r0,y
|
||||
sta _cx16_vreg_storage,y
|
||||
dey
|
||||
bpl -
|
||||
rts
|
||||
|
||||
_cx16_vreg_storage
|
||||
.word 0,0,0,0,0,0,0,0
|
||||
.word 0,0,0,0,0,0,0,0
|
||||
}}
|
||||
}
|
||||
|
||||
asmsub restore_virtual_registers() clobbers(A,Y) {
|
||||
%asm {{
|
||||
ldy #31
|
||||
- lda save_virtual_registers._cx16_vreg_storage,y
|
||||
sta cx16.r0,y
|
||||
dey
|
||||
bpl -
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
sub cpu_is_65816() -> bool {
|
||||
; Returns true when you have a 65816 cpu, false when it's a 6502.
|
||||
return false
|
||||
}
|
||||
|
||||
}
|
@ -96,7 +96,7 @@ asmsub kbdbuf_clear() {
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 32 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 32=PET
|
||||
const ubyte target = 32 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
const ubyte sizeof_bool = 1
|
||||
const ubyte sizeof_byte = 1
|
||||
|
@ -5,7 +5,7 @@
|
||||
sys {
|
||||
; ------- lowlevel system routines --------
|
||||
|
||||
const ubyte target = 255 ; compilation target specifier. 64 = C64, 128 = C128, 16 = CommanderX16, 8 = atari800XL, 255 = virtual
|
||||
const ubyte target = 255 ; compilation target specifier. 255=virtual, 128=C128, 64=C64, 32=PET, 16=CommanderX16, 8=atari800XL, 7=Neo6502
|
||||
|
||||
const ubyte sizeof_bool = 1
|
||||
const ubyte sizeof_byte = 1
|
||||
|
@ -292,7 +292,7 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
val programNameInPath = outputPath.resolve(compilationResult.compilerAst.name)
|
||||
|
||||
if(startEmulator1==true || startEmulator2==true) {
|
||||
if (compilationResult.compilationOptions.launcher != CbmPrgLauncherType.NONE || compilationTarget=="atari") {
|
||||
if (compilationResult.compilationOptions.launcher != CbmPrgLauncherType.NONE || compilationTarget=="atari" || compilationTarget=="neo") {
|
||||
if (startEmulator1 == true)
|
||||
compilationResult.compilationOptions.compTarget.machine.launchEmulator(1, programNameInPath)
|
||||
else if (startEmulator2 == true)
|
||||
|
@ -15,10 +15,7 @@ import prog8.code.ast.printAst
|
||||
import prog8.code.ast.verifyFinalAstBeforeAsmGen
|
||||
import prog8.code.core.*
|
||||
import prog8.code.optimize.optimizeIntermediateAst
|
||||
import prog8.code.target.AtariTarget
|
||||
import prog8.code.target.Cx16Target
|
||||
import prog8.code.target.VMTarget
|
||||
import prog8.code.target.getCompilationTargetByName
|
||||
import prog8.code.target.*
|
||||
import prog8.codegen.vm.VmCodeGen
|
||||
import prog8.compiler.astprocessing.*
|
||||
import prog8.optimizer.*
|
||||
@ -236,7 +233,11 @@ internal fun determineProgramLoadAddress(program: Program, options: CompilationO
|
||||
}
|
||||
else {
|
||||
when(options.output) {
|
||||
OutputType.RAW -> { /* no predefined load address */ }
|
||||
OutputType.RAW -> {
|
||||
if(options.compTarget.name==Neo6502Target.NAME)
|
||||
loadAddress = options.compTarget.machine.PROGRAM_LOAD_ADDRESS
|
||||
// for all other targets, RAW has no predefined load address.
|
||||
}
|
||||
OutputType.PRG -> {
|
||||
if(options.launcher==CbmPrgLauncherType.BASIC) {
|
||||
loadAddress = options.compTarget.machine.PROGRAM_LOAD_ADDRESS
|
||||
|
@ -136,7 +136,7 @@ One or more .p8 module files
|
||||
``-target <compilation target>``
|
||||
Sets the target output of the compiler. This option is required.
|
||||
``c64`` = Commodore 64, ``c128`` = Commodore 128, ``cx16`` = Commander X16, ``pet32`` - Commodore PET model 4032,
|
||||
``atari`` = Atari 800 XL, ``virtual`` = builtin virtual machine.
|
||||
``atari`` = Atari 800 XL, ``neo`` = Neo6502, ``virtual`` = builtin virtual machine.
|
||||
|
||||
``-srcdirs <pathlist>``
|
||||
Specify a list of extra paths (separated with ':'), to search in for imported modules.
|
||||
|
@ -235,6 +235,7 @@ Grouped per compilation target.
|
||||
* `c128 <_static/symboldumps/skeletons-c128.txt>`_
|
||||
* `cx16 <_static/symboldumps/skeletons-cx16.txt>`_
|
||||
* `pet32 <_static/symboldumps/skeletons-pet32.txt>`_
|
||||
* `neo <_static/symboldumps/skeletons-neo.txt>`_
|
||||
* `virtual <_static/symboldumps/skeletons-virtual.txt>`_
|
||||
|
||||
|
||||
|
@ -16,6 +16,7 @@ Currently these machines can be selected as a compilation target (via the ``-tar
|
||||
- 'c128': the Commodore 128 (*limited support*)
|
||||
- 'pet32': the Commodore PET 4032 (*limited support*)
|
||||
- 'atari': the Atari 800 XL (*experimental support*)
|
||||
- 'neo': the `Neo6502 <https://github.com/paulscottrobson/neo6502-firmware/wiki>`_ (*experimental*)
|
||||
- 'virtual': a builtin virtual machine
|
||||
|
||||
This chapter explains some relevant system details of the c64 and cx16 machines.
|
||||
|
128
examples/test.p8
128
examples/test.p8
@ -1,20 +1,118 @@
|
||||
%import textio
|
||||
%import floats
|
||||
%option no_sysinit
|
||||
%zeropage basicsafe
|
||||
%output raw
|
||||
%launcher none
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
float @shared fl1 = 4444.234
|
||||
float @shared fl2 = -9999.111
|
||||
float @shared fl3 = fl1+fl2
|
||||
floats.print(fl1)
|
||||
txt.spc()
|
||||
floats.print(fl2)
|
||||
txt.spc()
|
||||
floats.print(fl3)
|
||||
txt.nl()
|
||||
txt.print_w(fl3 as word)
|
||||
txt.nl()
|
||||
romsub $fff1 = WriteCharacter(ubyte character @A)
|
||||
|
||||
for cx16.r0L in "\n\n\n.... Hello from Prog8 :-)"
|
||||
WriteCharacter(cx16.r0L)
|
||||
|
||||
repeat {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub start2() {
|
||||
|
||||
%asm {{
|
||||
|
||||
; Program constants
|
||||
CURSOR_POS_X = #0 ; character display 'X' coordinate
|
||||
CURSOR_POS_Y = #21 ; character display 'Y' coordinate
|
||||
NEWLINE_CHAR = #13 ; ASCII character code
|
||||
|
||||
|
||||
;--------------;
|
||||
; Main Program ;
|
||||
;--------------;
|
||||
|
||||
start:
|
||||
;-----------------------------------------------;
|
||||
; Play sound effect - (API Group 8, Function 5) ;
|
||||
;-----------------------------------------------;
|
||||
|
||||
lda neo.API_SOUND_CH_00 ; sound channel (API::sound->play->channel)
|
||||
sta neo.API_PARAMETERS + 0 ; set API 'Parameter0' (API::sound->play->channel)
|
||||
lda neo.API_SFX_COIN ; sound effect index (API::sound->play->effect)
|
||||
sta neo.API_PARAMETERS + 1 ; set API 'Parameter1' (API::sound->play->effect)
|
||||
lda neo.API_FN_PLAY_SOUND ; sound effect function (API::sound->play)
|
||||
sta neo.API_FUNCTION ; set API 'Function' (API::sound->play)
|
||||
lda neo.API_GROUP_SOUND ; 'Sound' API function group (API::sound)
|
||||
sta neo.API_COMMAND ; trigger 'Sound' API routine (API::sound)
|
||||
|
||||
|
||||
;--------------------------------------------------;
|
||||
; Set cursor position - (API Group 2, Function 7) ;
|
||||
;--------------------------------------------------;
|
||||
|
||||
; reposition the cursor to overwrite the default welcome text
|
||||
lda neo.API_FN_SET_CURSOR_POS ; set cursor position function (API::console->cursor)
|
||||
sta neo.API_FUNCTION ; set API 'Function' (API::console->cursor)
|
||||
lda CURSOR_POS_X ; cursor 'X' coordinate (API::console->cursor->x)
|
||||
sta neo.API_PARAMETERS + 0 ; set API 'Parameter0' (API::console->cursor->x)
|
||||
lda CURSOR_POS_Y ; cursor 'Y' coordinate (API::console->cursor->y)
|
||||
sta neo.API_PARAMETERS + 1 ; set API 'Parameter1' (API::console->cursor->y)
|
||||
lda neo.API_GROUP_CONSOLE ; 'Console' API function group (API::console)
|
||||
sta neo.API_COMMAND ; trigger 'Console' API routine (API::console)
|
||||
|
||||
; this simply repeats the same routine as the previous block,
|
||||
; but using the generic convenience macro, for the sake of demonstration
|
||||
lda CURSOR_POS_X
|
||||
sta neo.API_PARAMETERS + 0
|
||||
lda CURSOR_POS_Y
|
||||
sta neo.API_PARAMETERS + 1
|
||||
#neo.DoSendMessage ; send command 2,7
|
||||
.byte 2,7
|
||||
|
||||
|
||||
;--------------------------------------------------------;
|
||||
; Write character to console - (API Group 2, Function 6) ;
|
||||
;--------------------------------------------------------;
|
||||
|
||||
; first, write a single newline character, using the special convenience macro
|
||||
lda NEWLINE_CHAR
|
||||
jsr neo.WriteCharacter
|
||||
; the text foreground color can also be set by injecting a control character
|
||||
lda neo.COLOR_DARK_GREEN
|
||||
jsr neo.WriteCharacter
|
||||
|
||||
; next, print the welcome message (a string of characters), using the API
|
||||
ldx #0 ; initialize string iteration index
|
||||
lda neo.API_FN_WRITE_CHAR ; console write function (API::console->write)
|
||||
sta neo.API_FUNCTION ; set API 'Function' (API::console->write)
|
||||
print_next_char:
|
||||
lda neo.API_COMMAND ; previous API routine status
|
||||
bne print_next_char ; wait for previous API routine to complete
|
||||
|
||||
lda hello_msg , x ; next character of 'hello_msg' (API::console->write->char)
|
||||
beq end ; test for string end null byte
|
||||
sta neo.API_PARAMETERS + 0 ; set API 'Parameter0' (API::console->write->char)
|
||||
lda neo.API_GROUP_CONSOLE ; 'Console' API function group (API::console)
|
||||
sta neo.API_COMMAND ; trigger 'Console' API routine (API::console)
|
||||
|
||||
inx ; increment iteration index
|
||||
jmp print_next_char ; continue 'hello_msg' print loop
|
||||
|
||||
end:
|
||||
jmp end ; infinite loop
|
||||
|
||||
|
||||
;--------------;
|
||||
; Program data ;
|
||||
;--------------;
|
||||
|
||||
hello_msg:
|
||||
.text " Hello Neo6502" ; line 1 to display
|
||||
.text 13 ; newline
|
||||
.text " " ; 53 blanks
|
||||
.text 13 ; newline
|
||||
.text " Now you're playing with Neo Power!" ; line 2 to display
|
||||
.text 13 ; newline
|
||||
.text " (Some assembly required)" ; line 3 to display
|
||||
.text 0 ; null-terminated
|
||||
|
||||
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user