Sunday, November 8, 2020

 CARDIAC Simulation using PC/370 - Part 2

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 Processing 

Welcome back to the 2nd part of my CARDIAC Simulation project (See Part 1 for an Overview). In short CARDIAC represents a mini-CPU with it's own Assembly Language Instruction Set, corresponding Machine Code & active logic flow. It can perform basic functions such as reading input, adding/subtracting, branching & more. My daughter's college computer class used this to demonstrate CPU functionality. It looked pretty cool. I told her I was going to create my own version of the simulator - just for fun of course.

Once again I'm compelled to add a small disclaimer. This exercise was purely for enjoyment within a very limited time frame. It is not an Assembler "purity" test where everyone's individual concept of "purity" should be adhered to. It is strictly a PC/370 version using DOS Interrupts that emulate 370 SVC Calls. There's a multitude of ways & methods to do this... I chose this way. It's slick, elegant, very solid & developed very rapidly.

Time to Design & Build the CARDIAC Simulator

Above: Constructing the CARDIAC Simulator. Spoiler Alert - It works perfectly!

Since the program is mimicking a mini-CPU I decided to call the program TDCPU.ALC - short & sweet.

Designing the Screen Layout - 24x80

My first step was sketching out a screen design suitable for PC/370. It needs to fit nicely within the 24x80 text screen limitation while being aesthetically pleasing with a reasonable resemblance to the online GUI version of the simulator. Unlike GUI development I have to maintain every aspect of the display including calculating cell position to drop data & code into.

  |....5...10...15...20...25...30...35...40...45...50...55...60...65...70...75...80|
==|================================================================================|
01|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|
02|x                                                                              x|
03|x  CARDIAC CPU SIMULATION          <F1>=STEP      <F4>=RESET      <ESC>=EXIT   x|
04|x                                                                              x|
05|x      00     10     20     30     40     50     60     70     80     90       x|
06|x      ====   ====   ====   ====   ====   ====   ====   ====   ====   ====     x|
07|x    0:____ 0:____ 0:____ 0:____ 0:____ 0:____ 0:____ 0:____ 0:____ 0:____     x|
08|x    1:____ 1:____ 1:____ 1:____ 1:____ 1:____ 1:____ 1:____ 1:____ 1:____     x|
09|x    2:____ 2:____ 2:____ 2:____ 2:____ 2:____ 2:____ 2:____ 2:____ 2:____     x|
00|x    3:____ 3:____ 3:____ 3:____ 3:____ 3:____ 3:____ 3:____ 3:____ 3:____     x|
11|x    4:____ 4:____ 4:____ 4:____ 4:____ 4:____ 4:____ 4:____ 4:____ 4:____     x|
12|x    5:____ 5:____ 5:____ 5:____ 5:____ 5:____ 5:____ 5:____ 5:____ 5:____     x|
13|x    6:____ 6:____ 6:____ 6:____ 6:____ 6:____ 6:____ 6:____ 6:____ 6:____     x|
14|x    7:____ 7:____ 7:____ 7:____ 7:____ 7:____ 7:____ 7:____ 7:____ 7:____     x|
15|x    8:____ 8:____ 8:____ 8:____ 8:____ 8:____ 8:____ 8:____ 8:____ 8:____     x|
16|x    9:____ 9:____ 9:____ 9:____ 9:____ 9:____ 9:____ 9:____ 9:____ 9:____     x|
17|x                                                                              x|
18|x           PC: ___  ACC: ____  IR: ___  OPCODE: ____  OPERAND: ___            x|
19|x                                                                              x|
20|x  READER:  xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,***    x|
21|x                                                                              x|
22|x  OUTPUT:  xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx,xxxx   x|
23|x                                                                              x|
24|xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx|

I was happy with the screen design... just enough room to maneuver without looking too crammed.

Input File - CODE & DATA DECK - TDCPU.TXT

The online CARDIAC simulator requires the user to type in the 3 digit code/values on the web page. Each time you return to the page it must be refreshed - that's a lot of tedious redundant typing. I decided to create an input file containing the full source & object code as well as the data values to be used. This way multiple CARDIAC programs can be maintained & tested.

