{"id":792,"date":"2021-10-22T16:08:46","date_gmt":"2021-10-22T16:08:46","guid":{"rendered":"http:\/\/tlindner.macmess.org\/?p=792"},"modified":"2021-10-22T16:08:46","modified_gmt":"2021-10-22T16:08:46","slug":"salient-assembly-episode-1","status":"publish","type":"post","link":"https:\/\/tlindner.macmess.org\/?p=792","title":{"rendered":"Salient Assembly Episode 1"},"content":{"rendered":"\n<!--\n .tab { margin-left: 40px; }\n blockquote p { margin-bottom: 0px; margin-block-end: 0px}\n-->\n\n<p><a href=\"https:\/\/www.youtube.com\/watch?v=dxwmPFIUpLY\" title=\"https:\/\/www.youtube.com\/watch?v=dxwmPFIUpLY\"><iframe loading=\"lazy\" width=\"356\" height=\"200\" src=\"https:\/\/www.youtube.com\/embed\/dxwmPFIUpLY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" allowfullscreen title=\"Salient Assembly Episode 1\"><\/iframe><\/a>\nWelcome to Salient Assembly.<\/p>\n<p>The show where we deep dive into a very specific 6809 assembly language topic.<\/p>\n<p>Today we&#8217;re talking about calling subroutines. Subroutines are a very important aspect to programming. When ever you find yourself needing to do the same thing in two different parts of your program your best bet is to create a subroutine for that function. This process is so fundamental it has a name: refactoring.<\/p>\n<p>There are many instructions to facilitate this. But the today we&#8217;ll be investiagting Branch to subroutine, and jump to subroutine. The branch version is used in position independant code, and also has a faster, shorter version for smaller branches.<\/p>\n<h1>JSR with no parameters<\/h1>\n<p>Let&#8217;s first talk about a subroutine that requires no parameters to be passed. The JSR instruction will push the address of the next instruction to the stack and then pass control to the subroutine.<\/p>\n<p>The RTS instruction will pull two bytes off the top of the stack and jump to that memory location.<\/p>\n<p>These two instructions are what enable calling subroutines in 6809 assemble language.<\/p>\n<p>For example, let&#8217;s say we&#8217;re writing a game and we want to write a subroutine that displays the text GAME OVER in the center of the screen.<\/p>\n<blockquote><code>GameOverCondition\n&lt;p class=&quot;tab&quot;&gt;jsr GAMEOVER&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jmp NextMiniGame&lt;\/p&gt;\n\nGAMEOVER\n&lt;p class=&quot;tab&quot;&gt;ldx #$50C&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldy #text&lt;\/p&gt;\nloop\n&lt;p class=&quot;tab&quot;&gt;lda ,y+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;sta ,x+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;bra loop&lt;\/p&gt;\nWaitGameOver\n&lt;p class=&quot;tab&quot;&gt;jsr [POLCAT]&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;rts&lt;\/p&gt;\ntext fcn &quot;GAME OVER&quot;\n<\/code>\n<\/blockquote>\n<p><br><br>\nHere we see the code for a mini game ending. Let&#8217;s dig in deep to the specifics<\/p>\n<p>\u2022 We execute the jsr instruction. It will push the address of the next instruction on the stack and jump to the operand.\n\u2022 Do the work of the subroutine. This will copy some text to the middle of the VDG screen.\n\u2022 Then return to the main program<\/p>\n<h1>JSR with calculated address<\/h1>\n<p>Sometimes you want to branch to different subroutines based on a condition. One method to do this is with a table of of subroutines. For example:<\/p>\n<blockquote><code>GameOverCondition\n&lt;p class=&quot;tab&quot;&gt;ldb randomNumber&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;aslb&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldx #gameOverTable&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;abx&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jsr [,x]&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jmp nextMiniGame&lt;\/p&gt;\ngameOverTable\n&lt;p class=&quot;tab&quot;&gt;fdb WaitGameOver1&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;fdb WaitGameOver2&lt;\/p&gt;\nWaitGameOver1\n&lt;p class=&quot;tab&quot;&gt;...&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;rts&lt;\/p&gt;\nWaitGameOver2\n&lt;p class=&quot;tab&quot;&gt;...&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;rts&lt;\/p&gt;\n<\/code><\/blockquote>\n<p><br>\n\u2022 I load a previously calculated random number that will be 0 or 1.\n\u2022 Then multiply it by two.\n\u2022 I add that value to the base address of the subroutine table.\n\u2022 Then jump to that specific subroutine.\n\u2022 After the subroutine finishes, it returns to the main program.<\/p>\n<h1>Parameter passing<\/h1>\n<p>Most of the time a subroutine will take parameters. These are values that change how the subroutine functions. In the example we&#8217;ve seen so far we may want to change the subroutine to make the text it displays variable. We also may want to have the text&#8217;s final position variable. Let&#8217;s go over some methods of passing these parameters to our subroutine.<\/p>\n<h1>JSR fixed memory locations<\/h1>\n<p>A simple, non-position independant method of passing parameters to a sub-routine is by using fixed memory locations.<\/p>\n<blockquote><code>GameOverCondition\n&lt;p class=&quot;tab&quot;&gt;ldx #text&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;stx textBufferAddress&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldx #$50C&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;stx textposition&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jsr GAMEOVER&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jmp NextMiniGame&lt;\/p&gt;\nGAMEOVER\n&lt;p class=&quot;tab&quot;&gt;ldx textposition&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldy textBufferAddress&lt;\/p&gt;\nloop\n&lt;p class=&quot;tab&quot;&gt;lda ,y+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;sta ,x+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;bra loop&lt;\/p&gt;\nWaitGameOver\n&lt;p class=&quot;tab&quot;&gt;jsr [POLCAT]&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;rts&lt;\/p&gt;\ntextBufferAddress fdb 0\ntextposition fdb 0\ntext fcn &quot;GAME OVER&quot;\n<\/code>\n<\/blockquote>\n<p><br><\/p>\n<ol>\n<li>load the address of the text string and store it in the parameter area<\/li>\n<li>load the screen position and store it into the parameter area<\/li>\n<li>jump to the subroutine<\/li>\n<li>load the parameters into registers and perform the function.<\/li>\n<li>then return to the main program.<\/li>\n<\/ol>\n<p>This allows the GAMEOVER subroutine to print different messages. You can pass different text string and different positions to get different results.<\/p>\n<h1>JSR register<\/h1>\n<p>A faster way to pass parameters would be to use registers<\/p>\n<blockquote><code>GameOverCondition\n&lt;p class=&quot;tab&quot;&gt;ldy #text&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldx #$50C&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jsr GAMEOVER&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jmp NextMiniGame&lt;\/p&gt;\nGAMEOVER\nloop\n&lt;p class=&quot;tab&quot;&gt;lda ,y+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;sta ,x+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;bra loop&lt;\/p&gt;\nWaitGameOver\n&lt;p class=&quot;tab&quot;&gt;jsr [POLCAT]&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;rts&lt;\/p&gt;\ntext fcn &quot;GAME OVER&quot;\n<\/code><\/blockquote>\n<p><br>\n\u2022 load the registers with the parameters\n\u2022 call the subroutine\n\u2022 notice how the registers are all setup ready for the function to be done.\n\u2022 and return to the main program.<\/p>\n<h1>JSR stack<\/h1>\n<p>The stack is also a good way to pass parameters to a subroutine. Since the return address is already stored on the stack it makes sense to put the other parameters there.<\/p>\n<blockquote><code>GameOverCondition\n&lt;p class=&quot;tab&quot;&gt;ldx #text&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;pshs x&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldx #$50C&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;pshs x&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jsr GAMEOVER&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jmp NextMiniGame&lt;\/p&gt;\nGAMEOVER\n&lt;p class=&quot;tab&quot;&gt;puls u&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;puls x&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;puls y&lt;\/p&gt;\nloop\n&lt;p class=&quot;tab&quot;&gt;lda ,y+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;sta ,x+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;bra loop&lt;\/p&gt;\nWaitGameOver\n&lt;p class=&quot;tab&quot;&gt;jsr [POLCAT]&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;tfr u,pc&lt;\/p&gt;\ntext fcn &quot;GAME OVER&quot;<\/code><\/blockquote>\n<p><br>\n\u2022 Push the two parameters onto the stack\n\u2022 Call the subroutine\n\u2022 Pop the return address off the stack\n\u2022 pop the parameters off the stack\n\u2022 perform the function\n\u2022 transfer the return address to the pc register and return to the main program.<\/p>\n<h1>JSR post data<\/h1>\n<p>The last method we&#8217;ll discuss is when you put the data to be passed after the subroutine call. Care must be taken to return to the proper address when done with the subroutine.<\/p>\n<blockquote><code>GameOverCondition\n&lt;p class=&quot;tab&quot;&gt;jsr GAMEOVER&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;fdb $50C&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;fcn &quot;GAME OVER&quot;&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;jmp NextMiniGame&lt;\/p&gt;\nGAMEOVER\n&lt;p class=&quot;tab&quot;&gt;puls x&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;leay 2,x&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;ldx ,x&lt;\/p&gt;\nloop\n&lt;p class=&quot;tab&quot;&gt;lda ,y+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;sta ,x+&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;bra loop&lt;\/p&gt;\nWaitGameOver\n&lt;p class=&quot;tab&quot;&gt;jsr [POLCAT]&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;beq WaitGameOver&lt;\/p&gt;\n&lt;p class=&quot;tab&quot;&gt;tfr y,pc&lt;\/p&gt;<\/code><\/blockquote>\n<p><br>\n\u2022 First we call the subroutine\n\u2022 immediately after the call, we put two bytes of a destination address and then a string of characters with a zero terminator.\n\u2022 In the subroutine we load x with the address that was pushed onto the stack. This is technically the return address, but if we used it as such, we would return to data, not code.\n\u2022 Then we load register Y with the address of the text string\n\u2022 Then we load register X with the address of the text destination.\n\u2022 We perform the function\n\u2022 Then we return from the subroutine by transferring the Y register to the PC register which will conveniently be the proper return address.<\/p>\n<p>That&#8217;s it for this episode. I hope you had a good time learning about subroutines and all the various ways you can pass parameters to them.<\/p>\n<p>Bye for now.<\/p>","protected":false},"excerpt":{"rendered":"<p>Welcome to Salient Assembly. The show where we deep dive into a very specific 6809 assembly language topic. Today we&#8217;re talking about calling subroutines. Subroutines are a very important aspect to programming. When ever you find yourself needing to do &hellip; <a href=\"https:\/\/tlindner.macmess.org\/?p=792\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-792","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=\/wp\/v2\/posts\/792","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=792"}],"version-history":[{"count":17,"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=\/wp\/v2\/posts\/792\/revisions"}],"predecessor-version":[{"id":809,"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=\/wp\/v2\/posts\/792\/revisions\/809"}],"wp:attachment":[{"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=792"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=792"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tlindner.macmess.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=792"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}