From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.7 required=5.0 tests=BAYES_00,INVALID_DATE, MSGID_SHORT,REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 Path: utzoo!attcan!uunet!lll-winken!lll-lcc!ames!pasteur!ucbvax!decwrl!decvax!savax!lewin From: lewin@savax.UUCP (Stuart Lewin) Newsgroups: comp.lang.ada Subject: Ada, VADS 5.5h and Sun3 Frame Buffers Summary: help!!! Message-ID: <747@savax.UUCP> Date: 18 May 88 15:12:38 GMT References: <8805171509.AA23218@ajpo.sei.cmu.edu> Reply-To: lewin@savax.UUCP (Stu Lewin) Organization: Sanders Associates Inc., Nashua, NH List-Id: Well, what started out as a simple programming project while fooling around with Ada has become extremely frustrating and so I'm appealing for help to all you Ada gurus out there in net-land. We have a program here called "dark" which is used to clear a Sun workstation screen when you logoff. I want to rewrite "dark" in Ada. It works by opening the framebuffer and then writing directly to it in order to turn all the pixels off. My system configuration consists of a monochrome frame buffer that is currently attached to a Sun3 running SunOS 3.5. The system is using the colorboard as the system console (/dev/fb(?)). I'm using VADS 5.5h as my Ada environment. Although dark obviously works, I also wrote another simple C program that simply opens the frame buffer (/dev/bwtwo0), does a "valloc" in order to get a matching array of unsigned chars and then does a mmap. I can then write to the array directly and have it appear on the screen. So I'm fairly confident that I can do what I want to do. What follows is the Ada program that attempts to do the same, and the C routine to open the device and mmap it. If I run it, however, mmap fails with error EINVAL (appearing to fail since I get buffer addresses from the Ada code that aren't aligned on a page boundary as required). I can print out elements of the array from within the C code, so I would assume this means that the right address is being passed. What appears to be failing is the record representation spec for the frame buffer, in that the "at mod 8192" is not placing it correctly. I've tried all the record and (record) access types permutations that I can think of and can't get this to work. From reading the VADS documentation, I can't see anything that says this wouldn't work. Can anyone help me out with this - am I trying to do something completely foreign to Ada or just making a stupid mistake somewhere. Please reply to me directly... Thanks In Advance, Stu ...!decvax!savax!lewin Disclaimer: My opinions are my own, and in no way reflect those of my supervisor, or my supervisor's supervisor, ..., or anyone else at either Sanders or Lockheed -- Whew, all that just to ask a question! ------------------------------------------------------------------------------- -------------------- -----File: fb_test.a -------------------- ------------------------------------------------------------------------------- with System; with Text_IO; use Text_IO; procedure FB_Test is type MY_UNSIGNED_CHAR_TYPE is range 0 .. (2 ** 8) - 1; for MY_UNSIGNED_CHAR_TYPE'SIZE use 8 * 1; type MY_INT_TYPE is range -(2 ** 32)/2 .. (2 ** 32)/2 - 1; for MY_INT_TYPE'SIZE use 32 * 1; System_Page_Size : constant MY_INT_TYPE := (8192 * 8) / System.Storage_Unit; Frame_Buffer_Size : constant MY_INT_TYPE := (131072 * 8) / System.Storage_Unit; type Frame_Buffer_Type is array(MY_INT_TYPE range <>) of MY_UNSIGNED_CHAR_TYPE; type Frame_Buffer_Record_Type is record Image : Frame_Buffer_Type(1 .. Frame_Buffer_Size); end record; for Frame_Buffer_Record_Type use record at mod System_Page_Size; Image at 0 range 0 .. (Frame_Buffer_Size*System.Storage_Unit - 1); end record; for Frame_Buffer_Record_Type'SIZE use Frame_Buffer_Size * 8; Frame_Buffer : Frame_Buffer_Record_Type; package My_Integer_IO is new Integer_IO(MY_INT_TYPE); use My_Integer_IO; --------------------------------- -- Unix/C Procedure Specification --------------------------------- procedure Unix_Frame_Buffer_Init(FB : in System.Address; Size : in MY_INT_TYPE); pragma Interface(C, Unix_Frame_Buffer_Init, "_unix_frame_buffer_init"); begin -- store some values for debugging on the c side Frame_Buffer.Image(1) := 3; Frame_Buffer.Image(2) := 17; Frame_Buffer.Image(3) := 60; Frame_Buffer.Image(4) := 0; Frame_Buffer.Image(5) := 10; Frame_Buffer.Image(131067) := 5; Frame_Buffer.Image(131068) := 6; Frame_Buffer.Image(131069) := 7; Frame_Buffer.Image(131070) := 8; Frame_Buffer.Image(131071) := 9; Frame_Buffer.Image(131072) := 10; Put("Pagesize is "); Put(System_Page_Size); New_Line; Put("FrameBuffer size is "); Put(Frame_Buffer_Size); New_Line; Put("Record size is "); Put(Frame_Buffer.Image'SIZE / System.Storage_Unit); New_Line; -- open frame buffer and map it to physical device Unix_Frame_Buffer_Init(Frame_Buffer.Image'ADDRESS, Frame_Buffer_Size); -- now write to frame buffer and erase screen (on a sun 1 = OFF) for Index in Frame_Buffer.Image'FIRST .. Frame_Buffer.Image'LAST loop Frame_Buffer.Image(Index) := 16#ff#; end loop; end FB_Test; ------------------------------------------------------------------------------- ----------------------------------- -----File: unix_frame_buffer_init.c ----------------------------------- ------------------------------------------------------------------------------- #include #include #include #define DEBUG 1 extern int errno; unix_frame_buffer_init(logical_address, length) char *logical_address; int length; { int prot; int share; int fd; off_t off; char *pBuff; int i; #ifdef DEBUG printf("\nunix_frame_buffer_init:\n"); printf("logical_address: %d\n", logical_address); printf("length : %d\n", length); /* * print out the values at beginning & end to make sure address passed * correctly */ for(i=0, pBuff=logical_address; i<5; i++, pBuff++) printf("%d(th) array element is: %d\n",i,*pBuff); for(i=length, pBuff=logical_address+length; i>length-5; i--) printf("%d(th) array element is: %d\n",i,*(--pBuff)); #endif /* open monochrome framebuffer */ if((fd = open("/dev/bwtwo0", O_RDWR)) < 0) { printf("Error opening device; errno = %d\n", errno); } else { /* map it to user space */ if (mmap(logical_address, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0) < 0) { printf("Error mapping device; errno = %d\n", errno); } } } ----The End!!!