; 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.VduGrafF ; ; ARTHUR OPERATING SYSTEM - Vdu Drivers ; ======================= ; ; Vdu driver code - Solid & Dotted Line drawing routines ; ; Author R C Manby ; Date 27.10.86 ; ; ; ; ;------------------------------------------------------------------------------ ; ; DoOsbyte163_242 - Set dotted line length and return status information ; =============== ; ; We are only interested in OsByte 163,242,0..66 ; ; OsByte 163,242,0..64 set dotted line length ; 163,242,0 set default dot pattern and length ; 163,242,1..64 set specified pattern length ; ; OsByte 163,242,65 return graphics status ; returns R1 = &Cn (means GXR on & flood on (for GXR)) ; (means SpriteRom on (for master/compact)) ; n = dotted line length MOD 64 ; R2 = number of sprite pages ; ; OsByte 163,242,66 return sprite status ; returns R1 = R2 = 0 if no sprite selected ; R1 = current sprite width ; R2 = current sprite height ; ; When entered, we know it is FX 163,242,n ; Exit by MOV PC, R14 if still don't understand (ie n>66) ; Otherwise exit with Pull PC DoOsbyte163_242 ROUT CMP R2,#66 MOVHI PC, R14 ; Not 0..66, so pass it on Push "R3-R12" ; Preserve the world VDWS WsPtr ; Point R12 at Vdu driver workspace CMP R2,#65 BLLT SetPatLength ; R2 holds 0/1..64 ; PSR preserved BLT OsByte_QuitA BGT OsByte163_242_66 OsByte163_242_65 ; OsByte 163,242,65 - graphics status LDR R1,[WsPtr,#DotLineLength] AND R1,R1,#&3F ; Dot count MOD 64 ORR R1,R1,#&C0 ; GXR on, Flood on LDR R2,[WsPtr,#SpAreaStart] CMP R2,#0 LDRNE R2,[R2,#saEnd] ; SpriteWS size B OsByte_QuitA OsByte163_242_66 ; OsByte 163,242,66 - sprite status MOV R0,#SpriteReason_ReadSpriteSize LDR R2,=SpChooseName ADD R2,R2,WsPtr ; Sprite name ptr SWI XOS_SpriteOp MOVVS R1,#0 ; If no sprite memory, or no sprite MOVVS R2,#0 ; chosen, return 0,0 as width,height MOVVC R1,R3 ; else return width,height in pixels MOVVC R2,R4 OsByte_QuitA Pull "R3-R12,PC" ; restore registers and claim call ; ; ; ;------------------------------------------------------------------------------ MACRO WriteToScreen $Adr,$Msk,$Ecf, $a,$b,$c LDMIA $Ecf,{$a,$b} AND $a,$a,$Msk AND $b,$b,$Msk [ AvoidScreenReads CMP $a,#&FFFFFFFF LDRNE $c,[$Adr] | LDR $c,[$Adr] ] ORR $c,$c,$a EOR $c,$c,$b STR $c,[$Adr] MEND ; ; ; ;------------------------------------------------------------------------------ rXCnt RN 0 rYCnt RN 1 rBres RN 2 rDeltaY RN 3 rPixShft RN 4 rScrAdr RN 5 rPixMsk RN 6 rDotPtr RN 7 rEcfPtr RN 8 rEcfBase RN 8 rEcfIndx RN 9 rDeltaX RN 10 rScanStp RN 11 rDotCnt RN 9 rDotPatLSW RN 10 rDotPatMSW RN 11 rDOTCnt RN 10 rDOTPatLSW RN 11 rDOTPatMSW RN 14 ; ;------------------------------------------------------------------------------ ; ; LineDraw - General line drawing routine ; ======== ; ; On entry, ICursor is the start point of the line ; NewPt is the end point ; ; R2 holds plot code, where bits mean :- ; bit 5 clear/set - include/exclude initial point ; bit 4 clear/set - solid/dotted line ; bit 3 clear/set - include/exclude final point ; ; bit 5 implies - restart/continue dot pattern ; LineDrawSolid TST R2, #&03 ; if a no action one MOVEQ PC, R14 ; then do nowt, just shunt coords LineDrawDotted ROUT EOR R11, R2, #&18 ; Flip solid/dotted flag, and final point flag ; bit 4 set/clear - solid/dotted line ; bit 3 set/clear - include/exclude final point MOV R9, #0 ADD R10, WsPtr, #LineDotCnt TST R11, #&10 STRNE R9, [WsPtr, #LineDotPtr] ; Solid line STREQ R10, [WsPtr, #LineDotPtr] ; Dotted line TSTEQ R11, #&20 ; If dotted line & first point included STREQ R9, [WsPtr, #LineDotCnt] ; then force a restart of the pattern STR R9, [WsPtr, #PostCycleCount] ; Assume all dots get plotted ADD R0,WsPtr,#GCsIX ;Start ICursor LDMIA R0,{R0,R1,R2,R3} ;End NewPt TEQ R1, R3 ; If line is horizontal BEQ TryHLine ; try to use HLine [ UseVLineOnSolidLines TEQ R0, R2 ; If line is vertical BEQ TryVLine ; try to use VLine CantUseVLine ] CantUseHLineOrVLine SaveRetAdr Difference R4,R0,R2 Difference R5,R1,R3 Greatest R10,R4,R5 ADD R10,R10,#1 ;Total number of dots on line BL GenLineParm ;Generate line control block ; in R0..R8 TST R11,#&20 ;If first point excluded SUBNE R10,R10,#1 ; then dec DotCycleCount and BLNE AdvLineParm ; advance to first pixel and TST R11,#&08 ;If last point excluded SUBEQ R10,R10,#1 ; then dec DotCycleCount CMP R10,#0 ;IF DotCycleCount <= 0 Return LE ; then nothing to plot STR R10,[WsPtr,#DotCycleCount] STR R11,[WsPtr,#LineEndPtFlags] WINDow R0,R1, R9,R10,R11,R14 ;If start point outside window BLLT LineStartsOutsideWindow ; then panic {won't return if whole ; line outside window} WINDow R7,R8, R9,R10,R11,R14 ;If end point outside window BLLT LineEndsOutsideWindow ; then panic as well ; ; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ; StartX,StartY,Bres,DeltaX,DeltaY,StepX,StepY ; ;Modify StepX (+1/-1 means right/left) CMP R5,#0 ; to give PixelMask shift factor LDR R5,[WsPtr,#BytesPerChar] ; "Left" RSBPL R5,R5,#0 ; "Right" ;Modify StepY (+1/-1 means up/down) CMP R6,#0 ; to give offset to next scan line LDR R6,[WsPtr,#LineLength] ; "Down" RSBPL R6,R6,#0 ; "Up" Push "R2-R6" ;Bres,DeltaX,DeltaY,StepX,StepY BL ScreenAddr MOV R7,R2 ;Screen Adr MOV R8,R3 ;Pixel Mask LDR R9,[WsPtr, #YWindLimit] SUB R9,R9,R1 ;subtract Y from YWindLimit AND R9,R9,#7 ;EcfIndx Pull "R2-R6" ;Bres,DeltaX,DeltaY,StepX,StepY LDR R0,[WsPtr,#DotCycleCount] ;Number of on screen pixels CMP R0,#0 ; An LPO line starting outside & ending Return LE ; on the window leaves zero dots! LDR R1,[WsPtr,#LineDotPtr] CMP R1,#0 BNE DotDashLine SolidLine ROUT Push R12 LDR R1, [WsPtr, #GColAdr] ; Base address of ECF ADD R1, R1, R9, LSL #3 ; current address of ECF ; ; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R9 ; PixCnt,EcfBase,Bres,DeltaX,DeltaY,MskShft,LineStp,ScrAdr,Mask,Indx ; LDMIA R1, {R9, R10} ; R9 = zgora; R10 = zgeor 20 MOV R12, R8 30 SUBS R0, R0, #1 ; Dec pixel count BEQ %FT57 ; if zero, then finish off 40 ; Advance the screen address and pixel mask one pixel TEQ R2, #0 ; If Bres positive BPL %FT55 ; then advance in X dirn only ; else advance in Y direction, which ; may involve advancing X afterwards 45 AND R14, R9, R12 ; R14 = zgora AND pixmask [ AvoidScreenReads CMP R14, #&FFFFFFFF LDRNE R11, [R7] ; R11 = word from screen | LDR R11, [R7] ; R11 = word from screen ] ORR R11, R11, R14 ; OR with screen AND R14, R10, R12 ; R14 = zgeor AND pixmask EOR R11, R11, R14 ; EOR with screen STR R11, [R7], R6 ; and store back, moving on CMP R6, #&80000000 ; C=1 => going up the screen TSTCS R1, #63 ; so check being at word 0 of ECF SUBCS R1, R1, #8 ; and then subtract 2 words ADDCC R1, R1, #8 ; else add on 2 words first TSTCC R1, #63 ; and then test for wrap BEQ %FT60 LDMIA R1, {R9, R10} ; reload zgora and zgeor ADDS R2, R2, R3 ; Advance Bres, in Y dirn BMI %BT20 ; [don't need to move in X direction] 50 MOV R12, #0 ; clear total pixel mask 55 ; ; Advance in X direction ; CMP R5, #&80000000 ; if +ve then RORing, so test if TSTCC R8, #1 ; bottom bit set before shifting MOV R8, R8, ROR R5 ; shift word TSTCS R8, #1 ; else test after shifting SUB R2, R2, R4 ; always advance Bres in X direction ORREQ R12, R12, R8 ; if not wrapped, OR in new pixel BEQ %BT30 ; and loop 57 [ AvoidScreenReads TEQ R12, #0 BEQ %FT58 ] AND R14, R9, R12 ; R14 = zgora AND pixmask [ AvoidScreenReads MVNS R11, R14 LDRNE R11, [R7] ; R11 = word from screen | LDR R11, [R7] ; R11 = word from screen ] ORR R11, R11, R14 ; OR with screen AND R14, R10, R12 ; R14 = zgeor AND pixmask EOR R11, R11, R14 ; EOR with screen [ AvoidScreenReads STR R11, [R7] ; and store back 58 SUBCC R7, R7, #4 ; increment or decrement ADDCS R7, R7, #4 | STRCC R11, [R7], #-4 ; and store back STRCS R11, [R7], #4 ; incrementing or decrementing ] MOV R12, R8 ; reset total pixel mask SUBS R0, R0, #1 Pull "R12, PC", LT ; exit if COMPLETELY finished BEQ %BT57 ; if no more to do, then output word! TEQ R2, #0 ; test Bres again BPL %BT55 B %BT45 ; come here when ECF wraps (ie every eight Y coords) 60 ADDCS R1, R1, #64 ; if wrap and going up, then add 64 SUBCC R1, R1, #64 ; if wrap and going down, subtract 64 LDMIA R1, {R9, R10} ; reload zgora and zgeor ADDS R2, R2, R3 ; Advance Bres, in Y dirn BMI %BT20 ; [don't need to move in X direction] B %BT50 ; ***************************************************************************** ; ; TryHLine - Try to use HLine (we already know Y1=Y2) ; ; in: R0 = X1 ; R1 = R3 = Y ; R2 = X2 ; R11 = plot code EOR &18 ; bit 3 set => include last point ; bit 4 set => solid ; bit 5 set => exclude first point ; TryHLine ROUT TST R11, #&10 ; is it dotted BEQ CantUseHLineOrVLine ; yes, then can't use HLine CMP R2, R0 MOVGE R4, #1 MOVLT R4, #-1 TST R11, #&20 ; if first point excluded ADDNE R0, R0, R4 ; then move R0 one pixel towards R2 TST R11, #&08 ; if last point excluded SUBEQ R2, R2, R4 ; then move R2 one pixel towards R0 CMP R2, R0 ; check order again EORLT R0, R0, R2 ; make sure R0 <= R2 EORLT R2, R0, R2 EORLT R0, R0, R2 RSBLT R4, R4, #0 ; if swapped, then invert sign of R4 TEQNE R4, #1 ; if order is now different ; (and they're not equal now) MOVNE PC, R14 ; then there's nothing to plot B NewHLine ; else go and do it! ; ***************************************************************************** ; ; TryVLine - Try to use VLine (we already know X1=X2) ; ; in: R0 = R2 = X ; R1 = Y1 ; R3 = Y2 ; R11 = plot code EOR &18 ; bit 3 set => include last point ; bit 4 set => solid ; bit 5 set => exclude first point ; TryVLine ROUT TST R11, #&10 ; is it dotted BEQ CantUseHLineOrVLine ; yes, then can't use VLine (or HLine) ; now make sure that we are using a solid pattern (not an ECF) ; this is true if the appropriate GCOL action is < 8 AND R4, R11, #3 ; look at bottom 2 bits of R11 CMP R4, #2 ; to check which action ; (already ruled out 0 (no action)) LDRCC R4, [WsPtr, #GPLFMD] ; <2 => 1 => foreground action MOVEQ R4, #4 ; =2 => 2 => invert action LDRHI R4, [WsPtr, #GPLBMD] ; >2 => 3 => background action CMP R4, #8 ; is it a solid action BCS CantUseVLine CMP R3, R1 MOVGE R4, #1 MOVLT R4, #-1 TST R11, #&20 ; if first point excluded ADDNE R1, R1, R4 ; then move R1 one pixel towards R3 TST R11, #&08 ; if last point excluded SUBEQ R3, R3, R4 ; then move R3 one pixel towards R1 CMP R3, R1 ; check order again EORLT R1, R1, R3 ; make sure R1 <= R3 EORLT R3, R1, R3 EORLT R1, R1, R3 RSBLT R4, R4, #0 ; if swapped, then invert sign of R4 TEQNE R4, #1 ; if order is now different ; (and they're not equal now) MOVNE PC, R14 ; then there's nothing to plot B NewVLine ; else go and do it! ; ; ; DotDashLine ; ; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R9 ; PixCnt,DotPtr,Bres,DeltaX,DeltaY,MskShft,LineStp,ScrAdr,Mask,Indx ; DotDash20 LDMIA R1,{rDOTCnt,rDOTPatLSW,rDOTPatMSW} CMP rDOTCnt,#0 ADDEQ rDOTCnt,WsPtr,#DotLineStyle ;Restart pattern LDMEQIA rDOTCnt,{rDOTPatLSW,rDOTPatMSW} LDREQ rDOTCnt,[WsPtr,#DotLineLength] SUB rDOTCnt,rDOTCnt,#1 MOVS rDOTPatMSW,rDOTPatMSW,LSL #1 ORR rDOTPatMSW,rDOTPatMSW,rDOTPatLSW,LSR #31 MOV rDOTPatLSW,rDOTPatLSW,LSL #1 STMIA R1,{rDOTCnt,rDOTPatLSW,rDOTPatMSW} BCC DotDash30 ;Don't plot this dot LDR R10,[WsPtr,#GColAdr] ;Base address of ECF ADD R10,R10,R9,LSL #3 ;Address of ECFora & ECFeor WriteToScreen R7,R8,R10, R10,R11,R14 DotDash30 SUBS R0,R0,#1 ;Dec pixel count BEQ DotDash60 ;Finished on screen DotDash40 ; ; Advance the screen address and pixel mask one pixel ; CMP R2,#0 ;If Bres positive BPL DotDash50 ;then advance in X dirn only ;else advance in Y direction, which may ; involve advancement in X afterwards CMP R6,#0 ;Advance Ecf to next scanline SUBLT R9,R9,#1 ; "Up" = (Old-1) Mod 7 ADDGE R9,R9,#1 ; "Doun" = (Old+1) Mod 7 AND R9,R9,#7 ADD R7,R7,R6 ;Advance screen address one scanline ADDS R2,R2,R3 ;Advance Bres, in Y dirn BMI DotDash20 ; ; may now need advancing in X dirn DotDash50 ; ; Advance in X direction ; ; Rotate PixMsk to next pixel position, altering ScrAdr if we cross to ; the next word. ; TST R8, R5 ;If PixMsk at MSEnd of word ; and shifting left ADDMI R7, R7, #4 ;then inc ScrAdr {PixMsk will wrap} MOVS R8, R8, ROR R5 ;Move PixMsk ;If PixMsk now at MSEnd of word RSBMIS R11, R5, #0 ; and shift was right SUBMI R7, R7, #4 ;then dec ScrAdr {PixMsk wrapped} SUB R2, R2, R4 ;Advance Bres, in X dirn B DotDash20 DotDash60 LDR R0,[WsPtr,#PostCycleCount] CMP R0,#0 BLNE AdvanceDotPattern Return LTORG DCD 0 ; *** Inserted for diagnostic purposes ! *** ; ; ; ;------------------------------------------------------------------------------ ; ; LineEndsOutSideWindow ; ===================== ; LineEndsOutsideWindow Push "R0-R8,Link" ;Push whole parameter block ADD R0,WsPtr,#GCsIX ;Start ICursor LDMIA R0,{R0,R1,R2,R3} ;End NewPt Swap R0,R2 Swap R1,R3 BL GenLineParm ;Generate line control block ; in R0..R8 LDR R11,[WsPtr,#LineEndPtFlags] TST R11,#&08 ;If last point excluded BLEQ AdvLineParm ; then advance to actual last point Push "R0,R1" ;EndX,EndY WindowRes R11,R0,R1, R7,R8,R9,R10 ;R11 := Window(End) ; ; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 , ,R11 ; EndX,EndY,Bres,DeltaX,DeltaY,StepX,StepY, ,WEnd ; TST R11,#&C ;If above/below window BEQ LEO10 BL InYWind ; then bring Y into window WindowRes R11,R0,R1, R7,R8,R9,R10 ;R11 := Window(NewEnd) LEO10 TST R11,#&3 BEQ LEO20 ;If start outside X window BL InXWind WindowRes R11,R0,R1, R7,R8,R9,R10 ;R11 := Window(NewEnd) LEO20 Pull "R9,R10" ;EndX,EndY Difference R0,R0,R9 Difference R1,R1,R10 Greatest R0,R0,R1 LDR R1,[WsPtr,#DotCycleCount] SUB R1,R1,R0 STR R1,[WsPtr,#DotCycleCount] STR R0,[WsPtr,#PostCycleCount] Pull "R0-R8,PC" ; ; ; ;------------------------------------------------------------------------------ ; ; LineStartsOutSideWindow ; ======================= ; LineStartsOutsideWindow Push Link Push "R0,R1" ;StartX,StartY Push "R5,R6" WindowRes R10,R0,R1, R5,R6,R9,R14 ;R10 := Window(Start) WindowRes R11,R7,R8, R5,R6,R9,R14 ;R11 := Window(End) Pull "R5,R6" TST R10,R11 BNE LineOutsideWindow ;Line completely outside window ; ; R0 ,R1 ,R2 ,R3 ,R4 ,R5 ,R6 ,R7 ,R8 ,R10 ,R11 ; StartX,StartY,Bres,DeltaX,DeltaY,StepX,StepY,EndX,EndY ,WStart,WEnd ; TST R10,#&C ;If above/below window BEQ LSO10 Push R11 BL InYWind ; then bring Y into window Pull R11 Push "R6-R8" WindowRes R10,R0,R1, R6,R7,R8,R9 ;R10 := Window(NewStart) Pull "R6-R8" TST R10,R11 BNE LineOutsideWindow ;Line completely outside window LSO10 TST R10,#&3 BEQ LSO20 ;If start outside X window Push R11 BL InXWind Pull R11 Push "R6-R8" WindowRes R10,R0,R1, R6,R7,R8,R9 ;R10 := Window(NewStart) Pull "R6-R8" CMP R10,#0 BNE LineOutsideWindow ;Cannot clip to window LSO20 Pull "R9,R10" ;StartX,StartY Push "R0-R8" Difference R0,R0,R9 Difference R1,R1,R10 Greatest R0,R0,R1 BL AdvanceDotPattern Pull "R0-R8" Pull "PC" LineOutsideWindow Pull "R0,R1" ;Balance the stack LDR R0,[WsPtr,#DotCycleCount] BL AdvanceDotPattern Pull "Link" Return ;To caller of the line routine ; ; ; ;------------------------------------------------------------------------------ ; lpStartX RN 0 lpStartY RN 1 lpBres RN 2 lpDeltaX RN 3 lpDeltaY RN 4 lpStepX RN 5 lpStepY RN 6 ; ; InYWind - Bring a set of line parameters into the Y window ; ======= ; ; On entry, R0-R6 contain a line parameter block ; R0 - StartX ; R1 - StartY ; R2 - Bres ; R3 - DeltaX ; R4 - DeltaY ; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) ; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) ; R7 - EndX ; R8 - EndY ; ; R9 - gwbrow ; R10 - gwtrow ; ; Algorithm: ; 1. Calculate distance to Y window ; 2. Change StartY by (distance-1) ; 3. Add (distance-1)*DeltaX to Bres ; 4. Divide Bres by DeltaY ; 5. Subtract (quotient+1)*DeltaY from Bres ; 6. Change StartX by (quotient+1) ; 7. Do one more pixel advance by AdvLineParm ; (N.B. this is always the Bres -ve case) ; ; ; InYWind SaveRetAdr LDR R9,[WsPtr,#GWBRow] LDR R10,[WsPtr,#GWTRow] ;(1) CMP lpStepY,#0 SUBGE R11,R9,lpStartY SUBLT R11,lpStartY,R10 SUB R11,R11,#1 ;(Distance to window) - 1 BL InYW30 ;Steps 2-6 BL AdvLineParm ;Step to first pixel in window Return ; ; Flags still valid, GE/LT ; ; R11 holds distance to window -1 ; InYW30 ;(2) ADDGE lpStartY,lpStartY,R11 ;StartY := GWBRow-1 SUBLT lpStartY,lpStartY,R11 ;StartY := GWTRow+1 ;(3) MOV R10,lpDeltaX MUL R9,R11,R10 ADDS lpBres,lpBres,R9 ;Bres := Bres+(dist-1)*DeltaX ;If lpBres now -ve, MOVLT PC,Link ;then don't modify StartX ; (quotient+1 is 0) ;else MOV R10,lpDeltaY ; *****Change made by DJS ; Use new DivRem macro, not old DIVREM ; Original code was: ; DIVREM R11,lpBres,R10,R9 DivRem R11,lpBres,R10,R9 ; *****End of change made by DJS SUB lpBres,lpBres,lpDeltaY ADD R11,R11,#1 ; quotient := 1+bres/deltay ;(6) CMP lpStepX,#0 ADDGE lpStartX,lpStartX,R11 SUBLT lpStartX,lpStartX,R11 MOV PC,Link ; ; InXWind - Bring a set of line parametres into the X window ; ======= ; ; On entry, R0-R6 contain a line parameter block ; R0 - StartX ; R1 - StartY ; R2 - Bres ; R3 - DeltaX ; R4 - DeltaY ; R5 - StepX (+1/-1) (Equv bit6 of Sign in 6502 version) ; R6 - StepY (+1/-1) (Equv bit7 of Sign in 6502 version) ; R7 - EndX ; R8 - EndY ; ; R9 - gwlcol ; R10 - gwrcol ; ; Algorithm: ; 1. Replace Bres by -Bres-1 ; 2. Swap StartX and StartY ; 3. Swap DeltaX and DeltaY ; 3a Swap StepX and StepY ; 4. Calculate distance to X window ; 5. Do steps 2-6 of InYWind ; 6. Repeat steps 1-3 ; 7. Do one more pixel advance by AdvLineParm ; (N.B. this is always the Bres +ve case) ; InXWind SaveRetAdr LDR R9,[WsPtr,#GWLCol] LDR R10,[WsPtr,#GWRCol] ;(1) MVN lpBres,lpBres ;(2)(3) Push "lpStartX,lpDeltaX,lpStepX" Push "lpStartY,lpDeltaY,lpStepY" Pull "lpStartX,lpDeltaX,lpStepX" Pull "lpStartY,lpDeltaY,lpStepY" CMP lpStepY,#0 ;Really StepX SUBGE R11,R9,lpStartY SUBLT R11,lpStartY,R10 SUB R11,R11,#1 ;(Distance to window) - 1 BL InYW30 ;Steps 2-6 ;(1) MVN lpBres,lpBres ;(2)(3) Push "lpStartX,lpDeltaX,lpStepX" Push "lpStartY,lpDeltaY,lpStepY" Pull "lpStartX,lpDeltaX,lpStepX" Pull "lpStartY,lpDeltaY,lpStepY" BL AdvLineParm ;Step to first pixel in window Return ; ; rDotPtr RN 7 ; rDotCnt RN 9 ; rDotPatLSW RN 10 ; rDotPatMSW RN 11 ; ; On entry R0 holds number of places to step dot pattern ; AdvanceDotPattern LDR R1,[WsPtr,#DotCycleCount] SUB R1,R1,R0 STR R1,[WsPtr,#DotCycleCount] LDR rDotPtr,[WsPtr,#LineDotPtr] CMP rDotPtr,#0 MOVEQ PC,Link LDR R1,[WsPtr,#DotLineLength] MOV R2,R1 ; *****Change made by DJS ; Use new DivRem macro, not old DIVREM ; Original code was: ; DIVREM R3,R0,R2,R4 ;R0:=R0 REM DotLineLength DivRem R3,R0,R2,R4 ;R0:=R0 REM DotLineLength ; *****End of change made by DJS LDMIA rDotPtr,{rDotCnt,rDotPatLSW,rDotPatMSW} CMP rDotCnt,R0 SUBLT R0,R0,rDotCnt ADDLT rDotCnt,WsPtr,#DotLineStyle ;Restart pattern LDMLTIA rDotCnt,{rDotPatLSW,rDotPatMSW} LDRLT rDotCnt,[WsPtr,#DotLineLength] SUB rDotCnt,rDotCnt,R0 ;New value [ {TRUE} ; need special code if R0 > 32 RSBS R1, R0, #32 MOVLT rDotPatMSW, rDotPatLSW MOVLT rDotPatLSW, #0 ; probably not necessary SUBLT R0, R0, #32 RSBLT R1, R0, #32 MOV rDotPatMSW,rDotPatMSW,LSL R0 ORR rDotPatMSW,rDotPatMSW,rDotPatLSW,LSR R1 MOV rDotPatLSW,rDotPatLSW,LSL R0 | ; old code RSB R1,R0,#32 MOV rDotPatMSW,rDotPatMSW,LSL R0 ORR rDotPatMSW,rDotPatMSW,rDotPatLSW,LSR R1 MOV rDotPatLSW,rDotPatLSW,LSL R0 ] STMIA rDotPtr,{rDotCnt,rDotPatLSW,rDotPatMSW} MOV PC,Link ; ;--------------------------------------------------------------------------- ; END