Schrijver
| Age's CMP format
| snout
 msx legend Berichten: 4991 | Geplaatst: 20 November 2003, 02:03   | This question from Gerald Stap remained unanswered on Usenet and mailinglists, maybe someone over here can help out?
Hi,
Does anyone have any information regarding the encoding and decoding of
screen 5 pictures in CMP format? CMP is the format that DD-GRAPH/AGE
uses for compressed screen 5 pictures and is seems to be very efficient.
But I've never seen any document or article about how CMP works.
I've got this snippet of code. Don't know where it's from or if it
actually works. I'm more intereseted in the theory behind CMP so I can
write my own encoder/decoder.
Note: Comments are a mix of dutch/english
=============
; UNCRUNCH ROUTINE T&E SOFT
;
; IN: HL= RAMADRES CRUNCH DATA
; DE= COORDINATEN IN VRAM
; A = VRAM PAGE (0,1,2,3)
;
CMPER:: JP USTART
;
UVARIA: DB 0 ;&H4EC0 ;&HE000 ; 1 BYTE
UTABEL: DB 0,0,0,0,0,0,0,0 ;&H4EC1 ;&HE001 ; 8 BYTES
UTABE2: DW 0,0,0,0,0,0,0,0,0,0 ;&H4EC9 ;&HE009 ;
MAX. 256 B
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
;
USKIP EQU 0FEH
UVDP EQU 98H
;
UROUT1: XOR A
SLA B
JR NC,X1
LD A,(HL)
INC HL
X1: DEC C
RET NZ
PUSH AF
LD A,(DE)
LD B,A
LD A,E
CP UTABE2 MOD 256
JR NZ,X2
DEFB USKIP ; PUSH AF won't be executed now !
ROUTIN: PUSH AF
LD C,(HL)
INC HL
LD DE,UTABEL
LD B,8
X4: XOR A
SLA C
JR NC,X3
LD A,(HL)
INC HL
X3: LD (DE),A
INC DE
DJNZ X4
LD DE,UTABEL
LD A,(DE)
LD B,A
X2: INC DE
LD C,8
POP AF
RET
USTART: LD B,A
SRL A
LD (UVARIA),A
LD A,D
LD D,E
LD E,A
XOR A
SRL D
RRA
ADD A,E
LD E,A
JR NC,X5
INC D
X5: BIT 0,B
JR Z,X6
SET 7,D
X6: PUSH DE
LD B,(HL)
INC HL
LD C,(HL)
INC HL
LD A,(HL)
INC HL
EX AF,AF
PUSH BC
CALL ROUTIN
EXX
POP BC
POP HL
DEFB USKIP ; EX AF,AF won't be executed now
X8: EX AF,AF
PUSH BC
LD A,(UVARIA)
CALL USETWR
LD DE,UTABE2
X7: EXX
CALL UROUT1
EXX
LD (DE),A
INC DE
OUT (C),A
DJNZ X7
EI
LD C,128
ADD HL,BC
POP BC
DEC C
RET Z
EX AF,AF
DEC A
JP NZ,X8
X9: PUSH BC
LD A,(UVARIA)
CALL USETWR
LD DE,UTABE2
EX DE,HL
X10: EXX
CALL UROUT1
EXX
XOR (HL)
LD (HL),A
INC HL
OUT (C),A
DJNZ X10
EI
EX DE,HL
LD C,128
ADD HL,BC
POP BC
DEC C
JP NZ,X9
LD B,E
LD B,C
LD D,E
RET
;
USETWR: DI
PUSH BC
PUSH HL
LD C,H
RL C
RLA
RL C
RLA
OUT (UVDP+1),A
LD A,8EH
OUT (UVDP+1),A
LD C,UVDP+1
OUT (C),L
RES 7,H
SET 6,H
OUT (C),H
POP HL
POP BC
LD C,UVDP
RET
EINDE: NOP
; EINDE UNCRUNCH ROUTINE
END
| | GuyveR800 msx guru Berichten: 3048 | Geplaatst: 20 November 2003, 05:40   | Spent a bit of time on the routine.
It's a fairly efficient (for graphics) line difference compression.
I cut out some unimportant VRAM address setup stuff, added some comments. You should be able to figure out the file format quite easily now. But it's easier to just use the routine as-is, since it's about as optimal as it gets.
; IN: HL= RAMADRES CRUNCH DATA
;
CMPER:: JP USTART
;
UVARIA: DB 0 ;&H4EC0 ;&HE000 ; 1 BYTE
UTABEL: DB 0,0,0,0,0,0,0,0 ;&H4EC1 ;&HE001 ; 8 BYTES
LineBuffer: DW 0,0,0,0,0,0,0,0,0,0 ;&H4EC9 ;&HE009 ; MAX. 256 B
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
DW 0,0,0,0,0,0,0,0,0,0
USTART:
LD B,(HL) ; load picture width (in bytes)
INC HL
LD C,(HL) ; load picture height (number of lines)
INC HL
LD A,(HL) ; load number of unxored lines
INC HL
EX AF,AF' ; store number of unxored lines
PUSH BC
CALL FillUTABLE
EXX
POP BC
ld hl,VRAMAddress
EX AF,AF' ; load number of unxored lines
Loop1: EX AF,AF' ; store number of unxored lines
PUSH BC
VRAM write address = HL
LD DE,LineBuffer
.loop: EXX
CALL UROUT1
EXX
LD (DE),A
INC DE
OUT (98h),A
DJNZ .loop
LD BC,128 ; next line
ADD HL,BC
POP BC
DEC C
RET Z ; quit if number of lines already reached
EX AF,AF' ; load number of unxored lines
DEC A
JP NZ,Loop1
Loop2:
PUSH BC
VRAM write address = HL
EX DE,HL
LD HL,LineBuffer
.loop: EXX
CALL UROUT1
EXX
XOR (HL)
LD (HL),A
INC HL
OUT (98h),A
DJNZ .loop
EX DE,HL
LD BC,128 ; next line
ADD HL,BC
POP BC
DEC C ; loop until number of lines reached
JP NZ,Loop2
RET
UROUT1: XOR A
SLA B
JR NC,.skip
LD A,(HL) ; read byte to output
INC HL
.skip: DEC C
RET NZ
PUSH AF
LD A,(DE)
LD B,A
LD A,E
CP LineBuffer & 255
JR NZ,ROUTIN.end
POP AF
FillUTABLE: PUSH AF
LD C,(HL)
INC HL
LD DE,UTABEL
LD B,8
.loop: XOR A
SLA C
JR NC,.skip
LD A,(HL)
INC HL
.skip: LD (DE),A
INC DE
DJNZ .loop
LD DE,UTABEL
LD A,(DE)
LD B,A
.end: INC DE
LD C,8
POP AF
RET
| | ro msx guru Berichten: 2346 | Geplaatst: 20 November 2003, 13:18   | So, Guyver, based on your findings would u b able to write a sheet describing the file format?
| | GuyveR800 msx guru Berichten: 3048 | Geplaatst: 20 November 2003, 19:43   | I would, it'd just take more time than I can invest in it at the moment.
Besides, the source is really simple and clear. Any intermediate programmer can understand it and write up a format description.
| |
| |
| |