![]() |
Assembly question - Printable Version +- Forum (https://www.boriel.com/forum) +-- Forum: Compilers and Computer Languages (https://www.boriel.com/forum/forumdisplay.php?fid=12) +--- Forum: ZX Basic Compiler (https://www.boriel.com/forum/forumdisplay.php?fid=11) +---- Forum: Help & Support (https://www.boriel.com/forum/forumdisplay.php?fid=16) +---- Thread: Assembly question (/showthread.php?tid=543) Pages:
1
2
|
Re: Assembly question - slenkar - 05-14-2013 thanks Ive read a few tutorials on spectrum screen memory but still dont understand it the first 3 bits are always 010 so a lot of screen manipulation starts off with binary rotations, aside from that I dont get it :?: :?: Re: Assembly question - LCD - 05-15-2013 Yes, rotations are important. I'm using rotation to calculate screen address from line. You just need to change bits 0-2 with 3-5 to get the address that can be multipied with 32 (bitshift 5 times to left) and added 16384 or 49152 to get the address in screen memory. This all can be done much easier in binary. Re: Assembly question - britlion - 05-15-2013 boriel Wrote:britlion Wrote:You could read my tutorial for Berksman? It discusses things like where to place data for the map in an array within ZX Basic as one of the many topics I rambled on about randomly in passing while making a game.... Um. It's the first one listed? Re: Assembly question - boriel - 05-15-2013 britlion Wrote:Yes, I realised later but didn't commented it here. Sorry.boriel Wrote:britlion Wrote:You could read my tutorial for Berksman? It discusses things like where to place data for the map in an array within ZX Basic as one of the many topics I rambled on about randomly in passing while making a game.... I overlooked it at first, because you say the "ASM" tutorial, and for me this is the "Awesome PAC-MAN Tutorial" ![]() Update: No joke. Many people here has read your tutorial. Me included ![]() Re: Assembly question - britlion - 05-15-2013 slenkar Wrote:thanks It's a bit hard to get your head around - though if you call it a binary number it becomes clearer. There are two ways of thinking of this. If T = third of screen, R = Character row inside a third (row 0 to row 7), and L = line of that character row, and X = X value along the screen, then the 16 bit value you want in binary is: 010TTLLLRRRXXXXX So you can think of it as chaining together numbers T (a two bit number 0-2 ["3" here is in the attributes - there isn't a "fourth third"]), followed by L (a three bit number 0-7), R (a three bit number 0-7), and the X value (a 5 bit number 0-31) As you can imagine, this requires some bit shuffling to glue the parts together. The L before R seems strange - but inside a character, you can actually go down one line with an 8 bit command INC H, which is very fast. (It sets bit 8 of the above, or the last bit of the high byte). Alternatively, you can think of it in pixels alone - and you have an X value along the screen, and a Y value down the screen. In this case you have: 0 1 0 Y7 Y6 Y2 Y1 Y0 Y5 Y4 Y3 XXXXX So it's 010 YYYYYYYY XXXXX Yay! Except the 8 Y value bits are in the wrong order ![]() e.g. if we have a Y value with bits 76543210 - we can rotate it left twice to get 54321076, then use AND to map the first three bits off into another register. (e.g. AND 11100000) then AND the X value with the result to make the lower byte. So yes. It's complex. But read this post over and over while looking at some screen routines ( <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:Library#Graphics_Library">http://www.boriel.com/wiki/en/index.php ... cs_Library</a><!-- m --> ) and hopefully you'll work out how it was all done. Here's an example from the high res print routine: Code: ;HRPAT is a subroutine TO convert pixel values into an absolute screen address Re: Assembly question - boriel - 05-15-2013 The best way, IMHO, is to try to write your own routine in ZX Basic (in BASIC, yes). UIsing POKE 16384 + Yourfunction(x, y) to calculate the screen address. I did it in Sinclair BASIC years ago, and you will learn a lot doing it. :roll: Update: This is what I did, If I recall correctly.
Re: Assembly question - slenkar - 05-15-2013 thanks, I made this little program to draw on each line going down the screen but it didnt look like I expected Code: function FASTCALL drawthis() as ubyte it just draws a couple of blobs to the screen I am using INC H to go down the screen using BC as a 16 bit counter Loading 254 into screen memory each time Re: Assembly question - boriel - 05-15-2013 slenkar Wrote:thanks,Yes, you are on STEP 3) of the list ![]() Britlion has written the generic solution. But I suggest you to proceed as you are doing now (you are doing great, BTW!). Basically, each time you use INC H, you are adding 256 to HL. Lets see it in binary form:
HL = 16384 + 256 * 7 = 18176 = 0x4700 = BIN 0100 0111 0000 0000 As you can see, the bit pattern seems to be: BIN 0100 0xxx 0000 0000 where 'xxx' ranges from 000 to 111 (0..7). These are the caracter scalines. But LINE 8 is just 32 bytes ahead of LINE 0! This means, we have to "undo" 7 times INC H, and ADD 32 to L. A simple way to do this could be, DEC H, DEC H, DEC H (7 times) and then ADD L, 32. :roll: But this is slow and takes 9 bytes. Using bit operations leads to an optimized method. ![]() Experiment with this now, and try again. If not, we'll keep working on it. Re: Assembly question - slenkar - 05-16-2013 thanks both for number 1 did you mean horizontal lines? if so here is the solution: Code: function FASTCALL drawthis() as ubyte doing it with vertical lines would be doing the above, but drawing lines in like this 100000000 replaced with.. 11000000 replaced with.. 11100000 replaced with.. 11110000 replaced with.. 11111000 replaced with.. 11111100 replaced with.. 11111110 replaced with.. 11111111 Re: Assembly question - slenkar - 05-16-2013 this is fun here is how I printed a block to co-ords 7,3 Code: function FASTCALL drawthis() as ubyte but if I move INC H to just before the jump command the screen goes a bit weird Code: function FASTCALL drawthis() as ubyte EDIT ohhh INC seems to set the zero flag Re: Assembly question - boriel - 05-16-2013 Hmmm. This wasn't what I was thinking. The ZX Spectrum screen has 24 * 8 = 192 scan lines (0..to 191 couting from the top of the screen). My idea was you created an *universal* function to return the memory address of a scan line. This way: Code: function ScrAdd(scanline as uByte) as Uinteger Code: Lets try for line 120 (BIN 0111 1101) The number 32 * 64 above is 32 bytes * 64 lines = Number of bytes on each 1/3 of the screen (each 3rd has 64 lines, of a total of 64 * 3 = 192 lines). Here is the function (in ZX BASIC): Code: FUNCTION ScrAddr(scanline as Ubyte) AS UInteger ![]() E.g.
Re: Assembly question - slenkar - 05-16-2013 yes that is what I need for sprites, but I am trying to do some scrolling got it to work ![]() Code: function FASTCALL drawthis() as ubyte I slowed it down intentionally so you can see whats going on Re: Assembly question - slenkar - 05-16-2013 scrolling 8 lines: Code: function FASTCALL drawthis() as ubyte why does it wrap around? thats like a bit shift affecting the byte next to it?!?! |