Writing a new protocol If you want to add a new protocol to BACKDOWN, here is a description of the interface that BACKDOWN uses to communicate with protocol modules. First, BACKDOWN searches for potential protocol modules by scanning for *.BDP files in the directory indicated by the BDP environment variable. If the environment variable is not set, it searches the current directory. When BACKDOWN finds a matching file, it opens that file and reads the first six bytes looking for the characters "BD" in fourth and fifth byte. If found, BACKDOWN uses the sixth byte to identify the number of protocols implemented in the module. Then it reads the associated headers into memory. The "Protocol Module Header" code segment in Figure A shows the header for the XMODEM protocol module where two protocols are implemented. BACKDOWN cannot use another program's protocol modules because they do not adhere to BACKDOWN's user interface and are not designed to run in the background. During the search, BACKDOWN notes the length of the longest protocol module and subsequently reserves enough memory to accommodate it. When a protocol is invoked, BACKDOWN loads the module into memory with the opening jump statement aligned on a paragraph boundary (an address evenly divisible by 16.) BACKDOWN then calls the module with a far call to (segment address:0), allowing the protocol module easy addressability to its local variables and buffers. Refer to Figure B for the protocol module calling conventions. The entry section describes register contents when BACKDOWN calls the protocol module. This is how BACKDOWN tells the protocol module of an event occurring. There are four events that BACKDOWN passes to the module: Initialization, keyboard, character receive, and simple dispatch. The initialization event occurs as soon as the module is loaded. It should only happen once and all of the protocol modules supplied with BACKDOWN fail if initialization is invoked a second time. During this event, the module may prepare to receive a download, but this will vary from protocol to protocol. For instance, the XMODEM protocol opens the receive file and sends a NAK to the host, while the B+ protocol it simply sets up a few variables and returns. The keyboard event is called only if BACKDOWN is popped up and the user presses a key. The module may process the key or discard it. BACKDOWN issues a character receive event when a character is available in the communications receive buffer. Most of a module's life is spent waiting for these events. Finally, the simple dispatch event gives the module a chance to run and determine if an error condition (such as a timeout) has occurred. Unlike the typical subroutine, protocol modules do not simply return so BACKDOWN can continue running. More appropriately, a module returns with a request code directing BACKDOWN to do some work. This mechanism frees you from worrying about how to do file or communications I/O in the background and lets you concentrate on implementing the protocol. When the protocol module returns to BACKDOWN, the DI register contains the request code that directs BACKDOWN's next action. Except for request codes 0 (No request) and 10 (Done), BACKDOWN performs the requested action and calls the module with function code 2 (Previous request successful) or 4 (Previous function failed). It is up to the protocol module to remember where it was when it returned to BACKDOWN with a request code. Some request codes pass a string to BACKDOWN by putting the offset of the string within the protocol module into the BX register. In the case of request codes 4 (Write file) and 18 (Send string out on COM port), the area referenced must start with a word containing the number of bytes to process, directly followed by the bytes. When the module returns with request code 0 (No request), it tells BACKDOWN that the protocol module has no more work to do for now, and that it can go look for another event. When the module returns with request code 10 (Done), BACKDOWN unloads the protocol module and returns control to the dumb terminal or script. If the protocol module did not issue an explicit close, the receive file will be closed when the protocol module return with code 10. -- Bob Flanders *************************Figure A********************************** ; --------------------------------------------------------------- ; ; Example of a protocol module header ; ; The first 3 bytes are a jump statement to the body of the ; module. The next two are the letters "BD" which BACKDOWN ; uses to identify its protocol modules. ; ; Following the identifier is a byte indicating the number of ; protocols supported by this module, in this case, two ; protocols. ; ; Immediately following the count byte is one or more 19 byte ; descriptors that identify the protocols supported. ; ; The first byte of the descriptor is a letter used to invoke the ; protocol. Next is a 16 byte description of the module followed ; by a single zero byte, making it an ASCIIZ string. Finally, ; the last byte is a number that will be passed to the module ; when it is invoked with the corresponding letter. This lets ; the module know which protocol the user requested to invoke ; this module. ; ; --------------------------------------------------------------- start: jmp bpmxmodem ; jump to start db "BD" ; BACKDOWN protocol ID db 2 ; number of protocols db "X" ; invocation letter db "Xmodem V1.0 ", 0 ; name to display db 1 ; protocol number db "C" ; invocation letter db "Xmodem/CRC V1.0 ", 0 ; name to display db 2 ; protocol number *************************Figure B********************************** Entry: ax = current tick downcounter di = function code cs = the module's segment ds = caller's segment Function: 0 = initialization call ds:bx contains address of any operands given after the script letter. The operands are passed as ASCIIZ strings. dx contains protocol number from the header si contains the offset in BACKDOWN of a 10 byte work area. (This is needed for BPLUS protocol) 2 = Dispatch or Previous request successful 4 = Last request failed 6 = Communications character received dl: Received Character 8 = Keystroke detected dl: character or 0 dh: scan code Exit: di = Request code ds, es, ss and sp are restored to entry values. Request Code: 0 = No request 2 = Open output file bx: offset in module of ASCIIZ string containing filename to open 4 = Write file bx: offset in module of buffer 6 = Close file 8 = Delete file bx: offset in module of ASCIIZ string containing filename to delete 10 = Done. Module will be unloaded. 12 = Display an ASCIIZ string, 's translated bx: Offset in module of string to display 14 = Display one character, 's translated bl: Character to display 16 = Get a line (max 64 chars) bx: Offset in module of buffer for line. 18 = Send string out on COM port bx: offset in module of buffer 20 = Send single character out on COM port bl: Character to send 22 = Set timer bx: Number of Ticks to set 24 = Display ASCIIZ string, no translation bx: Offset in module of string to display -------------------------------------------------------------------------