/*======================================================================* * * * Ymodem send a single file. * * * *======================================================================*/ #version $50 #address $7000 #reserve 6 #copyright "Ymsend.cmd Copyright 1995 K-Products" #include runtime.h #include bbs_pro.h #define DISK_2 2 #define MODEM 5 #define C_ACK 6 #define C_NAK 21 #define C_SOH 1 #define C_STX 2 #define C_EOT 4 #define C_CAN 24 #define C_TIMEOUT 256 #define MAX_BUFF 12288 byte sdmctl = 559; byte console = 53279; int current_block; /* block we're currently on */ int bytes_in_buffer; int buffer_idx; int packet_size; byte crc_mode; /* 0 = standard, 1 = CRC */ byte tries; /* tries at current block */ char buffer [MAX_BUFF]; main() { cr_lf(); if (parm1 [0] == 0) { echose("Parameter error!"); cr_lf(); echose("Use YMSEND filename.ext"); aborted = 1; return; } MIOsuspend(); if (open (DISK_2, parm1, 4, 0) != OK) { MIOresume(); echose("That file doesn't exist!"); aborted = 1; return; } MIOresume(); send_file(); MIOsuspend(); close (DISK_2); MIOresume(); } send_file() { int ch, crc; packet_size = 1024; bytes_in_buffer = MAX_BUFF; buffer_idx = MAX_BUFF; current_block = 1; tries = 0; MIOresume(); echos ("File "); echos (parm2); echose(" ready to send"); cr_lf(); while ( 1 ) { ++tries; if (baud < 3) /* if < 4800 baud */ printf("%cSending block %d/%d/1024 ", $9c, current_block, tries); if (tries > 10) { printf("%eToo many errors!%e"); aborted = 1; return; } ch = com_getc(50); case ( ch ) { C_TIMEOUT : { aborted = 1; return; } C_ACK : { tries = 0; ++current_block; buffer_idx = buffer_idx + packet_size; } C_NAK : if (current_block == 1) crc_mode = 0; 'C' : if (current_block == 1) crc_mode = 1; C_CAN : { printf ("%eReceiver aborted.."); aborted = 1; return; } else : { if (check_carrier() == 1) { printf("%eCarrier dropped!%e"); aborted = 1; return; } purge_modem(); } } if ( buffer_idx >= bytes_in_buffer ) { if ( bytes_in_buffer < MAX_BUFF ) { signal_EOT(); aborted = 0; return; } else { MIOsuspend(); setblock (buffer, MAX_BUFF, $1a); bytes_in_buffer = blockread (DISK_2, buffer, MAX_BUFF); if (IOresult (DISK_2) != 1 && IOresult (DISK_2) != 136) { printf("%eDisk error: %d%e", IOresult(DISK_2)); MIOresume(); aborted = 1; return; } buffer_idx = 0; MIOresume(); if ( bytes_in_buffer == 0 ) { signal_EOT(); aborted = 0; return; } } } putd ( MODEM, C_STX ); putd ( MODEM, current_block ); putd ( MODEM, current_block ^ $ff ); blockwrite ( MODEM, buffer + buffer_idx, packet_size); if ( crc_mode ) { crc = calculate_crc ( buffer + buffer_idx, packet_size ); putd ( MODEM, crc >> 8 ); putd ( MODEM, crc & $ff); } else { crc = calc_cksum ( buffer + buffer_idx, packet_size ); putd ( MODEM, crc & $ff ); } } } signal_EOT() { byte x; printf ("%cEOT..%e", $9c); for (x=0; x < 10; ++x) { putd (MODEM, C_EOT); if ( com_getc (10) == C_ACK ) break; } } purge_modem() { do { } while (com_getc(1) != C_TIMEOUT); } /*------------------------------------------------------* * return either a character from modem, * * or C_TIMEOUT if "secs" seconds expire. * *------------------------------------------------------*/ com_getc ( byte timeout ) { seconds = 0; while ( seconds <= timeout ) { if (console == 6) return ( C_CAN ); /* return fake cancel */ if (bytes_in()) return (getd (MODEM)); } return ( C_TIMEOUT ); } calc_cksum ( char *buffer; int numbytes) { #asm { .ptr: equ $a0 lda #0 sta .crc lda .buffer sta .ptr lda .buffer+1 sta .ptr+1 .loop: ldy #0 lda (.ptr),y clc adc .crc sta .crc .nxtbyte: inc .ptr bne .nv1 inc .ptr+1 .nv1: lda .numbytes sec sbc #1 sta .numbytes lda .numbytes+1 sbc #0 sta .numbytes+1 ora .numbytes bne .loop .done: lda .crc ldx #0 rts .crc: ds.b 1 } } calculate_crc ( char *buffer; int numbytes) { #asm { .ptr: equ $a0 lda #0 sta .crc sta .crc+1 lda .buffer sta .ptr lda .buffer+1 sta .ptr+1 .loop: ldy #0 lda (.ptr),y eor .crc+1 tax lda .crc_hitable,x eor .crc sta .crc+1 lda .crc_lotable,x eor #0 sta .crc .nxtbyte: inc .ptr bne .nv1 inc .ptr+1 .nv1: lda .numbytes sec sbc #1 sta .numbytes lda .numbytes+1 sbc #0 sta .numbytes+1 ora .numbytes bne .loop .done: lda .crc ldx .crc+1 rts .crc: ds.b 2 .crc_lotable: dc.b $00,$21,$42,$63,$84,$A5,$C6,$E7,$08,$29 dc.b $4A,$6B,$8C,$AD,$CE,$EF,$31,$10,$73,$52 dc.b $B5,$94,$F7,$D6,$39,$18,$7B,$5A,$BD,$9C dc.b $FF,$DE,$62,$43,$20,$01,$E6,$C7,$A4,$85 dc.b $6A,$4B,$28,$09,$EE,$CF,$AC,$8D,$53,$72 dc.b $11,$30,$D7,$F6,$95,$B4,$5B,$7A,$19,$38 dc.b $DF,$FE,$9D,$BC,$C4,$E5,$86,$A7,$40,$61 dc.b $02,$23,$CC,$ED,$8E,$AF,$48,$69,$0A,$2B dc.b $F5,$D4,$B7,$96,$71,$50,$33,$12,$FD,$DC dc.b $BF,$9E,$79,$58,$3B,$1A,$A6,$87,$E4,$C5 dc.b $22,$03,$60,$41,$AE,$8F,$EC,$CD,$2A,$0B dc.b $68,$49,$97,$B6,$D5,$F4,$13,$32,$51,$70 dc.b $9F,$BE,$DD,$FC,$1B,$3A,$59,$78,$88,$A9 dc.b $CA,$EB,$0C,$2D,$4E,$6F,$80,$A1,$C2,$E3 dc.b $04,$25,$46,$67,$B9,$98,$FB,$DA,$3D,$1C dc.b $7F,$5E,$B1,$90,$F3,$D2,$35,$14,$77,$56 dc.b $EA,$CB,$A8,$89,$6E,$4F,$2C,$0D,$E2,$C3 dc.b $A0,$81,$66,$47,$24,$05,$DB,$FA,$99,$B8 dc.b $5F,$7E,$1D,$3C,$D3,$F2,$91,$B0,$57,$76 dc.b $15,$34,$4C,$6D,$0E,$2F,$C8,$E9,$8A,$AB dc.b $44,$65,$06,$27,$C0,$E1,$82,$A3,$7D,$5C dc.b $3F,$1E,$F9,$D8,$BB,$9A,$75,$54,$37,$16 dc.b $F1,$D0,$B3,$92,$2E,$0F,$6C,$4D,$AA,$8B dc.b $E8,$C9,$26,$07,$64,$45,$A2,$83,$E0,$C1 dc.b $1F,$3E,$5D,$7C,$9B,$BA,$D9,$F8,$17,$36 dc.b $55,$74,$93,$B2,$D1,$F0 .crc_hitable: dc.b $00,$10,$20,$30,$40,$50,$60,$70,$81,$91,$A1,$B1,$C1 dc.b $D1,$E1,$F1,$12,$02,$32,$22,$52,$42,$72,$62,$93,$83 dc.b $B3,$A3,$D3,$C3,$F3,$E3,$24,$34,$04,$14,$64,$74,$44 dc.b $54,$A5,$B5,$85,$95,$E5,$F5,$C5,$D5,$36,$26,$16,$06 dc.b $76,$66,$56,$46,$B7,$A7,$97,$87,$F7,$E7,$D7,$C7,$48 dc.b $58,$68,$78,$08,$18,$28,$38,$C9,$D9,$E9,$F9,$89,$99 dc.b $A9,$B9,$5A,$4A,$7A,$6A,$1A,$0A,$3A,$2A,$DB,$CB,$FB dc.b $EB,$9B,$8B,$BB,$AB,$6C,$7C,$4C,$5C,$2C,$3C,$0C,$1C dc.b $ED,$FD,$CD,$DD,$AD,$BD,$8D,$9D,$7E,$6E,$5E,$4E,$3E dc.b $2E,$1E,$0E,$FF,$EF,$DF,$CF,$BF,$AF,$9F,$8F,$91,$81 dc.b $B1,$A1,$D1,$C1,$F1,$E1,$10,$00,$30,$20,$50,$40,$70 dc.b $60,$83,$93,$A3,$B3,$C3,$D3,$E3,$F3,$02,$12,$22,$32 dc.b $42,$52,$62,$72,$B5,$A5,$95,$85,$F5,$E5,$D5,$C5,$34 dc.b $24,$14,$04,$74,$64,$54,$44,$A7,$B7,$87,$97,$E7,$F7 dc.b $C7,$D7,$26,$36,$06,$16,$66,$76,$46,$56,$D9,$C9,$F9 dc.b $E9,$99,$89,$B9,$A9,$58,$48,$78,$68,$18,$08,$38,$28 dc.b $CB,$DB,$EB,$FB,$8B,$9B,$AB,$BB,$4A,$5A,$6A,$7A,$0A dc.b $1A,$2A,$3A,$FD,$ED,$DD,$CD,$BD,$AD,$9D,$8D,$7C,$6C dc.b $5C,$4C,$3C,$2C,$1C,$0C,$EF,$FF,$CF,$DF,$AF,$BF,$8F dc.b $9F,$6E,$7E,$4E,$5E,$2E,$3E,$0E,$1E } }