6 * This program is provided as a service to the programmer
7 * community to demonstrate one or more features of the Amiga
8 * personal computer. These code samples may be freely used
9 * for commercial or noncommercial purposes.
11 * Commodore Electronics, Ltd ("Commodore") makes no
12 * warranties, either expressed or implied, with respect
13 * to the program described herein, its quality, performance,
14 * merchantability, or fitness for any particular purpose.
15 * This program is provided "as is" and the entire risk
16 * as to its quality and performance is with the user.
17 * Should the program prove defective following its
18 * purchase, the user (and not the creator of the program,
19 * Commodore, their distributors or their retailers)
20 * assumes the entire cost of all necessary damages. In
21 * no event will Commodore be liable for direct, indirect,
22 * incidental or consequential damages resulting from any
23 * defect in the program even if it has been advised of the
24 * possibility of such damages. Some laws do not allow
25 * the exclusion or limitation of implied warranties or
26 * liabilities for incidental or consequential damages,
27 * so the above limitation or exclusion may not apply.
31 /* cons.c - a console device demo program with supporting macro routines. */
33 /* This program is supported by the Amiga C compiler, version 1.1 and beyond.
34 * (v1.0 compiler has difficulties if string variables do not have their
35 * initial character aligned on a longword boundary. Compiles acceptably
36 * but won't run correctly.)
38 * Author: Rob Peck, 12/1/85
40 * This code may be freely utilized to develop programs for the Amiga.
42 * Modifications for AROS, July 2010:
44 * - Header required for AROS
46 * - Added some casts needed by newer compilers
50 #include <exec/types.h>
52 #include "exec/memory.h"
54 #define SHORT signed char
56 #include "graphics/gfx.h"
57 #include "graphics/gfxmacros.h"
58 #include "graphics/copper.h"
59 #include "graphics/view.h"
60 #include "graphics/gels.h"
61 #include "graphics/regions.h"
62 #include "graphics/clip.h"
64 #include "proto/exec.h"
65 #include "proto/intuition.h"
66 #include "proto/dos.h"
67 #include "proto/alib.h"
69 #include "exec/exec.h"
70 #include "graphics/text.h"
71 #include "graphics/gfxbase.h"
73 #include "devices/console.h"
74 #include "devices/keymap.h"
76 #include "libraries/dos.h"
77 #include "graphics/text.h"
78 #include "libraries/diskfont.h"
79 #include "intuition/intuition.h"
83 UBYTE escdata
[] = { 0x9b, '@', /* insert character */
84 0x9b, 'A', /* cursor up */
85 0x9b, 'B', /* cursor down */
86 0x9b, 'C', /* cursor left */
87 0x9b, 'D', /* cursor right */
88 0x9b, 'E', /* cursor next line */
89 0x9b, 'F', /* cursor prev line */
90 0x9b, 'J', /* erase to end of display */
91 0x9b, 'K', /* erase to end of line */
92 0x9b, 'L', /* insert line */
93 0x9b, 'M', /* delete line */
94 0x9b, 'P', /* delete character */
95 0x9b, 'S', /* scroll up */
96 0x9b, 'T', /* scroll down */
97 0x1b, 'c', /* reset to initial state */
98 0x9b, 'q', /* window status request */
99 0x9b, 'n', /* device status report */
100 0x9b, ' ', 'p',/* cursor on */
101 0x9b, '0', ' ', 'p', /* cursor off */
102 0x9b, '2', '0', 'h', /* set mode */
103 0x9b, '2', '0', 'l', /* reset mode */
106 /* COVER A SELECTED SUBSET OF THE CONSOLE AVAILABLE FUNCTIONS */
108 #define INSERTCHARSTRING &escdata[0]
109 #define CURSUPSTRING &escdata[0+2]
110 #define CURSDOWNSTRING &escdata[0+4]
111 #define CURSFWDSTRING &escdata[0+6]
112 #define CURSBAKSTRING &escdata[0+8]
113 #define CURSNEXTLINE &escdata[0+10]
114 #define CURSPREVLINE &escdata[0+12]
115 #define ERASEEODSTRING &escdata[0+14]
116 #define ERASEEOLSTRING &escdata[0+16]
117 #define INSERTLINESTRING &escdata[0+18]
118 #define DELETELINESTRING &escdata[0+20]
119 #define DELCHARSTRING &escdata[0+22]
120 #define SCROLLUPSTRING &escdata[0+24]
121 #define SCROLLDOWNSTRING &escdata[0+26]
122 #define RESETINITSTRING &escdata[0+28]
123 #define WINDOWSTATSTRING &escdata[0+30]
124 #define DEVSTATSTRING &escdata[0+32]
125 #define CURSONSTRING &escdata[0+34]
126 #define CURSOFFSTRING &escdata[0+37]
127 #define SETMODESTRING &escdata[0+41]
128 #define RESETMODESTRING &escdata[0+45]
130 #define BACKSPACE(r) ConPutChar(r,0x08)
131 #define TAB(r) ConPutChar(r,0x09)
132 #define LINEFEED(r) ConPutChar(r,0x0a)
133 #define VERTICALTAB(r) ConPutChar(r,0x0b)
134 #define FORMFEED(r) ConPutChar(r,0x0c)
135 #define CR(r) ConPutChar(r,0x0d)
136 #define SHIFTOUT(r) ConPutChar(r,0x0e)
137 #define SHIFTIN(r) ConPutChar(r,0x0f)
138 #define CLEARSCREEN(r) ConPutChar(r,0x0c)
140 #define RESET(r) ConWrite(r,RESETINITSTRING,2)
141 #define INSERT(r) ConWrite(r,INSERTCHARSTRING,2)
142 #define CURSUP(r) ConWrite(r,CURSUPSTRING,2)
143 #define CURSDOWN(r) ConWrite(r,CURSDOWNSTRING,2)
144 #define CURSFWD(r) ConWrite(r,CURSFWDSTRING,2)
145 #define CURSBAK(r) ConWrite(r,CURSBAKSTRING,2)
146 #define CURSNEXTLN(r) ConWrite(r,CURSNEXTLINE,2)
147 #define CURSPREVLN(r) ConWrite(r,CURSPREVLINE,2)
148 #define ERASEEOD(r) ConWrite(r,ERASEEODSTRING,2)
149 #define ERASEEOL(r) ConWrite(r,ERASEEOLSTRING,2)
150 #define INSERTLINE(r) ConWrite(r,INSERTLINESTRING,2)
151 #define DELETELINE(r) ConWrite(r,DELETELINESTRING,2)
152 #define SCROLLUP(r) ConWrite(r,SCROLLUPSTRING,2)
153 #define SCROLLDOWN(r) ConWrite(r,SCROLLDOWNSTRING,2)
154 #define DEVICESTATUS(r) ConWrite(r,DEVSTATSTRING,2)
155 #define WINDOWSTATUS(r) ConWrite(r,WINDOWSTATSTRING,2)
156 #define DELCHAR(r) ConWrite(r,DELCHARSTRING,2)
157 #define CURSORON(r) ConWrite(r,CURSONSTRING,3)
158 #define CURSOROFF(r) ConWrite(r,CURSOFFSTRING,4)
159 #define SETMODE(r) ConWrite(r,SETMODESTRING,4)
160 #define RESETMODE(r) ConWrite(r,RESETMODESTRING,4)
162 #define CloseConsole(r) CloseDevice(r)
166 struct NewWindow nw
= {
167 10, 10, /* starting position (left,top) */
168 620,400, /* width, height */
169 -1,-1, /* detailpen, blockpen */
170 0, /* flags for idcmp */
177 /* window gadget flags */
178 0, /* pointer to 1st user gadget */
179 NULL
, /* pointer to user check */
180 "Console Test", /* title */
181 NULL
, /* pointer to window screen */
182 NULL
, /* pointer to super bitmap */
183 100,45, /* min width, height */
184 640,200, /* max width, height */
190 struct IOStdReq
*consoleWriteMsg
; /* I/O request block pointer */
191 struct MsgPort
*consoleWritePort
; /* a port at which to receive */
192 struct IOStdReq
*consoleReadMsg
; /* I/O request block pointer */
193 struct MsgPort
*consoleReadPort
; /* a port at which to receive */
195 extern struct MsgPort
*CreatePort();
196 extern struct IOStdReq
*CreateStdIO();
198 char readstring
[200]; /* provides a buffer even though using only one char */
200 int OpenConsole(struct IOStdReq
* writerequest
, struct IOStdReq
* readrequest
, struct Window
* window
);
201 int QueueRead(struct IOStdReq
* request
, char * whereto
);
202 int ConWrite(struct IOStdReq
* request
, char * string
, int length
);
203 int ConPutStr(struct IOStdReq
* request
, char * string
);
204 int ConPutChar(struct IOStdReq
* request
,char character
);
206 struct Library
* DosBase
;
207 struct Library
* DiskfontBase
;
208 struct Library
* GfxBase
;
219 if((DosBase
= OpenLibrary("dos.library", 0)) == NULL
)
220 { problem
= 1; goto cleanup1
; }
221 if((DiskfontBase
=OpenLibrary("diskfont.library",0))==NULL
)
222 { problem
= 2; goto cleanup2
; }
223 if((IntuitionBase
=(APTR
)OpenLibrary("intuition.library",0))==NULL
)
224 { problem
= 3; goto cleanup3
; }
225 if((GfxBase
=OpenLibrary("graphics.library",0))==NULL
)
226 { problem
= 4; goto cleanup4
; }
228 consoleWritePort
= CreatePort("my.con.write",0);
229 if(consoleWritePort
== 0)
230 { problem
= 5; goto cleanup5
; }
231 consoleWriteMsg
= CreateStdIO(consoleWritePort
);
232 if(consoleWritePort
== 0)
233 { problem
= 6; goto cleanup6
; }
235 consoleReadPort
= CreatePort("my.con.read",0);
236 if(consoleReadPort
== 0)
237 { problem
= 7; goto cleanup7
; }
238 consoleReadMsg
= CreateStdIO(consoleReadPort
);
239 if(consoleReadPort
== 0)
240 { problem
= 8; goto cleanup8
; }
242 w
= (struct Window
*)OpenWindow(&nw
); /* create a window */
244 { problem
= 9; goto cleanup9
; }
246 rp
= w
->RPort
; /* establish its rastport for later */
248 /* ************************************************************************ */
249 /* NOW, Begin using the actual console macros defined above. */
250 /* ************************************************************************ */
252 error
= OpenConsole(consoleWriteMsg
,consoleReadMsg
,w
);
254 { problem
= 10; goto cleanup10
; }
255 /* attach a console to this window, initialize
256 * for both write and read */
258 QueueRead(consoleReadMsg
,&readstring
[0]); /* tell console where to
259 * put a character that
260 * it wants to give me
261 * queue up first read */
262 ConWrite(consoleWriteMsg
,"Hello, World\r\n",14);
264 ConPutStr(consoleWriteMsg
,"testing BACKSPACE");
266 { BACKSPACE(consoleWriteMsg
); Delay(30); }
268 ConPutStr(consoleWriteMsg
,"\r\n");
270 ConPutStr(consoleWriteMsg
,"testing TAB\r");
272 { TAB(consoleWriteMsg
); Delay(30); }
274 ConPutStr(consoleWriteMsg
,"\r\n");
276 ConPutStr(consoleWriteMsg
,"testing LINEFEED\r");
278 { LINEFEED(consoleWriteMsg
); Delay(30); }
280 ConPutStr(consoleWriteMsg
,"\r\n");
282 ConPutStr(consoleWriteMsg
,"testing VERTICALTAB\r");
284 { VERTICALTAB(consoleWriteMsg
); Delay(30); }
286 ConPutStr(consoleWriteMsg
,"\r\n");
288 ConPutStr(consoleWriteMsg
,"testing FORMFEED\r");
291 { FORMFEED(consoleWriteMsg
); Delay(30); }
293 ConPutStr(consoleWriteMsg
,"\r\n");
295 ConPutStr(consoleWriteMsg
,"testing CR");
299 ConPutStr(consoleWriteMsg
,"\r\n");
301 ConPutStr(consoleWriteMsg
,"testing INSERT\r");
303 { INSERT(consoleWriteMsg
); Delay(30); }
305 ConPutStr(consoleWriteMsg
,"\r\n");
307 ConPutStr(consoleWriteMsg
," testing DELCHAR\r");
310 { DELCHAR(consoleWriteMsg
); Delay(30); }
312 ConPutStr(consoleWriteMsg
,"\r\n");
314 ConPutStr(consoleWriteMsg
,"testing INSERTLINE\r");
317 { INSERTLINE(consoleWriteMsg
); Delay(30); }
318 ConPutStr(consoleWriteMsg
,"\r\n");
320 ConPutStr(consoleWriteMsg
,"testing DELETELINE\r");
322 LINEFEED(consoleWriteMsg
);
325 { DELETELINE(consoleWriteMsg
); Delay(30); }
326 ConPutStr(consoleWriteMsg
,"\r\n");
328 ConPutStr(consoleWriteMsg
,"testing CURSUP\r");
330 { CURSUP(consoleWriteMsg
); Delay(30); }
332 ConPutStr(consoleWriteMsg
,"\r\n");
334 ConPutStr(consoleWriteMsg
,"testing CURSDOWN\r");
336 { CURSDOWN(consoleWriteMsg
); Delay(30); }
338 ConPutStr(consoleWriteMsg
,"\r\n");
340 ConPutStr(consoleWriteMsg
,"testing CURSFWD\r");
342 { CURSFWD(consoleWriteMsg
); Delay(30); }
344 ConPutStr(consoleWriteMsg
,"\r\n");
346 ConPutStr(consoleWriteMsg
,"testing CURSBAK");
348 { CURSBAK(consoleWriteMsg
); Delay(30); }
350 ConPutStr(consoleWriteMsg
,"\r\n");
352 ConPutStr(consoleWriteMsg
,"testing CURSPREVLN");
354 { CURSPREVLN(consoleWriteMsg
); Delay(30); }
356 ConPutStr(consoleWriteMsg
,"\r\n");
358 ConPutStr(consoleWriteMsg
,"testing CURSNEXTLN");
360 { CURSNEXTLN(consoleWriteMsg
); Delay(30); }
362 ConPutStr(consoleWriteMsg
,"\r\n");
364 ConPutStr(consoleWriteMsg
,"testing ERASEEOD");
365 CURSPREVLN(consoleWriteMsg
);
366 CURSPREVLN(consoleWriteMsg
);
367 CURSPREVLN(consoleWriteMsg
);
370 { ERASEEOD(consoleWriteMsg
); Delay(30); }
372 ConPutStr(consoleWriteMsg
,"\r\n");
374 ConPutStr(consoleWriteMsg
,"testing ERASEEOL.junk");
375 CURSBAK(consoleWriteMsg
);
376 CURSBAK(consoleWriteMsg
);
377 CURSBAK(consoleWriteMsg
);
378 CURSBAK(consoleWriteMsg
);
379 CURSBAK(consoleWriteMsg
);
381 ERASEEOL(consoleWriteMsg
);
383 ConPutStr(consoleWriteMsg
,"\r\n");
385 ConPutStr(consoleWriteMsg
,"testing SCROLLUP");
387 { SCROLLUP(consoleWriteMsg
); Delay(30); }
389 ConPutStr(consoleWriteMsg
,"\r\n");
390 ConPutStr(consoleWriteMsg
,"testing SCROLLDOWN");
391 ConPutStr(consoleWriteMsg
,"\n\n\n");
393 { SCROLLDOWN(consoleWriteMsg
); Delay(30); }
395 ConPutStr(consoleWriteMsg
,"\r\n");
397 ConPutStr(consoleWriteMsg
,"testing CURSOROFF");
398 CURSOROFF(consoleWriteMsg
);
399 ConPutStr(consoleWriteMsg
, "printed.with.cursor.off");
401 ConPutStr(consoleWriteMsg
,"\r\n");
403 CURSORON(consoleWriteMsg
); Delay(30);
404 ConPutStr(consoleWriteMsg
,"testing CURSORON");
407 /* ************************************************************************ */
408 Delay(120); /* wait 2 seconds (120/60 ticks) */
410 status
= CheckIO((struct IORequest
*)consoleReadMsg
); /* see if console read
411 * anything, abort if not */
412 if(status
== FALSE
) AbortIO((struct IORequest
*)consoleReadMsg
);
413 WaitPort(consoleReadPort
); /* wait for abort to complete */
414 GetMsg(consoleReadPort
); /* and strip message from port */
416 CloseConsole((struct IORequest
*)consoleWriteMsg
);
421 DeleteStdIO(consoleReadMsg
);
423 DeletePort(consoleReadPort
);
425 DeleteStdIO(consoleWriteMsg
);
427 DeletePort(consoleWritePort
);
429 CloseLibrary(GfxBase
);
431 CloseLibrary((struct Library
*)IntuitionBase
);
433 CloseLibrary(DiskfontBase
);
435 CloseLibrary(DosBase
);
436 if(problem
> 0) exit(problem
+1000);
440 } /* end of main() */
443 /* Open a console device */
445 /* this function returns a value of 0 if the console
446 * device opened correctly and a nonzero value (the error
447 * returned from OpenDevice) if there was an error.
450 int OpenConsole(struct IOStdReq
* writerequest
, struct IOStdReq
* readrequest
, struct Window
* window
)
453 writerequest
->io_Data
= (APTR
) window
;
454 writerequest
->io_Length
= sizeof(*window
);
455 error
= OpenDevice("console.device", 1, (struct IORequest
*)writerequest
, 0);
456 readrequest
->io_Device
= writerequest
->io_Device
;
457 readrequest
->io_Unit
= writerequest
->io_Unit
;
458 /* clone required parts of the request */
462 /* Output a single character to a specified console */
464 int ConPutChar(struct IOStdReq
* request
,char character
)
466 request
->io_Command
= CMD_WRITE
;
467 request
->io_Data
= (APTR
)&character
;
468 request
->io_Length
= 1;
469 DoIO((struct IORequest
*)request
);
470 /* command works because DoIO blocks until command is
471 * done (otherwise pointer to the character could become
472 * invalid in the meantime).
477 /* Output a stream of known length to a console */
479 int ConWrite(struct IOStdReq
* request
, char * string
, int length
)
481 request
->io_Command
= CMD_WRITE
;
482 request
->io_Data
= (APTR
)string
;
483 request
->io_Length
= length
;
484 DoIO((struct IORequest
*)request
);
485 /* command works because DoIO blocks until command is
486 * done (otherwise pointer to string could become
487 * invalid in the meantime).
492 /* Output a NULL-terminated string of characters to a console */
494 int ConPutStr(struct IOStdReq
* request
, char * string
)
496 request
->io_Command
= CMD_WRITE
;
497 request
->io_Data
= (APTR
)string
;
498 request
->io_Length
= -1; /* tells console to end when it
499 * sees a terminating zero on
501 DoIO((struct IORequest
*)request
);
505 /* queue up a read request to a console, show where to
506 * put the character when ready to be returned. Most
507 * efficient if this is called right after console is
510 int QueueRead(struct IOStdReq
* request
, char * whereto
)
512 request
->io_Command
= CMD_READ
;
513 request
->io_Data
= (APTR
)whereto
;
514 request
->io_Length
= 1;
515 SendIO((struct IORequest
*)request
);
519 /* see if there is a character to read. If none, don't wait,
520 * come back with a value of -1 */
523 ConMayGetChar(request
,requestPort
, whereto
)
524 struct IOStdReq
*request
;
525 struct MsgPort
* requestPort
;
530 if ( GetMsg(requestPort
) == NULL
) return(-1);
532 QueueRead(request
,whereto
);
536 /* go and get a character; put the task to sleep if
537 * there isn't one present */
540 ConGetChar(consolePort
,request
,whereto
)
541 struct IOStdReq
*request
;
542 struct MsgPort
*consolePort
;
546 while((GetMsg(consolePort
) == NULL
)) WaitPort(consolePort
);
547 temp
= *whereto
; /* get the character */
548 QueueRead(request
,whereto
);