' JJJJ ?\>' L-=l>  ԠéԠˠ#~?  xDIR ERA TYPESAVEREN USER!!yO#< Ty#O 3ǯ21y_͸2y2ͽ:ķ˜1͘A͌>>͌92^ :˷¥.!_~#fow]ɭʎʥ!v"!çREAD ERRORçNO FILE^:˷#͘*~ "Ʒ"͌#>?͌͘ =_.:;<> Oƅo$>!Y2*O"ʉ@G:ʐ:wÖx2p0ʹ#*©6?ëw˜0ï#6 ¹.0#*6?w0#6 #6"  Ň!˶2:2a{_:˷ʖ:˷>Ľʖ:=2–!B!6#5ʖ:˷Ľ!ͬʧ )!F#xʺ~0wëw!" !~6ͽ:ý(!\X COPYRIGHT (C) 1979, DIGITAL RESEARCH _͌> ͒> Ò> Ò͘~#͌ì _2<į2: :):>:(y2E!|"*wɍ`JX)^>EE??++ ԩ  [\ ǭ ?  JL ``LLL $Lq<`ΧԠĠڸčԠԠ͠Ԡ؍2>o:= gw8H<8H=` }Hx / hJ Leh<> > @A @A>i =<>+ LeÍڍh@(L>*// -П( ( $8` %  ZNx`. }x$50x.$50xL JJJJ`Hjf5 }h $50x`  Ȍ` Hx  -(hL(h8֩`Lx (`H݌hHhHh݌>?F؅G(jf5(  ;  R( FGj 0x j $xxH` ( Rh RL.xxH h  !"#$%&'()*+,-./0123456789:;<=>?x&& 8 , P ; ' / \ ; & ; x)*++`FGG8`0($ p,&" cI꽌ɪVɭ&Y & &Y &   꽌ɪ\8`&&꽌ɪɖ'*&%&,E'зЮ꽌ɪФ`V0 ^ *^ *>`+*xS&x'8*3IxiU ,>J>V J>V `8'x0| &HhHh V Y V '&Y V x ꪽV ' `Hh` ! ~ 3#0 Wx x ƀ Ƃ G ~ # 3x~#B!Y~ɯ2:˷=!˾ý:˷=!˾:ý^T!~  6?#ˆ:`O> K{͘A͒>:͒͢>:͒͢xK > K > ͒x  ͢ØÆ^ BRͧ9!5‚#~Y‚#"T<ÆALL (Y/N)?^ Tʧ͘!6!~ڇ ɯw4!Y~ʆ͌†t=ʆf ^ T ɯ2o&)|+!<ͧЯ2*C!!~~#~O~G#n,-.‹! w! yG!x͢.:E<ʄ! q!pQ:E<. ʄ$.:E<ʄi6}2ExN! ~态O>G~G!~G} *C!r#r#r ^ͥ_y#x#{2>2T*CGͻ:ẅ́n>2;O ^DM;}H>"*C :ٷ:ddslO s#r:EϷ͊:==»y==»*Ww#*"͸*:G#š"͸:!پw4!iw:Z!E~=26 w ~>2!E5T*C!"C"C!w# F! w͌xѯ2͢*C ~<wʃG:٠!٦ʎì 4~ʶ¬:<ʶ$ʶïZͻЯx>2>2ͻ:!پZկ2:EϷẅ́͊Ͳ> *C ^OT *C~wD -'  -@ͦ~^*C Ox! N!Fwyxʋ>ڋ>*Cw~#+w#w+ɯ2E22i^ *C :ٷ~w~͔͔# # ::/GyO>2!q*C"͡ʔ*JҔ^:Oyʃ?|x | sӖ-|N-# S:2E!~Яw>T D^6k-äPYy 5*{zBK5:AϾ#~$=2Ek͌ ):BO!yoxg*:BO}!N#F "*#*s#r^ ~!J! J*:مo$*C~i6iw**{#zr+s{ozg**͕** Ѿ,w͜͸Ͳ!!N#F$**O!~#O: \зSЀ*C :ٷqn& ^#V>O^"*}:*)=":O:١o"*C *C!ͮ~2~2ͦ:٦2ͮ:ЯO:فw:w |g}o*ٯ# 2E>! ^#V w#P:BO|^#V#"##"##"##"!O*!O*|!6ʝ6>گ*w#w*w#w'û*ڷ! J*""!N#F*^#V*~#foyx*{_zW+*x: 2 p&x~+é7ͯ2 H! >w_: ! Ͼ5ͤNkͱ¦ͱxʊ#Nx: Ϸ! ϖ2 ͤ! 5™#wO~x½p Hy<< ڷʑ :!qMD# O͐  :ϷE B 2>: Ϸb# : Ϸy! 4 5~yy5 6yҐ^H@Oy H H: –ͬ  #H: ! Ͼ Hù H H $O͐: 2 *CN# ʽ!̙̥̫̱"C{2!"E9"1Aϯ22!ty)K!G_^#V*Cΐ~؃E؜إث ,&-AGMSϛ!!ô!ô!Bdos Err On : $Bad Sector$Select$File R/O$:BA2!~6=qf^!~2>`~2˯2\!!B!~> >#0~O#Cx2͘1)ͽÂf zͧÆBAD LOADCOMf^: !˶ Â$$$ SUBÆNO SPACE^ :Ty!B*O=?_s#"^sG!~Yʸpsp2mÆÆf ͧÆFILE EXISTS _: É: :˷ʉ=2)ͽÉ T!@k!}|qs+p+q-*C ͥ!!q#p#w*:BOYG}*MD "ã:!BϾw!>2*C~=2u:B2~2wE:A*C϶w>"!""ٯ2B!"!rQQQâ~?ͦ~?rQ*"CQ-Q͜QüQrQ$Q*):B"*)*)Q;*"E:;:A2AQÓQÜQ*C}/_|/*٤W}_*"}o|g":ٷʑ*C6:ٷʑw:2E**E}DQ>2C0T"I !>"H>2J: !͢:d::d!s~B#1!P!J߇o~,foɷp:BB Apple ][ CP/M 56K Ver. 2.20 (C) 1980 Microsoft ;ۯ2>EE??++B#1!P!J߇o~,foɷp;ۯ2:޷;ۯ2e ]~6(*} *:޽ y(3:޷s:2G<2x/a2:oa":޷zޯ2{![:޷ <2:>sɯ2>!>2!;:*     1>2>2*"?ۯ2:08 !"Y"BT"->2:8Y"/:8Y"F~!xq!;`~0,~!M;!x~>.~8[q>:޷ 2y2!!{o!:=8 ~y!3w.y2Cɯ2>!w#w#wOa."y .:g"*"!~((5:# :*޽ :޼ $| 8g,"ޯ2!"_!ޅoN!޷((+! ~O#O:x >2ޯ2:޷*(*D*:wk*(:$_"~28 ?@wx( !;!܅ony 2$8!2E!y>>?22!ɯog"$2E!.B...X&*}(8.|8&"$պ`~(,qy2E[22G: 2:O*:P!O#~#'۹~y/:02?"2O: K*:*(0**:8'(*:08* *: 8(*7!w˹#~(=5:!( +_ywɷ+ͱ*:]lc_O{- OMG!~_ :( 6>83! ~èCfuÇKmVÉÎÓãݯ`iޓښ:ޓڦJޓڲZޓھjޓzޓߊ / !~ `66= !; !{g1:Q!͢گ22>2!"2!"͎>2PLINK925ASM PLINK925ASM!PURGE ASC RELDUMP ASM< RIBBS ASC!"#$%&'()*+,-./0RIBBS ASC1SAP-FIX DOC2TAG ASM'34567* MODE ASKING FOR FILENAME * ; * * ; * (NOTE: ALL OTHER CONTROL CODES ARE PASSED TO * ; * MODEM OUTPUT) * ; **************************************************** ; ; ;CONDITIONAL ASSEMBLY SWITCHES <<-- SET FOR YOUR SYSTEM ; EDCAM JULY, 1977 ; ; This version by Keith Petersen, W8SDZ. ; WITH HEATH EQUATES ADDED BY TOM JORGENSON ; ; TRS-80 MODEL 1 mods by Steve Vinokuroff, Vanc CBBS ; Optional Triger characters by Steve Vinokuroff ; TRS-80 mods by Dennis Brecken ; * CONTROL E EXIT PLINK TO CP/M WARM BOOT * ; * CONTROL T TRANSMIT ASCII FILE TO MODEM. * ; * ASKS FOR DRIVE AND FILENAME.TYP * ; * CONTROL C ABORT FILE SEND TO MODEM * ; * CONTROL Y SAVE INCOMING ASCII IN RAM BUFFER * ; * FOR TEXCLEANASM"89:;<TPA3 ASM=>USER-8/8ASM?@V2FORMATASM"ABCDEXFER5-8 ASMFGHXFER8-5 ASMIJKXMODEM32ASMLMNOPQRSTUVWXYZ[XMODEM32ASM\]^_model 1 ; 4. TRS-80 model 2 ; 5. HEATH H8 WITH 8251 UART AT PORT 330Q ; 6. D.C.Hayes 80-103A or Micromodem 100 ; ; ;-->NOTE: IF ASSEMBLED AS WRITTEN WILL WORK WITH D.C.Hayes 80-103A ; OR MICROMODEM 100 AT PORT 90H ; ;PLINK CURRENTLY SUPPORTS TWOridge, Burnaby CBBS ; D.C.Hayes mods by Bruce Ratoff, Iselin NJ Remote CP/M ; ;This program currently supports the following modems ; or computers via conditional assembly. ; ; 1. PMMI modem ; 2. ANY serial i/o board (TUART INCLUDED) ; 3. TRS-80 LATER TRANSFER TO DISK * ; * CONTROL Q WRITE RAM BUFFER TO DISK - ASKS * ; * FOR DRIVE AND FILENAME.TYP * ; * DELETE BACKSPACE WHEN IN COMMAND MODE * ; * ASKING FOR FILENAME * ; * CONTROL U ABORT CURRENT LINE WHEN IN COMMAND * ; ; PLINK.ASM ; (latest version SEPT 25 1980) ; ; PLINK - SUPPORT COMMUNICATIONS LINK WITH CYBER ; ;PLINK IS A CP/M TRANSIENT COMMAND WHICH ALLOWS THE USER TO ;ESTABLISH A COMMUNICATIONS LINK WITH A REMOTE COMPUTER ; ; ORIGINAL BY L.E. HUGHESZ80EXT LIB`abSIG/M LIBcdUGFORM LIBefgh WAY TRANSFER OF TEXT FILES ;BETWEEN THE CP/M DISK AND THE REMOTE COMPUTER. THE FOLLOWING ;CONTROL CODES MAY BE INITIATED FROM THE CONSOLE KEYBOARD: ; ; **************************************************** ; * COMMANDS: * ; * *TUART SET 0 ;CROMEMCO TUART I/O BOARD PMMI EQU 0 ;PUT A 1 HERE IF YOU HAVE A PMMI DCH EQU 1 ;PUT A 1 HERE IF YOU HAVE A D.C.HAYES TRS1 EQU 0 ;PUT A 1 HERE IF YOU HAVE TRS80-MOD1 TRSPT EQU 0 ;PUT 1 HERE IF YOU HAVE TRS80-MOD2 ;USING PICKLES & TROUT OUT JUMP STA OVERL1+1 ;CHANGE CHECK FOR C/R TO NULL STA OVERL2+1 ;AND SEND LINEFEEDS AS WELL JMP SKP ; SKP EQU $ IF H84 MVI A,80H; SET DLAB BIT IN 8250 UART OUT 0DBH; 8250 AT PORT D8H (330Q) NOP ! NOP ! NOP NOP ! NOP MVI A,01H; MSB OF B ;MODEM DATA PORT MODS EQU 91H ;MODEM STATUS PORT MODINIT EQU 05H ;7 DATA, EVEN PARITY, 1 STOP ENDIF ; IF TRS1 MODD EQU 0EBH ;TRS80 MOD 1 RS232 DATA PORT MODS EQU 0EAH ; AND THE RS232 STATUS PORT ENDIF ; IF TUART MODD EQU 0D8H ;<<--MODIFY FOCFFC EQU 16 ;CLOSE FILE DFFC EQU 19 ;DELETE FILE RRFC EQU 20 ;READ RECORD WRFC EQU 21 ;WRITE RECORD MFFC EQU 22 ;MAKE FILE ; ; TRS80 PICKLES AND TROUT SIO CALLS ; OFFSET BY -3 THAT IS ADD 3 TO ALL CALLS ; SETSIO EQU 30H ;SET UP Z80 SIO SIOTST ERS DAD D ;POINT TO CON IN JMP SHLD RCCAL+1 ;MODIFY CALL ADRS DAD D ;POINT TO CON OUT JMP SHLD WCCAL+1 ;MODIFY CALL ADRS LDA FCB+1 ;SEE IF OPTIONAL TRIGER CHAR CPI 20H ;BLANK.. ? JZ SKP ;..BLANK SO USE DEFAULT "LF" CPI 'B' ;BELL WANTED JZ ; 1. B = BELL 07H ; 2. X = XON 11H ; 3. U = UPLOAD NO TRIGER CHECK AT ALL ;ANY OTHER ASCII CHARACTER MAY BE PASSED THROUGH FCB1 ; ; TRIGER EQU LF ;DEFAULT VALUE ; ; ;WARNING CHARACTER FOR LOW MEMORY ; WRNSIG EQU BELL ;IF YOU HAVE ONE, PUT 'BECP/M 2.X H84 EQU 0 ;PUT 1 HERE IF YOU HAVE H8/H8-4 IF H84 TUART SET 1 ENDIF ; INIT$REQUIRED EQU 1 ;PUT 1 HERE IF INITIALIZATION NEEDED ; IF TRS1 OR PMMI OR TUART OR DCH PORT EQU 1 ENDIF ; IF TRSPT PORT EQU 0 ;STILL NEED THE SWITCH ENDIFY FLAG MRDA EQU 01H ;MODEM RECEIVE DATA AVAIL. FLAG ENDIF ; IF TRS1 MTBE EQU 40H ;TRS80 MOD1 RS232 BUFFER READY MRDA EQU 80H ;MODEM RECEIVE DATA AVAIL. ENDIF ; IF TUART ;<<--OR ANY OTHER SERIAL I/O MTBE EQU 20H ;<<--MODIFY FOR YOURS MRDA EQUR YOURS MODS EQU 0DDH ;<<--MODIFY FOR YOURS ENDIF ; ;MODEM STATUS PORT BIT DEFINITIONS ; IF PMMI MTBE EQU 01H ;MODEM TRANS. BUFFER READY FLAG MRDA EQU 02H ;MODEM RECEIVE DATA AVAIL. FLAG ENDIF ; IF DCH MTBE EQU 02H ;MODEM TRANS. BUFFER READQU 33H ;READ SIO STATUS SIOINP EQU 36H ;INPUT A CHAR SIOOUT EQU 39H ;OUTPUT A CHAR ; ;DEFAULT FCB AND FIELD DEFINITIONS ; FCB EQU BASE+5CH FN EQU 1 ;FILE NAME FIELD (REL) FT EQU 9 ;FILE TYPE FIELD (REL) EX EQU 12 ;FILE EXTENT FIELD (REL) NR EQU TRGBEL CPI 'X' ;XON WANTED JZ TRGXON CPI 'U' ;UPLOADING NO CHECKING FOR TRIGER JZ TRGUPL ; SETTRG STA OVERLY+1 ;STORE THE CHARACTER AS IS THEN JMP SKP ; TRGBEL MVI A,BELL JMP SETTRG ; TRGXON MVI A,XON JMP SETTRG ; TRGUPL XRA A ;ZERO LL' HERE ;...ELSE PUT '*' HERE. ; ;MODEM I/O PORT ADDRESSES ; IF PMMI MODD EQU 0C1H ;MODEM DATA PORT MODS EQU 0C0H ;MODEM STATUS PORT MODINIT EQU 29H ;INITIALIZE BYTE ORIGINATE, ;7 DATA, EVEN PARITY, 1 STOP ENDIF ; IF DCH MODD EQU 90H ; ; ; ;BDOS ENTRY POINT AND FUNCTION CODES ; IF NOT TRS1 BASE SET 0 ;STANDARD CPM ENDIF ; IF TRS1 OR H84 BASE SET 4200H ;TRS-80 MODEL 1 CP/M BASE ADDRESS ENDIF ; BDOS EQU BASE+5 RESDSK EQU 13 ;RESET DISK SYSTEM OFFC EQU 15 ;OPEN FILE 1H ;<<--MODIFY FOR YOURS ENDIF ; ; **MAIN PROGRAM** ; ORG BASE+100H ; LINK: LXI SP,STACK+64 ;CREATE LOCAL STACK LHLD BASE+1 ;POINT TO CP/M JMP TABLE LXI D,3 ;GET READY TO ADD 3 DAD D ;POINT TO CON STATUS JMP SHLD CITCAL+1 ;MODIFY CALL AD11H ;X-ON CHARACTER NULL EQU 00H ;NULL CHAR ; ;THE FOLLOWING "TRIGER" EQUATE IS SET TO "LF" (LINEFEED) ;BY DEFAULT. AN OPTIONAL TRIGER CHAR MAY BE PASSED VIA FCB1 ; ; IE: PLINK B WILL SET TRIGER TO "BELL" ; ;THE FOLLOWING OPTIONS ARE ALLOWED ; 32 ;NEXT RECORD FIELD (REL) DBUF EQU BASE+80H ;DEFAULT DISK BUFFER ADDRESS ; ;ASCII CONTROL CHARACTERS ; CR EQU 0DH ;CARRIAGE RETURN LF EQU 0AH ;LINE FEED DEL EQU 7FH ;DELETE (RUBOUT) BELL EQU 07H ;BELL SIGNAL TAB EQU 09H ;HORIZONTAL TAB XON EQU AUD RATE DIVISOR OUT 0D9H; ...TO UART NOP ! NOP ! NOP NOP ! NOP MVI A,80H; LSB OF BAUD RATE DIVISOR OUT 0D8H; ...TO UART NOP ! NOP ! NOP NOP ! NOP MVI A,03H; 8 BITS, 1 STOP BIT, NO PARITY, DLAB RESET OUT 0DBH; ...TO UART NOP ! NOP ! NOPT DISCONNECTED++',CR,LF DB 'USE "MODEM D" TO DISCONNECT',0 ENDIF ; IF NOT PMMI AND NOT DCH DISMS: DB CR,LF,'+++ EXIT TO CP/M +++',CR,LF,0 ENDIF ; PCCMR: DB CR,LF,'SAVING INCOMING TEXT IN MEMORY',CR,LF,0 ; ; STF - SEND TEXT FILE (TO MODEM) IF TRSPT PUSH B ;STORE REGISTERS PUSH H PUSH D CALL WMC ;SEND CHAR POP D POP H POP B ENDIF ; XRA A ;...THEN CLEAR INPUT CHAR BUFFER STA INCH LINK7: JMP LINK3 ;END OF MAIN LOOP ; LINKMS: DB CR,LF,'PLINK as of 25-SEP-80' DB CR,;300 BAUD MVI L,00H ;DISABLE EXT/ACK SIO FUNCTIONS MVI H,'S'-40H ;CONTROL S (X-ON) RET ;TROUGH SETUP PROG INITR NOP ;DO IT TO IT ENDIF ; IF TRS1 ;INIT FOR TRS80 MOD1 RS232 OUT 0E8H ;RESET RS232 IN 0E9H ;READ THE SWITCHES ANI 0F8H ALL WCS STC ;TELL LINK TO IGNORE THIS CHARACTER RET ; PCC3: CPI 'Q'-40H ;JUMP IF NOT CONTROL-Q JNZ PCC4 XRA A ;TURN OFF TEXT SAVE FLAG STA FLAG CALL WTB ;WRITE TEXT BUFFER TO DISK STC RET ; PCC4: STC ;LET LINK HANDLE ALL OTHER CO CALL WCC ;SEND CHAR TO CONSOLE XRA A ;THEN CLEAR OUTPUT CHAR BUFFER STA OUTCH LINK5: CALL MITEST ;JUMP IF NO DATA FROM MODEM JZ LINK6 CALL RMC2 ;ELSE READ MODEM DATA CALL SAVE ;SAVE CHAR IN TEXT BUFFER IF FLAG ON ORI 80H ;SET DATA VALID BIT NOP ! NOP MVI A,0; RESET CONTROL REGISTER OUT 0DCH; ...TO UART JMP CONT ENDIF IF INIT$REQUIRED AND NOT H84 OR PMMI AND NOT H84 MVI A,MODINIT OUT MODS ;INITIALIZE MODEM PORT ENDIF ; IF TUART MVI A,80H ;DSR ON BIT 7 PARL PORT B OUT 'Y' ;YES? JZ PCCEX ;EXIT CALL WCCR ;CRLF STC ;TELL LINK TO IGNORE THIS CHARACTER ; IF TRSPT POP PSW ;GOBBLE UP CALL ADDRESS JMP RESET ;RE-INITIALIZE SIO ENDIF ; IF PORT RET ENDIF ; PCC1: CPI 'T'-40H ;JUMP IF NOT CONTROL-T JNZ PCLF,LF,'READY',CR,LF,LF,0 ; ; PCC - PROCESS CONTROL CHARACTER ; PCC: CPI 'E'-40H ;JUMP OUT IF CTRL E JNZ PCC1 PUSH H LXI H,AYS ;PRINT 'ARE YOU SURE' CALL WCS POP H CALL RCC ;GET ANSWER CALL WCC ;ECHO IT ANI 5FH ;MAKE UPPER CASE CPI ORI 5 OUT 0EAH ;SET DSR AND CTS MVI A,55H ;300 BAUD OUT 0E9H ENDIF ; ; IF PORT IN MODD ;CLEAR MODEM UART READ BUFFERS IN MODD ENDIF ; CONT XRA A ;CLEAR CHAR BUFFERS STA INCH STA OUTCH STA FLAG ;CLEAR TEXT SAVE FLAG NT. CODES CMC RET ; PCCEX: LXI H,DISMS ;PRINT 'MODEM NOT DISCONNECTED' CALL WCS JMP BASE ;EXIT TO WARM BOOT ; AYS: DB CR,LF,'EXIT TO CP/M - ARE YOU SURE (Y OR N)?',0 IF PMMI OR DCH DISMS: DB CR,LF,'++DON''T FORGET - THE MODEM ' DB 'IS NO STA OUTCH ;STORE IN OUTPUT CHAR BUFFER LINK6: CALL MOTEST ;JUMP IF MODEM XMIT BUFFER BUSY JZ LINK7 LDA INCH ;JUMP IF NO DATA FOR MODEM ORA A JP LINK7 ANI 7FH ;DISCARD VALID DATA BIT ; IF PORT OUT MODD ;OUTPUT CHAR TO MODEM ENDIF ; 54H ENDIF ; IF TRSPT ;MUST SET UP SERIAL CHANNEL RESET: LXI H,INITR ;STORE RETURN ADDRESS PUSH H LHLD 1 LXI D,SETSIO ;SIO SETUP ROUTINE DAD D PUSH H ;STORE ON STACK MVI C,00H ;NO PARITY CHAN-A MVI D,0E6H ;8 bits ,1 STOP MVI E,3 C2 CALL STF ;TRANSMIT TEXT FILE TO MODEM STC ;TELL LINK TO IGNORE THIS CHARACTER RET ; PCC2: CPI 'Y'-40H ;JUMP IF NOT CONTROL-Y JNZ PCC3 MVI A,1 ;TURN ON TEXT SAVE FLAG STA FLAG LXI H,PCCMR ;PRINT 'SAVING INCOMING TEXT IN MEMORY' CCC PCC ;CALL PCC IF CONTROL CHAR JC LINK4 ;JUMP IF PCC HANDLED CHAR ORI 80H ;ELSE SET VALID DATA BIT STA INCH ;AND STORE IN INPUT CHAR BUFFER LINK4: LDA OUTCH ;JUMP IF NO DATA FOR CONSOLE ORA A JP LINK5 ANI 7FH ;ELSE DISCARD VALID DATA BIT LXI H,TBUF ;SET PTR TO TBUF SHLD PTR LXI H,0 ;SIZE = 0 SHLD SIZE LXI H,LINKMS ;PRINT SIGN-ON MESSAGE CALL WCS ; ; MAIN LOOP ; LINK3: CALL CITEST ;JUMP IF NO DATA FROM CONSOLE JZ LINK4 CALL RCC ;ELSE READ CONSOLE DATA CPI 20H ; STF: CALL GFN ;GET NAME OF DISK FILE TO SEND JC STF6 ;JUMP IF FILE NAME ERROR CALL OPEN ;TRY TO OPEN SPECIFIED FILE CPI 255 ;JUMP IF FILE NOT FOUND JZ STF7 STF1: CALL READ ;READ NEXT RECORD INTO DBUF CPI 1 ;JUMP IF END-OF-FILE JZ STF5 ERROR' CALL WCS RET ; WTBSM: DB CR,LF,'BUFFER SAVED ON DISK',CR,LF DB 'MEMORY SAVE CANCELLED',CR,LF,0 WTBS1: DB 'TEXT BUFFER EMPTY',CR,LF,0 WTBS2: DB 'FILE NAME ERROR',CR,LF,0 ; ; WCS - WRITE CONSOLE STRING ; ; ; ENTRY CONDITIONS ; HL MESSAGE AND FLOW ; THROUGH TO DISK SAVE ROUTINE ; SAVEND: DB BELL,CR,LF,'ABORTING - NO ROOM LEFT',0 ; SAVEAB: LXI SP,STACK+64 ;REINITIALIZE STACK LXI H,SAVEND ;PRINT 'ABORTING - NO ROOM LEFT' CALL WCS LXI H,LINK ;SET UP RETURN ADDRESS PUSR NEXT MODEM KHARACTER JZ STF3 CALL RMC2 ;CHECK MODEM FOR TRIGGER CHAR. OVERLY CPI TRIGER JNZ STF3 CALL WCCR ;SEND CRLF TO CONSOLE STF4: DCR C ;LOOP THRU REST OF DBUF JNZ STF2 JMP STF1 ;GO GET NEXT RECORD FROM DISK ; STF5: LXI H,STFSM ;I H,DBUF XTHL JMP WTB1 ;LOOP UNTIL END OF TBUF ; WTB3: POP H ;HL POINTS TO CURRENT PLACE IN DBUF WTB4: MVI M,'Z'-40H ;STORE EOF CODE INX H DCR C ;LOOP THRU REST OF DBUF JNZ WTB4 CALL WRITE ;WRITE LAST SECTOR TO DISK CALL CLOSE ;CLEAN;ALLOW LF TO BE SAVED JZ SAVE2 CPI TAB ;ALLOW TAB TO BE SAVED JZ SAVE2 RET ;IGNORE ALL OTHER CONTROL CHARS. ; SAVE2: PUSH H LHLD SIZE ;SIZE = SIZE + 1 INX H SHLD SIZE LHLD PTR MOV M,A INX H SHLD PTR PUSH PSW LDA BASE+7 ;GET SY LXI H,DBUF ;POINT TO DISK BUFFER MVI C,128 STF2: MOV A,M ;FETCH NEXT CHAR FROM DBUF INX H CPI 'Z'-40H ;JUMP IF END-OF-FILE CHARACTER JZ STF5 OVERL2 CPI LF ;IGNORE LINE FEEDS JZ STF4 CALL WMC ;WRITE CHARACTER TO MODEM CALL WCC ;WRITE CALL DELT ;DELETE OLD FILE, IF ANY CALL MAKE ;MAKE NEW FILE LHLD SIZE ;DE = TBUF SIZE XCHG LXI H,DBUF ;TOP OF STACK POINTS TO DBUF PUSH H LXI H,TBUF ;HL POINTS TO TBUF WTB1: MVI C,128 ;DISK BUFFER SIZE WTB2: MOV A,M ;FETCH NEXT BYTE OF TBUH H ;LEAVE IT ON THE STACK ; ; WTB - WRITE TEXT BUFFER TO DISK ; WTB: LHLD SIZE ;JUMP IF TEXT BUFFER EMPTY MOV A,L ORA H JZ WTB5 MVI C,RESDSK ;RESET IN CASE READ-ONLY CALL BDOS CALL GFN ;GET FILE NAME JC WTB6 ;JUMP IF FILE NAME ERROR PRINT 'FILE SEND COMPLETE' CALL WCS RET ; STF6: LXI H,STFS1 ;PRINT 'FILE NAME ERROR' CALL WCS RET ; STF7: LXI H,STFS2 ;PRINT 'FILE NOT FOUND' CALL WCS RET ; STF8: LXI H,STFSA ;PRINT 'FILE SEND ABORTED' CALL WCS RET ; STFSM: DB ' UP ACT AND GO HOME LXI H,TBUF ;CLEAR TEXT BUFFER SHLD PTR LXI H,0 SHLD SIZE LXI H,WTBSM ;PRINT 'BUFFER SAVED ON DISK' CALL WCS RET ; WTB5: LXI H,WTBS1 ;PRINT 'TEXT BUFFER EMPTY' CALL WCS RET ; WTB6: LXI H,WTBS2 ;PRINT 'FILE NAME STEM SIZE SUI 1 ;SO WE DONT CRASH CP/M CMP H ;ARE WE OUT OF ROOM? JZ SAVEAB ;YES, ABORT SUI 4 ;LEAVE SOME ROOM (1K) CMP H MVI A,WRNSIG ;SIGNAL CONSOLE RUNNING OUT OF SPACE CC WCC POP PSW POP H RET ; ; SAVEAB - RAN OUT OF ROOM, ISSUECHARACTER TO CONSOLE OVERL1 CPI CR ;JUMP IF NOT CARRIAGE RETURN JNZ STF4 STF3: CALL CITEST ;CHECK CONSOLE DATA READY JZ STF3A ;NO DATA THERE CALL RCC ;GET CONSOLE CHARACTER CPI 'C'-40H ;CONTROL C ABORTS IT JZ STF8 STF3A: CALL MITEST ;WAIT FOF INX H XTHL MOV M,A ;STORE IN DBUF INX H XTHL DCX D ;SIZE = SIZE - 1 MOV A,D ;EXIT LOOP IF SIZE = 0 ORA E JZ WTB3 DCR C ;LOOP UNTIL DBUF FULL JNZ WTB2 CALL WRITE ;WRITE FULL DBUF TO DISK XTHL ;TOP OF STACK POINTS TO DBUF LX: PUSH PSW LDA FLAG ORA A JNZ SAVE1 POP PSW RET ; SAVE1: POP PSW CPI DEL ;RUBOUT (DEL) ? RZ ;YES, IGNORE IT CPI 20H ;TEST FOR CONTROL CHARACTERS JNC SAVE2 ;JUMP IF NOT CONTROL CHAR. CPI CR ;ALLOW CR TO BE SAVED JZ SAVE2 CPI LF FILE SEND COMPLETE',CR,LF,0 STFS1: DB 'FILE NAME ERROR',CR,LF,0 STFS2: DB 'FILE NOT FOUND',CR,LF,0 STFSA: DB CR,LF,'FILE SEND ABORTED',CR,LF,0 ; ; SAVE - SAVE CHAR IN TEXT BUFFER IF FLAG ON ; ; ENTRY CONDITIONS ; A - CHARACTER TO SAVE ; SAVE- POINTS TO STRING (TERM BY ZERO BYTE) ; WCS: MOV A,M INX H ORA A RZ CALL WCC JMP WCS ; ; WCCR - WRITE CONSOLE CARRIAGE RETURN (AND LINE FEED) ; WCCR: MVI A,CR CALL WCC MVI A,LF ; ; WCC - WRITE CONSOLE CHARACTER ; ; ENTRY CONO ZERO STA FCB+NR ;SET RECORD NUMBER TO ZERO STC ;CLEAR ERROR FLAG AND RETURN CMC RET ; GFN6: STC ;SET ERROR FLAG AND RETURN RET ; GFNSD: DB CR,LF,'WHICH DRIVE? ',0 GFNS1: DB CR,LF,'FILENAME? ',0 ; ; OPEN - OPEN DISK FILE ; OPEN:LL MITEST ;CHAR AVAILABLE JZ RMC ;LOOP IF NOT READY RMC2: PUSH B ;STORE B PUSH D PUSH H MVI B,00H ;CHANNEL A LXI H,RMCRE ;RETURN ADDRESS PUSH H LHLD 1 LXI D,SIOINP DAD D PCHL RMCRE: POP H POP D POP B ANI 7FH ;STRIP PARITY RET R B JZ RCS1 DCX H ;ELSE DISCARD LAST CHAR MOV A,M ;ECHO DISCARDED CHAR TO CONSOLE CALL WCC DCR B ;DECREMENT COUNT JMP RCS1 ; AND LOOP ; RCS2: CPI 'U'-40H ;JUMP IF NOT CONTROL U JNZ RCS3 CALL WCCR ;ELSE ABORT CURRENT LINE JMP RCS ; X D ;ELSE STORE CHAR IN FN FIELD INX D DCR C ;LOOP IF 8 OR LESS CHARS SO FAR JNZ GFN2 JMP GFN6 ;ELSE TAKE ERROR EXIT ; GFN3: LXI D,FCB+FT ;SCAN OFF FT FIELD MVI C,4 GFN4: MOV A,M ;FETCH NEXT CHAR FROM IBUF INX H CPI 61H ;IF LC, CONVERT Z WMCL ;LOOP TILL TX EMPTY POP PSW ;RESTORE CHAR ANI 7FH ;STRIP PARITY PUSH B ;STORE B MOV C,A ;PUT CHAR INTO C MVI B,00H ;CHANNEL A LXI H,WMCRE ;STORE RETURN ADDRESS PUSH H LHLD 1 ;GET BASE ADDRESS LXI D,SIOOUT DAD D PCHL ;JUMP TO IDITIONS: ; A - CHARACTER TO WRITE ; WCC: PUSH PSW PUSH B PUSH D PUSH H MOV C,A ;GET CHARACTER FOR CBIOS WCCAL: CALL $-$ ;MODIFIED BY INIT. POP H POP D POP B POP PSW RET ; ; RCS - READ CONSOLE STRING (WITH ECHO) ; ; EXIT CODRIVES (AS IN CP/M 2.X) JNC GFN STA FCB GFNB: LXI H,GFNS1 ;PRINT 'FILENAME? ' CALL WCS CALL RCS ;READ RESPONSE INTO IBUF LXI H,FCB+FN ;BLANK FILL FN AND FT FIELDS MVI C,11 GFN1: MVI M,' ' INX H DCR C JNZ GFN1 LXI H,IBUF ;POINT TO ENDIF ; ; ; GFN - GET FILE NAME ; GFN: LXI H,GFNSD ;PRINT 'WHICH DRIVE?' CALL WCS CALL RCC ;GET ANSWER FROM CONSOLE CALL WCC ;ECHO IT TO CONSOLE ANI 5FH ;MAKE UPPER CASE SUI 'A'-1 JC GFN ;REQUIRE ALPHABETIC JZ GFN CPI 17 ;ALLOW 16 AND START OVER ; RCS3: CALL WCC ;ECHO CHAR TO CONSOLE MOV M,A ;STORE CHAR IN IBUF INR B ;INCREMENT COUNT CPI CR ;JUMP IF CARRIAGE RETURN JZ RCS4 INX H ;ELSE ADVANCE POINTER JMP RCS1 ; AND LOOP ; RCS4: MVI A,LF ;ISSUE LINE FEED AND RETUTO UC JC GFN4A SUI 20H GFN4A: CPI CR ;JUMP IF END OF LINE JZ GFN5 STAX D ;ELSE STORE CHAR IN FT FIELD INX D DCR C ;LOOP IF 3 OR LESS CHARS SO FAR JNZ GFN4 JMP GFN6 ;ELSE TAKE ERROR EXIT ; GFN5: XRA A STA FCB+EX ;SET EXTENT NUMBER TT WMCRE: POP B ;RESTORE IT POP D POP H RET ENDIF ; ; RMC - READ MODEM CHARACTER ; ; EXIT CONDITIONS: ; A - CHARACTER READ ; ; IF PORT RMC: IN MODS ANI MRDA JZ RMC RMC2: IN MODD ANI 7FH RET ENDIF ; IF TRSPT RMC: CANDITIONS ; B - NUMBER OF CHARACTERS READ (<255) ; HL - POINTS TO LAST CHAR STORED (CR) ; RCS: LXI H,IBUF MVI B,0 RCS1: CALL RCC ;READ NEXT CHAR FROM CONSOLE CPI DEL ;JUMP IF NOT DEL JNZ RCS2 INR B ;IGNORE DEL IF IBUF ALREADY EMPTY DCINPUT BUFFER LXI D,FCB+FN ;SCAN OFF FN FIELD MVI C,9 GFN2: MOV A,M ;FETCH NEXT CHAR FROM IBUF INX H CPI 61H ;IF LC, CONVERT TO UC JC GFN2A SUI 20H GFN2A: CPI CR ;JUMP IF END OF LINE JZ GFN5 CPI '.' ;JUMP IF END OF NAME JZ GFN3 STAY CONDITIONS ; A - CHARACTER TO WRITE ; ; IF PORT WMC: PUSH PSW WMCL: IN MODS ANI MTBE JZ WMCL POP PSW ANI 7FH ;STRIP PARITY BIT OUT MODD RET ENDIF ; IF TRSPT WMC: PUSH H PUSH D PUSH PSW WMCL: CALL MOTEST ;TEST STATUS JRN CALL WCC RET ; ; RCC - READ CONSOLE CHARACTER ; ; EXIT CONDITIONS ; A - CHARACTER READ ; RCC: PUSH B PUSH D PUSH H RCCAL: CALL $-$ ;MODIFIED BY INI\. POP H POP D POP B RET ; ; WMC - WRITE MODEM CHARACTER ; ; ENTR PUSH H PUSH D PUSH B LXI D,FCB MVI C,OFFC CALL BDOS POP B POP D POP H RET ; ; READ - READ RECORD FROM DISK FILE ; READ: PUSH H PUSH D PUSH B LXI D,FCB MVI C,RRFC CALL BDOS POP B POP D POP H RET ; ; CLOSE S "SUMMARY" 160 PRINT "Purging message file..." 170 OPEN "R",1,"A:MESSAGES",65:FIELD#1,65 AS R1$ 180 OPEN "R",2,"A:$MESSAGS.$$$",65:FIELD#2,65 AS R2$ 190 R1=1:R2=1 200 GET#1,R1:IF EOF(1) THEN 300 210 IF VAL(R1$)=0 THEN GET#1,R1+5:R1=R1+VAL(R1$)+6:GOT POP B POP D POP H RET ; ; CITEST - CHECK CONSOLE INPUT STATUS ; CITEST: PUSH B PUSH D PUSH H CITCAL: CALL $-$ ;MODIFIED BY INIT. ORA A ;SET ZERO FLAG POP H POP D POP B RET ;ZERO FLAG CARRIES ANSWER ; ; MITEST - CHECK MODEM INP,30 30 FIELD#1,30 AS R1$ 40 R1=1 50 OPEN "R",2,"A:$SUMMARY.$$$",30 60 FIELD#2,30 AS R2$ 70 R2=1 80 GET#1,R1:IF EOF(1) THEN 150 90 IF VAL(R1$)=0 THEN R1=R1+6:GOTO 80 100 LSET R2$=R1$:PUT#2,R2 103 IF VAL(R1$)>9998 THEN 150 105 PRINT LEFT$(R1$,28) NCH: DS 1 ;INPUT CHAR BUFFER (TO CYBER) OUTCH: DS 1 ;OUTPUT CHAR BUFFER (FROM CIBER) STACK: DS 80 ;LOCAL STACK IBUF: DS 256 ;INPUT BUFFER ; ; TEXT BUFFER ; FLAG: DS 1 ;TEXT SAVE FLAG PTR: DS 2 ;TEXT BUFFER POINTER SIZE: DS 2 ;TEXT BUFFER SIZE- CLOSE DISK FILE ; CLOSE: PUSH H PUSH D PUSH B LXI D,FCB MVI C,CFFC CALL BDOS POP B POP D POP H RET ; ; DELT - DELETE DISK FILE ; DELT: PUSH H PUSH D PUSH B LXI D,FCB MVI C,DFFC CALL BDOS POP B POP D POP H UT STATUS ; IF PORT MITEST: IN MODS ;GET MODEM UART STATUS ANI MRDA ;ANY DATA AVAILABLE? RET ;ZERO FLAG CARRIES ANSWER ENDIF ; ; IF TRSPT ; MITEST: PUSH B PUSH H PUSH D MVI B,00 ;CHANNEL A LXI H,MITSTR PUSH H LHLD 1 LXI D,SIO110 FOR I=1 TO 5 120 R1=R1+1:R2=R2+1:GET#1,R1:LSET R2$=R1$:PUT#2,R2 125 PRINT LEFT$(R2$,28) 130 NEXT I 140 R1=R1+1:R2=R2+1:GOTO 80 150 CLOSE:OPEN "O",1,"SUMMARY.BAK":CLOSE:KILL "SUMMARY.BAK": NAME "SUMMARY" AS "SUMMARY.BAK":NAME "$SUMMARY.$$$" A TBUF: EQU $ ;START OF TEXT BUFFER ; END LINK ; ;INPUT BUFFER ; ; TEXT BUFFER ; FLAG: DS 1 ;TEXT SAVE FLAG PTR: DS 2 ;TEXT BUFFER POINTER SIZE: DS 2 ;TEXT BUFFER SIZE RET ; ; WRITE - WRITE RECORD TO DISK ; WRITE: PUSH H PUSH D PUSH B LXI D,FCB MVI C,WRFC CALL BDOS POP B POP D POP H RET ; ; MAKE - MAKE NEW DISK FILE ; MAKE: PUSH H PUSH D PUSH B LXI D,FCB MVI C,MFFC CALL BDOS 1 REM PURGE - Remove "Killed" messages from SJBBS data files 2 REM Last change 7/8/80 by Bruce Ratoff 3 REM 5 IF (INP(&H91) AND &H40)=0 THEN 10 6 PRINT "Not allowed remote.":GOTO 310 7 REM 10 PRINT "Purging summary file..." 20 OPEN "R",1,"A:SUMMARY"ERO FLAG CARRIES ANSWER ENDIF ; IF TRSPT MOTEST: PUSH B PUSH H PUSH D MVI B,00 ;CHANNEL A LXI H,MOTSTR PUSH H LHLD 1 LXI D,SIOTST DAD D PCHL MOTSTR: ANI 02 ;BUFFER EMPTY POP D POP H POP B RET ENDIF ; ; DATA AREA ; ITST DAD D PCHL MITSTR: POP D POP H ANI 01 ;TX EMPTY POP B RET ;ZERO FLAG HOLDS THE ANSWER ENDIF ; ; MOTEST - CHECK MODEM OUTPUT STATUS ; ; IF PORT MOTEST: IN MODS ;GET MODEM UART STATUS ANI MTBE ;UART READY FOR CHARACTER? RET ;ZO 200 220 PRINT LEFT$(R1$,6) 230 LSET R2$=R1$:PUT#2,R2 235 IF VAL(R1$)>9998 THEN 300 240 FOR I=1 TO 5 250 R1=R1+1:R2=R2+1:GET#1,R1:LSET R2$=R1$:PUT#2,R2 255 PRINT LEFT$(R2$,63) 260 NEXT I 270 FOR I=1 TO VAL(R1$):R1=R1+1:R2=R2+1 280 GET#1,R1:LSET Rnt a space ora a ;not eof yet ret page ; ; handle special relative field ; spl: print ', (special), ctrl fld=$' bits 4 ;spl fld has.. sta ctrlfld ;..4 bits push psw call hexout ;print it print ', $' pop psw mov l,a mvi h,0 ;ctl fldb 'File not found.$' page ; ; main work loop ; main: call item ;identify one item jc done ;cy is eof indicator call stop ;console says stop? jnc main ;continue if not done: call msgxit ;else print 'done' db cr,lf,'done.$' ; stop: mvi c,cs: type $' bits 2 ;get rel type spec push psw call hexout pop psw ora a jz spl ;0 is special type dcr a jz prgrel ;1 is program relative dcr a jz datrel ;2 is data relative ; ; must be 3, common relative ; print ', com rel, val=$' bdos endm ; bits macro num mvi b,num call getbits endm page ; ; get local stack and ; set up fcb ; ORG 100H ; base: lxi h,0 dad sp shld stack lxi sp,stack lda fcb+9 ;look at filetype cpi ' ' ;see if type specified jnz sk1 ;2$=R1$:PUT#2,R2 285 PRINT LEFT$(R2$,63) 290 NEXT I:R1=R1+1:R2=R2+1:GOTO 200 300 CLOSE:OPEN "O",1,"MESSAGES.BAK":CLOSE:KILL "MESSAGES.BAK": NAME "MESSAGES" AS "MESSAGES.BAK":NAME "$MESSAGS.$$$" AS "MESSAGES" 310 END ,"MESSAGES.BAK":CLOSE:KILL "Ml lxi h,relflg mov a,m mvi m,0 ora a jz cont1 call crlf mvi a,maxperline+1 sta abscnt cont1: lxi h,abscnt ;line up abs values mov a,m inr a mov m,a cpi maxperline jc lnok ;max values per line xra a mov m,a call crlf printtsf call bdos ora a rz mvi c,cifnc call bdos cpi 'C'-40h ;control-c? stc ;says stop rz cmc ;false char ret page ; ; decode an item ; item: bits 1 ;get first bit of item ora a ;test for zero jnz not$abs ;not zero, jmp for re; ; Program to dump Microsoft format ; rel files field by field ; with field comments ; ; See Microsoft 'linking loader' manual ; for more information on .rel files ; ; ; Requires Digital Research 'MAC' ; assembler, or alternatively, you ; can e jmp prnt16 prgrel: print ', prg rel, val=$' jmp prnt16 datrel: print ', dat rel, val=$' prnt16: bits 8 ;get rel byte push psw ;save lst sig byte bits 8 ;next call hexout ;print most sig pop psw call hexout ;print least sig pchar ' ' ;prijmp if so lxi h,'RE' ;part of 'REl' shld fcb+9 ;store into fcb mvi a,'L' ;rest of 'reL' sta fcb+11 sk1: mvi c,openf ;open the .rel file lxi d,fcb call bdos cpi 0ffh ;should not be jnz main ;jump if not call msgxit ;else say can't find 'ABS: $' lnok: bits 8 ;get 8 absolute bits call hexout ;display 'em pchar ' ' ora a ;no eof yet ret ; not$abs: call crlf call crlf mvi a,0ffh ;idntfy rel iterm sta relflg mvi a,maxperline+1 ;make new abs line sta abscnt print 'REL20 ; maxperline equ 16 ;abs items per line ; ; define some macros ; pchar macro x if not nul x mvi a,x endif call outchr endm ; print macro string local overstring call overstring db string overstring: pop d mvi c,printf callxpand the macros and use ; the cp/m assembler 'asm'. ; ; ; 8/22/80 by Ron Fowler ; Westland, Mich. ; cr equ 13 lf equ 10 bdos equ 5 fcb equ 5ch buf equ 80h ; cifnc equ 1 prtchr equ 2 printf equ 9 cstsf equ 11 openf equ 15 readf equ d in hl dad h ;offset for table lxi d,msgtable dad d mov e,m ;get lo byte inx h mov d,m ;de has field msg mvi c,printf call bdos ;identify type lda ctrlfld ;get control byte cpi 15 ;15 is eof stc ;so say so rz push psw ;new lin fin external *$' m7: db '* define entry point *$' m8: db '* external - offset *$' m9: db '* external + offset *$' m10: db '* define data size *$' m11: db '* set loc counter *$' m12: db '* chain address *$' m13: buffer mov a,m ;reach in and get byte sta char ;save it mvi a,8 ;new bit count sta bitcnt pop b ret ; ; read next sector from file ; diskrd: mvi c,readf lxi d,fcb call bdos cpi 0ffh ;should not be.. mvi a,0 ;..early eof rnz call comma,spc pop psw ;get back a field ora a ;examine it for type jz absad ;0=absolute adrs dcr a jz prg2 ;1=program rel dcr a jz data2 ;2=data rel ; ; must be common relative ; print '(common rel) value= $' jmp prnt16 data2: print '(da jnc fix outx: push h push d push b mvi c,prtchr mov e,a call bdos pop b pop d pop h ret ; ; table of control-field ; type messages ; msgtable: dw m0,m1,m2,m3 dw m4,m5,m6,m7 dw m8,m9,m10,m11 dw m12,m13,m14,m15 ; ; the messit from input stream ; nxtbit: push b mov b,a ;can't alter a lda bitcnt ;any left this byte? ora a cz refill ;get another if not dcr a sta bitcnt ;update for nxt time lda char ;current byte ral ;bit into cy sta char mov a,b ;restore or a & b flds call crlf print ' $';tab over pop psw cpi 4+1 ;type 0-4 has no a fld jc bonly call afield ;show the a field lda ctrlfld cpi 14 ;end program... jnz not14 ;..forces byte boundary call refill ;go next byte ora a ;retursta lincnt cpi 61 ;lines/page rnz mvi b,6 ;lines to nxt page formfd: mvi a,lf call outx ;<<< dcr b jnz formfd mvi a,1 ;say first line sta lincnt ret hexout: push psw rar rar rar rar call nybble pop psw nybble: ani 0fh cpi msgxit ;oops! db '??? Unexpected end of file.$' ; ; print message pointed ; to by tos then exit ; msgxit: pop d mvi c,printf call bdos lhld stack sphl ret ;to ccp crlf: mvi a,cr call outx mvi a,lf call outx lda lincnt inr a ta rel) value= $' jmp prnt16 prg2: print '(prog rel) value= $' jmp prnt16 absad: print '(absolute) value= $' jmp prnt16 ; bfield: bits 3 ;get b-field size mov e,a ;make a counter pchar '"' ;enclose in quotes bsym: mov a,e ;when e is zeroages: ; m0: db '* entry symbol *$' m1: db '* sel com blk *$' m2: db '* program name *$' m3: db '* request library search *$' m4: db '* extension link item *$' m5: db '* common size *$' m6: db '* chaaccumulator pop b ret ; ; get the next byte from input buffer ; refill: push b lda bufptr cpi 80h ;see if buf empty cz diskrd ;fill if so mov l,a mvi h,0 ;form 16 bits inr a ;update buf pntr sta bufptr lxi d,buf dad d ;point into n cy clr ret not14: cpi 9 ;type 9-15 has no b rnc bonly: call bfield ora a ;say no eof ret page ; ; handle special rel fields ; afield: print 'a fld type: $' bits 2 ;get the a field push psw call hexout ;print it print ', $' ;make a 10 jc xnum adi 7 xnum: adi '0' pchar ret page ; ; print char in a (called from ; macros only). ; outchr: cpi ' ' ;check for printable.. jnc chka ;..characters, make... fix: mvi a,'.' ;...non-printing chars.... chka: cpi 7fh ;....dots ; ; get number of bits from ; input stream as in b reg ; getbits: push h push d xra a ;zero our byte bitlop: call nxtbit ;next bit into cy flg ral ;shift into our byte dcr b ;count down jnz bitlop pop d pop h ret ; ; get next b ora a ;then we are done jz brout dcr e ;count down bits 8 ;get sym char pchar ;print it jmp bsym ;loop till done brout: pchar '"' ;close quotes ret page ; ;************************* ;* subroutines * ;************************* ;db '* program size *$' m14: db '* end program *$' m15: db '* end of file *$' page ; ; variables ; bufptr: db 80h ;force initial read bitcnt: db 0 ;and empty char char: db 0 ctrlfld: db 0 abscnt: db maxperline+1 IELD#1,28 AS RR$ 1100 BK=0:GET#1,RE:IF EOF(1) THEN 1220 1120 G=VAL(RR$):MZ=MZ+1:M(MZ,1)=G:IF G=0 THEN 1200 1130 IF G>9998 THEN MZ=MZ-1:GOTO 1220 1140 GET#1,RE+3:GOSUB 14100:IF INSTR(S$,N$)>0 AND INSTR(S$,O$)>0 THEN 1160 1145 IF N$<>"SYSOP" THEN 1200 STR(RR$,N$)>0 AND INSTR(RR$,O$)>0 THEN MF$=LEFT$(RR$,1):CLOSE: GOSUB 13000:GOTO 780 620 NEXT I 640 V=1:A$="Where (City,State) are you calling from ?":GOSUB 13000: C=1:GOSUB 13200:C=0:ST$=B$:IF ST$="" THEN 540 660 A$="Hello "+N$+" "+O$+" f1,"A:COUNTERS",5:FIELD#1,5 AS RR$:GET#1,MSGS:M=VAL(RR$) 860 A$=STR$(M)+".":GOSUB 13000 880 A$="You are caller # ":N=1:GOSUB 13000:GET#1,CALLS 900 A$=STR$(VAL(RR$)+1):LSET RR$=A$:GOSUB 13000:PUT#1,CALLS 920 A$="Next msg # will be ":N=1:GOSUB 13000:GET#1SUB 13000 500 GOSUB 13000 520 A$="What is your FIRST name ?":GOSUB 13000:C=1:GOSUB 13200:C=0:N$=B$: IF N$="" THEN 520 530 IF N$<"A" THEN 520 540 A$="What is your LAST name ?":GOSUB 13000:C=1:GOSUB 13200:C=0:O$=B$: IF O$="" THEN 520 550 IF ;force initial crlf lincnt: db 1 ;start paper at line 1 relflg: db 0 db 0 ds 50 ;stack space stack: ;stk prt save end rce initial crlf lincnt: db 1 ;start paper at line 1 relflg: db 0 db 0 ds 50 ;stack space stack: ;stk prt save end1:PUT#1,NU+1: S$=STR$(NU):GOSUB 14000:PUT#1,1:CLOSE 720 GOSUB 13000:OPEN "I",1,"A:NEWCOM":BK=0 740 IF EOF(1) OR BK THEN 760 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 740 760 CLOSE:GOSUB 13000:MF$=" " 780 A$="Logging name to disk...":N=1:GOSUB 13000:Orom "+ST$:GOSUB 13000: A$="Did I misspell anything ?":GOSUB 13000:C=1:GOSUB 13200:C=0: IF LEFT$(B$,1)="Y" THEN 520 680 A$="This checking is only done the first time you call.":GOSUB 13000 700 S$=" "+N$+" "+O$+" "+ST$:RL=62:GOSUB 14000:NU=NU+100 REM *****RIBBS - "Remote Iselin Bulletin Board System"***** 120 REM by Bruce R Ratoff 140 REM adapted from Xitan Basic SJBBS by Howard Moulton 160 REM Last change: 9/19/80 180 REM 200 REM 220 DEFINT A-Z 240 DIM A$(17),M(400,2) 260 POKE 0,&HCD ,MNUM:U=VAL(RR$) 940 A$=STR$(U+1):GOSUB 13000:CLOSE:GOSUB 13000 1000 REM 1020 REM LOOK FOR MSGS FOR THIS CALLER 1030 REM AND BUILD MESSAGE INDEX 1040 REM 1060 FT=1:MX=0:MZ=0:'FLAG FIRST TIME FOR PRINTING HEADING 1080 OPEN "R",1,"A:SUMMARY",30:RE=1:FO$<"A" THEN 520 560 IF N$="SYSOP" AND O$="BRUCE" THEN O$="":GOTO 780 570 IF N$="SYSOP" THEN 520 580 V=0:OPEN "R",1,"A:USERS",62:FIELD#1,62 AS RR$:GET#1,1:NU=VAL(RR$): A$="Checking user file...":GOSUB 13000 600 FOR I=2 TO NU+1:GET#1,I: IF INPEN "R",1,"A:CALLERS",60: FIELD#1,60 AS RR$:GET#1,1 800 RE=VAL(RR$)+1:S$=STR$(RE):RL=60:GOSUB 14000:PUT#1,1:RE=RE+1 820 S$=N$+" "+O$+" "+ST$:GOSUB 14000:PUT#1,RE:CLOSE#1 840 BK=0:GOSUB 13000:A$="Active # of msg's ":N=1:GOSUB 13000: OPEN "R", EOF(1) OR BK THEN 440 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 420 440 CLOSE#1:OPEN "I",1,"A:BULLETIN":BK=0:N=0 460 IF EOF(1) OR BK THEN 480 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 460 480 CLOSE#1:BK=0:A$="Prompting bell means system is ready for input.":GO280 ON ERROR GOTO 13500 300 REM 320 REM SIGNON FUNCTIONS 340 REM 350 MSGS=1:CALLS=MSGS+1:MNUM=CALLS+1 360 BK=0:GOSUB 13000:A$="Iselin N.J. RIBBS ":GOSUB 13000 380 A$="Program exchange on request.":GOSUB 13000 400 OPEN "I",1,"A:INFO":BK=0:N=0 420 IF1150 IF INSTR(S$,"BRUCE")=0 THEN 1200 1160 IF FT THEN A$="Please retrieve and kill the following message(s) left for you:":GOSUB 13000:FT=0 1180 A$=STR$(G):N=1:GOSUB 13000 1200 GET#1,RE+5:M(MZ,2)=VAL(RR$):MX=MX+M(MZ,2)+6:RE=RE+6:GOTO 1100 1220 CLOSE:GOEN 7120 7320 IF B$="E" THEN 7380 7340 IF B$="S" THEN 7460 7360 GOTO 7180 7380 GOSUB 13000:A$="Line #?":GOSUB 13000:GOSUB 13200:L=VAL(B$) 7400 IF L=0 OR L>F THEN 7180 ELSE A$="Was:":GOSUB 13000:A$=A$(L):GOSUB 13000 7420 A$="Enter new line (C/R for no Bulletins W--> retype Welcome":GOSUB 13000:IF BK THEN 2000 6140 A$="C--> exit to CP/M U--> list User file":GOSUB 13000:IF BK THEN 2000 6160 A$="G--> Goodbye (signoff)":GOSUB 13000:IF BK THEN 2000 6180 GOSUB 13000:A$="Software exchange is done undest that privelege, "+N$:GOSUB 13000:GOTO 2000 3060 'A$="Password ?":GOSUB 13000:C=1:GOSUB 13200:C=0 3080 'IF B$<>"THERAT" THEN A$="+++INVALID+++":GOSUB 13000:GOSUB 13000:GOTO 2000 3100 A$="Please remember to type BYE before hanging up the phone.":GOSUB 7180 7140 F=F+1:A$=STR$(F)+" ":N=1:GOSUB 13000:GOSUB 13200:IF B$="" THEN F=F-1:GOTO 7180 7160 A$(F)=B$+" ":GOTO 7120 7180 GOSUB 13000:A$="(L)ist, (E)dit, (Q)uit, (C)ontinue, (S)ave; Select?":GOSUB 13000:C=1:GOSUB 13200:C=0 7200 IF B$<>"L" THEN 7280 ELUse ctl-K to abort, ctl-S to pause.":GOSUB 13000 5080 OPEN "I",1,"A:INFO" 5100 IF EOF(1) OR BK THEN 5120 ELSE LINE INPUT#1,A$:GOSUB 13000:B=0:GOTO 5100 5120 CLOSE#1:GOSUB 13000:GOTO 2000 6000 REM 6020 REM *** DISPLAY MENU OF FUNCTIONS *** 6040 REM 6SUB 13000:GOSUB 13000 2000 REM 2020 REM *** MAIN COMMAND ACCEPTOR/DISPATCHER *** 2040 REM 2060 A$="Function B,E,R,S,K,G,W,C,U (or '?' if not known)?":GOSUB 13000: C=1:GOSUB 13200:C=0 2080 IF B$="" THEN 2000 2100 FF=INSTR("BER?SKGWCU",B$) 2120:GOSUB 13000: A$="be listed using MBASIC instead of MLIST.":GOSUB 13000 6210 IF BK THEN 2000 6280 GOSUB 13000:GOTO 2000 7000 REM 7020 REM ***ENTER A NEW MESSAGE*** 7040 REM 7060 F=0:GOSUB 13000:OPEN "R",1,"A:COUNTERS",5:A$="Msg # will be ":N=1r CP/M using":GOSUB 13000: A$="the XMODEM program (for intelligent transfer)":GOSUB 13000: A$="or the MLIST program (simple ASCII listing).":GOSUB 13000 6190 IF BK THEN 2000 6200 GOSUB 13000:A$="BASIC programs are stored in binary and must"13000:GOSUB 13000 3120 A$="To re-enter RIBBS, type:":GOSUB 13000: A$="A>USER 3":GOSUB 13000: A$="A>RIBBS":GOSUB 13000:GOSUB 13000 3140 A$="For info on software exchange, type:":GOSUB 13000: A$="A>MLIST THIS-SYS.DOC":GOSUB 13000:GOSUB 1SE A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000 7220 GOSUB 13000:FOR L=1 TO F:A$=STR$(L)+" "+A$(L) 7240 IF BK THEN 7180 ELSE GOSUB 13000:NEXT L 7260 GOSUB 13000:GOTO 7180 7280 IF B$="Q" THEN A$="Aborted":GOSUB 13000:GOTO 2000 7300 IF B$="C" TH060 GOSUB 13000:A$="Functions supported:":GOSUB 13000:IF BK THEN 2000 6080 A$="S--> Scan messages R--> Retrieve message":GOSUB 13000:IF BK THEN 2000 6100 A$="E--> Enter message K--> Kill message":GOSUB 13000:IF BK THEN 2000 6120 A$="B--> retype IF FF=0 THEN 2160 2140 ON FF GOTO 4000,7000,9000,6000,10000,12000,11000,5000,3000,12500 2160 A$="I don't understand '"+B$+"', "+N$+".":GOSUB 13000:GOSUB 13000:GOTO 2000 3000 REM 3020 REM ***EXIT TO CP/M*** 3040 REM 3050 IF MF$="*" THEN A$="You've lo: GOSUB 13000:FIELD#1,5 AS RR$:GET#1,MNUM:V=VAL(RR$) 7080 A$=STR$(V+1):GOSUB 13000:CLOSE 7100 A$="To enter msg, type in lines.":GOSUB 13000:A$="To edit, hit blank C/R.":GOSUB 13000:GOSUB 13000:F=0 7120 IF F=16 THEN A$="Msg full.":GOSUB 13000:GOTOrt, ctl-S to pause.":GOSUB 13000 4080 OPEN "I",1,"A:BULLETIN" 4100 IF EOF(1) OR BK THEN 4120 ELSE LINE INPUT#1,A$:GOSUB 13000:GOTO 4100 4120 GOSUB 13000:CLOSE#1:GOTO 2000 5000 REM 5020 REM ***DISPLAY WELCOME MESSAGE*** 5040 REM 5060 GOSUB 13000:A$="3000 3160 A$="For general info, type:":GOSUB 13000: A$="A>HELP":GOSUB 13000:GOSUB 13000 3280 POKE 4,0:A$="Entering CP/M...":GOSUB 13000:POKE 0,&HC3:SYSTEM 4000 REM 4020 REM ***DISPLAY BULLETINS*** 4040 REM 4060 GOSUB 13000:A$="Use ctl-K to abochange):":GOSUB 13000:GOSUB 13200 7440 IF B$="" THEN 7180 ELSE A$(L)=B$+" ":GOTO 7180 7460 GOSUB 13000:A$="Todays date (MM/DD/YY)?":GOSUB 13000:GOSUB 13200:D$=B$ 7480 A$="Who to (C/R for ALL)?":GOSUB 13000:C=1:GOSUB 13200:C=0:IF B$="" THEN T$="ALL" ELSErt, ctl-S to pause.":GOSUB 13000:GOSUB 13000 10260 OPEN "R",1,"A:SUMMARY",30:RE=1:FIELD#1,28 AS RR$ 10280 GET#1,RE 10300 IF EOF(1) OR BK THEN 10660 ELSE G=VAL(RR$) 10310 IF G>9998 THEN 10660 10320 IF GM THEN 9460 9260 RE=RE+1:GET#1,RE:GOSUB 14100:D$=S$ 9280 RE=RE+1:GET#1,RE:GOSUB 14100:NO$=S$ 9300 RE=RE+1:GET#1,RE:GOSUB 14100:T$=S$ 9320 RE=RE+1:GET#1,RE:GOSUB 14100:K$=S$ 9340 RE=RE+1:GET#1, 14000:PUT#1,RE 7680 RE=RE+1:S$=T$:GOSUB 14000:PUT#1,RE 7700 RE=RE+1:S$=K$:GOSUB 14000:PUT#1,RE 7720 RE=RE+1:S$=STR$(F):GOSUB 14000:PUT#1,RE 7730 RE=RE+1:S$=" 9999":GOSUB 14000:PUT#1,RE 7740 CLOSE#1 7760 A$="next msg #, ":N=1:GOSUB 13000: OPENr (S)ubject ?":GOSUB 13000:C=1:GOSUB 13200:C=0: B$=LEFT$(B$,1):ST=INSTR("FTS",B$):IF ST=0 THEN 2000 10100 A$="Search string ?":GOSUB 13000:C=1:GOSUB 13200:C=0:SV$=B$: IF SV$="" THEN 2000 10120 M=1:GOTO 10240 10140 GOSUB 13000:A$="Msg # to 0:U=U+1:GOTO 2000 9000 REM 9020 REM ***RETRIEVE MESSAGE*** 9040 REM 9060 GOSUB 13000:A$="Msg # to retrieve (C/R to end)?":GOSUB 13000:GOSUB 13200:GOSUB 13000 9080 IF LEN(B$)=0 THEN M=0 ELSE M=VAL(B$) 9100 IF M<1 THEN GOSUB 13000:GOTO 2000 9120 IF M> T$=B$ 7500 A$="Subject?":GOSUB 13000:C=1:GOSUB 13200:C=0:K$=B$: A$="Password ?":GOSUB 13000:C=1:GOSUB 13200:C=0:PW$=B$: A$="Want to make any changes (Y/N)?":GOSUB 13000:C=1:GOSUB 13200:C=0: IF LEFT$(B$,1)="Y" THEN 7180 7510 IF PW$<>"" E+1:NEXT P:GOSUB 13000 9460 IF INSTR(B$,";") THEN B$=MID$(B$,INSTR(B$,";")+1): M=VAL(B$):RE=1:IF M>0 THEN MI=0:GOTO 9180 9480 IF RIGHT$(B$,1)<>"+" THEN CLOSE:GOTO 9020 9500 M=M+1:MI=0:RE=1 9520 IF M<=U AND NOT BK THEN 9180 9540 CLOSE:A$="End ofRE:J=VAL(RR$):GOSUB 13000 9360 A$="Msg #"+STR$(G)+" was entered on date "+D$+" from "+NO$:GOSUB 13000 9380 A$="To "+T$+" about "+K$:GOSUB 13000:GOSUB 13000 9400 RE=RE+1:FOR P=1 TO J:GET#1,RE:GOSUB 14100:A$=S$:GOSUB 13000 9420 IF BK THEN 9540 9440 RE=R "R",1,"A:COUNTERS",5:FIELD#1,5 AS RR$ 7780 GET#1,MNUM:LSET RR$=STR$(VAL(RR$)+1):PUT#1,MNUM 7800 A$="active msg's, ":N=1:GOSUB 13000 7820 GET#1,MSGS:LSET RR$=STR$(VAL(RR$)+1):PUT#1,MSGS:CLOSE#1 7840 A$="and msg file.":N=1:GOSUB 13000:OPEN "R",1,"A:MESSstart (C/R to end)?":GOSUB 13000:GOSUB 13200:GOSUB 13000 10160 IF LEN(B$)=0 THEN M=0 ELSE M=VAL(B$) 10180 GOSUB 13160 10200 IF M<1 THEN 2000 10220 IF M>U THEN A$="There aren't that many msg's, "+N$+".":GOSUB 13000:GOTO 10020 10240 A$="Use ctl-K to aboU THEN A$="There aren't that many msg's, "+N$+".":GOSUB 13000:GOTO 9060 9140 A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000:GOSUB 13000 9160 OPEN "R",1,"A:MESSAGES",65:RE=1:FIELD#1,63 AS RR$:MI=0 9180 MI=MI+1:IF (MI>MZ) OR BK THEN 9540 ELSE G=M(MITHEN PW$=";"+PW$ 7520 A$="Updating summary file, ":N=1:GOSUB 13000 7540 OPEN "R",1,"A:SUMMARY",30:RE=1:FIELD#1,30 AS RR$:RL=30 7620 RE=MZ*6+1:S$=STR$(V+1)+PW$:GOSUB 14000:PUT#1,RE 7640 RE=RE+1:S$=D$:GOSUB 14000:PUT#1,RE 7660 RE=RE+1:S$=N$+" "+O$:GOSUB msg's.":GOSUB 13000:GOSUB 13000:D$="":NO$="":GOTO 2000 10000 REM 10020 REM ***SUMMARIZE MESSAGES*** 10040 REM 10060 A$="Selective scan ?":GOSUB 13000:C=1:GOSUB 13200:C=0:B$=LEFT$(B$,1): IF B$<>"Y" THEN ST=0:GOTO 10140 10080 A$="(F)rom, (T)o, oUT#1,RE 8060 RE=RE+1:S$=STR$(F):GOSUB 14000:PUT#1,RE 8080 RE=RE+1 8100 FOR P=1 TO F:S$=A$(P):GOSUB 14000:PUT#1,RE:RE=RE+1:NEXT P: S$=" 9999":GOSUB 14000:PUT#1,RE:CLOSE#1:MX=MX+F+6:MZ=MZ+1: M(MZ,1)=V+1:M(MZ,2)=F 8120 GOSUB 13000:GOSUB 1300AGES",65:RL=65 7860 FIELD#1,65 AS RR$ 7880 RE=MX+1 7960 S$=STR$(V+1):GOSUB 14000:PUT#1,RE 7980 RE=RE+1:S$=D$:GOSUB 14000:PUT#1,RE 8000 RE=RE+1:S$=N$+" "+O$:GOSUB 14000:PUT#1,RE 8020 RE=RE+1:S$=T$:GOSUB 14000:PUT#1,RE 8040 RE=RE+1:S$=K$:GOSUB 14000:P80 10360 GET#1,RE+ST+1:GOSUB 14100:IF INSTR(S$,SV$)=0 THEN RE=RE+6:GOTO 10280 10380 A$="Msg #"+STR$(G)+" Date entered: ":N=1:GOSUB 13000 10400 IF BK THEN 10660 10420 RE=RE+1:GET#1,RE:GOSUB 14100:A$=S$+" From: ":N=1:GOSUB 13000 10440 IF BK THEN 10660 IF N=0 AND RIGHT$(A$,1)<>"?" THEN LPRINT 13160 A$="":N=0 13180 RETURN 13200 REM 13220 REM ***ACCEPT STRING INTO B$ FROM CONSOLE*** 13240 REM 13260 PRINT CHR$(7);:B$="":BK=0 13280 LINE INPUT B$:IF LEN(B$)=0 THEN RETURN 13300 IF C=0 THEN 2230 ELSE PW$=MID$(S$,PW+1) 12225 A$="Password ?":GOSUB 13000:C=1:GOSUB 13200:C=0: IF B$<>PW$ THEN A$="Incorrect.":GOSUB 13000:GOSUB 13000:CLOSE:GOTO 2000 12230 S$=" 0":GOSUB 14000:PUT#1,RE:CLOSE 12240 A$="Updating message file...":GOSUB 13000 y *****":GOSUB 13000: GOSUB 13000:GOSUB 13000:CLOSE:GOTO 2000 11000 REM 11020 REM ***GOODBYE*** 11040 REM 11060 GOSUB 13000:A$="Want to leave any comments?":GOSUB 13000:C=1:GOSUB 13200:C=0 11080 IF LEFT$(B$,1)<>"Y" THEN 11240 11100 OPEN "R",1,$:GET#1,1:NU=VAL(NN$) 12600 FOR I=NU+1 TO 2 STEP -1: GET#1,I:IF SU$<>"*" THEN GOSUB 14100:A$=S$:GOSUB 13000 12620 IF BK THEN 12660 12640 NEXT I 12660 CLOSE:GOSUB 13000:GOTO 2000 13000 REM 13020 REM ***PRINT STRING FROM A$ ON CONSOLE*** 130402080 IF LEN(B$)=0 THEN M=0 ELSE M=VAL(B$) 12100 IF M<1 THEN GOSUB 13000:GOTO 2000 12120 IF M>U THEN A$="There aren't that many msg's, "+N$+".":GOSUB 13000:GOTO 12040 12140 A$="Scanning summary file...":GOSUB 13000: OPEN "R",1,"A:SUMMARY",30:RE=1: 10460 RE=RE+1:GET#1,RE:GOSUB 14100:A$=S$:GOSUB 13000 10480 IF BK THEN 10660 10500 A$="To: ":N=1:GOSUB 13000:RE=RE+1:GET#1,RE:GOSUB 14100:A$=S$:GOSUB 13000 10520 IF BK THEN 10660 10540 A$="About: ":N=1:GOSUB 13000:RE=RE+1:GET#1,RE:GOSUB 14100:A$=S$:GOcount...":GOSUB 13000 12380 OPEN "R",1,"A:COUNTERS",5:FIELD#1,5 AS RR$: GET#1,MSGS:LSET RR$=STR$(VAL(RR$)-1):PUT#1,MSGS:CLOSE 12400 GOSUB 13000:A$="Message killed.":GOSUB 13000:GOSUB 13000:GOTO 2000 12420 CLOSE:A$="Message not found.":GOSUB 1300012260 OPEN "R",1,"A:MESSAGES",65:RE=1:FIELD#1,65 AS RR$:MI=0 12280 MI=MI+1:IF MI>MZ THEN 12420 ELSE G=M(MI,1) 12300 IF G9998 THEN 12420 12200 IF GM THEN 12420 ELSE GOSUB 14100:PW=INSTR(S$,";"):PW$="": IF PW=0 OR N$+O$="SYSOP" THEN 1SUB 13000 10560 IF BK THEN 10660 10580 A$="Size: ":N=1:GOSUB 13000:RE=RE+1:GET#1,RE:GOSUB 14100:A$=S$:GOSUB 13000 10600 IF BK THEN 10660 10620 GOSUB 13000 10640 IF U=G OR BK THEN 10660 ELSE RE=RE+1:GOTO 10280 10660 GOSUB 13000:A$="***** End of summar:GOSUB 13000:GOTO 2000 12500 REM 12520 REM ***DISPLAY USER FILE*** 12540 REM 12560 GOSUB 13000:A$="Use ctl-K to abort, ctl-S to pause.":GOSUB 13000:GOSUB 13000 12580 OPEN "R",1,"A:USERS",62:FIELD#1,1 AS MU$,1 AS SU$,60 AS RR$: FIELD#1,10 AS NN A$="From Bruce: thanks for calling, "+N$+".":GOSUB 13000 11260 A$="***** End of connection ******":GOSUB 13000:GOSUB 13000:SYSTEM 12000 REM 12020 REM ***KILL A MESSAGE*** 12040 REM 12060 GOSUB 13000:A$="Message # to kill?":GOSUB 13000:GOSUB 13200 1$="" THEN 11220 ELSE RE=RE+1:S$=B$:RL=65:GOSUB 14000:PUT#1,RE:GOTO 11180 11220 S$=STR$(RE):RL=65:GOSUB 14000:PUT#1,1:CLOSE 11240 GOSUB 13000: A$="Character count: "+STR$(A)+" typed by system - "+STR$(D)+ " typed by you.":GOSUB 13000: 13340 13320 FOR ZZ=1 TO LEN(B$):MID$(B$,ZZ,1)=CHR$(ASC(MID$(B$,ZZ,1))+32*(ASC(MID$(B$,ZZ,1))>96)):NEXT ZZ 13340 IF LEN(B$)<63 THEN 13440 13360 A$="Input line too long - would be truncated to:":GOSUB 13000 13380 B$=LEFT$(B$,62):PRINT B$ 13400 LINE INPUain the wildcards "*" and "?". ; ; ; ; Please forward all comments, suggestions and improvements to: ; Bruce R. Ratoff ; 80 Gill Lane, Apt 1B ; Iselin, New Jersey 08830 ; ; ; bdos equ 5 ;cp/m entry point exit equ 0 ;cp/m exit point dfcb equ by modifying your COMP1 routine to read as seen below. This fix applies to all versions of SAP, whether you have single or double density. ; COMP1: MOV A,M ;GET NEXT BYTE ANI 7FH ;REMOVE ATTRIBUTES MOV B,A ;SAVE IN B LDAX D ANI 7FH ;REM740 IF ERL=7060 THEN V=0:RESUME 7080 13760 IF ERL=7760 THEN C=0:RESUME 7780 13780 IF ERL=7800 THEN C=0:RESUME 7820 13800 RESUME NEXT 14000 REM 14020 REM FILL AND STORE DISK RECORD 14040 REM 14060 LSET RR$=LEFT$(S$+SPACE$(RL-2),RL-2)+CHR$(13)+CHR$(10d by the XMODEM program to indicate that a file may not ; be transmitted. The anticipated purpose is to allow remote use of ; licensed programs without the danger of their being copied by the ; remote users. This should protect the licensee from liabiT "Retype line (Y/N)?";QQ$:QQ$=LEFT$(QQ$,1) 13420 IF QQ$="Y" OR QQ$="y" THEN PRINT PP$;:GOTO 13200 13440 D=D+LEN(B$):RETURN 13500 REM 13520 REM ***ON ERROR HANDLER*** 13540 REM 13560 IF ERL=400 THEN RESUME 440 13580 IF ERL=440 THEN RESUME 480 13600OVE ATTRIBUTES CMP B ;COMPARE CHARACTER RNZ ;RETURN IF NOT EQUAL INX D INX H DCR C ;LOOP THRU FIRST 13 BYTES JNZ COMP1 XRA A ;CLEAR FLAGS AND EXIT RET ; END OF SAP-FIX.DOC ) 14080 RETURN 14100 REM 14120 REM UNPACK DISK RECORD 14140 REM 14160 ZZ=LEN(RR$)-2 14180 WHILE MID$(RR$,ZZ,1)=" " 14200 ZZ=ZZ-1:IF ZZ=1 THEN 14240 14220 WEND 14240 S$=LEFT$(RR$,ZZ) 14260 RETURN 14280 END 14180 WHILE MID$(RR$,ZZ,1)=" " 14200 lities ; associated with dissemination of licensed software. ; ; To Set the "no copy" flag on a file, type: ; A>TAG d:filename.typ S ; To Reset the flag (allows copying via XMODEM), type: ; A>TAG d:filename.typ R ; ; The filename.typ may cont SAP-FIX.DOC as of 5/22/80 by Keith Petersen, W8SDZ If you are using CP/M-2 and have SAP.COM on your system, you probably have noticed that the directory sorting gets confused by the file attributes used in CP/M-2. This can be easily fixed IF ERL=720 THEN RESUME 760 13620 IF ERL=4080 THEN RESUME 4120 13640 IF ERL=5080 THEN RESUME 5120 13660 IF ERL=780 THEN RE=0:RESUME 800 13680 IF ERL=840 THEN M=0:RESUME 860 13700 IF ERL=880 THEN C=0:RESUME 900 13720 IF ERL=920 THEN U=0:RESUME 940 13; title 'TAG - set or reset and display the "no copy" flag on a file' ; by Bruce R. Ratoff - first version 5/18/80 ; modified 5/19/80 by BRR to display 4 across ; ; ; The purpose of this program is to set or reset the f1' bit on a file. ; This is use5ch ;cp/m default fcb dbuff equ 80h ;default disk buffer ; pchar equ 2 ;print character function pmessg equ 9 ;print message function seldsk equ 14 ;select drive function srchfst equ 17 ;search for first file match srchnxt equ 18 ;search for ; filetable equ $ ;start table here, take all avail memory ; end dex to file table ret ; ; ; ; filcnt: ds 1 ;count of files in filetable sropt: ds 1 ;storage for S or R option letter 2 ;get extent # push psw ;save it adi '0' ;convert to ascii mov e,a mvi c,pchar pop psw ora a ;print extent if nonzero jnz pext mvi e,' ' pext: call bdos lda sropt ;get S or R cpi ' ' ;display only? jz nextfile rrc ;bit 7pt: lxi d,ilgopt mvi c,pmessg ;bitch about illegal option call bdos jmp exit ilgopt: db 'Invalid option letter$' okopt: sub a ;zero out file count sta filcnt lxi d,dfcb ;find the first file and get its block map mvi c,srchfst call b0,'$' ; ; ; subroutine to do block moves blkmov: mov a,m ;copy byte from m(hl) to m(de) stax d inx h ;bump pointers inx d dcr b ;loop for count in b jnz blkmov ret ; ; ; subroutine to index bc by file counter filepoint: lhld filcther one...go save it ; ; end of directory encountered, now process them ; tagfile: lxi b,filetable-32 ;allow for filcnt one greater than desired call filepoint push h lxi d,dfcb ;copy next name to default fcb mvi b,32 call blkmov sub a next file match attrib equ 30 ;set file attributes function ; ; org 100h begin: lhld bdos+1 ;set up a stack sphl ;at top of tpa lda dfcb ;check for specific drive dcr a mov e,a ;set up for select disk call mvi c,seldsk inr a ;if trib ;do set attributes call call bdos nextfile: lda dfcb+1 ;get f1 rlc ;isolate f1' ani 1 adi 'R' ;make an R or S sta donmsg+1 lxi d,donmsg mvi c,pmessg ;print completion message for this file call bdos lda filcnt ;get file count=0 for R, 1 for S ani 80h mov b,a ;save mask lxi d,dfcb+1 ;point to f1 ldax d ;get it ani 7fh ;strip f1' ora b ;set bit if option was S stax d ;put it back dcx d ;point to start of fcb sub a ;zap out drive field stax d mvi c,atdos inr a ;search successful? jnz gotfile ;yes, go process rest lxi d,nofile mvi c,pmessg ;say "no file" call bdos jmp exit nofile: db 'File not found$' gotfile: dcr a ;compensate for inr above rrc ;file offset to bits 5 and 6 rrnt ;get file counter mvi h,0 ;force hi ord to 0 dad h ;multiply by 32 dad h dad h dad h dad h dad b ;use as index to file table ret ; ; ; ; filcnt: ds 1 ;count of files in filetable sropt: ds 1 ;storage for S or R option letter sta dfcb ;clear drive number lxi d,-20 ;point back to extent field dad d mvi m,'$' ;tag end of print here pop d ;get back pointer to start of entry inx d ;bump fwd to name mvi c,pmessg call bdos ;say what we're working on lda dfcb+1no specified drive, skip call cnz bdos sub a ;now zap out drive spec sta dfcb mvi a,'?' ;force extent number wild sta dfcb+12 lda dfcb+17 ;get "S" or "R" option sta sropt cpi 'S' jz okopt cpi 'R' jz okopt cpi ' ' jz okopt badoer ani 3 ;multiple of 4? lxi d,crlf mvi c,9 ;if so, time for new line cz bdos lxi h,filcnt ;point to file counter dcr m ;count it down jz exit ;exit if done jmp tagfile ;and go work on next one donmsg: db ' ',9,'$' crlf: db 13,1 inr a sta filcnt ;bump file count pop h ;hl points to directory entry mvi b,32 call blkmov ;copy entry into table mvi c,srchnxt ;search for another entry lxi d,dfcb call bdos inr a ;returns 0ffh at end of search jnz gotfile ;got anoc rrc ani 60h lxi h,dbuff ;point to base of buffer mov c,a mvi b,0 dad b ;index by file offset push h ;save for the moment lxi b,filetable call filepoint ;get table pointer to hl xchg ;de now points to place in table lda filcnt ; ;TEXCLEAN.ASM ver 1.0 by Keith Petersen, W8SDZ ; ;This program cleans up CP/M files which where ;created with a text processor that sets bit 7 ;of some characters. ; month equ 5 ;last.. day equ 22 ;..modification.. year equ 80 ;..date ; ;CleanEXIT W/"INFORMATIONAL" MSG ERXIT POP D ;GET MSG MVI C,PRINT CALL BDOS ;EXIT, RESTORING STACK AND RETURN EXIT LHLD STACK SPHL RET ;TO CCP ; DS 40H ;STACK AREA STACK DS 2 ;OLD STACK KEPT HERE ; ;BDOS/CBIOS EQUATES (VERSION 7) RDCON EQU 1 CITLY CLOSE THE FILE, BECAUSE THE WRITE ;TO THE DIRECTORY WILL CAUSE THE CLEVER LIFEBOAT- ;DESIGNED BIOS TO FLUSH IT'S MEMORY-RESIDENT DISK ;BUFFERS ; FINISH CPM CLOSE,FCB INR A ;THIS BETTER WORK.. JNZ EXIT DB '++ CLOSE ERROR - FILE LEFT IN ' VE from,to,length ; from may be addr, or quoted string ; MOVE MACRO ?F,?T,?L IF NOT NUL ?F IRPC ?C,?F ?Q SET '&?C&?C' ;;TEST FOR QUOTE EXITM ENDM IF ?Q EQ '''' LOCAL ?B,?Z CALL ?Z ?B DB ?F ?Z POP H ;GET FROM LXI B,?Z-?B ;GET LEN ELSOPENING EXTENT FAILED',0DH,0AH DB '++ FILE IS CLOBBERED $' OPEN2OK MVI A,7FH ;GET HI SECTOR STA FCBRNO RET ; ;WRITE BACK THE SECTOR ; WRSECT XRA A STA FCB+14 ;RESET S-2 BYTE IN FCB CPM WRITE,FCB ORA A RZ CALL ERXIT DB '++ WRITE ERROR, CLEAN IT CALL ERXIT DB '++NO SUCH FILE++$' ; ;READ THE FILE, RESET BIT 7 OF ALL CHARACTERS IN ;A SECTOR, RE-WRITE IT. ; READFLP CALL RDSECT ;READ A SECTOR JC FINISH ;EXIT LOOP IF EOF CALL FIXIT ;GET RID OF ALL BIT 7'S CALL BACKUP ;RE-POSIT-up is done in place, i.e. the file is ;modified on top of itself. Each sector is read ;into memory and the characters are all ani'ed with ;7FH to set bit 7 low, and then the same sector is ;written back to the disk. ; ;Command format: ; ; TEXCLEA ;FIX THE SECTOR ; FIXIT LXI H,80H ;POINT TO SECTOR FIXLP MOV A,M ;GET CHARACTER ANI 7FH ;STRIP BIT 7 MOV M,A ;RESTORE IT TO MEMORY INR L ;MORE IN SECTOR? JNZ FIXLP RET ; ;BACKUP THE FILE POINTER FOR THE RE-WRITE ; BACKUP LDA FCBRNO ;GET DB 'UNKNOWN CONDITION ++$' ; ;SECTOR READ ROUTINE ; RDSECT CPM READ,FCB ORA A RZ ;ALL OK ; ;READ ERROR OR EOF ; CPI 1 ;EOF? STC ;CARRY SHOWS EOF RZ ;RET, CARRY SET CALL ERXIT DB '++ READ ERROR - FILE MAY BE ' DB 'DESTROYED ++$' ;E LXI H,?F ENDIF ENDIF IF NOT NUL ?T LXI D,?T ENDIF IF NOT NUL ?L LXI B,?L ENDIF CALL MOVER MF SET -1 ;;SHOW EXPANSION ENDM ; ;DEFINE CP/M MACRO - CPM FNC,PARM ; CPM MACRO ?F,?P PUSH B PUSH D PUSH H IF NOT NUL ?F MVI C, - FILE CLOBBERED ++$' ; ;FOLLOWING FROM 'EQU7.LIB'----> ; ;MOVE SUBROUTINES ; IF MF ;MACRO EXPANSION FLAG SET? MOVER MOV A,M STAX D INX H INX D DCX B MOV A,B ORA C JNZ MOVER RET ENDIF ; ;EXIT WITH ERROR MESSAGE MSGEXIT EQU $ ;ION FOR WRITE CALL WRSECT ;RE-WRITE THE SECTOR JMP READFLP ;LOOP UNTIL EOF ; ;ALL DONE - ON A "NORMAL" CP/M SYSTEM, WE WOULDN'T ;HAVE TO DO ANYTHING, BECAUSE WE RE-WROTE IN PLACE. ; ;HOWEVER, FOR SUCH SYSTEMS AS THE NORTHSTAR CP/M, ;WE MUST EXPLIN FILENAME.TYPE ; ;This program is adapted from Ward Christensen's ;SCRAMBLE.ASM. ; MF SET 0 ;SHOW MOVE NOT REQUESTED CF SET 0 ;SHOW COMP NOT REQUESTED ; ;(FROM EQU8.LIB...) ;DEFINE SOME MACROS TO MAKE THINGS EASIER ; ;DEFINE DATA MOVE MACRO: MOSECTOR # DCR A ;BACK UP STA FCBRNO RP ;RETURN IF OK ; ;WE BACKED UP INTO PREVIOUS EXTENT, WILL HAVE ;TO RE-OPEN IT ; LDA FCBEXT ;GET EXTENT DCR A ;BACK UP 1 STA FCBEXT CPM OPEN,FCB ;RE-OPEN INR A JNZ OPEN2OK CALL ERXIT DB '++ RE-'+MONTH MOD 10,'/' DB '0'+DAY/10 DB '0'+DAY MOD 10,'/' DB '0'+YEAR/10 DB '0'+YEAR MOD 10 DB 0DH,0AH,'$' START POP D ;GET ID MVI C,PRINT CALL BDOS ;PRINT ID ; ;SEE THAT THE INPUT FILE EXISTS ; CPM OPEN,FCB INR A ;OK? JNZ READFLP ;YES?F ENDIF IF NOT NUL ?P LXI D,?P ENDIF CALL BDOS POP H POP D POP B ENDM ; ORG 100H ; ;INIT LOCAL STACK ; LXI H,0 DAD SP SHLD STACK LXI SP,STACK ; ;SIGN ON ; CALL START DB 'TEXCLEAN.COM as of ' DB '0'+MONTH/10 DB '0 WRCON EQU 2 PRINT EQU 9 CONST EQU 11 OPEN EQU 15 CLOSE EQU 16 SRCHF EQU 17 SRCHN EQU 18 ERASE EQU 19 READ EQU 20 WRITE EQU 21 MAKE EQU 22 REN EQU 23 STDMA EQU 26 BDOS EQU 5 FCB EQU 5CH FCB2 EQU 6CH FCBEXT EQU FCB+12 FCBRNO EQU FCB+32  drive byte at loc 4, ; bypassing the need to warm boot ; By Ron Fowler ; ; DFCB EQU 5CH MAXUSER EQU 3 ;for example SETUSR EQU 32 ;set user in bdos DRIVE EQU 4 BDOS EQU 5 ; ORG 100H ; LXI H,DFCB+1 ;POINT TO ORIGINATING USER # IN CMD LINE er pop b pop d pop h ret ; ; Decimal output routine ; this routine has following ; entry and external parameters: ; ; entry: hl=binary number to print in decimal ; external calls: co routine ; ** note...this routine is recursivegh- ; est available public user area is de- ; fined by "MAXUSER". ; ;08/07/80 CORRECTED TO MAINTAIN REQUESTED ; USER NUMBER EVEN AFTER WARM BOOT. ; AND TO ALLOW NUMBERS HIGHER THAN ; 9. By Keith Petersen, W8SDZ. ; ;08/07/80 Replaced RAL i100h) ;ccp size + tpa dad d ;subtract it, answer left in hl call decout ;print it call tb2 ;print rest of line db ' bytes before overlaying the ccp.',13,10,'$' ; tb2: mvi c,9 ;print msg function pop d ;get msg adrs call 5 ;print it pop h ;r ora l cnz decout mov a,e adi '0' call co pop h pop d pop b ret ; stack equ $+80 ;40 level stack ; end  cout: push b push d push h lxi b,-10 lxi d,-1 ; decou2: dad b inx d jc decou2 lxi b,10 dad b xchg mov a,h , and uses ; 6 bytes of stack for each recursive call, in ad- ; dition to any stack space used by the co routine. ; decout: push b push d push h lxi b,-10 lxi d,-1 ; decou2: dad b inx d jc decou2 lxi b,10 dad b xchg mov a,h ; ; this program returns the amount ; of free space in the tpa. ; this can be useful when running under ; fast, despool, ddt, sid, etc. ; ; version of 8/30/80 ; ; ; by Ron Fowler ; Westland, Mich. ; 8/24/80 ; ; fixes and code optimiznstructions with RLC to ; eliminate drive select error caused by ; rotating carry bit into accumulator. ; By Dave Hardy and Bruce Levison ; ;08/08/80 Modified for improved response time ; by calling the setusr function after ; modifying theestore ccp stack sphl ret ;back to the ccp ; ; subroutines ; ; Console output routine ; prints character in 'a' register ; co: push h push d push b mov e,a ;character to e for CP/M mvi c,2 ;print console function call 5 ;print charact; ; USER.ASM vers. 1.2 ; by Ron Fowler ; Westland, Mich. ; ; ; revised 8/7/80 ; ; (FOR USE WITH CP/M-2.x ONLY) ; This program is used to restrict access ; to the higher user areas while leaving ; the lower user areas public. The hisubtract it, answer left in hl call decout ;print it call tb1 ;print the rest of line db ' bytes total tpa space.',13,10,'$' ; tb1: mvi c,9 ;print msg function pop d ;get msg adrs call 5 ;print it pop d ;get top of memory back lxi H,-(800h+ations by ; Keith Petersen ; org 100h ; base: lxi h,0 dad sp ;get local stack lxi sp,stack push h ;save old stack lhld 6 ;get the top of memory xchg ;put it in de push d ;save it for later lxi h,-100h ;get the start of mem dad d ; MVI E,0 NUMLUP: MOV A,M ;GET CHARACTER INX H ;BUMP CHAR POINTER SUI '0' ;REMOVE ASCII BIAS JC NUMDONE CPI 10 ;CHECK IF PAST 9 JNC NUMDONE ;ANY INVALID CHAR ENDS NUMBER MOV D,A MOV A,E ;GET ACCUMULATED NUMBER ADD A ;TIMES TWO ADD A ;TLF,CR .ASCII '128 BYTES = 0 ' .BYTE LF,CR .ASCII '256 BYTES = 1' .BYTE LF,CR,'$' MSG2: .BYTE VT,LF,CR .ASCII ' DENSITY' .BYTE LF,CR .ASCII ' -------' .BYTE LF,CR,LF,CR .ASCII 'SINGLE = 0 ' .BYTE LF,CR .ASCII 'DOUBLE = 1' .BYTE LF,CDOS MVI C,1 CALL BDOS ANI 0FH CPI 02H JNC SIZE CPI 00H JZ RESET7 JMP SET7 DEN: MVI C,9 LXI D,MSG2 CALL BDOS MVI C,1 CALL BDOS ANI 0FH CPI 02H JNC DEN CPI 00H JZ RESET6 JMP SET6 DSIZE: MVI C,9 LXI D,MSG3 CALL BDOS NUMBER MVI C,SETUSR ;SET THE USER FOR NOW JMP BDOS ;SET IT AND EXIT ; HUH: LXI D,MSG MVI C,9 ;PRINT STRING FUNCTION JMP BDOS ;PRINT & EXIT ; MSG: DB 'Only USER 0-' DB MAXUSER+30H DB ' available.$' ; END C,9 ;PRINT STRING FUNCTION JMNIT RES 5,M POP H JMP DSIDE RESET4: PUSH H LXI H,UNIT RES 4,M POP H JMP GO SET7: PUSH H LXI H,UNIT SET 7,M POP H JMP DEN SET6: PUSH H LXI H,UNIT SET 6,M POP H JMP DSIZE SET5: PUSH H LXI H,UNIT SET 5,M POP H JMP DSIRAM+44H ;Track Pointer BIOS = 0F000H ;Versafloppy BIOS Address HME = BIOS+18H ;Home Entry to BIOS FMATE = BIOS+33H ;Format Entry to BIOS NTRKS = BIOS+40H ;Contains # of Disk TRACKS CR = 0DH ;Carriage-Return LF = 0AH ;Line-Feed VT = 0BH ;Clear SCIMES FOUR ADD E ;TIMES FIVE ADD A ;TIMES TEN ADD D ;PLUS NEW DIGIT MOV E,A ;SAVE ACCUMULATION JMP NUMLUP ;LOOP BACK FOR NEXT CHAR ; NUMDONE: MOV A,E ;GET ACCUMULATED NUMBER ORA A ;BELOW ZERO OR ABOVE 127? JM HUH ;INVALID CHARACTER ENTEREDI C,1 CALL BDOS CPI CR RNZ XRA A STA TRK INR A STA SCTR CALL HME FORMT1: CALL FMATE ;Format this Track JNZ ERROR LDA TRK INR A STA TRK MOV B,A LDA NTRKS CMP B JNZ FORMT1 MVI C,9 LXI D,MSG6 CALL BDOS MVI C,1 CALL MVI C,1 CALL BDOS ANI 0FH CPI 02H JNC DSIZE CPI 00H JZ RESET5 JMP SET5 DSIDE: MVI C,9 LXI D,MSG4 CALL BDOS MVI C,1 CALL BDOS ANI 0FH CPI 02H JNC DSIDE CPI 00H JZ RESET4 JMP SET4 GO: MVI C,9 LXI D,MMSG CALL BDOS MV; ; VERSAFLOPPY II DISK FORMATTER ; ; Formats a New Disk with IBM Soft-Sectored Format. ; ; R. W. Hart - July 1980 ; ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; XX CAUTION!!! - This Program Will Destroy the XX ; XX Contents of a Disk UDE SET4: PUSH H LXI H,UNIT SET 4,M POP H JMP GO ; ERROR: MVI C,9 LXI D,EMSG CALL BDOS PUSH H LHLD SAVUNIT SHLD UNIT POP H JMP 00H ; MSG1: .BYTE VT,LF,CR .ASCII ' SECTOR SIZE' .BYTE LF,CR .ASCII ' -----------' .BYTE LF,CR,REEN FILLER = 0000H ; ; LHLD UNIT SHLD SAVUNIT FORMAT: MVI C,9 LXI D,GMSG CALL BDOS ;Output Greeting DRIVE: MVI C,9 LXI D,MSG5 CALL BDOS MVI C,1 CALL BDOS ANI 0FH CPI 04H JNC DRIVE STA UNIT SIZE: MVI C,9 LXI D,MSG1 CALL B CPI MAXUSER+1 JNC HUH ;RESTRICT ACCESS RLC ! RLC ! RLC ! RLC ;MOVE TO UPPER NIBBLE MOV B,A ;SAVE REQUESTED USER NUMBER LDA DRIVE ;GET CURRENT USER/DRIVE ANI 0FH ;STRIP OFF OLD USER NUMBER ORA B ;GET NEW USER NUMBER STA DRIVE ;SET NEW USER BDOS CPI 'Y' JZ GO MVI C,9 LXI D,FMSG CALL BDOS PUSH H LHLD SAVUNIT SHLD UNIT POP H JMP 00H ; RESET7: PUSH H LXI H,UNIT RES 7,M POP H JMP DEN RESET6: PUSH H LXI H,UNIT RES 6,M POP H JMP DSIZE RESET5: PUSH H LXI H,Uthe Disk. XX ; XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; .PABS .LOC 0100H ; ; DEFINITIONS ; SRAM = 0000H ;Start of RAM BDOS = 0005H ;Operating System Entry UNIT = SRAM+42H ;Unit Byte SCTR = SRAM+43H ;Sector Pointer TRK = Snless it is Write- XX ; XX Protected. When Calling the Program by XX ; XX Mistake, any Response other than RETURN to XX ; XX the Question "When Ready, Respond with XX ; XX RETURN.." Will Abort the Program Without XX ; XX Writing to R,'$' MSG3: .BYTE VT,LF,CR .ASCII 'DRIVE SIZE ' .BYTE LF,CR .ASCII '----------' .BYTE LF,CR,LF,CR .ASCII ' FULL = 0' .BYTE LF,CR .ASCII ' MINI = 1' .BYTE LF,CR,'$' MSG4: .BYTE VT,LF,CR .ASCII ' # OF SIDES' .BYTE LF,CR .ASCII ' - CALL REBDOS POP H POP D POP B RET DONE LXI D,MSG4 MVI C,PRINT CALL BDOS MVI C,CLOSE LXI D,NFCB CALL REBDOS JMP WBOOT ERROR POP D MVI C,PRINT CALL BDOS JMP WBOOT NFCB DS 35 OLDSP DS 2 MSG1 DB 'THE OPENING OF FILES WAS OK' AND USE DDT TO BOOT UP THE ; NORTH STAR SYSTEM. ; THESE EQUATES ARE USED BY THIS PROGRAM VT EQU 0BH ;VDM-1 CLEAR SCREEN BDOS EQU 5 REBDOS EQU 0AC06H ;48K VERSAFLOPPY BDOS VECTOR SEBDOS EQU 00005H ;16K N* BDOS VECTOR DEFFCB EQU 5CH ;DEFAULT FORMATER - ' .ASCII 'VERSION 1.00' .BYTE LF,CR,LF,CR,'$' MMSG: .BYTE VT,LF,CR .ASCII 'Mount Disk to be Formatted...' .BYTE LF,CR,LF,CR .ASCII 'When Ready, Respond With RETURN...' .BYTE LF,CR,'$' ; EMSG: .BYTE VT,LF,CR .ASCII '*** DISK WRITE BDOS CALL READIT CPI 0 JZ HERE CPI 1 JZ DONE CALL ERROR DB 'THERE WAS AN ERROR IN THE CALL TO BDOS.$' HERE LXI D,MSG3 MVI C,PRINT CALL BDOS CALL WRITIT CPI 2 JNZ OKOPN CALL ERROR DB 'THE DISK IS FULL, CANNOT WRITE ANY MORE TO ---------' .BYTE LF,CR,LF,CR .ASCII 'SINGLE SIDED = 0' .BYTE LF,CR .ASCII 'DOUBLE SIDED = 1' .BYTE LF,CR,'$' MSG5: .BYTE LF,CR .ASCII ' DRIVE' .BYTE LF,CR .ASCII ' -----' .BYTE LF,CR,LF,CR .ASCII 'DRIVE A = 0' .BYTE LF,CR .ASCI LXI SP,STACK MVI B,0FH LXI D,6CH LXI H,NFCB LOOP1 LDAX D MOV M,A INX H INX D DCR B JNZ LOOP1 LXI D,DEFFCB MVI C,OPEN CALL SEBDOS CPI 255 JNZ OPNOK CALL ERROR DB 'FILE NOT FOUND ON THE NORTH STAR DISK.$' OPNOK LXI D,MSG1 MILE CONTROL BLOCK OPEN EQU 15 SETBUF EQU 26 DELETE EQU 19 MAKE EQU 22 READ EQU 20 WRITE EQU 21 CLOSE EQU 16 PRINT EQU 9 FCBCR EQU DEFFCB+32 WBOOT EQU 0 ORG 100H LXI D,MSG5 MVI C,PRINT CALL BDOS START LXI H,0 DAD SP SHLD OLDSP ERROR - PROGRAM ABORTED ***' .BYTE LF,CR,LF,CR,'$' ; FMSG: .BYTE VT,LF,CR .ASCII '*** FORMATTING COMPLETE - REMOVE DISK ***' .BYTE LF,CR,LF,CR,'$' ; ; SAVUNIT: .WORD FILLER ; .END IT.$' READIT PUSH B PUSH D PUSH H MVI C,SETBUF LXI D,0080H CALL SEBDOS MVI C,READ LXI D,DEFFCB CALL SEBDOS POP H POP D POP B RET WRITIT PUSH B PUSH D PUSH H MVI C,SETBUF LXI D,0080H CALL REBDOS MVI C,WRITE LXI D,NFCB; ;NORTHSTAR TO VERSAFLOPPY FILE TRANSFER PROGRAM ;DEBUGGED AND ENHANCED BY ROD HART WA3MEZ ; AUGUST 14, 1980 ; ; TO USE, BRING UP THE NORTH STAR CP/M AS A 16K SYSTEM ; AND THE VERSAFLOPPY AS A 48K SYSTEM. BE SURE TO BOOT ; UP THE VERSAFLOPPY FIRST I 'DRIVE B = 1' .BYTE LF,CR .ASCII 'DRIVE C = 2' .BYTE LF,CR .ASCII 'DRIVE D = 3' .BYTE LF,CR,'$' MSG6: .BYTE VT,LF,CR .ASCII 'Do You Wish To Format Another Disk ?' .BYTE LF,CR,'$' GMSG: .BYTE VT,LF,CR .ASCII 'WA3MEZ VERSAFLOPPY II DISK FVI C,PRINT CALL BDOS XRA A STA FCBCR STA NFCB+32 LXI D,NFCB MVI C,DELETE CALL REBDOS LXI D,NFCB MVI C,MAKE CALL REBDOS JP OKOPN CALL ERROR DB 'CANNOT CREATE THE FILE ON THE VERSAFLOPPY DISK$' OKOPN LXI D,MSG2 MVI C,PRINT CALL DB 0AH,0DH,'$' MSG2 DB 'READING A SECTOR FROM NORTH STAR DISK' DB 0AH,0DH,'$' MSG3 DB 'WRITING A SECTOR TO VERSAFLOPPY DISK' DB 0AH,0DH,'$' MSG4 DB 'CLOSING THE FILES NOW' DB 0AH,0DH,'$' MSG5 DB VT,0AH,0DH,'16K NORTH STAR TO 48K VERSAFLOPPY CP/MRINT CALL BDOS CALL READIT CPI 0 JZ HERE CPI 1 JZ DONE CALL ERROR DB 'THERE WAS AN ERROR IN THE CALL TO BDOS.$' HERE LXI D,MSG3 MVI C,PRINT CALL BDOS CALL WRITIT CPI 2 JNZ OKOPN CALL ERROR DB 'THE DISK IS FULL, CANNOT WRITE AH STAR CP/M TRANSFER PROGRAM' DB 0AH,0DH,'$' STACK EQU $+100 END H STAR DISK' DB 0AH,0DH,'$' MSG4 DB 'CLOSING THE FILES NOW' DB 0AH,0DH,'$' MSG5 DB VT,0AH,0DH,'48K VERSAFLOPPY TO 16K NORTHLD OLDSP LXI SP,STACK MVI B,0FH LXI D,6CH LI H,NFCB LOOP1 LAX D MOV M,A INX H IN D DCR B JNZ LOOP1 LXI D,DEFFCB MVI C,OPEN CALL SEBDOS CPI 255 JNZ OPNOK CALL ERROR DB 'FILE NOT FOUND ON THE VERSAFLOPPY DISK.$' OPNOK LX TRANSFER PROGRAM' DB 0AH,0DH,'$' STACK EQU $+100 END ' DB 0AH,0DH,'$' MSG4 DB 'CLOSING THE FILES NOW' DB 0AH,0DH,'$' MSG5 DB VT,0AH,0DH,'16K NORTH STAR TO 48K VERSAFLOPPY CP/M LXI D,NFCB CALL REBDOS POP H POP D POP B RET DONE LXI D,MSG4 MVI C,PRINT CALL BDOS MVI C,CLOSE LXI D,NFCB CALL REBDOS JMP WBOOT ERROR POP D MVI C,PRINT CALL BDOS JMP WBOOT NFCB DS 35 OLDSP DS 2 MSG1 DB 'THE OPENING OF FILENY MORE TO IT.$' READIT PUSH B PUSH D PUSH H MVI C,SETBUF LXI D,0080H CALL SEBDOS MVI C,READ LXI D,DEFFCB CALL SEBDOS POP H POP D POP B RET WRITIT PUSH B PUSH D PUSH H MVI C,SETBUF LXI D,0080H CALL REBDOS MVI C,WRITE ; ;VERSAFLOPPY TO NORTH STAR FILE TRANSFER PROGRAM ;DEBUGGED AND ENHANCED BY ROD HART WA3MEZ ; AUGUST 14, 1980 ; ; TO USE, BRING UP THE VERSAFLOPPY CP/M AS A 48K SYSTEM ; AND THE NORTH STAR AS A 16K SYSTEM. BE SURE TO BOOT ; UP THE NORTH STAR FIRST I D,MSG1 MVI C,PRINT CALL BDOS XRA A STA FCBCR STA NFCB+32 LXI D,NFCB MVI C,DELETE CALL REBDOS LXI D,NFCB MVI C,MAKE CALL REBDOS JP OKOPN CALL ERROR DB 'CANNOT CREATE THE FILE ON THE NORTH STAR DISK$' OKOPN LXI D,MSG2 MVI C,PS WAS OK' DB 0AH,0DH,'$' MSG2 DB 'READING A SECTOR FROM VERSAFLOPPY DISK' DB 0AH,0DH,'$' MSG3 DB 'WRITING A SECTOR TO NORTH STAR DISK' DB 0AH,0DH,'$' MSG4 DB 'CLOSING THE FILES NOW' DB 0AH,0DH,'$' MSG5 DB VT,0AH,0DH,'48K VERSAFLOPPY TO 16K NORT ;DEFAULT FILE CONTROL BLOCK OPEN EQU 15 SETBUF EQU 26 DELETE EQU 19 MAKE EQU 22 READ EQU 20 WRITE EQU 21 CLOSE EQU 16 PRINT EQU 9 FCBCR EQU DEFFCB+32 WBOOT EQU 0 ORG 100H LXI D,MSG5 MVI C,PRINT CALL BDOS START LXI H,0 DAD SP SAND USE DDT TO BOOT UP THE ; VERSAFLOPPY SYSTEM. ; THESE EQUATES ARE USED BY THIS PROGRAM VT EQU 0BH ;VDM-1 CLEAR SCREEN BDOS EQU 5 REBDOS EQU 03106H ; 16K NORTH STAR BDOS VECTOR SEBDOS EQU 00005H ; 48K VERSAFLOPPY BDOS VECTOR DEFFCB EQU 5CH ; ;XMODEM.ASM V3.2, BY KEITH PETERSEN, W8SDZ ; (revised 9/13/80) ; ;CP/M - CP/M FILE TRANSFER PROGRAM ;BASED ON MODEM.ASM V2.0, BY WARD CHRISTENSEN ;THIS PROGRAM IS INTENDED FOR USE ON REMOTE CP/M ;SYSTEMS WHERE IT IS IMPORTANT THAT THE INITIALIZ ;TRANSMISSION ON ERRORS. ; ; SENDFIL CALL OPENFIL ;OPEN THE FILE MVI E,80 ;WAIT 80 SEC.. CALL WAITNAK ;..FOR INITIAL NAK SENDLP CALL RDSECT ;READ A SECTOR JC SENDEOF ;SEND EOF IF DONE CALL INCRSNO ;BUMP SECTOR # XRA A ;ZERO ERROR.. STA MODDATP EQU 03H ;YOUR MODEM DATA PORT ENDIF ;END OF EXTERNAL MODEM EQUATES ; ERRLIM EQU 10 ;MAX ALLOWABLE ERRORS ; FASTCLK EQU FALSE ;PUT TRUE HERE FOR 4 MHZ CLOCK ; ;DEFINE ASCII CHARACTERS USED ; SOH EQU 1 ;START OF HEADER EOT EQU 4 ;END OF;and added conditional assembly of test for '.COM' ;filetype on receive as well. See 'NOCOM' below. ; Any filetype ending in '#' will not be sent by ;this program if 'NOCOM' is set to TRUE. ; 9-SEP-80 J.SEYMOUR ; FALSE EQU 0 TRUE EQU NOT FALSE ; CALL ERXIT ;EXIT W/ERROR DB '++INVALID OPTION ON XMODEM ' DB 'COMMAND++',CR,LF DB 'Must be S for SEND or R for ' DB 'RECEIVE',CR,LF,'$' ; * * * * * * * * * * * * * * * * * * * * * * * * SENDFIL: SENDS A CP/M FILE * * * * * * * * * *DY MODRCVB EQU 1 ;BIT TO TEST FOR RECEIVE MODRCVR EQU 1 ;VALUE WHEN READY MODDATP EQU 80H ;DATA PORT MODCTL2 EQU 81H ;SECOND CTL PORT ENDIF ; ;IF YOU ARE USING AN EXTERNAL MODEM (NOT S-100 PLUG-IN) ;CHANGE THESE EQUATES FOR YOUR MODEM PORT REQUIREATION ;OF THE MODEM NOT BE CHANGED, SUCH AS WHEN USING ;THE PMMIBYE PROGRAM. THE BAUD RATE AND NUMBER OF BITS ;REMAINS THE SAME AS WHATEVER WAS SET PREVIOUSLY. ;THERE IS NO DISCONNECT, TERMINAL OR ECHO OPTION. ; ;NOTE: THIS FILE WILL ASSEMBLE, WITHOU.SAVE IT LXI SP,STACK ;SP=MY STACK CALL ILPRT ;PRINT: DB CR,LF DB 'XMODEM ver 3.2',CR,LF,0 ; ;GET OPTION ; LDA FCB+1 ;GET OPTION (S or R) PUSH PSW ;SAVE OPTION ; ;MOVE THE FILENAME FROM FCB 2 TO FCB 1 ; CALL MOVEFCB ; ;GOBBLE UP GARBA TRANSMISSION ACK EQU 6 ;ACKNOWLEDGE NAK EQU 15H ;NEG ACKNOWLEDGE CAN EQU 18H ;CONTROL-X FOR CANCEL LF EQU 10 ;LINEFEED CR EQU 13 ;CARRIAGE RETURN ; ORG BASE+100H ; ;INIT PRIVATE STACK LXI H,0 ;HL=0 DAD SP ;HL=STACK FROM CP/M SHLD STACK ;. STDCPM EQU TRUE ;TRUE, IS STANDARD CP/M ALTCPM EQU FALSE ;TRUE, IS H8 OR TRS-80 CP/M ; IF STDCPM BASE EQU 0 ;CP/M BASE ADDRESS ENDIF ; IF ALTCPM BASE EQU 4200H ;ALTERNATE CP/M BASE ADDRESS ENDIF ; PMMI EQU TRUE ;TRUE, IS PMMI ; DCH EQU FA * * * * * * * * * * * * * * ; ;THE CP/M FILE SPECIFIED IN THE MODEM COMMAND ;IS TRANSFERRED OVER THE PHONE TO ANOTHER ;COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE) ;OPTION. THE DATA IS SENT ONE SECTOR AT A ;TIME WITH HEADERS AND CHECKSUMS, AND RE-MENTS ; IF NOT PMMI AND NOT DCH MODCTLP EQU 02H ;PUT YOUR MODEM CONTROL PORT HERE MODSNDB EQU 80H ;YOUR BIT TO TEST FOR SEND MODSNDR EQU 80H ;YOUR VALUE WHEN READY MODRCVB EQU 40H ;YOUR BIT TO TEST FOR RECEIVE MODRCVR EQU 40H ;YOUR VALUE WHEN READYT NEED FOR ;EDITING, TO WORK WITH A PMMI MM-103 MODEM. SEE ;EQUATES FOR OTHER OPTIONS INCLUDING SYSTEM CLOCK ;FREQUENCY AND OTHER TYPES OF MODEMS. ; ; Added conditional assembly to prevent filetypes ;'.COM' or '.??#' from being sent to distant end GE CHARS FROM THE LINE ;PRIOR TO RECEIVE OR SEND ; IN MODDATP IN MODDATP ; ;JMP TO APPROPRIATE FUNCTION ; POP PSW ;GET OPTION ; CPI 'S' ;SEND.. JZ SENDFIL ;..A FILE? ; CPI 'R' ;RECEIVE.. JZ RCVFIL ;..A FILE? ; ;INVALID OPTION MODRCVR EQU 2 ;VALUE WHEN READY MODDATP EQU 0C1H ;DATA PORT BAUDRP EQU 0C2H ;BAUD RATE OUTPUT MODCTL2 EQU 0C3H ;SECOND CTL PORT ENDIF ; IF DCH MODCTLP EQU 82H ;D. C. HAYES VALUES MODSNDB EQU 2 ;BIT TO TEST FOR SEND MODSNDR EQU 2 ;VALUE WHEN REALSE ;TRUE, IS D.C. HAYES ; NOCOM EQU TRUE ;TRUE, NO .COM OR .??# FILES ;SENT OR '.COM' RECEIVED ; IF PMMI MODCTLP EQU 0C0H ;PMMI VALUES MODSNDB EQU 1 ;BIT TO TEST FOR SEND MODSNDR EQU 1 ;VALUE WHEN READY MODRCVB EQU 2 ;BIT TO TEST FOR RECEIVE ERRCT ;..COUNT SENDRPT CALL SENDHDR ;SEND A HEADER CALL SENDSEC ;SEND DATA SECTOR CALL SENDCKS ;SEND CKSUM CALL GETACK ;GET THE ACK JC SENDRPT ;REPEAT IF NO ACK JMP SENDLP ;LOOP UNTIL EOF ; ;FILE SENT, SEND EOT'S ; SENDEOF MVI A,EOT ;SEND.. NDER, EXIT RET ;CARRY OFF - NO ERRORS ; ;PREV SECT REPEATED, DUE TO THE LAST ACK ;BEING GARBAGED. ACK IT SO SENDER WILL CATCH UP ; RECVACK CALL SENDACK ;SEND THE ACK, JMP RCVSECT ;GET NEXT BLOCK ; ;SEND AN ACK FOR THE SECTOR ; SENDACK MVI A,1 ;WAIT FOR 1 SEC.. CALL RECV ;..WITH NO CHARS JNC RCVSERR ;LOOP UNTIL SENDER DONE MVI A,NAK ;SEND.. CALL SEND ;..THE NAK LDA ERRCT ;ABORT IF.. INR A ;..WE HAVE REACHED.. STA ERRCT ;..THE ERROR.. CPI ERRLIM ;..LIMIT? JC RCVRPT ;..NO, TRYLETTER CMP M ;IS IT O ? JNZ CONTINU ;IF NOT, CONTINUE NORMALLY INX H ;GET 3RD LETTER MVI A,'M' ;3RD LETTER CMP M ;IS IT M ? JNZ CONTINU ;IF NOT, CONTINUE NORMALLY CALL ERXIT ;EXIT, PRINT ERROR MESSAGE DB '++CAN''T RECEIVE A .COM FILE++'OT ;TIMEOUT MOV M,A ;STORE CHAR INR L ;DONE? JNZ RCVCHR ;NO, LOOP ; ;VERIFY CHECKSUM ; MOV D,C ;SAVE CHECKSUM MVI B,1 ;TIMEOUT LEN. CALL RECV ;GET CHECKSUM JC RCVSTOT ;TIMEOUT CMP D ;CHECKSUM OK? JNZ RCVSERR ;NO, ERROR ; ;GOT A SECTOSET IF EOT RECEIVED. ; RCVSECT XRA A ;GET 0 STA ERRCT ;INIT ERROR COUNT ; RCVRPT MVI B,10 ;10 SEC TIMEOUT CALL RECV ;GET SOH/EOT JC RCVSTOT ;TIMEOUT CPI SOH ;GET SOH? JZ RCVSOH ;..YES ; ;EARLIER VERS. OF MODEM PROG SENT SOME NULLS - ;IGNOR CALL SEND ;..AN EOT CALL GETACK ;GET THE ACK JC SENDEOF ;LOOP IF NO ACK JMP EXIT ;ALL DONE ; * * * * * * * * * * * * * * * * * * * * * * * * RCVFIL: RECEIVE A FILE * * * * * * * * * * * * * * * * * * * * * * * * ; ;RECEIVES A FILE OCK # COMPLEMENTED ; RCVSOH MVI B,1 ;TIMEOUT = 1 SEC CALL RECV ;GET SECTOR JC RCVSTOT ;GOT TIMEOUT MOV D,A ;D=BLK # MVI B,1 ;TIMEOUT = 1 SEC CALL RECV ;GET CMA'D SECT # JC RCVSTOT ;TIMEOUT CMA ;CALC COMPLEMENT CMP D ;GOOD SECTOR #? JZ AGAIN ; ;10 ERRORS IN A ROW - ; RCVSABT CALL CLOSFIL ;KEEP WHATEVER WE GOT CALL ERXIT DB '++UNABLE TO RECEIVE BLOCK ' DB '- ABORTING++',CR,LF,'$' ; ;TIMEDOUT ON RECEIVE ; RCVSTOT JMP RCVSERR ;BUMP ERR CT, ETC. ; ;GOT SOH - GET BLOCK #, BL DB CR,LF,CR,LF DB 'Rename filetype ".OBJ" and try again' DB CR,LF,'$' ENDIF ; CONTINU CALL CHEKFIL ;SEE IF FILE EXISTS CALL MAKEFIL ;..THEN MAKE NEW CALL ILPRT ;PRINT: DB 'FILE OPEN, READY TO RECEIVE',CR,LF,0 ; RCVLP CALL RCVSECT ;GET A R, IT'S A DUP IF = PREV, ; OR OK IF = 1 + PREV SECTOR ; LDA RCVSNO ;GET RECEIVED MOV B,A ;SAVE IT LDA SECTNO ;GET PREV CMP B ;PREV REPEATED? JZ RECVACK ;ACK TO CATCH UP INR A ;CALC NEXT SECTOR # CMP B ;MATCH? JNZ ABORT ;NO MATCH - STOP SEE THEM ; ORA A ;00 FROM SPEED CHECK? JZ RCVRPT ;YES, IGNORE IT CPI EOT ;END OF TRANSFER? STC ;RETURN WITH CARRY.. RZ ;..SET IF EOT ; ;DIDN'T GET SOH OR EOT - ; ;DIDN'T GET VALID HEADER - PURGE THE LINE, ;THEN SEND NAK. ; RCVSERR MVI BIN BLOCK FORMAT AS SENT ;BY ANOTHER PERSON DOING "MODEM S FN.FT". ; RCVFIL EQU $ ; IF NOCOM LXI H,FCB+9 ;POINT TO FILETYPE MVI A,'C' ;1ST LETTER CMP M ;IS IT C ? JNZ CONTINU ;IF NOT, CONTINUE NORMALLY INX H ;GET 2ND LETTER MVI A,'O' ;2ND RCVDATA ;YES, GET DATA ; ;GOT BAD SECTOR # ; JMP RCVSERR ;BUMP ERROR CT. ; RCVDATA MOV A,D ;GET SECTOR # STA RCVSNO ;SAVE IT MVI C,0 ;INIT CKSUM LXI H,BASE+80H ;POINT TO BUFFER ; RCVCHR MVI B,1 ;1 SEC TIMEOUT CALL RECV ;GET CHAR JC RCVSTCK THE SECTOR CALL CLOSFIL ;CLOSE THE FILE JMP EXIT ;ALL DONE ; * * * * * * * * * * * * * * * * * * * * * * * * SUBROUTINES * * * * * * * * * * * * * * * * * * * * * * * * ; ; ;----> RCVSECT: RECEIVE A SECTOR ; ;RETURNS WITH CARRY SECTOR JC RCVEOT ;GOT EOT CALL WRSECT ;WRITE THE SECTOR CALL INCRSNO ;BUMP SECTOR # CALL SENDACK ;ACK THE SECTOR JMP RCVLP ;LOOP UNTIL EOF ; ;GOT EOT ON SECTOR - FLUSH BUFFERS, END ; RCVEOT CALL WRBLOCK ;WRITE THE LAST BLOCK CALL SENDACK ;A,ACK ;GET ACK CALL SEND ;..AND SEND IT RET ; ;----> SENDHDR: SEND THE SECTOR HEADER ; ;SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #) ; SENDHDR MVI A,SOH ;SEND.. CALL SEND ;..SOH, LDA SECTNO ;THEN SEND.. CALL SEND ;..SECTOR # LDA SECTNO ;TH ;----> CLOSFIL: CLOSES THE RECEIVED FILE ; CLOSFIL LXI D,FCB ;POINT TO FILE MVI C,CLOSE ;GET FUNCTION CALL BDOS ;CLOSE IT INR A ;CLOSE OK? RNZ ;..YES, RETURN CALL ERXIT ;..NO, ABORT DB '++CAN''T CLOSE FILE++',CR,LF,'$' ; ;----> RDSECT: R BE RECEIVED ; MAKEFIL LXI D,FCB ;POINT TO FCB MVI C,MAKE ;GET BDOS FNC CALL BDOS ;TO THE MAKE INR A ;FF=BAD? RNZ ;OPEN OK ;DIRECTORY FULL - CAN'T MAKE FILE CALL ERXIT DB '++ERROR - CAN''T MAKE FILE++',CR,LF DB 'Directory must be full',CRCEIVED. ;IF AN ACK IS NOT RECEIVED, THE ERROR COUNT ;IS INCREMENTED, AND IF LESS THAN "ERRLIM", ;CARRY IS SET AND CONTROL RETURNS. IF THE ;ERROR COUNT IS AT "ERRLIM", THE PROGRAM ;ABORTS. ; GETACK MVI B,10 ;WAIT 10 SECONDS MAX CALL RECVDG ;RECV W MOV A,M ;CHK NEXT CHAR ANI 7FH ;STRIP ATTRIBUTES CPI 'O' ; 'O'? JNZ OPENOK3 ;IF NOT, OK TO SEND DCX H MOV A,M ;NOW CHK FIRST CHAR ANI 7FH ;STRIP ATTRIBUTES CPI 'C' ; 'C' AS IN '.COM'? JNZ OPENOK3 ;IF NOT, CONTINUE CALL ERXIT ;EXIT W/MESORT MSG DB 'XMODEM PROGRAM CANCELLED',CR,LF,'$' ; ;----> INCRSNO: INCREMENT SECTOR # ; INCRSNO LDA SECTNO ;INCR.. INR A ;..SECT.. STA SECTNO ;..NUMBER RET ; ;----> CHEKFIL: SEE IF FILE EXISTS ; ;IF IT EXISTS, SAY IT MUST BE ERASED. ; CHEKEN SECTOR # CMA ;..COMPLEMENTED.. CALL SEND ;..SECTOR # RET ;FROM SENDHDR ; ;----> SENDSEC: SEND THE DATA SECTOR ; SENDSEC MVI C,0 ;INIT CKSUM LXI H,BASE+80H ;POINT TO BUFFER SENDC MOV A,M ;GET A CHAR CALL SEND ;SEND IT INR L ;POINT TO NSTRIBUTION-PROTECTED FILE ; OPENOK LDA FCB+1 ;FIRST CHAR OF FILE NAME ANI 80H ;CHECK BIT 7 JZ OPENOK2 ;IT WAS OFF, FILE CAN BE SENT ; OPENOT CALL ERXIT ;EXIT W/MESSAGE DB '++THIS FILE IS NOT FOR DISTRIBUTION, SORRY++' DB CR,LF,'$' ; OPENOK2 E,LF,'$' ; ;----> OPENFIL: OPENS THE FILE TO BE SENT ; OPENFIL LXI D,FCB ;POINT TO FILE MVI C,OPEN ;GET FUNCTION CALL BDOS ;OPEN IT INR A ;OPEN OK? JNZ OPENOK ;..YES CALL ERXIT ;..NO, ABORT DB '++FILE NOT FOUND++',CR,LF,'$' ; ;CHECK FOR DI/GARBAGE COLLECT JC GETATOT ;TIMED OUT CPI ACK ;OK? (CARRY OFF IF =) RZ ;YES, RET FROM GETACK ; ;TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT ; ACKERR LDA ERRCT ;GET COUNT INR A ;BUMP IT STA ERRCT ;SAVE BACK CPI ERRLIM ;AT LIMIT? RC ;NOT SAGE DB '++CAN''T SEND A .COM FILE++' DB CR,LF,'$' ENDIF ; OPENOK3 CALL ILPRT ;PRINT: DB 'FILE OPEN, EXTENT LENGTH: ',0 LDA FCB+15 ;GET # SECTORS CALL HEXO ;PRINT IN HEX CALL ILPRT ;PRINT H AFTER NUMBER, THEN CR,LF DB 'H',CR,LF,0 RET ;FIL LXI D,FCB ;POINT TO CTL BLOCK MVI C,SRCHF ;SEE IF IT.. CALL BDOS ;..EXISTS INR A ;FOUND? RZ ;..NO, RETURN CALL ERXIT ;EXIT, PRINT ERROR MESSAGE DB '++FILE EXISTS, USE A DIFFERENT NAME++' DB CR,LF,'$' ; ;----> MAKEFIL: MAKES THE FILE TOEXT CHAR JNZ SENDC ;LOOP IF <100H RET ;FROM SENDSEC ; ;----> SENDCKS: SEND THE CHECKSUM ; SENDCKS MOV A,C ;SEND THE.. CALL SEND ;..CHECKSUM RET ;FROM SENDCKS ; ;----> GETACK: GET THE ACK ON THE SECTOR ; ;RETURNS WITH CARRY CLEAR IF ACK REQU $ ; IF NOCOM LXI H,FCB+11 MOV A,M ;CHECK FOR PROTECT ATTR ANI 7FH ;REMOVE CP/M 2.x ATTRS CPI '#' ;CHK FOR '#' AS LAST FIRST JZ OPENOT ;IF '#', CAN'T SEND, SHOW WHY CPI 'M' ;IF NOT, CHK FOR '.COM' JNZ OPENOK3 ;IF NOT, OK TO SEND DCX H TL ;LOOP UNTIL SENDER DONE MVI A,CAN ;CONTROL X CALL SEND ;STOP SENDING END ; ABORTW MVI B,1 ;1 SEC W/O CHARS. CALL RECV JNC ABORTW ;LOOP UNTIL SENDER DONE MVI A,' ' ;GET A SPACE... CALL SEND ;TO CLEAR OUT CONTROL X CALL ERXIT ;EXIT WITH ABAT LIMIT ; ;REACHED ERROR LIMIT ; CSABORT CALL ERXIT DB '++CAN''T SEND SECTOR ' DB '- ABORTING++',CR,LF,'$' ; ;TIMEOUT GETTING ACK ; GETATOT JMP ACKERR ;NO MSG ; ABORT LXI SP,STACK ; ABORTL MVI B,1 ;1 SEC. W/O CHARS. CALL RECV JNC ABOREADS A SECTOR ; ;FOR SPEED, THIS ROUTINE BUFFERS UP 16 ;SECTORS AT A TIME. ; RDSECT LDA SECINBF ;GET # SECT IN BUFF. DCR A ;DECREMENT.. STA SECINBF ;..IT JM RDBLOCK ;EXHAUSTED? NEED MORE. LHLD SECPTR ;GET POINTER LXI D,BASE+80H ;TO DATA C ; ;----> SEND: SEND A CHARACTER TO THE MODEM ; SEND PUSH PSW ;SAVE THE CHAR ADD C ;CALC CKSUM MOV C,A ;SAVE CKSUM ; IF NOT DCH SENDW IN MODCTLP ;GET STATUS ENDIF ; IF DCH SENDW IN MODCTL2 ;GET STATUS ENDIF ; ANI MODSNDB ;ISOLATE REAA ;GET A ZERO STA SECINBF ;RESET # OF SECTORS LXI H,DBUF ;RESET BUFFER.. SHLD SECPTR ;..POINTER ; RSDMA LXI D,BASE+80H ;RESET.. MVI C,STDMA ;..DMA.. CALL BDOS ;..ADDR RET ; WRERR CALL RSDMA ;RESET DMA TO NORM. MVI C,CAN ;CANCEL.. CALL SB '++FILE READ ERROR',CR,LF,'$' ; RDSECOK LXI H,80H ;ADD LENGTH OF ONE SECTOR... DAD D ;...TO NEXT BUFF XCHG ;BUFF TO DE INR C ;MORE SECTORS? MOV A,C ;GET COUNT CPI 16 ;DONE? JZ RDBFULL ;..YES, BUFF IS FULL JMP RDSECLP ;READ MORE ; REOF TE BIT CPI MODRCVR ;READY? JZ MCHAR ;GOT CHAR DCR E ;COUNT.. JNZ MWTI ;..DOWN.. DCR D ;..FOR.. JNZ MWTI ;..TIMEOUT DCR B ;MORE SECONDS? JNZ MSEC ;YES, WAIT ; ;MODEM TIMED OUT RECEIVING ; POP D ;RESTORE D,E STC ;CARRY SHOWS TIMEOUT WRITES A BLOCK TO DISK ; WRBLOCK LDA SECINBF ;# SECT IN BUFFER ORA A ;0 MEANS END OF FILE RZ ;NONE TO WRITE MOV C,A ;SAVE COUNT LXI D,DBUF ;POINT TO DISK BUFF ; DKWRLP PUSH H PUSH D PUSH B MVI C,STDMA ;SET DMA CALL BDOS ;TO BUFFER LALL MOVE128 ;MOVE TO BUFFER SHLD SECPTR ;SAVE BUFFER POINTER RET ;FROM "READSEC" ; ;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 16 ; RDBLOCK LDA EOFLG ;GED EOF FLAG CPI 1 ;IS IT SET/ STC ;TO SHOW EOF RZ ;GOT EOF MVI C,0 ;SECTORS IN BLOCK TOR, ;CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED ;CHARACTERS "LONG" BEFORE THE ACK/NAK WOULD ;BE RECEIVED. ; RECVDG EQU $ ;RECEIVE W/GARBAGE DELETE IN MODDATP ;GET A CHAR IN MODDATP ;..TOTALLY PURGE UART ; RECV PUSH D ;SAVE ; IF FASTCLEND ;..SENDER CALL ERXIT ;EXIT W/MSG: DB '++ERROR WRITING FILE++',CR,LF,'$' ; ;----> RECV: RECEIVE A CHARACTER ; ;TIMEOUT TIME IS IN B, IN SECONDS. ENTRY VIA ;"RECVDG" DELETES GARBAGE CHARACTERS ON THE ;LINE. FOR EXAMPLE, HAVING JUST SENT A SECMVI A,1 STA EOFLG ;SET EOF FLAG MOV A,C ; ;BUFFER IS FULL, OR GOT EOF ; RDBFULL STA SECINBF ;STORE SECTOR COUNT LXI H,DBUF ;INIT BUFFER.. SHLD SECPTR ;..POINTER LXI D,BASE+80H ;RESET.. MVI C,STDMA ;..DMA.. CALL BDOS ;..ADDR JMP RDSECT ; RET ; ;GOT CHAR FROM MODEM ; MCHAR IN MODDATP ;READ THE CHAR POP D ;RESTORE DE ; ;CALC CHECKSUM ; PUSH PSW ;SAVE THE CHAR ADD C ;ADD TO CHECKSUM MOV C,A ;SAVE CHECKSUM POP PSW ;RESTORE CHAR ORA A ;CARRY OFF: NO ERROR RET ;FROM "RECV"XI D,FCB ;THEN WRITE MVI C,WRITE ;..THE.. CALL BDOS ;..BLOCK POP B POP D POP H ORA A JNZ WRERR ;OOPS, ERROR LXI H,80H ;LENGTH OF 1 SECT DAD D ;HL= NEXT BUFF XCHG ;TO DE FOR SETDMA DCR C ;MORE SECTORS? JNZ DKWRLP ;..YES, LOOP XRA LXI D,DBUF ;TO DISK BUFFER RDSECLP PUSH B PUSH D MVI C,STDMA ;SET DMA.. CALL BDOS ;..ADDR LXI D,FCB MVI C,READ CALL BDOS POP D POP B ORA A ;READ OK? JZ RDSECOK ;YES DCR A ;EOF? JZ REOF ;GOT EOF ; ;READ ERROR ; CALL ERXIT DK ;4MHZ? MOV A,B ;GET TIME REQUEST ADD A ;DOUBLE IT MOV B,A ;NEW TIME IN B ENDIF ; MSEC LXI D,50000 ;1 SEC DCR COUNT ; IF NOT DCH MWTI IN MODCTLP ;CHECK STATUS ENDIF ; IF DCH MWTI IN MODCTL2 ;CHECK STATUS ENDIF ; ANI MODRCVB ;ISOLAOR MOVE LXI H,BASE+80H ;FROM HERE CALL MOVE128 ;MOVE TO BUFFER XCHG ;SAVE NEXT.. SHLD SECPTR ;..BLOCK POINTER LDA SECINBF ;BUMP THE.. INR A ;..SECTOR #.. STA SECINBF ;..IN DHE BUFF CPI 16 ;HAVE WE 16? RNZ ;NO, RETURN ; ;----> WRBLOCK:PASS SECT TO CALLER ; ;----> WRSECT: WRITE A SECTOR ; ;WRITES THE SECTOR INTO A BUFFER. WHEN 16 ;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK. ; ;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF. ; WRSECT LHLD SECPTR ;GET BUFF ADDR XCHG ;TO DE FDY BIT CPI MODSNDR ;READY? JNZ SENDW ;..NO, WAIT POP PSW ;GET CHAR OUT MODDATP ;OUTPUT IT RET ;FROM "SEND" ; ;----> WAITNAK: WAITS FOR INITIAL NAK ; ;TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING ;PROGRAM IS READY, THIS ROUTINE WAITS FOR THRY STORAGE AREA ; RCVSNO DB 0 ;SECT # RECEIVED SECTNO DB 0 ;CURRENT SECTOR NUMBER ERRCT DB 0 ;ERROR COUNT ;FOLLOWING 3 USED BY DISK BUFFERING ROUTINES EOFLG DB 0 ;EOF FLAG (1=TRUE) SECPTR DW DBUF SECINBF DB 0 ;# OF SECTORS IN BUFFER DS 60 ;STACKST ; MOVEFCB LXI H,FCB+16 ;FROM LXI D,FCB ;TO MVI B,16 ;LEN CALL MOVE ;DO THE MOVE XRA A ;GET 0 STA FCBSNO ;ZERO SECTOR # STA FCBEXT ;..AND EXTENT RET ; CTYPE PUSH B ;SAVE.. PUSH D ;..ALL.. PUSH H ;..REGS MOV E,A ;CHAR TO E MVI C, HL RET ;PAST MSG ; ;----> ERXIT: EXIT PRINTING MSG FOLLOWING CALL ; ERXIT POP D ;GET MESSAGE MVI C,PRINT ;GET BDOS FNC CALL BDOS ;PRINT MESSAGE ; EXIT LHLD STACK ;GET ORIGINAL STACK SPHL ;RESTORE IT RET ;--EXIT-- TO CP/M ; ;MOVE 128 CE ;THE FIRST TIMEOUT-NAK FROM THE RECEIVER. ;(E) CONTAINS THE # OF SECONDS TO WAIT. ; WAITNAK MVI B,1 ;TIMEOUT DELAY CALL RECV ;DID WE GET.. CPI NAK ;..A NAK? RZ ;YES, SEND BLOCK DCR E ;80 TRIES? JZ ABORT ;YES, ABORT JMP WAITNAK ;NO, LOOP QU 17 ; " " SRCHN EQU 18 ; " " ERASE EQU 19 ;NO RET CODE READ EQU 20 ;0=OK, 1=EOF WRITE EQU 21 ;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC MAKE EQU 22 ;0FFH=BAD REN EQU 23 ;0FFH=BAD STDMA EQU 26 ;SET DMA BDOS EQU BASE+5 FCB EQU BASE+5CH ;SYSTEM FCB FCBEXT AREA STACK DS 2 ;STACK POINTER ; ;16 SECTOR DISK BUFFER ; DBUF EQU $ ;16 SECTOR DISK BUFFER ; ; BDOS EQUATES (VERSION 2) ; RDCON EQU 1 WRCON EQU 2 PRINT EQU 9 CONST EQU 11 ;CONSOLE STAT OPEN EQU 15 ;0FFH=NOT FOUND CLOSE EQU 16 ; " " SRCHF EWRCON ;GET BDOS FNC CALL BDOS ;PRIN THE CHR POP H ;RESTORE.. POP D ;..ALL.. POP B ;..REGS RET ;FROM "CTYPE" ; HEXO PUSH PSW ;SAVE FOR RIGHT DIGIT RAR ;RIGHT.. RAR ;..JUSTIFY.. RAR ;..LEFT.. RAR ;..DIGIT.. CALL NIBBL ;PRINT LEFT DHARACTERS ; MOVE128 MVI B,128 ;SET MOVE COUNT ; ;MOVE FROM (HL) TO (DE) LENGTH IN (B) ; MOVE MOV A,M ;GET A CHAR STAX D ;STORE IT INX H ;TO NEXT "FROM" INX D ;TO NEXT "TO" DCR B ;MORE? JNZ MOVE ;..YES, LOOP RET ;..NO, RETURN ; ;TEMPORA ; ;----> MOVEFCB: MOVES FCB(2) TO FCB ; ;I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL', ;I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER ;THAN MODEM FILENAME SEND (MODEM FN.FT S) SO THIS ;ROUTINE MOVES THE FILENAME FROM THE SECOND FCB ;TO THE FIR EQU FCB+12 ;FILE EXTENT FCBSNO EQU FCB+32 ;SECTOR # FCB2 EQU BASE+6CH ;SECOND FCB ; END R SPC MAKE EQU 22 ;0FFH=BAD REN EQU 23 ;0FFH=BAD STDMA EQU 26 ;SET DMA BDOS EQU BASE+5 FCB EQU BASE+5CH ;SYSTEM FCB FCBEXTT IS FOLLOWED BY A MESSAGE, ;BINARY 0 AS THE END. ; ILPRT XTHL ;SAVE HL, GET HL=MSG ; ILPLP MOV A,M ;GET CHAR ORA A ;END OF MSG? JZ ILPRET ;..YES, RETURN CALL CTYPE ;TYPE THE MSG INX H ;TO NEXT CHAR JMP ILPLP ;LOOP ; ILPRET XTHL ;RESTOREIGIT POP PSW ;RESTORE RIGHT ; NIBBL ANI 0FH ;ISOLATE DIGIT CPI 10 ;IS IS <10? JC ISNUM ;YES, NOT ALPHA ADI 7 ;ADD ALPHA BIAS ; ISNUM ADI '0' ;MAKE PRINTABLE JMP CTYPE ;..THEN TYPE IT ; ;----> ILPRT: INLINE PRINT OF MSG ; ;THE CALL TO ILPR; ; ; THESE ARE UNDOCUMENTED Z80 CODES. THEY ALLOW 8-BIT ; OPERATIONS WITH THE IX AND IY REGISTERS. ; OTHER CODES ALLOW A SHIFT-LEFT-AND-SET-LSB OPERATION ; TO ANY REGISTER ; XX EQU 0DDH YY EQU 0FDH ; MOVAHX MACRO DB XX MOV A,H ENDM MOVBHXCONTAINING THE SOURCE, ASSEMBLY/COMPILATION/LINKAGE COMMAND FILES, OBJECT CODE, AND ANY OTHER MACHINE READABLE DOCUMENTATION. PLEASE USE THE FOLLOWING FILE EXTENSIONS: .ASM .SOURCE FILE OR .BAS, .Z80, .FORM YRALY MACRO DB YY YRA L ENDM ORAHY MACRO DB YY ORA H ENDM ORALY MACRO DB YY ORA L ENDM CMPHY MACRO DB YY CMP H ENDM CMPLY MACRO DB YY CMP L ENDM ; INRHX MACRO DB XX INR H ENDM INRLX MACRO DB XX INR L ENDMACRO DB YY MOV C,H ENDM MOVDHY MACRO DB YY MOV D,H ENDM MOVEHY MACRO DB YY MOV E,H ENDM MOVLHY MACRO DB YY MOV L,H ENDM MOVALY MACRO DB YY MOV A,L ENDM MOVBLY MACRO DB YY MOV B,L ENDM MOVCLY MACRO DB YY MOV C,L......... STATE .......... ZIP ....... PHONE ..................... CLUB AFFILIATION ................... NAME OF PROGRAM, PROCEDURE, OR MODULE (CIRCLE ONE) SOURCE LANGUAGE ................ HARDWARE REQUIRED ............ ENDM ORALX MACRO DB XX ORA L ENDM CMPHX MACRO DB XX CMP H ENDM CMPLX MACRO DB XX CMP L ENDM ; ADDHY MACRO DB YY ADD H ENDM ADDLY MACRO DB YY ADD L ENDM ADCHY MACRO DB YY ADC H ENDM ADCLY MACRO DB YY ADC L MACRO DB XX MOV B,H ENDM MOVCHX MACRO DB XX MOV C,H ENDM MOVDHX MACRO DB XX MOV D,H ENDM MOVEHX MACRO DB XX MOV E,H ENDM MOVLHX MACRO DB XX MOV L,H ENDM MOVALX MACRO DB XX MOV A,L ENDM MOVBLX MACRO DB XX MOV B ENDM B XX DCR L ENDM DCRHY MACRO DB YY DCR H ENDM DCRLY MACRO DB YY DCR L ENDM ; SLAS MACRO ?R DB 0CBH,30H + ?R INRHY MACRO DB YY INR H ENDM INRLY MACRO DB YY INR L ENDM ; DCRHX MACRO DB XX DCR H ENDM DCRLX MACRO DB XX DCR L ENDM DCRHY MACRO DB YY DCR H ENDM DCRLY MACRO DB YY DCR L ENDM ; SLAS MACRO ?R DB 0CBH,30H + ?R ENDM MOVDLY MACRO DB YY MOV D,L ENDM MOVELY MACRO DB YY MOV E,L ENDM MOVHLY MACRO DB YY MOV H,L ENDM ; MVIHX MACRO ?NN DB XX MVI H,?NN ENDM MVILX MACRO ?NN DB XX MVI L,?NN ENDM MVIHY MACRO ?NN DB YY MVI H,?NN E. MEMORY REQUIRED .......... ............................... DESCRIPTION OF WHAT IT DOES: HOW TO USE IT: PLEASE ATTACH ALL RELEVANT DOCUMENTATION AND A DISKETTE ENDM SUBHY MACRO DB YY SUB H ENDM SUBLY MACRO DB YY SUB L ENDM SBBHY MACRO DB YY SBB H ENDM SBBLY MACRO DB YY SBB L ENDM ANAHY MACRO DB YY ANA H ENDM ANALY MACRO DB YY ANA L ENDM YRAHY MACRO DB YY YRA H END,L ENDM MOVCLX MACRO DB XX MOV C,L ENDM MOVDLX MACRO DB XX MOV D,L ENDM MOVELX MACRO DB XX MOV E,L ENDM MOVHLX MACRO DB XX MOV H,L ENDM ; MOVAHY MACRO DB YY MOV A,H ENDM MOVBHY MACRO DB YY MOV B,H ENDM MOVCHY M CONTRIBUTION FORM FOR SIG/M LIBRARY NAME ..................................... DATE...../...../..... ADDRESS ......................................................... CITY .....................B L ENDM SBBHX MACRO DB XX SBB H ENDM SBBLX MACRO DB XX SBB L ENDM ANAHX MACRO DB XX ANA H ENDM ANALX MACRO DB XX ANA L ENDM XRAHX MACRO DB XX XRA H ENDM XRALX MACRO DB XX XRA L ENDM ORAHX MACRO DB XX ORA H NDM MVILY MACRO ?NN DB YY MVI L,?NN ENDM ; ADDHX MACRO DB XX ADD H ENDM ADDLX MACRO DB XX ADD L ENDM ADCHX MACRO DB XX ADC H ENDM ADCLX MACRO DB XX ADC L ENDM SUBHX MACRO DB XX SUB H ENDM SUBLX MACRO DB XX SU, .COB, ETC. .DOC .DOCUMENTATION OR .TXT, .ABS, ETC. .COM .OBJECT CODE THE SUBMITTED FILES ARE IN THEIR PRESENT REVISION LEVEL, .... TO THE BEST OF MY KNOWLEDGE CURRENTLY IN PUBLIC DOMAIrequired !! which is NOT on this disk? Timing dependencies? !! !! "STANDARD CP/M" means it runs with 8" disks (or similarly !! behaving ones like Northstar), 24K or more memory, CP/M 1.4. !! !! Do you think/know it works with: CP/M 2.0? Source prtk National CP/M Users Group - Program Submission Form Submission Date: File name: !! (or names). Include a 1 line description of each !! !! examples... !! !! MORSE.ASM Sends Morse code from ASCII file to port. !! SAMPLE.DAT Sample data fiere is further documentation available: !! E.G. name the appropriate .DOC files on this disk; !! Was anything published in a magazine, etc. !! Is this a modification of a previous Users Group program, !! and if so, what was its "name" (e.g. 23.05) for each !! program. (You may group similar programs together). !! All lines starting !! are comments which should be !! deleted from the form. Remember to keep an original !! of the form around for submitting more than one program. !! !! This forN .... UNDER MY DIRECT CONTROL HEREBY PLACED INTO PUBLIC DOMAIN. PERMISSION IS HEREBY GRANTED TO SIG/M TO DISTRIBUTE THE FILES FOR NON-COMMERCIAL PERSONAL USE. t that author). Also include address !! and phone if different. This program is public domain because: !! E.G. Submitted by author; author's approval, !! approval from magazine in which it was published, etc. Who would this program be useful tole for MORSE. Author: !! Please include address and phone number. If either !! is not to be published, so indicate, but include !! them for the Users Group disk cataloging process, !! in case there are questions. Submitted by: !! (if differen!! Created 02/21/80 WLC !! Last Rev. 02/22/80 WLC !! !! If you have any comments on this form please pass !! them on to the CP/M users group. !! !! Please fill out this form for all material submitted !! to the CP/M users group. It will aid in the Hardware dependencies: !! E.G. specific processor, disk controller, plotter, printer, !! modem, viedo board, etc. Software dependencies: !! E.G. I/O via PROM calls, or hard-coded ports; JMPS/CALLS !! to specific machine-size BIOS; Other software m is most easily filled out with a full screen !! editor. You may do a "macro next colon" (mn:$v) to locate !! the fields which have to be filled in. !! !! Save this file as "filename.CPM" !! !! You can then delete all comments lines via... bmn!!$0l SIGNED................................ DATE.................................. MAIL DISKETTE SIG/M AND FORM TO: P.O. BOX 97 ISELIN, NJ 08830 : !! e.g. "All CP/M users" or "People with Tarbell floppy !! controllers" or "People with one-disk systems" etc. Briefly describe the program function: !! Include run instructions only if not included in !! some other .DOC file on this disk. Wh't mind, there are still a lot of us out here !! with 64 wide displays. We would appreciate your limiting !! your lines to 63 characters. <>) !! !! It is intended that this form be filled out with an !! editor, and left on the submitted disk !! cataloging of the disks, and in helping people choose !! which programs they might be interested in. !! !! Send the contributions with the completed forms to: !! !! CP/M Users Group !! 1651 Third Avenue !! New York, NY 10028 !! !! (If you donocessor: !! I.E. if this is a source program, what do you "run it !! with"... MAC, ASM, Microsoft BASIC version x.y, TDL ASM etc. Does the software "drop in": !! i.e. what type of modifications are required to make !! it run? How easy is the code to modify: !! E.G. "COM file only" !! "Well commented .ASM file" !! "Poorly commented .ASM file" etc. Does the software "drop in": !! i.e. what type of modifications are required to make !! it run? How easy is the co