extrn waitretrace:far
data segment public
  maxrow dw (?)
data ends

code segment public
public makecopper

assume cs:code,ds:data

MakeCopper proc pascal y_pos1,y_pos2,overlay_mask:word
; draws 2 copper beams at positions y_pos1 (red) and y_pos2 (green)
; overlay_mask: 0ff00h : Copper 2 in foreground
;                000ffh : copper 1 in foreground
;                00000h : penetration of both coppers

height equ 88                   ;total height per copper


  mov ax,y_pos1                 ;define maximum y-coordinate
  cmp ax,y_pos2
  ja ax_high
  mov ax,y_pos2
ax_high:
  add ax,height                 ;add height
  mov maxrow,ax                 ;maximum row to be taken into consideration

  xor cx,cx                     ;start row counter with 0

  call waitretrace              ;wait for retrace for synchronization

next_line:
  inc cx                        ;increment row counter

  mov bx,cx                     ;calculate color 1
  sub bx,y_pos1                 ;in addition, get position relative to copper start
  cmp bx,height/2 -1            ;2nd half ?
  jle copper1_up
  sub bx,height -1              ;then bx:=127-bx
  neg bx
copper1_up:
  or bx,bx
  jns copper1_ok                ;positive, then color
  xor bl,bl
copper1_ok:
  mov ax,cx                     ;calculate color 2
  sub ax,y_pos2                 ;calculate position relatively
  cmp ax,height/2 -1            ;2nd half
  jle copper2_up
  sub ax,height -1              ;then ax:=127-ax
  neg ax
copper2_up:
  or ax,ax                      ;positive, then color
  jns copper2_ok
  xor al,al
copper2_ok:
  mov bh,al                     ;bl now has color copper 1 / bh copper 2

  mov ax,bx                     ;calculate overlay
  and ax,overlay_mask           ;mask out copper 1 or 2
  or al,al                      ;copper 1 priority
  je copper1_back
  xor bh,bh                     ;then clear copper 2
copper1_back:
  or ah,ah                      ;copper 2 priority
  je copper2_back
  xor bl,bl                     ;then clear copper 1
copper2_back:

  xor al,al                     ;select color 0 in DAC
  mov dx,3c8h
  out dx,al

  or bl,bl                      ;if copper 1 black -> leave as is
  je bl_0
  add bl,(128-height) / 2       ;otherwise lighten to achieve maximum
bl_0:                           ;brightness
  or bh,bh                      ;the same for copper 2
  je bh_0
  add bh,(128-height) / 2
bh_0:

;now wait for horizontal retrace and enable copper

  cli                           ;clear interrupts, because it is VERY time-critical
  mov dx,3dah                   ;select Input Status Register 1
in_retrace:
  in al,dx                      ;wait for display
  test al,1
  jne in_retrace

in_display:
  in al,dx                      ;wait for (horizontal) retrace
  test al,1
  je in_display

  mov al,bl                     ;load color 1
  mov dx,3c9h                   ;and set
  out dx,al                     ;set red percentage for copper 1
  mov al,bh
  out dx,al                     ;set green percentage for copper 2
  xor al,al
  out dx,al

  cmp cx,maxrow                 ;last row generated ?
  jne next_line

  mov dx,3dah                   ;yes -> end
wait_hret:                      ;before switching off, wait for retrace
  in al,dx                      ;otherwise flickering in last row
  test al,1
  je wait_hret

  xor al,al                     ;select color 0 in DAC
  mov dx,3c8h
  out dx,al
  inc dx                        ;set all to 0: black
  out dx,al
  out dx,al
  out dx,al

  sti
  ret
makecopper endp
code ends
end
