Had to dig into the FPGA code for the SD card. Using Neal Crook's documentation of Grant Searle's version (longer pedigree on the page).
The status register values are:
// SD_Status bit values from Neal Crook's documentation of Grant's SD card
// b7 Write Data Byte can be accepted
// b6 Read Data Byte available
// b5 Block Busy
// b4 Init Busy
// b3 Unused. Read 0
// b2 Unused. Read 0
// b1 Unused. Read 0
// b0 Unused. Read 0
This translates into defines:
#define SD_CARD_WR_RDY 0x80 // 128 dec
#define SD_CARD_RD_DATA_RDY 0x40
#define SD_CARD_BLOCK_BUSY 0x20
#define SD_CARD_INIT_BUSY 0x10
// Composite values
#define SD_CARD_READY 0x80 // 128 dec
#define SD_CARD_TX_BUSY 0xA0 // 160 dec
#define SD_CARD_RX_BUSY 0xE0 // 224 dec
I'm still getting this error when I write to the SD card.
Close error
Not sure if the error is because I am not returning a good status or not. in the CP/M code [CBIOS128.LST] file the function that does the SD block write is writehst:. At the end of the routine a status value is returned in the erflag variable. The variable is read by the calling routine. Not sure which routine is calling the writehst function but rwmove is the only function which reads it.. Not sure yet what I have to do to tell the host that the write completed but it has to be something inside of witehst that does it.
Here's the wrthst routine (again):
0754 EAC4 ;================================================================================================ 0755 EAC4 ; Write physical sector to host 0756 EAC4 ;================================================================================================ 0757 EAC4 0758 EAC4 writehst: 0759 EAC4 F5 PUSH AF 0760 EAC5 C5 PUSH BC 0761 EAC6 E5 PUSH HL 0762 EAC7 0763 EAC7 DB 89 wrWait1: IN A,(SD_STATUS) 0764 EAC9 FE 80 CP 128 0765 EACB 20 FA JR NZ,wrWait1 0766 EACD 0767 EACD CD 2B EA CALL setLBAaddr 0768 EAD0 0769 EAD0 3E 01 LD A,$01 ; 01 = Write block 0770 EAD2 D3 89 OUT (SD_CONTROL),A 0771 EAD4 0772 EAD4 0E 04 LD c,4 0773 EAD6 21 D2 FB LD HL,hstbuf 0774 EAD9 wr4secs: 0775 EAD9 06 80 LD b,128 0776 EADB wrByte: 0777 EADB 0778 EADB DB 89 wrWait2: IN A,(SD_STATUS) 0779 EADD FE A0 CP 160 ; Write buffer empty 0780 EADF 20 FA JR NZ,wrWait2 0781 EAE1 0782 EAE1 7E LD A,(HL) 0783 EAE2 D3 88 OUT (SD_DATA),A 0784 EAE4 23 INC HL 0785 EAE5 05 dec b 0786 EAE6 20 F3 JR NZ, wrByte 0787 EAE8 0788 EAE8 0D dec c 0789 EAE9 20 EE JR NZ,wr4secs 0790 EAEB 0791 EAEB E1 POP HL 0792 EAEC C1 POP BC 0793 EAED F1 POP AF 0794 EAEE 0795 EAEE AF XOR a 0796 EAEF 32 CC FB ld (erflag),a 0797 EAF2 C9 RET
The routine puts the complement of the a register contents into erflag. before the XOR a would have had the last character so the routine would have sent out the complement of the last byte sent out. I don't think this is the source of the error message since the Z80_PSOC card has no control over the return value.
I can't find any use of the string "Close error" in the BIOS file. Does it come out of the CPM code? I wonder if I broke the card with bad writes? I think I will try the card in one of the FPGA boards that have an SD interface that works. Here's what the directory looks like from on the FPGA card within PuTTY.
CP/M BIOS 2.0 by G. Searle 2013 CP/M 2.2 (c) 1979 by Digital Research A>dir A: DOWNLOAD COM : LOAD COM : PIP COM : STAT COM A: SUBMIT COM : DDT COM : DISPLAY COM : DUMP COM A: ED COM : ASM COM : BBCBASIC COM : POWER COM A: MBASIC COM : BAS BAS : BLINKLED BAS : blinkled bas A: 0@@@ : .@@@ : 2@@@ : 2@@@ A: : MYBAS4 BAS A>
So, I was able to write to the card from the FPGA CP/M machine. Not sure yet what the difference is. There are more files than shown above which only show up in the VGA display for the FPGA card. PuTTY must filter them out.
Writes must be at least partly working since the directory does have the added items. But they are wrong. Not sure what it would take to clean up the card since it's not accessible from Windoze being formatted as a CP/M card.
The error is probably coming out of the function, CLOSEIT: which is found in the CPM22.LST file.
Looked up the XOR A instruction and found it does an XOR of itself so it will always return a status of 0. So I'm even more sure that it's not the block write command which is returning an error.
However, a bad block write could cause the error at a higher level in CP/M if the write didn't work properly. And I've still not verified the write worked properly so back to the PSoC monitor code that I used to test the read blocks. Adding a command to write a pattern to a block which can then be read by the read block routine. But I probably should use a block which is above the 128MB region of the disk drives.
128MB/512 bytes per block would be block 256K or block 0x4000. The SD card is 2 GB so I think I'll work with the block at 1 GB to be safe. Hopefully I won't kill the card, but if I do I have several other cards.
I've got another reason to think it's the SD write routine because of the directory being messed up. There has to be some difference between the block read which seems to work and the block write which sorta works.
Long enough for now, so I will be picking this up in the next log post.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.