Jump to content

flashjazzcat

Members
  • Content Count

    17,025
  • Joined

  • Last visited

  • Days Won

    25

Everything posted by flashjazzcat

  1. I can't. Candle wrote the SIDE loader and I know little of the detail of its inner workings.
  2. I wouldn't post updates if I didn't NEED feedback to stay motivated.
  3. Been coding like a man possessed and managed to get the rectangle lists working: I haven't yet limited redrawing to the "dirty" region (i.e. the area of the desktop exposed by the moved window) - this is just a test to ensure the rectangles redraw properly. You can see that the smaller exposed areas of the desktop background redraw faster than others, since all that's being redrawn is that very small rectangle. Lots of tweaking to do, but I'm pleased to have got this working in two days. Next job is to clip desktop redrawing to the intersections of the desktop rectangles and the window's old position, which will yield a much smoother and faster redraw. Then add more windows... PS: Having removed the masking overhead and redesigned vertical clipping, the text rendering's had a real shot in the arm. The menus are extremely fast now.
  4. Rectangle split algorithm turned out to be slightly flawed and a bit long-winded. The revised version works and is somewhat shorter: .local RectSplit ; splits rect2 with rect1 lda Top1 ; top3 = max (top1, top2) cmp Top2 ; pre-initialize for the next two split checks, but we do this after the checks in the actual source code to save time if there's no split bcs @+ lda Top2 @ sta Top3 lda Bottom1 ; bottom3 = min (bottom1, bottom2) cmp Bottom2 bcc @+ lda Bottom2 @ sta Bottom3 cpw Left2 Left1 ; split on left hand side? bcs NoLeftSplit mwa Left2 Left3 sbw Left1 #1 Right3 jsr AddWindowRect ; add Rect3 to the head of the rectangle list NoLeftSplit cpw Right1 Right2 bcs NoRightSplit adw Right1 #1 Left3 mwa Right2 Right3 jsr AddWindowRect NoRightSplit mwa Left2 Left3 ; again, placing this after the split checks saves time if there's no split mwa Right2 Right3 lda Top2 ; split at the top? cmp Top1 bcs NoTopSplit sta Top3 sbb Top1 #1 Bottom3 jsr AddWindowRect NoTopSplit lda Bottom1 ; split at the bottom? cmp Bottom2 bcs NoBottomSplit adc #1 sta Top3 mva Bottom2 Bottom3 jsr AddWindowRect NoBottomSplit rts .endl The actual source code looks a bit less brief since I've opted for repetition for the sake of speed there, but it's tested and working. Great fun threading through linked lists of rectangles while debugging... RectSplit is called by an iterator which applies a new rectangle to every existing rectangle in a list, deleting them afterwards. This way, any rectangle entirely obscured by the new rectangle disappears entirely, and no part of that window will then be rendered until part of it becomes visible. ; ---------------------------------------------------------------------------------------------------- ; Iterate through a Window's rectangle list ; dividing all rectangles which intersect with Rect1 ; Pass head of list in HeadNode, new rect in Rect1 ; ---------------------------------------------------------------------------------------------------- .local IterateRectangles mva HeadNode CurrNode mva #0 PrevNode Loop ldx CurrNode lda WindowRectNextNode-1,x ; save next node, since the current node might be removed sta NextNode jsr GetRectFromList ; get Rect2 from the rectangle list jsr RectsOverlap ; see if Rect1 overlaps Rect2 bcc NoOverlap ; if not, then leave this entry alone jsr RectSplit ; split Rect2 with Rect1 and add rectangles to head of list ldx CurrNode ; remove the original Rect jsr RemoveWindowRect NoOverlap mva NextNode CurrNode bne Loop EndOfList rts .endl A brute-force optimisation (as touched upon earlier) would be to oblige window borders to line up exactly on byte boundaries, thus making all the rectangles' left and right extents byte values. In many instances (such as drawing exposed sections of the desktop wallpaper and window backgrounds) this would make updates blindingly fast and completely remove the need for pixel masks. Tempting... Oh: and something I need to work out how to do efficiently to check for two adjacent rects cropping up with the same height and the same Y position, for example. This wouldn't happen often, but would result in two rectangles where one larger one would suffice. Not sure if the overhead of checking a new rect against every other rect in the list for this condition is even worth it.
  5. Well, I certainly hope the RLE masks can be re-used in some way, but I wouldn't really like to burden a rectangle list system with the additional overhead of rendering through a mask when drawing regular windows. It would suck all the performance improvement out of the system. Anyway: I can't wait to get the new system working either so we can do a performance comparison.
  6. Cross-links don't appear to work, but you can download from the Altirra page. Thanks!
  7. This raises the point that it might now be easier and more expedient to keep the window borders inside the byte boundaries, instead of outside as they currently are. This way, the split rectangles would always be whole byte extents. This would certainly save a bit of time when updating chunks of the desktop or clearing out sections of the display - not to mention making the window rect calculations 8-bit. Good stuff - thanks. The stuff about driver structure is interesting, since this is something I'll need to design further down the line.
  8. I seem to remember this being something to do with Trub and Candle being unable to agree on a common RTC format. It's probably gone on too long now...
  9. So: can the undocumented opcodes be used to improve the efficiency of counting up/down to zero? Otherwise this (and the state table) seem to be faster than the undocumented opcodes - so I'm still looking for a compelling example.
  10. Removing the requirement to load up the window masks for each rendered scanline and then mask the bytes through them has certainly sped things up already. Therefore anything which actually does get drawn will be drawn faster. What remains to be seen (and I'm keeping a backed-up version using the masks) is how long all the rectangle clipping takes, with potentially multiple passes through the renderer to exhaust all the rectangles in the list. On paper it should be quite a bit faster (especially with regard to the slight delay in responsiveness in the current version after moving a front window, when nothing is apparently being drawn but in fact stuff is being drawn through a mask).
  11. BTW: after a couple of restless nights worrying about redraw performance, I finally made a difficult but overdue decision and am abandoning my beloved RLE compressed window masks in favour of rectangle lists. The decision was made a little easier thanks to this article on the topic. SymbOS (like GEM) uses rectangle lists, but I had resisted change primarily because I considered the window masks such an elegant and novel solution. Another factor was that I simply couldn't get my head around rectangle lists and was going all out for simplicity as far as the client redraws were concerned. Now, clipping masks are wonderfully versatile but unfortunately they work ex post in the sense that by the time you extract the mask information and realize a particular byte is obscured, you're already in the middle of rendering the object. I think the classic Mac's QuickDraw used clipping masks (i.e. Regions) pre factum, since the 68000 is fast enough to AND an object's extent against a region prior to rendering. Very nice for rounded corner windows, etc, but I had to balance this against the fact that using the window masks, simply moving a window by a few pixels caused a calamitous amount of redrawing. What we really want to happen when we - for example - move a window, is to create an update region and see if any of the background windows' rectangles intersect with it. About the only drawback with rectangle lists is that you have to call a render on everything in the window for each rectangle in the list, but coordinate clipping is much faster than actually rendering stuff, and anything outside of the update region is just discarded. Anyway - all the methodology suddenly becomes wonderfully clear. Every time a window is opened, moved, resized or closed, the rectangle lists for every window (the desktop being window zero) are rebuilt. It's been quite interesting designing the code for all this. Here's my initial interpretation of the rectangle split algorithm described in the article above: .local RectSplit cpw Left2 Left1 ; split on left hand side? bcs NoLeftSplit mwa Left2 Left3 sbw Left1 #1 Right3 lda Top1 ; top3 = max (top1, top2) cmp Top2 bcs @+ lda Top2 @ sta Top3 lda Bottom1 ; bottom3 = min (bottom1, bottom2) cmp Bottom2 bcc @+ lda Bottom2 @ sta Bottom3 jsr AddWindowRect ; add Rect3 to the head of the rectangle list NoLeftSplit cpw Right1 Right2 bcs NoRightSplit adw Right1 #1 Left3 mwa Right2 Right3 lda Top1 ; top3 = max (top1, top2) cmp Top2 bcs @+ lda Top2 @ sta Top3 lda Bottom1 ; bottom3 = min (bottom1, bottom2) cmp Bottom2 bcc @+ lda Bottom2 @ sta Bottom3 jsr AddWindowRect NoRightSplit lda Top2 cmp Top1 bcs NoTopSplit sta Top3 sbb Top1 #1 Bottom3 cpw Left1 Left2 bcc Less1 mwa Left1 Left3 jmp @+ Less1 mwa Left2 Left3 @ jsr AddWindowRect NoTopSplit lda Bottom1 cmp Bottom2 bcs NoBottomSplit adc #1 sta Top3 mva Bottom2 Bottom3 cpw Left1 Left2 bcc Less2 mwa Left1 Left3 jmp @+ Less1 mwa Left2 Left3 @ jsr AddWindowRect NoBottomSplit rts .endl AddWindowRect adds the newly created rectangle to the head of the current window's rect list. By placing the new rect at the head of the list, we can simultaneously iterate through the existing rects from the original list head without visiting the new additions. So: we start with the desktop, and place a 320x200 rectangle at the start of its rect list. Then we split that rect with the first window, and then split that window and all the resulting desktop rects with the next window and so on. Stuff like background rendering can then be confined to the rectangle bounds, while larger objects which can't easily be "downsized" to fit the rects will be nicely clipped by the clipping routines. This all seems remarkably obvious now, but it's another fairly substantial change and thus rewrite...
  12. Interesting - thanks. Here's another pertinent document: http://www.1000bit.it/support/manuali/apple/a3sosrm.pdf. It's a single-tasking OS, but the sections on banked memory management and device drivers are especially relevant.
  13. Heh - I get my code analysed from time to time (willingly) in the GUI thread, and one thing I've learned from this is to turn things around wherever possible so they count down to zero, saving a load and a compare.
  14. Looks good - can't really argue with that. However, if not using ISC, could you not just load Count3Frames with 3 and count down, branching on zero? dec Count3Frames ; 5 bne @counter3_done ; 2 -> 8/9 lda #3 ; 2 sta Count3Frames ; 3 ; 13 I realize this is contrary to the assumption that the memory location is initialized to zero - in this case it's initialized to 3. Sorry if I've totally misunderstood.
  15. Altirra doesn't (yet) emulate this hardware, and it has nothing to do with VBXE.
  16. Well - this is extremely cool use of bit 6. I take it this will work in hi-res mode too, yielding 640x192 and even 1280x192? With maybe doubled bit-depth as an option, this could be very interesting when all one wants is extra resolution and little else.
  17. Wow - just noticed POKE 559,66... if only this unused bit worked on the real thing.
  18. Surely the programmer can pre-optimise stuff like target=40*20 out of his code? Especially on an 8-bit compiler.
  19. If you hack the ROM image so that it banks using the U1MB base register, might be doable.
  20. I used to sit with the guitar on my lap and get a lot of practice in while big projects were assembling.
  21. Precisely my point. PHX/PHY and PLX/PLA, BRA, etc, would be wonderful time savers but all I see in the 6502C is a rag-tag collection of accidental operations, and the greatest challenge many of them present is to find an uncontrived use for them.
  22. Most useful would be the 65C02 instructions that aren't there: INC/DEC A, BRA, PHX/PHY, etc.
  23. Installed Practically Macro for now, which kind of does what I want.
×
×
  • Create New...