ORIGINALLY PUBLISHED IN LIMA NEWSLETTER DECEMBER 1993 December 1993 BB&P Editor's note: The following article by Bob Carmany is the first in a series. This first article in the series was published several years ago in the Hunter Valley (Australia) user group's newsletter. The rest of the series, which will appear in futue issues of BB&P, has not previously been published. ---------------------------------------------------------- Assembler Executing . . . By Bob Carmany (This is going to be a series of narrations about my "adventures" through the wonderous world of Assembly Language. I have Ron Kleinschafer and Tony McGovern to thank for prodding me into this. If I can try it, anyone can!) The first thing to do is to find a book for the beginner dealing with the basic ideas of Assembly Language (hereafter called "A/L"). I discovered much to my dismay that the rather extensive manual that comes with the E/A cartridge assumes a prior knowledge of A/L. Anyway, I finally found a rather elementary text on the subject and decided to spend some time learning to program in A/L -- after all, it was supposed to be easy! I quickly discovered that books aren't written in logical order. This one was making comparisons between XB and A/L coding and I decided that wasn't the best way to start. You have to understand some basics before you can get tha far. For example, there was a good deal of discussion of converting numbers from one base to another --- a good place to start! There are three number bases that we have to deal with in A/L programming. I could see that this was going to be fun! Binary (zero's and one's) is the only language that the computer understands. Fortunately, we no longer have to program in binary -- an interpreter does that for us. The other two number bases are hexidecimal (base 16) and decimal (what we all learned in school). I could see that this was getting easier all the time. One of the number bases had already been eliminated. All I had to do was learn how to convert a number from decimal to hexidecimal and vice versa. OK, let's see what the book has to say! You take the decimal number and divide it by radix 16. I didn't know there was gardening involved in this! I have a whole row of radixes planted out back --- my error, that's radishes! Sorry, back to the task at hand. This is awful! You have to keep track of these "F's" and "A's" when you divide the numbers for the conversions. Anyway, I managed to get through the exercises in the book but it must have had the wrong answers in a couple of places because they didn't agree with my results at all! I could see right off that I had been sold a "blind horse" by Ron and Tony! You know what? I got through the whole chapter and you know what the book said? "The easiest way is to use a decimal to hexidecimal calculator or a computer program to do the calculations for you". Hmmm! I think I just happen to have a program that does that. In fact, it gives you the equivalent in all three bases! So much for that chapter and here is the conversion program. 100 ON WARNING NEXT :: CALL CLEAR :: H$="0123456789ABCDEF" :: PRINT "DEPRESS YOUR ALPHA LOCK KEY": :"PRESS LETTER FOR INPUT BASE": : 110 PRINT : :"D=DEC # H=HEX # B=BIN #": : :: CALL SOUND(80,660,6) 120 CALL KEY(0,K,S):: IF S<1 THEN 120 ELSE ON POS("DHB",CHR$(K),1)+1 GOTO 110,13 0,140,150 130 INPUT "DEC #=":DEC :: IF DEC<-32768 OR DEC>65535 THEN 130 ELSE A,DEC=INT(DEC -65536*(DEC<0)):: GOSUB 200 :: GOSUB 220 :: GOTO 160 140 PRINT "HEX #=" :: ACCEPT AT(23,7)BEEP SIZE(4)VALIDATE(H$):HEX$ :: GOSUB 180 :: GOSUB 200 :: GOTO 160 150 PRINT "BIN #=" :: ACCEPT AT(23,7)BEEP SIZE(16)VALIDATE("10"):BIN$ :: GOSUB 90 :: GOSUB 220 :: GOSUB 210 160 A=INT(DEC/256):: PRINT :"D=";DEC;TAB(12);A;DEC-A*256 :: IF DEC>32767 THEN PR INT " ";DEC-65536 170 PRINT "H= ";HEX$:"B= ";SEG$(BIN$,1,8)&&" "&&SEG$(BIN$,9,8):: HEX$,BIN$="" :: A ,DEC=0 :: GOTO 110 180 HEX$=SEG$("0000",1,4-LEN(HEX$))&&HEX$ :: FOR I=1 TO 4 :: A,DEC=DEC+(POS(H$,SEG$(HEX$,I,1),1)-1)*16^(4-I):: NEXT I :: RETURN 190 FOR I=1 TO LEN(BIN$):: DEC=DEC-2^(I-1)*(SEG$(BIN$,(LEN(BIN$)+1-I),1)="1"):: NEXT I :: RETURN 200 A=A/2 :: BIN$=STR$(-(A-INT(A)<>0))&&BIN$ :: A=INT(A):: IF A THEN 200 210 BIN$=SEG$(RPT$("00",8),1,16-LEN(BIN$))&&BIN$ :: RETURN 220 A=DEC+65536*(DEC>32767) 230 HEX$=SEG$(H$,(INT(A/4096)AND 15)+1,1)&&SEG$(H$,(INT(A/256)AND 15)+1,1)&&SEG$(H $,(INT(A/16)AND 15)+1,1)&&SEG$(H$,(A AND 15)+1,1):: RETURN Maybe this isn't going to be so bad after all. I managed to finesse having to calculate all of those conversions by hand with a short program that I found in my library. Let's see, there is something about registers in the next chapter. This one starts of with a rather innocent statement. It says that there are three internal registers in the TI CPU --- the Program Counter. the Workspace Pointer, and the Status Register. No worries, mate! This doesn't look to be too difficult! The Program Counter (PC) is a special register that keeps track of the address of the instruction to be performed. After the instruction is performed, the CPU adjusts the address to the next instruction. Right --- the same thing as a line number in XB! Geez, I might have to apologize to Ron and Tony for what I wrote earlier. This isn't too bad so far! Now for the Workspace Pointer (WP) is another register that contains the address of the program's workspace. Whew! A sentence that says absolutely nothing! OK, a workspace is a memory area of 16 words of memory that are accessed faster than the rest of the computer's memory. Each of these words is referred to as a working register. Aha! I bet that is what they are talking about with those R0 to R15 things in the A/L source code. That means that the Workspace Pointer must point to the first of the working registers -- R0 --- and the rest must follow immediately in memory. This stuff is getting a little more complicated but I think I can grasp the concept. Now for the last of these registers --- the Status Register (SR). The book says that it holds the individual status bits that are affected by the instructions are executed. Now that makes no sense at all to me. It seems that each of the status bits is affected differently depending on the instruction executed and they can be read by the conditional jump instructions to make the program branch to another routine. That sound like the "IF --THEN" statement in XB. I guess I'll have to wait until I work with the individual instructions to see which of the 16 status bits they affect. Hey! They even provided a chart: Name Abbreviation Bit Position ~~~~ ~~~~~~~~~~~~ ~~~ ~~~~~~~~ Logical Greater Than L> 0 Arithmetic Greater Than A> 1 Equal EQ 2 Carry CY 3 Overflow OV 4 Odd Parity OP 5 Extended Operation X 6 Not Used -- 7-11 Interrupt Mask I0-I3 12-15 I've heard of some of these at one time or another but I guess I'll just have to wait and see how they can be tested and used by the various A/L instructions. All of this reading and writing has made my mouth dry! It's time for a cold Foster's (no Toohey's to be had here) and a bit of a rest before I start the second article in this series. I think I'll look at the structure of a bit of source code and maybe see if I can translate some familiar XB statements into corresponding A/L source code. That should be interesting!