[V9990] Q&A Official Thread

Page 11/19
4 | 5 | 6 | 7 | 8 | 9 | 10 | | 12 | 13 | 14 | 15 | 16

By hit9918

Prophet (2832)

hit9918's picture

07-03-2016, 11:42

It is like a fractal to just have an image for the demo, such thing is not used in game.
The heaviest part in there is multiplication, "(x-16)*(y-16)". But *32 is not multiplication, just shift.
While this pain

(c-int(c/256)*256) and 255

was stumbeling with the BASIC 15bit maths and what I wanted was far from a division

	ld a,h

just give me that high byte.
A matter of 1.4 microseconds on the machine level.

do BASIC compilers have high byte low byte features?
In the gosub 11000 are lots of those "/256", if BASIC compiler makes a division then speed is superbad.
Then can try setting DEFUSR or BASE.
They are 16bit values that one can set and then PEEK the high byte and low byte from sysarea.

By Grauw

Enlighted (7894)

Grauw's picture

07-03-2016, 13:03

The low byte is a simple AND. Afaik the only way to get the high byte is an integer division by 256.

By hit9918

Prophet (2832)

hit9918's picture

07-03-2016, 14:54

bad things happen.
in attempts to prevent overflows I got wrong results.
but I can't reproduce the example.
something in the corner
doing /256 one gets minus 0.something
then some OUT makes some implicit conversion, which one is it, cint() or int(), who knows.
cint(-0.9) = 0, a candidate.
the thing ends up with 0 instead the desired high byte.
when one adds an int() op trying to put something straight, it gets -1, and an OUT of -1 is an error.

I dont know whether BASIC programmers know ways about it.
for me storing the value to DEFUSR or BASE worked best. and then PEEK the bytes.
that is because defusr = 65535 does not make an error, the 16th bit is available.

when defusr = 32768 would make an error, it was thought "ok, that is confusing, because its a 64k machine".
And at that point DEFUSR did get a conversion to 16bit available nowhere else.

By hit9918

Prophet (2832)

hit9918's picture

07-03-2016, 15:53

Maybe I should explain the problem simpler.

a = 65535
? a and 255
Overflow BEEP!

With blitter sx dx values it still works, they can stay below 32768.

By tvalenca

Paladin (719)

tvalenca's picture

07-03-2016, 16:27

Kai Magazine wrote:

DEFNIT A-Z on turbobasic makes real wanders.
It does not only accelerate the FOR loops but all mathematical calculations as long as those are done with integers.
This is why I try to find solutions with integer calculations as much as I can.
Anyway, if you need a non-integer variable in particular, you can DEFINTA-Y and you can use Z as you wish.

Or you can use the variable modifier characters on the one variable name you need to be calculated different, the same way you do with Strings...

So, even if you put DEFINTA-Z on the first line of your program:
A$= will always be a String variable
A#= will always be a double precision variable
A!= will always be a single precision variable
A%= will always be an integer variable.

hit9918 wrote:

It is like a fractal to just have an image for the demo, such thing is not used in game.
The heaviest part in there is multiplication, "(x-16)*(y-16)". But *32 is not multiplication, just shift.

Does the BASIC interpreter is smart enough to treat operations with powers of two (2, 4, 8, 16, 32...) as shift operations, or it will treat like normal multiplications?

hit9918 wrote:

Maybe I should explain the problem simpler.

a = 65535
? a and 255
Overflow BEEP!

With blitter sx dx values it still works, they can stay below 32768.

Didn't worked here either.

What I know: BASIC works with signed INTs.
What I think, but I don't know: Maybe you can't work with unsigned INTs, and logic operators only work with INTegers.

If you enter:
a% = 65535
you will get overflow right away.

BUT if you replace 65535 with "-1" (using binary representation, both 65535 unsigned int and -1 signed int are equal to &B1111111111111111) your code works:

a = -1
? a and 255
 255
Ok

By Grauw

Enlighted (7894)

Grauw's picture

07-03-2016, 16:47

hit9918 wrote:

Maybe I should explain the problem simpler.

a = 65535
? a and 255
Overflow BEEP!

Hmm ok, because they are 16-bit signed integers... You can use -1 to represent 65535, but that doesn’t work for the division. That’s a shame. (Btw, use the integer division \.)

I guess you could use if x < 0 then (x + 1) \ 256 + 255... but yeah, meh.

By tvalenca

Paladin (719)

tvalenca's picture

08-03-2016, 20:54

Just to wrap the offtopic:

I found a HD63C09 and a SRAM on my parts drawer. As it has specific multiplication and division instructions, I'm thinking on putting it inside a cartridge to test how fast things could be if Z80 had a better ALU.

Now, that creating pixel art post made me think how those images look on V9990, and how easily we can animate them...

By hit9918

Prophet (2832)

hit9918's picture

09-03-2016, 12:56

a multiplication with gfx 9000 in 134 cycles.
the deal is that the 128k table needs no main RAM.

	;HL = H * L
8	ld a,3
12	out (0x64),a
12	add hl,hl
8	adc a		;a = 6 or a = 7. 60000..7ffff
8	add n		;different location in vram
8	ld c,0x63
14	out (c),l
14	out (c),h
14	out (c),a
8	ld c,0x60
14	in l,(c)
14	in h,(c)
--
134

how to communicate with the 63xx?

5	ld a,l
12	out (0),a
5	ld a,h
12	out (1),a
5	xor a
12	out (2),a	;I have provided new value, go
wait:
12	in a,(2)
5	rrca
11	jp nc,wait
12	in a,(0)
5	ld l,a
12	in a,(1)
5	ld h,a
--
113

the fastest communication I could think of.
but I dont think the 63xx gonna set the result to all 3 ports in the 12 z80 cycles.
more loops needed.

what about logartihm. it can to great things with mul and div.
ld l,(hl)
that was a logarithm lookup 8bit->8bit.
ld e,(hl)
inc h
ld d,(hl)
that was logarithm 8bit->16bit precision result
512 bytes table, superfast, very intriguing.
except that no completed code was ever seen.

By hit9918

Prophet (2832)

hit9918's picture

12-03-2016, 00:18

kunbasic needs horrible 50 rasterlines to make a blit.
the /256 results in 3 calls to some maths code.

but using defusr1 to store and peek, it looks like this

	ld hl,(0x8d61) ;sx
	ld (0xf39c),hl ;defusr1

	ld hl,0xf39c
	ld l,(hl)
	ld h,0
	ld a,l
	out (0x63),a

	ld hl,0xf39d
	ld l,(hl)
	ld h,0
	ld a,l
	out (0x63),a
--
122

The whole gosub should go in 4 rasterlines on z80.
It's not like asm coding but can make a game.
One could fire 80 blits in 50fps.

same demo again, but without the div in blitter code

1 defint a-z
2 dim sx(32), sy(32)

9 out &h6f,0 : rem 'init superimpose

10 for i = 0 to 24 : read a
12 out &h64,i : rem			'write register i
14 out &h63,a
16 next i

60 for i = 0 to 15 : rem		'palette
61 out (&h64),128+14 : out (&h63),i*4
70 out (&h61),i*2 : out (&h61),i*2 : out (&h61),i*1 + 13
80 next i

90 'CLS beta
92 nx = 512 : ny = 256 : sx = 0 : sy = 0 : dx = s0 : dy = 0
94 ar = 0 : lo = &h00 : op = &h40
96 gosub 11000

100 rem				'16bit bitmap
110 for y = 0 to 31
115 p = 0 : a = y * 512 * 2 : gosub 10000
120 for x = 0 to 31
125 c = (y and &h1f) *32*32 + &h1f*32 + (x and &h1f)
126 if abs((x-16)*(y-16)) > 64 then c = 0
130 out &h60,(c-int(c/256)*256) and 255
135 out &h60,(c/256) and 255
140 next x,y

