News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_mr_lou

How fast can the CPC draw?

Started by mr_lou, 22:14, 12 December 11

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

mr_lou

How fast can the CPC draw a line?


ld hl,#2
add hl,sp
ld a,(hl)
ld e,a

ld hl,#3
add hl,sp
ld a,(hl)
ld d,a

ld hl,#4
add hl,sp
ld a,(hl)
ld c,a

ld hl,#5
add hl,sp
ld a,(hl)
ld b,a

ld h,b
ld l,c
call 0xBBF6 ; GRA LlNE ABSOLUTE
ret

Typical way of doing it by calling firmware. (Taken from http://www.cpcwiki.eu/index.php/SDCC_and_CPC)

But then looking at this fast plot routine:

CMASK EQU &B338 ;Adress for colormask
;664/6128: &B6A3

FPLOT LD A, L ;A = Lowbyte Y
AND %00000111 ;isolate Bit 0..2
LD H, A ;= y MOD 8 to H
XOR L ;A = Bit 3..7 of Y
LD L, A ;= (Y\8)*8 to L
LD C, A ;store in C
LD B, &60 ;B = &C0\2 = Highbyte Screenstart\2

ADD HL, HL ;HL * 2
ADD HL, HL ;HL * 4
ADD HL, BC ;+ BC = Startaddress
ADD HL, HL ;of the raster line

LD A, E ;Lowbyte X to A
SRL D ;calculate X\4, because
RR E ;4 pixel per byte
SRL E
ADD HL, DE ;+ HL = Screenaddress

LD C, %10001000 ;Bitmask for MODE 1
AND %00000011 ;A = X MOD 4
JR Z, NSHIFT ;-> = 0, no shift
SHIFT SRL C ;move bitmask to pixel
DEC A ;loop counter
JR NZ,SHIFT ;-position

NSHIFT LD A, (CMASK) ;get color mask
XOR (HL) ;XOR screenbyte
AND C ;AND bitmask
XOR (HL) ;XOR screenbyte
LD (HL), A ;new screenbyte
RET ;done



- I'm wondering if there's a similar faster way of drawling lines, like there is plotting.
(Taken from http://www.cpcwiki.eu/index.php/Programming:Fast_plot)

I know the next example is a bit too much, but I'm wondering if the CPC would ever be able to produce something similar to this: http://dewfall.dk/html5
(Runs best in Chrome or Opera).

TFM

A very fast way to draw a line is used by the C command "draw(x,y)" in the C library FIOLIB. See here:
http://cpcwiki.eu/index.php/FIOLIB

draw(x,y)
int x,y;
DRAWs a line form the actual graphic cursor position (use MOVE to set it!) to the coordinates X and
Y. The coordinate position 0, 0 is the upper left corner.
You can use this function in all screen-MODEs, -formats and with all PENs.

I never saw a routine to be more quick.
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

mr_lou

Quote from: TFM/FS on 22:20, 12 December 11
A very fast way to draw a line is used by the C command "draw(x,y)" in the C library FIOLIB.
So it's not just calling the firmware routine?

I read briefly about FIOLIB earlier, but came to the understanding that it was only for FutureOS stuff?

TFM

Quote from: mr_lou on 22:30, 12 December 11
So it's not just calling the firmware routine?

That's right. It has own specialiced routines for all modes, encoded in assembler.

Quote from: mr_lou on 22:30, 12 December 11
I read briefly about FIOLIB earlier, but came to the understanding that it was only for FutureOS stuff?

That's right.

TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

TFM

Woho! At work I missed that part completely.  8)  (No, not cool! Just blind! :laugh: )


Quote from: mr_lou on 22:14, 12 December 11
I know the next example is a bit too much, but I'm wondering if the CPC would ever be able to produce something similar to this: http://dewfall.dk/html5

Looks great!!! Do you have a source code for it? If you have one (in Small C for example), then I can try to convert it to CPC.
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

mr_lou

Well, it sounds great that it's a lot faster than the firmware call. Would love to see it in action.
But I don't want to develop for FutureOS, sorry. I don't want to require people to have FutureOS in order to run my stuff.

Quote from: TFM/FS on 04:13, 13 December 11
Looks great!!! Do you have a source code for it? If you have one (in Small C for example), then I can try to convert it to CPC.

Well it's plain HTML/Javascript, so you can view the source in the browser. But here it is:


<script type="text/javascript">

// Adjust the canvas to fit the screen.
document.getElementById("GameCanvas").width=window.innerWidth;
document.getElementById("GameCanvas").height=window.innerHeight;

var g = getGraphics(); // The object with all the drawing methods. The class I'd love to have for CPC :->
var w = getWidth();
var h = getHeight();

var t = 0;
var c = 3.141592654;
var count = 0;

var cyclems = 0;
var lastTime = System.currentTimeMillis();

var lastX = w/2;
var lastY = h/2;

function mainloop() {
cyclems = System.currentTimeMillis()-lastTime;
lastTime = System.currentTimeMillis();
while (cyclems>5) {
  cyclems-=5;
  c += 0.00001;
}
t = c;
count = 0;
g.setClip(0,0,w,h);
g.setColor(0x000000);
g.fillRect(0, 0, w, h);

lastX = w/2;
lastY = h/2;

while (count < 200) {
  g.setColor(t * 64+0xff0000);
  newX = (Math.cos(t) * t + w / 2);
  newY = (Math.sin(t) * t + h / 2);
  g.drawLine(lastX, lastY, newX, newY);
  lastX = newX;
  lastY = newY;
  t += c;
  count++;
}
setTimeout("mainloop()", 10); // Wait 10 milliseconds, then draw again
}

mainloop(); // Start it up

</script>


Note, that the above code is using those drawing methods from J2ME, because I've made Javascript "classes" that translates them into HTML5-Canvas code. That makes it easier for me to code for J2ME + HTML5. (I've done the same with Flash/Flex3 and Android and would love to be able to do it for the CPC as well. Use the same methods to code for J2ME, Flash, HTML5, Android, Amstrad....)

