mirror of https://github.com/wwarthen/RomWBW.git
committed by
GitHub
118 changed files with 15304 additions and 43 deletions
@ -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" |
|||
} |
|||
} |
|||
|
|||
@ -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 {} \; |
|||
@ -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 |
|||
@ -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 |
|||
@ -0,0 +1 @@ |
|||
*.asm |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
File diff suppressed because it is too large
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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" |
|||
@ -0,0 +1 @@ |
|||
*.asm |
|||
@ -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) |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -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` |
|||
@ -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" |
|||
@ -0,0 +1 @@ |
|||
*.asm |
|||
@ -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 |
|||
@ -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 |
|||
@ -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 |
|||
@ -0,0 +1,13 @@ |
|||
BasedOnStyle: LLVM |
|||
IndentWidth: 2 |
|||
AlignConsecutiveMacros: true |
|||
ColumnLimit: 132 |
|||
AlignConsecutiveAssignments: true |
|||
AlignConsecutiveDeclarations: true |
|||
AlignEscapedNewlines: true |
|||
AlignConsecutiveMacros: true |
|||
AlignEscapedNewlines: Right |
|||
BinPackArguments: true |
|||
BinPackParameters: false |
|||
IncludeBlocks: Preserve |
|||
SortIncludes: CaseInsensitive |
|||
@ -0,0 +1,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; |
|||
} |
|||
@ -0,0 +1,176 @@ |
|||
|
|||
#ifndef __CH376 |
|||
#define __CH376 |
|||
|
|||
#include "ch376inc.h" |
|||
#include "delay.h" |
|||
#include <stdint.h> |
|||
#include <stdlib.h> |
|||
|
|||
typedef enum { |
|||
USB_ERR_OK = 0, |
|||
USB_ERR_NAK = 1, |
|||
USB_ERR_STALL = 2, |
|||
USB_ERR_TIMEOUT = 3, |
|||
USB_ERR_DATA_ERROR = 4, |
|||
USB_ERR_NO_DEVICE = 5, |
|||
USB_ERR_PANIC_BUTTON_PRESSED = 6, |
|||
USB_TOKEN_OUT_OF_SYNC = 7, |
|||
USB_ERR_UNEXPECTED_STATUS_FROM_HOST = 8, |
|||
USB_ERR_CODE_EXCEPTION = 9, |
|||
USB_ERR_MEDIA_CHANGED = 10, |
|||
USB_ERR_MEDIA_NOT_PRESENT = 11, |
|||
USB_ERR_CH376_BLOCKED = 12, |
|||
USB_ERR_CH376_TIMEOUT = 13, |
|||
USB_ERR_FAIL = 14, |
|||
USB_ERR_MAX = 14, |
|||
USB_ERR_OTHER = 15, |
|||
USB_ERR_DISK_READ = 0x1D, |
|||
USB_ERR_DISK_WRITE = 0x1E, |
|||
USB_FILERR_MIN = 0x41, |
|||
USB_ERR_OPEN_DIR = 0x41, |
|||
USB_ERR_MISS_FILE = 0x42, |
|||
USB_FILERR_MAX = 0xB4, |
|||
USB_INT_CONNECT = 0x81, |
|||
USB_BAD_ADDRESS = 0x82, |
|||
USB_ERR_OUT_OF_MEMORY = 0x83, |
|||
USB_ERR_BUFF_TO_LARGE = 0x84, |
|||
USB_ERROR_DEVICE_NOT_FOUND = 0x85, |
|||
} usb_error; |
|||
|
|||
typedef enum { CH_NAK_RETRY_DONT = 0b00, CH_NAK_RETRY_INDEFINITE = 0b10, CH_NAK_RETRY_3S = 0b11 } ch_nak_retry_type; |
|||
|
|||
typedef enum { |
|||
USB_NOT_SUPPORTED = 0, |
|||
USB_IS_FLOPPY = 1, |
|||
USB_IS_MASS_STORAGE = 2, |
|||
USB_IS_CDC = 3, |
|||
USB_IS_KEYBOARD = 4, |
|||
USB_IS_UNKNOWN = 6, |
|||
_USB_LAST_DEVICE_TYPE, |
|||
USB_IS_HUB = 15 |
|||
|
|||
} usb_device_type; // 4 bits only
|
|||
|
|||
typedef enum { ENDPOINT_BULK_OUT = 0, ENDPOINT_BULK_IN = 1, ENDPOINT_INTERRUPT_IN = 2 } usb_endpoint_type; |
|||
|
|||
extern int printf(const char *msg, ...); |
|||
|
|||
#if STACK_TRACE_ENABLED |
|||
|
|||
#define trace_printf printf |
|||
|
|||
#define CHECK(fn) \ |
|||
{ \ |
|||
result = fn; \ |
|||
if (result != USB_ERR_OK && result != USB_ERR_STALL) { \ |
|||
if (result != USB_TOKEN_OUT_OF_SYNC) \ |
|||
printf("Error: %s:%d %d\r\n", __FILE__, __LINE__, result); \ |
|||
return result; \ |
|||
} \ |
|||
} |
|||
|
|||
#define RETURN_CHECK(fn) \ |
|||
{ \ |
|||
result = fn; \ |
|||
if (result != USB_ERR_OK && result != USB_ERR_STALL) { \ |
|||
if (result != USB_TOKEN_OUT_OF_SYNC) \ |
|||
printf("Error: %s:%d %d\r\n", __FILE__, __LINE__, result); \ |
|||
return result; \ |
|||
} \ |
|||
return result; \ |
|||
} |
|||
|
|||
#define TRACE_USB_ERROR(result) \ |
|||
{ \ |
|||
if (result != USB_ERR_OK) { \ |
|||
printf("USB: %s:%d %d\r\n", __FILE__, __LINE__, result); \ |
|||
} \ |
|||
} |
|||
|
|||
#else |
|||
|
|||
#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 |
|||
@ -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); } |
|||
File diff suppressed because it is too large
@ -0,0 +1,9 @@ |
|||
#include "class_hub.h" |
|||
#include "protocol.h" |
|||
#include "usb_state.h" |
|||
|
|||
const setup_packet cmd_get_hub_descriptor = {RT_DEVICE_TO_HOST | RT_CLASS | RT_DEVICE, 6, {0, 0x29}, {0, 0}, 8}; |
|||
|
|||
usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1) { |
|||
return usb_control_transfer(&cmd_get_hub_descriptor, hub_description, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
@ -0,0 +1,62 @@ |
|||
#ifndef __CLASS_HUB |
|||
#define __CLASS_HUB |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include <stdlib.h> |
|||
|
|||
/*
|
|||
wHubCharacteristics: |
|||
D1...D0: Logical Power Switching Mode |
|||
00: Ganged power switching (all ports power at once) |
|||
01: Individual port power switching |
|||
1X: Reserved. Used only on 1.0 compliant hubs that implement no power switching |
|||
|
|||
D2: Identifies a Compound Device |
|||
0: Hub is not part of a compound device. |
|||
1: Hub is part of a compound device. |
|||
|
|||
D4...D3: Logical Power Switching Mode |
|||
00: Global Over-current Protection. The hub reports over-current as a summation |
|||
of all ports’ current draw, without a breakdown of individual port |
|||
over-current status. |
|||
01: Individual Port Over-current Protection. The hub reports over-current on a |
|||
per-port basis. Each port has an over-current status. |
|||
1X: No Over-current Protection. This option is allowed only for bus-powered |
|||
*/ |
|||
|
|||
typedef struct { |
|||
uint8_t bDescLength; |
|||
uint8_t bDescriptorType; /* HUB Descriptor Type 0x29 */ |
|||
uint8_t bNbrPorts; /* Number of ports */ |
|||
uint16_t wHubCharacteristics; /* Bitmap Hub Characteristics (see above) */ |
|||
uint8_t bPwrOn2PwrGood; /* Time (*2 ms) from port power on to power good */ |
|||
uint8_t bHubContrCurrent; /* Maximum current used by hub controller (mA).*/ |
|||
uint8_t DeviceRemovable[1]; /* bits indicating deviceRemovable and portPwrCtrlMask */ |
|||
} hub_descriptor; |
|||
|
|||
typedef struct { |
|||
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 |
|||
@ -0,0 +1,8 @@ |
|||
#include "critical-section.h" |
|||
#include <stdint.h> |
|||
|
|||
uint8_t in_critical_usb_section = 0; |
|||
|
|||
void critical_begin() { in_critical_usb_section++; } |
|||
|
|||
void critical_end() { in_critical_usb_section--; } |
|||
@ -0,0 +1,13 @@ |
|||
#ifndef __CRITICAL_BLOCKS_H__ |
|||
#define __CRITICAL_BLOCKS_H__ |
|||
|
|||
#include <stdint.h> |
|||
|
|||
extern uint8_t in_critical_usb_section; |
|||
|
|||
void critical_begin(); |
|||
void critical_end(); |
|||
|
|||
#define is_in_critical_section() (in_critical_usb_section != 0) |
|||
|
|||
#endif |
|||
@ -0,0 +1,11 @@ |
|||
#ifndef __DELAY |
|||
#define __DELAY |
|||
|
|||
#include <stdlib.h> |
|||
|
|||
extern void delay(void); |
|||
extern void delay_20ms(void); |
|||
extern void delay_short(void); |
|||
extern void delay_medium(void); |
|||
|
|||
#endif |
|||
@ -0,0 +1,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 <stdlib.h> |
|||
|
|||
/**
|
|||
* @brief Perform a USB control transfer (in or out) |
|||
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
|
|||
* |
|||
* @param device the usb device |
|||
* @param cmd_packet Pointer to the setup packet - top bit of bmRequestType indicate data direction |
|||
* @param buffer Pointer of data to send or receive into |
|||
* @return usb_error USB_ERR_OK if all good, otherwise specific error code |
|||
*/ |
|||
usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) { |
|||
return usb_control_transfer(cmd_packet, buffer, device->address, device->max_packet_size); |
|||
} |
|||
|
|||
usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) { |
|||
usb_error result; |
|||
|
|||
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT]; |
|||
|
|||
result = usb_data_out_transfer(buffer, buffer_size, dev->address, endpoint); |
|||
|
|||
if (result == USB_ERR_STALL) { |
|||
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size); |
|||
endpoint->toggle = 0; |
|||
return USB_ERR_STALL; |
|||
} |
|||
|
|||
RETURN_CHECK(result); |
|||
|
|||
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; |
|||
} |
|||
@ -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 <stdlib.h> |
|||
|
|||
typedef struct { |
|||
|
|||
uint8_t number : 3; |
|||
uint16_t max_packet_sizex : 10; |
|||
} endpoint; |
|||
|
|||
// 3 bytes
|
|||
#define COMMON_DEVICE_CONFIG \ |
|||
usb_device_type type : 4; \ |
|||
uint8_t address : 4; \ |
|||
uint8_t max_packet_size; \ |
|||
uint8_t interface_number; |
|||
|
|||
typedef struct { |
|||
COMMON_DEVICE_CONFIG |
|||
endpoint_param endpoints[3]; // bulk in/out and interrupt
|
|||
} device_config; |
|||
|
|||
typedef struct { |
|||
COMMON_DEVICE_CONFIG // bytes: 0-2
|
|||
endpoint_param endpoints[3]; // bytes: 3-5, 6-8, 9-11 bulk in/out and interrupt
|
|||
uint32_t current_lba; // bytes 12-15
|
|||
} 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 |
|||
@ -0,0 +1,262 @@ |
|||
#include "enumerate.h" |
|||
#include "enumerate_hub.h" |
|||
#include "enumerate_storage.h" |
|||
#include "protocol.h" |
|||
#include "work-area.h" |
|||
#include <string.h> |
|||
|
|||
#include "print.h" |
|||
|
|||
usb_error op_id_class_drv(_working *const working) __sdcccall(1); |
|||
usb_error op_parse_endpoint(_working *const working) __sdcccall(1); |
|||
|
|||
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 -^ |
|||
|
|||
|
|||
*/ |
|||
@ -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 |
|||
@ -0,0 +1,82 @@ |
|||
#include "enumerate_hub.h" |
|||
#include "class_hub.h" |
|||
#include "delay.h" |
|||
#include "protocol.h" |
|||
#include "work-area.h" |
|||
#include <string.h> |
|||
|
|||
const setup_packet cmd_set_feature = {RT_HOST_TO_DEVICE | RT_CLASS | RT_OTHER, SET_FEATURE, {FEAT_PORT_POWER, 0}, {1, 0}, 0}; |
|||
const setup_packet cmd_clear_feature = {RT_HOST_TO_DEVICE | RT_CLASS | RT_OTHER, CLEAR_FEATURE, {FEAT_PORT_POWER, 0}, {1, 0}, 0}; |
|||
const setup_packet cmd_get_status_port = { |
|||
RT_DEVICE_TO_HOST | RT_CLASS | RT_OTHER, GET_STATUS, {0, 0}, {1, 0}, sizeof(hub_port_status)}; |
|||
|
|||
usb_error hub_set_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) { |
|||
setup_packet set_feature; |
|||
set_feature = cmd_set_feature; |
|||
|
|||
set_feature.bValue[0] = feature; |
|||
set_feature.bIndex[0] = index; |
|||
return usb_control_transfer(&set_feature, 0, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
|
|||
usb_error hub_clear_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) { |
|||
setup_packet clear_feature; |
|||
clear_feature = cmd_clear_feature; |
|||
|
|||
clear_feature.bValue[0] = feature; |
|||
clear_feature.bIndex[0] = index; |
|||
return usb_control_transfer(&clear_feature, 0, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
|
|||
usb_error hub_get_status_port(const device_config_hub *const hub_config, const uint8_t index, hub_port_status *const port_status) { |
|||
setup_packet get_status_port; |
|||
get_status_port = cmd_get_status_port; |
|||
|
|||
get_status_port.bIndex[0] = index; |
|||
return usb_control_transfer(&get_status_port, port_status, hub_config->address, hub_config->max_packet_size); |
|||
} |
|||
|
|||
usb_error configure_usb_hub(_working *const working) __z88dk_fastcall { |
|||
_usb_state *const work_area = get_usb_work_area(); |
|||
|
|||
usb_error result; |
|||
hub_descriptor hub_description; |
|||
hub_port_status port_status; |
|||
const device_config_hub *const hub_config = working->hub_config; |
|||
|
|||
CHECK(hub_get_descriptor(hub_config, &hub_description)); |
|||
|
|||
uint8_t i = hub_description.bNbrPorts; |
|||
do { |
|||
CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
|
|||
CHECK(hub_set_feature(hub_config, FEAT_PORT_POWER, i)); |
|||
|
|||
hub_clear_feature(hub_config, FEAT_PORT_RESET, i); |
|||
|
|||
CHECK(hub_set_feature(hub_config, FEAT_PORT_RESET, i)); |
|||
|
|||
CHECK(hub_get_status_port(hub_config, i, &port_status)); |
|||
|
|||
if (port_status.wPortStatus & PORT_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; |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
#ifndef __USB_ENUMERATE_HUB |
|||
#define __USB_ENUMERATE_HUB |
|||
|
|||
#include "enumerate.h" |
|||
#include "protocol.h" |
|||
#include "usb_state.h" |
|||
|
|||
extern usb_error configure_usb_hub(_working *const working) __z88dk_fastcall; |
|||
|
|||
#endif |
|||
@ -0,0 +1,27 @@ |
|||
#include "enumerate_storage.h" |
|||
#include "protocol.h" |
|||
#include <string.h> |
|||
|
|||
void parse_endpoints(device_config_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; |
|||
} |
|||
@ -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 |
|||
@ -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") |
|||
@ -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; |
|||
} |
|||
@ -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 |
|||
@ -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 |
|||
@ -0,0 +1,11 @@ |
|||
#ifndef __XPRINT |
|||
#define __XPRINT |
|||
|
|||
#include <stdint.h> |
|||
#include <stdlib.h> |
|||
|
|||
extern void print_hex(const char c) __z88dk_fastcall; |
|||
extern void print_string(const char *p) __z88dk_fastcall; |
|||
extern void print_uint16(const uint16_t n) __z88dk_fastcall; |
|||
|
|||
#endif |
|||
@ -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 <stdlib.h> |
|||
|
|||
#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); |
|||
} |
|||
@ -0,0 +1,98 @@ |
|||
#ifndef __HW |
|||
#define __HW |
|||
|
|||
#include "ch376.h" |
|||
#include "dev_transfers.h" |
|||
#include "transfers.h" |
|||
#include <stdlib.h> |
|||
|
|||
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 |
|||
@ -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 <stdlib.h> |
|||
|
|||
/**
|
|||
* @brief Perform a USB control transfer (in or out) |
|||
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
|
|||
* |
|||
* @param 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; |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
/**
|
|||
* @file transfer.h |
|||
* @author Dean Netherton |
|||
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip |
|||
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
|
|||
* @version 1.0 |
|||
* @date 2023-09-22 |
|||
* |
|||
* @copyright Copyright (c) 2023 |
|||
* |
|||
*/ |
|||
|
|||
#ifndef __USB_TRANSFERS |
|||
#define __USB_TRANSFERS |
|||
|
|||
#include "ch376.h" |
|||
#include <stdlib.h> |
|||
|
|||
#define GET_STATUS 0 |
|||
#define CLEAR_FEATURE 1 |
|||
#define SET_FEATURE 3 |
|||
#define GET_DESCRIPTOR 6 |
|||
#define SET_DESCRIPTOR 7 |
|||
#define CLEAR_TT_BUFFER 8 |
|||
#define RESET_TT 9 |
|||
#define GET_TT_STATE 10 |
|||
#define CSTOP_TT 11 |
|||
|
|||
#define FEAT_PORT_POWER 8 |
|||
#define FEAT_PORT_RESET 4 |
|||
#define HUB_FEATURE_PORT_CONNECTION_CHANGE 16 |
|||
#define FEAT_PORT_ENABLE_CHANGE 17 |
|||
#define FEAT_PORT_RESET_CHANGE 20 |
|||
|
|||
// HUB_FEATURE_PORT_CONNECTION = 0,
|
|||
// HUB_FEATURE_PORT_ENABLE = 1,
|
|||
// HUB_FEATURE_PORT_SUSPEND = 2,
|
|||
// HUB_FEATURE_PORT_OVER_CURRENT = 3,
|
|||
// HUB_FEATURE_PORT_RESET = 4,
|
|||
|
|||
// HUB_FEATURE_PORT_POWER = 8,
|
|||
// HUB_FEATURE_PORT_LOW_SPEED = 9,
|
|||
|
|||
// HUB_FEATURE_PORT_CONNECTION_CHANGE = 16,
|
|||
// HUB_FEATURE_PORT_ENABLE_CHANGE = 17,
|
|||
// HUB_FEATURE_PORT_SUSPEND_CHANGE = 18,
|
|||
// HUB_FEATURE_PORT_OVER_CURRENT_CHANGE = 19,
|
|||
// HUB_FEATURE_PORT_RESET_CHANGE = 20,
|
|||
// HUB_FEATURE_PORT_TEST = 21,
|
|||
// HUB_FEATURE_PORT_INDICATOR = 22
|
|||
|
|||
#define RT_HOST_TO_DEVICE 0b00000000 |
|||
#define RT_DEVICE_TO_HOST 0b10000000 |
|||
#define RT_STANDARD 0b00000000 |
|||
#define RT_CLASS 0b00100000 |
|||
#define RT_VENDOR 0b01000000 |
|||
#define RT_DEVICE 0b00000000 |
|||
#define RT_INTERFACE 0b00000001 |
|||
#define RT_ENDPOINT 0b00000010 |
|||
#define RT_OTHER 0b00000011 |
|||
|
|||
typedef struct _setup_packet { |
|||
uint8_t bmRequestType; |
|||
uint8_t bRequest; |
|||
uint8_t bValue[2]; |
|||
uint8_t bIndex[2]; |
|||
uint16_t wLength; |
|||
} setup_packet; |
|||
|
|||
enum libusb_request_type { |
|||
LIBUSB_REQUEST_TYPE_STANDARD = (0x00 << 5), |
|||
LIBUSB_REQUEST_TYPE_CLASS = (0x01 << 5), |
|||
LIBUSB_REQUEST_TYPE_VENDOR = (0x02 << 5), |
|||
LIBUSB_REQUEST_TYPE_RESERVED = (0x03 << 5), |
|||
}; |
|||
|
|||
enum libusb_request_recipient { |
|||
LIBUSB_RECIPIENT_DEVICE = 0x00, |
|||
LIBUSB_RECIPIENT_INTERFACE = 0x01, |
|||
LIBUSB_RECIPIENT_ENDPOINT = 0x02, |
|||
LIBUSB_RECIPIENT_OTHER = 0x03, |
|||
}; |
|||
|
|||
enum libusb_endpoint_direction { |
|||
LIBUSB_ENDPOINT_IN = 0x80, |
|||
LIBUSB_ENDPOINT_OUT = 0x00, |
|||
}; |
|||
|
|||
extern usb_error usb_control_transfer(const setup_packet *const cmd_packet, |
|||
void *const buffer, |
|||
const uint8_t device_address, |
|||
const uint8_t max_packet_size); |
|||
|
|||
extern usb_error |
|||
usb_data_in_transfer(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint); |
|||
|
|||
extern usb_error |
|||
usb_data_in_transfer_n(uint8_t *buffer, uint8_t *const buffer_size, const uint8_t device_address, endpoint_param *const endpoint); |
|||
|
|||
extern usb_error |
|||
usb_data_out_transfer(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint); |
|||
|
|||
#endif |
|||
@ -0,0 +1,76 @@ |
|||
#include "usb-base-drv.h" |
|||
#include "ch376.h" |
|||
#include "enumerate.h" |
|||
#include "work-area.h" |
|||
#include <string.h> |
|||
|
|||
static usb_error usb_host_bus_reset(void) { |
|||
ch_cmd_set_usb_mode(CH_MODE_HOST); |
|||
delay_20ms(); |
|||
|
|||
ch_cmd_set_usb_mode(CH_MODE_HOST_RESET); |
|||
delay_20ms(); |
|||
|
|||
ch_cmd_set_usb_mode(CH_MODE_HOST); |
|||
delay_20ms(); |
|||
|
|||
ch_configure_nak_retry_3s(); |
|||
|
|||
return USB_ERR_OK; |
|||
} |
|||
|
|||
#define ERASE_LINE "\x1B\x6C\r$" |
|||
|
|||
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; |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
#ifndef __USB_BASE_DRV |
|||
#define __USB_BASE_DRV |
|||
|
|||
#include "dev_transfers.h" |
|||
#include "usb_state.h" |
|||
#include <stdint.h> |
|||
|
|||
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 |
|||
@ -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; |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
#ifndef __USB_STATE |
|||
#define __USB_STATE |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include <stdlib.h> |
|||
|
|||
#define MAX_NUMBER_OF_DEVICES 6 |
|||
#define DEVICE_CONFIG_STRUCT_SIZE sizeof(device_config_storage) /* Assumes is largest struct */ |
|||
|
|||
typedef struct __usb_state { |
|||
uint8_t active : 1; /* if true, a usb operation/interrupt handler is active, prevent re-entrant */ |
|||
uint8_t reserved : 7; |
|||
uint8_t count_of_detected_usb_devices; |
|||
uint8_t device_configs[DEVICE_CONFIG_STRUCT_SIZE * MAX_NUMBER_OF_DEVICES]; |
|||
|
|||
uint8_t device_configs_end; // always zero to mark end
|
|||
} _usb_state; |
|||
|
|||
extern device_config *find_first_free(void); |
|||
extern 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 |
|||
@ -0,0 +1,3 @@ |
|||
#include "usb_state.h" |
|||
|
|||
_usb_state x = {0, 0, 0}; |
|||
@ -0,0 +1,54 @@ |
|||
#ifndef __WORK_AREA |
|||
#define __WORK_AREA |
|||
|
|||
#include "ch376.h" |
|||
#include "protocol.h" |
|||
#include "stdlib.h" |
|||
#include "usb_state.h" |
|||
|
|||
#define PRES_CF 1 /* BIT MASK FOR COMPACTFLASH PRESENT */ |
|||
#define PRES_MS 2 /* BIT MASK FOR MSX MUSIC NOR FLASH PRESENT */ |
|||
#define PRES_USB1 4 /* BIT MASK FOR USB1 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_USB2 8 /* BIT MASK FOR USB2 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_USB3 16 /* BIT MASK FOR USB3 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_USB4 32 /* BIT MASK FOR USB4 STORAGE PRESENT AT BOOT UP */ |
|||
#define PRES_CH376 128 /* BIT MASK FOR CH376 PRESENT AT BOOT UP */ |
|||
|
|||
#define BIT_PRES_CF 0 /* BIT POSTION FOR COMPACTFLASH PRESENT */ |
|||
#define BIT_PRES_MS 1 /* BIT POSTION FOR MSX MUSIC NOR FLASH PRESENT */ |
|||
#define BIT_PRES_USB1 2 /* BIT POSTION FOR USB1 STORAGE PRESENT */ |
|||
#define BIT_PRES_USB2 3 /* BIT POSTION FOR USB2 STORAGE PRESENT */ |
|||
#define BIT_PRES_USB3 4 /* BIT POSTION FOR USB3 STORAGE PRESENT */ |
|||
#define BIT_PRES_USB4 5 /* BIT POSTION FOR USB4 STORAGE PRESENT */ |
|||
#define BIT_PRES_CH376 7 /* BIT POSTION FOR CH376 PRESENT */ |
|||
|
|||
typedef enum { |
|||
DEV_MAP_NONE = 0, |
|||
DEV_MAP_ROM = 1, |
|||
DEV_MAP_CF = 2, |
|||
DEV_MAP_MS = 3, |
|||
DEV_MAP_USB1 = 4, |
|||
DEV_MAP_USB2 = 5, |
|||
DEV_MAP_USB3 = 6, |
|||
DEV_MAP_USB4 = 7 |
|||
} device_map; |
|||
|
|||
typedef struct _work_area { |
|||
uint8_t read_count; /* COUNT OF SECTORS TO BE READ */ |
|||
uint16_t index; /* sector number to be read */ |
|||
uint8_t *dest; /* destination write address */ |
|||
uint8_t read_count_requested; /* number of sectors requested */ |
|||
uint8_t present; /* BIT FIELD FOR DETECTED DEVICES
|
|||
(BIT 0 -> COMPACTFLASH/IDE, BIT 1-> MSX-MUSIC NOR FLASH, BITS 2-5 FOR USB)*/ |
|||
_usb_state ch376; |
|||
} work_area; |
|||
|
|||
// extern work_area *get_work_area(void);
|
|||
|
|||
extern uint8_t get_number_of_usb_drives(void); |
|||
|
|||
extern _usb_state x; |
|||
|
|||
#define get_usb_work_area() (&x) |
|||
|
|||
#endif |
|||
@ -0,0 +1,54 @@ |
|||
#!/bin/sh |
|||
|
|||
# Check if exactly two arguments are provided |
|||
if [ "$#" -ne 2 ]; then |
|||
echo "Usage: $0 <source_file> <destination_file>" |
|||
exit 1 |
|||
fi |
|||
|
|||
source_file="$1" |
|||
destination_file="$2" |
|||
|
|||
rm -f "$destination_file" |
|||
|
|||
# create a unique prefix for all generated labels |
|||
prefix=$(basename "$source_file" | cut -d. -f1 | tr '-' '_') |
|||
|
|||
sed -E \ |
|||
-e "1i\;\r\n; Generated from source-doc/${source_file} -- not to be modify directly\r\n;\r\n; " \ |
|||
-e '/SECTION IGNORE/d' \ |
|||
-e '/\sEXTERN\s/d' \ |
|||
-e '/\sGLOBAL\s/d' \ |
|||
-e '/SECTION .*/d' \ |
|||
-e 's/^IF 0/#IF 0/g' \ |
|||
-e 's/^ENDIF/#ENDIF/g' \ |
|||
-e 's/\s+cp\s+a,\((ix\+[0-9-]+)\)/\tcp\t\(\1\)/g' \ |
|||
-e 's/\s+sub\s+a,\((iy\+[0-9]+)\)/\tsub\t\(\1\)/g' \ |
|||
-e 's/\s+sub\s+a,\((ix\+[0-9]+)\)/\tsub\t\(\1\)/g' \ |
|||
-e 's/\s+sub\s+a,\((ix-[0-9]+)\)/\tsub\t\(\1\)/g' \ |
|||
-e 's/\s+or\s+a,\((ix\+[0-9-]+)\)/\tor\t\(\1\)/g' \ |
|||
-e 's/\s+or\s+a,\((ix\-[0-9-]+)\)/\tor\t\(\1\)/g' \ |
|||
-e 's/\s+or\s+a,\((iy\+[0-9-]+)\)/\tor\t\(\1\)/g' \ |
|||
-e 's/\s+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' \ |
|||
@ -0,0 +1,24 @@ |
|||
#include "class_hid.h" |
|||
#include <stdint.h> |
|||
|
|||
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); |
|||
} |
|||
@ -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 |
|||
@ -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); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
#ifndef __CLASS_HID_KEYBOARD_H__ |
|||
#define __CLASS_HID_KEYBOARD_H__ |
|||
|
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
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 |
|||
@ -0,0 +1,25 @@ |
|||
#include "kyb_driver.h" |
|||
#include <print.h> |
|||
#include <stdint.h> |
|||
#include <usb_state.h> |
|||
|
|||
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; |
|||
} |
|||
@ -0,0 +1,136 @@ |
|||
#include "kyb_driver.h" |
|||
#include "class_hid.h" |
|||
#include "class_hid_keyboard.h" |
|||
#include <critical-section.h> |
|||
#include <dev_transfers.h> |
|||
#include <stdint.h> |
|||
#include <usb_state.h> |
|||
|
|||
#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); |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
#ifndef __KYB_DRIVER__ |
|||
#define __KYB_DRIVER__ |
|||
|
|||
#include <ch376.h> |
|||
#include <stdint.h> |
|||
|
|||
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 |
|||
@ -0,0 +1,77 @@ |
|||
#include "class_scsi.h" |
|||
#include <critical-section.h> |
|||
#include <string.h> |
|||
#include <usb_state.h> |
|||
#include <z80.h> |
|||
|
|||
_scsi_command_block_wrapper scsi_command_block_wrapper = {{0x55, 0x53, 0x42, 0x43}, {0, 0}, 0, 0, 0, 0}; |
|||
|
|||
uint16_t next_tag = 0; |
|||
|
|||
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); |
|||
} |
|||
@ -0,0 +1,196 @@ |
|||
#ifndef __CLASS_SCSI |
|||
#define __CLASS_SCSI |
|||
|
|||
#include <protocol.h> |
|||
|
|||
typedef struct { |
|||
uint8_t dCBWSignature[4]; |
|||
uint16_t dCBWTag[2]; |
|||
uint32_t dCBWDataTransferLength; |
|||
uint8_t bmCBWFlags; |
|||
uint8_t bCBWLUN; |
|||
uint8_t bCBWCBLength; |
|||
} _scsi_command_block_wrapper; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved1; |
|||
uint8_t reserved2; |
|||
uint8_t allocation_length; |
|||
uint8_t reserved3; |
|||
uint8_t pad[6]; |
|||
} _scsi_packet_request_sense; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_request_sense request_sense; |
|||
} cbw_scsi_request_sense; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
|
|||
uint8_t IMMED : 1; |
|||
uint8_t reserved : 7; |
|||
|
|||
uint8_t reserved2; |
|||
|
|||
uint8_t power_condition_modifier : 4; |
|||
uint8_t reserved3 : 4; |
|||
|
|||
uint8_t start : 1; |
|||
uint8_t loej : 1; |
|||
uint8_t no_flush : 1; |
|||
uint8_t reserved4 : 1; |
|||
uint8_t power_condition : 4; |
|||
|
|||
uint8_t control; |
|||
} _scsi_packet_eject; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_eject eject; |
|||
} cbw_scsi_eject; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved1; |
|||
uint8_t reserved2; |
|||
uint8_t reserved3; |
|||
uint8_t reserved4; |
|||
uint8_t pad[6]; |
|||
} _scsi_packet_test; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_test test; |
|||
} cbw_scsi_test; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved[8]; |
|||
uint8_t pad[2]; |
|||
} _scsi_read_capacity; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_read_capacity read_capacity; |
|||
} cbw_scsi_read_capacity; |
|||
|
|||
typedef struct __scsi_packet_inquiry { // contains information about a specific device
|
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t reserved1; |
|||
uint8_t reserved2; |
|||
uint8_t allocation_length; |
|||
uint8_t reserved3; |
|||
uint8_t pad[6]; |
|||
} _scsi_packet_inquiry; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_inquiry inquiry; |
|||
} cbw_scsi_inquiry; |
|||
|
|||
typedef struct { |
|||
uint8_t device_type : 5; |
|||
uint8_t device_type_qualifier : 3; |
|||
uint8_t device_type_modifier : 7; |
|||
uint8_t removable_media : 1; |
|||
union { |
|||
uint8_t versions; |
|||
struct { |
|||
uint8_t ansi_version : 3; |
|||
uint8_t ecma_version : 3; |
|||
uint8_t iso_version : 2; |
|||
}; |
|||
}; |
|||
uint8_t response_data_format : 4; |
|||
uint8_t hi_support : 1; |
|||
uint8_t norm_aca : 1; |
|||
uint8_t terminate_task : 1; |
|||
uint8_t aerc : 1; |
|||
uint8_t additional_length; |
|||
uint8_t reserved; |
|||
uint8_t addr16 : 1; |
|||
uint8_t addr32 : 1; |
|||
uint8_t ack_req_q : 1; |
|||
uint8_t medium_changer : 1; |
|||
uint8_t multi_port : 1; |
|||
uint8_t reserved_bit2 : 1; |
|||
uint8_t enclosure_services : 1; |
|||
uint8_t reserved_bit3 : 1; |
|||
uint8_t soft_reset : 1; |
|||
uint8_t command_queue : 1; |
|||
uint8_t transfer_disable : 1; |
|||
uint8_t linked_commands : 1; |
|||
uint8_t synchronous : 1; |
|||
uint8_t wide16_bit : 1; |
|||
uint8_t wide32_bit : 1; |
|||
uint8_t relative_addressing : 1; |
|||
uint8_t vendor_information[8]; |
|||
uint8_t product_id[16]; |
|||
uint8_t product_revision[4]; |
|||
uint8_t vendor_specific[20]; |
|||
uint8_t reserved3[40]; |
|||
} scsi_inquiry_result; |
|||
|
|||
typedef struct __scsi_command_status_wrapper { |
|||
uint8_t dCSWSignature[4]; |
|||
uint16_t dCSWTag[2]; |
|||
uint8_t dCSWDataResidue[4]; |
|||
uint8_t bCSWStatus; |
|||
} _scsi_command_status_wrapper; |
|||
|
|||
typedef struct { |
|||
uint8_t number_of_blocks[4]; |
|||
uint8_t block_size[4]; |
|||
} scsi_read_capacity_result; |
|||
|
|||
typedef struct { |
|||
uint8_t error_code : 7; |
|||
uint8_t valid : 1; |
|||
uint8_t segment_number; |
|||
uint8_t sense_key : 4; |
|||
uint8_t reserved : 1; |
|||
uint8_t incorrect_length : 1; |
|||
uint8_t end_of_media : 1; |
|||
uint8_t file_mark : 1; |
|||
uint8_t information[4]; |
|||
uint8_t additional_sense_length; |
|||
uint8_t command_specific_information[4]; |
|||
uint8_t additional_sense_code; |
|||
uint8_t additional_sense_code_qualifier; |
|||
uint8_t field_replaceable_unit_code; |
|||
uint8_t sense_key_specific[3]; |
|||
} scsi_sense_result; |
|||
|
|||
typedef struct { |
|||
uint8_t operation_code; |
|||
uint8_t lun; |
|||
uint8_t lba[4]; // high-endian block number
|
|||
uint8_t reserved1; |
|||
uint8_t transfer_len[2]; // high-endian in blocks of block_len (see scsi_capacity)
|
|||
uint8_t reserved2; |
|||
uint8_t pad[2]; |
|||
} _scsi_packet_read_write; |
|||
|
|||
typedef struct { |
|||
_scsi_command_block_wrapper cbw; |
|||
_scsi_packet_read_write scsi_cmd; |
|||
} cbw_scsi_read_write; |
|||
|
|||
extern _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 |
|||
@ -0,0 +1,30 @@ |
|||
#include "hbios-driver-storage.h" |
|||
#include "scsi_driver.h" |
|||
#include <hbios.h> |
|||
#include <print.h> |
|||
#include <string.h> |
|||
|
|||
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); |
|||
} |
|||
@ -0,0 +1,123 @@ |
|||
#include "scsi_driver.h" |
|||
#include "class_scsi.h" |
|||
#include <ch376.h> |
|||
#include <critical-section.h> |
|||
#include <string.h> |
|||
#include <usb_state.h> |
|||
|
|||
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);
|
|||
// }
|
|||
@ -0,0 +1,14 @@ |
|||
#ifndef __SCSI_DRIVER__ |
|||
#define __SCSI_DRIVER__ |
|||
|
|||
#include "class_scsi.h" |
|||
#include <ch376.h> |
|||
#include <stdint.h> |
|||
|
|||
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 |
|||
@ -0,0 +1,179 @@ |
|||
#include "class_ufi.h" |
|||
#include <delay.h> |
|||
#include <protocol.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <z80.h> |
|||
|
|||
const ufi_request_sense_command _ufi_cmd_request_sense = {0x03, 0, 0, 0, 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; |
|||
} |
|||
@ -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 <stdlib.h> |
|||
|
|||
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 |
|||
@ -0,0 +1,29 @@ |
|||
#include "hbios-driver-storage.h" |
|||
#include <hbios.h> |
|||
#include <print.h> |
|||
#include <usb_state.h> |
|||
|
|||
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); |
|||
} |
|||
@ -0,0 +1,85 @@ |
|||
#include "ufi_driver.h" |
|||
#include "class_ufi.h" |
|||
#include <dev_transfers.h> |
|||
#include <string.h> |
|||
|
|||
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; |
|||
} |
|||
@ -0,0 +1,11 @@ |
|||
#ifndef __UFI_DRIVER__ |
|||
#define __UFI_DRIVER__ |
|||
|
|||
#include <ch376.h> |
|||
#include <stdint.h> |
|||
|
|||
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 |
|||
@ -0,0 +1,69 @@ |
|||
#include "usb_cbi.h" |
|||
#include "dev_transfers.h" |
|||
#include "protocol.h" |
|||
#include <ch376.h> |
|||
#include <critical-section.h> |
|||
|
|||
setup_packet cbi2_adsc = {0x21, 0, {0, 0}, {255, 0}, 12}; // ;4th byte is interface number
|
|||
|
|||
// was no clear
|
|||
usb_error usb_execute_cbi(device_config *const storage_device, |
|||
const uint8_t *const cmd, |
|||
const bool send, |
|||
const uint16_t buffer_size, |
|||
uint8_t *const buffer, |
|||
uint8_t *const sense_codes) { |
|||
usb_error result; |
|||
const uint8_t interface_number = storage_device->interface_number; |
|||
|
|||
setup_packet adsc; |
|||
adsc = cbi2_adsc; |
|||
adsc.bIndex[0] = interface_number; |
|||
|
|||
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; |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
#ifndef __USB_CBI_H__ |
|||
#define __USB_CBI_H__ |
|||
|
|||
#include <ch376.h> |
|||
#include <dev_transfers.h> |
|||
|
|||
usb_error usb_execute_cbi(device_config *const storage_device, |
|||
const uint8_t *const cmd, |
|||
const bool send, |
|||
const uint16_t buffer_size, |
|||
uint8_t *const buffer, |
|||
uint8_t *const asc); |
|||
|
|||
#endif |
|||
@ -0,0 +1,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 |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue