vdupalxx 43.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
; Copyright 2000 Pace Micro Technology plc
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; vdupalxx

; mjs Sep 2000
;
; Palette programming for generic video controller, delegating h/w
; specifics to HAL calls. Think of any 'VIDC' references here as for a
; generic video controller.

; Format of a 32-bit palette entry in soft palette tables (eg. FirPalAddr) and
; for calls to HAL is:
;
;    BBGGRRSS
;
; ie. 8-8-8-8 bits for Blue-Green-Red-Supremacy
; 'Supremacy' is expected to be 0=solid .. 255=transparent
; [pre-HAL, Medusa kernels used a soft palette format of 0SBBGGRR, being VIDC20-ish]
;
; soft palette tables are indexed by 0..259, where:
;
;   0..255    are normal (display) palette entries
;             type 0, index 0..255 for HAL calls
;   256       is border entry
;             type 1, index 0 for HAL calls
;   257..259  are pointer palette entries
;             type 2, index 1..3 for HAL calls (HAL index 0 assumed to
;             correspond to transparent, and not used)


; *****************************************************************************

; PaletteV handler
; ----------------

; *****************************************************************************
;
;       MOSPaletteV - Default owner of PaletteV
;

        ASSERT  paletteV_Complete = 0
        ASSERT  paletteV_Read = 1
        ASSERT  paletteV_Set = 2
        ASSERT  paletteV_1stFlashState = 3
        ASSERT  paletteV_2ndFlashState = 4
        ASSERT  paletteV_SetDefaultPalette = 5
        ASSERT  paletteV_BlankScreen = 6
        ASSERT  paletteV_BulkRead = 7
        ASSERT  paletteV_BulkWrite = 8
        ASSERT  paletteV_GammaCorrection = 9
        ASSERT  paletteV_LCDInvert = 10
        ASSERT  paletteV_VIDCDisable = 12
        ASSERT  paletteV_VIDCRestore = 13
66 67 68
        ASSERT  paletteV_ReadGammaCorrection = 14
        ASSERT  paletteV_ReadSupremacyTransfer = 15
        ASSERT  paletteV_SetSupremacyTransfer = 16
69 70

MOSPaletteV ROUT
71
        CMP     r4, #16
Kevin Bracey's avatar
Kevin Bracey committed
72 73 74 75 76 77 78 79 80 81 82 83
        ADDLS   pc, pc, r4, LSL #2
        MOV     pc, lr                  ; reason code not known, so pass it on
        MOV     pc, lr                  ; 0
        B       PV_ReadPalette          ; 1
        B       PV_SetPalette           ; 2
        B       PV_1stFlashState        ; 3
        B       PV_2ndFlashState        ; 4
        B       PV_SetDefaultPalette    ; 5
        B       PV_BlankScreen          ; 6
        B       PV_BulkRead             ; 7
        B       PV_BulkWrite            ; 8
        B       PV_GammaCorrect         ; 9
Jeffrey Lee's avatar
Jeffrey Lee committed
84
        MOV     pc, lr                  ; 10 (was PV_LCDInvert)
Kevin Bracey's avatar
Kevin Bracey committed
85 86 87
        MOV     pc, lr                  ; 11
        B       PV_VIDCDisable          ; 12
        B       PV_VIDCRestore          ; 13
88 89 90
        B       PV_ReadGammaCorrect     ; 22
        B       PV_ReadSupremacyXfer    ; 23
        B       PV_SetSupremacyXfer     ; 24
91 92 93 94 95

; *****************************************************************************

PV_SetDefaultPalette ROUT
        Push    "r0-r3,r5-r9"
