Skip to main content

  | मौसम…

411 समाचार
Public archive edition · Attributed source reporting with original dates · AI drafts are excluded

411 REFERENCE · Wikibooks

Oberon/ETH Oberon/2.3.7/DisplayVGA4.Mod

Reference material by Wikibooks contributors. This retains its source identity and is not 411 news reporting.

(* ETH Oberon, Copyright 1990-2003 Computer Systems Institute, ETH Zurich, CH-8092 Zurich. Refer to the license.txt file provided with this distribution. *) MODULE DisplayVGA4; (* pjm *) (* 16-color VGA display driver for Native Oberon with virtual truecolor. Config strings: Display="Displays." DDriver="DisplayVGA4" Init="b81200cd10" *) IMPORT SYSTEM, Kernel, CLUTs, Displays; CONST Width = 640; Height = 480; VAR d: Display; base: LONGINT; clut: POINTER TO CLUTs.CLUT; pal: ARRAY 16 OF LONGINT; shadow: POINTER TO ARRAY OF CHAR; pelmask: LONGINT; (* trace *) TYPE Display* = OBJECT (Displays.Display) PROCEDURE Transfer*(VAR buf: ARRAY OF CHAR; ofs, stride, x, y, w, h, op: LONGINT); VAR bufadr, buflow, bufhigh, dispadr, scradr: LONGINT; BEGIN IF w > 0 THEN bufadr := SYSTEM.ADR(buf[ofs]); IF op = Displays.set THEN buflow := SYSTEM.ADR(shadow[0]); bufhigh := buflow + LEN(shadow^); dispadr := SYSTEM.ADR(shadow[0]) + ((y*Width)+x); scradr := base + (x DIV 8 + y*(Width DIV 8)) MOD 10000H; WHILE h > 0 DO ASSERT((dispadr >= buflow) & (dispadr+w <= bufhigh)); (* index check *) SYSTEM.MOVE(bufadr, dispadr, w); CopyLineTo(bufadr, scradr, x, w); INC(bufadr, stride); INC(dispadr, Width); INC(scradr, Width DIV 8); DEC(h) END ELSIF op = Displays.get THEN buflow := SYSTEM.ADR(buf[0]); bufhigh := buflow + LEN(buf); dispadr := SYSTEM.ADR(shadow[0]) + ((y*Width)+x); WHILE h > 0 DO ASSERT((bufadr >= buflow) & (bufadr+w <= bufhigh)); (* index check *) SYSTEM.MOVE(dispadr, bufadr, w); INC(bufadr, stride); INC(dispadr, Width); DEC(h) END ELSE (* skip *) END END END Transfer; (* PROCEDURE Dot*(col, x, y: LONGINT); VAR ch: CHAR; BEGIN y := base + (x + y*Width) DIV 8 MOD 10000H; SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 8 + ASH(100H, 7-x MOD 8))); IF ASH(col, 1) >= 0 THEN (* replace *) SYSTEM.GET(y, ch); SYSTEM.PUT(y, CHR(CLUTs.Match(clut^, col))) ELSE (* invert *) SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 1803H)); SYSTEM.GET(y, ch); SYSTEM.PUT(y, CHR(CLUTs.Match(clut^, col))); SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 0003H)) END END Dot; *) PROCEDURE ColorToIndex*(col: LONGINT): LONGINT; BEGIN RETURN CLUTs.Match(clut^, col) END ColorToIndex; PROCEDURE IndexToColor*(index: LONGINT): LONGINT; BEGIN RETURN pal[index MOD 16] END IndexToColor; END Display; (* Copy a line of pixels to the display. *) PROCEDURE CopyLineTo(src, dst, x, w: LONGINT); CODE {SYSTEM.i386} MOV ESI, src[EBP] MOV EDI, dst[EBP] MOV EBX, x[EBP] MOV EDX, 3CEH MOV AL, 8 new: MOV CH, [ESI] ; CH = current pixel color MOV AH, 80H ; AH = mask for current pixels (at left of byte) MOV CL, BL AND CL, 7 ; CL = offset to shift mask right JMP loop same: SAR AH, 1 loop: DEC w[EBP] JZ done INC EBX INC ESI TEST BL, 7 JZ edge CMP CH, [ESI] JE same diff: SHR AH, CL OUT DX, AX MOV CL, [EDI] MOV [EDI], CH JMP new edge: SHR AH, CL ; adjust mask OUT DX, AX ; set mask MOV CL, [EDI] ; latch MOV [EDI], CH ; output color INC EDI JMP new done: SHR AH, CL OUT DX, AX MOV CL, [EDI] MOV [EDI], CH end: END CopyLineTo; PROCEDURE Install*; BEGIN IF d # NIL THEN Displays.main := d END END Install; PROCEDURE InitPalette; VAR i, col: LONGINT; ch: CHAR; BEGIN (* standard Oberon colours *) pal[0] := 0; pal[1] := 0FF0000H; pal[2] := 000FF00H; pal[3] := 00000FFH; pal[4] := 0FF00FFH; pal[5] := 0FFFF00H; pal[6] := 000FFFFH; pal[7] := 0AA0000H; pal[9] := 000009AH; pal[10] := 0A6CBF3H; pal[11] := 0008282H; pal[12] := 08A8A8AH; pal[13] := 0BEBEBEH; pal[14] := 0DFDFDFH; pal[15] := 0FFFFFFH; (* set attribute controller registers *) SYSTEM.PORTIN(3DAH, ch); (* clear flip/flop *) FOR i := 0 TO 0FH DO SYSTEM.PORTOUT(3C0H, CHR(i)); (* EGA palette register i *) SYSTEM.PORTOUT(3C0H, CHR(i)) (* maps to VGA palette i *) END; SYSTEM.PORTOUT(3C0H, 11X); (* overscan color *) SYSTEM.PORTOUT(3C0H, 0X); (* black/EGA palette 0/VGA palette 0 *) SYSTEM.PORTOUT(3C0H, 12X); (* color plane enable *) SYSTEM.PORTOUT(3C0H, 0FX); (* enable all planes *) SYSTEM.PORTOUT(3C0H, 14X); (* color select *) SYSTEM.PORTOUT(3C0H, 0X); (* use first 16 colors in VGA palette *) SYSTEM.PORTOUT(3C0H, 20X); (* enable display to use palette again *) (* set up VGA palette and reverse lookup table *) NEW(clut); SYSTEM.PORTOUT(3C8H, 0X); (* select index 0 *) FOR i := 0 TO 15 DO col := pal[i]; CLUTs.Set(clut^, i, col); SYSTEM.PORTOUT(3C9H, CHR(col DIV 10000H MOD 100H DIV 4)); SYSTEM.PORTOUT(3C9H, CHR(col DIV 100H MOD 100H DIV 4)); SYSTEM.PORTOUT(3C9H, CHR(col MOD 100H DIV 4)) END; FOR i := 16 TO 255 DO SYSTEM.PORTOUT(3C9H, 0X); SYSTEM.PORTOUT(3C9H, 0X); SYSTEM.PORTOUT(3C9H, 0X) END; CLUTs.Init(clut^, 16, 3); SYSTEM.PORTIN(3C6H, ch); pelmask := ORD(ch) END InitPalette; (* IF i = 6 THEN j := 14H ELSIF i > 7 THEN j := i+30H ELSE j := i END; *) PROCEDURE Init; BEGIN NEW(d); d.width := Width; d.height := Height; d.offscreen := 0; d.format := Displays.index8; d.unit := 10000; Kernel.MapPhysical(0A0000H, 10000H, base); NEW(shadow, Width*Height); (* data rotate 0 *) SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 0003H)); (* write mode 2 *) SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 0205H)); (* set/reset disabled *) SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 0001H)); (* no set/reset *) SYSTEM.PORTOUT(3CEH, SYSTEM.VAL(INTEGER, 0000H)); (* map mask enable all planes *) SYSTEM.PORTOUT(3C4H, SYSTEM.VAL(INTEGER, 0F02H)); InitPalette END Init; BEGIN Init; Install END DisplayVGA4. (* to do: 1 fix for Mach64 1 remove shadow (read from real display) 1 offscreen *)