1
0
mirror of https://github.com/open-simh/simh.git synced 2026-02-28 17:29:55 +00:00
Files
open-simh.simh/simh.doc
Bob Supnik 654937fc88 simh v2.7
2011-04-15 08:33:36 -07:00

974 lines
110 KiB
Plaintext

{\rtf1\ansi\ansicpg1252\uc1 \deff0\deflang1033\deflangfe1033{\fonttbl{\f0\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f1\fswiss\fcharset0\fprq2{\*\panose 020b0604020202020204}Arial;}
{\f2\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}{\f3\froman\fcharset2\fprq2{\*\panose 05050102010706020507}Symbol;}{\f4\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Times;}
{\f5\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helvetica;}{\f6\fmodern\fcharset0\fprq1{\*\panose 00000000000000000000}Courier;}{\f7\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Geneva;}
{\f8\froman\fcharset0\fprq2{\*\panose 00000000000000000000}Tms Rmn;}{\f9\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}Helv;}{\f10\froman\fcharset0\fprq2{\*\panose 00000000000000000000}MS Serif;}
{\f11\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}MS Sans Serif;}{\f12\froman\fcharset0\fprq2{\*\panose 00000000000000000000}New York;}{\f13\fswiss\fcharset0\fprq2{\*\panose 00000000000000000000}System;}
{\f14\fnil\fcharset2\fprq2{\*\panose 05000000000000000000}Wingdings;}{\f15\fswiss\fcharset0\fprq2{\*\panose 020b0604030504040204}Tahoma;}{\f16\froman\fcharset177\fprq2{\*\panose 00000000000000000000}Times New Roman (Hebrew);}
{\f17\froman\fcharset178\fprq2{\*\panose 00000000000000000000}Times New Roman (Arabic);}{\f18\fswiss\fcharset177\fprq2{\*\panose 00000000000000000000}Arial (Hebrew);}{\f19\fswiss\fcharset178\fprq2{\*\panose 00000000000000000000}Arial (Arabic);}
{\f20\fmodern\fcharset177\fprq1{\*\panose 00000000000000000000}Courier New (Hebrew);}{\f21\fmodern\fcharset178\fprq1{\*\panose 00000000000000000000}Courier New (Arabic);}{\f22\fswiss\fcharset177\fprq2{\*\panose 00000000000000000000}Tahoma (Hebrew);}
{\f23\fswiss\fcharset178\fprq2{\*\panose 00000000000000000000}Tahoma (Arabic);}{\f24\froman\fcharset238\fprq2 Times New Roman CE;}{\f25\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f27\froman\fcharset161\fprq2 Times New Roman Greek;}
{\f28\froman\fcharset162\fprq2 Times New Roman Tur;}{\f29\froman\fcharset186\fprq2 Times New Roman Baltic;}{\f30\fswiss\fcharset238\fprq2 Arial CE;}{\f31\fswiss\fcharset204\fprq2 Arial Cyr;}{\f33\fswiss\fcharset161\fprq2 Arial Greek;}
{\f34\fswiss\fcharset162\fprq2 Arial Tur;}{\f35\fswiss\fcharset186\fprq2 Arial Baltic;}{\f36\fmodern\fcharset238\fprq1 Courier New CE;}{\f37\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f39\fmodern\fcharset161\fprq1 Courier New Greek;}
{\f40\fmodern\fcharset162\fprq1 Courier New Tur;}{\f41\fmodern\fcharset186\fprq1 Courier New Baltic;}{\f114\fswiss\fcharset238\fprq2 Tahoma CE;}{\f115\fswiss\fcharset204\fprq2 Tahoma Cyr;}{\f117\fswiss\fcharset161\fprq2 Tahoma Greek;}
{\f118\fswiss\fcharset162\fprq2 Tahoma Tur;}{\f119\fswiss\fcharset186\fprq2 Tahoma Baltic;}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;
\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\widctlpar\adjustright
\fs20\cgrid \snext0 Normal;}{\s1\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360\ls1\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid \sbasedon0 \snext0 heading 1;}{\s2\fi-390\li390\sb240\sa60\keepn\widctlpar
\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid \sbasedon0 \snext0 heading 2;}{\s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid \sbasedon0 \snext0 heading 3;}{\*\cs10 \additive
Default Paragraph Font;}{\*\cs15 \additive \b \sbasedon10 Strong;}{\s16\widctlpar\adjustright \b\f1\fs20\cgrid \sbasedon0 \snext16 Body Text;}{\s17\li720\widctlpar\adjustright \f1\fs20\cgrid \sbasedon0 \snext17 Body Text 2;}{
\s18\sb120\widctlpar\adjustright \b\i\cgrid \sbasedon0 \snext0 \sautoupd toc 1;}{\s19\li200\sb120\widctlpar\adjustright \b\fs22\cgrid \sbasedon0 \snext0 \sautoupd toc 2;}{\s20\li400\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 3;}{
\s21\li600\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 4;}{\s22\li800\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 5;}{\s23\li1000\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 6;}{
\s24\li1200\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 7;}{\s25\li1400\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 8;}{\s26\li1600\widctlpar\adjustright \fs20\cgrid \sbasedon0 \snext0 \sautoupd toc 9;}{
\s27\widctlpar\adjustright \cbpat9 \f15\fs20\cgrid \sbasedon0 \snext27 Document Map;}}{\*\listtable{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname ;}\listid22442644}{\list\listtemplateid1593215596{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext
\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\jclisttab\tx1440 }{\listlevel
\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li2160\jclisttab\tx2160 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0
{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\jclisttab\tx2880 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\jclisttab\tx3600 }
{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li4320\jclisttab\tx4320 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360
\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040\jclisttab\tx5040 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760
\jclisttab\tx5760 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li6480\jclisttab\tx6480 }{\listname ;}\listid56512481}{\list\listtemplateid-332364684
{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'02\'00.;}{\levelnumbers\'01;}\fbias0 \s1\fi-360\li360\jclisttab\tx360 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0
\levelindent0{\leveltext\'03\'00.\'01;}{\levelnumbers\'01\'03;}\fbias0 \s2\fi-390\li390\jclisttab\tx390 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'05\'00.\'01.\'02;}{\levelnumbers
\'01\'03\'05;}\fbias0 \s3\fi-720\li720\jclisttab\tx720 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'07\'00.\'01.\'02.\'03;}{\levelnumbers\'01\'03\'05\'07;}\fbias0 \fi-1080\li1080
\jclisttab\tx1080 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'09\'00.\'01.\'02.\'03.\'04;}{\levelnumbers\'01\'03\'05\'07\'09;}\fbias0 \fi-1080\li1080\jclisttab\tx1080 }{\listlevel\levelnfc0
\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'0b\'00.\'01.\'02.\'03.\'04.\'05;}{\levelnumbers\'01\'03\'05\'07\'09\'0b;}\fbias0 \fi-1440\li1440\jclisttab\tx1440 }{\listlevel\levelnfc0\leveljc0\levelfollow0
\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'0d\'00.\'01.\'02.\'03.\'04.\'05.\'06;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\fbias0 \fi-1440\li1440\jclisttab\tx1440 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal
\levelspace0\levelindent0{\leveltext\'0f\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\fbias0 \fi-1800\li1800\jclisttab\tx1800 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0
\levelindent0{\leveltext\'11\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\fbias0 \fi-1800\li1800\jclisttab\tx1800 }{\listname ;}\listid155609463}{\list\listtemplateid1706078190\listsimple{\listlevel
\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname ;}\listid602111040}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23
\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname ;}\listid621424954}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0
\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname ;}\listid717362522}{\list\listtemplateid67698689\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0
\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listname ;}\listid1064328194}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1
\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname ;}\listid1080104542}{\list\listtemplateid-5054418{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat2\levelspace0\levelindent0
{\leveltext\'01\'00;}{\levelnumbers\'01;}\fbias0 \fi-435\li435\jclisttab\tx435 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'03\'00.\'01;}{\levelnumbers\'01\'03;}\fbias0 \fi-435\li435\jclisttab\tx435 }
{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat2\levelspace0\levelindent0{\leveltext\'05\'00.\'01.\'02;}{\levelnumbers\'01\'03\'05;}\fbias0 \fi-720\li720\jclisttab\tx720 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0
\levelindent0{\leveltext\'07\'00.\'01.\'02.\'03;}{\levelnumbers\'01\'03\'05\'07;}\fbias0 \fi-720\li720\jclisttab\tx720 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext
\'09\'00.\'01.\'02.\'03.\'04;}{\levelnumbers\'01\'03\'05\'07\'09;}\fbias0 \fi-1080\li1080\jclisttab\tx1080 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0b\'00.\'01.\'02.\'03.\'04.\'05;}{\levelnumbers
\'01\'03\'05\'07\'09\'0b;}\fbias0 \fi-1080\li1080\jclisttab\tx1080 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0d\'00.\'01.\'02.\'03.\'04.\'05.\'06;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\fbias0
\fi-1440\li1440\jclisttab\tx1440 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'0f\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\fbias0 \fi-1440\li1440
\jclisttab\tx1440 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'11\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\fbias0 \fi-1800\li1800\jclisttab\tx1800
}{\listname ;}\listid1262834005}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname
;}\listid1272592440}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname
;}\listid1339387548}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname
;}\listid1409111490}{\list\listtemplateid1666980492{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listlevel\levelnfc23\leveljc0
\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\jclisttab\tx1440 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext
\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li2160\jclisttab\tx2160 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\jclisttab\tx2880 }
{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\jclisttab\tx3600 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0
{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li4320\jclisttab\tx4320 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040
\jclisttab\tx5040 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\jclisttab\tx5760 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360
\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li6480\jclisttab\tx6480 }{\listname ;}\listid1484007768}{\list\listtemplateid230209238{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat3\levelspace0\levelindent0{\leveltext
\'02\'00.;}{\levelnumbers\'01;}\fbias0 \fi-360\li360\jclisttab\tx360 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'03\'00.\'01;}{\levelnumbers\'01\'03;}\fbias0 \fi-360\li360\jclisttab\tx360 }
{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext\'05\'00.\'01.\'02;}{\levelnumbers\'01\'03\'05;}\fbias0 \fi-720\li720\jclisttab\tx720 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1
\levellegal\levelspace0\levelindent0{\leveltext\'07\'00.\'01.\'02.\'03;}{\levelnumbers\'01\'03\'05\'07;}\fbias0 \fi-720\li720\jclisttab\tx720 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext
\'09\'00.\'01.\'02.\'03.\'04;}{\levelnumbers\'01\'03\'05\'07\'09;}\fbias0 \fi-720\li720\jclisttab\tx720 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext
\'0b\'00.\'01.\'02.\'03.\'04.\'05;}{\levelnumbers\'01\'03\'05\'07\'09\'0b;}\fbias0 \fi-1080\li1080\jclisttab\tx1080 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext
\'0d\'00.\'01.\'02.\'03.\'04.\'05.\'06;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d;}\fbias0 \fi-1080\li1080\jclisttab\tx1080 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext
\'0f\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f;}\fbias0 \fi-1440\li1440\jclisttab\tx1440 }{\listlevel\levelnfc0\leveljc0\levelfollow0\levelstartat1\levellegal\levelspace0\levelindent0{\leveltext
\'11\'00.\'01.\'02.\'03.\'04.\'05.\'06.\'07.\'08;}{\levelnumbers\'01\'03\'05\'07\'09\'0b\'0d\'0f\'11;}\fbias0 \fi-1440\li1440\jclisttab\tx1440 }{\listname ;}\listid1502426668}{\list\listtemplateid355235766{\listlevel\levelnfc23\leveljc0\levelfollow0
\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li360\jclisttab\tx360 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0
\fi-360\li1080\jclisttab\tx1080 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li1800\jclisttab\tx1800 }{\listlevel\levelnfc23\leveljc0\levelfollow0
\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2520\jclisttab\tx2520 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}
\f2\fbias0 \fi-360\li3240\jclisttab\tx3240 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li3960\jclisttab\tx3960 }{\listlevel\levelnfc23\leveljc0
\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li4680\jclisttab\tx4680 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext
\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5400\jclisttab\tx5400 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li6120\jclisttab\tx6120 }{\listname
;}\listid1523011899}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname
;}\listid1645162521}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname
;}\listid2006126440}{\list\listtemplateid1706078190\listsimple{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace0\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li720\jclisttab\tx720 }{\listname
;}\listid2076124660}{\list\listtemplateid1666980492{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li720\jclisttab\tx720 }{\listlevel\levelnfc23\leveljc0
\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li1440\jclisttab\tx1440 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext
\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li2160\jclisttab\tx2160 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li2880\jclisttab\tx2880 }
{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li3600\jclisttab\tx3600 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0
{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li4320\jclisttab\tx4320 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01\u-3913 ?;}{\levelnumbers;}\f3\fbias0 \fi-360\li5040
\jclisttab\tx5040 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360\levelindent0{\leveltext\'01o;}{\levelnumbers;}\f2\fbias0 \fi-360\li5760\jclisttab\tx5760 }{\listlevel\levelnfc23\leveljc0\levelfollow0\levelstartat1\levelspace360
\levelindent0{\leveltext\'01\u-3929 ?;}{\levelnumbers;}\f14\fbias0 \fi-360\li6480\jclisttab\tx6480 }{\listname ;}\listid2112620548}}{\*\listoverridetable{\listoverride\listid155609463\listoverridecount0\ls1}{\listoverride\listid1409111490
\listoverridecount0\ls2}{\listoverride\listid1272592440\listoverridecount0\ls3}{\listoverride\listid2076124660\listoverridecount0\ls4}{\listoverride\listid717362522\listoverridecount0\ls5}{\listoverride\listid1339387548\listoverridecount0\ls6}
{\listoverride\listid621424954\listoverridecount0\ls7}{\listoverride\listid1080104542\listoverridecount0\ls8}{\listoverride\listid1262834005\listoverridecount0\ls9}{\listoverride\listid2006126440\listoverridecount0\ls10}{\listoverride\listid602111040
\listoverridecount0\ls11}{\listoverride\listid22442644\listoverridecount0\ls12}{\listoverride\listid1502426668\listoverridecount0\ls13}{\listoverride\listid1645162521\listoverridecount0\ls14}{\listoverride\listid1064328194\listoverridecount0\ls15}
{\listoverride\listid2112620548\listoverridecount0\ls16}{\listoverride\listid1484007768\listoverridecount0\ls17}{\listoverride\listid1523011899\listoverridecount0\ls18}{\listoverride\listid56512481\listoverridecount0\ls19}}{\info
{\title Writing a Simulator for the SIMH System}{\author Bob Supnik}{\operator Bob Supnik}{\creatim\yr1997\mo8\dy30\hr19}{\revtim\yr2001\mo10\dy20\hr10\min58}{\version29}{\edmins519}{\nofpages19}{\nofwords6533}{\nofchars-32766}
{\*\company Digital Equipment Corporation}{\nofcharsws0}{\vern113}}\widowctrl\ftnbj\aenddoc\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\hyphcaps0\formshade\viewkind4\viewscale100\pgbrdrhead\pgbrdrfoot \fet0\sectd
\linex0\endnhere\sectdefaultcl {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl4
\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}
{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain \widctlpar\outlinelevel0\adjustright \fs20\cgrid {\f1
Writing a Simulator for the SIMH System
\par }\pard \widctlpar\adjustright {\f1 Revised 20-Oct-01 for V2.7-14
\par
\par }\pard\plain \s18\sb120\widctlpar\tx400\tqr\tldot\tx8630\adjustright \b\i\cgrid {\field\fldedit{\*\fldinst {\f1 TOC \\o }}{\fldrslt {\lang1024 1.\tab Overview\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228037 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f0063003500320036003200320038003000330037000000000000001e006f}}}{\fldrslt {\lang1024 1}}}{\lang1024
\par 2.\tab Data Types\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228038 \\h }{\fs20\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300033003800000000016f00000000}}}{\fldrslt {
\lang1024 2}}}{\lang1024
\par 3.\tab VM Organization\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228039 \\h }{\fs20\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300033003900000000010000001e00}}
}{\fldrslt {\lang1024 2}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 3.1\tab CPU Organization\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228040 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300034003000000000020100000004}}}{\fldrslt {\lang1024 3}}}{\lang1024
\par }\pard\plain \s20\li400\widctlpar\tx1200\tqr\tldot\tx8630\adjustright \fs20\cgrid {\lang1024 3.1.1\tab Time Base\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228041 \\h }{\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300034003100000000001e0000001e}}}{\fldrslt {\lang1024 4}}}{\lang1024
\par 3.1.2\tab Memory Organization\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228042 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300034003200000000000000006f00}}
}{\fldrslt {\lang1024 4}}}{\lang1024
\par 3.1.3\tab Interrupt Organization\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228043 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f00630035003200360032003200380030003400330000000001fe00000000}}
}{\fldrslt {\lang1024 4}}}{\lang1024
\par 3.1.4\tab I/O Dispatching\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228044 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300034003400000000000000eb0280}}}{\fldrslt
{\lang1024 5}}}{\lang1024
\par 3.1.5\tab Instruction Execution\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228045 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f0063003500320036003200320038003000340035000000000080000201ff}}
}{\fldrslt {\lang1024 5}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 3.2\tab Peripheral Device Organization\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228046 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300034003600000000640100006401}}}{\fldrslt {\lang1024 6}}}{\lang1024
\par }\pard\plain \s20\li400\widctlpar\tx1200\tqr\tldot\tx8630\adjustright \fs20\cgrid {\lang1024 3.2.1\tab Device Timing\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228047 \\h }{\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f00630035003200360032003200380030003400370000000000000001fe00}}}{\fldrslt {\lang1024 7}}}{\lang1024
\par 3.2.2\tab Clock Calibration\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228048 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f0063003500320036003200320038003000340038000000000000008002e2}}
}{\fldrslt {\lang1024 8}}}{\lang1024
\par 3.2.3\tab Data I/O\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228049 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300034003900000000000000000000}}}{\fldrslt {
\lang1024 9}}}{\lang1024
\par }\pard\plain \s18\sb120\widctlpar\tx400\tqr\tldot\tx8630\adjustright \b\i\cgrid {\lang1024 4.\tab Data Structures\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228050 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003000000000000000000000}}}{\fldrslt {\lang1024 10}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 4.1\tab device Structure\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228051 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003100000000000000000000}}}{\fldrslt {\lang1024 10}}}{\lang1024
\par }\pard\plain \s20\li400\widctlpar\tx1200\tqr\tldot\tx8630\adjustright \fs20\cgrid {\lang1024 4.1.1\tab Examine and Deposit Routines\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228052 \\h }{\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003200000000000000000000}}}{\fldrslt {\lang1024 11}}}{\lang1024
\par 4.1.2\tab Reset Routine\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228053 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003300000000000000000000}}}{\fldrslt {
\lang1024 11}}}{\lang1024
\par 4.1.3\tab Boot Routine\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228054 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003400000000000000000000}}}{\fldrslt {
\lang1024 11}}}{\lang1024
\par 4.1.4\tab Attach and Detach Routines\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228055 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003500000000000000000000}}
}{\fldrslt {\lang1024 11}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 4.2\tab unit Structure\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228056 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003600000000000000000000}}}{\fldrslt {\lang1024 12}}}{\lang1024
\par }\pard\plain \s20\li400\widctlpar\tx1200\tqr\tldot\tx8630\adjustright \fs20\cgrid {\lang1024 4.2.1\tab Unit Flags\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228057 \\h }{\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003700000000000000000000}}}{\fldrslt {\lang1024 13}}}{\lang1024
\par 4.2.2\tab Service Routine\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228058 \\h }{\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003800000000000000000000}}}{\fldrslt
{\lang1024 13}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 4.3\tab reg Structure\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228059 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300035003900000000000000000000}}}{\fldrslt {\lang1024 13}}}{\lang1024
\par }\pard\plain \s20\li400\widctlpar\tx1200\tqr\tldot\tx8630\adjustright \fs20\cgrid {\lang1024 4.3.1\tab Register Flags\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228060 \\h }{\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003000000000000000000000}}}{\fldrslt {\lang1024 14}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 4.4\tab mtab Structure\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228061 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003100000000000000000000}}}{\fldrslt {\lang1024 15}}}{\lang1024
\par }\pard\plain \s20\li400\widctlpar\tx1200\tqr\tldot\tx8630\adjustright \fs20\cgrid {\lang1024 4.4.1\tab Validation/Display Routine\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228062 \\h }{\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003200000000000000000000}}}{\fldrslt {\lang1024 15}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 4.5\tab Other Data Structures\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228063 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003300000000000000000000}}}{\fldrslt {\lang1024 15}}}{\lang1024
\par }\pard\plain \s18\sb120\widctlpar\tx400\tqr\tldot\tx8630\adjustright \b\i\cgrid {\lang1024 5.\tab VM Provided Routines\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228064 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003400000000000000000000}}}{\fldrslt {\lang1024 16}}}{\lang1024
\par }\pard\plain \s19\li200\sb120\widctlpar\tx800\tqr\tldot\tx8630\adjustright \b\fs22\cgrid {\lang1024 5.1\tab Instruction Execution\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228065 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003500000000000000000000}}}{\fldrslt {\lang1024 16}}}{\lang1024
\par 5.2\tab Binary Load and Dump\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228066 \\h }{\fs20\lang1024 {\*\datafield 08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003600000000000000000000}}
}{\fldrslt {\lang1024 16}}}{\lang1024
\par 5.3\tab Symbolic Examination and Deposit\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228067 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003700000000000000000000}}}{\fldrslt {\lang1024 16}}}{\lang1024
\par 5.4\tab Multi-Terminal Support (Telnet)\tab }{\field{\*\fldinst {\lang1024 PAGEREF _Toc526228068 \\h }{\fs20\lang1024 {\*\datafield
08d0c9ea79f9bace118c8200aa004ba90b02000000080000000e0000005f0054006f006300350032003600320032003800300036003800000000000000000000}}}{\fldrslt {\lang1024 17}}}{\lang1024
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid }}\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par {\*\bkmkstart _Toc526228037}{\listtext\pard\plain\s1 \b\f1\fs28\kerning28\cgrid \hich\af1\dbch\af0\loch\f1 1.\tab}}\pard\plain \s1\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360\ls1\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {Overview
{\*\bkmkend _Toc526228037}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par SIMH (history simulators) is a set of portab
le programs, written in C, which simulate various historically interesting computers. This document describes how to design, write, and check out a new simulator for SIMH. It is not an introduction to either the philosophy or external operation of SIMH,
and the reader should be familiar with both of those topics before proceeding. Nor is it a guide to the internal design or operation of SIMH, except insofar as those areas interact with simulator design. Instead, this manual presents and explains the fo
r
m, meaning, and operation of the interfaces between simulators and the SIMH simulator control package. It also offers some suggestions for utilizing the services SIMH offers and explains the constraints that all simulators operating within SIMH will expe
rience.
\par
\par Some terminology: Each simulator consists of a standard }{\i\f1 simulator control package}{\f1 (SCP), which provides a control framework and utility routines for a simulator; and a unique }{\i\f1 virtual machine}{\f1
(VM), which implements the simulated processor and selected peripherals. A VM consists of multiple }{\i\f1 devices}{\f1 , such as the CPU, paper tape reader, disk controller, etc. Each controller consists of a named state space (called }{\i\f1
registers}{\f1 ) and one or more }{\i\f1 units}{\f1 . Each unit consists of a numbered state space (called a }{\i\f1 data set}{\f1 ). }{\i\f1 }{\f1 The }{\i\f1 host computer}{\f1 is the system on which SIMH runs; the }{\i\f1 target computer}{\f1
is the system being simulated.
\par
\par SIMH is unabashedly based on the MIMIC simulation system, designed in the late 1960\rquote s by Len Fehskens, Mike McCarthy, and Bob Supnik. This document is based on MIMIC\rquote s published interface specification, \ldblquote
How to Write a Virtual Machine for the MIMIC Simulation System\rdblquote , by Len Fehskens and Bob Supnik.
\par
\par {\*\bkmkstart _Toc526228038}{\listtext\pard\plain\s1 \b\f1\fs28\kerning28\cgrid \hich\af1\dbch\af0\loch\f1 2.\tab}}\pard\plain \s1\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360\ls1\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {Data Types
{\*\bkmkend _Toc526228038}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par SIMH is written in C. The host system must support (at least) 32-bit data types (64-bit data types for the PDP-10 and other large-word target systems). To cope with the vagaries of C data types, SIMH defines some unambiguous data types for its inter
faces:
\par
\par \tab SIMH data type\tab \tab \tab interpretation in typical 32-bit C
\par
\par \tab int8, uint8\tab \tab \tab char, unsigned char
\par \tab int16, uint16\tab \tab \tab short, unsigned short
\par \tab int32, uint32\tab \tab \tab int, unsigned int
\par \tab t_int64, t_uint64\tab \tab \tab long long, _int64 (system specific)
\par \tab t_addr\tab \tab \tab \tab simulated address, int32
\par \tab t_value\tab \tab \tab \tab simulated value, unsigned int32 or int64
\par \tab t_svalue\tab \tab \tab simulated signed value, int32 or int64
\par \tab t_mtrec\tab \tab \tab \tab mag tape record length, int32
\par \tab t_stat\tab \tab \tab \tab status code, int
\par \tab t_bool\tab \tab \tab \tab true/false value, int
\par
\par [The inconsistency in naming t_int64 and t_uint64 is due to VC++, which uses int64 as a structure name member in the master Windows definitions file.]
\par
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 In addition, SIMH defines structures for each of its major data elements
\par }\pard \widctlpar\adjustright {\f1
\par \tab }{\b\f1 DEVICE}{\f1 \tab \tab \tab device definition structure
\par \tab }{\b\f1 UNIT}{\f1 \tab \tab \tab \tab unit definition structure
\par \tab }{\b\f1 REG}{\f1 \tab \tab \tab \tab register definition structure
\par \tab }{\b\f1 MTAB}{\f1 \tab \tab \tab \tab modifier definition structure
\par
\par {\*\bkmkstart _Toc526228039}{\listtext\pard\plain\s1 \b\f1\fs28\kerning28\cgrid \hich\af1\dbch\af0\loch\f1 3.\tab}}\pard\plain \s1\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360\ls1\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {
VM Organization{\*\bkmkend _Toc526228039}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par A virtual machine (VM) is a collection of devices bound together through their internal logic. Each device is named and corresponds more or less to a hunk of hardware on the real machine; for example:
\par
\par \tab VM device\tab \tab \tab Real machine hardware
\par
\par \tab CPU\tab \tab \tab \tab central processor and main memory
\par \tab PTR\tab \tab \tab \tab paper tape reader controller and paper tape reader
\par \tab TTI\tab \tab \tab \tab console keyboard
\par \tab TTO\tab \tab \tab \tab console output
\par \tab DKP\tab \tab \tab \tab disk pack controller and drives
\par
\par There may be more than one device per physical hardware entity, as for the console; but for each user-accessible device there
must be at least one. One of these devices will have the pre-eminent responsibility for directing simulated operations. Normally, this is the CPU, but it could be a higher-level entity, such as a bus master.
\par
\par The VM actually runs as a subroutine of the simulator control package (SCP). It provides a master routine for running simulated programs and other routines and data structures to implement SCP\rquote
s command and control functions. The interfaces between a VM and SCP are relatively few:
\par
\par \tab Interface\tab \tab \tab Function
\par
\par \tab char }{\b\f1 sim_name[]}{\f1 \tab \tab simulator name string
\par \tab REG *}{\b\f1 sim_pc}{\f1 \tab \tab \tab pointer to simulated program counter
\par \tab int32 }{\b\f1 sim_emax}{\f1 \tab \tab maximum number of words in an instruction
\par \tab DEVICE *}{\b\f1 sim_devices[]}{\f1 \tab table of pointers to simulated devices, NULL terminated
\par \tab UNIT }{\b\f1 *sim_consoles[]}{\f1 \tab \tab table of pointers to simulated consoles
\par \tab char *}{\b\f1 sim_stop_messages[]}{\f1 \tab table of pointers to error messages
\par \tab t_stat }{\b\f1 sim_load}{\f1 (\'85)\tab \tab binary loader subroutine
\par \tab t_stat }{\b\f1 sim_inst}{\f1 (void)\tab \tab instruction execution subroutine
\par \tab t_stat }{\b\f1 parse_sym}{\f1 (\'85)\tab \tab symbolic instruction parse subroutine (optional)
\par \tab t_stat }{\b\f1 fprint_sym}{\f1 (\'85)\tab \tab symbolic instruction print subroutine (optional)
\par
\par There is no required organization for VM code. The following convention has been used so far. Let name be the }{\i\f1 name}{\f1 of the real system (i1401 for the IBM 1401; pdp1 for the PDP-1; pdp18b for the other 18-bit PDP\rquote
s; pdp8 for the PDP-8; pdp11 for the PDP-11; nova for Nova; hp2100 for the HP 21XX; id4 for the Interdata 4; pdp10 for the PDP-10):
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls2\adjustright {\i\f1 name}{\f1
.h contains definitions for the particular simulator
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls2\adjustright {\i\f1 name}{\f1
_sys.c contains all the SCP interfaces except the instruction simulator
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls2\adjustright {\i\f1 name}{\f1
_cpu.c contains the instruction simulator and CPU data structures
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls2\adjustright {\i\f1 name}{\f1
_stddev.c contains the peripherals which were standard with the real system.
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls2\adjustright {\i\f1 name}{\f1 _lp.c contains th
e line printer.
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls2\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls2\adjustright {\i\f1 name}{\f1
_mt.c contains the mag tape controller and drives, etc.
\par }\pard \fi1440\widctlpar\adjustright {\f1
\par }\pard \widctlpar\adjustright {\f1 The SIMH standard definitions are in sim_defs.h, the simulator control package in scp.c, and the operating-system dependent terminal routines in scp_tty.c. Additional librarie
s include sim_tmxr.c (header file sim_tmxr.h) for terminal multiplexors, and sim_sock.c (header file sim_sock.h) for network processing.
\par {\*\bkmkstart _Toc526228040}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 3.1\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {CPU Organization
{\*\bkmkend _Toc526228040}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par Most CPU\rquote s perform at least the following functions:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls3\adjustright {\f1 Time keeping
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls3\adjustright {\f1 Instruction fetching
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls3\adjustright {\f1 Address decoding
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls3\adjustright {\f1 Execution of non-I/O instructions
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls3\adjustright {\f1 I/O command processing
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls3\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls3\adjustright {\f1 Interrupt processing
\par }\pard \widctlpar\adjustright {\f1
\par Instruction execution is actually the least complicated part of the design; memory and I/O organization should be tackled first.
\par {\*\bkmkstart _Toc526228041}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.1.1\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Time Base{\*\bkmkend _Toc526228041}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par In order to simulate asynchronous events, such as I/O completion, the VM must define and keep a time base. This can be accurate (for example, nanoseconds of execution) or arbitrary (for example, number of ins
tructions executed), but it must be consistently used throughout the VM. All existing VM\rquote s count time in instructions.
\par
\par The CPU is responsible for counting down the event counter }{\b\f1 sim_interval}{\f1 and calling the asynchronous event controller }{\b\f1 sim_process_event}{\f1 . The record keeping for timing is done by SCP.
\par {\*\bkmkstart _Toc526228042}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.1.2\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Memory Organization
{\*\bkmkend _Toc526228042}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The criterion for memory layout is very simple: use the SIMH data type that is as large as (or if necessary, larger than), the word length of the real mac
hine. Note that the criterion is word length, not addressability: the PDP-11 has byte addressable memory, but it is a 16-bit machine, and its memory is defined as uint16 M[]. It may seem tempting to define memory as a union of int8 and int16 data types,
but this would make the resulting VM endian-dependent. Instead, the VM should be based on the underlying word size of the real machine, and byte manipulation should be done explicitly. Examples:
\par
\par \tab Simulator\tab \tab memory size\tab \tab memory declaration
\par
\par \tab IBM 1401\tab \tab 6-bit\tab \tab \tab uint8
\par \tab PDP-8\tab \tab \tab 12-bit\tab \tab \tab uint16
\par \tab PDP-11, Nova\tab \tab 16-bit\tab \tab \tab uint16
\par \tab PDP-1\tab \tab \tab 18-bit\tab \tab \tab uint32
\par \tab PDP-10\tab \tab \tab 36-bit\tab \tab \tab uint64
\par {\*\bkmkstart _Toc526228043}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.1.3\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Interrupt Organization
{\*\bkmkend _Toc526228043}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The design of the VM\rquote s interrupt structure is a complex interaction between efficiency and fidelity to the hardware. If the VM\rquote
s interrupt structure is too abstract, interrupt driven software may not run. On the other hand, if it follows the hardware too literally, it may si
gnificantly reduce simulation speed. One rule I can offer is to minimize the fetch-phase cost of interrupts, even if this complicates the (much less frequent) evaluation of the interrupt system following an I/O operation or asynchronous event. Another i
s not to over-generalize; even if the real hardware could support 64 or 256 interrupting devices, the simulators will be running much smaller configurations. I\rquote
ll start with a simple interrupt structure and then offer suggestions for generalization.
\par
\par In th
e simplest structure, interrupt requests correspond to device flags and are kept in an interrupt request variable, with one flag per bit. The fetch-phase evaluation of interrupts consists of two steps: are interrupts enabled, and is there an interrupt ou
tstanding? If all the interrupt requests are kept as single-bit flags in a variable, the fetch-phase test is very fast:
\par
\par \tab if (int_enable && int_requests) \{ \'85process interrupt\'85 \}
\par
\par Indeed, the interrupt enable flag can be made the highest bit in the interrupt request variable, and the two tests combined:
\par
\par \tab if (int_requests > INT_ENABLE) \{ \'85process interrupt\'85 \}
\par
\par Setting or clearing device flags directly sets or clears the appropriate interrupt request flag:
\par
\par \tab set: \tab int_requests = int_requests | DEVICE_FLAG;
\par \tab clear:\tab int_requests = int_requests & ~DEVICE_FLAG;
\par
\par At a slightly higher complexity, interrupt requests do not correspond directly to device flags but are based on masking the device flags with an enable (or disable) mask. There are now three parallel vari
ables: interrupt requests, device flags, and interrupt enable mask. The fetch-phase test does not change; however, the evaluation of whether an interrupt is pending now requires an extra step:
\par
\par \tab enable:\tab int_requests = device_flags & int_enables;
\par \tab disable:\tab int_requests = device_flags & ~int_disables;
\par
\par If required for interrupt processing, the highest priority interrupting device can be determined by scanning the interrupt request variable from high priority to low until a set bit is found. The bit position
can then be back-mapped through a table to determine the address or interrupt vector of the interrupting device.
\par
\par At yet higher complexity, the interrupt system may be too complex or too large to evaluate during the fetch-phase. In this case, an interrup
t pending flag is created, and it is evaluated by subroutine call whenever a change could occur (start of execution, I/O instruction issued, device time out occurs). This makes fetch-phase evaluation simple and isolates interrupt evaluation to a common s
ubroutine.
\par {\*\bkmkstart _Toc526228044}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.1.4\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {I/O Dispatching
{\*\bkmkend _Toc526228044}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par I/O dispatching consists of four steps:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls14\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls14\adjustright {\f1
Identify the I/O command and analyze for the device address.
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls14\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls14\adjustright {\f1 Locate the selected device.
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls14\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls14\adjustright {\f1
Break down the I/O command into standard fields.
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls14\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls14\adjustright {\f1 Call the device processor.
\par }\pard \widctlpar\adjustright {\f1
\par Analyzing an I/O command is usually easy. Most systems have one or more explicit I/O instructions containing an I/O command and a device address. Memory mapped I/O is more complicated; the identification of a reference to I/O
space becomes part of memory addressing. This usually requires centralizing memory reads and writes into subroutines, rather than as inline code.
\par
\par Once an I/O command has been analyzed, the CPU must locate the device subroutine. The simplest way is a lar
ge switch statement with hardwired subroutine calls. Slightly more modular is to call through a dispatch table, with NULL entries representing non-existent devices. Before calling the device routine, the CPU usually breaks down the I/O command into stan
dard fields. This simplifies writing the peripheral simulator.
\par {\*\bkmkstart _Toc526228045}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.1.5\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Instruction Execution
{\*\bkmkend _Toc526228045}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par Instruction execution is the responsibility of VM subroutine }{\b\f1 sim_instr}{\f1 . It is called from SCP as a result of a RUN, GO, CONT, or BOOT command. It begins executing instructions at the current PC (}{\b\f1 sim_PC}{\f1
points to its register description block) and continues until halted by an error or an external event.
\par
\par When called, the CPU needs to account for any state changes that the user made. For e
xample, it may need to re-evaluate whether an interrupt is pending, or restore frequently used state to local register variables for efficiency. The actual instruction fetch and execute cycle is usually structured as a loop controlled by an error variabl
e, e.g.,
\par
\par \tab reason = 0;
\par \tab do \{ \'85 \} while (reason == 0);\tab or\tab while (reason == 0) \{ \'85 \}
\par
\par Within this loop, the usual order of events is:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls4\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls4\adjustright {\f1 If the event timer }{\b\f1
sim_interval}{\f1 has reached zero, process any timed events. This is done by SCP subroutine }{\b\f1 sim_process_event}{\f1 . Because this is the polling mechanism for user-generated processor halts (^E), errors must be recognized immediately:
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par }\pard \li1440\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1 if (sim_interval <= 0) \{
\par }\pard \fi720\li1440\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1 if (reason = sim_process_event ()) break; \}
\par }\pard \fi2160\widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls4\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls4\adjustright {\f1
Check for outstanding interrupts and process if required.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls4\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls4\adjustright {\f1
Check for other processor-unique events, such as wait-state outstanding or traps outstanding.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls4\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls4\adjustright {\f1
Check for an instruction breakpoint. SCP has no breakpoint facility, but it is customary to implement a single instruction breakpoint to help with processor code. All the existing CPU\rquote s use the same mechanism, see the sources for details.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls4\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls4\adjustright {\f1 Fetch the n
ext instruction, increment the PC, optionally decode the address, and dispatch (via a switch statement) for execution.
\par }\pard \widctlpar\adjustright {\f1
\par A few guidelines for implementation:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls5\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls5\adjustright {\f1
In general, code should reflect the hardware being simulated. This is usually simplest and easiest to debug.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls5\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls5\adjustright {\f1
The VM should provide some debugging aids. The existing CPU\rquote s all provide an instruction breakpoint, an OLDPC register, and error stops on invalid instructions or operations.
\par {\*\bkmkstart _Toc526228046}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 3.2\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {
Peripheral Device Organization{\*\bkmkend _Toc526228046}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The basic elements of a VM are devices, each corresponding roughly to a real chunk of hardware. A device consists of register-based state and one or more units. Thus, a multi-drive disk subsystem is a single device (representing the hardware of the real
controller) and one or more units (each representing a single disk drive). Sometimes the device and its unit are the same entity as, for example, in the case of a paper tape reader. However, a single physical device, such as the console, may be broken
up for convenience into separate input and output devices.
\par
\par In general, units correspond to individual sources of input or output (one tape transport, one A-to-D channel). Units are the basic medium for both device timing and device I/O. Except for the co
nsole, all I/O devices are simulated as host-resident files. SCP allows the user to make an explicit association between a host-resident file and a simulated hardware entity.
\par
\par Both devices and units have state. Devices operate on }{\i\f1 registers}{\f1 , which contain information about the state of the device, and indirectly, about the state of the units. Units operate on }{\i\f1 data sets}{\f1
, which may be thought of as individual instances of input or output, such as a disk pack or a punched paper tape. In a typical multi-unit
device, all units are the same, and the device performs similar operations on all of them, depending on which one has been selected by the program being simulated.
\par
\par (Note: SIMH, like MIMIC, restricts registers to devices. This requires replicated registers, for example, disk drive current state, to have unique names in the device name space.)
\par
\par For each structural level, SIMH defines, and the VM must supply, a corresponding data structure. }{\b\f1 device}{\f1 structures correspond to devices, }{\b\f1 reg}{\f1 structures to registers, and }{\b\f1 unit}{\f1
structures to units. These structures are described in detail in section 4.
\par
\par The primary functions of a peripheral are:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls6\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls6\adjustright {\f1 command decoding and execution
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls6\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls6\adjustright {\f1 device timing
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls6\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls6\adjustright {\f1 data transmission.
\par }\pard \widctlpar\adjustright {\f1
\par Command decoding is fairly obvious. At least one section of the peripheral code module will be devoted to processing directives issued by the CPU. Typically, the command decoder will be responsible for register and flag manipulation, and for issuing or
canceling I/O requests. The former is easy, but the later requires a thorough understanding of device timing.
\par {\*\bkmkstart _Toc526228047}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.2.1\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Device Timing
{\*\bkmkend _Toc526228047}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The principal problem in I/O device simulation is imitating asynchronous operations in a sequential
simulation environment. Fortunately, the timing characteristics of most I/O devices do not vary with external circumstances. The distinction between devices whose timing is externally generated (e.g., console keyboard) and those whose timing is externa
l
ly generated (disk, paper tape reader) is crucial. With an externally timed device, there is no way to know when an in-progress operation will begin or end; with an internally timed device, given the time when an operation starts, the end time can be cal
culated.
\par
\par For an internally timed device, the elapsed time between the start and conclusion of an operation is called the wait time. Some typical internally timed devices and their wait times include:
\par
\par \tab PTR (300 char/sec)\tab \tab 3.3 msec
\par \tab PTP (50 char/sec)\tab \tab 20 msec
\par \tab CLK (line frequency)\tab \tab 16.6 msec
\par \tab TTO (30 char/sec)\tab \tab 33 msec
\par
\par Mass storage devices, such as disks and tapes, do not have a fixed response time, but a start-to-finish time can be calculated based on current versus desired position, state of motion, etc.
\par
\par For an externally timed device, there is no portable mechanism by which a VM can be notified of an external event. Because the only important externally timed device is the console keyboard, all current VM\rquote
s poll for keyboard input, thus converting the externally timed keyboard to a pseudo-internally timed device.
\par
\par SCP provides the supporting routines for device timing. SCP maintains a list of devices (called }{\i\f1 active devices}{\f1 ) which are in the process of timing out. It also provides routines for querying or manipulating this list (called the }{\i\f1
active queue}{\f1 ). Lastly, it provides a routine for checking for timed-out units and executing a VM-specified action when a time-out occurs.
\par
\par Device timing is done with the UNIT structure, described in section 3. To se
t up a timed operation, the peripheral calculates a waiting period for a unit and places that unit on the active queue. The CPU counts down the waiting period. When the waiting period has expired, }{\b\f1 sim_process_event}{\f1
removes the unit from the active queue and calls a device subroutine. A device may also cancel an outstanding timed operation and query the state of the queue. The timing subroutines are:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 t_stat }{\b\f1 sim_activate}{\f1
(UNIT *uptr, int32 wait). This routine places the specified unit on the active q
ueue with the specified waiting period. A waiting period of 0 is legal; negative waits cause an error. If the unit is already active, the active queue is not changed, and no error occurs.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 t_stat }{\b\f1 sim_cancel}{\f1
(UNIT *uptr). This routine removes the specified unit from the active queue. If the unit is not on the queue, no error occurs.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 int32 }{\b\f1 sim_is_active}{\f1
(UNIT *uptr). This routine tests whether a unit is in the active queue. If it is, the routine returns the time (+1) remaining; if it is not, the routine returns 0.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 double }{\b\f1 sim_gtime}{\f1
(void). This routine returns the time elapsed since the last RUN or BOOT command.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 uint32 }{\b\f1 sim_grtime}{\f1
(void). This routine returns the low-order 32b of the time elapsed since the last RUN or BOOT command.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 int32 }{\b\f1 sim_qcount}{\f1
(void). This routine returns the number of entries on the clock queue.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 t_stat }{\b\f1 sim_process_event}{
\f1 (void). This routine removes all timed out units from the active queue and calls the appropriate device subroutine to service the time-out.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls7\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls7\adjustright {\f1 int32 }{\b\f1 sim_interval}{\f1
. This variable counts down the first outstanding timed event. If there are no timed events outstanding, SCP counts down a \ldblquote null interval\rdblquote of 10,000 time units.
\par {\*\bkmkstart _Toc526228048}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.2.2\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Clock Calibration
{\*\bkmkend _Toc526228048}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The timing mechanism described in the previous section is approximate. Devices, such as real-time clocks, which track wall time will be inaccurate. SCP provides routines to synchronize a simulated real-time clock to wall time.
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls15\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls15\adjustright {\f1 int32 }{\b\f1 sim_rtc_init}{\f1
(int32 clock_interval). This routine initializes the clock calibration mechanism. The argument is returned as the result.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li360\widctlpar\jclisttab\tx360{\*\pn \pnlvlblt\ilvl0\ls15\pnrnot0\pnf3\pnstart1\pnindent360\pnhang{\pntxtb \'b7}}\ls15\adjustright {\f1 int32 }{\b\f1 sim_rtc_calb}{\f1
(int32 tickspersecond). This routine calibrates the real-time clock. The argument is the number of clock ticks expected per second.
\par }\pard \widctlpar\adjustright {\f1
\par The simulator calls }{\b\f1 sim_rtc_init}{\f1 in the prolog of }{\b\f1 sim_instr}{\f1 , before instruction execution starts, and whenever the real-time clock is started. The simulator calls }{\b\f1 sim_rtc_calb}{\f1
to calculate the actual interval delay when the real-time clock is serviced:
\par
\par \tab /* clock start */
\par
\par \tab if (!sim_is_active (&clk_unit)) sim_activate (&clk_unit, sim_rtc_init (clk_delay));
\par \tab etc.
\par
\par \tab /* clock service */
\par
\par \tab sim_activate (&clk_unit, sim_rtc_calb (clk_ticks_per_second);
\par {\*\bkmkstart _Toc526228049}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 3.2.3\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Data I/O{\*\bkmkend _Toc526228049}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par For most devices, timing is half the battle (for clocks it is the entire war); the other half is I/O. Except for the console, all I/O devices are simulated as files on the host file system in little-endian format. SCP provides facilities for associating
files with units (ATTACH command) and for reading and writing data from and to devices in a endian- and size-independent way.
\par
\par For most devices, the VM designer does not have to be concerned about the formatting of simulated device files. I/O occurs in 1, 2, or 4 byte quantities; SCP automatically chooses the correct data size and corrects for byte ordering. Specific issues:
\par
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls8\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls8\adjustright {\f1
Line printers should write data as 7-bit ASCII, with newlines replacing carriage-return/line-feed sequences.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls8\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls8\adjustright {\f1 Disks should be
viewed as linear data sets, from sector 0 of surface 0 of cylinder 0 to the last sector on the disk. This allows easy transcription of real disks to files usable by the simulator.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls8\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls8\adjustright {\f1
Magtapes, by convention, use a record based format. Each record consi
sts of a leading 32-bit record length, the record data (padded with a byte of 0 if the record length is odd), and a trailing 32-bit record length. File marks are recorded as one record length of 0.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls8\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls8\adjustright {\f1
Cards have 12 bits of data per column, but the data is most conveniently viewed as (ASCII) characters. Existing card reader simulators do not support binary operation.
\par }\pard \widctlpar\adjustright {\f1
\par Data I/O varies between fixed and variable capacity devices, and between buffered and non-buffered devices. A fixed capacity device differ
s from a variable capacity device in that the file attached to the former has a maximum size, while the file attached to the latter may expand indefinitely. A buffered device differs from a non-buffered device in that the former buffers its data set in h
ost memory, while the latter maintains it as a file. Most variable capacity devices (such as the paper tape reader and punch) are sequential; all buffered devices are fixed capacity.
\par
\par {\listtext\pard\plain\f1\fs20\cgrid \hich\af1\dbch\af0\loch\f1 3.2.3.1\tab}}\pard \fi-1080\li1080\widctlpar\jclisttab\tx1080\ls1\ilvl3\adjustright {\f1 Reading and Writing Data
\par }\pard \widctlpar\adjustright {\f1
\par The ATTACH command creates an association between a host file and an I/O unit. For non-buffered devices, ATTACH stores the file pointer for the host file in the }{\b\f1 fileref}{\f1
field of the UNIT structure. For buffered devices, ATTACH reads the entire host file into an allocated buffer pointed to by the }{\b\f1 filebuf }{\f1 field of the UNIT structure.
\par
\par For non-buffered devices, I/O is done with standard C subroutines plus the SCP routines }{\b\f1 fxread}{\f1 and }{\b\f1 fxwrite}{\f1 . }{\b\f1 fxread}{\f1 and }{\b\f1 fxwrite}{\f1
are identical in calling sequence and function to fread and fwrite, respectively, but
will correct for endian dependencies. For buffered devices, I/O is done by copying data to or from the allocated buffer. The device code must maintain the number (+1) of the highest address modified in the }{\b\f1 hwmark}{\f1
field of the UNIT structure. For both the non-buffered and buffered cases, the device must perform all address calculations and positioning operations.
\par
\par The DETACH command breaks the association between a host file and an I/O unit. For buffered devices, DETACH writes the allocated buffer back to the host file.
\par
\par {\listtext\pard\plain\f1\fs20\cgrid \hich\af1\dbch\af0\loch\f1 3.2.3.2\tab}}\pard \fi-1080\li1080\widctlpar\jclisttab\tx1080\ls1\ilvl3\adjustright {\f1 Console I/O
\par }\pard \widctlpar\adjustright {\f1
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 SCP provides two routines for console I/O.
\par }\pard \widctlpar\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls10\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls10\adjustright {\f1 t_stat }{\b\f1 sim_poll_char }{
\f1 (void). This routine polls for keyboard input. If there is a character, it returns SCPE_KFLAG + the character. If the user typed the interrupt character (^E), it returns SCPE_STOP. If there is no input, it returns SCPE_OK.
\par }\pard \widctlpar{\*\pn \pnlvlcont\ilvl0\ls0\pnrnot0\pndec }\adjustright {\f1
\par {\pntext\pard\plain\f3\fs20\cgrid \loch\af3\dbch\af0\hich\f3 \'b7\tab}}\pard \fi-360\li720\widctlpar\jclisttab\tx720{\*\pn \pnlvlblt\ilvl0\ls10\pnrnot0\pnf3\pnstart1\pnindent720\pnhang{\pntxtb \'b7}}\ls10\adjustright {\f1 t_stat }{\b\f1 sim_putchar}{\f1
(int32 char). This routine types the specified ASCII character on the console. There are no errors.
\par }\pard \widctlpar\adjustright {\f1
\par {\*\bkmkstart _Toc526228050}{\listtext\pard\plain\s1 \b\f1\fs28\kerning28\cgrid \hich\af1\dbch\af0\loch\f1 4.\tab}}\pard\plain \s1\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360\ls1\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {
Data Structures{\*\bkmkend _Toc526228050}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The devices, units, and registers which make up a VM are formally described through a set of data structures which interface the VM to the control portions of SCP. The devices themselves are pointed to by the device list array }{\b\f1 sim_devices[]}{\f1
. Within a device, both units and registers are allocated contiguously as arrays of structures. In addition, many devices allow the user to set or clear options via a modifications table.
\par {\*\bkmkstart _Toc526228051}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 4.1\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {device Structure
{\*\bkmkend _Toc526228051}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par Devices are defined by the }{\b\f1 device}{\f1 structure (typedef }{\b\f1 DEVICE}{\f1 ):
\par
\par }\pard \li720\widctlpar\adjustright {\f1 struct device \{
\par \tab char\tab \tab *name;\tab \tab \tab \tab /* name */
\par \tab struct unit \tab *units;\tab \tab \tab \tab /* units */
\par \tab struct reg\tab *registers;\tab \tab \tab /* registers */
\par \tab struct mtab\tab *modifiers;\tab \tab \tab /* modifiers */
\par \tab int\tab \tab numunits;\tab \tab \tab /* #units */
\par \tab int\tab \tab aradix;\tab \tab \tab \tab /* address radix */
\par \tab int\tab \tab awidth;\tab \tab \tab \tab /* address width */
\par \tab int\tab \tab aincr;\tab \tab \tab \tab /* addr increment */
\par \tab int\tab \tab dradix;\tab \tab \tab \tab /* data radix */
\par \tab int\tab \tab dwidth;\tab \tab \tab \tab /* data width */
\par \tab t_stat\tab \tab (*examine)();\tab \tab \tab /* examine routine */
\par \tab t_stat\tab \tab (*deposit)();\tab \tab \tab /* deposit routine */
\par \tab t_stat\tab \tab (*reset)();\tab \tab \tab /* reset routine */
\par \tab t_stat\tab \tab (*boot)();\tab \tab \tab /* boot routine */
\par \tab t_stat\tab \tab (*attach)();\tab \tab \tab /* attach routine */
\par \tab t_stat\tab \tab (*detach)();\tab \tab \tab /* detach routine */
\par \};
\par }\pard \widctlpar\adjustright {\f1
\par The fields are the following:
\par
\par }\pard \li720\widctlpar\adjustright {\b\f1 name}{\f1 \tab \tab device name, string of all capital alphanumeric characters.
\par }{\b\f1 units}{\f1 \tab \tab pointer to array of }{\b\f1 unit}{\f1 structures, or NULL if none.
\par }{\b\f1 registers}{\f1 \tab pointer to array of }{\b\f1 reg}{\f1 structures, or NULL if none.
\par }{\b\f1 modifiers}{\f1 \tab pointer to array of }{\b\f1 mtab}{\f1 structures, or NULL if none.
\par }{\b\f1 numunits}{\f1 \tab number of units in this device.
\par }{\b\f1 aradix}{\f1 \tab \tab radix for input and display of device addresses, 2 to 16 inclusive.
\par }{\b\f1 awidth}{\f1 \tab \tab width in bits of a device address, 1 to 31 inclusive.
\par }\pard \fi-1440\li2160\widctlpar\adjustright {\b\f1 aincr}{\f1 \tab increment between device addresses, normally 1; however, byte addressed devices with 16-bit words specify 2, with 32-bit words 4.
\par }\pard \li720\widctlpar\adjustright {\b\f1 dradix}{\f1 \tab \tab radix for input and display of device data, 2 to 16 inclusive.
\par }{\b\f1 dwidth}{\f1 \tab \tab width in bits of device data, 1 to 32 inclusive.
\par }{\b\f1 examine}{\f1 \tab address of special device data read routine, or NULL if none is required.
\par }{\b\f1 deposit}{\f1 \tab \tab address of special device data write routine, or NULL if none is required.
\par }{\b\f1 reset}{\f1 \tab \tab address of device reset routine, or NULL if none is required.
\par }{\b\f1 boot}{\f1 \tab \tab address of device bootstrap routine, or NULL if none is required.
\par }{\b\f1 attach}{\f1 \tab \tab address of special device attach routine, or NULL if none is required.
\par }{\b\f1 detach}{\f1 \tab \tab address of special device detach routine, or NULL if none is required.
\par {\*\bkmkstart _Toc526228052}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.1.1\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Examine and Deposit Routines
{\*\bkmkend _Toc526228052}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par For devices which maintain their data sets as host files, SCP implements the examine and deposit data functions. However, devices which maintain their data sets as private state (typically just the C
PU) must supply special examine and deposit routines. The calling sequences are:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat }{\i\f1 examine_routine}{\f1 (t_val *eval_array, t_addr addr, UNIT *uptr, int32 switches) \endash Copy }{\b\f1 sim_emax}{\f1 consecutive addresses for unit }{\i\f1 uptr}{\f1 , starting at }{\i\f1 addr}{
\f1 , into }{\i\f1 eval_array}{\f1 . The }{\i\f1 switch}{\f1 variable has bit<n> set if the n\rquote th letter was specified as a switch to the examine command.
\par
\par t_stat }{\i\f1 deposit_routine}{\f1 (t_val value, t_addr addr, UNIT *uptr, int32 switches) \endash Store the specified }{\i\f1 value}{\f1 in the specified }{\i\f1 addr}{\f1 for unit }{\i\f1 uptr}{\f1 . The }{\i\f1 switch}{\f1
variable is the same as for the examine routine.
\par {\*\bkmkstart _Toc526228053}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.1.2\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Reset Routine
{\*\bkmkend _Toc526228053}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The reset routine implements the device reset function for the RESET, RUN, and BOOT commands. Its calling sequence is:
\par
\par \tab t_stat }{\i\f1 reset_routine}{\f1 (DEVICE *dptr) \endash Reset the specified device to its initial state.
\par
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 A typical reset routine clears all device flags and cancels any outstanding timing operations.
\par {\*\bkmkstart _Toc526228054}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.1.3\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Boot Routine
{\*\bkmkend _Toc526228054}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par If a device responds to a BOOT command, the boot routine implements the bootstrapping function. Its calling sequence is:
\par
\par \tab t_stat }{\i\f1 boot_routine}{\f1 (int32 unit_number) \endash Bootstrap the specified unit.
\par
\par A typical bootstrap routine copies a bootstrap loader into main memory and sets the PC to the starting address of the loader. SCP then starts simulation at the specified address.
\par {\*\bkmkstart _Toc526228055}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.1.4\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Attach and Detach Routines
{\*\bkmkend _Toc526228055}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par Normally, the ATTACH and DETACH commands are handled by SCP. However, devices which need to pre- or post-process these commands must supply special attach and detach routines. The calling sequences are:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat }{\i\f1 attach_routine }{\f1 (UNIT *uptr, char *file) \endash Attach the specified }{\i\f1 file}{\f1 to the unit }{\i\f1 uptr}{\f1 .
\par
\par t_stat }{\i\f1 detach_routine}{\f1 (UNIT *uptr) \endash Detach unit }{\i\f1 uptr}{\f1 .
\par }\pard \widctlpar\adjustright {\f1
\par In practice, these routines always invoke the standard SCP routines, }{\b\f1 attach_unit}{\f1 and }{\b\f1 detach_unit}{\f1 , respectively. For example, here are special attach and detach routines to update line printer error state:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat lpt_attach (UNIT *uptr, char *cptr) \{
\par }\pard \fi720\li720\widctlpar\adjustright {\f1 t_stat r;
\par if ((r = attach_unit (uptr, cptr)) != SCPE_OK) return r;
\par lpt_error = 0;
\par return SCPE_OK;
\par }\pard \li720\widctlpar\adjustright {\f1 \}
\par
\par t_stat lpt_detach (UNIT *uptr) \{
\par \tab lpt_error = 1;
\par \tab return detach_unit (uptr);
\par \}
\par }\pard \widctlpar\adjustright {\f1
\par SCP executes a DETACH ALL command as part of simulator exit. Normally, DETACH ALL only calls a unit\rquote s detach routine if the unit\rquote
s UNIT_ATTABLE flag is set. During simulator exit, the detach routine is called unconditionally. This allows the detach routine of a non-attachable unit to function as a simulator-specific cleanup routine for the unit, device, or entire simulator.
\par {\*\bkmkstart _Toc526228056}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 4.2\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {unit Structure
{\*\bkmkend _Toc526228056}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\b\f1
\par }{\f1 Units are allocated as contiguous array. Each unit is defined with a }{\b\f1 unit}{\f1 structure (typedef }{\b\f1 UNIT}{\f1 ):
\par
\par }\pard \li720\widctlpar\adjustright {\f1 struct unit \{
\par \tab struct unit\tab *next;\tab \tab \tab \tab /* next active */
\par \tab t_stat\tab \tab (*action)();\tab \tab \tab /* action routine */
\par \tab char\tab \tab *filename;\tab \tab \tab /* open file name */
\par \tab FILE\tab \tab *fileref;\tab \tab \tab \tab /* file reference */
\par \tab void\tab \tab *filebuf;\tab \tab \tab \tab /* memory buffer */
\par \tab t_addr\tab \tab hwmark;\tab \tab \tab /* high water mark */
\par \tab int32\tab \tab time;\tab \tab \tab \tab /* time out */
\par \tab int32\tab \tab flags;\tab \tab \tab \tab /* flags */
\par \tab t_addr\tab \tab capac;\tab \tab \tab \tab /* capacity */
\par \tab t_addr\tab \tab pos;\tab \tab \tab \tab /* file position */
\par \tab int32\tab \tab buf;\tab \tab \tab \tab /* buffer */
\par \tab int32\tab \tab wait;\tab \tab \tab \tab /* wait */
\par \tab int32\tab \tab u3;\tab \tab \tab \tab /* device specific */
\par \tab int32\tab \tab u4;\tab \tab \tab \tab /* device specific */
\par \};
\par }\pard \widctlpar\adjustright {\f1
\par The fields are the following:
\par
\par }\pard \li720\widctlpar\adjustright {\b\f1 next}{\f1 \tab \tab pointer to next unit in active queue, NULL if none.
\par }{\b\f1 action}{\f1 \tab \tab address of unit time-out service routine.
\par }{\b\f1 filename}{\f1 \tab pointer to name of attached file, NULL if none.
\par }{\b\f1 fileref}{\f1 \tab \tab pointer to FILE structure of attached file, NULL if none.
\par }{\b\f1 hwmark}{\f1 \tab buffered devices only; highest modified address, + 1.
\par }{\b\f1 time}{\f1 \tab \tab increment until time-out beyond previous unit in active queue.
\par }{\b\f1 flags}{\f1 \tab \tab unit flags.
\par }{\b\f1 capac}{\f1 \tab \tab unit capacity, 0 if variable.
\par }{\b\f1 pos}{\f1 \tab \tab sequential devices only; next device address to be read or written.
\par }{\b\f1 buf}{\f1 \tab \tab by convention, the unit buffer, but can be used for other purposes.
\par }{\b\f1 wait}{\f1 \tab \tab by convention, the unit wait time, but can be used for other purposes.
\par }{\b\f1 u3}{\f1 \tab \tab user-defined.
\par }{\b\f1 u4}{\f1 \tab \tab user-defined.
\par }\pard \widctlpar\adjustright {\b\f1
\par buf, wait, u3, u4}{\f1 are all saved and restored by the SAVE and RESTORE commands and thus can be used for unit state which must be preserved.
\par
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 Macro }{\b\f1 UDATA}{\f1 is available to fill in the common fields of a UNIT. It is invoked by
\par }\pard \widctlpar\adjustright {\f1
\par \tab UDATA\tab \tab (action_routine, flags, capacity)
\par
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 Fields after }{\b\f1 buf}{\f1 can be filled in manually, e.g,
\par }\pard \widctlpar\adjustright {\f1
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 \tab UNIT lpt_unit = \{ UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), 500 \};
\par }\pard \widctlpar\adjustright {\f1
\par defines the line printer as a sequential unit with a wait time of 500.
\par {\*\bkmkstart _Toc526228057}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.2.1\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Unit Flags{\*\bkmkend _Toc526228057
}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The }{\b\f1 flags }{\f1 field contains indicators of current unit status. SIMH defines 11 flags:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 flag name\tab \tab meaning if set
\par
\par UNIT_DISABLE\tab \tab the unit responds to ENABLE and DISABLE.
\par UNIT_DIS\tab \tab the unit is currently disabled.
\par UNIT_ATTABLE\tab the unit responds to ATTACH and DETACH.
\par UNIT_ATT\tab \tab the unit is currently attached to a file.
\par UNIT_BUFABLE\tab the unit can buffer its data set in memory.
\par UNIT_MUSTBUF\tab the unit must buffer its data set in memory.
\par UNIT_BUF\tab \tab the unit is currently buffering its data set in memory.
\par UNIT_RO\tab \tab the unit is read only.
\par UNIT_SEQ\tab \tab the unit is sequential.
\par UNIX_FIX\tab \tab the unit is fixed capacity.
\par UNIT_BINK\tab \tab the unit measures \ldblquote K\rdblquote as 1024, rather than 1000.
\par }\pard \widctlpar\adjustright {\f1
\par Starting at bit position UNIT_V_UF, the remaining flags are device-specific. Device-specific flags are set and cleared with the SET and CLEAR commands, which reference the MTAB array (see be
low). Device-specific flags and UNIT_DIS are not automatically saved and restored; the device must supply a register covering these bits.
\par {\*\bkmkstart _Toc526228058}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.2.2\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Service Routine
{\*\bkmkend _Toc526228058}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par This routine is called by }{\b\f1 sim_process_event}{\f1 when a unit times out. Its calling sequence is:
\par
\par }\pard \fi720\widctlpar\adjustright {\f1 t_stat }{\i\f1 service_routine}{\f1 (UNIT *uptr)
\par }\pard \widctlpar\adjustright {\f1
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 The status returned by the service routine is passed by }{\b\f1 sim_process_event}{\f1 back to the CPU.
\par {\*\bkmkstart _Toc526228059}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 4.3\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {reg Structure
{\*\bkmkend _Toc526228059}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\b\f1
\par }{\f1 Registers are allocated as contiguous array, with a NULL register at the end. Each register is defined with a }{\b\f1 reg}{\f1 structure (typedef }{\b\f1 REG}{\f1 ):
\par
\par }\pard \li720\widctlpar\adjustright {\f1 struct reg \{
\par \tab char\tab \tab *name;\tab \tab \tab \tab /* name */
\par \tab void\tab \tab *loc;\tab \tab \tab \tab /* location */
\par \tab int\tab \tab radix;\tab \tab \tab \tab /* radix */
\par \tab int\tab \tab width;\tab \tab \tab \tab /* width */
\par \tab int\tab \tab offset;\tab \tab \tab \tab /* starting bit */
\par \tab int\tab \tab depth;\tab \tab \tab \tab /* save depth */
\par \tab int32\tab \tab flags;\tab \tab \tab \tab /* flags */
\par \};
\par }\pard \widctlpar\adjustright {\f1
\par The fields are the following:
\par
\par }\pard \li720\widctlpar\adjustright {\b\f1 name}{\f1 \tab \tab device name, string of all capital alphanumeric characters.
\par }{\b\f1 loc}{\f1 \tab \tab pointer to location of the register value.
\par }{\b\f1 radix}{\f1 \tab \tab radix for input and display of data, 2 to 16 inclusive.
\par }{\b\f1 width}{\f1 \tab \tab width in bits of data, 1 to 32 inclusive.
\par }{\b\f1 width\tab }{\f1 \tab bit offset (from right end of data).
\par }{\b\f1 depth\tab }{\f1 \tab size of data array (normally 1).
\par }{\b\f1 flags}{\f1 \tab \tab flags and formatting information.
\par }\pard \widctlpar\adjustright {\f1
\par The }{\b\f1 depth}{\f1 field is only used with special \ldblquote arrayed registers\rdblquote
, like the data buffer in the PDP floppy disk controller. Arrayed registers cannot be examined or deposited, but all the values in the array will be saved and restored by SAVE and RESTORE.
\par
\par Macros }{\b\f1 ORDATA}{\f1 , }{\b\f1 DRDATA}{\f1 , and }{\b\f1 HRDATA}{\f1 define right-justified octal, decimal, and hexidecimal registers, respectively. They are invoked by:
\par
\par \tab xRDATA\tab (name, location, width)
\par
\par Macro }{\b\f1 FLDATA}{\f1 defines a one-bit binary flag at an arbitrary offset in a 32-bit word. It is invoked by:
\par
\par \tab FLDATA\tab (name, location, bit_position)
\par
\par Macro }{\b\f1 GRDATA}{\f1 defines a register with arbitrary location and radix. It is invoked by:
\par
\par \tab GRDATA\tab (name, location, radix, width, bit_position)
\par
\par Finally }{\b\f1 BRDATA}{\f1 defines an arrayed register. It is invoked by:
\par
\par \tab BRDATA\tab (name, location, radix, width, depth)
\par
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 The }{\b\f1 flag}{\f1 field can be filled in manually, e.g.,
\par }\pard \widctlpar\adjustright {\f1
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 \tab REG lpt_reg = \{
\par }\pard \widctlpar\adjustright {\f1 \tab \tab \{ DRDATA\tab (POS, lpt_unit.pos, 31), PV_LFT \}, \'85 \}
\par {\*\bkmkstart _Toc526228060}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.3.1\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Register Flags
{\*\bkmkend _Toc526228060}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 The }{\b\f1 flags }{\f1 field contains indicators that control register examination and deposit.
\par }\pard \widctlpar\adjustright {\f1
\par }\pard \li720\widctlpar\adjustright {\f1 flag name\tab \tab meaning if specified
\par
\par PV_RZRO\tab \tab print register right justified with leading zeroes.
\par PV_RSPC\tab \tab print register right justified with leading spaces.
\par PV_LEFT\tab \tab print register left justified.
\par REG_RO\tab \tab register is read only.
\par REG_HIDDEN\tab \tab register is hidden (will not appear in EXAMINE STATE).
\par REG_HRO\tab \tab register is read only and hidden.
\par REG_NZ\tab \tab new register values must be non-zero.
\par {\*\bkmkstart _Toc526228061}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 4.4\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {mtab Structure
{\*\bkmkend _Toc526228061}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\b\f1
\par }{\f1 Device-specific SHOW and SET commands are processed using the modifications array, which is allocated as contiguous array, with a NULL at the end. Each possible modification is defined with a }{\b\f1 mtab}{\f1 structure (synonym }{\b\f1 MTAB}{\f1
), which has the following fields:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 struct mtab \{
\par \tab int32\tab \tab mask;\tab \tab \tab \tab /* mask */
\par \tab int32\tab \tab match;\tab \tab \tab \tab /* match */
\par \tab char\tab \tab *pstring;\tab \tab \tab /* print string */
\par \tab char\tab \tab *mstring;\tab \tab \tab /* match string */
\par \tab t_stat\tab \tab (*valid)();\tab \tab \tab /* validation routine */
\par \};
\par }\pard \widctlpar\adjustright {\f1
\par The fields are the following:
\par
\par }\pard \li720\widctlpar\adjustright {\b\f1 mask}{\f1 \tab \tab bit mask for testing the unit.}{\b\f1 flags}{\f1 field
\par }\pard \fi-1440\li2160\widctlpar\adjustright {\b\f1 match}{\f1 \tab (SHOW) if the masked bits equal this value, }{\b\f1 pstring}{\f1 is printed
\par }{\b\f1 \tab }{\f1 (SET) if }{\b\f1 mstring}{\f1 is matched, the masked bits are set to this value
\par }{\b\f1 pstring}{\f1 \tab pointer to character string printed on a match (SHOW), or NULL
\par }{\b\f1 mstring}{\f1 \tab pointer to character string to be matched (SET), or NULL
\par }{\b\f1 valid}{\f1 \tab address of validation/display routine, or NULL if none required
\par {\*\bkmkstart _Toc526228062}{\listtext\pard\plain\s3 \f1\cgrid \hich\af1\dbch\af0\loch\f1 4.4.1\tab}}\pard\plain \s3\fi-720\li720\sb240\sa60\keepn\widctlpar\jclisttab\tx720\ls1\ilvl2\outlinelevel2\adjustright \f1\cgrid {Validation/Display Routine
{\*\bkmkend _Toc526228062}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par The validation/display routine can be used to validate input during SET processing, or to display device-specific output during SHOW processing, but not both. If }{\b\f1 mstring}{\f1 is not NULL, then the routine is a validation routine. If }{\b\f1
mstring}{\f1 is NULL, and }{\b\f1 pstring}{\f1 is not NULL, then the routine is a display routine.
\par
\par The validation routine is called during SET processing to make sure that the proposed modification is valid. It can make other state changes required by the modification or initiate additional dialogs needed by the modifier. Its calling sequence is:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat }{\i\f1 validation_routine}{\f1 (UNIT *uptr, int32 value) \endash test that }{\i\f1 uptr}{\f1 .}{\b\f1 flags}{\f1 can be set to }{\i\f1 value}{\f1 .
\par }\pard \widctlpar\adjustright {\f1
\par The display routine is called during SHOW processing to display device- or unit-specific state. Its calling sequence is:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat }{\i\f1 display_routine}{\f1 (UNIT *uptr, FILE *st) \endash output device- or unit-specific state for }{\i\f1 uptr}{\f1 to stream }{\i\f1 st}{\f1 .
\par }\pard \widctlpar\adjustright {\f1
\par When the display routine is called, SHOW has output the }{\b\f1 pstring}{\f1 argument but has not appended a newline. SHOW will append a final newline after the display routine returns.
\par {\*\bkmkstart _Toc526228063}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 4.5\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {Other Data Structures
{\*\bkmkend _Toc526228063}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par char }{\b\f1 sim_name[]}{\f1 is a character array containing the VM name.
\par
\par int32 }{\b\f1 sim_emax}{\f1 contains the maximum number of words needed to hold the largest instruction or data item in the VM. Examine and deposit will process up to }{\b\f1 sim_emax}{\f1 words.
\par
\par DEVICE *}{\b\f1 sim_devices[]}{\f1 is an array of pointers to all the devices in the VM. It is terminated by a NULL. By convention, the CPU is always the first device in the array.
\par
\par UNIT }{\b\f1 *sim_consoles[]}{\f1 is an array of pointers to the units of simulate
d consoles, alternating input and output. (If a console has only an input unit, the output slot should also point to the input unit.) This structure is only used for multi-console support. If the VM has only one console, the pointer should be NULL.
\par
\par REG *}{\b\f1 sim_PC}{\f1 points to the }{\b\f1 reg}{\f1 structure for the program counter. By convention, the PC is always the first register in the CPU\rquote s register array.
\par
\par char *}{\b\f1 sim_stop_messages[]}{\f1 is an array of pointers to character strings, corresponding to error status returns greater than zero. If }{\b\f1 sim_instr}{\f1 returns status code n > 0, then }{\b\f1 sim_stop_message[n]}{\f1 is printed by SCP.
\par
\par {\*\bkmkstart _Toc526228064}{\listtext\pard\plain\s1 \b\f1\fs28\kerning28\cgrid \hich\af1\dbch\af0\loch\f1 5.\tab}}\pard\plain \s1\fi-360\li360\sb240\sa60\keepn\widctlpar\jclisttab\tx360\ls1\outlinelevel0\adjustright \b\f1\fs28\kerning28\cgrid {
VM Provided Routines{\*\bkmkend _Toc526228064}
\par {\*\bkmkstart _Toc526228065}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 5.1\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {Instruction Execution
{\*\bkmkend _Toc526228065}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par Instruction execution is performed by routine }{\b\f1 sim_instr}{\f1 . Its calling sequence is:
\par
\par t_stat }{\b\f1 sim_instr}{\f1 (void) \endash Execute from current PC until error or halt.
\par {\*\bkmkstart _Toc526228066}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 5.2\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {Binary Load and Dump
{\*\bkmkend _Toc526228066}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par If the VM responds to the LOAD (or DUMP) command, the loader (dumper) is implemented by routine }{\b\f1 sim_load}{\f1 . Its calling sequence is:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat }{\b\f1 sim_load}{\f1 (FILE *fptr, char *buf, char *fnam, t_bool flag) - If }{\i\f1 flag}{\f1 = 0, load data from binary file }{\i\f1 fptr}{\f1 . If }{\i\f1 flag}{\f1 = 1, dump data to binary file }{
\i\f1 fptr}{\f1 . For either command, }{\i\f1 buf}{\f1 contains any VM-specific arguments, and }{\i\f1 fnam}{\f1 contains the file name.
\par }\pard \widctlpar\adjustright {\f1
\par If LOAD or DUMP is not implemented, }{\b\f1 sim_load}{\f1 should simply return SCPE_ARG. The LOAD and DUMP commands open and close the specified file for }{\b\f1 sim_load}{\f1 .
\par {\*\bkmkstart _Toc526228067}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 5.3\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {
Symbolic Examination and Deposit{\*\bkmkend _Toc526228067}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par If the VM provides symbolic examination and deposit of data, it must provide two routines, }{\b\f1 fprint_sym}{\f1 for output and }{\b\f1 parse_sym}{\f1 for input. Their calling sequences are:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 t_stat }{\b\f1 fprint_sym}{\f1 (FILE *ofile, t_addr addr, t_value *val, UNIT *uptr, int32 switch) \endash Based on the }{\i\f1 switch}{\f1 variable, symbolically output to stream }{\i\f1 ofile}{\f1
the data in array }{\i\f1 val}{\f1 at the specified }{\i\f1 addr}{\f1 in unit }{\i\f1 uptr}{\f1 .
\par
\par t_stat }{\b\f1 parse_sym}{\f1 (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 switch) \endash Based on the }{\i\f1 switch}{\f1 variable, parse character string }{\i\f1 cptr}{\f1 for a symbolic value }{\i\f1 val}{\f1 at the specified }{
\i\f1 addr}{\f1 in unit }{\i\f1 uptr}{\f1 .
\par }\pard \widctlpar\adjustright {\f1
\par If symbolic processing is not implemented, or the output value or input string cannot be parsed, these routines should return SCPE_ARG. If the processing
was successful and consumed more than a single word, then these routines should return extra number of words (not bytes) consumed as a }{\b\f1 negative}{\f1
number. If the processing was successful and consumed a single word, then these routines should return SCPE_OK. For example, PDP-11 }{\b\f1 parse_sym}{\f1 would respond as follows to various inputs:
\par
\par \tab input\tab \tab \tab \tab return value
\par
\par \tab XYZGH\tab \tab \tab \tab SCPE_ARG
\par \tab MOV R0,R1\tab \tab \tab SCPE_OK
\par \tab MOV #4,R5\tab \tab \tab -1
\par \tab MOV 1234,5670\tab \tab -2
\par
\par The interpretation of switch values is arbitrary, but the following are used by existing VM\rquote s:
\par
\par \tab switch\tab \tab \tab \tab interpretation
\par
\par \tab -a\tab \tab \tab \tab single character
\par \tab -c\tab \tab \tab \tab character string
\par \tab -m\tab \tab \tab \tab instruction mnemonic
\par
\par In addition, on input, a leading \lquote (apostrophe) is interpreted to mean a single character, and a leading \ldblquote (double quote) is interpreted to mean a character string.
\par {\*\bkmkstart _Toc526228068}{\listtext\pard\plain\s2 \b\i\f1\cgrid \hich\af1\dbch\af0\loch\f1 5.4\tab}}\pard\plain \s2\fi-390\li390\sb240\sa60\keepn\widctlpar\jclisttab\tx390\ls1\ilvl1\outlinelevel1\adjustright \b\i\f1\cgrid {
Multi-Terminal Support (Telnet){\*\bkmkend _Toc526228068}
\par }\pard\plain \widctlpar\adjustright \fs20\cgrid {\f1
\par SIMH supports the use of multiple terminals. All terminals except the console are accessed via Telnet. SIMH provides two supporting
libraries for implementing multiple terminals: sim_tmxr.c (and its header file, sim_tmxr.h), which provide OS-independent support routines for terminal multiplexors; and sim_sock.c (and its header file, sim_sock.h), which provide OS-dependent socket routi
nes. Sim_sock.c is presently implemented only under Windows and UNIX.
\par
\par Two basic data structures define the multiple terminals. Individual lines are defined by the }{\b\f1 tmln}{\f1 structure (typedef }{\b\f1 TMLN}{\f1 ):
\par
\par }\pard \li720\widctlpar\adjustright {\f1 struct tmln \{
\par \tab SOCKET\tab conn;\tab \tab \tab \tab /* line conn */
\par \tab uint32\tab \tab ipad;\tab \tab \tab \tab /* IP address */
\par \tab uint32\tab \tab cnms;\tab \tab \tab \tab /* connect time ms */
\par \tab int32\tab \tab tsta;\tab \tab \tab \tab /* Telnet state */
\par \tab int32\tab \tab rcve;\tab \tab \tab \tab /* rcv enable */
\par \tab int32\tab \tab xmte;\tab \tab \tab \tab /* xmt enable */
\par \tab int32\tab \tab dstb;\tab \tab \tab \tab /* disable Tlnt bin */
\par \tab int32\tab \tab rxbpr;\tab \tab \tab \tab /* rcv buf remove */
\par \tab int32\tab \tab rxbpi;\tab \tab \tab \tab /* rcv buf insert */
\par \tab int32\tab \tab rxcnt;\tab \tab \tab \tab /* rcv count */
\par \tab int32\tab \tab txbpr;\tab \tab \tab \tab /* xmt buf remove */
\par \tab int32\tab \tab txbpi;\tab \tab \tab \tab /* xmt buf insert */
\par \tab int32\tab \tab txcnt;\tab \tab \tab \tab /* xmt count */
\par \tab uint8\tab \tab rxb[TMXR_MAXBUF];\tab \tab /* rcv buffer */
\par \tab uint8\tab \tab txb[TMXR_MAXBUF];\tab \tab /* xmt buffer */
\par \tab \};
\par }\pard \widctlpar\adjustright {\f1
\par The fields are the following:
\par
\par \tab }{\b\f1 conn}{\f1 \tab \tab connection socket (0 = disconnected)
\par \tab }{\b\f1 tsta}{\f1 \tab \tab Telnet state
\par \tab }{\b\f1 rcve}{\f1 \tab \tab receive enable flag (0 = disabled)
\par \tab }{\b\f1 xmte}{\f1 \tab \tab transmit flow control flag (0 = transmit disabled)
\par \tab }{\b\f1 dstb}{\f1 \tab \tab Telnet bin mode disabled
\par \tab }{\b\f1 rxbp}{\f1 r\tab \tab receive buffer remove pointer
\par \tab }{\b\f1 rxbpi}{\f1 \tab \tab receive buffer insert pointer
\par \tab }{\b\f1 rxcnt}{\f1 \tab \tab receive count
\par \tab }{\b\f1 txbpr}{\f1 \tab \tab transmit buffer remove pointer
\par \tab }{\b\f1 txbpi}{\f1 \tab \tab transmit buffer insert pointer
\par \tab }{\b\f1 txcnt}{\f1 \tab \tab transmit count
\par }\pard \fi720\widctlpar\adjustright {\b\f1 rxb}{\f1 \tab \tab receive buffer
\par }\pard \widctlpar\adjustright {\f1 \tab }{\b\f1 txb}{\f1 \tab \tab transmit buffer
\par
\par The overall set of extra terminals is defined by the }{\b\f1 tmxr}{\f1 structure (typedef }{\b\f1 TMXR}{\f1 ):
\par
\par }\pard \li720\widctlpar\adjustright {\f1 struct tmxr \{
\par \tab int32\tab \tab lines;\tab \tab \tab \tab /* # lines */
\par \tab SOCKET\tab master;\tab \tab \tab \tab /* master socket */
\par \tab TMLN\tab \tab *ldsc[TMXR_MAXLIN];\tab \tab /* line descriptors */
\par \tab \};
\par }\pard \widctlpar\adjustright {\f1
\par The fields are the following:
\par
\par \tab }{\b\f1 lines}{\f1 \tab \tab number of lines (constant)
\par \tab }{\b\f1 master}{\f1 \tab \tab master listening socket (specified by ATTACH command)
\par \tab }{\b\f1 ldsc}{\f1 \tab \tab array of line descriptors
\par
\par Library sim_tmxr.c provides the following routines to support Telnet-based terminals:
\par
\par }\pard \li720\widctlpar\adjustright {\f1 int32 }{\b\f1 tmxr_poll_conn}{\f1 (TMXR *mp, UNIT *uptr) \endash poll for a new connection to the terminals described by }{\i\f1 mp }{\f1 and unit }{\i\f1 uptr}{\f1
. If there is a new connection, the routine resets all the line descriptor state (including receive enable) and returns the line number (index to line descriptor) for the new connection. If there isn\rquote t a new connection, the routine returns
\endash 1.
\par
\par void }{\b\f1 tmxr_reset_ln}{\f1 (TMLN *lp) \endash reset the line described by }{\i\f1 lp}{\f1 . The connection is closed and all line descriptor state is reset.
\par
\par int32 }{\b\f1 tmxr_getc_ln}{\f1 (TMLN *lp) \endash return the next available character from the line described by }{\i\f1 lp}{\f1 . If a character is available, the return variable is:
\par
\par \tab (1 << TMXR_V_VALID) | character
\par
\par If no character is available, the return variable is 0.
\par
\par void }{\b\f1 tmxr_poll_rx}{\f1 (TMXR *mp) \endash poll for input available on the terminals described by }{\i\f1 mp}{\f1 .
\par
\par void }{\b\f1 tmxr_rqln}{\f1 (TMLN *lp) \endash return the number of characters in the receive queue of the line described by }{\i\f1 lp}{\f1 .
\par
\par }\pard\plain \s17\li720\widctlpar\adjustright \f1\fs20\cgrid {void }{\b tmxr_putc_ln}{ (TMLN *lp, int32 chr) \endash output character }{\i chr }{to the line described by }{\i lp}{.
\par }\pard\plain \li720\widctlpar\adjustright \fs20\cgrid {\f1
\par }\pard\plain \s17\li720\widctlpar\adjustright \f1\fs20\cgrid {void }{\b tmxr_poll_tx}{ (TMXR *mp) \endash poll for output complete on the terminals described by }{\i mp}{.
\par }\pard\plain \li720\widctlpar\adjustright \fs20\cgrid {\f1
\par }{\f1 void }{\b\f1 tmxr_}{\b\f1 t}{\b\f1 qln}{\f1 (TMLN *lp) \endash return the number of characters in the }{\f1 transmit}{\f1 queue of the line described by }{\i\f1 lp}{\f1 .
\par
\par }{\f1 t_stat }{\b\f1 tmxr_attach}{\f1 (TMXR *mp, UNIT *uptr, char *cptr) \endash attach the port contained in character string }{\i\f1 cptr}{\f1 to the terminals described by }{\i\f1 mp}{\f1 and unit }{\i\f1 uptr}{\f1 .
\par
\par }\pard\plain \s17\li720\widctlpar\adjustright \f1\fs20\cgrid {t_stat }{\b tmxr_detach}{ (TMXR *mp, UNIT *uptr) \endash detach all connections for the terminals described by }{\i mp}{ and unit }{\i uptr}{.
\par }\pard\plain \li720\widctlpar\adjustright \fs20\cgrid {\f1
\par t_stat }{\b\f1 tmxr_ex}{\f1 (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw) \endash stub examine routine, needed because the extra terminals are marked as attached; always returns an error.
\par
\par t_stat }{\b\f1 tmxr_dep}{\f1 (t_value val, t_addr addr, UNIT *uptr, int32 sw) \endash stub deposit routine, needed because the extra terminals are marked as detached; always returns an error.
\par }\pard \li360\widctlpar\adjustright {\f1
\par }\pard \fi360\li360\widctlpar\adjustright {\f1 void }{\b\f1 tmxr_msg}{\f1 (SOCKET sock, char *msg) \endash output character string }{\i\f1 msg}{\f1 to socket }{\i\f1 sock}{\f1 .
\par }\pard \widctlpar\adjustright {\f1
\par }\pard \widctlpar\outlinelevel0\adjustright {\f1 The OS-dependent socket routines should not need to be accessed by the terminal simulators.
\par }\pard \widctlpar\adjustright {\f1
\par }}