--- /dev/null
+;-----------------------------------------------------------\r
+;\r
+; MXGI.ASM - Get image\r
+; Copyright (c) 1994 by Alessandro Scotti\r
+;\r
+;-----------------------------------------------------------\r
+WARN PRO\r
+NOWARN RES\r
+INCLUDE MODEX.DEF\r
+\r
+PUBLIC mxGetImage\r
+\r
+EXTRN subClipImage : NEAR\r
+\r
+MX_TEXT SEGMENT USE16 PARA PUBLIC 'CODE'\r
+ ASSUME cs:MX_TEXT, ds:NOTHING, es:NOTHING\r
+\r
+EXTRN mx_VideoSegment : WORD\r
+EXTRN mx_BytesPerLine : WORD\r
+\r
+;-----------------------------------------------------------\r
+;\r
+; Copies an image from screen to memory.\r
+;\r
+; Input:\r
+; Image = pointer to buffer for image\r
+; X, Y = coordinates of image on screen\r
+; Width = width of image in pixels\r
+; Height = height of image in pixels\r
+; Output:\r
+; none\r
+;\r
+mxGetImage PROC FAR\r
+ ARG Height:WORD, \\r
+ Width:WORD, \\r
+ Y:WORD, \\r
+ X:WORD, \\r
+ Image:DWORD = ARG_SIZE\r
+ LOCAL PlaneWidth:WORD:4, \\r
+ PixelOffset:WORD, \\r
+ MoveFunction:WORD, \\r
+ ReadPlane:BYTE, \\r
+ Count:BYTE = AUTO_SIZE\r
+ ASSUME ds:NOTHING\r
+ .enter AUTO_SIZE\r
+ .push ds, si, es, di\r
+\r
+; Clip image\r
+ mov bx, [X]\r
+ mov ax, [Y]\r
+ mov cx, [Width]\r
+ mov dx, [Height]\r
+ call subClipImage\r
+ jc @@Exit ; Full clipped\r
+ mov [Height], dx\r
+ add WORD PTR Image[0], si ; Skip clipped pixels\r
+\r
+; Get pixel address\r
+ mul [mx_BytesPerLine]\r
+ mov si, bx\r
+ shr si, 1\r
+ shr si, 1\r
+ add si, ax\r
+ mov [PixelOffset], si\r
+ mov ds, [mx_VideoSegment] ; DS:SI points to pixel\r
+ and bl, 03h\r
+ mov [ReadPlane], bl\r
+\r
+; Compute extra bytes and width count for each plane\r
+ mov bx, cx\r
+ shr bx, 1\r
+ shr bx, 1 ; Width for each plane\r
+ and cl, 03h\r
+ mov al, 00001000b\r
+ shr al, cl\r
+ mov di, 3 SHL 1\r
+@@PatchLoop:\r
+ mov PlaneWidth[di], bx\r
+ shr al, 1\r
+ adc bx, 0\r
+ dec di\r
+ dec di\r
+ jge @@PatchLoop\r
+\r
+; Get image\r
+ cld\r
+ mov [Count], 4 ; Four planes\r
+ lea bx, PlaneWidth ; SS:[BX] = width in bytes for plane\r
+ mov es, WORD PTR Image[2] ; ES:DI will point to image\r
+ mov ah, [ReadPlane]\r
+@@PlaneLoop:\r
+ cmp WORD PTR ss:[bx], 0 ; Exit if nothing more to do\r
+ je @@Exit ; (also, never try to move zero bytes!)\r
+ mov di, WORD PTR Image[0]\r
+ mov al, 04h\r
+ mov dx, GDC\r
+ out dx, ax ; Select read plane\r
+ mov dx, [Height]\r
+ mov si, [PixelOffset] ; DS:SI points to video memory\r
+@@Loop:\r
+ .push si, di\r
+ mov cx, WORD PTR ss:[bx] ; Number of bytes to move\r
+@@MoveLoop:\r
+ movsb\r
+ add di, 3\r
+ dec cx\r
+ jnz @@MoveLoop\r
+ .pop si, di\r
+ add di, [Width] ; Go to next image line\r
+ add si, [mx_BytesPerLine] ; Go to next screen row\r
+ dec dx\r
+ jnz @@Loop ; Repeat for all lines\r
+ inc bx\r
+ inc bx ; Select width for next plane\r
+ inc ah\r
+ test ah, 04h ; Plane wraparound?\r
+ jz @@PlaneOk ; No\r
+ inc [PixelOffset] ; Yes, bump video pointer\r
+ and ah, 03h\r
+@@PlaneOk:\r
+ inc WORD PTR Image[0]\r
+ dec [Count]\r
+ jnz @@PlaneLoop ; Repeat for all planes\r
+\r
+@@Exit:\r
+ xor ax, ax\r
+ .pop ds, si, es, di\r
+ .leave ARG_SIZE\r
+mxGetImage ENDP\r
+\r
+MX_TEXT ENDS\r
+END\r