Commit d1af0ed0 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Add builtin software pointer support

Detail:
  This set of changes adds support for rendering software mouse pointers directly in the kernel, rather than requiring graphics drivers to render them themselves as was the case previously.
  If a driver returns from GraphicsV_Features with the 'hardware pointer' bit clear, and a call to GraphicsV_UpdatePointer is returned unclaimed, then the kernel will step in and render a software pointer. This allows selective control over which areas of the screen the software pointer is used (e.g. if hardware only supports its use in some areas)
  hdr/KernelWS - Shrink PointerXEigFactor to 1 byte to free up some space for tracking the display log2bpp. Use 8 words of space for tracking software pointer state.
  s/vdu/vducursoft - Adjust existing the existing calls to the software pointer RemovePointer/RestorePointer functions so that they're called with IRQs enabled
  s/vdu/vdudriver - Keep track of display log2bpp. Claim/release memory needed for restoring pixels under software pointer.
  s/vdu/vdugrafhal - Update HAL_VideoUpdatePointer handling so that 0 can be returned in a1 to indicate the GraphicsV call should be left unclaimed.
  s/vdu/vdupalxx - Trigger updates of the cached software pointer palette whenever it's likely to become invalidated.
  s/vdu/vdupointer - Add software pointer implementation. Relying on a SpriteExtend OS_SpriteOp would be nice, but we're in the background so have to do plotting & unplotting manually. ColourTrans is used to cache the pointer palette colours for the current mode, although we're limited to calling it from a callback.
Admin:
  Tested on Raspberry Pi & BB-xM
  Pointer is very flickery under some circumstances (e.g. running !CloseUp) due to needing to plot/unplot around any VDU driver screen access (as per text cursor). So code may need revising in future once we can trap reads/writes from specific screen memory pages.


