Author Topic: EASy68K  (Read 7183 times)

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
EASy68K
« on: October 23, 2015, 02:42:28 AM »

  ______   ______   ______            ______   ______   __    __
 /\  ___\ /\  __ \ /\  ___\   __  __ /\  ___\ /\  __ \ /\ \  / /
 \ \ \__/ \ \ \_\ \\ \ \____ /\ \_\ \\ \ \____\ \ \_\ \\ \ \/ /_
  \ \  _\  \ \  __ \\ \____ \\ \____ \\ \  __ \\ \  _  \\ \  __ \   
   \ \ \/___\ \ \ \ \\/____\ \\/____\ \\ \ \_\ \\ \ \_\ \\ \ \ \ \ 
    \ \_____\\ \_\ \_\ /\_____\   /\___\\ \_____\\ \_____\\ \_\ \_\
     \/_____/ \/_/\/_/ \/_____/   \/___/ \/_____/ \/_____/ \/_/\/_/

*************************************************
Editor, Assembler, Simulator, S-Record/Binary utility for 68000 microprocessor

*------------------------------------
* Versions included in this package.
*------------------------------------

Editor/Assembler
v5.15.04 August-13-2015

Simulator
v5.15.04 August-13-2015

EASy68K Help
v5.15.04

EASyBIN
v2.4.1 Jan-20-2013

*------------------------------------
Editor written by Tim Larson
Original Assembler code by Paul McKee
Assembler code modified by Charles Kelly

Original Simulator code by Paul McKee
Simulator GUI by Charles Kelly
Simulator code modified by Charles Kelly and Eric Nelson

EASyBIN S-Record/Binary file utility by Charles Kelly

Borland C++ Builder 6.0 or greater required to compile.

Web and forum
         www.easy68k.com


Please post comments, suggestions, and bug reports to the EASy68K forum.


This package contains everything you need to create and run 68000 assembly language programs on a Windows PC. All programs and files are distributed under the GNU General Public Use License. A copy of the GNU license is available in the Help menu.

Please see help for full contact information, bug reports, downloading and credits.

Several example programs are included in the Examples folder more examples are available on the web site.

The file extensions used by EASy68k are:
    .X68  68000 source code created with Edit68k
    .S68  68000 S-Record file created by assembling source. S-Record files are read by
                Sim68k and may be executed.
    .L68  68000 Listing file created by Edit68k when the source code is assembled.

Enjoy.

Prof. Charles Kelly
ckelly@monroeccc.edu


