CHAPTER 5 from SyncWare News Volume 2 Number 5 May-Jun. '85 pages 16-18
A P file version of THE LOADER can be found in the type-in thread: [Zx81:Type-Ins] "SyncWare News" campaignBASIL'S COMPENDIUM
Hexadecimal & 256-imal
Basil Wentworth
1413 Elliston Drive
Bloomington, IN 47401
This chapter will introduce the concept of hexadecimal notation, and what I call "256-imal". But first, the "fun" program.
This program will let you find the memory location of the first byte of any line. Just set the cursor at the line you're interested in, tell the computer to PRINT (notice: not RAND) USR 16514, and voila! There's the memory location of the line number. The first digit of the line number, that is--as you'll learn later on, the computer stores the line number in two bytes.
If you want, you can use this program instead of PROGTOP (see chapter 1). Just give the command POKE USR 16514,118.
You'll notice that the instructions for building the "fun" program are getting shorter and shorter. As you get more experience, I'm counting on you to fill in the missing details by yourself. So this time you get only a repeat of the loader program (Figure 5-1) and the final listing of the machine code routine (Figure 5-2).Code: Select all
FIG 5-1. THE LOADER PROGRAM 5000 LET F=16513 5010 LET F=F+1 5020 PRINT F;" " ; 5030 IF PEEK F<>27 THEN GOTO 5060 5040 INPUT A 5050 POKE F,A 5060 PRINT PEEK F, CHR$ PEEK F 5070 IF PEEK (F+1)=118 THEN STOP 5080 GOTO 5010
This "1 REM" program finds the first address by BASIC line number. Discussion and disassembly are at the [Zx81:Type-Ins] threadBy now, you probably feel a little as I did when I started studying the violin--the teacher spent what seemed like hours explaining how to hold the violin properly, when all I wanted to do was make music. I'm sorry about that. But we have one more digression to make before we really get into the business of coding.
If you already know all about hexadecimal notation (referred to indiscriminately as "hexadecimal" and "hex" throughout this series), or if you don't know, but don't mind sitting around trying to look wise when you talk with your computing friends or read a book on computing, then you can skip the first part of this chapter. Right up to the section on 256-imal. When you need to know the hex equivalent for a decimal number, or vice versa, you can always look up the conversion in the ZX81 handbook. Or compute your own conversions with a program like the one Tom Woods presented in Vol. 2 No. 2 of this publication.
But the section on 256-imal is important. Read and digest it.
Code: Select all
FIG 5-2. THE 1 REM STATEMENT 16514 42 E LD HL, 16515 10 GR S (16394) 16516 64 RND 16517 235 FOR EX DE,HL 16518 33 5 LD HL, 16519 125 ? 16509 16520 64 RND 16521 35 7 INC HL 16522 62 Y LD A, 16523 117 ? 117 16524 60 W INC A 16525 190 D CP(HL) 16526 32 4 JR NZ, 16527 249 RAND -7 16528 35 7 INC HL 16529 190 D CP(HL) 16530 200 COS RET Z 16531 122 ? LD A,D 16532 190 D CP(HL) 16533 32 4 JR NZ, 16534 242 PAUSE -14 16535 35 7 INC HL 16536 123 ? LD A,E 16537 190 D CP(HL) 16538 32 4 JR NZ, 16539 237 GOSUB -19 16540 43 F DEC HL 16541 229 FAST PUSH HL 16542 193 AT POP BC 16543 201 TAN RET
What is Hexadecimal?
You may already be familiar with binary counting. You're certainly familiar with decimal, although you may not have stopped to think how it works. (As Tom Lehrer points out, tongue in cheek, the important thing is to know how the system works--it doesn't matter whether you get the right answer or not.) Just to review, the meanings of the digits of the two systems are as shown in Figures 5-3 and 5-4. By logical extension, hexadecimal, based on 16, works as shown in Figure 5-5.
But, just as binary requires only two symbols (0 and 1) and decimal requires 10 of them (0-9), hex will require 16 separate characters. We already have 0-9; the other six are taken from the alphabet: A=10, B=11, C=12, D=13, E=14, and F=15. So A9 would be (10*16+9)=169; 9A would beCode: Select all
FIG 5-3. DECIMAL NOTATION 1325 IN DECIMAL = 1 * 10**3 (=1000) + 3 * 10**2 (= 300) + 2 * 10**1 (= 20) + 5 * 10**0 (= 5) (=1325)
(9*16+10)-154; and so on. And C9, which you’ll soon learn from constant repetition, is our old friend 201, the code for RETURN.Code: Select all
FIG 5-4. BINARY NOTATION 1011 IN BINARY = 1 * 2**3 (= 8d) + 0 * 2**2 (= 0d) + 1 * 2**1 (= 2d) + 1 * 2**0 (= 1d) (=lld)
Code: Select all
FIG 5-5. HEX NOTATION 1A2F IN HEX = 1 * 16**3 (=4096d) + 10 * 16**2 (= 320d) + 2 * 16**1 (= 32d) + 15 * 16** (= 15d) (=4463d)
But Why Use Hex?
To be honest, the most important reason to learn hexadecimal is that "everybody does it." Most published listings of the Z80 chip, for instance, are given in hex. So are large numbers of published programs. Typographically, the use of hex makes for a neater looking page--the fact that each hex byte is expressed in exactly two bytes makes it easier to list a program in a symmetrical fashion. And loader programs for hex are a bit simpler than those expressed in decimal.
However, I never accepted "everybody does it" as an excuse from my kids. And this is, after all, a series for beginners. So we'll be using decimal notation primarily. If there's any chance for confusion, I'll follow the accepted convention of adding an "h" or a "d" after a number, such as:One other thing. Hex numbers do not contain the letter "O." Anything that looks like an "O" is bound to be a "0" (zero). On the other hand, any number that is not made up of an even number of digits (usually 2 or 4) can not be hex.Code: Select all
20h=32d (i.e. 20 hex = 32 dec) or 20d=14h
Two-Fifty-Six-imal
That sounds like a made-up word, doesn't it? It should--it's my own invention. There's probably a fancy Greek or Latin derivative to describe this form of notation--or more likely a word with one parent from each language, as is the case with "hexadecimal" but I don't know what it would be. I suppose, by analogy with the abbreviation "hex", it would be called "toof", but I'll let that one go.
Two-fifty-six-imal isn't strictly analogous to decimal and hex, by the way, but is perhaps more like the Binary Coded Decimal notation that you run across from time to time. If it really were analogous to decimal and hex, it would require 256 characters, which would exhaust the Latin, Greek, Hebrew, and Cyrillic alphabets, and then some. Not to mention exhausting our patience.
In the 256-imal system, as used in this series, a number mn usually has the value of (256*m)+n. That is, 256 times the value of the first number, plus the value of the second number. You may recognize this system from the earlier chapter, where BC was 256*B+C. The first number in this case is referred to as the "most significant number", since it has 256 times the weight of the second ("least significant") number.
You can't always count on the most significant number coming first, however. To look ahead a bit, the registers of the Z80 are always NAMED with the most significant byte first. You can remember this by the fact that the HL register originally meant "High-Low." However, the memory usually STORES information with the least significant byte first. So the contents of the memory pair 16388/16389 would beDon't ask me why Sir Clive did it that way; he probably wasn't the first to do it.Code: Select all
PEEK 16388 + 256*PEEK 16389.
And to make matters worse, there's an exception to the exception--but we'll get to that in due course.
For the moment, remember that the value of a 256-imal number will always be 256*MSN+LSN, where MSN and LSN stand for Most Significant Number and Least Significant Number, respectively. This fact will never change--the only thing that may change from time to time is whether we print MSN or LSN first.
You will see why we need a system like 256-imal if you recall that each byte in computer memory will handle numbers from 0 to 255. Any number higher than 255 is stored in two successive bytes, in 256-imal.Code: Select all
FIG 5 -6. SOME ZX81 ADDRESSES IN 256-IMAL NUMBER NUMBER IN ZX81 SIGNIFICANCE IN DEC 256-IMAL OF THIS ADDRESS LSN MSN 16388 4 64 RAMTOP 16389 5 64 16396 12 64 D-FILE 16397 13 64 16400 16 64 VARS 16401 17 64 16404 20 64 E-LINE 16405 21 64 16421 37 64 LAST KEY 16422 38 64 PRESSED 16507 123 64 SPARE BYTES 16508 124 64 OF MEMORY 16509 125 64 FIRST BYTE OF PROGRAM 16514 130 64 FIRST BYTE OF 1 REM
A typical use of 256-imal would be in storing the values of memory addresses. The addresses that you most often will use are from 16507 on up. Figure 5-6 lists a number of ZX81 addresses that are particularly useful, along with their equivalents in 256-imal. You'll notice that you will be using 64 as the most significant number more often than any other value. For this reason, you might find it useful to memorize the fact that 256*64=16384, so that you can quickly compute in your head the 256-imal value of the most-often used memory addresses.
Problem
What is the largest number that can be expressed in 256-imal? See if you can figure it out for yourself before you read further.
Answer
Remember that the largest number a single byte can store is 255. The largest number in 256-imal, then, is two bytes of 255 each, or 256*255+255, or 65535.
You may recognize this as the equivalent of 256*256-1 (or 256**2-1). This gives the 256-imal system a total capacity of 256*256 numbers (counting 0), just as two digits of binary have a repertoire of 4 values (0-3), while two decimal digits can represent any one of 100 values (0-99).
And that's it for now. There will be more.