IGNORED

# Assembly Lang Prog - Lesson 10 - Memory Pages & Hexadeci

## Recommended Posts

```Assembly Language Programming - Lesson 10 - Memory Pages & Hexadecimal Numbers

==============================================================================

In this lesson I will explain what is meant by "pages" when used talk about computer memory.  I will also teach you how to write numbers in hexidecimal notation, and how to convert numbers between decimal and hexidecimal.

Pages in Memory:

----------------

In the prevoius lesson I showed you memory maps and how they map all the devices in a computer system to addresses in the address space of the CPU.   To access a device the CPU places its address on the address bus.   We have already learned that the address bus is 16-bits wide which is the same as 2 bytes.   So it takes 2 bytes for form a complete address.   Like this:

15      8 7      0

+--------+--------+

|xxxxxxxx|xxxxxxxx|  The structure of a 16-bit address

+--------+--------+

High-byte|Low-byte

|

Page #   | byte #

One way to look as memory is to divide it into equal chunks with each chunk having 256 bytes.   Starting with a 65536 addresses you end up with 256 chunks with 256 bytes each.   Let the high-byte of an address be the number of the chunk to be accessed, and let the Low-byte be the byte within the chunk that is being accessed.  Another name for a chunk of 256 bytes is a page of memory.  So a 650x system has 256 pages of memory.  Each page is referred to by its number which is the same as the number in the High-byte of the address.  Pages are important to you as a programmer because when the CPU has to cross a page boundary in memory to complete some instructions, those instructions are slowed down and take an extra cycle to complete.  That slow down can ruin the timing you planned in your program, and the result is a bad television image.  When we discuss instructions in future lessons that are sensitive to page boundaries I will point them out to you.

Memory pages are not all bad.  Zero page is a special page in a 650X system.  The zero page is the first 256 memory addresses from 0 to 255.  The high-byte of the address is always zero.   Many instructions are 1 clock cycle faster if they are accessing memory in the zero page.  The primary image for the 128 bytes of RAM as well as the TIA chip are located in the zero page of the VCS memory map.  So when you access these devices in your code you can do so 1 cycle faster.   That's all that needs to be said about memory pages for now.  The impact of pages on your programming will be a common topic in future lessons.

---------------------------------------------------------------------------------

---------------------

In lesson 4, you learned how to count in binary with just two digits 0 and 1.   You already knew how to count in decimal which has ten digits: 0, 1, 2, 3, 4, 5, 6, 7 ,8 ,9.  Well, hexadecimal is counting with 16 digits: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.   Notice that the first 10 digits are the same as for decimal, but for the digits 11 through 15 we use the letters A through F. Hexadecimal numbers are handy for you the programmer because each hex digit is equivalent to exactly four binary digits:

Hex  Binary  Decimal

---  ------  -------

\$0 = %0000 = 0

\$1 = %0001 = 1

\$2 = %0010 = 2

\$3 = %0011 = 3

\$4 = %0100 = 4

\$5 = %0101 = 5

\$6 = %0110 = 6

\$7 = %0111 = 7

\$8 = %1000 = 8

\$9 = %1001 = 9

\$A = %1010 = 10

\$B = %1011 = 11

\$C = %1100 = 12

\$D = %1101 = 13

\$E = %1110 = 14

\$F = %1111 = 15

You may have noticed that I proceded each of the Hexadecimal numbers with the '\$' dollar sign symbol.  It is standard practice in assembly languages to indicate a number is in Hexadecimal by preceding it with a dollar sign.  This is no different than the use of a '%' percent sign to inidicate a binary number and it is important. The numbers \$101, %101, and 101 are not equal!

As a VCS programmer you will encounter Hexadecimal numbers in the listing files produced by the DASM tool.  All address and symbol values are reported in hexadecimal.  The tool is rude though in that it does not preceed the numbers with a dollar sign.  :P

In these lessons I plan to restrict the number formats that I use to binary and decimal which should do everything we need and increase your understanding of the underlying programming principles rather than making you lose time converting hex numbers.  I will avoid using hexadecimal unless the compiler is using it, and the case is one where aping the compiler will make it easier to understand.

How to convert between Decimal and Hexidecimal:

-----------------------------------------------

Get yourself a scientific calculator.  Yes we could slog through dividing decimal numbers by 16 and hexadecimal numbers by 10, but ye gods! why bother?  Get a calculator that can convert between the number systems and you are set.  I should point out that both Windows and Macintosh OS provided calculators can perform these conversions but you may have to turn on Advanced mode.  I don't know what is out there for Linux but I am sure there is something.

Exercises:

----------

If you are looking for something to do to drive home these lessons.   I recommend that you convert the decimal addresses in VCS memory map below into there Hexadecimal equivalents.

VCS Memory map:

************************

0 to   47 = TIA Control Registers Primary Image

48 to   95 = [shadow] TIA Control Registers

96 to  127 = [shadow-partial] TIA Control Registers

128 to  255 = 128 bytes of RAM Primary Image (zero page image allow fast access)

256 to  303 = [shadow] TIA Control Registers

304 to  351 = [shadow] TIA Control Registers

352 to  383 = [shadow-partial] TIA Control Registers

384 to  511 = [shadow] 128 bytes of RAM (The CPU stack uses this image)

512 to  559 = [shadow] TIA Control Registers

560 to  607 = [shadow] TIA Control Registers

608 to  639 = [shadow-partial] TIA Control Registers

640 to  671 = 6532-PIA I/O ports and timer Control Registers Primary image

672 to  703 = [shadow] 6532-PIA Control Registers

704 to  735 = [shadow] 6532-PIA Control Registers

736 to  767 = [shadow] 6532-PIA Control Registers

768 to  815 = [shadow] TIA Control Registers

816 to  863 = [shadow] TIA Control Registers

864 to  895 = [shadow-partial] TIA Control Registers

896 to  927 = [shadow] 6532-PIA Control Registers

928 to  959 = [shadow] 6532-PIA Control Registers

960 to  991 = [shadow] 6532-PIA Control Registers

992 to 1023 = [shadow] 6532-PIA Control Registers

1024 to 2047 = [shadows] Repeat the entire pattern from \$0000-03FF

2048 to 3071 = [shadows] Repeat the entire pattern from \$0000-03FF

3072 to 4095 = [shadows] Repeat the entire pattern from \$0000-03FF

4096 to  6143 = Lower 2K Cartridge ROM (4K carts start here)

6144 to  8191 = Upper 2K Cartridge ROM (2K carts go here)

8192 to 65535 = [shadows] Repeat the entire pattern from \$0000-1FFF, seven times.

Ha!  I just noticed I forgot to change the Hex numbers on the right side of my VCS memory map from hex to decimal in the prevous lesson.  Consider that mistake to be a head start for you.

Any questions?

**********************************************************************************```