Original J2ME version of the code:


private Stoney midlet;
private int w, h, count, lastX, lastY, newX, newY;
private Graphics g;
private double t, c;
private long lastTime;
private int cyclems;

this.setFullScreenMode(true);
g = getGraphics();
w = getWidth();
h = getHeight();

t = 0;
c = 3.141592654;
count = 0;

cyclems = 0;
lastTime = System.currentTimeMillis();

while (true) {
cyclems = (int)(System.currentTimeMillis()-lastTime);
lastTime = System.currentTimeMillis();
while (cyclems>10) {
  cyclems-=10;
  c += 0.0001;
}
t = c;
count = 0;
g.setColor(0x000000);
g.fillRect(0, 0, w, h);
lastX = w/2;
lastY = h/2;

while (count < 200) {
  g.setColor((int) (t * 64));
  newX = (int) (Math.cos(t) * t / 7 + w / 2);
  newY = (int) (Math.sin(t) * t / 7 + h / 2);
  g.drawLine(lastX, lastY, newX, newY);
  lastX = newX;
  lastY = newY;
  t += c;
  count++;
}
flushGraphics();
try {
  Thread.sleep(10);
} catch (Exception e) {
}
}

ralferoo

Well, it's a specialised case as I'm not drawing to the normal CPC screen layout (i.e. I'm doing "blocky graphics" using a byte per pixel and using the crtc to repeat lines), but I've got line drawing down to 28us per pixel in my particular case. I don't plan to release the source any time soon though, because it's part of a demo I'm working on...

But, for rough calculations, 28us per pixel means my routine is capable of producing an absolute maximum of 713 pixels per frame and setup time for each line segment is about 3 pixels worth. So, that's around 50 lines of 10 pixels each at 50fps. Which isn't really very much at all... :(

TFM

Quote from: mr_lou on 07:46, 13 December 11
Well, it sounds great that it's a lot faster than the firmware call. Would love to see it in action.
But I don't want to develop for FutureOS, sorry. I don't want to require people to have FutureOS in order to run my stuff.

Well, that's your decision. But FutureOS is free for download for everyone. So requiring FutureOS is not a constraint. In contrast it's needed to provide a fast environment.

Further... If you write a C program, you can use IOLIB's for Amsdos, CP/M and FutureOS. You will not developp for a specific OS.


Quote from: mr_lou on 07:46, 13 December 11
Well it's plain HTML/Javascript, so you can view the source in the browser. But here it is:

... snip

Thank's a lot. I try to find somebody who helps me to make a C program for the Small C compiler for CP/M and will then use FIOLIB to compile. I haven't setup SDCC / Z88DK on my maching now. So I have to use what I have (and that's all CPC based). It can take a while, but it's very interesting :-))) Thanks' a lot for the code :-)))
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

