ABOUT THIS PROGRAM This is a Graphical CARDIAC CPU Simulator that I made based on the CARDIAC Cardboard Computer by David Hagelbarger, and Saul Fingerman, Bell Telephone Laboratories, (a Bell System Educational Aid.) WHAT IS A CARDIAC CARDBOARD COMPUTER? The CARDIAC Cardboard Computer is a theory based paper computer that allows individuals without access to a computer to program a computer made of cardboard. If someone knows how to draw the CARDIAC Computer, (see https://ia800804.us.archive.org/18/items/CardiacCardboardIllustrativeAidToComputation/Enhanced%20Edition/CARDIAC_Instruction_Manual.pdf), that person can work out programs in the sand, on doodle notes in class, or anywhere there is no access to a computer. I know of the many lost hours that I could have been programming when as a child, because I had to get permission from people to use their computer. Now smart phones, laptops and other devices are available everywhere and the CARDIAC Computer is a relic. I've developed the Graphic CARDIAC CPU Simulator for Android, using RFO-BASIC, so I can continue coding for it when I have a free moment, and it fits in my pocket. HOW TO USE THE GRAPHICAL CARDIAC CPU SIMULATOR There are two ways to enter values into the memory slots. The direct way is to tap on the memory slots, and the app will go into editing mode. While in editing mode, use the up and down arrows to select a memory slot. Then tap the large numbers on the numberpad at the bottom of the screen to enter vales. Tap the page back button at the top left of the screen to go back to the main page. The indirect way to enter values into the memory slots is by loading a Card as input. To load a card as input, tap the input button. You can paste a boot program from a text editor, or type in three digit comma seperated values to make a horizontal list, or by typing three digit values and hitting after each value to make a vertical list. When done, tap the "Ok" button. The Card is loaded into the input slot and when the program executes, the code is inputted into memory as coded by you. Coding a boot card goes like this: The first machine instruction you should know for CARDIAC is the "001" instruction. This is the Operation Code "0", telling the CPU to input into memory location "01". The first value in a boot card will be "002" which will be input into location 01. The Program Counter will advance to the location 01 and the Instruction Decoder interpret "0" to input the next value into location 02. What the new CARDIAC programmer needs to know is that every machine instruction beginning with a zero will input the next value on the Card into the memory location stated by the second two digits called the Operand. "0" + "01" = "001". The jump to zero instruction, "800", is used next to create a loop to memory location 00, causing the entire Card to be input or until the "800" value in location 02 is changed. At the end of the boot card, that value is changed to jump to the start location of the program. Try it with this code and tap the step down button on the bottom left of Graphical CARDIAC CPU Simulator to see how the input loads: BOOT CARD LOAD DATA: 002 800 003 123 004 456 005 789 006 900 002 806 What this boot card does is load the values "123", "456", "789", and "900" into memory locations 03, 04, 05, and 06. The first three values are just data for the program. The instruction, "900", tells the CARDIAC to Halt and Reset the PC to memory location 00. A FULL LIST OF ALL TEN INSTRUCTIONS OF THE CARDIAC CPU: Opcode Mnemonic Operation 0 INP Read a card into memory 1 CLA Clear accumulator and add from memory (load) 2 ADD Add from memory to accumulator 3 TAC Test accumulator and jump if negative 4 SFT Shift accumulator 5 OUT Write memory location to output card 6 STO Store accumulator to memory 7 SUB Subtract memory from accumulator 8 JMP Jump and save PC 9 HRS Halt and reset https://www.cs.drexel.edu/~bls96/museum/cardiac.html HOW THE BUTTONS ON THE GRAPHIC CARDIAC CPU SIMULATOR FUNCTION The top left button at start up, is the execute button. It will run the code that is displayed in the CARDIAC CPU's memory. It is the fastest way to execute the code. The button underneith that is a stepped execute that runs while also displaying the values of the Program Counter and Instruction Register, the instruction decoded, and the memory offset that the arrow buttons point to. The second to bottom left button is the Execution Halt button. Tap it during an executing program and the CARDIAC CPU Simulator will halt. The bottom left button is the Step Down button, previously explained. Next to the Input Button is the Output Button. Tapping it allows any output from the user program to be copied and pasted for export. The button to the right of the Output Button is the Reset Button, and underneith that is the Full Reset Button. Tap the BACK Button on your Android to exit the app. EXAMPLE CODES OF CARDIAC CARDBOARD COMPUTER PROGRAMS THAT I HAVE WRITTEN: REM Objective: Zero the Accumulator whenever needed. AC=2018 % Before AC=MEMORY_SLOT[03] AC=AC-MEMORY_SLOT[03] % After 03 103 START: CLA 103 ; Clear and Load the Accumulator with contents of memory location 03: 04 703 SUB 103 ; Solve for n. 103 - n = 0 05 903 END: HRS 03 ; Halt and reset Program Counter to memory location 03: BOOT CARD ZERO THE ACCUMULATOR: 002 800 003 103 004 703 005 903 002 803 REM Objective: Multiply and output result. PRINT A * B MEMORY LAYOUT AND ASSEMBLY CODE: 00: 001 ; *****BEGIN BOOTSTRAP BY LOADING CARD INTO MEMORY**** 01: 002 DATA 002 ; 02: 8-- ; ***DURING BOOT-->JMP 00; BOOTSTRAP COMPLETE-->JMP 07*** ; 03: --- A DATA --- ; Pick any non-negative value, between 0 and the number that adds up to <= 999. This code does not error check for sums 04: --- B DATA --- ; greater than 999. Examples: 1 * 999, 3 * 333, 11 * 99, 3 * 7. Note: for fastest speeds arrange A < B. 05: 999 COUNTD DATA 999 ; Use A to count down how many times to add B to the FACTORY. 06: 999 FACTORY DATA 999 ; Build the multiples of B here. 19: 000 ZERO DATA 000 ; (Place a zero value at memory location, 19:, for this code to work properly.) ; 07: 103 Start CLA A ; 08: 700 SUB 001 ; 09: 605 STO COUNTD ; 10: 119 CLA ZERO ; 11: 204 LOOP01 ADD B ; 12: 606 STO FACTORY ; 13: 105 CLA COUNTD ; 14: 700 SUB 001 ; 15: 320 TAC ELOOP01 ; 16: 605 STO COUNTD ; 17: 106 CLA FACTORY ; 18: 811 JMP LOOP01 ; 20: 506 ELOOP01 OUT FACTORY ; 21: 907 HRS 07 ; BOOTCARD MULTIPLY WITH OUTPUT: 002 800 003 5 004 7 005 999 006 999 007 103 008 700 009 605 010 119 011 204 012 606 013 105 014 700 015 320 016 605 017 106 018 811 019 000 020 506 021 907 002 807 REM Objective: Create a nested FOR/NEXT loop. FOR y=1 TO 5 PRINT y FOR x=1 TO 5 PRINT x NEXT x NEXT y MEMORY LAYOUT AND ASSEMBLY CODE: 00 001 ; *****BEGIN BOOTSTRAP**** 01 000 ; ************************ 02 800 ; ***BOOTSTRAP COMPLETE*** 03 001 xLOWER DATA 001 04 005 xUPPER DATA 005 05 000 xCOUNTD DATA --- ; (IF xCOUNT < 0 EXIT FOR x) 06 001 yLOWER DATA 001 07 005 yUPPER DATA 005 08 000 yCOUNTD DATA --- ; (IF yCOUNT < 0 EXIT FOR y) 09 000 10 107 CLA yUPPER ; FOR y=1 TO 5 11 706 SUB yLOWER 12 608 STO yCOUNTD 13 506 yNEXT OUT yLOWER ; PRINT y 14 104 CLA xUPPER ; FOR x=1 TO 5 15 703 SUB xLOWER 16 605 STO xCOUNTD 17 503 xNEXT OUT xLOWER ; PRINT x 18 103 CLA xLOWER 19 200 ADD 001 20 603 STO xLOWER 21 105 CLA xCOUNTD 22 700 SUB 001 23 605 STO xCOUNTD 24 326 TAC xCONT 25 817 JMP xNEXT ; NEXT x 26 103 xCONT CLA xLOWER 27 704 SUB xUPPER 28 603 STO xLOWER ; FOR/NEXT x cycle complete 29 106 CLA yLOWER 30 200 ADD 00 31 606 STO yLOWER 32 108 CLA yCOUNTD 33 700 SUB 00 34 608 STO yCOUNTD 35 337 TAC yCONT 36 813 JMP yNEXT ; NEXT y 37 106 yCONT CLA yLOWER 38 707 SUB yUPPER 39 606 STO yLOWER ; FOR/NEXT y cycle complete 40 900 exit HRS 00 BOOTCARD FOR/NEXT LOOP: 002 800 010 107 011 706 012 608 013 506 014 104 015 703 016 605 017 503 018 103 019 200 020 603 021 105 022 700 023 605 024 326 025 817 026 103 027 704 028 603 029 106 030 200 031 606 032 108 033 700 034 608 035 337 036 813 037 106 038 707 039 606 003 001 004 005 006 001 007 005 040 900 002 810 OBJECTIVE OF THIS DEMO IS TO CREATE A NESTED FOR/NEXT LOOP AND CALCULATE THE OFFSET OF CARTESIAN COORDINATES THEN POKE A COUNT IN A HORIZONTAL DIRECTION: w = 10 COUNTU001 = 0 FOR yCOUNTU = 0 TO 8 FOR xCOUNTU = 7 TO 9 i = yCOUNTU + (xCOUNTU * w) POKE i, CNTU001 CNTU001=CNTU001 + 1 out xCOUNTU out yCOUNTU NEXT xCOUNTU NEXT yCOUNTU During execution the program "POKES" to memory by calculating the OPERAND i for STO i, where i is the offset in memory to write the Accumulator to. The program calculates offset i from the x and y coordinates. A nested FOR/NEXT loop for x is in the FOR/NEXT loop for y. The coordinates of x and y are outputed. The memory viewer shows a count in memory locations 70 through 98 (within the boundries of x and y). Notice that the count is plotted horizontally from left to right with wrap around. MEMORY LAYOUT AND ASSEMBLY CODE: 00: 001 STEP001 DATA 001 ; After boot, this memory location is left alone to be used to increment/decrement. 01: 002 PRDCT01 DATA --- ; During execution the multiplication function places its product here. 02: 815 CNTD001 DATA --- ; The multiplication function also places a downwards count here. 03: 7 xLOWER DATA 7 ; 04: 9 xUPPER DATA 9 ; 05: 999 xCOUNTD DATA 999 ; (IF xCOUNTD < 0 EXIT FOR x) 06: 000 xCOUNTU DATA 000 ; 07: 0 yLOWER DATA 0 ; 08: 8 yUPPER DATA 8 ; 09: 999 yCOUNTD DATA 999 ; (IF yCOUNTD < 0 EXIT FOR y) 10: 000 yCOUNTU DATA 000 ; 11: 10 W DATA 10 ; 12: 999 i DATA 999 ; 13: 0 CNTU001 DATA 0 ; This example will use an upwards count as the data to put into memory block (7,0)-(9,8). 14: 600 SIXHUN DATA 600 ; This is the OPCODE for STO at location 00, which will be added to i to create a new OPCODE: 6i, and then surgered into code. 15: 108 START CLA yUPPER ; FOR y = 0 TO 8 16: 707 SUB yLOWER ; 17: 609 STO yCOUNTD ; 18: 107 CLA yLOWER ; yCOUNTU = yLOWER 19: 610 STO yCOUNTU ; 20: 104 yNEXT CLA xUPPER ; FOR x = 7 TO 9 21: 703 SUB xLOWER ; 22: 605 STO xCOUNTD ; 23: 103 CLA xLOWER ; xCOUNTU = xLOWER 24: 606 STO xCOUNTU ; ; ; Calculate i = yCOUNTU + (xCOUNTU * W). ; 25: 106 xNEXT CLA xCOUNTU ; Clear the Accumulator and load xCOUNTU. 26: 602 STO CNTD001 ; CNTD001 = xLOWER 27: 702 SUB CNTD001 ; ZERO out the Accumulator. (AC = xLOWER and CNTD001 = xLOWER, so AC - CNTD001 = 0.) 28: 835 JMP KPAC001 ; Skip past some code to get into the loop at the correct place. 29: 102 LP001 CLA CNTD001 ; Clear the Accumulator and load CNTD001. 30: 700 SUB STEP001 ; Decrement the Accumulator 31: 337 TAC ELP001 ; Test if the Accumulator is < 0. If so, jump to ELP001 (Exit Loop001). 32: 602 STO CNTD001 ; Store the Accumulator into CNTD001. 33: 101 CLA PRDCT01 ; Clear the Accumulator and load PRDCT01. 34: 211 ADD W ; Add B to the Accumulator. 35: 601 KPAC001 STO PRDCT01 ; Keep the result by storing it in PRDCT01. 36: 829 JMP LP001 ; Repeat the process until complete. 37: 101 ELP001 CLA PRDCT01 ; Clear AC and load PRDCT01. Note that here: PRDCT01 = (xCOUNTU * W) 38: 210 ADD yCOUNTU ; AC = yCOUNTU + PRDCT01 39: 612 STO i ; i = AC 40: 214 ADD SIXHUN ; Add 600 to the AC to get 600 + i, which is the OPCODE to POKE at location i. 41: 643 STO POKE001 ; Change the execution code at POKE001 so it has the opcode "6"+i. 42: 113 CLA CNTU001 ; AC = CNTU001. 43: 670 POKE001 STO 70 ; POKE i, AC. The default value will be 70 for the start of the memory block (7,0)-(9,8). 44: 200 ADD STEP001 ; Increment AC. 45: 613 STO CNTU001 ; Store incremented count into CNTU001. 46: 506 OUT xCOUNTU ; PRINT x 47: 510 OUT yCOUNTU ; PRINT y 48: 106 CLA xCOUNTU ; 49: 200 ADD STEP001 ; 50: 606 STO xCOUNTU ; 51: 105 CLA xCOUNTD ; 52: 700 SUB STEP001 ; 53: 605 STO xCOUNTD ; 54: 356 TAC xCONT ; 55: 825 JMP xNEXT ; NEXT x 56: 110 xCONT CLA yCOUNTU ; FOR/NEXT x cycle complete 57: 200 ADD STEP001 ; 58: 610 STO yCOUNTU ; 59: 109 CLA yCOUNTD ; 60: 700 SUB STEP001 ; 61: 609 STO yCOUNTD ; 62: 364 TAC yCONT ; 63: 820 JMP yNEXT ; NEXT y 64: 915 yCONT HRS START ; FOR/NEXT y cycle complete BOOTCARD: 002 800 003 7 004 9 005 999 006 000 007 0 008 8 009 999 010 000 011 10 012 999 013 0 014 600 015 108 016 707 017 609 018 107 019 610 020 104 021 703 022 605 023 103 024 606 025 106 026 602 027 702 028 835 029 102 030 700 031 337 032 602 033 101 034 211 035 601 036 829 037 101 038 210 039 612 040 214 041 643 042 113 043 670 044 200 045 613 046 506 047 510 048 106 049 200 050 606 051 105 052 700 053 605 054 356 055 825 056 110 057 200 058 610 059 109 060 700 061 609 062 364 063 820 064 915 002 815