****:PC OOO LLLLLLLL MNE   OOOOOOOO       XXXXXXXXXXXXXXXXXXXXXXXXXXXX
CODE:00 001          DATA  001            ;Initialize Cell 00
CODE:04 000 ctr      DATA  000            ;Initialize Counter
CODE:05 000 sum      DATA  000            ;Initialize Sum
CODE:06 001 one      DATA  001            ;Set Static Variable 1
CODE:07 000 num      DATA  000            ;Initialize Input Number
*
CODE:10 007 loop     INP   num            ;Read/Store Input Value
CODE:11 107          CLA   num            ;Load Accumulator with Value
CODE:12 315          TAC   print          ;Exit Loop when Negative
CODE:13 861          JMP   xproc          ;Perform xproc Subroutine
CODE:14 810          JMP   loop           ;Loop for next Input Value
CODE:15 504 print    OUT   ctr            ;Display Record Count
CODE:16 505          OUT   sum            ;Display Sum Total
CODE:17 900          HRS   00             ;Halt/Reset Program (DONE)
*
CODE:60 000 xsave    DATA  000            ;Accumulator Save Area
CODE:61 660 xproc    STO   xsave          ;Store Accumulator Value
CODE:62 199          CLA   ret99          ;Retrieve Return Address
CODE:63 671          STO   xexit          ;Push Return to Exit
CODE:64 105          CLA   sum            ;Load Accumulator with Sum
CODE:65 207          ADD   num            ;Add Input Value
CODE:66 605          STO   sum            ;Store Accumulator to Sum
CODE:67 104          CLA   ctr            ;Load Accumulator with Count
CODE:68 206          ADD   one            ;Add 1 to Accumulator
CODE:69 604          STO   ctr            ;Store Accumulator to Ctr
CODE:70 160          CLA   xsave          ;Restore Accumulator Value
CODE:71 800 xexit    JMP   00             ;Return to Main Process
*
CODE:99 800 ret99    DATA  800            ;Return Address Area (JMP)
*
****:+NN
DECK:001
DECK:002
DECK:004
DECK:008
DECK:-01

Mainline Processing Logic

The first step of the TDCPU program is to read the input data file (TDCPU.TXT) containing the source/object code and any input data values (if necessary). The Code & data is then stored in the tables CTAB & DTAB. These tables are used to initially populate the Memory Cells and when the <F4> RESET function is pressed. The Main Loop writes the current Memory State to the Screen Variables which are then displayed. The <F1> STEP key will then step through the code associated with the Program Counter - with each opcode branching to the appropriate function. Once the Halt/Reset instruction is executed the <F1> STEP key is inactivated - only <ESC> EXIT & <F4> RESET are permitted. <F4> will reset the program counter, re-initialize memory & re-activate the <F1> STEP key.

***********************************************************************
*        MAINLINE PROCEDURE                                           *
***********************************************************************
         PRINT NOGEN
         SVC   @TRACE                        ISSUE SUPERVISOR CALL
         DC    CL4'IOF '                     KEYBOARD INTERRUPT OFF
*
         XFILO STDWKO                        OPEN OUTPUT FILE
*
         BAL   6,DATA                        LOAD CODE/DECK DATA
RESET    EQU   *
         BAL   6,INIT                        INITIALIZE MEMORY
LOOP     EQU   *
         BAL   6,MEMSCR                      WRITE MEMORY TO SCREEN
         BAL   6,SCREEN                      BUILD SCREEN
*
         CLI   KEY,@K#ESC                    KEY = ESCAPE ???
         BE    LOOPX                         YES - EXIT PLEASE
         CLI   KEY,@K#F4                     KEY = <F4> ???
         BE    RESET                         YES - RESET CARDIAC
*
         CP    XPC,=P'0'                     HALT EXECUTED?
         BE    LOOP                          YES - ONLY RESET/EXIT
*
         CLI   KEY,@K#F1                     KEY = <F1> ???
         BNE   LOOP                          NO  - DISPLAY SCREEN
*
         LA    7,MEMTAB                      LOAD MEMORY ADDRESS
         ZAP   DUBB,XPC                      MOVE PROGRAM COUNTER
         CVB   3,DUBB                        CONVERT TO BINARY
         MH    3,=H'8'                       MULTIPLY BY LENGTH
         AR    7,3                           ADJUST MEMORY PTR
*
         MVC   XIR,0(7)                      SET INSTRUCT REGISTER
         LA    8,OPTAB                       LOAD OPERATION TABLE
IRLOOP   EQU   *
         CLI   0(8),X'FF'                    END OF TABLE???
         BE    LOOP                          YES - INVALID OPCODE
         CLC   0(1,8),XIR                    OPCODE MATCH???
         BE    IRFOUND                       YES - EXIT OPCODE LOOP
         LA    8,8(,8)                       BUMP OPCODE POINTER
         B     IRLOOP                        TEST NEXT OPCODE
