FAQ  •  Register  •  Login

Screen handling

<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Wed Apr 18, 2012 1:10 am

Screen handling

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 :)

  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"

          
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Wed Apr 18, 2012 12:50 pm

Re: Screen handling

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
Last edited by slenkar on Wed Apr 18, 2012 1:06 pm, edited 1 time in total.
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Wed Apr 18, 2012 1:04 pm

Re: Screen handling

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.
<<

boriel

Site Admin

Posts: 1463

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Wed Apr 18, 2012 1:12 pm

Re: Screen handling

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).
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Wed Apr 18, 2012 1:21 pm

Re: Screen handling

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.
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Wed Apr 18, 2012 1:40 pm

Re: Screen handling

  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.
<<

slenkar

Posts: 282

Joined: Sun Feb 13, 2011 3:33 am

Location: Kentucky US, used to be Birmingham UK

Post Wed Apr 18, 2012 3:28 pm

Re: Screen handling

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
<<

LCD

Posts: 596

Joined: Fri Feb 13, 2009 3:11 pm

Location: Vienna, Austria

Post Wed Apr 18, 2012 5:19 pm

Re: Screen handling

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!
<<

boriel

Site Admin

Posts: 1463

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Wed Apr 18, 2012 5:35 pm

Re: Screen handling

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!
<<

britlion

Posts: 766

Joined: Mon Apr 27, 2009 7:26 pm

Location: Slough, Berkshire, UK

Post Wed Apr 18, 2012 7:33 pm

Re: Screen handling

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

Return to ZX Basic Compiler

Who is online

Users browsing this forum: No registered users and 1 guest

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO