added "double dabble" example

git-svn-id: https://svn.code.sf.net/p/acme-crossass/code-0/trunk@322 4df02467-bbd4-4a76-a152-e7ce94205b78
This commit is contained in:
marcobaye 2021-11-04 20:15:04 +00:00
parent ec1e640dfd
commit eeece2db6e
5 changed files with 91 additions and 2 deletions

View File

@ -2,10 +2,13 @@ ASSEMBLER6502 = acme
AS_FLAGS = -v9 -Wtype-mismatch
RM = rm
PROGS = c64misc.prg ddrv128.prg ddrv64.prg macedit.o trigono.o
PROGS = c64doubledabble.prg c64misc.prg ddrv128.prg ddrv64.prg macedit.o trigono.o
all: $(PROGS)
c64doubledabble.prg: c64doubledabble.a
$(ASSEMBLER6502) $(AS_FLAGS) --outfile c64doubledabble.prg --format cbm c64doubledabble.a
c64misc.prg: c64misc.a
$(ASSEMBLER6502) $(AS_FLAGS) --outfile c64misc.prg --format cbm c64misc.a

View File

@ -0,0 +1,86 @@
;ACME 0.97
; here's an implementation of the "double dabble" algorithm, a quick
; and easy way to output integers as decimal digits.
; in this example, the 24-bit value of the time variable TI is shown
; on the screen as eight decimal digits, updated once per frame (every
; once in a while there will be a glitch because the system interrupt
; handler is not synchronized with the screen, to fix this is left as
; an excercise to the reader).
; the raster time used is indicated via changes of the border color.
DIGITS = 8 ; three input bytes -> 24 bits -> max 16777216 -> we need eight digits
!addr {
byte = $fb ; buffers input byte during shifts
ti_high = $a0 ; input data
ti_med = $a1
ti_low = $a2
out = $0400 ; where to show output digits (big-endian!)
raster = $d012 ; to sync with screen
border = $d020 ; to show raster time
}
* = $0801
!src "misc/basicstub.a"
--- ; wait for lower border
lda raster
cmp #251
bne ---
inc border ; start "stop watch"
jsr dd_clear ; clear output
sei ; make sure TI is stable while we read it
lda ti_low
pha
lda ti_med
pha
lda ti_high
cli ; re-allow irq
jsr dd_process_A ; process high byte
pla ; restore medium byte
jsr dd_process_A
pla ; restore low byte
jsr dd_process_A
jsr dd_result ; convert result from 0..9 values to '0'..'9' characters
dec border ; stop "stop watch"
jmp ---
dd_clear ; clear result bytes
ldx #DIGITS - 1
lda #0
--- sta out, x
dex
bpl ---
rts
dd_result ; convert result bytes to ascii digits
ldx #DIGITS - 1
--- lda out, x
ora #$30
sta out, x
dex
bpl ---
rts
dd_process_A ; process eight bits
; use the zero-means-empty trick so we do not need a bit counter:
sec ; create "marker bit"
rol ; push into A, now C = data bit
sta byte ; remember for later
; here's how to process a bit:
; "out" holds digits (0..9, not '0'..'9'),
; but in big-endian order (for screen output).
; the new bit is in C:
next_bit ldx #DIGITS - 1 ; loop over output digits
next_digit ldy out, x ; now Y = 0..9 (old value)
lda table, y ; now A = 0/1/2/3/4/128/129/130/131/132
rol ; now A = 0..9 (new value), bit for next digit in C
sta out, x ; update digit
dex
bpl next_digit
;clc ; only needed if overflow possible
rol byte ; get next data bit
bne next_bit
; byte is empty (C is 1, but that's the marker bit)
rts
table
!by 0, 1, 2, 3, 4, $80, $81, $82, $83, $84

Binary file not shown.

Binary file not shown.

View File

@ -3,7 +3,7 @@
;* = $0801 ; c64
;* = $1001 ; c16/+4
;* = $1c01 ; c128
!wo line2, 2020 ; link pointer and line number
!wo line2, 2021 ; link pointer and line number
!by $9e, ' ' ; "sys "
!by '0' + entry % 10000 / 1000
!by '0' + entry % 1000 / 100