96 97 98 99
        LDR     r0, [WsPtr, #DisplayModeFlags]
        TST     r0, #ModeFlag_GreyscalePalette
        BNE     %FT30
05
100
        BL      GetPalIndex             ; the new index 0-6
101
        ADR     r1, paldptab
102 103 104
        LDR     r2, [r1, r6, LSL #2]    ; offset from r1 to start of table
        ADD     r6, r6, #1              ; point to next item
        LDR     r5, [r1, r6, LSL #2]    ; offset from r1 to end of table +1
105 106 107 108 109
        TST     r2, #&80000000          ; if bit 31 set, it's a routine
        BIC     r2, r2, #&80000000      ; clear that flag
        ADD     r2, r2, r1              ; r2 -> start of table
        MOVNE   pc, r2                  ; or call routine
        BIC     r5, r5, #&80000000      ; clear routine flag
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
        ADD     r5, r5, r1              ; r5 -> end of table
        MOV     r0, #0                  ; start at palette index 0
        MOV     r1, #3                  ; set both halves
10
        LDR     r6, [r2], #4
        MOVS    r3, r6, LSL #17         ; get 1st half word and set carry if flashing
        MOV     r3, r3, LSR #17
        MOVCC   r4, #0
        LDRCS   r4, =&FFF               ; flashing so invert 2nd half RGB
        BL      UpdateSettingStraightRGB
        ADD     r0, r0, #1
        MOVS    r3, r6, LSL #1          ; get 2nd half word and set carry if flashing
        MOV     r3, r3, LSR #17
        MOVCC   r4, #0
        LDRCS   r4, =&FFF
        BL      UpdateSettingStraightRGB
        ADD     r0, r0, #1
        TEQ     r2, r5
        BNE     %BT10

; now ensure all palette entries from 0..255 are initialised

132
15
133 134 135 136 137 138 139 140 141
        MOV     r3, #0                  ; set unused (and border) to black
        MOV     r4, #0                  ; no flashing
20
        CMP     r0, #256
        BHS     FinishDefault
        BL      UpdateSettingStraightRGB
        ADD     r0, r0, #1
        B       %BT20

142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
30
        ; Check that we know how to generate a greyscale palette for this mode
        ASSERT  ModeFlag_DataFormatFamily_RGB = 0
        TST     r0, #ModeFlag_DataFormatFamily_Mask ; Must be RGB
        BNE     %BT05
        LDR     r6, [WsPtr, #DisplayNColour]
        CMP     r6, #63                 ; not possible in VIDC10 256 colour
        BEQ     %BT05
        LDR     r0, [WsPtr, #Log2BPP]
        CMP     r0, #3                  ; Must be <= 256 colour
        CMPLS   r6, #255                ; Check both values to be sure
        BHI     %BT05
        MOV     r1, #3
        MOV     r2, #0
        ADR     r5, greyscale_mult
        LDR     r5, [r5, r0, LSL #2]
        MOV     r0, #0
35
        MUL     r2, r0, r5
        BL      UpdateNormalColour
        SUBS    r6, r6, #1
        ADD     r0, r0, #1
        BGE     %BT35
        B       %BT15

167 168 169 170
FinishDefault
        MOV     r2, #0                  ; set border to black (and setup colours 2,3 in BBC gap modes)
        BL      BorderInitEntry

171 172 173 174 175 176 177
        ; Ensure software pointer palette is refereshed
        LDR     r4, [WsPtr, #GraphicsVFeatures]
        TST     r4, #GVDisplayFeature_HardwarePointer
        LDREQB  r4, [WsPtr, #SWP_Callback]
        TEQEQ   r4, #0
        BLEQ    RegisterSoftwarePointerCallback

178 179 180 181 182
        MOV     r4, #0                  ; indicate PaletteV operation complete
        Pull    "r0-r3,r5-r9,pc"        ; restore registers and claim vector

        LTORG

183 184 185 186 187 188
greyscale_mult
        DCD     &FFFFFF00 ; 1bpp
        DCD     &55555500 ; 2bpp
        DCD     &11111100 ; 4bpp
        DCD     &01010100 ; 8bpp

189 190 191 192 193 194 195 196 197
; *****************************************************************************

; Table of offsets from paldata_pointer to palette data

paldptab
        &       paldat1-paldptab        ; 2  Colour Modes
        &       paldat2-paldptab        ; 4
        &       paldat4-paldptab        ; 16
        &       (paldat8-paldptab) :OR: &80000000  ; 256 (VIDC10 compatible) - use routine
198
        &       (paldatLin-paldptab) :OR: &80000000 ; 16bpp, 32bpp, 256 greys - use routine
199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
        &       paldatT-paldptab        ; teletext mode
        &       paldatHR-paldptab       ; Hi-res mono mode
        &       paldatend-paldptab      ; end of table marker

paldat1 ; Data for 1 bit modes - only necessary to program registers 0 and 1

;               FSBGR

        DCW     &0000           ; 0  Black
        DCW     &0FFF           ; 1  White

paldat2 ; Data for 2 bit modes - only necessary to program registers 0..3

;               FSBGR

        DCW     &0000           ; 0  Black
        DCW     &000F           ; 1  Red
        DCW     &00FF           ; 2  Yellow
        DCW     &0FFF           ; 3  White

paldat4 ; Data for 4 bit modes - program all registers
        ; Flashing Colours will be needed here

;               FSBGR

        DCW     &0000           ; 0  Black
        DCW     &000F           ; 1  Red
        DCW     &00F0           ; 2  Green
        DCW     &00FF           ; 3  Yellow
        DCW     &0F00           ; 4  Blue
        DCW     &0F0F           ; 5  Magenta
        DCW     &0FF0           ; 6  Cyan
        DCW     &0FFF           ; 7  White
        DCW     &8000           ; 8  Flashing Black
        DCW     &800F           ; 9  Flashing Red
        DCW     &80F0           ; 10 Flashing Green
        DCW     &80FF           ; 11 Flashing Yellow
        DCW     &8F00           ; 12 Flashing Blue
        DCW     &8F0F           ; 13 Flashing Magenta
        DCW     &8FF0           ; 14 Flashing Cyan
        DCW     &8FFF           ; 15 Flashing White

; Routine to initialise palette for VIDC10-compatible 8bpp modes
; Note this must still be in between paldat4 and paldatT

paldat8 ROUT
        MOV     r1, #3                  ; set both halves of palette
        MOV     r0, #0                  ; starting index
10
        AND     r2, r0, #3              ; get tint bits
        ORR     r2, r2, r2, LSL #4      ; and duplicate into bits 8,9,12,13,16,17,20,21,24,25,28,29
        ORR     r2, r2, r2, LSL #8
        ORR     r2, r2, r2, LSL #16
        BIC     r2, r2, #&FF
        TST     r0, #4
        ORRNE   r2, r2, #&00004400
        TST     r0, #8
        ORRNE   r2, r2, #&44000000
        TST     r0, #&10
        ORRNE   r2, r2, #&00008800
        TST     r0, #&20
        ORRNE   r2, r2, #&00440000
        TST     r0, #&40
        ORRNE   r2, r2, #&00880000
        TST     r0, #&80
        ORRNE   r2, r2, #&88000000
        BL      UpdateSettingAndVIDC
        ADD     r0, r0, #1
        TEQ     r0, #&100
        BNE     %BT10
        B       FinishDefault

271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
; Linear / greyscale palette or gamma table
paldatLin ROUT
        ADR     r5, paldatLintab
palmetatab
        MOV     r1, #3                  ; set both halves of palette
        MOV     r0, #0                  ; starting index
10
        MOV     r8, r5
        MOV     r2, #0
        MOV     r6, r0
20
        LDR     r7, [r8], #4
        MOVS    r6, r6, LSR #1
        ORRCS   r2, r2, r7
        BNE     %BT20
        BL      UpdateSettingAndVIDC
        ADD     r0, r0, #1
        TEQ     r0, #&100
        BNE     %BT10
        B       FinishDefault

paldatLintab
 [ DefaultSupremacy
        &       &01010101       ; palette bit 0
        &       &02020202       ;             1
        &       &04040404       ;             2
        &       &08080808       ;             3
        &       &10101010       ;             4
        &       &20202020       ;             5
        &       &40404040       ;             6
        &       &80808080       ;             7
 |
        &       &01010100       ; palette bit 0
        &       &02020200       ;             1
        &       &04040400       ;             2
        &       &08080800       ;             3
        &       &10101000       ;             4
        &       &20202000       ;             5
        &       &40404000       ;             6
        &       &80808000       ;             7
 ]

313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
paldatT ; Data for teletext mode

        DCW     &0000           ; 0 Black
        DCW     &000F           ; 1 Red
        DCW     &00F0           ; 2 Green
        DCW     &00FF           ; 3 Yellow
        DCW     &0F00           ; 4 Blue
        DCW     &0F0F           ; 5 Magenta
        DCW     &0FF0           ; 6 Cyan
        DCW     &0FFF           ; 7 White

; Colours 8 to 15 have supremacy bit set

        DCW     &1000           ; 8 Supremacy+ Black
        DCW     &100F           ; 9            Red
        DCW     &10F0           ; 10           Green
        DCW     &10FF           ; 11           Yellow
        DCW     &1F00           ; 12           Blue
        DCW     &1F0F           ; 13           Magenta
        DCW     &1FF0           ; 14           Cyan
        DCW     &1FFF           ; 15           White

paldatHR  ; data for Hi-res mono mode
        DCW     &0000           ; Only red gun necessary
        DCW     &0111           ; but setting all three makes
        DCW     &0222           ; reading it more natural
        DCW     &0333
        DCW     &0444
        DCW     &0555
        DCW     &0666
        DCW     &0777
        DCW     &0888
        DCW     &0999
        DCW     &0AAA
        DCW     &0BBB
        DCW     &0CCC
        DCW     &0DDD
        DCW     &0EEE
        DCW     &0FFF

        DCW     &0000           ; border black
        DCW     &0010           ; fixed pointer colours
        DCW     &0020
        DCW     &0030


paldatend

; *****************************************************************************

; PaletteV call to set palette in bulk
; in:   R0 => list of colours, or 0
;       R1 =  colour type (16,17,18,24,25) in b24-31 & number to do in b23-b00
;       R2 => list of palette entries (both flash states if 16, one if 17/18)
;       R4 = PaletteV reason code
;
; out:  R4 = 0, claim vector if recognised
;       otherwise preserve R4 and pass on

PV_BulkWrite    ROUT
        Push    "R0-R3,R5-R11"          ; pc already stacked

        ;register usage:
        ;[R6] colour list
        ;R7   colour type
        ;R8   max number
        ;[R9] palette entries
        ;R10  loop counter
        ;R11  colour number

        MOV     R7,R1,LSR #24
        BIC     R8,R1,#&FF000000
        MOV     R6,R0
        MOV     R9,R2

        MOV     R10,#0
10
        TEQ     R6,#0
        MOVEQ   R11,R10
        LDRNE   R11,[R6],#4

        TEQ     R7,#16
        TEQNE   R7,#17

        MOVEQ   R0,R11
398
        MOVEQ   R1,#1+4
399 400 401 402 403 404 405
        LDREQ   R2,[R9],#4
        BLEQ    UpdateNormalColour

        TEQ     R7,#16
        TEQNE   R7,#18

        MOVEQ   R0,R11
406
        MOVEQ   R1,#2+4
407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
        LDREQ   R2,[R9],#4
        BLEQ    UpdateNormalColour

        TEQ     R7,#24

        MOVEQ   R0,R11
        LDREQ   R2,[R9],#4
        BLEQ    BorderColour

        TEQ     R7,#25

        MOVEQ   R0,R11
        LDREQ   R2,[R9],#4
        BLEQ    PointerColour

        ADD     R10,R10,#1
        CMP     R10,R8
        BCC     %BT10

426 427 428
        ; Update greyscale palette mode flag as appropriate
        LDR     r2, [WsPtr, #DisplayNColour]
        CMP     r7, #19
Jeffrey Lee's avatar
Jeffrey Lee committed
429
        CMPLO   r2, #256
430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457
        BHS     %FT90
        PHPSEI
        LDR     r7, [WsPtr, #DisplayModeFlags]
        CMP     r2, #63
        LDR     r5, [WsPtr, #FirPalAddr]
        MOVEQ   r2, #255
        LDR     r6, [WsPtr, #SecPalAddr]
        BIC     r7, r7, #ModeFlag_GreyscalePalette
30
        LDR     r8, [r5], #4
        LDR     r9, [r6], #4
        EOR     r8, r8, r8, LSL #8
        EOR     r9, r9, r9, LSL #8
        CMP     r8, #&10000
        CMPLO   r9, #&10000
        BHS     %FT40
        SUBS    r2, r2, #1
        BGE     %BT30
        ORR     r7, r7, #ModeFlag_GreyscalePalette
40
        STR     r7, [WsPtr, #DisplayModeFlags]
        ; Update live ModeFlags if not redirected to sprite
        LDR     r8, [WsPtr, #VduSprite]
        TEQ     r8, #0
        STREQ   r7, [WsPtr, #ModeFlags]
        PLP
90

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
        MOV     R4,#0
        Pull    "R0-R3,R5-R11,PC"

; *****************************************************************************

; PaletteV call to set palette
; in:   R0 = logical colour
;       R1 = colour type (16,17,18,24,25)
;       R2 = BBGGRRSS
;       R4 = PaletteV reason code
;
; out:  R4 = 0, claim vector if recognised
;       otherwise preserve R4 and pass on
;

;amg 19/4/93 - change this routine to make all the calls subroutines rather
; than branches. Although it will slow this down a bit, it makes the bulk
; write a lot simpler and involves less duplication of mungeing code.

PV_SetPalette ROUT
        Push    "r0-r3"
        TEQ     r1, #16                 ; if 16 then set both colours
        MOVEQ   r1, #3
        BEQ     Call_UpdateNormalColour

        TEQ     r1, #17                 ; elif 17 then set 1st colour
        MOVEQ   r1, #1
        BEQ     Call_UpdateNormalColour

        TEQ     r1, #18                 ; elif 18 then set 2nd colour
        MOVEQ   r1, #2
        BEQ     Call_UpdateNormalColour

        TEQ     r1, #24                 ; elif 24 then border colour
        BEQ     Call_BorderColour

        TEQ     r1, #25                 ; elif 25 then pointer colour
        BEQ     Call_PointerColour
10
        Pull    "r0-r3"
        MOV     pc, lr                  ; else not defined

Call_UpdateNormalColour
        BL      UpdateNormalColour
        Pull    "r0-r3,pc"

BorderInitEntry Push "r0-r3,lr"           ; entry used in default palette setting
Call_BorderColour
        BL      BorderColour
        Pull    "r0-r3,pc"

Call_PointerColour
        BL      PointerColour
        Pull    "r0-r3,pc"

; *****************************************************************************

UpdateNormalColour ROUT
        Push    "LR"
        LDR     lr, [WsPtr, #DisplayNColour] ; get the mask
        TEQ     lr, #63                 ; is it brain-damaged VIDC10-compatible 256 colour mode?
        BEQ     %FT10
        AND     r0, r0, lr              ; and mask it off
        AND     r0, r0, #255            ; definitely no more than 256 palette entries
        BL      UpdateSettingAndVIDC
05
524 525 526 527 528 529 530
        LDR     r4, [WsPtr, #GraphicsVFeatures]
        TST     r4, #GVDisplayFeature_HardwarePointer
        LDREQB  r4, [WsPtr, #SWP_Callback]
        TEQEQ   r4, #0
        LDREQB  r4, [WsPtr, #DisplayLog2BPP]
        TSTEQ   r4, #&FC                ; Callback only needed here for <=8bpp
        BLEQ    RegisterSoftwarePointerCallback
531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562
        MOV     r4, #0                  ; indicate successful PaletteV op
        Pull    "pc"

10
        AND     r0, r0, #15             ; starting palette entry
20
        LDR     r3, =&88CC8800          ; r3 = bits controlled by bits 4..7 of pixel value
        BIC     r2, r2, r3
        TST     r0, #&10                ; test bit 4 (r3,7)
        ORRNE   r2, r2, #&00008800
        TST     r0, #&20                ; test bit 5 (g2,6)
        ORRNE   r2, r2, #&00440000
        TST     r0, #&40                ; test bit 6 (g3,7)
        ORRNE   r2, r2, #&00880000
        TST     r0, #&80                ; test bit 7 (b3,7)
        ORRNE   r2, r2, #&88000000
        BL      UpdateSettingAndVIDC
        ADD     r0, r0, #&10
        CMP     r0, #&100
        BCC     %BT20
        B       %BT05

BorderColour ROUT
        Push    "LR"
        MOV     r0, #256                ; pseudo-palette-index for border colour
        MOV     r1, #3                  ; both colours
        BL      UpdateSettingAndVIDC

; Now test for BBC gap mode (ie 3 or 6)
; if so then set colour 2 to same as border, and colour 3 to inverse

        LDR     lr, [WsPtr, #DisplayModeFlags]
563
        TST     lr, #ModeFlag_BBCGapMode
564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585
        BEQ     %FT10

        MOV     r0, #2                  ; make colour 2 (gap) same as border
        BL      UpdateSettingAndVIDC

        MOV     r0, #3                  ; make colour 3 inverse gap
        MVN     r2, r2                  ; invert R, G and B
        EOR     r2, r2, #&FF            ; but use same supremacy
        BL      UpdateSettingAndVIDC
10
        MOV     r4, #0                  ; indicate successful PaletteV op
        Pull    "pc"


PointerColour ROUT
        Push    "LR"
        ANDS    r0, r0, #3              ; force pointer colour number in range 1..3
        BEQ     %FT10                   ; zero is invalid
        ADD     r0, r0, #256            ; index in range 257..259
        MOV     r1, #3
        BL      UpdateSettingAndVIDC
10
586 587 588 589 590
        LDR     r4, [WsPtr, #GraphicsVFeatures]
        TST     r4, #GVDisplayFeature_HardwarePointer
        LDREQB  r4, [WsPtr, #SWP_Callback]
        TEQEQ   r4, #0
        BLEQ    RegisterSoftwarePointerCallback
591 592 593 594 595 596 597
        MOV     r4, #0                  ; indicate successful PaletteV op
        Pull    "pc"

; UpdateSettingStraightRGB
;
; in:   r0 = index (0..255 for normal, 256 for border, 257..259 for pointer)
;       r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd)
598
;            bit 2 set to suppress greyscale palette check
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
;       r3 = SBGR
;       r4 = SBGR to EOR with to go from 1st to 2nd flash state

; out:  r0,r1,r2,r4 preserved
;       r3 corrupted

UpdateSettingStraightRGB EntryS "r2,r5,r6,r7"

        ANDS    r5, r3, #1 :SHL: 12     ; get supremacy bit (s) in 1st colour
        MOVNE   r5, #&FF                ; r5 = 000000SS
        AND     r6, r3, #&FF0           ; r6 = 00000BG0
        ORR     r5, r5, r6, LSL #16     ; r5 = 0BG000SS
        AND     r6, r3, #&0FF           ; r6 = 000000GR
        ORR     r5, r5, r6, LSL #12     ; r5 = 0BGGR0SS
        AND     r6, r3, #&00F           ; r6 = 0000000R
        ORR     r5, r5, r6, LSL #8      ; r5 = 0BGGRRSS
        AND     r6, r3, #&F00           ; r6 = 00000B00
        ORR     r3, r5, r6, LSL #20     ; r3 = BBGGRRSS

        ANDS    r5, r4, #1 :SHL: 12     ; get supremacy bit (s) in EOR mask
        MOVNE   r5, #&FF                ; r5 = 000000SS
        AND     r6, r4, #&FF0           ; r6 = 00000BG0
        ORR     r5, r5, r6, LSL #16     ; r5 = 0BG000SS
        AND     r6, r4, #&0FF           ; r6 = 000000GR
        ORR     r5, r5, r6, LSL #12     ; r5 = 0BGGR0SS
        AND     r6, r4, #&00F           ; r6 = 0000000R
        ORR     r5, r5, r6, LSL #8      ; r5 = 0BGGRRSS
        AND     r6, r4, #&F00           ; r6 = 00000B00
        ORR     r4, r5, r6, LSL #20     ; r4 = BBGGRRSS

        B       UpdateSettingCommon


; UpdateSettingAndVIDC
;
; in:   r0 = index (0..255 for normal, 256 for border, 257..259 for pointer)
;       r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd)
636
;            bit 2 set to suppress greyscale palette check
637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
;       r2 = BBGGRRSS
;
; out:  r0, r1, r2 preserved
;       r3, r4 corrupted
;

UpdateSettingAndVIDC ALTENTRY

        MOV     r3, r2
        MOV     r4, #0                  ; indicate no EORing between parts

; ... and drop thru to

; UpdateSettingCommon
;
; in:   r0 = index (0..255 for normal, 256 for border, 257..259 for pointer)
;       r1 = bit mask of which flash states to update (bit 0 set => 1st, bit 1 set => 2nd)
654
;            bit 2 set to suppress greyscale palette check
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
;       r3 = BBGGRRSS
;       r4 = BBGGRRSS to EOR with to go from 1st to 2nd flash state
;       r2, r5, r6, r7, lr stacked
;
; out:  r0, r1, r2, r4 preserved
;       r3 corrupted
;
UpdateSettingCommon ROUT
        PHPSEI                          ; protect against IRQs

        Push    "r8, r9"

        LDRB    r5, [WsPtr, #ScreenBlankFlag]
        TEQ     r5, #0
        MOVNE   r5, #&FFFFFFFF          ; bits to knock out if blanked

        LDROSB  r2, FlashState          ; 0 => second, 1 => first
        CMP     r2, #1                  ; C=0 => second, C=1 => first

        TST     r1, #1
        BEQ     %FT10                   ; skip if not setting 1st colour
        LDR     r2, [WsPtr, #FirPalAddr]
677
        ADD     r8, r2, #Pal_RTable-Pal_LogFirst ; r8 -> rgb transfer tables
678 679 680 681 682 683 684 685 686 687 688
        STR     r3, [r2, r0, LSL #2]!   ; store in logical colour and write back pointer
        AND     r6, r3, #&0000FF00      ; r6 = red << 8
        LDRB    r6, [r8, r6, LSR #8]    ; r6 = gamma(red)
        ADD     r8, r8, #&100           ; r8 -> green transfer
        AND     r9, r3, #&00FF0000      ; r9 = green << 16
        LDRB    r9, [r8, r9, LSR #16]   ; r9 = gamma(green)
        ORR     r6, r6, r9, LSL #8      ; r6 = gamma(red) + (gamma(green)<<8)
        ADD     r8, r8, #&100           ; r8 -> blue transfer
        AND     r9, r3, #&FF000000      ; r9 = blue << 24
        LDRB    r9, [r8, r9, LSR #24]   ; r9 = gamma(blue)
        ORR     r6, r6, r9, LSL #16     ; r6 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16)
689 690 691 692 693
        ADD     r8, r8, #&100           ; r8 -> supremacy transfer
        AND     r9, r3, #&000000FF      ; r9 = supremacy
        LDRB    r9, [r8, r9]            ; r9 = transfer(supremacy)
        ORR     r6, r9, r6, LSL #8      ; r6 = gamma(rgb) + transfer(supremacy)
        STR     r6, [r2, #Pal_PhysFirst-Pal_LogFirst] ; store in physical copy
694 695 696

        BCC     %FT10                   ; only hit hardware if flash state = first

697 698
;;; mjs
;;; Pre HAL code had possible LCD greyscale munging, not supported in interim s.vduhint code
699
;;;
Kevin Bracey's avatar
Kevin Bracey committed
700
        Push    "r0-r2,r4,lr"
Jeffrey Lee's avatar
Jeffrey Lee committed
701 702 703
        LDR     r4, [WsPtr, #CurrentGraphicsVDriver]
        MOV     r4, r4, LSL #24
        ORR     r4, r4, #GraphicsV_WritePaletteEntry
Kevin Bracey's avatar
Kevin Bracey committed
704 705 706 707 708 709 710
        BIC     r1, r6, r5                ; r1 = palette colour after knocking out blanking bits
        AND     r2, r0, #255              ; reduced index (0..255 normal, 0 border, 1..3 pointer)
        CMP     r0, #256                  ; HI if pointer
        MOVLS   r0, r0, LSR #8            ; type 0=normal, 1=border
        MOVHI   r0, #2                    ; type 2=pointer
        BL      CallGraphicsV
        Pull    "r0-r2,r4,lr"
711 712 713 714 715 716

10
        EOR     r3, r3, r4              ; toggle requested bits for 2nd half
        TST     r1, #2
        BEQ     %FT20                   ; skip if not setting 2nd colour
        LDR     r2, [WsPtr, #SecPalAddr]
717
        ADD     r8, r2, #Pal_RTable-Pal_LogSecond ; r8 -> rgb transfer tables
718 719 720 721 722 723 724 725 726 727 728 729
        STR     r3, [r2, r0, LSL #2]!   ; store in logical copy and write back

        AND     r6, r3, #&0000FF00      ; r6 = red << 8
        LDRB    r6, [r8, r6, LSR #8]    ; r6 = gamma(red)
        ADD     r8, r8, #&100           ; r8 -> green transfer
        AND     r9, r3, #&00FF0000      ; r9 = green << 16
        LDRB    r9, [r8, r9, LSR #16]   ; r9 = gamma(green)
        ORR     r6, r6, r9, LSL #8      ; r6 = gamma(red) + (gamma(green)<<8)
        ADD     r8, r8, #&100           ; r8 -> blue transfer
        AND     r9, r3, #&FF000000      ; r9 = blue << 24
        LDRB    r9, [r8, r9, LSR #24]   ; r9 = gamma(blue)
        ORR     r6, r6, r9, LSL #16     ; r6 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16)
730 731 732 733 734
        ADD     r8, r8, #&100           ; r8 -> supremacy transfer
        AND     r9, r3, #&000000FF      ; r9 = supremacy
        LDRB    r9, [r8, r9]            ; r9 = transfer(supremacy)
        ORR     r6, r9, r6, LSL #8      ; r6 = gamma(rgb) + transfer(supremacy)
        STR     r6, [r2, #Pal_PhysSecond-Pal_LogSecond] ; store in physical copy
735 736 737

        BCS     %FT20                   ; only hit hardware if flash state = second

738 739
;;; mjs
;;; Pre HAL code had possible LCD greyscale munging, not supported in interim s.vduhint code
740
;;;
Kevin Bracey's avatar
Kevin Bracey committed
741
        Push    "r0-r2,r4,lr"
Jeffrey Lee's avatar
Jeffrey Lee committed
742 743 744
        LDR     r4, [WsPtr, #CurrentGraphicsVDriver]
        MOV     r4, r4, LSL #24
        ORR     r4, r4, #GraphicsV_WritePaletteEntry
Kevin Bracey's avatar
Kevin Bracey committed
745 746 747 748 749 750 751
        BIC     r1, r6, r5                ; r1 = palette colour after knocking out blanking bits
        AND     r2, r0, #255              ; reduced index (0..255 normal, 0 border, 1..3 pointer)
        CMP     r0, #256                  ; HI if pointer
        MOVLS   r0, r0, LSR #8            ; type 0=normal, 1=border
        MOVHI   r0, #2                    ; type 2=pointer
        BL      CallGraphicsV
        Pull    "r0-r2,r4,lr"
752 753

20
754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798
        ; Update greyscale palette mode flag as appropriate
        ; NOTE - relies on r3 being 2nd flash state
        LDR     r2, [WsPtr, #DisplayNColour]
        CMP     r0, #256
        CMPLO   r2, #256
        CMPLO   r1, #4
        BHS     %FT90
        EOR     r4, r3, r4              ; r4 = 1st flash state, r3 = 2nd
        EOR     r8, r3, r3, LSL #8
        EOR     r9, r4, r4, LSL #8
        TST     r1, #1
        MOVEQ   r9, #0                  ; treat unmodified flash states as greyscale - the full check below will sort things out properly if required
        TST     r2, #1
        MOVEQ   r8, #0
        CMP     r8, #&10000
        CMPLO   r9, #&10000
        ; LO -> palette potentially greyscale, HS -> definitely not greyscale
        LDR     r7, [WsPtr, #DisplayModeFlags]
        BICHS   r7, r7, #ModeFlag_GreyscalePalette
        BHS     %FT40
        TST     r7, #ModeFlag_GreyscalePalette
        BNE     %FT90
        ; Check the full palette for greyscaleness
        CMP     r2, #63
        LDR     r5, [WsPtr, #FirPalAddr]
        MOVEQ   r2, #255
        LDR     r6, [WsPtr, #SecPalAddr]
30
        LDR     r8, [r5], #4
        LDR     r9, [r6], #4
        EOR     r8, r8, r8, LSL #8
        EOR     r9, r9, r9, LSL #8
        CMP     r8, #&10000
        CMPLO   r9, #&10000
        BHS     %FT90
        SUBS    r2, r2, #1
        BGE     %BT30
        ORR     r7, r7, #ModeFlag_GreyscalePalette
40
        STR     r7, [WsPtr, #DisplayModeFlags]
        ; Update live ModeFlags if not redirected to sprite
        LDR     r8, [WsPtr, #VduSprite]
        TEQ     r8, #0
        STREQ   r7, [WsPtr, #ModeFlags]
90
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966
        PLP
        Pull    "r8, r9"
        EXITS                           ; restore registers, claim vector

; *****************************************************************************
;
; PV_BulkRead - Read multiple palette entries with one call
;
; in:   R0 => list of colours wanted, or 0 to start with first and increment
;       R1 =  b24-b31 - colour type: 16/17/18/24/25
;             b00-b23 - number of colours to do
;
;       R2 => memory for first flash state colours (and second if R3=0)
;       R3 => memory for second flash state colours (if 0, intermingle with R2 instead)
;
; out:  all preserved (R4 set to 0 to show call handled)

; flags used to control routine

PV_BR_WantFirst *       1               ; doing 16 or 17
PV_BR_WantSecond *      2               ; doing 16 or 18
PV_BR_HaveList *        4               ; we have a list of colours
PV_BR_TwoLists *        8               ; we have two output areas (R2 & R3 valid)
PV_BR_Border   *        16              ; doing 24
PV_BR_Mouse    *        32              ; doing 25

PV_BulkRead ROUT
        Push    "R0-R3,R6-R11"             ; return addr already stacked

        MOV     R6,R1,LSR #24           ; isolate the colour type

        MOV     R7,#(PV_BR_WantFirst + PV_BR_WantSecond)

        CMP     R6,#17                  ; do we want both flash states ?
        BICEQ   R7,R7,#PV_BR_WantSecond ; if 17 only want first flash state

        CMP     R6,#18
        BICEQ   R7,R7,#PV_BR_WantFirst  ; if 18 only want second flash state

        CMP     R6,#24
        ORREQ   R7,R7,#PV_BR_Border
        ORRGT   R7,R7,#PV_BR_Mouse

        ;now set up other control flags
        CMP     R0,#0
        ORRNE   R7,R7,#PV_BR_HaveList   ; we have a list of colours

        CMP     R3,#0
        ORRNE   R7,R7,#PV_BR_TwoLists   ; we have two output areas

        ;set up a mask for the number of colours
        LDR     R8,[WsPtr,#DisplayNColour]
        TEQ     R8,#63
        MOVEQ   R8,#255                 ; deal with braindamaged 8BPP case

        ;the mouse has colours 1-3
        TST     R7,#PV_BR_Mouse
        MOVNE   R8,#3

        ;take the colour type off the top of R1, leaving #colours wanted
        BIC     R1,R1,#&FF000000

        ; register usage:
        ; [R0]: colour list
        ; R1: number of colours
        ; [R2]: first flash state list
        ; [R3]: second flash state list
        ; R7: control flags
        ; R8: mask for colour number
        ; R9: loop counter
        ; R10: misc
        ; LR: misc

        MOV     R9,#0
30
        TST     R7,#PV_BR_HaveList
        LDRNE   LR,[R0],#4
        MOVEQ   LR,R9                   ; LR = wanted colour number

        AND     LR,LR,R8                ; ensure it is sensible

        TST     R7,#PV_BR_Border
        MOVNE   LR,#256                 ; border is stored as colour 256

        TST     R7,#PV_BR_Mouse
        BEQ     %FT40

        TEQ     LR,#0
        BEQ     %FT50                   ;colour 0 is invalid
        ADD     LR,LR,#256              ;bring into range (257-259)

40
        TST     R7,#PV_BR_WantFirst

        LDRNE   R10,[WsPtr,#FirPalAddr]

        LDRNE   R11,[R10,LR,LSL#2]      ; BBGGRRSS
        STRNE   R11,[R2],#4

        TST     R7,#PV_BR_WantSecond
        BEQ     %FT60                   ; have to use a branch here - another TST coming up

        LDR     R10,[WsPtr,#SecPalAddr]

        LDR     R11,[R10,LR,LSL#2]      ; BBGGRRSS

        TST     R7,#PV_BR_TwoLists

        STREQ   R11,[R2],#4
        STRNE   R11,[R3],#4

60      ADD     R9,R9,#1
        CMP     R9,R1
        BCC     %BT30
50
        MOV     R4,#0
        Pull    "R0-R3,R6-R11,PC"          ; return addr already stacked


; *****************************************************************************
;
;       PV_ReadPalette - PaletteV read palette handler
;
; in:   R0 = logical colour
;       R1 = 16 (read normal colour)
;            24 (read border colour)
;            25 (read cursor colour)
;
; out:  R2 = first flash setting   (BBGGRRSS)
;       R3 = second flash setting  (BBGGRRSS)
;

PV_ReadPalette ROUT
        Push    "r10,r11"
        LDR     r10, [WsPtr, #DisplayNColour] ; logical colours in this mode -1
        TEQ     r10, #63                ; if bodgy 256 colour mode
        MOVEQ   r10, #255               ; then use AND mask of 255

        TEQ     r1, #24                 ; is it reading border palette
        MOVEQ   r11, #&100              ; then set up border index
        BEQ     %FT10                   ; and go

        TEQ     r1, #25                 ; is it reading pointer palette
        BEQ     %FT05
        AND     r11, r0, r10            ; no, then force into suitable range
        B       %FT10                   ; always skip
05
        ANDS    r11, r0, #3             ; else force logical colour 0..3
        BEQ     %FT99                   ; and 0 is illegal, so do nothing
        ADD     r11, r11, #&100         ; set up correct index
10

; note no need to fudge 256-colour modes, since we have the correct full 256 entry palette

        LDR     r10, [WsPtr, #FirPalAddr]
        LDR     r2, [r10, r11, LSL #2]  ; r2 := 1st BBGGRRSS
        LDR     r10, [WsPtr, #SecPalAddr]
        LDR     r3, [r10, r11, LSL #2]  ; r3 := 2nd BBGGRRSS
99
        MOV     r4, #0
        Pull    "r10, r11, pc"

; *****************************************************************************
;
;       PV_1stFlashState - PaletteV routine to set first flash state
;

PV_1stFlashState ROUT
Kevin Bracey's avatar
Kevin Bracey committed
967
        Entry   "r0-r3"
968 969 970
        LDRB    r1, [WsPtr, #ScreenBlankFlag]
        TEQ     r1, #0
        LDREQ   r1, [WsPtr, #FirPalAddr]
971
        ADDEQ   r1, r1, #Pal_PhysFirst - Pal_LogFirst ; move pointer to physical palette copy
972 973
        LDRNE   r1, [WsPtr, #BlankPalAddr]
DoR0Flash
Jeffrey Lee's avatar
Jeffrey Lee committed
974 975 976
        LDR     r0, [WsPtr, #DisplayNColour]
        CMP     r0, #256
        EXIT    HS                      ; In > 256 colour modes, this is gamma (which shouldn't flash)
977 978 979
        MOV     r0, #0                  ; type 0 (normal)
        MOV     r2, #0                  ; start at entry 0
        MOV     r3, #256                ; 256 entries
Jeffrey Lee's avatar
Jeffrey Lee committed
980 981 982
        LDR     r4, [WsPtr, #CurrentGraphicsVDriver]
        MOV     r4, r4, LSL #24
        ORR     r4, r4, #GraphicsV_WritePaletteEntries
Kevin Bracey's avatar
Kevin Bracey committed
983 984
        BL      CallGraphicsV
        EXIT
985 986 987 988 989 990 991

; *****************************************************************************
;
;       PV_2ndFlashState - PaletteV routine to set second flash state
;

PV_2ndFlashState ROUT
Kevin Bracey's avatar
Kevin Bracey committed
992
        ALTENTRY
993 994 995
        LDRB    r1, [WsPtr, #ScreenBlankFlag]
        TEQ     r1, #0
        LDREQ   r1, [WsPtr, #SecPalAddr]
996
        ADDEQ   r1, r1, #Pal_PhysFirst-Pal_LogFirst ; move pointer to physical palette copy
997 998 999 1000 1001 1002 1003 1004 1005
        LDRNE   r1, [WsPtr, #BlankPalAddr]
        B       DoR0Flash

; *****************************************************************************
;
;       UpdateAllPalette - Update all VIDC palette entries
;

UpdateAllPalette ROUT
1006
        Entry   "r0-r4, r9-r11"
1007 1008 1009 1010 1011
;sort out which palette to use
        LDROSB  r0, FlashState
        CMP     r0, #1
        LDRCS   r1, [WsPtr, #FirPalAddr]   ; FlashState = 1 => 1st state, 0 => 2nd state
        LDRCC   r1, [WsPtr, #SecPalAddr]
1012
        ADD     r1, r1, #Pal_PhysFirst-Pal_LogFirst ; move pointer to physical palette copy
1013 1014 1015 1016 1017 1018
        LDRB    r10, [WsPtr, #ScreenBlankFlag]
        TEQ     r10, #0
        LDRNE   r1, [WsPtr, #BlankPalAddr] ; blank palette after all
;
        ADD     r10, r1, #256*4            ; pointer to border colour
        PHPSEI  r11                        ; disable IRQs round this bit
Kevin Bracey's avatar
Kevin Bracey committed
1019 1020 1021 1022
;first, the normal colours
        MOV     r0, #0                  ; type 0 (normal)
        MOV     r2, #0                  ; start at entry 0
        MOV     r3, #256                ; 256 entries
Jeffrey Lee's avatar
Jeffrey Lee committed
1023 1024 1025
        LDR     r9, [WsPtr, #CurrentGraphicsVDriver]
        MOV     r9, r9, LSL #24
        ORR     r4, r9, #GraphicsV_WritePaletteEntries
Kevin Bracey's avatar
Kevin Bracey committed
1026 1027 1028 1029 1030
        BL      CallGraphicsV
;next, border colour
        LDR     r1, [r10]               ; border colour
        MOV     r0, #1                  ; type 1
        MOV     r2, #0                  ; index 0
Jeffrey Lee's avatar
Jeffrey Lee committed
1031
        ORR     r4, r9, #GraphicsV_WritePaletteEntry
Kevin Bracey's avatar
Kevin Bracey committed
1032 1033 1034 1035 1036 1037
        BL      CallGraphicsV
;finally, pointer colours
        ADD     r1, r10, #4             ; pointer to pointer colours (oh yes)
        MOV     r0, #2                  ; type 2
        MOV     r2, #1                  ; start at index 1
        MOV     r3, #3                  ; 3 entries
Jeffrey Lee's avatar
Jeffrey Lee committed
1038
        ORR     r4, r9, #GraphicsV_WritePaletteEntries
Kevin Bracey's avatar
Kevin Bracey committed
1039
        BL      CallGraphicsV
1040 1041
;
        PLP     r11
Kevin Bracey's avatar
Kevin Bracey committed
1042
        EXIT
1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057

; *****************************************************************************
;
;       PV_BlankScreen - Blank/unblank screen
;
; in:   R0 = -1 => read blank state
;       R0 = 0 => unblank screen
;       R0 = 1 => blank screen
;
; out:  R0 = old state (0=unblanked, 1=blanked)
;       R4 = 0

PV_BlankScreen ROUT
        Push    "r1-r3, r9"

1058
        LDRB    r3, [WsPtr, #ScreenBlankFlag]
1059 1060
        CMP     r0, #1
        BHI     %FT99                   ; just reading
1061
        TEQ     r0, r3                  ; changing to same state?
1062 1063 1064 1065 1066 1067
        BEQ     %FT99                   ; if so, do nothing

        AND     r0, r0, #1
        STRB    r0, [WsPtr, #ScreenBlankFlag]      ; update new state
        LDRB    r1, [WsPtr, #ScreenBlankDPMSState]

Jeffrey Lee's avatar
Jeffrey Lee committed
1068 1069 1070
        LDR     r4, [WsPtr, #CurrentGraphicsVDriver]
        MOV     r4, r4, LSL #24
        ORR     r4, r4, #GraphicsV_SetBlank
Kevin Bracey's avatar
Kevin Bracey committed
1071
        BL      CallGraphicsV
1072

1073 1074 1075 1076 1077
        ; for backward compatibility, show video DMA state in
        ; MEMC soft copy (DON'T call OS_UpdateMEMC, which would also
        ; make redundant call to HAL)
        ;
        SavePSR r2
Jeffrey Lee's avatar
Jeffrey Lee committed
1078
        LDR     r9, =ZeroPage
1079 1080
        WritePSRc SVC_mode+I_bit+F_bit, r14
        LDR     r1, [r9, #MEMC_CR_SoftCopy]
1081
        TEQ     r0, #1
1082 1083 1084 1085
        BICEQ   r1, r1, #(1 :SHL: 10)
        ORRNE   r1, r1, #(1 :SHL: 10)
        STR     r1, [r9, #MEMC_CR_SoftCopy]
        RestPSR r2
1086 1087 1088 1089

        BL      UpdateAllPalette        ; update all palette, including border + pointer

99
1090
        MOV     r0, r3
1091 1092 1093
        MOV     r4, #0
        Pull    "r1-r3, r9, pc"

1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133
; *****************************************************************************
;
;       PV_ReadGammaCorrect - Read gamma correction tables
;
; in:   r0 -> red table
;       r1 -> green table
;       r2 -> blue table
;
; out:  r4 = 0

PV_ReadGammaCorrect ROUT
        Push    "r0-r3"
        LDR     r4, [WsPtr, #FirPalAddr]
        ADD     r4, r4, #Pal_RTable-Pal_LogFirst; point to gamma tables
        ADD     r3, r4, #256
10
        LDR     lr, [r4], #4
        STR     lr, [r0], #4
        TEQ     r4, r3
        BNE     %BT10

        ASSERT  Pal_GTable = Pal_RTable+256
        ADD     r3, r4, #256
20
        LDR     lr, [r4], #4
        STR     lr, [r1], #4
        TEQ     r4, r3
        BNE     %BT20

        ASSERT  Pal_BTable = Pal_GTable+256
        ADD     r3, r4, #256
30
        LDR     lr, [r4], #4
        STR     lr, [r2], #4
        TEQ     r4, r3
        BNE     %BT30

        MOV     r4, #0
        Pull    "r0-r3, pc"

1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
; *****************************************************************************
;
;       PV_GammaCorrect - Update gamma correction tables
;
; in:   r0 -> red table
;       r1 -> green table
;       r2 -> blue table
;
; out:  r4 = 0

PV_GammaCorrect ROUT
1145
        Push    "r0-r3"
1146
        LDR     r4, [WsPtr, #FirPalAddr]
1147
        ADD     r4, r4, #Pal_RTable-Pal_LogFirst; point to gamma tables
1148 1149 1150 1151 1152 1153 1154
        ADD     r3, r4, #256
10
        LDR     lr, [r0], #4
        STR     lr, [r4], #4
        TEQ     r4, r3
        BNE     %BT10

1155
        ASSERT  Pal_GTable = Pal_RTable+256
1156 1157 1158 1159 1160 1161 1162
        ADD     r3, r4, #256
20
        LDR     lr, [r1], #4
        STR     lr, [r4], #4
        TEQ     r4, r3
        BNE     %BT20

1163
        ASSERT  Pal_BTable = Pal_GTable+256
1164 1165 1166 1167 1168 1169 1170
        ADD     r3, r4, #256
30
        LDR     lr, [r2], #4
        STR     lr, [r4], #4
        TEQ     r4, r3
        BNE     %BT30

1171 1172 1173 1174 1175
        BL      RecomputeLogicalPalette

        MOV     r4, #0
        Pull    "r0-r3, pc"

1176

1177 1178 1179 1180 1181 1182
; go through the logical palette, recomputing the physical from it using the new tables
;
; out:  r0-r4 corrupted

RecomputeLogicalPalette ROUT
        Push    "r5-r8, lr"
1183 1184

        LDR     r4, [WsPtr, #FirPalAddr]        ; r4 -> start of logical palette
1185
        ADD     r5, r4, #Pal_PhysFirst-Pal_LogFirst ; r5 -> start of physical palette
1186
        MOV     r6, r5                          ; r6 = r5 = end of logical palette
1187 1188 1189 1190
        ADD     r0, r4, #Pal_RTable-Pal_LogFirst; r0 -> red table
        ADD     r1, r4, #Pal_GTable-Pal_LogFirst; r1 -> green table
        ADD     r2, r4, #Pal_BTable-Pal_LogFirst; r2 -> blue table
        ADD     r3, r4, #Pal_STable-Pal_LogFirst; r3 -> supremacy table
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200
40
        LDR     r7, [r4], #4                    ; get word
        AND     r8, r7, #&0000FF00              ; r8 = red << 8
        LDRB    r8, [r0, r8, LSR #8]            ; r8 = gamma(red)
        AND     lr, r7, #&00FF0000              ; lr = green << 16
        LDRB    lr, [r1, lr, LSR #16]           ; lr = gamma(green)
        ORR     r8, r8, lr, LSL #8              ; r8 = gamma(red) + (gamma(green)<<8)
        AND     lr, r7, #&FF000000              ; lr = blue << 24
        LDRB    lr, [r2, lr, LSR #24]           ; lr = gamma(blue)
        ORR     r8, r8, lr, LSL #16             ; r8 = gamma(red) + (gamma(green)<<8) + (gamma(blue)<<16)
1201 1202
        AND     lr, r7, #&000000FF              ; lr = supremacy
        LDRB    lr, [r3, lr]                    ; lr = transfer(supremacy)
1203 1204 1205 1206 1207 1208 1209
        ORR     r8, lr, r8, LSL #8              ; r8 = gamma-corrected BBGGRRSS value
        STR     r8, [r5], #4                    ; store word
        TEQ     r4, r6
        BNE     %BT40

        BL      UpdateAllPalette

1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254
        Pull    "r5-r8, pc"

; *****************************************************************************
;
;       PV_ReadSupremacyXfer - Read supremacy transfer table
;
; in:   r0 -> supremacy table
;
; out:  r4 = 0

PV_ReadSupremacyXfer ROUT
        Push    "r0,r3"
        LDR     r4, [WsPtr, #FirPalAddr]
        ADD     r4, r4, #Pal_STable-Pal_LogFirst; point to supremacy table
        ADD     r3, r4, #256
10
        LDR     lr, [r4], #4
        STR     lr, [r0], #4
        TEQ     r4, r3
        BNE     %BT10

        MOV     r4, #0
        Pull    "r0,r3, pc"

; *****************************************************************************
;
;       PV_SetSupremacyXfer - Read supremacy transfer table
;
; in:   r0 -> supremacy table
;
; out:  r4 = 0

PV_SetSupremacyXfer ROUT
        Push    "r0-r3"
        LDR     r4, [WsPtr, #FirPalAddr]
        ADD     r4, r4, #Pal_STable-Pal_LogFirst; point to supremacy table
        ADD     r3, r4, #256
10
        LDR     lr, [r0], #4
        STR     lr, [r4], #4
        TEQ     r4, r3
        BNE     %BT10

        BL      RecomputeLogicalPalette

1255
        MOV     r4, #0
1256
        Pull    "r0-r3, pc"
1257 1258 1259 1260 1261 1262 1263 1264


; *****************************************************************************

PV_VIDCDisable  ROUT
        Push    "r0-r3, r9, r12"

        MOV     r0, #1
1265
        AddressHAL
1266
        CallHAL HAL_VideoSetPowerSave
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276

        MOV     r4, #0
        Pull    "r0-r3, r9, r12, pc"

; *****************************************************************************

PV_VIDCRestore  ROUT
        Push    "r0-r3, r9, r12"

        MOV     r0, #0
1277
        AddressHAL
1278
        CallHAL HAL_VideoSetPowerSave
1279 1280 1281 1282 1283

        MOV     r4, #0
        Pull    "r0-r3, r9, r12, pc"

        END