IRFOUND  EQU   *
         MVC   XMNE,1(8)                     MOVE INSTRUCTION MNEMONIC
         ZAP   ZPC,XPC                       SAVE PRIOR INSTRUCTION
         AP    XPC,=P'1'                     BUMP PROGRAM COUNTER
         UNPK  XPCU,XPC                      UNPACK PROGRAM COUNTER
         OI    XPCU+2,X'F0'                  TURN ON ZONE BITS
         L     5,4(8)                        LOAD INSTRUCTION ADDRESS
         BALR  6,5                           PERFORM INSTRUCTION
         B     LOOP                          DISPLAY SCREEN AGAIN
LOOPX    EQU   *
         B     RETURN                        EXIT PROGRAM PLEASE
***********************************************************************
 

Build Screen Routine

I developed a generic Screen Display routine that utilizes a WTO Supervisor call that is mapped to Windows PC-Based DOS Interrupts. The table SCTAB contains all the variables that displayed on the page. My algorithm & supporting custom copybooks allow very quick development - even in complex scenarios. The <F1>, <F4><ESC> keys break out of the routine and returns to the main loop.

***********************************************************************
*        BUILD SCREEN                                                 *
***********************************************************************
         DC    F'0'                          RETURN ADDRESS SAVE AREA
SCREEN   EQU   *
         ST    6,*-4                         SAVE RETURN ADDRESS
*
         MVI   VBITS,@BKWT                   SET BG(BLACK)/FG(WHITE)
         BAL   6,VRESET                      CHANGE SCREEN ATTRIBUTES
*
*        DISPLAY SINGLE BOX
*
         MVC   VBX,VBOX2                     LOAD BOX FRAME
         MVC   VBXRC,BXTAB                   LOAD BOX COORDINATES
         BAL   6,VBOX                        DISPLAY BOX FRAME
*
*        DISPLAY SCREEN TEXT
*
         LA    5,SCTAB                       LOAD TABLE ADDRESS
SC1LP    EQU   *
         CLI   0(5),X'FF'                    END OF TABLE ???
         BE    SC1LPX                        YES - EXIT LOOP PLEASE
*
         MVC   VXYS,0(5)                     MOVE CURSOR POSITION
         BAL   6,VXYSET                      SET CURSOR POSITION
         L     2,4(5)                        LOAD MESSAGE ADDRESS
         SVC   @WTO                          ISSUE SUPERVISOR CALL
*
         LA    5,8(,5)                       BUMP TABLE POINTER
         B     SC1LP                         TEST NEXT TABLE ENTRY
SC1LPX   EQU   *
*
*        ACCEPT KEYSTROKE
*
         BAL   6,KBGET                       READ KEYBOARD INPUT
         MVC   KEY,KBCHR                     STORE KEYSTROKE
*
         CLI   KEY,@K#ESC                    KEY = ESCAPE ???
         BE    SC2LPX                        YES - EXIT ROUTINE
         CLI   KEY,@K#F1                     KEY = F1 ???
         BE    SC2LPX                        YES - EXIT ROUTINE
         CLI   KEY,@K#F4                     KEY = F4 ???
         BE    SC2LPX                        YES - EXIT ROUTINE
*
         B     SC1LPX                        BACK TO KEYBOARD
SC2LPX   EQU   *
         MVI   VBITS,@BKWT                   SET BG(BLACK)/FG(WHITE)
         BAL   6,VRESET                      CHANGE SCREEN ATTRIBUTES
SCREENX  EQU   *
         L     6,SCREEN-4                    RESTORE LINK REGISTER
         BR    6                             BRANCH ON LINK REGISTER
***********************************************************************
 

Screen Definition

Below are the primary definitions for the SCREEN Build Routine. Screen variable addresses & their X-Y coordinates are listed in SCTAB. The SCRMEM0 thru SCRMEM9 lines will contain the 100 CARDIAC Memory Cell values. Other display fields include CARDIAC internal registers, instructions, deck reader queue & print output.

***********************************************************************
*        BOX COMPONENTS (COORDINATES/FRAME)                           *
***********************************************************************
BXTAB    DS    0F
         DC    AL1(0,0,23,79)                BOX COORDINATES/FRAME
