From: falk@peregrine.Sun.COM (Ed Falk)
Newsgroups: comp.sys.palmtops
Subject: Re: HP95LX DOCUMENTATION WANTED!
Date: 11 Nov 1992 21:32:26 GMT
Organization: Sun Microsystems, Mt. View, Ca.
NNTP-Posting-Host: peregrine

On top of what comes in hp95dev.zip, I have this information.  This is
deduced from what's in hp95dev, sample programs, the interrupt list,
and trial and error.  I make no warranties about the accuracy of this
information (HP wouldn't accept me as a developer, the snobs), but it's
worked for me so far.  There's an excellent article that was just
posted on the development of .exm programs.  I also have some utility
routines which I find very useful.

I invite other hp hackers to fill in the blanks.  In particular, how
do you read directories?




	.exm interface is defined in interfac.h

	Macros coerce all pointers to FAR pointers.

	Start all programs with m_init() ;
	Call m_event(&EVENT) to get next event.
	End with m_fini() ;
	Do not call anything from C library you don't have to.  Especially
	stay away from i/o calls.
	Link HP's crt0.obj instead of C's.


/*SC_PM*/

	m_init()		start program
	m_fini()		exit
	m_lock()		inhibit task switches
	m_unlock()		release task lock

	m_spawn(char *command, int len, 0, char *prompt)
	    execute command with COMMAND.COM.  command must end
	    with \r.

	m_appcount()
	m_reboot()
	m_spawnarg(a*,b,c*,d)
	m_reg_app_name(a*)
	app_name(a*)


/* SC_EVENT */

	m_event(EVENT *)
		get an event, time out after .5 sec.  Returns E_NONE for
		timeout or for change in shift keys.

	m_nevent(EVENT *)
		get an event, return immediately if none.  Also, E_KEY
		events are left in queue.

	int m_sh_status()	return shifts
	bridge_serv()		lotus 123 only
	m_flush_kb()		flush keyboard buffer
	m_yield(EVENT *)	yield cpu; expect E_ACTIV event on return
	m_no_fini(EVENT *)	veto termination.


	      event.shifts:
		02	shift
		04	ctrl
		08	alt
		10	scrolllock(?)
		20	numlock(?)
		40	caps
		80	insert

/*SC_MENU */

	See <menu.h>.  MENUDATA structure:

	menu_setup(MENUDATA *,		menudata structure to fill
		char * menustr,		series of null-terminated strings
					("foo\0bar\0quit")
		int nmenu,		# of strings in menustr
		bool,			double-spaces between items
		char * tprompt,		top-line prompt
		int tplen,		length of tprompt
		NULL)			NULL (long_prompts??)

	menu_on(MENUDATA *)		enable menu
	menu_dis(MENUDATA *)		display menu
	menu_off(MENUDATA *)		remove menu

	menu_key(MENUDATA *, int event.data, int *menuselect)
		Pass keyboard events to the menu, returns item selected
		in menuselect (0-based) or -1 if nothing selected yet.



/*SC_MENU */

	File Menus:  See <fmenu.h> FMENU structure and <edit.h> EDITDATA
	structure.  First, fill the structure with some info:

		#define	NFILES	50
		FILEINFO	fmbuffer[NFILES];

		FMENU fmenu = {
			(char far *) "C:\\_DAT",	/* path */
			(char far *) "*.TXT",		/* pattern */
			( FILEINFO far * ) fmbuffer,	/* file info */
			sizeof(fmbuffer),		/* sizeof(file info) */
			-2, 0,				/* start line,col */
			13, 40,				/* #lines, #cols */
			3				/* files/line */
			};

		fmenu.fm_pattern = "*.TXT" ;	/* set again before calling
						   fmenu_init */

	Next, fill in some edit_data fields:

		EDITDATA edit_data ;

		edit_data.prompt_window = TRUE;	   /* put in prompt win. */
		edit_data.message_line = "File to use:" ;
		edit_data.message_line_length = strlen(edit_data.message_line);
		edit_data.prompt_line_length = 0;


	fmenu_init( FMENU *fmenu,	FMENU structure to init
		EDITDATA *editdata,	edit_data for FMENU to use
		"pattern",		eg: "*.txt"
		int len,		length of pattern
		int maxlen?)		not used

	    Initialize FMENU structure.  fmenu and editdata should be
	    initialized as shown above.  If "pattern" is NULL, uses the
	    pattern in fmenu and display a list of matches.


	fmenu_dis(FMENU *,EDITDATA *)	display file menu

	int fmenu_key(FMENU *, EDITDATA *, int event.data)
		Pass an event to fmenu.  Returns RET_OK, RET_REDISPLAY,
		RET_ACCEPT, etc.  See <fmenu.h>

	fmenu_off(FMENU *,EDITDATA *)	turn off fmenu, remove from screen.


/*SC_SCREEN*/

	m_disp( int row,		row, -3 = top of screen
		int col,		col, 0 = left
		char *msg,		text to display
		int msglen,		length of text
		int style,		style
		0)			??
	    display text.  "style" is the OR of these bits:
	    01h=inverse, 04h=underline, 08h=blink

	m_clear(row,col,rows,cols)	clear part of screen
	m_scroll(row,col,rows,cols,n)	scroll part of screen "n" lines
					n<0 scrolls up, n>0 scrolls down
	m_chrinv(row,col,len)		invert characters?

	m_xchg(row,col,nrows,ncols,char *region)	??

	m_chrattr(char *buf, int len)
		get chars and attrs, starting from top-left of screen

	m_chrrvrt(row,col,char *buf, len)	??

	m_rows_cols()		returns 1028h (rows<<8 + cols)
	m_setmode(a)		1=text mode, 2=graphics
	m_getmode()		return current mode
	m_setcur(row,col)	place cursor.  Set col=-1 to put off screen

/*SC_EDIT*/

	See <edit.h>, EDITDATA structure

	edit_init(		setup for editing
		EDITDATA *e,	  structure to set up
		char *init,	  initial value
		int len,	  length of above
		int max,	  max length
		int row,col)

	edit_top(		setup for editing, top line
		EDITDATA *e,	  structure to edit
		char *init,	  initial value
		int len,	  length of above
		int max,	  max length
		char *prompt1,	  first line prompt
		int len1,
		char *prompt2,	  second line prompt
		int len2)

	    Set up for editing at top of screen.  Edit buffer will
	    follow last character of prompt2.

	edit_dis(EDITDATA *e)	display edit buffer

	edit_key( EDITDATA *e, app_event.data, int *result)
		hand keystroke to editor.  Returns 1 in result if user
		accepts, 0 otherwise.  Results in e.edit_buffer


	Multi-line editing, see <edit.h>, MDITDATA structure

	mdit_ini(MDITDATA *,		structure to init
		int row,col,lines,cols,	region
		int len,		maximum length of buffer
		char *buffer,		buffer
		bool flag,		enable wrap-around
		rows,			rows on screen
		int *work)		workspace

	    Set up for multi-line edit.  row,col,rows,cols defines
	    the region on the screen; lines is the number of lines in
	    the buffer.  work is a workspace used by MDIT; it needs
	    to be at least (lines+1)*sizeof(int) long.

	mdit_dis(MDITDATA *)		display edit buffer

	mdit_key(MDITDATA *,int key)
		Pass keystroke to MDIT

	mdit_fil(MDITDATA *,FILE *)	write buffer to file

	mdit_ins_str(MDITDATA *,char *str,int len)
		insert text

	mdit_mark(MDITDATA *)		start marking
	mdit_unmark(MDITDATA *)		end marking
	mdit_cutmark(MDITDATA *)	delete marked characters
		Note that these functions do not handle the cut/paste
		buffer.  The application must manually save marked data
		if it wants.  The marked data is defined by the markst
		and markend fields in MDITDATA

/*SC_FILE*/

	See <fileio.h>.  Note that this definition of FILE is incompatible
	with <stdio.h>

	int
	m_open( FILE *,			you provide the FILE structure
		char *filename,		file to open.  Returns 0 on success,
		int len,		error code on failure.
		attrs,
		BOOL nobuffering)

	m_openro(FILE *,name,len,att,nb)	open read-only
	m_create(FILE *,name,len,att,nb)	open only if doesn't exist
	m_fcreat(FILE *,name,len,att,nb)	open and truncate
	m_tell(FILE *, long *rval)		get file pointer
	m_close(FILE *)				close file
	m_delete(char *name, int namelen, 0)	delete file, ignore 3rd arg.
	m_setdir(char *name, int len)		set cwd, may include drive.
	m_mkdir(char *name, int len, 0)		mkdir
	m_rmdir(char *name, int len, 0)		rmdir
	m_setdrv(char drv)			set current drive
	m_fdate(FILE *,char *rval)		get file date and time (string)
	m_getfdt(FILE *,long *date)		get file data and time (long)
	m_get_sysdir(char *)			get sys dir, eg "C:\_DAT"
	m_common_open(a*,b*,c,d,e,f,g)
	m_copydt(FILE *src,FILE *dst)		copy date and time
	m_putfdt(FILE *,long date)		set file data and time

	m_read(FILE *, caddr_t addr, int len, int *rlen)
		Read from file.  Returns 0 on success or EOF, error code on
		failure.  EOF if rlen != len.

	m_write(FILE *, caddr_t addr, int len)
		write..  Returns 0 on success, error code on failure.

	m_getdrv(char *drive)
		returns current drive, eg: 'A'.

	m_getdir(char drive, char *path, int *len)
		return current path for given drive, eg: "A:\TMP".  len
		is returned length of returned path

	m_getattr(char *name, int namelen, 0, unsigned *attr)
		get file attributes

	m_setattr(char *name, int len, 0, int attr)
		set file attributes

	m_ident(char *name, int len, 0, int *rval)
		get file type: 0=not found, 1=file, 2=directory, 3=device

	m_setpat(MATCH *, char *name, int len, 0)
		initialize a MATCH structure.

	m_match(MATCH *, int *flag)
		find next match described by MATCH.  sets flag to 0 if
		no match found.  Returns 0 or error code.

	m_rename(char *oldname, char *newname, int len1, 0, int len2, 0)
		rename a file.

	m_seek(FILE *, int mode, long offset)
		set file pointer relative to mode.  mode is one of
		seek_beginning, seek_current, seek_end

	m_volume(char *name, long *size)
		sets name to volume name, size to # free bytes on disk

/*SC_CB*/

	see <cbcodes.h>.  Data in a clipboard can have several
	representations.  The representation "TEXT" should always be
	created and should always be understood.  Lines of text should
	be ended with single \r.  Returns codes are in <cbcodes.h>

	m_open_cb()		open clipboard, returns 0 on success

	m_reset_cb(char *name)
		clears clipboard and announces that application "name"
		is now responsible for its contents.

	m_new_rep(char *rep)	prepare to write new data representation.

	m_cb_write(char *data, int len)
		write data to representation.

	m_fini_rep()		done writing current representation.

	m_rep_index(char *name, int *rindex, int *rlength)
		get index and length of named representation.  Returns
		0 on success, error code on error.

	m_rep_name(int index, char *rname, int *rlength)
		get the name and length of indexed representation.  Returns
		0 on success, error code on error.

	m_cb_read(int index, int offset, char *data, int length)
		read data from indexed representation.

	m_close_cb()		close clipboard, returns 0 on success

/*SC_SOUND*/

	m_beep()		beep
	m_thud()		thud
	m_asound(int)		0-9 sound library
	m_soundoff()		stop a sound

/*SC_MM*/

	void near *m_alloc(int bytes)
		allocate memory, near pointer

	m_free(void *ptr)		(near pointer to block?)

	void near *m_alloc_large(int paragraphs)
		allocate "paragraphs" 16-byte paragraphs

	m_free_large(int paragraphs)

/*SC_DTIME*/

	See <smtime.h>

	m_dtinfo(DTINFO *)		fill DTINFO struct (why?)
	m_getdtm(DTM *)			get date and time
	m_setdtm(DTM *)			set date and time
	m_alarm(ALARM *, u_int client)	sets an alamrm
	m_xalarm(u_int client)		kill alarms that match client
	m_start_sw(a)
	m_get_sw(TIME *,TIME *,char *)
	m_stop_sw(a)
	m_get_settings(a,b)
	m_set_settings(a,b)
	m_start_timer(a)
	m_stop_timer(a)
	m_get_timer(TIME *,TIME *,char *)
	m_telltime(flag,row,col)	see DATE_N_TIME in smtime.h
	m_set_daterule(a)
	m_set_timerule(a)
	m_posttime()			display current date & time
	m_day_trigger(a)

	m_parse_date(int rule, char *input, DTM *rval)
		parse a date.  rule is 0 to use system date format or
		use a value from settings.h (see DR_DMY_LIM.)

	m_parse_time(int rule, char *input, DTM *rval)
		parse a time.  rule is 0 to use system date format or
		use a value from settings.h (see TM_H_M_S_P.)

	m_tell_anytime(flag,row,col,DTINFO *,DTM *)

	SETTINGS *m_get_settings_addr()
		Gets a pointer to settings structure.  Treat this as
		read-only.  see <settings.h>


/*SC_PRINTER */

	m_open_printer()		open printer
	m_close_printer()		release printer
	m_write_printer(str,len)	print
	m_init_printer()
	m_fall_printer(a,b)

	m_trans_printer(char c, char *buf)
		translate character c to string that will produce that
		character on current printer.

/*SC_COMM*/

	See <comio.h>, com_handle, com_settings structure

	InitCom(a)

	ComOpen(com_handle *,int line)	open line, returning handle

	ComClose(com_handle)		close line

	int ComGetModem(com_handle)	returns modem type (see COM_MDM_HAYES)

	ComAnswer(com_handle, COM_ANS_NOWAIT)
		put moden into answer mode.

	ComDial(com_handle, char *number)
		dial a phone number

	ComReset(com_handle,flags)	see COM_RESET_LINE
	ComHangUp(com_handle)		hang up modem

	ComSendBytes(com_handle, char *buf, int flags, int *len)
	    Send len characters.  Actual # of chars queued is returned
	    in len.  flags: see COM_CTL_WHOLE

	ComReceiveBytes(com_handle, char *buf, int *len)
	    receive len characters.  Actual # of chars received is put
	    into len.  returns 0 on success, error code on error.

	ComQryRxQue(com_handle,		query receive queue
		int *size,		  returned buffer size (constant)
		int *free)		  returned free bytes in buffer
					note: if size != free, then there are
					bytes in the buffer.

	ComQryTxQue(com_handle, int *size, int *free)

	ComHayesCommand(com_handle, char *cmd, int cmdlen)
		send hayes command to modem (translated for other modems?)

	ComCommand(com_handle, char *cmd, int cmdlen)
		send command verbatim to modem

	ComBreak(com_handle, int n)	send a break for n ms
	ComForceXon(com_handle)		force Xon state
	ComForceXoff(com_handle)	force Xoff state
	ComSetDtr(com_handle, bool)	set DTR off/on
	bool ComXmitting(com_handle)	return TRUE if transmitting
	int ComStatus(com_handle)	get status, 0=no error. See E_OVERN
	ComSet(com_handle,com_settings*)	set settings
	ComGet(com_handle,com_settings*)	get settings
	ComConfigure(a,b,c,d,e)
	int ComQryErr(com_handle)	get error, see E_OVERN


/*SC_MISC*/

	m_errmsg(int code, char *buf, int len, int *rlen)
		get text for given error code.  See <m_error.h>

	drawbox(char *name)		clear screen, draw standard program
					box with name at -3,0
	showname(char *name)		show program name at -3,0
	message(str,len,str2,len2)	display message
	msg_off()			undisplay message, restore screen
	com_timer_addr()
	com_timer_count_addr()
	m_sys_rsrc_addr()

	message3(str,len,str2,len2,str3,len3)
	m_disable_macros()
	m_enable_macros()
	char *m_form_ft(DTM *dtm)	return date & time for directory list
	m_ram_iv_info(a)



/*SC_VIDVIR*/

	m_dirty_sync()		sync display



/*SC_RSRC*/

	map_resource_file(a)
	get_resource_ptr(a)
	get_rsrc_tab_ptr()
	init_sysmgr_resources()




/*SC_HELP*/


	m_help_init(a,b,c)
	m_help_display(a)
	m_help_key(a,b)
	m_help_term(a)


/*SC_COL*/

	collating services

	m_col_init()			init codepage comparator.

	int
	m_col_cpstr(char *s1, int l1, char *s2, int l2)
		codepage 850 character compare.  case and accent
		are ignored.  Returns -1,0,+1 if s2<,=,>s1

	m_col_tolower(char *str, int len)
		convert codepage 850 characters in str to lower-case

	m_col_toupper(char *str, int len)
		convert codepage 850 characters in str to lower-case

	int
	m_col_cpsearch(char *str, int slen, char *buf, int blen, int dir)
		search for str in buf, return offset in buf if found, else
		0.  m_col_cpstr() is used for comparisons.  dir is +1 for
		forward search, -1 for backward search.




/* SPECIAL BIOS CALLS */

	/* allow process to run at full speed; eats batteries */

	disable_light_sleep(void)
	{
	_asm  {
		mov ax,4e00h
		int 15h
	      }
	}

	enable_light_sleep(void)
	{
	_asm  {
		mov ax,4e01h
		int 15h
	      }
	}
		-ed falk, sun microsystems
		 sun!falk, falk@sun.com
To be loyal to rags, to shout for rags, to worship rags, to die for rags 
-- that is a loyalty of unreason, it is pure animal (Mark Twain).
Newsgroups: comp.sys.palmtops