Jump to content
IGNORED

Assembly->XB link project


Opry99er

Recommended Posts

Here's one Marc wrote:

 

       LI   R0,>9F00
       MOVB R0,@>8400          

That part is dealing with the sound-chip, so it's not relevant to VMBW.

 

 

Obviously Matthew's is dependant on other VDP routines he wrote, but I have them all in the Beryl scroller that he sent me. It's really interesting to read through that source... just so neat and clean. =)

Yes, often you'll discover, that you will help yourself to better and more quickly reread/understand and debug your own code, if you have a lot of comments like that.

 

 

I'm studying "ORI" right now.... Looks like it compares two words and sets the bits to the new word if either of the bits are set in either of the compared words.

Yes, a bit set in either will set a bit in the "output".

 

The comment "Set read/write bits 14 and 15 to write (01)" might be slightly off (no big deal). The assembler instruction is "just" setting bit 14 and not carrying about the state of bit 15. We must assume bit 15 to be 0 to get to 01. I don't know if 11 will work.

 

The three possible commands should be, write to register (10), set address for write (01), and set address for read (00).

 

:cool:

Link to comment
Share on other sites

Obviously Matthew's is dependant on other VDP routines he wrote, but I have them all in the Beryl scroller that he sent me. It's really interesting to read through that source... just so neat and clean. =)

 

Actually, each of my VDP routines is stand alone. If you set the equates in your code, you can use only the ones you need. If you don't want to set the equates, then just change the routine and hard code the VDP addresses.

 

 

I'm studying "ORI" right now.... Looks like it compares two words and sets the bits to the new word if either of the bits are set in either of the compared words. Therefore:

 

0101100110011001
and
0011101111000100 
becomes

0111101111011101

 

I guess I'm just trying to figure out why this is so crucial in a VDP write routine....

 

The ORI itself is not crucial to the VDP in any direct way. It is just convenient for what we have to do to communicate with the VDP. I think I covered some of this in the assembly thread, but I'll do it here to make sure.

 

The VDP has a few things the programmer needs to be aware of:

 

1. An internal "auto incrementing" address register. This register is FOURTEEN bits, so 2^14 = 16,384 (16K) which is the maximum RAM the 9918A can address.

 

2. Seven internal WRITE ONLY registers that control the VDP's video mode, location of various "tables" used to define patterns, sprites, etc.

 

3. An 8-bit data bus to communicate with the host computer.

 

4. A specific protocol for communicating.

 

 

There are four things we can do with the VDP:

 

1. Read the status register.

 

2. Write one of the seven registers.

 

3. Write a byte to a VRAM location.

 

4. Read a byte from a VRAM location.

 

 

So let's just focus on writing a byte to the VDP right now, since that's what you are trying to do. The VDP's protocol for writing a byte is this:

 

1. Set up the VDP's internal 14-bit address register to the location in VRAM where you want to write the byte.

 

2. Write the byte.

 

 

In the 9918A datasheet are the details of the protocols we have to follow, in case you want a detailed reference.

 

NOTE: The VDP only reads and writes to VRAM at the memory address pointed to by its internal address register. That's why we have to set this register, otherwise we have no idea where the byte will be written. You can not read the current address of the VDP's internal address register, it is write only.

 

 

Now, when setting the VDP's internal address register, we have to tell the VDP if we intend to read or write after setting the address. Because the VDP's address register is 14-bits, and we transfer data to / from the VDP 8-bits (1 byte) at a time, we have to make two 1-byte write operations to set the VDP's internal address.

 

Now, since the VDP's address register will only use 14 of the 16 bits we are sending, the two MOST SIGNIFICANT bits are used by the VDP to know if we intend to read or write after setting the internal address.

 

There is also a MODE pin on the VDP that indicates if a register is being written to (the address register, or one of the other internal registers), or if a byte of VRAM is being read or written. This mode pin is controlled by logic on the motherboard that is controlled by the CPU address we indicate. Basically that's why we have to use different address for the VDP, that and because the 9900 does a read-before-write. You don't have to worry about the details of this mode pin, you just have to make sure you use the proper HARD WIRED addresses to communicate with the VDP. In code it is easier to use EQUates, but you can use the addresses directly in your code if you want, they will NEVER change (but it is considered bad practice to use hard coded values in code, so use EQUates.)

 

 

VDP Hard Wired Addresses:

 

>8800 Used to read data from the VDP

>8802 Used to read the VDP status register

>8C00 Used to write data to the VDP

>8C02 Used to set the VDP's internal address register

 

So, logic chips in the console will set the MODE pin correctly when we are writing to address >8C02, and that is how the VDP can tell the difference between when we are trying to set up its internal address or when we are just writing data bytes. After all, bytes of an address look just like bytes of data, so this is how the VDP knows the difference.

 

 

Now, the VDP uses those two MSb (most significant bits) of the 16-bit address to know if we intend to read or write data after setting the address register. Technically there is really no difference, however internally the VDP will to a pre-fetch of the data byte if we indicate we intend to read vs. write a byte. Also, if you tell the VDP you are setting up a read address, but then do a write operation, your byte will not go to the address you set up. But don't worry about that right now, just follow the rules and things will work. Leave the rule breaking to Marc. ;)

 

 

To set the address we have to make two writes, since we can only send a byte at a time. The VDP expects the LSB first, then the MSB of the address. So we usually put the VRAM address we want to write to into a CPU register, then pass the bytes:

      LWPI >8300
.
.
.
      LI   R0,some_vram_address
      MOVB @8301,@>8C02

 

We generally *ASSUME* that R0 will never have an address greater than 16,385 since that's the largest VRAM address the VDP can accept. That means that we *ASSUME* the top two bits of the CPU register we are using will always be ZERO when we start this code.

 

Because we have to send the LSB first, the MOVB uses the byte address of R0. Remember that the 9900 will always send the MBS of a register when using byte instructions. You will also see a lot of people do this:

 

       SWPB R0
       MOVB R0,>8C02
       SWPB R0
       MOVB R0,>8C02

 

