8bitlenser/lenser/atari/viewer/slideshow_dli.s
2026-07-03 19:35:35 -07:00

248 lines
5 KiB
ArmAsm

; lenser -- Atari GR.15 + DLI slideshow viewer (per-line colour).
;
; Self-booting (OS loads this to $2000, JSRs $2006). Steps through NIMAGES
; pictures stored as raw sectors -- image i at sectors BASESEC + i*SPI -- SIO-
; reading SPI sectors into $4000 (bitmap $4000/$5000, colour table $6000 of
; 96 bands x 4, display list $6400) and showing each with a display-list
; interrupt that rewrites the four colour registers every two scanlines.
;
; build-time #defines -- WAITMODE WAITSECS RATE NIMAGES LOOPFLAG BASESEC SPI.
CP = $cb ; zero-page pointer into the colour table
* = $2000
boot:
.byte 0 ; flags
.byte 0 ; sector count (patched)
.word $2000
.word binit
cont: ; $2006 -- OS JSRs here after loading the stub
sei
lda #$00
sta $26f ; GPRIOR = 0
lda #$00
sta $230 ; SDLSTL = $6400 (the loaded display list)
lda #$64
sta $231
lda #<dli
sta $200
lda #>dli
sta $201
ldy #<vbi
ldx #>vbi
lda #$07
jsr $e45c ; SETVBV (deferred VBI)
lda #$00
sta ssidx
cli
ssmain:
lda #$00
sta $d40e ; NMIEN off (no DLI/VBI while loading)
sta $22f ; SDMCTL off (blank)
jsr readimg ; SIO-load image ssidx (IRQ stays on for SIOV)
; re-init the colour pointer + band-0 colours for the new image
lda #$04
sta CP
lda #$60
sta CP+1
lda $6000
sta $2c8
lda $6001
sta $2c4
lda $6002
sta $2c5
lda $6003
sta $2c6
lda #$c0
sta $d40e ; NMIEN = DLI + VBI
lda #$22
sta $22f ; SDMCTL = playfield + DL DMA
jsr sswait
inc ssidx
lda ssidx
cmp #NIMAGES
bcc ssmain
#if LOOPFLAG == 1
lda #$00
sta ssidx
jmp ssmain
#else
sei
lda #$00
sta $d40e ; NMIEN off
lda #$40
sta $d40e ; restore VBI only (OS housekeeping)
lda #$00
sta $09
cli
jmp $e474 ; warm-start (exit)
#endif
binit:
rts
; ---- SIO read SPI sectors of image ssidx into $4000 ----
readimg:
lda #<BASESEC
sta secn
lda #>BASESEC
sta secn+1
ldx ssidx
beq rsbuf
radd:
clc
lda secn
adc #SPI
sta secn
bcc ra1
inc secn+1
ra1:
dex
bne radd
rsbuf:
lda #$00
sta $0304
lda #$40
sta $0305
lda #SPI
sta cnt
rloop:
lda #$31
sta $0300
lda #$01
sta $0301
lda #$52
sta $0302
lda #$40
sta $0303
lda #$1f
sta $0306
lda #$80
sta $0308
lda #$00
sta $0309
lda secn
sta $030a
lda secn+1
sta $030b
jsr $e459 ; SIOV
clc
lda $0304
adc #$80
sta $0304
bcc rb1
inc $0305
rb1:
inc secn
bne rb2
inc secn+1
rb2:
dec cnt
bne rloop
rts
; ---- wait (returns; defeats attract mode via $4d) ----
sswait:
#if WAITMODE == 1
lda #$ff
sta $2fc
sw1:
lda #$00
sta $4d
lda $2fc
cmp #$ff
beq sw1
rts
#endif
#if WAITMODE == 2
lda #$00
sta $12
sta $13
sta $14
sw2:
lda #$00
sta $4d
lda $13
cmp #>(WAITSECS*RATE)
bcc sw2
bne sw2d
lda $14
cmp #<(WAITSECS*RATE)
bcc sw2
sw2d:
rts
#endif
#if WAITMODE == 3
lda #$ff
sta $2fc
lda #$00
sta $12
sta $13
sta $14
sw3:
lda #$00
sta $4d
lda $2fc
cmp #$ff
bne sw3d
lda $13
cmp #>(WAITSECS*RATE)
bcc sw3
bne sw3d
lda $14
cmp #<(WAITSECS*RATE)
bcc sw3
sw3d:
rts
#endif
ssidx: .byte 0
secn: .word 0
cnt: .byte 0
; reset colour pointer + band-0 colours each frame (from the loaded $6000 table)
vbi:
lda #$04
sta CP
lda #$60
sta CP+1
lda $6000
sta $d01a
lda $6001
sta $d016
lda $6002
sta $d017
lda $6003
sta $d018
jmp $e462 ; XITVBV
dli:
pha
tya
pha
ldy #$00
sta $d40a ; WSYNC
lda (CP),y
sta $d01a
iny
lda (CP),y
sta $d016
iny
lda (CP),y
sta $d017
iny
lda (CP),y
sta $d018
lda CP
clc
adc #$04
sta CP
bcc nocarry
inc CP+1
nocarry:
pla
tay
pla
rti