From 2dda7676787e981d1d672d8d0bfdbcc36c5e0a0d Mon Sep 17 00:00:00 2001 From: sboydlns Date: Thu, 31 Dec 2020 15:47:14 -0500 Subject: [PATCH] Updates for 1230 emulation. --- AlgolV2/Algol.dproj | 2 +- AlgolV2/AlgolV2.pjt | 6 +- AlgolV2/U494CodeGen.pas | 2 +- AlgolV2/test.alg | 2 +- U494/Algol/Buildalgrt.bat | 6 +- U494/Algol/RTTest.asm | 2 +- U494/Algol/algrt.asm | 12 +- U494/Algol/algrt.pjt | 8 +- U494/Docs/Monitor6.odt | Bin 0 -> 18355 bytes U494/Docs/U494.odt | Bin 68343 -> 69506 bytes U494/FH880Device.pas | 14 +- U494/Procs/ExecReturn.proc | 4 +- U494/Setup/U494.iss | 13 +- U494/Source/BcdTest.asm | 2 +- U494/Source/BcdTest.pjt | 4 +- U494/Source/BuildMOS.bat | 5 +- U494/Source/Cave.asm | 22 +- U494/Source/Cave.pjt | 8 +- U494/Source/FileUtil.asm | 4 +- U494/Source/FileUtil.pjt | 6 +- U494/Source/FloatTest.asm | 2 +- U494/Source/FloatTest.pjt | 6 +- U494/Source/HelloWorld.pjt | 4 +- U494/Source/MOS.pjt | 12 +- U494/Source/Monitor6.spurt | 32 +- U494/Spurt.pas | 2 +- U494/U1230.cfg | 4 + U494/U490.cfg | 15 + U494/U494.cfg | 15 + U494/U494.dproj | 3 +- U494/U494Config.pas | 160 ++++++++- U494/U494ConsDevice.pas | 10 +- U494/U494Console.dpr | 1 + U494/U494Console.dproj | 6 +- U494/U494ConsoleFrm.dfm | 22 +- U494/U494ConsoleFrm.pas | 66 +++- U494/U494Cpu.pas | 719 +++++++++++++++++++++++++++++-------- U494/U494Memory.pas | 261 +++++++++++--- U494/U494Opcodes.pas | 85 ++++- U494/U494Panel.dfm | 4 - U494/U494Panel.pas | 56 ++- U494/U494Printer.pas | 4 +- U494/U494Reader.pas | 20 +- U494/U494System.pas | 187 +++++++--- U494/U494Util.pas | 4 + 45 files changed, 1440 insertions(+), 382 deletions(-) create mode 100644 U494/Docs/Monitor6.odt diff --git a/AlgolV2/Algol.dproj b/AlgolV2/Algol.dproj index dd23c13..d466794 100644 --- a/AlgolV2/Algol.dproj +++ b/AlgolV2/Algol.dproj @@ -64,7 +64,7 @@ 3 true - ..\..\Tests\test4.alg + ..\..\test.alg 1033 None Algol_Icon.ico diff --git a/AlgolV2/AlgolV2.pjt b/AlgolV2/AlgolV2.pjt index eb512e0..54a834d 100644 --- a/AlgolV2/AlgolV2.pjt +++ b/AlgolV2/AlgolV2.pjt @@ -25,9 +25,9 @@ SysSetCwd='C:\Development\Emulators\U494' SrchSetFlags=0x4418600b FileSortMode=0x0 StateWindowFrame=0,1,1142,1082,0x63097f08 -_StateWindow=52,52,662,556,0x00100010,'C:\Development\Emulators\U494\U1230.cfg',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,4,9,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 -_StateBuffer='C:\Development\Emulators\U494\U1230.cfg',0x0400048a,4,9,25,'6 12 17 22 27 32 37 41','',0x1,'',1,72,1 -_StateHistory=FILELIST,'C:\Development\Emulators\U494\Source\MOS.lst','C:\Development\Emulators\U494\Algol\algrt.asm','D:\LIB\37873205\F02_05.PDA','C:\Development\Emulators\U494\Source\Monitor6.spurt','C:\Development\Emulators\U494\Source\monitor6.mem','C:\Development\Emulators\U9200\U9200.cfg','C:\Development\Emulators\U494\U490.cfg','C:\Development\Emulators\U494\U494.cfg','C:\Development\Emulators\U494\U1230.cfg' +_StateWindow=208,208,662,556,0x00100010,'C:\DEVELOPMENT\EMULATORS\ALGOLV2\test.alg',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,21,56,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 +_StateBuffer='C:\DEVELOPMENT\EMULATORS\ALGOLV2\test.alg',0x0c00048a,21,56,25,'4','',0x1,'',1,72,1 +_StateHistory=FILELIST,'D:\LIB\37873205\F02_05.PDA','C:\Development\Emulators\U494\Source\Monitor6.spurt','C:\Development\Emulators\U494\Source\monitor6.mem','C:\Development\Emulators\U9200\U9200.cfg','C:\Development\Emulators\U494\U490.cfg','C:\Development\Emulators\U494\U494.cfg','C:\Development\Emulators\U494\U1230.cfg','C:\DEVELOPMENT\EMULATORS\ALGOLV2\test.alg','C:\Development\Emulators\U494\Algol\Buildalgrt.bat' _StateHistory=SEARCH,'strarray','ccp$','ccp$cmds','l$0','extern','isi$ext','j$ext','io$savea','cons$ext','$ext' _StateHistory=XSYMBOL,'FILE','ARRAY','GetElements','GetLocation' _StateHistory=EDITFILE,'C:\Development\Emulators\AlgolV2\Tests\test4.s','C:\Development\Emulators\U494\Source\MOS.lst','C:\Development\Emulators\U494\Source\MOS.pjt','D:\LIB\37873205\F02_05.PDA','C:\Development\Emulators\U494\Source\Monitor6.spurt','C:\Development\Emulators\U494\Source\monitor6.mem','C:\Development\Emulators\U9200\U9200.cfg','C:\Development\Emulators\U494\U490.cfg','C:\Development\Emulators\U494\U494.cfg','C:\Development\Emulators\U494\U1230.cfg' diff --git a/AlgolV2/U494CodeGen.pas b/AlgolV2/U494CodeGen.pas index 1a8b390..07387d3 100644 --- a/AlgolV2/U494CodeGen.pas +++ b/AlgolV2/U494CodeGen.pas @@ -1186,7 +1186,7 @@ var heapSize: Integer; stemp: AnsiString; begin - Emit('', 'EXIT', '0'); + Emit('', 'HALT', '0'); Emit('', '.'); Emit('TEMP$AQ', 'RES', '2'); Emit('TEMP$AQ2', 'RES', '2'); diff --git a/AlgolV2/test.alg b/AlgolV2/test.alg index c52325f..d6f1a78 100644 --- a/AlgolV2/test.alg +++ b/AlgolV2/test.alg @@ -20,7 +20,7 @@ begin comment this is the main program starting point; for i := 1 while not done do done := true; - for i := 1 step 1 until i geq 10 do i := i * 2; + for i := 1 step 1 until 10 do i := i * 2; for i:= 1, 2, 3, 4 do i := i * 2; diff --git a/U494/Algol/Buildalgrt.bat b/U494/Algol/Buildalgrt.bat index 123384e..7e5003e 100644 --- a/U494/Algol/Buildalgrt.bat +++ b/U494/Algol/Buildalgrt.bat @@ -22,9 +22,11 @@ start /b notepad++ Algol\RTTest.map if errorlevel 1 goto end win32\debug\FH880Util -d Drums\sysvol.drum -i Bin\RTTest.mem -f RTTEST -lp -win32\debug\u494asm ..\AlgolV2\test.s -obj -P Procs -O ..\AlgolV2\Obj -noproc +..\AlgolV2\win32\debug\algol ..\Algol\test.alg if errorlevel 1 goto end -start /b notepad++ ..\AlgolV2\test.lst +win32\debug\u494asm ..\Algol\test.s -obj -P Procs -O ..\AlgolV2\Obj -noproc +if errorlevel 1 goto end +start /b notepad++ ..\Algol\test.lst if errorlevel 1 goto end win32\debug\u494link Obj\algrt.obj Obj\algio.obj Obj\algmath.obj ..\AlgolV2\Obj\test.obj -exe -o ..\AlgolV2\Bin\test.mem -l ..\AlgolV2\test.map diff --git a/U494/Algol/RTTest.asm b/U494/Algol/RTTest.asm index 0121490..51e7385 100644 --- a/U494/Algol/RTTest.asm +++ b/U494/Algol/RTTest.asm @@ -75,7 +75,7 @@ LBPJB1 WR$INT LBPJB1 WR$FLUSH . - EXIT 0 + HALT 0 . diff --git a/U494/Algol/algrt.asm b/U494/Algol/algrt.asm index 66d25d3..44eb551 100644 --- a/U494/Algol/algrt.asm +++ b/U494/Algol/algrt.asm @@ -130,7 +130,7 @@ . STACK OVERFLOW DETECTED . TYPE SO$LEN,S$OVFL - EXIT ESOVFL + HALT ESOVFL . S$SAVE RES 2D S$OVFL +'STACK OVERFLOW' @@ -192,12 +192,12 @@ J S$UERR TBI B4,77777 J,L S$INCR - EXIT 666 + HALT 666 . . STACK UNDERFLOW DETECTED . S$UERR TYPE SU$LEN,S$UNFL - EXIT ESUNFL + HALT ESUNFL . S$UNFL +'STACK UNDERFLOW' +' ^' @@ -411,7 +411,7 @@ J FMG$LOOP . FMG$HMTY TYPE HELEN,HEMSG - EXIT EHMTY + HALT EHMTY . HEMSG +'HEAP EXHAUSTED' +' ^' @@ -502,7 +502,7 @@ J FMF$ADDNEW . END OF LIST . HEAPBAD TYPE HBLEN,HBMSG - EXIT EHCRUPT + HALT EHCRUPT . HBMSG +'HEAP FREE LIST CORRUPTED' +' ^' @@ -740,7 +740,7 @@ AA$RTRN J $ . AA$BADIDX TYPE AA$LEN,AA$MSG - EXIT EABADIDX + HALT EABADIDX . AA$MSG +'RUN-TIME ERROR: WRONG NUMBER OF ARRAY INDICES' +' ^' diff --git a/U494/Algol/algrt.pjt b/U494/Algol/algrt.pjt index bc2a395..efaccae 100644 --- a/U494/Algol/algrt.pjt +++ b/U494/Algol/algrt.pjt @@ -8,10 +8,10 @@ SysSetCwd='C:\Development\Emulators\AlgolV2' SrchSetFlags=0x4410600b FileSortMode=0x0 StateWindowFrame=0,4,974,1083,0x63097f08 -_StateWindow=52,52,494,587,0x00100010,'C:\Development\Emulators\AlgolV2\test.s',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,19,5,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 -_StateBuffer='C:\Development\Emulators\AlgolV2\test.s',0x0400048a,19,5,25,'6 12 17 22 27 32 37 41','',0x1,'',1,72,1 -_StateHistory=FILELIST,'C:\temp\junk','C:\Development\Emulators\U494\Algol\Buildalgrt.bat','C:\Development\Emulators\Algol\notes.asm','C:\Development\Emulators\U494\Algol\algrt.asm','C:\Development\Emulators\U494\Algol\RTTest.asm','C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\AlgolV2\test.s','C:\Development\Emulators\AlgolV2\test.alg' -_StateHistory=SEARCH,'FM$Q','c$6','c$0','***','b6','NA$DIM','AA$LEN','77777','newarray','arrayadr' +_StateWindow=156,156,494,557,0x00100010,'C:\Development\Emulators\U494\Algol\Buildalgrt.bat',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,29,28,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 +_StateBuffer='C:\Development\Emulators\U494\Algol\Buildalgrt.bat',0x0400048e,29,28,25,'5 9','',0x0,'',1,72,1 +_StateHistory=FILELIST,'C:\temp\junk','C:\Development\Emulators\Algol\notes.asm','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\AlgolV2\test.s','C:\Development\Emulators\AlgolV2\test.alg','C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\U494\Algol\algrt.asm','C:\Development\Emulators\U494\Algol\RTTest.asm','C:\Development\Emulators\U494\Algol\Buildalgrt.bat' +_StateHistory=SEARCH,'***','b6','NA$DIM','AA$LEN','77777','newarray','arrayadr','EXIT','TEST.ALG','test.s' _StateHistory=XSYMBOL,'ERROR','ARRAY' _StateHistory=EDITFILE,'C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\Algol\notes.asm','C:\Development\Emulators\AlgolV2\test.alg','C:\Development\Emulators\AlgolV2\test.s','C:\Development\Emulators\AlgolV2\test.alg' diff --git a/U494/Docs/Monitor6.odt b/U494/Docs/Monitor6.odt new file mode 100644 index 0000000000000000000000000000000000000000..1ee249d2c34cdda4b80993b3dcd9bce72f83c2c5 GIT binary patch literal 18355 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 literal 0 HcmV?d00001 diff --git a/U494/Docs/U494.odt b/U494/Docs/U494.odt index 137aba5f15ffbac737a9f779af2eb2b9a65ea184..15d84de336729d77bfa3161fbd08e03cb79d744c 100644 GIT binary patch delta 25211 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 S0L&o4^qv5jP(%Kb5BMJn)zfbP diff --git a/U494/FH880Device.pas b/U494/FH880Device.pas index 95b2ff0..d98851a 100644 --- a/U494/FH880Device.pas +++ b/U494/FH880Device.pas @@ -193,7 +193,7 @@ var word: T494Word; begin FStatus := 0; - bcr := FMemory.FetchBcr(BcrIn0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrIn(FChannel), True); while (FInputActive and (bcr.Count > 0) and (StatusCode <> CEND_OF_FILE)) do begin word.Value := FDrum.ReadWord(addr); @@ -203,7 +203,7 @@ begin Inc(addr); bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); if (word.Value = BITS30) then begin // End of block detected. Read overflow word, @@ -220,7 +220,7 @@ begin FMemory.Store(bcr.Address, word, True); bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); end; end else begin @@ -241,7 +241,7 @@ var word: T494Word; begin FStatus := 0; - bcr := FMemory.FetchBcr(BcrIn0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrIn(FChannel), True); while (FInputActive and (bcr.Count > 0) and (StatusCode <> CEND_OF_FILE)) do begin word.Value := FDrum.ReadWord(addr); @@ -251,7 +251,7 @@ begin Inc(addr); bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); end; if (FInputMonitor and (bcr.Count = 0)) then begin @@ -387,7 +387,7 @@ var word: T494Word; begin FStatus := 0; - bcr := FMemory.FetchBcr(BcrOut0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); while ((bcr.Count > 0) and (StatusCode <> CEND_OF_FILE)) do begin word := FMemory.Fetch(bcr.Address, True); @@ -397,7 +397,7 @@ begin Inc(addr); bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrOut0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrOut(FChannel), bcr, True); end; if (FOutputMonitor and (bcr.Count = 0)) then begin diff --git a/U494/Procs/ExecReturn.proc b/U494/Procs/ExecReturn.proc index 801190c..c0d5243 100644 --- a/U494/Procs/ExecReturn.proc +++ b/U494/Procs/ExecReturn.proc @@ -46,7 +46,7 @@ AQ,A END . - . EXIT + . HALT . . Parameters: . exit_code @@ -55,7 +55,7 @@ . None . P PROC - EXIT* NAME + HALT* NAME EXRN EREXIT$ +P(1,1) END diff --git a/U494/Setup/U494.iss b/U494/Setup/U494.iss index 73e34ee..a8b2515 100644 --- a/U494/Setup/U494.iss +++ b/U494/Setup/U494.iss @@ -79,14 +79,25 @@ Source: ..\Procs\Lists.proc; DestDir: {app}\Procs Source: ..\Procs\Mem.proc; DestDir: {app}\Procs Source: ..\Procs\Mfd.proc; DestDir: {app}\Procs Source: ..\Obj\BcdTest.obj; DestDir: {app}\Obj +Source: ..\U490.cfg; DestDir: {app} +Source: ..\U494.cfg; DestDir: {app} +Source: ..\U1230.cfg; DestDir: {app} +Source: ..\Win32\Debug\U494Spurt.exe; DestDir: {app} +Source: ..\Source\Monitor6.spurt; DestDir: {app}\Source +Source: ..\Manuals\490\UP-3900_SPURT_refMan_1963.pdf; DestDir: {app}\Manuals +Source: ..\Manuals\1230\PX3892_Programming_Manual_for_1230_Computer_Feb66.pdf; DestDir: {app}\Manuals +Source: ..\Bin\monitor6.mem; DestDir: {app}\Bin +Source: ..\Bin\monitor6.mem; DestDir: {commonappdata}\Univac 494 Emulator\Data +Source: ..\Docs\Monitor6.pdf; DestDir: {app}\Docs [Icons] Name: {group}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; WorkingDir: {app} Name: {commondesktop}\{#MyAppName}; Filename: {app}\{#MyAppExeName}; Tasks: desktopicon; WorkingDir: {app} -Name: {group}\U494 Assembler; Filename: {app}\U494Asm.exe; WorkingDir: {app} Name: {group}\FH880 Utilities; Filename: {app}\FH880Util.exe; WorkingDir: {app}; IconIndex: 0 Name: {group}\U494 Console; Filename: {app}\U494Console.exe; WorkingDir: {app}; IconIndex: 0 Name: {group}\U494 Emulator Docs; Filename: {app}\Docs\U494.pdf +Name: {group}\Univac 1230 Emulator; Filename: {app}\U494.exe; Parameters: -c U1230.cfg; WorkingDir: {app} +Name: {group}\Univac 490 Emulator; Filename: {app}\U494.exe; Parameters: -c U490.cfg; WorkingDir: {app}; IconIndex: 0 [Run] Filename: {app}\{#MyAppExeName}; Description: {cm:LaunchProgram,{#MyAppName}}; Flags: nowait postinstall skipifsilent diff --git a/U494/Source/BcdTest.asm b/U494/Source/BcdTest.asm index 9c67454..732d885 100644 --- a/U494/Source/BcdTest.asm +++ b/U494/Source/BcdTest.asm @@ -141,7 +141,7 @@ DPS RSLT TYPE MLEN,MSG . - EXIT + HALT BCD0 DLD 0I BCD1 DLD 1234567I diff --git a/U494/Source/BcdTest.pjt b/U494/Source/BcdTest.pjt index e57eaed..f676ac4 100644 --- a/U494/Source/BcdTest.pjt +++ b/U494/Source/BcdTest.pjt @@ -8,8 +8,8 @@ SysSetCwd='C:\Development\Emulators\U494\Source' SrchSetFlags=0x0410600a FileSortMode=0x0 StateWindowFrame=0,0,1211,1069,0x63097f08 -_StateWindow=52,52,731,573,0x00100010,'C:\Development\Emulators\U494\Source\BcdTest.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,153,1,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,85,1,208,1,6 -_StateBuffer='C:\Development\Emulators\U494\Source\BcdTest.asm',0x0400048a,153,1,25,'8 20 30 50','',0x1,'',1,72,1 +_StateWindow=52,52,731,573,0x00100010,'C:\Development\Emulators\U494\Source\BcdTest.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,109,42,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,88,1,208,1,6 +_StateBuffer='C:\Development\Emulators\U494\Source\BcdTest.asm',0x0c00048a,109,42,25,'8 20 30 50','',0x1,'',1,72,1 _StateHistory=FILELIST,'C:\Development\Emulators\U494\Source\BuildCave.bat','C:\Development\Emulators\U494\Source\BuildBcdTest.bat','C:\Development\Emulators\U494\Obj\BcdTest.obj','C:\Development\Emulators\U494\Source\BcdTest.asm' _StateHistory=SEARCH,'msg' _StateHistory=EDITFILE,'C:\Development\Emulators\U494\Source\BuildCave.bat','C:\Development\Emulators\U494\Obj\BcdTest.obj','C:\Development\Emulators\U494\Source\FloatTest.pjt' diff --git a/U494/Source/BuildMOS.bat b/U494/Source/BuildMOS.bat index 3f12ef4..690a83f 100644 --- a/U494/Source/BuildMOS.bat +++ b/U494/Source/BuildMOS.bat @@ -3,6 +3,9 @@ c: cd \development\emulators\u494 win32\debug\u494asm Source\MOS.asm -P Procs -O Bin if errorlevel 1 goto end -notepad++ Source\MOS.lst +start /b notepad++ Source\MOS.lst +win32\debug\u494spurt -tab # -sep * Source\MONITOR6.spurt -O Bin +if errorlevel 1 goto end +start /b notepad++ Source\MONITOR6.lst :end diff --git a/U494/Source/Cave.asm b/U494/Source/Cave.asm index 73a7e07..018f530 100644 --- a/U494/Source/Cave.asm +++ b/U494/Source/Cave.asm @@ -76,7 +76,7 @@ TA 601D,,YLESS . TABLE FULL? J L1004 TYPE TMLLEN,TMLERR . YES - EXIT 1D + HALT 1D . . RECORD TYPE 5 (STATIC GAME STATES) . @@ -152,7 +152,7 @@ RI,W I . I = I+1 JNE 400D,L1018 . IF I<>1000 GOTO L1017 TYPE TM3LEN,TM3ERR - EXIT 2D + HALT 2D L1018 TBI B2,10D J L1017A L1019 LB,W B1,I . TRAVEL(I-1)=-TRAVEL(I-1) @@ -174,7 +174,7 @@ TBI B1,200D J L1020A TYPE TMWLEN,TMWERR - EXIT 3D + HALT 3D . . RECORD TYPE 6 (HINTS AND EVENTS) . @@ -876,7 +876,7 @@ LA,W AA MATE SQUIT . A = 'QUIT'? J L2020C . NO - EXIT 0 . YES, END GAME + HALT 0 . YES, END GAME L2020C MATE SENTER . A = 'ENTER'? J L2021 . NO LA,W WD2 @@ -914,7 +914,7 @@ . NO END SENTINAL (ID = 99999) IN KTAB . TYPE E6LEN,ERR6 . OOPS! - EXIT 4D + HALT 4D . . GO TO THE APPROPRIATE ROUTINE TO PROCESS THE CLASS OF THE WORD. . ACTION WORDS ARE BETWEEN 0 AND 999, OJBECTS ARE BETWEEN @@ -937,7 +937,7 @@ J,L L2025$J,B1 . GOTO ... KQ . L2025A TYPE NNLEN,NONO - EXIT 5D + HALT 5D . L2025$J +0 +L5014 . 0-999 @@ -961,7 +961,7 @@ J,L L2026$J,B1 . GO TO APPROPRAITE ROUTINE . L2026A TYPE E5LEN,ERR5 - EXIT 6D + HALT 6D . . JUMP TABLE FOR 2000 SERIES WORDS WITH AN OBJECT . @@ -1072,7 +1072,7 @@ J,L L2036$J,B1 . GO TO APPROPRIATE RTN . L2036A TYPE OLEN,OOPS - EXIT 6D + HALT 6D . . JUMP TABLE FOR 2000 SERIES WORDS WITHOUT AN OBJECT . @@ -1495,7 +1495,7 @@ SA,W PROP,B1 . PROP(WATER)=1 J L5200 . - EXIT 0 + HALT 0 . ++++++++++ . MOD . @@ -1672,7 +1672,7 @@ OR,W SPCZERO SA,W FILSTAT TYPE FELEN,FILERR - EXIT 8D + HALT 8D . . INFILE EOF . @@ -1732,7 +1732,7 @@ R$Q +0 . CFG$ERR TYPE CFG$LEN,CFG$MSG - EXIT 9D + HALT 9D CFG$MSG +'INVALID LINE TYPE DETECTED IN CONFIGURATION FILE ^' CFG$LEN EQU $-CFG$MSG . diff --git a/U494/Source/Cave.pjt b/U494/Source/Cave.pjt index c7d126d..85028a5 100644 --- a/U494/Source/Cave.pjt +++ b/U494/Source/Cave.pjt @@ -14,10 +14,10 @@ SysSetCwd='C:\Development\Emulators\U494\Source' SrchSetFlags=0x4410600b FileSortMode=0x0 StateWindowFrame=0,2,974,1085,0x63097f08 -_StateWindow=52,52,494,589,0x00100010,'C:\Development\Emulators\U494\Source\BuildCave.bat',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,4,50,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 -_StateBuffer='C:\Development\Emulators\U494\Source\BuildCave.bat',0x0400048e,4,50,25,'5 9','',0x0,'',1,72,1 -_StateHistory=FILELIST,'C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\Development\Emulators\U494\Source\MOS.asm','C:\Development\Emulators\U494\Procs\misc.proc','C:\Development\Emulators\U494\Source\Cave.asm','C:\Development\Emulators\U494\Cave\adv350-pdp10\adven.dat','C:\Development\Emulators\U494\Cave\u494_adventure.txt','C:\DEVELOPMENT\EMULATORS\U494\SOURCE\Cave.asm','C:\Development\Emulators\U494\Source\AsmTest.asm','C:\Development\Emulators\U494\Source\BuildCave.bat' -_StateHistory=SEARCH,'secret canyon','slab','vast hall','prop+','jt','exit','EXIT','invalid line ',' JE ','JNE' +_StateWindow=234,234,494,559,0x00100010,'C:\DEVELOPMENT\EMULATORS\U494\SOURCE\Cave.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,1735,24,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1673,1,208,1,6 +_StateBuffer='C:\DEVELOPMENT\EMULATORS\U494\SOURCE\Cave.asm',0x0400048a,1735,24,25,'8 20 30 50','',0x1,'',1,72,1 +_StateHistory=FILELIST,'C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\Development\Emulators\U494\Source\MOS.asm','C:\Development\Emulators\U494\Procs\misc.proc','C:\Development\Emulators\U494\Source\Cave.asm','C:\Development\Emulators\U494\Cave\adv350-pdp10\adven.dat','C:\Development\Emulators\U494\Cave\u494_adventure.txt','C:\Development\Emulators\U494\Source\AsmTest.asm','C:\Development\Emulators\U494\Source\BuildCave.bat','C:\DEVELOPMENT\EMULATORS\U494\SOURCE\Cave.asm' +_StateHistory=SEARCH,'secret canyon','slab','vast hall','prop+','jt','EXIT','invalid line ',' JE ','JNE','exit' _StateHistory=REPLACE,'ProgressCancelForm','++++++++++','FH8$CHAN5Q','SW$RESUME' _StateHistory=XSYMBOL,'PROCEDURE','INPUT' _StateHistory=EDITFILE,'C:\Development\Emulators\U494\Procs\misc.proc','C:\Development\Emulators\U494\Cave\u494_adventure.txt','C:\Development\Emulators\U494\Source\Cave.asm','C:\Development\Emulators\U494\Source\BuildCave.bat','C:\Development\Emulators\U494\Cave\u494_adventure.txt','C:\Development\Emulators\U494\Cave\adv350-pdp10\adven.dat','C:\Development\Emulators\U494\Source\AsmTest.asm','C:\Development\Emulators\U494\Source\MOS.pjt','C:\Development\Emulators\U494\Source\MOS.PJT','C:\Development\Emulators\U494\Source\HelloWorld.pjt' diff --git a/U494/Source/FileUtil.asm b/U494/Source/FileUtil.asm index 92d0b97..423f7d6 100644 --- a/U494/Source/FileUtil.asm +++ b/U494/Source/FileUtil.asm @@ -33,7 +33,7 @@ SLJ EXECCMD . GO EXECUTE THE VERB J LOOP . - EXIT 0 + HALT 0 . ++++++++++ . EXECCMD . @@ -143,7 +143,7 @@ . ++++++++++ . QUIT - EXIT THE PROGRAM . ++++++++++ - QUIT EXIT 0 + QUIT HALT 0 . ++++++++++ . PARSEID . diff --git a/U494/Source/FileUtil.pjt b/U494/Source/FileUtil.pjt index c4ac3f6..366da70 100644 --- a/U494/Source/FileUtil.pjt +++ b/U494/Source/FileUtil.pjt @@ -13,10 +13,10 @@ SysSetCwd='C:\Development\Emulators\U494\Source' SrchSetFlags=0x4410600b FileSortMode=0x0 StateWindowFrame=0,0,1211,1069,0x63097f08 -_StateWindow=130,130,731,573,0x00100010,'C:\DEVELOPMENT\EMULATORS\U494\SOURCE\FileUtil.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,294,30,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,256,1,208,1,6 -_StateBuffer='C:\DEVELOPMENT\EMULATORS\U494\SOURCE\FileUtil.asm',0x0400048a,294,30,25,'8 20 30 50','',0x1,'',1,72,1 +_StateWindow=130,130,731,573,0x00100010,'C:\DEVELOPMENT\EMULATORS\U494\SOURCE\FileUtil.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,146,24,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,142,1,208,1,6 +_StateBuffer='C:\DEVELOPMENT\EMULATORS\U494\SOURCE\FileUtil.asm',0x0400048a,146,24,25,'8 20 30 50','',0x1,'',1,72,1 _StateHistory=FILELIST,'C:\Development\Emulators\U494\Source\BuildBcdTest.bat','C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\Development\Emulators\U494\Source\BuildDrum.bat','C:\Development\Emulators\U494\Source\BcdTest.asm','C:\Development\Emulators\U494\Procs\files.proc','n:\trkcob\mc2hrcvd.cbl','C:\Development\Emulators\U494\Source\BuildFileUtil.bat','C:\DEVELOPMENT\EMULATORS\U494\SOURCE\FileUtil.asm' -_StateHistory=SEARCH,'GOTDEST','ZERO','PUN','PRN','RDR','\'','OPDTF1','BANNER','DTFCP','DTF$CHAN' +_StateHistory=SEARCH,'ZERO','PUN','PRN','RDR','\'','OPDTF1','BANNER','DTFCP','DTF$CHAN','EXIT' _StateHistory=XSYMBOL,'FILE','INPUT','LINE','OUTPUT' _StateHistory=EDITFILE,'C:\Development\Emulators\U494\Source\MOS.pjt','C:\Development\Emulators\U494\Source\BcdTest.asm','C:\Development\Emulators\U494\Source\MOS.pjt','C:\Development\Emulators\U494\Source\MOS.PJT','C:\Development\Emulators\U494\Source\mos.pjt','C:\Development\Emulators\U494\Procs\files.proc','C:\Development\Emulators\U494\Source\mos.pjt','C:\Development\Emulators\U494\Procs\files.proc','C:\Development\Emulators\U494\Source\mos.pjt','C:\Development\Emulators\U494\Source\MOS.pjt' diff --git a/U494/Source/FloatTest.asm b/U494/Source/FloatTest.asm index 5d22b04..7e7c73a 100644 --- a/U494/Source/FloatTest.asm +++ b/U494/Source/FloatTest.asm @@ -139,7 +139,7 @@ DPS RSLT TYPE MLEN,MSG . - EXIT 0 + HALT 0 . . RETURN THE INTEGER PART OF THE FLOATING POINT NUMBER IN AQ . AS A 60-BIT INTEGER IN AQ. diff --git a/U494/Source/FloatTest.pjt b/U494/Source/FloatTest.pjt index 3dacd38..2a3ab79 100644 --- a/U494/Source/FloatTest.pjt +++ b/U494/Source/FloatTest.pjt @@ -8,10 +8,10 @@ SysSetCwd='C:\Development\Emulators\U494\Algol' SrchSetFlags=0x4410600b FileSortMode=0x0 StateWindowFrame=0,2,974,1085,0x63097f08 -_StateWindow=78,78,494,589,0x00100010,'C:\Development\Emulators\U494\Source\FloatTest.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,223,1,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,178,1,208,1,6 -_StateBuffer='C:\Development\Emulators\U494\Source\FloatTest.asm',0x0400048a,223,1,25,'8 20 30 50','',0x1,'',1,72,1 +_StateWindow=78,78,494,589,0x00100010,'C:\Development\Emulators\U494\Source\FloatTest.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,142,24,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,140,1,208,1,6 +_StateBuffer='C:\Development\Emulators\U494\Source\FloatTest.asm',0x0400048a,142,24,25,'8 20 30 50','',0x1,'',1,72,1 _StateHistory=FILELIST,'C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\DEVELOPMENT\EMULATORS\U494\SOURCE\BuildFloatTest.bat','C:\Development\Emulators\U494\Source\AsmTest.asm','C:\Development\Emulators\U494\Source\FloatTest.asm' -_StateHistory=SEARCH,'int','I$','FRAC','T$EXP0','FPP' +_StateHistory=SEARCH,'int','I$','FRAC','T$EXP0','FPP','EXIT' _StateHistory=REPLACE,'T$' _StateHistory=EDITFILE,'C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\Development\Emulators\U494\Source\AsmTest.asm','C:\Development\Emulators\U494\Source\MOS.pjt' diff --git a/U494/Source/HelloWorld.pjt b/U494/Source/HelloWorld.pjt index 4a2e6a5..ff56899 100644 --- a/U494/Source/HelloWorld.pjt +++ b/U494/Source/HelloWorld.pjt @@ -13,8 +13,8 @@ SysSetCwd='C:\Development\Emulators\U494\Source' SrchSetFlags=0x0410600a FileSortMode=0x0 StateWindowFrame=0,0,1211,1069,0x63097f08 -_StateWindow=130,130,731,573,0x00100010,'C:\DEVELOPMENT\EMULATORS\U494\SOURCE\HelloWorld.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,11,9,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 -_StateBuffer='C:\DEVELOPMENT\EMULATORS\U494\SOURCE\HelloWorld.asm',0x0400048a,11,9,25,'8 20 30 50','',0x1,'',1,72,1 +_StateWindow=130,130,731,573,0x00100010,'C:\DEVELOPMENT\EMULATORS\U494\SOURCE\HelloWorld.asm',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,8,24,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1,1,208,1,6 +_StateBuffer='C:\DEVELOPMENT\EMULATORS\U494\SOURCE\HelloWorld.asm',0x0400048a,8,24,25,'8 20 30 50','',0x1,'',1,72,1 _StateHistory=FILELIST,'C:\DEVELOPMENT\EMULATORS\U494\SOURCE\HelloWorld.asm','C:\Development\Emulators\U494\Source\BuildBcdTest.bat','C:\Development\Emulators\U494\Source\BuildHelloWorld.bat','C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\Development\Emulators\U494\Procs\files.proc' _StateHistory=EDITFILE,'C:\Development\Emulators\U494\Source\BuildBcdTest.bat','C:\Development\Emulators\U494\Procs\ExecReturn.proc','C:\Development\Emulators\U494\Procs\files.proc','C:\Development\Emulators\U494\Source\MOS.pjt' diff --git a/U494/Source/MOS.pjt b/U494/Source/MOS.pjt index fdfee70..56f5013 100644 --- a/U494/Source/MOS.pjt +++ b/U494/Source/MOS.pjt @@ -22,16 +22,16 @@ C:\DEVELOPMENT\EMULATORS\U494\PROCS\misc.proc C:\DEVELOPMENT\EMULATORS\U494\PROCS\Tasks.proc [State] -SysSetCwd='C:\Development\Emulators\U494\Source' +SysSetCwd='C:\Development\Emulators\U494\Algol' SrchSetFlags=0x4410600b FileSortMode=0x0 StateWindowFrame=0,1,1056,1068,0x63097f08 -_StateWindow=130,130,731,542,0x00100010,'C:\Development\Emulators\U494\Source\Monitor6.spurt',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,1070,2,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,1063,1,208,1,6 -_StateBuffer='C:\Development\Emulators\U494\Source\Monitor6.spurt',0x0400048a,1070,2,25,'6 12 17 22 27 32 37 41','',0x1,'',1,72,1 -_StateHistory=FILELIST,'C:\Development\Emulators\U494\Source\AsmTest.obj','C:\DEVELOPMENT\EMULATORS\U494\PROCS\ExecReturn.proc','C:\DEVELOPMENT\EMULATORS\U494\PROCS\Tasks.proc','C:\Development\Emulators\U494\Source\BuildMOS.bat','C:\DEVELOPMENT\EMULATORS\U494\PROCS\Lists.proc','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\Algol\test.alg','C:\DEVELOPMENT\EMULATORS\U494\SOURCE\MOS.asm','C:\Development\Emulators\U494\Source\Monitor6.spurt' -_StateHistory=SEARCH,'.MONITOR','*MONITOR','term','term*','*66','366','#66','*SIL','#SIL','ril' +_StateWindow=104,104,576,542,0x00100010,'C:\DEVELOPMENT\EMULATORS\U494\PROCS\ExecReturn.proc',208,31,212,4,20,12,46,26,126,176,8,4294967295,4294967295,1,10,'',12,255,48,72,10,467,0,0,721,252,249,58,12,400,0,212,214,210,220,721,721,720,729,217,80,0,223,224,14,13,1,208,1,6 +_StateBuffer='C:\DEVELOPMENT\EMULATORS\U494\PROCS\ExecReturn.proc',0x0400048a,58,12,25,'8 20 30 50','',0x1,'',1,72,1 +_StateHistory=FILELIST,'C:\Development\Emulators\U494\Source\monitor6.lst','C:\temp\monitor.txt','C:\Development\Emulators\U494\Source\Monitor6.spurt','C:\Development\Emulators\U494\Source\BuildMOS.bat','C:\DEVELOPMENT\EMULATORS\U494\SOURCE\MOS.asm','C:\DEVELOPMENT\EMULATORS\U494\PROCS\Lists.proc','C:\DEVELOPMENT\EMULATORS\U494\PROCS\ExecReturn.proc','C:\Development\Emulators\U494\Algol\Buildalgrt.bat','C:\Development\Emulators\U494\Algol\RTTest.asm' +_StateHistory=SEARCH,'77400','dump','rjp#','keyin#','numb1#','ICH3#','*cest','numbera#','pack1#','exit' _StateHistory=XSYMBOL,'OUTPUT','ERROR','INPUT','FILE' -_StateHistory=EDITFILE,'C:\Development\Emulators\U494\Source\BuildDrum.bat','C:\Development\Emulators\U494\Source\AsmTest.asm','C:\Development\Emulators\U494\Source\AsmTest.obj','C:\Development\Emulators\U494\Source\BcdTest.pjt','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\Algol\test.alg','C:\Development\Emulators\Algol\test.s','C:\Development\Emulators\U494\Source\Monitor6.spurt' +_StateHistory=EDITFILE,'C:\Development\Emulators\U494\Source\u494.cfg','C:\Development\Emulators\U494\u494.cfg','C:\Development\Emulators\U494\U490.cfg','C:\Development\Emulators\U494\U1230.cfg','c:\temp\monitor.txt','C:\Development\Emulators\U494\Source\monitor6.lst','c:\temp\monitor.txt','C:\Development\Emulators\U494\Source\BuildMOS.bat','C:\Development\Emulators\U494\Algol\Buildalgrt.bat','C:\Development\Emulators\U494\Algol\RTTest.asm' _StateHistory=GOTOMARK,'1','2','1' [Editor] diff --git a/U494/Source/Monitor6.spurt b/U494/Source/Monitor6.spurt index 5ca226d..bbde221 100644 --- a/U494/Source/Monitor6.spurt +++ b/U494/Source/Monitor6.spurt @@ -23,7 +23,9 @@ M0NIT0R1#JP*M0NIT0R#1232 EXT INT ENTRANCE #ENT*Q*W(M0NITOR2+B1) #STR*Q*W(B1) #RJP*SRESTORE -#77400*0 +#COMMENT.THE FOLLOWING APPEARS TO BE AN UNDOCUMENTED +#COMMENT.INSTRUCTION +#COMMENT.77400*0 #EX-C0M*KEY*W(TYPE)#TURN 0N 1232 #ENT*A*74230 #STR*A*U(KEYIN+5) @@ -31,7 +33,9 @@ M0NIT0R1#JP*M0NIT0R#1232 EXT INT ENTRANCE #SUB*Q*20#CHAN N0 #RJP*ICH7#CHAN T0 FD #STR*A*Q -#C0M*MASK*-700*AN0T#SUPPRESS MS ZERO +#COMMENT*FOLLOWING MODIFIED BECAUSE LITERALS ARE NOT SUPPORTED +#COMMENT*C0M*MASK*-700*AN0T#SUPPRESS MS ZERO +#C0M*MASK*X-700*AN0T#SUPPRESS MS ZERO #SEL*CL*X77700*SKIP #SEL*CL*X70000 #STR*A*W(LINE1+2)#SET CHAN @@ -40,9 +44,9 @@ PACK#ENT*Q*LINE1#M0NIT0R #ENT*B1*4 #CL*W(PACK5) PACK1#RJP*KEYIN -#ENT*Y-Q*56*ANOT#PR0CEED TO C0DE +#ENT*Y-Q*56*ANOT#PR0CEED TO C0DE *SWB* COMMA (,) #JP*PACK4#EXIT -#ENT*Y-Q*77*AN0T +#ENT*Y-Q*77*AN0T#*SWB* BACKSPACE #JP*PACK PACK2#ENT*A*W(PACK5) #LSH*A*6 @@ -52,7 +56,7 @@ PACK2#ENT*A*W(PACK5) PACK3#RJP*KEYIN#GET PR0CEED C0DE #ENT*Y-Q*77*ANOT #JP*PACK -#ENT*Y-Q*56*AZER0#WAIT F0R C0DE +#ENT*Y-Q*56*AZER0#WAIT F0R C0DE *SWB* COMMA (,) #JP*PACK3 PACK4#ENT*Q*W(PACK5) #ENT*B1*50D @@ -133,6 +137,7 @@ KEYIN#ENTRY*#ACCEPT KEYBOARD ENTRIES #ENT*Y-Q*76*ANOT#WAS MONITOR REQUESTED #JP*MONITOR #OUT*KEY*W(PRINT5)#TYPE SAME CHAR AS ENTERED +KEYIN1#JP*KEYIN1*TYPEACTIVE#*SWB* THIS WAS NOT WAITING #ENT*Y-Q*5*AZERO #EXIT* #JP*KEYIN+1#IGNORE SPACE CODES @@ -144,9 +149,9 @@ READ1#JP*READ1*KEYWAIT #EXIT* NUMB1#ENTRY* #RJP*KEYIN -#ENT*Y-Q*41*ANOT +#ENT*Y-Q*41*ANOT#*SWB* MINUS SIGN (-) #STR*Q*CPW(SRSAVE) -#ENT*Y-Q*56*ANOT +#ENT*Y-Q*56*ANOT#*SWB* COMMA (,) #JP*NUMBER3 NUMB2#EXIT* #ENT*Y-Q*77*AZERO#TEST ARROW @@ -165,7 +170,8 @@ NUMBERA#ENTRY* #RPL*Y+1*U(RBLOD2+2) #RJP*NUMBER #ENT*Q*W(NUMB2+2)#RESTORE EXIT -#STR*Q*W(SRSAVE) +#STR*Q*W(NUMB2) +#ENT*Q*W(SRSAVE) #EXIT* NUMBER#ENTRY*#ASSEMBLE OCTAL NUMBER #CL*W(EEXP) @@ -208,7 +214,7 @@ ADDRESSES1#ENT*Q*LINE20#FORMAT ERROR #RJP*PRINT #JP*ADDRESSES+1 BLOCKS#ENTRY*#SET UP MULTIPLE BLOCKS -#ENT*A*LINE2#NO OF AREAS +#ENT*Q*LINE2#NO OF AREAS #RJP*PRINT #RJP*NUMBERA #JP*BLOCKS+1*AZERO#NO AREAS ILLEGAL @@ -268,11 +274,11 @@ ICH2#RJP*KEYIN#INSPECT AND CHANGE ROUTINE #RJP*EEXP#TEST 17-BIT MODE #RJP*ICH11#PRINT CONTENTS ICH3#RJP*KEYIN#GET FUNCTION CODE -#ENT*Y-Q*56*AZERO#PROCEED CODE +#ENT*Y-Q*56*AZERO#PROCEED CODE *SWB* COMMA (,) #JP*ICH5#IS IT CHANGE CODE ICH4#INCREMENT*B7*+1 #JP*ICH1 -ICH5#ENT*Y-Q*74*AZERO#CHANGE CONTENTS +ICH5#ENT*Y-Q*74*AZERO#CHANGE CONTENTS *SWB* SLASH (/) #JP*ICH3 #LSH*A*0*SKIP #JP*ICH1#RETURN TO PRINT ADDRESS @@ -302,7 +308,7 @@ ICH8#LSH*A*3 #ENT*B1*W(ICH12) #EXIT* ICH10#ENTRY*#PRINT CR, LF, 5 DIGITS -#RJP#CRLF +#RJP*CRLF #ENT*A*B7 #SEL*CL*77777*AZERO#TEST 6TH DIGIT #RJP*ICH12#PRINT MS DIGIT @@ -893,7 +899,7 @@ SELECTED#U-TAG*MARK0*2#PCOPY #U-TAG*MARK0*34#IONIC #U-TAG*MARK0*31#MACAB #U-TAG*MARK0*32#BRAIN -#U-TAG*MARK0*13*CEST +#U-TAG*MARK0*13#CEST #U-TAG*MARK0*21#ECCLAT #U-TAG*MARK0*22#1230M #U-TAG*MARK0*40#ICE diff --git a/U494/Spurt.pas b/U494/Spurt.pas index cbd6f4a..cf7d9d5 100644 --- a/U494/Spurt.pas +++ b/U494/Spurt.pas @@ -1565,7 +1565,6 @@ var b: Byte; rel1, rel2, rel: TRelocatableType; begin - Inc(FLocationCounter.Value); if (FPass = 2) then begin h1 := GetY(lineNum, ops, rel1, b); @@ -1587,6 +1586,7 @@ begin FListFile.Value := word; FListFile.Print; end; + Inc(FLocationCounter.Value); end; procedure TAssembler.DoWord(lineNum: Integer; var ops: AnsiString); diff --git a/U494/U1230.cfg b/U494/U1230.cfg index 9489525..de2793d 100644 --- a/U494/U1230.cfg +++ b/U494/U1230.cfg @@ -2,4 +2,8 @@ 1230 monitor6.mem + + 4 + 1232 + diff --git a/U494/U490.cfg b/U494/U490.cfg index 310be58..1216948 100644 --- a/U494/U490.cfg +++ b/U494/U490.cfg @@ -2,4 +2,19 @@ 490 mos.mem + + 0 + 1232 + + + 1 + + + 2 + + + 5 + fh880 + sysvol.drum + diff --git a/U494/U494.cfg b/U494/U494.cfg index 255faf4..266842e 100644 --- a/U494/U494.cfg +++ b/U494/U494.cfg @@ -2,4 +2,19 @@ 494 mos.mem + + 0 + 1232 + + + 1 + + + 2 + + + 5 + fh880 + sysvol.drum + diff --git a/U494/U494.dproj b/U494/U494.dproj index 054f51f..9c3c07a 100644 --- a/U494/U494.dproj +++ b/U494/U494.dproj @@ -65,7 +65,8 @@ true - -c ..\..\U494.cfg + -c ..\..\U1230.cfg + 3 U494_Icon.ico true 1033 diff --git a/U494/U494Config.pas b/U494/U494Config.pas index be1c9fd..330f270 100644 --- a/U494/U494Config.pas +++ b/U494/U494Config.pas @@ -2,22 +2,44 @@ unit U494Config; interface -uses SysUtils, Classes, Forms, XmlDoc, XmlIntf, U494Util; +uses SysUtils, Classes, Forms, XmlDoc, XmlIntf, U494Util, Generics.Collections; type + T494Drum = record + Chan: Integer; + DrumType: T494DrumType; + DrumFile: String; + end; + + TDrumList = class(TList) + end; + T494Config = class(TObject) private FMode: T494Mode; + FConsoleChan: Integer; + FConsoleType: T494ConsoleType; + FRdrPunChan: Integer; + FPrinterChan: Integer; + FDrums: TDrumList; FLoadFiles: TStringList; function GetLoadFileCount: Integer; function GetLoadFiles(idx: Integer): String; + function GetDrumCount: Integer; + function GetDrums(idx: Integer): T494Drum; public constructor Create; destructor Destroy; override; + property ConsoleChan: Integer read FConsoleChan; + property ConsoleType: T494ConsoleType read FConsoleType; + property DrumCount: Integer read GetDrumCount; + property Drums[idx: Integer]: T494Drum read GetDrums; procedure Load(AOwner: TComponent; fname: String); property LoadFileCount: Integer read GetLoadFileCount; property LoadFiles[idx: Integer]: String read GetLoadFiles; property Mode: T494Mode read FMode; + property PrinterChan: Integer read FPrinterChan; + property RdrPunChan: Integer read FRdrPunChan; end; var @@ -28,16 +50,44 @@ implementation { T494Config } constructor T494Config.Create; +var + drum: T494Drum; begin FLoadFiles := TStringList.Create; + FDrums := TDrumList.Create; + FMode := m494; + FConsoleChan := 0; + FRdrPunChan := -1; + FPrinterChan := -1; + FConsoleType := ct1232; + case FMode of + m494: FLoadFiles.Add('mos.mem'); + m490: FLoadFiles.Add('mos.mem'); + m1230: FLoadFiles.Add('monitor6.mem'); + end; + drum.Chan := 5; + drum.DrumType := dtFH880; + drum.DrumFile := 'sysvol.drum'; + FDrums.Add(drum); end; destructor T494Config.Destroy; begin FreeAndNil(FLoadFiles); + FreeAndNil(FDrums); inherited; end; +function T494Config.GetDrumCount: Integer; +begin + Result := FDrums.Count; +end; + +function T494Config.GetDrums(idx: Integer): T494Drum; +begin + Result := FDrums[idx]; +end; + function T494Config.GetLoadFileCount: Integer; begin Result := FLoadFiles.Count; @@ -51,10 +101,28 @@ end; procedure T494Config.Load(AOwner: TComponent; fname: String); var xml: TXmlDocument; - node: IXmlNode; - i: Integer; + node, node1: IXmlNode; + i, j: Integer; + drum: T494Drum; + + function GetChan(node: IXmlNode): Integer; + begin + if (not TryStrToInt(node1.Text, Result)) then + raise Exception.Create('Invalid console channel #'); + if (FMode = m494) then + if ((Result < 0) or (Result > 23)) then + raise Exception.Create('Invalid console channel #') + else + if ((Result < 0) or (Result > 15)) then + raise Exception.Create('Invalid console channel #'); + end; + begin - FMode := m494; + if (not FileExists(fname)) then + raise Exception.Create('Config file not found'); + + FLoadFiles.Clear; + FDrums.Clear; xml := TXmlDocument.Create(AOwner); try xml.LoadFromFile(fname); @@ -74,8 +142,92 @@ begin end else if (node.NodeName = 'load') then begin FLoadFiles.Add(node.Text); + end else if (node.NodeName = 'console') then + begin + for j := 0 to node.ChildNodes.Count -1 do + begin + node1 := node.ChildNodes[j]; + if (node1.NodeName = 'chan') then + begin + FConsoleChan := GetChan(node1); + end else if (node1.NodeName = 'type') then + begin + if (node1.Text = '1232') then + FConsoleType := ct1232 + else + raise Exception.Create('Invalid console type'); + end; + end; + end else if (node.NodeName = 'rdrpun') then + begin + for j := 0 to node.ChildNodes.Count -1 do + begin + node1 := node.ChildNodes[j]; + if (node1.NodeName = 'chan') then + begin + FRdrPunChan := GetChan(node1); + end; + end; + end else if (node.NodeName = 'printer') then + begin + for j := 0 to node.ChildNodes.Count -1 do + begin + node1 := node.ChildNodes[j]; + if (node1.NodeName = 'chan') then + begin + FPrinterChan := GetChan(node1); + end; + end; + end else if (node.NodeName = 'drum') then + begin + drum.Chan := 5; + drum.DrumType := dtFH880; + drum.DrumFile := 'sysvol.drum'; + for j := 0 to node.ChildNodes.Count -1 do + begin + node1 := node.ChildNodes[j]; + if (node1.NodeName = 'chan') then + begin + drum.Chan := GetChan(node1); + end else if (node1.NodeName = 'type') then + begin + if (node1.Text = 'fh880') then + drum.DrumType := dtFH880 + else + raise Exception.Create('Invalid drum type'); + end else if (node1.NodeName = 'file') then + begin + drum.DrumFile := node1.Text; + end; + end; + FDrums.Add(drum); end; end; + if (FLoadFiles.Count = 0) then + case FMode of + m494: FLoadFiles.Add('mos.mem'); + m490: FLoadFiles.Add('mos.mem'); + m1230: FLoadFiles.Add('monitor6.mem'); + end; + if (FDrums.Count = 0) then + begin + drum.Chan := 5; + drum.DrumType := dtFH880; + drum.DrumFile := 'sysvol.drum'; + end; + if (FLoadFiles.Count = 0) then + case FMode of + m494: FLoadFiles.Add('mos.mem'); + m490: FLoadFiles.Add('mos.mem'); + m1230: FLoadFiles.Add('monitor6.mem'); + end; + if (FDrums.Count = 0) then + begin + drum.Chan := 5; + drum.DrumType := dtFH880; + drum.DrumFile := 'sysvol.drum'; + FDrums.Add(drum); + end; xml.Free; except xml.Free; diff --git a/U494/U494ConsDevice.pas b/U494/U494ConsDevice.pas index 513376c..1f22434 100644 --- a/U494/U494ConsDevice.pas +++ b/U494/U494ConsDevice.pas @@ -31,7 +31,7 @@ type implementation -uses U494Util, U494Interrupts; +uses U494Util, U494Interrupts, U494Config; const OUTPUT_ENABLE = $01; @@ -178,7 +178,7 @@ begin Dec(bytesCopied, bytesWritten); end; // Copy CPU buffer to output buffer - bcr := FMemory.FetchBcr(BcrOut0, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); tail := FOBfrTail; while (OutputActive and ((FFunction.Value and PRINTER_ENABLED) = PRINTER_ENABLED) and @@ -190,7 +190,7 @@ begin FOBfrTail := tail; bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrOut0, bcr, True); + FMemory.StoreBcr(BcrOut(FChannel), bcr, True); if (tail = FOBfrHead) then Break; end; @@ -227,7 +227,7 @@ begin end; // Send any new input to the buffer if input is activated and // the keyword is enabled - bcr := FMemory.FetchBcr(BcrIn0, True); + bcr := FMemory.FetchBcr(BcrIn(FChannel), True); head := FIBfrHead; while (InputActive and ((FFunction.Value and KEYBOARD_ENABLED) = KEYBOARD_ENABLED) and @@ -241,7 +241,7 @@ begin FIBfrHead := head; bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); end; if (InputActive and (bcr.Count = 0)) then begin diff --git a/U494/U494Console.dpr b/U494/U494Console.dpr index 8004a66..7579961 100644 --- a/U494/U494Console.dpr +++ b/U494/U494Console.dpr @@ -1,6 +1,7 @@ program U494Console; uses + ExceptionLog, Vcl.Forms, U494ConsoleFrm in 'U494ConsoleFrm.pas' {U494ConsoleForm}, U494Util in 'U494Util.pas', diff --git a/U494/U494Console.dproj b/U494/U494Console.dproj index de31184..9d95544 100644 --- a/U494/U494Console.dproj +++ b/U494/U494Console.dproj @@ -65,6 +65,8 @@ true + 3 + EUREKALOG;EUREKALOG_VER6;$(DCC_Define) 1033 true U494Console_Icon.ico @@ -155,7 +157,7 @@ diff --git a/U494/U494ConsoleFrm.dfm b/U494/U494ConsoleFrm.dfm index 81708c7..7cab6e8 100644 --- a/U494/U494ConsoleFrm.dfm +++ b/U494/U494ConsoleFrm.dfm @@ -1,7 +1,7 @@ object U494ConsoleForm: TU494ConsoleForm Left = 0 Top = 0 - BorderStyle = bsDialog + BorderStyle = bsSingle Caption = 'Univac 494 Console' ClientHeight = 571 ClientWidth = 670 @@ -12,9 +12,13 @@ object U494ConsoleForm: TU494ConsoleForm Font.Name = 'Tahoma' Font.Style = [] KeyPreview = True + Menu = MainMenu OldCreateOrder = False OnKeyPress = FormKeyPress OnShow = FormShow + DesignSize = ( + 670 + 571) PixelsPerInch = 96 TextHeight = 13 object Printer: TMemo @@ -22,7 +26,7 @@ object U494ConsoleForm: TU494ConsoleForm Top = 0 Width = 670 Height = 571 - Align = alClient + Anchors = [akLeft, akTop, akRight, akBottom] Enabled = False Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText @@ -39,4 +43,18 @@ object U494ConsoleForm: TU494ConsoleForm Left = 558 Top = 236 end + object MainMenu: TMainMenu + Left = 92 + Top = 12 + object RecordMenu: TMenuItem + Caption = 'Record' + OnClick = RecordMenuClick + end + end + object OpenDlg: TOpenDialog + Filter = 'Text Files|*.txt|All Files|*.*' + Options = [ofHideReadOnly, ofPathMustExist, ofEnableSizing] + Left = 92 + Top = 90 + end end diff --git a/U494/U494ConsoleFrm.pas b/U494/U494ConsoleFrm.pas index e49c941..637306e 100644 --- a/U494/U494ConsoleFrm.pas +++ b/U494/U494ConsoleFrm.pas @@ -4,7 +4,7 @@ interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, - Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls; + Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls, Vcl.Menus; const START_MSG = WM_USER + 1; @@ -13,14 +13,21 @@ type TU494ConsoleForm = class(TForm) Timer: TTimer; Printer: TMemo; + MainMenu: TMainMenu; + RecordMenu: TMenuItem; + OpenDlg: TOpenDialog; procedure TimerTimer(Sender: TObject); procedure FormKeyPress(Sender: TObject; var Key: Char); procedure FormShow(Sender: TObject); + procedure RecordMenuClick(Sender: TObject); private FPipe: THandle; FKeyBfr: AnsiString; FInTimer: Boolean; FMaxLines: Integer; + FLastChar: AnsiChar; + FRecordFile: TFileStream; + procedure CloseRecord; procedure StartMsg(var Message: TMessage); message START_MSG; public constructor Create(AOwner: TComponent); override; @@ -38,15 +45,30 @@ uses U494Util, EmulatorTypes; { TForm4 } +procedure TU494ConsoleForm.CloseRecord; +var + l: String; +begin + if (Assigned(FRecordFile)) then + begin + l := Printer.Lines[FMaxLines - 1]; + FRecordFile.Write(PAnsiChar(AnsiString(l))^, Length(l)); + FRecordFile.Write(PAnsiChar(AnsiString(#13#10))^, 2); + FreeAndNil(FRecordFile); + end; +end; + constructor TU494ConsoleForm.Create(AOwner: TComponent); begin inherited; + FLastChar := ' '; PostMessage(Handle, START_MSG, 0, 0); end; destructor TU494ConsoleForm.Destroy; begin CloseHandle(FPipe); + CloseRecord; inherited Destroy; end; @@ -96,6 +118,22 @@ begin FMaxLines := Printer.ClientHeight div Abs(Printer.Font.Height); end; +procedure TU494ConsoleForm.RecordMenuClick(Sender: TObject); +begin + if (RecordMenu.Checked) then + begin + CloseRecord; + RecordMenu.Checked := False; + end else + begin + if (not OpenDlg.Execute) then + Exit; + + FRecordFile := TFileStream.Create(OpenDlg.FileName, fmCreate); + RecordMenu.Checked := True; + end; +end; + procedure TU494ConsoleForm.StartMsg(var Message: TMessage); var msg: String; @@ -177,15 +215,34 @@ begin for i := 1 to bytesRead do begin case bfr[i] of - #3, - #4: + #3: // begin + if (FLastChar <> #4) then // ignore if last char was + begin + if (Assigned(FRecordFile)) then + begin + FRecordFile.Write(PAnsiChar(AnsiString(line))^, Length(line)); + FRecordFile.Write(PAnsiChar(AnsiString(#13#10))^, 2); + end; + Printer.Lines[l] := line; + Printer.Lines.Delete(0); + Printer.Lines.Add(''); + line := ''; + end; + end; + #4: // + begin + if (Assigned(FRecordFile)) then + begin + FRecordFile.Write(PAnsiChar(AnsiString(line))^, Length(line)); + FRecordFile.Write(PAnsiChar(AnsiString(#13#10))^, 2); + end; Printer.Lines[l] := line; Printer.Lines.Delete(0); Printer.Lines.Add(''); line := ''; end; - #$3f: + #$3f: // begin line := Copy(line, 1, Length(line) - 1); end @@ -194,6 +251,7 @@ begin line := line + Char(TCodeTranslator.FieldataToAscii(Byte(bfr[i]))); end; end; + FLastChar := bfr[i]; end; Printer.Lines[l] := line; end; diff --git a/U494/U494Cpu.pas b/U494/U494Cpu.pas index d09945f..9435500 100644 --- a/U494/U494Cpu.pas +++ b/U494/U494Cpu.pas @@ -121,13 +121,16 @@ public procedure CUL; procedure CUU; procedure D; + procedure D17; procedure DA; procedure DAC; procedure DAN; procedure DANB; procedure DCL; procedure DCU; + procedure DICDM; procedure DN; + procedure DOCDM; procedure DPA; procedure DPAN; procedure DPL; @@ -138,11 +141,20 @@ public procedure DT; procedure DTE; procedure DTL; + procedure E17; procedure ECSR; + procedure EESR; + procedure EICDM; procedure EIR; + procedure EISR; + procedure EOCDM; + procedure EOSR; procedure ER; procedure ERIR; + procedure ESR; procedure EXF; + procedure EXF490; + procedure EXF1230; procedure EXRN; procedure FA; procedure FAN; @@ -151,10 +163,14 @@ public procedure FP; procedure FU; procedure INMON; + procedure INMON490; procedure INN; + procedure INN490; procedure J; procedure JACTI; + procedure JACTI490; procedure JACTO; + procedure JACTO490; procedure JBD; procedure JT; procedure LA; @@ -183,10 +199,15 @@ public procedure M; procedure MATE; procedure MATL; + procedure NORM; procedure NOTT; procedure ORR; procedure OUTMON; + procedure OUTMON490; + procedure OUTMON1230; procedure OUT; + procedure OUT490; + procedure OUT1230; procedure R; procedure RA; procedure RALP; @@ -212,16 +233,24 @@ public procedure SBW; procedure SC; procedure SCN; + procedure SESR; procedure SFS; procedure SIFR; + procedure SISR; procedure SLJ; procedure SLJT; + procedure SOSR; procedure SQ; + procedure SSR; procedure SSU; procedure TA; procedure TBI; procedure TERMIN; + procedure TERMIN1230; + procedure TERMIN490; procedure TERMOT; + procedure TERMOT1230; + procedure TERMOT490; procedure TLP; procedure TSET; procedure XORR; @@ -249,7 +278,7 @@ implementation { T494Cpu } -uses FmtBcd, Bcd; +uses FmtBcd, Bcd, U494Config; procedure T494Cpu.A; var @@ -374,20 +403,10 @@ begin j := FMemory.Inst.j; if (j = 0) then Exit; - if ((FMemory.IFR.f7 = 0) or (j <= 3)) then + if (FMemory.B[FMemory.IFR.f6, j].Value <> 0) then begin - if (FMemory.B[FMemory.IFR.f6, j].Value15 <> 0) then - begin - FMemory.B[FMemory.IFR.f6, j] := FMemory.B[FMemory.IFR.f6, j] - 1; - FMemory.P := addr + FMemory.RIR.Value; - end; - end else - begin - if (FMemory.B[FMemory.IFR.f6, j].Value <> 0) then - begin - FMemory.B[FMemory.IFR.f6, j] := FMemory.B[FMemory.IFR.f6, j] - 1; - FMemory.P := addr + FMemory.RIR.Value; - end; + FMemory.B[FMemory.IFR.f6, j].Value := FMemory.B[FMemory.IFR.f6, j].Value - 1; + FMemory.P := addr + FMemory.RIR.Value; end; end; @@ -480,10 +499,10 @@ begin end; if (operand.Value <> FMemory.B[FMemory.IFR.f6, j].Value) then begin - FMemory.B[FMemory.IFR.f6, j] := FMemory.B[FMemory.IFR.f6, j] + 1; + FMemory.B[FMemory.IFR.f6, j].Value := FMemory.B[FMemory.IFR.f6, j].Value + 1; end else begin - FMemory.B[FMemory.IFR.f6, j] := 0; + FMemory.B[FMemory.IFR.f6, j].Value := 0; FMemory.P := FMemory.P + 1; end; end; @@ -500,6 +519,37 @@ begin FChannels[chan].TerminateInput; end; +procedure T494Cpu.TERMIN1230; +var + chan: Byte; +begin + chan := FMemory.Inst.jhat; + case FMemory.Inst.khat of + 0: + begin + if (Assigned(FChannels[chan])) then + FChannels[chan].TerminateInput; + end; + 1: + begin + InterruptLockout := (FMemory.Inst.b <> 0); + end; + else + begin + raise Exception.CreateFmt('TERMIN1230 k designator %d not implemented', [FMemory.Inst.khat]); + end; + end; +end; + +procedure T494Cpu.TERMIN490; +var + chan: Byte; +begin + chan := FMemory.Inst.jhat; + if (Assigned(FChannels[chan])) then + FChannels[chan].TerminateInput; +end; + procedure T494Cpu.TERMOT; var chan: Byte; @@ -512,6 +562,33 @@ begin FChannels[chan].TerminateOutput; end; +procedure T494Cpu.TERMOT1230; +var + chan: Byte; +begin + chan := FMemory.Inst.jhat; + case FMemory.Inst.khat of + 0: + begin + if (Assigned(FChannels[chan])) then + FChannels[chan].TerminateOutput; + end; + else + begin + raise Exception.CreateFmt('TERMOT1230 k designator %d not implemented', [FMemory.Inst.khat]); + end; + end; +end; + +procedure T494Cpu.TERMOT490; +var + chan: Byte; +begin + chan := FMemory.Inst.jhat; + if (Assigned(FChannels[chan])) then + FChannels[chan].TerminateOutput; +end; + procedure T494Cpu.Clear; var i: Integer; @@ -597,11 +674,12 @@ end; procedure T494Cpu.TLP; var - operand: T494Word; + operand, lp: T494Word; test: Integer; begin operand := StdFetch; - test := FMemory.A - (operand.Value and FMemory.Q.Value); + lp.Value := operand.Value and FMemory.Q.Value; + test := FMemory.A - lp; case FMemory.Inst.j of 1: begin @@ -686,7 +764,6 @@ begin FStdInstProcs[8] := LQ; FStdInstProcs[9] := LA; FStdInstProcs[10] := LB; - FStdInstProcs[11] := EXF; FStdInstProcs[12] := SQ; FStdInstProcs[13] := SA; FStdInstProcs[14] := SB; @@ -725,73 +802,126 @@ begin FStdInstProcs[47] := RSSU; FStdInstProcs[48] := JT; FStdInstProcs[49] := J; - FStdInstProcs[50] := JACTI; - FStdInstProcs[51] := JACTO; FStdInstProcs[52] := SLJT; FStdInstProcs[53] := SLJ; - FStdInstProcs[54] := TERMIN; - FStdInstProcs[55] := TERMOT; FStdInstProcs[56] := R; FStdInstProcs[57] := TBI; FStdInstProcs[58] := JBD; - FStdInstProcs[59] := INN; - FStdInstProcs[60] := OUT; - FStdInstProcs[61] := INMON; - FStdInstProcs[62] := OUTMON; + case gConfig.Mode of + m494: + begin + FStdInstProcs[11] := EXF; + FStdInstProcs[50] := JACTI; + FStdInstProcs[51] := JACTO; + FStdInstProcs[54] := TERMIN; + FStdInstProcs[55] := TERMOT; + FStdInstProcs[59] := INN; + FStdInstProcs[60] := OUT; + FStdInstProcs[61] := INMON; + FStdInstProcs[62] := OUTMON; + end; + m490: + begin + FStdInstProcs[11] := EXF490; + FStdInstProcs[50] := JACTI490; + FStdInstProcs[51] := JACTO490; + FStdInstProcs[54] := TERMIN490; + FStdInstProcs[55] := TERMOT490; + FStdInstProcs[59] := INN490; + FStdInstProcs[60] := OUT490; + FStdInstProcs[61] := INMON490; + FStdInstProcs[62] := OUTMON490; + end; + m1230: + begin + FStdInstProcs[11] := EXF1230; + FStdInstProcs[50] := JACTI490; + FStdInstProcs[51] := JACTO490; + FStdInstProcs[54] := TERMIN1230; + FStdInstProcs[55] := TERMOT1230; + FStdInstProcs[59] := INN490; + FStdInstProcs[60] := OUT1230; + FStdInstProcs[61] := INMON490; + FStdInstProcs[62] := OUTMON1230; + end; + end; // Extended instructions - FExtInstProcs[1] := FA; - FExtInstProcs[2] := FAN; - FExtInstProcs[3] := FM; - FExtInstProcs[5] := FD; - FExtInstProcs[6] := FP; - FExtInstProcs[7] := FU; - FExtInstProcs[8] := DT; - FExtInstProcs[9] := DA; - FExtInstProcs[10] := DAN; - FExtInstProcs[11] := DTE; - FExtInstProcs[12] := DN; - FExtInstProcs[13] := DAC; - FExtInstProcs[14] := DANB; - FExtInstProcs[15] := DTL; - FExtInstProcs[17] := DPL; - FExtInstProcs[18] := DPA; - FExtInstProcs[19] := DPTE; - FExtInstProcs[20] := DPN; - FExtInstProcs[21] := DPS; - FExtInstProcs[22] := DPAN; - FExtInstProcs[23] := DPTL; - FExtInstProcs[24] := SFS; - FExtInstProcs[25] := CPL; - FExtInstProcs[26] := CPU; - FExtInstProcs[27] := DCL; - FExtInstProcs[28] := DCU; - FExtInstProcs[29] := CUL; - FExtInstProcs[30] := CUU; - FExtInstProcs[31] := ER; - FExtInstProcs[32] := LBPJB0; - FExtInstProcs[33] := LBPJB1; - FExtInstProcs[34] := LBPJB2; - FExtInstProcs[35] := LBPJB3; - FExtInstProcs[36] := LBPJB4; - FExtInstProcs[37] := LBPJB5; - FExtInstProcs[38] := LBPJB6; - FExtInstProcs[39] := LBPJB7; - FExtInstProcs[41] := LRSQ; - FExtInstProcs[42] := TSET; - FExtInstProcs[43] := MATE; - FExtInstProcs[44] := EXRN; - FExtInstProcs[45] := LRSA; - FExtInstProcs[46] := LRSAQ; - FExtInstProcs[47] := MATL; - FExtInstProcs[49] := EIR; - FExtInstProcs[50] := LPLR; - FExtInstProcs[53] := SIFR; - FExtInstProcs[54] := ERIR; - FExtInstProcs[57] := LBW; - FExtInstProcs[58] := SCN; - FExtInstProcs[59] := ECSR; - FExtInstProcs[61] := SBW; - FExtInstProcs[63] := LOG; + case gConfig.Mode of + m494: + begin + FExtInstProcs[1] := FA; + FExtInstProcs[2] := FAN; + FExtInstProcs[3] := FM; + FExtInstProcs[5] := FD; + FExtInstProcs[6] := FP; + FExtInstProcs[7] := FU; + FExtInstProcs[8] := DT; + FExtInstProcs[9] := DA; + FExtInstProcs[10] := DAN; + FExtInstProcs[11] := DTE; + FExtInstProcs[12] := DN; + FExtInstProcs[13] := DAC; + FExtInstProcs[14] := DANB; + FExtInstProcs[15] := DTL; + FExtInstProcs[17] := DPL; + FExtInstProcs[18] := DPA; + FExtInstProcs[19] := DPTE; + FExtInstProcs[20] := DPN; + FExtInstProcs[21] := DPS; + FExtInstProcs[22] := DPAN; + FExtInstProcs[23] := DPTL; + FExtInstProcs[24] := SFS; + FExtInstProcs[25] := CPL; + FExtInstProcs[26] := CPU; + FExtInstProcs[27] := DCL; + FExtInstProcs[28] := DCU; + FExtInstProcs[29] := CUL; + FExtInstProcs[30] := CUU; + FExtInstProcs[31] := ER; + FExtInstProcs[32] := LBPJB0; + FExtInstProcs[33] := LBPJB1; + FExtInstProcs[34] := LBPJB2; + FExtInstProcs[35] := LBPJB3; + FExtInstProcs[36] := LBPJB4; + FExtInstProcs[37] := LBPJB5; + FExtInstProcs[38] := LBPJB6; + FExtInstProcs[39] := LBPJB7; + FExtInstProcs[41] := LRSQ; + FExtInstProcs[42] := TSET; + FExtInstProcs[43] := MATE; + FExtInstProcs[44] := EXRN; + FExtInstProcs[45] := LRSA; + FExtInstProcs[46] := LRSAQ; + FExtInstProcs[47] := MATL; + FExtInstProcs[49] := EIR; + FExtInstProcs[50] := LPLR; + FExtInstProcs[53] := SIFR; + FExtInstProcs[54] := ERIR; + FExtInstProcs[57] := LBW; + FExtInstProcs[58] := SCN; + FExtInstProcs[59] := ECSR; + FExtInstProcs[61] := SBW; + FExtInstProcs[63] := LOG; + end; + m1230: + begin + FExtInstProcs[7] := NORM; + FExtInstProcs[48] := ESR; + FExtInstProcs[49] := EISR; + FExtInstProcs[50] := EOSR; + FExtInstProcs[51] := EESR; + FExtInstProcs[52] := EICDM; + FExtInstProcs[53] := EOCDM; + FExtInstProcs[54] := DICDM; + FExtInstProcs[55] := DOCDM; + FExtInstProcs[56] := SSR; + FExtInstProcs[57] := SISR; + FExtInstProcs[58] := SOSR; + FExtInstProcs[59] := SESR; + FExtInstProcs[60] := D17; + FExtInstProcs[61] := E17; + end; + end; end; procedure T494Cpu.CUL; @@ -938,6 +1068,11 @@ with assembler manual when I get it. } end; end; +procedure T494Cpu.D17; +begin + +end; + procedure T494Cpu.DA; var addr: UInt32; @@ -1056,6 +1191,11 @@ begin FMemory.StoreAQ(aq); end; +procedure T494Cpu.DICDM; +begin + +end; + procedure T494Cpu.DN; var op1, op2: TBcd; @@ -1070,6 +1210,16 @@ begin FMemory.StoreBcdAQ(op1); end; +procedure T494Cpu.DOCDM; +begin + +end; + +procedure T494Cpu.E17; +begin + +end; + procedure T494Cpu.ECSR; begin if (FInterruptActive) then @@ -1078,6 +1228,16 @@ begin FMemory.CSR.Value := FMemory.Fetch(FMemory.Operand.Value).Value; end; +procedure T494Cpu.EESR; +begin + +end; + +procedure T494Cpu.EICDM; +begin + +end; + procedure T494Cpu.EIR; var addr: UInt32; @@ -1088,6 +1248,21 @@ begin FMemory.IFR.SetDelay(1); end; +procedure T494Cpu.EISR; +begin + +end; + +procedure T494Cpu.EOCDM; +begin + +end; + +procedure T494Cpu.EOSR; +begin + +end; + procedure T494Cpu.ER; begin FExecRemotePending := True; @@ -1099,6 +1274,16 @@ begin FMemory.RIR.Value := FMemory.Fetch(FMemory.Operand.Value).Value; end; +procedure T494Cpu.ESR; +var + r: Byte; +begin + r := FMemory.Inst.j77; + if (r > 2) then + raise Exception.CreateFmt('Illegal SR (%d)', [r]); + FMemory.SR[r].Value := FMemory.Inst.y.Value15 and $f; +end; + procedure T494Cpu.LA; begin FMemory.A := StdFetch; @@ -1153,9 +1338,9 @@ var procedure ExtendSign; begin if ((FMemory.B[b1, b2].Value and $4fff) = 0) then - FMemory.B[b1, b2] := FMemory.B[b1, b2].Value and (not $18000) + FMemory.B[b1, b2].Value := FMemory.B[b1, b2].Value and (not $18000) else - FMemory.B[b1, b2] := FMemory.B[b1, b2].Value or $18000; + FMemory.B[b1, b2].Value := FMemory.B[b1, b2].Value or $18000; end; begin @@ -1170,22 +1355,22 @@ begin 0, 4: begin - FMemory.B[b1, b2] := FMemory.Operand.Value15; + FMemory.B[b1, b2].Value := FMemory.Operand.Value15; end; 1, 3, 5: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).H2.Value and BITS15; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).H2.Value and BITS15; end; 2, 6: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).H1.Value and BITS15; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).H1.Value and BITS15; end; 7: begin - FMemory.B[b1, b2] := FMemory.A.H2.Value and BITS15; + FMemory.B[b1, b2].Value := FMemory.A.H2.Value and BITS15; end; end; end else @@ -1193,38 +1378,38 @@ begin case FMemory.Inst.k of 0: begin - FMemory.B[b1, b2] := FMemory.Operand.Value; + FMemory.B[b1, b2].Value := FMemory.Operand.Value; end; 1: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).H2.Value; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).H2.Value; end; 2: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).H1.Value; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).H1.Value; end; 3: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).Value and BITS17; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).Value and BITS17; end; 4: begin - FMemory.B[b1, b2] := FMemory.Operand.Value15; + FMemory.B[b1, b2].Value := FMemory.Operand.Value15; ExtendSign; end; 5: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).H2.Value; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).H2.Value; ExtendSign; end; 6: begin - FMemory.B[b1, b2] := FMemory.Fetch(FMemory.Operand.Value).H1.Value; + FMemory.B[b1, b2].Value := FMemory.Fetch(FMemory.Operand.Value).H1.Value; ExtendSign; end; 7: begin - FMemory.B[b1, b2] := FMemory.A.Value and BITS17; + FMemory.B[b1, b2].Value := FMemory.A.Value and BITS17; end; end; end; @@ -1237,43 +1422,43 @@ end; procedure T494Cpu.LBPJB1; begin - FMemory.B[FMemory.IFR.f6, 1] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 1].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; procedure T494Cpu.LBPJB2; begin - FMemory.B[FMemory.IFR.f6, 2] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 2].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; procedure T494Cpu.LBPJB3; begin - FMemory.B[FMemory.IFR.f6, 3] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 3].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; procedure T494Cpu.LBPJB4; begin - FMemory.B[FMemory.IFR.f6, 4] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 4].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; procedure T494Cpu.LBPJB5; begin - FMemory.B[FMemory.IFR.f6, 5] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 5].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; procedure T494Cpu.LBPJB6; begin - FMemory.B[FMemory.IFR.f6, 6] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 6].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; procedure T494Cpu.LBPJB7; begin - FMemory.B[FMemory.IFR.f6, 7] := FMemory.P.Value - FMemory.RIR.Value; + FMemory.B[FMemory.IFR.f6, 7].Value := FMemory.P.Value - FMemory.RIR.Value; FMemory.P := FMemory.Operand.Value; end; @@ -1282,13 +1467,13 @@ var addr: UInt32; begin addr := FMemory.Operand.Value; - FMemory.B[1, 1] := FMemory.Fetch(addr).H2.Value; - FMemory.B[1, 2] := FMemory.Fetch(addr + 1).H2.Value; - FMemory.B[1, 3] := FMemory.Fetch(addr + 2).H2.Value; - FMemory.B[1, 4] := FMemory.Fetch(addr + 3).Value; - FMemory.B[1, 5] := FMemory.Fetch(addr + 4).Value; - FMemory.B[1, 6] := FMemory.Fetch(addr + 5).Value; - FMemory.B[1, 7] := FMemory.Fetch(addr + 6).Value; + FMemory.B[1, 1].Value := FMemory.Fetch(addr).H2.Value; + FMemory.B[1, 2].Value := FMemory.Fetch(addr + 1).H2.Value; + FMemory.B[1, 3].Value := FMemory.Fetch(addr + 2).H2.Value; + FMemory.B[1, 4].Value := FMemory.Fetch(addr + 3).Value; + FMemory.B[1, 5].Value := FMemory.Fetch(addr + 4).Value; + FMemory.B[1, 6].Value := FMemory.Fetch(addr + 5).Value; + FMemory.B[1, 7].Value := FMemory.Fetch(addr + 6).Value; end; procedure T494Cpu.LLP; @@ -1373,10 +1558,7 @@ begin FMemory.Inst.ybar := FMemory.Inst.y; if (b <> 0) then begin - if ((FMemory.IFR.f7 = 0) or ((b >= 1) and (b <= 3))) then - bval := FMemory.B[FMemory.IFR.f6, b].Value15 - else - bval := FMemory.B[FMemory.IFR.f6, b].Value; + bval := FMemory.B[FMemory.IFR.f6, b].Value; FMemory.Inst.ybar := FMemory.Inst.y + bval; if ((FMemory.IFR.f7 = 0) or ((b >= 1) and (b <= 3))) then FMemory.Inst.ybar := FMemory.Inst.ybar.Value15; @@ -1398,7 +1580,7 @@ begin end; 3: begin - FMemory.IFR.f1 := FMemory.IFR.f1 + FMemory.B[FMemory.IFR.f6, FMemory.Inst.b]; + FMemory.IFR.f1 := FMemory.IFR.f1 + FMemory.B[FMemory.IFR.f6, FMemory.Inst.b]^; end; 4: begin @@ -1416,7 +1598,7 @@ begin end; 7: begin - FMemory.IFR.f1 := FMemory.IFR.f1 + FMemory.B[FMemory.IFR.f6, FMemory.Inst.b]; + FMemory.IFR.f1 := FMemory.IFR.f1 + FMemory.B[FMemory.IFR.f6, FMemory.Inst.b]^; FMemory.Store(FMemory.Operand.Value + FMemory.B[Fmemory.IFR.f6, 6].Value, FMemory.IFR.f1.Value); end; end; @@ -1471,9 +1653,46 @@ begin 0, 1, 2: Exit; + 3: + begin + if (Assigned(FChannels[chan])) then + FChannels[chan].ExternalFunction(FMemory.Fetch(FMemory.Operand.Value)); + end; + end; +end; + +procedure T494Cpu.EXF1230; +var + chan: Byte; +begin + chan := FMemory.Inst.jhat; + case FMemory.Inst.khat of + 0, + 1, + 3: raise Exception.CreateFmt('EXF1230 designator %d not implemented', [FMemory.Inst.khat]); + 2: + begin + if (Assigned(FChannels[chan])) then + FChannels[chan].ExternalFunction(FMemory.Fetch(FMemory.Operand.Value)); + end; + end; +end; + +procedure T494Cpu.EXF490; +var + chan: Byte; +begin + chan := FMemory.Inst.jhat; + case FMemory.Inst.khat of + 0, + 1, + 2: Exit; + 3: + begin + if (Assigned(FChannels[chan])) then + FChannels[chan].ExternalFunction(FMemory.Fetch(FMemory.Operand.Value)); + end; end; - if (Assigned(FChannels[chan])) then - FChannels[chan].ExternalFunction(FMemory.Fetch(FMemory.Operand.Value)); end; procedure T494Cpu.EXRN; @@ -1648,10 +1867,7 @@ instruction. } FMemory.Inst.ybar := FMemory.Inst.y; if (b <> 0) then begin - if ((FMemory.IFR.f7 = 0) or ((b >= 1) and (b <= 3))) then - bval := FMemory.B[FMemory.IFR.f6, b].Value15 - else - bval := FMemory.B[FMemory.IFR.f6, b].Value; + bval := FMemory.B[FMemory.IFR.f6, b].Value; FMemory.Inst.ybar := FMemory.Inst.y + bval; if ((FMemory.IFR.f7 = 0) or ((b >= 1) and (b <= 3))) then FMemory.Inst.ybar := FMemory.Inst.ybar.Value15; @@ -1899,7 +2115,7 @@ begin chan := FMemory.IASR.Value else chan := FMemory.CSR.Value; - addr := BcrIn0 + chan; + addr := BcrIn(chan); bcr := FMemory.Fetch(addr.Value); case FMemory.Inst.khat of 0: Exit; @@ -1913,6 +2129,29 @@ begin FChannels[chan].ActivateInput(True); end; +procedure T494Cpu.INMON490; +var + operand: T494Word; + chan: Byte; + addr: T494Address; + bcr: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + addr := BcrIn(chan); + bcr := FMemory.Fetch(addr.Value); + case FMemory.Inst.khat of + 0: bcr.H2 := operand.H2; + 1: bcr.H2 := operand.H2; + 2: ; + 3: bcr := operand; + end; + FMemory.Store(addr.Value, bcr); + if (not Assigned(FChannels[chan])) then + Exit; + FChannels[chan].ActivateInput(True); +end; + procedure T494Cpu.INN; var operand: T494Word; @@ -1925,7 +2164,7 @@ begin chan := FMemory.IASR.Value else chan := FMemory.CSR.Value; - addr := BcrIn0 + chan; + addr := BcrIn(chan); bcr := FMemory.Fetch(addr.Value); case FMemory.Inst.khat of 0: Exit; @@ -1939,6 +2178,29 @@ begin FChannels[chan].ActivateInput(False); end; +procedure T494Cpu.INN490; +var + operand: T494Word; + chan: Byte; + addr: T494Address; + bcr: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + addr := BcrIn(chan); + bcr := FMemory.Fetch(addr.Value); + case FMemory.Inst.khat of + 0: bcr.H2 := operand.H2; + 1: bcr.H2 := operand.H2; + 2: ; + 3: bcr := operand; + end; + FMemory.Store(addr.Value, bcr); + if (not Assigned(FChannels[chan])) then + Exit; + FChannels[chan].ActivateInput(False); +end; + function T494Cpu.IOFetch: T494Word; // Fetch the operand for I/O type instructions var @@ -2107,6 +2369,26 @@ begin end; end; +procedure T494Cpu.JACTI490; +var + chan: Byte; + operand: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + if (not Assigned(FChannels[chan])) then + Exit; + if (FChannels[chan].InputActive) then + begin + case FMemory.Inst.khat of + 0: FMemory.P := operand.Value; + 1, + 3: FMemory.P := operand.H2.Value; + 2: FMemory.P := operand.H1.Value; + end; + end; +end; + procedure T494Cpu.JACTO; var chan: Byte; @@ -2130,6 +2412,26 @@ begin end; end; +procedure T494Cpu.JACTO490; +var + chan: Byte; + operand: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + if (not Assigned(FChannels[chan])) then + Exit; + if (FChannels[chan].OutputActive) then + begin + case FMemory.Inst.khat of + 0: FMemory.P := operand.Value; + 1, + 3: FMemory.P := operand.H2.Value; + 2: FMemory.P := operand.H1.Value; + end; + end; +end; + function T494Cpu.LeftShift(value: UInt32; count: Integer): UInt32; begin if (count > 59) then @@ -2403,6 +2705,11 @@ begin pi^ := r; end; +procedure T494Cpu.NORM; +begin + +end; + procedure T494Cpu.NormalSkip; // Skip processing for "normal" instructions begin @@ -2503,7 +2810,11 @@ begin if (op = $3f) then begin g := FMemory.Inst.g; - FCurOpcode := U494ExtOpcodes[g]; + case gConfig.Mode of + m494: FCurOpcode := U494ExtOpcodes[g]; + m490: IllegalInst; + m1230: FCurOpcode := U1230ExtOpcodes[g]; + end; FCurInstProc := FExtInstProcs[g]; end else begin @@ -2648,6 +2959,11 @@ begin end; end; +procedure T494Cpu.SOSR; +begin + +end; + procedure T494Cpu.SLJ; var operand, mem: T494Word; @@ -2718,7 +3034,7 @@ var operand: T494Word; begin operand := StdFetch; - FMemory.B[FMemory.IFR.f6, 7] := operand.Value; + FMemory.B[FMemory.IFR.f6, 7].Value := operand.Value; if (operand.Value = 0) then begin FMemory.P := FMemory.P + 1; @@ -2835,7 +3151,7 @@ begin chan := FMemory.IASR.Value else chan := FMemory.CSR.Value; - addr := BcrOut0 + chan; + addr := BcrOut(chan); if ((FMemory.Inst.jhat mod 2) = 1) then begin if (Assigned(FChannels[chan])) then @@ -2855,6 +3171,52 @@ begin end; end; +procedure T494Cpu.OUTMON1230; +var + operand: T494Word; + chan: Byte; + addr: T494Address; + bcr: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + addr := BcrOut(chan); + if (FMemory.Inst.khat = 2) then + addr := BcrExt(chan); + bcr := FMemory.Fetch(addr.Value); + case FMemory.Inst.khat of + 0: bcr.H2 := operand.H2; + 1: bcr.H2 := operand.H2; + 2: bcr := operand; + 3: bcr := operand; + end; + FMemory.Store(addr.Value, bcr); + if (Assigned(FChannels[chan])) then + FChannels[chan].ActivateOutput(True); +end; + +procedure T494Cpu.OUTMON490; +var + operand: T494Word; + chan: Byte; + addr: T494Address; + bcr: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + addr := BcrOut(chan); + bcr := FMemory.Fetch(addr.Value); + case FMemory.Inst.khat of + 0: bcr.H2 := operand.H2; + 1: bcr.H2 := operand.H2; + 2: ; + 3: bcr := operand; + end; + FMemory.Store(addr.Value, bcr); + if (Assigned(FChannels[chan])) then + FChannels[chan].ActivateOutput(True); +end; + procedure T494Cpu.OUT; var operand: T494Word; @@ -2867,7 +3229,7 @@ begin chan := FMemory.IASR.Value else chan := FMemory.CSR.Value; - addr := BcrOut0 + chan; + addr := BcrOut(chan); if ((FMemory.Inst.jhat mod 2) = 1) then begin if (Assigned(FChannels[chan])) then @@ -2887,6 +3249,62 @@ begin end; end; +procedure T494Cpu.OUT1230; +var + operand: T494Word; + chan: Byte; + addr: T494Address; + bcr: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + addr := BcrOut(chan); + if (FMemory.Inst.khat = 2) then + addr := BcrExt(chan); + bcr := FMemory.Fetch(addr.Value); + case FMemory.Inst.khat of + 0: bcr.H2 := operand.H2; + 1: bcr.H2 := operand.H2; + 2: bcr := operand; + 3: bcr := operand; + end; + FMemory.Store(addr.Value, bcr); + if (Assigned(FChannels[chan])) then + FChannels[chan].ActivateOutput(False); +end; + +procedure T494Cpu.OUT490; +var + operand: T494Word; + chan: Byte; + addr: T494Address; + bcr: T494Word; +begin + operand := IOFetch; + chan := FMemory.Inst.jhat; + addr := BcrOut(chan); + bcr := FMemory.Fetch(addr.Value); + case FMemory.Inst.khat of + 0: bcr.H2 := operand.H2; + 1: bcr.H2 := operand.H2; + 2: ; + 3: bcr := operand; + end; + FMemory.Store(addr.Value, bcr); + if (Assigned(FChannels[chan])) then + FChannels[chan].ActivateOutput(False); +end; + +procedure T494Cpu.SSR; +var + r: Byte; +begin + r := FMemory.Inst.j77; + if (r > 2) then + raise Exception.CreateFmt('Illegal SR (%d)', [r]); + FMemory.Q.Value := FMemory.SR[r].Value; +end; + procedure T494Cpu.SSU; var operand: T494Word; @@ -2938,6 +3356,11 @@ begin FMemory.Store(FMemory.Operand.Value, word); end; +procedure T494Cpu.SISR; +begin + +end; + procedure T494Cpu.Start; var count: Integer; @@ -3293,10 +3716,7 @@ begin case FMemory.Inst.k of 0: begin - if ((FMemory.IFR.f7 = 0) or ((b2 >= 1) and (b2 <= 3))) then - FMemory.Q := FMemory.B[b1, b2].Value15 - else - FMemory.Q := FMemory.B[b1, b2].Value; + FMemory.Q := FMemory.B[b1, b2].Value; end; 1: begin @@ -3307,32 +3727,24 @@ begin 2: begin value := FMemory.Fetch(addr); - hvalue.Value := FMemory.B[b1, b2].Value15; + hvalue.Value := FMemory.B[b1, b2].Value; value.H1 := hvalue; FMemory.Store(addr, value); end; 3: begin - value := FMemory.Fetch(addr); - value := 0; - if ((FMemory.IFR.f7 = 0) or ((b2 >= 1) and (b2 <= 3))) then - value.H2 := FMemory.B[b1, b2].Value15 - else - value.Value := FMemory.B[b1, b2].Value; + value.Value := FMemory.B[b1, b2].Value; FMemory.Store(addr, value); end; 4: begin - if ((FMemory.IFR.f7 = 0) or ((b2 >= 1) and (b2 <= 3))) then - FMemory.A := FMemory.B[b1, b2].Value15 - else - FMemory.A := FMemory.B[b1, b2].Value; + FMemory.A := FMemory.B[b1, b2].Value; end; 5: begin value := FMemory.Fetch(addr); hvalue := value.H2; - hvalue.Value := FMemory.B[b1, b2].Value15 xor BITS15; + hvalue.Value := (FMemory.B[b1, b2].Value and BITS15) xor BITS15; value.H2 := hvalue; FMemory.Store(addr, value); end; @@ -3340,7 +3752,7 @@ begin begin value := FMemory.Fetch(addr); hvalue := value.H1; - hvalue.Value := FMemory.B[b1, b2].Value15 xor BITS15; + hvalue.Value := (FMemory.B[b1, b2].Value and BITS15) xor BITS15; value.H1 := hvalue; FMemory.Store(addr, value); end; @@ -3349,7 +3761,7 @@ begin value := FMemory.Fetch(addr); if ((FMemory.IFR.f7 = 0) or ((b2 >= 1) and (b2 <= 3))) then begin - bval := (not FMemory.B[b1, b2].Value15) and BITS15; + bval := (not FMemory.B[b1, b2].Value) and BITS15; if ((bval and BIT14) = 0) then value.Value := 0 else @@ -3376,11 +3788,11 @@ var word: T494Word; begin addr := FMemory.Operand.Value; - word.Value := FMemory.B[1, 1].Value15; + word.Value := FMemory.B[1, 1].Value; FMemory.Store(addr, word); - word.Value := FMemory.B[1, 2].Value15; + word.Value := FMemory.B[1, 2].Value; FMemory.Store(addr + 1, word); - word.Value := FMemory.B[1, 3].Value15; + word.Value := FMemory.B[1, 3].Value; FMemory.Store(addr + 2, word); word.Value := FMemory.B[1, 4].Value; FMemory.Store(addr + 3, word); @@ -3409,6 +3821,11 @@ begin FMemory.Store(FMemory.Operand.Value, value); end; +procedure T494Cpu.SESR; +begin + +end; + procedure T494Cpu.SetInterruptActive(const Value: Boolean); begin FInterruptActive := Value; @@ -3608,12 +4025,12 @@ end; function T494Device.FetchInputBcr: T494Word; begin - Result := FMemory.Fetch(BcrIn0 + FChannel, True); + Result := FMemory.Fetch(BcrIn(FChannel), True); end; function T494Device.FetchOutputBcr: T494Word; begin - Result := FMemory.Fetch(BcrOut0 + FChannel, True); + Result := FMemory.Fetch(BcrOut(FChannel), True); end; function T494Device.InputActive: Boolean; @@ -3644,12 +4061,12 @@ end; procedure T494Device.StoreInputBcr(Value: T494Word); begin - Fmemory.Store(BcrIn0 + FChannel, Value, True); + Fmemory.Store(BcrIn(FChannel), Value, True); end; procedure T494Device.StoreOutputBcr(Value: T494Word); begin - Fmemory.Store(BcrOut0 + FChannel, Value, True); + Fmemory.Store(BcrOut(FChannel), Value, True); end; procedure T494Device.Terminate; diff --git a/U494/U494Memory.pas b/U494/U494Memory.pas index 1645144..acdd723 100644 --- a/U494/U494Memory.pas +++ b/U494/U494Memory.pas @@ -30,55 +30,16 @@ const IIsiOutput = 22; IParityBank3 = 23; ITestAndSet = 24; - // Buffer Control Register addresses - BcrOut0 = 32; - BcrOut1 = 33; - BcrOut2 = 34; - BcrOut3 = 35; - BcrOut4 = 36; - BcrOut5 = 37; - BcrOut6 = 38; - BcrOut7 = 39; - BcrOut8 = 40; - BcrOut9 = 41; - BcrOut10 = 42; - BcrOut11 = 43; - BcrOut12 = 44; - BcrOut13 = 45; - BcrOut14 = 46; - BcrOut15 = 47; - BcrOut16 = 48; - BcrOut17 = 49; - BcrOut18 = 50; - BcrOut19 = 51; - BcrOut20 = 52; - BcrOut21 = 53; - BcrOut22 = 54; - BcrOut23 = 55; - BcrIn0 = 64; - BcrIn1 = 65; - BcrIn2 = 66; - BcrIn3 = 67; - BcrIn4 = 68; - BcrIn5 = 69; - BcrIn6 = 70; - BcrIn7 = 71; - BcrIn8 = 72; - BcrIn9 = 73; - BcrIn10 = 74; - BcrIn11 = 75; - BcrIn12 = 76; - BcrIn13 = 77; - BcrIn14 = 78; - BcrIn15 = 79; - BcrIn16 = 80; - BcrIn17 = 81; - BcrIn18 = 82; - BcrIn19 = 83; - BcrIn20 = 84; - BcrIn21 = 85; - BcrIn22 = 86; - BcrIn23 = 87; + // BCR starting addresses + BcrIn494 = 64; + BcrOut494= 32; + BcrIn490 = 64; + BcrOut490= 80; + BcrIn1230 = 64; + BcrOut1230= 80; + BcrExt1230 = 96; + // 1230 B register memory start + B1230 = 113; // Misc low memory locations DayClock = 14; RTClock = 15; @@ -91,6 +52,23 @@ const BIT29 = $20000000; // Sign bit for 30-bit word type + T494Memory = class; + + T494BRegister = packed record // Used to hold 17-bit addresses + private + FValue: UInt32; + FRegNumber: Byte; + FMemory: T494Memory; + function GetValue15: UInt32; + function GetValue: UInt32; + procedure SetValue(const Value: UInt32); + public + property Value: UInt32 read GetValue write SetValue; +// property Value15: UInt32 read GetValue15; + end; + + P494BRegister = ^T494BRegister; + T494Address = packed record // Used to hold 17-bit addresses private FValue: UInt32; @@ -99,6 +77,7 @@ type procedure SetValue(const Value: UInt32); public class operator Add(a: T494Address; b: Integer): T494Address; + class operator Add(a: T494Address; b: T494BRegister): T494Address; class operator Add(a, b: T494Address): T494Address; class operator Equal(a, b: T494Address): Boolean; class operator GreaterThan(a: T494Address; b: Integer): Boolean; @@ -112,6 +91,8 @@ type property Value15: UInt32 read GetValue15; end; + P494Address = ^T494Address; + T494HalfWord = packed record // Simulate a Univac 494 half word. A 15-bit ones complement value. // The value is stored in the lower 15 bits with sign extension @@ -254,9 +235,15 @@ type function GetCount: UInt32; procedure SetAddress(const Value: UInt32); procedure SetCount(const Value: UInt32); + function GetEndAddr: UInt32; + function GetStartAddr: UInt32; + procedure SetEndAddr(const Value: UInt32); + procedure SetStartAddr(const Value: UInt32); public property Address: UInt32 read GetAddress write SetAddress; + property EndAddr: UInt32 read GetEndAddr write SetEndAddr; property Count: UInt32 read GetCount write SetCount; + property StartAddr: UInt32 read GetStartAddr write SetStartAddr; property Value: UInt32 read GetValue write SetValue; end; @@ -270,9 +257,12 @@ type function f: Byte; function g: Byte; function j: Byte; + function j77: Byte; function jhat: Byte; function k: Byte; + function k77: Byte; function khat: Byte; + function s: Byte; function y: T494Address; property Value: UInt32 read FValue; property ybar: T494Address read Fybar write Fybar; @@ -294,12 +284,23 @@ type property Value: Byte read FValue write SetValue; end; + T1230Sr = packed record + private + FValue: Byte; + procedure SetValue(const Value: Byte); + public + property Value: Byte read FValue write SetValue; + end; + T494Memory = class // Simulate Univac 494 memory of 128K, 30-bit words. // Also provides a storage area for the various CPU registers. private FCore: array [0..MemSize] of T494Word; + FB: array [0..1, 1..7] of T494BRegister; // B (index) registers + // 0 = exec 1 = user function NativeToBcd(value: UInt64): TBcd; + function GetB(i, j: Integer): P494BRegister; public // registers IFR: T494Ifr; // Internal function register @@ -316,8 +317,8 @@ type A: T494Word; Q: T494Word; K: T494Word; - B: array [0..1, 1..7] of T494Address; // B (index) registers - // 0 = exec 1 = user + SR: array [0..2] of T1230Sr; // 1230 bank descriptors + constructor Create; function Fetch(addr: Integer; nolimit: Boolean = False): T494Word; function FetchAQ: UInt64; function FetchBcd(addr: Integer; nolimit: Boolean = False): TBcd; @@ -329,11 +330,45 @@ type procedure StoreBcdAQ(value: TBcd); procedure StoreBcr(addr: Integer; value: T494Bcr; nolimit: Boolean = False); procedure StoreDWord(addr: Integer; value: T494DWord; nolimit: Boolean = False); + property B[i, j: Integer]: P494BRegister read GetB; end; + function BcrEXT(chan: Byte): Integer; + function BcrIN(chan: Byte): Integer; + function BcrOUT(chan: Byte): Integer; + implementation -uses U494Util; +uses U494Util, U494Config; + +function BcrEXT(chan: Byte): Integer; +begin + if (gConfig.Mode = m1230) then + Result := BcrExt1230 + chan + else + Result := 0; +end; + +function BcrIN(chan: Byte): Integer; +begin + case gConfig.Mode of + m494: Result := BcrIn494 + chan; + m490: Result := BcrIn490 + chan; + m1230: Result := BcrIn1230 + chan; + else Result := BcrIn494 + chan; + end; +end; + +function BcrOUT(chan: Byte): Integer; +begin + case gConfig.Mode of + m494: Result := BcrOut494 + chan; + m490: Result := BcrOut490 + chan; + m1230: Result := BcrOut1230 + chan; + else Result := BcrOut494 + chan; + end; +end; + { T494Word } @@ -569,6 +604,11 @@ begin Result := (FValue and $e00000) shr 21; end; +function T494Inst.j77: Byte; +begin + Result := (FValue shr 9) and $0f; +end; + function T494Inst.jhat: Byte; begin Result := (FValue and $f00000) shr 20; @@ -580,11 +620,21 @@ begin Result := (FValue and $1c0000) shr 18; end; +function T494Inst.k77: Byte; +begin + Result := (FValue shr 8) and $1; +end; + function T494Inst.khat: Byte; begin Result := (FValue and $c0000) shr 18; end; +function T494Inst.s: Byte; +begin + Result := (FValue shr 13) and $3; +end; + function T494Inst.y: T494Address; begin Result.FValue := FValue and BITS15; @@ -603,6 +653,11 @@ begin Result.FValue := (a.FValue + b.FValue) and BITS17; end; +class operator T494Address.Add(a: T494Address; b: T494BRegister): T494Address; +begin + Result.FValue := (a.FValue + b.FValue) and BITS17; +end; + class operator T494Address.Equal(a, b: T494Address): Boolean; begin Result := Integer(a) = Integer(b); @@ -811,6 +866,18 @@ end; { T494Memory } +constructor T494Memory.Create; +var + i, j: Integer; +begin + for i := 0 to 1 do + for j := 1 to 7 do + begin + FB[i, j].FRegNumber := j; + FB[i, j].FMemory := Self; + end; +end; + function T494Memory.Fetch(addr: Integer; nolimit: Boolean): T494Word; begin if (not nolimit) then @@ -866,6 +933,11 @@ begin Result.Value := Int64(FCore[addr].Value) shl 30 or FCore[addr + 1].Value; end; +function T494Memory.GetB(i, j: Integer): P494BRegister; +begin + Result := @FB[i, j]; +end; + function T494Memory.NativeToBcd(value: UInt64): TBcd; var n: Byte; @@ -965,12 +1037,28 @@ end; function T494Bcr.GetAddress: UInt32; begin - Result := FValue and BITS17; + case gConfig.Mode of + m494: Result := FValue and BITS17; + else Result := StartAddr; + end; end; function T494Bcr.GetCount: UInt32; begin - Result := (FValue and $3ffc0000) shr 18; + case gConfig.Mode of + m494: Result := (FValue and $3ffc0000) shr 18; + else Result := EndAddr - StartAddr + 1; + end; +end; + +function T494Bcr.GetEndAddr: UInt32; +begin + Result := (FValue shr 15) and BITS15; +end; + +function T494Bcr.GetStartAddr: UInt32; +begin + Result := FValue and BITS15; end; function T494Bcr.GetValue: UInt32; @@ -980,12 +1068,28 @@ end; procedure T494Bcr.SetAddress(const Value: UInt32); begin - FValue := (FValue and (not BITS17)) or (Value and BITS17); + case gConfig.Mode of + m494: FValue := (FValue and (not BITS17)) or (Value and BITS17); + else StartAddr := FValue; + end; end; procedure T494Bcr.SetCount(const Value: UInt32); begin - FValue := (FValue and (not $3ffc0000)) or ((Value and $fff) shl 18); + case gConfig.Mode of + m494: FValue := (FValue and (not $3ffc0000)) or ((Value and $fff) shl 18); + else StartAddr := EndAddr - Value + 1; + end; +end; + +procedure T494Bcr.SetEndAddr(const Value: UInt32); +begin + FValue := ((Value shl 15) and BITS15) or (FValue and BITS15) +end; + +procedure T494Bcr.SetStartAddr(const Value: UInt32); +begin + FValue := (FValue and (not BITS15)) or (Value and BITS15); end; procedure T494Bcr.SetValue(const Value: UInt32); @@ -1082,4 +1186,49 @@ begin FValue := Value and $1f; end; +{ T1230Sr } + +procedure T1230Sr.SetValue(const Value: Byte); +begin + FValue := Value and $f; +end; + +{ T494BRegister } + +function T494BRegister.GetValue: UInt32; +begin + case gConfig.Mode of + m494: + begin + if ((FMemory.IFR.f7 = 0) or (FRegNumber <= 3)) then + Result := FValue and BITS15 + else + Result := FValue and BITS17; + end; + m490: + begin + Result := FValue and BITS15; + end; + m1230: + begin + FValue := FMemory.Fetch(B1230 + FRegNumber - 1, True); + Result := FValue and BITS17; + end; + end; +end; + +function T494BRegister.GetValue15: UInt32; +begin + if (gConfig.Mode = m1230) then + FValue := FMemory.Fetch(B1230 + FRegNumber - 1, True); + Result := FValue and BITS15; +end; + +procedure T494BRegister.SetValue(const Value: UInt32); +begin + FValue := Value and BITS17; + if (gConfig.Mode = m1230) then + FMemory.Store(B1230 + FRegNumber - 1, FValue, True); +end; + end. diff --git a/U494/U494Opcodes.pas b/U494/U494Opcodes.pas index 6280045..5f431af 100644 --- a/U494/U494Opcodes.pas +++ b/U494/U494Opcodes.pas @@ -37,7 +37,7 @@ const (SpurtMnemonic: 'ENT.Q'; AsmMnemonic: 'LQ'; Opcode: 8; InstType: itRead; jInterpret: jiNormal; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'ENT.A'; AsmMnemonic: 'LA'; Opcode: 9; InstType: itRead; jInterpret: jiNormal; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'ENT.B'; AsmMnemonic: 'LB'; Opcode: 10; InstType: itRead; jInterpret: jiOther; OperandType: otBRegister; Priviledged: False), - (SpurtMnemonic: 'EX-FCT'; AsmMnemonic: 'EXF'; Opcode: 11; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'EX-FCT'; AsmMnemonic: 'EXF'; Opcode: 11; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), (SpurtMnemonic: 'STR.Q'; AsmMnemonic: 'SQ'; Opcode: 12; InstType: itStore; jInterpret: jiNormal; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'STR.A'; AsmMnemonic: 'SA'; Opcode: 13; InstType: itStore; jInterpret: jiNormal; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'STR.B'; AsmMnemonic: 'SB'; Opcode: 14; InstType: itStore; jInterpret: jiOther; OperandType: otBRegister; Priviledged: False), @@ -76,19 +76,19 @@ const (SpurtMnemonic: 'RSE.SU'; AsmMnemonic: 'RSSU'; Opcode: 47; InstType: itReplace; jInterpret: jiNormal; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'JP'; AsmMnemonic: 'JT'; Opcode: 48; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'JP.MAN'; AsmMnemonic: 'J'; Opcode: 49; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), - (SpurtMnemonic: 'JP.ACTI'; AsmMnemonic: 'JACTI'; Opcode: 50; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), - (SpurtMnemonic: 'JP.ACTO'; AsmMnemonic: 'JACTO'; Opcode: 51; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'JP.ACTI'; AsmMnemonic: 'JACTI'; Opcode: 50; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'JP.ACTO'; AsmMnemonic: 'JACTO'; Opcode: 51; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), (SpurtMnemonic: 'RJP'; AsmMnemonic: 'SLJT'; Opcode: 52; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'RJP.MAN'; AsmMnemonic: 'SLJ'; Opcode: 53; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), - (SpurtMnemonic: 'TERM.IN'; AsmMnemonic: 'TERMIN'; Opcode: 54; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), - (SpurtMnemonic: 'TERM.OUT'; AsmMnemonic: 'TERMOT'; Opcode: 55; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'TERM.IN'; AsmMnemonic: 'TERMIN'; Opcode: 54; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'TERM.OUT'; AsmMnemonic: 'TERMOT'; Opcode: 55; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), (SpurtMnemonic: 'RPT'; AsmMnemonic: 'R'; Opcode: 56; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'BSK.B'; AsmMnemonic: 'TBI'; Opcode: 57; InstType: itRead; jInterpret: jiOther; OperandType: otBRegister; Priviledged: False), (SpurtMnemonic: 'BJP.B'; AsmMnemonic: 'JBD'; Opcode: 58; InstType: itRead; jInterpret: jiOther; OperandType: otBRegister; Priviledged: False), - (SpurtMnemonic: 'IN'; AsmMnemonic: 'IN'; Opcode: 59; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), - (SpurtMnemonic: 'OUT'; AsmMnemonic: 'OUT'; Opcode: 60; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), - (SpurtMnemonic: 'IN.MON'; AsmMnemonic: 'INMON'; Opcode: 61; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), - (SpurtMnemonic: 'OUT.MON'; AsmMnemonic: 'OUTMON'; Opcode: 62; InstType: itIO; jInterpret: jiNormal; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'IN'; AsmMnemonic: 'IN'; Opcode: 59; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'OUT'; AsmMnemonic: 'OUT'; Opcode: 60; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'IN.MON'; AsmMnemonic: 'INMON'; Opcode: 61; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), + (SpurtMnemonic: 'OUT.MON'; AsmMnemonic: 'OUTMON'; Opcode: 62; InstType: itIO; jInterpret: jiNone; OperandType: otIO; Priviledged: True), (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 63) ); // Extended instructions (opcode 77). This table list the opcodes @@ -160,6 +160,73 @@ const (SpurtMnemonic: 'LOG'; AsmMnemonic: 'LOG'; Opcode: 63; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: False) ); + U1230ExtOpcodes: array [0..63] of T494Opcode = ( + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 0), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 1), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 2), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 3), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 4), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 5), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 6), + (SpurtMnemonic: 'NORM'; AsmMnemonic: 'NORM'; Opcode: 7; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: False), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 8), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 9), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 10), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 11), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 12), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 13), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 14), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 15), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 16), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 17), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 18), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 19), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 20), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 21), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 22), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 23), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 24), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 25), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 26), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 27), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 28), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 29), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 30), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 31), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 32), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 33), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 34), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 35), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 36), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 37), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 38), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 39), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 40), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 41), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 42), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 43), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 44), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 45), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 46), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 47), + (SpurtMnemonic: 'ESR'; AsmMnemonic: 'ESR'; Opcode: 48; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'EISR'; AsmMnemonic: 'EISR'; Opcode: 49; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'EOSR'; AsmMnemonic: 'EOSR'; Opcode: 50; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'EESR'; AsmMnemonic: 'EESR'; Opcode: 51; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'EICDM'; AsmMnemonic: 'EICDM'; Opcode: 52; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'EOCDM'; AsmMnemonic: 'EOCDM'; Opcode: 53; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'DICMD'; AsmMnemonic: 'DICDM'; Opcode: 54; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'EICMD'; AsmMnemonic: 'EICDM'; Opcode: 54; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'SSR'; AsmMnemonic: 'SSR'; Opcode: 56; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'SISR'; AsmMnemonic: 'SISR'; Opcode: 57; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: False), + (SpurtMnemonic: 'SOSR'; AsmMnemonic: 'SOSR'; Opcode: 58; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'SESR'; AsmMnemonic: 'SESR'; Opcode: 59; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'D71'; AsmMnemonic: 'D17'; Opcode: 60; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: True), + (SpurtMnemonic: 'E17'; AsmMnemonic: 'E17'; Opcode: 61; InstType: it77; JInterpret: jiNone; OperandType: ot77; Priviledged: False), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 62), + (SpurtMnemonic: 'UNK'; AsmMnemonic: 'UNK'; Opcode: 63) + ); + U494PsuedoOps: array [0..12] of T494Opcode = ( (SpurtMnemonic: 'COM.Q'; AsmMnemonic: 'TQ'; Opcode: 4; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), (SpurtMnemonic: 'COM.AQ'; AsmMnemonic: 'TR'; Opcode: 4; InstType: itRead; jInterpret: jiOther; OperandType: otGeneral; Priviledged: False), diff --git a/U494/U494Panel.dfm b/U494/U494Panel.dfm index 68cf688..fa928d3 100644 --- a/U494/U494Panel.dfm +++ b/U494/U494Panel.dfm @@ -700,10 +700,6 @@ object U494PanelFrm: TU494PanelFrm object PrinterPage: TTabSheet Caption = 'Printer' ImageIndex = 1 - ExplicitLeft = 0 - ExplicitTop = 0 - ExplicitWidth = 0 - ExplicitHeight = 0 object PrinterPanel: TPanel Left = 0 Top = 0 diff --git a/U494/U494Panel.pas b/U494/U494Panel.pas index a44ae44..ca43de2 100644 --- a/U494/U494Panel.pas +++ b/U494/U494Panel.pas @@ -227,15 +227,23 @@ begin FSystem := T494System.Create; FBreakpoints := TList.Create; PeripheralPages.ActivePageIndex := 0; - FReaderFrame := TU494ReaderFrame.Create(Self, FSystem.Reader); - FReaderFrame.Parent := ReaderPanel; - FReaderFrame.Align := alClient; - FPunchFrame := TU494PunchFrame.Create(Self, FSystem.Punch); - FPunchFrame.Parent := PunchPanel; - FPunchFrame.Align := alClient; - FPrinterFrame := TU494PrinterFrame.Create(Self, FSystem.Printer); - FPrinterFrame.Parent := PrinterPanel; - FPrinterFrame.Align := alClient; + if (gConfig.RdrPunChan <> -1) then + begin + FReaderFrame := TU494ReaderFrame.Create(Self, FSystem.Reader); + FReaderFrame.Parent := ReaderPanel; + FReaderFrame.Align := alClient; + FPunchFrame := TU494PunchFrame.Create(Self, FSystem.Punch); + FPunchFrame.Parent := PunchPanel; + FPunchFrame.Align := alClient; + end else + CardPage.TabVisible := False; + if (gConfig.PrinterChan <> -1) then + begin + FPrinterFrame := TU494PrinterFrame.Create(Self, FSystem.Printer); + FPrinterFrame.Parent := PrinterPanel; + FPrinterFrame.Align := alClient; + end else + PrinterPage.TabVisible := False; FDebuggerState := udsContinue; FSystem.Cpu.OnLog := DoLog; FDebugOS := True; @@ -361,6 +369,7 @@ var f, g: Byte; op: T494Opcode; j, k, b: String; + mnemonic: String; procedure DisAssemble; begin @@ -369,17 +378,38 @@ var if (f = $3f) then begin g := FSystem.Memory.Inst.g; - op := U494ExtOpcodes[g]; + case gConfig.Mode of + m494: + begin + op := U494ExtOpcodes[g]; + mnemonic := op.AsmMnemonic; + end; + m490: + begin + op := U494ExtOpcodes[g]; + mnemonic := op.SpurtMnemonic; + end; + m1230: + begin + op := U1230ExtOpcodes[g]; + mnemonic := op.SpurtMnemonic; + end; + end; WriteAudit(Format('%s/%s: %s %-10.10s %s%s', [Copy(FormatOctal(FSystem.Memory.RIR.Value), 5), Copy(FormatOctal(p - FSystem.Memory.RIR.Value), 5), FormatOctal(FSystem.Memory.Inst.Value), - op.AsmMnemonic, + mnemonic, Copy(FormatOctal(FSystem.Memory.Inst.y.Value15), 6), b])); end else begin op := U494StdOpcodes[f]; + case gConfig.Mode of + m494: mnemonic := op.AsmMnemonic; + m490: mnemonic := op.SpurtMnemonic; + m1230: mnemonic := op.SpurtMnemonic; + end; if (op.InstType = itRead) then k := kdesig_read[FSystem.Memory.Inst.k] else if (op.InstType = itStore) then @@ -401,7 +431,7 @@ var [Copy(FormatOctal(FSystem.Memory.RIR.Value), 5), Copy(FormatOctal(p - FSystem.Memory.RIR.Value), 5), FormatOctal(FSystem.Memory.Inst.Value), - op.AsmMnemonic + k, + mnemonic + k, j, Copy(FormatOctal(FSystem.Memory.Inst.y.Value15), 6), b])); @@ -415,7 +445,7 @@ var [Copy(FormatOctal(FSystem.Memory.RIR.Value), 5), Copy(FormatOctal(p - FSystem.Memory.RIR.Value), 5), FormatOctal(FSystem.Memory.Inst.Value), - op.AsmMnemonic + k, + mnemonic + k, Copy(FormatOctal(FSystem.Memory.Inst.y.Value15), 6), b, j])); diff --git a/U494/U494Printer.pas b/U494/U494Printer.pas index 52f0464..41fc12b 100644 --- a/U494/U494Printer.pas +++ b/U494/U494Printer.pas @@ -252,7 +252,7 @@ var word: T494Word; begin // Get the text to be printed and convert to ASCII. - bcr := FMemory.FetchBcr(BcrOut0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); i := 1; text := ''; while (FOutputActive and (i <= 132) and (bcr.Count > 0)) do @@ -265,7 +265,7 @@ begin text := text + AnsiChar(Chr(word.Value and $3f)); bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrOut0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrOut(FChannel), bcr, True); Inc(i, 5); end; text := TCodeTranslator.FieldataToAscii(text); diff --git a/U494/U494Reader.pas b/U494/U494Reader.pas index c4b3b46..7403bc8 100644 --- a/U494/U494Reader.pas +++ b/U494/U494Reader.pas @@ -346,7 +346,7 @@ var begin if (FReadStationLoaded) then begin - bcr := FMemory.FetchBcr(BcrIn0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrIn(FChannel), True); for r := 15 downto 4 do begin word.Value := 0; @@ -362,7 +362,7 @@ begin word := 0; bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); if (bcr.Count = 0) then Break; end; @@ -373,7 +373,7 @@ begin FMemory.Store(bcr.Address, word, True); bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); end; FInputActive := False; FFuncCode := 0; @@ -416,7 +416,7 @@ var bcr: T494Bcr; word: T494Word; begin - bcr := FMemory.FetchBcr(BcrIn0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrIn(FChannel), True); word := 0; count := 0; i := Low(bfr.Columns); @@ -431,7 +431,7 @@ begin count := 0; bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrIn0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrIn(FChannel), bcr, True); end; Inc(i); end; @@ -736,7 +736,7 @@ var begin for i := 1 to 80 do bfr.Columns[i] := Ord(TCodeTranslator.AsciiToFieldata(' ')); - bcr := FMemory.FetchBcr(BcrOut0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); i := Low(bfr.Columns); while (FOutputActive and (i <= 80) and (bcr.Count > 0)) do begin @@ -748,7 +748,7 @@ begin bfr.Columns[i + 4] := word.Value and $3f; bcr.Address := bcr.Address + 1; bcr.Count := bcr.Count - 1; - FMemory.StoreBcr(BcrOut0 + FChannel, bcr, True); + FMemory.StoreBcr(BcrOut(FChannel), bcr, True); Inc(i, 5); end; bfr.Count := 80; @@ -794,7 +794,7 @@ begin FOutputFile1.Merge(rawBfr, FPunchStation); FOutputActive := False; FFuncCode := 0; - bcr := FMemory.FetchBcr(BcrOut0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); if (FInputMonitor and (bcr.Count = 0)) then QueueInterrupt(intIO, IIsiOutput, 0); if (FWithExtInterrupt) then @@ -817,7 +817,7 @@ begin if (FPunchStationLoaded) then begin rawBfr.Clear; - bcr := FMemory.FetchBcr(BcrOut0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); r := 15; while (FOutputActive and (bcr.Count > 0) and (r >= 4)) do begin @@ -875,7 +875,7 @@ begin FOutputFile1.Merge(rawBfr, FPunchStation); FOutputActive := False; FFuncCode := 0; - bcr := FMemory.FetchBcr(BcrOut0 + FChannel, True); + bcr := FMemory.FetchBcr(BcrOut(FChannel), True); if (FInputMonitor and (bcr.Count = 0)) then QueueInterrupt(intIO, IIsiOutput, 0); if (FWithExtInterrupt) then diff --git a/U494/U494System.pas b/U494/U494System.pas index b725328..e2ec856 100644 --- a/U494/U494System.pas +++ b/U494/U494System.pas @@ -5,7 +5,7 @@ interface uses Windows, SysUtils, Classes, U494Memory, U494Cpu, U494Interrupts, U494Reader, U494Printer; type - T494RTClock = class(TThread) + TRTClock = class(TThread) private FCpu: T494Cpu; FMemory: T494Memory; @@ -14,6 +14,21 @@ type procedure Execute; override; end; + T1230RTClock = class(TRTClock) + public + procedure Execute; override; + end; + + T490RTClock = class(TRTClock) + public + procedure Execute; override; + end; + + T494RTClock = class(TRTClock) + public + procedure Execute; override; + end; + T494DayClock = class(TThread) private FCpu: T494Cpu; @@ -27,7 +42,7 @@ type private FCpu: T494Cpu; FMemory: T494Memory; - FRTClock: T494RTClock; + FRTClock: TRTClock; FDayClock: T494DayClock; function GetReader: T494Reader; function GetPunch: T494Punch; @@ -52,21 +67,41 @@ constructor T494System.Create; var dev: T494Device; fname: String; + i: Integer; + drum: T494Drum; begin inherited; FMemory := T494Memory.Create; FCpu := T494Cpu.Create(Fmemory); - FCpu.Channels[0] := T494ConsDevice.Create(FCpu, FMemory, 0); - FCpu.Channels[1] := T494ReaderPunch.Create(FCpu, FMemory, 1); - FCpu.Channels[2] := T494Printer.Create(FCpu, FMemory, 2); - FCpu.Channels[5] := TFH880Device.Create(FCpu, FMemory, 5); - fname := PublicDataDir + '\Univac 494 Emulator\Data\SYSVOL.drum'; - if (FileExists(fname)) then - TFH880Device(FCpu.Channels[5]).DrumFile := fname - else - TFH880Device(FCpu.Channels[5]).DrumFile := '..\..\Drums\SYSVOL.drum'; - FRTClock := T494RTClock.Create(FCpu, FMemory); - FRTClock.Start; + case gConfig.ConsoleType of + ct1232: FCpu.Channels[gConfig.ConsoleChan] := T494ConsDevice.Create(FCpu, FMemory, gConfig.ConsoleChan); + end; + if (gConfig.RdrPunChan <> -1) then + FCpu.Channels[gConfig.RdrPunChan] := T494ReaderPunch.Create(FCpu, FMemory, gConfig.RdrPunChan); + if (gConfig.PrinterChan <> -1) then + FCpu.Channels[gConfig.PrinterChan] := T494Printer.Create(FCpu, FMemory, gConfig.PrinterChan); + for i := 0 to gConfig.DrumCount - 1 do + begin + drum := gConfig.Drums[i]; + case drum.DrumType of + dtFH880: FCpu.Channels[drum.Chan] := TFH880Device.Create(FCpu, FMemory, drum.Chan); + end; + if (Assigned(FCpu.Channels[drum.Chan])) then + begin + fname := PublicDataDir + '\Univac 494 Emulator\Data\SYSVOL.drum'; + if (FileExists(fname)) then + TFH880Device(FCpu.Channels[drum.Chan]).DrumFile := fname + else + TFH880Device(FCpu.Channels[drum.Chan]).DrumFile := '..\..\Drums\SYSVOL.drum'; + end; + end; + case gConfig.Mode of + m494: FRTClock := T494RTClock.Create(FCpu, FMemory); + m490: FRTClock := T490RTClock.Create(FCpu, FMemory); + m1230: FRTClock := T1230RTClock.Create(FCpu, FMemory); + end; + if (Assigned(FRTClock)) then + FRTClock.Start; if ((gConfig.Mode = m494) or (gConfig.Mode = m490)) then begin FDayCLock := T494DayClock.Create(FCpu, FMemory); @@ -121,30 +156,27 @@ end; function T494System.GetPunch: T494Punch; begin - Result := T494ReaderPunch(FCpu.Channels[1]).Punch; + Result := nil; + if (gConfig.RdrPunChan <> -1) then + Result := T494ReaderPunch(FCpu.Channels[gConfig.RdrPunChan]).Punch; end; function T494System.GetReader: T494Reader; begin - Result := T494ReaderPunch(FCpu.Channels[1]).Reader; + Result := nil; + if (gConfig.RdrPunChan <> -1) then + Result := T494ReaderPunch(FCpu.Channels[gConfig.RdrPunChan]).Reader; end; { T494DayClock } -constructor T494RTClock.Create(cpu: T494Cpu; mem: T494Memory); -begin - inherited Create(True); - FCpu := cpu; - FMemory := mem; -end; - procedure T494RTClock.Execute; // The real time clock is supposed to fire every 200 microseconds. The // only way to accomplish this under Windows is to spin on QueryPerformanceCounter. // This uses excessive amounts of CPU time. Since 200 ms resolution is likely not // going to be required for the emulator, we use Sleep(1) which gives us about // 2 millisecond resolution. We capture the interval to the nearest multiple -// of 200 microseconds (1 millisecond for 490 mode) and update the real time clock counter accordingly. +// of 200 microseconds and update the real time clock counter accordingly. var timerFreq, intervalStart, intervalEnd, ms200: Int64; word: T494Word; @@ -163,7 +195,7 @@ begin origWord := word.Value; QueryPerformanceCounter(intervalEnd); ms200 := Round(((intervalEnd - intervalStart) / timerFreq) * 5000); - if ((gConfig.Mode = m494) and (ms200 > 0)) then + if (ms200 > 0) then begin QueryPerformanceCounter(intervalStart); word.Value := (word.Value + ms200) and $3ffff; @@ -175,22 +207,6 @@ begin int.Vector := IRTClock; FCpu.Interrupts.Enqueue(int); end; - end else if ((gConfig.Mode = m490) and (ms200 > 4)) then - begin - QueryPerformanceCounter(intervalStart); - word.Value := (word.Value + (ms200 div 5)) and BITS15; - FMemory.Store(RTClock, word, True); - if (word.Value < origWord) then - begin - int.IType := intClock; - int.Vector := IRTClock; - FCpu.Interrupts.Enqueue(int); - end; - end else if ((gConfig.Mode = m1230) and (ms200 > 4)) then - begin - QueryPerformanceCounter(intervalStart); - word.Value := (word.Value + (ms200 div 5)) and BITS15; - FMemory.Store(RTClock1230, word, True); end; end; end; @@ -236,4 +252,95 @@ begin end; end; +{ TGenericRTClock } + +constructor TRTClock.Create(cpu: T494Cpu; mem: T494Memory); +begin + inherited Create(True); + FCpu := cpu; + FMemory := mem; +end; + +procedure TRTClock.Execute; +begin + while (not Terminated) do + Sleep(100); +end; + +{ T1230RTClock } + +procedure T1230RTClock.Execute; +// The real time clock is supposed to fire every 200 microseconds. The +// only way to accomplish this under Windows is to spin on QueryPerformanceCounter. +// This uses excessive amounts of CPU time. Since 200 ms resolution is likely not +// going to be required for the emulator, we use Sleep(1) which gives us about +// 2 millisecond resolution. We capture the interval to the nearest multiple +// of 1 millisecond and update the real time clock counter accordingly. +var + timerFreq, intervalStart, intervalEnd, ms200: Int64; + word: T494Word; +begin + QueryPerformanceFrequency(timerFreq); + QueryPerformanceCounter(intervalStart); + while (not Terminated) do + begin + Sleep(1); + if (gConfig.Mode = m1230) then + word := FMemory.Fetch(RTClock1230, True) + else + word := FMemory.Fetch(RTClock, True); + QueryPerformanceCounter(intervalEnd); + ms200 := Round(((intervalEnd - intervalStart) / timerFreq) * 5000); + if (ms200 > 4) then + begin + QueryPerformanceCounter(intervalStart); + word.Value := (word.Value + ms200) and $3ffff; + FMemory.Store(RTClock1230, word, True); + end; + end; +end; + +{ T490RTClock } + +procedure T490RTClock.Execute; +// The real time clock is supposed to fire every 200 microseconds. The +// only way to accomplish this under Windows is to spin on QueryPerformanceCounter. +// This uses excessive amounts of CPU time. Since 200 ms resolution is likely not +// going to be required for the emulator, we use Sleep(1) which gives us about +// 1 millisecond resolution. We capture the interval to the nearest multiple +// of 1 millisecond and update the real time clock counter accordingly. +var + timerFreq, intervalStart, intervalEnd, ms200: Int64; + word: T494Word; + origWord: UInt32; + int: T494Interrupt; +begin + QueryPerformanceFrequency(timerFreq); + QueryPerformanceCounter(intervalStart); + while (not Terminated) do + begin + Sleep(1); + if (gConfig.Mode = m1230) then + word := FMemory.Fetch(RTClock1230, True) + else + word := FMemory.Fetch(RTClock, True); + origWord := word.Value; + QueryPerformanceCounter(intervalEnd); + ms200 := Round(((intervalEnd - intervalStart) / timerFreq) * 5000); + if (ms200 > 4) then + begin + QueryPerformanceCounter(intervalStart); + word.Value := (word.Value + ms200) and $3ffff; + FMemory.Store(RTClock, word, True); + // Queue an interrupt if the counter wraps. + if (word.Value < origWord) then + begin + int.IType := intClock; + int.Vector := IRTClock; + FCpu.Interrupts.Enqueue(int); + end; + end; + end; +end; + end. diff --git a/U494/U494Util.pas b/U494/U494Util.pas index 3e76a06..91a48bf 100644 --- a/U494/U494Util.pas +++ b/U494/U494Util.pas @@ -8,6 +8,10 @@ type T494Mode = ( m494, m490, m1230 ); + T494ConsoleType = ( ct1232 ); + + T494DrumType = (dtFH880 ); + EMemoryException = class(Exception); EIllegalInstruction = class(Exception); EProgramProtection = class(Exception);