head     56.3;
access   paws bayes jws quist brad dew jwh;
symbols  ;
locks    ; strict;
comment  @# @;


56.3
date     93.01.27.13.36.36;  author jwh;  state Exp;
branches ;
next     56.2;

56.2
date     93.01.27.12.12.23;  author jwh;  state Exp;
branches ;
next     56.1;

56.1
date     91.11.05.09.42.05;  author jwh;  state Exp;
branches ;
next     55.1;

55.1
date     91.08.25.10.20.21;  author jwh;  state Exp;
branches ;
next     54.1;

54.1
date     91.03.18.15.25.05;  author jwh;  state Exp;
branches ;
next     53.1;

53.1
date     91.03.11.19.26.16;  author jwh;  state Exp;
branches ;
next     52.1;

52.1
date     91.02.19.09.10.15;  author jwh;  state Exp;
branches ;
next     51.1;

51.1
date     91.01.30.16.09.46;  author jwh;  state Exp;
branches ;
next     50.1;

50.1
date     90.10.29.16.24.40;  author jwh;  state Exp;
branches ;
next     49.1;

49.1
date     90.08.14.14.08.58;  author jwh;  state Exp;
branches ;
next     48.1;

48.1
date     90.07.26.11.14.57;  author jwh;  state Exp;
branches ;
next     47.1;

47.1
date     90.05.14.10.56.23;  author dew;  state Exp;
branches ;
next     46.1;

46.1
date     90.05.07.08.43.33;  author jwh;  state Exp;
branches ;
next     45.1;

45.1
date     90.04.19.15.51.03;  author jwh;  state Exp;
branches ;
next     44.1;

44.1
date     90.04.01.22.08.34;  author jwh;  state Exp;
branches ;
next     43.1;

43.1
date     90.03.20.13.59.51;  author jwh;  state Exp;
branches ;
next     42.1;

42.1
date     90.01.23.17.44.18;  author jwh;  state Exp;
branches ;
next     41.1;

41.1
date     89.12.22.11.27.31;  author jwh;  state Exp;
branches ;
next     40.1;

40.1
date     89.09.29.11.49.27;  author jwh;  state Exp;
branches ;
next     39.1;

39.1
date     89.09.26.16.33.59;  author dew;  state Exp;
branches ;
next     38.1;

38.1
date     89.08.29.11.25.17;  author jwh;  state Exp;
branches ;
next     37.1;

37.1
date     89.05.12.11.38.06;  author dew;  state Exp;
branches ;
next     36.1;

36.1
date     89.02.06.10.16.40;  author dew;  state Exp;
branches ;
next     35.1;

35.1
date     89.02.02.13.30.25;  author dew;  state Exp;
branches ;
next     34.1;

34.1
date     89.01.23.16.05.35;  author jwh;  state Exp;
branches ;
next     33.1;

33.1
date     89.01.16.11.38.35;  author dew;  state Exp;
branches ;
next     32.1;

32.1
date     89.01.10.11.46.06;  author bayes;  state Exp;
branches ;
next     31.1;

31.1
date     88.12.14.18.07.24;  author bayes;  state Exp;
branches ;
next     30.1;

30.1
date     88.12.09.13.44.49;  author dew;  state Exp;
branches ;
next     29.3;

29.3
date     88.11.18.10.59.10;  author bayes;  state Exp;
branches ;
next     29.2;

29.2
date     88.11.01.16.10.42;  author dew;  state Exp;
branches ;
next     29.1;

29.1
date     88.10.31.15.29.25;  author bayes;  state Exp;
branches ;
next     28.1;

28.1
date     88.10.06.10.57.15;  author dew;  state Exp;
branches ;
next     27.1;

27.1
date     88.09.29.11.27.11;  author bayes;  state Exp;
branches ;
next     26.1;

26.1
date     88.09.28.13.08.42;  author bayes;  state Exp;
branches ;
next     25.4;

25.4
date     88.06.06.10.06.11;  author bayes;  state Exp;
branches ;
next     25.3;

25.3
date     88.05.23.17.17.11;  author bayes;  state Exp;
branches ;
next     25.2;

25.2
date     88.03.29.17.16.24;  author bayes;  state Exp;
branches ;
next     25.1;

25.1
date     88.03.02.09.25.10;  author bayes;  state Exp;
branches ;
next     24.1;

24.1
date     88.02.04.14.53.05;  author bayes;  state Exp;
branches ;
next     1.1;

1.1
date     88.02.04.14.51.41;  author bayes;  state tmp;
branches ;
next     ;


desc
@Base file for PWS 3.2 release.

@


56.3
log
@
pws2rcs automatic delta on Wed Jan 27 13:14:25 MST 1993
@
text
@	page
*
*   CATSEYE family bit-mapped alpha driver
*
*     Pascal 3.21 version by S. Bayes (SFB)
*
* Note that there are many commented-out line of source. These are usually
* enhancements that I wasn't allowed to implement. They're left in because
* they may be instructive to people who wish to make certain kinds of
* enhancements: split alpha/graphics, character micro-spacing, various
* cursor-restoration strategies, etc.
*
* The data structures in the source "CATCRT.TEXT" will give more hints as to
* what might have been. SFB
*
* 11/17/88 - many small bug fixes for unusual cases:
*       o autoscrolling characters out of plane 0 (depends on alpha color)
*         was clearing top of display (planemode probem)
*       o wrr1 was not getting set due to badly aligned word move of #$ff
*         to tcwen1. Caused debug window shifts to change colors
*       o was adding dispx instead of dispy to position (effectless bug)


	def     cscrollup,cscrolldown,cupdatecursor,cchar,cclear
	def     cbuildtable,cshiftleft,cshiftright
	def     cexchange,cscrollwindow,cursoroff
	def     cscrollwinddn,cdbscrolll,cdbscrollr,cclearall
	def     csetcolormap,csetreg,csavecatenv,crestorecatenv
	def     cromshort,cputfontchar,csetupcchar,cprepdumpline

	def setupcchar

	rorg.l 0

	refa    catseyedvr,sysdevs

	nosyms
	sprint

crtinfo         equ     catseyedvr-4
cpl             equ     crtinfo-2
cppl            equ     cpl-2
fb_fontchars    equ     cppl-2
maxy            equ     fb_fontchars-2
cursx           equ     maxy-2
cursy           equ     cursx-2
hascolor        equ     cursy-1
midres          equ     hascolor-1

controladdr     equ     sysdevs-86
screen          equ     sysdevs-90

doblit          equ     $90             {literal to set RUGCMD to blit mode}


* OFFSETS FOR CRTPARAMS

fbwidth         equ     0
fbheight        equ     fbwidth+2
dispx           equ     fbheight+2
dispy           equ     dispx+2
dispw           equ     dispy+2
disph           equ     dispw+2
printx          equ     disph+2
printy          equ     printx+2
printw          equ     printy+2
printh          equ     printw+2
offx            equ     printh+2
offy            equ     offx+2
offw            equ     offy+2
offh            equ     offw+2
charw           equ     offh+2
charh           equ     charw+2
fb_fontstartx   equ     charh+2
fb_fontstarty   equ     fb_fontstartx+2
fb_font_line_len equ    fb_fontstarty+2
fb_fontlines    equ     fb_font_line_len+2
nfontchars      equ     fb_fontlines+2
fb_cursorx      equ     nfontchars+4
fb_cursory      equ     fb_cursorx+2

set_colormap_proc equ   fb_cursory+2
planemask       equ     set_colormap_proc+8
alphacolor      equ     planemask+4
cursorcolor     equ     alphacolor+2
*lowalphaplane  equ     writeyoffset+2
*highlight      equ     lowalphaplane+1
highlight       equ     cursorcolor+2
creplrule0      equ     highlight+2
creplrule1      equ     creplrule0+1
cursreplrule0   equ     creplrule1+1
cursreplrule1   equ     cursreplrule0+1

flags           equ     cursreplrule1+1
togglealpha     equ     7       bit number
togglegraphics  equ     6       bit number
copy_under_cursor equ   5       bit number
use_fib_xy      equ     4       bit number
disable_low_ctl equ     3       bit number
disable_hi_ctl  equ     2       bit number
copy_to_abuf    equ     1       bit number

*       CATSEYE REGISTER OFFSETS (ADD CONTROL BASE ADDRESS)

IDREG           equ     $0000
INTREG          equ     $0002

CATSTAT         equ     $4800
CMSTAT          equ     $6002
VBSTAT          equ     $6040

BLANKALL        equ     $605C

OVERLAYCTL      equ     $60A2

CMINDEX         equ     $60B0
CMRED           equ     $60B2
CMGREEN         equ     $60B4
CMBLUE          equ     $60B6

PLANEMASKREG    equ     $60BA

CMAPWRITE       equ     $60F0
CMAPREAD        equ     $60F8

WMSTAT          equ     $4044

TCWEN1          equ     $4508
TCWEN2          equ     $4708
TCREN1          equ     $4504
TCREN2          equ     $4704

FBEN1           equ     $4500
FBEN2           equ     $4700

STARTMOVE       equ     $409C

RUGCMD          equ     $4206
RUGSTAT         equ     $4206

WMWIDTH         equ     $4208
WMHEIGHT        equ     $420A
WMSOURCEX       equ     $4210
WMSOURCEY       equ     $4212
WMDESTX         equ     $4214
WMDESTY         equ     $4216
LINEPATT        equ     $420C
LINETYPE        equ     $420E

TWMWIDTH        equ     $4308
TWMHEIGHT       equ     $430A
TWMSOURCEX      equ     $4310
TWMSOURCEY      equ     $4312
TWMDESTX        equ     $4314
TWMDESTY        equ     $4316
WMSTART         equ     $409C

WMCLIPLEFT      equ     $4218
WMCLIPRIGHT     equ     $421A
WMCLIPTOP       equ     $421C
WMCLIPBOTTOM    equ     $421E

PRR1            equ     $4502
WRR1            equ     $4506

PRR2            equ     $4702
WRR2            equ     $4706

PATTERNS        equ     $4400

TRR             equ     $450C

COLOR1          equ     $450E
COLOR2          equ     $470E

VB              equ     $4510

TRRCTL          equ     $4512

ACNTRL1         equ     $4514
ACNTRL2         equ     $4714

PLANEMODE       equ     $4516


* GRAPHICS ROM OFFSETS

initoffset   equ      $23            offset to initialization offset
fontoffset   equ      $3B            offset to font info offset
frameoffset  equ      $5D            offset to frame buffer reg. offset
cmapaddr     equ      $33            addr of color map (0 = monochrome)
cmapidoff    equ      $57            offset to color map id offset
cmapinitoff  equ      $3F            offset to cmap 0 init region offset
framecnt     equ      $5B            offset of number of frames
fbw          equ      $5             width of frame buffer
fbh          equ      $9             height of frame buffer
dspw         equ      $D             width of displayed frame buffer
dsph         equ      $11            height of displayed frame buffer

*
* cromshort returns a shortint from the graphics ID ROM.
* it picks up the byte at the offset, and the one 2 bytes away from
* it and composes a shortint
*
cromshort   equ      *
	    movea.l  controladdr(a5),a0
	    movea.l  (sp)+,a1           return address
	    adda.l   (sp)+,a0           offset
	    movep    0(a0),d0
	    move.w   d0,(sp)            store on stack as function value
	    jmp      (a1)

*
* csetreg sets the register which is offset from the graphics control
* address to the value
*
csetreg     equ       *
	    movea.l   controladdr(a5),a0
	    movea.l   (sp)+,a1          return address
	    move      (sp)+,d0          value
waitset     equ       *
	    btst      #0,catstat+1(a0)
	    bne.s     waitset
	    adda.l    (sp)+,a0          offset
	    move      d0,(a0)           set the register
	    jmp       (a1)

*
* cputfontchar takes a fontchardata structure from the address (dataptr) passed
* in, moves it to the phantom plane, thence to the cell for font storage
* in the framebuf. It does not restore CATSEYE registers when done.
*
cputfontchar equ      *
	    movea.l   controladdr(a5),a0
	    movea.l   crtinfo(a5),a3
	    movea.l   (sp)+,a1          return address
	    move.b    (sp)+,d1          oddbytes
	    addq      #1,d1             1+ord(oddbytes)
	    movea.l   (sp)+,a2          dataptr
	    move      (sp)+,d2          yposition
	    move      (sp)+,d0          plane number
	    move      d0,d4             in case it's negative
	    ext.l     d4
	    blt.s     charplaneready
	    move      #1,d4             generate destination plane mask
	    asl       d0,d4             single plane to enable
charplaneready equ    *
	    btst      #0,catstat+1(a0)
	    bne.s     charplaneready
	    move      d2,wmdesty(a0)    yposition
	    move      (sp)+,wmdestx(a0) xposition
	    move      #0,wmsourcex(a0)
	    move      #0,wmsourcey(a0)
	    move      charw(a3),wmwidth(a0)
	    move      charh(a3),wmheight(a0)
	    btst      #0,midres(a5)
	    bne       lccputfontc
	    btst      #1,planemask+3(a3)
	    bne.s     hrcputfontc

hrmputfontc equ       *
	    move.b    #2,fben1(a0)      disable display/enable phantom plane
	    move.b    #2,tcwen1(a0)     set rule for phantom plane only
	    move.b    #3,prr1(a0)       source rule for pixel moves
	    move.b    #1,acntrl1(a0)    set "bit-per-pixel"
	    bsr       movetophantom
	    move.b    #$11,planemode(a0) select phantom plane as move source
	    move.b    d4,tcwen1(a0)     font storage plane
	    move.b    #3,wrr1+1(a0)     set source rule
	    move.b    d4,fben1(a0)      enable only target font plane
	    move.b    #0,wmstart(a0)    trigger the move
	    bsr       waitforready
	    move.b    #0,acntrl1(a0)    set "byte-per-pixel"
	    jmp       (a1)              return

hrcputfontc equ       *
	    move.b    #0,fben1(a0)      disable display planes
	    move.b    #4,fben2(a0)      enable phantom plane
	    move.b    #4,tcwen2(a0)     set rule for phantom plane only
	    move.b    #3,prr2(a0)       source rule for pixel moves
	    move.b    #3,acntrl2(a0)    set "bit-per-pixel"/"BARC bank 2"
	    bsr       movetophantom
	    move.b    #$1a,planemode(a0) select phantom plane as move source
	    move.b    d4,tcwen1(a0)     font storage plane
	    move.b    #3,wrr1+1(a0)     set source rule
	    move.b    d4,fben1(a0)      enable only target font plane
	    move.b    #0,fben2(a0)      disable upper 3 planes
	    move.b    #0,wmstart(a0)    trigger the move
	    bsr       waitforready
	    move.b    #0,acntrl2(a0)    set "byte-per-pixel"
	    jmp       (a1)              return

