{"id":283,"date":"2011-12-21T12:38:29","date_gmt":"2011-12-21T18:38:29","guid":{"rendered":"http:\/\/tommysprinkle.com\/txxos\/?p=283"},"modified":"2021-04-17T18:25:11","modified_gmt":"2021-04-17T23:25:11","slug":"determine-memory-size","status":"publish","type":"post","link":"https:\/\/tommysprinkle.com\/txxos\/?p=283","title":{"rendered":"Determine Memory Size"},"content":{"rendered":"<p>In order to relocate to high memory we must first determine how much memory is available. \u00a0Hercules allows us to define a memory size from 1 to 16 megabytes in 1 megabyte increments.<\/p>\n<p>To determine the memory we have available at IPL time we will simply scan through all memory beginning at location zero until we reach 16 Meg or we get an error attempting to access memory.<\/p>\n<p>We will use the SSK (Set Storage Key) instruction to test for vaild storage. \u00a0It has the format SSK R1,R2. \u00a0Bits 21-27 of R2 specify a 2k (2048) block memory. \u00a0The storage key is set to the value specified by bits 24-30 of R1. \u00a0If the storage block does not exist an Access Specification interrupt is generated.<\/p>\n<p>By using the SSK instruction we not only determine how much memory is available but we also set the access key for all memory to zero.<\/p>\n<pre> *\r\n *\r\n          LA    R2,0\r\n          LA    R3,0\r\n          L     R4,=A(X'01000000')   16 MEG\r\n          LA    R1,2048              2K\r\n *\r\n          MVC   104(8),=A(0,MDONE) PROGRAM CHECK NEW PSW\r\n *\r\n MLOOP    DS    0H\r\n          SSK   R2,R3              SET STORAGE KEY\r\n          AR    R3,R1              NEXT 2K PAGE\r\n          CR    R3,R4              HIT 16 MEG?\r\n          BL    MLOOP              LOOP BACK\r\n *\r\n MDONE    DS    0H\r\n          MVC   104(8),=A(X'00020000',X'00010BAD') PC NEW PSW\r\n *\r\n *<\/pre>\n<p>We start by setting our access key value to zero in Register 2. \u00a0We set the initial address in Register 3 to zero (storage location zero). \u00a0Register 4 is set to the maximum memory size (16 Meg) and Register 1 is set to 2k for our increment value.<\/p>\n<p>Before beginning the loop we specify a New Program Check PSW. \u00a0If a program check interruption occurs, the CPU will load the value contained at location 104 into the PSW. \u00a0Here we specify a PSW with MDONE as the instruction address value. \u00a0If a program check occurs it will effectively cause a branch to the label MDONE.<\/p>\n<p>The loop is very simple. \u00a0We use the SSK instruction to set the storage key of a 2k block of storage. \u00a0If the storage address does not exist a program check interruption occurs which causes a branch in execution to MDONE. \u00a0If the SSK was successful we add 2k to the address, check to see if we have reached the maximum memory size (16 Meg) and then loop back.<\/p>\n<p>When we reach MDONE either because of a program check interruption or because fell through the branch, Register 3 contains the high memory address and tells us how much memory is available.<\/p>\n<p>The first thing we need to do is to set a new program check PSW. \u00a0Here we load a PSW with the wait bit set and an error code of x&#8217;010BAD&#8217;. \u00a0If we failed to specify a new program check PSW and a a program check \u00a0occurred, we could possibly end up in an endless loop.<\/p>\n<pre>*\r\n         ST    R3,WORK4           SAVE MEMORY SIZE\r\n         UNPK  WORK8(9),WORK4(5)  UNPACK\r\n         TR    WORK8,TRTAB-C'0'   MAKE PRINTABLE\r\n*\r\n*\r\n         LR    R1,R3              COPY MEMORY SIZE\r\n         SLR   R0,R0\r\n         D     R0,=A(X'00100000')  DIVIDE BY 1MEG\r\n         CVD   R1,DOUBLE          SAVE RESULT AS DECIMAL\r\n         ED    EDWK,DOUBLE+6\r\n         MVC   MEMSIZE2,EDWK+1\r\n*\r\n*\r\n         MVC   MEMSIZE1,WORK8     MOVE IN MEMORY SIZE\r\n*\r\n         @PRINT MSG1,LEN=L'MSG1\r\n         @PRINT MSG2,LEN=L'MSG2\r\n         @PRINT MSG1,LEN=L'MSG1\r\n*\r\n*\r\n         LPSW   DONE\r\n*<\/pre>\n<p>For testing we can us UNPK and then TR to get a printable hex value. \u00a0We then divide the max memory size by 1 Meg, and use CVD and ED to get a decimal value. \u00a0These values are moved into our print line and then printed.<\/p>\n<pre>DONE     DC    A(X'00020000',X'0099FACE')   WAIT STATE PSW\r\n*                                                                      \r\n\r\nMSG1     DC    C'*****************************************************'\r\nMSG2     DC    CL132' '\r\n         ORG   MSG2\r\n         DC    C'  MEMORY SIZE=X'''\r\nMEMSIZE1 DC    CL8'********',C'''  '\r\nMEMSIZE2 DC    CL3'***',C' MEG'\r\n         ORG   ,\r\n*\r\nDOUBLE   DS    D\r\nFSA      DS    18F\r\nWORK4    DS    F\r\nWORK8    DC    CL8'********',C'**'\r\n*\r\nEDWK     DC    X'40202020'\r\n*\r\nTRTAB    DC    C'0123456789ABCDEF'\r\n*<\/pre>\n<p>The complete program is available at DBOOT1.<\/p>\n<p>[Next &#8211; <a title=\"Copy To High Memory\" href=\"http:\/\/tommysprinkle.com\/txxos\/?p=289\">Copy To High Memory<\/a>]<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In order to relocate to high memory we must first determine how much memory is available. \u00a0Hercules allows us to define a memory size from 1 to 16 megabytes in 1 megabyte increments. To determine the memory we have available &hellip; <a href=\"https:\/\/tommysprinkle.com\/txxos\/?p=283\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"template-page-builder-no-sidebar.php","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-283","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1CPQT-4z","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/283","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=283"}],"version-history":[{"count":3,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/283\/revisions"}],"predecessor-version":[{"id":494,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=\/wp\/v2\/posts\/283\/revisions\/494"}],"wp:attachment":[{"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=283"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=283"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tommysprinkle.com\/txxos\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=283"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}