CARDIAC Simulation using PC/370 - Part 3
CARDIAC Simulation - Part 1 - Introduction to CARDIAC
CARDIAC Simulation - Part 2 - Primary Logic/Architecture
CARDIAC Simulation - Part 3 - Memory Design / Management
CARDIAC Simulation - Part 4 - CARDIAC Instruction Set ProcessingWelcome back! Here's the 3rd part of my CARDIAC Simulation
project (See Part 1 for an Overview). As mentioned in the previous posts CARDIAC is a mini-CPU created by David Hagelbarger at Bell Labs in the 1960's. It's a theoretical piece of hardware made out of cardboard with strategically placed sliders. My daughter's college class based some assignments on it. When she showed it to me I decided to create my own working CARDIAC simulator. The question shouldn't be "Why?" - it should be "Why not?"
CARDIAC Simulator - Memory Design / Management
Above: Constructing my version of the CARDIAC Simulator. The little stick guy is trying to help...
The critical component in creating this simulator is memory design & management. Once this architecture is in place the execution of the individual instructions becomes very easy.
Memory Table - 100 Cells
The MEMTAB contains 100 entries for CARDIAC cells 00 thru 99. The first 4 positions will hold the object code & data values. Due to 24x80 screen restrictions I decided to limit the memory screen display to 3 characters. The second 2-byte position contains the numeric value of the cell (00 thru 99). The third 2-byte packed field holds the calculated displacement for the screen display. The ten's position is multiplied by 7 and the one's position is multiplied by 70. It is calculated once & used throughout the program.
*---------------------------------------------------------------------*
* CARDIAC MEMORY/CELL LOCATIONS *
*---------------------------------------------------------------------*
MEMTAB DC 100XL8'00000000F0F0000F' MEMORY CELLS 00-99
DC X'FF' END OF TABLE
MEM99 DC A(MEMTAB+99*8) CELL 99 ADDRESS FOR JMP
***********************************************************************
Memory Initialization
Memory is initialized at the start of the program and when the <F4> RESET key is pressed. The CODE contained in the input file has already been read & stored in the table CTAB. It is distributed into the proper cells in MEMTAB in the Initialization/Reset process.
***********************************************************************
* INITIALIZE MEMORY AREA *
***********************************************************************
DC F'0' RETURN ADDRESS SAVE AREA
INIT EQU *
ST 6,*-4 SAVE RETURN ADDRESS
*
LA 2,BLANK LOAD SOURCE ADDRESS
LA 3,1 LOAD SOURCE LENGTH
LA 4,MEMTAB LOAD TARGET ADDRESS
LA 5,100*8 LOAD TARGET LENGTH
ICM 3,B'1000',BLANK LOAD PAD CHARACTER
MVCL 4,2 INIT RECORD AREA
*
LA 7,MEMTAB LOAD MEMORY ADDRESS
ZAP CTR,=P'0' INIT CELL COUNTER
ILOOP0 EQU *
CLI 0(7),X'FF' END OF TABLE???
BE ILOOP0X YES - EXIT LOOP
*
OI CTR+1,X'0F' TURN ON SIGN BITS
UNPK 4(2,7),CTR UNPACK COUNTER
*
PACK WTENS,4(1,7) PACK TEN'S PLACE
PACK WONES,5(1,7) PACK ONE'S PLACE
MP WTENS,=PL2'7' ADJUST COL BY 7
MP WONES,=PL2'70' ADJUST ROW BY 70
ZAP WDISP,=P'0' INIT DISPLACEMENT
AP WDISP,WONES ADD ROW ADJUSTMENT
AP WDISP,WTENS ADD COL ADJUSTMENT
MVC 6(2,7),WDISP+2 SAVE DISPLACEMENT
INITBC BC 0,INITGO
MVC OPRT,OBLANK CLEAR OUTPUT RECORD
MVC OPRT(7),=CL7'*MEMX*' MOVE TRACE ID
MVC OPRT+7(2),4(7) MOVE CELL NUMBER
MVC OPRT+11(4),0(7) MOVE CELL CONTENTS
UNPK OPRT+17(3),6(2,7) MOVE DISPLACEMENT
OI OPRT+19,X'F0' TURN ON ZONE BITS
XPRNT OREC,132 WRITE OUTPUT RECORD
INITGO EQU *
LA 7,8(,7) BUMP MEM POINTER
AP CTR,=P'1' ADD TO CELL COUNT
B ILOOP0 LOOP AGAIN PLEASE
ILOOP0X EQU *
LA 8,CTAB LOAD CODE ADDRESS
ILOOP1 EQU *
CLI 0(8),X'FF' END OF CODE???
BE ILOOP1X YES - EXIT LOOP
*
LA 7,MEMTAB LOAD MEMORY ADDRESS
PACK DUBB,0(2,8) PACK CELL NUMBER
CVB 3,DUBB CONVERT TO BINARY
MH 3,=H'8' MULTIPLY BY LENGTH
AR 7,3 ADJUST MEMORY PTR
MVC 0(4,7),=CL4' ' CLEAR CELL CONTENTS
MVC 0(3,7),2(8) MOVE CODE TO MEMORY
*
LA 8,5(,8) BUMP CODE POINTER
B ILOOP1 TEST NEXT ENTRY
ILOOP1X EQU *
ZAP XACC,=P'0' ACCUMULATOR PACKED
MVC XACCU,=CL4'0000' ACCUMULATOR UNPACKED
ZAP ZPC,=P'-1' PROGRAM COUNTER PREVIOUS
ZAP XPC,=P'10' PROGRAM COUNTER PACKED
MVC XPCU,=CL3'010' PROGRAM COUNTER UNPACKED
MVC XIR,=CL3' ' INSTRUCTION REGISTER
MVC XMNE,=CL3' ' OPERATION MNEMONIC
*
MVC DPTR,=A(DTAB) RESET DECK POINTER
MVI SCRRDR,C' ' MOVE BLANK TO SCRRDR
MVC SCRRDR+1(L'SCRRDR-1),SCRRDR PROPAGATE BLANKS
MVI SCROUT,C' ' MOVE BLANK TO SCROUT
MVC SCROUT+1(L'SCROUT-1),SCROUT PROPAGATE BLANKS
*
OI INITBC+1,X'F0' DEACTIVATE TRACE OUTPUT
INITX EQU *
L 6,INIT-4 RESTORE LINK REGISTER
BR 6 BRANCH ON LINK REGISTER
***********************************************************************
As the program progresses via the <F1> STEP key the memory values may change along with the Program Counter that tracks the executable lines. An asterisk (*) is displayed on the screen to track the current instruction. The MEMTAB values are copied to the screen location using the pre-calculated displacements. The standard SCREEN build routine is then called at the top of the main processing loop.
***********************************************************************
* MEMORY TO SCREEN *
***********************************************************************
DC F'0' RETURN ADDRESS SAVE AREA
MEMSCR EQU *
ST 6,*-4 SAVE RETURN ADDRESS
*
LA 6,100 LOAD CELL COUNT
LA 7,MEMTAB LOAD MEMORY ADDRESS
MEMLOOP EQU *
LA 5,SCRMEM0+2 LOAD SCREEN ADDRESS
ZAP DUBB,6(2,7) LOAD DISPLACEMENT
CVB 4,DUBB CONVERT TO BINARY
AR 5,4 ADD DISPLACEMENT
*
CLI 0(7),C' ' MEMORY CELL BLANK???
BNE MEMBC NO - CONTINUE PLEASE
MVC 0(4,5),=CL4'____' CLEAR MEMORY AREA
B MEMBUMP BUMP CELL POINTER
MEMBC BC 0,MEMFILL
MVC OPRT,OBLANK CLEAR OUTPUT RECORD
MVC OPRT(7),=CL7'*MEM#*' MOVE TRACE ID
MVC OPRT+7(2),4(7) MOVE CELL NUMBER
MVC OPRT+11(4),0(7) MOVE CELL CONTENTS
UNPK OPRT+17(3),6(2,7) MOVE DISPLACEMENT
OI OPRT+19,X'F0' TURN ON ZONE BITS
XPRNT OREC,132 WRITE OUTPUT RECORD
MEMFILL EQU *
MVC 0(4,5),=CL4' ' CLEAR MEMORY AREA
MVC 0(3,5),0(7) MOVE CODE TO MEMORY
CLC XPCU+1(2),4(7) PROGRAM COUNTER??
BNE MEMBUMP NO - CONTINUE PLEASE
MVI 3(5),C'*' YES - FLAG CELL
MEMBUMP EQU *
LA 7,8(,7) BUMP MEMORY ADDRESS
BCT 6,MEMLOOP LOOP UNTIL COMPLETE
*
MVC SCRVAR+4(3),XPCU MOVE PROGRAM COUNTER
MVC SCRVAR+14(4),XACCU MOVE ACCUMULATOR
MVC SCRVAR+24(3),XIR MOVE INSTRUCT REGISTER
MVC SCRVAR+37(3),XMNE MOVE INSTRUCT MNEMONIC
MVC SCRVAR+52(2),XOPER MOVE INSTRUCT OPERANDS
*
OI MEMBC+1,X'F0' DEACTIVATE TRACE OUTPUT
MEMSCRX EQU *
L 6,MEMSCR-4 RESTORE LINK REGISTER
BR 6 BRANCH ON LINK REGISTER
***********************************************************************
CODE/DATA Loaded from Input File TDCPU.TXT
All Code & Data is contained in the file TDCPU.TXT (as opposed to entering it cell by cell like the college's online simulator). The Code & Deck entries are held in the tables CTAB & DTAB respectively. CTAB is utilized by the Memory Initialization routine while DTAB is the data source behind the INP (Read Input) CARDIAC Instruction.
***********************************************************************
* DATA LOAD - CARDIAC CODE & DECK *
***********************************************************************
DC F'0' RETURN ADDRESS SAVE AREA
DATA EQU *
ST 6,*-4 SAVE RETURN ADDRESS
*
XFILI STDWKI OPEN INPUT FILE
*
LA 8,CTAB LOAD CODE ADDRESS
LA 9,DTAB LOAD DECK ADDRESS
GETI EQU *
XREAD IREC,80 READ INPUT RECORD
BNZ EOFI EOF - EXIT ROUTINE
*
CLC IREC(5),=C'CODE:' DATA = CODE???
BNE *+12 NO - CHECK DECK
BAL 6,ICODE YES - PROCESS CODE
B GETI READ NEXT RECORD
*
CLC IREC(5),=C'DECK:' DATA = DECK???
BNE GETI NO - READ AGAIN
BAL 6,IDECK YES - PROCESS DECK
B GETI READ NEXT RECORD
EOFI EQU *
MVI 0(8),X'FF' END OF CODE TABLE
MVI 0(9),X'FF' END OF DECK TABLE
DATAX EQU *
L 6,DATA-4 RESTORE LINK REGISTER
BR 6 BRANCH ON LINK REGISTER
***********************************************************************
EJECT
***********************************************************************
* INPUT CODE - CARDIAC OBJECT CODE R8=CTAB (CL2+CL3) *
***********************************************************************
DC F'0' RETURN ADDRESS SAVE AREA
ICODE EQU *
ST 6,*-4 SAVE RETURN ADDRESS
*
MVC 0(2,8),IREC+5 MOVE CELL NUMBER
MVC 2(3,8),IREC+8 MOVE INSTRUCTION
*
MVC OPRT,OBLANK CLEAR OUTPUT RECORD
MVC OPRT(7),=CL7'*CODE*' MOVE TRACE ID
MVC OPRT+7(2),0(8) MOVE CELL NUMBER
MVC OPRT+10(3),2(8) MOVE INSTRUCTION
MVC OPRT+20(40),IREC MOVE INPUT RECORD
XPRNT OREC,132 WRITE OUTPUT RECORD
*
LA 8,5(,8) BUMP TABLE POINTER
ICODEX EQU *
L 6,ICODE-4 RESTORE LINK REGISTER
BR 6 BRANCH ON LINK REGISTER
***********************************************************************
EJECT
***********************************************************************
* INPUT DECK - CARDIAC READER DATA R9=DTAB (CL4+PL2) *
***********************************************************************
DC F'0' RETURN ADDRESS SAVE AREA
IDECK EQU *
ST 6,*-4 SAVE RETURN ADDRESS
*
MVC 0(3,9),IREC+5 MOVE DECK VALUE
CLI IREC+5,C'-' NEGATIVE VALUE?
BNE *+8 NO - CONTINUE
MVI IREC+5,C'0' SET SIGN TO ZERO
*
PACK 4(2,9),IREC+5(3) PACK DECK VALUE
*
OI 5(9),X'0F' SET POSITIVE SIGN
CLI 0(9),C'-' NEGATIVE VALUE?
BNE *+12 NO - CONTINUE PLEASE
NI 5(9),X'F0' TURN OFF SIGN BITS
OI 5(9),X'0D' SET NEGATIVE SIGN
*
MVC OPRT,OBLANK CLEAR OUTPUT RECORD
MVC OPRT(7),=CL7'*DECK*' MOVE TRACE ID
MVC OPRT+7(4),0(9) MOVE CELL NUMBER
MVC OPRT+20(40),IREC MOVE INPUT RECORD
XPRNT OREC,132 WRITE OUTPUT RECORD
*
LA 9,6(,9) BUMP TABLE POINTER
IDECKX EQU *
L 6,IDECK-4 RESTORE LINK REGISTER
BR 6 BRANCH ON LINK REGISTER
***********************************************************************
The next post will cover the CARDIAC Instruction Set. That's where the magic happens...