diff --git a/.vscode/settings.json b/.vscode/settings.json index 7c12e6b0..70be832d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" + } } diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index 26c55e33..ae670c67 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -3407,6 +3407,7 @@ DEVTBL: ; DEVICE TABLE .DW DEV04, DEV05, DEV06, DEV07 .DW DEV08, DEV09, DEV10, DEV11 .DW DEV12, DEV13, DEV14, DEV15 + .DW DEV16 ; DEVUNK .DB "???$" DEV00 .DB "MD$" @@ -3424,7 +3425,8 @@ DEV11 .DB "IMM$" DEV12 .DB "SYQ$" DEV13 .DB "CHUSB$" DEV14 .DB "CHSD$" -DEV15 .EQU DEVUNK +DEV15 .DB "USB$" +DEV16 .EQU DEVUNK ; #ENDIF ; diff --git a/Source/Doc/SystemGuide.md b/Source/Doc/SystemGuide.md index 59b40f32..7b5862c3 100644 --- a/Source/Doc/SystemGuide.md +++ b/Source/Doc/SystemGuide.md @@ -1088,6 +1088,7 @@ below enumerates their values. | DIODEV_SYQ | 0x0C | Syquest Sparq Disk | syq.asm | | DIODEV_CHUSB | 0x0D | CH375/376 USB Disk | ch.asm | | DIODEV_CHSD | 0x0E | CH375/376 SD Card | ch.asm | +| DIODEV_USB | 0x0F | CH376 Native USB Device | ch376.asm | A fixed set of media types are defined. The currently defined media types identifiers are listed below. Each driver will support one or diff --git a/Source/HBIOS/Config/RCEZ80_std.asm b/Source/HBIOS/Config/RCEZ80_std.asm index f51f0d03..8383e087 100644 --- a/Source/HBIOS/Config/RCEZ80_std.asm +++ b/Source/HBIOS/Config/RCEZ80_std.asm @@ -82,3 +82,7 @@ SN76489ENABLE .SET FALSE ; SN: ENABLE SN76489 SOUND DRIVER AY38910ENABLE .SET FALSE ; AY: ENABLE AY-3-8910 / YM2149 SOUND DRIVER AYMODE .SET AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC|MBC|DUO|NABU] AY_FORCE .SET FALSE ; AY: BYPASS AUTO-DETECT, FORCED PRESENT + +CHNATIVEENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE USB DRIVER +CHSCSIENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE) +CHUFIENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE) diff --git a/Source/HBIOS/cfg_MASTER.asm b/Source/HBIOS/cfg_MASTER.asm index 4c20af26..2caf43cf 100644 --- a/Source/HBIOS/cfg_MASTER.asm +++ b/Source/HBIOS/cfg_MASTER.asm @@ -501,3 +501,7 @@ EZ80_WSMD_TYP .EQU EZ80WSMD_CALC ; BUS WAIT STATE CONFIG: EZ80WSMD_[CALC|CYCLES| EZ80_FLSH_WS .EQU 1 ; WAIT STATES FOR ON CHIP FLASH (0-7) EZ80_FLSH_MIN_NS .EQU 60 ; MINIMUM WAIT STATES TO APPLY TO ON-CHIP FLASH, IF EZ80_WSMD_TYP = EZ80WSMD_CALC EZ80_FWSMD_TYP .EQU EZ80WSMD_CALC ; WAIT STATE TYPE: EZ80RMMD_[CALC|WAIT] (CYCLES NOT ALLOWED) + +CHNATIVEENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER +CHSCSIENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE) +CHUFIENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE) diff --git a/Source/HBIOS/ch376-native/Makefile b/Source/HBIOS/ch376-native/Makefile new file mode 100644 index 00000000..6a08c627 --- /dev/null +++ b/Source/HBIOS/ch376-native/Makefile @@ -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" diff --git a/Source/HBIOS/ch376-native/base-drv.asm b/Source/HBIOS/ch376-native/base-drv.asm new file mode 100644 index 00000000..8990bf92 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv.asm @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv.s b/Source/HBIOS/ch376-native/base-drv.s new file mode 100644 index 00000000..6aa5aa97 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv.s @@ -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" diff --git a/Source/HBIOS/ch376-native/base-drv/ch376.c.s b/Source/HBIOS/ch376-native/base-drv/ch376.c.s new file mode 100644 index 00000000..ea6a174c --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/ch376.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 diff --git a/Source/HBIOS/ch376-native/base-drv/class_hub.c.s b/Source/HBIOS/ch376-native/base-drv/class_hub.c.s new file mode 100644 index 00000000..37be1196 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/class_hub.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/dev_transfers.c.s b/Source/HBIOS/ch376-native/base-drv/dev_transfers.c.s new file mode 100644 index 00000000..200bb6b2 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/dev_transfers.c.s @@ -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) diff --git a/Source/HBIOS/ch376-native/base-drv/enumerate.c.s b/Source/HBIOS/ch376-native/base-drv/enumerate.c.s new file mode 100644 index 00000000..34a3b265 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/enumerate.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/enumerate_hub.c.s b/Source/HBIOS/ch376-native/base-drv/enumerate_hub.c.s new file mode 100644 index 00000000..7974a653 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/enumerate_hub.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/enumerate_storage.c.s b/Source/HBIOS/ch376-native/base-drv/enumerate_storage.c.s new file mode 100644 index 00000000..0c6b3b90 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/enumerate_storage.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/print.c.s b/Source/HBIOS/ch376-native/base-drv/print.c.s new file mode 100644 index 00000000..2bfe74db --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/print.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/protocol.c.s b/Source/HBIOS/ch376-native/base-drv/protocol.c.s new file mode 100644 index 00000000..6d9e0b73 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/protocol.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/transfers.c.s b/Source/HBIOS/ch376-native/base-drv/transfers.c.s new file mode 100644 index 00000000..fc056368 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/transfers.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/usb-base-drv.c.s b/Source/HBIOS/ch376-native/base-drv/usb-base-drv.c.s new file mode 100644 index 00000000..46c575d9 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/usb-base-drv.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/usb-init.c.s b/Source/HBIOS/ch376-native/base-drv/usb-init.c.s new file mode 100644 index 00000000..a376087d --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/usb-init.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/usb_state.c.s b/Source/HBIOS/ch376-native/base-drv/usb_state.c.s new file mode 100644 index 00000000..363e00b9 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/usb_state.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/base-drv/work-area.c.s b/Source/HBIOS/ch376-native/base-drv/work-area.c.s new file mode 100644 index 00000000..7e5fcc29 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/work-area.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/cruntime.asm b/Source/HBIOS/ch376-native/cruntime.asm new file mode 100644 index 00000000..29e2060e --- /dev/null +++ b/Source/HBIOS/ch376-native/cruntime.asm @@ -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 diff --git a/Source/HBIOS/ch376-native/print.asm b/Source/HBIOS/ch376-native/print.asm new file mode 100644 index 00000000..70acafe7 --- /dev/null +++ b/Source/HBIOS/ch376-native/print.asm @@ -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 diff --git a/Source/HBIOS/ch376-native/root.md b/Source/HBIOS/ch376-native/root.md new file mode 100644 index 00000000..e69de29b diff --git a/Source/HBIOS/ch376-native/scsi-drv.s b/Source/HBIOS/ch376-native/scsi-drv.s new file mode 100644 index 00000000..65cee345 --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv.s @@ -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" diff --git a/Source/HBIOS/ch376-native/scsi-drv/class_scsi.c.s b/Source/HBIOS/ch376-native/scsi-drv/class_scsi.c.s new file mode 100644 index 00000000..119505b8 --- /dev/null +++ b/Source/HBIOS/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 diff --git a/Source/HBIOS/ch376-native/scsi-drv/init.c.s b/Source/HBIOS/ch376-native/scsi-drv/init.c.s new file mode 100644 index 00000000..5a8f145d --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv/init.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/scsi-drv/scsi-init.c.s b/Source/HBIOS/ch376-native/scsi-drv/scsi-init.c.s new file mode 100644 index 00000000..673285b5 --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv/scsi-init.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/.clang-format b/Source/HBIOS/ch376-native/source-doc/.clang-format new file mode 100644 index 00000000..74924c0f --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/.clang-format @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.c b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.c new file mode 100644 index 00000000..7f4dca77 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.c @@ -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(); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.h b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.h new file mode 100644 index 00000000..88d38dc5 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.h @@ -0,0 +1,175 @@ + +#ifndef __CH376 +#define __CH376 + +#include "ch376inc.h" +#include "delay.h" +#include + +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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/ch376inc.h b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376inc.h new file mode 100644 index 00000000..db4270a3 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376inc.h @@ -0,0 +1,1311 @@ +/* C Define for CH376 */ +/* Website: http://wch.cn */ +/* Email: tech@wch.cn */ +/* Author: W.ch 2008.10 */ +/* V1.0 for CH376 */ + +/* Oringinal file at + * https://github.com/changleo828/BOSSEN_USB_FOR_WT/blob/master/code/CH376INC.H + */ +/* google translated */ +/* other changes by Dean Netherton, 2022 */ + +#ifndef _CH376INC_H__ +#define _CH376INC_H__ + +#ifdef _cplusplus +extern " C " { +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Common types and constant definitions */ + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif + +#ifndef UINT8 +typedef unsigned char UINT8; +#endif +#ifndef UINT16 +typedef unsigned short UINT16; +#endif +#ifndef UINT32 +typedef unsigned long UINT32; +#endif +#ifndef PUINT8 +typedef unsigned char *PUINT8; +#endif +#ifndef PUINT16 +typedef unsigned short *PUINT16; +#endif +#ifndef PUINT32 +typedef unsigned long *PUINT32; +#endif +#ifndef UINT8V +typedef unsigned char volatile UINT8V; +#endif +#ifndef PUINT8V +typedef unsigned char volatile *PUINT8V; +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Hardware features */ + +/* USB single data packet, the maximum length of the data block, the length of + * the default buffer */ + +#define CH376_DAT_BLOCK_LEN 0x40 + +/* ************************************************ + * **************************************************** ***************** */ +/* command code */ +/* Some commands are compatible with CH375 chip, but the input data or output + * data may be partially different) */ +/* A command sequence of operations consists of: + * A command code (for the serial port mode, two synchronization codes are + * required before the command code), Several input data (can be 0), Generate an + * interrupt notification or several output data (can be 0), choose one of the + * two, if there is an interrupt notification, there must be no output data, and + * if there is output data, no interrupt will be generated Only the + * CMD01_WR_REQ_DATA command is an exception, the sequence includes: one command + * code, one output data, several input data Command code naming rules: + * CMDxy_NAME Where x and y are numbers, x indicates the minimum number of input + * data (bytes), y indicates the minimum output data (bytes), if y is H, it + * indicates that an interrupt notification is generated, Some commands can read + * and write data blocks of 0 to multiple bytes, and the number of bytes of the + * data block itself is not included in the above x or y */ +/* This file will also provide a command code format compatible with the CH375 + * chip command code by default (that is, after removing x and y). If you don't + * need it, you can defineNO_CH375_COMPATIBLE_prohibit */ + +/* ************************************************ + * **************************************************** ***************** */ +/* Main commands (manual 1), commonly used */ + +/* Get the chip and firmware version + * Output: version number (bit 7 is 0, bit 6 is 1, bit 5~bit 0 is the version + * number) The value of the version number returned by CH376 is 041H, that is, + * the version number is 01H */ +#define CMD01_GET_IC_VER 0x01 + +/* Serial port mode: set the serial port communication baud rate (the default + baud rate after power-on or reset is 9600bps, selected by D4/D5/D6 pins) + * input: baud rate division factor, baud rate division constant + * output: operation status (CMD_RET_SUCCESS or CMD_RET_ABORT, other values + ​​indicate that the operation is not + * completed) */ +#define CMD21_SET_BAUDRATE 0x02 + +/* Enter sleep state */ +#define CMD00_ENTER_SLEEP 0x03 + +/* perform a hardware reset */ +#define CMD00_RESET_ALL 0x05 + +/* Test the communication interface and working status + * input: any data + * output: bitwise negation of the input data */ +#define CMD11_CHECK_EXIST 0x06 + +/* Device mode: set the way to check the USB bus suspend state + * Input: data 10H, check method + * 00H=do not check for USB suspend, 04H=check for USB suspend at 50mS + * intervals, 05H=check for USB suspend at 10mS intervals + */ +#define CMD20_CHK_SUSPEND 0x0B + +#define CMD20_SET_SDO_INT 0x0B /* SPI interface mode: set the interrupt mode of the SDO pin of SPI */ +/* input: data 16H, interrupt mode */ +/* 10H=SDO pin is disabled for interrupt output, tri-state output is disabled + * when SCS chip selection is invalid, 90H=SDO pin is also used as interrupt + * request output when SCS chip selection is invalid */ + +#define CMD14_GET_FILE_SIZE 0x0C /* Host file mode: get current file length */ +/* input: data 68H */ +/* Output: current file length (total length 32 bits, low byte first) */ + +#define CMD50_SET_FILE_SIZE 0x0D /* host file mode: set current file length */ +/* Input: data 68H, current file length (total length 32 bits, low byte first) + */ + +/* Set USB working mode + * input: mode code + * 00H=Device mode not enabled + * 01H=Device mode enabled and using external firmware mode (serial port not + * supported) 02H=Device mode enabled and using built-in firmware mode 03H=SD + * card host mode/inactive host mode, used to manage and access files in SD card + * 04H=Host mode not enabled + * 05H=Host mode enabled + * 06H=Host mode enabled and SOF packet generated automatically + * 07H=Host mode enabled and USB bus reset + * output: operation status (CMD_RET_SUCCESS or CMD_RET_ABORT, other values + * ​​indicate that the operation is not completed) */ +#define CMD11_SET_USB_MODE 0x15 + +#define CMD01_GET_STATUS 0x22 /* Get interrupt status and cancel interrupt request */ +/* output: interrupt status */ + +#define CMD00_UNLOCK_USB \ + 0x23 /* Device mode: release the current USB buffer \ + */ + +#define CMD01_RD_USB_DATA0 \ + 0x27 /* Read data block from current USB interrupt endpoint buffer or host \ + endpoint receive buffer */ +/* output: length, data stream */ + +#define CMD01_RD_USB_DATA \ + 0x28 /* Device mode: read the data block from the endpoint buffer of the \ + current USB interrupt, and release the buffer, equivalent to \ + CMD01_RD_USB_DATA0 + CMD00_UNLOCK_USB */ +/* output: length, data stream */ + +#define CMD10_WR_USB_DATA7 \ + 0x2B /* Device mode: write data block to the send buffer of USB endpoint 2 \ + */ +/* input: length, data stream */ + +#define CMD10_WR_HOST_DATA 0x2C /* Write a data block to the send buffer of the USB host endpoint */ +/* input: length, data stream */ + +#define CMD01_WR_REQ_DATA 0x2D /* Write the requested data block to the internal specified buffer */ +/* output: length */ +/* input: data stream */ + +#define CMD20_WR_OFS_DATA \ + 0x2E /* Write a data block to the specified offset address in the internal \ + buffer */ +/* input: offset, length, stream */ + +#define CMD10_SET_FILE_NAME 0x2F /* Host file mode: set the filename of the file to be operated on */ +/* Input: 0-terminated string (no more than 14 characters including terminator + * 0) */ + +/* ************************************************ + * **************************************************** ***************** */ +/* Main command (Manual 1), commonly used, the following commands always + * generate an interrupt notification at the end of the operation, and there is + * always no output data */ + +#define CMD0H_DISK_CONNECT \ + 0x30 /* host file mode / SD card not supported: check if disk is connected \ + */ +/* output interrupt */ + +#define CMD0H_DISK_MOUNT 0x31 /* host file mode: initialize disk and test if disk is ready */ +/* output interrupt */ + +/* Host file mode : open files or directories(folders), or enumerate files and + * directories(folders) output interrupt */ +#define CMD0H_FILE_OPEN 0x32 + +#define CMD0H_FILE_ENUM_GO \ + 0x33 /* Host file mode: continue enumerating files and directories (folders) \ + */ +/* output interrupt */ + +#define CMD0H_FILE_CREATE \ + 0x34 /* Host file mode: create a new file, if the file already exists, \ + delete it first */ +/* output interrupt */ + +#define CMD0H_FILE_ERASE \ + 0x35 /* Host file mode: delete the file, if it is already opened, delete it \ + directly, otherwise the file will be opened first and then deleted, \ + and the subdirectory must be opened first */ +/* output interrupt */ + +#define CMD1H_FILE_CLOSE \ + 0x36 /* Host file mode: close the currently opened file or directory \ + (folder) */ +/* input: whether to allow to update file length */ +/* 00H=Disable update length, 01H=Allow update length */ +/* output interrupt */ + +#define CMD1H_DIR_INFO_READ 0x37 /* Host file mode: read file directory information */ +/* Input: Specify the index number of the directory information structure to be + * read in the sector */ +/* The range of the index number is 00H~0FH, and the index number 0FFH is the + * currently opened file */ +/* output interrupt */ + +#define CMD0H_DIR_INFO_SAVE \ + 0x38 /*Host file mode : save file directory information */ /* output \ + interrupt */ + +#define CMD4H_BYTE_LOCATE 0x39 /* host file mode: move current file pointer in bytes */ +/* Input: offset bytes (total length 32 bits, low byte first) */ +/* output interrupt */ + +#define CMD2H_BYTE_READ 0x3A /* host file mode: read data block from current position in bytes */ +/* Input: The number of bytes requested to be read (total length is 16 bits, low + * byte first) */ +/* output interrupt */ + +#define CMD0H_BYTE_RD_GO 0x3B /* host file mode: continue byte read */ +/* output interrupt */ + +#define CMD2H_BYTE_WRITE 0x3C /* Host file mode: write data block to current location in bytes */ +/* Input: The number of bytes requested to be written (total length is 16 bits, + * low byte first) */ +/* output interrupt */ + +#define CMD0H_BYTE_WR_GO 0x3D /* host file mode: continue byte write */ +/* output interrupt */ + +#define CMD0H_DISK_CAPACITY 0x3E /* host file mode: query disk physical capacity */ +/* output interrupt */ + +#define CMD0H_DISK_QUERY \ + 0x3F /* Host file mode: query disk space information \ + */ +/* output interrupt */ + +#define CMD0H_DIR_CREATE \ + 0x40 /* Host file mode: create a new directory (folder) and open it, if the \ + * directory already exists, open it directly \ + */ +/* output interrupt */ + +#define CMD4H_SEC_LOCATE 0x4A /* Host file mode: move the current file pointer in sectors */ +/* Input: number of offset sectors (total length 32 bits, low byte first) */ +/* output interrupt */ + +#define CMD1H_SEC_READ \ + 0x4B /* host file mode / SD card not supported: read data blocks from \ + current location in sectors */ +/* input: the number of sectors requested to be read */ +/* output interrupt */ + +#define CMD1H_SEC_WRITE \ + 0x4C /* host file mode/SD card not supported: write data block at current \ + location in sectors */ +/* input: the number of sectors requested to be written */ +/* output interrupt */ + +#define CMD0H_DISK_BOC_CMD \ + 0x50 /* host mode/SD card not supported: command to execute BulkOnly \ + * transfer protocol for USB storage \ + */ +/* output interrupt */ + +#define CMD5H_DISK_READ \ + 0x54 /* host mode/SD card not supported: read physical sectors from USB \ + storage */ +/* Input: LBA physical sector address (total length 32 bits, low byte first), + * sector number (01H~FFH) */ +/* output interrupt */ + +#define CMD0H_DISK_RD_GO \ + 0x55 /* Host mode/SD card not supported: continue to perform physical sector \ + read operation of USB storage */ +/* output interrupt */ + +#define CMD5H_DISK_WRITE \ + 0x56 /* Host mode/SD card not supported: write physical sector to USB \ + storage */ +/* Input: LBA physical sector address (total length 32 bits, low byte first), + * sector number (01H~FFH) */ +/* output interrupt */ + +#define CMD0H_DISK_WR_GO \ + 0x57 /* Host mode/SD card not supported: continue to perform physical sector \ + write operation of USB storage */ +/* output interrupt */ + +/* ************************************************ + * **************************************************** ***************** */ +/* Auxiliary command (manual 2), not commonly used or for compatibility with + * CH375 and CH372 */ + +#define CMD10_SET_USB_SPEED \ + 0x04 /* Set the USB bus speed, it will automatically return to 12Mbps full \ + speed every time CMD11_SET_USB_MODE sets the USB working mode */ +/* input: bus speed code */ +/* 00H=12Mbps full speed FullSpeed ​​(default value), 01H=1.5Mbps (modify + * frequency only), 02H=1.5Mbps low speed LowSpeed ​​*/ + +#define CMD11_GET_DEV_RATE \ + 0x0A /* Host mode: Get the data rate type of the currently connected USB \ + device */ +/* input: data 07H */ +/* output: data rate type */ +/* If bit 4 is 1, it is a 1.5Mbps low-speed USB device, otherwise it is a 12Mbps + * full-speed USB device */ + +#define CMD11_GET_TOGGLE 0x0A /* Get the synchronization status of the OUT transaction */ +/* input: data 1AH */ +/* output: sync status */ +/* If bit 4 is 1, the OUT transaction is synchronized, otherwise the OUT + * transaction is not synchronized */ + +#define CMD11_READ_VAR8 \ + 0x0A /* Read the specified 8-bit file system variable \ + */ +/* input: variable address */ +/* output: data */ + +/* #define CMD11_GET_MAX_LUN = CMD11_READ_VAR8( VAR_UDISK_LUN ) */ +/* Host mode: Get the maximum and current logical unit number of USB storage */ + +#define CMD20_SET_RETRY \ + 0x0B /* Host mode: set the number of retries for USB transaction operations \ + */ +/* Input: data 25H, number of retries */ +/* Bit 7 is 0, no retry when receiving NAK, + bit 7 is 1, bit 6 is 0, infinite retry when receiving NAK, + bit 7 is 1, bit 6 is 1, retry for up to 3 seconds when receiving NAK, + bit 5~bit 0 is the number of retries after timeout */ + +#define CMD20_WRITE_VAR8 \ + 0x0B /* Set the specified 8-bit file system variable \ + */ +/* input: variable address, data */ + +/* #define CMD20_SET_DISK_LUN = CMD20_WRITE_VAR8( VAR_UDISK_LUN ) */ +/* Host mode: set the current logical unit number of the USB memory */ + +#define CMD14_READ_VAR32 0x0C /* Read the specified 32-bit file system variable */ +/* input: variable address */ +/* output: data (total length 32 bits, low byte first) */ + +#define CMD50_WRITE_VAR32 0x0D /* Set the specified 32-bit file system variable */ +/* Input: variable address, data (total length 32 bits, low byte first) */ + +#define CMD01_DELAY_100US 0x0F /* Delay 100uS (serial port not supported) */ +/* Output: output 0 during the delay, output non-0 after the delay */ + +#define CMD40_SET_USB_ID 0x12 /* Device Mode: Set USB Vendor VID and Product PID */ +/* Input: Manufacturer ID low byte, Manufacturer ID high byte, Product ID low + * byte, Product ID high byte */ + +#define CMD10_SET_USB_ADDR 0x13 /* Set USB address */ +/* input: address value */ + +#define CMD01_TEST_CONNECT \ + 0x16 /* host mode/SD card not supported: check USB device connection status \ + */ +/* output: status (USB_INT_CONNECT or USB_INT_DISCONNECT or USB_INT_USB_READY, + * other values ​​indicate that the operation is not complete) */ + +#define CMD00_ABORT_NAK 0x17 /* Host mode: Abort current NAK retry */ + +#define CMD10_SET_ENDP2 \ + 0x18 /* Device mode (serial port not supported): set the receiver for USB \ + endpoint 0 */ +/* input: how it works */ +/* If bit 7 is 1, bit 6 is the synchronization trigger bit, otherwise the + * synchronization trigger bit remains unchanged */ +/* Bit 3~Bit 0 is the transaction response mode: 0000-ready ACK, 1110-busy NAK, + * 1111-error STALL */ + +#define CMD10_SET_ENDP3 \ + 0x19 /* Device mode (serial port not supported): set the transmitter of USB \ + endpoint 0 */ +/* input: how it works */ +/* If bit 7 is 1, bit 6 is the synchronization trigger bit, otherwise the + * synchronization trigger bit remains unchanged */ +/* Bit 3~Bit 0 is the transaction response mode: 0000~1000-Ready ACK, 1110-Busy + * NAK, 1111-Error STALL */ + +#define CMD10_SET_ENDP4 \ + 0x1A /*Device mode(serial port not supported) : set the receiver of USB endpoint 1 */ /* input: how it works */ +/* If bit 7 is 1, bit 6 is the synchronization trigger bit, otherwise the + * synchronization trigger bit remains unchanged */ +/* Bit 3~Bit 0 is the transaction response mode: 0000-ready ACK, 1110-busy NAK, + * 1111-error STALL */ + +#define CMD10_SET_ENDP5 \ + 0x1B /* Device mode (serial port not supported): set the transmitter of USB \ + endpoint 1 */ +/* input: how it works */ +/* If bit 7 is 1, bit 6 is the synchronization trigger bit, otherwise the + * synchronization trigger bit remains unchanged */ +/* Bit 3~Bit 0 is the transaction response mode: 0000~1000-Ready ACK, 1110-Busy + * NAK, 1111-Error STALL */ + +#define CMD10_SET_ENDP6 0x1C /* Set the receiver for USB endpoint 2/host endpoint */ +/* input: how it works */ +/* If bit 7 is 1, bit 6 is the synchronization trigger bit, otherwise the + * synchronization trigger bit remains unchanged */ +/* Bit 3~Bit 0 is the transaction response mode: 0000-ready ACK, 1101-ready but + * not returning ACK, 1110-busy NAK, 1111-error STALL */ + +#define CMD10_SET_ENDP7 0x1D /* Set the transmitter for USB endpoint 2/host endpoint */ +/* input: how it works */ +/* If bit 7 is 1, bit 6 is the synchronization trigger bit, otherwise the + * synchronization trigger bit remains unchanged */ +/* Bit 3~Bit 0 is the transaction response mode: 0000-ready ACK, 1101-ready but + * no response, 1110-busy NAK, 1111-error STALL + */ + +#define CMD00_DIRTY_BUFFER 0x25 /* Host file mode: clear internal disk and file buffers */ + +#define CMD10_WR_USB_DATA3 \ + 0x29 /* Device mode (serial port not supported): write data block to the \ + * send buffer of USB endpoint 0 \ + */ +/* input: length, data stream */ + +#define CMD10_WR_USB_DATA5 \ + 0x2A /* Device mode (serial port not supported): write data block to the \ + * send buffer of USB endpoint 1 \ + */ +/* input: length, data stream */ + +/* ************************************************ + * **************************************************** ***************** */ +/* Auxiliary commands (manual 2), not commonly used or for compatibility with + * CH375 and CH372, the following commands always generate an interrupt + * notification at the end of the operation, and always have no output data */ + +#define CMD1H_CLR_STALL 0x41 /* host mode: control transfer - clear endpoint error */ +/* input: endpoint number */ +/* output interrupt */ + +#define CMD1H_SET_ADDRESS 0x45 /* host mode: control transfer - set usb address */ +/* input: address value */ +/* output interrupt */ + +#define CMD1H_GET_DESCR \ + 0x46 /* host mode: control transfer - get descriptor \ + */ +/* input: descriptor type */ +/* output interrupt */ + +#define CMD1H_SET_CONFIG 0x49 /* host mode: control transfer - set usb configuration */ +/* input: config value */ +/* output interrupt */ + +#define CMD0H_AUTO_SETUP 0x4D /* host mode/SD card not supported: auto configure USB device */ +/* output interrupt */ + +#define CMD2H_ISSUE_TKN_X \ + 0x4E /* Host mode: issue sync token, execute transaction, this command can \ + replace CMD10_SET_ENDP6/CMD10_SET_ENDP7 + CMD1H_ISSUE_TOKEN */ +/* input: sync flag, transaction attributes */ +/* Bit 7 of the synchronization flag is the synchronization trigger bit of the + * host endpoint IN, bit 6 is the synchronization trigger bit of the host + * endpoint OUT, bit 5~bit 0 must be 0 */ +/* The lower 4 bits of the transaction attribute are the token, and the upper 4 + * bits are the endpoint number */ +/* output interrupt */ + +#define CMD1H_ISSUE_TOKEN \ + 0x4F /* Host mode: issue token, execute transaction, it is recommended to \ + * use CMD2H_ISSUE_TKN_X command \ + */ +/* input: transaction properties */ +/* The lower 4 bits are the token, the upper 4 bits are the endpoint number */ +/* output interrupt */ + +#define CMD0H_DISK_INIT 0x51 /* host mode/SD card not supported: initialize USB storage */ +/* output interrupt */ + +#define CMD0H_DISK_RESET \ + 0x52 /* host mode/SD card not supported: control transfer - reset usb \ + storage */ +/* output interrupt */ + +#define CMD0H_DISK_SIZE 0x53 /* Host mode/SD card not supported: Get the capacity of USB storage */ +/* output interrupt */ + +#define CMD0H_DISK_INQUIRY \ + 0x58 /* host mode/SD card not supported: query USB storage characteristics \ + */ +/* output interrupt */ + +#define CMD0H_DISK_READY 0x59 /* host mode/SD card not supported: check usb storage ready */ +/* output interrupt */ + +#define CMD0H_DISK_R_SENSE 0x5A /* host mode /SD card not supported: check usb storage error */ +/* output interrupt */ + +#define CMD0H_RD_DISK_SEC \ + 0x5B /* Host file mode: read one sector of data from disk into internal \ + buffer */ +/* output interrupt */ + +#define CMD0H_WR_DISK_SEC \ + 0x5C /* Host file mode: write data of one sector of internal buffer to disk \ + */ +/* output interrupt */ + +#define CMD0H_DISK_MAX_LUN \ + 0x5D /* Host mode: control transfer - get the maximum logical unit number of \ + USB storage */ +/* output interrupt */ + +/* ************************************************ + * **************************************************** ***************** */ +/* The following definitions are only for compatibility with the command name + * format in the INCLUDE file of CH375 */ + +#ifndef NO_CH375_COMPATIBLE_ +#define CH_CMD_GET_IC_VER CMD01_GET_IC_VER +#define CH_CMD_SET_BAUDRATE CMD21_SET_BAUDRATE +#define CH_CMD_ENTER_SLEEP CMD00_ENTER_SLEEP +#define CH_CMD_RESET_ALL CMD00_RESET_ALL +#define CH_CMD_CHECK_EXIST CMD11_CHECK_EXIST +#define CH_CMD_CHK_SUSPEND CMD20_CHK_SUSPEND +#define CH_CMD_SET_SDO_INT CMD20_SET_SDO_INT +#define CH_CMD_GET_FILE_SIZE CMD14_GET_FILE_SIZE +#define CH_CMD_SET_FILE_SIZE CMD50_SET_FILE_SIZE +#define CH_CMD_SET_USB_MODE CMD11_SET_USB_MODE +#define CH_CMD_GET_STATUS CMD01_GET_STATUS +#define CH_CMD_UNLOCK_USB CMD00_UNLOCK_USB +#define CH_CMD_RD_USB_DATA0 CMD01_RD_USB_DATA0 +#define CH_CMD_RD_USB_DATA CMD01_RD_USB_DATA +#define CH_CMD_WR_USB_DATA7 CMD10_WR_USB_DATA7 +#define CH_CMD_WR_HOST_DATA CMD10_WR_HOST_DATA +#define CH_CMD_WR_REQ_DATA CMD01_WR_REQ_DATA +#define CH_CMD_WR_OFS_DATA CMD20_WR_OFS_DATA +#define CH_CMD_SET_FILE_NAME CMD10_SET_FILE_NAME +#define CH_CMD_DISK_CONNECT CMD0H_DISK_CONNECT +#define CH_CMD_DISK_MOUNT CMD0H_DISK_MOUNT +#define CH_CMD_FILE_OPEN CMD0H_FILE_OPEN +#define CH_CMD_FILE_ENUM_GO CMD0H_FILE_ENUM_GO +#define CH_CMD_FILE_CREATE CMD0H_FILE_CREATE +#define CH_CMD_FILE_ERASE CMD0H_FILE_ERASE +#define CH_CMD_FILE_CLOSE CMD1H_FILE_CLOSE +#define CH_CMD_DIR_INFO_READ CMD1H_DIR_INFO_READ +#define CH_CMD_DIR_INFO_SAVE CMD0H_DIR_INFO_SAVE +#define CH_CMD_BYTE_LOCATE CMD4H_BYTE_LOCATE +#define CH_CMD_BYTE_READ CMD2H_BYTE_READ +#define CH_CMD_BYTE_RD_GO CMD0H_BYTE_RD_GO +#define CH_CMD_BYTE_WRITE CMD2H_BYTE_WRITE +#define CH_CMD_BYTE_WR_GO CMD0H_BYTE_WR_GO +#define CH_CMD_DISK_CAPACITY CMD0H_DISK_CAPACITY +#define CH_CMD_DISK_QUERY CMD0H_DISK_QUERY +#define CH_CMD_DIR_CREATE CMD0H_DIR_CREATE +#define CH_CMD_SEC_LOCATE CMD4H_SEC_LOCATE +#define CH_CMD_SEC_READ CMD1H_SEC_READ +#define CH_CMD_SEC_WRITE CMD1H_SEC_WRITE +#define CH_CMD_DISK_BOC_CMD CMD0H_DISK_BOC_CMD +#define CH_CMD_DISK_READ CMD5H_DISK_READ +#define CH_CMD_DISK_RD_GO CMD0H_DISK_RD_GO +#define CH_CMD_DISK_WRITE CMD5H_DISK_WRITE +#define CH_CMD_DISK_WR_GO CMD0H_DISK_WR_GO +#define CH_CMD_SET_USB_SPEED CMD10_SET_USB_SPEED +#define CH_CMD_GET_DEV_RATE CMD11_GET_DEV_RATE +#define CH_CMD_GET_TOGGLE CMD11_GET_TOGGLE +#define CH_CMD_READ_VAR8 CMD11_READ_VAR8 +#define CH_CMD_SET_RETRY CMD20_SET_RETRY +#define CH_CMD_WRITE_VAR8 CMD20_WRITE_VAR8 +#define CH_CMD_READ_VAR32 CMD14_READ_VAR32 +#define CH_CMD_WRITE_VAR32 CMD50_WRITE_VAR32 +#define CH_CMD_DELAY_100US CMD01_DELAY_100US +#define CH_CMD_SET_USB_ID CMD40_SET_USB_ID +#define CH_CMD_SET_USB_ADDR CMD10_SET_USB_ADDR +#define CH_CMD_TEST_CONNECT CMD01_TEST_CONNECT +#define CH_CMD_ABORT_NAK CMD00_ABORT_NAK +#define CH_CMD_SET_ENDP2 CMD10_SET_ENDP2 +#define CH_CMD_SET_ENDP3 CMD10_SET_ENDP3 +#define CH_CMD_SET_ENDP4 CMD10_SET_ENDP4 +#define CH_CMD_SET_ENDP5 CMD10_SET_ENDP5 +#define CH_CMD_SET_ENDP6 CMD10_SET_ENDP6 +#define CH_CMD_SET_ENDP7 CMD10_SET_ENDP7 +#define CH_CMD_DIRTY_BUFFER CMD00_DIRTY_BUFFER +#define CH_CMD_WR_USB_DATA3 CMD10_WR_USB_DATA3 +#define CH_CMD_WR_USB_DATA5 CMD10_WR_USB_DATA5 +#define CH_CMD_CLR_STALL CMD1H_CLR_STALL +#define CH_CMD_SET_ADDRESS CMD1H_SET_ADDRESS +#define CH_CMD_GET_DESCR CMD1H_GET_DESCR +#define CH_CMD_SET_CONFIG CMD1H_SET_CONFIG +#define CH_CMD_AUTO_SETUP CMD0H_AUTO_SETUP +#define CH_CMD_ISSUE_TKN_X CMD2H_ISSUE_TKN_X +#define CH_CMD_ISSUE_TOKEN CMD1H_ISSUE_TOKEN +#define CH_CMD_DISK_INIT CMD0H_DISK_INIT +#define CH_CMD_DISK_RESET CMD0H_DISK_RESET +#define CH_CMD_DISK_SIZE CMD0H_DISK_SIZE +#define CH_CMD_DISK_INQUIRY CMD0H_DISK_INQUIRY +#define CH_CMD_DISK_READY CMD0H_DISK_READY +#define CH_CMD_DISK_R_SENSE CMD0H_DISK_R_SENSE +#define CH_CMD_RD_DISK_SEC CMD0H_RD_DISK_SEC +#define CH_CMD_WR_DISK_SEC CMD0H_WR_DISK_SEC +#define CH_CMD_DISK_MAX_LUN CMD0H_DISK_MAX_LUN +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Parallel port mode, bit definition of status port (read command port) */ +#ifndef PARA_STATE_INTB +#define PARA_STATE_INTB 0x80 /* Bit 7 of parallel port status port: interrupt flag, active low */ +#define PARA_STATE_BUSY 0x10 /* Bit 4 of parallel port status port: busy flag, active high */ +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Serial mode, boot synchronization code before the operation command */ +#ifndef SER_CMD_TIMEOUT +#define SER_CMD_TIMEOUT \ + 32 /* Serial command timeout time, the unit is mS, the interval between \ + synchronization codes and between synchronization codes and command \ + codes should be as short as possible, and the processing method after \ + timeout is to discard */ +#define SER_SYNC_CODE1 0x57 /* The first serial port synchronization code to start the operation */ +#define SER_SYNC_CODE2 \ + 0xAB /* The second serial port synchronization code to start the operation \ + */ +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Operation status */ + +#ifndef CH_CMD_RET_SUCCESS +#define CH_CMD_RET_SUCCESS 0x51 /* Command operation succeeded */ +#define CH_CMD_RET_ABORT 0x5F /* Command operation failed */ +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* USB interrupt status */ + +#ifndef USB_INT_EP0_SETUP + +/* The following status codes are special event interrupts, if the USB bus + * suspend check is enabled through CMD20_CHK_SUSPEND, then the interrupt status + * of USB bus suspend and sleep wakeup must be handled */ +#define USB_INT_USB_SUSPEND 0x05 /* USB bus suspend event */ +#define USB_INT_WAKE_UP 0x06 /* Wake from sleep event */ + +/* The following status code 0XH is used for USB device mode */ +/* Only need to process in built-in firmware mode: USB_INT_EP1_OUT, + * USB_INT_EP1_IN, USB_INT_EP2_OUT, USB_INT_EP2_IN */ +/* bit 7 - bit 4 is 0000 */ +/* Bit 3-Bit 2 indicates the current transaction, 00=OUT, 10=IN, 11=SETUP */ +/* Bit 1-Bit 0 indicates the current endpoint, 00=Endpoint 0, 01=Endpoint 1, + * 10=Endpoint 2, 11=USB bus reset */ +#define USB_INT_EP0_SETUP 0x0C /* SETUP for USB endpoint 0 */ +#define USB_INT_EP0_OUT 0x00 /* OUT of USB endpoint 0 */ +#define USB_INT_EP0_IN 0x08 /* IN for USB endpoint 0 */ +#define USB_INT_EP1_OUT 0x01 /* OUT of USB endpoint 1 */ +#define USB_INT_EP1_IN 0x09 /* IN for USB endpoint 1 */ +#define USB_INT_EP2_OUT 0x02 /* OUT of USB endpoint 2 */ +#define USB_INT_EP2_IN 0x0A /* IN for USB endpoint 2 */ +/* USB_INT_BUS_RESET 0x0000XX11B */ +/* USB bus reset */ +#define USB_INT_BUS_RESET1 0x03 /* USB bus reset */ +#define USB_INT_BUS_RESET2 0x07 /* USB bus reset */ +#define USB_INT_BUS_RESET3 0x0B /* USB bus reset */ +#define USB_INT_BUS_RESET4 0x0F /* USB bus reset */ + +#endif + +/* The following status codes 2XH-3XH are used for communication failure codes + * in USB host mode */ +/* bit 7 - bit 6 is 00 */ +/* bit 5 is 1 */ +/* Bit 4 indicates whether the currently received packet is synchronized */ +/* Bit 3-Bit 0 indicates the response from the USB device when communication + * failed: 0010=ACK, 1010=NAK, 1110=STALL, 0011=DATA0, 1011=DATA1, XX00=timeout + */ +/* USB_INT_RET_ACK 0x001X0010B */ +/* ERROR: return ACK for IN transaction */ +/* USB_INT_RET_NAK 0x001X1010B */ +/* Error: return NAK */ +/* USB_INT_RET_STALL 0x001X1110B */ +/* Error: return STALL */ +/* USB_INT_RET_DATA0 0x001X0011B */ +/* Error: DATA0 returned for OUT/SETUP transactions */ +/* USB_INT_RET_DATA1 0x001X1011B */ +/* ERROR: DATA1 returned for OUT/SETUP transactions */ +/* USB_INT_RET_TOUT 0x001XXX00B */ +/* Error: return timeout */ +/* USB_INT_RET_TOGX 0x0010X011B */ +/* Error: return data out of sync for IN transaction */ +/* USB_INT_RET_PID 0x001XXXXXB */ +/* ERROR: undefined */ + +/* The following status code 1XH is used for the operation status code of USB + * host mode */ +#ifndef CH_USB_INT_SUCCESS + +/* USB transaction or transfer operation succeeded */ +#define CH_USB_INT_SUCCESS 0x14 + +/* A USB device connection event is detected, it may be a new connection or + * reconnection after disconnection */ +#define CH_USB_INT_CONNECT 0x15 + +/* USB device disconnection event detected */ +#define CH_USB_INT_DISCONNECT 0x16 + +/* The data transmitted by USB is wrong or the buffer overflows due to too much + * data */ +#define CH_USB_INT_BUF_OVER 0x17 + +/* USB device has been initialized (USB address has been assigned) */ +#define CH_USB_INT_USB_READY 0x18 + +/* USB storage request data read */ +#define CH_USB_INT_DISK_READ 0x1D + +/* USB storage request data write */ +#define CH_USB_INT_DISK_WRITE 0x1E + +/* USB storage operation failed */ +#define CH_USB_INT_DISK_ERR 0x1F +#endif + +/* The following status codes are used for file system error codes in host file + * mode */ +#ifndef ERR_DISK_DISCON +#define ERR_DISK_DISCON \ + 0x82 /* The disk has not been connected, maybe the disk has been \ + disconnected */ +#define ERR_LARGE_SECTOR \ + 0x84 /*The sector of the disk is too large, only 512 bytes per sector are \ + supported */ \ + #define ERR_TYPE_ERROR 0x92 /* The disk partition type is not \ + supported, only FAT12/FAT16/BigDOS/FAT32 is \ + supported, it needs to be re-partitioned by the \ + disk management tool */ +#define ERR_BPB_ERROR \ + 0xA1 /*The disk has not been formatted, \ + or the parameters are wrong and need to be reformatted by WINDOWS with \ + default parameters */ \ + #define ERR_DISK_FULL 0xB1 /*The disk file is too full, the remaining \ + space is too little or there is no more, and \ + disk defragmentation is required */ \ + #define ERR_FDT_OVER 0xB2 /*There are too many files in the \ + directory(folder), there is no free directory \ + entry, the number of files in the FAT12 / \ + FAT16 root directory should be less than 512, \ + and disk defragmentation is required */ \ + #define ERR_FILE_CLOSE 0xB4 /*The file has been closed, it should be \ + reopened if needed */ \ + #define ERR_OPEN_DIR 0x41 /* The directory (folder) of the specified \ + path is opened */ +#define ERR_MISS_FILE \ + 0x42 /*The file in the specified path is not found, maybe the file name is \ + wrong */ \ + #define ERR_FOUND_NAME 0x43 /* Search for a matching file name, or ask \ + to open a directory (folder) but the actual result opens the file */ +/* The following file system error codes are used for file system subroutines */ +#define ERR_MISS_DIR \ + 0xB3 /*A subdirectory(folder) of the specified path is not found, maybe the \ + directory name is wrong */ \ + #define ERR_LONG_BUF_OVER 0x48 /* long file buffer overflow */ +#define ERR_LONG_NAME_ERR \ + 0x49 /* The short file name does not have a corresponding long file name or \ + * the long file name is wrong \ + */ +#define ERR_NAME_EXIST \ + 0x4A /* A short file with the same name already exists, it is recommended to \ + regenerate another short file name */ +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* The following status codes are used for disk and file status in host file + * mode, VAR_DISK_STATUS */ +#ifndef DEF_DISK_UNKNOWN +#define DEF_DISK_UNKNOWN \ + 0x00 /*Not initialized, unknown state */ \ + #define DEF_DISK_DISCONN 0x01 /* The disk is not connected or has been \ + disconnected */ +#define DEF_DISK_CONNECT \ + 0x02 /* The disk is connected, but it has not been initialized or the disk \ + * cannot be recognized \ + */ +#define DEF_DISK_MOUNTED \ + 0x03 /* The disk has been initialized successfully, but the file system has \ + not been analyzed or the file system does not support */ +#define DEF_DISK_READY 0x10 /* The file system of the disk has been analyzed and can support */ +#define DEF_DISK_OPEN_ROOT \ + 0x12 /* The root directory has been opened and must be closed after use. \ + Note that the FAT12/FAT16 root directory is a fixed length */ +#define DEF_DISK_OPEN_DIR 0x13 /* A subdirectory (folder) has been opened */ +#define DEF_DISK_OPEN_FILE 0x14 /* The file has been opened */ +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Common definitions of file system */ + +#ifndef DEF_SECTOR_SIZE +#define DEF_SECTOR_SIZE 512 /* The default physical sector size of U disk or SD card */ +#endif + +#ifndef DEF_WILDCARD_CHAR +#define DEF_WILDCARD_CHAR 0x2A /* Wildcard '*' for pathname */ +#define DEF_SEPAR_CHAR1 0x5C /* The path name separator '\' */ +#define DEF_SEPAR_CHAR2 0x2F /* The delimiter of the path name '/' */ +#define DEF_FILE_YEAR 2004 /* Default file date: 2004 */ +#define DEF_FILE_MONTH 1 /* Default file date: January */ +#define DEF_FILE_DATE 1 /* Default file date: 1st */ +#endif + +#ifndef ATTR_DIRECTORY + +/* File directory information in FAT data area */ +typedef struct FAT_DIR_INFO { + UINT8 DIR_Name[11]; /* 00H, file name, a total of 11 bytes, fill in blanks */ + UINT8 DIR_Attr; /* 0BH, file attribute, refer to the following description */ + UINT8 DIR_NTRes; /* 0CH */ + UINT8 DIR_CrtTimeTenth; /* 0DH, the time of file creation, counted in 0.1 + second units */ + UINT16 DIR_CrtTime; /* 0EH, file creation time */ + UINT16 DIR_CrtDate; /* 10H, the date the file was created */ + UINT16 DIR_LstAccDate; /* 12H, the date of the last access operation */ + UINT16 DIR_FstClusHI; /* 14H */ + UINT16 DIR_WrtTime; /* 16H, file modification time, refer to the previous + macro MAKE_FILE_TIME */ + UINT16 DIR_WrtDate; /* 18H, file modification date, refer to the previous + macro MAKE_FILE_DATE */ + UINT16 DIR_FstClusLO; /* 1AH */ + UINT32 DIR_FileSize; /* 1CH, file length */ +} FAT_DIR_INFO, *P_FAT_DIR_INFO; /* 20H */ + +/* file attributes */ +#define ATTR_READ_ONLY 0x01 /* The file is read-only */ +#define ATTR_HIDDEN 0x02 /* file is a hidden attribute */ +#define ATTR_SYSTEM 0x04 /* The file is a system attribute */ +#define ATTR_VOLUME_ID 0x08 /* Volume label */ +#define ATTR_DIRECTORY 0x10 /* subdirectories (folders) */ +#define ATTR_ARCHIVE 0x20 /* file is archive attribute */ +#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID) /* long filename attribute */ +#define ATTR_LONG_NAME_MASK (ATTR_LONG_NAME | ATTR_DIRECTORY | ATTR_ARCHIVE) +/* file attribute UINT8 */ +/* bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 */ +/* Only hidden volume is undefined */ +/* Read the Tibetan standard record file */ +/* file time UINT16 */ +/* Time = (Hour<<11) + (Minute<<5) + (Second>>1) */ +#define MAKE_FILE_TIME \ + (h, m, s)((h << 11) + (m << 5) + (s >> 1)) /* Generate file time data of specified \ + hours, minutes and seconds */ +/* file date UINT16 */ +/* Date = ((Year-1980)<<9) + (Month<<5) + Day */ +#define MAKE_FILE_DATE \ + (y, m, d)(((y - 1980) << 9) + (m << 5) + d) /* Generate the file date data of the \ + specified year, month and day */ + +#define LONE_NAME_MAX_CHAR (255 * 2) /* The maximum number of characters/bytes of the long file name */ +#define LONG_NAME_PER_DIR \ + (13 * 2) /* The number of characters/bytes of the long file name in the \ + directory information structure of each file */ + +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* SCSI command and data input and output structures */ + +#ifndef SPC_CMD_INQUIRY + +/* SCSI command code */ +#define SPC_CMD_INQUIRY 0x12 +#define SPC_CMD_READ_CAPACITY 0x25 +#define SPC_CMD_READ10 0x28 +#define SPC_CMD_WRITE10 0x2A +#define SPC_CMD_TEST_READY 0x00 +#define SPC_CMD_REQUEST_SENSE 0x03 +#define SPC_CMD_MODESENSE6 0x1A +#define SPC_CMD_MODESENSE10 0x5A +#define SPC_CMD_START_STOP 0x1B + +/* BulkOnly protocol command block */ +typedef struct BULK_ONLY_CBW { + UINT32 CBW_Sig; + UINT32 CBW_Tag; + UINT8 CBW_DataLen0; /* 08H, input: data transmission length, the valid value + for input data is 0 to 48, and the valid value for + output data is 0 to 33 */ + UINT8 CBW_DataLen1; + UINT16 CBW_DataLen2; + UINT8 CBW_Flag; /* 0CH, input: transmission direction and other flags, if bit + 7 is 1, input data, if bit 0, output data or no data */ + UINT8 CBW_LUN; + UINT8 CBW_CB_Len; /* 0EH, input: the length of the command block, valid values + ​​are 1 to 16 */ + UINT8 CBW_CB_Buf[16]; /* 0FH, input: command block, the buffer is up to 16 + bytes */ +} BULK_ONLY_CBW, *P_BULK_ONLY_CBW; /* BulkOnly protocol command block, input CBW structure */ + +/* INQUIRY command return data */ +typedef struct INQUIRY_DATA { + UINT8 DeviceType; /* 00H, device type */ + UINT8 RemovableMedia; /* 01H, if bit 7 is 1, it means removable storage */ + UINT8 Versions; /* 02H, protocol version */ + UINT8 DataFormatAndEtc; /* 03H, specify the return data format */ + UINT8 AdditionalLength; /* 04H, the length of subsequent data */ + UINT8 Reserved1; + UINT8 Reserved2; + UINT8 MiscFlag; /* 07H, some control flags */ + UINT8 VendorIdStr[8]; /* 08H, Vendor information */ + UINT8 ProductIdStr[16]; /* 10H, product information */ + UINT8 ProductRevStr[4]; /* 20H, product version */ +} INQUIRY_DATA, *P_INQUIRY_DATA; /* 24H */ + +/* REQUEST SENSE command return data */ +typedef struct SENSE_DATA { + UINT8 ErrorCode; /* 00H, error code and valid bits */ + UINT8 SegmentNumber; + UINT8 SenseKeyAndEtc; /* 02H, primary key code */ + UINT8 Information0; + UINT8 Information1; + UINT8 Information2; + UINT8 Information3; + UINT8 AdditSenseLen; /* 07H, the length of subsequent data */ + UINT8 CmdSpecInfo[4]; + UINT8 AdditSenseCode; /* 0CH, additional key code */ + UINT8 AddSenCodeQual; /* 0DH, detailed additional key code */ + UINT8 FieldReplaUnit; + UINT8 SenseKeySpec[3]; +} SENSE_DATA, *P_SENSE_DATA; /* 12H */ + +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Data input and output structures in host file mode */ + +#ifndef MAX_FILE_NAME_LEN + +#define MAX_FILE_NAME_LEN \ + (13 + 1) /* The maximum length of the file name, the maximum length is 1 \ + root directory character + 8 main file names + 1 decimal point + \ + 3 type names + terminator = 14 */ + +/* Command input data and output data */ +typedef union CH376_CMD_DATA { + struct { + UINT8 mBuffer[MAX_FILE_NAME_LEN]; + } Default; + + INQUIRY_DATA DiskMountInq; /* Return: return data of INQUIRY command */ + /* CMD0H_DISK_MOUNT: Initialize the disk and test if the disk is ready, when + * executed for the first time */ + + FAT_DIR_INFO OpenDirInfo; /* Return: Enumerated file directory information */ + /* CMD0H_FILE_OPEN: Enumerate files and directories (folders) */ + + FAT_DIR_INFO EnumDirInfo; /* Return: Enumerated file directory information */ + /* CMD0H_FILE_ENUM_GO: Continue to enumerate files and directories (folders) + */ + + struct { + UINT8 mUpdateFileSz; /* Input parameter: whether to allow the file length to + be updated, or 0 to prohibit the update of the + length */ + } FileCLose; /* CMD1H_FILE_CLOSE: close the currently opened file */ + + struct { + UINT8 mDirInfoIndex; /* Input parameters: specify the index number of the + directory information structure to be read in the + sector, 0FFH is the currently opened file */ + } DirInfoRead; /* CMD1H_DIR_INFO_READ: read the directory information of the + file */ + + union { + UINT32 mByteOffset; /* Input parameter: number of offset bytes, offset in + bytes (total length 32 bits, low byte first) */ + UINT32 + mSectorLba; /* Return: the absolute linear sector number corresponding + to the current file pointer, 0FFFFFFFFH has reached the + end of the file (total length 32 bits, low byte first) */ + } ByteLocate; /* CMD4H_BYTE_LOCATE: move the current file pointer in bytes */ + + struct { + UINT16 + mByteCount; /* Input parameter: the number of bytes requested to be read + (total length is 16 bits, low byte first) */ + } ByteRead; /* CMD2H_BYTE_READ: read data block from current position in bytes + */ + + struct { + UINT16 mByteCount; /* Input parameter: the number of bytes requested to be + written (total length is 16 bits, low byte first) */ + } ByteWrite; /* CMD2H_BYTE_WRITE: Write a block of data to the current + location in bytes */ + + union { + UINT32 mSectorOffset; /* Input parameter: number of offset sectors, offset + in sector (total length 32 bits, low byte first) */ + UINT32 + mSectorLba; /* Return: the absolute linear sector number corresponding + to the current file pointer, 0FFFFFFFFH has reached the + end of the file (total length 32 bits, low byte first) */ + } SectorLocate; /* CMD4H_SEC_LOCATE: move the current file pointer in sectors + */ + + struct { + UINT8 mSectorCount; /* Input parameters: the number of sectors requested to + be read */ + /* return: the number of sectors allowed to be read */ + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; /* Return: The starting absolute linear sector number + of the sector block allowed to be read (total length + 32 bits, low byte first) */ + } SectorRead; /* CMD1H_SEC_READ: Read the data block from the current position + in sectors */ + + struct { + UINT8 mSectorCount; /* Input parameters: the number of sectors requested to + be written */ + /* return: the number of sectors allowed to be written */ + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; /* Return: the starting absolute linear sector number + of the sector block allowed to be written (total + length 32 bits, low byte first) */ + } SectorWrite; /* CMD1H_SEC_WRITE: Write a data block at the current location + in sectors */ + + struct { + UINT32 + mDiskSizeSec; /* Return: the total number of sectors of the entire + physical disk (total length 32 bits, low byte first) */ + } DiskCapacity; /* CMD0H_DISK_CAPACITY: Query the physical capacity of the + disk */ + + struct { + UINT32 mTotalSector; /* Return: the total number of sectors of the current + logical disk (total length is 32 bits, low byte + first) */ + UINT32 mFreeSector; /* Return: the number of remaining sectors of the + current logical disk (total length is 32 bits, low + byte first) */ + UINT8 mDiskFat; /* Return: FAT type of the current logical disk, 1-FAT12, + 2-FAT16, 3-FAT32 */ + } DiskQuery; /* CMD_DiskQuery, query disk information */ + + BULK_ONLY_CBW DiskBocCbw; /* Input parameters: CBW command structure */ + /* CMD0H_DISK_BOC_CMD: command to execute BulkOnly transfer protocol to USB + * memory */ + + struct { + UINT8 mMaxLogicUnit; /* return: the maximum logic unit number of the USB + memory */ + } DiskMaxLun; /* CMD0H_DISK_MAX_LUN: Control transfer - get the maximum + logical unit number of USB memory */ + + INQUIRY_DATA DiskInitInq; /* Return: return data of INQUIRY command */ + /* CMD0H_DISK_INIT: Initialize USB storage */ + + INQUIRY_DATA DiskInqData; /* Return: return data of INQUIRY command */ + /* CMD0H_DISK_INQUIRY: Query USB storage characteristics */ + + SENSE_DATA ReqSenseData; /* Return: REQUEST SENSE command return data */ + /* CMD0H_DISK_R_SENSE: Check for USB storage errors */ + + struct { + UINT32 mDiskSizeSec; /* Return: the total number of sectors of the entire + physical disk (total length is 32 bits, high byte + first) */ + } DiskSize; /* CMD0H_DISK_SIZE: Get the capacity of the USB memory */ + + struct { + UINT32 mStartSector; /* Input parameters: LBA sector address (total length + 32 bits, low byte first) */ + UINT8 mSectorCount; /* Input parameters: the number of sectors requested to + be read */ + } DiskRead; /* CMD5H_DISK_READ: Read data blocks from USB memory (in sectors) + */ + + struct { + UINT32 mStartSector; /* Input parameters: LBA sector address (total length + 32 bits, low byte first) */ + UINT8 mSectorCount; /* Input parameters: the number of sectors requested to + be written */ + } DiskWrite; /* CMD5H_DISK_WRITE: Write data block to USB memory (in sectors) + */ +} CH376_CMD_DATA, *P_CH376_CMD_DATA; + +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Address of filesystem variable in host file mode */ + +#ifndef VAR_FILE_SIZE + +/* 8-bit/single-byte variable */ + +/* Basic information of the current system + * Bit 6 is used to indicate the subclass SubClass-Code of the USB storage + * device. If bit 6 is 0, it means that the subclass is 6, and if bit 6 is 1, it + * means that the subclass is other than 6 Bit 5 is used to indicate the USB + * configuration status in USB device mode and the USB device connection status + * in USB host mode In USB device mode, if bit 5 is 1, the USB configuration is + * complete, and if bit 5 is 0, it has not yet been configured In USB host mode, + * if bit 5 is 1, there is a USB device on the USB port, and if bit 5 is 0, + * there is no USB device on the USB port Bit 4 is used to indicate the buffer + * lock state in USB device mode. If bit 4 is 1, it means that the USB buffer is + * in a locked state. If bit 6 is 1, it means it has been released Other bits, + * reserved, do not modify */ +#define CH_VAR_SYS_BASE_INFO 0x20 + +/* The number of retries for the USB transaction operation + * If bit 7 is 0, it will not retry when receiving NAK, if bit 7 is 1, if bit 6 + * is 0, it will retry infinitely when receiving NAK (you can use CMD_ABORT_NAK + * command to give up retry), if bit 7 is 1, bit 6 is 1 Retry for up to 3 + * seconds when NAK is received Bit 5~Bit 0 is the number of retries after + * timeout */ +#define CH_VAR_RETRY_TIMES 0x25 + +/* Bit flag in host file mode + * Bit 1 and bit 0, FAT file system flag of the logical disk, 00-FAT12, + * 01-FAT16, 10-FAT32, 11-Illegal Bit 2, whether the FAT table data in the + * current buffer has been modified, 0-unmodified, 1-modified Bit 3, the file + * length needs to be modified flag, the current file is appended with data, + * 0-no modification is required if it is not appended, 1-modification is + * required if it has been appended Other bits, reserved, do not modify */ +#define CH_VAR_FILE_BIT_FLAG 0x26 + +/* Disk and file status in host file mode */ +#define CH_VAR_DISK_STATUS 0x2B + +/* Bit flag of SD card in host file mode + * Bit 0, SD card version, 0-only supports SD first version, 1-supports SD + * second version bit 1, auto-identification, 0-SD card, 1-MMC card Bit 2, + * automatic identification, 0-standard capacity SD card, 1-high capacity SD + * card (HC-SD) bit 4, ACMD41 command timeout bit 5, CMD1 command timeout bit 6, + * CMD58 command timeout Other bits, reserved, do not modify */ +#define CH_VAR_SD_BIT_FLAG 0x30 + +/* Sync flag for BULK-IN/BULK-OUT endpoint of USB storage device + * bit 7, sync flag for Bulk-In endpoint + * bit 6, sync flag for Bulk-In endpoint + * Bit 5~Bit 0, must be 0 */ +#define CH_VAR_UDISK_TOGGLE 0x31 + +/* The logical unit number of the USB storage device + * Bit 7~Bit 4, the current logical unit number of the USB storage device, after + * CH376 initializes the USB storage device, the default is to access the 0# + * logical unit Bit 3~Bit 0, the maximum logical unit number of the USB storage + * device, plus 1 equals the number of logical units */ +#define CH_VAR_UDISK_LUN 0x34 + +/* Number of sectors per cluster of logical disk */ +#define CH_VAR_SEC_PER_CLUS 0x38 + +/* The index number of the current file directory information in the sector */ +#define CH_VAR_FILE_DIR_INDEX 0x3B + +/* The sector offset of the current file pointer in the cluster, if it is 0xFF, + * it points to the end of the file and the end of the cluster */ +#define CH_VAR_CLUS_SEC_OFS 0x3C + +/* 32-bit/4-byte variable + * For FAT16 disk, it is the number of sectors occupied by the root directory, + * and for FAT32 disk, it is the starting cluster number of the root directory + * (total length 32 bits, low byte first) */ +#define CH_VAR_DISK_ROOT 0x44 + +/* The total number of clusters of the logical disk(total length is 32 bits, low + * byte first) */ +#define CH_VAR_DSK_TOTAL_CLUS 0x48 + +/* The starting absolute sector number LBA of the logical disk(total length is + * 32 bits, low byte first) */ +#define CH_VAR_DSK_START_LBA 0x4C + +/* The starting LBA of the data area of ​​the logical disk (total length is + * 32 bits, low byte first) */ +#define CH_VAR_DSK_DAT_START 0x50 + +/* The LBA corresponding to the data in the current disk data buffer (total + * length is 32 bits, low byte first) */ +#define CH_VAR_LBA_BUFFER 0x54 + +/* The current read and write disk start LBA address (total length 32 bits, low + * byte first) */ +#define CH_VAR_LBA_CURRENT 0x58 + +/* LBA address of the sector where the current file directory information is + * located (total length 32 bits, low byte first) + */ +#define CH_VAR_FAT_DIR_LBA 0x5C + +/* The starting cluster number of the current file or directory (folder) (total + * length 32 bits, low byte first) */ +#define CH_VAR_START_CLUSTER 0x60 + +/* The current cluster number of the current file (total length is 32 bits, low + * byte first) */ +#define CH_VAR_CURRENT_CLUST 0x64 + +/* The length of the current file (total length is 32 bits, low byte first) */ +#define CH_VAR_FILE_SIZE 0x68 + +/* The current file pointer, the byte offset of the current read and write + * position(total length 32 bits, low byte first) */ +#define CH_VAR_CURRENT_OFFSET 0x6C + +#endif + +/* ******************************************************************************************************************/ +/* Common USB definitions */ + +/* USB packet identification PID, the host mode may be used */ +#ifndef DEF_USB_PID_SETUP +#define DEF_USB_PID_NULL 0x00 /* PID reserved, undefined */ +#define DEF_USB_PID_SOF 0x05 +#define DEF_USB_PID_SETUP 0x0D +#define DEF_USB_PID_IN 0x09 +#define DEF_USB_PID_OUT 0x01 +#define DEF_USB_PID_ACK 0x02 +#define DEF_USB_PID_NAK 0x0A +#define DEF_USB_PID_STALL 0x0E +#define DEF_USB_PID_DATA0 0x03 +#define DEF_USB_PID_DATA1 0x0B +#define DEF_USB_PID_PRE 0x0C +#endif + +/* USB request type, may be used in external firmware mode */ +#ifndef DEF_USB_REQ_TYPE +#define DEF_USB_REQ_READ 0x80 /* Control read operation */ +#define DEF_USB_REQ_WRITE 0x00 /* Control write operation */ +#define DEF_USB_REQ_TYPE 0x60 /* Control request type */ +#define DEF_USB_REQ_STAND 0x00 /* Standard Request */ +#define DEF_USB_REQ_CLASS 0x20 /* Device class request */ +#define DEF_USB_REQ_VENDOR 0x40 /* Vendor Request */ +#define DEF_USB_REQ_RESERVE 0x60 /* Reservation Request */ +#endif + +/* USB standard device request, Bit 6 of RequestType 5=00 (Standard), external + * firmware mode may be used */ +#ifndef DEF_USB_GET_DESCR +#define DEF_USB_CLR_FEATURE 0x01 +#define DEF_USB_SET_FEATURE 0x03 +#define DEF_USB_GET_STATUS 0x00 +#define DEF_USB_SET_ADDRESS 0x05 +#define DEF_USB_GET_DESCR 0x06 +#define DEF_USB_SET_DESCR 0x07 +#define DEF_USB_GET_CONFIG 0x08 +#define DEF_USB_SET_CONFIG 0x09 +#define DEF_USB_GET_INTERF 0x0A +#define DEF_USB_SET_INTERF 0x0B +#define DEF_USB_SYNC_FRAME 0x0C +#endif + +// desscriptor types for CMD1H_GET_DESCR +#ifndef CH375_USB_DEVICE_DESCRIPTOR +#define CH375_USB_DEVICE_DESCRIPTOR 0x01 +#define CH375_USB_CONFIGURATION_DESCRIPTOR 0x02 +#define CH375_USB_INTERFACE_DESCRIPTOR 0x04 +#define CH375_USB_ENDPOINT_DESCRIPTOR 0x05 +#endif + +/* ************************************************ + * **************************************************** ***************** */ + +#ifdef _cplusplus +} +#endif + +#endif diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.c b/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.c new file mode 100644 index 00000000..7fdc71b5 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.c @@ -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); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.h b/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.h new file mode 100644 index 00000000..7d7c75da --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.h @@ -0,0 +1,75 @@ +#ifndef __CLASS_HUB +#define __CLASS_HUB + +#include "ch376.h" +#include "protocol.h" +#include + +/* +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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/delay.h b/Source/HBIOS/ch376-native/source-doc/base-drv/delay.h new file mode 100644 index 00000000..05f9d1bf --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/delay.h @@ -0,0 +1,11 @@ +#ifndef __DELAY +#define __DELAY + +#include + +extern void delay(void); +extern void delay_20ms(void); +extern void delay_short(void); +extern void delay_medium(void); + +#endif diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c b/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c new file mode 100644 index 00000000..e30284ea --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c @@ -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 + +/** + * @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); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.h b/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.h new file mode 100644 index 00000000..23cf0001 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.h @@ -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 + +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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.c b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.c new file mode 100644 index 00000000..86eca0a6 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.c @@ -0,0 +1,221 @@ +#include "enumerate.h" +#include "enumerate_hub.h" +#include "enumerate_storage.h" +#include "protocol.h" +#include "work-area.h" +#include + +#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 -^ + + +*/ diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.h b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.h new file mode 100644 index 00000000..f8f971b7 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.h @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.c b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.c new file mode 100644 index 00000000..63cde3bc --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.c @@ -0,0 +1,80 @@ +#include "enumerate_hub.h" +#include "class_hub.h" +#include "delay.h" +#include "protocol.h" +#include "work-area.h" +#include + +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; +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.h b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.h new file mode 100644 index 00000000..32be6558 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.h @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.c b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.c new file mode 100644 index 00000000..289182d9 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.c @@ -0,0 +1,27 @@ +#include "enumerate_storage.h" +#include "protocol.h" +#include + +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; +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.h b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.h new file mode 100644 index 00000000..3f4a3508 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.h @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/hbios.h b/Source/HBIOS/ch376-native/source-doc/base-drv/hbios.h new file mode 100644 index 00000000..179a5267 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/hbios.h @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/print.c b/Source/HBIOS/ch376-native/source-doc/base-drv/print.c new file mode 100644 index 00000000..bcec3e82 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/print.c @@ -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$"); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/print.h b/Source/HBIOS/ch376-native/source-doc/base-drv/print.h new file mode 100644 index 00000000..7b4c4723 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/print.h @@ -0,0 +1,11 @@ +#ifndef __XPRINT +#define __XPRINT + +#include + +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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.c b/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.c new file mode 100644 index 00000000..0b09bcdf --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.c @@ -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 + +#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); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.h b/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.h new file mode 100644 index 00000000..df622b44 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.h @@ -0,0 +1,82 @@ +#ifndef __HW +#define __HW + +#include "ch376.h" +#include "dev_transfers.h" +#include "transfers.h" +#include + +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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.c b/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.c new file mode 100644 index 00000000..883ec873 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.c @@ -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 + +#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); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.h b/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.h new file mode 100644 index 00000000..b3d9d3ca --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.h @@ -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 + +#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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.c b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.c new file mode 100644 index 00000000..84b14855 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.c @@ -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; +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.h b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.h new file mode 100644 index 00000000..3d2abd53 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.h @@ -0,0 +1,11 @@ +#ifndef __USB_BASE_DRV +#define __USB_BASE_DRV + +#include +#include + +extern uint8_t storage_count; + +extern uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1); + +#endif diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/usb-init.c b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-init.c new file mode 100644 index 00000000..a76a7e3a --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-init.c @@ -0,0 +1,56 @@ +#include "ch376.h" +#include "enumerate.h" +#include "print.h" +#include "work-area.h" +#include "z80.h" +#include + +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$"); +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.c b/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.c new file mode 100644 index 00000000..1138c9fe --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.c @@ -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 +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.h b/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.h new file mode 100644 index 00000000..87821f27 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.h @@ -0,0 +1,27 @@ +#ifndef __USB_STATE +#define __USB_STATE + +#include "ch376.h" +#include "protocol.h" +#include + +#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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/work-area.c b/Source/HBIOS/ch376-native/source-doc/base-drv/work-area.c new file mode 100644 index 00000000..fb7f46bd --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/work-area.c @@ -0,0 +1,3 @@ +#include "usb_state.h" + +_usb_state x = {0, 0, 0}; diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/work-area.h b/Source/HBIOS/ch376-native/source-doc/base-drv/work-area.h new file mode 100644 index 00000000..354f0697 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/work-area.h @@ -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 diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/z80.h b/Source/HBIOS/ch376-native/source-doc/base-drv/z80.h new file mode 100644 index 00000000..d9eaf0bb --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/z80.h @@ -0,0 +1,17 @@ +#ifndef __Z80_HELPERS +#define __Z80_HELPERS + +#include + +#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 diff --git a/Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh b/Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh new file mode 100755 index 00000000..ad00b407 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh @@ -0,0 +1,50 @@ +#!/bin/bash + +# Check if exactly two arguments are provided +if [ "$#" -ne 2 ]; then + echo "Usage: $0 " + 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' \ diff --git a/Source/HBIOS/ch376-native/source-doc/depends.d b/Source/HBIOS/ch376-native/source-doc/depends.d new file mode 100644 index 00000000..5d2e46b4 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/depends.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 diff --git a/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.c b/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.c new file mode 100644 index 00000000..c554e345 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.c @@ -0,0 +1,168 @@ +#include "class_scsi.h" +#include +#include +#include + +_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); +} diff --git a/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.h b/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.h new file mode 100644 index 00000000..356da856 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.h @@ -0,0 +1,196 @@ +#ifndef __CLASS_SCSI +#define __CLASS_SCSI + +#include + +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 diff --git a/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi-init.c b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi-init.c new file mode 100644 index 00000000..1511f3b5 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi-init.c @@ -0,0 +1,35 @@ +#include "class_scsi.h" +#include +#include +#include +#include +#include +#include +#include +#include + +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); +} diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.c b/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.c new file mode 100644 index 00000000..035c33d4 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.c @@ -0,0 +1,176 @@ +#include "class_ufi.h" +#include +#include +#include +#include +#include + +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; +} diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.h b/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.h new file mode 100644 index 00000000..1b761bd9 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.h @@ -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 + +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 diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi-init.c b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi-init.c new file mode 100644 index 00000000..6cbd88bd --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi-init.c @@ -0,0 +1,92 @@ +#include "class_ufi.h" +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.c b/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.c new file mode 100644 index 00000000..bf43a45e --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.c @@ -0,0 +1,64 @@ +#include "usb_cbi.h" +#include "dev_transfers.h" +#include "protocol.h" +#include + +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; +} diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.h b/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.h new file mode 100644 index 00000000..349a7853 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.h @@ -0,0 +1,14 @@ +#ifndef __USB_CBI_H__ +#define __USB_CBI_H__ + +#include +#include + +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 diff --git a/Source/HBIOS/ch376-native/ufi-drv.s b/Source/HBIOS/ch376-native/ufi-drv.s new file mode 100644 index 00000000..5ed7edf6 --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv.s @@ -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" diff --git a/Source/HBIOS/ch376-native/ufi-drv/class_ufi.c.s b/Source/HBIOS/ch376-native/ufi-drv/class_ufi.c.s new file mode 100644 index 00000000..24ac5b51 --- /dev/null +++ b/Source/HBIOS/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 diff --git a/Source/HBIOS/ch376-native/ufi-drv/ufi-init.c.s b/Source/HBIOS/ch376-native/ufi-drv/ufi-init.c.s new file mode 100644 index 00000000..6b99f86e --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/ufi-init.c.s @@ -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 diff --git a/Source/HBIOS/ch376-native/ufi-drv/usb_cbi.c.s b/Source/HBIOS/ch376-native/ufi-drv/usb_cbi.c.s new file mode 100644 index 00000000..852dd31b --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/usb_cbi.c.s @@ -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 diff --git a/Source/HBIOS/ch376.asm b/Source/HBIOS/ch376.asm new file mode 100644 index 00000000..b0c05df3 --- /dev/null +++ b/Source/HBIOS/ch376.asm @@ -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 diff --git a/Source/HBIOS/ch376scsi.asm b/Source/HBIOS/ch376scsi.asm new file mode 100644 index 00000000..576b44c2 --- /dev/null +++ b/Source/HBIOS/ch376scsi.asm @@ -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 diff --git a/Source/HBIOS/ch376ufi.asm b/Source/HBIOS/ch376ufi.asm new file mode 100644 index 00000000..95e819e9 --- /dev/null +++ b/Source/HBIOS/ch376ufi.asm @@ -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 diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index d5781f95..3c8c9031 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -4165,6 +4165,15 @@ HB_INITTBL: #IF (ESPENABLE) .DW ESP_INIT #ENDIF +#IF (CHNATIVEENABLE) + .DW CHNATIVE_INIT +#ENDIF +#IF (CHSCSIENABLE) + .DW CHSCSI_INIT +#ENDIF +#IF (CHUFIENABLE) + .DW CHUFI_INIT +#ENDIF ; HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2) ; @@ -7045,6 +7054,7 @@ HB_BADINTCNT .DB 0 CALL NEWLINE ;CALL CONTINUE OR $FF ; SIGNAL INTERRUPT HANDLED + EZ80_UTIL_DEBUG RET ; ;-------------------------------------------------------------------------------------------------- @@ -8776,6 +8786,7 @@ PS_DDIMM .TEXT "IMM$" PS_DDSYQ .TEXT "SYQ$" PS_DDCHUSB .TEXT "CHUSB$" PS_DDCHSD .TEXT "CHSD$" +PS_DDCHNATUSB .TEXT "USB$" ; ; DISK TYPE STRINGS ; @@ -8790,7 +8801,10 @@ PS_DTFSH .TEXT "Flash ROM$" PS_DTRF .TEXT "RAM Floppy$" PS_DTCD .TEXT "CD-ROM$" PS_DTCRT .TEXT "Cartridge$" +PS_DTOUSBSCI .TEXT "SCSI$" +PS_DTOUSBUFI .TEXT "UFI$" PS_DTOTHER .TEXT "???$" + ; ; FLOPPY ATTRIBUTE STRINGS ; @@ -9446,6 +9460,32 @@ SIZ_YM2612 .EQU $ - ORG_YM2612 MEMECHO " bytes.\n" #ENDIF ; +#IF (CHNATIVEENABLE) +ORG_CHNATIVE .EQU $ + #INCLUDE "ch376.asm" +SIZ_CHNATIVE .EQU $ - ORG_CHNATIVE + MEMECHO "CH376 Native occupies " + MEMECHO SIZ_CHNATIVE + MEMECHO " bytes.\n" +#ENDIF +; +#IF (CHSCSIENABLE) +ORG_CHSCSI .EQU $ + #INCLUDE "ch376scsi.asm" +SIZ_CHSCSI .EQU $ - ORG_CHSCSI + MEMECHO "CH376 SCSI Mass Storage occupies " + MEMECHO SIZ_CHSCSI + MEMECHO " bytes.\n" +#ENDIF +; +#IF (CHUFIENABLE) +ORG_CHUFI .EQU $ + #INCLUDE "ch376ufi.asm" +SIZ_CHUFI .EQU $ - ORG_CHUFI + MEMECHO "CH376 UFI Floppy Storage occupies " + MEMECHO SIZ_CHUFI + MEMECHO " bytes.\n" +#ENDIF ; #IF (CPUFAM == CPU_EZ80) MEMECHO "EZ80 DRIVERS\n" diff --git a/Source/HBIOS/hbios.inc b/Source/HBIOS/hbios.inc index 368aeaf7..3c7a42f5 100644 --- a/Source/HBIOS/hbios.inc +++ b/Source/HBIOS/hbios.inc @@ -420,6 +420,7 @@ DIODEV_IMM .EQU $0B DIODEV_SYQ .EQU $0C DIODEV_CHUSB .EQU $0D DIODEV_CHSD .EQU $0E +DIODEV_USB .EQU $0F ; ; RTC DEVICE IDS ;