;-------------------------------------------------------------------------;
;                                  TIGA                                   ;
;        Copyright (c) 1987-1990  Texas Instruments Incorporated.         ;
;			   All Rights Reserved				  ;
;-------------------------------------------------------------------------;
;   TIGA - Graphics Manager                                               ;
;-------------------------------------------------------------------------;
;                                                                         ;
;   void set_palet(size, offset, palet_ary)                               ;
;                                                                         ;
;   This function loads the global "palet" array with the palette values  ;
;   in the parameters and then goes on to load the palette itself.        ;
;   This routine is intended for display boards using the TMS34070        ;
;   palette in line-load mode.                                            ;
;                                                                         ;
;-------------------------------------------------------------------------;
;                                                                         ;
;   int  set_palet_entry(index, r, g, b, i)                               ;
;                                                                         ;
;   This function loads one entry of the global "palet" array,            ;
;   and then goes on to load the palette itself.                          ;
;                                                                         ;
;   Notes: - A8 is False (0) if an invalid index is requested             ;
;-------------------------------------------------------------------------;
;  01/01/87  Original Version Written                      J.G.Littleton  ;
;  07/12/88  Modified for 8-bit RGB, global palet, TIGA dm Graham Short   ;
;  08/26/88  Modified to support multiple display pages    J.G.Littleton  ;
;  09/12/88  Access globals thru environment struct        W.S.Egr        ;
;  11/21/88  Added return value to _entry function         Graham Short   ;
;  01/10/89  Modified to store 4 MSBs in _palet only       Graham Short   ;
;  01/25/89  Modified clear CONTROL to not clear CD bit    Graham Short   ;
;  01/26/89  Cleared PMASK and wrote to all display pages  Graham Short   ;
;  01/02/90  Enhanced error check for size and index parms WSE            ;
;-------------------------------------------------------------------------;
        .include   gspreg.inc
        .include   gsptypes.inc
        .include   gspglobs.inc
        .include   oem.inc
;   Define Functions        
        def        _set_palet
        def        _set_palet_entry
        def        _dm_set_palet_entry

Rcount  .set    A0
Rarg    .set    A1
Rcol    .set    A2
Rpal    .set    A3
Rframe  .set    A4
Rsave1  .set    A5
Rsave2  .set    A9
Roffset .set    A10
Rpage   .set    A11

Rindex  .set    A0
Rred    .set    A1
Rgrn    .set    A2
Rblu    .set    A6
Rint    .set    A7

COLOR_MONOCHROME_FLAG   .set    1

;-------------------------------------------------------------------------;
;  set_palet                                                              ;
;-------------------------------------------------------------------------;
_set_palet:
        mmtm    SP,A0,A1,A2,A3,A4,A5,A9,A10,A11
        mmtm    SP,B0,B1,B3,B9
;-------------------------------------------------------------------------;
;  set up control and pmask io registers                                  ;
;-------------------------------------------------------------------------;
set_CONTROL:
        clr     A8
        move    @CONTROL,Rsave1,0           ;save CONTROL
        setf    16-1-5,0,0
        move    A8,@CONTROL+5,0             ;clear T thru PPOP in CONTROL    
set_PMASK:
        setf    16,0,0
        move    @PMASK,Rsave2,0             ;save PMASK
        move    A8,@PMASK                   ;clear PMASK
;-------------------------------------------------------------------------;
;  set up outer loop register values                                      ;
;-------------------------------------------------------------------------;
set_DYDX:
        move    @(_config+CONFIG_DISP_VRES),DYDX,0  ;0:VRES
        sll     16,DYDX                          ;VRES:0
        addk    4,DYDX                           ;VRES:4
set_Rpage:
        move    @(_config+CONFIG_NUM_PAGES),Rpage,0 ;number of display pages
;-------------------------------------------------------------------------;
;  outer loop executed once per number of display pages                   ;
;  get arguments                                                          ;
;-------------------------------------------------------------------------;
outer_loop:
        setf    32,0,1
        move    *-STK,Rcount,1              ; number  of palette vals
        move    *-STK,Roffset,1             ; offset into the palet  
        move    *-STK,Rarg,1                ; address of palette vals
;-------------------------------------------------------------------------;
;  if count <= 0, abort.                                                  ;
;-------------------------------------------------------------------------;
check_count:
        cmpi    0,Rcount
        jrle    abort
;-------------------------------------------------------------------------;
;  check that the number of entries being set does not overflow the palet ;
;-------------------------------------------------------------------------;
set_Rcount:
        move    @_config+CONFIG_PALET_SIZE,Rpal,1 ; get size of palet in temp           
        move    Roffset,Rframe
        add     Rcount,Rframe               ;get Offset + Count in temporary
        cmp     Rframe,Rpal                 ;compare against size of palette
        jrgt    set_Rframe
        move    Rpal,Rcount                 ;if larger, adjust count 
        sub     Roffset,Rcount
;-------------------------------------------------------------------------;
;  set up inner loop register values                                      ;
;-------------------------------------------------------------------------;
set_Rframe:
        move    @_page,Rframe,1
        move    Rpage,Rpal                      
        dec     Rpal                            ;get page number
        sll     6,Rpal                          ;convert page to offset into array
        add     Rpal,Rframe                     ;point to start of structure
        move    *Rframe,Rframe,1                ;read offset value
        move    @_config+CONFIG_PALET_INSET,Rpal,0 ; get palet inset into temp
        sub     Rpal,Rframe
        sla     4,Roffset                       ;16 bits per frame palet entry
        add     Roffset,Rframe                  ;point to correct element in frame
set_Rpal:
        sla     1,Roffset                       ;32 bits per palet entry
        move    Roffset,Rpal                    ;Address of palet entry
        addi    _palet,Rpal                     ;Address of global palet array
;-------------------------------------------------------------------------;
;  inner loop to initalize the palette for a given display page           ;
;-------------------------------------------------------------------------;
init_pal:
        clr     COLOR1
        move    Rframe,DADDR
        setf    32,0,1
        move    @_monitorinfo,A8,1   
        .if     GSP_34010
        move    *A8(MONITOR_FLAGS10),A8,1 ; Get color/mono flag
        .endif
        .if     GSP_34020
        move    *A8(MONITOR_FLAGS20),A8,1 ; Get color/mono flag
        .endif
        setf    8,0,1
        andi    COLOR_MONOCHROME_FLAG,A8
        jrz     color_monitor
monochrome_monitor:
        addi    24,Rarg 
        clrs    Rcol
        move    Rcol,*Rpal+,1               ; clear "r" in global palet array
        move    Rcol,*Rpal+,1               ; clear "g" in global palet array
        move    Rcol,*Rpal+,1               ; clear "b" in global palet array
        move    *Rarg+,A8,1                 ; get "i"
        srl     4,A8                        ; ignore ls 4 bits
        sla     4,A8
        move    A8,*Rpal+,1                 ; store "i" in global palet array
        move    A8,SADDR
        or      SADDR,COLOR1                ; or in "r" part
        sla     4,SADDR
        or      SADDR,COLOR1                ; or in "g" part
        sla     4,SADDR
        or      SADDR,COLOR1                ; or in "b" part
        jruc    fill_palet
color_monitor:
        move    *Rarg+,Rcol,1               ; get red component (a byte)
        srl     4,Rcol                      ; ignore ls 4 bits
        sla     4,Rcol
        move    Rcol,*Rpal+,1               ; save in global palet array
        move    Rcol,SADDR
        or      SADDR,COLOR1
        move    *Rarg+,Rcol,1               ; repeat for green...
        srl     4,Rcol
        sla     4,Rcol
        move    Rcol,*Rpal+,1               ; ignore ls 4 bits
        sla     4,Rcol
        move    Rcol,SADDR
        or      SADDR,COLOR1
        move    *Rarg+,Rcol,1               ; ...and blue
        srl     4,Rcol
        sla     4,Rcol
        move    Rcol,*Rpal+,1               ; ignore ls 4 bits
        sla     8,Rcol
        move    Rcol,SADDR
        or      SADDR,COLOR1
        move    *Rarg+,A8,1                 ; ignore "i"
        clrs    A8 
        move    A8,*Rpal+,1
