Final refinements to documentation and examples for 2.2

This commit is contained in:
Michael Martin 2024-07-28 00:05:06 -07:00
parent e69fe05fac
commit 228a423621
4 changed files with 119 additions and 65 deletions

Binary file not shown.

View File

@ -106,35 +106,25 @@
<section> <section>
<title>Getting a copy of Ophis</title> <title>Getting a copy of Ophis</title>
<para> <para>
As of this writing, the Ophis assembler is hosted at Github. The As of version 2.2, the Python Package Index offers Ophis
latest downloads and documentation will be available at <ulink url="https://pypi.org/manage/project/ophis-asm/"></ulink>.
This version may be installed on any system
where <literal>pip</literal> or <literal>pipx</literal> works.
</para>
<para>
Development is hosted at Github. The latest downloads and
documentation will be available
at <ulink url="http://github.com/michaelcmartin/Ophis"></ulink>. If at <ulink url="http://github.com/michaelcmartin/Ophis"></ulink>. If
this is out-of-date, a Web search on <quote>Ophis 6502 this is out-of-date, a Web search on <quote>Ophis 6502
assembler</quote> (without the quotation marks) should yield its assembler</quote> (without the quotation marks) should yield its
page. page.
</para> </para>
<para>
Ophis is written entirely in Python and packaged using the
distutils. The default installation script on Unix and Mac OS X
systems should put the files where they need to go. If you are
running it locally, you will need to install
the <literal>Ophis</literal> package somewhere in your Python
package path, and then put the <command>ophis</command> script
somewhere in your path.
</para>
<para> <para>
For Windows users, a prepackaged system made For Windows users, a prepackaged system made
with <command>py2exe</command> is also available. The default with <command>py2exe</command> is also available. The default
Windows installer will use this. In this case, all you need to Windows installer will use this. In this case, all you need to
do is have <command>ophis.exe</command> in your path. do is have <command>ophis.exe</command> in your path.
</para> </para>
<para>
If you are working on a system with Python installed but to
which you do not wish to install software, there is also a
standalone pure-Python edition with an ophis.py script. This may
be placed anywhere and running ophis.py will temporarily set the
library path to point to your directory.
</para>
</section> </section>
<section> <section>

View File

