home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol1 / exec / asmdeviceio next >
Text File  |  1990-01-26  |  10KB  |  263 lines

  1. (c)  Copyright 1989 Commodore-Amiga, Inc.   All rights reserved.
  2. The information contained herein is subject to change without notice, and 
  3. is provided "as is" without warranty of any kind, either expressed or implied.  
  4. The entire risk as to the use of this information is assumed by the user.
  5.  
  6.  
  7.  
  8.                   Assembler Device IO - The Easy Way
  9.  
  10.                        Carolyn Scheppner
  11.                         
  12.  
  13.    Amiga.lib contains a number of compiled C Exec support functions which
  14. are used by C programmers to simplify the creation of tasks and ports
  15. and the setup of IORequest structures.  In addition, amiga.lib contains
  16. a number of C support functions such as printf() and getchar().  These
  17. functions are all documented in the Addison-Wesley Exec manual in 
  18. Appendix B, along with the C source of the Exec support functions.
  19.  
  20.    Although these functions are only provided with a C interface, it is
  21. relatively easy to call them from assembler.  The Exec support functions
  22. can greatly simplify assembler device IO and task creation code, and the
  23. C support functions such as printf() are handy for simple formatted output
  24. and debugging.  Note that to use the amiga.lib stdio functions, you must
  25. link with Astartup.obj or set up your own Amiga stdio file handles.
  26.  
  27.    The general method for accessing the C interface amiga.lib functions
  28. from assembler is as follows:
  29.  
  30.      1. XREF the function name prepended with an underscore ("_")
  31.  
  32.      2. Look at the C calling conventions for the function.
  33.         You will have to push the required arguments onto the stack
  34.         as longs, in right to left order as they appear in the C call.
  35.         If an argument is a literal string or string pointer, you
  36.         must push the address of a string that you have terminated
  37.         with a null. (See fstr DC.B in the DevIO.asm example.)
  38.  
  39.      3. Assume that the contents of d0-d1/a0-a1 will be lost, so save
  40.         them if necessary.  Push your arguments, as longs, onto the stack.
  41.         JSR _functionname, then add 4 to the stack pointer for each long
  42.         that you pushed on the stack.  The function result is returned
  43.         in D0.
  44.  
  45.  
  46.    The DevIO.asm example source in this issue is commented so that you can 
  47. compare the C calling conventions with the assembler equivalents.
  48.  
  49.  
  50.  
  51.         
  52. ---------------------------  Example  -------------------------------
  53.  
  54. *  DevIO.asm
  55. *
  56. *  Opening and talking to a device in mostly asm  - Carolyn Scheppner
  57. *
  58. *  Copyright 1988 Commodore-Amiga, Inc.  All Rights Reserved
  59. *
  60. *  Opens gameport.device unit 0 and asks gameport what controller type
  61. *     gameport 0 is set to  (1=mouse)
  62. *
  63. *  Demonstrates assembler use of the compiled C exec support
  64. *  routines (CreatePort, etc.) in amiga.lib, and also the use of
  65. *  amiga.lib csupport functions such as _printf for simple formatted
  66. *  output and debugging.
  67. *
  68. *  Outputs   address of port
  69. *            address of iob
  70. *            return of Opendevice (0=success)
  71. *            controller type (1=mouse)
  72. *
  73. *  LINK INSTRUCTIONS: Alink with Astartup.obj ... LIBRARY amiga.lib
  74. *   (Astartup sets up the stdout needed for amiga.lib _printf, etc.)
  75. *
  76.  
  77.    INCLUDE "exec/types.i"
  78.    INCLUDE "exec/io.i"
  79.    INCLUDE "libraries/dos.i"
  80.    INCLUDE "devices/gameport.i"
  81.  
  82. ** Imported Labels **
  83.  
  84. *------ from Astartup.obj
  85.    XREF     _AbsExecBase
  86.    XREF     _SysBase
  87.  
  88. *------ System function Library Vector Offsets 
  89.    XREF     _LVOOpenDevice
  90.    XREF     _LVOCloseDevice
  91.    XREF     _LVOSendIO
  92.    XREF     _LVOWait
  93.    XREF     _LVOGetMsg
  94.  
  95. *------ C interface Exec Support functions in amiga.lib 
  96.    XREF     _CreatePort
  97.    XREF     _DeletePort
  98.    XREF     _CreateStdIO
  99.    XREF     _DeleteStdIO
  100.  
  101. *------ C interface C Support functions in amiga.lib 
  102.    XREF     _getchar
  103.    XREF     _printf
  104.  
  105. ** Exported Labels **
  106.  
  107. *------ Where Astartup.obj JSR's to our code
  108.    XDEF     _main
  109.  
  110.             CODE
  111.  
  112. ** Code **
  113.  
  114. _main:
  115.             movem.l   d2-d7/a2-a6,-(sp)  ;Save the registers
  116.  
  117. *----- Exec Support function:  msgPort = CreatePort(name,pri)
  118. *      Used to create the replyPort for our messages
  119.  
  120.             move.l    #0,-(sp)       ;push priority 0 on stack as long
  121.             pea       portname       ;push addr of my null-termed portname
  122.             jsr       _CreatePort    ;call CreatePort
  123.             addq.l    #8,sp          ;add 4 to stack for each long pushed
  124.             jsr       mydebug0       ;my print d0 debugging rtn
  125.             move.l    d0,myport      ;save result
  126.             beq       failure        ;if zero, CreatePort failed
  127.  
  128. *----- Exec Support function:  ioReq = CreateStdIO(ioReplyPort)
  129. *      Note - many other devices use special extended IO requests
  130. *             which are defined in the include file for the device.
  131. *             If a larger request is required, you must use
  132. *             _CreateExtIO(ioReplyPort,size) and _DeleteExtIO(ioReq) 
  133.  
  134.             move.l    d0,-(sp)       ;push d0 (still holds port from above)
  135.             jsr       _CreateStdIO   ;call CreateStdIO
  136.             addq.l    #4,sp          ;add 4 to stack for the long pushed
  137.             jsr       mydebug0       ;my print d0 debugging rtn
  138.             move.l    d0,myiob       ;save result
  139.             beq       failure        ;if zero, CreateStdIO failed
  140.  
  141. *----- The normal assembler _LVO method is used to call system routines
  142.  
  143. *----- Open the device
  144.  
  145.             move.l    d0,a1          ;iorequest returned above
  146.             lea.l     devname,a0     ;null terminated device name
  147.             moveq     #0,d0          ;unit 0
  148.             moveq     #0,d1          ;flags
  149.             move.l    _SysBase,a6           ;prepare to call Exec function
  150.             jsr       _LVOOpenDevice(a6)    ;call OpenDevice
  151.             jsr       mydebug0              ;my print d0 debugging rtn
  152.             tst.l     d0             ;check for 0 (success) of OpenDevice
  153.             bne       failure        ;branch if OpenDevice failed
  154.             move      #1,gotdev      ;else set flag that it was successful
  155.  
  156. *----- Build waitmask of 1 << myport->mp_SigBit
  157.  
  158.             moveq     #0,d0             ;clear d0
  159.             movea.l   myport,a0         ;myport to a1
  160.             move.b    MP_SIGBIT(a0),d0  ;get sigbit number from myport
  161.             moveq     #1,d1             ;put 1 in d1
  162.             lsl.l     d0,d1             ; and shift left  (1 << sigbit)
  163.             move.l    d1,waitmask       ; to create waitmask for our Wait
  164.  
  165. *----- Set up our command as specified in gameport device autodocs
  166.  
  167.             movea.l   myiob,a1          ;myiob to a1 to set up command
  168.             move.w    #GPD_ASKCTYPE,IO_COMMAND(a1)  ;our command
  169.             move.l    #1,IO_LENGTH(a1)              ;as per autodocs
  170.             move.l    #result,IO_DATA(a1)   ;address of byte for result
  171.  
  172. *----- Send the command, Wait for the reply, the GetMsg the reply
  173. *      Note that 
  174.  
  175.             move.l    _SysBase,a6       ;set up for an Exec call
  176.             jsr       _LVOSendIO(a6)    ;call SendIO, myiob already in a1
  177.  
  178.             move.l    waitmask,d0       ;CreatePort'd port is a signal port
  179.             jsr       _LVOWait(a6)      ;So I wait for the signal
  180.  
  181.             movea.l   myport,a0         ;then get the message
  182.             jsr       _LVOGetMsg(a6)
  183.              
  184.             moveq     #0,d0             ;clear d0 since result is a byte
  185.             move.b    result,d0         ;move result to d0
  186.             jsr       mydebug0          ;my print d0 debugging rtn
  187.  
  188. *----- If you uncomment this, program will wait till you hit <RETURN>
  189. *      A loop of _getchar calls can be used to simulate a gets().
  190. *      Just store each d0 returned in an array until you get a 10 ('\n').
  191. *      Then null terminate the string.
  192. *          jsr       _getchar    ;waits for <RET> in case you want to wack
  193.  
  194. *----- Code was successfully executed
  195.             move.l    #RETURN_OK,retcode    ;set up success return code
  196.             bra.s     cleanup               ;and skip to cleanup code
  197.  
  198. *----- Failures in earlier code will branch here
  199. failure:
  200.             move.l    #RETURN_FAIL,retcode  ;set up success return code
  201.  
  202. cleanup:
  203.             tst.l     gotdev            ;if OpenDevice was unsuccessful
  204.             beq       nodev             ;  skip CloseDevice
  205.             move.l    _SysBase,a6       ;else set up for Exec call
  206.             move.l    myiob,a1               ;ioReq to a1
  207.             jsr       _LVOCloseDevice(a6)    ;call CloseDevice
  208. nodev
  209.             move.l    myiob,d0          ;if CreateStdIO was unsuccessful
  210.             beq       noiob             ;  skip DeleteStdIO
  211.  
  212. *----- Exec Support function:  DeleteStdIO(ioReq)
  213.             move.l    d0,-(sp)          ;else push d0 (now our ioReq)
  214.             jsr       _DeleteStdIO      ;call DeleteStdIO
  215.             addq.l    #4,sp             ;add 4 to stack for pushed long
  216. noiob
  217.             move.l    myport,d0         ;if CreatePort was unsuccessful
  218.             beq       noport            ;  skip DeletePort
  219.  
  220. *----- Exec Support function:  DeletePort(port)
  221.             move.l    d0,-(sp)          ;else push d0 (now our msgPort)
  222.             jsr       _DeletePort       ;call DeletePort
  223.             addq.l    #4,sp             ;add 4 to stack for pushed long
  224. noport
  225.  
  226.             movem.l   (sp)+,d2-d7/a2-a6        ;Restore registers
  227.             move.l    retcode,d0               ;Put our return code in d0
  228.             rts                                ;rts
  229.  
  230.  
  231. *----- mydebug0 - uses amiga.lib _printf to print the contents of d0
  232. *                 I preserve d0-d1/a0-a1/a6
  233. mydebug0:     
  234.             movem.l   d0-d1/a0-a1/a6,-(sp)     ;save these registers
  235.  
  236. *----- C Support function printf(): here  printf("$%lx\n",contents_of_d0)
  237. *      Note that the fstr DC.B below specifies '\n' and null as 10,0
  238.  
  239.             move.l    d0,-(sp)                 ;push d0 on the stack
  240.             pea       fstr                     ;push addr of format string
  241.             jsr       _printf                  ;call printf
  242.             addq.l    #8,sp                    ;add 4 to stack for each long
  243.             movem.l   (sp)+,d0-d1/a0-a1/a6     ;restore the saved registers
  244.             rts                                ;rts
  245.  
  246.  
  247.             DATA
  248.  
  249.             CNOP  0,4
  250. myiob       DC.L  0
  251. myport      DC.L  0
  252. gotdev      DC.L  0
  253. waitmask    DC.L  0
  254. retcode     DC.L  0
  255. result      DC.B  0
  256. portname    DC.B  'cas_devport',0
  257. devname     DC.B  'gameport.device',0
  258. fstr        DC.B  '$%lx',10,0
  259.             END
  260.  
  261.  
  262.  
  263.