From dc6d05e9f59fae91e6428a8c4bde4411b98a4977 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Fri, 18 Dec 2020 03:56:15 -0800 Subject: [PATCH] S3: Removed legacy version of IBM System 3 not maintained by Bob Supnik --- S3/haltguide.txt | 950 ---------------- S3/readme_s3.txt | 78 -- S3/s3_cd.c | 448 -------- S3/s3_cpu.c | 1830 ------------------------------ S3/s3_defs.h | 94 -- S3/s3_disk.c | 792 ------------- S3/s3_lp.c | 364 ------ S3/s3_pkb.c | 313 ----- S3/s3_sys.c | 950 ---------------- S3/system3.txt | 472 -------- Visual Studio Projects/S3.vcproj | 296 ----- Visual Studio Projects/Simh.sln | 6 - 12 files changed, 6593 deletions(-) delete mode 100644 S3/haltguide.txt delete mode 100644 S3/readme_s3.txt delete mode 100644 S3/s3_cd.c delete mode 100644 S3/s3_cpu.c delete mode 100644 S3/s3_defs.h delete mode 100644 S3/s3_disk.c delete mode 100644 S3/s3_lp.c delete mode 100644 S3/s3_pkb.c delete mode 100644 S3/s3_sys.c delete mode 100644 S3/system3.txt delete mode 100644 Visual Studio Projects/S3.vcproj diff --git a/S3/haltguide.txt b/S3/haltguide.txt deleted file mode 100644 index 24e90f86..00000000 --- a/S3/haltguide.txt +++ /dev/null @@ -1,950 +0,0 @@ - IBM System/3 Model 8/10 SCP - - ********** - Halt Guide - ********** - -This following list is my own reformatting and rewording of the -official IBM Halt Guide for the Model 8/10 SCP. - -The halts are those displayed on the message display unit. The -list is in alphabetical order for easy reference. - -When the system halts, the two 7-segment displays will display the -halt as listed here, and the system console (or printer if the log -device is the printer) will print the "SCP Message" below. To -respond to the halt, deposit one of the valid response numbers -(0 thru 3) into the SR, and then use the C command to continue. - -Unless otherwise stated, a response of 0 means to continue and accept -the error, 1 means to retry the operation or re-read the statement in -error, 2 means to cancel the job and retain added records (if any) and -3 means to end the job and discard any added records in files. - -This is a listing of those halts likely to be encountered using SCP on -the simuator, it is not the complete list of all possible halts. - -Halt SCP Message Description ----- ----------- ----------- - -00 Invalid response to another halt. Deposit a valid - value (0 thru 3) in SR. - -0A A 5448 Disk Unit not ready. - -0C 5448 Disk Equipment Check - -0E Permanent disk error during logging. - -0F ID0FXX 23 Invalid cylinder number on disk operation. - XX = Disk Drive. - -0H ID0HXX 23 Invalid sector number on disk operation - XX = Disk Drive. - -0Y IK0Y0X 123 3741 Error. X: 1=not ready 2=wrong mode - 3=parity error 5=record length error - -0 ID0 XX 23 Disk Data Check - XX = Disk Drive. - -0- ID0-XX Invalid disk operation code: Start cancels job. - XX = Disk Drive. - -10 3 No input file allocate, user error. - -11 0 23 Square root of a negative field - -12 0 23 Divide Overflow - -13 0 23 Divide by zero - -14 0 23 Varible index zero of out of range - -15 0 23 Sequenced table is out of sequence - -16 0 23 (RPG) OBject tables expected. /* Read. - -17 0 23 (RPG) Object table exceeds specified length - -18 0 23 (RPG) Terminal errors in source program. - -19 0 3 (RPG) Warning errors in source program. 0=continue. - -1A 3 (RPG) Out of core memory - -1C 23 Unidentified halt has been issued. Probable system - error. - -1E 0 3 (RPG) Demand file at end of file. - -1F 23 (RPG) End of file or end of extent. If during RPG - compilation, expand $SOURCE or $WORK. - -1H 0 23 Duplicate keys found during build of indexed file. - 0=skip this record and continue. - -1J 0 23 Out of sequence keys during build of indexed file. - 0=skip this record and continue. - -1L 0 23 Key changed during record update. User error. - 0=continue, do not update record. - -1P 01 Forms in printer need positioning. - -1U 123 No record found on direct or indexed file. - -1Y 0 23 (RPG) Invalid numeric data to DSPLY statement. - -1 0 3 Object program ready to punch tables. - -20 1 3 Disk Sort: Invalid header and no // SOURCE - -21 01 3 Disk Sort: Name on // SOURCE not found - -22 0 2 Disk Sort: Warning errors found. - -23 3 Disk Sort: Unrecoverable error. - -25 3 Disk Sort: Terminal errors in sort statements. - -27 0 Disk Sort: In debug mode, finished pass. - -2C 0 3 Disk Sort: No Input Records selected. - -2E 3 Disk Sort: Workfile too small. - -2F 23 Disk Sort: Output file too small. - -2L DT2LY2 3 Tape Record too large to process. - DT2LY7 3 No FILE statement for tape file open. - DT2LY9 3 No enough storage for tape operation - DT2LTC 3 Invalid tape header length - DT2LYF 123 Incorrect block length read from tape - -2P Permanent tape error. - -2U 12 Tape unit is write protected. - -2Y 3 Invalid device specification in object. - -2- 0 3 First statement was not a Tape Sort header. - -30 EG30 3 Space not available on R1 or F1. - UB30A1 0 3 Active files exist on output disk - UB30AF 0 3 Active files exist on 5448 disk - UB30H1 0 3 Wrong capacity or uninitialized pack - UB30NS 3 No 5448 disk for $PCOPY - UB30TP 0 3 Pack change required. - UC30AF 3 Active or system files on target - UC30BD 3 Volume label cannot be read - UC30SP 3 Not enough space for work file - UP30AF 3 Active or system files on target - -31 UI31AF 0 3 Active or system files on target - 0=proceed to next unit to initialize - UI30WP 01 3 Wrong pack, name does not match. - -32 UB32Bx 01 3 5444 pack is not a $PCOPY backup pack. - UB32NP 01 3 Unit specified is not a $PCOPY pack. - UC32BD 3 FROM pack is a TO pack from an interrupted - COPYPACK run. - UC32BP 3 Output pack is a $PCOPY output pack. - Must be initialized or reset by a RESET - statement to be used. - UC32DS 3 Packs FROM and TO are different sizes. - -33 UI33PU 0 3 Pack defective, cannot be initialized. - -34 Ux34 1 3 Keyword in a utility control statement is invalid. - -35 UC35xx 1 3 Error in $COPY or $KCOPY control statement. - -36 UI36CE 0 3 CE track defective on unit F1. - -37 UC37xx 0 3 Pack change required. xx: FP=mount on R1, - IP=pack on COPYIN, OP=pack on COPYO. - -38 UA38XX 0 3 Wrong pack mounted. - UB38DA 01 3 Dates do not match. - UB38DM 01 3 2nd 5444 pack not from same backup set as 1st. - UB38IP 01 3 PACKIN keyword pack not same as pack mounted. - UB38OP 01 3 PACKO keyword not same as pack mounted. - -3A UC3Axx 3 Key out of sequence (DP), invalid high key (HK), - out of space to copy file (XE), or disk I/O error. - -3C UC3CCS 3 COPYFILE out of core. - UC3CNF 3 Module not found, name is logged as R XXXXXX. - -3E UC3EOX 0 3 COPYFILE output not as big as size of input. - -3F UC3Fxx 1 3 Error in COPYFILE statement. - -3J UC3Fxx 3 Invalid specification for Copy/Dump. - -3P UC3Pxx 1 3 Error in COPYPACK, RESET, or LABELS statement. - -3Y UI3YIS 0 3 Requested secondary init when primary required. - -3 UI3 xx 1 3 Error in VOL statement. - -40 DD40 3 File has been referenced as an output or add file - and the file is already allocated. - -4A DD4A 3 File had already been opened and is re-opened. - -4C DD4C 3 Multivolumne file spec error. - -4E DD4E 3 FILE indicates a multivolule file being built, - but program compiled for single volume. - -4F DD4F 3 Print buffers not aligned in program. - -4H DD4H 0 3 Unordered load specified for ISAM. Ordered load - must be specified on RPG file specs. - -4J DD4J 3 All file specs have been checked and there were - errors. - -4L DD4L 3 Referenced file already allocated. - -4P DD4P 3 Prgram/FILE statement mismatch. - -4U DD4U 3 File referenced as update, already allocated. - -4Y DD4Y 3 File has an incorrect device specification. - -4 DD4 3 No FILE specification for referenced file. - -4' DD4' 3 Attempting reference to a file in 2 levels, one or - both using RETAIN-S. - -50 UA50ID 2 Bad track which can't be reassigned. - -51 UR51 12 Can't use Alternate Track program in procedure. - -52 ML52 12 EOJ for Card List program. - -53 IU53 1 3 Number of VOL statements does not agree with number - of units on UIN statement. - -54 EO54 3 End-of-file. - -55 UF55xx 1 3 Error in SCRATCH or REMOVE statement. - -56 UA56TS 0 3 ASSIGN track is over disk capacity. - UA56XX 0 3 Unit specified is uninitialized. - -57 UF57WP 01 3 File delete program. Wrong pack is mounted. - 0: Mount correct pack and continue. 1: - correct statement and retry. - -5A UA5Axx 012 Alternate track assignment error. - -5C MR5Cxx 1 3 Invalid reformat specs. - -5F UF5Fxx 1 3 Error in DISPLAY statement. - -5H UA5HEU 0123 Primary track is still defective. - -5L UF5LAF 0 3 PRogram try to delete files that are being used by - another program. - UF5LNF 0 3 File not found. - UF5LTM 23 Too many files specified. Max is 40. - -5U UI5Uxx 1 3 Error in UIN statement. - -5Y UR5Yxx 1 3 Error in REBUILD statment. - -5 UA5 xx 1 3 Error in ALT statement. - -5- 3 Tape Sort error occurred. - -5' UF5'N1 0 3 Pack cannot be used. Not inited. - UF5'NU 0 3 Pack was used as TO pack on a COPYPACK job - that required early termination. Can only - be used for another COPYPACK job. - -60 LM60SY 0 3 Cannot remove or change library size on pack - from which $MAINT was loaded. - -61 LM61EP 0 3 Trying to copy a system to a library that is - 1) not empty, 2) not allocated with large enough - SWA, or 3) not allocated with enough space. - LM61NS 0 3 System does not exist on FROM pack. - -62 LM62CS 01 3 Check Sum error. - LM62DR Can't determine if REMOVE is data or control. - LM62EF FROM, TO, or AFTER statement does not exist or - is out of sequence. - LM62ND NO data records following INSERT or REPLACE. - LM62SQ Records are out of sequence. - LM62TP Incorrect type record. - -63 LM63DE 0 3 Directory entry error. Name can't be found or - attributes don't match, or attempt to remove - dir entry with MODIFY. - -64 LM64DS 0 3 Syntax error in ALLOCATE. - -65 LM65UN 0 3 Pack not properly initialized. - -66 LA66xx 3 Error with LOAD * function. - -67 EL67NL 0 3 Library does not exist. - -68 EL68DF 0 3 No room in library or directory. - -69 XX69HE 3 Disk I/O Error while using library. - -6A LM6Axx 1 3 $MAINT has detected a syntax error on a control - statement. xx gives a hint of what might be wrong. - AL: SOURCE or OBJECT missing or invalid - AZ: SYSTEM missing or invalid - D2: FROM, TO, or WORK is R2 or F2, not available - DK: Duplicate keyword - DS: Invalid DIRSIZE - FL: Invalid or missing FILE keyword - FM: Invalid or missing FROM keyword - IK: Invalid keyword - IN: Invalid INCR keyword - IS: first 3 columns must be // blank - IV: Invalid statement identifier - LB: Invalid LIBRARY keyword - LS: Invalid LIST keyword - NK: No keywords - NM: Invalid NAME keyword - NU: Invalid NEWNAME keyword - OM: Invalid OMIT keyword - RL: Invalid RECL keyword - RS: Invalid RESER keyword - RT: Invalid RETAIN keyword - SF: INvalid SEQFLD keyword - SQ: Invalid FROM, TO, or AFTER in MODIFY mode - XC: Invalid record. - XD: Duplicate keyword - XF: $$SYFG could not be found. - XL: LIBRARY keyword missing - XM: NAME keyword missing - XN: NAME parameter is invalid - XP: Library does not exist on this pack - XS: Syntax error - XT: Invalid library type - XV: INvalid operation - -6C LM6CSP 0 3 Not enough space on pack. - LM6CSW 0 3 Space not available for work file. - -6E LM6EOF 0 3 Overflow in seq field during RESER. - LM6EDP 0 3 Entry with same name already exists in library. - -6H EL6HDT 0 3 Trying to replace perm with temp entry. - LM6HDP 0 3 NEWNAME is already in library. - -6J LM6JCC 0 3 Control statements are missing. - -6L UA6L 3 Log device is required for this program. - -6Y LM6YNN 1 3 No NEWNAME when copying to same library. - -6 LM6 BC 3 Invalid character in source record. - LM6 CM 0 3 Invalid object deck. - LM6 ND 0 3 No data between COPY and CEND. - -6- LM6-BC 01 Entry containing a blank card being placed in - library. 0: accept, 1: skip and read next card. - -6' LM6'CE 1 3 // CEND expected but not found. 1: Retry, - provide CEND. NOTE: For option 3, if a module - was being replaced, it may have been deleted but - new module not loaded. - -70 CR70 3 Too many overrides for procedure. Max is 25. - -71 CR71 0 3 OCL Syntax Error. - -73 CR73 0 // PARTITION given in invalid location. - -74 CR74 3 /& between LOAD and RUN or CALL and RUN. - -75 CR75 23 Extraneous statement. - -76 CR76 0 3 // Missing from OCL statement. - -77 CR77 23 Invalid OCL statement identifier. - -78 CR78 0 3 Unknown OCL keyword. - -79 CR79 23 Continuation expected but not received. - -7A CR7A 3 A second LOAD or CALL found before run, or a - CALL in procedure overrides. - -7C CR7C 0 3 // COMPILE found between jobs. - -7E CR7E 0 3 // DATE found between jobs. 0: Ignore and continue. - -7F CR7F 0 3 // FILE found between jobs. Must go between - // LOAD or // CALL and // RUN statements. - -7H CR7H 0 3 // SWITCH found between jobs. - -7J CR7J 23 // READER found between LOAD or CALL and RUN. - -7L CI7Lxx 23 Error when reading a tape file. - -7P New print chain expected. Load it and press START. - -7U CR7U 3 RUN statement not preceeded by LOAD or CALL. - -7Y CI7Yxx 23 Error outputing a tape file. - -7 CR7 3 Too many utility control statements, max is 25. - -7- CR7- 0 // PARTITION was read but system does not support - Dual Programming. - -7' Error during tape processing. - -80 CR80 0 // DATE card has not been entered. - -81 CR81 23 Error in LOAD statement. - -83 CR83 23 Error in LOAD * statement. - -84 CR84 23 Error in CALL statement - -85 CR85 23 Second SWITCH statement found. - -86 CR86 23 Invalid paramter in switch statement. - -88 CR88 1 3 Procedure not found. - -89 CR89 01 // DATE has already been given. - 0 - accept the new date as the date. - 1 - leave the old date as the current date. - -8A CR8A01 0 Invalid date specified. - CR8A02 0 DATE parameter missing. - -8C CR8C 23 Second DATE found. - -8E CR8E01 23 Date specified incorrectly. - -8F CR8Fxx 23 Invalid BSCA statement. - -8H CR8H 3 More than 9 levels of procedures have been called. - -8J CR8J 0 Invalid // READER parameter. - -8L CR8L 0 Desired system input device being used by other - program. - -8P CR8P 0 Output device not defined. - -8U CU8UIP 23 Invalid HIKEY in FILE statement: non-numeric. - CR8UKL Parameter length mismatch. - CR8ULO Key greater than 29. - CR8UPL HIKEY-P greater than 15. - CR8USQ HIKEY parameters not in sequence. - -8Y CR8Y 0 Not logging can be done. Log turned off by - other program level. - -8- CR8- 0 3 Logging requested but cannot be done. - -90 CR90 0 // PAUSE statement read. Check printer or console - for instructions and continue. PAUSE was outside - LOAD and RUN. - -91 CR90 0 // PAUSE statement read. Check printer or console - for instructions and continue. PAUSE was inside - LOAD and RUN. - -92 CR92 23 COMPILE already recieved for this job. - -93 CR93 23 Error in COMPILE statement. - -94 CR94 23 Error in COMPILE statement. - -95 CR95 23 Error in COMPILE statement. - -96 CR96 0 23 System error. An OCL error was found, but the system - cannot resolve the error. - -97 CR97 0 Error in LOG statement. - -98 CR98 23 Error in LOG statement. - -99 CR99 0 23 Error in LOG statement. - -9A CR9A 23 Indicated action on last OCL statement read will - be ignored due to previous errors detected. - -9C CR9Cxx 123 Incorrect tape volume online. - -9E CR9E 0 Logging device being used by other program level. - -9F CR9F 0 23 Logging device in use by other program. - -9H CR9H 23 Log device in use. - -9J CR9J 0 Error in FORMS statement. - -9L CR9L 0 23 Error in FORMS statement. - -9P CR9P 23 Error in FORMS statement. - -9U CR9U 0 3 Other program has gotten a // IMAGE or other - program level is using the printer. - -9Y CR9Y 0 23 Logging device not sysgenned or CCP has it. - -9 CR9 0 23 Same as 9Y. - -9- CR9- 0 3 Other program level received a // FORMS or - other level using the printer. - -9' CR9' 0 Same as 9Y. - -A0 CRa0xx 23 Syntax error in FILE statement. - -A1 CRA1xx 23 Keyword error in FILE statement. - -A2 CRA2xx 23 Parameter error on FILE statement. - xx gives parameter: - 01 NAME, 02 UNIT, 03 PACK, 04 LABEL, - 05 RETAIN, 06 DATE, 07 RECORDS, 08 TRACKS, - 09 LOCATION, AS ASCII, BL BLKL, CV CONVERT, - DF DEFER, DN DENSITY, EN END, PT PARITY, - RC RECL, RF RECFM, RL REEL, SP SPLIT, - TN TRANSLATE. - -A3 CRA3xx 23 Missing Parameter on FILE statement, xx = - NN: NAME, NP: PACK, NU: UNIT, OP: no - parameters. - -A4 CRA4xx 23 Invalid parameter combination in FILE statement: - AS: ASCII-YES and RECFM-D/DB on 7-track tape - AV: ASCII-YES and RECFB-V/VB - AY: RECFM-D/DB without ASCII-YES - CT: CONVERT-ON and TRANSLATE - DI: UNIT says tape but disk parameters given - DN: DENSITY-800 not supported. - FS: RECFM is fexed and block or rec len less than 18 - IL: Incorrected RECL or BLKL for RECFM - IP: SPLIT or LOCATION used with RECORDS / TRACKS. - IR: LABEL, DATE or RETAIN wirh REEL-NL or REEL-NS - NS: Not all units are 7-track - PC: CONVERT-ON and PARITY-EVEN - RC: CONVERT-ON not given with RECFM-V/VB for 7-track - SD: DENSITY-1600 invalid for 7-track - SL: LOCATION missing or invalid for SPLIT. - SM: SPLIT invalid for multivolume files. - ST: 7-track paras with 9-track unit - SU: SPlit can't be used with 5444 - TL: TRACKS/LOCATION invalid with unit - TP: UNIT is disk but tape paras given - TR: TRACKS and RECORDS both given - -A6 CRA6xx 23 Error in FILE statement for multivolumne files. - -A7 CRA7xx 23 Error in IMAGE statement. - -A8 CRA8xx 0 Error in IMAGE statements o disk. - -A9 CRA9xx 0 23 Same as A8. - -AA CRAAxx 23 Same as A8. - -AC CRAC 0 Invalid hex character in chain image. - -AE CRAE 0 23 Same as AC. - -AF CRAF 23 Same as AC. - -AH CRAH 0 Error in IMAGE statement. - -AJ CRAJ 0 23 Same as AH - -AL CRALxx 0 Error in PARTITION statement. - -AP CRMN 0 3 Either reocvery option has has been selected during - a job, or OCL errors have occurred for this job. - 0: Continue iwth next job, or no data cards in - reader for this job, otherwise, 3 to cancel. - -AU CRAUxx 23 Error in PARTITION statement. - -A CRA 23 Total number of volumes for a FILE statement - exceeds 40 (!). - -A- CRA-xx 0 23 Error in PARTITION statement. - -A' CRA' 3 No space remaining is System work area. Too many - FILE statements are in this job. - -C1-C9 IFC1 123 1442 Check, various causes. - -CL UDCLxx 1 3 5445 Data Interchange Utility error - -E7 DKE7 0 3 Incorrect record length for attached 3741 - -E8 UTE8xx 1 3 Error in Tape Init VOL statement. - -E9 UTE9xy 0 3 Error during Tape Init Processing. - -F8 DDF8 3 RPG--LIne counter specs omitted and skip past - page size for printer. - -F9 CIF9xy 23 Tape drive not available, x = drive #. - -FA CIFA 3 Program requesting Data Recorder, unsupported. - -FC CIFC 3 Program requesting CRT, unsupported. - -FE DDFE 0 3 Program requesting line line on printer that - exceeds sysgen value. - -FF RPQ routine error. Press start to continue. - -FH CIFH 123 BSCA line not supported. - -FJ CIFJ01 123 1442 not supported but requested - CIFJ02 123 3741 not supported but requested - -FL CIFL 123 Printer/keyboard not supported or unavailable. - -FP CIFP 123 Printer not supported or allocated to other level - -FU CIFU 123 MFCU not supported or allocated to other level - -FY CIFY 23 Device is not supported or in use. - -F CIF 23 Conflict with a resource being used by other level. - -H0-H9 0 23 RPG Programmed halt indicator is on. - -HA CIHA 3 Out of space on $SOURCE during compile. - -HC CIHC 3 Program given on LOAD statement not found. - -HE Hardware error. Simulator has messed up. - -HF CIHF 0 3 // COMPILE read but not required. - -HJ CIHJ01 1 3 Program not found on removable unit, 1: - mount new unit and retry. - CIHJ02 3 Program not found, but removable unit in use. - -HL CIHL 3 Inquiry request made but program is wrong type. - -HP CIHP 3 Insufficient main storage for program. - LMHP 3 $MAINT function out of storage. NOTE: After the - cancel, IPL from the system pack or the pack will - be unusable. - -HU CIHUxx 3 Source program not found on disk. IF a 1 option - is present, you can mount a new removeable pack. - -HY CCHYNN 0 A checkpoint is received and accepted. - -H CCH NN 0 23 A restart has been requested. - -H' CIH' 3 An uninitialized pack has been referenced. - -J0-J9 123 Record with specified match field out of sequence. - This is an RPG error, the 2nd digit indicates which - RPG file statement the error applies to in the - source program. 0=greater than statement 9, - otherwise indicates the file statement number. - -JA CIJA 3 Trying to laod a program that requires or allows - inquiry while another inquiry program is running - in the other level. - -JC CIJCxx 3 Program cannot be run for this reason (xx): - 01: Must be dedicated and other level active - 02: Program in other level must be dedicated - 03: $$RSTR cannot run in level 2 - 04: CHeckpointed program not allowed in level 2 - 05: Program can't run while checkpoint active - -JE CIJE 0 3 Level 1 partition too small. - -JF CIJF 3 Attempt to start inquiry program but keyboard - in use. - -JH CIJF 3 Attempt to start program which allows interrupts in - level 2. - -JJ CIJJ 3 No object library on pack requested for load. - -JL CIJL 3 Not enough storage for program. DPF only. - -JP System input device in use by other level. - -JU 0123 Cancel request made from interrupt key. 0: ignore - 1: continue, request ignored - -JY CIJYRD 0 2 Inquiry request made and accepted. - -J- 3 Attempt to run a CCP program, but CCP not running. - -J' 01 3 Inquiry request is completed, interrupted program - can now resume. - -L0-L9 123 RPG. Unidentified record, 2nd digit gives file - statement number in source program 1-9, 0 means - greater than 9. Can also occur if record is out - of sequence. - -LA CILA 23 Too little storage for number of files in program. - -LC CILC 23 Too little storage for requested allocation. - -LE CILE 23 No FILE or an incorrect FILE for a file requested - by current program. - -LH CILH 23 No space given for an output file on FILE statement. - -LJ CILJ 23 Attempt to output to existing permanent file. - -LL CILL 0 23 Attempt to output over an existing temporary file. - -LP CILP 23 File already exists. - -LU CILU 123 Pack name requested but wrong pack mounted. 1: - retry after mounting correct pack. - -LY CILYxx 23 Attempt to allocate space that isn't available. - xx=02 means space not available in split cylinder - area. - -L LML CP 01 3 $MAINT detected attempt to modify a program on - a pack with an active checkpoint. - -L- CIL- 3 Attempt to add a split cylinder to a split cyl - file while other level is fiddling with a split - cylinder file. - -L' CIl' 23 Trying to allocate a split cylinder file before - allocating the first split cylinder file in a group. - -P1-P8 Printer hardware errors, should not occur in sim. - -PC IPPC 0 23 Unprintable character. - -PH CIPH 23 LOCATION plus TRACKS goes past end of pack. - -PJ CIPJxx 1 A Pack is to be remounted, pack name printed before - half code, xx= unit. - -PU CIPU 3 Duplicate file names in the FILE statements. - -PY CIPY01 3 ISAM file requires at least 2 tracks. - CIPY02 3 ISAM file can't be split cylinder. - -P' CIP'xx 23 Too many scratch or work files. - -U0-U9 0123 RPG. Unidentified record in file, 2nd digit of - halt is file statement in RPG source, 0= greater - than 9. - -UA CIUA 3 Attempt to create a multivolume file in - invalid. - -UC CIUC 3 The printed actived file cannot be found in the - list of scratch files. - -UE CIUExx 1 3 PACK parameter does not match pack name on unit. - xx = Unit referenced. - 1 = Mount another pack and continue. - -UF CIUF 3 Disk file referenced by name and date not found. - -UH CIUH 3 Attempt to create multivolume file failed, - because name alreayd exists. - -UJ CIUJ 3 A LOCATION was specified for an existing disk file - and the file exists but not at that location. - -UL CIUL 3 File on // FILE statement not found, and no size - in TRACKS or RECORDS was given. - -UP CIUP 3 Permanent file referenced with RETAIN-S - -UU CIUU 3 Disk Pack not available. - -UY CIUY 3 File is a System/3 BASIC file which must be unique. - -U CIU 3 Existing file: TRACKS/RECORDS or LOCATION mismatch. - -U- General CCP halt. Press start to see subhalt. - Refer to CCP manual for more info. - -U' CIU' 23 VTOC is full, or more than 2 multivolume files per - pack, or more than 2 ISAM files using HIKEY - parameter. - -YH CRYH 0 3 Cards are being punched, but card read from - reader was not blank. This means you are trying to - punch with a file attached to the CDR device. - Unattach the file and take the zero option. - - 0 (blank 0) FILE WRITE switch in off position. - - 1 (blank 1) Permanent DIsk I/O Error - - 2 RC 211 3 COBOL. Out of room on $WORK. - RC 212 3 Out of room on $SOURCE. - RC 213 3 Out of room on $WORKX. - RC 214 3 Subprogram name table greater than 20. - RC 219 0 3 C or E level diagnostics during compile. - RC 2A1 23 Subscript invalid - RC 2A2 23 Negative exponent or 0 degrees in program - RC 2F1 23 MFCU File not open or opened improperly - RC 2F2 23 1442 File not open or opened improperly - RC 2F3 23 1403/5203 File not open or opened improperly - RC 2F4 23 5444 Disk File not open or opened improperly - RC 2F5 23 5444 File not open or opened improperly - RC 2F7 23 5444 File not open or opened improperly - RC 2F8 23 Tape File not open or opened improperly - RC 2H1 23 OPEN attempted after CLOSE WITH LOCK - RC 2H2 23 Error during ACCEPT - RC 2H3 23 $$STOP not found - RC 2H4 23 CHeckpoint could not be taken. - RC 2H5 23 $$STIC not found for ACCEPT - RC 2H6 23 Parameter mismatch CALL and USING - RC 2H7 23 ACCEPT after /& read - RC 2H8 23 OPEN for a file already OPEN - RC 2 0 3 Too little core for compile - RC 2 1 3 PROCEDURE or DATA division not found. - RC 2 3 3 Program has more than 65535 statements (!) - RC 2 4 3 Source name on COMPILE statement not found - - 3 R 3XX 0 3 COBOL Stop literal. XX is user-specified. - 0 continues program 3 cancels. - - 4 VF 4NF 3 Program not found. Program library and - not printed before halt message. - - 6 RF 6XX 0 23 FORTRAN stop statement. - - 7 RF 701 23 Source member on COMPILE not found - RF 702 23 Object program too large for core. - - 8 CS 8 1 3 System input device allocated to other level. - - 9 CS 9 1 3 System input device has an error. This usually - means the card hopper is empty (i.e. EOF on the - file attached to the reader but SCP wants more - input). - - A DC A 123 Number of characters entered from keyboard - incorrect. - - C DD C 0 23 Unprintable character for printer/keyboard. - - E DC E 123 Hardware error, PKB - - F DC F 0 23 End of forms, PKB - - L DD L 0 3 Records with duplicate keys have been loaded - into ISAM file. Each dup key is logged followed - by blank P halt. 0: continue. Index will - contain duplicate keys. 3: cancel, file is - not usable, reload it. - - P DD P 0 3 Duplicate key encountered. The key is printed - on the log. 0: continue, halt will recur for - any other duplicates, then blank L appears. - - U DD U 3 Disk I/O error while sorting ISAM index. - - Y DD Y 3 System error during file termination. - --0 DD-0XX 3 ISAM multivolume file being used and high key - not found for current columme, or does not agree - with HIKEY spec. XX=unit number. - --1 DD-1XX 123 Halt -P occurred and option 0 taken. But, the - pack mounted is not a part of volume set. - --2 DD-2XX 123 Multivolume load sequence error. - --3 DD-3XX 123 Multivolume load sequence error. - --4 DD-4XX 0123 Warning that one or more volumes are about to be - bypassed. - --5 DD-5XX 123 Multivolume file not found. 1: mount correct pack. - --6 DD-6XX 0 23 Warning. ENd of volume and HIKEY not found. - --7 DD-7XX 1 3 -A halt and option 1 taken. But the pack referenced - does not match pack name. - --8 DD-8XX 3 Multivolume file referenced but file isn't - multivolume. - --9 DD-9XX 3 Add to a multivolumen file, but last pack not - mounted. - --A DD-AXX 1 3 Add to existing multivolume filebut no room. - --C DD-CXX 3 Multivolume file error. Probably out of sequence - volume mounts. - --E DD-EXX 123 Next volume cannot be processed, because the - location is not available or space is not available - or there are scratch files on the pack. - --F DD-Fxx 123 Finished a volume, next cannot be processed, mount - the correct pack or cancel. - --H DD-Hxx 3 HIKEY length does not match file. - --J DD-Jxx 01 3 First volume referenced is not volumme 1. 0: - continue with this volume, 1: mount another pack. - --L DD-Lxx 3 Output to multivolume, but file isn't multivolume - or referenced volume isn't first one of set. - --P DD-PXX 0123 Mount next volume. XX=unit number. 0: continue - bypassing volumes, 1: mount next volume. - --U DD-UXX 1 3 Halt -J just occurred and 0 or 1 taken. But the - pack name is incorrect or the file isn't found. - -- DD- 123 Multivolume key error. Key too low or high for - volume. - --' DD-' 123 Sequential add to multivolume file, but HIKEY - record missing on previous volume. - -'0 GM'0DE 3 SYSGEN. I/O Error on reader. - GM'0EX 3 SYSGEN. End of extent on MACOUT or $SOURCE. - GM'0IC 1 3 SYSGEN. Option dependent on a preceding option, the - preceding one was omitted or invalid. - GM'0ID 1 3 SYSGEN invalid delimiter. - GM'0IK 1 3 SYSGEN invalid keyword. - GM'0IR 1 3 SYSGEN invalid option. - GM'0IS 1 3 SYSGEN sequence error. - GM'0NF 1 3 SYSGEN entry in cols 8-12 not found. - GM'0NS 3 SYSGEN Requested source program not found. - GM'0EM 1 3 SYSGEN. END statement not found. - GM'0NP 3 SYSGEN. Module $SGXP2, $SGXP3, $SGXP4, $SGXP5, or - $SGXP6 missing for sysgen, or $MPXP2, $MPXP3 or - $MPXP4 missing for macro processor. - -'1 GG'1 3 System Generation Errors. - -'2 0 3 Error during macro processor run. - -'3 3 Invalid 5445 disk label record. - -'4 GG'4EX 3 Out of room on Sysgen, or disk error. - ------------------------ End of haltguide.txt --------------------------- diff --git a/S3/readme_s3.txt b/S3/readme_s3.txt deleted file mode 100644 index 37afdd9c..00000000 --- a/S3/readme_s3.txt +++ /dev/null @@ -1,78 +0,0 @@ - Welcome to the IBM System/3 Model 10 SIMH simulator. - --------------------------------------------------- - - To compile under linux: - - cc s3*.c scp*.c sim_rev.c -o s3 - - This code can be compiled and run as a console application using - Microsoft Visual C++. - - - - To IPL the provided SCP distribution disk: - - ./s3 - sim> at r1 m10scp.dsk - sim> at f1 f1f1f1.dsk - sim> at lpt print.txt - sim> d sr 5471 - sim> boot r1 - - - // DATE 06/14/01 - // NOHALT - // LOAD $MAINT,R1 - // RUN - // COPY FROM-R1,LIBRARY-ALL,NAME-DIR,TO-PRINT - // END - - - (A printout of the libraries and directories on the SCP DTR - disk will be in the file print.txt) - - - The text file "system3.txt" gives details on the simulators - implementation of System/3 hardware. - - A write up on the use of the SCP and the OCL job control language is - in the text file "userguide.txt". This includes examples of using the - utility programs, and a tutorial guiding you thru a sysgen. - - A nearly complete listing of all possible SCP halts is in the - document "haltguide.txt". - - IMPORTANT NOTES: - - 1) How to correct typing errors when using the System/3 console: - If you make an error, press ESC, which will cancel the current - line being typed and print a quote in position 1. Then you - can use CTRL/R to retype characters up until the error, then - type correctly. Or simply retype the line. BACKSPACE DOES NOT - WORK with the SCP. - - 2) While the simulator allows disk images to be independently - attached to any disk unit, on the real hardware R1 and F1 were on - a single spindle, and R2 and F2 likewise. It is not possible using - SCP to attach R1 without attaching a disk image to F1 also, because - SCP will always look at F1 even when IPLed off R1. - - The OS distributed with the simulator is version 16 of the Model - 10 SCP. This is sysgenned with support only for R1 and F1. If you - do a sysgen to support R2 amd F2 also, you must have images attached - to all 4 disks when you IPL, because SCP looks at all drives when - it starts up, and you will get an "Unattached Unit" error if you - fail to have one attached. - - 3) The 1442 card reader had in reality one card input hopper - and two stackers. This means the same path is used for reading and - punching cards. When punching cards, SCP does a read operation - and inspects the card read for blanks, and if it is not blank, - issues a YH halt. SCP will not punch data onto non-blank cards. - This feature causes problems in the simulator, and as a result - if you punch cards from SCP, YOU MUST not have any file attached - to the CDR device. Leaving this device unattached presents an - infinite supply of blank cards to SCP for punching. - - - -- End of README_S3.txt -- diff --git a/S3/s3_cd.c b/S3/s3_cd.c deleted file mode 100644 index 9dd3a93e..00000000 --- a/S3/s3_cd.c +++ /dev/null @@ -1,448 +0,0 @@ -/* s3_cd.c: IBM 1442 card reader/punch - - Copyright (c) 2001-2012, Charles E. Owen - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. - - cdr card reader - cdp card punch - cdp2 card punch stacker 2 - - 19-Mar-12 RMS Fixed declaration of conversion tables (Mark Pizzolato) - 25-Apr-03 RMS Revised for extended file support - 08-Oct-02 RMS Added impossible function catcher - - Normally, cards are represented as ASCII text streams terminated by newlines. - This allows cards to be created and edited as normal files. Set the EBCDIC - flag on the card unit allows cards to be read or punched in EBCDIC format, - suitable for binary data. -*/ - -#include "s3_defs.h" -#include - -extern uint8 M[]; -extern unsigned char ebcdic_to_ascii[]; -extern unsigned char ascii_to_ebcdic[]; -int32 s1sel, s2sel; -char rbuf[CBUFSIZE]; /* > CDR_WIDTH */ -t_stat cdr_svc (UNIT *uptr); -t_stat cdr_boot (int32 unitno, DEVICE *dptr); -t_stat cdr_attach (UNIT *uptr, char *cptr); -t_stat cd_reset (DEVICE *dptr); -t_stat read_card (int32 ilnt, int32 mod); -t_stat punch_card (int32 ilnt, int32 mod); - -int32 DAR; /* Data address register */ -int32 LCR; /* Length Count Register */ -int32 lastcard = 0; /* Last card switch */ -int32 carderr = 0; /* Error switch */ -int32 pcherror = 0; /* Punch error */ -int32 notready = 0; /* Not ready error */ -int32 cdr_ebcdic = 0; /* EBCDIC mode on reader */ -int32 cdp_ebcdic = 0; /* EBCDIC mode on punch */ - -extern int32 GetMem(int32 addr); -extern int32 PutMem(int32 addr, int32 data); - -/* Card reader data structures - - cdr_dev CDR descriptor - cdr_unit CDR unit descriptor - cdr_reg CDR register list -*/ - -UNIT cdr_unit = { UDATA (&cdr_svc, UNIT_SEQ+UNIT_ATTABLE, 0), 100 }; - -REG cdr_reg[] = { - { FLDATA (LAST, lastcard, 0) }, - { FLDATA (ERR, carderr, 0) }, - { FLDATA (NOTRDY, notready, 0) }, - { HRDATA (DAR, DAR, 16) }, - { HRDATA (LCR, LCR, 16) }, - { FLDATA (EBCDIC, cdr_ebcdic, 0) }, - { FLDATA (S2, s2sel, 0) }, - { DRDATA (POS, cdr_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TIME, cdr_unit.wait, 24), PV_LEFT }, - { BRDATA (BUF, rbuf, 8, 8, CDR_WIDTH) }, - { NULL } -}; - -DEVICE cdr_dev = { - "CDR", &cdr_unit, cdr_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &cd_reset, - &cdr_boot, &cdr_attach, NULL -}; - -/* CDP data structures - - cdp_dev CDP device descriptor - cdp_unit CDP unit descriptor - cdp_reg CDP register list -*/ - -UNIT cdp_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }; - -REG cdp_reg[] = { - { FLDATA (ERR, pcherror, 0) }, - { FLDATA (EBCDIC, cdp_ebcdic, 0) }, - { FLDATA (S2, s2sel, 0) }, - { FLDATA (NOTRDY, notready, 0) }, - { HRDATA (DAR, DAR, 16) }, - { HRDATA (LCR, LCR, 16) }, - { DRDATA (POS, cdp_unit.pos, T_ADDR_W), PV_LEFT }, - { NULL } -}; - -DEVICE cdp_dev = { - "CDP", &cdp_unit, cdp_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &cd_reset, - NULL, NULL, NULL -}; - -/* Stacker data structures - - stack_dev STACK device descriptor - stack_unit STACK unit descriptors - stack_reg STACK register list -*/ - -UNIT stack_unit[] = { - { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) } -}; - -REG stack_reg[] = { - { DRDATA (POS0, stack_unit[0].pos, 32), PV_LEFT }, - { NULL } -}; - -DEVICE stack_dev = { - "CDP2", stack_unit, stack_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &cd_reset, - NULL, NULL, NULL -}; - - -/* -------------------------------------------------------------------- */ - -/* 1442: master routine */ - -int32 crd (int32 op, int32 m, int32 n, int32 data) -{ - int32 iodata; - switch (op) { - case 0: /* SIO 1442 */ - /* if (n == 1) - return STOP_IBKPT; */ - switch (data) { /* Select stacker */ - case 0x00: - break; - case 0x01: - s2sel = 1; - break; - default: - break; - } - switch (n) { - case 0x00: /* Feed */ - iodata = SCPE_OK; - break; - case 0x01: /* Read only */ - if (cdr_ebcdic) - iodata = read_card(0, 1); - else - iodata = read_card(0, 0); - break; - case 0x02: /* Punch and feed */ - iodata = punch_card(0, 0); - break; - case 0x03: /* Read Col Binary */ - iodata = read_card(0, 1); - break; - case 0x04: /* Punch no feed */ - iodata = punch_card(0, 1); - break; - default: - return STOP_INVDEV; - } - return iodata; - case 1: /* LIO 1442 */ - switch (n) { - case 0x00: /* Load LCR */ - LCR = data & 0xffff; - break; - case 0x04: - DAR = data & 0xffff; - break; - default: - return STOP_INVDEV; - } - return SCPE_OK; - case 2: /* TIO 1442 */ - iodata = 0; - switch (n) { - case 0x00: /* Error */ - if (carderr || pcherror || notready) - iodata = 1; - if ((cdr_unit.flags & UNIT_ATT) == 0) - iodata = 1; /* attached? */ - break; - case 0x02: /* Busy */ - if (sim_is_active (&cdr_unit)) - iodata = 1; - break; - default: - return (STOP_INVDEV << 16); - } - return ((SCPE_OK << 16) | iodata); - case 3: /* SNS 1442 */ - iodata = 0; - switch (n) { - case 0x01: - break; - case 0x02: - break; - case 0x03: - if (carderr) - iodata |= 0x80; - if (lastcard) - iodata |= 0x40; - if (pcherror) - iodata |= 0x20; - if ((cdr_unit.flags & UNIT_ATT) == 0) - iodata |= 0x08; - if (notready) - iodata |= 0x08; - break; - case 0x04: - iodata = DAR; - break; - default: - return (STOP_INVDEV << 16); - } - iodata |= ((SCPE_OK << 16) & 0xffff0000); - return (iodata); - case 4: /* APL 1442 */ - iodata = 0; - switch (n) { - case 0x00: /* Error */ - if (carderr || pcherror || notready) - iodata = 1; - if ((cdr_unit.flags & UNIT_ATT) == 0) - iodata = 1; /* attached? */ - break; - case 0x02: /* Busy */ - if (sim_is_active (&cdr_unit)) - iodata = 1; - break; - default: - return (STOP_INVDEV << 16); - } - return ((SCPE_OK << 16) | iodata); - default: - break; - } - sim_printf (">>CRD non-existent function %d\n", op); - return SCPE_OK; -} - -/* Card read routine - mod 0 = ASCII read - mod 1 = EBCDIC read -*/ - -t_stat read_card (int32 ilnt, int32 mod) -{ -int32 i; -t_stat r; - -if (sim_is_active (&cdr_unit)) { /* busy? */ - sim_cancel (&cdr_unit); /* cancel */ - if (r = cdr_svc (&cdr_unit)) return r; /* process */ -} - -if (((cdp_unit.flags & UNIT_ATT) != 0 || - (stack_unit[0].flags & UNIT_ATT) != 0) && /* Punch is attached and */ - (cdr_unit.flags & UNIT_ATT) == 0) { /* reader is not --- */ - for (i = 0; i < 80; i++) { /* Assume blank cards in hopper */ - PutMem(DAR, 0x40); - DAR++; - } - sim_activate (&cdr_unit, cdr_unit.wait); /* activate */ - return SCPE_OK; -} - -if ((cdr_unit.flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */ - -lastcard = carderr = notready = s1sel = s2sel = 0; /* default stacker */ - -for (i = 0; i < CBUFSIZE; i++) rbuf[i] = 0x20; /* clear buffer */ -if (mod) { - for (i = 0; i < 80; i++) { - rbuf[i] = fgetc(cdr_unit.fileref); /* Read EBCDIC */ - } -} else { - fgets (rbuf, CBUFSIZE, cdr_unit.fileref); /* read Ascii */ -} -if (feof (cdr_unit.fileref)) { /* eof? */ - notready = 1; - return STOP_NOCD; -} -if (ferror (cdr_unit.fileref)) { /* error? */ - perror ("Card reader I/O error"); - clearerr (cdr_unit.fileref); - carderr = 1; - return SCPE_OK; } -cdr_unit.pos = ftell (cdr_unit.fileref); /* update position */ -i = getc (cdr_unit.fileref); /* see if more */ -if (feof (cdr_unit.fileref)) lastcard = 1; /* eof? set flag */ -fseek (cdr_unit.fileref, cdr_unit.pos, SEEK_SET); -for (i = 0; i < 80; i++) { - if (mod == 0) { /* If ASCII mode... */ - if (rbuf[i] == '\n' || /* remove ASCII CR/LF */ - rbuf[i] == '\r' || - rbuf[i] == 0x00) - rbuf[i] = ' '; - rbuf[i] = ascii_to_ebcdic[rbuf[i]]; /* convert to EBCDIC */ - } - PutMem(DAR, rbuf[i]); /* Copy to main memory */ - DAR++; -} -sim_activate (&cdr_unit, cdr_unit.wait); /* activate */ -return SCPE_OK; -} - -/* Card reader service. If a stacker select is active, copy to the - selected stacker. Otherwise, copy to the normal stacker. If the - unit is unattached, simply exit. -*/ - -t_stat cdr_svc (UNIT *uptr) -{ -int32 i; - -if (s2sel) uptr = &stack_unit[0]; /* stacker 1? */ -else uptr = &stack_unit[0]; /* then default */ -if ((uptr -> flags & UNIT_ATT) == 0) return SCPE_OK; /* attached? */ -for (i = 0; (size_t)i < CDR_WIDTH; i++) rbuf[i] = ebcdic_to_ascii[rbuf[i]]; -for (i = CDR_WIDTH - 1; (i >= 0) && (rbuf[i] == ' '); i--) rbuf[i] = 0; -rbuf[CDR_WIDTH] = 0; /* null at end */ -fputs (rbuf, uptr -> fileref); /* write card */ -fputc ('\n', uptr -> fileref); /* plus new line */ -if (ferror (uptr -> fileref)) { /* error? */ - perror ("Card stacker I/O error"); - clearerr (uptr -> fileref); -} -uptr -> pos = ftell (uptr -> fileref); /* update position */ -return SCPE_OK; -} - -/* Card punch routine - - mod: not used -*/ - -t_stat punch_card (int32 ilnt, int32 mod) -{ -int32 i, colcount; -static char pbuf[CDP_WIDTH + 1]; /* + null */ -UNIT *uptr; - -if (s2sel) uptr = &stack_unit[0]; /* stack 2? */ -else uptr = &cdp_unit; /* normal output */ -if ((uptr -> flags & UNIT_ATT) == 0) { /* Attached? */ - notready = 1; - return SCPE_OK; -} -pcherror = s1sel = notready = 0; /* clear flags */ - -colcount = 128 - LCR; -for (i = 0; i < colcount; i++) { /* Fetch data */ - if (cdp_ebcdic) - pbuf[i] = GetMem(DAR) & 0xff; - else - pbuf[i] = ebcdic_to_ascii[GetMem(DAR)]; - DAR++; -} -for (i = CDP_WIDTH - 1; (i >= 0) && (pbuf[i] == ' '); i--) pbuf[i] = 0; -pbuf[CDP_WIDTH] = 0; /* trailing null */ -if (!cdp_ebcdic) { - fputs (pbuf, uptr -> fileref); /* output card */ - fputc ('\n', uptr -> fileref); /* plus new line */ -} else { - for (i = 0; i < 80; i++) { - fputc(pbuf[i], uptr -> fileref); - } -} -if (ferror (uptr -> fileref)) { /* error? */ - perror ("Card punch I/O error"); - clearerr (uptr -> fileref); - pcherror = 1; -} -uptr -> pos = ftell (uptr -> fileref); /* update position */ -return SCPE_OK; -} - -/* Select stack routine - - Modifiers have been checked by the caller - Modifiers are 1, 2, for the respective stack -*/ - -t_stat select_stack (int32 ilnt, int32 mod) -{ -if (mod == 1) s1sel = 1; -else if (mod == 2) s2sel = 1; -return SCPE_OK; -} - -/* Card reader/punch reset */ - -t_stat cd_reset (DEVICE *dptr) -{ -lastcard = carderr = notready = pcherror = 0; /* clear indicators */ -s1sel = s2sel = 0; /* clear stacker sel */ -sim_cancel (&cdr_unit); /* clear reader event */ -return SCPE_OK; -} - -/* Card reader attach */ - -t_stat cdr_attach (UNIT *uptr, char *cptr) -{ -carderr = lastcard = notready = 0; /* clear last card */ -return attach_unit (uptr, cptr); -} - -/* Bootstrap routine */ - -t_stat cdr_boot (int32 unitno, DEVICE *dptr) -{ -cdr_ebcdic = 1; -DAR = 0; -LCR = 80; -read_card(0, 1); -return SCPE_OK; -} diff --git a/S3/s3_cpu.c b/S3/s3_cpu.c deleted file mode 100644 index 84de92f2..00000000 --- a/S3/s3_cpu.c +++ /dev/null @@ -1,1830 +0,0 @@ -/* s3_cpu.c: IBM System/3 CPU simulator - - Copyright (c) 2001-2012, Charles E. Owen - HPL & SLC instruction code Copyright (c) 2001 by Henk Stegeman - Decimal Arithmetic Copyright (c) 2000 by Roger Bowler - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. - - ------------------------------------------------------------------------------ - - cpu System/3 (models 10 and 15) central processor - - 19-Mar-12 RMS Changed int to int32 in declarations (Mark Pizzolato) - - The IBM System/3 was a popular small-business computing system introduced - in 1969 as an entry-level system for businesses that could not afford - the lowest rungs of the System/360. Its architecture is inspired by and - in some ways similar to the 360, but to save cost the instruction set is - much smaller and the I/O channel system greatly simplified. There is no - compatibilty between the two systems. - - The original System/3 had two models, 6 and 10, and these came in two - configurations: card system and disk system. The unique feature of - the /3 was the use of 96-column cards, although traditional 80-column - cards were supprted also via attachment of a 1442 reader/punch. - System/3 is a batch-oriented system, controlled by an operating - system known as SCP (System Control Program), with it's own job control - language known as OCL (simpler and more logical than the JCL used on - the mainframes). Original models did not support multiprogramming - or any form of interactivity. (There was a hardware dual-program - facility available on the model 10 at the high end). - - The line grew throughout the 1970s, overlapping the low end of the 360 - line with the introduction of the model 15. The 15 (and later larger - variations of the model 12) broke the 64K limit designed in the original - models by adding a simple address translation unit to support up to 512K - bytes. The model 15 added a system of storage protection and allowed - multiprogramming in up to 3 partitions. Communications were added to - allow support of multiple 3270 terminals and the models 12 and 15 broke - the batch orientation and facilitated interactive use via the CCP - (communications control program). The System/3 was effectively replaced - by the much easier to manage and use System/34 and System/36 at the - low and middle of the range, and by System/370 or System/38 at the - high end. - - This simulator implements the model 10 and model 15. Models 4, 6, - 8, and 12 are not supported (these were technical variations on the - design which offered no functionality not present on either 10 or 15). - - The System/3 is a byte-oriented machine with a data path of 8 bits - in all models, and an address width of 16 bits. - - The register state for the System/3 CPU is: - - BAR <0:15> Operand 1 address register - AAR <0:15> Operand 2 address register - XR1 <0:15> Index Register 1 - XR2 <0:15> Index Register 2 - PSR <0:15> Condition Register - IAR [0:9]<0:15> Instruction Address Register (p1, p2, plus 1 for each interrupt) - ARR [0:9]<0:15> Address Recall Register (p1, p2, plus 1 for each interrupt) - (The P2 IAR & ARR are used for the Dual Program feature) - - Instruction formats follow the same basic pattern: a 1-byte opcode, a - 1-byte "Q byte", and one or two addresses following in a format defined - by the first 4 bits of the opcode: - - Op Code Q Byte Address(es) - - 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 - +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--... - | A 1 | A 2 | operation | | (defined by operation)| | Format based on A1, A2 - +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--+--+ +--+--+--+--+--+--+--... - - { --- } <---------------- Bits 00 = Operand 2 specified by 2-byte direct addr - Bits 01 = Operand 2 is 1-byte displacement + XR1 - Bits 10 = Operand 2 is 1-byte displacement + XR2 - Bits 11 = Operand 2 is not used - - { --- } <---------------------- Bits 00 = Operand 1 specified by 2-byte direct addr - Bits 01 = Operand 1 is 1-byte displacement + XR1 - Bits 10 = Operand 1 is 1-byte displacement + XR2 - Bits 11 = Operand 1 is not used - - Instructions come in 3 basic formats, of varying lengths which are determined - by the top 4 bits of opcode defined above. Minimum instruction length is 3 bytes, - maximum is 6. - - 1) Command Format (Bits 0-3 are 1111): - - +------------+ +------------+ +------------+ - | Opcode | | Q-byte | | R-byte + - +------------+ +------------+ +------------+ - - (The meaning of Q-byte and R-byte defined by the operation) - - - 2) One Address Instructions (either bits 0-1 or bits 2-3 are 01): - - - Direct Addressing Format: - - +------------+ +------------+ +-----------+----------+ - | Opcode | | Q-byte | | MSB + LSB + - +------------+ +------------+ +-----------+----------+ - - Base-Displacement Format: - - +------------+ +------------+ +------------+ - | Opcode | | Q-byte | |displacement+ - +------------+ +------------+ +------------+ - - Opcodes are 0011xxxx or 1100xxxx. - - Q-byte can be: 1) An immediate operand - 2) A mask - 3) A branch condition - 4) A data selection - - 2) Two Address Instructions (neither bits 0-1 nor bits 2-3 are both 11): - - Operand 1 Address Direct (opcodes 0001 or 0010): - - +------------+ +------------+ +----------+----------+ +------------+ - | Opcode | | Q-byte | | MSB + LSB + |displacement| - +------------+ +------------+ +----------+----------+ +------------+ - - Operand 2 Address Direct (opcodes 0100 or 1000): - - +------------+ +------------+ +------------+ +----------+----------+ - | Opcode | | Q-byte | |displacement| | MSB + LSB + - +------------+ +------------+ +------------+ +----------+----------+ - - Both Addresses Direct (opcode 0000): - - +------------+ +------------+ +----------+----------+ +-----------+----------+ - | Opcode | | Q-byte | | MSB + LSB + + MSB + LSB + - +------------+ +------------+ +----------+----------+ +-----------+----------+ - - Both Addresses Displacement (opcodes 0101, 0110, 1001, or 1010): - - +------------+ +------------+ +------------+ +------------+ - | Opcode | | Q-byte | |displacement| |displacement| - +------------+ +------------+ +------------+ +------------+ - - -Assembler Mnemonic Format -------------------------- - - The assembler format contains the same elements as the machine language operation, -but not always in the same format. The operation code frequently specifies both -the opcode and the Q byte, and the top nybble of the opcode is determined by -the format of the addresses. - - Addresses take two forms: the direct address in hex, or a relative address -specified thusly: (byte,XRx) where 'byte' is a 1-byte offset, and XRx is -either XR1 or XR2 for the two index registers. Use these formats when -'address' is indicated below: - - When 'reg' is mentioned, a mnemonic may be used for the register, thusly: - IAR Instruction Address Register for the current program level - ARR Address Recall Register for the current program level - P1IAR IAR for Program Level 1 - P2IAR IAR for Program Level 2 - PSR Program Status Register - 0x01 - Equal - 0x02 - Low - 0x04 - High - 0x08 - Decimal overflow - 0x10 - Test false - 0x20 - Binary overflow - 0x40 - Not used - 0x80 - Not used - XR1 Index Register 1 - XR2 Index Register 2 - IARx IAR for the interrupt level x (x = 0 thru 7) - - All other operands mentioned below are single-byte hex, except for the -length (len) operand of the two-address instructions, which is a decimal length -in the range 1-256. - - No-address formats: - ------------------ - - HPL hex,hex Halt Program Level, the operands are the Q and R bytes - - - One-address formats: - ------------------- - - A reg,address Add to register - CLI address,byte Compare Logical Immediate - MVI address,byte Move Immediate - TBF address,mask Test Bits Off - TBN address,mask Test Bits On - SBF address,mask Set Bits Off - SBN address,mask Set Bits On - ST reg,address Store Register - L reg,address Load Register - LA reg,address Load Address - JC address,cond Jump on Condition - BC address,cond Branch on Condition - - These operations do not specify a qbyte, it is implicit in the opcode: - - B address Unconditional branch to address - BE address Branch Equal - BNE address Branch Not Equal - BH address Branch High - BNH address Branch Not High - BL address Branch Low - BNL address Branch Not Low - BT address Branch True - BF address Branch False - BP address Branch Plus - BM address Branch Minus - BNP address Branch Not Plus - BNM address Branch Not Minus - BZ address Branch Zero - BNZ address Branch Not Zero - BOZ address Branch Overflow Zoned - BOL address Branch Overflow Logical - BNOZ address Branch No Overflow Zoned - BNOL address Branch No Overflow Logical - NOPB address No - never jump - - (substitute J for B above for a set of Jumps -- 1-byte operand (not 2), - always jumps forward up to 255 bytes. In this case, 'address' cannot be - less than the current address, nor greater than the current address + 255) - - Two-address formats (first address is destination, len is decimal 1-256): - ------------------- - - MVC address,address,len Move Characters - CLC address,address,len Compare Logical Characters - ALC address,address,len Add Logical Characters - SLC address,address,len Subtract Logical Characters - ED address,address,len Edit - ITC address,address,len Insert and Test Characters - AZ address,address,len Add Zoned Decimal - SZ address,address,len Subtract Zoned Decimal - - MNN address,address Move Numeric to Numeric - MNZ address,address Move Numeric to Zone - MZZ address,address Move Zone to Zone - MZN address,address Move Zone to Numeric - - I/O Format - ---------- - - In the I/O format, there are always 3 fields: - - da - Device Address 0-15 (decimal) - m - Modifier 0-1 - n - Function 0-7 - - The meaning of these is entirely defined by the device addressed. - - There may be an optional control byte, or an optional address (based on -the type of instruction). - - SNS da,m,n,address Sense I/O - LIO da,m,n,address Load I/O - TIO da,m,n,address Test I/O - - SIO da,m,n,cc Start I/O -- cc is a control byte - - APL da,m,n Advance Program Level - - - - --------------------------------------------- - Here is a handy opcode cross-reference table: - --------------------------------------------- - - | x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF ----+------------------------------------------------------------------ -0x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -1x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -2x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -3x | SNS LIO - - ST L A - TBN TBF SBN SBF MVI CLI - - - | -4x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -5x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -6x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -7x | SNS LIO - - ST L A - TBN TBF SBN SBF MVI CLI - - - | -8x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -9x | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -Ax | - - - - ZAZ - AZ SZ MVX - ED ITC MVC CLC ALC SLC -Bx | SNS LIO - - ST L A - TBN TBF SBN SBF MVI CLI - - - | -Cx | BC TIO LA - - - - - - - - - - - - - -Dx | BC TIO LA - - - - - - - - - - - - - -Ex | BC TIO LA - - - - - - - - - - - - - -Fx | HPL APL JC SIO - - - - - - - - - - - - - - - This routine is the instruction decode routine for System/3. - It is called from the simulator control program to execute - instructions in simulated memory, starting at the simulated PC. - It runs until 'reason' is set non-zero. - - General notes: - - 1. Reasons to stop. The simulator can be stopped by: - - HALT instruction - breakpoint encountered - program check caused by invalid opcode or qbyte or address or I/O spec - unknown I/O device and STOP_DEV flag set - I/O error in I/O simulator - - 2. Interrupts. - - There are 8 levels of interrupt, each with it's own IAR (program - counter). When an interrupt occurs, execution begins at the - location in the IAR for that level interrupt. The program - must save and restore state. Each device is assigned both a - level and a priority in hardware. Interrupts are reset via - an SIO instruction, when this happens, the program level - IAR resumes control. - - Interrupts are maintained in the global variable int_req, - which is zero if no interrupts are pending, otherwise, the - lower 16 bits represent devices, rightmost bit being device - 0. Each device requesting an interrupt sets its bit on. - - - 3. Non-existent memory. On the System/3, any reference to non-existent - memory (read or write) causes a program check and machine stop. - - 4. Adding I/O devices. These modules must be modified: - - ibms3_defs.h add interrupt request definition - ibms3_cpu.c add IOT mask, PI mask, and routine to dev_table - ibms3_sys.c add pointer to data structures to sim_devices -*/ - -#include "s3_defs.h" - -#define UNIT_V_M15 (UNIT_V_UF) /* Model 15 extensions */ -#define UNIT_M15 (1 << UNIT_V_M15) -#define UNIT_V_DPF (UNIT_V_UF+1) /* Dual Programming */ -#define UNIT_DPF (1 << UNIT_V_DPF) -#define UNIT_V_MSIZE (UNIT_V_UF+3) /* dummy mask */ -#define UNIT_MSIZE (1 << UNIT_V_MSIZE) - -uint8 M[MAXMEMSIZE] = { 0 }; /* memory */ -int32 AAR = 0; /* Operand 1 addr reg */ -int32 BAR = 0; /* Operand 2 addr reg */ -int32 XR1 = 0; /* Index register 1 */ -int32 XR2 = 0; /* Index register 2 */ -int32 PSR = 0; /* Condition Register */ -int32 IAR[10] = { 0 }; /* IAR 0-7 = int level 8=P1 9=P2 */ -int32 ARR[10] = { 0 }; /* ARR 0-7 = int level 8=P1 9=P2 */ -int32 dev_disable = 0; /* interrupt disable mask */ -int32 int_req = 0; /* Interrupt request device bitmap */ -int32 level = 8; /* Current Execution Level*/ -int32 stop_dev = 0; /* stop on ill dev */ -int32 SR = 0; /* Switch Register */ -int32 saved_PC; /* Saved (old) PC) */ -int32 debug_reg = 0; /* set for debug/trace */ -int32 debug_flag = 0; /* 1 when trace.log open */ -FILE *trace; - -t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); -t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); -t_stat cpu_reset (DEVICE *dptr); -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc); -t_stat cpu_boot (int32 unitno, DEVICE *dptr1); -extern int32 pkb (int32 op, int32 m, int32 n, int32 data); -extern int32 crd (int32 op, int32 m, int32 n, int32 data); -extern int32 lpt (int32 op, int32 m, int32 n, int32 data); -extern int32 dsk1 (int32 op, int32 m, int32 n, int32 data); -extern int32 dsk2 (int32 op, int32 m, int32 n, int32 data); -extern int32 cpu (int32 op, int32 m, int32 n, int32 data); -int32 nulldev (int32 opcode, int32 m, int32 n, int32 data); -int32 add_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2); -int32 subtract_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2); -static int32 compare(int32 byte1, int32 byte2, int32 cond); -static int32 condition(int32 qbyte); -static void store_decimal (int32 addr, int32 len, uint8 *dec, int sign); -static void load_decimal (int32 addr, int32 len, uint8 *result, int *count, int *sign); -static void add_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count); -static void subtract_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count, int *sign); -int32 GetMem(int32 addr); -int32 PutMem(int32 addr, int32 data); - -/* IOT dispatch table */ - -/* System/3 supports only 16 unique device addresses! */ - -struct ndev dev_table[16] = { - { 0, 0, &cpu }, /* Device 0: CPU control */ - { 1, 0, &pkb }, /* Device 1: 5471 console printer/keyboard */ - { 0, 0, &nulldev }, - { 0, 0, &nulldev }, - { 0, 0, &nulldev }, - { 0, 0, &crd }, /* Device 5: 1442 card reader/punch */ - { 0, 0, &nulldev }, /* Device 6: 3410 Tape drives 1 & 2 */ - { 0, 0, &nulldev }, /* Device 7: 3410 Tape drives 3 & 4 */ - { 0, 0, &nulldev }, - { 0, 0, &nulldev }, - { 0, 0, &dsk1 }, /* Device 10: 5444 Disk Drive 1 */ - { 0, 0, &dsk2 }, /* Device 11: 5444 Disk Drive 2 */ - { 0, 0, &nulldev }, /* Device 12: 5448 Disk Drive 1 */ - { 0, 0, &nulldev }, /* DEvice 13: 5448 Disk Drive 2 */ - { 0, 0, &lpt }, /* Device 14: 1403/5203 Printer */ - { 0, 0, &nulldev } /* Device 15: 5424 MFCU */ -}; - -/* Priority assigned to interrupt levels */ - -int32 priority[8] = {8, 7, 5, 4, 3, 6, 2, 1}; - -/* CPU data structures - - cpu_dev CPU device descriptor - cpu_unit CPU unit descriptor - cpu_reg CPU register list - cpu_mod CPU modifiers list -*/ - -UNIT cpu_unit = { UDATA (NULL, UNIT_FIX + UNIT_BINK, MAXMEMSIZE) }; - -REG cpu_reg[] = { - { HRDATA (IAR, saved_PC, 16), REG_RO }, - { HRDATA (IAR-P1, IAR[8], 16) }, - { HRDATA (IAR-P2, IAR[9], 16) }, - { HRDATA (ARR-P1, ARR[8], 16) }, - { HRDATA (ARR-P2, ARR[9], 16) }, - { HRDATA (AAR, AAR, 16) }, - { HRDATA (BAR, BAR, 16) }, - { HRDATA (XR1, XR1, 16) }, - { HRDATA (XR2, XR2, 16) }, - { HRDATA (PSR, PSR, 16) }, - { HRDATA (SR, SR, 16) }, - { HRDATA (INT, int_req, 16), REG_RO }, - { HRDATA (LEVEL, level, 16) }, - { HRDATA (IAR0, IAR[0], 16) }, - { HRDATA (IAR1, IAR[1], 16) }, - { HRDATA (IAR2, IAR[2], 16) }, - { HRDATA (IAR3, IAR[3], 16) }, - { HRDATA (IAR4, IAR[4], 16) }, - { HRDATA (IAR5, IAR[5], 16) }, - { HRDATA (IAR6, IAR[6], 16) }, - { HRDATA (IAR7, IAR[7], 16) }, - { HRDATA (ARR0, ARR[0], 16) }, - { HRDATA (ARR1, ARR[1], 16) }, - { HRDATA (ARR2, ARR[2], 16) }, - { HRDATA (ARR3, ARR[3], 16) }, - { HRDATA (ARR4, ARR[4], 16) }, - { HRDATA (ARR5, ARR[5], 16) }, - { HRDATA (ARR6, ARR[6], 16) }, - { HRDATA (ARR7, ARR[7], 16) }, - { HRDATA (DISABLE, dev_disable, 16), REG_RO }, - { FLDATA (STOP_DEV, stop_dev, 0) }, - { HRDATA (WRU, sim_int_char, 8) }, - { HRDATA (DEBUG, debug_reg, 16) }, - { NULL } -}; - -MTAB cpu_mod[] = { - { UNIT_M15, UNIT_M15, "M15", "M15", NULL }, - { UNIT_M15, 0, "M10", "M10", NULL }, - { UNIT_DPF, UNIT_DPF, "DPF", "DPF", NULL }, - { UNIT_DPF, 0, "NODPF", "NODPF", NULL }, - { UNIT_MSIZE, 8192, NULL, "8K", &cpu_set_size }, - { UNIT_MSIZE, 16384, NULL, "16K", &cpu_set_size }, - { UNIT_MSIZE, 32768, NULL, "32K", &cpu_set_size }, - { UNIT_MSIZE, 49152, NULL, "48K", &cpu_set_size }, - { UNIT_MSIZE, 65535, NULL, "64K", &cpu_set_size }, - { 0 } -}; - -DEVICE cpu_dev = { - "CPU", &cpu_unit, cpu_reg, cpu_mod, - 1, 16, 16, 1, 16, 8, - &cpu_ex, &cpu_dep, &cpu_reset, - NULL, NULL, NULL -}; - -t_stat sim_instr (void) -{ -register int32 PC, IR; -int32 i, j, carry, zero, op1, op2; -int32 opcode = 0, qbyte = 0, rbyte = 0; -int32 opaddr, addr1, addr2, dlen1, dlen2, r; -int32 int_savelevel = 8, intpri, intlev, intdev, intmask; -int32 devno, devm, devn; -char display[3][9]; -int32 val [32]; -register t_stat reason; - -/* Restore register state */ - -PC = IAR[level]; /* load local PC */ -reason = 0; - -/* Main instruction fetch/decode loop */ - -while (reason == 0) { /* loop until halted */ -if (sim_interval <= 0) { /* check clock queue */ - if (reason = sim_process_event ()) break; -} - -if (int_req) { /* interrupt? */ - intpri = 16; - for (i = 0; i < 16; i++) { /* Get highest priority device */ - if ((int_req >> i) & 0x01) { - intlev = dev_table[i].level; - if (priority[intlev] < intpri) { - intdev = i; - intpri = priority[intlev]; - } - } - } - intmask = 1 << intdev; /* mask is interrupting dev bit */ - int_req = ~int_req & intmask; /* Turn off int_req for device */ - int_savelevel = level; /* save current level for reset */ - level = dev_table[intdev].level; /* get int level from device */ - PC = IAR[level]; /* Use int level IAR for new PC */ -} /* end interrupt */ - -if (sim_brk_summ && sim_brk_test (PC, SWMASK ('E'))) { /* breakpoint? */ - reason = STOP_IBKPT; /* stop simulation */ - break; -} - -/* Machine Instruction Execution Here */ - -if ((debug_reg == 0) && debug_flag == 1) { - fclose(trace); - debug_flag = 0; -} -if (debug_reg) { - if (!debug_flag) { - trace = fopen("trace.log", "w"); - debug_flag = 1; - } -} - -if (debug_reg & 0x01) { - fprintf(trace, "ARR=%04X XR1=%04X XR2=%04X IAR=%04X ", ARR[level], XR1, XR2, PC); - val[0] = GetMem(PC); - val[1] = GetMem(PC+1); - val[2] = GetMem(PC+2); - val[3] = GetMem(PC+3); - val[4] = GetMem(PC+4); - val[5] = GetMem(PC+5); - fprint_sym(trace, PC, (uint32 *) val, &cpu_unit, SWMASK('M')); - fprintf(trace, "\n"); -} - -saved_PC = PC; -opaddr = GetMem(PC) & 0xf0; /* fetch addressing mode */ -opcode = GetMem(PC) & 0x0f; /* fetch opcode */ -PC = (PC + 1) & AMASK; -sim_interval = sim_interval - 1; - -qbyte = GetMem(PC) & 0xff; /* fetch qbyte */ -PC = (PC + 1) & AMASK; - -if (opaddr == 0xf0) { /* Is it command format? */ - rbyte = GetMem(PC) & 0xff; - PC = (PC + 1) & AMASK; - switch (opcode) { - case 0x00: /* HPL: Halt Program Level */ - for (i = 0; i < 3; i++) { - for (j = 0; j < 9; j++) { - display[i][j] = ' '; - } - } - /* First line */ - if (qbyte & 0x04) display[0][2] = '_' ; - if (rbyte & 0x04) display[0][6] = '_' ; - /* Second line */ - if (qbyte & 0x08) display[1][1] = '|' ; - if (rbyte & 0x08) display[1][5] = '|' ; - if (qbyte & 0x10) display[1][2] = '_' ; - if (rbyte & 0x10) display[1][6] = '_' ; - if (qbyte & 0x02) display[1][3] = '|' ; - if (rbyte & 0x02) display[1][7] = '|' ; - /* Third line */ - if (qbyte & 0x20) display[2][1] = '|' ; - if (rbyte & 0x20) display[2][5] = '|' ; - if (qbyte & 0x40) display[2][2] = '_' ; - if (rbyte & 0x40) display[2][6] = '_' ; - if (qbyte & 0x01) display[2][3] = '|' ; - if (rbyte & 0x01) display[2][7] = '|' ; - /* Print display segment array */ - sim_printf("\n"); - for (i = 0; i < 3; i++) { - for (j = 0; j < 9; j++) { - sim_printf ("%c", display[i][j]); - } - sim_printf ("\n"); - } - reason = STOP_HALT; - break; - case 0x01: /* APL: Advance Program Level */ - devno = (qbyte >> 4) & 0x0f; - devm = (qbyte >> 3) & 0x01; - devn = qbyte & 0x07; - op1 = dev_table[devno].routine(4, devm, devn, rbyte); - if (op1 & 0x01) { - if (cpu_unit.flags & UNIT_DPF) { /* Dual Programming? */ - if (level == 8) /* Yes: switch program levels */ - level = 9; - else - level = 8; - PC = IAR[level]; - } else { /* No: Loop on this inst */ - PC = PC - 3; - } - } - reason = (op1 >> 16) & 0xffff; - break; - case 0x02: /* JC: Jump on Condition */ - if (condition(qbyte) == 1) { - PC = (PC + rbyte) & AMASK; - } - break; - case 0x03: /* SIO: Start I/O */ - devno = (qbyte >> 4) & 0x0f; - devm = (qbyte >> 3) & 0x01; - devn = qbyte & 0x07; - reason = dev_table[devno].routine(0, devm, devn, rbyte); - if (reason == RESET_INTERRUPT) { - reason = SCPE_OK; - IAR[level] = PC; - level = int_savelevel; - PC = IAR[level]; - } - break; - default: - reason = STOP_INVOP; - break; - } /* switch (opcode) */ - IAR[level] = PC; - continue; -} - -/* Not command format: fetch the addresses */ - -addr1 = (opaddr >> 6) & 3; -addr2 = (opaddr >> 4) & 3; - -switch (addr1) { - case 0: - BAR = GetMem(PC) << 8; - PC = (PC + 1) & AMASK; - BAR |=GetMem(PC); - PC = (PC + 1) & AMASK; - break; - case 1: - BAR = GetMem(PC); - BAR = (BAR + XR1) & AMASK; - PC = (PC + 1) & AMASK; - break; - case 2: - BAR = GetMem(PC); - BAR = (BAR + XR2) & AMASK; - PC = (PC + 1) & AMASK; - break; - case 3: - break; - default: - break; -} /* switch (addr1) */ - -switch (addr2) { - case 0: - AAR = GetMem(PC) << 8; - PC = (PC + 1) & AMASK; - AAR |= GetMem(PC); - PC = (PC + 1) & AMASK; - break; - case 1: - AAR = GetMem(PC); - AAR = (AAR + XR1) & AMASK; - PC = (PC + 1) & AMASK; - break; - case 2: - AAR = GetMem(PC); - AAR = (AAR + XR2) & AMASK; - PC = (PC + 1) & AMASK; - break; - case 3: - break; - default: - break; -} /* switch (addr1) */ - -switch (opaddr) { - case 0x00: - case 0x10: - case 0x20: - case 0x40: - case 0x50: - case 0x60: - case 0x80: - case 0x90: - case 0xa0: - switch (opcode) { - case 4: /* ZAZ: Zero and Add Zoned */ - dlen2 = qbyte & 0x0f; - dlen1 = (qbyte >> 4) & 0xf; - dlen1 += dlen2; - op1 = BAR; - for (i = 0; i < (dlen1+1); i++) { - PutMem(op1, 0xf0); - op1--; - } - r = add_zoned(BAR, dlen1+1, AAR, dlen2+1); - PSR &= 0xF8; /* HJS mod */ - switch (r) { - case 0: - PSR |= 0x01; - break; - case 1: - PSR |= 0x02; - break; - case 2: - PSR |= 0x04; - break; - default: - break; - } - break; - case 6: /* AZ: Add Zoned */ - dlen2 = qbyte & 0x0f; - dlen1 = (qbyte >> 4) & 0xf; - dlen1 += dlen2; - r = add_zoned(BAR, dlen1+1, AAR, dlen2+1); - PSR &= 0xF0; - switch (r) { - case 0: - PSR |= 0x01; - break; - case 1: - PSR |= 0x02; - break; - case 2: - PSR |= 0x04; - break; - case 3: - PSR |= 0x08; - break; - default: - break; - } - break; - case 7: /* SZ: Subtract Zoned */ - dlen2 = qbyte & 0x0f; - dlen1 = (qbyte >> 4) & 0xf; - dlen1 += dlen2; - r = subtract_zoned(BAR, dlen1+1, AAR, dlen2+1); - PSR &= 0xF0; - switch (r) { - case 0: - PSR |= 0x01; - break; - case 1: - PSR |= 0x02; - break; - case 2: - PSR |= 0x04; - break; - case 3: - PSR |= 0x08; - break; - default: - break; - } - break; - case 8: /* MVX: Move Hex */ - op1 = GetMem(BAR); - op2 = GetMem(AAR); - switch (qbyte) { - case 0: /* Zone to zone */ - op1 = (op1 & 0x0F) | (op2 & 0xF0); - break; - case 1: /* Numeric to zone */ - op1 = (op1 & 0x0F) | (op2 << 4); - break; - case 2: /* Zone to numeric */ - op1 = (op1 & 0xF0) | (op2 >> 4); - break; - case 3: /* Numeric to numeric */ - op1 = (op1 & 0xF0) | (op2 & 0x0F); - break; - default: - reason = STOP_INVQ; - break; - } - PutMem(BAR, op1); - break; - case 0xa: /* ED: Edit */ - zero = 1; - PSR &= 0xF8; - IR = GetMem(AAR); - if ((IR & 0xf0) != 0xF0) - PSR |= 0x02; - else - PSR |= 0x04; - while (qbyte > -1) { - op2 = GetMem(AAR); - op1 = GetMem(BAR); - if (op1 == 0x20) { - op2 |= 0xf0; - PutMem(BAR, op2); - AAR--; - if (op2 != 0xF0) zero = 0; - } - BAR--; - qbyte--; - } - if (zero) - PSR |= 0x01; - break; - case 0xb: /* ITC: Insert and Test Chars */ - op2 = GetMem(AAR); - while (qbyte > -1) { - op1 = GetMem(BAR); - if (op1 >= 0xF1 && op1 <= 0xF9) - break; - PutMem(BAR, op2); - BAR++; - qbyte--; - } - ARR[level] = BAR; - break; - case 0xc: /* MVC: Move Characters */ - while (qbyte > -1) { - PutMem(BAR, GetMem(AAR)); - BAR--; - AAR--; - qbyte--; - } - break; - case 0xd: /* CLC: Compare Characters */ - PSR &= 0xF8; - i = BAR = BAR - qbyte; - j = AAR = AAR - qbyte; - while (qbyte > -1) { - if (GetMem(i) > GetMem(j)) { - PSR |= 0x04; - break; - } - if (GetMem(i) < GetMem(j)) { - PSR |= 0x02; - break; - } - i++; - j++; - qbyte--; - } - if (qbyte == -1) - PSR |= 0x01; - break; - case 0xe: /* ALC: Add Logical Characters */ - carry = 0; - zero = 1; - while (qbyte > -1) { - IR = GetMem(BAR) + GetMem(AAR) + carry; - if (IR & 0x100) - carry = 1; - else - carry = 0; - if ((IR & 0xFF) != 0) zero = 0; /* HJS mod */ - PutMem(BAR,(IR & 0xFF)); - BAR--; - AAR--; - qbyte--; - } - PSR &= 0xD8; - if (zero) - PSR |= 0x01; /* Equal */ - if (!zero && !carry) - PSR |= 0x02; /* Low */ - if (!zero && carry) - PSR |= 0x04; /* High */ - if (carry) - PSR |= 0x20; /* Overflow */ - break; - case 0xf: /* SLC: Subtract Logical Characters */ - carry = 1; - zero = 1; - while (qbyte > -1) { - IR = GetMem(BAR) + (0xFF - GetMem(AAR)) + carry; - if (IR & 0x100) - carry = 1; - else - carry = 0; - if ((IR & 0xFF) != 0) zero = 0; /* HJS mod */ - PutMem(BAR,(IR & 0xFF)); - BAR--; - AAR--; - qbyte--; - } - PSR &= 0xF8; - if (zero) - PSR |= 0x01; /* Equal */ - if (!zero && !carry) - PSR |= 0x02; /* Low */ - if (!zero && carry) - PSR |= 0x04; /* High */ - break; - default: - reason = STOP_INVOP; - break; - } - IAR[level] = PC; - continue; - break; - case 0x30: - case 0x70: - case 0xb0: - switch (opcode) { - case 0: /* SNS: Sense I/O */ - devno = (qbyte >> 4) & 0x0f; - devm = (qbyte >> 3) & 0x01; - devn = qbyte & 0x07; - i = dev_table[devno].routine(3, devm, devn, rbyte); - PutMem(BAR, i & 0xff); - BAR--; - PutMem(BAR, (i >> 8) & 0xff); - reason = (i >> 16) & 0xffff; - break; - case 1: /* LIO: Load I/O */ - devno = (qbyte >> 4) & 0x0f; - devm = (qbyte >> 3) & 0x01; - devn = qbyte & 0x07; - op1 = GetMem(BAR); - BAR--; - op1 |= (GetMem(BAR) << 8) & 0xff00; - reason = dev_table[devno].routine(1, devm, devn, op1); - break; - case 4: /* ST: Store Register */ - switch (qbyte) { - case 0x01: - PutMem(BAR, XR1 & 0xff); - BAR--; - PutMem(BAR, (XR1 >> 8) & 0xff); - break; - case 0x02: - PutMem(BAR, XR2 & 0xff); - BAR--; - PutMem(BAR, (XR2 >> 8) & 0xff); - break; - case 0x04: - PutMem(BAR, PSR & 0xFF); - BAR--; - PutMem(BAR, 0); /* LCRR, not imp. */ - break; - case 0x08: - PutMem(BAR, ARR[level] & 0xff); - BAR--; - PutMem(BAR, (ARR[level] >> 8) & 0xff); - break; - case 0x10: - PutMem(BAR, IAR[level] & 0xff); - BAR--; - PutMem(BAR, (IAR[level] >> 8) & 0xff); - break; - case 0x20: - PutMem(BAR, IAR[8] & 0xff); - BAR--; - PutMem(BAR, (IAR[8] >> 8) & 0xff); - break; - case 0x40: - PutMem(BAR, IAR[9] & 0xff); - BAR--; - PutMem(BAR, (IAR[9] >> 8) & 0xff); - break; - case 0x80: - PutMem(BAR, IAR[0] & 0xff); - BAR--; - PutMem(BAR, (IAR[0] >> 8) & 0xff); - break; - case 0x81: - PutMem(BAR, IAR[7] & 0xff); - BAR--; - PutMem(BAR, (IAR[7] >> 8) & 0xff); - break; - case 0x82: - PutMem(BAR, IAR[6] & 0xff); - BAR--; - PutMem(BAR, (IAR[6] >> 8) & 0xff); - break; - case 0x84: - PutMem(BAR, IAR[5] & 0xff); - BAR--; - PutMem(BAR, (IAR[5] >> 8) & 0xff); - break; - case 0x88: - PutMem(BAR, IAR[4] & 0xff); - BAR--; - PutMem(BAR, (IAR[4] >> 8) & 0xff); - break; - case 0x90: - PutMem(BAR, IAR[3] & 0xff); - BAR--; - PutMem(BAR, (IAR[3] >> 8) & 0xff); - break; - case 0xA0: - PutMem(BAR, IAR[2] & 0xff); - BAR--; - PutMem(BAR, (IAR[2] >> 8) & 0xff); - break; - case 0xC0: - PutMem(BAR, IAR[1] & 0xff); - BAR--; - PutMem(BAR, (IAR[1] >> 8) & 0xff); - break; - default: - reason = STOP_INVQ; - break; - } - break; - case 5: /* L: Load Register */ - switch (qbyte) { - case 0x01: - XR1 = GetMem(BAR) & 0xff; - BAR--; - XR1 |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x02: - XR2 = GetMem(BAR) & 0xff; - BAR--; - XR2 |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x04: - PSR = GetMem(BAR) & 0xff; - BAR--; - break; - case 0x08: - ARR[level] = GetMem(BAR) & 0xff; - BAR--; - ARR[level] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x10: - IAR[level] = GetMem(BAR) & 0xff; - BAR--; - IAR[level] |= (GetMem(BAR) << 8) & 0xff00; - PC = IAR[level]; - break; - case 0x20: - IAR[8] = GetMem(BAR) & 0xff; - BAR--; - IAR[8] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x40: - IAR[9] = GetMem(BAR) & 0xff; - BAR--; - IAR[9] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x80: - IAR[0] = GetMem(BAR) & 0xff; - BAR--; - IAR[0] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x81: - IAR[7] = GetMem(BAR) & 0xff; - BAR--; - IAR[7] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x82: - IAR[6] = GetMem(BAR) & 0xff; - BAR--; - IAR[6] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x84: - IAR[5] = GetMem(BAR) & 0xff; - BAR--; - IAR[5] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x88: - IAR[4] = GetMem(BAR) & 0xff; - BAR--; - IAR[4] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0x90: - IAR[3] = GetMem(BAR) & 0xff; - BAR--; - IAR[3] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0xA0: - IAR[2] = GetMem(BAR) & 0xff; - BAR--; - IAR[2] |= (GetMem(BAR) << 8) & 0xff00; - break; - case 0xC0: - IAR[1] = GetMem(BAR) & 0xff; - BAR--; - IAR[1] |= (GetMem(BAR) << 8) & 0xff00; - break; - default: - reason = STOP_INVQ; - break; - } - break; - case 6: /* A: Add to Register */ - IR = GetMem(BAR) & 0x00ff; - BAR--; - IR |= (GetMem(BAR) << 8) & 0xff00; - switch (qbyte) { - case 0x01: - IR += XR1; - XR1 = IR & AMASK; - break; - case 0x02: - IR += XR2; - XR2 = IR & AMASK; - break; - case 0x04: - IR += PSR; - PSR = IR & AMASK; - break; - case 0x08: - IR += ARR[level]; - ARR[level] = IR & AMASK; - break; - case 0x10: - IR += IAR[level]; - IAR[level] = IR & AMASK; - break; - case 0x20: - IR += IAR[8]; - IAR[8] = IR & AMASK; - break; - case 0x40: - IR += IAR[9]; - IAR[9] = IR & AMASK; - break; - case 0x80: - IR += IAR[0]; - IAR[0] = IR & AMASK; - break; - case 0x81: - IR += IAR[7]; - IAR[7] = IR & AMASK; - break; - case 0x82: - IR += IAR[6]; - IAR[6] = IR & AMASK; - break; - case 0x84: - IR += IAR[5]; - IAR[5] = IR & AMASK; - break; - case 0x88: - IR += IAR[4]; - IAR[4] = IR & AMASK; - break; - case 0x90: - IR += IAR[3]; - IAR[3] = IR & AMASK; - break; - case 0xA0: - IR += IAR[2]; - IAR[2] = IR & AMASK; - break; - case 0xC0: - IR += IAR[1]; - IAR[1] = IR & AMASK; - break; - default: - reason = STOP_INVQ; - break; - } - PSR &= 0xD8; - if ((IR & 0xffff) == 0) - PSR |= 0x01; /* Zero */ - if ((IR & 0xffff) != 0 && !(IR & 0x10000)) - PSR |= 0x02; /* Low */ - if ((IR & 0xffff) != 0 && (IR & 0x10000)) - PSR |= 0x04; /* High */ - if ((IR & 0x10000)) - PSR |= 0x20; /* Bin overflow */ - break; - case 8: /* TBN: Test Bits On */ - IR = GetMem(BAR); - PSR &= 0xFF; - if ((IR & qbyte) != qbyte) - PSR |= 0x10; - break; - case 9: /* TBF: Test Bits Off */ - IR = GetMem(BAR); - PSR &= 0xFF; - if ((IR & qbyte)) - PSR |= 0x10; - break; - case 0xa: /* SBN: Set Bits On */ - IR = GetMem(BAR); - IR |= qbyte; - PutMem(BAR, IR); - break; - case 0xb: /* SBF: Set Bits Off */ - IR = GetMem(BAR); - IR &= ~qbyte; - PutMem(BAR, IR); - break; - case 0xc: /* MVI: Move Immediate */ - PutMem(BAR, qbyte); - break; - case 0xd: /* CLI: Compare Immediate */ - PSR = compare(GetMem(BAR), qbyte, PSR); - break; - default: - reason = STOP_INVOP; - break; - } - IAR[level] = PC; - continue; - break; - case 0xc0: - case 0xd0: - case 0xe0: - switch (opcode) { - case 0: /* BC: Branch on Condition */ - ARR[level] = AAR & AMASK; - if (condition(qbyte) == 1) { - IR = ARR[level]; - ARR[level] = PC & AMASK; - PC = IR; - } - break; - case 1: /* TIO: Test I/O */ - devno = (qbyte >> 4) & 0x0f; - devm = (qbyte >> 3) & 0x01; - devn = qbyte & 0x07; - op1 = dev_table[devno].routine(2, devm, devn, rbyte); - if (op1 & 0x01) { - ARR[level] = AAR & AMASK; - IR = ARR[level]; - ARR[level] = PC & AMASK; - PC = IR; - } - reason = (op1 >> 16) & 0xffff; - break; - case 2: /* LA: Load Address */ - switch (qbyte) { - case 1: - XR1 = AAR; - break; - case 2: - XR2 = AAR; - break; - default: - reason = STOP_INVQ; - break; - } - break; - default: - reason = STOP_INVOP; - break; - } /* switch (opcode) */ - IAR[level] = PC; - continue; - - default: - reason = STOP_INVOP; - break; -} /* switch (opaddr) */ - -} /* end while (reason == 0) */ - -/* Simulation halted */ - -saved_PC = PC; -return reason; -} - -/* On models 4-12, these memory functions could be inline, but - on a model 15 with ATU address mapping must be performed so - they are in functions here for future expansion. -*/ - -/* Fetch a byte from memory */ - -int32 GetMem(int32 addr) -{ - return M[addr] & 0xff; -} - -/* Place a byte in memory */ - -int32 PutMem(int32 addr, int32 data) -{ - M[addr] = data & 0xff; - return 0; -} - -/* Check the condition register against the qbyte and return 1 if true */ - -static int32 condition(int32 qbyte) -{ - int32 r = 0, t, q; - t = (qbyte & 0xf0) >> 4; - q = qbyte & 0x0f; - if (qbyte & 0x80) { /* True if any condition tested = 1*/ - if (((qbyte & 0x3f) & PSR) != 0) r = 1; - } else { /* True if all conditions tested = 0 */ - if (((qbyte & 0x3f) & PSR) == 0) r = 1; - } - /* these bits reset by a test */ - if (qbyte & 0x10) - PSR &= 0xEF; /* Reset test false if used */ - if (qbyte & 0x08) - PSR &= 0xF7; /* Reset decimal overflow if tested */ - if (qbyte == 0x00) - r = 1; /* unconditional branch */ - if (qbyte == 0x80) - r = 0; /* force no branch */ - if (t >=0 && t < 8 && (q == 7 || q == 0xf)) - r = 0; /* no-op */ - if (t > 7 && t < 0x10 && (q == 7 || q == 0xf)) - r = 1; /* Force branch */ -return (r); -} -/* Given operand 1 and operand 2, compares the two and returns - the System/3 condition register bits appropriately, given the - condition register initial state in parameter 3 -*/ - -static int32 compare(int32 byte1, int32 byte2, int32 cond) -{ - int32 r; - - r = cond & 0xF8; /* mask off all but unaffected bits 2,3,4 */ - if (byte1 == byte2) - r |= 0x01; /* set equal bit */ - if (byte1 < byte2) - r |= 0x02; /* set less-than bit */ - if (byte1 > byte2) - r |= 0x04; /* set greater than bit */ - return r; -} - -/*-------------------------------------------------------------------*/ -/* Add two zoned decimal operands */ -/* */ -/* Input: */ -/* addr1 Logical address of packed decimal storage operand 1 */ -/* len1 Length minus one of storage operand 1 (range 0-15) */ -/* addr2 Logical address of packed decimal storage operand 2 */ -/* len2 Length minus one of storage operand 2 (range 0-15) */ -/* Output: */ -/* The return value is the condition code: */ -/* 0=result zero, 1=result -ve, 2=result +ve, 3=overflow */ -/* */ -/* A program check may be generated if either logical address */ -/* causes an addressing, translation, or fetch protection */ -/* exception, or if either operand causes a data exception */ -/* because of invalid decimal digits or sign, or if the */ -/* first operand is store protected. Depending on the PSW */ -/* program mask, decimal overflow may cause a program check. */ -/*-------------------------------------------------------------------*/ -int32 add_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2) -{ -int cc; /* Condition code */ -uint8 dec1[MAX_DECIMAL_DIGITS]; /* Work area for operand 1 */ -uint8 dec2[MAX_DECIMAL_DIGITS]; /* Work area for operand 2 */ -uint8 dec3[MAX_DECIMAL_DIGITS]; /* Work area for result */ -int count1, count2, count3; /* Significant digit counters*/ -int sign1, sign2, sign3; /* Sign of operands & result */ - - /* Load operands into work areas */ - load_decimal (addr1, len1, dec1, &count1, &sign1); - load_decimal (addr2, len2, dec2, &count2, &sign2); - - /* Add or subtract operand values */ - if (count2 == 0) - { - /* If second operand is zero then result is first operand */ - memcpy (dec3, dec1, MAX_DECIMAL_DIGITS); - count3 = count1; - sign3 = sign1; - } - else if (count1 == 0) - { - /* If first operand is zero then result is second operand */ - memcpy (dec3, dec2, MAX_DECIMAL_DIGITS); - count3 = count2; - sign3 = sign2; - } - else if (sign1 == sign2) - { - /* If signs are equal then add operands */ - add_decimal (dec1, dec2, dec3, &count3); - sign3 = sign1; - } - else - { - /* If signs are opposite then subtract operands */ - subtract_decimal (dec1, dec2, dec3, &count3, &sign3); - if (sign1 < 0) sign3 = -sign3; - } - - /* Set condition code */ - cc = (count3 == 0) ? 0 : (sign3 < 1) ? 1 : 2; - - /* Overflow if result exceeds first operand length */ - if (count3 > len1) - cc = 3; - - /* Set positive sign if result is zero */ - if (count3 == 0) - sign3 = 1; - - /* Store result into first operand location */ - store_decimal (addr1, len1, dec3, sign3); - - /* Return condition code */ - return cc; - -} /* end function add_packed */ - -/*-------------------------------------------------------------------*/ -/* Subtract two zoned decimal operands */ -/* */ -/* Input: */ -/* addr1 Logical address of packed decimal storage operand 1 */ -/* len1 Length minus one of storage operand 1 (range 0-15) */ -/* addr2 Logical address of packed decimal storage operand 2 */ -/* len2 Length minus one of storage operand 2 (range 0-15) */ -/* Output: */ -/* The return value is the condition code: */ -/* 0=result zero, 1=result -ve, 2=result +ve, 3=overflow */ -/* */ -/* A program check may be generated if either logical address */ -/* causes an addressing, translation, or fetch protection */ -/* exception, or if either operand causes a data exception */ -/* because of invalid decimal digits or sign, or if the */ -/* first operand is store protected. Depending on the PSW */ -/* program mask, decimal overflow may cause a program check. */ -/*-------------------------------------------------------------------*/ -int32 subtract_zoned (int32 addr1, int32 len1, int32 addr2, int32 len2) -{ -int cc; /* Condition code */ -uint8 dec1[MAX_DECIMAL_DIGITS]; /* Work area for operand 1 */ -uint8 dec2[MAX_DECIMAL_DIGITS]; /* Work area for operand 2 */ -uint8 dec3[MAX_DECIMAL_DIGITS]; /* Work area for result */ -int count1, count2, count3; /* Significant digit counters*/ -int sign1, sign2, sign3; /* Sign of operands & result */ - - /* Load operands into work areas */ - load_decimal (addr1, len1, dec1, &count1, &sign1); - load_decimal (addr2, len2, dec2, &count2, &sign2); - - /* Add or subtract operand values */ - if (count2 == 0) - { - /* If second operand is zero then result is first operand */ - memcpy (dec3, dec1, MAX_DECIMAL_DIGITS); - count3 = count1; - sign3 = sign1; - } - else if (count1 == 0) - { - /* If first operand is zero then result is -second operand */ - memcpy (dec3, dec2, MAX_DECIMAL_DIGITS); - count3 = count2; - sign3 = -sign2; - } - else if (sign1 != sign2) - { - /* If signs are opposite then add operands */ - add_decimal (dec1, dec2, dec3, &count3); - sign3 = sign1; - } - else - { - /* If signs are equal then subtract operands */ - subtract_decimal (dec1, dec2, dec3, &count3, &sign3); - if (sign1 < 0) sign3 = -sign3; - } - - /* Set condition code */ - cc = (count3 == 0) ? 0 : (sign3 < 1) ? 1 : 2; - - /* Overflow if result exceeds first operand length */ - if (count3 > len1) - cc = 3; - - /* Set positive sign if result is zero */ - if (count3 == 0) - sign3 = 1; - - /* Store result into first operand location */ - store_decimal (addr1, len1, dec3, sign3); - - /* Return condition code */ - return cc; - -} /* end function subtract_packed */ - - -/*-------------------------------------------------------------------*/ -/* Add two decimal byte strings as unsigned decimal numbers */ -/* */ -/* Input: */ -/* dec1 A 31-byte area containing the decimal digits of */ -/* the first operand. Each byte contains one decimal */ -/* digit in the low-order 4 bits of the byte. */ -/* dec2 A 31-byte area containing the decimal digits of */ -/* the second operand. Each byte contains one decimal */ -/* digit in the low-order 4 bits of the byte. */ -/* Output: */ -/* result Points to a 31-byte area to contain the result */ -/* digits. One decimal digit is placed in the low-order */ -/* 4 bits of each byte. */ -/* count Points to an integer to receive the number of */ -/* digits in the result excluding leading zeroes. */ -/* This field is set to zero if the result is all zero, */ -/* or to MAX_DECIMAL_DIGITS+1 if overflow occurred. */ -/*-------------------------------------------------------------------*/ -static void add_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count) -{ -int d; /* Decimal digit */ -int i; /* Array subscript */ -int n = 0; /* Significant digit counter */ -int carry = 0; /* Carry indicator */ - - /* Add digits from right to left */ - for (i = MAX_DECIMAL_DIGITS - 1; i >= 0; i--) - { - /* Add digits from first and second operands */ - d = dec1[i] + dec2[i] + carry; - - /* Check for carry into next digit */ - if (d > 9) { - d -= 10; - carry = 1; - } else { - carry = 0; - } - - /* Check for significant digit */ - if (d != 0) - n = MAX_DECIMAL_DIGITS - i; - - /* Store digit in result */ - result[i] = d; - - } /* end for */ - - /* Check for carry out of leftmost digit */ - if (carry) - n = MAX_DECIMAL_DIGITS + 1; - - /* Return significant digit counter */ - *count = n; - -} /* end function add_decimal */ - -/*-------------------------------------------------------------------*/ -/* Subtract two decimal byte strings as unsigned decimal numbers */ -/* */ -/* Input: */ -/* dec1 A 31-byte area containing the decimal digits of */ -/* the first operand. Each byte contains one decimal */ -/* digit in the low-order 4 bits of the byte. */ -/* dec2 A 31-byte area containing the decimal digits of */ -/* the second operand. Each byte contains one decimal */ -/* digit in the low-order 4 bits of the byte. */ -/* Output: */ -/* result Points to a 31-byte area to contain the result */ -/* digits. One decimal digit is placed in the low-order */ -/* 4 bits of each byte. */ -/* count Points to an integer to receive the number of */ -/* digits in the result excluding leading zeroes. */ -/* This field is set to zero if the result is all zero. */ -/* sign -1 if the result is negative (operand2 > operand1) */ -/* +1 if the result is positive (operand2 <= operand1) */ -/*-------------------------------------------------------------------*/ -static void subtract_decimal (uint8 *dec1, uint8 *dec2, uint8 *result, int *count, int *sign) -{ -int d; /* Decimal digit */ -int i; /* Array subscript */ -int n = 0; /* Significant digit counter */ -int borrow = 0; /* Borrow indicator */ -int rc; /* Return code */ -uint8 *higher; /* -> Higher value operand */ -uint8 *lower; /* -> Lower value operand */ - - /* Compare digits to find which operand has higher numeric value */ - rc = memcmp (dec1, dec2, MAX_DECIMAL_DIGITS); - - /* Return positive zero result if both operands are equal */ - if (rc == 0) { - memset (result, 0, MAX_DECIMAL_DIGITS); - *count = 0; - *sign = +1; - return; - } - - /* Point to higher and lower value operands and set sign */ - if (rc > 0) { - higher = dec1; - lower = dec2; - *sign = +1; - } else { - lower = dec1; - higher = dec2; - *sign = -1; - } - - /* Subtract digits from right to left */ - for (i = MAX_DECIMAL_DIGITS - 1; i >= 0; i--) - { - /* Subtract lower operand digit from higher operand digit */ - d = higher[i] - lower[i] - borrow; - - /* Check for borrow from next digit */ - if (d < 0) { - d += 10; - borrow = 1; - } else { - borrow = 0; - } - - /* Check for significant digit */ - if (d != 0) - n = MAX_DECIMAL_DIGITS - i; - - /* Store digit in result */ - result[i] = d; - - } /* end for */ - - /* Return significant digit counter */ - *count = n; - -} /* end function subtract_decimal */ - -/*-------------------------------------------------------------------*/ -/* Load a zoned decimal storage operand into a decimal byte string */ -/* */ -/* Input: */ -/* addr Logical address of zoned decimal storage operand */ -/* len Length minus one of storage operand (range 0-15) */ -/* Output: */ -/* result Points to a 31-byte area into which the decimal */ -/* digits are loaded. One decimal digit is loaded */ -/* into the low-order 4 bits of each byte, and the */ -/* result is padded to the left with high-order zeroes */ -/* if the storage operand contains less than 31 digits. */ -/* count Points to an integer to receive the number of */ -/* digits in the result excluding leading zeroes. */ -/* This field is set to zero if the result is all zero. */ -/* sign Points to an integer which will be set to -1 if a */ -/* negative sign was loaded from the operand, or +1 if */ -/* a positive sign was loaded from the operand. */ -/* */ -/* A program check may be generated if the logical address */ -/* causes an addressing, translation, or fetch protection */ -/* exception, or if the operand causes a data exception */ -/* because of invalid decimal digits or sign. */ -/*-------------------------------------------------------------------*/ -static void load_decimal (int32 addr, int32 len, uint8 *result, int *count, int *sign) -{ -int h; /* Hexadecimal digit */ -int i, j; /* Array subscripts */ -int n; /* Significant digit counter */ - - if ((GetMem(addr) & 0xf0) == 0xD0) - *sign = -1; - else - *sign = 1; - j = len; - for (i = MAX_DECIMAL_DIGITS; i > -1; i--) { - if (j) { - h = GetMem(addr) & 0x0f; - addr--; - j--; - } else { - h = 0; - } - result [i-1] = h; - if (h > 0) n = i; - } - *count = 32 - n; - -} /* end function load_decimal */ - -/*-------------------------------------------------------------------*/ -/* Store decimal byte string into packed decimal storage operand */ -/* */ -/* Input: */ -/* addr Logical address of packed decimal storage operand */ -/* len Length minus one of storage operand (range 0-15) */ -/* dec A 31-byte area containing the decimal digits to be */ -/* stored. Each byte contains one decimal digit in */ -/* the low-order 4 bits of the byte. */ -/* sign -1 if a negative sign is to be stored, or +1 if a */ -/* positive sign is to be stored. */ -/* */ -/* A program check may be generated if the logical address */ -/* causes an addressing, translation, or protection exception. */ -/*-------------------------------------------------------------------*/ -static void store_decimal (int32 addr, int32 len, uint8 *dec, int sign) -{ -int i, j, a; /* Array subscripts */ - - j = len; - a = addr; - for (i = MAX_DECIMAL_DIGITS; i > -1; i--) { - if (j) { - PutMem(a, (dec[i-1] | 0xf0)); - a--; - j--; - } else { - break; - } - } - if (sign == -1) { - PutMem(addr, (GetMem(addr) & 0x0f)); - PutMem(addr, (GetMem(addr) | 0xf0)); - } - -} /* end function store_decimal */ - -/* CPU Device Control */ - -int32 cpu (int32 op, int32 m, int32 n, int32 data) -{ - int32 iodata = 0; - - switch (op) { - case 0x00: /* Start IO */ - return SCPE_OK; - case 0x01: /* LIO */ - return SCPE_OK; - case 0x02: /* TIO */ - break; - case 0x03: /* SNS */ - /* SNS CPU gets the data switches */ - iodata = SR; - break; - case 0x04: /* APL */ - break; - default: - break; - } - return ((SCPE_OK << 16) | iodata); -} - - - -/* Null device */ - -int32 nulldev (int32 opcode, int32 m, int32 n, int32 data) -{ -if (opcode == 1) - return SCPE_OK; /* Ok to LIO unconfigured devices? */ -return STOP_INVDEV; -} - -/* Reset routine */ - -t_stat cpu_reset (DEVICE *dptr) -{ -int_req = 0; -level = 8; -sim_brk_types = sim_brk_dflt = SWMASK ('E'); -return SCPE_OK; -} - -/* Memory examine */ - -t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) -{ -if (addr >= MEMSIZE) return SCPE_NXM; -if (vptr != NULL) *vptr = M[addr] & 0xff; -return SCPE_OK; -} - -/* Memory deposit */ - -t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw) -{ -if (addr >= MEMSIZE) return SCPE_NXM; -M[addr] = val & 0xff; -return SCPE_OK; -} - -t_stat cpu_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) -{ -int32 mc = 0; -uint32 i; - -if ((val <= 0) || (val > MAXMEMSIZE) || ((val & 07777) != 0)) - return SCPE_ARG; -for (i = val; i < MEMSIZE; i++) mc = mc | M[i]; -if ((mc != 0) && (!get_yn ("Really truncate memory [N]?", FALSE))) - return SCPE_OK; -MEMSIZE = val; -for (i = MEMSIZE; i < MAXMEMSIZE; i++) M[i] = 0; -return SCPE_OK; -} - -t_stat cpu_boot (int32 unitno, DEVICE *dptr) -{ -level = 8; -IAR[8] = 0; -return SCPE_OK; -} diff --git a/S3/s3_defs.h b/S3/s3_defs.h deleted file mode 100644 index 3bb0a93d..00000000 --- a/S3/s3_defs.h +++ /dev/null @@ -1,94 +0,0 @@ -/* s3_defs.h: IBM System/3 simulator definitions - - Copyright (c) 2001-2005, Charles E. Owen - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. -*/ - -#include "sim_defs.h" /* simulator defns */ - -/* Simulator stop codes */ - -#define STOP_RSRV 1 /* must be 1 */ -#define STOP_HALT 2 /* HALT */ -#define STOP_IBKPT 3 /* breakpoint */ -#define STOP_INVOP 4 /* program check - invalid op */ -#define STOP_INVQ 5 /* Prog check - invalid Q */ -#define STOP_INVADDR 6 /* Prog check - invalid addr */ -#define STOP_INVDEV 7 /* Prog check - invalid dev cmd */ -#define STOP_NOCD 8 /* ATTN card reader */ -#define RESET_INTERRUPT 77 /* special return from SIO */ - -/* Memory */ - -#define MAXMEMSIZE 65536 /* max memory size */ -#define AMASK (MAXMEMSIZE - 1) /* logical addr mask */ -#define PAMASK (MAXMEMSIZE - 1) /* physical addr mask */ -#define MEMSIZE (cpu_unit.capac) /* actual memory size */ - -#define MAX_DECIMAL_DIGITS 31 /* max size of a decimal number */ -#define CDR_WIDTH 80 /* Max card size */ -#define CDP_WIDTH 80 /* Punch width */ -#define LPT_WIDTH 132 -#define CCT_LNT 132 - -#define DSK_SECTSIZE 256 /* Sector length */ -#define DSK_CYLSIZE 256*48 /* Cylinder length */ - -/* I/O structure - - The I/O structure is tied together by dev_table, indexed by - the device number. Each entry in dev_table consists of - - level Interrupt level for device (0-7) - priority Priority for device (1-8) - routine IOT action routine -*/ - -struct ndev { - int32 level; /* interrupt level */ - int32 pri; /* Device priority */ - int32 (*routine)(int32, int32, int32, int32); /* dispatch routine */ -}; - -/* Structure to define operation codes */ - -struct opdef { - char op[6]; /* Mnemonic for op */ - int32 opmask; /* Bits set on in opcode */ - int32 q; /* Qbyte */ - int32 form; /* Forms are: - 0 - 1-byte hex operand - 1 - 1-byte register addr, A-Addr - 2 - A-addr,B-addr,Qbyte - 3 - A-addr,Qbyte - 4 - da,m,n - 5 - da,m,n,cc - 6 - da,m,n,A-addr - 7 - 1-address implict Q - 8 - 2-address implict Q */ - int32 group; /* Group Code: - 0 - Command Format (0xFx) - 1 - 1-address A (0xx) - 2 - 2-address (0x<0,1,2,4,5,6,8,9,A>x) - 3 - 1-address B (0x<3,7,B>x) */ -}; diff --git a/S3/s3_disk.c b/S3/s3_disk.c deleted file mode 100644 index 1faea2e5..00000000 --- a/S3/s3_disk.c +++ /dev/null @@ -1,792 +0,0 @@ -/* s3_disk.c: IBM 5444 Disk Drives - - Copyright (c) 2001-2005, Charles E. Owen - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. - - r1 Removeable disk 1 - f1 Fixed disk 1 - r2 Removeable disk 2 - f2 Fixed disk 2 - - 25-Apr-03 RMS Revised for extended file support - 08-Oct-02 RMS Added impossible function catcher -*/ - -#include "s3_defs.h" -#include - -extern uint8 M[]; -extern int32 IAR[], level; -extern FILE *trace; -extern int32 debug_reg; -char dbuf[DSK_SECTSIZE]; /* Disk buffer */ -int32 dsk (int32 disk, int32 op, int32 m, int32 n, int32 data); -int32 read_sector(UNIT *uptr, char *dbuf, int32 sect); -int32 write_sector(UNIT *uptr, char *dbuf, int32 sect); -t_stat r1_svc (UNIT *uptr); -t_stat r1_boot (int32 unitno, DEVICE *dptr); -t_stat r1_attach (UNIT *uptr, char *cptr); -t_stat r1_reset (DEVICE *dptr); -t_stat f1_svc (UNIT *uptr); -t_stat f1_boot (int32 unitno, DEVICE *dptr); -t_stat f1_attach (UNIT *uptr, char *cptr); -t_stat f1_reset (DEVICE *dptr); -t_stat r2_svc (UNIT *uptr); -t_stat r2_boot (int32 unitno, DEVICE *dptr); -t_stat r2_attach (UNIT *uptr, char *cptr); -t_stat r2_reset (DEVICE *dptr); -t_stat f2_svc (UNIT *uptr); -t_stat f2_boot (int32 unitno, DEVICE *dptr); -t_stat f2_attach (UNIT *uptr, char *cptr); -t_stat f2_reset (DEVICE *dptr); -extern int32 GetMem(int32 addr); -extern int32 PutMem(int32 addr, int32 data); - -char opstr[5][5] = { "SIO", "LIO", "TIO", "SNS", "APL" }; - -int32 DDAR[2]; /* Data address register */ -int32 DCAR[2]; /* Disk Control Address Register */ -int32 diskerr[2] = { 0, 0 }; /* Error status */ -int32 notrdy[2] = { 0, 0 }; /* Not ready error */ -int32 seekbusy[2] = { 0, 0 }; /* Drive busy flags */ -int32 seekhead[2] = { 0, 0 }; /* Disk head 0,1 */ -int32 found[2] = { 0, 0 }; /* Scan found bit */ -int32 RIDsect[2] = { 0, 0 }; /* for Read ID */ - -/* Disk data structures - - xy_dev CDR descriptor - xy_unit CDR unit descriptor - xy_reg CDR register list - - x = F or R - y = 1 or 2 -*/ - -UNIT r1_unit = { UDATA (&r1_svc, UNIT_FIX+UNIT_ATTABLE, 0), 100 }; - -REG r1_reg[] = { - { FLDATA (NOTRDY, notrdy[0], 0) }, - { FLDATA (SEEK, seekbusy[0], 0) }, - { HRDATA (DAR, DDAR[0], 16) }, - { HRDATA (CAR, DCAR[0], 16) }, - { HRDATA (ERR, diskerr[0], 16) }, - { DRDATA (CYL, r1_unit.u3, 8) }, - { DRDATA (HEAD, seekhead[0], 8) }, - { DRDATA (POS, r1_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TIME, r1_unit.wait, 24), PV_LEFT }, - { BRDATA (BUF, dbuf, 8, 8, 256) }, - { NULL } -}; - -DEVICE r1_dev = { - "R1", &r1_unit, r1_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &r1_reset, - &r1_boot, &r1_attach, NULL -}; - -UNIT f1_unit = { UDATA (&f1_svc, UNIT_FIX+UNIT_ATTABLE, 0), 100 }; - -REG f1_reg[] = { - { FLDATA (NOTRDY, notrdy[0], 0) }, - { FLDATA (SEEK, seekbusy[0], 0) }, - { HRDATA (DAR, DDAR[0], 16) }, - { HRDATA (CAR, DCAR[0], 16) }, - { HRDATA (ERR, diskerr[0], 16) }, - { DRDATA (CYL, f1_unit.u3, 8) }, - { DRDATA (HEAD, seekhead[0], 8) }, - { DRDATA (POS, f1_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, f1_unit.wait, 24), PV_LEFT }, - { BRDATA (BUF, dbuf, 8, 8, 256) }, - { NULL } -}; - -DEVICE f1_dev = { - "F1", &f1_unit, f1_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &f1_reset, - &f1_boot, &f1_attach, NULL -}; - -UNIT r2_unit = { UDATA (&r2_svc, UNIT_FIX+UNIT_ATTABLE, 0), 100 }; - -REG r2_reg[] = { - { FLDATA (NOTRDY, notrdy[1], 0) }, - { FLDATA (SEEK, seekbusy[1], 0) }, - { HRDATA (DAR, DDAR[1], 16) }, - { HRDATA (CAR, DCAR[1], 16) }, - { HRDATA (ERR, diskerr[1], 16) }, - { DRDATA (CYL, r2_unit.u3, 8) }, - { DRDATA (HEAD, seekhead[1], 8) }, - { DRDATA (POS, r2_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, r2_unit.wait, 24), PV_LEFT }, - { BRDATA (BUF, dbuf, 8, 8, 256) }, - { NULL } -}; - -DEVICE r2_dev = { - "R2", &r2_unit, r2_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &r2_reset, - &r2_boot, &r2_attach, NULL -}; - -UNIT f2_unit = { UDATA (&f2_svc, UNIT_FIX+UNIT_ATTABLE, 0), 100 }; - -REG f2_reg[] = { - { FLDATA (NOTRDY, notrdy[1], 0) }, - { FLDATA (SEEK, seekbusy[1], 0) }, - { HRDATA (DAR, DDAR[1], 16) }, - { HRDATA (CAR, DCAR[1], 16) }, - { HRDATA (ERR, diskerr[1], 16) }, - { DRDATA (CYL, f2_unit.u3, 8) }, - { DRDATA (HEAD, seekhead[1], 8) }, - { DRDATA (POS, f2_unit.pos, 32), PV_LEFT }, - { DRDATA (TIME, f2_unit.wait, 24), PV_LEFT }, - { BRDATA (BUF, dbuf, 8, 8, 256) }, - { NULL } -}; - -DEVICE f2_dev = { - "F2", &f2_unit, f2_reg, NULL, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &f2_reset, - &f2_boot, &f2_attach, NULL -}; - -/* -------------------------------------------------------------------- */ - -/* 5444: master routines */ - -int32 dsk1 (int32 op, int32 m, int32 n, int32 data) -{ - int32 r; - - r = dsk(0, op, m, n, data); - return (r); -} - -int32 dsk2 (int32 op, int32 m, int32 n, int32 data) -{ - int32 r; - - r = dsk(1, op, m, n, data); - return (r); -} - -/* 5444: operational routine */ - -int32 dsk (int32 disk, int32 op, int32 m, int32 n, int32 data) -{ - int32 iodata, i, j, u, sect, nsects, addr, r, c, res; - int32 F, C, S, N, usave; - UNIT *uptr; - - u = m; - if (disk == 1) u += 2; - F = GetMem(DCAR[disk]+0); /* Flag bits */ - C = GetMem(DCAR[disk]+1); /* Cylinder */ - S = GetMem(DCAR[disk]+2); /* Sector */ - N = GetMem(DCAR[disk]+3); /* Number of sectors */ - switch (u) { - case 0: - uptr = r1_dev.units; - break; - case 1: - uptr = f1_dev.units; - break; - case 2: - uptr = r2_dev.units; - break; - case 3: - uptr = f2_dev.units; - break; - default: - break; - } - if (debug_reg & 0x02) - fprintf(trace, "==> %04X %s %01X,%d,%04X DAR=%04X CAR=%04X C=%02X, S=%02X, N=%02X\n", - IAR[level], - opstr[op], - m, n, data, - DDAR[disk], - DCAR[disk], - C, S, N); - - switch (op) { - - /* SIO 5444 */ - case 0: - if ((uptr->flags & UNIT_ATT) == 0) - return SCPE_UNATT; - diskerr[disk] = 0; /* SIO resets errors */ - found[disk] = 0; /* ... and found bit */ - iodata = 0; - switch (n) { - case 0x00: /* Seek */ - if (S & 0x80) - seekhead[disk] = 1; - else - seekhead[disk] = 0; - if (S & 1) { - uptr -> u3 += N; - } else { - uptr -> u3 -= N; - } - if (uptr -> u3 < 0) - uptr -> u3 = 0; - if (uptr -> u3 > 203) { - uptr -> u3 = 0; - diskerr[disk] |= 0x0100; - if (debug_reg & 0x02) - fprintf(trace, "==> Seek Past End of Disk\n"); - } - - /*sim_activate(uptr, uptr -> wait);*/ - sim_activate(uptr, 1); - - /* Seek arms are the same for both disks on a drive: - update the other arm */ - - usave = uptr -> u3; - if (u == 0) uptr = f1_dev.units; - if (u == 1) uptr = r1_dev.units; - if (u == 2) uptr = f2_dev.units; - if (u == 3) uptr = r2_dev.units; - uptr -> u3 = usave; - - seekbusy[disk] = 1; - iodata = SCPE_OK; - break; - - case 0x01: /* Read */ - switch (data) { - case 0: /* Read data */ - sect = (S >> 2) & 0x3F; - nsects = N + 1; - addr = DDAR[disk]; - - for (i = 0; i < nsects; i++) { - r = read_sector(uptr, dbuf, sect); - if (r != 1 || uptr->u3 != C) { - diskerr[disk] |= 0x0800; - break; - } - for (j = 0; j < DSK_SECTSIZE; j++) { - PutMem(addr, dbuf[j]); - addr++; - } - - if (sect == 55) { /* HJS MODS */ - S = sect; - N = nsects - i - 2; - if (N > -1) diskerr[disk] |= 0x0020; /* end of cyl. */ - DDAR[disk] = addr & 0xFFFF; /* HJS mod */ - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - sim_activate(uptr, 1); - iodata = SCPE_OK; - break; - } - - sect++; - S = sect - 1; - N = nsects - i - 2; - if (sect == 24) - sect = 32; - } - DDAR[disk] = addr & 0xFFFF; /* HJS mod */ - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - /*sim_activate(uptr, uptr -> wait);*/ - sim_activate(uptr, 1); - iodata = SCPE_OK; - break; - case 1: /* Read ID */ - if (uptr -> u3 > 0 && uptr -> u3 < 4) - PutMem(DCAR[disk], 1); - else - PutMem(DCAR[disk], 0); - PutMem(DCAR[disk]+1, uptr -> u3); - PutMem(DCAR[disk]+2, RIDsect[disk]); - RIDsect[disk]++; - if (RIDsect[disk] > 23) - RIDsect[disk] = 32; - if (RIDsect[disk] > 55) - RIDsect[disk] = 0; - break; - case 2: /* Read Diagnostic */ - iodata = STOP_INVDEV; - break; - case 3: /* Verify */ - sect = (S >> 2) & 0x3F; - nsects = N + 1; - addr = DDAR[disk]; - for (i = 0; i < nsects; i++) { - r = read_sector(uptr, dbuf, sect); - if (r != 1 || uptr->u3 != C) { - diskerr[disk] |= 0x0800; - break; - } - if (sect == 55) { /* HJS MODS */ - S = sect; - N = nsects - i - 2; - if (N > -1) diskerr[disk] |= 0x0020; /* end of cyl. */ - DDAR[disk] = addr & 0xFFFF; - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - sim_activate(uptr, 1); - iodata = SCPE_OK; - break; - } - sect++; - S = sect - 1; - N = nsects - i - 2; - if (sect == 24) - sect = 32; - } - DDAR[disk] = addr & 0xFFFF; - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - /*sim_activate(uptr, uptr -> wait);*/ - sim_activate(uptr, 1); - break; - default: - return STOP_INVDEV; - } - break; - case 0x02: /* Write */ - switch (data) { - case 0: /* Write Data */ - sect = (S >> 2) & 0x3F; - nsects = N + 1; - addr = DDAR[disk]; - for (i = 0; i < nsects; i++) { - for (j = 0; j < DSK_SECTSIZE; j++) { - dbuf[j] = GetMem(addr); - addr++; - } - r = write_sector(uptr, dbuf, sect); - if (r != 1 || uptr->u3 != C) { - diskerr[disk] |= 0x0400; - break; - } - if (sect == 55) { /* HJS MODS */ - S = sect; - N = nsects - i - 2; - if (N > -1) diskerr[disk] |= 0x0020; /* end of cyl. */ - DDAR[disk] = addr & 0xFFFF; - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - sim_activate(uptr, 1); - iodata = SCPE_OK; - break; - } - sect++; - S = sect - 1; - N = nsects - i - 2; - if (sect == 24) - sect = 32; - } - DDAR[disk] = addr & 0xFFFF; /* HJS mod */ - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - /*sim_activate(uptr, uptr -> wait);*/ - sim_activate(uptr, 1); - break; - case 1: /* Write identifier */ - if (seekhead[disk] == 0) - S = 0; - else - S = 0x80; - N = 23; - - sect = (S >> 2) & 0x3F; - nsects = N + 1; - addr = DDAR[disk]; - for (i = 0; i < nsects; i++) { - for (j = 0; j < DSK_SECTSIZE; j++) { - dbuf[j] = GetMem(addr); - } - r = write_sector(uptr, dbuf, sect); - if (r != 1) { - diskerr[disk] |= 0x0400; - break; - } - if (sect == 55) { - S = sect; - N = nsects - i - 2; - if (N > 0) diskerr[disk] |= 0x0020; - DDAR[disk] = addr & 0xFFFF; - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - sim_activate(uptr, 1); - iodata = SCPE_OK; - break; - } - sect++; - S = sect - 1; - N = nsects - i - 2; - if (sect == 24) - sect = 32; - } - DDAR[disk] = addr & 0xFFFF; - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - /*sim_activate(uptr, uptr -> wait);*/ - sim_activate(uptr, 1); - break; - default: - return STOP_INVDEV; - } - break; - case 0x03: /* Scan */ - sect = (S >> 2) & 0x3F; - nsects = N + 1; - addr = DDAR[disk]; - for (i = 0; i < nsects; i++) { - r = read_sector(uptr, dbuf, sect); - if (r != 1 || uptr->u3 != C) { - diskerr[disk] |= 0x0800; - break; - } - res = 0; - for (j = 0; j < DSK_SECTSIZE; j++) { - c = GetMem(addr); - if (j != 0xff) { - if (dbuf[i] < c) - res = 1; - if (dbuf[i] > c) - res = 3; - } - addr++; - } - if (res == 0) - found[disk] = 1; - if (res == data) - break; - if (sect == 55) { /* HJS MODS */ - S = sect; - N = nsects - i - 2; - if (N > -1) diskerr[disk] |= 0x0020; /* end of cyl. */ - DDAR[disk] = addr & 0xFFFF; - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - sim_activate(uptr, 1); - iodata = SCPE_OK; - break; - } - sect++; - S = sect - 1; - N = nsects - i - 2; - if (sect == 24) - sect = 32; - } - PutMem(DCAR[disk]+2, S << 2); - PutMem(DCAR[disk]+3, N); - /*sim_activate(uptr, uptr -> wait);*/ - sim_activate(uptr, 1); - break; - default: - return STOP_INVDEV; - } - return iodata; - - /* LIO 5444 */ - case 1: - if ((uptr->flags & UNIT_ATT) == 0) - return SCPE_UNATT; - switch (n) { - case 0x04: /* Data Addr */ - DDAR[disk] = data; - break; - case 0x06: /* Control Addr */ - DCAR[disk] = data; - break; - default: - return STOP_INVDEV; - } - return SCPE_OK; - /* TIO 5444 */ - case 2: - if ((uptr->flags & UNIT_ATT) == 0) - return SCPE_UNATT << 16; - iodata = 0; - switch (n) { - case 0x00: /* Error */ - if (diskerr[disk] || notrdy[disk]) - iodata = 1; - if ((uptr -> flags & UNIT_ATT) == 0) - iodata = 1; - break; - case 0x02: /* Busy */ - if (sim_is_active (uptr)) - iodata = 1; - break; - case 0x04: - if (found[disk]) - iodata = 1; - break; - default: - return (STOP_INVDEV << 16); - } - return ((SCPE_OK << 16) | iodata); - - /* SNS 5444 */ - case 3: - if ((uptr->flags & UNIT_ATT) == 0) - return SCPE_UNATT << 16; - iodata = 0; - switch (n) { - case 0x01: - break; - case 0x02: - iodata = diskerr[disk]; - if (notrdy[disk]) - iodata |= 0x4000; - if ((uptr -> flags & UNIT_ATT) == 0) - iodata |= 0x4000; - if (seekbusy[disk]) - iodata |= 0x0010; - if (uptr -> u3 == 0) - iodata |= 0x0040; - break; - case 0x03: - iodata = 0; - break; - case 0x04: - iodata = DDAR[disk]; - break; - case 0x06: - iodata = DCAR[disk]; - break; - default: - return (STOP_INVDEV << 16); - } - iodata |= ((SCPE_OK << 16) & 0xffff0000); - return (iodata); - - /* APL 5444 */ - case 4: - if ((uptr->flags & UNIT_ATT) == 0) - return SCPE_UNATT << 16; - iodata = 0; - switch (n) { - case 0x00: /* Error */ - if (diskerr[disk] || notrdy[disk]) - iodata = 1; - if ((uptr -> flags & UNIT_ATT) == 0) - iodata = 1; - break; - case 0x02: /* Busy */ - if (sim_is_active (uptr)) - iodata = 1; - break; - default: - return (STOP_INVDEV << 16); - } - return ((SCPE_OK << 16) | iodata); - default: - break; - } - sim_printf (">>DSK%d non-existent function %d\n", disk, op); - return SCPE_OK; -} - -/* Disk unit service. If a stacker select is active, copy to the - selected stacker. Otherwise, copy to the normal stacker. If the - unit is unattached, simply exit. -*/ - -t_stat r1_svc (UNIT *uptr) -{ -seekbusy[0] = 0; -return SCPE_OK; -} -t_stat f1_svc (UNIT *uptr) -{ -seekbusy[0] = 0; -return SCPE_OK; -} -t_stat r2_svc (UNIT *uptr) -{ -seekbusy[1] = 0; -return SCPE_OK; -} -t_stat f2_svc (UNIT *uptr) -{ -seekbusy[1] = 0; -return SCPE_OK; -} - - -/* Disk reset */ - -t_stat r1_reset (DEVICE *dptr) -{ -diskerr[0] = notrdy[0] = seekbusy[0] = 0; /* clear indicators */ -found[0] = 0; -sim_cancel (&r1_unit); /* clear event */ -r1_unit.u3 = 0; /* cylinder 0 */ -return SCPE_OK; -} -t_stat f1_reset (DEVICE *dptr) -{ -diskerr[0] = notrdy[0] = seekbusy[0] = 0; /* clear indicators */ -found[0] = 0; -sim_cancel (&f1_unit); /* clear event */ -f1_unit.u3 = 0; /* cylinder 0 */ -return SCPE_OK; -} -t_stat r2_reset (DEVICE *dptr) -{ -diskerr[1] = notrdy[1] = seekbusy[1] = 0; /* clear indicators */ -found[1] = 0; -sim_cancel (&r2_unit); /* clear event */ -r2_unit.u3 = 0; /* cylinder 0 */ -return SCPE_OK; -} -t_stat f2_reset (DEVICE *dptr) -{ -diskerr[1] = notrdy[1] = seekbusy[1] = 0; /* clear indicators */ -found[1] = 0; -sim_cancel (&f2_unit); /* clear event */ -f2_unit.u3 = 0; /* cylinder 0 */ -return SCPE_OK; -} - -/* Disk unit attach */ - -t_stat r1_attach (UNIT *uptr, char *cptr) -{ -diskerr[0] = notrdy[0] = seekbusy[0] = 0; /* clear status */ -found[0] = 0; -uptr -> u3 = 0; /* cylinder 0 */ -return attach_unit (uptr, cptr); -} -t_stat f1_attach (UNIT *uptr, char *cptr) -{ -diskerr[0] = notrdy[0] = seekbusy[0] = 0; /* clear status */ -found[0] = 0; -uptr -> u3 = 0; /* cylinder 0 */ -return attach_unit (uptr, cptr); -} -t_stat r2_attach (UNIT *uptr, char *cptr) -{ -diskerr[1] = notrdy[1] = seekbusy[1] = 0; /* clear status */ -found[1] = 0; -uptr -> u3 = 0; /* cylinder 0 */ -return attach_unit (uptr, cptr); -} -t_stat f2_attach (UNIT *uptr, char *cptr) -{ -diskerr[1] = notrdy[1] = seekbusy[1] = 0; /* clear status */ -found[1] = 0; -uptr -> u3 = 0; /* cylinder 0 */ -return attach_unit (uptr, cptr); -} - -/* Bootstrap routine */ - -t_stat r1_boot (int32 unitno, DEVICE *dptr) -{ -int i; -r1_unit.u3 = 0; -read_sector(r1_dev.units, dbuf, 0); -for (i = 0; i < 256; i++) { - M[i] = dbuf[i]; -} -return SCPE_OK; -} -t_stat f1_boot (int32 unitno, DEVICE *dptr) -{ -int i; -f1_unit.u3 = 0; -read_sector(f1_dev.units, dbuf, 0); -for (i = 0; i < 256; i++) { - M[i] = dbuf[i]; -} -return SCPE_OK; -} -t_stat r2_boot (int32 unitno, DEVICE *dptr) -{ -int i; -r2_unit.u3 = 0; -read_sector(r2_dev.units, dbuf, 0); -for (i = 0; i < 256; i++) { - M[i] = dbuf[i]; -} -return SCPE_OK; -} -t_stat f2_boot (int32 unitno, DEVICE *dptr) -{ -int i; -f2_unit.u3 = 0; -read_sector(f2_dev.units, dbuf, 0); -for (i = 0; i < 256; i++) { - M[i] = dbuf[i]; -} -return SCPE_OK; -} - - -/* Raw Disk Data In/Out */ - -int32 read_sector(UNIT *uptr, char *dbuf, int32 sect) -{ - static int32 rtn, realsect; - static long pos; - - /* calculate real sector no */ - if (sect > 23) - realsect = sect - 8; - else - realsect = sect; - /* physically read the sector */ - pos = DSK_CYLSIZE * uptr -> u3; - pos += DSK_SECTSIZE * realsect; - rtn = fseek(uptr -> fileref, pos, 0); - rtn = fread(dbuf, DSK_SECTSIZE, 1, uptr -> fileref); - return (rtn); -} - -int32 write_sector(UNIT *uptr, char *dbuf, int32 sect) -{ - static int32 rtn, realsect; - static long pos; - - /* calculate real sector no */ - if (sect > 23) - realsect = sect - 8; - else - realsect = sect; - if (uptr -> u3 == 0 && realsect == 32) - rtn = 0; - /* physically write the sector */ - pos = DSK_CYLSIZE * uptr -> u3; - pos += DSK_SECTSIZE * realsect; - rtn = fseek(uptr -> fileref, pos, 0); - rtn = fwrite(dbuf, DSK_SECTSIZE, 1, uptr -> fileref); - return (rtn); -} diff --git a/S3/s3_lp.c b/S3/s3_lp.c deleted file mode 100644 index a0507f50..00000000 --- a/S3/s3_lp.c +++ /dev/null @@ -1,364 +0,0 @@ -/* s3_lp.c: IBM 1403 line printer simulator - - Copyright (c) 2001-2012, Charles E. Owen - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. - - lpt 1403 line printer - - 19-Mar-12 RMS Fixed declaration of conversion tables (Mark Pizzolato) - 25-Apr-03 RMS Revised for extended file support - 08-Oct-02 RMS Added impossible function catcher -*/ - -#include "s3_defs.h" - -extern uint8 M[]; -extern char bcd_to_ascii[64]; -extern int32 iochk, ind[64]; -int32 cct[CCT_LNT] = { 03 }; -int32 cctlnt = 66, cctptr = 0, lines = 0, lflag = 0; -t_stat lpt_reset (DEVICE *dptr); -t_stat lpt_attach (UNIT *uptr, char *cptr); -t_stat write_line (int32 ilnt, int32 mod); -t_stat space (int32 lines, int32 lflag); -t_stat carriage_control (int32 action, int32 mod); -extern unsigned char ebcdic_to_ascii[]; - -#define UNIT_V_PCHAIN (UNIT_V_UF + 0) -#define UNIT_M_PCHAIN 03 -#define M_UCS 00 /* Universal */ -#define M_PCF 00 /* full */ -#define M_PCA 01 /* business */ -#define M_PCH 02 /* Fortran */ -#define UNIT_PCHAIN (UNIT_M_PCHAIN << UNIT_V_PCHAIN) -#define UCS (M_UCS << UNIT_V_PCHAIN) -#define PCF (M_PCF << UNIT_V_PCHAIN) -#define PCA (M_PCA << UNIT_V_PCHAIN) -#define PCH (M_PCH << UNIT_V_PCHAIN) -#define GET_PCHAIN(x) (((x) >> UNIT_V_PCHAIN) & UNIT_M_PCHAIN) -#define CHP(ch,val) ((val) & (1 << (ch))) - -int32 LPDAR; /* Data Address */ -int32 LPFLR; /* Forms Length */ -int32 LPIAR; /* Image address */ -int32 linectr; /* current line # */ -int32 lpterror = 0; -int32 CC9 = 0; -int32 CC12 = 0; - -/* LPT data structures - - lpt_dev LPT device descriptor - lpt_unit LPT unit descriptor - lpt_reg LPT register list -*/ - -UNIT lpt_unit = { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }; - -REG lpt_reg[] = { - { FLDATA (ERR, lpterror, 0) }, - { HRDATA (LPDAR, LPDAR, 16) }, - { HRDATA (LPFLR, LPFLR, 8) }, - { HRDATA (LPIAR, LPIAR, 16) }, - { DRDATA (LINECT, linectr, 8) }, - { DRDATA (POS, lpt_unit.pos, T_ADDR_W), PV_LEFT }, - { BRDATA (CCT, cct, 8, 32, CCT_LNT) }, - { DRDATA (LINES, lines, 8), PV_LEFT }, - { DRDATA (CCTP, cctptr, 8), PV_LEFT }, - { DRDATA (CCTL, cctlnt, 8), REG_RO + PV_LEFT }, - { GRDATA (CHAIN, lpt_unit.flags, 10, 2, UNIT_V_PCHAIN), REG_HRO }, - { NULL } -}; - -MTAB lpt_mod[] = { - { UNIT_PCHAIN, UCS, "UCS", "UCS", NULL }, - { UNIT_PCHAIN, PCA, "A chain", "PCA", NULL }, - { UNIT_PCHAIN, PCH, "H chain", "PCH", NULL }, - { 0 } -}; - -DEVICE lpt_dev = { - "LPT", &lpt_unit, lpt_reg, lpt_mod, - 1, 10, 31, 1, 8, 7, - NULL, NULL, &lpt_reset, - NULL, NULL, NULL -}; - - -/* -------------------------------------------------------------------- */ - -/* Printer: master routine */ - -int32 lpt (int32 op, int32 m, int32 n, int32 data) -{ - int32 iodata; - switch (op) { - case 0: /* SIO 1403 */ - iodata = 0; -// printf("\0"); - switch (n) { - case 0x00: /* Spacing only */ - if (data > 0 && data < 4) - iodata = carriage_control(2, data); - break; - case 0x02: /* Print & space */ - iodata = write_line(0, 0); - if (data > 3) data = 0; - if (iodata == SCPE_OK) - iodata = carriage_control(2, data); - break; - case 0x04: /* Skip only */ - iodata = carriage_control(4, data); - break; - case 0x06: /* Print and skip */ - iodata = write_line(0, 0); - if (iodata == SCPE_OK) - iodata = carriage_control(4, data); - break; - default: - return STOP_INVDEV; - } - return iodata; - case 1: /* LIO 1403 */ - switch (n) { - case 0x00: /* LPFLR */ - LPFLR = (data >> 8) & 0xff; - break; - case 0x04: - LPIAR = data & 0xffff; - break; - case 0x06: - LPDAR = data & 0xffff; - break; - default: - return STOP_INVDEV; - } - return SCPE_OK; - case 2: /* TIO 1403 */ - iodata = 0; - switch (n) { - case 0x00: /* Not ready/check */ - if (lpterror) - iodata = 1; - if ((lpt_unit.flags & UNIT_ATT) == 0) - iodata = 1; - break; - case 0x02: /* Buffer Busy */ - iodata = 0; - break; - case 0x04: /* Carriage Busy */ - iodata = 0; - break; - case 0x06: /* Printer busy */ - iodata = 0; - break; - default: - return (STOP_INVDEV << 16); - } - return ((SCPE_OK << 16) | iodata); - case 3: /* SNS 1403 */ - switch (n) { - case 0x00: /* Line count */ - iodata = (linectr << 8); - break; - case 0x02: /* Timing data */ - iodata = 0; - break; - case 0x03: /* Check data */ - iodata = 0; - break; - case 0x04: /* LPIAR */ - iodata = LPIAR; - break; - case 0x06: /* LPDAR */ - iodata = LPDAR; - break; - default: - return (STOP_INVDEV << 16); - } - return ((SCPE_OK << 16) | iodata); - case 4: /* APL 1403 */ - iodata = 0; - return ((SCPE_OK << 16) | iodata); - default: - break; - } - sim_printf (">>LPT non-existent function %d\n", op); - return SCPE_OK; -} - - -/* Print routine - - Modifiers have been checked by the caller - S = suppress automatic newline -*/ - -t_stat write_line (int32 ilnt, int32 mod) -{ -int32 i, t, lc; -static char lbuf[LPT_WIDTH + 1]; /* + null */ - -if ((lpt_unit.flags & UNIT_ATT) == 0) - return SCPE_UNATT; - -lpterror = 0; -lc = LPDAR; /* clear error */ -for (i = 0; i < LPT_WIDTH; i++) { /* convert print buf */ - t = M[lc]; - lbuf[i] = ebcdic_to_ascii[t & 0xff]; - M[lc] = 0x40; /* HJS MOD */ - lc++; -} -for (i = LPT_WIDTH - 1; (i >= 0) && (lbuf[i] == ' '); i--) lbuf[i] = 0; -fputs (lbuf, lpt_unit.fileref); /* write line */ -if (lines) space (lines, lflag); /* cc action? do it */ -else if (mod == 0) space (1, FALSE); /* default? 1 line */ -else { - fputc ('\r', lpt_unit.fileref); /* sup -> overprint */ - lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */ -} -lines = lflag = 0; /* clear cc action */ -if (ferror (lpt_unit.fileref)) { /* error? */ - perror ("Line printer I/O error"); - clearerr (lpt_unit.fileref); - lpterror = 1; -} -return SCPE_OK; -} - -/* Carriage control routine - - Parameters: - action = 00, skip to channel now - = 01, space lines after - = 02, space lines now - = 03, skip to channel after - = 04, skip to line number - mod = number of lines or channel number or line number -*/ - -t_stat carriage_control (int32 action, int32 mod) -{ -int32 i; - -if ((lpt_unit.flags & UNIT_ATT) == 0) - return SCPE_UNATT; - -switch (action) { -case 0: /* to channel now */ - if ((mod == 0) || (mod > 12) || CHP (mod, cct[cctptr])) return SCPE_OK; - for (i = 1; i < cctlnt + 1; i++) { /* sweep thru cct */ - if (CHP (mod, cct[(cctptr + i) % cctlnt])) - return space (i, TRUE); - } - return STOP_INVDEV; /* runaway channel */ -case 1: /* space after */ - if (mod <= 3) { - lines = mod; /* save # lines */ - lflag = FALSE; /* flag spacing */ - CC9 = CC12 = 0; - } - return SCPE_OK; -case 2: /* space now */ - if (mod <= 3) return space (mod, FALSE); - return SCPE_OK; -case 3: /* to channel after */ - if ((mod == 0) || (mod > 12)) return SCPE_OK; /* check channel */ - CC9 = CC12 = 0; - for (i = 1; i < cctlnt + 1; i++) { /* sweep thru cct */ - if (CHP (mod, cct[(cctptr + i) % cctlnt])) { - lines = i; /* save # lines */ - lflag = TRUE; /* flag skipping */ - return SCPE_OK; - } - } - return STOP_INVDEV; -case 4: /* To line # */ - if (mod < 2) { - fputs ("\n\f", lpt_unit.fileref); /* nl, ff */ - linectr = 1; - } else { - if (mod <= linectr) { - fputs ("\n\f", lpt_unit.fileref); - linectr = 1; - } - while (1) { - if (linectr == mod) - break; - space(1, 0); - } - } - return SCPE_OK; -} -return SCPE_OK; -} - -/* Space routine - space or skip n lines - - Inputs: - count = number of lines to space or skip - sflag = skip (TRUE) or space (FALSE) -*/ - -t_stat space (int32 count, int32 sflag) -{ -int32 i; - -if ((lpt_unit.flags & UNIT_ATT) == 0) return SCPE_UNATT; -cctptr = (cctptr + count) % cctlnt; /* adv cct, mod lnt */ -if (sflag && CHP (0, cct[cctptr])) { /* skip, top of form? */ - fputs ("\n\f", lpt_unit.fileref); /* nl, ff */ - linectr = 1; -} else { - for (i = 0; i < count; i++) fputc ('\n', lpt_unit.fileref); -} -lpt_unit.pos = ftell (lpt_unit.fileref); /* update position */ -CC9 = CHP (9, cct[cctptr]) != 0; /* set indicators */ -CC12 = CHP (12, cct[cctptr]) != 0; -linectr += count; -if (linectr > LPFLR) - linectr -= LPFLR; -return SCPE_OK; -} - -/* Reset routine */ - -t_stat lpt_reset (DEVICE *dptr) -{ -cctptr = 0; /* clear cct ptr */ -lines = linectr = lflag = 0; /* no cc action */ -lpterror = 0; -return SCPE_OK; -} - -/* Attach routine */ - -t_stat lpt_attach (UNIT *uptr, char *cptr) -{ -cctptr = 0; /* clear cct ptr */ -lines = 0; /* no cc action */ -lpterror = 0; -linectr = 0; -return attach_unit (uptr, cptr); -} diff --git a/S3/s3_pkb.c b/S3/s3_pkb.c deleted file mode 100644 index 7dcdd4d4..00000000 --- a/S3/s3_pkb.c +++ /dev/null @@ -1,313 +0,0 @@ -/* s3_pkb.c: System/3 5471 console terminal simulator - - Copyright (c) 2001-2005, Charles E. Owen - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. - - pkb 5471 printer/keyboard - - 25-Apr-03 RMS Revised for extended file support - 08-Oct-02 RMS Added impossible function catcher -*/ - -#include "s3_defs.h" -#include - -extern int32 int_req, dev_busy, dev_done, dev_disable; -t_stat pkb_svc (UNIT *uptr); -t_stat pkb_reset (DEVICE *dptr); -extern int32 IAR[], level; -extern int32 debug_reg; - -/* 5471 data structures - - pkb_dev TTI device descriptor - pkb_unit TTI unit descriptor - pkb_reg TTI register list - pkb_mod TTI/TTO modifiers list -*/ - -/* Flag bits : (kept in pkb_unit.u3) */ - -#define PRT_INTREQ 0x800 /* Printer interrupt pending */ -#define KBD_INTREQ 0x400 /* Request key interrupt pending */ -#define KBD_INTEND 0x200 /* End or cancel key interrupt pending */ -#define KBD_INTKEY 0x100 /* Return or other key interrupt pending */ -#define KBD_REQLIGHT 0x20 /* Request Pending Indicator (light on/off) */ -#define KBD_PROLIGHT 0x10 /* Proceed indicator (light on/off) */ -#define KBD_REQINT 0x04 /* Req key interrupts enabled */ -#define KBD_KEYINT 0x02 /* Other key interrupts enabled */ -#define PRT_PRTINT 0x01 /* Printer interrupts enabled */ - -/* Keys mapped to 5471 functions */ - -int32 key_req = 0x01; /* Request key: ^A */ -int32 key_rtn = 0x12; /* Return key: ^R */ -int32 key_can = 0x1B; /* Cancel key: ESC */ -int32 key_end = 0x0d; /* End key - CR */ - -UNIT pkb_unit = { UDATA (&pkb_svc, 0, 0), KBD_POLL_WAIT }; - -REG pkb_reg[] = { - { HRDATA (FLAG, pkb_unit.u3, 16) }, - { HRDATA (IBUF, pkb_unit.buf, 8) }, - { HRDATA (OBUF, pkb_unit.u4, 8) }, - { HRDATA (REQKEY, key_req, 8) }, - { HRDATA (RTNKEY, key_rtn, 8) }, - { HRDATA (CANKEY, key_can, 8) }, - { HRDATA (ENDKEY, key_end, 8) }, - { DRDATA (POS, pkb_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (TIME, pkb_unit.wait, 24), REG_NZ + PV_LEFT }, - { NULL } -}; - -MTAB pkb_mod[] = { - { 0 } -}; - -DEVICE pkb_dev = { - "PKB", &pkb_unit, pkb_reg, pkb_mod, - 1, 10, 31, 1, 8, 8, - NULL, NULL, &pkb_reset, - NULL, NULL, NULL -}; - - -/*-------------------------------------------------------------------*/ -/* EBCDIC to ASCII translate table */ -/*-------------------------------------------------------------------*/ -unsigned char ebcdic_to_ascii[] = { -"\x00\x01\x02\x03\xA6\x09\xA7\x7F\xA9\xB0\xB1\x0B\x0C\x0D\x0E\x0F" -"\x10\x11\x12\x13\xB2\xB4\x08\xB7\x18\x19\x1A\xB8\xBA\x1D\xBB\x1F" -"\xBD\xC0\x1C\xC1\xC2\x0A\x17\x1B\xC3\xC4\xC5\xC6\xC7\x05\x06\x07" -"\xC8\xC9\x16\xCB\xCC\x1E\xCD\x04\xCE\xD0\xD1\xD2\x14\x15\xD3\xFC" -"\x20\xD4\x83\x84\x85\xA0\xD5\x86\x87\xA4\xD6\x2E\x3C\x28\x2B\xD7" -"\x26\x82\x88\x89\x8A\xA1\x8C\x8B\x8D\xD8\x21\x24\x2A\x29\x3B\x5E" -"\x2D\x2F\xD9\x8E\xDB\xDC\xDD\x8F\x80\xA5\x7C\x2C\x25\x5F\x3E\x3F" -"\xDE\x90\xDF\xE0\xE2\xE3\xE4\xE5\xE6\x60\x3A\x23\x40\x27\x3D\x22" -"\xE7\x61\x62\x63\x64\x65\x66\x67\x68\x69\xAE\xAF\xE8\xE9\xEA\xEC" -"\xF0\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\xF1\xF2\x91\xF3\x92\xF4" -"\xF5\x7E\x73\x74\x75\x76\x77\x78\x79\x7A\xAD\xA8\xF6\x5B\xF7\xF8" -"\x9B\x9C\x9D\x9E\x9F\xB5\xB6\xAC\xAB\xB9\xAA\xB3\xBC\x5D\xBE\xBF" -"\x7B\x41\x42\x43\x44\x45\x46\x47\x48\x49\xCA\x93\x94\x95\xA2\xCF" -"\x7D\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\xDA\x96\x81\x97\xA3\x98" -"\x5C\xE1\x53\x54\x55\x56\x57\x58\x59\x5A\xFD\xEB\x99\xED\xEE\xEF" -"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\xFE\xFB\x9A\xF9\xFA\xFF" -}; - -/*-------------------------------------------------------------------*/ -/* ASCII to EBCDIC translate table */ -/*-------------------------------------------------------------------*/ -unsigned char ascii_to_ebcdic[] = { -"\x00\x01\x02\x03\x37\x2D\x2E\x2F\x16\x05\x25\x0B\x0C\x0D\x0E\x0F" -"\x10\x11\x12\x13\x3C\x3D\x32\x26\x18\x19\x1A\x27\x22\x1D\x35\x1F" -"\x40\x5A\x7F\x7B\x5B\x6C\x50\x7D\x4D\x5D\x5C\x4E\x6B\x60\x4B\x61" -"\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\x7A\x5E\x4C\x7E\x6E\x6F" -"\x7C\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xD1\xD2\xD3\xD4\xD5\xD6" -"\xD7\xD8\xD9\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xAD\xE0\xBD\x5F\x6D" -"\x79\x81\x82\x83\x84\x85\x86\x87\x88\x89\x91\x92\x93\x94\x95\x96" -"\x97\x98\x99\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xC0\x6A\xD0\xA1\x07" -"\x68\xDC\x51\x42\x43\x44\x47\x48\x52\x53\x54\x57\x56\x58\x63\x67" -"\x71\x9C\x9E\xCB\xCC\xCD\xDB\xDD\xDF\xEC\xFC\xB0\xB1\xB2\xB3\xB4" -"\x45\x55\xCE\xDE\x49\x69\x04\x06\xAB\x08\xBA\xB8\xB7\xAA\x8A\x8B" -"\x09\x0A\x14\xBB\x15\xB5\xB6\x17\x1B\xB9\x1C\x1E\xBC\x20\xBE\xBF" -"\x21\x23\x24\x28\x29\x2A\x2B\x2C\x30\x31\xCA\x33\x34\x36\x38\xCF" -"\x39\x3A\x3B\x3E\x41\x46\x4A\x4F\x59\x62\xDA\x64\x65\x66\x70\x72" -"\x73\xE1\x74\x75\x76\x77\x78\x80\x8C\x8D\x8E\xEB\x8F\xED\xEE\xEF" -"\x90\x9A\x9B\x9D\x9F\xA0\xAC\xAE\xAF\xFD\xFE\xFB\x3F\xEA\xFA\xFF" -}; - -/* -------------------------------------------------------------------- */ - -/* Console Input: master routine */ - -int32 pkb (int32 op, int32 m, int32 n, int32 data) -{ - int32 iodata= 0, ec, ac; - switch (op) { - case 0: /* SIO 5471 */ - if (n != 0) - return STOP_INVDEV; - /*printf("%04X SIO %d,%d,%02X\n\r", IAR[level]-4, m, n, data);*/ - if (m == 0) { /* Keyboard */ - pkb_unit.u3 &= 0xFC1; - pkb_unit.u3 |= data; - if (data & 0x01) { - pkb_unit.u3 &= ~KBD_INTREQ; - pkb_unit.u3 &= ~KBD_INTKEY; - pkb_unit.u3 &= ~KBD_INTEND; - return RESET_INTERRUPT; - } - } else { /* Printer */ - if (data & 0x80) { /* start print bit */ - if (debug_reg & 0x80) - return STOP_IBKPT; - ec = pkb_unit.u4 & 0xff; - ac = ebcdic_to_ascii[ec]; - sim_putchar(ac); - pkb_unit.u3 |= PRT_INTREQ; - } - if (data & 0x40) { /* Carr. Return */ - sim_putchar('\n'); - sim_putchar('\r'); - pkb_unit.u3 |= PRT_INTREQ; - } - pkb_unit.u3 &= 0xFFe; - if (data & 0x04) /* Print interrupt flag */ - pkb_unit.u3 |= PRT_PRTINT; - if (data & 0x01) { /* Reset Interrupt */ - if (level < 8) { - if (!(data & 0x80)) - pkb_unit.u3 &= ~PRT_INTREQ; - return RESET_INTERRUPT; - } - } - } - return SCPE_OK; - case 1: /* LIO 5471 */ - if (n != 0) - return STOP_INVDEV; - if (m != 1) - return STOP_INVDEV; - pkb_unit.u4 = (data >> 8) & 0xff; - return SCPE_OK; - break; - case 2: /* TIO 5471 */ - return STOP_INVDEV; - case 3: /* SNS 5471 */ - if (n != 1 && n != 3) - return (STOP_INVDEV << 16); - if (m == 0) { /* Keyboard data */ - if (n == 1) { /* Sense bytes 0 & 1 */ - iodata = (pkb_unit.buf << 8) & 0xff00; - if (pkb_unit.u3 & KBD_INTREQ) - iodata |= 0x80; - if (pkb_unit.u3 & KBD_INTEND) - iodata |= 0x40; - if (pkb_unit.u3 & KBD_INTKEY) - iodata |= 0x08; - if (pkb_unit.buf == 0x12) /* Return key */ - iodata |= 0x04; - if (pkb_unit.buf == 0x03) /* Cancel key */ - iodata |= 0x20; - if (pkb_unit.buf == 0x0d) /* End key */ - iodata |= 0x10; - iodata |= ((SCPE_OK << 16) & 0xffff0000); - } else { /* Sense bytes 2 & 3 */ - iodata = 0; /* Manual says CE use only */ - } - } else { /* Printer Data */ - if (n == 1) { /* Sense bytes 0 & 1 */ - iodata = 0; - if (pkb_unit.u3 & PRT_INTREQ) - iodata |= 0x80; - } else { - iodata = 0; /* CE use only */ - } - } - iodata |= ((SCPE_OK << 16) & 0xffff0000); - return (iodata); - case 4: /* APL 5471 */ - return STOP_INVDEV; - default: - break; - } - sim_printf (">>PKB non-existent function %d\n", op); - return SCPE_OK; -} - -/* Unit service */ - -t_stat pkb_svc (UNIT *uptr) -{ -int32 temp, ac, ec; - -sim_activate (&pkb_unit, pkb_unit.wait); /* continue poll */ - -if (pkb_unit.u3 & PRT_INTREQ) { /* Printer Interrupt */ - int_req |= 2; - return SCPE_OK; -} - -/* Keyboard : handle input */ - -if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp; /* no char or error? */ - -ac = temp & 0x7f; /* placed type ASCII char in ac */ -if (pkb_unit.u3 & KBD_REQINT) { - if (ac == key_req) { /* Request Key */ - pkb_unit.u3 |= KBD_INTREQ; - int_req |= 2; - return SCPE_OK; - } -} -if (islower(ac)) - ac = toupper(ac); -ec = ascii_to_ebcdic[ac]; /* Translate */ -pkb_unit.buf = ec; /* put in buf */ -pkb_unit.pos = pkb_unit.pos + 1; -if (ac == key_end) { /* End key */ - if (pkb_unit.u3 & KBD_KEYINT) { - pkb_unit.u3 |= KBD_INTEND; - pkb_unit.buf = 0x0d; - int_req |= 2; - } - return SCPE_OK; -} -if (ac == key_can) { /* Cancel key */ - if (pkb_unit.u3 & KBD_KEYINT) { - pkb_unit.u3 |= KBD_INTEND; - pkb_unit.buf = 0x03; - int_req |= 2; - } - return SCPE_OK; -} -if (ac == key_rtn) { /* Return key */ - if (pkb_unit.u3 & KBD_KEYINT) { - pkb_unit.u3 |= KBD_INTKEY; - pkb_unit.buf = 0x12; - int_req |= 2; - } - return SCPE_OK; -} -if (pkb_unit.u3 & KBD_KEYINT) { /* Key interupts enabled ? */ - int_req |= 2; /* Device 1 Interrupt! */ - pkb_unit.u3 |= KBD_INTKEY; /* Set pending flag */ -} -return SCPE_OK; -} - -/* Reset routine */ - -t_stat pkb_reset (DEVICE *dptr) -{ -pkb_unit.buf = 0; -int_req = int_req & ~0x02; /* reset interrupt */ -sim_activate (&pkb_unit, pkb_unit.wait); /* activate unit */ -return SCPE_OK; -} - -t_stat pkb_setmod (UNIT *uptr, int32 value) -{ -return SCPE_OK; -} - diff --git a/S3/s3_sys.c b/S3/s3_sys.c deleted file mode 100644 index 85ee11a9..00000000 --- a/S3/s3_sys.c +++ /dev/null @@ -1,950 +0,0 @@ -/* s3_sys.c: IBM System/3 system interface - - Copyright (c) 2001-2020, Charles E. Owen - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, sublicense, - and/or sell copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - Except as contained in this notice, the name of Charles E. Owen shall not be - used in advertising or otherwise to promote the sale, use or other dealings - in this Software without prior written authorization from Charles E. Owen. - - 06-Jun-20 RMS Fixed declaration of bldaddr (Mark Pizzolato) - 19-Mar-12 RMS Fixed declaration of conversion tables (Mark Pizzolato) -*/ - -#include -#include "s3_defs.h" - -extern DEVICE cpu_dev; -extern DEVICE pkb_dev; -extern DEVICE cdr_dev; -extern DEVICE cdp_dev; -extern DEVICE stack_dev; -extern DEVICE lpt_dev; -extern DEVICE r1_dev; -extern DEVICE f1_dev; -extern DEVICE r2_dev; -extern DEVICE f2_dev; -extern UNIT cpu_unit; -extern REG cpu_reg[]; -extern unsigned char M[]; -extern int32 saved_PC, IAR[]; -extern unsigned char ebcdic_to_ascii[]; -char *parse_addr(char *cptr, char *gbuf, t_addr *addr, int32 *addrtype); - -int32 printf_sym (FILE *of, char *strg, t_addr addr, uint32 *val, - UNIT *uptr, int32 sw); - -/* SCP data structures - - sim_name simulator name string - sim_PC pointer to saved PC register descriptor - sim_emax number of words needed for examine - sim_devices array of pointers to simulated devices - sim_stop_messages array of pointers to stop messages - sim_load binary loader -*/ - -char sim_name[] = "System/3"; - -REG *sim_PC = &cpu_reg[0]; - -int32 sim_emax = 6; - -DEVICE *sim_devices[] = { - &cpu_dev, - &pkb_dev, - &cdr_dev, - &cdp_dev, - &stack_dev, - &lpt_dev, - &r1_dev, - &f1_dev, - &r2_dev, - &f2_dev, - NULL -}; - -const char *sim_stop_messages[] = { - "Unknown error", - "Unknown I/O Instruction", - "HALT instruction", - "Breakpoint", - "Invalid Opcode", - "Invalid Qbyte", - "Invalid Address", - "Invalid Device Command", - "ATTN Card Reader" -}; - -/* This is the opcode master defintion table. Each possible opcode mnemonic - is defined here, with enough information to translate to and from - symbolic to binary machine code. - First field is the opcode's mnemonic - Second field is the hex of the right nybble of the binary opcode - Third field is the Q code for those with implicit Q codes - Fourth field is the symbolic format of the operands: - 0 - (Q-byte),(R-byte) - 1 - (Q-byte),(Address) - 2 - (Address),(Address),(Qbyte) - 3 - (Address),(Qbyte) - 4 - (device),(modifier),(function) -- these 3 make up qbyte - 5 - (device),(modifier),(function),(control) - 6 - (device),(modifier),(function),(Address) - 7 - (displacement) -- Q byte is implicit in opcode - 8 - (address) -- Qbyte is implicit in opcode - 9 - (Address),(Address) -- Qbyte is implicit in opcode - Fifth Field is the group number: - 0 - Command Group (left op nybble is F) - 1 - One Address Operations A (Left Nybble C, D, or E) - 2 - Two Address Operations (Left Nybble 0,1,2,4,5,6,8,9, or A) - 3 - One Address Operations B (left Nybble 3, 7, or B) - - There is duplication in this table -- IBM defines different opcodes - that resolve to the same binary machine instruction -- e.g. JE and - JZ. On input this is no problem, on output, define the one you - want to appear first, the second will never appear on output. -*/ - -int32 nopcode = 75; -struct opdef opcode[75] = { - {"HPL", 0x00,0,0,0}, /** Halt Program Level */ - {"A", 0x06,0,1,3}, /** Add to Register: A R,AADD */ - {"ST", 0x04,0,1,3}, /** Store Register */ - {"L", 0x05,0,1,3}, /** Load Register */ - {"LA", 0x02,0,1,1}, /** Load Address */ - {"ZAZ", 0x04,0,2,2}, /** Zero and Add Zoned */ - {"AZ", 0x06,0,2,2}, /** Add Zoned Decimal */ - {"SZ", 0x07,0,2,2}, /** Subtract Zoned Decimal */ - {"ALC", 0x0E,0,2,2}, /** Add Logical: ALC BADD,AADD,LEN */ - {"SLC", 0x0F,0,2,2}, /** Sub Logical: SLC BADD,AADD,LEN */ - {"MVC", 0x0C,0,2,2}, /** Move Chars MVX BADD,AADD,LEN */ - {"ED", 0x0A,0,2,2}, /** Edit: ED BADD,AADD,LEN */ - {"ITC", 0x0B,0,2,2}, /** Insert Chars: ITC BADD,AADD,LEN */ - {"CLC", 0x0D,0,2,2}, /** Compare Logical: CLC BADD,AADD,LEN */ - {"MVI", 0x0C,0,3,3}, /** Move Immediate */ - {"SBN", 0x0A,0,3,3}, /** Set Bits On */ - {"SBF", 0x0B,0,3,3}, /** Set Bits Off */ - {"CLI", 0x0D,0,3,3}, /** Compare Immediate */ - {"TBN", 0x08,0,3,3}, /** Test Bits On */ - {"TBF", 0x09,0,3,3}, /** Test Bits Off */ - {"APL", 0x01,0,4,0}, /** Advance Program Level */ - {"SIO", 0x03,0,5,0}, /** Start I/O */ - {"SNS", 0x00,0,6,3}, /** Sense I/O */ - {"LIO", 0x01,0,6,3}, /** Load I/O */ - {"TIO", 0x01,0,6,1}, /** Test I/O */ - {"J", 0x02,0,7,0}, /** Jump Unconditional */ - {"J", 0x02,0x87,7,0}, /* Alternate J */ - {"JH", 0x02,132,7,0}, /* Jump if High */ - {"JL", 0x02,130,7,0}, /* Jump if Low */ - {"JE", 0x02,129,7,0}, /* Jump if Equal */ - {"JNH", 0x02,4,7,0}, /** Jump if Not High */ - {"JNL", 0x02,2,7,0}, /** Jump if Not Low */ - {"JNE", 0x02,1,7,0}, /** Jump if Not Equal */ - {"JOZ", 0x02,136,7,0}, /* Jump if Overflow Zoned */ - {"JOL", 0x02,160,7,0}, /* Jump if Overflow Logical */ - {"JNOZ", 0x02,8,7,0}, /** Jump if No Overflow Zoned */ - {"JNOL", 0x02,32,7,0}, /* Jump if No Overflow Logical */ - {"JT", 0x02,16,7,0}, /* Jump if True */ - {"JF", 0x02,144,7,0}, /* Jump if False */ - {"JP", 0x02,132,7,0}, /* Jump if Plus */ - {"JM", 0x02,130,7,0}, /* Jump if Minus */ - {"JZ", 0x02,129,7,0}, /* Jump if Zero */ - {"JNP", 0x02,4,7,0}, /** Jump if Not Plus */ - {"JNM", 0x02,2,7,0}, /** Jump if Not Minus */ - {"JNZ", 0x02,1,7,0}, /** Jump if Not Zero */ - {"NOPJ", 0x02,0x80,7,0}, /* Never Jump - NOP */ - {"B", 0x00,0x00,8,1}, /* Branch Unconditional */ - {"B", 0x00,0x87,8,1}, /* Alternate B */ - {"BH", 0x00,0x84,8,1}, /* Branch if High */ - {"BL", 0x00,0x82,8,1}, /* Branch if Low */ - {"BE", 0x00,0x81,8,1}, /* Branch if Equal */ - {"BNH", 0x00,0x04,8,1}, /* Branch if Not High */ - {"BNL", 0x00,0x02,8,1}, /* Branch if Not Low */ - {"BNE", 0x00,0x01,8,1}, /* Branch if Not Equal */ - {"BOZ", 0x00,0x88,8,1}, /* Branch if Overflow Zoned */ - {"BOL", 0x00,0xA0,8,1}, /* Branch if Overflow Logical */ - {"BNOZ", 0x00,0x08,8,1}, /* Branch if No Overflow Zoned */ - {"BNOL", 0x00,0x20,8,1}, /* Branch if No Overflow Logical */ - {"BT", 0x00,0x10,8,1}, /* Branch if True */ - {"BF", 0x00,0x90,8,1}, /* Branch if False */ - {"BP", 0x00,0x84,8,1}, /* Branch if Plus */ - {"BM", 0x00,0x82,8,1}, /* Branch if Minus */ - {"BZ", 0x00,0x81,8,1}, /* Branch if Zero */ - {"BNP", 0x00,0x04,8,1}, /* Branch if Not Plus */ - {"BNM", 0x00,0x02,8,1}, /* Branch if Not Minus */ - {"BNZ", 0x00,0x01,8,1}, /* Branch if Not Zero */ - {"NOPB", 0x00,0x80,8,1}, /* Never Branch - NOP */ - {"MZZ", 0x08,0,9,2}, /** Move Zone to Zone */ - {"MNZ", 0x08,1,9,2}, /** Move Numeric to Zone */ - {"MZN", 0x08,2,9,2}, /** Move Zone to Numeric */ - {"MNN", 0x08,3,9,2}, /** Move Numeric to Numeric */ - {"MVX", 0x08,0,2,2}, /** Move Hex: MVX BADD,AADD,CODE */ - {"JC", 0x02,0,3,0}, /** Jump on Specified Condition bits */ - {"BC", 0x00,0,3,1}, /** Branch on Specified Condition */ - {"***", 0x00,0,0,0} -}; - -int32 regcode[15] = { 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, - 0x80, 0xC0, 0xA0, 0x90, 0x88, 0x84, 0x82, 0x81 -}; - -char regname[15][8] = { "(P2IAR)", - "(P1IAR)", - "(IAR)", - "(ARR)", - "(PSR)", - "(XR2)", - "(XR1)", - "(IAR0)", - "(IAR1)", - "(IAR2)", - "(IAR3)", - "(IAR4)", - "(IAR5)", - "(IAR6)", - "(IAR7)" -}; - -/* This is the binary loader. The input file is considered to be - a string of literal bytes with no special format. The - load starts at the current value of the P1IAR. -*/ - -t_stat sim_load (FILE *fileref, char *cptr, char *fnam, int flag) -{ -int32 i, addr = 0, cnt = 0; - -if ((*cptr != 0) || (flag != 0)) return SCPE_ARG; -addr = IAR[8]; -while ((i = getc (fileref)) != EOF) { - M[addr] = i & 0xff; - addr++; - cnt++; -} /* end while */ -printf ("%d Bytes loaded.\n", cnt); -return (SCPE_OK); -} - -/* Symbolic output - - Inputs: - *of = output stream - addr = current PC - *val = pointer to values - *uptr = pointer to unit - sw = switches - Outputs: - status = error code -*/ - -t_stat fprint_sym (FILE *of, t_addr addr, uint32 *val, - UNIT *uptr, int32 sw) -{ - int32 r; - char strg[256]; - - strcpy(strg, ""); - r = printf_sym(of, strg, addr, val, uptr, sw); - if (sw & SWMASK ('A')) - strcpy(strg, ""); - else - fprintf(of, "%s", strg); - return (r); -} - -t_stat printf_sym (FILE *of, char *strg, t_addr addr, uint32 *val, - UNIT *uptr, int32 sw) -{ -int32 c1, c2, group, len1, len2, inst, aaddr, baddr; -int32 oplen, groupno, i, j, vpos, qbyte, da, m, n; -char bld[128], bldaddr[160], boperand[32], aoperand[32]; -int32 blk[16], blt[16]; -int32 blkadd; - -c1 = val[0] & 0xff; -if (sw & SWMASK ('A')) { - for (i = 0; i < 16; i++) { - blkadd = addr + (i*16); - for (j = 0; j < 16; j++) { - blk[j] = M[blkadd+j] & 0xff; - c2 = ebcdic_to_ascii[blk[j]]; - if (c2 < 040 || c2 > 0177 || blk[j] == 07) { - blt[j] = '.'; - } else { - blt[j] = c2; - } - } - if (i == 0) { - fprintf(of, "%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c]\n ", - blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7], - blk[8], blk[9], blk[10], blk[11], blk[12], blk[13], blk[14], blk[15], - blt[0], blt[1], blt[2], blt[3], blt[4], blt[5], blt[6], blt[7], - blt[8], blt[9], blt[10], blt[11], blt[12], blt[13], blt[14], blt[15]); - } else { - fprintf(of, "%X\t%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X [%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c]\n ", - blkadd, blk[0], blk[1], blk[2], blk[3], blk[4], blk[5], blk[6], blk[7], - blk[8], blk[9], blk[10], blk[11], blk[12], blk[13], blk[14], blk[15], - blt[0], blt[1], blt[2], blt[3], blt[4], blt[5], blt[6], blt[7], - blt[8], blt[9], blt[10], blt[11], blt[12], blt[13], blt[14], blt[15]); - } - } - return SCPE_OK; } -if (sw & SWMASK ('C')) { - c2 = ebcdic_to_ascii[c1]; - if (c2 < 040 || c2 > 0177) { - sprintf(strg, "<%02X>", c1 & 0xff); - } else { - sprintf (strg, "%c", c2 & 0xff); - } - return SCPE_OK; } -if (!(sw & SWMASK ('M'))) return SCPE_ARG; - -inst = val[0] & 0x0f; -len1 = (val[0] >> 6) & 3; -len2 = (val[0] >> 4) & 3; -group = (val[0] >> 4) & 0x0f; -qbyte = val[1]; - -/* Get total length of instruction */ - -if (group == 0x0f) { - oplen = 3; -} else { - oplen = 2; - if (len1 == 0) oplen += 2; - if (len1 == 1 || len1 == 2) oplen++; - if (len2 == 0) oplen += 2; - if (len2 == 1 || len2 == 2) oplen++; -} - -/* Find which group it belongs to */ - -switch (group) { - case 0x0f: - groupno = 0; - break; - case 0x0c: - case 0x0d: - case 0x0e: - groupno = 1; - break; - case 0x03: - case 0x07: - case 0x0b: - groupno = 3; - break; - default: - groupno = 2; - break; -} - -/* find the table entry */ - -for (i = 0; i < nopcode; i++) { - if (opcode[i].form < 7) { /* Explicit Q */ - if (opcode[i].group == groupno && - opcode[i].opmask == inst) break; - } else { /* Implicit Q */ - if (opcode[i].group == groupno && - opcode[i].opmask == inst && - opcode[i].q == qbyte) break; - } -} - -/* print the opcode */ - -if (i >= nopcode) { - sprintf(strg, "%02X", val[0]); - oplen = 1; -} else { - sprintf(bld, "%s ", opcode[i].op); - - /* Extract the addresses into aaddr and baddr */ - - strcpy(aoperand, "ERROR"); - strcpy(boperand, "ERROR"); - vpos = 2; - aaddr = baddr = 0; - switch (len1) { - case 0: - baddr = ((val[vpos] << 8) & 0xff00) | (val[vpos + 1] & 0x00ff); - sprintf(boperand, "%04X", baddr); - vpos = 4; - break; - case 1: - baddr = val[vpos] & 255; - sprintf(boperand, "(%02X,XR1)", baddr); - vpos = 3; - break; - case 2: - baddr = val[vpos] & 255; - sprintf(boperand, "(%02X,XR2)", baddr); - vpos = 3; - break; - default: - baddr = 0; - break; - } - switch (len2) { - case 0: - aaddr = ((val[vpos] << 8) & 0xff00) | (val[vpos + 1] & 0x00ff); - if (group == 0x0C || group == 0x0D || group == 0x0E) - sprintf(boperand, "%04X", aaddr); - else - sprintf(aoperand, "%04X", aaddr); - break; - case 1: - aaddr = val[vpos] & 255; - if (group == 0x0C || group == 0x0D || group == 0x0E) - sprintf(boperand, "(%02X,XR1)", aaddr); - else - sprintf(aoperand, "(%02X,XR1)", aaddr); - break; - case 2: - aaddr = val[vpos] & 255; - if (group == 0x0C || group == 0x0D || group == 0x0E) - sprintf(boperand, "(%02X,XR2)", aaddr); - else - sprintf(aoperand, "(%02X,XR2)", aaddr); - break; - default: - aaddr = 0; - break; - } - - /* Display the operands in the correct format */ - - da = (qbyte >> 4) & 0x0f; - m = (qbyte >> 3) & 0x01; - n = (qbyte) & 0x07; - - switch (opcode[i].form) { - case 0: - sprintf(bldaddr, "%02X,%02X", qbyte, val[2]); - break; - case 1: - if (inst == 2 || inst == 4 || inst == 5 || inst == 6) { - for (i = 0; i < 16; i++) { - if (regcode[i] == qbyte) - break; - } - if (i < 16) { - sprintf(bldaddr, "%s,%s", regname[i], boperand); - } else { - sprintf(bldaddr, "%02X,%s", qbyte, boperand); - } - } else { - sprintf(bldaddr, "%02X,%s", qbyte, boperand); - } - break; - case 2: - if (inst > 9 || inst == 4 || inst == 6 || inst == 7) - qbyte++; /* special +1 for length display */ - sprintf(bldaddr, "%s,%s,%d", boperand, aoperand, qbyte); - break; - case 3: - if (strcmp(opcode[i].op, "JC") == 0) { - sprintf(bldaddr, "%04X,%02X", addr+oplen+val[2], qbyte); - } else { - sprintf(bldaddr, "%s,%02X", boperand, qbyte); - } - break; - case 4: - sprintf(bldaddr, "%d,%d,%d", da, m, n); - break; - case 5: - sprintf(bldaddr, "%d,%d,%d,%02X", da, m, n, val[2]); - break; - case 6: - sprintf(bldaddr, "%d,%d,%d,%s", da, m, n, boperand); - break; - case 7: - sprintf(bldaddr, "%04X", addr+oplen+val[2]); - break; - case 8: - sprintf(bldaddr, "%s", boperand); - break; - default: - sprintf(bldaddr, "%s,%s", boperand, aoperand); - break; - } - sprintf(strg, "%s%s", bld, bldaddr); -} - -return -(oplen - 1); -} - -/* Symbolic input - - Inputs: - *cptr = pointer to input string - addr = current PC - *uptr = pointer to unit - *val = pointer to output values - sw = switches - Outputs: - status = error status -*/ - -t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw) -{ -int32 cflag, i = 0, j, r, oplen, addtyp, saveaddr, vptr; -char gbuf[CBUFSIZE]; - -cflag = (uptr == NULL) || (uptr == &cpu_unit); -while (isspace (*cptr)) cptr++; /* absorb spaces */ -if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */ - if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */ - val[0] = (unsigned int) cptr[0]; - return SCPE_OK; -} -if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* ASCII string? */ - if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */ - val[0] = ((unsigned int) cptr[0] << 8) + (unsigned int) cptr[1]; - return SCPE_OK; -} - -/* An instruction: get opcode (all characters until null, comma, left paren, - or numeric (including spaces). -*/ - -while (1) { - if (*cptr == ',' || *cptr == '\0' || *cptr == '(' || - isdigit(*cptr)) - break; - gbuf[i] = toupper(*cptr); - cptr++; - i++; -} - -/* kill trailing spaces if any */ -gbuf[i] = '\0'; -for (j = i - 1; gbuf[j] == ' '; j--) { - gbuf[j] = '\0'; -} - -/* find opcode in table */ -for (j = 0; j < nopcode; j++) { - if (strcmp(gbuf, opcode[j].op) == 0) - break; -} -if (j >= nopcode) /* not found */ - return SCPE_ARG; - -oplen = 2; /* start with op & q */ - -val[0] = opcode[j].opmask; /* store opcode right nybble */ - -switch (opcode[j].form) { /* Get operands based on operand format */ - case 0: /* Single Byte Operand */ - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); /* Get Q Byte */ - sscanf(gbuf, "%x", &r); - val[1] = r; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); /* Get R Byte */ - sscanf(gbuf, "%x", &r); - val[2] = r; - oplen = 3; - val[0] = 0xf0 | opcode[j].opmask; - break; - case 1: - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - if (opcode[j].opmask == 2 || - opcode[j].opmask == 4 || - opcode[j].opmask == 5 || - opcode[j].opmask == 6) { - if (isdigit(gbuf[0])) { - sscanf(gbuf, "%x", &r); - } else { - for (i = 0; i < 16; i++) { - if (strcmp(gbuf, regname[i]) == 0) - break; - } - if (i < 16) { - r = regcode[i]; - } else { - return SCPE_ARG; - } - } - } else { - sscanf(gbuf, "%x", &r); - } - if (r > 255) return SCPE_ARG; - val[1] = r; - if (*cptr == ',') cptr++; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[2] = (addr >> 8) & 0x00ff; - val[3] = addr & 0xff; - oplen = 4; - if (opcode[j].group == 1) - val[0] = 0xC0 | opcode[j].opmask; - else - val[0] = 0x30 | opcode[j].opmask; - break; - case 1: - val[2] = addr & 0xff; - oplen = 3; - if (opcode[j].group == 1) - val[0] = 0xD0 | opcode[j].opmask; - else - val[0] = 0x70 | opcode[j].opmask; - break; - case 2: - val[2] = addr & 0xff; - oplen = 3; - if (opcode[j].group == 1) - val[0] = 0xE0 | opcode[j].opmask; - else - val[0] = 0xB0 | opcode[j].opmask; - break; - default: - return SCPE_ARG; - break; - } - break; - case 2: - oplen = 2; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[2] = (addr >> 8) & 0xff; - val[3] = addr & 0xff; - oplen += 2; - vptr = 4; - val[0] = 0x00 | opcode[j].opmask; - break; - case 1: - val[2] = addr & 0xff; - oplen += 1; - vptr = 3; - val[0] = 0x40 | opcode[j].opmask; - break; - case 2: - val[2] = addr & 0xff; - oplen += 1; - vptr = 3; - val[0] = 0x80 | opcode[j].opmask; - break; - default: - return SCPE_ARG; - break; - } - if (*cptr == ',') cptr++; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[vptr] = (addr >> 8) & 0xff; - val[vptr+1] = addr & 0xff; - oplen += 2; - break; - case 1: - val[vptr] = addr & 0xff; - oplen += 1; - val[0] = 0x10 | val[0]; - break; - case 2: - val[vptr] = addr & 0xff; - oplen += 1; - val[0] = 0x20 | val[0]; - break; - default: - return SCPE_ARG; - break; - } - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); - sscanf(gbuf, "%d", &r); - if (opcode[j].opmask > 9 || - opcode[j].opmask == 4 || - opcode[j].opmask == 6 || - opcode[j].opmask == 7) r--; /* special: length -1 */ - val[1] = r; - if (*cptr == ',') cptr++; - break; - case 3: - saveaddr = addr; - if (*cptr == ',') cptr++; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - if (opcode[j].group == 0) { /* Group 0 form 3 is JC with explicit Q */ - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); - sscanf(gbuf, "%x", &r); - if ((addr - (saveaddr+3)) > 255 || (addr - (saveaddr+3)) < 1) - return SCPE_ARG; - val[2] = addr - (saveaddr+3); - val[1] = r; - val[0] = 0xf0 | opcode[j].opmask; - oplen = 3; - - } else { - val[2] = (addr >> 8) & 0x00ff; - val[3] = addr & 0xff; - oplen = 4; - if (opcode[j].group == 1) - val[0] = 0xC0 | opcode[j].opmask; - else - val[0] = 0x30 | opcode[j].opmask; - } - break; - case 1: - val[2] = addr & 0xff; - oplen = 3; - if (opcode[j].group == 1) - val[0] = 0xD0 | opcode[j].opmask; - else - val[0] = 0x70 | opcode[j].opmask; - break; - case 2: - val[2] = addr & 0xff; - oplen = 3; - if (opcode[j].group == 1) - val[0] = 0xE0 | opcode[j].opmask; - else - val[0] = 0xB0 | opcode[j].opmask; - break; - default: - return SCPE_ARG; - break; - } - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); - sscanf(gbuf, "%x", &r); - if (r > 255) return SCPE_ARG; - val[1] = r; - break; - case 4: - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 15) return SCPE_ARG; - val[1] = (r << 4) & 0xf0; - val[0] = 0xf0 | opcode[j].opmask; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 1) return SCPE_ARG; - val[1] |= (r << 3) & 0x08; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); - sscanf(gbuf, "%d", &r); - if (r > 7) return SCPE_ARG; - val[1] |= r & 0x07; - val[2] = 0; - oplen = 3; - break; - case 5: - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 15) return SCPE_ARG; - val[1] = (r << 4) & 0xf0; - val[0] = 0xf0 | opcode[j].opmask; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 1) return SCPE_ARG; - val[1] |= (r << 3) & 0x08; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 7) return SCPE_ARG; - val[1] |= r & 0x07; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); - sscanf(gbuf, "%x", &r); - if (r > 255) return SCPE_ARG; - val[2] = r; - oplen = 3; - break; - case 6: - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 15) return SCPE_ARG; - val[1] = (r << 4) & 0xf0; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 1) return SCPE_ARG; - val[1] |= (r << 3) & 0x08; - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - sscanf(gbuf, "%d", &r); - if (r > 7) return SCPE_ARG; - val[1] |= r & 0x07; - if (*cptr == ',') cptr++; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[2] = (addr >> 8) & 0x00ff; - val[3] = addr & 0xff; - oplen = 4; - if (opcode[j].group == 1) - val[0] = 0xC0 | opcode[j].opmask; - else - val[0] = 0x30 | opcode[j].opmask; - break; - case 1: - val[2] = addr & 0xff; - oplen = 3; - if (opcode[j].group == 1) - val[0] = 0xD0 | opcode[j].opmask; - else - val[0] = 0x70 | opcode[j].opmask; - break; - case 2: - val[2] = addr & 0xff; - oplen = 3; - if (opcode[j].group == 1) - val[0] = 0xE0 | opcode[j].opmask; - else - val[0] = 0xB0 | opcode[j].opmask; - break; - default: - return SCPE_ARG; - break; - } - break; - case 7: - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, 0); - sscanf(gbuf, "%x", &r); - if ((r - (addr+3)) > 255 || (r - (addr+3)) < 1) return SCPE_ARG; - val[2] = r - (addr+3); - val[1] = opcode[j].q; - val[0] = 0xf0 | opcode[j].opmask; - oplen = 3; - break; - - case 8: - if (*cptr == ',') cptr++; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[2] = (addr >> 8) & 0x00ff; - val[3] = addr & 0xff; - oplen = 4; - val[0] = 0xC0 | opcode[j].opmask; - break; - case 1: - val[2] = addr & 0xff; - oplen = 3; - val[0] = 0xD0 | opcode[j].opmask; - break; - case 2: - val[2] = addr & 0xff; - oplen = 3; - val[0] = 0xE0 | opcode[j].opmask; - break; - default: - return SCPE_ARG; - break; - } - val[1] = opcode[j].q; - break; - case 9: - oplen = 2; - val[0] = 0; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[2] = (addr >> 8) & 0xff; - val[3] = addr & 0xff; - oplen += 2; - vptr = 4; - val[0] = 0x00 | opcode[j].opmask; - break; - case 1: - val[2] = addr & 0xff; - oplen += 1; - vptr = 3; - val[0] = 0x40 | opcode[j].opmask; - break; - case 2: - val[2] = addr & 0xff; - oplen += 1; - vptr = 3; - val[0] = 0x80 | opcode[j].opmask; - break; - default: - return SCPE_ARG; - break; - } - if (*cptr == ',') cptr++; - cptr = parse_addr(cptr, gbuf, &addr, &addtyp); - switch(addtyp) { - case 0: - val[vptr] = (addr >> 8) & 0xff; - val[vptr+1] = addr & 0xff; - oplen += 2; - break; - case 1: - val[vptr] = addr & 0xff; - oplen += 1; - val[0] = 0x10 | val[0]; - break; - case 2: - val[vptr] = addr & 0xff; - oplen += 1; - val[0] = 0x20 | val[0]; - break; - default: - return SCPE_ARG; - break; - } - val[1] = opcode[j].q; - break; - default: - break; -} - - -return (-(oplen-1)); -} - -char *parse_addr(char *cptr, char *gbuf, t_addr *addr, int32 *addrtype) -{ -int32 nybble = 0; -char temp[32]; - -cptr = get_glyph(cptr, gbuf, ','); -if (gbuf[0] == '(') { /* XR relative */ - strcpy(temp, gbuf+1); - sscanf(temp, "%x", addr); - if (*cptr == ',') cptr++; - cptr = get_glyph(cptr, gbuf, ','); - nybble = -1; - if (strcmp(gbuf, "XR1)") == 0) - nybble = 1; - if (strcmp(gbuf, "XR2)") == 0) - nybble = 2; -} else { /* Direct */ - sscanf(gbuf, "%x", addr); - nybble = 0; -} -*addrtype = nybble; -return cptr; -} - diff --git a/S3/system3.txt b/S3/system3.txt deleted file mode 100644 index e01a97df..00000000 --- a/S3/system3.txt +++ /dev/null @@ -1,472 +0,0 @@ - The IBM System/3 simulator is configured as follows: - - CPU 5410 (Model 10) CPU with 64KB of memory. - PKB 5471 Printer/Keyboard console. - CDR 1442 Card Reader - CDP 1442 Card Punch - CDP2 1442 2nd stacker - LPT 1403 Line Printer - R1 5444 Top Drive (removeable) - F1 5444 Top Drive (fixed) - R2 5444 Bottom Drive (removeable) - F2 5444 Bottom Drive (fixed - - The only CPU options are to set Model 15 mode (not implemented), DPF -(Dual Programming Facility, not implemented), and the memory size 8K, 16K, -32K, 48K, or 64K. - - CPU registers are the standard System/3 set: - - name size Description - - IAR-P1 16 Instruction Address Register for Program Level 1 - ARR-P2 16 Address Recall Register for Program Level 1 - IAR-P2 16 IAR for Program Level 2 (not implemented) - ARR-P2 16 ARR for Program Level 2 (not implemented) - AAR 16 A-Address Register - BAR 16 B-Address Register - PSR 16 Program Status Register - XR1 16 Index Register 1 - XR2 16 Index Register 2 - IAR<0:7> 16 IAR for interrupt level 0 thru 7 - ARR<0:7> 16 ARR for interrupt level 0 thru 7 - - Plus these simulator registers: - - IAR 16 Value of last IAR used. - LEVEL 8 Current operating level (8=P1, 9=P2, - 0 thru 7 = Interrupt level) - SR 16 Front Panel switches - INT 16 Interrupt Request Flags - WRU 8 Simulator Interrupt Character - BREAK 17 Breakpoint Address - DEBUG 16 Debugging bits: - 0x01: Write all instructions executed to - file trace.log. - 0x02: Write details of all Disk I/O - requests to trace.log. - 0x80: Breakpoint on first character - written to 5471 printer. - -1 5471 Printer/Keyboard - - This is the operator console. It has the following registers: - - FLAG 5471 Flag Bytes - IBUF: Input character from keyboard - OBUF: Output character to printer - POS: Number of characters printed - TIME: Delay for device operation - REQKEY: ASCII value of key mapped to 5471 REQUEST key - RTNKEY: ASCII value of key mapped to 5471 RETURN key - ENDKEY: ASCII value of key mapped to 5471 END key - CANKEY: ASCII value of key mapped to 5471 CANCEL key - - -2 1442 Card Reader. This reader reads 80-column cards; the input - is usually an ASCII file which is translated to EBCDIC when read, - but optionally can be a binary file in EBCDIC format (such as an - object program). - - LAST Last card switch - ERR Card Reader Error - NOTRDY 1442 reader not ready (not attached or past EOF) - DAR Data Address Register (shared with punch) - LCR Length Count Register (shared with punch) - EBCDIC EBCDIC mode flag: if 1, input is 80-col EBCDIC binary. - (IPL from 1442 automatically sets this to 1). - S2 Stacker 2 is selected when this is 1 - POS Number of cards read - TIME Device Delay - - The real hardware 1442 had only 1 hopper for cards, whether - these were used for blank cards for punching, or cards to be - read. Cards could be read without a feed cycle, then - punched. When punching cards, the SCP does a read of a card, - makes sure it is blank, and then punches it. To simulate - this without requiring that a stack of blank lines be attached - to the card reader device, a special feature of the simulator - is this: if no file is attached to the cdr device, but a file - is attached to the cdp or the cdp2 devices, any read from the - reader will return a blank card -- i.e. when punching, an - unattached cdr device is assumed to be loaded with an unlimited - supply of blank cards. - - -3 1442 Card Punch. Normally cards are written to the attached - disk file as ASCII with newline/cr delimiters. But an optional - flag allows writing as 80-column binary EBCDIC. - - ERR Card Punch Error - EBCDIC When this is 1, output will be 80-col EBCDIC. - S2 When this is 1, output is placed in stacker 2 - NOTRDY 1442 punch not ready (not attached) - DAR Data Address Register (shared with reader) - LCR Length Count Register (shared with reader) - POS Number of cards punched - TIME Device Delay - -4 1442 Stacker 2. When cards are to be punched in stacker 2, - attach a disk file to this device (cdp2) to hold that output. - Note: When SCP punches cards, the default is to punch in - stacker 2. - - POS0 Number of cards punched. - -5 1403 Printer. This is a 132-column output device, emulating - the famous IBM 1403, models 2, 6, and N1. Output is always - translated to ASCII with newline/CR delimiters. Page advance - is output as a form feed. - - ERR 1403 error flags - LPDAR Data Address Register - LPFLR Forms Length Register - LPIAR Image Address Register - LINECT Current Line on form - POS Number of lines printed - -6 5444 Disk Drives (R1, R2, F1, F2) - - The 5444 came as a set of two drives, each with two disks. The - top disk in a drive was removable, the bottom fixed. The first - drive consists of disks R1 and F1, the second drive R2 and F2. - Each disk holds 2,467,600 bytes of user data, plus 3 alternate - tracks and a CE track. Flagging of alternate tracks is not - supported in this version of the simulator. - - NOTRDY Drive not ready (not attached) - SEEK Drive is busy with a seek operation - DAR Data Address Register - CAR Control Address Register - ERR Error Flags (16 bits) - CYL Current Cylinder (0 thru 203) - HEAD Current head (0 or 1) - POS Current position in attached disk file - TIME Device Delay - -7 Symbolic Display and Input - - The System/3 Simulator supports symbolic display and input. - Display is controlled by command line switches: - - (none) display as hex EBCDIC - -c display bytes as characters - -m display instruction mnemonics. - -a display a 256-byte block of memory in both hex and ASCII. - - The symbolic format contains the same elements as the machine - language operation, but not always in the same order. The - operation code frequently specifies both the opcode and the Q byte, - and the top nybble of the opcode is determined by the format of the - addresses. - - Addresses take two forms: the direct address in hex, or a relative - address specified thusly: (byte,XRx) where 'byte' is a 1-byte - offset, and XRx is either XR1 or XR2 for the two index registers. - Use these formats when 'address' is indicated below: - - When 'reg' is mentioned, a mnemonic may be used for the register, - thusly: - - IAR Instruction Address Register for the current program level - ARR Address Recall Register for the current program level - P1IAR IAR for Program Level 1 - P2IAR IAR for Program Level 2 - PSR Program Status Register - XR1 Index Register 1 - XR2 Index Register 2 - IARx IAR for the interrupt level x (x = 0 thru 7) - - All other operands mentioned below are single-byte hex, except for - the length (len) operand of the two-address instructions, which is a - decimal length in the range 1-256. - - In operations where there is a source and a destination, the - destination is always operand 1, the source is operand 2. - - No-address formats: - ------------------ - - HPL hex,hex Halt Program Level, the operands are the - Q and R bytes. - - - One-address formats: - ------------------- - - A reg,address Add to register - CLI address,byte Compare Logical Immediate - MVI address,byte Move Immediate - TBF address,mask Test Bits Off - TBN address,mask Test Bits On - SBF address,mask Set Bits Off - SBN address,mask Set Bits On - ST reg,address Store Register - L reg,address Load Register - LA reg,address Load Address (reg can only be XR1 or XR2) - JC address,cond Jump on Condition - BC address,cond Branch on Condition - - These operations do not specify a qbyte, it is implicit in the - opcode: - - B address Unconditional branch to address - BE address Branch Equal - BNE address Branch Not Equal - BH address Branch High - BNH address Branch Not High - BL address Branch Low - BNL address Branch Not Low - BT address Branch True - BF address Branch False - BP address Branch Plus - BM address Branch Minus - BNP address Branch Not Plus - BNM address Branch Not Minus - BZ address Branch Zero - BNZ address Branch Not Zero - BOZ address Branch Overflow Zoned - BOL address Branch Overflow Logical - BNOZ address Branch No Overflow Zoned - BNOL address Branch No Overflow Logical - NOPB address No - never branch - - (substitute J for B above for a set of Jumps -- 1-byte operand (not - 2), always jumps forward up to 255 bytes from the address following - the Jump instruction. In this case, 'address' cannot be less than - the current address, nor greater than the current address + 255) - - Two-address formats (first address is destination, len is decimal 1-256): - ------------------- - - MVC address,address,len Move Characters - CLC address,address,len Compare Logical Characters - ALC address,address,len Add Logical Characters - SLC address,address,len Subtract Logical Characters - ED address,address,len Edit - ITC address,address,len Insert and Test Characters - AZ address,address,len Add Zoned Decimal - SZ address,address,len Subtract Zoned Decimal - - MNN address,address Move Numeric to Numeric - MNZ address,address Move Numeric to Zone - MZZ address,address Move Zone to Zone - MZN address,address Move Zone to Numeric - - I/O Format - ---------- - - In the I/O format, there are always 3 fields: - - da - Device Address 0-15 (decimal) - m - Modifier 0-1 - n - Function 0-7 - - The meaning of these is entirely defined by the device addressed. - - There may be an optional control byte, or an optional address (based - on the type of instruction). - - SNS da,m,n,address Sense I/O - LIO da,m,n,address Load I/O - TIO da,m,n,address Test I/O - - SIO da,m,n,cc Start I/O -- cc is a control byte - - APL da,m,n Advance Program Level - - -8 Device Programming. - - Note: On a model 15, interrupts are used for all devices. On - other models, interrupts are only used for the printer/keyboard. - - This is a summary of the DA, M, N, and CC codes for all supported - devices: - - 5471 Printer Keyboard - --------------------- - - The PKB has 2 visible indicators: Proceed and Request - Pending. It has a normal keyboard and 4 special keys: - Request, Return, End, and Cancel. - - SIO 1,0,0,XX Start Keyboard Operation, bit masks for XX are: - X'20': Request Pending Indicator On - X'10': Proceed Indicator On - X'04': Request Key Interrupts Enable (1) Disable (0) - X'02': Other Key Interrupts Enable (1) Disable (0) - X'01': Reset request key and other key interrupts - - SIO 1,1,0,XX Start Printer Operation, bit masks for XX are: - X'80': Start Printing - X'40': Start Carrier Return - X'04': Printer Interrupt Enable(1) or Disable (0) - X'01': Reset Printer Interrupt - - LIO 1,1,0,addr Load Printer Output Character - addr is address of low-order (highest numbered) - byte of two-byte field, and high-order byte - (that is, addr - 1) is loaded into output - register to print. Printing is done one character - at a time. - - SNS 1,0,1,addr Sense Status Bytes 0 and 1: - Byte 0 (leftmost) is the character typed in - in EBCDIC. - Byte 1 is status: - X'80': Request key interrupt pending - X'40': End or Cancel key interrupt pending - X'20': Cancel key pressed - X'10': End Key Pressed - X'08': Return or data key interrupt pending - X'04': Return key pressed - - SNS 1,0,3,addr Sense Status Bytes 2 and 3: returns 0000 in - this sim. - - 1442 Reader/Punch - ----------------- - - SIO 5,0,0,XX Feed Card without reading/punching - XX is stacker select for all functions: 0 = stacker - 1 (normal), 1 = stacker 2. - - SIO 5,0,1,XX Read Card - SIO 5,0,2,XX Punch and Feed - SIO 5,0,3,XX Read Column Binary - SIO 5,0,4,XX Punch with no feed - - TIO 5,0,0,addr Branch to addr if not ready or busy - TIO 5,0,2,addr Branch to addr if busy - TIO 5,0,5,addr (mod 15 only) branch if interrupt pending - - APL 5,0,0 Loop (or switch prog levels) if not ready/busy - APL 5,0,2 Loop (or switch) if busy - APL 5,0,5 Loop (or switch) if interrupt pending (mod 15 only) - - LIO 5,0,0,addr Load 2-byte field to Length Count Register - LIO 5,0,4,addr Load 2-byte field to Data Address Register - (DAR is incremented by a read/punch operation and must - be reset every card) - - SNS 5,0,1,addr Sense CE indicators (0000 returned in this sim) - SNS 5,0,2,addr Sense CE indicators (0000 returned in this sim) - SNS 5,0,3,addr Sense Status Indicators: (only simulated bits shown) - X'8000': Read Check - X'4000': Last Card - X'2000': Punch Check - X'1000': Data Overrun - X'0800': Not Ready - - - 1403 Printer - ------------ - - SIO 14,0,0,XX Line space XX lines (0-3 valid in XX) - SIO 14,0,2,XX Print a line space (0-3 valid in XX) - SIO 14,0,4,XX Skip Only (line number 1-112 in XX) - - SIO 14,0,6,XX Print and Skip (line number 0-112 in XX) - - TIO 14,0,0,addr Branch to addr if not ready - TIO 14,0,2,addr Branch to addr if buffer busy - TIO 14,0,3,addr Branch to addr if interrupt pending (mod 15 only) - TIO 14,0,4,addr Branch if carriage busy - TIO 14,0,6,addr Branch if printer busy - - APL 14,0,0 Loop (or switch prog levels) if not ready/check - APL 14,0,2 Loop (or switch) if buffer busy - APL 14,0,3 Loop (or switch) if interrupt pending (mod 15 only) - APL 14,0,4 Loop (or switch) if carriage busy - APL 14,0,6 Loop (or switch) if printer busy - - LIO 14,0,0,addr Load 1 byte to Forms Length Reg at addr-1 - LIO 14,0,4,addr Load 2 bytes to Chain Image Address Register - LIO 14,0,6,addr Load 2 bytes to Data Address Register - - SNS 14,0,0,addr Sense Character Count - SNS 14,0,4,addr Sense LPIAR (Image Address Register) - SNS 14,0,6,addr Sense LPDAR (data addres register) - - - 5444 Disk Drives - ---------------- - - Each drive has two disks (upper and lower), each disk - has two surfaces (upper and lower), each surface has - 24 256-byte sectors, sectors are number 0 thru 23 on - upper surface, 32 thru 55 on lower. - - d = drive, 0 is R1/F1, 1 is R2/F2 - s = surface, 0 = upper (removable), 1 = lower (fixed) - - The Control register points to the leftmost byte of a 4-byte - control field in memory with these bytes: - - F - Flag byte (not supported in this sim) - C - Cylinder Address (0-203) - S - Sector Number (0-23, or 32-55) in top 6 bits - N - Number of sectors minus 1 - - These have meaning for all operations except seek, seek uses - the fields differently. - - SIO 1d,s,0,XX Seek, XX not used, control field is used: - - F - not used - C - not used - S - high bit is head to be used 0-upper 1-lower - low bit is direction to move 0-back 1-forward - N - number of cylinders to move - - SIO 1d,s,1,XX Read, values of XX are as follows: - X'00': Read Data - X'01': Read Identifier (updates control field, no - data is read) - X'02': Read Data Diagnostic - X'03': Verify (does not read, but checks) - - SIO 1d,s,2,XX Write, values of XX are as follows: - X'00': Write Data - X'01': Write Identifier (24 sectors with byte at - data address register) - - SIO 1d,s,3,XX Scan. All 256 bytes in memory at data - address register are compared to disk - sectors on current track, except those - bytes of X'FF' are not compared. Values of - XX are: - - X'00': Scan Equal - X'01': Scan Low or Equal - X'02': Scan High or Equal - - LIO 1d,0,4,addr Load Data Address Register - LIO 1d,0,6,addr Load Disk Control Address Register - - TIO 1d,0,0,addr Branch if not ready/unit check - TIO 1d,0,2,addr Branch if busy - TIO 1d,0,4,addr Branch if Scan Found - - APL 1d,0,0 Loop if not ready/unit check - APL 1d,0,2 Loop if busy - APL 1d,0,4 Loop if scan found - - SNS 1d,0,2,addr Sense Status Bytes 0 and 1: (simulated - bits only are shown, otehrs are 0): - X'1000': equipment check - X'0800': data check - X'0400': No record found - X'0100': Seek Check (past cyl 203) - X'0080': Scan equal Hit - X'0040': Cylinder 0 - X'0020': End of Cylinder - X'0010': Seek Busy - SNS 1d,0,3,addr Sense bytes 2 and 3 (0000 in this sim) - SNS 1d,0,4,addr Sense Data Address Register - SNS 1d,0,6,addr Sense Control Address Register - - - - diff --git a/Visual Studio Projects/S3.vcproj b/Visual Studio Projects/S3.vcproj deleted file mode 100644 index 85d75574..00000000 --- a/Visual Studio Projects/S3.vcproj +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Visual Studio Projects/Simh.sln b/Visual Studio Projects/Simh.sln index b52c6d7a..a3f12fe9 100644 --- a/Visual Studio Projects/Simh.sln +++ b/Visual Studio Projects/Simh.sln @@ -19,8 +19,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDP8", "PDP8.vcproj", "{5EB EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDP10", "PDP10.vcproj", "{A39C0AFE-BDE5-4236-B740-AC710FCA1DA2}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "S3", "S3.vcproj", "{927C3BD9-BD0C-4A23-99F9-573A40236509}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SDS", "SDS.vcproj", "{750762C6-A2AF-40BA-A006-5E68002C1E87}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PDP11", "PDP11.vcproj", "{49499E1B-5019-4B98-9DC7-2E73306D5578}" @@ -95,10 +93,6 @@ Global {A39C0AFE-BDE5-4236-B740-AC710FCA1DA2}.Debug|Win32.Build.0 = Debug|Win32 {A39C0AFE-BDE5-4236-B740-AC710FCA1DA2}.Release|Win32.ActiveCfg = Release|Win32 {A39C0AFE-BDE5-4236-B740-AC710FCA1DA2}.Release|Win32.Build.0 = Release|Win32 - {927C3BD9-BD0C-4A23-99F9-573A40236509}.Debug|Win32.ActiveCfg = Debug|Win32 - {927C3BD9-BD0C-4A23-99F9-573A40236509}.Debug|Win32.Build.0 = Debug|Win32 - {927C3BD9-BD0C-4A23-99F9-573A40236509}.Release|Win32.ActiveCfg = Release|Win32 - {927C3BD9-BD0C-4A23-99F9-573A40236509}.Release|Win32.Build.0 = Release|Win32 {750762C6-A2AF-40BA-A006-5E68002C1E87}.Debug|Win32.ActiveCfg = Debug|Win32 {750762C6-A2AF-40BA-A006-5E68002C1E87}.Debug|Win32.Build.0 = Debug|Win32 {750762C6-A2AF-40BA-A006-5E68002C1E87}.Release|Win32.ActiveCfg = Release|Win32