<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="hu">
	<id>http://wiki.amigaspirit.hu/index.php?action=history&amp;feed=atom&amp;title=Amiga_Machine_Language_%28Chapter_8%29</id>
	<title>Amiga Machine Language (Chapter 8) - Laptörténet</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.amigaspirit.hu/index.php?action=history&amp;feed=atom&amp;title=Amiga_Machine_Language_%28Chapter_8%29"/>
	<link rel="alternate" type="text/html" href="http://wiki.amigaspirit.hu/index.php?title=Amiga_Machine_Language_(Chapter_8)&amp;action=history"/>
	<updated>2026-04-23T00:31:37Z</updated>
	<subtitle>Az oldal laptörténete a wikiben</subtitle>
	<generator>MediaWiki 1.39.10</generator>
	<entry>
		<id>http://wiki.amigaspirit.hu/index.php?title=Amiga_Machine_Language_(Chapter_8)&amp;diff=1174&amp;oldid=prev</id>
		<title>Chain-Q: initial import as separate page</title>
		<link rel="alternate" type="text/html" href="http://wiki.amigaspirit.hu/index.php?title=Amiga_Machine_Language_(Chapter_8)&amp;diff=1174&amp;oldid=prev"/>
		<updated>2009-05-25T13:37:23Z</updated>

		<summary type="html">&lt;p&gt;initial import as separate page&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Új lap&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&lt;br /&gt;
      Chapter 8.&lt;br /&gt;
      ----------&lt;br /&gt;
      8.Advanced Programming.&lt;br /&gt;
      -----------------------&lt;br /&gt;
        You&amp;#039;ve learned a lot about machine language programming on the&lt;br /&gt;
        Amiga.What you need yet are a few routines that can be used as&lt;br /&gt;
        programming tools.We&amp;#039;ll work on that right now.They&amp;#039;ll be easy to &lt;br /&gt;
        use in your own program.The sky&amp;#039;s the limit now!&lt;br /&gt;
&lt;br /&gt;
      8.1.Supervisor Mode.&lt;br /&gt;
      --------------------&lt;br /&gt;
        As mentioned in the chapter on the MC68000 processor,there are two&lt;br /&gt;
        operating modes:the User and the Supervisor mode.It is often&lt;br /&gt;
        necessary to move between the two modes.However,this isn&amp;#039;t a&lt;br /&gt;
        simple process.&lt;br /&gt;
        The reason you want to do this,is that in User mode,you can&amp;#039;t&lt;br /&gt;
        access the Status register.If you write to one of them,an&lt;br /&gt;
        Exception is executed which crashes the program.&lt;br /&gt;
&lt;br /&gt;
        How can you get in Supervisor mode?&lt;br /&gt;
&lt;br /&gt;
        No problem.The operating system of the Amiga contains a function&lt;br /&gt;
        in the EXEC library that lets you get into supervisor mode.Its&lt;br /&gt;
        called SuperState and it doesn&amp;#039;t need any parameters.You can&lt;br /&gt;
        easily call this program by using the following lines:&lt;br /&gt;
&lt;br /&gt;
        execbase    = 4                 ;exec base address&lt;br /&gt;
        superstate  =-150               ;turn on function&lt;br /&gt;
               ...&lt;br /&gt;
               move.l  execbase,a6      ;exec base address in A6&lt;br /&gt;
               jsr     superstate(a6)   ;turn on supervisor mode&lt;br /&gt;
               move.l  d0,savesp        ;save return value&lt;br /&gt;
               ...&lt;br /&gt;
        savesp:blk.l   1                ;space for sp value&lt;br /&gt;
&lt;br /&gt;
        You get the value of the Stack Pointer(SP)back in the D0 register.&lt;br /&gt;
        You&amp;#039;ll also find it in register A7,but this register is changed   &lt;br /&gt;
        regularly.The reason is that in Supervisor mode,the Amiga works&lt;br /&gt;
        with all the Interrupts and with the SP,and there are lots of     &lt;br /&gt;
        Interrupts for this computor.We&amp;#039;ll talk about interrupts in a bit.&lt;br /&gt;
&lt;br /&gt;
        After this call,you&amp;#039;ll use the user stack instead of the&lt;br /&gt;
        supervisor stack.In this way,you can access the old user stack.You&lt;br /&gt;
        need to make sure that the user stack is large enough since the   &lt;br /&gt;
        interrupts must have enough room for their data on the stack.&lt;br /&gt;
        You need to save the value returned in D0,because you&amp;#039;ll need this&lt;br /&gt;
        value later.You need to return to user mode sometime.Theres a&lt;br /&gt;
        function for this in the exec library as well.It is called the    &lt;br /&gt;
        UserState function.It needs one parameter,the SP value that comes &lt;br /&gt;
        back from the SuperState function.&lt;br /&gt;
        Since you&amp;#039;ve saved this value in the long word starting at&lt;br /&gt;
        &amp;quot;savesp&amp;quot;,you can write the following:&lt;br /&gt;
