Showing posts with label graphic tiles. Show all posts
Showing posts with label graphic tiles. Show all posts

Saturday, June 21, 2025

TUTORIAL #24 – LOW side

TUTORIAL #24 – LOW side - indirect indexed addressing “Is used to define the LOW side of the byte for mapping directly to the PAGE 1 screen memory”. 


This is the final assembly code page that you need to enter.  After you enter everything go ahead and save the code as ULTIMA1REV and compile the code.  Once you compile the code you will want to enter the basic programming code on the next Tutorial page.  

As always, if you have any questions please email me at:

josephpropati@yahoo.com

Joe “kingspud”

 

TUTORIAL #22 – MAP TILE DATA

TUTORIAL #22 – MAP TILE DATA “Is used to define all the byte information for each 2 x 2 sized MAP TILES used on the world map”. 


All the MAP TILES in Ultima 1 are made up of 2 bytes wide by 16 byte deep, that are drawn in memory regions which corresponds to locations on the screen.  Each individual map tile is a two byte wide shape and when they are read from the data string it is referenced by a number from 0 to 15 or the HEX equivalent to $00 thru $0F.

 

The following are the order in which the tiles are referenced:

 

0 = SHIP

1 = RAFT

2 = PLAINS

3 = TREES

4 = CASTLE

5 = TOWN

6 = SIGNPOST

7 = FIGHTER or main character

8 = TROLL

9 = DUNGEON ENTRANCE

10 = CART

11 = HORSE

12 = SPEEDER

13 = SPACE SHIP

14 = OCEAN

15 = DUNGEON

 

Since there are 82 horizontal line that make up the Ultima 1 world map, you will see a data string represented by a MAP## going from MAP1 all the way to MAP82.

 

To break down how each MAP TILE DATA STRING is read by the program I will use MAP70 as an example.

 

TUTORIAL PART 22JAAAAA - MAP TILE DATA image.jpg

 

This example will be the same for all the MAP TILE DATA STRINGS!

 

First, you see the MAP70 with correlates to the 70th line on the World Map that will be shown on the screen.

 

Second, you see DFB which stands for Defined Byte for a defined data string.  So everything after the DFB will represent the MAP TILES for the entire horizontal 70th line of the World Map.

 

Third, the first HEX value after the DFB will represent the number of HEX values that make up the entire MAP DATA string for MAP70.  So $1E in this case is equal to the decimal value of 30, which if you count all the HEX values after the $1E will give you a total of 30 HEX values!  The program uses this number to verify how many HEX values it can read in the DATA STRING before it gets to the end, without this HEX verifier it would cause the program to error by continuing to read the data string and not knowing where to end its read function.

 

Fourth, all the 30 HEX values after the $1E represent the amount and type of each MAP TILE shown on the world map.  So for this example, the first $FE represent F = 15 and the E = OCEAN TILES.  That is, there are 15 OCEAN TILES at the start of World Map horizontal line 70!  The next amount and type of MAP TILE would be $1E or [1] OCEAN TILE.  Then you have [3] PLAINS TILES, [1] TREE TILE, [1] PLAINS TILE, [7] OCEAN TILES, [13] PLAINS TILES, [6] OCEAN TILES, [3] TREES TILES, [1] OCEAN TILE, [3] PLAINS TILES, [1] TREES TILE, [3] PLAINS TILES, [9] OCEAN TILES, [1] DUNGEON TILE, [4] PLAINS TILES, [2] DUNGEON TILES, [15] OCEAN TILES, [13] OCEAN TILES, [4] TREES TILES, [1] PLAINS TILE, [14] OCEAN TILES, [4] TREES TILES, [8] OCEAN TILES, [5] DUNGEON TILES, [14] OCEAN TILES, [3] PLAINS TILES, [3] OCEAN TILES, [3] PLAINS TILES, and [11] OCEAN TILES.  All of these data reference types make up the entire horizontal line for MAP row 70!

 

The reason this was created this way was the compression system I was talking about earlier in the blog.  By doing each data string in this way I was able to save thousands of memory locations, which in turn allow me to have more programs on the disk.

 

To try and write this without the data compression would cause me to store each of these bytes in a separate memory location and if you add up all the type of each MAP TILE you would get just for this horizontal line alone, 171 bytes. Now multiply that by 82 horizontal map line and you can see that this is a lot of memory usages wasted!  Remember, assembly language stores everything in a cells which are a $## HEX value of bytes, which are only readable up to 256 in numerical value.

 

