TITLE 'UWRITE - Write CP/M file to uSD card' ; ; Write a file to the uDrive ; 9/2010 rzh ; CPM EQU 0 BDOS EQU 5 LF EQU 0AH CR EQU 0DH ESC EQU 1BH SFCB EQU 5CH BS EQU 8 ; backspace ADAT EQU 0 ; serial data port A BDAT EQU ADAT+1 ; serial data port B ACON EQU ADAT+2 ; console status port A BCON EQU ADAT+3 ; port B status reg. ACK EQU 6 ; udrv ACK NACK EQU 15h ; udrv NACK ORG 100H UWRT: LD SP,STACK LD C,'U' ;autobaud the udrv CALL UDOUT CALL UDIN ; set up the fcb LD HL,SFCB LD DE,FCB LD BC,16 LDIR ; copy filename to udrv staging area ; remove spaces and add '.' LD HL,SFCB+1 LD DE,WRCN LD B,8 CFUD: LD A,(HL) CP ' ' JR Z,CFUD1 LD (DE),A INC DE INC HL DJNZ CFUD CFUD1: LD A,'.' LD (DE),A INC DE ; LD B,3 LD HL,SFCB+9 CFUD2: LD A,(HL) CP ' ' JR Z,CFUD3 LD (DE),A INC DE INC HL DJNZ CFUD2 CFUD3: LD A,'$' LD (DE),A ; LD DE,FCB LD C,0FH CALL BDOS ;OPENFIL INC A JR NZ,FILEOK LD DE,CANTOPE CALL PSTRING JP CPM FILEOK: LD DE,FCB LD C,23H ;GET FILE SIZE CALL BDOS ; byte 33,34,&35 of FCB are r0,r1,r2 ; r2=1 means max rec. count (65536) [unlikely] ; else r0,r1 is file size in 128 byte "records" LD A,(R1) LD (FSZ2),A LD A,(R0) LD (FSZ1),A ; ; shift up in multibyte (multiply by 128) ; register to convert to bytes. ; LD C,7 BYLP: LD HL,FSZ1 LD B,4 OR A SHFLP: RL (HL) INC HL DJNZ SHFLP DEC C JR NZ,BYLP ; CALL CRLF LD DE,MSG CALL PSTRING LD DE,WRCN CALL PSTRING LD DE,BLNKS CALL PSTRING ; LD DE,(OUTBUF) LD C,1AH ;SETDMA CALL BDOS ; CALL SFN ; LD DE,HEX CALL PSTRING ; CALL UDIN ; RDREC: LD DE,FCB LD C,14H CALL BDOS ;READSEQ OR A JP NZ,END ;EOF SEEN LD B,4 LD HL,(OUTBUF) WRTIO: CALL SNDAT ;send 32b to uDrive ; pointed to by HL CALL UDNP DJNZ WRTIO ; CALL SHWACT JR RDREC ; END: CALL SHWACT JP CPM ; SNDAT: PUSH BC LD B,32 SND1: LD C,(HL) CALL UDOUT INC HL DJNZ SND1 POP BC RET ; SHWACT: ; do progress thing PUSH BC PUSH HL LD B,0 LD A,(OFFST) LD C,A PUSH HL LD HL,SYMBS ADD HL,BC LD C,BS CALL CONOUT LD C,(HL) CALL CONOUT POP HL LD A,(OFFST) INC A CP 4 JP NZ,PRDT1 LD A,0 PRDT1: LD (OFFST),A POP HL POP BC RET ; OFFST: db 0 SYMBS: db '\|/-' ; CONIN: IN A,(ACON) ;read from kbd AND 1 RET Z ; no kbd input IN A,(ADAT) CP 3 JP Z,CPM RET UDIN: CALL CONIN IN A,(BCON) AND 1 JP Z,UDIN ;no udrv output IN A,(BDAT) LD C,A CP ACK CALL Z,PRACK CP NACK CALL Z,PRNACK RET UDNP: CALL CONIN IN A,(BCON) AND 1 JP Z,UDNP ;no udrv output IN A,(BDAT) LD C,A CP ACK CALL Z,SHWACT ;don't show ACK CP NACK CALL Z,PRNACK RET UDOUT: IN A,(BCON) ;send to udrive BIT 2,A JP Z,UDOUT LD A,C OUT (BDAT),A RET ; PRACK: PUSH DE LD DE,ACKMSG CALL PSTRING POP DE RET ACKMSG: DB 'ACK',CR,LF,'$' ; PRNACK: PUSH DE LD DE,NACKMSG CALL PSTRING POP DE JP CPM NACKMSG: DB 'NACK',CR,LF,'$' ; SFN: LD DE,WRCMD ; form up write command for uDrive PWRCM: LD A,(DE) CP '$' JR Z,TAIL INC DE JR PWRCM TAIL: LD A,0 LD (DE),A LD DE,WRCMD CALL UDSTNG ; put out string terminator (0) and 4-byte size LD C,0 CALL UDOUT LD HL,FSZ+1 LD B,4 SZLP: LD A,(HL) CALL PHEX LD C,(HL) CALL UDOUT DEC HL DJNZ SZLP RET ; UDSTNG: LD A,(DE) CP 0 RET Z LD C,A UDS1: IN A,(BCON) BIT 2,A JP Z,UDS1 LD A,C OUT (BDAT),A INC DE JP UDSTNG ; ; print content of (A) in hex ; PHEX: PUSH AF RRCA RRCA RRCA RRCA CALL PNIB POP AF CALL PNIB RET ; PNIB: AND 0fh CP 10 JR NC,PN0 ADD A,'0' JP PN1 PN0: ADD A,'A'-10 PN1: LD C,A CALL CONOUT RET ; CONOUT: IN A,(ACON) ;send to screen BIT 2,A JP Z,CONOUT LD A,C OUT (ADAT),A RET ; PSTRING: LD C,9 JP BDOS CRLF: LD C,CR CALL CONOUT LD C,LF JP CONOUT CANTOPE: DB 'Can',27H,'t Open File$' WRCMD: DB '@t',20h WRCN: DB ' .' WRCT: DB ' 0 $' ; BLNKS: DB ' $' HEX: DB 'h bytes',CR,LF,'$' FSZ1: DB 0 FSZ2: DB 0 FSZ: DW 0 ; MSG: DB 'Writing $' ; FCB: DB 0 FN: DB 0,0,0,0,0,0,0,0 FT: DB 0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0,0,0,0 DB 0,0,0,0,0 R0: DB 0 R1: DB 0 R2: DB 0 ; DS 50 STACK: ; OUTBUF: DS 128 NDBUF: END