LF: For newbies... III


[Prev][Next][Index][Thread]

LF: For newbies... III



First, the end of last message: 

In the processor, everything happens the same way: it calculates your
addition on the data specified and stores the carry ( retunue: i didn' t knew
how to say it last night ) bit elsewhere. ( it stores it in the carry bit of
the status register : see jimmy guide for precisions on the structure of the
status register ) then, if YOU are working with signed numbers, you know you
don' t have to bother about the carry bit but if not working with signed
numbers, you should better test the carry bit...

Ok: you know how to additions, substractions... What about multiplications
and divisions ? 
the corresponding instructions are :  mulu ( unsigned ) , muls ( signed ) ,
divu ( unsigned ) and divs ( signed ) . if working with signed numbers, then
use muls and divs. 
muls  D2,D4  will multiply the lower words of D2 and D4, and store the 32 bit
result in D4
divs D2,D4 will calculate D4/D2 and store the quotient in the lower word of
D4 and the rest in the upper word of D2. Nothing else to say about this...

III ) The stack / the compiler / first program 

1) The stack

the stack is a 8 kilobyte ( i think ) zone of memory stored in the system
memory. ( you don' t need to know where exactly )  . You have access to this
memory by the stack pointer ( A7 ) : the adress to the stack is stored in A7.

The stack is mainly used to: 
     1) save variables before working with them 
     2) transmit parameters to a subroutine

I have never myself used the second one : storing params in the registers is
much more easy and much faster ( that is the way of most of the libraries i
know ) . Why using the stack in this way ? Because we ( the users of fargo )
are using routines implemented in the ti os: these routines use the stack to
store parameters. ( ex: the put_text or put_hex 
routines of the romlib library ) . 
Then it is often usefull to use the stack to save all registers and restore
them after: this is something most libs do .

The stack is used by the processor in another way: 

when you are in a prog and you what to jump ( branch without conditions ) to
a subroutine, you may write : BSR  <name_of_sub> ( there are other ways to do
this ) 
when writing this, you oblige the processor to do this: 
he stores in the stack the adress written in the PC ( program counter ) ( in
fact , he saves the position of the execution of the program before calling
the subroutine ) then, he puts in the PC the adress of the first instruction
of the subroutine. at the end of the subroutine , when you write RTS, the
processor restores the PC with the value stored in the stack and exutes the
instruction the PC points to . 
This isn' t that simple but, basicaly, it is what happens. 

there is other similar stuff about the link and unlnk instructions but i have
never used these, so... ( if some want more details, then again , jimmy guide
or email me : i got some ref book and will try to figure this out ) 

now , you know what the stack is used for: how can you use it ? 

easy: imagine you want to call the put_text subroutine ( in romlib ) 
You need to store 4 parameters in the stack. 
first:   move.w   #"1stparam", ( A7 )

now, you have to move the adress ( longword ) of the string to disp to the
stack. 
but, if you just add:  move.l   "adress",(A7)     you will just crunch the
data you had pushed before.
you may have written: sub   #4, A7
then , move.l  "adress",(A7) 
thus you would have now:         _______________
                                              1st param            
  <----this was the place A7 pointed to 
                                              adress                  
 <----this is the place A7 points to 

i have sub the size of the adress ( 4 bytes ) before sending the adress to
the stack. 
why haven' t we added the size of " adress"  ? because the rom needs us to
push the parameters in reverse order. that' s all ! 
However, there is another way to do this, more efficient: 
move.w   "1st param", - (A7)
move.l    "adress", - (A7)
all this does is before moving data, removing the size of the data from the
stack pointer ( A7 ) . here, some of you may understand why the first move
has a minus now: just before, we had crunched the data which was stored
before our first move. It could have been a big problem if we had been in a
subroutine with bsr ... 
So, now, you know that A7 points at the adress of the last data which has
been moved in  ( or pushed: when moving to the stack, you push, we moving
from the stack , you pop )

2) the compiler

now, you know basic instructions : you know how to write some assembly code. 
when working with fargo, you use A68k as a compiler ( a great freeware
compiler from W. Gibbs ) . i think you need to do a difference betwwen the
compiler's directives and the instructions of assembly: 

here is the general laying of a program: 

  @program  prog_code,prog_name                 ; make sure you don' t forget
a space
                                                                   ; before
the "program" statement 
         
prog_code: 

; here, your program 

rts        ; the instruction which ends a prog 

prog_name: dc.b  " my_prog",0

; here, your variables 
; ex:   
my_var: dc.w  0
 
 reloc_open:                          ; don' t forget here  too the space
before this block  
 add_library flib
 ; other libraries 
 reloc_close:
 end               
    
; over

you have seen here the use of a very precise syntax: respect it or you will
never be able to compile anything ... 
We have used here a compiler directive: dc."data lenght"  where " data
lenght" is b, w or l 
this directive difines the label which precedes as a var: here, my_var is a
word with 0 inside.
you may access to it in the program with: move.w  my_var, D0 or move.w   D0,
my_var
easy, no ? 
For precisions, go and see jimmy' s guide ( yeah, always refering to it but i
am just presenting basic things  )



3) 1st program: hello world ! 

ok: we want to disp sth on the screen.
here is the prog_code section: we' ll need to use the put_text routine in
romlib: 
 puttext(int x, int y, char *string, int color)  
we need to push the parameters in reverse order: 

prog_code:
    
    move.w   #4,-(A7)                                ; moving the first param
to the stack 
    lea          string(pc),-(A7)                      ; moving adress of
string to ths stack
    move.w   #0,-(A7)                                 ;   pushing position
    move.w    #0,-(A7)                               ;     pushing position
    jsr           romlib[put_text]                    ; calling subroutine
    add.l        #10,(A7)                              ; restoring the stack
pointer
    rts
       

now: let' s see what we did: lea ? what' s this ? 
lea  srting,D0 :  moves the relative adress of string to D0 ( the relative
adress is number of bytes you need to add to the absolute adress of the
instruction "lea" to get the adress of string ) 
we wrote: lea   string(pc),D0
this adds the absolute adress of the "lea" inst to the relative adress of
string and stores the result in D0 ( or, to the adress specified by A7)
thus, you get the absolute adress of "string"

we could have written: pea    string(pc) ( push effective adress ) 
then we call the subroutine: a jsr which has the same effect than bsr on the
stack (however slightly different ) 
lastly, after having dsiplayed our string, we restore the stack: instead of
erasing the data in the stack, we restore the pointer to its initial value:
10=2+4+2+2: we add the sum of the size of the data we pushed to the stack
pointer
or, more simply:  lea  10(A7),A7

ok: you got this txt file written with all the syntax stuff ( don' t forget
to add the romlib library) . Save this file with the extension : "asm" and
run "fargo <name of the file without the asm extension> "
you get your <name of the file>.92p file: send it to the calc, lauch it...
Nothing happens ! 
why ? well: the calc disps your message bu goes too fast for you to see it. 
all you have to do is to add a waiting loop ...
exercise: try to find in the libs with fargo a subroutine which does this and
write the corrected prog...

That' s it for now. If anyone found errors or imprecisions, e mail me ( i
would be Xtremly astonished if there were none...  thanks in advance ) 
Mathieu, <hm lacage@aol.com>