This example is read exactly the same for each MAP DATA STRING from 1 to 82 so I’m not going to show each code line like I have been doing in the past because it is just easier to show each image from the lines of code that make up the MAP lines from MAP1 to MAP82.

 

As always, if you have any questions please email me at:

Joe “kingspud”

 

 

TUTORIAL #21 – SHAPES/TILE GRAPHCS

 TUTORIAL #21 – SHAPES/TILE GRAPHCS “Is used to define all the bit information for each 16 x 14 sized SHAPE/TILE GRAPHICS used on the world map”. 

 




All the graphic-tiles/shapes in Ultima 1 are made up of bits that are drawn on the screen.  Each individual bit in a two byte wide shape is either shown ON or OFF to help represent the design of each shape displayed.

For this tutorial I need to go back in the blog a bit and explain how the actual shape is created.  Below is a photo of a MOUNTAIN shape with its shape table byte references marked out.

 

tumblr_lmnpssNDxI1qjrzteo2_1280.png

 

You can see that the shape is created from [2] bytes laid side by side.  They are stacked 16 high, which make a shape 14x16.

 

In the data reference for a MOUNTAIN shape, which you will see within the assembly code, you will see the following information:

 

mountain shape data.jpg

 

You will notice that after the DFB you can see the first two bytes in the data file that are the same as the first two byte in the previous image of the mountain shape.  This is how each shape/graphic tile is referenced in a data file so it can be drawn to the screen.  Remember that one byte is made up of the two bits.  So for example:  HEX $08 is made up of two nibbles or four bits values.  The [0] is basically 0000 and the [8] is 1000, which means the byte is 00001000.  This is the same as $08!  Each byte that is referenced on the shape will be placed in a graphic resolution byte that makes up the Hi-Res graphics screen.   So to get the shape of the mountain drawn to the screen you have to draw each of the two bytes side by side and 16 rows deep.   This is done 200 times to eventually create the entire world map section of the screen.

 

This is probably the coolest part of the Ultima game because once you realize how to create shapes/graphic tiles; you can make any type of shape you want just by following the example above.   This is how Richard created all the cool objects in the later Ultima’s, he used the 14x16 bits process and came up with some really cool shapes.  It is really only limited to your imagination and the 14x16 grid!  Remember that you are not limited to one shape, you could make an object that is comprised of 2 shapes or 4 shapes or even an entire grid of shapes, the sky is the limit!

 

I will be going through the subroutine SHAPE/TILE GRAPHICS line-by-line and explaining what each line of code is doing and how it affects the outcome of the program.

 

753  **********************************

 

This is just a comment line to separate each subroutine and helps to define the start of the subroutine. 

 

754  ****** SHIP TILE ****************

 

Line 754 is a comment line which tells the user that the SHIP TILE shape data will be referenced below. 

 

755  SHAPE1               DFB   $00,$00,$40,$00,$40,$07,$40,$03,$40,$00,

$44,$09,$4C,$1B,$5C,$3B,$5C,$3B,$4C,$19,$44,$08,$7E,$7F,$6F,$36,$7E,$1F,$7C,$0F,$00,$00

 

Line 755 is used to “[D]e[F]ine [B]ype” of SHAPE1 data.  Each SHAPE is defined by 14 bits wide and 16 bits deep, which give it a distinct shape style.  This gives a shape/graphic tile a two byte wide appearance.  Each byte is referenced one after the other and when read from data it will read each shape in two byte increments or 16 times.  Since four bytes make up a shape then a loop will be used to read all 32 lines of the two bytes.

 

Also, line 755 has a header titled SHAPE1, which is referenced from the SHPADR data subroutine and is defined by the two HI and LOW bytes for the location where SHAPE1 will reside and start its shape table in memory.

 

756  ****** RAFT TILE ****************

 

Line 756 is a comment line which tells the user that the RAFT TILE shape data will be referenced below. 

 

757  SHAPE2               DFB   $00,$00,$00,$00,$40,$00,$40,$01,$40,$03,

$40,$06,$40,$04,$40,$04,$40,$06,$40,$03,$40,$01,$40,$00,$7C,$1F,$78,$3F,$00,$00,$00,$00

 