***********************************************************************
*        SCREEN DISPLAY COMPONENTS                                    *
***********************************************************************
SCTAB    DS    0F
         DC    AL1(0,0,2,3),A(SCRHDR)        SCREEN COORDINATES/MSG
         DC    AL1(0,0,4,7),A(SCRTTL)        SCREEN COORDINATES/MSG
         DC    AL1(0,0,5,7),A(SCRDASH)       SCREEN COORDINATES/MSG
         DC    AL1(0,0,6,5),A(SCRMEM0)       SCREEN COORDINATES/MSG
         DC    AL1(0,0,7,5),A(SCRMEM1)       SCREEN COORDINATES/MSG
         DC    AL1(0,0,8,5),A(SCRMEM2)       SCREEN COORDINATES/MSG
         DC    AL1(0,0,9,5),A(SCRMEM3)       SCREEN COORDINATES/MSG
         DC    AL1(0,0,10,5),A(SCRMEM4)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,11,5),A(SCRMEM5)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,12,5),A(SCRMEM6)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,13,5),A(SCRMEM7)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,14,5),A(SCRMEM8)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,15,5),A(SCRMEM9)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,17,12),A(SCRVAR)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,19,3),A(SCRRDRT)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,19,11),A(SCRRDR)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,21,3),A(SCROUTT)      SCREEN COORDINATES/MSG
         DC    AL1(0,0,21,11),A(SCROUT)      SCREEN COORDINATES/MSG
         DC    XL1'FF'                       END OF TABLE
***********************************************************************
SCRHDR   DC    C'CARDIAC CPU SIMULATION          <F1>=STEP'
         DC    C'      <F4>=RESET      <ESC>=EXIT',C'$'
SCRTTL   DC    C'00     10     20     30     40     '
         DC    C'50     60     70     80     90',C'$'
SCRDASH  DC    C'====   ====   ====   ====   ====   '
         DC    C'====   ====   ====   ====   ====',C'$'
SCRMEM0  DC    C'0:____ 0:____ 0:____ 0:____ 0:____ '
         DC    C'0:____ 0:____ 0:____ 0:____ 0:____',C'$'
SCRMEM1  DC    C'1:____ 1:____ 1:____ 1:____ 1:____ '
         DC    C'1:____ 1:____ 1:____ 1:____ 1:____',C'$'
SCRMEM2  DC    C'2:____ 2:____ 2:____ 2:____ 2:____ '
         DC    C'2:____ 2:____ 2:____ 2:____ 2:____',C'$'
SCRMEM3  DC    C'3:____ 3:____ 3:____ 3:____ 3:____ '
         DC    C'3:____ 3:____ 3:____ 3:____ 3:____',C'$'
SCRMEM4  DC    C'4:____ 4:____ 4:____ 4:____ 4:____ '
         DC    C'4:____ 4:____ 4:____ 4:____ 4:____',C'$'
SCRMEM5  DC    C'5:____ 5:____ 5:____ 5:____ 5:____ '
         DC    C'5:____ 5:____ 5:____ 5:____ 5:____',C'$'
SCRMEM6  DC    C'6:____ 6:____ 6:____ 6:____ 6:____ '
         DC    C'6:____ 6:____ 6:____ 6:____ 6:____',C'$'
SCRMEM7  DC    C'7:____ 7:____ 7:____ 7:____ 7:____ '
         DC    C'7:____ 7:____ 7:____ 7:____ 7:____',C'$'
SCRMEM8  DC    C'8:____ 8:____ 8:____ 8:____ 8:____ '
         DC    C'8:____ 8:____ 8:____ 8:____ 8:____',C'$'
SCRMEM9  DC    C'9:____ 9:____ 9:____ 9:____ 9:____ '
         DC    C'9:____ 9:____ 9:____ 9:____ 9:____',C'$'
SCRVAR   DC    C'PC: __   ACC: ____  IR: ___  '
         DC    C'OPCODE: ___   OPERAND: __ ',C'$'
SCRRDRT  DC    CL7'READER:',C'$'
SCRRDR   DC    CL66' ',C'$'
SCROUTT  DC    CL7'OUTPUT:',C'$'
SCROUT   DC    CL66' ',C'$'
***********************************************************************

This is primarily supporting architecture for the PC/370 CARDIAC Simulator. The trickiest part of the entire process was aligning the cell values with the proper position on the screen. Using the variables SCRMEM0 thru SCRMEM9 as a single table each ten's position has a horizontal offset multiplier of 7 while the one's position has a vertical offset of 70. For example, cell 73 would be in position 7*7 + 3*70 = 259. That would be 8th column (heading=70) residing on the 4th line (SCRMEM3). 

More to come... much more...