lccputfontc move.b    #$20,fben1(a0)    disable non-phantom planes
	    move.b    #$80,catstat+1(a0) select phantom plane destination
	    move.b    #$20,tcwen1(a0)
	    move.b    #3,prr1(a0)       source rule for pixel moves
	    move.b    #1,acntrl1(a0)    set "bit-per-pixel"
	    bsr       movetophantom
	    move.b    #$40,catstat+1(a0) select phantom plane source
	    move.b    #$15,planemode(a0) select phantom plane as move source
	    move.b    d4,tcwen1(a0)
	    move.b    #3,wrr1+1(a0)     set source rule
	    move.b    d4,fben1(a0)      enable only target font plane
	    move.b    #0,wmstart(a0)    trigger the move
	    bsr       waitforready
	    move.b    #$0,catstat+1(a0) disable phantom access
	    move.b    #0,acntrl1(a0)    set "byte-per-pixel"
	    jmp       (a1)              return

movetophantom equ     *
* move the fontchar in datastructure pointed to by dataptr to the
* cell in phantom plane whose upper left corner is at 0,0.
* oddbytes=true implies use only every second byte (ie font is in ROM)
* some setup for this done at putfontchar

* implements    fbelement:=0;
*               k:=0;
*               for i:=0 to charh-1 do
*                begin
*                 for j:=0 to (charw-1) div 8 do
*                  begin
*                       framebuf[fbelement+j*8+ord(odd(j))]:=dataptr^[k];
*                       k:=k+ord(oddbyte);
*                  endl
*                 fbelement:=fbelement+fbwidth;
*                end;

* previous setup                        a2 dataptr
*    ditto                              d1 ord(oddbyte)+1

	    movea.l   screen(a5),a4     a4 framebuffer address
	    move      charw(a3),d6      width loop limit
	    subq      #1,d6
	    asr.w     #3,d6             d6 (charw-1) div 8
	    moveq     #0,d3             d3 indexes dataptr (k)
	    move      charh(a3),d0      d0 height loop (i)
	    subq      #1,d0             for use in dbra
iloop       equ       *
	    moveq     #0,d2       d2 pixel this scanline (like fbelement kinda)
	    moveq     #0,d5             d5 width loop (j)
jloop       equ       *
	    btst      #0,d5
	    beq.s     evenj
oddj        move.b    0(a2,d3),1(a4,d2) copy the byte
	    bra.s     finishloop
evenj       move.b    0(a2,d3),0(a4,d2) copy the byte
finishloop  add.b     d1,d3             k:=k+ord(oddbyte)+1
	    add       #8,d2             fbelement+j*8
	    addq      #1,d5
	    cmp       d5,d6
	    bge       jloop
	    adda.w    fbwidth(a3),a4    next scanline
	    dbra      d0,iloop
	    rts

*
*   cbuildtable
*
cbuildtable movea.l  controladdr(a5),a0    get pointer to ROM start
	    movea.l  crtinfo(a5),a3        crtparamrec
	    movep    initoffset(a0),d1     form pointer to init block
	    movea.l  a0,a1                  make copy of ROM start addr
	    adda     d1,a1                  a1 points to init info now
	    bsr      ginitblock             call the initialization routine
	    clr.b    hascolor(a5)
	    movep    cmapaddr(a0),d0        get color map addr
	    tst      d0
	    beq.s    cnocolor               if 0 then no color init

	    moveq    #0,d1
	    movep    cmapidoff(a0),d0       get ptr to color map id reg
	    tst      d0                     if ptr=0, then use init region 0
	    beq.s    cinitclr
	    move.b   0(a0,d0),d1            get cmap id into d1
cinitclr    and      #3,d1                  look at least sig bits
	    lsl      #2,d1
	    move.b   cmapinitoff(a0,d1.w),d2  form cmap init block addr
	    lsl      #8,d2
	    move.b   cmapinitoff+2(a0,d1.w),d2
	    movea.l  a0,a1
	    adda     d2,a1                  a1 points to cmap init block
	    bsr      ginitblock
	    st       hascolor(a5)           set color boolean
cnocolor    clr.l    screen(a5)             clear space for frame buffer addr
	    movep.w  frameoffset(a0),d0     get offset of frame buffer loc.
	    move.b   0(a0,d0),screen+1(a5)  form frame buffer addr

	    move.b   framecnt(a0),d0      d0=# of planes in system
	    beq.s    cnumplanes           if zero then read planes
	    moveq    #8,d1                else make the mask up
	    moveq    #$FF,d2
	    sub      d0,d1                d1 has shift count
	    lsr.b    d1,d2                after shift d2 has mask
	    bra.s    csetplanes           go setup planemask

cnumplanes  moveq   #0,d2
	    movea.l screen(a5),a1         addr of fb in a1
	    move.b  #$FF,(a1)             write all 1's
	    move.b  (a1),d2               get plane mask in d2
csetplanes  move.l  #0,planemask(a3)       clear MSBs, as this is full 32 bits
	    move.b  d2,3+planemask(a3)     save as plane mask
	    tst.b   hascolor(a5)           monochrome ?
	    beq.s   cnocolor2              if so then skip color map init
	    move    d2,planemaskreg(a0)    set color map mask
	    bsr     loadcmap               load the color map
	    st       hascolor(a5)          set color boolean


cnocolor2   moveq    #0,d0      {we don't clear framebuf here, as the graphics
*                                ID ROM will do it anyway on CATSEYE. SFB}
	    move     d0,dispx(a3)
	    move     d0,printx(a3)
	    move     d0,dispy(a3)
	    move     d0,printy(a3)
	    movep.w  fbw(a0),d2             get width from ROM
	    move     d2,fbwidth(a3)
	    movep.w  dspw(a0),d2            set visible widthas window width SFB
	    movep.w  fbh(a0),d2             get height from ROM
	    move     d2,fbheight(a3)
	    movep.w  dspw(a0),d2
	    cmp      #1024,d2
	    beq.s    setuplcc

setuphrx    equ      *
	    move     #1280,offx(a3)
	    move     #0,offy(a3)
	    move     #768,offw(a3)
	    move     #1024,offh(a3)
	    bra.s    donesetupoff

setuplcc    equ      *
	    move     #0,offx(a3)
	    move     #768,offy(a3)
	    move     #1024,offw(a3)
	    move     #256,offh(a3)

donesetupoff equ     *
	    move     d2,dispw(a3)
	    move     d2,printw(a3)
	    movep.w  dsph(a0),d2
	    move     d2,disph(a3)
*           sub      charh(a3),d2       would like to do this now, but can't,
*           move     d2,printh(a3)      as we haven't sorted out the font yet


cclrtst     btst     #0,catstat+1(a0)
	    bne      cclrtst
cfbclrdone  move.b   #$3,prr1(a0)           setup pixel repl rule

*           bsr      catseyedvr_loadfonts   set up all 3 fonts @@ 128 char each
*                                           We'll do this from Pascal
	    rts
*
*   misc utilities for initialization
*
*
loadcmap    lea     cmaptable,a1          initialize the color map
	    moveq   #0,d1                 clear some registers
	    move.l  d1,d2
	    move.l  d1,d3
	    move.l  d1,d4
cmaploop1   move.b  (a1)+,d2              get rgb values in d2-d4
	    move.b  (a1)+,d3
	    move.b  (a1)+,d4
	    bsr     cmapenter             stuff the color map entry
	    addq    #1,d1                 bump cmap pointer value
	    cmp     #16,d1                have we done 16 yet?
	    bne     cmaploop1             if not then continue
	    moveq   #-1,d2                set entries 16-255 to white
	    move.l  d2,d3
	    move.l  d2,d4
cmaploop2   bsr     cmapenter
	    addq    #1,d1
	    cmp     #256,d1                done with cmap init?
	    bne     cmaploop2
	    rts

csetcolormap equ    *                   callable from pascal
	    movea.l controladdr(a5),a0
	    move.l  (sp)+,d1            colormap index parameter
	    move.l  (sp)+,d2            red value
	    move.l  (sp)+,d3            green value
	    move.l  (sp)+,d4            blue value

cmapenter   btst    #2,cmstat+1(a0)       check for color map busy
	    bne     cmapenter             loop till bit is clear
	    move    d1,cmindex(a0)        set pointer register
	    move    d2,cmred(a0)          stuff the rgb regs
	    move    d3,cmgreen(a0)
	    move    d4,cmblue(a0)
	    move    d5,cmapwrite(a0)      hit the write trigger
	    rts                           done with cmap entry write
*
*
*
ginitblock  moveq    #0,d1                  clear some regs
	    moveq    #0,d0
	    move.b   2(a1),d0               get word count to initialize
	    movep    4(a1),d1               form destination offset
	    add.l    a0,d1                  d1 points to dest addr
	    lea      8(a1),a2               a2 points to first data byte
	    movea.l  d1,a4                  a4 points to destination
	    btst     #0,(a1)                is this a bit test block?
	    bne.s    ginitbtst              if so go handle it
ginitloop   movep    0(a2),d1                form a data word in d1
	    move.w   d1,(a4)+               move data to the destination addr
	    btst     #6,(a1)                increment data pointer
	    bne.s    ginit1                 based on control byte
	    addq     #4,a2
ginit1      dbra     d0,ginitloop           loop till word count exhausted
	    btst     #7,(a1)                was this last block?
	    bne.s    ginitdone              yes -- go return
	    btst     #6,(a1)                adjust data pointer
	    beq.s    ginit2                 to point to next init block
ginit3      addq     #4,a2
ginit2      movea.l  a2,a1                  a1 points to new init block
	    bra      ginitblock             do the initialize
ginitdone   rts

ginitbtst   moveq    #0,d2                  handle bit test blocks here
	    move.b   2(a2),d2               d2 = bit # to test
ginittst2   move     (a4),d3                d3 = data word to test
	    btst     #0,(a2)                check for sense of test
	    bne.s    ginittst3              comp if waiting for 0
	    not      d3
ginittst3   btst     d2,d3                  check the bit
	    beq      ginittst2              if not 1 then loop
	    btst     #7,(a1)                was this last block?
	    bne      ginitdone              if so then return
	    bra      ginit3                 else do next block
*
*
cmaptable   equ      *                      initial color map contents (r,g,b)
	    dc.b     0,0,0                  0
	    dc.b     255,255,255            1
	    dc.b     255,0,0                2
	    dc.b     255,255,0              3
	    dc.b     0,255,0                4
	    dc.b     0,255,255              5
	    dc.b     0,0,255                6
	    dc.b     255,0,255              7
	    dc.b     0,0,0                  8
	    dc.b     204,187,51             9
	    dc.b     51,170,119             10
	    dc.b     136,102,170            11
	    dc.b     204,68,102             12
	    dc.b     255,102,51             13
	    dc.b     255,119,0              14
	    dc.b     221,136,68             15

*
*  waitforready:  wait till window mover done
*
*
waitforready equ *
	movea.l controladdr(a5),a0
waitmready      equ     *
	btst    #0,catstat+1(a0)
	bne.s   waitmready
	rts
*
*
* csavecatenv: preserve CATSEYE registers used by alpha driver
* and set up for future cchar and cupdatecursor calls (optimization).
* Register contents are stored in CATSEYEDVR stack frame buffer
* allocated for that purpose, whose address is passed in.
*

csavecatenv equ *
	    movea.l (sp)+,a2            save return addr
	    movea.l (sp)+,a1            buffer address
	    move.l  a2,-(sp)            prepare for regular rts

	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3      get crtparams ptr
	    lea     rugcmd(a0),a2       address of first catseye reg to save

waitsave    equ     *                   wait for registers idle
	    btst    #0,catstat+1(a0)
	    bne.s   waitsave

	    move.w  (a2)+,(a1)+         RUGCMD  (not on longword boundary)
	    move.l  (a2)+,(a1)+         WMWIDTH & WMHEIGHT (now in longwords)
*           move.l  (a2)+,(a1)+         LINEPATT & LINETYPE (not saved)
	    addq    #4,a2               instead, skip linepatt & linetype
	    move.l  (a2)+,(a1)+         WMSOURCEX & WMSOURCEY
	    move.l  (a2)+,(a1)+         WMDESTX & WMDESTY
	    move.w  fben1(a0),(a1)+     get other regs
*
*                       the tcwen and tcren registers provide floating
*                       bits when read if all 8 planes are not loaded.
*                       Because writing these registers with more
*                       than one bit set will cause h/w problems, need
*                       to 'and' out the floating  bits. 6/2/88 SFB/DEW
*
	    move.w  tcren1(a0),d0
	    move.w  planemask+2(a3),d2    d2 will hold the adjusted plane
	    lsl.w   #8,d2               mask for the tcwen register.
	    and.w   d2,d0
	    move.w  d0,(a1)+
*
	    moveq   #7,d0
	    moveq   #1,d1               select plane 0
getwrr      equ     *                   preserve all 8 wrrs
	    move.b  d1,tcren1(a0)       address next plane wrr
	    move.b  wrr1+1(a0),(a1)+    and save wrr
	    asl     #1,d1               select next plane
	    dbra    d0,getwrr
*
	    move.w  tcwen1(a0),d0       6/2/88 SFB/DEW (see comment above)
	    and.w   d2,d0
	    move.w  d0,(a1)+
*
	    move.w  vb(a0),(a1)+
	    move.w  trrctl(a0),(a1)+   added save of TRRCTL 5/24/88 SFB/DEW
	    move.w  planemode(a0),(a1)

*           now drop through and set up driver state of CATSEYE