That puts the LSB into the MSB, then sends the MSB (LSB of the address) to the VDP. I don't like to do this personally because I'm a freak about speed and memory use, and you then have to do another SWPB to get the original MSB back into the MSB of the register. To me, it makes more sense to exploit the fact that our VDP keeps its registers in RAM, and we know where those registers are, so just reference the LBS of R0 directly. That's where you see in my code where I set up R0LB, R1LB, etc. So my initial code above is usually written:

 

      LI   R0,some_vram_address
      MOVB R0LB,@>8C02

 

Next we send the MSB of the address to the VDP. At this point we need to make sure the top two bits are set accordingly:

 

  MSB of setup byte, ie. second byte set to address >8C02
--------
00xxxxxx - Read from VRAM
01xxxxxx - Write to VRAM
10xxxxxx - Write to VDP Register
11xxxxxx - Illegal (undefined)

 

The xxxxxx is the top part of the 14-bit address we are sending. The low 8 bits were sent first.

 

So, if we are setting up the address and intend to do a read operation, we don't have to do anything but send the MSB of R0 now (ASSUMING we don't have a address greater than 16,385 in R0!!!) To indicate we are setting up an address and intend to WRITE, we need to set the two top bits of R0 to 01. This is where we use ORI instruction. The logical OR operation will let us set zero bits to one bits without affecting the other bits in the register, which is exactly what we need. Also note that the 9900 only has an OR-immediate, ie. can only OR with an immediate value. The OR value is called a "MASK" and is a common term when using OR, AND, and XOR to do "bit twiddling".

 

      ORI  R0,>4000
      MOVB R0,>8C02

 

If you convert >40 to bits, it looks like this: 01000000. So, ORing that with R0 will leave all the other bits as they are, but will ensure that the second top bit is set to 1. Now, we again ASSUME that R0 did not have a value over 16,385, so the top MSb would already have been zero. So we end up with the proper "01" in the top two bits of the second byte to let the VDP know we are going to write after setting up this address.

 

If we were reading, we do not have to do the ORI since we assume the top two bits are already "00", and "00" tells the VDP we intend to read.

 

 

Now that the address is set, the VDP is expecting bytes to read or write. So, for VSBW we just write the byte:

 

VSBW   MOVB @R0LB,@VDPWA   Send low byte of VDP RAM write address
      ORI  R0,>4000       Set read/write bits 14 and 15 to write (01)
      MOVB R0,@VDPWA      Send high byte of VDP RAM write address
      MOVB R1,@VDPWD      Write byte to VDP RAM
      B    *R11           Return

 

This code assumes the normal setup of the address in R0, and the byte to write in the MSB of R1, and called with BL @VSBW.

 

The last thing you need to understand is the "auto increment" feature of the VDP. After *any* byte read or write operation, the VDP auto increments the internal address register. Thus if you were doing a bulk read or write of data, you only have to set the start address of the block, then read or write the data over and over without having to mess with the address again. That's what VMBW does. This is also why using VSBW in a loop is SLOW! VSBW sets the VDP address every time you call it, since it assumes you are writing a single byte, then changing the address to somewhere else totally different. When you need to write the same byte to multiple VRAM locations (like clearing the screen) it is better to use a new VDP function with did not exist in the one's TI came up with: VSMW. I came up with this as a natural conclusion, as did many other people independently. It just makes sense.

 

Hopefully this makes more sense to you now. It is not really that mysterious, you just have a learn a little more about the 99/4A and how the VDP is wired into it. Since setting up the address all the time is a pain and repetitive, we write up routines like we have. The console routines ultimately do the same thing, however they use the slow BLWP, an 8-bit workspace, and internally branch again.

 

Last note: speed. Many people used the SWPB instruction between writes to the VDP because of the problem of overwriting the VDP. This extra instruction between writes to the VDP (when setting up the address) was to give the VDP the time it needed to function. However, we have proved that on the 99/4A that you cannot over run the VDP unless you specifically run from the scratch pad RAM to get the most speed you can. Or if you have 32K in the console on the 16-bit bus.

 

Matthew

Edited by matthew180
Link to comment
Share on other sites

Thank you Matthew. That is a very nice explanation. =)

 

I should have some stuff to show on this process very soon... just spent two days rebuilding my computer after a big crash. NOT fun. Does this sound familiar to any of you?

 

-Run virus scan

-Defrag

-Memory scan

-Disk Scan

-GOTO Run virus scan.

 

Dude.... I'm so thankful it's over....

Link to comment
Share on other sites

That's a pretty wild graphic there, sometimes. =) Thanks for that. Also glad you like the myspace site. =)

 

 

Right now I'm getting the XB motion routines together for the player character. I'm currently using strings to display the viewport in XB while I work on the VMBW routine. When I have something to show, I'll post it. For the here and now, I'm slogging through this crap and trying to figure out "why". =)

 

 

Link to comment
Share on other sites

Okay... it ran and put the bytes on the screen... just the first line. Looks to work quite nicely. I imagine that long pause before it actually draws is just XB creating the INIT space for the assembly routines.... Thanks, sometimes. Looking good. =)

Oh, that was quick. That's good. You know how to do that. Excellent.

 

Now try and understand the assembler code and add comments (to the code).

 

The source only has the first 3 rows from the big map. If I have all 72 rows in the source, the CALL LOAD takes like forever.

 

Have you ever tried the Debugger of Classic99 ?

 

Finally, try and display 3 rows instead of just 1. Careful now.

 

:)

Link to comment
Share on other sites

Well, I failed with some very pretty colors. =)

 

DRAW   MOV  R11,R10       	SAVE XB RETURN ADDRESS

  	LI   R0,>0
  	LI   R1,MAPDAT
  	LI   R2,>1C
LI R3,3
DRW	BL   @VMBW
AI R0,32
AI R1,28
DEC R3
JNE DRW

 

I need to read up on what auto increments and what doesn't. I also noticed that the VMBW uses R0 and R2, so whatever WAS there in the DRAW routine is no longer there... I was planning to add a new label and instead of using RT at the end of the VMBW routine, have it JMP to that label (which will reload all the registers after incrementing R0 by 32) but it failed as well.... I'll need to experiment more... using VSBW is ALOT easier for me... just because I understand it.

 

 

Link to comment
Share on other sites

The main difference between using the VDP routines in the console vs. the ones I wrote is R0, R1, and R2 are usually destroyed. The workspace used by the routines is the same one you are using.

 

What is it about VMBW that you don't understand?

 