fill_palet:
        fill    L                           ; init register on every line
        addk    16,Rframe
        dsj     Rcount,init_pal
;-------------------------------------------------------------------------;
;  end of inner loop, restore offset and STK                              ;
;-------------------------------------------------------------------------;
        addi    96,STK
        dsj     Rpage,outer_loop
;-------------------------------------------------------------------------;
;  end of outer loop, restore all registers                               ;
;-------------------------------------------------------------------------;
abort:
        move    Rsave1,@CONTROL,0
        move    Rsave2,@PMASK,0
        setf    32,0,1
        mmfm    SP,B0,B1,B3,B9
        mmfm    SP,A0,A1,A2,A3,A4,A5,A9,A10,A11
        move    *SP(32),STK,1               ; restore C-stack pointer
        rets    2


;-------------------------------------------------------------------------;
;  set_palet_entry                                                        ;
;-------------------------------------------------------------------------;
;                                                                         ;
; DIRECT-MODE ENTRY POINT                                                 ;
;                                                                         ;
;-------------------------------------------------------------------------;
_dm_set_palet_entry:
        mmtm    SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A11
        mmtm    SP,B0,B1,B3,B9
;-------------------------------------------------------------------------;
;  get arguments                                                          ;
;-------------------------------------------------------------------------;
        move    *-STK,A8,1                  ;address of data area
        setf    16,0,0
        move    *A8+,Rindex,1               ;get index
        move    *A8+,Rred,0                 ;get red color
        move    *A8+,Rgrn,0                 ;get green color
        move    *A8+,Rblu,0                 ;get blue color
        move    *A8,Rint,0                  ;get intensity color
        jruc    common_ep2
;-------------------------------------------------------------------------;
;                                                                         ;
; C-PACKET ENTRY POINT                                                    ;
;                                                                         ;
;-------------------------------------------------------------------------;
_set_palet_entry
        mmtm    SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A11
        mmtm    SP,B0,B1,B3,B9
;-------------------------------------------------------------------------;
;  get arguments                                                          ;
;-------------------------------------------------------------------------;
        move    *-STK,Rindex,1              ;pop index
        move    *-STK,Rred,1                ;pop red color
        move    *-STK,Rgrn,1                ;pop green color
        move    *-STK,Rblu,1                ;pop blue color
        move    *-STK,Rint,1                ;pop intensity color
        setf    16,0,0
;-------------------------------------------------------------------------;
;                                                                         ;
; 2-ENTRY POINTS JOIN UP HERE                                             ;
;                                                                         ;
;-------------------------------------------------------------------------;
;  check index, if < 0 or >= palet_size, abort and return FALSE           ;
;-------------------------------------------------------------------------;
common_ep2:
        clr     A8                          ;Clear return value (Error)
        cmpi    0,Rindex                    ;If index < 0,
        jrlt    abort2                      ; then abort
        move    @_config+CONFIG_PALET_SIZE,Rsave1,1
        cmp     Rsave1,Rindex               ;If index >= palet_size,
        jrge    abort2                      ; then abort
;-------------------------------------------------------------------------;
;  set up control and pmask io registers                                  ;
;-------------------------------------------------------------------------;
set_CONTROL2:
        move    @CONTROL,Rsave1,0            ;save CONTROL
        setf    16-5,0,0
        move    A8,@CONTROL+5,0
set_PMASK2:
        setf    16,0,0
        move    @PMASK,Rsave2,0              ;save PMASK
        move    A8,@PMASK                    ;clear PMASK
;-------------------------------------------------------------------------;
;  set up initial register values                                         ;
;-------------------------------------------------------------------------;
set_DYDX2:
        move    @(_config+CONFIG_DISP_VRES),DYDX,0  ;0:VRES
        sll     16,DYDX                          ;VRES:0
        addk    4,DYDX                           ;VRES:4
