Re: A83: Re: modules operator


[Prev][Next][Index][Thread]

Re: A83: Re: modules operator




> What's Olle's sprite routine?? Could someone send it to me.
> 
> Nat Sith
> smithrh@esper.com

Well, here's the routine, and the tutorial to go with it :)
------------------------------------------------------------
Introduction.
Olle Hedman recently came out with an amazing pixel-plotting routine.  This tutorial will just introduce you to it, and even
explain it!

Pixel Code Explanation.
Thanks to Olle for explaining this to me.


PIX:
;	push	af		; Uncomment these to save regs..  
;	push	de

	ld	d,0		; Do y*12
	sla	e
	sla	e
	ld	hl,0
	add	hl,de
	add	hl,de
	add	hl,de


Now, why does he do y*12?  Ok, this routine plots to PLOTSSSCREEN, which is an area 768 bytes big, right?  Now, to plot the
pixel we have to find the byte its in.  Why?  Because we can only set bytes (or words) at a time, not bits.  Ok, so why
multiply by 12.  Well, what's 96/8?…12!  Thus, by multiplying by 12, we essentially skip as many as many bytes as we want to go
down.

The instructions behind this are simple enough.  First, Olle initializes d, then multiples e by 4 with two SLA statements
(check Tutorial 28 for bit-level instructions).  Initializes hl, and in essence multiples de by 3, by adding it three times
over to HL which is keeping the running total.

       ld      d,0             ; Do x/8

       ld      e,a

       srl     e

       srl     e

       srl     e

       add     hl,de

Ok, now we have to find the horizontal byte we're in.  This is done by dividing x by 8, because there's 8 bits in a byte!  For
example, if a = 5, 5/8 truncated is 0, so it would be in the first byte of our horizontal line that HL is already pointing to. 
So, we would add 0 to hl…it would still point to the first byte in our horizontal line.  If a=53, it would point to the 6th
byte, thus, we would add 6 to HL.  We now know the exact BYTE that our pixel resides in.

       ld      de,8e29h

       add     hl,de           ; Add address to graphbuf

We have the byte number, but we need to add it to PLOTSSCREEN so that it points to the right place, don't we!

       ld      de,0007h     	; Get the remainder of x/8
       and     e


Ok, check this out!  This is really neat, IMO.  Note that a still contains the original x address.  Now, we want the bit on our
byte, so that we can then mask the byte and update PLOTSSCREEN appropriately.  So get the bit, get back the three bits we
shifted (thus, destroyed) when we divided.  We do this by using a bit-mask (see Tutorial 13).  07h is equivalent to 00000111d. 
So we AND a and e.  And bingo, we have the bit!  Don't believe?…let's look.  Assume you want 12 as the x-coordinate:

12 			= 00001100  AND
bitmask	= 00000111
	 		---------
	  		00000100 = 4

And that is correct!  We'd want the fourth bit (in the second byte)!  Pretty neat, huh?

       ld 	e,a
       ld	IX,pixtable  	; Look up in table which pixel to be set
       add	IX,de		
       ld	a,(IX+0)  	; and load this

Ok, now that we have the bit number, we need to set the byte.  First of all, we load the bit position into e, then a look-up
tables of the bytes into IX (an index register).  We then add IX and de, now IX points to the correct byte in the lookup table
(if a = 3, then IX points to 00100000b).  We then load this into a again.

or	(HL)		; 'xor' to toggle pixel, 'and' cpl to clear.
	ld	(HL),a		


Ok, now…We don't want to clear all the bits (remember, we're using Bytes here), so we OR it to keep everything, and our new
bit.  For example, using our 4 example and a made-up byte from Plotscreen:

Lookup (using 4)		= 00010000   OR
Example of Plotscreen	= 01001001
			   		--------
 					01011001

Notice, that both our bit, and the original plotsscreen contents are there!  Finally, you put the byte into (HL), and bingo,
your pixel is set!

;	pop	de
;	pop	af

	ret

pixtable:
	.db	10000000b
	.db	01000000b
	.db	00100000b
	.db	00010000b
	.db	00001000b
	.db	00000100b
	.db	00000010b
	.db	00000001b


Phew, there you have it!  Amazing piece of coding from Olle!!

New Commands.
	pix		- Yep, you guessed it…calls his routine!


Code.

Tiny program, not worth putting in, but if you want to quickly test it…

ld	b,96
loop1:
	ld	a,b
	push	bc
	ld	b,64
loop2:
	ld	e,b
	call	pix
	djnz	loop2
	pop	bc
	djnz	loop1
	call	_grbufcpy_v
	ret

;Put Olle's code here!;


Note that Olle's code is available here.

Conclusion.

This is a GREAT exercise in bit-level ASM, and looking and understand real source code.  Hopefully, soon I'll get on Movax's
case, and see if I can explain his sprite routines.

Thanks to Olle!


Follow-Ups: