; LAST UPDATE: 06.02.2025 savelij
; входные параметры общие:
; HL-адрес загрузки в память
; BCDE-32-х битный номер сектора
; A-количество блоков (блок=512 байт)
; только для многоблочной записи/чтении
; ошибки выдаваемые на выходе:
; A=0-инициализация прошла успешно
; A=1-карта не найдена или не ответила
;общая точка входа для работы с 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
PEC_OFF M_SHADOW_BF
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 (RREG_L),HL
EX (SP),HL
LD (RREG_F),HL
EX (SP),HL
RET4SD1
PEC_ON M_SHADOW_BF
POP AF
RET
TABLSDZ DW SD_INIT ; 0 параметров не требует, на выходе 'A'
; смотри выше первые 2 значения
DW SD_CMP ; 1 проверка наличия SD карты
DW RDMULTI ; 2 чтение секторов, кол-во в 'A'
DW WRMULTI ; 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
in (c) ;in f,(c)
in (c) ;in f,(c)
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
in (c) ;in f,(c)
in (c) ;in f,(c)
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
SD_CMP LD A,CMD_58
LD BC,P_DATA
CALL OUT_COM
CALL IN_OOUT
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C)
NOP
IN H,(C)
RET
SECM200 PUSH HL
PUSH DE
PUSH BC
PUSH AF
PUSH BC
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)
INC A
JP Z,SD_CARD_LOST
DEC A
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
in (c) ;in f,(c)
in (c) ;in f,(c)
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,0x30FF
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 A,IYL
BIT 1,A
JR NZ,RD_SECT3 ;ЕСЛИ ДЛЯ ВНЕШНЕЙ
AND A
JR NZ,RD_SECT2
RD_SECT3
READ_7FFD
LD BC,(B0_CPU2)
JR Z,RD_SECT1
LD BC,(B1_CPU2)
RD_SECT1
PEC_ON M_SHADOW_BF
LD A,B
OR 0x37
LD B,A
LD A,C
LD C,LOW (WIN_A0)
OUT (C),A
PEC_OFF M_SHADOW_BF
RD_SECT2 LD BC,P_DATA
INIR
NOP
INIR
NOP
IN A,(C)
NOP
IN A,(C)
PEC_ON M_SHADOW_BF
LD BC,WIN_P2
XOR A
OUT (C),A
PEC_OFF M_SHADOW_BF
POP BC
RET
WR_SECT PUSH BC
LD BC,P_DATA
OUT (C),A
OTIR
NOP
OTIR
LD A,0xFF
OUT (C),A
NOP
OUT (C),A
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
WRMULTI EX AF,AF'
LD A,CMD_25
CALL SECM200
CALL IN_OOUT
INC A
JR NZ,$-4
EX AF,AF'
WRMULT1 EX AF,AF'
LD A,0xFC
CALL WR_SECT
CALL IN_OOUT
INC A
JR NZ,$-4
EX AF,AF'
DEC A
JR NZ,WRMULT1
LD C,P_DATA
LD A,0xFD
OUT (C),A
CALL IN_OOUT
INC A
JR NZ,$-4
JP CS_HIGH