151 lines
3.7 KiB
ArmAsm
151 lines
3.7 KiB
ArmAsm
; lenser -- FLI multicolor viewer (self-contained)
|
|
;
|
|
; 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 $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 ; ack
|
|
cli
|
|
hang:
|
|
jmp hang
|
|
|
|
; first IRQ, arrives with jitter on line 48, sets up the stabilised one
|
|
irq1:
|
|
lda #<irq2
|
|
sta $0314
|
|
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
|
|
inx
|
|
cpx #200
|
|
bne fliloop
|
|
|
|
; bottom border: leave bitmap on but stop forcing badlines
|
|
lda #<irq1
|
|
sta $0314
|
|
lda #>irq1
|
|
sta $0315
|
|
lda #$30
|
|
sta $d012
|
|
asl $d019
|
|
jmp $ea81 ; restore regs + RTI
|
|
|
|
d018tab:
|
|
.dsb 256,0
|
|
d011tab:
|
|
.dsb 256,0
|