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

247 lines
5.5 KiB
ArmAsm

; lenser -- FLI slideshow viewer
;
; Steps through NIMAGES FLI pictures named "00".."NN", each a PRG that KERNAL-
; loads to $4000 with the layout from fli.s --
; $4000+L*$400 screen RAM for line L (L=0..7), 1000 bytes each
; $6000 bitmap 8000 (offset $2000 in VIC bank 1)
; $8000 colour RAM 1000 (copied to $D800)
; $83E8 background 1
; The cycle-timed raster loop re-points $D018/$D011 every line for per-line
; colour; at the bottom border it chains to the KERNAL IRQ ($ea31) so GETIN and
; the jiffy clock keep working, letting wait.i advance on key / seconds / both.
; All slides are FLI (uniform). NTSC=1 adds one NOP for the 65-cycle line.
;
; assembled by viewer/assemble.py via xa; NIMAGES / LOOPFLAG / WAITMODE / NTSC
; etc. are #defined by the generated wrapper.
; BASIC autostart, SYS 2061
* = $0801
.word basicend
.word 10
.byte $9e
.byte "2061"
.byte 0
basicend:
.word 0
start:
lda #$00
sta $9d ; suppress KERNAL LOAD messages
sta ss_idx
jsr build_tables ; per-line $D018/$D011 tables (once)
mainloop:
jsr ss_name_build
lda #$0b
sta $d011 ; blank while loading
jsr ss_load ; LOAD "NN",8,1 -> $4000 (KERNAL IRQ active)
; ---- FLI setup ----
sei
lda #$ff
sta $cc ; cursor off (so blink can't corrupt $D800)
; copy colour RAM $8000 -> $D800 (1024 bytes)
ldx #0
ccopy:
lda $8000,x
sta $d800,x
lda $8100,x
sta $d900,x
lda $8200,x
sta $da00,x
lda $8300,x
sta $db00,x
inx
bne ccopy
lda $dd00
and #$fc
ora #$02
sta $dd00 ; VIC bank 1 ($4000-$7FFF)
lda $83e8
sta $d021 ; background
lda #$00
sta $d020 ; border black
lda #$d8
sta $d016 ; multicolor on
lda #<irq1
sta $0314
lda #>irq1
sta $0315
lda #$7f
sta $dc0d ; disable CIA timer IRQs
sta $dd0d
lda $dc0d
lda $dd0d
lda #$01
sta $d01a ; enable raster IRQ
lda #$30
sta $d012 ; line 48
lda $d011
and #$7f
sta $d011
asl $d019
cli
#include "wait.i"
; ---- stop the engine (KERNAL IRQ back on for the next LOAD) ----
sei
lda #$00
sta $d01a
lda #$81
sta $dc0d
lda #$31
sta $0314
lda #$ea
sta $0315
lda $dd00
ora #$03
sta $dd00 ; bank 0
asl $d019
cli
; ---- advance ----
inc ss_idx
lda ss_idx
cmp #NIMAGES
bcc ssgo
#if LOOPFLAG == 1
lda #$00
sta ss_idx
ssgo:
jmp mainloop
#else
jmp ssend
ssgo:
jmp mainloop
ssend:
#endif
; ---- final restore to BASIC ----
lda #$1b
sta $d011
lda #$c8
sta $d016
lda #$15
sta $d018
lda #$0e
sta $d020
lda #$06
sta $d021
lda #$00
sta $cc
jsr $e544
rts
; build d018tab = ((line AND 7) << 4) OR $08, d011tab = $38 OR ((line+3) AND 7)
build_tables:
ldx #0
btab:
txa
and #$07
asl
asl
asl
asl
ora #$08
sta d018tab,x
txa
clc
adc #$03
and #$07
ora #$38
sta d011tab,x
inx
bne btab
rts
; first IRQ, arrives with jitter on line 48, sets up the stabilised one
irq1:
lda #<irq2
sta $0314
lda #>irq2
sta $0315
inc $d012
asl $d019
tsx
cli
.dsb 40,$ea ; 40 NOPs -- irq2 fires inside this slide
; stabilised IRQ on line 49, runs the FLI loop then chains to the KERNAL IRQ
irq2:
txs
lda $d012
cmp $d012
beq jl
jl:
ldx #$0d
d0: dex
bne d0
nop
nop
#if NTSC == 1
nop ; NTSC extra 2 cycles for the 65-cycle line
#endif
ldx #$00
fliloop:
lda d011tab,x
sta $d011
lda d018tab,x
sta $d018
inx
cpx #200
bne fliloop
; bottom border -- re-arm irq1, then KERNAL housekeeping (keys + jiffy)
lda #<irq1
sta $0314
lda #>irq1
sta $0315
lda #$30
sta $d012
asl $d019
jmp $ea31 ; KERNAL housekeeping (keys + jiffy) then RTI
ss_load:
lda #2
ldx #<ss_name
ldy #>ss_name
jsr $ffbd ; SETNAM
lda #1
ldx #8
ldy #1
jsr $ffba ; SETLFS (secondary 1 = file's own address)
lda #0
jsr $ffd5 ; LOAD
rts
ss_name_build:
lda ss_idx
ldx #$2f
sec
ssten:
inx
sbc #10
bcs ssten
adc #10
ora #$30
sta ss_name+1
txa
sta ss_name
rts
ss_idx: .byte 0
ss_name: .byte $30,$30
; The cycle-exact fliloop reads `lda d018tab,x` / `lda d011tab,x` for x=0..199,
; so each table MUST be page-aligned -- otherwise indices past the page boundary
; add a page-cross penalty cycle and tear the FLI display.
* = (* + $ff) & $ff00
d018tab:
.dsb 256,0
d011tab:
.dsb 256,0