Line 757 is used to “[D]e[F]ine [B]ype” of SHAPE2 data.  Each SHAPE is defined by 14 bits wide and 16 bits deep.  This gives a shape/graphic tile a two byte wide appearance.  Each byte is referenced one after the other and when read from data it will read each shape in two byte increments or 16 times.  Since four bytes make up a shape then a loop will be used to read all 32 lines of the two bytes.

 

Also, line 757 has a header titled SHAPE2, which is referenced from the SHPADR data subroutine and is defined by the two HI and LOW bytes for the location where SHAPE2 will reside and start its shape table in memory.

 

758  ****** PLAINS TILE ****************

 

Line 758 is a comment line which tells the user that the PLAINS TILE shape data will be referenced below. 

 

759  SHAPE3               DFB   $00,$00,$02,$00,$00,$04,$02,$00,$00,$00,

$08,$00,$00,$10,$00,$00,$00,$00,$20,$00,$00,$10,$00,$01,$00,$00,$00,$00,$00,$04,$08,$00

 

Line 759 is used to “[D]e[F]ine [B]ype” of SHAPE3 data.  Each SHAPE is defined by 14 bits wide and 16 bits deep.  This gives a shape/graphic tile a two byte wide appearance.  Each byte is referenced one after the other and when read from data it will read each shape in two byte increments or 16 times.  Since four bytes make up a shape then a loop will be used to read all 32 lines of the two bytes.

 

760  ****** TREES TILE ****************

 

Line 760 is a comment line which tells the user that the TREES TILE shape data will be referenced below. 

 

761  SHAPE4               DFB   $28,$00,$2A,$01,$2A,$01,$2A,$01,$28,

$00,$00,$14,$00,$55,$00,$55,$00,$55,$00,$14,$28,$00,$2A,$01,$2A,$01,$2A,$01,$28,$00,$00,$00

 

Line 761 is used to “[D]e[F]ine [B]ype” of SHAPE4 data. 

 

762  ****** CASTLE TILE ****************

 

Line 762 is a comment line which tells the user that the CASTLE TILE shape data will be referenced below. 

 

763  SHAPE5               DFB   $03,$60,$7F,$7F,$7E,3F,$06,$30,$06,

$30,$06,$30,$06,$30,$06,$30,$06,$30,$06,$30,$06,$30,$06,$30,$06,$30,$3E,$3E,$3F,$7E,$03,$60

 

Line 763 is used to “[D]e[F]ine [B]ype” of SHAPE5 data. 

 

764  ****** TOWN TILE ****************

 

Line 764 is a comment line which tells the user that the TOWN TILE shape data will be referenced below. 

 

765  SHAPE6               DFB   $00,$00,$3E,$3E,$22,$22,$22,$22,$22,

$22,$22,$22,$7E,$3F,$20,$02,$20,$02,$7E,$3F,$22,$22,$22,$22,$22,$22,$22,$22,$3E,$3E,$00,$00

 

Line 765 is used to “[D]e[F]ine [B]ype” of SHAPE6 data. 

 

766  ****** SIGNPOST TILE ****************

 

Line 766 is a comment line which tells the user that the SIGNPOST TILE shape data will be referenced below. 

 

767  SHAPE7               DFB   $00,$00,$40,$01,$40,$01,$78,$0F,$78,

$0F,$78,$0F,$78,$0F,$78,$0F,$78,$0F,$40,$01,$40,$01,$40,$01,$40,$01,$78,$1F,$7E,$7F,$00,$00

 

Line 767 is used to “[D]e[F]ine [B]ype” of SHAPE7 data. 

 

768  ****** CHARACTER TILE ****************

 

Line 768 is a comment line which tells the user that the CHARACTER TILE shape data will be referenced below. 

 

769  SHAPE8               DFB   $00,$00,$60,$01,$60,$01,$60,$01,$40,

$00,$78,$07,$7C,$0F,$62,$11,$44,$08,$78,$07,$60,$01,$70,$03,$10,$02,$10,$02,$18,$06,$00,$00

 

Line 769 is used to “[D]e[F]ine [B]ype” of SHAPE8 data. 

 

770  ****** TROLL TILE ****************

 

Line 770 is a comment line which tells the user that the TROLL TILE shape data will be referenced below. 

 

771  SHAPE9               DFB   $00,$00,$10,$04,$70,$07,$60,$03,$40,

