;------------------------------------------------------------------------------ ; ; FR2.ASM FILE RECEIVER ; ; FR 2.1 Revised July 6, 1986 ;------------------------------------------------------------------------------ ; ; Rod Clark ; Box 47205 ; Seattle WA 98146 ; ;------------------------------------------------------------------------------ ; LF EQU 10 CR EQU 13 XON EQU 17 XOFF EQU 19 ESC EQU 27 ; CAPMASK EQU 5FH ; BDOS EQU 5 CONINBYTE EQU 1 CONOUTBYTE EQU 2 DIRIO EQU 6 INFLAG EQU 0FFH CONINSTR EQU 10 OPENFILE EQU 15 CLOSEFILE EQU 16 ERASEFILE EQU 19 WRITESEQ EQU 21 MAKEFILE EQU 22 SETDMA EQU 26 ; ;------------------------------------------------------------------------------ ; MEMBASE EQU 0600H ;0100H BOUNDARY JUST ABOVE PROGRAM = RAM BUFFER BASE ; ORG 0100H JMP START ; ;============================================================================== ; ; **** USER CONFIGURATION ++++ ; ; ;SYSMSG: DB 'For 56k VECTOR SYSTEM B with BITSTREAMER II I/O board',CR,LF ; DB 0 ; ;DATAPORT EQU 6 ;BITSTREAMER II I/O BOARD ;STATPORT EQU 7 ; ;TXRDY EQU 1 ;STATUS PORT BIT 0, 8251 USART ;RXRDY EQU 2 ;STATUS PORT BIT 1 ; ;CCP EQU 0C000H ;8k UNDER 56k CP/M ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; SYSMSG: DB 'For 64k MORROW MD2/MD3',CR,LF DB 0 ; DATAPORT EQU 254 STATPORT EQU 255 ; TXRDY EQU 1 ;STATUS PORT BIT 0, 8251 USART RXRDY EQU 2 ;STATUS PORT BIT 1 ; CCP EQU 0DC00H ;9k UNDER 64k CP/M ; ;============================================================================== ; IN$BUFFER: DB 16 ;BUFFER FOR BDOS 10 CONINSTR IN$COUNT: DB 0 IN$STR: DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0 DB 0,0 ; FCB: FCB$DRV: DB 0 FCB$NAME: DB 0,0,0,0,0,0,0,0 FCB$EXT: DB 0,0,0 DB 0,0,0,0 FCB$RDRV: DB 0 FCB$RNAME: DB 0,0,0,0,0,0,0,0 FCB$REXT: DB 0,0,0 DB 0,0,0,0 DB 0,0,0,0 ; OLDSTAK DS 2 ;STACK POINTER PRIOR TO PROGRAM ; MEMBYTE DS 2 ;CURRENT BYTE IN BUFFER MEMTAIL DS 2 ;NEXT BYTE PAST END OF FILE IN BUFFER MEMROOF DS 2 ;0100H BOUNDARY 2ND BELOW START OF CCP = BUFFER ROOF ; ;------------------------------------------------------------------------------ ; START: LXI H,0 ;SAVE OLD STACK POINTER DAD SP SHLD OLDSTAK ; LXI H,CCP ;SET PROGRAM STACK JUST UNDER CCP DCX H SPHL ; DCR H ;SET BUFFER ROOF ON 2ND LOWER 0100H BOUNDARY MVI L,0 SHLD MEMROOF ; LXI H,MEMBASE SHLD MEMBYTE ; CALL WRITE$CON DB CR,LF DB CR,LF DB CR,LF DB CR,LF DB CR,LF DB CR,LF DB CR,LF DB CR,LF DB CR,LF DB 'FILE RECEIVER 2.1',CR,LF DB 'Emulates serial printer --- ' DB 'issues XOFF/XON when buffer full/ready',CR,LF DB 0 ; LXI D,SYSMSG CALL MSG$CON ; CALL WRITE$CON DB CR,LF DB CR,LF DB ' Receiving end: ','Sending end:',CR,LF DB CR,LF DB ' 1) Filename: D:FILENAME.EXT ',CR,LF DB ' ','2) PIP LST: = D:FILENAME.EXT[o] ',CR,LF DB ' ','3) Wait for A> to reappear',CR,LF DB ' 4) Press to save to disk',CR,LF DB ' 5) Filename: if finished',CR,LF DB 0 ; PROMPT: CALL WRITE$CON DB CR,LF DB CR,LF DB 'Filename: ' DB 0 ; MVI C,CONINSTR LXI D,IN$BUFFER CALL BDOS ; LDA IN$BUFFER+1 ;CHECK FOR USER EXIT (zero length input string) CPI 0 JZ EXIT ; LXI D,FCB ;MAKE FCB FROM FILENAME BUFFER LXI H,IN$BUFFER CALL FC$BUFF ; MVI C,OPENFILE LXI D,FCB CALL BDOS CPI 0FFH ;IS FILENAME UNUSED? JZ NEWFILE ; CALL WRITE$CON DB CR,LF DB 'FILE EXISTS --- Overwrite? Y / N ' DB 0 ; KEYWAIT: MVI C,DIRIO MVI E,INFLAG CALL BDOS CPI 0 JZ KEYWAIT ; ANI CAPMASK CPI 'Y' JZ ECHOYES ; CALL WRITE$CON DB 'No' DB 0 ; JMP PROMPT ; ECHOYES: ; CALL WRITE$CON DB 'Yes' DB 0 ; MVI C,ERASEFILE LXI D,FCB CALL BDOS ; NEWFILE: MVI C,MAKEFILE LXI D,FCB CALL BDOS ; CALL WRITE$CON DB CR,LF DB 0 ; ;------------------------------------------------------------------------------ ; TRANSMIT: IN STATPORT ANI TXRDY JZ RECEIVE ; MVI C,DIRIO ;CHECK CONSOLE MVI E,INFLAG CALL BDOS CPI 0 ;CONSOLE IDLE? JZ RECEIVE ; CPI ESC JZ USERSAVE ; OUT DATAPORT ; MVI C,DIRIO ;ECHO KEYBOARD CHAR TO SCREEN MOV E,A CALL BDOS ; RECEIVE: IN STATPORT ANI RXRDY JZ TRANSMIT ; IN DATAPORT ; LHLD MEMBYTE ;STORE INCOMING BYTE IN RAM BUFFER MOV M,A INX H SHLD MEMBYTE ; LDA MEMROOF+1 ;END OF SPACE IN BUFFER? CMP H JNZ TRANSMIT ; CALL AUTOSAVE JMP TRANSMIT ; ;------------------------------------------------------------------------------ ; CLOSE: MVI C,CLOSEFILE LXI D,FCB CALL BDOS ; JMP PROMPT ; ;------------------------------------------------------------------------------ ; EXIT: CALL WRITE$CON DB CR,LF DB CR,LF DB 0 ; LHLD OLDSTAK ;AVOID SYSTEM REBOOT SPHL RET ;TH..TH.. THAT'S ALL, FOLKS ; ;------------------------------------------------------------------------------ ; DISKFULL: CALL WRITE$CON DB CR,LF DB 'DISK OR DIRECTORY FULL --- partial file saved',CR,LF DB 0 ; JMP EXIT ; ;------------------------------------------------------------------------------ ; USERSAVE: CALL SAVE JMP CLOSE ; ;------------------------------------------------------------------------------ ; AUTOSAVE: MVI A,XOFF OUT DATAPORT ; CALL SAVE ; MVI A,XON OUT DATAPORT ; RET ; ;------------------------------------------------------------------------------ ; SAVE: LHLD MEMBYTE SHLD MEMTAIL ; LXI H,MEMBASE SHLD MEMBYTE ; SAVELOOP: LDA MEMTAIL+1 ;NEAR END OF FILE? CMP H JNZ SAVEONE ; LDA MEMTAIL ;END OF FILE? CMP L JZ SAVEOUT ; SAVEONE: MVI C,SETDMA ;set RAM block start XCHG ;HL current address -> DE CALL BDOS ; MVI C,WRITESEQ ;write 128 bytes from RAM to disk LXI D,FCB CALL BDOS CPI 0 JNZ DISKFULL ; LHLD MEMBYTE ;compute next dma address LXI D,128 DAD D SHLD MEMBYTE ; JMP SAVELOOP ; SAVEOUT: LXI H,MEMBASE ;POINT BACK TO RAM BASE SHLD MEMBYTE RET ; ;------------------------------------------------------------------------------ ; clark,r 5-4-86 ; WRITE$LST: ;WRITES IMMEDIATE MESSAGE TO LIST DEVICE ; ; CALL WRITE$LST ; DB 'MESSAGE FOLLOWS CALL, ENDS WITH NULL',CR,LF ; DB 0 ; PUSH PSW MVI A,5 ;BDOS 5 = LIST OUTPUT BYTE STA WRITE$FUNC POP PSW JMP WRITE$START ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; WRITE$PUN: ;WRITES IMMEDIATE MESSAGE TO PUNCH DEVICE, AS ABOVE ; PUSH PSW MVI A,4 ;BDOS 4 = PUNCH OUTPUT BYTE STA WRITE$FUNC POP PSW JMP WRITE$START ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; WRITE$CON: ;WRITES IMMEDIATE MESSAGE TO CONSOLE DEVICE, AS ABOVE ; PUSH PSW MVI A,2 ;BDOS 2 = CONSOLE OUTPUT BYTE STA WRITE$FUNC POP PSW ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; WRITE$START: XTHL SHLD WRITE$PC ;STORE TOP OF STACK (STACKED RETURN ADDRESS IS XTHL ;ADDRESS OF BEGINNING OF MESSAGE) ; PUSH PSW PUSH B PUSH D PUSH H ; LHLD WRITE$PC ;POINT TO BEGINNING OF MESSAGE ; WRITE$CHAR: XRA A MOV E,M CMP E JZ WRITE$ENDS ; PUSH H LDA WRITE$FUNC MOV C,A CALL BDOS POP H ; INX H JMP WRITE$CHAR ; WRITE$ENDS: INX H ;NULL = NOP, BUT SKIP OVER IT ANYWAY SHLD WRITE$PC ; POP H POP D POP B POP PSW ; XTHL LHLD WRITE$PC ;ADDRESS OF NEXT BYTE AFTER MESSAGE XTHL ;REPLACES ORIGINAL STACKED RETURN ADDRESS ; RET ; WRITE$PC: DS 2 WRITE$FUNC: DS 1 ; ;------------------------------------------------------------------------------ ; ; clark,r 5-4-86 ; MSG$LST: ;SENDS LABELED MESSAGE TO LIST DEVICE ; ;LABEL: DB 'TEXT BEGINS AT LABEL, ENDS WITH NULL',CR,LF ; DB 0 ; ; CALL WITH DE -> LABEL ; ; LXI D,LABEL ; CALL MSG$LST ; PUSH PSW MVI A,5 ;BDOS 5 = LIST OUTPUT BYTE STA MSG$FUNC JMP MSG$CONT ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; MSG$PUN: ;SENDS LABELED MESSAGE TO PUNCH DEVICE, AS ABOVE ; PUSH PSW MVI A,4 ;BDOS 4 = PUNCH OUTPUT BYTE STA MSG$FUNC JMP MSG$CONT ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; MSG$CON: ;SENDS LABELED MESSAGE TO CONSOLE, AS ABOVE ; PUSH PSW MVI A,2 ;BDOS 2 = CONSOLE OUTPUT BYTE STA MSG$FUNC ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; MSG$CONT: PUSH B PUSH D PUSH H ; XCHG ;POINT TO BEGINNING OF LABELED MESSAGE ; MSG$CHAR: XRA A MOV E,M CMP E JZ MSG$ENDS ; PUSH H LDA MSG$FUNC MOV C,A CALL BDOS POP H ; INX H JMP MSG$CHAR ; MSG$ENDS: POP H POP D POP B POP PSW ; RET ; MSG$FUNC DS 1 ; ;------------------------------------------------------------------------------ ; ; clark,r revised 7-4-86 ; FC$BUFF: ;SETS UP FCB FROM BUFFER LEFT BY BDOS 10 ;CALL WITH ; DE -> YOUR FCB ; HL -> BUFFER YOU USED FOR BDOS 10 ; PUSH H INX H ;GET PAST MAX LENGTH BYTE IN BDOS 10 BUFFER JMP FC$CONT ; ; - - - - - - - - - - - - - - - - - - - ; FC$TAIL: ;SETS UP FCB FROM COMMAND TAIL ;CALL WITH ; DE -> YOUR FCB ; HL -> COMMAND TAIL BUFFER ; PUSH H ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; FC$CONT: PUSH D PUSH B PUSH PSW ; PUSH D ;SAVE FCB POINTER MVI C,36 ;NULL OUT ANY PREVIOUS CONTENTS OF FCB XRA A FC$NULLS: DCR C JM FC$NEND STAX D INX D JMP FC$NULLS FC$NEND:POP D ;POINT AGAIN TO START OF FCB ; MOV B,M ;LENGTH BYTE FROM FILENAME BUFFER INX H ;GET PAST LENGTH BYTE, TO FIRST CHAR IN BUFFER ; INX H ;LOOK AT SECOND CHAR IN BUFFER MOV A,M CPI ':' DCX H ;POINT BACK TO FIRST CHAR (AFFECTS NO FLAGS) JZ FC$DRIVE ; XRA A ;IF NOT COLON, 0 = DEFAULT DRIVE STAX D ;TO DRIVE BYTE WITHIN FCB JMP FC$NAME ; FC$DRIVE: MOV A,M ANI 0000$1111B ;MASK Aa = 1, Bb = 2 etc. STAX D ;DRIVE BYTE WITHIN FCB INX H ;GET PAST DRIVE INX H ;..AND COLON ; FC$NAME: INX D ;GET PAST FCB DRIVE BYTE, TO FILENAME FIELD MVI C,8 ;MAX FILE NAME LENGTH CALL FC$FIELD ; MVI C,3 ;MAX FILE TYPE LENGTH CALL FC$FIELD ; POP PSW POP B POP D POP H RET ;RETURN TO MAIN PROGRAM ; ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; FC$FIELD: DCR C ;END OF OUTPUT FIELD? JM FC$FOFEND ; DCR B ;END OF INPUT FILENAME LENGTH? JM FC$FILLSP ; MOV A,M ;CHAR FROM FILENAME INPUT BUFFER INX H ; CPI 0 ;NUL = END OF TYPE, OR NAME WITH NO TYPE JZ FC$FILLSP CPI ' ' ;SPACE = END OF NAME OR TYPE JZ FC$FILLSP CPI '.' ;END OF NAME JZ FC$FILLSP CPI '*' ;AMBIGUOUS NAME JZ FC$FILLQU ; CPI 'a' ;before lower case 'a'? JC FC$CHAR CPI 'z'+1 ;after lower case 'z'? JNC FC$CHAR ANI 0101$1111B ;MASK LOWER CASE TO UPPER CASE ; FC$CHAR: STAX D ;CHAR TO FCB NAME FIELD INX D JMP FC$FIELD ; FC$FILLQU: MVI A,'?' JMP FC$FILL FC$FILLSP: MVI A,' ' FC$FILL: STAX D ;FILL UP FCB NAME FIELD INX D DCR C JP FC$FILL JMP FC$FEND ; FC$FOFEND: INX H ;GET PAST "." IF NAME FIELD FULL ; FC$FEND: RET ;RETURN FROM FC$FIELD TO FC$NAME ROUTINE ABOVE ; ;------------------------------------------------------------------------------ ; END