* sets up CATSEYE regs to the state we mostly maintain during driver execution,
* ready for a cchar call (as it's the most common call)
* At entry to setupcchar, a0=controladdr(a5), a3=crtinfo(a5), a5=global ptr,
* and return address is on stack

setupcchar  equ     *                   callable from elsewhere in this code
	    lea     rugcmd(a0),a2       set up regs for cchar & cupdatecursor

	    move.w  #doblit,(a2)+       RUGCMD
	    move.l  charw(a3),(a2)+     WMWIDTH & WMHEIGHT

*           move.b  lowalphaplane(a3),d0 set up fben1 mask for split
*           moveq   #$ff,d1             alpha and graphics
*           lsl.l   d0,d1               mask is in d1 (d0 <= 7 for CATSEYE)
*           move.b  d1,fben1(a0)

	    move.b  #$ff,fben1(a0)

	    move.w  alphacolor(a3),d1   prepare wrrs for putting characters

*           move.w  alphacolor(a3),d2   prepare wrrs for putting characters
*           lsl     d0,d2               according to alphacolor and
*           and     d2,d1               lowalphaplane. d1 is bit mask for

	    move.b  d1,tcwen1(a0)       for 1s in color.
	    move.b  creplrule1(a3),wrr1+1(a0)
	    not     d1
	    move.b  d1,tcwen1(a0)       now set up for 0s
	    move.b  creplrule0(a3),wrr1+1(a0)
	    move.b  #0,vb(a0)
	    move.b  #0,trrctl(a0)       added set not TRRCTL. SFB/DEW 5/24/88
	    rts

*
* csetupcchar sets up window mover params without csavecatenv. Meant for
* call from Pascal when color or inverse video enhancement enable change.
*

csetupcchar equ     *
	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3      get crtparams ptr

waitcsetup  equ     *                   wait for registers idle
	    btst    #0,catstat+1(a0)
	    bne.s   waitcsetup

	    bra     setupcchar

*
*
* restorecatenv: restore CATSEYE registers used by alpha driver.
* Register contents were stored in CATSEYEDVR stack frame buffer
* allocated for that purpose, whose address is passed in.
*

crestorecatenv equ  *
	    movea.l (sp)+,a2            save return addr
	    movea.l (sp)+,a1            buffer address
	    move.l  a2,-(sp)            prepare for regular rts
	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3      get crtparams ptr
	    lea     rugcmd(a0),a2       address of first catseye reg to save
waitrestore equ   *                     wait for registers idle
	    btst    #0,catstat+1(a0)
	    bne.s   waitrestore

	    move.w  (a1)+,(a2)+         RUGCMD  (not on longword boundary)
	    move.l  (a1)+,(a2)+         WMWIDTH & WMHEIGHT (now in longwords)
*           move.l  (a1)+,(a2)+         LINEPATT & LINETYPE (not saved)
	    addq    #4,a2               instead, skip linepatt & linetype
	    move.l  (a1)+,(a2)+         WMSOURCEX & WMSOURCEY
	    move.l  (a1)+,(a2)+         WMDESTX & WMDESTY
	    move.w  (a1)+,fben1(a0)     restore other regs
	    move.w  (a1)+,tcren1(a0)
	    moveq   #7,d0
	    moveq   #1,d1               select plane 0
setwrr      equ     *                   restore all 8 wrrs
	    move.b  d1,tcwen1(a0)       address next plane wrr
	    move.b  (a1)+,wrr1+1(a0)    and restore wrr
	    asl     #1,d1               select next plane
	    dbra    d0,setwrr
	    move.w  (a1)+,tcwen1(a0)
	    move.w  (a1)+,vb(a0)
	    move.w  (a1)+,trrctl(a0)   added restore of TRRCTL 5/24/88 SFB/DEW
	    move.w  (a1),planemode(a0)
	    rts

*
*
*  procedure cclearall: clears all of visible area except typeahead
*
cclearall   equ     *
	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3              crtparamrec
cclralltst  btst    #0,catstat+1(a0)
	    bne     cclralltst
	    move.b  #$ff,tcwen1(a0)             to clear on all planes 11/18/88 SFB
	    move    #0,wrr1(a0)                 set repl rule
	    move    dispx(a3),wmsourcex(a0)     setup x,y
	    move    dispy(a3),wmsourcey(a0)
	    move    dispx(a3),wmdestx(a0)
	    move    dispy(a3),wmdesty(a0)
	    move    dispw(a3),wmwidth(a0)       set width, height
	    move    disph(a3),twmheight(a0)    and do move

*           don't need to set up for cchar, as cclearall can't be called in
*           same invocation of driver as cchar

	    rts

*
*
*   procedure cchar(ord(char),x,y:shortint);
*
*       note that we place the character in one window move in cchar,
*       because setupcchar or csetupcchar has already set up all windowmover replacement
*       rules on a per plane basis to move 1s and 0s where necessary, as well as
*       setting up the move height and width to character cell size,
*       and this is a run-on sentence   :-)

cchar    movea.l (sp)+,a4               return address
	 movea.l controladdr(a5),a0     CATSEYE registers
	 movea.l crtinfo(a5),a3         crtparamrec

	 move.w  (sp)+,d0               d0 = dest y char offset
	 mulu    charh(a3),d0           d0 = pixel row offset
	 add.w   printy(a3),d0          adjust to display window
*        add.w   writeyoffset(a3),d0    pixel y offset of chars
*                                       d0 is y-destination

	 move.w  (sp)+,d1               d1 = x char offset
	 mulu.w  charw(a3),d1           d1 = pixel column offset
	 add.w   printx(a3),d1          adjust to display window
*        add.w   writexoffset(a3),d1    pixel x offset of chars
*                                       d1 is x-destination

	 moveq   #0,d2                  clear longword for divide
	 move.w  (sp)+,d2               character index
	 cmp.w   fb_fontchars(a5),d2    see if char is in frame buf, or RAM
	 bge     offscreenchar

*       font character is somewhere in frame buffer
*       calculate x,y,plane of fontchar
*       cppl and cpl precomputed at driver init time, global to catseyedvr
*       cppl=characters in one fontline rectangle 1 plane deep (characters per
*          plane line)
*       cpl=characters in one fontline rectangle n planes deep (characters per
*          line)
*       x=fb_fontstartx+(c mod cppl)*charw
*        =fb_fontstartx+((c mod cpl) mod cppl)*charw
*         (because cpl=n*cppl, and the code works out shorter this way)
*       y=fonty+(c div cpl)*fonth
*       p=(c mod cpl) div cppl

	 divu.w  cpl(a5),d2
	 move.w  d2,d6                  c div cpl=y index of fontchar
	 mulu.w  charh(a3),d6
	 add.w   fb_fontstarty(a3),d6   d6=font y position

	 move.w  #0,d2                  blank out lower word, then
	 swap    d2                     c mod cpl
	 divu.w  cppl(a5),d2            (c mod cpl) div cppl=plane of fontchar
	 move.w  d2,d7
	 ori.w   #16,d7              d7=plane select for "between planes" move

	 swap    d2                     (c mod cpl) mod cppl==c mod cppl
	 mulu.w  charw(a3),d2
	 add.w   fb_fontstartx(a3),d2   d2=font x position

waitcchar1 equ   *                      wait for windowmover idle
	 btst    #0,catstat+1(a0)
	 bne.s   waitcchar1

	 move.b  d7,planemode(a0)       fontchar source plane to CATSEYE
	 move.w  d0,wmdesty(a0)         destination y-position to CATSEYE
	 move.w  d1,wmdestx(a0)         destination x-position to CATSEYE
	 move.w  d2,wmsourcex(a0)       fontchar source x-position to CATSEYE
	 move.w  d6,twmsourcey(a0)      fontchar source y-position to CATSEYE
*                                       and trigger the move


	 btst    #2,highlight(a3)       underline?
	 bne.s   do_underline
	 jmp     (a4)                   back to caller of cchar

do_underline equ *
	 add     charh(a3),d0
	 subq    #1,d0                  get y pos for underline
*        move.b  lowalphaplane(a3),d1   set up to complement under 1s in color
	 move.w  alphacolor(a3),d2
*        lsl     d1,d2                  color adjusted by alpha/graphics split

waitcchar2 equ   *                      wait for character finished writing
	 btst    #0,catstat+1(a0)
	 bne.s   waitcchar2

	 move.b  d2,tcwen1(a0)          d2 is bit mask for 1s in color.
	 move.b  #10,wrr1+1(a0)         complement under the underline
	 move.w  d0,wmdesty(a0)
	 move.w  #1,twmheight(a0)       trigger the one-line underbar move

waitcchar3 equ   *                      wait for underline finished writing
	 btst    #0,catstat+1(a0)
	 bne.s   waitcchar3

	 move.b  creplrule1(a3),wrr1+1(a0)   and restore the regs (don't need to
	 move.w  charh(a3),wmheight(a0)      call setupcchar for this small stuff)

offscreenchar equ *
	 jmp     (a4)


*
*
*   cscrollup;
*
*   scrolls the screen up one line of alpha text
*
cscrollup movea.l controladdr(a5),a0
	  movea.l crtinfo(a5),a3

	  move    printy(a3),d0
	  add     charh(a3),d0                  start one line width down
	  move    printh(a3),d1                 set up window size
	  sub.w   charh(a3),d1                  one line less

waitscrollup equ  *
	  btst    #0,catstat+1(a0)
	  bne.s   waitscrollup

	  move.b  #$ff,tcwen1(a0)               ALL planes
*                                               DGL planes protected by fben1
	  move.b  #0,planemode(a0)              added 11/17/88 SFB/DEW
	  move.b  #3,wrr1+1(a0)                 repl rule to replace
	  move    printx(a3),wmsourcex(a0)      set up src loc
	  move    d0,wmsourcey(a0)
	  move    printw(a3),wmwidth(a0)
	  move    d1,wmheight(a0)
	  move    printx(a3),wmdestx(a0)        set up dest. loc
	  move    printy(a3),twmdesty(a0)       and trigger the move

* clear bottom line on screen

	  move    maxy(a5),d2
	  mulu    charh(a3),d2                  d2 = y offset of bottom line

waitscrollup2 equ *
	  btst    #0,catstat+1(a0)
	  bne.s   waitscrollup2

	  move.b  #0,wrr1+1(a0)               repl rule to clear
	  move    d2,wmdesty(a0)
	  move    charh(a3),twmheight(a0)     clear one char line ht

	  bra     waitcsetup                  restore regs for next cchar

*         rts

*
*    cscrolldown
*
*    scrolls the screen down one text line
*
cscrolldown movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3
	    move    printh(a3),d0               set up window size
	    sub.w   charh(a3),d0                one line less

waitscrolldn equ    *
	    btst    #0,catstat+1(a0)
	    bne.s   waitscrolldn

	    move.b  #$ff,tcwen1(a0)             ALL planes
*                                               DGL planes protected by fben1
	    move.b  #0,planemode(a0)            added 11/17/88 SFB/DEW
	    move.b  #3,wrr1+1(a0)               setup repl rule
	    move    printx(a3),wmsourcex(a0)     set up src origin
	    move    printy(a3),wmsourcey(a0)
	    move    printx(a3),wmdestx(a0)       setup dest. origin
	    move    charh(a3),wmdesty(a0)
	    move    d0,wmheight(a0)
	    move    printw(a3),twmwidth(a0)      and trigger the move

* clear top line on screen

waitscrolldn2 equ    *
	    btst    #0,catstat+1(a0)
	    bne.s   waitscrolldn2

	    move.b  #0,wrr1+1(a0)               repl rule to clear
	    move    printy(a3),wmdesty(a0)
	    move    charh(a3),twmheight(a0)     clear one char line ht

	    bra     waitcsetup                  restore regs for next cchar


*
*  cclear(xpos,ypos,nchars:shortint);
*    -- clears nchars starting at xpos, ypos
*    -- nchars + xpos must not exceed screenwidth
*       no range checking is done
*

cclear        equ     *
	      movea.l controladdr(a5),a0
	      movea.l crtinfo(a5),a3
	      movea.l (sp)+,a4          a4 = return address
	      move    (sp)+,d1          d4 = number of characters to clear
	      mulu    charw(a3),d1
	      move    (sp)+,d3          d3 = y to begin at
	      mulu    charh(a3),d3      d3 = y in pixels
	      move    (sp)+,d5          d5 = x
	      mulu    charw(a3),d5      d5 = x in pixels
	      move.l  a4,-(sp)          stack return address
waitcclear    equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitcclear

	      move    d3,wmdesty(a0)
cclear2       move    d5,wmdestx(a0)    setup dest. x reg
	      move    charh(a3),wmheight(a0)  setup window size
	      move    d1,wmwidth(a0)
	      move.b  #$ff,tcwen1(a0)
	      move.b  #0,wrr1+1(a0)     repl rule to clear
	      move    printx(a3),wmsourcex(a0)
	      move    printy(a3),twmsourcey(a0)
	      bsr     csetupcchar
	      rts

*
* cupdatecursor(x,y:shortint);
*

cupdatecursor equ *
	      movea.l  crtinfo(a5),a3
	      movea.l (sp)+,a4          a4 = return addr
	      move    (sp)+,d5          y in chars
	      mulu    charh(a3),d5
	      move    d5,cursy(a5)      y in pixels
	      move    (sp)+,d5          x in chars
	      mulu    charw(a3),d5
	      move    d5,cursx(a5)      x in pixels
	      bsr.s   cursoron1         turn on soft cursor

	      jmp     (a4)


cursoron1     movea.l   controladdr(a5),a0
	      move      fb_cursorx(a3),d0       save beside cursor cell
	      add       charw(a3),d0            in anticipation of save

waitcurson    equ       *
	      btst      #0,catstat+1(a0)
	      bne.s     waitcurson

	      move.b    #0,planemode(a0)
	      move      cursx(a5),wmsourcex(a0)
	      move      cursy(a5),wmsourcey(a0)
*             btst      #copy_under_cursor,flags(a3)
*             beq.s     drawcursor

	      move.b    #$ff,tcwen1(a0)         save all planes of character
	      move.b    #3,wrr1+1(a0)           sourcerule to save under cursor
	      move      d0,wmdestx(a0)
	      move      fb_cursory(a3),twmdesty(a0)

drawcursor    equ       *
*             move.b  lowalphaplane(a3),d0 set up mask for split
*             moveq   #$ff,d1             alpha and graphics
*             lsl.l   d0,d1               mask is in d1 (d0 <= 7 for CATSEYE)
*             move.w  cursorcolor(a3),d2  prepare wrrs for putting cursor
*             lsl     d0,d2               according to cursorcolor and
*             and     d2,d1               lowalphaplane. d1 is bit mask for
*                                         1s in cursor color.

	      move.w  cursorcolor(a3),d1  prepare wrrs for putting cursor

waitcurson2   equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitcurson2

	      move.b  d1,tcwen1(a0)       only LSBs of color significant in CATSEYE
	      move.b  cursreplrule1(a3),wrr1+1(a0)
	      not.b   d1
	      move.b  d1,tcwen1(a0)       now set up for 0s
	      move.b  cursreplrule0(a3),wrr1+1(a0)

	      move    wmsourcex(a0),wmdestx(a0)
	      move    wmsourcey(a0),wmdesty(a0)
	      move    fb_cursorx(a3),wmsourcex(a0)
	      move    fb_cursory(a3),twmsourcey(a0)

*               don't need to setupcchar, as cupdatecursor never called BEFORE
*               cchar, except in cbdscrllr/l, which do restore themselves

	      rts


cursoroff     equ     *               disable cursor
	      movea.l   controladdr(a5),a0
	      movea.l   crtinfo(a5),a3
	      move      fb_cursorx(a3),d0       was saved next to cursor cell
	      add       charw(a3),d0            prepare for probable restore

waitcursoff   equ       *
	      btst      #0,catstat+1(a0)
	      bne.s     waitcursoff

	      move.b    #0,planemode(a0)
