; Cards 2.0 object file
; by Thomas Lack¢, http://togye.host.sk
IDEAL
MODEL LARGE,PASCAL
P386

DATASEG

  MaxCards = 59
  InnerCardSize = 68*96
  extrn CardCount:word,CardDataSize:word,PackerColor:byte
  extrn CardData:dword ; struct { void* Data, short Size } *CardData

CODESEG

public GetCardImage

proc RGB near ; DH:DL:AL ® red:green:blue, AX ¯ RGB colour ; changes AX,DX
  shr  ax,1
  and  dh,3Eh
  shl  dh,2
  or   ah,dh
  shl  dx,5
  or   ax,dx
  ret
endp

proc To16 near ; AL ® colour index, AX ¯ RGB colour ; changes AX,DX
  cmp al,7
  jb  @@0_6
  cmp al,8
  ja  @@9_15
  or  al,8
  and al,12
  shl al,2
  mov dl,al
  mov dh,al
  call RGB
  ret
@@0_6:
  test al,1
  setnz dh
  test al,2
  setnz dl
  shl dx,5
  test al,4
  setnz al
  shl al,5
  call RGB
  ret
@@9_15:
  xor dx,dx
  test al,1
  jz @@9_15_g
  mov dh,3Fh
@@9_15_g:
  test al,2
  jz @@9_15_b
  mov dl,3Fh
@@9_15_b:
  test al,4
  mov al,0
  jz @@9_15_x
  mov al,3Fh
@@9_15_x:
  call RGB
  ret
endp

proc Bin8 near ; CX ® length of binary block in bytes ; changes EAX,CX,DL
  shr cx,1
  setc dl
  jz @@last
@@next:
  xor eax,eax
  lodsw
  shl eax,4
  shr ax,4
  shl eax,8
  shr ax,4
  shr al,4
  stosd
  loop @@next
@@last:
  or dl,dl
  jz @@exit
  lodsb
  shl ax,4
  shr al,4
  and ah,15
  stosw
@@exit:
  ret
endp

proc Bin16 near ; CX ® length of binary block in bytes ; changes EAX,CX,DX
  lodsb
  shl eax,12
  shr ax,12
  rol eax,16
  and ax,15
  call To16
  rol eax,16
  call To16
  stosd
  loop bin16
  ret
endp

proc GetCardImage Index:word,Buffer:dword,Mode:byte
uses ds
  mov cx,[CardDataSize]
  les di,[Buffer]
  cmp [CardData],0
  je @@none
  mov ax,[Index]
  cmp ax,[CardCount]
  jge @@none
  or ax,ax
  js @@none
  mov bl,[PackerColor]
  lds si,[CardData]
  shl ax,1
  add si,ax
  shl ax,1
  add si,ax ; DS:SI = CardData+6*Index = @CardData[Index].Data
  cmp [dword ptr si],0
  je @@none
  lds si,[si]
  lodsb
  cmp al,2
  ja @@CB
  je @@BC
  dec al
  jz @@two
  ; primitive binary
  shr cx,1
  cmp [Mode],16
  je @@bin16
  call bin8
  jmp @@exit
@@bin16:
  call bin16
  jmp @@exit
@@BC: ; binary, then counter
  cmp [Mode],16
  je @@bc16_next
@@bc8_next:
  lodsb
  shl ax,4
  shr al,4
  and ah,15
  cmp al,bl
  je @@bc8_rep
  stosw
  dec cx
  loop @@bc8_next
  jmp @@exit
@@bc8_rep:
  mov dx,cx
  lodsb
  movzx cx,al
  sub dx,cx
  inc dx
  mov al,ah
  rep stosb
  mov cx,dx
  loop @@bc8_next
  jmp @@exit
@@bc16_next:
  lodsb
  shl eax,12
  shr ax,12
  rol eax,16
  and ax,15
  call To16
  rol eax,16
  cmp al,bl
  je @@bc16_rep
  call To16
  stosd
  dec cx
  loop @@bc16_next
  jmp @@exit
@@bc16_rep:
  mov dx,cx
  lodsb
  movzx cx,al
  sub dx,cx
  inc dx
  rol eax,16
  rep stosw
  mov cx,dx
  loop @@bc16_next
  jmp @@exit
@@CB: ; counter, then binary
  mov bx,cx
  cmp [Mode],16
  je @@cb16_next
@@cb8_next:
  lodsb
  shl ax,4
  shr al,4
  and ah,15
  jz @@cb8_bin
  cmp ah,15
  je @@cb8_long
  movzx cx,ah
@@cb8_rep:
  sub bx,cx
  rep stosb
  jnz @@cb8_next
  jmp @@exit
@@cb8_long:
  movzx cx,[si]
  inc si
  jmp @@cb8_rep
@@cb8_bin:
  movzx cx,al
  sub bx,cx
  sub bx,cx
  call bin8
  or bx,bx
  jnz @@cb8_next
  jmp @@exit
@@cb16_next:
  lodsb
  shld cx,ax,12
  and ax,15
  and cx,15
  jz @@cb16_bin
  cmp cl,15
  je @@cb16_long
@@cb16_rep:
  sub bx,cx
  call To16
  rep stosw
  or bx,bx
  jnz @@cb16_next
  jmp @@exit
@@cb16_long:
  movzx cx,[si]
  inc si
  jmp @@cb16_rep
@@cb16_bin:
  mov cx,ax
  shl ax,1
  sub bx,ax
  call bin16
  or bx,bx
  jnz @@cb16_next
  jmp @@exit
@@TWO: ; two colours
  movzx ebx,cx
  lodsb
  cmp [Mode],16
  je @@two16_init
  shl ax,4
  shr al,4
  and ax,0F0Fh
  xchg dx,ax
  jmp @@two_next
@@two16_init:
  or ebx,80000000h
  shl eax,12
  shr ax,12
  call To16
  rol eax,16
  and ax,15
  call To16
  rol eax,16
  xchg edx,eax
@@two_next:
  lodsb
  or al,al
  je @@two_rep
  mov cl,al
  shr cx,5
  and cx,7
  sub bx,cx
  rol ecx,16
  mov cl,al
  and cx,1Fh
  sub bx,cx
  or ebx,ebx
  js @@two16_put
  mov al,dl
  rep stosb
  rol ecx,16
  mov al,dh
  rep stosb
@@two_loop:
  or bx,bx
  jnz @@two_next
  jmp @@exit
@@two16_put:
  mov ax,dx
  rep stosw
  rol ecx,16
  shld eax,edx,16
  rep stosw
  jmp @@two_loop
@@two_rep:
  lodsb
  movzx cx,al
  sub bx,cx
  or ebx,ebx
  js @@two16_rep
  mov al,dl
  rep stosb
  jmp @@two_loop
@@two16_rep:
  mov ax,dx
  rep stosw
  jmp @@two_loop
@@NONE: ; no card
  cmp [Mode],16
  je @@none16
  shr cx,2
  mov eax,0F0F0F0Fh
@@none_put:
  rep stosd
@@exit:
  ret
@@none16:
  shr cx,1
  mov eax,-1
  jmp @@none_put
endp

END