The only thing that auto-increments are instructions with + signs in them, like:

 

MOVB *R1+,@>8C00

 

That would move the MSB of R0 to the address >8C00, then increment the *value* in R1 by 1. VMBW uses an instruction like that to move data from a location in CPU RAM to VRAM. >8C00 is the hard wired address you use to write *data* to the VDP. Remember, the VDP will auto-increment its internal address after each write. So, R1 starts out pointing at the beginning of your data and is auto-incremented by the MOVB instruction after each byte written. The VDP is also auto-incrementing its internal address, so you end up writing a block or bytes from CPU RAM to VRAM. R2 is used as a counter.

 

So, R0 holds the start address in VRAM, R1 holds the start address in CPU RAM, and R2 is the number of bytes to write. After VMBW, R0 will be the same, R1 will have been incremented by the count that was in R2. R2 will be zero. The VDP's internal address will also be incremented by the count that was in R2.

 

Use VSBW when you need to write a single byte to some VRAM location, and the next data you write needs to go to some totally different address.

 

Use VMBW when you have a block of data in CPU RAM that you need to write to VRAM, like character patterns, a whole screen of data, etc.

 

The reason you might be getting confused in this case is because you are used to your workspace not being overwritten when you called BLWP @VMBW vs. BL @VMBW. Remember, BLWP stands for Branch and Load Workspace Pointer. Which means the called routine will use a different workspace than the calling workspace.

 

Your code looks like you need to write 28 bytes to the screen, which means you are 4 short of a full line. You might want to consider adding those 4 bytes as padding, which would make your routine a *lot* easier. Short of that, to do what you are needing to do, you just need to set up some temporary registers since VMBW will modify R1 and R2. Something like this:

 

       LI   R0,>0000     Start of VRAM screen name table (top left corner)
       LI   R1,MAPDAT    CPU Map Data, 28 bytes per line
       LI   R3,3         Write 3 lines until Owen sees what is going on

* Set up the R2 counter each time a line is written.
DRW
       LI   R2,28        Write 28 bytes at a time (don't use hex if you don't have to)
       BL   @VMBW        Write the line
       AI   R0,32        R0 was not affected, so bump down 1 line in VRAM
       DEC  R3           Count the line
       JNE  DRW          Loop if not done

 

Note that I'm not doing anything with R1. You started R1 pointing to the MAPDAT, and I assume the data is 28 bytes per line. So after the VMBW call, R1 will already be pointing to the start of the next line of map data. All you have to do is adjust the screen address to start writing to, which is in R0 and is not modified by VMBW (well, it is restored anyway.)

 

Ask specific questions if you don't understand something.

 

Matthew

Link to comment
Share on other sites

BL vs. BLWP..... That is the issue primarily. So, after a block of data is written using VMBW, the Byte at the next address will be written by the following VMBW.... Therefore it is unnecessary to attempt to increment R1, as it is already done.....

Edited by Opry99er
Link to comment
Share on other sites

I just sat here debugging for the last 15 minutes... I realized that removed RT from the VMBW routine and forgot to put it back in... stupid. Got it now... I wasn't TOO far away, just needed a bit of direction. =) Thank you Matthew and sometimes. =)

 

fortest.png

 

 

 

Now I will attempt to draw the entire viewport in the proper location. I will leave the border out for now... That's why I can't really pad the write data, because on the left and right of the viewport there will be a permanent border. Blasting 2 ">20's" on each side of the map data would blow out my border. This is one reason I had thought about doing individual maps as opposed to one BIG map and doing math to display the proper section... CALL LINK (MAP2) could have the entire border in the map data... that adds 160 or so extra bytes to each map though...

 

 

 

 

***edit***

Then again, it would be easy to draw the border AFTER the viewport each time. This would allow me to pad the map as you suggest, Matthew.... That way, only 92 bytes need be in memory for the viewport TOTAL. Just redraw it each time

 

 

 

Edited by Opry99er
Link to comment
Share on other sites

Okay, I'm going to try loading the entire map into memory and draw from that. I will need to skip 28 bytes for each line. here's how it looks in ASCII form:

 

 

*--------*--------*
*    	*    	*
*	1   *   2	*
*--------*--------*
*    	*    	*
*	3   *   4	*
*--------*--------*
*    	*    	*
*	5   *   6	*
*--------*--------*

 

I want to draw section 1. So I will need to write 28 bytes, skip 28 bytes, carriage return, write 28 bytes, skip 28 bytes, carriage return, continue......

 

 

Can I use an AI R1,28? Will that work?

 

***God, that ASCII art really sucks... even using Notepad++ and code tags. eek

Edited by Opry99er
Link to comment
Share on other sites

Yeeeeee haw!!!!

 

forestviewport.png

 

 

 

 

  	DEF  DRAW

VDPWD  EQU  >8C00     		VDP RAM WRITE DATA
VDPWA  EQU  >8C02     		VDP RAM READ/WRITE ADDRESS


DRAW   MOV  R11,R10   		SAVE XB RETURN ADDRESS

*Draw border (inefficient, but by golly it works)
      LI R0,256   	starting location in VRAM
      LI R1,BORDER	CPU data
  	LI R2,512   	number of bytes to write
  	BL @VMBW    	write it


  	LI   R0,322   	Start of VRAM screen name table (top left corner)
  	LI   R1,MAPDAT	CPU Map Data, 28 bytes per line
  	LI   R3,12    	12 rows of map data for viewport

* Set up the R2 counter each time a line is written.
DRW


  	LI   R2,28    	Write 28 bytes at a time (don't use hex if you don't have to)
  	BL   @VMBW    	Write the line
  	AI   R0,32    	R0 was not affected, so bump down 1 line in VRAM
  	AI R1,28    	Offset for next line of viewport
  	DEC  R3   		Count the line
  	JNE  DRW      	Loop if not done



  	B	*R10          	RETURN TO XB

 

 

Edited by Opry99er
Link to comment
Share on other sites

Entire source below

 

 

 

 

  	DEF  DRAW

VDPWD  EQU  >8C00     		VDP RAM WRITE DATA
VDPWA  EQU  >8C02     		VDP RAM READ/WRITE ADDRESS


DRAW   MOV  R11,R10   		SAVE XB RETURN ADDRESS