*             btst      #copy_under_cursor,flags(a3)
*             beq.s     reversecursor

	      move.b    #$ff,tcwen1(a0)         restore all planes of character
	      move.b    #3,wrr1+1(a0)           sourcerule to restore character
	      move      d0,wmsourcex(a0)
	      move      fb_cursory(a3),wmsourcey(a0)
	      move      cursx(a5),wmdestx(a0)
	      move      cursy(a5),twmdesty(a0)
	      bra       csetupcchar             and prepare for cchar

reversecursor equ       *
*             move.b  lowalphaplane(a3),d0 set up mask for split
*             move.b  #$ff,d1           alpha and graphics
*             lsl.l   d0,d1             mask is in d1 (d0 <= 7 for CATSEYE)
*             move.w  cursorcolor(a3),d2  prepare wrrs for putting cursor
*             lsl     d0,d2             according to cursorcolor and
*             and     d2,d1             lowalphaplane. d1 is bit mask for
*             move.b  d1,tcwen1(a0)     1s in cursorcolor. 11/17/88 SFB/DEW
*             move.w  cursreplrule1(a3),wrr1(a0)
*             not.w   d1
*             move.b  d1,tcwen1(a0)     now set up for 0s. 11/17/88 SFB/DEW
*             move.w  cursreplrule0(a3),wrr1(a0)
*
*             move      cursx(a5),wmdestx(a0)
*             move      cursy(a5),wmdesty(a0)
*             move      fb_cursorx(a3),wmsourcex(a0)
*             move      fb_cursory(a3),twmsourcey(a0)

*             rts

cshiftleft    equ     *
	      movea.l crtinfo(a5),a3
	      move    printx(a3),d1     destx for left shift
	      move    charw(a3),d0      sourcex for left shift
	      add     d1,d0

cshift1       equ     *
	      movea.l controladdr(a5),a0
	      move    printw(a3),d2     calculate width of lastline in pixels
	      move    charw(a3),d3
	      mulu    #8,d3             lastline ends 8 from right edge
	      sub     d3,d2             width of last line
	      move    printy(a3),d3     find position of lastline
	      add     printh(a3),d3


waitcshift    equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitcshift

	      move.b  #$ff,tcwen1(a0)   talk to all wrrs. Added .b 11/17/88 SFB/DEW
	      move.b  #0,planemode(a0)  added 11/17/88 SFB/DEW
	      move    #3,wrr1(a0)       setup replacement rule
	      move    d0,wmsourcex(a0)
	      move    d3,wmsourcey(a0)
	      move    d2,wmwidth(a0)
	      move    charh(a3),wmheight(a0)
	      move    d1,wmdestx(a0)
	      move    d3,twmdesty(a0)   setup destination and trigger

	      bsr     waitmready
	      bsr     setupcchar        because we will do a cchar next

	      rts

cshiftright   equ     *
	      movea.l crtinfo(a5),a3
	      move    printx(a3),d0     src x location
	      move    charw(a3),d1      dest x location
	      add     d0,d1
	      bra     cshift1           now do same as shift left


*  procedure cexchange(savearea: windowp; ymin, ymax, xmin, width: shortint);

cexchange     movea.l (sp)+,a4          a4 = temp return addr
	      movea.l controladdr(a5),a0
	      movea.l crtinfo(a5),a3
	      move.w  (sp)+,d0          width of window in bytes in d0
	      move.w  (sp)+,d4          d4 = x offset in chars
	      mulu.w  charw(a3),d4      d4 = x offset in pixels
	      move.w  (sp)+,d5          d5 = ymax
	      move.w  (sp)+,d1          d1 = ymin
	      movea.l (sp)+,a1          a1 = ptr to save area
	      move.l  a4,-(sp)
	      sub.w   d1,d5
	      addq    #1,d5             d5 has # of char rows to move
	      mulu.w  charh(a3),d5      now has # of pixel rows to move
	      subi.w  #1,d5             setup for outer loop
	      mulu.w  charh(a3),d1      d1 = y offset in pixels
	      mulu.w  fbwidth(a3),d1    d1 = y address offset

	      movea.l screen(a5),a4     a4 points to frame buffer start
	      adda.l  d1,a4             now points to correct row
	      adda.l  d4,a4             do x offset into row

waitexchg     equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitexchg

	      move.b  #$ff,tcwen1(a0)   added .b 11/17/88 SFB/DEW
	      move.b  #3,prr1(a0)       setup pixel repl rule all planes
cexchg1       lsr.w   #2,d0             d0=window width in long integers
	      subq  #1,d0               setup for later looping
cexchg2       movea.l a4,a2             make a working copy
	      move.w  d0,d7             initialize inner loop
cexchg3       move.l  (a2),d6           screen to temp
	      move.l  (a1),(a2)+        save area to screen
	      move.l  d6,(a1)+          temp to save area
	      dbra    d7,cexchg3        inner loop (pixel row move)
	      adda.w  fbwidth(a3),a4    bump row pointer
	      dbra    d5,cexchg2        outer loop (row count)

	      rts


* procedure cscrollwindow( ymin, ymax, xmin, width: shortint);

cscrollwindow equ     *
	      moveq   #0,d6          set upscroll flag in d6
cscrollwindc  movea.l crtinfo(a5),a3
	      movea.l controladdr(a5),a0
	      movea.l (sp)+,a4       a4 = return addr
	      move    (sp)+,d1       d1 = width in chars
	      mulu    charw(a3),d1   d1 = width in pixels
	      move    (sp)+,d0       d0 = x offset of window in chars
	      mulu    charw(a3),d0   d0 = x offset in pixels (bytes)
	      add     printx(a3),d0  adjusted to diplayable portion of fb
	      move    (sp)+,d2       d2 = ymax
	      move    (sp)+,d3       d3 = ymin
	      sub     d3,d2          d2 has # of char rows to move
	      mulu    charh(a3),d2   now d2 has height to move
	      mulu    charh(a3),d3   d3 = y offset in bytes of origin
	      add     printy(a3),d3  adjusted to displayable portion of fb
	      tst     d6             check up/down flag
	      bne.s   cscrollwindb   and branch if dn
	      move    d3,wmdesty(a0) set ymin to dest y origin
	      add     charh(a3),d3
	      move    d3,wmsourcey(a0)     one row down is src y origin

cscrollwincom move.b  #0,planemode(a0) added 11/17/88 SFB/DEW
	      move.b  #$ff,tcwen1(a0)   added .b 11/17/88 SFB/DEW
	      move    #3,wrr1(a0)
	      move    d1,wmwidth(a0)    setup width reg
	      move    d2,wmheight(a0)   setup height reg
	      move    d0,wmsourcex(a0)  setup x coordinates
	      move    d0,twmdestx(a0)   and trigger move
	      jmp     (a4)


cscrollwindb  move    d3,wmsourcey(a0)      ymin = src y origin
	      add     charh(a3),d3
	      move    d3,wmdesty(a0)      one row down is dest y
	      bra     cscrollwincom

cscrollwinddn equ     *
	      moveq   #1,d6          set down scroll flag
	      bra     cscrollwindc    go to common code





cdbscrolll    equ     *
	      moveq   #0,d6          set left scroll flag
cdbscrollb    movea.l crtinfo(a5),a3
	      movea.l controladdr(a5),a0
	      movea.l (sp)+,a4       pickup return addr
	      move    (sp)+,d1       width in chars
	      subq    #1,d1          actual width to move is 1 less
	      mulu    charw(a3),d1   width in pixels in d1
	      move    (sp)+,d0       x offset in chars
	      mulu    charw(a3),d0   d0 = x offset in pixels
	      add     dispx(a3),d0   adjusted for displayable framebuf
	      move    (sp)+,d5       d5 = ymax
	      move    (sp)+,d3       d3 = ymin
	      sub     d3,d5
	      addq    #1,d5          d5 = # char rows to move
	      mulu    charh(a3),d5   d5 = # pixel rows to move
	      mulu    charh(a3),d3   d3 = y window start offset
	      add     dispy(a3),d3   adjusted for displayable framebuf dispx->dispy SFB 11/17/88

	      tst     d6             check left/right flag
	      bne.s   cdbscroll2     if right, skip
	      move    d0,wmdestx(a0)     if left xmin= dest x
	      add     charw(a3),d0
	      move    d0,wmsourcex(a0)     and src is 1 char to rt
cdbscrollc    move.b  #0,planemode(a0) added 11/17/88 SFB/DEW
	      move    #3,wrr1(a0)    setup repl rule
	      move    d1,wmwidth(a0)  setup width reg
	      move    d5,wmheight(a0) setup height reg
	      move    d3,wmsourcey(a0)     y is same for src and dest
	      move    d3,twmdesty(a0)   and trigger move
	      move.l  a4,-(sp)
*             rts                    finished!
*  no longer return because the assumptions made with csavecatenv
*  (which is csetupcchar) are no longer valid.
*  branch to waitcsetup to wait for the shift to finish and then branch
*  to csetupchar.
*  DEW/SFB 11/01/88
*
	      bra     waitcsetup

cdbscroll2    move    d0,wmsourcex(a0)     xmin is src x for rt move
	      add     charw(a3),d0
	      move    d0,wmdestx(a0)     dest is 1 char to rt
	      bra     cdbscrollc     goto common code





cdbscrollr    equ     *
	      moveq   #1,d6          set right shift flag
	      bra     cdbscrollb     go to common code

* procedure cprepdumpline(mybuf:windowp; size:shortint; rowstart:anyptr);
* takes the data in the frame buffer at rowstart, for size*8 bytes, and
* preps it for graphic output by creating an array of size number of bytes
* which has 1 bits where there are non-0 pixels in rowstart array, and 0 bits
* elsewhere. This is the format of PCL graphics data. The mybuf pointer
* is actually a pointer 8 bytes into a pascal string structure.
* the routine detects the last non-0 output byte, and adjusts both the
* strlen of the Pascal string, and the ASCII numeric string to that. The
* adjustment is done to minimize data transmission to printer, especially
* for RS232 printers.
* The ASCII string header looks like #27'*bxxxW' where xxx is a
* 3-digit number, which reflects the length of FOLLOWING binary data.

* called by dumpg in CATCRT - SFB/LAF Jan 26, '88

cprepdumpline equ *
	move.l  (sp)+,a0        return address
	move.l  (sp)+,a3        rowstart
	move.w  (sp)+,d0        size
	move.l  (sp),a1         outbufptr, leave on stack for later
	move.w  d0,d1           copy for adjusting strlen, etc later
	ext.l   d1              ensure MSBs are 0 for later divide
	move.l  d1,d5           keeps track of last non-zero outbuf char
	movea.l crtinfo(a5),a2  get access to crt description
	bra.s   initcharbuf     start up the process

preploop equ    *
	move.b  (a3)+,d2        prepare to test non-zero pixel
	and.b   planemask+3(a2),d2 mask out "floating" bits in pixel
	subi.b  #1,d2           will set X in CCR if (a3) is zero
	roxl.b  #1,d3           put X into output char buf LSB
	dbra    d4,preploop     do it 8 times per out char

	not.b   d3              because X was wrong sense
	move.b  d3,(a1)+        put character into outbuf
	beq.s   initcharbuf     if it wasn't empty, then
	move.w  d0,d5           keep track of last non-empty char

initcharbuf equ *
	move.w  #7,d4           8 bits per output char
	dbra    d0,preploop     n chars/line

	move.l  (sp)+,a1        recover initial outbufptr, and clr stack
	sub.w   d5,d1
	bne.s   fixstrlen       line has something on it
	moveq   #1,d1           must have min of 1 to force slew (we wish!)
fixstrlen equ   *
	move.b  d1,-8(a1)       stick correct length in strlen of outbuf
	addi.b  #7,-8(a1)       and adjust for #27'*bxxxW' header

* compute ASCII representation of d1 into longword, with trailing 'W'
	divu    #10,d1          remainder->upper word of d1
	move.w  d1,d2
	ext.l   d2              clear MSBs of d2
	divu    #10,d2          remainder->upper word of d2
	swap    d2
	rol.w   #8,d2
	clr.w   d1              clear LSBs
	swap    d1
	or.l    d2,d1
	ori.l   #'000',d1       attach ASCII numeric headers
	rol.l   #8,d1           justify for copy to outbuf
	ori.b   #'W',d1         now have 'xxxW' in longword
	move.l  d1,-4(a1)       copy to outbuf
	jmp     (a0)            and return



	end
@


56.2
log
@
pws2rcs automatic delta on Wed Jan 27 11:57:27 MST 1993
@
text
@d1 1314
@


56.1
log
@Automatic bump of revision number for PWS version 3.25
@
text
@a0 1314
	page
*
*   CATSEYE family bit-mapped alpha driver
*
*     Pascal 3.21 version by S. Bayes (SFB)
*
* Note that there are many commented-out line of source. These are usually
* enhancements that I wasn't allowed to implement. They're left in because
* they may be instructive to people who wish to make certain kinds of
* enhancements: split alpha/graphics, character micro-spacing, various
* cursor-restoration strategies, etc.
*
* The data structures in the source "CATCRT.TEXT" will give more hints as to
* what might have been. SFB
*
* 11/17/88 - many small bug fixes for unusual cases:
*       o autoscrolling characters out of plane 0 (depends on alpha color)
*         was clearing top of display (planemode probem)
*       o wrr1 was not getting set due to badly aligned word move of #$ff
*         to tcwen1. Caused debug window shifts to change colors
*       o was adding dispx instead of dispy to position (effectless bug)


	def     cscrollup,cscrolldown,cupdatecursor,cchar,cclear
	def     cbuildtable,cshiftleft,cshiftright
	def     cexchange,cscrollwindow,cursoroff
	def     cscrollwinddn,cdbscrolll,cdbscrollr,cclearall
	def     csetcolormap,csetreg,csavecatenv,crestorecatenv
	def     cromshort,cputfontchar,csetupcchar,cprepdumpline

	def setupcchar

	rorg.l 0

	refa    catseyedvr,sysdevs

	nosyms
	sprint

crtinfo         equ     catseyedvr-4
cpl             equ     crtinfo-2
cppl            equ     cpl-2
fb_fontchars    equ     cppl-2
maxy            equ     fb_fontchars-2
cursx           equ     maxy-2
cursy           equ     cursx-2
hascolor        equ     cursy-1
midres          equ     hascolor-1

controladdr     equ     sysdevs-86
screen          equ     sysdevs-90

doblit          equ     $90             {literal to set RUGCMD to blit mode}


* OFFSETS FOR CRTPARAMS

