Fleshed out Memory and Microprogramming interfaces
[Mograsim.git] / net.mograsim.plugin.core / src / net / mograsim / plugin / memory / MemoryView.java
1 package net.mograsim.plugin.memory;
2
3 import org.eclipse.jface.viewers.ColumnLabelProvider;
4 import org.eclipse.jface.viewers.TableViewer;
5 import org.eclipse.jface.viewers.TableViewerColumn;
6 import org.eclipse.swt.SWT;
7 import org.eclipse.swt.events.SelectionEvent;
8 import org.eclipse.swt.events.SelectionListener;
9 import org.eclipse.swt.events.VerifyListener;
10 import org.eclipse.swt.layout.GridData;
11 import org.eclipse.swt.layout.GridLayout;
12 import org.eclipse.swt.widgets.Combo;
13 import org.eclipse.swt.widgets.Composite;
14 import org.eclipse.swt.widgets.Label;
15 import org.eclipse.swt.widgets.Table;
16 import org.eclipse.swt.widgets.TableColumn;
17 import org.eclipse.swt.widgets.Text;
18 import org.eclipse.ui.part.ViewPart;
19
20 import net.mograsim.machine.DefaultMainMemoryDefinition;
21 import net.mograsim.machine.MainMemory;
22 import net.mograsim.machine.standard.memory.WordAddressableMemory;
23 import net.mograsim.plugin.asm.AsmNumberUtil;
24 import net.mograsim.plugin.asm.AsmNumberUtil.NumberType;
25
26 public class MemoryView extends ViewPart
27 {
28         private TableViewer viewer;
29         private MemoryTableContentProvider provider;
30         private DisplaySettings displaySettings;
31         private String addressFormat;
32
33         @Override
34         public void createPartControl(Composite parent)
35         {
36                 provider = new MemoryTableContentProvider();
37                 displaySettings = new DisplaySettings();
38                 displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
39
40                 GridLayout layout = new GridLayout(6, false);
41                 parent.setLayout(layout);
42                 Label fromLabel = new Label(parent, SWT.NONE);
43                 fromLabel.setText("Address: ");
44                 Text fromText = new Text(parent, SWT.BORDER | SWT.SEARCH);
45                 fromText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
46                 VerifyListener vl = new NumberVerifyListener();
47                 fromText.addVerifyListener(vl);
48                 fromText.setText("0");
49                 fromText.addModifyListener(e ->
50                 {
51                         try
52                         {
53                                 provider.setLowerBound(AsmNumberUtil.valueOf(fromText.getText()).longValue());
54                                 viewer.refresh();
55                         }
56                         catch (@SuppressWarnings("unused") NumberFormatException ex)
57                         {
58                                 // Nothing to do here
59                         }
60                 });
61
62                 Label amountLabel = new Label(parent, SWT.NONE);
63                 amountLabel.setText("Number of cells: ");
64                 Text amountText = new Text(parent, SWT.BORDER | SWT.SEARCH);
65                 amountText.setLayoutData(new GridData(GridData.GRAB_HORIZONTAL | GridData.FILL_HORIZONTAL));
66                 amountText.addVerifyListener(vl);
67                 amountText.setText("0");
68                 amountText.addModifyListener(e ->
69                 {
70                         try
71                         {
72                                 provider.setAmount(AsmNumberUtil.valueOf(amountText.getText()).intValue());
73                                 viewer.refresh();
74                         }
75                         catch (@SuppressWarnings("unused") NumberFormatException ex)
76                         {
77                                 // Nothing to do here
78                         }
79                 });
80
81                 setupRadixSelector(parent);
82
83                 createViewer(parent);
84         }
85
86         private void setupRadixSelector(Composite parent)
87         {
88                 Label radixLabel = new Label(parent, SWT.NONE);
89                 radixLabel.setText("Radix: ");
90                 Combo selectRadix = new Combo(parent, SWT.READ_ONLY);
91
92                 String entries[] = new String[] { "Binary", "Octal", "Decimal", "Hexadecimal" };
93                 NumberType corTypes[] = new NumberType[] { NumberType.BINARY, NumberType.OCTAL, NumberType.DECIMAL, NumberType.HEXADECIMAL };
94                 selectRadix.setItems(entries);
95                 selectRadix.addSelectionListener(new SelectionListener()
96                 {
97                         @Override
98                         public void widgetSelected(SelectionEvent e)
99                         {
100                                 int index = selectRadix.getSelectionIndex();
101                                 if (index == -1)
102                                         displaySettings.setDataNumberType(NumberType.HEXADECIMAL);
103                                 else
104                                 {
105                                         displaySettings.setDataNumberType(corTypes[index]);
106                                 }
107                                 viewer.refresh();
108                         }
109
110                         @Override
111                         public void widgetDefaultSelected(SelectionEvent e)
112                         {
113                                 widgetSelected(e);
114                         }
115                 });
116         }
117
118         private void createViewer(Composite parent)
119         {
120                 viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER | SWT.VIRTUAL);
121                 createColumns();
122                 Table table = viewer.getTable();
123                 table.setHeaderVisible(true);
124                 table.setLinesVisible(true);
125                 viewer.setUseHashlookup(true);
126                 viewer.setContentProvider(provider);
127                 setMemoryBinding(new WordAddressableMemory(new DefaultMainMemoryDefinition(8, 8, 8L, Long.MAX_VALUE)));
128                 getSite().setSelectionProvider(viewer);
129
130                 GridData gd = new GridData();
131                 gd.verticalAlignment = GridData.FILL;
132                 gd.horizontalSpan = 6;
133                 gd.grabExcessHorizontalSpace = true;
134                 gd.grabExcessVerticalSpace = true;
135                 gd.horizontalAlignment = GridData.FILL;
136                 viewer.getControl().setLayoutData(gd);
137         }
138
139         private void createColumns()
140         {
141                 String[] titles = { "Address", "Data" };
142                 int[] bounds = { 100, 100 };
143
144                 TableViewerColumn col = createTableViewerColumn(titles[0], bounds[0]);
145                 col.setLabelProvider(new ColumnLabelProvider()
146                 {
147                         @Override
148                         public String getText(Object element)
149                         {
150                                 MemoryTableRow row = (MemoryTableRow) element;
151                                 return String.format(addressFormat, row.address);// TODO: make the string length dependent on memory address length
152                         }
153                 });
154
155                 col = createTableViewerColumn(titles[1], bounds[1]);
156                 col.setLabelProvider(new ColumnLabelProvider()
157                 {
158                         @Override
159                         public String getText(Object element)
160                         {
161                                 MemoryTableRow row = (MemoryTableRow) element;
162                                 return AsmNumberUtil.toString(row.getMemory().getCellAsBigInteger(row.address), displaySettings.getDataNumberType());
163                         }
164                 });
165                 col.setEditingSupport(new MemoryCellEditingSupport(viewer, displaySettings));
166         }
167
168         private TableViewerColumn createTableViewerColumn(String title, int bound)
169         {
170                 TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
171                 TableColumn column = viewerColumn.getColumn();
172                 column.setText(title);
173                 column.setWidth(bound);
174                 column.setResizable(true);
175                 column.setMoveable(false);
176                 return viewerColumn;
177         }
178
179         @Override
180         public void setFocus()
181         {
182                 viewer.getControl().setFocus();
183         }
184
185         public void setMemoryBinding(MainMemory m)
186         {
187                 int hexAddressLength = Long.toUnsignedString(m.getDefinition().getMaximalAddress(), 16).length();
188                 addressFormat = "0x%0" + hexAddressLength + "X";
189                 viewer.setInput(m);
190         }
191
192         public static class DisplaySettings
193         {
194                 private AsmNumberUtil.NumberType dataNumberType;
195
196                 public AsmNumberUtil.NumberType getDataNumberType()
197                 {
198                         return dataNumberType;
199                 }
200
201                 public void setDataNumberType(AsmNumberUtil.NumberType dataNumberType)
202                 {
203                         this.dataNumberType = dataNumberType;
204                 }
205         }
206 }