diff --git a/docs/Makefile b/docs/Makefile
index ed44760bd..af05adf85 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -22,6 +22,7 @@ symboldumps:
prog8c -target c128 import-all-c128.p8 -dumpsymbols > source/_static/symboldumps/skeletons-c128.txt
prog8c -target cx16 import-all-cx16.p8 -dumpsymbols > source/_static/symboldumps/skeletons-cx16.txt
prog8c -target pet32 import-all-pet32.p8 -dumpsymbols > source/_static/symboldumps/skeletons-pet32.txt
+ prog8c -target neo import-all-neo.p8 -dumpsymbols > source/_static/symboldumps/skeletons-neo.txt
prog8c -target virtual import-all-virtual.p8 -dumpsymbols > source/_static/symboldumps/skeletons-virtual.txt
diff --git a/docs/source/_static/symboldumps/skeletons-neo.txt b/docs/source/_static/symboldumps/skeletons-neo.txt
new file mode 100644
index 000000000..61d538d3c
--- /dev/null
+++ b/docs/source/_static/symboldumps/skeletons-neo.txt
@@ -0,0 +1,323 @@
+
+Prog8 compiler v10.5-SNAPSHOT by Irmen de Jong (irmen@razorvine.net)
+Prerelease version from git commit 7d4dc3c0 in branch master
+This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html
+
+Compiling program import-all-neo.p8
+Compiler target: neo
+
+
+LIBRARY MODULE NAME: anyall
+---------------------------
+
+anyall {
+ all (uword arrayptr, uword num_elements) -> bool
+ allw (uword arrayptr, uword num_elements) -> bool
+ any (uword arrayptr, uword num_elements) -> bool
+ anyw (uword arrayptr, uword num_elements) -> bool
+}
+
+
+LIBRARY MODULE NAME: buffers
+----------------------------
+
+smallringbuffer {
+ ubyte[] buffer
+ ubyte fill
+ ubyte head
+ ubyte tail
+ get () -> ubyte
+ getw () -> uword
+ init ()
+ put (ubyte value) -> bool
+ putw (uword value) -> bool
+}
+
+ringbuffer {
+ uword buffer_ptr
+ uword fill
+ uword head
+ uword tail
+ get () -> ubyte
+ getw () -> uword
+ inc_head ()
+ inc_tail ()
+ init ()
+ put (ubyte value) -> bool
+ putw (uword value) -> bool
+}
+
+
+LIBRARY MODULE NAME: compression
+--------------------------------
+
+compression {
+ decode_rle (uword compressed @AY, uword target @R0, uword maxsize @R1) -> clobbers (X) -> uword @AY
+ decode_rle_srcfunc (uword source_function @AY, uword target @R0, uword maxsize @R1) -> clobbers (X) -> uword @AY
+ encode_rle (uword data, uword size, uword target, bool is_last_block) -> uword
+ encode_rle_outfunc (uword data, uword size, uword output_function, bool is_last_block)
+}
+
+
+LIBRARY MODULE NAME: conv
+-------------------------
+
+conv {
+ str @shared string_out
+ any2uword (str string @AY) -> clobbers (Y) -> ubyte @A
+ bin2uword (str string @AY) -> uword @AY
+ hex2uword (str string @AY) -> uword @AY
+ internal_byte2decimal (byte value @A) -> ubyte @Y, ubyte @A, ubyte @X
+ internal_ubyte2decimal (ubyte value @A) -> ubyte @Y, ubyte @X, ubyte @A
+ internal_ubyte2hex (ubyte value @A) -> clobbers (X) -> ubyte @A, ubyte @Y
+ internal_uword2decimal (uword value @AY) -> ubyte @Y, ubyte @A, ubyte @X
+ internal_uword2hex (uword value @AY) -> clobbers (A,Y)
+ str2byte (str string @AY) -> clobbers (Y) -> byte @A
+ str2ubyte (str string @AY) -> clobbers (Y) -> ubyte @A
+ str2uword (str string @AY) -> uword @AY
+ str2word (str string @AY) -> word @AY
+ str_b (byte value @A) -> clobbers (X) -> str @AY
+ str_ub (ubyte value @A) -> clobbers (X) -> str @AY
+ str_ub0 (ubyte value @A) -> clobbers (X) -> str @AY
+ str_ubbin (ubyte value @A) -> clobbers (X) -> str @AY
+ str_ubhex (ubyte value @A) -> clobbers (X) -> str @AY
+ str_uw (uword value @AY) -> clobbers (X) -> str @AY
+ str_uw0 (uword value @AY) -> clobbers (X) -> str @AY
+ str_uwbin (uword value @AY) -> clobbers (X) -> str @AY
+ str_uwhex (uword value @AY) -> str @AY
+ str_w (word value @AY) -> clobbers (X) -> str @AY
+}
+
+
+LIBRARY MODULE NAME: math
+-------------------------
+
+math {
+ atan2 (ubyte x1 @R0, ubyte y1 @R1, ubyte x2 @R2, ubyte y2 @R3) -> ubyte @A
+ cos8 (ubyte angle @A) -> clobbers (Y) -> byte @A
+ cos8u (ubyte angle @A) -> clobbers (Y) -> ubyte @A
+ cosr8 (ubyte radians @A) -> clobbers (Y) -> byte @A
+ cosr8u (ubyte radians @A) -> clobbers (Y) -> ubyte @A
+ crc16 (uword data, uword length) -> uword
+ crc16_end () -> uword
+ crc16_start ()
+ crc16_update (ubyte value @A)
+ crc32 (uword data, uword length)
+ crc32_end ()
+ crc32_start ()
+ crc32_update (ubyte value @A)
+ diff (ubyte v1 @A, ubyte v2 @Y) -> ubyte @A
+ diffw (uword w1 @R0, uword w2 @AY) -> uword @AY
+ direction (ubyte x1, ubyte y1, ubyte x2, ubyte y2) -> ubyte
+ direction_qd (ubyte quadrant @A, ubyte xdelta @X, ubyte ydelta @Y) -> ubyte @A
+ direction_sc (byte x1, byte y1, byte x2, byte y2) -> ubyte
+ lerp (ubyte v0, ubyte v1, ubyte t) -> ubyte
+ log2 (ubyte value @A) -> ubyte @Y
+ log2w (uword value @AY) -> ubyte @Y
+ mul16_last_upper () -> uword @AY
+ randrange (ubyte n) -> ubyte
+ randrangew (uword n) -> uword
+ rnd () -> clobbers (Y) -> ubyte @A
+ rndseed (uword seed1 @AY, uword seed2 @R0) -> clobbers (A,Y)
+ rndw () -> uword @AY
+ sin8 (ubyte angle @A) -> clobbers (Y) -> byte @A
+ sin8u (ubyte angle @A) -> clobbers (Y) -> ubyte @A
+ sinr8 (ubyte radians @A) -> clobbers (Y) -> byte @A
+ sinr8u (ubyte radians @A) -> clobbers (Y) -> ubyte @A
+}
+
+
+LIBRARY MODULE NAME: string
+---------------------------
+
+string {
+ append (uword target @R0, uword suffix @R1) -> clobbers (Y) -> ubyte @A
+ compare (uword string1 @R0, uword string2 @AY) -> clobbers (Y) -> byte @A
+ contains (uword string @AY, ubyte character @X) -> bool @Pc
+ copy (uword source @R0, uword target @AY) -> clobbers (A) -> ubyte @Y
+ endswith (str st, str suffix) -> bool
+ find (uword string @AY, ubyte character @X) -> ubyte @A, bool @Pc
+ findstr (str haystack, str needle) -> ubyte
+ hash (str string @R0) -> ubyte @A
+ isdigit (ubyte petsciichar @A) -> bool @Pc
+ isletter (ubyte petsciichar @A) -> bool @Pc
+ islower (ubyte petsciichar @A) -> bool @Pc
+ isprint (ubyte petsciichar @A) -> bool @Pc
+ isspace (ubyte petsciichar @A) -> bool @Pc
+ isupper (ubyte petsciichar @A) -> bool @Pc
+ left (uword source @AX, ubyte length @Y, uword target @R1) -> clobbers (A,Y)
+ length (uword string @AY) -> clobbers (A) -> ubyte @Y
+ lower (uword st @AY) -> ubyte @Y
+ lowerchar (ubyte character @A) -> ubyte @A
+ lstrip (str s)
+ lstripped (str s) -> str
+ ltrim (str s)
+ ltrimmed (str s) -> str
+ pattern_match (str string @AY, str pattern @R0) -> clobbers (Y) -> bool @A
+ rfind (uword string @AY, ubyte character @X) -> ubyte @A, bool @Pc
+ right (uword source @AY, ubyte length @X, uword target @R1) -> clobbers (A,Y)
+ rstrip (str s)
+ rtrim (str s)
+ slice (uword source @R0, ubyte start @A, ubyte length @Y, uword target @R1) -> clobbers (A,Y)
+ startswith (str st, str prefix) -> bool
+ strip (str s)
+ trim (str s)
+ upper (uword st @AY) -> ubyte @Y
+ upperchar (ubyte character @A) -> ubyte @A
+}
+
+
+LIBRARY MODULE NAME: syslib
+---------------------------
+
+neo {
+ &uword IRQ_VEC
+ &uword NMI_VEC
+ &uword RESET_VEC
+}
+
+sys {
+ const ubyte sizeof_bool
+ const ubyte sizeof_byte
+ const ubyte sizeof_float
+ const ubyte sizeof_ubyte
+ const ubyte sizeof_uword
+ const ubyte sizeof_word
+ const ubyte target
+ clear_carry ()
+ clear_irqd ()
+ disable_caseswitch ()
+ enable_caseswitch ()
+ exit (ubyte returnvalue @A)
+ exit2 (ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y)
+ exit3 (ubyte resulta @A, ubyte resultx @X, ubyte resulty @Y, bool carry @Pc)
+ internal_stringcopy (uword source @R0, uword target @AY) -> clobbers (A,Y)
+ irqsafe_clear_irqd ()
+ irqsafe_set_irqd ()
+ memcopy (uword source @R0, uword target @R1, uword count @AY) -> clobbers (A,X,Y)
+ memset (uword mem @R0, uword numbytes @R1, ubyte value @A) -> clobbers (A,X,Y)
+ memsetw (uword mem @R0, uword numwords @R1, uword value @AY) -> clobbers (A,X,Y)
+ pop () -> ubyte @A
+ popw () -> uword @AY
+ progend () -> uword @AY
+ push (ubyte value @A)
+ pushw (uword value @AY)
+ read_flags () -> ubyte @A
+ reset_system ()
+ restore_prog8_internals ()
+ save_prog8_internals ()
+ set_carry ()
+ set_irqd ()
+ wait (uword jiffies)
+ waitvsync () -> clobbers (A)
+}
+
+cx16 {
+ &uword r0
+ &ubyte r0H
+ &ubyte r0L
+ &word r0s
+ &byte r0sH
+ &byte r0sL
+ &uword r1
+ &uword r10
+ &ubyte r10H
+ &ubyte r10L
+ &word r10s
+ &byte r10sH
+ &byte r10sL
+ &uword r11
+ &ubyte r11H
+ &ubyte r11L
+ &word r11s
+ &byte r11sH
+ &byte r11sL
+ &uword r12
+ &ubyte r12H
+ &ubyte r12L
+ &word r12s
+ &byte r12sH
+ &byte r12sL
+ &uword r13
+ &ubyte r13H
+ &ubyte r13L
+ &word r13s
+ &byte r13sH
+ &byte r13sL
+ &uword r14
+ &ubyte r14H
+ &ubyte r14L
+ &word r14s
+ &byte r14sH
+ &byte r14sL
+ &uword r15
+ &ubyte r15H
+ &ubyte r15L
+ &word r15s
+ &byte r15sH
+ &byte r15sL
+ &ubyte r1H
+ &ubyte r1L
+ &word r1s
+ &byte r1sH
+ &byte r1sL
+ &uword r2
+ &ubyte r2H
+ &ubyte r2L
+ &word r2s
+ &byte r2sH
+ &byte r2sL
+ &uword r3
+ &ubyte r3H
+ &ubyte r3L
+ &word r3s
+ &byte r3sH
+ &byte r3sL
+ &uword r4
+ &ubyte r4H
+ &ubyte r4L
+ &word r4s
+ &byte r4sH
+ &byte r4sL
+ &uword r5
+ &ubyte r5H
+ &ubyte r5L
+ &word r5s
+ &byte r5sH
+ &byte r5sL
+ &uword r6
+ &ubyte r6H
+ &ubyte r6L
+ &word r6s
+ &byte r6sH
+ &byte r6sL
+ &uword r7
+ &ubyte r7H
+ &ubyte r7L
+ &word r7s
+ &byte r7sH
+ &byte r7sL
+ &uword r8
+ &ubyte r8H
+ &ubyte r8L
+ &word r8s
+ &byte r8sH
+ &byte r8sL
+ &uword r9
+ &ubyte r9H
+ &ubyte r9L
+ &word r9s
+ &byte r9sH
+ &byte r9sL
+ cpu_is_65816 () -> bool
+ restore_virtual_registers () -> clobbers (A,Y)
+ save_virtual_registers () -> clobbers (A,Y)
+}
+
+p8_sys_startup {
+ cleanup_at_exit ()
+ init_system ()
+ init_system_phase2 ()
+}
+
+
diff --git a/docs/source/targetsystem.rst b/docs/source/targetsystem.rst
index 88cadc944..b35fca52a 100644
--- a/docs/source/targetsystem.rst
+++ b/docs/source/targetsystem.rst
@@ -15,7 +15,7 @@ Currently these machines can be selected as a compilation target (via the ``-tar
- 'cx16': the `Commander X16 `_
- 'c128': the Commodore 128 (*limited support*)
- 'pet32': the Commodore PET 4032 (*limited support*)
-- 'atari': the Atari 800 XL (*experimental support*)
+- 'atari': the Atari 800 XL (*experimental*)
- 'neo': the `Neo6502 `_ (*experimental*)
- 'virtual': a builtin virtual machine
diff --git a/examples/neo/hello.p8 b/examples/neo/hello.p8
new file mode 100644
index 000000000..b52f77b32
--- /dev/null
+++ b/examples/neo/hello.p8
@@ -0,0 +1,118 @@
+%output raw
+%launcher none
+
+main {
+ sub start() {
+ 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
+
+
+ }}
+ }
+}