fbwidth         equ     0
fbheight        equ     fbwidth+2
dispx           equ     fbheight+2
dispy           equ     dispx+2
dispw           equ     dispy+2
disph           equ     dispw+2
printx          equ     disph+2
printy          equ     printx+2
printw          equ     printy+2
printh          equ     printw+2
offx            equ     printh+2
offy            equ     offx+2
offw            equ     offy+2
offh            equ     offw+2
charw           equ     offh+2
charh           equ     charw+2
fb_fontstartx   equ     charh+2
fb_fontstarty   equ     fb_fontstartx+2
fb_font_line_len equ    fb_fontstarty+2
fb_fontlines    equ     fb_font_line_len+2
nfontchars      equ     fb_fontlines+2
fb_cursorx      equ     nfontchars+4
fb_cursory      equ     fb_cursorx+2

set_colormap_proc equ   fb_cursory+2
planemask       equ     set_colormap_proc+8
alphacolor      equ     planemask+4
cursorcolor     equ     alphacolor+2
*lowalphaplane  equ     writeyoffset+2
*highlight      equ     lowalphaplane+1
highlight       equ     cursorcolor+2
creplrule0      equ     highlight+2
creplrule1      equ     creplrule0+1
cursreplrule0   equ     creplrule1+1
cursreplrule1   equ     cursreplrule0+1

flags           equ     cursreplrule1+1
togglealpha     equ     7       bit number
togglegraphics  equ     6       bit number
copy_under_cursor equ   5       bit number
use_fib_xy      equ     4       bit number
disable_low_ctl equ     3       bit number
disable_hi_ctl  equ     2       bit number
copy_to_abuf    equ     1       bit number

*       CATSEYE REGISTER OFFSETS (ADD CONTROL BASE ADDRESS)

IDREG           equ     $0000
INTREG          equ     $0002

CATSTAT         equ     $4800
CMSTAT          equ     $6002
VBSTAT          equ     $6040

BLANKALL        equ     $605C

OVERLAYCTL      equ     $60A2

CMINDEX         equ     $60B0
CMRED           equ     $60B2
CMGREEN         equ     $60B4
CMBLUE          equ     $60B6

PLANEMASKREG    equ     $60BA

CMAPWRITE       equ     $60F0
CMAPREAD        equ     $60F8

WMSTAT          equ     $4044

TCWEN1          equ     $4508
TCWEN2          equ     $4708
TCREN1          equ     $4504
TCREN2          equ     $4704

FBEN1           equ     $4500
FBEN2           equ     $4700

STARTMOVE       equ     $409C

RUGCMD          equ     $4206
RUGSTAT         equ     $4206

WMWIDTH         equ     $4208
WMHEIGHT        equ     $420A
WMSOURCEX       equ     $4210
WMSOURCEY       equ     $4212
WMDESTX         equ     $4214
WMDESTY         equ     $4216
LINEPATT        equ     $420C
LINETYPE        equ     $420E

TWMWIDTH        equ     $4308
TWMHEIGHT       equ     $430A
TWMSOURCEX      equ     $4310
TWMSOURCEY      equ     $4312
TWMDESTX        equ     $4314
TWMDESTY        equ     $4316
WMSTART         equ     $409C

WMCLIPLEFT      equ     $4218
WMCLIPRIGHT     equ     $421A
WMCLIPTOP       equ     $421C
WMCLIPBOTTOM    equ     $421E

PRR1            equ     $4502
WRR1            equ     $4506

PRR2            equ     $4702
WRR2            equ     $4706

PATTERNS        equ     $4400

TRR             equ     $450C

COLOR1          equ     $450E
COLOR2          equ     $470E

VB              equ     $4510

TRRCTL          equ     $4512

ACNTRL1         equ     $4514
ACNTRL2         equ     $4714

PLANEMODE       equ     $4516


* GRAPHICS ROM OFFSETS

initoffset   equ      $23            offset to initialization offset
fontoffset   equ      $3B            offset to font info offset
frameoffset  equ      $5D            offset to frame buffer reg. offset
cmapaddr     equ      $33            addr of color map (0 = monochrome)
cmapidoff    equ      $57            offset to color map id offset
cmapinitoff  equ      $3F            offset to cmap 0 init region offset
framecnt     equ      $5B            offset of number of frames
fbw          equ      $5             width of frame buffer
fbh          equ      $9             height of frame buffer
dspw         equ      $D             width of displayed frame buffer
dsph         equ      $11            height of displayed frame buffer

*
* cromshort returns a shortint from the graphics ID ROM.
* it picks up the byte at the offset, and the one 2 bytes away from
* it and composes a shortint
*
cromshort   equ      *
	    movea.l  controladdr(a5),a0
	    movea.l  (sp)+,a1           return address
	    adda.l   (sp)+,a0           offset
	    movep    0(a0),d0
	    move.w   d0,(sp)            store on stack as function value
	    jmp      (a1)

*
* csetreg sets the register which is offset from the graphics control
* address to the value
*
csetreg     equ       *
	    movea.l   controladdr(a5),a0
	    movea.l   (sp)+,a1          return address
	    move      (sp)+,d0          value
waitset     equ       *
	    btst      #0,catstat+1(a0)
	    bne.s     waitset
	    adda.l    (sp)+,a0          offset
	    move      d0,(a0)           set the register
	    jmp       (a1)

*
* cputfontchar takes a fontchardata structure from the address (dataptr) passed
* in, moves it to the phantom plane, thence to the cell for font storage
* in the framebuf. It does not restore CATSEYE registers when done.
*
cputfontchar equ      *
	    movea.l   controladdr(a5),a0
	    movea.l   crtinfo(a5),a3
	    movea.l   (sp)+,a1          return address
	    move.b    (sp)+,d1          oddbytes
	    addq      #1,d1             1+ord(oddbytes)
	    movea.l   (sp)+,a2          dataptr
	    move      (sp)+,d2          yposition
	    move      (sp)+,d0          plane number
	    move      d0,d4             in case it's negative
	    ext.l     d4
	    blt.s     charplaneready
	    move      #1,d4             generate destination plane mask
	    asl       d0,d4             single plane to enable
charplaneready equ    *
	    btst      #0,catstat+1(a0)
	    bne.s     charplaneready
	    move      d2,wmdesty(a0)    yposition
	    move      (sp)+,wmdestx(a0) xposition
	    move      #0,wmsourcex(a0)
	    move      #0,wmsourcey(a0)
	    move      charw(a3),wmwidth(a0)
	    move      charh(a3),wmheight(a0)
	    btst      #0,midres(a5)
	    bne       lccputfontc
	    btst      #1,planemask+3(a3)
	    bne.s     hrcputfontc

hrmputfontc equ       *
	    move.b    #2,fben1(a0)      disable display/enable phantom plane
	    move.b    #2,tcwen1(a0)     set rule for phantom plane only
	    move.b    #3,prr1(a0)       source rule for pixel moves
	    move.b    #1,acntrl1(a0)    set "bit-per-pixel"
	    bsr       movetophantom
	    move.b    #$11,planemode(a0) select phantom plane as move source
	    move.b    d4,tcwen1(a0)     font storage plane
	    move.b    #3,wrr1+1(a0)     set source rule
	    move.b    d4,fben1(a0)      enable only target font plane
	    move.b    #0,wmstart(a0)    trigger the move
	    bsr       waitforready
	    move.b    #0,acntrl1(a0)    set "byte-per-pixel"
	    jmp       (a1)              return

hrcputfontc equ       *
	    move.b    #0,fben1(a0)      disable display planes
	    move.b    #4,fben2(a0)      enable phantom plane
	    move.b    #4,tcwen2(a0)     set rule for phantom plane only
	    move.b    #3,prr2(a0)       source rule for pixel moves
	    move.b    #3,acntrl2(a0)    set "bit-per-pixel"/"BARC bank 2"
	    bsr       movetophantom
	    move.b    #$1a,planemode(a0) select phantom plane as move source
	    move.b    d4,tcwen1(a0)     font storage plane
	    move.b    #3,wrr1+1(a0)     set source rule
	    move.b    d4,fben1(a0)      enable only target font plane
	    move.b    #0,fben2(a0)      disable upper 3 planes
	    move.b    #0,wmstart(a0)    trigger the move
	    bsr       waitforready
	    move.b    #0,acntrl2(a0)    set "byte-per-pixel"
	    jmp       (a1)              return

lccputfontc move.b    #$20,fben1(a0)    disable non-phantom planes
	    move.b    #$80,catstat+1(a0) select phantom plane destination
	    move.b    #$20,tcwen1(a0)
	    move.b    #3,prr1(a0)       source rule for pixel moves
	    move.b    #1,acntrl1(a0)    set "bit-per-pixel"
	    bsr       movetophantom
	    move.b    #$40,catstat+1(a0) select phantom plane source
	    move.b    #$15,planemode(a0) select phantom plane as move source
	    move.b    d4,tcwen1(a0)
	    move.b    #3,wrr1+1(a0)     set source rule
	    move.b    d4,fben1(a0)      enable only target font plane
	    move.b    #0,wmstart(a0)    trigger the move
	    bsr       waitforready
	    move.b    #$0,catstat+1(a0) disable phantom access
	    move.b    #0,acntrl1(a0)    set "byte-per-pixel"
	    jmp       (a1)              return

movetophantom equ     *
* move the fontchar in datastructure pointed to by dataptr to the
* cell in phantom plane whose upper left corner is at 0,0.
* oddbytes=true implies use only every second byte (ie font is in ROM)
* some setup for this done at putfontchar

* implements    fbelement:=0;
*               k:=0;
*               for i:=0 to charh-1 do
*                begin
*                 for j:=0 to (charw-1) div 8 do
*                  begin
*                       framebuf[fbelement+j*8+ord(odd(j))]:=dataptr^[k];
*                       k:=k+ord(oddbyte);
*                  endl
*                 fbelement:=fbelement+fbwidth;
*                end;

* previous setup                        a2 dataptr
*    ditto                              d1 ord(oddbyte)+1

	    movea.l   screen(a5),a4     a4 framebuffer address
	    move      charw(a3),d6      width loop limit
	    subq      #1,d6
	    asr.w     #3,d6             d6 (charw-1) div 8
	    moveq     #0,d3             d3 indexes dataptr (k)
	    move      charh(a3),d0      d0 height loop (i)
	    subq      #1,d0             for use in dbra
iloop       equ       *
	    moveq     #0,d2       d2 pixel this scanline (like fbelement kinda)
	    moveq     #0,d5             d5 width loop (j)
jloop       equ       *
	    btst      #0,d5
	    beq.s     evenj
oddj        move.b    0(a2,d3),1(a4,d2) copy the byte
	    bra.s     finishloop
evenj       move.b    0(a2,d3),0(a4,d2) copy the byte
finishloop  add.b     d1,d3             k:=k+ord(oddbyte)+1
	    add       #8,d2             fbelement+j*8
	    addq      #1,d5
	    cmp       d5,d6
	    bge       jloop
	    adda.w    fbwidth(a3),a4    next scanline
	    dbra      d0,iloop
	    rts

*
*   cbuildtable
*
cbuildtable movea.l  controladdr(a5),a0    get pointer to ROM start
	    movea.l  crtinfo(a5),a3        crtparamrec
	    movep    initoffset(a0),d1     form pointer to init block
	    movea.l  a0,a1                  make copy of ROM start addr
	    adda     d1,a1                  a1 points to init info now
	    bsr      ginitblock             call the initialization routine
	    clr.b    hascolor(a5)
	    movep    cmapaddr(a0),d0        get color map addr
	    tst      d0
	    beq.s    cnocolor               if 0 then no color init

	    moveq    #0,d1
	    movep    cmapidoff(a0),d0       get ptr to color map id reg
	    tst      d0                     if ptr=0, then use init region 0
	    beq.s    cinitclr
	    move.b   0(a0,d0),d1            get cmap id into d1
cinitclr    and      #3,d1                  look at least sig bits
	    lsl      #2,d1
	    move.b   cmapinitoff(a0,d1.w),d2  form cmap init block addr
	    lsl      #8,d2
	    move.b   cmapinitoff+2(a0,d1.w),d2
	    movea.l  a0,a1
	    adda     d2,a1                  a1 points to cmap init block
	    bsr      ginitblock
	    st       hascolor(a5)           set color boolean
cnocolor    clr.l    screen(a5)             clear space for frame buffer addr
	    movep.w  frameoffset(a0),d0     get offset of frame buffer loc.
	    move.b   0(a0,d0),screen+1(a5)  form frame buffer addr

	    move.b   framecnt(a0),d0      d0=# of planes in system
	    beq.s    cnumplanes           if zero then read planes
	    moveq    #8,d1                else make the mask up
	    moveq    #$FF,d2
	    sub      d0,d1                d1 has shift count
	    lsr.b    d1,d2                after shift d2 has mask
	    bra.s    csetplanes           go setup planemask

cnumplanes  moveq   #0,d2
	    movea.l screen(a5),a1         addr of fb in a1
	    move.b  #$FF,(a1)             write all 1's
	    move.b  (a1),d2               get plane mask in d2
csetplanes  move.l  #0,planemask(a3)       clear MSBs, as this is full 32 bits
	    move.b  d2,3+planemask(a3)     save as plane mask
	    tst.b   hascolor(a5)           monochrome ?
	    beq.s   cnocolor2              if so then skip color map init
	    move    d2,planemaskreg(a0)    set color map mask
	    bsr     loadcmap               load the color map
	    st       hascolor(a5)          set color boolean


cnocolor2   moveq    #0,d0      {we don't clear framebuf here, as the graphics
*                                ID ROM will do it anyway on CATSEYE. SFB}
	    move     d0,dispx(a3)
	    move     d0,printx(a3)
	    move     d0,dispy(a3)
	    move     d0,printy(a3)
	    movep.w  fbw(a0),d2             get width from ROM
	    move     d2,fbwidth(a3)
	    movep.w  dspw(a0),d2            set visible widthas window width SFB
	    movep.w  fbh(a0),d2             get height from ROM
	    move     d2,fbheight(a3)
	    movep.w  dspw(a0),d2
	    cmp      #1024,d2
	    beq.s    setuplcc

setuphrx    equ      *
	    move     #1280,offx(a3)
	    move     #0,offy(a3)
	    move     #768,offw(a3)
	    move     #1024,offh(a3)
	    bra.s    donesetupoff

setuplcc    equ      *
	    move     #0,offx(a3)
	    move     #768,offy(a3)
	    move     #1024,offw(a3)
	    move     #256,offh(a3)

donesetupoff equ     *
	    move     d2,dispw(a3)
	    move     d2,printw(a3)
	    movep.w  dsph(a0),d2
	    move     d2,disph(a3)
*           sub      charh(a3),d2       would like to do this now, but can't,
*           move     d2,printh(a3)      as we haven't sorted out the font yet


cclrtst     btst     #0,catstat+1(a0)
	    bne      cclrtst
cfbclrdone  move.b   #$3,prr1(a0)           setup pixel repl rule

