1 /* pMARS Globals:
2 
3    int displayLevel	0: no detail, 1: executions/deaths only
4 			2: as level 1 but also writes, 3: as level 2 but also
5 			decrements/increments, 4: as level 3 but also reads.
6 
7    int displaySpeed	0..SPEEDLEVELS-1.  0 is slowest, SPEEDLEVELS-1 is
8 			fastest.  Speed level 1 is the default.
9 
10    int displayMode	Implementation dependent.  In windowed systems
11    			typically controls the window size and size in pixels
12 			of a core cell.  On non-windowed systems it
13 			controls the display resolution.  Conventionally
14 			display mode 0 is the same as display mode 1.
15 
16    int curPanel		The current text panel, either 1 (left panel) or 2
17    			(right panel) or -1 (none, not initialised).
18 			cdb.c uses the function XXX_update(int nextpanel)
19 			to update the panel and panel movement, so
20 			only the display code needs to know about curPanel.
21 
22    int curAddr		While debugging this holds the current core address.
23    			Managed by cdb.c --- read-only in the display code.
24 
25    int inCbd		A flag that tells the display code if we are debugging
26    			or not.  Managed by cdb.c --- read-only in the display
27 			code.
28 
29    int inputRedirection A flag that tells us whether or not input is
30    			redirected from stdin.  read-only.
31 
32    void sighandler(int)  The signal handler function of pMARS.  Call this
33    			with the argument 0 when suspending a fight to resume
34 			debugging so that cdb knows to stop executing the
35 			current macro.  Note: you need to add a test
36 			to pmars.c to include <signal.h> if you call this.
37  */
38 extern int displayLevel;
39 extern int displayMode;
40 extern int displaySpeed;
41 extern int curPanel;
42 extern int curAddr;
43 extern int inCdb;
44 extern int inputRedirection;
45 void sighandler(int);
46 
47 /* Initialise the graphics subsystem. */
48 void
stdio_open_graphics(void)49 stdio_open_graphics(void)
50 {}
51 
52 /* Close down the graphics subsystem.  If the argument WAIT is equal to
53    the #define WAIT then print the message pressAnyKey and wait for a key
54    press before closing down. */
55 void
stdio_display_close(int wait)56 stdio_display_close(int wait)
57 {}
58 
59 /* Clear the arena. */
60 void
stdio_clear_arena(void)61 stdio_clear_arena(void)
62 {}
63 
64 /* Clear the arena process meters and cycle meter. */
65 void
stdio_display_clear(void)66 stdio_display_clear(void)
67 {}
68 
69 /* Draw the status line.  That is, the line under the arena
70    that has the speed meter, detail level indicator and debugging status.
71  */
72 void
stdio_write_menu(void)73 stdio_write_menu(void)
74 {}
75 
76 /* Update the text panels.  If NEXTPANEL = 0 then close the current panel
77  * curPanel.  If NEXTPANEL = 1 the update the cursor to the left panel.
78  * If NEXTPANEL = 2 then update the cursor to the right panel, possibly
79  * creating it if it didn't exist before.  On entry if curPanel is -1
80  * then no panels have been initialised yet.
81  */
82 void
stdio_update(int nextpanel)83 stdio_update(int nextpanel)
84 {
85 	/* stdio doesn't support panels -- do nothing but update curPanel. */
86 	if (curPanel <= 0) {
87 		curPanel = 1;
88 	}
89 	if (nextpanel == 0) {
90 		curPanel = 1;
91 	} else {
92 		curPanel = nextpanel;
93 	}
94 }
95 
96 /* Clear the current panel and move the cursor to the upper left corner
97    of the current panel. */
98 void
stdio_clear(void)99 stdio_clear(void)
100 {}
101 
102 /* Print a string to the current panel.  The only special control character
103    that needs to be recognised is '\n' that performs a line feed. */
104 void
stdio_puts(const char * s)105 stdio_puts(const char *s)
106 {
107 	printf(s);
108 }
109 
110 /* Get the maximum number of visible rows in the current panel. */
111 int
stdio_text_lines(void)112 stdio_text_lines(void)
113 {
114 	return 25;
115 }
116 
117 /* Get a string from the current panel into the buffer BUF of at most
118    MAXBUF-1 characters using the prompt string PROMPT.  Return BUF.
119    As a special case, if the global inputRedirection is non-zero then
120    read a line from the standard input stream.
121  */
122 char *
stdio_gets(char * buf,int maxbuf,const char * prompt)123 stdio_gets(char *buf, int maxbuf, const char *prompt)
124 {
125 	stdio_puts(prompt);
126 	if (maxbuf > 0) {
127 		buf[maxbuf-1] = 0;
128 		return fgets(buf, maxbuf-1, stdin);
129 	}
130 	return buf; // or NULL?
131 }
132 
133 /* Set the display mode to NEWMODE. */
134 void
stdio_set_displayMode(int newmode)135 stdio_set_displayMode(int newmode)
136 {
137 	newmode = newmode < 0 ? 0 : newmode;
138 	newmode = newmode > 9 ? 9 : newmode;
139 	displayMode = newmode;
140 }
141 
142 /* Set the display speed to NEWSPEED. */
143 void
stdio_set_displaySpeed(int newspeed)144 stdio_set_displaySpeed(int newspeed)
145 {
146 	newspeed = newspeed < 0 ? 0 : newspeed;
147 	newspeed = newspeed > SPEEDLEVELS-1 ? SPEEDLEVELS-1 : newspeed;
148 	displaySpeed = newspeed;
149 }
150 
151 /* Set the display detail level to NEWLEVEL. */
152 void
stdio_set_displayLevel(int newlevel)153 stdio_set_displayLevel(int newlevel)
154 {
155 	newlevel = newlevel < 0 ? 0 : newlevel;
156 	newlevel = newlevel > 4 ? 4 : newlevel;
157 	displayLevel = newlevel;
158 }
159 
160 
161 /* --------------------------------------------------------------------------
162  * Macros called from the simulator during execution.
163  */
164 
165 /* Called every cycle from the simulator to update the cycle meter and
166    process special key strokes if the global flag inputRedirection
167    is false.  The keys recognised should be:
168  	SPACE r R 	Clear the arena.
169 	>		Speed up the display (decrement displaySpeed.)
170 	<		Slow down the display (increment displaySpeed.)
171 	ESCAPE q Q	Quit pMARS.
172 	0 1 2 3 4	Set the display detail level to 0 1 2 3 or 4.
173 	otherwise	Enter debugging state by calling sighandler(0).
174  */
175 static void
stdio_display_cycle(void)176 stdio_display_cycle(void)
177 {}
178 
179 /* The following display_XXX macros are expanded inside sim.c/simulator(). */
180 
181 #define display_cycle() stdio_display_cycle()
182 #define display_close() stdio_display_close(WAIT)
183 #define display_init() stdio_open_graphics()
184 #define display_clear() stdio_display_clear()
185 
186 /* All processes of the WARNUMth warrior died. */
187 #define display_die(warnum)
188 
189 /* The given core address was pushed to the process queue of the current
190    warrior.  Doesn't need to update the process meters.  */
191 #define display_push(addr)
192 
193 /* Display the foo at the given core address if displayLevel is sufficient. */
194 #define display_read(addr)
195 #define display_write(addr)
196 #define display_dec(addr)
197 #define display_inc(addr)
198 #define display_exec(addr)
199 
200 /* The WARNUMth warrior just split and now has NPROCS processes.  Update its
201    process meter.  Called when an SPL instruction executes succesfully. */
202 #define display_spl(warnum, nprocs)
203 
204 /* A process of the WARNUMth warrior executed a DAT at the core address ADDR
205    and now has NPROCS processes left.  Display the death at ADDR if
206    displayLevel is sufficient and update the warrior's process meter. */
207 #define display_dat(addr, warnum, nprocs)
208