Source Code
![]() |
YAYUL: ASSEMBLE REVISION 6 OF PROGRAM BOREALIS BY MSTEWART JUN. 28,2017This is a modern AGC system self-test program, though based on the Apollo-era AURORA 12 program, and was not written by the original AGC developers, but rather by Mike Stewart. All of the original AURORA 12 DAP code added by the DAP Group has been removed, and extensive new system test code has been added in its place. This allows more in-depth testing of CPU behavior, both in AGC software simulations and hardware simulations. |
017533,000002: ## Copyright: Public domain.
017534,000003: ## Filename: AGC_BLOCK_TWO_EXTENDED_TESTS.agc
017535,000004: ## Purpose: This program is designed to extensively test the Apollo Guidance Computer
017536,000005: ## (specifically the LM instantiation of it). It is built on top of a heavily
017537,000006: ## stripped-down Aurora 12, with all code ostensibly added by the DAP Group
017538,000007: ## removed. Instead Borealis expands upon the tests provided by Aurora,
017539,000008: ## including corrected tests from Retread 44 and tests from Ron Burkey's
017540,000009: ## Validation.
017541,000010: ## Assembler: yaYUL
017542,000011: ## Contact: Mike Stewart <mastewar1@gmail.com>.
017543,000012: ## Website: www.ibiblio.org/apollo/index.html
017544,000013: ## Mod history: 2017-01-15 MAS Created to hold new extended tests, starting off with
017545,000014: ## checking out all the timers, EDRUPT, BRUPT substitution,
017546,000015: ## and interrupts following an INDEX.
017547,000016:
017548,000017: 24,2000 BANK 24
017549,000018: # The extended tests check out functionalities not exercised by the Aurora or Retread tests. First up
017550,000019: # is testing of the interrupt priority chain (insofar as it can be deterministically and automatically
017551,000020: # checked) by queuing up all four timer interrupts, and then executing them one at a time using EDRUPT.
017552,000021:
017553,000022: # What we're about to do is sensitive to the phasing of TIME3. Instead of risking it, we simply wait
017554,000023: # for the next TIME3 increment so we can be sure we're safe.
017555,000024: 24,2000 30026 EXTTESTS CA TIME3
017556,000025: 24,2001 55371 TS SKEEP1
017557,000026: 24,2002 40026 WAITT3 CS TIME3 # Wait for the next TIME3 increment.
017558,000027: 24,2003 61371 AD SKEEP1 # No TCs are needed due to a bug in
017559,000028: 24,2004 00006 EXTEND # the TC alarm hardware.
017560,000029: 24,2005 12002 BZF WAITT3
017561,000030:
017562,000031: # With phasing correct, inhibit interrupts and trigger all the timers.
017563,000032: 24,2006 00004 INHINT
017564,000033:
017565,000034: 24,2007 37704 SCHEDT6 CAF LOW4 # Start with TIME6. It counts the fastest,
017566,000035: 24,2010 54031 TS TIME6 # and will provide a bounds after which we'll
017567,000036: 24,2011 37653 CAF BIT15 # know all the others have fired.
017568,000037: 24,2012 00006 EXTEND
017569,000038: 24,2013 05013 WOR CHAN13 # Start the timer for a bit over 10ms. This
017570,000039: # bit resetting will tell us we're done.
017571,000040:
017572,000041: 24,2014 37651 SCHEDT5 CAF POSMAX # Schedule T5RUPT to happen in <=10ms.
017573,000042: 24,2015 54030 TS TIME5
017574,000043:
017575,000044: 24,2016 37671 SCHEDT3 CAF ONE # Schedule a T3RUPT by waitlisting a task
017576,000045: 24,2017 04517 TC WAITLIST # that does nothing to execute ASAP.
017577,000046: 24,2020 02070 50003 2CADR NOTHING
017578,000047:
017579,000048: # TIME4 needs a bit of special handling. It expects to execute periodically and naively forcing it to
017580,000049: # happen sooner could throw off display handling or other things. Instead, we'll only accelerate it
017581,000050: # if necessary, and if so make sure it doesn't do any actual work in the accelerated interrupt.
017582,000051: 24,2022 10027 SCHEDT4 CCS TIME4 # Check to see if we need to force TIME4.
017583,000052: 24,2023 12025 TCF +2 # TIME4 positive, we may need to accelerate.
017584,000053: 24,2024 12034 TCF T6CHK # TIME4 is zero, so T4RUPT is already pending
017585,000054: 24,2025 67670 AD TWO # Calculate the new TIME4 value (+10ms from old)
017586,000055: 24,2026 54000 OVSK # ... and if that overflows, TIME4 is already going
017587,000056: 24,2027 12031 TCF +2 # to happen as quickly as is possible, so we can
017588,000057: 24,2030 12034 TCF T6CHK # just leave it alone.
017589,000058: 24,2031 55113 TS T4TEMP # Save the adjusted original TIME4 value so T4RUPT
017590,000059: 24,2032 37651 CA POSMAX # can reschedule, and then set T4RUPT to occur in
017591,000060: 24,2033 54027 TS TIME4 # <= 10ms.
017592,000061:
017593,000062: # All of the balls are now rolling, so we can now wait for TIME6 to expire. While doing so, we can
017594,000063: # verify that TIME6 and the DINC sequence behave as expected.
017595,000064: 24,2034 10031 T6CHK CCS TIME6 # Wait for TIME6 to hit -0
017596,000065: 24,2035 12034 TCF T6CHK
017597,000066: 24,2036 05546 TC ERRORS # (NOT +0, is skipped over)
017598,000067: 24,2037 05546 TC ERRORS
017599,000068: 24,2040 47653 CS BIT15 # TIME6 has reached -0. It is, hover, still active,
017600,000069: 24,2041 00006 EXTEND # because DINC doesn't trigger ZOUT (needed for
017601,000070: 24,2042 04013 ROR CHAN13 # T6RUPT) until it occurs when its counter is already
017602,000071: 24,2043 05563 TC -0CHK # +-0. Thus, T6 should still be enabled.
017603,000072:
017604,000073: # We can now waste a bit of time until the final TIME6 count occurs, and in doing so verify that
017605,000074: # it's counting at roughly the expected rate (1/1600 seconds). That translates to ~53.333 MCT. The
017606,000075: # following loops is timed such that from the "CS BIT15" above to to the "EXTEND" below there
017607,000076: # are exactly 54 MCTs (ignoring any counter increments).
017608,000077: 24,2044 35170 CAF NINE
017609,000078: 24,2045 12046 T6BUSYWT NOOP
017610,000079: 24,2046 10000 CCS A
017611,000080: 24,2047 12045 TCF T6BUSYWT
017612,000081:
017613,000082: 24,2050 37653 CAF BIT15 # T6 should now have switched itself off.
017614,000083: 24,2051 00006 EXTEND
017615,000084: 24,2052 02013 RAND CHAN13
017616,000085: 24,2053 05562 TC +0CHK
017617,000086:
017618,000087: # At this point, we can safely expect all four timer interrupts to be pending. We can now
017619,000088: # test each one works, and that each has the correct priority, by executing four EDRUPTs
017620,000089: # and checking to see that the expected timer interrupt was serviced. The expected priority
017621,000090: # order is 6, 5, 3, 4.
017622,000091: 24,2054 36173 PRIOCHK CAF SIX
017623,000092: 24,2055 07741 TC TRIGRUPT
017624,000093: 24,2056 37674 CAF FIVE
017625,000094: 24,2057 07741 TC TRIGRUPT
017626,000095: 24,2060 36176 CAF THREE
017627,000096: 24,2061 07741 TC TRIGRUPT
017628,000097: 24,2062 37667 CAF FOUR
017629,000098: 24,2063 07741 TC TRIGRUPT
017630,000099:
017631,000100: # Timers and their interrupts are healthy. It's finally safe to release interrupts. The
017632,000101: # next test must take place entirely in the 7xxx address range.
017633,000102: 24,2064 00003 RELINT
017634,000103: 24,2065 07711 TC BRUPTCHK
017635,000104:
017636,000105: # Extended tests are complete. Head back to self-check proper.
017637,000106: 24,2066 04104 TC POSTJUMP
017638,000107: 24,2067 40727 CADR EXTTDONE
017639,000108:
017640,000109: # Do-nothing waitlist task, used as a dummy when generating a fast T3RUPT.
017641,000110: 24,2070 04563 NOTHING TC TASKOVER
017642,000111:
017643,000112: 24,2071 ENDEXTST EQUALS
017644,000113:
017645,000114: 7711 SETLOC ENDINTF
017646,000115: # Check EDRUPT's ability to vector to A with no pending interrupts, the correct
017647,000116: # behavior of BRUPT for interrupts following an INDEX, and BRUPT substitution.
017648,000117: 7711 37674 BRUPTCHK CAF FIVE # SKEEP1 = 5. This will be used for indexing.
017649,000118: 7712 55371 TS SKEEP1
017650,000119: 7713 00006 EXTEND # Save our return address.
017651,000120: 7714 23372 QXCH SKEEP2
017652,000121: 7715 37737 CAF ARVECADR # Attempt to use EDRUPT to vector to ARUPTVEC.
017653,000122: 7716 00006 +5 EXTEND # If some other interrupt is taken, continue
017654,000123: 7717 51371 INDEX SKEEP1 # at BRUPTCHK+5 (as calculated by the INDEX).
017655,000124: 7720 07711 EDRPTWRD EDRUPT BRUPTCHK # This instruction should be replaced with
017656,000125: 7721 66043 EDRPT+1 AD NEG4 # "CAF FIVE" upon resume. Make sure it did.
017657,000126: 7722 05570 TC +1CHK
017658,000127: 7723 01372 TC SKEEP2 # EDRUPT-to-A and BRUPT look good. Carry on.
017659,000128:
017660,000129: # Interrupt routine used in BRUPTCHK.
017661,000130: 7724 52011 ARUPTVEC DXCH ARUPT # Although Q is also destroyed, we happen to know
017662,000131: # that the "interrupted" program doesn't need it.
017663,000132:
017664,000133: 7725 40017 CS BRUPT # Check that BRUPT was correctly calculated as
017665,000134: 7726 67720 AD EDRPTWRD # "EDRUPT BRUPTCHK +5".
017666,000135: 7727 67674 AD FIVE
017667,000136: 7730 05563 TC -0CHK
017668,000137:
017669,000138: 7731 40015 CS ZRUPT # ZRUPT should be pointing at the address
017670,000139: 7732 67740 AD EDRP+1AD # immediately following the EDRUPT.
017671,000140: 7733 05563 TC -0CHK
017672,000141:
017673,000142: 7734 37711 CAF BRUPTCHK # Break out of the EDRUPT loop by replacing
017674,000143: 7735 54017 TS BRUPT # BRUPT with "CAF FIVE".
017675,000144: 7736 04573 TC NOQBRSM
017676,000145:
017677,000146: 7737 07724 ARVECADR ADRES ARUPTVEC
017678,000147: 7740 07721 EDRP+1AD ADRES EDRPT+1
017679,000148:
017680,000149: # Routine to trigger a pending timer interrupt and verify that the timer whose number is
017681,000150: # specified in A was the one that got serviced.
017682,000151: 7741 56001 TRIGRUPT XCH L
017683,000152: 7742 00006 EXTEND
017684,000153: 7743 23371 QXCH SKEEP1
017685,000154: 7744 37675 CAF ZERO # Zero LASTIMER so we don't get duped.
017686,000155: 7745 55112 TS LASTIMER
017687,000156: 7746 37757 CA NOPNDADR # EDRUPT will fall back on this vector if
017688,000157: 7747 00006 EXTEND # no interrupts at all are pending.
017689,000158: 7750 07752 EDRUPT TRPTCHK # Trigger an interrupt, then skip over TC ERRORS.
017690,000159: 7751 05546 TC ERRORS
017691,000160: 7752 41112 TRPTCHK CS LASTIMER # Check the timer that just got executed matches
017692,000161: 7753 60001 AD L # what was expected.
017693,000162: 7754 05563 TC -0CHK
017694,000163: 7755 01371 TC SKEEP1
017695,000164:
017696,000165: 7756 05546 NOPNDING TC ERRORS
017697,000166: 7757 07756 NOPNDADR ADRES NOPNDING
017698,000167:
017699,000168: # T5 and T6 interrupt routines. Both currently only set LASTIMER for use with the extended self-tests.
017700,000169: 7760 54016 T5RUPT TS BANKRUPT
017701,000170: 7761 37674 CAF FIVE
017702,000171: 7762 55112 TS LASTIMER
017703,000172: 7763 14571 TCF NOQRSM
017704,000173:
017705,000174: 7764 54016 T6RUPT TS BANKRUPT
017706,000175: 7765 36173 CAF SIX
017707,000176: 7766 55112 TS LASTIMER
017708,000177: 7767 14571 TCF NOQRSM
017709,000178:
017710,000179: 7770 ENDSLFS4 EQUALS
End of include-file AGC_BLOCK_TWO_EXTENDED_TESTS.agc. Parent file is MAIN.agc