*           bsr      catseyedvr_loadfonts   set up all 3 fonts @@ 128 char each
*                                           We'll do this from Pascal
	    rts
*
*   misc utilities for initialization
*
*
loadcmap    lea     cmaptable,a1          initialize the color map
	    moveq   #0,d1                 clear some registers
	    move.l  d1,d2
	    move.l  d1,d3
	    move.l  d1,d4
cmaploop1   move.b  (a1)+,d2              get rgb values in d2-d4
	    move.b  (a1)+,d3
	    move.b  (a1)+,d4
	    bsr     cmapenter             stuff the color map entry
	    addq    #1,d1                 bump cmap pointer value
	    cmp     #16,d1                have we done 16 yet?
	    bne     cmaploop1             if not then continue
	    moveq   #-1,d2                set entries 16-255 to white
	    move.l  d2,d3
	    move.l  d2,d4
cmaploop2   bsr     cmapenter
	    addq    #1,d1
	    cmp     #256,d1                done with cmap init?
	    bne     cmaploop2
	    rts

csetcolormap equ    *                   callable from pascal
	    movea.l controladdr(a5),a0
	    move.l  (sp)+,d1            colormap index parameter
	    move.l  (sp)+,d2            red value
	    move.l  (sp)+,d3            green value
	    move.l  (sp)+,d4            blue value

cmapenter   btst    #2,cmstat+1(a0)       check for color map busy
	    bne     cmapenter             loop till bit is clear
	    move    d1,cmindex(a0)        set pointer register
	    move    d2,cmred(a0)          stuff the rgb regs
	    move    d3,cmgreen(a0)
	    move    d4,cmblue(a0)
	    move    d5,cmapwrite(a0)      hit the write trigger
	    rts                           done with cmap entry write
*
*
*
ginitblock  moveq    #0,d1                  clear some regs
	    moveq    #0,d0
	    move.b   2(a1),d0               get word count to initialize
	    movep    4(a1),d1               form destination offset
	    add.l    a0,d1                  d1 points to dest addr
	    lea      8(a1),a2               a2 points to first data byte
	    movea.l  d1,a4                  a4 points to destination
	    btst     #0,(a1)                is this a bit test block?
	    bne.s    ginitbtst              if so go handle it
ginitloop   movep    0(a2),d1                form a data word in d1
	    move.w   d1,(a4)+               move data to the destination addr
	    btst     #6,(a1)                increment data pointer
	    bne.s    ginit1                 based on control byte
	    addq     #4,a2
ginit1      dbra     d0,ginitloop           loop till word count exhausted
	    btst     #7,(a1)                was this last block?
	    bne.s    ginitdone              yes -- go return
	    btst     #6,(a1)                adjust data pointer
	    beq.s    ginit2                 to point to next init block
ginit3      addq     #4,a2
ginit2      movea.l  a2,a1                  a1 points to new init block
	    bra      ginitblock             do the initialize
ginitdone   rts

ginitbtst   moveq    #0,d2                  handle bit test blocks here
	    move.b   2(a2),d2               d2 = bit # to test
ginittst2   move     (a4),d3                d3 = data word to test
	    btst     #0,(a2)                check for sense of test
	    bne.s    ginittst3              comp if waiting for 0
	    not      d3
ginittst3   btst     d2,d3                  check the bit
	    beq      ginittst2              if not 1 then loop
	    btst     #7,(a1)                was this last block?
	    bne      ginitdone              if so then return
	    bra      ginit3                 else do next block
*
*
cmaptable   equ      *                      initial color map contents (r,g,b)
	    dc.b     0,0,0                  0
	    dc.b     255,255,255            1
	    dc.b     255,0,0                2
	    dc.b     255,255,0              3
	    dc.b     0,255,0                4
	    dc.b     0,255,255              5
	    dc.b     0,0,255                6
	    dc.b     255,0,255              7
	    dc.b     0,0,0                  8
	    dc.b     204,187,51             9
	    dc.b     51,170,119             10
	    dc.b     136,102,170            11
	    dc.b     204,68,102             12
	    dc.b     255,102,51             13
	    dc.b     255,119,0              14
	    dc.b     221,136,68             15

*
*  waitforready:  wait till window mover done
*
*
waitforready equ *
	movea.l controladdr(a5),a0
waitmready      equ     *
	btst    #0,catstat+1(a0)
	bne.s   waitmready
	rts
*
*
* csavecatenv: preserve CATSEYE registers used by alpha driver
* and set up for future cchar and cupdatecursor calls (optimization).
* Register contents are stored in CATSEYEDVR stack frame buffer
* allocated for that purpose, whose address is passed in.
*

csavecatenv equ *
	    movea.l (sp)+,a2            save return addr
	    movea.l (sp)+,a1            buffer address
	    move.l  a2,-(sp)            prepare for regular rts

	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3      get crtparams ptr
	    lea     rugcmd(a0),a2       address of first catseye reg to save

waitsave    equ     *                   wait for registers idle
	    btst    #0,catstat+1(a0)
	    bne.s   waitsave

	    move.w  (a2)+,(a1)+         RUGCMD  (not on longword boundary)
	    move.l  (a2)+,(a1)+         WMWIDTH & WMHEIGHT (now in longwords)
*           move.l  (a2)+,(a1)+         LINEPATT & LINETYPE (not saved)
	    addq    #4,a2               instead, skip linepatt & linetype
	    move.l  (a2)+,(a1)+         WMSOURCEX & WMSOURCEY
	    move.l  (a2)+,(a1)+         WMDESTX & WMDESTY
	    move.w  fben1(a0),(a1)+     get other regs
*
*                       the tcwen and tcren registers provide floating
*                       bits when read if all 8 planes are not loaded.
*                       Because writing these registers with more
*                       than one bit set will cause h/w problems, need
*                       to 'and' out the floating  bits. 6/2/88 SFB/DEW
*
	    move.w  tcren1(a0),d0
	    move.w  planemask+2(a3),d2    d2 will hold the adjusted plane
	    lsl.w   #8,d2               mask for the tcwen register.
	    and.w   d2,d0
	    move.w  d0,(a1)+
*
	    moveq   #7,d0
	    moveq   #1,d1               select plane 0
getwrr      equ     *                   preserve all 8 wrrs
	    move.b  d1,tcren1(a0)       address next plane wrr
	    move.b  wrr1+1(a0),(a1)+    and save wrr
	    asl     #1,d1               select next plane
	    dbra    d0,getwrr
*
	    move.w  tcwen1(a0),d0       6/2/88 SFB/DEW (see comment above)
	    and.w   d2,d0
	    move.w  d0,(a1)+
*
	    move.w  vb(a0),(a1)+
	    move.w  trrctl(a0),(a1)+   added save of TRRCTL 5/24/88 SFB/DEW
	    move.w  planemode(a0),(a1)

*           now drop through and set up driver state of CATSEYE

* sets up CATSEYE regs to the state we mostly maintain during driver execution,
* ready for a cchar call (as it's the most common call)
* At entry to setupcchar, a0=controladdr(a5), a3=crtinfo(a5), a5=global ptr,
* and return address is on stack

setupcchar  equ     *                   callable from elsewhere in this code
	    lea     rugcmd(a0),a2       set up regs for cchar & cupdatecursor

	    move.w  #doblit,(a2)+       RUGCMD
	    move.l  charw(a3),(a2)+     WMWIDTH & WMHEIGHT

*           move.b  lowalphaplane(a3),d0 set up fben1 mask for split
*           moveq   #$ff,d1             alpha and graphics
*           lsl.l   d0,d1               mask is in d1 (d0 <= 7 for CATSEYE)
*           move.b  d1,fben1(a0)

	    move.b  #$ff,fben1(a0)

	    move.w  alphacolor(a3),d1   prepare wrrs for putting characters

*           move.w  alphacolor(a3),d2   prepare wrrs for putting characters
*           lsl     d0,d2               according to alphacolor and
*           and     d2,d1               lowalphaplane. d1 is bit mask for

	    move.b  d1,tcwen1(a0)       for 1s in color.
	    move.b  creplrule1(a3),wrr1+1(a0)
	    not     d1
	    move.b  d1,tcwen1(a0)       now set up for 0s
	    move.b  creplrule0(a3),wrr1+1(a0)
	    move.b  #0,vb(a0)
	    move.b  #0,trrctl(a0)       added set not TRRCTL. SFB/DEW 5/24/88
	    rts

*
* csetupcchar sets up window mover params without csavecatenv. Meant for
* call from Pascal when color or inverse video enhancement enable change.
*

csetupcchar equ     *
	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3      get crtparams ptr

waitcsetup  equ     *                   wait for registers idle
	    btst    #0,catstat+1(a0)
	    bne.s   waitcsetup

	    bra     setupcchar

*
*
* restorecatenv: restore CATSEYE registers used by alpha driver.
* Register contents were stored in CATSEYEDVR stack frame buffer
* allocated for that purpose, whose address is passed in.
*

crestorecatenv equ  *
	    movea.l (sp)+,a2            save return addr
	    movea.l (sp)+,a1            buffer address
	    move.l  a2,-(sp)            prepare for regular rts
	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3      get crtparams ptr
	    lea     rugcmd(a0),a2       address of first catseye reg to save
waitrestore equ   *                     wait for registers idle
	    btst    #0,catstat+1(a0)
	    bne.s   waitrestore

	    move.w  (a1)+,(a2)+         RUGCMD  (not on longword boundary)
	    move.l  (a1)+,(a2)+         WMWIDTH & WMHEIGHT (now in longwords)
*           move.l  (a1)+,(a2)+         LINEPATT & LINETYPE (not saved)
	    addq    #4,a2               instead, skip linepatt & linetype
	    move.l  (a1)+,(a2)+         WMSOURCEX & WMSOURCEY
	    move.l  (a1)+,(a2)+         WMDESTX & WMDESTY
	    move.w  (a1)+,fben1(a0)     restore other regs
	    move.w  (a1)+,tcren1(a0)
	    moveq   #7,d0
	    moveq   #1,d1               select plane 0
setwrr      equ     *                   restore all 8 wrrs
	    move.b  d1,tcwen1(a0)       address next plane wrr
	    move.b  (a1)+,wrr1+1(a0)    and restore wrr
	    asl     #1,d1               select next plane
	    dbra    d0,setwrr
	    move.w  (a1)+,tcwen1(a0)
	    move.w  (a1)+,vb(a0)
	    move.w  (a1)+,trrctl(a0)   added restore of TRRCTL 5/24/88 SFB/DEW
	    move.w  (a1),planemode(a0)
	    rts

*
*
*  procedure cclearall: clears all of visible area except typeahead
*
cclearall   equ     *
	    movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3              crtparamrec
cclralltst  btst    #0,catstat+1(a0)
	    bne     cclralltst
	    move.b  #$ff,tcwen1(a0)             to clear on all planes 11/18/88 SFB
	    move    #0,wrr1(a0)                 set repl rule
	    move    dispx(a3),wmsourcex(a0)     setup x,y
	    move    dispy(a3),wmsourcey(a0)
	    move    dispx(a3),wmdestx(a0)
	    move    dispy(a3),wmdesty(a0)
	    move    dispw(a3),wmwidth(a0)       set width, height
	    move    disph(a3),twmheight(a0)    and do move

*           don't need to set up for cchar, as cclearall can't be called in
*           same invocation of driver as cchar

	    rts

*
*
*   procedure cchar(ord(char),x,y:shortint);
*
*       note that we place the character in one window move in cchar,
*       because setupcchar or csetupcchar has already set up all windowmover replacement
*       rules on a per plane basis to move 1s and 0s where necessary, as well as
*       setting up the move height and width to character cell size,
*       and this is a run-on sentence   :-)

cchar    movea.l (sp)+,a4               return address
	 movea.l controladdr(a5),a0     CATSEYE registers
	 movea.l crtinfo(a5),a3         crtparamrec

	 move.w  (sp)+,d0               d0 = dest y char offset
	 mulu    charh(a3),d0           d0 = pixel row offset
	 add.w   printy(a3),d0          adjust to display window
*        add.w   writeyoffset(a3),d0    pixel y offset of chars
*                                       d0 is y-destination

	 move.w  (sp)+,d1               d1 = x char offset
	 mulu.w  charw(a3),d1           d1 = pixel column offset
	 add.w   printx(a3),d1          adjust to display window
*        add.w   writexoffset(a3),d1    pixel x offset of chars
*                                       d1 is x-destination

	 moveq   #0,d2                  clear longword for divide
	 move.w  (sp)+,d2               character index
	 cmp.w   fb_fontchars(a5),d2    see if char is in frame buf, or RAM
	 bge     offscreenchar

*       font character is somewhere in frame buffer
*       calculate x,y,plane of fontchar
*       cppl and cpl precomputed at driver init time, global to catseyedvr
*       cppl=characters in one fontline rectangle 1 plane deep (characters per
*          plane line)
*       cpl=characters in one fontline rectangle n planes deep (characters per
*          line)
*       x=fb_fontstartx+(c mod cppl)*charw
*        =fb_fontstartx+((c mod cpl) mod cppl)*charw
*         (because cpl=n*cppl, and the code works out shorter this way)
*       y=fonty+(c div cpl)*fonth
*       p=(c mod cpl) div cppl

	 divu.w  cpl(a5),d2
	 move.w  d2,d6                  c div cpl=y index of fontchar
	 mulu.w  charh(a3),d6
	 add.w   fb_fontstarty(a3),d6   d6=font y position

	 move.w  #0,d2                  blank out lower word, then
	 swap    d2                     c mod cpl
	 divu.w  cppl(a5),d2            (c mod cpl) div cppl=plane of fontchar
	 move.w  d2,d7
	 ori.w   #16,d7              d7=plane select for "between planes" move

	 swap    d2                     (c mod cpl) mod cppl==c mod cppl
	 mulu.w  charw(a3),d2
	 add.w   fb_fontstartx(a3),d2   d2=font x position

waitcchar1 equ   *                      wait for windowmover idle
	 btst    #0,catstat+1(a0)
	 bne.s   waitcchar1

	 move.b  d7,planemode(a0)       fontchar source plane to CATSEYE
	 move.w  d0,wmdesty(a0)         destination y-position to CATSEYE
	 move.w  d1,wmdestx(a0)         destination x-position to CATSEYE
	 move.w  d2,wmsourcex(a0)       fontchar source x-position to CATSEYE
	 move.w  d6,twmsourcey(a0)      fontchar source y-position to CATSEYE
*                                       and trigger the move


	 btst    #2,highlight(a3)       underline?
	 bne.s   do_underline
	 jmp     (a4)                   back to caller of cchar

do_underline equ *
	 add     charh(a3),d0
	 subq    #1,d0                  get y pos for underline
