Click here to download a PETSCII .seq file that can be loaded directly into Turbo Macro Pro by Style.
;---------------------------------------
;
; Full color IFLI Renderer
;
; Code by: dW/Style
;
; Created on: Sept 16/99
;
;---------------------------------------
; Zero page locations
;---------------------------------------
; Buffer pointers (must be contiguous
; in zp and in this order)
r1 = $4c
g1 = $4e
b1 = $50
r2 = $52
g2 = $54
b2 = $56
; Square table pointers
rsl = $58
rsh = $5a
gsl = $5c
gsh = $5e
bsl = $60
bsh = $62
; Color distance value
dl = $64
dh = $65
; Temp pointers
sp = $66
dp = $68
; Pointer to remapped data
rmap = $6a
; Current pix index (1 byte)
cpptr = $6c
; Buffers and tables
;---------------------------------------
; Line buffers
red1 = $4000
grn1 = $4130
blu1 = $4260
red2 = $c000
grn2 = $c130
blu2 = $c260
; Square table
sqrl = $0a00
sqrh = $0d00
; F-S dither tables
fs1 = $8000
fs3 = $8100
fs5 = $8200
fs7 = $8300
; C64 color closeness table
closetbl = $7f00
closback = $ff40
; IFLI banks
bank0 = $4000
bank1 = $c000
; IFLI Memory areas
scrn0 = $4390
bmap0 = $6078
scrn1 = $c390
bmap1 = $e078
; Main code. To be replaced with the
; JPEG decopressor
;---------------------------------------
; *= $1fff
; jmp mainfli
; rts
; IFLI renderer code jump points
;---------------------------------------
*= $2000
rendinit jmp initifli
rendrow jmp render
display jmp dodisply
; IFLI initialization. Wipes bitmaps
; and initializes renderer
;---------------------------------------
initifli
.block
sei
; set up vic
inc $01
lda #$38
sta $d011
lda #$08
sta $d018
lda #216
sta $d016
lda $dd00
and #%11111100
ora #$02
sta $dd00
dec $01
;
lda $01
sta restore+1
lda #$34
sta $01
jsr clearfli
lda #$03
sta cmem
lda #$d8
sta cmem+1
lda #$00
ldx #$07
setptrs lda rendptrs,x
sta bmapptrs,x
dex
bpl setptrs
ldx #$7f
cpyclose lda closback,x
sta closetbl,x
dex
bpl cpyclose
restore lda #$00
sta $01
cli
rts
rendptrs .byte scrn0
.byte bmap0
.byte scrn1
.byte bmap1
.bend
bmapptrs .byte $00,$00,$00,$00
.byte $00,$00,$00,$00
; IFLI main render routine
;---------------------------------------
render
.block
ldx $01
stx restore+1
ldx #$34
stx $01
sta bmptr
sta rmapmain
sty bmptr+1
sty rmapmain+1
lda #>sqrl
sta rsl+1
sta gsl+1
sta bsl+1
lda #>sqrh
sta rsh+1
sta gsh+1
sta bsh+1
lda #$00
sta currline
clc
jsr copyline
inc currline
jsr remap
jsr renderrw
restore lda #$00
sta $01
rts
.bend
; Copy line to buffer
;---------------------------------------
copyline
.block
ldx #11
bcs altern
donorm lda normal,x
sta r1,x
dex
bpl donorm
bmi continue
altern lda reversed,x
sta r1,x
dex
bpl altern
continue
lda bmptr
sta sp
lda bmptr+1
sta sp+1
ldx r2
inx
stx dp
lda r2+1
sta dp+1
jsr docopy ; copy red
lda bmptr+1
clc
adc #$13
sta sp+1
ldx g2
inx
stx dp
lda g2+1
sta dp+1
jsr docopy ; copy green
lda bmptr+1
clc
adc #$26
sta sp+1
ldx b2
inx
stx dp
lda b2+1
sta dp+1
jsr docopy ; copy blue
lda bmptr
clc
adc #$30
sta bmptr
lda bmptr+1
adc #$01
sta bmptr+1
rts
docopy lda currline
bne skipmrg
beq mergcomp
skipmrg cmp #$08
beq clrcomp
copycomp
.block
ldy #$00
copy1 lda (sp),y
lsr a
lsr a
sta (dp),y
iny
bne copy1
inc sp+1
inc dp+1
ldy #$2f
copy2 lda (sp),y
lsr a
lsr a
sta (dp),y
dey
bpl copy2
rts
.bend
mergcomp
.block
ldy #$00
mrg1 lda (sp),y
lsr a
lsr a
clc
adc (dp),y
sta (dp),y
iny
bne mrg1
inc sp+1
inc dp+1
ldy #$2f
mrg2 lda (sp),y
lsr a
lsr a
clc
adc (dp),y
sta (dp),y
dey
bpl mrg2
rts
.bend
clrcomp
.block
ldy #$00
tya
clr1 sta (dp),y
iny
bne clr1
inc sp+1
inc dp+1
ldy #$2f
clr2 sta (dp),y
dey
bpl clr2
rts
.bend
normal .byte red1
.byte grn1
.byte blu1
reversed .byte red2
.byte grn2
.byte blu2
.byte red1
.byte grn1
.byte blu1
.bend
bmptr .byte $00,$00
currline .byte $00
; Remap true color to c64's 16 colors
;---------------------------------------
remap
.block
lda #$07
sta lcount
lda #$55
sta buffsel
lda rmapmain
sta rmap
lda rmapmain+1
sta rmap+1
rmore lsr buffsel
jsr copyline
jsr remapln
inc currline
dec lcount
bpl rmore
rts
lcount .byte $00
buffsel .byte $00
.bend
rmapmain .byte $00,$00
; Remap scanline
;---------------------------------------
remapln
.block
inc r1
inc g1
inc b1
lda #$03
sta chunkcnt
lda #$4a
sta addval+1
inc $01
inc $d020
dec $01
nchunk ldy #$00
nextpix sty cpptr
jsr close64
sta (rmap),y
jsr floyd
iny
cpy #$4a
bne nextpix
ldy #$06
fixptr ldx addtbl,y
jsr addptr
dey
bpl fixptr
dec chunkcnt
bpl nchunk
lda #$08
sta addval+1
ldx #rmap
addptr
lda $00,x
clc
addval adc #$4a
sta $00,x
bcc skiph
inc $01,x
skiph rts
addtbl .byte r1,g1,b1,r2,g2,b2,rmap
chunkcnt .byte $00
.bend
; Floyd-steinberg dither main routine
;---------------------------------------
floyd
.block
stx storx+1
sty story+1
tax
lda times3,x
tax
lda #$40
clc
adc (r1),y
sec
sbc c64,x
inx
sta rerr+1
lda #$40
clc
adc (g1),y
sec
sbc c64,x
inx
sta gerr+1
lda #$40
clc
adc (b1),y
sec
sbc c64,x
sta berr+1
rerr ldx #$00
clc
lda fs1,x
adc (r2),y
sta (r2),y
iny
clc
lda fs7,x
adc (r1),y
sta (r1),y
clc
lda fs5,x
adc (r2),y
sta (r2),y
iny
clc
lda fs3,x
adc (r2),y
sta (r2),y
dey
dey
gerr ldx #$00
clc
lda fs1,x
adc (g2),y
sta (g2),y
iny
clc
lda fs7,x
adc (g1),y
sta (g1),y
clc
lda fs5,x
adc (g2),y
sta (g2),y
iny
clc
lda fs3,x
adc (g2),y
sta (g2),y
dey
dey
berr ldx #$00
clc
lda fs1,x
adc (b2),y
sta (b2),y
iny
clc
lda fs7,x
adc (b1),y
sta (b1),y
clc
lda fs5,x
adc (b2),y
sta (b2),y
iny
clc
lda fs3,x
adc (b2),y
sta (b2),y
storx ldx #$00
story ldy #$00
rts
times3 .byte 0,3,6,9,12,15,18,21
.byte 24,27,30,33,36,39,42,45
.bend
; Compute closest c64 color for current
; pixel and return it in .A
;---------------------------------------
close64
.block
stx tmpx+1 ; save x and y
sty tmpy+1
ldy cpptr ; current pix ptr
lda #$c0
tax
sec
sbc (r1),y
sta rsl
sta rsh
txa
sec
sbc (g1),y
sta gsl
sta gsh
txa
sec
sbc (b1),y
sta bsl
sta bsh
ldx #$ff
stx dminl
stx dminh
inx
stx count
next64
ldy c64,x
lda (rsl),y
sta dl
lda (rsh),y
sta dh
inx
ldy c64,x
lda (gsl),y
clc
adc dl
sta dl
lda (gsh),y
adc dh
sta dh
inx
ldy c64,x
lda (bsl),y
clc
adc dl
sta dl
lda (bsh),y
adc dh
sta dh
inx
lda dminh
cmp dh
bcc skip
bne replace
lda dminl
cmp dl
bcc skip
replace lda dl
sta dminl
lda dh
sta dminh
lda count
sta closest
skip
inc count
lda count
cmp #$10
bne next64
tmpx ldx #$00
tmpy ldy #$00
lda closest
rts
count .byte $00
dminl .byte $00
dminh .byte $00
.bend
closest .byte $00
; ===== MOVE THIS STUFF UP =====
; zp pointers
sc0 = $4c
bm0 = $4e
sc1 = $50
bm1 = $52
; zp variables
c64color = $54
storhp = $55
max = $56
mask = $57
bground = $58
scrmem0 = $59
scrmem1 = $5a
colmem = $5b
srctmp = $5c
bmtmp = $5d
; Histograms
blockh = $7e00
blockcol = $7e10
ccount = $7e20
hist = $7e30
; Render a remapped row to IFLI
;---------------------------------------
renderrw
.block
jsr initrend
lda #36
sta blkcount
ldy #$00
sty bground
iny ;
iny ; debugging
sty scrmem0 ;
iny ; REMOVE THIS
sty scrmem1 ; IN FINAL
lda cmem
sta stor+1
lda cmem+1
sta stor+2
lda #$00
sta tmpy+1
nxtblock jsr initblk
inc $01
inc $d020
dec $01
jsr pickcol
inc $01
tmpy ldy #$00
lda colmem
stor sta $d803,y
inc tmpy+1
dec $01
jsr rendrblk
dec blkcount
bpl nxtblock
lda cmem
clc
adc #$28
sta cmem
bcc skipm
inc cmem+1
skipm
jsr storptrs
rts
blkcount .byte $00
.bend
cmem .byte $03,$d8
; Store bitmap & screen mem ptrs
;---------------------------------------
storptrs
.block
ldx #$07
copy lda sc0,x
sta bmapptrs,x
dex
bpl copy
rts
.bend
; Render 8x8 block
;---------------------------------------
rendrblk
.block
lda #$07
sta lines
lda #$00
sta storhp
sta bmtmp
lda sp
sta dp
lda sp+1
sta dp+1
moreblk jsr pick4x1
lda #%11000000
sta mask
ldy #$00
nextpix lda (dp),y
ldx #$03
again cmp bground,x
beq found
dex
bpl again
jsr nextbest
found sty srctmp
lda bitpair,x
and mask
ldy bmtmp
ora (bm0),y
sta (bm0),y
ldy srctmp
iny
iny
lsr mask
lsr mask
bne nextpix
lda scrmem0
asl a
asl a
asl a
asl a
ora scrmem1
ldy #$00
sta (sc0),y
lda sc0
clc
adc #$9d
sta sc0
lda sc0+1
adc #$03
sta sc0+1
jsr pick4x1
lda #%11000000
sta mask
inc dp
ldy #$00
nextpix2 lda (dp),y
ldx #$03
again2 cmp bground,x
beq found2
dex
bpl again2
jsr nextbest
found2 sty srctmp
lda bitpair,x
and mask
ldy bmtmp
ora (bm1),y
sta (bm1),y
ldy srctmp
iny
iny
lsr mask
lsr mask
bne nextpix2
lda scrmem0
asl a
asl a
asl a
asl a
ora scrmem1
ldy #$00
sta (sc1),y
lda sc1
clc
adc #$9d
sta sc1
lda sc1+1
adc #$03
sta sc1+1
inc bmtmp
lda dp
clc
adc #$2f
sta dp
lda dp+1
adc #$01
sta dp+1
dec lines
bmi finish
jmp moreblk
finish lda sp
clc
adc #$08
sta sp
bne skipi
inc sp+1
skipi lda bm0
clc
adc #$08
sta bm0
sta bm1
bne skipb
inc bm0+1
inc bm1+1
skipb lda sc0
sec
sbc #$e7
sta sc0
lda sc0+1
sbc #$1c
sta sc0+1
lda sc1
sec
sbc #$e7
sta sc1
lda sc1+1
sbc #$1c
sta sc1+1
rts
lines .byte $00
bitpair .byte %00000000
.byte %01010101
.byte %10101010
.byte %11111111
.bend
; Find closest color for color in .A
;---------------------------------------
nextbest
.block
sty story+1
asl a
asl a
asl a
asl a
tay
again lda closetbl,y
ldx #$03
find cmp bground,x
beq story
dex
bpl find
iny
jmp again
story ldy #$00
rts
.bend
; Pick colors for a 4x1 block
;---------------------------------------
pick4x1
.block
ldx storhp
txa
clc
adc #$08
sta compx+1
sta storhp
ldy #$00
morepix lda hist,x
bmi end4x1
cmp colmem
beq skipcol
sta scrmem0,y
iny
skipcol inx
inx
compx cpx #$00
beq end4x1
cpy #$02
bne morepix
end4x1 rts
.bend
; Pick colors for an 8x8 block
;---------------------------------------
pickcol
.block
lda #$07
sta lncount
lda #$00
sta storhp
nextline sta cpptr
jsr rowhist
lda storhp
clc
adc #$08
sta storhp
inc sp
jsr rowhist
lda sp
clc
adc #$2f
sta sp
lda sp+1
adc #$01
sta sp+1
lda storhp
adc #$08
sta storhp
lda #$00
dec lncount
bpl nextline
jsr pickblk
lda sp
sec
sbc #$80
sta sp
lda sp+1
sbc #$09
sta sp+1
rts
lncount .byte $00
.bend
; Pick color memory color for current
; 8x8 block
;---------------------------------------
pickblk
.block
lda #$00
sta storhp
lda #$0f
sta cnt
next lda storhp
sta tmpx+1
clc
adc #$06
tax
ldy hist,x
bpl countmor
dex
dex
ldy hist,x
bpl countmor
setnxt lda storhp
clc
adc #$08
sta storhp
dec cnt
bpl next
jmp endhist
countmor lda hist+1,x
clc
adc blockh,y
sta blockh,y
tmpx cpx #$00
beq setnxt
dex
dex
ldy hist,x
jmp countmor
endhist
ldy #$0f
lda blockh,y
sta max
dey
findcol lda blockh,y
cmp max
bcc bigger
sta max
sty colmem
bigger dey
bne findcol ; skip black
rts
cnt .byte $00
.bend
; Do a 4x1 row histogram
;---------------------------------------
rowhist
.block
ldy #$00
lda storhp
clc
adc #$06
sta tmpx+1
newpix ldx storhp
lda (sp),y
beq nextpix
sta c64color
nexthist cmp hist,x
bne skip0
inx
inc hist,x
bne nextpix
skip0 lda hist,x
bmi empty
lda c64color
inx
inx
tmpx cpx #$00
bcc nexthist
empty lda c64color
sta hist,x
inx
inc hist,x
inx
nextpix iny
iny
cpy #$08
bne newpix
rts
.bend
; Clear histograms
;---------------------------------------
initblk
.block
ldy #$0f
ldx #$00
clr txa
sta blockh,y
sta ccount,y
dey
bpl clr
ldy #$7f
clrhist lda #$00
sta hist,y
dey
lda #$ff
sta hist,y
dey
bpl clrhist
rts
.bend
; Set pointers for renderer
;---------------------------------------
initrend
.block
ldx #$07
setptrs lda bmapptrs,x
sta sc0,x
dex
bpl setptrs
lda rmapmain
sta sp
lda rmapmain+1
sta sp+1
rts
rendptrs .byte scrn0
.byte bmap0
.byte scrn1
.byte bmap1
.bend
; IFLI main display routine
;---------------------------------------
dodisply
.block
sei
lda $01
sta store1+1
lda #$34
sta $01
lda #$43
ldx #$40
jsr shiftfli
lda #fixb0
jsr setptrs
jsr defragbm
lda #$c3
ldx #$c0
jsr shiftfli
lda #fixb1
jsr setptrs
jsr defragbm
lda #fixs0
jsr setptrs
jsr defragsc
lda #fixs1
jsr setptrs
jsr defragsc
lda #$37
sta $01
jsr mainfli
store1 lda #$00
sta $01
rts
setptrs sta sc0
sty sc0+1
ldy #$03
set1 lda (sc0),y
sta sp,y
dey
bpl set1
rts
fixb0 .byte $d0,$78,$40,$7e
fixb1 .byte $d0,$f8,$40,$fe
fixs0 .byte $c0,$5c,$c0,$5f
fixs1 .byte $c0,$dc,$c0,$df
.bend
; Defragment screen mem
;---------------------------------------
defragsc
.block
lda #7
sta screens
morescr lda #24
sta rows
morerow ldy #39
line lda (sp),y
sta (dp),y
dey
cpy #$02
bne line
lda #$00
clr sta (dp),y
dey
bpl clr
lda sp
sec
sbc #37
sta sp
bcs skip0
dec sp+1
skip0 lda dp
sec
sbc #40
sta dp
bcs skip1
dec dp+1
skip1 dec rows
bpl morerow
lda dp
sec
sbc #24
sta dp
bcs skip2
dec dp+1
skip2 dec screens
bpl morescr
rts
rows .byte $00
screens .byte $00
.bend
; Defragment bitmaps
;---------------------------------------
defragbm
.block
lda #24
sta linecnt
movemore ldy #$ff
loop0 lda (sp),y
sta (dp),y
dey
cpy #$ff
bne loop0
lda sp
sec
sbc #$40
sta sp
bcs skpd0
dec sp+1
skpd0 lda dp
sec
sbc #$40
sta dp
bcs skpd1
dec dp+1
skpd1 ldy #$3f
loop1 lda (sp),y
sta (dp),y
dey
cpy #$17
bne loop1
lda #$00
loop2 sta (dp),y
dey
bpl loop2
lda sp
sec
sbc #$e8
sta sp
bcs skip0
dec sp+1
skip0 dec dp+1
dec linecnt
bpl movemore
rts
linecnt .byte $00
.bend
; Shift ifli bitmaps up
;---------------------------------------
shiftfli
.block
sta sp+1
stx dp+1
ldx #$3c
lda #$90
sta sp
lda #$00
sta dp
ldy #$00
shftup lda (sp),y
sta (dp),y
iny
bne shftup
inc sp+1
inc dp+1
dex
bpl shftup
rts
.bend
; Clear off the two IFLI banks
; two IFLI banks
;---------------------------------------
clearfli
.block
lda #bank0
sta r1+1
lda #bank1
sta r2+1
ldx #$3f
lda #$00
tay
clear1 sta (r1),y
sta (r2),y
iny
bne clear1
inc r1+1
inc r2+1
dex
bne clear1
ldy #$3f
clear2 sta (r1),y
sta (r2),y
dey
bpl clear2
rts
.bend
raster = 45
; Main IRQ for ifli display
;---------------------------------------
irq0
.block
inc $d019
lda #irq0
sta $0315
jmp $ea81
irq1 lda $02a6 ; 4
beq addcyc1 ; 2
addcyc1 beq addcyc2 ; 2
addcyc2 nop ; 2
lsr r1 ; 5
nop ; 2
lda $d012 ; 4
cmp $d012
beq extra
extra
ldx #$09
wait dex
bpl wait
stx $d000
lda #$38
sta $d011
lsr r1
nop
bit r1
ldy #199
jmp (vidform)
.bend
morpal dey ; 2
beq endfli ; 2
pal lda $8700,y ; 4
sta $d018 ; 4
lda $8800,y ; 4
sta $d011 ; 4
jmp morpal ; 3
endfli
inc $d019
lda #$70
sta $d011
ldx #$70
border1 dex
bpl border1
lda $dd00
eor #$02
sta $dd00
lda $d016
eor #$01
sta $d016
lda #$38
sta $d011
lda #$08
sta $d018
lda #raster
sta $d012
jmp $ea81
morntsc dey ; 2
ntsc beq endfli ; 2
nop ; 2
lda $8700,y ; 4
sta $d018 ; 4
lda $8800,y ; 4
sta $d011 ; 4
jmp morntsc ; 3
vidform .byte pal
; Main FLI routine
;---------------------------------------
mainfli
.block
ldy #200
ldx #$07
victable lda stord018,x
sta $8700,y
lda stord011,x
sta $8800,y
dex
bpl skip18
ldx #$07
skip18 dey
bne victable
lda $02a6
bne setpal
lda #ntsc
sta vidform+1
jmp goon
setpal lda #pal
sta vidform+1
goon sta $d07a ; scpu off
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
lda $0314
sta storelo+1
lda $0315
sta storehi+1
lda #irq0
sta $0315
lda #$01
sta $d01a
sta $d019
lda #raster
sta $d012
lda #$38
sta $d011
cli
lda #$ff
sta $dc02
lda #$7f
sta $dc00
spacebar lda $dc01
and #$10
bne spacebar
sei
lda #$81
sta $dc0d
ldx #$00
stx $d01a
inx
stx $d019
storelo lda #$00
sta $0314
storehi lda #$00
sta $0315
sta $d07b ; scpu on
lda #$93
jsr $ffd2
rts
stord018 .byte $78,$68,$58,$48
.byte $38,$28,$18,$08
stord011 .byte $3f,$3e,$3d,$3c
.byte $3b,$3a,$39,$38
linecnt .byte $00
.bend
; RGB for c64's ntsc colors (18 bit)
; Offset by $40
;---------------------------------------
c64
.byte $40,$40,$40 ;0 black
.byte $7f,$7f,$7f ;1 white
.byte $6e,$4a,$40 ;2 red
.byte $54,$6d,$7f ;3 cyan
.byte $72,$44,$6c ;4 purple
.byte $4b,$6b,$57 ;5 green
.byte $4e,$42,$7f ;6 blue
.byte $7f,$77,$46 ;7 yellow
.byte $70,$53,$40
.byte $62,$7f,$40
.byte $7d,$5a,$4f
.byte $53,$53,$53
.byte $5d,$5d,$5d
.byte $5b,$7f,$6a
.byte $54,$58,$7f
.byte $69,$69,$69
; Credits
;---------------------------------------
.null "renderer by dw/style"
Back to dW's technical info home page