From 4daf75a8cc8b70b3f924fa48383658bd2eeb58e5 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 23 Sep 2020 00:22:36 +0200 Subject: [PATCH] better checks for invalid %output and %launcher values. Added diskdir examples. --- compiler/res/prog8lib/c64/syslib.p8 | 1 + compiler/src/prog8/compiler/Main.kt | 9 ++++ docs/source/todo.rst | 5 +- examples/diskdir-sys50000.p8 | 46 ++++++++++++++++++ examples/diskdir.p8 | 73 ++++++++++++----------------- 5 files changed, 91 insertions(+), 43 deletions(-) create mode 100644 examples/diskdir-sys50000.p8 diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index eaf38f22f..8af3f0754 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -11,6 +11,7 @@ c64 { &ubyte TIME_HI = $a0 ; software jiffy clock, hi byte &ubyte TIME_MID = $a1 ; .. mid byte &ubyte TIME_LO = $a2 ; .. lo byte. Updated by IRQ every 1/60 sec + &ubyte STATUS = $90 ; kernel status variable for I/O &ubyte STKEY = $91 ; various keyboard statuses (updated by IRQ) &ubyte SFDX = $cb ; current key pressed (matrix value) (updated by IRQ) diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index de6c143c6..bc9948615 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -148,6 +148,15 @@ private fun determineCompilationOptions(program: Program): CompilationOptions { .map { it[0].int!!..it[1].int!! } .toList() + if(outputType!=null && !OutputType.values().any {it.name==outputType}) { + System.err.println("invalid output type $outputType") + exitProcess(1) + } + if(launcherType!=null && !LauncherType.values().any {it.name==launcherType}) { + System.err.println("invalid launcher type $launcherType") + exitProcess(1) + } + return CompilationOptions( if (outputType == null) OutputType.PRG else OutputType.valueOf(outputType), if (launcherType == null) LauncherType.BASIC else LauncherType.valueOf(launcherType), diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 2df49ea85..bbd27dea7 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,11 @@ TODO ==== - get rid of all other TODO's in the code ;-) +- move the ldx #$ff | clc | cld from the startup logic into the start() function as first instructions +- add an %option that omits the 'system-init' code at the start. Useful to create separate standalone routines that shouldn't re-init the whole machine every time they're called - line-circle-gfx examples are now a few hundred bytes larger than before. Why is that, can it be fixed? +- until condition should be able to refer to variables defined IN the do-until block itself. +- add support? example? for processing arguments to a sys call : sys 999, 1, 2, "aaa" - make it possible for array literals to not only contain compile time constants - further optimize assignment codegeneration - implement @stack for asmsub parameters @@ -13,7 +17,6 @@ TODO - use VIC banking to move up the graphics bitmap memory location. Don't move it under the ROM though as that would require IRQ disabling and memory bank swapping for every bitmap manipulation - add some primitives/support/examples for using custom char sets, copying the default charset. - More optimizations ^^^^^^^^^^^^^^^^^^ diff --git a/examples/diskdir-sys50000.p8 b/examples/diskdir-sys50000.p8 new file mode 100644 index 000000000..8afc16bfb --- /dev/null +++ b/examples/diskdir-sys50000.p8 @@ -0,0 +1,46 @@ +%target c64 +%import textio +%import syslib +%zeropage basicsafe +%launcher none +%address 50000 + +; This example shows the directory contents of disk drive 8. +; You load it with LOAD "diskdir-sys50000",8,1 +; and then call it with SYS 50000. + +main { + sub start() { + txt.print("directory of disk drive #8:\n\n") + diskdir(8) + } + + sub diskdir(ubyte drivenumber) { + c64.SETNAM(1, "$") + c64.SETLFS(1, drivenumber, 0) + c64.OPEN() ; open 1,8,0,"$" + c64.CHKIN(1) ; use #1 as input channel + + repeat 4 { + void c64.CHRIN() ; skip the 4 prologue bytes + } + + ; while not key pressed / EOF encountered, read data. + while not (@($c6) | c64.STATUS) { + txt.print_uw(mkword(c64.CHRIN(), c64.CHRIN())) + txt.chrout(' ') + ubyte @zp char + do { + char = c64.CHRIN() + txt.chrout(char) + } until char==0 + txt.chrout('\n') + repeat 2 { + void c64.CHRIN() ; skip 2 bytes + } + } + + c64.CLOSE(1) + c64.CLRCHN() ; restore default i/o devices + } +} diff --git a/examples/diskdir.p8 b/examples/diskdir.p8 index b03dce528..adcd6386a 100644 --- a/examples/diskdir.p8 +++ b/examples/diskdir.p8 @@ -1,53 +1,42 @@ %target c64 %import textio %import syslib -%zeropage dontuse +%zeropage basicsafe ; This example shows the directory contents of disk drive 8. main { sub start() { - %asm {{ - lda #$01 - ldx #dirname - jsr c64.SETNAM - lda #1 - ldx #8 - ldy #0 - jsr c64.SETLFS - jsr c64.OPEN ; OPEN 1,8,0 - ldx #1 - jsr c64.CHKIN ; define input channel - ldy #$04 -labl1 jsr c64.CHRIN ; input byte on serial bus - dey - bne labl1 ; get rid of Y bytes - lda $C6 ; key pressed? - ora $90 ; or EOF? - bne labl2 ; if yes exit - jsr c64.CHRIN ; now get the size of the file - pha - jsr c64.CHRIN - tay - pla - jsr txt.print_uw - lda #32 - jsr c64.CHROUT -labl3 jsr c64.CHRIN ; now the filename - jsr c64.CHROUT ; put a character to screen - cmp #0 - bne labl3 ; while not 0 encountered - lda #13 - jsr c64.CHROUT ; put a CR , end line - ldy #$02 ; set 2 bytes to skip - bne labl1 ; repeat -labl2 lda #1 - jsr c64.CLOSE ; close serial bus device - jsr c64.CLRCHN ; restore I/O devices to default - rts + txt.print("directory of disk drive #8:\n\n") + diskdir(8) + } -dirname .byte "$" - }} + sub diskdir(ubyte drivenumber) { + c64.SETNAM(1, "$") + c64.SETLFS(1, drivenumber, 0) + c64.OPEN() ; open 1,8,0,"$" + c64.CHKIN(1) ; use #1 as input channel + + repeat 4 { + void c64.CHRIN() ; skip the 4 prologue bytes + } + + ; while not key pressed / EOF encountered, read data. + while not (@($c6) | c64.STATUS) { + txt.print_uw(mkword(c64.CHRIN(), c64.CHRIN())) + txt.chrout(' ') + ubyte @zp char + do { + char = c64.CHRIN() + txt.chrout(char) + } until char==0 + txt.chrout('\n') + repeat 2 { + void c64.CHRIN() ; skip 2 bytes + } + } + + c64.CLOSE(1) + c64.CLRCHN() ; restore default i/o devices } }