*Draw border (inefficient, but by golly it works)
LI R0,256   	starting location in VRAM
LI R1,BORDER	CPU data
LI R2,512   	number of bytes to write
BL @VMBW    	write it


  	LI   R0,322   	Start of VRAM screen name table (top left corner)
  	LI   R1,MAPDAT	CPU Map Data, 28 bytes per line
  	LI   R3,12    	12 rows of map data for viewport

* Set up the R2 counter each time a line is written.
DRW


  	LI   R2,28    	Write 28 bytes at a time (don't use hex if you don't have to)
  	BL   @VMBW    	Write the line
  	AI   R0,32    	R0 was not affected, so bump down 1 line in VRAM
AI R1,28    	Offset for next line of viewport
  	DEC  R3   		Count the line
  	JNE  DRW      	Loop if not done



  	B	*R10          	RETURN TO XB



* VDP MULTIPLE BYTE WRITE

VMBW   ORI  R0,>4000
  	SWPB R0
  	MOVB R0,@VDPWA
  	SWPB R0
  	MOVB R0,@VDPWA
VMBW1  MOVB *R1+,R12
  	AI   R12,>6000 		ADD OFFSET
  	MOVB R12,@VDPWD
  	DEC  R2
  	JNE  VMBW1
  	
RT

BORDER
            		
  	DATA >6265,>6565,>6565,>6565	;
  	DATA >6565,>6565,>6565,>6565	;
  	DATA >6565,>6565,>6565,>6565	;
  	DATA >6565,>6565,>6565,>6564	;
* -- Map Row 9 --               		
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 10 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 11 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 12 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 13 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 14 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 15 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 16 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 17 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 18 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 19 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 20 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 21 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 22 --                  	
  	DATA >6120,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2020	;
  	DATA >2020,>2020,>2020,>2061	;
* -- Map Row 23 --                  	
  	DATA >6365,>6565,>6565,>6565	;
  	DATA >6565,>6565,>6565,>6565	;
  	DATA >6565,>6565,>6565,>6565	;
  	DATA >6565,>6565,>6565,>6560	;


MAPDAT 
MD10   DATA >8989,>8989,>8989,>8989	;
  	DATA >8989,>8989,>8989,>8989	;
  	DATA >8989,>8989,>8989,>7289	;
  	DATA >7272,>7089,>8989,>8989	;
  	DATA >8989,>8989,>8989,>8989	;
  	DATA >8989,>8989,>8989,>8989	;
  	DATA >8989,>8989,>7070,>7070	;
* -- Map Row 1 --               		
  	DATA >8989,>8989,>8989,>8966	;
  	DATA >6666,>6666,>6666,>6666	;
  	DATA >6666,>6689,>8989,>8989	;
  	DATA >8989,>7070,>8889,>8988	;
  	DATA >888C,>8D8F,>8889,>8988	;
  	DATA >8889,>8989,>8989,>8988	;
  	DATA >8888,>8989,>7070,>7270	;
* -- Map Row 2 --               		
  	DATA >8989,>8888,>8888,>8866	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>6689,>6666,>6666	;
  	DATA >6666,>7089,>8970,>8888	;
  	DATA >888B,>8A8E,>8866,>6666	;
  	DATA >6666,>6689,>8988,>8888	;
  	DATA >8888,>8989,>7070,>7070	;
* -- Map Row 3 --               		
  	DATA >8988,>8888,>8888,>8866	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>6689,>6688,>8989	;
  	DATA >8966,>7070,>7070,>7070	;
  	DATA >8884,>8283,>8866,>8888	;
  	DATA >8888,>6689,>8866,>6666	;
  	DATA >6666,>8889,>7270,>7070	;
* -- Map Row 4 --               		
  	DATA >8988,>8888,>8888,>8866	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8889,>6689,>6670,>7270	;
  	DATA >8966,>7270,>7072,>7072	;
  	DATA >8988,>8888,>8866,>8888	;
  	DATA >8888,>6688,>8866,>8888	;
  	DATA >8866,>8889,>7072,>7070	;
* -- Map Row 5 --               		
  	DATA >8989,>8988,>8888,>8866	;
  	DATA >6666,>6666,>6666,>6666	;
  	DATA >8888,>6666,>6689,>7072	;
  	DATA >7066,>7070,>7270,>8989	;
  	DATA >8989,>8888,>8866,>8888	;
  	DATA >8888,>6666,>6666,>8888	;
  	DATA >8866,>8989,>7070,>7070	;
* -- Map Row 6 --               		
  	DATA >8989,>8888,>8888,>6666	;
  	DATA >6666,>6666,>8888,>8866	;
  	DATA >8888,>8888,>8889,>8972	;
  	DATA >7266,>7270,>8989,>8989	;
  	DATA >8888,>8889,>8866,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8866,>8972,>7072,>7272	;
* -- Map Row 7 --               		
  	DATA >8988,>8866,>6666,>6666	;
  	DATA >6666,>6666,>8888,>8866	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >7066,>7070,>8989,>8988	;
  	DATA >8888,>8888,>8866,>8888	;
  	DATA >8988,>8888,>8888,>8889	;
  	DATA >8866,>8970,>7070,>7270	;
* -- Map Row 8 --               		
  	DATA >8988,>8866,>8888,>6666	;
  	DATA >6666,>6666,>8888,>8866	;
  	DATA >6666,>6666,>6666,>6666	;
  	DATA >6666,>6666,>6666,>6666	;
  	DATA >6666,>6688,>8866,>8889	;
  	DATA >8888,>8888,>8988,>8888	;
  	DATA >8866,>8972,>7070,>7070	;
* -- Map Row 9 --               		
  	DATA >8988,>8866,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8989,>7089,>8988,>8888	;
  	DATA >8888,>6688,>8866,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8866,>7270,>7070,>7070	;
* -- Map Row 10 --                  	
  	DATA >8989,>8866,>8888,>8888	;
  	DATA >8888,>8888,>888C,>8D8F	;
  	DATA >8888,>8888,>8888,>8989	;
  	DATA >8972,>7070,>8989,>8888	;
  	DATA >8888,>6688,>8866,>8888	;
  	DATA >8889,>8989,>6666,>6666	;
  	DATA >6666,>7272,>7072,>7072	;