&lt;br /&gt;
        userstate     =-156&lt;br /&gt;
               ...&lt;br /&gt;
               move.l  execbase,a6      ;exec base address in A6&lt;br /&gt;
               move.l  savesp,d0        ;put old sp in D0&lt;br /&gt;
               jsr     userstate(a6)    ;return to user mode&lt;br /&gt;
&lt;br /&gt;
        Now you are back in the user mode.The user stack point(USP)is the &lt;br /&gt;
        same as before.You can write functions that need to be run from&lt;br /&gt;
        the supervisor mode as subroutines.First you call superstate,save &lt;br /&gt;
        the return value,execute the desired function,call userstate,and  &lt;br /&gt;
        end with a RTS command.If the USP was changed,the RTS command     &lt;br /&gt;
        would&amp;#039;nt work right,and the computor would jump who knows where&lt;br /&gt;
        and perhaps crash.Here it works though.&lt;br /&gt;
        Now comes the question:how does the operating system get the&lt;br /&gt;
        supervisor mode?Thats not too difficult;it goes like this:&lt;br /&gt;
&lt;br /&gt;
        The superstate function attempts to access a Status Register.This &lt;br /&gt;
        causes an Exception to occur and a routine is called whose address&lt;br /&gt;
        begins at the long word starting at $20.It is the Exception Vector&lt;br /&gt;
        for Privilege Violation.The routine that it branches to is called &lt;br /&gt;
        in supervisor mode.Then it tests where this exception came from.If&lt;br /&gt;
        the routine finds that the exception comes from the superstate    &lt;br /&gt;
        routine whose address it knows,the matter is settled.It just&lt;br /&gt;
        branches to the routine without turning off the user mode.Thats&lt;br /&gt;
        all there is to it.&lt;br /&gt;
&lt;br /&gt;
      8.2.Exception Programming.&lt;br /&gt;
      --------------------------&lt;br /&gt;
        The exceptions described in the processor chapter offer you a lot &lt;br /&gt;
        of oppertunities to control the Amiga&amp;#039;s functions.You can use them&lt;br /&gt;
        to specify how errors should be handled and even list a crash&lt;br /&gt;
        program.&lt;br /&gt;
&lt;br /&gt;
        Here is a list of vectors that are used to jump to the exception  &lt;br /&gt;
        routines:&lt;br /&gt;
&lt;br /&gt;
        Number      Address          Use with&lt;br /&gt;
        ------------------------------------------------------------------&lt;br /&gt;
          2         $008             Bus error&lt;br /&gt;
          3         $00C             Address eror&lt;br /&gt;
          4         $010             Illegal command&lt;br /&gt;
          5         $014             Division by zero&lt;br /&gt;
          6         $018             CHK command&lt;br /&gt;
          7         $01C             TRAPV command&lt;br /&gt;
          8         $020             Privilege Violation&lt;br /&gt;
          9         $024             Trace&lt;br /&gt;
         10         $028             Axxx command emulation&lt;br /&gt;
         11         $02C             Fxxx command emulation&lt;br /&gt;
                    $030-$038        Reserved&lt;br /&gt;
         15         $03C             Uninitialized interrupt&lt;br /&gt;
                    $040-$05F        Reserved&lt;br /&gt;
         24         $060             Unauthorised interrupt&lt;br /&gt;
        25-31       $064-$083        Level 1-7 interrupt&lt;br /&gt;
        32-47       $080-$0BF        TRAP commands&lt;br /&gt;
                    $0C0-$0FF        Reserved&lt;br /&gt;
        64-255      $100-$3FF        User interrupt vector&lt;br /&gt;
&lt;br /&gt;
        Lets look at the TRAP commands as an example.They aren&amp;#039;t used in&lt;br /&gt;
        the Amiga operating system.A TRAP command and a number between&lt;br /&gt;
        zero and fifteen are used to call one of the 16 posible TRAP&lt;br /&gt;
        routines.If the command TRAP #0 is executed,the processor (in&lt;br /&gt;
        supervisor mode)branches to the routine whose address lies at $80 &lt;br /&gt;
        in memory.This routine must end with a RTE(ReTurn from Exception) &lt;br /&gt;
        command.&lt;br /&gt;
        Some operating systems,for example,the ATARI ST&amp;#039;s TOS operating   &lt;br /&gt;
        systems,are completely callable via these TRAP&amp;#039;s.Parameters are&lt;br /&gt;
        put on the stack,and then a TRAP command is executed.The advantage&lt;br /&gt;
        is that you don&amp;#039;t have to know any of the operating systems&lt;br /&gt;
        addresses.In the Amiga you must know the addresses(Execbase=4).&lt;br /&gt;
