Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-1 PAGE ,132 TITLE JMODEM.ASM ; COMMENT * Created 02-SEP-1988 Richard B. Johnson Purpose: File transfer protocol. Use with BBS systems and communications programs that allow "external protocols". This program will transfer a single file between the host and an IBM compatible microcomputer. It will use data-compression when the data can be compressed and transfers data uncompressed should comp- ression techniques fail to reduce the block-size. The block-size is variable, ranging from 512 bytes (plus a 6-byte overhead) to 8192 bytes (plus a 6-byte overhead). The block-size is increased up to the limit if there are no transmission errors. Should errors occur, the block-size is reduced to a minimum of 512 bytes. Since the bytes transferred may be of any length, the file- size is exactly correct after the file is received. Data compression is used when its been found that the compression will reduce the size of the transmitted blocks. Flow control is also provided to interface with high-speed modems. The flow-control techniques used are invisible to the user so no special provisions are necessary. You don't have to add anything on the command line. Usage: JMODEM S1 (to send a file via COM1) JMODEM R1 (to receive a file via COM1) JMODEM S2 (to send a file via COM2) JMODEM R2 (to receive a file via COM2) Known bugs(?) Since the DOS function 9 is used to print many strings, filenames that contain a '$' will be incompletely displayed on the screen. This will be fixed in the second minor revision. Modification record: Release 04-SEP-1988 05-SEPT-1988 Richard B. Johnson V1.01 Added interrupt on receive routines so that data could be received while the file is being written. 07-SEPT-1988 Richard B. Johnson V1.02 Added checks for an abort in the flow-control routine. This should prevent long time-outs if one end aborts. 07-SEPT-1988 Richard B. Johnson V1.02 Fixed bug (typo) in source code that prevented operation on COM2. Port address 2F8H was mispelled to 02FH which prevented operation 08-SEPT-1988 Richard B. Johnson V1.03 Added a status window with direct writes to the screen to reduce Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-2 the time necessary to show the TX/RX status Changed the local variable [CLOCK] to a word and increased the sync interval to allow slow users more time to get their files ready for TX. Note: This must be linked as a '.COM' file. MASM JMODEM; LINK JMODEM; EXE2BIN JMODEM.EXE JMODEM.COM DEL JMODEM.EXE * ; ELSE %OUT [PASS2] ENDIF ; = 0009 TIMOUT EQU 9 ; About 1/2 second = 000A MAX EQU 10 ; Max retries = 0021 MS_DOS EQU 21H ; MS-DOS functions = 0010 VIDEO EQU 10H ; Video BIOS routines = 000D CR EQU 0DH ; ASCII = 000A LF EQU 0AH ; ASCII = 4000 CODELOC EQU 16384 ; Where to code/decode data = 8000 HOME EQU CODELOC + 16384 ; Interrupt buffer = 0021 INT_CTL EQU 21H ; Interrupt controller address = 000C INT_1 EQU 0CH ; For COM1 = 000B INT_2 EQU 0BH ; For COM2 = 00EF IRQ4 EQU 11101111B ; For COM1 = 00F7 IRQ3 EQU 11110111B ; For COM2 = 0001 INT_RC EQU 00000001B ; Interrupt on received character = 0008 TRISTAT EQU 00001000B ; Turn on tristate buffer = 0003 RTS_DTR EQU 00000011B ; DTR/RTS bits ; IBUFFER STRUC 0000 ???? LEN DW ? ; String length 0002 ?? CTRL DB ? ; Control byte 0003 ?? RECN DB ? ; Record number 0004 ?? IDATA DB ? ; Start of data 0005 IBUFFER ENDS ; ; Control byte context ; = 0001 NORMAL EQU 00000001B ; Normal data = 0002 COMP EQU 00000010B ; Compressed data = 0004 EOF EQU 00000100B ; End of file = 0008 RETRY EQU 00001000B ; Ask/respond with retry = 0010 TIMEOUT EQU 00010000B ; Informational = 0020 ABORT EQU 00100000B ; Kill U/D load = 0040 SYNC EQU 01000000B ; Hello /ack = 0080 ERROR EQU 10000000B ; Undefined error = FFFE NONORM EQU NOT NORMAL ; Invert 'NORMAL' bits ; Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-3 ; UART equates. ; = 0001 DR EQU 00000001B ; Data ready = 0010 CTS EQU 00010000B ; Clear to send = 0020 DSR EQU 00100000B ; Data set ready = 0020 THRE EQU 00100000B ; TX holding register empty = 0080 RLSD EQU 10000000B ; Rec. line signal det = 0030 CTSDSR EQU CTS OR DSR ; ; Control bytes. ; = 0006 ACK EQU 'F' - 64 = 0015 NAK EQU 'U' - 64 = 0004 EOT EQU 'D' - 64 = 0018 CAN EQU 'X' - 64 = 0016 SYN EQU 'V' - 64 ; ; BIOS segment structure. ; 0000 BSEG SEGMENT AT 40H 0063 ORG 63H 0063 ???? ADDR_6845 DW ? ; Address of the video controller 0065 BSEG ENDS ; = 03F6 ORIGIN EQU 1014 ; Where to put the status box = 0017 LINLEN EQU 23 ; Length of a line = 054C SCR_BLK EQU ORIGIN + ( (160 - (LINLEN *2) ) * 3) ; Offset to block count = 05EC SCR_LEN EQU SCR_BLK + 160 ; Offset to block length = 068C SCR_BYT EQU SCR_LEN + 160 ; Offset to byte count = 055E SCR_ACK EQU SCR_BLK + 18 ; Where to put ACK/NAK ; 0000 PSEG SEGMENT PARA PUBLIC 'CODE' = 0000 START EQU $ ASSUME CS:PSEG, DS:PSEG, ES:PSEG, SS:NOTHING 0100 ORG 100H 0100 MAIN PROC NEAR 0100 BC 0E70 R MOV SP,OFFSET STACKP ; Keep stack pointer safe ; 0103 BF 09F0 R MOV DI,OFFSET KILL ; First variable to zero out 0106 B9 000D 90 MOV CX,KLEN ; Length of the variable list 010A 32 C0 XOR AL,AL ; Get a zero 010C F3/ AA REP STOSB ; Set all to zero ; 010E E8 09A5 R CALL FIND_VIDEO ; Find the video segment 0111 E8 0489 R CALL SET_SEG ; Set up data segment 0114 E8 07CA R CALL PARSE ; Parse the command line 0117 73 0E JNC WASOK ; Commands okay 0119 E8 0908 R CALL SENDX ; Tell other end to quit 011C BA 0AAE R MOV DX,OFFSET PRP3 ; Point to 'usage' prompt 011F E8 03DC R CALL PROMPT ; Print to screen 0122 B8 4C01 MOV AX,4C01H ; Terminate with error 0125 CD 21 INT MS_DOS ; 0127 80 3E 0A00 R 53 WASOK: CMP BYTE PTR [RXTX],'S' ; Do we want to send? Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-4 012C 74 03 JZ SEND ; Yes 012E E9 01C9 R JMP RECV ; Else receive 0131 MAIN ENDP ; ; Send file contents to remote. ; 0131 SEND PROC NEAR 0131 C6 06 09FF R 00 MOV BYTE PTR [TRIES],0 ; Conditional for Read 0136 E8 04BB R CALL SET_INT ; Set up interrupts 0139 BA 0C55 R MOV DX,OFFSET PRP7 ; Point to 'Sending' 013C E8 03DC R CALL PROMPT ; Print to screen 013F E8 05EE R CALL OPEN_R ; Open for read 0142 72 6B JC EXITF ; Can't open the file 0144 BF 0CED R MOV DI,OFFSET FNAME ; Point to filename 0147 B9 0040 MOV CX,64 ; Max bytes to scan 014A B0 00 MOV AL,0 ; What to scan for 014C F2/ AE REPNZ SCASB ; Find the first null 014E C6 45 FF 24 MOV BYTE PTR [DI-1],'$' ; Put in a stopper 0152 BA 0CED R MOV DX,OFFSET FNAME ; Point to filename 0155 E8 03DC R CALL PROMPT ; Print to screen 0158 BA 0C21 R MOV DX,OFFSET CRLF ; End of the line 015B E8 03DC R CALL PROMPT ; Print to screen 015E E8 069A R CALL READ ; Read the file first 0161 E8 038B R CALL SYNCH ; Synchronize 0164 72 49 JC EXITF ; Exit fatal 0166 E8 0913 R CALL SAV_SCR 0169 E8 0985 R CALL WRT_SCR 016C EB 03 JMP SHORT BYPASS ; Bypass first read (already done) 016E E8 069A R SEND0: CALL READ ; Read the file 0171 C6 06 09FF R 0A BYPASS: MOV BYTE PTR [TRIES],MAX ; Max attempts to send blocks 0176 E8 0282 R SEND1: CALL SDATA ; Send the data ; 0179 E8 0318 R SEND2: CALL GET_ACK ; Get host ackknowlege 017C 72 31 JC EXITF ; Fatal exit 017E 75 20 JNZ CHKRES ; Was not good 0180 B0 20 MOV AL,' ' ; Clear any error mes 0182 E8 03D0 R CALL SHO_RES ; on the screen 0185 80 3E 09FA R 00 CMP BYTE PTR [FEND],0 ; Check for file end 018A 74 E2 JZ SEND0 ; Not end of the file yet 018C E8 0950 R CALL RES_SCR ; 018F BA 0C90 R MOV DX,OFFSET PRP10 ; Point to the prompt 0192 E8 03DC R CALL PROMPT 0195 E8 0690 R CALL CLOSE ; Close the file 0198 E8 0589 R CALL RES_INT ; Restore vectors 019B B8 4C00 MOV AX,4C00H ; Exit with NO errors 019E CD 21 INT MS_DOS ; Do it now ; 01A0 3C 18 CHKRES: CMP AL,CAN ; Wanted to cancel? 01A2 74 0B JZ EXITF ; Yes 01A4 B0 2A MOV AL,'*' 01A6 E8 03D0 R CALL SHO_RES ; Show error response 01A9 FE 0E 09FF R DEC BYTE PTR [TRIES] ; Bump retries 01AD 75 C7 JNZ SEND1 ; Continue Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-5 ; 01AF BC 0E70 R EXITF: MOV SP,OFFSET STACKP ; Level stack 01B2 E8 0908 R CALL SENDX ; Tell other end to quit 01B5 E8 0950 R CALL RES_SCR ; Restore screen state 01B8 BA 0C77 R MOV DX,OFFSET PRP9 ; Point to 'aborted' 01BB E8 03DC R CALL PROMPT ; Print to screen 01BE E8 0690 R CALL CLOSE ; Close the file 01C1 E8 0589 R CALL RES_INT ; Restore interrupts 01C4 B8 4C01 MOV AX,4C01H ; Exit with error 01C7 CD 21 INT MS_DOS ; Do it now 01C9 SEND ENDP ; ; Receive a file from remote ; 01C9 RECV PROC NEAR 01C9 E8 04BB R CALL SET_INT ; Set up interrupts 01CC BA 0C65 R MOV DX,OFFSET PRP8 ; Poiint to 'receiving' 01CF E8 03DC R CALL PROMPT ; Print to screen 01D2 E8 061F R CALL OPEN_W ; Open for write 01D5 72 41 JC CANCEL ; Bad open 01D7 BF 0CED R MOV DI,OFFSET FNAME ; Point to filename 01DA B9 0040 MOV CX,64 ; Max bytes to scan 01DD B0 00 MOV AL,0 ; What to scan for 01DF F2/ AE REPNZ SCASB ; Find the first null 01E1 C6 45 FF 24 MOV BYTE PTR [DI-1],'$' ; Put in a stopper 01E5 BA 0CED R MOV DX,OFFSET FNAME ; Point to filename 01E8 E8 03DC R CALL PROMPT ; Print to screen 01EB BA 0C21 R MOV DX,OFFSET CRLF 01EE E8 03DC R CALL PROMPT 01F1 E8 038B R CALL SYNCH ; Establish communications 01F4 72 22 JC CANCEL ; No good, quit. 01F6 E8 0913 R CALL SAV_SCR ; Save screen context 01F9 E8 0985 R CALL WRT_SCR ; Write box on screen 01FC C6 06 09FF R 0A MOV BYTE PTR [TRIES],MAX ; Max re-tries 0201 EB 0A JMP SHORT NONAK ; Bypass the initial NAK 0203 B0 2A RECV0: MOV AL,'*' 0205 E8 03D0 R CALL SHO_RES ; Show response 0208 B0 15 MOV AL,NAK ; Get a NAK 020A E8 02B5 R RECV1: CALL RESP ; Send to remote 020D E8 0340 R NONAK: CALL RDATA ; Receive data 0210 73 20 JNC RECV3 ; Good block 0212 FE 0E 09FF R RECV2: DEC BYTE PTR [TRIES] ; Bump retries 0216 75 EB JNZ RECV0 ; Send a NAK and try again ; 0218 BC 0E70 R CANCEL: MOV SP,OFFSET STACKP ; Level stack 021B E8 0908 R CALL SENDX ; Tell remote to quit 021E E8 0950 R CALL RES_SCR ; Restore screen context 0221 BA 0C77 R MOV DX,OFFSET PRP9 ; Point to 'aborted' 0224 E8 03DC R CALL PROMPT ; Print to screen 0227 E8 0690 R CALL CLOSE ; Close the file 022A E8 0589 R CALL RES_INT ; Restore interrupts 022D B8 4C01 MOV AX,4C01H ; Exit with error 0230 CD 21 INT MS_DOS ; Exit now ; Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-6 0232 E8 044E R RECV3: CALL CRC ; Check the CRC 0235 75 DB JNZ RECV2 ; Bad CRC 0237 B0 06 MOV AL,ACK ; Get an ACK 0239 E8 02B5 R CALL RESP ; Send to remote 023C B0 20 MOV AL,' ' 023E E8 03D0 R CALL SHO_RES ; Show good response 0241 E8 0730 R CALL WRITE ; Write the file 0244 1E PUSH DS ; Save segment 0245 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Get buffer segment 0249 A0 0002 MOV AL,BYTE PTR DS:[CTRL] ; Get control byte 024C 1F POP DS ; Restore segment 024D A8 04 TEST AL,EOF ; Check for end-of-file 024F 75 0B JNZ END_F ; Is end of file 0251 A8 20 TEST AL,ABORT ; Check for abort 0253 75 C3 JNZ CANCEL ; It was an abort 0255 C6 06 09FF R 0A MOV BYTE PTR [TRIES],MAX ; Reset the retry count 025A EB B1 JMP SHORT NONAK ; Get more ; 025C BC 0E70 R END_F: MOV SP,OFFSET STACKP ; Level stack 025F B0 20 MOV AL,' ' 0261 E8 03D0 R CALL SHO_RES ; Show response 0264 B9 0005 MOV CX,5 ; Number of ACKs 0267 B0 06 ENDACK: MOV AL,ACK ; Get an ack 0269 E8 02B5 R CALL RESP ; Send to remote 026C E2 F9 LOOP ENDACK ; Send a few. 026E E8 0950 R CALL RES_SCR ; Restore screen context 0271 BA 0C90 R MOV DX,OFFSET PRP10 ; Point to 'good' 0274 E8 03DC R CALL PROMPT ; Print to screen 0277 E8 0690 R CALL CLOSE ; Close the file 027A E8 0589 R CALL RES_INT ; Restore vectors 027D B8 4C00 MOV AX,4C00H ; Exit with NO errors 0280 CD 21 INT MS_DOS 0282 RECV ENDP ; ; Send data. Data is in the BUFFER.IDATA ; 0282 SDATA PROC NEAR 0282 FA CLI ; Clear buffer enables 0283 E8 0308 R CALL CLR_BUF ; Clear interrupt buffer 0286 E8 0842 R CALL SHOW ; Show what we are doing 0289 8B 16 0A03 R MOV DX,WORD PTR [PORT] ; Get port address 028D A0 09FB R MOV AL,BYTE PTR [REC_NOL] ; Get low byte of rec to xmit. 0290 1E PUSH DS ; Save segment 0291 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Pick up data buffer 0295 8B 0E 0000 MOV CX,WORD PTR DS:[LEN] ; Get the string length 0299 A2 0003 MOV BYTE PTR DS:[RECN],AL ; Record number 029C E8 044E R CALL CRC ; Calculate the CRC 029F 33 F6 XOR SI,SI ; Offset Zero 02A1 83 C2 05 SDATA1: ADD DX,5 ; Offset to status 02A4 EC SDATA2: IN AL,DX ; Get UART status 02A5 A8 20 TEST AL,THRE ; Test holding register ready 02A7 74 FB JZ SDATA2 ; Wait 02A9 E8 03E1 R CALL FLOW ; Flow control 02AC 83 EA 05 SUB DX,5 ; To base port Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-7 02AF AC LODSB ; Get memory byte 02B0 EE OUT DX,AL ; Output to UART 02B1 E2 EE LOOP SDATA1 ; Continue for all bytes 02B3 1F POP DS ; Restore data segment 02B4 C3 RET ; Exit 02B5 SDATA ENDP ; ; Send a single byte in AL to the modem port. ; 02B5 RESP PROC NEAR 02B5 FA CLI ; CLR_BUF enables 02B6 E8 0308 R CALL CLR_BUF ; Clear any garbage. 02B9 E8 03E1 R CALL FLOW ; Flow control 02BC FORCE PROC NEAR ; Force output, no flow control 02BC 52 PUSH DX ; Save 02BD 50 PUSH AX ; Save byte 02BE 2E: 8B 16 0A03 R MOV DX,WORD PTR CS:[PORT] ; Get modem port 02C3 83 C2 05 ADD DX,5 ; Offset to status 02C6 EC RESP0: IN AL,DX ; Get the status 02C7 24 20 AND AL,THRE ; Test holding register ready 02C9 74 FB JZ RESP0 ; Wait 02CB 83 EA 05 SUB DX,5 ; To base port 02CE 58 POP AX ; Restore byte to send 02CF EE OUT DX,AL ; Output to UART 02D0 5A POP DX ; Restore 02D1 C3 RET 02D2 FORCE ENDP 02D2 RESP ENDP ; ; Easy interrupt happens each time a byte is assembled in the UART. ; The byte is stacked in the interrupt buffer and the time-out clock ; is reset. An appropriate reset is also sent to the interrupt ; controller. ; 02D2 EASY_INT PROC FAR 02D2 50 PUSH AX ; Save registers used. 02D3 53 PUSH BX 02D4 52 PUSH DX 02D5 1E PUSH DS ; 02D6 0E PUSH CS 02D7 1F POP DS ; DS=CS ; 02D8 8B 16 0A03 R MOV DX,WORD PTR [PORT] ; Get port address 02DC EC IN AL,DX ; Get the byte 02DD 8B 1E 0A1E R MOV BX,WORD PTR [WPOINT] ; Pick up write pointer 02E1 FF 06 0A1E R INC WORD PTR [WPOINT] ; Ready next 02E5 FF 06 0A1C R INC WORD PTR [BYTE_CNT] ; Count of bytes in the buffer 02E9 C7 06 0A01 R 0009 MOV WORD PTR [CLOCK],TIMOUT ; Set timeout to max again 02EF 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Pick up buffer segment 02F3 88 07 MOV BYTE PTR [BX],AL ; Put byte in the buffer 02F5 B0 20 MOV AL,20H ; Non-specific end-of-interrupt 02F7 E6 20 OUT 20H,AL ; Reset the controller ; Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-8 02F9 1F POP DS ; Restore registers used 02FA 5A POP DX 02FB 5B POP BX 02FC 58 POP AX 02FD CF IRET 02FE EASY_INT ENDP ; ; Return byte count in interrupt buffer in CX. ; 02FE CHK_STA PROC NEAR 02FE FA CLI ; No interrupts 02FF 2E: 8B 0E 0A1C R MOV CX,WORD PTR CS:[BYTE_CNT] ; Get byte count 0304 0B C9 OR CX,CX ; Test for zero 0306 75 0E JNZ CHK_EX ; Got some bytes 0308 CLR_BUF PROC NEAR 0308 2E: C7 06 0A1E R 8000 MOV WORD PTR CS:[WPOINT],HOME ; Set pointer to top of buffer 030F 2E: C7 06 0A1C R 0000 MOV WORD PTR CS:[BYTE_CNT],0 ; Zero the byte-count 0316 FB CHK_EX: STI ; Allow interrupts 0317 C3 RET 0318 CLR_BUF ENDP 0318 CHK_STA ENDP ; ; Get a single byte from the remote. Check to see if its an ACK. ; 0318 GET_ACK PROC NEAR 0318 C7 06 0A01 R 00FF MOV WORD PTR [CLOCK],255 ; Max time to wait 031E GET_INP PROC NEAR 031E 51 PUSH CX ; Save count 031F 83 3E 0A01 R 00 GET0: CMP WORD PTR [CLOCK],0 ; Check for timeout 0324 74 17 JZ GET1 0326 E8 02FE R CALL CHK_STA ; Check status 0329 74 F4 JZ GET0 ; No bytes available ; 032B FA CLI ; CLR_BUF enables 032C E8 0308 R CALL CLR_BUF ; Clear any garbage. 032F 1E PUSH DS 0330 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Pick up buffer segment 0334 A0 8000 MOV AL,BYTE PTR DS:[HOME] ; Pick up byte at bottom 0337 1F POP DS 0338 3C 06 CMP AL,ACK ; Check for an ACK 033A F8 CLC ; Clear carry 033B EB 01 JMP SHORT GET2 ; Exit ; 033D F9 GET1: STC ; Set carry for error 033E 59 GET2: POP CX ; Restore count 033F C3 RET 0340 GET_INP ENDP 0340 GET_ACK ENDP ; ; Receive data string from remote. First word is the string length. ; 0340 RDATA PROC NEAR 0340 C7 06 0A01 R 00FF MOV WORD PTR [CLOCK],255 ; Max time to wait ; Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-9 ; Wait for the first two bytes so we know how many bytes are supposed ; to be received. ; 0346 83 3E 0A01 R 00 RDATA0: CMP WORD PTR [CLOCK],0 ; Check for timeout 034B 74 38 JZ RDATA2 ; Timed out 034D E8 02FE R CALL CHK_STA ; Check status 0350 83 F9 02 CMP CX,2 ; Check for two bytes received 0353 72 F1 JC RDATA0 ; Not here yet 0355 1E PUSH DS 0356 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Pick up buffer segment 035A A1 8000 MOV AX,WORD PTR DS:[HOME] ; Pick up word at bottom 035D 1F POP DS ; ; AX now contains the string length. Wait until the entire string is ; received by checking the status. ; 035E 83 3E 0A01 R 00 RDATA1: CMP WORD PTR [CLOCK],0 ; Check for timeout 0363 74 20 JZ RDATA2 ; Timed out 0365 E8 02FE R CALL CHK_STA ; Check status 0368 3B C8 CMP CX,AX ; Check byte count 036A 72 F2 JC RDATA1 ; Not here yet ; ; Got all the bytes we need, now transfer them. ; 036C 1E PUSH DS 036D 06 PUSH ES 036E A1 0A07 R MOV AX,WORD PTR [BUF_SEG] ; Pick up segment 0371 8E C0 MOV ES,AX 0373 8E D8 MOV DS,AX ; Fix up segments 0375 BE 8000 MOV SI,HOME ; Where data is 0378 BF 0000 MOV DI,LEN ; Where to put it 037B F3/ A4 REP MOVSB ; transfer it 037D 07 POP ES ; Restore registers 037E 1F POP DS 037F FA CLI ; CLR_BUF enables 0380 E8 0308 R CALL CLR_BUF ; Clear the buffer 0383 F8 CLC ; Show no errors 0384 C3 RET ; ; Timeout error return ; 0385 FA RDATA2: CLI ; CLR_BUF enables 0386 E8 0308 R CALL CLR_BUF ; Clear the buffer 0389 F9 STC 038A C3 RET 038B RDATA ENDP ; ; Attempt to synchronize TX/RX ; 038B SYNCH PROC NEAR 038B BA 0CD8 R MOV DX,OFFSET PRP13 ; Pick up prompt 038E E8 03DC R CALL PROMPT ; Print to console 0391 FA CLI ; CLR_BUF enables 0392 E8 0308 R CALL CLR_BUF ; Clear any garbage Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-10 0395 C7 06 0A01 R 0200 MOV WORD PTR [CLOCK],512 ; Max time to wait 039B B9 0040 MOV CX,64 ; Number of SYNC bytes ; 039E 83 3E 0A01 R 00 SYNCH0: CMP WORD PTR [CLOCK],0 ; Check for abort 03A3 74 29 JZ SYNCEX 03A5 B0 16 MOV AL,SYN ; Get sync byte 03A7 E8 02B5 R CALL RESP ; Send it out ; 03AA E8 031E R SYNCH1: CALL GET_INP ; Get a single byte from remote 03AD 72 EF JC SYNCH0 ; No bytes at all 03AF 3C 18 CMP AL,CAN ; See if its a cancel 03B1 74 1B JZ SYNCEX ; Yes 03B3 3C 16 CMP AL,SYN ; See if its sync 03B5 75 E7 JNZ SYNCH0 ; No 03B7 C7 06 0A01 R 0009 MOV WORD PTR [CLOCK],TIMOUT ; Max time limit 03BD E2 DF LOOP SYNCH0 ; Continue ; 03BF E8 02B5 R CALL RESP ; Send it out 03C2 FA CLI ; CLR_BUF enables 03C3 E8 0308 R CALL CLR_BUF ; Clear any garbage 03C6 BA 0CC2 R MOV DX,OFFSET PRP12 ; Pick up prompt 03C9 E8 03DC R CALL PROMPT ; Print to console 03CC F8 CLC ; Show no error 03CD C3 RET ; Yes, we are talking. 03CE F9 SYNCEX: STC 03CF C3 RET 03D0 SYNCH ENDP ; ; Show ACK/NAK with a '*' after the block ; 03D0 SHO_RES PROC NEAR 03D0 1E PUSH DS ; Save screen segment 03D1 8E 1E 0A22 R MOV DS,WORD PTR [SCR_SEG] ; Pick up screen segment 03D5 B4 07 MOV AH,7 ; Normal attribute 03D7 A3 055E MOV WORD PTR DS:[SCR_ACK],AX ; Put on the screen 03DA 1F POP DS 03DB C3 RET 03DC SHO_RES ENDP ; ; Print string to console until a '$'. String location in DX ; 03DC PROMPT PROC NEAR 03DC B4 09 MOV AH,9 03DE CD 21 INT MS_DOS 03E0 C3 RET 03E1 PROMPT ENDP ; ; Flow control and carrier detect. ; 03E1 FLOW PROC NEAR 03E1 50 PUSH AX ; Save byte 03E2 51 PUSH CX ; Save any count 03E3 52 PUSH DX ; Save registers used 03E4 1E PUSH DS ; Save data segment Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-11 03E5 0E PUSH CS 03E6 1F POP DS ; DS=CS 03E7 80 3E 09F7 R 00 CMP BYTE PTR [ENABLE],0 ; Original mask 03EC 74 5B JZ CONT1 ; Ignore flow control 03EE 8B 16 0A03 R MOV DX,WORD PTR [PORT] ; Get port address 03F2 83 C2 06 ADD DX,6 ; Offset to modem status port 03F5 80 3E 09F0 R 00 FLOW0: CMP BYTE PTR [KILL],0 ; Check for an abort 03FA 75 12 JNZ BYEBYE ; Wanted to abort 03FC EC IN AL,DX ; Get status 03FD A8 80 TEST AL,RLSD ; Check for carrier 03FF 75 27 JNZ CAROK ; Carrier is still okay 0401 80 3E 09F8 R 00 CMP BYTE PTR [WASC],0 ; See if a carrier when we started 0406 74 20 JZ CAROK ; No, ignore status 0408 BA 0CAA R MOV DX,OFFSET PRP11 ; Point to carrier failed 040B E8 03DC R CALL PROMPT 040E BC 0E70 R BYEBYE: MOV SP,OFFSET STACKP ; Level stack 0411 E8 0690 R CALL CLOSE ; Close the file 0414 E8 0908 R CALL SENDX ; Tell other end to quit. 0417 E8 0950 R CALL RES_SCR ; Restore screen 041A BA 0C77 R MOV DX,OFFSET PRP9 ; Point to aborted 041D E8 03DC R CALL PROMPT ; Print to screen 0420 E8 0589 R CALL RES_INT ; Restore interrupts 0423 B8 4C01 MOV AX,4C01H ; Error exit 0426 CD 21 INT MS_DOS ; Exit ; 0428 24 30 CAROK: AND AL,CTSDSR ; Mask all but DSR/CTS 042A 3A 06 09F7 R CMP AL,BYTE PTR [ENABLE] ; Original mask 042E 74 02 JZ CONT0 ; Okay to continue 0430 EB C3 JMP SHORT FLOW0 ; Wait until Okay 0432 E8 02FE R CONT0: CALL CHK_STA ; Check for any incomming bytes 0435 74 12 JZ CONT1 ; Buffer's clear 0437 1E PUSH DS ; Save segment 0438 2E: 8E 1E 0A07 R MOV DS,WORD PTR CS:[BUF_SEG] ; Pick up segment 043D A0 8000 MOV AL,BYTE PTR DS:[HOME] ; Get byte in the buffer 0440 1F POP DS ; Restore segment 0441 3C 18 CMP AL,CAN ; Want to cancel? 0443 74 C9 JZ BYEBYE ; Yes 0445 FA CLI ; CLR_BUF Restores 0446 E8 0308 R CALL CLR_BUF ; Clear the buffer 0449 1F CONT1: POP DS ; Restore segment 044A 5A POP DX ; Register used 044B 59 POP CX ; Restore any count 044C 58 POP AX ; Restore byte 044D C3 RET 044E FLOW ENDP ; ; Make/check CRC word. String is in BUFFER ; 044E CRC PROC NEAR 044E 51 PUSH CX 044F 56 PUSH SI 0450 1E PUSH DS 0451 2E: 8E 1E 0A07 R MOV DS,WORD PTR CS:[BUF_SEG] ; Pick up buffer segment 0456 8B 0E 0000 MOV CX,WORD PTR DS:[LEN] ; Get string length Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-12 045A 83 E9 02 SUB CX,2 ; Don't CRC the CRC 045D 32 E4 XOR AH,AH ; Always zero 045F 33 DB XOR BX,BX ; Start with zero 0461 33 F6 XOR SI,SI ; Buffer offset zero 0463 51 CRC0: PUSH CX ; Save count 0464 AC LODSB ; Get byte 0465 03 D8 ADD BX,AX ; Total so far 0467 83 E1 07 AND CX,0000111B ; Rotate max 7 bits 046A D3 C3 ROL BX,CL ; Multiply 046C 59 POP CX ; Restore count 046D E2 F4 LOOP CRC0 ; Continue 046F 39 1C CMP WORD PTR [SI],BX ; For checking 0471 89 1C MOV WORD PTR [SI],BX ; Insert CRC 0473 1F POP DS 0474 5E POP SI 0475 59 POP CX 0476 C3 RET 0477 CRC ENDP ; ; Output a string, in outbuf to the screen. NULL terminates ; 0477 DIRECT PROC NEAR 0477 BE 0AAE R MOV SI,OFFSET OUTBUF ; Pick up buffer. 047A AC DIREC0: LODSB ; Get byte 047B 3C 00 CMP AL,0 ; End of string? 047D 74 09 JZ DIREX ; Yes 047F B4 0E MOV AH,14 ; Dumb terminal mode 0481 BB 0007 MOV BX,7 ; Page zero/normal attributes 0484 CD 10 INT VIDEO ; Send it out 0486 EB F2 JMP SHORT DIREC0 0488 C3 DIREX: RET 0489 DIRECT ENDP ; 0489 SET_SEG PROC NEAR 0489 B8 0E80 R MOV AX,OFFSET BUFFER ; Point to buffer 048C D1 E8 SHR AX,1 ; /2 048E D1 E8 SHR AX,1 ; /4 0490 D1 E8 SHR AX,1 ; /8 0492 D1 E8 SHR AX,1 ; /16 0494 8C CB MOV BX,CS ; Get code segment 0496 03 C3 ADD AX,BX ; Add to offset paragraph 0498 A3 0A07 R MOV WORD PTR [BUF_SEG],AX ; Save for later 049B 05 1000 ADD AX,4096 ; Next segment higher 049E A3 0A09 R MOV WORD PTR [DAT_SEG],AX ; Into next 04A1 C3 RET 04A2 SET_SEG ENDP ; ; Local extension of the clock vector. ; 04A2 LCL_CLK PROC FAR 04A2 FB STI ; Allow interrupts 04A3 50 PUSH AX ; Save registers user 04A4 B0 20 MOV AL,20H ; Non-specific end-of-interrupt 04A6 E6 20 OUT 20H,AL ; Out to the controller Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-13 04A8 58 POP AX ; Restore registers used 04A9 2E: 83 3E 0A01 R 00 CMP WORD PTR CS:[CLOCK],0 ; See if already zero 04AF 74 05 JZ CLK_EX ; Yes, quit 04B1 2E: FF 0E 0A01 R DEC WORD PTR CS:[CLOCK] ; Bump the timer 04B6 2E: FF 2E 0A0B R CLK_EX: JMP DWORD PTR CS:[OLD_CLK] ; Continue 04BB LCL_CLK ENDP ; 04BB SET_INT PROC NEAR 04BB C6 06 09F2 R FF MOV BYTE PTR [INT_FLG],0FFH ; Show we've set up interrupts 04C0 E8 0308 R CALL CLR_BUF ; Put pointers at correct loc 04C3 8B 16 0A03 R MOV DX,WORD PTR [PORT] ; Get port address 04C7 83 C2 01 ADD DX,1 ; Interrupt enable register 04CA EC IN AL,DX ; Get the control byte 04CB A2 09F9 R MOV BYTE PTR [STATUS],AL ; Save interrupt status 04CE B0 01 MOV AL,INT_RC ; Interrupt on received characters 04D0 EE OUT DX,AL ; Enable interrupts ; 04D1 83 C2 03 ADD DX,3 ; Offset to modem control register 04D4 B0 0B MOV AL,RTS_DTR OR TRISTAT ; Get control byte 04D6 EE OUT DX,AL ; Output the byte 04D7 83 C2 02 ADD DX,2 ; Offset to modem status 04DA EC IN AL,DX ; Get modem status 04DB 8A E0 MOV AH,AL ; Duplicate 04DD 80 E4 80 AND AH,RLSD ; Mask all but carrier det 04E0 88 26 09F8 R MOV BYTE PTR [WASC],AH ; Save carrier status 04E4 24 30 AND AL,CTSDSR ; Mask all but CTS/DSR 04E6 A2 09F7 R MOV BYTE PTR [ENABLE],AL ; Save data enable byte ; 04E9 06 PUSH ES ; Save segment 04EA 81 3E 0A03 R 03F8 CMP WORD PTR [PORT],03F8H ; Check for COM1: 04F0 75 10 JNZ COM2 ; 04F2 B0 0C MOV AL,INT_1 ; COM1 interrupt 04F4 B4 35 MOV AH,35H ; Get interrupt vector 04F6 CD 21 INT MS_DOS ; Go get it 04F8 8C 06 0A19 R MOV WORD PTR [UAR_SEG],ES ; Store UART segment 04FC 89 1E 0A17 R MOV WORD PTR [UAR_OFF],BX ; Store UART offset 0500 EB 0E JMP SHORT COMSAV ; Saved old parameters 0502 B0 0B COM2: MOV AL,INT_2 ; COM2 interrupt 0504 B4 35 MOV AH,35H ; Get interrupt vector 0506 CD 21 INT MS_DOS ; Go get it 0508 8C 06 0A19 R MOV WORD PTR [UAR_SEG],ES ; Store UART segment 050C 89 1E 0A17 R MOV WORD PTR [UAR_OFF],BX ; Store UART offset ; 0510 B0 1C COMSAV: MOV AL,1CH ; Clock interrupt 0512 B4 35 MOV AH,35H ; Get interrupt vector 0514 CD 21 INT MS_DOS ; Go get it 0516 8C 06 0A0D R MOV WORD PTR [CLK_SEG],ES ; Store clock segment 051A 89 1E 0A0B R MOV WORD PTR [CLK_OFF],BX ; Store clock offset ; 051E B0 1B MOV AL,1BH ; Control break interrupt 0520 B4 35 MOV AH,35H ; Get interrupt vector 0522 CD 21 INT MS_DOS ; Go get it Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-14 0524 8C 06 0A11 R MOV WORD PTR [BRK_SEG],ES ; Store clock segment 0528 89 1E 0A0F R MOV WORD PTR [BRK_OFF],BX ; Store clock offset ; 052C B0 23 MOV AL,23H ; Control C interrupt 052E B4 35 MOV AH,35H ; Get interrupt vector 0530 CD 21 INT MS_DOS ; Go get it 0532 8C 06 0A15 R MOV WORD PTR [CTC_SEG],ES ; Store clock segment 0536 89 1E 0A13 R MOV WORD PTR [CTC_OFF],BX ; Store clock offset 053A 07 POP ES ; Restore segment ; 053B 81 3E 0A03 R 03F8 CMP WORD PTR [PORT],03F8H ; Check for COM1: 0541 75 14 JNZ COMM2 ; 0543 B0 0C MOV AL,INT_1 ; Communications vector 0545 B4 25 MOV AH,25H ; Set interrupt vector 0547 BA 02D2 R MOV DX,OFFSET EASY_INT ; Our local vector 054A CD 21 INT MS_DOS ; Go set it ; 054C E4 21 IN AL,INT_CTL ; Get interrupt control mask 054E A2 0A1B R MOV BYTE PTR [OLD_MASK],AL ; Save the mask. 0551 24 EF AND AL,IRQ4 ; Set the mask 0553 E6 21 OUT INT_CTL,AL ; Set the mask 0555 EB 12 JMP SHORT COMSET ; 0557 B0 0B COMM2: MOV AL,INT_2 ; Communications vector 0559 B4 25 MOV AH,25H ; Set interrupt vector 055B BA 02D2 R MOV DX,OFFSET EASY_INT ; Our local vector 055E CD 21 INT MS_DOS ; Go set it ; 0560 E4 21 IN AL,INT_CTL ; Get interrupt control mask 0562 A2 0A1B R MOV BYTE PTR [OLD_MASK],AL ; Save the mask. 0565 24 F7 AND AL,IRQ3 ; Set the mask 0567 E6 21 OUT INT_CTL,AL ; Set the mask ; 0569 B0 1C COMSET: MOV AL,1CH ; Clock vector 056B B4 25 MOV AH,25H ; Set interrupt vector 056D BA 04A2 R MOV DX,OFFSET LCL_CLK ; Our local vector 0570 CD 21 INT MS_DOS ; Go set it ; 0572 B0 1B MOV AL,1BH ; Control break vector 0574 B4 25 MOV AH,25H ; Set interrupt vector 0576 BA 083B R MOV DX,OFFSET BRK ; Our local vector 0579 CD 21 INT MS_DOS ; Go set it ; 057B B0 23 MOV AL,23H ; Control C vector 057D B4 25 MOV AH,25H ; Set interrupt vector 057F BA 083B R MOV DX,OFFSET BRK ; Our local vector 0582 CD 21 INT MS_DOS ; Go set it 0584 B0 20 MOV AL,20H ; Non-specific end-of-interrupt 0586 E6 20 OUT 20H,AL ; Reset controller 0588 C3 RET 0589 SET_INT ENDP ; 0589 RES_INT PROC NEAR Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-15 0589 80 3E 09F2 R 00 CMP BYTE PTR [INT_FLG],0 ; See if we have hot Interrupts 058E 75 01 JNZ HOT_IN ; Yes 0590 C3 RET ; No, don't "restore" them 0591 C6 06 09F2 R 00 HOT_IN: MOV BYTE PTR [INT_FLG],0 ; Show we are doing it now 0596 8B 16 0A03 R MOV DX,WORD PTR [PORT] ; Get port address 059A 83 C2 01 ADD DX,1 ; Interrupt enable register 059D A0 09F9 R MOV AL,BYTE PTR [STATUS] ; Get old UART status 05A0 EE OUT DX,AL ; Restore it ; 05A1 A0 0A1B R MOV AL,BYTE PTR [OLD_MASK] ; Get old Interrupt/ctl mask 05A4 E6 21 OUT INT_CTL,AL ; Restore it ; 05A6 1E PUSH DS ; Save segment 05A7 81 3E 0A03 R 03F8 CMP WORD PTR [PORT],03F8H ; Check for COM1 port 05AD 75 0D JNZ NCOM1 ; Not COM1 ; 05AF B0 0C MOV AL,INT_1 ; Vector to restore 05B1 B4 25 MOV AH,25H ; Set interrupt function 05B3 2E: C5 16 0A17 R LDS DX,CS:[OLD_UART] ; Pick up old vector 05B8 CD 21 INT MS_DOS ; Restore it 05BA EB 0B JMP SHORT COMRES ; 05BC B0 0B NCOM1: MOV AL,INT_2 ; Vector to restore 05BE B4 25 MOV AH,25H ; Set interrupt function 05C0 2E: C5 16 0A17 R LDS DX,CS:[OLD_UART] ; Pick up old vector 05C5 CD 21 INT MS_DOS ; Restore it ; 05C7 B0 1C COMRES: MOV AL,1CH ; Vector to restore 05C9 B4 25 MOV AH,25H ; Set interrupt function 05CB 2E: C5 16 0A0B R LDS DX,CS:[OLD_CLK] ; Pick up old vector 05D0 CD 21 INT MS_DOS ; Restore it ; 05D2 B4 25 MOV AH,25H ; Set interrupt function 05D4 B0 1B MOV AL,1BH ; Control break vector 05D6 2E: C5 16 0A0F R LDS DX,CS:[OLD_BRK] ; Pick up old vector 05DB CD 21 INT MS_DOS ; Restore it ; 05DD B4 25 MOV AH,25H ; Set interrupt function 05DF B0 23 MOV AL,23H ; Control C vector 05E1 2E: C5 16 0A13 R LDS DX,CS:[OLD_CTC] ; Pick up old vector 05E6 CD 21 INT MS_DOS ; Restore it 05E8 1F POP DS 05E9 B0 20 MOV AL,20H ; Non-specific end-of-interrupt 05EB E6 20 OUT 20H,AL ; Reset controller 05ED C3 RET 05EE RES_INT ENDP ; ; Open a fiile for reading. ; 05EE OPEN_R PROC NEAR 05EE B8 3D00 MOV AX,3D00H ; Open for read 05F1 33 C9 XOR CX,CX ; Normal file 05F3 BA 0CED R MOV DX,OFFSET FNAME ; File name 05F6 CD 21 INT MS_DOS Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-16 05F8 A3 0A05 R MOV WORD PTR [HANDLE],AX ; Save handle/error code 05FB 73 21 JNC OPN_OK 05FD BA 0C24 R MOV DX,OFFSET PRP4 ; Point to prompt 0600 E8 03DC R CALL PROMPT ; Print to screen 0603 BF 0CED R MOV DI,OFFSET FNAME ; Point to filename 0606 B9 0040 MOV CX,64 ; Max bytes to scan 0609 B0 00 MOV AL,0 ; What to scan for 060B F2/ AE REPNZ SCASB ; Find the first null 060D C6 45 FF 24 MOV BYTE PTR [DI-1],'$' ; Put in a stopper 0611 BA 0CED R MOV DX,OFFSET FNAME ; Point to filename 0614 E8 03DC R CALL PROMPT ; Print to screen 0617 BA 0C36 R MOV DX,OFFSET PRP5 ; End of the string 061A E8 03DC R CALL PROMPT 061D F9 STC ; Maintain error status 061E C3 OPN_OK: RET 061F OPEN_R ENDP ; 061F OPEN_W PROC NEAR 061F B8 3D00 MOV AX,3D00H ; Open for read 0622 33 C9 XOR CX,CX ; Normal file 0624 BA 0CED R MOV DX,OFFSET FNAME ; File name 0627 CD 21 INT MS_DOS 0629 A3 0A05 R MOV WORD PTR [HANDLE],AX ; Save handle/error code 062C 72 31 JC CREATE ; Not found, create one. 062E E8 0690 R CALL CLOSE ; File was found, close it 0631 BE 0CED R MOV SI,OFFSET FNAME ; Present file name 0634 BF 0D2D R MOV DI,OFFSET ONAME ; New name to '.old' 0637 B9 0040 MOV CX,64 ; Max characters 063A AC NFILE0: LODSB ; Get byte 063B 3C 2E CMP AL,'.' ; Find the delimiter? 063D 75 0A JNZ NODOT 063F AA STOSB ; Put in the dot 0640 B0 4F MOV AL,'O' ; Get a 'O' for old 0642 AA STOSB ; Save 0643 B8 444C MOV AX,'DL' ; 'LD' backwards 0646 AB STOSW ; Save in string 0647 EB 03 JMP SHORT NFILE1 0649 AA NODOT: STOSB 064A E2 EE LOOP NFILE0 ; Continue for the whole name 064C B8 4100 NFILE1: MOV AX,4100H ; Delete file function 064F BA 0D2D R MOV DX,OFFSET ONAME ; Delete any such old name 0652 CD 21 INT MS_DOS ; Do it, ignore any errors 0654 B8 5600 MOV AX,5600H ; Rename file 0657 BA 0CED R MOV DX,OFFSET FNAME ; File to be renamed 065A BF 0D2D R MOV DI,OFFSET ONAME ; What to name it to 065D CD 21 INT MS_DOS ; Rename the file 065F B8 3C00 CREATE: MOV AX,3C00H ; Create file 0662 BA 0CED R MOV DX,OFFSET FNAME ; File to create 0665 33 C9 XOR CX,CX ; Normal attribute 0667 CD 21 INT MS_DOS ; Create it 0669 A3 0A05 R MOV WORD PTR [HANDLE],AX ; Save handle/error 066C 73 21 JNC CREOK 066E BA 0C24 R MOV DX,OFFSET PRP4 ; Point to prompt 0671 E8 03DC R CALL PROMPT Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-17 0674 BF 0CED R MOV DI,OFFSET FNAME ; Point to filename 0677 B9 0040 MOV CX,64 ; Max bytes to scan 067A B0 00 MOV AL,0 ; What to scan for 067C F2/ AE REPNZ SCASB ; Find the first null 067E C6 45 FF 24 MOV BYTE PTR [DI-1],'$' ; Put in a stopper 0682 BA 0CED R MOV DX,OFFSET FNAME ; Point to filename 0685 E8 03DC R CALL PROMPT ; Print to screen 0688 BA 0C42 R MOV DX,OFFSET PRP6 ; End of the string 068B E8 03DC R CALL PROMPT 068E F9 STC ; Maintain error status 068F C3 CREOK: RET 0690 OPEN_W ENDP ; 0690 CLOSE PROC NEAR 0690 B8 3E00 MOV AX,3E00H ; Close file function 0693 8B 1E 0A05 R MOV BX,WORD PTR [HANDLE] ; Get file handle 0697 CD 21 INT MS_DOS 0699 C3 RET 069A CLOSE ENDP ; ; Read the file open for reading into the buffer. ; 069A READ PROC NEAR 069A 80 3E 09FF R 0A CMP BYTE PTR [TRIES],MAX ; No retries? 069F 75 10 JNZ NOUP 06A1 81 3E 09FD R 2000 CMP WORD PTR [BYTES],8192 ; Check upper limit 06A7 73 16 JNC NODWN ; Don't add more 06A9 81 06 09FD R 0200 ADD WORD PTR [BYTES],512 ; Send more bytes 06AF EB 0E JMP SHORT NODWN ; Continue 06B1 81 3E 09FD R 0200 NOUP: CMP WORD PTR [BYTES],512 ; Already the lowest? 06B7 74 06 JZ NODWN 06B9 81 2E 09FD R 0200 SUB WORD PTR [BYTES],512 ; Get/send fewer bytes ; 06BF 8B 0E 09FD R NODWN: MOV CX,WORD PTR [BYTES] ; Get Bytes to read 06C3 8B 1E 0A05 R MOV BX,WORD PTR [HANDLE] ; Get open file handle 06C7 B8 3F00 MOV AX,3F00H ; Read file/device 06CA 1E PUSH DS ; Save segment 06CB 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Pick up segment for output data 06CF BA 0004 MOV DX,IDATA ; Offset of the data 06D2 CD 21 INT MS_DOS ; Read the data 06D4 C6 06 0002 01 MOV BYTE PTR DS:[CTRL],NORMAL ; Assume normal read 06D9 3B C1 CMP AX,CX ; Check for end of file 06DB 74 0B JZ NORM ; Was not the end of file 06DD 80 0E 0002 04 OR BYTE PTR DS:[CTRL],EOF ; Is the end of file 06E2 26: C6 06 09FA R 04 MOV BYTE PTR ES:[FEND],EOF ; Local info also 06E8 8B C8 NORM: MOV CX,AX ; Save real byte count 06EA 05 0006 ADD AX,6 ; Overhead 06ED A3 0000 MOV WORD PTR DS:[LEN],AX ; Bytes to transmit ; 06F0 06 PUSH ES ; Save segment 06F1 1E PUSH DS 06F2 07 POP ES ; ES=DS 06F3 51 PUSH CX ; Save byte count for now 06F4 8B C1 MOV AX,CX ; Count to encode Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-18 06F6 BE 0004 MOV SI,IDATA ; Where the data is 06F9 BF 4000 MOV DI,CODELOC ; Where to put coded data 06FC E8 0792 R CALL ENCODE ; Encode the data 06FF 59 POP CX ; Restore original byte count 0700 3B C1 CMP AX,CX ; Check to see if new is less 0702 73 1C JNC READ0 ; Not less ; 0704 51 PUSH CX ; Save original byte count 0705 8B C8 MOV CX,AX ; New byte count 0707 BE 4000 MOV SI,CODELOC ; When compressed data is 070A BF 0004 MOV DI,IDATA ; Where to put compressed data 070D F3/ A4 REP MOVSB ; Copy the data 070F 05 0006 ADD AX,6 ; Add in overhead 0712 A3 0000 MOV WORD PTR DS:[LEN],AX ; Bytes to actually transmit 0715 80 26 0002 FE AND BYTE PTR DS:[CTRL],NONORM ; Reset, normal bit 071A 80 0E 0002 02 OR BYTE PTR DS:[CTRL],COMP ; Show its encoded 071F 59 POP CX ; Restore original byte count ; 0720 07 READ0: POP ES ; Restore segments 0721 1F POP DS 0722 01 0E 09F5 R ADD WORD PTR [CNT_LO],CX ; Add to the count 0726 83 16 09F3 R 00 ADC WORD PTR [CNT_HI],0 ; Take care of overflow. 072B FF 06 09FB R INC WORD PTR [REC_NOL] ; Next record number 072F C3 RET 0730 READ ENDP ; ; Write the buffer contents to the file ; 0730 WRITE PROC NEAR 0730 1E PUSH DS 0731 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Where the data is 0735 BA 0004 MOV DX,IDATA ; Offset for data 0738 8B 0E 0000 MOV CX,WORD PTR DS:[LEN] ; Get string length 073C 83 E9 06 SUB CX,6 ; Remove overhead 073F F6 06 0002 02 TEST BYTE PTR DS:[CTRL],COMP ; Check for compressed data 0744 74 13 JZ WRITE0 ; Its normal, not compressed 0746 06 PUSH ES ; Save segment 0747 1E PUSH DS 0748 07 POP ES ; ES=DS 0749 8B F2 MOV SI,DX ; Location of the string 074B BF 4000 MOV DI,CODELOC ; Where to put the decoded data 074E 8B C1 MOV AX,CX ; String length 0750 E8 0775 R CALL DECODE ; Decode the data 0753 8B C8 MOV CX,AX ; New string length 0755 BA 4000 MOV DX,CODELOC ; Where the data is 0758 07 POP ES ; Restore segment 0759 2E: 8B 1E 0A05 R WRITE0: MOV BX,WORD PTR CS:[HANDLE] ; Get the file access word 075E B8 4000 MOV AX,4000H ; Write to file/device 0761 CD 21 INT MS_DOS 0763 1F POP DS 0764 01 0E 09F5 R ADD WORD PTR [CNT_LO],CX ; Add to the count 0768 83 16 09F3 R 00 ADC WORD PTR [CNT_HI],0 ; Take care of overflow. 076D FF 06 09FB R INC WORD PTR [REC_NOL] ; Next record number 0771 E8 0842 R CALL SHOW Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-19 0774 C3 RET 0775 WRITE ENDP ; ; ; Decode compressed string in DS:SI and transfer to ES:DI ; Input string length is in AX, output string length in AX ; 0775 DECODE PROC NEAR 0775 57 PUSH DI ; SAVE START ADDRESS 0776 8B DE MOV BX,SI ; GET STARTING OFFSET 0778 03 D8 ADD BX,AX ; CALC END OF STRING OFFSET 077A AC DECD0: LODSB ; GET BYTE 077B 3C BB CMP AL,0BBH ; SENTINEL ? 077D 75 08 JNZ DECD1 ; NO 077F AD LODSW ; PICK UP LENGTH 0780 8B C8 MOV CX,AX ; UPDATE BYTE COUNT 0782 AC LODSB ; GET REPEAT CHARACTER 0783 F3/ AA REP STOSB ; FILL IN CHARACTER 0785 EB 01 JMP SHORT DECD2 ; AND CONTINUE 0787 AA DECD1: STOSB ; TRANSFER BYTE 0788 3B F3 DECD2: CMP SI,BX ; END OF STRING? 078A 72 EE JC DECD0 ; NOT YET 078C 8B C7 MOV AX,DI ; GET ENDING STRING OFFSET 078E 5F POP DI ; RESTORE START ADDRESS 078F 2B C7 SUB AX,DI ; SUBTRACT START 0791 C3 RET ; AX = BYTE COUNT 0792 DECODE ENDP ; ; Encode string in DS:SI. Output string in ES:DI. Upon input ; AX = Byte count. Upon output AX = new string length ; 0792 ENCODE PROC NEAR 0792 52 PUSH DX 0793 57 PUSH DI ; SAVE OUTPUT STRING LOC 0794 03 C6 ADD AX,SI ; CALC LAST ADDRESS 0796 8B D0 MOV DX,AX ; SAVE LAST ADDESSS 0798 AC ENCD0: LODSB ; GET BYTE 0799 56 PUSH SI ; SAVE SOURCE INDEX 079A 57 PUSH DI ; SAVE DEST INDEX 079B 8B CA MOV CX,DX ; GET LAST POSSIBLE ADDRESS 079D 2B CE SUB CX,SI ; SUBTRACT PRESENT ADDRESS 079F 41 INC CX ; ADD ONE ; 07A0 8B FE MOV DI,SI ; FOR SEARCH DI=POINTER 07A2 F3/ AE REPZ SCASB ; SEE HOW MANY THERE ARE 07A4 8B DF MOV BX,DI ; GET LAST ADDRESS ; 07A6 5F POP DI ; RESTORE REGISTERS 07A7 5E POP SI 07A8 2B DE SUB BX,SI ; BX = BYTE COUNT 07AA 3C BB CMP AL,0BBH ; WAS IT THE SENTINEL? 07AC 74 05 JZ ENCD1 ; YES, REQUIRES ENCODING 07AE 83 FB 04 CMP BX,4 ; ENOUGH TO COMPACT? 07B1 72 0B JC NOENC ; NO, DON'T ENCODE Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-20 07B3 50 ENCD1: PUSH AX ; SAVE BYTE 07B4 B0 BB MOV AL,0BBH ; SENTINEL 07B6 AA STOSB ; PUT IN OUTPUT BUFFER 07B7 8B C3 MOV AX,BX ; BYTE COUNT 07B9 AB STOSW ; INTO BUFFER 07BA 58 POP AX ; RESTORE SAVED BYTE 07BB 4B DEC BX ; LODSB INCREMENTED IT ONCE 07BC 03 F3 ADD SI,BX ; UPDATE SOURCE 07BE AA NOENC: STOSB ; SAVE BYTE 07BF 3B F2 ENCD2: CMP SI,DX ; CHECK LIMITS 07C1 72 D5 JC ENCD0 ; CONTINUE 07C3 8B C7 ENCD3: MOV AX,DI ; GET LAST ADDRESS 07C5 5F POP DI ; RESTORE START ADDRESS 07C6 2B C7 SUB AX,DI ; CALC BYTE COUNT 07C8 5A POP DX 07C9 C3 RET 07CA ENCODE ENDP ; ; Parse the command line to extract filename and function. ; 07CA PARSE PROC NEAR 07CA BE 0080 MOV SI,80H 07CD AC LODSB ; Get bytes typed 07CE 3C 03 CMP AL,3 ; Nothing? 07D0 72 22 JC PARSEX ; Yes, nothing typed 07D2 98 CBW 07D3 8B C8 MOV CX,AX ; Use as a count 07D5 E8 0824 R CALL MAP ; Map to upper case 07D8 49 DEC CX 07D9 49 DEC CX 07DA AC PARSE0: LODSB ; Get byte 07DB 3C 20 CMP AL,' ' ; Is it a space (or less) 07DD 76 04 JBE PARSE1 ; Space found 07DF E2 F9 LOOP PARSE0 ; None, continue 07E1 EB 11 JMP SHORT PARSEX ; Not found, exit with error ; 07E3 80 3C 20 PARSE1: CMP BYTE PTR [SI],' ' ; Check next byte 07E6 76 F2 JBE PARSE0 ; Yes 07E8 AC LODSB ; Get the byte 07E9 49 DEC CX ; Byte count 07EA E3 08 JCXZ PARSEX ; Ran out of characters 07EC 3C 52 CMP AL,'R' ; Was it a [R]eceive? 07EE 74 06 JZ YES ; Yes 07F0 3C 53 CMP AL,'S' ; Was it a [S]end? 07F2 74 02 JZ YES ; Yes 07F4 F9 PARSEX: STC ; Show error and exit 07F5 C3 RET ; 07F6 A2 0A00 R YES: MOV BYTE PTR [RXTX],AL ; Save flag 07F9 80 3C 20 CMP BYTE PTR [SI],' ' ; More spaces? 07FC 76 12 JBE PARSE2 ; Filter them all 07FE AC LODSB ; Get port 07FF 49 DEC CX ; Bump byte count 0800 E3 F2 JCXZ PARSEX ; Ran out of bytes Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-21 0802 3C 31 CMP AL,'1' ; Default port? 0804 74 0A JZ PARSE2 ; Yes 0806 3C 32 CMP AL,'2' ; Com2? 0808 75 06 JNZ PARSE2 ; Not a port number 080A C7 06 0A03 R 02F8 MOV WORD PTR [PORT],02F8H ; Put in com2 port number 0810 AC PARSE2: LODSB 0811 3C 20 CMP AL,' ' ; Look for another space 0813 76 04 JBE PARSE3 0815 E2 F9 LOOP PARSE2 0817 EB DB JMP SHORT PARSEX ; No more spaces ; 0819 80 3C 20 PARSE3: CMP BYTE PTR [SI],' ' ; More spaces? 081C 76 F2 JBE PARSE2 ; Filter them all 081E BF 0CED R MOV DI,OFFSET FNAME ; We got to the filename 0821 F3/ A4 REP MOVSB ; Copy it 0823 C3 RET 0824 PARSE ENDP ; ; Map string addressed by SI to upper case. CX = byte count. ; 0824 MAP PROC NEAR 0824 51 PUSH CX 0825 56 PUSH SI 0826 57 PUSH DI 0827 8B FE MOV DI,SI ; Copy for same offset 0829 AC MAP0: LODSB ; Get byte 082A 3C 7A CMP AL,'z' ; Check upper limit 082C 77 06 JA MAP1 ; Not a lower case character 082E 3C 61 CMP AL,'a' ; Check lower limit 0830 72 02 JB MAP1 ; Not a lower case character 0832 24 5F AND AL,95 ; Reset lower case bits 0834 AA MAP1: STOSB ; Replace in the string 0835 E2 F2 LOOP MAP0 0837 5F POP DI 0838 5E POP SI 0839 59 POP CX 083A C3 RET 083B MAP ENDP ; ; Control Break not allowed. ; 083B BRK PROC FAR 083B 2E: C6 06 09F0 R FF MOV BYTE PTR CS:[KILL],0FFH ; Set the flag. 0841 CF IRET 0842 BRK ENDP ; 0842 SHOW PROC NEAR 0842 06 PUSH ES 0843 8E 06 0A22 R MOV ES,WORD PTR [SCR_SEG] ; Pick up screen segment ; 0847 A1 09FB R MOV AX,WORD PTR [REC_NOL] ; Get record number 084A 33 D2 XOR DX,DX ; Set high word 084C BF 054C MOV DI,SCR_BLK ; Where to put the data 084F E8 0877 R CALL ASCII ; Convert Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-22 ; 0852 1E PUSH DS ; Save segment 0853 8E 1E 0A07 R MOV DS,WORD PTR [BUF_SEG] ; Get buffer segment 0857 A1 0000 MOV AX,WORD PTR DS:[LEN] ; Get bytes 085A 1F POP DS ; Restore segment 085B 33 D2 XOR DX,DX ; Zero high word 085D BF 05EC MOV DI,SCR_LEN ; Where to put the ASCII 0860 E8 0877 R CALL ASCII ; Convert to ascii 0863 B8 0720 MOV AX,0720H ; Normal attribute and a space 0866 AB STOSW 0867 AB STOSW ; 0868 8B 16 09F3 R MOV DX,WORD PTR [CNT_HI] ; Pick up byte count 086C A1 09F5 R MOV AX,WORD PTR [CNT_LO] 086F BF 068C MOV DI,SCR_BYT ; Where to put the data 0872 E8 0877 R CALL ASCII ; Convert to ASCII decimal ; 0875 07 POP ES 0876 C3 RET 0877 SHOW ENDP ; ; Print double precision number in DX:AX. The string is addressed by DI ; All registers except BP are destroyed by this call. ; 0877 ASCII PROC NEAR 0877 BD 0000 MOV BP,0000 ; Leading zero flag 087A B9 3B9A MOV CX,3B9AH ; Get billions 087D BB CA00 MOV BX,0CA00H 0880 E8 08DA R CALL SUBTR ; Subtract them out 0883 E8 08FB R CALL COMMA ; Put in a comma 0886 B9 05F5 MOV CX,05F5H ; Get hundred-millions 0889 BB E100 MOV BX,0E100H 088C E8 08DA R CALL SUBTR ; Subtract them out 088F B9 0098 MOV CX,0098H ; Get ten-millions 0892 BB 9680 MOV BX,9680H 0895 E8 08DA R CALL SUBTR ; Subtract them out 0898 B9 000F MOV CX,000FH ; Get millions 089B BB 4240 MOV BX,4240H 089E E8 08DA R CALL SUBTR ; Subtract them out 08A1 E8 08FB R CALL COMMA ; Put in a comma 08A4 B9 0001 MOV CX,0001H ; Get hundred-thousands 08A7 BB 86A0 MOV BX,86A0H 08AA E8 08DA R CALL SUBTR ; Subtract them out 08AD B9 0000 MOV CX,0000H ; Get ten-thousands 08B0 BB 2710 MOV BX,2710H 08B3 E8 08DA R CALL SUBTR ; Subtract them out 08B6 B9 0000 MOV CX,0000H ; Get thousands 08B9 BB 03E8 MOV BX,03E8H 08BC E8 08DA R CALL SUBTR ; Subtract them out 08BF E8 08FB R CALL COMMA ; Put in a comma 08C2 B9 0000 MOV CX,0000H ; Get hundreds 08C5 BB 0064 MOV BX,0064H 08C8 E8 08DA R CALL SUBTR ; Subtract them out 08CB B9 0000 MOV CX,0000H ; Get tens Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-23 08CE BB 000A MOV BX,000AH 08D1 E8 08DA R CALL SUBTR ; Subtract them out 08D4 04 30 ADD AL,'0' ; Add bias to residual 08D6 B4 07 MOV AH,7 ; Normal attribute 08D8 AB STOSW ; Put in the string 08D9 C3 RET ; 08DA BE 002F SUBTR: MOV SI,'0'-1 ; We are out of registers! 08DD 46 SUBTR1: INC SI ; Counter 08DE 2B C3 SUB AX,BX ; Dword subtraction 08E0 1B D1 SBB DX,CX 08E2 73 F9 JNB SUBTR1 ; Continue until a carry 08E4 03 C3 ADD AX,BX ; One too many, add back 08E6 13 D1 ADC DX,CX ; and the remainder 08E8 83 FD 00 CMP BP,0 ; See if we printed anything yet 08EB 75 05 JNZ SUBTR2 ; No, can't be a leading zero 08ED 83 FE 30 CMP SI,'0' ; See if its a zero 08F0 74 08 JZ SUBTR3 ; Yes, don't print them ; 08F2 45 SUBTR2: INC BP ; We are now 'printing' a character 08F3 50 PUSH AX ; Save accumulator 08F4 8B C6 MOV AX,SI ; Get index 08F6 B4 07 MOV AH,7 ; Attribute byte 08F8 AB STOSW ; Put in screen memort 08F9 58 POP AX ; Restore accumulator 08FA C3 SUBTR3: RET ; 08FB 83 FD 00 COMMA: CMP BP,0 ; Any bytes printed? 08FE 74 07 JZ PASS ; No, then no commas 0900 50 PUSH AX ; Yes, save 0901 B0 2C MOV AL,',' ; Get a comma 0903 B4 07 MOV AH,7 0905 AB STOSW ; Into string 0906 58 POP AX ; Restore 0907 C3 PASS: RET 0908 ASCII ENDP ; ; Send 10 control-Xes to remote to cause an abort. ; 0908 SENDX PROC NEAR 0908 B9 000A MOV CX,10 ; Bytes to send 090B B0 18 SENDX0: MOV AL,CAN ; Control-x 090D E8 02BC R CALL FORCE ; Send (no flow control)the byte 0910 E2 F9 LOOP SENDX0 ; Continue for all bytes 0912 C3 RET 0913 SENDX ENDP ; ; Save any information in the screen regen buffer. ; 0913 SAV_SCR PROC NEAR 0913 C6 06 09F1 R FF MOV BYTE PTR [SCR_SAV],0FFH ; Set entry flag 0918 B8 0500 MOV AX,0500H ; Select page zero 091B CD 10 INT VIDEO ; Do it ; Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-24 091D B8 0300 MOV AX,0300H ; Get cursor position 0920 BB 0000 MOV BX,0 ; Page zero 0923 CD 10 INT VIDEO ; Get the cursor position 0925 89 16 0A20 R MOV WORD PTR [CUR_POS],DX ; Save the position ; 0929 B8 0200 MOV AX,0200H ; Set cursor position 092C BB 0000 MOV BX,0 ; Page zero 092F BA 1A00 MOV DX,1A00H ; Hide off screen 0932 CD 10 INT VIDEO ; Set the position ; 0934 1E PUSH DS ; Save data segment 0935 8E 1E 0A22 R MOV DS,WORD PTR [SCR_SEG] ; Pick up screen segment 0939 BE 03F6 MOV SI,ORIGIN ; Where we will put logo 093C BF 0AAE R MOV DI,OFFSET SCR_BUF ; Where to save the data 093F B9 0006 MOV CX,6 ; Lines to save 0942 51 SAV0: PUSH CX ; Save count 0943 B9 0017 MOV CX,LINLEN ; Length of line 0946 F3/ A5 REP MOVSW ; Copy to buffer 0948 83 C6 72 ADD SI,160 - (LINLEN *2) ; Next line 094B 59 POP CX ; Restore count 094C E2 F4 LOOP SAV0 ; Continue for all lines 094E 1F POP DS ; Restore segment 094F C3 RET 0950 SAV_SCR ENDP ; ; Restore saved bytes/attributes to the screen regen buffer ; 0950 RES_SCR PROC NEAR 0950 80 3E 09F1 R 00 CMP BYTE PTR [SCR_SAV],0 ; Did we save the screen? 0955 75 01 JNZ RESIT ; Yes 0957 C3 RET ; No, don't restore 0958 C6 06 09F1 R 00 RESIT: MOV BYTE PTR [SCR_SAV],0 ; Show its already been restored. 095D 06 PUSH ES ; Save segment 095E 8E 06 0A22 R MOV ES,WORD PTR [SCR_SEG] ; Pick up screen segment 0962 BF 03F6 MOV DI,ORIGIN ; Where to start 0965 BE 0AAE R MOV SI,OFFSET SCR_BUF ; Where the saved data are 0968 B9 0006 MOV CX,6 ; Lines to restore 096B 51 RES0: PUSH CX ; Save count 096C B9 0017 MOV CX,LINLEN ; Line length 096F F3/ A5 REP MOVSW ; Move to screen buffer 0971 83 C7 72 ADD DI,160 - ( LINLEN * 2 ) ; Ready next line 0974 59 POP CX ; Restore line count 0975 E2 F4 LOOP RES0 ; Continue for all lines 0977 07 POP ES ; Restore segment ; 0978 B8 0200 MOV AX,0200H ; Set cursor position 097B BB 0000 MOV BX,0 ; Page zero 097E 8B 16 0A20 R MOV DX,WORD PTR [CUR_POS] ; Get old position 0982 CD 10 INT VIDEO ; Set the position 0984 C3 RET 0985 RES_SCR ENDP ; ; Write status block to the screen. ; Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-25 0985 WRT_SCR PROC NEAR 0985 06 PUSH ES ; Save segment 0986 8E 06 0A22 R MOV ES,WORD PTR [SCR_SEG] ; Pick up screen segment 098A BE 0A24 R MOV SI,OFFSET LIN1 ; Data for line q 098D BF 03F6 MOV DI,ORIGIN ; Screen regen buffer 0990 B9 0006 MOV CX,6 ; Number of lines 0993 B4 07 MOV AH,7 ; Normal attribute 0995 51 WRT0: PUSH CX ; Save line count 0996 B9 0017 MOV CX,LINLEN ; Get length of the line 0999 AC WRT1: LODSB ; Get byte from logo 099A AB STOSW ; Save a word in screen memory 099B E2 FC LOOP WRT1 ; Continue for the line 099D 83 C7 72 ADD DI,160 - (LINLEN * 2) ; Offset to next line 09A0 59 POP CX ; Restore line count 09A1 E2 F2 LOOP WRT0 ; Continue for all lines 09A3 07 POP ES ; Restore segment 09A4 C3 RET 09A5 WRT_SCR ENDP ; ; Get segment address for screen regen buffer and base/status port for ; the video controller. Save addresses in code segment. ; 09A5 FIND_VIDEO PROC NEAR 09A5 1E PUSH DS ; Save present 09A6 B8 ---- R MOV AX,BSEG ; Get BIOS segment 09A9 8E D8 MOV DS,AX ; Into ours 09AB 81 3E 0063 R 03D0 CMP WORD PTR DS:[ADDR_6845],3D0H 09B1 1F POP DS ; Restore the data segment 09B2 B8 B800 MOV AX,0B800H ; Segment for color 09B5 73 03 JAE COLOR ; Yes, its correct 09B7 B8 B000 MOV AX,0B000H ; Must be B&W 09BA A3 0A22 R COLOR: MOV WORD PTR [SCR_SEG],AX ; Save for later ; 09BD 1E PUSH DS 09BE 8E 1E 0A22 R MOV DS,WORD PTR [SCR_SEG] ; Pick up screen segment 09C2 A1 0000 MOV AX,WORD PTR DS:[0] ; Get first word 09C5 F7 D0 NOT AX ; Invert it 09C7 A3 0000 MOV WORD PTR DS:[0],AX ; Put back in screen memory 09CA 50 PUSH AX ; Exercise bus 09CB 58 POP AX 09CC 39 06 0000 CMP WORD PTR DS:[0],AX ; See if it went 09D0 9C PUSHF ; Save result 09D1 F7 16 0000 NOT WORD PTR DS:[0] ; Change back to normal 09D5 9D POPF 09D6 1F POP DS ; Restore segment 09D7 75 01 JNZ CHKMEM ; Memory was not writable 09D9 C3 RET ; 09DA 81 3E 0A22 R B000 CHKMEM: CMP WORD PTR [SCR_SEG],0B000H ; See if mono 09E0 74 07 JZ MONO ; ; Color didn't work, change to Mono ; 09E2 C7 06 0A22 R B000 MOV WORD PTR [SCR_SEG],0B000H Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-26 09E8 C3 RET ; ; Mono didn't work, change to color ; 09E9 C7 06 0A22 R B800 MONO: MOV WORD PTR [SCR_SEG],0B800H 09EF C3 RET 09F0 FIND_VIDEO ENDP ; 09F0 00 KILL DB 0 ; Abort program. 09F1 00 SCR_SAV DB 0 ; Flag to show we saved the screen. 09F2 00 INT_FLG DB 0 ; Flag to show hot interrupts 09F3 0000 CNT_HI DW 0 ; Transfer byte count 09F5 0000 CNT_LO DW 0 ; Low word of above. 09F7 00 ENABLE DB 0 ; TX enable bytes 09F8 00 WASC DB 0 ; Flag for carrier 09F9 00 STATUS DB 0 ; Port status 09FA 00 FEND DB 0 ; End of file? 09FB 0000 REC_NOL DW 0 ; Record number of file to send/rec = 000D KLEN EQU $ - KILL ; Length to zero out 09FD 0400 BYTES DW 1024 ; Bytes to read/send 09FF ?? TRIES DB ? ; Attempts to send a block 0A00 ?? RXTX DB ? ; Receive/transm flag 0A01 ???? CLOCK DW ? ; Local timer 0A03 03F8 PORT DW 3F8H ; Modem port 0A05 ???? HANDLE DW ? ; File handle 0A07 ???? BUF_SEG DW ? ; Segment of buffer 0A09 ???? DAT_SEG DW ? ; Next 64k segment 0A0B OLD_CLK LABEL DWORD ; Old clock vector 0A0B ???? CLK_OFF DW ? ; Clock offset 0A0D ???? CLK_SEG DW ? ; Clock segment 0A0F OLD_BRK LABEL DWORD ; Old break key vector 0A0F ???? BRK_OFF DW ? 0A11 ???? BRK_SEG DW ? 0A13 OLD_CTC LABEL DWORD ; Old ^C vector 0A13 ???? CTC_OFF DW ? 0A15 ???? CTC_SEG DW ? 0A17 OLD_UART LABEL DWORD ; Old UART interrupt address 0A17 ???? UAR_OFF DW ? ; Its offset 0A19 ???? UAR_SEG DW ? ; and segment 0A1B ?? OLD_MASK DB ? ; Old interrupt masm 0A1C ???? BYTE_CNT DW ? ; Interrupt byte count 0A1E ???? WPOINT DW ? ; Write pointer for interrupt 0A20 ???? CUR_POS DW ? 0A22 ???? SCR_SEG DW ? ; 0A24 C9 LIN1 DB 201 0A25 0015[ DB 21 DUP (205) CD ] 0A3A BB DB 187 0A3B BA 20 4A 20 4D 20 4F DB 186,' J M O D E M Status ',186 20 44 20 45 20 4D 20 20 53 74 61 74 75 73 Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-27 20 BA 0A52 BA 20 20 42 6C 6F 63 DB 186,' Block : ',186 6B 20 3A 20 20 20 20 20 20 20 20 20 20 20 20 BA 0A69 BA 20 4C 65 6E 67 74 DB 186,' Length : ',186 68 20 3A 20 20 20 20 20 20 20 20 20 20 20 20 BA 0A80 BA 20 42 79 74 65 73 DB 186,' Bytes : ',186 20 20 3A 20 20 20 20 20 20 20 20 20 20 20 20 BA 0A97 C8 DB 200 0A98 0015[ DB 21 DUP (205) CD ] 0AAD BC DB 188 ; = 0AAE OUTBUF EQU $ ; Use as an output buffer 0AAE SCR_BUF LABEL BYTE 0AAE 0D 0A 20 20 20 20 20 PRP3 DB CR,LF,' J M O D E M File transfer system V1.03' 20 20 20 20 20 4A 20 4D 20 4F 20 44 20 45 20 4D 20 20 46 69 6C 65 20 74 72 61 6E 73 66 65 72 20 73 79 73 74 65 6D 20 56 31 2E 30 33 0AE1 0D 0A 20 20 20 20 20 DB CR,LF,' Created by Richard B. Johnson' 20 20 20 20 20 20 20 20 43 72 65 61 74 65 64 20 62 79 20 20 20 20 52 69 63 68 61 72 64 20 42 2E 20 4A 6F 68 6E 73 6F 6E 0B10 0D 0A 20 20 20 20 20 DB CR,LF,' PROGRAM EXCHANGE (719) 548-0208' 20 20 20 20 20 20 20 20 50 52 4F 47 52 41 4D 20 45 58 43 48 41 4E 47 45 20 20 28 37 31 39 29 20 35 34 38 2D 30 32 30 38 0B3F 0D 0A 55 73 61 67 65 DB CR,LF,'Usage:' 3A 0B47 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM S1 (to send a file via COM1)' 4D 20 53 31 20 3C 66 69 6C 65 6E 61 6D 65 2E 74 79 70 3E 20 20 28 74 6F 20 73 65 6E 64 20 61 20 66 69 6C 65 20 76 69 61 20 43 4F 4D 31 29 Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-28 0B7C 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM R1 (to receive a file via COM1)' 4D 20 52 31 20 3C 66 69 6C 65 6E 61 6D 65 2E 74 79 70 3E 20 20 28 74 6F 20 72 65 63 65 69 76 65 20 61 20 66 69 6C 65 20 76 69 61 20 43 4F 4D 31 29 0BB4 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM S2 (to send a file via COM2)' 4D 20 53 32 20 3C 66 69 6C 65 6E 61 6D 65 2E 74 79 70 3E 20 20 28 74 6F 20 73 65 6E 64 20 61 20 66 69 6C 65 20 76 69 61 20 43 4F 4D 32 29 0BE9 0D 0A 4A 4D 4F 44 45 DB CR,LF,'JMODEM R2 (to receive a file via COM2)' 4D 20 52 32 20 3C 66 69 6C 65 6E 61 6D 65 2E 74 79 70 3E 20 20 28 74 6F 20 72 65 63 65 69 76 65 20 61 20 66 69 6C 65 20 76 69 61 20 43 4F 4D 32 29 0C21 0D 0A 24 CRLF DB CR,LF,'$' 0C24 0D 0A 53 70 65 63 69 PRP4 DB CR,LF,'Specified file $' 66 69 65 64 20 66 69 6C 65 20 24 0C36 20 6E 6F 74 20 66 6F PRP5 DB ' not found.$' 75 6E 64 2E 24 0C42 20 43 61 6E 27 74 20 PRP6 DB ' Can''t be created.$' 62 65 20 63 72 65 61 74 65 64 2E 24 0C55 0D 0A 53 65 6E 64 69 PRP7 DB CR,LF,'Sending file $' 6E 67 20 66 69 6C 65 20 24 0C65 0D 0A 52 65 63 65 69 PRP8 DB CR,LF,'Receiving file $' 76 69 6E 67 20 66 69 6C 65 20 24 0C77 0D 0A 46 69 6C 65 20 PRP9 DB CR,LF,'File transfer aborted!$' 74 72 61 6E 73 66 65 72 20 61 62 6F 72 74 65 64 21 24 0C90 0D 0A 46 69 6C 65 20 PRP10 DB CR,LF,'File transfer complete.$' 74 72 61 6E 73 66 65 72 20 63 6F 6D 70 6C 65 74 65 2E 24 0CAA 0D 0A 4D 6F 64 65 6D PRP11 DB CR,LF,'Modem carrier failed.$' 20 63 61 72 72 69 65 72 20 66 61 69 6C 65 64 2E 24 0CC2 20 20 5B 20 53 79 6E PRP12 DB ' [ Synchronized ] ',CR,LF,'$' 63 68 72 6F 6E 69 7A 65 64 20 5D 20 0D 0A Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Page 1-29 24 0CD8 20 20 5B 20 53 79 6E PRP13 DB ' [ Synchronizing ]',CR,'$' 63 68 72 6F 6E 69 7A 69 6E 67 20 5D 0D 24 0CED 0040[ FNAME DB 64 DUP (0) 00 ] 0D2D 0040[ ONAME DB 64 DUP (0) 00 ] ; 0D70 ORG ((($ - START) + 16) AND 0FFF0H) 0D70 0020[ DB 32 DUP ('STACK ') 53 54 41 43 4B 20 20 20 ] 0E70 STACKP LABEL WORD ; 0E80 ORG ((($ - START) + 16) AND 0FFF0H) 0E80 BUFFER LABEL BYTE 0E80 PSEG ENDS END MAIN Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Symbols-1 Structures and Records: N a m e Width # fields Shift Width Mask Initial IBUFFER . . . . . . . . . . . . 0005 0004 LEN . . . . . . . . . . . . . 0000 CTRL . . . . . . . . . . . . . 0002 RECN . . . . . . . . . . . . . 0003 IDATA . . . . . . . . . . . . 0004 Segments and Groups: N a m e Length Align Combine Class BSEG . . . . . . . . . . . . . . 0065 AT 0040 PSEG . . . . . . . . . . . . . . 0E80 PARA PUBLIC 'CODE' Symbols: N a m e Type Value Attr ABORT . . . . . . . . . . . . . NUMBER 0020 ACK . . . . . . . . . . . . . . NUMBER 0006 ADDR_6845 . . . . . . . . . . . L WORD 0063 BSEG ASCII . . . . . . . . . . . . . N PROC 0877 PSEG Length = 0091 BRK . . . . . . . . . . . . . . F PROC 083B PSEG Length = 0007 BRK_OFF . . . . . . . . . . . . L WORD 0A0F PSEG BRK_SEG . . . . . . . . . . . . L WORD 0A11 PSEG BUFFER . . . . . . . . . . . . . L BYTE 0E80 PSEG BUF_SEG . . . . . . . . . . . . L WORD 0A07 PSEG BYEBYE . . . . . . . . . . . . . L NEAR 040E PSEG BYPASS . . . . . . . . . . . . . L NEAR 0171 PSEG BYTES . . . . . . . . . . . . . L WORD 09FD PSEG BYTE_CNT . . . . . . . . . . . . L WORD 0A1C PSEG CAN . . . . . . . . . . . . . . NUMBER 0018 CANCEL . . . . . . . . . . . . . L NEAR 0218 PSEG CAROK . . . . . . . . . . . . . L NEAR 0428 PSEG CHKMEM . . . . . . . . . . . . . L NEAR 09DA PSEG CHKRES . . . . . . . . . . . . . L NEAR 01A0 PSEG CHK_EX . . . . . . . . . . . . . L NEAR 0316 PSEG CHK_STA . . . . . . . . . . . . N PROC 02FE PSEG Length = 001A CLK_EX . . . . . . . . . . . . . L NEAR 04B6 PSEG CLK_OFF . . . . . . . . . . . . L WORD 0A0B PSEG CLK_SEG . . . . . . . . . . . . L WORD 0A0D PSEG CLOCK . . . . . . . . . . . . . L WORD 0A01 PSEG CLOSE . . . . . . . . . . . . . N PROC 0690 PSEG Length = 000A CLR_BUF . . . . . . . . . . . . N PROC 0308 PSEG Length = 0010 CNT_HI . . . . . . . . . . . . . L WORD 09F3 PSEG CNT_LO . . . . . . . . . . . . . L WORD 09F5 PSEG CODELOC . . . . . . . . . . . . NUMBER 4000 COLOR . . . . . . . . . . . . . L NEAR 09BA PSEG Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Symbols-2 COM2 . . . . . . . . . . . . . . L NEAR 0502 PSEG COMM2 . . . . . . . . . . . . . L NEAR 0557 PSEG COMMA . . . . . . . . . . . . . L NEAR 08FB PSEG COMP . . . . . . . . . . . . . . NUMBER 0002 COMRES . . . . . . . . . . . . . L NEAR 05C7 PSEG COMSAV . . . . . . . . . . . . . L NEAR 0510 PSEG COMSET . . . . . . . . . . . . . L NEAR 0569 PSEG CONT0 . . . . . . . . . . . . . L NEAR 0432 PSEG CONT1 . . . . . . . . . . . . . L NEAR 0449 PSEG CR . . . . . . . . . . . . . . . NUMBER 000D CRC . . . . . . . . . . . . . . N PROC 044E PSEG Length = 0029 CRC0 . . . . . . . . . . . . . . L NEAR 0463 PSEG CREATE . . . . . . . . . . . . . L NEAR 065F PSEG CREOK . . . . . . . . . . . . . L NEAR 068F PSEG CRLF . . . . . . . . . . . . . . L BYTE 0C21 PSEG CTC_OFF . . . . . . . . . . . . L WORD 0A13 PSEG CTC_SEG . . . . . . . . . . . . L WORD 0A15 PSEG CTS . . . . . . . . . . . . . . NUMBER 0010 CTSDSR . . . . . . . . . . . . . NUMBER 0030 CUR_POS . . . . . . . . . . . . L WORD 0A20 PSEG DAT_SEG . . . . . . . . . . . . L WORD 0A09 PSEG DECD0 . . . . . . . . . . . . . L NEAR 077A PSEG DECD1 . . . . . . . . . . . . . L NEAR 0787 PSEG DECD2 . . . . . . . . . . . . . L NEAR 0788 PSEG DECODE . . . . . . . . . . . . . N PROC 0775 PSEG Length = 001D DIREC0 . . . . . . . . . . . . . L NEAR 047A PSEG DIRECT . . . . . . . . . . . . . N PROC 0477 PSEG Length = 0012 DIREX . . . . . . . . . . . . . L NEAR 0488 PSEG DR . . . . . . . . . . . . . . . NUMBER 0001 DSR . . . . . . . . . . . . . . NUMBER 0020 EASY_INT . . . . . . . . . . . . F PROC 02D2 PSEG Length = 002C ENABLE . . . . . . . . . . . . . L BYTE 09F7 PSEG ENCD0 . . . . . . . . . . . . . L NEAR 0798 PSEG ENCD1 . . . . . . . . . . . . . L NEAR 07B3 PSEG ENCD2 . . . . . . . . . . . . . L NEAR 07BF PSEG ENCD3 . . . . . . . . . . . . . L NEAR 07C3 PSEG ENCODE . . . . . . . . . . . . . N PROC 0792 PSEG Length = 0038 ENDACK . . . . . . . . . . . . . L NEAR 0267 PSEG END_F . . . . . . . . . . . . . L NEAR 025C PSEG EOF . . . . . . . . . . . . . . NUMBER 0004 EOT . . . . . . . . . . . . . . NUMBER 0004 ERROR . . . . . . . . . . . . . NUMBER 0080 EXITF . . . . . . . . . . . . . L NEAR 01AF PSEG FEND . . . . . . . . . . . . . . L BYTE 09FA PSEG FIND_VIDEO . . . . . . . . . . . N PROC 09A5 PSEG Length = 004B FLOW . . . . . . . . . . . . . . N PROC 03E1 PSEG Length = 006D FLOW0 . . . . . . . . . . . . . L NEAR 03F5 PSEG FNAME . . . . . . . . . . . . . L BYTE 0CED PSEG Length = 0040 FORCE . . . . . . . . . . . . . N PROC 02BC PSEG Length = 0016 GET0 . . . . . . . . . . . . . . L NEAR 031F PSEG Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Symbols-3 GET1 . . . . . . . . . . . . . . L NEAR 033D PSEG GET2 . . . . . . . . . . . . . . L NEAR 033E PSEG GET_ACK . . . . . . . . . . . . N PROC 0318 PSEG Length = 0028 GET_INP . . . . . . . . . . . . N PROC 031E PSEG Length = 0022 HANDLE . . . . . . . . . . . . . L WORD 0A05 PSEG HOME . . . . . . . . . . . . . . NUMBER 8000 HOT_IN . . . . . . . . . . . . . L NEAR 0591 PSEG INT_1 . . . . . . . . . . . . . NUMBER 000C INT_2 . . . . . . . . . . . . . NUMBER 000B INT_CTL . . . . . . . . . . . . NUMBER 0021 INT_FLG . . . . . . . . . . . . L BYTE 09F2 PSEG INT_RC . . . . . . . . . . . . . NUMBER 0001 IRQ3 . . . . . . . . . . . . . . NUMBER 00F7 IRQ4 . . . . . . . . . . . . . . NUMBER 00EF KILL . . . . . . . . . . . . . . L BYTE 09F0 PSEG KLEN . . . . . . . . . . . . . . NUMBER 000D LCL_CLK . . . . . . . . . . . . F PROC 04A2 PSEG Length = 0019 LF . . . . . . . . . . . . . . . NUMBER 000A LIN1 . . . . . . . . . . . . . . L BYTE 0A24 PSEG LINLEN . . . . . . . . . . . . . NUMBER 0017 MAIN . . . . . . . . . . . . . . N PROC 0100 PSEG Length = 0031 MAP . . . . . . . . . . . . . . N PROC 0824 PSEG Length = 0017 MAP0 . . . . . . . . . . . . . . L NEAR 0829 PSEG MAP1 . . . . . . . . . . . . . . L NEAR 0834 PSEG MAX . . . . . . . . . . . . . . NUMBER 000A MONO . . . . . . . . . . . . . . L NEAR 09E9 PSEG MS_DOS . . . . . . . . . . . . . NUMBER 0021 NAK . . . . . . . . . . . . . . NUMBER 0015 NCOM1 . . . . . . . . . . . . . L NEAR 05BC PSEG NFILE0 . . . . . . . . . . . . . L NEAR 063A PSEG NFILE1 . . . . . . . . . . . . . L NEAR 064C PSEG NODOT . . . . . . . . . . . . . L NEAR 0649 PSEG NODWN . . . . . . . . . . . . . L NEAR 06BF PSEG NOENC . . . . . . . . . . . . . L NEAR 07BE PSEG NONAK . . . . . . . . . . . . . L NEAR 020D PSEG NONORM . . . . . . . . . . . . . NUMBER FFFE NORM . . . . . . . . . . . . . . L NEAR 06E8 PSEG NORMAL . . . . . . . . . . . . . NUMBER 0001 NOUP . . . . . . . . . . . . . . L NEAR 06B1 PSEG OLD_BRK . . . . . . . . . . . . L DWORD 0A0F PSEG OLD_CLK . . . . . . . . . . . . L DWORD 0A0B PSEG OLD_CTC . . . . . . . . . . . . L DWORD 0A13 PSEG OLD_MASK . . . . . . . . . . . . L BYTE 0A1B PSEG OLD_UART . . . . . . . . . . . . L DWORD 0A17 PSEG ONAME . . . . . . . . . . . . . L BYTE 0D2D PSEG Length = 0040 OPEN_R . . . . . . . . . . . . . N PROC 05EE PSEG Length = 0031 OPEN_W . . . . . . . . . . . . . N PROC 061F PSEG Length = 0071 Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Symbols-4 OPN_OK . . . . . . . . . . . . . L NEAR 061E PSEG ORIGIN . . . . . . . . . . . . . NUMBER 03F6 OUTBUF . . . . . . . . . . . . . NEAR 0AAE PSEG PARSE . . . . . . . . . . . . . N PROC 07CA PSEG Length = 005A PARSE0 . . . . . . . . . . . . . L NEAR 07DA PSEG PARSE1 . . . . . . . . . . . . . L NEAR 07E3 PSEG PARSE2 . . . . . . . . . . . . . L NEAR 0810 PSEG PARSE3 . . . . . . . . . . . . . L NEAR 0819 PSEG PARSEX . . . . . . . . . . . . . L NEAR 07F4 PSEG PASS . . . . . . . . . . . . . . L NEAR 0907 PSEG PORT . . . . . . . . . . . . . . L WORD 0A03 PSEG PROMPT . . . . . . . . . . . . . N PROC 03DC PSEG Length = 0005 PRP10 . . . . . . . . . . . . . L BYTE 0C90 PSEG PRP11 . . . . . . . . . . . . . L BYTE 0CAA PSEG PRP12 . . . . . . . . . . . . . L BYTE 0CC2 PSEG PRP13 . . . . . . . . . . . . . L BYTE 0CD8 PSEG PRP3 . . . . . . . . . . . . . . L BYTE 0AAE PSEG PRP4 . . . . . . . . . . . . . . L BYTE 0C24 PSEG PRP5 . . . . . . . . . . . . . . L BYTE 0C36 PSEG PRP6 . . . . . . . . . . . . . . L BYTE 0C42 PSEG PRP7 . . . . . . . . . . . . . . L BYTE 0C55 PSEG PRP8 . . . . . . . . . . . . . . L BYTE 0C65 PSEG PRP9 . . . . . . . . . . . . . . L BYTE 0C77 PSEG RDATA . . . . . . . . . . . . . N PROC 0340 PSEG Length = 004B RDATA0 . . . . . . . . . . . . . L NEAR 0346 PSEG RDATA1 . . . . . . . . . . . . . L NEAR 035E PSEG RDATA2 . . . . . . . . . . . . . L NEAR 0385 PSEG READ . . . . . . . . . . . . . . N PROC 069A PSEG Length = 0096 READ0 . . . . . . . . . . . . . L NEAR 0720 PSEG RECV . . . . . . . . . . . . . . N PROC 01C9 PSEG Length = 00B9 RECV0 . . . . . . . . . . . . . L NEAR 0203 PSEG RECV1 . . . . . . . . . . . . . L NEAR 020A PSEG RECV2 . . . . . . . . . . . . . L NEAR 0212 PSEG RECV3 . . . . . . . . . . . . . L NEAR 0232 PSEG REC_NOL . . . . . . . . . . . . L WORD 09FB PSEG RES0 . . . . . . . . . . . . . . L NEAR 096B PSEG RESIT . . . . . . . . . . . . . L NEAR 0958 PSEG RESP . . . . . . . . . . . . . . N PROC 02B5 PSEG Length = 001D RESP0 . . . . . . . . . . . . . L NEAR 02C6 PSEG RES_INT . . . . . . . . . . . . N PROC 0589 PSEG Length = 0065 RES_SCR . . . . . . . . . . . . N PROC 0950 PSEG Length = 0035 RETRY . . . . . . . . . . . . . NUMBER 0008 RLSD . . . . . . . . . . . . . . NUMBER 0080 RTS_DTR . . . . . . . . . . . . NUMBER 0003 RXTX . . . . . . . . . . . . . . L BYTE 0A00 PSEG SAV0 . . . . . . . . . . . . . . L NEAR 0942 PSEG SAV_SCR . . . . . . . . . . . . N PROC 0913 PSEG Length = 003D SCR_ACK . . . . . . . . . . . . NUMBER 055E SCR_BLK . . . . . . . . . . . . NUMBER 054C SCR_BUF . . . . . . . . . . . . L BYTE 0AAE PSEG SCR_BYT . . . . . . . . . . . . NUMBER 068C Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Symbols-5 SCR_LEN . . . . . . . . . . . . NUMBER 05EC SCR_SAV . . . . . . . . . . . . L BYTE 09F1 PSEG SCR_SEG . . . . . . . . . . . . L WORD 0A22 PSEG SDATA . . . . . . . . . . . . . N PROC 0282 PSEG Length = 0033 SDATA1 . . . . . . . . . . . . . L NEAR 02A1 PSEG SDATA2 . . . . . . . . . . . . . L NEAR 02A4 PSEG SEND . . . . . . . . . . . . . . N PROC 0131 PSEG Length = 0098 SEND0 . . . . . . . . . . . . . L NEAR 016E PSEG SEND1 . . . . . . . . . . . . . L NEAR 0176 PSEG SEND2 . . . . . . . . . . . . . L NEAR 0179 PSEG SENDX . . . . . . . . . . . . . N PROC 0908 PSEG Length = 000B SENDX0 . . . . . . . . . . . . . L NEAR 090B PSEG SET_INT . . . . . . . . . . . . N PROC 04BB PSEG Length = 00CE SET_SEG . . . . . . . . . . . . N PROC 0489 PSEG Length = 0019 SHOW . . . . . . . . . . . . . . N PROC 0842 PSEG Length = 0035 SHO_RES . . . . . . . . . . . . N PROC 03D0 PSEG Length = 000C STACKP . . . . . . . . . . . . . L WORD 0E70 PSEG START . . . . . . . . . . . . . NEAR 0000 PSEG STATUS . . . . . . . . . . . . . L BYTE 09F9 PSEG SUBTR . . . . . . . . . . . . . L NEAR 08DA PSEG SUBTR1 . . . . . . . . . . . . . L NEAR 08DD PSEG SUBTR2 . . . . . . . . . . . . . L NEAR 08F2 PSEG SUBTR3 . . . . . . . . . . . . . L NEAR 08FA PSEG SYN . . . . . . . . . . . . . . NUMBER 0016 SYNC . . . . . . . . . . . . . . NUMBER 0040 SYNCEX . . . . . . . . . . . . . L NEAR 03CE PSEG SYNCH . . . . . . . . . . . . . N PROC 038B PSEG Length = 0045 SYNCH0 . . . . . . . . . . . . . L NEAR 039E PSEG SYNCH1 . . . . . . . . . . . . . L NEAR 03AA PSEG THRE . . . . . . . . . . . . . . NUMBER 0020 TIMEOUT . . . . . . . . . . . . NUMBER 0010 TIMOUT . . . . . . . . . . . . . NUMBER 0009 TRIES . . . . . . . . . . . . . L BYTE 09FF PSEG TRISTAT . . . . . . . . . . . . NUMBER 0008 UAR_OFF . . . . . . . . . . . . L WORD 0A17 PSEG UAR_SEG . . . . . . . . . . . . L WORD 0A19 PSEG VIDEO . . . . . . . . . . . . . NUMBER 0010 WASC . . . . . . . . . . . . . . L BYTE 09F8 PSEG WASOK . . . . . . . . . . . . . L NEAR 0127 PSEG WPOINT . . . . . . . . . . . . . L WORD 0A1E PSEG WRITE . . . . . . . . . . . . . N PROC 0730 PSEG Length = 0045 WRITE0 . . . . . . . . . . . . . L NEAR 0759 PSEG WRT0 . . . . . . . . . . . . . . L NEAR 0995 PSEG WRT1 . . . . . . . . . . . . . . L NEAR 0999 PSEG WRT_SCR . . . . . . . . . . . . N PROC 0985 PSEG Length = 0020 YES . . . . . . . . . . . . . . L NEAR 07F6 PSEG @FILENAME . . . . . . . . . . . TEXT JMODEM Microsoft (R) Macro Assembler Version 5.00 9/8/88 14:51:18 JMODEM.ASM Symbols-6 1440 Source Lines 1440 Total Lines 234 Symbols 50468 + 358300 Bytes symbol space free 0 Warning Errors 0 Severe Errors