aboutsummaryrefslogtreecommitdiff
path: root/io.s
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2022-10-31 15:07:02 -0400
committerB. Watson <urchlay@slackware.uk>2022-10-31 15:07:02 -0400
commitb0d6af17e313ac574fc7db761c79a812ec2ecf15 (patch)
tree380cf2d7b490800a1060dee97727268405ad0fc9 /io.s
parent081a62091a60153e814b361d858e4a51ec59cd5f (diff)
downloaddla-asm-b0d6af17e313ac574fc7db761c79a812ec2ecf15.tar.gz
Keep default particles & seed on New.
Diffstat (limited to 'io.s')
-rw-r--r--io.s147
1 files changed, 46 insertions, 101 deletions
diff --git a/io.s b/io.s
index 98dc219..7b63f95 100644
--- a/io.s
+++ b/io.s
@@ -1,104 +1,3 @@
- ; 20220930 bkw, aka Urchlay on libera IRC, aka urchlay@slackware.uk:
-
- ; Example code for calling CIO through the back door, like BASIC does.
- ; Provided under the terms of the WTFPL: Do WTF you want to with this.
-
- ; Verbose documentation here. To skip to the actual code, search for
- ; three ; characters.
-
- ; There's a lot of old code that calls the OS ROM's print-character
- ; and read-character addresses directly. These were never published
- ; by Atari as part of their API... and in fact they changed between
- ; the 400/800 and XL/XE, which is a major reason why certain software
- ; is "OS B only" or "XL only". People coming from other platforms such
- ; at the C=64 or Apple II were used to their ROMs having fixed
- ; addresses to JSR to, for print-character and read-character, and
- ; so they used $F6A4 to print and $F6E2 to read... which were
- ; never guaranteed by Atari not to change. And they did change,
- ; in the XL OS.
-
- ; The pedantically correct way to print a character is to set up
- ; a 1-byte buffer for IOCB #0, and call CIOV with ICCOM set to
- ; $09 (aka 'put record'). Even Atari decided this was too much
- ; work, so they also provided a handy "put-one-byte" vector in
- ; EDITRV, which gets copied to ICPTL/H when the OS opens the E:
- ; device... BASIC uses this to print characters, and you can, too. It
- ; works on any revision of the Atari OS, because it's part of the
- ; OS specification: if it *didn't* work on some OS version, neither
- ; would Atari BASIC, which would count as a show-stopper!
-
- ; Atari didn't provide a similar slot in the IOCB for the
- ; get-one-byte vector... and generally, if you're interested in
- ; reading input one character at a time, you don't want IOCB #0 (E:)
- ; anyway. You want the K: device (which returns immediately after
- ; each keypress, rather than waiting for a whole line of input). The
- ; correct way to read from the keyboard is to open an IOCB (other
- ; than #0) to the K: device, set up that IOCB, including a 1-byte
- ; buffer, and call CIOV with ICCOM set to $05 (aka get-record). But
- ; it turns out that the K: device has a get-one-byte routine that (a)
- ; can be found in a published location (KEYBDV table) that doesn't
- ; change with ROM revision, and (b) works without even having an IOCB
- ; open for K:.
-
- ; The vectors are stored as "address minus one", because they're
- ; intended to be called via the RTS instruction (probably Atari did
- ; this because the JSR instruction doesn't have an indexed mode like
- ; JMP does). Read on, to see how to call them. The calling sequence
- ; isn't as convenient as the illegal entry points (or the Commodore's
- ; Kernal, which does publish print-acumulator and get-1-byte
- ; vectors), but it's a lot less code than the 'proper' IOCB setup
- ; would be. And if you copy/paste from this file, you just call these
- ; subroutines in your code (as convenient as the Commodore).
-
- ; You are welcome to copy the code in this file into your own
- ; project. It's unencumbered: I release it under the WTFPL. I would
- ; just say it's public domain, but I have been told by people who
- ; ought to know that some countries don't actually recognize public
- ; domain in their law. WTFPL explicitly says you can do whatever you
- ; want with this.
-
- ; Examples:
-
- ; You could make your own "memo pad mode" with this:
- ;
- ; main:
- ; jsr getchr
- ; jsr printchr
- ; jmp main
-
- ; Print a null-terminated string, up to 256 bytes long:
- ;
- ; ldx #0
- ; msgloop:
- ; lda message,x
- ; beq msgdone
- ; jsr printchrx
- ; inx
- ; bne msgloop
- ; msgdone:
- ; rts ; or whatever other code goes here...
- ;
- ; message: .byte "Hello, World!",$9b,$00
-
- ; Environment:
-
- ; The code depends on a few symbols (equates) being defined. How you
- ; do this depends on the assembler you're using.
-
- ; .include "atari.inc" ; for ca65
- ; .include "sysequ.m65" ; for atasm
- ; include atari8.h ; dasm, if it actually had this file :(
-
- ; If your assembler doesn't have a file of Atari symbols, use:
- ; ICPTL = $0346
- ; ICPTH = $0347
- ; KEYBDV = $E420
- ; EDITRV = $E400 ; only if you change getchr to use this.
- ; ...of course your assembler might want EQU or .EQU instead of = signs.
-
- ; .org <wherever> ; your assembler may want org without the dot, or *=
-
- ;;; Start of actual code.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Subroutine: printchr
@@ -159,6 +58,28 @@ getchr:
; remember that they call printchr and getchr, so you have to copy
; those also.
+ ; Subroutine: Print A register in hex.
+ ; Preserves X (but not A or Y).
+printhex:
+ pha ; stash argument
+ lsr ; shift right 4 times,
+ lsr ; to get the first hex digit
+ lsr ; (aka nybble) into the bottom
+ lsr ; 4 bit positions.
+ jsr printxdig ; print the top nybble.
+ pla ; restore original value...
+ and #$0f ; mask off high nybble
+ ; fall through to print the 2nd digit.
+
+ ; Subroutine: Print a nybble (A=0 to $0f) in hex.
+printxdig:
+ ora #$30 ; 0-9 now ASCII...
+ cmp #$3a ; do we have A-F?
+ bcc xok ; if not, don't adjust it
+ adc #$26 ; A-F now ASCII: $3a + $26 + 1 (carry always set) = $61 (a)
+xok:
+ ; fall through to print the digit.
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Subroutine: printchrx
;
@@ -201,3 +122,27 @@ getchrx:
tax ; from stack.
tya ; restore return value to A.
rts ; regular RTS.
+
+ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ ; Subroutine: printmsg
+ ;
+ ; Print the null-terminated message pointed to by A (low) and X (high).
+ ; Limited to <= 256 character messages.
+ ;
+ ; Trashes all registers, plus uses FR0 for temp storage.
+ ; Calls printchr.
+ ;
+printmsg:
+ sta FR0
+ stx FR0+1
+ lda #0
+ sta FR0+2
+pmloop:
+ ldy FR0+2
+ lda (FR0),y
+ beq pmdone
+ jsr printchr
+ inc FR0+2
+ bne pmloop
+pmdone:
+ rts