1 LISP LIBRARY PACKAGES MANUAL 1 LISP LIBRARY PACKAGES MANUAL BUSCOLOR 1 GRAPHICS 1 BUSCOLOR 6 2 Introduction 1 Currently, all Xerox Lisp color software drivers for the Dandelion (Xerox 1108) run with the help of the BUSCOLOR package. BUSCOLOR defines an update daemon that moves pages from a Lisp framebuffer to a BusMaster color card's framebuffer. Packages like COLORNNCC, DANDELIONUFO, and DANDELIONUFO4096 automatically LOAD BUSCOLOR and a user will normally LOAD one of COLORNNCC, DANDELIONUFO, and DANDELIONUFO4096 rather than BUSCOLOR alone. A BusMaster color card's display framebuffer lives in the IBM PC-compatible chassis attached to the BusMaster card, while the framebuffer that Lisp programs manipulate lives in the Lisp address space. Without some sort of special intervention, updates to the Lisp framebuffer would never appear on the color screen. This intervention is provided by an update daemon that runs under the keyhandler many times a second, scanning the Lisp copy of the framebuffer for changes, and transmitting those changes to the BusMaster color card's display framebuffer. The dirty bit of each page in the Lisp framebuffer is checked; if the page is dirty, the page is transmitted across the BusMaster interface to the appropriate spot in the remote framebuffer and then the page is marked as clean; if the page was already clean, the update daemon simply skips over that page. 2 Adjustable BUSCOLOR Global Variables 1 \PERIODIC.INTERRUPT.FREQUENCY [Variable] To ensure that the update daemon runs in a timely fashion, the update daemon is invoked from Lisp's keyboard interrupt, which happens 77 times per second. The system variable \PERIODIC.INTERRUPT.FREQUENCY specifies how many keyboard interrupts should occur between invocations of the update daemon. A value of 1 means to run the update daemon 77 times per second; a value of 77 means to run the update daemon once per second. It is reasonable to set \PERIODIC.INTERRUPT.FREQUENCY to 10 or so. \BUSCOLOR.MOVELIMIT [Variable] Another variable, \BUSCOLOR.MOVELIMIT, specifies the maximum number of pages to move per daemon invocation. Forty (40) is a reasonable value for \BUSCOLOR.MOVELIMIT. The upper extreme is to set \BUSCOLOR.MOVELIMIT to ColorScreenBitMapPages, the number of pages in the color screen bitmap. 2 Implementing A BusMaster Color Card 1 As pointed out in the Introduction, all Xerox 1108 color drivers such as COLORNNCC, DANDELIONUFO, and DANDELIONUFO4096 work through BUSCOLOR. BUSCOLOR has been written so that as much common work as possible is done by BUSCOLOR through a narrow clean interface. A user with sufficient Lisp profiency should be able to implement the software to drive a BusMaster color card of the user's own choosing. It is necessary to write roughly 5 functions for the BusMaster color card of the user's own choosing, after which the user gets the Xerox Lisp color window system for free. We'll imagine that the user is going to write a package called MYCARD to drive the MYCARD color card manufactured by MYCARD Corporation. After buying a MYCARD color card, the user sets up all the hardware that is needed. This means (1) 1108 is running Interlisp-D. (2) PC expansion chassis is plugged in and powered on. (3) A cable connects between 1108 CPE board and Busmaster board. (The Busmaster board does not go into the 1108, but should rest outside the 1108.) (4) Another cable connects between PC expansion chassis and your Busmaster board. (5) A pair of purple and orange wires connects Busmaster board to the +5V/Gnd power supply terminals on the side of the 1108. (6) The MYCARD color card is plugged into the PC expansion chassis. (7) Color display is plugged in and powered on. (8) Three cables for red, green, and blue signal connect the MYCARD card to the color display. Any reconnections that involve (3), (4), or (5) should be made while the 1108 is off. Until some software commands are issued, a black display or an almost black display with a modest amount of noise visible is normal. It is probably a good idea for the user to try to do some exploration of the MYCARD color card that is independent of any attempt at writing the 5 magic functions that will hook MYCARD into the color window system. The user should write a few functions and try to become familiar with MYCARD's addressing scheme, how to set MYCARD color map entries, how to initialize MYCARD after MYCARD has been turned on, etc. A good exercise is to write a function that will set pixel (X,Y) to color C. The pixel writing function can then be used to draw some simple lines by using a loop. To do these kinds of exercises, the user will have to become acquainted with the functions and documention of the BUSMASTER library package and the user will also have to pull out of whatever documentation MYCARD Corporation supplies about MYCARD the right address numbers, command opcodes, other magic numbers, and addressing scheme needed to initialize and to drive the MYCARD color card. The user's exercising functions will just call BUSMASTER functions like PCBUS.WRITEHL or PCBUS.OUTPUT with the right combinations of numbers that MYCARD is supposed to understand. Supposing the user now wants to implement the MYCARD package that will work directly with the Xerox Lisp color window system, the user should should begin by setting MYCARDCOMS to ((* MYCARD -- Driver for MYCARD. *) (FNS \MYCARD.INIT \MYCARD.STARTBOARD \MYCARD.SENDCOLORMAPENTRY \MYCARD.SENDPAGE \MYCARD.PILOTBITBLT) (FILES BUSCOLOR) (DECLARE: DONTEVAL@COMPILE DOCOPY (P (\MYCARD.INIT)))) Function \MYCARD.INIT will announce the existence of the MYCARD software to the system, allowing (COLORDISPLAY 'ON 'MYCARD) to work. Assuming that MYCARD.WIDTH, MYCARD.HEIGHT, and MYCARD.BITSPERPIXEL are the frame buffer width, frame buffer height, and frame buffer bitsperpixel of MYCARD (MYCARD.BITSPERPIXEL must be 4, 8, or 24), function \MYCARD.INIT should look like so: (\MYCARD.INIT (LAMBDA NIL (DECLARE (GLOBALVARS \MYCARDWSOPS \MYCARDINFO)) (SETQ \MYCARDWSOPS (create WSOPS STARTBOARD _(FUNCTION \MYCARD.STARTBOARD) STARTCOLOR _(FUNCTION \BUSCOLOR.STARTCOLOR) STOPCOLOR _(FUNCTION \BUSCOLOR.STOPCOLOR) EVENTFN _(FUNCTION \BUSCOLOR.EVENTFN) SENDCOLORMAPENTRY _(FUNCTION \MYCARD.SENDCOLORMAPENTRY) SENDPAGE _(FUNCTION \MYCARD.SENDPAGE) PILOTBITBLT _(FUNCTION \MYCARD.PILOTBITBL))) (SETQ \MYCARDINFO (create DISPLAYINFO DITYPE _(QUOTE MYCARD) DIWIDTH _ MYCARD.WIDTH DIHEIGHT _ MYCARD.HEIGHT DIBITSPERPIXEL _ MYCARD.BITSPERPIXEL DIWSOPS _ \MYCARDWSOPS)) (\DEFINEDISPLAYINFO \MYCARDINFO))) Function \MYCARD.STARTBOARD should bring up a stable image on the user's color display. A color board generally needs to be enabled and passed a highly specific sequence of commands that describes such matters as frequencies and screen dimensions of the color monitor that is to be driven by the color board. Function \MYCARD.STARTBOARD should send the magic bytes the color board needs to know about to the color board by calling functions like PCBUS.WRITEHL or PCBUS.OUTPUT. The Xerox Lisp color window system does not care what the screen or color map look like after \MYCARD.STARTBOARD is called, so long as the color card is properly initialized with the attached color monitor showing a stable image of some kind. A correctly written \MYCARD.STARTBOARD will probably cause a completely black screen to flicker and then change into an abstract pattern representing the contents of MYCARD's RAM at the time MYCARD was turned on. Function \MYCARD.STARTBOARD should look something like so: (\MYCARD.STARTBOARD (LAMBDA NIL (* Initialize MYCARD board. Set access modes, overlay selects, board enables, zoom factors, frequencies, etc. *) (PCBUS.WRITEHL ... ... ...) (PCBUS.WRITEHL ... ... ...) ... (PCBUS.WRITEHL ... ... ...))) Function \MYCARD.SENDCOLORMAPENTRY should set an entry in the color map of MYCARD. A 4bpp color card will have a 16 element color map. An 8bpp color card will have a 256 element color map. For 24bpp, the user should use NILL in place of \MYCARD.SENDCOLORMAPENTRY inside the create form for \MYCARDWSOPS in function \MYCARD.INIT. Function \MYCARD.SENDCOLORMAPENTRY will be passed three arguments--an FDEV, a COLOR#, and an RGB triple--and should set entry COLOR# of MYCARD's color map to have the red, green, and blue components of RGB. Function \MYCARD.SENDCOLORMAPENTRY should look something like so: (\MYCARD.SENDCOLORMAPENTRY (LAMBDA (FDEV COLOR# RGB) (* Make entry COLOR# of MYCARD be RGB. *) (PROG(RED GREEN BLUE) (SETQ RED (fetch (RGB RED) of RGB)) (SETQ GREEN (fetch (RGB GREEN) of RGB)) (SETQ BLUE (fetch (RGB BLUE) of RGB)) (* Possibly some arithmetic to get RED, GREEN, BLUE into a form MYCARD likes. *) (* Send commands to MYCARD to make entry COLOR# of MYCARD be RGB. *) (PCBUS.WRITEHL ... ... ...) (PCBUS.WRITEHL ... ... ...) (PCBUS.WRITEHL ... ... ...) ))) Function \MYCARD.SENDPAGE should ship a page of the color screen bitmap out to the MYCARD frame buffer. There will be two copies of what is being shown on the color display stored in memory. One copy is the color screen bitmap which is stored in the 1108's memory. The other copy is the MYCARD frame buffer stored in MYCARD's memory (MYCARD will have its own RAM). The BUSCOLOR package supplies an update daemon called \BUSCOLOR.UPDATEDAEMON which periodically looks at the dirty page bits of pages in the color screen bitmap and then will call \MYCARD.SENDPAGE on dirty pages before marking dirty pages clean again. \MYCARD.SENDPAGE will be called with two arguments, PAGE and PAGE#. PAGE is the page of the color screen bitmap that was found to be dirty and is to be shipped to the MYCARD color card. PAGE# is the relative page number of PAGE in the representation of the color screen bitmap. (\MYCARD.SENDPAGE (LAMBDA (PAGE PAGE#) (PROG(DISPINTERRUPT) (* These two instructions do interrupt masking during a sendpage, so that there will be no interference by the cursor while sending a page. *) (SETQ DISPINTERRUPT (\GETBASE \EM.DISPINTERRUPT 0)) (\PUTBASE \EM.DISPINTERRUPT 0 0) (* The user should now ship PAGE out to the MYCARD color card. Because frame buffers are so big, the user will probably first have to tell MYCARD which "bank" or "window" of MYCARD memory is going to be written to. This is known as bank switching. After selecting a bank, the user should ship the contents of PAGE. *) (* The following two instructions typify the kind of instructions needed to choose a "window" of MYCARD memory. *) (PCBUS.WRITEHL MYCARD.PARAMAREA MYCARD.WINDOWADDRHI (LLSH (LOGAND PAGE# 3) 6)) (PCBUS.WRITEHL MYCARD.PARAMAREA MYCARD.WINDOWADDRLO (LRSH PAGE# 2)) (* The next instruction ships the contents of PAGE. *) (\BUSBLTOUTNYBBLES PAGE MYCARD.FRAMEADDRHI MYCARD.FRAMEADDRLO WORDSPERPAGE) (* The next instruction resets the interrupt mask which was set above. *) (\PUTBASE \EM.DISPINTERRUPT 0 DISPINTERRUPT)))) Blah blah blah \MYCARD.PILOTBITBLT.  +8+8/ÌÌøøT.ÌÌø È/øÈT/ø2ÈT/ÌÌøÈT/ÌÌøÈT<ø PAGEHEADING VERSOHEAD<ø PAGEHEADING RECTOHEAD;ø PAGEHEADINGFOOTINGV;ø PAGEHEADINGFOOTINGRMODERN MODERN MODERNMODERNMODERN   HRULE.GETFNMODERN    HRULE.GETFNMODERN     HRULE.GETFNMODERN    HRULE.GETFNMODERN   HRULE.GETFNMODERN HRULE.GETFNMODERN  HRULE.GETFNMODERN¹=" HRULE.GETFNMODERN% HRULE.GETFNMODERN ð # HRULE.GETFNMODERN% HRULE.GETFNMODERNAê'<˜WƒJ5bÜ‚¦ *+:!=  c  ;,tvtp‚pw113?3, Ê %n'' + >< 6:8k^+++ nPQ:'NWPU)R2WJ=RP6$/€zº