Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Screen handling
#1
This is interesting. There's quite a lot of overhead in PLOT, I think - this is fairly unoptimized, still - and appears to be a little buggy. It also doesn't use the screen tables lookup yet. But it's late and I need to go to bed Smile

Code:
SUB plotPoint (x as uByte, y as uByte) ASM ld d,(IX+5) ;'X ld e,(IX+7) ;'Y ld a, 191 sub e ret c ld e, a and a rra scf rra and a rra xor e and 248 xor e ld h, a ld a, d rlca rlca rlca xor e and 199 xor e rlca rlca ld l, a ld a, d and 7 ld b, a inc b ld a, 1 plotPoint_loop: rrca djnz plotPoint_loop ;cpl ld b, a ld a, (hl) or b ld (hl), a END ASM END SUB FUNCTION t() as uLong asm DI LD DE,(23674) LD D,0 LD HL,(23672) EI end asm end function dim time0, time1, time2 as long dim n as uInteger cls for n=1 to 150 plotPoint(n,n-1) plot n,n+3 next n time0=t() for n=0 to 50000 plot 50,50 next n time1=t() for n=0 to 50000 plotPoint(50,50) next n time2=t() print "ZX Basic 50,000 plot:" print time1-time0;"frames =";(time1-time0)/cast(float,50);" seconds" print print "plotPoint 50,000 times:" print time2-time1;"frames=";(time2-time1)/cast(float,50);" seconds"
Reply
#2
nice, i got 11 secs for zxbasic and 7 secs for your function

I cant seem to get any colour of dots except black

Code:
SUB plotPoint (x as uByte, y as uByte) ASM ld d,(IX+5) ;'X ld e,(IX+7) ;'Y ld a, 191 sub e ret c ld e, a and a rra scf rra and a rra xor e and 248 xor e ld h, a ld a, d rlca rlca rlca xor e and 199 xor e rlca rlca ld l, a ld a, d and 7 ld b, a inc b ld a, 1 plotPoint_loop: rrca djnz plotPoint_loop ;cpl ld b, a ld a, (hl) or b ld (hl), a END ASM END SUB FUNCTION t() as uLong asm DI LD DE,(23674) LD D,0 LD HL,(23672) EI end asm end function dim time0, time1, time2 as long dim n as uInteger cls for n=1 to 150 plotPoint(n,n-1) plot n,n+3 next n time0=t() Paper 5 INK 2 for n=0 to 191 for y=0 to 191 plotPoint(n,y) next y next n time1=t() Paper 3 INK 4 for n=0 to 191 for y=0 to 191 plot y,n next y next n time2=t() print "plotpoint 50,000 plot:" print time1-time0;"frames =";(time1-time0)/cast(float,50);" seconds" print print "zxbasic 50,000 times:" print time2-time1;"frames=";(time2-time1)/cast(float,50);" seconds"

On the second pass only the green paper shows up
Reply
#3
You know, looking at this, I'm particularly impressed with this bit:

Code:
rra scf rra and a rra xor e and 248 xor e

As we know, the bit pattern for a screen address is 010LLrrr LLLCCCCC - where L = character line number (0-31), r=row in character. C=column.

This rotates in the 010, and slides over the two first line bits LL.

Then it does something really clever. It puts in the last 3 bits from the original, left in e. I'd have probably done something like:

Code:
RRCA RRCA RRCA AND %010110000 ld d,a ld a,e and 7 or d

Which is far more faffing. XOR/AND/XOR. How cool is that for three instructions to merge some bits of one register with another? New trick learned.
Reply
#4
slenkar Wrote:nice, i got 11 secs for zxbasic and 7 secs for your function
ZX Basic uses ROMs PLOT (which is already somewhat optimized, BTW!), but uses a different entry point, to allow 192 scanlines.
On the other hand, DRAW has already been optimized and no longer uses PLOT, but PIXELADDR for the 1st point of a scan line (remaining points are computed relatively to the last plotted dot).

Also, keep en mind that ZX Basic/ROM PLOT routine also updates ATTR according to TEMP ATTRs and also take into account the SCREEN_ADDR variable (so you can draw/print in another memory/region like a temporary buffer).
Reply
#5
slenkar Wrote:nice, i got 11 secs for zxbasic and 7 secs for your function

I cant seem to get any colour of dots except black


On the second pass only the green paper shows up

The routine, as it stands, just sets the ink point on - it doesn't touch attributes, change the current plot values or any such thing - it's optimized to get that point changed, and do nothing else. Slenkar - if you did a CLS after setting ink and paper values, you'd get what you were looking for, since that would change all the attribute data on the screen for you.