Version 5.35, 4.79.2.269. Tagged as 'Kernel-5_35-4_79_2_269'
parent f5644f74
......@@ -13,11 +13,11 @@
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.268"
Module_Date SETS "04 Jul 2015"
Module_ApplicationDate SETS "04-Jul-15"
Module_MinorVersion SETS "4.79.2.269"
Module_Date SETS "10 Jul 2015"
Module_ApplicationDate SETS "10-Jul-15"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.268)"
Module_HelpVersion SETS "5.35 (04 Jul 2015) 4.79.2.268"
Module_FullVersion SETS "5.35 (4.79.2.269)"
Module_HelpVersion SETS "5.35 (10 Jul 2015) 4.79.2.269"
END
......@@ -5,19 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.268
#define Module_Date_CMHG 04 Jul 2015
#define Module_MinorVersion_CMHG 4.79.2.269
#define Module_Date_CMHG 10 Jul 2015
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.268"
#define Module_Date "04 Jul 2015"
#define Module_MinorVersion "4.79.2.269"
#define Module_Date "10 Jul 2015"
#define Module_ApplicationDate "04-Jul-15"
#define Module_ApplicationDate "10-Jul-15"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.268)"
#define Module_HelpVersion "5.35 (04 Jul 2015) 4.79.2.268"
#define Module_FullVersion "5.35 (4.79.2.269)"
#define Module_HelpVersion "5.35 (10 Jul 2015) 4.79.2.269"
#define Module_LibraryVersionInfo "5:35"
......@@ -685,7 +685,9 @@ DisplayXWindLimit # 4 ; Used for pointer programming
DisplayYWindLimit # 4
DisplayXEigFactor # 4
DisplayYEigFactor # 4
PointerXEigFactor # 4
DisplayLog2BPP # 1
PointerXEigFactor # 1
# 2
Ecf1 # 8 ; The Ecf patterns
Ecf2 # 8
......@@ -856,7 +858,17 @@ SpAreaStart # 4 ; Start of sprite area
SpChooseName # 16 ; No comment says Richard
SpChoosePtr # 4
# 8*4 ; SPARE (avoiding changes of exported addresses for now)
SWP_W # 1 ; Width & height of image to restore
SWP_H # 1
SWP_Callback # 1 ; Nonzero if palette update callback registered
SWP_Mutex # 1 ; Mutex to prevent re-entrancy
SWP_Restore # 1 ; Nonzero if restore needed in RestorePointer
SWP_Dirty # 1 ; Nonzero if need replot due to palette change
# 2
SWP_Coords # 4 ; Coordinates of last plot
SWP_Pos # 4 ; Address to restore pixels to, 0 if not displayed
SWP_Under # 4 ; Pointer to copy of screen pixels from under the pointer
SWP_Palette # 3*4 ; Pointer colours converted to pixel values for current mode
TeletextOffset # 4 ; Offset to current teletext flash bank
......
......@@ -83,13 +83,10 @@ PreWrchCursor
; Need to disable IRQs here to stop Vsync modifying CursorFlags in between
; us reading it and writing it
[ No26bitCode
MRS R3, CPSR
ORR R1, R3, #I32_bit
MSR CPSR_c, R1
|
SETPSR I_bit, R1
]
LDR R6, [WsPtr, #CursorFlags]
MOVS R0, R6, LSL #(32-InWrchBitPosn) ; CS => was already off
ORRCC R6, R6, #InWrchBit ; protect against vsyncs
......@@ -100,20 +97,15 @@ PreWrchCursor
; state in top bit
STR R0, [WsPtr, #CursorStack]
MOV R2,R14
LDR R14, [WsPtr, #GraphicsVFeatures]
TST R14, #GVDisplayFeature_HardwarePointer
BLEQ RemovePointer
MOV R14,R2
[ No26bitCode
MSR CPSR_c, R3 ; restore old I bit
MOV R2,R14 ; n.b. calling remove even if
LDR R14, [WsPtr, #SWP_Under] ; soft pointer not currently
TEQ R14, #0 ; visible. This sets the lock,
BLNE RemovePointer ; preventing it from being
MOV R14,R2 ; turned on while we're busy.
MOVCS PC, R14 ; already off, so exit
|
MOVCSS PC, R14 ; already off, so exit
; (restoring I_bit)
TEQP R14, #0 ; restore old I_bit
]
LDR R2, [WsPtr, #CursorAddr] ; point to output
TST R6, #CursorsSplit
......@@ -279,16 +271,12 @@ Cursor32loop
PostWrchCursor ROUT
LDR R6,[WsPtr, #GraphicsVFeatures]
TST R6,#GVDisplayFeature_HardwarePointer
BNE %FT10
LDR R6,[WsPtr, #SWP_Restore]
TEQ R6,#0
BEQ %FT10
MOV R6,R14
MRS R4,CPSR
ORR R3,R4,#I32_bit
MSR CPSR_c,R3
BL RestorePointer
MSR CPSR_c,R4
MOV R14,R6
10
......
......@@ -1080,9 +1080,10 @@ TV_Mode_string
ASSERT Log2BPP = Log2BPC +4
ADD R0, WsPtr, #Log2BPC
LDMIA R0, {R0, R1} ; R0 = Log2BPC; R1 = Log2BPP
STRB R1, [WsPtr, #DisplayLog2BPP]
SUB R3, R3, R0 ; adjust XEig for double pixels
ADD R3, R3, R1
STR R3, [WsPtr, #PointerXEigFactor]
STRB R3, [WsPtr, #PointerXEigFactor]
LDR R3, [R13, #wkModeFlags]
STR R3, [WsPtr, #ModeFlags]
......@@ -1215,6 +1216,32 @@ HardwareModeChange
BL CallGraphicsV
STR R0, [WsPtr, #GraphicsVFeatures] ; refresh cached features just in case something's happened to change them
; claim/release memory needed for software pointer
TST R0, #GVDisplayFeature_HardwarePointer
LDR R2, [WsPtr, #SWP_Under]
BEQ %FT40
TEQ R2, #0
MOVNE R0, #0
STRNE R0, [WsPtr, #SWP_Under]
MOVNE R0, #ModHandReason_Free
SWINE XOS_Module
B %FT50
40
TEQ R2, #0
BNE %FT50
; Claim maximum amount needed
MOV R0, #ModHandReason_Claim
MOV R3, #32*32*4
SWI XOS_Module
STRVC R2, [WsPtr, #SWP_Under]
50
; Release mutex and reset state
; Note that we do this even if the pointer isn't needed, to ensure we
; don't get confused about its state
MOV R2, #0
STR R2, [WsPtr, #SWP_Pos]
STRB R2, [WsPtr, #SWP_Mutex]
Pull "R0-R4, PC"
......
......@@ -79,8 +79,9 @@ GVHAL_SetBlank
GVHAL_UpdatePointer
Push "r0-r3, r9, lr"
AddressHAL WsPtr
MOV r4, #0
CallHAL HAL_VideoUpdatePointer
TEQ r0, #0
MOVNE r4, #0
Pull "r0-r3, r9, pc"
GVHAL_SetDMAAddress
......
......@@ -181,6 +181,13 @@ FinishDefault
MOV r2, #0 ; set border to black (and setup colours 2,3 in BBC gap modes)
BL BorderInitEntry
; Ensure software pointer palette is refereshed
LDR r4, [WsPtr, #GraphicsVFeatures]
TST r4, #GVDisplayFeature_HardwarePointer
LDREQB r4, [WsPtr, #SWP_Callback]
TEQEQ r4, #0
BLEQ RegisterSoftwarePointerCallback
MOV r4, #0 ; indicate PaletteV operation complete
Pull "r0-r3,r5-r9,pc" ; restore registers and claim vector
......@@ -551,6 +558,13 @@ UpdateNormalColour ROUT
AND r0, r0, #255 ; definitely no more than 256 palette entries
BL UpdateSettingAndVIDC
05
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
MOV r4, #0 ; indicate successful PaletteV op
Pull "pc"
......@@ -606,6 +620,11 @@ PointerColour ROUT
MOV r1, #3
BL UpdateSettingAndVIDC
10
LDR r4, [WsPtr, #GraphicsVFeatures]
TST r4, #GVDisplayFeature_HardwarePointer
LDREQB r4, [WsPtr, #SWP_Callback]
TEQEQ r4, #0
BLEQ RegisterSoftwarePointerCallback
MOV r4, #0 ; indicate successful PaletteV op
Pull "pc"
......
......@@ -337,8 +337,10 @@ DoMouseBoxRegs
; UpdatePointer - Called on vsync to update pointer position
;
; in: WsPtr (R12) -> VduDriverWorkSpace
; IRQs disabled, but can be enabled (n.b. may be in IRQ mode)
;
UpdatePointer ROUT
Push "R14"
LDRB R5, [WsPtr, #PointerShapeNumber]
......@@ -377,7 +379,7 @@ UpdatePointer ROUT
ORRNE R0, R0, #2 ; flag new shape (bit 1 = 1)
LDR R1, [WsPtr, #PointerX]
LDR R4, [WsPtr, #PointerXEigFactor]
LDRB R4, [WsPtr, #PointerXEigFactor]
MOV R1, R1, ASR R4 ; R1 = pointer x, pixels
LDRB R4, [R3, #PointerActiveX]
SUB R1, R1, R4 ; R1 = pointer x, adjusted for active point
......@@ -394,8 +396,27 @@ UpdatePointer ROUT
LDR R4, [WsPtr, #CurrentGraphicsVDriver]
MOV R4, R4, LSL #24
ORR R4, R4, #GraphicsV_UpdatePointer
B CallGraphicsV
BL CallGraphicsV
; Software pointer required?
LDR R5, [WsPtr, #GraphicsVFeatures]
TST R5, #GVDisplayFeature_HardwarePointer
Pull "pc", NE
; Software pointer code can run with IRQs enabled; drop into SVC mode
MRS R6, CPSR ; Currently we should always be in IRQ mode here, but read current mode just in case
MSR CPSR_c, #SVC32_mode
MOV R5, R14
; If the call wasn't claimed, pass on to software pointer code
; If the call was claimed, we need to make sure the software pointer is off
TEQ R4, #0
MOVEQ R0, #0
BL UpdateSoftwarePointer
MOV R14, R5
MSR CPSR_c, R6
Pull "pc"
LTORG
......@@ -601,27 +622,39 @@ FlushMouse ROUT
;
; RemovePointer - Remove soft mouse pointer from screen
;
; in: WsPtr -> VduDriverWorkspace
; out: flags preserved
RemovePointer ROUT
STMFD R13!,{R0-R6,R14}
LDRB R3, [WsPtr, #PointerShapeNumber]
TST R3, #&7F
BEQ %FT10
MOV R0, #0
LDR R4, [WsPtr, #CurrentGraphicsVDriver]
MOV R4, R4, LSL #24
ORR R4, R4, #GraphicsV_UpdatePointer
BL CallGraphicsV
10
LDMFD R13!,{R0-R6,PC}
EntryS "r10-r11"
LDRB r10, [WsPtr, #SWP_Mutex]
TEQ r10, #0
BNE %FT90
; Lock mutex
MOV r10, #1
STRB r10, [WsPtr, #SWP_Restore]
STRB r10, [WsPtr, #SWP_Mutex]
; Remove pointer if possible
LDR r11, [WsPtr, #SWP_Pos]
LDR r10, [WsPtr, #SWP_Under]
TEQ r11, #0
BLNE RemoveSoftwarePointer
; Exit with mutex still locked
90
EXITS
; *****************************************************************************
;
; RestorePointer - Restore soft mouse pointer to previous state
;
; in: WsPtr -> VduDriverWorkspace
; Software pointer restore assumed to be needed
RestorePointer ROUT
STMFD R13!,{R0-R6,R14}
MOV R0, #0
STRB R0, [WsPtr, #SWP_Restore]
STRB R0, [WsPtr, #SWP_Mutex]
LDRB R6, [WsPtr, #PointerShapeNumber]
ANDS R6, R6, #&7F
BEQ %FT10
......@@ -638,7 +671,7 @@ RestorePointer ROUT
ORRNE R0, R0, #2 ; flag new shape (bit 1 = 1)
LDR R1, [WsPtr, #PointerX]
LDR R4, [WsPtr, #PointerXEigFactor]
LDRB R4, [WsPtr, #PointerXEigFactor]
MOV R1, R1, ASR R4 ; R1 = pointer x, pixels
LDRB R4, [R3, #PointerActiveX]
SUB R1, R1, R4 ; R1 = pointer x, adjusted for active point
......@@ -650,13 +683,414 @@ RestorePointer ROUT
LDRB R4, [R3, #PointerActiveY]
SUB R2, R2, R4 ; R2 = pointer y, adjusted for active point
; and it's up to the HAL to handle clipping according to h/w capabilities
LDR R4, [WsPtr, #CurrentGraphicsVDriver]
MOV R4, R4, LSL #24
ORR R4, R4, #GraphicsV_UpdatePointer
BL CallGraphicsV
BL UpdateSoftwarePointer
10
LDMFD R13!,{R0-R6,PC}
; *****************************************************************************
;
; UpdateSoftwarePointer - Like GraphicsV_UpdatePointer, but for the
; software pointer
;
; in: r0-r3 as per GraphicsV_UpdatePointer
; WsPtr -> VduDriverWorkSpace
UpdateSoftwarePointer ROUT
Entry "r10-r11"
; Is the pointer possible?
LDR r10, [WsPtr, #SWP_Under]
TEQ r10, #0
BEQ %FT99
; Is mutex locked?
LDRB r11, [WsPtr, #SWP_Mutex]
TEQ r11, #0
BNE %FT99
MOV r11, #1
STRB r11, [WsPtr, #SWP_Mutex]
; Is pointer in same state as last time?
[ NoARMv6
MOV r11, r1, LSL #16
MOV lr, r2, LSL #16
ORR r11, lr, r11, LSR #16
|
PKHBT r11, r1, r2, LSL #16
]
LDR lr, [WsPtr, #SWP_Coords]
TEQ r11, lr ; Have coords changed?
STRNE r11, [WsPtr, #SWP_Coords]
TSTEQ r0, #2 ; Has shape changed?
LDREQB lr, [WsPtr, #SWP_Dirty]
LDR r11, [WsPtr, #SWP_Pos]
TEQEQ lr, #0 ; Has palette changed?
BNE %FT20
; The above state variables only track correctly for when the pointer is on. So we can only skip if it's currently on, and it's staying on.
TEQ r11, #0
TSTNE r0, #1
BNE %FT90
20
; Remove from previous position, if any
TEQ r11, #0
BLNE RemoveSoftwarePointer
; Plot in new position, if any
TST r0, #1
BLNE PlotSoftwarePointer
90
; Release mutex
MOV r11, #0
STRB r11, [WsPtr, #SWP_Mutex]
99
EXIT
; *****************************************************************************
;
; PlotSoftwarePointer - Plot software pointer to the screen
;
; in: r1 = X position
; r2 = Y position
; r3 -> PointerBlkHAL
; WsPtr -> VduDriverWorkSpace
PlotSoftwarePointer ROUT
Entry "r0-r11"
; Load shape info
LDRB r5, [r3, #PointerHeight]
LDRB r4, [r3, #PointerWidth]
CMP r5, #32
LDR r3, [r3, #PointerBuffLA]
MOVGT r5, #32
; Load screen info
; Must be careful to only use variables which aren't affected by output redirection
LDR r0, [WsPtr, #DisplayBankAddr]
LDR r6, [WsPtr, #DisplayXWindLimit]
LDR r7, [WsPtr, #DisplayYWindLimit]
LDRB r9, [WsPtr, #DisplayLog2BPP]
ADD r6, r6, #1
ADD r7, r7, #1
MOV r8, #0 ; Start X offset into pointer image (bits)
MOV r4, r4, LSL #2 ; byte width -> pixel width
STRB r8, [WsPtr, #SWP_Dirty]
; Do a quick scan of the image to see if the LHS is fully transparent
; This is the case for the default pointer image, at least
CMP r5, #0 ; Height can be zero on startup!
ADD r11, r3, r5, LSL #3
BLE %FT99
MOV r10, #0
10
LDR lr, [r11, #-8]!
CMP r11, r3
ORR r10, r10, lr
BNE %BT10
TEQ r10, #0
ADDEQ r8, r8, #32
ADDEQ r1, r1, #16
SUBEQ r4, r4, #16
; Crop image to screen
CMP r1, #0
ADDLT r4, r4, r1
SUBLT r8, r8, r1, LSL #1
MOVLT r1, #0
ADD lr, r1, r4
SUBS lr, lr, r6
SUBGT r4, r4, lr
CMP r2, #0
ADDLT r5, r5, r2
SUBLT r3, r3, r2, LSL #3
MOVLT r2, #0
ADD lr, r2, r5
SUBS lr, lr, r7
SUBGT r5, r5, lr
; Bail if fully off-screen
CMP r4, #0
CMPGT r5, #0
BLE %FT99
MOV r7, r6, LSL r9
MOV r7, r7, LSR #3 ; LineLen
MLA r0, r7, r2, r0 ; First screen row to touch
MOV r1, r1, LSL r9 ; Screen X start, in bits
; Save the rectangle under the pointer
ADR lr, %FT30
Push "r0-r12,lr" ; For RemoveSoftwarePointerAltEntry
; Make things easier by converting to word-aligned coordinates
ADD lr, r1, r4, LSL r9 ; Screen X end, in bits
ADD lr, lr, #31
MOV r1, r1, LSR #5 ; X start in words
RSB r4, r1, lr, LSR #5 ; width in words
; Calculate screen addr to copy from
ADD r10, r0, r1, LSL #2 ; Copy dest
; Remember image size, position for restore later on
STR r10, [WsPtr, #SWP_Pos]
STRB r4, [WsPtr, #SWP_W]
STRB r5, [WsPtr, #SWP_H]
; Copy to SWP_Under
; Can reuse copy loop in RemoveSoftwarePointer
SUB r6, r7, r4, LSL #2 ; Src stride
MOV r7, #0 ; Dest stride
LDR r11, [WsPtr, #SWP_Under] ; Copy src
B RemoveSoftwarePointerAltEntry
30
; Arrive back here with r0-r12 restored
; Important values:
; r0 -> initial screen row
; r1 = screen X start, in bits
; r3 -> initial pointer row
; r4 = pointer pixel width
; r5 = height
; r7 = LineLen
; r8 = pointer X start, in bits
; r9 = Log2BPP
; For 32bpp modes we have a faster plotter available
TEQ r9, #5
BEQ %FT70
; Calculate end-of-row shift amount
ADD lr, r1, r4, LSL r9
AND lr, lr, #31
RSB lr, lr, #32
ORR lr, lr, lr, LSR #5 ; Use 33 to represent case where no shift is needed - ensures the MOVS clears C
Push "lr"
; Convert Log2BPP to BPP
MOV lr, #1
MOV r9, lr, LSL r9
LDR r10, =ZeroPage+VduDriverWorkSpace+SWP_Palette-4
; Conveniently, we can read screen words from SWP_Under, avoiding slow read-modify-write of screen memory
LDR r11, [WsPtr, #SWP_Under]
; Offset r0 to point at first word in row, compute initial mask word
AND lr, r1, #31
ADD r0, r0, r1, LSR #3
MOV r6, #&80000000
BIC r0, r0, #3 ; Row ptr assumed to be word aligned!
MOV r6, r6, LSR lr
Push "r0,r4,r6,r7,r8"
40
; Since the pointer is padded out to 32 pixels wide, it's easiest to
; just load an entire row and treat it as a 64 bit value
LDMIA r3!, {r1, r2}
; Skip the initial pixels
TST r8, #32
AND lr, r8, #31
MOVNE r1, r2
RSB r7, lr, #32
MOV r1, r1, LSR lr
MVN r8, #0
ORR r1, r1, r2, LSL r7
MOV r2, r2, LSR lr
BIC r8, r8, r8, LSR r9 ; Value to merge into mask word
MOV r7, #0
50
ANDS lr, r1, #3
MOV r1, r1, LSR #2
LDRNE lr, [r10, lr, LSL #2]
ORR r1, r1, r2, LSL #30
ORR r7, lr, r7, LSR r9 ; Merge in output pixel, 0 if transparent
MOVNE lr, r8
MOV r2, r2, LSR #2
ORRS r6, lr, r6, LSR r9 ; Merge in mask, 0 if transparent
BCC %FT60
; Store completed screen word
; EQ condition if fully transparent
BEQ %FT55
LDR lr, [r11]
BIC lr, lr, r6
ORR lr, lr, r7
STR lr, [r0]
55
ADD r11, r11, #4
ADD r0, r0, #4
MOV r6, #&80000000
60
SUBS r4, r4, #1
BGT %BT50
; Next row
; However, we may have a partial word to store
; Shift it down to the low end of the word, ready to store
LDR lr, [sp, #5*4] ; Grab precomputed shift amount
MOVS r6, r6, LSR lr
MOV r7, r7, LSR lr
BLS %FT65 ; ~C if no shift needed (actually, lr=33 to ensure C gets cleared), C+Z if word is transparent, C+~Z if visible
LDR lr, [r11]
BIC lr, lr, r6
ORR lr, lr, r7
STR lr, [r0]
65
ADDCS r11, r11, #4
; Last word dealt with
; Advance to next row
LDMIA sp, {r0,r4,r6,r7,r8}
SUBS r5, r5, #1
ADD r0, r0, r7
STRNE r0, [sp]
BNE %BT40
; Junk stack contents
ADD sp, sp, #6*4
99
EXIT
70
; Plotter for 32bpp modes
; No need to read from the screen, just blast out any non-transparent
; pixels
LDR r10, =ZeroPage+VduDriverWorkSpace+SWP_Palette-4
; Offset r0 to point at first word in row
ADD r0, r0, r1, LSR #3
; Calculate shift amount for pointer row
AND r6, r8, #31
RSB r11, r6, #32
Push "r0,r4"
75
; Since the pointer is padded out to 32 pixels wide, it's easiest to
; just load an entire row and treat it as a 64 bit value
LDMIA r3!, {r1, r2}
; Skip the initial pixels
TST r8, #32
MOVNE r1, r2
MOV r1, r1, LSR r6
ORR r1, r1, r2, LSL r11
MOV r2, r2, LSR r6
80
ANDS lr, r1, #3
MOV r1, r1, LSR #2
LDRNE lr, [r10, lr, LSL #2]
ORR r1, r1, r2, LSL #30
MOV r2, r2, LSR #2
STRNE lr, [r0]
SUBS r4, r4, #1
ORRNES lr, r1, r2 ; Stop if remainder of row is transparent
ADD r0, r0, #4
BNE %BT80
; Next row
LDMIA sp, {r0,r4}
SUBS r5, r5, #1
ADD r0, r0, r7
STRNE r0, [sp]
BNE %BT75
; Junk stack contents
ADD sp, sp, #2*4
EXIT
; *****************************************************************************
;
; RemoveSoftwarePointer - Remove software pointer from the screen
;
; in: r10 -> SWP_Under
; r11 -> SWP_Pos
; WsPtr -> VduDriverWorkSpace
RemoveSoftwarePointer
Entry "r0-r12" ; n.b. keep in sync with call from PlotSoftwarePointer
; Get parameters needed for unplot
LDRB r4, [WsPtr, #SWP_W]
LDRB r5, [WsPtr, #SWP_H]
LDR r6, [WsPtr, #DisplayXWindLimit]
LDRB r9, [WsPtr, #DisplayLog2BPP]
ADD r6, r6, #1
MOV r6, r6, LSL r9
MOV r6, r6, LSR #3
SUB r7, r6, r4, LSL #2 ; Dest stride
MOV r6, #0 ; Src stride
STR r6, [WsPtr, #SWP_Pos]
RemoveSoftwarePointerAltEntry
; Width assumed to be max of 32 words
; r0-r3, r8-r9, r12, lr free for use
Push "r4"
05
; Width will almost always be >= 8, so transfer groups of 8 first
CMP r4, #8
06
LDMGEIA r10!, {r0-r3, r8-r9, r12, lr}
SUBGE r4, r4, #8
STMGEIA r11!, {r0-r3, r8-r9, r12, lr}
BEQ %FT90
CMP r4, #8
BGE %BT06
; Transfer remainder
MOVS r4, r4, LSR #1
LDRCS r0, [r10], #4
STRCS r0, [r11], #4
BEQ %FT90
MOVS r4, r4, LSR #1
LDMCSIA r10!, {r0-r1}
STMCSIA r11!, {r0-r1}
BEQ %FT90
; NE so must be 4 left
LDMIA r10!, {r0-r3}
STMIA r11!, {r0-r3}
90
LDR r4, [sp]
ADD r10, r10, r6
SUBS r5, r5, #1
ADD r11, r11, r7
BNE %BT05
ADD sp, sp, #4
EXIT
; *****************************************************************************
;
; RegisterSoftwarePointerCallback - Register callback for palette update
;
; in: WsPtr -> VduDriverWorkSpace
RegisterSoftwarePointerCallback
Entry "r0-r2"
; We may be in IRQ mode, so switch to SVC before calling SWI
MRS r2, CPSR
ORR r1, r2, #SVC32_mode
MSR CPSR_c, r1
Push "lr"
ADR r0, SoftwarePointerCallback
MOV r1, WsPtr
SWI XOS_AddCallBack
MOVVC r0, #1
STRVCB r0, [WsPtr, #SWP_Callback]
Pull "lr"
MSR CPSR_c, r2
EXIT
; *****************************************************************************
;
; SoftwarePointerCallback - Recalculate software pointer palette
;
; in: WsPtr -> VduDriverWorkSpace
SoftwarePointerCallback
Entry "r0-r3"
MOV r0, #0
STRB r0, [WsPtr, #SWP_Callback]
; Can now enable IRQs (ColourTrans may be slow!)
MSR CPSR_c, #SVC32_mode
; Grab the three pointer colours and translate them
; We want to shift the result up to the high end of each word
LDRB r0, [WsPtr, #DisplayLog2BPP]
MOV r1, #1
MOV r0, r1, LSL r0
RSB r3, r0, #32
LDR r2, [WsPtr, #FirPalAddr]
LDR r1, [WsPtr, #DisplayModeNo]
LDR r0, [r2, #257*4]
SWI XColourTrans_ReturnColourNumberForMode
MOV r0, r0, LSL r3
STR r0, [WsPtr, #SWP_Palette]
LDR r0, [r2, #258*4]
SWI XColourTrans_ReturnColourNumberForMode
MOV r0, r0, LSL r3
STR r0, [WsPtr, #SWP_Palette+4]
LDR r0, [r2, #259*4]
SWI XColourTrans_ReturnColourNumberForMode
MOV r0, r0, LSL r3
STR r0, [WsPtr, #SWP_Palette+8]
STRB r1, [WsPtr, #SWP_Dirty]
EXIT
LTORG
END
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment