Commit fa159ee5 authored by Mike Stephens's avatar Mike Stephens
Browse files

further kernel/HAL split work in video area almost-HAL code for VIDC20/IOMD in...

further kernel/HAL split work in video area almost-HAL code for VIDC20/IOMD in vdu.vduhint, now almost divorced from kernel workspace tested briefly in Ursula desktop environment

Version 5.35, 4.79.2.4. Tagged as 'Kernel-5_35-4_79_2_4'
parent 2b17314a
......@@ -11,10 +11,10 @@
GBLS Module_HelpVersion
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.3"
Module_Date SETS "03 Oct 2000"
Module_ApplicationDate2 SETS "03-Oct-00"
Module_ApplicationDate4 SETS "03-Oct-2000"
Module_FullVersion SETS "5.35 (4.79.2.3)"
Module_HelpVersion SETS "5.35 (03 Oct 2000) 4.79.2.3"
Module_MinorVersion SETS "4.79.2.4"
Module_Date SETS "05 Oct 2000"
Module_ApplicationDate2 SETS "05-Oct-00"
Module_ApplicationDate4 SETS "05-Oct-2000"
Module_FullVersion SETS "5.35 (4.79.2.4)"
Module_HelpVersion SETS "5.35 (05 Oct 2000) 4.79.2.4"
END
......@@ -4,16 +4,16 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.3
#define Module_Date_CMHG 03 Oct 2000
#define Module_MinorVersion_CMHG 4.79.2.4
#define Module_Date_CMHG 05 Oct 2000
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.3"
#define Module_Date "03 Oct 2000"
#define Module_MinorVersion "4.79.2.4"
#define Module_Date "05 Oct 2000"
#define Module_ApplicationDate2 "03-Oct-00"
#define Module_ApplicationDate4 "03-Oct-2000"
#define Module_ApplicationDate2 "05-Oct-00"
#define Module_ApplicationDate4 "05-Oct-2000"
#define Module_FullVersion "5.35 (4.79.2.3)"
#define Module_HelpVersion "5.35 (03 Oct 2000) (4.79.2.3)"
#define Module_FullVersion "5.35 (4.79.2.4)"
#define Module_HelpVersion "5.35 (05 Oct 2000) (4.79.2.4)"
......@@ -683,7 +683,7 @@ TotalScreenSize # 4 ; Amount configured for screen (in bytes)
MaxMode # 4 ; Maximum mode number allowed (20 for now)
VinitCopy # 4 ; Copy of Vinit for VDU 23;12 or 13
# 4 ; SPARE
CursorFlags # 4 ; Silly Master cursor movement flags
......@@ -1030,9 +1030,7 @@ EvtHan # 4
; (256 words) which is no longer adequate, so we can reuse it
JordanWS # 0
VInitSoftCopy # 4 ; soft copy of VInit so we can set L bit correctly
VEndSoftCopy # 4 ; soft copy of VEnd ------------""---------------
VStartSoftCopy # 4 ; soft copy of VStart so we can calculate VIDINITB correctly
# 3*4 ; SPARE
DAList # 4 ; Pointer to first node on dynamic area list
......@@ -1104,12 +1102,16 @@ InitKbdWs # 16 ; Workspace for reset keyboard IRQ code (was 12
CLine_Softcopy # 1 ; Added for Morris - Monitor id
VRAMWidth # 1 ; 0 => no VRAM, 1 => 32-bits wide, 2 => 64-bits wide
[ :LNOT: STB
[ {FALSE} ;;; mjsHAL no LCD support
LCD_Active # 1 ; Added to support LCD/CRT switching. bm 6 bits 0=>External CRT in use, 1=>Mono, 2=>Passive colour, 3=>Active colour
; bit 7 unset=>single panel, set=>dual panel
LCD_Inverted # 1 ; Added to support LCD palette inversion. 0=normal, 1=inverted. Note that the inversion is invisible to apps.
! 0, "LCD_Active flag byte held at ":CC::STR:(LCD_Active)
]
|
# 2 ; SPARE
]
[ HAL
AlignSpace
HAL_Descriptor # 4
......
......@@ -181,99 +181,10 @@ OneMByte EQU (1024*1024)
SixteenMByte EQU (1024*1024 * 16)
; *****************************************************************************
;
; SetDAG - Program DMA address generator R1 with physical address R0
; NB on IOMD this is the true physical address, not just offset into VRAM or DRAM
;
; in: r0 = physical address
; r1 = index of DMA address generator to program, as defined in vdudecl
;
; out: All registers preserved, operation ignored if illegal
;
SetDAG Entry "r0-r1,r12"
MOV r12, #IOMD_Base
CMP r1, #1
BEQ %FT10
BHI %FT20
; Program VInit
00
ASSERT MEMCDAG_VInit = 0
MOV r14, #0
STR r0, [r14, #VInitSoftCopy] ; save VInit so that writes to VEnd can check
LDR r14, [r14, #VEndSoftCopy]
CMP r0, r14 ; if VInit >= VEnd then set L bit
ORRCS r0, r0, #IOMD_DMA_L_Bit
STR r0, [r12, #IOMD_VIDINIT]
[ :LNOT: STB
MOV r1, #0
LDRB r1, [r1, #LCD_Active]
TST r1, #&80
EXIT EQ ;Exit if not a dual-panel LC display
]
;Otherwise, we are going to have to update VIDINITB too...
MOV r1, #VduDriverWorkSpace
LDR r1, [r1, #ScreenSize]
BIC r0, r0, #IOMD_DMA_L_Bit
ADD r0, r0, r1, LSR #1 ;R0 = VIDINIT+(screensize/2)
CMP r0, r14 ;If VIDINITB>=VEnd...
ORREQ r0, r0, #IOMD_DMA_L_Bit ;Set the L bit if =
SUBGT r0, r0, r14 ;VIDINITB=VIDINITB-VEnd
MOVGT r14, #0
LDRGT r1, [r14, #VStartSoftCopy]
ADDGT r0, r0, r1 ;VIDINITB=VIDINITB+VStart
SUBGT r0, r0, #16 ;Quad word correction. /** You are not expected to understand this **/ :-)
STR r0, [r12, #IOMD_VIDINITB]
EXIT
; Program VStart
10
ASSERT MEMCDAG_VStart = 1
MOV r14, #0
STR r0, [r14, #VStartSoftCopy]
STR r0, [r12, #IOMD_VIDSTART]
EXIT
20
CMP r1, #3
EXIT HI
BEQ %FT30
; Program VEnd
ASSERT MEMCDAG_VEnd = 2
MOV r14, #0
STR r0, [r14, #VEndSoftCopy] ; remember old VEnd value
LDR r14, [r14, #VInitSoftCopy] ; load old VInit
CMP r14, r0 ; if VInit >= VEnd
ORRCS r14, r14, #IOMD_DMA_L_Bit ; then set L bit
STR r14, [r12, #IOMD_VIDINIT] ; store VInit
STR r0, [r12, #IOMD_VIDEND] ; and VEnd
[ :LNOT: STB
MOV r14, #0
LDRB r14, [r14, #LCD_Active]
TST r14, #&80
EXIT EQ ; Not a dual-panel LCD so no need to hang around....
]
;Check whether we need to update VIDINITB or not...
EXIT
; Program CInit
30
ASSERT MEMCDAG_CInit = 3
STR r0, [r12, #IOMD_CURSINIT]
EXIT
; mjs Oct 2000 kernel/HAL split
; SetDAG stuff is no more, routines like SetVinit now call equivalent HAL
; routine
; **************** CAM manipulation utility routines ***********************************
......@@ -631,7 +542,16 @@ SSETMEMC ROUT
ORR r11, r11, #MEMCADR
STR r11, [r12, #MEMC_CR_SoftCopy]
; We now have to mimic the relevant bits of the MEMC1 control register
; mjs Oct 2000 kernel/HAL split
;
; The kernel itself should now never call this SWI, but grudgingly has
; to maintain at least bit 10 of soft copy
;
; Here, we only mimic action of bit 10 to control video/cursor DMA (eg. for ADFS)
; The whole OS_UpdateMEMC thing would ideally be withdrawn as archaic, but
; unfortunately has not even been deprecated up to now
; for reference, the bits of the MEMC1 control register are:
;
; bits 0,1 => unused
; bits 2,3 => page size, irrelevant since always 4K
......@@ -642,20 +562,20 @@ SSETMEMC ROUT
; bit 11 => Sound DMA enable
; bit 12 => OS mode
Push "r10"
MOV r12, #IOMD_Base
TST r11, #1 :SHL: 10 ; see if video DMA wants to be enabled
LDRB r11, [r12, #IOMD_VIDCR]
AND r11, r11, #(&7F :AND: :NOT: IOMD_VIDCR_Enable) ; knock out bit 7 and video DMA enable bit
ORRNE r11, r11, #IOMD_VIDCR_Enable
[ :LNOT: STB
MOV r10, #0
LDRB r10, [r10, #LCD_Active]
TST r10, #&80
ORRNE r11, r11, #IOMD_VIDCR_Dup ;Set bit 7 if we're on an LCD dual-panel display
]
Pull "r10"
STRB r11, [r12, #IOMD_VIDCR]
Push "r0-r3, r9, r14" ; can corrupt r12
TST r11, #(1 :SHL: 10)
MOVEQ r0, #1 ; blank (video DMA disable)
MOVNE r0, #0 ; unblank (video DMA enable)
MOV r1, #0 ; no funny business with DPMS
;;;
;;;mjsHAL my temporary macros aren't defined early enough!
;;; mjsAddressHAL
;;; mjsCallHAL HAL_Video_SetBlank
LDR r9, =mjs_tempHALworkspace
LDR r9, [r9]
BL HAL_Video_SetBlank
;;;
Pull "r0-r3, r9, r14"
WritePSRc SVC_mode+I_bit, r11
ExitSWIHandler
......
......@@ -46,14 +46,12 @@ Link RN 14
PhysCursorStartAdr * CursorSoundPhysRAM
; Reason codes for generalised DAG interface - independent of MEMC type
; Reason codes for generalised DAG interface
MEMCDAG_VInit * 0
MEMCDAG_VStart * 1
MEMCDAG_VEnd * 2
MEMCDAG_CInit * 3
HALDAG_VInit * 0
HALDAG_VStart * 1
HALDAG_VEnd * 2
MEMCDAG_MaxReason * 3
[ ModeSelectors
......
......@@ -609,10 +609,7 @@ VduBadExit ; jumped to if an error in VDU code
ModeChangeSub ROUT
Push lr
[ :LNOT: STB
MOV r1, #0
STRB r1, [r1, #LCD_Active] ;Default to non-lcd active, single panel (mainly for Stork power-saving info)
]
MOV R1, #Service_PreModeChange
IssueService
TEQ R1, #0 ; was service claimed ?
......@@ -723,7 +720,8 @@ TV_Mode_string
BL IssueModeService
[ LCDPowerCtrl :LAND: :LNOT: STB
[ {FALSE} ;;; LCDPowerCtrl :LAND: :LNOT: STB
;;; mjsHAL no LCD support
;Switch LCD off here if it is _not_ an LCD mode
MOV R3, #0
LDRB R3, [R3, #LCD_Active]
......@@ -867,15 +865,19 @@ TV_Mode_string
ADD R13, R13, #PushedInfoSize ; junk stacked data
;;; mjsHAL - still some hardware dependency here - IOMD for DMA etc
;;; needs transfer to HAL routine, either as part of hit-specific-VIDC
;;; call above, or as additional call(s)
MOV R0, #(1 :SHL: 10) ; enable video DMA
ORR R1, R0, #(1 :SHL: 9) ; refresh only in vflyback
SWI XOS_UpdateMEMC
; for backward compatibility, show that video DMA is enabled in
; MEMC soft copy (DON'T call OS_UpdateMEMC, which would also
; make redundant call to HAL)
;
SavePSR R2
MOV R0, #0
WritePSRc SVC_mode+I_bit+F_bit, R14
LDR R1, [R0, #MEMC_CR_SoftCopy]
ORR R1, R1, #(1 :SHL: 10)
STR R1, [R0, #MEMC_CR_SoftCopy]
RestPSR R2
BL SetVendDefault ; set to ScreenEndAdr-16
BL SetVendDefault
MOV R1, #ScreenEndAdr ; need to reload cos corrupt
LDR R2, [WsPtr, #TotalScreenSize]
......@@ -891,7 +893,8 @@ TV_Mode_string
BL SetMouseRectangle
BL FF
[ LCDPowerCtrl :LAND: :LNOT: STB
[ {FALSE} ;;; LCDPowerCtrl :LAND: :LNOT: STB
;;; mjsHAL no LCD support
;Switch the LCD on if LCD mode
Push "r0"
MOV R1, #0
......
......@@ -18,15 +18,15 @@
;
; part of Kernel/HAL division
;
; Author M Stephens
; Author Mike Stephens (mjs)
; Date Sep 2000
;;;mjsHAL
;
; vduhint is currently also a repository for VIDC20/IOMD specific HAL
; code, as stage 1 of Kernel/HAL split for video code
; eventually, vduhint should just be veneer for calls to defined HAL routines
;
; eventually, vduhint should either have any veneer code/defns or
; should disappear altogether
; temp mjs versions of macros to call HAL routines
;
......@@ -65,8 +65,10 @@
; -----------------------------------------------------------------------------------
;
; TEMP defn for workspace while code still in kernel
; layout of workspace block anchored at mjs_tempHALworkspace
;
^ 0
mjs_thalwk_start # 0
......@@ -82,6 +84,8 @@ VIDC_FSynSoftCopy # 4
VIDC_ControlSoftCopy # 4
VIDC_HSWRSoftCopy # 4 ; horizontal sync width
VIDC_VSWRSoftCopy # 4 ; vertical sync width
IOMD_VInitSoftCopy # 4
IOMD_VEndSoftCopy # 4
mjs_thalwk_end # 0
mjs_thalwk_size * mjs_thalwk_end - mjs_thalwk_start
......@@ -97,23 +101,6 @@ mjs_tempHALworkspace_init ROUT
STR lr, [r0, #VIDC_Interlace]
Pull "r0, pc"
; -----------------------------------------------------------------------------------
;;;mjsHAL - is the mode workspace really generic enough to pass to HAL?
;;;
; HAL routine
;
; int HAL_Video_VetMode(void *VIDClist, void *workspace)
;
; VIDClist -> generic video controller list (VIDC list type 3)
; workspace -> mode workspace (if mode number), or 0
; returns 0 if OK (may be minor adjusts to VIDClist and/or workspace values)
; non-zero if not OK
;
HAL_Video_VetMode ROUT
MOV r0,#0 ; do nothing for now
MOV PC,LR
; -------------------------------------------------------------------------
......@@ -240,18 +227,6 @@ DCR_HDWRShift * 0
; -------------------------------------------------------------------------
;;;mjsHAL
;;;
;;; HAL_Video_SetMode - routine for HAL to support VIDC20
;;;
;;; mjs: adapted from ProcessVIDCListType3 in old kernel
;;;
;;; this code still accesses kernel variable(s),
;;; also calls ComputeModuli
;;; also calls ProcessControlListItem
;;; so more work needed to fully divorce it
;;; put here for first stage of kernel/HAL split
;
; void HAL_Video_SetMode(const void *VIDCList3)
;
......@@ -259,6 +234,7 @@ DCR_HDWRShift * 0
;
; in: VIDClist -> video mode list (in VIDCList type 3 format)
; (and sb (r9) -> HAL workspace)
;
HAL_Video_SetMode ROUT
Push "r4, r7,r8,r10,r11, lr"
......@@ -416,6 +392,8 @@ FIFOLoadTable
LDR r0, [r3, #VIDCList3_PixelRate] ; get pixel rate
MOV r10, r0, LSL r7 ; peak mem b/w (x 1E3 bits/sec) - save for FIFO calculation
! 0, "mjsHAL - using kernel variable IOSystemType"
[ MorrisSupport
MOV R1, #0
LDRB R1, [R1, #IOSystemType]
......@@ -464,20 +442,19 @@ FIFOLoadTable
ADD R0, r11, #(&80*4) ; R0 -> VIDC20 table (remove offset for reg indices starting at &80)
BL ProgramVIDC20Regs
; now make sure video DMA enabled
;
MOV r7, #IOMD_Base
LDRB r8, [r7, #IOMD_VIDCR]
AND r8, r8, #&7F ; knock out IOMD_VIDCR_Dup
ORR r8, r8, #IOMD_VIDCR_Enable ; enable video DMA
STRB r8, [r7, #IOMD_VIDCR]
ADD sp, sp, #VIDC20ParmsSize ; drop workspace for table
Pull "r4, r7,r8,r10,r11, pc"
; -------------------------------------------------------------------------
;;;
;;; mjsHAL - code for hitting VIDC20 registers, taken from s.vdudriver
;;;
;;; eventually, need to do *TV adjustment to VIDCList3 itself before calling HAL routine
;;; other adjustments in old code, remembering things in kernel variables etc.
;;; may have to stay for this first stage, but need sorting when candidate HAL
;;; routine is really moved out of kernel
; ProgramVIDC20Regs - program registers from table
;
; entry: r0 -> VIDC table to program into registers
......@@ -492,19 +469,6 @@ ProgramVIDC20Regs ROUT
TST R4, #1
MOVNE R4, #CR_Interlace
[ STB
;;;mjsHAL - unacceptable to call SWI from HAL code, needs sorting
;;;
LDR R1, [R0, #(PseudoRegister_HClockSpeed:SHR:22)-&80*4] ; are we using HCLK?
CMP R1, #-1
Push "r0-r1"
MOVEQ R0, #1 ; if not, pull the TV_Mode GPIO line low (if present)
MOVNE R0, #3 ; if we are, pull it high
ADR R1, TV_Mode_string
SWI XPortMan_AccessBit ; (don't forget svc_PortMan below)
Pull "r0-r1"
]
MOV R7, R0 ; keep copy in R7 in case we go wrong
MOV R3, #VIDC ; R3 -> VIDC20 h/w
18
......@@ -531,13 +495,12 @@ ProgramVIDC20Regs ROUT
TEQ R6, #VIDCExternal ; check for external register (which contains syncs)
BNE %FT50
;;;mjsHAL this calls a SWI - not acceptable eventually for HAL, see comments for ReadSyncType
Push "r4"
BL ReadSyncType
Pull "r4"
BICNE R2, R2, #(Ext_HSYNCbits :OR: Ext_VSYNCbits) ; if composite sync then don't invert syncs
ORRNE R2, R2, #Ext_InvertCompVSYNC :OR: Ext_InvertCompHSYNC ; and force both syncs to be composite (because of lack of
! 0, "mjsHAL - currently assume vertical sync rather than find out (by HAL call to OS?)"
;;;
;;;mjsHAL old code that operated on NE if composite sync found from SWI OS_ReadSysInfo 1
;;;
;;; BICNE R2, R2, #(Ext_HSYNCbits :OR: Ext_VSYNCbits) ; if composite sync then don't invert syncs
;;; ORRNE R2, R2, #Ext_InvertCompVSYNC :OR: Ext_InvertCompHSYNC ; and force both syncs to be composite (because of lack of
; swap in A540 VIDC card)
B %FT75
50
......@@ -564,6 +527,8 @@ ProgramVIDC20Regs ROUT
TEQ r6, #VIDCDataControl
BNE %FT65
! 0, "mjsHAL - using kernel variable VRAMWidth"
BIC r2, r2, #DCR_BusBits
MOV r14, #0
LDRB r14, [r14, #VRAMWidth]
......@@ -631,31 +596,6 @@ ProgramVIDC20Regs ROUT
; -------------------------------------------------------------------------
;;; mjsHAL - spliced here for now (called by code above)
;;; note, we would _not_ want to call a SWI from HAL
;;; eventually, either this info is passed in to routine above, or HAL must
;;; make a call back to kernel
;;; (such calls have similar ATPCS style API, but there is no r9=workspace)
;
; ReadSyncType - Read sync type
;
; out: R4 = sync type (0 or 1)
; Z set/clear on R4
; All other registers preserved
;
ReadSyncType Entry "r0-r2"
MOV r0, #1
SWI XOS_ReadSysInfo ; out: r0 = mode, r1 = monitortype, r2 = sync
MOVS r4, r2 ; move into r4
EXIT
; -------------------------------------------------------------------------
;;; mjsHAL - ProcessControlListItem spliced here for now, not investigated deeply
;;;
;
; ProcessControlListItem
;
......@@ -683,20 +623,14 @@ ProcessControlListItem Entry
& ProcessControlListDPMSState ; 11 - DPMS state
& ProcessControlListNOP ; 12 - Interlaced mode
! 0, "mjsHAL - no LCD support (VIDCList3 control list stuff)"
ProcessControlListLCDMode
[ STB
MOV r1, #Ext_LCDGrey
|
MOV r0, #0
LDRB r1, [r0, #LCD_Active] ;Read the existing value
AND r1, r1, #&80 ;Clear all but the single/dual bit, 'cos this might have been set already
ORR r1, r1, r2 ;Bung our new lcdmode into the byte, and....
STRB r1, [r0, #LCD_Active] ;...store in the KernelWS which LCD mode we are in.
MOV r1, #Ext_ECKOn ;Set the ECLK on
CMP r2, #3 ;Was (is) it active-matrix?
ORRNE r1, r1, #Ext_LCDGrey ;If not, set the LCD greyscaler 'on'
]
;;;mjsHAL we have no support
EXIT
ProcessControlListHiResMode
MOV r1, #Ext_HiResMono ; bit of a misnomer, it's not nec. mono
05
MOV r0, #VIDCExternal
10
......@@ -709,14 +643,10 @@ ProcessControlListLCDMode
BIC lr, lr, r7 ; knock out bits in mask
ORR lr, lr, r2 ; OR in new bits
STR lr, [r11, r0, LSR #22] ; and store in array
;
ProcessControlListNOP
EXIT
ProcessControlListHiResMode
MOV r1, #Ext_HiResMono ; bit of a misnomer, it's not nec. mono
B %BT05
ProcessControlListDACControl
MOV r1, #Ext_DACsOn
B %BT05
......@@ -733,64 +663,16 @@ ProcessControlListExternalRegister
B %BT15
ProcessControlListLCDDualPanelMode
[ STB
MOV r0, #VIDCControl
MOV r1, #CR_DualPanel
B %BT10
|
MOV r0, #0
LDRB r1, [r0, #LCD_Active]
ORR r1, r1, #&80 ;Set the top bit & leave the rest as-is
STRB r1, [r0, #LCD_Active] ;Store in the KernelWS that we are in dual-panel LCD mode.
LDR r0, [r11, #VIDCDataControl :SHR: 22]
MOV r1, r0, LSL #(31-10) ;Put HDWR bits to the top
BIC r0, r0, r1, LSR #(31-10) ;knock off bits
ORR r0, r0, r1, LSR #(31-11) ;Put back one bit further up (ie mul by 2)
STR r0, [r11, #VIDCDataControl :SHR: 22]
LDR r0, [r11, #VertiDisplayEnd :SHR: 22]
LDR r1, [r11, #VertiDisplayStart :SHR: 22]
BIC r0, r0, #VertiDisplayEnd
BIC r1, r1, #VertiDisplayStart
SUB r0, r0, r1 ;R0 = Vres
ADD r1, r1, r0, LSR #1 ;R1 = Vres/2 + VDSR
ORR r1, r1, #VertiDisplayEnd
STR r1, [r11, #VertiDisplayEnd :SHR: 22]
LDR r1, [r11, #VertiCycle :SHR: 22]
BIC r1, r1, #VertiCycle
SUB r1, r1, r0, LSR #1
ORR r1, r1, #VertiCycle
STR r1, [r11, #VertiCycle :SHR: 22]
LDR r1, [r11, #VertiBorderEnd :SHR: 22]
BIC r1, r1, #VertiBorderEnd
SUB r1, r1, r0, LSR #1
ORR r1, r1, #VertiBorderEnd
STR r1, [r11, #VertiBorderEnd :SHR: 22]
LDR r1, [r11, #VIDCExternal :SHR: 22]
BIC r1, r1, #Ext_ERegExt
ORR r1, r1, #Ext_ERegGreen
STR r1, [r11, #VIDCExternal :SHR: 22]
MOV r0, #VIDCControl
MOV r1, #CR_DualPanel
B %BT10
]
;;;mjsHAL we have no support
EXIT
ProcessControlListLCDOffsetRegister0
MOV r0, #LCDOffsetRegister0
20
ORR r2, r2, r0 ; put high bits of register at top
STR r2, [r11, r0, LSR #22] ; and store in array
MOV r0, #VIDC ;ACTUALLY PROGRAM VIDC (I know I shouldn't but I don't care - I've got a cold)
STR r2, [r0]
;;;mjsHAL we have no support
EXIT
ProcessControlListLCDOffsetRegister1
MOV r0, #LCDOffsetRegister1
B %BT20
;;;mjsHAL we have no support
EXIT
ProcessControlListHClockSelect
MOV r0, #PseudoRegister_HClockSpeed ; pseudo-register holding HClock speed
......@@ -804,9 +686,6 @@ ProcessControlListDPMSState
; -------------------------------------------------------------------------
;;; mjsHAL - ComputeModuli spliced here for now, not investigated deeply
;;;
; *****************************************************************************
;
; ComputeModuli - Work out VCO moduli for a given frequency
;
......@@ -970,8 +849,6 @@ ComputeModuli Entry "r2-r12", ComputeModuliStack
; -------------------------------------------------------------------------
;
; HAL routine, implemented for VIDC20
;
; void HAL_Video_WritePaletteEntry(uint type, uint pcolour, uint index)
;
......@@ -1045,8 +922,6 @@ HV_WritePalettEntry_type1
; -------------------------------------------------------------------------
;
; HAL routine, implemented for VIDC20
;
; void HAL_Video_WritePaletteEntries(uint type, const uint *pcolours, uint index, uint Nentries)
;
......@@ -1123,8 +998,6 @@ HAL_Video_WritePaletteEntries ROUT
; -------------------------------------------------------------------------
;
; HAL routine, implemented for VIDC20
;
; uint HAL_Video_ReadPaletteEntry(uint type, uint pcolour, uint index)
;
......@@ -1196,6 +1069,12 @@ HAL_Video_SetInterlace ROUT
; DMPS = 0..3 as specified by monitor DPMSState (from mode file)
; 0 for no DPMS power saving
; HAL is expected to attempt to turn syncs off according to DPMS, and
; to turn video DMA off for blank (and therefore on for unblank) if possible.
; HAL is not expected to do anything else, eg. blank all palette entries.
; Such things are the responsibility of the OS, and also this call is expected
; to be fast. May be called with interrupts off.
HAL_Video_SetBlank ROUT
MOV r3, #VIDC
......@@ -1220,6 +1099,12 @@ HAL_Video_SetBlank ROUT
ORREQ r2, r2, #Ext_InvertHSYNC :OR: Ext_InvertVSYNC ; set sync signals to low (less power)
BIC r2, r2, #Ext_DACsOn ; turn off the DACs
STR r2, [r3]
MOV r0, #IOMD_Base
LDRB r1, [r0, #IOMD_VIDCR]
BIC r1, r1, #IOMD_VIDCR_Enable ; disable video DMA
STRB r1, [r0, #IOMD_VIDCR]
MOV pc, lr
;
; unblanking
......@@ -1234,6 +1119,12 @@ HAL_Video_SetBlank ROUT
TST r1, #2 ; if vsyncs were turned off,
LDRNE r2, [R9, #VIDC_VSWRSoftCopy] ; then restore from soft copy
STRNE r2, [r3]
MOV r0, #IOMD_Base
LDRB r1, [r0, #IOMD_VIDCR]
ORR r1, r1, #IOMD_VIDCR_Enable ; enable video DMA
STRB r1, [r0, #IOMD_VIDCR]
MOV pc, lr
; -------------------------------------------------------------------------
......@@ -1405,6 +1296,94 @@ HAL_Video_UpdatePointer
Pull "r4, r5, pc"
; -------------------------------------------------------------------------
; void HAL_Video_SetDAG(uint DAG, uint paddr)
;
; set Video DMA address generator value to given physical address
;
; DAG = 0 set start address of current video display
; 1 set start address of total video buffer
; 2 set end address (exclusive) of total video buffer
; all other values reserved
; paddr = physical address for given DAG
;
; Notes:
; The OS has a video buffer which is >= total display size, and may be using
; bank switching (several display buffers) or hardware scroll within the
; total video buffer.
;
; DAG=1 will be start address of current total video buffer
; DAG=2 will be end address (exclusive) of current total video buffer
; DAG=0 will be start address in buffer for current display
;
; HALs should respond as follows:
; 1) If they have no hardware scroll support, only DAG=0 is significant,
; and the end address of the current display is implied by the size
; of the current mode. Calls with DAG=1,2 should be ignored.
; 2) If they support hardware scroll, DAG=0 again defines display start.
; DAG=2 defines the last address (exclusive) that should be displayed
; before wrapping back (if reached within display size), and DAG=1
; defines the address to which accesses should wrap back.
HAL_Video_SetDAG ROUT
MOV r12, #IOMD_Base
CMP r0, #1
BEQ %FT20
BHI %FT40
;
; DAG=0 program VInit
;
STR r1, [r9, #IOMD_VInitSoftCopy] ; save VInit so that writes to VEnd can check
LDR r2, [r9, #IOMD_VEndSoftCopy]
CMP r1, r2 ; if VInit >= VEnd then set L bit
ORRCS r1, r1, #IOMD_DMA_L_Bit
STR r1, [r12, #IOMD_VIDINIT]
MOV pc, lr
;
; DAG=1 program VStart
;
20 STR r1, [r12, #IOMD_VIDSTART]
MOV pc, lr
! 0, "mjsHAL - using kernel variable VRAMWidth"
;
; DAG=2 program VEnd
;
40 MOV r2, #0 ; we must adjust address to that of
LDRB r2, [r2, #VRAMWidth] ; last DMA fetch, allowing for fetch size
CMP r2, #1
MOVLO r2, #16 ; DRAM-only, subtract 16 (quadword)
MOVEQ r2, #SAMLength/2 ; 1 bank of VRAM - 1/2 SAM
MOVHI r2, #SAMLength ; 2 banks of VRAM - 1/2 SAM * 2
SUB r1, r1, r2
STR r1, [r9, #IOMD_VEndSoftCopy] ; remember VEnd value
LDR r2, [r9, #IOMD_VInitSoftCopy] ; load current VInit
CMP r2, r1 ; if VInit >= VEnd
ORRCS r2, r2, #IOMD_DMA_L_Bit ; then set L bit
STR r2, [r12, #IOMD_VIDINIT] ; store VInit
STR r1, [r12, #IOMD_VIDEND] ; and VEnd
MOV pc, lr
; -------------------------------------------------------------------------
;;;mjsHAL - is the mode workspace really generic enough to pass to HAL?
;;;
;
; int HAL_Video_VetMode(const void *VIDClist, const void *workspace)
;
; VIDClist -> generic video controller list (VIDC list type 3)
; workspace -> mode workspace (if mode number), or 0
; returns 0 if OK (may be minor adjusts to VIDClist and/or workspace values)
; non-zero if not OK
;
HAL_Video_VetMode ROUT
MOV r0,#0 ; do nothing for now
MOV PC,LR
; -------------------------------------------------------------------------
END
......@@ -930,13 +930,19 @@ PV_BlankScreen ROUT
mjsCallHAL HAL_Video_SetBlank
Pull "r0, r12"
;;;mjsHAL still h/w dependency here for IOMD, needs sorting?
;;;
; 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
MOV r9, #0
WritePSRc SVC_mode+I_bit+F_bit, r14
LDR r1, [r9, #MEMC_CR_SoftCopy]
TEQ r0, #1
MOVEQ r0, #(0 :SHL: 10) :OR: (3 :SHL: 8) ; blank: video DMA off, continuous refresh
MOVNE r0, #(1 :SHL: 10) :OR: (0 :SHL: 8) ; unblank: video DMA on, no refresh
MOV r1, #(1 :SHL: 10) :OR: (3 :SHL: 8) ; bits to modify
SWI XOS_UpdateMEMC
BICEQ r1, r1, #(1 :SHL: 10)
ORRNE r1, r1, #(1 :SHL: 10)
STR r1, [r9, #MEMC_CR_SoftCopy]
RestPSR r2
BL UpdateAllPalette ; update all palette, including border + pointer
......@@ -1021,10 +1027,8 @@ PV_GammaCorrect ROUT
; out: r4 = 0
PV_LCDInvert ROUT
MOV r4, #0
STRB r0, [r4, #LCD_Inverted]
BL UpdateAllPalette
;;;mjsHAL not supported
;;;
MOV r4, #0
Pull "pc"
]
......
......@@ -355,7 +355,7 @@ UpdatePointer ROUT
MOV R0, #1 ; R0 = flags, set pointer on (bit 0 = 1)
LDR R1, [WsPtr, #PointerShapeLA] ; last shape buffer given to HAL
LDRNE R4, [R3, #PointerBuffLA] ; shape buffer we're about to give
LDR R4, [R3, #PointerBuffLA] ; shape buffer we're about to give
TEQ R1, R4 ; same as last time?
STRNE R4, [WsPtr, #PointerShapeLA] ; update
ORRNE R0, R0, #2 ; flag new shape (bit 1 = 1)
......
......@@ -1961,56 +1961,61 @@ ScrollLineDown
; *****************************************************************************
;
; SetVinit - Program Vinit with address in R0
; SetVstart - Program Vstart --------""--------
; SetVend - Program Vend --------""--------
; SetVinit - Program Vinit with address in R0
; SetVstart - Program Vstart with address in R0
; SetVendDefault - Program Vend with end address for TotalScreenSize
;
; out: R0-R2 corrupted
;
; mjs Oct 2000 kernel/HAL split
; these routines now call HAL_Video_SetDAG
; Note that the addresses provided are logical addresses for the software mapping
; of the display, and this starts at (ScreenEndAdr - TotalScreenSize) for
; wonderful historical reasons (h/w scroll, two mappings, blah, blah) - see eg. PRM 1-354
;
; To get physical address for the HAL, we subtract this software mapping start
; address and add the physical address of the start of video memory.
;
SetVstart
MOV R1, #MEMCDAG_VStart
SetLag
SUB R0, R0, #ScreenEndAdr
LDR R2, [WsPtr, #TotalScreenSize]
ADD R0, R0, R2 ; make startofscreen 0
B SetDAGOffset ; call generic interface
SUB r1, r0, #ScreenEndAdr
LDR r2, [WsPtr, #TotalScreenSize]
ADD r1, r1, r2 ; now we have offset of Vstart in video RAM
MOV r2, #0
LDR r2, [r2, #VideoPhysAddr]
ADD r1, r1, r2 ; now we have physical address of Vstart
MOV r0, #HALDAG_VStart
B Do_HALDAG
SetVendDefault
[ MEMC_Type = "IOMD"
MOV R0, #0
LDRB R0, [R0, #VRAMWidth]
CMP R0, #1
MOVLO R0, #16 ; DRAM-only, subtract 16
MOVEQ R0, #SAMLength/2 ; 1 bank of VRAM - 1/2 SAM
MOVHI R0, #SAMLength ; 2 banks of VRAM - 1/2 SAM * 2
RSB R0, R0, #ScreenEndAdr
|
MOV R0, #ScreenEndAdr
SUB R0, R0, #16
]
MOV R1, #MEMCDAG_VEnd
B SetLag
MOV r2, #0
LDR r2, [r2, #VideoPhysAddr]
LDR r1, [WsPtr, #TotalScreenSize]
ADD r1, r1, r2 ; physical address of Vend
MOV r0, #HALDAG_VEnd
B Do_HALDAG
SetVinit
STR R0, [WsPtr, #DisplayStart]
SUB R0, R0, #ScreenEndAdr
LDR R2, [WsPtr, #TotalScreenSize]
ADD R0, R0, R2 ; make start of screen 0
LDR R1, [WsPtr, #TeletextOffset]
ADD R0, R0, R1 ; add on teletext bank offset
CMP R0, R2 ; if out of range
SUBCS R0, R0, R2 ; then subtract total size
SetVinitPhys
STR R0, [WsPtr, #VinitCopy]
MOV R1, #MEMCDAG_VInit
SetDAGOffset
[ MEMC_Type = "IOMD"
MOV R2, #0
LDR R2, [R2, #VideoPhysAddr] ; add on physical address of start of video RAM
ADD R0, R0, R2
]
B SetDAG ; call generic interface
STR r0, [WsPtr, #DisplayStart]
SUB r1, r0, #ScreenEndAdr
LDR r2, [WsPtr, #TotalScreenSize]
ADD r1, r1, r2 ; now we have offset of Vinit in video RAM
LDR r0, [WsPtr, #TeletextOffset]
ADD r1, r1, r0 ; add on teletext bank offset
CMP r1, r2 ; if out of range
SUBCS r1, r1, r2 ; then subtract total size
MOV r2, #0
LDR r2, [r2, #VideoPhysAddr] ; now we have physical address
ADD r1, r1, r2
MOV r0, #HALDAG_VInit
Do_HALDAG
Push "r3, r9, r12, lr" ; we can corrupt r0-r2
mjsAddressHAL
mjsCallHAL HAL_Video_SetDAG
Pull "r3, r9, r12, lr"
MOV pc, lr
; *****************************************************************************
;
......
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