;Signum! image decompressoion code for PureC ;code taken from Imagic demo -> denisdem.prg ;size of unpacked data is always 32000 bytes (st high resolution) ;dis-assembled and modified by Lonny Pursell ;--------------------------------------------------------------------------- ;rockyone Adapted for MI-3 and Mi-9 14.08.2019 ;check 04.03.2025 ;Optimise 15.03.2025 ;ajout test file size 19.03.2025 ; .......................................................................... ; ; Unpack: Signum2's ".IMC" file ; Creator.prg ".IMC" file ; ; ; buf_pic 32046 bytes Whatever the size of the IMC file ; buf_ecr 32034 bytes For the image PI3 ; ; 60 64 68 70 ; Call ( L buf_pic, L buf_ecr,W dummy%,W low(File_size%) ) ; ;Return 0 in d0 goog file ; -2 in d0 bad file ; -4 in d0 image too big ; ;-------------------------------------------------------------------------- ; ; +0 L Id file 'bimc' ; +4 L version ? '0002' ; +8 L File size -8 (unused by "creator.prg") ; +12 W Width of the image in pixels 640 pisel Alway ? ; +14 W Heiht of the image in pixels 400 pixel Alway ? ; +16 W Alway $28 = #40 Always ? ; +18 W Alway >= $19 = #25 ; +20 L size control byte ; +24 L size daya compressed ; +28 W Mask for "eor" with the words ; +30 ? ? ; +40 Address of control bytes ; +40+offset_adr Address of data image compresed ? ; ;-------------------------------------------------------------------------- ; d7 ; a0 a3 Buffer source ; a1 a2 -10(a4) -14(a4) Buffer destination movem.l d1-d7/a0-a6,-(sp) movem.l 60(sp),a0-a1 ; buffers source and detination move.w 70(SP),d7 ; file size ext.l d7 subq.l #8,d7 ;....................................... moveq.l #-2,d0 ; error file cmp.l #'bimc',(a0)+ ; Id file ? bne error ; <> cmp.l #'0002',(a0)+ ; Version ? bne error ; <> cmp.l (a0),d7 ; Size-8 unused by "Creator.prg" bne.s error ; <> moveq.l #-4,d0 ; error size cmp.w #$0280,4(a0) ; Width ? bhi.s error ; > cmp.w #$0190,8(a0) ; Height ? bhi.s error ; > ; --------------------------------------- ; Clearing the destination buffer ; --------------------------------------- movea.l a1,a2 ; Start destination move.l #32034/8-1,d7 ; clean buffer ! cls_buffer: clr.l (a2)+ clr.l (a2)+ dbra.w d7,cls_buffer move.w #2,(a1)+ ; Write resol move.l #$fff0000,(a1) ; Write two colors ; --------------------------------------- ; ; --------------------------------------- lea.l 32(a1),a2 ; Start of the destination image lea.l 32046(a0),a4 ; Buffer of work. 46 bytes ; To -46, 32 bytes for the data convesion move.w 8(a0),-2(a4) ; number of words per line >0 x <=40 move.w 10(a0),-4(a4) ; number of line blocks subq.w #1,-2(a4) ; -1 for dbra move.l a2,-10(a4) ; Backup for revers bits image. move.w 20(a0),-6(a4) ; Stores the EOR mask movea.l 12(a0),a5 ; offset address of compressed data lea.l 32(a0),a6 ; Point to the control table adda.l a6,a5 ; start of compressed data movem.l (a2),d0-d6 ; clr moveq.l #80,d7 ; Offset for next line ; --------------------------------------- ; Block decompression loop ; d4 here only ! ; --------------------------------------- move.w -4(a4),d4 ; Number of blocks (25 lines) subq.w #1,d4 ; -1 for dbra all_block: bsr.s set_carry ; Check the control bit bcc.s c_0 ; If 0? we jump bsr.s decompress_block ; Decompression of a block c_0: adda.l #80*16,a2 ; Next block dbra.w d4,all_block ; 25 * 16 = 400 ; --------------------------------------- ; Reverse bits if needed ; --------------------------------------- tst.w -6(a4) ; Check if an EOR mask is applied bne revers_bits ; If yes, we invert the bits ; --------------------------------------- ; End of routine ; --------------------------------------- _end: moveq.l #0,d0 ; good file error: movem.l (sp)+,d1-d7/a0-a6 rts ; --------------------------------------- ; Block decompression (16 lines) ; --------------------------------------- decompress_block: move.l a2,-14(a4) ; Save destination buffer address move.w -2(a4),d3 ; Get width (40 words) boucle_line: bsr.s set_carry ; Checks a control bit bcc.s next_word ; If 0 we jump bsr.s copy_byte ; Otherwise, we copy the bytes next_word: addq.l #2,-14(a4) ; next word dbra.w d3,boucle_line ; Repeat for the whole line rts ; --------------------------------------- ; Set the carry bit in the CCR ; d5-d6 only here ! ; --------------------------------------- set_carry: subq.w #1,d5 ; bits counter bpl.s loop_2 ; >0 moveq.l #7,d5 ; Reset d5 move.b (a6)+,d6 ; Read contol byte loop_2: lsl.b #1,d6 ; Shift the most significant bit rts ; --------------------------------------- ;Reads and processes a compressed byte ; --------------------------------------- read_compressed_byte: movea.l a3,a0 move.b (a5)+,d1 ; Reads a compressed byte beq.s end_copy moveq.l #7,d0 byte_loop: lsl.b #1,d1 ; Shift bits one by one bcc.s next_octet move.b (a5)+,(a0) ; Stores the uncompressed byte next_octet: addq.l #2,a0 dbra.w d0,byte_loop end_copy: rts ; --------------------------------------- ; Copy decompressed bytes ; ; --------------------------------------- copy_byte: movem.l d3/a3,-(sp) moveq.l #0,d3 bsr.s set_carry bcc.s c_02 addq.w #2,d3 c_02: bsr.s set_carry bcc.s c_03 addq.w #1,d3 c_03: lea.l -46(a4),a3 ;32 bytes working buffer movea.l a3,a0 cmpi.w #3,d3 beq.s in_work ; rts here clr.l (a0)+ -46 clr.l (a0)+ -42 clr.l (a0)+ -38 clr.l (a0)+ -34 clr.l (a0)+ -30 clr.l (a0)+ -26 clr.l (a0)+ -22 clr.l (a0)+ -18 bsr.s set_carry bcc.s c_04 bsr.s read_compressed_byte c_04: addq.l #1,a3 bsr.s set_carry bcc.s c_05 bsr.s read_compressed_byte c_05: lea.l 15(a3),a3 bsr.s set_carry bcc.s c_06 bsr.s read_compressed_byte c_06: addq.l #1,a3 bsr.s set_carry bcc.s c_07 bsr.s read_compressed_byte ; ....................................... c_07: lea.l -46(a4),a0 ; buffer out work cmpi.w #1,d3 beq.s op_16_W ; rts here cmpi.w #2,d3 beq.s op_8_LW ; rts here bra.s out_work ; rts here ; --------------------------------------- ; XOR operations on 16 words ; --------------------------------------- op_16_W: move.w (a0)+,d0 moveq.l #14,d2 loop_4: move.w (a0),d1 eor.w d1,d0 move.w d0,(a0)+ dbra.w d2,loop_4 bra.s out_work ; rts here ; --------------------------------------- ; XOR operations on with 8 long words ; --------------------------------------- op_8_LW: move.l (a0)+,d0 moveq.l #6,d2 loop_5: move.l (a0),d1 eor.l d1,d0 move.l d0,(a0)+ dbra.w d2,loop_5 bra.s out_work ; rst here ;......................................Copy 16 bytes in buffer of work in_work: moveq.l #7,d0 copy_bytes: move.b (a5)+,(a0)+ move.b (a5)+,(a0)+ move.b (a5)+,(a0)+ move.b (a5)+,(a0)+ dbra.w d0,copy_bytes out_work: lea.l -46(a4),a0 movea.l -14(a4),a1 moveq.l #3,d0 ;......................................Copy the 16 Working of destination copy_Words: move.w (a0)+,(a1) adda.l d7,a1 ; Next line move.w (a0)+,(a1) adda.l d7,a1 move.w (a0)+,(a1) adda.l d7,a1 move.w (a0)+,(a1) adda.l d7,a1 dbra.w d0,copy_Words movem.l (a7)+,d3/a3 rts ; --------------------------------------- ; invert bits if n‚cessary ; --------------------------------------- revers_bits: movea.l -10(a4),a3 ; Start image destination moveq.l #0,d0 move.b -6(a4),d0 ; Mask bsr.s revers ; Start line 0 adda.w d7,a3 ; next line moveq.l #0,d0 move.b -5(a4),d0 ; Mask bsr.s revers ; Start line 1 bra _end ; ....................................... revers: movea.l a3,a2 move.w d0,d1 lsl.w #8,d1 or.w d1,d0 move.w -4(a4),d1 ; <= 25 blocs asl.w #3,d1 ; 200 line max subq.l #1,d1 ; -1 for debra d_1: movea.l a2,a1 move.w -2(a4),d2 ; 40-1 d_2: eor.w d0,(a1)+ dbra.w d2,d_2 ; 40 words lea.l 80(a1),a2 ; next line dbra.w d1,d_1 rts end ;-------------------------------------------------------------------------