anchor.diff:  (defconstant +dspcntr-180-rotation+ (byte 1 15))
   (defconstant +dspcntr-tiled+ (byte 1 10))
   
  -(defstruct mode-parameters
  -  width
  -  height
  -  format
  -  ;; PLL parameters
  -  n
  -  m1
  -  m2
  -  p1
  -  p2
  -  ;; Display timings
  -  htotal-active
  -  htotal-total
  -  hblank-start
  -  hblank-end
  -  hsync-start
  -  hsync-end
  -  vtotal-active
  -  vtotal-total
  -  vblank-start
  -  vblank-end
  -  vsync-start
  -  vsync-end)
  -
  -(eval-when (:compile-toplevel :load-toplevel :execute)
  -  (defmethod make-load-form ((object mode-parameters) &optional environment)
  -    (make-load-form-saving-slots object :environment environment)))
  -
  -(defparameter *modes*
  -  '(#S(mode-parameters
  -       :width 1600 :height 1200 :format :x8r8g8b8
  -       :n 4 :m1 16 :m2 9 :p1 1 :p2 0
  -       :htotal-active 1599 :htotal-total 2159
  -       :hblank-start 1599 :hblank-end 2159
  -       :hsync-start 1663 :hsync-end 1855
  -       :vtotal-active 1199 :vtotal-total 1249
  -       :vblank-start 1199 :vblank-end 1249
  -       :vsync-start 1200 :vsync-end 1203)
  -    #S(mode-parameters
  -       :width 1280 :height 1024 :format :x8r8g8b8
  -       :n 2 :m1 14 :m2 8 :p1 2 :p2 0
  -       :htotal-active 1279 :htotal-total 1687
  -       :hblank-start 1279 :hblank-end 1687
  -       :hsync-start 1327 :hsync-end 1439
  -       :vtotal-active 1023 :vtotal-total 1065
  -       :vblank-start 1023 :vblank-end 1065
  -       :vsync-start 1024 :vsync-end 1027)))
  +(defstruct timing
  +  pixel-clock
  +  horz-left-border
  +  horz-active ; width
  +  horz-right-border
  +  horz-front-porch
  +  horz-sync
  +  horz-back-porch
  +  horz-image-size
  +  vert-top-border
  +  vert-active ; height
  +  vert-bottom-border
  +  vert-front-porch
  +  vert-sync
  +  vert-back-porch
  +  vert-image-size
  +  interlaced
  +  stereo
  +  ;; FIXME: Figure this out.
  +  sync-config)
  +
  +(defun timing-refresh-rate (timing)
  +  (round (timing-pixel-clock timing)
  +         (* (+ (timing-horz-sync timing)
  +               (timing-horz-back-porch timing)
  +               (timing-horz-front-porch timing))
  +            (+ (timing-vert-sync timing)
  +               (timing-vert-back-porch timing)
  +               (timing-vert-front-porch timing)))))
   
   (defmacro with-i945-access ((device) &body body)
     `(sup:with-device-access ((pci:pci-device-boot-id (i945-device ,device))
                               (error "~S is stale" ,device))
        (sup:with-mutex ((i945-lock ,device))
          ,@body)))
  +
  +(defun framebuffer-address (device)
  +  (logand (pci:pci-io-region (i945-device device) 2) (lognot #xF)))
  +
  +(defconstant +reference-frequency+ 96000000)
  +
  +(defun pll-parameters-to-dot-clock (n m1 m2 p1 p2 &key (refclk +reference-frequency+))
  +  (let* ((p1 (ecase p1
  +               (#b00000001 1)
  +               (#b00000010 2)
  +               (#b00000100 3)
  +               (#b00001000 4)
  +               (#b00010000 5)
  +               (#b00100000 6)
  +               (#b01000000 7)
  +               (#b10000000 8)))
  +         (p2 (ecase p2
  +               (#b00 10)
  +               (#b01 5)))
  +         (m (+ (* 5 (+ m1 2)) (+ m2 2)))
  +         (p-div (* p1 p2)))
  +    (truncate (/ (* refclk m) (+ n 2) p-div))))
  +
  +(defun compute-pll-parameters (target-clock)
  +  "Calculate the best PLL paramters for TARGET-CLOCK.
  +Returns the N, M1, M2, P1, P2, and the actual dot clock frequency."
  +  (let ((best-clock 0)
  +        (best-n 0) (best-m1 0) (best-m2 0)
  +        ;; p1 raw value, not register value
  +        (best-p1 0)
  +        ;; p2 raw value, not register value.
  +        (p2 10))
  +    ;; Cycle through all PLL values looking for the closest frequency.
  +    (loop
  +       for n from 3 to 8
  +       do (loop
  +             for m1 from 10 to 20
  +             do (loop
  +                   for m2 from 5 to 9
  +                   for m = (+ (* 5 (+ m1 2)) (+ m2 2))
  +                   when (<= 70 m 120)
  +                   do
  +                     (loop
  +                        for p1 from 1 to 8
  +                        for p-div = (* p1 p2)
  +                        when (<= 5 p-div 80)
  +                        do
  +                          (let* ((vco (/ (* +reference-frequency+ m) (+ n 2)))
  +                                 (clock (/ vco p-div)))
  +                            (when (and
  +                                   ;; Must be in range.
  +                                   (<= 1400000000 vco 2800000000)
  +                                   ;; Must be better.
  +                                   (< (abs (- target-clock clock))
  +                                      (abs (- target-clock best-clock))))
  +                              (setf best-clock clock
  +                                    best-n n
  +                                    best-m1 m1
  +                                    best-m2 m2
  +                                    best-p1 p1)))))))
  +    (let ((error (float (abs (- 1 (/ target-clock best-clock))))))
  +      ;; TODO: This should bail if the error is too great. It's not clear
  +      ;; what "too great" is though.
  +      (values best-n best-m1 best-m2
  +              (ash 1 (1- best-p1)) ; Convert to register value.
  +              #b00 ; p2 register value
  +              (truncate best-clock)
  +              error))))
   
   (defun save-current-mode-parameters (device)
     "Return a MODE-PARAMETERS object for the device's currently configured mode."
  
positive.code:   chromacticity
    timing-modes)
  
  (defstruct timing
    width
    height
    refresh-rate
    pixel-clock
    horz-left-border
    horz-active
    horz-right-border
    horz-back-porch
    horz-sync
    horz-front-porch
    horz-image-size
    vert-top-border
    vert-active
    vert-bottom-border
    vert-back-porch
    vert-sync
    vert-front-porch
    vert-image-size
    stereo
    ;; FIXME: Figure this out.
    sync-config
  )
  ;640x480 @ 60Hz (Industry standard) hsync: 31.5kHz	640x480	25.2 640 656 752 800 480 490 492 525	-hsync	-vsync
  
  (defun decode-edid-established-timings (edid)
    (let ((timings '()))
      (flet ((add (byte bit width height pixel-clock hsync hbporch hactive hfporch vsync vbporch vactive vfporch)
               (when (logbitp bit (aref edid byte))
                 (push (make-timing
                        :width width
                        :height height
                        :refresh-rate (truncate pixel-clock (* (+ hsync hbporch hactive hfporch)
                                                               (+ vsync vbporch vactive vfporch)))
                        :pixel-clock pixel-clock
                        :horz-left-border (floor (- hactive width) 2)
                        :horz-active hactive
                        :horz-right-border (ceiling (- hactive width) 2)
                        :horz-back-porch hbporch
                        :horz-sync hsync
                        :horz-front-porch hfporch
                        :horz-image-size (truncate (* (/ width 72) 25.4)) ; Assume 72dpi
                        :vert-top-border (floor (- vactive height) 2)
                        :vert-active vactive
                        :vert-bottom-border (ceiling (- vactive height) 2)
                        :vert-back-porch vbporch
                        :vert-sync vsync
  
negative.code:   (loop
       for i below 4
       for offset = (+ 54 (* i 18))
       when (not (and (zerop (aref edid offset))
                           (zerop (aref edid (+ offset 1)))))
       collect (decode-edid-detailed-timing edid offset)))
  
  (defun decode-raw-edid (edid)
  