.286
b equ byte ptr
w equ word ptr

data segment
  extrn vpage:word              ;aktuelle Bildschirmseite
data ends

putpixel macro                  ;setzt Pixel an ax/bx
  pusha
  xchg ax,bx                    ;x und y vertauschen
  push ax                       ;y fr spter sichern
  mov cx,bx                     ;x holen
  and cx,3                      ;Plane maskieren
  mov ax,1                      ;und entspr. Bit setzen
  shl ax,cl
  mov ah,2                      ;TS Register 2
  xchg ah,al
  mov dx,3c4h
  out dx,ax

  pop cx                        ;y holen
  mov ax,80d                    ;Zeilen-Offset berechnen
  mul cx
  shr bx,2                      ;Spalten-Offset addieren
  add bx,ax
  add bx,vpage                  ;auf aktuelle Seite schreiben
  mov b es:[bx],3               ;und Farbe setzen

  popa
endm

code segment public
assume cs:code,ds:data

public bline
bline proc    near
;zieht Linie von ax/bx nach cx/dx
  push bp
  push ax                       ;x0 und
  push bx                       ;y0 sichern
  mov bx,4340h                  ;Selbstmodifikation vorbereiten
  sub cx,ax                     ;deltax berechnen
  jns deltax_ok                 ;negativ ?
  neg cx                        ;ja, dann deltax Vorzeichen umkehren
  mov bl,48h                    ;und dec ax statt inc ax
deltax_ok:
  mov bp,sp                     ;Addressierung von y1 auf dem Stack
  sub dx,ss:[bp]                ;deltay berechnen
  jns deltay_ok                 ;negativ ?
  neg dx                        ;ja, dann deltay Vorzeichen umkehren
  mov bh,4bh                    ;und dec bx statt inc bx
deltay_ok:
  mov si,dx                     ;deltay und
  or si,cx                      ;deltax = 0 ?
  jne ok
  add sp,6                      ;dann ax, bx und bp vom Stack und Ende
  ret
ok:
  mov w cs:dist_pos,bx          ;dec/inc ax/bx an Ziel schreiben
  cmp cx,dx                     ;deltax >= deltay ?
  jge deltax_gross
  xchg cx,dx                    ;nein, dann deltax und deltay tauschen
  mov bl,90h                    ;und inc ax noppen
  jmp konstanten
deltax_gross:
  mov bh,90h                    ;sonst inc bx noppen
konstanten:
  mov w cs:dist_neg,bx          ;dec/inc ax/bx an Ziel schreiben
  shl dx,1                      ;Add_2 bestimmen
  mov di,dx                     ;in di sichern
  sub dx,cx                     ;Start-Dist bestimmen
  mov bp,dx                     ;und in bp sichern
  mov si,bp                     ;Add_1 bestimmen
  sub si,cx                     ;und in si sichern
  mov ax,0a000h                 ;VGA-Segment laden
  mov es,ax
  pop bx                        ;gesicherte Werte fr x0 und y0 zurckholen
  pop ax
loop_p:
  putpixel                      ;Punkt setzen
  or bp,bp                      ;Dist positiv ?
  jns dist_pos
dist_neg:
  inc ax                        ;x weiter (evtl Selbstmodifikation)
  inc bx                        ;y weiter (evtl Selbstmodifikation)
  add bp,di                     ;Dist aktualisieren
  loop loop_p                   ;nchsten Punkt
  jmp fertig                    ;danach fertig
dist_pos:
  inc ax                        ;x weiter (evtl Selbstmodifikation)
  inc bx                        ;y weiter (evtl Selbstmodifikation)
  add bp,si                     ;Dist aktualisieren
  loop loop_p                   ;nchsten Punkt
fertig:
  pop bp
  ret
bline endp
code ends
end