TFM

Quote from: ralferoo on 12:58, 13 December 11
Well, it's a specialised case as I'm not drawing to the normal CPC screen layout (i.e. I'm doing "blocky graphics" using a byte per pixel and using the crtc to repeat lines), but I've got line drawing down to 28us per pixel in my particular case. I don't plan to release the source any time soon though, because it's part of a demo I'm working on...

But, for rough calculations, 28us per pixel means my routine is capable of producing an absolute maximum of 713 pixels per frame and setup time for each line segment is about 3 pixels worth. So, that's around 50 lines of 10 pixels each at 50fps. Which isn't really very much at all... :(

28 ys is pretty cool! But on a 64x32 screen you can do a bit faster ;-)
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

AMSDOS

* Using the old Amstrad Languages :D   * with the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

mr_lou


ralferoo

Quote from: CP/M User on 08:58, 14 December 11How fast does 'LDI' draw?
5us per byte, so maximum 3993 bytes per frame.

The quickest way of writing data is by using PUSH to write the graphics data which is 4us for 2 bytes, but obviously you also need to get the data into a register to start with. For LD B,(HL):DEC HL:LD B,(HL):DEC HL:PUSH BC you're break even, but if you know the layout of your source material, you can replace the DEC HL with DEC L. Alternatively, you might be able to use load immediate values into the registers, which will give you 7us per 2 bytes and better if data is repeated.

ralferoo

Quote from: TFM/FS on 18:40, 13 December 11
28 ys is pretty cool! But on a 64x32 screen you can do a bit faster ;-)
Good way to spur me on to improve... ;)

There are some things I don't like, like 1/3 of that time being calculating the next pixel address, but there are others I can't change, such as my requirement to draw in xor mode...

I'm also not prepared to drop down to 64 pixels horizontally because there'd be too much empty space on screen (I'm currently experimenting with 96x37).

TFM

Looking forward to see your next project being released. Show Rhino how to do it :-D If you can keep that speed than it will do pretty well  :)

I never used the 64x32 square screen for the same reasons. However if somthing uses vertical scrolling, then this mode make really, really sense :-)
TFM of FutureSoft
Also visit the CPC and Plus users favorite OS: FutureOS - The Revolution on CPC6128 and 6128Plus

cpcitor

Quote from: TFM on 22:20, 12 December 11
A very fast way to draw a line is used by the C command "draw(x,y)" in the C library FIOLIB. See here:
http://cpcwiki.eu/index.php/FIOLIB

draw(x,y)
int x,y;
DRAWs a line form the actual graphic cursor position (use MOVE to set it!) to the coordinates X and
Y. The coordinate position 0, 0 is the upper left corner.
You can use this function in all screen-MODEs, -formats and with all PENs.

I never saw a routine to be more quick.

Hi TFM. I'm trying to see how it is programmed.

I looked for FutureOS source code on http://futureos.cpc-live.com/.

FAQ says:

QuoteSID: (...) everything concerning FutureOS is free. And all the codes are open sources.
     If you have the source of such codes, it's easy to adapt them to FutureOS.

I could not find FutureOS source code on http://futureos.cpc-live.com/.

I found some source code on http://koaks.amstrad.free.fr/amstrad/documents/fiolib.html, namely http://koaks.amstrad.free.fr/amstrad/download/fiolib.zip and see a small-C source code:

draw(x,y) int x,y;
{
regs[1]=y;
regs[2]=x;
oscall(LINE_ABS_GRA,regs);
}


Looks like it calls firmware. I guess this is not the correct source code.

Can you help me?
Had a CPC since 1985, currently software dev professional, including embedded systems.

I made in 2013 the first CPC cross-dev environment that auto-installs C compiler and tools: cpc-dev-tool-chain: a portable toolchain for C/ASM development targetting CPC, later forked into CPCTelera.

SRS

This DRAW must indeed be very fast
ASM:
LINE_ABS_GRA ld a,15:jp notmade
notmade
;function is NOT implemented yet
;=-> display error message
;
;A = number of functionretRET
and for sure working in every mode at same speed :)


Powered by SMFPacks Menu Editor Mod