]> git.sur5r.net Git - cc65/commitdiff
Added a second OSI C1P program file format.
authorGreg King <gregdk@users.sf.net>
Sat, 7 Mar 2015 21:37:58 +0000 (16:37 -0500)
committerGreg King <gregdk@users.sf.net>
Sat, 7 Mar 2015 21:39:44 +0000 (16:39 -0500)
Unlike the first format, the new format is already loadable; it doesn't need to be converted.

cfg/osic1p-asm.cfg
cfg/osic1p.cfg
doc/intro.sgml
doc/osi.sgml
libsrc/osic1p/bootstrap.s [new file with mode: 0644]

index d37f17f88cdcb5d52110ac40472d6f27f746847c..d9f128f8aaf77bad72b02cc61926b81a4271c643 100644 (file)
@@ -2,19 +2,23 @@ FEATURES {
     STARTADDRESS: default = $0200;
 }
 SYMBOLS {
     STARTADDRESS: default = $0200;
 }
 SYMBOLS {
+# Add "-u __BOOT__" to a command line if you want a file that can be loaded directly.
+#    __BOOT__:      type = import;
     __STACKSIZE__: type = weak, value = $0400; # 1 kB stack
     __HIMEM__:     type = weak, value = $8000; # 32 kB RAM
 }
 MEMORY {
     __STACKSIZE__: type = weak, value = $0400; # 1 kB stack
     __HIMEM__:     type = weak, value = $8000; # 32 kB RAM
 }
 MEMORY {
-    # for size of ZP see runtime/zeropage.s and c1p/extzp.s
+    # for size of ZP, see runtime/zeropage.s and c1p/extzp.s
     ZP:       file = "", define = yes, start = $0002, size = $001A + $0006;
     ZP:       file = "", define = yes, start = $0002, size = $001A + $0006;
+    HEAD:     file = %O,               start = $0000, size = $00AA;
     RAM:      file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S;
 }
 SEGMENTS {
     RAM:      file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S;
 }
 SEGMENTS {
-    INIT:     load = RAM, type = ro,  define = yes, optional = yes;
-    CODE:     load = RAM, type = rw;
-    RODATA:   load = RAM, type = rw;
-    DATA:     load = RAM, type = rw;
-    BSS:      load = RAM, type = bss, define = yes;
-    ZEROPAGE: load = ZP,  type = zp;
+    BOOT:     load = HEAD, type = ro,                optional = yes;
+    INIT:     load = RAM,  type = ro,  define = yes, optional = yes;
+    CODE:     load = RAM,  type = rw;
+    RODATA:   load = RAM,  type = rw;
+    DATA:     load = RAM,  type = rw;
+    BSS:      load = RAM,  type = bss, define = yes;
+    ZEROPAGE: load = ZP,   type = zp;
 }
 }