##### Share on other sites

```Complete VCS Memory map:

************************

\$0 to  \$2F = TIA Control Registers Primary Image

30 to   5F = [shadow] TIA Control Registers

60 to   7F = [shadow-partial] TIA Control Registers

80 to   FF = 128 bytes of RAM Primary Image (zero page image allow fast access)

100 to  12F = [shadow] TIA Control Registers

130 to  15F = [shadow] TIA Control Registers

160 to  17F = [shadow-partial] TIA Control Registers

180 to  1FF = [shadow] 128 bytes of RAM (The CPU stack uses this image)

200 to  22F = [shadow] TIA Control Registers

230 to  25F = [shadow] TIA Control Registers

260 to  27F = [shadow-partial] TIA Control Registers

280 to  29F = 6532-PIA I/O ports and timer Control Registers Primary image

2A0 to  2BF = [shadow] 6532-PIA Control Registers

2C0 to  2DF = [shadow] 6532-PIA Control Registers

2E0 to  2FF = [shadow] 6532-PIA Control Registers

300 to  32F = [shadow] TIA Control Registers

330 to  35F = [shadow] TIA Control Registers

360 to  37F = [shadow-partial] TIA Control Registers

380 to  39F = [shadow] 6532-PIA Control Registers

3A0 to  3BF = [shadow] 6532-PIA Control Registers

3C0 to  3DF = [shadow] 6532-PIA Control Registers

3E0 to  3FF = [shadow] 6532-PIA Control Registers

400 to  7FF = [shadows] Repeat the entire pattern from \$0000-03FF

800 to  BFF = [shadows] Repeat the entire pattern from \$0000-03FF

C00 to  FFF = [shadows] Repeat the entire pattern from \$0000-03FF

1000 to  17FF = Lower 2K Cartridge ROM (4K carts start here)

1800 to  1FFF = Upper 2K Cartridge ROM (2K carts go here)

2000 to \$FFFF = [shadows] Repeat the entire pattern from \$0000-1FFF, seven times. ```

I did it! My HP200LX palmtop has a Hex, Dec, Oct, Bin calculator built-in!

Rob Mitchell, Atlanta, GA

##### Share on other sites

```Complete VCS Memory map:

************************

\$0 to  \$2F = TIA Control Registers Primary Image

... snip ...

2000 to \$FFFF = [shadows] Repeat the entire pattern from \$0000-1FFF, seven times. ```

I did it!  My HP200LX palmtop has a Hex, Dec, Oct, Bin calculator built-in!

Rob Mitchell, Atlanta, GA

Yep! That's it. good work. I am expeecting to post Lesson 11 some day next week.

Cheers,

##### Share on other sites

```    \$0 to  \$2F = TIA Control Registers Primary Image

30 to   5F = [shadow] TIA Control Registers ```

Actually there is a difference between those two, because the 2nd one only shadows the read-registers (collisions and input), but not the write-reagisters (e.g. GRPx, WSYNC, COLUPx etc.)

This is sometime useful to know, when optimizing code. E.g.:

`ASL INPT4; shift bit7 into carry for later usage`

When using \$0c for INPT4 here, you automatically change REFP1 too. By using \$3c you can avoid that.

##### Share on other sites

```    \$0 to  \$2F = TIA Control Registers Primary Image

30 to   5F = [shadow] TIA Control Registers ```

Actually there is a difference between those two, because the 2nd one only shadows the read-registers (collisions and input), but not the write-reagisters (e.g. GRPx, WSYNC, COLUPx etc.)

This is sometime useful to know, when optimizing code. E.g.:

`ASL INPT4; shift bit7 into carry for later usage`

When using \$0c for INPT4 here, you automatically change REFP1 too. By using \$3c you can avoid that.

Thanks Thomas, that is a good point you made.

## 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.

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.