123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- (* Aos, Copyright 2001, Pieter Muller, ETH Zurich *)
- MODULE DisplayLinear; (** AUTHOR "pjm"; PURPOSE "Linear framebuffer display driver"; *)
- (*
- Config strings:
- DWidth=1024 Display width
- DHeight=768 Display height
- DDepth=16 Display depth
- DMem=? Display memory size in bytes
- Init=? Init program.
- The Init program is a 8086 machine code program in hexadecimal. It has to initialize the specified display mode, possibly by making display BIOS calls, and leave the 32-bit physical address of the frame buffer in DX:CX.
- *)
- IMPORT SYSTEM, Machine, KernelLog, MemCache, Displays, Strings, Commands, Options, Modules;
- VAR
- d: Displays.Display;
- PROCEDURE GetVal(name: ARRAY OF CHAR; default: LONGINT): LONGINT;
- VAR v: LONGINT; s: ARRAY 10 OF CHAR; p: LONGINT;
- BEGIN
- Machine.GetConfig(name, s);
- IF s[0] = 0X THEN
- v := default
- ELSE
- p := 0; v := Machine.StrToInt(p, s)
- END;
- RETURN v
- END GetVal;
- PROCEDURE Install*(context: Commands.Context);
- VAR options: Options.Options;
- BEGIN
- NEW(options);
- options.Add("r", "reverse", Options.Flag);
- IF options.Parse(context.arg, context.error) THEN
- IF options.GetFlag("r") THEN Displays.Reverse() END;
- END;
- END Install;
- PROCEDURE InitPalette;
- VAR col: LONGINT; ch: CHAR;
- BEGIN
- Machine.Portin8(3DAH, ch);
- Machine.Portout8(3C0H, 11X);
- Machine.Portout8(3C0H, 0X); (* palette entry 0 is black *)
- Machine.Portout8(3C0H, 20X);
- FOR col := 0 TO 255 DO
- Machine.Portout8(3C8H, CHR(col));
- Machine.Portout8(3C9H, CHR(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, col) * {5..7}) DIV 4));
- Machine.Portout8(3C9H, CHR(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ASH(col, 7-4)) * {5..7}) DIV 4));
- Machine.Portout8(3C9H, CHR(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ASH(col, 7-1)) * {6..7}) DIV 4))
- END
- END InitPalette;
- PROCEDURE Init;
- VAR w, h, f, mem, res: LONGINT; ts : ARRAY 16 OF CHAR; padr, vadr: ADDRESS;
- BEGIN
- w := GetVal("DWidth", 1024); h := GetVal("DHeight", 768);
- CASE GetVal("DDepth", 16) DIV 8 OF
- 1: f := Displays.index8; InitPalette
- |2: f := Displays.color565
- |3: f := Displays.color888
- |4: f := Displays.color8888
- END;
- mem := GetVal("DMem", 0)*1024;
- IF mem = 0 THEN (* compute default *)
- mem := 512*1024;
- WHILE w*h*f >= mem DO mem := mem*2 END
- END;
- Machine.GetInit(1, SYSTEM.VAL(LONGINT,padr)); (* DX:CX from Init code *)
- ASSERT((padr # 0) & (padr MOD 4096 = 0));
- IF GetVal("DCache", 1) = 1 THEN
- MemCache.GlobalSetCacheProperties(padr, mem, MemCache.WC, res);
- IF res # 0 THEN
- KernelLog.Enter; KernelLog.String("DisplayLinear: GlobalSetCacheProperties = ");
- KernelLog.Int(res, 1); KernelLog.Exit
- END
- END;
- (* KernelLog.ScreenOff; *)
- Machine.MapPhysical(padr, mem, vadr);
- Machine.Fill32(vadr, mem, 0); (* clear video memory *)
- NEW(d);
- d.width := w; d.height := h; d.offscreen := mem DIV (w*f) - h;
- d.format := f; d.unit := 10000;
- d.InitFrameBuffer(vadr, mem, w * f);
- d.desc := "Generic linear framebuffer driver (";
- Strings.IntToStr(d.width, ts); Strings.Append(d.desc, ts);
- Strings.Append(d.desc, "x");
- Strings.IntToStr(d.height, ts); Strings.Append(d.desc, ts);
- Strings.Append(d.desc, "x");
- Strings.IntToStr(d.format, ts); Strings.Append(d.desc, ts);
- Strings.Append(d.desc, ")");
- Displays.registry.Add(d, res);
- ASSERT(res = 0)
- END Init;
- PROCEDURE CleanUp;
- BEGIN
- ASSERT (d # NIL);
- Machine.Fill32(d.fbadr, d.fbsize, 0); (* clear video memory *)
- END CleanUp;
- BEGIN
- Init;
- Modules.InstallTermHandler(CleanUp);
- END DisplayLinear.
|