* -- Map Row 11 --                  	
  	DATA >8989,>8866,>8888,>8888	;
  	DATA >8888,>8888,>888B,>8A8E	;
  	DATA >8888,>8888,>8889,>8989	;
  	DATA >7070,>7272,>8989,>8988	;
  	DATA >8888,>6688,>8866,>8888	;
  	DATA >8870,>8989,>6666,>6666	;
  	DATA >6666,>7272,>7070,>7070	;
* -- Map Row 12 --                  	
  	DATA >8988,>8866,>8888,>8888	;
  	DATA >8888,>8888,>8884,>8283	;
  	DATA >8888,>8888,>8889,>8970	;
  	DATA >7270,>7070,>7070,>8989	;
  	DATA >8888,>6666,>6666,>8889	;
  	DATA >7072,>7089,>6666,>6666	;
  	DATA >6666,>7072,>7066,>6666	;
* -- Map Row 13 --                  	
  	DATA >8988,>8866,>6666,>6666	;
  	DATA >6666,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8889,>7070	;
  	DATA >7070,>7270,>2070,>7089	;
  	DATA >8989,>8989,>8889,>8870	;
  	DATA >2072,>7089,>6666,>6666	;
  	DATA >6672,>7272,>7066,>7070	;
* -- Map Row 14 --                  	
  	DATA >8989,>8988,>8888,>8888	;
  	DATA >8866,>6666,>6667,>6767	;
  	DATA >6767,>6767,>8989,>7020	;
  	DATA >7070,>7070,>7070,>7270	;
  	DATA >8989,>8989,>8989,>8988	;
  	DATA >7270,>7272,>6666,>6666	;
  	DATA >7072,>7270,>7066,>7070	;
* -- Map Row 15 --                  	
  	DATA >8989,>8988,>8888,>8888	;
  	DATA >8888,>8888,>8867,>6767	;
  	DATA >6767,>6767,>7270,>7070	;
  	DATA >7072,>7270,>7070,>7270	;
  	DATA >7270,>7072,>7089,>8989	;
  	DATA >7070,>7270,>7289,>8972	;
  	DATA >7270,>7270,>6666,>6670	;
* -- Map Row 16 --                  	
  	DATA >8C8D,>8F89,>8989,>8989	;
  	DATA >8989,>8988,>8867,>6667	;
  	DATA >6767,>6767,>7272,>7070	;
  	DATA >7270,>7070,>7270,>7072	;
  	DATA >7270,>7070,>7070,>7070	;
  	DATA >7070,>7272,>7272,>7070	;
  	DATA >7070,>7072,>6666,>6672	;
* -- Map Row 17 --                  	
  	DATA >8B8A,>8E89,>8989,>8988	;
  	DATA >8888,>8888,>8866,>6767	;
  	DATA >7366,>6766,>8888,>7270	;
  	DATA >7072,>7270,>7072,>8989	;
  	DATA >7072,>7270,>7270,>7070	;
  	DATA >7072,>7270,>7089,>7272	;
  	DATA >7070,>7070,>6666,>6670	;
* -- Map Row 18 --                  	
  	DATA >8482,>8389,>8988,>8888	;
  	DATA >8888,>8888,>8867,>6766	;
  	DATA >6767,>6767,>8888,>8970	;
  	DATA >7270,>7070,>7089,>8989	;
  	DATA >8888,>8888,>7072,>7088	;
  	DATA >8888,>8888,>8989,>8970	;
  	DATA >7070,>7270,>6666,>6670	;
* -- Map Row 19 --                  	
  	DATA >6766,>6766,>6767,>8888	;
  	DATA >8888,>8888,>8867,>6767	;
  	DATA >6767,>6766,>8888,>8989	;
  	DATA >7072,>7272,>7089,>8988	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8989	;
  	DATA >7070,>7270,>7066,>7072	;
* -- Map Row 20 --                  	
  	DATA >8989,>8988,>8866,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >6788,>8888,>8888,>8889	;
  	DATA >8972,>7072,>7289,>8988	;
  	DATA >8888,>6666,>6666,>8888	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8970,>7070,>7066,>7070	;
* -- Map Row 21 --                  	
  	DATA >8989,>8988,>8867,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >6788,>8888,>8888,>8888	;
  	DATA >8972,>7072,>7089,>8988	;
  	DATA >8888,>6666,>7166,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8989,>7270,>7066,>7270	;
* -- Map Row 22 --                  	
  	DATA >8989,>8888,>8867,>6766	;
  	DATA >6767,>6767,>8888,>8888	;
  	DATA >6688,>8888,>8888,>8888	;
  	DATA >8972,>7070,>8989,>8988	;
  	DATA >8888,>6666,>6666,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8989,>7270,>7066,>7070	;
* -- Map Row 23 --                  	
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8867,>6766,>6767	;
  	DATA >6788,>8888,>8888,>8888	;
  	DATA >8989,>7272,>8989,>8888	;
  	DATA >8888,>7166,>6666,>6666	;
  	DATA >6666,>8888,>8888,>8889	;
  	DATA >8972,>7270,>7066,>7070	;
* -- Map Row 24 --                  	
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8888,>8888	;
  	DATA >6788,>8888,>8888,>8888	;
  	DATA >8989,>7072,>8989,>8888	;
  	DATA >8888,>6666,>6666,>8888	;
  	DATA >8866,>8888,>8888,>8888	;
  	DATA >8989,>7070,>7066,>7272	;
* -- Map Row 25 --                  	
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8888,>8888	;
  	DATA >6788,>8888,>8888,>8888	;
  	DATA >8989,>7070,>8988,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8866,>8888,>8888,>8889	;
  	DATA >8972,>7070,>7066,>7070	;
* -- Map Row 26 --                  	
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8989,>8888	;
  	DATA >6767,>8888,>8888,>8888	;
  	DATA >8989,>7089,>8988,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8866,>8888,>8889,>8989	;
  	DATA >7270,>7067,>6767,>6770	;
* -- Map Row 27 --                  	
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8988,>8888	;
  	DATA >6767,>6767,>6788,>8888	;
  	DATA >8989,>8989,>898C,>8D8F	;
  	DATA >8888,>8888,>6666,>6666	;
  	DATA >6666,>8888,>8989,>8972	;
  	DATA >7070,>7067,>6767,>6770	;