*        move.b  lowalphaplane(a3),d1   set up to complement under 1s in color
	 move.w  alphacolor(a3),d2
*        lsl     d1,d2                  color adjusted by alpha/graphics split

waitcchar2 equ   *                      wait for character finished writing
	 btst    #0,catstat+1(a0)
	 bne.s   waitcchar2

	 move.b  d2,tcwen1(a0)          d2 is bit mask for 1s in color.
	 move.b  #10,wrr1+1(a0)         complement under the underline
	 move.w  d0,wmdesty(a0)
	 move.w  #1,twmheight(a0)       trigger the one-line underbar move

waitcchar3 equ   *                      wait for underline finished writing
	 btst    #0,catstat+1(a0)
	 bne.s   waitcchar3

	 move.b  creplrule1(a3),wrr1+1(a0)   and restore the regs (don't need to
	 move.w  charh(a3),wmheight(a0)      call setupcchar for this small stuff)

offscreenchar equ *
	 jmp     (a4)


*
*
*   cscrollup;
*
*   scrolls the screen up one line of alpha text
*
cscrollup movea.l controladdr(a5),a0
	  movea.l crtinfo(a5),a3

	  move    printy(a3),d0
	  add     charh(a3),d0                  start one line width down
	  move    printh(a3),d1                 set up window size
	  sub.w   charh(a3),d1                  one line less

waitscrollup equ  *
	  btst    #0,catstat+1(a0)
	  bne.s   waitscrollup

	  move.b  #$ff,tcwen1(a0)               ALL planes
*                                               DGL planes protected by fben1
	  move.b  #0,planemode(a0)              added 11/17/88 SFB/DEW
	  move.b  #3,wrr1+1(a0)                 repl rule to replace
	  move    printx(a3),wmsourcex(a0)      set up src loc
	  move    d0,wmsourcey(a0)
	  move    printw(a3),wmwidth(a0)
	  move    d1,wmheight(a0)
	  move    printx(a3),wmdestx(a0)        set up dest. loc
	  move    printy(a3),twmdesty(a0)       and trigger the move

* clear bottom line on screen

	  move    maxy(a5),d2
	  mulu    charh(a3),d2                  d2 = y offset of bottom line

waitscrollup2 equ *
	  btst    #0,catstat+1(a0)
	  bne.s   waitscrollup2

	  move.b  #0,wrr1+1(a0)               repl rule to clear
	  move    d2,wmdesty(a0)
	  move    charh(a3),twmheight(a0)     clear one char line ht

	  bra     waitcsetup                  restore regs for next cchar

*         rts

*
*    cscrolldown
*
*    scrolls the screen down one text line
*
cscrolldown movea.l controladdr(a5),a0
	    movea.l crtinfo(a5),a3
	    move    printh(a3),d0               set up window size
	    sub.w   charh(a3),d0                one line less

waitscrolldn equ    *
	    btst    #0,catstat+1(a0)
	    bne.s   waitscrolldn

	    move.b  #$ff,tcwen1(a0)             ALL planes
*                                               DGL planes protected by fben1
	    move.b  #0,planemode(a0)            added 11/17/88 SFB/DEW
	    move.b  #3,wrr1+1(a0)               setup repl rule
	    move    printx(a3),wmsourcex(a0)     set up src origin
	    move    printy(a3),wmsourcey(a0)
	    move    printx(a3),wmdestx(a0)       setup dest. origin
	    move    charh(a3),wmdesty(a0)
	    move    d0,wmheight(a0)
	    move    printw(a3),twmwidth(a0)      and trigger the move

* clear top line on screen

waitscrolldn2 equ    *
	    btst    #0,catstat+1(a0)
	    bne.s   waitscrolldn2

	    move.b  #0,wrr1+1(a0)               repl rule to clear
	    move    printy(a3),wmdesty(a0)
	    move    charh(a3),twmheight(a0)     clear one char line ht

	    bra     waitcsetup                  restore regs for next cchar


*
*  cclear(xpos,ypos,nchars:shortint);
*    -- clears nchars starting at xpos, ypos
*    -- nchars + xpos must not exceed screenwidth
*       no range checking is done
*

cclear        equ     *
	      movea.l controladdr(a5),a0
	      movea.l crtinfo(a5),a3
	      movea.l (sp)+,a4          a4 = return address
	      move    (sp)+,d1          d4 = number of characters to clear
	      mulu    charw(a3),d1
	      move    (sp)+,d3          d3 = y to begin at
	      mulu    charh(a3),d3      d3 = y in pixels
	      move    (sp)+,d5          d5 = x
	      mulu    charw(a3),d5      d5 = x in pixels
	      move.l  a4,-(sp)          stack return address
waitcclear    equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitcclear

	      move    d3,wmdesty(a0)
cclear2       move    d5,wmdestx(a0)    setup dest. x reg
	      move    charh(a3),wmheight(a0)  setup window size
	      move    d1,wmwidth(a0)
	      move.b  #$ff,tcwen1(a0)
	      move.b  #0,wrr1+1(a0)     repl rule to clear
	      move    printx(a3),wmsourcex(a0)
	      move    printy(a3),twmsourcey(a0)
	      bsr     csetupcchar
	      rts

*
* cupdatecursor(x,y:shortint);
*

cupdatecursor equ *
	      movea.l  crtinfo(a5),a3
	      movea.l (sp)+,a4          a4 = return addr
	      move    (sp)+,d5          y in chars
	      mulu    charh(a3),d5
	      move    d5,cursy(a5)      y in pixels
	      move    (sp)+,d5          x in chars
	      mulu    charw(a3),d5
	      move    d5,cursx(a5)      x in pixels
	      bsr.s   cursoron1         turn on soft cursor

	      jmp     (a4)


cursoron1     movea.l   controladdr(a5),a0
	      move      fb_cursorx(a3),d0       save beside cursor cell
	      add       charw(a3),d0            in anticipation of save

waitcurson    equ       *
	      btst      #0,catstat+1(a0)
	      bne.s     waitcurson

	      move.b    #0,planemode(a0)
	      move      cursx(a5),wmsourcex(a0)
	      move      cursy(a5),wmsourcey(a0)
*             btst      #copy_under_cursor,flags(a3)
*             beq.s     drawcursor

	      move.b    #$ff,tcwen1(a0)         save all planes of character
	      move.b    #3,wrr1+1(a0)           sourcerule to save under cursor
	      move      d0,wmdestx(a0)
	      move      fb_cursory(a3),twmdesty(a0)

drawcursor    equ       *
*             move.b  lowalphaplane(a3),d0 set up mask for split
*             moveq   #$ff,d1             alpha and graphics
*             lsl.l   d0,d1               mask is in d1 (d0 <= 7 for CATSEYE)
*             move.w  cursorcolor(a3),d2  prepare wrrs for putting cursor
*             lsl     d0,d2               according to cursorcolor and
*             and     d2,d1               lowalphaplane. d1 is bit mask for
*                                         1s in cursor color.

	      move.w  cursorcolor(a3),d1  prepare wrrs for putting cursor

waitcurson2   equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitcurson2

	      move.b  d1,tcwen1(a0)       only LSBs of color significant in CATSEYE
	      move.b  cursreplrule1(a3),wrr1+1(a0)
	      not.b   d1
	      move.b  d1,tcwen1(a0)       now set up for 0s
	      move.b  cursreplrule0(a3),wrr1+1(a0)

	      move    wmsourcex(a0),wmdestx(a0)
	      move    wmsourcey(a0),wmdesty(a0)
	      move    fb_cursorx(a3),wmsourcex(a0)
	      move    fb_cursory(a3),twmsourcey(a0)

*               don't need to setupcchar, as cupdatecursor never called BEFORE
*               cchar, except in cbdscrllr/l, which do restore themselves

	      rts


cursoroff     equ     *               disable cursor
	      movea.l   controladdr(a5),a0
	      movea.l   crtinfo(a5),a3
	      move      fb_cursorx(a3),d0       was saved next to cursor cell
	      add       charw(a3),d0            prepare for probable restore

waitcursoff   equ       *
	      btst      #0,catstat+1(a0)
	      bne.s     waitcursoff

	      move.b    #0,planemode(a0)
*             btst      #copy_under_cursor,flags(a3)
*             beq.s     reversecursor

	      move.b    #$ff,tcwen1(a0)         restore all planes of character
	      move.b    #3,wrr1+1(a0)           sourcerule to restore character
	      move      d0,wmsourcex(a0)
	      move      fb_cursory(a3),wmsourcey(a0)
	      move      cursx(a5),wmdestx(a0)
	      move      cursy(a5),twmdesty(a0)
	      bra       csetupcchar             and prepare for cchar

reversecursor equ       *
*             move.b  lowalphaplane(a3),d0 set up mask for split
*             move.b  #$ff,d1           alpha and graphics
*             lsl.l   d0,d1             mask is in d1 (d0 <= 7 for CATSEYE)
*             move.w  cursorcolor(a3),d2  prepare wrrs for putting cursor
*             lsl     d0,d2             according to cursorcolor and
*             and     d2,d1             lowalphaplane. d1 is bit mask for
*             move.b  d1,tcwen1(a0)     1s in cursorcolor. 11/17/88 SFB/DEW
*             move.w  cursreplrule1(a3),wrr1(a0)
*             not.w   d1
*             move.b  d1,tcwen1(a0)     now set up for 0s. 11/17/88 SFB/DEW
*             move.w  cursreplrule0(a3),wrr1(a0)
*
*             move      cursx(a5),wmdestx(a0)
*             move      cursy(a5),wmdesty(a0)
*             move      fb_cursorx(a3),wmsourcex(a0)
*             move      fb_cursory(a3),twmsourcey(a0)

*             rts

cshiftleft    equ     *
	      movea.l crtinfo(a5),a3
	      move    printx(a3),d1     destx for left shift
	      move    charw(a3),d0      sourcex for left shift
	      add     d1,d0

cshift1       equ     *
	      movea.l controladdr(a5),a0
	      move    printw(a3),d2     calculate width of lastline in pixels
	      move    charw(a3),d3
	      mulu    #8,d3             lastline ends 8 from right edge
	      sub     d3,d2             width of last line
	      move    printy(a3),d3     find position of lastline
	      add     printh(a3),d3


waitcshift    equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitcshift

	      move.b  #$ff,tcwen1(a0)   talk to all wrrs. Added .b 11/17/88 SFB/DEW
	      move.b  #0,planemode(a0)  added 11/17/88 SFB/DEW
	      move    #3,wrr1(a0)       setup replacement rule
	      move    d0,wmsourcex(a0)
	      move    d3,wmsourcey(a0)
	      move    d2,wmwidth(a0)
	      move    charh(a3),wmheight(a0)
	      move    d1,wmdestx(a0)
	      move    d3,twmdesty(a0)   setup destination and trigger

	      bsr     waitmready
	      bsr     setupcchar        because we will do a cchar next

	      rts

cshiftright   equ     *
	      movea.l crtinfo(a5),a3
	      move    printx(a3),d0     src x location
	      move    charw(a3),d1      dest x location
	      add     d0,d1
	      bra     cshift1           now do same as shift left


*  procedure cexchange(savearea: windowp; ymin, ymax, xmin, width: shortint);

cexchange     movea.l (sp)+,a4          a4 = temp return addr
	      movea.l controladdr(a5),a0
	      movea.l crtinfo(a5),a3
	      move.w  (sp)+,d0          width of window in bytes in d0
	      move.w  (sp)+,d4          d4 = x offset in chars
	      mulu.w  charw(a3),d4      d4 = x offset in pixels
	      move.w  (sp)+,d5          d5 = ymax
	      move.w  (sp)+,d1          d1 = ymin
	      movea.l (sp)+,a1          a1 = ptr to save area
	      move.l  a4,-(sp)
	      sub.w   d1,d5
	      addq    #1,d5             d5 has # of char rows to move
	      mulu.w  charh(a3),d5      now has # of pixel rows to move
	      subi.w  #1,d5             setup for outer loop
	      mulu.w  charh(a3),d1      d1 = y offset in pixels
	      mulu.w  fbwidth(a3),d1    d1 = y address offset

	      movea.l screen(a5),a4     a4 points to frame buffer start
	      adda.l  d1,a4             now points to correct row
	      adda.l  d4,a4             do x offset into row

waitexchg     equ     *
	      btst    #0,catstat+1(a0)
	      bne.s   waitexchg

	      move.b  #$ff,tcwen1(a0)   added .b 11/17/88 SFB/DEW
	      move.b  #3,prr1(a0)       setup pixel repl rule all planes
cexchg1       lsr.w   #2,d0             d0=window width in long integers
	      subq  #1,d0               setup for later looping
cexchg2       movea.l a4,a2             make a working copy
	      move.w  d0,d7             initialize inner loop
cexchg3       move.l  (a2),d6           screen to temp
	      move.l  (a1),(a2)+        save area to screen
	      move.l  d6,(a1)+          temp to save area
	      dbra    d7,cexchg3        inner loop (pixel row move)
	      adda.w  fbwidth(a3),a4    bump row pointer
	      dbra    d5,cexchg2        outer loop (row count)

	      rts


* procedure cscrollwindow( ymin, ymax, xmin, width: shortint);

cscrollwindow equ     *
	      moveq   #0,d6          set upscroll flag in d6
cscrollwindc  movea.l crtinfo(a5),a3
	      movea.l controladdr(a5),a0
	      movea.l (sp)+,a4       a4 = return addr
	      move    (sp)+,d1       d1 = width in chars
	      mulu    charw(a3),d1   d1 = width in pixels
	      move    (sp)+,d0       d0 = x offset of window in chars
	      mulu    charw(a3),d0   d0 = x offset in pixels (bytes)
	      add     printx(a3),d0  adjusted to diplayable portion of fb
	      move    (sp)+,d2       d2 = ymax
	      move    (sp)+,d3       d3 = ymin
	      sub     d3,d2          d2 has # of char rows to move
	      mulu    charh(a3),d2   now d2 has height to move
	      mulu    charh(a3),d3   d3 = y offset in bytes of origin
	      add     printy(a3),d3  adjusted to displayable portion of fb
	      tst     d6             check up/down flag
	      bne.s   cscrollwindb   and branch if dn
	      move    d3,wmdesty(a0) set ymin to dest y origin
	      add     charh(a3),d3
	      move    d3,wmsourcey(a0)     one row down is src y origin

cscrollwincom move.b  #0,planemode(a0) added 11/17/88 SFB/DEW
	      move.b  #$ff,tcwen1(a0)   added .b 11/17/88 SFB/DEW
	      move    #3,wrr1(a0)
	      move    d1,wmwidth(a0)    setup width reg
	      move    d2,wmheight(a0)   setup height reg
	      move    d0,wmsourcex(a0)  setup x coordinates
	      move    d0,twmdestx(a0)   and trigger move
	      jmp     (a4)


