--- /dev/null
+;-----------------------------------------------------------\r
+;\r
+; MXCL.ASM - Bresenham circle\r
+; Copyright (c) 1993,1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN PRO\r
+NOWARN RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC mxCircle\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 a circle using the Bresenham algorithm.\r
+;\r
+; Input:\r
+; XC, YC = center coordinates\r
+; Radius = circle radius\r
+; Color = circle color\r
+; Output:\r
+; none\r
+; Note:\r
+; computes only points in the first octant, all other\r
+; points are obtained by symmetry.\r
+;\r
+mxCircle PROC FAR\r
+ ARG Color:BYTE:2, \\r
+ Radius:WORD, \\r
+ YC:WORD, \\r
+ XC:WORD = ARG_SIZE\r
+ LOCAL Delta:WORD = AUTO_SIZE\r
+ .enter AUTO_SIZE\r
+ .push ds, si, di\r
+\r
+ xor si, si ; X\r
+ mov di, [Radius] ; Y\r
+ mov ax, 3\r
+ sub ax, di\r
+ sub ax, di\r
+ mov [Delta], ax ; Delta = 3-R*2\r
+\r
+ mov ds, [mx_VideoSegment]\r
+\r
+@@Loop:\r
+ cmp si, di ;\r
+ jg @@Done ; Exit when X > Y\r
+; Draw points\r
+ mov ax, si\r
+ mov bx, di\r
+ call @@subPutPixel\r
+ mov ax, si\r
+ neg ax\r
+ mov bx, di\r
+ call @@subPutPixel\r
+ mov ax, si\r
+ mov bx, di\r
+ neg bx\r
+ call @@subPutPixel\r
+ mov ax, si\r
+ neg ax\r
+ mov bx, di\r
+ neg bx\r
+ call @@subPutPixel\r
+ mov ax, di\r
+ mov bx, si\r
+ call @@subPutPixel\r
+ mov ax, di\r
+ neg ax\r
+ mov bx, si\r
+ call @@subPutPixel\r
+ mov ax, di\r
+ mov bx, si\r
+ neg bx\r
+ call @@subPutPixel\r
+ mov ax, di\r
+ neg ax\r
+ mov bx, si\r
+ neg bx\r
+ call @@subPutPixel\r
+; Moves coordinates to next point\r
+ mov ax, [Delta]\r
+ test ax, ax\r
+ jl @@Next\r
+ mov ax, di\r
+ .shl ax, 2\r
+ sub ax, 4\r
+ sub [Delta], ax\r
+ dec di\r
+@@Next:\r
+ mov ax, si\r
+ .shl ax, 2\r
+ add ax, 6\r
+ add [Delta], ax\r
+ inc si\r
+ jmp @@Loop\r
+\r
+@@Done:\r
+ xor ax, ax\r
+ .pop ds, si, di\r
+ .leave ARG_SIZE\r
+\r
+;---------------------------------------\r
+; Put pixel function.\r
+; Input:\r
+; BX = X coordinate (relative to center)\r
+; AX = Y coordinate (relative to center)\r
+; DS = video segment\r
+@@subPutPixel:\r
+ add bx, [XC] ; Get absolute coordinates\r
+ add ax, [YC]\r
+\r
+ cmp bx, [mx_ClipX1] ; Clip pixel\r
+ jl @@subExit\r
+ cmp bx, [mx_ClipX2]\r
+ jg @@subExit\r
+ cmp ax, [mx_ClipY1]\r
+ jl @@subExit\r
+ cmp ax, [mx_ClipY2]\r
+ jg @@subExit\r
+\r
+ mul [mx_BytesPerLine] ; Get pixel offset\r
+ mov cx, bx ; Save X coordinate\r
+ .shr bx, 2\r
+ add bx, ax ; DS:BX = pixel offset\r
+\r
+ and cl, 3 ; Set write plane\r
+ mov ax, 0102h\r
+ shl ah, cl\r
+ mov dx, TS\r
+ out dx, ax\r
+\r
+ mov al, [Color] ; Write pixel\r
+ mov ds:[bx], al\r
+\r
+@@subExit:\r
+ retn\r
+mxCircle ENDP\r
+\r
+MX_TEXT ENDS\r
+END\r