{"id":4585,"date":"2023-02-25T15:56:12","date_gmt":"2023-02-25T15:56:12","guid":{"rendered":"https:\/\/www.petecodes.co.uk\/?p=4585"},"modified":"2023-03-13T12:52:54","modified_gmt":"2023-03-13T12:52:54","slug":"graphics-in-assembler-for-the-sam-coupe","status":"publish","type":"post","link":"https:\/\/www.petecodes.co.uk\/graphics-in-assembler-for-the-sam-coupe\/","title":{"rendered":"Graphics in Assembler for the SAM Coup\u00e8"},"content":{"rendered":"\n
Continuing my series on Assembler for the SAM Coup\u00e9, where in the first post<\/a> we introduced the various principles required to get started with Assembly Language Programming. We\u2019ll now be looking at Graphics and Sprites and how to start showing Graphics on the screen.<\/p>\n\n\n\n If you haven\u2019t caught up on the first post in this series, you can find the first post in the series here.<\/a><\/p>\n\n\n\n Since creating this post, I’ve created a really basic Sprite Editor that produces the required Sprite Data for this tutorial, so you can go on and show some far prettier sprites.<\/p>\n\n\n\n You can find the SAM Coupe Sprite Editor here;<\/p>\n\n\n\n https:\/\/www.petecodes.co.uk\/sam-coupe-sprite-editor<\/a><\/p>\n\n\n\n It should be easy enough to get your head around… Just pick a colour, start clicking on pixels to create your Sprite. Then hit the Generate Sprite Data button.<\/p>\n\n\n\n At teh bottom of the page will be your Sprite Data.<\/p>\n\n\n\n Select all the text and copy that into your asm file (or over the top of the existing Sprite Data) and you’re good to go!<\/p>\n\n\n\n This has been quite a complicated blog post to write and get right, some of the topics needed a bit of research. It certainly wouldn\u2019t of been possible without the help of the people in the Facebook SAM Coupe Users Group<\/a>. Special mentions (in no particular order) go out to; Andrew Collier, Frode Tenneb\u00f8, Graham Clemo, Stefan Drissen, Anton Javor\u010dek, Simon Owen, Colin Coupe, Adrian Brown and David Brown\u2026 Thanks all!<\/p>\n\n\n\n Wikipedia <\/a>describes sprites as;<\/p>\n\n\n\n \u2026a two-dimensional<\/a> bitmap<\/a> that is integrated into a larger scene.<\/p>\n<\/blockquote>\n\n\n\n In simple terms, a sprite is a small piece of graphics on the screen;<\/p>\n\n\n The main sprite in the above scene of course is our egg shaped friend Dizzy\u2026 In fact, there\u2019s quite a few Sprites in the GIF above\u2026 The Cloud, the Spider, the Well, the Cauldron and so on\u2026<\/p>\n\n\n\n In our example above, some of the sprites are changing their appearance, that is, to give the impression of movement, a series of different sprites are drawn one after another to provide animation. Nonetheless, each frame of the animation is made up of simply one sprite.<\/p>\n\n\n\n Ok, so Sprites are actually just a collection of bytes of data relating to a set of individual pixels. Here\u2019s an example of a simple sprite;<\/p>\n\n\n So, we have a white square filled with black\u2026 This could be viewed as series of 1\u2019s and 0\u2019s such as;<\/p>\n\n\n\n Where the 1\u2019s will show a white pixel and the 0\u2019s will show a black pixel. This is of course a simplifcation\u2026 The Sprite above is actually stored in memory as a series of bytes as follows;<\/p>\n\n\n\n You\u2019ll see above, that there\u2019s actually half as many columns of bytes above as you\u2019d expect. This is because, to save space, the SAM combines columns of pixels into a single byte, with adjacent columns occupying adjacent nibbles (4 bits) of a byte. So, if we look again, at the second row down, we have;<\/p>\n\n\n\n We can see that the To take things a little further, if we now consider the following sprite;<\/p>\n\n\n We now have a Green box with black centre\u2026. The code for this sprite is;<\/p>\n\n\n\n So, we can now see that our The main SAM Coup\u00e9 Welcome Screen has a good example of the basic SAM Coup\u00e9 Palette;<\/p>\n\n\n Each of the colours in the screen above is assigned to a number;<\/p>\n\n\n I\u2019ve added the first black row here, as I guess MGT didn\u2019t like a black bar at the top. You\u2019ll see that colour 12 or C in HEX, is green and corresponds to the green in our sprite above.<\/p>\n\n\n\n These 16 colours are the default colours given to you when you first turn on your SAM\u2026 But, the SAM Coup\u00e9 can actually choose from 128 colours in total. The full SAM Coup\u00e9 Palette of 128 colours is shown below, with each colour\u2019s associated number given beside it (Click to open the full image);<\/p>\n\n\n If you\u2019d like to see the palette on your SAM Coup\u00e9, here\u2019s a disk image<\/a> which will automatically load the little palette test program from page 163 of the SAM Coup\u00e9 User Manual.<\/p>\n\n\n\n We get to choose each of the 128 colours by using a technique called Palette Switching, which we\u2019ll get onto later\u2026 It\u2019s actually interesting to note that, although the SAM Coup\u00e9 Welcome Screen looks straightforward enough, the Image is actually created using Palette Switching too rather than using a similair technique to the Palette Demo Program.<\/p>\n\n\n\n The SAM Coup\u00e9 has four different screen modes for different purposes, which are named Modes 1 to 4. They differ in the following ways as described in the SAM Coup\u00e9 User\u2019s Guide;<\/p>\n\n\n\n 32 cells * 24 lines = 768 character cells, each cell has individual choice of PEN and PAPER colour. 32 cells * 192 lines = 6,144 cells, each cell has individual choice of PEN and PAPER colour. 512 pixels * 192 lines, each pixel has individual choice of colour, choice of any 4 screen colours from 128.<\/p>\n\n\n\n 256 pixels * 192 lines, each pixel has individual choice of colour, choice of any 16 screen colours from 128.<\/p>\n<\/blockquote>\n\n\n\n It\u2019s amusing to note that, the above section of the SAM Coup\u00e9 User Guide (page 66) has an error, which states that that Mode 2\u2019s 32\u00d7192 characters = 5,444 rather than the correct 6,144!<\/p>\n\n\n\n The default mode that the SAM Coup\u00e9 starts in is Mode 4, and this is the mode we\u2019ll be using in this guide.<\/p>\n\n\n\n Aside from Mode 3, you\u2019ll notice that the SAM Coup\u00e9 has a screen resolution of 256 pixels wide by 192 pixels high;<\/p>\n\n\n The origin, or the pixel at location 0 down by 0 across is in the top left-hand corner of the screen.<\/p>\n\n\n\n Much like a lot of the 8 Bit computers from the 80\u2019s and 90\u2019s, the SAM Coup\u00e9 uses a Z80B 8 Bit processor. To coordinate all of this MGT designed an ASIC, or Application Specific Integrated Circuit. The ASIC contains the control of the various SAM functions and Hardware\u2026 Everything from controlling the Display to controlling the on board MIDI ports.<\/p>\n\n\n\n The Z80B can only access 64 KB of Memory at any given time, which is in turn broken down into 4 banks of 16KB. This limitation of course is part an parcel of the Z80B being an 8 Bit Microprocessor, with a 16bit address space\u2026 Where, the maximum number which can be represented by 16 Bits is 65535 (or 65536 if you count 0).<\/p>\n\n\n\n But, we know of course, that the SAM Coup\u00e9 has upto 512KB of RAM, so how does this 512KB translate to the 64KB addressable by the Z80B? One of the main functions of the ASIC is controlling how the Z80B communicates with the SAM Coup\u00e9\u2019s Memory, both ROM (Read Only Memory) and RAM (Random Access Memory);<\/p>\n\n\n This is a simplified view of how things are connected together of course\u2026 But, we can work with this to help explain how things hang together.<\/p>\n\n\n\n So, we know that the Z80B can only address up to 64KB of Memory, but we have up to 512KB to play with. Here\u2019s where some of the magic of the SAM Coup\u00e9 ASIC comes to life. In order to allow the Z80B to see our RAM (and ROM), that is, in order for the Z80B to execute instructions and process data held in our RAM, the ASIC \u201cPages\u201d sections into the relevant positions in the 64KB address space that the Z80B can see it.<\/p>\n\n\n\n Wikipedia <\/a>describes Memory Paging as;<\/p>\n\n\n\n \u2026a memory management<\/a> scheme by which a computer stores and retrieves data from secondary storage<\/a><\/sup> for use in main memory<\/a><\/p>\n<\/blockquote>\n\n\n\n Pretty obvious right? Well, in basic terms, the ASIC takes up to the full 512KB of the SAM Coup\u00e9\u2019s RAM and splits it up into 32 Page<\/strong>s of 16KB. This then allows us to choose which sections of memory the Z80B can see at any one time. We choose which Pages the Z80B can see by using the LMPR and HMPR registers;<\/p>\n\n\n\n This register primarily controls which pages of RAM are paged into Sections A and B of the Z80B Memory space.<\/p>\n\n\n\n This register primarily controls which pages of RAM are paged into Sections C and D of the Z80B Memory space.<\/p>\n\n\n\n  <\/p>\n\n\n\n If we look back at our simplified view of how the SAM Coup\u00e9 Memory is organised, then we can see that the ASIC allows us, through the use of the LMPR, HMPR and VMPR registers, to allow the Z80 to read and write our RAM. The best way to imagine this is like a set of circuits perhaps, where we connect a wire between what the Z80B can read and write, and our RAM. So, imagine if we want to read and write the first four pages of our RAM\u2026 We\u2019d need to tell the ASIC to page these into Sections A,B,C and D of the address space of the Z80B. Which is something like this graphically;<\/p>\n\n\nA New Sprite Editor<\/h2>\n\n\n\n
A Quick Word of Thanks<\/h1>\n\n\n\n
Introducing Graphics<\/h1>\n\n\n\n
What are sprites?<\/h2>\n\n\n\n
\n
Introducing Graphics<\/h1>\n\n\n\n
What are sprites\u2026 Really?<\/h2>\n\n\n\n
1, 1, 1, 1, 1, 1, 1, 1
1, 0, 0, 0, 0, 0, 0, 1
1, 0, 0, 0, 0, 0, 0, 1
1, 0, 0, 0, 0, 0, 0, 1
1, 0, 0, 0, 0, 0, 0, 1
1, 0, 0, 0, 0, 0, 0, 1
1, 0, 0, 0, 0, 0, 0, 1
1, 1, 1, 1, 1, 1, 1, 1<\/code><\/code><\/pre>\n\n\n\nDB &FF,&FF,&FF,&FF
DB &F0,&00,&00,&0F
DB &F0,&00,&00,&0F
DB &F0,&00,&00,&0F
DB &F0,&00,&00,&0F
DB &F0,&00,&00,&0F
DB &F0,&00,&00,&0F
DB &FF,&FF,&FF,&FF<\/code><\/code><\/pre>\n\n\n\nDB &F0,&00,&00,&0F<\/code><\/code><\/pre>\n\n\n\n
&F<\/code>\u2018s correspond to our
1<\/code>\u2018s and the
&0<\/code>\u2018s correspond to our
0<\/code>\u2018s (as you\u2019d expect). And you can see that the first byte is
&F0<\/code>, so we have a
1<\/code> and
0<\/code> pixel described in a single byte, with the opposite at the end where we have
&0F<\/code>, with a
0<\/code> and a
1<\/code> described in a single byte.<\/p>\n\n\n\n
Introducing Graphics<\/h1>\n\n\n\n
The SAM Coup\u00e9 Palette<\/h2>\n\n\n\n
DB &CC,&CC,&CC,&CC
DB &C0,&00,&00,&0C
DB &C0,&00,&00,&0C
DB &C0,&00,&00,&0C
DB &C0,&00,&00,&0C
DB &C0,&00,&00,&0C
DB &C0,&00,&00,&0C
DB &CC,&CC,&CC,&CC<\/code><\/code><\/pre>\n\n\n\n&F<\/code>\u2018s have changed to
&C<\/code>\u2018s. This is because the colour of each pixel is denoted by the value in each nibble of each byte. Each nibble can be set to one of 16 colours: 0 to F. The SAM Coup\u00e9 however, actually has access to a total palette of 128 colours, but only 16 can be chosen at any one time. We\u2019ll actually expand upon this somewhat later, where we\u2019ll talk about Screen modes.<\/p>\n\n\n\n
Introducing Graphics<\/h1>\n\n\n\n
The Screen Layout<\/h2>\n\n\n\n
\n
MODE 1<\/h3>\n\n\n\n
256 * 192 pixels, choice of any 16 screen colours from 128.<\/p>\n\n\n\nMODE 2<\/h3>\n\n\n\n
256 * 192 pixels, choice of any 16 screen colours from 128.<\/p>\n\n\n\nMODE 3<\/h3>\n\n\n\n
MODE 4<\/h3>\n\n\n\n
About Memory<\/h1>\n\n\n\n
The SAM Coup\u00e9 Memory Map<\/h2>\n\n\n\n
About Memory<\/h1>\n\n\n\n
Paging<\/h2>\n\n\n\n
\n
LMPR:<\/strong><\/h3>\n\n\n\n
Bit<\/th> Name<\/th> Function<\/th><\/tr> 0<\/td> BCD 1<\/td> Low Memory Page Control<\/td><\/tr> 1<\/td> BCD 2<\/td> Low Memory Page Control<\/td><\/tr> 2<\/td> BCD 4<\/td> Low Memory Page Control<\/td><\/tr> 3<\/td> BCD 8<\/td> Low Memory Page Control<\/td><\/tr> 4<\/td> BCD 16<\/td> Low Memory Page Control<\/td><\/tr> 5<\/td> RAM0<\/td> If set, ROM 0 is Paged out Section A of
Memory and RAM paged in its place<\/td><\/tr>6<\/td> RAM1<\/td> If set, ROM 1 is Paged into Section D of Memory<\/td><\/tr> 7<\/td> WPRAM<\/td> If set, will write protect the RAM in Section A<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n HMPR:<\/strong><\/h3>\n\n\n\n
Bit<\/th> Name<\/th> Function<\/th><\/tr> 0<\/td> BCD 1<\/td> High Memory Page Control<\/td><\/tr> 1<\/td> BCD 2<\/td> High Memory Page Control<\/td><\/tr> 2<\/td> BCD 4<\/td> High Memory Page Control<\/td><\/tr> 3<\/td> BCD 8<\/td> High Memory Page Control<\/td><\/tr> 4<\/td> BCD 16<\/td> High Memory Page Control<\/td><\/tr> 5<\/td> MD3S0<\/td> BCD 4 of the Mode 3 Colour Lookup Address<\/td><\/tr> 6<\/td> MD3S1<\/td> BCD 8 of the Mode 3 Colour Lookup Address<\/td><\/tr> 7<\/td> MCNTRL<\/td> Set to Allow access to the External Memory Space<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n About Memory<\/h1>\n\n\n\n
How Paging Works<\/h2>\n\n\n\n