; 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 $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 $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 $0315 lda #$30 sta $d012 asl $d019 jmp $ea31 ; KERNAL housekeeping (keys + jiffy) then RTI ss_load: lda #2 ldx #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