* -- Map Row 28 --                  	
  	DATA >8988,>8888,>8888,>6666	;
  	DATA >6666,>6667,>8888,>8888	;
  	DATA >8888,>8888,>6788,>8888	;
  	DATA >8989,>8988,>888B,>8A8E	;
  	DATA >8888,>8888,>6688,>8888	;
  	DATA >8888,>8888,>8989,>8989	;
  	DATA >7070,>7067,>6767,>6770	;
* -- Map Row 29 --                  	
  	DATA >8989,>8888,>8888,>6688	;
  	DATA >8888,>8889,>8888,>8888	;
  	DATA >8888,>8888,>6788,>8888	;
  	DATA >8989,>8988,>8884,>8283	;
  	DATA >8888,>8888,>6688,>8888	;
  	DATA >8888,>8888,>8989,>8989	;
  	DATA >7270,>7070,>6767,>6772	;
* -- Map Row 30 --                  	
  	DATA >8989,>8988,>8888,>6688	;
  	DATA >8889,>8989,>8888,>8888	;
  	DATA >8888,>8888,>6788,>8889	;
  	DATA >8989,>8888,>8888,>8888	;
  	DATA >8888,>8888,>6666,>6666	;
  	DATA >6666,>8889,>8989,>8970	;
  	DATA >7272,>7270,>6767,>6770	;
* -- Map Row 31 --                  	
  	DATA >8989,>8989,>8988,>6688	;
  	DATA >8989,>8989,>8988,>8867	;
  	DATA >6767,>6767,>6788,>8889	;
  	DATA >8989,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8866,>8888,>8989,>7070	;
  	DATA >7070,>7070,>6770,>7072	;
* -- Map Row 32 --                  	
  	DATA >8989,>8989,>8888,>6688	;
  	DATA >8989,>8989,>8988,>8867	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8866,>8888,>8870,>7070	;
  	DATA >7070,>7070,>6770,>7070	;
* -- Map Row 33 --                  	
  	DATA >8989,>8988,>8888,>6688	;
  	DATA >8989,>8989,>8888,>8867	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8989,>8889,>8989	;
  	DATA >8866,>8888,>7070,>7070	;
  	DATA >7272,>7070,>6770,>7270	;
* -- Map Row 34 --                  	
  	DATA >8988,>8867,>6767,>6688	;
  	DATA >8889,>8989,>8888,>8866	;
  	DATA >6666,>6666,>6688,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8989,>8989,>8989,>8988	;
  	DATA >8866,>8888,>7070,>7272	;
  	DATA >7272,>7270,>6770,>7070	;
* -- Map Row 35 --                  	
  	DATA >8989,>8867,>6767,>6688	;
  	DATA >8888,>8889,>8989,>8888	;
  	DATA >8888,>8888,>6666,>6667	;
  	DATA >6767,>6666,>6666,>6666	;
  	DATA >6666,>6666,>6666,>6666	;
  	DATA >6666,>8872,>7272,>7070	;
  	DATA >7270,>7270,>6770,>7070	;
* -- Map Row 36 --                  	
  	DATA >8988,>8867,>6767,>6788	;
  	DATA >8888,>8889,>8989,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8888,>8872,>7070,>7270	;
  	DATA >7072,>7270,>6770,>7020	;
* -- Map Row 37 --                  	
  	DATA >7088,>8867,>6767,>6767	;
  	DATA >6767,>678C,>8D8F,>8988	;
  	DATA >8989,>8989,>8989,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8989,>8889,>8989	;
  	DATA >8888,>8888,>8888,>7072	;
  	DATA >7272,>7270,>6770,>7070	;
* -- Map Row 38 --                  	
  	DATA >7088,>8867,>8888,>8888	;
  	DATA >8888,>678B,>8A8E,>8988	;
  	DATA >8989,>8888,>8888,>8889	;
  	DATA >8989,>8888,>8888,>8888	;
  	DATA >8989,>8989,>8989,>8988	;
  	DATA >8888,>8888,>8888,>8870	;
  	DATA >7072,>7070,>6770,>7070	;
* -- Map Row 39 --                  	
  	DATA >7089,>8867,>6788,>8888	;
  	DATA >8888,>6784,>8283,>8989	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8989,>8989,>8888,>8889	;
  	DATA >8989,>8989,>8889,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >7070,>7070,>6770,>7270	;
* -- Map Row 40 --                  	
  	DATA >7089,>8888,>6788,>8888	;
  	DATA >8888,>6767,>6667,>6667	;
  	DATA >6788,>8888,>8888,>8889	;
  	DATA >8989,>8989,>8989,>8989	;
  	DATA >8967,>6767,>6767,>6788	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8870,>7270,>6770,>7070	;
* -- Map Row 41 --                  	
  	DATA >7070,>8988,>6788,>8C8D	;
  	DATA >8F88,>8889,>8989,>8888	;
  	DATA >6688,>8888,>8888,>8888	;
  	DATA >8988,>8989,>8989,>8989	;
  	DATA >8967,>8888,>8888,>6688	;
  	DATA >8888,>8888,>6767,>6767	;
  	DATA >6788,>7070,>6770,>7070	;
* -- Map Row 42 --                  	
  	DATA >7070,>8989,>6788,>8B8A	;
  	DATA >8E88,>8889,>8989,>8888	;
  	DATA >6788,>8888,>8888,>8888	;
  	DATA >8888,>8989,>8989,>8989	;
  	DATA >8967,>8888,>8888,>6688	;
  	DATA >8888,>8888,>6767,>6767	;
  	DATA >6767,>6767,>6770,>7070	;
* -- Map Row 43 --                  	
  	DATA >7070,>7067,>6788,>8482	;
  	DATA >8388,>8889,>8988,>8888	;
  	DATA >6767,>6667,>6767,>6767	;
  	DATA >6767,>6767,>6767,>6767	;
  	DATA >6767,>8889,>8888,>6688	;
  	DATA >8888,>8888,>6767,>6767	;
  	DATA >6788,>7070,>7070,>7270	;
