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_maske:word
; Zeichnet 2 Copperbalken an Positionen y_pos1 (rot) und y_pos2 (gruen)
; overlay_maske: 0ff00h : Copper 2 im Vordergrund
;                000ffh : Copper 1 im Vordergrund
;                00000h : Durchdringung beider Copper

hoehe equ 88                    ;Gesamth”he je Copper


  mov ax,y_pos1                 ;maximale y-Koordinate bestimmen
  cmp ax,y_pos2
  ja ax_high
  mov ax,y_pos2
ax_high:
  add ax,hoehe                  ;H”he drauf
  mov maxrow,ax                 ;maximale Zeile, die beachtet werden muá

  xor cx,cx                     ;Zeilenz„hler mit 0 starten

  call waitretrace              ;auf Retrace warten zur Synchronisation

next_line:
  inc cx                        ;Zeilenz„hler hochz„hlen

  mov bx,cx                     ;Farbe 1 berechnen
  sub bx,y_pos1                 ;dazu Position relativ zum Copperstart holen
  cmp bx,hoehe/2 -1             ;schon 2. H„lfte ?
  jle copper1_up
  sub bx,hoehe -1               ;dann bx:=127-bx
  neg bx
copper1_up:
  or bx,bx
  jns copper1_ok                ;positiv, dann Farbe
  xor bl,bl
copper1_ok:
  mov ax,cx                     ;Farbe 2 berechnen
  sub ax,y_pos2                 ;Position relativ berechnen
  cmp ax,hoehe/2 -1             ;2. H„lfte
  jle copper2_up
  sub ax,hoehe -1               ;dann ax:=127-ax
  neg ax
copper2_up:
  or ax,ax                      ;positiv, dann Farbe
  jns copper2_ok
  xor al,al
copper2_ok:
  mov bh,al                     ;bl hat jetzt Farbe Copper 1 / bh Copper 2

  mov ax,bx                     ;Overlay berechnen
  and ax,overlay_maske          ;Copper 1 oder 2 ausmaskieren
  or al,al                      ;Copper 1 Vorrang
  je Copper1_hinten
  xor bh,bh                     ;dann Copper 2 l”schen
copper1_hinten:
  or ah,ah                      ;Copper 2 Vorrang
  je Copper2_hinten
  xor bl,bl                     ;dann Copper 1 l”schen
copper2_hinten:

  xor al,al                     ;Farbe 0 im DAC selektieren
  mov dx,3c8h
  out dx,al

  or bl,bl                      ;wenn Copper 1 schwarz -> lassen
  je bl_0
  add bl,(128-hoehe) / 2        ;sonst aufhellen, um Maximalhelligkeit
bl_0:                           ;zu erreichen
  or bh,bh                      ;fr Copper 2 das Gleiche
  je bh_0
  add bh,(128-hoehe) / 2
bh_0:

;jetzt auf horizontalen Retrace warten und Copper aktivieren

  cli                           ;Interrupts l”schen, da SEHR zeitkritisch
  mov dx,3dah                   ;Input Status Register 1 selektieren
in_retrace:
  in al,dx                      ;auf Display warten
  test al,1
  jne in_retrace

in_display:
  in al,dx                      ;Warten auf (Horizontal-) Retrace
  test al,1
  je in_display

  mov al,bl                     ;Farbe 1 laden
  mov dx,3c9h                   ;und setzen
  out dx,al                     ;Rot-Anteile fr Copper 1 setzen
  mov al,bh
  out dx,al                     ;Gruen-Anteile fr Copper 2 setzen
  xor al,al
  out dx,al

  cmp cx,maxrow                 ;letzte Zeile erzeugt ?
  jne next_line

  mov dx,3dah                   ;ja -> beenden
wait_hret:                      ;vor dem Abschalten, unbedingt auf Retrace
  in al,dx                      ;warten, sonst Flimmern in letzter Zeile
  test al,1
  je wait_hret

  xor al,al                     ;Farbe 0 im DAC selektieren
  mov dx,3c8h
  out dx,al
  inc dx                        ;alle auf 0 setzen: schwarz
  out dx,al
  out dx,al
  out dx,al

  sti
  ret
makecopper endp
code ends
end
