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

DATASEG
  extrn FRes:word

CODESEG

public ReadCode,WriteCode

struc FBuffer
  BufferIO   dd ?
  SpecData   dd ?
  Buffer     dd ?
  BufferSize dw ?
  BufPos     dw ?
  RegBuf     dd ?
  BitPos     db ?
  Mode       db ?
ends

proc Read far CodeSize:byte,Self:dword
local DSeg
endp

proc ReadBuffer near ; parameters inherited from Read ; DS:SI ®¯ [Self]
  push 0 ds si ;Self
  mov  ax,ds
  mov  es,ax
  mov  ds,[DSeg]
  call [es:si+FBuffer.BufferIO]
  lds  si,[Self]
  mov  [si+FBuffer.BufPos],0
  ret
endp

proc ReadReg near ; parameters inherited from Read ; DS:SI ®¯ [Self]
  lea  bx,[si+FBuffer.BufPos]
  mov  cx,[si+FBuffer.BufferSize]
  cmp  [bx],cx ;BufPos
  jne  @@dontread
  push bx
  call ReadBuffer
  pop  bx
  mov  cx,[si+FBuffer.BufferSize]
@@dontread:
  mov  ax,[bx] ;BufPos
  les  di,[si+FBuffer.Buffer]
  add  di,ax
  sub  cx,ax
  cmp  cx,4
  jb   @@part
  mov  eax,[es:di] ;Buffer^[BufPos]
  mov  [si+FBuffer.RegBuf],eax
  add  [word ptr bx],4 ;BufPos
  ret
@@part:
  shl  cx,3
  push cx [dword ptr es:di] ;Buffer^[BufPos]
  call ReadBuffer
  pop  edx cx
  mov  eax,1
  shl  eax,cl
  dec  eax
  and  edx,eax
  les  di,[si+FBuffer.Buffer]
  mov  eax,[es:di] ;Buffer^[0]
  shl  eax,cl
  or   edx,eax
  mov  [si+FBuffer.RegBuf],edx
  shr  cx,3
  mov  ax,4
  sub  ax,cx
  add  [si+FBuffer.BufPos],ax
  ret
endp

proc ReadCode near ; parameters inherited from Read
; jump point from TManalBitStream.Read
  mov  [DSeg],ds
  lds  si,[Self]
  mov  bl,[si+FBuffer.BitPos]
  cmp  bl,32
  jb   @@go
  call ReadReg
  mov  bl,0
@@go:
  mov  eax,[si+FBuffer.RegBuf]
  mov  cl,bl
  shr  eax,cl
  mov  cl,[CodeSize]
  cmp  cl,1
  je   @@onebit
  mov  edx,1
  shl  edx,cl
  dec  edx
  and  eax,edx
  add  bl,cl
  cmp  bl,32
  jbe  @@done
  ; next integer
  push eax bx
  call ReadReg
  pop  bx
  sub  bl,32
  mov  cl,bl
  mov  eax,[si+FBuffer.RegBuf]
  mov  edx,1
  shl  edx,cl
  dec  edx
  and  eax,edx
  mov  cl,[CodeSize]
  sub  cl,bl
  shl  eax,cl
  pop  edx
  or   eax,edx
@@done:
  mov  [si+FBuffer.BitPos],bl
  mov  ds,[DSeg]
  shld edx,eax,16 ;Result in DX:AX
  leave
  retf 6 ; simulate return from TManalBitStream.Read
@@onebit: ; one bit only
  and  ax,1
  cwd
  inc  [byte ptr si+FBuffer.BitPos]
  mov  ds,[DSeg]
  leave
  retf 6 ; simulate return from TManalBitStream.Read
endp

proc Write far CodeSize:byte,Code:dword,Self:dword
local DSeg
endp

proc WriteBuffer near ; parameters inherited from Write ; DS:SI ®¯ [Self]
  push [si+FBuffer.BufPos]
  push ds si ;Self
  mov  ax,ds
  mov  es,ax
  mov  ds,[DSeg]
  call [es:si+FBuffer.BufferIO]
  lds  si,[Self]
  mov  [si+FBuffer.BufPos],0
  ret
endp

proc WriteReg near ; parameters inherited from Write ; DS:SI ®¯ [Self]
  lea  bx,[si+FBuffer.BufPos]
  mov  dx,[bx] ;BufPos
  les  di,[si+FBuffer.Buffer]
  add  di,dx
  mov  eax,[si+FBuffer.RegBuf]
  mov  cx,[si+FBuffer.BufferSize]
  sub  cx,dx
  cmp  cx,4
  jb   @@part
  stosd ;Buffer^[BufPos]
  add  [word ptr bx],4 ;BufPos
  add  cx,4
  cmp  [bx],cx ;BufPos
  jb   @@dontwrite
  call WriteBuffer
@@dontwrite:
  ret
@@part:
  push cx eax
@@nextbyte:
  stosb
  shr  eax,8
  dec  cx
  jnz  @@nextbyte
  call WriteBuffer
  pop  eax cx
  les  di,[si+FBuffer.Buffer]
  shl  cx,3
  shr  eax,cl
  stosd ;Buffer^[0]
  shr  cx,3
  mov  ax,4
  sub  ax,cx
  add  [si+FBuffer.BufPos],ax
  ret
endp

proc WriteCode near ; parameters inherited from Write
; jump point from TManalBitStream.Write
  mov  [DSeg],ds
  lds  si,[Self]
  mov  cl,[CodeSize]
  mov  eax,1
  shl  eax,cl
  dec  eax
  and  [Code],eax
  mov  eax,[Code]
  mov  bl,[si+FBuffer.BitPos]
  mov  cl,bl
  shl  eax,cl
  or   [si+FBuffer.RegBuf],eax
  add  bl,[CodeSize]
  cmp  bl,32
  jb   @@done
  ; next integer
  push bx
  call WriteReg
  pop  bx
  sub  bl,32
  jz   @@done
  mov  eax,[Code]
  mov  cl,[CodeSize]
  sub  cl,bl
  shr  eax,cl
  mov  [si+FBuffer.RegBuf],eax
@@done:
  mov  [si+FBuffer.BitPos],bl
  mov  ds,[DSeg]
  leave
  retf 10 ; simulate return from TManalBitStream.Write
endp

END