BudgieSoft door hints (release 5) The 'CastAVote' protocol: CastAVote demanded the use of a WIMP message to broadcast to other versions running concurrently the vote choice selected, or new votes added et cetera. The idea was to keep all copies up to date - whereever they were held. That was expanded to allow my Parlez door to broadcast a message to a user if they're in CastAVote. Two extra bits were added, one for Virtual Cafe and another for any message. At this time it doesn't appear that the author of Virtual Cafe has implemented the protocol. Never mind though, you can... Specification for Wimp Message &16F00: This is BudgieSoft's Wimp_Message number. Several of the viable codes call CastAVote to update. It is sent out as a Wimp_Broadcast. It should not be replied. We are hereby referring to the Wimp data block as wimp%. Block received: message_action = wimp%!20 To receive: If wimp%!16 returned by Wimp_Poll = &16F00, then: DEFPROCmessage_16F00 msgaction%=wimp%!20 CASE msgaction% OF WHEN 1 : Message action 1... WHEN 2 : Message action 2... etc. ENDCASE ENDPROC Current &16F00 action codes: 1 - Load new vote from 'MyQ' [CastAVote, don't use] 2 - Update vote results [CastAVote, don't use] 3 - Message inbound from !Parlez [use by permission] 4 - Message inbound from VirtualCafe [use by permission] 5 - Message inbound [feel free to use] 6 - Exit_And_Die_Request [CastAVote, don't use!] 7 - Reserved for CastAVote 8 - Delete vote [CastAVote, don't use!] 12 - MTerm remote internal message [Don't use.] This will be followed by whatever code it is aliasing. If you recognise this code aimed at you, wait for the alias code, and mark a flag for MTerm. 60 to 79 are reserved for BudgieSoft test applications. Proper implementations of the &16F00 protocol will open a file called "MsgIn_XX" (XX=action code) and then dump the contents of the message. These messages won't be replied or noticed by the user. Release software will not use these codes. Action codes 3, 4 and 5: 3: This will print the sender's name and the message on the screen. 4: This will print " invites you for coffee and a chat in Virtual Cafe." As far as I am aware, Graham hasn't implemented this yet into Virtual Cafe. 5: This will print whatever is received. Construct your own message. Little note: The !Natter SysOp chat door (by Chris Jackson) supports the &16F00 message protocols. :-) The Wimp_Message &16F00 message sending protocols: ACTION CODE 3: [PROCmsg_inbound] Right... The message action is wimp%!20, and the string is passed as $(wimp%+24). The string is laid out in the following format: Chars Meaning 1,2 The port number of the recipient. If this is not the port that CastAVote/application is on, the message should be ignored. 3,4 The port number of the sender (for the 'on port #' text). 5-37 The name of the message sender, trailing spaces. 38-40 Not used. Spaces. 41+ The message. If the message is >79 chars, it should be split across two lines. The incoming message shouldn't be >158 chars, if it is - chop the end off... The limit is 158. The output is up the top of the screen, in the form: INCOMING MESSAGE: From on port # ACTION CODE 4: [PROCmsg_virtualcafe] Right... The message action is wimp%!20, and the string is passed as $(wimp%+24). The string is laid out in the following format: Chars Meaning 1,2 The port number of the recipient. If this is not the port that CastAVote/application is on, the message should be ignored. 3+ The name of the user sending the message, zero terminated. The output is up the top of the screen, in the form: invites you for coffee and a chat in Virtual Cafe. THIS IS ONLY FOR USE BY VIRTUAL CAFE. ACTION CODE 5: [PROCmsg_unknown] Right... The message action is wimp%!20, and the string is passed as $(wimp%+24). The string is laid out in the following format: Chars Meaning 1,2 The port number of the recipient. If this is not the port that CastAVote/application is on, the message should be ignored. 3+ The message, zero terminated. The output is up the top of the screen, in the form: This is so you can build your own custom messages... The DOING display: If you're not interested in the reproduced DOING display, feel free to skip this... It may be a bit on the techie side, for which I make no apologies... :-) Right, Hugo says the SYS call "ARCbbsFiler_GetStatusPointer" returns the necessary information from the RMA. R0 is a pointer to the following structure: struct { int baudrate,usernumber; char username[31]; char doing[13]; char fill[7]; } /* 64 bytes */ In BASIC, we shall assume the following: DIM userstat% 4096 SYS "ARCbbsFiler_GetStatusPointer" TO userstat% Then, userstat%!0+offset% will be either a baudrate (as shown by ArcBBS) or -1 if the port is not in use. offset% is used because the data repeats at userstat%!64, userstat%!128 etc... This extract is simplified. All text within { curly brackets } is a comment, not part of the code: DEF PROCio(show) {the show variable is used because this routine is called again just before sending the message, to check the port is around. However, this time we don't want the data displayed} IF show=TRUE THEN {set up the screen} PROCdoors_tx(esc$+"2J"+esc$+"32mDOING"+CHR$10+CHR$13) PROCdoors_tx(esc$+"44m"+esc$+"37m"+" # "+esc$+"36mBaudR "+esc$+"37m User# "+esc$+"36mUsername "+esc$+"37m Where " +esc$+"40m"+CHR$10+CHR$13) {the 3 lines above are all one line. I've included the codes to make it easier for you if you just want to copy ArcBBS's DOING style...} ENDIF SYS "ARCbbsFiler_GetStatusPointer" TO userstat% FOR loop=0 TO 36 {scanning all possible ports, >12 is undefined on ArcBBS1.63.} speed%=userstat%!(loop*64 {this is the alternative to offset%} IF speed%=-1 THEN port%(loop)=FALSE {port%() is TRUE if port in use, FALSE if port not in use or '2' if logging on. The logging on value is set later. It's TRUE for now.} ELSE port%(loop)=TRUE IF show=TRUE THEN PROCshowstats {PROCshowstats displays stats} ENDIF NEXT nowfinished%=TRUE {then quit?} ENDPROC DEFPROCshowstats pointer%=(64*loop) {setting pointer% - which is similar to offset% as shown above} speed%=userstat%!pointer% {first extract the baudrate} pointer%=(64*loop)+4 {increment the pointer} usernumber%=userstat%!pointer% {extract the usernumber} pointer%=(64*loop)+8 {increment the pointer} username$="" {blank the username} REPEAT {the following REPEAT...UNTIL loop extracts the string from a variable. Door programmers should be au fait with this idea. :-)} C%=userstat%?pointer% : pointer%+=1 IF C%>31 username$+=CHR$C% UNTIL C%<32 pointer%=(64*loop)+39 doing$="" {blank the doing string} REPEAT {and extract it} C%=userstat%?pointer% : pointer%+=1 IF C%>31 doing$+=CHR$C% UNTIL C%<32 IF doing$="Logging on" OR doing$="New user" THEN port%(loop)=2 : EN DPROC {If logging on, set port%() to 2 to reflect this, and don't display} {The following displays the information in ArcBBS DOING style...} pad%=3-LEN(STR$(loop)) PROCdoors_tx(esc$+"36m"+STRING$(pad%," ")+STR$(loop)+" ") pad%=5-LEN(STR$(speed%)) PROCdoors_tx(esc$+"37m"+STRING$(pad%," ")+STR$(speed%)+" ") pad%=5-LEN(STR$(usernumber%)) PROCdoors_tx(esc$+"36m"+STRING$(pad%," ")+STR$(usernumber%)+" ") pad%=30-LEN(username$) PROCdoors_tx(esc$+"37m"+username$+STRING$(pad%," ")+" "+esc$+"36 m"+doing$+esc$+"37m") PROCdoors_tx(CHR$10+CHR$13) ENDPROC PROCdoors_tx: This is my revision of PROCdoors_sendstring... Below is the readable form... DEFPROCdoors_tx(a$) LOCAL f% FOR f%=1 TO LENa$ REPEAT SYS "ARCbbsDoors_OutputStatus",port_in_use% TO s% IF s%=0 PROCwindow_poll UNTILs%>0 SYS "ARCbbsDoors_OutputWrite",port_in_use%,(ASC(MID$(a$,f% ,1))) NEXT ENDPROC This is the same routine below, but it offers vast speed improvements... DEFPROCdoors_tx(a$) LOCAL f%, piu% piu%=port_in_use% FOR f%=1 TO LENa$ REPEAT SYS &41048,piu% TO s% IF s%=0 SYS &400C7,0,wimp% {or 'block%' or 'q%' etc} UNTILs%>0 SYS &41049,piu%,(ASC(MID$(a$,f%,1))) NEXT ENDPROC ANSI codes: Note, this isn't always STRICTLY ANSI. The 'ANSI' terminal appears at the moment to be a mish-mash of ANSI, VT100 and bolt-on ideas. These commands should be tested on at least two comms programs before you implement them. Note that cursor home position is 1,1... ArcBBS users will be used to the code _>0000 - just add one to the ArcBBS code to get the real ANSI for it. The sequence ESC doesn't mean 'E S C', it means ESCape, character 27, &1B. So 'ESC[11A' is '<&1B> [ 1 1 A'. Keystrokes: Pressing a particular key in a comms program will send a code, here are the special codes: Left cursor key ESC[D Right cursor key ESC[C Up cursor key ESC[A Down cursor key ESC[B Home key ESC[H End key ESC[K Ctrl + Home key ESC[L Ctrl + Page Up key ESC[M Function key 1 ESCOP Function key 2 ESCOQ Function key 3 ESCOw Function key 4 ESCOx * - Not all terminals send function key codes. Maybe this is VT100? ASCII codes that affect the terminal: &7 ^G Beep &8 ^H Destructive backspace &9 ^I Tab &A ^J Line feed, scroll if necessary &C ^L Clear screen and home cursor (1,1) &D ^M Return, move cursor to column 1. It should be noted that to 'continue on the next line properly', you must send a CHR$13 and a CHR$10 (return cursor, move down a line). Scroll up ESCD The screen is scrolled up one line. The bottom line is filled with spaces coloured according to the current attributes. Note, there is no left bracket '[' after the ESC. Scroll down ESCM The screen is scrolled down one line. The top line is filled with spaces coloured according to the current attributes. Note, there is no left bracket '[' after the ESC. Reset terminal ESCc This command resets the terminal to its defaults. However this is not recommended. Here is what the hard-reset does: - Set all features in set-up screens to default saved settings. - Can cause a line disconnect on some 'real' terminals. - Clears user defined keys (if available). - Clears the soft character set (if available). - Home cursor. - Select normal graphics type. - Select default character set. Insert character ESC[@ Insert a space at the current cursor position. The current attributes are used for the space. The character moved from column 80 is discarded, not wrapped. Set character sets on VT100 terminals ESC[(A Set United Kingdom G0 character set (setukg0) ESC[)A Set United Kingdom G1 character set (setukg1) ESC[(B Set United States G0 character set (setusg0) ESC[)B Set United Stated G1 character set (setusg1) ESC[(0 Set G0 special characters and line set (setspecg0) ESC[)0 Set G1 special characters and line set (setspecg1) ESC[(1 Set G0 alternate character ROM (setaltg0) ESC[)1 Set G1 alternate character ROM (setaltg1) ESC[(2 Set G0 alternate character ROM and special graphics (setaltspecg0) ESC[)2 Set G1 alternate character ROM and special graphics (setaltspecg1) CUrsor Up (CUU) ESC[A ( ESCA to move cursor up a line on VT52) The cursor up sequence moves the cursor up by the specified number of rows. If rows is not specified, the cursor will be moved up one line. When the cursor reaches the top of the display, it will stay there (not wrapped). CUrsor Down (CUD) ESC[B ( ESCB to move cursor down a line on VT52) The cursor down sequence moves the cursor down by the specified number of rows. If rows is not specified, the cursor will be moved down one line. When the cursor reaches the bottom of the display, it will stay there (not wrapped). CUrsor Forward (CUF) ESC[C ( ESCC to move cursor right 1 character on VT52) The cursor forward sequence moves the cursor to the right by the specified number of columns. If columns is not specified, the cursor will be moved right one column. When the cursor reaches the far right of the display, it will stay there (not wrapped). CUrsor Backward (CUB) ESC[D ( ESCD to move cursor left 1 character on VT52) The cursor backward sequence moves the cursor to the left by the specified number of columns. If columns is not specified, the cursor will be moved left one column. When the cursor reaches the far left of the display, it will stay there (not wrapped). Line Feed (LF) ESC[E Convert to specified number of line feeds. If the cursor is the the bottom of the screen, the screen will be scrolled up. If no number is given, one linefeed will be sent. CUrsor Position (CUP) ESC[;H ( ESCH to move cursor to upper-left corner on VT52) This is identical to HVP... The horizontal and vertical position sequence moves the cursor to the position specified by row and column. If row and column are omitted, the cursor will be 'homed' (moved to the upper-left corner). Erase Display (ED) ESC[J ( ESCJ to erase to end-of-screen on VT52) The erase display sequence erases the display according to . If a background colour is selected, the screen will be cleared to that background colour. No specified assumes type 0. is: 0 - ESC[0J - Clear from cursor to end of screen. 1 - ESC[1J - Clear from beginning of screen to cursor. 2 - ESC[2J - Clear whole screen and home cursor. Erase Line (EL) ESC[K ( ESCK to erase to end of current line on VT52) The erase line sequence erases the current line according to . If a background colour is selected, the background will be set to that background colour. No specified assumes type 0. is: 0 - ESC[0K - Clear from cursor to end of line. 1 - ESC[1K - Clear from beginning of line to cursor. 2 - ESC[2K - Clear whole line. Insert Line (IL) ESC[L This will insert blank lines at the current cursor position. These lines will be coloured according to the current attributes. The previous current line and all lines below will be moved down. Lines moved beyond the bottom of the screen will be lost. ANSI music / Delete line ESC[M This is a big conflict in ANSI. The actual ANSI standard says this sequence is to be used to delete lines. The person that invented ANSI music (!) obviously didn't know that. Using this command incorrectly can cause major problems, from pouring gibberish on your user to core-dumping and locking up. Therefore, the use of the alternative commands are strongly recommended: ANSI music - use ESC[N Delete line - use ESC[Y Note, ESC[~N and ESC[~Y codes are not strictly ANSI and aren't, therefore, supported by all terminals. ANSI music ESC[N<^N> This command should be used as a substitute for the traditional [M sequence, as [M has conflicts. Note that not all terminals will support this. Example: ESC[NE8G8G8G8F4E8G2<^N> will play the first few notes of "Popeye the Sailor". The [N sequence starts, and the Ctrl-N character finishes. What's in between are the notes, and how long each lasts for. Delete Character ESC[P Will delete the character at the current cursor position. All characters to the right of the cursor will be shifted one place to the left. The rightmost character will become a space, with the attributes of the character that used to be there. If no is specified, one character will be deleted. Cursor Position Report (CPR) ESC[;R Output from the DSR command. Scroll Up ESC[S See ESCD. Scroll Down ESC[T See ESCM. Clear ESC[U This will clear the screen with the 'normal' attribute and home the cursor. New text will use the previously defined attribute. This is functionally the same as ^L. Delete lines ESC[Y This will delete lines at the current cursor position. Lines below will be scrolled up. The blank lines inserted the the bottom of the screen will be coloured with the current attribute. Note, this isn't strictly ANSI, but is provided as a substitute for the clashing [M command. Not all terminals will support it. Back tab ESC[Z Relocate the cursor to the previous tab. Tabs are located at columns: 1, 8, 16, 24, 32, 40, 48, 46, 64, 72 and 80. VT100 query sequence ESC[c Some mainframes send this and are looking for some unique response, otherwise they'll assume your terminal is a TTY or something equally brain dead. Sending back 'ESC[?1;20c' seems to keep most mainframes happy. Official reply syntax is /usually/: VT100 - ESC[?1;2c VT101 - ESC[?1;0c VT102 - ESC[?6c VT220 - ESC[?62;1;2;6;7;8;9;11;14c VT300 - ESC[?63;...;...c Official interpretation on modern terminals: ESC[?x1;x2..x2c x1 is the operating mode. x2 are the extensions: 1 = 132 coloumns 2 = Printer port 6 = Selective erase 7 = Soft character set 8 = User defined keys See also DSR. Horizontal and Vertical Position (HVP) ESC[;f The horizontal and vertical position sequence moves the cursor to the position specified by row and column. If row and column are omitted, the cursor will be 'homed' (moved to the upper-left corner). In VT52, the sequence is 'ESC'. Set options ESC[h or ESC[l Note, these are mainly VT100 codes, but may work on ANSI terminals. Sending 'ESC[?3h' - Sets number of columns to 132. Sending 'ESC[?4h' - Set smooth scrolling. Sending 'ESC[?5h' - Set reverse video on screen. Sending 'ESC[?6h' - Certain functions which normally ignore the scrolling region will now operate relative to the defined scrolling region. Note that those functions will again ignore the scrolling region the next time it is changed. You'll need to send this code again to re-enable scrolling regions. Sending 'ESC[?7h' - Auto-wrap is turned on (in case you turned it off earlier, default is ON). Sending 'ESC[?8h' - Set auto-repeat mode. Sending 'ESC[?9h' - Set interlacing mode. Sending 'ESC[?25h' - Visible cursor (default). Sending 'ESC[?3l' - Sets number of columns to 80 (default). Sending 'ESC[?4l' - Set jump (line-by-line) scrolling (default). Sending 'ESC[?5l' - Set normal video on screen (default). Sending 'ESC[?6l' - Will negate the effect of 'ESC[?6h'... Commands will affect the entire screen, not just the scrolling region. This is the default. Sending 'ESC[?7l' - Auto-wrap turned off. Note that the next time you alter the scrolling region, the wrap will be turned on. Sending 'ESC[?8l' - Reset auto-repeat mode. Sending 'ESC[?9l' - Reset interlacing mode. Sending 'ESC[?25l' - Invisible cursor. Here, 'l' is a lowercase L, not a 1 (one). Set Graphics Rendition (SGR) ESC[;...;m The set graphics rendition is used to set attributes (VT100 and ANSI) and colours (ANSI). These attributes are passed to the terminal by specifying one of more parameters seperated by semicolons... parameter Function 0 Turn off all attributes 1 Turn bold on 2 Turn faint/low intensity text on (#) 3 Turn italics on (#) 4 Turn underline on 5 Turn blink on 6 Turn rapid blink on (*) 7 Turn reverse video on 8 Turn concealed/invisible on (*) 22 Bold off (@) 24 Underline off (@) 25 Blink off (@) 27 Reverse video off (@) 48 Turn subscript on (*) 49 Turn superscript on (*) (#) - not supported by all terminals. A PC terminal using ANSI.SYS will only display italics in monochrome mode, a VT100 will display italics. (*) - not widely supported. All other commands should work on modern ANSI/VT100 terminals. Note that ArcTerm7 doesn't display many of the more unusual effects, like italics, but HearSay2 and ZAnsi do... (@) - These functions have not been tested on ANSI, but are known to work on VT300 terminals. No effect on VT52/VT100. parameter Foreground colour (colours not supported by VT100) 30 Black 31 Red 32 Green 33 Yellow 34 Blue 35 Magenta 36 Cyan 37 White parameter Background colour (colours not supported by VT100) 40 Black 41 Red 42 Green 43 Yellow 44 Blue 45 Magenta 46 Cyan 47 White Device Status Report (DSR) ESC[6n The device status report sequence tells the ANSI terminal to output an RCP sequence. Unfortunately, this is the method used by MS-DOS's ANSI.SYS and it is not correct. According to the ANSI standard, a DSR sequence should generate a CPR sequence is response - but ANSI.SYS does not support CPR sequences. It's lucky, therefore, that the DSR sequence is really only used in the comms world to detect if the remote terminal can support ANSI. To perform such a check, send a DSR and wait for an ESC in return. If an ESC is returned, it's pretty safe to assume the remote terminal supports ANSI, or is ANSI compliant (in the case of most VT100's). ESC[255n The 'report screen size' command. You should almost always receive 'ESC[24;80R' in reply. Set scroll region ESC[;r Define a region of the screen for scrolling. This is usually used for full-screen editors etc... Some information can be written on the screen, to remain there constantly throughout (like which keys to press to quit et cetera...). Some commands always ingore the scrolling region. Some default to ignoring it, but can be activated to work relative to the scrolling region by sending an 'ESC[?6h' command. Some terminals always work relative to the scrolling region when one is defined. Examples: ESC[2;23r - leave the first and last lines out of the scrolling region. ESC[5r - the first four lines are left out of the scrolling region. ESC[r - turn off the scrolling region. Save Cursor Position (SCP) ESC[s (or ESC[7 on VT100) The save cursor position sequence tells the ANSI terminal to save the current cursor position. The cursor can be returned to this saved position at any time with an RCP sequence. VT100 terminals will also store the current text attributes Restore Cursor Position (RCP) ESC[u (or ESC[8 on VT100) The restore cursor position sequence restores the cursor to position it held when the ANSI terminal last received a SCP sequence. VT100 terminals will also reset the text attributes saved. Reset ESC[z Some terminals use this to reset. Not widely supported. See also 'ESC[c'. And finally... Other codes you might like to try (ANSI and VT100): ESC#3 Select double-height characters, top half. ESC#4 Select double-height characters, bottom half. ESC#5 Select single-width, single height characters (default each new line). ESC#6 Select double width, single height characters. #3/#4/#5/#6 are toggles, and will affect the current line only. This is not wrapped to the next line, unlike the 'graphics renditions'. Try it with ZAnsi and HearSay... ESC#8 Screen alighnment display. ESC[2;1y Confidence power-up test. ESC[2;2y Confidence RS232 port data loopback test. ESC[2;3y Confidence printer port loopback test. ESC[2;6y Confidence RS232 port control loopback test. ESC[2;7y Confidence DEC-423 port loopback test. ESC[0q Turn off all four LEDs (VT100). ESC[1q Turn on LED #1 (VT100). ESC[2q Turn on LED #2 (VT100). ESC[3q Turn on LED #3 (VT100). ESC[4q Turn on LED #4 (VT100). ESCF Use special graphics character set (VT52). ESCG Use normal UK/US character set (VT52). ESCZ VT52, identify terminal. Correct reponse is ESC/Z. ESC\ Disable Manual Input (DMI) ESCb Enable Manual Input (EMI) ESCW End of Protected Area (EPA) ESC[; D << space /is/ included. Font selection (FNT) ESCK Partial Line Down (PLD) ESCL Partial Line Up (PLU) ESCV Start of Protected Area (SPA) Compatibility issues: Using your doors with ARCHIBOARD: At this moment in time, it doesn't seem to possible. Some doors may work, particulary if using the Doobs interface, whilst others won't. Keith Marlow is working on it. Using your doors with ARMBBS: ArmBBS supports all ARCbbsDoor_ SWIs, and all data requests except: Anything added in ArcBBS 1.64 time of first logon amount of private mail waiting pointer to start of mail-linked list in message file " " " end... highest message read highest file read [terminal type] will be 0 or 3. message flags file flags user flags up/down ratio fido credit fido flags outbox start outbox end outbox count bitset of joined message + filebases (will be imp. soon) time allocated = same as time left call rate no name and address info is stored by ArmBBS. writing information to the BBS - NOT detected : write new ratio message flags fileflags userflags Using your doors with RISCBBS: This will require several code changes! Initially, add this: SYS "OS_GetEnv" TO env_str$ quit%=INSTR(env_str$,"-quit") IF quit% THEN params$=MID$(env_str$,INSTR(env_str$," ",quit%)+1) ENDIF To find the username: _server_h%=0 _user%=0 DIM buffer% &1000 SYS "OS_ReadArgs","filename/a,riscbbs/e/a,user/e/a",params$,buff er%,&1000 _server_h%=!(buffer%!4+1) _user%=!(buffer%!8+1) : userdataF%=OPENIN".System.Kernel.UserData" PTR#userdataF%=144*_user%+48 _user$="" REPEAT c%=BGET#userdataF% IF c%>31 THEN _user$+=CHR$c% UNTIL c%<32 OR LEN_user$=255 OR EOF#userdataF% CLOSE#userdataF% : username$=_user$ To connect: Get rid of PROCdoors_scanconnect stuff and replace with: PROC_send_server(&C0900) queue$="" Add this to DEFPROCmessage routine, or whatever handles your WimpMessages: WHEN &400C3: IF q%!4=_server_h% THEN exit%=TRUE WHEN &C0903: _server_ack%=TRUE WHEN &C0904: q%!12=q%!8 SYS "Wimp_SendMessage",19,q%,q%!4 return%=q%!20 Finally, replace your door routine library with: DEFPROCdoors_sendbyte(a%) PROCdoors_tx(CHR$(a%)) ENDPROC : DEFFNdoors_getbyte REPEAT PROCwindow_poll UNTIL return%<>-1 =return% : DEFPROCdoors_close IF doorconnectedokay%=TRUE THEN PROC_send_server(&C0901) SYS "Wimp_CloseDown" ENDPROC : DEFPROCdoors_sendstring(a$) LOCAL f% FOR f%=1 TO LENa$ PROCdoors_tx(MID$(a$,f%,1)) NEXT ENDPROC : DEFPROCdoors_tx(string$) PROCflush PROCqueue(string$) PROCflush PROCwindow_poll ENDPROC : DEF PROCqueue(string$) IF (LENqueue$+LENstring$)>150 THEN PROCflush queue$+=string$ ENDPROC : DEF PROCwait_for_ack _server_ack%=FALSE REPEAT PROCwindow_poll UNTIL _server_ack% ENDPROC : DEF PROCflush IF queue$="" THEN ENDPROC q%!0=((LENqueue$+4) AND NOT 3)+20 q%!12=0 q%!16=&C0902 $(q%+20)=queue$+STRING$(4,CHR$0) SYS "Wimp_SendMessage",17,q%,_server_h% PROCwait_for_ack queue$="" ENDPROC : DEF PROC_send_server(msg%) q%!0=20 q%!12=0 q%!16=msg% SYS "Wimp_SendMessage",17,q%,_server_h% ENDPROC Using your doors with NewsFlash: It appears to me that NewsFlash supports a semi-implementation of the ArcBBS system. If you treat NewsFlash like ArmBBS you should be okay. Using your doors with VHOST: Get real! Using your doors with !BBS: Now, you really are taking the ****. :-) Using your doors with REMOTE ACCESS/WildCat etc...: Yuk! Bleugh! Barf! This file has been compiled by Richard Murray [BudgieSoft] after loads of really hard work [;-)] and research. I would appreciate if you pass this file around UNALTERED. Finally, I hope this is useful to you if you're writing an ArcBBS add-on or converting your doors... oo, o, ooo ]8888o, 88[ ]88 o888o, d888 ]888888, 88 '8P d88888[ ]8P`' oo ]8[ 88[ 88 88P '` ]8[ 88 ]8bod88 88 88 o8888 od88b ]8[ .d8b, Y88 .o88b, 88888 88888 888888o 88 ]88 888888 d88888 d8[ ]88Y88 '888o .888888 "88P" Y88"" 88P""88[ .88 ]88 ]8P 88 ]8P` 88 88[ 88 .88 'Y88b ]8P 88[ 88 ]88 88[ ]88 ]8P ]8[ 88[ 88 88` .88 88[ ]88888` Y88, 88[ 88[ 88 ]8P 88[ d88 ]8b d8[ 88[ d88 88b d88 88 ]88"` , 88[ 88b .88 88 ]8b 8888888[ '888888o ]888888o ]888888 88b, 88oo8 ]88b888 ]88888P 88 ]88o8 88888"` "88"Y8P "8P`Y8P "88Y8P '88` 'Y88" "Y88P` "Y8P" 88 Y88" ]8[ .88 ooo88` .d8[ 8888P 888P '"" ""` © Richard Murray, August 1995 ©.......................munch!