(42S) CARDIAC
10-11-2014, 08:54 PM (This post was last modified: 06-15-2017 01:20 PM by Gene.)
Post: #1
 Thomas Klemm Senior Member Posts: 1,448 Joined: Dec 2013
(42S) CARDIAC
Quote:The acronym CARDIAC stands for "CARDboard Interactive Aid to Computation." It was developed by David Hagelbarger at Bell Labs as a tool for teaching how computers work in a time when access to real computers was extremely limited. The CARDIAC kit consists of a folded cardboard "computer" and an instruction manual. In July 1969, the Bell Laboratories Record contained an article describing the system and the materials being made available to teachers for working with it.
-- Brian L. Stuart, A discription of the CARDIAC

This program is a CARDIAC-simulator. It allows to run programs written for CARDIAC on your HP-42S.
In order to work properly we need registers 00-99. Thus you have to set the size accordingly:

SIZE 100

The simulator allows to load a CARDIAC-program (deck of cards) into the the memory of the HP-42S. These cards have to be stored in a matrix. This is an example of a program that counts to 10.

Program Listing:
Code:
04     009     n      DATA    009 05     000     cntr   DATA    000                                10     100            CLA     00      Initialize the counter 11     605            STO     cntr     12     104     loop   CLA     n       If n < 0, exit 13     322            TAC     exit 14     505            OUT     cntr    Output a card 15     105            CLA     cntr    Increment the card 16     200            ADD     00 17     605            STO     cntr 18     104            CLA     n       Decrement n 19     700            SUB     00 20     605            STO     n 21     812            JMP     loop 22     900     exit   HRS     00

Create a 1×2 Matrix and set it to GROW:

1 ENTER 2
MATRIX.NEW
EDIT
GROW

Now enter all the numbers of the listing:
Code:
[   2, 800,  10, 100,  11, 605,  12, 104,  13, 322,  14, 505,  15, 105,  16, 200,  17, 605,  18, 104,  19, 700,  20, 604,  21, 812,  22, 900,   4,   9,   2, 810, ]

STO "COUNT"

The first row [2, 800] is just the boot-loader program.
At the end we write n = 9 into register 4 [4, 9] and then we jump to line 10 to start the program [2, 810].

This loads the program from the matrix into the memory and runs it:

RCL "COUNT"
XEQ "CARDIAC"

Make sure to set flag 21 when using Free42 or it will run too fast to notice anything.
Alternatively you may add a PSE in the implementation of OUT (LBL 05).

If everything is correct you should see:

R05=1
R05=2
R05=3
R05=4
R05=5
R05=6
R05=7
R05=8
R05=9
R05=10

The program is still loaded in the memory of the HP-42S. Let's assume we want to count to 100 instead:

99 STO 04
10 XEQ 99

R05=1
R05=2
R05=3
R05=4
(...)
R05=97
R05=98
R05=99
R05=100

Implementation details
The registers 00-99 are used as memory. The accumulator acc and the program-counter pc are kept on the stack.
The instruction register ir consists of two parts: the code and the address addr. Furthermore the address consists of the left and the right digit. They are used in the "shift accumulator" operator.

Here's an example:

ir = 835
code = 8
left = 3
right = 5