200 pi = 3.1415926
210 for i = -1 to 20
220 nx = 32 : ny = 32 : sx = 0 : sy = 0 : dx = i*13 : dy = 128-i*4 : gosub 11600
230 next i
250 for i = -1 to 15
260 nx = 32 : ny = 32 : sx = 0 : sy = 0 : dx = 128+i*4 : dy = i*13-1 : gosub 11600
270 next i

290 for i = 31 to 0 step -1
291 sx(i) = sx(i) + sy(i)
292 next i

300 dx = &h23 : dy = &h24 : gosub 11600 : goto 300

9990 if inkey$ = "" then 9990
9991 out &h6f,16 : rem			'superimpose tidy exit
9999 stop

10000 'vram write address = p*65536 + a . out &h60 vpokes with autoincrement.
10005 out &h64,0 : rem		'write vdp registers 0+
10006 defusr1 = a : rem		'to get at H,L
10010 xx = peek(&hf39c) : out &h63,xx : '?xx;
10020 xx = peek(&hf39d) : out &h63,xx : '?xx;"."
10030 out &h63,p : rem 'bit 7 address increment inhibit
10050 return


11000 if inp(&h65) and 1 then 11000 'wait for blitter
11005 dx = dx and 32767 : dy = dy and 32767 'math problems of BASIC
11010 out &h64,32 'write r32+
11015 defusr1 = sx
11020 out &h63,peek(&hf39c) 'r32
11030 out &h63,peek(&hf39d) 'r33
11025 defusr1 = sy
11040 out &h63,peek(&hf39c) 'r34
11050 out &h63,peek(&hf39d) 'r35
11055 defusr1 = dx
11060 out &h63,peek(&hf39c) 'r36
11070 out &h63,peek(&hf39d) 'r37
11075 defusr1 = dy
11080 out &h63,peek(&hf39c) 'r38
11090 out &h63,peek(&hf39d) 'r39
11095 defusr1 = nx
11100 out &h63,peek(&hf39c) 'r40
11110 out &h63,peek(&hf39d) 'r41
11115 defusr1 = ny
11120 out &h63,peek(&hf39c) 'r42
11130 out &h63,peek(&hf39d) 'r43
11140 out &h63,ar         'r44 arg
11150 out &h63,lo         'r45 lop
11151 out &h63,255        'r46
11152 out &h63,255        'r47
11160 out &h64,52 'write r52+
11170 out &h63,op         'r52
11180 return

11500 'blit (sx,sy)-(sx+nx-1,sy+ny-1) to (dx,dy)
11510 op = &h40 'lmmm
11520 ar = 0 : lo = &hc
11530 gosub 11000 : return

11600 'blit (sx,sy)-(sx+nx-1,sy+ny-1) to (dx,dy) with source value = 0 meaning transparent pixel.
11610 op = &h40 'lmmm
11620 ar = 0 : lo = &h1c
11630 gosub 11000 : return


21000 'regs
21010 data 0,0,0,0
21020 data 0,0,&h87,0
21030 data &hC2,0,0,0
21040 data 0,0,0,0
21050 data 0,0,0,0
21060 data 0,0,0,0
21070 data 0


50000 'B1-B6 VRAM
50010 'Physical mapping: even addresses (bit 0=0) in VRAM0 and odd addresses (bit0=1) in VRAM1. 
50020 '00000-7FDFF Bitmap Data
50030 '7FE00-7FFFF Cursor area (512 bytes)

By tvalenca

Paladin (719)

tvalenca's picture

12-03-2016, 03:02

why only the OUT(&H63) on the ML code?
well, I think I know the answer, there isn't a way to pass two parameters to ML code via USR(x), right?

Page 11/19
4 | 5 | 6 | 7 | 8 | 9 | 10 | | 12 | 13 | 14 | 15 | 16
My MSX profile