@ -1,13 +1,26 @@
;;; HELLO WORLD for the Atari 800
;;; This produces a file named "HELLO.OBJ" in the Atari DOS ("XEX")
;;; format. Loading it into a DOS-capable disk will let it run
;;; with the "LOAD BINARY FILE" command, and many emulators will
;;; accept it as a boot image.
.outfile "hello.obj" .outfile "hello.obj"
.word $ffff ; Binary file
.word start ; start of code
.word end-1 ; end of code
.org $0600 ; Load into page 6 ;; Outputting text on the Atari is more reminiscent of modern
;; Unix or Windows-based systems than like most 8-bit BIOSes.
;; `iostob OFFSET, VALUE ;; A series of 16-byte blocks of memory starting at $340 serve
;; `iostow OFFSET, VALUE ;; as "I/O channels", and writing text is a matter of
;; Store value in OFFSET in I/O control block X>>4. ;; outputting a string of bytes to the screen editor device in
;; channel zero.
;;
;; Writing the arguments can be tedious, so this example
;; includes two macros for simplifying that a bit: IOSTOB and
;; IOSTOW (I/O Store Byte/Word). The first argument is the
;; offset to write (0-15), and the second is the 8- or 16-bit
;; value to write. The channel itself is selected by the X
;; index register, and the value in .X should be the
;; destination channel multiplied by 16 (so, 0 for channel 0,
;; $10 for channel 1, etc.)
.macro iostob .macro iostob
lda #_2 lda #_2
sta $340+_1,x sta $340+_1,x
@ -18,17 +31,59 @@
`iostob _1+1,>_2 `iostob _1+1,>_2
.macend .macend
start: ldx #$00 ; Channel 0 (E:) ;; With that out of the way, we may start producing our
;; actual file. We open with a $FFFF word to mark ourselves
;; as a binary file.
.word $ffff
;; Write message with one I/O call, and exit ;; The rest of the file is a series of blocks, marking the
`iostob 2,11 ; WRITE command ;; first and last addresses that the block occupies, followed
;; by the data itself. These addresses are inclusive, so we
;; will need to subtract one from a label placed after the
;; final line of the block to get the correct value.
.word start
.word end-1
;; The main program block begins here. The .org instruction
;; sets us to assemble at the location we want the program
;; to actually live; this ensures that the start and end
;; labels have the correct values. For this program, we will
;; load into location $0600 --- the $0600-$06FF region ("page
;; six") is reserved for use by support cartridges, but BASIC
;; doesn't use it and the OS is guaranteed not to.
.org $0600
;; The program itself does a single write request.
start: ldx #$00 ; I/O request on Channel 0
`iostob 2,11 ; request type: WRITE
`iostow 4,msg ; buffer pointer `iostow 4,msg ; buffer pointer
`iostow 8,msgend-msg ; buffer length `iostow 8,msglen ; buffer length
jmp $e456 ; Do I/O call and quit jsr $e456 ; Do I/O call
;; This program intends to return to DOS once it's done, so
;; it returns with RTS. If this were to be a program to boot
;; directly into the emulator, going into an infinite loop
;; would be more polite.
rts ; Return to DOS
;; The message itself. Character $9B is the new-line on the
;; Atari 800. Strings are written with length arguments here
;; instead of with a terminator character, so we collect the
;; length of the string here as well.
msg: .byte "Hello, world!",$9b msg: .byte "Hello, world!",$9b
msgend: ; End of message .alias msglen ^-msg
end: ; End of code block
;; Autostart at start ;; The end of the main file block. This mark lets the block
;; header compute the correct address.
end:
;; Two memory locations are special during load. If a block
;; load rewrites the word at $02E2, the load process will be
;; interrupted and will call the routine at the address
;; written to that location. $02E0 is similar, but the word
;; written is taken to be the address of the start of the
;; program, and controll will pass to that address once the
;; load is complete. We don't need any intervening init
;; routines, so we close by putting our entry point in $02e0
;; as a two-byte block in its own right.
.word $02e0,$02e1,start .word $02e0,$02e1,start

View File

@ -1,9 +1,18 @@
;;; ---------------------------------------------------------------------- ;;; ----------------------------------------------------------------------
;;; HELLO WORLD for the Apple II ;;; HELLO WORLD for the Apple II
;;; This is a ProDOS 8 program. Its output should be importable by ;;; This is a ProDOS 8 program. Its output should be importable by
;;; CiderPress without incident. ;;; CiderPress without incident, and by CADIUS with only minor changes.
;;; ---------------------------------------------------------------------- ;;; ----------------------------------------------------------------------
;; All ProDOS 8 programs are loaded into location $2000 and
;; own the memory from $0800 to $BEFF, as well as all of the
;; zero page except for $30-$4F. The suffix of the output
;; file is used by CiderPress to mark file type and
;; attributes -- for ProDOS 8 programs this type is always
;; $FF (System file) and the attribute is always $2000 (the
;; load address). Be sure to set the option to infer type
;; and attributes from filenames when adding files in
;; CiderPress.
.outfile "HI.SYSTEM#ff2000" .outfile "HI.SYSTEM#ff2000"
.org $2000 .org $2000
@ -21,7 +30,7 @@ wait: bit $c000 ; Check keypress bit
bpl wait bpl wait
bit $c010 ; Acknowledge keypress bit $c010 ; Acknowledge keypress
;; Return to ProDOS ;; Return to ProDOS with a QUIT call
jsr $bf00 jsr $bf00
.byte $65 .byte $65
.word + .word +