From ddb83467116f62c5daa3331d7454b53157d0ac1a Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 7 Apr 2024 19:32:44 +0200 Subject: [PATCH] added txt.cls() as a shorter alternative to clear_screen(). cx16: added new character encodings, and routines in textio to enable the character sets for them. cx16: added txt.chrout_lit() and txt.print_lit() to always print the literal characters and never as control codes --- .../src/prog8/code/core/IStringEncoding.kt | 5 +- codeCore/src/prog8/code/target/Encoder.kt | 10 ++- .../{cbm => encodings}/AtasciiEncoding.kt | 2 +- .../code/target/encodings/Cp437Encoding.kt | 68 +++++++++++++++++++ .../target/{cbm => encodings}/IsoEncoding.kt | 11 ++- .../{cbm => encodings}/PetsciiEncoding.kt | 2 +- compiler/res/prog8lib/atari/textio.p8 | 12 ++-- compiler/res/prog8lib/c128/syslib.p8 | 7 +- compiler/res/prog8lib/c128/textio.p8 | 4 ++ compiler/res/prog8lib/c64/syslib.p8 | 6 +- compiler/res/prog8lib/c64/textio.p8 | 4 ++ compiler/res/prog8lib/cx16/syslib.p8 | 5 +- compiler/res/prog8lib/cx16/textio.p8 | 60 +++++++++++++++- compiler/res/prog8lib/pet32/textio.p8 | 4 ++ .../prog8lib/shared_cbm_textio_functions.p8 | 8 +-- compiler/res/prog8lib/virtual/textio.p8 | 4 ++ compiler/test/TestCompilerOnExamples.kt | 1 + compiler/test/TestStringEncodings.kt | 6 +- compiler/test/ast/TestProg8Parser.kt | 2 +- docs/source/compiling.rst | 11 +-- docs/source/syntaxreference.rst | 7 +- docs/source/todo.rst | 8 +++ examples/cx16/charsets.p8 | 65 ++++++++++++++++++ syntax-files/IDEA/Prog8.xml | 2 +- 24 files changed, 275 insertions(+), 39 deletions(-) rename codeCore/src/prog8/code/target/{cbm => encodings}/AtasciiEncoding.kt (99%) create mode 100644 codeCore/src/prog8/code/target/encodings/Cp437Encoding.kt rename codeCore/src/prog8/code/target/{cbm => encodings}/IsoEncoding.kt (77%) rename codeCore/src/prog8/code/target/{cbm => encodings}/PetsciiEncoding.kt (99%) create mode 100644 examples/cx16/charsets.p8 diff --git a/codeCore/src/prog8/code/core/IStringEncoding.kt b/codeCore/src/prog8/code/core/IStringEncoding.kt index efbc11475..843a3f1c2 100644 --- a/codeCore/src/prog8/code/core/IStringEncoding.kt +++ b/codeCore/src/prog8/code/core/IStringEncoding.kt @@ -5,7 +5,10 @@ enum class Encoding(val prefix: String) { PETSCII("petscii"), // c64/c128/cx16 SCREENCODES("sc"), // c64/c128/cx16 ATASCII("atascii"), // atari - ISO("iso") // cx16 + ISO("iso"), // cx16 (iso-8859-15) + ISO5("iso5"), // cx16 (iso-8859-5, cyrillic) + ISO16("iso16"), // cx16 (iso-8859-16, eastern european) + CP437("cp437") // cx16 (ibm pc, codepage 437) } interface IStringEncoding { diff --git a/codeCore/src/prog8/code/target/Encoder.kt b/codeCore/src/prog8/code/target/Encoder.kt index 16a8703fa..b1294c95d 100644 --- a/codeCore/src/prog8/code/target/Encoder.kt +++ b/codeCore/src/prog8/code/target/Encoder.kt @@ -4,9 +4,7 @@ import com.github.michaelbull.result.fold import prog8.code.core.Encoding import prog8.code.core.IStringEncoding import prog8.code.core.InternalCompilerException -import prog8.code.target.cbm.AtasciiEncoding -import prog8.code.target.cbm.IsoEncoding -import prog8.code.target.cbm.PetsciiEncoding +import prog8.code.target.encodings.* object Encoder: IStringEncoding { @@ -18,6 +16,9 @@ object Encoder: IStringEncoding { Encoding.SCREENCODES -> PetsciiEncoding.encodeScreencode(str, true) Encoding.ISO -> IsoEncoding.encode(str) Encoding.ATASCII -> AtasciiEncoding.encode(str) + Encoding.ISO5 -> IsoCyrillicEncoding.encode(str) + Encoding.ISO16 -> IsoEasternEncoding.encode(str) + Encoding.CP437 -> Cp437Encoding.encode(str) else -> throw InternalCompilerException("unsupported encoding $encoding") } return coded.fold( @@ -31,6 +32,9 @@ object Encoder: IStringEncoding { Encoding.SCREENCODES -> PetsciiEncoding.decodeScreencode(bytes, true) Encoding.ISO -> IsoEncoding.decode(bytes) Encoding.ATASCII -> AtasciiEncoding.decode(bytes) + Encoding.ISO5 -> IsoCyrillicEncoding.decode(bytes) + Encoding.ISO16 -> IsoEasternEncoding.decode(bytes) + Encoding.CP437 -> Cp437Encoding.decode(bytes) else -> throw InternalCompilerException("unsupported encoding $encoding") } return decoded.fold( diff --git a/codeCore/src/prog8/code/target/cbm/AtasciiEncoding.kt b/codeCore/src/prog8/code/target/encodings/AtasciiEncoding.kt similarity index 99% rename from codeCore/src/prog8/code/target/cbm/AtasciiEncoding.kt rename to codeCore/src/prog8/code/target/encodings/AtasciiEncoding.kt index 51f5d3173..dbac5e418 100644 --- a/codeCore/src/prog8/code/target/cbm/AtasciiEncoding.kt +++ b/codeCore/src/prog8/code/target/encodings/AtasciiEncoding.kt @@ -1,4 +1,4 @@ -package prog8.code.target.cbm +package prog8.code.target.encodings import com.github.michaelbull.result.Ok import com.github.michaelbull.result.Result diff --git a/codeCore/src/prog8/code/target/encodings/Cp437Encoding.kt b/codeCore/src/prog8/code/target/encodings/Cp437Encoding.kt new file mode 100644 index 000000000..30aa7a0a2 --- /dev/null +++ b/codeCore/src/prog8/code/target/encodings/Cp437Encoding.kt @@ -0,0 +1,68 @@ +package prog8.code.target.encodings + +import com.github.michaelbull.result.Err +import com.github.michaelbull.result.Ok +import com.github.michaelbull.result.Result +import java.io.CharConversionException +import java.nio.charset.Charset + +object Cp437Encoding { + val charset: Charset = Charset.forName("IBM437") + + fun encode(str: String): Result, CharConversionException> { + return try { + val mapped = str.map { chr -> + when (chr) { + '\u0000' -> 0u + '☺' -> 1u + '☻' -> 2u + '♥' -> 3u + '♦' -> 4u + '♣' -> 5u + '♠' -> 6u + '•' -> 7u + '◘' -> 8u + '○' -> 9u + '◙' -> 10u + '♂' -> 11u + '♀' -> 12u + '♪' -> 13u + '♫' -> 14u + '☼' -> 15u + '►' -> 16u + '◄' -> 17u + '↕' -> 18u + '‼' -> 19u + '¶' -> 20u + '§' -> 21u + '▬' -> 22u + '↨' -> 23u + '↑' -> 24u + '↓' -> 25u + '→' -> 26u + '←' -> 27u + '∟' -> 28u + '↔' -> 29u + '▲' -> 30u + '▼' -> 31u + in '\u8000'..'\u80ff' -> { + // special case: take the lower 8 bit hex value directly + (chr.code - 0x8000).toUByte() + } + else -> charset.encode(chr.toString())[0].toUByte() + } + } + Ok(mapped) + } catch (ce: CharConversionException) { + Err(ce) + } + } + + fun decode(bytes: Iterable): Result { + return try { + Ok(String(bytes.map { it.toByte() }.toByteArray(), charset)) + } catch (ce: CharConversionException) { + Err(ce) + } + } +} diff --git a/codeCore/src/prog8/code/target/cbm/IsoEncoding.kt b/codeCore/src/prog8/code/target/encodings/IsoEncoding.kt similarity index 77% rename from codeCore/src/prog8/code/target/cbm/IsoEncoding.kt rename to codeCore/src/prog8/code/target/encodings/IsoEncoding.kt index acd12e849..9f0a8a947 100644 --- a/codeCore/src/prog8/code/target/cbm/IsoEncoding.kt +++ b/codeCore/src/prog8/code/target/encodings/IsoEncoding.kt @@ -1,4 +1,4 @@ -package prog8.code.target.cbm +package prog8.code.target.encodings import com.github.michaelbull.result.Err import com.github.michaelbull.result.Ok @@ -6,8 +6,8 @@ import com.github.michaelbull.result.Result import java.io.CharConversionException import java.nio.charset.Charset -object IsoEncoding { - val charset: Charset = Charset.forName("ISO-8859-15") +open class IsoEncodingBase(charsetName: String) { + val charset: Charset = Charset.forName(charsetName) fun encode(str: String): Result, CharConversionException> { return try { @@ -35,3 +35,8 @@ object IsoEncoding { } } } + + +object IsoEncoding: IsoEncodingBase("ISO-8859-15") +object IsoCyrillicEncoding: IsoEncodingBase("ISO-8859-5") +object IsoEasternEncoding: IsoEncodingBase("ISO-8859-16") diff --git a/codeCore/src/prog8/code/target/cbm/PetsciiEncoding.kt b/codeCore/src/prog8/code/target/encodings/PetsciiEncoding.kt similarity index 99% rename from codeCore/src/prog8/code/target/cbm/PetsciiEncoding.kt rename to codeCore/src/prog8/code/target/encodings/PetsciiEncoding.kt index 30370e54e..77e9a3f52 100644 --- a/codeCore/src/prog8/code/target/cbm/PetsciiEncoding.kt +++ b/codeCore/src/prog8/code/target/encodings/PetsciiEncoding.kt @@ -1,4 +1,4 @@ -package prog8.code.target.cbm +package prog8.code.target.encodings import com.github.michaelbull.result.Err import com.github.michaelbull.result.Ok diff --git a/compiler/res/prog8lib/atari/textio.p8 b/compiler/res/prog8lib/atari/textio.p8 index 49a391c66..fece5f65e 100644 --- a/compiler/res/prog8lib/atari/textio.p8 +++ b/compiler/res/prog8lib/atari/textio.p8 @@ -16,6 +16,10 @@ sub clear_screen() { chrout(125) } +sub cls() { + chrout(125) +} + sub nl() { chrout('\n') } @@ -147,15 +151,15 @@ _tmp_outchar } asmsub print (str text @ AY) clobbers(A,Y) { - ; ---- print null terminated string from A/Y + ; ---- print zero terminated string from A/Y ; note: the compiler contains an optimization that will replace ; a call to this subroutine with a string argument of just one char, ; by just one call to CHROUT of that single char. %asm {{ - sta P8ZP_SCRATCH_B1 - sty P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 ldy #0 -- lda (P8ZP_SCRATCH_B1),y +- lda (P8ZP_SCRATCH_W2),y beq + jsr chrout iny diff --git a/compiler/res/prog8lib/c128/syslib.p8 b/compiler/res/prog8lib/c128/syslib.p8 index 7d8816ef1..1ade1d546 100644 --- a/compiler/res/prog8lib/c128/syslib.p8 +++ b/compiler/res/prog8lib/c128/syslib.p8 @@ -93,11 +93,12 @@ romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high) -romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 -romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 +romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 +romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock -romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns +romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! +romsub $FFED = SCRORG() -> ubyte @ X, ubyte @ Y ; get current window dimensions into X (columns) and Y (rows) NOTE: changed behavior compared to VIC/C64/PET SCREEN() routine! romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices diff --git a/compiler/res/prog8lib/c128/textio.p8 b/compiler/res/prog8lib/c128/textio.p8 index 7536e2868..8a62ba700 100644 --- a/compiler/res/prog8lib/c128/textio.p8 +++ b/compiler/res/prog8lib/c128/textio.p8 @@ -20,6 +20,10 @@ sub clear_screen() { chrout(147) } +sub cls() { + chrout(147) +} + sub home() { chrout(19) } diff --git a/compiler/res/prog8lib/c64/syslib.p8 b/compiler/res/prog8lib/c64/syslib.p8 index 40342f2c9..20abff7a2 100644 --- a/compiler/res/prog8lib/c64/syslib.p8 +++ b/compiler/res/prog8lib/c64/syslib.p8 @@ -94,11 +94,11 @@ romsub $FFD5 = LOAD(ubyte verify @ A, uword address @ XY) -> bool @Pc, ubyte @ A romsub $FFD8 = SAVE(ubyte zp_startaddr @ A, uword endaddr @ XY) -> bool @ Pc, ubyte @ A ; (via 818 ($332)) save to a device romsub $FFDB = SETTIM(ubyte low @ A, ubyte middle @ X, ubyte high @ Y) ; set the software clock romsub $FFDE = RDTIM() -> ubyte @ A, ubyte @ X, ubyte @ Y ; read the software clock (A=lo,X=mid,Y=high) -romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 -romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 +romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328)) check the STOP key (and some others in A) also see STOP2 +romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock -romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns +romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Use txt.plot for a 'safe' wrapper that preserves X. romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices diff --git a/compiler/res/prog8lib/c64/textio.p8 b/compiler/res/prog8lib/c64/textio.p8 index c547fb0ed..9316aaa03 100644 --- a/compiler/res/prog8lib/c64/textio.p8 +++ b/compiler/res/prog8lib/c64/textio.p8 @@ -19,6 +19,10 @@ sub clear_screen() { chrout(147) } +sub cls() { + chrout(147) +} + sub home() { chrout(19) } diff --git a/compiler/res/prog8lib/cx16/syslib.p8 b/compiler/res/prog8lib/cx16/syslib.p8 index 6fc23c235..12a3dad40 100644 --- a/compiler/res/prog8lib/cx16/syslib.p8 +++ b/compiler/res/prog8lib/cx16/syslib.p8 @@ -47,7 +47,7 @@ romsub $FFE1 = STOP() clobbers(X) -> bool @ Pz, ubyte @ A ; (via 808 ($328 romsub $FFE4 = GETIN() clobbers(X,Y) -> bool @Pc, ubyte @ A ; (via 810 ($32A)) get a character also see GETIN2 romsub $FFE7 = CLALL() clobbers(A,X) ; (via 812 ($32C)) close all files romsub $FFEA = UDTIM() clobbers(A,X) ; update the software clock -romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; read number of screen rows and columns +romsub $FFED = SCREEN() -> ubyte @ X, ubyte @ Y ; get size of text screen into X (columns) and Y (rows) romsub $FFF0 = PLOT(ubyte col @ Y, ubyte row @ X, bool dir @ Pc) clobbers(A) -> ubyte @ X, ubyte @ Y ; read/set position of cursor on screen. Also see txt.plot romsub $FFF3 = IOBASE() -> uword @ XY ; read base address of I/O devices @@ -567,8 +567,7 @@ asmsub set_screen_mode(ubyte mode @A) clobbers(A,X,Y) -> bool @Pc { } asmsub get_screen_mode() -> ubyte @A, ubyte @X, ubyte @Y { - ; -- convenience wrapper for screen_mode() to just get the current mode in A, and size in characters in X+Y - ; this does need a piece of inlined asm to call it ans store the result values if you call this from prog8 code + ; -- convenience wrapper for screen_mode() to just get the current mode in A, and size in characters in X (width) and Y (height) ; Note: you can also just do the SEC yourself and simply call screen_mode() directly, ; or use the existing SCREEN kernal routine for just getting the size in characters. %asm {{ diff --git a/compiler/res/prog8lib/cx16/textio.p8 b/compiler/res/prog8lib/cx16/textio.p8 index b68be4f38..6cc002184 100644 --- a/compiler/res/prog8lib/cx16/textio.p8 +++ b/compiler/res/prog8lib/cx16/textio.p8 @@ -23,6 +23,10 @@ sub clear_screen() { chrout(147) } +sub cls() { + chrout(147) +} + sub home() { chrout(19) } @@ -225,8 +229,8 @@ sub uppercase() { } sub iso() { + ; -- switch to iso-8859-15 character set cbm.CHROUT($0f) - ; This doesn't enable it completely: cx16.screen_set_charset(1, 0) ; iso charset } sub iso_off() { @@ -234,6 +238,29 @@ sub iso_off() { cbm.CHROUT($8f) } +sub cp437() { + ; -- switch to CP-437 (ibm PC) character set + cbm.CHROUT($0f) ; iso mode + cx16.screen_set_charset(7, 0) ; charset + %asm {{ + clc + ldx #95 ; underscore + lda #cx16.EXTAPI_iso_cursor_char + jsr cx16.extapi + }} +} + +sub iso5() { + ; -- switch to iso-8859-5 character set (Cyrillic) + cbm.CHROUT($0f) ; iso mode + cx16.screen_set_charset(8, 0) ; charset +} + +sub iso16() { + ; -- switch to iso-8859-16 character set (Eastern Europe) + cbm.CHROUT($0f) ; iso mode + cx16.screen_set_charset(10, 0) ; charset +} asmsub scroll_left() clobbers(A, X, Y) { ; ---- scroll the whole screen 1 character to the left @@ -604,4 +631,35 @@ asmsub waitkey() -> ubyte @A { rts }} } + +asmsub chrout_lit(ubyte character @A) { + ; -- print the character always as a literal character, not as possible control code. + %asm {{ + tax + lda #128 + jsr cbm.CHROUT + txa + jmp cbm.CHROUT + }} +} + +asmsub print_lit(str text @ AY) clobbers(A,Y) { + ; -- print zero terminated string, from A/Y, as all literal characters (no control codes) + %asm {{ + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy #0 +- lda (P8ZP_SCRATCH_W2),y + beq + + tax + lda #128 + jsr cbm.CHROUT + txa + jsr cbm.CHROUT + iny + bne - ++ rts + }} +} + } diff --git a/compiler/res/prog8lib/pet32/textio.p8 b/compiler/res/prog8lib/pet32/textio.p8 index caf2982b2..da60aeacd 100644 --- a/compiler/res/prog8lib/pet32/textio.p8 +++ b/compiler/res/prog8lib/pet32/textio.p8 @@ -19,6 +19,10 @@ sub clear_screen() { chrout(147) } +sub cls() { + chrout(147) +} + sub home() { chrout(19) } diff --git a/compiler/res/prog8lib/shared_cbm_textio_functions.p8 b/compiler/res/prog8lib/shared_cbm_textio_functions.p8 index d91f57f9b..12faa9109 100644 --- a/compiler/res/prog8lib/shared_cbm_textio_functions.p8 +++ b/compiler/res/prog8lib/shared_cbm_textio_functions.p8 @@ -4,15 +4,15 @@ txt { %option merge, no_symbol_prefixing, ignore_unused asmsub print (str text @ AY) clobbers(A,Y) { - ; ---- print null terminated string, in PETSCII encoding, from A/Y + ; ---- print zero terminated string, in PETSCII encoding, from A/Y ; note: the compiler contains an optimization that will replace ; a call to this subroutine with a string argument of just one char, ; by just one call to cbm.CHROUT of that single char. %asm {{ - sta P8ZP_SCRATCH_B1 - sty P8ZP_SCRATCH_REG + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 ldy #0 -- lda (P8ZP_SCRATCH_B1),y +- lda (P8ZP_SCRATCH_W2),y beq + jsr cbm.CHROUT iny diff --git a/compiler/res/prog8lib/virtual/textio.p8 b/compiler/res/prog8lib/virtual/textio.p8 index f7148d3b9..650e594bf 100644 --- a/compiler/res/prog8lib/virtual/textio.p8 +++ b/compiler/res/prog8lib/virtual/textio.p8 @@ -28,6 +28,10 @@ sub clear_screen() { }} } +sub cls() { + clear_screen() +} + sub nl() { chrout('\n') } diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index 5bdf9902c..31fb06fa6 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -115,6 +115,7 @@ class TestCompilerOnExamplesCx16: FunSpec({ "bdmusic", "bobs", "bubbleuniverse", + "charsets", "circles", "cobramk3-gfx", "colorbars", diff --git a/compiler/test/TestStringEncodings.kt b/compiler/test/TestStringEncodings.kt index e8b12606d..8a2e31610 100644 --- a/compiler/test/TestStringEncodings.kt +++ b/compiler/test/TestStringEncodings.kt @@ -16,9 +16,9 @@ import prog8.code.core.unescape import prog8.code.target.C64Target import prog8.code.target.Cx16Target import prog8.code.target.Encoder -import prog8.code.target.cbm.AtasciiEncoding -import prog8.code.target.cbm.IsoEncoding -import prog8.code.target.cbm.PetsciiEncoding +import prog8.code.target.encodings.AtasciiEncoding +import prog8.code.target.encodings.IsoEncoding +import prog8.code.target.encodings.PetsciiEncoding import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.compileText diff --git a/compiler/test/ast/TestProg8Parser.kt b/compiler/test/ast/TestProg8Parser.kt index 3b6e84138..0cb903578 100644 --- a/compiler/test/ast/TestProg8Parser.kt +++ b/compiler/test/ast/TestProg8Parser.kt @@ -20,7 +20,7 @@ import prog8.ast.statements.* import prog8.code.core.* import prog8.code.target.C64Target import prog8.code.target.VMTarget -import prog8.code.target.cbm.PetsciiEncoding +import prog8.code.target.encodings.PetsciiEncoding import prog8.parser.ParseError import prog8.parser.Prog8Parser.parseModule import prog8tests.helpers.* diff --git a/docs/source/compiling.rst b/docs/source/compiling.rst index 53ac561c9..d89922c95 100644 --- a/docs/source/compiling.rst +++ b/docs/source/compiling.rst @@ -371,13 +371,14 @@ dedicated to Prog8. Other than that, use the issue tracker on github. Examples -------- -A couple of example programs can be found in the 'examples' directory of the source tree. -Make sure you have installed the :ref:`requirements`. Then, for instance, -to compile and run the Commodore 64 rasterbars example program, use this command:: +A bunch of example programs can be found in the 'examples' directory of the source tree. +There are cross-platform examples that can be compiled for various systems unaltered, +and there are also examples specific to certain computers (C64, X16, etcetera). +So for instance, to compile and run the Commodore 64 rasterbars example program, use this command:: - $ java -jar prog8compiler.jar -target c64 -emu examples/rasterbars.p8 + $ java -jar prog8compiler.jar -target c64 -emu examples/c64/rasterbars.p8 or:: - $ /path/to/p8compile -target c64 -emu examples/rasterbars.p8 + $ /path/to/p8compile -target c64 -emu examples/c64/rasterbars.p8 diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index ac75cc75b..63cfc747b 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -542,13 +542,16 @@ A string literal can occur with or without an encoding prefix (encoding followed When this is omitted, the string is stored in the machine's default character encoding (which is PETSCII on the CBM machines). You can choose to store the string in other encodings such as ``sc`` (screencodes) or ``iso`` (iso-8859-15). String length is limited to 255 characters. -Here are several examples: +Here are examples of the various encodings: - ``"hello"`` a string translated into the default character encoding (PETSCII on the CBM machines) - ``petscii:"hello"`` string in CBM PETSCII encoding - ``sc:"my name is Alice"`` string in CBM screencode encoding - - ``iso:"Ich heiße François"`` string in iso-8859-15 encoding + - ``iso:"Ich heiße François"`` string in iso-8859-15 encoding (Latin) + - ``iso5:"Хозяин и Работник"`` string in iso-8859-5 encoding (Cyrillic) + - ``iso16:"zażółć gęślą jaźń"`` string in iso-8859-16 encoding (Eastern Europe) - ``atascii:"I am Atari!"`` string in "atascii" encoding (Atari 8-bit) + - ``cp437:"≈ IBM Pc ≈ ♂♀♪☺¶"`` string in "cp437" encoding (IBM PC codepage 437) There are several escape sequences available to put special characters into your string value: diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 0c203eb06..977d6f842 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,14 @@ TODO ==== +change meaning of sprite module's palette offset parameter to 0-15 + +fix routines such as mult in verafx to return both 16-bit words of the result. + +ubyte x,y compiles to more code than ubyte x + ubyte y + +can we make ubyte x,y = cbm.SCREEN() work? + ... diff --git a/examples/cx16/charsets.p8 b/examples/cx16/charsets.p8 new file mode 100644 index 000000000..893204233 --- /dev/null +++ b/examples/cx16/charsets.p8 @@ -0,0 +1,65 @@ +%import textio +%zeropage basicsafe + +main { + str buf = "?" * 20 + + sub start() { + txt.print("a demonstration of the various non-petscii character sets in the x16.") + wait() + latin() + wait() + cyrillic() + wait() + eastern() + wait() + ibmpc() + } + + sub latin() { + txt.iso() + repeat 3 txt.nl() + write_screencodes(iso:"Latin: Le garçon n'a pas acheté d'œuf.") + txt.print(iso:"Latin: Le garçon n'a pas acheté d'œuf.") + } + + sub cyrillic() { + txt.iso5() + repeat 3 txt.nl() + write_screencodes(iso5:"Cyrillic: 'Хозяин и Работник' написана Лев Толстой.") + txt.print(iso5:"Cyrillic: 'Хозяин и Работник' написана Лев Толстой.") + } + + sub eastern() { + txt.iso16() + repeat 3 txt.nl() + write_screencodes(iso16:"Eastern European: zażółć gęślą jaźń") + txt.print(iso16:"Eastern European: zażółć gęślą jaźń") + } + + sub ibmpc() { + txt.color2(5,0) + void cx16.screen_mode(1,false) + txt.cp437() + repeat 3 txt.nl() + write_screencodes(cp437:"≈ IBM Pc ≈ ÇüéâäàåçêëèïîìÄ ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ ☺☻♥♦♣♠•◘○◙♂♀♪♫☼ ►◄↕‼¶§▬↨↑↓→←∟↔▲▼") + ; regular print() won't work because of control codes (<32) in this one. + txt.print_lit(cp437:"≈ IBM Pc ≈ ÇüéâäàåçêëèïîìÄ ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐ ☺☻♥♦♣♠•◘○◙♂♀♪♫☼ ►◄↕‼¶§▬↨↑↓→←∟↔▲▼") + txt.nl() + } + + sub wait() { + txt.print("\n\npress enter: ") + void txt.input_chars(buf) + } + + sub write_screencodes(str message) { + ubyte column=0 + repeat { + if message[column]==0 + return + txt.setchr(column, 1, message[column]) + column++ + } + } +} diff --git a/syntax-files/IDEA/Prog8.xml b/syntax-files/IDEA/Prog8.xml index f0acf5a1e..75d88784b 100644 --- a/syntax-files/IDEA/Prog8.xml +++ b/syntax-files/IDEA/Prog8.xml @@ -12,7 +12,7 @@