; 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+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; 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+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 sta zp+1 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 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 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]