
; the FLI viewer code was ripped from Loadstar's Video FLI'er in LS #166
; but it as off by as much as a half cycle too late, so I added a forced
DMA
; trigger to syncronize the FLI display part to interlace nicely w/ each
other.
; NTSC IFLI module by Todd S. Elliott
; For the FunPainter II IFLI file format.
; The code was originally used in FileMaster, a program that appeared in
; Loadstar #176. Go to www.loadstar.com and order that disk ASAP, if you
; want to view FunPainter II files created by Godot. :)

; equates for the IFLI displayer
r6510  = $01
; these can be moved elsewhere.
iflag  = $02
zp     = 251
; hardware equates
iirq   = $0314
vidata = $83e8
gfxdat = $a3e8
vidram = $c000
scroly = $d011
raster = $d012
scrolx = $d016
vmcsb  = $d018
vicirq = $d019
irqmsk = $d01a
bckgnd = $d021
scpu'1MHz = $d07a
scpu'20MHz = $d07b
scpuver = $d0b0
scpudet = $d0bc
ciapra = $dc00
ciaprb = $dc01
ciaicr = $dc0d
ci2pra = $dd00
reudma = $df00
gfxram = $e000

fun'paint'ii =*; this MUST fall on a page boundary such as $3000, $3100,
etc.
  lda #$00
  sta border
  sta bckgnd; paint the screen black- if this has already been done by
the
            ; superboot program and cannot be changed by the user, then
it
            ; can be omitted.

; jsr detect'hardware; detect the SCPU and REU

; lda reuflag; if REU is present, then proceed - this was set by the
             ; previous jsr detect'hardware call.
; bne +
; rts; otherwise, abort the IFLI routines.

+ ldx #$90; pass parameter to the following JSR
  jsr xfer'REU; saves the memory contents of affected RAM regions.
  jsr open'fp2'file; opens the funpainterii file
  ldy #$10; skip the first 15 characters
- jsr chrin
  dey
  bpl -
  sta decomp; save it temporarily
  cmp #$00; check the decomp flag in the file
  bne +
  jsr chrin; get rid of the decomp indicator byte
  jmp ++; and go ahead to the decomper routine
+ jsr chrin; get the decomp indicator byte
  sta decomp; store the decomp indicator byte
; Now, we are ready to read the entire file and decomp if necessary
+ jsr decomp'data
  jsr clrchn; restores default i/o
  lda #$02; LFN
  jsr close; close the funpainterii file- the program is done with it.
  jsr prep'fp2'for'display; preps the data for actual display

  lda scpu'flag; if SCPU is present, slow it down to 1MHz.
  beq +        ; the flag was set by the detect'hardware call
  sta scpu'1MHz; switch it to 1MHz.

+ lda #<ifli'switch
  sta iirq
  lda #>ifli'switch
  sta iirq+1; wedges in the IFLI routine in c64's interrupt scheme

  lda #%00011000; clear msb of raster register
  sta scroly
  lda #$00; start raster line for IRQ FLIroutine
  sta raster
  lda #$01
  sta irqmsk; enable raster interrupts
  lsr vicirq; acknowledge raster interrupts
  lda ciaicr; acknowledge cia #1 interrupts
  cli

  lda #$7f; select a row on the keyboard matrix
  sta ciapra
- lda ciaprb; check for the SPACE keypress
  cmp #$ef; this method is used to detect the keyboard as the keyscan
routine
  bne -   ; is disabled while the IFLI routine is running.

  lda scpu'flag; if a SCPU is present, switch it back up to 20MHz.
  beq +        ; the flag was set during the jsr detect'hardware call.
  sta scpu'20MHz; switch it to 20MHz.

+ sei
  lda #$31
  sta iirq
  lda #$ea
  sta iirq+1; restore the IRQ vector
  lda #$97
  sta ci2pra; select VIC bank 0
  lda #$c8
  sta scrolx; turn off MCM
  lda #$14
  sta vmcsb; set video ram defaults
  lda #%00011011; resynchronize the text screen
  sta scroly; clear MSB of raster interrupt and restores charset mode
  lda #$81
  sta ciaicr; turn on CIA interrupts
  lda #$00
  sta vicirq; acknowledge raster interrupts
  sta irqmsk; and disable raster interrupts
  cli

  ldx #$91; pass parameter to the following JSR
  jsr xfer'REU; restores program data from the REU
  rts

