--- /dev/null
+;-----------------------------------------------------------\r
+;\r
+; MXEL.ASM - Mid-point ellipse\r
+; Copyright (c) 1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN PRO\r
+NOWARN RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC mxEllipse\r
+\r
+MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
+ ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN mx_BytesPerLine : WORD\r
+EXTRN mx_VideoSegment : WORD\r
+EXTRN mx_ClipX1 : WORD\r
+EXTRN mx_ClipY1 : WORD\r
+EXTRN mx_ClipX2 : WORD\r
+EXTRN mx_ClipY2 : WORD\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Draws an ellipse using the mid-point algorithm.\r
+;\r
+; Input:\r
+; XC, YC = center coordinates\r
+; A = horizontal radius\r
+; B = vertical radius\r
+; Color = ellipse color\r
+; Output:\r
+; none\r
+; Note:\r
+; computes only points in the first quadrant, all other\r
+; points are obtained by symmetry.\r
+;\r
+mxEllipse PROC FAR\r
+ ARG Color:BYTE:2, \\r
+ B:WORD, \\r
+ A:WORD, \\r
+ YC:WORD, \\r
+ XC:WORD = ARG_SIZE\r
+ LOCAL A2:DWORD, \\r
+ B2:DWORD, \\r
+ CC:DWORD, \\r
+ DD:DWORD, \\r
+ X:DWORD, \\r
+ Y:DWORD = AUTO_SIZE\r
+ .enter AUTO_SIZE\r
+ .push ds, si, di\r
+\r
+ .chk386 mxEllipse, @@Exit\r
+\r
+; Initialize variables\r
+ xor eax, eax\r
+ mov [X], ax ; X = 0\r
+ mov ax, [A]\r
+ mul eax ; EAX = A*A\r
+ mov [DD], eax ; DD = A*A\r
+ shl eax, 1\r
+ mov [CC], eax ; CC = 2*A*A\r
+ shl eax, 1\r
+ mov [A2], eax ; A2 = 4*A*A\r
+ movzx edx, [B]\r
+ mov [Y], edx\r
+ mul edx ; EAX = 4*A*A*B\r
+ sub [DD], eax ; DD = A*A - 4*A*A*B\r
+ movzx eax, [B]\r
+ mul eax ; EAX = B*B\r
+ shl eax, 2 ; EAX = 4*B*B\r
+ mov [B2], eax ; B2 = 4*B*B\r
+ add [CC], eax ; CC = 2*A*A + 4*B*B\r
+ add [D1], eax ; DD = A*A - 4*A*A*B + 4*B*B\r
+\r
+; Draw initial points\r
+ call subPlot4\r
+\r
+; First loop\r
+@@Loop1:\r
+ mov eax, [X] ; Check slope\r
+ mul [B2]\r
+ mov ecx, eax\r
+ mov eax, [Y]\r
+ mul [A2]\r
+ sub eax, ecx\r
+ sub eax, [CC] ; EAX = Y*A2 - X*B2 - CC\r
+ jle @@Done1 ; Crossed critical point, jump to next loop\r
+\r
+ mov ecx, [DD] ; Get error\r
+ test ecx, ecx ; Positive?\r
+ jl @@Draw1 ; No, use default step\r
+\r
+ mov eax, 1\r
+ sub eax, [Y]\r
+ mul [A2]\r
+ shl eax, 1\r
+ add ecx, eax ; Bump error\r
+ dec WORD PTR [Y] ; Decrement Y coordinate\r
+\r
+@@Draw1:\r
+ mov eax, [X]\r
+ shl eax, 1\r
+ add eax, 3\r
+ mul [B2]\r
+ add ecx, eax ; Bump error\r
+ mov [DD], ecx ; Save error\r
+ inc WORD PTR [X] ; Increment X coordinate\r
+\r
+ call subPlot4 ; Draw points\r
+ jmp @@Loop1\r
+@@Done1:\r
+\r
+; Initialize variables\r
+ shr [B2], 2\r
+ mov eax, [X]\r
+ mul eax\r
+ add [X]\r
+ shl eax, 2\r
+ inc eax\r
+ mul [B2]\r
+ mov [DD], eax\r
+ mov eax, [Y]\r
+ mul eax\r
+ add [Y]\r
+ dec eax\r
+ add [Y]\r
+ sub eax, [B2]\r
+ add [DD], eax\r
+ shl [B2], 3\r
+ inc WORD PTR [X]\r
+\r
+; Second loop\r
+@@Loop2:\r
+ cmp WORD PTR [Y], 0\r
+ ja @@Done2\r
+\r
+ mov ecx, [DD]\r
+ test ecx, ecx\r
+ jge @@Draw2\r
+\r
+ mov eax, [X]\r
+ inc eax\r
+ mul [B2]\r
+ add ecx, eax\r
+ inc WORD PTR [X]\r
+\r
+@@Draw2:\r
+ mov eax, [Y]\r
+ shl eax, 1\r
+ sub eax, 3\r
+ neg eax\r
+ imul [A2]\r
+ add ecx, eax\r
+ dec WORD PTR [Y]\r
+\r
+ call subPlot4\r
+ jmp @@Loop2\r
+@@Done2:\r
+\r
+@@Exit:\r
+ xor ax, ax\r
+ .leave ARG_SIZE\r
+mxEllipse ENDP\r
+\r
+MX_TEXT ENDS\r
+END\r