* -- Map Row 44 --                  	
  	DATA >7070,>7067,>8888,>8888	;
  	DATA >8888,>8889,>8888,>8888	;
  	DATA >6767,>6767,>6767,>6688	;
  	DATA >8888,>8889,>8989,>8888	;
  	DATA >8888,>8889,>8988,>6688	;
  	DATA >8888,>8888,>6767,>6767	;
  	DATA >6788,>7070,>7070,>7270	;
* -- Map Row 45 --                  	
  	DATA >7070,>7067,>7270,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >6767,>6767,>6767,>6788	;
  	DATA >8888,>7070,>8889,>8989	;
  	DATA >8989,>8989,>8988,>6688	;
  	DATA >8888,>8888,>6788,>8989	;
  	DATA >8989,>7072,>7072,>7070	;
* -- Map Row 46 --                  	
  	DATA >7070,>7067,>7072,>7070	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >7270,>7067,>6767,>6788	;
  	DATA >8870,>7070,>7070,>7089	;
  	DATA >8989,>8989,>8989,>6666	;
  	DATA >6666,>6666,>6789,>8972	;
  	DATA >7270,>7272,>7070,>7072	;
* -- Map Row 47 --                  	
  	DATA >7072,>7067,>7070,>7270	;
  	DATA >7070,>7072,>7272,>7070	;
  	DATA >7070,>7070,>7070,>7270	;
  	DATA >7070,>7072,>7089,>7070	;
  	DATA >7070,>7089,>8989,>8989	;
  	DATA >8989,>8989,>8989,>8972	;
  	DATA >7072,>7270,>7070,>7070	;
* -- Map Row 48 --                  	
  	DATA >7070,>7067,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7270	;
  	DATA >7089,>8989,>8989,>8989	;
  	DATA >7088,>8889,>8989,>8889	;
  	DATA >8989,>8989,>8989,>8970	;
  	DATA >7070,>7070,>7070,>7070	;
* -- Map Row 49 --                  	
  	DATA >7070,>7067,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7072,>7089	;
  	DATA >8989,>8989,>8989,>8989	;
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8989,>8989,>8989,>8970	;
  	DATA >7070,>7070,>7070,>7070	;
* -- Map Row 50 --                  	
  	DATA >7070,>7067,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7289,>8989	;
  	DATA >8888,>8989,>8989,>8989	;
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8989,>8889,>8989,>8970	;
  	DATA >7070,>7070,>7070,>7070	;
* -- Map Row 51 --                  	
  	DATA >7070,>7067,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7072,>8989,>8989	;
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8889,>8989,>8970	;
  	DATA >7070,>7020,>7070,>7070	;
* -- Map Row 52 --                  	
  	DATA >7070,>7067,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7289,>8989,>8988	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8889,>8989,>8970	;
  	DATA >2070,>7070,>7070,>7070	;
* -- Map Row 53 --                  	
  	DATA >7070,>7067,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>8989,>8989,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8989,>8970	;
  	DATA >7070,>7070,>7070,>7070	;
* -- Map Row 54 --                  	
  	DATA >7070,>7067,>6767,>6767	;
  	DATA >6767,>6767,>6767,>6767	;
  	DATA >6767,>6767,>6767,>6767	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8989,>8989	;
  	DATA >7070,>7070,>7070,>7070	;
* -- Map Row 55 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>6767,>7070,>7072	;
  	DATA >7289,>8967,>6767,>6767	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8989	;
  	DATA >8920,>7070,>7070,>7070	;
* -- Map Row 56 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7070,>7270	;
  	DATA >8989,>8967,>6767,>6767	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8970,>7070,>7020,>7070	;
* -- Map Row 57 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7072,>7089	;
  	DATA >8989,>8967,>6767,>6767	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8889	;
  	DATA >8989,>7020,>7070,>7020	;
* -- Map Row 58 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7072,>7089	;
  	DATA >8989,>8867,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8989,>7070,>7070,>7070	;
* -- Map Row 59 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7070,>7270,>8988	;
  	DATA >8988,>8867,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8989,>7067,>6767,>6767	;
* -- Map Row 60 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7072,>7089,>8888	;
  	DATA >8888,>8867,>8888,>8888	;
  	DATA >8888,>8888,>8867,>6767	;
  	DATA >6767,>6767,>6767,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8889,>2067,>7070,>7070	;
* -- Map Row 61 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7070,>7270,>8988,>8888	;
  	DATA >8888,>8867,>8888,>8888	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8967,>2070,>7070	;
* -- Map Row 62 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7072,>7289,>8989,>8888	;
  	DATA >8888,>8867,>8888,>8888	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8C8D,>8F88,>8867,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8967,>7070,>7070	;
* -- Map Row 63 --                  	
  	DATA >7070,>7070,>7070,>7070	;
  	DATA >7270,>8989,>8988,>8888	;
  	DATA >8888,>8867,>888C,>8D8F	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8B8A,>8E88,>8867,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>7070,>7020	;
* -- Map Row 64 --                  	
  	DATA >7070,>7070,>7070,>7072	;
  	DATA >7089,>8989,>8888,>8888	;
  	DATA >8888,>8867,>888B,>8A8E	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8482,>8388,>8867,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8970,>7070	;
* -- Map Row 65 --                  	
  	DATA >7070,>7070,>7072,>7270	;
  	DATA >8989,>8988,>8888,>8888	;
  	DATA >8888,>8867,>8884,>8283	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8888,>8888,>8867,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8970,>7020	;
* -- Map Row 66 --                  	
  	DATA >7070,>7070,>7072,>7089	;
  	DATA >8989,>8888,>8888,>8888	;
  	DATA >8888,>8867,>6767,>6767	;
  	DATA >6767,>6767,>6767,>6767	;
  	DATA >6767,>6767,>6767,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8989,>7070	;
* -- Map Row 67 --                  	
  	DATA >7070,>7070,>7072,>8989	;
  	DATA >8989,>8888,>8888,>8888	;
  	DATA >8888,>8867,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8867	;
  	DATA >8888,>8888,>6767,>6767	;
  	DATA >6767,>6767,>6767,>8888	;
  	DATA >8888,>8867,>8989,>7070	;
* -- Map Row 68 --                  	
  	DATA >7070,>7070,>7270,>8989	;
  	DATA >8988,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8867	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>6767,>8888	;
  	DATA >8888,>8867,>6789,>7070	;
