;------------------------------------------------------------------------ INCLUDE "pk92lib.h" INCLUDE "tios.h" INCLUDE "flib.h" INCLUDE "gray4lib.h" INCLUDE "gray7lib.h" ;------------------------------------------------------------------------ ;------------------------------------------------------------------------ XDEF _library XDEF ugplib@0000 XDEF ugplib@0001 ;------------------------------------------------------------------------ ; The UGP-format: ;------------------ ; $0000.w: ; bit 0: 1 = animation; 0 = picture ; bit 1, 2: number of planes = (word >> 1) & 3 ; bit 3: 1 = interleaved; 0 = non-interleaved ; bit 4: compressed / uncompressed ; bit 5: only for animations: 1 = pictures stored as xor-difference ; to the last picture, 0 = pictures stored normal ; bit 6: 1= slide show instead of animation ; bit 7: unused ; bit 8-15: reserved for version info... currently: UGP_VERSION ; $0002.b: ; picture width ; $0003.b: ; picture height ; $0004.w ; if animation: number of pictures ; else: begin of picture data (if compressed: packer92 - archive, ; containingt hese data) ; $0006: ; begin of animation data (if compressed: packer92 - archive, ; containingt hese data) ;----- UGP version number, as it is stored within the UGP pics ---- UGP_VERSION EQU 1 ;----- UGP access - macros ---- ANIMAT EQU 0 PLANES EQU 1 INTERL EQU 3 COMPR EQU 4 XORDIF EQU 5 SLIDESHOW EQU 6 ;---------------------------------- ;DispNonInterl ;---------------------------------- ;Par: ; a4.w = offset of Pixel in VideoRAM ; d4.b = Number of Pixel 0..7 ; a1-a3.l = pointer to planes ; a0.l = pointer to raw picdata ; d3.b = UGP sign ; d5.b = 1: rplc 0: xor ; d6.w = Width, d7.w = Height ;Temp: ; a5 = Byte of Pic ; a6 = *putPlane DispNonInterl: movem.l d5-d7/a0/a5/a6, -(a7) lsr.w #3, d6 subq.w #1, d6 subq.w #1, d7 cmp.b #29, d6 bne \NotFullWidth lea putPlaneXorf(PC), a6 tst.b d5 beq \putXor lea putPlaneRplcf(PC), a6 bra \putXor \NotFullWidth: lea putPlaneXor(PC), a6 tst.b d5 beq \putXor lea putPlaneRplc(PC), a6 \putXor: lea 0(a1, a4.w), a5 ;most significant plane jsr (a6) btst #PLANES+1, d3 ;next plane (lsp if 2 planes) beq \EndDisp lea 0(a2, a4.w), a5 jsr (a6) btst #PLANES, d3 ;least significant plane (if 3 planes) beq \EndDisp lea 0(a3, a4.w), a5 jsr (a6) \EndDisp: movem.l (a7)+, d5-d7/a0/a5/a6 rts ;---------------------------- putPlanef -------------------------- ; Changed: a0, a5 (to next plane) putPlaneRplcf: move.w d7, -(a7) \YLoop: moveq.w #6, d5 ;put 7 longwords \_XLoop: move.l (a0)+, (a5)+ dbra d5, \_XLoop move.w (a0)+, (a5)+ ; + put 1 word = 30 Byte = 1 row dbra d7, \YLoop move.w (a7)+, d7 rts putPlaneXorf: movem.w d7/d6, -(a7) \YLoop: moveq.w #6, d5 ;xor 7 longwords \_XLoop: move.l (a0)+, d6 eor.l d6, (a5)+ dbra d5, \_XLoop move.l (a0)+, d6 ; + xor 1 word = 30 Byte = 1 row eor.l d6, (a5)+ dbra d7, \YLoop movem.w (a7)+, d7/d6 rts ;---------------------------- putPlane -------------------------- ; Changed: d5, a0, a5 (a0 points to next plane) putPlaneRplc: move.w d7, -(a7) \YLoop: movem.l d6/a5, -(a7) \_XLoop: move.w #$FF00, d5 ror.w d4, d5 and.b d5, (a5) lsr.w #8, d5 and.b d5, 1(a5) move.b (a0)+, d5 ror.w d4, d5 or.b d5, (a5)+ lsr.w #8, d5 or.b d5, (a5) dbra d6, \_XLoop \_XLpEnd: movem.l (a7)+, d6/a5 ;Pointer to next line moveq.l #30, d5 adda.l d5, a5 dbra d7, \YLoop \YLpEnd: move.w (a7)+, d7 rts putPlaneXor: move.w d7, -(a7) \YLoop: movem.l d6/a5, -(a7) \_XLoop: move.b (a0)+, d5 ror.w d4, d5 eor.b d5, (a5)+ lsr.w #8, d5 eor.b d5, (a5) dbra d6, \_XLoop \_XLpEnd: movem.l (a7)+, d6/a5 ;Pointer to next line moveq.l #30, d5 adda.l d5, a5 dbra d7, \YLoop \YLpEnd: move.w (a7)+, d7 rts ;---------------------------------- ;DispInterl ;---------------------------------- ;Par: ; a4.w = offset of Pixel in VideoRAM ; d4.b = Number of Pixel 0..7 ; a1-a3.l = pointer to planes ; a0.l = pointer to raw picdata ; d3.b = UGP sign ; d5.b = 1: rplc 0: xor ; d6.w = Width, d7.w = Height ;Temp: ; d0.b = WriteMask ; d1.b = ReadBit ; d2.b = ReadByte ; d3 = Planebyte0 ; d5 = Planebyte1 ; d7 = Planebyte2 DispInterl: movem.l d0-d3/d5-d7/a0-a3, -(a7) subq.w #1, d6 ;set Counters subq.w #1, d7 move.b #7, d1 ;set ReadBit moveq.b #-128, d0 ;set WriteMask lea 0(a1, a4), a1 ;set addresses for Plane0 & 1 lea 0(a2, a4), a2 tst.b d5 bne \AndPlane btst.b #PLANES, d3 bne \Xor3Planes bsr xorI2Plane bra \End \Xor3Planes: bsr xorI3Plane bra \End \AndPlane: btst.b #PLANES, d3 bne \And3Planes bsr putI2Plane bra \End \And3Planes: bsr putI3Plane \End: movem.l (a7)+, d0-d3/d5-d7/a0-a3 rts putI2Plane: clr.b d3 ;clear Plane0 & 1 clr.b d5 \YLoop: movem.l d6/a1-a2, -(a7) \_XLoop: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead move.b (a0)+, d2 \__DontRead: btst d1, d2 beq \__NoPlane0 or.b d0, d3 \__NoPlane0: addq.b #1, d1 ;Readbit += 1 btst d1, d2 beq \__NoPlane1 or.b d0, d5 \__NoPlane1: ror.b #1, d0 bcc \__DontWrite move.w #$FF00, d0 ;Clear pixels ror.w d4, d0 and.b d0, (a1) and.b d0, (a2) lsr.w #8, d0 and.b d0, 1(a1) and.b d0, 1(a2) ror.w d4, d3 ;Set pixels ror.w d4, d5 or.b d3, (a1)+ or.b d5, (a2)+ lsr.w #8, d3 lsr.w #8, d5 or.b d3, (a1) or.b d5, (a2) clr.b d3 clr.b d5 moveq.b #-128, d0 \__DontWrite: dbra d6, \_XLoop \_XLpEnd: movem.l (a7)+, d6/a1-a2 ;Pointer to next line moveq.l #30, d5 adda.l d5, a1 adda.l d5, a2 clr.b d5 dbra d7, \YLoop \YLpEnd: rts putI3Plane: clr.b d3 ;clear Plane0 & 1 clr.b d5 lea 0(a3, a4), a3 ;set address for Plane2 \YLoop: movem.l d6/d7/a1-a3, -(a7) clr.b d7 ;clear Plane2byte \_XLoop: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead move.b (a0)+, d2 \__DontRead: btst d1, d2 beq \__NoPlane0 or.b d0, d3 \__NoPlane0: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead1 move.b (a0)+, d2 \__DontRead1: btst d1, d2 beq \__NoPlane1 or.b d0, d5 \__NoPlane1: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead2 move.b (a0)+, d2 \__DontRead2: btst d1, d2 beq \__NoPlane2 or.b d0, d7 \__NoPlane2: ror.b #1, d0 bcc \__DontWrite move.w #$FF00, d0 ;Clear pixels ror.w d4, d0 and.b d0, (a1) and.b d0, (a2) and.b d0, (a3) lsr.w #8, d0 and.b d0, 1(a1) and.b d0, 1(a2) and.b d0, 1(a3) ror.w d4, d3 ;Set pixels ror.w d4, d5 ror.w d4, d7 or.b d3, (a1)+ or.b d5, (a2)+ or.b d7, (a3)+ lsr.w #8, d3 lsr.w #8, d5 lsr.w #8, d7 or.b d3, (a1) or.b d5, (a2) or.b d7, (a3) clr.b d3 clr.b d5 clr.b d7 moveq.b #-128, d0 \__DontWrite: dbra d6, \_XLoop \_XLpEnd: movem.l (a7)+, d6/d7/a1-a3 ;Pointer to next line moveq.l #30, d5 adda.l d5, a1 adda.l d5, a2 adda.l d5, a3 clr.b d5 dbra d7, \YLoop \YLpEnd: rts xorI2Plane: clr.b d3 ;clear Plane0 & 1 clr.b d5 \YLoop: movem.l d6/a1-a2, -(a7) \_XLoop: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead move.b (a0)+, d2 \__DontRead: btst d1, d2 beq \__NoPlane0 or.b d0, d3 \__NoPlane0: addq.b #1, d1 ;Readbit += 1 btst d1, d2 beq \__NoPlane1 or.b d0, d5 \__NoPlane1: ror.b #1, d0 bcc \__DontWrite ror.w d4, d3 ;Set pixels ror.w d4, d5 eor.b d3, (a1)+ eor.b d5, (a2)+ lsr.w #8, d3 lsr.w #8, d5 eor.b d3, (a1) eor.b d5, (a2) clr.b d3 clr.b d5 moveq.b #-128, d0 \__DontWrite: dbra d6, \_XLoop \_XLpEnd: movem.l (a7)+, d6/a1-a2 ;Pointer to next line moveq.l #30, d5 adda.l d5, a1 adda.l d5, a2 clr.b d5 dbra d7, \YLoop \YLpEnd: rts xorI3Plane: clr.b d3 ;clear Plane0 & 1 clr.b d5 lea 0(a3, a4), a3 ;set address for Plane2 \YLoop: movem.l d6/d7/a1-a3, -(a7) clr.b d7 ;clear Plane2byte \_XLoop: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead move.b (a0)+, d2 \__DontRead: btst d1, d2 beq \__NoPlane0 or.b d0, d3 \__NoPlane0: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead1 move.b (a0)+, d2 \__DontRead1: btst d1, d2 beq \__NoPlane1 or.b d0, d5 \__NoPlane1: addq.b #1, d1 ;Readbit += 1 bclr #3, d1 beq \__DontRead2 move.b (a0)+, d2 \__DontRead2: btst d1, d2 beq \__NoPlane2 or.b d0, d7 \__NoPlane2: ror.b #1, d0 bcc \__DontWrite ror.w d4, d3 ;Set pixels ror.w d4, d5 ror.w d4, d7 eor.b d3, (a1)+ eor.b d5, (a2)+ eor.b d7, (a3)+ lsr.w #8, d3 lsr.w #8, d5 lsr.w #8, d7 eor.b d3, (a1) eor.b d5, (a2) eor.b d7, (a3) clr.b d3 clr.b d5 clr.b d7 moveq.b #-128, d0 \__DontWrite: dbra d6, \_XLoop \_XLpEnd: movem.l (a7)+, d6/d7/a1-a3 ;Pointer to next line moveq.l #30, d5 adda.l d5, a1 adda.l d5, a2 adda.l d5, a3 clr.b d5 dbra d7, \YLoop \YLpEnd: rts ;------------------------------- ; Delay ;------------------------------- ; Parameters: ; d5.w: wait for time*(1/350) seconds ; ; If Slide Show (bit #SLIDESHOW set in d3): wait for keypress instead ; ; Regs: all registers are kept as they are ;------------------------------- Delay: movem.l d0-d7/a0-a6, -(a7) btst #SLIDESHOW, d3 beq \WaitDelay jsr flib::idle_loop bra \Exit \WaitDelay: move.w #$700, d0 trap #1 bclr.b #2, $600001 move.l $64, OldAutoInt1 move.l #\NewAutoInt1, $64 trap #1 \WaitLoop: tst.w d5 bne \WaitLoop move.w #$700, d0 trap #1 move.l OldAutoInt1(PC), $64 bset.b #2, $600001 trap #1 \Exit: movem.l (a7)+, d0-d7/a0-a6 rts \NewAutoInt1: tst.w d5 beq \d5Zero subq.w #1, d5 \d5Zero: move.l OldAutoInt1(PC), -(a7) rts ;************************************************************************ ;* Display * ;*----------------------------------------------------------------------* ;* Displays a ugp picture / animation (animation: for one cycle) * ;* Parameter: * ;* d0.w = x-position * ;* d1.w = y-position * ;* d2.w = Delay per Picture (for animations only) in 1/350 seconds * ;* a0.l = pointer to ugp-image (mustn't be odd address) * ;* a1.l = pointer to most-significant plane * ;* a2.l = pointer to plane with the next significance (2 greyplanes) * ;* a3.l = pointer to least-significant plane (3 greyplanes) * ;* Output: * ;* d3.b = 0: Ok, FF: Error * ;* Registers: * ;* nothing is destroyed * ;************************************************************************ ;Temp: ; d6.w = Width, d7.w = Height ; a4.w = picture offset in videoram ; d4.b = picture bit begin 0..7 ; d3.b = UGP sign ; a0.w = pointer to raw picdata ; a6.w = stored pointer -^ (if ani) ; d1.w = num of pics (if ani) ; d2.w = Picture count ugplib@0000: movem.l d0-d7/a0-a6, -(a7) cmp.b #UGP_VERSION, (a0)+ ;check version-byte bgt \DispErr move.b (a0)+, d3 ;d3 = UGP-sign clr.w d6 ;d6 x d7 = Width x Height clr.w d7 move.b (a0)+, d6 move.b (a0)+, d7 ;a0 = *PicData move.w d1, d5 ;d5 = *PicBegin mulu #30, d5 move.w d0, d4 lsr.w #3, d4 add.w d4, d5 move.w d5, a4 move.b d0, d4 ;d4 = Pixel andi.b #7, d4 btst #ANIMAT, d3 beq \NoAni move.w (a0)+, d1 ;Pics = Pics-2 (for dbra-loop) movea.l a0, a6 ;a6 = a0 subq.w #2, d1 move.w d2, DelayTime clr.w d0 \NoAni: ;---------------- put Picture --------------- btst #COMPR, d3 beq \PicNotCompr movem.l a1/d1, -(a7) jsr pk92lib::Extract tst.b d0 bne \DispErr movea.l a1, a0 movem.l (a7)+, a1/d1 \PicNotCompr: st d5 ;put Picture rplc btst #INTERL, d3 bne \PicInterl bsr DispNonInterl bra \PicEnd \PicInterl: bsr DispInterl \PicEnd: btst #COMPR, d3 beq \AniTest jsr pk92lib::FreeMem \AniTest: ;--------------- Animation -------------- btst #ANIMAT, d3 beq \DispOk clr.w d2 ;picCount = 0 move.w DelayTime(PC), d5 bsr Delay \AniLp: addq.w #1, d2 ;-------- get Add of Pic ------ btst #COMPR, d3 beq \AniUnC movem.l a1/d1/d2, -(a7) move.w d2, d0 movea.l a6, a0 jsr pk92lib::Extract tst.b d0 bne \DispErr movea.l a1, a0 movem.l (a7)+, a1/d1/d2 bra \ShowAniPic \AniUnC: move.w d6, d5 ;Pic-Size to d5 mulu.w d7, d5 move.w d3, d4 lsr.w #1, d4 andi.w #3, d4 mulu.w d4, d5 lsr.w #3, d5 ;add to a0 mulu.w d2, d5 lea 0(a6, d5.w), a0 \ShowAniPic: btst #XORDIF, d3 seq d5 btst #INTERL, d3 beq \AniNonI bsr DispInterl bra \Show_Done \AniNonI: bsr DispNonInterl \Show_Done: btst #COMPR, d3 beq \AniLpCond jsr pk92lib::FreeMem \AniLpCond: move.w DelayTime(PC), d5 bsr Delay dbra d1, \AniLp \DispOk: movem.l (a7)+, d0-d7/a0-a6 clr.b d3 rts \DispErr: movem.l (a7)+, d0-d7/a0-a6 st d3 rts ;************************************************************************ ;* AutoDisp * ;*----------------------------------------------------------------------* ;* Displays a UGP - Picture automatically, switches to the right gray- * ;* mode, clears the screen, shows the picture/animation/slide show until* ;* key is pressed, in the middle of the screen. * ;* Parameter: * ;* a0 = Ptr. to UGP-pic(/ani) * ;* d2.w = Delaytime for animations in 1/350 seconds * ;* Return: * ;* d0 = 0: OK = 1: Error * ;************************************************************************ ugplib@0001: movem.l a0-a6/d1-d7, -(a7) move.b 1(a0), d0 ;d0 = UGP-sign lea tios::main_lcd, a1 ;Plane1 = 4440 move.l a1, a5 bsr \delPlane lea \JustRts(PC), a6 btst #PLANES, d0 bne \PlaneNum1or3 jsr gray4lib::on ;2 Planes move.l gray4lib::plane0, a2 move.l a2, a5 bsr \delPlane lea gray4lib::off, a6 bra \ShowUGP \PlaneNum1or3: btst #PLANES+1, d0 beq \ShowUGP movem.l a0/d2, -(a7) jsr gray7lib::on ;3 Planes movem.l (a7)+, a0/d2 lea gray7lib::off, a6 move.l gray7lib::plane0, a3 move.l gray7lib::plane1, a2 move.l a2, a5 bsr \delPlane move.l a3, a5 bsr \delPlane tst.l d0 bne \ShowUGP st d0 bra \AbortDisp \ShowUGP: move.w #240, d0 move.w #128, d1 sub.b 2(a0), d0 lsr.w #1, d0 sub.b 3(a0), d1 lsr.w #1, d1 lea tios::kb_vars+$1C, a5 ;KeysInBuffer-Address in a5 clr.w (a5) \Display: bsr ugplib@0000 tst.b d3 bne \AbortDisp btst.b #ANIMAT, 1(a0) beq \AbortDispWait btst.b #SLIDESHOW, 1(a0) bne \AbortDisp tst.w (a5) beq \Display \AbortDisp: clr.w (a5) ;clear keaboard buffer move.b d3, d0 ;errorflag to d0, wait move.b d0, -(a7) jsr (a6) ;switch off grayscale move.b (a7)+, d0 movem.l (a7)+, a0-a6/d1-d7 \JustRts: rts \AbortDispWait: jsr flib::idle_loop bra \AbortDisp \delPlane: ;Add of Plane in a5 move.w #959, d7 ;d7/a5 is destroyed \delLoop: clr.l (a5)+ dbra d7, \delLoop rts ;---------------------------------------- DelayTime: dc.w 0 OldAutoInt1: dc.l 0 ;---------------------------------------- ;---------------------------------------- _library dc.b "ugplib", 0 ;---------------------------------------- END