diff --git a/.github/workflows/commit.yml b/.github/workflows/commit.yml index 2110be86..33eaad76 100644 --- a/.github/workflows/commit.yml +++ b/.github/workflows/commit.yml @@ -26,7 +26,8 @@ jobs: run: | export TZ='America/Los_Angeles' sudo apt-get install srecord - make distlog + make transpile-c-code + make distlog --trace rm -rf .git* - name: List Output diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e48d5225..e418df06 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,8 @@ jobs: export TZ='America/Los_Angeles' sudo apt-get install libncurses-dev sudo apt-get install srecord - make distlog + make transpile-c-code + make distlog --trace rm -rf .git* - name: Create Package Archive diff --git a/.gitignore b/.gitignore index 79b2eaa5..6c116cc0 100644 --- a/.gitignore +++ b/.gitignore @@ -114,20 +114,24 @@ Source/ZPM3/genbnk.dat Source/ZSDOS/zsdos.err # Lets explicit list all generate untracked binary files +Binary/*.upd +Binary/Apps/bbcbasic.txt +Binary/Apps/copysl.doc +Binary/Apps/copysl.doc +Binary/Apps/fdu.doc +Binary/Apps/fdu.doc Binary/Apps/Tunes/bgm.vgm Binary/Apps/Tunes/ending.vgm Binary/Apps/Tunes/inchina.vgm Binary/Apps/Tunes/shirakaw.vgm Binary/Apps/Tunes/startdem.vgm Binary/Apps/Tunes/wonder01.vgm -Binary/Apps/copysl.doc -Binary/Apps/fdu.doc Binary/Apps/zmconfig.ovr Binary/Apps/zminit.ovr -Binary/Apps/zmp.doc -Binary/Apps/zmp.hlp Binary/Apps/zmp.cfg +Binary/Apps/zmp.doc Binary/Apps/zmp.fon +Binary/Apps/zmp.hlp Binary/Apps/zmterm.ovr Binary/Apps/zmxfer.ovr Binary/CPM3/bdos3.spr @@ -146,13 +150,12 @@ Binary/CPNET/cpn12ser.lbr Binary/CPNET/cpn3duo.lbr Binary/CPNET/cpn3mt.lbr Binary/CPNET/cpn3ser.lbr -Binary/*.upd +Binary/hd1k_prefix.dat Binary/ZPM3/bnkbdos3.spr Binary/ZPM3/bnkbios3.spr Binary/ZPM3/gencpm.dat Binary/ZPM3/resbdos3.spr Binary/ZPM3/zinstal.zpm -Binary/hd1k_prefix.dat Source/BPBIOS/def-ww.lib Source/CPNET/cpn12duo.lbr Source/CPNET/cpn12mt.lbr @@ -180,6 +183,8 @@ Source/Fonts/fontvgarcc.bin Source/Fonts/fontvgarcu.asm Source/HBIOS/*.upd Source/HBIOS/build_env.cmd +Source/HBIOS/build_env.cmd +Source/HBIOS/hbios_env.sh Source/HBIOS/hbios_env.sh Source/HBIOS/netboot.mod Source/Images/*.cat @@ -197,4 +202,3 @@ Source/ZPM3/setz3.com Tools/unix/OpenSpin/build/ Tools/unix/zxcc/config.h Tools/unix/zxcc/zxcc -Binary/Apps/bbcbasic.txt diff --git a/.vscode/settings.json b/.vscode/settings.json index 7c12e6b0..45145d9e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,4 +1,38 @@ { + "z80-macroasm.format.enabled": true, + "z80-macroasm.format.baseIndent": 1, + "z80-macroasm.format.whitespaceAfterInstruction": "tab", + "z80-macroasm.format.uppercaseKeywords": true, + "z80-macroasm.format.spaceAfterArgument": true, + "z80-macroasm.format.hexaNumberStyle": "motorola", + "z80-macroasm.format.hexaNumberCase": true, "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", + "*.Z80": "z80-macroasm", + "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", + "critical-section.h": "c", + "enumerate.h": "c", + "ch376inc.h": "c", + "enumerate_storage.h": "c", + "work-area.h": "c", + "hbios-driver-storage.h": "c", + "class_hid_keyboard.h": "c", + "print.h": "c" + } } diff --git a/Dockerfile b/Dockerfile index d053f4ee..0a9d0f28 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:jammy-20240111 as basebuilder +FROM ubuntu:jammy-20240111 AS basebuilder # This docker file can be used to build a tool chain docker image for building RomWBW images. @@ -10,7 +10,7 @@ FROM ubuntu:jammy-20240111 as basebuilder # After you have built the above image (called romwbw-chain), you can use it to compile and build the RomWBW images # as per the standard make scripts within RomWBW. # Start a new terminal, cd to where you have clone RomWBW, and then run this command: -# docker run --rm -v ${PWD}:/src/ --privileged=true -u $(id -u ${USER}):$(id -g ${USER}) -it romwbw-chain:latest +# docker run --rm -v ${PWD}:/src/ --privileged=true -u $(id -u ${USER}):$(id -g ${USER}) -it romwbw-chain # you can now compile and build the required images: @@ -21,13 +21,11 @@ FROM ubuntu:jammy-20240111 as basebuilder # when finish, type 'exit' to return to back to your standard terminal session LABEL Maintainer="Dean Netherton" \ - Description="spike to use clang for ez80 target" + Description="RomWBW builder platform" ENV DEBIAN_FRONTEND=noninteractive - RUN dpkg --add-architecture i386 -RUN sed -i 's/http:\/\/archive\.ubuntu\.com\/ubuntu/http:\/\/au.archive.ubuntu.com\/ubuntu/g' /etc/apt/sources.list RUN apt update -y RUN apt dist-upgrade -y RUN apt install -y --no-install-recommends cmake lzip ca-certificates mtools build-essential dos2unix libboost-all-dev texinfo texi2html libxml2-dev subversion bison flex zlib1g-dev m4 git wget dosfstools curl @@ -35,10 +33,10 @@ RUN apt install -y --no-install-recommends cmake lzip ca-certificates mtools bui RUN mkdir work WORKDIR /work -FROM basebuilder as main +FROM basebuilder AS main LABEL Maintainer="Dean Netherton" \ - Description="spike to build RomWBW" + Description="RomWBW builder platform" RUN mkdir /src WORKDIR /src/ diff --git a/Makefile b/Makefile index 87fb9244..91b8f819 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: tools source clean clobber diff dist .ONESHELL: -.SHELLFLAGS = -cex +.SHELLFLAGS = -ce all: tools source @@ -22,6 +22,11 @@ clobber: clean diff: $(MAKE) --directory Source diff +# Convert c code to assembly code +transpile-c-code: + @cd Source/HBIOS/ch376-native + $(MAKE) -j + dist: $(MAKE) ROM_PLATFORM=dist $(MAKE) --directory Tools clean diff --git a/Source/CBIOS/cbios.asm b/Source/CBIOS/cbios.asm index 26c55e33..98cf9510 100644 --- a/Source/CBIOS/cbios.asm +++ b/Source/CBIOS/cbios.asm @@ -3381,7 +3381,7 @@ DEVUNK .DB "UNK$" RST 08 ; CALL HBIOS LD A,D ; RESULTANT DEVICE TYPE PUSH DE ; NEED TO SAVE UNIT NUMBER (IN E) - AND $0F ; ISOLATE DEVICE BITS + AND $1F ; ISOLATE DEVICE BITS ADD A,A ; MULTIPLY BY TWO FOR WORD TABLE LD HL,DEVTBL ; POINT TO START OF DEVICE NAME TABLE CALL ADDHLA ; ADD A TO HL TO POINT TO TABLE ENTRY @@ -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..12411306 100644 --- a/Source/HBIOS/Config/RCEZ80_std.asm +++ b/Source/HBIOS/Config/RCEZ80_std.asm @@ -55,7 +55,7 @@ CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP VDAEMU_SERKBD .SET $FF ; VDA EMULATION: SERIAL KBD UNIT #, OR $FF FOR HW KBD ;; TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) -TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU] +TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY] TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958 TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VRCENABLE .SET FALSE ; VRC: ENABLE VGARC VIDEO/KBD DRIVER (VRC.ASM) @@ -71,6 +71,14 @@ PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) SDENABLE .SET FALSE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM) SDMODE .SET SDMODE_PIO ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT|USR|PIO|Z80R|EPITX|FZ80|GM|EZ512|K80W] SDCNT .SET 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD/SC/MT ONLY +; +CHENABLE .SET TRUE ; CH: ENABLE CH375/376 USB SUPPORT +CHNATIVEENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER +CHSCSIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE) +CHUFIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE) +CHNATIVEEZ80 .SET TRUE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE +CHNATIVEFORCE .SET FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED +; PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) ; LPTENABLE .SET FALSE ; LPT: ENABLE CENTRONICS PRINTER DRIVER (LPT.ASM) @@ -82,3 +90,5 @@ 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 + +EZ80TIMER .SET EZ80TMR_FIRM ; EZ80: TIMER TICK MODEL: EZ80TMR_[INT|FIRM] diff --git a/Source/HBIOS/Config/RCZ80_std.asm b/Source/HBIOS/Config/RCZ80_std.asm index 80e756b3..f8cce67c 100644 --- a/Source/HBIOS/Config/RCZ80_std.asm +++ b/Source/HBIOS/Config/RCZ80_std.asm @@ -72,7 +72,7 @@ ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) ; TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) -TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU] +TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY] TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958 TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VRCENABLE .SET FALSE ; VRC: ENABLE VGARC VIDEO/KBD DRIVER (VRC.ASM) @@ -92,6 +92,10 @@ SDMODE .SET SDMODE_PIO ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4 SDCNT .SET 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD/SC/MT ONLY ; CHENABLE .SET TRUE ; CH: ENABLE CH375/376 USB SUPPORT +CHNATIVEENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER +CHSCSIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE) +CHUFIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE) +CHNATIVEFORCE .SET FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED ; PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM) ; diff --git a/Source/HBIOS/ansi.asm b/Source/HBIOS/ansi.asm index 8ca7e7f5..3bd77be0 100644 --- a/Source/HBIOS/ansi.asm +++ b/Source/HBIOS/ansi.asm @@ -1554,4 +1554,4 @@ ANSI_DEVNUM .DB $FF ; TERMINAL DEVICE NUMBER ; E Light Cyan ; F Bright White ;============================================================= -; \ No newline at end of file +; diff --git a/Source/HBIOS/cfg_MASTER.asm b/Source/HBIOS/cfg_MASTER.asm index bb6a4b58..5eb061f9 100644 --- a/Source/HBIOS/cfg_MASTER.asm +++ b/Source/HBIOS/cfg_MASTER.asm @@ -503,3 +503,13 @@ 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) +CHNATIVEFORCE .EQU FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED (REQUIRES CHNATIVEENABLE) +CHNATIVEEZ80 .EQU FALSE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE + +_CH376_DATA_PORT .EQU $FF88 ; CH376: DATA PORT +_CH376_COMMAND_PORT .EQU $FF89 ; CH376: COMMAND PORT +_USB_MODULE_LEDS .EQU $FF8A ; CH376: LED CONTROL PORT diff --git a/Source/HBIOS/cfg_RCEZ80.asm b/Source/HBIOS/cfg_RCEZ80.asm index 2ad50ba6..eaedc78c 100644 --- a/Source/HBIOS/cfg_RCEZ80.asm +++ b/Source/HBIOS/cfg_RCEZ80.asm @@ -250,7 +250,7 @@ VDUENABLE .SET FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM) CVDUENABLE .SET FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM) GDCENABLE .SET FALSE ; GDC: ENABLE 7220 GDC VIDEO/KBD DRIVER (GDC.ASM) TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) -TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU] +TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY] TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958 TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) VGAENABLE .SET FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM) @@ -406,6 +406,12 @@ EZ80TMR_NONE .SET 0 ; DO NOT USE ON-BOARD TIMER TO GENERATE TICKS EZ80TMR_INT .SET 1 ; MARSHALL TIMER TICK INTERRUPTS FROM EZ80 TO HBIOS EZ80TMR_FIRM .SET 2 ; DELEGATE SYS TIMER HBIOS CALL TO EZ80 FIRMWARE (TIMER TICK INTS DISABLED) ; +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) +CHNATIVEFORCE .EQU FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED (REQUIRES CHNATIVEENABLE) +CHNATIVEEZ80 .EQU TRUE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE + EZ80UARTENABLE .SET TRUE ; EZ80 UART: ENABLE EZ80 UART0 DRIVER (EZ80UART.ASM) EZ80RTCENABLE .SET TRUE ; EZ80 ON CHIP RTC EZ80TIMER .SET EZ80TMR_FIRM ; EZ80: TIMER TICK MODEL: EZ80TMR_[INT|FIRM] diff --git a/Source/HBIOS/ch376-native/Makefile b/Source/HBIOS/ch376-native/Makefile new file mode 100644 index 00000000..95ab59ab --- /dev/null +++ b/Source/HBIOS/ch376-native/Makefile @@ -0,0 +1,107 @@ +SHELL := /bin/sh +SHELLFLAGS := -c -e -x +.ONESHELL: +MAKEFLAGS += --warn-undefined-variables +MAKEFLAGS += --no-builtin-rules +MAKEFLAGS += --always-make +ZCCRELFLAGS := -SO3 --max-allocs-per-node600000 --allow-unsafe-read --opt-code-speed + +SRC := ./source-doc/ +LIBS := -I./$(SRC)base-drv/ +ZCCFLAGS := +z80 -vn -startup=0 -clib=sdcc_iy -compiler=sdcc -Cs--std=c23 -Cs--Werror $(ZCCRELFLAGS) $(LIBS) + +ZCC_PATH := $(shell command -v zcc) +DOCKER_PATH := $(shell command -v docker) +ZCC := $(shell command -v zcc >/dev/null 2>&1 && echo zcc || echo 'docker run -w /host/${PWD} -v /:/host/ -u $(shell id -u ${USER}):$(shell id -g ${USER}) -t z88dk/z88dk:20250224 zcc') + +ifeq ($(ZCC_PATH),) + ifeq ($(DOCKER_PATH),) + .DEFAULT_GOAL := skip + else + $(info ZCC is set to use Docker to run zcc) + endif +else + $(info ZCC is set to $(ZCC_PATH)) +endif + +ASSDIR := ./ + +all: $(ASSDIR)base-drv.s $(ASSDIR)scsi-drv.s $(ASSDIR)ufi-drv.s $(ASSDIR)keyboard.s + +skip: + @echo "Unable to compile ch376 native to assembly. Install docker or z88dk." + exit 0 + +clean: + @rm -rf base-drv/*.s + rm -rf base-drv/*.asm + rm -rf scsi-drv/*.s + rm -rf scsi-drv/*.asm + rm -rf ufi-drv/*.s + rm -rf ufi-drv/*.asm + rm -rf keyboard/*.s + rm -rf keyboard/*.asm + rm ufi-drv.s + rm scsi-drv.s + rm base-drv.s + rm keyboard.s + +.PRECIOUS: $(ASSDIR)%.c.asm +$(ASSDIR)%.c.s: $(ASSDIR)%.c.asm + @mkdir -p $(dir $@) + echo "Converting $< to $@" + ${SRC}convert-for-uz80as.sh $< $@ + +define compile + @set -e + mkdir -p $(dir $@) + $(ZCC) $(ZCCFLAGS) --c-code-in-asm --assemble-only $< -o $@ + echo "Compiled $(notdir $@) from $(notdir $<)" +endef + +FIRMWARE_ALT = kyb-init ch376_init scsi-init ufi-init hbios-driver-storage + +define build_subsystem = +$$(ASSDIR)$(1).s: + @echo "Creating $(1).s" + echo "; Generated File -- not to be modify directly" > $$(ASSDIR)$(1).s + for dep in $$^; do + dep=$$$${dep#*/} + dep=$$$${dep#*/} + filename=$$$${dep##*/} + basename=$$$${filename%.*.*} + if echo "$(FIRMWARE_ALT)" | grep -w -q "$$$${basename}"; then + if [ -n "$$$${dep%%*.asm}" ]; then + echo '#include "'ch376-native/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s + else + echo '#include "'ch376-native/source-doc/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s + fi + else + echo '#IF (!CHNATIVEEZ80)' >> $$(ASSDIR)$(1).s + if [ -n "$$$${dep%%*.asm}" ]; then + echo '#include "'ch376-native/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s + else + echo '#include "'ch376-native/source-doc/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s + fi + echo '#ENDIF' >> $$(ASSDIR)$(1).s + fi + done + +$$(ASSDIR)$(1)/%.c.asm: $$(SRC)$(1)/%.c; $$(compile) +# $$(ASSDIR)$(1)/%.asm: $$(SRC)$(1)/%.asm; echo $$@ $$< + +$(1)_C_FILES := $$(wildcard $$(SRC)$(1)/*.c) +$(1)_ASM_FILES := $$(wildcard $$(SRC)$(1)/*.asm) +$(1)_C_S_FILES := $$(patsubst ./source-doc/%, ./%, $$($(1)_C_FILES:.c=.c.s)) +./$(1).s: $$($(1)_C_S_FILES) $$($(1)_ASM_FILES) +endef + +$(eval $(call build_subsystem,base-drv)) +$(eval $(call build_subsystem,scsi-drv)) +$(eval $(call build_subsystem,keyboard)) +$(eval $(call build_subsystem,ufi-drv)) + +.PHONY: format +format: SHELL:=/bin/bash +format: + @find \( -name "*.c" -o -name "*.h" \) -exec echo "formating {}" \; -exec clang-format -i {} \; diff --git a/Source/HBIOS/ch376-native/base-drv.asm b/Source/HBIOS/ch376-native/base-drv.asm new file mode 100644 index 00000000..67583ba6 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv.asm @@ -0,0 +1,106 @@ + +DELAY_FACTOR .EQU 640 + +CMD01_RD_USB_DATA0 .EQU $27 ; Read data block from current USB interrupt endpoint buffer or host endpoint receive buffer + ; output: length, data stream + +CMD10_WR_HOST_DATA .EQU $2C ; 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: + 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 & $FF) + bit 4, a ; _CH376_COMMAND_PORT & PARA_STATE_BUSY + + ld l, $0C ; USB_ERR_CH376_BLOCKED; + ret nz + + ld l, $0D ; USB_ERR_CH376_TIMEOUT + ret + +; uint8_t ch_read_data(uint8_t *buffer) __sdcccall(1); +_ch_read_data: + 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: + 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..e534c158 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv.s @@ -0,0 +1,39 @@ +; Generated File -- not to be modify directly +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/ch376.c.s" +#ENDIF +#include "ch376-native/base-drv/ch376_init.c.s" +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/class_hub.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/critical-section.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/dev_transfers.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/enumerate.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/enumerate_hub.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/enumerate_storage.c.s" +#ENDIF +#include "ch376-native/base-drv/hbios-driver-storage.c.s" +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/protocol.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/transfers.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/usb-base-drv.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/usb_state.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/base-drv/work-area.c.s" +#ENDIF diff --git a/Source/HBIOS/ch376-native/base-drv/.gitignore b/Source/HBIOS/ch376-native/base-drv/.gitignore new file mode 100644 index 00000000..f4cb8488 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/.gitignore @@ -0,0 +1 @@ +*.asm 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..31fce084 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/ch376.c.s @@ -0,0 +1,769 @@ +; +; 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.5.0 #15248 (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/ch376.c:6: void ch_command(const uint8_t command) __z88dk_fastcall { +; --------------------------------- +; Function ch_command +; --------------------------------- +_ch_command: +;source-doc/base-drv/ch376.c:8: while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0) + ld b,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 + djnz l_ch_command_00102 +l_ch_command_00104: +;source-doc/base-drv/ch376.c:19: CH376_COMMAND_PORT = command; + ld a, l + ld bc,_CH376_COMMAND_PORT + out (c), a +;source-doc/base-drv/ch376.c:20: } + ret +;source-doc/base-drv/ch376.c:24: 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:26: 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:28: 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:30: usb_error ch_get_status(void) { +; --------------------------------- +; Function ch_get_status +; --------------------------------- +_ch_get_status: +;source-doc/base-drv/ch376.c:31: ch_command(CH_CMD_GET_STATUS); + ld l,0x22 + call _ch_command +;source-doc/base-drv/ch376.c:32: 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:34: if (ch_status >= USB_FILERR_MIN && ch_status <= USB_FILERR_MAX) + cp 0x41 + jr C,l_ch_get_status_00102 + cp 0xb5 + jr NC,l_ch_get_status_00102 +;source-doc/base-drv/ch376.c:35: return ch_status; + ld l, a + jr l_ch_get_status_00126 +l_ch_get_status_00102: +;source-doc/base-drv/ch376.c:37: if (ch_status == CH_CMD_RET_SUCCESS) + cp 0x51 + jr NZ,l_ch_get_status_00105 +;source-doc/base-drv/ch376.c:38: return USB_ERR_OK; + ld l,0x00 + jr l_ch_get_status_00126 +l_ch_get_status_00105: +;source-doc/base-drv/ch376.c:40: if (ch_status == CH_USB_INT_SUCCESS) + cp 0x14 + jr NZ,l_ch_get_status_00107 +;source-doc/base-drv/ch376.c:41: return USB_ERR_OK; + ld l,0x00 + jr l_ch_get_status_00126 +l_ch_get_status_00107: +;source-doc/base-drv/ch376.c:43: if (ch_status == CH_USB_INT_CONNECT) + cp 0x15 + jr NZ,l_ch_get_status_00109 +;source-doc/base-drv/ch376.c:44: return USB_INT_CONNECT; + ld l,0x81 + jr l_ch_get_status_00126 +l_ch_get_status_00109: +;source-doc/base-drv/ch376.c:46: if (ch_status == CH_USB_INT_DISK_READ) + cp 0x1d + jr NZ,l_ch_get_status_00111 +;source-doc/base-drv/ch376.c:47: 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:49: if (ch_status == CH_USB_INT_DISK_WRITE) + cp 0x1e + jr NZ,l_ch_get_status_00113 +;source-doc/base-drv/ch376.c:50: 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:52: if (ch_status == CH_USB_INT_DISCONNECT) { + cp 0x16 + jr NZ,l_ch_get_status_00115 +;source-doc/base-drv/ch376.c:53: ch_cmd_set_usb_mode(5); + ld l,0x05 + call _ch_cmd_set_usb_mode +;source-doc/base-drv/ch376.c:54: 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:57: if (ch_status == CH_USB_INT_BUF_OVER) + cp 0x17 + jr NZ,l_ch_get_status_00117 +;source-doc/base-drv/ch376.c:58: 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:60: ch_status &= 0x2F; + and 0x2f +;source-doc/base-drv/ch376.c:62: if (ch_status == 0x2A) + cp 0x2a + jr NZ,l_ch_get_status_00119 +;source-doc/base-drv/ch376.c:63: return USB_ERR_NAK; + ld l,0x01 + jr l_ch_get_status_00126 +l_ch_get_status_00119: +;source-doc/base-drv/ch376.c:65: if (ch_status == 0x2E) + cp 0x2e + jr NZ,l_ch_get_status_00121 +;source-doc/base-drv/ch376.c:66: return USB_ERR_STALL; + ld l,0x02 + jr l_ch_get_status_00126 +l_ch_get_status_00121: +;source-doc/base-drv/ch376.c:68: ch_status &= 0x23; + and 0x23 +;source-doc/base-drv/ch376.c:70: if (ch_status == 0x20) + cp 0x20 + jr NZ,l_ch_get_status_00123 +;source-doc/base-drv/ch376.c:71: return USB_ERR_TIMEOUT; + ld l,0x03 + jr l_ch_get_status_00126 +l_ch_get_status_00123: +;source-doc/base-drv/ch376.c:73: if (ch_status == 0x23) + sub 0x23 + jr NZ,l_ch_get_status_00125 +;source-doc/base-drv/ch376.c:74: 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:76: return USB_ERR_UNEXPECTED_STATUS_FROM_; + ld l,0x08 +l_ch_get_status_00126: +;source-doc/base-drv/ch376.c:77: } + ret +;source-doc/base-drv/ch376.c:79: 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:98: uint8_t ch_probe(void) { +; --------------------------------- +; Function ch_probe +; --------------------------------- +_ch_probe: + push ix + ld ix,0 + add ix,sp + dec sp +;source-doc/base-drv/ch376.c:100: do { + ld (ix-1),0x05 +l_ch_probe_00103: +;source-doc/base-drv/ch376.c:83: ch_command(CH_CMD_CHECK_EXIST); + ld l,0x06 + call _ch_command +;source-doc/base-drv/ch376.c:84: CH376_DATA_PORT = (uint8_t)~0x55; + ld a,0xaa + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/ch376.c:85: delay(); + call _delay +;source-doc/base-drv/ch376.c:86: complement = CH376_DATA_PORT; + ld a, +((_CH376_DATA_PORT) / 256) + in a, (((_CH376_DATA_PORT) & 0xFF)) +;source-doc/base-drv/ch376.c:87: return complement == 0x55; + sub 0x55 + jr NZ,l_ch_probe_00102 +;source-doc/base-drv/ch376.c:101: if (ch_cmd_check_exist()) +;source-doc/base-drv/ch376.c:102: return true; + ld l,0x01 + jr l_ch_probe_00107 +l_ch_probe_00102: +;source-doc/base-drv/ch376.c:104: delay_medium(); + call _delay_medium +;source-doc/base-drv/ch376.c:105: } while (--i != 0); + dec (ix-1) + jr NZ,l_ch_probe_00103 +;source-doc/base-drv/ch376.c:107: return false; + ld l,0x00 +l_ch_probe_00107: +;source-doc/base-drv/ch376.c:108: } + inc sp + pop ix + ret +;source-doc/base-drv/ch376.c:110: usb_error ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall { +; --------------------------------- +; Function ch_cmd_set_usb_mode +; --------------------------------- +_ch_cmd_set_usb_mode: + ld c, l +;source-doc/base-drv/ch376.c:111: uint8_t result = 0; + ld b,0x00 +;source-doc/base-drv/ch376.c:113: CH376_COMMAND_PORT = CH_CMD_SET_USB_MODE; + ld a,0x15 + push bc + ld bc,_CH376_COMMAND_PORT + out (c), a +;source-doc/base-drv/ch376.c:114: delay(); + call _delay + pop bc +;source-doc/base-drv/ch376.c:115: CH376_DATA_PORT = mode; + ld a, c + push bc + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/ch376.c:116: delay(); + call _delay + pop bc +;source-doc/base-drv/ch376.c:120: while (result != CH_CMD_RET_SUCCESS && result != CH_CMD_RET_ABORT && --count != 0) { + ld c,0x7f +l_ch_cmd_set_usb_mode_00103: + ld a, b + sub 0x51 + jr NZ,l_ch_cmd_set_usb_mode_00146 + ld a,0x01 + jr l_ch_cmd_set_usb_mode_00147 +l_ch_cmd_set_usb_mode_00146: + xor a +l_ch_cmd_set_usb_mode_00147: + ld e,a + bit 0,a + jr NZ,l_ch_cmd_set_usb_mode_00105 + ld a, b + sub 0x5f + jr Z,l_ch_cmd_set_usb_mode_00105 + dec c + jr Z,l_ch_cmd_set_usb_mode_00105 +;source-doc/base-drv/ch376.c:121: result = CH376_DATA_PORT; + ld a, +((_CH376_DATA_PORT) / 256) + in a, (((_CH376_DATA_PORT) & 0xFF)) + ld b, a +;source-doc/base-drv/ch376.c:122: delay(); + push bc + call _delay + pop bc + jr l_ch_cmd_set_usb_mode_00103 +l_ch_cmd_set_usb_mode_00105: +;source-doc/base-drv/ch376.c:125: return (result == CH_CMD_RET_SUCCESS) ? USB_ERR_OK : USB_ERR_FAIL; + ld a, e + or a + jr Z,l_ch_cmd_set_usb_mode_00108 + ld l,0x00 + jr l_ch_cmd_set_usb_mode_00109 +l_ch_cmd_set_usb_mode_00108: + ld l,0x0e +l_ch_cmd_set_usb_mode_00109: +;source-doc/base-drv/ch376.c:126: } + ret +;source-doc/base-drv/ch376.c:128: 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:129: ch_command(CH_CMD_GET_IC_VER); + ld l,0x01 + call _ch_command +;source-doc/base-drv/ch376.c:130: 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:131: } + ret +;source-doc/base-drv/ch376.c:133: void ch_issue_token(const uint8_t toggle_bit, const uint8_t endpoint, const ch376_pid pid) { +; --------------------------------- +; Function ch_issue_token +; --------------------------------- +_ch_issue_token: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/ch376.c:134: ch_command(CH_CMD_ISSUE_TKN_X); + ld l,0x4e + call _ch_command +;source-doc/base-drv/ch376.c:135: CH376_DATA_PORT = toggle_bit; + ld a,(ix+4) + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/ch376.c:136: CH376_DATA_PORT = endpoint << 4 | pid; + ld a,(ix+5) + add a, a + add a, a + add a, a + add a, a + or (ix+6) + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/ch376.c:137: } + pop ix + ret +;source-doc/base-drv/ch376.c:139: 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:140: 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:141: } + ret +;source-doc/base-drv/ch376.c:143: 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:144: 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:145: } + ret +;source-doc/base-drv/ch376.c:147: 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:149: 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:151: 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:153: 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 +;source-doc/base-drv/ch376.c:157: 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:158: return USB_ERR_OK; + ld l,0x00 + jp l_ch_data_in_transfer_00111 +l_ch_data_in_transfer_00102: +;source-doc/base-drv/ch376.c:160: USB_MODULE_LEDS = 0x01; + ld a,0x01 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:161: do { + ld c,(ix+8) + ld b,(ix+9) +l_ch_data_in_transfer_00107: +;source-doc/base-drv/ch376.c:162: ch_issue_token_in(endpoint); + ld l,c + ld h,b + push hl + call _ch_issue_token_in +;source-doc/base-drv/ch376.c:164: result = ch_long_wait_int_and_get_status(); + call _ch_long_wait_int_and_get_statu + ld a, l + pop bc + ld l, a +;source-doc/base-drv/ch376.c:165: CHECK(result); + or a + jr NZ,l_ch_data_in_transfer_00110 +;source-doc/base-drv/ch376.c:167: endpoint->toggle = !endpoint->toggle; + ld e, c + ld d, b + ld l, e + ld h, d + ld a, (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:169: count = ch_read_data(buffer); + push bc + ld l,(ix+4) + ld h,(ix+5) + call _ch_read_data + ld e, a + pop bc +;source-doc/base-drv/ch376.c:171: if (count == 0) { + ld a, e +;source-doc/base-drv/ch376.c:172: 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:173: return USB_ERR_DATA_ERROR; + ld l,0x04 + jr l_ch_data_in_transfer_00111 +l_ch_data_in_transfer_00106: +;source-doc/base-drv/ch376.c:176: buffer += count; + ld a,(ix+4) + add a, e + ld (ix+4),a + jr NC,l_ch_data_in_transfer_00148 + inc (ix+5) +l_ch_data_in_transfer_00148: +;source-doc/base-drv/ch376.c:177: 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:178: } while (buffer_size > 0); + xor a + cp (ix+6) + sbc a,(ix+7) + jp PO, l_ch_data_in_transfer_00149 + xor 0x80 +l_ch_data_in_transfer_00149: + jp M, l_ch_data_in_transfer_00107 +;source-doc/base-drv/ch376.c:180: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:181: return USB_ERR_OK; + ld l,0x00 + jr l_ch_data_in_transfer_00111 +;source-doc/base-drv/ch376.c:183: done: +l_ch_data_in_transfer_00110: +;source-doc/base-drv/ch376.c:184: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:185: return result; +l_ch_data_in_transfer_00111: +;source-doc/base-drv/ch376.c:186: } + pop ix + ret +;source-doc/base-drv/ch376.c:189: usb_error ch_data_in_transfer_n(uint8_t *const buffer, uint8_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:193: USB_MODULE_LEDS = 0x01; + ld a,0x01 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:195: ch_issue_token_in(endpoint); + ld l,(ix+8) + ld h,(ix+9) + call _ch_issue_token_in +;source-doc/base-drv/ch376.c:197: 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:199: endpoint->toggle = !endpoint->toggle; + ld l,(ix+8) + ld h,(ix+9) + ld a, (hl) + and 0x01 + xor 0x01 + and 0x01 + ld c, a + ld a, (hl) + and 0xfe + or c + ld (hl), a +;source-doc/base-drv/ch376.c:201: count = ch_read_data(buffer); + ld l,(ix+4) + ld h,(ix+5) + call _ch_read_data +;source-doc/base-drv/ch376.c:203: *buffer_size = count; + ld c,(ix+6) + ld b,(ix+7) + ld (bc), a +;source-doc/base-drv/ch376.c:205: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:207: return USB_ERR_OK; + ld l,0x00 + jr l_ch_data_in_transfer_n_00104 +;source-doc/base-drv/ch376.c:208: done: +l_ch_data_in_transfer_n_00103: +;source-doc/base-drv/ch376.c:209: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:210: return result; +l_ch_data_in_transfer_n_00104: +;source-doc/base-drv/ch376.c:211: } + pop ix + ret +;source-doc/base-drv/ch376.c:213: 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 + dec sp +;source-doc/base-drv/ch376.c:216: 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-1),a +;source-doc/base-drv/ch376.c:218: 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:220: while (buffer_length > 0) { +l_ch_data_out_transfer_00103: + xor a + cp (ix+6) + sbc a,(ix+7) + jp PO, l_ch_data_out_transfer_00139 + xor 0x80 +l_ch_data_out_transfer_00139: + jp P, l_ch_data_out_transfer_00105 +;source-doc/base-drv/ch376.c:221: const uint8_t size = max_packet_size < buffer_length ? max_packet_size : buffer_length; + ld d,(ix-1) + ld e,0x00 + ld a, d + sub (ix+6) + ld a, e + sbc a,(ix+7) + jp PO, l_ch_data_out_transfer_00140 + xor 0x80 +l_ch_data_out_transfer_00140: + jp P, l_ch_data_out_transfer_00109 + jr l_ch_data_out_transfer_00110 +l_ch_data_out_transfer_00109: + ld d,(ix+6) + ld e,(ix+7) +l_ch_data_out_transfer_00110: +;source-doc/base-drv/ch376.c:222: 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:223: 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:224: ch_issue_token_out(endpoint); + ld l,c + ld h,b + push hl + call _ch_issue_token_out +;source-doc/base-drv/ch376.c:226: CHECK(ch_long_wait_int_and_get_status()); + 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:228: endpoint->toggle = !endpoint->toggle; + ld e, c + ld d, b + ld l, e + ld h, d + 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:231: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:232: return USB_ERR_OK; + ld l,0x00 + jr l_ch_data_out_transfer_00107 +;source-doc/base-drv/ch376.c:234: done: +l_ch_data_out_transfer_00106: +;source-doc/base-drv/ch376.c:235: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/ch376.c:236: return result; +l_ch_data_out_transfer_00107: +;source-doc/base-drv/ch376.c:237: } + inc sp + pop ix + ret +;source-doc/base-drv/ch376.c:239: 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:240: ch_command(CH_CMD_SET_USB_ADDR); + push hl + ld l,0x13 + call _ch_command + pop hl +;source-doc/base-drv/ch376.c:241: CH376_DATA_PORT = device_address; + ld a, l + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/ch376.c:242: } + ret diff --git a/Source/HBIOS/ch376-native/base-drv/ch376_init.c.s b/Source/HBIOS/ch376-native/base-drv/ch376_init.c.s new file mode 100644 index 00000000..bdd67453 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/ch376_init.c.s @@ -0,0 +1,293 @@ +; +; Generated from source-doc/base-drv/ch376_init.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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/ch376_init.c:4: static uint16_t wait_for_state(const uint8_t loop_counter, uint8_t state, const uint8_t desired_state) __sdcccall(1) { +; --------------------------------- +; Function wait_for_state +; --------------------------------- +_wait_for_state: + push ix + ld ix,0 + add ix,sp + dec sp + ld (ix-1),a +;source-doc/base-drv/ch376_init.c:5: uint16_t r = state; + ld c,l + ld e,l +;source-doc/base-drv/ch376_init.c:7: for (uint8_t i = 0; i < loop_counter; i++) { + ld d,0x00 + ld b,d +l_wait_for_state_00108: + ld a, b + sub (ix-1) + jr NC,l_wait_for_state_00106 +;source-doc/base-drv/ch376_init.c:8: if (state == desired_state) + ld a,(ix+4) + sub c + jr Z,l_wait_for_state_00106 +;source-doc/base-drv/ch376_init.c:11: if (i & 1) + bit 0, b + jr Z,l_wait_for_state_00104 +;source-doc/base-drv/ch376_init.c:12: print_string("\b $"); + push bc + ld hl,ch376_init_str_0 + call _print_string + pop bc + jr l_wait_for_state_00105 +l_wait_for_state_00104: +;source-doc/base-drv/ch376_init.c:14: print_string("\b*$"); + push bc + ld hl,ch376_init_str_1 + call _print_string + pop bc +l_wait_for_state_00105: +;source-doc/base-drv/ch376_init.c:16: r = usb_init(state); + push bc + ld l, c + call _usb_init + ex de, hl + pop bc +;source-doc/base-drv/ch376_init.c:17: state = r & 255; + ld c, e +;source-doc/base-drv/ch376_init.c:7: for (uint8_t i = 0; i < loop_counter; i++) { + inc b + jr l_wait_for_state_00108 +l_wait_for_state_00106: +;source-doc/base-drv/ch376_init.c:20: return r; +;source-doc/base-drv/ch376_init.c:21: } + inc sp + pop ix + pop hl + inc sp + jp (hl) +ch376_init_str_0: + DEFB 0x08 + DEFM " $" + DEFB 0x00 +ch376_init_str_1: + DEFB 0x08 + DEFM "*$" + DEFB 0x00 +;source-doc/base-drv/ch376_init.c:25: static void _chnative_init(bool forced) { +; --------------------------------- +; Function _chnative_init +; --------------------------------- +__chnative_init: + push ix + ld ix,0 + add ix,sp + dec sp +;source-doc/base-drv/ch376_init.c:28: const uint8_t loop_counter = forced ? 40 : 5; + bit 0,(ix+4) + jr Z,l__chnative_init_00113 + ld a,0x28 + jr l__chnative_init_00114 +l__chnative_init_00113: + ld a,0x05 +l__chnative_init_00114: + ld (ix-1),a +;source-doc/base-drv/ch376_init.c:30: print_string("\r\nCH376: *$"); + ld hl,ch376_init_str_2 + call _print_string +;source-doc/base-drv/ch376_init.c:32: r = wait_for_state(loop_counter, state, 1); + ld a,0x01 + push af + inc sp + ld l,0x00 + ld a,(ix-1) + call _wait_for_state +;source-doc/base-drv/ch376_init.c:33: state = r & 255; +;source-doc/base-drv/ch376_init.c:35: print_string("\bPRESENT (VER $"); + push de + ld hl,ch376_init_str_3 + call _print_string + pop de +;source-doc/base-drv/ch376_init.c:37: r = usb_init(state); + ld l, e + call _usb_init + ex de, hl +;source-doc/base-drv/ch376_init.c:38: state = r & 255; + ld c, e +;source-doc/base-drv/ch376_init.c:39: if (state != 2) { + ld a, c + sub 0x02 + jr Z,l__chnative_init_00102 +;source-doc/base-drv/ch376_init.c:40: print_string("\rCH376: $"); + ld hl,ch376_init_str_4 + call _print_string +;source-doc/base-drv/ch376_init.c:41: print_string("VERSION FAILURE\r\n$"); + ld hl,ch376_init_str_5 + call _print_string +;source-doc/base-drv/ch376_init.c:42: return; + jr l__chnative_init_00111 +l__chnative_init_00102: +;source-doc/base-drv/ch376_init.c:45: print_hex(r >> 8); + push bc + ld l, d + call _print_hex +;source-doc/base-drv/ch376_init.c:46: print_string(ch376_driver_version); + ld hl,_ch376_driver_version + call _print_string +;source-doc/base-drv/ch376_init.c:48: print_string("USB: *$"); + ld hl,ch376_init_str_6 + call _print_string + pop bc +;source-doc/base-drv/ch376_init.c:50: r = wait_for_state(loop_counter, state, 3); + ld a,0x03 + push af + inc sp + ld l, c + ld a,(ix-1) + call _wait_for_state +;source-doc/base-drv/ch376_init.c:51: state = r & 255; +;source-doc/base-drv/ch376_init.c:53: if (state == 2) { + ld a, e + sub 0x02 + jr NZ,l__chnative_init_00104 +;source-doc/base-drv/ch376_init.c:54: print_string("\bDISCONNECTED$"); + ld hl,ch376_init_str_7 + call _print_string +;source-doc/base-drv/ch376_init.c:55: return; + jr l__chnative_init_00111 +l__chnative_init_00104: +;source-doc/base-drv/ch376_init.c:58: print_string("\bCONNECTED$"); + push de + ld hl,ch376_init_str_8 + call _print_string + pop de +;source-doc/base-drv/ch376_init.c:61: r = usb_init(state); + ld l, e + call _usb_init + ex de, hl +;source-doc/base-drv/ch376_init.c:62: state = r & 255; + ld c, e +;source-doc/base-drv/ch376_init.c:64: for (uint8_t i = 0; i < loop_counter; i++) { + ld b,0x00 +l__chnative_init_00109: + ld a, b + sub (ix-1) + jr NC,l__chnative_init_00111 +;source-doc/base-drv/ch376_init.c:65: if (r >> 8 != 0) + ld a,0x00 + or d + jr NZ,l__chnative_init_00111 +;source-doc/base-drv/ch376_init.c:68: print_string(".$"); + push bc + ld hl,ch376_init_str_9 + call _print_string + pop bc +;source-doc/base-drv/ch376_init.c:69: r = usb_init(state); + push bc + ld l, c + call _usb_init + ex de, hl + pop bc +;source-doc/base-drv/ch376_init.c:70: state = r & 255; + ld c, e +;source-doc/base-drv/ch376_init.c:64: for (uint8_t i = 0; i < loop_counter; i++) { + inc b + jr l__chnative_init_00109 +l__chnative_init_00111: +;source-doc/base-drv/ch376_init.c:72: } + inc sp + pop ix + ret +ch376_init_str_2: + DEFB 0x0d + DEFB 0x0a + DEFM "CH376: *$" + DEFB 0x00 +ch376_init_str_3: + DEFB 0x08 + DEFM "PRESENT (VER $" + DEFB 0x00 +ch376_init_str_4: + DEFB 0x0d + DEFM "CH376: $" + DEFB 0x00 +ch376_init_str_5: + DEFM "VERSION FAILURE" + DEFB 0x0d + DEFB 0x0a + DEFM "$" + DEFB 0x00 +ch376_init_str_6: + DEFM "USB: *$" + DEFB 0x00 +ch376_init_str_7: + DEFB 0x08 + DEFM "DISCONNECTED$" + DEFB 0x00 +ch376_init_str_8: + DEFB 0x08 + DEFM "CONNECTED$" + DEFB 0x00 +ch376_init_str_9: + DEFM ".$" + DEFB 0x00 +;source-doc/base-drv/ch376_init.c:74: void chnative_init_force(void) { _chnative_init(true); } +; --------------------------------- +; Function chnative_init_force +; --------------------------------- +_chnative_init_force: + ld a,0x01 + push af + inc sp + call __chnative_init + inc sp + ret +;source-doc/base-drv/ch376_init.c:76: void chnative_init(void) { _chnative_init(false); } +; --------------------------------- +; Function chnative_init +; --------------------------------- +_chnative_init: + xor a + push af + inc sp + call __chnative_init + inc sp + ret 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..27677a28 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/class_hub.c.s @@ -0,0 +1,85 @@ +; +; 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.5.0 #15248 (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/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: +;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 a,l + ld c,h + inc hl + ld b, (hl) + ld l, a + ld h, c + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + ld c, 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: } + 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/critical-section.c.s b/Source/HBIOS/ch376-native/base-drv/critical-section.c.s new file mode 100644 index 00000000..62766348 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/critical-section.c.s @@ -0,0 +1,67 @@ +; +; Generated from source-doc/base-drv/critical-section.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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 + +_in_critical_usb_section: + DEFS 1 + +#ENDIF + +;-------------------------------------------------------- +; absolute external ram data +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;source-doc/base-drv/critical-section.c:6: void critical_begin() { in_critical_usb_section++; } +; --------------------------------- +; Function critical_begin +; --------------------------------- +_critical_begin: + ld hl,_in_critical_usb_section + inc (hl) + ret +;source-doc/base-drv/critical-section.c:8: void critical_end() { in_critical_usb_section--; } +; --------------------------------- +; Function critical_end +; --------------------------------- +_critical_end: + ld hl,_in_critical_usb_section + dec (hl) + ret +_in_critical_usb_section: + DEFB +0x00 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..7019e002 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/dev_transfers.c.s @@ -0,0 +1,449 @@ +; +; 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.5.0 #15248 (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/dev_transfers.c:23: * See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer +; --------------------------------- +; Function usbdev_control_transfer +; --------------------------------- +_usbdev_control_transfer: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/dev_transfers.c:24: * + 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+8) + ld d,(ix+9) + ld c,a + push bc + push de + ld l,(ix+6) + ld h,(ix+7) + push hl + call _usb_control_transfer + pop af + pop af + pop af +;source-doc/base-drv/dev_transfers.c:25: * @param device the usb device + pop ix + ret +;source-doc/base-drv/dev_transfers.c:27: * @param buffer Pointer of data to send or receive into +; --------------------------------- +; Function usbdev_blk_out_trnsfer +; --------------------------------- +_usbdev_blk_out_trnsfer: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/dev_transfers.c:30: usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) { + 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:32: } + pop hl + ld l,c + ld h,b + ld a,(hl) + push 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:34: usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) { + ld a, l + sub 0x02 + jr NZ,l_usbdev_blk_out_trnsfer_00102 +;source-doc/base-drv/dev_transfers.c:35: usb_error result; + inc bc + ld a, (bc) + ld b, a + pop hl + ld a,(hl) + push hl + rlca + rlca + rlca + rlca + and 0x0f + ld c, a + ld l, e + ld h, d + ld a, (hl) + rrca + and 0x07 + push de + push bc + inc sp + ld h, c + ld l,a + push hl + call _usbtrn_clear_endpoint_halt + pop af + inc sp + pop de +;source-doc/base-drv/dev_transfers.c:36: + ex de, hl + res 0, (hl) +;source-doc/base-drv/dev_transfers.c:37: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT]; + ld l,0x02 +;source-doc/base-drv/dev_transfers.c:43: endpoint->toggle = 0; +l_usbdev_blk_out_trnsfer_00102: +;source-doc/base-drv/dev_transfers.c:44: return USB_ERR_STALL; + ld sp, ix + pop ix + ret +;source-doc/base-drv/dev_transfers.c:46: +; --------------------------------- +; Function usbdev_bulk_in_transfer +; --------------------------------- +_usbdev_bulk_in_transfer: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/dev_transfers.c:49: done: + ld c,(ix+4) + ld b,(ix+5) + ld hl,0x0006 + add hl, bc +;source-doc/base-drv/dev_transfers.c:51: } + pop de + ld e,c + ld d,b + ex de,hl + ld a,(hl) + push 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:53: usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) { + ld a, l + sub 0x02 + jr NZ,l_usbdev_bulk_in_transfer_00102 +;source-doc/base-drv/dev_transfers.c:54: usb_error result; + inc bc + ld a, (bc) + ld b, a + pop hl + ld a,(hl) + push hl + rlca + rlca + rlca + rlca + and 0x0f + ld c, a + ld l, e + ld h, d + ld a, (hl) + rrca + and 0x07 + push de + push bc + inc sp + ld h, c + ld l,a + push hl + call _usbtrn_clear_endpoint_halt + pop af + inc sp + pop de +;source-doc/base-drv/dev_transfers.c:55: + ex de, hl + res 0, (hl) +;source-doc/base-drv/dev_transfers.c:56: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN]; + ld l,0x02 +;source-doc/base-drv/dev_transfers.c:61: usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size); +l_usbdev_bulk_in_transfer_00102: +;source-doc/base-drv/dev_transfers.c:62: endpoint->toggle = 0; + ld sp, ix + pop ix + ret +;source-doc/base-drv/dev_transfers.c:64: } +; --------------------------------- +; Function usbdev_dat_in_trnsfer +; --------------------------------- +_usbdev_dat_in_trnsfer: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/dev_transfers.c:70: + ld c,(ix+4) + ld b,(ix+5) + ld e, c + ld d, b + inc de + inc de + inc de + push de + ld a,(ix+10) + ld e, a + add a, a + add a, e + pop de + add a, e + ld e, a + ld a,0x00 + adc a, d + ld d, a +;source-doc/base-drv/dev_transfers.c:72: uint8_t *const buffer, + pop hl + ld l,c + ld h,b + ld a,(hl) + push 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:74: const usb_endpoint_type endpoint_type) { + ld a, l + sub 0x02 + jr NZ,l_usbdev_dat_in_trnsfer_00102 +;source-doc/base-drv/dev_transfers.c:75: usb_error result; + inc bc + ld a, (bc) + ld b, a + pop hl + ld a,(hl) + push hl + rlca + rlca + rlca + rlca + and 0x0f + ld c, a + ld l, e + ld h, d + ld a, (hl) + rrca + and 0x07 + push de + push bc + inc sp + ld h, c + ld l,a + push hl + call _usbtrn_clear_endpoint_halt + pop af + inc sp + pop de +;source-doc/base-drv/dev_transfers.c:76: + ex de, hl + res 0, (hl) +;source-doc/base-drv/dev_transfers.c:77: endpoint_param *const endpoint = &device->endpoints[endpoint_type]; + ld l,0x02 +;source-doc/base-drv/dev_transfers.c:82: usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size); +l_usbdev_dat_in_trnsfer_00102: +;source-doc/base-drv/dev_transfers.c:83: endpoint->toggle = 0; + ld sp, ix + pop ix + ret +;source-doc/base-drv/dev_transfers.c:85: } +; --------------------------------- +; Function usbdev_dat_in_trnsfer_0 +; --------------------------------- +_usbdev_dat_in_trnsfer_0: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/dev_transfers.c:88: done: + 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:90: } + pop hl + ld l,c + ld h,b + ld a,(hl) + push hl + rlca + rlca + rlca + rlca + and 0x0f + ld l,(ix+8) + ld h,0x00 + push bc + push de + push de + push af + inc sp + 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:92: usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) { + ld a, l + sub 0x02 + jr NZ,l_usbdev_dat_in_trnsfer_0_00102 +;source-doc/base-drv/dev_transfers.c:93: usb_error result; + inc bc + ld a, (bc) + ld b, a + pop hl + ld a,(hl) + push hl + rlca + rlca + rlca + rlca + and 0x0f + ld c, a + ld l, e + ld h, d + ld a, (hl) + rrca + and 0x07 + push de + push bc + inc sp + ld h, c + ld l,a + push hl + call _usbtrn_clear_endpoint_halt + pop af + inc sp + pop de +;source-doc/base-drv/dev_transfers.c:94: + ex de, hl + res 0, (hl) +;source-doc/base-drv/dev_transfers.c:95: endpoint_param *const endpoint = &device->endpoints[0]; + ld l,0x02 +;source-doc/base-drv/dev_transfers.c:98: +l_usbdev_dat_in_trnsfer_0_00102: +;source-doc/base-drv/dev_transfers.c:99: if (result == USB_ERR_STALL) { + ld sp, ix + pop ix + ret 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..7b99952f --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/enumerate.c.s @@ -0,0 +1,1085 @@ +; +; 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.5.0 #15248 (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/enumerate.c:13: static usb_error adv_to_next_desc(_working *const working, const uint8_t descriptor_type) __sdcccall(1) { +; --------------------------------- +; Function adv_to_next_desc +; --------------------------------- +_adv_to_next_desc: + push ix + ld ix,0 + add ix,sp + push af + push af + ex de, hl +;source-doc/base-drv/enumerate.c:15: const uint8_t *buffer_end = working->config.buffer + MAX_CONFIG_SIZE; + ld hl,0x00ab + add hl, de + ex (sp), hl +;source-doc/base-drv/enumerate.c:17: if (working->ptr >= buffer_end) + ld hl,0x001b + add hl, de + ld (ix-2),l + ld (ix-1),h + pop de + pop hl + ld a,(hl) + push hl + push de + inc hl + ld b,(hl) + ld c,a + sub (ix-4) + ld a, b + sbc a,(ix-3) + jr C,l_adv_to_next_desc_00102 +;source-doc/base-drv/enumerate.c:18: return USB_ERR_BUFF_TO_LARGE; + ld a,0x84 + jr l_adv_to_next_desc_00110 +l_adv_to_next_desc_00102: +;source-doc/base-drv/enumerate.c:20: d = (usb_descriptor_t *)working->ptr; + ld e, c + ld d, b +;source-doc/base-drv/enumerate.c:22: do { +l_adv_to_next_desc_00105: +;source-doc/base-drv/enumerate.c:23: working->ptr += d->bLength; + ld a, (de) + add a, c + ld c, a + ld a,0x00 + adc a, b + ld b, a + ld l,(ix-2) + ld h,(ix-1) + ld (hl), c + inc hl + ld (hl), b +;source-doc/base-drv/enumerate.c:25: if (working->ptr >= buffer_end) + ld a, c + sub (ix-4) + ld a, b + sbc a,(ix-3) + jr C,l_adv_to_next_desc_00104 +;source-doc/base-drv/enumerate.c:26: return USB_ERR_BUFF_TO_LARGE; + ld a,0x84 + jr l_adv_to_next_desc_00110 +l_adv_to_next_desc_00104: +;source-doc/base-drv/enumerate.c:17: if (working->ptr >= buffer_end) + pop de + pop hl + ld c,(hl) + push hl + push de + inc hl + ld b, (hl) +;source-doc/base-drv/enumerate.c:28: d = (usb_descriptor_t *)working->ptr; + ld e, c + ld d, b +;source-doc/base-drv/enumerate.c:29: } while (d->bDescriptorType != descriptor_type); + ld l, e + ld h, d + inc hl + ld a, (hl) + sub (ix+4) + jr NZ,l_adv_to_next_desc_00105 +;source-doc/base-drv/enumerate.c:31: if (working->ptr + d->bLength >= buffer_end) + ld a, (de) + ld l, a + ld h,0x00 + add hl, bc + ld a, l + sub (ix-4) + ld a, h + sbc a,(ix-3) + jr C,l_adv_to_next_desc_00109 +;source-doc/base-drv/enumerate.c:32: return USB_ERR_BUFF_TO_LARGE; + ld a,0x84 + jr l_adv_to_next_desc_00110 +l_adv_to_next_desc_00109: +;source-doc/base-drv/enumerate.c:34: return USB_ERR_OK; + xor a +l_adv_to_next_desc_00110: +;source-doc/base-drv/enumerate.c:35: } + ld sp, ix + pop ix + pop hl + inc sp + jp (hl) +;source-doc/base-drv/enumerate.c:37: void parse_endpoint_keyboard(device_config_keyboard *const keyboard_config, const endpoint_descriptor const *pEndpoint) +; --------------------------------- +; Function parse_endpoint_keyboard +; --------------------------------- +_parse_endpoint_keyboard: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/enumerate.c:39: endpoint_param *const ep = &keyboard_config->endpoints[0]; + inc hl + inc hl + inc hl +;source-doc/base-drv/enumerate.c:40: ep->number = pEndpoint->bEndpointAddress; + ld c,l + ld b,h + ex (sp),hl + ld l, e + ld h, d + inc hl + inc hl + ld a, (hl) + pop hl + push hl + rlca + and 0x0e + push bc + ld c, a + ld a, (hl) + and 0xf1 + or c + ld (hl), a +;source-doc/base-drv/enumerate.c:41: ep->toggle = 0; + pop hl + ld c,l + ld b,h + res 0, (hl) +;source-doc/base-drv/enumerate.c:42: ep->max_packet_sizex = calc_max_packet_sizex(pEndpoint->wMaxPacketSize); + 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:43: } + ld sp, ix + pop ix + ret +;source-doc/base-drv/enumerate.c:45: 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:46: 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:47: if (p->bInterfaceClass == 2) + ld hl,5 + add hl,bc + ld a,(hl) + ld e,a + sub 0x02 + jr NZ,l_identify_class_driver_00102 +;source-doc/base-drv/enumerate.c:48: return USB_IS_CDC; + ld l,0x03 + jr l_identify_class_driver_00118 +l_identify_class_driver_00102: +;source-doc/base-drv/enumerate.c:50: if (p->bInterfaceClass == 8 && (p->bInterfaceSubClass == 6 || p->bInterfaceSubClass == 5) && p->bInterfaceProtocol == 80) + ld a, e + sub 0x08 + jr NZ,l_identify_class_driver_00199 + ld a,0x01 + jr l_identify_class_driver_00200 +l_identify_class_driver_00199: + xor a +l_identify_class_driver_00200: + 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:51: 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:53: 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:54: return USB_IS_FLOPPY; + ld l,0x01 + jr l_identify_class_driver_00118 +l_identify_class_driver_00109: +;source-doc/base-drv/enumerate.c:56: 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:57: return USB_IS_HUB; + ld l,0x0f + jr l_identify_class_driver_00118 +l_identify_class_driver_00113: +;source-doc/base-drv/enumerate.c:59: if (p->bInterfaceClass == 3) + ld a, e + sub 0x03 + jr NZ,l_identify_class_driver_00117 +;source-doc/base-drv/enumerate.c:60: return USB_IS_KEYBOARD; + ld l,0x04 + jr l_identify_class_driver_00118 +l_identify_class_driver_00117: +;source-doc/base-drv/enumerate.c:62: return USB_IS_UNKNOWN; + ld l,0x06 +l_identify_class_driver_00118: +;source-doc/base-drv/enumerate.c:63: } + pop ix + ret +;source-doc/base-drv/enumerate.c:65: 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:68: 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:69: return USB_ERR_OK; + or a + jr NZ,l_op_interface_next_00102 + ld l,a + jr l_op_interface_next_00106 +l_op_interface_next_00102: +;source-doc/base-drv/enumerate.c:71: CHECK(adv_to_next_desc(working, USB_DESCR_INTERFACE)); + push de + ld a,0x04 + push af + inc sp + ex de,hl + call _adv_to_next_desc + pop de + ld l, a + or a + ret NZ +;source-doc/base-drv/enumerate.c:72: return op_id_class_drv(working); + ex de, hl + call _op_id_class_drv + ld l, a +;source-doc/base-drv/enumerate.c:74: done: +;source-doc/base-drv/enumerate.c:75: return result; +l_op_interface_next_00106: +;source-doc/base-drv/enumerate.c:76: } + ret +;source-doc/base-drv/enumerate.c:78: usb_error op_endpoint_next(_working *const working) __sdcccall(1) { +; --------------------------------- +; Function op_endpoint_next +; --------------------------------- +_op_endpoint_next: +;source-doc/base-drv/enumerate.c:81: if (working->endpoint_count != 0 && --working->endpoint_count > 0) { + ld a, l + add a,0x17 + ld c, a + ld a, h + adc a,0x00 + ld b, a + ld a, (bc) + or a + jr Z,l_op_endpoint_next_00104 + dec a + ld (bc), a + or a + jr Z,l_op_endpoint_next_00104 +;source-doc/base-drv/enumerate.c:82: CHECK(adv_to_next_desc(working, USB_DESCR_ENDPOINT)); + push hl + ld a,0x05 + push af + inc sp + call _adv_to_next_desc + pop hl + ld c, a + or a + jr NZ,l_op_endpoint_next_00106 +;source-doc/base-drv/enumerate.c:83: return op_parse_endpoint(working); + jp _op_parse_endpoint + jr l_op_endpoint_next_00107 +l_op_endpoint_next_00104: +;source-doc/base-drv/enumerate.c:86: return op_interface_next(working); + call _op_interface_next + ld a, l + jr l_op_endpoint_next_00107 +;source-doc/base-drv/enumerate.c:88: done: +l_op_endpoint_next_00106: +;source-doc/base-drv/enumerate.c:89: return result; + ld a, c +l_op_endpoint_next_00107: +;source-doc/base-drv/enumerate.c:90: } + ret +;source-doc/base-drv/enumerate.c:92: usb_error op_parse_endpoint(_working *const working) __sdcccall(1) { +; --------------------------------- +; Function op_parse_endpoint +; --------------------------------- +_op_parse_endpoint: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/enumerate.c:93: const endpoint_descriptor *endpoint = (endpoint_descriptor *)working->ptr; + ld de,0x001c + ld c,l + ld b,h + add hl, de + ld a, (hl) + dec hl + ld l, (hl) + ld (ix-2),l + ld (ix-1),a +;source-doc/base-drv/enumerate.c:94: 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:96: 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:98: case USB_IS_MASS_STORAGE: { +l_op_parse_endpoint_00102: +;source-doc/base-drv/enumerate.c:99: parse_endpoints((device_config_storage *)device, endpoint); + push bc + ld l,(ix-2) + ld h,(ix-1) + push hl + push de + call _parse_endpoints + pop af + pop af + pop bc +;source-doc/base-drv/enumerate.c:100: break; + jr l_op_parse_endpoint_00104 +;source-doc/base-drv/enumerate.c:103: case USB_IS_KEYBOARD: { +l_op_parse_endpoint_00103: +;source-doc/base-drv/enumerate.c:104: parse_endpoint_keyboard((device_config_keyboard *)device, endpoint); + ex de, hl + push bc + ld e,(ix-2) + ld d,(ix-1) + call _parse_endpoint_keyboard + pop bc +;source-doc/base-drv/enumerate.c:107: } +l_op_parse_endpoint_00104: +;source-doc/base-drv/enumerate.c:109: return op_endpoint_next(working); + ld l, c + ld h, b + call _op_endpoint_next +;source-doc/base-drv/enumerate.c:110: } + ld sp, ix + pop ix + ret +;source-doc/base-drv/enumerate.c:113: 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 + push af +;source-doc/base-drv/enumerate.c:114: dev_cfg->interface_number = interface->bInterfaceNumber; + ld c,(ix+8) + ld b,(ix+9) + ld e, c + ld d, b + inc de + inc de + ld l,(ix+6) + ld h,(ix+7) + inc hl + inc hl + ld a, (hl) + ld (de), a +;source-doc/base-drv/enumerate.c:115: dev_cfg->max_packet_size = working->desc.bMaxPacketSize0; + ld hl,0x0001 + add hl, bc + ex (sp), hl + ld e,(ix+4) + ld d,(ix+5) + ld hl,0x000a + add hl,de + ld a, (hl) + pop hl + push hl + ld (hl), a +;source-doc/base-drv/enumerate.c:116: dev_cfg->address = working->current_device_address; + ld (ix-2),c + ld (ix-1),b + ld l, e + ld h, d + ld a,+((0x0018) & 0xFF) + add a,l + ld l,a + ld a,+((0x0018) / 256) + adc a,h + ld h,a + ld a, (hl) + ld l,(ix-2) + ld h,(ix-1) + add a, a + add a, a + add a, a + add a, a + push bc + ld c, a + ld a, (hl) + and 0x0f + or c + ld (hl), a + pop bc +;source-doc/base-drv/enumerate.c:117: dev_cfg->type = working->usb_device; + ld l, e + ld h, d + 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:119: return usbtrn_set_configuration(dev_cfg->address, dev_cfg->max_packet_size, working->config.desc.bConfigurationvalue); + ld hl,36 + add hl, de + ld b, (hl) + pop hl + ld d,(hl) + push hl + ld l,(ix-2) + ld h,(ix-1) + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + ld c, d + push bc + push af + inc sp + call _usbtrn_set_configuration +;source-doc/base-drv/enumerate.c:120: } + ld sp,ix + pop ix + ret +;source-doc/base-drv/enumerate.c:122: 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 + push af + push af + dec sp + ex de, hl +;source-doc/base-drv/enumerate.c:123: const interface_descriptor *const interface = (interface_descriptor *)working->ptr; + ld hl,0x001c + add hl,de + ld a, (hl) + dec hl + ld l, (hl) + ld (ix-2),l + ld (ix-1),a +;source-doc/base-drv/enumerate.c:127: working->hub_config = &hub_config; + ld hl,0x0019 + add hl, de + ld c, l + ld b, h + ld hl,0 + add hl, sp + ld a, l + ld (bc), a + inc bc + ld a, h + ld (bc), a +;source-doc/base-drv/enumerate.c:129: 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:130: CHECK(configure_device(working, interface, (device_config *const)&hub_config)); + push de + ld hl,2 + add hl, sp + push hl + ld l,(ix-2) + ld h,(ix-1) + push hl + push de + call _configure_device + pop af + pop af + pop af + pop de + ld a, l + inc l + dec l + jr NZ,l_op_capture_hub_driver_interfa +;source-doc/base-drv/enumerate.c:131: RETURN_CHECK(configure_usb_hub(working)); + ex de, hl + call _configure_usb_hub + ld a, l +;source-doc/base-drv/enumerate.c:132: done: +l_op_capture_hub_driver_interfa: +;source-doc/base-drv/enumerate.c:133: return result; +;source-doc/base-drv/enumerate.c:134: } + ld sp, ix + pop ix + ret +;source-doc/base-drv/enumerate.c:136: 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 c, l + ld b, h + ld hl, -14 + add hl, sp + ld sp, hl +;source-doc/base-drv/enumerate.c:139: const interface_descriptor *const interface = (interface_descriptor *)working->ptr; + ld l,c + ld h, b + ld de,0x001c + add hl, de + ld a, (hl) + dec hl + ld l, (hl) + ld (ix-2),l + ld (ix-1),a +;source-doc/base-drv/enumerate.c:141: working->endpoint_count = interface->bNumEndpoints; + ld hl,0x0017 + add hl, bc + ex de, hl + ld l,(ix-2) + ld h,(ix-1) + inc hl + inc hl + inc hl + inc hl + ld a, (hl) + ld (de), a +;source-doc/base-drv/enumerate.c:142: if (working->endpoint_count > 0) + or a + jr Z,l_op_cap_drv_intf_00104 +;source-doc/base-drv/enumerate.c:143: CHECK(adv_to_next_desc(working, USB_DESCR_ENDPOINT)); + push bc + ld a,0x05 + push af + inc sp + ld l, c + ld h, b + call _adv_to_next_desc + pop bc + or a + jp NZ, l_op_cap_drv_intf_00117 +l_op_cap_drv_intf_00104: +;source-doc/base-drv/enumerate.c:144: working->p_current_device = NULL; + ld hl,0x001d + add hl, bc + ld e,l + ld d,h + xor a + ld (hl), a + inc hl + ld (hl), a +;source-doc/base-drv/enumerate.c:146: switch (working->usb_device) { + ld l, c + ld h, b + inc hl + inc hl + ld a, (hl) + cp 0x06 + jr Z,l_op_cap_drv_intf_00108 + sub 0x0f + jr NZ,l_op_cap_drv_intf_00111 +;source-doc/base-drv/enumerate.c:148: CHECK(op_capture_hub_driver_interface(working)) + ld l,c + ld h,b + push hl + call _op_capture_hub_driver_interfac + pop bc + or a + jr Z,l_op_cap_drv_intf_00116 + jr l_op_cap_drv_intf_00117 +;source-doc/base-drv/enumerate.c:152: case USB_IS_UNKNOWN: { +l_op_cap_drv_intf_00108: +;source-doc/base-drv/enumerate.c:154: memset(&unkown_dev_cfg, 0, sizeof(device_config)); + push bc + ld hl,2 + add hl, sp + ld b,0x06 +l_op_cap_drv_intf_00165: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_op_cap_drv_intf_00165 + pop bc +;source-doc/base-drv/enumerate.c:155: working->p_current_device = &unkown_dev_cfg; + ld hl,0 + add hl, sp + ld a, l + ld (de), a + inc de + ld a, h + ld (de), a +;source-doc/base-drv/enumerate.c:156: CHECK(configure_device(working, interface, &unkown_dev_cfg)); + push bc + push hl + ld l,(ix-2) + ld h,(ix-1) + push hl + push bc + call _configure_device + pop af + pop af + pop af + ld a, l + pop bc + or a + jr Z,l_op_cap_drv_intf_00116 + jr l_op_cap_drv_intf_00117 +;source-doc/base-drv/enumerate.c:160: default: { +l_op_cap_drv_intf_00111: +;source-doc/base-drv/enumerate.c:161: device_config *dev_cfg = find_first_free(); + push bc + push de + call _find_first_free + pop de + pop bc +;source-doc/base-drv/enumerate.c:162: if (dev_cfg == NULL) + ld a, h + or l + jr NZ,l_op_cap_drv_intf_00113 +;source-doc/base-drv/enumerate.c:163: return USB_ERR_OUT_OF_MEMORY; + ld l,0x83 + jr l_op_cap_drv_intf_00118 +l_op_cap_drv_intf_00113: +;source-doc/base-drv/enumerate.c:164: working->p_current_device = dev_cfg; + ld a, l + ld (de), a + inc de + ld a, h + ld (de), a +;source-doc/base-drv/enumerate.c:165: CHECK(configure_device(working, interface, dev_cfg)); + push bc + push hl + ld l,(ix-2) + ld h,(ix-1) + push hl + push bc + call _configure_device + pop af + pop af + pop af + ld a, l + pop bc + or a + jr NZ,l_op_cap_drv_intf_00117 +;source-doc/base-drv/enumerate.c:168: } +l_op_cap_drv_intf_00116: +;source-doc/base-drv/enumerate.c:170: return op_parse_endpoint(working); + ld l, c + ld h, b + call _op_parse_endpoint + ld l, a + jr l_op_cap_drv_intf_00118 +;source-doc/base-drv/enumerate.c:172: done: +l_op_cap_drv_intf_00117: +;source-doc/base-drv/enumerate.c:173: return result; + ld l, a +l_op_cap_drv_intf_00118: +;source-doc/base-drv/enumerate.c:174: } + ld sp, ix + pop ix + ret +;source-doc/base-drv/enumerate.c:176: usb_error op_id_class_drv(_working *const working) __sdcccall(1) { +; --------------------------------- +; Function op_id_class_drv +; --------------------------------- +_op_id_class_drv: + ex de, hl +;source-doc/base-drv/enumerate.c:177: const interface_descriptor *const ptr = (const interface_descriptor *)working->ptr; + ld hl,27 + add hl,de + ld c, (hl) + inc hl + ld b, (hl) +;source-doc/base-drv/enumerate.c:179: if (ptr->bDescriptorType != USB_DESCR_INTERFACE) + inc bc + ld a, (bc) + sub 0x04 + jr Z,l_op_id_class_drv_00102 +;source-doc/base-drv/enumerate.c:180: return USB_ERR_FAIL; + ld a,0x0e + jr l_op_id_class_drv_00103 +l_op_id_class_drv_00102: +;source-doc/base-drv/enumerate.c:182: working->usb_device = identify_class_driver(working); + ld c, e + ld b, d + inc bc + inc bc + push bc + push de + push de + call _identify_class_driver + pop af + ld a, l + pop de + pop bc + ld (bc), a +;source-doc/base-drv/enumerate.c:184: return op_cap_drv_intf(working); + ex de, hl + call _op_cap_drv_intf + ld a, l +l_op_id_class_drv_00103: +;source-doc/base-drv/enumerate.c:185: } + ret +;source-doc/base-drv/enumerate.c:187: usb_error op_get_cfg_desc(_working *const working) __sdcccall(1) { +; --------------------------------- +; Function op_get_cfg_desc +; --------------------------------- +_op_get_cfg_desc: + push ix + ld ix,0 + add ix,sp + dec sp +;source-doc/base-drv/enumerate.c:190: const uint8_t max_packet_size = working->desc.bMaxPacketSize0; + ld d,h + ld c,l + ld b,h + ld hl,10 + add hl,bc + ld a, (hl) + ld (ix-1),a +;source-doc/base-drv/enumerate.c:192: memset(working->config.buffer, 0, MAX_CONFIG_SIZE); + ld hl,0x001f + add hl, bc + push bc + ld b,0x46 +l_op_get_cfg_desc_00122: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_op_get_cfg_desc_00122 + pop bc +;source-doc/base-drv/enumerate.c:193: working->ptr = working->config.buffer; + ld hl,0x001b + add hl, bc + ld a, c + add a,0x1f + ld e, a + ld a, b + adc a,0x00 + ld (hl), e + inc hl + ld (hl), a +;source-doc/base-drv/enumerate.c:196: working->config.buffer)); + ld hl,0x001f + add hl, bc + ex de, hl + ld hl,0x0018 + add hl,bc + ld a, (hl) + ld hl,0x0015 + add hl,bc + ld h, (hl) + push bc + push de + ld d,0x8c + push de + inc sp + ld d,(ix-1) + push de + inc sp + ld l,h + ld h,a + push hl + call _usbtrn_gfull_cfg_desc + pop af + pop af + pop af + ld a, l + pop bc + or a + jr NZ,l_op_get_cfg_desc_00105 +;source-doc/base-drv/enumerate.c:198: CHECK(adv_to_next_desc(working, USB_DESCR_INTERFACE)); + push bc + ld a,0x04 + push af + inc sp + ld l, c + ld h, b + call _adv_to_next_desc + pop bc + or a + jr NZ,l_op_get_cfg_desc_00105 +;source-doc/base-drv/enumerate.c:199: working->interface_count = working->config.desc.bNumInterfaces; + ld hl,0x0016 + add hl, bc + ex de, hl + ld hl,0x0023 + add hl,bc + ld a, (hl) + ld (de), a +;source-doc/base-drv/enumerate.c:201: return op_id_class_drv(working); + ld l, c + ld h, b + call _op_id_class_drv +;source-doc/base-drv/enumerate.c:203: done: +;source-doc/base-drv/enumerate.c:204: return result; +l_op_get_cfg_desc_00105: +;source-doc/base-drv/enumerate.c:205: } + inc sp + pop ix + ret +;source-doc/base-drv/enumerate.c:207: 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:212: memset(&working, 0, sizeof(_working)); + ld hl,0 + add hl, sp + ld e,l + ld d,h + ld b,0x56 + jr l_read_all_configs_00150 +l_read_all_configs_00149: + ld (hl),0x00 + inc hl +l_read_all_configs_00150: + ld (hl),0x00 + inc hl + djnz l_read_all_configs_00149 +;source-doc/base-drv/enumerate.c:213: working.state = state; + ld l, e + ld h, d + ld a,(ix+4) + ld (hl), a + inc hl + ld a,(ix+5) + ld (hl), a +;source-doc/base-drv/enumerate.c:215: CHECK(usbtrn_get_descriptor(&working.desc)); + push de + ld hl,5 + add hl, sp + push hl + call _usbtrn_get_descriptor + pop af + ld a, l + pop de + or a + jr NZ,l_read_all_configs_00108 +;source-doc/base-drv/enumerate.c:217: state->next_device_address++; + ld b,(ix+5) + ld a,(ix+4) + ld l, a + ld h, b + ld c, (hl) + inc c + ld l, a + ld h, b + ld (hl), c +;source-doc/base-drv/enumerate.c:218: working.current_device_address = state->next_device_address; + ld hl,0x0018 + add hl, de + ld (hl), c +;source-doc/base-drv/enumerate.c:219: CHECK(usbtrn_set_address(working.current_device_address)); + push de + ld l, c + call _usbtrn_set_address + ld a, l + pop de +;source-doc/base-drv/enumerate.c:221: for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) { + or a + jr NZ,l_read_all_configs_00108 + ld c,a +l_read_all_configs_00110: + ld hl,20 + add hl, sp + ld b, (hl) + ld a, c + sub b + jr NC,l_read_all_configs_00107 +;source-doc/base-drv/enumerate.c:222: working.config_index = config_index; + ld hl,0x0015 + add hl, de + ld (hl), c +;source-doc/base-drv/enumerate.c:224: CHECK(op_get_cfg_desc(&working)); + ld l, e + ld h, d + push bc + push de + call _op_get_cfg_desc + pop de + pop bc + or a + jr NZ,l_read_all_configs_00108 +;source-doc/base-drv/enumerate.c:221: for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) { + inc c + jr l_read_all_configs_00110 +l_read_all_configs_00107: +;source-doc/base-drv/enumerate.c:227: return USB_ERR_OK; + ld l,0x00 + jr l_read_all_configs_00112 +;source-doc/base-drv/enumerate.c:228: done: +l_read_all_configs_00108: +;source-doc/base-drv/enumerate.c:229: return result; + ld l, a +l_read_all_configs_00112: +;source-doc/base-drv/enumerate.c:230: } + ld sp, ix + pop ix + ret +;source-doc/base-drv/enumerate.c:232: usb_error enumerate_all_devices(void) { +; --------------------------------- +; Function enumerate_all_devices +; --------------------------------- +_enumerate_all_devices: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/base-drv/enumerate.c:233: _usb_state *const work_area = get_usb_work_area(); +;source-doc/base-drv/enumerate.c:235: memset(&state, 0, sizeof(enumeration_state)); + ld hl,0 + add hl, sp + ld e,l + ld d,h + xor a + ld (hl), a + inc hl + ld (hl), a +;source-doc/base-drv/enumerate.c:237: usb_error result = read_all_configs(&state); + push de + push de + call _read_all_configs + pop af + pop de +;source-doc/base-drv/enumerate.c:239: work_area->count_of_detected_usb_devices = state.next_device_address; + ld bc,_x + 1 + ld a, (de) + ld (bc), a +;source-doc/base-drv/enumerate.c:242: return result; +;source-doc/base-drv/enumerate.c:243: } + ld sp, ix + 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..7b970bcf --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/enumerate_hub.c.s @@ -0,0 +1,457 @@ +; +; 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.5.0 #15248 (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/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 + ld e,l + ld d,h + push hl + ld bc,0x0008 + ld hl,_cmd_set_feature + ldir + pop bc +;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 e,(ix+5) + ld a,(ix+4) + ld l, a + ld h, e + inc hl + ld d, (hl) + ld l, a + ld h, e + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + ld e,a + push de + ld hl,0x0000 + push hl + push bc + 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 + ld e,l + ld d,h + push hl + ld bc,0x0008 + ld hl,_cmd_clear_feature + ldir + pop bc +;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 e,(ix+5) + ld a,(ix+4) + ld l, a + ld h, e + inc hl + ld d, (hl) + ld l, a + ld h, e + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + ld e,a + push de + ld hl,0x0000 + push hl + push bc + 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 + ld e,l + ld d,h + push hl + ld bc,0x0008 + ld hl,_cmd_get_status_port + ldir + pop bc +;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 e,(ix+5) + ld a,(ix+4) + ld l, a + ld h, e + inc hl + ld d, (hl) + ld l, a + ld h, e + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + ld l,(ix+7) + ld h,(ix+8) + ld e,a + push de + push hl + push bc + 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 c, l + ld b, h + ld hl, -14 + add hl, sp + ld sp, hl +;source-doc/base-drv/enumerate_hub.c:45: const device_config_hub *const hub_config = working->hub_config; + ld (ix-2),c + ld (ix-1),b + ld hl,25 + add hl, bc + ld c, (hl) + inc hl + ld b, (hl) +;source-doc/base-drv/enumerate_hub.c:47: CHECK(hub_get_descriptor(hub_config, &hub_description)); + push bc + ld hl,2 + add hl, sp + ld e,c + ld d,b + ex de,hl + call _hub_get_descriptor + pop bc + or a + jp NZ, l_configure_usb_hub_00129 +;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 + push bc + call _hub_clear_feature + pop af + pop af + ld a, l + pop de + pop bc + 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 + push bc + call _hub_set_feature + pop af + pop af + ld a, l + pop de + pop bc + 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 + push bc + call _hub_clear_feature + pop af + pop af + pop de + pop bc +;source-doc/base-drv/enumerate_hub.c:57: CHECK(hub_set_feature(hub_config, FEAT_PORT_RESET, i)); + push bc + push de + ld e,0x04 + push de + push bc + call _hub_set_feature + pop af + pop af + ld a, l + pop de + pop bc + 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 + push bc + call _hub_get_status_port + pop af + pop af + inc sp + ld a, l + pop de + pop bc + or a + jp NZ, l_configure_usb_hub_00129 +;source-doc/base-drv/enumerate_hub.c:61: if (port_status.wPortStatus & PORT_STAT_CONNECTION) { + ld e,(ix-6) + bit 0, e + jr 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 + push bc + call _hub_clear_feature + pop af + pop af + ld a, l + pop de + pop bc + or a + jr 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 + push bc + call _hub_clear_feature + pop af + pop af + ld a, l + pop de + pop bc + 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 + push bc + call _hub_clear_feature + pop af + pop af + ld a, l + pop de + pop bc + 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 + pop bc +;source-doc/base-drv/enumerate_hub.c:69: 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 + push bc + call _hub_get_status_port + pop af + pop af + inc sp + ld a, l + pop de + pop bc + 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 + pop bc +;source-doc/base-drv/enumerate_hub.c:72: CHECK(read_all_configs(working->state)); + ld l,(ix-2) + ld h,(ix-1) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + push bc + push de + push hl + call _read_all_configs + pop af + ld a, l + pop de + pop bc + 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 + push bc + call _hub_clear_feature + pop af + pop af + ld a, l + pop de + pop bc + 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 + jp NZ, l_configure_usb_hub_00126 +;source-doc/base-drv/enumerate_hub.c:79: return USB_ERR_OK; + ld l,0x00 + jr l_configure_usb_hub_00130 +;source-doc/base-drv/enumerate_hub.c:80: done: +l_configure_usb_hub_00129: +;source-doc/base-drv/enumerate_hub.c:81: return result; + ld l, a +l_configure_usb_hub_00130: +;source-doc/base-drv/enumerate_hub.c:82: } + 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..bb73bfab --- /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.5.0 #15248 (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/enumerate_storage.c:5: void parse_endpoints(device_config_storage *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 l,(ix+6) + ld h,(ix+7) + ld c,l + ld b,h + inc hl + inc hl + inc hl + ld a, (hl) + 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); + ld hl,4 + add hl,bc + ld a, (hl) + 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/hbios-driver-storage.c.s b/Source/HBIOS/ch376-native/base-drv/hbios-driver-storage.c.s new file mode 100644 index 00000000..164d6677 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/hbios-driver-storage.c.s @@ -0,0 +1,97 @@ +; +; Generated from source-doc/base-drv/hbios-driver-storage.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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 + +_hbios_usb_storage_devices: + DEFS 12 + +#ENDIF + +;-------------------------------------------------------- +; absolute external ram data +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;source-doc/base-drv/hbios-driver-storage.c:5: uint8_t find_storage_dev(void) { +; --------------------------------- +; Function find_storage_dev +; --------------------------------- +_find_storage_dev: +;source-doc/base-drv/hbios-driver-storage.c:6: for (uint8_t i = 0; i < MAX_NUMBER_OF_DEVICES; i++) + ld c,0x00 + ld de,_hbios_usb_storage_devices+0 + ld b,c +l_find_storage_dev_00105: + ld a, b + sub 0x06 + jr NC,l_find_storage_dev_00103 +;source-doc/base-drv/hbios-driver-storage.c:7: if (hbios_usb_storage_devices[i].drive_index == 0) + ld l, b + ld h,0x00 + add hl, hl + add hl, de + ld a, (hl) + or a + jr NZ,l_find_storage_dev_00106 +;source-doc/base-drv/hbios-driver-storage.c:8: return i; + ld l, c + jr l_find_storage_dev_00107 +l_find_storage_dev_00106: +;source-doc/base-drv/hbios-driver-storage.c:6: for (uint8_t i = 0; i < MAX_NUMBER_OF_DEVICES; i++) + inc b + ld c, b + jr l_find_storage_dev_00105 +l_find_storage_dev_00103: +;source-doc/base-drv/hbios-driver-storage.c:10: return -1; + ld l,0xff +l_find_storage_dev_00107: +;source-doc/base-drv/hbios-driver-storage.c:11: } + ret +_hbios_usb_storage_devices: + 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/base-drv/protocol.c.s b/Source/HBIOS/ch376-native/base-drv/protocol.c.s new file mode 100644 index 00000000..0b07a180 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/protocol.c.s @@ -0,0 +1,482 @@ +; +; 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.5.0 #15248 (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/protocol.c:25: * +; --------------------------------- +; 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:28: */ + 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:29: usb_error usbtrn_get_descriptor(device_descriptor *const buffer) { + ld (ix-2),0x08 + xor a + ld (ix-1),a +;source-doc/base-drv/protocol.c:31: setup_packet cmd; + ld c,(ix+4) + ld b,(ix+5) + push bc + push bc + ld e,c + ld d,b + ld a,0x08 + push af + inc sp + xor a + push af + inc sp + push de + ld hl,8 + add hl, sp + push hl + call _usb_control_transfer + pop af + pop af + pop af + ld a, l + pop de + pop bc + ld l, a +;source-doc/base-drv/protocol.c:33: cmd.wLength = 8; + or a + jr NZ,l_usbtrn_get_descriptor_00103 +;source-doc/base-drv/protocol.c:35: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8); + push de + push bc + ld hl,4 + add hl, sp + ex de, hl + ld bc,0x0008 + ld hl,_cmd_get_device_descriptor + ldir + pop bc + pop de +;source-doc/base-drv/protocol.c:36: + ld (ix-2),0x12 + xor a + ld (ix-1),a +;source-doc/base-drv/protocol.c:37: CHECK(result); + ld hl,7 + add hl, bc + ld a, (hl) + push af + inc sp + xor a + push af + inc sp + push de + ld hl,4 + add hl, sp + push hl + call _usb_control_transfer + pop af + pop af + pop af +;source-doc/base-drv/protocol.c:41: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0); +l_usbtrn_get_descriptor_00103: +;source-doc/base-drv/protocol.c:42: +;source-doc/base-drv/protocol.c:43: RETURN_CHECK(result); + 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:47: } +; --------------------------------- +; Function usbtrn_get_descriptor2 +; --------------------------------- +_usbtrn_get_descriptor2: + push ix + ld ix,0 + add ix,sp + ld hl, -8 + add hl, sp + ld sp, hl +;source-doc/base-drv/protocol.c:51: * + 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:52: * @param buffer the buffer to store the device descriptor in + ld (ix-2),0x08 + xor a + ld (ix-1),a +;source-doc/base-drv/protocol.c:54: */ + ld c,(ix+4) + ld b,(ix+5) + push bc + push bc + ld e,c + ld d,b + ld h,0x08 + ld l,(ix+6) + push hl + push de + ld hl,8 + add hl, sp + push hl + call _usb_control_transfer + pop af + pop af + pop af + ld a, l + pop de + pop bc + ld l, a +;source-doc/base-drv/protocol.c:56: usb_error result; + or a + jr NZ,l_usbtrn_get_descriptor2_00103 +;source-doc/base-drv/protocol.c:58: setup_packet cmd; + push de + push bc + ld hl,4 + add hl, sp + ex de, hl + ld bc,0x0008 + ld hl,_cmd_get_device_descriptor + ldir + pop bc + pop de +;source-doc/base-drv/protocol.c:59: cmd = cmd_get_device_descriptor; + ld (ix-2),0x12 + xor a + ld (ix-1),a +;source-doc/base-drv/protocol.c:60: cmd.wLength = 8; + ld hl,7 + add hl, bc + ld h,(hl) + ld l,(ix+6) + push hl + push de + ld hl,4 + add hl, sp + push hl + call _usb_control_transfer + pop af + pop af + pop af +;source-doc/base-drv/protocol.c:61: +l_usbtrn_get_descriptor2_00103: +;source-doc/base-drv/protocol.c:62: result = usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, 8); +;source-doc/base-drv/protocol.c:63: + ld sp, ix + pop ix + ret +;source-doc/base-drv/protocol.c:69: done: +; --------------------------------- +; Function usbtrn_set_address +; --------------------------------- +_usbtrn_set_address: + push ix + ld ix,0 + add ix,sp + push af + push af + push af + push af + ld c, l +;source-doc/base-drv/protocol.c:71: } + push bc + ld hl,2 + add hl, sp + ex de, hl + ld bc,0x0008 + ld hl,_cmd_set_device_address + ldir + pop bc +;source-doc/base-drv/protocol.c:72: + ld (ix-6),c +;source-doc/base-drv/protocol.c:74: + 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:75: /** + 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:81: usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall { +; --------------------------------- +; 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:83: cmd = cmd_set_device_address; + 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:84: cmd.bValue[0] = device_address; + ld a,(ix+6) + ld (ix-6),a +;source-doc/base-drv/protocol.c:86: return usb_control_transfer(&cmd, 0, 0, 0); + 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:87: } + 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:93: * +; --------------------------------- +; 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:99: cmd = cmd_set_configuration; + 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:100: cmd.bValue[0] = configuration; + ld a,(ix+6) + ld (ix-6),a +;source-doc/base-drv/protocol.c:101: + ld hl,0x0006 + add hl, bc + ld e,(ix+7) + xor a + ld (hl), e + inc hl + ld (hl), a +;source-doc/base-drv/protocol.c:103: } + 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:104: + 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:106: +; --------------------------------- +; Function usbtrn_gfull_cfg_desc +; --------------------------------- +_usbtrn_gfull_cfg_desc: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/protocol.c:114: * @param max_packet_size the max packet size for control transfers (endpoint 0) + 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:116: */ + ld l,(ix+8) + ld h,(ix+9) + inc hl + inc hl + ld d, (hl) +;source-doc/base-drv/protocol.c:117: usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer, + ld a,(ix+7) + sub d + jr NC,l_usbtrn_gfull_cfg_desc_00104 +;source-doc/base-drv/protocol.c:118: const uint8_t config_index, + ld d,(ix+7) +l_usbtrn_gfull_cfg_desc_00104: +;source-doc/base-drv/protocol.c:120: const uint8_t device_address, + 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:122: setup_packet cmd; + or a + jr NZ,l_usbtrn_gfull_cfg_desc_00107 + ld l,a +;source-doc/base-drv/protocol.c:123: cmd = cmd_get_config_descriptor; +;source-doc/base-drv/protocol.c:124: cmd.bValue[0] = config_index; +l_usbtrn_gfull_cfg_desc_00107: +;source-doc/base-drv/protocol.c:125: cmd.wLength = (uint16_t)buffer_size; + pop ix + ret +;source-doc/base-drv/protocol.c:129: +; --------------------------------- +; 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:131: const uint8_t device_address, + 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:132: const uint8_t max_packet_size, + ld a,(ix+4) + ld (ix-4),a +;source-doc/base-drv/protocol.c:134: uint8_t *const buffer) { + 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:135: usb_error result; + 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..f048769d --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/transfers.c.s @@ -0,0 +1,311 @@ +; +; 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.5.0 #15248 (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/transfers.c:23: * See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer +; --------------------------------- +; 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:28: * @param max_packet_size Maximum packet size for endpoint + 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:30: */ + ld c,(ix+4) + ld b,(ix+5) + ld a, (bc) + and 0x80 +;source-doc/base-drv/transfers.c:32: void *const buffer, + 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:33: const uint8_t device_address, + ld l,0x0f + jp l_usb_control_transfer_00114 +l_usb_control_transfer_00102: +;source-doc/base-drv/transfers.c:35: usb_error result; + push bc + call _critical_begin +;source-doc/base-drv/transfers.c:37: + ld l,(ix+8) + call _ch_set_usb_address + pop bc +;source-doc/base-drv/transfers.c:39: + 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 +;source-doc/base-drv/transfers.c:40: if (transferIn && buffer == 0) + call _ch_issue_token_setup +;source-doc/base-drv/transfers.c:41: return USB_ERR_OTHER; + call _ch_short_wait_int_and_get_stat + pop bc +;source-doc/base-drv/transfers.c:42: + ld a, l + or a + jr NZ,l_usb_control_transfer_00113 +;source-doc/base-drv/transfers.c:44: + ld hl,6 + add hl, bc + ld c, (hl) + inc hl +;source-doc/base-drv/transfers.c:47: ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet)); + ld a,(hl) + ld b,a + or c + jr Z,l_usb_control_transfer_00116 + ld hl,0 + add hl, sp + ld e,(ix+6) + ld d,(ix+7) + ld a,(ix-1) + or a + jr Z,l_usb_control_transfer_00118 + push hl + push bc + push de + call _ch_data_in_transfer + pop af + pop af + pop af + jr l_usb_control_transfer_00119 +l_usb_control_transfer_00118: + push hl + push bc + push de + call _ch_data_out_transfer + pop af + pop af + pop af +l_usb_control_transfer_00119: + jr l_usb_control_transfer_00117 +l_usb_control_transfer_00116: +;source-doc/base-drv/transfers.c:48: ch_issue_token_setup(); + ld l,0x00 +l_usb_control_transfer_00117: +;source-doc/base-drv/transfers.c:50: CHECK(result); + ld a, l + or a + jr NZ,l_usb_control_transfer_00113 +;source-doc/base-drv/transfers.c:52: const uint16_t length = cmd_packet->wLength; + ld a,(ix-1) + or a + jr Z,l_usb_control_transfer_00112 +;source-doc/base-drv/transfers.c:53: + ld l,0x2c + call _ch_command +;source-doc/base-drv/transfers.c:54: result = length != 0 + ld a,0x00 + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/transfers.c:55: ? (transferIn ? ch_data_in_transfer(buffer, length, &endpoint) : ch_data_out_transfer(buffer, length, &endpoint)) + call _ch_issue_token_out_ep0 +;source-doc/base-drv/transfers.c:56: : USB_ERR_OK; + call _ch_long_wait_int_and_get_statu +;source-doc/base-drv/transfers.c:58: CHECK(result) + ld a,l + or a + jr Z,l_usb_control_transfer_00108 + sub 0x02 + jr NZ,l_usb_control_transfer_00113 +l_usb_control_transfer_00108: +;source-doc/base-drv/transfers.c:59: + ld l,0x00 +;source-doc/base-drv/transfers.c:60: if (transferIn) { + jr l_usb_control_transfer_00113 +;source-doc/base-drv/transfers.c:63: ch_issue_token_out_ep0(); +l_usb_control_transfer_00112: +;source-doc/base-drv/transfers.c:66: if (result == USB_ERR_OK || result == USB_ERR_STALL) { + call _ch_issue_token_in_ep0 +;source-doc/base-drv/transfers.c:67: result = USB_ERR_OK; + call _ch_long_wait_int_and_get_statu +;source-doc/base-drv/transfers.c:71: RETURN_CHECK(result); +l_usb_control_transfer_00113: +;source-doc/base-drv/transfers.c:72: } + push hl + call _critical_end + pop hl +;source-doc/base-drv/transfers.c:73: +l_usb_control_transfer_00114: +;source-doc/base-drv/transfers.c:74: ch_issue_token_in_ep0(); + ld sp, ix + pop ix + ret +;source-doc/base-drv/transfers.c:79: done: +; --------------------------------- +; Function usb_data_in_transfer +; --------------------------------- +_usb_data_in_transfer: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/transfers.c:81: return result; + call _critical_begin +;source-doc/base-drv/transfers.c:83: + ld l,(ix+8) + call _ch_set_usb_address +;source-doc/base-drv/transfers.c:85: * @brief Perform a USB data in on the specified endpoint + ld l,(ix+9) + ld h,(ix+10) + push hl + ld l,(ix+6) + ld h,(ix+7) + push hl + ld l,(ix+4) + ld h,(ix+5) + push hl + call _ch_data_in_transfer + pop af + pop af +;source-doc/base-drv/transfers.c:87: * @param buffer the buffer to receive the data + ex (sp),hl + call _critical_end + pop hl +;source-doc/base-drv/transfers.c:89: * @param device_address the usb address of the device +;source-doc/base-drv/transfers.c:90: * @param endpoint the usb endpoint to receive from (toggle of endpoint is updated) + pop ix + ret +;source-doc/base-drv/transfers.c:95: usb_error result; +; --------------------------------- +; Function usb_data_in_transfer_n +; --------------------------------- +_usb_data_in_transfer_n: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/transfers.c:98: ch_set_usb_address(device_address); + call _critical_begin +;source-doc/base-drv/transfers.c:100: result = ch_data_in_transfer(buffer, buffer_size, endpoint); + ld l,(ix+8) + call _ch_set_usb_address +;source-doc/base-drv/transfers.c:102: critical_end(); + ld l,(ix+9) + ld h,(ix+10) + push hl + ld l,(ix+6) + ld h,(ix+7) + push hl + ld l,(ix+4) + ld h,(ix+5) + push hl + call _ch_data_in_transfer_n + pop af + pop af +;source-doc/base-drv/transfers.c:104: return result; + ex (sp),hl + call _critical_end + pop hl +;source-doc/base-drv/transfers.c:106: +;source-doc/base-drv/transfers.c:107: /** + pop ix + ret +;source-doc/base-drv/transfers.c:112: * @param device_address the usb address of the device +; --------------------------------- +; Function usb_data_out_transfer +; --------------------------------- +_usb_data_out_transfer: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/transfers.c:114: * @return usb_error USB_ERR_OK if all good, otherwise specific error code + call _critical_begin +;source-doc/base-drv/transfers.c:116: usb_error + ld l,(ix+8) + call _ch_set_usb_address +;source-doc/base-drv/transfers.c:118: usb_error result; + ld l,(ix+9) + ld h,(ix+10) + push hl + ld l,(ix+6) + ld h,(ix+7) + push hl + ld l,(ix+4) + ld h,(ix+5) + push hl + call _ch_data_out_transfer + pop af + pop af +;source-doc/base-drv/transfers.c:120: critical_begin(); + ex (sp),hl + call _critical_end + pop hl +;source-doc/base-drv/transfers.c:122: ch_set_usb_address(device_address); +;source-doc/base-drv/transfers.c:123: + pop ix + 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..06bec59b --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/usb-base-drv.c.s @@ -0,0 +1,224 @@ +; +; 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.5.0 #15248 (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/usb-base-drv.c:7: static usb_error usb_host_bus_reset(void) { +; --------------------------------- +; Function usb_host_bus_reset +; --------------------------------- +_usb_host_bus_reset: +;source-doc/base-drv/usb-base-drv.c:8: ch_cmd_set_usb_mode(CH_MODE_HOST); + ld l,0x06 + call _ch_cmd_set_usb_mode +;source-doc/base-drv/usb-base-drv.c:9: delay_20ms(); + call _delay_20ms +;source-doc/base-drv/usb-base-drv.c:11: ch_cmd_set_usb_mode(CH_MODE_HOST_RESET); + ld l,0x07 + call _ch_cmd_set_usb_mode +;source-doc/base-drv/usb-base-drv.c:12: delay_20ms(); + call _delay_20ms +;source-doc/base-drv/usb-base-drv.c:14: ch_cmd_set_usb_mode(CH_MODE_HOST); + ld l,0x06 + call _ch_cmd_set_usb_mode +;source-doc/base-drv/usb-base-drv.c:15: delay_20ms(); + call _delay_20ms +;source-doc/base-drv/ch376.h:108: #define TRACE_USB_ERROR(result) + ld l,0x0b + call _ch_command +;source-doc/base-drv/ch376.h:109: + ld a,0x25 + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/ch376.h:110: #endif + ld a,0xdf + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/base-drv/usb-base-drv.c:19: return USB_ERR_OK; + ld l,0x00 +;source-doc/base-drv/usb-base-drv.c:20: } + ret +;source-doc/base-drv/usb-base-drv.c:24: uint16_t usb_init(uint8_t state) __z88dk_fastcall { +; --------------------------------- +; Function usb_init +; --------------------------------- +_usb_init: +;source-doc/base-drv/usb-base-drv.c:27: USB_MODULE_LEDS = 0x03; + ld a,0x03 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/usb-base-drv.c:29: if (state == 0) { + ld a, l + or a + jr NZ,l_usb_init_00104 +;source-doc/base-drv/usb-base-drv.c:30: ch_cmd_reset_all(); + call _ch_cmd_reset_all +;source-doc/base-drv/usb-base-drv.c:31: delay_medium(); + call _delay_medium +;source-doc/base-drv/usb-base-drv.c:33: if (!ch_probe()) { + call _ch_probe + ld a, l +;source-doc/base-drv/usb-base-drv.c:34: USB_MODULE_LEDS = 0x00; + or a + jr NZ,l_usb_init_00102 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/usb-base-drv.c:35: return 0xFF00; + ld hl,0xff00 + jp l_usb_init_00113 +l_usb_init_00102: +;source-doc/base-drv/usb-base-drv.c:37: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/usb-base-drv.c:38: return 1; + ld hl,0x0001 + jr l_usb_init_00113 +l_usb_init_00104: +;source-doc/base-drv/usb-base-drv.c:41: if (state == 1) { + ld a, l + dec a + jr NZ,l_usb_init_00106 +;source-doc/base-drv/usb-base-drv.c:42: r = ch_cmd_get_ic_version(); + call _ch_cmd_get_ic_version +;source-doc/base-drv/usb-base-drv.c:44: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/usb-base-drv.c:45: return (uint16_t)r << 8 | 2; + xor a + ld h, l + ld l,0x02 + jr l_usb_init_00113 +l_usb_init_00106: +;source-doc/base-drv/usb-base-drv.c:48: if (state == 2) { + ld a, l + sub 0x02 + jr NZ,l_usb_init_00159 + ld a,0x01 + jr l_usb_init_00160 +l_usb_init_00159: + xor a +l_usb_init_00160: + ld c,a + or a + jr Z,l_usb_init_00110 +;source-doc/base-drv/usb-base-drv.c:49: usb_host_bus_reset(); + call _usb_host_bus_reset +;source-doc/base-drv/usb-base-drv.c:51: r = ch_very_short_wait_int_and_get_(); + call _ch_very_short_wait_int_and_get + ld a, l +;source-doc/base-drv/usb-base-drv.c:53: if (r != USB_INT_CONNECT) { + sub 0x81 + jr Z,l_usb_init_00108 +;source-doc/base-drv/usb-base-drv.c:54: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/usb-base-drv.c:55: return 2; + ld hl,0x0002 + jr l_usb_init_00113 +l_usb_init_00108: +;source-doc/base-drv/usb-base-drv.c:58: return 3; + ld hl,0x0003 + jr l_usb_init_00113 +l_usb_init_00110: +;source-doc/base-drv/usb-base-drv.c:61: memset(get_usb_work_area(), 0, sizeof(_usb_state)); + ld b,0x32 + ld hl,_x + jr l_usb_init_00163 +l_usb_init_00162: + ld (hl),0x00 + inc hl +l_usb_init_00163: + ld (hl),0x00 + inc hl + djnz l_usb_init_00162 +;source-doc/base-drv/usb-base-drv.c:62: if (state != 2) { + bit 0, c + jr NZ,l_usb_init_00112 +;source-doc/base-drv/usb-base-drv.c:63: usb_host_bus_reset(); + call _usb_host_bus_reset +;source-doc/base-drv/usb-base-drv.c:64: delay_medium(); + call _delay_medium +l_usb_init_00112: +;source-doc/base-drv/usb-base-drv.c:66: enumerate_all_devices(); + call _enumerate_all_devices +;source-doc/base-drv/usb-base-drv.c:67: USB_MODULE_LEDS = 0x00; + ld a,0x00 + ld bc,_USB_MODULE_LEDS + out (c), a +;source-doc/base-drv/usb-base-drv.c:68: return (uint16_t)count_of_devices() << 8 | 4; + call _count_of_devices + ld h, a + xor a + ld l,0x04 +l_usb_init_00113: +;source-doc/base-drv/usb-base-drv.c:69: } + ret +;source-doc/base-drv/usb-base-drv.c:71: usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba) { +; --------------------------------- +; Function usb_scsi_seek +; --------------------------------- +_usb_scsi_seek: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/usb-base-drv.c:72: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config +;source-doc/base-drv/usb-base-drv.c:74: dev->current_lba = lba; + ld hl,0x000c + add hl, de + ex de, hl + ld hl,6 + add hl, sp + ld bc,0x0004 + ldir +;source-doc/base-drv/usb-base-drv.c:75: return USB_ERR_OK; + ld l,0x00 +;source-doc/base-drv/usb-base-drv.c:76: } + pop ix + ret 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..d70ea4c5 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/usb_state.c.s @@ -0,0 +1,258 @@ +; +; 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.5.0 #15248 (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/usb_state.c:17: uint8_t count_of_devices(void) __sdcccall(1) { +; --------------------------------- +; Function count_of_devices +; --------------------------------- +_count_of_devices: +;source-doc/base-drv/usb_state.c:18: _usb_state *const p = get_usb_work_area(); +;source-doc/base-drv/usb_state.c:22: const device_config *p_config = first_device_config(p); + ld hl,_x + call _first_device_config +;source-doc/base-drv/usb_state.c:23: while (p_config) { + ld c,0x00 +l_count_of_devices_00104: + ld a, d + or e + jr Z,l_count_of_devices_00106 +;source-doc/base-drv/usb_state.c:24: const uint8_t type = p_config->type; + ld l, e + ld h, d + ld a, (hl) + and 0x0f +;source-doc/base-drv/usb_state.c:26: if (type != USB_IS_HUB && type) + cp 0x0f + jr Z,l_count_of_devices_00102 + or a + jr Z,l_count_of_devices_00102 +;source-doc/base-drv/usb_state.c:27: count++; + inc c +l_count_of_devices_00102: +;source-doc/base-drv/usb_state.c:30: p_config = next_device_config(p, p_config); + push bc + ld hl,_x + call _next_device_config + pop bc + jr l_count_of_devices_00104 +l_count_of_devices_00106: +;source-doc/base-drv/usb_state.c:33: return count; + ld a, c +;source-doc/base-drv/usb_state.c:34: } + ret +_device_config_sizes: + DEFB +0x00 + DEFB +0x10 + DEFB +0x10 + DEFB +0x0c + DEFB +0x06 + DEFB 0x00 + DEFB 0x00 +;source-doc/base-drv/usb_state.c:37: device_config *find_first_free(void) { +; --------------------------------- +; Function find_first_free +; --------------------------------- +_find_first_free: +;source-doc/base-drv/usb_state.c:38: _usb_state *const boot_state = get_usb_work_area(); +;source-doc/base-drv/usb_state.c:41: device_config *p = first_device_config(boot_state); + ld hl,_x + call _first_device_config +;source-doc/base-drv/usb_state.c:42: 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:43: 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:44: return p; + ex de, hl + jr l_find_first_free_00106 +l_find_first_free_00102: +;source-doc/base-drv/usb_state.c:46: 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:49: return NULL; + ld hl,0x0000 +l_find_first_free_00106: +;source-doc/base-drv/usb_state.c:50: } + ret +;source-doc/base-drv/usb_state.c:52: 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:54: 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:55: 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:56: return NULL; + ld de,0x0000 + jr l_next_device_config_00105 +l_next_device_config_00102: +;source-doc/base-drv/usb_state.c:58: 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 a, (hl) +;source-doc/base-drv/usb_state.c:65: const uint8_t *_p = (uint8_t *)p; +;source-doc/base-drv/usb_state.c:66: device_config *const result = (device_config *)(_p + size); + add a, e + ld e, a + ld a,0x00 + adc a, d + ld d, a +;source-doc/base-drv/usb_state.c:68: if (result >= (device_config *)&usb_state->device_configs_end) + ld hl,0x0062 + add hl, bc + ld a, e + sub l + ld a, d + sbc a, h + ret C +;source-doc/base-drv/usb_state.c:69: return NULL; + ld de,0x0000 +;source-doc/base-drv/usb_state.c:71: return result; +l_next_device_config_00105: +;source-doc/base-drv/usb_state.c:72: } + ret +;source-doc/base-drv/usb_state.c:74: device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1) { +; --------------------------------- +; Function get_usb_device_config +; --------------------------------- +_get_usb_device_config: + ld c, a +;source-doc/base-drv/usb_state.c:75: const _usb_state *const usb_state = get_usb_work_area(); +;source-doc/base-drv/usb_state.c:79: 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_00107: + ld a, d + or e + jr Z,l_get_usb_device_config_00105 +;source-doc/base-drv/usb_state.c:80: if (p->type != USB_NOT_SUPPORTED) { + ld l, e + ld h, d + ld a, (hl) + and 0x0f + jr Z,l_get_usb_device_config_00108 +;source-doc/base-drv/usb_state.c:81: if (counter == device_index) + ld a, c + sub b +;source-doc/base-drv/usb_state.c:82: return p; + jr Z,l_get_usb_device_config_00109 +;source-doc/base-drv/usb_state.c:83: counter++; + inc b +l_get_usb_device_config_00108: +;source-doc/base-drv/usb_state.c:79: 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_00107 +l_get_usb_device_config_00105: +;source-doc/base-drv/usb_state.c:87: return NULL; // is not a usb device + ld de,0x0000 +l_get_usb_device_config_00109: +;source-doc/base-drv/usb_state.c:88: } + ret +;source-doc/base-drv/usb_state.c:90: usb_device_type usb_get_device_type(const uint16_t dev_index) { +; --------------------------------- +; Function usb_get_device_type +; --------------------------------- +_usb_get_device_type: + push ix + ld ix,0 + add ix,sp +;source-doc/base-drv/usb_state.c:91: const device_config *dev = get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config + ld l, e +;source-doc/base-drv/usb_state.c:93: if (dev == NULL) + ld a,d + ld h,a + or e + jr NZ,l_usb_get_device_type_00102 +;source-doc/base-drv/usb_state.c:94: return -1; + ld l,0xff + jr l_usb_get_device_type_00103 +l_usb_get_device_type_00102: +;source-doc/base-drv/usb_state.c:96: return dev->type; + ld a, (hl) + and 0x0f + ld l, a +l_usb_get_device_type_00103: +;source-doc/base-drv/usb_state.c:97: } + 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..ff1b7e91 --- /dev/null +++ b/Source/HBIOS/ch376-native/base-drv/work-area.c.s @@ -0,0 +1,149 @@ +; +; 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.5.0 #15248 (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 + +_x: + DEFS 99 + +#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 diff --git a/Source/HBIOS/ch376-native/cruntime.asm b/Source/HBIOS/ch376-native/cruntime.asm new file mode 100644 index 00000000..74426810 --- /dev/null +++ b/Source/HBIOS/ch376-native/cruntime.asm @@ -0,0 +1,133 @@ + +_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 + +_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 + +.if 0 +; required if --optimise-for-size is targetted +; but there appears to be a regression that stop the driver from working +; if optimised for size is selected +___sdcc_enter_ix: + ex (sp), ix + push ix + ld ix, 2 + add ix, sp + ret + +____sdcc_lib_setmem_hl: +l_setmem_hl: + ret + +____sdcc_load_debc_mhl: + ld c, (hl) + inc hl + ld b, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + ret + +____sdcc_4_push_hlix: + pop af + push af + push af + push af + + push de + + push ix + pop de + + add hl, de + + ex de, hl + + ld hl, 2+2 + add hl, sp + + ex de, hl + + ldi + ldi + ldi + ld a, (hl) + ld (de), a + + inc bc + inc bc + inc bc + + pop de + ret + +____sdcc_store_debc_mhl: + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d + ret +.endif diff --git a/Source/HBIOS/ch376-native/ez80-firmware.asm b/Source/HBIOS/ch376-native/ez80-firmware.asm new file mode 100644 index 00000000..2cce1a71 --- /dev/null +++ b/Source/HBIOS/ch376-native/ez80-firmware.asm @@ -0,0 +1,143 @@ +; delegate usb function to firmware of ez80 module + +; extern uint16_t usb_init(uint8_t state) __z88dk_fastcall; +_usb_init: + EZ80_EX_USB_INIT + RET + +; usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba) +_usb_scsi_seek: + ; iy+2 : dev_index + ; iy+4:5:6:7 : lba + LD IY, 0 + ADD IY, SP + EZ80_EXTN_IY_TO_MB_IY + + LD C, (IY+2) + LD_DE_IY_P_.L(4) ; LD.L DE, (IY+4) + LD L, (IY+7) + EZ80_EX_USB_STORAGE_SEEK + LD L, A + RET + +; usb_error usb_scsi_init(const uint16_t dev_index) +_usb_scsi_init: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + EZ80_EX_USB_SCSI_INIT + LD L, A + RET + +; usb_error usb_scsi_read(const uint16_t dev_index, uint8_t *const buffer); +_usb_scsi_read: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + LD E, (IY+4) + LD D, (IY+5) + EZ80_EXTN_DE_TO_MB_DE + EZ80_EX_USB_SCSI_READ + LD L, A + RET + +; usb_error usb_scsi_write(const uint16_t dev_index, uint8_t *const buffer) +_usb_scsi_write: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + LD E, (IY+4) + LD D, (IY+5) + EZ80_EXTN_DE_TO_MB_DE + EZ80_EX_USB_SCSI_WRITE + LD L, A + RET + +; usb_error usb_scsi_read_capacity(const uint16_t dev_index, scsi_read_capacity_result *cap_result) +_usb_scsi_read_capacity: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + LD E, (IY+4) + LD D, (IY+5) + EZ80_EXTN_DE_TO_MB_DE + EZ80_EX_USB_SCSI_READ_CAP + LD L, A + RET + +; extern uint8_t usb_ufi_read(const uint16_t dev_index, uint8_t *const buffer) +_usb_ufi_read: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + LD E, (IY+4) + LD D, (IY+5) + EZ80_EXTN_DE_TO_MB_DE + EZ80_EX_USB_UFI_READ + LD L, A + RET + +;extern usb_error usb_ufi_write(const uint16_t dev_index, uint8_t *const buffer); +_usb_ufi_write: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + LD E, (IY+4) + LD D, (IY+5) + EZ80_EXTN_DE_TO_MB_DE + EZ80_EX_USB_UFI_WRITE + LD L, A + RET + +; extern uint32_t usb_ufi_get_cap(const uint16_t dev_index) +_usb_ufi_get_cap: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + EZ80_EXTN_DE_TO_MB_DE + EZ80_EX_USB_UFI_GET_CAP ; + + LD D, E ; convert E:uHL to DE:HL + EZ80_CPY_UHL_TO_EHL + RET + +; extern void usb_kyb_init(const uint8_t dev_index) __sdcccall(1); +_usb_kyb_init: + LD C, A + EZ80_EX_USB_KYB_INIT + RET + +; extern uint8_t usb_kyb_flush() __sdcccall(1); +_usb_kyb_flush: + EZ80_EX_USB_KYB_FLUSH + RET + +; extern uint8_t usb_kyb_status() __sdcccall(1); +_usb_kyb_status: + EZ80_EX_USB_KYB_STATUS + RET + +; extern uint16_t usb_kyb_read(); +; H = 0/1 set if char, L=>code +_usb_kyb_read: + EZ80_EX_USB_KYB_READ + LD H, A + RET + + +;usb_device_type usb_get_device_type(const uint16_t dev_index) +_usb_get_device_type: + LD IY, 0 + ADD IY, SP + + LD C, (IY+2) + EZ80_EX_USB_GET_DEV_TYPE + LD L, A + RET diff --git a/Source/HBIOS/ch376-native/keyboard.s b/Source/HBIOS/ch376-native/keyboard.s new file mode 100644 index 00000000..abc73e8a --- /dev/null +++ b/Source/HBIOS/ch376-native/keyboard.s @@ -0,0 +1,11 @@ +; Generated File -- not to be modify directly +#IF (!CHNATIVEEZ80) +#include "ch376-native/keyboard/class_hid.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/keyboard/class_hid_keyboard.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/keyboard/kyb_driver.c.s" +#ENDIF +#include "ch376-native/keyboard/kyb-init.c.s" diff --git a/Source/HBIOS/ch376-native/keyboard/.gitignore b/Source/HBIOS/ch376-native/keyboard/.gitignore new file mode 100644 index 00000000..f4cb8488 --- /dev/null +++ b/Source/HBIOS/ch376-native/keyboard/.gitignore @@ -0,0 +1 @@ +*.asm diff --git a/Source/HBIOS/ch376-native/keyboard/class_hid.c.s b/Source/HBIOS/ch376-native/keyboard/class_hid.c.s new file mode 100644 index 00000000..a3dbc2b3 --- /dev/null +++ b/Source/HBIOS/ch376-native/keyboard/class_hid.c.s @@ -0,0 +1,169 @@ +; +; Generated from source-doc/keyboard/class_hid.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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/keyboard/class_hid.c:6: usb_error hid_set_protocol(const device_config_keyboard *const dev, const uint8_t protocol) __sdcccall(1) { +; --------------------------------- +; Function hid_set_protocol +; --------------------------------- +_hid_set_protocol: + push ix + ld ix,0 + add ix,sp + push af + push af + push af + push af +;source-doc/keyboard/class_hid.c:8: cmd = cmd_hid_set; + push hl + ex de,hl + ld hl,2 + add hl, sp + ex de, hl + ld bc,0x0008 + ld hl,_cmd_hid_set + ldir + pop de +;source-doc/keyboard/class_hid.c:10: cmd.bRequest = HID_SET_PROTOCOL; + ld (ix-7),0x0b +;source-doc/keyboard/class_hid.c:11: cmd.bValue[0] = protocol; + ld a,(ix+4) + ld (ix-6),a +;source-doc/keyboard/class_hid.c:13: return usb_control_transfer(&cmd, NULL, dev->address, dev->max_packet_size); + ld l, e + ld h, d + 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 + pop af + pop af + pop af + ld a, l +;source-doc/keyboard/class_hid.c:14: } + ld sp, ix + pop ix + pop hl + inc sp + jp (hl) +_cmd_hid_set: + DEFB +0x21 + DEFB +0x0b + DEFB +0x00 + DEFB +0x00 + DEFB +0x00 + DEFB +0x00 + DEFW +0x0000 +;source-doc/keyboard/class_hid.c:16: usb_error hid_set_idle(const device_config_keyboard *const dev, const uint8_t duration) __sdcccall(1) { +; --------------------------------- +; Function hid_set_idle +; --------------------------------- +_hid_set_idle: + push ix + ld ix,0 + add ix,sp + push af + push af + push af + push af +;source-doc/keyboard/class_hid.c:18: cmd = cmd_hid_set; + push hl + ex de,hl + ld hl,2 + add hl, sp + ex de, hl + ld bc,0x0008 + ld hl,_cmd_hid_set + ldir + pop de +;source-doc/keyboard/class_hid.c:20: cmd.bRequest = HID_SET_IDLE; + ld (ix-7),0x0a +;source-doc/keyboard/class_hid.c:21: cmd.bValue[0] = duration; + ld a,(ix+4) + ld (ix-6),a +;source-doc/keyboard/class_hid.c:23: return usb_control_transfer(&cmd, NULL, dev->address, dev->max_packet_size); + ld l, e + ld h, d + 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 + pop af + pop af + pop af + ld a, l +;source-doc/keyboard/class_hid.c:24: } + ld sp, ix + pop ix + pop hl + inc sp + jp (hl) diff --git a/Source/HBIOS/ch376-native/keyboard/class_hid_keyboard.c.s b/Source/HBIOS/ch376-native/keyboard/class_hid_keyboard.c.s new file mode 100644 index 00000000..4e690852 --- /dev/null +++ b/Source/HBIOS/ch376-native/keyboard/class_hid_keyboard.c.s @@ -0,0 +1,440 @@ +; +; Generated from source-doc/keyboard/class_hid_keyboard.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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 + +_scancodes_shift_table: + DEFS 128 +_scancodes_table: + DEFS 128 + +#ENDIF + +;-------------------------------------------------------- +; absolute external ram data +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;source-doc/keyboard/class_hid_keyboard.c:334: }; +; --------------------------------- +; Function char_with_caps_lock +; --------------------------------- +_char_with_caps_lock: +;source-doc/keyboard/class_hid_keyboard.c:335: + bit 0, l +;source-doc/keyboard/class_hid_keyboard.c:336: static char char_with_caps_lock(const char c, const bool caps_lock_engaged) __sdcccall(1) { + jr Z,l_char_with_caps_lock_00109 +;source-doc/keyboard/class_hid_keyboard.c:338: return c; + cp 0x41 + jr C,l_char_with_caps_lock_00104 + cp 0x5b + jr NC,l_char_with_caps_lock_00104 +;source-doc/keyboard/class_hid_keyboard.c:339: + add a,0x20 + jr l_char_with_caps_lock_00109 +l_char_with_caps_lock_00104: +;source-doc/keyboard/class_hid_keyboard.c:341: return c - 'A' + 'a'; + cp 0x61 + ret C + cp 0x7b + ret NC +;source-doc/keyboard/class_hid_keyboard.c:342: + add a,0xe0 +;source-doc/keyboard/class_hid_keyboard.c:344: return c - 'a' + 'A'; +l_char_with_caps_lock_00109: +;source-doc/keyboard/class_hid_keyboard.c:345: + ret +;source-doc/keyboard/class_hid_keyboard.c:347: } +; --------------------------------- +; Function scancode_to_char +; --------------------------------- +_scancode_to_char: + push ix + ld ix,0 + add ix,sp +;source-doc/keyboard/class_hid_keyboard.c:348: + ld c,a + ld e,l + and 0x11 + jr Z,l_scancode_to_char_00118 +;source-doc/keyboard/class_hid_keyboard.c:349: char scancode_to_char(const uint8_t modifier_keys, const uint8_t code, const bool caps_lock_engaged) __sdcccall(1) { + ld a, e + sub 0x04 + jr C,l_scancode_to_char_00102 + ld a,0x1d + sub e + jr C,l_scancode_to_char_00102 +;source-doc/keyboard/class_hid_keyboard.c:350: if ((modifier_keys & (KEY_MOD_LCTRL | KEY_MOD_RCTRL))) { + ld a, e + add a,0xfd + jr l_scancode_to_char_00121 +l_scancode_to_char_00102: +;source-doc/keyboard/class_hid_keyboard.c:352: return code - 3; + ld a,e + cp 0x1f + jr Z,l_scancode_to_char_00104 + sub 0x2c + jr NZ,l_scancode_to_char_00105 +l_scancode_to_char_00104: +;source-doc/keyboard/class_hid_keyboard.c:353: + xor a + jr l_scancode_to_char_00121 +l_scancode_to_char_00105: +;source-doc/keyboard/class_hid_keyboard.c:355: return 0; + ld a, e + sub 0x2f + jr NZ,l_scancode_to_char_00108 +;source-doc/keyboard/class_hid_keyboard.c:356: + ld a,0x1b + jr l_scancode_to_char_00121 +l_scancode_to_char_00108: +;source-doc/keyboard/class_hid_keyboard.c:358: return 27; + ld a, e + sub 0x31 + jr NZ,l_scancode_to_char_00110 +;source-doc/keyboard/class_hid_keyboard.c:359: + ld a,0x1c + jr l_scancode_to_char_00121 +l_scancode_to_char_00110: +;source-doc/keyboard/class_hid_keyboard.c:361: return 28; + ld a, e + sub 0x30 + jr NZ,l_scancode_to_char_00112 +;source-doc/keyboard/class_hid_keyboard.c:362: + ld a,0x1d + jr l_scancode_to_char_00121 +l_scancode_to_char_00112: +;source-doc/keyboard/class_hid_keyboard.c:364: return 29; + ld a, e + sub 0x23 + jr NZ,l_scancode_to_char_00114 +;source-doc/keyboard/class_hid_keyboard.c:365: + ld a,0x1e + jr l_scancode_to_char_00121 +l_scancode_to_char_00114: +;source-doc/keyboard/class_hid_keyboard.c:367: return 30; + ld a, e + sub 0x2d + jr NZ,l_scancode_to_char_00118 +;source-doc/keyboard/class_hid_keyboard.c:368: + ld a,0x1f + jr l_scancode_to_char_00121 +l_scancode_to_char_00118: +;source-doc/keyboard/class_hid_keyboard.c:371: } + ld a, c + and 0x22 + jr Z,l_scancode_to_char_00120 +;source-doc/keyboard/class_hid_keyboard.c:372: + ld d,0x00 + ld hl,_scancodes_shift_table + add hl, de + ld a, (hl) + ld l,(ix+4) + call _char_with_caps_lock + jr l_scancode_to_char_00121 +l_scancode_to_char_00120: +;source-doc/keyboard/class_hid_keyboard.c:374: return char_with_caps_lock(scancodes_shift_table[code], caps_lock_engaged); + ld d,0x00 + ld hl,_scancodes_table + add hl, de + ld a, (hl) + ld l,(ix+4) + call _char_with_caps_lock +l_scancode_to_char_00121: +;source-doc/keyboard/class_hid_keyboard.c:375: + pop ix + pop hl + inc sp + jp (hl) +_scancodes_shift_table: + DEFB +0x00 + DEFB +0x00 + DEFB +0x00 + DEFB +0x00 + DEFB +0x41 + DEFB +0x42 + DEFB +0x43 + DEFB +0x44 + DEFB +0x45 + DEFB +0x46 + DEFB +0x47 + DEFB +0x48 + DEFB +0x49 + DEFB +0x4a + DEFB +0x4b + DEFB +0x4c + DEFB +0x4d + DEFB +0x4e + DEFB +0x4f + DEFB +0x50 + DEFB +0x51 + DEFB +0x52 + DEFB +0x53 + DEFB +0x54 + DEFB +0x55 + DEFB +0x56 + DEFB +0x57 + DEFB +0x58 + DEFB +0x59 + DEFB +0x5a + DEFB +0x21 + DEFB +0x40 + DEFB +0x23 + DEFB +0x24 + DEFB +0x25 + DEFB +0x5e + DEFB +0x26 + DEFB +0x2a + DEFB +0x28 + DEFB +0x29 + DEFB +0x0d + DEFB +0x1b + DEFB +0x08 + DEFB +0x09 + DEFB +0x20 + DEFB +0x5f + DEFB +0x2b + DEFB +0x7b + DEFB +0x7d + DEFB +0x7c + DEFB +0x7e + DEFB +0x3a + DEFB +0x22 + DEFB +0x7e + DEFB +0x3c + DEFB +0x3e + DEFB +0x3f + 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 +0x2f + DEFB +0x2a + DEFB +0x2d + DEFB +0x2b + DEFB +0x0d + DEFB +0x31 + DEFB +0x32 + DEFB +0x33 + DEFB +0x34 + DEFB +0x35 + DEFB +0x36 + DEFB +0x37 + DEFB +0x38 + DEFB +0x39 + DEFB +0x30 + DEFB +0x2e + DEFB +0x5c + DEFB +0x00 + DEFB +0x00 + DEFB +0x3d + 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 +_scancodes_table: + DEFB +0x00 + DEFB +0x00 + DEFB +0x00 + DEFB +0x00 + DEFB +0x61 + DEFB +0x62 + DEFB +0x63 + DEFB +0x64 + DEFB +0x65 + DEFB +0x66 + DEFB +0x67 + DEFB +0x68 + DEFB +0x69 + DEFB +0x6a + DEFB +0x6b + DEFB +0x6c + DEFB +0x6d + DEFB +0x6e + DEFB +0x6f + DEFB +0x70 + DEFB +0x71 + DEFB +0x72 + DEFB +0x73 + DEFB +0x74 + DEFB +0x75 + DEFB +0x76 + DEFB +0x77 + DEFB +0x78 + DEFB +0x79 + DEFB +0x7a + DEFB +0x31 + DEFB +0x32 + DEFB +0x33 + DEFB +0x34 + DEFB +0x35 + DEFB +0x36 + DEFB +0x37 + DEFB +0x38 + DEFB +0x39 + DEFB +0x30 + DEFB +0x0d + DEFB +0x1b + DEFB +0x08 + DEFB +0x09 + DEFB +0x20 + DEFB +0x2d + DEFB +0x3d + DEFB +0x5b + DEFB +0x5d + DEFB +0x5c + DEFB +0x23 + DEFB +0x3b + DEFB +0x27 + DEFB +0x60 + DEFB +0x2c + DEFB +0x2e + DEFB +0x2f + 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 +0x2f + DEFB +0x2a + DEFB +0x2d + DEFB +0x2b + DEFB +0x0d + DEFB +0x31 + DEFB +0x32 + DEFB +0x33 + DEFB +0x34 + DEFB +0x35 + DEFB +0x36 + DEFB +0x37 + DEFB +0x38 + DEFB +0x39 + DEFB +0x30 + DEFB +0x2e + DEFB +0x5c + DEFB +0x00 + DEFB +0x00 + DEFB +0x3d + 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/keyboard/kyb-init.c.s b/Source/HBIOS/ch376-native/keyboard/kyb-init.c.s new file mode 100644 index 00000000..9aba172e --- /dev/null +++ b/Source/HBIOS/ch376-native/keyboard/kyb-init.c.s @@ -0,0 +1,122 @@ +; +; Generated from source-doc/keyboard/kyb-init.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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/keyboard/kyb-init.c:6: uint8_t keyboard_init(void) __sdcccall(1) { +; --------------------------------- +; Function keyboard_init +; --------------------------------- +_keyboard_init: + push ix + ld ix,0 + add ix,sp + dec sp +;source-doc/keyboard/kyb-init.c:7: uint8_t index = 1; +;source-doc/keyboard/kyb-init.c:9: do { + ld c,0x01 + ld (ix-1),c +l_keyboard_init_00103: +;source-doc/keyboard/kyb-init.c:10: usb_device_type t = usb_get_device_type(index); + ld e, c + ld d,0x00 + push bc + push de + push de + call _usb_get_device_type + pop af + ld a, l + pop de + pop bc +;source-doc/keyboard/kyb-init.c:12: if (t == USB_IS_KEYBOARD) { + sub 0x04 + jr NZ,l_keyboard_init_00104 +;source-doc/keyboard/kyb-init.c:13: print_string("\r\nUSB: KEYBOARD @ $"); + push de + ld hl,kyb_init_str_0 + call _print_string + pop de +;source-doc/keyboard/kyb-init.c:14: print_uint16(index); + ex de, hl + call _print_uint16 +;source-doc/keyboard/kyb-init.c:15: print_string(" $"); + ld hl,kyb_init_str_1 + call _print_string +;source-doc/keyboard/kyb-init.c:17: usb_kyb_init(index); + ld a,(ix-1) + call _usb_kyb_init +;source-doc/keyboard/kyb-init.c:18: return 1; + ld a,0x01 + jr l_keyboard_init_00106 +l_keyboard_init_00104: +;source-doc/keyboard/kyb-init.c:20: } while (++index != MAX_NUMBER_OF_DEVICES + 1); + inc c + ld (ix-1),c + ld a, c + sub 0x07 + jr NZ,l_keyboard_init_00103 +;source-doc/keyboard/kyb-init.c:22: print_string("\r\nUSB: KEYBOARD: NOT FOUND$"); + ld hl,kyb_init_str_2 + call _print_string +;source-doc/keyboard/kyb-init.c:24: return 0; + xor a +l_keyboard_init_00106: +;source-doc/keyboard/kyb-init.c:25: } + inc sp + pop ix + ret +kyb_init_str_0: + DEFB 0x0d + DEFB 0x0a + DEFM "USB: KEYBOARD @ $" + DEFB 0x00 +kyb_init_str_1: + DEFM " $" + DEFB 0x00 +kyb_init_str_2: + DEFB 0x0d + DEFB 0x0a + DEFM "USB: KEYBOARD: NOT FOUND$" + DEFB 0x00 diff --git a/Source/HBIOS/ch376-native/keyboard/kyb_driver.c.s b/Source/HBIOS/ch376-native/keyboard/kyb_driver.c.s new file mode 100644 index 00000000..f804e4ae --- /dev/null +++ b/Source/HBIOS/ch376-native/keyboard/kyb_driver.c.s @@ -0,0 +1,406 @@ +; +; Generated from source-doc/keyboard/kyb_driver.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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 + +_caps_lock_engaged: + DEFS 1 +_keyboard_config: + DEFS 2 +_buffer: + DEFS 8 +_write_index: + DEFS 1 +_read_index: + DEFS 1 +_report: + DEFS 8 +_previous: + DEFS 8 + +#ENDIF + +;-------------------------------------------------------- +; absolute external ram data +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;source-doc/keyboard/kyb_driver.c:23: #define EI __asm__("EI") +; --------------------------------- +; Function report_diff +; --------------------------------- +_report_diff: +;source-doc/keyboard/kyb_driver.c:24: + ld de,_report+0 +;source-doc/keyboard/kyb_driver.c:25: static uint8_t report_diff() __sdcccall(1) { +;source-doc/keyboard/kyb_driver.c:28: + ld b,0x08 + ld hl,_previous +l_report_diff_00103: +;source-doc/keyboard/kyb_driver.c:29: uint8_t i = sizeof(report); + ld a, (de) + inc de + ld c, (hl) + inc hl + sub c + jr Z,l_report_diff_00104 +;source-doc/keyboard/kyb_driver.c:30: do { + ld a,0x01 + jr l_report_diff_00106 +l_report_diff_00104: +;source-doc/keyboard/kyb_driver.c:31: if (*a++ != *b++) + djnz l_report_diff_00103 +;source-doc/keyboard/kyb_driver.c:33: } while (--i != 0); + xor a +l_report_diff_00106: +;source-doc/keyboard/kyb_driver.c:34: + ret +;source-doc/keyboard/kyb_driver.c:36: } +; --------------------------------- +; Function keyboard_buf_put +; --------------------------------- +_keyboard_buf_put: + ld c, a +;source-doc/keyboard/kyb_driver.c:37: + ld b,0x00 + ld hl,+(_report + 2) + add hl, bc +;source-doc/keyboard/kyb_driver.c:38: static void keyboard_buf_put(const uint8_t indx) __sdcccall(1) { + ld a,(hl) + ld e,a + sub 0x80 + jr NC,l_keyboard_buf_put_00112 + ld a, e + or a +;source-doc/keyboard/kyb_driver.c:39: const uint8_t key_code = report.keyCode[indx]; + jr Z,l_keyboard_buf_put_00112 +;source-doc/keyboard/kyb_driver.c:42: + ld b,0x00 + ld hl,+(_previous + 2) + add hl, bc + ld a, (hl) + sub e +;source-doc/keyboard/kyb_driver.c:43: // if already reported, just skip it + jr Z,l_keyboard_buf_put_00112 +;source-doc/keyboard/kyb_driver.c:45: return; + ld a, e + sub 0x39 + jr NZ,l_keyboard_buf_put_00107 +;source-doc/keyboard/kyb_driver.c:46: + ld hl,_caps_lock_engaged + ld a, (hl) + xor 0x01 + ld (hl), a +;source-doc/keyboard/kyb_driver.c:47: if (key_code == KEY_CODE_CAPS_LOCK) { + jr l_keyboard_buf_put_00112 +l_keyboard_buf_put_00107: +;source-doc/keyboard/kyb_driver.c:50: } + ld a,(_report) + ld hl,_caps_lock_engaged + ld h, (hl) + push hl + inc sp + ld l, e + call _scancode_to_char + ld b, a +;source-doc/keyboard/kyb_driver.c:52: const unsigned char c = scancode_to_char(report.bModifierKeys, key_code, caps_lock_engaged); + or a +;source-doc/keyboard/kyb_driver.c:53: + ret Z +;source-doc/keyboard/kyb_driver.c:55: return; + ld a, (_write_index) + inc a + and 0x07 + ld c, a +;source-doc/keyboard/kyb_driver.c:56: + ld hl,_read_index + ld a, (hl) + sub c + ret Z +;source-doc/keyboard/kyb_driver.c:57: uint8_t next_write_index = (write_index + 1) & KEYBOARD_BUFFER_SIZE_MASK; + ld hl,(_write_index) + ld h,0x00 + ld de,_buffer + add hl,de + ld a,b + ld (hl),a + ld hl,_write_index +;source-doc/keyboard/kyb_driver.c:58: if (next_write_index != read_index) { // Check if buffer is not full + ld (hl), c +l_keyboard_buf_put_00112: +;source-doc/keyboard/kyb_driver.c:60: write_index = next_write_index; + ret +;source-doc/keyboard/kyb_driver.c:62: } +; --------------------------------- +; Function usb_kyb_status +; --------------------------------- +_usb_kyb_status: +;source-doc/keyboard/kyb_driver.c:63: + DI +;source-doc/keyboard/kyb_driver.c:67: uint8_t size; + ld a,(_write_index) + ld hl,_read_index + sub (hl) + jr C,l_usb_kyb_status_00102 +;source-doc/keyboard/kyb_driver.c:68: + ld a,(_write_index) + ld hl,_read_index + sub (hl) + jr l_usb_kyb_status_00103 +l_usb_kyb_status_00102: +;source-doc/keyboard/kyb_driver.c:70: size = write_index - read_index; + ld hl, (_read_index) + ld a,0x08 + sub l + ld hl, (_write_index) + add a, l +l_usb_kyb_status_00103: +;source-doc/keyboard/kyb_driver.c:72: size = KEYBOARD_BUFFER_SIZE - read_index + write_index; + EI +;source-doc/keyboard/kyb_driver.c:73: +;source-doc/keyboard/kyb_driver.c:74: EI; + ret +;source-doc/keyboard/kyb_driver.c:76: } +; --------------------------------- +; Function usb_kyb_read +; --------------------------------- +_usb_kyb_read: +;source-doc/keyboard/kyb_driver.c:77: + ld a,(_write_index) + ld hl,_read_index + sub (hl) + jr NZ,l_usb_kyb_read_00102 +;source-doc/keyboard/kyb_driver.c:78: uint16_t usb_kyb_read() { + ld hl,0xff00 + jr l_usb_kyb_read_00103 +l_usb_kyb_read_00102: +;source-doc/keyboard/kyb_driver.c:80: return 0xFF00; // H = -1, L = 0 + DI +;source-doc/keyboard/kyb_driver.c:81: + ld hl,(_read_index) + ld h,0x00 + ld bc,_buffer + add hl,bc + ld a,(hl) + ld c,l + ld b,h + ld hl,_read_index + ld l, a +;source-doc/keyboard/kyb_driver.c:82: DI; + ld a, (_read_index) + inc a + and 0x07 + ld (_read_index), a +;source-doc/keyboard/kyb_driver.c:83: const uint8_t c = buffer[read_index]; + EI +;source-doc/keyboard/kyb_driver.c:86: + ld h,0x00 +l_usb_kyb_read_00103: +;source-doc/keyboard/kyb_driver.c:87: /* H = 0, L = ascii char */ + ret +;source-doc/keyboard/kyb_driver.c:89: } +; --------------------------------- +; Function usb_kyb_flush +; --------------------------------- +_usb_kyb_flush: +;source-doc/keyboard/kyb_driver.c:90: + DI +;source-doc/keyboard/kyb_driver.c:91: uint8_t usb_kyb_flush() __sdcccall(1) { + xor a + ld (_read_index),a + ld (_write_index),a +;source-doc/keyboard/kyb_driver.c:94: + ld de,_previous+0 +;source-doc/keyboard/kyb_driver.c:95: uint8_t i = sizeof(previous); +;source-doc/keyboard/kyb_driver.c:96: uint8_t *a = (uint8_t *)previous; + ld b,0x08 + ld hl,_report +l_usb_kyb_flush_00101: +;source-doc/keyboard/kyb_driver.c:97: uint8_t *b = (uint8_t *)report; + xor a + ld (de), a + inc de +;source-doc/keyboard/kyb_driver.c:98: do { + ld (hl),0x00 + inc hl +;source-doc/keyboard/kyb_driver.c:99: *a++ = 0; + djnz l_usb_kyb_flush_00101 +;source-doc/keyboard/kyb_driver.c:101: } while (--i != 0); + EI +;source-doc/keyboard/kyb_driver.c:103: EI; + xor a +;source-doc/keyboard/kyb_driver.c:104: + ret +;source-doc/keyboard/kyb_driver.c:106: } +; --------------------------------- +; Function usb_kyb_tick +; --------------------------------- +_usb_kyb_tick: +;source-doc/keyboard/kyb_driver.c:109: usb_error result; + ld hl,_in_critical_usb_section + ld a, (hl) + or a +;source-doc/keyboard/kyb_driver.c:110: + jr NZ,l_usb_kyb_tick_00112 +;././source-doc/base-drv//ch376.h:108: #define TRACE_USB_ERROR(result) + ld l,0x0b + call _ch_command +;././source-doc/base-drv//ch376.h:109: + ld a,0x25 + ld bc,_CH376_DATA_PORT + out (c), a +;././source-doc/base-drv//ch376.h:110: #endif + ld a,0x1f + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/keyboard/kyb_driver.c:113: + ld bc,_report+0 + ld hl, (_keyboard_config) + ld a,0x08 + push af + inc sp + push bc + push hl + call _usbdev_dat_in_trnsfer_0 + pop af + pop af + inc sp +;././source-doc/base-drv//ch376.h:108: #define TRACE_USB_ERROR(result) + push hl + ld l,0x0b + call _ch_command + pop hl +;././source-doc/base-drv//ch376.h:109: + ld a,0x25 + ld bc,_CH376_DATA_PORT + out (c), a +;././source-doc/base-drv//ch376.h:110: #endif + ld a,0xdf + ld bc,_CH376_DATA_PORT + out (c), a +;source-doc/keyboard/kyb_driver.c:115: result = usbdev_dat_in_trnsfer_0((device_config *)keyboard_config, (uint8_t *)&report, 8); + ld a, l + or a + jr NZ,l_usb_kyb_tick_00112 +;source-doc/keyboard/kyb_driver.c:116: ch_configure_nak_retry_3s(); + call _report_diff + or a + jr Z,l_usb_kyb_tick_00112 +;source-doc/keyboard/kyb_driver.c:118: if (report_diff()) { + ld b,0x06 +l_usb_kyb_tick_00103: +;source-doc/keyboard/kyb_driver.c:119: uint8_t i = 6; + ld a, b + dec a + push bc + call _keyboard_buf_put + pop bc +;source-doc/keyboard/kyb_driver.c:120: do { + djnz l_usb_kyb_tick_00103 +;source-doc/keyboard/kyb_driver.c:121: keyboard_buf_put(i - 1); + ld de,_previous + ld bc,0x0008 + ld hl,_report + ldir +l_usb_kyb_tick_00112: +;source-doc/keyboard/kyb_driver.c:124: } + ret +;source-doc/keyboard/kyb_driver.c:126: } +; --------------------------------- +; Function usb_kyb_init +; --------------------------------- +_usb_kyb_init: +;source-doc/keyboard/kyb_driver.c:127: + call _get_usb_device_config + ex de, hl + ld (_keyboard_config), hl +;source-doc/keyboard/kyb_driver.c:129: keyboard_config = (device_config_keyboard *)get_usb_device_config(dev_index); + ld hl,_keyboard_config + 1 + ld a, (hl) + dec hl + or (hl) +;source-doc/keyboard/kyb_driver.c:130: + ret Z +;source-doc/keyboard/kyb_driver.c:132: return; + ld a,0x01 + push af + inc sp + ld hl, (_keyboard_config) + call _hid_set_protocol +;source-doc/keyboard/kyb_driver.c:133: + ld a,0x80 + push af + inc sp + ld hl, (_keyboard_config) + call _hid_set_idle +;source-doc/keyboard/kyb_driver.c:134: hid_set_protocol(keyboard_config, 1); + ret +_caps_lock_engaged: + DEFB +0x01 +_keyboard_config: + DEFW +0x0000 +_buffer: + DEFB +0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 +_write_index: + DEFB +0x00 +_read_index: + DEFB +0x00 +_report: + DEFB +0x00 + DEFB +0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 +_previous: + DEFB +0x00 + DEFB +0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 + DEFB 0x00 diff --git a/Source/HBIOS/ch376-native/print.asm b/Source/HBIOS/ch376-native/print.asm new file mode 100644 index 00000000..99d736f2 --- /dev/null +++ b/Source/HBIOS/ch376-native/print.asm @@ -0,0 +1,39 @@ + + ; HL = unsigned 16 bit number to write out + ; call CHPUT to write a single ascii character (in A) +_print_uint16: + ld a, h + or l + jr z, print_zero + 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 + +print_zero + ld a, '0' + jp COUT diff --git a/Source/HBIOS/ch376-native/readme.md b/Source/HBIOS/ch376-native/readme.md new file mode 100644 index 00000000..f92ffd8c --- /dev/null +++ b/Source/HBIOS/ch376-native/readme.md @@ -0,0 +1,125 @@ +# Native CH376 Driver + +The native CH376 HBIOS driver is written in c, using z88dk's zcc compiler. + +The build process, is a 3 stage process. + +1. Compile all the C code to assembly files (.asm) +2. Translate the produced .asm files syntax to compile with the RomWBW assembler (.s) +3. Assemble the driver .s files as per the standard HBIOS build process + +The original C code and produced/translated .s files are all committed units in the repo. But it is +expected, that only the c files are to be modified/updated. + +The .s files are checked in, so builders do not require the C compiler tool chain (z88dk) to be installed. + +The c compiling/translating process is only supported on linux, as the script to translate the .asm files +to .s files is a linux bash script. (Although the script can be easily run within Windows's Sub-system for linux) + +## Compiling the C code + +> Requires linux with docker installed. + +> The C code only needs to be recompiled if and when you change any of the `.c` source files. + +To compile the `.c` code to generate updated `.s` files: + +Within the `Source/HBIOS/ch376-native` directory: + +``` +make +``` + +The make script will search for z88dk's `zcc` compiler, if not found, will attempt to use a docker wrapper. +It will not work if z88dk or docker is not installed. + +## USB Native Driver systems + +The default builds of RomWBW do not enable the CH376 native usb drivers. These drivers take a reasonable chunk of ROM space. As such you +will need to build a new HBIOS image customised for your platform. Please familiarise yourself with the HBIOS/RomWBW build and configuration process. + +The usb driver is divided into a few sub-system, which can be individually enabled within the standard HBIOS config files. + +For activating the full native USB support, the non native CH365 drivers need to be disabled and the relevant `CHNATIVE` drivers enabled + +Example: + +``` +CHENABLE .SET FALSE ; CH: ENABLE CH375/376 USB SUPPORT +CH0USBENABLE .SET FALSE ; CH375: ENABLE CH375 USB DRIVER +CH1USBENABLE .SET FALSE ; CH376: ENABLE CH376 USB DRIVER +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) +CHNATIVEEZ80 .SET FALSE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE +CHNATIVEFORCE .SET TRUE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED +``` + +As the USB driver is a fairly large, you may need to disable other HBIOS drivers in your configuration. As such, it is +recommend to only enable drivers for your platform's hardware configuration - for example, enable only the serial driver +required for your system. + +``` +DUARTENABLE .SET FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM) +UARTENABLE .SET FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM) +ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM) +SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM) +``` + +You may also need to disable other storage drivers: + +``` +FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM) +IDEENABLE .SET FALSE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM) +PPIDEENABLE .SET FALSE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM) +``` + +### base-drv `CHNATIVEENABLE` + +The `base-drv` system contains the core code to discover, enumerate, and communicate with USB devices. + +It also includes the driver code to enumerate and operating USB devices through a USB hub. + +### scsi-drv `CHSCSIENABLE` + +The `scsi-drv` system can be enabled with the HBIOS config `CHSCSIENABLE` + +When activated, access to most USB mass storage devices (thumb drives, magnetic usb drives) is enabled. + +### ufi-drv `CHUFIENABLE` + +The `ufi-drv` system can be enabled with the HBIOS config `CHUFIENABLE` + +When activated, access to 3.5" Floppy USB devices will be enabled. + +### keyboard `TMSMODE_MSXUKY` + +The `keyboard` system can be enabled with the inferred config entry `USBKYBENABLE` + +This config item is not to be directly set, but is activated via the TMS keyboard driver + +Example configuration, combined with the TMS VDP module driver. + +``` +TMSENABLE .SET TRUE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM) +TMSMODE .SET TMSMODE_MSXUKY ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY] +TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958 +TMSTIMENABLE .SET TRUE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1) +``` + +When activated, usb keyboards can be used as input devices. + +### Force activation `CHNATIVEFORCE` + +The CH376 module, during a cold power on boot, can take many seconds before it will +respond to the CPU. As such, the CPU may fail to detect the presence of the module. + +A manual reset (without power cycling) generally enables detection. The config entry +`CHNATIVEFORCE` can be enabled to force the CPU to always wait for the module to come online. + + +### eZ80 support `CHNATIVEEZ80` + +If you have the eZ80 CPU installed with onboard USB firmware support, you +can gain performance by delegating HBIOS to the firmware implementation. To enable +delegation, enable the config entry `CHNATIVEEZ80` diff --git a/Source/HBIOS/ch376-native/scsi-drv.s b/Source/HBIOS/ch376-native/scsi-drv.s new file mode 100644 index 00000000..ea6f8a70 --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv.s @@ -0,0 +1,8 @@ +; Generated File -- not to be modify directly +#IF (!CHNATIVEEZ80) +#include "ch376-native/scsi-drv/class_scsi.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/scsi-drv/scsi_driver.c.s" +#ENDIF +#include "ch376-native/scsi-drv/scsi-init.c.s" diff --git a/Source/HBIOS/ch376-native/scsi-drv/.gitignore b/Source/HBIOS/ch376-native/scsi-drv/.gitignore new file mode 100644 index 00000000..f4cb8488 --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv/.gitignore @@ -0,0 +1 @@ +*.asm 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..bcf0bdae --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv/class_scsi.c.s @@ -0,0 +1,446 @@ +; +; 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.5.0 #15248 (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 + +_scsi_command_block_wrapper: + DEFS 15 +_next_tag: + DEFS 2 + +#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, -21 + add hl, sp + ld sp, hl +;source-doc/scsi-drv/class_scsi.c:17: _scsi_command_status_wrapper csw = {{{0}}}; + ld a,0x00 + ld (ix-21),a + ld (ix-20),a + ld (ix-19),a + ld (ix-18),a + xor a + ld (ix-17),a + ld (ix-16),a + xor a + ld (ix-15),a + ld (ix-14),a + ld a,0x00 + ld (ix-13),a + ld (ix-12),a + ld (ix-11),a + ld (ix-10),a + ld (ix-9),0x00 +;source-doc/scsi-drv/class_scsi.c:19: cbw->dCBWTag[0] = next_tag++; + ld c,(ix+6) + ld b,(ix+7) + ld hl,0x0004 + add hl, bc + ld (ix-8),l + ld (ix-7),h + ld a, (_next_tag) + ld e, a + ld hl,_next_tag + 1 + ld d, (hl) + ld hl, (_next_tag) + inc hl + ld (_next_tag), hl + ld l,(ix-8) + ld h,(ix-7) + ld (hl), e + inc hl + ld (hl), d +;source-doc/scsi-drv/class_scsi.c:21: if (!send) + bit 0,(ix+10) + jr NZ,l_do_scsi_cmd_00102 +;source-doc/scsi-drv/class_scsi.c:22: cbw->bmCBWFlags = 0x80; + ld hl,0x000c + add hl, bc + ld (hl),0x80 +l_do_scsi_cmd_00102: +;source-doc/scsi-drv/class_scsi.c:24: critical_begin(); + push bc + call _critical_begin + pop bc +;source-doc/scsi-drv/class_scsi.c:27: &dev->endpoints[ENDPOINT_BULK_OUT])); + ld a,(ix+4) + ld (ix-6),a + ld e, a + ld a,(ix+5) + ld (ix-5),a + ld d,a + inc de + inc de + inc de + ld a,(ix-6) + ld (ix-4),a + ld l, a + ld a,(ix-5) + ld (ix-3),a + ld h,a + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + ld l,(ix+6) + ld h,(ix+7) + push bc + push de + push de + push af + inc sp + push hl + ld hl,0x001f + ex (sp), hl + push hl + call _usb_data_out_transfer + pop af + pop af + pop af + inc sp + pop de + pop bc + ld a, l + or a + jp NZ, l_do_scsi_cmd_00120 +;source-doc/scsi-drv/class_scsi.c:29: 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:32: &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:30: if (!send) { + bit 0,(ix+10) + jr NZ,l_do_scsi_cmd_00110 +;source-doc/scsi-drv/class_scsi.c:32: &dev->endpoints[ENDPOINT_BULK_IN])); + ld a,(ix-6) + add a,0x06 + ld e, a + ld a,(ix-5) + adc a,0x00 + ld d, a + ld l,(ix-4) + ld h,(ix-3) + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + push de + 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 + or a + jr Z,l_do_scsi_cmd_00113 + jr l_do_scsi_cmd_00120 +l_do_scsi_cmd_00110: +;source-doc/scsi-drv/class_scsi.c:36: &dev->endpoints[ENDPOINT_BULK_OUT])); + ld l,(ix-4) + ld h,(ix-3) + ld a, (hl) + rlca + rlca + rlca + rlca + and 0x0f + push de + 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 + or a + jr NZ,l_do_scsi_cmd_00120 +l_do_scsi_cmd_00113: +;source-doc/scsi-drv/class_scsi.c:41: usb_data_in_transfer((uint8_t *)&csw, sizeof(_scsi_command_status_wrapper), dev->address, &dev->endpoints[ENDPOINT_BULK_IN])); + ld a,(ix-6) + add a,0x06 + ld c, a + ld a,(ix-5) + adc a,0x00 + ld b, a + ld l,(ix-4) + ld h,(ix-3) + 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,5 + add hl, sp + push hl + call _usb_data_in_transfer + pop af + pop af + pop af + inc sp + ld a, l + or a + jr NZ,l_do_scsi_cmd_00120 +;source-doc/scsi-drv/class_scsi.c:43: if (csw.bCSWStatus != 0 || csw.dCSWTag[0] != cbw->dCBWTag[0]) + ld a,(ix-9) + or a + jr NZ,l_do_scsi_cmd_00116 + ld c,(ix-17) + ld b,(ix-16) + ld l,(ix-8) + ld h,(ix-7) + ld a, (hl) + inc hl + ld h, (hl) + ld l, a + xor a + sbc hl,bc + jr Z,l_do_scsi_cmd_00117 +l_do_scsi_cmd_00116: +;source-doc/scsi-drv/class_scsi.c:44: result = USB_ERR_FAIL; + ld l,0x0e + jr l_do_scsi_cmd_00120 +l_do_scsi_cmd_00117: +;source-doc/scsi-drv/class_scsi.c:46: result = USB_ERR_OK; + ld l,0x00 +;source-doc/scsi-drv/class_scsi.c:48: done: +l_do_scsi_cmd_00120: +;source-doc/scsi-drv/class_scsi.c:49: critical_end(); + push hl + call _critical_end + pop hl +;source-doc/scsi-drv/class_scsi.c:50: return result; +;source-doc/scsi-drv/class_scsi.c:51: } + ld sp, ix + pop ix + ret +;source-doc/scsi-drv/class_scsi.c:53: 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:55: cbw_scsi.cbw = scsi_command_block_wrapper; + ld hl,0 + add hl, sp + ld e,l + ld d,h + push hl + ld bc,0x000f + ld hl,_scsi_command_block_wrapper + ldir +;source-doc/scsi-drv/class_scsi.c:56: memset(&cbw_scsi.test, 0, sizeof(_scsi_packet_test)); + ld hl,17 + add hl, sp + ld b,0x06 +l_scsi_test_00103: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_scsi_test_00103 + pop bc +;source-doc/scsi-drv/class_scsi.c:58: cbw_scsi.cbw.bCBWLUN = 0; + ld (ix-14),0x00 +;source-doc/scsi-drv/class_scsi.c:59: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_test); + ld (ix-13),0x0c +;source-doc/scsi-drv/class_scsi.c:60: cbw_scsi.cbw.dCBWDataTransferLength = 0; + ld hl,0x0008 + add hl, bc + 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:62: return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false); + xor a + push af + inc sp + ld hl,0x0000 + push hl + push bc + ld l,(ix+4) + ld h,(ix+5) + push hl + call _do_scsi_cmd +;source-doc/scsi-drv/class_scsi.c:63: } + ld sp,ix + pop ix + ret +;source-doc/scsi-drv/class_scsi.c:67: 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:69: cbw_scsi.cbw = scsi_command_block_wrapper; + ld hl,0 + add hl, sp + ld e,l + ld d,h + push hl + ld bc,0x000f + ld hl,_scsi_command_block_wrapper + ldir +;source-doc/scsi-drv/class_scsi.c:70: cbw_scsi.request_sense = scsi_packet_request_sense; + ld hl,17 + add hl, sp + ex de, hl + ld bc,0x000c + ld hl,_scsi_packet_request_sense + ldir + pop bc +;source-doc/scsi-drv/class_scsi.c:72: cbw_scsi.cbw.bCBWLUN = 0; + ld (ix-14),0x00 +;source-doc/scsi-drv/class_scsi.c:73: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_request_sense); + ld (ix-13),0x0c +;source-doc/scsi-drv/class_scsi.c:74: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_sense_result); + ld hl,0x0008 + add hl, bc + ld (hl),0x12 + inc hl + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + ld (hl), a +;source-doc/scsi-drv/class_scsi.c:76: return do_scsi_cmd(dev, &cbw_scsi.cbw, sens_result, false); + ld e,(ix+6) + ld d,(ix+7) + xor a + push af + inc sp + push de + push bc + ld l,(ix+4) + ld h,(ix+5) + push hl + call _do_scsi_cmd +;source-doc/scsi-drv/class_scsi.c:77: } + ld sp,ix + pop ix + ret +_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 +_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 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..3f0802de --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv/scsi-init.c.s @@ -0,0 +1,148 @@ +; +; 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.5.0 #15248 (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/scsi-drv/scsi-init.c:9: void chscsi_init(void) { +; --------------------------------- +; Function chscsi_init +; --------------------------------- +_chscsi_init: + push ix + ld ix,0 + add ix,sp + push af + dec sp +;source-doc/scsi-drv/scsi-init.c:11: do { + ld (ix-1),0x01 +l_chscsi_init_00103: +;source-doc/scsi-drv/scsi-init.c:12: usb_device_type t = usb_get_device_type(index); + ld a,(ix-1) + ld (ix-3),a + ld (ix-2),0x00 + pop hl + push hl + push hl + call _usb_get_device_type + pop af + ld a, l +;source-doc/scsi-drv/scsi-init.c:14: if (t == USB_IS_MASS_STORAGE) { + sub 0x02 + jr NZ,l_chscsi_init_00104 +;source-doc/scsi-drv/scsi-init.c:15: const uint8_t dev_index = find_storage_dev(); // index == -1 (no more left) should never happen + call _find_storage_dev +;source-doc/scsi-drv/scsi-init.c:17: hbios_usb_storage_devices[dev_index].drive_index = dev_index + 1; + ld a, l + ld c,0x00 + add a, a + rl c + add a, +((_hbios_usb_storage_devices) & 0xFF) + ld e, a + ld a, c + adc a, +((_hbios_usb_storage_devices) / 256) + ld d, a + ld c, e + ld b, d + ld a, l + inc a + ld (bc), a +;source-doc/scsi-drv/scsi-init.c:18: hbios_usb_storage_devices[dev_index].usb_device = index; + ld c, e + ld b, d + inc bc + ld a,(ix-1) + ld (bc), a +;source-doc/scsi-drv/scsi-init.c:20: print_string("\r\nUSB: MASS STORAGE @ $"); + push hl + push de + ld hl,scsi_init_str_0 + call _print_string +;source-doc/scsi-drv/scsi-init.c:21: print_uint16(index); + ld l,(ix-3) + ld h,0x00 + call _print_uint16 +;source-doc/scsi-drv/scsi-init.c:22: print_string(":$"); + ld hl,scsi_init_str_1 + call _print_string + pop de + pop hl +;source-doc/scsi-drv/scsi-init.c:23: print_uint16(dev_index); + ld h,0x00 + push de + call _print_uint16 +;source-doc/scsi-drv/scsi-init.c:24: print_string(" $"); + ld hl,scsi_init_str_2 + call _print_string +;source-doc/scsi-drv/scsi-init.c:25: usb_scsi_init(index); + ld l,(ix-3) + ld h,0x00 + push hl + call _usb_scsi_init + pop af + pop de +;source-doc/scsi-drv/scsi-init.c:26: dio_add_entry(ch_scsi_fntbl, &hbios_usb_storage_devices[dev_index]); + ld hl,_ch_scsi_fntbl + call _dio_add_entry +l_chscsi_init_00104: +;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_00103 +;source-doc/scsi-drv/scsi-init.c:30: } + ld sp, ix + pop ix + ret +scsi_init_str_0: + DEFB 0x0d + DEFB 0x0a + DEFM "USB: MASS STORAGE @ $" + DEFB 0x00 +scsi_init_str_1: + DEFM ":$" + DEFB 0x00 +scsi_init_str_2: + DEFM " $" + DEFB 0x00 diff --git a/Source/HBIOS/ch376-native/scsi-drv/scsi_driver.c.s b/Source/HBIOS/ch376-native/scsi-drv/scsi_driver.c.s new file mode 100644 index 00000000..9dc504aa --- /dev/null +++ b/Source/HBIOS/ch376-native/scsi-drv/scsi_driver.c.s @@ -0,0 +1,470 @@ +; +; Generated from source-doc/scsi-drv/scsi_driver.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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 + +_scsi_packet_read_capacity: + DEFS 12 +_cbw: + DEFS 27 + +#ENDIF + +;-------------------------------------------------------- +; absolute external ram data +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;source-doc/scsi-drv/scsi_driver.c:8: usb_error usb_scsi_init(const uint16_t dev_index) { +; --------------------------------- +; Function usb_scsi_init +; --------------------------------- +_usb_scsi_init: + push ix + ld ix,0 + add ix,sp + ld hl, -18 + add hl, sp + ld sp, hl +;source-doc/scsi-drv/scsi_driver.c:11: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config +;source-doc/scsi-drv/scsi_driver.c:16: critical_begin(); + push de + call _critical_begin + pop de +;source-doc/scsi-drv/scsi_driver.c:17: while ((result = scsi_test(dev)) && --counter > 0) + ld c,0x03 +l_usb_scsi_init_00102: + push bc + push de + push de + call _scsi_test + pop af + ld a, l + pop de + pop bc + ld l, a + or a + jr Z,l_usb_scsi_init_00104 + dec c + jr Z,l_usb_scsi_init_00104 +;source-doc/scsi-drv/scsi_driver.c:18: scsi_request_sense(dev, &response); + push bc + push de + ld hl,4 + add hl, sp + push hl + push de + call _scsi_request_sense + pop af + pop af + pop de + pop bc + jr l_usb_scsi_init_00102 +l_usb_scsi_init_00104: +;source-doc/scsi-drv/scsi_driver.c:19: critical_end(); + push hl + call _critical_end + pop hl +;source-doc/scsi-drv/scsi_driver.c:21: return result; +;source-doc/scsi-drv/scsi_driver.c:22: } + ld sp, ix + pop ix + ret +;source-doc/scsi-drv/scsi_driver.c:26: usb_error usb_scsi_read_capacity(const uint16_t dev_index, scsi_read_capacity_result *cap_result) { +; --------------------------------- +; Function usb_scsi_read_capacity +; --------------------------------- +_usb_scsi_read_capacity: + push ix + ld ix,0 + add ix,sp + ld hl, -27 + add hl, sp + ld sp, hl +;source-doc/scsi-drv/scsi_driver.c:27: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config +;source-doc/scsi-drv/scsi_driver.c:30: cbw_scsi.cbw = scsi_command_block_wrapper; + push de + ld hl,2 + add hl, sp + ex de, hl + ld bc,0x000f + ld hl,_scsi_command_block_wrapper + ldir + pop de +;source-doc/scsi-drv/scsi_driver.c:31: cbw_scsi.read_capacity = scsi_packet_read_capacity; + push de + ld hl,17 + add hl, sp + ex de, hl + ld bc,0x000c + ld hl,_scsi_packet_read_capacity + ldir + pop de +;source-doc/scsi-drv/scsi_driver.c:33: cbw_scsi.cbw.bCBWLUN = 0; + ld (ix-14),0x00 +;source-doc/scsi-drv/scsi_driver.c:34: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_read_capacity); + ld (ix-13),0x0c +;source-doc/scsi-drv/scsi_driver.c:35: 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/scsi_driver.c:37: 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 + push de + call _do_scsi_cmd + pop af + pop af + pop af + inc sp +;source-doc/scsi-drv/scsi_driver.c:38: } + ld sp, ix + pop ix + ret +;source-doc/scsi-drv/scsi_driver.c:58: usb_error usb_scsi_read(const uint16_t dev_index, uint8_t *const buffer) { +; --------------------------------- +; Function usb_scsi_read +; --------------------------------- +_usb_scsi_read: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/scsi-drv/scsi_driver.c:61: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config + pop bc + push de +;source-doc/scsi-drv/scsi_driver.c:63: memset(&cbw, 0, sizeof(cbw_scsi_read_write)); + ld de,_cbw + ld l, e + ld h, d + ld b,0x0e + jr l_usb_scsi_read_00113 +l_usb_scsi_read_00112: + ld (hl),0x00 + inc hl +l_usb_scsi_read_00113: + ld (hl),0x00 + inc hl + djnz l_usb_scsi_read_00112 +;source-doc/scsi-drv/scsi_driver.c:64: cbw.cbw = scsi_command_block_wrapper; + ld bc,0x000f + ld hl,_scsi_command_block_wrapper + ldir +;source-doc/scsi-drv/scsi_driver.c:66: cbw.cbw.bCBWLUN = 0; + ld hl,_cbw + 13 + ld (hl),0x00 +;source-doc/scsi-drv/scsi_driver.c:67: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write); + ld hl,_cbw + 14 + ld (hl),0x0c +;source-doc/scsi-drv/scsi_driver.c:68: cbw.cbw.dCBWDataTransferLength = 512; + ld hl,0x0200 + ld (_cbw + 8),hl + ld h, l + ld (_cbw + 8 + 2),hl +;source-doc/scsi-drv/scsi_driver.c:70: cbw.scsi_cmd.operation_code = 0x28; // read operation + ld hl,_cbw + 15 + ld (hl),0x28 +;source-doc/scsi-drv/scsi_driver.c:71: cbw.scsi_cmd.transfer_len[1] = 1; + ld hl,_cbw + 23 + ld (hl),0x01 +;source-doc/scsi-drv/scsi_driver.c:72: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24; + pop hl + push hl + ld de,0x000c + add hl, de + push hl + inc hl + inc hl + inc hl + ld a, (hl) + ld ((_cbw + 17)),a + pop hl +;source-doc/scsi-drv/scsi_driver.c:73: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16; + push hl + inc hl + inc hl + ld a, (hl) + ld ((_cbw + 18)),a + pop hl +;source-doc/scsi-drv/scsi_driver.c:74: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8; + push hl + inc hl + ld a, (hl) + ld ((_cbw + 19)),a + pop hl +;source-doc/scsi-drv/scsi_driver.c:75: cbw.scsi_cmd.lba[3] = dev->current_lba; + ld bc,_cbw + 20 + ld a, (hl) + ld (bc), a +;source-doc/scsi-drv/scsi_driver.c:77: result = do_scsi_cmd(dev, &cbw.cbw, buffer, false); + ld c,(ix+6) + ld b,(ix+7) + push hl + xor a + push af + inc sp + push bc + ld de,_cbw + push de + ld e,(ix-2) + ld d,(ix-1) + push de + call _do_scsi_cmd + pop af + pop af + pop af + inc sp + ld a, l + pop hl + ld (ix-1),a +;source-doc/scsi-drv/scsi_driver.c:79: if (result == USB_ERR_OK) + or a + jr NZ,l_usb_scsi_read_00102 +;source-doc/scsi-drv/scsi_driver.c:80: dev->current_lba++; + ld c,(hl) + push hl + inc hl + ld b, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + pop hl + inc c + jr NZ,l_usb_scsi_read_00114 + inc b + jr NZ,l_usb_scsi_read_00114 + inc de +l_usb_scsi_read_00114: + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d +l_usb_scsi_read_00102: +;source-doc/scsi-drv/scsi_driver.c:81: return result; + ld l,(ix-1) +;source-doc/scsi-drv/scsi_driver.c:82: } + ld sp, ix + pop ix + ret +;source-doc/scsi-drv/scsi_driver.c:84: usb_error usb_scsi_write(const uint16_t dev_index, uint8_t *const buffer) { +; --------------------------------- +; Function usb_scsi_write +; --------------------------------- +_usb_scsi_write: + push ix + ld ix,0 + add ix,sp + push af +;source-doc/scsi-drv/scsi_driver.c:86: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config + pop bc + push de +;source-doc/scsi-drv/scsi_driver.c:88: memset(&cbw, 0, sizeof(cbw_scsi_read_write)); + ld de,_cbw + ld l, e + ld h, d + ld b,0x0e + jr l_usb_scsi_write_00113 +l_usb_scsi_write_00112: + ld (hl),0x00 + inc hl +l_usb_scsi_write_00113: + ld (hl),0x00 + inc hl + djnz l_usb_scsi_write_00112 +;source-doc/scsi-drv/scsi_driver.c:89: cbw.cbw = scsi_command_block_wrapper; + ld bc,0x000f + ld hl,_scsi_command_block_wrapper + ldir +;source-doc/scsi-drv/scsi_driver.c:91: cbw.cbw.bCBWLUN = 0; + ld hl,_cbw + 13 + ld (hl),0x00 +;source-doc/scsi-drv/scsi_driver.c:92: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write); + ld hl,_cbw + 14 + ld (hl),0x0c +;source-doc/scsi-drv/scsi_driver.c:93: cbw.cbw.dCBWDataTransferLength = 512; + ld hl,0x0200 + ld (_cbw + 8),hl + ld h, l + ld (_cbw + 8 + 2),hl +;source-doc/scsi-drv/scsi_driver.c:95: cbw.scsi_cmd.operation_code = 0x2A; // write operation + ld hl,_cbw + 15 + ld (hl),0x2a +;source-doc/scsi-drv/scsi_driver.c:96: cbw.scsi_cmd.transfer_len[1] = 1; + ld hl,_cbw + 23 + ld (hl),0x01 +;source-doc/scsi-drv/scsi_driver.c:97: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24; + pop hl + push hl + ld de,0x000c + add hl, de + push hl + inc hl + inc hl + inc hl + ld a, (hl) + ld ((_cbw + 17)),a + pop hl +;source-doc/scsi-drv/scsi_driver.c:98: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16; + push hl + inc hl + inc hl + ld a, (hl) + ld ((_cbw + 18)),a + pop hl +;source-doc/scsi-drv/scsi_driver.c:99: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8; + push hl + inc hl + ld a, (hl) + ld ((_cbw + 19)),a + pop hl +;source-doc/scsi-drv/scsi_driver.c:100: cbw.scsi_cmd.lba[3] = dev->current_lba; + ld bc,_cbw + 20 + ld a, (hl) + ld (bc), a +;source-doc/scsi-drv/scsi_driver.c:102: result = do_scsi_cmd(dev, &cbw.cbw, buffer, true); + ld c,(ix+6) + ld b,(ix+7) + push hl + ld a,0x01 + push af + inc sp + push bc + ld de,_cbw + push de + ld e,(ix-2) + ld d,(ix-1) + push de + call _do_scsi_cmd + pop af + pop af + pop af + inc sp + ld a, l + pop hl + ld (ix-1),a +;source-doc/scsi-drv/scsi_driver.c:104: if (result == USB_ERR_OK) + or a + jr NZ,l_usb_scsi_write_00102 +;source-doc/scsi-drv/scsi_driver.c:105: dev->current_lba++; + ld c,(hl) + push hl + inc hl + ld b, (hl) + inc hl + ld e, (hl) + inc hl + ld d, (hl) + pop hl + inc c + jr NZ,l_usb_scsi_write_00114 + inc b + jr NZ,l_usb_scsi_write_00114 + inc de +l_usb_scsi_write_00114: + ld (hl), c + inc hl + ld (hl), b + inc hl + ld (hl), e + inc hl + ld (hl), d +l_usb_scsi_write_00102: +;source-doc/scsi-drv/scsi_driver.c:106: return result; + ld l,(ix-1) +;source-doc/scsi-drv/scsi_driver.c:107: } + ld sp, ix + pop ix + ret +_scsi_packet_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 +_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/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..6892df6d --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.c @@ -0,0 +1,242 @@ +#include "ch376.h" + +#include "ez80-helpers.h" +#include "print.h" + +void ch_command(const uint8_t command) __z88dk_fastcall { + uint8_t counter = 255; + while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0) + ; + + // 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; + // } + + CH376_COMMAND_PORT = command; +} + +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; +} + +usb_error 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; + CH376_DATA_PORT = endpoint << 4 | pid; +} + +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; + +done: + USB_MODULE_LEDS = 0x00; + return result; +} + +// TODO: review: does buffer_size need to be signed? +usb_error ch_data_in_transfer_n(uint8_t *const buffer, uint8_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; +done: + USB_MODULE_LEDS = 0x00; + return result; +} + +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; + +done: + USB_MODULE_LEDS = 0x00; + return result; +} + +void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall { + ch_command(CH_CMD_SET_USB_ADDR); + CH376_DATA_PORT = device_address; +} 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..c40173a0 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376.h @@ -0,0 +1,176 @@ + +#ifndef __CH376 +#define __CH376 + +#include "ch376inc.h" +#include "delay.h" +#include +#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 + +#define trace_printf(...) + +#define CHECK(fn) \ + { \ + result = fn; \ + if (result != USB_ERR_OK) \ + goto done; \ + } + +#define RETURN_CHECK(fn) \ + { \ + result = fn; \ + goto done; \ + } + +#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; + +extern __sfr __banked CH376_DATA_PORT; +extern __sfr __banked CH376_COMMAND_PORT; + +extern __sfr __banked 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, uint8_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; + CH376_DATA_PORT = retry << 6 | (number_of_retries & 0x1F); +} + +#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/ch376_init.c b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376_init.c new file mode 100644 index 00000000..65cfc43d --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376_init.c @@ -0,0 +1,76 @@ +#include "print.h" +#include "usb-base-drv.h" + +static uint16_t wait_for_state(const uint8_t loop_counter, uint8_t state, const uint8_t desired_state) __sdcccall(1) { + uint16_t r = state; + + for (uint8_t i = 0; i < loop_counter; i++) { + if (state == desired_state) + break; + + if (i & 1) + print_string("\b $"); + else + print_string("\b*$"); + + r = usb_init(state); + state = r & 255; + } + + return r; +} + +extern const char ch376_driver_version[]; + +static void _chnative_init(bool forced) { + uint8_t state = 0; + uint16_t r; + const uint8_t loop_counter = forced ? 40 : 5; + + print_string("\r\nCH376: *$"); + + r = wait_for_state(loop_counter, state, 1); + state = r & 255; + + print_string("\bPRESENT (VER $"); + + r = usb_init(state); + state = r & 255; + if (state != 2) { + print_string("\rCH376: $"); + print_string("VERSION FAILURE\r\n$"); + return; + } + + print_hex(r >> 8); + print_string(ch376_driver_version); + + print_string("USB: *$"); + + r = wait_for_state(loop_counter, state, 3); + state = r & 255; + + if (state == 2) { + print_string("\bDISCONNECTED$"); + return; + } + + print_string("\bCONNECTED$"); + + // enumerate.... + r = usb_init(state); + state = r & 255; + + for (uint8_t i = 0; i < loop_counter; i++) { + if (r >> 8 != 0) + break; + + print_string(".$"); + r = usb_init(state); + state = r & 255; + } +} + +void chnative_init_force(void) { _chnative_init(true); } + +void chnative_init(void) { _chnative_init(false); } 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..ec760bca --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ch376inc.h @@ -0,0 +1,1323 @@ +/* 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 + +/* The disk has not been connected, maybe the disk has been disconnected */ +#define ERR_DISK_DISCON 0x82 + +/*The sector of the disk is too large, only 512 bytes per sector are supported */ +#define ERR_LARGE_SECTOR 0x84 + +/* 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_TYPE_ERROR 0x92 + +/* The disk has not been formatted, or the parameters are wrong and need to be reformatted by WINDOWS with default parameters */ +#define ERR_BPB_ERROR 0xA1 + +/* The disk file is too full, the remaining space is too little or there is no more, and disk defragmentation is required */ +#define ERR_DISK_FULL 0xB1 + +/* 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_FDT_OVER 0xB2 + +/*The file has been closed, it should be reopened if needed */ +#define ERR_FILE_CLOSE 0xB4 + +/* The directory (folder) of the specified path is opened */ +#define ERR_OPEN_DIR 0x41 + +/* The file in the specified path is not found, maybe the file name is wrong */ +#define ERR_MISS_FILE 0x42 + +/* 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_FOUND_NAME 0x43 + +/* A subdirectory(folder) of the specified path is not found, maybe the directory name is wrong */ +#define ERR_MISS_DIR 0xB3 + +/* long file buffer overflow */ +#define ERR_LONG_BUF_OVER 0x48 + +/* The short file name does not have a corresponding long file name or the long file name is wrong */ +#define ERR_LONG_NAME_ERR 0x49 + +/* A short file with the same name already exists, it is recommended to regenerate another short file name */ +#define ERR_NAME_EXIST 0x4A + +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* The following status codes are used for disk and file status in host file + * mode, VAR_DISK_STATUS */ +#ifndef DEF_DISK_UNKNOWN + +/*Not initialized, unknown state */ +#define DEF_DISK_UNKNOWN 0x00 + +/* The disk is not connected or has been disconnected */ +#define DEF_DISK_DISCONN 0x01 + +/* The disk is connected, but it has not been initialized or the disk cannot be recognized */ +#define DEF_DISK_CONNECT 0x02 + +/* The disk has been initialized successfully, but the file system has not been analyzed or the file system does not support */ +#define DEF_DISK_MOUNTED 0x03 + +/* The file system of the disk has been analyzed and can support */ +#define DEF_DISK_READY 0x10 + +/* 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_ROOT 0x12 + +/* A subdirectory (folder) has been opened */ +#define DEF_DISK_OPEN_DIR 0x13 + +/* The file has been opened */ +#define DEF_DISK_OPEN_FILE 0x14 +#endif + +/* ************************************************ + * **************************************************** ***************** */ +/* Common definitions of file system */ + +#ifndef DEF_SECTOR_SIZE +/* The default physical sector size of U disk or SD card */ +#define DEF_SECTOR_SIZE 512 +#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..73d05184 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.h @@ -0,0 +1,62 @@ +#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 { + uint16_t wPortStatus; + uint16_t wPortChange; +} hub_port_status; + +#define PORT_STAT_CONNECTION 0x0001 +#define PORT_STAT_ENABLE 0x0002 +#define PORT_STAT_SUSPEND 0x0004 +#define PORT_STAT_OVERCURRENT 0x0008 +#define PORT_STAT_RESET 0x0010 +#define PORT_STAT_POWER 0x0100 +#define PORT_STAT_LOW_SPEED 0x0200 +#define PORT_STAT_HIGH_SPEED 0x0400 +#define PORT_STAT_TEST 0x0800 +#define PORT_STAT_INDICATOR 0x1000 + +#define PORT_STAT_C_CONNECTION 0x0001 +#define PORT_STAT_C_ENABLE 0x0002 +#define PORT_STAT_C_SUSPEND 0x0004 +#define PORT_STAT_C_OVERCURRENT 0x0008 +#define PORT_STAT_C_RESET 0x0010 + +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/critical-section.c b/Source/HBIOS/ch376-native/source-doc/base-drv/critical-section.c new file mode 100644 index 00000000..37ad03b2 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/critical-section.c @@ -0,0 +1,8 @@ +#include "critical-section.h" +#include + +uint8_t in_critical_usb_section = 0; + +void critical_begin() { in_critical_usb_section++; } + +void critical_end() { in_critical_usb_section--; } diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/critical-section.h b/Source/HBIOS/ch376-native/source-doc/base-drv/critical-section.h new file mode 100644 index 00000000..2ddb3961 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/critical-section.h @@ -0,0 +1,13 @@ +#ifndef __CRITICAL_BLOCKS_H__ +#define __CRITICAL_BLOCKS_H__ + +#include + +extern uint8_t in_critical_usb_section; + +void critical_begin(); +void critical_end(); + +#define is_in_critical_section() (in_critical_usb_section != 0) + +#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..e3be00e4 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c @@ -0,0 +1,106 @@ +/** + * @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 "critical-section.h" +#include "delay.h" +#include "ez80-helpers.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); + +done: + return 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); +done: + return 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); +done: + return result; +} + +usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) { + 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 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..54342438 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.h @@ -0,0 +1,66 @@ +/** + * @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 +} 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); + +#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..69b666f6 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.c @@ -0,0 +1,262 @@ +#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); + +static usb_error adv_to_next_desc(_working *const working, const uint8_t descriptor_type) __sdcccall(1) { + usb_descriptor_t *d; + const uint8_t *buffer_end = working->config.buffer + MAX_CONFIG_SIZE; + + if (working->ptr >= buffer_end) + return USB_ERR_BUFF_TO_LARGE; + + d = (usb_descriptor_t *)working->ptr; + + do { + working->ptr += d->bLength; + + if (working->ptr >= buffer_end) + return USB_ERR_BUFF_TO_LARGE; + + d = (usb_descriptor_t *)working->ptr; + } while (d->bDescriptorType != descriptor_type); + + if (working->ptr + d->bLength >= buffer_end) + return USB_ERR_BUFF_TO_LARGE; + + return USB_ERR_OK; +} + +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 { + uint8_t result; + + if (--working->interface_count == 0) + return USB_ERR_OK; + + CHECK(adv_to_next_desc(working, USB_DESCR_INTERFACE)); + return op_id_class_drv(working); + +done: + return result; +} + +usb_error op_endpoint_next(_working *const working) __sdcccall(1) { + usb_error result; + + if (working->endpoint_count != 0 && --working->endpoint_count > 0) { + CHECK(adv_to_next_desc(working, USB_DESCR_ENDPOINT)); + return op_parse_endpoint(working); + } + + return op_interface_next(working); + +done: + return result; +} + +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_config_storage *)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)); +done: + return result; +} + +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->endpoint_count = interface->bNumEndpoints; + if (working->endpoint_count > 0) + CHECK(adv_to_next_desc(working, USB_DESCR_ENDPOINT)); + 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; + } + } + + return op_parse_endpoint(working); + +done: + return result; +} + +usb_error op_id_class_drv(_working *const working) __sdcccall(1) { + const interface_descriptor *const ptr = (const interface_descriptor *)working->ptr; + + if (ptr->bDescriptorType != USB_DESCR_INTERFACE) + return USB_ERR_FAIL; + + working->usb_device = identify_class_driver(working); + + return op_cap_drv_intf(working); +} + +usb_error op_get_cfg_desc(_working *const working) __sdcccall(1) { + usb_error result; + + const uint8_t max_packet_size = working->desc.bMaxPacketSize0; + + memset(working->config.buffer, 0, MAX_CONFIG_SIZE); + working->ptr = working->config.buffer; + + CHECK(usbtrn_gfull_cfg_desc(working->config_index, working->current_device_address, max_packet_size, MAX_CONFIG_SIZE, + working->config.buffer)); + + CHECK(adv_to_next_desc(working, USB_DESCR_INTERFACE)); + working->interface_count = working->config.desc.bNumInterfaces; + + return op_id_class_drv(working); + +done: + 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; +done: + return result; +} + +usb_error enumerate_all_devices(void) { + _usb_state *const work_area = get_usb_work_area(); + enumeration_state state; + memset(&state, 0, sizeof(enumeration_state)); + + usb_error result = read_all_configs(&state); + + work_area->count_of_detected_usb_devices = state.next_device_address; + +done: + 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..f057a5ce --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.h @@ -0,0 +1,39 @@ +#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; /* Track the count of installed usb devices*/ + uint8_t storage_count; /* Track the count of storage devices (scsi, ufi) */ +} 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..1db8ddb2 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.c @@ -0,0 +1,82 @@ +#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_STAT_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; +done: + return result; +} 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..b2ab79ef --- /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_storage *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..17f81a8a --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.h @@ -0,0 +1,9 @@ +#ifndef __USB_ENUMERATE_STORAGE +#define __USB_ENUMERATE_STORAGE + +#include "dev_transfers.h" +#include "protocol.h" + +extern void parse_endpoints(device_config_storage *const storage_dev, const endpoint_descriptor const *pEndpoint); + +#endif diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/ez80-helpers.h b/Source/HBIOS/ch376-native/source-doc/base-drv/ez80-helpers.h new file mode 100644 index 00000000..02240c95 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/ez80-helpers.h @@ -0,0 +1 @@ +#define debugger() __asm__("PUSH AF \n PUSH BC \n XOR A \n LD B, 7 \n .DB 0x49, 0xD7 \n POP BC \n POP AF") diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/hbios-driver-storage.c b/Source/HBIOS/ch376-native/source-doc/base-drv/hbios-driver-storage.c new file mode 100644 index 00000000..a0b208b6 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/hbios-driver-storage.c @@ -0,0 +1,11 @@ +#include "hbios-driver-storage.h" + +hbios_storage_device_t hbios_usb_storage_devices[MAX_NUMBER_OF_DEVICES] = {{NULL}}; + +uint8_t find_storage_dev(void) { + for (uint8_t i = 0; i < MAX_NUMBER_OF_DEVICES; i++) + if (hbios_usb_storage_devices[i].drive_index == 0) + return i; + + return -1; +} diff --git a/Source/HBIOS/ch376-native/source-doc/base-drv/hbios-driver-storage.h b/Source/HBIOS/ch376-native/source-doc/base-drv/hbios-driver-storage.h new file mode 100644 index 00000000..437bee01 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/hbios-driver-storage.h @@ -0,0 +1,15 @@ +#ifndef __HBIOS_DRIVER_STORAGE +#define __HBIOS_DRIVER_STORAGE + +#include "usb_state.h" + +typedef struct _hbios_storage_device { + uint8_t drive_index; + uint8_t usb_device; +} hbios_storage_device_t; + +extern hbios_storage_device_t hbios_usb_storage_devices[MAX_NUMBER_OF_DEVICES]; + +uint8_t find_storage_dev(void); + +#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..3c4c83e8 --- /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 void *const storage_device) __sdcccall(1); + +#endif 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..df7491b3 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/print.h @@ -0,0 +1,11 @@ +#ifndef __XPRINT +#define __XPRINT + +#include +#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; + +#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..c9bf9476 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.c @@ -0,0 +1,159 @@ +/** + * @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 "ez80-helpers.h" +#include "print.h" + +const setup_packet cmd_get_device_descriptor = {0x80, 6, {0, 1}, {0, 0}, 8}; + +/** + * @brief Issue GET_DESCRIPTOR request to retrieve the device descriptor for usb device at address 0 + * + * @param buffer the buffer to store the device descriptor in + * @return usb_error USB_ERR_OK if all good, otherwise specific error code + */ +usb_error usbtrn_get_descriptor(device_descriptor *const buffer) { + usb_error result; + setup_packet cmd; + cmd = cmd_get_device_descriptor; + cmd.wLength = 8; + + result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8); + + CHECK(result); + + cmd = cmd_get_device_descriptor; + cmd.wLength = 18; + result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0); + + RETURN_CHECK(result); + +done: + return 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)); +done: + return result; +} + +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 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; +done: + return result; +} + +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; + + return usb_control_transfer(&cmd, (uint8_t *)0, device_address, max_packet_size); +} 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..d0ec7091 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/protocol.h @@ -0,0 +1,98 @@ +#ifndef __HW +#define __HW + +#include "ch376.h" +#include "dev_transfers.h" +#include "transfers.h" +#include + +typedef struct { + uint8_t bLength; + uint8_t bDescriptorType; +} usb_descriptor_t; + +#define USB_DESCR_DEVICE 1 +#define USB_DESCR_CONFIGURATION 2 +#define USB_DESCR_STRING 3 +#define USB_DESCR_INTERFACE 4 +#define USB_DESCR_ENDPOINT 5 +#define USB_DESCR_DEV_QUALIFIER 6 +#define USB_DESCR_OTHER_SPEED 7 +#define USB_DESCR_HID 33 +#define USB_DESCR_HID_REPORT 34 +#define USB_DESCR_HID_PHYSICAL_DESC 35 + +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..a5e1e9c1 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/transfers.c @@ -0,0 +1,152 @@ +/** + * @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 "critical-section.h" +#include "delay.h" +#include "ez80-helpers.h" +#include "print.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 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; + + critical_begin(); + + ch_set_usb_address(device_address); + + ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet)); + ch_issue_token_setup(); + result = ch_short_wait_int_and_get_status(); + CHECK(result); + + 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; + 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) { + result = USB_ERR_OK; + goto done; + } + + RETURN_CHECK(result); + } + + ch_issue_token_in_ep0(); + result = ch_long_wait_int_and_get_status(); + + RETURN_CHECK(result); + +done: + critical_end(); + return result; +} + +/** + * @brief Perform a USB data in on the specified 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) { + usb_error result; + critical_begin(); + + ch_set_usb_address(device_address); + + result = ch_data_in_transfer(buffer, buffer_size, endpoint); + + critical_end(); + + return result; +} + +/** + * @brief Perform a USB data in on the specified 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) { + usb_error result; + + critical_begin(); + + ch_set_usb_address(device_address); + + result = ch_data_in_transfer_n(buffer, buffer_size, endpoint); // does ch_data_in_transfer_n size need to be signed? + + critical_end(); + + return result; +} + +/** + * @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) { + usb_error result; + critical_begin(); + + ch_set_usb_address(device_address); + + result = ch_data_out_transfer(buffer, buffer_size, endpoint); + + critical_end(); + + return result; +} 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..b809de1d --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.c @@ -0,0 +1,76 @@ +#include "usb-base-drv.h" +#include "ch376.h" +#include "enumerate.h" +#include "work-area.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$" + +uint16_t usb_init(uint8_t state) __z88dk_fastcall { + uint8_t r; + + USB_MODULE_LEDS = 0x03; + + if (state == 0) { + ch_cmd_reset_all(); + delay_medium(); + + if (!ch_probe()) { + USB_MODULE_LEDS = 0x00; + return 0xFF00; + } + USB_MODULE_LEDS = 0x00; + return 1; + } + + if (state == 1) { + r = ch_cmd_get_ic_version(); + + USB_MODULE_LEDS = 0x00; + return (uint16_t)r << 8 | 2; + } + + if (state == 2) { + usb_host_bus_reset(); + + r = ch_very_short_wait_int_and_get_status(); + + if (r != USB_INT_CONNECT) { + USB_MODULE_LEDS = 0x00; + return 2; + } + + return 3; + } + + memset(get_usb_work_area(), 0, sizeof(_usb_state)); + if (state != 2) { + usb_host_bus_reset(); + delay_medium(); + } + enumerate_all_devices(); + USB_MODULE_LEDS = 0x00; + return (uint16_t)count_of_devices() << 8 | 4; +} + +usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba) { + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + dev->current_lba = lba; + return USB_ERR_OK; +} 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..a2ab3b1a --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.h @@ -0,0 +1,14 @@ +#ifndef __USB_BASE_DRV +#define __USB_BASE_DRV + +#include "dev_transfers.h" +#include "usb_state.h" +#include + +extern uint16_t usb_init(uint8_t state) __z88dk_fastcall; + +// ufi_seek is an alias for scsi_seek +extern usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba); +extern usb_error ufi_seek(const uint16_t dev_index, const uint32_t lba); + +#endif 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..28c2f9b0 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.c @@ -0,0 +1,97 @@ +#include "usb_state.h" +#include "ch376.h" +#include "work-area.h" + +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); + +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 +uint8_t count_of_devices(void) __sdcccall(1) { + _usb_state *const p = get_usb_work_area(); + + uint8_t count = 0; + + const device_config *p_config = first_device_config(p); + while (p_config) { + const uint8_t type = p_config->type; + + if (type != USB_IS_HUB && type) + count++; + ; + + p_config = next_device_config(p, p_config); + }; + + return count; +} + +// 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; +} + +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_NOT_SUPPORTED) { + if (counter == device_index) + return p; + counter++; + } + } + + return NULL; // is not a usb device +} + +usb_device_type usb_get_device_type(const uint16_t dev_index) { + const device_config *dev = get_usb_device_config(dev_index); + + if (dev == NULL) + return -1; + + return dev->type; +} 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..c360f788 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.h @@ -0,0 +1,26 @@ +#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 uint8_t count_of_devices(void) __sdcccall(1); +extern device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1); + +extern usb_device_type usb_get_device_type(const uint16_t dev_index); + +#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/convert-for-uz80as.sh b/Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh new file mode 100755 index 00000000..5bcd0523 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# 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+or\s+a,\s*\((hl)\)/\tor\t\(\1\)/g' \ + -e 's/\s+sub\s+a,\s*\((hl)\)/\tsub\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+and\s+a,\s*a/\tand\ta/g' \ + -e 's/\s+and\s+a,\s*(b|c|d|e|h|l|iyl|iyh|ixl|ixh)/\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/keyboard/class_hid.c b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid.c new file mode 100644 index 00000000..e8c0a7b3 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid.c @@ -0,0 +1,24 @@ +#include "class_hid.h" +#include + +const setup_packet cmd_hid_set = {0x21, HID_SET_PROTOCOL, {0, 0}, {0, 0}, 0}; + +usb_error hid_set_protocol(const device_config_keyboard *const dev, const uint8_t protocol) __sdcccall(1) { + setup_packet cmd; + cmd = cmd_hid_set; + + cmd.bRequest = HID_SET_PROTOCOL; + cmd.bValue[0] = protocol; + + return usb_control_transfer(&cmd, NULL, dev->address, dev->max_packet_size); +} + +usb_error hid_set_idle(const device_config_keyboard *const dev, const uint8_t duration) __sdcccall(1) { + setup_packet cmd; + cmd = cmd_hid_set; + + cmd.bRequest = HID_SET_IDLE; + cmd.bValue[0] = duration; + + return usb_control_transfer(&cmd, NULL, dev->address, dev->max_packet_size); +} diff --git a/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid.h b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid.h new file mode 100644 index 00000000..d3771b79 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid.h @@ -0,0 +1,21 @@ +#ifndef __CLASS_HID_H__ +#define __CLASS_HID_H__ + +#include "ch376.h" +#include "protocol.h" + +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +#define HID_BOOT_PROTOCOL 0x00 +#define HID_REPORT_PROTOCOL 0x01 + +extern usb_error hid_set_protocol(const device_config_keyboard *const dev, const uint8_t protocol) __sdcccall(1); +extern usb_error hid_set_idle(const device_config_keyboard *const dev, const uint8_t duration) __sdcccall(1); +extern usb_error hid_get_input_report(const device_config_keyboard *const dev, uint8_t const *report) __sdcccall(1); + +#endif diff --git a/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid_keyboard.c b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid_keyboard.c new file mode 100644 index 00000000..a047f36a --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid_keyboard.c @@ -0,0 +1,377 @@ +#include "class_hid_keyboard.h" + +#define ESC 0x1B +/** + * scan codes sourced from https://deskthority.net/wiki/Scancode + * + */ +char scancodes_shift_table[128] = { + 0x00, /*Reserved*/ + 0x00, /*Reserved*/ + 0x00, /*Reserved*/ + 0x00, /*Reserved*/ + + /* 0x04 */ + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + 'G', + 'H', + + /* 0x0C */ + 'I', + 'J', + 'K', + 'L', + 'M', + 'N', + 'O', + 'P', + + /* 0X14 */ + 'Q', + 'R', + 'S', + 'T', + 'U', + 'V', + 'W', + 'X', + + /* 0X1C */ + 'Y', + 'Z', + '!', + '@', + '#', + '$', + '%', + '^', + + /* 0x24 */ + '&', + '*', + '(', + ')', + '\r', + ESC, + '\b', + '\t', + + /* 0x2C */ + ' ', + '_', + '+', + '{', + '}', + '|', + '~', + ':', + + /* 0x34 */ + '"', + '~', + '<', + '>', + '?', + 0x00 /*CAPSLOCK*/, + 0x00 /* F1 */, + 0x00 /* F2 */, + + /* 0x3C */ + 0x00 /* F3 */, + 0x00 /* F4 */, + 0x00 /* F5 */, + 0x00 /* F6 */, + 0x00 /* F7 */, + 0x00 /* F8 */, + 0x00 /* F9 */, + 0x00 /* F10 */, + + /* 0x44 */ + 0x00 /* F11 */, + 0x00 /* F12 */, + 0x00 /* PRINTSCREEN */, + 0x00 /* SCROLLLOCK */, + 0x00 /* PAUSE */, + 0x00 /* INSERT */, + 0x00 /* HOME */, + 0x00 /* PAGEUP */, + + /* 0x4C */ + 0x00 /* DELETE */, + 0x00 /* END */, + 0x00 /* PAGEDOWN */, + 0x00 /* RIGHT */, + 0x00 /* LEFT */, + 0x00 /* DOWN */, + 0x00 /* UP */, + 0x00 /* NUMLOCK */, + + /* 0x54 */ + '/' /* KP / */, + '*' /* KP * */, + '-' /* KP - */, + '+' /* KP + */, + '\r' /* KP ENTER */, + '1' /* KP 1 */, + '2' /* KP 2 */, + '3' /* KP 3 */, + + /* 0x5C */ + '4' /* KP 4 */, + '5' /* KP 5 */, + '6' /* KP 6 */, + '7' /* KP 7 */, + '8' /* KP 8 */, + '9' /* KP 9 */, + '0' /* KP 0 */, + '.' /* KP . */, + + /* 0x64 */ + '\\', + 0x00 /* MENU */, + 0x00 /* POWER */, + '=' /* KP = */, + 0x00 /* F13 */, + 0x00 /* F14 */, + 0x00 /* F15 */, + 0x00 /* F16 */, + + /* 0x6C */ + 0x00 /* F17 */, + 0x00 /* F18 */, + 0x00 /* F19 */, + 0x00 /* F20 */, + 0x00 /* F21 */, + 0x00 /* F22 */, + 0x00 /* F23 */, + 0x00 /* F24 */, + + /* 0x74 */ + 0x00 /* EXECUTE */, + 0x00 /* HELP */, + 0x00 /* MENU */, + 0x00 /* SELECT */, + 0x00 /* STOP */, + 0x00 /* AGAIN */, + 0x00 /* UNDO */, + 0x00 /* CUT */, + + /* 0x7C */ + 0x00 /* COPY */, + 0x00 /* PASTE */, + 0x00 /* FIND */, + 0x00 /* MUTE */, +}; + +char scancodes_table[128] = { + 0x00, /*Reserved*/ + 0x00, /*Reserved*/ + 0x00, /*Reserved*/ + 0x00, /*Reserved*/ + + /* 0x04 */ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + + /* 0x0C */ + 'i', + 'j', + 'k', + 'l', + 'm', + 'n', + 'o', + 'p', + + /* 0x14 */ + 'q', + 'r', + 's', + 't', + 'u', + 'v', + 'w', + 'x', + + /* 0x1C */ + 'y', + 'z', + '1', + '2', + '3', + '4', + '5', + '6', + + /* 0x24 */ + '7', + '8', + '9', + '0', + '\r', + ESC, + '\b', + '\t', + + /* 0x2C */ + ' ', + '-', + '=', + '[', + ']', + '\\', + '#', + ';', + + /* 0x34 */ + '\'', + '`', + ',', + '.', + '/', + + /* 0x39 */ + 0x00 /*CAPSLOCK*/, + 0x00 /* F1 */, + 0x00 /* F2 */, + + /* 0x3C */ + 0x00 /* F3 */, + 0x00 /* F4 */, + 0x00 /* F5 */, + 0x00 /* F6 */, + 0x00 /* F7 */, + 0x00 /* F8 */, + 0x00 /* F9 */, + 0x00 /* F10 */, + + /* 0x44 */ + 0x00 /* F11 */, + 0x00 /* F12 */, + 0x00 /* PRINTSCREEN */, + 0x00 /* SCROLLLOCK */, + 0x00 /* PAUSE */, + 0x00 /* INSERT */, + 0x00 /* HOME */, + 0x00 /* PAGEUP */, + + /* 0x4C */ + 0x00 /* DELETE */, + 0x00 /* END */, + 0x00 /* PAGEDOWN */, + 0x00 /* RIGHT */, + 0x00 /* LEFT */, + 0x00 /* DOWN */, + 0x00 /* UP */, + 0x00 /* NUMLOCK */, + + /* 0x54 */ + '/' /* KP / */, + '*' /* KP * */, + '-' /* KP - */, + '+' /* KP + */, + '\r' /* KP ENTER */, + '1' /* KP 1 */, + '2' /* KP 2 */, + '3' /* KP 3 */, + + /* 0x5C */ + '4' /* KP 4 */, + '5' /* KP 5 */, + '6' /* KP 6 */, + '7' /* KP 7 */, + '8' /* KP 8 */, + '9' /* KP 9 */, + '0' /* KP 0 */, + '.' /* KP . */, + + /* 0x64 */ + '\\', + 0x00 /* MENU */, + 0x00 /* POWER */, + '=' /* KP = */, + 0x00 /* F13 */, + 0x00 /* F14 */, + 0x00 /* F15 */, + 0x00 /* F16 */, + + /* 0x6C */ + 0x00 /* F17 */, + 0x00 /* F18 */, + 0x00 /* F19 */, + 0x00 /* F20 */, + 0x00 /* F21 */, + 0x00 /* F22 */, + 0x00 /* F23 */, + 0x00 /* F24 */, + + /* 0x74 */ + 0x00 /* EXECUTE */, + 0x00 /* HELP */, + 0x00 /* MENU */, + 0x00 /* SELECT */, + 0x00 /* STOP */, + 0x00 /* AGAIN */, + 0x00 /* UNDO */, + 0x00 /* CUT */, + + /* 0x7C */ + 0x00 /* COPY */, + 0x00 /* PASTE */, + 0x00 /* FIND */, + 0x00 /* MUTE */, +}; + +static char char_with_caps_lock(const char c, const bool caps_lock_engaged) __sdcccall(1) { + if (!caps_lock_engaged) + return c; + + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + + if (c >= 'a' && c <= 'z') + return c - 'a' + 'A'; + + return c; +} + +char scancode_to_char(const uint8_t modifier_keys, const uint8_t code, const bool caps_lock_engaged) __sdcccall(1) { + if ((modifier_keys & (KEY_MOD_LCTRL | KEY_MOD_RCTRL))) { + if (code >= 4 && code <= 0x1d) + return code - 3; + + if (code == 0x1F || code == 0x2C) //@ or SPACE + return 0; + + if (code == 0x2F) // [ + return 27; + + if (code == 0x31) // back slash + return 28; + + if (code == 0x30) // ] + return 29; + + if (code == 0x23) //^ + return 30; + + if (code == 0x2D) //_ + return 31; + } + + if (modifier_keys & (KEY_MOD_LSHIFT | KEY_MOD_RSHIFT)) + return char_with_caps_lock(scancodes_shift_table[code], caps_lock_engaged); + + return char_with_caps_lock(scancodes_table[code], caps_lock_engaged); +} diff --git a/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid_keyboard.h b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid_keyboard.h new file mode 100644 index 00000000..6243c437 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/class_hid_keyboard.h @@ -0,0 +1,27 @@ +#ifndef __CLASS_HID_KEYBOARD_H__ +#define __CLASS_HID_KEYBOARD_H__ + +#include +#include + +typedef struct { + uint8_t bModifierKeys; + uint8_t bReserved; + uint8_t keyCode[6]; +} keyboard_report_t; + +#define KEY_MOD_LCTRL 0x01 +#define KEY_MOD_LSHIFT 0x02 +#define KEY_MOD_LALT 0x04 +#define KEY_MOD_LMETA 0x08 +#define KEY_MOD_RCTRL 0x10 +#define KEY_MOD_RSHIFT 0x20 +#define KEY_MOD_RALT 0x40 +#define KEY_MOD_RMETA 0x80 + +#define KEY_CODE_CAPS_LOCK 0x39 + +extern char scancodes_table[128]; +extern char scancode_to_char(const uint8_t modifier_keys, const uint8_t code, const bool caps_lock_engaged) __sdcccall(1); + +#endif diff --git a/Source/HBIOS/ch376-native/source-doc/keyboard/kyb-init.c b/Source/HBIOS/ch376-native/source-doc/keyboard/kyb-init.c new file mode 100644 index 00000000..e33d6f71 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/kyb-init.c @@ -0,0 +1,25 @@ +#include "kyb_driver.h" +#include +#include +#include + +uint8_t keyboard_init(void) __sdcccall(1) { + uint8_t index = 1; + + do { + usb_device_type t = usb_get_device_type(index); + + if (t == USB_IS_KEYBOARD) { + print_string("\r\nUSB: KEYBOARD @ $"); + print_uint16(index); + print_string(" $"); + + usb_kyb_init(index); + return 1; + } + } while (++index != MAX_NUMBER_OF_DEVICES + 1); + + print_string("\r\nUSB: KEYBOARD: NOT FOUND$"); + + return 0; +} diff --git a/Source/HBIOS/ch376-native/source-doc/keyboard/kyb_driver.c b/Source/HBIOS/ch376-native/source-doc/keyboard/kyb_driver.c new file mode 100644 index 00000000..17d5a015 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/kyb_driver.c @@ -0,0 +1,136 @@ +#include "kyb_driver.h" +#include "class_hid.h" +#include "class_hid_keyboard.h" +#include +#include +#include +#include + +#define KEYBOARD_BUFFER_SIZE 8 +#define KEYBOARD_BUFFER_SIZE_MASK 7 + +static bool caps_lock_engaged = true; +static device_config_keyboard *keyboard_config = 0; + +static uint8_t buffer[KEYBOARD_BUFFER_SIZE] = {0}; +static uint8_t write_index = 0; +static uint8_t read_index = 0; + +static keyboard_report_t report = {0}; +static keyboard_report_t previous = {0}; + +#define DI __asm__("DI") +#define EI __asm__("EI") + +static uint8_t report_diff() __sdcccall(1) { + uint8_t *a = (uint8_t *)&report; + uint8_t *b = (uint8_t *)&previous; + + uint8_t i = sizeof(report); + do { + if (*a++ != *b++) + return true; + } while (--i != 0); + + return false; +} + +static void keyboard_buf_put(const uint8_t indx) __sdcccall(1) { + const uint8_t key_code = report.keyCode[indx]; + if (key_code >= 0x80 || key_code == 0) + return; // ignore ??? + + // if already reported, just skip it + if (previous.keyCode[indx] == key_code) + return; + + if (key_code == KEY_CODE_CAPS_LOCK) { + caps_lock_engaged = !caps_lock_engaged; + return; + } + + const unsigned char c = scancode_to_char(report.bModifierKeys, key_code, caps_lock_engaged); + + if (c == 0) + return; + + uint8_t next_write_index = (write_index + 1) & KEYBOARD_BUFFER_SIZE_MASK; + if (next_write_index != read_index) { // Check if buffer is not full + buffer[write_index] = c; + write_index = next_write_index; + } +} + +uint8_t usb_kyb_status() __sdcccall(1) { + DI; + + uint8_t size; + + if (write_index >= read_index) + size = write_index - read_index; + else + size = KEYBOARD_BUFFER_SIZE - read_index + write_index; + + EI; + return size; +} + +uint16_t usb_kyb_read() { + if (write_index == read_index) // Check if buffer is empty + return 0xFF00; // H = -1, L = 0 + + DI; + const uint8_t c = buffer[read_index]; + read_index = (read_index + 1) & KEYBOARD_BUFFER_SIZE_MASK; + EI; + + /* H = 0, L = ascii char */ + return c; +} + +uint8_t usb_kyb_flush() __sdcccall(1) { + DI; + write_index = read_index = 0; + + uint8_t i = sizeof(previous); + uint8_t *a = (uint8_t *)previous; + uint8_t *b = (uint8_t *)report; + do { + *a++ = 0; + *b++ = 0; + } while (--i != 0); + + EI; + + return 0; +} + +void usb_kyb_tick(void) { + usb_error result; + + if (is_in_critical_section()) + return; + + ch_configure_nak_retry_disable(); + result = usbdev_dat_in_trnsfer_0((device_config *)keyboard_config, (uint8_t *)&report, 8); + ch_configure_nak_retry_3s(); + if (result == 0) { + if (report_diff()) { + uint8_t i = 6; + do { + keyboard_buf_put(i - 1); + } while (--i != 0); + previous = report; + } + } +} + +void usb_kyb_init(const uint8_t dev_index) __sdcccall(1) { + keyboard_config = (device_config_keyboard *)get_usb_device_config(dev_index); + + if (keyboard_config == NULL) + return; + + hid_set_protocol(keyboard_config, 1); + hid_set_idle(keyboard_config, 0x80); +} diff --git a/Source/HBIOS/ch376-native/source-doc/keyboard/kyb_driver.h b/Source/HBIOS/ch376-native/source-doc/keyboard/kyb_driver.h new file mode 100644 index 00000000..c9a744f7 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/keyboard/kyb_driver.h @@ -0,0 +1,12 @@ +#ifndef __KYB_DRIVER__ +#define __KYB_DRIVER__ + +#include +#include + +extern void usb_kyb_init(const uint8_t dev_index) __sdcccall(1); +extern uint8_t usb_kyb_flush() __sdcccall(1); +extern uint8_t usb_kyb_status() __sdcccall(1); +extern uint16_t usb_kyb_read(); + +#endif 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..755681d3 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.c @@ -0,0 +1,77 @@ +#include "class_scsi.h" +#include +#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; + +usb_error do_scsi_cmd(device_config_storage *const dev, + _scsi_command_block_wrapper *const cbw, + void *const send_receive_buffer, + const bool send) { + + usb_error result; + _scsi_command_status_wrapper csw = {{{0}}}; + + cbw->dCBWTag[0] = next_tag++; + + if (!send) + cbw->bmCBWFlags = 0x80; + + critical_begin(); + + 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]) + result = USB_ERR_FAIL; + else + result = USB_ERR_OK; + +done: + critical_end(); + return result; +} + +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); +} + +const _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); +} 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..2c5d6fe9 --- /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 _scsi_command_block_wrapper scsi_command_block_wrapper; + +extern usb_error do_scsi_cmd(device_config_storage *const dev, + _scsi_command_block_wrapper *const cbw, + void *const send_receive_buffer, + const bool send); + +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); + +#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..481e8262 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi-init.c @@ -0,0 +1,30 @@ +#include "hbios-driver-storage.h" +#include "scsi_driver.h" +#include +#include +#include + +extern const uint16_t const ch_scsi_fntbl[]; + +void chscsi_init(void) { + uint8_t index = 1; + do { + usb_device_type t = usb_get_device_type(index); + + if (t == USB_IS_MASS_STORAGE) { + const uint8_t dev_index = find_storage_dev(); // index == -1 (no more left) should never happen + + hbios_usb_storage_devices[dev_index].drive_index = dev_index + 1; + hbios_usb_storage_devices[dev_index].usb_device = index; + + print_string("\r\nUSB: MASS STORAGE @ $"); + print_uint16(index); + print_string(":$"); + print_uint16(dev_index); + print_string(" $"); + usb_scsi_init(index); + dio_add_entry(ch_scsi_fntbl, &hbios_usb_storage_devices[dev_index]); + } + + } while (++index != MAX_NUMBER_OF_DEVICES + 1); +} diff --git a/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi_driver.c b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi_driver.c new file mode 100644 index 00000000..4151f853 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi_driver.c @@ -0,0 +1,123 @@ +#include "scsi_driver.h" +#include "class_scsi.h" +#include +#include +#include +#include + +usb_error usb_scsi_init(const uint16_t dev_index) { + usb_error result; + + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + scsi_sense_result response; + uint8_t counter = 3; + + critical_begin(); + while ((result = scsi_test(dev)) && --counter > 0) + scsi_request_sense(dev, &response); + critical_end(); + + return result; +} + +_scsi_read_capacity scsi_packet_read_capacity = {0x25, 0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0}}; + +usb_error usb_scsi_read_capacity(const uint16_t dev_index, scsi_read_capacity_result *cap_result) { + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + cbw_scsi_read_capacity cbw_scsi; + cbw_scsi.cbw = scsi_command_block_wrapper; + cbw_scsi.read_capacity = scsi_packet_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 usb_scsi_inquiry(const uint16_t dev_index, scsi_inquiry_result *inq_result) { +// device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + +// 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); +// } + +static cbw_scsi_read_write cbw = {{{0}}}; + +usb_error usb_scsi_read(const uint16_t dev_index, uint8_t *const buffer) { + usb_error result; + + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + 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 usb_scsi_write(const uint16_t dev_index, uint8_t *const buffer) { + usb_error result; + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + 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/scsi_driver.h b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi_driver.h new file mode 100644 index 00000000..92e57912 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi_driver.h @@ -0,0 +1,14 @@ +#ifndef __SCSI_DRIVER__ +#define __SCSI_DRIVER__ + +#include "class_scsi.h" +#include +#include + +extern usb_error usb_scsi_init(const uint16_t dev_index); +extern usb_error usb_scsi_read_capacity(const uint16_t dev_index, scsi_read_capacity_result *result); +extern usb_error usb_scsi_read(const uint16_t dev_index, uint8_t *const buffer); +extern usb_error usb_scsi_write(const uint16_t dev_index, uint8_t *const buffer); +extern usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba); + +#endif 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..5dc980e9 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.c @@ -0,0 +1,179 @@ +#include "class_ufi.h" +#include +#include +#include +#include +#include + +const ufi_request_sense_command _ufi_cmd_request_sense = {0x03, 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, 12}, {0, 0, 0}}; +const ufi_inquiry_command _ufi_cmd_inquiry = {0x12, 0, 0, 0, 0x24, {0, 0, 0, 0, 0, 0, 0}}; +const ufi_format_command _ufi_cmd_format = {0x04, 7 | 1 << 4, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0, 0}}; +const ufi_send_diagnostic_command _ufi_cmd_send_diagnostic = {0x1D, 1 << 2, {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 & 15) == 0) || timeout_counter-- == 0) + break; + + delay_medium(); + + } while (true); + + return result | (sense.sense_key & 15); +} + +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); +done: + return 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); +done: + return 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); +done: + return 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); +done: + return 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, + 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); +done: + return 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.status = + FMT_DEFECT_STATUS_FOV | FMT_DEFECT_STATUS_DCRT | FMT_DEFECT_STATUS_SINGLE_TRACK | (side & 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); +done: + return result; +} + +usb_error ufi_send_diagnostics(device_config *const storage_device) { + ufi_send_diagnostic_command ufi_cmd_send_diagnostic; + + ufi_cmd_send_diagnostic = _ufi_cmd_send_diagnostic; + + return usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_send_diagnostic, true, 0, NULL, NULL); +} + +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..58df1c6e --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.h @@ -0,0 +1,186 @@ +#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 lun; // in top 3 bits + 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_codex; // UFI_DESCRIPTOR_CODE + 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 lun_and_evpd; + 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 lun; // top 3 bits + 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; // lower 4 bits + 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; // lower 5 bits + + // Removable Media Bit: this shall be set to one to indicate removable media. + uint8_t removable_media; // top bit + + // ANSI Version: must contain a zero to comply with this version of the Specification. + // ISO/ECMA: These fields shall be zero for the UFI device. + uint8_t version; + + // Response Data Format: a value of 01h shall be used for UFI device + uint8_t response_data_format; // lower 4 bits + + // 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*/ + uint8_t byte_1; /*1*/ + /* [7:5] lun, [4] dpo, [3] fua, [0]rel_adr*/ + 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; + /* [7] FOV, [6] Extend, [5] DCRT, [4] SingleTrack, [1] Immediate, [0] Side*/ + uint8_t status; + 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; + +#define FMT_DEFECT_STATUS_FOV 0x80 +#define FMT_DEFECT_STATUS_EXTEND 0x40 +#define FMT_DEFECT_STATUS_DCRT 0x20 +#define FMT_DEFECT_STATUS_SINGLE_TRACK 0x10 +#define FMT_DEFECT_STATUS_IMMEDIATE 0x02 +#define FMT_DEFECT_STATUS_SIDE 0x01 + +typedef struct { + uint8_t operation_code; /* 0x04 */ + /* [7:5] lun, [4]format_data, [3]cmp_list, [2:0] defect_list_format*/ + uint8_t status; + 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*/ + /* [7:5] lun, [4] pf, [2] self test, [1] def of l [0] unit of l*/ + uint8_t status; + 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); + +extern usb_error ufi_seek(const uint16_t dev_index, const uint32_t lba); + +#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..4fb47fc0 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi-init.c @@ -0,0 +1,29 @@ +#include "hbios-driver-storage.h" +#include +#include +#include + +extern const uint16_t const ch_ufi_fntbl[]; + +void chufi_init(void) { + uint8_t index = 1; + + do { + usb_device_type t = usb_get_device_type(index); + + if (t == USB_IS_FLOPPY) { + const uint8_t dev_index = find_storage_dev(); // dev_index == -1 (no more left) should never happen + + hbios_usb_storage_devices[dev_index].drive_index = dev_index + 1; + hbios_usb_storage_devices[dev_index].usb_device = index; + + print_string("\r\nUSB: FLOPPY @ $"); + print_uint16(index); + print_string(":$"); + print_uint16(dev_index); + print_string(" $"); + dio_add_entry(ch_ufi_fntbl, &hbios_usb_storage_devices[dev_index]); + } + + } while (++index != MAX_NUMBER_OF_DEVICES + 1); +} diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi_driver.c b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi_driver.c new file mode 100644 index 00000000..65a7d904 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi_driver.c @@ -0,0 +1,85 @@ +#include "ufi_driver.h" +#include "class_ufi.h" +#include +#include + +uint32_t usb_ufi_get_cap(const uint16_t dev_index) { + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + 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; + + return convert_from_msb_first(response.descriptors[0].number_of_blocks); +} + +usb_error usb_ufi_read(const uint16_t dev_index, uint8_t *const buffer) { + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + 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 & 15; + + if (sense_key != 0) + return -1; + + return USB_ERR_OK; +} + +usb_error usb_ufi_write(const uint16_t dev_index, uint8_t *const buffer) { + device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + + if (wait_for_device_ready((device_config *)dev, 20) != 0) + return -1; // Not READY! + + ufi_interrupt_status sense_codes; + + memset(&sense_codes, 0, sizeof(sense_codes)); + if ((ufi_read_write_sector((device_config *)dev, true, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes)) != USB_ERR_OK) { + return -1; + } + + ufi_request_sense_response response; + memset(&response, 0, sizeof(response)); + + if ((ufi_request_sense((device_config *)dev, &response)) != USB_ERR_OK) { + return -1; + } + + const uint8_t asc = response.asc; + const uint8_t ascq = response.ascq; + const uint8_t sense_key = response.sense_key & 15; + + if (sense_key != 0) + return -1; + + return USB_ERR_OK; +} diff --git a/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi_driver.h b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi_driver.h new file mode 100644 index 00000000..4c847bee --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi_driver.h @@ -0,0 +1,11 @@ +#ifndef __UFI_DRIVER__ +#define __UFI_DRIVER__ + +#include +#include + +extern uint32_t usb_ufi_get_cap(const uint16_t dev_index); +extern usb_error usb_ufi_read(const uint16_t dev_index, uint8_t *const buffer); +extern usb_error usb_ufi_write(const uint16_t dev_index, uint8_t *const buffer); + +#endif 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..8c2763e5 --- /dev/null +++ b/Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.c @@ -0,0 +1,69 @@ +#include "usb_cbi.h" +#include "dev_transfers.h" +#include "protocol.h" +#include +#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; + + critical_begin(); + + 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); + + result = USB_ERR_STALL; + goto done; + } + + if (result != USB_ERR_OK) { + TRACE_USB_ERROR(result); + goto done; + } + + if (send) { + result = usbdev_blk_out_trnsfer(storage_device, buffer, buffer_size); + + if (result != USB_ERR_OK) { + TRACE_USB_ERROR(result); + goto done; + } + } else { + result = usbdev_dat_in_trnsfer(storage_device, buffer, buffer_size, ENDPOINT_BULK_IN); + + if (result != USB_ERR_OK) { + TRACE_USB_ERROR(result); + goto done; + } + } + + 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); + // goto done; + } + } + +done: + critical_end(); + + return result; +} 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..bcc735b4 --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv.s @@ -0,0 +1,11 @@ +; Generated File -- not to be modify directly +#IF (!CHNATIVEEZ80) +#include "ch376-native/ufi-drv/class_ufi.c.s" +#ENDIF +#IF (!CHNATIVEEZ80) +#include "ch376-native/ufi-drv/ufi_driver.c.s" +#ENDIF +#include "ch376-native/ufi-drv/ufi-init.c.s" +#IF (!CHNATIVEEZ80) +#include "ch376-native/ufi-drv/usb_cbi.c.s" +#ENDIF diff --git a/Source/HBIOS/ch376-native/ufi-drv/.gitignore b/Source/HBIOS/ch376-native/ufi-drv/.gitignore new file mode 100644 index 00000000..f4cb8488 --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/.gitignore @@ -0,0 +1 @@ +*.asm 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..560fd123 --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/class_ufi.c.s @@ -0,0 +1,666 @@ +; +; 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.5.0 #15248 (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/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)); + ld hl,0 + add hl, sp + ld b,0x09 +l_wait_for_device_ready_00132: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_wait_for_device_ready_00132 +;source-doc/ufi-drv/class_ufi.c:20: result = ufi_test_unit_ready(storage_device, &sense); + push bc + 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 & 15) == 0) || timeout_counter-- == 0) + or a + jr NZ,l_wait_for_device_ready_00104 + ld a,(ix-16) + 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 & 15); + ld a,(ix-16) + 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 + ld b,0x06 +l_ufi_test_unit_ready_00104: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_ufi_test_unit_ready_00104 +;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 + ex de, hl + ld bc,0x000c + ld hl,__ufi_cmd_request_sense + ldir +;source-doc/ufi-drv/class_ufi.c:43: (uint8_t *)response, NULL); + ld c,(ix+6) + ld b,(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 bc + ld l,0x12 + push hl + 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 +;source-doc/ufi-drv/class_ufi.c:46: return result; +;source-doc/ufi-drv/class_ufi.c:47: } + ld sp,ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:49: 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:51: ufi_cmd_request_sense = _ufi_cmd_request_sense; + ld hl,0 + add hl, sp + ex de, hl + ld bc,0x000c + ld hl,__ufi_cmd_request_sense + ldir +;source-doc/ufi-drv/class_ufi.c:53: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response), + ld c,(ix+6) + ld b,(ix+7) + ld hl,0x0000 + push hl + push bc + ld l,0x12 + 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 +;source-doc/ufi-drv/class_ufi.c:58: return result; +;source-doc/ufi-drv/class_ufi.c:59: } + ld sp,ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:61: 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:65: 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:66: 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 + pop af + pop af + pop af + pop af + pop af + inc sp + ld a, l + pop bc + ld l, a +;source-doc/ufi-drv/class_ufi.c:69: CHECK(result); + or a + jr NZ,l_ufi_read_frmt_caps_00103 +;source-doc/ufi-drv/class_ufi.c:71: const uint8_t available_length = response->capacity_list_length; + ld l,(ix+6) + ld h,(ix+7) + inc hl + inc hl + inc hl + ld a, (hl) +;source-doc/ufi-drv/class_ufi.c:73: const uint8_t max_length = + cp 0x25 + jr C,l_ufi_read_frmt_caps_00106 + ld e,0x24 + jr l_ufi_read_frmt_caps_00107 +l_ufi_read_frmt_caps_00106: + ld e, a +l_ufi_read_frmt_caps_00107: +;source-doc/ufi-drv/class_ufi.c:77: memcpy(&cmd, &ufi_cmd_read_format_capacities, sizeof(cmd)); + push de + push bc + ld hl,16 + add hl, sp + ex de, hl + ld hl,4 + add hl, sp + ld bc,0x000c + ldir + pop bc + pop de +;source-doc/ufi-drv/class_ufi.c:78: cmd.allocation_length[1] = max_length; + ld (ix-4),e +;source-doc/ufi-drv/class_ufi.c:80: 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 + pop af + pop af + pop af + pop af + pop af + inc sp +;source-doc/ufi-drv/class_ufi.c:84: done: +l_ufi_read_frmt_caps_00103: +;source-doc/ufi-drv/class_ufi.c:85: return result; +;source-doc/ufi-drv/class_ufi.c:86: } + ld sp, ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:88: 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:90: ufi_cmd_inquiry = _ufi_cmd_inquiry; + ld hl,0 + add hl, sp + ex de, hl + ld bc,0x000c + ld hl,__ufi_cmd_inquiry + ldir +;source-doc/ufi-drv/class_ufi.c:92: usb_error result = + ld c,(ix+6) + ld b,(ix+7) + ld hl,0x0000 + push hl + push bc + ld l,0x24 + 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 +;source-doc/ufi-drv/class_ufi.c:97: return result; +;source-doc/ufi-drv/class_ufi.c:98: } + ld sp,ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:100: 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:107: memset(&cmd, 0, sizeof(cmd)); + ld hl,0 + add hl, sp + ld b,0x06 +l_ufi_read_write_sector_00113: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_ufi_read_write_sector_00113 +;source-doc/ufi-drv/class_ufi.c:108: cmd.operation_code = send ? 0x2A : 0x28; + bit 0,(ix+6) + jr Z,l_ufi_read_write_sector_00104 + ld a,0x2a + jr l_ufi_read_write_sector_00105 +l_ufi_read_write_sector_00104: + ld a,0x28 +l_ufi_read_write_sector_00105: + ld (ix-12),a +;source-doc/ufi-drv/class_ufi.c:109: cmd.lba[2] = sector_number >> 8; + ld a,(ix+8) + ld (ix-8),a +;source-doc/ufi-drv/class_ufi.c:110: cmd.lba[3] = sector_number & 0xFF; + ld a,(ix+7) + ld (ix-7),a +;source-doc/ufi-drv/class_ufi.c:111: cmd.transfer_length[1] = sector_count; +;source-doc/ufi-drv/class_ufi.c:113: 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 b, a + ld c,0x00 + ld l,(ix+12) + ld h,(ix+13) + push hl + ld l,(ix+10) + ld h,(ix+11) + push hl + 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 +;source-doc/ufi-drv/class_ufi.c:117: return result; +;source-doc/ufi-drv/class_ufi.c:118: } + ld sp,ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:123: * HD | 93h | 1.25 MB | 77 | 2 | 8 | 1232 04D0h | 1024 0400h | +; --------------------------------- +; 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:130: const ufi_format_capacity_descriptor *const format) { + ld hl,2 + add hl, sp + ld b,0x06 +l_ufi_format_00104: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_ufi_format_00104 +;source-doc/ufi-drv/class_ufi.c:133: ufi_format_parameter_list parameter_list; + 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:136: ufi_format_command cmd; + ld a,(ix+7) + ld (ix-10),a +;source-doc/ufi-drv/class_ufi.c:137: cmd = _ufi_cmd_format; + ld (ix-8),0x00 +;source-doc/ufi-drv/class_ufi.c:138: // memcpy(&cmd, &_ufi_cmd_format, sizeof(cmd)); + ld (ix-4),0x0c +;source-doc/ufi-drv/class_ufi.c:140: cmd.track_number = track_number; +;source-doc/ufi-drv/class_ufi.c:141: cmd.interleave[1] = 0; + ld a,(ix+6) + and 0x01 + or 0xb0 + ld (ix-23),a +;source-doc/ufi-drv/class_ufi.c:142: cmd.parameter_list_length[1] = sizeof(parameter_list); + ld (ix-22),0x00 +;source-doc/ufi-drv/class_ufi.c:143: + ld (ix-21),0x08 +;source-doc/ufi-drv/class_ufi.c:144: parameter_list.defect_list_header.status = + ld hl,6 + add hl, sp + ex de, hl + ld l,(ix+8) + ld h,(ix+9) + ld bc,0x0008 + ldir +;source-doc/ufi-drv/class_ufi.c:146: parameter_list.defect_list_header.defect_list_length_msb = 0; + 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 +;source-doc/ufi-drv/class_ufi.c:153: // trace_printf("ufi_format: %d, %02X %02X (len: %d)\r\n", result, sense_codes.bASC, sense_codes.bASCQ, sizeof(parameter_list)); +;source-doc/ufi-drv/class_ufi.c:154: + ld sp,ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:156: done: +; --------------------------------- +; 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:159: + ld hl,0 + add hl, sp + ex de, hl + ld bc,0x000c + ld hl,__ufi_cmd_send_diagnostic + ldir +;source-doc/ufi-drv/class_ufi.c:161: ufi_send_diagnostic_command ufi_cmd_send_diagnostic; + ld hl,0x0000 + push hl + push hl + push hl + ld a,0x01 + 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 +;source-doc/ufi-drv/class_ufi.c:162: + ld sp,ix + pop ix + ret +;source-doc/ufi-drv/class_ufi.c:164: +; --------------------------------- +; 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:166: } + ld hl,0 + add hl, sp + ex de, hl +;source-doc/ufi-drv/class_ufi.c:167: + ld l,(ix+4) + ld h,(ix+5) + inc hl + inc hl + inc hl +;source-doc/ufi-drv/class_ufi.c:169: uint32_t result; + ld a, (hl) + dec hl + ld (de), a + inc de +;source-doc/ufi-drv/class_ufi.c:170: uint8_t *p_output = ((uint8_t *)&result); + ld a, (hl) + dec hl + ld (de), a + inc de +;source-doc/ufi-drv/class_ufi.c:171: const uint8_t *p_input = buffer + 3; + ld a, (hl) + ld (de), a + inc de +;source-doc/ufi-drv/class_ufi.c:172: + dec hl + ld a, (hl) + ld (de), a +;source-doc/ufi-drv/class_ufi.c:174: *p_output++ = *p_input--; + pop hl + push hl + ld e,(ix-2) + ld d,(ix-1) +;source-doc/ufi-drv/class_ufi.c:175: *p_output++ = *p_input--; + 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..01d67fbe --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/ufi-init.c.s @@ -0,0 +1,139 @@ +; +; 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.5.0 #15248 (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/ufi-drv/ufi-init.c:8: 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:11: do { + ld (ix-1),0x01 +l_chufi_init_00103: +;source-doc/ufi-drv/ufi-init.c:12: usb_device_type t = usb_get_device_type(index); + ld e,(ix-1) + ld d,0x00 + push de + push de + call _usb_get_device_type + pop af + pop de +;source-doc/ufi-drv/ufi-init.c:14: if (t == USB_IS_FLOPPY) { + dec l + jr NZ,l_chufi_init_00104 +;source-doc/ufi-drv/ufi-init.c:15: const uint8_t dev_index = find_storage_dev(); // dev_index == -1 (no more left) should never happen + push de + call _find_storage_dev + ld (ix-2),l + pop de +;source-doc/ufi-drv/ufi-init.c:17: hbios_usb_storage_devices[dev_index].drive_index = dev_index + 1; + ld l,(ix-2) + ld h,0x00 + add hl, hl + ld bc,_hbios_usb_storage_devices + add hl, bc + ld a,(ix-2) + inc a + ld (hl),a +;source-doc/ufi-drv/ufi-init.c:18: hbios_usb_storage_devices[dev_index].usb_device = index; + inc hl + ld a,(ix-1) + ld (hl),a + dec hl +;source-doc/ufi-drv/ufi-init.c:20: print_string("\r\nUSB: FLOPPY @ $"); + push hl + push de + ld hl,ufi_init_str_0 + call _print_string + pop de + pop hl +;source-doc/ufi-drv/ufi-init.c:21: print_uint16(index); + push hl + ex de, hl + call _print_uint16 +;source-doc/ufi-drv/ufi-init.c:22: print_string(":$"); + ld hl,ufi_init_str_1 + call _print_string + pop hl +;source-doc/ufi-drv/ufi-init.c:23: print_uint16(dev_index); + ld e,(ix-2) + ld d,0x00 + push hl + ex de, hl + call _print_uint16 +;source-doc/ufi-drv/ufi-init.c:24: print_string(" $"); + ld hl,ufi_init_str_2 + call _print_string + pop hl +;source-doc/ufi-drv/ufi-init.c:25: dio_add_entry(ch_ufi_fntbl, &hbios_usb_storage_devices[dev_index]); + ex de, hl + ld hl,_ch_ufi_fntbl + call _dio_add_entry +l_chufi_init_00104: +;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_00103 +;source-doc/ufi-drv/ufi-init.c:29: } + ld sp, ix + pop ix + ret +ufi_init_str_0: + DEFB 0x0d + DEFB 0x0a + DEFM "USB: FLOPPY @ $" + DEFB 0x00 +ufi_init_str_1: + DEFM ":$" + DEFB 0x00 +ufi_init_str_2: + DEFM " $" + DEFB 0x00 diff --git a/Source/HBIOS/ch376-native/ufi-drv/ufi_driver.c.s b/Source/HBIOS/ch376-native/ufi-drv/ufi_driver.c.s new file mode 100644 index 00000000..b440df7d --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/ufi_driver.c.s @@ -0,0 +1,373 @@ +; +; Generated from source-doc/ufi-drv/ufi_driver.c.asm -- not to be modify directly +; +; +;-------------------------------------------------------- +; File Created by SDCC : free open source ISO C Compiler +; Version 4.5.0 #15248 (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/ufi-drv/ufi_driver.c:6: uint32_t usb_ufi_get_cap(const uint16_t dev_index) { +; --------------------------------- +; Function usb_ufi_get_cap +; --------------------------------- +_usb_ufi_get_cap: + push ix + ld ix,0 + add ix,sp + ld hl, -72 + add hl, sp + ld sp, hl +;source-doc/ufi-drv/ufi_driver.c:7: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config +;source-doc/ufi-drv/ufi_driver.c:10: memset(&response, 0, sizeof(ufi_format_capacities_response)); + ld hl,0 + add hl, sp + ld b,0x12 +l_usb_ufi_get_cap_00112: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_usb_ufi_get_cap_00112 +;source-doc/ufi-drv/ufi_driver.c:12: wait_for_device_ready(dev, 25); + push de + ld a,0x19 + push af + inc sp + push de + call _wait_for_device_ready + pop af + inc sp + pop de +;source-doc/ufi-drv/ufi_driver.c:16: ufi_inquiry(dev, &inquiry); + push de + ld hl,38 + add hl, sp + push hl + push de + call _ufi_inquiry + pop af + pop af + pop de +;source-doc/ufi-drv/ufi_driver.c:18: wait_for_device_ready(dev, 15); + push de + ld a,0x0f + push af + inc sp + push de + call _wait_for_device_ready + pop af + inc sp + pop de +;source-doc/ufi-drv/ufi_driver.c:20: const usb_error result = ufi_read_frmt_caps(dev, &response); + ld hl,0 + add hl, sp + push hl + push de + call _ufi_read_frmt_caps + pop af + pop af + ld a, l +;source-doc/ufi-drv/ufi_driver.c:21: if (result != USB_ERR_OK) + or a + jr Z,l_usb_ufi_get_cap_00102 +;source-doc/ufi-drv/ufi_driver.c:22: return 0; + ld hl,0x0000 + ld e, l + ld d, l + jr l_usb_ufi_get_cap_00103 +l_usb_ufi_get_cap_00102: +;source-doc/ufi-drv/ufi_driver.c:24: 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_usb_ufi_get_cap_00103: +;source-doc/ufi-drv/ufi_driver.c:25: } + ld sp, ix + pop ix + ret +;source-doc/ufi-drv/ufi_driver.c:27: usb_error usb_ufi_read(const uint16_t dev_index, uint8_t *const buffer) { +; --------------------------------- +; Function usb_ufi_read +; --------------------------------- +_usb_ufi_read: + push ix + ld ix,0 + add ix,sp + ld hl, -20 + add hl, sp + ld sp, hl +;source-doc/ufi-drv/ufi_driver.c:28: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config +;source-doc/ufi-drv/ufi_driver.c:30: if (wait_for_device_ready((device_config *)dev, 20) != 0) + push de + ld c,e + ld b,d + push de + ld a,0x14 + push af + inc sp + push bc + call _wait_for_device_ready + pop af + inc sp + ld a, l + pop de + pop bc + or a + jr Z,l_usb_ufi_read_00102 +;source-doc/ufi-drv/ufi_driver.c:31: return -1; // Not READY! + ld l,0xff + jr l_usb_ufi_read_00109 +l_usb_ufi_read_00102: +;source-doc/ufi-drv/ufi_driver.c:36: memset(&sense_codes, 0, sizeof(sense_codes)); + ld hl,0 + add hl, sp + xor a + ld (hl), a + inc hl + ld (hl), a +;source-doc/ufi-drv/ufi_driver.c:38: if (ufi_read_write_sector((device_config *)dev, false, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes) != USB_ERR_OK) + 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 + pop af + pop af + pop af + pop af + pop af + ld a, l + pop bc + or a + jr Z,l_usb_ufi_read_00104 +;source-doc/ufi-drv/ufi_driver.c:39: return -1; // general error + ld l,0xff + jr l_usb_ufi_read_00109 +l_usb_ufi_read_00104: +;source-doc/ufi-drv/ufi_driver.c:42: memset(&response, 0, sizeof(response)); + push bc + ld hl,4 + add hl, sp + ld b,0x09 +l_usb_ufi_read_00139: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_usb_ufi_read_00139 + pop bc +;source-doc/ufi-drv/ufi_driver.c:44: 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_usb_ufi_read_00106 +;source-doc/ufi-drv/ufi_driver.c:45: return -1; // error + ld l,0xff + jr l_usb_ufi_read_00109 +l_usb_ufi_read_00106: +;source-doc/ufi-drv/ufi_driver.c:49: const uint8_t sense_key = response.sense_key & 15; + ld a,(ix-16) + and 0x0f + jr Z,l_usb_ufi_read_00108 +;source-doc/ufi-drv/ufi_driver.c:51: if (sense_key != 0) +;source-doc/ufi-drv/ufi_driver.c:52: return -1; + ld l,0xff + jr l_usb_ufi_read_00109 +l_usb_ufi_read_00108: +;source-doc/ufi-drv/ufi_driver.c:54: return USB_ERR_OK; + ld l,0x00 +l_usb_ufi_read_00109: +;source-doc/ufi-drv/ufi_driver.c:55: } + ld sp, ix + pop ix + ret +;source-doc/ufi-drv/ufi_driver.c:57: usb_error usb_ufi_write(const uint16_t dev_index, uint8_t *const buffer) { +; --------------------------------- +; Function usb_ufi_write +; --------------------------------- +_usb_ufi_write: + push ix + ld ix,0 + add ix,sp + ld hl, -20 + add hl, sp + ld sp, hl +;source-doc/ufi-drv/ufi_driver.c:58: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index); + ld a,(ix+4) + call _get_usb_device_config +;source-doc/ufi-drv/ufi_driver.c:60: if (wait_for_device_ready((device_config *)dev, 20) != 0) + push de + ld c,e + ld b,d + push de + ld a,0x14 + push af + inc sp + push bc + call _wait_for_device_ready + pop af + inc sp + ld a, l + pop de + pop bc + or a + jr Z,l_usb_ufi_write_00102 +;source-doc/ufi-drv/ufi_driver.c:61: return -1; // Not READY! + ld l,0xff + jr l_usb_ufi_write_00109 +l_usb_ufi_write_00102: +;source-doc/ufi-drv/ufi_driver.c:65: memset(&sense_codes, 0, sizeof(sense_codes)); + ld hl,0 + add hl, sp + xor a + ld (hl), a + inc hl + ld (hl), a +;source-doc/ufi-drv/ufi_driver.c:66: if ((ufi_read_write_sector((device_config *)dev, true, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes)) != USB_ERR_OK) { + 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 + ld a,0x01 + push af + inc sp + push bc + call _ufi_read_write_sector + pop af + pop af + pop af + pop af + pop af + ld a, l + pop bc + or a + jr Z,l_usb_ufi_write_00104 +;source-doc/ufi-drv/ufi_driver.c:67: return -1; + ld l,0xff + jr l_usb_ufi_write_00109 +l_usb_ufi_write_00104: +;source-doc/ufi-drv/ufi_driver.c:71: memset(&response, 0, sizeof(response)); + push bc + ld hl,4 + add hl, sp + ld b,0x09 +l_usb_ufi_write_00139: + xor a + ld (hl), a + inc hl + ld (hl), a + inc hl + djnz l_usb_ufi_write_00139 + pop bc +;source-doc/ufi-drv/ufi_driver.c:73: if ((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_usb_ufi_write_00106 +;source-doc/ufi-drv/ufi_driver.c:74: return -1; + ld l,0xff + jr l_usb_ufi_write_00109 +l_usb_ufi_write_00106: +;source-doc/ufi-drv/ufi_driver.c:79: const uint8_t sense_key = response.sense_key & 15; + ld a,(ix-16) + and 0x0f + jr Z,l_usb_ufi_write_00108 +;source-doc/ufi-drv/ufi_driver.c:81: if (sense_key != 0) +;source-doc/ufi-drv/ufi_driver.c:82: return -1; + ld l,0xff + jr l_usb_ufi_write_00109 +l_usb_ufi_write_00108: +;source-doc/ufi-drv/ufi_driver.c:84: return USB_ERR_OK; + ld l,0x00 +l_usb_ufi_write_00109: +;source-doc/ufi-drv/ufi_driver.c:85: } + 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..90a034cd --- /dev/null +++ b/Source/HBIOS/ch376-native/ufi-drv/usb_cbi.c.s @@ -0,0 +1,219 @@ +; +; 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.5.0 #15248 (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 + +_cbi2_adsc: + DEFS 8 + +#ENDIF + +;-------------------------------------------------------- +; absolute external ram data +;-------------------------------------------------------- +;-------------------------------------------------------- +; global & static initialisations +;-------------------------------------------------------- +;-------------------------------------------------------- +; Home +;-------------------------------------------------------- +;-------------------------------------------------------- +; code +;-------------------------------------------------------- +;source-doc/ufi-drv/usb_cbi.c:10: 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:17: 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:20: adsc = cbi2_adsc; + push de + push bc + 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:21: adsc.bIndex[0] = interface_number; + ld (ix-4),e +;source-doc/ufi-drv/usb_cbi.c:23: critical_begin(); + push bc + call _critical_begin + pop bc +;source-doc/ufi-drv/usb_cbi.c:25: 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 +;source-doc/ufi-drv/usb_cbi.c:27: if (result == USB_ERR_STALL) { + ld a, l + sub 0x02 + jr NZ,l_usb_execute_cbi_00104 +;source-doc/ufi-drv/usb_cbi.c:28: 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:29: 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 + ld sp, hl +l_usb_execute_cbi_00102: +;source-doc/ufi-drv/usb_cbi.c:31: result = USB_ERR_STALL; + ld l,0x02 +;source-doc/ufi-drv/usb_cbi.c:32: goto done; + jr l_usb_execute_cbi_00116 +l_usb_execute_cbi_00104: +;source-doc/ufi-drv/usb_cbi.c:35: if (result != USB_ERR_OK) { + ld a, l + or a + jr NZ,l_usb_execute_cbi_00116 +;source-doc/ufi-drv/usb_cbi.c:40: if (send) { + bit 0,(ix+8) + jr Z,l_usb_execute_cbi_00112 +;source-doc/ufi-drv/usb_cbi.c:41: 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:43: if (result != USB_ERR_OK) { + ld a, l + or a + jr Z,l_usb_execute_cbi_00113 +;source-doc/ufi-drv/usb_cbi.c:45: goto done; + jr l_usb_execute_cbi_00116 +l_usb_execute_cbi_00112: +;source-doc/ufi-drv/usb_cbi.c:48: 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:50: if (result != USB_ERR_OK) { + ld a, l + or a + jr NZ,l_usb_execute_cbi_00116 +;source-doc/ufi-drv/usb_cbi.c:52: goto done; +l_usb_execute_cbi_00113: +;source-doc/ufi-drv/usb_cbi.c:56: if (sense_codes != NULL) { + ld a,(ix+14) + or (ix+13) + jr Z,l_usb_execute_cbi_00116 +;source-doc/ufi-drv/usb_cbi.c:57: 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:65: done: +l_usb_execute_cbi_00116: +;source-doc/ufi-drv/usb_cbi.c:66: critical_end(); + push hl + call _critical_end + pop hl +;source-doc/ufi-drv/usb_cbi.c:68: return result; +;source-doc/ufi-drv/usb_cbi.c:69: } + 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..edde7dc0 --- /dev/null +++ b/Source/HBIOS/ch376.asm @@ -0,0 +1,61 @@ +; +;================================================================================================== +; CH376 NATIVE USB DRIVER +;================================================================================================== +; + +#DEFINE DEFM .DB +#DEFINE DEFB .DB +#DEFINE DEFW .DW + +_print_string .EQU PRTSTR + +_print_hex: + ld a, l + JP PRTHEXBYTE + +_dio_add_entry: + LD B, H + LD C, L + JP DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE + +#IF (CHNATIVEEZ80) + +#include "./ch376-native/ez80-firmware.asm" + +_ch376_driver_version: + .DB ",F); $", 0 + +#ELSE + +_ch376_driver_version: + .DB ",W); $", 0 + +_delay: + push af + 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 + +#include "./ch376-native/cruntime.asm" +#include "./ch376-native/base-drv.asm" +#ENDIF + +#include "./ch376-native/print.asm" +#include "./ch376-native/base-drv.s" + +CHNATIVE_INIT .EQU _chnative_init +CHNATIVE_INITF .EQU _chnative_init_force + diff --git a/Source/HBIOS/ch376kyb.asm b/Source/HBIOS/ch376kyb.asm new file mode 100644 index 00000000..bf552ea7 --- /dev/null +++ b/Source/HBIOS/ch376kyb.asm @@ -0,0 +1,151 @@ +; +;================================================================================================== +; CH376 NATIVE USB KEYBOARD DRIVER +;================================================================================================== +; +; This driver is designed to work within the TMS video driver for a CRT solution. + + +#IF (!CHNATIVEENABLE) + .ECHO "*** TMSMODE: TMSMODE_MSXUKY REQUIRES CHNATIVEENABLE***\n" + !!!!! *** TMSMODE: TMSMODE_MSXUKY REQUIRES CHNATIVEENABLE*** +_usb_kyb_status: +_usb_kyb_flush: +#ENDIF + + +#DEFINE DEFM .DB +#DEFINE DEFB .DB +#DEFINE DEFW .DW + +#IF (!CHNATIVEEZ80) +#IF (SYSTIM == TM_NONE) + .ECHO "*** ERROR: MKY REQUIRES SYSTEM TIMER -- NONE CONFIGURED!!!\n" + !!! ; FORCE AN ASSEMBLY ERROR +#ENDIF +#ENDIF + +#include "./ch376-native/keyboard.s" + +#IF (CHNATIVEEZ80) +CHUKB_INIT .EQU _keyboard_init + +#ELSE +; COUNT FOR INTERRUPT HANDLER TO TRIGGER KEYBOARD SCANNER (EG: SCAN KEYBOARD ONLY EVERY 2ND INTERRUPT (2/60)) +SCAN_INT_PERIOD: .EQU 2 + + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + .DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +UKY_INTSTK: ; 128 bytes for keyboard interrupt stack - need ~52 bytes??? + +CHUKB_INIT: + CALL _keyboard_init + OR A + RET Z + + ; INSTALL INTERRUPT HANDLER + LD HL, (VEC_TICK+1) + LD (VEC_CHUKB_TICK+1), HL + + LD HL, CHUKB_TICK + LD (VEC_TICK+1), HL + + RET + +CHUKB_TICK: + LD A, SCAN_INT_PERIOD ; SCAN THE KEYBOARD EVERY 'SCAN_INT_PERIOD' INTERRUPTS. +UKY_SCNCNT .EQU $ - 1 + DEC A + LD (UKY_SCNCNT), A + JP NZ, HB_TICK + + LD A, SCAN_INT_PERIOD + LD (UKY_SCNCNT), A + + ; we gonna need a bigger stack + + LD (UKY_INT_SP),SP ; SAVE ORIGINAL STACK FRAME + LD SP,UKY_INTSTK ; USE DEDICATED INT STACK FRAME IN HI MEM + + CALL _usb_kyb_tick + + LD SP, $FFFF ; RESTORE ORIGINAL STACK FRAME +UKY_INT_SP .EQU $ - 2 +; + + +VEC_CHUKB_TICK: + JP HB_TICK + +#ENDIF + +; ### Function 0x4C -- Keyboard Status (VDAKST) +; +; Inputs: +; None +; +; Outputs: +; A: Status / Codes Pending +; +; Return a count of the number of key Codes Pending (A) in the keyboard buffer. +; If it is not possible to determine the actual number in the buffer, it is +; acceptable to return 1 to indicate there are key codes available to read and +; 0 if there are none available. +; The value returned in register A is used as both a Status (A) code and the +; return value. Negative values (bit 7 set) indicate a standard HBIOS result +; (error) code. Otherwise, the return value represents the number of key codes +; pending. +; +UKY_STAT: .EQU _usb_kyb_status + +; ### Function 0x4D -- Video Keyboard Flush (VDAKFL) +; +; Inputs: +; None +; +; Outputs: +; A: standard HBIOS result code +; +; Purged and all contents discarded. The Status (A) is a standard HBIOS result code. +; +UKY_FLUSH .EQU _usb_kyb_flush + +; +; ### Function 0x4E -- Video Keyboard Read (VDAKRD) +; +; Inputs: +; None +; +; Outputs: +; A: Status +; E: Keycode +; +; Read the next key data from the keyboard. If a buffer is used, return the next key code in the buffer. +; If no key data is available, this function will wait indefinitely for a key press. The Status (A) is a +; standard HBIOS result code. +; +; The Keycode (E) is generally returned as appropriate ASCII values, if possible. Special keys, like +; function keys and arrows, are returned as reserved codes. +; +UKY_READ: + CALL _usb_kyb_read + LD A, H + OR A + JR NZ, UKY_READ + LD E, L + XOR A + RET diff --git a/Source/HBIOS/ch376scsi.asm b/Source/HBIOS/ch376scsi.asm new file mode 100644 index 00000000..653031cf --- /dev/null +++ b/Source/HBIOS/ch376scsi.asm @@ -0,0 +1,316 @@ +; +;================================================================================================== +; 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: + XOR A + RET + +CH_SCSI_RESET: + 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + 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) + + PUSH DE + PUSH HL + PUSH IY + CALL _usb_scsi_seek + POP IY + POP HL + POP DE + + XOR A + 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR + + ; call scsi_read(IY, HL); + ; HL = HL + 512 + PUSH HL + PUSH IY + CALL _usb_scsi_read + LD A, L + POP IY + POP HL + 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR + + ; call scsi_write(IY, HL); + ; HL = HL + 512 + PUSH HL + PUSH IY + CALL _usb_scsi_write + LD A, L + POP IY + POP HL + 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, %00111010 + LD D, DIODEV_USB + LD E, (IY+0) ; drive_index + DEC E + LD HL, 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + PUSH IX + LD IX, -8 ; reserve 8 bytes for + ADD IX, SP ; scsi_read_capacity_result + LD SP, IX + + PUSH IX + PUSH IY + CALL _usb_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..ab2e18fb --- /dev/null +++ b/Source/HBIOS/ch376ufi.asm @@ -0,0 +1,283 @@ +; +;================================================================================================== +; CH376 NATIVE MASS STORAGE DRIVER +;================================================================================================== +; + +#include "./ch376-native/ufi-drv.s" +_ufi_seek .EQU _usb_scsi_seek + + ; 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: + XOR A + RET + +CH_UFI_RESET: + 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + 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) + + PUSH DE + PUSH HL + PUSH IY + CALL _ufi_seek + POP IY + POP HL + POP DE + + XOR A + 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR + + PUSH HL + PUSH IY + CALL _usb_ufi_read + LD L, 0 + LD A, L + POP IY + POP HL + 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_UFI_WRITE: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR + + ; call scsi_write(IY, HL); + ; HL = HL + 512 + PUSH HL + PUSH IY + CALL _usb_ufi_write + LD A, L + POP IY + POP HL + LD BC, 512 + ADD HL, BC + 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, %11010110 + LD D, DIODEV_USB + LD E, (IY+0) ; drive_index + DEC E + LD HL, 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: + EXX + LD D, 0 + LD E, (IY+1) ; usb_device + PUSH DE + POP IY + EXX + + PUSH IY + CALL _usb_ufi_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/ez80cpudrv.asm b/Source/HBIOS/ez80cpudrv.asm index 01db5f78..813869c4 100644 --- a/Source/HBIOS/ez80cpudrv.asm +++ b/Source/HBIOS/ez80cpudrv.asm @@ -40,13 +40,20 @@ EZ80_PREINIT: LD A, 5 LD (HB_CPUTYPE),A - ; DETECT IF USING ALT-FIRMWARE - LD A, C - AND $80 - LD (EZ80_ALT_FIRM), A LD (EZ80_PLT_VERSION), HL LD (EZ80_PLT_VERSION+2), DE + ; need version 0.4.x.x at miniumum + LD HL, 4-1 + XOR A + SBC HL, DE + + JR c, EZ80_VEROK + CPL + +EZ80_VEROK: + LD (EZ80_VER_WARNING), A + EXX LD A, C LD (EZ80_BUILD_DATE), A ; DAY @@ -243,11 +250,12 @@ EZ80_RPT_FIRMWARE: CALL PC_LEADING_ZERO CALL PRTDECB - LD A, (EZ80_ALT_FIRM) - OR A - RET Z - CALL PRTSTRD - .TEXT " (ALT)$" + LD A, (EZ80_VER_WARNING) + OR A + RET Z + CALL PRTSTRD + .TEXT " (WARN-VER-OOD)$" + RET PC_LEADING_ZERO: @@ -273,7 +281,7 @@ EZ80_PLT_FLSHWS: EZ80_PLT_VERSION: .DB 0, 0, 0, 0 -EZ80_ALT_FIRM: +EZ80_VER_WARNING: .DB 0 EZ80_BUILD_DATE: @@ -302,3 +310,23 @@ _EZ80_CPY_UHL_TO_EHL: .DB $49, $E1 ; POP.L HL POP IX RET + +; set the upper byte (u of DE) to MB. +_EZ80_EXTN_DE_TO_MB_DE: + .DB $49, $D5 ; PUSH.L DE + .DB $5B, $FD, $21, $00, $00, $00 ; LD.LIL IY, 0 + .DB $49, $FD, $39 ; ADD.L IY, SP + .DB $ED, $6E ; LD A, MB + .DB $5B, $FD, $77, $02 ; LD.LIL (IY+2), A + .DB $49, $D1 ; POP.L DE + RET + +; set the upper byte (u of IY) to MB. +_EZ80_EXTN_IY_TO_MB_IY: + .DB $49, $FD, $E5 ; PUSH.L IY + .DB $5B, $FD, $21, $00, $00, $00 ; LD.LIL IY, 0 + .DB $49, $FD, $39 ; ADD.L IY, SP + .DB $ED, $6E ; LD A, MB + .DB $5B, $FD, $77, $02 ; LD.LIL (IY+2), A + .DB $49, $FD, $E1 ; POP.L IY + RET diff --git a/Source/HBIOS/ez80instr.inc b/Source/HBIOS/ez80instr.inc index 5da3db4d..de7e168a 100644 --- a/Source/HBIOS/ez80instr.inc +++ b/Source/HBIOS/ez80instr.inc @@ -47,6 +47,25 @@ #DEFINE EZ80_TMR_IS_TICK_ISR LD A, 2 \ LD B, 10 \ EZ80_FN #DEFINE EZ80_TMR_DELAY LD A, 2 \ LD B, 11 \ EZ80_FN + #DEFINE EZ80_EX_USB_INIT LD A, 6 \ LD B, 255 \ EZ80_FN + #DEFINE EZ80_EX_USB_STORAGE_SEEK LD A, 6 \ LD B, 254 \ EZ80_FN + #DEFINE EZ80_EX_USB_GET_DEV_TYPE LD A, 6 \ LD B, 253 \ EZ80_FN + + #DEFINE EZ80_EX_USB_SCSI_READ LD A, 6 \ LD B, 0 \ EZ80_FN + #DEFINE EZ80_EX_USB_SCSI_WRITE LD A, 6 \ LD B, 1 \ EZ80_FN + #DEFINE EZ80_EX_USB_SCSI_READ_CAP LD A, 6 \ LD B, 2 \ EZ80_FN + #DEFINE EZ80_EX_USB_SCSI_INIT LD A, 6 \ LD B, 15 \ EZ80_FN + + #DEFINE EZ80_EX_USB_UFI_READ LD A, 6 \ LD B, 16 \ EZ80_FN + #DEFINE EZ80_EX_USB_UFI_WRITE LD A, 6 \ LD B, 17 \ EZ80_FN + #DEFINE EZ80_EX_USB_UFI_GET_CAP LD A, 6 \ LD B, 18 \ EZ80_FN +; #DEFINE EZ80_EX_USB_UFI_INIT LD A, 6 \ LD B, 31 \ EZ80_FN + + #DEFINE EZ80_EX_USB_KYB_STATUS LD A, 6 \ LD B, 32 \ EZ80_FN + #DEFINE EZ80_EX_USB_KYB_READ LD A, 6 \ LD B, 33 \ EZ80_FN + #DEFINE EZ80_EX_USB_KYB_FLUSH LD A, 6 \ LD B, 34 \ EZ80_FN + #DEFINE EZ80_EX_USB_KYB_INIT LD A, 6 \ LD B, 47 \ EZ80_FN + #DEFINE EZ80_THROTTLE_START(p,store) \ #DEFCONT \ PUSH AF #DEFCONT \ PUSH BC @@ -112,6 +131,13 @@ #defcont \ .DB $49 #defcont \ SBC HL, BC + ; LD.L DE,(IY+d) $49, $FD, $17, d + #DEFINE LD_DE_IY_P_.L(dd) \ + #DEFCONT \ .DB $49 + #DEFCONT \ .DB $FD + #DEFCONT \ .DB $17 + #DEFCONT \ .DB dd + IO_SEGMENT .EQU $FF ; THE UPPER 8-BIT ADDRESS FOR I/O #DEFINE OUT_NN_A(addr) \ @@ -126,6 +152,8 @@ IO_SEGMENT .EQU $FF ; THE UPPER 8-BIT ADDRESS FOR I/O #define EZ80_CPY_EHL_TO_UHL CALL _EZ80_CPY_EHL_TO_UHL #define EZ80_CPY_UHL_TO_EHL CALL _EZ80_CPY_UHL_TO_EHL +#define EZ80_EXTN_DE_TO_MB_DE CALL _EZ80_EXTN_DE_TO_MB_DE +#DEFINE EZ80_EXTN_IY_TO_MB_IY CALL _EZ80_EXTN_IY_TO_MB_IY #ELSE #DEFINE EZ80_IO diff --git a/Source/HBIOS/hbios.asm b/Source/HBIOS/hbios.asm index 0cfa082a..d8b4bb86 100644 --- a/Source/HBIOS/hbios.asm +++ b/Source/HBIOS/hbios.asm @@ -1929,7 +1929,7 @@ ROMRESUME: LD A,BID_IMG2 ; S100 MONITOR BANK LD IX,HWMON_IMGLOC ; EXECUTION RESUMES HERE CALL HBX_BNKCALL ; CONTINUE IN RAM BANK, DO NOT RETURN - HALT ; WE SHOULD NOT COME BACK HERE! + JR $ ; HALT WE SHOULD NOT COME BACK HERE! ; S100MON_SKIP: ; RESTORE DEFAULT RELOAD REGISTER VALUE (PROBABLY NOT NEEDED) @@ -2084,7 +2084,7 @@ MBC_SINGLE: LD A,BID_BIOS ; BIOS BANK ID LD IX,HB_START1 ; EXECUTION RESUMES HERE CALL HBX_BNKCALL ; CONTINUE IN RAM BANK, DO NOT RETURN - HALT ; WE SHOULD NOT COME BACK HERE! + JR $ ; HALT WE SHOULD NOT COME BACK HERE! #ENDIF ; ; EXECUTION RESUMES HERE AFTER SWITCH TO RAM BANK @@ -3888,7 +3888,7 @@ INITSYS4: #ENDIF LD IX,0 ; ENTER AT ADDRESS 0 CALL HBX_BNKCALL ; GO THERE - HALT ; WE SHOULD NEVER COME BACK! + JR $ ; HALT WE SHOULD NEVER COME BACK! ; ;-------------------------------------------------------------------------------------------------- ; TABLE OF RECOVERY MODE INITIALIZATION ENTRY POINTS @@ -3983,6 +3983,15 @@ HB_PCINITTBLLEN .EQU (($ - HB_PCINITTBL) / 2) ; HB_INITTBL: ; +#IF (CHNATIVEENABLE) + ; NEED TO ENUMERATE USB DEVICES EARLY, SO THAT ACTUAL DRIVERS + ; WILL BE ABLE TO FIND THEM. +#IF (CHNATIVEFORCE) + .DW CHNATIVE_INITF +#ELSE + .DW CHNATIVE_INIT +#ENDIF +#ENDIF #IF (KIOENABLE) .DW KIO_INIT #ENDIF @@ -4169,6 +4178,12 @@ HB_INITTBL: #IF (ESPENABLE) .DW ESP_INIT #ENDIF +#IF (CHSCSIENABLE) + .DW CHSCSI_INIT +#ENDIF +#IF (CHUFIENABLE) + .DW CHUFI_INIT +#ENDIF ; HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2) ; @@ -6927,7 +6942,7 @@ SYSHALT: LD DE,STR_HALT CALL WRITESTR DI - HALT + JR $ ; HALT ; ;-------------------------------------------------------------------------------------------------- ; INTERRUPT MANAGEMENT SUPPORT @@ -7373,7 +7388,7 @@ Z280_DIAG: ; ;RETIL DI - HALT + JR $ ; HALT ; Z280_BADINTSTR .TEXT "BAD INT $" Z280_SSTEPSTR .TEXT "SINGLE STEP $" @@ -7443,7 +7458,7 @@ Z280_PRIVINST4: ; ; GO NO FURTHER DI - HALT + JR $ ; HALT ; Z280_PRIVINSTX: ; RESTORE REGISTERS @@ -9113,6 +9128,41 @@ 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 (USBKYBENABLE) +ORG_UKY .EQU $ + #INCLUDE "ch376kyb.asm" +SIZ_UKY .EQU $ - ORG_UKY + MEMECHO " CH376 USB Keyboard occupies " + MEMECHO SIZ_UKY + 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 ; diff --git a/Source/HBIOS/invntdev.asm b/Source/HBIOS/invntdev.asm index eeb18871..164015b8 100644 --- a/Source/HBIOS/invntdev.asm +++ b/Source/HBIOS/invntdev.asm @@ -581,6 +581,7 @@ PS_DDIMM .TEXT "IMM$" PS_DDSYQ .TEXT "SYQ$" PS_DDCHUSB .TEXT "CHUSB$" PS_DDCHSD .TEXT "CHSD$" +PS_DDCHNATUSB .TEXT "USB$" ; ; DISK TYPE STRINGS ; @@ -595,7 +596,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 ; diff --git a/Source/HBIOS/std.asm b/Source/HBIOS/std.asm index 145ae7e1..e9d77ec3 100644 --- a/Source/HBIOS/std.asm +++ b/Source/HBIOS/std.asm @@ -288,6 +288,7 @@ TMSMODE_MBC .EQU 6 ; MBC V9938/58 VIDEO BOARD TMSMODE_COLECO .EQU 7 ; COLECOVISION PORT MAPPING TMSMODE_DUO .EQU 8 ; DUODYNE PORT MAPPING TMSMODE_NABU .EQU 9 ; NABU +TMSMODE_MSXUKY .EQU 10 ; STD MSX PORTS + USB KEYBOARD ; ; CVDU VIDEO MODE SELECTIONS ; @@ -542,6 +543,7 @@ PPKENABLE .EQU FALSE ; PPK KEYBOARD DRIVER MKYENABLE .EQU FALSE ; MSX KEYBOARD DRIVER NABUKBENABLE .EQU FALSE ; NABU KEYBOARD DRIVER FVKBDENABLE .EQU FALSE ; FPGA KEYBOARD DRIVER +USBKYBENABLE .EQU FALSE ; USB KEYBOARD DRIVER ; ; VIDEO MODES ; diff --git a/Source/HBIOS/tms.asm b/Source/HBIOS/tms.asm index eb6dee54..091509ca 100644 --- a/Source/HBIOS/tms.asm +++ b/Source/HBIOS/tms.asm @@ -48,6 +48,7 @@ TMSKBD_KBD .EQU 1 TMSKBD_PPK .EQU 2 TMSKBD_MKY .EQU 3 TMSKBD_NABU .EQU 4 +TMSKBD_USB .EQU 5 ; TMSKBD .EQU TMSKBD_NONE ; ASSUME NONE ; @@ -93,6 +94,13 @@ TMSKBD .SET TMSKBD_MKY ; MSX KEYBOARD DEVECHO "MSXMKY" #ENDIF ; +#IF (TMSMODE == TMSMODE_MSXUKY) +TMS_DATREG .EQU $98 ; READ/WRITE DATA +TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL +TMSKBD .SET TMSKBD_USB ; MSX KEYBOARD + DEVECHO "MSX-USB_KYB" +#ENDIF +; #IF (TMSMODE == TMSMODE_MBC) TMS_DATREG .EQU $98 ; READ/WRITE DATA TMS_CMDREG .EQU $99 ; READ STATUS / WRITE REG SEL @@ -183,6 +191,11 @@ NABUKBENABLE .SET TRUE ; INCLUDE NABU KEYBOARD SUPPORT DEVECHO "NABU" #ENDIF ; +#IF (TMSKBD == TMSKBD_USB) +USBKYBENABLE .SET TRUE ; INCLUDE USB KEYBOARD SUPPORT + DEVECHO "USB-KYB" +#ENDIF +; #IF (TMSTIMENABLE & (INTMODE > 0)) DEVECHO ", INTERRUPTS ENABLED" #ENDIF @@ -311,6 +324,9 @@ TMS_INIT1: #IF (TMSKBD == TMSKBD_NABU) CALL NABUKB_INIT ; INITIALIZE NABU KEYBOARD DRIVER #ENDIF +#IF (TMSKBD == TMSKBD_USB) + CALL CHUKB_INIT +#ENDIF #IF (TMSTIMENABLE & (INTMODE > 0)) ; @@ -394,6 +410,11 @@ TMS_FNTBL: .DW MKY_FLUSH .DW MKY_READ #ENDIF +#IF (TMSKBD == TMSKBD_USB) + .DW UKY_STAT + .DW UKY_FLUSH + .DW UKY_READ +#ENDIF #IF (TMSKBD == TMSKBD_NABU) .DW NABUKB_STAT .DW NABUKB_FLUSH @@ -1136,7 +1157,6 @@ TMS_TSTINT: RET TMS_INTHNDL: - CALL HB_TIMINT ; RETURN NZ - HANDLED OR $FF RET diff --git a/Source/ver.inc b/Source/ver.inc index 69d7bc15..46e1e428 100644 --- a/Source/ver.inc +++ b/Source/ver.inc @@ -2,7 +2,7 @@ #DEFINE RMN 6 #DEFINE RUP 0 #DEFINE RTP 0 -#DEFINE BIOSVER "3.6.0-dev.11" +#DEFINE BIOSVER "3.6.0-dev.11+ch376native" #define rmj RMJ #define rmn RMN #define rup RUP diff --git a/Source/ver.lib b/Source/ver.lib index d26a4924..484d264f 100644 --- a/Source/ver.lib +++ b/Source/ver.lib @@ -3,5 +3,5 @@ rmn equ 6 rup equ 0 rtp equ 0 biosver macro - db "3.6.0-dev.11" + db "3.6.0-dev.11+ch376native" endm