;LAST UPDATE: 09.02.2010 savelij
;Входные параметры общие:
;HL-адрес загрузки в память
;BCDE-32-х битный номер сектора
;A-количество блоков (блок=512 байт)
;только для многоблочной записи/чтении
;Ошибки выдаваемые на выходе:
;A=0-инициализация прошла успешно
;A=1-карта не найдена или не ответила
Sd_init EQU 0
Sd__off EQU 1
Rdsingl EQU 2
Rdmulti EQU 3
;ОБЩАЯ ТОЧКА ВХОДА ДЛЯ РАБОТЫ С SD
COMSDZ EX AF,AF'
LD A,IYL
AND A
LD A,(NEXTBYTERST8)
JR Z,COMSDZ1
EX (SP),HL
LD A,(HL)
INC HL
EX (SP),HL
COMSDZ1 ADD A,A
PUSH HL
LD HL,RET4SDZ
EX (SP),HL
PUSH HL
LD HL,TABLSDZ
ADD A,L
LD L,A
ADC A,H
SUB L
LD H,A
XOR A
OUT (PEVO_CONF),A
LD A,(HL)
INC HL
LD H,(HL)
LD L,A
EX AF,AF'
EX (SP),HL
RET
RET4SDZ PUSH AF
LD A,IYL
AND A
JR NZ,RET4SD1
LD (REG_L),HL
EX (SP),HL
LD (REG_F),HL
EX (SP),HL
RET4SD1 LD A,1
OUT (PEVO_CONF),A
POP AF
RET
TABLSDZ DW SD_INIT ;0 параметров не требует, на выходе A
;смотри выше первые 2 значения
DW SD__OFF ;1 просто вырубает питание карты
DW RDSINGL ;2 чтение одного сектора
DW RDMULTI ;3 чтение секторов, кол-во в "A"
SD_INIT CALL CS_HIGH
LD BC,P_DATA
LD DE,0X10FF
OUT (C),E
DEC D
JR NZ,$-3
XOR A
EX AF,AF'
ZAW001 LD HL,CMD00
CALL OUTCOM
CALL IN_OOUT
EX AF,AF'
DEC A
JR Z,ZAW003
EX AF,AF'
DEC A
JR NZ,ZAW001
LD HL,CMD08
CALL OUTCOM
CALL IN_OOUT
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C)
LD HL,0
BIT 2,A
JR NZ,ZAW006
LD H,0X40
ZAW006 LD A,CMD_55
CALL OUT_COM
CALL IN_OOUT
LD A,ACMD_41
OUT (C),A
NOP
OUT (C),H
NOP
OUT (C),L
NOP
OUT (C),L
NOP
OUT (C),L
LD A,0XFF
OUT (C),A
CALL IN_OOUT
AND A
JR NZ,ZAW006
ZAW004 LD A,CMD_59
CALL OUT_COM
CALL IN_OOUT
AND A
JR NZ,ZAW004
ZAW005 LD HL,CMD16
CALL OUTCOM
CALL IN_OOUT
AND A
JR NZ,ZAW005
CS_HIGH PUSH AF
LD A,3
OUT (P_CONF),A
XOR A
OUT (P_DATA),A
POP AF
RET
ZAW003 CALL SD__OFF
INC A
RET
SD__OFF XOR A
OUT (P_CONF),A
OUT (P_DATA),A
RET
CS__LOW PUSH AF
LD A,1
OUT (P_CONF),A
POP AF
RET
OUTCOM CALL CS__LOW
PUSH BC
LD BC,0X0600+P_DATA
OTIR
POP BC
RET
OUT_COM PUSH BC
CALL CS__LOW
LD BC,P_DATA
OUT (C),A
XOR A
OUT (C),A
NOP
OUT (C),A
NOP
OUT (C),A
NOP
OUT (C),A
DEC A
OUT (C),A
POP BC
RET
SECM200 PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH BC
;----
;ЗАПАСНОЙ ВАРИАНТ С CMD09
; LD A,CMD_09
; CALL OUT_COM
; CALL IN_OOUT
; CP 0XFE
; JR NZ,$-5
; LD BC,P_DATA
; IN A,(C)
; LD L,0X12
; IN H,(C)
; DEC L
; JR NZ,$-3
;ОСНОВНОЙ ВАРИАНТ С CMD58
LD A,CMD_58
LD BC,P_DATA
CALL OUT_COM
CALL IN_OOUT
IN A,(C)
NOP
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C)
;----
BIT 6,A
POP HL
JR NZ,SECN200
EX DE,HL
ADD HL,HL
EX DE,HL
ADC HL,HL
LD H,L
LD L,D
LD D,E
LD E,0
SECN200 POP AF
LD BC,P_DATA
OUT (C),A
NOP
OUT (C),H
NOP
OUT (C),L
NOP
OUT (C),D
NOP
OUT (C),E
LD A,0XFF
OUT (C),A
POP BC
POP DE
POP HL
RET
IN_OOUT PUSH DE
LD DE,0X10FF
IN_WAIT IN A,(P_DATA)
CP E
JR NZ,IN_EXIT
IN_NEXT DEC D
JR NZ,IN_WAIT
IN_EXIT POP DE
RET
CMD00 DB 0X40,0X00,0X00,0X00,0X00,0X95 ;GO_IDLE_STATE
CMD08 DB 0X48,0X00,0X00,0X01,0XAA,0X87 ;SEND_IF_COND
CMD16 DB 0X50,0X00,0X00,0X02,0X00,0XFF ;SET_BLOCKEN
RD_SECT PUSH BC
LD BC,P_DATA
INIR
NOP
INIR
NOP
IN A,(C)
NOP
IN A,(C)
POP BC
RET
RDMULTI EX AF,AF'
LD A,CMD_18
CALL SECM200
EX AF,AF'
RDMULT1 EX AF,AF'
CALL IN_OOUT
CP 0XFE
JR NZ,$-5
CALL RD_SECT
EX AF,AF'
DEC A
JR NZ,RDMULT1
LD A,CMD_12
CALL OUT_COM
CALL IN_OOUT
INC A
JR NZ,$-4
JP CS_HIGH
RDSINGL LD A,CMD_17
CALL SECM200
CALL IN_OOUT
CP 0XFE
JR NZ,$-5
CALL RD_SECT
CALL IN_OOUT
INC A
JR NZ,$-4
JP CS_HIGH