Oberon/ETH Oberon/2.3.7/VGA.Display.Mod

(* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. Refer to the license.txt file provided with this distribution. *) MODULE Display;	(* Ott Hans-Werner, ard, pjm *) IMPORT Kernel, SYSTEM, Objects; CONST BG* = 0; FG* = 15; (*background, foreground*) replace* = 0; paint* = 1; invert* = 2; (*operation modes*) remove* = 0; suspend* = 1; restore* = 2; newprinter* = 3; (*ControlMsg id*) reduce* = 0; extend* = 1; move* = 2; (*ModifyMsg id*) display* = 0; state* = 1; (*ModifyMsg mode*) screen* = 0; printer* = 1; (* DisplayMsg device *) full* = 0; area* = 1; contents* = 2; (* DisplayMsg id. *) get* = 0; set* = 1; reset* = 2; (*SelectMsg id*) drop* = 0; integrate* = 1; (*ConsumeMsg id*) unknown* = 0; index8* = 8; color555* = 16; color565* = 17; color664* = 18; color888* = 24; color8888* = 32; TYPE Color* = LONGINT; Pattern* = LONGINT; PatternPtr = POINTER TO RECORD w, h: CHAR; pixmap: ARRAY 8192 OF CHAR END; List = POINTER TO ListDesc; ListDesc = RECORD next: List; pat: PatternPtr END; Frame* = POINTER TO FrameDesc; FrameDesc* = RECORD (Objects.ObjDesc) next*, dsc*: Frame; X*, Y*, W*, H*: INTEGER END; FrameMsg* = RECORD (Objects.ObjMsg) F*: Frame; (*target*) x*, y*, res*: INTEGER END; ControlMsg* = RECORD (FrameMsg) id*: INTEGER END; ModifyMsg* = RECORD (FrameMsg) id*, mode*: INTEGER; dX*, dY*, dW*, dH*: INTEGER; X*, Y*, W*, H*: INTEGER END; DisplayMsg* = RECORD (FrameMsg) device*: INTEGER; id*: INTEGER; u*, v*, w*, h*: INTEGER END; LocateMsg* = RECORD (FrameMsg) loc*: Frame; X*, Y*, u*, v*: INTEGER END; SelectMsg* = RECORD (FrameMsg) id*: INTEGER; time*: LONGINT; sel*: Frame; obj*: Objects.Object END; ConsumeMsg* = RECORD (FrameMsg) id*: INTEGER; u*, v*: INTEGER; obj*: Objects.Object END; MsgProc* = PROCEDURE (VAR M: FrameMsg); VAR Unit*: LONGINT; (* RasterUnit = Unit/36000 mm *) Left*, (* left margin of black-and-white maps *) ColLeft*, (* left margin of color maps *) Bottom*, (* bottom of primary map *) UBottom*, (* bottom of secondary map *) Width*, (* map width *) Height*: (* map hight*) INTEGER; arrow*, star*, cross*, downArrow*, hook*, grey0*, grey1*, grey2*, ticks*, solid*: Pattern; Broadcast*: MsgProc; pattern: List; clipx, clipy, clipright, cliptop, height, width: INTEGER;	(* clipping variables *) width3: LONGINT; mask, imask: ARRAY 9 OF CHAR; rev: ARRAY 256 OF CHAR; depth: INTEGER; palette: ARRAY 256 OF LONGINT; PROCEDURE max (i, j: INTEGER): INTEGER; BEGIN IF i >= j THEN RETURN i ELSE RETURN j END END max; PROCEDURE min (i, j: LONGINT): INTEGER; BEGIN IF i >= j THEN RETURN SHORT(j) ELSE RETURN SHORT(i) END END min; PROCEDURE Map*(x: LONGINT): LONGINT; BEGIN RETURN 0A0000H END Map; PROCEDURE AdjustClip*(x, y, w, h: LONGINT); VAR right, top: INTEGER; BEGIN right := SHORT(x + w); top := SHORT(y + h); clipx := max(clipx, SHORT(x)); clipy := max(clipy, SHORT(y)); clipright := min(right, clipright); cliptop := min(top, cliptop) END AdjustClip; PROCEDURE GetDim*(pat: Pattern; VAR w, h: INTEGER); VAR ch: CHAR; BEGIN SYSTEM.GET(pat, ch); w := ORD(ch); SYSTEM.GET(pat+1, ch); h := ORD(ch) END GetDim; PROCEDURE ResetClip*; BEGIN clipx := 0; clipy := UBottom; clipright := width; cliptop := height END ResetClip; PROCEDURE SetClip*(x, y, w, h: LONGINT); BEGIN clipright := SHORT(x+w); cliptop := SHORT(y+h); clipy := SHORT(y); clipx := SHORT(x) END SetClip; PROCEDURE GetClip*(VAR x, y, w, h: INTEGER); BEGIN x := clipx; y := clipy; w := clipright - clipx; h := cliptop - clipy END GetClip; PROCEDURE SetColor*(col: Color; red, green, blue: LONGINT);	(* 0 <= col, red, green, blue < 256 *) VAR ch: CHAR; BEGIN palette[col] := ASH(ASH(red, 8) + green, 8) + blue; col := col MOD 16; (* see table 8.11 of Ferraro, 3rd edition *) IF col = 6 THEN col := 14H ELSIF col > 7 THEN INC(col, 30H) END; red := (red + 4) DIV 4 -1; green := (green + 4) DIV 4 -1; blue := (blue + 4) DIV 4 -1; SYSTEM.PORTOUT(3C8H, CHR(col)); SYSTEM.PORTOUT(3C9H, CHR(red)); SYSTEM.PORTOUT(3C9H, CHR(green)); SYSTEM.PORTOUT(3C9H, CHR(blue)) END SetColor; PROCEDURE GetColor*(col: Color; VAR red, green, blue: INTEGER); BEGIN IF col >= 0 THEN col := palette[col] END; red := SHORT(ASH(col, -16) MOD 256); green := SHORT(ASH(col, -8) MOD 256); blue := SHORT(col MOD 256) END GetColor; PROCEDURE RGB*(red, green, blue: LONGINT): Color; BEGIN RETURN MIN(LONGINT) + ASH(red, 16) + ASH(green, 8) + blue END RGB; PROCEDURE Dot*(col: Color; x, y, mode: LONGINT); CODE {SYSTEM.i386} MOV AX, clipy CMP WORD y[EBP], AX 		JL ret MOV AX, cliptop CMP WORD y[EBP], AX 		JGE ret MOV AX, clipx CMP WORD x[EBP], AX 		JL ret MOV AX, clipright CMP WORD x[EBP], AX 		JGE ret MOV AX, 1803H	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV DX, 03CEH CMP mode[EBP],invert JE smode MOV AX,3 CMP mode[EBP],replace JE smode MOV AX, 1003H	; paint smode: OUT DX, AX 		MOV DX, 03C4H	; AX = Default map mask; DX = Sequencer MOV AX, 0F02H OUT DX, AX 		MOV DX, 03CEH	; AL = Gaphics mode; AH = Read-Mode = 0/Write-Mode = 2 (bits 0,1) MOV AX, 0205H OUT DX, AX 		MOV AX, Height SUB AX, WORD y[EBP] DEC AX 		MOVSX EAX,AX IMUL EAX,width3 MOV ESI, x[EBP] SHR ESI, 3 ADD ESI, EAX AND ESI, 0FFFFH ADD ESI, 0A0000H MOV DX, 03CEH MOV CL, BYTE x[EBP] AND CL, 7 MOV AH, 128 SHR AH, CL 		MOV AL, 8 OUT DX, AX 		MOV AL, [ESI]	; latch bytes MOV AL, BYTE col[EBP] MOV [ESI], AL ret: END Dot; PROCEDURE CopyBlock*(sx, sy, w, h, dx, dy, mode: LONGINT); VAR top, right: INTEGER; x1, x2, x3, x4, x5, x6, x7, x8: LONGINT; help, help2, diff, start, end, msk, imsk, lh: LONGINT; leftmask, rightmask: CHAR; plane, count: SHORTINT; CODE {SYSTEM.i386} MOV EDX, dx[EBP] MOV AX,DX ADD AX, WORD w[EBP] MOV right[EBP], AX	; right := DX + W 		MOV AX, WORD dy[EBP] ADD AX, WORD h[EBP] MOV top[EBP], AX	; top := DY + H 			; IF DX < clipx THEN W := W - (clipx - DX); DX := clipx END CMP DX, clipx JGE ok0 MOV AX, clipx SUB AX, DX 		SUB WORD w[EBP], AX 		MOV DX, clipx ok0: ; IF DY < clipy THEN H := H - (clipy - DY); DY := clipy END MOV AX, WORD dy[EBP] CMP AX, clipy JGE ok1 MOV AX, clipy SUB AX, WORD dy[EBP] SUB WORD h[EBP], AX 		MOV AX, clipy MOV WORD dy[EBP], AX ok1: ; IF clipright < right THEN  W :=  clipright - DX END MOV AX, clipright CMP AX, right[EBP] JGE ok2 MOV AX, clipright SUB AX, DX 		MOV WORD w[EBP], AX ok2: ; IF cliptop < top THEN H := cliptop - DY END MOV AX, cliptop CMP AX, top[EBP] JGE ok3 MOV AX, cliptop SUB AX, WORD dy[EBP] MOV WORD h[EBP], AX ok3: ;	IF (W <= 0) OR (H <= 0) THEN RETURN END; CMP WORD w[EBP], 0 JLE ret CMP WORD h[EBP], 0 JLE ret LEA EAX, mask MOV msk[EBP], EAX	; msk := SYSTEM.ADR(mask[0]) LEA EAX, imask MOV imsk[EBP], EAX	; imsk := SYSTEM.ADR(imask[0]) MOV AX, height DEC AX 		MOVSX EAX,AX MOV lh[EBP], EAX	; h := height-1 MOV dx[EBP], EDX	; DX := DX 		MOV	EAX, lh[EBP] MOV	EBX, EAX SUB	EAX, sy[EBP]	; EAX := height - sy 		MOV	sy[EBP], EAX SUB	EBX, dy[EBP]	; EBX := height - dy 		MOV	dy[EBP], EBX MOV	EAX, sx[EBP]	; EAX := sx 		MOV	ECX, EAX MOV	EBX, EAX MOV	EDX, EAX SHR	EAX, 3	; EAX := sx DIV 8 AND	ECX, 7	; ECX := sx MOD 8 ADD	EBX, w[EBP] ADD	EDX, w[EBP] SHR	EBX, 3	; EBX := (sx+w) DIV 8 AND	EDX, 7	; EDX := (sx+w) MOD 8 MOV	x1[EBP], EAX	; x1 := sx DIV 8 MOV	x2[EBP], EBX	; x2 := (sx+w) DIV 8 MOV	x3[EBP], ECX	; x3 := sx MOD 8 INC	EDX MOV	x4[EBP], EDX	; x4 := (sx+w) MOD 8 (+1) MOV	EAX, dx[EBP]	; EAX := dx 		MOV	ECX, EAX MOV	EBX, EAX MOV	EDX, EAX SHR	EAX, 3	; EAX := dx DIV 8 AND	ECX, 7	; ECX := dx MOD 8 ADD	EBX, w[EBP]	; EBX := dx +w ADD	EDX, w[EBP] SHR	EBX, 3	; EBX := (dx+w) DIV 8 AND	EDX, 7	; EDX := (dx+w) MOD 8 MOV	x5[EBP], EAX	; x5 := dx DIV 8 MOV	x6[EBP], EBX	; x6 := (dx+w) DIV 8 MOV	x7[EBP], ECX	; x7 := dx MOD 8 INC	EDX MOV	x8[EBP], EDX	; x8 := (dx+w) MOD 8 MOV	ESI, sy[EBP] IMUL	ESI, width3	; w3[EBP] ADD	ESI, x1[EBP]	; ESI := startbyte source bottomleft AND ESI, 0FFFFH ADD ESI, 0A0000H	; offset of screen MOV	EDI, dy[EBP] IMUL	EDI, width3	; w3[EBP] ADD	EDI, EAX AND EDI, 0FFFFH ADD EDI, 0A0000H	; offset of screen MOV	start[EBP], ESI	; starbyte source bottom left MOV	end[EBP], EDI	; startbyte dest bottom left MOV	DX, 03CEH MOV	AX, 0005 OUT	DX, AX	; read/writemode = 0 MOV	AX, 0001 OUT	DX, AX	; enable/reset = 0000b MOV	AH, 0 MOV	AL, 3 OUT	DX, AX	; replacemode MOV	EBX, x8[EBP] DEC	EBX MOV	EDX, msk[EBP] MOV	AH, [EDX][EBX] ;			MOV	AH, mask[EBX] MOV	rightmask[EBP], AH 		MOV	EBX, x7[EBP] MOV	EDX, imsk[EBP] MOV	AH, [EDX][EBX] ;			MOV	AH, imask[EBX] MOV	leftmask[EBP], AH 		MOV	EBX, x6[EBP] SUB	EBX, x5[EBP]	; EBX := difference in bytes dx/dx+w DEC	EBX MOV	diff[EBP], EBX JGE	inmorebytes MOV	DH, rightmask[EBP]	; EBX = 0 /only one byte AND	DH, leftmask[EBP] MOV	leftmask[EBP], DH 		MOV	rightmask[EBP], DH inmorebytes: MOV	EDX, h[EBP]	; EDX := h 		MOV	EAX, sx[EBP]	; EAX := sx 		MOV	EBX, sy[EBP]	; EBX := sy CMP	EAX, dx[EBP]	; sx < dx ? JGE	CB1	; no -> goto CB1 MOV	ECX, x8[EBP]	; sx < dx ! SUB	ECX, x4[EBP]	; ECX := difference between s/dest x 		ADD	ECX, 32 AND	CL, 1FH	; CL := rotate shift count CMP	BX, WORD dy[EBP]	; sy < dy ? was EBX JL	CB10	; yes goto CB10 JMP	CB13	; else goto CB13 CB1: SUB	ECX, x3[EBP]	; sx >= dx 		ADD	ECX, 32 AND	CL, 1FH	; CL:= rotate shift count CMP	BX, WORD dy[EBP]	; sy >= dy? JGE	CB12	; yes goto CB12 CB11: MOV	help[EBP], EDX	; (sx >= dx) & (sy < dy) / save linecounter MOV	EBX, diff[EBP] CMP	EBX, 1 JLE	byte11	; in 1 Byte => normal CopyBlock CMP	CL, 0	; rotateoffset = 0 ? JE	qCB11	; QuickCopy byte11: MOV	count[EBP], 3	; there are 4 Bitplanes MOV	plane[EBP], 8	; begin with plane 4 CB11h: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX	; select plane to read MOV	AH, leftmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	DX, 03C4H MOV	AH, plane[EBP]	; set bitplanemask MOV	AL, 2 OUT	DX, AX	; set sequencer XOR	EAX, EAX MOV	AH, [ESI] MOV	AL, 1[ESI] ADD	ESI, 2 ROR	EAX, CL CMP	EBX, 0	; in one byte ? JL	cbl31 cbl6i: MOV	DL, [EDI]	; latch bytes MOV	[EDI], AH 		INC	EDI ROL	EAX, 8 CMP	EBX, 0	; in 2 bytes ? JE	cbl3 ;** MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H	; all maskbits OUT	DX, AX 		MOV	EAX, help2[EBP] cbl6: ROL	EAX, CL 		MOV	AL, [ESI] INC	ESI ROR	EAX, CL 		MOV	[EDI], AH 		INC	EDI ROL	EAX, 8 DEC	BX JG	cbl6 cbl3: MOV	EBX, x6[EBP] SUB	EBX, x5[EBP] MOV	help2[EBP], EBX MOV	EBX, x2[EBP] SUB	EBX, x1[EBP] CMP	EBX, help2[EBP] JE	cbl31 ROL	EAX, CL 		MOV	AL, [ESI] ROR	EAX, CL cbl31: PUSH	EAX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX	; set right dest bitmask POP	EAX MOV	DL, [EDI] MOV	[EDI], AH 		MOV	ESI, start[EBP] MOV	EDI, end[EBP] SHR	plane[EBP], 1 MOV	EBX, diff[EBP] DEC	count[EBP] JGE	CB11h MOV	EDX, help[EBP]	; next line / get linecounter SUB	start[EBP], 80 SUB	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] MOV	count[EBP], 3 MOV	plane[EBP], 8 DEC	EDX MOV	help[EBP], EDX	; save new linecounter CMP	EDX, 0 JG	CB11h JMP	resetgrafCB CB12: MOV	EAX, h[EBP]	; (sx >= dx) & (sy >= dy) DEC	EAX IMUL	EAX, width3	; w3[EBP]	; (Note: EDX is not modified) SUB	ESI, EAX SUB	EDI, EAX MOV	start[EBP], ESI MOV	end[EBP], EDI MOV	help[EBP], EDX	; save linecounter MOV	EBX, diff[EBP] CMP	EBX, 1 JLE	byte12 CMP	CL, 0	; rotate shift = 0 ? JE	qCB12	; quick CopyBlock byte12: MOV	count[EBP], 3	; there are 4 Bitplanes MOV	plane[EBP], 8 cbl1: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX	; select plane to read MOV	AH, leftmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX	; set sequencer XOR	EAX, EAX MOV	AH, [ESI] MOV	AL, 1[ESI] ADD	ESI, 2 ROR	EAX, CL 		CMP	EBX, 0 JL	cbl41 cbl7i: MOV	DL, [EDI]	; latch bytes MOV	[EDI], AH 		INC	EDI ROL	EAX, 8	; ready for new out CMP	EBX, 0	; in 2 bytes ? JE	cbl4 ;** MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H	; all maskbits OUT	DX, AX 		MOV	EAX, help2[EBP] cbl7: ROL	EAX, CL 		MOV	AL, [ESI] INC	ESI ROR	EAX, CL 		MOV	[EDI], AH 		INC	EDI ROL	EAX, 8 DEC	BX JG	cbl7 cbl4: MOV	EBX, x6[EBP] SUB	EBX, x5[EBP] MOV	help2[EBP], EBX MOV	EBX, x2[EBP] SUB	EBX, x1[EBP] CMP	EBX, help2[EBP] JE	cbl41 ROL	EAX, CL 		MOV	AL, [ESI] ROR	EAX, CL cbl41: PUSH	EAX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX	; set right dest bitmask POP	EAX MOV	DL, [EDI] MOV	[EDI], AH 		MOV	ESI, start[EBP] MOV	EDI, end[EBP] SHR	plane[EBP], 1 MOV	EBX, diff[EBP] DEC	count[EBP] JGE	cbl1 MOV	EDX, help[EBP]	; next line / get linecounter ADD	start[EBP], 80 ADD	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] MOV	plane[EBP], 8 MOV	count[EBP], 3 DEC	EDX MOV	help[EBP], EDX	; save new linecounter CMP	EDX, 0 JG	cbl1 JMP	resetgrafCB CB10: MOV	EAX, x2[EBP]	; (sx < dx) & (sy < dy) SUB	EAX, x1[EBP] ADD	ESI, EAX MOV	EAX, x6[EBP] SUB	EAX, x5[EBP] ADD	EDI, EAX MOV	start[EBP], ESI	; startbyte source bottom right MOV	end[EBP], EDI	; starbyte dest bottom right MOV	help[EBP], EDX	; save linecounter MOV	EBX, diff[EBP] CMP	EBX, 1 JLE	byte10 CMP	CL, 0 JE	qCB10	; Quick CopyBlock byte10: MOV	count[EBP], 3	; there are 4 Bitplanes MOV	plane[EBP], 8 cbl10: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX	; select plane to read MOV	AH, rightmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX	; set sequencer XOR	EAX, EAX MOV	AL, [ESI] MOV	AH, -1[ESI] SUB	ESI, 2 ROR	EAX, CL CMP	EBX, 0	; in one byte ? JGE	cbl11i MOV	DL, rightmask[EBP]	; xchg masks MOV	leftmask[EBP], DL 		JMP	cbl121 cbl11i: MOV	DL, [EDI]	; latch bytes MOV	[EDI], AL 		DEC	EDI ROR	EAX, 8 CMP	EBX, 0 JE	cbl12 ;** MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H	; all maskbits OUT	DX, AX 		MOV	EAX, help2[EBP] cbl11: ROL	EAX, CL 		MOV	AH, [ESI] DEC	ESI ROR	EAX, CL 		MOV	[EDI], AL 		DEC	EDI ROR	EAX, 8 DEC	BX JG	cbl11 cbl12: MOV	EBX, x6[EBP] SUB	EBX, x5[EBP] MOV	help2[EBP], EBX MOV	EBX, x2[EBP] SUB	EBX, x1[EBP] CMP	EBX, help2[EBP] JE	cbl121 ROL	EAX, CL 		MOV	AH, [ESI] ROR	EAX, CL cbl121: PUSH	EAX MOV	DX, 03CEH MOV	AH, leftmask[EBP] MOV	AL, 8 OUT	DX, AX	; set left dest bitmask POP	EAX MOV	DL, [EDI] MOV	[EDI], AL 		MOV	ESI, start[EBP] MOV	EDI, end[EBP] SHR	plane[EBP], 1 MOV	EBX, diff[EBP] DEC	count[EBP] JGE	cbl10 MOV	EDX, help[EBP]	; next line / get linecounter SUB	start[EBP], 80 SUB	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] MOV	plane[EBP], 8 MOV	count[EBP], 3 DEC	EDX MOV	help[EBP], EDX	; save new linecounter CMP	EDX, 0 JG	cbl10 JMP	resetgrafCB CB13: MOV	EAX, h[EBP]	; (sx < dx) & (sy >= dy) DEC	EAX IMUL	EAX, width3	; w3[EBP] SUB	ESI, EAX SUB	EDI, EAX MOV	EAX, x2[EBP] SUB	EAX, x1[EBP] ADD	ESI, EAX MOV	EAX, x6[EBP] SUB	EAX, x5[EBP] ADD	EDI, EAX MOV	start[EBP], ESI MOV	end[EBP], EDI MOV	help[EBP], EDX	; save linecounter MOV	EBX, diff[EBP] CMP	EBX, 1 JLE	byte13 CMP	CL, 0 JE	qCB13 byte13: MOV	count[EBP], 3	; there are 4 Bitplanes MOV	plane[EBP], 8 cbl13: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX	; select plane to read MOV	AH, rightmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX	; set sequencer XOR	EAX, EAX MOV	AL, [ESI] MOV	AH, -1[ESI] SUB	ESI, 2 ROR	EAX, CL 		CMP	EBX, 0 JGE	cbl14i MOV	DL, rightmask[EBP] MOV	leftmask[EBP], DL 		JMP	cbl151 cbl14i: MOV	DL, [EDI]	; latch bytes MOV	[EDI], AL 		DEC	EDI ROR	EAX, 8 CMP	EBX, 0	; in 2 bytes ? JE	cbl15 ;** MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H	; all maskbits OUT	DX, AX 		MOV	EAX, help2[EBP] cbl14: ROL	EAX, CL 		MOV	AH, [ESI] DEC	ESI ROR	EAX, CL 		MOV	[EDI], AL 		DEC	EDI ROR	EAX, 8 DEC	BX JG	cbl14 cbl15: MOV	EBX, x6[EBP] SUB	EBX, x5[EBP] MOV	help2[EBP], EBX MOV	EBX, x2[EBP] SUB	EBX, x1[EBP] CMP	EBX, help2[EBP] JE	cbl151 ROL	EAX, CL 		MOV	AH, [ESI] ROR	EAX, CL cbl151: PUSH	EAX MOV	DX, 03CEH MOV	AH, leftmask[EBP] MOV	AL, 8 OUT	DX, AX	; set left dest bitmask POP	EAX MOV	DL, [EDI] MOV	[EDI], AL 		MOV	ESI, start[EBP] MOV	EDI, end[EBP] SHR	plane[EBP], 1 MOV	EBX, diff[EBP] DEC	count[EBP] JGE	cbl13 MOV	EDX, help[EBP]	; next line / get linecounter ADD	start[EBP], 80 ADD	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] MOV	count[EBP], 3 MOV	plane[EBP], 8 DEC	EDX MOV	help[EBP], EDX	; save new linecounter CMP	EDX, 0 JG	cbl13 JMP	resetgrafCB qCB12: MOV	DX, 03CEH	; Quick CopyBlock begin MOV	AH, leftmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	count[EBP], 3 MOV	plane[EBP], 8 q12lloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q12lloop	; next plane MOV	DX, 03C4H MOV	AH, 00FH MOV	AL, 2 OUT	DX, AX	; all planes again MOV	DX, 03CEH INC	ESI INC	EDI MOV	AX, 0105H	; writemode 1 OUT	DX, AX qcbl1: MOV	AL, [ESI] INC	ESI MOV	[EDI], AH 		INC	EDI DEC	BX JG	qcbl1 qcbl7: MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX	; set right dest bitmask MOV	AX, 0005	; writemode 0 OUT	DX, AX 		MOV	count[EBP], 3 MOV	plane[EBP], 8 q12rloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q12rloop	; next plane MOV	EBX, diff[EBP] ADD	start[EBP], 80 ADD	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] DEC	help[EBP]	; dec linecounter JG	qCB12 JMP	resetgrafCB qCB11: MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	count[EBP], 3 MOV	plane[EBP], 8 q11lloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q11lloop	; next plane MOV	DX, 03C4H MOV	AH, 00FH MOV	AL, 2 OUT	DX, AX	; all panes again MOV	DX, 03CEH INC	ESI INC	EDI MOV	AX, 0105H	; writemode 1 OUT	DX, AX qcbl6: MOV	AL, [ESI] INC	ESI MOV	[EDI], AH 		INC	EDI DEC	BX JG	qcbl6 qcbl3: MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX	; set right dest bitmask MOV	AX, 0005	; writemode 0 OUT	DX, AX 		MOV	count[EBP], 3 MOV	plane[EBP], 8 q11rloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q11rloop	; next plane MOV	EBX, diff[EBP] SUB	start[EBP], 80 SUB	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] DEC	help[EBP]	; dec linecounter JG	qCB11 JMP	resetgrafCB qCB10: MOV	DX, 03CEH MOV	AH, rightmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	count[EBP], 3 MOV	plane[EBP], 8 q10rloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q10rloop	; next plane MOV	DX, 03C4H MOV	AH, 00FH MOV	AL, 2 OUT	DX, AX	; all panes again MOV	DX, 03CEH DEC	ESI DEC	EDI MOV	AX, 0105H	; writemode 1 OUT	DX, AX qcbl10: MOV	AL, [ESI] DEC	ESI MOV	[EDI], AH 		DEC	EDI DEC	BX JG	qcbl10 qcbl12: MOV	DX, 03CEH MOV	AX, 0005	; writemode 0 OUT	DX, AX 		MOV	AH, leftmask[EBP] MOV	AL, 8 OUT	DX, AX	; set left dest bitmask MOV	count[EBP], 3 MOV	plane[EBP], 8 q10lloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q10lloop	; next plane MOV	EBX, diff[EBP] SUB	start[EBP], 80 SUB	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] DEC	help[EBP]	; dec linecounter JG	qCB10 JMP	resetgrafCB qCB13: MOV	DX, 03CEH MOV	AH, rightmask[EBP]	; bitmask select MOV	AL, 8 OUT	DX, AX	; set mask at destination MOV	AH, 0 MOV	AL, 3 OUT	DX, AX 		MOV	count[EBP], 3 MOV	plane[EBP], 8 q13rloop: MOV	DX, 03CEH MOV	AH, count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q13rloop	; next plane MOV	DX, 03C4H MOV	AH, 00FH MOV	AL, 2 OUT	DX, AX	; all panes again MOV	DX, 03CEH DEC	ESI DEC	EDI MOV	AX, 0105H	; writemode 1 OUT	DX, AX qcbl13: MOV	AL, [ESI] DEC	ESI MOV	[EDI], AH 		DEC	EDI DEC	BX JG	qcbl13 qcbl14: MOV	DX, 03CEH MOV	AX, 0005	; writemode 0 OUT	DX, AX 		MOV	AH, leftmask[EBP] MOV	AL, 8 OUT	DX, AX	; set left dest bitmask MOV	count[EBP], 3 MOV	plane[EBP], 8 q13lloop: MOV	DX, 03CEH MOV	AH, BYTE count[EBP] MOV	AL, 4 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, plane[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	CL, [ESI]	; fetch source MOV	AL, [EDI]	; latch at destiation MOV	[EDI], CL	; set source ; 		MOV	DX, 03CEH SHR	plane[EBP], 1 DEC	count[EBP] JGE	q13lloop	; next plane MOV	EBX, diff[EBP] ADD	start[EBP], 80 ADD	end[EBP], 80 MOV	ESI, start[EBP] MOV	EDI, end[EBP] DEC	help[EBP]	; dec linecounter JG	qCB13 JMP	resetgrafCB resetgrafCB: MOV	DX, 03CEH MOV	AX, 0FF08H	; default bitmask OUT	DX, AX 		MOV	AX, 0005	; default mode-reg OUT	DX, AX 		MOV	AX, 0003	; default Function-Select OUT	DX, AX 		MOV	AX, 0001	; default enable set/reset OUT	DX, AX 		MOV	DX, 03C4H MOV	AX, 0F02H	; default map mask OUT	DX, AX endCB: ret: END CopyBlock; PROCEDURE SetMode*(x: LONGINT; s: SET); BEGIN END SetMode; PROCEDURE CPTranslate(pat: LONGINT; cpX, cpY, cpW, cpH: INTEGER;  VAR buf: ARRAY OF INTEGER); VAR cpw, cph, cpsw: SHORTINT; CODE {SYSTEM.i386} MOV BX,cpW[EBP] ADD BX,7 SHR BX,3 MOV cpw[EBP],BL				 ; cpw := cpW DIV 8 MOV ESI,pat[EBP] XOR EAX,EAX MOV AL,[ESI] ADD AX,7 SHR AX,3 MOV cpsw[EBP],AL				 ; cpsw := p.w DIV 8 MOV EDI,buf[EBP] MOV AX,cpW[EBP] MOV [EDI],AL				 ; new p.w 		INC EDI MOV AX,cpH[EBP]				 ; new p.h 		MOV [EDI],AL INC EDI MOVSX BX,cpsw[EBP] MOV AX,cpY[EBP] IMUL AX,BX MOVSX EAX,AX ADD ESI,EAX MOV CX,cpX[EBP] SHR CX,3 MOVSX ECX,CX ADD ESI,ECX ADD ESI,2					; ESI := Sourcepos for Copyloop MOV cph[EBP],0					; init loop variables MOV DH, 0 MOV DL,cph[EBP] MOV CX,cpX[EBP] AND CX,7					 ; cpX MOD 8 loopcp: CMP cpH[EBP],DX JLE l7cp					 ; height reached ? MOV EAX,[ESI] SHR EAX,CL				 ; in proper position PUSH ECX MOV EBX,-2 MOV CX,cpW[EBP] SHL EBX,CL SHR EBX, 1 NOT EBX AND EAX,EBX POP ECX MOV [EDI],EAX				; copy for a new pattern MOVSX EAX,cpsw[EBP] ADD ESI,EAX				 ; one line in source up 		MOVSX EAX,cpw[EBP] ADD EDI,EAX				 ; one line at destination up 		INC DX 		JMP loopcp l7cp: END CPTranslate; PROCEDURE CP1(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AH, col[EBP] MOV AL, 2 OUT DX, AX 		LEA EAX, rev	; MOV EAX, reverse[EBP] MOV DL, h[EBP] XOR EBX, EBX cploop2: MOV BL, [ESI] INC ESI SHL BL, CL 		MOV BL, [EAX][EBX] MOV DH, [EDI]	; latch byte MOV [EDI], BL	; set pattern SUB EDI, width3	; w3[EBP] DEC DL 		JG cploop2 END CP1; PROCEDURE CP2(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AH, col[EBP] MOV AL, 2 OUT DX, AX 		LEA EAX, rev	; MOV EAX, reverse[EBP] cploop3: XOR EBX, EBX MOV BL, [ESI] INC ESI SHL BX, CL 		MOV DX, BX 		AND BX, 0FFH MOV DL, [EAX][EBX] MOV BL, DH 		MOV DH, [EAX][EBX] MOV BL, [EDI]	; latch byte MOV [EDI], DL	; set pattern MOV BL, 1[EDI]	; latch byte MOV 1[EDI], DH	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop3 END CP2; PROCEDURE CP3(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AH, col[EBP] MOV AL, 2 OUT DX, AX 		LEA EAX, rev	; MOV EAX, reverse[EBP] cploop5: XOR EBX, EBX MOV BX, [ESI] ADD ESI, 2 SHL BX, CL 		MOV DX, BX 		AND BX, 0FFH MOV DL, [EAX][EBX] MOV BL, DH 		MOV DH, [EAX][EBX] MOV BL, [EDI]	; latch byte MOV [EDI], DL	; set pattern MOV BL, 1[EDI]	; latch byte MOV 1[EDI], DH	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop5 END CP3; PROCEDURE CP4(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AH, col[EBP] MOV AL, 2 OUT DX, AX 		LEA EAX, rev	; MOV EAX, reverse[EBP] cploop7: XOR EBX, EBX MOV BX, [ESI] ADD ESI, 2 SHL EBX, CL 		MOV DX, BX 		SHR EBX, 16 AND BX, 0FFH MOV CH, [EAX][EBX] MOV BL, DL 		MOV DL, [EAX][EBX] MOV BL, DH 		MOV DH, [EAX][EBX] MOV BL, [EDI]	; latch byte MOV [EDI], DL	; set pattern MOV BL, 1[EDI]	; latch byte MOV 1[EDI], DH	; set pattern MOV BL, 2[EDI]	; latch byte MOV 2[EDI], CH	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop7 END CP4; PROCEDURE CP5(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AH, col[EBP] MOV AL, 2 OUT DX, AX 		LEA EAX, rev	; MOV EAX, reverse[EBP] cploop9: MOV EBX, [ESI] ADD ESI, 3 AND EBX, 0FFFFFFH SHL EBX, CL 		PUSH ECX MOV DX, BX 		SHR EBX, 16 MOV CX, BX 		AND BX, 0FFH MOV CL, [EAX][EBX] MOV BL, CH 		MOV CH, [EAX][EBX] MOV BL, DL 		MOV DL, [EAX][EBX] MOV BL, DH 		MOV DH, [EAX][EBX] MOV BL, [EDI]	; latch byte MOV [EDI], DL	; set pattern MOV BL, 1[EDI]	; latch byte MOV 1[EDI], DH	; set pattern MOV BL, 2[EDI]	; latch byte MOV 2[EDI], CL	; set pattern MOV BL, 3[EDI]	; latch byte MOV 3[EDI], CH	; set pattern POP ECX SUB EDI, width3 DEC h[EBP] JG cploop9 END CP5; PROCEDURE CP6(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AH, col[EBP] MOV AL, 2 OUT DX, AX 		LEA EAX, rev	; MOV EAX, reverse[EBP] cploop11: MOV EBX, [ESI] ADD ESI, 4 PUSH ESI XOR ESI, ESI SHLD ESI, EBX, CL 		SHL EBX, CL 		PUSH ECX MOV DX, BX 		SHR EBX, 16 MOV CX, BX 		AND BX, 0FFH MOV CL, [EAX][EBX] MOV BL, CH 		MOV CH, [EAX][EBX] MOV BL, DL 		MOV DL, [EAX][EBX] MOV BL, DH 		MOV DH, [EAX][EBX] MOV BH, [EAX][ESI] MOV BL, [EDI]	; latch byte MOV [EDI], DL	; set pattern MOV BL, 1[EDI]	; latch byte MOV 1[EDI], DH	; set pattern MOV BL, 2[EDI]	; latch byte MOV 2[EDI], CL	; set pattern MOV BL, 3[EDI]	; latch byte MOV 3[EDI], CH	; set pattern MOV BL, 4[EDI]	; latch byte MOV 4[EDI], BH	; set pattern POP ECX POP ESI SUB EDI, width3 DEC h[EBP] JG cploop11 END CP6; PROCEDURE CP7(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer cploop1: MOV AX, 0F02H OUT DX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 0803H OUT DX, AX 		XOR EBX, EBX MOV BL, [ESI] INC ESI SHL BL, CL 		LEA EDX, rev MOV BL, [EDX][EBX] MOV BH, [EDI]	; latch byte NOT BL 		MOV [EDI], BL	; clear pattern NOT BL 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 1003H OUT DX, AX 		MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AL, 2 MOV AH, col[EBP] OUT DX, AX 		MOV BH, [EDI]	; latch byte MOV [EDI], BL	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop1 END CP7; PROCEDURE CP8(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer cploop4: MOV AX, 0F02H OUT DX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 0803H OUT DX, AX 		XOR EBX, EBX MOV BL, [ESI] INC ESI SHL BX, CL 		LEA EDX, rev MOV AX, BX 		AND BX, 0FFH MOV AL, [EDX][EBX] MOV BL, AH 		MOV AH, [EDX][EBX] NOT AX 		MOV BH, [EDI]	; latch byte MOV [EDI], AL	; clear pattern MOV BH, 1[EDI]	; latch byte MOV 1[EDI], AH	; clear pattern NOT AX 		MOV BX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 1003H OUT DX, AX 		MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AL, 2 MOV AH, col[EBP] OUT DX, AX 		MOV CH, [EDI]	; latch byte MOV [EDI], BL	; set pattern MOV CH, 1[EDI]	; latch byte MOV 1[EDI], BH	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop4 END CP8; PROCEDURE CP9(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer cploop6: MOV AX, 0F02H OUT DX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 0803H OUT DX, AX 		XOR EBX, EBX MOV BX, [ESI] ADD ESI, 2 SHL BX, CL 		LEA EDX, rev MOV AX, BX 		AND BX, 0FFH MOV AL, [EDX][EBX] MOV BL, AH 		MOV AH, [EDX][EBX] NOT AX 		MOV BH, [EDI]	; latch byte MOV [EDI], AL	; clear pattern MOV BH, 1[EDI]	; latch byte MOV 1[EDI], AH	; clear pattern NOT AX 		MOV BX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 1003H OUT DX, AX 		MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AL, 2 MOV AH, col[EBP] OUT DX, AX 		MOV CH, [EDI]	; latch byte MOV [EDI], BL	; set pattern MOV CH, 1[EDI]	; latch byte MOV 1[EDI], BH	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop6 END CP9; PROCEDURE CP10(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 cploop8: MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AX, 0F02H OUT DX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 0803H OUT DX, AX 		XOR EBX, EBX MOV BX, [ESI] ADD ESI, 2 SHL EBX, CL 		LEA EDX, rev MOV AX, BX 		SHR EBX, 16 AND BX, 0FFH MOV CH, [EDX][EBX] MOV BL, AL 		MOV AL, [EDX][EBX] MOV BL, AH 		MOV AH, [EDX][EBX] NOT AX 		NOT CH 		MOV BH, [EDI]	; latch byte MOV [EDI], AL	; clear pattern MOV BH, 1[EDI]	; latch byte MOV 1[EDI], AH	; clear pattern MOV BH, 2[EDI]	; latch byte MOV 2[EDI], CH	; clear pattern NOT CH 		NOT AX 		MOV BX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 1003H OUT DX, AX 		MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AL, 2 MOV AH, col[EBP] OUT DX, AX 		MOV DH, [EDI]	; latch byte MOV [EDI], BL	; set pattern MOV DH, 1[EDI]	; latch byte MOV 1[EDI], BH	; set pattern MOV DH, 2[EDI]	; latch byte MOV 2[EDI], CH	; set pattern SUB EDI, width3 DEC h[EBP] JG cploop8 END CP10; PROCEDURE CP11(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 cploop10: MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AX, 0F02H OUT DX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 0803H OUT DX, AX 		MOV EBX, [ESI] AND EBX, 0FFFFFFH ADD ESI, 3 SHL EBX, CL 		PUSH ECX LEA EDX, rev MOV AX, BX 		SHR EBX, 16 MOV CX, BX 		AND BX, 0FFH MOV CL, [EDX][EBX] MOV BL, CH 		MOV CH, [EDX][EBX] MOV BL, AL 		MOV AL, [EDX][EBX] MOV BL, AH 		MOV AH, [EDX][EBX] NOT AX 		NOT CX 		MOV BH, [EDI]	; latch byte MOV [EDI], AL	; clear pattern MOV BH, 1[EDI]	; latch byte MOV 1[EDI], AH	; clear pattern MOV BH, 2[EDI]	; latch byte MOV 2[EDI], CL	; clear pattern MOV BH, 3[EDI]	; latch byte MOV 3[EDI], CH	; clear pattern NOT CX 		NOT AX 		MOV BX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 1003H OUT DX, AX 		MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AL, 2 MOV AH, col[EBP] OUT DX, AX 		MOV DH, [EDI]	; latch byte MOV [EDI], BL	; set pattern MOV DH, 1[EDI]	; latch byte MOV 1[EDI], BH	; set pattern MOV DH, 2[EDI]	; latch byte MOV 2[EDI], CL	; set pattern MOV DH, 3[EDI]	; latch byte MOV 3[EDI], CH	; set pattern POP ECX SUB EDI, width3 DEC h[EBP] JG cploop10 END CP11; PROCEDURE CP12(col: CHAR; dest, pat, X: LONGINT;  h: SHORTINT); CODE {SYSTEM.i386} MOV EDI, dest[EBP] MOV ESI, pat[EBP]	; patternaddress ADD ESI, 2 MOV ECX, X[EBP]	; X MOD 8 AND ECX, 7 cploop12: MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AX, 0F02H OUT DX, AX 		MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 0803H OUT DX, AX 		MOV EBX, [ESI] ADD ESI, 4 PUSH ESI XOR ESI, ESI SHLD ESI, EBX, CL 		SHL EBX, CL 		PUSH ECX LEA EDX, rev MOV AX, BX 		SHR EBX, 16 MOV CX, BX 		AND BX, 0FFH MOV CL, [EDX][EBX] MOV BL, CH 		MOV CH, [EDX][EBX] MOV BL, AL 		MOV AL, [EDX][EBX] MOV BL, AH 		MOV AH, [EDX][EBX] MOV BL, [EDX][ESI] NOT AX 		NOT CX 		NOT BL 		MOV BH, [EDI]	; latch byte MOV [EDI], AL	; clear pattern MOV BH, 1[EDI]	; latch byte MOV 1[EDI], AH	; clear pattern MOV BH, 2[EDI]	; latch byte MOV 2[EDI], CL	; clear pattern MOV BH, 3[EDI]	; latch byte MOV 3[EDI], CH	; clear pattern MOV BH, 4[EDI]	; latch byte MOV 4[EDI], BL	; clear pattern NOT BL 		NOT CX 		NOT AX 		MOV DX, BX 		MOV BX, AX 		PUSH EDX MOV EDX, 03CEH	; AL = Data/Rotate; AH = Modus; DX = Graphic-Controller MOV AX, 1003H OUT DX, AX 		MOV EDX, 03C4H	; AL = Plane select; AH = Bitplanemask; DX = Sequencer MOV AL, 2 MOV AH, col[EBP] OUT DX, AX 		POP EDX MOV DH, [EDI]	; latch byte MOV [EDI], BL	; set pattern MOV DH, 1[EDI]	; latch byte MOV 1[EDI], BH	; set pattern MOV DH, 2[EDI]	; latch byte MOV 2[EDI], CL	; set pattern MOV DH, 3[EDI]	; latch byte MOV 3[EDI], CH	; set pattern MOV DH, 4[EDI]	; latch byte MOV 4[EDI], DL	; set pattern POP ECX POP ESI SUB EDI, width3 DEC h[EBP] JG cploop12 END CP12; PROCEDURE CopyPattern*(col: Color; pat: Pattern; x, y, mode: LONGINT); VAR dest, i, diff: LONGINT; w, h: SHORTINT; x1, y1, cpX, cpY, cpW, cpH, nofbytes: INTEGER; buf: ARRAY 256 OF INTEGER; lm, rm: CHAR; BEGIN SYSTEM.GET(pat, w); SYSTEM.GET(pat+1, h); cpW := SHORT(w + x); cpH := SHORT(h + y); x1 := SHORT(x); y1 := SHORT(y); IF x1 < clipx THEN x := clipx END; IF y1 < clipy THEN y := clipy END; IF cpW > clipright THEN cpW :=  clipright END; IF cpH > cliptop THEN cpH := cliptop END; cpW := cpW - SHORT(x); cpH := cpH - SHORT(y); cpX := SHORT(x) - x1; cpY := SHORT(y) - y1; IF (cpW <= 0) OR (cpH <= 0) OR (cpX < 0) OR (cpY < 0) THEN RETURN END; IF (cpW # w) OR (cpH # h) THEN CPTranslate(pat, cpX, cpY, cpW, cpH, buf); pat := SYSTEM.ADR(buf[0]) END; SYSTEM.GET(pat, w); SYSTEM.GET(pat+1, h); dest := ((Height-SHORT(y)-1) * width3 + SHORT(x) DIV 8) MOD 10000H; INC(dest, 0A0000H);	(* display offset *) (*help1 := (SHORT(x) + w-1) MOD 8;*) diff := (SHORT(x) + w-1) DIV 8 - (SHORT(x) DIV 8); SYSTEM.PORTOUT(03CEH, SYSTEM.VAL(INTEGER, 0FF08H));	(* AX = Default bitmask; DX = Graphic-Controller *) SYSTEM.PORTOUT(03CEH, SYSTEM.VAL(INTEGER, 5));	(* AL = Graphics mode; AH = Read-Mode = 0/Write-Mode = 0 (bits 0,1) *) IF mode = invert THEN SYSTEM.PORTOUT(03CEH, SYSTEM.VAL(INTEGER, 1803H));	(* AX = invert mode; DX = Graphic-Controller *) IF w <= 8 THEN IF diff = 0 THEN CP1(CHR(col), dest, pat, SHORT(x), h) 				ELSE CP2(CHR(col), dest, pat, SHORT(x), h) 				END ELSIF w <= 16 THEN IF diff = 1 THEN CP3(CHR(col), dest, pat, SHORT(x), h) 				ELSE CP4(CHR(col), dest, pat, SHORT(x), h) 				END ELSIF w <= 24 THEN CP5(CHR(col), dest, pat, SHORT(x), h) 			ELSE CP6(CHR(col), dest, pat, SHORT(x), h) 			END ELSE (* paint & replace *) IF w <= 8 THEN IF diff = 0 THEN CP7(CHR(col), dest, pat, SHORT(x), h) 				ELSE CP8(CHR(col), dest, pat, SHORT(x), h) 				END ELSIF w <= 16 THEN IF diff = 1 THEN CP9(CHR(col), dest, pat, SHORT(x), h) 				ELSE CP10(CHR(col), dest, pat, SHORT(x), h) 				END ELSIF w <= 24 THEN CP11(CHR(col), dest, pat, SHORT(x), h) 			ELSE CP12(CHR(col), dest, pat, SHORT(x), h) 			END END END CopyPattern; PROCEDURE ReplConst1(col: CHAR; H, start: LONGINT;  rm, lm: CHAR); CODE {SYSTEM.i386} MOV AH, lm[EBP] AND AH, rm[EBP] MOV AL, 8 MOV EDX, 03CEH OUT DX, AX	; Bitmask MOV AH, col[EBP] MOV ECX, H[EBP] MOV ESI, start[EBP] rcloop1: MOV AL, [ESI]	; latch bytes MOV [ESI], AH 		SUB ESI, width3	;w3[EBP] LOOP rcloop1 END ReplConst1; PROCEDURE ReplConst2(col: CHAR; H: INTEGER;  start, end: LONGINT;  rm, lm: CHAR); VAR temp: LONGINT; CODE {SYSTEM.i386} MOV ESI, start[EBP] MOV BH, col[EBP] MOV EDI, end[EBP] SUB EDI, ESI	; difference beween start and end MOV temp[EBP], EDI	; save difference beween start and end MOV EDX, 03CEH		; set Graphic controller rcloop2: MOV AH, lm[EBP]	; prepare left mask MOV AL, 8 OUT DX, AX	; set left Bitmask MOV AL, [ESI]	; latch byte MOV [ESI], BH	; set byte MOV AX, 0FF08H	; prepare full mask OUT DX, AX	; set full mask MOV ECX,ESI INC ECX rclabel2: CMP EDI, 1 JLE rclabel1 MOV AL, [ECX]	; latch bytes MOV [ECX], BH	; set bytes DEC EDI INC ECX JMP rclabel2 rclabel1: MOV AH, rm[EBP]	; prepare right mask MOV AL, 8 OUT DX, AX	; set right Bitmask MOV AL, [ECX]	; latch byte MOV [ECX], BH	; set byte SUB ESI, width3;	w3[EBP]	; next line DEC H[EBP] MOV EDI, temp[EBP] JG rcloop2 END ReplConst2; PROCEDURE ReplConst*(col: Color; x, y, w, h, mode: LONGINT); VAR right, top, X, Y, W, H: INTEGER; addr, start, end: LONGINT; rm, lm: CHAR; BEGIN X := SHORT(x); Y := SHORT(y);  W := SHORT(w);  H := SHORT(h); top := Y + H; right := X + W; 		IF X < clipx THEN X := clipx END; IF Y < clipy THEN Y := clipy END; IF clipright < right THEN right :=  clipright END; IF cliptop < top THEN top := cliptop END; W := right - X; H := top - Y; 		IF (W <= 0) OR (H <= 0) OR (X < 0) OR (Y < 0) THEN RETURN END; IF mode = invert THEN SYSTEM.PORTOUT(03CEH, SYSTEM.VAL(INTEGER, 1803H))	(* AL = Data/Rotate; AH = Modus; DX = Graphic-Controller *) ELSE	(* was replace only *) SYSTEM.PORTOUT(03CEH, SYSTEM.VAL(INTEGER, 03H)) (*ELSE (* mode = paint *) SYSTEM.PORTOUT(03CEH, SYSTEM.VAL(INTEGER, 1003H))*) END; SYSTEM.PORTOUT(03CEH, 205H);	(* AL = Gaphics mode; AH = Read-Mode = 0/Write-Mode = 2 (bits 0,1) *) SYSTEM.PORTOUT(03C4H, 0F02H);	(* AL = Plane select; AH = Bitplanemask; DX = Sequencer *) addr := ((Height - Y - 1) * width3) MOD 10000H; INC(addr, 0A0000H); start := addr + X DIV 8; end := addr + (X + W) DIV 8; lm := imask[X MOD 8]; rm := mask[(X + W) MOD 8]; IF start = end THEN ReplConst1(CHR(col), H, start, rm, lm) ELSE ReplConst2(CHR(col), H, start, end, rm, lm) END; END ReplConst; PROCEDURE FillPattern1(col: CHAR; pat: Pattern; pX, pY, X, Y, W, H, mode: LONGINT); VAR leftmask, rightmask, flag, color, help3: CHAR; topleft, help, help1, help2: LONGINT; CODE {SYSTEM.i386} MOV	EAX, mode[EBP]	; get mode and set local AH 		CMP	AX, 0 JNE	Inv4 MOV	AH, 0 JMP	setGC4 Inv4: CMP	AX, 2 JNE	Paint4 MOV	AH, 18H JMP	setGC4 Paint4: MOV	AH, 10H	; with wrong mode => ;		; automatically paint mode ; Set graphic-controller-registers setGC4: MOV	DX, 03CEH	; Graphic-Controller MOV	AL, 3	; AL = Data/Rotate / AH = Modus OUT	DX, AX 		MOV	AX, 0005H	; AL = Read-Mode = 0 ;		; Write-Mode = 0 (bits 0, 1) OUT	DX, AX	; Set ; Get params x, y getxy4: MOVSX EBX, height DEC EBX	; MOV	EBX, hgt[EBP] SUB	EBX, Y[EBP]	; (0, 0) in bottom left corner MOV	EAX, Y[EBP] MOV	Y[EBP], EBX	; y:= height -1 - y 		XOR	EDX, EDX SUB	EAX, pY[EBP] MOV	ECX, pat[EBP] MOVSX	ECX, BYTE 1[ECX] IDIV	EAX,ECX MOV	help2[EBP], EDX MOV	EBX, X[EBP]	; EBX := x 		MOV	ECX, EBX MOV	EDX, EBX MOV	ESI, EBX SHR	EBX, 3	; EBX := X DIV 8 ADD	EDX, W[EBP]	; EDX := x + w 		DEC	EDX SHR	EDX, 3	; EDX := (x + w-1) DIV 8 AND	ECX, 7	; ECX := x mod 8 ADD	ESI, W[EBP] DEC	ESI AND	ESI, 7	; ESI := (x+w-1) MOD 8 LEA EDI, imask	; MOV	EDI, imsk[EBP] MOV	AL, [EDI][ECX] ;		MOV	AL, imask[ECX] MOV	leftmask[EBP], AL 		INC	ESI	; *$* LEA EDI, mask	; MOV	EDI, msk[EBP] MOV	AL, [EDI][ESI] ;		MOV	AL, mask[ESI] MOV	rightmask[EBP], AL 		MOV	EDI, width3	; w3[EBP] IMUL	EDI, Y[EBP] AND EDI, 0FFFFH ADD	EDI,0A0000H ADD	EDI, EBX	; EDI := START-Adr SUB	EDX, EBX	; Diff in bytes MOV	help[EBP], EDX MOV	help1[EBP], EDI MOV	EBX, H[EBP] IMUL	EBX, width3	; w3[EBP] SUB	EDI, EBX MOV	topleft[EBP], EDI MOV	EDI, help1[EBP] MOV	ESI, pat[EBP]	; get addr of pat MOV	EAX, X[EBP]	; EAX := x 		XOR	EDX, EDX MOVSX	EBX, BYTE [ESI] IDIV	EAX,EBX MOV	help3[EBP], DL	;help3 := x MOD p.w 		MOV	DX, 03CEH MOV	AH, leftmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	DX, 03C4H MOV	AH, col[EBP] MOV	AL, 2 OUT	DX, AX 		MOV	EBX, help2[EBP] MOV	flag[EBP], 0 MOV	EDX, help[EBP] CMP	EDX, 0	; in one byte ? JE	onebyte CMP	BYTE [ESI], 16	; width = 16 ? JNE	RP32 RP16: CMP	mode[EBP], 0	; replacemode ? JE	R16 CMP	mode[EBP], 1	; paintmode ? JE	P16left IP16left: MOV	AX, 2[ESI][EBX*2]	; invert/paint p.w = 16 CMP	help3[EBP], 8 JGE	label ROR	AX, 8 label: MOV	CL, BYTE pX[EBP] ROL	AX, CL 		XOR	EDX, EDX PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	DL, AL 		MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] MOV	DL, AH 		MOV	AH, [EBX][EDX] ;		MOV	AH, rev[EDX] POP EBX MOV	CH, [EDI]	; latch MOV	[EDI], AH 		ROL	AX, 8 MOV	EDX, 1 CMP	EDX, help[EBP] JE	IP16right MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, 1 IP16mid: MOV	CH, [EDI][EDX]	; latch MOV	[EDI][EDX], AH 		ROL	AX, 8 INC	EDX CMP	EDX, help[EBP] JL	IP16mid IP16right: MOV	help1[EBP], EDX MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, help1[EBP] MOV	CH, [EDI][EDX] MOV	[EDI][EDX], AH 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; prepare rightmask again MOV	AL, 8 OUT	DX, AX 		XOR	EDX, EDX INC	EBX CMP	BL, 1[ESI]	; height of pattern reached? JNE	IP16left XOR	EBX, EBX	; yes, then reset counter JMP	IP16left P16left: MOV	AX, 2[ESI][EBX*2]	; invert/paint p.w = 16 CMP	help3[EBP], 8 JGE	plabel ROR	AX, 8 plabel: MOV	CL, BYTE pX[EBP] ROL	AX, CL 		XOR	EDX, EDX MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] MOV	DL, AH 		MOV	AH, [EBX][EDX] ;		MOV	AH, rev[EDX] POP EBX MOV	CH, [EDI]	; latch PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX NOT	AH	; negate AH 		MOV	[EDI], AH	; clear pattern NOT	AH	; negate AH 		PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI], AH 		ROL	AX, 8 MOV	EDX, 1 CMP	EDX, help[EBP] JE	P16right MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, 1 P16mid: MOV	CH, [EDI][EDX]	; latch PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX POP	EDX NOT	AH	; negate AH 		MOV	[EDI][EDX], AH	; clear pattern NOT	AH	; negate AH 		PUSH	EDX PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI][EDX], AH 		ROL	AX, 8 INC	EDX CMP	EDX, help[EBP] JL	P16mid P16right: MOV	help1[EBP], EDX MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, help1[EBP] MOV	CH, [EDI][EDX] PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX POP	EDX NOT	AH	; negate AH 		MOV	[EDI][EDX], AH	; clear pattern NOT	AH	; negate AH 		PUSH	EDX PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI][EDX], AH 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; prepare rightmask again MOV	AL, 8 OUT	DX, AX 		XOR	EDX, EDX INC	EBX CMP	BL, 1[ESI]	; height of pattern reached? JNE	P16left XOR	EBX, EBX	; yes, then reset counter JMP	P16left R16: MOV	AH, col[EBP] MOV	color[EBP], AH R16left: MOV	AX, 2[ESI][EBX*2]	; replace p.w = 16 CMP	help3[EBP], 8 JGE	label1 ROR	AX, 8 label1: MOV	CL, BYTE pX[EBP] ROL	AX, CL 		XOR	DX, DX 		MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] MOV	DL, AH ;		MOV	AH, rev[EDX] MOV	AH, [EBX][EDX] POP EBX MOV	help2[EBP], EAX MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		MOV	CH, [EDI]	; latch MOV	BYTE [EDI], 0 MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color MOV	EAX, help2[EBP] MOV	[EDI], AH 		ROL	AX, 8 MOV	EDX, 1 CMP	EDX, help[EBP] JE	R16right MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H OUT	DX, AX 		MOV	EDX, 1 MOV	EAX, help2[EBP] R16mid: MOV	help1[EBP], EDX MOV	help2[EBP], EAX MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		XCHG	help1[EBP], EDX MOV	BYTE [EDI][EDX], 0 XCHG	help1[EBP], EDX MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color XCHG	help1[EBP], EDX XCHG	help2[EBP], EAX MOV	[EDI][EDX], AH 		ROL	AX, 8 INC	EDX CMP	EDX, help[EBP] JL	R16mid R16right: MOV	help1[EBP], EDX MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		XCHG	help1[EBP], EDX MOV	CH, [EDI][EDX]	; latch MOV	BYTE [EDI][EDX], 0 XCHG	help1[EBP], EDX MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color MOV	EAX, help2[EBP] MOV	EDX, help1[EBP] MOV	[EDI][EDX], AH 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; prepare rightmask again MOV	AL, 8 OUT	DX, AX 		XOR	EDX, EDX INC	EBX CMP	BL, 1[ESI]	; height of pattern reached? JNE	R16left XOR	EBX, EBX	; yes, then reset counter JMP	R16left onebyte: CMP	BYTE [ESI], 16	; width = 16 ? SETE	flag[EBP]	; flag = 1 if p.w=16 CMP	mode[EBP], 0	; replace ? JE	onebyteR CMP	mode[EBP], 1	; paint ? JE	onebyteP IPonebyte: CMP	flag[EBP], 1 JNE	p32 MOV	AX, 2[ESI][EBX*2]	; p.w = 16 CMP	help3[EBP], 8 JGE	label2 ROR	AX, 8 label2: MOV	CL, BYTE pX[EBP] ROL	AX, CL 		JMP	down p32: MOV	EAX, 2[ESI][EBX*4]	; p.w = 32 CMP	help3[EBP], 24 JL	labela ROR	EAX, 24 JMP	labelc labela: CMP	help3[EBP], 16 JL	labelb ROR	EAX, 16 JMP	labelc labelb: CMP	help3[EBP], 8 JL	labelc ROR	EAX, 8 labelc: MOV	CL, BYTE pX[EBP] ROL	EAX, CL down: XOR	DX, DX 		MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	DL, [EBX][EDX] ;		MOV	DL, rev[EDX] POP EBX AND	AL, rightmask[EBP] MOV	CH, [EDI]	; latch MOV	[EDI], AL 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP INC	EBX CMP	BL, 1[ESI] JNE	IPonebyte XOR	EBX, EBX JMP	IPonebyte onebyteP: CMP	flag[EBP], 1 JNE	pp32 MOV	AX, 2[ESI][EBX*2]	; p.w = 16 CMP	help3[EBP], 8 JGE	plabel2 ROR	AX, 8 plabel2: MOV	CL, BYTE pX[EBP] ROL	AX, CL 		JMP	pdown pp32: MOV	EAX, 2[ESI][EBX*4]	; p.w = 32 CMP	help3[EBP], 24 JL	plabela ROR	EAX, 24 JMP	plabelc plabela: CMP	help3[EBP], 16 JL	plabelb ROR	EAX, 16 JMP	plabelc plabelb: CMP	help3[EBP], 8 JL	plabelc ROR	EAX, 8 plabelc: MOV	CL, BYTE pX[EBP] ROL	EAX, CL pdown: XOR	DX, DX 		MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	DL, [EBX][EDX] ;		MOV	DL, rev[EDX] POP EBX AND	AL, rightmask[EBP] MOV	CH, [EDI]	; latch PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX NOT	AL	; negate AL 		MOV	[EDI], AL	; clear pattern NOT	AL	; negate AL 		PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI], AL 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP INC	EBX CMP	BL, 1[ESI] JNE	onebyteP XOR	EBX, EBX JMP	onebyteP onebyteR: MOV	AH, col[EBP]	; replace in 1 byte MOV	color[EBP], AH Ronebyte: CMP	flag[EBP], 1 JNE	p32r MOV	AX, 2[ESI][EBX*2]	; p.w = 16 CMP	help3[EBP], 8 JGE	label3 ROR	AX, 8 label3: MOV	CL, BYTE pX[EBP] ROL	AX, CL 		JMP	downr p32r: MOV	EAX, 2[ESI][EBX*4]	; p.w = 32 CMP	help3[EBP], 24 JL	labelc1 ROR	EAX, 24 JMP	labelc1 labela1: CMP	help3[EBP], 16 JL	labelb1 ROR	EAX, 16 JMP	labelc1 labelb1: CMP	help3[EBP], 8 JL	labelc1 ROR	EAX, 8 labelc1: MOV	CL, BYTE pX[EBP] ROL	EAX, CL downr: XOR	EDX, EDX MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] POP EBX MOV	help1[EBP], EAX MOV	AH, leftmask[EBP] AND	AH, rightmask[EBP] MOV	DX, 03CEH MOV	AL, 8 OUT	DX, AX 		MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		MOV	CH, [EDI]	; latch MOV	BYTE [EDI], 0 MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color MOV	EAX, help1[EBP] MOV	[EDI], AL 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP INC	EBX CMP	BL, 1[ESI] JNE	Ronebyte XOR	EBX, EBX JMP	Ronebyte RP32: CMP	BYTE [ESI], 32	; p.w = 32 ? JNE	endRP	; only p.w = 16 OR 32 allowed CMP	mode[EBP], 0 JE	R32 CMP	mode[EBP], 1 JE	P32left IP32left: MOV	EAX, 2[ESI][EBX*4]	;invert/paint p.w = 32 CMP	help3[EBP], 24 JL	labela2 ROR	EAX, 24 JMP	labelc2 labela2: CMP	help3[EBP], 16 JL	labelb2 ROR	EAX, 16 JMP	labelc2 labelb2: CMP	help3[EBP], 8 JL	labelc2 ROR	EAX, 8 labelc2: MOV	CL, BYTE pX[EBP] ROL	EAX, CL 		XOR	EDX, EDX PUSH	ECX MOV	CX, 4 iloop: MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] POP EBX ROR	EAX, 8 LOOP	iloop POP	ECX MOV	CH, [EDI]	; latch MOV	[EDI], AL 		ROR	EAX, 8 MOV	EDX, 1 CMP	EDX, help[EBP] JE	IP32right MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, 1 IP32mid: MOV	CH, [EDI][EDX]	; latch MOV	[EDI][EDX], AL 		ROR	EAX, 8 INC	EDX CMP	EDX, help[EBP] JL	IP32mid IP32right: MOV	help2[EBP], EAX MOV	help1[EBP], EDX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, help1[EBP] MOV	CH, [EDI][EDX] MOV	[EDI][EDX], AL 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; prepare leftmask again MOV	AL, 8 OUT	DX, AX 		XOR	EDX, EDX INC	EBX CMP	BL, 1[ESI]	; height of pattern reached? JNE	IP32left XOR	EBX, EBX	; yes, then reset counter JMP	IP32left P32left: MOV	EAX, 2[ESI][EBX*4]	;invert/paint p.w = 32 CMP	help3[EBP], 24 JL	plabela2 ROR	EAX, 24 JMP	plabelc2 plabela2: CMP	help3[EBP], 16 JL	plabelb2 ROR	EAX, 16 JMP	plabelc2 plabelb2: CMP	help3[EBP], 8 JL	plabelc2 ROR	EAX, 8 plabelc2: MOV	CL, BYTE pX[EBP] ROL	EAX, CL 		XOR	EDX, EDX PUSH	ECX MOV	CX, 4 piloop: MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] POP EBX ROR	EAX, 8 LOOP	piloop POP	ECX MOV	CH, [EDI]	; latch PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX NOT	AL	; negate AL 		MOV	[EDI], AL	; clear pattern NOT	AL	; negate AL 		PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI], AL 		ROR	EAX, 8 MOV	EDX, 1 CMP	EDX, help[EBP] JE	P32right MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, 1 P32mid: MOV	CH, [EDI][EDX]	; latch PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX POP	EDX NOT	AL	; negate AL 		MOV	[EDI][EDX], AL	; clear pattern NOT	AL	; negate AL 		PUSH	EDX PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI][EDX], AL 		ROR	EAX, 8 INC	EDX CMP	EDX, help[EBP] JL	P32mid P32right: MOV	help2[EBP], EAX MOV	help1[EBP], EDX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	EAX, help2[EBP] MOV	EDX, help1[EBP] MOV	CH, [EDI][EDX] PUSH	EDX PUSH	EAX MOV	DX, 03C4H MOV	AX, 0F02H	; set all planes OUT	DX, AX	; set color/sequencer planemap MOV	AH, 8	; set mode to AND MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		POP	EAX POP	EDX NOT	AL	; negate AL 		MOV	[EDI][EDX], AL	; clear pattern NOT	AL	; negate AL 		PUSH	EDX PUSH	EAX MOV	AH, 10H	; set mode to OR 		MOV	AL, 3 MOV	DX, 03CEH OUT	DX, AX 		MOV	AH, col[EBP]	; get color and set bitplanes MOV	AL, 2 MOV	DX, 03C4H OUT	DX, AX 		POP	EAX POP	EDX MOV	[EDI][EDX], AL 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; prepare leftmask again MOV	AL, 8 OUT	DX, AX 		XOR	EDX, EDX INC	EBX CMP	BL, 1[ESI]	; height of pattern reached? JNE	IP32left XOR	EBX, EBX	; yes, then reset counter JMP	P32left R32: MOV	AH, col[EBP] MOV	color[EBP], AH R32left: MOV	EAX, 2[ESI][EBX*4]	; replace p.w = 32 CMP	help3[EBP], 24 JL	labela3 ROR	EAX, 24 JMP	labelc3 labela3: CMP	help3[EBP], 16 JL	labelb3 ROR	EAX, 16 JMP	labelc3 labelb3: CMP	help3[EBP], 8 JL	labelc3 ROR	EAX, 8 labelc3: MOV	CL, BYTE pX[EBP] ROL	EAX, CL 		XOR	EDX, EDX PUSH	ECX MOV	CX, 4 i2loop: MOV	DL, AL 		PUSH EBX LEA EBX, rev	; MOV EBX, reverse[EBP] MOV	AL, [EBX][EDX] ;		MOV	AL, rev[EDX] POP EBX ROR	EAX, 8 LOOP	i2loop POP	ECX MOV	help2[EBP], EAX MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		MOV	CH, [EDI]	; latch MOV	BYTE [EDI], 0 MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color MOV	EAX, help2[EBP] MOV	[EDI], AL 		ROR	EAX, 8 MOV	EDX, 1 CMP	EDX, help[EBP] JE	R32right MOV	help2[EBP], EAX MOV	DX, 03CEH MOV	AX, 0FF08H OUT	DX, AX 		MOV	EDX, 1 MOV	EAX, help2[EBP] R32mid: MOV	help1[EBP], EDX MOV	help2[EBP], EAX MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		XCHG	help1[EBP], EDX MOV	BYTE [EDI][EDX], 0 XCHG	help1[EBP], EDX MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color XCHG	help1[EBP], EDX XCHG	help2[EBP], EAX MOV	[EDI][EDX], AL 		ROR	EAX, 8 INC	EDX CMP	EDX, help[EBP] JL	R32mid R32right: MOV	help2[EBP], EAX MOV	help1[EBP], EDX MOV	DX, 03CEH MOV	AH, rightmask[EBP] MOV	AL, 8 OUT	DX, AX 		MOV	DX, 03C4H MOV	AX, 0F02H OUT	DX, AX 		XCHG	help1[EBP], EDX MOV	CH, [EDI][EDX]	; latch MOV	BYTE [EDI][EDX], 0 XCHG	help1[EBP], EDX MOV	AH, color[EBP] MOV	AL, 2 OUT	DX, AX	; set color MOV	EAX, help2[EBP] MOV	EDX, help1[EBP] MOV	[EDI][EDX], AL 		SUB	EDI, width3	; w3[EBP] CMP	EDI, topleft[EBP] JLE	resetgrafRP MOV	DX, 03CEH MOV	AH, leftmask[EBP]	; prepare leftmask again MOV	AL, 8 OUT	DX, AX 		XOR	EDX, EDX INC	EBX CMP	BL, 1[ESI]	; height of pattern reached? JNE	R32left XOR	EBX, EBX	; yes, then reset counter JMP	R32left JMP	endRP resetgrafRP: MOV	DX, 03CEH MOV	AX, 0FF08H	; default bit mask OUT	DX, AX 		MOV	AX, 0005	; default mode-reg OUT	DX, AX 		MOV	AX, 0003	; default function OUT	DX, AX 		MOV	DX, 03C4H MOV	AX, 0F02H	; default map mask OUT	DX, AX endRP: END FillPattern1; PROCEDURE FillPattern*(col: Color; pat: Pattern; px, py, x, y, w, h, mode: LONGINT); VAR pw: SHORTINT; right, top: INTEGER; BEGIN SYSTEM.GET(pat, pw); IF (pw # 16) & (pw # 32) THEN RETURN END; top := SHORT(y + h); right := SHORT(x + w); IF x < clipx THEN x := clipx END; IF y < clipy THEN y := clipy END; IF clipright < right THEN right :=  clipright END; IF cliptop < top THEN top := cliptop END; IF (w <= 0) OR (h <= 0) OR (x < 0) OR (y < 0) THEN RETURN END; FillPattern1(CHR(col), pat, px, py, x, y, w, h, mode) END FillPattern; PROCEDURE ReplPattern*(col: Color; pat: Pattern; x, y, w, h, mode: LONGINT); BEGIN FillPattern(col, pat, 0, 0, x, y, w, h, mode) END ReplPattern; PROCEDURE NewPattern*(w, h: LONGINT; VAR image: ARRAY OF SET): Pattern; VAR len, src, dest, i: LONGINT; p: PatternPtr;  pl: List; BEGIN len := (w+7) DIV 8; SYSTEM.NEW(p, 4+len*h); p.w := CHR(w);  p.h := CHR(h); src := SYSTEM.ADR(image[0]); dest := SYSTEM.ADR(p.pixmap[0]); i := 0; WHILE i < h DO SYSTEM.MOVE(src, dest, len); INC(src, 4);  INC(dest, len);  INC(i) END; NEW(pl); pl.pat := p;  pl.next := pattern;  pattern := pl;	(* put in list to avoid GC *) RETURN SYSTEM.ADR(p.w) 	END NewPattern; PROCEDURE CreatePatterns; VAR image: ARRAY 16 OF SET; BEGIN image[0] := {13}; image[1] := {12..14}; image[2] := {11..13}; image[3] := {10..12}; image[4] := {9..11}; image[5] := {8..10}; image[6] := {7..9}; image[7] := {0, 6..8}; image[8] := {0, 1, 5..7}; image[9] := {0..2, 4..6}; image[10] := {0..5}; image[11] := {0..4}; image[12] := {0..5}; image[13] := {0..6}; image[14] := {0..7}; arrow := NewPattern(15, 15, image); image[0] := {0, 10}; image[1] := {1, 9}; image[2] := {2, 8}; image[3] := {3, 7}; image[4] := {4, 6}; image[5] := {}; image[6] := {4, 6}; image[7] := {3, 7}; image[8] := {2, 8}; image[9] := {1, 9}; image[10] := {0, 10}; cross := NewPattern(11, 11, image); image[0] := {6}; image[1] := {5..7}; image[2] := {4..8}; image[3] := {3..9}; image[4] := {2..10}; image[5] := {5..7}; image[6] := {5..7}; image[7] := {5..7}; image[8] := {5..7}; image[9] := {5..7}; image[10] := {5..7}; image[11] := {5..7}; image[12] := {5..7}; image[13] := {5..7}; image[14] := {}; downArrow := NewPattern(15, 15, image); image[0] := {0, 4, 8, 12}; image[1] := {}; image[2] := {2, 6, 10, 14}; image[3] := {}; image[4] := {0, 4, 8, 12}; image[5] := {}; image[6] := {2, 6, 10, 14}; image[7] := {}; image[8] := {0, 4, 8, 12}; image[9] := {}; image[10] := {2, 6, 10, 14}; image[11] := {}; image[12] := {0, 4, 8, 12}; image[13] := {}; image[14] := {2, 6, 10, 14}; image[15] := {}; grey0 := NewPattern(16, 16, image); image[0] := {0, 2, 4, 6, 8, 10, 12, 14}; image[1] := {1, 3, 5, 7, 9, 11, 13, 15}; image[2] := {0, 2, 4, 6, 8, 10, 12, 14}; image[3] := {1, 3, 5, 7, 9, 11, 13, 15}; image[4] := {0, 2, 4, 6, 8, 10, 12, 14}; image[5] := {1, 3, 5, 7, 9, 11, 13, 15}; image[6] := {0, 2, 4, 6, 8, 10, 12, 14}; image[7] := {1, 3, 5, 7, 9, 11, 13, 15}; image[8] := {0, 2, 4, 6, 8, 10, 12, 14}; image[9] := {1, 3, 5, 7, 9, 11, 13, 15}; image[10] := {0, 2, 4, 6, 8, 10, 12, 14}; image[11] := {1, 3, 5, 7, 9, 11, 13, 15}; image[12] := {0, 2, 4, 6, 8, 10, 12, 14}; image[13] := {1, 3, 5, 7, 9, 11, 13, 15}; image[14] := {0, 2, 4, 6, 8, 10, 12, 14}; image[15] := {1, 3, 5, 7, 9, 11, 13, 15}; grey1 := NewPattern(16, 16, image); image[0] := {0, 1, 4, 5, 8, 9, 12, 13}; image[1] := {0, 1, 4, 5, 8, 9, 12, 13}; image[2] := {2, 3, 6, 7, 10, 11, 14, 15}; image[3] := {2, 3, 6, 7, 10, 11, 14, 15}; image[4] := {0, 1, 4, 5, 8, 9, 12, 13}; image[5] := {0, 1, 4, 5, 8, 9, 12, 13}; image[6] := {2, 3, 6, 7, 10, 11, 14, 15}; image[7] := {2, 3, 6, 7, 10, 11, 14, 15}; image[8] := {0, 1, 4, 5, 8, 9, 12, 13}; image[9] := {0, 1, 4, 5, 8, 9, 12, 13}; image[10] := {2, 3, 6, 7, 10, 11, 14, 15}; image[11] := {2, 3, 6, 7, 10, 11, 14, 15}; image[12] := {0, 1, 4, 5, 8, 9, 12, 13}; image[13] := {0, 1, 4, 5, 8, 9, 12, 13}; image[14] := {2, 3, 6, 7, 10, 11, 14, 15}; image[15] := {2, 3, 6, 7, 10, 11, 14, 15}; grey2 := NewPattern(16, 16, image); image[0] := {0..2, 8..11}; image[1] := {0..2, 7..10}; image[2] := {0..2, 6..9}; image[3] := {0..2, 5..8}; image[4] := {0..2, 4..7}; image[5] := {0..6}; image[6] := {0..5}; image[7] := {0..4}; image[8] := {0..3}; image[9] := {0..2}; image[10] := {0, 1}; image[11] := {0}; hook := NewPattern(12, 12, image); image[0] := {7}; image[1] := {7}; image[2] := {2, 7, 12}; image[3] := {3, 7, 11}; image[4] := {4, 7, 10}; image[5] := {5, 7, 9}; image[6] := {6..8}; image[7] := {0..6, 8..14}; image[8] := {6..8}; image[9] := {5, 7, 9}; image[10] := {4, 7, 10}; image[11] := {3, 7, 11}; image[12] := {2, 7, 12}; image[13] := {7}; image[14] := {7}; star := NewPattern(15, 15, image); image[0] := {}; image[1] := {}; image[2] := {0}; image[3] := {}; image[4] := {}; image[5] := {}; image[6] := {}; image[7] := {}; image[8] := {}; image[9] := {}; image[10] := {}; image[11] := {}; image[12] := {}; image[13] := {}; image[14] := {}; image[15] := {}; ticks := NewPattern(16, 16, image); image[0] := -{}; image[1] := -{}; image[2] := -{}; image[3] := -{}; image[4] := -{}; image[5] := -{}; image[6] := -{}; image[7] := -{}; solid := NewPattern(16, 8, image) END CreatePatterns; PROCEDURE Depth*(x: LONGINT): INTEGER; BEGIN RETURN depth END Depth; PROCEDURE TrueColor*(x: LONGINT): BOOLEAN; BEGIN RETURN FALSE END TrueColor; PROCEDURE DisplayBlock*(adr, dx, dy, w, h, sx, sy, mode: LONGINT); VAR BitmapWth, locW, locH, SourceAdr, DestAdr, AreaHeight: LONGINT; CODE {SYSTEM.i386} MOVSX EAX, Width SHR EAX,3 MOV locW[EBP], EAX	; locW := Width DIV 8 MOVSX EAX, Height DEC EAX MOV locH[EBP], EAX	; locH := Height-1 CLI MOV ESI, adr[EBP]		; address of bitmap descriptor MOV EDI, 12[ESI] MOV EAX, 8[ESI] MOV BitmapWth[EBP], EAX MOV ECX, dy[EBP] IMUL EAX,ECX MOV EBX, dx[EBP] ADD EAX, EBX ADD EAX, EDI		; source address MOV SourceAdr[EBP], EAX MOV ESI, EAX		; esi = source index register MOV EAX, locW[EBP] MOV EBX, locH[EBP] SUB EBX, sy[EBP] IMUL EAX,EBX MOV EBX, sx[EBP] SHR EBX,3 ADD EAX, EBX AND EAX, 0FFFFH ADD EAX, 0A0000H		; destination address MOV DestAdr[EBP], EAX MOV EDI, EAX		; edi = destination index register MOV DX, 03C4H	; AX = Default map mask; DX = Sequencer MOV AX, 0F02H OUT DX, AX 		MOV DX, 03CEH MOV AL, 3 MOV BX, WORD mode[EBP] CMP BX, 1 JE DispPMode JG DispIMode DispRMode: MOV AH,00 JMP DispSetMode DispPMode: MOV AH, 10H JMP DispSetMode DispIMode: MOV AH, 18H DispSetMode: OUT DX, AX	; set rotate and function select MOV AX, 0205H OUT DX, AX		 ; set writemode 2, readmode 0 XOR AX, AX 		OUT DX, AX	; disable set/reset MOV CL, BYTE sx[EBP] AND CL, 7		; ?DX MOD 8 MOV AX, 8008H SHR AH,CL		 ; prepare bitmask MOV DestAdr[EBP], EDI MOV ECX, h[EBP] IMUL ECX, BitmapWth[EBP] ADD ECX, ESI MOV EBX, w[EBP] MOV AreaHeight[EBP], EBX DispRowLoop: JE DispEnd OUT DX, AX		; set bitmask register MOV SourceAdr[EBP], ESI DispColLoop: CMP ESI, ECX JGE DispColEnd MOV BL, [EDI] MOV BL, [ESI]		; get PEL from bitmap MOV [EDI], BL		; write PEL to VGA ADD ESI, BitmapWth[EBP] SUB EDI, locW[EBP] JMP DispColLoop DispColEnd: MOV ESI, SourceAdr[EBP] INC ESI INC ECX MOV EDI, DestAdr[EBP] ROR AH,1 JNB NextCol INC EDI MOV DestAdr[EBP], EDI NextCol: DEC AreaHeight[EBP]		 	; next row JMP DispRowLoop DispEnd: MOV AL, 3		; restore invert mode MOV AH, 18H OUT DX, AX 		MOV AX, 0FF08H		; enable all latches OUT DX, AX 		MOV AX, 05H		; restore read/write mode 0 OUT DX, AX 		STI END DisplayBlock; PROCEDURE TransferFormat*(x: LONGINT): LONGINT;	(** non-portable *) BEGIN RETURN unknown END TransferFormat; PROCEDURE TransferBlock*(VAR buf: ARRAY OF CHAR; ofs, stride, x, y, w, h, mode: LONGINT);	(** non-portable *) BEGIN HALT(99) END TransferBlock; PROCEDURE SetBorder; VAR ch: CHAR; BEGIN SYSTEM.PORTIN(3DAH, ch); SYSTEM.PORTOUT(3C0H, 11X); SYSTEM.PORTOUT(3C0H, 0FFX); SYSTEM.PORTOUT(3C0H, 020X) END SetBorder; PROCEDURE Init; VAR s: ARRAY 10 OF CHAR; BEGIN Kernel.GetConfig("Color", s); IF s = "0" THEN depth := 1 ELSE depth := 4 END END Init; PROCEDURE InitRev; VAR i, j, x: LONGINT; BEGIN FOR i := 0 TO 255 DO 			x := 0; FOR j := 0 TO 7 DO 				x := ASH(x, 1); IF ODD(ASH(i, -j)) THEN INC(x) END END; rev[i] := CHR(x) END END InitRev; BEGIN Init; Width := 640; Height := 480; Left:= 0; ColLeft:= 0; Bottom:= 0; UBottom:= -330; pattern := NIL; width := Width; height := Height; clipx := 0; clipy := UBottom; clipright := width; cliptop := height; width3 := width DIV 8; mask[0] := 0X; mask[1] := 80X; mask[2] := 0C0X; mask[3] := 0E0X; mask[4] := 0F0X; mask[5] := 0F8X; mask[6] := 0FCX; mask[7] := 0FEX; mask[8] := 0FFX; imask[0] := 0FFX; imask[1] := 7FX; imask[2] := 3FX; imask[3] := 1FX; imask[4] := 0FX; imask[5] := 7X; imask[6] := 3X; imask[7] := 1X; imask[8] := 0X; InitRev; CreatePatterns; SetBorder; Unit := 10000 END Display. Compiler.Compile VGA.Display.Mod\X ~