set_Rpal2:
        sla     5,Rindex                        ;32 bits per palet entry
        move    Rindex,Rpal                     ;Address of palet entry
        addi    _palet,Rpal                     ;Address of global palet array
        sra     5,Rindex                        ;Restore Rindex
set_Rpage2:
        move    @(_config+CONFIG_NUM_PAGES),Rpage,0 ;number of display pages
;-------------------------------------------------------------------------;
;  initalize the global palet array and set up the COLOR1 register        ;
;-------------------------------------------------------------------------;
        clr     COLOR1
        setf    32,0,1
        move    @_monitorinfo,A8,1   
        .if     GSP_34010
        move    *A8(MONITOR_FLAGS10),A8,1 ; Get color/mono flag
        .endif
        .if     GSP_34020
        move    *A8(MONITOR_FLAGS20),A8,1 ; Get color/mono flag
        .endif
        setf    8,0,1
        andi    COLOR_MONOCHROME_FLAG,A8
        jrz     color_monitor_entry
monochrome_monitor_entry:
        clrs    Rred
        move    Rred,*Rpal+,1               ; clear "r" in global palet array
        move    Rred,*Rpal+,1               ; clear "g" in global palet array
        move    Rred,*Rpal+,1               ; clear "b" in global palet array
        srl     4,Rint                      ; ignore ls 4 bits
        sla     4,Rint
        move    Rint,*Rpal+,1               ; store "i" in global palet array
        move    Rint,SADDR
        or      SADDR,COLOR1                ; or in "r" part
        sla     4,SADDR
        or      SADDR,COLOR1                ; or in "g" part
        sla     4,SADDR
        or      SADDR,COLOR1                ; or in "b" part
        jruc    fill_palet_entry
color_monitor_entry:
        srl     4,Rred                      ; ignore ls 4 bits
        sla     4,Rred
        move    Rred,*Rpal+,1               ; save in global palet array
        move    Rred,SADDR
        or      SADDR,COLOR1
        srl     4,Rgrn
        sla     4,Rgrn                      ; ignore ls 4 bits
        move    Rgrn,*Rpal+,1               ; repeat for green
        sla     4,Rgrn
        move    Rgrn,SADDR
        or      SADDR,COLOR1
        srl     4,Rblu
        sla     4,Rblu                      ; ignore ls 4 bits
        move    Rblu,*Rpal+,1               ; ...and blue
        sla     8,Rblu
        move    Rblu,SADDR
        or      SADDR,COLOR1
        clrs    Rint                        ; ignore intensity
        move    Rint,*Rpal,1                ; save intensity
;-------------------------------------------------------------------------;
;  main loop executed once per number of display pages                    ;
;-------------------------------------------------------------------------;
fill_palet_entry:
        setf    32,0,1
set_Rframe2:
        move    @_page,Rframe,1
        move    Rpage,Rpal                      
        dec     Rpal                            ;get page number
        sll     6,Rpal                          ;convert page to offset into array
        add     Rpal,Rframe                     ;point to start of structure
        move    *Rframe,Rframe,1                ;read offset value
        move    @_config+CONFIG_PALET_INSET,Rpal,0 ; get palet inset into temp
        sub     Rpal,Rframe
        sla     4,Rindex                        ;16 bits per frame palet entry
        add     Rindex,Rframe                   ;point to correct element in frame
        move    Rframe,DADDR
        fill    L                           ; init frame palet
;-------------------------------------------------------------------------;
;  restore index                                                          ;
;-------------------------------------------------------------------------;
        sra     4,Rindex
        dsjs    Rpage,set_Rframe2
;-------------------------------------------------------------------------;
;  end of loop, restore all registers                                     ;
;-------------------------------------------------------------------------;
        move    Rsave1,@CONTROL,0
        move    Rsave2,@PMASK,0
        movk    1,A8                        ; normal return (TRUE, A8 <> 0)
abort2: mmfm    SP,B0,B1,B3,B9
        mmfm    SP,A0,A1,A2,A3,A4,A5,A6,A7,A9,A11
        rets    2
        .end