As Boriel points out, the standard plot routine also changes the attribute value and does some housekeeping in the background. That said, it's pretty rare that a draw needs to do this, since the effect is usually terrible. I can't think of any games that would require it - usually all the attribs in the game area are set already.

It might be reasonable to set up a fastplot and fastdraw routine for games purposes, that don't do the overhead. If so, it would be a plot similar to this, an absolute draw (from x1,y1 to x2,y2 - no relative movement), and routines to change the ink and paper in an area block - which would go with the clearblock routine.

The reason for not using relative draw is if you were working with a vector game, you'd generate the vertices explicitly, so a draw from vertex point 1 to vertex point 2 is probably more useful.
Reply
#6
Code:
SUB plotPoint (x as uByte, y as uByte) ASM ld d,a ;'X ld a, 191 sub (IX+7) ;' y jr c, plotPoint_end ld l,a ld h,ScreenTables/256 ld a,(HL) inc h ld l,(HL) ld h,a ; now we're on the right row on screen. ld a,d RRCA ; divide column by 8 for bytes. RRCA RRCA AND 31 add a,l ld l,a ld a, d and 7 ld b, a inc b ld a, 1 plotPoint_loop: rrca djnz plotPoint_loop ld b, a ld a, (hl) or b ld (hl), a plotPoint_end: END ASM END SUB

Using screen address tables shaves this down to 6.42 seconds for 50,000 points plotted. That's not too bad, all told.
(screentables.asm is available elsewhere in the forum, I promise!)

Considering that quite a few routines can use the screen lookup tables, 512 bytes of screen tables isn't crazy for a solid speedup (and of course, if you are using a shadow screen, then you could either rewrite a bit, or make screen tables that point to your shadow screen memory).

Not sure requiring rotate tables, which is much bigger, is a win, here for one loop removal.
Reply
#7
ive never required any color dots than black anyway i suppose,
the zxbasic plot doesnt seem to draw colored dots either I dont think.

those lookup tables really seem worth using
Reply
#8
Uncontended Memory: ZXBC Plot: 11 Sec. Britlions FastPlot: 7.7 sec
Contended Memory: ZXBC Plot: 12.1 Sec. Britlions FastPlot: 9.1 sec
Impressive!!!
------------------------------------------------------------
http://lcd-one.da.ru redirector is dead
Visit my http://members.inode.at/838331/index.html home page!
Reply
#9
slenkar Wrote:ive never required any color dots than black anyway i suppose,
the zxbasic plot doesnt seem to draw colored dots either I dont think.

those lookup tables really seem worth using
It does (otherwise, it would be a bug). ZXBC tries to mimic Sinclair BASIC command as much as possible while trying not to increase the overhead.
BTW impressive measures!
Reply
#10
Slenkar: Perhaps these are useful for setting colours?

They both paint a rectangle in the specified colours - one needs ink/paper/bright/flash separately, the second takes the attribute byte directly.

Code:
SUB WindowPaint(x as uByte,y as uByte, width as uByte, height as uByte, inkCol as ubyte, paperCol as uByte, isBright as uByte, isFlash as uByte) paint(x,y,width,height,(isFlash<<7+isBright<<6+paperCol<<3+inkCol)) END SUB

Code:
SUB paint (x as uByte,y as uByte, width as uByte, height as uByte, attribute as ubyte) asm ld a,(IX+7) ;ypos rrca rrca rrca ; Multiply by 32 ld l,a ; Pass to L and 3 ; Mask with 00000011 add a,88 ; 88 * 256 = 22528 - start of attributes. Change this if you are working with a buffer or somesuch. ld h,a ; Put it in the High Byte ld a,l ; We get y value *32 and 224 ; Mask with 11100000 ld l,a ; Put it in L ld a,(IX+5) ; xpos add a,l ; Add it to the Low byte ld l,a ; Put it back in L, and we're done. HL=Address. push HL ; save address LD A, (IX+13) ; attribute LD DE,32 LD c,(IX+11) ; height BLPaintHeightLoop: LD b,(IX+9) ; width BLPaintWidthLoop: LD (HL),a ; paint a character INC L ; Move to the right (Note that we only would have to inc H if we are crossing from the right edge to the left, and we shouldn't be needing to do that) DJNZ BLPaintWidthLoop BLPaintWidthExitLoop: POP HL ; recover our left edge DEC C JR Z, BLPaintHeightExitLoop ADD HL,DE ; move 32 down PUSH HL ; save it again JP BLPaintHeightLoop BLPaintHeightExitLoop: end asm END SUB
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)