* -- Map Row 69 --                  	
  	DATA >7070,>7072,>7070,>8989	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8867	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>6767,>6767	;
  	DATA >6767,>6767,>6788,>8970	;
* -- Map Row 70 --                  	
  	DATA >7070,>7272,>7089,>8988	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8867	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8867,>6767,>8888	;
  	DATA >8888,>8888,>8888,>8989	;
* -- Map Row 71 --                  	
  	DATA >7070,>7220,>7089,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8867	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8888	;
  	DATA >8888,>8888,>8888,>8989	;

END

 

 

 

Entire XB program listing below

 

 

 

90 CALL SCREEN(2)

REM COLORSET DECLARATIONS

100 DATA 1,2,1,2,2,1,3,2,1,4,2,1,5,2,1,6,2,1,7,2,1,8,2,1
110 DATA 9,11,1,10,6,5,11,15,1,12,2,11,13,7,3,14,2,3

REM CHARACTER DATA

500 DATA 96,"C3C303030303FFFF",97,"C3C3C3C3C3C3C3C3",98,"FFFFC0C0C0C0C3C3",99,"C3C3C0C0C0C0FFFF"
510 DATA 100,"FFFF03030303C3C3",101,"FFFF00000000FFFF",102,"FFDFFFFFF7BFFDFF",103,"FFFDBFFBFFDFFEFF"
520 DATA 104,"C3241800C3241800",112,"181C36315E448212",113,"1818FFFF18181818",114,"0018382464D08202"
530 DATA 115,"03070E9C7830D0C8",120,"070F1F1C1C1F1F1F",121,"E0F0F83838F8F8F8",122,"8080F0888880C0E0"
540 DATA 123,"01010F1111010307",128,"005555FFDFFBBFFD",129,"FFF7BFEDFF00AAAA",130,"1CFC3F1E3E3EFEFF"
550 DATA 131,"30E0800000000000",132,"0603000000000003",136,"8104002002882200",137,"380AD1C988087337"
560 DATA 138,"01000000804000FF",139,"88C141602030180F",140,"0001070C3860C488",141,"7EC3003040000006"
570 DATA 142,"0181011322C60CF8",143,"00C0780CC6222311"

REM LOAD COLORSET

3430 RESTORE 100::FOR C=1 TO 14::READ CS,CF,CB::CALL COLOR(CS,CF,CB)::NEXT C

REM LOAD CHARACTERS

3440 RESTORE 500::FOR C=1 TO 30::READ CN,CC$::CALL CHAR(CN,CC$)::NEXT C

3600 CALL INIT
3610 CALL LOAD("DSK1.FOREST3O")
3620 CALL LINK("DRAW")
3630 GOTO 3630

 

 

 

 

Edited by Opry99er
Link to comment
Share on other sites

*Draw border (inefficient, but by golly it works)
LI R0,256   	starting location in VRAM
LI R1,BORDER	CPU data
LI R2,512   	number of bytes to write
BL @VMBW    	write it

With 512 bytes in the "forest3o", the extra loadtime and the drag on the "draw" routine, is, yes, inefficient, even to a total of 8 H- and VCHARs. The viewport itself is "cleared" anyway when a chunk of the big map is displayed.

 

Now, I guess we would want to tell the routine, which part of the big map to draw. We could pass a parameter with the LINK, we could LOAD a value into a certain memory location or use other trickery like assemble a string like "31" and use a character pattern to pass information.

Link to comment
Share on other sites

With 512 bytes in the "forest3o", the extra loadtime and the drag on the "draw" routine, is, yes, inefficient, even to a total of 8 H- and VCHARs. The viewport itself is "cleared" anyway when a chunk of the big map is displayed.

 

 

True, but this longer load time would only happen once per "world". That's expected. But if you think 2 CALL VCHARs and 6 HCHARs would be faster, then that is what shall be. As long as that only has to happen once per world as well... =) I thought it might be a bit inefficient, but it seemed quicker than doing it via BASIC before the CALL COLORs happened... leaving the screen and all info on the screen black before displaying all at once. I'll test further. In the meantime, I'm looking forward to setting up another "virtual tour" using the assembly routine and seeing how fast we can "page" the screens. =)

 

 

Link to comment
Share on other sites

The XB workspace starts at >83E0, so passing the proper value directly into the register from XB shouldn't be a problem. =)

Holy shit, Owen, I didn't even think of being that direct. But before we get there (get inside our DRAW routine), I guess XB and what's more, may already have destroyed most of the workspace. Maybe somewhere else in Scratchpad ?

Link to comment
Share on other sites

With 512 bytes in the "forest3o", the extra loadtime and the drag on the "draw" routine, is, yes, inefficient, even to a total of 8 H- and VCHARs. The viewport itself is "cleared" anyway when a chunk of the big map is displayed.

True, but this longer load time would only happen once per "world". That's expected. But if you think 2 CALL VCHARs and 6 HCHARs would be faster, then that is what shall be. As long as that only has to happen once per world as well... =) I thought it might be a bit inefficient, but it seemed quicker than doing it via BASIC before the CALL COLORs happened... leaving the screen and all info on the screen black before displaying all at once. I'll test further. In the meantime, I'm looking forward to setting up another "virtual tour" using the assembly routine and seeing how fast we can "page" the screens. =)

Let's try and make the viewport routine only. We can move/put the border in later, and assembler code more like H- and VCHAR would be much less than 512 bytes - no doubt. And I expect that code to be quite reusable with a twist et al.

Link to comment
Share on other sites

I have a feeling scratchpad is blown out.... We can either use a direct load into a register or find an obscure location to pass it to. I think a direct load is the way to go... We have open registers.... Outside of our registers which are available to us, scratchpad is pretty much cannibalized by XB...

Link to comment
Share on other sites

We share the workspace with the system @>83E0. We have to assume that workspace is out of the question. We could swap workspace to an area (and back), but we would need and potentially destroy 32 bytes.

 

quote:

>8300 to >8313 is used to support parameter passing from XB to machine language subprograms.

 

So I guess we could safely load a byte @>8300.

 

quote:

The address is a decimal value from -32768 to 32767, representing two byte addresses. Addresses above >7FFF are written as negative numbers, treating the two byte quantity as a two's complement integer. (i.e. to access an address above 32767, subtract 65536 from it.)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...