(42S) CARDIAC - Thomas Klemm - 10-11-2014 08:54 PM
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 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
addr = 35
left = 3
right = 5
Links
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
RE: (HP-42S) CARDIAC - Thomas Klemm - 10-12-2014 06:15 PM
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
Example (after loading the program):
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
RE: (HP-42S) CARDIAC - Dave Britten - 10-13-2014 07:30 PM
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.
RE: (HP-42S) CARDIAC - Thomas Klemm - 10-13-2014 09:06 PM
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?
RE: (HP-42S) CARDIAC - Dave Britten - 10-13-2014 09:27 PM
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.
RE: (HP-42S) CARDIAC - Thomas Klemm - 10-16-2014 09:49 PM
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
|