.286
  w equ word ptr cs:
  b equ byte ptr cs:
;code segment public
;code ends
code segment public
;gcode group code,arescode
assume cs:code,ds:code
extrn setpal:near
public init_modex,p13_2_modex,squeeze
public vscreen

Init_ModeX proc pascal
  mov ax,0013h
  int 10h

  mov dx,3c4h
  mov al,4
  out dx,al
  inc dx
  in al,dx
  and al,0f7h
  or al,4h
  out dx,al
  dec dx
  mov ax,0f02h
  out dx,ax

  mov ax,0a000h
  mov es,ax
  xor di,di
  xor ax,ax
  mov cx,8000h
  cld
  rep stosw

  mov dx,3d4h
  mov al,14h
  out dx,al
  inc dx
  in al,dx
  and al,0bfh
  out dx,al
  dec dx
  mov al,17h
  out dx,al
  inc dx
  in al,dx
  or al,40h
  out dx,al
  ret
Endp

plane_l: db 0
plane_pos: dw 0
vscreen: dd 0

p13_2_modex proc pascal start,pic_size:word
    mov b plane_l,1
    mov w plane_pos,0
    push ds
    lds si,dword ptr cs:vscreen
    mov w plane_pos,si
    mov ax,0a000h
    mov es,ax
    mov di,start
    mov cx,pic_size
@lpplane:
    mov al,02h
    mov ah,b plane_l
    mov dx,3c4h
    out dx,ax

@lp1:
    movsb
    add si,3
    loop @lp1

    mov di,start
    inc w plane_pos
    mov si,w plane_pos
    mov cx,pic_size
    shl b plane_l,1
    cmp b plane_l,10h
    jne @lpplane

    pop ds
    ret
Endp
Split proc pascal row:byte
  mov bl,row
  xor bh,bh
  shl bx,1
  mov cx,bx

  mov dx,3d4h
  mov al,07h
  out dx,al
  inc dx
  in al,dx
  and al,11101111b
  shr cx,4
  and cl,16
  or al,cl
  out dx,al

  dec dx
  mov al,09h
  out dx,al
  inc dx
  in al,dx
  and al,10111111b
  shr bl,3
  and bl,64
  or al,bl
  out dx,al

  dec dx
  mov al,18h
  mov ah,row
  shl ah,1
  out dx,ax
  ret
Endp
SetStart proc pascal t:word
  mov dx,3d4h
  mov al,0ch
  mov ah,byte ptr t + 1
  out dx,ax
  mov al,0dh
  mov ah,byte ptr t
  out dx,ax
  ret
Endp
WaitRetrace proc pascal
  mov dx,3dah
@wait1:
  in al,dx
  test al,8h
  jz @wait1
@wait2:
  in al,dx
  test al,8h
  jnz @wait2
  ret
Endp

squeeze proc pascal
  mov si,200*80
  mov di,199
  push di
  call split
  push si
  call setstart
  call waitretrace
  call setpal
sqlp:
  call waitretrace
  push di
  call split
  push si
  call setstart
  sub si,2*80
  sub di,2
  cmp di,99d
  jae sqlp
  ret
squeeze endp
code ends
end
