aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile5
-rw-r--r--dla.s75
-rw-r--r--io.s147
-rw-r--r--printint.s37
4 files changed, 130 insertions, 134 deletions
diff --git a/Makefile b/Makefile
index 7af560a..fb969a8 100644
--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,7 @@ PERL = perl
all: dla.xex
-dla.xex: dla.s io.s dlatbl.s xex.inc
+dla.xex: dla.s io.s dlatbl.s xex.inc printint.s
$(CL65) $(CL65FLAGS) -l dla.list -Ln dla.labels -t none -o dla.xex dla.s
dlatbl.s: mkdlatbl.pl
@@ -15,3 +15,6 @@ clean:
test: all
atari800 -turbo dla.xex
+
+%.xex: %.s
+ $(CL65) $(CL65FLAGS) -t none -o $@ $<
diff --git a/dla.s b/dla.s
index 7106a0a..debb196 100644
--- a/dla.s
+++ b/dla.s
@@ -49,9 +49,13 @@
xex_org loadaddr
.include "io.s" ; printchrx and getchrx
+ .include "printint.s"
; init stuff gets done once, at startup
init:
+ lda #0
+ sta seedtype
+ sta LMARGN
lda SDMCTL
sta old_dma
lda SDLSTL
@@ -59,6 +63,12 @@ init:
lda SDLSTH
sta old_dl+1
+ ; set default particles (if user just hits return)
+ lda #<DEFAULTPART
+ sta maxparticles
+ lda #>DEFAULTPART
+ sta maxparticles+1
+
; "New" option jumps here, restore GR.0 screen
getargs:
lda #$90
@@ -74,22 +84,19 @@ getargs:
lda old_dma
sta SDMCTL
- ; set default particles (if user just hits return)
- lda #<DEFAULTPART
- sta maxparticles
- lda #>DEFAULTPART
- sta maxparticles+1
-
; print banner and prompt.
-printmsg:
- ldx #0
-pmloop:
- lda msg,x
- beq pmdone
- jsr printchrx
- inx
- bne pmloop
-pmdone:
+printbanner:
+ lda #<banner
+ ldx #>banner
+ jsr printmsg
+
+ lda maxparticles
+ ldx maxparticles+1
+ jsr printdecw
+
+ lda #<prompt
+ ldx #>prompt
+ jsr printmsg
; use CIO to read input, so user can use backspace/etc.
jsr readline
@@ -100,13 +107,13 @@ pmdone:
lda #0
sta CIX
jsr AFP ; ASCII to floating point, result in FR0
- bcs printmsg ; C set means error
+ bcs printbanner ; C set means error
jsr FPI ; convert FR0 to integer (result in FR0)
- bcs printmsg
+ bcs printbanner
lda FR0
tax
ora FR0+1 ; we don't accept 0 for an answer!
- beq printmsg
+ beq printbanner
lda FR0+1
stx maxparticles
sta maxparticles+1
@@ -114,21 +121,21 @@ pmdone:
usedefault:
; print seed type prompt
- ldx #0
-pm2loop:
- lda msg2,x
- beq pm2done
- jsr printchrx
+ lda #<seedprompt
+ ldx #>seedprompt
+ jsr printmsg
+ ldx seedtype
inx
- bne pm2loop
-pm2done:
+ txa
+ jsr printdecb
+ lda #<seedprompt2
+ ldx #>seedprompt2
+ jsr printmsg
readgen:
jsr getchrx
cmp #$9b
- bne noteol
- lda #$31
-noteol:
+ beq generate
cmp #$31
bcc readgen
cmp #$35
@@ -700,13 +707,17 @@ readline:
;;;;; end of executable code, data tables from here on out.
; prompts
-msg:
+banner:
.byte $7d, "Diffusion Limited Aggregate",$9b
.byte "Urchlay's ASM version 0.0.7",$9b,$9b
.byte "Particle count range: 1 to 65535",$9b
- .byte "How many particles [",.sprintf("%d", DEFAULTPART),"]? ",$0
-msg2:
- .byte $9b,"Seed Type: ",$9b,"1=Dot 2=Plus 3=4Dots 4=Line [1]? ",$0
+ .byte "How many particles [",$0
+prompt:
+ .byte "]? ",$0
+seedprompt:
+ .byte $9b,"Seed Type: ",$9b,"1=Dot 2=Plus 3=4Dots 4=Line [",$0
+seedprompt2:
+ .byte "]? ",$0
; screen codes for menu
menumsg:
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
diff --git a/printint.s b/printint.s
new file mode 100644
index 0000000..6d65f93
--- /dev/null
+++ b/printint.s
@@ -0,0 +1,37 @@
+
+; use FP math pack to print 8- or 16-bit integers in decimal.
+
+;;; Subroutine: printdecb
+;;; Print byte in accumulator, in decimal
+;;; Trashes all regs/flags
+printdecb:
+ ldx #0
+ ; fall thru to printdecw
+
+;;; Subroutine: printdecw
+;;; Print word in A/X, in decimal (X is high byte)
+;;; Trashes all regs/flags
+; one annoyance here: we need (zp),y addressing because FASC actually
+; updates INBUFF to point to the first non-zero ASCII digit (this is
+; how we skip leading zeroes), but we don't have a "printchry" that
+; preserves Y, so we end up using X for a counter and copying it to Y
+; every loop iteration...
+; also, why did I pick A/X instead of X/Y like FLD(0|1)R uses? in case
+; someone ever wants to call this from C code in cc65...
+printdecw:
+ sta FR0
+ stx FR0+1
+ jsr IFP
+ jsr FASC
+ ldx #0
+pwloop:
+ txa
+ tay
+ lda (INBUFF),y
+ php
+ and #$7f
+ jsr printchrx
+ inx
+ plp
+ bpl pwloop
+ rts