fli =*; the actual FLI routine
      ; You could use this same routine for displaying plain vanilla FLI
files
      ; the only problem is that this routine will attempt to call the
IFLI
      ; portion and that is a no-no for plain vanilla FLI files.
  nop
  bit $ea
  bit $ea
  bit $ea
  bit $ea
  bit $ea
  ldx #$1a; for 25 rows
  nop; originally, the minus temp label was here in the original
VIDEOFLI'er
  nop; disassembled source code.
  nop

; this is the syncronization VIC marker for the IFLI display. Without
this
; routine, the FLI portion of the IFLI display would be by an half-cycle
to
; a full cycle late and as a result, white speckles will form on the
first
; rasterline.

  lda #$08
  sta vmcsb; switch videoram bank
  lda #$3a
  sta scroly; VICDMAretrigger- forces badlines
  cmp $00,x ; and syncronize the IFLI display
- cmp $00,x
  cmp $00

; normal FLI display as originally in VIDEO FLI'er starts here.
  lda #$08
  sta vmcsb; switch videoram bank
  lda #$3b
  sta scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$18
  sta vmcsb; switch videoram bank
  inc scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$28
  sta vmcsb; switch videoram bank
  inc scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$38
  sta vmcsb; switch videoram bank
  inc scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$48
  sta vmcsb; switch videoram bank
  inc scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$58
  sta vmcsb; switch videoram bank
  lda #$38
  sta scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$68
  sta vmcsb; switch videoram bank
  inc scroly; VICDMAretrigger- forces badlines
  cmp ($00,x)
  cmp $00,x
  cmp $00

  lda #$78
  sta vmcsb; switch videoram bank
  inc scroly; VICDMAretrigger- forces badlines

  dex; decrement row counter
  bne -; if not at the end of screen, repeat the FLI effect
       ; the BNE must branch back within the same page or an additional
       ; cycle will result and then the IFLI display is mucked up.

  lda #<ifli'switch; if you want to reuse the FLI routine for displaying
  sta iirq         ; regular FLI pictures, then you would need to get rid
of
  lda #>ifli'switch; this with a JMP $ea31 or $ea81 a la self-modifying
code.
  sta iirq+1; wedges in the IFLI routine in c64's interrupt scheme

  lda #$1b
  sta scroly; clear MSB of raster compare
            ; need to change RASTER register for IFLI mode
  lda #$00; start raster line for IRQ FLI routine
  sta raster
  inc vicirq; acknowledge raster interrupts
  pla; restore registers
  tay
  pla
  tax
  pla
  rti

; jmp $ea81- jmp into normal c64 IRQ interrupt handler

ifli'switch =*; Switches screens
  lda iflag; check IFLI flag
  beq +
  lda #$02; select VIC bank 1
  sta ci2pra; switch video banks
  lda #%00011000; move the screen back to normal
  sta scrolx
  inc iflag; toggle the IFLI flag
  beq ++

+ lda #$00; select VIC bank 3
  sta ci2pra; switch video banks
  lda #%00011001; shift the entire screen one pixel
  sta scrolx
  dec iflag; toggle the IFLI flag

+ lda #<fli
  sta iirq
  lda #>fli
  sta iirq+1; wedges in the FLI routine in c64's interrupt scheme

  lda #$1b
  sta scroly; clear MSB of raster compare
            ; need to change RASTER register for IFLI mode
  lda #$31; start raster line for IRQ FLI routine
  sta raster
  inc vicirq; acknowledge raster interrupts
  pla; restore registers
  tay
  pla
  tax
  pla
  rti

; jmp $ea81- jmp into normal c64 IRQ interrupt handler

; preps the funpainterii raw data for actual display by the IFLI routine
prep'fp2'for'display =*
  ldx #$00; set up the IFLI screen