index 4771639a63e00ce29862c2c1575629d8d68b684c..0ad2f893968549f315afacedc788194b35eadb32 100644 (file)
@@ -2,24 +2,28 @@ FEATURES {
     STARTADDRESS: default = $0200;
 }
 SYMBOLS {
     STARTADDRESS: default = $0200;
 }
 SYMBOLS {
+# Add "-u __BOOT__" to a command line if you want a file that can be loaded directly.
+#    __BOOT__:      type = import;
     __STACKSIZE__: type = weak, value = $0400; # 1 kB stack
     __HIMEM__:     type = weak, value = $8000; # 32 kB RAM
 }
 MEMORY {
     __STACKSIZE__: type = weak, value = $0400; # 1 kB stack
     __HIMEM__:     type = weak, value = $8000; # 32 kB RAM
 }
 MEMORY {
-    # for size of ZP see runtime/zeropage.s and c1p/extzp.s
-    ZP:       file = "", define = yes, start = $0002, size = $001A + $0005;
+    # for size of ZP, see runtime/zeropage.s and c1p/extzp.s
+    ZP:       file = "", define = yes, start = $0002, size = $001A + $0006;
+    HEAD:     file = %O,               start = $0000, size = $00AA;
     RAM:      file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S;
 }
 SEGMENTS {
     RAM:      file = %O, define = yes, start = %S, size = __HIMEM__ - __STACKSIZE__ - %S;
 }
 SEGMENTS {
-    STARTUP:  load = RAM, type = ro;
-    LOWCODE:  load = RAM, type = ro,                optional = yes;
-    INIT:     load = RAM, type = ro,  define = yes, optional = yes;
-    CODE:     load = RAM, type = rw;
-    RODATA:   load = RAM, type = rw;
-    DATA:     load = RAM, type = rw;
-    BSS:      load = RAM, type = bss, define = yes;
-    ZEROPAGE: load = ZP,  type = zp;
-    EXTZP:    load = ZP,  type = rw,  define = yes;
+    BOOT:     load = HEAD, type = ro,                optional = yes;
+    STARTUP:  load = RAM,  type = ro;
+    LOWCODE:  load = RAM,  type = ro,                optional = yes;
+    INIT:     load = RAM,  type = ro,  define = yes, optional = yes;
+    CODE:     load = RAM,  type = rw;
+    RODATA:   load = RAM,  type = rw;
+    DATA:     load = RAM,  type = rw;
+    BSS:      load = RAM,  type = bss, define = yes;
+    ZEROPAGE: load = ZP,   type = zp;
+    EXTZP:    load = ZP,   type = zp,  define = yes, optional = yes;
 }
 FEATURES {
     CONDES: type    = constructor,
 }
 FEATURES {
     CONDES: type    = constructor,
index 10693aa4a769590f55ad69e56cade7af559d6618..d92fd1d20f2216d48338a9137a0a93c2a4e4b07d 100644 (file)
@@ -6,8 +6,9 @@
 <author>
 <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
 <url url="mailto:cbmnut@hushmail.com" name="CbmNut">,<newline>
 <author>
 <url url="mailto:uz@cc65.org" name="Ullrich von Bassewitz">,<newline>
 <url url="mailto:cbmnut@hushmail.com" name="CbmNut">,<newline>
-<url url="mailto:greg.king5@verizon.net" name="Greg King">
-<date>2015-2-27
+<url url="mailto:greg.king5@verizon.net" name="Greg King">,<newline>
+<url url="mailto:stephan.muehlstrasser@web.de" name="Stephan M&uuml;hlstrasser">
+<date>2015-03-07
 
 <abstract>
 How to use the cc65 C language system -- an introduction.
 
 <abstract>
 How to use the cc65 C language system -- an introduction.
@@ -520,28 +521,18 @@ directory notePad.  Look at the eight file-positions on each page until you see
 The output is shown in a GEOS dialog box; click <bf/OK/ when you have finished
 reading it.
 
 The output is shown in a GEOS dialog box; click <bf/OK/ when you have finished
 reading it.
 
-<sect1>Ohio Scientific Challenger 1P<p>
-Available at <url url="http://www.pcjs.org/docs/c1pjs/" name="C1Pjs">:
-
-Emulates the Ohio Scientific Challenger 1P computer in different configurations.
-The 32 kb RAM machine that must be used with the default compiler settings is
-<url url="http://www.pcjs.org/devices/c1p/machine/32kb/" name="here">.
-
-In addition to cc65 the srec_cat program from the
-<url url="http://srecord.sourceforge.net/" name="SRecord">
-tool collection must be installed. Some Linux distributions also provide the
-srecord package directly as an installable package.
 
 
-The osic1p runtime library returns to the boot prompt when the
-main() program exits. Therefore the C file in the tutorial must be slightly
-modified in order to see the results on the screen. Otherwise the program
-would print the text string and then jump to the boot prompt, making it
+<sect1>Ohio Scientific Challenger 1P<p>
+The <tt/osic1p/ runtime library returns to the boot prompt when the main()
+program exits. Therefore, the C file in the tutorial must be modified
+slightly, in order to see the results on the screen. Otherwise, the program
+would print the text string, and then jump to the boot prompt, making it
 impossible to see the results of running the tutorial program.
 
 impossible to see the results of running the tutorial program.
 
-In addition to that the osic1p target does not yet have support for stdio
+In addition to that, the <tt/osic1p/ target does not yet have support for stdio
 functions. Only the functions from the conio library are available.
 
 functions. Only the functions from the conio library are available.
 
-Therefore modify the hello.c source file as follows:
+Therefore, modify the "<tt/hello.c/" source file, as follows:
 
 <tscreen><code>
 #include <conio.h>
 
 <tscreen><code>
 #include <conio.h>
@@ -552,7 +543,7 @@ extern const char text[];       /* In text.s */
 int main (void)
 {
     clrscr ();
 int main (void)
 {
     clrscr ();
-    cprintf ("%s\r\nPress <RETURN>\r\n", text);
+    cprintf ("%s\r\nPress <RETURN>.\r\n", text);
     cgetc ();
     return EXIT_SUCCESS;
 }
     cgetc ();
     return EXIT_SUCCESS;
 }
@@ -560,35 +551,97 @@ int main (void)
 
 Compile the tutorial with
 
 
 Compile the tutorial with
 
+<tscreen><verb>
+cl65 -O -t osic1p -u __BOOT__ -o hello.lod hello.c text.s
+</verb></tscreen>
+
+The program is configured for a Challenger 1P computer with, at least, 32 kB
+of RAM. See the <url url="osi.html"
+name="Ohio Scientifc-specific documentation"> for instructions about how to
+compile for other RAM sizes.
+
+Plug a cassette player into your C1P computer; or, connect an RS-232 cable
+between your C1P and a PC (set the PC's serial port to 300 Bits Per Second,
+8 data bits, No parity, and 2 stop bits).  (Turn on the computers.)
+
+Tap the "<bf/BREAK/" key, to display the boot prompt; then, tap the "<tt/M/"
+key, to enter the 65V PROM monitor. Tap the "<tt/L/" key. Either start the
+cassette player (with a tape of the program), or start a transfer of the
+program file "<tt/hello.lod/" from the PC. After a while, you should see the
+following text on the screen:
+
+<tscreen><verb>
+Hello world!
+Press <RETURN>.
+</verb></tscreen>
+
+(Stop the cassette player.) After hitting the RETURN key, you should see the
+boot prompt again.
+
+<sect2>WinOSI<p>
+Available at <url
+url="http://osi.marks-lab.com/#Emulator">:
+
+Emulates the Ohio Scientific Challenger computers in different configurations.
+Configure it to emulate a C1P (model 600 board) with 32 kB of RAM.
+
+Compile the tutorial with the same command that is used to make the program
+for a real machine.
+
+Start the emulator. Tap the "<tt/M/" key, to enter the 65V PROM monitor; then,
+tap the "<tt/L/" key. If you had configured WinOSI to ask for a file when it
+starts to read data from the serial port, then you will see a file dialog box;
+otherwise, you must tap your host keyboard's F10 function key. Select the file
+"<tt/hello.lod/". After a moment, you should see the following text on the
+screen:
+
+<tscreen><verb>
+Hello world!
+Press <RETURN>.
+</verb></tscreen>
+
+After hitting the RETURN key, you should see the boot prompt again.
+
+<sect2>C1Pjs<p>
+Available at <url
+url="http://www.pcjs.org/docs/c1pjs/">:
+
+Emulates the Ohio Scientific Challenger 1P computer in different configurations.
+The 32 kB RAM machine that must be used with the default compiler settings is
+<url url="http://www.pcjs.org/devices/c1p/machine/32kb/" name="here">.
+
+In addition to cc65, the <bf/srec_cat/ program from <url
+url="http://srecord.sourceforge.net/" name="the SRecord tool collection">
+must be installed. Some Linux distributions also provide srecord directly as
+an installable package.
+
+Compile the tutorial with this command line:
+
 <tscreen><verb>
 cl65 -O -t osic1p hello.c text.s
 </verb></tscreen>
 
 <tscreen><verb>
 cl65 -O -t osic1p hello.c text.s
 </verb></tscreen>
 
-Convert the executable file into a text file that can be loaded via
-the Ohio Scientific 65V PROM monitor at start address 0x200:
+Convert the binary file into a text file that can be loaded via
+the Ohio Scientific 65V PROM monitor, at start address 0x200:
 
 <tscreen><verb>
 srec_cat hello -binary -offset 0x200 -o hello.c1p -Ohio_Scientific -execution-start-address=0x200
 </verb></tscreen>
 
 
 <tscreen><verb>
 srec_cat hello -binary -offset 0x200 -o hello.c1p -Ohio_Scientific -execution-start-address=0x200
 </verb></tscreen>
 
-Open the URL <url url="http://www.pcjs.org/devices/c1p/machine/32kb/" name="http://www.pcjs.org/devices/c1p/machine/32kb/">
-and wait until the emulator has been loaded. Click on the "BREAK"
-button to display the boot prompt, then press the "M" key to enter the
-65V PROM monitor. Click the "Choose File" button and select the file "hello.c1p"
-that was created as the output of the above invocation of the "srec_cat"
-command. Press the "Load" button. You should see the following text on the
-screen:
+Open the URL that points to the 32 kB machine; and, wait until the emulator
+has been loaded. Click on the "<bf/BREAK/" button to display the boot prompt;
+then, press the "<tt/M/" key to enter the 65V PROM monitor. Click the
+"<bf/Browse.../" button; and, select the file "<tt/hello.c1p/" that was
+created as the output of the above invocation of the "<tt/srec_cat/" command.
+Press the "<bf/Load/" button. You should see the following text on the screen:
 
 <tscreen><verb>
 Hello world!
 
 <tscreen><verb>
 Hello world!
-Press <RETURN>
+Press <RETURN>.
 </verb></tscreen>
 
 </verb></tscreen>
 
-After hitting the RETURN key you should see the boot prompt again.
+After hitting the RETURN key, you should see the boot prompt again.
 
 
-The program can also be uploaded over the serial port to a real Challenger 1P
-computer with 32 kB RAM. See the <url url="osi.html" name="Ohio Scientifc-specific documentation"> for instructions how to
-compile for other RAM sizes.
 
 <sect1>Contributions wanted<p>
 
 
 <sect1>Contributions wanted<p>
 
index e360daf7afdc458748bbf53cbf9659b1f7b171e0..0167b2bd1ba5537c9e5a30444e0b1af414cc8ff2 100644 (file)
@@ -4,8 +4,9 @@
 
 <title>Ohio Scientific-specific information for cc65
 <author>
 
 <title>Ohio Scientific-specific information for cc65
 <author>
-<url url="mailto:stephan.muehlstrasser@web.de" name="Stephan M&uuml;hlstrasser"><newline>
-<date>2015-02-04
+<url url="mailto:stephan.muehlstrasser@web.de" name="Stephan M&uuml;hlstrasser">,<newline>
+<url url="mailto:greg.king5@verizon.net" name="Greg King">
+<date>2015-03-07
 
 <abstract>
 An overview over the Ohio Scientific runtime system as it is implemented for the cc65 C
 
 <abstract>
 An overview over the Ohio Scientific runtime system as it is implemented for the cc65 C
@@ -34,42 +35,63 @@ information.
 Currently the target "osic1p" is implemented. This works for the Ohio Scientific
 Challenger 1P machine.
 
 Currently the target "osic1p" is implemented. This works for the Ohio Scientific
 Challenger 1P machine.
 
-<sect>Binary format<p>
+<sect>Program file formats<p>
 
 
-The standard binary output format generated by the linker for the osic1p target
-is a machine language program.<p>
+<descrip>
+  <tag/Binary, then text/
+  The standard binary output format generated by the linker for the osic1p
+  target is a pure machine language program.
+
+  For uploading into a real machine over its serial port or into an emulator,
+  that program must be converted into a text file that can be understood by
+  the 65V PROM monitor. For that purpose, the <bf/srec_cat/ program from <url
+  url="http://srecord.sourceforge.net/" name="the SRecord tool collection">
+  can be used.
+
+  Care must be taken that the <tt/-offset/ and <tt/-execution-start-address/
+  options for the <bf/srec_cat/ program correspond to the start address
+  of the executable.
+
+  Example for converting an executable "hello" file that was built for the
+  default start address &dollar;0200 to an uploadable file "hello.c1p":
 
 
-For uploading into a real machine over the serial port or into an emulator a
-program must be converted to a text file that is understood by the 65V PROM
-monitor. For this purpose the srec_cat program from the
-<url url="http://srecord.sourceforge.net/" name="SRecord">
-tool collection can be used.
+  <tscreen><verb>
+  srec_cat hello -bin -of 0x200 -o hello.c1p -os -esa=0x200
+  </verb></tscreen>
 
 
-Care must be taken that the -offset and -execution-start-address options for the srec_cat
-program correspond to the start address of the executable.
+  <tag/Hybrid/
+  The linker can create an alternate format that contains two parts:
+  <enum>
+    <item>A text header that is understood by the 65V PROM monitor.
+          It is a boot loader that reads the second part.
+    <item>The default binary code that is described above.
+  </enum>
 
 
-Example for converting an executable "hello" that was built for the default
-start address &dollar;0200 to an uploadable file "hello.c1p":
+  You can make the alternate format by adding the option <tt/-u __BOOT__/ to
+  <tt/cl65/'s or <tt/ld65/'s command lines.
 
 
-<tscreen>
-srec_cat hello -binary -offset 0x200 -o hello.c1p -Ohio_Scientific -execution-start-address=0x200
-</tscreen>
+  This format doesn't need to be converted. It is smaller than the text-only
+  format.  But, it cannot be loaded by <url
+  url="http://www.pcjs.org/docs/c1pjs/" name="C1Pjs">; you must use the
+  SRecord-produced text-only format with that emulator.
+
+</descrip>
 
 <sect>Memory layout<p>
 
 By default programs compiled for the osic1p target are configured for 32 kB RAM.
 
 <sect>Memory layout<p>
 
 By default programs compiled for the osic1p target are configured for 32 kB RAM.
-The RAM size can be configured via the symbol __HIMEM__.
+The RAM size can be configured via the symbol <tt/__HIMEM__/.
 
 Special locations:
 
 <descrip>
   <tag/Program start address/
   The default start address is &dollar;0200. The start address is configurable
 
 Special locations:
 
 <descrip>
   <tag/Program start address/
   The default start address is &dollar;0200. The start address is configurable
-  via the compiler option --start-addr.
+  via the linker option <tt/--start-addr/.
 
   <tag/Stack/
   The C runtime stack is located at the top of RAM and growing downwards.
 
   <tag/Stack/
   The C runtime stack is located at the top of RAM and growing downwards.
-  The size is configurable via the symbol __STACKSIZE__. The default
+  The size is configurable via the symbol <tt/__STACKSIZE__/. The default
   stack size is &dollar;0400.
 
   <tag/Heap/
   stack size is &dollar;0400.
 
   <tag/Heap/
@@ -77,7 +99,7 @@ Special locations:
   runtime stack.
 
   <tag/Video RAM/
   runtime stack.
 
   <tag/Video RAM/
-  The 1 kB video RAM is located at &dollar;D000. On the monitor only a subset
+  The 1 kB video RAM is located at &dollar;D000. On the monitor, only a subset
   of the available video RAM is visible. The address of the upper left corner
   of the visible area is &dollar;D085 and corresponds to conio cursor
   position (0, 0).
   of the available video RAM is visible. The address of the upper left corner
   of the visible area is &dollar;D085 and corresponds to conio cursor
   position (0, 0).
@@ -87,9 +109,9 @@ Special locations:
 Example for building a program with start address &dollar;0300, stack size
 &dollar;0200 and RAM size &dollar;2000:
 
 Example for building a program with start address &dollar;0300, stack size
 &dollar;0200 and RAM size &dollar;2000:
 
-<tscreen>
+<tscreen><verb>
 cl65 --start-addr 0x300 -Wl -D,__HIMEM__=$2000,-D,__STACKSIZE__=$0200 -t osic1p hello.c
 cl65 --start-addr 0x300 -Wl -D,__HIMEM__=$2000,-D,__STACKSIZE__=$0200 -t osic1p hello.c
-</tscreen>
+</verb></tscreen>
 
 <sect>Linker configurations<p>
 
 
 <sect>Linker configurations<p>
 
@@ -112,16 +134,17 @@ To use this config file, assemble with <tt/-t osic1p/ and link with
 is used, while the latter supplies the actual config. When using <tt/cl65/,
 use both command line options.
 
 is used, while the latter supplies the actual config. When using <tt/cl65/,
 use both command line options.
 
-Sample command line for <tt/cl65/:
+Sample command lines for <tt/cl65/:
 
 <tscreen><verb>
 
 <tscreen><verb>
-cl65 -o program -t osic1p -C osic1p-asm.cfg source.s
+cl65 -t osic1p -C osic1p-asm.cfg -o program source.s
+cl65 -t osic1p -C osic1p-asm.cfg -u __BOOT__ -o program.lod source.s
 </verb></tscreen>
 
 <sect>Platform-specific header files<p>
 
 </verb></tscreen>
 
 <sect>Platform-specific header files<p>
 
-Programs containing Ohio Scientific-specific code may use the <tt/osic1p.h/ 
-header file. 
+Programs containing Ohio Scientific-specific code may use the <tt/osic1p.h/
+header file.
 
 <sect1>Ohio Scientific-specific functions<p>
 
 
 <sect1>Ohio Scientific-specific functions<p>
 
diff --git a/libsrc/osic1p/bootstrap.s b/libsrc/osic1p/bootstrap.s
new file mode 100644 (file)
index 0000000..298de8f
--- /dev/null
@@ -0,0 +1,138 @@
+;
+; 2015-03-06, Greg King
+;
+
+; When you want to create a program with the alternate file format,
+; add "-u __BOOT__" to the cl65/ld65 command line.  Then, the linker
+; will import this symbol name; and, link this module at the front
+; of your program file.
+;
+        .export         __BOOT__:abs = 1
+
+        .import         __RAM_START__, __RAM_SIZE__, __BSS_RUN__
+
+; ------------------------------------------------------------------------
+
+load_addr       :=      __RAM_START__
+load_size       =       __BSS_RUN__ - __RAM_START__
+ram_top         :=      __RAM_START__ + __RAM_SIZE__
+
+        .segment        "BOOT"
+
+.ifdef ASM
+
+        .include        "osic1p.inc"
+        .macpack        generic
+
+load            :=      $08             ; private variables
+count           :=      $0A
+
+GETCHAR         :=      $FFBF           ; gets one character from ACIA
+
+FIRSTVISC       =       $85             ; Offset of first visible character in video RAM
+LINEDIST        =       $20             ; Offset in video RAM between two lines
+
+        lda     #<load_addr
+        ldx     #>load_addr
+        tay
+        stx     load+1
+        lda     #<load_size
+        eor     #$FF
+        sta     count                   ; store (-size - 1)
+        lda     #>load_size
+        eor     #$FF
+        sta     count+1
+
+L1:     inc     count                   ; pre-count one's-complement upwards
+        bnz     L2
+        inc     count+1
+        bze     L3
+L2:     jsr     GETCHAR                 ; (doesn't change .Y)
+        sta     (load),y
+
+; Show that the file is being loaded by rotating an arrow on the screen.
+;
+        tya
+        lsr     a
+        lsr     a
+        and     #8 - 1
+        ora     #$10                    ; eight arrow characters
+        sta     SCRNBASE + FIRSTVISC + 2 * LINEDIST + 11
+
+        iny
+        bnz     L1
+        inc     load+1
+        bnz     L1                      ; branch always
+
+L3:     jmp     load_addr
+
+.else
+
+.mac    hex1    h
+        .lobytes        ((h) & $0F) + (((h) & $0F) > 9) * 7 + '0'
+.endmac
+
+.mac    hex2    h
+        hex1    (h) >> 4
+        hex1    (h) >> 0
+.endmac
+
+.mac    hex4    h
+        hex2    >(h)
+        hex2    <(h)
+.endmac
+
+CR      =       $0D
+
+        .byte   CR, CR
+        .byte   "."                     ; set an address
+        hex4    ram_top                 ; put loader where stack will sit
+        .byte   "/"                     ; write bytes into RAM
+
+; ASCII-coded hexadecimal translation of the above assembly code.
+; It was copied from the assembler listing.
+
+        .byte   "A9", CR
+        hex2    <load_addr
+        .byte   CR, "A2", CR
+        hex2    >load_addr
+        .byte   CR, "A8", CR
+        .byte   "86", CR, "09", CR
+        .byte   "A9", CR
+        hex2    <load_size
+        .byte   CR, "49", CR, "FF", CR
+        .byte   "85", CR, "0A", CR
+        .byte   "A9", CR
+        hex2    >load_size
+        .byte   CR, "49", CR, "FF", CR
+        .byte   "85", CR, "0B", CR
+
+        .byte   "E6", CR, "0A", CR
+        .byte   "D0", CR, "04", CR
+        .byte   "E6", CR, "0B", CR
+        .byte   "F0", CR, "16", CR
+        .byte   "20", CR, "BF", CR, "FF", CR
+        .byte   "91", CR, "08", CR
+
+        .byte   "98", CR
+        .byte   "4A", CR
+        .byte   "4A", CR
+        .byte   "29", CR, "07", CR
+        .byte   "09", CR, "10", CR
+        .byte   "8D", CR, "D0", CR, "D0", CR
+
+        .byte   "C8", CR
+        .byte   "D0", CR, "E6", CR
+        .byte   "E6", CR, "09", CR
+        .byte   "D0", CR, "E2", CR
+
+        .byte   "4C", CR
+        hex2    <load_addr
+        .byte   CR
+        hex2    >load_addr
+
+        .byte   CR, "."
+        hex4    ram_top
+        .byte   "G"                     ; go to address
+
+.endif