Code: ASM
  1. *************************************************************************************
  2. *                                                                                                               *
  3. *       Fireworks for EASy68k V1.01                                     2011/06/04                      *
  4. *                                                                                                               *
  5. *       Fireworks launch, fly, explode and fall with reasonably realistic physics.      *
  6. *                                                                                                               *
  7. *       The first version used 16 bit integer maths but this resulted in rounding       *
  8. *       artifacts being visible as symetric spacing of supposedly random particles      *
  9. *       and waves of velocity change as an effect rounded to the next bit.              *
  10. *                                                                                                               *
  11. *       This program uses 16.16 fixed point math to reduce rounding artifacts to        *
  12. *       near invisibility.                                                                              *
  13. *                                                                                                               *
  14. *                                                                                                               *
  15. *       The [F2], [F3] and [F4] keys can be used to select a screen size of 640 x       *
  16. *       480, 800 x 600 and 1024 x 768 respectively.                                             *
  17. *                                                                                                               *
  18. *       [ESC] can be used to quit the program.                                                  *
  19. *                                                                                                               *
  20. *       More 68000 and other projects can be found on my website at ..                  *
  21. *                                                                                                               *
  22. *        http://mycorner.no-ip.org/index.html                                                   *
  23. *                                                                                                               *
  24. *       mail : leeedavison@googlemail.com                                                               *
  25. *                                                                                                               *
  26. *************************************************************************************
  27. *
  28. * first some constants
  29.  
  30. ESC             EQU     $1B                             * [ESC] character
  31. CR              EQU     $0D                             * [CR] character
  32. LF              EQU     $0A                             * [LF] character
  33.  
  34. num_objs        EQU     200                             * number of objects
  35.  
  36. gravity EQU $00010000                   * acceleration due to gravity
  37.  
  38. rocket  EQU       2                             * rocket object
  39. zorst           EQU       4                             * exhaust object
  40. burst           EQU       6                             * burst object
  41. star            EQU       8                             * star object
  42.  
  43. rocket_drag     EQU      10                             * rocket v^2 drag effect
  44. zorst_drag      EQU      64                             * exhaust v^2 drag effect
  45. burst_drag      EQU     128                             * burst v^2 drag effect
  46. star_drag       EQU     200                             * star v^2 drag effect
  47.  
  48. rocket_life     EQU      40                             * rocket life
  49. zorst_life      EQU      -1                             * exhaust life
  50. burst_life      EQU       2                             * burst life minimum
  51. star_life       EQU       1                             * star life
  52.  
  53. burst_v EQU      17                             * burst particle velocity minimum
  54.  
  55.  
  56. *************************************************************************************
  57. *
  58. * the code
  59.  
  60.         ORG     $1000
  61.  
  62. start
  63.         BSR             Initialise                      * go setup everything
  64. restart
  65.         BSR             setup_world                     * go setup the firework world
  66. main_loop
  67.         MOVEQ           #8,d0                           * get the time in 1/100 ths seconds
  68.         TRAP            #15
  69.  
  70.         MOVE.l  d1,-(sp)                        * save the time
  71.  
  72.         MOVEQ           #94,d0                  * copy the screen buffer to the screen
  73.         TRAP            #15
  74.  
  75.         MOVEQ           #11,d0                  * position cursor
  76.         MOVE.w  #$FF00,d1                       * clear screen
  77.         TRAP            #15
  78.  
  79. * animate the scene
  80.  
  81.         BSR             new_rocket                      * go see if a new rocket is needed
  82.         BSR.s           update_objects          * go update the objects
  83.         BSR             draw_objects            * draw the objects
  84.  
  85. * test the keys used
  86.  
  87.         BSR             screen_size                     * test and handle widow size change keys
  88.         BSR             test_escape                     * test if the user wants to quit
  89.  
  90. * now see if we need to wait for some time
  91.  
  92.         MOVE.(sp)+,d7                        * get the main loop start time
  93.         MOVEQ           #8,d0                           * get time in 1/100 ths seconds
  94.         TRAP            #15
  95.  
  96. * doing the BGT means that if the clock passed midnight while the code was in the main
  97. * loop then the delay is skipped this go. this means things may run a bit fast for one
  98. * loop which is waaaaay better than waiting for a few 100ths of a second shy of twenty
  99. * four hours by mistake
  100.  
  101.         SUB.l           d1,d7                           * subtract the current time from the start time
  102.         BGT.s           end_main_loop           * if the time crossed midnight just contimue
  103.  
  104. * moving the wait time into d1 like this menas we can have any wait up to 1.27 seconds
  105. * and still use the MOVEQ form to load it
  106.  
  107.         MOVEQ           #5,d1                           * set the wait time in 100ths of a second
  108.         ADD.l           d7,d1                           * add the loop negative time delta
  109.         BLE.s           end_main_loop           * if the time is up just contimue
  110.  
  111.         MOVEQ           #23,d0                  * else wait d1 100ths of a second
  112.         TRAP            #15
  113.  
  114. end_main_loop
  115.         TST.w           redraw(a3)                      * test the redraw flag
  116.         BNE.s           restart                 * if redraw go initialise the world
  117.  
  118.         TST.w           quit(a3)                        * test the quit flag
  119.         BEQ.s           main_loop                       * if not quit go get another key
  120.  
  121. * all done so tidy up and stop
  122.  
  123.         MOVEQ           #16,d1                  * disable double buffering
  124.         MOVEQ           #92,d0                  * set draw mode
  125.         TRAP            #15
  126.  
  127.         LEA             goodbye_message(pc),a1  * set the goodbye message pointer
  128.         MOVEQ           #13,d0                  * display a string with [CR][LF]
  129.         TRAP            #15
  130.  
  131.         MOVEQ           #9,d0                           * halt the simulator
  132.         TRAP            #15
  133.  
  134. goodbye_message
  135.         dc.b    $0C,CR,LF
  136.         dc.b    '  Goodbye',0
  137.  
  138.         ds.w    0                                       * ensure even
  139.  
  140.  
  141. *************************************************************************************
  142. *
  143. * update the objects routine
  144.  
  145. update_objects
  146.         MOVE.w  #obj_length*num_objs-obj_length,d7
  147.                                                         * set the index to the last object
  148. update_loop
  149.         MOVE.w  obj_type(a0,d7.w),d0    * get the object type
  150.         BEQ             end_update_loop         * if no object go do next
  151.  
  152.         CMPI.w  #rocket,d0                      * compare the object type with a rocket
  153.         BNE.s           not_a_rocket            * if not a rocket skip exhast spawn
  154.  
  155.         BSR             spawn_zorst                     * go spawn an exhast particle
  156. not_a_rocket
  157.         MOVE.l  obj_x(a0,d7.w),d1               * get the object x co-ordinate
  158.         MOVE.l  obj_y(a0,d7.w),d2               * get the object y co-ordinate
  159.  
  160.         MOVE.l  obj_vx(a0,d7.w),d3      * get the object x velocity
  161.         MOVE.l  obj_vy(a0,d7.w),d4      * get the object y velocity
  162.  
  163.         ADD.l           d3,d1                           * add the x velocity to the x co-ordinate
  164.         BMI.s           object_done                     * if < 0 then the object is off screen
  165.  
  166.         ADD.l           d4,d2                           * add the y velocity to the y co-ordinate
  167. *##     BMI.s           object_done                     * if < 0 then the object is off screen. I took
  168.                                                         * this out to allow particles that go off the
  169.                                                         * top of the screen to re-enter when they fall
  170.                                                         * back as long as they stay within the x bounds
  171.  
  172.         SWAP            d1                              * high word to low word
  173.         CMP.w           width(a3),d1            * compare x with the screen width
  174.         BGE.s           object_done                     * if >= max + 1 then the object is off screen
  175.  
  176.         SWAP            d2                              * high word to low word
  177.         CMP.w           height(a3),d2           * compare y with the screen height
  178.         BGE.s           object_done                     * if >= max + 1 then the object is off screen
  179.  
  180.         SWAP            d1                              * low word back to high word
  181.         SWAP            d2                              * low word back to high word
  182.  
  183.         MOVE.l  d1,obj_x(a0,d7.w)               * save the object x co-ordinate
  184.         MOVE.l  d2,obj_y(a0,d7.w)               * save the object y co-ordinate
  185.  
  186.         BSR             calc_drag                       * calculate (v^2)*drag
  187.         ADD.l           d3,obj_vx(a0,d7.w)      * add the drag to the object x velocity
  188.  
  189.         MOVE.l  d4,d3                           * copy vy
  190.         BSR             calc_drag                       * calculate (v^2)*drag
  191.         ADD.l           d3,obj_vy(a0,d7.w)      * add the drag to the object y velocity
  192.  
  193.         TST.w           obj_accel(a0,d7.w)      * test the acceleration flag
  194.         BEQ.s           no_acceleration         * if done skip acceleration
  195.  
  196.         SUBQ.w  #1,obj_accel(a0,d7.w)   * decrement the acceleration flag
  197.  
  198.         MOVE.l  obj_x_accel(a0,d7.w),d1 * get the x acceleration
  199.         MOVE.l  obj_y_accel(a0,d7.w),d2 * get the y acceleration
  200.         ADD.l           d1,obj_vx(a0,d7.w)      * add x acceleration to the x velocity
  201.         ADD.l           d2,obj_vy(a0,d7.w)      * add y acceleration to the y velocity
  202. no_acceleration
  203.         ADD.l           #gravity,obj_vy(a0,d7.w)
  204.                                                         * add gravity to the y velocity
  205.         SUBQ.w  #1,obj_life(a0,d7.w)    * decrement the object life
  206.         BNE.s           end_update_loop         * if still alive skip killing the object
  207.  
  208.         BSR.s           spawn_object            * the object has timed out so see if it spawns
  209. object_done
  210.         MOVEQ           #0,d0                           * clear the longword
  211.         MOVE.w  d0,obj_life(a0,d7.w)    * clear the object life flag
  212.         MOVE.w  d0,obj_type(a0,d7.w)    * clear the object type flag
  213.         SUBQ.w  #1,obj_count(a3)                * decrement the objects count
  214. end_update_loop
  215.         SUB.w           #obj_length,d7          * decrement to previous object
  216.         BPL             update_loop                     * loop if not all done
  217.  
  218. exit_update_objects
  219.         RTS
  220.  
  221.  
  222. *************************************************************************************
  223. *
  224. * an object has died so see if it spawns anything
  225.  
  226. spawn_object
  227.         MOVE.w  obj_type(a0,d7.w),d0    * get the object type
  228.         CMPI.w  #rocket,d0                      * compare the object type with a rocket
  229.         BEQ.s           spawn_burst                     * if it is a rocket go spawn a burst
  230.  
  231.         CMPI.w  #burst,d0                       * compare the object type with a burst
  232.         BEQ.s           spawn_star                      * if it is a burst go spawn a star
  233.  
  234.         RTS
  235.  
  236.  
  237. *************************************************************************************
  238. *
  239. * spawn a star. when a burst dies it spawns a star which is a brief flash of white
  240. * at the end
  241.  
  242. spawn_star
  243.         MOVE.w  #obj_length*num_objs-obj_length,d6
  244.                                                         * set the index to the last object
  245. spawn_star_loop
  246.         CMP.w           d6,d7                           * compare with this object
  247.         BEQ.s           end_spawn_star_loop     * if this object go try next
  248.  
  249.         TST.w           obj_type(a0,d6.w)               * test the object type flag
  250.         BEQ.s           spawn_a_star            * if this object is free use it
  251.  
  252. end_spawn_star_loop
  253.         SUB.w           #obj_length,d6          * decrement to previous object
  254.         BPL.s           spawn_star_loop         * loop if not all done
  255.  
  256.         RTS
  257.  
  258. * found a vacant object, copy the burst parameters
  259.  
  260. spawn_a_star
  261.         BSR             copy_object                     * copy the burst object to the star object
  262.                                                         * returns this object pointer, (a0,d6.w), in a2
  263.  
  264.         MOVE.w  #star_drag,obj_drag(a2) * set the drag
  265.  
  266. * star_colour(a3) could be used to have other colour stars apart from white
  267.  
  268.         MOVE.l  star_colour(a3),obj_colour(a2)
  269.                                                         * set the object colour
  270. * set the object type
  271.  
  272.         MOVEQ           #star,d0                        * set the object type
  273.         MOVE.w  d0,obj_type(a2)         * save the object type
  274.  
  275. * set the object life
  276.  
  277.         MOVEQ           #star_life,d0           * set the object life
  278.         MOVE.w  d0,obj_life(a2)         * save the object life
  279.  
  280. * add the object to the count
  281.  
  282.         ADDQ.w  #1,obj_count(a3)                * increment the objects count
  283.  
  284.         RTS
  285.  
  286.  
  287. *************************************************************************************
  288. *
  289. * spawn a burst. this fills all the free object slots with burst objects
  290.  
  291. spawn_burst
  292.         MOVEQ           #8,d2                           * velocity change is 0 to 7
  293.         BSR             rand_d2                 * generate a random value in d0.w in range
  294.                                                         * 0 to d2.w - 1
  295.         ADD.w           #burst_v,d0                     * velocity from burst_v
  296.         MOVE.w  d0,v_burst(a3)          * copy the velocity max for this burst
  297.  
  298.         MOVE.w  #obj_length*num_objs-obj_length,d6
  299.                                                         * set the index to the last object
  300. spawn_burst_loop
  301.         CMP.w           d6,d7                           * compare with this object
  302.         BEQ.s           end_spawn_burst_loop    * if this object go try next
  303.  
  304.         TST.w           obj_type(a0,d6.w)               * test the object type
  305.         BNE.s           end_spawn_burst_loop    * if object go try next
  306.  
  307. * found a vacant object, copy the burst parameters
  308.  
  309.         BSR             copy_object                     * copy the burst object to the star object
  310.                                                         * returns this object pointer, (a0,d6.w), in a2
  311.  
  312.         MOVE.w  #burst_drag,obj_drag(a2)
  313.                                                         * set the drag
  314. * chose a random velocity
  315.  
  316.         MOVE.w  v_burst(a3),d2          * get the velocity maximum for this burst
  317.         BSR             rand_d2                 * generate a random value in d0.w in range
  318.                                                         * 0 to d2.w - 1
  319.         MOVE.w  d0,d3                           * copy the random velocity
  320.  
  321. * chose a random direction
  322.  
  323.         BSR             random_n                        * get the next random number
  324.         MOVE.w  PRNlword(a3),d0         * get the random direction word
  325.         BSR             sincos                  * get sin(d0) in d0, cos(d0) in d1
  326.  
  327.         MULS.w  d3,d0                           * velocity * sin direction
  328.         MULS.w  d3,d1                           * velocity * cos direction
  329.  
  330. * add the velocity to the inherited velocity
  331.  
  332.         ADD.l           d1,obj_vx(a2)           * add the x velocity to the burst x velocity
  333.         ADD.l           d0,obj_vy(a2)           * add the y velocity to the burst y velocity
  334.  
  335. * chose a colour
  336.  
  337.         MOVE.l  burst_colour(a3),d0     * get the object colour
  338.         BPL.s           save_burst_colour               * if it is a valid colour go save it
  339.  
  340.                                                         * else this is a multicolour burst so
  341.         BSR             get_colour                      * get a random colour from the table
  342. save_burst_colour
  343.         MOVE.l  d0,obj_colour(a2)               * save the object colour
  344.  
  345. * set the object type
  346.  
  347.         MOVEQ           #burst,d0                       * set the object type
  348.         MOVE.w  d0,obj_type(a2)         * save the object type
  349.  
  350. * set a random life depending on the screen size
  351.  
  352.         MOVE.w  width(a3),d2            * get the width
  353.         ASR.w           #4,d2                           * / 16
  354.         BSR             rand_d2                 * generate a random value in d0.w in range
  355.                                                         * 0 to d2.w - 1
  356.         ADDQ.w  #burst_life,d0          * add the object life
  357.         MOVE.w  d0,obj_life(a2)         * save the object life
  358.  
  359. * add the object to the count
  360.  
  361.         ADDQ.w  #1,obj_count(a3)                * increment the objects count
  362. end_spawn_burst_loop
  363.         SUB.w           #obj_length,d6          * decrement to previous object
  364.         BPL.s           spawn_burst_loop                * loop if not all done
  365.  
  366.         RTS
  367.  
  368.  
  369. *************************************************************************************
  370. *
  371. * spawn an exhast particle
  372.  
  373. spawn_zorst
  374.         TST.w           obj_accel(a0,d7.w)      * test the acceleration flag
  375.         BEQ.s           exit_spawn_zorst                * if done skip spawn
  376.  
  377.         MOVE.w  #obj_length*num_objs-obj_length,d6
  378.                                                         * set the index to the last object
  379. spawn_zorst_loop
  380.         TST.w           obj_type(a0,d6.w)               * test the object type
  381.         BNE.s           end_spawn_zorst_loop    * if object go try next
  382.  
  383. * found a vacant object, copy the rocket parameters
  384.  
  385.         BSR             copy_object                     * copy the rocket object to the burst object
  386.                                                         * returns this object pointer, (a0,d6.w), in a2
  387.  
  388.         MOVE.w  #zorst_drag,obj_drag(a2)
  389.                                                         * set the drag
  390.  
  391. * kill any acceleration, only need to clear the flag
  392.  
  393.         MOVEQ           #0,d0                           * clear the longword
  394.         MOVE.w  d0,obj_accel(a2)                * clear the acceleration flag
  395.  
  396. * make the velocity half that of the rocket, this is glowing exhaust that is ejected
  397. * from the rocket so it will be traveling in the same direction as the rocket but
  398. * behind it and slower
  399.  
  400.         MOVE.l  obj_vx(a2),d1           * get the zorst x velocity
  401.         MOVE.l  obj_vy(a2),d2           * get the zorst y velocity
  402.         ASR.l           #1,d1                           * x velocity / 2
  403.         ASR.l           #1,d2                           * y velocity / 2
  404.         MOVE.l  d1,obj_vx(a2)           * save the zorst x velocity
  405.         MOVE.l  d2,obj_vy(a2)           * save the zorst y velocity
  406.  
  407.         MOVE.l  zorst_colour(a3),obj_colour(a2)
  408.                                                         * set the object colour
  409. * set the object type
  410.  
  411.         MOVEQ           #zorst,d0                       * set the object type
  412.         MOVE.w  d0,obj_type(a2)         * save the object type
  413.  
  414. * set the object life
  415.  
  416.         MOVEQ           #zorst_life,d0          * set the object life
  417.         MOVE.w  d0,obj_life(a2)         * save the object life
  418.  
  419. * add the object to the count
  420.  
  421.         ADDQ.w  #1,obj_count(a3)                * increment the objects count
  422.         RTS
  423.  
  424. end_spawn_zorst_loop
  425.         SUB.w           #obj_length,d6          * decrement to previous object
  426.         BPL.s           spawn_zorst_loop                * loop if not all done
  427.  
  428. exit_spawn_zorst
  429.         RTS
  430.  
  431.  
  432. *************************************************************************************
  433. *
  434. * new rocket routine. sets up a new rocket object as object zero
  435.  
  436. new_rocket
  437.         TST.w           obj_count(a3)           * test the objects count
  438.         BNE             exit_new_rocket         * if objects exist just exit
  439.  
  440. * no objects so a new rocket is needed
  441.  
  442.         MOVE.w  width(a3),d2            * get the width of the window
  443.         BSR             rand_d2                 * generate a random value in d0.w in range
  444.                                                         * 0 to d2.w - 1
  445.         SWAP            d0                              * low word to high word
  446.         MOVE.l  d0,obj_x(a0)            * set the object x co-ordinate
  447.  
  448. * start from near the bottom of the screen, actually 4 pixels up from the bottom
  449.  
  450.         MOVEQ           #0,d2                           * clear the longword
  451.         MOVE.w  height(a3),d2           * get the height of the window
  452.         SUBQ.w  #4,d2                           * - 4
  453.         SWAP            d2                              * low word to high word
  454.         MOVE.l  d2,obj_y(a0)            * set the object y co-ordinate
  455.  
  456. * the rocket starts stationary and accelerates up so clear the initial velocity
  457.  
  458.         MOVE.l  #0,obj_vx(a0)           * set the object x velocity
  459.         MOVE.l  #0,obj_vy(a0)           * set the object y velocity
  460.  
  461.         MOVE.w  #rocket_drag,obj_drag(a0)
  462.                                                         * set the drag
  463. * set the acceleration time
  464.  
  465.         MOVE.w  #22,obj_accel(a0)               * set the object acceleration count
  466.  
  467. * set a random x acceleration depending on the object's initial x position
  468.  
  469.         SWAP            d0                              * swap the x position back to low word
  470.         MOVE.l  d0,d1                           * copy it
  471.         MOVE.w  width(a3),d2            * set the range
  472.         BSR             rand_d2                 * generate a random value in d0.w in range
  473.                                                         * 0 to d2.w - 1
  474.         SUB.l           d1,d0                           * - x
  475.         ASL.l           #6,d0                           * * 64
  476.         MOVE.l  d0,obj_x_accel(a0)      * set the object x acceleration
  477.  
  478. * set a random y acceleration depending on the screen height. a1 is used because putting
  479. * a value in an address register doesn't alter the flags from the compare
  480.  
  481.         MOVE.w  height(a3),d2           * get the screen height
  482.         MOVEA.l #$FFFDD000,a1           * set for 800 x 600
  483.         CMPI.w  #600,d2                 * compare the height with 600
  484.         BEQ.s           set_accel                       * if 800 x 600 go use the value
  485.  
  486.         MOVEA.l #$FFFD9000,a1           * set for 1024 x 768
  487.         BPL.s           set_accel                       * if 1024 x 768 go use the value
  488.  
  489.         MOVEA.l #$FFFE0000,a1           * else set for 640 x 480
  490.  
  491. set_accel
  492.         BSR             rand_d2                 * generate a random value in d0.w in range
  493.                                                         * 0 to d2.w - 1
  494.         ASL.l           #6,d0                           * * 64
  495.         ADD.l           d0,a1                           * adjust the object y acceleration
  496.         MOVE.l  a1,obj_y_accel(a0)      * save the object y acceleration
  497.  
  498.         MOVE.l  rocket_colour(a3),obj_colour(a0)
  499.                                                         * set the object colour
  500. * set the object type
  501.  
  502.         MOVEQ           #rocket,d0                      * set the object type
  503.         MOVE.w  d0,obj_type(a0)         * save the object type
  504.  
  505. * set the object life
  506.  
  507.         MOVEQ           #rocket_life,d0         * set the object life
  508.         MOVE.w  d0,obj_life(a0)         * save the object life
  509.  
  510. * add the object to the count
  511.  
  512.         ADDQ.w  #1,obj_count(a3)                * increment the objects count
  513.  
  514. * each rocket has a different coloured burst so set the burst colour
  515.  
  516.         BSR.s           get_col_f                       * get a random colour or flag from the table
  517.         MOVE.l  d0,burst_colour(a3)     * save the burst colour
  518.  
  519. exit_new_rocket
  520.         RTS
  521.  
  522.  
  523. *************************************************************************************
  524. *
  525. * get a random colour or flag from the table
  526.  
  527. get_col_f
  528.         MOVEQ           #colour_fla/4,d2                * set for the table length with the flag
  529.         BRA.s           get_colour_less         * go get the colour
  530.  
  531.  
  532. *************************************************************************************
  533. *
  534. * get a random colour from the table
  535.  
  536. get_colour
  537.         MOVEQ           #colour_len/4,d2                * set for the table length
  538. get_colour_less
  539.         BSR             rand_d2                 * generate a random value in d0.w in range
  540.                                                         * 0 to d2.w - 1
  541.         ASL.w           #2,d0                           * * 4
  542.         MOVE.l  colours(pc,d0.w),d0     * get a random colour
  543.         RTS
  544.  
  545. * colours for the bursts
  546.  
  547. colours
  548.         dc.l    $0000C0                         * dark red
  549.         dc.l    $0000FF                         * red
  550.         dc.l    $00C000                         * dark green
  551.         dc.l    $00FF00                         * green
  552.         dc.l    $00FFC0                         * mustard
  553.         dc.l    $00C0FF                         * orange
  554.         dc.l    $00FFFF                         * yellow
  555.         dc.l    $C00000                         * dark blue
  556.         dc.l    $FF0000                         * blue
  557.         dc.l    $C000C0                         * dark magenta
  558.         dc.l    $FF00FF                         * magenta
  559.         dc.l    $C0C000                         * dark cyan
  560.         dc.l    $FFFF00                         * cyan
  561.         dc.l    $C0C0C0                         * light
  562. colour_len      EQU     *-colours                       * table length
  563.         dc.l    -1                                      * flag random colour
  564. colour_fla      EQU     *-colours                       * table length with the flag
  565.  
  566.  
  567. *************************************************************************************
  568. *
  569. * copy an object from index d7 to index d6. this returns (a0,d6.w) in a2 which makes
  570. * some following code much simpler
  571.  
  572. copy_object
  573.         LEA             (a0,d7.w),a1            * copy the source address
  574.         LEA             (a0,d6.w),a2            * copy the destination address
  575.         MOVEQ           #obj_length-2,d0                * set the word count
  576. copy_object_loop
  577.         MOVE.(a1,d0.w),(a2,d0.w)     * copy a word
  578.         SUBQ.w  #2,d0                           * decrement the index
  579.         BPL.s           copy_object_loop                * loop if more to do
  580.  
  581.         RTS
  582.  
  583.  
  584. *************************************************************************************
  585. *
  586. * calculate v^2 * drag. all done in 16.16 bit fixed point math
  587.  
  588. calc_drag
  589.         MOVE.l  d3,d1                           * copy the velocity
  590.         BPL.s           positive                        * if positive skip negate
  591.  
  592.         NEG.l           d3                              * else make positive
  593. positive
  594.  
  595. * first do v^2
  596.  
  597. *                                        aaaa bbbb
  598. *                                       *               = b * b + 2(a * b) + a * a
  599. *                                        aaaa bbbb
  600. *
  601. *                                        BBBB BBBB
  602. *                                 ABAB ABAB
  603. *                                 ABAB ABAB
  604. *                          AAAA AAAA
  605.  
  606.         MOVE.w  d3,d2                           * copy low word
  607.         SWAP            d3                              * high word to low word
  608.         MOVE.w  d3,d0                           * copy high word
  609.  
  610.         MULU.w  d2,d0                           * make AB
  611.         ADD.l           d0,d0                           * make AB + AB
  612.  
  613.         MULU.w  d2,d2                           * make BB
  614.         MULU.w  d3,d3                           * make AA
  615.  
  616.         ADD.l           #$00008000,d2           * round up the high word in BBBB BBBB
  617.         CLR.w           d2                              * clear the low word
  618.         SWAP            d2                              * high word to low word
  619.         ADD.l           d2,d0                           * add to Ab
  620.  
  621.         SWAP            d3                              * low word to high word
  622.         CLR.w           d3                              * clear the low word
  623.         ADD.l           d0,d3                           * add to AA
  624.  
  625. * now multiply by the drag
  626.  
  627. *                                        aaaa bbbb
  628. *                                       *               = b * c + a * c
  629. *                                        0000 cccc
  630. *
  631. *                                        CBCB CBCB
  632. *                                 CACA CACA
  633.  
  634.         MOVE.w  d3,d2                           * copy the low word
  635.         SWAP            d3                              * high word to low word
  636.  
  637.         MOVE.w  obj_drag(a0,d7.w),d1    * get the object drag
  638.         MULU.w  d1,d2                           * make CB
  639.         MULU.w  d1,d3                           * make CA
  640.  
  641.         ADD.l           #$00008000,d2           * round up
  642.         CLR.w           d2                              * clear low word
  643.         SWAP            d2                              * high word to low word
  644.         ADD.l           d2,d3                           * add to CA
  645.  
  646.         TST.l           d1                              * test the original sign
  647.         BMI.s           negative                        * if the original was negative skip the ^2 sign
  648.                                                         * change
  649.  
  650.         NEG.l           d3                              * else make v^2 * drag negative
  651. negative
  652.         RTS
  653.  
  654.  
  655. *************************************************************************************
  656. *
  657. * object draw routine. draws all the existing objects
  658.  
  659. draw_objects
  660.         MOVE.w  #obj_length*num_objs-obj_length,d7
  661.                                                         * set the index to the last object
  662. draw_loop
  663.         MOVE.w  obj_type(a0,d7.w),d5    * get the object type flag
  664.         BEQ.s           end_draw_loop           * if no object go do next
  665.  
  666. * this object exists so set the pen colour
  667.  
  668.         MOVE.l  obj_colour(a0,d7.w),d1  * get the object colour
  669.         MOVEQ           #80,d0                  * set pen colour
  670.         TRAP            #15
  671.  
  672. * get the object's position
  673.  
  674.         MOVE.w  obj_y(a0,d7.w),d2               * get the object y co-ordinate
  675.         BMI.s           end_draw_loop           * if off screen go do the next object
  676.  
  677.         MOVE.w  obj_x(a0,d7.w),d1               * get the object x co-ordinate
  678.  
  679. * make x2,y2 for a 2 x 2 object on screen
  680.  
  681.         MOVE.w  d1,d3                           * copy x1
  682.         ADDQ.w  #1,d3                           * x2 = x1 + 1
  683.         MOVE.w  d2,d4                           * copy y1
  684.         ADDQ.w  #1,d4                           * y2 = y1 + 1
  685.  
  686. * stars are different, see if this is a star
  687.  
  688.         SUBQ.w  #star,d5                        * is the object a star
  689.         BNE.s           not_star                        * if not go draw a general object
  690.  
  691. * the object is a star so make it 3 x 3
  692.  
  693.         SUBQ.w  #1,d1                           * x1 = x1 - 1
  694.         SUBQ.w  #1,d2                           * y1 = y1 - 1
  695. not_star
  696.         MOVEQ           #87,d0                  * draw a filled rectangle
  697.         TRAP            #15
  698.  
  699. end_draw_loop
  700.         SUB.w           #obj_length,d7          * decrement to previous object
  701.         BPL.s           draw_loop                       * loop if not all done
  702.  
  703.         RTS
  704.  
  705.  
  706. *************************************************************************************
  707. *
  708. * object world setup routine. clear the life and type for each object, get the screen
  709. * size and set the colours
  710.  
  711. setup_world
  712.         LEA             objects(a3),a0          * a0 points to the fire objects
  713.  
  714.         MOVEQ           #0,d0                           * clear the longword
  715.         MOVE.w  #obj_length*num_objs-obj_length,d7
  716.                                                         * set the index to the last object
  717. clear_loop
  718.         MOVE.w  d0,obj_life(a0,d7.w)    * clear the object life flag
  719.         MOVE.w  d0,obj_type(a0,d7.w)    * clear the object type flag
  720.         SUB.w           #obj_length,d7          * decrement the index to the previous object
  721.         BPL.s           clear_loop                      * loop if not all done
  722.  
  723.         MOVE.w  d0,obj_count(a3)                * clear the objects count
  724.         MOVE.w  d0,redraw(a3)           * clear the redraw flag
  725.  
  726. * get the screen size
  727.  
  728.         MOVEQ           #0,d1                           * get current window size
  729.         MOVEQ           #33,d0                  * set/get output window size
  730.         TRAP            #15
  731.  
  732.         MOVE.l  d1,width(a3)            * save the screen x,y size
  733.  
  734. * set the colours
  735.  
  736.         MOVE.l  #$0000FF,d1                     * set the rocket colour
  737.         MOVE.l  d1,rocket_colour(a3)    * save the rocket colour
  738.  
  739.         MOVE.l  #$00FFFF,d1                     * set the exhaust colour
  740.         MOVE.l  d1,zorst_colour(a3)     * save the exhaust colour
  741.  
  742.         MOVE.l  #$FFFFFF,d1                     * set the star colour
  743.         MOVE.l  d1,star_colour(a3)      * save the star colour
  744.  
  745.         MOVEQ           #81,d0                  * set the fill colour
  746.         TRAP            #15
  747.  
  748.         RTS
  749.  
  750.  
  751. *************************************************************************************
  752. *
  753. * setup stuff
  754.  
  755. Initialise
  756.         MOVEQ           #17,d1                  * enable double buffering
  757.         MOVEQ           #92,d0                  * set draw mode
  758.         TRAP            #15
  759.  
  760.         LEA             variables(pc),a3                * get the variables base address
  761.  
  762.         MOVEQ           #8,d0                           * get time in 1/100 ths seconds
  763.         TRAP            #15
  764.  
  765.         EORI.l  #$DEADBEEF,d1           * EOR with the initial PRNG seed, this must
  766.                                                         * result in any value but zero
  767.         MOVE.l  d1,PRNlword(a3)         * save the initial PRNG seed
  768.  
  769.         MOVEQ           #0,d1                           * clear the longword
  770.         MOVE.w  d1,quit(a3)                     * clear the quit flag
  771.  
  772.         RTS
  773.  
  774.  
  775. *************************************************************************************
  776. *
  777. * test if the user wants to quit
  778.  
  779. test_escape
  780.         MOVEQ           #7,d0                           * read the key status
  781.         TRAP            #15
  782.  
  783.         TST.b           d1                              * test the result
  784.         BEQ.s           exit_test_escape                * if no key just exit
  785.  
  786.         MOVEQ           #5,d0                           * read a key
  787.         TRAP            #15
  788.  
  789.         CMPI.b  #ESC,d1                 * compare with [ESC]
  790.         BNE.s           exit_test_escape                * if not [ESC] just exit
  791.  
  792.         MOVEQ           #-1,d1                  * set the longword
  793.         MOVE.w  d1,quit(a3)                     * set the quit flag
  794. exit_test_escape
  795.         RTS
  796.  
  797.  
  798. *************************************************************************************
  799. *
  800. * check the [F2], [F3] and [F4] keys. set the screen size to 640 x 480, 800 x 600 or
  801. * 1024 x 768 if the corresponding key has been pressed
  802.  
  803. screen_size
  804.         MOVE.l  #$71007273,d1           * [F2], [], [F3] and [F4] keys
  805.         MOVEQ           #19,d0                  * check for keypress
  806.         TRAP            #15
  807.  
  808.         MOVE.l  d1,d2                           * copy result
  809.         BEQ.s           notscreen                       * skip screen size if no F key
  810.  
  811.         MOVE.l  #$028001E0,d1           * set 640 x 480
  812.         TST.l           d2                              * test result
  813.         BMI.s           setscreen                       * if F2 go set window size
  814.  
  815.         MOVE.l  #$03200258,d1           * set 800 x 600
  816.         TST.w           d2                              * test result
  817.         BMI.s           setscreen                       * if F3 go set window size
  818.  
  819.                                                         * else was F4 so ..
  820.         MOVE.l  #$04000300,d1           * set 1024 x 768
  821. setscreen
  822.         CMP.l           width(a3),d1            * compare with current screen size
  823.         BEQ.s           notscreen                       * if already set skip setting it now
  824.  
  825.         MOVEQ           #33,d0                  * get/set window size
  826.         TRAP            #15
  827.  
  828.         MOVEQ           #-1,d0                  * set the longword
  829.         MOVE.w  d0,redraw(a3)           * set the redraw flag
  830. notscreen
  831.         RTS
  832.  
  833.  
  834. *************************************************************************************
  835. *
  836. * generate a random value in d0.w in range 0 to d2.w - 1
  837.  
  838. rand_d2
  839.         BSR.s           random_n                        * generate a random number
  840.         MOVEQ           #0,d0                           * clear longword
  841.         MOVE.w  PRNlword(a3),d0         * get a random word
  842.         DIVU.w  d2,d0                           * divide by range
  843.         CLR.w           d0                              * clear the low word
  844.         SWAP            d0                              * use the remainder
  845.         RTS
  846.  
  847.  
  848. *************************************************************************************
  849. *
  850. * This is the code that generates the pseudo random sequence. A seed word located in
  851. * PRNlword(a3) is loaded into a register before being operated on to generate the
  852. * next number in the sequence. This number is then saved as the seed for the next
  853. * time it's called.
  854. *
  855. * This code is adapted from the 32 bit version of RND(n) used in EhBASIC68. Taking
  856. * the 19th next number is slower but helps to hide the shift and add nature of this
  857. * generator as can be seen from analysing the output.
  858.  
  859. random_n
  860.         MOVEM.l d0-d2,-(sp)                     * save d0, d1 and d2
  861.         MOVE.l  PRNlword(a3),d0         * get current seed longword
  862.         MOVEQ           #$AF-$100,d1            * set EOR value
  863.         MOVEQ           #18,d2                  * do this 19 times
  864. Ninc0
  865.         ADD.l           d0,d0                           * shift left 1 bit
  866.         BCC.s           Ninc1                           * if bit not set skip feedback
  867.  
  868.         EOR.b           d1,d0                           * do Galois LFSR feedback
  869. Ninc1
  870.         DBF             d2,Ninc0                        * loop
  871.  
  872.         MOVE.l  d0,PRNlword(a3)         * save back to seed longword
  873.         MOVEM.l (sp)+,d0-d2                     * restore d0, d1 and d2
  874.  
  875.         RTS
  876.  
  877.  
  878. *************************************************************************************
  879. *
  880. * get sin(d0) in d0, cos(d0) in d1
  881.  
  882. sincos
  883.         MOVE.w  d0,d1                           * copy the angle
  884.         BSR.s           cos_d0                  * get COS(d0) in d0
  885.         EXG             d0,d1                           * swap it with d1
  886.  
  887.         BRA.s           sin_d0                  * get SIN(d0) in d0 and return
  888.  
  889.  
  890. *************************************************************************************
  891. *
  892. * get COS(d0) in d0. d0 is a nine bit value representing a full circle with the value
  893. * increasing as you turn widdershins
  894.  
  895. cos_d0
  896.         ADD.w           #$80,d0                 * add 1/4 rotation
  897.  
  898. *************************************************************************************
  899. *
  900. * get SIN(d0) in d0. d0 is a nine bit value representing a full circle with the value
  901. * increasing as you turn widdershins
  902.  
  903. sin_d0
  904.         BTST            #8,d0                           * test angle sign
  905.         BEQ.s           cossin_d0                       * just get SIN/COS and return if +ve
  906.  
  907.         BSR.s           cossin_d0                       * else get SIN/COS
  908.         NEG.w           d0                              * now do twos complement
  909.         RTS
  910.  
  911. * get d0.w from SIN/COS table
  912.  
  913. cossin_d0
  914.         TST.b           d0                              * test for >= $80
  915.         BPL.s           a_was_less                      * branch if < 1/4 circle
  916.  
  917.         NEG.b           d0                              * wrap $81 to $FF to $7F to $01
  918. a_was_less
  919.         AND.w           #$FF,d0                 * ensure word high byte clear
  920.         ADD.w           d0,d0                           * * 2 bytes per word value
  921.         MOVE.w  sin_cos(pc,d0.w),d0     * get the SIN/COS value from the table
  922.         RTS
  923.  
  924.  
  925. *************************************************************************************
  926. *
  927. * SIN/COS table, returns values between $0000 and $7FFF. the last value should be
  928. * $8000 but that can cause an overflow in the word length calculations and it's
  929. * easier to fudge the table a bit. no one will ever notice.
  930.  
  931. sin_cos
  932.         dc.w    $0000,$0192,$0324,$04B6,$0648,$07D9,$096B,$0AFB
  933.         dc.w    $0C8C,$0E1C,$0FAB,$113A,$12C8,$1455,$15E2,$176E
  934.         dc.w    $18F9,$1A83,$1C0C,$1D93,$1F1A,$209F,$2224,$23A7
  935.         dc.w    $2528,$26A8,$2827,$29A4,$2B1F,$2C99,$2E11,$2F87
  936.         dc.w    $30FC,$326E,$33DF,$354E,$36BA,$3825,$398D,$3AF3
  937.         dc.w    $3C57,$3DB8,$3F17,$4074,$41CE,$4326,$447B,$45CD
  938.         dc.w    $471D,$486A,$49B4,$4AFB,$4C40,$4D81,$4EC0,$4FFB
  939.         dc.w    $5134,$5269,$539B,$54CA,$55F6,$571E,$5843,$5964
  940.         dc.w    $5A82,$5B9D,$5CB4,$5DC8,$5ED7,$5FE4,$60EC,$61F1
  941.         dc.w    $62F2,$63EF,$64E9,$65DE,$66CF,$67BD,$68A7,$698C
  942.         dc.w    $6A6E,$6B4B,$6C24,$6CF9,$6DCA,$6E97,$6F5F,$7023
  943.         dc.w    $70E3,$719E,$7255,$7308,$73B6,$7460,$7505,$75A6
  944.         dc.w    $7642,$76D9,$776C,$77FB,$7885,$790A,$798A,$7A06
  945.         dc.w    $7A7D,$7AEF,$7B5D,$7BC6,$7C2A,$7C89,$7CE4,$7D3A
  946.         dc.w    $7D8A,$7DD6,$7E1E,$7E60,$7E9D,$7ED6,$7F0A,$7F38
  947.         dc.w    $7F62,$7F87,$7FA7,$7FC2,$7FD9,$7FEA,$7FF6,$7FFE
  948.         dc.w    $7FFF
  949.  
  950.  
  951. *************************************************************************************
  952. *
  953. * variables used
  954.  
  955. variables
  956.  
  957.         OFFSET  0                               * going to use relative addressing
  958.  
  959. PRNlword
  960.         ds.l    1                                       * PRNG seed long word
  961. quit
  962.         ds.w    1                                       * quit flag
  963. redraw
  964.         ds.w    1                                       * redraw the world flag
  965.  
  966. width
  967.         ds.w    1                                       * screen width
  968. height
  969.         ds.w    1                                       * screen height
  970.  
  971. rocket_colour
  972.         ds.l    1                                       * rocket colour
  973. zorst_colour
  974.         ds.l    1                                       * exhaust colour
  975. burst_colour
  976.         ds.l    1                                       * burst colour
  977. star_colour
  978.         ds.l    1                                       * star colour
  979.  
  980. v_burst
  981.         ds.w    1                                       * burst velocity for this burst
  982. obj_count
  983.         ds.w    1                                       * the number ot active objects
  984.  
  985. objects
  986. obj_life                                        EQU     *-objects
  987.         ds.w    1                                       * object life
  988. obj_type                                        EQU     *-obj_life
  989.         ds.w    1                                       * object type
  990. obj_x                                           EQU     *-obj_life
  991.         ds.l    1                                       * object x co-ordinate  16.16
  992. obj_y                                           EQU     *-obj_life
  993.         ds.l    1                                       * object y co-ordinate  16.16
  994. obj_vx                                  EQU     *-obj_life
  995.         ds.l    1                                       * object x velocity     16.16
  996. obj_vy                                  EQU     *-obj_life
  997.         ds.l    1                                       * object y velocity     16.16
  998. obj_drag                                        EQU     *-obj_life
  999.         ds.w    1                                       * drag effect
  1000. obj_accel                                       EQU     *-obj_life
  1001.         ds.w    1                                       * acceleration life
  1002. obj_x_accel                                     EQU     *-obj_life
  1003.         ds.l    1                                       * object x acceleration 16.16
  1004. obj_y_accel                                     EQU     *-obj_life
  1005.         ds.l    1                                       * object y acceleration 16.16
  1006. obj_colour                                      EQU     *-obj_life
  1007.         ds.l    1                                       * object colour
  1008. obj_length                                      EQU     *-obj_life
  1009.  
  1010.         ds.b    obj_length*num_objs-obj_length
  1011.                                                         * room for the rest of the objects
  1012.  
  1013. *************************************************************************************
  1014.  
  1015.  
  1016.         END     start
  1017.  
  1018.  
  1019. *************************************************************************************
  1020.  
« Last Edit: October 23, 2015, 03:04:23 AM by John »

Mike Lobanovsky

  • Guest
Re: EASy68K
« Reply #1 on: October 23, 2015, 07:59:12 PM »
This could be interesting for an asm geek with one clarification: 68K (Motorola) assembler syntax is not compatible with modern i386-oriented Intel (Windows-mostly) and AT&T (*nix-mostly) assembly languages.

Offline John

  • Forum Support / SB Dev
  • Posts: 3510
    • ScriptBasic Open Source Project
Re: EASy68K
« Reply #2 on: October 23, 2015, 09:11:28 PM »
I thought Paul Dunn might find it interesting and rejoin the All BASIC forum.