├── .gitattributes
├── .gitignore
├── Contralto.sln
├── Contralto
├── App.config
├── Contralto.cfg
├── Contralto.csproj
├── Disks
│ ├── animation.dsk
│ ├── bcpl.dsk
│ ├── bravox54.dsk
│ ├── diag.dsk
│ ├── games.dsk
│ ├── music.dsk
│ ├── nonprog.dsk
│ ├── spruce-server-t300.zip
│ ├── spruce-server.dsk
│ └── xmsmall.dsk
├── Program.cs
├── app.manifest
├── packages.config
└── readme.txt
├── ContraltoLib
├── AltoSystem.cs
├── CPU
│ ├── ALU.cs
│ ├── CPU.cs
│ ├── ConstantMemory.cs
│ ├── MicroInstruction.cs
│ ├── NovaDisassembler.cs
│ ├── Shifter.cs
│ ├── Tasks
│ │ ├── CursorTask.cs
│ │ ├── DiskTask.cs
│ │ ├── DisplayHorizontalTask.cs
│ │ ├── DisplayVerticalTask.cs
│ │ ├── DisplayWordTask.cs
│ │ ├── EmulatorTask.cs
│ │ ├── EthernetTask.cs
│ │ ├── MemoryRefreshTask.cs
│ │ ├── OrbitTask.cs
│ │ ├── ParityTask.cs
│ │ ├── Task.cs
│ │ └── TridentTask.cs
│ ├── UCodeDisassembler.cs
│ └── UCodeMemory.cs
├── Configuration.cs
├── ContraltoLib.csproj
├── Conversion.cs
├── Disassembly
│ ├── MesaROM.mu
│ ├── altoIIcode3.mu
│ └── altocode24.mu
├── Display
│ ├── DisplayController.cs
│ └── IAltoDisplay.cs
├── ExecutionController.cs
├── HighResTimer.cs
├── IClockable.cs
├── IO
│ ├── AudioDAC.cs
│ ├── DiabloDrive.cs
│ ├── DiskController.cs
│ ├── DiskPack.cs
│ ├── DoverROS.cs
│ ├── EthernetController.cs
│ ├── HostEthernetEncapsulation.cs
│ ├── IAudioSink.cs
│ ├── IPacketEncapsulation.cs
│ ├── Keyboard.cs
│ ├── MouseAndKeyset.cs
│ ├── OrbitController.cs
│ ├── OrganKeyboard.cs
│ ├── Printing
│ │ ├── IPageSink.cs
│ │ ├── NullPageSink.cs
│ │ └── PdfPageSink.cs
│ ├── TridentController.cs
│ ├── TridentDrive.cs
│ └── UDPEncapsulation.cs
├── Logging
│ └── Log.cs
├── Memory
│ ├── IMemoryMappedDevice.cs
│ ├── Memory.cs
│ └── MemoryBus.cs
├── ROM
│ ├── ACSOURCE.NEW
│ ├── ACSOURCE.OLD
│ ├── AltoI
│ │ ├── 00_23.BIN
│ │ ├── 01_23.BIN
│ │ ├── 02_23.BIN
│ │ ├── 03_23.BIN
│ │ ├── 04_23.BIN
│ │ ├── 05_23.BIN
│ │ ├── 06_23.BIN
│ │ ├── 07_23.BIN
│ │ ├── 10_23.BIN
│ │ ├── 11_23.BIN
│ │ ├── 12_23.BIN
│ │ ├── 13_23.BIN
│ │ ├── 14_23.BIN
│ │ ├── 15_23.BIN
│ │ ├── 16_23.BIN
│ │ ├── 17_23.BIN
│ │ ├── 20_23.BIN
│ │ ├── 21_23.BIN
│ │ ├── 22_23.BIN
│ │ ├── 23_23.BIN
│ │ ├── 24_23.BIN
│ │ ├── 25_23.BIN
│ │ ├── 26_23.BIN
│ │ ├── 27_23.BIN
│ │ ├── 30_23.BIN
│ │ ├── 31_23.BIN
│ │ ├── 32_23.BIN
│ │ ├── 33_23.BIN
│ │ ├── 34_23.BIN
│ │ ├── 35_23.BIN
│ │ ├── 36_23.BIN
│ │ ├── 37_23.BIN
│ │ ├── C0_23.BIN
│ │ ├── C1_23.BIN
│ │ ├── C2_23.BIN
│ │ └── C3_23.BIN
│ └── AltoII
│ │ ├── C0
│ │ ├── C1
│ │ ├── C2
│ │ ├── C3
│ │ ├── U52
│ │ ├── U53
│ │ ├── U54
│ │ ├── U55
│ │ ├── U60
│ │ ├── U61
│ │ ├── U62
│ │ ├── U63
│ │ ├── U64
│ │ ├── U65
│ │ ├── U70
│ │ ├── U71
│ │ ├── U72
│ │ ├── U73
│ │ ├── U74
│ │ └── U75
├── Scheduler.cs
└── Scripting
│ ├── CommandExecutor.cs
│ ├── ControlCommands.cs
│ ├── DebuggerAttributes.cs
│ ├── ScriptAction.cs
│ ├── ScriptManager.cs
│ ├── ScriptPlayback.cs
│ ├── ScriptReader.cs
│ ├── ScriptRecorder.cs
│ └── ScriptWriter.cs
├── ContraltoUI
├── App.axaml
├── App.axaml.cs
├── Assets
│ ├── Alto.ico
│ └── DisplayCursor.png
├── ContraltoUI.csproj
├── Converters
│ ├── BoolToWindowStateConverter.cs
│ └── EnumToBoolConverter.cs
├── HighResolutionTimer.cs
├── SDLAudioSink.cs
├── ViewModels
│ ├── AltoUIViewModel.cs
│ ├── ConfigurationViewModel.cs
│ ├── LogViewModel.cs
│ └── ViewModelBase.cs
└── Views
│ ├── AboutDialog.axaml
│ ├── AboutDialog.axaml.cs
│ ├── AlternateBootDialog.axaml
│ ├── AlternateBootDialog.axaml.cs
│ ├── AltoDisplay.axaml
│ ├── AltoDisplay.axaml.cs
│ ├── ConfigurationDialog.axaml
│ ├── ConfigurationDialog.axaml.cs
│ ├── DebuggerWindow.axaml
│ ├── DebuggerWindow.axaml.cs
│ ├── LogWindow.axaml
│ ├── LogWindow.axaml.cs
│ ├── MainWindow.axaml
│ └── MainWindow.axaml.cs
├── Directory.Build.props
├── LICENSE
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Contralto.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.33627.172
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContraltoUI", "ContraltoUI\ContraltoUI.csproj", "{E84024BF-708F-403A-8306-2D39BC8CA8E3}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Contralto", "Contralto\Contralto.csproj", "{32B69575-A26F-4B09-9C7A-228B9CCD1C27}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ContraltoLib", "ContraltoLib\ContraltoLib.csproj", "{F679C754-43AE-4199-B22B-460F8F3E0E52}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {E84024BF-708F-403A-8306-2D39BC8CA8E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {E84024BF-708F-403A-8306-2D39BC8CA8E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {E84024BF-708F-403A-8306-2D39BC8CA8E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {E84024BF-708F-403A-8306-2D39BC8CA8E3}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {32B69575-A26F-4B09-9C7A-228B9CCD1C27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {32B69575-A26F-4B09-9C7A-228B9CCD1C27}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {32B69575-A26F-4B09-9C7A-228B9CCD1C27}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {32B69575-A26F-4B09-9C7A-228B9CCD1C27}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {F679C754-43AE-4199-B22B-460F8F3E0E52}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {F679C754-43AE-4199-B22B-460F8F3E0E52}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {F679C754-43AE-4199-B22B-460F8F3E0E52}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {F679C754-43AE-4199-B22B-460F8F3E0E52}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {A986B277-2686-4768-8F55-EDD68BA466DB}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/Contralto/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/Contralto/Contralto.cfg:
--------------------------------------------------------------------------------
1 | # contralto.cfg:
2 | #
3 | # This file contains configuration parameters for ContrAlto.
4 | # All integers are specified in octal.
5 | #
6 |
7 | # System configuration
8 | SystemType = TwoKRom
9 | HostAddress = 42
10 |
11 | # Host networking configuration
12 | HostPacketInterfaceType = None
13 | HostPacketInterfaceName = None
14 |
15 | # Emulation Options
16 | ThrottleSpeed = True
17 | BootAddress = 0
18 | BootFile = 0
19 | AlternateBootType = Ethernet
20 |
21 | # Display / Interface options
22 | KioskMode = False
23 | AllowKioskExit = True
24 | PauseWhenNotActive = False
25 | FullScreenStretch = False
26 | SlowPhosphorSimulation = True
27 | DisplayScale = 1
28 |
29 | # Printing options
30 | EnablePrinting = true
31 | PrintOutputPath = .
32 | ReversePageOrder = true
33 |
34 | # Disk options
35 | #
36 |
37 | # Diablo images: These specify a single image file for drive 0 and drive 1
38 | #
39 | Drive0Image = Disk\diag.dsk
40 | # Drive1Image =
41 |
42 | # Trident images: This specifies up to eight images for Trident drives 0 through 8
43 | # in a comma-delimited list. Empty entries are allowed, as below:
44 | # TridentImages = image0.dsk80, , image2.dsk300, image3.disk80
45 |
--------------------------------------------------------------------------------
/Contralto/Contralto.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | WinExe
4 |
6 | net8.0
7 | enable
8 | true
9 | app.manifest
10 | Contralto.Program
11 | 2.0.0.0
12 | 2.0.0.0
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | PreserveNewest
31 |
32 |
33 | PreserveNewest
34 |
35 |
36 | PreserveNewest
37 |
38 |
39 | PreserveNewest
40 |
41 |
42 | PreserveNewest
43 |
44 |
45 | PreserveNewest
46 |
47 |
48 | PreserveNewest
49 |
50 |
51 | PreserveNewest
52 |
53 |
54 | PreserveNewest
55 |
56 |
57 | PreserveNewest
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | PreserveNewest
78 |
79 |
80 |
81 |
82 |
83 | PreserveNewest
84 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/Contralto/Disks/animation.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/animation.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/bcpl.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/bcpl.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/bravox54.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/bravox54.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/diag.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/diag.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/games.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/games.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/music.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/music.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/nonprog.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/nonprog.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/spruce-server-t300.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/spruce-server-t300.zip
--------------------------------------------------------------------------------
/Contralto/Disks/spruce-server.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/spruce-server.dsk
--------------------------------------------------------------------------------
/Contralto/Disks/xmsmall.dsk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/Contralto/Disks/xmsmall.dsk
--------------------------------------------------------------------------------
/Contralto/Program.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using System;
24 |
25 | using Avalonia;
26 | using Avalonia.ReactiveUI;
27 | using ContraltoUI;
28 |
29 | namespace Contralto;
30 |
31 | class Program
32 | {
33 | // Initialization code. Don't use any Avalonia, third-party APIs or any
34 | // SynchronizationContext-reliant code before AppMain is called: things aren't initialized
35 | // yet and stuff might break.
36 | [STAThread]
37 | public static void Main(string[] args)
38 | {
39 | BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
40 | }
41 |
42 | // Avalonia configuration, don't remove; also used by visual designer.
43 | public static AppBuilder BuildAvaloniaApp()
44 | => AppBuilder.Configure()
45 | .UsePlatformDetect()
46 | .UseReactiveUI()
47 | .LogToTrace();
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/Contralto/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/Contralto/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/ALU.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using System.Runtime.CompilerServices;
24 |
25 | namespace Contralto.CPU
26 | {
27 | //
28 | // This implements the stripped-down version of the 74181 ALU
29 | // that the Alto exposes to the microcode, and nothing more.
30 | //
31 | static class ALU
32 | {
33 | static ALU()
34 | {
35 | Reset();
36 | }
37 |
38 | public static void Reset()
39 | {
40 | _carry = 0;
41 | }
42 |
43 | public static int Carry
44 | {
45 | get { return _carry; }
46 | set { _carry = value; }
47 | }
48 |
49 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
50 | public static ushort Execute(AluFunction fn, ushort bus, ushort t, int skip)
51 | {
52 | int r;
53 | switch (fn)
54 | {
55 | case AluFunction.Bus:
56 | _carry = 0; // M = 1
57 | r = bus;
58 | break;
59 |
60 | case AluFunction.T:
61 | _carry = 0; // M = 1
62 | r = t;
63 | break;
64 |
65 | case AluFunction.BusOrT:
66 | _carry = 0; // M = 1
67 | r = (bus | t);
68 | break;
69 |
70 | case AluFunction.BusAndT:
71 | case AluFunction.AluBusAndT:
72 | _carry = 0; // M = 1
73 | r = (bus & t);
74 | break;
75 |
76 | case AluFunction.BusXorT:
77 | _carry = 0; // M = 1
78 | r = (bus ^ t);
79 | break;
80 |
81 | case AluFunction.BusPlus1:
82 | r = bus + 1;
83 | _carry = (r > 0xffff) ? 1 : 0;
84 | break;
85 |
86 | case AluFunction.BusMinus1:
87 | r = bus - 1;
88 |
89 | // Just for clarification; the datasheet specifies:
90 | // "Because subtraction is actually performed by complementary
91 | // addition (1s complement), a carry out means borrow; thus,
92 | // a carry is generated when there is no underflow and no carry
93 | // is generated when there is underflow."
94 | _carry = (r < 0) ? 0 : 1;
95 | break;
96 |
97 | case AluFunction.BusPlusT:
98 | r = bus + t;
99 | _carry = (r > 0xffff) ? 1 : 0;
100 | break;
101 |
102 | case AluFunction.BusMinusT:
103 | r = bus - t;
104 | _carry = (r < 0) ? 0 : 1;
105 | break;
106 |
107 | case AluFunction.BusMinusTMinus1:
108 | r = bus - t - 1;
109 | _carry = (r < 0) ? 0 : 1;
110 | break;
111 |
112 | case AluFunction.BusPlusTPlus1:
113 | r = bus + t + 1;
114 | _carry = (r > 0xffff) ? 1 : 0;
115 | break;
116 |
117 | case AluFunction.BusPlusSkip:
118 | r = bus + skip;
119 | _carry = (r > 0xffff) ? 1 : 0;
120 | break;
121 |
122 | case AluFunction.BusAndNotT:
123 | r = bus & (~t);
124 | _carry = 0;
125 | break;
126 |
127 | default:
128 | throw new InvalidOperationException(String.Format("Unhandled ALU function {0}", fn));
129 | }
130 |
131 | return (ushort)r;
132 | }
133 |
134 | private static int _carry;
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/Tasks/CursorTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.CPU
24 | {
25 | public partial class AltoCPU
26 | {
27 | ///
28 | /// CursorTask provides the implementation of Cursor-specific task functions
29 | ///
30 | private sealed class CursorTask : Task
31 | {
32 | public CursorTask(AltoCPU cpu) : base(cpu)
33 | {
34 | _taskType = TaskType.Cursor;
35 | _wakeup = false;
36 | }
37 |
38 | public override void OnTaskSwitch()
39 | {
40 | // We put ourselves back to sleep immediately once we've started running.
41 | _wakeup = false;
42 | }
43 |
44 | protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
45 | {
46 | CursorF2 cf2 = (CursorF2)instruction.F2;
47 | switch (cf2)
48 | {
49 | case CursorF2.LoadXPREG:
50 | // Load cursor X-position register from bus
51 | _cpu._system.DisplayController.LoadXPREG(_busData);
52 | break;
53 |
54 | case CursorF2.LoadCSR:
55 | // Load cursor shift register from bus
56 | _cpu._system.DisplayController.LoadCSR(_busData);
57 | break;
58 |
59 | default:
60 | throw new InvalidOperationException(String.Format("Unhandled cursor F2 {0}.", cf2));
61 | }
62 | }
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/Tasks/DisplayHorizontalTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.Display;
24 |
25 | namespace Contralto.CPU
26 | {
27 | public partial class AltoCPU
28 | {
29 | ///
30 | /// DisplayHorizontalTask provides implementations of the DHT task functions.
31 | ///
32 | private sealed class DisplayHorizontalTask : Task
33 | {
34 | public DisplayHorizontalTask(AltoCPU cpu) : base(cpu)
35 | {
36 | _taskType = TaskType.DisplayHorizontal;
37 | _wakeup = false;
38 |
39 | _displayController = _cpu._system.DisplayController;
40 | }
41 |
42 | public override void OnTaskSwitch()
43 | {
44 | // We put ourselves back to sleep immediately once we've started running.
45 | _wakeup = false;
46 | }
47 |
48 | protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
49 | {
50 | DisplayHorizontalF2 dh2 = (DisplayHorizontalF2)instruction.F2;
51 | switch (dh2)
52 | {
53 | case DisplayHorizontalF2.EVENFIELD:
54 | _nextModifier |= (ushort)(_displayController.EVENFIELD ? 1 : 0);
55 | break;
56 |
57 | case DisplayHorizontalF2.SETMODE:
58 | // "If bit 0 = 1, the bit clock rate is set to 100ns period (at the start of the next scan line),
59 | // and a 1 is merged into NEXT[9]."
60 | _displayController.SETMODE(_busData);
61 |
62 | if ((_busData & 0x8000) != 0)
63 | {
64 | _nextModifier |= 1;
65 | }
66 | break;
67 |
68 | default:
69 | throw new InvalidOperationException(String.Format("Unhandled display word F2 {0}.", dh2));
70 | }
71 | }
72 |
73 | protected override void ExecuteBlock()
74 | {
75 | _displayController.DHTBLOCK = true;
76 | }
77 |
78 | private DisplayController _displayController;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/Tasks/DisplayVerticalTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.Display;
24 |
25 | namespace Contralto.CPU
26 | {
27 | public partial class AltoCPU
28 | {
29 | ///
30 | /// DisplayVerticalTask provides functionality for the DVT task
31 | ///
32 | private sealed class DisplayVerticalTask : Task
33 | {
34 | public DisplayVerticalTask(AltoCPU cpu) : base(cpu)
35 | {
36 | _taskType = TaskType.DisplayVertical;
37 | _wakeup = false;
38 |
39 | _displayController = _cpu._system.DisplayController;
40 | }
41 |
42 | public override void OnTaskSwitch()
43 | {
44 | // We put ourselves back to sleep immediately once we've started running.
45 | _wakeup = false;
46 | }
47 |
48 | protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
49 | {
50 | DisplayVerticalF2 dv2 = (DisplayVerticalF2)instruction.F2;
51 | switch (dv2)
52 | {
53 | case DisplayVerticalF2.EVENFIELD:
54 | _nextModifier |= (ushort)(_displayController.EVENFIELD ? 1 : 0);
55 | break;
56 |
57 | default:
58 | throw new InvalidOperationException(String.Format("Unhandled display vertical F2 {0}.", dv2));
59 | }
60 | }
61 |
62 | private DisplayController _displayController;
63 | }
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/Tasks/DisplayWordTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.Display;
24 |
25 |
26 | namespace Contralto.CPU
27 | {
28 | public partial class AltoCPU
29 | {
30 | ///
31 | /// DisplayWordTask provides functionality for the DWT task
32 | ///
33 | private sealed class DisplayWordTask : Task
34 | {
35 | public DisplayWordTask(AltoCPU cpu) : base(cpu)
36 | {
37 | _taskType = TaskType.DisplayWord;
38 | _wakeup = false;
39 |
40 | _displayController = _cpu._system.DisplayController;
41 | }
42 |
43 | protected override void ExecuteSpecialFunction2(MicroInstruction instruction)
44 | {
45 | DisplayWordF2 dw2 = (DisplayWordF2)instruction.F2;
46 | switch (dw2)
47 | {
48 | case DisplayWordF2.LoadDDR:
49 | _displayController.LoadDDR(_busData);
50 | break;
51 |
52 | default:
53 | throw new InvalidOperationException(String.Format("Unhandled display word F2 {0}.", dw2));
54 | }
55 | }
56 |
57 | protected override void ExecuteBlock()
58 | {
59 | _displayController.DWTBLOCK = true;
60 |
61 | //
62 | // Wake up DHT if it has not blocked itself.
63 | //
64 | if (!_displayController.DHTBLOCK)
65 | {
66 | _cpu.WakeupTask(TaskType.DisplayHorizontal);
67 | }
68 | }
69 |
70 | private DisplayController _displayController;
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/Tasks/MemoryRefreshTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.CPU
24 | {
25 | public partial class AltoCPU
26 | {
27 | ///
28 | /// DisplayWordTask provides functionality for the Memory Refresh task.
29 | ///
30 | private sealed class MemoryRefreshTask : Task
31 | {
32 | public MemoryRefreshTask(AltoCPU cpu) : base(cpu)
33 | {
34 | _taskType = TaskType.MemoryRefresh;
35 |
36 | _wakeup = false;
37 | }
38 |
39 | protected override void ExecuteSpecialFunction1Early(MicroInstruction instruction)
40 | {
41 | //
42 | // Based on readings of the below MRT microcode comment, the MRT keeps its wakeup
43 | // until it executes a BLOCK on Alto IIs. (i.e. no special wakeup handling at all.)
44 | // On Alto Is, this was accomplished by doing an MAR <- R37.
45 | //
46 | // "; This version assumes MRTACT is cleared by BLOCK, not MAR<- R37"
47 | //
48 | if (_systemType == SystemType.AltoI &&
49 | instruction.F1 == SpecialFunction1.LoadMAR &&
50 | _rSelect == 31)
51 | {
52 | BlockTask();
53 | }
54 |
55 | base.ExecuteSpecialFunction1Early(instruction);
56 | }
57 |
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/ContraltoLib/CPU/Tasks/ParityTask.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.CPU
24 | {
25 | public partial class AltoCPU
26 | {
27 | ///
28 | /// ParityTask is provided for completeness only, and implements the logic for the Parity task.
29 | /// The Parity Task will never actually be woken because I'm not planning on emulating faulty memory.
30 | ///
31 | private sealed class ParityTask : Task
32 | {
33 | public ParityTask(AltoCPU cpu) : base(cpu)
34 | {
35 | _taskType = TaskType.Parity;
36 | _wakeup = false;
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ContraltoLib/Conversion.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto
24 | {
25 | public static class Conversion
26 | {
27 | public static string ToOctal(int i)
28 | {
29 | return Convert.ToString(i, 8);
30 | }
31 |
32 | public static string ToOctal(sbyte s)
33 | {
34 | if (s < 0)
35 | {
36 | return "-" + Convert.ToString(-s, 8);
37 | }
38 | else
39 | {
40 | return Convert.ToString(s, 8);
41 | }
42 | }
43 |
44 | public static string ToOctal(int i, int digits)
45 | {
46 | string octalString = Convert.ToString(i, 8);
47 | return new String('0', digits - octalString.Length) + octalString;
48 | }
49 |
50 | ///
51 | /// Conversion from millseconds to nanoseconds
52 | ///
53 | public static readonly ulong MsecToNsec = 1000000;
54 |
55 | ///
56 | /// Conversion from nanoseconds to milliseconds
57 | ///
58 | public static readonly double NsecToMsec = 0.000001;
59 |
60 | ///
61 | /// Conversion from microseconds to nanoseconds
62 | ///
63 | public static readonly ulong UsecToNsec = 1000;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/ContraltoLib/Display/IAltoDisplay.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.Display
24 | {
25 | ///
26 | /// IAltoDisplay defines the interface necessary for generating and rendering the Alto's
27 | /// bitmapped display.
28 | ///
29 | public interface IAltoDisplay
30 | {
31 |
32 | ///
33 | /// Renders a word's worth of data to the specified scanline and word offset.
34 | ///
35 | ///
36 | ///
37 | ///
38 | ///
39 | void DrawDisplayWord(int scanline, int wordOffset, ushort dataWord, bool lowRes);
40 |
41 | ///
42 | /// Renders the cursor word for the specified scanline.
43 | ///
44 | ///
45 | ///
46 | ///
47 | ///
48 | void DrawCursorWord(int scanline, int xOffset, bool whiteOnBlack, ushort cursorWord);
49 |
50 | ///
51 | /// Indicates that an entire frame is ready for display and should be rendered.
52 | ///
53 | void Render();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ContraltoLib/IClockable.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto
24 | {
25 | ///
26 | /// Used by classes implementing devices that are clocked (i.e. that are dependent
27 | /// on time passing in units of a single CPU clock.)
28 | ///
29 | public interface IClockable
30 | {
31 | void Clock();
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/ContraltoLib/IO/AudioDAC.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.CPU;
24 | using Contralto.Memory;
25 |
26 | namespace Contralto.IO
27 | {
28 | ///
29 | /// Implements the hardware for the Audio DAC used by Ted Kaehler's
30 | /// ST-74 Music System (either the FM-synthesis "TWANG" system or the
31 | /// Sampling system.)
32 | ///
33 | public class AudioDAC : IMemoryMappedDevice
34 | {
35 | public AudioDAC()
36 | {
37 |
38 | }
39 |
40 | public void AttachSink(IAudioSink sink)
41 | {
42 | _audioSink = sink;
43 | }
44 |
45 | public void Shutdown()
46 | {
47 | if (_audioSink != null)
48 | {
49 | _audioSink.Shutdown();
50 | }
51 | }
52 |
53 | ///
54 | /// Comments in the FM synthesis microcode indicate:
55 | /// "240 SAMPLES = 18 msec"
56 | /// Which works out to about 13.3333...Khz.
57 | ///
58 | /// Unsure if this value also applies to the Sampling microcode, but
59 | /// it sounds about right in action.
60 | ///
61 | /// TODO: This is set to 13.3Khz below to allow audio production to keep up with
62 | /// the consumption on the host output side; this may be an indication that our
63 | /// execution frequency is slightly off. This should be investigated.
64 | ///
65 | public static readonly int AudioDACSamplingRate = 13000;
66 |
67 | ///
68 | /// Reads a word from the specified address.
69 | ///
70 | ///
71 | ///
72 | ///
73 | public ushort Read(int address, TaskType task, bool extendedMemory)
74 | {
75 | // The DAC is, as far as I can tell, write-only.
76 | return 0;
77 | }
78 |
79 | ///
80 | /// Writes a word to the specified address.
81 | ///
82 | ///
83 | ///
84 | public void Load(int address, ushort data, TaskType task, bool extendedMemory)
85 | {
86 | if (_audioSink != null)
87 | {
88 | _audioSink.WriteSample(data);
89 | }
90 | }
91 |
92 | ///
93 | /// Specifies the range (or ranges) of addresses decoded by this device.
94 | ///
95 | public MemoryRange[] Addresses
96 | {
97 | get { return _addresses; }
98 | }
99 |
100 | ///
101 | /// From: http://bitsavers.org/pdf/xerox/alto/memos_1975/Reserved_Alto_Memory_Locations_Jan75.pdf
102 | ///
103 | /// #177776: Digital-Analog Converter (DAC Hardware - Kaehler)
104 | ///
105 | private readonly MemoryRange[] _addresses =
106 | {
107 | new MemoryRange(0xfffe, 0xfffe),
108 | };
109 |
110 | private IAudioSink? _audioSink;
111 | }
112 |
113 | }
114 |
--------------------------------------------------------------------------------
/ContraltoLib/IO/IAudioSink.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Contralto.IO
8 | {
9 | ///
10 | /// IAudioSink provides a method for outputting audio samples to a variety of targets.
11 | ///
12 | public interface IAudioSink
13 | {
14 | ///
15 | /// Writes a single audio sample to the sink.
16 | ///
17 | ///
18 | void WriteSample(ushort sample);
19 |
20 | void Shutdown();
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ContraltoLib/IO/IPacketEncapsulation.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.IO
24 | {
25 | public delegate void ReceivePacketDelegate(MemoryStream data);
26 |
27 | ///
28 | /// Provides a generic interface for host network devices that can encapsulate
29 | /// Alto ethernet packets.
30 | ///
31 | public interface IPacketEncapsulation
32 | {
33 | ///
34 | /// Registers a callback delegate to handle packets that are received.
35 | ///
36 | ///
37 | void RegisterReceiveCallback(ReceivePacketDelegate callback);
38 |
39 | ///
40 | /// Sends the specified word array over the device.
41 | ///
42 | ///
43 | ///
44 | void Send(ushort[] packet, int length);
45 |
46 | ///
47 | /// Shuts down the encapsulation provider.
48 | ///
49 | void Shutdown();
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/ContraltoLib/IO/OrganKeyboard.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.CPU;
24 | using Contralto.Logging;
25 | using Contralto.Memory;
26 |
27 | namespace Contralto.IO
28 | {
29 | ///
30 | /// Implements the Organ Keyboard interface used by the ST-74
31 | /// Music System. Very little is known about the hardware at this time,
32 | /// so most of this is speculation or based on disassembly/reverse-engineering
33 | /// of the music system code.
34 | ///
35 | /// This is currently a stub that implements the bare minimum to make the
36 | /// music system think there's a keyboard attached to the system.
37 | ///
38 | public class OrganKeyboard : IMemoryMappedDevice
39 | {
40 | public OrganKeyboard(AltoSystem system)
41 | {
42 | _system = system;
43 | Reset();
44 | }
45 |
46 | public void Reset()
47 | {
48 | //
49 | // Initialize keyboard registers.
50 | // Based on disassembly of the Nova code that drives the keyboard
51 | // interface, the top 6 bits are active low.
52 | //
53 | for (int i = 0; i < 16; i++)
54 | {
55 | _keyData[i] = (ushort)(0xfc00);
56 | }
57 | }
58 |
59 | ///
60 | /// Reads a word from the specified address.
61 | ///
62 | ///
63 | ///
64 | ///
65 | public ushort Read(int address, TaskType task, bool extendedMemory)
66 | {
67 |
68 | Log.Write(LogType.Verbose, LogComponent.Organ, "Organ read from {0} by task {1} (bank {2}), Nova PC {3}",
69 | Conversion.ToOctal(address),
70 | task,
71 | _system.CPU.UCodeMemory.GetBank(task),
72 | Conversion.ToOctal(_system.CPU.R[6]));
73 |
74 | return _keyData[address - 0xfe60];
75 |
76 | }
77 |
78 | ///
79 | /// Writes a word to the specified address.
80 | ///
81 | ///
82 | ///
83 | public void Load(int address, ushort data, TaskType task, bool extendedMemory)
84 | {
85 |
86 | // The registers are write-only as far as I've been able to ascertain.
87 | Log.Write(LogType.Verbose, LogComponent.Organ, "Unexpected organ write to {0} ({1}) by task {2} (bank {3})",
88 | Conversion.ToOctal(address),
89 | Conversion.ToOctal(data),
90 | task,
91 | _system.CPU.UCodeMemory.GetBank(task));
92 | }
93 |
94 | ///
95 | /// Specifies the range (or ranges) of addresses decoded by this device.
96 | ///
97 | public MemoryRange[] Addresses
98 | {
99 | get { return _addresses; }
100 | }
101 |
102 |
103 | ///
104 | /// From: http://bitsavers.org/pdf/xerox/alto/memos_1975/Reserved_Alto_Memory_Locations_Jan75.pdf
105 | ///
106 | /// #177140 - #177157: Organ Keyboard (Organ Hardware - Kaehler)
107 | ///
108 | private readonly MemoryRange[] _addresses =
109 | {
110 | new MemoryRange(0xfe60, 0xfe6f),
111 | };
112 |
113 | private ushort[] _keyData = new ushort[16];
114 |
115 | private AltoSystem _system;
116 | }
117 |
118 | }
--------------------------------------------------------------------------------
/ContraltoLib/IO/Printing/IPageSink.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.IO.Printing
24 | {
25 | ///
26 | /// IPageSink defines the interface between a ROS device and physical output
27 | /// on the emulated host (be it real paper on a printer or PDF, Postscript, etc).
28 | ///
29 | public interface IPageSink
30 | {
31 | ///
32 | /// Starts a new document to be printed.
33 | ///
34 | void StartDoc();
35 |
36 | ///
37 | /// Adds a new page to the output. This is provided as a byte array containing 'height' scanlines of the specified width.
38 | ///
39 | ///
40 | ///
41 | ///
42 | void AddPage(byte[] raster, int width, int height);
43 |
44 | ///
45 | /// Ends the document being printed.
46 | ///
47 | void EndDoc();
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ContraltoLib/IO/Printing/NullPageSink.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.IO.Printing
24 | {
25 | ///
26 | /// The NullPageSink: All pages go to the bit-bucket, for the true paperless office.
27 | ///
28 | public class NullPageSink : IPageSink
29 | {
30 | public NullPageSink()
31 | {
32 |
33 | }
34 |
35 | public void StartDoc()
36 | {
37 |
38 | }
39 |
40 | public void AddPage(byte[] rasters, int width, int height)
41 | {
42 |
43 | }
44 |
45 | public void EndDoc()
46 | {
47 |
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/ContraltoLib/IO/Printing/PdfPageSink.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using iText.Kernel.Pdf;
24 | using Contralto.Logging;
25 | using iText.Layout;
26 | using iText.Kernel.Geom;
27 | using iText.Layout.Element;
28 | using iText.IO.Image;
29 | using iText.Layout.Properties;
30 |
31 | namespace Contralto.IO.Printing
32 | {
33 | ///
34 | /// PdfPageSink takes output from the ROS and turns it into
35 | /// PDF documents in the PrintOutputPath folder.
36 | ///
37 | /// This uses the iTextSharp PDF creation libraries to do the hard work.
38 | ///
39 | public class PdfPageSink : IPageSink
40 | {
41 | public PdfPageSink(Configuration configuration)
42 | {
43 | _pageImages = new List();
44 | _configuration = configuration;
45 | }
46 |
47 | public void StartDoc()
48 | {
49 | _pageImages.Clear();
50 |
51 | try
52 | {
53 | string path = System.IO.Path.Combine(
54 | _configuration.PrintOutputPath,
55 | String.Format("AltoDocument-{0}.pdf", DateTime.Now.ToString("yyyyMMdd-hhmmss")));
56 |
57 | // Start a new document.
58 |
59 | PdfDocument doc = new PdfDocument(new PdfWriter(path));
60 |
61 | // All output to a Dover printer is letter-sized.
62 | _pdf = new Document(doc, PageSize.LETTER);
63 |
64 | // Let the Orbit deal with the margins.
65 | _pdf.SetMargins(0, 0, 0, 0);
66 | }
67 | catch(Exception e)
68 | {
69 | //
70 | // Most likely we couldn't create the output file; log the failure.
71 | // All output will be relegated to the bit bucket.
72 | //
73 | _pdf = null;
74 |
75 | Log.Write(LogType.Error, LogComponent.DoverROS, "Failed to create output PDF. Error {0}", e.Message);
76 | }
77 | }
78 |
79 | public void AddPage(byte[] rasters, int width, int height)
80 | {
81 | if (_pdf != null)
82 | {
83 | ImageData pageImageData = ImageDataFactory.Create(height, width, 1 /* greyscale */, 1 /* 1bpp */, rasters, null);
84 | Image pageImage = new Image(pageImageData);
85 | pageImage.SetFixedPosition(_configuration.PageRasterOffsetX, _configuration.PageRasterOffsetY);
86 | pageImage.SetRotationAngle(90.0 * (Math.PI / 180.0));
87 |
88 | Rectangle pageRect = _pdf.GetPageEffectiveArea(PageSize.LETTER);
89 | pageImage.ScaleToFit(pageRect.GetHeight(), pageRect.GetWidth());
90 |
91 | _pageImages.Add(pageImage);
92 | }
93 | }
94 |
95 | public void EndDoc()
96 | {
97 | if (_pdf != null)
98 | {
99 | try
100 | {
101 | // Grab the configuration here so that if some joker changes the configuration
102 | // while we're printing we don't do something weird.
103 | bool reversePageOrder = _configuration.ReversePageOrder;
104 |
105 | // Actually write out the pages now, in the proper order.
106 | for (int i = 0; i < _pageImages.Count; i++)
107 | {
108 | _pdf.Add(_pageImages[reversePageOrder ? (_pageImages.Count - 1) - i : i]);
109 | _pdf.Add(new AreaBreak(i < _pageImages.Count - 1 ? AreaBreakType.NEXT_PAGE : AreaBreakType.LAST_PAGE));
110 | }
111 |
112 | _pdf.Close();
113 | }
114 | catch (Exception e)
115 | {
116 | // Something bad happened during creation, log an error.
117 | Log.Write(LogComponent.DoverROS, "Failed to create output PDF. Error {0}", e.Message);
118 | }
119 | }
120 | }
121 |
122 | ///
123 | /// List of page images in this document.
124 | /// Since Alto software typically prints the document in reverse-page-order due to the way the
125 | /// Dover produces output, we need be able to produce the PDF in reverse order.
126 | /// This uses extra memory, (about 1.7mb per page printed.)
127 | ///
128 | private List _pageImages;
129 | private Document _pdf;
130 | private Configuration _configuration;
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/ContraltoLib/Logging/Log.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | #define LOGGING_ENABLED
24 |
25 | namespace Contralto.Logging
26 | {
27 | ///
28 | /// Specifies a component to specify logging for
29 | ///
30 | [Flags]
31 | public enum LogComponent
32 | {
33 | None = 0,
34 | EmulatorTask = 0x1,
35 | DiskSectorTask = 0x2,
36 | DiskWordTask = 0x4,
37 | DiskController = 0x8,
38 | Alu = 0x10,
39 | Memory = 0x20,
40 | Keyboard = 0x40,
41 | Display = 0x80,
42 | Microcode = 0x100,
43 | CPU = 0x200,
44 | EthernetController = 0x400,
45 | EthernetTask = 0x800,
46 | TaskSwitch = 0x1000,
47 | HostNetworkInterface = 0x2000,
48 | EthernetPacket = 0x4000,
49 | Configuration = 0x8000,
50 | DAC = 0x10000,
51 | Organ = 0x20000,
52 | Orbit = 0x40000,
53 | DoverROS = 0x80000,
54 | TridentTask = 0x100000,
55 | TridentController = 0x200000,
56 | TridentDisk = 0x400000,
57 |
58 | Scripting = 0x2000000,
59 | Debug = 0x40000000,
60 | All = 0x7fffffff
61 | }
62 |
63 | ///
64 | /// Specifies the type (or severity) of a given log message
65 | ///
66 | [Flags]
67 | public enum LogType
68 | {
69 | None = 0,
70 | Normal = 0x1,
71 | Warning = 0x2,
72 | Error = 0x4,
73 | Verbose = 0x8,
74 | All = 0x7fffffff
75 | }
76 |
77 | ///
78 | /// Provides basic functionality for logging messages of all types.
79 | ///
80 | public static class Log
81 | {
82 | static Log()
83 | {
84 | _components = Configuration.LogComponents;
85 | _type = Configuration.LogTypes;
86 | _logText = new List();
87 | }
88 |
89 | public static event EventHandler? Updated;
90 |
91 | public static LogComponent LogComponents
92 | {
93 | get { return _components; }
94 | set { _components = value; }
95 | }
96 |
97 | public static IEnumerable LogText => _logText;
98 |
99 | public static void Clear()
100 | {
101 | _logText.Clear();
102 | }
103 |
104 | #if LOGGING_ENABLED
105 | ///
106 | /// Logs a message without specifying type/severity for terseness;
107 | /// will not log if Type has been set to None.
108 | ///
109 | ///
110 | ///
111 | ///
112 | public static void Write(LogComponent component, string message, params object[] args)
113 | {
114 | Write(LogType.Normal, component, message, args);
115 | }
116 |
117 | public static void Write(LogType type, LogComponent component, string message, params object[] args)
118 | {
119 | if ((_type & type) != 0 &&
120 | (_components & component) != 0)
121 | {
122 | //
123 | // My log has something to tell you...
124 | string format = $"{_logText.Count}: {component.ToString()} : {message}";
125 | string output = String.Format(format, args);
126 | _logText.Add(output);
127 |
128 | Updated?.Invoke(output, new EventArgs());
129 | }
130 | }
131 | #else
132 | public static void Write(LogComponent component, string message, params object[] args)
133 | {
134 |
135 | }
136 |
137 | public static void Write(LogType type, LogComponent component, string message, params object[] args)
138 | {
139 |
140 | }
141 |
142 | #endif
143 |
144 | private static LogComponent _components;
145 | private static LogType _type;
146 | private static List _logText;
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/ContraltoLib/Memory/IMemoryMappedDevice.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.CPU;
24 |
25 | namespace Contralto.Memory
26 | {
27 | ///
28 | /// Specifies a range of memory from Start to End, inclusive.
29 | ///
30 | public struct MemoryRange
31 | {
32 | public MemoryRange(ushort start, ushort end)
33 | {
34 | if (!(end >= start))
35 | {
36 | throw new ArgumentOutOfRangeException("end must be greater than or equal to start.");
37 | }
38 |
39 | Start = start;
40 | End = end;
41 | }
42 |
43 | public bool Overlaps(MemoryRange other)
44 | {
45 | return ((other.Start >= this.Start && other.Start <= this.End) ||
46 | (other.End >= this.Start && other.End <= this.End));
47 | }
48 |
49 | public ushort Start;
50 | public ushort End;
51 | }
52 |
53 | ///
54 | /// Specifies an interfaces for devices that appear in mapped memory. This includes
55 | /// RAM as well as regular I/O devices.
56 | ///
57 | public interface IMemoryMappedDevice
58 | {
59 | ///
60 | /// Reads a word from the specified address.
61 | ///
62 | ///
63 | ///
64 | ///
65 | ushort Read(int address, TaskType task, bool extendedMemory);
66 |
67 | ///
68 | /// Writes a word to the specified address.
69 | ///
70 | ///
71 | ///
72 | void Load(int address, ushort data, TaskType task, bool extendedMemory);
73 |
74 | ///
75 | /// Specifies the range (or ranges) of addresses decoded by this device.
76 | ///
77 | MemoryRange[] Addresses { get; }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/ContraltoLib/Memory/Memory.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.CPU;
24 | using Contralto.Logging;
25 | using System.Diagnostics.CodeAnalysis;
26 | using System.Runtime.CompilerServices;
27 |
28 | namespace Contralto.Memory
29 | {
30 | ///
31 | /// Implements the Alto's main memory, up to 4 banks of 64KW in 16-bit words.
32 | /// Provides implementation of the IIXM's memory mapping hardware.
33 | ///
34 | public class Memory : IMemoryMappedDevice
35 | {
36 | public Memory(Configuration configuration)
37 | {
38 | // Set up handled addresses based on the system type.
39 | if (configuration.SystemType == SystemType.AltoI)
40 | {
41 | _addresses = new MemoryRange[]
42 | {
43 | new MemoryRange(0, _memTop), // Main bank of RAM to 176777; IO page above this.
44 | };
45 | }
46 | else
47 | {
48 | _addresses = new MemoryRange[]
49 | {
50 | new MemoryRange(0, _memTop), // Main bank of RAM to 176777; IO page above this.
51 | new MemoryRange(_xmBanksStart, (ushort)(_xmBanksStart + 16)), // Memory bank registers
52 | };
53 | }
54 |
55 | Reset();
56 | }
57 |
58 | ///
59 | /// The top address of main memory (above which lies the I/O space)
60 | ///
61 | public static ushort RamTop
62 | {
63 | get { return _memTop; }
64 | }
65 |
66 | ///
67 | /// Full reset, clears all memory.
68 | ///
69 | [MemberNotNull(nameof(_mem), nameof(_xmBanks), nameof(_xmBanksAlternate), nameof(_xmBanksNormal))]
70 | public void Reset()
71 | {
72 | // 4 64K banks, regardless of system type. (Alto Is just won't use the extra memory.)
73 | _mem = new ushort[0x40000];
74 | _xmBanks = new ushort[16];
75 | _xmBanksAlternate = new int[16];
76 | _xmBanksNormal = new int[16];
77 | }
78 |
79 | ///
80 | /// Soft reset, clears XM bank registers.
81 | ///
82 | public void SoftReset()
83 | {
84 | _xmBanks = new ushort[16];
85 | _xmBanksAlternate = new int[16];
86 | _xmBanksNormal = new int[16];
87 | }
88 |
89 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
90 | public ushort Read(int address, TaskType task, bool extendedMemory)
91 | {
92 | // Check for XM registers; this occurs regardless of XM flag since it's in the I/O page.
93 | if (address >= _xmBanksStart && address < _xmBanksStart + 16)
94 | {
95 | // NB: While not specified in documentation, some code (IFS in particular) relies on the fact that
96 | // the upper 12 bits of the bank registers are all 1s.
97 | return (ushort)(0xfff0 | _xmBanks[address - _xmBanksStart]);
98 | }
99 | else
100 | {
101 | return _mem[address + 0x10000 * GetBankNumber(task, extendedMemory)];
102 | }
103 | }
104 |
105 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
106 | public void Load(int address, ushort data, TaskType task, bool extendedMemory)
107 | {
108 | // Check for XM registers; this occurs regardless of XM flag since it's in the I/O page.
109 | if (address >= _xmBanksStart && address < _xmBanksStart + 16)
110 | {
111 | _xmBanks[address - _xmBanksStart] = data;
112 |
113 | // Precalc bank numbers to speed memory accesses that use them
114 | _xmBanksAlternate[address - _xmBanksStart] = data & 0x3;
115 | _xmBanksNormal[address - _xmBanksStart] = (data & 0xc) >> 2;
116 |
117 | Log.Write(LogComponent.Memory, "XM register for task {0} set to bank {1} (normal), {2} (xm)",
118 | (TaskType)(address - _xmBanksStart),
119 | (data & 0xc) >> 2,
120 | (data & 0x3));
121 | }
122 | else
123 | {
124 | _mem[address + 0x10000 * GetBankNumber(task, extendedMemory)] = data;
125 | }
126 | }
127 |
128 | public MemoryRange[] Addresses
129 | {
130 | get { return _addresses; }
131 | }
132 |
133 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
134 | private int GetBankNumber(TaskType task, bool extendedMemory)
135 | {
136 | return extendedMemory ?
137 | _xmBanksAlternate[(int)task] : _xmBanksNormal[(int)task];
138 | }
139 |
140 | private readonly MemoryRange[] _addresses;
141 |
142 | private static readonly ushort _memTop = 0xfdff; // 176777
143 | private static readonly ushort _xmBanksStart = 0xffe0; // 177740
144 |
145 | private ushort[] _mem;
146 |
147 | private ushort[] _xmBanks;
148 | private int[] _xmBanksAlternate;
149 | private int[] _xmBanksNormal;
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/ACSOURCE.NEW:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/ACSOURCE.OLD:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/00_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/01_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/02_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/03_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/04_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/05_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/06_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/07_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/10_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/11_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/12_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/13_23.BIN:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/14_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/15_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/16_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/17_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/20_23.BIN:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/21_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/22_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/23_23.BIN:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/24_23.BIN:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/25_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/26_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/27_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/30_23.BIN:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/31_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/32_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/33_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/34_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/35_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/36_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/37_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/C0_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/C1_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/C2_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoI/C3_23.BIN:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/C0:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/C1:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/C2:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/C3:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U52:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U53:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U54:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U55:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U60:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U61:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U62:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U63:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U64:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U65:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U70:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U71:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U72:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U73:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U74:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/ContraltoLib/ROM/AltoII/U75:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/ContraltoLib/Scripting/DebuggerAttributes.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.Scripting
24 |
25 | {
26 | public class DebuggerFunction : Attribute
27 | {
28 | public DebuggerFunction(string commandName)
29 | {
30 | _commandName = commandName;
31 | _usage = "";
32 | _description = "";
33 | }
34 |
35 | public DebuggerFunction(string commandName, string description)
36 | {
37 | _usage = "";
38 | _commandName = commandName;
39 | _description = description;
40 | }
41 |
42 | public DebuggerFunction(string commandName, string description, string usage)
43 | {
44 | _commandName = commandName;
45 | _description = description;
46 | _usage = usage;
47 | }
48 |
49 | public string CommandName
50 | {
51 | get { return _commandName; }
52 | }
53 |
54 | public string Usage
55 | {
56 | get { return _usage; }
57 | }
58 |
59 | public string Description
60 | {
61 | get { return _description; }
62 | }
63 |
64 | private string _commandName;
65 | private string _description;
66 | private string _usage;
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/ContraltoLib/Scripting/ScriptManager.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.Logging;
24 |
25 | namespace Contralto.Scripting
26 | {
27 | public static class ScriptManager
28 | {
29 | static ScriptManager()
30 | {
31 | _scheduler = new Scheduler();
32 | }
33 |
34 | public static Scheduler ScriptScheduler
35 | {
36 | get { return _scheduler; }
37 | }
38 |
39 | ///
40 | /// Fired when playback of a script has completed or is stopped.
41 | ///
42 | public static event EventHandler? PlaybackCompleted;
43 |
44 | public static void StartRecording(AltoSystem system, string scriptPath)
45 | {
46 | // Stop any pending actions
47 | StopRecording();
48 | StopPlayback();
49 |
50 | _scriptRecorder = new ScriptRecorder(system, scriptPath);
51 |
52 | Log.Write(LogComponent.Scripting, "Starting recording to {0}", scriptPath);
53 |
54 | //
55 | // Record the absolute position of the mouse (as held in MOUSELOC in system memory).
56 | // All other mouse movements in the script will be recorded relative to this point.
57 | //
58 | int x = system.Memory.Read(0x114, CPU.TaskType.Ethernet, false);
59 | int y = system.Memory.Read(0x115, CPU.TaskType.Ethernet, false);
60 | _scriptRecorder.MouseMoveAbsolute(x, y);
61 | }
62 |
63 | public static void StopRecording()
64 | {
65 | if (IsRecording)
66 | {
67 | _scriptRecorder?.End();
68 | _scriptRecorder = null;
69 | }
70 |
71 | Log.Write(LogComponent.Scripting, "Stopped recording.");
72 | }
73 |
74 | public static void StartPlayback(AltoSystem system, string scriptPath)
75 | {
76 | // Stop any pending actions
77 | StopRecording();
78 | StopPlayback();
79 |
80 | _scheduler.Reset();
81 |
82 | _scriptPlayback = new ScriptPlayback(scriptPath, system);
83 | _scriptPlayback.PlaybackCompleted += OnPlaybackCompleted;
84 | _scriptPlayback.Start();
85 |
86 | Log.Write(LogComponent.Scripting, "Starting playback of {0}", scriptPath);
87 | }
88 |
89 | public static void StopPlayback()
90 | {
91 | if (IsPlaying)
92 | {
93 | _scriptPlayback?.Stop();
94 | _scriptPlayback = null;
95 |
96 | PlaybackCompleted?.Invoke(null, null!);
97 | }
98 |
99 | Log.Write(LogComponent.Scripting, "Stopped playback.");
100 | }
101 |
102 | public static void CompleteWait()
103 | {
104 | if (IsPlaying)
105 | {
106 | _scriptPlayback?.Start();
107 |
108 | Log.Write(LogComponent.Scripting, "Playback resumed after Wait.");
109 | }
110 | }
111 |
112 | public static ScriptRecorder? Recorder
113 | {
114 | get { return _scriptRecorder; }
115 | }
116 |
117 | public static ScriptPlayback? Playback
118 | {
119 | get { return _scriptPlayback; }
120 | }
121 |
122 | public static bool IsRecording
123 | {
124 | get { return _scriptRecorder != null; }
125 | }
126 |
127 | public static bool IsPlaying
128 | {
129 | get { return _scriptPlayback != null; }
130 | }
131 |
132 | private static void OnPlaybackCompleted(object? sender, EventArgs e)
133 | {
134 | _scriptPlayback = null;
135 | PlaybackCompleted?.Invoke(null, null!);
136 | }
137 |
138 | private static ScriptRecorder? _scriptRecorder;
139 | private static ScriptPlayback? _scriptPlayback;
140 |
141 | private static Scheduler _scheduler;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/ContraltoLib/Scripting/ScriptPlayback.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.Logging;
24 |
25 | namespace Contralto.Scripting
26 | {
27 | public class ScriptPlayback
28 | {
29 | public ScriptPlayback(string scriptFile, AltoSystem system)
30 | {
31 | _scriptReader = new ScriptReader(scriptFile);
32 | _system = system;
33 |
34 | _currentAction = null;
35 |
36 | _stopPlayback = false;
37 | }
38 |
39 | ///
40 | /// Fired when playback of the script has completed or is stopped.
41 | ///
42 | public event EventHandler? PlaybackCompleted;
43 |
44 | public void Start()
45 | {
46 | _stopPlayback = false;
47 |
48 | // Schedule first event.
49 | ScheduleNextEvent(0);
50 | }
51 |
52 | public void Stop()
53 | {
54 | // We will stop after the next event is fired (if any)
55 | _stopPlayback = true;
56 | }
57 |
58 | private void ScheduleNextEvent(ulong skewNsec)
59 | {
60 | //
61 | // Grab the next action if the current one is done.
62 | //
63 | if (_currentAction == null || _currentAction.Completed)
64 | {
65 | _currentAction = _scriptReader.ReadNext();
66 | }
67 |
68 | if (_currentAction != null)
69 | {
70 | // We have another action to queue up.
71 | Event scriptEvent = new Event(_currentAction.Timestamp, _currentAction, OnEvent);
72 | ScriptManager.ScriptScheduler.Schedule(scriptEvent);
73 |
74 | Log.Write(LogComponent.Scripting, "Queueing script action {0}", _currentAction);
75 | }
76 | else
77 | {
78 | //
79 | // Playback is complete.
80 | //
81 | Log.Write(LogComponent.Scripting, "Playback completed.");
82 | PlaybackCompleted?.Invoke(this, null!);
83 | }
84 | }
85 |
86 | private void OnEvent(ulong skewNsec, object? context)
87 | {
88 | // Replay the action.
89 | if (!_stopPlayback)
90 | {
91 | if (context == null)
92 | {
93 | throw new InvalidOperationException("Script event callback context cannot be null");
94 | }
95 |
96 | ScriptAction action = (ScriptAction)context;
97 | Log.Write(LogComponent.Scripting, "Invoking action {0}", action);
98 |
99 | action.Replay(_system);
100 |
101 | // Special case for Wait -- this causes the script to stop here until the
102 | // Alto itself tells things to start up again.
103 | //
104 | if (action is WaitAction)
105 | {
106 | Log.Write(LogComponent.Scripting, "Playback paused, awaiting wakeup from Alto.");
107 | }
108 | else
109 | {
110 | // Kick off the next action in the script.
111 | ScheduleNextEvent(skewNsec);
112 | }
113 | }
114 | else
115 | {
116 | Log.Write(LogComponent.Scripting, "Playback stopped.");
117 | PlaybackCompleted?.Invoke(this, null!);
118 | }
119 | }
120 |
121 | private AltoSystem _system;
122 | private ScriptReader _scriptReader;
123 |
124 | private ScriptAction? _currentAction;
125 |
126 | private bool _stopPlayback;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/ContraltoLib/Scripting/ScriptReader.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.Logging;
24 | using System.Diagnostics.CodeAnalysis;
25 |
26 | namespace Contralto.Scripting
27 | {
28 | public class ScriptReader
29 | {
30 | public ScriptReader(string scriptPath)
31 | {
32 | _scriptReader = new StreamReader(scriptPath);
33 | }
34 |
35 | public ScriptAction? ReadNext()
36 | {
37 | if (_scriptReader == null || _scriptReader.EndOfStream)
38 | {
39 | return null;
40 | }
41 |
42 | //
43 | // Read the next action from the script file,
44 | // skipping over comments and empty lines.
45 | //
46 | while (true)
47 | {
48 | // The below null check should not be necessary; _scriptReader will never be null.
49 | // But try convincing C#'s static analyzer of this...
50 | if (_scriptReader == null || _scriptReader.EndOfStream)
51 | {
52 | // End of the stream, return null to indicate this,
53 | // and close the stream.
54 | _scriptReader?.Close();
55 | return null;
56 | }
57 |
58 | string? line = _scriptReader?.ReadLine()?.Trim();
59 |
60 | // Skip empty or comment lines.
61 | if (string.IsNullOrWhiteSpace(line) ||
62 | line.StartsWith("#"))
63 | {
64 | continue;
65 | }
66 |
67 | try
68 | {
69 | return ScriptAction.Parse(line);
70 | }
71 | catch(Exception e)
72 | {
73 | Log.Write(LogComponent.Scripting, "Invalid script; error: {0}.", e.Message);
74 | _scriptReader?.Close();
75 | return null;
76 | }
77 | }
78 | }
79 |
80 | private readonly StreamReader _scriptReader;
81 |
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/ContraltoLib/Scripting/ScriptRecorder.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto.IO;
24 |
25 | namespace Contralto.Scripting
26 | {
27 | ///
28 | /// Records actions.
29 | ///
30 | public class ScriptRecorder
31 | {
32 | public ScriptRecorder(AltoSystem system, string scriptFile)
33 | {
34 | _script = new ScriptWriter(scriptFile);
35 | _system = system;
36 | _lastTimestamp = 0;
37 |
38 | _firstTime = true;
39 | }
40 |
41 | public void End()
42 | {
43 | _script.End();
44 | }
45 |
46 | public void KeyDown(AltoKey key)
47 | {
48 | _script.AppendAction(
49 | new KeyAction(
50 | GetRelativeTimestamp(),
51 | key,
52 | true));
53 | }
54 |
55 | public void KeyUp(AltoKey key)
56 | {
57 | _script.AppendAction(
58 | new KeyAction(
59 | GetRelativeTimestamp(),
60 | key,
61 | false));
62 | }
63 |
64 | public void MouseDown(AltoMouseButton button)
65 | {
66 | _script.AppendAction(
67 | new MouseButtonAction(
68 | GetRelativeTimestamp(),
69 | button,
70 | true));
71 | }
72 |
73 | public void MouseUp(AltoMouseButton button)
74 | {
75 | _script.AppendAction(
76 | new MouseButtonAction(
77 | GetRelativeTimestamp(),
78 | button,
79 | false));
80 | }
81 |
82 | public void MouseMoveRelative(int dx, int dy)
83 | {
84 | _script.AppendAction(
85 | new MouseMoveAction(
86 | GetRelativeTimestamp(),
87 | dx,
88 | dy,
89 | false));
90 | }
91 |
92 | public void MouseMoveAbsolute(int dx, int dy)
93 | {
94 | _script.AppendAction(
95 | new MouseMoveAction(
96 | GetRelativeTimestamp(),
97 | dx,
98 | dy,
99 | true));
100 | }
101 |
102 | public void Command(string command)
103 | {
104 | _script.AppendAction(
105 | new CommandAction(
106 | GetRelativeTimestamp(),
107 | command));
108 | }
109 |
110 | private ulong GetRelativeTimestamp()
111 | {
112 | if (_firstTime)
113 | {
114 | _firstTime = false;
115 | //
116 | // First item recorded, occurs at relative timestamp 0.
117 | //
118 | _lastTimestamp = ScriptManager.ScriptScheduler.CurrentTimeNsec;
119 | return 0;
120 | }
121 | else
122 | {
123 | //
124 | // relative time is delta between current system timestamp and the last
125 | // recorded entry.
126 | ulong relativeTimestamp = ScriptManager.ScriptScheduler.CurrentTimeNsec - _lastTimestamp;
127 | _lastTimestamp = ScriptManager.ScriptScheduler.CurrentTimeNsec;
128 |
129 | return relativeTimestamp;
130 | }
131 | }
132 |
133 | private AltoSystem _system;
134 | private ulong _lastTimestamp;
135 | private bool _firstTime;
136 | private ScriptWriter _script;
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/ContraltoLib/Scripting/ScriptWriter.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | namespace Contralto.Scripting
24 | {
25 | ///
26 | ///
27 | ///
28 | public class ScriptWriter
29 | {
30 | public ScriptWriter(string scriptPath)
31 | {
32 | _scriptWriter = new StreamWriter(scriptPath);
33 | }
34 |
35 | ///
36 | /// Adds a new ScriptAction to the queue
37 | ///
38 | ///
39 | public void AppendAction(ScriptAction action)
40 | {
41 | if (_scriptWriter == null)
42 | {
43 | throw new InvalidOperationException("Cannot write to closed ScriptWriter.");
44 | }
45 |
46 | _scriptWriter.WriteLine(action.ToString());
47 | }
48 |
49 | public void End()
50 | {
51 | _scriptWriter?.Close();
52 | _scriptWriter = null;
53 | }
54 |
55 | private StreamWriter? _scriptWriter;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/ContraltoUI/App.axaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/ContraltoUI/App.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia;
24 | using Avalonia.Controls.ApplicationLifetimes;
25 | using Avalonia.Data.Core.Plugins;
26 | using Avalonia.Markup.Xaml;
27 | using Contralto;
28 | using ContraltoUI.ViewModels;
29 | using ContraltoUI.Views;
30 | using System;
31 |
32 | namespace ContraltoUI;
33 |
34 | public partial class App : Application
35 | {
36 | public override void Initialize()
37 | {
38 | AvaloniaXamlLoader.Load(this);
39 | }
40 |
41 | public override void OnFrameworkInitializationCompleted()
42 | {
43 | IClassicDesktopStyleApplicationLifetime? desktop = ApplicationLifetime as IClassicDesktopStyleApplicationLifetime;
44 |
45 | if (desktop == null)
46 | {
47 | return;
48 | }
49 |
50 | ParseArgs(desktop.Args);
51 |
52 | // TODO: move this inside AltoUIViewModel entirely?
53 | Configuration config = new Configuration(true);
54 | _system = new AltoSystem(config);
55 |
56 | if (config.EnableAudioDAC)
57 | {
58 | SDLAudioSink audioSink = new SDLAudioSink();
59 | _system.AudioDAC.AttachSink(audioSink);
60 | }
61 |
62 | AltoUIViewModel vm = new AltoUIViewModel(_system);
63 |
64 | // Line below is needed to remove Avalonia data validation.
65 | // Without this line you will get duplicate validations from both Avalonia and CT
66 | BindingPlugins.DataValidators.RemoveAt(0);
67 |
68 | desktop.MainWindow = new MainWindow()
69 | {
70 | DataContext = vm
71 | };
72 |
73 |
74 | base.OnFrameworkInitializationCompleted();
75 | }
76 |
77 | private void ParseArgs(string[]? args)
78 | {
79 | if (args == null || args.Length == 0)
80 | {
81 | return;
82 | }
83 |
84 | for (int i = 0; i < args.Length; i++)
85 | {
86 | switch (args[i++].ToLowerInvariant())
87 | {
88 | case "-config":
89 | if (i < args.Length)
90 | {
91 | StartupOptions.ConfigurationFile = args[i];
92 | }
93 | else
94 | {
95 | PrintUsage();
96 | return;
97 | }
98 | break;
99 |
100 | case "-script":
101 | if (i < args.Length)
102 | {
103 | StartupOptions.ScriptFile = args[i];
104 | }
105 | else
106 | {
107 | PrintUsage();
108 | return;
109 | }
110 | break;
111 |
112 | case "-rompath":
113 | if (i < args.Length)
114 | {
115 | StartupOptions.RomPath = args[i];
116 | }
117 | else
118 | {
119 | PrintUsage();
120 | return;
121 | }
122 | break;
123 |
124 | default:
125 | PrintUsage();
126 | return;
127 | }
128 | }
129 | }
130 |
131 | private static void PrintUsage()
132 | {
133 | Console.WriteLine("Usage: ContrAlto [-config ] [-script ]");
134 | }
135 |
136 | private AltoSystem _system = null!;
137 | }
138 |
--------------------------------------------------------------------------------
/ContraltoUI/Assets/Alto.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/ContraltoUI/Assets/Alto.ico
--------------------------------------------------------------------------------
/ContraltoUI/Assets/DisplayCursor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jdersch/Contralto2/3fa39763320c9fcf6ca6baf5ae94bbc0f38a95c5/ContraltoUI/Assets/DisplayCursor.png
--------------------------------------------------------------------------------
/ContraltoUI/ContraltoUI.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net8.0
4 | enable
5 | latest
6 | 2.0.0.0
7 | 2.0.0.0
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | AltoDisplay.axaml
39 |
40 |
41 | LogWindow.axaml
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/ContraltoUI/Converters/BoolToWindowStateConverter.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Data.Converters;
24 | using Avalonia.Data;
25 | using System;
26 | using System.Globalization;
27 | using Avalonia.Controls;
28 |
29 | namespace ContraltoUI.Converters
30 | {
31 | public class BoolToWindowStateConverter : IValueConverter
32 | {
33 | public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
34 | {
35 | if (value == null)
36 | {
37 | return false;
38 | }
39 |
40 | WindowState? val = (bool)value ? WindowState.FullScreen : WindowState.Normal;
41 | return val;
42 | }
43 |
44 | public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
45 | {
46 | throw new NotSupportedException();
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/ContraltoUI/Converters/EnumToBoolConverter.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Data.Converters;
24 | using Avalonia.Data;
25 | using System;
26 | using System.Globalization;
27 |
28 | namespace ContraltoUI.Converters
29 | {
30 | public class EnumToBoolConverter : IValueConverter
31 | {
32 | public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
33 | {
34 | return value?.Equals(parameter);
35 | }
36 |
37 | public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
38 | {
39 | return value?.Equals(true) == true ? parameter : BindingOperations.DoNothing;
40 | }
41 | }
42 |
43 | public class InvertedEnumToBoolConverter : IValueConverter
44 | {
45 | public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
46 | {
47 | return !value?.Equals(parameter);
48 | }
49 |
50 | public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
51 | {
52 | return !value?.Equals(true) == true ? parameter : BindingOperations.DoNothing;
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ContraltoUI/HighResolutionTimer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Threading;
4 |
5 |
6 | namespace ContraltoUI
7 | {
8 | ///
9 | /// High-Resolution timer for frame-rate throttling; based on a gist at https://gist.github.com/DraTeots/436019368d32007284f8a12f1ba0f545
10 | ///
11 | public class HighResolutionTimer
12 | {
13 | ///
14 | /// Tick time length in [ms]
15 | ///
16 | public static readonly double TickLength = 1000f / Stopwatch.Frequency;
17 |
18 | ///
19 | /// Tick frequency
20 | ///
21 | public static readonly double Frequency = Stopwatch.Frequency;
22 |
23 | ///
24 | /// True if the system/operating system supports HighResolution timer
25 | ///
26 | public static bool IsHighResolution = Stopwatch.IsHighResolution;
27 |
28 | ///
29 | /// Indicates whether the timer is currently running.
30 | ///
31 | public bool IsRunning => _isRunning;
32 |
33 |
34 | ///
35 | /// Creates timer with interval in [ms]
36 | ///
37 | /// Interval time in [ms]
38 | public HighResolutionTimer(float interval)
39 | {
40 | Interval = interval;
41 | _event = new AutoResetEvent(false);
42 | }
43 |
44 | ///
45 | /// The interval of a timer in [ms]
46 | ///
47 | public float Interval
48 | {
49 | get { return _interval; }
50 | set
51 | {
52 | if (value < 0f || Single.IsNaN(value))
53 | {
54 | throw new ArgumentOutOfRangeException(nameof(value));
55 | }
56 | _interval = value;
57 | }
58 | }
59 |
60 | ///
61 | /// If true, sets the execution thread to ThreadPriority.Highest
62 | /// (works after the next Start())
63 | ///
64 | ///
65 | /// It might help in some cases and get things worse in others.
66 | /// It suggested that you do some studies if you apply
67 | ///
68 | public bool UseHighPriorityThread { get; set; } = false;
69 |
70 | ///
71 | /// Starts the timer
72 | ///
73 | public void Start()
74 | {
75 | if (_isRunning)
76 | {
77 | return;
78 | }
79 |
80 | _isRunning = true;
81 | _thread = new Thread(ExecuteTimer)
82 | {
83 | IsBackground = true,
84 | };
85 |
86 | if (UseHighPriorityThread)
87 | {
88 | _thread.Priority = ThreadPriority.Highest;
89 | }
90 | _thread.Start();
91 | }
92 |
93 | ///
94 | /// Stops the timer
95 | ///
96 | ///
97 | /// This function is waiting an executing thread (which do to stop and join.
98 | ///
99 | public void Stop(bool joinThread = true)
100 | {
101 | if (!_isRunning || _thread == null)
102 | {
103 | return;
104 | }
105 |
106 | _isRunning = false;
107 |
108 | if (joinThread && Thread.CurrentThread != _thread)
109 | {
110 | _thread.Join();
111 | }
112 | }
113 |
114 | ///
115 | /// Waits for the timer to tick.
116 | ///
117 | public void Wait()
118 | {
119 | _event.WaitOne();
120 | }
121 |
122 | private void ExecuteTimer()
123 | {
124 | float nextTrigger = 0f;
125 |
126 | Stopwatch stopwatch = new Stopwatch();
127 | stopwatch.Start();
128 |
129 | while (_isRunning)
130 | {
131 | nextTrigger += _interval;
132 | double elapsed;
133 |
134 | while (true)
135 | {
136 | elapsed = ElapsedHiRes(stopwatch);
137 | double diff = nextTrigger - elapsed;
138 | if (diff <= 0.0f)
139 | {
140 | break;
141 | }
142 |
143 | if (diff < 1.0f)
144 | {
145 | Thread.SpinWait(10);
146 | }
147 | else if (diff < 5.0f)
148 | {
149 | Thread.SpinWait(100);
150 | }
151 | else if (diff < 15.0f)
152 | {
153 | Thread.Sleep(1);
154 | }
155 | else
156 | {
157 | Thread.Sleep(10);
158 | }
159 |
160 | if (!_isRunning)
161 | {
162 | return;
163 | }
164 | }
165 |
166 | double delay = elapsed - nextTrigger;
167 | _event.Set();
168 |
169 | if (!_isRunning)
170 | {
171 | return;
172 | }
173 |
174 | // restarting the timer in every hour to prevent precision problems
175 | if (stopwatch.Elapsed.TotalHours >= 1d)
176 | {
177 | stopwatch.Restart();
178 | nextTrigger = 0f;
179 | }
180 | }
181 |
182 | stopwatch.Stop();
183 | }
184 |
185 | private static double ElapsedHiRes(Stopwatch stopwatch)
186 | {
187 | return stopwatch.ElapsedTicks * TickLength;
188 | }
189 |
190 |
191 | private volatile float _interval;
192 | private volatile bool _isRunning;
193 | private Thread? _thread;
194 | private AutoResetEvent _event;
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/ContraltoUI/SDLAudioSink.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Concurrent;
3 | using System.Runtime.InteropServices;
4 | using Contralto.IO;
5 | using Contralto.Logging;
6 | using SDL2;
7 |
8 | namespace ContraltoUI
9 | {
10 | public class SDLAudioSink : IAudioSink
11 | {
12 | public SDLAudioSink()
13 | {
14 | InitializeSDL();
15 | _audioBuffer = new ConcurrentQueue();
16 | _sampleBuffer = new byte[0x10000];
17 | }
18 |
19 | public void WriteSample(ushort sample)
20 | {
21 | _audioBuffer.Enqueue(sample);
22 | }
23 |
24 | public void Shutdown()
25 | {
26 | SDL.SDL_Quit();
27 | }
28 |
29 | private void InitializeSDL()
30 | {
31 | SDL.SDL_SetHint("SDL_WINDOWS_DISABLE_THREAD_NAMING", "1");
32 |
33 | int retVal;
34 | if ((retVal = SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING)) < 0)
35 | {
36 | Log.Write(LogType.Error, LogComponent.DAC, "Failed to initialize SDL, retval 0x{0:x}", retVal);
37 | return;
38 | }
39 |
40 | //
41 | // Initialize SDL Audio:
42 | //
43 | SDL.SDL_AudioSpec desired = new SDL.SDL_AudioSpec();
44 |
45 | _audioCallback = AudioCallback;
46 |
47 | desired.freq = AudioDAC.AudioDACSamplingRate;
48 | desired.format = SDL.AUDIO_U16LSB; // the default is little-endian but we'll make it explicit.
49 | desired.channels = 1;
50 | desired.callback = _audioCallback;
51 | desired.samples = 4096;
52 |
53 | uint deviceId = 1;
54 | if (SDL.SDL_OpenAudio(ref desired, IntPtr.Zero) < 0)
55 | {
56 | Log.Write(LogType.Error, LogComponent.DAC, "Failed to open default audio device, error 0x{0:x}", SDL.SDL_GetError());
57 | return;
58 | }
59 |
60 | SDL.SDL_PauseAudioDevice(deviceId, 0);
61 |
62 |
63 | Log.Write(LogComponent.DAC, "SDL Audio initialized, device id {0}", deviceId);
64 | }
65 |
66 | private void AudioCallback(IntPtr userData, IntPtr stream, int length)
67 | {
68 | ushort lastSample = 0;
69 | for (int i = 0; i < length / 2; i++)
70 | {
71 | if (_audioBuffer.TryDequeue(out ushort sample))
72 | {
73 | _sampleBuffer[i * 2] = (byte)sample;
74 | _sampleBuffer[i * 2 + 1] = (byte)(sample >> 8);
75 | lastSample = sample;
76 | }
77 | else
78 | {
79 | // Out of data, just send the last sample to try to reduce popping.
80 | _sampleBuffer[i * 2] = (byte)lastSample;
81 | _sampleBuffer[i * 2 + 1] = (byte)(lastSample >> 8);
82 | }
83 | }
84 |
85 | Marshal.Copy(_sampleBuffer, 0, stream, length);
86 | }
87 |
88 | ///
89 | /// Reused buffer for marshaling to SDL2.
90 | ///
91 | private byte[] _sampleBuffer;
92 |
93 | ///
94 | /// Audio samples waiting to be written out.
95 | ///
96 | private ConcurrentQueue _audioBuffer;
97 |
98 | //
99 | // Local reference for the SDL Audio callback:
100 | // SDL-CS doesn't hold this reference which causes
101 | // problems when the GC runs.
102 | //
103 | private SDL.SDL_AudioCallback _audioCallback;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/ContraltoUI/ViewModels/LogViewModel.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Contralto;
24 | using Contralto.Logging;
25 | using System.Collections.Generic;
26 |
27 |
28 | namespace ContraltoUI.ViewModels
29 | {
30 | public partial class LogViewModel : ViewModelBase
31 | {
32 | public LogViewModel(AltoSystem system)
33 | {
34 | _system = system;
35 |
36 | Log.Updated += OnLogUpdated;
37 | }
38 |
39 | private void OnLogUpdated(object? sender, System.EventArgs e)
40 | {
41 | OnPropertyChanged(nameof(LogText));
42 | }
43 |
44 | public override void OnApplicationExit()
45 | {
46 |
47 | }
48 |
49 | public IEnumerable LogText => Log.LogText;
50 |
51 |
52 | private AltoSystem _system;
53 |
54 |
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/ContraltoUI/ViewModels/ViewModelBase.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Controls.ApplicationLifetimes;
24 | using Avalonia.Controls;
25 | using CommunityToolkit.Mvvm.ComponentModel;
26 | using System.Collections.Generic;
27 | using System.ComponentModel;
28 | using Avalonia;
29 | using System;
30 | using System.Linq;
31 |
32 | namespace ContraltoUI.ViewModels;
33 |
34 |
35 | public abstract class ViewModelBase : ObservableObject
36 | {
37 | // Let the VM know if the application is exiting so it can yell at the model about it.
38 | public abstract void OnApplicationExit();
39 |
40 | public static IEnumerable Windows =>
41 | (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime)?.Windows ?? Array.Empty();
42 |
43 | ///
44 | /// This is a hack to kinda sorta let viewmodels find an appropriate window for doing things like parenting file picker dialogs.
45 | ///
46 | ///
47 | ///
48 | public static Window FindWindowByViewModel(INotifyPropertyChanged viewModel)
49 | {
50 | Window? window = Windows.FirstOrDefault(x => ReferenceEquals(viewModel, x.DataContext));
51 |
52 | if (window == null)
53 | {
54 | throw new InvalidOperationException("No parent window found.");
55 | }
56 |
57 | return window;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/AboutDialog.axaml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
41 |
42 |
43 | ContrAlto v
44 |
45 |
46 | A Xerox Alto Emulator
47 | (c) 2016-2020 Living Computers: Museum+Labs
48 | (c) 2016-2024 Josh Dersch
49 | Bug reports or comments to derschjo@gmail.com
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/AboutDialog.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Controls;
24 | using Avalonia.Interactivity;
25 |
26 | namespace ContraltoUI.Views
27 | {
28 | public partial class AboutDialog : Window
29 | {
30 | public AboutDialog()
31 | {
32 | InitializeComponent();
33 | }
34 |
35 | private void OnOkClick(object sender, RoutedEventArgs args)
36 | {
37 | Close();
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/AlternateBootDialog.axaml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | Alternate Boot Type:
50 |
51 |
53 |
55 |
56 |
57 |
58 |
59 |
60 | Disk Boot Address:
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | Ethernet Boot File:
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/AlternateBootDialog.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Controls;
24 | using Avalonia.Interactivity;
25 | using ContraltoUI.ViewModels;
26 |
27 | namespace ContraltoUI.Views
28 | {
29 | public partial class AlternateBootDialog : Window
30 | {
31 | public AlternateBootDialog()
32 | {
33 | InitializeComponent();
34 | }
35 |
36 | ///
37 | /// Handles closure of the dialog.
38 | ///
39 | ///
40 | ///
41 | private void OnOkClick(object sender, RoutedEventArgs args)
42 | {
43 | // This is probably an MVVM abstraction violation. I have no idea how to accomplish this in a way that's
44 | // more clean, however.
45 | ConfigurationViewModel? vm = DataContext as ConfigurationViewModel;
46 | vm?.CommitChanges();
47 | Close();
48 | }
49 |
50 | private void OnCancelClick(object sender, RoutedEventArgs args)
51 | {
52 | Close();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/AltoDisplay.axaml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
24 |
34 |
35 |
37 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/AltoDisplay.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia;
24 | using Avalonia.Controls;
25 | using Avalonia.Input;
26 | using Avalonia.Interactivity;
27 | using Avalonia.Media.Imaging;
28 | using Avalonia.Platform;
29 | using ContraltoUI.ViewModels;
30 |
31 | namespace ContraltoUI.Views;
32 |
33 | public partial class AltoDisplay : UserControl
34 | {
35 | public AltoDisplay()
36 | {
37 | InitializeComponent();
38 | Bitmap cursorBitmap = new Bitmap(AssetLoader.Open(new System.Uri("avares://ContraltoUI/Assets/DisplayCursor.png")));
39 | _hiddenCursor = new Cursor(cursorBitmap, new PixelPoint(2, 2));
40 | }
41 |
42 | protected override void OnGotFocus(GotFocusEventArgs e)
43 | {
44 | // Show the "hidden" cursor only when the window has focus...
45 | Cursor = _hiddenCursor;
46 | base.OnGotFocus(e);
47 | }
48 |
49 | protected override void OnLostFocus(RoutedEventArgs e)
50 | {
51 | // ... otherwise use the default arrow cursor.
52 | Cursor = new Cursor(StandardCursorType.Arrow);
53 | base.OnLostFocus(e);
54 | }
55 |
56 | // There may be some maaaagical databinding way I can do the below, I just don't care right now.
57 | protected override void OnKeyDown(KeyEventArgs e)
58 | {
59 | AltoUIViewModel? alto = DataContext as AltoUIViewModel;
60 | alto?.OnKeyDown(e);
61 | }
62 |
63 | protected override void OnKeyUp(KeyEventArgs e)
64 | {
65 | AltoUIViewModel? alto = DataContext as AltoUIViewModel;
66 | alto?.OnKeyUp(e);
67 | }
68 |
69 | protected override void OnPointerMoved(PointerEventArgs e)
70 | {
71 | // Send mouse coordinate normalized to the image's (DPI-compensated) render size.
72 | Point pointerPoint = e.GetPosition(DisplayImage);
73 |
74 | AltoUIViewModel? alto = DataContext as AltoUIViewModel;
75 | alto?.OnMouseMoved(pointerPoint.X / (DisplayImage.DesiredSize.Width / alto.HostDesktopDisplayScale), pointerPoint.Y / (DisplayImage.DesiredSize.Height / alto.HostDesktopDisplayScale));
76 | }
77 |
78 | protected override void OnPointerPressed(PointerPressedEventArgs e)
79 | {
80 | AltoUIViewModel? alto = DataContext as AltoUIViewModel;
81 | PointerPointProperties pointerPoint = e.GetCurrentPoint(this).Properties;
82 | alto?.OnMouseDown(pointerPoint.IsLeftButtonPressed, pointerPoint.IsMiddleButtonPressed, pointerPoint.IsRightButtonPressed);
83 | }
84 |
85 | protected override void OnPointerReleased(PointerReleasedEventArgs e)
86 | {
87 | AltoUIViewModel? alto = DataContext as AltoUIViewModel;
88 | // this Avalonia API is weirdly asymmetrical.
89 | alto?.OnMouseUp(e.InitialPressMouseButton == MouseButton.Left, e.InitialPressMouseButton == MouseButton.Middle, e.InitialPressMouseButton == MouseButton.Right);
90 | }
91 |
92 | private Cursor _hiddenCursor;
93 | }
94 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/ConfigurationDialog.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Controls;
24 | using Avalonia.Interactivity;
25 | using ContraltoUI.ViewModels;
26 |
27 | namespace ContraltoUI.Views
28 | {
29 | public partial class ConfigurationDialog : Window
30 | {
31 | public ConfigurationDialog()
32 | {
33 | InitializeComponent();
34 | }
35 |
36 | ///
37 | /// Handles closure of the dialog.
38 | ///
39 | ///
40 | ///
41 | private void OnOkClick(object sender, RoutedEventArgs args)
42 | {
43 | // This is probably an MVVM abstraction violation. I have no idea how to accomplish this in a way that's
44 | // more clean, however.
45 | ConfigurationViewModel? vm = DataContext as ConfigurationViewModel;
46 | vm?.CommitChanges();
47 | Close();
48 | }
49 |
50 | private void OnCancelClick(object sender, RoutedEventArgs args)
51 | {
52 | Close();
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/DebuggerWindow.axaml:
--------------------------------------------------------------------------------
1 |
22 |
23 |
33 | Welcome to Avalonia!
34 |
35 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/DebuggerWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Controls;
24 |
25 | namespace ContraltoUI.Views
26 | {
27 | public partial class DebuggerWindow : Window
28 | {
29 | public DebuggerWindow()
30 | {
31 | InitializeComponent();
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/LogWindow.axaml:
--------------------------------------------------------------------------------
1 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/LogWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | using Avalonia.Controls;
2 |
3 | namespace ContraltoUI.Views
4 | {
5 | public partial class LogWindow : Window
6 | {
7 | public LogWindow()
8 | {
9 | InitializeComponent();
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/ContraltoUI/Views/MainWindow.axaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024 Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
10 | in the documentation and/or other materials provided with the distribution.
11 | 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from
12 | this software without specific prior written permission.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
15 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
18 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20 |
21 | */
22 |
23 | using Avalonia.Controls;
24 | using Avalonia.Input;
25 | using Avalonia.Interactivity;
26 | using ContraltoUI.ViewModels;
27 |
28 | namespace ContraltoUI.Views;
29 |
30 | public partial class MainWindow : Window
31 | {
32 | public MainWindow()
33 | {
34 | InitializeComponent();
35 | }
36 |
37 | protected override void OnLoaded(RoutedEventArgs e)
38 | {
39 | if (DataContext is AltoUIViewModel vm)
40 | {
41 | // Pass along the scale factor to the viewmodel so we can compensate.
42 | vm.HostDesktopDisplayScale = DesktopScaling;
43 | }
44 |
45 | base.OnLoaded(e);
46 | }
47 |
48 | protected override void OnClosing(WindowClosingEventArgs e)
49 | {
50 | // Is this tight coupling? Is this private action? Do I care?
51 | // (If there's a better way to do this, I'm unaware of it.)
52 | // Anyway -- let our viewmodel know what's going on so it can stop things.
53 | if (DataContext is ViewModelBase vm)
54 | {
55 | vm.OnApplicationExit();
56 | }
57 | }
58 |
59 | protected override void OnLostFocus(RoutedEventArgs e)
60 | {
61 | if (DataContext is AltoUIViewModel vm)
62 | {
63 | vm.OnLostFocus();
64 | }
65 | base.OnLostFocus(e);
66 | }
67 |
68 | protected override void OnGotFocus(GotFocusEventArgs e)
69 | {
70 | if (DataContext is AltoUIViewModel vm)
71 | {
72 | vm.OnFocused();
73 | }
74 | base.OnGotFocus(e);
75 | }
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | enable
4 | 11.0.2
5 |
6 |
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | BSD 3-Clause License
2 |
3 | Copyright (c) 2016-2020 Living Computers: Museum+Labs
4 | Copyright (c) 2016-2024, Josh Dersch
5 |
6 | Redistribution and use in source and binary forms, with or without
7 | modification, are permitted provided that the following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this
10 | list of conditions and the following disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice,
13 | this list of conditions and the following disclaimer in the documentation
14 | and/or other materials provided with the distribution.
15 |
16 | 3. Neither the name of the copyright holder nor the names of its
17 | contributors may be used to endorse or promote products derived from
18 | this software without specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ContrAlto 2.0
2 |
3 | ContrAlto aspires to be a faithful emulation of the Xerox Alto series of
4 | pioneering graphical workstations developed at Xerox PARC starting in 1973.
5 |
6 | At this time, it runs all known software, though some may make use of hardware
7 | that is not yet implemented (RS232, IMP interfaces, etc.)
8 |
9 | For releases, please see: https://github.com/jdersch/Contralto2/releases.
10 |
11 | For documentation, please see: https://github.com/jdersch/Contralto2/blob/master/Contralto/readme.txt
--------------------------------------------------------------------------------