Listing
Code:
;---------------------;------------------ { 207-Byte Prgm }     ; LBL "CARDIAC"         ; ;------- INIT --------;------------------ EDIT                  ; 1:1=2 ←                     ; n:2=0 CF 00                 ; CLRG                  ; 1                     ; 1 STO 00                ; 1 CLST                  ; 0 0 ;---- MAIN LOOP ------;------------------ LBL 99                ; acc pc RCL IND ST X          ; acc pc ir X<>Y                  ; acc ir pc 1                     ; acc ir pc 1 +                     ; acc acc ir pc' X<>Y                  ; acc acc pc' ir 1E2                   ; acc pc' ir 100 ÷                     ; acc acc pc' code.addr FP                    ; acc acc pc' .addr XEQ IND ST L          ; acc acc pc' .addr FC? 00                ; acc acc pc' .addr GTO 99                ; acc acc pc' .addr ;---------------------;------------------ EXITALL               ; CF 00                 ; CLST                  ; RTN                   ; ;------- INP ---------;------------------ LBL 00                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr OLD                   ; acc pc addr card →                     ; acc pc addr card' STO IND ST Y          ; acc pc addr card' RDN                   ; card' acc pc addr RDN                   ; addr card' acc pc RTN                   ; acc addr ;------- CLA ---------;------------------ LBL 01                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr X<>Y                  ; acc acc addr pc RCL IND ST Y          ; acc addr pc acc' X<>Y                  ; acc addr acc' pc RTN                   ; acc' pc ;------- ADD ---------;------------------ LBL 02                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr X<> ST Z              ; acc addr pc acc RCL+ IND ST Z         ; acc addr pc acc' X<>Y                  ; acc addr acc' pc RTN                   ; acc' pc ;------- TAC ---------;------------------ LBL 03                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr R↑                    ; acc pc addr acc X<0?                  ; acc pc addr acc GTO 10                ; acc pc addr acc RCL ST Z              ; pc addr acc pc RTN                   ; acc pc LBL 10                ; acc pc addr acc X<>Y                  ; acc pc acc addr RTN                   ; acc addr ;------- SFT ---------;------------------ LBL 04                ; acc pc .addr 10                    ; acc pc .addr 10 ×                     ; acc acc pc left.right ENTER                 ; acc pc left.right left.right IP                    ; acc pc left.right left 10↑X                  ; acc pc left.right 10↑left R↑                    ; pc left.right 10↑left acc ×                     ; pc pc left.right acc' 1E4                   ; pc left.right acc' 10000 ÷                     ; pc pc left.right .acc' LASTX                 ; pc left.right .acc' 10000 X<>Y                  ; pc left.right 1000 .acc' FP                    ; pc left.right 1000 .acc' ×                     ; pc pc left.right acc" X<>Y                  ; pc pc acc" left.right FP                    ; pc pc acc" .right 10                    ; pc acc" .right 10 ×                     ; pc pc acc" right 10↑X                  ; pc pc acc" 10↑right ÷                     ; pc pc pc acc~ IP                    ; pc pc pc acc X<>Y                  ; pc pc acc pc RTN                   ; acc pc ;------- OUT ---------;------------------ LBL 05                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr VIEW IND ST X         ; acc acc pc addr RDN                   ; addr acc acc pc END  RTN                   ; acc pc ;------- STO ---------;------------------ LBL 06                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr X<> ST Z              ; acc addr pc acc STO IND ST Z          ; acc addr pc acc 1E3                   ; addr pc acc 1000 ÷                     ; addr addr pc .acc LASTX                 ; addr pc .acc 1000 X<>Y                  ; addr pc 1000 .acc FP                    ; addr pc 1000 .acc' ×                     ; addr addr pc acc' X<> IND ST Z          ; addr addr pc acc X<>Y                  ; addr addr acc pc RTN                   ; addr pc ;------- SUB ---------;------------------ LBL 07                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr X<> ST Z              ; acc addr pc acc RCL- IND ST Z         ; acc addr pc acc' X<>Y                  ; acc addr acc' pc RTN                   ; acc' pc ;------- JMP ---------;------------------ LBL 08                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr X<>Y                  ; acc acc addr pc 8E2                   ; acc addr pc 800 +                     ; acc acc addr pc' STO 99                ; acc acc addr pc' RDN                   ; pc' acc acc addr RTN                   ; acc addr ;------- HRS ---------;------------------ LBL 09                ; acc pc .addr 1E2                   ; acc pc .addr 100 ×                     ; acc acc pc addr X<>Y                  ; acc acc addr pc RDN                   ; pc acc acc addr SF 00                 ; pc acc acc addr END                   ; acc addr ;---------------------;------------------

Attachment
Code:
Archive:  cardiac.zip   Length      Date    Time    Name ---------  ---------- -----   ----      5504  10-11-2014 22:42   cardiac.txt       210  10-11-2014 22:42   cardiac.raw      2206  10-11-2014 22:43   cardiac.py ---------                     -------      7920                     3 files

Attached File(s)
10-12-2014, 06:15 PM
Post: #2
 Thomas Klemm Senior Member Posts: 1,448 Joined: Dec 2013
RE: (HP-42S) CARDIAC
Greatest Common Divisor

Code:
05              a   DATA 06              b   DATA 07              c   DATA 10  005     load        INP     a 11  006                 INP     b 12  105     start       CLA     a 13  605     loop        STO     b 14  706                 SUB     b 15  317                 TAC     break 16  813                 JMP     loop 17  105     break       CLA     a 18  607                 STO     c 19  700                 SUB     1 20  326                 TAC     exit 21  106                 CLA     b 22  605                 STO     a 23  107                 CLA     c 24  606                 STO     b 25  812                 JMP     start 26  506                 OUT     b 27  910                 HRS     load

What is gcd(408, 360)?

408 STO 05
360 STO 06
12 XEQ 99

The result is:

R06=24

You can copy&paste this deck of cards into the simulator to run this example:

2
800
10
005
11
006
12
105
13
605
14
706
15
317
16
813
17
105
18
607
19
700
20
326
21
106
22
605
23
107
24
606
25
812
26
506
27
910
810
408
360
10-13-2014, 07:30 PM
Post: #3
 Dave Britten Senior Member Posts: 1,223 Joined: Dec 2013
RE: (HP-42S) CARDIAC
Very cool. Kind of reminds me of the Manchester Small-Scale Experimental Machine emulator I wrote on my TI-92 back in high school. It was several orders of magnitude slower than the real thing; I imagine this CARDIAC simulator doesn't have the same problem.
10-13-2014, 09:06 PM
Post: #4
 Thomas Klemm Senior Member Posts: 1,448 Joined: Dec 2013
RE: (HP-42S) CARDIAC
Loading and running the gcd-program above took ~42s while just running it took ~21s.
I used Christoph Giesselink's Emu42 but in my experience its speed is close to the original.

Could you write useful programs with your emulator? Have you been running one of the first programs?
10-13-2014, 09:27 PM
Post: #5
 Dave Britten Senior Member Posts: 1,223 Joined: Dec 2013
RE: (HP-42S) CARDIAC
I don't recall programming anything terribly sophisticated with it. The original machine had only 7 instructions - one of them being stop - and no add instruction, just subtract and a combined load/negate. I was able to run various example programs on it, though, including one that would scroll a simple bitmap graphic across the "display" (very, very slowly, in the case of my emulator).

The TI-92 variety of Basic requires a lot of string handling for the type of indirection I was doing, so I wouldn't be surprised if the 42S could emulate it faster.
10-16-2014, 09:49 PM
Post: #6
 Thomas Klemm Senior Member Posts: 1,448 Joined: Dec 2013
RE: (HP-42S) CARDIAC
Factor

This is a very simple CARDIAC-program to find the factors of a number:
Code:
    03      0   ; DATA     04      2   ; DATA         05      n   ; DATA     06      p   ; DATA     07      m   ; DATA     08      q   ; DATA                      10  005     ; start           INP n     11  104     ;                 CLA 2     12  606     ;                 STO p     13  105     ; trial           CLA n     14  607     ;                 STO m     15  103     ;                 CLA 0     16  608     ;                 STO q     17  107     ; division        CLA m     18  706     ;                 SUB p     19  607     ;                 STO m     20  325     ;                 TAC break     21  108     ;                 CLA q     22  200     ;                 ADD 1     23  608     ;                 STO q     24  817     ;                 JMP division     25  206     ; break           ADD p     26  607     ;                 STO m     27  700     ;                 SUB 1     28  333     ;                 TAC factor     29  106     ;                 CLA p     30  200     ;                 ADD 1     31  606     ;                 STO p     32  813     ;                 JMP trial     33  506     ; factor          OUT p     34  108     ;                 CLA m     35  605     ;                 STO n     36  704     ;                 SUB 2     37  339     ;                 TAC prime     38  813     ;                 JMP trial     39  910     ; prime           HRS start

As long as you don't use self-modifying code it can be translated 1:1 to the HP-42S:
Code:
LBL "FACTOR"    ; start            STO 05          ;                 INP n RCL 04          ;                 CLA 2 STO 06          ;                 STO p LBL 00          ; trial            RCL 05          ;                 CLA n STO 07          ;                 STO m RCL 03          ;                 CLA 0 STO 08          ;                 STO q LBL 01          ; division         RCL 07          ;                 CLA m RCL- 06         ;                 SUB p STO 07          ;                 STO m X<0?            ;                 TAC GTO 02          ;                     break RCL 08          ;                 CLA q RCL+ 00         ;                 ADD 1 STO 08          ;                 STO q GTO 01          ;                 JMP division LBL 02          ; break            RCL+ 06         ;                 ADD p STO 07          ;                 STO m RCL- 00         ;                 SUB 1 X<0?            ;                 TAC GTO 03          ;                     factor RCL 06          ;                 CLA p RCL+ 00         ;                 ADD 1 STO 06          ;                 STO p GTO 00          ;                 JMP trial LBL 03          ; factor                 VIEW 06         ;                 OUT p RCL 08          ;                 CLA m STO 05          ;                 STO n RCL- 04         ;                 SUB 2 X<0?            ;                 TAC GTO 04          ;                     prime GTO 00          ;                 JMP trial LBL 04          ; prime            END             ;                 HRS start`

Just make sure to initialize registers 00, 03 and 04 with 1, 0 and 2:
1 STO 00
0 STO 03
2 STO 04
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)