; Copyright 1996 Acorn Computers Ltd ; ; 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. ; ; > $.Source.VduDecl ; ARTHUR OPERATING SYSTEM - Vdu Drivers ; ======================= ; ; Vdu driver workspace and macro declarations ; ; Author R C Manby ; Date 5.9.86 ; GBLL ForceMark ; whether we force start of mark state ForceMark SETL {FALSE} ; of cursor on exit from WRCH GBLL RePlot ; Re-plot cursor after wrch RePlot SETL {TRUE} GBLL UseVLineOnSolidLines ; When TRUE VLine is assembled and used UseVLineOnSolidLines SETL {TRUE} ; to plot vertical solid lines GBLL AvoidScreenReads ; When TRUE, use extra code to avoid AvoidScreenReads SETL {TRUE} ; reading the screen when we can avoid it GBLL DefaultSupremacy ; When TRUE, 16bpp and 32bpp modes' default DefaultSupremacy SETL {FALSE} ; palettes use top bits for supremacy ; ; Register usage ; ============== ; StkPtr RN 13 ;Restore on exit to keep BASIC happy!! Link RN 14 ; ; Manifest constants ; ================== ; ; To change the order of mode variables, change the following:- ; a) The order of the 'wk' labels below ; b) The order of the output variables in macro VWSTAB ; c) The order of the variables in '$.Hdr.Workspace' and '$.Hdr.NewSpace' ^ 0 wkstart # 0 ; values which are calculated from sprite header when switching to sprite wkScreenSize # 4 wkXWindLimit # 4 wkYWindLimit # 4 wkLineLength # 4 wkmiddle # 0 ; values which are taken from pushed mode info (from wkmiddle ... wkmidend) wkNColour # 4 wkYShftFactor # 4 wkModeFlags # 4 wkXEigFactor # 4 wkYEigFactor # 4 wkLog2BPC # 4 wkLog2BPP # 4 wkmidend # 0 ; these are also taken from sprite header wkScrRCol # 4 wkScrBRow # 4 wkend # 0 wksize * wkend-wkstart wkwordsize * (wksize + 3) :AND: :NOT: 3 PushedInfoSize * wkwordsize + VIDCList3Size NumModes * 54 maxmode * NumModes-1 ; Reason codes for generalised DAG interface ; Layout of palette space PalEntries * 256+1+3 ^ 0 Pal_Blank # PalEntries*4 ; Blank palette (for screen saver) Pal_LogFirst # PalEntries*4 ; Logical palette (as read/written by user) Pal_LogSecond # PalEntries*4 Pal_PhysFirst # PalEntries*4 ; Physical palette (post transfer function) Pal_PhysSecond # PalEntries*4 Pal_RTable # 256 ; Logical->physical lookup tables for R,G,B,S Pal_GTable # 256 Pal_BTable # 256 Pal_STable # 256 Pal_Blocksize # 0 ; GraphicsV driver state ; For each allocated driver number, the corresponding word of GraphicsVDrivers ; points to an instance of the following structure: ^ 0 GVDriver_RegisterFlags # 4 ; Flags on registration GVDriver_Name # 4 ; Name on registration GVDriver_StateFlags # 4 ; Current state flags GVDriver_Size # 0 GVDriverState_Started * 1:SHL:0 ; ScreenMode_StartDriver called ; ; Macro Definitions ; ================= ; ; ; Macro Sort - Sort two values into increasing order ; MACRO Sort $lo, $hi CMP $hi, $lo EORLT $lo, $lo, $hi EORLT $hi, $lo, $hi EORLT $lo, $lo, $hi MEND ; ; Macro SortT - Sort two values into increasing order using a temporary reg ; MACRO SortT $lo, $hi, $temp SUBS $temp, $hi, $lo MOVLT $hi, $lo ADDLT $lo, $lo, $temp MEND ; ; Macro CompSwap - Compare and sort a pair of coordinates into ; order of increasing Y ; If Y values equal, sort in order of decreasing X ; MACRO CompSwap $xl,$yl, $xh,$yh CMP $yh, $yl EORLT $yl, $yl, $yh EORLT $yh, $yl, $yh EORLT $yl, $yl, $yh CMPEQ $xl, $xh EORLT $xl, $xl, $xh EORLT $xh, $xl, $xh EORLT $xl, $xl, $xh MEND ; ; Macro CompSwapT - Compare and sort a pair of coordinates into ; order of increasing Y ; If Y values equal, sort in order of decreasing X ; Uses a temporary register ; MACRO CompSwapT $xl,$yl, $xh,$yh, $temp SortT $yl, $yh, $temp CMPEQ $xl, $xh EORLT $xl, $xl, $xh EORLT $xh, $xl, $xh EORLT $xl, $xl, $xh MEND ; ; Macro Difference - rc := ABS(ra-rb) ; ; Test GE/LT for ra>=rb / ra<rb ; MACRO Difference $rc,$ra,$rb SUBS $rc,$ra,$rb RSBLT $rc,$rc,#0 MEND ; ; Macro Least - Select the smallest value (signed) ; MACRO Least $rc,$ra,$rb CMP $ra,$rb [ $rc = $ra | MOVLE $rc,$ra ] [ $rc = $rb | MOVGT $rc,$rb ] MEND ; ; Macro Greatest - Select the largest (signed) value ; MACRO Greatest $rc,$ra,$rb CMP $ra,$rb [ $rc = $ra | MOVGE $rc,$ra ] [ $rc = $rb | MOVLT $rc,$rb ] MEND ; ; Macro PackXtnd - pack 2 bytes into 1 word and sign extend ; MACRO PackXtnd $result,$hi,$lo [ $lo = $result ADD $result,$lo,$hi,LSL #8 MOV $result,$result,LSL #16 MOV $result,$result,ASR #16 | MOV $result,$hi,LSL #24 ORR $result,$lo,$result,ASR #16 ] MEND MACRO LoadCoordPair $x, $y, $basereg, $offset [ NoARMv4 :LOR: (($offset :AND: 1)=1) [ NoARMv6 :LOR: NoUnaligned ASSERT $x < $y [ ($offset) :AND: 3 = 2 ADD $x, $basereg, #($offset)-2 LDMIA $x, {$x, $y} ; (Xh,Xl,??,??) (??,??,Yh,Yl) MOV $x, $x, ASR #16 ; (Xs,Xs,Xh,Xl) [ NoARMv6 MOV $y, $y, LSL #16 ; (Yh,Yl, 0, 0) MOV $y, $y, ASR #16 ; (Ys,Ys,Yh,Yl) | SXTH $y, $y ; (Ys,Ys,Yh,Yl) ] | [ ($offset) :AND: 3 = 0 LDR $x, [$basereg, #$offset] ; (Yh,Yl,Xh,Xl) | [ ($offset) :AND: 3 = 1 ADD $x, $basereg, #($offset)-1 LDMIA $x, {$x, $y} ; (Yl,Xh,Xl,??) (??,??,??,Yh) MOV $x, $x, LSR #8 ; ( 0,Yl,Xh,Xl) ORR $x, $x, $y, LSL #24 ; (Yh,Yl,Xh,Xl) | ADD $x, $basereg, #($offset)-3 LDMIA $x, {$x, $y} ; (Xl,??,??,??) (??,Yh,Yl,Xh) MOV $x, $x, LSR #24 ; ( 0, 0, 0,Xl) ORR $x, $x, $y, LSL #8 ; (Yh,Yl,Xh,Xl) ] ] MOV $y, $x, ASR #16 ; (Ys,Ys,Yh,Yl) [ NoARMv6 MOV $x, $x, LSL #16 ; (Xh,Xl, 0, 0) MOV $x, $x, ASR #16 ; (Xs,Xs,Xh,Xl) | SXTH $x, $x ; (Xs,Xs,Xh,Xl) ] ] | ; Use unaligned loads from ARMv6 LDRSH $x, [$basereg, #$offset] LDRSH $y, [$basereg, #($offset)+2] ] | ; Aligned halfwords LDRSH $x, [$basereg, #$offset] LDRSH $y, [$basereg, #($offset)+2] ] MEND ; ; Macro SaveRetAdr - Push R14 to our pseudo stack ; MACRO SaveRetAdr Push R14 MEND ; ; Macro Return - Pull from stack into PC ; MACRO Return $cond LDR$cond PC, [StkPtr], #4 MEND ; ; Macro WINDow - Compare coordinate against graphics window ; ; Test GE/LT for within/outside window ; MACRO WINDow $rx,$ry, $rl,$rb,$rr,$rt ; ASSERT ($rl < $rb) AND ($rb < $rr) AND ($rr < $rt) ADD $rt,WsPtr,#GWLCol LDMIA $rt,{$rl,$rb,$rr,$rt} CMP $rx,$rl CMPGE $rr,$rx CMPGE $ry,$rb CMPGE $rt,$ry MEND ; ; Macro WindowRes - Window a coordinate, giving status word ; ; Result word is as follows: ; ; | | ; 1001 | 1000 | 1010 ; | | ; -----+------+----- GWTRow ; | | ; 0001 | 0000 | 0010 ; | | ; -----+------+----- GWBRow ; | | ; 0101 | 0100 | 0110 ; | | ; ; GWLCol GWRCol ; ; MACRO WindowRes $result, $rx,$ry, $rl,$rb,$rr,$rt ; ASSERT ($rl < $rb) AND ($rb < $rr) AND ($rr < $rt) MOV $result,#0 ADD $rt,WsPtr,#GWLCol LDMIA $rt,{$rl,$rb,$rr,$rt} CMP $rx,$rl ORRLT $result,$result,#1 ;Set bit 0 if X < window CMP $rr,$rx ORRLT $result,$result,#2 ;Set bit 1 if X > window CMP $ry,$rb ORRLT $result,$result,#4 ;Set bit 2 if Y < window CMP $rt,$ry ORRLT $result,$result,#8 ;Set bit 3 if Y > window MEND MACRO $lab EQUB $var ASSERT $var >= &00 ASSERT $var <= &FF $lab = $var MEND MACRO OrrEor $d,$s, $or,$eor ORR $d,$s,$or EOR $d,$d,$eor MEND MACRO ;Scr:=ScrOR(oraANDmsk)EOR(eorANDmsk) OrrEorMASK $scr,$msk, $ora,$eor, $tmp AND $tmp,$msk,$ora ORR $scr,$scr,$tmp AND $tmp,$msk,$eor EOR $scr,$scr,$tmp MEND MACRO ORoreorEORoreor $d,$s, $oo,$eo,$oe,$ee, $tmp OrrEor $tmp,$s, $oo,$eo ORR $d,$d,$tmp OrrEor $tmp,$s, $oe,$ee EOR $d,$d,$tmp MEND MACRO ORoreorEORoreorMASK $d,$s,$m, $oo,$eo,$oe,$ee, $tmp OrrEor $tmp,$s, $oo,$eo AND $tmp,$tmp,$m ORR $d,$d,$tmp OrrEor $tmp,$s, $oe,$ee AND $tmp,$tmp,$m EOR $d,$d,$tmp MEND MACRO ShiftR $d,$e, $r,$rcomp MOV $d,$d,LSR $r ORR $d,$d,$e,LSL $rcomp MEND MACRO ShiftL $d,$e, $r,$rcomp MOV $e,$e,LSL $rcomp ORR $e,$e,$d,LSR $r MEND MACRO BitLOffset $b,$x, $xshftfactor,$npix,$log2bpc AND $b,$x,$npix MOV $b,$b,LSL $log2bpc MEND MACRO BitROffset $b,$x, $xshftfactor,$npix,$log2bpc AND $b,$x,$npix ADD $b,$b,#1 MOV $b,$b,LSL $log2bpc SUB $b,$b,#1 MEND MACRO WordOffset $w,$x, $xshftfactor,$npix,$log2bpc MOV $w,$x,ASR $xshftfactor MEND MACRO OffsetWordAndBit $o,$b,$x,$tmp LDR $tmp,[WsPtr,#XShftFactor] MOV $o,$x,ASR $tmp ;Word offset into scanline LDR $tmp,[WsPtr,#NPix] AND $b,$x,$tmp ;Pixel offset into word LDR $tmp,[WsPtr,#Log2BPC] MOV $b,$b,LSL $tmp ;Bit offset into word MEND MACRO $label ErrorMsg $num,$string $label DCD $num DCB "$string", 0 ALIGN MEND ; ; Macro when given a register will return the state to indicate ; if we are in a graphics mode. Originally lots of code used to simply ; load NPix and look for a null parameter (fair enough in 1-8 bit per pixel) ; but now we look at the mode flags, the choice of a new generation! ; MACRO $label GraphicsMode $scrap $label LDR $scrap, [WsPtr, #ModeFlags] TST $scrap, #ModeFlag_NonGraphic ;NE then non-graphic mode! MEND END