home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
8bitfiles.net/archives
/
archives.tar
/
archives
/
genie-commodore-file-library
/
TelcomTools
/
WXMODEM.PAL
(
.txt
)
< prev
next >
Wrap
Commodore BASIC
|
2019-04-13
|
23KB
|
1,002 lines
10 REM SAVE "WXMODEM.SRC",8
20 REM OPEN 2,8,2,"CRC.C800,P,W
30 [158] 700
40 ;".OPT O2
50 ; XMODEM PROTOCOL (null) 4.1
60 ; CRC AND WXMODEM ADDED 1987
70 ; BY KERMIT R. WOODALL
80 ;
90 ; COMMODORE 64
100 ;
110 ; THIS (null) REQUIRES CALLING
120 ; PROGRAM TO OPEN THE FILE AS
130 ; FILE #8 AND MODEM AS #5, THEN
140 ; CALL THE APPROPRIATE ROUTINE
150 ; AND TURN TRANSLATION ON WHEN
160 ; NEEDED. WHEN NEEDED ALL THE
170 ; MESSAGES CAN BE SUPPRESSED FOR
180 ; BBS USEAGE. OPTION TO TURN ON
190 ; DLE SCREENING ADDED SO THAT CBM
200 ; USERS CAN D/L OVER PC-PURSUIT,
210 ; THIS OPTION IS RECOMMENDED AS
220 ; A SIMPLE SOLUTION TO THE PROBLEM
230 ; OF D/LS OVER PC-PURSUIT.
240 ;
250 ;
260 ; XMODEM COPYRIGHT (C) 1985 BY
270 ; MICROTECHNIC SOLUTIONS, INC.
280 ; ALL RIGHTS RESERVED
290 ;
300 ; CRC/XMODEM AND WXMODEM ADDITIONS
310 ; COPYRIGHT (C) 1987 BY THE AUTHOR:
320 ; KERMIT R. WOODALL,2600 JORDAN CT.
330 ; GLEN ALLEN, VA 23060
340 ;
350 ;" PLINK ID: KERMIT
360 ;" QLINK ID: CURVE
370 ;
380 ; OR CALL...THE FROG POND BBS
390 ; (804) 796-6734
400 ; 24HRS
410 ;
420 ; MANY THANKS TO TOM BROWN FOR THE
430 ; FIRST CRC CALCULATION ROUTINE AND
440 ; TO SCOTT MCGINNIS (TARTAN) FOR
450 ; EXPLAINING CRC AND WXMODEM THEORY
460 ; IN A WAY EVEN I COULD UNDERSTAND.
470 ; OTHER THANKS (null) TO THE PEOPLE WHO
480 ; DEVELOPED THESE PROTOCOLS, TO THE
490 ; COMMODORE CLUB STAFF ON PLINK WHO
500 ; PROVIDED SUPPORT AND SUGGESTIONS
510 ; DURING DEVELOPMENT AND LET'S NOT
520 ; NOT FORGET ALL THE LITTLE PEOPLE
530 ; OUT THERE TOO! OH, HI MOM!
540 ;
550 ; THIS PROTOCOL MAY BE USED IN ANY
560 ; PROGRAM, TERMINALS, BBS'S OR
570 ; WHATEVER. I DO ASK THAT ANYONE
580 ; USING THIS MACHINE LANGUAGE TO
590 ; PLEASE PROVIDE ME WITH CREDIT IN
600 ; YOUR PROGRAM FOR MY M/L & A FREE
610 ; COPY OF YOUR PROGRAM (AND ANY
620 ; UPGRADES) CALL IT..."SHAREDWAREZ"
630 ; <GRIN>...I ENCOURAGE MANY PEOPLE
640 ; TO USE THIS MACHINE LANGUAGE TO
650 ; MAKE TELECOMMUNICATIONS BETTER!
660 ;
670 ; MAY BE USED IN ANY COMMERCIAL,
680 ; SHAREWARE OR PUBLIC DOMAIN PRGS!
690 ;
700 *= $C800
710 ;
720 CHKIN = $FFC6
730 CHKOUT = $FFC9
740 CHROUT = $FFD2
750 CLOSE = $FFC3
760 CLRCHN = $FFCC
770 GETIN = $FFE4
780 READSS = $FFB7
790 STOP = $FFE1
800 INTOUT = $BDCD
810 SOH = 1
820 EOT = 4
830 ACK = 6
840 DLE = 16
850 DC1 = 17 ;X-ON
860 DC3 = 19 ;X-(null)
870 NAK = 21
880 SYN = 22
890 CAN = 24
900 JIFFY = $A1
910 MOVE = $C3
920 RIDBE = $029B
930 RIDBS = $029C
940 ENABLE = $02A1
950 CALC = $1021 ;POLYNOMINAL FOR CRC
960 BLOCK = $0400 ;BUFFER ON SCREEN
970 BLN = $0400
980 BLO = $0401
990 BLCK1 = $0402
1000 BLDATA = $0403
1010 BLCH = $0483
1020 XMOBLK = BLOCK+$85 ;BUFFER2 ON SCREEN
1030 WXBUF = XMOBLK ;BUFFER FOR WXMODEM
1040 WXBPTR = $8B ;POINTER TO WX BUFFER
1050 ;
1060 ; JUMP TABLES
1070 ;
1080 JMP XMD06 ; RECIEVE XMODEM FILE
1090 JMP XMD30 ; SEND XMODEM FILE
1100 ;
1110 USECRC .BYTE 0 ;"PROTOCOL TO START WITH, DEFAULT XMODEM
1120 TR[145] .BYTE 0 ;"TRANSLATE DEFAULT OFF, 128 = ON
1130 NOMSGS .BYTE 0 ;"SUPPRESS MSGS OFF, 128 = ON
1140 DLESCN .BYTE 0 ;"USE DLE SCREENING, 128 = ON
1150 DASHPS .BYTE 64 ;"USE PLUS' IN WXMODEM 128=ON, 64=DIGITAL OUTPUT (IN ALL)
1160 RCVCHR .BYTE 0
1170 RSTAT .BYTE 0
1180 TEMPX .BYTE 0,0
1190 FXMO .BYTE 0
1200 XMOSZ .BYTE 128
1210 LSTBLK .BYTE 0
1220 PADCHR .BYTE 0
1230 ERR .BYTE 0
1240 BLKNUM .BYTE 0
1250 BLK[195] .BYTE 132 ;XMODEM BLK [195]GTH
1260 BLK[195]1 .BYTE 131 ;THE SAME BUT [171]1
1270 CHRCNT .BYTE 0
1280 CKSUM .BYTE 0
1290 CISFMT .BYTE 4,0,67,67,51
1300 EBUFX .BYTE 0
1310 TBCOUNT .W[176]D $0000 ;"DA $0000
1320 CRC .BYTE 00,00 ; CRC STORAGE
1330 POLY .BYTE 00,00
1340 TIMOUT .BYTE 1
1350 TSTCHR .BYTE 0
1360 WLOOP .BYTE 0
1370 DOMSGS .BYTE 0
1380 WHOPTCL .BYTE 0
1390 WXBLKS .BYTE 0
1400 (null)ODB .BYTE 0,0
1410 BADB .BYTE 0,0
1420 ;
1430 ; RECEIVE FILE
1440 ;
1450 XMD06 LDA #0 ;INITIALIZE EVERYBODY
1460 STA FXMO
1470 STA LSTBLK
1480 STA TBCOUNT
1490 STA TBCOUNT+1
1500 STA (null)ODB
1510 STA (null)ODB+1
1520 STA BADB
1530 STA BADB+1
1540 STA BLKNUM
1550 STA WXBLKS
1560 JSR SETUPB ;ACTUALLY SET DEFAULTS
1570 ;
1580 DOSHK JSR SHAKE
1590 LDA #128 ;NORMAL DATA BLOCK SIZE
1600 STA XMOSZ
1610 XMD06A LDA #0
1620 ;
1630 XMD06A1 =* ;INITIALIZE BLOCK VARIABLES
1640 STA ERR
1650 STA CHRCNT
1660 STA CKSUM
1670 ;
1680 XMD07 JSR GTXMDM ;(null) GET A MODEM CHARACTER
1690 JSR STOP
1700 BNE XMD07A1
1710 JMP XMD18 ; USER WANTS TO ABORT
1720 ;
1730 XMD07A1 LDA CHRCNT
1740 BNE XMD10
1750 LDA RCVCHR ;LOOK FOR END OF TRANSFER AS
1760 CMP #EOT ;FIRST BYTE OF BLOCK
1770 BNE XMD07A
1780 JMP XMD42
1790 XMD07A CMP #CAN ;CHECK FOR USER CANCEL
1800 BNE XMD09A
1810 JSR XMD19
1820 XMD09A CMP #SYN
1830 BNE CHKSOH ;DISREGARD THE SYN(S)
1840 JMP XMD06A ;FLAG THAT SYN WAS RECEIVED
1850 CHKSOH CMP #SOH
1860 BNE XMD07 ;WAIT FOR START OF BLOCK
1870 SOHOK LDA #4 ;IT IS START OF BLOCK!
1880 STA TIMOUT
1890 LDA BLKNUM ;IT IS START OF BLOCK!
1900 BNE NOMSGF ;BUT NOT FIRST BLOCK
1910 LDA WHOPTCL:CMP #$55:BEQ NOMSGF
1920 JSR OUTMSG ; OUTPUT PROTOCOL TYPE USED - ONLY ON THE FIRST BLOCK!
1930 LDA #$55:STA WHOPTCL ; FIX TO PREVENT MSG FROM APPEARING ON 256TH BLOCK!
1940 NOMSGF LDA RCVCHR
1950 ;
1960 XMD10 JSR CHKADD ;ADD THE DATA BYTE TO CHECKSUM
1970 CMP BLKLEN ;IS THIS END OF BLOCK
1980 BNE XMD07 ;NO - GET NEXT CHARACTER
1990 ;
2000 LDA BLO ;YES - CHECK BLOCK NUMBER
2010 CLC ;WITH COMPLEMENT
2020 ADC BLCK1
2030 CLC
2040 CMP #255
2050 BEQ XMD12Z ;BLOCK NUMBER IS (null)OD
2060 XMD12 JSR XMD15 ;BLOCK ERROR - SEND A NAK
2070 JMP XMD06A
2080 ;
2090 XMD12Z INC BLKNUM ;NOW CHECK TO SEE IF THIS IS
2100 ;THE BLOCK NUMBER WE EXPECTED
2110 LDA BLO
2120 CMP BLKNUM
2130 BEQ XMD11 ;YES - CHECK NEXT ITEM
2140 XMD12Z1 DEC BLKNUM ;NAK THIS SUCKER!
2150 JSR XMD15 ;NOT THE RIGHT BLOCK #
2160 JMP XMD06A ;GET THE NEXT BLOCK WE ARE ON A WAIT CYCLE
2170 ;
2180 XMD11 LDA USECRC ;TEST THE CRC
2190 CMP #NAK
2200 BEQ XMD11Z ;NOT CRC MODE
2210 JSR DOCRC
2220 JSR CHKCRC
2230 CMP #0
2240 BNE XMD12Z1 ;CRC ERROR!
2250 JMP XMD11X
2260 ;
2270 XMD11Z LDA CKSUM ;NOW SEE IF OUR CALCULATED
2280 SEC ;CHECKSUM MATCHES THE ONE
2290 SBC BLCH ;WE RECEIVED FROM THE SENDER
2300 CLC
2310 CMP BLCH
2320 BNE XMD12Z1 ;CHECKSUM ERROR - (null) NAK
2330 ;
2340 XMD11X LDA USECRC:CMP #"W":BNE XMD13
2350 JSR STOREWX ; SAVE BUFFER FOR WX
2360 LDA DASHPS:CMP #64:BEQ DODIGIT
2370 CMP #128:BEQ XMD11Y
2380 DODIGIT JSR INC(null)OD:JMP XMD11Y
2390 DOADASH LDA #0
2400 JSR OUTMSG ; OUTPUT DASHES!
2410 XMD11Y INC WXBLKS
2420 LDA WXBLKS
2430 CMP #4 ; TIME TO SAVE WXBUFFER
2440 BNE XMD13A ; NO
2450 LDA DASHPS:CMP #128:BNE XMD11W
2460 LDA #7
2470 JSR OUTMSG ; OUTPUT "+" EVERY 4TH BLOCK! (SAVES ON LONG D/LS)
2480 XMD11W LDA #0 ; YES!
2490 STA WXBLKS
2500 JSR WXACK ; SAVE & ACK IT
2510 XMD13A JMP XMD06A ; LOOP BACK
2520 ;
2530 XMD13 LDA FXMO ;STUFF INTO 2ND BUFFER IF THIS
2540 BEQ XMD40 ;IS THE FIRST BLOCK
2550 XMD14 LDY #0
2560 LDX #4
2570 XMD14D LDA XMOBLK,X ;LOOK FOR COMPUSERVE
2580 CMP CISFMT,X ;MACHINE-SPECIFIC (null)
2590 BNE XMD14B ;AND STRIP IT OUT
2600 DEX
2610 BPL XMD14D
2620 LDY #6
2630 XMD14B STY TEMPX ;WRITE THE 2ND BUFFER TO DISK
2640 ;
2650 LDX #8
2660 JSR CHKOUT
2670 XMD14A LDX TEMPX
2680 LDA XMOBLK,X
2690 BIT TRON ;TRANSLATE THE CHARACTERS IF
2700 BPL XMD14E ;THE TRANSLATE FLAG IS ON
2710 JSR CNVRT
2720 XMD14E =*
2730 XMD14E1 JSR CHROUT
2740 JSR READSS ;WATCH FOR DISK ERRORS!
2750 BNE XMDERR
2760 XMD14E2 INC TEMPX
2770 LDA XMOSZ ;IS THIS THE END OF THE
2780 CMP TEMPX ;DATA BLOCK PORTION?
2790 BNE XMD14A ;NO - KEEP WRITING TO DISK
2800 ;
2810 BIT LSTBLK ;YES - IS THIS THE LAST
2820 BPL XMD40 ;BLOCK OF THE FILE
2830 JMP XMD24 ;YES - TIME TO FINISH UP
2840 XMD40 LDX #0
2850 XMD41 LDA BLDATA,X ;MOVE 1ST BUFFER TO 2ND
2860 STA XMOBLK,X ;WE USE DOUBLE-BUFFERING FOR
2870 INX ;ON-THE-FLY PAD STRIPPING
2880 BPL XMD41 ;MOVE 128 BYTES
2890 STX FXMO
2900 JSR XMDACK ;ACK - BLOCK (null)OD!
2910 JMP XMD06A ;LOOP BACK FOR ANOTHER
2920 ;
2930 XMDERR JSR XMD18 ;OOPS - (null)T A DISK ERROR!
2940 ;
2950 XMD42 LDA #128 ;SET LAST BLOCK INDICATOR
2960 STA LSTBLK
2970 LDX #127 ;DETERMINE WHETHER OR NOT
2980 LDA XMOBLK,X ;SENDER USED CTRL-Z OR NULL
2990 STA PADCHR ;AS A PAD CHARACTER
3000 CMP #26
3010 BEQ XMD42A ;HE USED CTRL-Z
3020 CMP #0
3030 BEQ XMD42A ;HE USED NULL
3040 JMP XMD42C
3050 XMD42A LDA XMOBLK,X ;NOW BACK UP INTO THE LAST
3060 CMP PADCHR ;BLOCK UNTIL WE FIND THE
3070 BNE XMD42C ;FINAL REAL DATA BYTE
3080 DEX
3090 BPL XMD42A
3100 JMP XMD24
3110 XMD42C INX ;SET BLOCK SIZE TO MATCH
3120 STX XMOSZ ;END OF LAST BLOCK
3130 JMP XMD14
3140 ;
3150 CNVRT AND #127 ;CONVERT ASCII-PETASCII
3160 CMP #65
3170 BCC XMD14L
3180 CMP #91
3190 BCS XMD14L
3200 ORA #32
3210 JMP XMD14L
3220 XMD14K CMP #97
3230 BCC XMD14L
3240 CMP #123
3250 BCS XMD14L
3260 AND #223
3270 XMD14L RTS
3280 ;
3290 ; GET XMODEM CHAR
3300 ;
3310 GTXMDM JSR SETJIF ;SET CHARACTER TIMEOUT
3320 GTX01 JSR STOP ;CHECK TO SEE IF USER IS
3330 BEQ GTXEX ;PRESSING STOP KEY TO ABORT
3340 JSR GIM ;GET CHARACTER FROM MODEM
3350 BNE GTX02 ;WAS THERE A CHARACTER
3360 LDA DLESCN:CMP #128:BEQ DOADLE ; DLE MASKING IN EFFECT ANYWAY!
3370 LDA USECRC:CMP #"W":BNE OK25 ;SKIP IF NOT WXMODEM OR DLE MASKING
3380 DOADLE LDA RCVCHR
3390 CMP #DLE ;IS THIS A DLE CHARACTER
3400 BNE CHKDCS ;NO - SEE IF IT WAS AN X-ON OR X-(null)
3410 JSR GTXMDM ;YES - XLATE IT!
3420 LDA RCVCHR
3430 EOR #64 ;MASK W/64 TO RETURN IT TO NORMAL
3440 STA RCVCHR ;SAVE IT
3450 RTS
3460 ;
3470 CHKDCS CMP #DC1:BEQ GTXMDM
3480 CMP #DC3:BEQ GTXMDM ; BE SURE IT WAS NOT X-ON OR X-(null)
3490 OK25 RTS ;YES - RETURN
3500 GTX02 JSR TSTJIF ;NO - DID WE TIME OUT YET
3510 BCC GTX01 ;NO - (null) TRY AGAIN
3520 ;
3530 LDA USECRC:CMP #"W":BNE (null)SHK0 ; WXMODEM ROUTINE FOR END OF TRANSMISSION
3540 LDA #CAN:JSR PTXMDM:LDA #CAN:JSR PTXMDM
3550 JSR WXACK ; SIGNALLED BY 11 SECOND TIMEOUT...(LOSS OF DATA NOT DETECTED!)
3560 LDA #CAN:JSR PTXMDM:LDA #CAN:JSR PTXMDM ; 2 CONTROL-X'S TELL PLINK TO END
3570 PLA:PLA
3580 JMP XMD24A ; NOW, CLOSE UP EVERYTHING AND PRINT FINAL MESSAGE!
3590 ;
3600 (null)SHK0 PLA
3610 PLA
3620 (null)SHK JMP DOSHK ;RETURN
3630 GTXEX JMP XMD18 ;USER WANTS TO ABORT
3640 ;
3650 ; CHECK CAN,NAK APPROPRIATE
3660 ;
3670 XMD15 INC ERR ;CANCEL IF 10 ERRORS IN A ROW
3680 LDA #10 ;OTHERWISE JUST NAK
3690 CMP ERR
3700 BEQ XMD18
3710 ;
3720 ; NAK HANDLING
3730 ;
3740 XMD16 LDA DASHPS:CMP #64:BNE XMD16A
3750 JSR INCBAD
3760 JMP XMD16B
3770 XMD16A LDA #1
3780 JSR OUTMSG
3790 XMD16B LDA USECRC:CMP #"W":BNE XMD16N
3800 JSR WXNAK
3810 RTS
3820 ;
3830 XMD16N LDA #NAK
3840 JSR PTXMDM
3850 XMD16R RTS
3860 ;
3870 INCBAD INC BADB:BNE IBAD1
3880 INC BADB+1
3890 IBAD1 JSR INTPRNT
3900 RTS
3910 ;
3920 ; ACK HANDLING
3930 ;
3940 XMDACK LDA DASHPS:CMP #64:BNE XMDACK2
3950 JSR INC(null)OD
3960 JMP XMDACK3
3970 XMDACK2 LDA #1
3980 JSR OUTMSG
3990 ;
4000 XMDACK3 LDA #ACK
4010 JSR PTXMDM
4020 XMDACKR RTS
4030 ;
4040 INC(null)OD INC (null)ODB:BNE I(null)OD1
4050 INC (null)ODB+1
4060 I(null)OD1 JSR INTPRNT
4070 RTS
4080 ;
4090 ; EOT
4100 ;
4110 XMD17 LDA #EOT
4120 JSR PTXMDM
4130 RTS
4140 ;
4150 ; CAN
4160 ;
4170 XMD18 LDA #CAN ;CANCEL THE TRANSFER
4180 JSR PTXMDM
4190 XMD19 LDA #4 ;DISPLAY MESSAGE TO USER
4200 JSR XMD25
4210 JSR WAITTWO
4220 PLA ;JUMP ALL THE WAY BACK TO
4230 PLA ;THE BASIC PROGRAM
4240 RTS
4250 ;
4260 ; ACK/NAK SEQUENCE FOR WXMODEM
4270 ;
4280 DOSEQ =* ; SEND WXMODEM SEQUENCE
4290 AND #%00000011
4300 JSR PTXMDM ;SEND THE SEQUENCE TOO
4310 SEQDONE RTS
4320 ;
4330 ; EOT HANDLING
4340 ;
4350 XMD24 LDA #ACK:JSR PTXMDM ;ACKNOWLEDGE RECEIPT OF EOT
4360 LDA USECRC:CMP #"W":BNE XMD24A ;SKIP NEXT CODE IF NOT WXMODEM
4370 LOOPEOT JSR GTXMDM:CMP #EOT:BNE LOOPEOT ; WAIT FOR SECOND EOT
4380 LDA #ACK:JSR PTXMDM ; ACK THE SECOND EOT
4390 JSR DUMPWX ; DUMP ANYTHING STILL IN BUFFER
4400 XMD24A LDA #3 ;DISPLAY COMPLETED MESSAGE
4410 XMD25 JSR OUTMSG
4420 LDA #8 ;CLOSE THE FILE AND (null) HOME
4430 JMP CLOSE
4440 ;
4450 ; SEND FILE
4460 ;
4470 XMD30 JSR STOP ;CHECK IS USING IS PRESSING
4480 BNE XMD30A ;STOP KEY
4490 JSR XMD19 ;YES - ABORT TRANSFER
4500 XMD30A LDA RIDBS ;CLEAR INPUT BUFFER
4510 STA RIDBE
4520 LDA #0 ;INITIALIZE VARIABLES
4530 STA TBCOUNT
4540 STA TBCOUNT+1
4550 STA (null)ODB
4560 STA (null)ODB+1
4570 STA BADB
4580 STA BADB+1
4590 LDA #SOH
4600 STA BLN
4610 STA BLO
4620 EOR #255
4630 STA BLCK1
4640 XMD30B JSR STOP ;CHECK STOP KEY
4650 BNE XMD30C
4660 JSR XMD17
4670 JSR XMD19
4680 XMD30C JSR GIM ;GET MODEM CHARACTER
4690 BNE XMD30B ;NO CHARACTER - LOOP
4700 XMD30C1 LDA RCVCHR
4710 CMP #CAN ;IS RECEIVER CANCELLING
4720 BNE XMD30D ;NO
4730 JSR XMD19 ;YES - TIME TO QUIT
4740 XMD30D CMP #"C" ;CHECK FOR CRC
4750 BEQ XMD30E
4760 XMD30D1 CMP #NAK ;WAS TRANSMISSION BAD
4770 BNE XMD30B ;NO
4780 ;
4790 XMD30E STA USECRC
4800 JSR SETUPB
4810 LDA WHOPTCL
4820 JSR OUTMSG
4830 ;
4840 XMD31 LDA #3 ;RETRANSMIT LAST BLOCK
4850 STA CHRCNT ;INITIALIZE BLOCK VARIABLES
4860 LDX #0
4870 STX CKSUM
4880 STX RSTAT
4890 XMD32 JSR STOP ;CHECK STOP KEY
4900 BNE XMD32A
4910 JMP XMD37X
4920 XMD32A LDX #8 ;GET CHARACTER FROM DISK
4930 JSR CHKIN
4940 JSR GETIN
4950 BIT TRON ;CHECK FOR TRANSLATE ON
4960 BPL XMD32B ;NO - BYPASS CON(null)
4970 JSR CNVRT ;YES - CONVERT TO ASCII
4980 XMD32B STA RCVCHR ;STORE THE CHARACTER
4990 JSR READSS ;WATCH DEM DISK ERRORS!
5000 AND #195 ;LOOK FOR END-OF-FILE
5010 STA RSTAT ;AND TIME-OUTS
5020 BNE XMD33A
5030 LDA RCVCHR ;CALCULATE CHECKSUM WITH
5040 JSR CHKADD ;THIS CHARACTER
5050 CMP #131 ;(null)T A FULL BLOCK YET
5060 BNE XMD32 ;NO - LOOP
5070 BEQ XMD34 ;YES - PROCESS END OF BLOCK
5080 XMD33A = *
5090 LDA RCVCHR ;CALCULATE CHECKSUM WITH
5100 JSR CHKADD ;THIS CHARACTER
5110 CMP BLKLEN1 ;IS THE BLOCK FULL
5120 BEQ XMD34 ;YES - BYPADD PADDING
5130 LDA #26 ;PAD THE FINAL BLOCK WITH
5140 STA PADCHR ;CTRL-Z UNLESS THE LAST
5150 LDA RCVCHR ;DATA CHARACTER HAPPENS TO
5160 CMP #26 ;BE A CTRL-Z
5170 BNE XMD33G ;IF IT IS THEN USE NULL
5180 LDA #0
5190 STA PADCHR
5200 XMD33G LDA PADCHR ;PAD OUT THE BLOCK UNTIL
5210 STA RCVCHR ;WE FILL IT UP
5220 XMD38A JSR CHKADD
5230 CMP BLKLEN1
5240 BNE XMD38A
5250 ;
5260 XMD34 LDA USECRC ;FILL IN THE CALCULATED
5270 CMP #NAK:BEQ DOASUM
5280 JSR DOCRC ; COMPUTE THE CRC
5290 JSR STOCRC ; ADD IT ONTO THE DATA PACKET
5300 JMP SKIPSUM ; BYPASS THE SUM
5310 ;
5320 DOASUM LDA CKSUM:STA BLCH ;CHECKSUM
5330 SKIPSUM LDA #0
5340 STA TEMPX
5350 ;
5360 XMD35 JSR STOP ;CHECK THE OLD STOP KEY
5370 BEQ XMD37X
5380 XMD35A LDX TEMPX ;NOW LET US OUTPUT THE
5390 LDA BLOCK,X ;ENTIRE BLOCK TO THE MODEM
5400 JSR PTXMDM
5410 XMD35B INC TEMPX ;DID WE FINISH THE BLOCK YET
5420 LDA BLKLEN
5430 CMP TEMPX
5440 BNE XMD35
5450 ;
5460 ;
5470 JSR SETJIF ;SET THE TIMEOUT
5480 XMD36 =*
5490 XMD36A JSR GIM ;LOOK FOR THE RECEIVER RESPONSE
5500 BEQ XMD37
5510 JSR STOP ;NO RESPONSE YET - LOOK FOR THE
5520 BEQ XMD37X ;STOP KEY
5530 JSR TSTJIF ;AND CHECK FOR A TIMEOUT
5540 BCC XMD36 ;LOOP IF NOT TIMED OUT YET
5550 BCS XMD34 ;OTHERWISE RETRANSMIT
5560 XMD37 LDA RCVCHR
5570 CMP #NAK ;DID HE SEND A NAK
5580 BNE XMD37E
5590 LDA DASHPS:CMP #64:BNE XMD37E1
5600 JSR INCBAD
5610 JMP XMD34
5620 XMD37E1 LDA #1 ;UPDATE THE DISPLAY
5630 JSR OUTMSG ;(null) BACK TO RETRANSMIT
5640 JMP XMD34
5650 XMD37E CMP #CAN ;DID HE SEND CANCEL
5660 BNE XMD37A
5670 XMD37X JSR XMD19 ;YES - THEN ABORT
5680 XMD37A CMP #ACK ;DID HE SEND ACK
5690 BNE XMD36 ;NONE OF THE ABOVE
5700 LDA DASHPS:CMP #64:BNE XMD37A1
5710 JSR INC(null)OD
5720 JMP XMD37A2
5730 XMD37A1 LDA #0
5740 JSR OUTMSG
5750 XMD37A2 LDA RSTAT ;CHECK FOR STATUS NOT ZERO
5760 BEQ XMD38 ;NO
5770 JSR XMD17 ;YES - SEND EOT
5780 JSR SETJIF ;SET TIMEOUT
5790 XMD37B LDA JIFFY ;CHECK THE TIMEOUT AND LOOK
5800 BMI XMD37C ;FOR FINAL RESPONSE FROM
5810 JSR GIM ;THE RECEIVER
5820 BNE XMD37B
5830 XMD37C LDA RSTAT ;CHECK FOR END OF FILE
5840 AND #64
5850 BEQ XMD37X ;NO - ABORT
5860 JMP XMD24A ;YES - DISPLAY COMPLETE
5870 XMD38 INC BLO ;INCREMENT THE BLOCK NUMBER
5880 LDA #255
5890 EOR BLO
5900 STA BLCK1
5910 JMP XMD31 ;BACK FOR NEXT BLOCK
5920 ;
5930 ; GET XMODEM CHAR
5940 ;
5950 GIM LDX #5
5960 JSR CHKIN
5970 JSR GETIN
5980 STA RCVCHR
5990 JSR READSS
6000 RTS
6010 ;
6020 ; TEST JIFFY
6030 ;
6040 TSTJIF LDA JIFFY
6050 CMP TIMOUT
6060 RTS
6070 ;
6080 ; SET JIFFY
6090 ;
6100 SETJIF LDA #0
6110 STA JIFFY
6120 STA JIFFY+1
6130 RTS
6140 ;
6150 ; PUT CHAR TO MODEM
6160 ;
6170 PTXMDM PHA
6180 LDX #5
6190 JSR CHKOUT
6200 PTX01 LDA ENABLE
6210 AND #3
6220 BNE PTX01
6230 PLA:TAY
6240 ;
6250 LDA DLESCN:CMP #128:BNE NODLE1 ; ONLY DO IF DLE MASKING IN EFFECT
6260 TYA
6270 CMP #DLE:BEQ DODLE2
6280 CMP #SYN:BEQ DODLE2
6290 CMP #DC1:BEQ DODLE2
6300 CMP #DC3:BEQ DODLE2
6310 ;
6320 JMP NODLE1
6330 ;
6340 DODLE2 EOR #64:TAY
6350 LDA #DLE
6360 JSR CHROUT
6370 ;
6380 NODLE1 TYA
6390 JSR CHROUT
6400 RTS
6410 ;
6420 ; CALCULATE CHECKSUM
6430 ;
6440 CHKADD LDA RCVCHR
6450 LDX CHRCNT
6460 STA BLOCK,X
6470 TAY
6480 LDA USECRC
6490 CMP #NAK
6500 BNE CHKADD1
6510 TYA
6520 CLC ;DONT DO THIS IF NOT XMODEM
6530 ADC CKSUM
6540 STA CKSUM
6550 CHKADD1 INC CHRCNT ;JUMP TO HERE
6560 INX
6570 TXA
6580 RTS
6590 ;
6600 ; OUTMSG PROMPT POINTER TABLE
6610 ;
6620 PRMTBL = *
6630 .WORD PROMPT4 ; 0
6640 .WORD PRMPT13 ; 1
6650 .WORD DISPR8 ; 2
6660 .WORD DISPR9 ; 3
6670 .WORD DISPR10 ; 4
6680 .WORD DISPR11 ; 5
6690 .WORD DISPR13 ; 6
6700 .WORD PRMPT14 ; 7
6710 .WORD INTOUT1 ; 8
6720 .WORD INTOUT2 ; 9
6730 .WORD INTOUT3 ; 10
6740 ;
6750 ; PROMPTS
6760 ;
6770 PROMPT4 .ASC "-"
6780 .BYTE 0
6790 PRMPT14 .ASC "+"
6800 .BYTE 0
6810 PRMPT13 .ASC ":"
6820 .BYTE 0
6830 DISPR8 .ASC "WXMODEM PROTOCOL "
6840 .BYTE 13,0
6850 DISPR9 .ASC "TRANSFER COMPLETE "
6860 .BYTE 13,0
6870 DISPR10 .ASC "TRANSFER ABORTED "
6880 .BYTE 13,0
6890 DISPR11 .ASC "XMODEM PROTOCOL "
6900 .BYTE 13,0
6910 DISPR13 .ASC "CRC PROTOCOL "
6920 .BYTE 13,0
6930 INTOUT1 .ASC "BLOCKS "
6940 .BYTE 0
6950 INTOUT2 .ASC " ERRORS "
6960 .BYTE 0
6970 INTOUT3 .ASC " [145]"
6980 .BYTE 13,0
6990 ;
7000 ; OUTPUT MESSAGE TO DEVICE
7010 ;
7020 OUTMSG PHA
7030 LDA NOMSGS
7040 BEQ DOMSG
7050 PLA
7060 RTS ; SUPPRESS MSGS, JUST RETURN
7070 ;
7080 DOMSG LDX #3
7090 JSR CHKOUT
7100 PLA
7110 OUTMSG1 ASL A ;START HERE IF NOT SCREEN
7120 TAX
7130 LDA PRMTBL,X
7140 STA MOVE
7150 INX
7160 LDA PRMTBL,X
7170 STA MOVE+1
7180 LDY #0
7190 OUTLP1 LDA (MOVE),Y
7200 CMP #0
7210 BEQ OUTEND
7220 OUTLP2 JSR CHROUT
7230 OUTLP6 INY
7240 CPY #0
7250 BNE OUTLP1
7260 OUTEND RTS
7270 ;
7280 ; WAIT TWO SECONDS
7290 ;
7300 WAITTWO JSR SETJIF
7310 WAIT2 BIT JIFFY+1
7320 BPL WAIT2
7330 RTS
7340 ;
7350 ;
7360 ; CRC PROTOCOL CALCULATION
7370 ; FOR COMMODORE COMPUTERS
7380 ; BY TOM BROWN
7390 ; REWRITTEN BY KERMIT WOODALL
7400 ;
7410 ; THE POLYNOMIAL $1021 IS FOR THE
7420 ; CALCULATION 2^16 + 2^12 + 2^5 + 1
7430 ; THE NUMBER IS (null)TTEN BY USING A
7440 ; 1 IN EACH BIT CORRESPONDING TO
7450 ; THE POLYNOMIAL.
7460 ;"EG: $1021 HAS A 1 IN BIT 0,5 & 12
7470 ;
7480 ;
7490 ; FIRST, WE HAVE [164] ERASE THE OLD
7500 ; CRC [197]UE [175] INITIALIZE THE
7510 ; POLYNOMIAL WE WILL USE [129] THE
7520 ; CALCULATI[145]. [168]E THAT THE POLY
7530 ; VARIABLE CAN BE CHANGED IN [145]E
7540 ; PLACE [164] BE USED BY THE WHOLE
7550 ; ROUTINE.
7560 ; A CALLING ROUTINE WILL CALL THIS
7570 ; [145]LY [145]CE. SUBSEQUENT CALLS WILL
7580 ; BE [164] CRCALC.
7590 ;
7600 ;
7610 ;
7620 INITCRC LDA #0
7630 STA CRC ;CRC CALCULATI[145]
7640 STA CRC[170]1
7650 LDA #[177]CALC
7660 STA POLY ;POLYNOMIAL
7670 LDA #[179]CALC
7680 STA POLY[170]1
7690 RTS
7700 ;
7710 ; THIS ROUTINE WILL CALCULATE THE
7720 ; CRC CHECKSUM WITH THE BYTE
7730 ; IN THE ACCUMULA[164]R.
7740 ;
7750 ;
7760 CRCALC LDX #8 ;COUNT 8 BITS
7770 ;
7780 ; FIRST, WE X[176] BIT 7 OF [131] WITH
7790 ; BIT 15 OF CRC (BIT 15 OF HIGHBYTE)
7800 ;
7810 E[176] CRC ;HIGH BYTE
7820 STA CRC
7830 ;
7840 ; NOW WE SH[139]T CRC (HI & LOW BYTES)
7850 ; LEFT [145]E BIT. THE ASL PUTS A 0 [181]O
7860 ; BIT 0 OF CRC LOW,SH[139]TS CRC LOW BYTE
7870 ; LEFT [145]E BIT, BIT 7 FALLING [181]O THE
7880 ; CARRY. THE ROL SH[139]TS THE CRC HIGH
7890 ; BYTE LEFT 1 BIT, THE CARRY IS MOVED
7900 ; [181]O BIT 0 OF CRC HIGH BYTE, [175] BIT
7910 ; 7 FALLS [181]O THE NOW[171]EMPTY CARRY
7920 ;
7930 LOOPC [178][172]
7940 ASL CRC[170]1 ;SH[139]T LOW BYTE
7950 ROL CRC ;NOW HIGH
7960 BCC CRCALC1
7970 ;
7980 ; BIT 15 (BIT 7 OF HIGH CRC BYTE) OF
7990 ; CRC WAS SH[139]TED [181]O THE CARRY.
8000 ; [139] THIS BIT WAS 1 [167] EXCLUSIVE[171][176]
8010 ; THE CRC WITH THE POLYNOMIAL
8020 ;
8030 LDA POLY ;POLYNOMIAL LOW
8040 E[176] CRC ;CRC LOW BYTE
8050 STA CRC
8060 LDA POLY[170]1 ;POLYNOMIAL HIGH
8070 E[176] CRC[170]1
8080 STA CRC[170]1
8090 ;
8100 ; NOW WE SH[139]T THE [131] BYTE LEFT 1 BIT
8110 ; [175] DEC[143]ENT OUR BIT COUNTER
8120 ; AS L[145]G AS IT'S [168] ZERO, WE [154]INUE
8130 ; OUR BITWISE CALCULATI[145]
8140 ;
8150 CRCALC1 [178][172]
8160 DEX ;DEC BIT COUNT
8170 BNE LOOPC
8180 RTS ;WHEW! D[145]E.
8190 ;
8200 ; (SHAKE) H[175]SHAKING ROUTINE
8210 ;
8220 SHAKE LDA BLKNUM
8230 BEQ W[154]1
8240 JMP XMD16
8250 W[154]1 LDA USECRC
8260 JSR PTXMDM
8270 INC WLOOP
8280 LDA WLOOP
8290 CMP #3
8300 BNE W[154]
8310 ;
8320 LDA #$00:STA WLOOP
8330 LDA USECRC
8340 CMP #"W"
8350 BNE MUSTBC
8360 LDA #6:STA WHOPTCL
8370 LDA #"C"
8380 STA USECRC
8390 LDA #1:STA TIMOUT
8400 RTS
8410 MUSTBC CMP #"C"
8420 BNE W[154]
8430 LDA #5:STA WHOPTCL
8440 LDA #NAK
8450 STA USECRC
8460 LDA #3:STA TIMOUT
8470 LDA #132:STA BLK[195]
8480 LDA #131:STA BLK[195]1
8490 ;
8500 W[154] RTS
8510 ;
8520 ; CALCULATE CRC [129] 128 BYTE BLOCK
8530 ; [129] TRANSMISSI[145] [176] RECEIVING
8540 ;
8550 DOCRC JSR INITCRC
8560 LDX #0
8570 DOCRC1 [178] [172]
8580 LDA BL[131],X:STX WLOOP
8590 JSR CRCALC
8600 LDX WLOOP:INX
8610 CPX #128
8620 BNE DOCRC1 ;CRC [129] 128 BYTES
8630 RTS
8640 ;
8650 ; CHECK THE CRC AGAINST THE TWO
8660 ; BYTES AT THE [128] OF THE [131]
8670 ; PACKET RECEIVED
8680 ;
8690 CHKCRC LDA CRC[170]1
8700 CMP BLCH[170]1 ;COMPARE LO [164] LO
8710 BNE CHKBAD
8720 LDA CRC
8730 CMP BLCH ;COMPARE HI [164] HI
8740 BNE CHKBAD
8750 ;
8760 LDA #0
8770 RTS
8780 ;
8790 CHKBAD LDA #1
8800 RTS
8810 ;
8820 ; TAKE COMPUTED CRC [175] S[164]RE [164]
8830 ; THE [128] OF THE [131] PACKET TO
8840 ; BE SENT OUT
8850 ;
8860 S[164]CRC LDA CRC
8870 STA BLCH
8880 LDA CRC[170]1
8890 STA BLCH[170]1
8900 RTS
8910 ;
8920 ;
8930 SETUPB JSR SETBUF ; SETUP ALL BASIC STUFF PER PRO[164]COL USED
8940 LDA #$00:STA WLOOP
8950 LDA #133:STA BLK[195]
8960 LDA #132:STA BLK[195]1
8970 LDA #1:STA TIMOUT
8980 LDA USECRC
8990 CMP #"W":BNE ISC
9000 LDA #2:STA WHOPTCL ;WXMODEM
9010 RTS
9020 ISC CMP #"C":BNE ISNAK
9030 LDA #6:STA WHOPTCL ;CRC
9040 RTS
9050 ISNAK LDA #5:STA WHOPTCL
9060 LDA #132:STA BLK[195]
9070 LDA #131:STA BLK[195]1 ;PLAIN XMODEM
9080 RTS
9090 ;
9100 SETBUF [178][172] ; SET WXBPTR [164] [197]UE OF WXBUF
9110 LDA #[179]WXBUF
9120 STA WXBPTR
9130 LDA #[177]WXBUF
9140 STA WXBPTR[170]1
9150 RTS
9160 ;
9170 INCBUF [178][172] ; ADD [145]E [164] WXBPTR
9180 INC WXBPTR
9190 BNE INCD[145]E
9200 INC WXBPTR[170]1
9210 INCD[145]E RTS
9220 ;
9230 DUMPWX LDA WXBPTR ; S[128] WX BUFFER [164] DISK
9240 CMP #[179]WXBUF
9250 BNE DWX1 ; IS THERE ANYTHING IN
9260 LDA WXBPTR[170]1 ; THE WXMODEM BUFFER
9270 CMP #[177]WXBUF
9280 BNE DWX1
9290 RTS ; [168]HING IN BUFFER!
9300 ;
9310 DWX1 LDA WXBPTR
9320 STA TEMPX
9330 LDA WXBPTR[170]1
9340 STA TEMPX[170]1
9350 LDX #8
9360 JSR CHKOUT
9370 JSR SETBUF
9380 DMPLOOP LDY #0
9390 LDA (WXBPTR),Y
9400 JSR CHROUT
9410 JSR INCBUF
9420 LDA WXBPTR
9430 CMP TEMPX
9440 BNE DMPLOOP
9450 LDA WXBPTR[170]1
9460 CMP TEMPX[170]1
9470 BNE DMPLOOP ;LOOP BACK [139] NEITHER LO [176] HI [178] [128]ING
9480 JSR SETBUF ; [222] [129] [130] 4 BLKS
9490 RTS
9500 ;
9510 S[164]REWX LDY #$00 ; S[164]RE CURRENT BYTE IN WXMODEM BUFFER
9520 SWX1 LDA BL[131],Y
9530 BIT TR[145]
9540 BPL SWX2
9550 JSR CNVRT
9560 SWX2 LDX #0:STA (WXBPTR),X
9570 JSR INCBUF
9580 INY
9590 CPY #128
9600 BNE SWX1 ; S[164]RE ALL 128 BYTES!
9610 RTS
9620 ;
9630 WXNAK JSR SETBUF ; [148] WXBUFFER [164] DISK [167] NAK
9640 LDA #1:STA TIMOUT ; [161] ANYTHING LEFT IN INCOMING RS232 AREA
9650 JSR SETJ[139]
9660 NX1 JSR GIM
9670 BEQ NX1 ; [203]T A BYTE, [161] M[176]E!
9680 JSR TSTJ[139]
9690 BCC NX1 ; NO TIMEOUT, TRY AGAIN
9700 LDA #4:STA TIMOUT
9710 LDA BLKNUM
9720 SEC:SBC WXBLKS
9730 STA BLKNUM ; SET BLKNUMBER BACK [164] FIRST BLOCK OF THE FOUR
9740 LDA #NAK:JSR PTXMDM
9750 LDA #1:JSR DOSEQ ; NOW, S[128] NAK[173]SEQUENCE
9760 RTS
9770 ;
9780 WXACK JSR DUMPWX
9790 LDA #ACK:JSR PTXMDM
9800 LDA #0:JSR DOSEQ ; ACK LAST BLOCK RECIEVED!
9810 LDA #ACK:JSR PTXMDM
9820 LDA #2:JSR DOSEQ ; ACK LAST BLOCK RECIEVED!
9830 LDA #ACK:JSR PTXMDM
9840 LDA #2:JSR DOSEQ ; ACK LAST BLOCK RECIEVED!
9850 LDA #ACK:JSR PTXMDM
9860 LDA #0:JSR DOSEQ ; ACK LAST BLOCK RECIEVED!
9870 RTS
9880 ;
9890 [181]PRNT LDA #8
9900 JSR OUTMSG ; OUTPUT "BLOCKS "
9910 LDX #3:STX $9A:LDX [203]ODB
9920 LDA [203]ODB[170]1
9930 JSR [181]OUT
9940 LDA #9
9950 JSR OUTMSG ; OUTPUT "ERRORS "
9960 LDX BADB
9970 LDA BADB[170]1
9980 JSR [181]OUT
9990 LDA #10
10000 JSR OUTMSG
10010 RTS ; WE HAVE SENT DIGITAL MSGS!