- lda $8000,x
  sta $d800,x
  lda $8100,x
  sta $d900,x
  lda $8200,x
  sta $da00,x
  lda $8300,x
  sta $db00,x; transfer color nybbles to color RAM
  inx
  bne -
  lda #$ff; set the IFLI toggle
  sta iflag

  sei
  lda #$7f
  sta ciaicr; turn off cia #1 interrupts

  lda r6510
  and #%11111000; activate CHAREN, turn off BASIC+KERNAL
  sta r6510

  lda #<gfxdat; get graphics data
  sta zp
  lda #>gfxdat
  sta zp+1
  lda #<gfxram
  sta zp+2
  lda #>gfxram; and store it in the proper offset
  sta zp+3
  jsr move'32'pages; shove 32 pages of graphics data
  lda #>vidata; get video ram data
  sta zp+1
  lda #>vidram; into their respective 1K banks
  sta zp+3
  jsr move'32'pages; shove 32 pages of graphics data

  lda r6510
  ora #%00000111; restore i/o, BASIC and KERNAL
  sta r6510
  rts

move'32'pages =*
  ldx #31
  ldy #$00
- lda (zp),y
  sta (zp+2),y
  iny
  bne -
  inc zp+1
  inc zp+3
  dex
  bpl -
  rts

xfer'REU =*; transfer program data to the REU first
           ; .X is passed to indicate direction of REU+CBM transfer
           ; $90 for CBM-->REU, or $91 for REU-->CBM.
  lda #<reudata; transfer program data to the REU
  sta zp
  lda #>reudata
  sta zp+1
  jsr set'reu'for'transfer; transfers the actual data between c64+REU
  stx reudma+1
  rts

decomp'data =*; reads in the graphics data and decompresses along the way
  lda #$00
  sta zp
  lda #$40; start decomping to $4000 onwards
  sta zp+1
  ldx #132; move 33K
  ldy #$00
  lda decomp; check to see if there needs to be some decomping done
  bne ++
- jsr chrin; get picture data from the file
  sta (zp),y; and store it
  lda $90; check status
  cmp #$40; test for EOF
  beq +; if so, then finish the routine
  iny
  bne -
  inc zp+1; increment high byte
  dex; decrement overall counter
  bne -
+ rts; exits the decomper

/ jsr chrin; get picture data from the file
  cmp decomp; is it the decomp indicator byte?
  beq +; if so, go to the repeat byte sequencer
  sta (zp),y; store it
- iny
  bne --
  inc zp+1; increment high byte
  dex; decrement overall counter
  bne --
- rts; exits the decomper

+ jsr chrin; get the repeat byte indicator from the file
  beq -; if equal to zero, we're done with decomping
  sta iflag; and save it as index counter
  jsr chrin; get the byte that is to be repeated (decomped).
- sta (zp),y; stores it into the IFLI region
  dec iflag; decrement the index counter
  beq ---; If equal to zero, we're done repeating the byte
  iny
  bne -
  inc zp+1; increment high byte
  dex; decrement overall counter
  bne -
  rts; exits the decomper

; REU memory management routine
set'reu'for'transfer =*
  ldy #$06
- lda (zp),y
  sta reudma+2,y; sets up the REU
  dey
  bpl -
  rts

; opens the funpainterii file
open'fp2'file =*
  lda #$02; LFN
  ldx device; dev number
  ldy #$02; OPEN2,8,2 equivalent
  jsr setlfs
  lda #14; filename length
  ldx #<fpii'filename
  ldy #>fpii'filename
  jsr setnam
  jsr open; finally opens the FunPainterII file
          ; may want to check for an error here.
  ldx #$02
  jsr chkin; redirect input to that file
  rts

; data
reudata =*
; 64 LSB, 64 MSB, REU LSB, REU MSB, REU Bank, Transfer LSB, Transfer MSB
.byte $00,$40,$00,$00,$00
.word last'byte; transfer RAM to the reu from $4000-$xxxx
               ; where $xxxx is last byte of program.

; Flags, Constants and Variables
scpu'flag = *
.buf 1
reuflag = *
.buf 1
decomp =*; decomp indicator byte
.buf 1

fpii'filename =*; filename of sample funpainter ii file.
                ; Note: the carets (^) are actually up-arrows
                ; in PETASCII
.byte "^^filename,p,r", 0

; end file ifliroutines

___________________________________________________________________
You don't need to buy Internet access to use free Internet e-mail.
Get completely free e-mail from Juno at http://www.juno.com/getjuno.html
or call Juno at (800) 654-JUNO [654-5866]