$01,$78,$0F,$7C,$1F,$66,$33,$66,$33,$7E,$3F,$30,$06,$30,$06,$30,$06,$30,$06,$38,$0E,$00,$00

 

Line 771 is used to “[D]e[F]ine [B]ype” of SHAPE9 data. 

 

772  ****** DUNGEON TILE ****************

 

Line 772 is a comment line which tells the user that the DUNGEON TILE shape data will be referenced below. 

 

773  SHAPE10             DFB   $08,$04,$1F,$0E,$62,$71,$41,$20,$20,

$40,$10,$00,$08,$41,$46,$23,$03,$10,$64,$03,$30,$76,$17,$24,$12,$14,$1C,$1C,$10,$04,$10,$04

 

Line 773 is used to “[D]e[F]ine [B]ype” of SHAPE10 data. 

 

774  ****** CART TILE ****************

 

Line 774 is a comment line which tells the user that the CART TILE shape data will be referenced below. 

 

775  SHAPE11             DFB   $00,$00,$00,$00,$00,$00,$00,$00,$00,

$00,$03,$00,$0E,$00,$78,$7F,$78,$7F,$78,$78,$30,$70,$20,$12,$20,$10,$40,$08,$00,$07,$00,$00

 

Line 775 is used to “[D]e[F]ine [B]ype” of SHAPE11 data. 

 

776  ****** HORSE TILE ****************

 

Line 776 is a comment line which tells the user that the HORSE TILE shape data will be referenced below. 

 

777  SHAPE12             DFB   $00,$00,$00,$00,$00,$00,$00,$00,$0C,

$00,$1E,$00,$3F,$00,$7C,$3F,$70,$7F,$78,$7F,$78,$3F,$1C,$7C,$12,$48,$12,$48,$08,$24,$00,$00

 

Line 777 is used to “[D]e[F]ine [B]ype” of SHAPE12 data. 

 

778  ****** SPEEDER TILE ****************

 

Line 778 is a comment line which tells the user that the SPEEDER TILE shape data will be referenced below. 

 

779  SHAPE13             DFB   $00,$00,$00,$00,$00,$00,$00,$00,$00,

$00,$00,$00,$00,$00,$3F,$00,$18,$00,$7C,$0C,$7E,$3F,$7E,$3F,$00,$00,$00,$00,$00,$00,$00,$00

 

Line 779 is used to “[D]e[F]ine [B]ype” of SHAPE13 data. 

 

780  ****** SPACE TILE ****************

 

Line 780 is a comment line which tells the user that the SPACE TILE shape data will be referenced below. 

 

781  SHAPE14             DFB   $40,$00,$60,$01,$10,$02,$70,$03,$70,

$03,$70,$03,$70,$03,$70,$03,$70,$03,$78,$07,$78,$07,$7C,$0F,$7E,$1F,$7F,$3F,$7F,$3F,$70,$03

 

Line 781 is used to “[D]e[F]ine [B]ype” of SHAPE14 data. 

 

782  ****** OCEAN TILE ****************

 

Line 782 is a comment line which tells the user that the OCEAN TILE shape data will be referenced below. 

 

783  SHAPE15             DFB   $80,$8A,$80,$A0,$85,$80,$D0,$80,$80,

$8A,$80,$A0,$85,$80,$D0,$80,$80,$8A,$80,$A0,$85,$80,$D0,$80,$80,$8A,$80,$A0,$85,$80,$D0,$80

 

Line 783 is used to “[D]e[F]ine [B]ype” of SHAPE15 data. 

 

784  ****** MOUNTAIN TILE ****************

 

Line 784 is a comment line which tells the user that the MOUNTAIN TILE shape data will be referenced below. 

 

784  SHAPE16             DFB   $08,$04,$1F,$0E,$62,$71,$41,$20,$20,

$40,$10,$00,$08,$41,$46,$23,$23,$1C,$1C,$08,$08,$07,$07,$20,$02,$10,$44,$08,$78,$07,$10,$02

 

Line 784 is used to “[D]e[F]ine [B]ype” of SHAPE16 data. 

 

These are all the shapes/graphic tiles represented on the world map.  There are more shapes in Ultima 1 but they represent the monsters and are generated from a different binary file.

 

As always, if you have any questions please email me


Joe “Kingspud”