From fa159ee5eec87c1efe529e8de0f1e1baa4171d36 Mon Sep 17 00:00:00 2001 From: Mike Stephens <mstephen@gitlab.riscosopen.org> Date: Thu, 5 Oct 2000 11:55:13 +0000 Subject: [PATCH] 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' --- VersionASM | 12 +- VersionNum | 16 +-- hdr/KernelWS | 14 ++- s/ARM600 | 134 ++++---------------- s/vdu/vdudecl | 10 +- s/vdu/vdudriver | 31 ++--- s/vdu/vduhint | 311 ++++++++++++++++++++++------------------------- s/vdu/vdupalxx | 24 ++-- s/vdu/vdupointer | 2 +- s/vdu/vduwrch | 87 ++++++------- 10 files changed, 276 insertions(+), 365 deletions(-) diff --git a/VersionASM b/VersionASM index 4d38de21..97cf8ae4 100644 --- a/VersionASM +++ b/VersionASM @@ -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 diff --git a/VersionNum b/VersionNum index 69df788d..b689cf6c 100644 --- a/VersionNum +++ b/VersionNum @@ -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)" diff --git a/hdr/KernelWS b/hdr/KernelWS index 6f0fa693..40b3d330 100644 --- a/hdr/KernelWS +++ b/hdr/KernelWS @@ -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 diff --git a/s/ARM600 b/s/ARM600 index 85ce92b7..70f3e545 100644 --- a/s/ARM600 +++ b/s/ARM600 @@ -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 diff --git a/s/vdu/vdudecl b/s/vdu/vdudecl index a48b7718..0558b07e 100644 --- a/s/vdu/vdudecl +++ b/s/vdu/vdudecl @@ -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 diff --git a/s/vdu/vdudriver b/s/vdu/vdudriver index 8ce6a02c..10804940 100644 --- a/s/vdu/vdudriver +++ b/s/vdu/vdudriver @@ -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 diff --git a/s/vdu/vduhint b/s/vdu/vduhint index 6c3d8865..8e912a88 100644 --- a/s/vdu/vduhint +++ b/s/vdu/vduhint @@ -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 diff --git a/s/vdu/vdupalxx b/s/vdu/vdupalxx index e40621cd..43624820 100644 --- a/s/vdu/vdupalxx +++ b/s/vdu/vdupalxx @@ -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" ] diff --git a/s/vdu/vdupointer b/s/vdu/vdupointer index 97313756..8ab1db42 100644 --- a/s/vdu/vdupointer +++ b/s/vdu/vdupointer @@ -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) diff --git a/s/vdu/vduwrch b/s/vdu/vduwrch index 81a33614..07df50d2 100644 --- a/s/vdu/vduwrch +++ b/s/vdu/vduwrch @@ -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 ; ***************************************************************************** ; -- GitLab