; lenser -- FLI multicolor viewer, NTSC timing (self-contained) ; ; Same as fli.s but the inner loop is one NOP (2 cycles) longer so it self-syncs ; to the NTSC 65-cycle raster line (25 free CPU cycles per badline) vs PAL's 63. ; ; Re-points the VIC video matrix ($D018) and forces a badline ($D011 yscroll) ; on every visible raster line via a cycle-timed loop, giving per-line colour. ; ; Memory layout of appended data (loads from $4000): ; $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 ; ; assembled by viewer/assemble.py via xa ; BASIC autostart, SYS 2061 * = $0801 .word basicend .word 10 .byte $9e .byte "2061" .byte 0 basicend: .word 0 ; ML begins at $080D start: sei ; 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 ; build per-line tables. d018tab = ((line AND 7) << 4) OR $08 ; d011tab = $38 OR (line AND 7) = BMM+DEN+RSEL plus yscroll ldx #0 btab: txa and #$07 asl asl asl asl ora #$08 sta d018tab,x ; yscroll must equal (raster AND 7) to force a badline; the first ; displayed raster is 51, so line x maps to raster 51+x. txa clc adc #$03 and #$07 ora #$38 sta d011tab,x inx bne btab ; VIC bank 1 ($4000-$7FFF) lda $dd00 and #$fc ora #$02 sta $dd00 lda $83e8 sta $d021 ; background lda #$00 sta $d020 ; border black lda #$d8 sta $d016 ; multicolor on ; raster IRQ setup 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 ; ack cli hang: jmp hang ; first IRQ, arrives with jitter on line 48, sets up the stabilised one irq1: lda #irq2 sta $0315 inc $d012 ; fire again next line (49) asl $d019 ; ack tsx cli ; burn the rest of the line so irq2 fires inside this NOP slide .dsb 40,$ea ; 40 NOPs ; stabilised IRQ on line 49, runs the FLI loop irq2: txs ; restore sp from irq1 ; cancel the remaining 0/1-cycle jitter: read the raster twice; the ; branch is 2 or 3 cycles depending on alignment, normalising entry. lda $d012 cmp $d012 beq jl jl: ; fixed delay so the first store lands before the c-access window ldx #$0d d0: dex bne d0 nop nop ldx #$00 fliloop: lda d011tab,x ; force badline (yscroll = line&7) sta $d011 lda d018tab,x ; point video matrix at screen[line] sta $d018 nop ; NTSC extra 2 cycles for 65 cycle line inx cpx #200 bne fliloop ; bottom border: leave bitmap on but stop forcing badlines lda #irq1 sta $0315 lda #$30 sta $d012 asl $d019 jmp $ea81 ; restore regs + RTI d018tab: .dsb 256,0 d011tab: .dsb 256,0