&lt;br /&gt;
        Lets write your own TRAP routine to demonstrate the use of the&lt;br /&gt;
        TRAP command.You&amp;#039;ll need three program sections:&lt;br /&gt;
&lt;br /&gt;
        1.The initialization of the TRAP vector.&lt;br /&gt;
        2.The TRAP routine itself(It must end with RTE).&lt;br /&gt;
        3.A test routine that calls the TRAP command.&lt;br /&gt;
&lt;br /&gt;
        Initialization is very short:&lt;br /&gt;
&lt;br /&gt;
        init:&lt;br /&gt;
               move.l  #trap0,$80        ;set vector for TRAP #0&lt;br /&gt;
               rts&lt;br /&gt;
&lt;br /&gt;
        Now you need to write the trap0 routine.Lets use the example from &lt;br /&gt;
        the hardware chapter that produced a beep.&lt;br /&gt;
        Lets write this routine using as little effort as possible.Change &lt;br /&gt;
        the RTS to a RTE at the end,erase the line in which the loop&lt;br /&gt;
        counter D0 was loaded for the tone production,and change the loop &lt;br /&gt;
        so that it works with long words.Now you can load the register&lt;br /&gt;
        with an arbitrary value and have the TRAP #0 followed by a peep of&lt;br /&gt;
        arbitrary duration.&lt;br /&gt;
&lt;br /&gt;
        ;** beep tone production after a TRAP #0 **&lt;br /&gt;
&lt;br /&gt;
        ctlw   =$dff096                  ;DMA control&lt;br /&gt;
        c0thi  =$dff0a0                  ;HI table address&lt;br /&gt;
        c0tlo  =c0thi+2                  ;LO table address&lt;br /&gt;
        c0tl   =c0thi+4                  ;table length&lt;br /&gt;
        c0per  =c0thi+6                  ;read in rate&lt;br /&gt;
        c0vol  =c0thi+8                  ;volume&lt;br /&gt;
&lt;br /&gt;
        trap0:                           ;* produce a short peep&lt;br /&gt;
               move.l  #table,c0thi      ;table beginning&lt;br /&gt;
               move    #4,c0tl           ;table length&lt;br /&gt;
               move    #300,c0per        ;read in rate&lt;br /&gt;
               move    #40,c0vol         ;volume&lt;br /&gt;
               move    #$8201,ctlw       ;start DMA (sound)&lt;br /&gt;
&lt;br /&gt;
        loop:&lt;br /&gt;
               subq.l  #1,d0             ;counter -1&lt;br /&gt;
               bne     loop              ;count dwn to zero&lt;br /&gt;
&lt;br /&gt;
        still:&lt;br /&gt;
               move    #1,ctlw           ;turn on tone&lt;br /&gt;
               rte                       ;exception end&lt;br /&gt;
&lt;br /&gt;
        table:                           ;sound table&lt;br /&gt;
               dc.b    -40,-70,-40,0,40,70,40,0&lt;br /&gt;
&lt;br /&gt;
        You need to make sure that &amp;quot;table&amp;quot;is in CHIP RAM($00000-$7FFFF),&lt;br /&gt;
        otherwise the sound chip can&amp;#039;t access the data!&lt;br /&gt;
&lt;br /&gt;
        After entering this,you can test it out using the following&lt;br /&gt;
        routine:&lt;br /&gt;
&lt;br /&gt;
        test:&lt;br /&gt;
               move.l  #$2ffff,d0        ;pass tone length in D0&lt;br /&gt;
               trap    #0                ;carry out exception:peep&lt;br /&gt;
               rts&lt;br /&gt;
&lt;br /&gt;
        Now assemble both routines and start the initialization routine,  &lt;br /&gt;
        init.Nothing happens.&lt;br /&gt;
        Start the second routine,test.A beep that lasts about one second&lt;br /&gt;
        is output.&lt;br /&gt;
        One thing you must keep in mind is that if you change the program &lt;br /&gt;
        and reassemble it,the address of the trap0 routine can change.    &lt;br /&gt;
        Before you execute the TRAP command,you must repeat the initializ-&lt;br /&gt;
        ation,so that the computor doesn&amp;#039;t jump to the wrong location!&lt;/div&gt;</summary>
		<author><name>Chain-Q</name></author>
	</entry>
</feed>