mirror of https://github.com/wwarthen/RomWBW.git
77 changed files with 12498 additions and 2 deletions
@ -1,4 +1,22 @@ |
|||
{ |
|||
"files.trimTrailingWhitespace": false, |
|||
"files.eol": "\r\n" |
|||
"files.eol": "\r\n", |
|||
"files.associations": { |
|||
"*.inc": "z80-macroasm", |
|||
"*.asm": "z80-macroasm", |
|||
"*.180": "z80-macroasm", |
|||
"*.asm.m4": "z80-macroasm", |
|||
"*.inc.m4": "z80-macroasm", |
|||
"*.mac": "z80-macroasm", |
|||
"*.asmpp": "z80-macroasm", |
|||
"*.zdsproj": "xml", |
|||
"ch376.h": "c", |
|||
"protocol.h": "c", |
|||
"usb_state.h": "c", |
|||
"functional": "c", |
|||
"class_scsi.h": "c", |
|||
"z80.h": "c", |
|||
"dev_transfers.h": "c", |
|||
"usb-base-drv.h": "c" |
|||
} |
|||
} |
|||
|
|||
@ -0,0 +1,133 @@ |
|||
SHELL := /bin/bash |
|||
.SHELLFLAGS := -eu -o pipefail -c |
|||
.ONESHELL: |
|||
MAKEFLAGS += --warn-undefined-variables |
|||
MAKEFLAGS += --no-builtin-rules |
|||
|
|||
ZCCRELFLAGS= |
|||
ifdef RELEASE |
|||
ZCCRELFLAGS=-SO3 --max-allocs-per-node600000 --allow-unsafe-read --opt-code-speed |
|||
endif |
|||
|
|||
SRC := ./source-doc/ |
|||
LIBS := -I./$(SRC)base-drv/ |
|||
|
|||
ZCC := zcc +msx --vc -subtype=rom -startup=1 -crt0 $(SRC)crt.asm -compiler=sdcc -Cs--std=c23 -Cs--Werror $(ZCCRELFLAGS) $(LIBS) |
|||
|
|||
ASSDIR := ./ |
|||
|
|||
all: $(ASSDIR)base-drv.s $(ASSDIR)scsi-drv.s $(ASSDIR)ufi-drv.s |
|||
|
|||
clean: |
|||
@rm -rf base-drv |
|||
@rm -rf scsi-drv |
|||
@rm -rf ufi-drv |
|||
|
|||
$(ASSDIR)base-drv.s: |
|||
@echo "Creating base-drv.s" |
|||
echo "; Generated File -- not to be modify directly" > $(ASSDIR)base-drv.s |
|||
for dep in $^; do |
|||
dep=$${dep#*/} |
|||
dep=$${dep#*/} |
|||
echo '#include "'ch376-native/base-drv/$${dep}'"' >> $(ASSDIR)base-drv.s |
|||
done |
|||
|
|||
$(ASSDIR)scsi-drv.s: |
|||
@echo "Creating scsi-drv.s" |
|||
echo "; Generated File -- not to be modify directly" > $(ASSDIR)scsi-drv.s |
|||
for dep in $^; do |
|||
dep=$${dep#*/} |
|||
dep=$${dep#*/} |
|||
echo '#include "'ch376-native/scsi-drv/$${dep}'"' >> $(ASSDIR)scsi-drv.s |
|||
done |
|||
|
|||
$(ASSDIR)ufi-drv.s: |
|||
@echo "Creating ufi-drv.s" |
|||
echo "; Generated File -- not to be modify directly" > $(ASSDIR)ufi-drv.s |
|||
for dep in $^; do |
|||
dep=$${dep#*/} |
|||
dep=$${dep#*/} |
|||
echo '#include "'ch376-native/ufi-drv/$${dep}'"' >> $(ASSDIR)ufi-drv.s |
|||
done |
|||
|
|||
$(ASSDIR)%.c.s: $(ASSDIR)%.c.asm |
|||
@mkdir -p $(dir $@) |
|||
echo "Converting $< to $@" |
|||
${SRC}convert-for-uz80as.sh $< $@ |
|||
|
|||
$(ASSDIR)%.s: $(SRC)%.asm |
|||
@mkdir -p $(dir $@) |
|||
cp $< $@ |
|||
sed -i "1i\;\r\n; Generated from $< -- not to be modify directly\r\n;\r\n; " $@ |
|||
|
|||
define compile |
|||
@mkdir -p $(dir $@) |
|||
$(ZCC) --c-code-in-asm --assemble-only $< -o $@ |
|||
echo "Compiled $(notdir $@) from $(notdir $<)" |
|||
endef |
|||
|
|||
$(ASSDIR)base-drv/%.c.asm: $(SRC)base-drv/%.c; $(compile) |
|||
$(ASSDIR)scsi-drv/%.c.asm: $(SRC)scsi-drv/%.c; $(compile) |
|||
$(ASSDIR)ufi-drv/%.c.asm: $(SRC)ufi-drv/%.c; $(compile) |
|||
$(ASSDIR)%.c.asm: $(SRC)%.c; $(compile) |
|||
$(ASSDIR)libraries/delay/%.c.asm: ../apps/libraries/delay/%.c; $(compile) |
|||
$(ASSDIR)libraries/usb/%.c.asm: ../apps/libraries/usb/%.c; $(compile) |
|||
|
|||
.PHONY: format |
|||
format: SHELL:=/bin/bash |
|||
format: |
|||
@clang-format --version |
|||
find \( -name "*.c" -o -name "*.h" \) -exec echo "formating {}" \; -exec clang-format -i {} \; |
|||
|
|||
ZSDCPP_FLAGS=-iquote"." -isystem"${ZCCCFG}/../../include/_DEVELOPMENT/sdcc" $(LIBS) |
|||
|
|||
include ${SRC}depends.d |
|||
|
|||
deps: |
|||
@echo "" > ${SRC}/depends.d |
|||
# C Dependencies |
|||
(cd ${SRC} && find -name "*.c") | while read -r file; do |
|||
file_no_ext="$${file%.*}" |
|||
file_no_ext=$${file_no_ext#./} |
|||
filename=$$(basename $$file_no_ext) |
|||
from="$$filename.o" |
|||
to="${ASSDIR}$$file_no_ext.c.s" |
|||
sdcpp ${ZSDCPP_FLAGS} -MM -MF /tmp/deps.deps ./${SRC}$$file_no_ext.c |
|||
sed "s+$$from+$$to+g" /tmp/deps.deps >> ${SRC}/depends.d |
|||
done |
|||
|
|||
# configure base-drv.s to all .s files |
|||
printf "##\r\n" >> ${SRC}/depends.d |
|||
printf "./base-drv.s: " >> ${SRC}/depends.d |
|||
(cd ${SRC}/base-drv && find -name "*.c") | while read -r file; do |
|||
file_no_ext="$${file%.*}" |
|||
file_no_ext=$${file_no_ext#./} |
|||
filename=$$(basename $$file_no_ext) |
|||
printf "base-drv/$$file.s " >> ${SRC}/depends.d |
|||
done |
|||
|
|||
printf "\r\n" >> ${SRC}/depends.d |
|||
# # configure scsi-drv.s to all .s files |
|||
printf "##\r\n" >> ${SRC}/depends.d |
|||
printf "./scsi-drv.s: " >> ${SRC}/depends.d |
|||
(cd ${SRC}/scsi-drv && find -name "*.c") | while read -r file; do |
|||
file_no_ext="$${file%.*}" |
|||
file_no_ext=$${file_no_ext#./} |
|||
filename=$$(basename $$file_no_ext) |
|||
printf "scsi-drv/$$file.s " >> ${SRC}/depends.d |
|||
done |
|||
|
|||
printf "\r\n" >> ${SRC}/depends.d |
|||
# # configure ufi-drv.s to all .s files |
|||
printf "##\r\n" >> ${SRC}/depends.d |
|||
printf "./ufi-drv.s: " >> ${SRC}/depends.d |
|||
(cd ${SRC}/ufi-drv && find -name "*.c") | while read -r file; do |
|||
file_no_ext="$${file%.*}" |
|||
file_no_ext=$${file_no_ext#./} |
|||
filename=$$(basename $$file_no_ext) |
|||
printf "ufi-drv/$$file.s " >> ${SRC}/depends.d |
|||
done |
|||
|
|||
echo "" >> ${SRC}/depends.d |
|||
|
|||
echo "${SRC}depends.d created" |
|||
@ -0,0 +1,109 @@ |
|||
|
|||
DELAY_FACTOR .EQU 640 |
|||
|
|||
CMD01_RD_USB_DATA0 .EQU 0x27 ; Read data block from current USB interrupt endpoint buffer or host endpoint receive buffer |
|||
; output: length, data stream |
|||
|
|||
CMD10_WR_HOST_DATA .EQU 0x2C ; Write a data block to the send buffer of the USB host endpoint |
|||
; input: length, data stream |
|||
|
|||
CH_CMD_RD_USB_DATA0 .EQU CMD01_RD_USB_DATA0 |
|||
CH_CMD_WR_HOST_DATA .EQU CMD10_WR_HOST_DATA |
|||
|
|||
; HL -> timeout |
|||
; returns |
|||
; L -> error code |
|||
|
|||
; --------------------------------- |
|||
; Function ch_wait_int_and_get_status |
|||
; --------------------------------- |
|||
_ch_wait_int_and_get_status: |
|||
ld bc, DELAY_FACTOR |
|||
|
|||
keep_waiting: |
|||
CALL _delay |
|||
ld a, $FF |
|||
in a, (_CH376_COMMAND_PORT & 0xFF) |
|||
rlca |
|||
jp nc, _ch_get_status |
|||
|
|||
dec bc |
|||
ld a, b |
|||
or c |
|||
jr nz, keep_waiting |
|||
|
|||
dec hl |
|||
ld a, h |
|||
or l |
|||
jr nz, _ch_wait_int_and_get_status |
|||
|
|||
CALL _delay |
|||
ld a, $FF |
|||
in a, (_CH376_COMMAND_PORT & 0xFF) |
|||
bit 4, a ; _CH376_COMMAND_PORT & PARA_STATE_BUSY |
|||
|
|||
ld l, 0x0C ; USB_ERR_CH376_BLOCKED; |
|||
ret nz |
|||
|
|||
ld l, 0x0D ; USB_ERR_CH376_TIMEOUT |
|||
ret |
|||
|
|||
; uint8_t ch_read_data(uint8_t *buffer) __sdcccall(1); |
|||
_ch_read_data: |
|||
; ch_command(CH_CMD_RD_USB_DATA0); |
|||
push hl |
|||
ld l, CH_CMD_RD_USB_DATA0 |
|||
call _ch_command |
|||
pop hl |
|||
|
|||
CALL _delay |
|||
ld bc, _CH376_DATA_PORT |
|||
in a, (c) |
|||
|
|||
or a |
|||
ret z |
|||
|
|||
ld e, a |
|||
push af |
|||
read_block: |
|||
CALL _delay |
|||
in a, (c) |
|||
ld (hl), a |
|||
inc hl |
|||
dec e |
|||
jr nz, read_block |
|||
|
|||
pop af |
|||
ret |
|||
|
|||
;const uint8_t *ch_write_data(const uint8_t *buffer, uint8_t length) |
|||
_ch_write_data: |
|||
;libraries/usb/ch376.c:125: ch_command(CH_CMD_WR_HOST_DATA); |
|||
ld l, CH_CMD_WR_HOST_DATA |
|||
call _ch_command |
|||
|
|||
ld iy, 2 |
|||
add iy, sp |
|||
ld l, (iy+0) |
|||
ld h, (iy+1) |
|||
ld a, (iy+2) |
|||
|
|||
ld bc, _CH376_DATA_PORT |
|||
|
|||
; _CH376_DATA_PORT = length; |
|||
call _delay |
|||
out (c), a |
|||
|
|||
or a |
|||
ret z |
|||
|
|||
ld d, a |
|||
write_block: |
|||
call _delay |
|||
ld a, (hl) |
|||
out (c), a |
|||
inc hl |
|||
dec d |
|||
jr nz, write_block |
|||
|
|||
ret |
|||
@ -0,0 +1,14 @@ |
|||
; Generated File -- not to be modify directly |
|||
#include "ch376-native/base-drv/dev_transfers.c.s" |
|||
#include "ch376-native/base-drv/enumerate.c.s" |
|||
#include "ch376-native/base-drv/usb_state.c.s" |
|||
#include "ch376-native/base-drv/class_hub.c.s" |
|||
#include "ch376-native/base-drv/enumerate_storage.c.s" |
|||
#include "ch376-native/base-drv/enumerate_hub.c.s" |
|||
#include "ch376-native/base-drv/usb-base-drv.c.s" |
|||
#include "ch376-native/base-drv/transfers.c.s" |
|||
#include "ch376-native/base-drv/print.c.s" |
|||
#include "ch376-native/base-drv/ch376.c.s" |
|||
#include "ch376-native/base-drv/protocol.c.s" |
|||
#include "ch376-native/base-drv/work-area.c.s" |
|||
#include "ch376-native/base-drv/usb-init.c.s" |
|||
@ -0,0 +1,780 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./ch376.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
_result: |
|||
DEFS 1 |
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./ch376.c:7: void ch_command(const uint8_t command) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function ch_command |
|||
; --------------------------------- |
|||
_ch_command: |
|||
;source-doc/base-drv/./ch376.c:9: while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0) |
|||
ld h,0xff |
|||
l_ch_command_00102: |
|||
ld a, +((_CH376_COMMAND_PORT) / 256) |
|||
in a, (((_CH376_COMMAND_PORT) & 0xFF)) |
|||
bit 4, a |
|||
jr Z,l_ch_command_00104 |
|||
dec h |
|||
jr Z,l_ch_command_00104 |
|||
;source-doc/base-drv/./ch376.c:10: delay(); |
|||
push hl |
|||
call _delay |
|||
pop hl |
|||
jr l_ch_command_00102 |
|||
l_ch_command_00104: |
|||
;source-doc/base-drv/./ch376.c:20: delay(); |
|||
push hl |
|||
call _delay |
|||
pop hl |
|||
;source-doc/base-drv/./ch376.c:21: CH376_COMMAND_PORT = command; |
|||
ld a, l |
|||
ld bc,_CH376_COMMAND_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:22: delay(); |
|||
;source-doc/base-drv/./ch376.c:23: } |
|||
jp _delay |
|||
;source-doc/base-drv/./ch376.c:27: usb_error ch_long_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(5000); } |
|||
; --------------------------------- |
|||
; Function ch_long_wait_int_and_get_status |
|||
; --------------------------------- |
|||
_ch_long_wait_int_and_get_statu: |
|||
ld hl,0x1388 |
|||
jp _ch_wait_int_and_get_status |
|||
;source-doc/base-drv/./ch376.c:29: usb_error ch_short_wait_int_and_get_statu(void) { return ch_wait_int_and_get_status(100); } |
|||
; --------------------------------- |
|||
; Function ch_short_wait_int_and_get_statu |
|||
; --------------------------------- |
|||
_ch_short_wait_int_and_get_stat: |
|||
ld hl,0x0064 |
|||
jp _ch_wait_int_and_get_status |
|||
;source-doc/base-drv/./ch376.c:31: usb_error ch_very_short_wait_int_and_get_(void) { return ch_wait_int_and_get_status(10); } |
|||
; --------------------------------- |
|||
; Function ch_very_short_wait_int_and_get_ |
|||
; --------------------------------- |
|||
_ch_very_short_wait_int_and_get: |
|||
ld hl,0x000a |
|||
jp _ch_wait_int_and_get_status |
|||
;source-doc/base-drv/./ch376.c:33: usb_error ch_get_status(void) { |
|||
; --------------------------------- |
|||
; Function ch_get_status |
|||
; --------------------------------- |
|||
_ch_get_status: |
|||
;source-doc/base-drv/./ch376.c:34: ch_command(CH_CMD_GET_STATUS); |
|||
ld l,0x22 |
|||
call _ch_command |
|||
;source-doc/base-drv/./ch376.c:35: uint8_t ch_status = CH376_DATA_PORT; |
|||
ld a, +((_CH376_DATA_PORT) / 256) |
|||
in a, (((_CH376_DATA_PORT) & 0xFF)) |
|||
;source-doc/base-drv/./ch376.c:37: if (ch_status >= USB_FILERR_MIN && ch_status <= USB_FILERR_MAX) |
|||
ld l,a |
|||
sub 0x41 |
|||
jr C,l_ch_get_status_00102 |
|||
ld a,0xb4 |
|||
sub l |
|||
;source-doc/base-drv/./ch376.c:38: return ch_status; |
|||
jr NC,l_ch_get_status_00126 |
|||
l_ch_get_status_00102: |
|||
;source-doc/base-drv/./ch376.c:40: if (ch_status == CH_CMD_RET_SUCCESS) |
|||
ld a, l |
|||
;source-doc/base-drv/./ch376.c:41: return USB_ERR_OK; |
|||
sub 0x51 |
|||
jr NZ,l_ch_get_status_00105 |
|||
ld l,a |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00105: |
|||
;source-doc/base-drv/./ch376.c:43: if (ch_status == CH_USB_INT_SUCCESS) |
|||
ld a, l |
|||
;source-doc/base-drv/./ch376.c:44: return USB_ERR_OK; |
|||
sub 0x14 |
|||
jr NZ,l_ch_get_status_00107 |
|||
ld l,a |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00107: |
|||
;source-doc/base-drv/./ch376.c:46: if (ch_status == CH_USB_INT_CONNECT) |
|||
ld a, l |
|||
sub 0x15 |
|||
jr NZ,l_ch_get_status_00109 |
|||
;source-doc/base-drv/./ch376.c:47: return USB_INT_CONNECT; |
|||
ld l,0x81 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00109: |
|||
;source-doc/base-drv/./ch376.c:49: if (ch_status == CH_USB_INT_DISK_READ) |
|||
ld a, l |
|||
sub 0x1d |
|||
jr NZ,l_ch_get_status_00111 |
|||
;source-doc/base-drv/./ch376.c:50: return USB_ERR_DISK_READ; |
|||
ld l,0x1d |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00111: |
|||
;source-doc/base-drv/./ch376.c:52: if (ch_status == CH_USB_INT_DISK_WRITE) |
|||
ld a, l |
|||
sub 0x1e |
|||
jr NZ,l_ch_get_status_00113 |
|||
;source-doc/base-drv/./ch376.c:53: return USB_ERR_DISK_WRITE; |
|||
ld l,0x1e |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00113: |
|||
;source-doc/base-drv/./ch376.c:55: if (ch_status == CH_USB_INT_DISCONNECT) { |
|||
ld a, l |
|||
sub 0x16 |
|||
jr NZ,l_ch_get_status_00115 |
|||
;source-doc/base-drv/./ch376.c:56: ch_cmd_set_usb_mode(5); |
|||
ld l,0x05 |
|||
call _ch_cmd_set_usb_mode |
|||
;source-doc/base-drv/./ch376.c:57: return USB_ERR_NO_DEVICE; |
|||
ld l,0x05 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00115: |
|||
;source-doc/base-drv/./ch376.c:60: if (ch_status == CH_USB_INT_BUF_OVER) |
|||
ld a, l |
|||
sub 0x17 |
|||
jr NZ,l_ch_get_status_00117 |
|||
;source-doc/base-drv/./ch376.c:61: return USB_ERR_DATA_ERROR; |
|||
ld l,0x04 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00117: |
|||
;source-doc/base-drv/./ch376.c:63: ch_status &= 0x2F; |
|||
ld a, l |
|||
and 0x2f |
|||
;source-doc/base-drv/./ch376.c:65: if (ch_status == 0x2A) |
|||
cp 0x2a |
|||
jr NZ,l_ch_get_status_00119 |
|||
;source-doc/base-drv/./ch376.c:66: return USB_ERR_NAK; |
|||
ld l,0x01 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00119: |
|||
;source-doc/base-drv/./ch376.c:68: if (ch_status == 0x2E) |
|||
cp 0x2e |
|||
jr NZ,l_ch_get_status_00121 |
|||
;source-doc/base-drv/./ch376.c:69: return USB_ERR_STALL; |
|||
ld l,0x02 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00121: |
|||
;source-doc/base-drv/./ch376.c:71: ch_status &= 0x23; |
|||
and 0x23 |
|||
;source-doc/base-drv/./ch376.c:73: if (ch_status == 0x20) |
|||
cp 0x20 |
|||
jr NZ,l_ch_get_status_00123 |
|||
;source-doc/base-drv/./ch376.c:74: return USB_ERR_TIMEOUT; |
|||
ld l,0x03 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00123: |
|||
;source-doc/base-drv/./ch376.c:76: if (ch_status == 0x23) |
|||
sub 0x23 |
|||
jr NZ,l_ch_get_status_00125 |
|||
;source-doc/base-drv/./ch376.c:77: return USB_TOKEN_OUT_OF_SYNC; |
|||
ld l,0x07 |
|||
jr l_ch_get_status_00126 |
|||
l_ch_get_status_00125: |
|||
;source-doc/base-drv/./ch376.c:79: return USB_ERR_UNEXPECTED_STATUS_FROM_; |
|||
ld l,0x08 |
|||
l_ch_get_status_00126: |
|||
;source-doc/base-drv/./ch376.c:80: } |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:82: void ch_cmd_reset_all(void) { ch_command(CH_CMD_RESET_ALL); } |
|||
; --------------------------------- |
|||
; Function ch_cmd_reset_all |
|||
; --------------------------------- |
|||
_ch_cmd_reset_all: |
|||
ld l,0x05 |
|||
jp _ch_command |
|||
;source-doc/base-drv/./ch376.c:101: uint8_t ch_probe(void) { |
|||
; --------------------------------- |
|||
; Function ch_probe |
|||
; --------------------------------- |
|||
_ch_probe: |
|||
;source-doc/base-drv/./ch376.c:103: do { |
|||
ld c,0x05 |
|||
l_ch_probe_00103: |
|||
;source-doc/base-drv/./ch376.c:86: ch_command(CH_CMD_CHECK_EXIST); |
|||
push bc |
|||
ld l,0x06 |
|||
call _ch_command |
|||
pop bc |
|||
;source-doc/base-drv/./ch376.c:87: CH376_DATA_PORT = (uint8_t)~0x55; |
|||
ld a,0xaa |
|||
push bc |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
call _delay |
|||
pop bc |
|||
;source-doc/base-drv/./ch376.c:89: complement = CH376_DATA_PORT; |
|||
ld a, +((_CH376_DATA_PORT) / 256) |
|||
in a, (((_CH376_DATA_PORT) & 0xFF)) |
|||
;source-doc/base-drv/./ch376.c:90: return complement == 0x55; |
|||
sub 0x55 |
|||
jr NZ,l_ch_probe_00102 |
|||
;source-doc/base-drv/./ch376.c:104: if (ch_cmd_check_exist()) |
|||
;source-doc/base-drv/./ch376.c:105: return true; |
|||
ld l,0x01 |
|||
jr l_ch_probe_00107 |
|||
l_ch_probe_00102: |
|||
;source-doc/base-drv/./ch376.c:107: delay_medium(); |
|||
push bc |
|||
call _delay_medium |
|||
pop bc |
|||
;source-doc/base-drv/./ch376.c:108: } while (--i != 0); |
|||
dec c |
|||
ld a, c |
|||
;source-doc/base-drv/./ch376.c:110: return false; |
|||
or a |
|||
jr NZ,l_ch_probe_00103 |
|||
ld l,a |
|||
l_ch_probe_00107: |
|||
;source-doc/base-drv/./ch376.c:111: } |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:113: uint8_t ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function ch_cmd_set_usb_mode |
|||
; --------------------------------- |
|||
_ch_cmd_set_usb_mode: |
|||
;source-doc/base-drv/./ch376.c:114: uint8_t result = 0; |
|||
ld h,0x00 |
|||
;source-doc/base-drv/./ch376.c:116: CH376_COMMAND_PORT = CH_CMD_SET_USB_MODE; |
|||
ld a,0x15 |
|||
ld bc,_CH376_COMMAND_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:117: delay(); |
|||
push hl |
|||
call _delay |
|||
pop hl |
|||
;source-doc/base-drv/./ch376.c:118: CH376_DATA_PORT = mode; |
|||
ld a, l |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:119: delay(); |
|||
push hl |
|||
call _delay |
|||
pop hl |
|||
;source-doc/base-drv/./ch376.c:123: while (result != CH_CMD_RET_SUCCESS && result != CH_CMD_RET_ABORT && --count != 0) { |
|||
ld l,0x7f |
|||
l_ch_cmd_set_usb_mode_00103: |
|||
ld a, h |
|||
sub 0x51 |
|||
jr NZ,l_ch_cmd_set_usb_mode_00136 |
|||
ld a,0x01 |
|||
jr l_ch_cmd_set_usb_mode_00137 |
|||
l_ch_cmd_set_usb_mode_00136: |
|||
xor a |
|||
l_ch_cmd_set_usb_mode_00137: |
|||
ld c,a |
|||
bit 0,a |
|||
jr NZ,l_ch_cmd_set_usb_mode_00105 |
|||
ld a, h |
|||
sub 0x5f |
|||
jr Z,l_ch_cmd_set_usb_mode_00105 |
|||
dec l |
|||
jr Z,l_ch_cmd_set_usb_mode_00105 |
|||
;source-doc/base-drv/./ch376.c:124: result = CH376_DATA_PORT; |
|||
ld a, +((_CH376_DATA_PORT) / 256) |
|||
in a, (((_CH376_DATA_PORT) & 0xFF)) |
|||
ld h, a |
|||
;source-doc/base-drv/./ch376.c:125: delay(); |
|||
push hl |
|||
call _delay |
|||
pop hl |
|||
jr l_ch_cmd_set_usb_mode_00103 |
|||
l_ch_cmd_set_usb_mode_00105: |
|||
;source-doc/base-drv/./ch376.c:128: return (result == CH_CMD_RET_SUCCESS) ? USB_ERR_OK : USB_ERR_FAIL; |
|||
ld a, c |
|||
or a |
|||
jr Z,l_ch_cmd_set_usb_mode_00108 |
|||
ld hl,0x0000 |
|||
jr l_ch_cmd_set_usb_mode_00109 |
|||
l_ch_cmd_set_usb_mode_00108: |
|||
ld hl,0x000e |
|||
l_ch_cmd_set_usb_mode_00109: |
|||
;source-doc/base-drv/./ch376.c:129: } |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:131: uint8_t ch_cmd_get_ic_version(void) { |
|||
; --------------------------------- |
|||
; Function ch_cmd_get_ic_version |
|||
; --------------------------------- |
|||
_ch_cmd_get_ic_version: |
|||
;source-doc/base-drv/./ch376.c:132: ch_command(CH_CMD_GET_IC_VER); |
|||
ld l,0x01 |
|||
call _ch_command |
|||
;source-doc/base-drv/./ch376.c:133: return CH376_DATA_PORT & 0x1f; |
|||
ld a, +((_CH376_DATA_PORT) / 256) |
|||
in a, (((_CH376_DATA_PORT) & 0xFF)) |
|||
and 0x1f |
|||
ld l, a |
|||
;source-doc/base-drv/./ch376.c:134: } |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:136: void ch_issue_token(const uint8_t toggle_bit, const uint8_t endpoint, const ch376_pid pid) { |
|||
; --------------------------------- |
|||
; Function ch_issue_token |
|||
; --------------------------------- |
|||
_ch_issue_token: |
|||
;source-doc/base-drv/./ch376.c:137: ch_command(CH_CMD_ISSUE_TKN_X); |
|||
ld l,0x4e |
|||
call _ch_command |
|||
;source-doc/base-drv/./ch376.c:138: CH376_DATA_PORT = toggle_bit; |
|||
ld hl,2+0 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:139: delay(); |
|||
call _delay |
|||
;source-doc/base-drv/./ch376.c:140: CH376_DATA_PORT = endpoint << 4 | pid; |
|||
ld iy,3 |
|||
add iy, sp |
|||
ld a,(iy+0) |
|||
add a, a |
|||
add a, a |
|||
add a, a |
|||
add a, a |
|||
inc iy |
|||
or (iy+0) |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:141: delay(); |
|||
;source-doc/base-drv/./ch376.c:142: } |
|||
jp _delay |
|||
;source-doc/base-drv/./ch376.c:144: void ch_issue_token_in(const endpoint_param *const endpoint) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function ch_issue_token_in |
|||
; --------------------------------- |
|||
_ch_issue_token_in: |
|||
;source-doc/base-drv/./ch376.c:145: ch_issue_token(endpoint->toggle ? 0x80 : 0x00, endpoint->number, CH_PID_IN); |
|||
ld e,l |
|||
ld d,h |
|||
ld a, (hl) |
|||
rrca |
|||
and 0x07 |
|||
ld b, a |
|||
ex de, hl |
|||
ld a, (hl) |
|||
and 0x01 |
|||
jr Z,l_ch_issue_token_in_00103 |
|||
ld a,0x80 |
|||
jr l_ch_issue_token_in_00104 |
|||
l_ch_issue_token_in_00103: |
|||
xor a |
|||
l_ch_issue_token_in_00104: |
|||
ld h,0x09 |
|||
ld l,b |
|||
push hl |
|||
push af |
|||
inc sp |
|||
call _ch_issue_token |
|||
pop af |
|||
inc sp |
|||
;source-doc/base-drv/./ch376.c:146: } |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:148: void ch_issue_token_out(const endpoint_param *const endpoint) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function ch_issue_token_out |
|||
; --------------------------------- |
|||
_ch_issue_token_out: |
|||
;source-doc/base-drv/./ch376.c:149: ch_issue_token(endpoint->toggle ? 0x40 : 0x00, endpoint->number, CH_PID_OUT); |
|||
ld e,l |
|||
ld d,h |
|||
ld a, (hl) |
|||
rrca |
|||
and 0x07 |
|||
ld b, a |
|||
ex de, hl |
|||
ld a, (hl) |
|||
and 0x01 |
|||
jr Z,l_ch_issue_token_out_00103 |
|||
ld a,0x40 |
|||
jr l_ch_issue_token_out_00104 |
|||
l_ch_issue_token_out_00103: |
|||
xor a |
|||
l_ch_issue_token_out_00104: |
|||
ld h,0x01 |
|||
ld l,b |
|||
push hl |
|||
push af |
|||
inc sp |
|||
call _ch_issue_token |
|||
pop af |
|||
inc sp |
|||
;source-doc/base-drv/./ch376.c:150: } |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:152: void ch_issue_token_out_ep0(void) { ch_issue_token(0x40, 0, CH_PID_OUT); } |
|||
; --------------------------------- |
|||
; Function ch_issue_token_out_ep0 |
|||
; --------------------------------- |
|||
_ch_issue_token_out_ep0: |
|||
ld a,0x01 |
|||
push af |
|||
inc sp |
|||
xor a |
|||
ld d,a |
|||
ld e,0x40 |
|||
push de |
|||
call _ch_issue_token |
|||
pop af |
|||
inc sp |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:154: void ch_issue_token_in_ep0(void) { ch_issue_token(0x80, 0, CH_PID_IN); } |
|||
; --------------------------------- |
|||
; Function ch_issue_token_in_ep0 |
|||
; --------------------------------- |
|||
_ch_issue_token_in_ep0: |
|||
ld a,0x09 |
|||
push af |
|||
inc sp |
|||
xor a |
|||
ld d,a |
|||
ld e,0x80 |
|||
push de |
|||
call _ch_issue_token |
|||
pop af |
|||
inc sp |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:156: void ch_issue_token_setup(void) { ch_issue_token(0, 0, CH_PID_SETUP); } |
|||
; --------------------------------- |
|||
; Function ch_issue_token_setup |
|||
; --------------------------------- |
|||
_ch_issue_token_setup: |
|||
ld a,0x0d |
|||
push af |
|||
inc sp |
|||
xor a |
|||
push af |
|||
inc sp |
|||
xor a |
|||
push af |
|||
inc sp |
|||
call _ch_issue_token |
|||
pop af |
|||
inc sp |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:158: usb_error ch_data_in_transfer(uint8_t *buffer, int16_t buffer_size, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function ch_data_in_transfer |
|||
; --------------------------------- |
|||
_ch_data_in_transfer: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/base-drv/./ch376.c:162: if (buffer_size == 0) |
|||
ld a,(ix+7) |
|||
or (ix+6) |
|||
jr NZ,l_ch_data_in_transfer_00102 |
|||
;source-doc/base-drv/./ch376.c:163: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
jp l_ch_data_in_transfer_00110 |
|||
l_ch_data_in_transfer_00102: |
|||
;source-doc/base-drv/./ch376.c:165: USB_MODULE_LEDS = 0x01; |
|||
ld a,0x01 |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:166: do { |
|||
ld c,(ix+8) |
|||
ld b,(ix+9) |
|||
pop de |
|||
push bc |
|||
l_ch_data_in_transfer_00107: |
|||
;source-doc/base-drv/./ch376.c:167: ch_issue_token_in(endpoint); |
|||
ld l,c |
|||
ld h,b |
|||
push hl |
|||
call _ch_issue_token_in |
|||
call _ch_long_wait_int_and_get_statu |
|||
ld a, l |
|||
pop bc |
|||
ld l, a |
|||
;source-doc/base-drv/./ch376.c:170: CHECK(result); |
|||
or a |
|||
jr NZ,l_ch_data_in_transfer_00110 |
|||
;source-doc/base-drv/./ch376.c:172: endpoint->toggle = !endpoint->toggle; |
|||
ld e, c |
|||
ld d, b |
|||
pop hl |
|||
ld a,(hl) |
|||
push hl |
|||
and 0x01 |
|||
xor 0x01 |
|||
and 0x01 |
|||
ld l, a |
|||
ld a, (de) |
|||
and 0xfe |
|||
or l |
|||
ld (de), a |
|||
;source-doc/base-drv/./ch376.c:174: count = ch_read_data(buffer); |
|||
push bc |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
call _ch_read_data |
|||
pop bc |
|||
;source-doc/base-drv/./ch376.c:176: if (count == 0) { |
|||
ld e,a |
|||
;source-doc/base-drv/./ch376.c:177: USB_MODULE_LEDS = 0x00; |
|||
or a |
|||
jr NZ,l_ch_data_in_transfer_00106 |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:178: return USB_ERR_DATA_ERROR; |
|||
ld l,0x04 |
|||
jr l_ch_data_in_transfer_00110 |
|||
l_ch_data_in_transfer_00106: |
|||
;source-doc/base-drv/./ch376.c:181: buffer += count; |
|||
ld a, e |
|||
add a,(ix+4) |
|||
ld (ix+4),a |
|||
ld a,0x00 |
|||
adc a,(ix+5) |
|||
ld (ix+5),a |
|||
;source-doc/base-drv/./ch376.c:182: buffer_size -= count; |
|||
ld d,0x00 |
|||
ld a,(ix+6) |
|||
sub e |
|||
ld (ix+6),a |
|||
ld a,(ix+7) |
|||
sbc a, d |
|||
ld (ix+7),a |
|||
;source-doc/base-drv/./ch376.c:183: } while (buffer_size > 0); |
|||
xor a |
|||
cp (ix+6) |
|||
sbc a,(ix+7) |
|||
jp PO, l_ch_data_in_transfer_00137 |
|||
xor 0x80 |
|||
l_ch_data_in_transfer_00137: |
|||
jp M, l_ch_data_in_transfer_00107 |
|||
;source-doc/base-drv/./ch376.c:185: USB_MODULE_LEDS = 0x00; |
|||
ld a,0x00 |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:187: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_ch_data_in_transfer_00110: |
|||
;source-doc/base-drv/./ch376.c:188: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:190: usb_error ch_data_in_transfer_n(uint8_t *const buffer, int8_t *const buffer_size, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function ch_data_in_transfer_n |
|||
; --------------------------------- |
|||
_ch_data_in_transfer_n: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./ch376.c:194: USB_MODULE_LEDS = 0x01; |
|||
ld a,0x01 |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:196: ch_issue_token_in(endpoint); |
|||
ld l,(ix+8) |
|||
ld h,(ix+9) |
|||
call _ch_issue_token_in |
|||
;source-doc/base-drv/./ch376.c:198: CHECK(ch_long_wait_int_and_get_status()); |
|||
call _ch_long_wait_int_and_get_statu |
|||
ld a,l |
|||
or a |
|||
jr NZ,l_ch_data_in_transfer_n_00103 |
|||
;source-doc/base-drv/./ch376.c:200: endpoint->toggle = !endpoint->toggle; |
|||
ld l,(ix+8) |
|||
ld h,(ix+9) |
|||
ld a,(hl) |
|||
and 0x01 |
|||
xor 0x01 |
|||
and 0x01 |
|||
ld e,a |
|||
ld a,(hl) |
|||
and 0xfe |
|||
or e |
|||
ld (hl),a |
|||
;source-doc/base-drv/./ch376.c:202: count = ch_read_data(buffer); |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
call _ch_read_data |
|||
;source-doc/base-drv/./ch376.c:204: *buffer_size = count; |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
ld (bc), a |
|||
;source-doc/base-drv/./ch376.c:206: USB_MODULE_LEDS = 0x00; |
|||
ld a,0x00 |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:208: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_ch_data_in_transfer_n_00103: |
|||
;source-doc/base-drv/./ch376.c:209: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:211: usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function ch_data_out_transfer |
|||
; --------------------------------- |
|||
_ch_data_out_transfer: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
dec sp |
|||
;source-doc/base-drv/./ch376.c:214: const uint8_t max_packet_size = calc_max_packet_size(endpoint->max_packet_sizex); |
|||
ld c,(ix+8) |
|||
ld b,(ix+9) |
|||
ld e, c |
|||
ld d, b |
|||
inc de |
|||
ld a, (de) |
|||
ld (ix-3),a |
|||
;source-doc/base-drv/./ch376.c:216: USB_MODULE_LEDS = 0x02; |
|||
ld a,0x02 |
|||
push bc |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
pop bc |
|||
;source-doc/base-drv/./ch376.c:218: while (buffer_length > 0) { |
|||
ld (ix-2),c |
|||
ld (ix-1),b |
|||
l_ch_data_out_transfer_00103: |
|||
xor a |
|||
cp (ix+6) |
|||
sbc a,(ix+7) |
|||
jp PO, l_ch_data_out_transfer_00130 |
|||
xor 0x80 |
|||
l_ch_data_out_transfer_00130: |
|||
jp P, l_ch_data_out_transfer_00105 |
|||
;source-doc/base-drv/./ch376.c:219: const uint8_t size = max_packet_size < buffer_length ? max_packet_size : buffer_length; |
|||
ld d,(ix-3) |
|||
ld e,0x00 |
|||
ld a, d |
|||
sub (ix+6) |
|||
ld a, e |
|||
sbc a,(ix+7) |
|||
jp PO, l_ch_data_out_transfer_00131 |
|||
xor 0x80 |
|||
l_ch_data_out_transfer_00131: |
|||
jp P, l_ch_data_out_transfer_00108 |
|||
jr l_ch_data_out_transfer_00109 |
|||
l_ch_data_out_transfer_00108: |
|||
ld d,(ix+6) |
|||
ld e,(ix+7) |
|||
l_ch_data_out_transfer_00109: |
|||
;source-doc/base-drv/./ch376.c:220: buffer = ch_write_data(buffer, size); |
|||
push bc |
|||
push de |
|||
push de |
|||
inc sp |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _ch_write_data |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
pop bc |
|||
ld (ix+4),l |
|||
ld (ix+5),h |
|||
;source-doc/base-drv/./ch376.c:221: buffer_length -= size; |
|||
ld e,0x00 |
|||
ld a,(ix+6) |
|||
sub d |
|||
ld (ix+6),a |
|||
ld a,(ix+7) |
|||
sbc a, e |
|||
ld (ix+7),a |
|||
;source-doc/base-drv/./ch376.c:222: ch_issue_token_out(endpoint); |
|||
ld l,c |
|||
ld h,b |
|||
push hl |
|||
call _ch_issue_token_out |
|||
call _ch_long_wait_int_and_get_statu |
|||
ld a, l |
|||
pop bc |
|||
ld l, a |
|||
or a |
|||
jr NZ,l_ch_data_out_transfer_00106 |
|||
;source-doc/base-drv/./ch376.c:226: endpoint->toggle = !endpoint->toggle; |
|||
ld e, c |
|||
ld d, b |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
ld a, (hl) |
|||
and 0x01 |
|||
xor 0x01 |
|||
and 0x01 |
|||
ld l, a |
|||
ld a, (de) |
|||
and 0xfe |
|||
or l |
|||
ld (de), a |
|||
jr l_ch_data_out_transfer_00103 |
|||
l_ch_data_out_transfer_00105: |
|||
;source-doc/base-drv/./ch376.c:229: USB_MODULE_LEDS = 0x00; |
|||
ld a,0x00 |
|||
ld bc,_USB_MODULE_LEDS |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:231: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_ch_data_out_transfer_00106: |
|||
;source-doc/base-drv/./ch376.c:232: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./ch376.c:234: void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function ch_set_usb_address |
|||
; --------------------------------- |
|||
_ch_set_usb_address: |
|||
;source-doc/base-drv/./ch376.c:235: ch_command(CH_CMD_SET_USB_ADDR); |
|||
push hl |
|||
ld l,0x13 |
|||
call _ch_command |
|||
pop hl |
|||
;source-doc/base-drv/./ch376.c:236: CH376_DATA_PORT = device_address; |
|||
ld a, l |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.c:237: delay(); |
|||
;source-doc/base-drv/./ch376.c:238: } |
|||
jp _delay |
|||
_result: |
|||
DEFB +0x00 |
|||
@ -0,0 +1,98 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./class_hub.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./class_hub.c:7: usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function hub_get_descriptor |
|||
; --------------------------------- |
|||
_hub_get_descriptor: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
;source-doc/base-drv/./class_hub.c:8: return usb_control_transfer(&cmd_get_hub_descriptor, hub_description, hub_config->address, hub_config->max_packet_size); |
|||
ld c,l |
|||
ld b,h |
|||
inc hl |
|||
ld a, (hl) |
|||
ld (ix-1),a |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld b, a |
|||
ld a,(ix-1) |
|||
ld c,b |
|||
ld b,a |
|||
push bc |
|||
push de |
|||
ld hl,_cmd_get_hub_descriptor |
|||
push hl |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
;source-doc/base-drv/./class_hub.c:9: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
_cmd_get_hub_descriptor: |
|||
DEFB +0xa0 |
|||
DEFB +0x06 |
|||
DEFB +0x00 |
|||
DEFB +0x29 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFW +0x0008 |
|||
@ -0,0 +1,454 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./dev_transfers.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./dev_transfers.c:28: usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) { |
|||
; --------------------------------- |
|||
; Function usbdev_control_transfer |
|||
; --------------------------------- |
|||
_usbdev_control_transfer: |
|||
;source-doc/base-drv/./dev_transfers.c:29: return usb_control_transfer(cmd_packet, buffer, device->address, device->max_packet_size); |
|||
ld hl,2 |
|||
add hl, sp |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
ld l, e |
|||
ld h, d |
|||
inc hl |
|||
ld b, (hl) |
|||
ex de, hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld iy,6 |
|||
add iy, sp |
|||
ld e,(iy+0) |
|||
ld d,(iy+1) |
|||
ld c,a |
|||
push bc |
|||
push de |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
;source-doc/base-drv/./dev_transfers.c:30: } |
|||
ret |
|||
;source-doc/base-drv/./dev_transfers.c:32: usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) { |
|||
; --------------------------------- |
|||
; Function usbdev_blk_out_trnsfer |
|||
; --------------------------------- |
|||
_usbdev_blk_out_trnsfer: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
;source-doc/base-drv/./dev_transfers.c:36: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT]; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld e, c |
|||
ld d, b |
|||
inc de |
|||
inc de |
|||
inc de |
|||
;source-doc/base-drv/./dev_transfers.c:38: result = usb_data_out_transfer(buffer, buffer_size, dev->address, endpoint); |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
push bc |
|||
push de |
|||
push de |
|||
push af |
|||
inc sp |
|||
ld l,(ix+8) |
|||
ld h,(ix+9) |
|||
push hl |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
call _usb_data_out_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
pop bc |
|||
;source-doc/base-drv/./dev_transfers.c:40: if (result == USB_ERR_STALL) { |
|||
ld a, l |
|||
sub 0x02 |
|||
jr NZ,l_usbdev_blk_out_trnsfer_00102 |
|||
;source-doc/base-drv/./dev_transfers.c:41: usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size); |
|||
ld l, c |
|||
ld h, b |
|||
inc hl |
|||
ld a, (hl) |
|||
ld (ix-1),a |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld b, a |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
rrca |
|||
and 0x07 |
|||
push de |
|||
ld h,(ix-1) |
|||
ld l,b |
|||
push hl |
|||
push af |
|||
inc sp |
|||
call _usbtrn_clear_endpoint_halt |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
;source-doc/base-drv/./dev_transfers.c:42: endpoint->toggle = 0; |
|||
ex de, hl |
|||
res 0, (hl) |
|||
;source-doc/base-drv/./dev_transfers.c:43: return USB_ERR_STALL; |
|||
ld l,0x02 |
|||
;source-doc/base-drv/./dev_transfers.c:46: RETURN_CHECK(result); |
|||
l_usbdev_blk_out_trnsfer_00102: |
|||
;source-doc/base-drv/./dev_transfers.c:47: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./dev_transfers.c:49: usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) { |
|||
; --------------------------------- |
|||
; Function usbdev_bulk_in_transfer |
|||
; --------------------------------- |
|||
_usbdev_bulk_in_transfer: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
;source-doc/base-drv/./dev_transfers.c:53: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN]; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld hl,0x0006 |
|||
add hl, bc |
|||
;source-doc/base-drv/./dev_transfers.c:55: result = usb_data_in_transfer_n(buffer, buffer_size, dev->address, endpoint); |
|||
ld e,c |
|||
ld d,b |
|||
ex de,hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
push bc |
|||
push de |
|||
push de |
|||
push af |
|||
inc sp |
|||
ld l,(ix+8) |
|||
ld h,(ix+9) |
|||
push hl |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
call _usb_data_in_transfer_n |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
pop bc |
|||
;source-doc/base-drv/./dev_transfers.c:57: if (result == USB_ERR_STALL) { |
|||
ld a, l |
|||
sub 0x02 |
|||
jr NZ,l_usbdev_bulk_in_transfer_00102 |
|||
;source-doc/base-drv/./dev_transfers.c:58: usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size); |
|||
ld l, c |
|||
ld h, b |
|||
inc hl |
|||
ld a, (hl) |
|||
ld (ix-1),a |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld b, a |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
rrca |
|||
and 0x07 |
|||
push de |
|||
ld h,(ix-1) |
|||
ld l,b |
|||
push hl |
|||
push af |
|||
inc sp |
|||
call _usbtrn_clear_endpoint_halt |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
;source-doc/base-drv/./dev_transfers.c:59: endpoint->toggle = 0; |
|||
ex de, hl |
|||
res 0, (hl) |
|||
;source-doc/base-drv/./dev_transfers.c:60: return USB_ERR_STALL; |
|||
ld l,0x02 |
|||
;source-doc/base-drv/./dev_transfers.c:63: RETURN_CHECK(result); |
|||
l_usbdev_bulk_in_transfer_00102: |
|||
;source-doc/base-drv/./dev_transfers.c:64: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./dev_transfers.c:66: usb_error usbdev_dat_in_trnsfer(device_config *const device, |
|||
; --------------------------------- |
|||
; Function usbdev_dat_in_trnsfer |
|||
; --------------------------------- |
|||
_usbdev_dat_in_trnsfer: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
;source-doc/base-drv/./dev_transfers.c:73: endpoint_param *const endpoint = &device->endpoints[endpoint_type]; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld e, c |
|||
ld d, b |
|||
inc de |
|||
inc de |
|||
inc de |
|||
push de |
|||
ld l,(ix+10) |
|||
ld e, l |
|||
add hl, hl |
|||
add hl, de |
|||
pop de |
|||
ld h,0x00 |
|||
add hl, de |
|||
;source-doc/base-drv/./dev_transfers.c:75: result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint); |
|||
ld e,c |
|||
ld d,b |
|||
ex de,hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
push bc |
|||
push de |
|||
push de |
|||
push af |
|||
inc sp |
|||
ld l,(ix+8) |
|||
ld h,(ix+9) |
|||
push hl |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
call _usb_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
pop bc |
|||
;source-doc/base-drv/./dev_transfers.c:77: if (result == USB_ERR_STALL) { |
|||
ld a, l |
|||
sub 0x02 |
|||
jr NZ,l_usbdev_dat_in_trnsfer_00102 |
|||
;source-doc/base-drv/./dev_transfers.c:78: usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size); |
|||
ld l, c |
|||
ld h, b |
|||
inc hl |
|||
ld a, (hl) |
|||
ld (ix-1),a |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld b, a |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
rrca |
|||
and 0x07 |
|||
push de |
|||
ld h,(ix-1) |
|||
ld l,b |
|||
push hl |
|||
push af |
|||
inc sp |
|||
call _usbtrn_clear_endpoint_halt |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
;source-doc/base-drv/./dev_transfers.c:79: endpoint->toggle = 0; |
|||
ex de, hl |
|||
res 0, (hl) |
|||
;source-doc/base-drv/./dev_transfers.c:80: return USB_ERR_STALL; |
|||
ld l,0x02 |
|||
;source-doc/base-drv/./dev_transfers.c:83: RETURN_CHECK(result); |
|||
l_usbdev_dat_in_trnsfer_00102: |
|||
;source-doc/base-drv/./dev_transfers.c:84: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./dev_transfers.c:86: usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function usbdev_dat_in_trnsfer_0 |
|||
; --------------------------------- |
|||
_usbdev_dat_in_trnsfer_0: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./dev_transfers.c:90: endpoint_param *const endpoint = &device->endpoints[0]; |
|||
push hl |
|||
ld c,l |
|||
ld b,h |
|||
pop iy |
|||
inc iy |
|||
inc iy |
|||
inc iy |
|||
;source-doc/base-drv/./dev_transfers.c:92: result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint); |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld l,(ix+4) |
|||
ld h,0x00 |
|||
push bc |
|||
push iy |
|||
push iy |
|||
push af |
|||
inc sp |
|||
push hl |
|||
push de |
|||
call _usb_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld d, l |
|||
pop iy |
|||
pop bc |
|||
;source-doc/base-drv/./dev_transfers.c:94: if (result == USB_ERR_STALL) { |
|||
ld a, d |
|||
sub 0x02 |
|||
jr NZ,l_usbdev_dat_in_trnsfer_0_00102 |
|||
;source-doc/base-drv/./dev_transfers.c:95: usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size); |
|||
ld l, c |
|||
ld h, b |
|||
inc hl |
|||
ld d, (hl) |
|||
ld l, c |
|||
ld h, b |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld b, a |
|||
push iy |
|||
pop hl |
|||
ld a, (hl) |
|||
rrca |
|||
and 0x07 |
|||
push iy |
|||
ld e,b |
|||
push de |
|||
push af |
|||
inc sp |
|||
call _usbtrn_clear_endpoint_halt |
|||
pop af |
|||
inc sp |
|||
pop iy |
|||
;source-doc/base-drv/./dev_transfers.c:96: endpoint->toggle = 0; |
|||
push iy |
|||
pop hl |
|||
res 0, (hl) |
|||
;source-doc/base-drv/./dev_transfers.c:97: return USB_ERR_STALL; |
|||
ld a,0x02 |
|||
jr l_usbdev_dat_in_trnsfer_0_00103 |
|||
l_usbdev_dat_in_trnsfer_0_00102: |
|||
;source-doc/base-drv/./dev_transfers.c:100: RETURN_CHECK(result); |
|||
ld a, d |
|||
l_usbdev_dat_in_trnsfer_0_00103: |
|||
;source-doc/base-drv/./dev_transfers.c:101: } |
|||
pop ix |
|||
pop hl |
|||
inc sp |
|||
jp (hl) |
|||
@ -0,0 +1,948 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./enumerate.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./enumerate.c:13: void parse_endpoint_keyboard(device_config_keyboard *const keyboard_config, const endpoint_descriptor const *pEndpoint) |
|||
; --------------------------------- |
|||
; Function parse_endpoint_keyboard |
|||
; --------------------------------- |
|||
_parse_endpoint_keyboard: |
|||
;source-doc/base-drv/./enumerate.c:15: endpoint_param *const ep = &keyboard_config->endpoints[0]; |
|||
inc hl |
|||
inc hl |
|||
inc hl |
|||
push hl |
|||
pop iy |
|||
;source-doc/base-drv/./enumerate.c:16: ep->number = pEndpoint->bEndpointAddress; |
|||
push iy |
|||
pop bc |
|||
ld l, e |
|||
ld h, d |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
rlca |
|||
and 0x0e |
|||
ld l, a |
|||
ld a, (bc) |
|||
and 0xf1 |
|||
or l |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:17: ep->toggle = 0; |
|||
push iy |
|||
pop hl |
|||
res 0, (hl) |
|||
;source-doc/base-drv/./enumerate.c:18: ep->max_packet_sizex = calc_max_packet_sizex(pEndpoint->wMaxPacketSize); |
|||
push iy |
|||
pop bc |
|||
inc bc |
|||
ld hl,4 |
|||
add hl, de |
|||
ld e, (hl) |
|||
inc hl |
|||
ld a, (hl) |
|||
and 0x03 |
|||
ld d, a |
|||
ld a, e |
|||
ld (bc), a |
|||
inc bc |
|||
ld a, d |
|||
and 0x03 |
|||
ld l,a |
|||
ld a, (bc) |
|||
and 0xfc |
|||
or l |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:19: } |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:21: usb_device_type identify_class_driver(_working *const working) { |
|||
; --------------------------------- |
|||
; Function identify_class_driver |
|||
; --------------------------------- |
|||
_identify_class_driver: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./enumerate.c:22: const interface_descriptor *const p = (const interface_descriptor *)working->ptr; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld hl,27 |
|||
add hl, bc |
|||
ld c, (hl) |
|||
inc hl |
|||
ld b, (hl) |
|||
;source-doc/base-drv/./enumerate.c:23: if (p->bInterfaceClass == 2) |
|||
push bc |
|||
pop iy |
|||
ld e,(iy+5) |
|||
ld a, e |
|||
sub 0x02 |
|||
jr NZ,l_identify_class_driver_00102 |
|||
;source-doc/base-drv/./enumerate.c:24: return USB_IS_CDC; |
|||
ld l,0x03 |
|||
jr l_identify_class_driver_00118 |
|||
l_identify_class_driver_00102: |
|||
;source-doc/base-drv/./enumerate.c:26: if (p->bInterfaceClass == 8 && (p->bInterfaceSubClass == 6 || p->bInterfaceSubClass == 5) && p->bInterfaceProtocol == 80) |
|||
ld a, e |
|||
sub 0x08 |
|||
jr NZ,l_identify_class_driver_00177 |
|||
ld a,0x01 |
|||
jr l_identify_class_driver_00178 |
|||
l_identify_class_driver_00177: |
|||
xor a |
|||
l_identify_class_driver_00178: |
|||
ld d,a |
|||
or a |
|||
jr Z,l_identify_class_driver_00104 |
|||
ld hl,0x0006 |
|||
add hl,bc |
|||
ld a, (hl) |
|||
cp 0x06 |
|||
jr Z,l_identify_class_driver_00107 |
|||
sub 0x05 |
|||
jr NZ,l_identify_class_driver_00104 |
|||
l_identify_class_driver_00107: |
|||
ld hl,0x0007 |
|||
add hl,bc |
|||
ld a, (hl) |
|||
sub 0x50 |
|||
jr NZ,l_identify_class_driver_00104 |
|||
;source-doc/base-drv/./enumerate.c:27: return USB_IS_MASS_STORAGE; |
|||
ld l,0x02 |
|||
jr l_identify_class_driver_00118 |
|||
l_identify_class_driver_00104: |
|||
;source-doc/base-drv/./enumerate.c:29: if (p->bInterfaceClass == 8 && p->bInterfaceSubClass == 4 && p->bInterfaceProtocol == 0) |
|||
ld a, d |
|||
or a |
|||
jr Z,l_identify_class_driver_00109 |
|||
ld hl,0x0006 |
|||
add hl,bc |
|||
ld a, (hl) |
|||
sub 0x04 |
|||
jr NZ,l_identify_class_driver_00109 |
|||
ld hl,0x0007 |
|||
add hl,bc |
|||
ld a, (hl) |
|||
or a |
|||
jr NZ,l_identify_class_driver_00109 |
|||
;source-doc/base-drv/./enumerate.c:30: return USB_IS_FLOPPY; |
|||
ld l,0x01 |
|||
jr l_identify_class_driver_00118 |
|||
l_identify_class_driver_00109: |
|||
;source-doc/base-drv/./enumerate.c:32: if (p->bInterfaceClass == 9 && p->bInterfaceSubClass == 0 && p->bInterfaceProtocol == 0) |
|||
ld a, e |
|||
sub 0x09 |
|||
jr NZ,l_identify_class_driver_00113 |
|||
ld hl,0x0006 |
|||
add hl,bc |
|||
ld a, (hl) |
|||
or a |
|||
jr NZ,l_identify_class_driver_00113 |
|||
ld hl,7 |
|||
add hl, bc |
|||
ld a, (hl) |
|||
or a |
|||
jr NZ,l_identify_class_driver_00113 |
|||
;source-doc/base-drv/./enumerate.c:33: return USB_IS_HUB; |
|||
ld l,0x0f |
|||
jr l_identify_class_driver_00118 |
|||
l_identify_class_driver_00113: |
|||
;source-doc/base-drv/./enumerate.c:35: if (p->bInterfaceClass == 3) |
|||
ld a, e |
|||
sub 0x03 |
|||
jr NZ,l_identify_class_driver_00117 |
|||
;source-doc/base-drv/./enumerate.c:36: return USB_IS_KEYBOARD; |
|||
ld l,0x04 |
|||
jr l_identify_class_driver_00118 |
|||
l_identify_class_driver_00117: |
|||
;source-doc/base-drv/./enumerate.c:38: return USB_IS_UNKNOWN; |
|||
ld l,0x06 |
|||
l_identify_class_driver_00118: |
|||
;source-doc/base-drv/./enumerate.c:39: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:41: usb_error op_interface_next(_working *const working) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function op_interface_next |
|||
; --------------------------------- |
|||
_op_interface_next: |
|||
ex de, hl |
|||
;source-doc/base-drv/./enumerate.c:42: if (--working->interface_count == 0) |
|||
ld hl,0x0016 |
|||
add hl, de |
|||
ld a, (hl) |
|||
dec a |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:43: return USB_ERR_OK; |
|||
or a |
|||
jr NZ,l_op_interface_next_00102 |
|||
ld l,a |
|||
jr l_op_interface_next_00103 |
|||
l_op_interface_next_00102: |
|||
;source-doc/base-drv/./enumerate.c:45: return op_id_class_drv(working); |
|||
ex de, hl |
|||
call _op_id_class_drv |
|||
ld l, a |
|||
l_op_interface_next_00103: |
|||
;source-doc/base-drv/./enumerate.c:46: } |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:48: usb_error op_endpoint_next(_working *const working) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function op_endpoint_next |
|||
; --------------------------------- |
|||
_op_endpoint_next: |
|||
ex de, hl |
|||
;source-doc/base-drv/./enumerate.c:49: if (--working->endpoint_count > 0) { |
|||
ld hl,0x0017 |
|||
add hl, de |
|||
ld a, (hl) |
|||
dec a |
|||
ld (hl), a |
|||
or a |
|||
jr Z,l_op_endpoint_next_00102 |
|||
;source-doc/base-drv/./enumerate.c:50: working->ptr += ((endpoint_descriptor *)working->ptr)->bLength; |
|||
ld hl,0x001b |
|||
add hl, de |
|||
ld c, (hl) |
|||
inc hl |
|||
ld b, (hl) |
|||
dec hl |
|||
ld a, (bc) |
|||
add a, c |
|||
ld c, a |
|||
ld a,0x00 |
|||
adc a, b |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:51: return op_parse_endpoint(working); |
|||
ex de, hl |
|||
jp _op_parse_endpoint |
|||
jr l_op_endpoint_next_00103 |
|||
l_op_endpoint_next_00102: |
|||
;source-doc/base-drv/./enumerate.c:54: return op_interface_next(working); |
|||
ex de, hl |
|||
call _op_interface_next |
|||
ld a, l |
|||
l_op_endpoint_next_00103: |
|||
;source-doc/base-drv/./enumerate.c:55: } |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:57: usb_error op_parse_endpoint(_working *const working) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function op_parse_endpoint |
|||
; --------------------------------- |
|||
_op_parse_endpoint: |
|||
;source-doc/base-drv/./enumerate.c:58: const endpoint_descriptor *endpoint = (endpoint_descriptor *)working->ptr; |
|||
ld c,l |
|||
ld b,h |
|||
ld hl,27 |
|||
add hl,bc |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
push de |
|||
pop iy |
|||
;source-doc/base-drv/./enumerate.c:59: device_config *const device = working->p_current_device; |
|||
ld hl,29 |
|||
add hl,bc |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
;source-doc/base-drv/./enumerate.c:61: switch (working->usb_device) { |
|||
ld l, c |
|||
ld h, b |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
cp 0x01 |
|||
jr Z,l_op_parse_endpoint_00102 |
|||
cp 0x02 |
|||
jr Z,l_op_parse_endpoint_00102 |
|||
sub 0x04 |
|||
jr Z,l_op_parse_endpoint_00103 |
|||
jr l_op_parse_endpoint_00104 |
|||
;source-doc/base-drv/./enumerate.c:63: case USB_IS_MASS_STORAGE: { |
|||
l_op_parse_endpoint_00102: |
|||
;source-doc/base-drv/./enumerate.c:64: parse_endpoints(device, endpoint); |
|||
push bc |
|||
push iy |
|||
push de |
|||
call _parse_endpoints |
|||
pop af |
|||
pop af |
|||
pop bc |
|||
;source-doc/base-drv/./enumerate.c:65: break; |
|||
jr l_op_parse_endpoint_00104 |
|||
;source-doc/base-drv/./enumerate.c:68: case USB_IS_KEYBOARD: { |
|||
l_op_parse_endpoint_00103: |
|||
;source-doc/base-drv/./enumerate.c:69: parse_endpoint_keyboard((device_config_keyboard *)device, endpoint); |
|||
ex de, hl |
|||
push bc |
|||
push iy |
|||
pop de |
|||
call _parse_endpoint_keyboard |
|||
pop bc |
|||
;source-doc/base-drv/./enumerate.c:72: } |
|||
l_op_parse_endpoint_00104: |
|||
;source-doc/base-drv/./enumerate.c:74: return op_endpoint_next(working); |
|||
ld l, c |
|||
ld h, b |
|||
;source-doc/base-drv/./enumerate.c:75: } |
|||
jp _op_endpoint_next |
|||
;source-doc/base-drv/./enumerate.c:78: configure_device(const _working *const working, const interface_descriptor *const interface, device_config *const dev_cfg) { |
|||
; --------------------------------- |
|||
; Function configure_device |
|||
; --------------------------------- |
|||
_configure_device: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/base-drv/./enumerate.c:79: dev_cfg->interface_number = interface->bInterfaceNumber; |
|||
ld e,(ix+8) |
|||
ld d,(ix+9) |
|||
ld c, e |
|||
ld b, d |
|||
inc bc |
|||
inc bc |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:80: dev_cfg->max_packet_size = working->desc.bMaxPacketSize0; |
|||
ld hl,0x0001 |
|||
add hl, de |
|||
ex (sp), hl |
|||
push iy |
|||
ex (sp), hl |
|||
ld l,(ix+4) |
|||
ex (sp), hl |
|||
ex (sp), hl |
|||
ld h,(ix+5) |
|||
ex (sp), hl |
|||
pop iy |
|||
push iy |
|||
pop bc |
|||
ld hl,10 |
|||
add hl, bc |
|||
ld a, (hl) |
|||
pop hl |
|||
push hl |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:81: dev_cfg->address = working->current_device_address; |
|||
ld c, e |
|||
ld b, d |
|||
push iy |
|||
pop hl |
|||
ld a,+((0x0018) & 0xFF) |
|||
add a,l |
|||
ld l,a |
|||
ld a,+((0x0018) / 256) |
|||
adc a,h |
|||
ld h,a |
|||
ld a, (hl) |
|||
add a, a |
|||
add a, a |
|||
add a, a |
|||
add a, a |
|||
ld l, a |
|||
ld a, (bc) |
|||
and 0x0f |
|||
or l |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:82: dev_cfg->type = working->usb_device; |
|||
ld c, e |
|||
ld b, d |
|||
push iy |
|||
pop hl |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
and 0x0f |
|||
ld l, a |
|||
ld a, (bc) |
|||
and 0xf0 |
|||
or l |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:84: return usbtrn_set_configuration(dev_cfg->address, dev_cfg->max_packet_size, working->config.desc.bConfigurationvalue); |
|||
push iy |
|||
pop bc |
|||
ld hl,36 |
|||
add hl, bc |
|||
ld c, (hl) |
|||
pop hl |
|||
ld b,(hl) |
|||
push hl |
|||
ex de, hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld h, c |
|||
ld l,b |
|||
push hl |
|||
push af |
|||
inc sp |
|||
call _usbtrn_set_configuration |
|||
;source-doc/base-drv/./enumerate.c:85: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:87: usb_error op_capture_hub_driver_interface(_working *const working) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function op_capture_hub_driver_interface |
|||
; --------------------------------- |
|||
_op_capture_hub_driver_interfac: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld iy, -7 |
|||
add iy, sp |
|||
ld sp, iy |
|||
;source-doc/base-drv/./enumerate.c:88: const interface_descriptor *const interface = (interface_descriptor *)working->ptr; |
|||
push hl |
|||
ex de,hl |
|||
pop iy |
|||
ld c,(iy+28) |
|||
ld a,(iy+27) |
|||
ld (ix-4),a |
|||
ld (ix-3),c |
|||
;source-doc/base-drv/./enumerate.c:92: working->hub_config = &hub_config; |
|||
ld hl,0x0019 |
|||
add hl, de |
|||
ld (ix-2),l |
|||
ld (ix-1),h |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld c, l |
|||
ld l,(ix-2) |
|||
ld b,h |
|||
ld h,(ix-1) |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), b |
|||
;source-doc/base-drv/./enumerate.c:94: hub_config.type = USB_IS_HUB; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
or 0x0f |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:95: CHECK(configure_device(working, interface, (device_config *const)&hub_config)); |
|||
push de |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix-4) |
|||
ld h,(ix-3) |
|||
push hl |
|||
push de |
|||
call _configure_device |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
pop de |
|||
or a |
|||
jr NZ,l_op_capture_hub_driver_interfa |
|||
;source-doc/base-drv/./enumerate.c:96: RETURN_CHECK(configure_usb_hub(working)); |
|||
ex de, hl |
|||
call _configure_usb_hub |
|||
ld a, l |
|||
l_op_capture_hub_driver_interfa: |
|||
;source-doc/base-drv/./enumerate.c:97: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:99: usb_error op_cap_drv_intf(_working *const working) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function op_cap_drv_intf |
|||
; --------------------------------- |
|||
_op_cap_drv_intf: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld iy, -16 |
|||
add iy, sp |
|||
ld sp, iy |
|||
;source-doc/base-drv/./enumerate.c:102: const interface_descriptor *const interface = (interface_descriptor *)working->ptr; |
|||
ld (ix-2),l |
|||
ld (ix-1),h |
|||
ld de,0x001b |
|||
add hl, de |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
dec hl |
|||
ld c, e |
|||
ld b, d |
|||
;source-doc/base-drv/./enumerate.c:104: working->ptr += interface->bLength; |
|||
ld a, (bc) |
|||
add a, e |
|||
ld e, a |
|||
ld a,0x00 |
|||
adc a, d |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:105: working->endpoint_count = interface->bNumEndpoints; |
|||
ld a,(ix-2) |
|||
add a,0x17 |
|||
ld e, a |
|||
ld a,(ix-1) |
|||
adc a,0x00 |
|||
ld d, a |
|||
push bc |
|||
pop iy |
|||
ld a,(iy+4) |
|||
ld (de), a |
|||
;source-doc/base-drv/./enumerate.c:106: working->p_current_device = NULL; |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
ld de,0x001d |
|||
add hl,de |
|||
ld (ix-4),l |
|||
ld (ix-3),h |
|||
xor a |
|||
ld (hl), a |
|||
inc hl |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:108: switch (working->usb_device) { |
|||
ld e,(ix-2) |
|||
ld d,(ix-1) |
|||
inc de |
|||
inc de |
|||
ld a, (de) |
|||
cp 0x06 |
|||
jr Z,l_op_cap_drv_intf_00104 |
|||
sub 0x0f |
|||
jr NZ,l_op_cap_drv_intf_00107 |
|||
;source-doc/base-drv/./enumerate.c:110: CHECK(op_capture_hub_driver_interface(working)) |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
call _op_capture_hub_driver_interfac |
|||
or a |
|||
jr Z,l_op_cap_drv_intf_00112 |
|||
ld l, a |
|||
jr l_op_cap_drv_intf_00115 |
|||
;source-doc/base-drv/./enumerate.c:114: case USB_IS_UNKNOWN: { |
|||
l_op_cap_drv_intf_00104: |
|||
;source-doc/base-drv/./enumerate.c:116: memset(&unkown_dev_cfg, 0, sizeof(device_config)); |
|||
push bc |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x0c |
|||
push hl |
|||
call _memset_callee |
|||
pop bc |
|||
;source-doc/base-drv/./enumerate.c:117: working->p_current_device = &unkown_dev_cfg; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld l,(ix-4) |
|||
ld h,(ix-3) |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
;source-doc/base-drv/./enumerate.c:118: CHECK(configure_device(working, interface, &unkown_dev_cfg)); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
push bc |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _configure_device |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
or a |
|||
jr Z,l_op_cap_drv_intf_00112 |
|||
jr l_op_cap_drv_intf_00115 |
|||
;source-doc/base-drv/./enumerate.c:122: default: { |
|||
l_op_cap_drv_intf_00107: |
|||
;source-doc/base-drv/./enumerate.c:123: device_config *dev_cfg = find_first_free(); |
|||
push bc |
|||
call _find_first_free |
|||
;source-doc/base-drv/./enumerate.c:124: if (dev_cfg == NULL) |
|||
pop bc |
|||
ld a,h |
|||
or l |
|||
ex de,hl |
|||
jr NZ,l_op_cap_drv_intf_00109 |
|||
;source-doc/base-drv/./enumerate.c:125: return USB_ERR_OUT_OF_MEMORY; |
|||
ld l,0x83 |
|||
jr l_op_cap_drv_intf_00115 |
|||
l_op_cap_drv_intf_00109: |
|||
;source-doc/base-drv/./enumerate.c:126: working->p_current_device = dev_cfg; |
|||
ld l,(ix-4) |
|||
ld h,(ix-3) |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
;source-doc/base-drv/./enumerate.c:127: CHECK(configure_device(working, interface, dev_cfg)); |
|||
push de |
|||
push bc |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _configure_device |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
or a |
|||
;source-doc/base-drv/./enumerate.c:130: } |
|||
jr NZ,l_op_cap_drv_intf_00115 |
|||
l_op_cap_drv_intf_00112: |
|||
;source-doc/base-drv/./enumerate.c:132: CHECK(op_parse_endpoint(working)); |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
call _op_parse_endpoint |
|||
or a |
|||
jr Z,l_op_cap_drv_intf_00114 |
|||
ld l, a |
|||
jr l_op_cap_drv_intf_00115 |
|||
l_op_cap_drv_intf_00114: |
|||
;source-doc/base-drv/./enumerate.c:134: return result; |
|||
ld l, a |
|||
l_op_cap_drv_intf_00115: |
|||
;source-doc/base-drv/./enumerate.c:135: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:137: usb_error op_id_class_drv(_working *const working) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function op_id_class_drv |
|||
; --------------------------------- |
|||
_op_id_class_drv: |
|||
;source-doc/base-drv/./enumerate.c:139: const interface_descriptor *const ptr = (const interface_descriptor *)working->ptr; |
|||
push hl |
|||
ex de,hl |
|||
pop iy |
|||
ld l,(iy+27) |
|||
ld h,(iy+28) |
|||
;source-doc/base-drv/./enumerate.c:141: working->usb_device = ptr->bLength > 5 ? identify_class_driver(working) : 0; |
|||
ld c, e |
|||
ld b, d |
|||
inc bc |
|||
inc bc |
|||
ld l, (hl) |
|||
ld a,0x05 |
|||
sub l |
|||
jr NC,l_op_id_class_drv_00105 |
|||
push bc |
|||
push de |
|||
push de |
|||
call _identify_class_driver |
|||
pop af |
|||
ld a, l |
|||
pop de |
|||
pop bc |
|||
ld l,0x00 |
|||
jr l_op_id_class_drv_00106 |
|||
l_op_id_class_drv_00105: |
|||
xor a |
|||
ld l, a |
|||
l_op_id_class_drv_00106: |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:143: CHECK(op_cap_drv_intf(working)); |
|||
ex de, hl |
|||
call _op_cap_drv_intf |
|||
ld a, l |
|||
or a |
|||
ret NZ |
|||
;source-doc/base-drv/./enumerate.c:145: return result; |
|||
;source-doc/base-drv/./enumerate.c:146: } |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:148: usb_error op_get_cfg_desc(_working *const working) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function op_get_cfg_desc |
|||
; --------------------------------- |
|||
_op_get_cfg_desc: |
|||
ex de, hl |
|||
;source-doc/base-drv/./enumerate.c:151: memset(working->config.buffer, 0, MAX_CONFIG_SIZE); |
|||
ld iy,0x001f |
|||
add iy, de |
|||
push iy |
|||
pop bc |
|||
push de |
|||
push iy |
|||
push bc |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x8c |
|||
push hl |
|||
call _memset_callee |
|||
pop iy |
|||
pop de |
|||
;source-doc/base-drv/./enumerate.c:153: const uint8_t max_packet_size = working->desc.bMaxPacketSize0; |
|||
ld c, e |
|||
ld b, d |
|||
inc bc |
|||
inc bc |
|||
inc bc |
|||
ld hl,7 |
|||
add hl, bc |
|||
ld a, (hl) |
|||
;source-doc/base-drv/./enumerate.c:156: working->config.buffer)); |
|||
ld c, e |
|||
ld b, d |
|||
ld hl,24 |
|||
add hl, bc |
|||
ld b, (hl) |
|||
ld l, e |
|||
ld h, d |
|||
push bc |
|||
ld bc,0x0015 |
|||
add hl, bc |
|||
pop bc |
|||
ld c, (hl) |
|||
push de |
|||
push iy |
|||
push iy |
|||
ld h,0x8c |
|||
ld l,a |
|||
push hl |
|||
push bc |
|||
call _usbtrn_gfull_cfg_desc |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
pop iy |
|||
pop de |
|||
or a |
|||
ret NZ |
|||
;source-doc/base-drv/./enumerate.c:158: working->ptr = (working->config.buffer + sizeof(config_descriptor)); |
|||
ld hl,0x001b |
|||
add hl, de |
|||
ld a, e |
|||
add a,0x1f |
|||
ld c, a |
|||
ld a, d |
|||
adc a,0x00 |
|||
ld b, a |
|||
ld a, c |
|||
add a,0x09 |
|||
ld c, a |
|||
ld a, b |
|||
adc a,0x00 |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:159: working->interface_count = working->config.desc.bNumInterfaces; |
|||
ld hl,0x0016 |
|||
add hl, de |
|||
ld c, l |
|||
ld b, h |
|||
push iy |
|||
pop hl |
|||
inc hl |
|||
inc hl |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
ld (bc), a |
|||
;source-doc/base-drv/./enumerate.c:161: CHECK(op_id_class_drv(working)); |
|||
ex de, hl |
|||
call _op_id_class_drv |
|||
or a |
|||
ret NZ |
|||
;source-doc/base-drv/./enumerate.c:163: return result; |
|||
;source-doc/base-drv/./enumerate.c:164: } |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:166: usb_error read_all_configs(enumeration_state *const state) { |
|||
; --------------------------------- |
|||
; Function read_all_configs |
|||
; --------------------------------- |
|||
_read_all_configs: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -171 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./enumerate.c:171: memset(&working, 0, sizeof(_working)); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0xab |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/base-drv/./enumerate.c:172: working.state = state; |
|||
pop hl |
|||
ld e,l |
|||
ld d,h |
|||
ld a,(ix+4) |
|||
ld (hl), a |
|||
inc hl |
|||
ld a,(ix+5) |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate.c:174: CHECK(usbtrn_get_descriptor(&working.desc)); |
|||
push de |
|||
ld hl,5 |
|||
add hl, sp |
|||
push hl |
|||
call _usbtrn_get_descriptor |
|||
pop af |
|||
pop de |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_read_all_configs_00111 |
|||
;source-doc/base-drv/./enumerate.c:176: state->next_device_address++; |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
ld c, (hl) |
|||
inc c |
|||
ld (hl), c |
|||
;source-doc/base-drv/./enumerate.c:177: working.current_device_address = state->next_device_address; |
|||
ld hl,0x0018 |
|||
add hl, de |
|||
ld (hl), c |
|||
;source-doc/base-drv/./enumerate.c:178: CHECK(usbtrn_set_address(working.current_device_address)); |
|||
push de |
|||
ld l, c |
|||
call _usbtrn_set_address |
|||
pop de |
|||
ld a, l |
|||
;source-doc/base-drv/./enumerate.c:180: for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) { |
|||
or a |
|||
jr NZ,l_read_all_configs_00111 |
|||
ld c,a |
|||
l_read_all_configs_00109: |
|||
ld hl,20+0 |
|||
add hl, sp |
|||
ld b, (hl) |
|||
ld a, c |
|||
sub b |
|||
jr NC,l_read_all_configs_00107 |
|||
;source-doc/base-drv/./enumerate.c:181: working.config_index = config_index; |
|||
ld hl,0x0015 |
|||
add hl, de |
|||
ld (hl), c |
|||
;source-doc/base-drv/./enumerate.c:183: CHECK(op_get_cfg_desc(&working)); |
|||
push bc |
|||
push de |
|||
ld hl,4 |
|||
add hl, sp |
|||
call _op_get_cfg_desc |
|||
pop de |
|||
pop bc |
|||
or a |
|||
jr Z,l_read_all_configs_00110 |
|||
ld l, a |
|||
jr l_read_all_configs_00111 |
|||
l_read_all_configs_00110: |
|||
;source-doc/base-drv/./enumerate.c:180: for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) { |
|||
inc c |
|||
jr l_read_all_configs_00109 |
|||
l_read_all_configs_00107: |
|||
;source-doc/base-drv/./enumerate.c:186: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_read_all_configs_00111: |
|||
;source-doc/base-drv/./enumerate.c:187: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate.c:189: usb_error enumerate_all_devices(void) { |
|||
; --------------------------------- |
|||
; Function enumerate_all_devices |
|||
; --------------------------------- |
|||
_enumerate_all_devices: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
;source-doc/base-drv/./enumerate.c:190: _usb_state *const work_area = get_usb_work_area(); |
|||
;source-doc/base-drv/./enumerate.c:192: memset(&state, 0, sizeof(enumeration_state)); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x01 |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/base-drv/./enumerate.c:193: state.next_device_address = 0; |
|||
ld (ix-1),0x00 |
|||
;source-doc/base-drv/./enumerate.c:195: usb_error result = read_all_configs(&state); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
call _read_all_configs |
|||
pop af |
|||
;source-doc/base-drv/./enumerate.c:197: work_area->count_of_detected_usb_devices = state.next_device_address; |
|||
ld a,(ix-1) |
|||
ld c,l |
|||
ld ((_x + 1)),a |
|||
;source-doc/base-drv/./enumerate.c:199: CHECK(result); |
|||
ld a, c |
|||
or a |
|||
jr Z,l_enumerate_all_devices_00102 |
|||
ld l, c |
|||
jr l_enumerate_all_devices_00103 |
|||
l_enumerate_all_devices_00102: |
|||
;source-doc/base-drv/./enumerate.c:201: return result; |
|||
ld l, c |
|||
l_enumerate_all_devices_00103: |
|||
;source-doc/base-drv/./enumerate.c:202: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
@ -0,0 +1,470 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./enumerate_hub.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./enumerate_hub.c:13: usb_error hub_set_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) { |
|||
; --------------------------------- |
|||
; Function hub_set_feature |
|||
; --------------------------------- |
|||
_hub_set_feature: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./enumerate_hub.c:15: set_feature = cmd_set_feature; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_set_feature |
|||
ldir |
|||
;source-doc/base-drv/./enumerate_hub.c:17: set_feature.bValue[0] = feature; |
|||
ld a,(ix+6) |
|||
ld (ix-6),a |
|||
;source-doc/base-drv/./enumerate_hub.c:18: set_feature.bIndex[0] = index; |
|||
ld a,(ix+7) |
|||
ld (ix-4),a |
|||
;source-doc/base-drv/./enumerate_hub.c:19: return usb_control_transfer(&set_feature, 0, hub_config->address, hub_config->max_packet_size); |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
ld e,l |
|||
ld d,h |
|||
inc hl |
|||
ld b, (hl) |
|||
ex de, hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld c,a |
|||
push bc |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./enumerate_hub.c:20: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
_cmd_set_feature: |
|||
DEFB +0x23 |
|||
DEFB +0x03 |
|||
DEFB +0x08 |
|||
DEFB +0x00 |
|||
DEFB +0x01 |
|||
DEFB +0x00 |
|||
DEFW +0x0000 |
|||
_cmd_clear_feature: |
|||
DEFB +0x23 |
|||
DEFB +0x01 |
|||
DEFB +0x08 |
|||
DEFB +0x00 |
|||
DEFB +0x01 |
|||
DEFB +0x00 |
|||
DEFW +0x0000 |
|||
_cmd_get_status_port: |
|||
DEFB +0xa3 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x01 |
|||
DEFB +0x00 |
|||
DEFW +0x0004 |
|||
;source-doc/base-drv/./enumerate_hub.c:22: usb_error hub_clear_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) { |
|||
; --------------------------------- |
|||
; Function hub_clear_feature |
|||
; --------------------------------- |
|||
_hub_clear_feature: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./enumerate_hub.c:24: clear_feature = cmd_clear_feature; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_clear_feature |
|||
ldir |
|||
;source-doc/base-drv/./enumerate_hub.c:26: clear_feature.bValue[0] = feature; |
|||
ld a,(ix+6) |
|||
ld (ix-6),a |
|||
;source-doc/base-drv/./enumerate_hub.c:27: clear_feature.bIndex[0] = index; |
|||
ld a,(ix+7) |
|||
ld (ix-4),a |
|||
;source-doc/base-drv/./enumerate_hub.c:28: return usb_control_transfer(&clear_feature, 0, hub_config->address, hub_config->max_packet_size); |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
ld e,l |
|||
ld d,h |
|||
inc hl |
|||
ld b, (hl) |
|||
ex de, hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld c,a |
|||
push bc |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./enumerate_hub.c:29: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate_hub.c:31: usb_error hub_get_status_port(const device_config_hub *const hub_config, const uint8_t index, hub_port_status *const port_status) { |
|||
; --------------------------------- |
|||
; Function hub_get_status_port |
|||
; --------------------------------- |
|||
_hub_get_status_port: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./enumerate_hub.c:33: get_status_port = cmd_get_status_port; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_get_status_port |
|||
ldir |
|||
;source-doc/base-drv/./enumerate_hub.c:35: get_status_port.bIndex[0] = index; |
|||
ld a,(ix+6) |
|||
ld (ix-4),a |
|||
;source-doc/base-drv/./enumerate_hub.c:36: return usb_control_transfer(&get_status_port, port_status, hub_config->address, hub_config->max_packet_size); |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
ld e,l |
|||
ld d,h |
|||
inc hl |
|||
ld b, (hl) |
|||
ex de, hl |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld e,(ix+7) |
|||
ld d,(ix+8) |
|||
ld c,a |
|||
push bc |
|||
push de |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./enumerate_hub.c:37: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./enumerate_hub.c:39: usb_error configure_usb_hub(_working *const working) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function configure_usb_hub |
|||
; --------------------------------- |
|||
_configure_usb_hub: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld iy, -14 |
|||
add iy, sp |
|||
ld sp, iy |
|||
;source-doc/base-drv/./enumerate_hub.c:45: const device_config_hub *const hub_config = working->hub_config; |
|||
push hl |
|||
ld c,l |
|||
ld b,h |
|||
pop iy |
|||
ld a,(iy+25) |
|||
ld (ix-2),a |
|||
ld a,(iy+26) |
|||
ld (ix-1),a |
|||
;source-doc/base-drv/./enumerate_hub.c:47: CHECK(hub_get_descriptor(hub_config, &hub_description)); |
|||
push bc |
|||
ld hl,2 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
call _hub_get_descriptor |
|||
pop bc |
|||
ld e,a |
|||
or a |
|||
jr Z,l_configure_usb_hub_00102 |
|||
ld l, e |
|||
jp l_configure_usb_hub_00129 |
|||
l_configure_usb_hub_00102: |
|||
;source-doc/base-drv/./enumerate_hub.c:49: uint8_t i = hub_description.bNbrPorts; |
|||
ld d,(ix-12) |
|||
;source-doc/base-drv/./enumerate_hub.c:50: do { |
|||
l_configure_usb_hub_00126: |
|||
;source-doc/base-drv/./enumerate_hub.c:51: CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
push bc |
|||
push de |
|||
ld e,0x08 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_clear_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jp NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:53: CHECK(hub_set_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
push bc |
|||
push de |
|||
ld e,0x08 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_set_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jp NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:55: hub_clear_feature(hub_config, FEAT_PORT_RESET, i); |
|||
push bc |
|||
push de |
|||
ld e,0x04 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_clear_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
push de |
|||
ld e,0x04 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_set_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jp NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:59: CHECK(hub_get_status_port(hub_config, i, &port_status)); |
|||
push bc |
|||
push de |
|||
ld hl,12 |
|||
add hl, sp |
|||
push hl |
|||
push de |
|||
inc sp |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_get_status_port |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jp NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:61: if (port_status.wPortStatus.port_connection) { |
|||
ld hl,8 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
and 0x01 |
|||
jp Z, l_configure_usb_hub_00124 |
|||
;source-doc/base-drv/./enumerate_hub.c:62: CHECK(hub_clear_feature(hub_config, HUB_FEATURE_PORT_CONNECTION_CHA, i)); |
|||
push bc |
|||
push de |
|||
ld e,0x10 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_clear_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jp NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:64: CHECK(hub_clear_feature(hub_config, FEAT_PORT_ENABLE_CHANGE, i)); |
|||
push bc |
|||
push de |
|||
ld e,0x11 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_clear_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:66: CHECK(hub_clear_feature(hub_config, FEAT_PORT_RESET_CHANGE, i)); |
|||
push bc |
|||
push de |
|||
ld e,0x14 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_clear_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:67: delay_short(); |
|||
push bc |
|||
push de |
|||
call _delay_short |
|||
pop de |
|||
push de |
|||
ld hl,12 |
|||
add hl, sp |
|||
push hl |
|||
push de |
|||
inc sp |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_get_status_port |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_configure_usb_hub_00129 |
|||
;source-doc/base-drv/./enumerate_hub.c:70: delay_short(); |
|||
push bc |
|||
push de |
|||
call _delay_short |
|||
pop de |
|||
;source-doc/base-drv/./enumerate_hub.c:72: CHECK(read_all_configs(working->state)); |
|||
pop hl |
|||
ld e,(hl) |
|||
ld c,l |
|||
ld b,h |
|||
inc hl |
|||
ld h, (hl) |
|||
push bc |
|||
push de |
|||
ld l, e |
|||
push hl |
|||
call _read_all_configs |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr Z,l_configure_usb_hub_00127 |
|||
jr l_configure_usb_hub_00129 |
|||
l_configure_usb_hub_00124: |
|||
;source-doc/base-drv/./enumerate_hub.c:75: CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
push bc |
|||
push de |
|||
ld e,0x08 |
|||
push de |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
call _hub_clear_feature |
|||
pop af |
|||
pop af |
|||
pop de |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_configure_usb_hub_00129 |
|||
l_configure_usb_hub_00127: |
|||
;source-doc/base-drv/./enumerate_hub.c:77: } while (--i != 0); |
|||
dec d |
|||
ld a, d |
|||
;source-doc/base-drv/./enumerate_hub.c:79: return USB_ERR_OK; |
|||
or a |
|||
jp NZ,l_configure_usb_hub_00126 |
|||
ld l,a |
|||
l_configure_usb_hub_00129: |
|||
;source-doc/base-drv/./enumerate_hub.c:80: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
@ -0,0 +1,142 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./enumerate_storage.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./enumerate_storage.c:5: void parse_endpoints(device_config *const storage_dev, const endpoint_descriptor const *pEndpoint) { |
|||
; --------------------------------- |
|||
; Function parse_endpoints |
|||
; --------------------------------- |
|||
_parse_endpoints: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/base-drv/./enumerate_storage.c:7: if (!(pEndpoint->bmAttributes & 0x02)) |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
push bc |
|||
pop iy |
|||
ld a,(iy+3) |
|||
ld (ix-2),a |
|||
bit 1,a |
|||
;source-doc/base-drv/./enumerate_storage.c:8: return; |
|||
jr Z,l_parse_endpoints_00108 |
|||
;source-doc/base-drv/./enumerate_storage.c:10: const uint8_t x = calc_max_packet_sizex(pEndpoint->wMaxPacketSize); |
|||
push bc |
|||
pop iy |
|||
ld a,(iy+4) |
|||
ld (ix-1),a |
|||
;source-doc/base-drv/./enumerate_storage.c:11: endpoint_param *const eps = storage_dev->endpoints; |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
inc de |
|||
inc de |
|||
inc de |
|||
;source-doc/base-drv/./enumerate_storage.c:15: if (!(pEndpoint->bEndpointAddress & 0x80)) |
|||
inc bc |
|||
inc bc |
|||
ld a, (bc) |
|||
ld c,a |
|||
and 0x80 |
|||
ld b,0x00 |
|||
;source-doc/base-drv/./enumerate_storage.c:14: if (pEndpoint->bmAttributes & 0x01) { // 3 -> Interrupt |
|||
bit 0,(ix-2) |
|||
jr Z,l_parse_endpoints_00106 |
|||
;source-doc/base-drv/./enumerate_storage.c:15: if (!(pEndpoint->bEndpointAddress & 0x80)) |
|||
or b |
|||
;source-doc/base-drv/./enumerate_storage.c:16: return; |
|||
jr Z,l_parse_endpoints_00108 |
|||
;source-doc/base-drv/./enumerate_storage.c:18: ep = &eps[ENDPOINT_INTERRUPT_IN]; |
|||
ld hl,0x0006 |
|||
add hl, de |
|||
ex de, hl |
|||
jr l_parse_endpoints_00107 |
|||
l_parse_endpoints_00106: |
|||
;source-doc/base-drv/./enumerate_storage.c:21: ep = (pEndpoint->bEndpointAddress & 0x80) ? &eps[ENDPOINT_BULK_IN] : &eps[ENDPOINT_BULK_OUT]; |
|||
or b |
|||
jr Z,l_parse_endpoints_00110 |
|||
inc de |
|||
inc de |
|||
inc de |
|||
l_parse_endpoints_00110: |
|||
l_parse_endpoints_00107: |
|||
;source-doc/base-drv/./enumerate_storage.c:24: ep->number = pEndpoint->bEndpointAddress & 0x07; |
|||
ld l, e |
|||
ld h, d |
|||
ld a, c |
|||
and 0x07 |
|||
rlca |
|||
and 0x0e |
|||
ld c, a |
|||
ld a, (hl) |
|||
and 0xf1 |
|||
or c |
|||
ld (hl), a |
|||
;source-doc/base-drv/./enumerate_storage.c:25: ep->toggle = 0; |
|||
ld l, e |
|||
ld h, d |
|||
res 0, (hl) |
|||
;source-doc/base-drv/./enumerate_storage.c:26: ep->max_packet_sizex = x; |
|||
inc de |
|||
ld a,(ix-1) |
|||
ld b,0x00 |
|||
ld (de), a |
|||
inc de |
|||
ld a, b |
|||
and 0x03 |
|||
ld l,a |
|||
ld a, (de) |
|||
and 0xfc |
|||
or l |
|||
ld (de), a |
|||
l_parse_endpoints_00108: |
|||
;source-doc/base-drv/./enumerate_storage.c:27: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
@ -0,0 +1,87 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./print.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./print.c:3: void print_device_mounted(const char *const description, const uint8_t count) { |
|||
; --------------------------------- |
|||
; Function print_device_mounted |
|||
; --------------------------------- |
|||
_print_device_mounted: |
|||
;source-doc/base-drv/./print.c:4: print_string("\r\n $"); |
|||
ld hl,print_str_0 |
|||
call _print_string |
|||
;source-doc/base-drv/./print.c:5: print_uint16(count); |
|||
ld iy,4 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
ld h,0x00 |
|||
call _print_uint16 |
|||
;source-doc/base-drv/./print.c:6: print_string(description); |
|||
ld hl,2 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
inc hl |
|||
ld h, (hl) |
|||
ld l, a |
|||
call _print_string |
|||
;source-doc/base-drv/./print.c:7: if (count > 1) |
|||
ld a,0x01 |
|||
ld iy,4 |
|||
add iy, sp |
|||
sub (iy+0) |
|||
ret NC |
|||
;source-doc/base-drv/./print.c:8: print_string("S$"); |
|||
ld hl,print_str_1 |
|||
;source-doc/base-drv/./print.c:9: } |
|||
jp _print_string |
|||
print_str_0: |
|||
DEFB 0x0d |
|||
DEFB 0x0a |
|||
DEFM " $" |
|||
DEFB 0x00 |
|||
print_str_1: |
|||
DEFM "S$" |
|||
DEFB 0x00 |
|||
@ -0,0 +1,478 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./protocol.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./protocol.c:28: usb_error usbtrn_get_descriptor(device_descriptor *const buffer) { |
|||
; --------------------------------- |
|||
; Function usbtrn_get_descriptor |
|||
; --------------------------------- |
|||
_usbtrn_get_descriptor: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./protocol.c:31: cmd = cmd_get_device_descriptor; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_get_device_descriptor |
|||
ldir |
|||
;source-doc/base-drv/./protocol.c:32: cmd.wLength = 8; |
|||
ld (ix-2),0x08 |
|||
xor a |
|||
ld (ix-1),a |
|||
;source-doc/base-drv/./protocol.c:34: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8); |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld e, c |
|||
ld d, b |
|||
push bc |
|||
ld a,0x08 |
|||
push af |
|||
inc sp |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push de |
|||
ld hl,6 |
|||
add hl, sp |
|||
push hl |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:36: CHECK(result); |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_usbtrn_get_descriptor_00103 |
|||
;source-doc/base-drv/./protocol.c:38: cmd = cmd_get_device_descriptor; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
push bc |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_get_device_descriptor |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:39: cmd.wLength = 18; |
|||
ld (ix-2),0x12 |
|||
xor a |
|||
ld (ix-1),a |
|||
;source-doc/base-drv/./protocol.c:40: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0); |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
ld hl,7 |
|||
add hl, de |
|||
ld a, (hl) |
|||
push af |
|||
inc sp |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
;source-doc/base-drv/./protocol.c:42: RETURN_CHECK(result); |
|||
l_usbtrn_get_descriptor_00103: |
|||
;source-doc/base-drv/./protocol.c:43: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
_cmd_get_device_descriptor: |
|||
DEFB +0x80 |
|||
DEFB +0x06 |
|||
DEFB +0x00 |
|||
DEFB +0x01 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFW +0x0008 |
|||
;source-doc/base-drv/./protocol.c:51: usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address) { |
|||
; --------------------------------- |
|||
; Function usbtrn_get_descriptor2 |
|||
; --------------------------------- |
|||
_usbtrn_get_descriptor2: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -10 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./protocol.c:54: cmd = cmd_get_device_descriptor; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_get_device_descriptor |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:55: cmd.wLength = 8; |
|||
ld (ix-4),0x08 |
|||
xor a |
|||
ld (ix-3),a |
|||
;source-doc/base-drv/./protocol.c:57: result = usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, 8); |
|||
ld a,(ix+4) |
|||
ld (ix-2),a |
|||
ld l, a |
|||
ld a,(ix+5) |
|||
ld (ix-1),a |
|||
ld h,a |
|||
ld e, c |
|||
ld d, b |
|||
push bc |
|||
ld b,0x08 |
|||
ld c,(ix+6) |
|||
push bc |
|||
push hl |
|||
push de |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
pop bc |
|||
ld l, a |
|||
;source-doc/base-drv/./protocol.c:59: CHECK(result); |
|||
or a |
|||
jr NZ,l_usbtrn_get_descriptor2_00103 |
|||
;source-doc/base-drv/./protocol.c:61: cmd = cmd_get_device_descriptor; |
|||
ld e, c |
|||
ld d, b |
|||
push bc |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_get_device_descriptor |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:62: cmd.wLength = 18; |
|||
ld (ix-4),0x12 |
|||
xor a |
|||
ld (ix-3),a |
|||
;source-doc/base-drv/./protocol.c:63: RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, buffer->bMaxPacketSize0)); |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
ld hl,7 |
|||
add hl, de |
|||
ld a, (hl) |
|||
ld e,(ix-2) |
|||
ld d,(ix-1) |
|||
push af |
|||
inc sp |
|||
ld a,(ix+6) |
|||
push af |
|||
inc sp |
|||
push de |
|||
push bc |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
l_usbtrn_get_descriptor2_00103: |
|||
;source-doc/base-drv/./protocol.c:64: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./protocol.c:74: usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall { |
|||
; --------------------------------- |
|||
; Function usbtrn_set_address |
|||
; --------------------------------- |
|||
_usbtrn_set_address: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld iy, -8 |
|||
add iy, sp |
|||
ld sp, iy |
|||
ld c, l |
|||
;source-doc/base-drv/./protocol.c:76: cmd = cmd_set_device_address; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
push bc |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_set_device_address |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:77: cmd.bValue[0] = device_address; |
|||
ld (ix-6),c |
|||
;source-doc/base-drv/./protocol.c:79: return usb_control_transfer(&cmd, 0, 0, 0); |
|||
xor a |
|||
push af |
|||
inc sp |
|||
xor a |
|||
push af |
|||
inc sp |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./protocol.c:80: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
_cmd_set_device_address: |
|||
DEFB +0x00 |
|||
DEFB +0x05 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFW +0x0000 |
|||
;source-doc/base-drv/./protocol.c:90: usb_error usbtrn_set_configuration(const uint8_t device_address, const uint8_t max_packet_size, const uint8_t configuration) { |
|||
; --------------------------------- |
|||
; Function usbtrn_set_configuration |
|||
; --------------------------------- |
|||
_usbtrn_set_configuration: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./protocol.c:92: cmd = cmd_set_configuration; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_set_configuration |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:93: cmd.bValue[0] = configuration; |
|||
ld a,(ix+6) |
|||
ld (ix-6),a |
|||
;source-doc/base-drv/./protocol.c:95: return usb_control_transfer(&cmd, 0, device_address, max_packet_size); |
|||
ld h,(ix+5) |
|||
ld l,(ix+4) |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
push bc |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./protocol.c:96: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
_cmd_set_configuration: |
|||
DEFB +0x00 |
|||
DEFB +0x09 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFW +0x0000 |
|||
;source-doc/base-drv/./protocol.c:110: usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer, |
|||
; --------------------------------- |
|||
; Function usbtrn_get_config_descriptor |
|||
; --------------------------------- |
|||
_usbtrn_get_config_descriptor: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./protocol.c:116: cmd = cmd_get_config_descriptor; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x0008 |
|||
ld hl,_cmd_get_config_descriptor |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:117: cmd.bValue[0] = config_index; |
|||
ld a,(ix+6) |
|||
ld (ix-6),a |
|||
;source-doc/base-drv/./protocol.c:118: cmd.wLength = (uint16_t)buffer_size; |
|||
ld e,(ix+7) |
|||
ld (ix-2),e |
|||
ld (ix-1),0x00 |
|||
;source-doc/base-drv/./protocol.c:120: RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, max_packet_size)); |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
ld h,(ix+9) |
|||
ld l,(ix+8) |
|||
push hl |
|||
push de |
|||
push bc |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./protocol.c:121: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
_cmd_get_config_descriptor: |
|||
DEFB +0x80 |
|||
DEFB +0x06 |
|||
DEFB +0x00 |
|||
DEFB +0x02 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFW +0x0000 |
|||
;source-doc/base-drv/./protocol.c:123: usb_error usbtrn_gfull_cfg_desc(const uint8_t config_index, |
|||
; --------------------------------- |
|||
; Function usbtrn_gfull_cfg_desc |
|||
; --------------------------------- |
|||
_usbtrn_gfull_cfg_desc: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./protocol.c:131: max_packet_size)); |
|||
ld c,(ix+8) |
|||
ld b,(ix+9) |
|||
push bc |
|||
ld a,(ix+6) |
|||
push af |
|||
inc sp |
|||
ld d,(ix+5) |
|||
ld e,0x09 |
|||
push de |
|||
ld a,(ix+4) |
|||
push af |
|||
inc sp |
|||
push bc |
|||
call _usbtrn_get_config_descriptor |
|||
pop af |
|||
pop af |
|||
pop af |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_usbtrn_gfull_cfg_desc_00107 |
|||
;source-doc/base-drv/./protocol.c:133: uint8_t max_length = ((config_descriptor *)buffer)->wTotalLength; |
|||
ld l, c |
|||
ld h, b |
|||
inc hl |
|||
inc hl |
|||
ld d, (hl) |
|||
;source-doc/base-drv/./protocol.c:134: if (max_length > max_buffer_size) |
|||
ld a,(ix+7) |
|||
sub d |
|||
jr NC,l_usbtrn_gfull_cfg_desc_00104 |
|||
;source-doc/base-drv/./protocol.c:135: max_length = max_buffer_size; |
|||
ld d,(ix+7) |
|||
l_usbtrn_gfull_cfg_desc_00104: |
|||
;source-doc/base-drv/./protocol.c:137: CHECK(usbtrn_get_config_descriptor((config_descriptor *)buffer, config_index, max_length, device_address, max_packet_size)); |
|||
ld h,(ix+6) |
|||
ld l,(ix+5) |
|||
push hl |
|||
ld e,(ix+4) |
|||
push de |
|||
push bc |
|||
call _usbtrn_get_config_descriptor |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
;source-doc/base-drv/./protocol.c:139: return USB_ERR_OK; |
|||
or a |
|||
jr NZ,l_usbtrn_gfull_cfg_desc_00107 |
|||
ld l,a |
|||
l_usbtrn_gfull_cfg_desc_00107: |
|||
;source-doc/base-drv/./protocol.c:140: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./protocol.c:144: usb_error usbtrn_clear_endpoint_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size) { |
|||
; --------------------------------- |
|||
; Function usbtrn_clear_endpoint_halt |
|||
; --------------------------------- |
|||
_usbtrn_clear_endpoint_halt: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/base-drv/./protocol.c:146: cmd = usb_cmd_clear_endpoint_halt; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x0008 |
|||
ld hl,_usb_cmd_clear_endpoint_halt |
|||
ldir |
|||
pop bc |
|||
;source-doc/base-drv/./protocol.c:147: cmd.bIndex[0] = endpoint_number; |
|||
ld a,(ix+4) |
|||
ld (ix-4),a |
|||
;source-doc/base-drv/./protocol.c:149: usb_error result = usb_control_transfer(&cmd, (uint8_t *)0, device_address, max_packet_size); |
|||
ld h,(ix+6) |
|||
ld l,(ix+5) |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
push bc |
|||
call _usb_control_transfer |
|||
;source-doc/base-drv/./protocol.c:151: RETURN_CHECK(result); |
|||
;source-doc/base-drv/./protocol.c:152: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
_usb_cmd_clear_endpoint_halt: |
|||
DEFB +0x02 |
|||
DEFB +0x01 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0xff |
|||
DEFB +0x00 |
|||
DEFW +0x0000 |
|||
@ -0,0 +1,506 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./transfers.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./transfers.c:21: usb_error usb_ctrl_trnsfer_ext(const setup_packet *const cmd_packet, |
|||
; --------------------------------- |
|||
; Function usb_ctrl_trnsfer_ext |
|||
; --------------------------------- |
|||
_usb_ctrl_trnsfer_ext: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./transfers.c:25: if ((uint16_t)cmd_packet < LOWER_SAFE_RAM_ADDRESS) |
|||
ld a,(ix+5) |
|||
sub 0x80 |
|||
jr NC,l_usb_ctrl_trnsfer_ext_00102 |
|||
;source-doc/base-drv/./transfers.c:26: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_ctrl_trnsfer_ext_00106 |
|||
l_usb_ctrl_trnsfer_ext_00102: |
|||
;source-doc/base-drv/./transfers.c:28: if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS) |
|||
ld a,(ix+7) |
|||
or (ix+6) |
|||
jr Z,l_usb_ctrl_trnsfer_ext_00104 |
|||
ld a,(ix+7) |
|||
sub 0x80 |
|||
jr NC,l_usb_ctrl_trnsfer_ext_00104 |
|||
;source-doc/base-drv/./transfers.c:29: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_ctrl_trnsfer_ext_00106 |
|||
l_usb_ctrl_trnsfer_ext_00104: |
|||
;source-doc/base-drv/./transfers.c:31: return usb_control_transfer(cmd_packet, buffer, device_address, max_packet_size); |
|||
ld h,(ix+9) |
|||
ld l,(ix+8) |
|||
push hl |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
l_usb_ctrl_trnsfer_ext_00106: |
|||
;source-doc/base-drv/./transfers.c:32: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:44: usb_error usb_control_transfer(const setup_packet *const cmd_packet, |
|||
; --------------------------------- |
|||
; Function usb_control_transfer |
|||
; --------------------------------- |
|||
_usb_control_transfer: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
push af |
|||
;source-doc/base-drv/./transfers.c:49: endpoint_param endpoint = {1, 0, max_packet_size}; |
|||
ld hl,0 |
|||
add hl, sp |
|||
set 0, (hl) |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
and 0xf1 |
|||
ld (hl), a |
|||
ld c,(ix+9) |
|||
ld b,0x00 |
|||
ld hl,1 |
|||
add hl, sp |
|||
ld (hl), c |
|||
inc hl |
|||
ld a, b |
|||
and 0x03 |
|||
ld e,a |
|||
ld a, (hl) |
|||
and 0xfc |
|||
or e |
|||
ld (hl), a |
|||
;source-doc/base-drv/./transfers.c:51: const uint8_t transferIn = (cmd_packet->bmRequestType & 0x80); |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld a, (bc) |
|||
and 0x80 |
|||
;source-doc/base-drv/./transfers.c:53: if (transferIn && buffer == 0) |
|||
ld (ix-1),a |
|||
or a |
|||
jr Z,l_usb_control_transfer_00102 |
|||
ld a,(ix+7) |
|||
or (ix+6) |
|||
jr NZ,l_usb_control_transfer_00102 |
|||
;source-doc/base-drv/./transfers.c:54: return USB_ERR_OTHER; |
|||
ld l,0x0f |
|||
jp l_usb_control_transfer_00113 |
|||
l_usb_control_transfer_00102: |
|||
;source-doc/base-drv/./transfers.c:56: ch_set_usb_address(device_address); |
|||
push bc |
|||
ld l,(ix+8) |
|||
call _ch_set_usb_address |
|||
pop bc |
|||
;source-doc/base-drv/./transfers.c:58: ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet)); |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
push bc |
|||
ld a,0x08 |
|||
push af |
|||
inc sp |
|||
push de |
|||
call _ch_write_data |
|||
pop af |
|||
inc sp |
|||
call _ch_issue_token_setup |
|||
call _ch_short_wait_int_and_get_stat |
|||
pop bc |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_usb_control_transfer_00113 |
|||
;source-doc/base-drv/./transfers.c:62: const uint16_t length = cmd_packet->wLength; |
|||
ld hl,6 |
|||
add hl, bc |
|||
ld c, (hl) |
|||
inc hl |
|||
;source-doc/base-drv/./transfers.c:65: ? (transferIn ? ch_data_in_transfer(buffer, length, &endpoint) : ch_data_out_transfer(buffer, length, &endpoint)) |
|||
ld a,(hl) |
|||
ld b,a |
|||
or c |
|||
jr Z,l_usb_control_transfer_00115 |
|||
ld e,(ix+6) |
|||
ld d,(ix+7) |
|||
ld a,(ix-1) |
|||
or a |
|||
jr Z,l_usb_control_transfer_00117 |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
push bc |
|||
push de |
|||
call _ch_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
jr l_usb_control_transfer_00118 |
|||
l_usb_control_transfer_00117: |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
push bc |
|||
push de |
|||
call _ch_data_out_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
l_usb_control_transfer_00118: |
|||
jr l_usb_control_transfer_00116 |
|||
l_usb_control_transfer_00115: |
|||
;source-doc/base-drv/./transfers.c:66: : USB_ERR_OK; |
|||
ld hl,0x0000 |
|||
l_usb_control_transfer_00116: |
|||
;source-doc/base-drv/./transfers.c:68: CHECK(result) |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_usb_control_transfer_00113 |
|||
;source-doc/base-drv/./transfers.c:70: if (transferIn) { |
|||
ld a,(ix-1) |
|||
or a |
|||
jr Z,l_usb_control_transfer_00112 |
|||
;source-doc/base-drv/./transfers.c:71: ch_command(CH_CMD_WR_HOST_DATA); |
|||
ld l,0x2c |
|||
call _ch_command |
|||
;source-doc/base-drv/./transfers.c:72: CH376_DATA_PORT = 0; |
|||
ld a,0x00 |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./transfers.c:73: delay(); |
|||
call _delay |
|||
;source-doc/base-drv/./transfers.c:74: ch_issue_token_out_ep0(); |
|||
call _ch_issue_token_out_ep0 |
|||
;source-doc/base-drv/./transfers.c:75: result = ch_long_wait_int_and_get_status(); /* sometimes we get STALL here - seems to be ok to ignore */ |
|||
call _ch_long_wait_int_and_get_statu |
|||
ld a, l |
|||
;source-doc/base-drv/./transfers.c:77: if (result == USB_ERR_OK || result == USB_ERR_STALL) |
|||
or a |
|||
jr Z,l_usb_control_transfer_00108 |
|||
cp 0x02 |
|||
jr NZ,l_usb_control_transfer_00109 |
|||
l_usb_control_transfer_00108: |
|||
;source-doc/base-drv/./transfers.c:78: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
jr l_usb_control_transfer_00113 |
|||
l_usb_control_transfer_00109: |
|||
;source-doc/base-drv/./transfers.c:80: RETURN_CHECK(result); |
|||
ld l, a |
|||
jr l_usb_control_transfer_00113 |
|||
l_usb_control_transfer_00112: |
|||
;source-doc/base-drv/./transfers.c:83: ch_issue_token_in_ep0(); |
|||
call _ch_issue_token_in_ep0 |
|||
;source-doc/base-drv/./transfers.c:84: result = ch_long_wait_int_and_get_status(); |
|||
call _ch_long_wait_int_and_get_statu |
|||
;source-doc/base-drv/./transfers.c:86: RETURN_CHECK(result); |
|||
l_usb_control_transfer_00113: |
|||
;source-doc/base-drv/./transfers.c:87: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:90: usb_dat_in_trnsfer_ext(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function usb_dat_in_trnsfer_ext |
|||
; --------------------------------- |
|||
_usb_dat_in_trnsfer_ext: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./transfers.c:91: if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS) |
|||
ld a,(ix+5) |
|||
or (ix+4) |
|||
jr Z,l_usb_dat_in_trnsfer_ext_00102 |
|||
ld a,(ix+5) |
|||
sub 0x80 |
|||
jr NC,l_usb_dat_in_trnsfer_ext_00102 |
|||
;source-doc/base-drv/./transfers.c:92: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_in_trnsfer_ext_00106 |
|||
l_usb_dat_in_trnsfer_ext_00102: |
|||
;source-doc/base-drv/./transfers.c:94: if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS) |
|||
ld a,(ix+10) |
|||
sub 0x80 |
|||
jr NC,l_usb_dat_in_trnsfer_ext_00105 |
|||
;source-doc/base-drv/./transfers.c:95: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_in_trnsfer_ext_00106 |
|||
l_usb_dat_in_trnsfer_ext_00105: |
|||
;source-doc/base-drv/./transfers.c:97: return usb_data_in_transfer(buffer, buffer_size, device_address, endpoint); |
|||
ld l,(ix+9) |
|||
ld h,(ix+10) |
|||
push hl |
|||
ld a,(ix+8) |
|||
push af |
|||
inc sp |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
l_usb_dat_in_trnsfer_ext_00106: |
|||
;source-doc/base-drv/./transfers.c:98: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:101: usb_dat_in_trns_n_ext(uint8_t *buffer, uint16_t *buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function usb_dat_in_trns_n_ext |
|||
; --------------------------------- |
|||
_usb_dat_in_trns_n_ext: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./transfers.c:102: if (buffer != 0 && ((uint16_t)buffer & 0xC000) == 0) |
|||
ld a,(ix+5) |
|||
or (ix+4) |
|||
jr Z,l_usb_dat_in_trns_n_ext_00102 |
|||
ld a,(ix+5) |
|||
and 0xc0 |
|||
jr NZ,l_usb_dat_in_trns_n_ext_00102 |
|||
;source-doc/base-drv/./transfers.c:103: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_in_trns_n_ext_00108 |
|||
l_usb_dat_in_trns_n_ext_00102: |
|||
;source-doc/base-drv/./transfers.c:105: if (((uint16_t)endpoint & 0xC000) == 0) |
|||
ld a,(ix+10) |
|||
and 0xc0 |
|||
jr NZ,l_usb_dat_in_trns_n_ext_00105 |
|||
;source-doc/base-drv/./transfers.c:106: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_in_trns_n_ext_00108 |
|||
l_usb_dat_in_trns_n_ext_00105: |
|||
;source-doc/base-drv/./transfers.c:108: if (((uint16_t)buffer_size & 0xC000) == 0) |
|||
ld a,(ix+7) |
|||
and 0xc0 |
|||
jr NZ,l_usb_dat_in_trns_n_ext_00107 |
|||
;source-doc/base-drv/./transfers.c:109: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_in_trns_n_ext_00108 |
|||
l_usb_dat_in_trns_n_ext_00107: |
|||
;source-doc/base-drv/./transfers.c:111: return usb_data_in_transfer_n(buffer, buffer_size, device_address, endpoint); |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
ld l,(ix+9) |
|||
ld h,(ix+10) |
|||
push hl |
|||
ld a,(ix+8) |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_data_in_transfer_n |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
l_usb_dat_in_trns_n_ext_00108: |
|||
;source-doc/base-drv/./transfers.c:112: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:124: usb_data_in_transfer(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function usb_data_in_transfer |
|||
; --------------------------------- |
|||
_usb_data_in_transfer: |
|||
;source-doc/base-drv/./transfers.c:125: ch_set_usb_address(device_address); |
|||
ld iy,6 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
call _ch_set_usb_address |
|||
;source-doc/base-drv/./transfers.c:127: return ch_data_in_transfer(buffer, buffer_size, endpoint); |
|||
ld iy,7 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
dec iy |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
call _ch_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
;source-doc/base-drv/./transfers.c:128: } |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:140: usb_data_in_transfer_n(uint8_t *buffer, uint8_t *const buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function usb_data_in_transfer_n |
|||
; --------------------------------- |
|||
_usb_data_in_transfer_n: |
|||
;source-doc/base-drv/./transfers.c:141: ch_set_usb_address(device_address); |
|||
ld iy,6 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
call _ch_set_usb_address |
|||
;source-doc/base-drv/./transfers.c:143: return ch_data_in_transfer_n(buffer, buffer_size, endpoint); |
|||
ld iy,7 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
dec iy |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
call _ch_data_in_transfer_n |
|||
pop af |
|||
pop af |
|||
pop af |
|||
;source-doc/base-drv/./transfers.c:144: } |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:147: usb_dat_out_trns_ext(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function usb_dat_out_trns_ext |
|||
; --------------------------------- |
|||
_usb_dat_out_trns_ext: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./transfers.c:149: if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS) |
|||
ld a,(ix+5) |
|||
or (ix+4) |
|||
jr Z,l_usb_dat_out_trns_ext_00102 |
|||
ld a,(ix+5) |
|||
sub 0x80 |
|||
jr NC,l_usb_dat_out_trns_ext_00102 |
|||
;source-doc/base-drv/./transfers.c:150: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_out_trns_ext_00106 |
|||
l_usb_dat_out_trns_ext_00102: |
|||
;source-doc/base-drv/./transfers.c:152: if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS) |
|||
ld a,(ix+10) |
|||
sub 0x80 |
|||
jr NC,l_usb_dat_out_trns_ext_00105 |
|||
;source-doc/base-drv/./transfers.c:153: return USB_BAD_ADDRESS; |
|||
ld l,0x82 |
|||
jr l_usb_dat_out_trns_ext_00106 |
|||
l_usb_dat_out_trns_ext_00105: |
|||
;source-doc/base-drv/./transfers.c:155: return usb_data_out_transfer(buffer, buffer_size, device_address, endpoint); |
|||
ld l,(ix+9) |
|||
ld h,(ix+10) |
|||
push hl |
|||
ld a,(ix+8) |
|||
push af |
|||
inc sp |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_data_out_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
l_usb_dat_out_trns_ext_00106: |
|||
;source-doc/base-drv/./transfers.c:156: } |
|||
pop ix |
|||
ret |
|||
;source-doc/base-drv/./transfers.c:168: usb_data_out_transfer(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
; --------------------------------- |
|||
; Function usb_data_out_transfer |
|||
; --------------------------------- |
|||
_usb_data_out_transfer: |
|||
;source-doc/base-drv/./transfers.c:169: ch_set_usb_address(device_address); |
|||
ld iy,6 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
call _ch_set_usb_address |
|||
;source-doc/base-drv/./transfers.c:171: return ch_data_out_transfer(buffer, buffer_size, endpoint); |
|||
ld iy,7 |
|||
add iy, sp |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
dec iy |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
dec iy |
|||
dec iy |
|||
ld l,(iy+0) |
|||
ld h,(iy+1) |
|||
push hl |
|||
call _ch_data_out_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
;source-doc/base-drv/./transfers.c:172: } |
|||
ret |
|||
@ -0,0 +1,86 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./usb-base-drv.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
_storage_count: |
|||
DEFS 1 |
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./usb-base-drv.c:6: uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function chnative_seek |
|||
; --------------------------------- |
|||
_chnative_seek: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld c, l |
|||
ld b, h |
|||
;source-doc/base-drv/./usb-base-drv.c:7: storage_device->current_lba = lba; |
|||
ld h,(ix+5) |
|||
ld a,(ix+4) |
|||
add a,0x0c |
|||
ld l, a |
|||
jr NC,l_chnative_seek_00103 |
|||
inc h |
|||
l_chnative_seek_00103: |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
inc hl |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), b |
|||
;source-doc/base-drv/./usb-base-drv.c:8: return 0; |
|||
xor a |
|||
;source-doc/base-drv/./usb-base-drv.c:9: } |
|||
pop ix |
|||
pop hl |
|||
pop bc |
|||
jp (hl) |
|||
_storage_count: |
|||
DEFB +0x00 |
|||
@ -0,0 +1,179 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./usb-init.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./usb-init.c:8: static usb_error usb_host_bus_reset(void) { |
|||
; --------------------------------- |
|||
; Function usb_host_bus_reset |
|||
; --------------------------------- |
|||
_usb_host_bus_reset: |
|||
;source-doc/base-drv/./usb-init.c:9: ch_cmd_set_usb_mode(CH_MODE_HOST); |
|||
ld l,0x06 |
|||
call _ch_cmd_set_usb_mode |
|||
;source-doc/base-drv/./usb-init.c:10: delay_20ms(); |
|||
call _delay_20ms |
|||
;source-doc/base-drv/./usb-init.c:12: ch_cmd_set_usb_mode(CH_MODE_HOST_RESET); |
|||
ld l,0x07 |
|||
call _ch_cmd_set_usb_mode |
|||
;source-doc/base-drv/./usb-init.c:13: delay_20ms(); |
|||
call _delay_20ms |
|||
;source-doc/base-drv/./usb-init.c:15: ch_cmd_set_usb_mode(CH_MODE_HOST); |
|||
ld l,0x06 |
|||
call _ch_cmd_set_usb_mode |
|||
;source-doc/base-drv/./usb-init.c:16: delay_20ms(); |
|||
call _delay_20ms |
|||
;source-doc/base-drv/./ch376.h:160: ch_command(CH_CMD_WRITE_VAR8); |
|||
ld l,0x0b |
|||
call _ch_command |
|||
;source-doc/base-drv/./ch376.h:161: CH376_DATA_PORT = CH_VAR_RETRY_TIMES; |
|||
ld a,0x25 |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.h:162: delay(); |
|||
call _delay |
|||
;source-doc/base-drv/./ch376.h:163: CH376_DATA_PORT = retry << 6 | (number_of_retries & 0x1F); |
|||
ld a,0xc0 |
|||
or 0x1f |
|||
ld bc,_CH376_DATA_PORT |
|||
out (c),a |
|||
;source-doc/base-drv/./ch376.h:164: delay(); |
|||
call _delay |
|||
;source-doc/base-drv/./usb-init.c:20: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
;source-doc/base-drv/./usb-init.c:21: } |
|||
ret |
|||
;source-doc/base-drv/./usb-init.c:25: void chnative_init(void) { |
|||
; --------------------------------- |
|||
; Function chnative_init |
|||
; --------------------------------- |
|||
_chnative_init: |
|||
;source-doc/base-drv/./usb-init.c:26: memset(get_usb_work_area(), 0, sizeof(_usb_state)); |
|||
ld hl,_x |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x69 |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/base-drv/./usb-init.c:28: ch_cmd_reset_all(); |
|||
call _ch_cmd_reset_all |
|||
;source-doc/base-drv/./usb-init.c:30: delay_medium(); |
|||
call _delay_medium |
|||
;source-doc/base-drv/./usb-init.c:32: if (!ch_probe()) { |
|||
call _ch_probe |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_chnative_init_00102 |
|||
;source-doc/base-drv/./usb-init.c:33: print_string("\r\nCH376: NOT PRESENT$"); |
|||
;source-doc/base-drv/./usb-init.c:34: return; |
|||
ld hl,usb_init_str_0 |
|||
jp _print_string |
|||
l_chnative_init_00102: |
|||
;source-doc/base-drv/./usb-init.c:37: print_string("\r\nCH376: PRESENT (VER $"); |
|||
ld hl,usb_init_str_1 |
|||
call _print_string |
|||
;source-doc/base-drv/./usb-init.c:38: print_hex(ch_cmd_get_ic_version()); |
|||
call _ch_cmd_get_ic_version |
|||
call _print_hex |
|||
;source-doc/base-drv/./usb-init.c:39: print_string("); $"); |
|||
ld hl,usb_init_str_2 |
|||
call _print_string |
|||
;source-doc/base-drv/./usb-init.c:41: usb_host_bus_reset(); |
|||
call _usb_host_bus_reset |
|||
;source-doc/base-drv/./usb-init.c:43: for (uint8_t i = 0; i < 4; i++) { |
|||
ld c,0x00 |
|||
l_chnative_init_00107: |
|||
ld a, c |
|||
sub 0x04 |
|||
jr NC,l_chnative_init_00105 |
|||
;source-doc/base-drv/./usb-init.c:44: const uint8_t r = ch_very_short_wait_int_and_get_(); |
|||
push bc |
|||
call _ch_very_short_wait_int_and_get |
|||
ld a, l |
|||
pop bc |
|||
;source-doc/base-drv/./usb-init.c:46: if (r == USB_INT_CONNECT) { |
|||
sub 0x81 |
|||
jr NZ,l_chnative_init_00108 |
|||
;source-doc/base-drv/./usb-init.c:47: print_string("USB: CONNECTED$"); |
|||
ld hl,usb_init_str_3 |
|||
call _print_string |
|||
;source-doc/base-drv/./usb-init.c:49: enumerate_all_devices(); |
|||
jp _enumerate_all_devices |
|||
;source-doc/base-drv/./usb-init.c:51: return; |
|||
jr l_chnative_init_00109 |
|||
l_chnative_init_00108: |
|||
;source-doc/base-drv/./usb-init.c:43: for (uint8_t i = 0; i < 4; i++) { |
|||
inc c |
|||
jr l_chnative_init_00107 |
|||
l_chnative_init_00105: |
|||
;source-doc/base-drv/./usb-init.c:55: print_string("USB: DISCONNECTED$"); |
|||
ld hl,usb_init_str_4 |
|||
jp _print_string |
|||
l_chnative_init_00109: |
|||
;source-doc/base-drv/./usb-init.c:56: } |
|||
ret |
|||
usb_init_str_0: |
|||
DEFB 0x0d |
|||
DEFB 0x0a |
|||
DEFM "CH376: NOT PRESENT$" |
|||
DEFB 0x00 |
|||
usb_init_str_1: |
|||
DEFB 0x0d |
|||
DEFB 0x0a |
|||
DEFM "CH376: PRESENT (VER $" |
|||
DEFB 0x00 |
|||
usb_init_str_2: |
|||
DEFM "); $" |
|||
DEFB 0x00 |
|||
usb_init_str_3: |
|||
DEFM "USB: CONNECTED$" |
|||
DEFB 0x00 |
|||
usb_init_str_4: |
|||
DEFM "USB: DISCONNECTED$" |
|||
DEFB 0x00 |
|||
@ -0,0 +1,274 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./usb_state.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/base-drv/./usb_state.c:13: device_config *find_device_config(const usb_device_type requested_type) { |
|||
; --------------------------------- |
|||
; Function find_device_config |
|||
; --------------------------------- |
|||
_find_device_config: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
;source-doc/base-drv/./usb_state.c:14: _usb_state *const p = get_usb_work_area(); |
|||
;source-doc/base-drv/./usb_state.c:16: const device_config *p_config = first_device_config(p); |
|||
ld hl,_x |
|||
call _first_device_config |
|||
;source-doc/base-drv/./usb_state.c:17: while (p_config) { |
|||
l_find_device_config_00103: |
|||
ld a, d |
|||
or e |
|||
jr Z,l_find_device_config_00105 |
|||
;source-doc/base-drv/./usb_state.c:18: const uint8_t type = p_config->type; |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
ld c, a |
|||
;source-doc/base-drv/./usb_state.c:20: if (type == requested_type) |
|||
ld a,(ix+4) |
|||
sub c |
|||
jr NZ,l_find_device_config_00102 |
|||
;source-doc/base-drv/./usb_state.c:21: return (device_config *)p_config; |
|||
ex de, hl |
|||
jr l_find_device_config_00106 |
|||
l_find_device_config_00102: |
|||
;source-doc/base-drv/./usb_state.c:23: p_config = next_device_config(p, p_config); |
|||
ld hl,_x |
|||
call _next_device_config |
|||
jr l_find_device_config_00103 |
|||
l_find_device_config_00105: |
|||
;source-doc/base-drv/./usb_state.c:26: return NULL; |
|||
ld hl,0x0000 |
|||
l_find_device_config_00106: |
|||
;source-doc/base-drv/./usb_state.c:27: } |
|||
pop ix |
|||
ret |
|||
_device_config_sizes: |
|||
DEFB +0x00 |
|||
DEFB +0x11 |
|||
DEFB +0x11 |
|||
DEFB +0x0c |
|||
DEFB +0x06 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
;source-doc/base-drv/./usb_state.c:30: device_config *find_first_free(void) { |
|||
; --------------------------------- |
|||
; Function find_first_free |
|||
; --------------------------------- |
|||
_find_first_free: |
|||
;source-doc/base-drv/./usb_state.c:31: _usb_state *const boot_state = get_usb_work_area(); |
|||
;source-doc/base-drv/./usb_state.c:34: device_config *p = first_device_config(boot_state); |
|||
ld hl,_x |
|||
call _first_device_config |
|||
;source-doc/base-drv/./usb_state.c:35: while (p) { |
|||
l_find_first_free_00103: |
|||
ld a, d |
|||
or e |
|||
jr Z,l_find_first_free_00105 |
|||
;source-doc/base-drv/./usb_state.c:36: if (p->type == 0) |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
jr NZ,l_find_first_free_00102 |
|||
;source-doc/base-drv/./usb_state.c:37: return p; |
|||
ex de, hl |
|||
jr l_find_first_free_00106 |
|||
l_find_first_free_00102: |
|||
;source-doc/base-drv/./usb_state.c:39: p = next_device_config(boot_state, p); |
|||
ld hl,_x |
|||
call _next_device_config |
|||
jr l_find_first_free_00103 |
|||
l_find_first_free_00105: |
|||
;source-doc/base-drv/./usb_state.c:42: return NULL; |
|||
ld hl,0x0000 |
|||
l_find_first_free_00106: |
|||
;source-doc/base-drv/./usb_state.c:43: } |
|||
ret |
|||
;source-doc/base-drv/./usb_state.c:45: device_config *first_device_config(const _usb_state *const p) __sdcccall(1) { return (device_config *)&p->device_configs[0]; } |
|||
; --------------------------------- |
|||
; Function first_device_config |
|||
; --------------------------------- |
|||
_first_device_config: |
|||
ex de, hl |
|||
inc de |
|||
inc de |
|||
ret |
|||
;source-doc/base-drv/./usb_state.c:47: device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function next_device_config |
|||
; --------------------------------- |
|||
_next_device_config: |
|||
ld c, l |
|||
ld b, h |
|||
;source-doc/base-drv/./usb_state.c:48: if (p->type == 0) |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
jr NZ,l_next_device_config_00102 |
|||
;source-doc/base-drv/./usb_state.c:49: return NULL; |
|||
ld de,0x0000 |
|||
jr l_next_device_config_00105 |
|||
l_next_device_config_00102: |
|||
;source-doc/base-drv/./usb_state.c:51: const uint8_t size = device_config_sizes[p->type]; |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
add a, +((_device_config_sizes) & 0xFF) |
|||
ld l, a |
|||
ld a,0x00 |
|||
adc a, +((_device_config_sizes) / 256) |
|||
ld h, a |
|||
ld l, (hl) |
|||
;source-doc/base-drv/./usb_state.c:58: const uint8_t *_p = (uint8_t *)p; |
|||
;source-doc/base-drv/./usb_state.c:59: device_config *const result = (device_config *)(_p + size); |
|||
ld h,0x00 |
|||
add hl, de |
|||
ex de, hl |
|||
;source-doc/base-drv/./usb_state.c:61: if (result >= (device_config *)&usb_state->device_configs_end) |
|||
ld hl,0x0068 |
|||
add hl, bc |
|||
ld a, e |
|||
sub l |
|||
ld a, d |
|||
sbc a, h |
|||
ret C |
|||
;source-doc/base-drv/./usb_state.c:62: return NULL; |
|||
ld de,0x0000 |
|||
;source-doc/base-drv/./usb_state.c:64: return result; |
|||
l_next_device_config_00105: |
|||
;source-doc/base-drv/./usb_state.c:65: } |
|||
ret |
|||
;source-doc/base-drv/./usb_state.c:68: device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function get_usb_device_config |
|||
; --------------------------------- |
|||
_get_usb_device_config: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
ld (ix-1),a |
|||
;source-doc/base-drv/./usb_state.c:69: const _usb_state *const usb_state = get_usb_work_area(); |
|||
;source-doc/base-drv/./usb_state.c:71: uint8_t counter = 1; |
|||
ld c,0x01 |
|||
;source-doc/base-drv/./usb_state.c:73: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) { |
|||
push bc |
|||
ld hl,_x |
|||
call _first_device_config |
|||
pop bc |
|||
ld b,0x01 |
|||
l_get_usb_device_config_00112: |
|||
ld a, d |
|||
or e |
|||
jr Z,l_get_usb_device_config_00105 |
|||
;source-doc/base-drv/./usb_state.c:74: if (p->type == USB_IS_FLOPPY) { |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
dec a |
|||
jr NZ,l_get_usb_device_config_00113 |
|||
;source-doc/base-drv/./usb_state.c:75: if (counter == device_index) |
|||
ld a,(ix-1) |
|||
sub b |
|||
;source-doc/base-drv/./usb_state.c:76: return p; |
|||
jr Z,l_get_usb_device_config_00117 |
|||
;source-doc/base-drv/./usb_state.c:77: counter++; |
|||
inc b |
|||
ld c, b |
|||
l_get_usb_device_config_00113: |
|||
;source-doc/base-drv/./usb_state.c:73: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) { |
|||
push bc |
|||
ld hl,_x |
|||
call _next_device_config |
|||
pop bc |
|||
jr l_get_usb_device_config_00112 |
|||
l_get_usb_device_config_00105: |
|||
;source-doc/base-drv/./usb_state.c:81: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) { |
|||
push bc |
|||
ld hl,_x |
|||
call _first_device_config |
|||
pop bc |
|||
l_get_usb_device_config_00115: |
|||
ld a, d |
|||
or e |
|||
jr Z,l_get_usb_device_config_00110 |
|||
;source-doc/base-drv/./usb_state.c:82: if (p->type == USB_IS_MASS_STORAGE) { |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
sub 0x02 |
|||
jr NZ,l_get_usb_device_config_00116 |
|||
;source-doc/base-drv/./usb_state.c:83: if (counter == device_index) |
|||
ld a,(ix-1) |
|||
sub c |
|||
;source-doc/base-drv/./usb_state.c:84: return p; |
|||
jr Z,l_get_usb_device_config_00117 |
|||
;source-doc/base-drv/./usb_state.c:85: counter++; |
|||
inc c |
|||
l_get_usb_device_config_00116: |
|||
;source-doc/base-drv/./usb_state.c:81: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) { |
|||
push bc |
|||
ld hl,_x |
|||
call _next_device_config |
|||
pop bc |
|||
jr l_get_usb_device_config_00115 |
|||
l_get_usb_device_config_00110: |
|||
;source-doc/base-drv/./usb_state.c:89: return NULL; // is not a usb device |
|||
ld de,0x0000 |
|||
l_get_usb_device_config_00117: |
|||
;source-doc/base-drv/./usb_state.c:90: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
@ -0,0 +1,158 @@ |
|||
; |
|||
; Generated from source-doc/base-drv/./work-area.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
_x: |
|||
DEFS 105 |
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
_x: |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
@ -0,0 +1,134 @@ |
|||
|
|||
_memset_callee: |
|||
pop af ; return address |
|||
pop bc ; address to be set |
|||
pop de ; value to be set |
|||
pop hl ; number of bytes to set |
|||
push af ; restore return address |
|||
|
|||
ld a, b |
|||
or c |
|||
ret z |
|||
|
|||
ld a, e |
|||
push hl |
|||
pop de |
|||
ret z |
|||
|
|||
ld (hl), a |
|||
inc de |
|||
dec bc |
|||
ld a, b |
|||
or c |
|||
ret Z |
|||
|
|||
push hl |
|||
ldir |
|||
pop hl |
|||
ret |
|||
|
|||
; _strlen_fastcall: |
|||
|
|||
; ; enter: hl = char *s |
|||
; ; |
|||
; ; exit : hl = length |
|||
; ; bc = -(length + 1) |
|||
; ; a = 0 |
|||
; ; z flag set if 0 length |
|||
; ; carry reset |
|||
; ; |
|||
; ; uses : af, bc, hl |
|||
|
|||
; xor a |
|||
; ld c,a |
|||
; ld b,a |
|||
; cpir |
|||
; ld hl,$ffff |
|||
; sbc hl,bc |
|||
|
|||
; ret |
|||
|
|||
_memcpy_callee: |
|||
|
|||
pop af |
|||
pop bc |
|||
pop hl |
|||
pop de |
|||
push af |
|||
|
|||
|
|||
; enter : bc = size_t n |
|||
; hl = void *s2 = src |
|||
; de = void *s1 = dst |
|||
; |
|||
; exit : hl = void *s1 = dst |
|||
; de = ptr in s1 to one byte past last byte copied |
|||
; bc = 0 |
|||
; carry reset |
|||
; |
|||
; uses : af, bc, de, hl |
|||
|
|||
ld a,b |
|||
or c |
|||
jr Z,zero_n |
|||
|
|||
asm0_memcpy: |
|||
push de |
|||
ldir |
|||
pop hl |
|||
or a |
|||
ret |
|||
|
|||
zero_n: |
|||
push de |
|||
pop hl |
|||
ret |
|||
|
|||
; _strcat_callee: |
|||
|
|||
; pop hl |
|||
; pop de |
|||
; ex (sp),hl |
|||
|
|||
|
|||
; ; enter : hl = char *s2 = src |
|||
; ; de = char *s1 = dst |
|||
; ; |
|||
; ; exit : hl = char *s1 = dst |
|||
; ; de = ptr in s1 to terminating 0 |
|||
; ; |
|||
; ; uses : af, bc, de, hl |
|||
|
|||
; push de ; save dst |
|||
|
|||
; ex de,hl |
|||
; call __str_locate_nul ; a = 0 |
|||
; ex de,hl |
|||
|
|||
; loop: ; append s2 to s1 |
|||
; cp (hl) |
|||
; ldi |
|||
; jr NZ,loop |
|||
|
|||
; ENDIF |
|||
|
|||
; pop hl ; hl = dst |
|||
; dec de |
|||
; ret |
|||
|
|||
; __str_locate_nul: |
|||
; ; enter : hl = char *s |
|||
; ; |
|||
; ; exit : hl = ptr in s to terminating 0 |
|||
; ; bc = -(strlen + 1) |
|||
; ; a = 0 |
|||
; ; carry reset |
|||
; ; |
|||
; ; uses : af, bc, hl |
|||
|
|||
; xor a |
|||
; ld c,a |
|||
; ld b,a |
|||
; cpir |
|||
; dec hl |
|||
; ret |
|||
@ -0,0 +1,32 @@ |
|||
|
|||
; HL = unsigned 16 bit number to write out |
|||
; call CHPUT to write a single ascii character (in A) |
|||
_print_uint16: |
|||
ld e, 0 |
|||
ld bc, -10000 |
|||
call num1 |
|||
ld bc, -1000 |
|||
call num1 |
|||
ld bc, -100 |
|||
call num1 |
|||
ld c, -10 |
|||
call num1 |
|||
ld c, b |
|||
|
|||
num1: ld a, '0'-1 |
|||
num2: inc a |
|||
add hl, bc |
|||
jr c, num2 |
|||
sbc hl, bc |
|||
|
|||
cp '0' |
|||
jr nz, num3 |
|||
|
|||
ld a, e |
|||
cp 1 |
|||
ret nz |
|||
ld a, '0' |
|||
|
|||
num3: |
|||
ld e, 1 |
|||
jp COUT |
|||
@ -0,0 +1,3 @@ |
|||
; Generated File -- not to be modify directly |
|||
#include "ch376-native/scsi-drv/scsi-init.c.s" |
|||
#include "ch376-native/scsi-drv/class_scsi.c.s" |
|||
@ -0,0 +1,952 @@ |
|||
; |
|||
; Generated from source-doc/scsi-drv/./class_scsi.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
_scsi_command_block_wrapper: |
|||
DEFS 15 |
|||
_next_tag: |
|||
DEFS 2 |
|||
_csw: |
|||
DEFS 13 |
|||
_scsi_read_capacity: |
|||
DEFS 12 |
|||
_scsi_packet_inquiry: |
|||
DEFS 12 |
|||
_scsi_packet_request_sense: |
|||
DEFS 12 |
|||
_cbw: |
|||
DEFS 27 |
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/scsi-drv/./class_scsi.c:11: usb_error do_scsi_cmd(device_config_storage *const dev, |
|||
; --------------------------------- |
|||
; Function do_scsi_cmd |
|||
; --------------------------------- |
|||
_do_scsi_cmd: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -6 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:16: cbw->dCBWTag[0] = next_tag++; |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
ld hl,0x0004 |
|||
add hl, bc |
|||
ex (sp), hl |
|||
ld de, (_next_tag) |
|||
ld hl, (_next_tag) |
|||
inc hl |
|||
ld (_next_tag), hl |
|||
pop hl |
|||
push hl |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
;source-doc/scsi-drv/./class_scsi.c:18: if (!send) |
|||
bit 0,(ix+10) |
|||
jr NZ,l_do_scsi_cmd_00102 |
|||
;source-doc/scsi-drv/./class_scsi.c:19: cbw->bmCBWFlags = 0x80; |
|||
ld hl,0x000c |
|||
add hl, bc |
|||
ld (hl),0x80 |
|||
l_do_scsi_cmd_00102: |
|||
;source-doc/scsi-drv/./class_scsi.c:22: &dev->endpoints[ENDPOINT_BULK_OUT])); |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
ld hl,0x0003 |
|||
add hl, de |
|||
ld (ix-4),l |
|||
ld (ix-3),h |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push bc |
|||
push de |
|||
push hl |
|||
ld l,(ix-4) |
|||
ld h,(ix-3) |
|||
ex (sp), hl |
|||
push af |
|||
inc sp |
|||
ld iy,0x001f |
|||
push iy |
|||
push hl |
|||
call _usb_data_out_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
pop de |
|||
pop bc |
|||
ld (_result+0),a |
|||
or a |
|||
jr Z,l_do_scsi_cmd_00104 |
|||
ld l, a |
|||
jp l_do_scsi_cmd_00119 |
|||
l_do_scsi_cmd_00104: |
|||
;source-doc/scsi-drv/./class_scsi.c:24: if (cbw->dCBWDataTransferLength != 0) { |
|||
ld hl,8 |
|||
add hl, bc |
|||
ld c, (hl) |
|||
inc hl |
|||
ld b, (hl) |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
dec hl |
|||
ld l, (hl) |
|||
or l |
|||
or b |
|||
or c |
|||
jr Z,l_do_scsi_cmd_00113 |
|||
;source-doc/scsi-drv/./class_scsi.c:27: &dev->endpoints[ENDPOINT_BULK_IN])); |
|||
ld (ix-2),c |
|||
ld (ix-1),b |
|||
ld c,(ix+8) |
|||
ld b,(ix+9) |
|||
;source-doc/scsi-drv/./class_scsi.c:25: if (!send) { |
|||
bit 0,(ix+10) |
|||
jr NZ,l_do_scsi_cmd_00110 |
|||
;source-doc/scsi-drv/./class_scsi.c:27: &dev->endpoints[ENDPOINT_BULK_IN])); |
|||
ld iy,0x0006 |
|||
add iy, de |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
push de |
|||
push iy |
|||
push af |
|||
inc sp |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
push bc |
|||
call _usb_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
pop de |
|||
ld (_result+0),a |
|||
or a |
|||
jr Z,l_do_scsi_cmd_00113 |
|||
ld l, a |
|||
jr l_do_scsi_cmd_00119 |
|||
l_do_scsi_cmd_00110: |
|||
;source-doc/scsi-drv/./class_scsi.c:31: &dev->endpoints[ENDPOINT_BULK_OUT])); |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
push de |
|||
ld l,(ix-4) |
|||
ld h,(ix-3) |
|||
push hl |
|||
push af |
|||
inc sp |
|||
ld l,(ix-2) |
|||
ld h,(ix-1) |
|||
push hl |
|||
push bc |
|||
call _usb_data_out_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
pop de |
|||
ld (_result+0),a |
|||
or a |
|||
jr Z,l_do_scsi_cmd_00113 |
|||
ld l, a |
|||
jr l_do_scsi_cmd_00119 |
|||
l_do_scsi_cmd_00113: |
|||
;source-doc/scsi-drv/./class_scsi.c:36: usb_data_in_transfer((uint8_t *)&csw, sizeof(_scsi_command_status_wrapper), dev->address, &dev->endpoints[ENDPOINT_BULK_IN])); |
|||
ld hl,0x0006 |
|||
add hl, de |
|||
ex de,hl |
|||
ld c,e |
|||
ld b,d |
|||
ld a, (hl) |
|||
rlca |
|||
rlca |
|||
rlca |
|||
rlca |
|||
and 0x0f |
|||
ld d, a |
|||
push bc |
|||
push de |
|||
inc sp |
|||
ld hl,0x000d |
|||
push hl |
|||
ld hl,_csw |
|||
push hl |
|||
call _usb_data_in_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
ld (_result+0),a |
|||
or a |
|||
jr Z,l_do_scsi_cmd_00115 |
|||
ld l, a |
|||
jr l_do_scsi_cmd_00119 |
|||
l_do_scsi_cmd_00115: |
|||
;source-doc/scsi-drv/./class_scsi.c:38: if (csw.bCSWStatus != 0 && csw.dCSWTag[0] != cbw->dCBWTag[0]) |
|||
ld a, (_csw + 12) |
|||
or a |
|||
jr Z,l_do_scsi_cmd_00117 |
|||
ld bc, (_csw + 4) |
|||
pop hl |
|||
ld e,(hl) |
|||
push hl |
|||
inc hl |
|||
ld h, (hl) |
|||
ld l, e |
|||
xor a |
|||
sbc hl,bc |
|||
jr Z,l_do_scsi_cmd_00117 |
|||
;source-doc/scsi-drv/./class_scsi.c:39: return USB_ERR_FAIL; |
|||
ld l,0x0e |
|||
jr l_do_scsi_cmd_00119 |
|||
l_do_scsi_cmd_00117: |
|||
;source-doc/scsi-drv/./class_scsi.c:41: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_do_scsi_cmd_00119: |
|||
;source-doc/scsi-drv/./class_scsi.c:42: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:46: usb_error get_scsi_read_capacity(device_config_storage *const dev, scsi_read_capacity_result *cap_result) { |
|||
; --------------------------------- |
|||
; Function get_scsi_read_capacity |
|||
; --------------------------------- |
|||
_get_scsi_read_capacity: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -27 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:48: cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:49: cbw_scsi.read_capacity = scsi_read_capacity; |
|||
ld hl,15 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000c |
|||
ld hl,_scsi_read_capacity |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:51: cbw_scsi.cbw.bCBWLUN = 0; |
|||
ld (ix-14),0x00 |
|||
;source-doc/scsi-drv/./class_scsi.c:52: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_read_capacity); |
|||
ld (ix-13),0x0c |
|||
;source-doc/scsi-drv/./class_scsi.c:53: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_read_capacity_result); |
|||
ld (ix-19),0x08 |
|||
xor a |
|||
ld (ix-18),a |
|||
ld (ix-17),a |
|||
ld (ix-16),a |
|||
;source-doc/scsi-drv/./class_scsi.c:55: return do_scsi_cmd(dev, &cbw_scsi.cbw, cap_result, false); |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld hl,3 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _do_scsi_cmd |
|||
;source-doc/scsi-drv/./class_scsi.c:56: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:60: usb_error scsi_inquiry(device_config_storage *const dev, scsi_inquiry_result *inq_result) { |
|||
; --------------------------------- |
|||
; Function scsi_inquiry |
|||
; --------------------------------- |
|||
_scsi_inquiry: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -27 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:62: cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:63: cbw_scsi.inquiry = scsi_packet_inquiry; |
|||
ld hl,15 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000c |
|||
ld hl,_scsi_packet_inquiry |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:65: cbw_scsi.cbw.bCBWLUN = 0; |
|||
ld (ix-14),0x00 |
|||
;source-doc/scsi-drv/./class_scsi.c:66: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_inquiry); |
|||
ld (ix-13),0x0c |
|||
;source-doc/scsi-drv/./class_scsi.c:67: cbw_scsi.cbw.dCBWDataTransferLength = 0x24; |
|||
ld (ix-19),0x24 |
|||
xor a |
|||
ld (ix-18),a |
|||
ld (ix-17),a |
|||
ld (ix-16),a |
|||
;source-doc/scsi-drv/./class_scsi.c:69: return do_scsi_cmd(dev, &cbw_scsi.cbw, inq_result, false); |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld hl,3 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _do_scsi_cmd |
|||
;source-doc/scsi-drv/./class_scsi.c:70: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:72: usb_error scsi_test(device_config_storage *const dev) { |
|||
; --------------------------------- |
|||
; Function scsi_test |
|||
; --------------------------------- |
|||
_scsi_test: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -27 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:74: cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:75: memset(&cbw_scsi.test, 0, sizeof(_scsi_packet_test)); |
|||
ld hl,15 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x0c |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/scsi-drv/./class_scsi.c:77: cbw_scsi.cbw.bCBWLUN = 0; |
|||
ld (ix-14),0x00 |
|||
;source-doc/scsi-drv/./class_scsi.c:78: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_test); |
|||
ld (ix-13),0x0c |
|||
;source-doc/scsi-drv/./class_scsi.c:79: cbw_scsi.cbw.dCBWDataTransferLength = 0; |
|||
ld hl,8 |
|||
add hl, sp |
|||
xor a |
|||
ld (hl),a |
|||
inc hl |
|||
ld (hl),a |
|||
inc hl |
|||
ld (hl),a |
|||
inc hl |
|||
ld (hl),a |
|||
;source-doc/scsi-drv/./class_scsi.c:81: return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false); |
|||
xor a |
|||
push af |
|||
inc sp |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld hl,3 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _do_scsi_cmd |
|||
;source-doc/scsi-drv/./class_scsi.c:82: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:86: usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result) { |
|||
; --------------------------------- |
|||
; Function scsi_request_sense |
|||
; --------------------------------- |
|||
_scsi_request_sense: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -27 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:88: cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:89: cbw_scsi.request_sense = scsi_packet_request_sense; |
|||
ld hl,15 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000c |
|||
ld hl,_scsi_packet_request_sense |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:91: cbw_scsi.cbw.bCBWLUN = 0; |
|||
ld (ix-14),0x00 |
|||
;source-doc/scsi-drv/./class_scsi.c:92: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_request_sense); |
|||
ld (ix-13),0x0c |
|||
;source-doc/scsi-drv/./class_scsi.c:93: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_sense_result); |
|||
ld (ix-19),0x12 |
|||
xor a |
|||
ld (ix-18),a |
|||
ld (ix-17),a |
|||
ld (ix-16),a |
|||
;source-doc/scsi-drv/./class_scsi.c:95: return do_scsi_cmd(dev, &cbw_scsi.cbw, sens_result, false); |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld hl,3 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _do_scsi_cmd |
|||
;source-doc/scsi-drv/./class_scsi.c:96: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:98: usb_error scsi_sense_init(device_config_storage *const dev) { |
|||
; --------------------------------- |
|||
; Function scsi_sense_init |
|||
; --------------------------------- |
|||
_scsi_sense_init: |
|||
ld hl, -18 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:102: while ((result = scsi_test(dev)) && --counter > 0) |
|||
ld c,0x03 |
|||
l_scsi_sense_init_00102: |
|||
push bc |
|||
ld hl,22 |
|||
add hl, sp |
|||
ld c, (hl) |
|||
inc hl |
|||
ld b, (hl) |
|||
push bc |
|||
call _scsi_test |
|||
pop af |
|||
ld a, l |
|||
pop bc |
|||
ld (_result+0), a |
|||
or a |
|||
jr Z,l_scsi_sense_init_00104 |
|||
dec c |
|||
jr Z,l_scsi_sense_init_00104 |
|||
;source-doc/scsi-drv/./class_scsi.c:103: scsi_request_sense(dev, &response); |
|||
push bc |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,24 |
|||
add hl, sp |
|||
ld c, (hl) |
|||
inc hl |
|||
ld b, (hl) |
|||
push bc |
|||
call _scsi_request_sense |
|||
pop af |
|||
pop af |
|||
pop bc |
|||
jr l_scsi_sense_init_00102 |
|||
l_scsi_sense_init_00104: |
|||
;source-doc/scsi-drv/./class_scsi.c:105: return result; |
|||
ld a, (_result+0) |
|||
ld l, a |
|||
;source-doc/scsi-drv/./class_scsi.c:106: } |
|||
ld iy,18 |
|||
add iy, sp |
|||
ld sp, iy |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:110: usb_error scsi_read(device_config_storage *const dev, uint8_t *const buffer) { |
|||
; --------------------------------- |
|||
; Function scsi_read |
|||
; --------------------------------- |
|||
_scsi_read: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/scsi-drv/./class_scsi.c:111: memset(&cbw, 0, sizeof(cbw_scsi_read_write)); |
|||
ld hl,_cbw |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x1b |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/scsi-drv/./class_scsi.c:112: cbw.cbw = scsi_command_block_wrapper; |
|||
ld de,_cbw |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:114: cbw.cbw.bCBWLUN = 0; |
|||
;source-doc/scsi-drv/./class_scsi.c:115: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write); |
|||
ld hl,0x0c00 |
|||
ld ((_cbw + 13)),hl |
|||
;source-doc/scsi-drv/./class_scsi.c:116: cbw.cbw.dCBWDataTransferLength = 512; |
|||
ld hl,0x0200 |
|||
ld (_cbw + 8),hl |
|||
ld h, l |
|||
ld (_cbw + 8 + 2),hl |
|||
;source-doc/scsi-drv/./class_scsi.c:118: cbw.scsi_cmd.operation_code = 0x28; // read operation |
|||
ld hl, +(_cbw + 15) |
|||
ld (hl),0x28 |
|||
;source-doc/scsi-drv/./class_scsi.c:119: cbw.scsi_cmd.transfer_len[1] = 1; |
|||
ld hl, +(_cbw + 23) |
|||
ld (hl),0x01 |
|||
;source-doc/scsi-drv/./class_scsi.c:120: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld hl,0x000c |
|||
add hl, bc |
|||
pop af |
|||
push hl |
|||
inc hl |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
ld ((_cbw + 17)),a |
|||
;source-doc/scsi-drv/./class_scsi.c:121: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16; |
|||
pop hl |
|||
push hl |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
ld ((_cbw + 18)),a |
|||
;source-doc/scsi-drv/./class_scsi.c:122: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8; |
|||
pop hl |
|||
push hl |
|||
inc hl |
|||
ld a,(hl) |
|||
ld ((_cbw + 19)),a |
|||
;source-doc/scsi-drv/./class_scsi.c:123: cbw.scsi_cmd.lba[3] = dev->current_lba; |
|||
ld de,_cbw + 20 |
|||
pop hl |
|||
ld a,(hl) |
|||
push hl |
|||
ld (de), a |
|||
;source-doc/scsi-drv/./class_scsi.c:125: result = do_scsi_cmd(dev, &cbw.cbw, buffer, false); |
|||
ld e,(ix+6) |
|||
ld d,(ix+7) |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push de |
|||
ld hl,_cbw |
|||
push hl |
|||
push bc |
|||
call _do_scsi_cmd |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
;source-doc/scsi-drv/./class_scsi.c:127: if (result == USB_ERR_OK) |
|||
ld (_result+0),a |
|||
or a |
|||
jr NZ,l_scsi_read_00102 |
|||
;source-doc/scsi-drv/./class_scsi.c:128: dev->current_lba++; |
|||
pop hl |
|||
ld c,(hl) |
|||
push hl |
|||
inc hl |
|||
ld b, (hl) |
|||
inc hl |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
inc c |
|||
jr NZ,l_scsi_read_00110 |
|||
inc b |
|||
jr NZ,l_scsi_read_00110 |
|||
inc de |
|||
l_scsi_read_00110: |
|||
pop hl |
|||
push hl |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), b |
|||
inc hl |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
l_scsi_read_00102: |
|||
;source-doc/scsi-drv/./class_scsi.c:129: return result; |
|||
ld a, (_result+0) |
|||
ld l, a |
|||
;source-doc/scsi-drv/./class_scsi.c:130: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:132: usb_error scsi_write(device_config_storage *const dev, uint8_t *const buffer) { |
|||
; --------------------------------- |
|||
; Function scsi_write |
|||
; --------------------------------- |
|||
_scsi_write: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/scsi-drv/./class_scsi.c:133: memset(&cbw, 0, sizeof(cbw_scsi_read_write)); |
|||
ld hl,_cbw |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x1b |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/scsi-drv/./class_scsi.c:134: cbw.cbw = scsi_command_block_wrapper; |
|||
ld de,_cbw |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:136: cbw.cbw.bCBWLUN = 0; |
|||
;source-doc/scsi-drv/./class_scsi.c:137: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write); |
|||
ld hl,0x0c00 |
|||
ld ((_cbw + 13)),hl |
|||
;source-doc/scsi-drv/./class_scsi.c:138: cbw.cbw.dCBWDataTransferLength = 512; |
|||
ld hl,0x0200 |
|||
ld (_cbw + 8),hl |
|||
ld h, l |
|||
ld (_cbw + 8 + 2),hl |
|||
;source-doc/scsi-drv/./class_scsi.c:140: cbw.scsi_cmd.operation_code = 0x2A; // write operation |
|||
ld hl, +(_cbw + 15) |
|||
ld (hl),0x2a |
|||
;source-doc/scsi-drv/./class_scsi.c:141: cbw.scsi_cmd.transfer_len[1] = 1; |
|||
ld hl, +(_cbw + 23) |
|||
ld (hl),0x01 |
|||
;source-doc/scsi-drv/./class_scsi.c:142: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
ld hl,0x000c |
|||
add hl, bc |
|||
pop af |
|||
push hl |
|||
inc hl |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
ld ((_cbw + 17)),a |
|||
;source-doc/scsi-drv/./class_scsi.c:143: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16; |
|||
pop hl |
|||
push hl |
|||
inc hl |
|||
inc hl |
|||
ld a, (hl) |
|||
ld ((_cbw + 18)),a |
|||
;source-doc/scsi-drv/./class_scsi.c:144: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8; |
|||
pop hl |
|||
push hl |
|||
inc hl |
|||
ld a,(hl) |
|||
ld ((_cbw + 19)),a |
|||
;source-doc/scsi-drv/./class_scsi.c:145: cbw.scsi_cmd.lba[3] = dev->current_lba; |
|||
ld de,_cbw + 20 |
|||
pop hl |
|||
ld a,(hl) |
|||
push hl |
|||
ld (de), a |
|||
;source-doc/scsi-drv/./class_scsi.c:147: result = do_scsi_cmd(dev, &cbw.cbw, buffer, true); |
|||
ld e,(ix+6) |
|||
ld d,(ix+7) |
|||
ld a,0x01 |
|||
push af |
|||
inc sp |
|||
push de |
|||
ld hl,_cbw |
|||
push hl |
|||
push bc |
|||
call _do_scsi_cmd |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
;source-doc/scsi-drv/./class_scsi.c:149: if (result == USB_ERR_OK) |
|||
ld (_result+0),a |
|||
or a |
|||
jr NZ,l_scsi_write_00102 |
|||
;source-doc/scsi-drv/./class_scsi.c:150: dev->current_lba++; |
|||
pop hl |
|||
ld c,(hl) |
|||
push hl |
|||
inc hl |
|||
ld b, (hl) |
|||
inc hl |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
inc c |
|||
jr NZ,l_scsi_write_00110 |
|||
inc b |
|||
jr NZ,l_scsi_write_00110 |
|||
inc de |
|||
l_scsi_write_00110: |
|||
pop hl |
|||
push hl |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), b |
|||
inc hl |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
l_scsi_write_00102: |
|||
;source-doc/scsi-drv/./class_scsi.c:151: return result; |
|||
ld a, (_result+0) |
|||
ld l, a |
|||
;source-doc/scsi-drv/./class_scsi.c:152: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/scsi-drv/./class_scsi.c:154: usb_error scsi_eject(device_config_storage *const dev) { |
|||
; --------------------------------- |
|||
; Function scsi_eject |
|||
; --------------------------------- |
|||
_scsi_eject: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -21 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/scsi-drv/./class_scsi.c:156: cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000f |
|||
ld hl,_scsi_command_block_wrapper |
|||
ldir |
|||
;source-doc/scsi-drv/./class_scsi.c:158: memset(&cbw_scsi.eject, 0, sizeof(_scsi_packet_eject)); |
|||
ld hl,15 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x06 |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/scsi-drv/./class_scsi.c:160: cbw_scsi.eject.operation_code = 0x1B; |
|||
ld (ix-6),0x1b |
|||
;source-doc/scsi-drv/./class_scsi.c:161: cbw_scsi.eject.loej = 1; |
|||
ld hl,19 |
|||
add hl, sp |
|||
set 1, (hl) |
|||
;source-doc/scsi-drv/./class_scsi.c:163: cbw_scsi.cbw.bCBWLUN = 0; |
|||
ld (ix-8),0x00 |
|||
;source-doc/scsi-drv/./class_scsi.c:164: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_eject); |
|||
ld (ix-7),0x06 |
|||
;source-doc/scsi-drv/./class_scsi.c:165: cbw_scsi.cbw.dCBWDataTransferLength = 0; |
|||
ld hl,8 |
|||
add hl, sp |
|||
xor a |
|||
ld (hl),a |
|||
inc hl |
|||
ld (hl),a |
|||
inc hl |
|||
ld (hl),a |
|||
inc hl |
|||
ld (hl),a |
|||
;source-doc/scsi-drv/./class_scsi.c:167: return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false); |
|||
xor a |
|||
push af |
|||
inc sp |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld hl,3 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _do_scsi_cmd |
|||
;source-doc/scsi-drv/./class_scsi.c:168: } |
|||
ld sp,ix |
|||
pop ix |
|||
ret |
|||
_scsi_command_block_wrapper: |
|||
DEFB +0x55 |
|||
DEFB +0x53 |
|||
DEFB +0x42 |
|||
DEFB +0x43 |
|||
DEFW +0x0000 |
|||
DEFW +0x0000 |
|||
DEFB +0x00,0x00, +0x00, +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
_next_tag: |
|||
DEFW +0x0000 |
|||
_csw: |
|||
DEFB +0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
_scsi_read_capacity: |
|||
DEFB +0x25 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
_scsi_packet_inquiry: |
|||
DEFB +0x12 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x24 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
_scsi_packet_request_sense: |
|||
DEFB +0x03 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x12 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
_cbw: |
|||
DEFB +0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB +0x00,0x00, +0x00, +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
DEFB 0x00 |
|||
DEFB 0x00 |
|||
@ -0,0 +1,162 @@ |
|||
; |
|||
; Generated from source-doc/scsi-drv/./init.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/scsi-drv/./init.c:13: uint8_t chscsi_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1) { |
|||
; --------------------------------- |
|||
; Function chscsi_seek |
|||
; --------------------------------- |
|||
_chscsi_seek: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld c, l |
|||
ld b, h |
|||
;source-doc/scsi-drv/./init.c:14: storage_device->current_lba = lba; |
|||
ld a,(ix+4) |
|||
ld h,(ix+5) |
|||
add a,0x0c |
|||
ld l, a |
|||
jr NC,l_chscsi_seek_00103 |
|||
inc h |
|||
l_chscsi_seek_00103: |
|||
ld (hl), e |
|||
inc hl |
|||
ld (hl), d |
|||
inc hl |
|||
ld (hl), c |
|||
inc hl |
|||
ld (hl), b |
|||
;source-doc/scsi-drv/./init.c:15: return 0; |
|||
xor a |
|||
;source-doc/scsi-drv/./init.c:16: } |
|||
pop ix |
|||
pop hl |
|||
pop bc |
|||
jp (hl) |
|||
;source-doc/scsi-drv/./init.c:18: void chscsi_init(void) { |
|||
; --------------------------------- |
|||
; Function chscsi_init |
|||
; --------------------------------- |
|||
_chscsi_init: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
dec sp |
|||
;source-doc/scsi-drv/./init.c:21: do { |
|||
ld c,0x00 |
|||
ld (ix-1),0x01 |
|||
l_chscsi_init_00105: |
|||
;source-doc/scsi-drv/./init.c:22: device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index); |
|||
push bc |
|||
ld a,(ix-1) |
|||
call _get_usb_device_config |
|||
pop bc |
|||
;source-doc/scsi-drv/./init.c:24: if (storage_device == NULL) |
|||
ld a, d |
|||
or e |
|||
jr Z,l_chscsi_init_00107 |
|||
;source-doc/scsi-drv/./init.c:27: const usb_device_type t = storage_device->type; |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
;source-doc/scsi-drv/./init.c:29: if (t == USB_IS_MASS_STORAGE) { |
|||
sub 0x02 |
|||
jr NZ,l_chscsi_init_00106 |
|||
;source-doc/scsi-drv/./init.c:30: storage_device->drive_index = storage_count++; |
|||
ld hl,0x0010 |
|||
add hl, de |
|||
ld (hl), c |
|||
inc c |
|||
;source-doc/scsi-drv/./init.c:31: scsi_sense_init(storage_device); |
|||
push bc |
|||
push de |
|||
push de |
|||
call _scsi_sense_init |
|||
pop af |
|||
pop de |
|||
ld hl,_ch_scsi_fntbl |
|||
call _dio_add_entry |
|||
pop bc |
|||
l_chscsi_init_00106: |
|||
;source-doc/scsi-drv/./init.c:35: } while (++index != MAX_NUMBER_OF_STORAGE_DEVICES + 1); |
|||
inc (ix-1) |
|||
ld a,(ix-1) |
|||
sub 0x05 |
|||
jr NZ,l_chscsi_init_00105 |
|||
l_chscsi_init_00107: |
|||
;source-doc/scsi-drv/./init.c:37: if (storage_count == 0) |
|||
ld a, c |
|||
or a |
|||
;source-doc/scsi-drv/./init.c:38: return; |
|||
jr Z,l_chscsi_init_00110 |
|||
;source-doc/scsi-drv/./init.c:40: print_string(" $"); |
|||
push bc |
|||
ld hl,init_str_0 |
|||
call _print_string |
|||
pop bc |
|||
;source-doc/scsi-drv/./init.c:41: print_uint16(storage_count); |
|||
ld h,0x00 |
|||
ld l, c |
|||
call _print_uint16 |
|||
;source-doc/scsi-drv/./init.c:42: print_string(" STORAGE DEVICES$"); |
|||
ld hl,init_str_1 |
|||
call _print_string |
|||
l_chscsi_init_00110: |
|||
;source-doc/scsi-drv/./init.c:43: } |
|||
inc sp |
|||
pop ix |
|||
ret |
|||
init_str_0: |
|||
DEFM " $" |
|||
DEFB 0x00 |
|||
init_str_1: |
|||
DEFM " STORAGE DEVICES$" |
|||
DEFB 0x00 |
|||
@ -0,0 +1,125 @@ |
|||
; |
|||
; Generated from source-doc/scsi-drv/./scsi-init.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/scsi-drv/./scsi-init.c:13: void chscsi_init(void) { |
|||
; --------------------------------- |
|||
; Function chscsi_init |
|||
; --------------------------------- |
|||
_chscsi_init: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/scsi-drv/./scsi-init.c:15: do { |
|||
ld (ix-1),0x01 |
|||
l_chscsi_init_00105: |
|||
;source-doc/scsi-drv/./scsi-init.c:16: device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index); |
|||
ld a,(ix-1) |
|||
call _get_usb_device_config |
|||
;source-doc/scsi-drv/./scsi-init.c:18: if (storage_device == NULL) |
|||
ld a, d |
|||
or e |
|||
jr Z,l_chscsi_init_00107 |
|||
;source-doc/scsi-drv/./scsi-init.c:21: const usb_device_type t = storage_device->type; |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
;source-doc/scsi-drv/./scsi-init.c:23: if (t == USB_IS_MASS_STORAGE) { |
|||
sub 0x02 |
|||
jr NZ,l_chscsi_init_00106 |
|||
;source-doc/scsi-drv/./scsi-init.c:24: storage_device->drive_index = storage_count++; |
|||
ld hl,0x0010 |
|||
add hl, de |
|||
ld a,(_storage_count+0) |
|||
ld (ix-2),a |
|||
ld c,l |
|||
ld b,h |
|||
ld hl,_storage_count+0 |
|||
inc (hl) |
|||
ld a,(ix-2) |
|||
ld (bc), a |
|||
;source-doc/scsi-drv/./scsi-init.c:25: scsi_sense_init(storage_device); |
|||
push de |
|||
push de |
|||
call _scsi_sense_init |
|||
pop af |
|||
pop de |
|||
;source-doc/scsi-drv/./scsi-init.c:26: dio_add_entry(ch_scsi_fntbl, storage_device); |
|||
ld hl,_ch_scsi_fntbl |
|||
call _dio_add_entry |
|||
l_chscsi_init_00106: |
|||
;source-doc/scsi-drv/./scsi-init.c:29: } while (++index != MAX_NUMBER_OF_DEVICES + 1); |
|||
inc (ix-1) |
|||
ld a,(ix-1) |
|||
sub 0x07 |
|||
jr NZ,l_chscsi_init_00105 |
|||
l_chscsi_init_00107: |
|||
;source-doc/scsi-drv/./scsi-init.c:31: if (storage_count == 0) |
|||
;source-doc/scsi-drv/./scsi-init.c:32: return; |
|||
;source-doc/scsi-drv/./scsi-init.c:34: print_device_mounted(" STORAGE DEVICE$", storage_count); |
|||
ld a,(_storage_count+0) |
|||
or a |
|||
jr Z,l_chscsi_init_00110 |
|||
push af |
|||
inc sp |
|||
ld hl,scsi_init_str_0 |
|||
push hl |
|||
call _print_device_mounted |
|||
pop af |
|||
inc sp |
|||
l_chscsi_init_00110: |
|||
;source-doc/scsi-drv/./scsi-init.c:35: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
scsi_init_str_0: |
|||
DEFM " STORAGE DEVICE$" |
|||
DEFB 0x00 |
|||
@ -0,0 +1,13 @@ |
|||
BasedOnStyle: LLVM |
|||
IndentWidth: 2 |
|||
AlignConsecutiveMacros: true |
|||
ColumnLimit: 132 |
|||
AlignConsecutiveAssignments: true |
|||
AlignConsecutiveDeclarations: true |
|||
AlignEscapedNewlines: true |
|||
AlignConsecutiveMacros: true |
|||
AlignEscapedNewlines: Right |
|||
BinPackArguments: true |
|||
BinPackParameters: false |
|||
IncludeBlocks: Preserve |
|||
SortIncludes: CaseInsensitive |
|||
@ -0,0 +1,238 @@ |
|||
#include "ch376.h" |
|||
|
|||
#include "print.h" |
|||
|
|||
usb_error result = 0; |
|||
|
|||
void ch_command(const uint8_t command) __z88dk_fastcall { |
|||
uint8_t counter = 255; |
|||
while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0) |
|||
delay(); |
|||
|
|||
// if (counter == 0) {
|
|||
// It appears that the Ch376 has become blocked
|
|||
// command will fail and timeout will eventually be returned by the ch_xxx_wait_int_and_get_status
|
|||
// todo consider a return value to allow callers to respond appropriately
|
|||
// Experimentation would indicate that USB_RESET_ALL will still work to reset chip
|
|||
// return;
|
|||
// }
|
|||
|
|||
delay(); |
|||
CH376_COMMAND_PORT = command; |
|||
delay(); |
|||
} |
|||
|
|||
extern usb_error ch_wait_int_and_get_status(const int16_t timeout) __z88dk_fastcall; |
|||
|
|||
usb_error ch_long_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(5000); } |
|||
|
|||
usb_error ch_short_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(100); } |
|||
|
|||
usb_error ch_very_short_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(10); } |
|||
|
|||
usb_error ch_get_status(void) { |
|||
ch_command(CH_CMD_GET_STATUS); |
|||
uint8_t ch_status = CH376_DATA_PORT; |
|||
|
|||
if (ch_status >= USB_FILERR_MIN && ch_status <= USB_FILERR_MAX) |
|||
return ch_status; |
|||
|
|||
if (ch_status == CH_CMD_RET_SUCCESS) |
|||
return USB_ERR_OK; |
|||
|
|||
if (ch_status == CH_USB_INT_SUCCESS) |
|||
return USB_ERR_OK; |
|||
|
|||
if (ch_status == CH_USB_INT_CONNECT) |
|||
return USB_INT_CONNECT; |
|||
|
|||
if (ch_status == CH_USB_INT_DISK_READ) |
|||
return USB_ERR_DISK_READ; |
|||
|
|||
if (ch_status == CH_USB_INT_DISK_WRITE) |
|||
return USB_ERR_DISK_WRITE; |
|||
|
|||
if (ch_status == CH_USB_INT_DISCONNECT) { |
|||
ch_cmd_set_usb_mode(5); |
|||
return USB_ERR_NO_DEVICE; |
|||
} |
|||
|
|||
if (ch_status == CH_USB_INT_BUF_OVER) |
|||
return USB_ERR_DATA_ERROR; |
|||
|
|||
ch_status &= 0x2F; |
|||
|
|||
if (ch_status == 0x2A) |
|||
return USB_ERR_NAK; |
|||
|
|||
if (ch_status == 0x2E) |
|||
return USB_ERR_STALL; |
|||
|
|||
ch_status &= 0x23; |
|||
|
|||
if (ch_status == 0x20) |
|||
return USB_ERR_TIMEOUT; |
|||
|
|||
if (ch_status == 0x23) |
|||
return USB_TOKEN_OUT_OF_SYNC; |
|||
|
|||
return USB_ERR_UNEXPECTED_STATUS_FROM_HOST; |
|||
} |
|||
|
|||
void ch_cmd_reset_all(void) { ch_command(CH_CMD_RESET_ALL); } |
|||
|
|||
inline uint8_t ch_cmd_check_exist(void) { |
|||
uint8_t complement; |
|||
ch_command(CH_CMD_CHECK_EXIST); |
|||
CH376_DATA_PORT = (uint8_t)~0x55; |
|||
delay(); |
|||
complement = CH376_DATA_PORT; |
|||
return complement == 0x55; |
|||
// if (complement != 0x55)
|
|||
// return false;
|
|||
|
|||
// ch_command(CH_CMD_CHECK_EXIST);
|
|||
// CH376_DATA_PORT = (uint8_t)~0x89;
|
|||
// delay();
|
|||
// complement = CH376_DATA_PORT;
|
|||
// return complement == 0x89;
|
|||
} |
|||
|
|||
uint8_t ch_probe(void) { |
|||
uint8_t i = 5; |
|||
do { |
|||
if (ch_cmd_check_exist()) |
|||
return true; |
|||
|
|||
delay_medium(); |
|||
} while (--i != 0); |
|||
|
|||
return false; |
|||
} |
|||
|
|||
uint8_t ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall { |
|||
uint8_t result = 0; |
|||
|
|||
CH376_COMMAND_PORT = CH_CMD_SET_USB_MODE; |
|||
delay(); |
|||
CH376_DATA_PORT = mode; |
|||
delay(); |
|||
|
|||
uint8_t count = 127; |
|||
|
|||
while (result != CH_CMD_RET_SUCCESS && result != CH_CMD_RET_ABORT && --count != 0) { |
|||
result = CH376_DATA_PORT; |
|||
delay(); |
|||
} |
|||
|
|||
return (result == CH_CMD_RET_SUCCESS) ? USB_ERR_OK : USB_ERR_FAIL; |
|||
} |
|||
|
|||
uint8_t ch_cmd_get_ic_version(void) { |
|||
ch_command(CH_CMD_GET_IC_VER); |
|||
return CH376_DATA_PORT & 0x1f; |
|||
} |
|||
|
|||
void ch_issue_token(const uint8_t toggle_bit, const uint8_t endpoint, const ch376_pid pid) { |
|||
ch_command(CH_CMD_ISSUE_TKN_X); |
|||
CH376_DATA_PORT = toggle_bit; |
|||
delay(); |
|||
CH376_DATA_PORT = endpoint << 4 | pid; |
|||
delay(); |
|||
} |
|||
|
|||
void ch_issue_token_in(const endpoint_param *const endpoint) __z88dk_fastcall { |
|||
ch_issue_token(endpoint->toggle ? 0x80 : 0x00, endpoint->number, CH_PID_IN); |
|||
} |
|||
|
|||
void ch_issue_token_out(const endpoint_param *const endpoint) __z88dk_fastcall { |
|||
ch_issue_token(endpoint->toggle ? 0x40 : 0x00, endpoint->number, CH_PID_OUT); |
|||
} |
|||
|
|||
void ch_issue_token_out_ep0(void) { ch_issue_token(0x40, 0, CH_PID_OUT); } |
|||
|
|||
void ch_issue_token_in_ep0(void) { ch_issue_token(0x80, 0, CH_PID_IN); } |
|||
|
|||
void ch_issue_token_setup(void) { ch_issue_token(0, 0, CH_PID_SETUP); } |
|||
|
|||
usb_error ch_data_in_transfer(uint8_t *buffer, int16_t buffer_size, endpoint_param *const endpoint) { |
|||
uint8_t count; |
|||
usb_error result; |
|||
|
|||
if (buffer_size == 0) |
|||
return USB_ERR_OK; |
|||
|
|||
USB_MODULE_LEDS = 0x01; |
|||
do { |
|||
ch_issue_token_in(endpoint); |
|||
|
|||
result = ch_long_wait_int_and_get_status(); |
|||
CHECK(result); |
|||
|
|||
endpoint->toggle = !endpoint->toggle; |
|||
|
|||
count = ch_read_data(buffer); |
|||
|
|||
if (count == 0) { |
|||
USB_MODULE_LEDS = 0x00; |
|||
return USB_ERR_DATA_ERROR; |
|||
} |
|||
|
|||
buffer += count; |
|||
buffer_size -= count; |
|||
} while (buffer_size > 0); |
|||
|
|||
USB_MODULE_LEDS = 0x00; |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
usb_error ch_data_in_transfer_n(uint8_t *const buffer, int8_t *const buffer_size, endpoint_param *const endpoint) { |
|||
uint8_t count; |
|||
usb_error result; |
|||
|
|||
USB_MODULE_LEDS = 0x01; |
|||
|
|||
ch_issue_token_in(endpoint); |
|||
|
|||
CHECK(ch_long_wait_int_and_get_status()); |
|||
|
|||
endpoint->toggle = !endpoint->toggle; |
|||
|
|||
count = ch_read_data(buffer); |
|||
|
|||
*buffer_size = count; |
|||
|
|||
USB_MODULE_LEDS = 0x00; |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint) { |
|||
usb_error result; |
|||
const uint8_t number = endpoint->number; |
|||
const uint8_t max_packet_size = calc_max_packet_size(endpoint->max_packet_sizex); |
|||
|
|||
USB_MODULE_LEDS = 0x02; |
|||
|
|||
while (buffer_length > 0) { |
|||
const uint8_t size = max_packet_size < buffer_length ? max_packet_size : buffer_length; |
|||
buffer = ch_write_data(buffer, size); |
|||
buffer_length -= size; |
|||
ch_issue_token_out(endpoint); |
|||
|
|||
CHECK(ch_long_wait_int_and_get_status()); |
|||
|
|||
endpoint->toggle = !endpoint->toggle; |
|||
} |
|||
|
|||
USB_MODULE_LEDS = 0x00; |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall { |
|||
ch_command(CH_CMD_SET_USB_ADDR); |
|||
CH376_DATA_PORT = device_address; |
|||
delay(); |
|||
} |
|||
@ -0,0 +1,175 @@ |
|||
|
|||
#ifndef __CH376 |
|||
#define __CH376 |
|||
|
|||
#include "ch376inc.h" |
|||
#include "delay.h" |
|||
#include <stdlib.h> |
|||
|
|||
typedef enum { |
|||
USB_ERR_OK = 0, |
|||
USB_ERR_NAK = 1, |
|||
USB_ERR_STALL = 2, |
|||
USB_ERR_TIMEOUT = 3, |
|||
USB_ERR_DATA_ERROR = 4, |
|||
USB_ERR_NO_DEVICE = 5, |
|||
USB_ERR_PANIC_BUTTON_PRESSED = 6, |
|||
USB_TOKEN_OUT_OF_SYNC = 7, |
|||
USB_ERR_UNEXPECTED_STATUS_FROM_HOST = 8, |
|||
USB_ERR_CODE_EXCEPTION = 9, |
|||
USB_ERR_MEDIA_CHANGED = 10, |
|||
USB_ERR_MEDIA_NOT_PRESENT = 11, |
|||
USB_ERR_CH376_BLOCKED = 12, |
|||
USB_ERR_CH376_TIMEOUT = 13, |
|||
USB_ERR_FAIL = 14, |
|||
USB_ERR_MAX = 14, |
|||
USB_ERR_OTHER = 15, |
|||
USB_ERR_DISK_READ = 0x1D, |
|||
USB_ERR_DISK_WRITE = 0x1E, |
|||
USB_FILERR_MIN = 0x41, |
|||
USB_ERR_OPEN_DIR = 0x41, |
|||
USB_ERR_MISS_FILE = 0x42, |
|||
USB_FILERR_MAX = 0xB4, |
|||
USB_INT_CONNECT = 0x81, |
|||
USB_BAD_ADDRESS = 0x82, |
|||
USB_ERR_OUT_OF_MEMORY = 0x83, |
|||
USB_ERR_BUFF_TO_LARGE = 0x84, |
|||
USB_ERROR_DEVICE_NOT_FOUND = 0x85, |
|||
} usb_error; |
|||
|
|||
typedef enum { CH_NAK_RETRY_DONT = 0b00, CH_NAK_RETRY_INDEFINITE = 0b10, CH_NAK_RETRY_3S = 0b11 } ch_nak_retry_type; |
|||
|
|||
typedef enum { |
|||
USB_NOT_SUPPORTED = 0, |
|||
USB_IS_FLOPPY = 1, |
|||
USB_IS_MASS_STORAGE = 2, |
|||
USB_IS_CDC = 3, |
|||
USB_IS_KEYBOARD = 4, |
|||
USB_IS_UNKNOWN = 6, |
|||
_USB_LAST_DEVICE_TYPE, |
|||
USB_IS_HUB = 15 |
|||
} usb_device_type; // 4 bits only
|
|||
|
|||
typedef enum { ENDPOINT_BULK_OUT = 0, ENDPOINT_BULK_IN = 1, ENDPOINT_INTERRUPT_IN = 2 } usb_endpoint_type; |
|||
|
|||
extern int printf(const char *msg, ...); |
|||
|
|||
#if STACK_TRACE_ENABLED |
|||
|
|||
#define trace_printf printf |
|||
|
|||
#define CHECK(fn) \ |
|||
{ \ |
|||
result = fn; \ |
|||
if (result != USB_ERR_OK && result != USB_ERR_STALL) { \ |
|||
if (result != USB_TOKEN_OUT_OF_SYNC) \ |
|||
printf("Error: %s:%d %d\r\n", __FILE__, __LINE__, result); \ |
|||
return result; \ |
|||
} \ |
|||
} |
|||
|
|||
#define RETURN_CHECK(fn) \ |
|||
{ \ |
|||
result = fn; \ |
|||
if (result != USB_ERR_OK && result != USB_ERR_STALL) { \ |
|||
if (result != USB_TOKEN_OUT_OF_SYNC) \ |
|||
printf("Error: %s:%d %d\r\n", __FILE__, __LINE__, result); \ |
|||
return result; \ |
|||
} \ |
|||
return result; \ |
|||
} |
|||
|
|||
#define TRACE_USB_ERROR(result) \ |
|||
{ \ |
|||
if (result != USB_ERR_OK) { \ |
|||
printf("USB: %s:%d %d\r\n", __FILE__, __LINE__, result); \ |
|||
} \ |
|||
} |
|||
|
|||
#else |
|||
|
|||
extern usb_error result; |
|||
|
|||
#define trace_printf(...) |
|||
|
|||
#define CHECK(fn) \ |
|||
{ \ |
|||
result = fn; \ |
|||
if (result != USB_ERR_OK) \ |
|||
return result; \ |
|||
} |
|||
|
|||
#define RETURN_CHECK(fn) \ |
|||
{ return fn; } |
|||
|
|||
#define TRACE_USB_ERROR(result) |
|||
|
|||
#endif |
|||
|
|||
#define calc_max_packet_sizex(packet_size) (packet_size & 0x3FF) |
|||
#define calc_max_packet_size(packet_sizex) packet_sizex |
|||
|
|||
typedef struct { |
|||
uint8_t toggle : 1; |
|||
uint8_t number : 3; |
|||
uint16_t max_packet_sizex : 10; |
|||
} endpoint_param; |
|||
|
|||
#define CH_SPEED_FULL \ |
|||
0 /* 12Mbps full speed FullSpeed (default value) \
|
|||
*/ |
|||
#define CH_SPEED_LOW_FREQ 1 /* 1.5Mbps (modify frequency only) */ |
|||
#define CH_SPEED_LOW 2 /* 1.5Mbps low speed LowSpeed */ |
|||
|
|||
#define CH_MODE_HOST_RESET 7 |
|||
#define CH_MODE_HOST 6 |
|||
|
|||
typedef enum _ch376_pid { CH_PID_SETUP = DEF_USB_PID_SETUP, CH_PID_IN = DEF_USB_PID_IN, CH_PID_OUT = DEF_USB_PID_OUT } ch376_pid; |
|||
|
|||
__sfr __banked __at(0xFF88) CH376_DATA_PORT; |
|||
__sfr __banked __at(0xFF89) CH376_COMMAND_PORT; |
|||
|
|||
__sfr __banked __at(0xFF8A) USB_MODULE_LEDS; |
|||
|
|||
extern void delay_20ms(void); |
|||
extern void delay_short(void); |
|||
extern void delay_medium(void); |
|||
|
|||
extern void ch_command(const uint8_t command) __z88dk_fastcall; |
|||
extern usb_error ch_get_status(void); |
|||
extern usb_error ch_long_wait_int_and_get_status(void); |
|||
extern usb_error ch_short_wait_int_and_get_status(void); |
|||
extern usb_error ch_very_short_wait_int_and_get_status(void); |
|||
extern uint8_t ch_read_data(uint8_t *buffer) __sdcccall(1); |
|||
extern void ch_cmd_reset_all(void); |
|||
extern uint8_t ch_probe(void); |
|||
extern usb_error ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall; |
|||
extern uint8_t ch_cmd_get_ic_version(void); |
|||
extern const uint8_t *ch_write_data(const uint8_t *buffer, uint8_t length); |
|||
|
|||
extern void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall; |
|||
|
|||
extern usb_error ch_control_transfer_request_descriptor(const uint8_t descriptor_type) __z88dk_fastcall; |
|||
extern usb_error ch_control_transfer_set_address(const uint8_t device_address) __z88dk_fastcall; |
|||
extern usb_error ch_control_transfer_set_config(const uint8_t config_value) __z88dk_fastcall; |
|||
extern usb_error ch_data_in_transfer(uint8_t *buffer, int16_t data_length, endpoint_param *const endpoint); |
|||
extern usb_error ch_data_in_transfer_n(uint8_t *buffer, int8_t *const buffer_size, endpoint_param *const endpoint); |
|||
extern usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint); |
|||
|
|||
inline void ch_configure_nak_retry(const ch_nak_retry_type retry, const uint8_t number_of_retries) { |
|||
ch_command(CH_CMD_WRITE_VAR8); |
|||
CH376_DATA_PORT = CH_VAR_RETRY_TIMES; |
|||
delay(); |
|||
CH376_DATA_PORT = retry << 6 | (number_of_retries & 0x1F); |
|||
delay(); |
|||
} |
|||
|
|||
#define ch_configure_nak_retry_indefinite() ch_configure_nak_retry(CH_NAK_RETRY_INDEFINITE, 0x1F) |
|||
#define ch_configure_nak_retry_disable() ch_configure_nak_retry(CH_NAK_RETRY_DONT, 0x1F) |
|||
#define ch_configure_nak_retry_3s() ch_configure_nak_retry(CH_NAK_RETRY_3S, 0x1F) |
|||
|
|||
extern void ch_issue_token_setup(void); |
|||
extern void ch_issue_token_out_ep0(void); |
|||
extern void ch_issue_token_in_ep0(void); |
|||
|
|||
#endif |
|||
File diff suppressed because it is too large
@ -0,0 +1,9 @@ |
|||
#include "class_hub.h" |
|||
#include "protocol.h" |
|||
#include "usb_state.h" |
|||
|
|||
const setup_packet cmd_get_hub_descriptor = {RT_DEVICE_TO_HOST | RT_CLASS | RT_DEVICE, 6, {0, 0x29}, {0, 0}, 8}; |
|||
|
|||
usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1) { |
|||
return usb_control_transfer(&cmd_get_hub_descriptor, hub_description, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
@ -0,0 +1,75 @@ |
|||
#ifndef __CLASS_HUB |
|||
#define __CLASS_HUB |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include <stdlib.h> |
|||
|
|||
/*
|
|||
wHubCharacteristics: |
|||
D1...D0: Logical Power Switching Mode |
|||
00: Ganged power switching (all ports power at once) |
|||
01: Individual port power switching |
|||
1X: Reserved. Used only on 1.0 compliant hubs that implement no power switching |
|||
|
|||
D2: Identifies a Compound Device |
|||
0: Hub is not part of a compound device. |
|||
1: Hub is part of a compound device. |
|||
|
|||
D4...D3: Logical Power Switching Mode |
|||
00: Global Over-current Protection. The hub reports over-current as a summation |
|||
of all ports’ current draw, without a breakdown of individual port |
|||
over-current status. |
|||
01: Individual Port Over-current Protection. The hub reports over-current on a |
|||
per-port basis. Each port has an over-current status. |
|||
1X: No Over-current Protection. This option is allowed only for bus-powered |
|||
*/ |
|||
|
|||
typedef struct { |
|||
uint8_t bDescLength; |
|||
uint8_t bDescriptorType; /* HUB Descriptor Type 0x29 */ |
|||
uint8_t bNbrPorts; /* Number of ports */ |
|||
uint16_t wHubCharacteristics; /* Bitmap Hub Characteristics (see above) */ |
|||
uint8_t bPwrOn2PwrGood; /* Time (*2 ms) from port power on to power good */ |
|||
uint8_t bHubContrCurrent; /* Maximum current used by hub controller (mA).*/ |
|||
uint8_t DeviceRemovable[1]; /* bits indicating deviceRemovable and portPwrCtrlMask */ |
|||
} hub_descriptor; |
|||
|
|||
typedef struct { |
|||
union { |
|||
struct { |
|||
uint8_t port_connection : 1; |
|||
uint8_t port_enable : 1; |
|||
uint8_t port_suspend : 1; |
|||
uint8_t port_over_current : 1; |
|||
uint8_t port_reset : 1; |
|||
uint8_t reserved : 3; |
|||
uint8_t port_power : 1; |
|||
uint8_t port_low_speed : 1; |
|||
uint8_t port_high_speed : 1; |
|||
uint8_t port_test : 1; |
|||
uint8_t port_indicator : 1; |
|||
}; |
|||
|
|||
uint16_t val; |
|||
|
|||
} wPortStatus; |
|||
|
|||
union { |
|||
struct { |
|||
uint8_t c_port_connection : 1; |
|||
uint8_t c_port_enable : 1; |
|||
uint8_t c_port_suspend : 1; |
|||
uint8_t c_port_over_current : 1; |
|||
uint8_t c_port_reset : 1; |
|||
}; |
|||
|
|||
uint16_t val; |
|||
|
|||
} wPortChange; |
|||
|
|||
} hub_port_status; |
|||
|
|||
usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1); |
|||
|
|||
#endif |
|||
@ -0,0 +1,11 @@ |
|||
#ifndef __DELAY |
|||
#define __DELAY |
|||
|
|||
#include <stdlib.h> |
|||
|
|||
extern void delay(void); |
|||
extern void delay_20ms(void); |
|||
extern void delay_short(void); |
|||
extern void delay_medium(void); |
|||
|
|||
#endif |
|||
@ -0,0 +1,101 @@ |
|||
/**
|
|||
* @file transfers.c |
|||
* @author Dean Netherton |
|||
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip |
|||
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
|
|||
* @version 1.0 |
|||
* @date 2023-09-22 |
|||
* |
|||
* @copyright Copyright (c) 2023 |
|||
* |
|||
*/ |
|||
|
|||
#include "dev_transfers.h" |
|||
#include "ch376.h" |
|||
#include "delay.h" |
|||
#include "protocol.h" |
|||
#include <stdlib.h> |
|||
|
|||
/**
|
|||
* @brief Perform a USB control transfer (in or out) |
|||
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
|
|||
* |
|||
* @param device the usb device |
|||
* @param cmd_packet Pointer to the setup packet - top bit of bmRequestType indicate data direction |
|||
* @param buffer Pointer of data to send or receive into |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) { |
|||
return usb_control_transfer(cmd_packet, buffer, device->address, device->max_packet_size); |
|||
} |
|||
|
|||
usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) { |
|||
|
|||
usb_error result; |
|||
|
|||
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT]; |
|||
|
|||
result = usb_data_out_transfer(buffer, buffer_size, dev->address, endpoint); |
|||
|
|||
if (result == USB_ERR_STALL) { |
|||
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size); |
|||
endpoint->toggle = 0; |
|||
return USB_ERR_STALL; |
|||
} |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) { |
|||
|
|||
usb_error result; |
|||
|
|||
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN]; |
|||
|
|||
result = usb_data_in_transfer_n(buffer, buffer_size, dev->address, endpoint); |
|||
|
|||
if (result == USB_ERR_STALL) { |
|||
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size); |
|||
endpoint->toggle = 0; |
|||
return USB_ERR_STALL; |
|||
} |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error usbdev_dat_in_trnsfer(device_config *const device, |
|||
uint8_t *const buffer, |
|||
const uint16_t buffer_size, |
|||
const usb_endpoint_type endpoint_type) { |
|||
|
|||
usb_error result; |
|||
|
|||
endpoint_param *const endpoint = &device->endpoints[endpoint_type]; |
|||
|
|||
result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint); |
|||
|
|||
if (result == USB_ERR_STALL) { |
|||
usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size); |
|||
endpoint->toggle = 0; |
|||
return USB_ERR_STALL; |
|||
} |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) __sdcccall(1) { |
|||
|
|||
usb_error result; |
|||
|
|||
endpoint_param *const endpoint = &device->endpoints[0]; |
|||
|
|||
result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint); |
|||
|
|||
if (result == USB_ERR_STALL) { |
|||
usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size); |
|||
endpoint->toggle = 0; |
|||
return USB_ERR_STALL; |
|||
} |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
@ -0,0 +1,68 @@ |
|||
/**
|
|||
* @file transfer.h |
|||
* @author Dean Netherton |
|||
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip |
|||
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
|
|||
* @version 1.0 |
|||
* @date 2023-09-22 |
|||
* |
|||
* @copyright Copyright (c) 2023 |
|||
* |
|||
*/ |
|||
|
|||
#ifndef __USBDEV_TRANSFERS |
|||
#define __USBDEV_TRANSFERS |
|||
|
|||
#include "ch376.h" |
|||
#include "transfers.h" |
|||
#include <stdlib.h> |
|||
|
|||
typedef struct { |
|||
|
|||
uint8_t number : 3; |
|||
uint16_t max_packet_sizex : 10; |
|||
} endpoint; |
|||
|
|||
// 3 bytes
|
|||
#define COMMON_DEVICE_CONFIG \ |
|||
usb_device_type type : 4; \ |
|||
uint8_t address : 4; \ |
|||
uint8_t max_packet_size; \ |
|||
uint8_t interface_number; |
|||
|
|||
typedef struct { |
|||
COMMON_DEVICE_CONFIG |
|||
endpoint_param endpoints[3]; // bulk in/out and interrupt
|
|||
} device_config; |
|||
|
|||
typedef struct { |
|||
COMMON_DEVICE_CONFIG // bytes: 0-2
|
|||
endpoint_param endpoints[3]; // bytes: 3-5, 6-8, 9-11 bulk in/out and interrupt
|
|||
uint32_t current_lba; // bytes 12-15
|
|||
uint8_t drive_index; // byte 16
|
|||
} device_config_storage; |
|||
|
|||
typedef struct { |
|||
COMMON_DEVICE_CONFIG |
|||
} device_config_hub; |
|||
|
|||
typedef struct { |
|||
COMMON_DEVICE_CONFIG |
|||
endpoint_param endpoints[1]; // Isochronous
|
|||
} device_config_keyboard; |
|||
|
|||
extern usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd, uint8_t *const buffer); |
|||
|
|||
extern usb_error usbdev_blk_out_trnsfer(device_config *const device, const uint8_t *const buffer, const uint16_t buffer_size); |
|||
|
|||
extern usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size); |
|||
|
|||
extern usb_error usbdev_dat_in_trnsfer(device_config *const device, |
|||
uint8_t *const buffer, |
|||
const uint16_t buffer_size, |
|||
const usb_endpoint_type endpoint_type); |
|||
|
|||
extern usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) |
|||
__sdcccall(1); |
|||
|
|||
#endif |
|||
@ -0,0 +1,221 @@ |
|||
#include "enumerate.h" |
|||
#include "enumerate_hub.h" |
|||
#include "enumerate_storage.h" |
|||
#include "protocol.h" |
|||
#include "work-area.h" |
|||
#include <string.h> |
|||
|
|||
#include "print.h" |
|||
|
|||
usb_error op_id_class_drv(_working *const working) __sdcccall(1); |
|||
usb_error op_parse_endpoint(_working *const working) __sdcccall(1); |
|||
|
|||
void parse_endpoint_keyboard(device_config_keyboard *const keyboard_config, const endpoint_descriptor const *pEndpoint) |
|||
__sdcccall(1) { |
|||
endpoint_param *const ep = &keyboard_config->endpoints[0]; |
|||
ep->number = pEndpoint->bEndpointAddress; |
|||
ep->toggle = 0; |
|||
ep->max_packet_sizex = calc_max_packet_sizex(pEndpoint->wMaxPacketSize); |
|||
} |
|||
|
|||
usb_device_type identify_class_driver(_working *const working) { |
|||
const interface_descriptor *const p = (const interface_descriptor *)working->ptr; |
|||
if (p->bInterfaceClass == 2) |
|||
return USB_IS_CDC; |
|||
|
|||
if (p->bInterfaceClass == 8 && (p->bInterfaceSubClass == 6 || p->bInterfaceSubClass == 5) && p->bInterfaceProtocol == 80) |
|||
return USB_IS_MASS_STORAGE; |
|||
|
|||
if (p->bInterfaceClass == 8 && p->bInterfaceSubClass == 4 && p->bInterfaceProtocol == 0) |
|||
return USB_IS_FLOPPY; |
|||
|
|||
if (p->bInterfaceClass == 9 && p->bInterfaceSubClass == 0 && p->bInterfaceProtocol == 0) |
|||
return USB_IS_HUB; |
|||
|
|||
if (p->bInterfaceClass == 3) |
|||
return USB_IS_KEYBOARD; |
|||
|
|||
return USB_IS_UNKNOWN; |
|||
} |
|||
|
|||
usb_error op_interface_next(_working *const working) __z88dk_fastcall { |
|||
if (--working->interface_count == 0) |
|||
return USB_ERR_OK; |
|||
|
|||
return op_id_class_drv(working); |
|||
} |
|||
|
|||
usb_error op_endpoint_next(_working *const working) __sdcccall(1) { |
|||
if (--working->endpoint_count > 0) { |
|||
working->ptr += ((endpoint_descriptor *)working->ptr)->bLength; |
|||
return op_parse_endpoint(working); |
|||
} |
|||
|
|||
return op_interface_next(working); |
|||
} |
|||
|
|||
usb_error op_parse_endpoint(_working *const working) __sdcccall(1) { |
|||
const endpoint_descriptor *endpoint = (endpoint_descriptor *)working->ptr; |
|||
device_config *const device = working->p_current_device; |
|||
|
|||
switch (working->usb_device) { |
|||
case USB_IS_FLOPPY: |
|||
case USB_IS_MASS_STORAGE: { |
|||
parse_endpoints(device, endpoint); |
|||
break; |
|||
} |
|||
|
|||
case USB_IS_KEYBOARD: { |
|||
parse_endpoint_keyboard((device_config_keyboard *)device, endpoint); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return op_endpoint_next(working); |
|||
} |
|||
|
|||
usb_error |
|||
configure_device(const _working *const working, const interface_descriptor *const interface, device_config *const dev_cfg) { |
|||
dev_cfg->interface_number = interface->bInterfaceNumber; |
|||
dev_cfg->max_packet_size = working->desc.bMaxPacketSize0; |
|||
dev_cfg->address = working->current_device_address; |
|||
dev_cfg->type = working->usb_device; |
|||
|
|||
return usbtrn_set_configuration(dev_cfg->address, dev_cfg->max_packet_size, working->config.desc.bConfigurationvalue); |
|||
} |
|||
|
|||
usb_error op_capture_hub_driver_interface(_working *const working) __sdcccall(1) { |
|||
const interface_descriptor *const interface = (interface_descriptor *)working->ptr; |
|||
|
|||
usb_error result; |
|||
device_config_hub hub_config; |
|||
working->hub_config = &hub_config; |
|||
|
|||
hub_config.type = USB_IS_HUB; |
|||
CHECK(configure_device(working, interface, (device_config *const)&hub_config)); |
|||
RETURN_CHECK(configure_usb_hub(working)); |
|||
} |
|||
|
|||
usb_error op_cap_drv_intf(_working *const working) __z88dk_fastcall { |
|||
usb_error result; |
|||
_usb_state *const work_area = get_usb_work_area(); |
|||
const interface_descriptor *const interface = (interface_descriptor *)working->ptr; |
|||
|
|||
working->ptr += interface->bLength; |
|||
working->endpoint_count = interface->bNumEndpoints; |
|||
working->p_current_device = NULL; |
|||
|
|||
switch (working->usb_device) { |
|||
case USB_IS_HUB: { |
|||
CHECK(op_capture_hub_driver_interface(working)) |
|||
break; |
|||
} |
|||
|
|||
case USB_IS_UNKNOWN: { |
|||
device_config unkown_dev_cfg; |
|||
memset(&unkown_dev_cfg, 0, sizeof(device_config)); |
|||
working->p_current_device = &unkown_dev_cfg; |
|||
CHECK(configure_device(working, interface, &unkown_dev_cfg)); |
|||
break; |
|||
} |
|||
|
|||
default: { |
|||
device_config *dev_cfg = find_first_free(); |
|||
if (dev_cfg == NULL) |
|||
return USB_ERR_OUT_OF_MEMORY; |
|||
working->p_current_device = dev_cfg; |
|||
CHECK(configure_device(working, interface, dev_cfg)); |
|||
break; |
|||
} |
|||
} |
|||
|
|||
CHECK(op_parse_endpoint(working)); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
usb_error op_id_class_drv(_working *const working) __sdcccall(1) { |
|||
usb_error result; |
|||
const interface_descriptor *const ptr = (const interface_descriptor *)working->ptr; |
|||
|
|||
working->usb_device = ptr->bLength > 5 ? identify_class_driver(working) : 0; |
|||
|
|||
CHECK(op_cap_drv_intf(working)); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
usb_error op_get_cfg_desc(_working *const working) __sdcccall(1) { |
|||
usb_error result; |
|||
|
|||
memset(working->config.buffer, 0, MAX_CONFIG_SIZE); |
|||
|
|||
const uint8_t max_packet_size = working->desc.bMaxPacketSize0; |
|||
|
|||
CHECK(usbtrn_gfull_cfg_desc(working->config_index, working->current_device_address, max_packet_size, MAX_CONFIG_SIZE, |
|||
working->config.buffer)); |
|||
|
|||
working->ptr = (working->config.buffer + sizeof(config_descriptor)); |
|||
working->interface_count = working->config.desc.bNumInterfaces; |
|||
|
|||
CHECK(op_id_class_drv(working)); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
usb_error read_all_configs(enumeration_state *const state) { |
|||
uint8_t result; |
|||
_usb_state *const work_area = get_usb_work_area(); |
|||
|
|||
_working working; |
|||
memset(&working, 0, sizeof(_working)); |
|||
working.state = state; |
|||
|
|||
CHECK(usbtrn_get_descriptor(&working.desc)); |
|||
|
|||
state->next_device_address++; |
|||
working.current_device_address = state->next_device_address; |
|||
CHECK(usbtrn_set_address(working.current_device_address)); |
|||
|
|||
for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) { |
|||
working.config_index = config_index; |
|||
|
|||
CHECK(op_get_cfg_desc(&working)); |
|||
} |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
usb_error enumerate_all_devices(void) { |
|||
_usb_state *const work_area = get_usb_work_area(); |
|||
enumeration_state state; |
|||
memset(&state, 0, sizeof(enumeration_state)); |
|||
state.next_device_address = 0; |
|||
|
|||
usb_error result = read_all_configs(&state); |
|||
|
|||
work_area->count_of_detected_usb_devices = state.next_device_address; |
|||
|
|||
CHECK(result); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
/*
|
|||
enumerate_all_devices |
|||
-> read_all_configs |
|||
-> parse_config |
|||
-> op_get_cfg_desc |
|||
-> op_id_class_drv |
|||
-> op_cap_drv_intf (increment index) |
|||
-> op_parse_endpoint |
|||
-> parse_endpoints |
|||
-> parse_endpoint_hub |
|||
-> op_endpoint_next |
|||
-> op_parse_endpoint -^ (install driver endpoint) |
|||
-> op_interface_next |
|||
-> return |
|||
-> op_id_class_drv -^ |
|||
|
|||
|
|||
*/ |
|||
@ -0,0 +1,38 @@ |
|||
#ifndef __USB_ENUMERATE |
|||
#define __USB_ENUMERATE |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include "usb_state.h" |
|||
|
|||
#define MAX_CONFIG_SIZE 140 |
|||
|
|||
typedef struct { |
|||
uint8_t next_device_address; |
|||
} enumeration_state; |
|||
|
|||
typedef struct __working { |
|||
enumeration_state *state; |
|||
|
|||
usb_device_type usb_device; |
|||
device_descriptor desc; |
|||
uint8_t config_index; |
|||
uint8_t interface_count; |
|||
uint8_t endpoint_count; |
|||
uint8_t current_device_address; |
|||
device_config_hub *hub_config; |
|||
|
|||
uint8_t *ptr; |
|||
device_config *p_current_device; |
|||
|
|||
union { |
|||
uint8_t buffer[MAX_CONFIG_SIZE]; |
|||
config_descriptor desc; |
|||
} config; |
|||
|
|||
} _working; |
|||
|
|||
extern usb_error read_all_configs(enumeration_state *const state); |
|||
extern usb_error enumerate_all_devices(void); |
|||
|
|||
#endif |
|||
@ -0,0 +1,80 @@ |
|||
#include "enumerate_hub.h" |
|||
#include "class_hub.h" |
|||
#include "delay.h" |
|||
#include "protocol.h" |
|||
#include "work-area.h" |
|||
#include <string.h> |
|||
|
|||
const setup_packet cmd_set_feature = {RT_HOST_TO_DEVICE | RT_CLASS | RT_OTHER, SET_FEATURE, {FEAT_PORT_POWER, 0}, {1, 0}, 0}; |
|||
const setup_packet cmd_clear_feature = {RT_HOST_TO_DEVICE | RT_CLASS | RT_OTHER, CLEAR_FEATURE, {FEAT_PORT_POWER, 0}, {1, 0}, 0}; |
|||
const setup_packet cmd_get_status_port = { |
|||
RT_DEVICE_TO_HOST | RT_CLASS | RT_OTHER, GET_STATUS, {0, 0}, {1, 0}, sizeof(hub_port_status)}; |
|||
|
|||
usb_error hub_set_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) { |
|||
setup_packet set_feature; |
|||
set_feature = cmd_set_feature; |
|||
|
|||
set_feature.bValue[0] = feature; |
|||
set_feature.bIndex[0] = index; |
|||
return usb_control_transfer(&set_feature, 0, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
|
|||
usb_error hub_clear_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) { |
|||
setup_packet clear_feature; |
|||
clear_feature = cmd_clear_feature; |
|||
|
|||
clear_feature.bValue[0] = feature; |
|||
clear_feature.bIndex[0] = index; |
|||
return usb_control_transfer(&clear_feature, 0, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
|
|||
usb_error hub_get_status_port(const device_config_hub *const hub_config, const uint8_t index, hub_port_status *const port_status) { |
|||
setup_packet get_status_port; |
|||
get_status_port = cmd_get_status_port; |
|||
|
|||
get_status_port.bIndex[0] = index; |
|||
return usb_control_transfer(&get_status_port, port_status, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
|
|||
usb_error configure_usb_hub(_working *const working) __z88dk_fastcall { |
|||
_usb_state *const work_area = get_usb_work_area(); |
|||
|
|||
usb_error result; |
|||
hub_descriptor hub_description; |
|||
hub_port_status port_status; |
|||
const device_config_hub *const hub_config = working->hub_config; |
|||
|
|||
CHECK(hub_get_descriptor(hub_config, &hub_description)); |
|||
|
|||
uint8_t i = hub_description.bNbrPorts; |
|||
do { |
|||
CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
|
|||
CHECK(hub_set_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
|
|||
hub_clear_feature(hub_config, FEAT_PORT_RESET, i); |
|||
|
|||
CHECK(hub_set_feature(hub_config, FEAT_PORT_RESET, i)); |
|||
|
|||
CHECK(hub_get_status_port(hub_config, i, &port_status)); |
|||
|
|||
if (port_status.wPortStatus.port_connection) { |
|||
CHECK(hub_clear_feature(hub_config, HUB_FEATURE_PORT_CONNECTION_CHANGE, i)); |
|||
|
|||
CHECK(hub_clear_feature(hub_config, FEAT_PORT_ENABLE_CHANGE, i)); |
|||
|
|||
CHECK(hub_clear_feature(hub_config, FEAT_PORT_RESET_CHANGE, i)); |
|||
delay_short(); |
|||
|
|||
CHECK(hub_get_status_port(hub_config, i, &port_status)); |
|||
delay_short(); |
|||
|
|||
CHECK(read_all_configs(working->state)); |
|||
|
|||
} else { |
|||
CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
} |
|||
} while (--i != 0); |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
#ifndef __USB_ENUMERATE_HUB |
|||
#define __USB_ENUMERATE_HUB |
|||
|
|||
#include "enumerate.h" |
|||
#include "protocol.h" |
|||
#include "usb_state.h" |
|||
|
|||
extern usb_error configure_usb_hub(_working *const working) __z88dk_fastcall; |
|||
|
|||
#endif |
|||
@ -0,0 +1,27 @@ |
|||
#include "enumerate_storage.h" |
|||
#include "protocol.h" |
|||
#include <string.h> |
|||
|
|||
void parse_endpoints(device_config *const storage_dev, const endpoint_descriptor const *pEndpoint) { |
|||
|
|||
if (!(pEndpoint->bmAttributes & 0x02)) |
|||
return; |
|||
|
|||
const uint8_t x = calc_max_packet_sizex(pEndpoint->wMaxPacketSize); |
|||
endpoint_param *const eps = storage_dev->endpoints; |
|||
endpoint_param *ep; |
|||
|
|||
if (pEndpoint->bmAttributes & 0x01) { // 3 -> Interrupt
|
|||
if (!(pEndpoint->bEndpointAddress & 0x80)) |
|||
return; |
|||
|
|||
ep = &eps[ENDPOINT_INTERRUPT_IN]; |
|||
|
|||
} else { |
|||
ep = (pEndpoint->bEndpointAddress & 0x80) ? &eps[ENDPOINT_BULK_IN] : &eps[ENDPOINT_BULK_OUT]; |
|||
} |
|||
|
|||
ep->number = pEndpoint->bEndpointAddress & 0x07; |
|||
ep->toggle = 0; |
|||
ep->max_packet_sizex = x; |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
#ifndef __USB_ENUMERATE_STORAGE |
|||
#define __USB_ENUMERATE_STORAGE |
|||
|
|||
#include "protocol.h" |
|||
|
|||
extern void parse_endpoints(device_config *const storage_dev, const endpoint_descriptor const *pEndpoint); |
|||
|
|||
#endif |
|||
@ -0,0 +1,6 @@ |
|||
#ifndef _HBIOS_H_ |
|||
#define _HBIOS_H_ |
|||
|
|||
extern void dio_add_entry(const uint16_t fnc_table[], const device_config_storage *const storage_device) __sdcccall(1); |
|||
|
|||
#endif |
|||
@ -0,0 +1,9 @@ |
|||
#include "print.h" |
|||
|
|||
void print_device_mounted(const char *const description, const uint8_t count) { |
|||
print_string("\r\n $"); |
|||
print_uint16(count); |
|||
print_string(description); |
|||
if (count > 1) |
|||
print_string("S$"); |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
#ifndef __XPRINT |
|||
#define __XPRINT |
|||
|
|||
#include <stdlib.h> |
|||
|
|||
extern void print_hex(const char c) __z88dk_fastcall; |
|||
extern void print_string(const char *p) __z88dk_fastcall; |
|||
extern void print_uint16(const uint16_t n) __z88dk_fastcall; |
|||
extern void print_device_mounted(const char *const description, const uint8_t count); |
|||
|
|||
#endif |
|||
@ -0,0 +1,152 @@ |
|||
/**
|
|||
* @file protocol.c |
|||
* @author Dean Netherton |
|||
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip |
|||
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
|
|||
* @version 1.0 |
|||
* @date 2023-09-22 |
|||
* |
|||
* @copyright Copyright (c) 2023 |
|||
* |
|||
*/ |
|||
|
|||
#include "protocol.h" |
|||
#include "ch376.h" |
|||
#include "delay.h" |
|||
#include <stdlib.h> |
|||
|
|||
#include "print.h" |
|||
|
|||
const setup_packet cmd_get_device_descriptor = {0x80, 6, {0, 1}, {0, 0}, 8}; |
|||
|
|||
/**
|
|||
* @brief Issue GET_DESCRIPTOR request to retrieve the device descriptor for usb device at address 0 |
|||
* |
|||
* @param buffer the buffer to store the device descriptor in |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbtrn_get_descriptor(device_descriptor *const buffer) { |
|||
usb_error result; |
|||
setup_packet cmd; |
|||
cmd = cmd_get_device_descriptor; |
|||
cmd.wLength = 8; |
|||
|
|||
result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8); |
|||
|
|||
CHECK(result); |
|||
|
|||
cmd = cmd_get_device_descriptor; |
|||
cmd.wLength = 18; |
|||
result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Issue GET_DESCRIPTOR request to retrieve the device descriptor for usb device at the specified address |
|||
* |
|||
* @param buffer the buffer to store the device descriptor in |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address) { |
|||
usb_error result; |
|||
setup_packet cmd; |
|||
cmd = cmd_get_device_descriptor; |
|||
cmd.wLength = 8; |
|||
|
|||
result = usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, 8); |
|||
|
|||
CHECK(result); |
|||
|
|||
cmd = cmd_get_device_descriptor; |
|||
cmd.wLength = 18; |
|||
RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, buffer->bMaxPacketSize0)); |
|||
} |
|||
|
|||
const setup_packet cmd_set_device_address = {0x00, 5, {0, 0}, {0, 0}, 0}; |
|||
|
|||
/**
|
|||
* @brief configure device at address 0 to be assigned a new device address |
|||
* |
|||
* @param device_address the new device address |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall { |
|||
setup_packet cmd; |
|||
cmd = cmd_set_device_address; |
|||
cmd.bValue[0] = device_address; |
|||
|
|||
return usb_control_transfer(&cmd, 0, 0, 0); |
|||
} |
|||
|
|||
const setup_packet cmd_set_configuration = {0x00, 9, {0, 0}, {0, 0}, 0}; |
|||
|
|||
/**
|
|||
* @brief configure device at address 0 to be assigned a new configuration |
|||
* |
|||
* @param config the device to be configured |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbtrn_set_configuration(const uint8_t device_address, const uint8_t max_packet_size, const uint8_t configuration) { |
|||
setup_packet cmd; |
|||
cmd = cmd_set_configuration; |
|||
cmd.bValue[0] = configuration; |
|||
|
|||
return usb_control_transfer(&cmd, 0, device_address, max_packet_size); |
|||
} |
|||
|
|||
const setup_packet cmd_get_config_descriptor = {0x80, 6, {0, 2}, {0, 0}, 0}; |
|||
|
|||
/**
|
|||
* @brief request the config descriptor for the specific config index of the specified device |
|||
* |
|||
* @param buffer the buffer to store the config descriptor in |
|||
* @param config_index the index of the config descriptor to retrieve |
|||
* @param buffer_size the size of the buffer |
|||
* @param device_address the usb address of the device |
|||
* @param max_packet_size the max packet size for control transfers (endpoint 0) |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer, |
|||
const uint8_t config_index, |
|||
const uint8_t buffer_size, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size) { |
|||
setup_packet cmd; |
|||
cmd = cmd_get_config_descriptor; |
|||
cmd.bValue[0] = config_index; |
|||
cmd.wLength = (uint16_t)buffer_size; |
|||
|
|||
RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, max_packet_size)); |
|||
} |
|||
|
|||
usb_error usbtrn_gfull_cfg_desc(const uint8_t config_index, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size, |
|||
const uint8_t max_buffer_size, |
|||
uint8_t *const buffer) { |
|||
usb_error result; |
|||
|
|||
CHECK(usbtrn_get_config_descriptor((config_descriptor *)buffer, config_index, sizeof(config_descriptor), device_address, |
|||
max_packet_size)); |
|||
|
|||
uint8_t max_length = ((config_descriptor *)buffer)->wTotalLength; |
|||
if (max_length > max_buffer_size) |
|||
max_length = max_buffer_size; |
|||
|
|||
CHECK(usbtrn_get_config_descriptor((config_descriptor *)buffer, config_index, max_length, device_address, max_packet_size)); |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
const setup_packet usb_cmd_clear_endpoint_halt = {2, 1, {0, 0}, {255, 0}, 0}; // ;byte 4 is the endpoint to be cleared
|
|||
|
|||
usb_error usbtrn_clear_endpoint_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size) { |
|||
setup_packet cmd; |
|||
cmd = usb_cmd_clear_endpoint_halt; |
|||
cmd.bIndex[0] = endpoint_number; |
|||
|
|||
usb_error result = usb_control_transfer(&cmd, (uint8_t *)0, device_address, max_packet_size); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
@ -0,0 +1,82 @@ |
|||
#ifndef __HW |
|||
#define __HW |
|||
|
|||
#include "ch376.h" |
|||
#include "dev_transfers.h" |
|||
#include "transfers.h" |
|||
#include <stdlib.h> |
|||
|
|||
typedef struct _device_descriptor { |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint16_t bcdUSB; |
|||
uint8_t bDeviceClass; |
|||
uint8_t bDeviceSubClass; |
|||
uint8_t bDeviceProtocol; |
|||
uint8_t bMaxPacketSize0; |
|||
uint16_t idVendor; |
|||
uint16_t idProduct; |
|||
uint16_t bcdDevice; |
|||
uint8_t iManufacturer; |
|||
uint8_t iProduct; |
|||
uint8_t iSerialNumber; |
|||
uint8_t bNumConfigurations; |
|||
} device_descriptor; |
|||
|
|||
typedef struct _config_descriptor { |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint16_t wTotalLength; |
|||
uint8_t bNumInterfaces; |
|||
uint8_t bConfigurationvalue; |
|||
uint8_t iConfiguration; |
|||
uint8_t bmAttributes; |
|||
uint8_t bMaxPower; |
|||
} config_descriptor; |
|||
|
|||
typedef struct _interface_descriptor { |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint8_t bInterfaceNumber; |
|||
uint8_t bAlternateSetting; |
|||
uint8_t bNumEndpoints; |
|||
uint8_t bInterfaceClass; |
|||
uint8_t bInterfaceSubClass; |
|||
uint8_t bInterfaceProtocol; |
|||
uint8_t iInterface; |
|||
} interface_descriptor, *p_interface_descriptor; |
|||
|
|||
typedef struct _endpoint_descriptor { |
|||
uint8_t bLength; |
|||
uint8_t bDescriptorType; |
|||
uint8_t bEndpointAddress; |
|||
uint8_t bmAttributes; |
|||
uint16_t wMaxPacketSize; |
|||
uint8_t bInterval; |
|||
} endpoint_descriptor; |
|||
|
|||
extern usb_error usbtrn_get_descriptor(device_descriptor *const buffer); |
|||
extern usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address); |
|||
|
|||
extern usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer, |
|||
const uint8_t config_index, |
|||
const uint8_t buffer_size, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size); |
|||
|
|||
extern usb_error usbtrn_gfull_cfg_desc(const uint8_t config_index, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size, |
|||
const uint8_t max_buffer_size, |
|||
uint8_t *const buffer); |
|||
|
|||
extern usb_error usbtrn_set_configuration(const uint8_t device_address, const uint8_t max_packet_size, const uint8_t configuration); |
|||
|
|||
extern usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall; |
|||
|
|||
extern usb_error |
|||
usbtrn_clear_endpoint_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size); |
|||
|
|||
// extern usb_error usb_clear_endpoint_halt(device_config *const storage_device, const usb_endpoint_type endpoint_type);
|
|||
|
|||
#endif |
|||
@ -0,0 +1,172 @@ |
|||
/**
|
|||
* @file transfers.c |
|||
* @author Dean Netherton |
|||
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip |
|||
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
|
|||
* @version 1.0 |
|||
* @date 2023-09-22 |
|||
* |
|||
* @copyright Copyright (c) 2023 |
|||
* |
|||
*/ |
|||
|
|||
#include "transfers.h" |
|||
#include "ch376.h" |
|||
#include "delay.h" |
|||
#include "z80.h" |
|||
#include <stdlib.h> |
|||
|
|||
#define LOWER_SAFE_RAM_ADDRESS 0x8000 |
|||
|
|||
usb_error usb_ctrl_trnsfer_ext(const setup_packet *const cmd_packet, |
|||
void *const buffer, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size) { |
|||
if ((uint16_t)cmd_packet < LOWER_SAFE_RAM_ADDRESS) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
return usb_control_transfer(cmd_packet, buffer, device_address, max_packet_size); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Perform a USB control transfer (in or out) |
|||
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
|
|||
* |
|||
* @param cmd_packet Pointer to the setup packet - top bit of bmRequestType indicate data direction |
|||
* @param buffer Pointer of data to send or receive into |
|||
* @param device_address usb device address |
|||
* @param max_packet_size Maximum packet size for endpoint |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usb_control_transfer(const setup_packet *const cmd_packet, |
|||
void *const buffer, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size) { |
|||
usb_error result; |
|||
endpoint_param endpoint = {1, 0, max_packet_size}; |
|||
|
|||
const uint8_t transferIn = (cmd_packet->bmRequestType & 0x80); |
|||
|
|||
if (transferIn && buffer == 0) |
|||
return USB_ERR_OTHER; |
|||
|
|||
ch_set_usb_address(device_address); |
|||
|
|||
ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet)); |
|||
ch_issue_token_setup(); |
|||
CHECK(ch_short_wait_int_and_get_status()) |
|||
|
|||
const uint16_t length = cmd_packet->wLength; |
|||
|
|||
result = length != 0 |
|||
? (transferIn ? ch_data_in_transfer(buffer, length, &endpoint) : ch_data_out_transfer(buffer, length, &endpoint)) |
|||
: USB_ERR_OK; |
|||
|
|||
CHECK(result) |
|||
|
|||
if (transferIn) { |
|||
ch_command(CH_CMD_WR_HOST_DATA); |
|||
CH376_DATA_PORT = 0; |
|||
delay(); |
|||
ch_issue_token_out_ep0(); |
|||
result = ch_long_wait_int_and_get_status(); /* sometimes we get STALL here - seems to be ok to ignore */ |
|||
|
|||
if (result == USB_ERR_OK || result == USB_ERR_STALL) |
|||
return USB_ERR_OK; |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
ch_issue_token_in_ep0(); |
|||
result = ch_long_wait_int_and_get_status(); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error |
|||
usb_dat_in_trnsfer_ext(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
return usb_data_in_transfer(buffer, buffer_size, device_address, endpoint); |
|||
} |
|||
|
|||
usb_error |
|||
usb_dat_in_trns_n_ext(uint8_t *buffer, uint16_t *buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
if (buffer != 0 && ((uint16_t)buffer & 0xC000) == 0) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
if (((uint16_t)endpoint & 0xC000) == 0) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
if (((uint16_t)buffer_size & 0xC000) == 0) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
return usb_data_in_transfer_n(buffer, buffer_size, device_address, endpoint); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Perform a USB data in on the specififed endpoint |
|||
* |
|||
* @param buffer the buffer to receive the data |
|||
* @param buffer_size the maximum size of data to be received |
|||
* @param device_address the usb address of the device |
|||
* @param endpoint the usb endpoint to receive from (toggle of endpoint is updated) |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error |
|||
usb_data_in_transfer(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
ch_set_usb_address(device_address); |
|||
|
|||
return ch_data_in_transfer(buffer, buffer_size, endpoint); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Perform a USB data in on the specififed endpoint |
|||
* |
|||
* @param buffer the buffer to receive the data - must be 62 bytes |
|||
* @param buffer_size on exit the actual size of data received |
|||
* @param device_address the usb address of the device |
|||
* @param endpoint the usb endpoint to receive from (toggle of endpoint is updated) |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error |
|||
usb_data_in_transfer_n(uint8_t *buffer, uint8_t *const buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
ch_set_usb_address(device_address); |
|||
|
|||
return ch_data_in_transfer_n(buffer, buffer_size, endpoint); |
|||
} |
|||
|
|||
usb_error |
|||
usb_dat_out_trns_ext(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
|
|||
if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS) |
|||
return USB_BAD_ADDRESS; |
|||
|
|||
return usb_data_out_transfer(buffer, buffer_size, device_address, endpoint); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Perform a USB data out on the specififed endpoint |
|||
* |
|||
* @param buffer the buffer to send the data from |
|||
* @param buffer_size the maximum size of data to be sent |
|||
* @param device_address the usb address of the device |
|||
* @param endpoint the usb endpoint to send to (toggle of endpoint is updated) |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error |
|||
usb_data_out_transfer(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) { |
|||
ch_set_usb_address(device_address); |
|||
|
|||
return ch_data_out_transfer(buffer, buffer_size, endpoint); |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
/**
|
|||
* @file transfer.h |
|||
* @author Dean Netherton |
|||
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip |
|||
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
|
|||
* @version 1.0 |
|||
* @date 2023-09-22 |
|||
* |
|||
* @copyright Copyright (c) 2023 |
|||
* |
|||
*/ |
|||
|
|||
#ifndef __USB_TRANSFERS |
|||
#define __USB_TRANSFERS |
|||
|
|||
#include "ch376.h" |
|||
#include <stdlib.h> |
|||
|
|||
#define GET_STATUS 0 |
|||
#define CLEAR_FEATURE 1 |
|||
#define SET_FEATURE 3 |
|||
#define GET_DESCRIPTOR 6 |
|||
#define SET_DESCRIPTOR 7 |
|||
#define CLEAR_TT_BUFFER 8 |
|||
#define RESET_TT 9 |
|||
#define GET_TT_STATE 10 |
|||
#define CSTOP_TT 11 |
|||
|
|||
#define FEAT_PORT_POWER 8 |
|||
#define FEAT_PORT_RESET 4 |
|||
#define HUB_FEATURE_PORT_CONNECTION_CHANGE 16 |
|||
#define FEAT_PORT_ENABLE_CHANGE 17 |
|||
#define FEAT_PORT_RESET_CHANGE 20 |
|||
|
|||
// HUB_FEATURE_PORT_CONNECTION = 0,
|
|||
// HUB_FEATURE_PORT_ENABLE = 1,
|
|||
// HUB_FEATURE_PORT_SUSPEND = 2,
|
|||
// HUB_FEATURE_PORT_OVER_CURRENT = 3,
|
|||
// HUB_FEATURE_PORT_RESET = 4,
|
|||
|
|||
// HUB_FEATURE_PORT_POWER = 8,
|
|||
// HUB_FEATURE_PORT_LOW_SPEED = 9,
|
|||
|
|||
// HUB_FEATURE_PORT_CONNECTION_CHANGE = 16,
|
|||
// HUB_FEATURE_PORT_ENABLE_CHANGE = 17,
|
|||
// HUB_FEATURE_PORT_SUSPEND_CHANGE = 18,
|
|||
// HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19,
|
|||
// HUB_FEATURE_PORT_RESET_CHANGE = 20,
|
|||
// HUB_FEATURE_PORT_TEST = 21,
|
|||
// HUB_FEATURE_PORT_INDICATOR = 22
|
|||
|
|||
#define RT_HOST_TO_DEVICE 0b00000000 |
|||
#define RT_DEVICE_TO_HOST 0b10000000 |
|||
#define RT_STANDARD 0b00000000 |
|||
#define RT_CLASS 0b00100000 |
|||
#define RT_VENDOR 0b01000000 |
|||
#define RT_DEVICE 0b00000000 |
|||
#define RT_INTERFACE 0b00000001 |
|||
#define RT_ENDPOINT 0b00000010 |
|||
#define RT_OTHER 0b00000011 |
|||
|
|||
typedef struct _setup_packet { |
|||
uint8_t bmRequestType; |
|||
uint8_t bRequest; |
|||
uint8_t bValue[2]; |
|||
uint8_t bIndex[2]; |
|||
uint16_t wLength; |
|||
} setup_packet; |
|||
|
|||
enum libusb_request_type { |
|||
LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), |
|||
LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), |
|||
LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), |
|||
LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5), |
|||
}; |
|||
|
|||
enum libusb_request_recipient { |
|||
LIBUSB_RECIPIENT_DEVICE = 0x00, |
|||
LIBUSB_RECIPIENT_INTERFACE = 0x01, |
|||
LIBUSB_RECIPIENT_ENDPOINT = 0x02, |
|||
LIBUSB_RECIPIENT_OTHER = 0x03, |
|||
}; |
|||
|
|||
enum libusb_endpoint_direction { |
|||
LIBUSB_ENDPOINT_IN = 0x80, |
|||
LIBUSB_ENDPOINT_OUT = 0x00, |
|||
}; |
|||
|
|||
extern usb_error usb_control_transfer(const setup_packet *const cmd_packet, |
|||
void *const buffer, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size); |
|||
|
|||
extern usb_error |
|||
usb_data_in_transfer(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint); |
|||
|
|||
extern usb_error |
|||
usb_data_in_transfer_n(uint8_t *buffer, uint8_t *const buffer_size, const uint8_t device_address, endpoint_param *const endpoint); |
|||
|
|||
extern usb_error |
|||
usb_data_out_transfer(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint); |
|||
|
|||
#endif |
|||
@ -0,0 +1,9 @@ |
|||
#include "usb-base-drv.h" |
|||
|
|||
/* The total number of mounted storage devices (scsi and ufi) */ |
|||
uint8_t storage_count = 0; |
|||
|
|||
uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1) { |
|||
storage_device->current_lba = lba; |
|||
return 0; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
#ifndef __USB_BASE_DRV |
|||
#define __USB_BASE_DRV |
|||
|
|||
#include <dev_transfers.h> |
|||
#include <stdint.h> |
|||
|
|||
extern uint8_t storage_count; |
|||
|
|||
extern uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1); |
|||
|
|||
#endif |
|||
@ -0,0 +1,56 @@ |
|||
#include "ch376.h" |
|||
#include "enumerate.h" |
|||
#include "print.h" |
|||
#include "work-area.h" |
|||
#include "z80.h" |
|||
#include <string.h> |
|||
|
|||
static usb_error usb_host_bus_reset(void) { |
|||
ch_cmd_set_usb_mode(CH_MODE_HOST); |
|||
delay_20ms(); |
|||
|
|||
ch_cmd_set_usb_mode(CH_MODE_HOST_RESET); |
|||
delay_20ms(); |
|||
|
|||
ch_cmd_set_usb_mode(CH_MODE_HOST); |
|||
delay_20ms(); |
|||
|
|||
ch_configure_nak_retry_3s(); |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
#define ERASE_LINE "\x1B\x6C\r$" |
|||
|
|||
void chnative_init(void) { |
|||
memset(get_usb_work_area(), 0, sizeof(_usb_state)); |
|||
|
|||
ch_cmd_reset_all(); |
|||
|
|||
delay_medium(); |
|||
|
|||
if (!ch_probe()) { |
|||
print_string("\r\nCH376: NOT PRESENT$"); |
|||
return; |
|||
} |
|||
|
|||
print_string("\r\nCH376: PRESENT (VER $"); |
|||
print_hex(ch_cmd_get_ic_version()); |
|||
print_string("); $"); |
|||
|
|||
usb_host_bus_reset(); |
|||
|
|||
for (uint8_t i = 0; i < 4; i++) { |
|||
const uint8_t r = ch_very_short_wait_int_and_get_status(); |
|||
|
|||
if (r == USB_INT_CONNECT) { |
|||
print_string("USB: CONNECTED$"); |
|||
|
|||
enumerate_all_devices(); |
|||
|
|||
return; |
|||
} |
|||
} |
|||
|
|||
print_string("USB: DISCONNECTED$"); |
|||
} |
|||
@ -0,0 +1,90 @@ |
|||
#include "usb_state.h" |
|||
#include "work-area.h" |
|||
|
|||
const uint8_t device_config_sizes[_USB_LAST_DEVICE_TYPE] = { |
|||
0, /* USB_NOT_SUPPORTED = 0 */ |
|||
sizeof(device_config_storage), /* USB_IS_FLOPPY = 1 */ |
|||
sizeof(device_config_storage), /* USB_IS_MASS_STORAGE = 2 */ |
|||
sizeof(device_config), /* USB_IS_CDC = 3 */ |
|||
sizeof(device_config_keyboard), /* USB_IS_KEYBOARD = 4 */ |
|||
}; |
|||
|
|||
// always usb work area
|
|||
device_config *find_device_config(const usb_device_type requested_type) { |
|||
_usb_state *const p = get_usb_work_area(); |
|||
|
|||
const device_config *p_config = first_device_config(p); |
|||
while (p_config) { |
|||
const uint8_t type = p_config->type; |
|||
|
|||
if (type == requested_type) |
|||
return (device_config *)p_config; |
|||
|
|||
p_config = next_device_config(p, p_config); |
|||
}; |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
// always search in boot
|
|||
device_config *find_first_free(void) { |
|||
_usb_state *const boot_state = get_usb_work_area(); |
|||
|
|||
uint8_t c = 0; |
|||
device_config *p = first_device_config(boot_state); |
|||
while (p) { |
|||
if (p->type == 0) |
|||
return p; |
|||
|
|||
p = next_device_config(boot_state, p); |
|||
} |
|||
|
|||
return NULL; |
|||
} |
|||
|
|||
device_config *first_device_config(const _usb_state *const p) __sdcccall(1) { return (device_config *)&p->device_configs[0]; } |
|||
|
|||
device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1) { |
|||
if (p->type == 0) |
|||
return NULL; |
|||
|
|||
const uint8_t size = device_config_sizes[p->type]; |
|||
// TODO: bug when size is zero we dont increment the pointer
|
|||
// but if we abort on size 0 - we fail to pick up other devices???
|
|||
// we should not get size of 0 unless the size entry is missing
|
|||
// if (size == 0)
|
|||
// return NULL;
|
|||
|
|||
const uint8_t *_p = (uint8_t *)p; |
|||
device_config *const result = (device_config *)(_p + size); |
|||
|
|||
if (result >= (device_config *)&usb_state->device_configs_end) |
|||
return NULL; |
|||
|
|||
return result; |
|||
} |
|||
|
|||
// always usb work area
|
|||
device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1) { |
|||
const _usb_state *const usb_state = get_usb_work_area(); |
|||
|
|||
uint8_t counter = 1; |
|||
|
|||
for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) { |
|||
if (p->type == USB_IS_FLOPPY) { |
|||
if (counter == device_index) |
|||
return p; |
|||
counter++; |
|||
} |
|||
} |
|||
|
|||
for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) { |
|||
if (p->type == USB_IS_MASS_STORAGE) { |
|||
if (counter == device_index) |
|||
return p; |
|||
counter++; |
|||
} |
|||
} |
|||
|
|||
return NULL; // is not a usb device
|
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
#ifndef __USB_STATE |
|||
#define __USB_STATE |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include <stdlib.h> |
|||
|
|||
#define MAX_NUMBER_OF_DEVICES 6 |
|||
#define DEVICE_CONFIG_STRUCT_SIZE sizeof(device_config_storage) /* Assumes is largest struct */ |
|||
|
|||
typedef struct __usb_state { |
|||
uint8_t active : 1; /* if true, a usb operation/interrupt handler is active, prevent re-entrant */ |
|||
uint8_t reserved : 7; |
|||
uint8_t count_of_detected_usb_devices; |
|||
uint8_t device_configs[DEVICE_CONFIG_STRUCT_SIZE * MAX_NUMBER_OF_DEVICES]; |
|||
|
|||
uint8_t device_configs_end; // always zero to mark end
|
|||
} _usb_state; |
|||
|
|||
extern device_config *find_first_free(void); |
|||
extern device_config *first_device_config(const _usb_state *const p) __sdcccall(1); |
|||
extern device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1); |
|||
extern device_config *find_device_config(const usb_device_type requested_type); |
|||
|
|||
extern device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1); |
|||
|
|||
#endif |
|||
@ -0,0 +1,3 @@ |
|||
#include "usb_state.h" |
|||
|
|||
_usb_state x = {0, 0, 0}; |
|||
@ -0,0 +1,54 @@ |
|||
#ifndef __WORK_AREA |
|||
#define __WORK_AREA |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include "stdlib.h" |
|||
#include "usb_state.h" |
|||
|
|||
#define PRES_CF 1 /* BIT MASK FOR COMPACTFLASH PRESENT */ |
|||
#define PRES_MS 2 /* BIT MASK FOR MSX MUSIC NOR FLASH PRESENT */ |
|||
#define PRES_USB1 4 /* BIT MASK FOR USB1 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_USB2 8 /* BIT MASK FOR USB2 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_USB3 16 /* BIT MASK FOR USB3 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_USB4 32 /* BIT MASK FOR USB4 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_CH376 128 /* BIT MASK FOR CH376 PRESENT AT BOOT UP */ |
|||
|
|||
#define BIT_PRES_CF 0 /* BIT POSTION FOR COMPACTFLASH PRESENT */ |
|||
#define BIT_PRES_MS 1 /* BIT POSTION FOR MSX MUSIC NOR FLASH PRESENT */ |
|||
#define BIT_PRES_USB1 2 /* BIT POSTION FOR USB1 STORAGE PRESENT */ |
|||
#define BIT_PRES_USB2 3 /* BIT POSTION FOR USB2 STORAGE PRESENT */ |
|||
#define BIT_PRES_USB3 4 /* BIT POSTION FOR USB3 STORAGE PRESENT */ |
|||
#define BIT_PRES_USB4 5 /* BIT POSTION FOR USB4 STORAGE PRESENT */ |
|||
#define BIT_PRES_CH376 7 /* BIT POSTION FOR CH376 PRESENT */ |
|||
|
|||
typedef enum { |
|||
DEV_MAP_NONE = 0, |
|||
DEV_MAP_ROM = 1, |
|||
DEV_MAP_CF = 2, |
|||
DEV_MAP_MS = 3, |
|||
DEV_MAP_USB1 = 4, |
|||
DEV_MAP_USB2 = 5, |
|||
DEV_MAP_USB3 = 6, |
|||
DEV_MAP_USB4 = 7 |
|||
} device_map; |
|||
|
|||
typedef struct _work_area { |
|||
uint8_t read_count; /* COUNT OF SECTORS TO BE READ */ |
|||
uint16_t index; /* sector number to be read */ |
|||
uint8_t *dest; /* destination write address */ |
|||
uint8_t read_count_requested; /* number of sectors requested */ |
|||
uint8_t present; /* BIT FIELD FOR DETECTED DEVICES
|
|||
(BIT 0 -> COMPACTFLASH/IDE, BIT 1-> MSX-MUSIC NOR FLASH, BITS 2-5 FOR USB)*/ |
|||
_usb_state ch376; |
|||
} work_area; |
|||
|
|||
// extern work_area *get_work_area(void);
|
|||
|
|||
extern uint8_t get_number_of_usb_drives(void); |
|||
|
|||
extern _usb_state x; |
|||
|
|||
#define get_usb_work_area() (&x) |
|||
|
|||
#endif |
|||
@ -0,0 +1,17 @@ |
|||
#ifndef __Z80_HELPERS |
|||
#define __Z80_HELPERS |
|||
|
|||
#include <stdint.h> |
|||
|
|||
#define EI __asm__("EI"); |
|||
#define DI __asm__("DI"); |
|||
#define HALT __asm__("HALT"); |
|||
|
|||
typedef void (*jump_fn_t)(void) __z88dk_fastcall; |
|||
|
|||
typedef struct { |
|||
uint8_t jump_op_code; // JMP or CALL
|
|||
jump_fn_t address; |
|||
} z80_jump_t; |
|||
|
|||
#endif |
|||
@ -0,0 +1,50 @@ |
|||
#!/bin/bash |
|||
|
|||
# Check if exactly two arguments are provided |
|||
if [ "$#" -ne 2 ]; then |
|||
echo "Usage: $0 <source_file> <destination_file>" |
|||
exit 1 |
|||
fi |
|||
|
|||
source_file="$1" |
|||
destination_file="$2" |
|||
|
|||
rm -f "$destination_file" |
|||
|
|||
# create a unique prefix for all generated labels |
|||
prefix=$(basename "$source_file" | cut -d. -f1 | tr '-' '_') |
|||
|
|||
sed -E \ |
|||
-e "1i\;\r\n; Generated from source-doc/${source_file} -- not to be modify directly\r\n;\r\n; " \ |
|||
-e '/SECTION IGNORE/d' \ |
|||
-e '/\sEXTERN\s/d' \ |
|||
-e '/\sGLOBAL\s/d' \ |
|||
-e '/SECTION .*/d' \ |
|||
-e 's/^IF 0/#IF 0/g' \ |
|||
-e 's/^ENDIF/#ENDIF/g' \ |
|||
-e 's/\s+cp\s+a,\((ix\+[0-9-]+)\)/\tcp\t\(\1\)/g' \ |
|||
-e 's/\s+sub\s+a,\((iy\+[0-9]+)\)/\tsub\t\(\1\)/g' \ |
|||
-e 's/\s+sub\s+a,\((ix\+[0-9]+)\)/\tsub\t\(\1\)/g' \ |
|||
-e 's/\s+sub\s+a,\((ix-[0-9]+)\)/\tsub\t\(\1\)/g' \ |
|||
-e 's/\s+or\s+a,\((ix\+[0-9-]+)\)/\tor\t\(\1\)/g' \ |
|||
-e 's/\s+or\s+a,\((ix\-[0-9-]+)\)/\tor\t\(\1\)/g' \ |
|||
-e 's/\s+or\s+a,\((iy\+[0-9-]+)\)/\tor\t\(\1\)/g' \ |
|||
-e 's/\s+cp\s+a,(0x[0-9A-Fa-f]{2})/\tcp\t\1/g' \ |
|||
-e 's/\s+or\s+a,(0x[0-9A-Fa-f]{2})/\tor\t\1/g' \ |
|||
-e 's/\s+xor\s+a,(0x[0-9A-Fa-f]{2})/\txor\t\1/g' \ |
|||
-e 's/\s+and\s+a,(0x[0-9A-Fa-f]{2})/\tand\t\1/g' \ |
|||
-e 's/\s+sub\s+a,(0x[0-9A-Fa-f]{2})/\tsub\t\1/g' \ |
|||
-e 's/\s+cp\s+a,\s*a/\tcp\ta/g' \ |
|||
-e 's/\s+or\s+a,\s*a/\tor\ta/g' \ |
|||
-e 's/\s+xor\s+a,\s*a/\txor\ta/g' \ |
|||
-e 's/\s+or\s+a,\s*(b|c|d|e|h|l|iyl|iyh|ixl|ixh)/\tor\t\1/g' \ |
|||
-e 's/\s+sub\s+a,\s+(b|c|d|e|h|l|iyl|iyh|ixl|ixh)/\tsub\t\1/g' \ |
|||
-e 's/\b([a-zA-Z0-9_]{31})[a-zA-Z0-9_]+\b/\1/g' \ |
|||
-e 's/;\t+/; /g' \ |
|||
-e 's/defc\s+([a-zA-Z0-9_]+)\s*=\s*(0x[0-9A-Fa-f]+)/\1\t.EQU\t\2/' \ |
|||
-e "s/___str_([0-9]+)/${prefix}_str_\1/g" \ |
|||
"$source_file" > "$destination_file" |
|||
|
|||
|
|||
# -e '/IF 0/d' \ |
|||
# -e '/ENDIF/d' \ |
|||
@ -0,0 +1,106 @@ |
|||
|
|||
./base-drv/dev_transfers.c.s: source-doc/base-drv/dev_transfers.c \ |
|||
source-doc/base-drv/dev_transfers.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/protocol.h |
|||
./base-drv/enumerate.c.s: source-doc/base-drv/enumerate.c \ |
|||
source-doc/base-drv/enumerate.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/usb_state.h \ |
|||
source-doc/base-drv/enumerate_hub.h \ |
|||
source-doc/base-drv/enumerate_storage.h source-doc/base-drv/work-area.h \ |
|||
source-doc/base-drv/print.h |
|||
./base-drv/usb_state.c.s: source-doc/base-drv/usb_state.c \ |
|||
source-doc/base-drv/usb_state.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/work-area.h |
|||
./base-drv/class_hub.c.s: source-doc/base-drv/class_hub.c \ |
|||
source-doc/base-drv/class_hub.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/usb_state.h |
|||
./base-drv/enumerate_storage.c.s: source-doc/base-drv/enumerate_storage.c \ |
|||
source-doc/base-drv/enumerate_storage.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h |
|||
./base-drv/enumerate_hub.c.s: source-doc/base-drv/enumerate_hub.c \ |
|||
source-doc/base-drv/enumerate_hub.h source-doc/base-drv/enumerate.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/dev_transfers.h source-doc/base-drv/transfers.h \ |
|||
source-doc/base-drv/usb_state.h source-doc/base-drv/class_hub.h \ |
|||
source-doc/base-drv/work-area.h |
|||
./base-drv/usb-base-drv.c.s: source-doc/base-drv/usb-base-drv.c \ |
|||
source-doc/base-drv/usb-base-drv.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/transfers.h |
|||
./base-drv/transfers.c.s: source-doc/base-drv/transfers.c \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/z80.h |
|||
./base-drv/print.c.s: source-doc/base-drv/print.c source-doc/base-drv/print.h |
|||
./base-drv/ch376.c.s: source-doc/base-drv/ch376.c source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/print.h |
|||
./base-drv/protocol.c.s: source-doc/base-drv/protocol.c source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/print.h |
|||
./base-drv/work-area.c.s: source-doc/base-drv/work-area.c \ |
|||
source-doc/base-drv/usb_state.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h |
|||
./base-drv/usb-init.c.s: source-doc/base-drv/usb-init.c source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/enumerate.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/dev_transfers.h source-doc/base-drv/transfers.h \ |
|||
source-doc/base-drv/usb_state.h source-doc/base-drv/print.h \ |
|||
source-doc/base-drv/work-area.h source-doc/base-drv/z80.h |
|||
./ufi-drv/ufi-init.c.s: source-doc/ufi-drv/ufi-init.c source-doc/ufi-drv/class_ufi.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/ufi-drv/usb_cbi.h \ |
|||
source-doc/base-drv/dev_transfers.h source-doc/base-drv/usb_state.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/hbios.h \ |
|||
source-doc/base-drv/print.h source-doc/base-drv/usb-base-drv.h \ |
|||
source-doc/base-drv/work-area.h source-doc/base-drv/usb_state.h |
|||
./ufi-drv/usb_cbi.c.s: source-doc/ufi-drv/usb_cbi.c source-doc/ufi-drv/usb_cbi.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/transfers.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h |
|||
./ufi-drv/class_ufi.c.s: source-doc/ufi-drv/class_ufi.c \ |
|||
source-doc/ufi-drv/class_ufi.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/dev_transfers.h source-doc/base-drv/transfers.h \ |
|||
source-doc/ufi-drv/usb_cbi.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/usb_state.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/z80.h |
|||
./scsi-drv/scsi-init.c.s: source-doc/scsi-drv/scsi-init.c \ |
|||
source-doc/scsi-drv/class_scsi.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/ch376.h \ |
|||
source-doc/base-drv/enumerate.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/usb_state.h source-doc/base-drv/hbios.h \ |
|||
source-doc/base-drv/print.h source-doc/base-drv/usb-base-drv.h \ |
|||
source-doc/base-drv/dev_transfers.h source-doc/base-drv/work-area.h \ |
|||
source-doc/base-drv/z80.h |
|||
./scsi-drv/class_scsi.c.s: source-doc/scsi-drv/class_scsi.c \ |
|||
source-doc/scsi-drv/class_scsi.h source-doc/base-drv/protocol.h \ |
|||
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \ |
|||
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \ |
|||
source-doc/base-drv/transfers.h source-doc/base-drv/usb_state.h \ |
|||
source-doc/base-drv/protocol.h source-doc/base-drv/z80.h |
|||
## |
|||
./base-drv.s: base-drv/./dev_transfers.c.s base-drv/./enumerate.c.s base-drv/./usb_state.c.s base-drv/./class_hub.c.s base-drv/./enumerate_storage.c.s base-drv/./enumerate_hub.c.s base-drv/./usb-base-drv.c.s base-drv/./transfers.c.s base-drv/./print.c.s base-drv/./ch376.c.s base-drv/./protocol.c.s base-drv/./work-area.c.s base-drv/./usb-init.c.s |
|||
## |
|||
./scsi-drv.s: scsi-drv/./scsi-init.c.s scsi-drv/./class_scsi.c.s |
|||
## |
|||
./ufi-drv.s: ufi-drv/./ufi-init.c.s ufi-drv/./usb_cbi.c.s ufi-drv/./class_ufi.c.s |
|||
@ -0,0 +1,168 @@ |
|||
#include "class_scsi.h" |
|||
#include <string.h> |
|||
#include <usb_state.h> |
|||
#include <z80.h> |
|||
|
|||
_scsi_command_block_wrapper scsi_command_block_wrapper = {{0x55, 0x53, 0x42, 0x43}, {0, 0}, 0, 0, 0, 0}; |
|||
|
|||
uint16_t next_tag = 0; |
|||
|
|||
_scsi_command_status_wrapper csw = {{{0}}}; |
|||
usb_error do_scsi_cmd(device_config_storage *const dev, |
|||
_scsi_command_block_wrapper *const cbw, |
|||
void *const send_receive_buffer, |
|||
const bool send) { |
|||
|
|||
cbw->dCBWTag[0] = next_tag++; |
|||
|
|||
if (!send) |
|||
cbw->bmCBWFlags = 0x80; |
|||
|
|||
CHECK(usb_data_out_transfer((uint8_t *)cbw, sizeof(_scsi_command_block_wrapper) + 16, dev->address, |
|||
&dev->endpoints[ENDPOINT_BULK_OUT])); |
|||
|
|||
if (cbw->dCBWDataTransferLength != 0) { |
|||
if (!send) { |
|||
CHECK(usb_data_in_transfer(send_receive_buffer, (uint16_t)cbw->dCBWDataTransferLength, dev->address, |
|||
&dev->endpoints[ENDPOINT_BULK_IN])); |
|||
|
|||
} else { |
|||
CHECK(usb_data_out_transfer(send_receive_buffer, (uint16_t)cbw->dCBWDataTransferLength, dev->address, |
|||
&dev->endpoints[ENDPOINT_BULK_OUT])); |
|||
} |
|||
} |
|||
|
|||
CHECK( |
|||
usb_data_in_transfer((uint8_t *)&csw, sizeof(_scsi_command_status_wrapper), dev->address, &dev->endpoints[ENDPOINT_BULK_IN])); |
|||
|
|||
if (csw.bCSWStatus != 0 && csw.dCSWTag[0] != cbw->dCBWTag[0]) |
|||
return USB_ERR_FAIL; |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
_scsi_read_capacity scsi_read_capacity = {0x25, 0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0}}; |
|||
|
|||
usb_error get_scsi_read_capacity(device_config_storage *const dev, scsi_read_capacity_result *cap_result) { |
|||
cbw_scsi_read_capacity cbw_scsi; |
|||
cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
cbw_scsi.read_capacity = scsi_read_capacity; |
|||
|
|||
cbw_scsi.cbw.bCBWLUN = 0; |
|||
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_read_capacity); |
|||
cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_read_capacity_result); |
|||
|
|||
return do_scsi_cmd(dev, &cbw_scsi.cbw, cap_result, false); |
|||
} |
|||
|
|||
_scsi_packet_inquiry scsi_packet_inquiry = {0x12, 0, 0, 0, 0x24, 0, {0, 0, 0, 0, 0, 0}}; |
|||
|
|||
usb_error scsi_inquiry(device_config_storage *const dev, scsi_inquiry_result *inq_result) { |
|||
cbw_scsi_inquiry cbw_scsi; |
|||
cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
cbw_scsi.inquiry = scsi_packet_inquiry; |
|||
|
|||
cbw_scsi.cbw.bCBWLUN = 0; |
|||
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_inquiry); |
|||
cbw_scsi.cbw.dCBWDataTransferLength = 0x24; |
|||
|
|||
return do_scsi_cmd(dev, &cbw_scsi.cbw, inq_result, false); |
|||
} |
|||
|
|||
usb_error scsi_test(device_config_storage *const dev) { |
|||
cbw_scsi_test cbw_scsi; |
|||
cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
memset(&cbw_scsi.test, 0, sizeof(_scsi_packet_test)); |
|||
|
|||
cbw_scsi.cbw.bCBWLUN = 0; |
|||
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_test); |
|||
cbw_scsi.cbw.dCBWDataTransferLength = 0; |
|||
|
|||
return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false); |
|||
} |
|||
|
|||
_scsi_packet_request_sense scsi_packet_request_sense = {0x03, 0, 0, 0, 18, 0, {0, 0, 0, 0, 0, 0}}; |
|||
|
|||
usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result) { |
|||
cbw_scsi_request_sense cbw_scsi; |
|||
cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
cbw_scsi.request_sense = scsi_packet_request_sense; |
|||
|
|||
cbw_scsi.cbw.bCBWLUN = 0; |
|||
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_request_sense); |
|||
cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_sense_result); |
|||
|
|||
return do_scsi_cmd(dev, &cbw_scsi.cbw, sens_result, false); |
|||
} |
|||
|
|||
usb_error scsi_sense_init(device_config_storage *const dev) { |
|||
scsi_sense_result response; |
|||
uint8_t counter = 3; |
|||
|
|||
while ((result = scsi_test(dev)) && --counter > 0) |
|||
scsi_request_sense(dev, &response); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
static cbw_scsi_read_write cbw = {{{0}}}; |
|||
|
|||
usb_error scsi_read(device_config_storage *const dev, uint8_t *const buffer) { |
|||
memset(&cbw, 0, sizeof(cbw_scsi_read_write)); |
|||
cbw.cbw = scsi_command_block_wrapper; |
|||
|
|||
cbw.cbw.bCBWLUN = 0; |
|||
cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write); |
|||
cbw.cbw.dCBWDataTransferLength = 512; |
|||
|
|||
cbw.scsi_cmd.operation_code = 0x28; // read operation
|
|||
cbw.scsi_cmd.transfer_len[1] = 1; |
|||
cbw.scsi_cmd.lba[0] = dev->current_lba >> 24; |
|||
cbw.scsi_cmd.lba[1] = dev->current_lba >> 16; |
|||
cbw.scsi_cmd.lba[2] = dev->current_lba >> 8; |
|||
cbw.scsi_cmd.lba[3] = dev->current_lba; |
|||
|
|||
result = do_scsi_cmd(dev, &cbw.cbw, buffer, false); |
|||
|
|||
if (result == USB_ERR_OK) |
|||
dev->current_lba++; |
|||
return result; |
|||
} |
|||
|
|||
usb_error scsi_write(device_config_storage *const dev, uint8_t *const buffer) { |
|||
memset(&cbw, 0, sizeof(cbw_scsi_read_write)); |
|||
cbw.cbw = scsi_command_block_wrapper; |
|||
|
|||
cbw.cbw.bCBWLUN = 0; |
|||
cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write); |
|||
cbw.cbw.dCBWDataTransferLength = 512; |
|||
|
|||
cbw.scsi_cmd.operation_code = 0x2A; // write operation
|
|||
cbw.scsi_cmd.transfer_len[1] = 1; |
|||
cbw.scsi_cmd.lba[0] = dev->current_lba >> 24; |
|||
cbw.scsi_cmd.lba[1] = dev->current_lba >> 16; |
|||
cbw.scsi_cmd.lba[2] = dev->current_lba >> 8; |
|||
cbw.scsi_cmd.lba[3] = dev->current_lba; |
|||
|
|||
result = do_scsi_cmd(dev, &cbw.cbw, buffer, true); |
|||
|
|||
if (result == USB_ERR_OK) |
|||
dev->current_lba++; |
|||
return result; |
|||
} |
|||
|
|||
usb_error scsi_eject(device_config_storage *const dev) { |
|||
cbw_scsi_eject cbw_scsi; |
|||
cbw_scsi.cbw = scsi_command_block_wrapper; |
|||
|
|||
memset(&cbw_scsi.eject, 0, sizeof(_scsi_packet_eject)); |
|||
|
|||
cbw_scsi.eject.operation_code = 0x1B; |
|||
cbw_scsi.eject.loej = 1; |
|||
|
|||
cbw_scsi.cbw.bCBWLUN = 0; |
|||
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_eject); |
|||
cbw_scsi.cbw.dCBWDataTransferLength = 0; |
|||
|
|||
return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false); |
|||
} |
|||
@ -0,0 +1,196 @@ |
|||
#ifndef __CLASS_SCSI |
|||
#define __CLASS_SCSI |
|||
|
|||
#include <protocol.h> |
|||
|
|||
typedef struct { |
|||
uint8_t dCBWSignature[4]; |
|||
uint16_t dCBWTag[2]; |
|||
uint32_t dCBWDataTransferLength; |
|||
uint8_t bmCBWFlags; |
|||
uint8_t bCBWLUN; |
|||
uint8_t bCBWCBLength; |
|||
} _scsi_command_block_wrapper; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved1; |
|||
uint8_t reserved2; |
|||
uint8_t allocation_length; |
|||
uint8_t reserved3; |
|||
uint8_t pad[6]; |
|||
} _scsi_packet_request_sense; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_request_sense request_sense; |
|||
} cbw_scsi_request_sense; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
|
|||
uint8_t IMMED : 1; |
|||
uint8_t reserved : 7; |
|||
|
|||
uint8_t reserved2; |
|||
|
|||
uint8_t power_condition_modifier : 4; |
|||
uint8_t reserved3 : 4; |
|||
|
|||
uint8_t start : 1; |
|||
uint8_t loej : 1; |
|||
uint8_t no_flush : 1; |
|||
uint8_t reserved4 : 1; |
|||
uint8_t power_condition : 4; |
|||
|
|||
uint8_t control; |
|||
} _scsi_packet_eject; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_eject eject; |
|||
} cbw_scsi_eject; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved1; |
|||
uint8_t reserved2; |
|||
uint8_t reserved3; |
|||
uint8_t reserved4; |
|||
uint8_t pad[6]; |
|||
} _scsi_packet_test; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_test test; |
|||
} cbw_scsi_test; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved[8]; |
|||
uint8_t pad[2]; |
|||
} _scsi_read_capacity; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_read_capacity read_capacity; |
|||
} cbw_scsi_read_capacity; |
|||
|
|||
typedef struct __scsi_packet_inquiry { // contains information about a specific device
|
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved1; |
|||
uint8_t reserved2; |
|||
uint8_t allocation_length; |
|||
uint8_t reserved3; |
|||
uint8_t pad[6]; |
|||
} _scsi_packet_inquiry; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_inquiry inquiry; |
|||
} cbw_scsi_inquiry; |
|||
|
|||
typedef struct { |
|||
uint8_t device_type : 5; |
|||
uint8_t device_type_qualifier : 3; |
|||
uint8_t device_type_modifier : 7; |
|||
uint8_t removable_media : 1; |
|||
union { |
|||
uint8_t versions; |
|||
struct { |
|||
uint8_t ansi_version : 3; |
|||
uint8_t ecma_version : 3; |
|||
uint8_t iso_version : 2; |
|||
}; |
|||
}; |
|||
uint8_t response_data_format : 4; |
|||
uint8_t hi_support : 1; |
|||
uint8_t norm_aca : 1; |
|||
uint8_t terminate_task : 1; |
|||
uint8_t aerc : 1; |
|||
uint8_t additional_length; |
|||
uint8_t reserved; |
|||
uint8_t addr16 : 1; |
|||
uint8_t addr32 : 1; |
|||
uint8_t ack_req_q : 1; |
|||
uint8_t medium_changer : 1; |
|||
uint8_t multi_port : 1; |
|||
uint8_t reserved_bit2 : 1; |
|||
uint8_t enclosure_services : 1; |
|||
uint8_t reserved_bit3 : 1; |
|||
uint8_t soft_reset : 1; |
|||
uint8_t command_queue : 1; |
|||
uint8_t transfer_disable : 1; |
|||
uint8_t linked_commands : 1; |
|||
uint8_t synchronous : 1; |
|||
uint8_t wide16_bit : 1; |
|||
uint8_t wide32_bit : 1; |
|||
uint8_t relative_addressing : 1; |
|||
uint8_t vendor_information[8]; |
|||
uint8_t product_id[16]; |
|||
uint8_t product_revision[4]; |
|||
uint8_t vendor_specific[20]; |
|||
uint8_t reserved3[40]; |
|||
} scsi_inquiry_result; |
|||
|
|||
typedef struct __scsi_command_status_wrapper { |
|||
uint8_t dCSWSignature[4]; |
|||
uint16_t dCSWTag[2]; |
|||
uint8_t dCSWDataResidue[4]; |
|||
uint8_t bCSWStatus; |
|||
} _scsi_command_status_wrapper; |
|||
|
|||
typedef struct { |
|||
uint8_t number_of_blocks[4]; |
|||
uint8_t block_size[4]; |
|||
} scsi_read_capacity_result; |
|||
|
|||
typedef struct { |
|||
uint8_t error_code : 7; |
|||
uint8_t valid : 1; |
|||
uint8_t segment_number; |
|||
uint8_t sense_key : 4; |
|||
uint8_t reserved : 1; |
|||
uint8_t incorrect_length : 1; |
|||
uint8_t end_of_media : 1; |
|||
uint8_t file_mark : 1; |
|||
uint8_t information[4]; |
|||
uint8_t additional_sense_length; |
|||
uint8_t command_specific_information[4]; |
|||
uint8_t additional_sense_code; |
|||
uint8_t additional_sense_code_qualifier; |
|||
uint8_t field_replaceable_unit_code; |
|||
uint8_t sense_key_specific[3]; |
|||
} scsi_sense_result; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t lba[4]; // high-endian block number
|
|||
uint8_t reserved1; |
|||
uint8_t transfer_len[2]; // high-endian in blocks of block_len (see scsi_capacity)
|
|||
uint8_t reserved2; |
|||
uint8_t pad[2]; |
|||
} _scsi_packet_read_write; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_read_write scsi_cmd; |
|||
} cbw_scsi_read_write; |
|||
|
|||
extern usb_error get_scsi_read_capacity(device_config_storage *const dev, scsi_read_capacity_result *result); |
|||
extern usb_error scsi_inquiry(device_config_storage *const dev, scsi_inquiry_result *inq_result); |
|||
extern usb_error scsi_sense_init(device_config_storage *const dev); |
|||
extern usb_error scsi_test(device_config_storage *const dev); |
|||
extern usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result); |
|||
extern usb_error scsi_eject(device_config_storage *const dev); |
|||
extern usb_error scsi_read_write( |
|||
device_config_storage *const dev, const bool send, uint32_t sector_number, const uint8_t sector_count, uint8_t *const buffer); |
|||
|
|||
extern usb_error scsi_read(device_config_storage *const dev, uint8_t *const buffer); |
|||
extern usb_error scsi_write(device_config_storage *const dev, uint8_t *const buffer); |
|||
#endif |
|||
@ -0,0 +1,35 @@ |
|||
#include "class_scsi.h" |
|||
#include <ch376.h> |
|||
#include <enumerate.h> |
|||
#include <hbios.h> |
|||
#include <print.h> |
|||
#include <string.h> |
|||
#include <usb-base-drv.h> |
|||
#include <work-area.h> |
|||
#include <z80.h> |
|||
|
|||
extern const uint16_t const ch_scsi_fntbl[]; |
|||
|
|||
void chscsi_init(void) { |
|||
uint8_t index = 1; |
|||
do { |
|||
device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index); |
|||
|
|||
if (storage_device == NULL) |
|||
break; |
|||
|
|||
const usb_device_type t = storage_device->type; |
|||
|
|||
if (t == USB_IS_MASS_STORAGE) { |
|||
storage_device->drive_index = storage_count++; |
|||
scsi_sense_init(storage_device); |
|||
dio_add_entry(ch_scsi_fntbl, storage_device); |
|||
} |
|||
|
|||
} while (++index != MAX_NUMBER_OF_DEVICES + 1); |
|||
|
|||
if (storage_count == 0) |
|||
return; |
|||
|
|||
print_device_mounted(" STORAGE DEVICE$", storage_count); |
|||
} |
|||
@ -0,0 +1,176 @@ |
|||
#include "class_ufi.h" |
|||
#include <delay.h> |
|||
#include <protocol.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <z80.h> |
|||
|
|||
const ufi_request_sense_command _ufi_cmd_request_sense = {0x03, 0, 0, 0, 0, 18, {0, 0, 0, 0, 0, 0, 0}}; |
|||
const ufi_read_format_capacities_command _ufi_cmd_read_format_capacities = {0x23, 0, 0, {0, 0, 0, 0, 0}, {0, 12}, {0, 0, 0}}; |
|||
const ufi_inquiry_command _ufi_cmd_inquiry = {0x12, 0, 0, 0, 0, 0, 0x24, {0, 0, 0, 0, 0, 0, 0}}; |
|||
const ufi_format_command _ufi_cmd_format = {0x04, 7, 0, 1, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0, 0}}; |
|||
const ufi_send_diagnostic_command _ufi_cmd_send_diagnostic = {0x1D, 0, 0, 1, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}; |
|||
|
|||
uint8_t wait_for_device_ready(device_config *const storage_device, uint8_t timeout_counter) { |
|||
usb_error result; |
|||
ufi_request_sense_response sense; |
|||
|
|||
do { |
|||
memset(&sense, 0, sizeof(sense)); |
|||
result = ufi_test_unit_ready(storage_device, &sense); |
|||
|
|||
if ((result == USB_ERR_OK && sense.sense_key == 0) || timeout_counter-- == 0) |
|||
break; |
|||
|
|||
delay_medium(); |
|||
|
|||
} while (true); |
|||
|
|||
return result | sense.sense_key; |
|||
} |
|||
|
|||
usb_error ufi_test_unit_ready(device_config *const storage_device, ufi_request_sense_response const *response) { |
|||
usb_error result; |
|||
ufi_test_unit_ready_command ufi_cmd_request_test_unit_ready; |
|||
memset(&ufi_cmd_request_test_unit_ready, 0, sizeof(ufi_test_unit_ready_command)); |
|||
|
|||
usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_test_unit_ready, false, 0, NULL, NULL); |
|||
|
|||
ufi_request_sense_command ufi_cmd_request_sense; |
|||
ufi_cmd_request_sense = _ufi_cmd_request_sense; |
|||
|
|||
result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response), |
|||
(uint8_t *)response, NULL); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error ufi_request_sense(device_config *const storage_device, ufi_request_sense_response const *response) { |
|||
ufi_request_sense_command ufi_cmd_request_sense; |
|||
ufi_cmd_request_sense = _ufi_cmd_request_sense; |
|||
|
|||
usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response), |
|||
(uint8_t *)response, NULL); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error ufi_read_frmt_caps(device_config *const storage_device, ufi_format_capacities_response const *response) { |
|||
usb_error result; |
|||
ufi_read_format_capacities_command ufi_cmd_read_format_capacities; |
|||
|
|||
ufi_cmd_read_format_capacities = _ufi_cmd_read_format_capacities; |
|||
result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_read_format_capacities, false, 12, (uint8_t *)response, NULL); |
|||
|
|||
TRACE_USB_ERROR(result); |
|||
CHECK(result); |
|||
|
|||
const uint8_t available_length = response->capacity_list_length; |
|||
|
|||
const uint8_t max_length = |
|||
available_length > sizeof(ufi_format_capacities_response) ? sizeof(ufi_format_capacities_response) : available_length; |
|||
|
|||
ufi_read_format_capacities_command cmd; |
|||
memcpy(&cmd, &ufi_cmd_read_format_capacities, sizeof(cmd)); |
|||
cmd.allocation_length[1] = max_length; |
|||
|
|||
result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, false, max_length, (uint8_t *)response, NULL); |
|||
|
|||
TRACE_USB_ERROR(result); |
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error ufi_inquiry(device_config *const storage_device, ufi_inquiry_response const *response) { |
|||
ufi_inquiry_command ufi_cmd_inquiry; |
|||
ufi_cmd_inquiry = _ufi_cmd_inquiry; |
|||
|
|||
usb_error result = |
|||
usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_inquiry, false, sizeof(ufi_inquiry_response), (uint8_t *)response, NULL); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error ufi_read_write_sector(device_config *const storage_device, |
|||
const bool send, |
|||
const uint16_t sector_number, |
|||
const uint8_t sector_count, |
|||
const uint8_t *const buffer, |
|||
uint8_t *const sense_codes) { |
|||
ufi_read_write_command cmd; |
|||
memset(&cmd, 0, sizeof(cmd)); |
|||
cmd.operation_code = send ? 0x2A : 0x28; |
|||
cmd.lba[2] = sector_number >> 8; |
|||
cmd.lba[3] = sector_number & 0xFF; |
|||
cmd.transfer_length[1] = sector_count; |
|||
|
|||
usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, send, 512 * sector_count, (uint8_t *)buffer, sense_codes); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
/**
|
|||
* Medium | Medium Type Code | Capacity | Tracks | Heads | Sectors/Track | Total Blocks | Block Length | |
|||
* DD | 1Eh | 720 KB | 80 | 2 | 9 | 1440 05A0h | 512 0200h | |
|||
* HD | 93h | 1.25 MB | 77 | 2 | 8 | 1232 04D0h | 1024 0400h | |
|||
* HD | 94h | 1.44 MB | 80 | 2 | 18 | 2880 0B40h | 512 0200h | |
|||
*/ |
|||
|
|||
usb_error ufi_format(device_config *const storage_device, |
|||
const uint8_t side, |
|||
const uint8_t track_number, |
|||
const ufi_format_capacity_descriptor *const format) { |
|||
ufi_interrupt_status sense_codes; |
|||
|
|||
ufi_format_parameter_list parameter_list; |
|||
memset(¶meter_list, 0, sizeof(parameter_list)); |
|||
|
|||
ufi_format_command cmd; |
|||
cmd = _ufi_cmd_format; |
|||
// memcpy(&cmd, &_ufi_cmd_format, sizeof(cmd));
|
|||
|
|||
cmd.track_number = track_number; |
|||
cmd.interleave[1] = 0; |
|||
cmd.parameter_list_length[1] = sizeof(parameter_list); |
|||
|
|||
parameter_list.defect_list_header.side = side; |
|||
parameter_list.defect_list_header.immediate = 0; |
|||
parameter_list.defect_list_header.reserved2 = 0; |
|||
parameter_list.defect_list_header.single_track = 1; |
|||
parameter_list.defect_list_header.dcrt = 1; |
|||
parameter_list.defect_list_header.extend = 0; |
|||
parameter_list.defect_list_header.fov = 1; |
|||
parameter_list.defect_list_header.defect_list_length_msb = 0; |
|||
parameter_list.defect_list_header.defect_list_length_lsb = 8; |
|||
memcpy(¶meter_list.format_descriptor, (void *)format, sizeof(ufi_format_capacity_descriptor)); |
|||
|
|||
usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, true, sizeof(parameter_list), (uint8_t *)¶meter_list, |
|||
(void *)&sense_codes); |
|||
|
|||
// trace_printf("ufi_format: %d, %02X %02X (len: %d)\r\n", result, sense_codes.bASC, sense_codes.bASCQ, sizeof(parameter_list));
|
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
usb_error ufi_send_diagnostics(device_config *const storage_device) { |
|||
usb_error result; |
|||
ufi_send_diagnostic_command ufi_cmd_send_diagnostic; |
|||
|
|||
ufi_cmd_send_diagnostic = _ufi_cmd_send_diagnostic; |
|||
|
|||
result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_send_diagnostic, true, 0, NULL, NULL); |
|||
|
|||
RETURN_CHECK(result); |
|||
} |
|||
|
|||
uint32_t convert_from_msb_first(const uint8_t *const buffer) { |
|||
uint32_t result; |
|||
uint8_t *p_output = ((uint8_t *)&result); |
|||
const uint8_t *p_input = buffer + 3; |
|||
|
|||
*p_output++ = *p_input--; |
|||
*p_output++ = *p_input--; |
|||
*p_output++ = *p_input--; |
|||
*p_output = *p_input--; |
|||
|
|||
return result; |
|||
} |
|||
@ -0,0 +1,207 @@ |
|||
#ifndef __CLASS_UFI2 |
|||
#define __CLASS_UFI2 |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include "usb_cbi.h" |
|||
#include "usb_state.h" |
|||
#include <stdlib.h> |
|||
|
|||
typedef struct { |
|||
uint8_t bASC; |
|||
uint8_t bASCQ; |
|||
} ufi_interrupt_status; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t reserverd1 : 5; |
|||
uint8_t lun : 3; |
|||
uint8_t reserved1[5]; |
|||
uint8_t allocation_length[2]; |
|||
uint8_t reserved[3]; |
|||
} ufi_read_format_capacities_command; |
|||
|
|||
typedef enum { UNFORMATTED_MEDIA = 1, FORMATTED_MEDIA = 2, NO_MEDIA = 3 } UFI_DESCRIPTOR_CODE; |
|||
|
|||
#define UFI_DESCRIPTOR_CODE_UNFORMATTED_MEDIA 1 |
|||
#define UFI_DESCRIPTOR_CODE_FORMATTED_MEDIA 2 |
|||
#define UFI_DESCRIPTOR_CODE_NO_MEDIA 3 |
|||
|
|||
typedef struct { |
|||
uint8_t number_of_blocks[4]; |
|||
uint8_t descriptor_code : 2; // UFI_DESCRIPTOR_CODE
|
|||
uint8_t reserved2 : 6; |
|||
uint8_t block_size[3]; |
|||
} ufi_format_capacity_descriptor; |
|||
|
|||
typedef struct { |
|||
uint8_t reserved1[3]; |
|||
uint8_t capacity_list_length; |
|||
ufi_format_capacity_descriptor descriptors[4]; // support upto
|
|||
} ufi_format_capacities_response; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved[10]; |
|||
} ufi_test_unit_ready_command; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t evpd : 1; |
|||
uint8_t reserved1 : 4; |
|||
uint8_t lun : 3; |
|||
uint8_t page_code; |
|||
uint8_t reserved3; |
|||
uint8_t allocation_length; |
|||
uint8_t reserved4[7]; |
|||
} ufi_inquiry_command; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t reserverd1 : 5; |
|||
uint8_t lun : 3; |
|||
uint8_t reserved2; |
|||
uint8_t reserved3; |
|||
uint8_t allocation_length; |
|||
uint8_t reserved4[7]; |
|||
} ufi_request_sense_command; |
|||
|
|||
typedef struct { |
|||
uint8_t error_code; |
|||
uint8_t reserved1; |
|||
uint8_t sense_key : 4; |
|||
uint8_t reserved2 : 4; |
|||
uint8_t information[4]; |
|||
uint8_t additional_length; |
|||
uint8_t reserved3[4]; |
|||
uint8_t asc; // Additional Sense Code
|
|||
uint8_t ascq; // Additional Sense Code Qualifier
|
|||
uint8_t reserved4[4]; |
|||
} ufi_request_sense_response; |
|||
|
|||
typedef struct { |
|||
// device_type: identifies the device currently connected to the requested logical unit.
|
|||
// 00h Direct-access device (floppy)
|
|||
// 1Fh none (no FDD connected to the requested logical unit)
|
|||
uint8_t device_type : 5; |
|||
uint8_t reserved1 : 3; |
|||
|
|||
uint8_t reserved2 : 7; |
|||
// Removable Media Bit: this shall be set to one to indicate removable media.
|
|||
uint8_t removable_media : 1; |
|||
|
|||
// ANSI Version: must contain a zero to comply with this version of the Specification.
|
|||
uint8_t ansi_version : 3; |
|||
// ISO/ECMA: These fields shall be zero for the UFI device.
|
|||
uint8_t ecma : 3; |
|||
uint8_t iso_version : 2; |
|||
|
|||
// Response Data Format: a value of 01h shall be used for UFI device
|
|||
uint8_t response_data_format : 4; |
|||
uint8_t reserved3 : 4; |
|||
|
|||
// The Additional Length field shall specify the length in bytes of the parameters. If the Allocation Length of the
|
|||
// Command Packet is too small to transfer all of the parameters, the Additional Length shall not be adjusted to
|
|||
// reflect the truncation. The UFI device shall set this field to 1Fh.
|
|||
uint8_t additional_length; |
|||
uint8_t reserved4[3]; |
|||
|
|||
// The Vendor Identification field contains 8 bytes of ASCII data identifying the vendor of the product. The data
|
|||
// shall be left aligned within this field.
|
|||
char vendor_information[8]; |
|||
|
|||
// The Product Identification field contains 16 bytes of ASCII data as defined by the vendor. The data shall be
|
|||
// left-aligned within this field.
|
|||
char product_id[16]; |
|||
|
|||
// The Product Revision Level field contains 4 bytes of ASCII data as defined by the vendor.
|
|||
char product_revision[4]; |
|||
} ufi_inquiry_response; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; /*0*/ |
|||
union { /*1*/ |
|||
uint8_t byte_1; |
|||
struct { |
|||
uint8_t rel_adr : 1; |
|||
uint8_t reserved1 : 2; |
|||
uint8_t fua : 1; |
|||
uint8_t dpo : 1; |
|||
uint8_t lun : 3; |
|||
}; |
|||
}; |
|||
uint8_t lba[4]; /*2, 3, 4, 5*/ |
|||
uint8_t reserved2; /*6*/ |
|||
uint8_t transfer_length[2]; /*7, 8*/ |
|||
uint8_t reserved3[3]; /*9, 10, 11*/ |
|||
} ufi_read_write_command; |
|||
|
|||
typedef struct { |
|||
struct { |
|||
uint8_t reserved1; |
|||
uint8_t side : 1; |
|||
uint8_t immediate : 1; |
|||
uint8_t reserved2 : 2; |
|||
uint8_t single_track : 1; |
|||
uint8_t dcrt : 1; |
|||
uint8_t extend : 1; |
|||
uint8_t fov : 1; |
|||
uint8_t defect_list_length_msb; |
|||
uint8_t defect_list_length_lsb; |
|||
} defect_list_header; |
|||
|
|||
ufi_format_capacity_descriptor format_descriptor; |
|||
} ufi_format_parameter_list; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; /* 0x04 */ |
|||
uint8_t defect_list_format : 3; |
|||
uint8_t cmp_list : 1; |
|||
uint8_t format_data : 1; |
|||
uint8_t lun : 3; |
|||
uint8_t track_number; |
|||
uint8_t interleave[2]; |
|||
uint8_t reserved1[2]; |
|||
uint8_t parameter_list_length[2]; |
|||
uint8_t reserved2[3]; |
|||
} ufi_format_command; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; /*0x1D*/ |
|||
uint8_t unit_of_l : 1; |
|||
uint8_t def_of_l : 1; |
|||
uint8_t self_test : 1; |
|||
uint8_t reserved1 : 1; |
|||
uint8_t pf : 1; |
|||
uint8_t lun : 3; |
|||
uint8_t reserved[10]; |
|||
} ufi_send_diagnostic_command; |
|||
|
|||
extern usb_error ufi_request_sense(device_config *const storage_device, ufi_request_sense_response const *response); |
|||
|
|||
extern usb_error ufi_read_frmt_caps(device_config *const storage_device, ufi_format_capacities_response const *response); |
|||
|
|||
extern usb_error ufi_test_unit_ready(device_config *const storage_device, ufi_request_sense_response const *response); |
|||
|
|||
extern usb_error ufi_inquiry(device_config *const storage_device, ufi_inquiry_response const *response); |
|||
|
|||
extern usb_error ufi_read_write_sector(device_config *const storage_device, |
|||
const bool send, |
|||
const uint16_t sector_number, |
|||
const uint8_t sector_count, |
|||
const uint8_t *const buffer, |
|||
uint8_t *const sense_codes); |
|||
|
|||
uint8_t wait_for_device_ready(device_config *const storage_device, uint8_t timeout_counter); |
|||
|
|||
usb_error ufi_format(device_config *const storage_device, |
|||
const uint8_t side, |
|||
const uint8_t track_number, |
|||
const ufi_format_capacity_descriptor *const format); |
|||
|
|||
usb_error ufi_send_diagnostics(device_config *const storage_device); |
|||
|
|||
uint32_t convert_from_msb_first(const uint8_t *const buffer); |
|||
|
|||
#endif |
|||
@ -0,0 +1,92 @@ |
|||
#include "class_ufi.h" |
|||
#include <dev_transfers.h> |
|||
#include <hbios.h> |
|||
#include <print.h> |
|||
#include <string.h> |
|||
#include <usb-base-drv.h> |
|||
#include <work-area.h> |
|||
|
|||
extern const uint16_t const ch_ufi_fntbl[]; |
|||
|
|||
void chufi_init(void) { |
|||
uint8_t index = 1; |
|||
|
|||
do { |
|||
device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index); |
|||
|
|||
if (storage_device == NULL) |
|||
break; |
|||
|
|||
const usb_device_type t = storage_device->type; |
|||
|
|||
if (t == USB_IS_FLOPPY) { |
|||
storage_device->drive_index = storage_count++; |
|||
// scsi_sense_init(storage_device);
|
|||
dio_add_entry(ch_ufi_fntbl, storage_device); |
|||
} |
|||
|
|||
} while (++index != MAX_NUMBER_OF_DEVICES + 1); |
|||
|
|||
if (storage_count == 0) |
|||
return; |
|||
|
|||
print_device_mounted(" FLOPPY DRIVE$", storage_count); |
|||
} |
|||
|
|||
uint32_t chufi_get_cap(device_config *const dev) { |
|||
ufi_format_capacities_response response; |
|||
memset(&response, 0, sizeof(ufi_format_capacities_response)); |
|||
|
|||
wait_for_device_ready(dev, 25); |
|||
|
|||
// not sure if we need to do this to 'clear' some state
|
|||
ufi_inquiry_response inquiry; |
|||
ufi_inquiry(dev, &inquiry); |
|||
|
|||
wait_for_device_ready(dev, 15); |
|||
|
|||
const usb_error result = ufi_read_frmt_caps(dev, &response); |
|||
if (result != USB_ERR_OK) |
|||
return 0; |
|||
|
|||
// info->sector_size = response.descriptors[0].block_size[1] << 8 + response.descriptors[0].block_size[0];
|
|||
return convert_from_msb_first(response.descriptors[0].number_of_blocks); |
|||
|
|||
// const disk_geometry *const geometry = size_to_geometry(info->number_of_sectors);
|
|||
|
|||
// info->flags = INFO_FLAG_REMOVABLE | INFO_FLAG_FLOPPY;
|
|||
// info->number_of_cylinders = geometry->tracks;
|
|||
// info->number_of_heads = geometry->sides;
|
|||
// info->number_of_sectors_per_track = geometry->sectors_per_track;
|
|||
|
|||
// return 0;
|
|||
} |
|||
|
|||
uint8_t chufi_read(device_config_storage *const dev, uint8_t *const buffer) { |
|||
|
|||
if (wait_for_device_ready((device_config *)dev, 20) != 0) |
|||
return -1; // Not READY!
|
|||
|
|||
usb_error result; |
|||
ufi_interrupt_status sense_codes; |
|||
|
|||
memset(&sense_codes, 0, sizeof(sense_codes)); |
|||
|
|||
if (ufi_read_write_sector((device_config *)dev, false, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes) != USB_ERR_OK) |
|||
return -1; // general error
|
|||
|
|||
ufi_request_sense_response response; |
|||
memset(&response, 0, sizeof(response)); |
|||
|
|||
if ((result = ufi_request_sense((device_config *)dev, &response)) != USB_ERR_OK) |
|||
return -1; // error
|
|||
|
|||
const uint8_t asc = response.asc; |
|||
const uint8_t ascq = response.ascq; |
|||
const uint8_t sense_key = response.sense_key; |
|||
|
|||
if (sense_key != 0) |
|||
return -1; |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
@ -0,0 +1,64 @@ |
|||
#include "usb_cbi.h" |
|||
#include "dev_transfers.h" |
|||
#include "protocol.h" |
|||
#include <ch376.h> |
|||
|
|||
setup_packet cbi2_adsc = {0x21, 0, {0, 0}, {255, 0}, 12}; // ;4th byte is interface number
|
|||
|
|||
// was no clear
|
|||
usb_error usb_execute_cbi(device_config *const storage_device, |
|||
const uint8_t *const cmd, |
|||
const bool send, |
|||
const uint16_t buffer_size, |
|||
uint8_t *const buffer, |
|||
uint8_t *const sense_codes) { |
|||
|
|||
usb_error result; |
|||
|
|||
const uint8_t interface_number = storage_device->interface_number; |
|||
|
|||
setup_packet adsc; |
|||
adsc = cbi2_adsc; |
|||
adsc.bIndex[0] = interface_number; |
|||
|
|||
result = usbdev_control_transfer(storage_device, &adsc, (uint8_t *const)cmd); |
|||
|
|||
if (result == USB_ERR_STALL) { |
|||
if (sense_codes != NULL) |
|||
usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN); |
|||
|
|||
return USB_ERR_STALL; |
|||
} |
|||
|
|||
if (result != USB_ERR_OK) { |
|||
TRACE_USB_ERROR(result); |
|||
return result; |
|||
} |
|||
|
|||
if (send) { |
|||
result = usbdev_blk_out_trnsfer(storage_device, buffer, buffer_size); |
|||
|
|||
if (result != USB_ERR_OK) { |
|||
TRACE_USB_ERROR(result); |
|||
return result; |
|||
} |
|||
} else { |
|||
result = usbdev_dat_in_trnsfer(storage_device, buffer, buffer_size, ENDPOINT_BULK_IN); |
|||
|
|||
if (result != USB_ERR_OK) { |
|||
TRACE_USB_ERROR(result); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
if (sense_codes != NULL) { |
|||
result = usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN); |
|||
|
|||
if (result != USB_ERR_OK) { |
|||
TRACE_USB_ERROR(result); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
#ifndef __USB_CBI_H__ |
|||
#define __USB_CBI_H__ |
|||
|
|||
#include <ch376.h> |
|||
#include <dev_transfers.h> |
|||
|
|||
usb_error usb_execute_cbi(device_config *const storage_device, |
|||
const uint8_t *const cmd, |
|||
const bool send, |
|||
const uint16_t buffer_size, |
|||
uint8_t *const buffer, |
|||
uint8_t *const asc); |
|||
|
|||
#endif |
|||
@ -0,0 +1,4 @@ |
|||
; Generated File -- not to be modify directly |
|||
#include "ch376-native/ufi-drv/ufi-init.c.s" |
|||
#include "ch376-native/ufi-drv/usb_cbi.c.s" |
|||
#include "ch376-native/ufi-drv/class_ufi.c.s" |
|||
@ -0,0 +1,705 @@ |
|||
; |
|||
; Generated from source-doc/ufi-drv/./class_ufi.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/ufi-drv/./class_ufi.c:14: uint8_t wait_for_device_ready(device_config *const storage_device, uint8_t timeout_counter) { |
|||
; --------------------------------- |
|||
; Function wait_for_device_ready |
|||
; --------------------------------- |
|||
_wait_for_device_ready: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -18 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:18: do { |
|||
ld c,(ix+6) |
|||
l_wait_for_device_ready_00105: |
|||
;source-doc/ufi-drv/./class_ufi.c:19: memset(&sense, 0, sizeof(sense)); |
|||
push bc |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x12 |
|||
push hl |
|||
call _memset_callee |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _ufi_test_unit_ready |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
pop bc |
|||
ld b, a |
|||
;source-doc/ufi-drv/./class_ufi.c:22: if ((result == USB_ERR_OK && sense.sense_key == 0) || timeout_counter-- == 0) |
|||
or a |
|||
jr NZ,l_wait_for_device_ready_00104 |
|||
ld hl,2 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
and 0x0f |
|||
jr Z,l_wait_for_device_ready_00107 |
|||
l_wait_for_device_ready_00104: |
|||
ld a, c |
|||
dec c |
|||
or a |
|||
jr Z,l_wait_for_device_ready_00107 |
|||
;source-doc/ufi-drv/./class_ufi.c:25: delay_medium(); |
|||
push bc |
|||
call _delay_medium |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:27: } while (true); |
|||
jr l_wait_for_device_ready_00105 |
|||
l_wait_for_device_ready_00107: |
|||
;source-doc/ufi-drv/./class_ufi.c:29: return result | sense.sense_key; |
|||
ld hl,2 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
and 0x0f |
|||
or b |
|||
ld l, a |
|||
;source-doc/ufi-drv/./class_ufi.c:30: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
__ufi_cmd_request_sense: |
|||
DEFB +0x03 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x12 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
__ufi_cmd_read_format_capacitie: |
|||
DEFB +0x23 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x0c |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
__ufi_cmd_inquiry: |
|||
DEFB +0x12 |
|||
DEFB 0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x24 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
__ufi_cmd_format: |
|||
DEFB +0x04 |
|||
DEFB 0x17 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
__ufi_cmd_send_diagnostic: |
|||
DEFB +0x1d |
|||
DEFB 0x04 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
;source-doc/ufi-drv/./class_ufi.c:32: usb_error ufi_test_unit_ready(device_config *const storage_device, ufi_request_sense_response const *response) { |
|||
; --------------------------------- |
|||
; Function ufi_test_unit_ready |
|||
; --------------------------------- |
|||
_ufi_test_unit_ready: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -24 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:35: memset(&ufi_cmd_request_test_unit_ready, 0, sizeof(ufi_test_unit_ready_command)); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x0c |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/ufi-drv/./class_ufi.c:37: usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_test_unit_ready, false, 0, NULL, NULL); |
|||
ld hl,0x0000 |
|||
push hl |
|||
push hl |
|||
push hl |
|||
xor a |
|||
push af |
|||
inc sp |
|||
ld hl,7 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld hl,11 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:40: ufi_cmd_request_sense = _ufi_cmd_request_sense; |
|||
ld hl,12 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x000c |
|||
ld hl,__ufi_cmd_request_sense |
|||
ldir |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:43: (uint8_t *)response, NULL); |
|||
ld e,(ix+6) |
|||
ld d,(ix+7) |
|||
;source-doc/ufi-drv/./class_ufi.c:42: result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response), |
|||
ld hl,0x0000 |
|||
push hl |
|||
push de |
|||
ld l,0x12 |
|||
push hl |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:45: RETURN_CHECK(result); |
|||
;source-doc/ufi-drv/./class_ufi.c:46: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:48: usb_error ufi_request_sense(device_config *const storage_device, ufi_request_sense_response const *response) { |
|||
; --------------------------------- |
|||
; Function ufi_request_sense |
|||
; --------------------------------- |
|||
_ufi_request_sense: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -12 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:50: ufi_cmd_request_sense = _ufi_cmd_request_sense; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x000c |
|||
ld hl,__ufi_cmd_request_sense |
|||
ldir |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:52: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response), |
|||
ld e,(ix+6) |
|||
ld d,(ix+7) |
|||
ld hl,0x0000 |
|||
push hl |
|||
push de |
|||
ld l,0x12 |
|||
push hl |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:55: RETURN_CHECK(result); |
|||
;source-doc/ufi-drv/./class_ufi.c:56: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:58: usb_error ufi_read_frmt_caps(device_config *const storage_device, ufi_format_capacities_response const *response) { |
|||
; --------------------------------- |
|||
; Function ufi_read_frmt_caps |
|||
; --------------------------------- |
|||
_ufi_read_frmt_caps: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -24 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:62: ufi_cmd_read_format_capacities = _ufi_cmd_read_format_capacities; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000c |
|||
ld hl,__ufi_cmd_read_format_capacitie |
|||
ldir |
|||
;source-doc/ufi-drv/./class_ufi.c:63: result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_read_format_capacities, false, 12, (uint8_t *)response, NULL); |
|||
ld c,(ix+6) |
|||
ld b,(ix+7) |
|||
push bc |
|||
ld hl,0x0000 |
|||
push hl |
|||
push bc |
|||
ld l,0x0c |
|||
push hl |
|||
xor a |
|||
push af |
|||
inc sp |
|||
ld hl,9 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
ld sp, iy |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:66: CHECK(result); |
|||
ld a, l |
|||
or a |
|||
jr NZ,l_ufi_read_frmt_caps_00103 |
|||
;source-doc/ufi-drv/./class_ufi.c:68: const uint8_t available_length = response->capacity_list_length; |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
inc hl |
|||
inc hl |
|||
inc hl |
|||
ld e, (hl) |
|||
;source-doc/ufi-drv/./class_ufi.c:70: const uint8_t max_length = |
|||
ld a,0x24 |
|||
sub e |
|||
jr NC,l_ufi_read_frmt_caps_00105 |
|||
ld e,0x24 |
|||
l_ufi_read_frmt_caps_00105: |
|||
;source-doc/ufi-drv/./class_ufi.c:74: memcpy(&cmd, &ufi_cmd_read_format_capacities, sizeof(cmd)); |
|||
push bc |
|||
push de |
|||
ld hl,16 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,6 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x000c |
|||
push hl |
|||
call _memcpy_callee |
|||
pop de |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:75: cmd.allocation_length[1] = max_length; |
|||
ld (ix-4),e |
|||
;source-doc/ufi-drv/./class_ufi.c:77: result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, false, max_length, (uint8_t *)response, NULL); |
|||
ld hl,0x0000 |
|||
ld d,l |
|||
push hl |
|||
push bc |
|||
push de |
|||
xor a |
|||
push af |
|||
inc sp |
|||
ld hl,19 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:80: RETURN_CHECK(result); |
|||
l_ufi_read_frmt_caps_00103: |
|||
;source-doc/ufi-drv/./class_ufi.c:81: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:83: usb_error ufi_inquiry(device_config *const storage_device, ufi_inquiry_response const *response) { |
|||
; --------------------------------- |
|||
; Function ufi_inquiry |
|||
; --------------------------------- |
|||
_ufi_inquiry: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -12 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:85: ufi_cmd_inquiry = _ufi_cmd_inquiry; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x000c |
|||
ld hl,__ufi_cmd_inquiry |
|||
ldir |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:87: usb_error result = |
|||
ld e,(ix+6) |
|||
ld d,(ix+7) |
|||
ld hl,0x0000 |
|||
push hl |
|||
push de |
|||
ld l,0x24 |
|||
push hl |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:90: RETURN_CHECK(result); |
|||
;source-doc/ufi-drv/./class_ufi.c:91: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:93: usb_error ufi_read_write_sector(device_config *const storage_device, |
|||
; --------------------------------- |
|||
; Function ufi_read_write_sector |
|||
; --------------------------------- |
|||
_ufi_read_write_sector: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -12 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:100: memset(&cmd, 0, sizeof(cmd)); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x0c |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/ufi-drv/./class_ufi.c:101: cmd.operation_code = send ? 0x2A : 0x28; |
|||
bit 0,(ix+6) |
|||
jr Z,l_ufi_read_write_sector_00103 |
|||
ld bc,0x002a |
|||
jr l_ufi_read_write_sector_00104 |
|||
l_ufi_read_write_sector_00103: |
|||
ld bc,0x0028 |
|||
l_ufi_read_write_sector_00104: |
|||
ld (ix-12),c |
|||
;source-doc/ufi-drv/./class_ufi.c:102: cmd.lba[2] = sector_number >> 8; |
|||
ld a,(ix+8) |
|||
ld (ix-8),a |
|||
;source-doc/ufi-drv/./class_ufi.c:103: cmd.lba[3] = sector_number & 0xFF; |
|||
ld a,(ix+7) |
|||
ld (ix-7),a |
|||
;source-doc/ufi-drv/./class_ufi.c:104: cmd.transfer_length[1] = sector_count; |
|||
;source-doc/ufi-drv/./class_ufi.c:106: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, send, 512 * sector_count, (uint8_t *)buffer, sense_codes); |
|||
ld a,(ix+9) |
|||
ld (ix-4),a |
|||
add a, a |
|||
ld c,0x00 |
|||
ld l,(ix+12) |
|||
ld h,(ix+13) |
|||
push hl |
|||
ld l,(ix+10) |
|||
ld h,(ix+11) |
|||
push hl |
|||
ld b, a |
|||
push bc |
|||
ld a,(ix+6) |
|||
push af |
|||
inc sp |
|||
ld hl,7 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:108: RETURN_CHECK(result); |
|||
;source-doc/ufi-drv/./class_ufi.c:109: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:118: usb_error ufi_format(device_config *const storage_device, |
|||
; --------------------------------- |
|||
; Function ufi_format |
|||
; --------------------------------- |
|||
_ufi_format: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -26 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:125: memset(¶meter_list, 0, sizeof(parameter_list)); |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x0c |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/ufi-drv/./class_ufi.c:128: cmd = _ufi_cmd_format; |
|||
ld hl,14 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x000c |
|||
ld hl,__ufi_cmd_format |
|||
ldir |
|||
;source-doc/ufi-drv/./class_ufi.c:131: cmd.track_number = track_number; |
|||
ld a,(ix+7) |
|||
ld (ix-10),a |
|||
;source-doc/ufi-drv/./class_ufi.c:132: cmd.interleave[1] = 0; |
|||
ld (ix-8),0x00 |
|||
;source-doc/ufi-drv/./class_ufi.c:133: cmd.parameter_list_length[1] = sizeof(parameter_list); |
|||
ld (ix-4),0x0c |
|||
;source-doc/ufi-drv/./class_ufi.c:135: parameter_list.defect_list_header.side = side; |
|||
ld hl,2+1 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld a,(ix+6) |
|||
and 0x01 |
|||
ld c, a |
|||
ld a, (de) |
|||
and 0xfe |
|||
or c |
|||
ld (de), a |
|||
;source-doc/ufi-drv/./class_ufi.c:136: parameter_list.defect_list_header.immediate = 0; |
|||
ld l, e |
|||
ld h, d |
|||
res 1, (hl) |
|||
;source-doc/ufi-drv/./class_ufi.c:137: parameter_list.defect_list_header.reserved2 = 0; |
|||
ld c, e |
|||
ld b, d |
|||
ld a, (bc) |
|||
and 0xf3 |
|||
ld (bc), a |
|||
;source-doc/ufi-drv/./class_ufi.c:138: parameter_list.defect_list_header.single_track = 1; |
|||
ld l, e |
|||
ld h, d |
|||
set 4, (hl) |
|||
;source-doc/ufi-drv/./class_ufi.c:139: parameter_list.defect_list_header.dcrt = 1; |
|||
ld l, e |
|||
ld h, d |
|||
set 5, (hl) |
|||
;source-doc/ufi-drv/./class_ufi.c:140: parameter_list.defect_list_header.extend = 0; |
|||
ld l, e |
|||
ld h, d |
|||
res 6, (hl) |
|||
;source-doc/ufi-drv/./class_ufi.c:141: parameter_list.defect_list_header.fov = 1; |
|||
ld a, (de) |
|||
or 0x80 |
|||
ld (de), a |
|||
;source-doc/ufi-drv/./class_ufi.c:142: parameter_list.defect_list_header.defect_list_length_msb = 0; |
|||
ld (ix-22),0x00 |
|||
;source-doc/ufi-drv/./class_ufi.c:143: parameter_list.defect_list_header.defect_list_length_lsb = 8; |
|||
ld (ix-21),0x08 |
|||
;source-doc/ufi-drv/./class_ufi.c:144: memcpy(¶meter_list.format_descriptor, (void *)format, sizeof(ufi_format_capacity_descriptor)); |
|||
ld c,(ix+8) |
|||
ld b,(ix+9) |
|||
ld hl,6 |
|||
add hl, sp |
|||
push hl |
|||
push bc |
|||
ld hl,0x0008 |
|||
push hl |
|||
call _memcpy_callee |
|||
;source-doc/ufi-drv/./class_ufi.c:146: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, true, sizeof(parameter_list), (uint8_t *)¶meter_list, |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x000c |
|||
push hl |
|||
ld a,0x01 |
|||
push af |
|||
inc sp |
|||
ld hl,21 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:151: RETURN_CHECK(result); |
|||
;source-doc/ufi-drv/./class_ufi.c:152: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:154: usb_error ufi_send_diagnostics(device_config *const storage_device) { |
|||
; --------------------------------- |
|||
; Function ufi_send_diagnostics |
|||
; --------------------------------- |
|||
_ufi_send_diagnostics: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -12 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:158: ufi_cmd_send_diagnostic = _ufi_cmd_send_diagnostic; |
|||
ld hl,0 |
|||
add hl, sp |
|||
ld e,l |
|||
ld d,h |
|||
push hl |
|||
ld bc,0x000c |
|||
ld hl,__ufi_cmd_send_diagnostic |
|||
ldir |
|||
pop bc |
|||
;source-doc/ufi-drv/./class_ufi.c:160: result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_send_diagnostic, true, 0, NULL, NULL); |
|||
ld hl,0x0000 |
|||
push hl |
|||
push hl |
|||
push hl |
|||
ld a,0x01 |
|||
push af |
|||
inc sp |
|||
push bc |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usb_execute_cbi |
|||
ld iy,11 |
|||
add iy, sp |
|||
;source-doc/ufi-drv/./class_ufi.c:162: RETURN_CHECK(result); |
|||
;source-doc/ufi-drv/./class_ufi.c:163: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./class_ufi.c:165: uint32_t convert_from_msb_first(const uint8_t *const buffer) { |
|||
; --------------------------------- |
|||
; Function convert_from_msb_first |
|||
; --------------------------------- |
|||
_convert_from_msb_first: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
push af |
|||
;source-doc/ufi-drv/./class_ufi.c:167: uint8_t *p_output = ((uint8_t *)&result); |
|||
ld hl,0 |
|||
add hl, sp |
|||
ex de, hl |
|||
;source-doc/ufi-drv/./class_ufi.c:168: const uint8_t *p_input = buffer + 3; |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
inc bc |
|||
inc bc |
|||
inc bc |
|||
;source-doc/ufi-drv/./class_ufi.c:170: *p_output++ = *p_input--; |
|||
ld a, (bc) |
|||
dec bc |
|||
ld (de), a |
|||
inc de |
|||
;source-doc/ufi-drv/./class_ufi.c:171: *p_output++ = *p_input--; |
|||
ld a, (bc) |
|||
dec bc |
|||
ld (de), a |
|||
inc de |
|||
;source-doc/ufi-drv/./class_ufi.c:172: *p_output++ = *p_input--; |
|||
ld a, (bc) |
|||
dec bc |
|||
ld (de), a |
|||
inc de |
|||
;source-doc/ufi-drv/./class_ufi.c:173: *p_output = *p_input--; |
|||
ld a, (bc) |
|||
ld (de), a |
|||
;source-doc/ufi-drv/./class_ufi.c:175: return result; |
|||
pop hl |
|||
push hl |
|||
ld e,(ix-2) |
|||
ld d,(ix-1) |
|||
;source-doc/ufi-drv/./class_ufi.c:176: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
@ -0,0 +1,319 @@ |
|||
; |
|||
; Generated from source-doc/ufi-drv/./ufi-init.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/ufi-drv/./ufi-init.c:11: void chufi_init(void) { |
|||
; --------------------------------- |
|||
; Function chufi_init |
|||
; --------------------------------- |
|||
_chufi_init: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
push af |
|||
;source-doc/ufi-drv/./ufi-init.c:14: do { |
|||
ld (ix-1),0x01 |
|||
l_chufi_init_00105: |
|||
;source-doc/ufi-drv/./ufi-init.c:15: device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index); |
|||
ld a,(ix-1) |
|||
call _get_usb_device_config |
|||
;source-doc/ufi-drv/./ufi-init.c:17: if (storage_device == NULL) |
|||
ld a, d |
|||
or e |
|||
jr Z,l_chufi_init_00107 |
|||
;source-doc/ufi-drv/./ufi-init.c:20: const usb_device_type t = storage_device->type; |
|||
ld l, e |
|||
ld h, d |
|||
ld a, (hl) |
|||
and 0x0f |
|||
;source-doc/ufi-drv/./ufi-init.c:22: if (t == USB_IS_FLOPPY) { |
|||
dec a |
|||
jr NZ,l_chufi_init_00106 |
|||
;source-doc/ufi-drv/./ufi-init.c:23: storage_device->drive_index = storage_count++; |
|||
ld hl,0x0010 |
|||
add hl, de |
|||
ld a,(_storage_count+0) |
|||
ld (ix-2),a |
|||
ld c,l |
|||
ld b,h |
|||
ld hl,_storage_count+0 |
|||
inc (hl) |
|||
ld a,(ix-2) |
|||
ld (bc), a |
|||
;source-doc/ufi-drv/./ufi-init.c:25: dio_add_entry(ch_ufi_fntbl, storage_device); |
|||
ld hl,_ch_ufi_fntbl |
|||
call _dio_add_entry |
|||
l_chufi_init_00106: |
|||
;source-doc/ufi-drv/./ufi-init.c:28: } while (++index != MAX_NUMBER_OF_DEVICES + 1); |
|||
inc (ix-1) |
|||
ld a,(ix-1) |
|||
sub 0x07 |
|||
jr NZ,l_chufi_init_00105 |
|||
l_chufi_init_00107: |
|||
;source-doc/ufi-drv/./ufi-init.c:30: if (storage_count == 0) |
|||
;source-doc/ufi-drv/./ufi-init.c:31: return; |
|||
;source-doc/ufi-drv/./ufi-init.c:33: print_device_mounted(" FLOPPY DRIVE$", storage_count); |
|||
ld a,(_storage_count+0) |
|||
or a |
|||
jr Z,l_chufi_init_00110 |
|||
push af |
|||
inc sp |
|||
ld hl,ufi_init_str_0 |
|||
push hl |
|||
call _print_device_mounted |
|||
pop af |
|||
inc sp |
|||
l_chufi_init_00110: |
|||
;source-doc/ufi-drv/./ufi-init.c:34: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
ufi_init_str_0: |
|||
DEFM " FLOPPY DRIVE$" |
|||
DEFB 0x00 |
|||
;source-doc/ufi-drv/./ufi-init.c:36: uint32_t chufi_get_cap(device_config *const dev) { |
|||
; --------------------------------- |
|||
; Function chufi_get_cap |
|||
; --------------------------------- |
|||
_chufi_get_cap: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -72 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./ufi-init.c:38: memset(&response, 0, sizeof(ufi_format_capacities_response)); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x24 |
|||
push hl |
|||
call _memset_callee |
|||
;source-doc/ufi-drv/./ufi-init.c:40: wait_for_device_ready(dev, 25); |
|||
ld a,0x19 |
|||
push af |
|||
inc sp |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _wait_for_device_ready |
|||
pop af |
|||
inc sp |
|||
;source-doc/ufi-drv/./ufi-init.c:44: ufi_inquiry(dev, &inquiry); |
|||
ld hl,36 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _ufi_inquiry |
|||
pop af |
|||
;source-doc/ufi-drv/./ufi-init.c:46: wait_for_device_ready(dev, 15); |
|||
ld h,0x0f |
|||
ex (sp),hl |
|||
inc sp |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _wait_for_device_ready |
|||
pop af |
|||
inc sp |
|||
;source-doc/ufi-drv/./ufi-init.c:48: const usb_error result = ufi_read_frmt_caps(dev, &response); |
|||
ld hl,0 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _ufi_read_frmt_caps |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
;source-doc/ufi-drv/./ufi-init.c:49: if (result != USB_ERR_OK) |
|||
or a |
|||
jr Z,l_chufi_get_cap_00102 |
|||
;source-doc/ufi-drv/./ufi-init.c:50: return 0; |
|||
ld hl,0x0000 |
|||
ld e, l |
|||
ld d, l |
|||
jr l_chufi_get_cap_00103 |
|||
l_chufi_get_cap_00102: |
|||
;source-doc/ufi-drv/./ufi-init.c:53: return convert_from_msb_first(response.descriptors[0].number_of_blocks); |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
call _convert_from_msb_first |
|||
pop af |
|||
l_chufi_get_cap_00103: |
|||
;source-doc/ufi-drv/./ufi-init.c:63: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
;source-doc/ufi-drv/./ufi-init.c:65: uint8_t chufi_read(device_config_storage *const dev, uint8_t *const buffer) { |
|||
; --------------------------------- |
|||
; Function chufi_read |
|||
; --------------------------------- |
|||
_chufi_read: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -20 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./ufi-init.c:67: if (wait_for_device_ready((device_config *)dev, 20) != 0) |
|||
ld c,(ix+4) |
|||
ld b,(ix+5) |
|||
push bc |
|||
ld a,0x14 |
|||
push af |
|||
inc sp |
|||
push bc |
|||
call _wait_for_device_ready |
|||
pop af |
|||
inc sp |
|||
ld a, l |
|||
pop bc |
|||
or a |
|||
jr Z,l_chufi_read_00102 |
|||
;source-doc/ufi-drv/./ufi-init.c:68: return -1; // Not READY! |
|||
ld l,0xff |
|||
jp l_chufi_read_00109 |
|||
l_chufi_read_00102: |
|||
;source-doc/ufi-drv/./ufi-init.c:73: memset(&sense_codes, 0, sizeof(sense_codes)); |
|||
push bc |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x02 |
|||
push hl |
|||
call _memset_callee |
|||
pop bc |
|||
;source-doc/ufi-drv/./ufi-init.c:75: if (ufi_read_write_sector((device_config *)dev, false, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes) != USB_ERR_OK) |
|||
ld e,(ix+4) |
|||
ld d,(ix+5) |
|||
ld hl,12 |
|||
add hl, de |
|||
ld e, (hl) |
|||
inc hl |
|||
ld d, (hl) |
|||
push bc |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
ld a,0x01 |
|||
push af |
|||
inc sp |
|||
push de |
|||
xor a |
|||
push af |
|||
inc sp |
|||
push bc |
|||
call _ufi_read_write_sector |
|||
ld iy,10 |
|||
add iy, sp |
|||
ld sp, iy |
|||
ld a, l |
|||
pop bc |
|||
or a |
|||
jr Z,l_chufi_read_00104 |
|||
;source-doc/ufi-drv/./ufi-init.c:76: return -1; // general error |
|||
ld l,0xff |
|||
jr l_chufi_read_00109 |
|||
l_chufi_read_00104: |
|||
;source-doc/ufi-drv/./ufi-init.c:79: memset(&response, 0, sizeof(response)); |
|||
push bc |
|||
ld hl,4 |
|||
add hl, sp |
|||
push hl |
|||
ld hl,0x0000 |
|||
push hl |
|||
ld l,0x12 |
|||
push hl |
|||
call _memset_callee |
|||
pop bc |
|||
;source-doc/ufi-drv/./ufi-init.c:81: if ((result = ufi_request_sense((device_config *)dev, &response)) != USB_ERR_OK) |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
push bc |
|||
call _ufi_request_sense |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
or a |
|||
jr Z,l_chufi_read_00106 |
|||
;source-doc/ufi-drv/./ufi-init.c:82: return -1; // error |
|||
ld l,0xff |
|||
jr l_chufi_read_00109 |
|||
l_chufi_read_00106: |
|||
;source-doc/ufi-drv/./ufi-init.c:86: const uint8_t sense_key = response.sense_key; |
|||
ld hl,4 |
|||
add hl, sp |
|||
ld a, (hl) |
|||
;source-doc/ufi-drv/./ufi-init.c:88: if (sense_key != 0) |
|||
and 0x0f |
|||
jr Z,l_chufi_read_00108 |
|||
;source-doc/ufi-drv/./ufi-init.c:89: return -1; |
|||
ld l,0xff |
|||
jr l_chufi_read_00109 |
|||
l_chufi_read_00108: |
|||
;source-doc/ufi-drv/./ufi-init.c:91: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_chufi_read_00109: |
|||
;source-doc/ufi-drv/./ufi-init.c:92: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
@ -0,0 +1,222 @@ |
|||
; |
|||
; Generated from source-doc/ufi-drv/./usb_cbi.c.asm -- not to be modify directly |
|||
; |
|||
; |
|||
;-------------------------------------------------------- |
|||
; File Created by SDCC : free open source ISO C Compiler |
|||
; Version 4.3.0 #14210 (Linux) |
|||
;-------------------------------------------------------- |
|||
; Processed by Z88DK |
|||
;-------------------------------------------------------- |
|||
|
|||
|
|||
;-------------------------------------------------------- |
|||
; Public variables in this module |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Externals used |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; special function registers |
|||
;-------------------------------------------------------- |
|||
_CH376_DATA_PORT .EQU 0xff88 |
|||
_CH376_COMMAND_PORT .EQU 0xff89 |
|||
_USB_MODULE_LEDS .EQU 0xff8a |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; ram data |
|||
;-------------------------------------------------------- |
|||
|
|||
#IF 0 |
|||
|
|||
; .area _INITIALIZED removed by z88dk |
|||
|
|||
_cbi2_adsc: |
|||
DEFS 8 |
|||
|
|||
#ENDIF |
|||
|
|||
;-------------------------------------------------------- |
|||
; absolute external ram data |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; global & static initialisations |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; Home |
|||
;-------------------------------------------------------- |
|||
;-------------------------------------------------------- |
|||
; code |
|||
;-------------------------------------------------------- |
|||
;source-doc/ufi-drv/./usb_cbi.c:9: usb_error usb_execute_cbi(device_config *const storage_device, |
|||
; --------------------------------- |
|||
; Function usb_execute_cbi |
|||
; --------------------------------- |
|||
_usb_execute_cbi: |
|||
push ix |
|||
ld ix,0 |
|||
add ix,sp |
|||
ld hl, -8 |
|||
add hl, sp |
|||
ld sp, hl |
|||
;source-doc/ufi-drv/./usb_cbi.c:18: const uint8_t interface_number = storage_device->interface_number; |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
ld c,l |
|||
ld b,h |
|||
inc hl |
|||
inc hl |
|||
ld e, (hl) |
|||
;source-doc/ufi-drv/./usb_cbi.c:21: adsc = cbi2_adsc; |
|||
push de |
|||
push bc |
|||
ex de, hl |
|||
ld hl,4 |
|||
add hl, sp |
|||
ex de, hl |
|||
ld bc,0x0008 |
|||
ld hl,_cbi2_adsc |
|||
ldir |
|||
pop bc |
|||
pop de |
|||
;source-doc/ufi-drv/./usb_cbi.c:22: adsc.bIndex[0] = interface_number; |
|||
ld (ix-4),e |
|||
;source-doc/ufi-drv/./usb_cbi.c:24: result = usbdev_control_transfer(storage_device, &adsc, (uint8_t *const)cmd); |
|||
ld l,(ix+6) |
|||
ld h,(ix+7) |
|||
push hl |
|||
ld hl,2 |
|||
add hl, sp |
|||
push hl |
|||
push bc |
|||
call _usbdev_control_transfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
ld a, l |
|||
;source-doc/ufi-drv/./usb_cbi.c:26: if (result == USB_ERR_STALL) { |
|||
cp 0x02 |
|||
jr NZ,l_usb_execute_cbi_00104 |
|||
;source-doc/ufi-drv/./usb_cbi.c:27: if (sense_codes != NULL) |
|||
ld a,(ix+14) |
|||
or (ix+13) |
|||
jr Z,l_usb_execute_cbi_00102 |
|||
;source-doc/ufi-drv/./usb_cbi.c:28: usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN); |
|||
ld a,0x02 |
|||
push af |
|||
inc sp |
|||
ld hl,0x0002 |
|||
push hl |
|||
ld l,(ix+13) |
|||
ld h,(ix+14) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usbdev_dat_in_trnsfer |
|||
ld hl,7 |
|||
add hl, sp |
|||
l_usb_execute_cbi_00102: |
|||
;source-doc/ufi-drv/./usb_cbi.c:30: return USB_ERR_STALL; |
|||
ld l,0x02 |
|||
jp l_usb_execute_cbi_00118 |
|||
l_usb_execute_cbi_00104: |
|||
;source-doc/ufi-drv/./usb_cbi.c:33: if (result != USB_ERR_OK) { |
|||
or a |
|||
jr Z,l_usb_execute_cbi_00106 |
|||
;source-doc/ufi-drv/./usb_cbi.c:35: return result; |
|||
ld l, a |
|||
jr l_usb_execute_cbi_00118 |
|||
l_usb_execute_cbi_00106: |
|||
;source-doc/ufi-drv/./usb_cbi.c:38: if (send) { |
|||
bit 0,(ix+8) |
|||
jr Z,l_usb_execute_cbi_00112 |
|||
;source-doc/ufi-drv/./usb_cbi.c:39: result = usbdev_blk_out_trnsfer(storage_device, buffer, buffer_size); |
|||
ld l,(ix+9) |
|||
ld h,(ix+10) |
|||
push hl |
|||
ld l,(ix+11) |
|||
ld h,(ix+12) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usbdev_blk_out_trnsfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
;source-doc/ufi-drv/./usb_cbi.c:41: if (result != USB_ERR_OK) { |
|||
ld a, l |
|||
or a |
|||
jr Z,l_usb_execute_cbi_00113 |
|||
;source-doc/ufi-drv/./usb_cbi.c:43: return result; |
|||
jr l_usb_execute_cbi_00118 |
|||
l_usb_execute_cbi_00112: |
|||
;source-doc/ufi-drv/./usb_cbi.c:46: result = usbdev_dat_in_trnsfer(storage_device, buffer, buffer_size, ENDPOINT_BULK_IN); |
|||
ld a,0x01 |
|||
push af |
|||
inc sp |
|||
ld l,(ix+9) |
|||
ld h,(ix+10) |
|||
push hl |
|||
ld l,(ix+11) |
|||
ld h,(ix+12) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usbdev_dat_in_trnsfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
;source-doc/ufi-drv/./usb_cbi.c:48: if (result != USB_ERR_OK) { |
|||
ld a, l |
|||
or a |
|||
;source-doc/ufi-drv/./usb_cbi.c:50: return result; |
|||
jr NZ,l_usb_execute_cbi_00118 |
|||
l_usb_execute_cbi_00113: |
|||
;source-doc/ufi-drv/./usb_cbi.c:54: if (sense_codes != NULL) { |
|||
ld a,(ix+14) |
|||
or (ix+13) |
|||
jr Z,l_usb_execute_cbi_00117 |
|||
;source-doc/ufi-drv/./usb_cbi.c:55: result = usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN); |
|||
ld a,0x02 |
|||
push af |
|||
inc sp |
|||
ld hl,0x0002 |
|||
push hl |
|||
ld l,(ix+13) |
|||
ld h,(ix+14) |
|||
push hl |
|||
ld l,(ix+4) |
|||
ld h,(ix+5) |
|||
push hl |
|||
call _usbdev_dat_in_trnsfer |
|||
pop af |
|||
pop af |
|||
pop af |
|||
inc sp |
|||
;source-doc/ufi-drv/./usb_cbi.c:57: if (result != USB_ERR_OK) { |
|||
ld a, l |
|||
or a |
|||
;source-doc/ufi-drv/./usb_cbi.c:59: return result; |
|||
jr NZ,l_usb_execute_cbi_00118 |
|||
l_usb_execute_cbi_00117: |
|||
;source-doc/ufi-drv/./usb_cbi.c:63: return USB_ERR_OK; |
|||
ld l,0x00 |
|||
l_usb_execute_cbi_00118: |
|||
;source-doc/ufi-drv/./usb_cbi.c:64: } |
|||
ld sp, ix |
|||
pop ix |
|||
ret |
|||
_cbi2_adsc: |
|||
DEFB +0x21 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0x00 |
|||
DEFB +0xff |
|||
DEFB +0x00 |
|||
DEFW +0x000c |
|||
@ -0,0 +1,48 @@ |
|||
; |
|||
;================================================================================================== |
|||
; CH376 NATIVE USB DRIVER |
|||
;================================================================================================== |
|||
; |
|||
|
|||
#DEFINE DEFM .DB |
|||
#DEFINE DEFB .DB |
|||
#DEFINE DEFW .DW |
|||
|
|||
_print_string .EQU PRTSTR |
|||
|
|||
_print_hex: |
|||
ld a, l |
|||
JP PRTHEXBYTE |
|||
|
|||
_delay: |
|||
push af |
|||
call DELAY |
|||
call DELAY |
|||
call DELAY |
|||
call DELAY |
|||
pop af |
|||
ret |
|||
|
|||
_delay_20ms: |
|||
LD DE, 1250 |
|||
JP VDELAY |
|||
; |
|||
; DELAY approx 60ms |
|||
_delay_short: |
|||
LD DE, 3750 |
|||
JP VDELAY |
|||
; |
|||
; DELAY approx 1/2 second |
|||
_delay_medium .EQU LDELAY |
|||
|
|||
_dio_add_entry: |
|||
LD B, H |
|||
LD C, L |
|||
JP DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE |
|||
|
|||
#include "./ch376-native/base-drv.asm" |
|||
#include "./ch376-native/print.asm" |
|||
#include "./ch376-native/cruntime.asm" |
|||
#include "./ch376-native/base-drv.s" |
|||
|
|||
CHNATIVE_INIT .EQU _chnative_init |
|||
@ -0,0 +1,284 @@ |
|||
; |
|||
;================================================================================================== |
|||
; CH376 NATIVE MASS STORAGE DRIVER |
|||
;================================================================================================== |
|||
; |
|||
|
|||
#include "./ch376-native/scsi-drv.s" |
|||
|
|||
; find and mount all Mass Storage USB devices |
|||
CHSCSI_INIT .EQU _chscsi_init |
|||
|
|||
; DRIVER FUNCTION TABLE |
|||
; |
|||
_ch_scsi_fntbl |
|||
CH_SCSI_FNTBL: |
|||
.DW CH_SCSI_STATUS |
|||
.DW CH_SCSI_RESET |
|||
.DW CH_SCSI_SEEK |
|||
.DW CH_SCSI_READ |
|||
.DW CH_SCSI_WRITE |
|||
.DW CH_SCSI_VERIFY |
|||
.DW CH_SCSI_FORMAT |
|||
.DW CH_SCSI_DEVICE |
|||
.DW CH_SCSI_MEDIA |
|||
.DW CH_SCSI_DEFMED |
|||
.DW CH_SCSI_CAP |
|||
.DW CH_SCSI_GEOM |
|||
#IF (($ - CH_SCSI_FNTBL) != (DIO_FNCNT * 2)) |
|||
.ECHO "*** INVALID CH_SCSI_FNTBL FUNCTION TABLE ***\n" |
|||
#ENDIF |
|||
|
|||
CH_SCSI_STATUS: |
|||
LD A, (IY) |
|||
XOR A |
|||
RET |
|||
|
|||
CH_SCSI_RESET: |
|||
LD A, (IY) |
|||
XOR A |
|||
RET |
|||
|
|||
; ### Function 0x12 -- Disk Seek (DIOSEEK) |
|||
; |
|||
; Inputs: |
|||
; IY: device config pointer |
|||
; DEHL: Sector Address |
|||
; |
|||
; Outputs: |
|||
; A: Status |
|||
; |
|||
; This function will set the desired sector to be used for the next I/O |
|||
; operation. The returned Status (A) is a standard HBIOS result code. |
|||
; |
|||
; The double-word Sector Address (DEHL) can represent either a Logical |
|||
; Block Address (LBA) or a Cylinder/Head/Sector (CHS). Bit 7 of D is |
|||
; set (1) for LBA mode and cleared (0) for CHS mode. |
|||
; |
|||
; For LBA mode operation, the high bit is set and the rest of the |
|||
; double-word is then treated as the logical sector address. |
|||
; |
|||
; For CHS mode operation, the Sector Address (DEHL) registers are |
|||
; interpreted as: D=Head, E=Sector, and HL=Track. All values (including |
|||
; sector) are 0 relative. |
|||
; |
|||
CH_SCSI_SEEK: |
|||
BIT 7,D ; CHECK FOR LBA FLAG |
|||
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA |
|||
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA) |
|||
EX DE, HL |
|||
|
|||
push IY |
|||
CALL _chnative_seek |
|||
RET |
|||
; |
|||
; ### Function 0x13 -- Disk Read (DIOREAD) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; D: Buffer Bank ID |
|||
; E: Sector Count |
|||
; HL: Buffer Address |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; E: Sectors Read |
|||
; |
|||
; Read Sector Count (E) sectors into the buffer located in Buffer Bank ID (D) |
|||
; at Buffer Address (HL) starting at the Current Sector. The returned |
|||
; Status (A) is a standard HBIOS result code. |
|||
; |
|||
CH_SCSI_READ: |
|||
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR |
|||
|
|||
; call scsi_read(IY, HL); |
|||
; HL = HL + 512 |
|||
push hl |
|||
push iy |
|||
call _scsi_read |
|||
ld a, l |
|||
pop hl |
|||
pop iy |
|||
ld bc, 512 |
|||
add hl, bc |
|||
ret |
|||
; |
|||
; ### Function 0x14 -- Disk Write (DIOWRITE) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; D: Buffer Bank ID |
|||
; E: Sector Count |
|||
; HL: Buffer Address |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; E: Sectors Written |
|||
; |
|||
; Write Sector Count (E) sectors from the buffer located in Buffer Bank ID (D) |
|||
; at Buffer Address (HL) starting at the Current Sector. The returned |
|||
; Status (A) is a standard HBIOS result code. |
|||
; |
|||
CH_SCSI_WRITE: |
|||
CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR |
|||
|
|||
; call scsi_write(IY, HL); |
|||
; HL = HL + 512 |
|||
push hl |
|||
push iy |
|||
call _scsi_write |
|||
ld a, l |
|||
pop hl |
|||
pop iy |
|||
ld bc, 512 |
|||
add hl, bc |
|||
ret |
|||
|
|||
CH_SCSI_VERIFY: |
|||
CH_SCSI_FORMAT: |
|||
LD A, $FF |
|||
OR A |
|||
RET |
|||
; |
|||
; ### Function 0x17 -- Disk Device (DIODEVICE) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; C: Device Attributes |
|||
; D: Device Type (DIODEV_USB) |
|||
; E: Device Number (1) |
|||
; H: Device Unit Mode (0) |
|||
; L: Device I/O Base Address |
|||
; |
|||
; Reports device information. The Status (A) is a standard |
|||
; HBIOS result code. |
|||
; |
|||
; The Device Attribute (C): |
|||
; |
|||
; | **Bits** | **Definition** | |
|||
; |---------:|--------------------------------------------------| |
|||
; | 7 | Floppy | |
|||
; | 6 | Removable | |
|||
; | 5 | High Capacity (>8 MB) | |
|||
; |
|||
; Low Capacity Devices?? |
|||
; |
|||
; | **Bits** | **Definition** | |
|||
; |---------:|--------------------------------------------------| |
|||
; | 4-3 | Form Factor: 0=8", 1=5.25", 2=3.5", 3=Other | |
|||
; | 2 | Sides: 0=SS, 1=DS | |
|||
; | 1-0 | Density: 0=SD, 1=DD, 2=HD, 3=ED | |
|||
; |
|||
; High Capacity Devices |
|||
; |
|||
; | **Bits** | **Definition** | |
|||
; |---------:|--------------------------------------------------| |
|||
; | 4 | LBA Capable | |
|||
; | 3-0 | Media Type: 0=Hard Disk, 1=CF, 2=SD, 3=USB, | |
|||
; | | 4=ROM, 5=RAM, 6=RAMF, 7=FLASH, 8=CD-ROM, | |
|||
; | | 9=Cartridge, 10=usb-scsi, 11=usb-ufi | |
|||
; |
|||
CH_SCSI_DEVICE: |
|||
LD C, %01111010 ; TODO? |
|||
LD D, DIODEV_USB |
|||
LD E, (iy+16) |
|||
LD H, 0 |
|||
LD L, 0 |
|||
XOR A |
|||
RET |
|||
; |
|||
; ### Function 0x18 -- Disk Media (DIOMEDIA) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; E: Flags |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; E: Media ID |
|||
; |
|||
; Report the Media ID (E) for the for media. If bit 0 of Flags (E) is set, |
|||
; then media discovery or verification will be performed. The Status |
|||
; (A) is a standard HBIOS result code. If there is no media in device, |
|||
; function will return an error status. |
|||
; |
|||
CH_SCSI_MEDIA: |
|||
LD E, MID_HD ;todo verify device still active? |
|||
XOR A |
|||
RET |
|||
|
|||
CH_SCSI_DEFMED: |
|||
LD A, $FF |
|||
OR A |
|||
RET |
|||
; |
|||
; ### Function 0x1A -- Disk Capacity (DIOCAPACITY) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; DEHL: Sector Count |
|||
; BC: Block Size |
|||
; |
|||
; |
|||
; Report the current media capacity information. |
|||
; |
|||
; |
|||
CH_SCSI_CAP: |
|||
push ix |
|||
ld ix, -8 ; reserve 8 bytes for |
|||
add ix, sp ; scsi_read_capacity_result |
|||
ld sp, ix |
|||
|
|||
push ix |
|||
push iy |
|||
call _get_scsi_read_capacity |
|||
pop iy |
|||
pop ix |
|||
|
|||
ld d, (ix) ; response.number_of_blocks[0] |
|||
ld e, (ix+1) ; response.number_of_blocks[1] |
|||
ld h, (ix+2) ; response.number_of_blocks[2] |
|||
ld l, (ix+3) ; response.number_of_blocks[3] |
|||
ld b, (ix+6) ; response.block_size[2] |
|||
ld c, (ix+7) ; response.block_size[3] |
|||
|
|||
ld ix, 8 |
|||
add ix, sp |
|||
ld sp, ix |
|||
pop ix |
|||
|
|||
xor a ; todo determine a drive status |
|||
ret |
|||
; |
|||
; ### Function 0x1B -- Disk Geometry (DIOGEOMETRY) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; D: Heads |
|||
; E: Sectors |
|||
; HL: Cylinder Count |
|||
; BC: Block Size |
|||
; |
|||
; Report the simulated geometry for the media. The Status (A) is a |
|||
; standard HBIOS result code. If the media is unknown, an error will be returned. |
|||
; |
|||
; ** Does not appear to be used?? |
|||
; |
|||
CH_SCSI_GEOM: |
|||
; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS |
|||
; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE |
|||
CALL CH_SCSI_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC |
|||
LD L,H ; DIVIDE BY 256 FOR # TRACKS |
|||
LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL |
|||
LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT |
|||
LD E,16 ; SECTORS / TRACK = 16 |
|||
RET ; DONE, A STILL HAS CHUSB_CAP STATUS |
|||
@ -0,0 +1,225 @@ |
|||
; |
|||
;================================================================================================== |
|||
; CH376 NATIVE MASS STORAGE DRIVER |
|||
;================================================================================================== |
|||
; |
|||
|
|||
#include "./ch376-native/ufi-drv.s" |
|||
|
|||
; find and mount all floppy USB drives |
|||
CHUFI_INIT .EQU _chufi_init |
|||
|
|||
; DRIVER FUNCTION TABLE |
|||
; |
|||
_ch_ufi_fntbl |
|||
CH_UFI_FNTBL: |
|||
.DW CH_UFI_STATUS |
|||
.DW CH_UFI_RESET |
|||
.DW CH_UFI_SEEK |
|||
.DW CH_UFI_READ |
|||
.DW CH_UFI_WRITE |
|||
.DW CH_UFI_VERIFY |
|||
.DW CH_UFI_FORMAT |
|||
.DW CH_UFI_DEVICE |
|||
.DW CH_UFI_MEDIA |
|||
.DW CH_UFI_DEFMED |
|||
.DW CH_UFI_CAP |
|||
.DW CH_UFI_GEOM |
|||
#IF (($ - CH_UFI_FNTBL) != (DIO_FNCNT * 2)) |
|||
.ECHO "*** INVALID CH_UFI_FNTBL FUNCTION TABLE ***\n" |
|||
#ENDIF |
|||
|
|||
CH_UFI_STATUS: |
|||
LD A, (IY) |
|||
XOR A |
|||
RET |
|||
|
|||
CH_UFI_RESET: |
|||
LD A, (IY) |
|||
XOR A |
|||
RET |
|||
; ### Function 0x12 -- Disk Seek (DIOSEEK) |
|||
; |
|||
; Inputs: |
|||
; IY: device config pointer |
|||
; DEHL: Sector Address |
|||
; |
|||
; Outputs: |
|||
; A: Status |
|||
; |
|||
; This function will set the desired sector to be used for the next I/O |
|||
; operation. The returned Status (A) is a standard HBIOS result code. |
|||
;if |
|||
; The double-word Sector Address (DEHL) can represent either a Logical |
|||
; Block Address (LBA) or a Cylinder/Head/Sector (CHS). Bit 7 of D is |
|||
; set (1) for LBA mode and cleared (0) for CHS mode. |
|||
; |
|||
; For LBA mode operation, the high bit is set and the rest of the |
|||
; double-word is then treated as the logical sector address. |
|||
; |
|||
; For CHS mode operation, the Sector Address (DEHL) registers are |
|||
; interpreted as: D=Head, E=Sector, and HL=Track. All values (including |
|||
; sector) are 0 relative. |
|||
; |
|||
CH_UFI_SEEK: |
|||
BIT 7, D ; CHECK FOR LBA FLAG |
|||
CALL Z, HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA - never seems to happen? |
|||
RES 7, D |
|||
EX DE, HL |
|||
|
|||
push IY |
|||
CALL _chnative_seek |
|||
RET |
|||
; |
|||
; ### Function 0x13 -- Disk Read (DIOREAD) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; D: Buffer Bank ID |
|||
; E: Sector Count |
|||
; HL: Buffer Address |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; E: Sectors Read |
|||
; |
|||
; Read Sector Count (E) sectors into the buffer located in Buffer Bank ID (D) |
|||
; at Buffer Address (HL) starting at the Current Sector. The returned |
|||
; Status (A) is a standard HBIOS result code. |
|||
; |
|||
CH_UFI_READ: |
|||
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR |
|||
|
|||
push hl |
|||
push iy |
|||
call _chufi_read |
|||
ld l, 0 |
|||
ld a, l |
|||
pop iy |
|||
pop hl |
|||
ld bc, 512 |
|||
add hl, bc |
|||
ret |
|||
|
|||
CH_UFI_WRITE: |
|||
EZ80_UTIL_DEBUG |
|||
|
|||
XOR A |
|||
RET |
|||
|
|||
CH_UFI_VERIFY: |
|||
CH_UFI_FORMAT: |
|||
LD HL, 0 |
|||
LD DE, 0 |
|||
LD BC, 0 |
|||
LD A, $FF |
|||
OR A |
|||
RET |
|||
|
|||
; ### Function 0x17 -- Disk Device (DIODEVICE) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; C: Device Attributes |
|||
; D: Device Type (DIODEV_USB) |
|||
; E: Device Number (1) |
|||
; H: Device Unit Mode (0) |
|||
; L: Device I/O Base Address |
|||
; |
|||
; Reports device information. The Status (A) is a standard |
|||
; HBIOS result code. |
|||
; |
|||
; The Device Attribute (C): |
|||
; |
|||
; | **Bits** | **Definition** | |
|||
; |---------:|--------------------------------------------------| |
|||
; | 7 | Floppy | |
|||
; | 6 | Removable | |
|||
; | 5 | High Capacity (>8 MB) | |
|||
; |
|||
; Low Capacity Devices?? |
|||
; |
|||
; | **Bits** | **Definition** | |
|||
; |---------:|--------------------------------------------------| |
|||
; | 4-3 | Form Factor: 0=8", 1=5.25", 2=3.5", 3=Other | |
|||
; | 2 | Sides: 0=SS, 1=DS | |
|||
; | 1-0 | Density: 0=SD, 1=DD, 2=HD, 3=ED | |
|||
; |
|||
; High Capacity Devices |
|||
; |
|||
; | **Bits** | **Definition** | |
|||
; |---------:|--------------------------------------------------| |
|||
; | 4 | LBA Capable | |
|||
; | 3-0 | Media Type: 0=Hard Disk, 1=CF, 2=SD, 3=USB, | |
|||
; | | 4=ROM, 5=RAM, 6=RAMF, 7=FLASH, 8=CD-ROM, | |
|||
; | | 9=Cartridge, 10=usb-scsi, 11=usb-ufi | |
|||
; |
|||
CH_UFI_DEVICE: |
|||
LD C, %01011011 |
|||
LD D, DIODEV_USB |
|||
LD E, (iy+16) |
|||
LD H, 0 |
|||
LD L, 0 |
|||
XOR A |
|||
RET |
|||
; |
|||
; ### Function 0x18 -- Disk Media (DIOMEDIA) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; E: Flags |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; E: Media ID |
|||
; |
|||
; Report the Media ID (E) for the for media. If bit 0 of Flags (E) is set, |
|||
; then media discovery or verification will be performed. The Status |
|||
; (A) is a standard HBIOS result code. If there is no media in device, |
|||
; function will return an error status. |
|||
; |
|||
CH_UFI_MEDIA: |
|||
LD E, MID_MDRAM ;todo verify device still active? |
|||
XOR A |
|||
RET |
|||
|
|||
CH_UFI_DEFMED: |
|||
LD HL, 0 |
|||
LD DE, 0 |
|||
LD BC, 0 |
|||
LD A, $FF |
|||
OR A |
|||
RET |
|||
|
|||
; |
|||
; ### Function 0x1A -- Disk Capacity (DIOCAPACITY) |
|||
; |
|||
; Inputs |
|||
; IY: device config pointer |
|||
; |
|||
; Outputs |
|||
; A: Status |
|||
; DEHL: Sector Count |
|||
; BC: Block Size |
|||
; |
|||
; |
|||
; Report the current media capacity information. |
|||
; |
|||
CH_UFI_CAP: |
|||
push iy |
|||
call _chufi_get_cap |
|||
pop iy |
|||
ld bc, 512 |
|||
xor a |
|||
ret |
|||
|
|||
CH_UFI_GEOM: |
|||
LD HL, 0 |
|||
LD DE, 0 |
|||
LD BC, 0 |
|||
LD A, $FF |
|||
OR A |
|||
RET |
|||
Loading…
Reference in new issue