Цитата Сообщение от ewgeny7 Посмотреть сообщение
Можно даже не гадать. А взять готовые исходники чтения/записи 24С16 на Скорпионе.
Я пытаюсь найти их у себя, но нуно потрясти spensor'a и savelij.
Если склероз мне не изменяет, то там даже меньше 200 байт...
Там выполняется переброска из 24С16 в ОЗУ и обратно.
Вот что нужно для чтения с SD/MMC. На взгляд, тут поболее 200 байт будет:
Код:
sd_select:
	call sd_fini

	or SD_CS            ; select, still idle data
	out (RTC), a
	ret                 ; af b trashed

sd_fini:
	ld b, 17            ; clock low high low high ... low, 8 pulses
sd_wiggle:
	ld a, SD_DOUT       ; unselected, idle data
L1:
	out (RTC), a
	xor SD_CLK
	djnz L1
	ret                 ; af b trashed

sd_put:                 ; byte from a
	ld c, a
	ld b, 8
L3:
	ld a, SD_CS >> 1    ; 7 msbits
	rl c
	rla                 ; SD_DOUT is RTC.0
	out (RTC), a        ; clock is low
	or SD_CLK
	out (RTC), a        ; rising clock edge
	djnz L3
	and ~SD_CLK
	out (RTC), a        ; leave with clock low
	ret                 ; af bc trashed

sd_get:                 ; byte to a
	ld b, 8
L2:
	in a, (RTC)
	rla                 ; SD_DIN is RTC.7
	rl c
	ld a, SD_CS | SD_DOUT | SD_CLK
	out (RTC), a
	and ~SD_CLK
	out (RTC), a
	djnz L2

	ld a, c
	ret                 ; af bc trashed

; command in a, includes fixed msbits
; arg32 in dehl
; z return, if R1 (in a) is 0

sd_command_no_arg:
	ld hl, 0

sd_command_word_arg:  ; fits in HL
	ld de, 0

sd_command:           ; command in a, dword arg in dehl

	call sd_put       ; command includes fixed 01 startbits

	ld a, d           ; arg
	call sd_put
	ld a, e
	call sd_put
	ld a, h
	call sd_put
	ld a, l
	call sd_put

	ld a, 095h        ; crc7 only valid for initial CMD0
	call sd_put       ; DOUT ends up idle because of the stopbit

	ld hl, 20000      ; XXX timeout XTAL dependent
L4:
	call sd_get       ; R1 response, when msbit is clear
	or a              ; zero and sign valid
	ret p             ; R1 in a. z if ok

	dec hl
	bit 7, h          ; until HL wraps negative
	jr z, L4
	ret               ; 0x80 | ? in a, nz

; command response R1
; 0x00 ok
; or bitfield
; 0x01 idle state
; 0x02 erase reset
; 0x04 illegal command
; 0x08 command crc error
; 0x10 erase sequence error
; 0x20 address error
; 0x40 parameter error
; 0x80 timeout (other bits meaningless)
;
; packet token
; 0xFF none yet
; 0xFE ok
; or bitfield
; 0x01 error
; 0x02 controller error
; 0x04 media ecc failed
; 0x08 out of range
; 0x10 card is locked

sd_wait_token:
	ld hl, 20000      ; XXX timeout XTAL dependent
L5:
	call sd_get       ; token is first non-FF
	cp 0FFh
	ret nz            ; token in a

	dec hl
	bit 7, h          ; until HL wraps negative
	jr z, L5
	ret               ; FF in a

sd_wait_busy:
	ld hl, 20000      ; XXX timeout XTAL dependent
L6:
	call sd_get       ; 8 clocks. data output activates after 1 clock
	inc a             ; FF is not busy
	ret z             ; z, ok. a=0

	dec hl            ; else busy or something
	bit 7, h          ; until HL wraps negative
	jr z, L6
	ret               ; nz, timeout

CMD0   equ 040h |  0 ; resets the card
CMD9   equ 040h |  9 ; read CSD
CMD10  equ 040h | 10 ; read CID
CMD16  equ 040h | 16 ; set R/W block
CMD17  equ 040h | 17 ; read block
CMD24  equ 040h | 24 ; write block
CMD55  equ 040h | 55 ; next command is ACMDxx
ACMD41 equ 040h | 41 ; send host capacity support, init card

; byte offset in dehl
; z return if ok

sd_read_block:
	ld a, CMD17           ; READ_SINGLE_BLOCK
	call sd_command       ; dehl byteaddress
	ret nz                ; not "ok"

	call sd_wait_token    ; packet start or FF if timed out
	cp 0FEh
	ret nz                ;  or error

	ld hl, (rwaddr)
	ld e, 128             ; loop counter
L9:
	call sd_get           ; data
	ld (hl), a
	inc hl
	dec e
	jr nz, L9             ; do the sector

	call sd_get           ; crc16
	ld h, a
	call sd_get           ;  in HL
	ld l, a               ; crcs are not used

	xor a                 ; zero, no carry
	ret

sd_setup:
	call sd_select
	call sd_wait_busy     ; nz if timed out, z a=0 if ok
	ret nz

	; A is 0 from sd_wait_busy.
	; byte address to dehl from TRACK, SECTOR
	; when spt 256 and sector 128

	ld hl, (sectorx)  ; sector to h, zero to l
	ld de, (track)    ; adehl (TRACK << 16) | (SECTOR << 8) | 0

	IF 0

	srl d
	rr e
	rr h
	rr l               ; dehl sector * 128
	xor a              ; z, ok. cannot overflow

	ELSE

	; XXX XXX XXX XXX easy way out

	add hl, hl
	rl e
	rl d               ; dehl sector * 512
	adc a, a           ; z, if ok

	ENDIF

	ret

sd_read:
	call sd_setup
	call z, sd_read_block

sd_done:
	push af
	call sd_fini
	call rtc_unselect       ; /CS high, clock and dout low
	pop af
	jp nz, rw_fail

	xor a
	ret