cscrollwindb  move    d3,wmsourcey(a0)      ymin = src y origin
	      add     charh(a3),d3
	      move    d3,wmdesty(a0)      one row down is dest y
	      bra     cscrollwincom

cscrollwinddn equ     *
	      moveq   #1,d6          set down scroll flag
	      bra     cscrollwindc    go to common code





cdbscrolll    equ     *
	      moveq   #0,d6          set left scroll flag
cdbscrollb    movea.l crtinfo(a5),a3
	      movea.l controladdr(a5),a0
	      movea.l (sp)+,a4       pickup return addr
	      move    (sp)+,d1       width in chars
	      subq    #1,d1          actual width to move is 1 less
	      mulu    charw(a3),d1   width in pixels in d1
	      move    (sp)+,d0       x offset in chars
	      mulu    charw(a3),d0   d0 = x offset in pixels
	      add     dispx(a3),d0   adjusted for displayable framebuf
	      move    (sp)+,d5       d5 = ymax
	      move    (sp)+,d3       d3 = ymin
	      sub     d3,d5
	      addq    #1,d5          d5 = # char rows to move
	      mulu    charh(a3),d5   d5 = # pixel rows to move
	      mulu    charh(a3),d3   d3 = y window start offset
	      add     dispy(a3),d3   adjusted for displayable framebuf dispx->dispy SFB 11/17/88

	      tst     d6             check left/right flag
	      bne.s   cdbscroll2     if right, skip
	      move    d0,wmdestx(a0)     if left xmin= dest x
	      add     charw(a3),d0
	      move    d0,wmsourcex(a0)     and src is 1 char to rt
cdbscrollc    move.b  #0,planemode(a0) added 11/17/88 SFB/DEW
	      move    #3,wrr1(a0)    setup repl rule
	      move    d1,wmwidth(a0)  setup width reg
	      move    d5,wmheight(a0) setup height reg
	      move    d3,wmsourcey(a0)     y is same for src and dest
	      move    d3,twmdesty(a0)   and trigger move
	      move.l  a4,-(sp)
*             rts                    finished!
*  no longer return because the assumptions made with csavecatenv
*  (which is csetupcchar) are no longer valid.
*  branch to waitcsetup to wait for the shift to finish and then branch
*  to csetupchar.
*  DEW/SFB 11/01/88
*
	      bra     waitcsetup

cdbscroll2    move    d0,wmsourcex(a0)     xmin is src x for rt move
	      add     charw(a3),d0
	      move    d0,wmdestx(a0)     dest is 1 char to rt
	      bra     cdbscrollc     goto common code





cdbscrollr    equ     *
	      moveq   #1,d6          set right shift flag
	      bra     cdbscrollb     go to common code

* procedure cprepdumpline(mybuf:windowp; size:shortint; rowstart:anyptr);
* takes the data in the frame buffer at rowstart, for size*8 bytes, and
* preps it for graphic output by creating an array of size number of bytes
* which has 1 bits where there are non-0 pixels in rowstart array, and 0 bits
* elsewhere. This is the format of PCL graphics data. The mybuf pointer
* is actually a pointer 8 bytes into a pascal string structure.
* the routine detects the last non-0 output byte, and adjusts both the
* strlen of the Pascal string, and the ASCII numeric string to that. The
* adjustment is done to minimize data transmission to printer, especially
* for RS232 printers.
* The ASCII string header looks like #27'*bxxxW' where xxx is a
* 3-digit number, which reflects the length of FOLLOWING binary data.

* called by dumpg in CATCRT - SFB/LAF Jan 26, '88

cprepdumpline equ *
	move.l  (sp)+,a0        return address
	move.l  (sp)+,a3        rowstart
	move.w  (sp)+,d0        size
	move.l  (sp),a1         outbufptr, leave on stack for later
	move.w  d0,d1           copy for adjusting strlen, etc later
	ext.l   d1              ensure MSBs are 0 for later divide
	move.l  d1,d5           keeps track of last non-zero outbuf char
	movea.l crtinfo(a5),a2  get access to crt description
	bra.s   initcharbuf     start up the process

preploop equ    *
	move.b  (a3)+,d2        prepare to test non-zero pixel
	and.b   planemask+3(a2),d2 mask out "floating" bits in pixel
	subi.b  #1,d2           will set X in CCR if (a3) is zero
	roxl.b  #1,d3           put X into output char buf LSB
	dbra    d4,preploop     do it 8 times per out char

	not.b   d3              because X was wrong sense
	move.b  d3,(a1)+        put character into outbuf
	beq.s   initcharbuf     if it wasn't empty, then
	move.w  d0,d5           keep track of last non-empty char

initcharbuf equ *
	move.w  #7,d4           8 bits per output char
	dbra    d0,preploop     n chars/line

	move.l  (sp)+,a1        recover initial outbufptr, and clr stack
	sub.w   d5,d1
	bne.s   fixstrlen       line has something on it
	moveq   #1,d1           must have min of 1 to force slew (we wish!)
fixstrlen equ   *
	move.b  d1,-8(a1)       stick correct length in strlen of outbuf
	addi.b  #7,-8(a1)       and adjust for #27'*bxxxW' header

* compute ASCII representation of d1 into longword, with trailing 'W'
	divu    #10,d1          remainder->upper word of d1
	move.w  d1,d2
	ext.l   d2              clear MSBs of d2
	divu    #10,d2          remainder->upper word of d2
	swap    d2
	rol.w   #8,d2
	clr.w   d1              clear LSBs
	swap    d1
	or.l    d2,d1
	ori.l   #'000',d1       attach ASCII numeric headers
	rol.l   #8,d1           justify for copy to outbuf
	ori.b   #'W',d1         now have 'xxxW' in longword
	move.l  d1,-4(a1)       copy to outbuf
	jmp     (a0)            and return



	end
@


55.1
log
@Automatic bump of revision number for PWS version 3.25A
@
text
@@


54.1
log
@Automatic bump of revision number for PWS version 3.24
@
text
@@


53.1
log
@Automatic bump of revision number for PWS version 3.24B
@
text
@@


52.1
log
@Automatic bump of revision number for PWS version 3.24A
@
text
@@


51.1
log
@Automatic bump of revision number for PWS version 3.24d
@
text
@@


50.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


49.1
log
@Automatic bump of revision number for PWS version 3.24b
@
text
@@


48.1
log
@Automatic bump of revision number for PWS version 3.24a
@
text
@@


47.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


46.1
log
@Automatic bump of revision number for PWS version 3.23
@
text
@@


45.1
log
@Automatic bump of revision number for PWS version 3.23C
@
text
@@


44.1
log
@Automatic bump of revision number for PWS version 3.23B
@
text
@@


43.1
log
@Automatic bump of revision number for PWS version 3.23aA
@
text
@@


42.1
log
@Automatic bump of revision number for PWS version 3.23e
@
text
@@


41.1
log
@Automatic bump of revision number for PWS version 3.23d
@
text
@@


40.1
log
@Automatic bump of revision number for PWS version 3.23c
@
text
@@


39.1
log
@Automatic bump of revision number for PWS version 3.23b
@
text
@@


38.1
log
@Automatic bump of revision number for PWS version 3.23a
@
text
@@


37.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


36.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


35.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


34.1
log
@Automatic bump of revision number for PWS version 3.22
@
text
@@


33.1
log
@Automatic bump of revision number for PWS version 3.22D
@
text
@@


32.1
log
@Automatic bump of revision number for PWS version 3.22C
@
text
@@


31.1
log
@Automatic bump of revision number for PWS version 3.22B
@
text
@@


30.1
log
@Automatic bump of revision number for PWS version 3.22A
@
text
@@


29.3
log
@Bugfixes with Dave Willis for the "Philips" bugs. Scott
@
text
@@


29.2
log
@Fixed non-reported bug on the CATSEYE drivers.
When using the debugger window, a shift left or right would
cause the display to corrupt.  Only way to recover was to reboot.

Problem was that after the shift, the defaults was not being reset.
When the driver went to clear out the left over data after the 
shift to spaces, the 'cchar' routine would assume the defaults.

Solution:  branch to waitcsetup after the shift.
@
text
@d16 6
d23 1
d716 1
a716 1
	    move    #$ff,tcwen1(a0)             to clear on all planes
d852 1
d894 1
d1047 1
a1047 1
*             move.b  d1,tcwen1+1(a0)   1s in cursorcolor.
d1050 1
a1050 1
*             move.b  d1,tcwen1+1(a0)   now set up for 0s
d1080 2
a1081 1
	      move    #$ff,tcwen1(a0)   talk to all wrrs
d1130 1
a1130 1
	      move.w  #$ff,tcwen1(a0)
d1170 2
a1171 1
cscrollwincom move    #$ff,tcwen1(a0)
d1210 1
a1210 1
	      add     dispx(a3),d3   adjusted for displayable framebuf
d1217 2
a1218 1
cdbscrollc    move    #3,wrr1(a0)    setup repl rule
@


29.1
log
@Automatic bump of revision number for PWS version 3.22b
@
text
@d1212 8
a1219 1
	      rts                    finished!
@


28.1
log
@Automatic bump of revision number for PWS version 3.3b
@
text
@@


27.1
log
@Automatic bump of revision number for PWS version 3.3a
@
text
@@


26.1
log
@Automatic bump of revision number for PWS version 3.3 Synch
@
text
@@


25.4
log
@Addedmany bug fixes, notably TRRCTL save/clear/restore, expanded stackbuf
use. See also CATCRT
@
text
@@


25.3
log
@FIrst QA rev of CATSEYE support for 3.21
@
text
@d582 13
a594 1
	    move.w  tcren1(a0),(a1)+
d602 5
a606 1
	    move.w  tcwen1(a0),(a1)+
d608 1
d643 1
a678 4
*           movem.w (a1)+,d0-d7/a3      slurp up main register buffer
*           movem.w d0-d7/a0,rugcmd(a0) and spit out into registers

*           but this is faster according to H/W guys
d696 2
a697 1
	    move.w  (a1)+,planemode(a0)
@


25.2
log
@Early3.21 version. Seems fully functional on all 3 models. No known bugs.
SFB
@
text
@d7 10
d80 1
d82 1
a82 2
*highlight      equ     lowalphaplane+1
creplrule0      equ     highlight+1
a574 4
*           movem.w rugcmd(a0),d0-d7/a3 slurp up main register block
*           movem.w d0-d7/a3,(a1)+      and spit out into buffer

*           but this is faster according to H/W guys
d606 1
d608 1
a608 1
	    moveq   #$ff,d1             alpha and graphics
d610 1
a610 1
	    move.b  d1,fben1(a0)
d612 5
a616 1
	    move.w  alphacolor(a3),d2   prepare wrrs for putting characters
d618 3
a620 2
	    and     d2,d1               lowalphaplane. d1 is bit mask for
	    move.b  d1,tcwen1(a0)       1s in color.
d629 2
a630 2
* csetupcchar sets up window mover params without save catenv. Meant for
* call from Pascal when color, etc change.
d713 2
a714 2
*       because savecatenv has already set up all windowmovers on a per
*       plane basis to move 1s and 0s where necessary, as well as
d788 1
a788 1
	 lsl     d1,d2                  color adjusted by alpha/graphics split
d964 1
a964 1
	      moveq   #$ff,d1             alpha and graphics
d966 1
a966 1
	      move.w  cursorcolor(a3),d2  prepare wrrs for putting cursor
d968 1
a968 1
	      and     d2,d1               lowalphaplane. d1 is bit mask for
a969 3
waitcurson2   equ       *
	      btst      #0,catstat+1(a0)
	      bne.s     waitcurson2
d971 7
a977 1
	      move.b  d1,tcwen1(a0)
d979 1
a979 1
	      not.w   d1
@


25.1
log
@Automatic bump of revision number for PWS version 3.2Y
@
text
@d3 1
a3 1
*   BOBCAT family bit-mapped alpha driver
d5 1
a5 1
*     Pascal 3.1 version by J. Schmidt
d23 1
a23 1
crtinfo         equ     catseyedvr-4    {SFB change this}
d392 2
a393 3
cnocolor2   moveq    #0,d0
	    move     d0,wrr1(a0)            setup to clear frame buffer
	    move     d0,wmdestx(a0)         dest is 0,0
a395 1
	    move     d0,wmdesty(a0)
a397 2
	    move     d0,wmsourcex(a0)
	    move     d0,wmsourcey(a0)
d400 1
a400 1
	    move     d2,wmwidth(a0)         set as window width
a402 2
	    move     d2,twmheight(a0)       set as window height and
*                                           trigger the move
d425 1
a425 1
*           sub      charh(a3),d2       like to do this now, but can't,
d590 1
a590 1
* sets up CATSEYE regs to the state we maintain during driver execution,
d675 1
a675 1
*  procedure cclearall: clears all of visible area
d678 1
d680 2
d689 1
a689 1
	    move    disph(a3),twmheight(a0)     and do move
d743 1
a743 1
	 add.w   fb_fontstarty(a3),d6
d745 1
d747 1
a747 1
	 moveq   #0,d7
d749 1
a749 2
	 divu.w  cppl(a5),d7            (c mod cpl) div cppl=plane of fontchar
	 ori.w   #16,d7                 plane select for "between windows" move
d751 1
a751 2
* WHY IS THE NEXT LINE HERE (COMMENTED OUT NOW) ? SFB
*        swap    d2                     (c mod cpl) mod cppl==c mod cppl
d753 1
a753 1
	 add.w   fb_fontstartx(a3),d2
a878 1
*           rts
a1068 2
	      lsr.w   #2,d0             d0=window width in long integers
	      subi.w  #1,d0             setup for later looping
d1092 2
a1093 17
	      tst.b   hascolor(a5)
	      bne.s   cexchg2
	      move.b  #1,acntrl1(a0)    set "bit-per-pixel", HRM only, for speed
* HRM (bit per pixel) swap - can't use word moves
cexchgmono2   movea.l a4,a2             make a working copy
	      move.w  d0,d7             initialize inner loop
cexchgmono3   move.w  (a2),d6           screen to temp
	      move.w  (a1),(a2)         save area to screen
	      move.w  d6,(a1)+          temp to save area
	      adda.l  #16,a2            next word address of framebuf
	      dbra    d7,cexchgmono3    inner loop (pixel row move)
	      adda.w  fbwidth(a3),a4    bump row pointer
	      dbra    d5,cexchgmono2    outer loop (row count)
	      move.b  #0,acntrl1(a0)    restore "byte-per-pixel"
	      rts

* LCC AND HRC (byte per pixel) swaps
@


24.1
log
@Initial checkin to RCS
@
text
@@


1.1
log
@Initial revision
@
text
@@
