Browse Source

ch376-native: native USB driver for the CH376 module

pull/592/head
Dean Netherton 2 years ago
parent
commit
ed47d2f8b6
  1. 20
      .vscode/settings.json
  2. 4
      Source/CBIOS/cbios.asm
  3. 1
      Source/Doc/SystemGuide.md
  4. 4
      Source/HBIOS/Config/RCEZ80_std.asm
  5. 4
      Source/HBIOS/cfg_MASTER.asm
  6. 133
      Source/HBIOS/ch376-native/Makefile
  7. 109
      Source/HBIOS/ch376-native/base-drv.asm
  8. 14
      Source/HBIOS/ch376-native/base-drv.s
  9. 780
      Source/HBIOS/ch376-native/base-drv/ch376.c.s
  10. 98
      Source/HBIOS/ch376-native/base-drv/class_hub.c.s
  11. 454
      Source/HBIOS/ch376-native/base-drv/dev_transfers.c.s
  12. 948
      Source/HBIOS/ch376-native/base-drv/enumerate.c.s
  13. 470
      Source/HBIOS/ch376-native/base-drv/enumerate_hub.c.s
  14. 142
      Source/HBIOS/ch376-native/base-drv/enumerate_storage.c.s
  15. 87
      Source/HBIOS/ch376-native/base-drv/print.c.s
  16. 478
      Source/HBIOS/ch376-native/base-drv/protocol.c.s
  17. 506
      Source/HBIOS/ch376-native/base-drv/transfers.c.s
  18. 86
      Source/HBIOS/ch376-native/base-drv/usb-base-drv.c.s
  19. 179
      Source/HBIOS/ch376-native/base-drv/usb-init.c.s
  20. 274
      Source/HBIOS/ch376-native/base-drv/usb_state.c.s
  21. 158
      Source/HBIOS/ch376-native/base-drv/work-area.c.s
  22. 134
      Source/HBIOS/ch376-native/cruntime.asm
  23. 32
      Source/HBIOS/ch376-native/print.asm
  24. 0
      Source/HBIOS/ch376-native/root.md
  25. 3
      Source/HBIOS/ch376-native/scsi-drv.s
  26. 952
      Source/HBIOS/ch376-native/scsi-drv/class_scsi.c.s
  27. 162
      Source/HBIOS/ch376-native/scsi-drv/init.c.s
  28. 125
      Source/HBIOS/ch376-native/scsi-drv/scsi-init.c.s
  29. 13
      Source/HBIOS/ch376-native/source-doc/.clang-format
  30. 238
      Source/HBIOS/ch376-native/source-doc/base-drv/ch376.c
  31. 175
      Source/HBIOS/ch376-native/source-doc/base-drv/ch376.h
  32. 1311
      Source/HBIOS/ch376-native/source-doc/base-drv/ch376inc.h
  33. 9
      Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.c
  34. 75
      Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.h
  35. 11
      Source/HBIOS/ch376-native/source-doc/base-drv/delay.h
  36. 101
      Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c
  37. 68
      Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.h
  38. 221
      Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.c
  39. 38
      Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.h
  40. 80
      Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.c
  41. 10
      Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.h
  42. 27
      Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.c
  43. 8
      Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.h
  44. 6
      Source/HBIOS/ch376-native/source-doc/base-drv/hbios.h
  45. 9
      Source/HBIOS/ch376-native/source-doc/base-drv/print.c
  46. 11
      Source/HBIOS/ch376-native/source-doc/base-drv/print.h
  47. 152
      Source/HBIOS/ch376-native/source-doc/base-drv/protocol.c
  48. 82
      Source/HBIOS/ch376-native/source-doc/base-drv/protocol.h
  49. 172
      Source/HBIOS/ch376-native/source-doc/base-drv/transfers.c
  50. 103
      Source/HBIOS/ch376-native/source-doc/base-drv/transfers.h
  51. 9
      Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.c
  52. 11
      Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.h
  53. 56
      Source/HBIOS/ch376-native/source-doc/base-drv/usb-init.c
  54. 90
      Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.c
  55. 27
      Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.h
  56. 3
      Source/HBIOS/ch376-native/source-doc/base-drv/work-area.c
  57. 54
      Source/HBIOS/ch376-native/source-doc/base-drv/work-area.h
  58. 17
      Source/HBIOS/ch376-native/source-doc/base-drv/z80.h
  59. 50
      Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh
  60. 106
      Source/HBIOS/ch376-native/source-doc/depends.d
  61. 168
      Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.c
  62. 196
      Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.h
  63. 35
      Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi-init.c
  64. 176
      Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.c
  65. 207
      Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.h
  66. 92
      Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi-init.c
  67. 64
      Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.c
  68. 14
      Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.h
  69. 4
      Source/HBIOS/ch376-native/ufi-drv.s
  70. 705
      Source/HBIOS/ch376-native/ufi-drv/class_ufi.c.s
  71. 319
      Source/HBIOS/ch376-native/ufi-drv/ufi-init.c.s
  72. 222
      Source/HBIOS/ch376-native/ufi-drv/usb_cbi.c.s
  73. 48
      Source/HBIOS/ch376.asm
  74. 284
      Source/HBIOS/ch376scsi.asm
  75. 225
      Source/HBIOS/ch376ufi.asm
  76. 40
      Source/HBIOS/hbios.asm
  77. 1
      Source/HBIOS/hbios.inc

20
.vscode/settings.json

@ -1,4 +1,22 @@
{
"files.trimTrailingWhitespace": false,
"files.eol": "\r\n"
"files.eol": "\r\n",
"files.associations": {
"*.inc": "z80-macroasm",
"*.asm": "z80-macroasm",
"*.180": "z80-macroasm",
"*.asm.m4": "z80-macroasm",
"*.inc.m4": "z80-macroasm",
"*.mac": "z80-macroasm",
"*.asmpp": "z80-macroasm",
"*.zdsproj": "xml",
"ch376.h": "c",
"protocol.h": "c",
"usb_state.h": "c",
"functional": "c",
"class_scsi.h": "c",
"z80.h": "c",
"dev_transfers.h": "c",
"usb-base-drv.h": "c"
}
}

4
Source/CBIOS/cbios.asm

@ -3407,6 +3407,7 @@ DEVTBL: ; DEVICE TABLE
.DW DEV04, DEV05, DEV06, DEV07
.DW DEV08, DEV09, DEV10, DEV11
.DW DEV12, DEV13, DEV14, DEV15
.DW DEV16
;
DEVUNK .DB "???$"
DEV00 .DB "MD$"
@ -3424,7 +3425,8 @@ DEV11 .DB "IMM$"
DEV12 .DB "SYQ$"
DEV13 .DB "CHUSB$"
DEV14 .DB "CHSD$"
DEV15 .EQU DEVUNK
DEV15 .DB "USB$"
DEV16 .EQU DEVUNK
;
#ENDIF
;

1
Source/Doc/SystemGuide.md

@ -1088,6 +1088,7 @@ below enumerates their values.
| DIODEV_SYQ | 0x0C | Syquest Sparq Disk | syq.asm |
| DIODEV_CHUSB | 0x0D | CH375/376 USB Disk | ch.asm |
| DIODEV_CHSD | 0x0E | CH375/376 SD Card | ch.asm |
| DIODEV_USB | 0x0F | CH376 Native USB Device | ch376.asm |
A fixed set of media types are defined. The currently defined media
types identifiers are listed below. Each driver will support one or

4
Source/HBIOS/Config/RCEZ80_std.asm

@ -82,3 +82,7 @@ SN76489ENABLE .SET FALSE ; SN: ENABLE SN76489 SOUND DRIVER
AY38910ENABLE .SET FALSE ; AY: ENABLE AY-3-8910 / YM2149 SOUND DRIVER
AYMODE .SET AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC|MBC|DUO|NABU]
AY_FORCE .SET FALSE ; AY: BYPASS AUTO-DETECT, FORCED PRESENT
CHNATIVEENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)

4
Source/HBIOS/cfg_MASTER.asm

@ -501,3 +501,7 @@ EZ80_WSMD_TYP .EQU EZ80WSMD_CALC ; BUS WAIT STATE CONFIG: EZ80WSMD_[CALC|CYCLES|
EZ80_FLSH_WS .EQU 1 ; WAIT STATES FOR ON CHIP FLASH (0-7)
EZ80_FLSH_MIN_NS .EQU 60 ; MINIMUM WAIT STATES TO APPLY TO ON-CHIP FLASH, IF EZ80_WSMD_TYP = EZ80WSMD_CALC
EZ80_FWSMD_TYP .EQU EZ80WSMD_CALC ; WAIT STATE TYPE: EZ80RMMD_[CALC|WAIT] (CYCLES NOT ALLOWED)
CHNATIVEENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)

133
Source/HBIOS/ch376-native/Makefile

@ -0,0 +1,133 @@
SHELL := /bin/bash
.SHELLFLAGS := -eu -o pipefail -c
.ONESHELL:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
ZCCRELFLAGS=
ifdef RELEASE
ZCCRELFLAGS=-SO3 --max-allocs-per-node600000 --allow-unsafe-read --opt-code-speed
endif
SRC := ./source-doc/
LIBS := -I./$(SRC)base-drv/
ZCC := zcc +msx --vc -subtype=rom -startup=1 -crt0 $(SRC)crt.asm -compiler=sdcc -Cs--std=c23 -Cs--Werror $(ZCCRELFLAGS) $(LIBS)
ASSDIR := ./
all: $(ASSDIR)base-drv.s $(ASSDIR)scsi-drv.s $(ASSDIR)ufi-drv.s
clean:
@rm -rf base-drv
@rm -rf scsi-drv
@rm -rf ufi-drv
$(ASSDIR)base-drv.s:
@echo "Creating base-drv.s"
echo "; Generated File -- not to be modify directly" > $(ASSDIR)base-drv.s
for dep in $^; do
dep=$${dep#*/}
dep=$${dep#*/}
echo '#include "'ch376-native/base-drv/$${dep}'"' >> $(ASSDIR)base-drv.s
done
$(ASSDIR)scsi-drv.s:
@echo "Creating scsi-drv.s"
echo "; Generated File -- not to be modify directly" > $(ASSDIR)scsi-drv.s
for dep in $^; do
dep=$${dep#*/}
dep=$${dep#*/}
echo '#include "'ch376-native/scsi-drv/$${dep}'"' >> $(ASSDIR)scsi-drv.s
done
$(ASSDIR)ufi-drv.s:
@echo "Creating ufi-drv.s"
echo "; Generated File -- not to be modify directly" > $(ASSDIR)ufi-drv.s
for dep in $^; do
dep=$${dep#*/}
dep=$${dep#*/}
echo '#include "'ch376-native/ufi-drv/$${dep}'"' >> $(ASSDIR)ufi-drv.s
done
$(ASSDIR)%.c.s: $(ASSDIR)%.c.asm
@mkdir -p $(dir $@)
echo "Converting $< to $@"
${SRC}convert-for-uz80as.sh $< $@
$(ASSDIR)%.s: $(SRC)%.asm
@mkdir -p $(dir $@)
cp $< $@
sed -i "1i\;\r\n; Generated from $< -- not to be modify directly\r\n;\r\n; " $@
define compile
@mkdir -p $(dir $@)
$(ZCC) --c-code-in-asm --assemble-only $< -o $@
echo "Compiled $(notdir $@) from $(notdir $<)"
endef
$(ASSDIR)base-drv/%.c.asm: $(SRC)base-drv/%.c; $(compile)
$(ASSDIR)scsi-drv/%.c.asm: $(SRC)scsi-drv/%.c; $(compile)
$(ASSDIR)ufi-drv/%.c.asm: $(SRC)ufi-drv/%.c; $(compile)
$(ASSDIR)%.c.asm: $(SRC)%.c; $(compile)
$(ASSDIR)libraries/delay/%.c.asm: ../apps/libraries/delay/%.c; $(compile)
$(ASSDIR)libraries/usb/%.c.asm: ../apps/libraries/usb/%.c; $(compile)
.PHONY: format
format: SHELL:=/bin/bash
format:
@clang-format --version
find \( -name "*.c" -o -name "*.h" \) -exec echo "formating {}" \; -exec clang-format -i {} \;
ZSDCPP_FLAGS=-iquote"." -isystem"${ZCCCFG}/../../include/_DEVELOPMENT/sdcc" $(LIBS)
include ${SRC}depends.d
deps:
@echo "" > ${SRC}/depends.d
# C Dependencies
(cd ${SRC} && find -name "*.c") | while read -r file; do
file_no_ext="$${file%.*}"
file_no_ext=$${file_no_ext#./}
filename=$$(basename $$file_no_ext)
from="$$filename.o"
to="${ASSDIR}$$file_no_ext.c.s"
sdcpp ${ZSDCPP_FLAGS} -MM -MF /tmp/deps.deps ./${SRC}$$file_no_ext.c
sed "s+$$from+$$to+g" /tmp/deps.deps >> ${SRC}/depends.d
done
# configure base-drv.s to all .s files
printf "##\r\n" >> ${SRC}/depends.d
printf "./base-drv.s: " >> ${SRC}/depends.d
(cd ${SRC}/base-drv && find -name "*.c") | while read -r file; do
file_no_ext="$${file%.*}"
file_no_ext=$${file_no_ext#./}
filename=$$(basename $$file_no_ext)
printf "base-drv/$$file.s " >> ${SRC}/depends.d
done
printf "\r\n" >> ${SRC}/depends.d
# # configure scsi-drv.s to all .s files
printf "##\r\n" >> ${SRC}/depends.d
printf "./scsi-drv.s: " >> ${SRC}/depends.d
(cd ${SRC}/scsi-drv && find -name "*.c") | while read -r file; do
file_no_ext="$${file%.*}"
file_no_ext=$${file_no_ext#./}
filename=$$(basename $$file_no_ext)
printf "scsi-drv/$$file.s " >> ${SRC}/depends.d
done
printf "\r\n" >> ${SRC}/depends.d
# # configure ufi-drv.s to all .s files
printf "##\r\n" >> ${SRC}/depends.d
printf "./ufi-drv.s: " >> ${SRC}/depends.d
(cd ${SRC}/ufi-drv && find -name "*.c") | while read -r file; do
file_no_ext="$${file%.*}"
file_no_ext=$${file_no_ext#./}
filename=$$(basename $$file_no_ext)
printf "ufi-drv/$$file.s " >> ${SRC}/depends.d
done
echo "" >> ${SRC}/depends.d
echo "${SRC}depends.d created"

109
Source/HBIOS/ch376-native/base-drv.asm

@ -0,0 +1,109 @@
DELAY_FACTOR .EQU 640
CMD01_RD_USB_DATA0 .EQU 0x27 ; Read data block from current USB interrupt endpoint buffer or host endpoint receive buffer
; output: length, data stream
CMD10_WR_HOST_DATA .EQU 0x2C ; Write a data block to the send buffer of the USB host endpoint
; input: length, data stream
CH_CMD_RD_USB_DATA0 .EQU CMD01_RD_USB_DATA0
CH_CMD_WR_HOST_DATA .EQU CMD10_WR_HOST_DATA
; HL -> timeout
; returns
; L -> error code
; ---------------------------------
; Function ch_wait_int_and_get_status
; ---------------------------------
_ch_wait_int_and_get_status:
ld bc, DELAY_FACTOR
keep_waiting:
CALL _delay
ld a, $FF
in a, (_CH376_COMMAND_PORT & 0xFF)
rlca
jp nc, _ch_get_status
dec bc
ld a, b
or c
jr nz, keep_waiting
dec hl
ld a, h
or l
jr nz, _ch_wait_int_and_get_status
CALL _delay
ld a, $FF
in a, (_CH376_COMMAND_PORT & 0xFF)
bit 4, a ; _CH376_COMMAND_PORT & PARA_STATE_BUSY
ld l, 0x0C ; USB_ERR_CH376_BLOCKED;
ret nz
ld l, 0x0D ; USB_ERR_CH376_TIMEOUT
ret
; uint8_t ch_read_data(uint8_t *buffer) __sdcccall(1);
_ch_read_data:
; ch_command(CH_CMD_RD_USB_DATA0);
push hl
ld l, CH_CMD_RD_USB_DATA0
call _ch_command
pop hl
CALL _delay
ld bc, _CH376_DATA_PORT
in a, (c)
or a
ret z
ld e, a
push af
read_block:
CALL _delay
in a, (c)
ld (hl), a
inc hl
dec e
jr nz, read_block
pop af
ret
;const uint8_t *ch_write_data(const uint8_t *buffer, uint8_t length)
_ch_write_data:
;libraries/usb/ch376.c:125: ch_command(CH_CMD_WR_HOST_DATA);
ld l, CH_CMD_WR_HOST_DATA
call _ch_command
ld iy, 2
add iy, sp
ld l, (iy+0)
ld h, (iy+1)
ld a, (iy+2)
ld bc, _CH376_DATA_PORT
; _CH376_DATA_PORT = length;
call _delay
out (c), a
or a
ret z
ld d, a
write_block:
call _delay
ld a, (hl)
out (c), a
inc hl
dec d
jr nz, write_block
ret

14
Source/HBIOS/ch376-native/base-drv.s

@ -0,0 +1,14 @@
; Generated File -- not to be modify directly
#include "ch376-native/base-drv/dev_transfers.c.s"
#include "ch376-native/base-drv/enumerate.c.s"
#include "ch376-native/base-drv/usb_state.c.s"
#include "ch376-native/base-drv/class_hub.c.s"
#include "ch376-native/base-drv/enumerate_storage.c.s"
#include "ch376-native/base-drv/enumerate_hub.c.s"
#include "ch376-native/base-drv/usb-base-drv.c.s"
#include "ch376-native/base-drv/transfers.c.s"
#include "ch376-native/base-drv/print.c.s"
#include "ch376-native/base-drv/ch376.c.s"
#include "ch376-native/base-drv/protocol.c.s"
#include "ch376-native/base-drv/work-area.c.s"
#include "ch376-native/base-drv/usb-init.c.s"

780
Source/HBIOS/ch376-native/base-drv/ch376.c.s

@ -0,0 +1,780 @@
;
; Generated from source-doc/base-drv/./ch376.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_result:
DEFS 1
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./ch376.c:7: void ch_command(const uint8_t command) __z88dk_fastcall {
; ---------------------------------
; Function ch_command
; ---------------------------------
_ch_command:
;source-doc/base-drv/./ch376.c:9: while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0)
ld h,0xff
l_ch_command_00102:
ld a, +((_CH376_COMMAND_PORT) / 256)
in a, (((_CH376_COMMAND_PORT) & 0xFF))
bit 4, a
jr Z,l_ch_command_00104
dec h
jr Z,l_ch_command_00104
;source-doc/base-drv/./ch376.c:10: delay();
push hl
call _delay
pop hl
jr l_ch_command_00102
l_ch_command_00104:
;source-doc/base-drv/./ch376.c:20: delay();
push hl
call _delay
pop hl
;source-doc/base-drv/./ch376.c:21: CH376_COMMAND_PORT = command;
ld a, l
ld bc,_CH376_COMMAND_PORT
out (c),a
;source-doc/base-drv/./ch376.c:22: delay();
;source-doc/base-drv/./ch376.c:23: }
jp _delay
;source-doc/base-drv/./ch376.c:27: usb_error ch_long_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(5000); }
; ---------------------------------
; Function ch_long_wait_int_and_get_status
; ---------------------------------
_ch_long_wait_int_and_get_statu:
ld hl,0x1388
jp _ch_wait_int_and_get_status
;source-doc/base-drv/./ch376.c:29: usb_error ch_short_wait_int_and_get_statu(void) { return ch_wait_int_and_get_status(100); }
; ---------------------------------
; Function ch_short_wait_int_and_get_statu
; ---------------------------------
_ch_short_wait_int_and_get_stat:
ld hl,0x0064
jp _ch_wait_int_and_get_status
;source-doc/base-drv/./ch376.c:31: usb_error ch_very_short_wait_int_and_get_(void) { return ch_wait_int_and_get_status(10); }
; ---------------------------------
; Function ch_very_short_wait_int_and_get_
; ---------------------------------
_ch_very_short_wait_int_and_get:
ld hl,0x000a
jp _ch_wait_int_and_get_status
;source-doc/base-drv/./ch376.c:33: usb_error ch_get_status(void) {
; ---------------------------------
; Function ch_get_status
; ---------------------------------
_ch_get_status:
;source-doc/base-drv/./ch376.c:34: ch_command(CH_CMD_GET_STATUS);
ld l,0x22
call _ch_command
;source-doc/base-drv/./ch376.c:35: uint8_t ch_status = CH376_DATA_PORT;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & 0xFF))
;source-doc/base-drv/./ch376.c:37: if (ch_status >= USB_FILERR_MIN && ch_status <= USB_FILERR_MAX)
ld l,a
sub 0x41
jr C,l_ch_get_status_00102
ld a,0xb4
sub l
;source-doc/base-drv/./ch376.c:38: return ch_status;
jr NC,l_ch_get_status_00126
l_ch_get_status_00102:
;source-doc/base-drv/./ch376.c:40: if (ch_status == CH_CMD_RET_SUCCESS)
ld a, l
;source-doc/base-drv/./ch376.c:41: return USB_ERR_OK;
sub 0x51
jr NZ,l_ch_get_status_00105
ld l,a
jr l_ch_get_status_00126
l_ch_get_status_00105:
;source-doc/base-drv/./ch376.c:43: if (ch_status == CH_USB_INT_SUCCESS)
ld a, l
;source-doc/base-drv/./ch376.c:44: return USB_ERR_OK;
sub 0x14
jr NZ,l_ch_get_status_00107
ld l,a
jr l_ch_get_status_00126
l_ch_get_status_00107:
;source-doc/base-drv/./ch376.c:46: if (ch_status == CH_USB_INT_CONNECT)
ld a, l
sub 0x15
jr NZ,l_ch_get_status_00109
;source-doc/base-drv/./ch376.c:47: return USB_INT_CONNECT;
ld l,0x81
jr l_ch_get_status_00126
l_ch_get_status_00109:
;source-doc/base-drv/./ch376.c:49: if (ch_status == CH_USB_INT_DISK_READ)
ld a, l
sub 0x1d
jr NZ,l_ch_get_status_00111
;source-doc/base-drv/./ch376.c:50: return USB_ERR_DISK_READ;
ld l,0x1d
jr l_ch_get_status_00126
l_ch_get_status_00111:
;source-doc/base-drv/./ch376.c:52: if (ch_status == CH_USB_INT_DISK_WRITE)
ld a, l
sub 0x1e
jr NZ,l_ch_get_status_00113
;source-doc/base-drv/./ch376.c:53: return USB_ERR_DISK_WRITE;
ld l,0x1e
jr l_ch_get_status_00126
l_ch_get_status_00113:
;source-doc/base-drv/./ch376.c:55: if (ch_status == CH_USB_INT_DISCONNECT) {
ld a, l
sub 0x16
jr NZ,l_ch_get_status_00115
;source-doc/base-drv/./ch376.c:56: ch_cmd_set_usb_mode(5);
ld l,0x05
call _ch_cmd_set_usb_mode
;source-doc/base-drv/./ch376.c:57: return USB_ERR_NO_DEVICE;
ld l,0x05
jr l_ch_get_status_00126
l_ch_get_status_00115:
;source-doc/base-drv/./ch376.c:60: if (ch_status == CH_USB_INT_BUF_OVER)
ld a, l
sub 0x17
jr NZ,l_ch_get_status_00117
;source-doc/base-drv/./ch376.c:61: return USB_ERR_DATA_ERROR;
ld l,0x04
jr l_ch_get_status_00126
l_ch_get_status_00117:
;source-doc/base-drv/./ch376.c:63: ch_status &= 0x2F;
ld a, l
and 0x2f
;source-doc/base-drv/./ch376.c:65: if (ch_status == 0x2A)
cp 0x2a
jr NZ,l_ch_get_status_00119
;source-doc/base-drv/./ch376.c:66: return USB_ERR_NAK;
ld l,0x01
jr l_ch_get_status_00126
l_ch_get_status_00119:
;source-doc/base-drv/./ch376.c:68: if (ch_status == 0x2E)
cp 0x2e
jr NZ,l_ch_get_status_00121
;source-doc/base-drv/./ch376.c:69: return USB_ERR_STALL;
ld l,0x02
jr l_ch_get_status_00126
l_ch_get_status_00121:
;source-doc/base-drv/./ch376.c:71: ch_status &= 0x23;
and 0x23
;source-doc/base-drv/./ch376.c:73: if (ch_status == 0x20)
cp 0x20
jr NZ,l_ch_get_status_00123
;source-doc/base-drv/./ch376.c:74: return USB_ERR_TIMEOUT;
ld l,0x03
jr l_ch_get_status_00126
l_ch_get_status_00123:
;source-doc/base-drv/./ch376.c:76: if (ch_status == 0x23)
sub 0x23
jr NZ,l_ch_get_status_00125
;source-doc/base-drv/./ch376.c:77: return USB_TOKEN_OUT_OF_SYNC;
ld l,0x07
jr l_ch_get_status_00126
l_ch_get_status_00125:
;source-doc/base-drv/./ch376.c:79: return USB_ERR_UNEXPECTED_STATUS_FROM_;
ld l,0x08
l_ch_get_status_00126:
;source-doc/base-drv/./ch376.c:80: }
ret
;source-doc/base-drv/./ch376.c:82: void ch_cmd_reset_all(void) { ch_command(CH_CMD_RESET_ALL); }
; ---------------------------------
; Function ch_cmd_reset_all
; ---------------------------------
_ch_cmd_reset_all:
ld l,0x05
jp _ch_command
;source-doc/base-drv/./ch376.c:101: uint8_t ch_probe(void) {
; ---------------------------------
; Function ch_probe
; ---------------------------------
_ch_probe:
;source-doc/base-drv/./ch376.c:103: do {
ld c,0x05
l_ch_probe_00103:
;source-doc/base-drv/./ch376.c:86: ch_command(CH_CMD_CHECK_EXIST);
push bc
ld l,0x06
call _ch_command
pop bc
;source-doc/base-drv/./ch376.c:87: CH376_DATA_PORT = (uint8_t)~0x55;
ld a,0xaa
push bc
ld bc,_CH376_DATA_PORT
out (c),a
call _delay
pop bc
;source-doc/base-drv/./ch376.c:89: complement = CH376_DATA_PORT;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & 0xFF))
;source-doc/base-drv/./ch376.c:90: return complement == 0x55;
sub 0x55
jr NZ,l_ch_probe_00102
;source-doc/base-drv/./ch376.c:104: if (ch_cmd_check_exist())
;source-doc/base-drv/./ch376.c:105: return true;
ld l,0x01
jr l_ch_probe_00107
l_ch_probe_00102:
;source-doc/base-drv/./ch376.c:107: delay_medium();
push bc
call _delay_medium
pop bc
;source-doc/base-drv/./ch376.c:108: } while (--i != 0);
dec c
ld a, c
;source-doc/base-drv/./ch376.c:110: return false;
or a
jr NZ,l_ch_probe_00103
ld l,a
l_ch_probe_00107:
;source-doc/base-drv/./ch376.c:111: }
ret
;source-doc/base-drv/./ch376.c:113: uint8_t ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall {
; ---------------------------------
; Function ch_cmd_set_usb_mode
; ---------------------------------
_ch_cmd_set_usb_mode:
;source-doc/base-drv/./ch376.c:114: uint8_t result = 0;
ld h,0x00
;source-doc/base-drv/./ch376.c:116: CH376_COMMAND_PORT = CH_CMD_SET_USB_MODE;
ld a,0x15
ld bc,_CH376_COMMAND_PORT
out (c),a
;source-doc/base-drv/./ch376.c:117: delay();
push hl
call _delay
pop hl
;source-doc/base-drv/./ch376.c:118: CH376_DATA_PORT = mode;
ld a, l
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./ch376.c:119: delay();
push hl
call _delay
pop hl
;source-doc/base-drv/./ch376.c:123: while (result != CH_CMD_RET_SUCCESS && result != CH_CMD_RET_ABORT && --count != 0) {
ld l,0x7f
l_ch_cmd_set_usb_mode_00103:
ld a, h
sub 0x51
jr NZ,l_ch_cmd_set_usb_mode_00136
ld a,0x01
jr l_ch_cmd_set_usb_mode_00137
l_ch_cmd_set_usb_mode_00136:
xor a
l_ch_cmd_set_usb_mode_00137:
ld c,a
bit 0,a
jr NZ,l_ch_cmd_set_usb_mode_00105
ld a, h
sub 0x5f
jr Z,l_ch_cmd_set_usb_mode_00105
dec l
jr Z,l_ch_cmd_set_usb_mode_00105
;source-doc/base-drv/./ch376.c:124: result = CH376_DATA_PORT;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & 0xFF))
ld h, a
;source-doc/base-drv/./ch376.c:125: delay();
push hl
call _delay
pop hl
jr l_ch_cmd_set_usb_mode_00103
l_ch_cmd_set_usb_mode_00105:
;source-doc/base-drv/./ch376.c:128: return (result == CH_CMD_RET_SUCCESS) ? USB_ERR_OK : USB_ERR_FAIL;
ld a, c
or a
jr Z,l_ch_cmd_set_usb_mode_00108
ld hl,0x0000
jr l_ch_cmd_set_usb_mode_00109
l_ch_cmd_set_usb_mode_00108:
ld hl,0x000e
l_ch_cmd_set_usb_mode_00109:
;source-doc/base-drv/./ch376.c:129: }
ret
;source-doc/base-drv/./ch376.c:131: uint8_t ch_cmd_get_ic_version(void) {
; ---------------------------------
; Function ch_cmd_get_ic_version
; ---------------------------------
_ch_cmd_get_ic_version:
;source-doc/base-drv/./ch376.c:132: ch_command(CH_CMD_GET_IC_VER);
ld l,0x01
call _ch_command
;source-doc/base-drv/./ch376.c:133: return CH376_DATA_PORT & 0x1f;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & 0xFF))
and 0x1f
ld l, a
;source-doc/base-drv/./ch376.c:134: }
ret
;source-doc/base-drv/./ch376.c:136: void ch_issue_token(const uint8_t toggle_bit, const uint8_t endpoint, const ch376_pid pid) {
; ---------------------------------
; Function ch_issue_token
; ---------------------------------
_ch_issue_token:
;source-doc/base-drv/./ch376.c:137: ch_command(CH_CMD_ISSUE_TKN_X);
ld l,0x4e
call _ch_command
;source-doc/base-drv/./ch376.c:138: CH376_DATA_PORT = toggle_bit;
ld hl,2+0
add hl, sp
ld a, (hl)
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./ch376.c:139: delay();
call _delay
;source-doc/base-drv/./ch376.c:140: CH376_DATA_PORT = endpoint << 4 | pid;
ld iy,3
add iy, sp
ld a,(iy+0)
add a, a
add a, a
add a, a
add a, a
inc iy
or (iy+0)
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./ch376.c:141: delay();
;source-doc/base-drv/./ch376.c:142: }
jp _delay
;source-doc/base-drv/./ch376.c:144: void ch_issue_token_in(const endpoint_param *const endpoint) __z88dk_fastcall {
; ---------------------------------
; Function ch_issue_token_in
; ---------------------------------
_ch_issue_token_in:
;source-doc/base-drv/./ch376.c:145: ch_issue_token(endpoint->toggle ? 0x80 : 0x00, endpoint->number, CH_PID_IN);
ld e,l
ld d,h
ld a, (hl)
rrca
and 0x07
ld b, a
ex de, hl
ld a, (hl)
and 0x01
jr Z,l_ch_issue_token_in_00103
ld a,0x80
jr l_ch_issue_token_in_00104
l_ch_issue_token_in_00103:
xor a
l_ch_issue_token_in_00104:
ld h,0x09
ld l,b
push hl
push af
inc sp
call _ch_issue_token
pop af
inc sp
;source-doc/base-drv/./ch376.c:146: }
ret
;source-doc/base-drv/./ch376.c:148: void ch_issue_token_out(const endpoint_param *const endpoint) __z88dk_fastcall {
; ---------------------------------
; Function ch_issue_token_out
; ---------------------------------
_ch_issue_token_out:
;source-doc/base-drv/./ch376.c:149: ch_issue_token(endpoint->toggle ? 0x40 : 0x00, endpoint->number, CH_PID_OUT);
ld e,l
ld d,h
ld a, (hl)
rrca
and 0x07
ld b, a
ex de, hl
ld a, (hl)
and 0x01
jr Z,l_ch_issue_token_out_00103
ld a,0x40
jr l_ch_issue_token_out_00104
l_ch_issue_token_out_00103:
xor a
l_ch_issue_token_out_00104:
ld h,0x01
ld l,b
push hl
push af
inc sp
call _ch_issue_token
pop af
inc sp
;source-doc/base-drv/./ch376.c:150: }
ret
;source-doc/base-drv/./ch376.c:152: void ch_issue_token_out_ep0(void) { ch_issue_token(0x40, 0, CH_PID_OUT); }
; ---------------------------------
; Function ch_issue_token_out_ep0
; ---------------------------------
_ch_issue_token_out_ep0:
ld a,0x01
push af
inc sp
xor a
ld d,a
ld e,0x40
push de
call _ch_issue_token
pop af
inc sp
ret
;source-doc/base-drv/./ch376.c:154: void ch_issue_token_in_ep0(void) { ch_issue_token(0x80, 0, CH_PID_IN); }
; ---------------------------------
; Function ch_issue_token_in_ep0
; ---------------------------------
_ch_issue_token_in_ep0:
ld a,0x09
push af
inc sp
xor a
ld d,a
ld e,0x80
push de
call _ch_issue_token
pop af
inc sp
ret
;source-doc/base-drv/./ch376.c:156: void ch_issue_token_setup(void) { ch_issue_token(0, 0, CH_PID_SETUP); }
; ---------------------------------
; Function ch_issue_token_setup
; ---------------------------------
_ch_issue_token_setup:
ld a,0x0d
push af
inc sp
xor a
push af
inc sp
xor a
push af
inc sp
call _ch_issue_token
pop af
inc sp
ret
;source-doc/base-drv/./ch376.c:158: usb_error ch_data_in_transfer(uint8_t *buffer, int16_t buffer_size, endpoint_param *const endpoint) {
; ---------------------------------
; Function ch_data_in_transfer
; ---------------------------------
_ch_data_in_transfer:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/./ch376.c:162: if (buffer_size == 0)
ld a,(ix+7)
or (ix+6)
jr NZ,l_ch_data_in_transfer_00102
;source-doc/base-drv/./ch376.c:163: return USB_ERR_OK;
ld l,0x00
jp l_ch_data_in_transfer_00110
l_ch_data_in_transfer_00102:
;source-doc/base-drv/./ch376.c:165: USB_MODULE_LEDS = 0x01;
ld a,0x01
ld bc,_USB_MODULE_LEDS
out (c),a
;source-doc/base-drv/./ch376.c:166: do {
ld c,(ix+8)
ld b,(ix+9)
pop de
push bc
l_ch_data_in_transfer_00107:
;source-doc/base-drv/./ch376.c:167: ch_issue_token_in(endpoint);
ld l,c
ld h,b
push hl
call _ch_issue_token_in
call _ch_long_wait_int_and_get_statu
ld a, l
pop bc
ld l, a
;source-doc/base-drv/./ch376.c:170: CHECK(result);
or a
jr NZ,l_ch_data_in_transfer_00110
;source-doc/base-drv/./ch376.c:172: endpoint->toggle = !endpoint->toggle;
ld e, c
ld d, b
pop hl
ld a,(hl)
push hl
and 0x01
xor 0x01
and 0x01
ld l, a
ld a, (de)
and 0xfe
or l
ld (de), a
;source-doc/base-drv/./ch376.c:174: count = ch_read_data(buffer);
push bc
ld l,(ix+4)
ld h,(ix+5)
call _ch_read_data
pop bc
;source-doc/base-drv/./ch376.c:176: if (count == 0) {
ld e,a
;source-doc/base-drv/./ch376.c:177: USB_MODULE_LEDS = 0x00;
or a
jr NZ,l_ch_data_in_transfer_00106
ld bc,_USB_MODULE_LEDS
out (c),a
;source-doc/base-drv/./ch376.c:178: return USB_ERR_DATA_ERROR;
ld l,0x04
jr l_ch_data_in_transfer_00110
l_ch_data_in_transfer_00106:
;source-doc/base-drv/./ch376.c:181: buffer += count;
ld a, e
add a,(ix+4)
ld (ix+4),a
ld a,0x00
adc a,(ix+5)
ld (ix+5),a
;source-doc/base-drv/./ch376.c:182: buffer_size -= count;
ld d,0x00
ld a,(ix+6)
sub e
ld (ix+6),a
ld a,(ix+7)
sbc a, d
ld (ix+7),a
;source-doc/base-drv/./ch376.c:183: } while (buffer_size > 0);
xor a
cp (ix+6)
sbc a,(ix+7)
jp PO, l_ch_data_in_transfer_00137
xor 0x80
l_ch_data_in_transfer_00137:
jp M, l_ch_data_in_transfer_00107
;source-doc/base-drv/./ch376.c:185: USB_MODULE_LEDS = 0x00;
ld a,0x00
ld bc,_USB_MODULE_LEDS
out (c),a
;source-doc/base-drv/./ch376.c:187: return USB_ERR_OK;
ld l,0x00
l_ch_data_in_transfer_00110:
;source-doc/base-drv/./ch376.c:188: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./ch376.c:190: usb_error ch_data_in_transfer_n(uint8_t *const buffer, int8_t *const buffer_size, endpoint_param *const endpoint) {
; ---------------------------------
; Function ch_data_in_transfer_n
; ---------------------------------
_ch_data_in_transfer_n:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./ch376.c:194: USB_MODULE_LEDS = 0x01;
ld a,0x01
ld bc,_USB_MODULE_LEDS
out (c),a
;source-doc/base-drv/./ch376.c:196: ch_issue_token_in(endpoint);
ld l,(ix+8)
ld h,(ix+9)
call _ch_issue_token_in
;source-doc/base-drv/./ch376.c:198: CHECK(ch_long_wait_int_and_get_status());
call _ch_long_wait_int_and_get_statu
ld a,l
or a
jr NZ,l_ch_data_in_transfer_n_00103
;source-doc/base-drv/./ch376.c:200: endpoint->toggle = !endpoint->toggle;
ld l,(ix+8)
ld h,(ix+9)
ld a,(hl)
and 0x01
xor 0x01
and 0x01
ld e,a
ld a,(hl)
and 0xfe
or e
ld (hl),a
;source-doc/base-drv/./ch376.c:202: count = ch_read_data(buffer);
ld l,(ix+4)
ld h,(ix+5)
call _ch_read_data
;source-doc/base-drv/./ch376.c:204: *buffer_size = count;
ld c,(ix+6)
ld b,(ix+7)
ld (bc), a
;source-doc/base-drv/./ch376.c:206: USB_MODULE_LEDS = 0x00;
ld a,0x00
ld bc,_USB_MODULE_LEDS
out (c),a
;source-doc/base-drv/./ch376.c:208: return USB_ERR_OK;
ld l,0x00
l_ch_data_in_transfer_n_00103:
;source-doc/base-drv/./ch376.c:209: }
pop ix
ret
;source-doc/base-drv/./ch376.c:211: usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint) {
; ---------------------------------
; Function ch_data_out_transfer
; ---------------------------------
_ch_data_out_transfer:
push ix
ld ix,0
add ix,sp
push af
dec sp
;source-doc/base-drv/./ch376.c:214: const uint8_t max_packet_size = calc_max_packet_size(endpoint->max_packet_sizex);
ld c,(ix+8)
ld b,(ix+9)
ld e, c
ld d, b
inc de
ld a, (de)
ld (ix-3),a
;source-doc/base-drv/./ch376.c:216: USB_MODULE_LEDS = 0x02;
ld a,0x02
push bc
ld bc,_USB_MODULE_LEDS
out (c),a
pop bc
;source-doc/base-drv/./ch376.c:218: while (buffer_length > 0) {
ld (ix-2),c
ld (ix-1),b
l_ch_data_out_transfer_00103:
xor a
cp (ix+6)
sbc a,(ix+7)
jp PO, l_ch_data_out_transfer_00130
xor 0x80
l_ch_data_out_transfer_00130:
jp P, l_ch_data_out_transfer_00105
;source-doc/base-drv/./ch376.c:219: const uint8_t size = max_packet_size < buffer_length ? max_packet_size : buffer_length;
ld d,(ix-3)
ld e,0x00
ld a, d
sub (ix+6)
ld a, e
sbc a,(ix+7)
jp PO, l_ch_data_out_transfer_00131
xor 0x80
l_ch_data_out_transfer_00131:
jp P, l_ch_data_out_transfer_00108
jr l_ch_data_out_transfer_00109
l_ch_data_out_transfer_00108:
ld d,(ix+6)
ld e,(ix+7)
l_ch_data_out_transfer_00109:
;source-doc/base-drv/./ch376.c:220: buffer = ch_write_data(buffer, size);
push bc
push de
push de
inc sp
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ch_write_data
pop af
inc sp
pop de
pop bc
ld (ix+4),l
ld (ix+5),h
;source-doc/base-drv/./ch376.c:221: buffer_length -= size;
ld e,0x00
ld a,(ix+6)
sub d
ld (ix+6),a
ld a,(ix+7)
sbc a, e
ld (ix+7),a
;source-doc/base-drv/./ch376.c:222: ch_issue_token_out(endpoint);
ld l,c
ld h,b
push hl
call _ch_issue_token_out
call _ch_long_wait_int_and_get_statu
ld a, l
pop bc
ld l, a
or a
jr NZ,l_ch_data_out_transfer_00106
;source-doc/base-drv/./ch376.c:226: endpoint->toggle = !endpoint->toggle;
ld e, c
ld d, b
ld l,(ix-2)
ld h,(ix-1)
ld a, (hl)
and 0x01
xor 0x01
and 0x01
ld l, a
ld a, (de)
and 0xfe
or l
ld (de), a
jr l_ch_data_out_transfer_00103
l_ch_data_out_transfer_00105:
;source-doc/base-drv/./ch376.c:229: USB_MODULE_LEDS = 0x00;
ld a,0x00
ld bc,_USB_MODULE_LEDS
out (c),a
;source-doc/base-drv/./ch376.c:231: return USB_ERR_OK;
ld l,0x00
l_ch_data_out_transfer_00106:
;source-doc/base-drv/./ch376.c:232: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./ch376.c:234: void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall {
; ---------------------------------
; Function ch_set_usb_address
; ---------------------------------
_ch_set_usb_address:
;source-doc/base-drv/./ch376.c:235: ch_command(CH_CMD_SET_USB_ADDR);
push hl
ld l,0x13
call _ch_command
pop hl
;source-doc/base-drv/./ch376.c:236: CH376_DATA_PORT = device_address;
ld a, l
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./ch376.c:237: delay();
;source-doc/base-drv/./ch376.c:238: }
jp _delay
_result:
DEFB +0x00

98
Source/HBIOS/ch376-native/base-drv/class_hub.c.s

@ -0,0 +1,98 @@
;
; Generated from source-doc/base-drv/./class_hub.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./class_hub.c:7: usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1) {
; ---------------------------------
; Function hub_get_descriptor
; ---------------------------------
_hub_get_descriptor:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/./class_hub.c:8: return usb_control_transfer(&cmd_get_hub_descriptor, hub_description, hub_config->address, hub_config->max_packet_size);
ld c,l
ld b,h
inc hl
ld a, (hl)
ld (ix-1),a
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld b, a
ld a,(ix-1)
ld c,b
ld b,a
push bc
push de
ld hl,_cmd_get_hub_descriptor
push hl
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
;source-doc/base-drv/./class_hub.c:9: }
inc sp
pop ix
ret
_cmd_get_hub_descriptor:
DEFB +0xa0
DEFB +0x06
DEFB +0x00
DEFB +0x29
DEFB +0x00
DEFB +0x00
DEFW +0x0008

454
Source/HBIOS/ch376-native/base-drv/dev_transfers.c.s

@ -0,0 +1,454 @@
;
; Generated from source-doc/base-drv/./dev_transfers.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./dev_transfers.c:28: usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) {
; ---------------------------------
; Function usbdev_control_transfer
; ---------------------------------
_usbdev_control_transfer:
;source-doc/base-drv/./dev_transfers.c:29: return usb_control_transfer(cmd_packet, buffer, device->address, device->max_packet_size);
ld hl,2
add hl, sp
ld e, (hl)
inc hl
ld d, (hl)
ld l, e
ld h, d
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld iy,6
add iy, sp
ld e,(iy+0)
ld d,(iy+1)
ld c,a
push bc
push de
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
call _usb_control_transfer
pop af
pop af
pop af
;source-doc/base-drv/./dev_transfers.c:30: }
ret
;source-doc/base-drv/./dev_transfers.c:32: usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) {
; ---------------------------------
; Function usbdev_blk_out_trnsfer
; ---------------------------------
_usbdev_blk_out_trnsfer:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/./dev_transfers.c:36: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT];
ld c,(ix+4)
ld b,(ix+5)
ld e, c
ld d, b
inc de
inc de
inc de
;source-doc/base-drv/./dev_transfers.c:38: result = usb_data_out_transfer(buffer, buffer_size, dev->address, endpoint);
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
push bc
push de
push de
push af
inc sp
ld l,(ix+8)
ld h,(ix+9)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/./dev_transfers.c:40: if (result == USB_ERR_STALL) {
ld a, l
sub 0x02
jr NZ,l_usbdev_blk_out_trnsfer_00102
;source-doc/base-drv/./dev_transfers.c:41: usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size);
ld l, c
ld h, b
inc hl
ld a, (hl)
ld (ix-1),a
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld b, a
ld l, e
ld h, d
ld a, (hl)
rrca
and 0x07
push de
ld h,(ix-1)
ld l,b
push hl
push af
inc sp
call _usbtrn_clear_endpoint_halt
pop af
inc sp
pop de
;source-doc/base-drv/./dev_transfers.c:42: endpoint->toggle = 0;
ex de, hl
res 0, (hl)
;source-doc/base-drv/./dev_transfers.c:43: return USB_ERR_STALL;
ld l,0x02
;source-doc/base-drv/./dev_transfers.c:46: RETURN_CHECK(result);
l_usbdev_blk_out_trnsfer_00102:
;source-doc/base-drv/./dev_transfers.c:47: }
inc sp
pop ix
ret
;source-doc/base-drv/./dev_transfers.c:49: usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) {
; ---------------------------------
; Function usbdev_bulk_in_transfer
; ---------------------------------
_usbdev_bulk_in_transfer:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/./dev_transfers.c:53: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN];
ld c,(ix+4)
ld b,(ix+5)
ld hl,0x0006
add hl, bc
;source-doc/base-drv/./dev_transfers.c:55: result = usb_data_in_transfer_n(buffer, buffer_size, dev->address, endpoint);
ld e,c
ld d,b
ex de,hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
push bc
push de
push de
push af
inc sp
ld l,(ix+8)
ld h,(ix+9)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_in_transfer_n
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/./dev_transfers.c:57: if (result == USB_ERR_STALL) {
ld a, l
sub 0x02
jr NZ,l_usbdev_bulk_in_transfer_00102
;source-doc/base-drv/./dev_transfers.c:58: usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size);
ld l, c
ld h, b
inc hl
ld a, (hl)
ld (ix-1),a
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld b, a
ld l, e
ld h, d
ld a, (hl)
rrca
and 0x07
push de
ld h,(ix-1)
ld l,b
push hl
push af
inc sp
call _usbtrn_clear_endpoint_halt
pop af
inc sp
pop de
;source-doc/base-drv/./dev_transfers.c:59: endpoint->toggle = 0;
ex de, hl
res 0, (hl)
;source-doc/base-drv/./dev_transfers.c:60: return USB_ERR_STALL;
ld l,0x02
;source-doc/base-drv/./dev_transfers.c:63: RETURN_CHECK(result);
l_usbdev_bulk_in_transfer_00102:
;source-doc/base-drv/./dev_transfers.c:64: }
inc sp
pop ix
ret
;source-doc/base-drv/./dev_transfers.c:66: usb_error usbdev_dat_in_trnsfer(device_config *const device,
; ---------------------------------
; Function usbdev_dat_in_trnsfer
; ---------------------------------
_usbdev_dat_in_trnsfer:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/./dev_transfers.c:73: endpoint_param *const endpoint = &device->endpoints[endpoint_type];
ld c,(ix+4)
ld b,(ix+5)
ld e, c
ld d, b
inc de
inc de
inc de
push de
ld l,(ix+10)
ld e, l
add hl, hl
add hl, de
pop de
ld h,0x00
add hl, de
;source-doc/base-drv/./dev_transfers.c:75: result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint);
ld e,c
ld d,b
ex de,hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
push bc
push de
push de
push af
inc sp
ld l,(ix+8)
ld h,(ix+9)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/./dev_transfers.c:77: if (result == USB_ERR_STALL) {
ld a, l
sub 0x02
jr NZ,l_usbdev_dat_in_trnsfer_00102
;source-doc/base-drv/./dev_transfers.c:78: usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size);
ld l, c
ld h, b
inc hl
ld a, (hl)
ld (ix-1),a
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld b, a
ld l, e
ld h, d
ld a, (hl)
rrca
and 0x07
push de
ld h,(ix-1)
ld l,b
push hl
push af
inc sp
call _usbtrn_clear_endpoint_halt
pop af
inc sp
pop de
;source-doc/base-drv/./dev_transfers.c:79: endpoint->toggle = 0;
ex de, hl
res 0, (hl)
;source-doc/base-drv/./dev_transfers.c:80: return USB_ERR_STALL;
ld l,0x02
;source-doc/base-drv/./dev_transfers.c:83: RETURN_CHECK(result);
l_usbdev_dat_in_trnsfer_00102:
;source-doc/base-drv/./dev_transfers.c:84: }
inc sp
pop ix
ret
;source-doc/base-drv/./dev_transfers.c:86: usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) __sdcccall(1) {
; ---------------------------------
; Function usbdev_dat_in_trnsfer_0
; ---------------------------------
_usbdev_dat_in_trnsfer_0:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./dev_transfers.c:90: endpoint_param *const endpoint = &device->endpoints[0];
push hl
ld c,l
ld b,h
pop iy
inc iy
inc iy
inc iy
;source-doc/base-drv/./dev_transfers.c:92: result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint);
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld l,(ix+4)
ld h,0x00
push bc
push iy
push iy
push af
inc sp
push hl
push de
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
ld d, l
pop iy
pop bc
;source-doc/base-drv/./dev_transfers.c:94: if (result == USB_ERR_STALL) {
ld a, d
sub 0x02
jr NZ,l_usbdev_dat_in_trnsfer_0_00102
;source-doc/base-drv/./dev_transfers.c:95: usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size);
ld l, c
ld h, b
inc hl
ld d, (hl)
ld l, c
ld h, b
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld b, a
push iy
pop hl
ld a, (hl)
rrca
and 0x07
push iy
ld e,b
push de
push af
inc sp
call _usbtrn_clear_endpoint_halt
pop af
inc sp
pop iy
;source-doc/base-drv/./dev_transfers.c:96: endpoint->toggle = 0;
push iy
pop hl
res 0, (hl)
;source-doc/base-drv/./dev_transfers.c:97: return USB_ERR_STALL;
ld a,0x02
jr l_usbdev_dat_in_trnsfer_0_00103
l_usbdev_dat_in_trnsfer_0_00102:
;source-doc/base-drv/./dev_transfers.c:100: RETURN_CHECK(result);
ld a, d
l_usbdev_dat_in_trnsfer_0_00103:
;source-doc/base-drv/./dev_transfers.c:101: }
pop ix
pop hl
inc sp
jp (hl)

948
Source/HBIOS/ch376-native/base-drv/enumerate.c.s

@ -0,0 +1,948 @@
;
; Generated from source-doc/base-drv/./enumerate.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./enumerate.c:13: void parse_endpoint_keyboard(device_config_keyboard *const keyboard_config, const endpoint_descriptor const *pEndpoint)
; ---------------------------------
; Function parse_endpoint_keyboard
; ---------------------------------
_parse_endpoint_keyboard:
;source-doc/base-drv/./enumerate.c:15: endpoint_param *const ep = &keyboard_config->endpoints[0];
inc hl
inc hl
inc hl
push hl
pop iy
;source-doc/base-drv/./enumerate.c:16: ep->number = pEndpoint->bEndpointAddress;
push iy
pop bc
ld l, e
ld h, d
inc hl
inc hl
ld a, (hl)
rlca
and 0x0e
ld l, a
ld a, (bc)
and 0xf1
or l
ld (bc), a
;source-doc/base-drv/./enumerate.c:17: ep->toggle = 0;
push iy
pop hl
res 0, (hl)
;source-doc/base-drv/./enumerate.c:18: ep->max_packet_sizex = calc_max_packet_sizex(pEndpoint->wMaxPacketSize);
push iy
pop bc
inc bc
ld hl,4
add hl, de
ld e, (hl)
inc hl
ld a, (hl)
and 0x03
ld d, a
ld a, e
ld (bc), a
inc bc
ld a, d
and 0x03
ld l,a
ld a, (bc)
and 0xfc
or l
ld (bc), a
;source-doc/base-drv/./enumerate.c:19: }
ret
;source-doc/base-drv/./enumerate.c:21: usb_device_type identify_class_driver(_working *const working) {
; ---------------------------------
; Function identify_class_driver
; ---------------------------------
_identify_class_driver:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./enumerate.c:22: const interface_descriptor *const p = (const interface_descriptor *)working->ptr;
ld c,(ix+4)
ld b,(ix+5)
ld hl,27
add hl, bc
ld c, (hl)
inc hl
ld b, (hl)
;source-doc/base-drv/./enumerate.c:23: if (p->bInterfaceClass == 2)
push bc
pop iy
ld e,(iy+5)
ld a, e
sub 0x02
jr NZ,l_identify_class_driver_00102
;source-doc/base-drv/./enumerate.c:24: return USB_IS_CDC;
ld l,0x03
jr l_identify_class_driver_00118
l_identify_class_driver_00102:
;source-doc/base-drv/./enumerate.c:26: if (p->bInterfaceClass == 8 && (p->bInterfaceSubClass == 6 || p->bInterfaceSubClass == 5) && p->bInterfaceProtocol == 80)
ld a, e
sub 0x08
jr NZ,l_identify_class_driver_00177
ld a,0x01
jr l_identify_class_driver_00178
l_identify_class_driver_00177:
xor a
l_identify_class_driver_00178:
ld d,a
or a
jr Z,l_identify_class_driver_00104
ld hl,0x0006
add hl,bc
ld a, (hl)
cp 0x06
jr Z,l_identify_class_driver_00107
sub 0x05
jr NZ,l_identify_class_driver_00104
l_identify_class_driver_00107:
ld hl,0x0007
add hl,bc
ld a, (hl)
sub 0x50
jr NZ,l_identify_class_driver_00104
;source-doc/base-drv/./enumerate.c:27: return USB_IS_MASS_STORAGE;
ld l,0x02
jr l_identify_class_driver_00118
l_identify_class_driver_00104:
;source-doc/base-drv/./enumerate.c:29: if (p->bInterfaceClass == 8 && p->bInterfaceSubClass == 4 && p->bInterfaceProtocol == 0)
ld a, d
or a
jr Z,l_identify_class_driver_00109
ld hl,0x0006
add hl,bc
ld a, (hl)
sub 0x04
jr NZ,l_identify_class_driver_00109
ld hl,0x0007
add hl,bc
ld a, (hl)
or a
jr NZ,l_identify_class_driver_00109
;source-doc/base-drv/./enumerate.c:30: return USB_IS_FLOPPY;
ld l,0x01
jr l_identify_class_driver_00118
l_identify_class_driver_00109:
;source-doc/base-drv/./enumerate.c:32: if (p->bInterfaceClass == 9 && p->bInterfaceSubClass == 0 && p->bInterfaceProtocol == 0)
ld a, e
sub 0x09
jr NZ,l_identify_class_driver_00113
ld hl,0x0006
add hl,bc
ld a, (hl)
or a
jr NZ,l_identify_class_driver_00113
ld hl,7
add hl, bc
ld a, (hl)
or a
jr NZ,l_identify_class_driver_00113
;source-doc/base-drv/./enumerate.c:33: return USB_IS_HUB;
ld l,0x0f
jr l_identify_class_driver_00118
l_identify_class_driver_00113:
;source-doc/base-drv/./enumerate.c:35: if (p->bInterfaceClass == 3)
ld a, e
sub 0x03
jr NZ,l_identify_class_driver_00117
;source-doc/base-drv/./enumerate.c:36: return USB_IS_KEYBOARD;
ld l,0x04
jr l_identify_class_driver_00118
l_identify_class_driver_00117:
;source-doc/base-drv/./enumerate.c:38: return USB_IS_UNKNOWN;
ld l,0x06
l_identify_class_driver_00118:
;source-doc/base-drv/./enumerate.c:39: }
pop ix
ret
;source-doc/base-drv/./enumerate.c:41: usb_error op_interface_next(_working *const working) __z88dk_fastcall {
; ---------------------------------
; Function op_interface_next
; ---------------------------------
_op_interface_next:
ex de, hl
;source-doc/base-drv/./enumerate.c:42: if (--working->interface_count == 0)
ld hl,0x0016
add hl, de
ld a, (hl)
dec a
ld (hl), a
;source-doc/base-drv/./enumerate.c:43: return USB_ERR_OK;
or a
jr NZ,l_op_interface_next_00102
ld l,a
jr l_op_interface_next_00103
l_op_interface_next_00102:
;source-doc/base-drv/./enumerate.c:45: return op_id_class_drv(working);
ex de, hl
call _op_id_class_drv
ld l, a
l_op_interface_next_00103:
;source-doc/base-drv/./enumerate.c:46: }
ret
;source-doc/base-drv/./enumerate.c:48: usb_error op_endpoint_next(_working *const working) __sdcccall(1) {
; ---------------------------------
; Function op_endpoint_next
; ---------------------------------
_op_endpoint_next:
ex de, hl
;source-doc/base-drv/./enumerate.c:49: if (--working->endpoint_count > 0) {
ld hl,0x0017
add hl, de
ld a, (hl)
dec a
ld (hl), a
or a
jr Z,l_op_endpoint_next_00102
;source-doc/base-drv/./enumerate.c:50: working->ptr += ((endpoint_descriptor *)working->ptr)->bLength;
ld hl,0x001b
add hl, de
ld c, (hl)
inc hl
ld b, (hl)
dec hl
ld a, (bc)
add a, c
ld c, a
ld a,0x00
adc a, b
ld (hl), c
inc hl
ld (hl), a
;source-doc/base-drv/./enumerate.c:51: return op_parse_endpoint(working);
ex de, hl
jp _op_parse_endpoint
jr l_op_endpoint_next_00103
l_op_endpoint_next_00102:
;source-doc/base-drv/./enumerate.c:54: return op_interface_next(working);
ex de, hl
call _op_interface_next
ld a, l
l_op_endpoint_next_00103:
;source-doc/base-drv/./enumerate.c:55: }
ret
;source-doc/base-drv/./enumerate.c:57: usb_error op_parse_endpoint(_working *const working) __sdcccall(1) {
; ---------------------------------
; Function op_parse_endpoint
; ---------------------------------
_op_parse_endpoint:
;source-doc/base-drv/./enumerate.c:58: const endpoint_descriptor *endpoint = (endpoint_descriptor *)working->ptr;
ld c,l
ld b,h
ld hl,27
add hl,bc
ld e, (hl)
inc hl
ld d, (hl)
push de
pop iy
;source-doc/base-drv/./enumerate.c:59: device_config *const device = working->p_current_device;
ld hl,29
add hl,bc
ld e, (hl)
inc hl
ld d, (hl)
;source-doc/base-drv/./enumerate.c:61: switch (working->usb_device) {
ld l, c
ld h, b
inc hl
inc hl
ld a, (hl)
cp 0x01
jr Z,l_op_parse_endpoint_00102
cp 0x02
jr Z,l_op_parse_endpoint_00102
sub 0x04
jr Z,l_op_parse_endpoint_00103
jr l_op_parse_endpoint_00104
;source-doc/base-drv/./enumerate.c:63: case USB_IS_MASS_STORAGE: {
l_op_parse_endpoint_00102:
;source-doc/base-drv/./enumerate.c:64: parse_endpoints(device, endpoint);
push bc
push iy
push de
call _parse_endpoints
pop af
pop af
pop bc
;source-doc/base-drv/./enumerate.c:65: break;
jr l_op_parse_endpoint_00104
;source-doc/base-drv/./enumerate.c:68: case USB_IS_KEYBOARD: {
l_op_parse_endpoint_00103:
;source-doc/base-drv/./enumerate.c:69: parse_endpoint_keyboard((device_config_keyboard *)device, endpoint);
ex de, hl
push bc
push iy
pop de
call _parse_endpoint_keyboard
pop bc
;source-doc/base-drv/./enumerate.c:72: }
l_op_parse_endpoint_00104:
;source-doc/base-drv/./enumerate.c:74: return op_endpoint_next(working);
ld l, c
ld h, b
;source-doc/base-drv/./enumerate.c:75: }
jp _op_endpoint_next
;source-doc/base-drv/./enumerate.c:78: configure_device(const _working *const working, const interface_descriptor *const interface, device_config *const dev_cfg) {
; ---------------------------------
; Function configure_device
; ---------------------------------
_configure_device:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/./enumerate.c:79: dev_cfg->interface_number = interface->bInterfaceNumber;
ld e,(ix+8)
ld d,(ix+9)
ld c, e
ld b, d
inc bc
inc bc
ld l,(ix+6)
ld h,(ix+7)
inc hl
inc hl
ld a, (hl)
ld (bc), a
;source-doc/base-drv/./enumerate.c:80: dev_cfg->max_packet_size = working->desc.bMaxPacketSize0;
ld hl,0x0001
add hl, de
ex (sp), hl
push iy
ex (sp), hl
ld l,(ix+4)
ex (sp), hl
ex (sp), hl
ld h,(ix+5)
ex (sp), hl
pop iy
push iy
pop bc
ld hl,10
add hl, bc
ld a, (hl)
pop hl
push hl
ld (hl), a
;source-doc/base-drv/./enumerate.c:81: dev_cfg->address = working->current_device_address;
ld c, e
ld b, d
push iy
pop hl
ld a,+((0x0018) & 0xFF)
add a,l
ld l,a
ld a,+((0x0018) / 256)
adc a,h
ld h,a
ld a, (hl)
add a, a
add a, a
add a, a
add a, a
ld l, a
ld a, (bc)
and 0x0f
or l
ld (bc), a
;source-doc/base-drv/./enumerate.c:82: dev_cfg->type = working->usb_device;
ld c, e
ld b, d
push iy
pop hl
inc hl
inc hl
ld a, (hl)
and 0x0f
ld l, a
ld a, (bc)
and 0xf0
or l
ld (bc), a
;source-doc/base-drv/./enumerate.c:84: return usbtrn_set_configuration(dev_cfg->address, dev_cfg->max_packet_size, working->config.desc.bConfigurationvalue);
push iy
pop bc
ld hl,36
add hl, bc
ld c, (hl)
pop hl
ld b,(hl)
push hl
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld h, c
ld l,b
push hl
push af
inc sp
call _usbtrn_set_configuration
;source-doc/base-drv/./enumerate.c:85: }
ld sp,ix
pop ix
ret
;source-doc/base-drv/./enumerate.c:87: usb_error op_capture_hub_driver_interface(_working *const working) __sdcccall(1) {
; ---------------------------------
; Function op_capture_hub_driver_interface
; ---------------------------------
_op_capture_hub_driver_interfac:
push ix
ld ix,0
add ix,sp
ld iy, -7
add iy, sp
ld sp, iy
;source-doc/base-drv/./enumerate.c:88: const interface_descriptor *const interface = (interface_descriptor *)working->ptr;
push hl
ex de,hl
pop iy
ld c,(iy+28)
ld a,(iy+27)
ld (ix-4),a
ld (ix-3),c
;source-doc/base-drv/./enumerate.c:92: working->hub_config = &hub_config;
ld hl,0x0019
add hl, de
ld (ix-2),l
ld (ix-1),h
ld hl,0
add hl, sp
ld c, l
ld l,(ix-2)
ld b,h
ld h,(ix-1)
ld (hl), c
inc hl
ld (hl), b
;source-doc/base-drv/./enumerate.c:94: hub_config.type = USB_IS_HUB;
ld hl,0
add hl, sp
ld a, (hl)
or 0x0f
ld (hl), a
;source-doc/base-drv/./enumerate.c:95: CHECK(configure_device(working, interface, (device_config *const)&hub_config));
push de
ld hl,2
add hl, sp
push hl
ld l,(ix-4)
ld h,(ix-3)
push hl
push de
call _configure_device
pop af
pop af
pop af
ld a, l
pop de
or a
jr NZ,l_op_capture_hub_driver_interfa
;source-doc/base-drv/./enumerate.c:96: RETURN_CHECK(configure_usb_hub(working));
ex de, hl
call _configure_usb_hub
ld a, l
l_op_capture_hub_driver_interfa:
;source-doc/base-drv/./enumerate.c:97: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./enumerate.c:99: usb_error op_cap_drv_intf(_working *const working) __z88dk_fastcall {
; ---------------------------------
; Function op_cap_drv_intf
; ---------------------------------
_op_cap_drv_intf:
push ix
ld ix,0
add ix,sp
ld iy, -16
add iy, sp
ld sp, iy
;source-doc/base-drv/./enumerate.c:102: const interface_descriptor *const interface = (interface_descriptor *)working->ptr;
ld (ix-2),l
ld (ix-1),h
ld de,0x001b
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
dec hl
ld c, e
ld b, d
;source-doc/base-drv/./enumerate.c:104: working->ptr += interface->bLength;
ld a, (bc)
add a, e
ld e, a
ld a,0x00
adc a, d
ld (hl), e
inc hl
ld (hl), a
;source-doc/base-drv/./enumerate.c:105: working->endpoint_count = interface->bNumEndpoints;
ld a,(ix-2)
add a,0x17
ld e, a
ld a,(ix-1)
adc a,0x00
ld d, a
push bc
pop iy
ld a,(iy+4)
ld (de), a
;source-doc/base-drv/./enumerate.c:106: working->p_current_device = NULL;
ld l,(ix-2)
ld h,(ix-1)
ld de,0x001d
add hl,de
ld (ix-4),l
ld (ix-3),h
xor a
ld (hl), a
inc hl
ld (hl), a
;source-doc/base-drv/./enumerate.c:108: switch (working->usb_device) {
ld e,(ix-2)
ld d,(ix-1)
inc de
inc de
ld a, (de)
cp 0x06
jr Z,l_op_cap_drv_intf_00104
sub 0x0f
jr NZ,l_op_cap_drv_intf_00107
;source-doc/base-drv/./enumerate.c:110: CHECK(op_capture_hub_driver_interface(working))
ld l,(ix-2)
ld h,(ix-1)
call _op_capture_hub_driver_interfac
or a
jr Z,l_op_cap_drv_intf_00112
ld l, a
jr l_op_cap_drv_intf_00115
;source-doc/base-drv/./enumerate.c:114: case USB_IS_UNKNOWN: {
l_op_cap_drv_intf_00104:
;source-doc/base-drv/./enumerate.c:116: memset(&unkown_dev_cfg, 0, sizeof(device_config));
push bc
ld hl,2
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x0c
push hl
call _memset_callee
pop bc
;source-doc/base-drv/./enumerate.c:117: working->p_current_device = &unkown_dev_cfg;
ld hl,0
add hl, sp
ex de, hl
ld l,(ix-4)
ld h,(ix-3)
ld (hl), e
inc hl
ld (hl), d
;source-doc/base-drv/./enumerate.c:118: CHECK(configure_device(working, interface, &unkown_dev_cfg));
ld hl,0
add hl, sp
push hl
push bc
ld l,(ix-2)
ld h,(ix-1)
push hl
call _configure_device
pop af
pop af
pop af
ld a, l
or a
jr Z,l_op_cap_drv_intf_00112
jr l_op_cap_drv_intf_00115
;source-doc/base-drv/./enumerate.c:122: default: {
l_op_cap_drv_intf_00107:
;source-doc/base-drv/./enumerate.c:123: device_config *dev_cfg = find_first_free();
push bc
call _find_first_free
;source-doc/base-drv/./enumerate.c:124: if (dev_cfg == NULL)
pop bc
ld a,h
or l
ex de,hl
jr NZ,l_op_cap_drv_intf_00109
;source-doc/base-drv/./enumerate.c:125: return USB_ERR_OUT_OF_MEMORY;
ld l,0x83
jr l_op_cap_drv_intf_00115
l_op_cap_drv_intf_00109:
;source-doc/base-drv/./enumerate.c:126: working->p_current_device = dev_cfg;
ld l,(ix-4)
ld h,(ix-3)
ld (hl), e
inc hl
ld (hl), d
;source-doc/base-drv/./enumerate.c:127: CHECK(configure_device(working, interface, dev_cfg));
push de
push bc
ld l,(ix-2)
ld h,(ix-1)
push hl
call _configure_device
pop af
pop af
pop af
ld a, l
or a
;source-doc/base-drv/./enumerate.c:130: }
jr NZ,l_op_cap_drv_intf_00115
l_op_cap_drv_intf_00112:
;source-doc/base-drv/./enumerate.c:132: CHECK(op_parse_endpoint(working));
ld l,(ix-2)
ld h,(ix-1)
call _op_parse_endpoint
or a
jr Z,l_op_cap_drv_intf_00114
ld l, a
jr l_op_cap_drv_intf_00115
l_op_cap_drv_intf_00114:
;source-doc/base-drv/./enumerate.c:134: return result;
ld l, a
l_op_cap_drv_intf_00115:
;source-doc/base-drv/./enumerate.c:135: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./enumerate.c:137: usb_error op_id_class_drv(_working *const working) __sdcccall(1) {
; ---------------------------------
; Function op_id_class_drv
; ---------------------------------
_op_id_class_drv:
;source-doc/base-drv/./enumerate.c:139: const interface_descriptor *const ptr = (const interface_descriptor *)working->ptr;
push hl
ex de,hl
pop iy
ld l,(iy+27)
ld h,(iy+28)
;source-doc/base-drv/./enumerate.c:141: working->usb_device = ptr->bLength > 5 ? identify_class_driver(working) : 0;
ld c, e
ld b, d
inc bc
inc bc
ld l, (hl)
ld a,0x05
sub l
jr NC,l_op_id_class_drv_00105
push bc
push de
push de
call _identify_class_driver
pop af
ld a, l
pop de
pop bc
ld l,0x00
jr l_op_id_class_drv_00106
l_op_id_class_drv_00105:
xor a
ld l, a
l_op_id_class_drv_00106:
ld (bc), a
;source-doc/base-drv/./enumerate.c:143: CHECK(op_cap_drv_intf(working));
ex de, hl
call _op_cap_drv_intf
ld a, l
or a
ret NZ
;source-doc/base-drv/./enumerate.c:145: return result;
;source-doc/base-drv/./enumerate.c:146: }
ret
;source-doc/base-drv/./enumerate.c:148: usb_error op_get_cfg_desc(_working *const working) __sdcccall(1) {
; ---------------------------------
; Function op_get_cfg_desc
; ---------------------------------
_op_get_cfg_desc:
ex de, hl
;source-doc/base-drv/./enumerate.c:151: memset(working->config.buffer, 0, MAX_CONFIG_SIZE);
ld iy,0x001f
add iy, de
push iy
pop bc
push de
push iy
push bc
ld hl,0x0000
push hl
ld l,0x8c
push hl
call _memset_callee
pop iy
pop de
;source-doc/base-drv/./enumerate.c:153: const uint8_t max_packet_size = working->desc.bMaxPacketSize0;
ld c, e
ld b, d
inc bc
inc bc
inc bc
ld hl,7
add hl, bc
ld a, (hl)
;source-doc/base-drv/./enumerate.c:156: working->config.buffer));
ld c, e
ld b, d
ld hl,24
add hl, bc
ld b, (hl)
ld l, e
ld h, d
push bc
ld bc,0x0015
add hl, bc
pop bc
ld c, (hl)
push de
push iy
push iy
ld h,0x8c
ld l,a
push hl
push bc
call _usbtrn_gfull_cfg_desc
pop af
pop af
pop af
ld a, l
pop iy
pop de
or a
ret NZ
;source-doc/base-drv/./enumerate.c:158: working->ptr = (working->config.buffer + sizeof(config_descriptor));
ld hl,0x001b
add hl, de
ld a, e
add a,0x1f
ld c, a
ld a, d
adc a,0x00
ld b, a
ld a, c
add a,0x09
ld c, a
ld a, b
adc a,0x00
ld (hl), c
inc hl
ld (hl), a
;source-doc/base-drv/./enumerate.c:159: working->interface_count = working->config.desc.bNumInterfaces;
ld hl,0x0016
add hl, de
ld c, l
ld b, h
push iy
pop hl
inc hl
inc hl
inc hl
inc hl
ld a, (hl)
ld (bc), a
;source-doc/base-drv/./enumerate.c:161: CHECK(op_id_class_drv(working));
ex de, hl
call _op_id_class_drv
or a
ret NZ
;source-doc/base-drv/./enumerate.c:163: return result;
;source-doc/base-drv/./enumerate.c:164: }
ret
;source-doc/base-drv/./enumerate.c:166: usb_error read_all_configs(enumeration_state *const state) {
; ---------------------------------
; Function read_all_configs
; ---------------------------------
_read_all_configs:
push ix
ld ix,0
add ix,sp
ld hl, -171
add hl, sp
ld sp, hl
;source-doc/base-drv/./enumerate.c:171: memset(&working, 0, sizeof(_working));
ld hl,0
add hl, sp
push hl
push hl
ld hl,0x0000
push hl
ld l,0xab
push hl
call _memset_callee
;source-doc/base-drv/./enumerate.c:172: working.state = state;
pop hl
ld e,l
ld d,h
ld a,(ix+4)
ld (hl), a
inc hl
ld a,(ix+5)
ld (hl), a
;source-doc/base-drv/./enumerate.c:174: CHECK(usbtrn_get_descriptor(&working.desc));
push de
ld hl,5
add hl, sp
push hl
call _usbtrn_get_descriptor
pop af
pop de
ld a, l
or a
jr NZ,l_read_all_configs_00111
;source-doc/base-drv/./enumerate.c:176: state->next_device_address++;
ld l,(ix+4)
ld h,(ix+5)
ld c, (hl)
inc c
ld (hl), c
;source-doc/base-drv/./enumerate.c:177: working.current_device_address = state->next_device_address;
ld hl,0x0018
add hl, de
ld (hl), c
;source-doc/base-drv/./enumerate.c:178: CHECK(usbtrn_set_address(working.current_device_address));
push de
ld l, c
call _usbtrn_set_address
pop de
ld a, l
;source-doc/base-drv/./enumerate.c:180: for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) {
or a
jr NZ,l_read_all_configs_00111
ld c,a
l_read_all_configs_00109:
ld hl,20+0
add hl, sp
ld b, (hl)
ld a, c
sub b
jr NC,l_read_all_configs_00107
;source-doc/base-drv/./enumerate.c:181: working.config_index = config_index;
ld hl,0x0015
add hl, de
ld (hl), c
;source-doc/base-drv/./enumerate.c:183: CHECK(op_get_cfg_desc(&working));
push bc
push de
ld hl,4
add hl, sp
call _op_get_cfg_desc
pop de
pop bc
or a
jr Z,l_read_all_configs_00110
ld l, a
jr l_read_all_configs_00111
l_read_all_configs_00110:
;source-doc/base-drv/./enumerate.c:180: for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) {
inc c
jr l_read_all_configs_00109
l_read_all_configs_00107:
;source-doc/base-drv/./enumerate.c:186: return USB_ERR_OK;
ld l,0x00
l_read_all_configs_00111:
;source-doc/base-drv/./enumerate.c:187: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./enumerate.c:189: usb_error enumerate_all_devices(void) {
; ---------------------------------
; Function enumerate_all_devices
; ---------------------------------
_enumerate_all_devices:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/./enumerate.c:190: _usb_state *const work_area = get_usb_work_area();
;source-doc/base-drv/./enumerate.c:192: memset(&state, 0, sizeof(enumeration_state));
ld hl,0
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x01
push hl
call _memset_callee
;source-doc/base-drv/./enumerate.c:193: state.next_device_address = 0;
ld (ix-1),0x00
;source-doc/base-drv/./enumerate.c:195: usb_error result = read_all_configs(&state);
ld hl,0
add hl, sp
push hl
call _read_all_configs
pop af
;source-doc/base-drv/./enumerate.c:197: work_area->count_of_detected_usb_devices = state.next_device_address;
ld a,(ix-1)
ld c,l
ld ((_x + 1)),a
;source-doc/base-drv/./enumerate.c:199: CHECK(result);
ld a, c
or a
jr Z,l_enumerate_all_devices_00102
ld l, c
jr l_enumerate_all_devices_00103
l_enumerate_all_devices_00102:
;source-doc/base-drv/./enumerate.c:201: return result;
ld l, c
l_enumerate_all_devices_00103:
;source-doc/base-drv/./enumerate.c:202: }
inc sp
pop ix
ret

470
Source/HBIOS/ch376-native/base-drv/enumerate_hub.c.s

@ -0,0 +1,470 @@
;
; Generated from source-doc/base-drv/./enumerate_hub.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./enumerate_hub.c:13: usb_error hub_set_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) {
; ---------------------------------
; Function hub_set_feature
; ---------------------------------
_hub_set_feature:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./enumerate_hub.c:15: set_feature = cmd_set_feature;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x0008
ld hl,_cmd_set_feature
ldir
;source-doc/base-drv/./enumerate_hub.c:17: set_feature.bValue[0] = feature;
ld a,(ix+6)
ld (ix-6),a
;source-doc/base-drv/./enumerate_hub.c:18: set_feature.bIndex[0] = index;
ld a,(ix+7)
ld (ix-4),a
;source-doc/base-drv/./enumerate_hub.c:19: return usb_control_transfer(&set_feature, 0, hub_config->address, hub_config->max_packet_size);
ld l,(ix+4)
ld h,(ix+5)
ld e,l
ld d,h
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld c,a
push bc
ld hl,0x0000
push hl
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
;source-doc/base-drv/./enumerate_hub.c:20: }
ld sp,ix
pop ix
ret
_cmd_set_feature:
DEFB +0x23
DEFB +0x03
DEFB +0x08
DEFB +0x00
DEFB +0x01
DEFB +0x00
DEFW +0x0000
_cmd_clear_feature:
DEFB +0x23
DEFB +0x01
DEFB +0x08
DEFB +0x00
DEFB +0x01
DEFB +0x00
DEFW +0x0000
_cmd_get_status_port:
DEFB +0xa3
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x01
DEFB +0x00
DEFW +0x0004
;source-doc/base-drv/./enumerate_hub.c:22: usb_error hub_clear_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) {
; ---------------------------------
; Function hub_clear_feature
; ---------------------------------
_hub_clear_feature:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./enumerate_hub.c:24: clear_feature = cmd_clear_feature;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x0008
ld hl,_cmd_clear_feature
ldir
;source-doc/base-drv/./enumerate_hub.c:26: clear_feature.bValue[0] = feature;
ld a,(ix+6)
ld (ix-6),a
;source-doc/base-drv/./enumerate_hub.c:27: clear_feature.bIndex[0] = index;
ld a,(ix+7)
ld (ix-4),a
;source-doc/base-drv/./enumerate_hub.c:28: return usb_control_transfer(&clear_feature, 0, hub_config->address, hub_config->max_packet_size);
ld l,(ix+4)
ld h,(ix+5)
ld e,l
ld d,h
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld c,a
push bc
ld hl,0x0000
push hl
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
;source-doc/base-drv/./enumerate_hub.c:29: }
ld sp,ix
pop ix
ret
;source-doc/base-drv/./enumerate_hub.c:31: usb_error hub_get_status_port(const device_config_hub *const hub_config, const uint8_t index, hub_port_status *const port_status) {
; ---------------------------------
; Function hub_get_status_port
; ---------------------------------
_hub_get_status_port:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./enumerate_hub.c:33: get_status_port = cmd_get_status_port;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x0008
ld hl,_cmd_get_status_port
ldir
;source-doc/base-drv/./enumerate_hub.c:35: get_status_port.bIndex[0] = index;
ld a,(ix+6)
ld (ix-4),a
;source-doc/base-drv/./enumerate_hub.c:36: return usb_control_transfer(&get_status_port, port_status, hub_config->address, hub_config->max_packet_size);
ld l,(ix+4)
ld h,(ix+5)
ld e,l
ld d,h
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld e,(ix+7)
ld d,(ix+8)
ld c,a
push bc
push de
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
;source-doc/base-drv/./enumerate_hub.c:37: }
ld sp,ix
pop ix
ret
;source-doc/base-drv/./enumerate_hub.c:39: usb_error configure_usb_hub(_working *const working) __z88dk_fastcall {
; ---------------------------------
; Function configure_usb_hub
; ---------------------------------
_configure_usb_hub:
push ix
ld ix,0
add ix,sp
ld iy, -14
add iy, sp
ld sp, iy
;source-doc/base-drv/./enumerate_hub.c:45: const device_config_hub *const hub_config = working->hub_config;
push hl
ld c,l
ld b,h
pop iy
ld a,(iy+25)
ld (ix-2),a
ld a,(iy+26)
ld (ix-1),a
;source-doc/base-drv/./enumerate_hub.c:47: CHECK(hub_get_descriptor(hub_config, &hub_description));
push bc
ld hl,2
add hl, sp
ex de, hl
ld l,(ix-2)
ld h,(ix-1)
call _hub_get_descriptor
pop bc
ld e,a
or a
jr Z,l_configure_usb_hub_00102
ld l, e
jp l_configure_usb_hub_00129
l_configure_usb_hub_00102:
;source-doc/base-drv/./enumerate_hub.c:49: uint8_t i = hub_description.bNbrPorts;
ld d,(ix-12)
;source-doc/base-drv/./enumerate_hub.c:50: do {
l_configure_usb_hub_00126:
;source-doc/base-drv/./enumerate_hub.c:51: CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i));
push bc
push de
ld e,0x08
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_clear_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jp NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:53: CHECK(hub_set_feature(hub_config, FEAT_PORT_POWER, i));
push bc
push de
ld e,0x08
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_set_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jp NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:55: hub_clear_feature(hub_config, FEAT_PORT_RESET, i);
push bc
push de
ld e,0x04
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_clear_feature
pop af
pop af
pop de
push de
ld e,0x04
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_set_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jp NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:59: CHECK(hub_get_status_port(hub_config, i, &port_status));
push bc
push de
ld hl,12
add hl, sp
push hl
push de
inc sp
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_get_status_port
pop af
pop af
inc sp
pop de
pop bc
ld a, l
or a
jp NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:61: if (port_status.wPortStatus.port_connection) {
ld hl,8
add hl, sp
ld a, (hl)
and 0x01
jp Z, l_configure_usb_hub_00124
;source-doc/base-drv/./enumerate_hub.c:62: CHECK(hub_clear_feature(hub_config, HUB_FEATURE_PORT_CONNECTION_CHA, i));
push bc
push de
ld e,0x10
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_clear_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jp NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:64: CHECK(hub_clear_feature(hub_config, FEAT_PORT_ENABLE_CHANGE, i));
push bc
push de
ld e,0x11
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_clear_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jr NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:66: CHECK(hub_clear_feature(hub_config, FEAT_PORT_RESET_CHANGE, i));
push bc
push de
ld e,0x14
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_clear_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jr NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:67: delay_short();
push bc
push de
call _delay_short
pop de
push de
ld hl,12
add hl, sp
push hl
push de
inc sp
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_get_status_port
pop af
pop af
inc sp
pop de
pop bc
ld a, l
or a
jr NZ,l_configure_usb_hub_00129
;source-doc/base-drv/./enumerate_hub.c:70: delay_short();
push bc
push de
call _delay_short
pop de
;source-doc/base-drv/./enumerate_hub.c:72: CHECK(read_all_configs(working->state));
pop hl
ld e,(hl)
ld c,l
ld b,h
inc hl
ld h, (hl)
push bc
push de
ld l, e
push hl
call _read_all_configs
pop af
pop de
pop bc
ld a, l
or a
jr Z,l_configure_usb_hub_00127
jr l_configure_usb_hub_00129
l_configure_usb_hub_00124:
;source-doc/base-drv/./enumerate_hub.c:75: CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i));
push bc
push de
ld e,0x08
push de
ld l,(ix-2)
ld h,(ix-1)
push hl
call _hub_clear_feature
pop af
pop af
pop de
pop bc
ld a, l
or a
jr NZ,l_configure_usb_hub_00129
l_configure_usb_hub_00127:
;source-doc/base-drv/./enumerate_hub.c:77: } while (--i != 0);
dec d
ld a, d
;source-doc/base-drv/./enumerate_hub.c:79: return USB_ERR_OK;
or a
jp NZ,l_configure_usb_hub_00126
ld l,a
l_configure_usb_hub_00129:
;source-doc/base-drv/./enumerate_hub.c:80: }
ld sp, ix
pop ix
ret

142
Source/HBIOS/ch376-native/base-drv/enumerate_storage.c.s

@ -0,0 +1,142 @@
;
; Generated from source-doc/base-drv/./enumerate_storage.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./enumerate_storage.c:5: void parse_endpoints(device_config *const storage_dev, const endpoint_descriptor const *pEndpoint) {
; ---------------------------------
; Function parse_endpoints
; ---------------------------------
_parse_endpoints:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/./enumerate_storage.c:7: if (!(pEndpoint->bmAttributes & 0x02))
ld c,(ix+6)
ld b,(ix+7)
push bc
pop iy
ld a,(iy+3)
ld (ix-2),a
bit 1,a
;source-doc/base-drv/./enumerate_storage.c:8: return;
jr Z,l_parse_endpoints_00108
;source-doc/base-drv/./enumerate_storage.c:10: const uint8_t x = calc_max_packet_sizex(pEndpoint->wMaxPacketSize);
push bc
pop iy
ld a,(iy+4)
ld (ix-1),a
;source-doc/base-drv/./enumerate_storage.c:11: endpoint_param *const eps = storage_dev->endpoints;
ld e,(ix+4)
ld d,(ix+5)
inc de
inc de
inc de
;source-doc/base-drv/./enumerate_storage.c:15: if (!(pEndpoint->bEndpointAddress & 0x80))
inc bc
inc bc
ld a, (bc)
ld c,a
and 0x80
ld b,0x00
;source-doc/base-drv/./enumerate_storage.c:14: if (pEndpoint->bmAttributes & 0x01) { // 3 -> Interrupt
bit 0,(ix-2)
jr Z,l_parse_endpoints_00106
;source-doc/base-drv/./enumerate_storage.c:15: if (!(pEndpoint->bEndpointAddress & 0x80))
or b
;source-doc/base-drv/./enumerate_storage.c:16: return;
jr Z,l_parse_endpoints_00108
;source-doc/base-drv/./enumerate_storage.c:18: ep = &eps[ENDPOINT_INTERRUPT_IN];
ld hl,0x0006
add hl, de
ex de, hl
jr l_parse_endpoints_00107
l_parse_endpoints_00106:
;source-doc/base-drv/./enumerate_storage.c:21: ep = (pEndpoint->bEndpointAddress & 0x80) ? &eps[ENDPOINT_BULK_IN] : &eps[ENDPOINT_BULK_OUT];
or b
jr Z,l_parse_endpoints_00110
inc de
inc de
inc de
l_parse_endpoints_00110:
l_parse_endpoints_00107:
;source-doc/base-drv/./enumerate_storage.c:24: ep->number = pEndpoint->bEndpointAddress & 0x07;
ld l, e
ld h, d
ld a, c
and 0x07
rlca
and 0x0e
ld c, a
ld a, (hl)
and 0xf1
or c
ld (hl), a
;source-doc/base-drv/./enumerate_storage.c:25: ep->toggle = 0;
ld l, e
ld h, d
res 0, (hl)
;source-doc/base-drv/./enumerate_storage.c:26: ep->max_packet_sizex = x;
inc de
ld a,(ix-1)
ld b,0x00
ld (de), a
inc de
ld a, b
and 0x03
ld l,a
ld a, (de)
and 0xfc
or l
ld (de), a
l_parse_endpoints_00108:
;source-doc/base-drv/./enumerate_storage.c:27: }
ld sp, ix
pop ix
ret

87
Source/HBIOS/ch376-native/base-drv/print.c.s

@ -0,0 +1,87 @@
;
; Generated from source-doc/base-drv/./print.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./print.c:3: void print_device_mounted(const char *const description, const uint8_t count) {
; ---------------------------------
; Function print_device_mounted
; ---------------------------------
_print_device_mounted:
;source-doc/base-drv/./print.c:4: print_string("\r\n $");
ld hl,print_str_0
call _print_string
;source-doc/base-drv/./print.c:5: print_uint16(count);
ld iy,4
add iy, sp
ld l,(iy+0)
ld h,0x00
call _print_uint16
;source-doc/base-drv/./print.c:6: print_string(description);
ld hl,2
add hl, sp
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
call _print_string
;source-doc/base-drv/./print.c:7: if (count > 1)
ld a,0x01
ld iy,4
add iy, sp
sub (iy+0)
ret NC
;source-doc/base-drv/./print.c:8: print_string("S$");
ld hl,print_str_1
;source-doc/base-drv/./print.c:9: }
jp _print_string
print_str_0:
DEFB 0x0d
DEFB 0x0a
DEFM " $"
DEFB 0x00
print_str_1:
DEFM "S$"
DEFB 0x00

478
Source/HBIOS/ch376-native/base-drv/protocol.c.s

@ -0,0 +1,478 @@
;
; Generated from source-doc/base-drv/./protocol.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./protocol.c:28: usb_error usbtrn_get_descriptor(device_descriptor *const buffer) {
; ---------------------------------
; Function usbtrn_get_descriptor
; ---------------------------------
_usbtrn_get_descriptor:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./protocol.c:31: cmd = cmd_get_device_descriptor;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x0008
ld hl,_cmd_get_device_descriptor
ldir
;source-doc/base-drv/./protocol.c:32: cmd.wLength = 8;
ld (ix-2),0x08
xor a
ld (ix-1),a
;source-doc/base-drv/./protocol.c:34: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8);
ld c,(ix+4)
ld b,(ix+5)
ld e, c
ld d, b
push bc
ld a,0x08
push af
inc sp
xor a
push af
inc sp
push de
ld hl,6
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
pop bc
;source-doc/base-drv/./protocol.c:36: CHECK(result);
ld a, l
or a
jr NZ,l_usbtrn_get_descriptor_00103
;source-doc/base-drv/./protocol.c:38: cmd = cmd_get_device_descriptor;
ld hl,0
add hl, sp
ex de, hl
push bc
ld bc,0x0008
ld hl,_cmd_get_device_descriptor
ldir
pop bc
;source-doc/base-drv/./protocol.c:39: cmd.wLength = 18;
ld (ix-2),0x12
xor a
ld (ix-1),a
;source-doc/base-drv/./protocol.c:40: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0);
ld e,(ix+4)
ld d,(ix+5)
ld hl,7
add hl, de
ld a, (hl)
push af
inc sp
xor a
push af
inc sp
push bc
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
;source-doc/base-drv/./protocol.c:42: RETURN_CHECK(result);
l_usbtrn_get_descriptor_00103:
;source-doc/base-drv/./protocol.c:43: }
ld sp, ix
pop ix
ret
_cmd_get_device_descriptor:
DEFB +0x80
DEFB +0x06
DEFB +0x00
DEFB +0x01
DEFB +0x00
DEFB +0x00
DEFW +0x0008
;source-doc/base-drv/./protocol.c:51: usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address) {
; ---------------------------------
; Function usbtrn_get_descriptor2
; ---------------------------------
_usbtrn_get_descriptor2:
push ix
ld ix,0
add ix,sp
ld hl, -10
add hl, sp
ld sp, hl
;source-doc/base-drv/./protocol.c:54: cmd = cmd_get_device_descriptor;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x0008
ld hl,_cmd_get_device_descriptor
ldir
pop bc
;source-doc/base-drv/./protocol.c:55: cmd.wLength = 8;
ld (ix-4),0x08
xor a
ld (ix-3),a
;source-doc/base-drv/./protocol.c:57: result = usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, 8);
ld a,(ix+4)
ld (ix-2),a
ld l, a
ld a,(ix+5)
ld (ix-1),a
ld h,a
ld e, c
ld d, b
push bc
ld b,0x08
ld c,(ix+6)
push bc
push hl
push de
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
pop bc
ld l, a
;source-doc/base-drv/./protocol.c:59: CHECK(result);
or a
jr NZ,l_usbtrn_get_descriptor2_00103
;source-doc/base-drv/./protocol.c:61: cmd = cmd_get_device_descriptor;
ld e, c
ld d, b
push bc
ld bc,0x0008
ld hl,_cmd_get_device_descriptor
ldir
pop bc
;source-doc/base-drv/./protocol.c:62: cmd.wLength = 18;
ld (ix-4),0x12
xor a
ld (ix-3),a
;source-doc/base-drv/./protocol.c:63: RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, buffer->bMaxPacketSize0));
ld e,(ix+4)
ld d,(ix+5)
ld hl,7
add hl, de
ld a, (hl)
ld e,(ix-2)
ld d,(ix-1)
push af
inc sp
ld a,(ix+6)
push af
inc sp
push de
push bc
call _usb_control_transfer
pop af
pop af
pop af
l_usbtrn_get_descriptor2_00103:
;source-doc/base-drv/./protocol.c:64: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./protocol.c:74: usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall {
; ---------------------------------
; Function usbtrn_set_address
; ---------------------------------
_usbtrn_set_address:
push ix
ld ix,0
add ix,sp
ld iy, -8
add iy, sp
ld sp, iy
ld c, l
;source-doc/base-drv/./protocol.c:76: cmd = cmd_set_device_address;
ld hl,0
add hl, sp
ex de, hl
push bc
ld bc,0x0008
ld hl,_cmd_set_device_address
ldir
pop bc
;source-doc/base-drv/./protocol.c:77: cmd.bValue[0] = device_address;
ld (ix-6),c
;source-doc/base-drv/./protocol.c:79: return usb_control_transfer(&cmd, 0, 0, 0);
xor a
push af
inc sp
xor a
push af
inc sp
ld hl,0x0000
push hl
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
;source-doc/base-drv/./protocol.c:80: }
ld sp,ix
pop ix
ret
_cmd_set_device_address:
DEFB +0x00
DEFB +0x05
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFW +0x0000
;source-doc/base-drv/./protocol.c:90: usb_error usbtrn_set_configuration(const uint8_t device_address, const uint8_t max_packet_size, const uint8_t configuration) {
; ---------------------------------
; Function usbtrn_set_configuration
; ---------------------------------
_usbtrn_set_configuration:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./protocol.c:92: cmd = cmd_set_configuration;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x0008
ld hl,_cmd_set_configuration
ldir
pop bc
;source-doc/base-drv/./protocol.c:93: cmd.bValue[0] = configuration;
ld a,(ix+6)
ld (ix-6),a
;source-doc/base-drv/./protocol.c:95: return usb_control_transfer(&cmd, 0, device_address, max_packet_size);
ld h,(ix+5)
ld l,(ix+4)
push hl
ld hl,0x0000
push hl
push bc
call _usb_control_transfer
;source-doc/base-drv/./protocol.c:96: }
ld sp,ix
pop ix
ret
_cmd_set_configuration:
DEFB +0x00
DEFB +0x09
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFW +0x0000
;source-doc/base-drv/./protocol.c:110: usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer,
; ---------------------------------
; Function usbtrn_get_config_descriptor
; ---------------------------------
_usbtrn_get_config_descriptor:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./protocol.c:116: cmd = cmd_get_config_descriptor;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x0008
ld hl,_cmd_get_config_descriptor
ldir
pop bc
;source-doc/base-drv/./protocol.c:117: cmd.bValue[0] = config_index;
ld a,(ix+6)
ld (ix-6),a
;source-doc/base-drv/./protocol.c:118: cmd.wLength = (uint16_t)buffer_size;
ld e,(ix+7)
ld (ix-2),e
ld (ix-1),0x00
;source-doc/base-drv/./protocol.c:120: RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, max_packet_size));
ld e,(ix+4)
ld d,(ix+5)
ld h,(ix+9)
ld l,(ix+8)
push hl
push de
push bc
call _usb_control_transfer
;source-doc/base-drv/./protocol.c:121: }
ld sp,ix
pop ix
ret
_cmd_get_config_descriptor:
DEFB +0x80
DEFB +0x06
DEFB +0x00
DEFB +0x02
DEFB +0x00
DEFB +0x00
DEFW +0x0000
;source-doc/base-drv/./protocol.c:123: usb_error usbtrn_gfull_cfg_desc(const uint8_t config_index,
; ---------------------------------
; Function usbtrn_gfull_cfg_desc
; ---------------------------------
_usbtrn_gfull_cfg_desc:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./protocol.c:131: max_packet_size));
ld c,(ix+8)
ld b,(ix+9)
push bc
ld a,(ix+6)
push af
inc sp
ld d,(ix+5)
ld e,0x09
push de
ld a,(ix+4)
push af
inc sp
push bc
call _usbtrn_get_config_descriptor
pop af
pop af
pop af
pop bc
ld a, l
or a
jr NZ,l_usbtrn_gfull_cfg_desc_00107
;source-doc/base-drv/./protocol.c:133: uint8_t max_length = ((config_descriptor *)buffer)->wTotalLength;
ld l, c
ld h, b
inc hl
inc hl
ld d, (hl)
;source-doc/base-drv/./protocol.c:134: if (max_length > max_buffer_size)
ld a,(ix+7)
sub d
jr NC,l_usbtrn_gfull_cfg_desc_00104
;source-doc/base-drv/./protocol.c:135: max_length = max_buffer_size;
ld d,(ix+7)
l_usbtrn_gfull_cfg_desc_00104:
;source-doc/base-drv/./protocol.c:137: CHECK(usbtrn_get_config_descriptor((config_descriptor *)buffer, config_index, max_length, device_address, max_packet_size));
ld h,(ix+6)
ld l,(ix+5)
push hl
ld e,(ix+4)
push de
push bc
call _usbtrn_get_config_descriptor
pop af
pop af
pop af
ld a, l
;source-doc/base-drv/./protocol.c:139: return USB_ERR_OK;
or a
jr NZ,l_usbtrn_gfull_cfg_desc_00107
ld l,a
l_usbtrn_gfull_cfg_desc_00107:
;source-doc/base-drv/./protocol.c:140: }
pop ix
ret
;source-doc/base-drv/./protocol.c:144: usb_error usbtrn_clear_endpoint_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size) {
; ---------------------------------
; Function usbtrn_clear_endpoint_halt
; ---------------------------------
_usbtrn_clear_endpoint_halt:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/./protocol.c:146: cmd = usb_cmd_clear_endpoint_halt;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x0008
ld hl,_usb_cmd_clear_endpoint_halt
ldir
pop bc
;source-doc/base-drv/./protocol.c:147: cmd.bIndex[0] = endpoint_number;
ld a,(ix+4)
ld (ix-4),a
;source-doc/base-drv/./protocol.c:149: usb_error result = usb_control_transfer(&cmd, (uint8_t *)0, device_address, max_packet_size);
ld h,(ix+6)
ld l,(ix+5)
push hl
ld hl,0x0000
push hl
push bc
call _usb_control_transfer
;source-doc/base-drv/./protocol.c:151: RETURN_CHECK(result);
;source-doc/base-drv/./protocol.c:152: }
ld sp,ix
pop ix
ret
_usb_cmd_clear_endpoint_halt:
DEFB +0x02
DEFB +0x01
DEFB +0x00
DEFB +0x00
DEFB +0xff
DEFB +0x00
DEFW +0x0000

506
Source/HBIOS/ch376-native/base-drv/transfers.c.s

@ -0,0 +1,506 @@
;
; Generated from source-doc/base-drv/./transfers.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./transfers.c:21: usb_error usb_ctrl_trnsfer_ext(const setup_packet *const cmd_packet,
; ---------------------------------
; Function usb_ctrl_trnsfer_ext
; ---------------------------------
_usb_ctrl_trnsfer_ext:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./transfers.c:25: if ((uint16_t)cmd_packet < LOWER_SAFE_RAM_ADDRESS)
ld a,(ix+5)
sub 0x80
jr NC,l_usb_ctrl_trnsfer_ext_00102
;source-doc/base-drv/./transfers.c:26: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_ctrl_trnsfer_ext_00106
l_usb_ctrl_trnsfer_ext_00102:
;source-doc/base-drv/./transfers.c:28: if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS)
ld a,(ix+7)
or (ix+6)
jr Z,l_usb_ctrl_trnsfer_ext_00104
ld a,(ix+7)
sub 0x80
jr NC,l_usb_ctrl_trnsfer_ext_00104
;source-doc/base-drv/./transfers.c:29: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_ctrl_trnsfer_ext_00106
l_usb_ctrl_trnsfer_ext_00104:
;source-doc/base-drv/./transfers.c:31: return usb_control_transfer(cmd_packet, buffer, device_address, max_packet_size);
ld h,(ix+9)
ld l,(ix+8)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_control_transfer
pop af
pop af
pop af
l_usb_ctrl_trnsfer_ext_00106:
;source-doc/base-drv/./transfers.c:32: }
pop ix
ret
;source-doc/base-drv/./transfers.c:44: usb_error usb_control_transfer(const setup_packet *const cmd_packet,
; ---------------------------------
; Function usb_control_transfer
; ---------------------------------
_usb_control_transfer:
push ix
ld ix,0
add ix,sp
push af
push af
;source-doc/base-drv/./transfers.c:49: endpoint_param endpoint = {1, 0, max_packet_size};
ld hl,0
add hl, sp
set 0, (hl)
ld hl,0
add hl, sp
ld a, (hl)
and 0xf1
ld (hl), a
ld c,(ix+9)
ld b,0x00
ld hl,1
add hl, sp
ld (hl), c
inc hl
ld a, b
and 0x03
ld e,a
ld a, (hl)
and 0xfc
or e
ld (hl), a
;source-doc/base-drv/./transfers.c:51: const uint8_t transferIn = (cmd_packet->bmRequestType & 0x80);
ld c,(ix+4)
ld b,(ix+5)
ld a, (bc)
and 0x80
;source-doc/base-drv/./transfers.c:53: if (transferIn && buffer == 0)
ld (ix-1),a
or a
jr Z,l_usb_control_transfer_00102
ld a,(ix+7)
or (ix+6)
jr NZ,l_usb_control_transfer_00102
;source-doc/base-drv/./transfers.c:54: return USB_ERR_OTHER;
ld l,0x0f
jp l_usb_control_transfer_00113
l_usb_control_transfer_00102:
;source-doc/base-drv/./transfers.c:56: ch_set_usb_address(device_address);
push bc
ld l,(ix+8)
call _ch_set_usb_address
pop bc
;source-doc/base-drv/./transfers.c:58: ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet));
ld e,(ix+4)
ld d,(ix+5)
push bc
ld a,0x08
push af
inc sp
push de
call _ch_write_data
pop af
inc sp
call _ch_issue_token_setup
call _ch_short_wait_int_and_get_stat
pop bc
ld a, l
or a
jr NZ,l_usb_control_transfer_00113
;source-doc/base-drv/./transfers.c:62: const uint16_t length = cmd_packet->wLength;
ld hl,6
add hl, bc
ld c, (hl)
inc hl
;source-doc/base-drv/./transfers.c:65: ? (transferIn ? ch_data_in_transfer(buffer, length, &endpoint) : ch_data_out_transfer(buffer, length, &endpoint))
ld a,(hl)
ld b,a
or c
jr Z,l_usb_control_transfer_00115
ld e,(ix+6)
ld d,(ix+7)
ld a,(ix-1)
or a
jr Z,l_usb_control_transfer_00117
ld hl,0
add hl, sp
push hl
push bc
push de
call _ch_data_in_transfer
pop af
pop af
pop af
jr l_usb_control_transfer_00118
l_usb_control_transfer_00117:
ld hl,0
add hl, sp
push hl
push bc
push de
call _ch_data_out_transfer
pop af
pop af
pop af
l_usb_control_transfer_00118:
jr l_usb_control_transfer_00116
l_usb_control_transfer_00115:
;source-doc/base-drv/./transfers.c:66: : USB_ERR_OK;
ld hl,0x0000
l_usb_control_transfer_00116:
;source-doc/base-drv/./transfers.c:68: CHECK(result)
ld a, l
or a
jr NZ,l_usb_control_transfer_00113
;source-doc/base-drv/./transfers.c:70: if (transferIn) {
ld a,(ix-1)
or a
jr Z,l_usb_control_transfer_00112
;source-doc/base-drv/./transfers.c:71: ch_command(CH_CMD_WR_HOST_DATA);
ld l,0x2c
call _ch_command
;source-doc/base-drv/./transfers.c:72: CH376_DATA_PORT = 0;
ld a,0x00
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./transfers.c:73: delay();
call _delay
;source-doc/base-drv/./transfers.c:74: ch_issue_token_out_ep0();
call _ch_issue_token_out_ep0
;source-doc/base-drv/./transfers.c:75: result = ch_long_wait_int_and_get_status(); /* sometimes we get STALL here - seems to be ok to ignore */
call _ch_long_wait_int_and_get_statu
ld a, l
;source-doc/base-drv/./transfers.c:77: if (result == USB_ERR_OK || result == USB_ERR_STALL)
or a
jr Z,l_usb_control_transfer_00108
cp 0x02
jr NZ,l_usb_control_transfer_00109
l_usb_control_transfer_00108:
;source-doc/base-drv/./transfers.c:78: return USB_ERR_OK;
ld l,0x00
jr l_usb_control_transfer_00113
l_usb_control_transfer_00109:
;source-doc/base-drv/./transfers.c:80: RETURN_CHECK(result);
ld l, a
jr l_usb_control_transfer_00113
l_usb_control_transfer_00112:
;source-doc/base-drv/./transfers.c:83: ch_issue_token_in_ep0();
call _ch_issue_token_in_ep0
;source-doc/base-drv/./transfers.c:84: result = ch_long_wait_int_and_get_status();
call _ch_long_wait_int_and_get_statu
;source-doc/base-drv/./transfers.c:86: RETURN_CHECK(result);
l_usb_control_transfer_00113:
;source-doc/base-drv/./transfers.c:87: }
ld sp, ix
pop ix
ret
;source-doc/base-drv/./transfers.c:90: usb_dat_in_trnsfer_ext(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
; ---------------------------------
; Function usb_dat_in_trnsfer_ext
; ---------------------------------
_usb_dat_in_trnsfer_ext:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./transfers.c:91: if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS)
ld a,(ix+5)
or (ix+4)
jr Z,l_usb_dat_in_trnsfer_ext_00102
ld a,(ix+5)
sub 0x80
jr NC,l_usb_dat_in_trnsfer_ext_00102
;source-doc/base-drv/./transfers.c:92: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_in_trnsfer_ext_00106
l_usb_dat_in_trnsfer_ext_00102:
;source-doc/base-drv/./transfers.c:94: if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS)
ld a,(ix+10)
sub 0x80
jr NC,l_usb_dat_in_trnsfer_ext_00105
;source-doc/base-drv/./transfers.c:95: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_in_trnsfer_ext_00106
l_usb_dat_in_trnsfer_ext_00105:
;source-doc/base-drv/./transfers.c:97: return usb_data_in_transfer(buffer, buffer_size, device_address, endpoint);
ld l,(ix+9)
ld h,(ix+10)
push hl
ld a,(ix+8)
push af
inc sp
ld l,(ix+6)
ld h,(ix+7)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
l_usb_dat_in_trnsfer_ext_00106:
;source-doc/base-drv/./transfers.c:98: }
pop ix
ret
;source-doc/base-drv/./transfers.c:101: usb_dat_in_trns_n_ext(uint8_t *buffer, uint16_t *buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
; ---------------------------------
; Function usb_dat_in_trns_n_ext
; ---------------------------------
_usb_dat_in_trns_n_ext:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./transfers.c:102: if (buffer != 0 && ((uint16_t)buffer & 0xC000) == 0)
ld a,(ix+5)
or (ix+4)
jr Z,l_usb_dat_in_trns_n_ext_00102
ld a,(ix+5)
and 0xc0
jr NZ,l_usb_dat_in_trns_n_ext_00102
;source-doc/base-drv/./transfers.c:103: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_in_trns_n_ext_00108
l_usb_dat_in_trns_n_ext_00102:
;source-doc/base-drv/./transfers.c:105: if (((uint16_t)endpoint & 0xC000) == 0)
ld a,(ix+10)
and 0xc0
jr NZ,l_usb_dat_in_trns_n_ext_00105
;source-doc/base-drv/./transfers.c:106: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_in_trns_n_ext_00108
l_usb_dat_in_trns_n_ext_00105:
;source-doc/base-drv/./transfers.c:108: if (((uint16_t)buffer_size & 0xC000) == 0)
ld a,(ix+7)
and 0xc0
jr NZ,l_usb_dat_in_trns_n_ext_00107
;source-doc/base-drv/./transfers.c:109: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_in_trns_n_ext_00108
l_usb_dat_in_trns_n_ext_00107:
;source-doc/base-drv/./transfers.c:111: return usb_data_in_transfer_n(buffer, buffer_size, device_address, endpoint);
ld c,(ix+6)
ld b,(ix+7)
ld l,(ix+9)
ld h,(ix+10)
push hl
ld a,(ix+8)
push af
inc sp
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_data_in_transfer_n
pop af
pop af
pop af
inc sp
l_usb_dat_in_trns_n_ext_00108:
;source-doc/base-drv/./transfers.c:112: }
pop ix
ret
;source-doc/base-drv/./transfers.c:124: usb_data_in_transfer(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
; ---------------------------------
; Function usb_data_in_transfer
; ---------------------------------
_usb_data_in_transfer:
;source-doc/base-drv/./transfers.c:125: ch_set_usb_address(device_address);
ld iy,6
add iy, sp
ld l,(iy+0)
call _ch_set_usb_address
;source-doc/base-drv/./transfers.c:127: return ch_data_in_transfer(buffer, buffer_size, endpoint);
ld iy,7
add iy, sp
ld l,(iy+0)
ld h,(iy+1)
push hl
dec iy
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
call _ch_data_in_transfer
pop af
pop af
pop af
;source-doc/base-drv/./transfers.c:128: }
ret
;source-doc/base-drv/./transfers.c:140: usb_data_in_transfer_n(uint8_t *buffer, uint8_t *const buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
; ---------------------------------
; Function usb_data_in_transfer_n
; ---------------------------------
_usb_data_in_transfer_n:
;source-doc/base-drv/./transfers.c:141: ch_set_usb_address(device_address);
ld iy,6
add iy, sp
ld l,(iy+0)
call _ch_set_usb_address
;source-doc/base-drv/./transfers.c:143: return ch_data_in_transfer_n(buffer, buffer_size, endpoint);
ld iy,7
add iy, sp
ld l,(iy+0)
ld h,(iy+1)
push hl
dec iy
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
call _ch_data_in_transfer_n
pop af
pop af
pop af
;source-doc/base-drv/./transfers.c:144: }
ret
;source-doc/base-drv/./transfers.c:147: usb_dat_out_trns_ext(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
; ---------------------------------
; Function usb_dat_out_trns_ext
; ---------------------------------
_usb_dat_out_trns_ext:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./transfers.c:149: if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS)
ld a,(ix+5)
or (ix+4)
jr Z,l_usb_dat_out_trns_ext_00102
ld a,(ix+5)
sub 0x80
jr NC,l_usb_dat_out_trns_ext_00102
;source-doc/base-drv/./transfers.c:150: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_out_trns_ext_00106
l_usb_dat_out_trns_ext_00102:
;source-doc/base-drv/./transfers.c:152: if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS)
ld a,(ix+10)
sub 0x80
jr NC,l_usb_dat_out_trns_ext_00105
;source-doc/base-drv/./transfers.c:153: return USB_BAD_ADDRESS;
ld l,0x82
jr l_usb_dat_out_trns_ext_00106
l_usb_dat_out_trns_ext_00105:
;source-doc/base-drv/./transfers.c:155: return usb_data_out_transfer(buffer, buffer_size, device_address, endpoint);
ld l,(ix+9)
ld h,(ix+10)
push hl
ld a,(ix+8)
push af
inc sp
ld l,(ix+6)
ld h,(ix+7)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
l_usb_dat_out_trns_ext_00106:
;source-doc/base-drv/./transfers.c:156: }
pop ix
ret
;source-doc/base-drv/./transfers.c:168: usb_data_out_transfer(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
; ---------------------------------
; Function usb_data_out_transfer
; ---------------------------------
_usb_data_out_transfer:
;source-doc/base-drv/./transfers.c:169: ch_set_usb_address(device_address);
ld iy,6
add iy, sp
ld l,(iy+0)
call _ch_set_usb_address
;source-doc/base-drv/./transfers.c:171: return ch_data_out_transfer(buffer, buffer_size, endpoint);
ld iy,7
add iy, sp
ld l,(iy+0)
ld h,(iy+1)
push hl
dec iy
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
dec iy
dec iy
ld l,(iy+0)
ld h,(iy+1)
push hl
call _ch_data_out_transfer
pop af
pop af
pop af
;source-doc/base-drv/./transfers.c:172: }
ret

86
Source/HBIOS/ch376-native/base-drv/usb-base-drv.c.s

@ -0,0 +1,86 @@
;
; Generated from source-doc/base-drv/./usb-base-drv.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_storage_count:
DEFS 1
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./usb-base-drv.c:6: uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1) {
; ---------------------------------
; Function chnative_seek
; ---------------------------------
_chnative_seek:
push ix
ld ix,0
add ix,sp
ld c, l
ld b, h
;source-doc/base-drv/./usb-base-drv.c:7: storage_device->current_lba = lba;
ld h,(ix+5)
ld a,(ix+4)
add a,0x0c
ld l, a
jr NC,l_chnative_seek_00103
inc h
l_chnative_seek_00103:
ld (hl), e
inc hl
ld (hl), d
inc hl
ld (hl), c
inc hl
ld (hl), b
;source-doc/base-drv/./usb-base-drv.c:8: return 0;
xor a
;source-doc/base-drv/./usb-base-drv.c:9: }
pop ix
pop hl
pop bc
jp (hl)
_storage_count:
DEFB +0x00

179
Source/HBIOS/ch376-native/base-drv/usb-init.c.s

@ -0,0 +1,179 @@
;
; Generated from source-doc/base-drv/./usb-init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./usb-init.c:8: static usb_error usb_host_bus_reset(void) {
; ---------------------------------
; Function usb_host_bus_reset
; ---------------------------------
_usb_host_bus_reset:
;source-doc/base-drv/./usb-init.c:9: ch_cmd_set_usb_mode(CH_MODE_HOST);
ld l,0x06
call _ch_cmd_set_usb_mode
;source-doc/base-drv/./usb-init.c:10: delay_20ms();
call _delay_20ms
;source-doc/base-drv/./usb-init.c:12: ch_cmd_set_usb_mode(CH_MODE_HOST_RESET);
ld l,0x07
call _ch_cmd_set_usb_mode
;source-doc/base-drv/./usb-init.c:13: delay_20ms();
call _delay_20ms
;source-doc/base-drv/./usb-init.c:15: ch_cmd_set_usb_mode(CH_MODE_HOST);
ld l,0x06
call _ch_cmd_set_usb_mode
;source-doc/base-drv/./usb-init.c:16: delay_20ms();
call _delay_20ms
;source-doc/base-drv/./ch376.h:160: ch_command(CH_CMD_WRITE_VAR8);
ld l,0x0b
call _ch_command
;source-doc/base-drv/./ch376.h:161: CH376_DATA_PORT = CH_VAR_RETRY_TIMES;
ld a,0x25
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./ch376.h:162: delay();
call _delay
;source-doc/base-drv/./ch376.h:163: CH376_DATA_PORT = retry << 6 | (number_of_retries & 0x1F);
ld a,0xc0
or 0x1f
ld bc,_CH376_DATA_PORT
out (c),a
;source-doc/base-drv/./ch376.h:164: delay();
call _delay
;source-doc/base-drv/./usb-init.c:20: return USB_ERR_OK;
ld l,0x00
;source-doc/base-drv/./usb-init.c:21: }
ret
;source-doc/base-drv/./usb-init.c:25: void chnative_init(void) {
; ---------------------------------
; Function chnative_init
; ---------------------------------
_chnative_init:
;source-doc/base-drv/./usb-init.c:26: memset(get_usb_work_area(), 0, sizeof(_usb_state));
ld hl,_x
push hl
ld hl,0x0000
push hl
ld l,0x69
push hl
call _memset_callee
;source-doc/base-drv/./usb-init.c:28: ch_cmd_reset_all();
call _ch_cmd_reset_all
;source-doc/base-drv/./usb-init.c:30: delay_medium();
call _delay_medium
;source-doc/base-drv/./usb-init.c:32: if (!ch_probe()) {
call _ch_probe
ld a, l
or a
jr NZ,l_chnative_init_00102
;source-doc/base-drv/./usb-init.c:33: print_string("\r\nCH376: NOT PRESENT$");
;source-doc/base-drv/./usb-init.c:34: return;
ld hl,usb_init_str_0
jp _print_string
l_chnative_init_00102:
;source-doc/base-drv/./usb-init.c:37: print_string("\r\nCH376: PRESENT (VER $");
ld hl,usb_init_str_1
call _print_string
;source-doc/base-drv/./usb-init.c:38: print_hex(ch_cmd_get_ic_version());
call _ch_cmd_get_ic_version
call _print_hex
;source-doc/base-drv/./usb-init.c:39: print_string("); $");
ld hl,usb_init_str_2
call _print_string
;source-doc/base-drv/./usb-init.c:41: usb_host_bus_reset();
call _usb_host_bus_reset
;source-doc/base-drv/./usb-init.c:43: for (uint8_t i = 0; i < 4; i++) {
ld c,0x00
l_chnative_init_00107:
ld a, c
sub 0x04
jr NC,l_chnative_init_00105
;source-doc/base-drv/./usb-init.c:44: const uint8_t r = ch_very_short_wait_int_and_get_();
push bc
call _ch_very_short_wait_int_and_get
ld a, l
pop bc
;source-doc/base-drv/./usb-init.c:46: if (r == USB_INT_CONNECT) {
sub 0x81
jr NZ,l_chnative_init_00108
;source-doc/base-drv/./usb-init.c:47: print_string("USB: CONNECTED$");
ld hl,usb_init_str_3
call _print_string
;source-doc/base-drv/./usb-init.c:49: enumerate_all_devices();
jp _enumerate_all_devices
;source-doc/base-drv/./usb-init.c:51: return;
jr l_chnative_init_00109
l_chnative_init_00108:
;source-doc/base-drv/./usb-init.c:43: for (uint8_t i = 0; i < 4; i++) {
inc c
jr l_chnative_init_00107
l_chnative_init_00105:
;source-doc/base-drv/./usb-init.c:55: print_string("USB: DISCONNECTED$");
ld hl,usb_init_str_4
jp _print_string
l_chnative_init_00109:
;source-doc/base-drv/./usb-init.c:56: }
ret
usb_init_str_0:
DEFB 0x0d
DEFB 0x0a
DEFM "CH376: NOT PRESENT$"
DEFB 0x00
usb_init_str_1:
DEFB 0x0d
DEFB 0x0a
DEFM "CH376: PRESENT (VER $"
DEFB 0x00
usb_init_str_2:
DEFM "); $"
DEFB 0x00
usb_init_str_3:
DEFM "USB: CONNECTED$"
DEFB 0x00
usb_init_str_4:
DEFM "USB: DISCONNECTED$"
DEFB 0x00

274
Source/HBIOS/ch376-native/base-drv/usb_state.c.s

@ -0,0 +1,274 @@
;
; Generated from source-doc/base-drv/./usb_state.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/./usb_state.c:13: device_config *find_device_config(const usb_device_type requested_type) {
; ---------------------------------
; Function find_device_config
; ---------------------------------
_find_device_config:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/./usb_state.c:14: _usb_state *const p = get_usb_work_area();
;source-doc/base-drv/./usb_state.c:16: const device_config *p_config = first_device_config(p);
ld hl,_x
call _first_device_config
;source-doc/base-drv/./usb_state.c:17: while (p_config) {
l_find_device_config_00103:
ld a, d
or e
jr Z,l_find_device_config_00105
;source-doc/base-drv/./usb_state.c:18: const uint8_t type = p_config->type;
ld l, e
ld h, d
ld a, (hl)
and 0x0f
ld c, a
;source-doc/base-drv/./usb_state.c:20: if (type == requested_type)
ld a,(ix+4)
sub c
jr NZ,l_find_device_config_00102
;source-doc/base-drv/./usb_state.c:21: return (device_config *)p_config;
ex de, hl
jr l_find_device_config_00106
l_find_device_config_00102:
;source-doc/base-drv/./usb_state.c:23: p_config = next_device_config(p, p_config);
ld hl,_x
call _next_device_config
jr l_find_device_config_00103
l_find_device_config_00105:
;source-doc/base-drv/./usb_state.c:26: return NULL;
ld hl,0x0000
l_find_device_config_00106:
;source-doc/base-drv/./usb_state.c:27: }
pop ix
ret
_device_config_sizes:
DEFB +0x00
DEFB +0x11
DEFB +0x11
DEFB +0x0c
DEFB +0x06
DEFB 0x00
DEFB 0x00
;source-doc/base-drv/./usb_state.c:30: device_config *find_first_free(void) {
; ---------------------------------
; Function find_first_free
; ---------------------------------
_find_first_free:
;source-doc/base-drv/./usb_state.c:31: _usb_state *const boot_state = get_usb_work_area();
;source-doc/base-drv/./usb_state.c:34: device_config *p = first_device_config(boot_state);
ld hl,_x
call _first_device_config
;source-doc/base-drv/./usb_state.c:35: while (p) {
l_find_first_free_00103:
ld a, d
or e
jr Z,l_find_first_free_00105
;source-doc/base-drv/./usb_state.c:36: if (p->type == 0)
ld l, e
ld h, d
ld a, (hl)
and 0x0f
jr NZ,l_find_first_free_00102
;source-doc/base-drv/./usb_state.c:37: return p;
ex de, hl
jr l_find_first_free_00106
l_find_first_free_00102:
;source-doc/base-drv/./usb_state.c:39: p = next_device_config(boot_state, p);
ld hl,_x
call _next_device_config
jr l_find_first_free_00103
l_find_first_free_00105:
;source-doc/base-drv/./usb_state.c:42: return NULL;
ld hl,0x0000
l_find_first_free_00106:
;source-doc/base-drv/./usb_state.c:43: }
ret
;source-doc/base-drv/./usb_state.c:45: device_config *first_device_config(const _usb_state *const p) __sdcccall(1) { return (device_config *)&p->device_configs[0]; }
; ---------------------------------
; Function first_device_config
; ---------------------------------
_first_device_config:
ex de, hl
inc de
inc de
ret
;source-doc/base-drv/./usb_state.c:47: device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1) {
; ---------------------------------
; Function next_device_config
; ---------------------------------
_next_device_config:
ld c, l
ld b, h
;source-doc/base-drv/./usb_state.c:48: if (p->type == 0)
ld l, e
ld h, d
ld a, (hl)
and 0x0f
jr NZ,l_next_device_config_00102
;source-doc/base-drv/./usb_state.c:49: return NULL;
ld de,0x0000
jr l_next_device_config_00105
l_next_device_config_00102:
;source-doc/base-drv/./usb_state.c:51: const uint8_t size = device_config_sizes[p->type];
ld l, e
ld h, d
ld a, (hl)
and 0x0f
add a, +((_device_config_sizes) & 0xFF)
ld l, a
ld a,0x00
adc a, +((_device_config_sizes) / 256)
ld h, a
ld l, (hl)
;source-doc/base-drv/./usb_state.c:58: const uint8_t *_p = (uint8_t *)p;
;source-doc/base-drv/./usb_state.c:59: device_config *const result = (device_config *)(_p + size);
ld h,0x00
add hl, de
ex de, hl
;source-doc/base-drv/./usb_state.c:61: if (result >= (device_config *)&usb_state->device_configs_end)
ld hl,0x0068
add hl, bc
ld a, e
sub l
ld a, d
sbc a, h
ret C
;source-doc/base-drv/./usb_state.c:62: return NULL;
ld de,0x0000
;source-doc/base-drv/./usb_state.c:64: return result;
l_next_device_config_00105:
;source-doc/base-drv/./usb_state.c:65: }
ret
;source-doc/base-drv/./usb_state.c:68: device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1) {
; ---------------------------------
; Function get_usb_device_config
; ---------------------------------
_get_usb_device_config:
push ix
ld ix,0
add ix,sp
dec sp
ld (ix-1),a
;source-doc/base-drv/./usb_state.c:69: const _usb_state *const usb_state = get_usb_work_area();
;source-doc/base-drv/./usb_state.c:71: uint8_t counter = 1;
ld c,0x01
;source-doc/base-drv/./usb_state.c:73: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
push bc
ld hl,_x
call _first_device_config
pop bc
ld b,0x01
l_get_usb_device_config_00112:
ld a, d
or e
jr Z,l_get_usb_device_config_00105
;source-doc/base-drv/./usb_state.c:74: if (p->type == USB_IS_FLOPPY) {
ld l, e
ld h, d
ld a, (hl)
and 0x0f
dec a
jr NZ,l_get_usb_device_config_00113
;source-doc/base-drv/./usb_state.c:75: if (counter == device_index)
ld a,(ix-1)
sub b
;source-doc/base-drv/./usb_state.c:76: return p;
jr Z,l_get_usb_device_config_00117
;source-doc/base-drv/./usb_state.c:77: counter++;
inc b
ld c, b
l_get_usb_device_config_00113:
;source-doc/base-drv/./usb_state.c:73: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
push bc
ld hl,_x
call _next_device_config
pop bc
jr l_get_usb_device_config_00112
l_get_usb_device_config_00105:
;source-doc/base-drv/./usb_state.c:81: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
push bc
ld hl,_x
call _first_device_config
pop bc
l_get_usb_device_config_00115:
ld a, d
or e
jr Z,l_get_usb_device_config_00110
;source-doc/base-drv/./usb_state.c:82: if (p->type == USB_IS_MASS_STORAGE) {
ld l, e
ld h, d
ld a, (hl)
and 0x0f
sub 0x02
jr NZ,l_get_usb_device_config_00116
;source-doc/base-drv/./usb_state.c:83: if (counter == device_index)
ld a,(ix-1)
sub c
;source-doc/base-drv/./usb_state.c:84: return p;
jr Z,l_get_usb_device_config_00117
;source-doc/base-drv/./usb_state.c:85: counter++;
inc c
l_get_usb_device_config_00116:
;source-doc/base-drv/./usb_state.c:81: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
push bc
ld hl,_x
call _next_device_config
pop bc
jr l_get_usb_device_config_00115
l_get_usb_device_config_00110:
;source-doc/base-drv/./usb_state.c:89: return NULL; // is not a usb device
ld de,0x0000
l_get_usb_device_config_00117:
;source-doc/base-drv/./usb_state.c:90: }
inc sp
pop ix
ret

158
Source/HBIOS/ch376-native/base-drv/work-area.c.s

@ -0,0 +1,158 @@
;
; Generated from source-doc/base-drv/./work-area.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_x:
DEFS 105
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
_x:
DEFB 0x00
DEFB +0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB +0x00

134
Source/HBIOS/ch376-native/cruntime.asm

@ -0,0 +1,134 @@
_memset_callee:
pop af ; return address
pop bc ; address to be set
pop de ; value to be set
pop hl ; number of bytes to set
push af ; restore return address
ld a, b
or c
ret z
ld a, e
push hl
pop de
ret z
ld (hl), a
inc de
dec bc
ld a, b
or c
ret Z
push hl
ldir
pop hl
ret
; _strlen_fastcall:
; ; enter: hl = char *s
; ;
; ; exit : hl = length
; ; bc = -(length + 1)
; ; a = 0
; ; z flag set if 0 length
; ; carry reset
; ;
; ; uses : af, bc, hl
; xor a
; ld c,a
; ld b,a
; cpir
; ld hl,$ffff
; sbc hl,bc
; ret
_memcpy_callee:
pop af
pop bc
pop hl
pop de
push af
; enter : bc = size_t n
; hl = void *s2 = src
; de = void *s1 = dst
;
; exit : hl = void *s1 = dst
; de = ptr in s1 to one byte past last byte copied
; bc = 0
; carry reset
;
; uses : af, bc, de, hl
ld a,b
or c
jr Z,zero_n
asm0_memcpy:
push de
ldir
pop hl
or a
ret
zero_n:
push de
pop hl
ret
; _strcat_callee:
; pop hl
; pop de
; ex (sp),hl
; ; enter : hl = char *s2 = src
; ; de = char *s1 = dst
; ;
; ; exit : hl = char *s1 = dst
; ; de = ptr in s1 to terminating 0
; ;
; ; uses : af, bc, de, hl
; push de ; save dst
; ex de,hl
; call __str_locate_nul ; a = 0
; ex de,hl
; loop: ; append s2 to s1
; cp (hl)
; ldi
; jr NZ,loop
; ENDIF
; pop hl ; hl = dst
; dec de
; ret
; __str_locate_nul:
; ; enter : hl = char *s
; ;
; ; exit : hl = ptr in s to terminating 0
; ; bc = -(strlen + 1)
; ; a = 0
; ; carry reset
; ;
; ; uses : af, bc, hl
; xor a
; ld c,a
; ld b,a
; cpir
; dec hl
; ret

32
Source/HBIOS/ch376-native/print.asm

@ -0,0 +1,32 @@
; HL = unsigned 16 bit number to write out
; call CHPUT to write a single ascii character (in A)
_print_uint16:
ld e, 0
ld bc, -10000
call num1
ld bc, -1000
call num1
ld bc, -100
call num1
ld c, -10
call num1
ld c, b
num1: ld a, '0'-1
num2: inc a
add hl, bc
jr c, num2
sbc hl, bc
cp '0'
jr nz, num3
ld a, e
cp 1
ret nz
ld a, '0'
num3:
ld e, 1
jp COUT

0
Source/HBIOS/ch376-native/root.md

3
Source/HBIOS/ch376-native/scsi-drv.s

@ -0,0 +1,3 @@
; Generated File -- not to be modify directly
#include "ch376-native/scsi-drv/scsi-init.c.s"
#include "ch376-native/scsi-drv/class_scsi.c.s"

952
Source/HBIOS/ch376-native/scsi-drv/class_scsi.c.s

@ -0,0 +1,952 @@
;
; Generated from source-doc/scsi-drv/./class_scsi.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_scsi_command_block_wrapper:
DEFS 15
_next_tag:
DEFS 2
_csw:
DEFS 13
_scsi_read_capacity:
DEFS 12
_scsi_packet_inquiry:
DEFS 12
_scsi_packet_request_sense:
DEFS 12
_cbw:
DEFS 27
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/scsi-drv/./class_scsi.c:11: usb_error do_scsi_cmd(device_config_storage *const dev,
; ---------------------------------
; Function do_scsi_cmd
; ---------------------------------
_do_scsi_cmd:
push ix
ld ix,0
add ix,sp
ld hl, -6
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:16: cbw->dCBWTag[0] = next_tag++;
ld c,(ix+6)
ld b,(ix+7)
ld hl,0x0004
add hl, bc
ex (sp), hl
ld de, (_next_tag)
ld hl, (_next_tag)
inc hl
ld (_next_tag), hl
pop hl
push hl
ld (hl), e
inc hl
ld (hl), d
;source-doc/scsi-drv/./class_scsi.c:18: if (!send)
bit 0,(ix+10)
jr NZ,l_do_scsi_cmd_00102
;source-doc/scsi-drv/./class_scsi.c:19: cbw->bmCBWFlags = 0x80;
ld hl,0x000c
add hl, bc
ld (hl),0x80
l_do_scsi_cmd_00102:
;source-doc/scsi-drv/./class_scsi.c:22: &dev->endpoints[ENDPOINT_BULK_OUT]));
ld e,(ix+4)
ld d,(ix+5)
ld hl,0x0003
add hl, de
ld (ix-4),l
ld (ix-3),h
ld l, e
ld h, d
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld l,(ix+6)
ld h,(ix+7)
push bc
push de
push hl
ld l,(ix-4)
ld h,(ix-3)
ex (sp), hl
push af
inc sp
ld iy,0x001f
push iy
push hl
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
ld a, l
pop de
pop bc
ld (_result+0),a
or a
jr Z,l_do_scsi_cmd_00104
ld l, a
jp l_do_scsi_cmd_00119
l_do_scsi_cmd_00104:
;source-doc/scsi-drv/./class_scsi.c:24: if (cbw->dCBWDataTransferLength != 0) {
ld hl,8
add hl, bc
ld c, (hl)
inc hl
ld b, (hl)
inc hl
inc hl
ld a, (hl)
dec hl
ld l, (hl)
or l
or b
or c
jr Z,l_do_scsi_cmd_00113
;source-doc/scsi-drv/./class_scsi.c:27: &dev->endpoints[ENDPOINT_BULK_IN]));
ld (ix-2),c
ld (ix-1),b
ld c,(ix+8)
ld b,(ix+9)
;source-doc/scsi-drv/./class_scsi.c:25: if (!send) {
bit 0,(ix+10)
jr NZ,l_do_scsi_cmd_00110
;source-doc/scsi-drv/./class_scsi.c:27: &dev->endpoints[ENDPOINT_BULK_IN]));
ld iy,0x0006
add iy, de
ld l, e
ld h, d
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
push de
push iy
push af
inc sp
ld l,(ix-2)
ld h,(ix-1)
push hl
push bc
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
ld a, l
pop de
ld (_result+0),a
or a
jr Z,l_do_scsi_cmd_00113
ld l, a
jr l_do_scsi_cmd_00119
l_do_scsi_cmd_00110:
;source-doc/scsi-drv/./class_scsi.c:31: &dev->endpoints[ENDPOINT_BULK_OUT]));
ld l, e
ld h, d
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
push de
ld l,(ix-4)
ld h,(ix-3)
push hl
push af
inc sp
ld l,(ix-2)
ld h,(ix-1)
push hl
push bc
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
ld a, l
pop de
ld (_result+0),a
or a
jr Z,l_do_scsi_cmd_00113
ld l, a
jr l_do_scsi_cmd_00119
l_do_scsi_cmd_00113:
;source-doc/scsi-drv/./class_scsi.c:36: usb_data_in_transfer((uint8_t *)&csw, sizeof(_scsi_command_status_wrapper), dev->address, &dev->endpoints[ENDPOINT_BULK_IN]));
ld hl,0x0006
add hl, de
ex de,hl
ld c,e
ld b,d
ld a, (hl)
rlca
rlca
rlca
rlca
and 0x0f
ld d, a
push bc
push de
inc sp
ld hl,0x000d
push hl
ld hl,_csw
push hl
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
ld a, l
ld (_result+0),a
or a
jr Z,l_do_scsi_cmd_00115
ld l, a
jr l_do_scsi_cmd_00119
l_do_scsi_cmd_00115:
;source-doc/scsi-drv/./class_scsi.c:38: if (csw.bCSWStatus != 0 && csw.dCSWTag[0] != cbw->dCBWTag[0])
ld a, (_csw + 12)
or a
jr Z,l_do_scsi_cmd_00117
ld bc, (_csw + 4)
pop hl
ld e,(hl)
push hl
inc hl
ld h, (hl)
ld l, e
xor a
sbc hl,bc
jr Z,l_do_scsi_cmd_00117
;source-doc/scsi-drv/./class_scsi.c:39: return USB_ERR_FAIL;
ld l,0x0e
jr l_do_scsi_cmd_00119
l_do_scsi_cmd_00117:
;source-doc/scsi-drv/./class_scsi.c:41: return USB_ERR_OK;
ld l,0x00
l_do_scsi_cmd_00119:
;source-doc/scsi-drv/./class_scsi.c:42: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:46: usb_error get_scsi_read_capacity(device_config_storage *const dev, scsi_read_capacity_result *cap_result) {
; ---------------------------------
; Function get_scsi_read_capacity
; ---------------------------------
_get_scsi_read_capacity:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:48: cbw_scsi.cbw = scsi_command_block_wrapper;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:49: cbw_scsi.read_capacity = scsi_read_capacity;
ld hl,15
add hl, sp
ex de, hl
ld bc,0x000c
ld hl,_scsi_read_capacity
ldir
;source-doc/scsi-drv/./class_scsi.c:51: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),0x00
;source-doc/scsi-drv/./class_scsi.c:52: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_read_capacity);
ld (ix-13),0x0c
;source-doc/scsi-drv/./class_scsi.c:53: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_read_capacity_result);
ld (ix-19),0x08
xor a
ld (ix-18),a
ld (ix-17),a
ld (ix-16),a
;source-doc/scsi-drv/./class_scsi.c:55: return do_scsi_cmd(dev, &cbw_scsi.cbw, cap_result, false);
ld c,(ix+6)
ld b,(ix+7)
xor a
push af
inc sp
push bc
ld hl,3
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/./class_scsi.c:56: }
ld sp,ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:60: usb_error scsi_inquiry(device_config_storage *const dev, scsi_inquiry_result *inq_result) {
; ---------------------------------
; Function scsi_inquiry
; ---------------------------------
_scsi_inquiry:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:62: cbw_scsi.cbw = scsi_command_block_wrapper;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:63: cbw_scsi.inquiry = scsi_packet_inquiry;
ld hl,15
add hl, sp
ex de, hl
ld bc,0x000c
ld hl,_scsi_packet_inquiry
ldir
;source-doc/scsi-drv/./class_scsi.c:65: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),0x00
;source-doc/scsi-drv/./class_scsi.c:66: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_inquiry);
ld (ix-13),0x0c
;source-doc/scsi-drv/./class_scsi.c:67: cbw_scsi.cbw.dCBWDataTransferLength = 0x24;
ld (ix-19),0x24
xor a
ld (ix-18),a
ld (ix-17),a
ld (ix-16),a
;source-doc/scsi-drv/./class_scsi.c:69: return do_scsi_cmd(dev, &cbw_scsi.cbw, inq_result, false);
ld c,(ix+6)
ld b,(ix+7)
xor a
push af
inc sp
push bc
ld hl,3
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/./class_scsi.c:70: }
ld sp,ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:72: usb_error scsi_test(device_config_storage *const dev) {
; ---------------------------------
; Function scsi_test
; ---------------------------------
_scsi_test:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:74: cbw_scsi.cbw = scsi_command_block_wrapper;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:75: memset(&cbw_scsi.test, 0, sizeof(_scsi_packet_test));
ld hl,15
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x0c
push hl
call _memset_callee
;source-doc/scsi-drv/./class_scsi.c:77: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),0x00
;source-doc/scsi-drv/./class_scsi.c:78: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_test);
ld (ix-13),0x0c
;source-doc/scsi-drv/./class_scsi.c:79: cbw_scsi.cbw.dCBWDataTransferLength = 0;
ld hl,8
add hl, sp
xor a
ld (hl),a
inc hl
ld (hl),a
inc hl
ld (hl),a
inc hl
ld (hl),a
;source-doc/scsi-drv/./class_scsi.c:81: return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false);
xor a
push af
inc sp
ld hl,0x0000
push hl
ld hl,3
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/./class_scsi.c:82: }
ld sp,ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:86: usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result) {
; ---------------------------------
; Function scsi_request_sense
; ---------------------------------
_scsi_request_sense:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:88: cbw_scsi.cbw = scsi_command_block_wrapper;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:89: cbw_scsi.request_sense = scsi_packet_request_sense;
ld hl,15
add hl, sp
ex de, hl
ld bc,0x000c
ld hl,_scsi_packet_request_sense
ldir
;source-doc/scsi-drv/./class_scsi.c:91: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),0x00
;source-doc/scsi-drv/./class_scsi.c:92: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_request_sense);
ld (ix-13),0x0c
;source-doc/scsi-drv/./class_scsi.c:93: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_sense_result);
ld (ix-19),0x12
xor a
ld (ix-18),a
ld (ix-17),a
ld (ix-16),a
;source-doc/scsi-drv/./class_scsi.c:95: return do_scsi_cmd(dev, &cbw_scsi.cbw, sens_result, false);
ld c,(ix+6)
ld b,(ix+7)
xor a
push af
inc sp
push bc
ld hl,3
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/./class_scsi.c:96: }
ld sp,ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:98: usb_error scsi_sense_init(device_config_storage *const dev) {
; ---------------------------------
; Function scsi_sense_init
; ---------------------------------
_scsi_sense_init:
ld hl, -18
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:102: while ((result = scsi_test(dev)) && --counter > 0)
ld c,0x03
l_scsi_sense_init_00102:
push bc
ld hl,22
add hl, sp
ld c, (hl)
inc hl
ld b, (hl)
push bc
call _scsi_test
pop af
ld a, l
pop bc
ld (_result+0), a
or a
jr Z,l_scsi_sense_init_00104
dec c
jr Z,l_scsi_sense_init_00104
;source-doc/scsi-drv/./class_scsi.c:103: scsi_request_sense(dev, &response);
push bc
ld hl,2
add hl, sp
push hl
ld hl,24
add hl, sp
ld c, (hl)
inc hl
ld b, (hl)
push bc
call _scsi_request_sense
pop af
pop af
pop bc
jr l_scsi_sense_init_00102
l_scsi_sense_init_00104:
;source-doc/scsi-drv/./class_scsi.c:105: return result;
ld a, (_result+0)
ld l, a
;source-doc/scsi-drv/./class_scsi.c:106: }
ld iy,18
add iy, sp
ld sp, iy
ret
;source-doc/scsi-drv/./class_scsi.c:110: usb_error scsi_read(device_config_storage *const dev, uint8_t *const buffer) {
; ---------------------------------
; Function scsi_read
; ---------------------------------
_scsi_read:
push ix
ld ix,0
add ix,sp
push af
;source-doc/scsi-drv/./class_scsi.c:111: memset(&cbw, 0, sizeof(cbw_scsi_read_write));
ld hl,_cbw
push hl
ld hl,0x0000
push hl
ld l,0x1b
push hl
call _memset_callee
;source-doc/scsi-drv/./class_scsi.c:112: cbw.cbw = scsi_command_block_wrapper;
ld de,_cbw
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:114: cbw.cbw.bCBWLUN = 0;
;source-doc/scsi-drv/./class_scsi.c:115: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write);
ld hl,0x0c00
ld ((_cbw + 13)),hl
;source-doc/scsi-drv/./class_scsi.c:116: cbw.cbw.dCBWDataTransferLength = 512;
ld hl,0x0200
ld (_cbw + 8),hl
ld h, l
ld (_cbw + 8 + 2),hl
;source-doc/scsi-drv/./class_scsi.c:118: cbw.scsi_cmd.operation_code = 0x28; // read operation
ld hl, +(_cbw + 15)
ld (hl),0x28
;source-doc/scsi-drv/./class_scsi.c:119: cbw.scsi_cmd.transfer_len[1] = 1;
ld hl, +(_cbw + 23)
ld (hl),0x01
;source-doc/scsi-drv/./class_scsi.c:120: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24;
ld c,(ix+4)
ld b,(ix+5)
ld hl,0x000c
add hl, bc
pop af
push hl
inc hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 17)),a
;source-doc/scsi-drv/./class_scsi.c:121: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16;
pop hl
push hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 18)),a
;source-doc/scsi-drv/./class_scsi.c:122: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8;
pop hl
push hl
inc hl
ld a,(hl)
ld ((_cbw + 19)),a
;source-doc/scsi-drv/./class_scsi.c:123: cbw.scsi_cmd.lba[3] = dev->current_lba;
ld de,_cbw + 20
pop hl
ld a,(hl)
push hl
ld (de), a
;source-doc/scsi-drv/./class_scsi.c:125: result = do_scsi_cmd(dev, &cbw.cbw, buffer, false);
ld e,(ix+6)
ld d,(ix+7)
xor a
push af
inc sp
push de
ld hl,_cbw
push hl
push bc
call _do_scsi_cmd
pop af
pop af
pop af
inc sp
ld a, l
;source-doc/scsi-drv/./class_scsi.c:127: if (result == USB_ERR_OK)
ld (_result+0),a
or a
jr NZ,l_scsi_read_00102
;source-doc/scsi-drv/./class_scsi.c:128: dev->current_lba++;
pop hl
ld c,(hl)
push hl
inc hl
ld b, (hl)
inc hl
ld e, (hl)
inc hl
ld d, (hl)
inc c
jr NZ,l_scsi_read_00110
inc b
jr NZ,l_scsi_read_00110
inc de
l_scsi_read_00110:
pop hl
push hl
ld (hl), c
inc hl
ld (hl), b
inc hl
ld (hl), e
inc hl
ld (hl), d
l_scsi_read_00102:
;source-doc/scsi-drv/./class_scsi.c:129: return result;
ld a, (_result+0)
ld l, a
;source-doc/scsi-drv/./class_scsi.c:130: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:132: usb_error scsi_write(device_config_storage *const dev, uint8_t *const buffer) {
; ---------------------------------
; Function scsi_write
; ---------------------------------
_scsi_write:
push ix
ld ix,0
add ix,sp
push af
;source-doc/scsi-drv/./class_scsi.c:133: memset(&cbw, 0, sizeof(cbw_scsi_read_write));
ld hl,_cbw
push hl
ld hl,0x0000
push hl
ld l,0x1b
push hl
call _memset_callee
;source-doc/scsi-drv/./class_scsi.c:134: cbw.cbw = scsi_command_block_wrapper;
ld de,_cbw
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:136: cbw.cbw.bCBWLUN = 0;
;source-doc/scsi-drv/./class_scsi.c:137: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write);
ld hl,0x0c00
ld ((_cbw + 13)),hl
;source-doc/scsi-drv/./class_scsi.c:138: cbw.cbw.dCBWDataTransferLength = 512;
ld hl,0x0200
ld (_cbw + 8),hl
ld h, l
ld (_cbw + 8 + 2),hl
;source-doc/scsi-drv/./class_scsi.c:140: cbw.scsi_cmd.operation_code = 0x2A; // write operation
ld hl, +(_cbw + 15)
ld (hl),0x2a
;source-doc/scsi-drv/./class_scsi.c:141: cbw.scsi_cmd.transfer_len[1] = 1;
ld hl, +(_cbw + 23)
ld (hl),0x01
;source-doc/scsi-drv/./class_scsi.c:142: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24;
ld c,(ix+4)
ld b,(ix+5)
ld hl,0x000c
add hl, bc
pop af
push hl
inc hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 17)),a
;source-doc/scsi-drv/./class_scsi.c:143: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16;
pop hl
push hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 18)),a
;source-doc/scsi-drv/./class_scsi.c:144: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8;
pop hl
push hl
inc hl
ld a,(hl)
ld ((_cbw + 19)),a
;source-doc/scsi-drv/./class_scsi.c:145: cbw.scsi_cmd.lba[3] = dev->current_lba;
ld de,_cbw + 20
pop hl
ld a,(hl)
push hl
ld (de), a
;source-doc/scsi-drv/./class_scsi.c:147: result = do_scsi_cmd(dev, &cbw.cbw, buffer, true);
ld e,(ix+6)
ld d,(ix+7)
ld a,0x01
push af
inc sp
push de
ld hl,_cbw
push hl
push bc
call _do_scsi_cmd
pop af
pop af
pop af
inc sp
ld a, l
;source-doc/scsi-drv/./class_scsi.c:149: if (result == USB_ERR_OK)
ld (_result+0),a
or a
jr NZ,l_scsi_write_00102
;source-doc/scsi-drv/./class_scsi.c:150: dev->current_lba++;
pop hl
ld c,(hl)
push hl
inc hl
ld b, (hl)
inc hl
ld e, (hl)
inc hl
ld d, (hl)
inc c
jr NZ,l_scsi_write_00110
inc b
jr NZ,l_scsi_write_00110
inc de
l_scsi_write_00110:
pop hl
push hl
ld (hl), c
inc hl
ld (hl), b
inc hl
ld (hl), e
inc hl
ld (hl), d
l_scsi_write_00102:
;source-doc/scsi-drv/./class_scsi.c:151: return result;
ld a, (_result+0)
ld l, a
;source-doc/scsi-drv/./class_scsi.c:152: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/./class_scsi.c:154: usb_error scsi_eject(device_config_storage *const dev) {
; ---------------------------------
; Function scsi_eject
; ---------------------------------
_scsi_eject:
push ix
ld ix,0
add ix,sp
ld hl, -21
add hl, sp
ld sp, hl
;source-doc/scsi-drv/./class_scsi.c:156: cbw_scsi.cbw = scsi_command_block_wrapper;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x000f
ld hl,_scsi_command_block_wrapper
ldir
;source-doc/scsi-drv/./class_scsi.c:158: memset(&cbw_scsi.eject, 0, sizeof(_scsi_packet_eject));
ld hl,15
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x06
push hl
call _memset_callee
;source-doc/scsi-drv/./class_scsi.c:160: cbw_scsi.eject.operation_code = 0x1B;
ld (ix-6),0x1b
;source-doc/scsi-drv/./class_scsi.c:161: cbw_scsi.eject.loej = 1;
ld hl,19
add hl, sp
set 1, (hl)
;source-doc/scsi-drv/./class_scsi.c:163: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-8),0x00
;source-doc/scsi-drv/./class_scsi.c:164: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_eject);
ld (ix-7),0x06
;source-doc/scsi-drv/./class_scsi.c:165: cbw_scsi.cbw.dCBWDataTransferLength = 0;
ld hl,8
add hl, sp
xor a
ld (hl),a
inc hl
ld (hl),a
inc hl
ld (hl),a
inc hl
ld (hl),a
;source-doc/scsi-drv/./class_scsi.c:167: return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false);
xor a
push af
inc sp
ld hl,0x0000
push hl
ld hl,3
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/./class_scsi.c:168: }
ld sp,ix
pop ix
ret
_scsi_command_block_wrapper:
DEFB +0x55
DEFB +0x53
DEFB +0x42
DEFB +0x43
DEFW +0x0000
DEFW +0x0000
DEFB +0x00,0x00, +0x00, +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
_next_tag:
DEFW +0x0000
_csw:
DEFB +0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB +0x00
_scsi_read_capacity:
DEFB +0x25
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
_scsi_packet_inquiry:
DEFB +0x12
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x24
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
_scsi_packet_request_sense:
DEFB +0x03
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x12
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
_cbw:
DEFB +0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB +0x00,0x00, +0x00, +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB 0x00
DEFB +0x00
DEFB 0x00
DEFB 0x00
DEFB +0x00
DEFB 0x00
DEFB 0x00

162
Source/HBIOS/ch376-native/scsi-drv/init.c.s

@ -0,0 +1,162 @@
;
; Generated from source-doc/scsi-drv/./init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/scsi-drv/./init.c:13: uint8_t chscsi_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1) {
; ---------------------------------
; Function chscsi_seek
; ---------------------------------
_chscsi_seek:
push ix
ld ix,0
add ix,sp
ld c, l
ld b, h
;source-doc/scsi-drv/./init.c:14: storage_device->current_lba = lba;
ld a,(ix+4)
ld h,(ix+5)
add a,0x0c
ld l, a
jr NC,l_chscsi_seek_00103
inc h
l_chscsi_seek_00103:
ld (hl), e
inc hl
ld (hl), d
inc hl
ld (hl), c
inc hl
ld (hl), b
;source-doc/scsi-drv/./init.c:15: return 0;
xor a
;source-doc/scsi-drv/./init.c:16: }
pop ix
pop hl
pop bc
jp (hl)
;source-doc/scsi-drv/./init.c:18: void chscsi_init(void) {
; ---------------------------------
; Function chscsi_init
; ---------------------------------
_chscsi_init:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/scsi-drv/./init.c:21: do {
ld c,0x00
ld (ix-1),0x01
l_chscsi_init_00105:
;source-doc/scsi-drv/./init.c:22: device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index);
push bc
ld a,(ix-1)
call _get_usb_device_config
pop bc
;source-doc/scsi-drv/./init.c:24: if (storage_device == NULL)
ld a, d
or e
jr Z,l_chscsi_init_00107
;source-doc/scsi-drv/./init.c:27: const usb_device_type t = storage_device->type;
ld l, e
ld h, d
ld a, (hl)
and 0x0f
;source-doc/scsi-drv/./init.c:29: if (t == USB_IS_MASS_STORAGE) {
sub 0x02
jr NZ,l_chscsi_init_00106
;source-doc/scsi-drv/./init.c:30: storage_device->drive_index = storage_count++;
ld hl,0x0010
add hl, de
ld (hl), c
inc c
;source-doc/scsi-drv/./init.c:31: scsi_sense_init(storage_device);
push bc
push de
push de
call _scsi_sense_init
pop af
pop de
ld hl,_ch_scsi_fntbl
call _dio_add_entry
pop bc
l_chscsi_init_00106:
;source-doc/scsi-drv/./init.c:35: } while (++index != MAX_NUMBER_OF_STORAGE_DEVICES + 1);
inc (ix-1)
ld a,(ix-1)
sub 0x05
jr NZ,l_chscsi_init_00105
l_chscsi_init_00107:
;source-doc/scsi-drv/./init.c:37: if (storage_count == 0)
ld a, c
or a
;source-doc/scsi-drv/./init.c:38: return;
jr Z,l_chscsi_init_00110
;source-doc/scsi-drv/./init.c:40: print_string(" $");
push bc
ld hl,init_str_0
call _print_string
pop bc
;source-doc/scsi-drv/./init.c:41: print_uint16(storage_count);
ld h,0x00
ld l, c
call _print_uint16
;source-doc/scsi-drv/./init.c:42: print_string(" STORAGE DEVICES$");
ld hl,init_str_1
call _print_string
l_chscsi_init_00110:
;source-doc/scsi-drv/./init.c:43: }
inc sp
pop ix
ret
init_str_0:
DEFM " $"
DEFB 0x00
init_str_1:
DEFM " STORAGE DEVICES$"
DEFB 0x00

125
Source/HBIOS/ch376-native/scsi-drv/scsi-init.c.s

@ -0,0 +1,125 @@
;
; Generated from source-doc/scsi-drv/./scsi-init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/scsi-drv/./scsi-init.c:13: void chscsi_init(void) {
; ---------------------------------
; Function chscsi_init
; ---------------------------------
_chscsi_init:
push ix
ld ix,0
add ix,sp
push af
;source-doc/scsi-drv/./scsi-init.c:15: do {
ld (ix-1),0x01
l_chscsi_init_00105:
;source-doc/scsi-drv/./scsi-init.c:16: device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index);
ld a,(ix-1)
call _get_usb_device_config
;source-doc/scsi-drv/./scsi-init.c:18: if (storage_device == NULL)
ld a, d
or e
jr Z,l_chscsi_init_00107
;source-doc/scsi-drv/./scsi-init.c:21: const usb_device_type t = storage_device->type;
ld l, e
ld h, d
ld a, (hl)
and 0x0f
;source-doc/scsi-drv/./scsi-init.c:23: if (t == USB_IS_MASS_STORAGE) {
sub 0x02
jr NZ,l_chscsi_init_00106
;source-doc/scsi-drv/./scsi-init.c:24: storage_device->drive_index = storage_count++;
ld hl,0x0010
add hl, de
ld a,(_storage_count+0)
ld (ix-2),a
ld c,l
ld b,h
ld hl,_storage_count+0
inc (hl)
ld a,(ix-2)
ld (bc), a
;source-doc/scsi-drv/./scsi-init.c:25: scsi_sense_init(storage_device);
push de
push de
call _scsi_sense_init
pop af
pop de
;source-doc/scsi-drv/./scsi-init.c:26: dio_add_entry(ch_scsi_fntbl, storage_device);
ld hl,_ch_scsi_fntbl
call _dio_add_entry
l_chscsi_init_00106:
;source-doc/scsi-drv/./scsi-init.c:29: } while (++index != MAX_NUMBER_OF_DEVICES + 1);
inc (ix-1)
ld a,(ix-1)
sub 0x07
jr NZ,l_chscsi_init_00105
l_chscsi_init_00107:
;source-doc/scsi-drv/./scsi-init.c:31: if (storage_count == 0)
;source-doc/scsi-drv/./scsi-init.c:32: return;
;source-doc/scsi-drv/./scsi-init.c:34: print_device_mounted(" STORAGE DEVICE$", storage_count);
ld a,(_storage_count+0)
or a
jr Z,l_chscsi_init_00110
push af
inc sp
ld hl,scsi_init_str_0
push hl
call _print_device_mounted
pop af
inc sp
l_chscsi_init_00110:
;source-doc/scsi-drv/./scsi-init.c:35: }
ld sp, ix
pop ix
ret
scsi_init_str_0:
DEFM " STORAGE DEVICE$"
DEFB 0x00

13
Source/HBIOS/ch376-native/source-doc/.clang-format

@ -0,0 +1,13 @@
BasedOnStyle: LLVM
IndentWidth: 2
AlignConsecutiveMacros: true
ColumnLimit: 132
AlignConsecutiveAssignments: true
AlignConsecutiveDeclarations: true
AlignEscapedNewlines: true
AlignConsecutiveMacros: true
AlignEscapedNewlines: Right
BinPackArguments: true
BinPackParameters: false
IncludeBlocks: Preserve
SortIncludes: CaseInsensitive

238
Source/HBIOS/ch376-native/source-doc/base-drv/ch376.c

@ -0,0 +1,238 @@
#include "ch376.h"
#include "print.h"
usb_error result = 0;
void ch_command(const uint8_t command) __z88dk_fastcall {
uint8_t counter = 255;
while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0)
delay();
// if (counter == 0) {
// It appears that the Ch376 has become blocked
// command will fail and timeout will eventually be returned by the ch_xxx_wait_int_and_get_status
// todo consider a return value to allow callers to respond appropriately
// Experimentation would indicate that USB_RESET_ALL will still work to reset chip
// return;
// }
delay();
CH376_COMMAND_PORT = command;
delay();
}
extern usb_error ch_wait_int_and_get_status(const int16_t timeout) __z88dk_fastcall;
usb_error ch_long_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(5000); }
usb_error ch_short_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(100); }
usb_error ch_very_short_wait_int_and_get_status(void) { return ch_wait_int_and_get_status(10); }
usb_error ch_get_status(void) {
ch_command(CH_CMD_GET_STATUS);
uint8_t ch_status = CH376_DATA_PORT;
if (ch_status >= USB_FILERR_MIN && ch_status <= USB_FILERR_MAX)
return ch_status;
if (ch_status == CH_CMD_RET_SUCCESS)
return USB_ERR_OK;
if (ch_status == CH_USB_INT_SUCCESS)
return USB_ERR_OK;
if (ch_status == CH_USB_INT_CONNECT)
return USB_INT_CONNECT;
if (ch_status == CH_USB_INT_DISK_READ)
return USB_ERR_DISK_READ;
if (ch_status == CH_USB_INT_DISK_WRITE)
return USB_ERR_DISK_WRITE;
if (ch_status == CH_USB_INT_DISCONNECT) {
ch_cmd_set_usb_mode(5);
return USB_ERR_NO_DEVICE;
}
if (ch_status == CH_USB_INT_BUF_OVER)
return USB_ERR_DATA_ERROR;
ch_status &= 0x2F;
if (ch_status == 0x2A)
return USB_ERR_NAK;
if (ch_status == 0x2E)
return USB_ERR_STALL;
ch_status &= 0x23;
if (ch_status == 0x20)
return USB_ERR_TIMEOUT;
if (ch_status == 0x23)
return USB_TOKEN_OUT_OF_SYNC;
return USB_ERR_UNEXPECTED_STATUS_FROM_HOST;
}
void ch_cmd_reset_all(void) { ch_command(CH_CMD_RESET_ALL); }
inline uint8_t ch_cmd_check_exist(void) {
uint8_t complement;
ch_command(CH_CMD_CHECK_EXIST);
CH376_DATA_PORT = (uint8_t)~0x55;
delay();
complement = CH376_DATA_PORT;
return complement == 0x55;
// if (complement != 0x55)
// return false;
// ch_command(CH_CMD_CHECK_EXIST);
// CH376_DATA_PORT = (uint8_t)~0x89;
// delay();
// complement = CH376_DATA_PORT;
// return complement == 0x89;
}
uint8_t ch_probe(void) {
uint8_t i = 5;
do {
if (ch_cmd_check_exist())
return true;
delay_medium();
} while (--i != 0);
return false;
}
uint8_t ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall {
uint8_t result = 0;
CH376_COMMAND_PORT = CH_CMD_SET_USB_MODE;
delay();
CH376_DATA_PORT = mode;
delay();
uint8_t count = 127;
while (result != CH_CMD_RET_SUCCESS && result != CH_CMD_RET_ABORT && --count != 0) {
result = CH376_DATA_PORT;
delay();
}
return (result == CH_CMD_RET_SUCCESS) ? USB_ERR_OK : USB_ERR_FAIL;
}
uint8_t ch_cmd_get_ic_version(void) {
ch_command(CH_CMD_GET_IC_VER);
return CH376_DATA_PORT & 0x1f;
}
void ch_issue_token(const uint8_t toggle_bit, const uint8_t endpoint, const ch376_pid pid) {
ch_command(CH_CMD_ISSUE_TKN_X);
CH376_DATA_PORT = toggle_bit;
delay();
CH376_DATA_PORT = endpoint << 4 | pid;
delay();
}
void ch_issue_token_in(const endpoint_param *const endpoint) __z88dk_fastcall {
ch_issue_token(endpoint->toggle ? 0x80 : 0x00, endpoint->number, CH_PID_IN);
}
void ch_issue_token_out(const endpoint_param *const endpoint) __z88dk_fastcall {
ch_issue_token(endpoint->toggle ? 0x40 : 0x00, endpoint->number, CH_PID_OUT);
}
void ch_issue_token_out_ep0(void) { ch_issue_token(0x40, 0, CH_PID_OUT); }
void ch_issue_token_in_ep0(void) { ch_issue_token(0x80, 0, CH_PID_IN); }
void ch_issue_token_setup(void) { ch_issue_token(0, 0, CH_PID_SETUP); }
usb_error ch_data_in_transfer(uint8_t *buffer, int16_t buffer_size, endpoint_param *const endpoint) {
uint8_t count;
usb_error result;
if (buffer_size == 0)
return USB_ERR_OK;
USB_MODULE_LEDS = 0x01;
do {
ch_issue_token_in(endpoint);
result = ch_long_wait_int_and_get_status();
CHECK(result);
endpoint->toggle = !endpoint->toggle;
count = ch_read_data(buffer);
if (count == 0) {
USB_MODULE_LEDS = 0x00;
return USB_ERR_DATA_ERROR;
}
buffer += count;
buffer_size -= count;
} while (buffer_size > 0);
USB_MODULE_LEDS = 0x00;
return USB_ERR_OK;
}
usb_error ch_data_in_transfer_n(uint8_t *const buffer, int8_t *const buffer_size, endpoint_param *const endpoint) {
uint8_t count;
usb_error result;
USB_MODULE_LEDS = 0x01;
ch_issue_token_in(endpoint);
CHECK(ch_long_wait_int_and_get_status());
endpoint->toggle = !endpoint->toggle;
count = ch_read_data(buffer);
*buffer_size = count;
USB_MODULE_LEDS = 0x00;
return USB_ERR_OK;
}
usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint) {
usb_error result;
const uint8_t number = endpoint->number;
const uint8_t max_packet_size = calc_max_packet_size(endpoint->max_packet_sizex);
USB_MODULE_LEDS = 0x02;
while (buffer_length > 0) {
const uint8_t size = max_packet_size < buffer_length ? max_packet_size : buffer_length;
buffer = ch_write_data(buffer, size);
buffer_length -= size;
ch_issue_token_out(endpoint);
CHECK(ch_long_wait_int_and_get_status());
endpoint->toggle = !endpoint->toggle;
}
USB_MODULE_LEDS = 0x00;
return USB_ERR_OK;
}
void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall {
ch_command(CH_CMD_SET_USB_ADDR);
CH376_DATA_PORT = device_address;
delay();
}

175
Source/HBIOS/ch376-native/source-doc/base-drv/ch376.h

@ -0,0 +1,175 @@
#ifndef __CH376
#define __CH376
#include "ch376inc.h"
#include "delay.h"
#include <stdlib.h>
typedef enum {
USB_ERR_OK = 0,
USB_ERR_NAK = 1,
USB_ERR_STALL = 2,
USB_ERR_TIMEOUT = 3,
USB_ERR_DATA_ERROR = 4,
USB_ERR_NO_DEVICE = 5,
USB_ERR_PANIC_BUTTON_PRESSED = 6,
USB_TOKEN_OUT_OF_SYNC = 7,
USB_ERR_UNEXPECTED_STATUS_FROM_HOST = 8,
USB_ERR_CODE_EXCEPTION = 9,
USB_ERR_MEDIA_CHANGED = 10,
USB_ERR_MEDIA_NOT_PRESENT = 11,
USB_ERR_CH376_BLOCKED = 12,
USB_ERR_CH376_TIMEOUT = 13,
USB_ERR_FAIL = 14,
USB_ERR_MAX = 14,
USB_ERR_OTHER = 15,
USB_ERR_DISK_READ = 0x1D,
USB_ERR_DISK_WRITE = 0x1E,
USB_FILERR_MIN = 0x41,
USB_ERR_OPEN_DIR = 0x41,
USB_ERR_MISS_FILE = 0x42,
USB_FILERR_MAX = 0xB4,
USB_INT_CONNECT = 0x81,
USB_BAD_ADDRESS = 0x82,
USB_ERR_OUT_OF_MEMORY = 0x83,
USB_ERR_BUFF_TO_LARGE = 0x84,
USB_ERROR_DEVICE_NOT_FOUND = 0x85,
} usb_error;
typedef enum { CH_NAK_RETRY_DONT = 0b00, CH_NAK_RETRY_INDEFINITE = 0b10, CH_NAK_RETRY_3S = 0b11 } ch_nak_retry_type;
typedef enum {
USB_NOT_SUPPORTED = 0,
USB_IS_FLOPPY = 1,
USB_IS_MASS_STORAGE = 2,
USB_IS_CDC = 3,
USB_IS_KEYBOARD = 4,
USB_IS_UNKNOWN = 6,
_USB_LAST_DEVICE_TYPE,
USB_IS_HUB = 15
} usb_device_type; // 4 bits only
typedef enum { ENDPOINT_BULK_OUT = 0, ENDPOINT_BULK_IN = 1, ENDPOINT_INTERRUPT_IN = 2 } usb_endpoint_type;
extern int printf(const char *msg, ...);
#if STACK_TRACE_ENABLED
#define trace_printf printf
#define CHECK(fn) \
{ \
result = fn; \
if (result != USB_ERR_OK && result != USB_ERR_STALL) { \
if (result != USB_TOKEN_OUT_OF_SYNC) \
printf("Error: %s:%d %d\r\n", __FILE__, __LINE__, result); \
return result; \
} \
}
#define RETURN_CHECK(fn) \
{ \
result = fn; \
if (result != USB_ERR_OK && result != USB_ERR_STALL) { \
if (result != USB_TOKEN_OUT_OF_SYNC) \
printf("Error: %s:%d %d\r\n", __FILE__, __LINE__, result); \
return result; \
} \
return result; \
}
#define TRACE_USB_ERROR(result) \
{ \
if (result != USB_ERR_OK) { \
printf("USB: %s:%d %d\r\n", __FILE__, __LINE__, result); \
} \
}
#else
extern usb_error result;
#define trace_printf(...)
#define CHECK(fn) \
{ \
result = fn; \
if (result != USB_ERR_OK) \
return result; \
}
#define RETURN_CHECK(fn) \
{ return fn; }
#define TRACE_USB_ERROR(result)
#endif
#define calc_max_packet_sizex(packet_size) (packet_size & 0x3FF)
#define calc_max_packet_size(packet_sizex) packet_sizex
typedef struct {
uint8_t toggle : 1;
uint8_t number : 3;
uint16_t max_packet_sizex : 10;
} endpoint_param;
#define CH_SPEED_FULL \
0 /* 12Mbps full speed FullSpeed ​​(default value) \
*/
#define CH_SPEED_LOW_FREQ 1 /* 1.5Mbps (modify frequency only) */
#define CH_SPEED_LOW 2 /* 1.5Mbps low speed LowSpeed */
#define CH_MODE_HOST_RESET 7
#define CH_MODE_HOST 6
typedef enum _ch376_pid { CH_PID_SETUP = DEF_USB_PID_SETUP, CH_PID_IN = DEF_USB_PID_IN, CH_PID_OUT = DEF_USB_PID_OUT } ch376_pid;
__sfr __banked __at(0xFF88) CH376_DATA_PORT;
__sfr __banked __at(0xFF89) CH376_COMMAND_PORT;
__sfr __banked __at(0xFF8A) USB_MODULE_LEDS;
extern void delay_20ms(void);
extern void delay_short(void);
extern void delay_medium(void);
extern void ch_command(const uint8_t command) __z88dk_fastcall;
extern usb_error ch_get_status(void);
extern usb_error ch_long_wait_int_and_get_status(void);
extern usb_error ch_short_wait_int_and_get_status(void);
extern usb_error ch_very_short_wait_int_and_get_status(void);
extern uint8_t ch_read_data(uint8_t *buffer) __sdcccall(1);
extern void ch_cmd_reset_all(void);
extern uint8_t ch_probe(void);
extern usb_error ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall;
extern uint8_t ch_cmd_get_ic_version(void);
extern const uint8_t *ch_write_data(const uint8_t *buffer, uint8_t length);
extern void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall;
extern usb_error ch_control_transfer_request_descriptor(const uint8_t descriptor_type) __z88dk_fastcall;
extern usb_error ch_control_transfer_set_address(const uint8_t device_address) __z88dk_fastcall;
extern usb_error ch_control_transfer_set_config(const uint8_t config_value) __z88dk_fastcall;
extern usb_error ch_data_in_transfer(uint8_t *buffer, int16_t data_length, endpoint_param *const endpoint);
extern usb_error ch_data_in_transfer_n(uint8_t *buffer, int8_t *const buffer_size, endpoint_param *const endpoint);
extern usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint);
inline void ch_configure_nak_retry(const ch_nak_retry_type retry, const uint8_t number_of_retries) {
ch_command(CH_CMD_WRITE_VAR8);
CH376_DATA_PORT = CH_VAR_RETRY_TIMES;
delay();
CH376_DATA_PORT = retry << 6 | (number_of_retries & 0x1F);
delay();
}
#define ch_configure_nak_retry_indefinite() ch_configure_nak_retry(CH_NAK_RETRY_INDEFINITE, 0x1F)
#define ch_configure_nak_retry_disable() ch_configure_nak_retry(CH_NAK_RETRY_DONT, 0x1F)
#define ch_configure_nak_retry_3s() ch_configure_nak_retry(CH_NAK_RETRY_3S, 0x1F)
extern void ch_issue_token_setup(void);
extern void ch_issue_token_out_ep0(void);
extern void ch_issue_token_in_ep0(void);
#endif

1311
Source/HBIOS/ch376-native/source-doc/base-drv/ch376inc.h

File diff suppressed because it is too large

9
Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.c

@ -0,0 +1,9 @@
#include "class_hub.h"
#include "protocol.h"
#include "usb_state.h"
const setup_packet cmd_get_hub_descriptor = {RT_DEVICE_TO_HOST | RT_CLASS | RT_DEVICE, 6, {0, 0x29}, {0, 0}, 8};
usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1) {
return usb_control_transfer(&cmd_get_hub_descriptor, hub_description, hub_config->address, hub_config->max_packet_size);
}

75
Source/HBIOS/ch376-native/source-doc/base-drv/class_hub.h

@ -0,0 +1,75 @@
#ifndef __CLASS_HUB
#define __CLASS_HUB
#include "ch376.h"
#include "protocol.h"
#include <stdlib.h>
/*
wHubCharacteristics:
D1...D0: Logical Power Switching Mode
00: Ganged power switching (all ports power at once)
01: Individual port power switching
1X: Reserved. Used only on 1.0 compliant hubs that implement no power switching
D2: Identifies a Compound Device
0: Hub is not part of a compound device.
1: Hub is part of a compound device.
D4...D3: Logical Power Switching Mode
00: Global Over-current Protection. The hub reports over-current as a summation
of all ports current draw, without a breakdown of individual port
over-current status.
01: Individual Port Over-current Protection. The hub reports over-current on a
per-port basis. Each port has an over-current status.
1X: No Over-current Protection. This option is allowed only for bus-powered
*/
typedef struct {
uint8_t bDescLength;
uint8_t bDescriptorType; /* HUB Descriptor Type 0x29 */
uint8_t bNbrPorts; /* Number of ports */
uint16_t wHubCharacteristics; /* Bitmap Hub Characteristics (see above) */
uint8_t bPwrOn2PwrGood; /* Time (*2 ms) from port power on to power good */
uint8_t bHubContrCurrent; /* Maximum current used by hub controller (mA).*/
uint8_t DeviceRemovable[1]; /* bits indicating deviceRemovable and portPwrCtrlMask */
} hub_descriptor;
typedef struct {
union {
struct {
uint8_t port_connection : 1;
uint8_t port_enable : 1;
uint8_t port_suspend : 1;
uint8_t port_over_current : 1;
uint8_t port_reset : 1;
uint8_t reserved : 3;
uint8_t port_power : 1;
uint8_t port_low_speed : 1;
uint8_t port_high_speed : 1;
uint8_t port_test : 1;
uint8_t port_indicator : 1;
};
uint16_t val;
} wPortStatus;
union {
struct {
uint8_t c_port_connection : 1;
uint8_t c_port_enable : 1;
uint8_t c_port_suspend : 1;
uint8_t c_port_over_current : 1;
uint8_t c_port_reset : 1;
};
uint16_t val;
} wPortChange;
} hub_port_status;
usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1);
#endif

11
Source/HBIOS/ch376-native/source-doc/base-drv/delay.h

@ -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

101
Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.c

@ -0,0 +1,101 @@
/**
* @file transfers.c
* @author Dean Netherton
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
* @version 1.0
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#include "dev_transfers.h"
#include "ch376.h"
#include "delay.h"
#include "protocol.h"
#include <stdlib.h>
/**
* @brief Perform a USB control transfer (in or out)
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
*
* @param device the usb device
* @param cmd_packet Pointer to the setup packet - top bit of bmRequestType indicate data direction
* @param buffer Pointer of data to send or receive into
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) {
return usb_control_transfer(cmd_packet, buffer, device->address, device->max_packet_size);
}
usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) {
usb_error result;
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT];
result = usb_data_out_transfer(buffer, buffer_size, dev->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}
usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) {
usb_error result;
endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN];
result = usb_data_in_transfer_n(buffer, buffer_size, dev->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, dev->address, dev->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}
usb_error usbdev_dat_in_trnsfer(device_config *const device,
uint8_t *const buffer,
const uint16_t buffer_size,
const usb_endpoint_type endpoint_type) {
usb_error result;
endpoint_param *const endpoint = &device->endpoints[endpoint_type];
result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}
usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) __sdcccall(1) {
usb_error result;
endpoint_param *const endpoint = &device->endpoints[0];
result = usb_data_in_transfer(buffer, buffer_size, device->address, endpoint);
if (result == USB_ERR_STALL) {
usbtrn_clear_endpoint_halt(endpoint->number, device->address, device->max_packet_size);
endpoint->toggle = 0;
return USB_ERR_STALL;
}
RETURN_CHECK(result);
}

68
Source/HBIOS/ch376-native/source-doc/base-drv/dev_transfers.h

@ -0,0 +1,68 @@
/**
* @file transfer.h
* @author Dean Netherton
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
* @version 1.0
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#ifndef __USBDEV_TRANSFERS
#define __USBDEV_TRANSFERS
#include "ch376.h"
#include "transfers.h"
#include <stdlib.h>
typedef struct {
uint8_t number : 3;
uint16_t max_packet_sizex : 10;
} endpoint;
// 3 bytes
#define COMMON_DEVICE_CONFIG \
usb_device_type type : 4; \
uint8_t address : 4; \
uint8_t max_packet_size; \
uint8_t interface_number;
typedef struct {
COMMON_DEVICE_CONFIG
endpoint_param endpoints[3]; // bulk in/out and interrupt
} device_config;
typedef struct {
COMMON_DEVICE_CONFIG // bytes: 0-2
endpoint_param endpoints[3]; // bytes: 3-5, 6-8, 9-11 bulk in/out and interrupt
uint32_t current_lba; // bytes 12-15
uint8_t drive_index; // byte 16
} device_config_storage;
typedef struct {
COMMON_DEVICE_CONFIG
} device_config_hub;
typedef struct {
COMMON_DEVICE_CONFIG
endpoint_param endpoints[1]; // Isochronous
} device_config_keyboard;
extern usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd, uint8_t *const buffer);
extern usb_error usbdev_blk_out_trnsfer(device_config *const device, const uint8_t *const buffer, const uint16_t buffer_size);
extern usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size);
extern usb_error usbdev_dat_in_trnsfer(device_config *const device,
uint8_t *const buffer,
const uint16_t buffer_size,
const usb_endpoint_type endpoint_type);
extern usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size)
__sdcccall(1);
#endif

221
Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.c

@ -0,0 +1,221 @@
#include "enumerate.h"
#include "enumerate_hub.h"
#include "enumerate_storage.h"
#include "protocol.h"
#include "work-area.h"
#include <string.h>
#include "print.h"
usb_error op_id_class_drv(_working *const working) __sdcccall(1);
usb_error op_parse_endpoint(_working *const working) __sdcccall(1);
void parse_endpoint_keyboard(device_config_keyboard *const keyboard_config, const endpoint_descriptor const *pEndpoint)
__sdcccall(1) {
endpoint_param *const ep = &keyboard_config->endpoints[0];
ep->number = pEndpoint->bEndpointAddress;
ep->toggle = 0;
ep->max_packet_sizex = calc_max_packet_sizex(pEndpoint->wMaxPacketSize);
}
usb_device_type identify_class_driver(_working *const working) {
const interface_descriptor *const p = (const interface_descriptor *)working->ptr;
if (p->bInterfaceClass == 2)
return USB_IS_CDC;
if (p->bInterfaceClass == 8 && (p->bInterfaceSubClass == 6 || p->bInterfaceSubClass == 5) && p->bInterfaceProtocol == 80)
return USB_IS_MASS_STORAGE;
if (p->bInterfaceClass == 8 && p->bInterfaceSubClass == 4 && p->bInterfaceProtocol == 0)
return USB_IS_FLOPPY;
if (p->bInterfaceClass == 9 && p->bInterfaceSubClass == 0 && p->bInterfaceProtocol == 0)
return USB_IS_HUB;
if (p->bInterfaceClass == 3)
return USB_IS_KEYBOARD;
return USB_IS_UNKNOWN;
}
usb_error op_interface_next(_working *const working) __z88dk_fastcall {
if (--working->interface_count == 0)
return USB_ERR_OK;
return op_id_class_drv(working);
}
usb_error op_endpoint_next(_working *const working) __sdcccall(1) {
if (--working->endpoint_count > 0) {
working->ptr += ((endpoint_descriptor *)working->ptr)->bLength;
return op_parse_endpoint(working);
}
return op_interface_next(working);
}
usb_error op_parse_endpoint(_working *const working) __sdcccall(1) {
const endpoint_descriptor *endpoint = (endpoint_descriptor *)working->ptr;
device_config *const device = working->p_current_device;
switch (working->usb_device) {
case USB_IS_FLOPPY:
case USB_IS_MASS_STORAGE: {
parse_endpoints(device, endpoint);
break;
}
case USB_IS_KEYBOARD: {
parse_endpoint_keyboard((device_config_keyboard *)device, endpoint);
break;
}
}
return op_endpoint_next(working);
}
usb_error
configure_device(const _working *const working, const interface_descriptor *const interface, device_config *const dev_cfg) {
dev_cfg->interface_number = interface->bInterfaceNumber;
dev_cfg->max_packet_size = working->desc.bMaxPacketSize0;
dev_cfg->address = working->current_device_address;
dev_cfg->type = working->usb_device;
return usbtrn_set_configuration(dev_cfg->address, dev_cfg->max_packet_size, working->config.desc.bConfigurationvalue);
}
usb_error op_capture_hub_driver_interface(_working *const working) __sdcccall(1) {
const interface_descriptor *const interface = (interface_descriptor *)working->ptr;
usb_error result;
device_config_hub hub_config;
working->hub_config = &hub_config;
hub_config.type = USB_IS_HUB;
CHECK(configure_device(working, interface, (device_config *const)&hub_config));
RETURN_CHECK(configure_usb_hub(working));
}
usb_error op_cap_drv_intf(_working *const working) __z88dk_fastcall {
usb_error result;
_usb_state *const work_area = get_usb_work_area();
const interface_descriptor *const interface = (interface_descriptor *)working->ptr;
working->ptr += interface->bLength;
working->endpoint_count = interface->bNumEndpoints;
working->p_current_device = NULL;
switch (working->usb_device) {
case USB_IS_HUB: {
CHECK(op_capture_hub_driver_interface(working))
break;
}
case USB_IS_UNKNOWN: {
device_config unkown_dev_cfg;
memset(&unkown_dev_cfg, 0, sizeof(device_config));
working->p_current_device = &unkown_dev_cfg;
CHECK(configure_device(working, interface, &unkown_dev_cfg));
break;
}
default: {
device_config *dev_cfg = find_first_free();
if (dev_cfg == NULL)
return USB_ERR_OUT_OF_MEMORY;
working->p_current_device = dev_cfg;
CHECK(configure_device(working, interface, dev_cfg));
break;
}
}
CHECK(op_parse_endpoint(working));
return result;
}
usb_error op_id_class_drv(_working *const working) __sdcccall(1) {
usb_error result;
const interface_descriptor *const ptr = (const interface_descriptor *)working->ptr;
working->usb_device = ptr->bLength > 5 ? identify_class_driver(working) : 0;
CHECK(op_cap_drv_intf(working));
return result;
}
usb_error op_get_cfg_desc(_working *const working) __sdcccall(1) {
usb_error result;
memset(working->config.buffer, 0, MAX_CONFIG_SIZE);
const uint8_t max_packet_size = working->desc.bMaxPacketSize0;
CHECK(usbtrn_gfull_cfg_desc(working->config_index, working->current_device_address, max_packet_size, MAX_CONFIG_SIZE,
working->config.buffer));
working->ptr = (working->config.buffer + sizeof(config_descriptor));
working->interface_count = working->config.desc.bNumInterfaces;
CHECK(op_id_class_drv(working));
return result;
}
usb_error read_all_configs(enumeration_state *const state) {
uint8_t result;
_usb_state *const work_area = get_usb_work_area();
_working working;
memset(&working, 0, sizeof(_working));
working.state = state;
CHECK(usbtrn_get_descriptor(&working.desc));
state->next_device_address++;
working.current_device_address = state->next_device_address;
CHECK(usbtrn_set_address(working.current_device_address));
for (uint8_t config_index = 0; config_index < working.desc.bNumConfigurations; config_index++) {
working.config_index = config_index;
CHECK(op_get_cfg_desc(&working));
}
return USB_ERR_OK;
}
usb_error enumerate_all_devices(void) {
_usb_state *const work_area = get_usb_work_area();
enumeration_state state;
memset(&state, 0, sizeof(enumeration_state));
state.next_device_address = 0;
usb_error result = read_all_configs(&state);
work_area->count_of_detected_usb_devices = state.next_device_address;
CHECK(result);
return result;
}
/*
enumerate_all_devices
-> read_all_configs
-> parse_config
-> op_get_cfg_desc
-> op_id_class_drv
-> op_cap_drv_intf (increment index)
-> op_parse_endpoint
-> parse_endpoints
-> parse_endpoint_hub
-> op_endpoint_next
-> op_parse_endpoint -^ (install driver endpoint)
-> op_interface_next
-> return
-> op_id_class_drv -^
*/

38
Source/HBIOS/ch376-native/source-doc/base-drv/enumerate.h

@ -0,0 +1,38 @@
#ifndef __USB_ENUMERATE
#define __USB_ENUMERATE
#include "ch376.h"
#include "protocol.h"
#include "usb_state.h"
#define MAX_CONFIG_SIZE 140
typedef struct {
uint8_t next_device_address;
} enumeration_state;
typedef struct __working {
enumeration_state *state;
usb_device_type usb_device;
device_descriptor desc;
uint8_t config_index;
uint8_t interface_count;
uint8_t endpoint_count;
uint8_t current_device_address;
device_config_hub *hub_config;
uint8_t *ptr;
device_config *p_current_device;
union {
uint8_t buffer[MAX_CONFIG_SIZE];
config_descriptor desc;
} config;
} _working;
extern usb_error read_all_configs(enumeration_state *const state);
extern usb_error enumerate_all_devices(void);
#endif

80
Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.c

@ -0,0 +1,80 @@
#include "enumerate_hub.h"
#include "class_hub.h"
#include "delay.h"
#include "protocol.h"
#include "work-area.h"
#include <string.h>
const setup_packet cmd_set_feature = {RT_HOST_TO_DEVICE | RT_CLASS | RT_OTHER, SET_FEATURE, {FEAT_PORT_POWER, 0}, {1, 0}, 0};
const setup_packet cmd_clear_feature = {RT_HOST_TO_DEVICE | RT_CLASS | RT_OTHER, CLEAR_FEATURE, {FEAT_PORT_POWER, 0}, {1, 0}, 0};
const setup_packet cmd_get_status_port = {
RT_DEVICE_TO_HOST | RT_CLASS | RT_OTHER, GET_STATUS, {0, 0}, {1, 0}, sizeof(hub_port_status)};
usb_error hub_set_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) {
setup_packet set_feature;
set_feature = cmd_set_feature;
set_feature.bValue[0] = feature;
set_feature.bIndex[0] = index;
return usb_control_transfer(&set_feature, 0, hub_config->address, hub_config->max_packet_size);
}
usb_error hub_clear_feature(const device_config_hub *const hub_config, const uint8_t feature, const uint8_t index) {
setup_packet clear_feature;
clear_feature = cmd_clear_feature;
clear_feature.bValue[0] = feature;
clear_feature.bIndex[0] = index;
return usb_control_transfer(&clear_feature, 0, hub_config->address, hub_config->max_packet_size);
}
usb_error hub_get_status_port(const device_config_hub *const hub_config, const uint8_t index, hub_port_status *const port_status) {
setup_packet get_status_port;
get_status_port = cmd_get_status_port;
get_status_port.bIndex[0] = index;
return usb_control_transfer(&get_status_port, port_status, hub_config->address, hub_config->max_packet_size);
}
usb_error configure_usb_hub(_working *const working) __z88dk_fastcall {
_usb_state *const work_area = get_usb_work_area();
usb_error result;
hub_descriptor hub_description;
hub_port_status port_status;
const device_config_hub *const hub_config = working->hub_config;
CHECK(hub_get_descriptor(hub_config, &hub_description));
uint8_t i = hub_description.bNbrPorts;
do {
CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i));
CHECK(hub_set_feature(hub_config, FEAT_PORT_POWER, i));
hub_clear_feature(hub_config, FEAT_PORT_RESET, i);
CHECK(hub_set_feature(hub_config, FEAT_PORT_RESET, i));
CHECK(hub_get_status_port(hub_config, i, &port_status));
if (port_status.wPortStatus.port_connection) {
CHECK(hub_clear_feature(hub_config, HUB_FEATURE_PORT_CONNECTION_CHANGE, i));
CHECK(hub_clear_feature(hub_config, FEAT_PORT_ENABLE_CHANGE, i));
CHECK(hub_clear_feature(hub_config, FEAT_PORT_RESET_CHANGE, i));
delay_short();
CHECK(hub_get_status_port(hub_config, i, &port_status));
delay_short();
CHECK(read_all_configs(working->state));
} else {
CHECK(hub_clear_feature(hub_config, FEAT_PORT_POWER, i));
}
} while (--i != 0);
return USB_ERR_OK;
}

10
Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_hub.h

@ -0,0 +1,10 @@
#ifndef __USB_ENUMERATE_HUB
#define __USB_ENUMERATE_HUB
#include "enumerate.h"
#include "protocol.h"
#include "usb_state.h"
extern usb_error configure_usb_hub(_working *const working) __z88dk_fastcall;
#endif

27
Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.c

@ -0,0 +1,27 @@
#include "enumerate_storage.h"
#include "protocol.h"
#include <string.h>
void parse_endpoints(device_config *const storage_dev, const endpoint_descriptor const *pEndpoint) {
if (!(pEndpoint->bmAttributes & 0x02))
return;
const uint8_t x = calc_max_packet_sizex(pEndpoint->wMaxPacketSize);
endpoint_param *const eps = storage_dev->endpoints;
endpoint_param *ep;
if (pEndpoint->bmAttributes & 0x01) { // 3 -> Interrupt
if (!(pEndpoint->bEndpointAddress & 0x80))
return;
ep = &eps[ENDPOINT_INTERRUPT_IN];
} else {
ep = (pEndpoint->bEndpointAddress & 0x80) ? &eps[ENDPOINT_BULK_IN] : &eps[ENDPOINT_BULK_OUT];
}
ep->number = pEndpoint->bEndpointAddress & 0x07;
ep->toggle = 0;
ep->max_packet_sizex = x;
}

8
Source/HBIOS/ch376-native/source-doc/base-drv/enumerate_storage.h

@ -0,0 +1,8 @@
#ifndef __USB_ENUMERATE_STORAGE
#define __USB_ENUMERATE_STORAGE
#include "protocol.h"
extern void parse_endpoints(device_config *const storage_dev, const endpoint_descriptor const *pEndpoint);
#endif

6
Source/HBIOS/ch376-native/source-doc/base-drv/hbios.h

@ -0,0 +1,6 @@
#ifndef _HBIOS_H_
#define _HBIOS_H_
extern void dio_add_entry(const uint16_t fnc_table[], const device_config_storage *const storage_device) __sdcccall(1);
#endif

9
Source/HBIOS/ch376-native/source-doc/base-drv/print.c

@ -0,0 +1,9 @@
#include "print.h"
void print_device_mounted(const char *const description, const uint8_t count) {
print_string("\r\n $");
print_uint16(count);
print_string(description);
if (count > 1)
print_string("S$");
}

11
Source/HBIOS/ch376-native/source-doc/base-drv/print.h

@ -0,0 +1,11 @@
#ifndef __XPRINT
#define __XPRINT
#include <stdlib.h>
extern void print_hex(const char c) __z88dk_fastcall;
extern void print_string(const char *p) __z88dk_fastcall;
extern void print_uint16(const uint16_t n) __z88dk_fastcall;
extern void print_device_mounted(const char *const description, const uint8_t count);
#endif

152
Source/HBIOS/ch376-native/source-doc/base-drv/protocol.c

@ -0,0 +1,152 @@
/**
* @file protocol.c
* @author Dean Netherton
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
* @version 1.0
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#include "protocol.h"
#include "ch376.h"
#include "delay.h"
#include <stdlib.h>
#include "print.h"
const setup_packet cmd_get_device_descriptor = {0x80, 6, {0, 1}, {0, 0}, 8};
/**
* @brief Issue GET_DESCRIPTOR request to retrieve the device descriptor for usb device at address 0
*
* @param buffer the buffer to store the device descriptor in
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbtrn_get_descriptor(device_descriptor *const buffer) {
usb_error result;
setup_packet cmd;
cmd = cmd_get_device_descriptor;
cmd.wLength = 8;
result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8);
CHECK(result);
cmd = cmd_get_device_descriptor;
cmd.wLength = 18;
result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0);
RETURN_CHECK(result);
}
/**
* @brief Issue GET_DESCRIPTOR request to retrieve the device descriptor for usb device at the specified address
*
* @param buffer the buffer to store the device descriptor in
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address) {
usb_error result;
setup_packet cmd;
cmd = cmd_get_device_descriptor;
cmd.wLength = 8;
result = usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, 8);
CHECK(result);
cmd = cmd_get_device_descriptor;
cmd.wLength = 18;
RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, buffer->bMaxPacketSize0));
}
const setup_packet cmd_set_device_address = {0x00, 5, {0, 0}, {0, 0}, 0};
/**
* @brief configure device at address 0 to be assigned a new device address
*
* @param device_address the new device address
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall {
setup_packet cmd;
cmd = cmd_set_device_address;
cmd.bValue[0] = device_address;
return usb_control_transfer(&cmd, 0, 0, 0);
}
const setup_packet cmd_set_configuration = {0x00, 9, {0, 0}, {0, 0}, 0};
/**
* @brief configure device at address 0 to be assigned a new configuration
*
* @param config the device to be configured
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbtrn_set_configuration(const uint8_t device_address, const uint8_t max_packet_size, const uint8_t configuration) {
setup_packet cmd;
cmd = cmd_set_configuration;
cmd.bValue[0] = configuration;
return usb_control_transfer(&cmd, 0, device_address, max_packet_size);
}
const setup_packet cmd_get_config_descriptor = {0x80, 6, {0, 2}, {0, 0}, 0};
/**
* @brief request the config descriptor for the specific config index of the specified device
*
* @param buffer the buffer to store the config descriptor in
* @param config_index the index of the config descriptor to retrieve
* @param buffer_size the size of the buffer
* @param device_address the usb address of the device
* @param max_packet_size the max packet size for control transfers (endpoint 0)
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer,
const uint8_t config_index,
const uint8_t buffer_size,
const uint8_t device_address,
const uint8_t max_packet_size) {
setup_packet cmd;
cmd = cmd_get_config_descriptor;
cmd.bValue[0] = config_index;
cmd.wLength = (uint16_t)buffer_size;
RETURN_CHECK(usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, max_packet_size));
}
usb_error usbtrn_gfull_cfg_desc(const uint8_t config_index,
const uint8_t device_address,
const uint8_t max_packet_size,
const uint8_t max_buffer_size,
uint8_t *const buffer) {
usb_error result;
CHECK(usbtrn_get_config_descriptor((config_descriptor *)buffer, config_index, sizeof(config_descriptor), device_address,
max_packet_size));
uint8_t max_length = ((config_descriptor *)buffer)->wTotalLength;
if (max_length > max_buffer_size)
max_length = max_buffer_size;
CHECK(usbtrn_get_config_descriptor((config_descriptor *)buffer, config_index, max_length, device_address, max_packet_size));
return USB_ERR_OK;
}
const setup_packet usb_cmd_clear_endpoint_halt = {2, 1, {0, 0}, {255, 0}, 0}; // ;byte 4 is the endpoint to be cleared
usb_error usbtrn_clear_endpoint_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size) {
setup_packet cmd;
cmd = usb_cmd_clear_endpoint_halt;
cmd.bIndex[0] = endpoint_number;
usb_error result = usb_control_transfer(&cmd, (uint8_t *)0, device_address, max_packet_size);
RETURN_CHECK(result);
}

82
Source/HBIOS/ch376-native/source-doc/base-drv/protocol.h

@ -0,0 +1,82 @@
#ifndef __HW
#define __HW
#include "ch376.h"
#include "dev_transfers.h"
#include "transfers.h"
#include <stdlib.h>
typedef struct _device_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} device_descriptor;
typedef struct _config_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationvalue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} config_descriptor;
typedef struct _interface_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} interface_descriptor, *p_interface_descriptor;
typedef struct _endpoint_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} endpoint_descriptor;
extern usb_error usbtrn_get_descriptor(device_descriptor *const buffer);
extern usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address);
extern usb_error usbtrn_get_config_descriptor(config_descriptor *const buffer,
const uint8_t config_index,
const uint8_t buffer_size,
const uint8_t device_address,
const uint8_t max_packet_size);
extern usb_error usbtrn_gfull_cfg_desc(const uint8_t config_index,
const uint8_t device_address,
const uint8_t max_packet_size,
const uint8_t max_buffer_size,
uint8_t *const buffer);
extern usb_error usbtrn_set_configuration(const uint8_t device_address, const uint8_t max_packet_size, const uint8_t configuration);
extern usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall;
extern usb_error
usbtrn_clear_endpoint_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size);
// extern usb_error usb_clear_endpoint_halt(device_config *const storage_device, const usb_endpoint_type endpoint_type);
#endif

172
Source/HBIOS/ch376-native/source-doc/base-drv/transfers.c

@ -0,0 +1,172 @@
/**
* @file transfers.c
* @author Dean Netherton
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
* @version 1.0
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#include "transfers.h"
#include "ch376.h"
#include "delay.h"
#include "z80.h"
#include <stdlib.h>
#define LOWER_SAFE_RAM_ADDRESS 0x8000
usb_error usb_ctrl_trnsfer_ext(const setup_packet *const cmd_packet,
void *const buffer,
const uint8_t device_address,
const uint8_t max_packet_size) {
if ((uint16_t)cmd_packet < LOWER_SAFE_RAM_ADDRESS)
return USB_BAD_ADDRESS;
if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS)
return USB_BAD_ADDRESS;
return usb_control_transfer(cmd_packet, buffer, device_address, max_packet_size);
}
/**
* @brief Perform a USB control transfer (in or out)
* See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
*
* @param cmd_packet Pointer to the setup packet - top bit of bmRequestType indicate data direction
* @param buffer Pointer of data to send or receive into
* @param device_address usb device address
* @param max_packet_size Maximum packet size for endpoint
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error usb_control_transfer(const setup_packet *const cmd_packet,
void *const buffer,
const uint8_t device_address,
const uint8_t max_packet_size) {
usb_error result;
endpoint_param endpoint = {1, 0, max_packet_size};
const uint8_t transferIn = (cmd_packet->bmRequestType & 0x80);
if (transferIn && buffer == 0)
return USB_ERR_OTHER;
ch_set_usb_address(device_address);
ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet));
ch_issue_token_setup();
CHECK(ch_short_wait_int_and_get_status())
const uint16_t length = cmd_packet->wLength;
result = length != 0
? (transferIn ? ch_data_in_transfer(buffer, length, &endpoint) : ch_data_out_transfer(buffer, length, &endpoint))
: USB_ERR_OK;
CHECK(result)
if (transferIn) {
ch_command(CH_CMD_WR_HOST_DATA);
CH376_DATA_PORT = 0;
delay();
ch_issue_token_out_ep0();
result = ch_long_wait_int_and_get_status(); /* sometimes we get STALL here - seems to be ok to ignore */
if (result == USB_ERR_OK || result == USB_ERR_STALL)
return USB_ERR_OK;
RETURN_CHECK(result);
}
ch_issue_token_in_ep0();
result = ch_long_wait_int_and_get_status();
RETURN_CHECK(result);
}
usb_error
usb_dat_in_trnsfer_ext(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS)
return USB_BAD_ADDRESS;
if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS)
return USB_BAD_ADDRESS;
return usb_data_in_transfer(buffer, buffer_size, device_address, endpoint);
}
usb_error
usb_dat_in_trns_n_ext(uint8_t *buffer, uint16_t *buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
if (buffer != 0 && ((uint16_t)buffer & 0xC000) == 0)
return USB_BAD_ADDRESS;
if (((uint16_t)endpoint & 0xC000) == 0)
return USB_BAD_ADDRESS;
if (((uint16_t)buffer_size & 0xC000) == 0)
return USB_BAD_ADDRESS;
return usb_data_in_transfer_n(buffer, buffer_size, device_address, endpoint);
}
/**
* @brief Perform a USB data in on the specififed endpoint
*
* @param buffer the buffer to receive the data
* @param buffer_size the maximum size of data to be received
* @param device_address the usb address of the device
* @param endpoint the usb endpoint to receive from (toggle of endpoint is updated)
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error
usb_data_in_transfer(uint8_t *buffer, const uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
ch_set_usb_address(device_address);
return ch_data_in_transfer(buffer, buffer_size, endpoint);
}
/**
* @brief Perform a USB data in on the specififed endpoint
*
* @param buffer the buffer to receive the data - must be 62 bytes
* @param buffer_size on exit the actual size of data received
* @param device_address the usb address of the device
* @param endpoint the usb endpoint to receive from (toggle of endpoint is updated)
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error
usb_data_in_transfer_n(uint8_t *buffer, uint8_t *const buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
ch_set_usb_address(device_address);
return ch_data_in_transfer_n(buffer, buffer_size, endpoint);
}
usb_error
usb_dat_out_trns_ext(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
if (buffer != 0 && (uint16_t)buffer < LOWER_SAFE_RAM_ADDRESS)
return USB_BAD_ADDRESS;
if ((uint16_t)endpoint < LOWER_SAFE_RAM_ADDRESS)
return USB_BAD_ADDRESS;
return usb_data_out_transfer(buffer, buffer_size, device_address, endpoint);
}
/**
* @brief Perform a USB data out on the specififed endpoint
*
* @param buffer the buffer to send the data from
* @param buffer_size the maximum size of data to be sent
* @param device_address the usb address of the device
* @param endpoint the usb endpoint to send to (toggle of endpoint is updated)
* @return usb_error USB_ERR_OK if all good, otherwise specific error code
*/
usb_error
usb_data_out_transfer(const uint8_t *buffer, uint16_t buffer_size, const uint8_t device_address, endpoint_param *const endpoint) {
ch_set_usb_address(device_address);
return ch_data_out_transfer(buffer, buffer_size, endpoint);
}

103
Source/HBIOS/ch376-native/source-doc/base-drv/transfers.h

@ -0,0 +1,103 @@
/**
* @file transfer.h
* @author Dean Netherton
* @brief A simplest implementation of common usb transfer functions, based on the CH376S chip
* @details For a basic walkthrough of the usb protocol see https://www.beyondlogic.org/usbnutshell/usb1.shtml
* @version 1.0
* @date 2023-09-22
*
* @copyright Copyright (c) 2023
*
*/
#ifndef __USB_TRANSFERS
#define __USB_TRANSFERS
#include "ch376.h"
#include <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

9
Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.c

@ -0,0 +1,9 @@
#include "usb-base-drv.h"
/* The total number of mounted storage devices (scsi and ufi) */
uint8_t storage_count = 0;
uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1) {
storage_device->current_lba = lba;
return 0;
}

11
Source/HBIOS/ch376-native/source-doc/base-drv/usb-base-drv.h

@ -0,0 +1,11 @@
#ifndef __USB_BASE_DRV
#define __USB_BASE_DRV
#include <dev_transfers.h>
#include <stdint.h>
extern uint8_t storage_count;
extern uint8_t chnative_seek(const uint32_t lba, device_config_storage *const storage_device) __sdcccall(1);
#endif

56
Source/HBIOS/ch376-native/source-doc/base-drv/usb-init.c

@ -0,0 +1,56 @@
#include "ch376.h"
#include "enumerate.h"
#include "print.h"
#include "work-area.h"
#include "z80.h"
#include <string.h>
static usb_error usb_host_bus_reset(void) {
ch_cmd_set_usb_mode(CH_MODE_HOST);
delay_20ms();
ch_cmd_set_usb_mode(CH_MODE_HOST_RESET);
delay_20ms();
ch_cmd_set_usb_mode(CH_MODE_HOST);
delay_20ms();
ch_configure_nak_retry_3s();
return USB_ERR_OK;
}
#define ERASE_LINE "\x1B\x6C\r$"
void chnative_init(void) {
memset(get_usb_work_area(), 0, sizeof(_usb_state));
ch_cmd_reset_all();
delay_medium();
if (!ch_probe()) {
print_string("\r\nCH376: NOT PRESENT$");
return;
}
print_string("\r\nCH376: PRESENT (VER $");
print_hex(ch_cmd_get_ic_version());
print_string("); $");
usb_host_bus_reset();
for (uint8_t i = 0; i < 4; i++) {
const uint8_t r = ch_very_short_wait_int_and_get_status();
if (r == USB_INT_CONNECT) {
print_string("USB: CONNECTED$");
enumerate_all_devices();
return;
}
}
print_string("USB: DISCONNECTED$");
}

90
Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.c

@ -0,0 +1,90 @@
#include "usb_state.h"
#include "work-area.h"
const uint8_t device_config_sizes[_USB_LAST_DEVICE_TYPE] = {
0, /* USB_NOT_SUPPORTED = 0 */
sizeof(device_config_storage), /* USB_IS_FLOPPY = 1 */
sizeof(device_config_storage), /* USB_IS_MASS_STORAGE = 2 */
sizeof(device_config), /* USB_IS_CDC = 3 */
sizeof(device_config_keyboard), /* USB_IS_KEYBOARD = 4 */
};
// always usb work area
device_config *find_device_config(const usb_device_type requested_type) {
_usb_state *const p = get_usb_work_area();
const device_config *p_config = first_device_config(p);
while (p_config) {
const uint8_t type = p_config->type;
if (type == requested_type)
return (device_config *)p_config;
p_config = next_device_config(p, p_config);
};
return NULL;
}
// always search in boot
device_config *find_first_free(void) {
_usb_state *const boot_state = get_usb_work_area();
uint8_t c = 0;
device_config *p = first_device_config(boot_state);
while (p) {
if (p->type == 0)
return p;
p = next_device_config(boot_state, p);
}
return NULL;
}
device_config *first_device_config(const _usb_state *const p) __sdcccall(1) { return (device_config *)&p->device_configs[0]; }
device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1) {
if (p->type == 0)
return NULL;
const uint8_t size = device_config_sizes[p->type];
// TODO: bug when size is zero we dont increment the pointer
// but if we abort on size 0 - we fail to pick up other devices???
// we should not get size of 0 unless the size entry is missing
// if (size == 0)
// return NULL;
const uint8_t *_p = (uint8_t *)p;
device_config *const result = (device_config *)(_p + size);
if (result >= (device_config *)&usb_state->device_configs_end)
return NULL;
return result;
}
// always usb work area
device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1) {
const _usb_state *const usb_state = get_usb_work_area();
uint8_t counter = 1;
for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
if (p->type == USB_IS_FLOPPY) {
if (counter == device_index)
return p;
counter++;
}
}
for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
if (p->type == USB_IS_MASS_STORAGE) {
if (counter == device_index)
return p;
counter++;
}
}
return NULL; // is not a usb device
}

27
Source/HBIOS/ch376-native/source-doc/base-drv/usb_state.h

@ -0,0 +1,27 @@
#ifndef __USB_STATE
#define __USB_STATE
#include "ch376.h"
#include "protocol.h"
#include <stdlib.h>
#define MAX_NUMBER_OF_DEVICES 6
#define DEVICE_CONFIG_STRUCT_SIZE sizeof(device_config_storage) /* Assumes is largest struct */
typedef struct __usb_state {
uint8_t active : 1; /* if true, a usb operation/interrupt handler is active, prevent re-entrant */
uint8_t reserved : 7;
uint8_t count_of_detected_usb_devices;
uint8_t device_configs[DEVICE_CONFIG_STRUCT_SIZE * MAX_NUMBER_OF_DEVICES];
uint8_t device_configs_end; // always zero to mark end
} _usb_state;
extern device_config *find_first_free(void);
extern device_config *first_device_config(const _usb_state *const p) __sdcccall(1);
extern device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1);
extern device_config *find_device_config(const usb_device_type requested_type);
extern device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1);
#endif

3
Source/HBIOS/ch376-native/source-doc/base-drv/work-area.c

@ -0,0 +1,3 @@
#include "usb_state.h"
_usb_state x = {0, 0, 0};

54
Source/HBIOS/ch376-native/source-doc/base-drv/work-area.h

@ -0,0 +1,54 @@
#ifndef __WORK_AREA
#define __WORK_AREA
#include "ch376.h"
#include "protocol.h"
#include "stdlib.h"
#include "usb_state.h"
#define PRES_CF 1 /* BIT MASK FOR COMPACTFLASH PRESENT */
#define PRES_MS 2 /* BIT MASK FOR MSX MUSIC NOR FLASH PRESENT */
#define PRES_USB1 4 /* BIT MASK FOR USB1 STORAGE PRESENT AT BOOT UP */
#define PRES_USB2 8 /* BIT MASK FOR USB2 STORAGE PRESENT AT BOOT UP */
#define PRES_USB3 16 /* BIT MASK FOR USB3 STORAGE PRESENT AT BOOT UP */
#define PRES_USB4 32 /* BIT MASK FOR USB4 STORAGE PRESENT AT BOOT UP */
#define PRES_CH376 128 /* BIT MASK FOR CH376 PRESENT AT BOOT UP */
#define BIT_PRES_CF 0 /* BIT POSTION FOR COMPACTFLASH PRESENT */
#define BIT_PRES_MS 1 /* BIT POSTION FOR MSX MUSIC NOR FLASH PRESENT */
#define BIT_PRES_USB1 2 /* BIT POSTION FOR USB1 STORAGE PRESENT */
#define BIT_PRES_USB2 3 /* BIT POSTION FOR USB2 STORAGE PRESENT */
#define BIT_PRES_USB3 4 /* BIT POSTION FOR USB3 STORAGE PRESENT */
#define BIT_PRES_USB4 5 /* BIT POSTION FOR USB4 STORAGE PRESENT */
#define BIT_PRES_CH376 7 /* BIT POSTION FOR CH376 PRESENT */
typedef enum {
DEV_MAP_NONE = 0,
DEV_MAP_ROM = 1,
DEV_MAP_CF = 2,
DEV_MAP_MS = 3,
DEV_MAP_USB1 = 4,
DEV_MAP_USB2 = 5,
DEV_MAP_USB3 = 6,
DEV_MAP_USB4 = 7
} device_map;
typedef struct _work_area {
uint8_t read_count; /* COUNT OF SECTORS TO BE READ */
uint16_t index; /* sector number to be read */
uint8_t *dest; /* destination write address */
uint8_t read_count_requested; /* number of sectors requested */
uint8_t present; /* BIT FIELD FOR DETECTED DEVICES
(BIT 0 -> COMPACTFLASH/IDE, BIT 1-> MSX-MUSIC NOR FLASH, BITS 2-5 FOR USB)*/
_usb_state ch376;
} work_area;
// extern work_area *get_work_area(void);
extern uint8_t get_number_of_usb_drives(void);
extern _usb_state x;
#define get_usb_work_area() (&x)
#endif

17
Source/HBIOS/ch376-native/source-doc/base-drv/z80.h

@ -0,0 +1,17 @@
#ifndef __Z80_HELPERS
#define __Z80_HELPERS
#include <stdint.h>
#define EI __asm__("EI");
#define DI __asm__("DI");
#define HALT __asm__("HALT");
typedef void (*jump_fn_t)(void) __z88dk_fastcall;
typedef struct {
uint8_t jump_op_code; // JMP or CALL
jump_fn_t address;
} z80_jump_t;
#endif

50
Source/HBIOS/ch376-native/source-doc/convert-for-uz80as.sh

@ -0,0 +1,50 @@
#!/bin/bash
# Check if exactly two arguments are provided
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <source_file> <destination_file>"
exit 1
fi
source_file="$1"
destination_file="$2"
rm -f "$destination_file"
# create a unique prefix for all generated labels
prefix=$(basename "$source_file" | cut -d. -f1 | tr '-' '_')
sed -E \
-e "1i\;\r\n; Generated from source-doc/${source_file} -- not to be modify directly\r\n;\r\n; " \
-e '/SECTION IGNORE/d' \
-e '/\sEXTERN\s/d' \
-e '/\sGLOBAL\s/d' \
-e '/SECTION .*/d' \
-e 's/^IF 0/#IF 0/g' \
-e 's/^ENDIF/#ENDIF/g' \
-e 's/\s+cp\s+a,\((ix\+[0-9-]+)\)/\tcp\t\(\1\)/g' \
-e 's/\s+sub\s+a,\((iy\+[0-9]+)\)/\tsub\t\(\1\)/g' \
-e 's/\s+sub\s+a,\((ix\+[0-9]+)\)/\tsub\t\(\1\)/g' \
-e 's/\s+sub\s+a,\((ix-[0-9]+)\)/\tsub\t\(\1\)/g' \
-e 's/\s+or\s+a,\((ix\+[0-9-]+)\)/\tor\t\(\1\)/g' \
-e 's/\s+or\s+a,\((ix\-[0-9-]+)\)/\tor\t\(\1\)/g' \
-e 's/\s+or\s+a,\((iy\+[0-9-]+)\)/\tor\t\(\1\)/g' \
-e 's/\s+cp\s+a,(0x[0-9A-Fa-f]{2})/\tcp\t\1/g' \
-e 's/\s+or\s+a,(0x[0-9A-Fa-f]{2})/\tor\t\1/g' \
-e 's/\s+xor\s+a,(0x[0-9A-Fa-f]{2})/\txor\t\1/g' \
-e 's/\s+and\s+a,(0x[0-9A-Fa-f]{2})/\tand\t\1/g' \
-e 's/\s+sub\s+a,(0x[0-9A-Fa-f]{2})/\tsub\t\1/g' \
-e 's/\s+cp\s+a,\s*a/\tcp\ta/g' \
-e 's/\s+or\s+a,\s*a/\tor\ta/g' \
-e 's/\s+xor\s+a,\s*a/\txor\ta/g' \
-e 's/\s+or\s+a,\s*(b|c|d|e|h|l|iyl|iyh|ixl|ixh)/\tor\t\1/g' \
-e 's/\s+sub\s+a,\s+(b|c|d|e|h|l|iyl|iyh|ixl|ixh)/\tsub\t\1/g' \
-e 's/\b([a-zA-Z0-9_]{31})[a-zA-Z0-9_]+\b/\1/g' \
-e 's/;\t+/; /g' \
-e 's/defc\s+([a-zA-Z0-9_]+)\s*=\s*(0x[0-9A-Fa-f]+)/\1\t.EQU\t\2/' \
-e "s/___str_([0-9]+)/${prefix}_str_\1/g" \
"$source_file" > "$destination_file"
# -e '/IF 0/d' \
# -e '/ENDIF/d' \

106
Source/HBIOS/ch376-native/source-doc/depends.d

@ -0,0 +1,106 @@
./base-drv/dev_transfers.c.s: source-doc/base-drv/dev_transfers.c \
source-doc/base-drv/dev_transfers.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/transfers.h source-doc/base-drv/protocol.h
./base-drv/enumerate.c.s: source-doc/base-drv/enumerate.c \
source-doc/base-drv/enumerate.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/base-drv/usb_state.h \
source-doc/base-drv/enumerate_hub.h \
source-doc/base-drv/enumerate_storage.h source-doc/base-drv/work-area.h \
source-doc/base-drv/print.h
./base-drv/usb_state.c.s: source-doc/base-drv/usb_state.c \
source-doc/base-drv/usb_state.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/base-drv/work-area.h
./base-drv/class_hub.c.s: source-doc/base-drv/class_hub.c \
source-doc/base-drv/class_hub.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/base-drv/usb_state.h
./base-drv/enumerate_storage.c.s: source-doc/base-drv/enumerate_storage.c \
source-doc/base-drv/enumerate_storage.h source-doc/base-drv/protocol.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h
./base-drv/enumerate_hub.c.s: source-doc/base-drv/enumerate_hub.c \
source-doc/base-drv/enumerate_hub.h source-doc/base-drv/enumerate.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/protocol.h \
source-doc/base-drv/dev_transfers.h source-doc/base-drv/transfers.h \
source-doc/base-drv/usb_state.h source-doc/base-drv/class_hub.h \
source-doc/base-drv/work-area.h
./base-drv/usb-base-drv.c.s: source-doc/base-drv/usb-base-drv.c \
source-doc/base-drv/usb-base-drv.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/transfers.h
./base-drv/transfers.c.s: source-doc/base-drv/transfers.c \
source-doc/base-drv/transfers.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/z80.h
./base-drv/print.c.s: source-doc/base-drv/print.c source-doc/base-drv/print.h
./base-drv/ch376.c.s: source-doc/base-drv/ch376.c source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/print.h
./base-drv/protocol.c.s: source-doc/base-drv/protocol.c source-doc/base-drv/protocol.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/base-drv/print.h
./base-drv/work-area.c.s: source-doc/base-drv/work-area.c \
source-doc/base-drv/usb_state.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h
./base-drv/usb-init.c.s: source-doc/base-drv/usb-init.c source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/enumerate.h source-doc/base-drv/protocol.h \
source-doc/base-drv/dev_transfers.h source-doc/base-drv/transfers.h \
source-doc/base-drv/usb_state.h source-doc/base-drv/print.h \
source-doc/base-drv/work-area.h source-doc/base-drv/z80.h
./ufi-drv/ufi-init.c.s: source-doc/ufi-drv/ufi-init.c source-doc/ufi-drv/class_ufi.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/protocol.h \
source-doc/base-drv/ch376.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/ufi-drv/usb_cbi.h \
source-doc/base-drv/dev_transfers.h source-doc/base-drv/usb_state.h \
source-doc/base-drv/protocol.h source-doc/base-drv/hbios.h \
source-doc/base-drv/print.h source-doc/base-drv/usb-base-drv.h \
source-doc/base-drv/work-area.h source-doc/base-drv/usb_state.h
./ufi-drv/usb_cbi.c.s: source-doc/ufi-drv/usb_cbi.c source-doc/ufi-drv/usb_cbi.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/ch376.h source-doc/base-drv/transfers.h \
source-doc/base-drv/protocol.h source-doc/base-drv/dev_transfers.h
./ufi-drv/class_ufi.c.s: source-doc/ufi-drv/class_ufi.c \
source-doc/ufi-drv/class_ufi.h source-doc/base-drv/ch376.h \
source-doc/base-drv/ch376inc.h source-doc/base-drv/delay.h \
source-doc/base-drv/protocol.h source-doc/base-drv/ch376.h \
source-doc/base-drv/dev_transfers.h source-doc/base-drv/transfers.h \
source-doc/ufi-drv/usb_cbi.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/usb_state.h source-doc/base-drv/protocol.h \
source-doc/base-drv/delay.h source-doc/base-drv/z80.h
./scsi-drv/scsi-init.c.s: source-doc/scsi-drv/scsi-init.c \
source-doc/scsi-drv/class_scsi.h source-doc/base-drv/protocol.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/base-drv/ch376.h \
source-doc/base-drv/enumerate.h source-doc/base-drv/protocol.h \
source-doc/base-drv/usb_state.h source-doc/base-drv/hbios.h \
source-doc/base-drv/print.h source-doc/base-drv/usb-base-drv.h \
source-doc/base-drv/dev_transfers.h source-doc/base-drv/work-area.h \
source-doc/base-drv/z80.h
./scsi-drv/class_scsi.c.s: source-doc/scsi-drv/class_scsi.c \
source-doc/scsi-drv/class_scsi.h source-doc/base-drv/protocol.h \
source-doc/base-drv/ch376.h source-doc/base-drv/ch376inc.h \
source-doc/base-drv/delay.h source-doc/base-drv/dev_transfers.h \
source-doc/base-drv/transfers.h source-doc/base-drv/usb_state.h \
source-doc/base-drv/protocol.h source-doc/base-drv/z80.h
##
./base-drv.s: base-drv/./dev_transfers.c.s base-drv/./enumerate.c.s base-drv/./usb_state.c.s base-drv/./class_hub.c.s base-drv/./enumerate_storage.c.s base-drv/./enumerate_hub.c.s base-drv/./usb-base-drv.c.s base-drv/./transfers.c.s base-drv/./print.c.s base-drv/./ch376.c.s base-drv/./protocol.c.s base-drv/./work-area.c.s base-drv/./usb-init.c.s
##
./scsi-drv.s: scsi-drv/./scsi-init.c.s scsi-drv/./class_scsi.c.s
##
./ufi-drv.s: ufi-drv/./ufi-init.c.s ufi-drv/./usb_cbi.c.s ufi-drv/./class_ufi.c.s

168
Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.c

@ -0,0 +1,168 @@
#include "class_scsi.h"
#include <string.h>
#include <usb_state.h>
#include <z80.h>
_scsi_command_block_wrapper scsi_command_block_wrapper = {{0x55, 0x53, 0x42, 0x43}, {0, 0}, 0, 0, 0, 0};
uint16_t next_tag = 0;
_scsi_command_status_wrapper csw = {{{0}}};
usb_error do_scsi_cmd(device_config_storage *const dev,
_scsi_command_block_wrapper *const cbw,
void *const send_receive_buffer,
const bool send) {
cbw->dCBWTag[0] = next_tag++;
if (!send)
cbw->bmCBWFlags = 0x80;
CHECK(usb_data_out_transfer((uint8_t *)cbw, sizeof(_scsi_command_block_wrapper) + 16, dev->address,
&dev->endpoints[ENDPOINT_BULK_OUT]));
if (cbw->dCBWDataTransferLength != 0) {
if (!send) {
CHECK(usb_data_in_transfer(send_receive_buffer, (uint16_t)cbw->dCBWDataTransferLength, dev->address,
&dev->endpoints[ENDPOINT_BULK_IN]));
} else {
CHECK(usb_data_out_transfer(send_receive_buffer, (uint16_t)cbw->dCBWDataTransferLength, dev->address,
&dev->endpoints[ENDPOINT_BULK_OUT]));
}
}
CHECK(
usb_data_in_transfer((uint8_t *)&csw, sizeof(_scsi_command_status_wrapper), dev->address, &dev->endpoints[ENDPOINT_BULK_IN]));
if (csw.bCSWStatus != 0 && csw.dCSWTag[0] != cbw->dCBWTag[0])
return USB_ERR_FAIL;
return USB_ERR_OK;
}
_scsi_read_capacity scsi_read_capacity = {0x25, 0, {0, 0, 0, 0, 0, 0, 0, 0}, {0, 0}};
usb_error get_scsi_read_capacity(device_config_storage *const dev, scsi_read_capacity_result *cap_result) {
cbw_scsi_read_capacity cbw_scsi;
cbw_scsi.cbw = scsi_command_block_wrapper;
cbw_scsi.read_capacity = scsi_read_capacity;
cbw_scsi.cbw.bCBWLUN = 0;
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_read_capacity);
cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_read_capacity_result);
return do_scsi_cmd(dev, &cbw_scsi.cbw, cap_result, false);
}
_scsi_packet_inquiry scsi_packet_inquiry = {0x12, 0, 0, 0, 0x24, 0, {0, 0, 0, 0, 0, 0}};
usb_error scsi_inquiry(device_config_storage *const dev, scsi_inquiry_result *inq_result) {
cbw_scsi_inquiry cbw_scsi;
cbw_scsi.cbw = scsi_command_block_wrapper;
cbw_scsi.inquiry = scsi_packet_inquiry;
cbw_scsi.cbw.bCBWLUN = 0;
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_inquiry);
cbw_scsi.cbw.dCBWDataTransferLength = 0x24;
return do_scsi_cmd(dev, &cbw_scsi.cbw, inq_result, false);
}
usb_error scsi_test(device_config_storage *const dev) {
cbw_scsi_test cbw_scsi;
cbw_scsi.cbw = scsi_command_block_wrapper;
memset(&cbw_scsi.test, 0, sizeof(_scsi_packet_test));
cbw_scsi.cbw.bCBWLUN = 0;
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_test);
cbw_scsi.cbw.dCBWDataTransferLength = 0;
return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false);
}
_scsi_packet_request_sense scsi_packet_request_sense = {0x03, 0, 0, 0, 18, 0, {0, 0, 0, 0, 0, 0}};
usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result) {
cbw_scsi_request_sense cbw_scsi;
cbw_scsi.cbw = scsi_command_block_wrapper;
cbw_scsi.request_sense = scsi_packet_request_sense;
cbw_scsi.cbw.bCBWLUN = 0;
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_request_sense);
cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_sense_result);
return do_scsi_cmd(dev, &cbw_scsi.cbw, sens_result, false);
}
usb_error scsi_sense_init(device_config_storage *const dev) {
scsi_sense_result response;
uint8_t counter = 3;
while ((result = scsi_test(dev)) && --counter > 0)
scsi_request_sense(dev, &response);
return result;
}
static cbw_scsi_read_write cbw = {{{0}}};
usb_error scsi_read(device_config_storage *const dev, uint8_t *const buffer) {
memset(&cbw, 0, sizeof(cbw_scsi_read_write));
cbw.cbw = scsi_command_block_wrapper;
cbw.cbw.bCBWLUN = 0;
cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write);
cbw.cbw.dCBWDataTransferLength = 512;
cbw.scsi_cmd.operation_code = 0x28; // read operation
cbw.scsi_cmd.transfer_len[1] = 1;
cbw.scsi_cmd.lba[0] = dev->current_lba >> 24;
cbw.scsi_cmd.lba[1] = dev->current_lba >> 16;
cbw.scsi_cmd.lba[2] = dev->current_lba >> 8;
cbw.scsi_cmd.lba[3] = dev->current_lba;
result = do_scsi_cmd(dev, &cbw.cbw, buffer, false);
if (result == USB_ERR_OK)
dev->current_lba++;
return result;
}
usb_error scsi_write(device_config_storage *const dev, uint8_t *const buffer) {
memset(&cbw, 0, sizeof(cbw_scsi_read_write));
cbw.cbw = scsi_command_block_wrapper;
cbw.cbw.bCBWLUN = 0;
cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write);
cbw.cbw.dCBWDataTransferLength = 512;
cbw.scsi_cmd.operation_code = 0x2A; // write operation
cbw.scsi_cmd.transfer_len[1] = 1;
cbw.scsi_cmd.lba[0] = dev->current_lba >> 24;
cbw.scsi_cmd.lba[1] = dev->current_lba >> 16;
cbw.scsi_cmd.lba[2] = dev->current_lba >> 8;
cbw.scsi_cmd.lba[3] = dev->current_lba;
result = do_scsi_cmd(dev, &cbw.cbw, buffer, true);
if (result == USB_ERR_OK)
dev->current_lba++;
return result;
}
usb_error scsi_eject(device_config_storage *const dev) {
cbw_scsi_eject cbw_scsi;
cbw_scsi.cbw = scsi_command_block_wrapper;
memset(&cbw_scsi.eject, 0, sizeof(_scsi_packet_eject));
cbw_scsi.eject.operation_code = 0x1B;
cbw_scsi.eject.loej = 1;
cbw_scsi.cbw.bCBWLUN = 0;
cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_eject);
cbw_scsi.cbw.dCBWDataTransferLength = 0;
return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false);
}

196
Source/HBIOS/ch376-native/source-doc/scsi-drv/class_scsi.h

@ -0,0 +1,196 @@
#ifndef __CLASS_SCSI
#define __CLASS_SCSI
#include <protocol.h>
typedef struct {
uint8_t dCBWSignature[4];
uint16_t dCBWTag[2];
uint32_t dCBWDataTransferLength;
uint8_t bmCBWFlags;
uint8_t bCBWLUN;
uint8_t bCBWCBLength;
} _scsi_command_block_wrapper;
typedef struct {
uint8_t operation_code;
uint8_t lun;
uint8_t reserved1;
uint8_t reserved2;
uint8_t allocation_length;
uint8_t reserved3;
uint8_t pad[6];
} _scsi_packet_request_sense;
typedef struct {
_scsi_command_block_wrapper cbw;
_scsi_packet_request_sense request_sense;
} cbw_scsi_request_sense;
typedef struct {
uint8_t operation_code;
uint8_t IMMED : 1;
uint8_t reserved : 7;
uint8_t reserved2;
uint8_t power_condition_modifier : 4;
uint8_t reserved3 : 4;
uint8_t start : 1;
uint8_t loej : 1;
uint8_t no_flush : 1;
uint8_t reserved4 : 1;
uint8_t power_condition : 4;
uint8_t control;
} _scsi_packet_eject;
typedef struct {
_scsi_command_block_wrapper cbw;
_scsi_packet_eject eject;
} cbw_scsi_eject;
typedef struct {
uint8_t operation_code;
uint8_t lun;
uint8_t reserved1;
uint8_t reserved2;
uint8_t reserved3;
uint8_t reserved4;
uint8_t pad[6];
} _scsi_packet_test;
typedef struct {
_scsi_command_block_wrapper cbw;
_scsi_packet_test test;
} cbw_scsi_test;
typedef struct {
uint8_t operation_code;
uint8_t lun;
uint8_t reserved[8];
uint8_t pad[2];
} _scsi_read_capacity;
typedef struct {
_scsi_command_block_wrapper cbw;
_scsi_read_capacity read_capacity;
} cbw_scsi_read_capacity;
typedef struct __scsi_packet_inquiry { // contains information about a specific device
uint8_t operation_code;
uint8_t lun;
uint8_t reserved1;
uint8_t reserved2;
uint8_t allocation_length;
uint8_t reserved3;
uint8_t pad[6];
} _scsi_packet_inquiry;
typedef struct {
_scsi_command_block_wrapper cbw;
_scsi_packet_inquiry inquiry;
} cbw_scsi_inquiry;
typedef struct {
uint8_t device_type : 5;
uint8_t device_type_qualifier : 3;
uint8_t device_type_modifier : 7;
uint8_t removable_media : 1;
union {
uint8_t versions;
struct {
uint8_t ansi_version : 3;
uint8_t ecma_version : 3;
uint8_t iso_version : 2;
};
};
uint8_t response_data_format : 4;
uint8_t hi_support : 1;
uint8_t norm_aca : 1;
uint8_t terminate_task : 1;
uint8_t aerc : 1;
uint8_t additional_length;
uint8_t reserved;
uint8_t addr16 : 1;
uint8_t addr32 : 1;
uint8_t ack_req_q : 1;
uint8_t medium_changer : 1;
uint8_t multi_port : 1;
uint8_t reserved_bit2 : 1;
uint8_t enclosure_services : 1;
uint8_t reserved_bit3 : 1;
uint8_t soft_reset : 1;
uint8_t command_queue : 1;
uint8_t transfer_disable : 1;
uint8_t linked_commands : 1;
uint8_t synchronous : 1;
uint8_t wide16_bit : 1;
uint8_t wide32_bit : 1;
uint8_t relative_addressing : 1;
uint8_t vendor_information[8];
uint8_t product_id[16];
uint8_t product_revision[4];
uint8_t vendor_specific[20];
uint8_t reserved3[40];
} scsi_inquiry_result;
typedef struct __scsi_command_status_wrapper {
uint8_t dCSWSignature[4];
uint16_t dCSWTag[2];
uint8_t dCSWDataResidue[4];
uint8_t bCSWStatus;
} _scsi_command_status_wrapper;
typedef struct {
uint8_t number_of_blocks[4];
uint8_t block_size[4];
} scsi_read_capacity_result;
typedef struct {
uint8_t error_code : 7;
uint8_t valid : 1;
uint8_t segment_number;
uint8_t sense_key : 4;
uint8_t reserved : 1;
uint8_t incorrect_length : 1;
uint8_t end_of_media : 1;
uint8_t file_mark : 1;
uint8_t information[4];
uint8_t additional_sense_length;
uint8_t command_specific_information[4];
uint8_t additional_sense_code;
uint8_t additional_sense_code_qualifier;
uint8_t field_replaceable_unit_code;
uint8_t sense_key_specific[3];
} scsi_sense_result;
typedef struct {
uint8_t operation_code;
uint8_t lun;
uint8_t lba[4]; // high-endian block number
uint8_t reserved1;
uint8_t transfer_len[2]; // high-endian in blocks of block_len (see scsi_capacity)
uint8_t reserved2;
uint8_t pad[2];
} _scsi_packet_read_write;
typedef struct {
_scsi_command_block_wrapper cbw;
_scsi_packet_read_write scsi_cmd;
} cbw_scsi_read_write;
extern usb_error get_scsi_read_capacity(device_config_storage *const dev, scsi_read_capacity_result *result);
extern usb_error scsi_inquiry(device_config_storage *const dev, scsi_inquiry_result *inq_result);
extern usb_error scsi_sense_init(device_config_storage *const dev);
extern usb_error scsi_test(device_config_storage *const dev);
extern usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result);
extern usb_error scsi_eject(device_config_storage *const dev);
extern usb_error scsi_read_write(
device_config_storage *const dev, const bool send, uint32_t sector_number, const uint8_t sector_count, uint8_t *const buffer);
extern usb_error scsi_read(device_config_storage *const dev, uint8_t *const buffer);
extern usb_error scsi_write(device_config_storage *const dev, uint8_t *const buffer);
#endif

35
Source/HBIOS/ch376-native/source-doc/scsi-drv/scsi-init.c

@ -0,0 +1,35 @@
#include "class_scsi.h"
#include <ch376.h>
#include <enumerate.h>
#include <hbios.h>
#include <print.h>
#include <string.h>
#include <usb-base-drv.h>
#include <work-area.h>
#include <z80.h>
extern const uint16_t const ch_scsi_fntbl[];
void chscsi_init(void) {
uint8_t index = 1;
do {
device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index);
if (storage_device == NULL)
break;
const usb_device_type t = storage_device->type;
if (t == USB_IS_MASS_STORAGE) {
storage_device->drive_index = storage_count++;
scsi_sense_init(storage_device);
dio_add_entry(ch_scsi_fntbl, storage_device);
}
} while (++index != MAX_NUMBER_OF_DEVICES + 1);
if (storage_count == 0)
return;
print_device_mounted(" STORAGE DEVICE$", storage_count);
}

176
Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.c

@ -0,0 +1,176 @@
#include "class_ufi.h"
#include <delay.h>
#include <protocol.h>
#include <stdlib.h>
#include <string.h>
#include <z80.h>
const ufi_request_sense_command _ufi_cmd_request_sense = {0x03, 0, 0, 0, 0, 18, {0, 0, 0, 0, 0, 0, 0}};
const ufi_read_format_capacities_command _ufi_cmd_read_format_capacities = {0x23, 0, 0, {0, 0, 0, 0, 0}, {0, 12}, {0, 0, 0}};
const ufi_inquiry_command _ufi_cmd_inquiry = {0x12, 0, 0, 0, 0, 0, 0x24, {0, 0, 0, 0, 0, 0, 0}};
const ufi_format_command _ufi_cmd_format = {0x04, 7, 0, 1, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0, 0}};
const ufi_send_diagnostic_command _ufi_cmd_send_diagnostic = {0x1D, 0, 0, 1, 0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
uint8_t wait_for_device_ready(device_config *const storage_device, uint8_t timeout_counter) {
usb_error result;
ufi_request_sense_response sense;
do {
memset(&sense, 0, sizeof(sense));
result = ufi_test_unit_ready(storage_device, &sense);
if ((result == USB_ERR_OK && sense.sense_key == 0) || timeout_counter-- == 0)
break;
delay_medium();
} while (true);
return result | sense.sense_key;
}
usb_error ufi_test_unit_ready(device_config *const storage_device, ufi_request_sense_response const *response) {
usb_error result;
ufi_test_unit_ready_command ufi_cmd_request_test_unit_ready;
memset(&ufi_cmd_request_test_unit_ready, 0, sizeof(ufi_test_unit_ready_command));
usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_test_unit_ready, false, 0, NULL, NULL);
ufi_request_sense_command ufi_cmd_request_sense;
ufi_cmd_request_sense = _ufi_cmd_request_sense;
result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response),
(uint8_t *)response, NULL);
RETURN_CHECK(result);
}
usb_error ufi_request_sense(device_config *const storage_device, ufi_request_sense_response const *response) {
ufi_request_sense_command ufi_cmd_request_sense;
ufi_cmd_request_sense = _ufi_cmd_request_sense;
usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response),
(uint8_t *)response, NULL);
RETURN_CHECK(result);
}
usb_error ufi_read_frmt_caps(device_config *const storage_device, ufi_format_capacities_response const *response) {
usb_error result;
ufi_read_format_capacities_command ufi_cmd_read_format_capacities;
ufi_cmd_read_format_capacities = _ufi_cmd_read_format_capacities;
result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_read_format_capacities, false, 12, (uint8_t *)response, NULL);
TRACE_USB_ERROR(result);
CHECK(result);
const uint8_t available_length = response->capacity_list_length;
const uint8_t max_length =
available_length > sizeof(ufi_format_capacities_response) ? sizeof(ufi_format_capacities_response) : available_length;
ufi_read_format_capacities_command cmd;
memcpy(&cmd, &ufi_cmd_read_format_capacities, sizeof(cmd));
cmd.allocation_length[1] = max_length;
result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, false, max_length, (uint8_t *)response, NULL);
TRACE_USB_ERROR(result);
RETURN_CHECK(result);
}
usb_error ufi_inquiry(device_config *const storage_device, ufi_inquiry_response const *response) {
ufi_inquiry_command ufi_cmd_inquiry;
ufi_cmd_inquiry = _ufi_cmd_inquiry;
usb_error result =
usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_inquiry, false, sizeof(ufi_inquiry_response), (uint8_t *)response, NULL);
RETURN_CHECK(result);
}
usb_error ufi_read_write_sector(device_config *const storage_device,
const bool send,
const uint16_t sector_number,
const uint8_t sector_count,
const uint8_t *const buffer,
uint8_t *const sense_codes) {
ufi_read_write_command cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.operation_code = send ? 0x2A : 0x28;
cmd.lba[2] = sector_number >> 8;
cmd.lba[3] = sector_number & 0xFF;
cmd.transfer_length[1] = sector_count;
usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, send, 512 * sector_count, (uint8_t *)buffer, sense_codes);
RETURN_CHECK(result);
}
/**
* Medium | Medium Type Code | Capacity | Tracks | Heads | Sectors/Track | Total Blocks | Block Length |
* DD | 1Eh | 720 KB | 80 | 2 | 9 | 1440 05A0h | 512 0200h |
* HD | 93h | 1.25 MB | 77 | 2 | 8 | 1232 04D0h | 1024 0400h |
* HD | 94h | 1.44 MB | 80 | 2 | 18 | 2880 0B40h | 512 0200h |
*/
usb_error ufi_format(device_config *const storage_device,
const uint8_t side,
const uint8_t track_number,
const ufi_format_capacity_descriptor *const format) {
ufi_interrupt_status sense_codes;
ufi_format_parameter_list parameter_list;
memset(&parameter_list, 0, sizeof(parameter_list));
ufi_format_command cmd;
cmd = _ufi_cmd_format;
// memcpy(&cmd, &_ufi_cmd_format, sizeof(cmd));
cmd.track_number = track_number;
cmd.interleave[1] = 0;
cmd.parameter_list_length[1] = sizeof(parameter_list);
parameter_list.defect_list_header.side = side;
parameter_list.defect_list_header.immediate = 0;
parameter_list.defect_list_header.reserved2 = 0;
parameter_list.defect_list_header.single_track = 1;
parameter_list.defect_list_header.dcrt = 1;
parameter_list.defect_list_header.extend = 0;
parameter_list.defect_list_header.fov = 1;
parameter_list.defect_list_header.defect_list_length_msb = 0;
parameter_list.defect_list_header.defect_list_length_lsb = 8;
memcpy(&parameter_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 *)&parameter_list,
(void *)&sense_codes);
// trace_printf("ufi_format: %d, %02X %02X (len: %d)\r\n", result, sense_codes.bASC, sense_codes.bASCQ, sizeof(parameter_list));
RETURN_CHECK(result);
}
usb_error ufi_send_diagnostics(device_config *const storage_device) {
usb_error result;
ufi_send_diagnostic_command ufi_cmd_send_diagnostic;
ufi_cmd_send_diagnostic = _ufi_cmd_send_diagnostic;
result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_send_diagnostic, true, 0, NULL, NULL);
RETURN_CHECK(result);
}
uint32_t convert_from_msb_first(const uint8_t *const buffer) {
uint32_t result;
uint8_t *p_output = ((uint8_t *)&result);
const uint8_t *p_input = buffer + 3;
*p_output++ = *p_input--;
*p_output++ = *p_input--;
*p_output++ = *p_input--;
*p_output = *p_input--;
return result;
}

207
Source/HBIOS/ch376-native/source-doc/ufi-drv/class_ufi.h

@ -0,0 +1,207 @@
#ifndef __CLASS_UFI2
#define __CLASS_UFI2
#include "ch376.h"
#include "protocol.h"
#include "usb_cbi.h"
#include "usb_state.h"
#include <stdlib.h>
typedef struct {
uint8_t bASC;
uint8_t bASCQ;
} ufi_interrupt_status;
typedef struct {
uint8_t operation_code;
uint8_t reserverd1 : 5;
uint8_t lun : 3;
uint8_t reserved1[5];
uint8_t allocation_length[2];
uint8_t reserved[3];
} ufi_read_format_capacities_command;
typedef enum { UNFORMATTED_MEDIA = 1, FORMATTED_MEDIA = 2, NO_MEDIA = 3 } UFI_DESCRIPTOR_CODE;
#define UFI_DESCRIPTOR_CODE_UNFORMATTED_MEDIA 1
#define UFI_DESCRIPTOR_CODE_FORMATTED_MEDIA 2
#define UFI_DESCRIPTOR_CODE_NO_MEDIA 3
typedef struct {
uint8_t number_of_blocks[4];
uint8_t descriptor_code : 2; // UFI_DESCRIPTOR_CODE
uint8_t reserved2 : 6;
uint8_t block_size[3];
} ufi_format_capacity_descriptor;
typedef struct {
uint8_t reserved1[3];
uint8_t capacity_list_length;
ufi_format_capacity_descriptor descriptors[4]; // support upto
} ufi_format_capacities_response;
typedef struct {
uint8_t operation_code;
uint8_t lun;
uint8_t reserved[10];
} ufi_test_unit_ready_command;
typedef struct {
uint8_t operation_code;
uint8_t evpd : 1;
uint8_t reserved1 : 4;
uint8_t lun : 3;
uint8_t page_code;
uint8_t reserved3;
uint8_t allocation_length;
uint8_t reserved4[7];
} ufi_inquiry_command;
typedef struct {
uint8_t operation_code;
uint8_t reserverd1 : 5;
uint8_t lun : 3;
uint8_t reserved2;
uint8_t reserved3;
uint8_t allocation_length;
uint8_t reserved4[7];
} ufi_request_sense_command;
typedef struct {
uint8_t error_code;
uint8_t reserved1;
uint8_t sense_key : 4;
uint8_t reserved2 : 4;
uint8_t information[4];
uint8_t additional_length;
uint8_t reserved3[4];
uint8_t asc; // Additional Sense Code
uint8_t ascq; // Additional Sense Code Qualifier
uint8_t reserved4[4];
} ufi_request_sense_response;
typedef struct {
// device_type: identifies the device currently connected to the requested logical unit.
// 00h Direct-access device (floppy)
// 1Fh none (no FDD connected to the requested logical unit)
uint8_t device_type : 5;
uint8_t reserved1 : 3;
uint8_t reserved2 : 7;
// Removable Media Bit: this shall be set to one to indicate removable media.
uint8_t removable_media : 1;
// ANSI Version: must contain a zero to comply with this version of the Specification.
uint8_t ansi_version : 3;
// ISO/ECMA: These fields shall be zero for the UFI device.
uint8_t ecma : 3;
uint8_t iso_version : 2;
// Response Data Format: a value of 01h shall be used for UFI device
uint8_t response_data_format : 4;
uint8_t reserved3 : 4;
// The Additional Length field shall specify the length in bytes of the parameters. If the Allocation Length of the
// Command Packet is too small to transfer all of the parameters, the Additional Length shall not be adjusted to
// reflect the truncation. The UFI device shall set this field to 1Fh.
uint8_t additional_length;
uint8_t reserved4[3];
// The Vendor Identification field contains 8 bytes of ASCII data identifying the vendor of the product. The data
// shall be left aligned within this field.
char vendor_information[8];
// The Product Identification field contains 16 bytes of ASCII data as defined by the vendor. The data shall be
// left-aligned within this field.
char product_id[16];
// The Product Revision Level field contains 4 bytes of ASCII data as defined by the vendor.
char product_revision[4];
} ufi_inquiry_response;
typedef struct {
uint8_t operation_code; /*0*/
union { /*1*/
uint8_t byte_1;
struct {
uint8_t rel_adr : 1;
uint8_t reserved1 : 2;
uint8_t fua : 1;
uint8_t dpo : 1;
uint8_t lun : 3;
};
};
uint8_t lba[4]; /*2, 3, 4, 5*/
uint8_t reserved2; /*6*/
uint8_t transfer_length[2]; /*7, 8*/
uint8_t reserved3[3]; /*9, 10, 11*/
} ufi_read_write_command;
typedef struct {
struct {
uint8_t reserved1;
uint8_t side : 1;
uint8_t immediate : 1;
uint8_t reserved2 : 2;
uint8_t single_track : 1;
uint8_t dcrt : 1;
uint8_t extend : 1;
uint8_t fov : 1;
uint8_t defect_list_length_msb;
uint8_t defect_list_length_lsb;
} defect_list_header;
ufi_format_capacity_descriptor format_descriptor;
} ufi_format_parameter_list;
typedef struct {
uint8_t operation_code; /* 0x04 */
uint8_t defect_list_format : 3;
uint8_t cmp_list : 1;
uint8_t format_data : 1;
uint8_t lun : 3;
uint8_t track_number;
uint8_t interleave[2];
uint8_t reserved1[2];
uint8_t parameter_list_length[2];
uint8_t reserved2[3];
} ufi_format_command;
typedef struct {
uint8_t operation_code; /*0x1D*/
uint8_t unit_of_l : 1;
uint8_t def_of_l : 1;
uint8_t self_test : 1;
uint8_t reserved1 : 1;
uint8_t pf : 1;
uint8_t lun : 3;
uint8_t reserved[10];
} ufi_send_diagnostic_command;
extern usb_error ufi_request_sense(device_config *const storage_device, ufi_request_sense_response const *response);
extern usb_error ufi_read_frmt_caps(device_config *const storage_device, ufi_format_capacities_response const *response);
extern usb_error ufi_test_unit_ready(device_config *const storage_device, ufi_request_sense_response const *response);
extern usb_error ufi_inquiry(device_config *const storage_device, ufi_inquiry_response const *response);
extern usb_error ufi_read_write_sector(device_config *const storage_device,
const bool send,
const uint16_t sector_number,
const uint8_t sector_count,
const uint8_t *const buffer,
uint8_t *const sense_codes);
uint8_t wait_for_device_ready(device_config *const storage_device, uint8_t timeout_counter);
usb_error ufi_format(device_config *const storage_device,
const uint8_t side,
const uint8_t track_number,
const ufi_format_capacity_descriptor *const format);
usb_error ufi_send_diagnostics(device_config *const storage_device);
uint32_t convert_from_msb_first(const uint8_t *const buffer);
#endif

92
Source/HBIOS/ch376-native/source-doc/ufi-drv/ufi-init.c

@ -0,0 +1,92 @@
#include "class_ufi.h"
#include <dev_transfers.h>
#include <hbios.h>
#include <print.h>
#include <string.h>
#include <usb-base-drv.h>
#include <work-area.h>
extern const uint16_t const ch_ufi_fntbl[];
void chufi_init(void) {
uint8_t index = 1;
do {
device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index);
if (storage_device == NULL)
break;
const usb_device_type t = storage_device->type;
if (t == USB_IS_FLOPPY) {
storage_device->drive_index = storage_count++;
// scsi_sense_init(storage_device);
dio_add_entry(ch_ufi_fntbl, storage_device);
}
} while (++index != MAX_NUMBER_OF_DEVICES + 1);
if (storage_count == 0)
return;
print_device_mounted(" FLOPPY DRIVE$", storage_count);
}
uint32_t chufi_get_cap(device_config *const dev) {
ufi_format_capacities_response response;
memset(&response, 0, sizeof(ufi_format_capacities_response));
wait_for_device_ready(dev, 25);
// not sure if we need to do this to 'clear' some state
ufi_inquiry_response inquiry;
ufi_inquiry(dev, &inquiry);
wait_for_device_ready(dev, 15);
const usb_error result = ufi_read_frmt_caps(dev, &response);
if (result != USB_ERR_OK)
return 0;
// info->sector_size = response.descriptors[0].block_size[1] << 8 + response.descriptors[0].block_size[0];
return convert_from_msb_first(response.descriptors[0].number_of_blocks);
// const disk_geometry *const geometry = size_to_geometry(info->number_of_sectors);
// info->flags = INFO_FLAG_REMOVABLE | INFO_FLAG_FLOPPY;
// info->number_of_cylinders = geometry->tracks;
// info->number_of_heads = geometry->sides;
// info->number_of_sectors_per_track = geometry->sectors_per_track;
// return 0;
}
uint8_t chufi_read(device_config_storage *const dev, uint8_t *const buffer) {
if (wait_for_device_ready((device_config *)dev, 20) != 0)
return -1; // Not READY!
usb_error result;
ufi_interrupt_status sense_codes;
memset(&sense_codes, 0, sizeof(sense_codes));
if (ufi_read_write_sector((device_config *)dev, false, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes) != USB_ERR_OK)
return -1; // general error
ufi_request_sense_response response;
memset(&response, 0, sizeof(response));
if ((result = ufi_request_sense((device_config *)dev, &response)) != USB_ERR_OK)
return -1; // error
const uint8_t asc = response.asc;
const uint8_t ascq = response.ascq;
const uint8_t sense_key = response.sense_key;
if (sense_key != 0)
return -1;
return USB_ERR_OK;
}

64
Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.c

@ -0,0 +1,64 @@
#include "usb_cbi.h"
#include "dev_transfers.h"
#include "protocol.h"
#include <ch376.h>
setup_packet cbi2_adsc = {0x21, 0, {0, 0}, {255, 0}, 12}; // ;4th byte is interface number
// was no clear
usb_error usb_execute_cbi(device_config *const storage_device,
const uint8_t *const cmd,
const bool send,
const uint16_t buffer_size,
uint8_t *const buffer,
uint8_t *const sense_codes) {
usb_error result;
const uint8_t interface_number = storage_device->interface_number;
setup_packet adsc;
adsc = cbi2_adsc;
adsc.bIndex[0] = interface_number;
result = usbdev_control_transfer(storage_device, &adsc, (uint8_t *const)cmd);
if (result == USB_ERR_STALL) {
if (sense_codes != NULL)
usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN);
return USB_ERR_STALL;
}
if (result != USB_ERR_OK) {
TRACE_USB_ERROR(result);
return result;
}
if (send) {
result = usbdev_blk_out_trnsfer(storage_device, buffer, buffer_size);
if (result != USB_ERR_OK) {
TRACE_USB_ERROR(result);
return result;
}
} else {
result = usbdev_dat_in_trnsfer(storage_device, buffer, buffer_size, ENDPOINT_BULK_IN);
if (result != USB_ERR_OK) {
TRACE_USB_ERROR(result);
return result;
}
}
if (sense_codes != NULL) {
result = usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN);
if (result != USB_ERR_OK) {
TRACE_USB_ERROR(result);
return result;
}
}
return USB_ERR_OK;
}

14
Source/HBIOS/ch376-native/source-doc/ufi-drv/usb_cbi.h

@ -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

4
Source/HBIOS/ch376-native/ufi-drv.s

@ -0,0 +1,4 @@
; Generated File -- not to be modify directly
#include "ch376-native/ufi-drv/ufi-init.c.s"
#include "ch376-native/ufi-drv/usb_cbi.c.s"
#include "ch376-native/ufi-drv/class_ufi.c.s"

705
Source/HBIOS/ch376-native/ufi-drv/class_ufi.c.s

@ -0,0 +1,705 @@
;
; Generated from source-doc/ufi-drv/./class_ufi.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/ufi-drv/./class_ufi.c:14: uint8_t wait_for_device_ready(device_config *const storage_device, uint8_t timeout_counter) {
; ---------------------------------
; Function wait_for_device_ready
; ---------------------------------
_wait_for_device_ready:
push ix
ld ix,0
add ix,sp
ld hl, -18
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:18: do {
ld c,(ix+6)
l_wait_for_device_ready_00105:
;source-doc/ufi-drv/./class_ufi.c:19: memset(&sense, 0, sizeof(sense));
push bc
ld hl,2
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x12
push hl
call _memset_callee
ld hl,2
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ufi_test_unit_ready
pop af
pop af
ld a, l
pop bc
ld b, a
;source-doc/ufi-drv/./class_ufi.c:22: if ((result == USB_ERR_OK && sense.sense_key == 0) || timeout_counter-- == 0)
or a
jr NZ,l_wait_for_device_ready_00104
ld hl,2
add hl, sp
ld a, (hl)
and 0x0f
jr Z,l_wait_for_device_ready_00107
l_wait_for_device_ready_00104:
ld a, c
dec c
or a
jr Z,l_wait_for_device_ready_00107
;source-doc/ufi-drv/./class_ufi.c:25: delay_medium();
push bc
call _delay_medium
pop bc
;source-doc/ufi-drv/./class_ufi.c:27: } while (true);
jr l_wait_for_device_ready_00105
l_wait_for_device_ready_00107:
;source-doc/ufi-drv/./class_ufi.c:29: return result | sense.sense_key;
ld hl,2
add hl, sp
ld a, (hl)
and 0x0f
or b
ld l, a
;source-doc/ufi-drv/./class_ufi.c:30: }
ld sp, ix
pop ix
ret
__ufi_cmd_request_sense:
DEFB +0x03
DEFB 0x00
DEFB +0x00
DEFB +0x00
DEFB +0x12
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
__ufi_cmd_read_format_capacitie:
DEFB +0x23
DEFB 0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x0c
DEFB +0x00
DEFB +0x00
DEFB +0x00
__ufi_cmd_inquiry:
DEFB +0x12
DEFB 0x00
DEFB +0x00
DEFB +0x00
DEFB +0x24
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
__ufi_cmd_format:
DEFB +0x04
DEFB 0x17
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
__ufi_cmd_send_diagnostic:
DEFB +0x1d
DEFB 0x04
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0x00
;source-doc/ufi-drv/./class_ufi.c:32: usb_error ufi_test_unit_ready(device_config *const storage_device, ufi_request_sense_response const *response) {
; ---------------------------------
; Function ufi_test_unit_ready
; ---------------------------------
_ufi_test_unit_ready:
push ix
ld ix,0
add ix,sp
ld hl, -24
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:35: memset(&ufi_cmd_request_test_unit_ready, 0, sizeof(ufi_test_unit_ready_command));
ld hl,0
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x0c
push hl
call _memset_callee
;source-doc/ufi-drv/./class_ufi.c:37: usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_test_unit_ready, false, 0, NULL, NULL);
ld hl,0x0000
push hl
push hl
push hl
xor a
push af
inc sp
ld hl,7
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld hl,11
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:40: ufi_cmd_request_sense = _ufi_cmd_request_sense;
ld hl,12
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x000c
ld hl,__ufi_cmd_request_sense
ldir
pop bc
;source-doc/ufi-drv/./class_ufi.c:43: (uint8_t *)response, NULL);
ld e,(ix+6)
ld d,(ix+7)
;source-doc/ufi-drv/./class_ufi.c:42: result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response),
ld hl,0x0000
push hl
push de
ld l,0x12
push hl
xor a
push af
inc sp
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:45: RETURN_CHECK(result);
;source-doc/ufi-drv/./class_ufi.c:46: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:48: usb_error ufi_request_sense(device_config *const storage_device, ufi_request_sense_response const *response) {
; ---------------------------------
; Function ufi_request_sense
; ---------------------------------
_ufi_request_sense:
push ix
ld ix,0
add ix,sp
ld hl, -12
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:50: ufi_cmd_request_sense = _ufi_cmd_request_sense;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x000c
ld hl,__ufi_cmd_request_sense
ldir
pop bc
;source-doc/ufi-drv/./class_ufi.c:52: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_request_sense, false, sizeof(ufi_request_sense_response),
ld e,(ix+6)
ld d,(ix+7)
ld hl,0x0000
push hl
push de
ld l,0x12
push hl
xor a
push af
inc sp
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:55: RETURN_CHECK(result);
;source-doc/ufi-drv/./class_ufi.c:56: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:58: usb_error ufi_read_frmt_caps(device_config *const storage_device, ufi_format_capacities_response const *response) {
; ---------------------------------
; Function ufi_read_frmt_caps
; ---------------------------------
_ufi_read_frmt_caps:
push ix
ld ix,0
add ix,sp
ld hl, -24
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:62: ufi_cmd_read_format_capacities = _ufi_cmd_read_format_capacities;
ld hl,0
add hl, sp
ex de, hl
ld bc,0x000c
ld hl,__ufi_cmd_read_format_capacitie
ldir
;source-doc/ufi-drv/./class_ufi.c:63: result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_read_format_capacities, false, 12, (uint8_t *)response, NULL);
ld c,(ix+6)
ld b,(ix+7)
push bc
ld hl,0x0000
push hl
push bc
ld l,0x0c
push hl
xor a
push af
inc sp
ld hl,9
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
ld sp, iy
pop bc
;source-doc/ufi-drv/./class_ufi.c:66: CHECK(result);
ld a, l
or a
jr NZ,l_ufi_read_frmt_caps_00103
;source-doc/ufi-drv/./class_ufi.c:68: const uint8_t available_length = response->capacity_list_length;
ld l,(ix+6)
ld h,(ix+7)
inc hl
inc hl
inc hl
ld e, (hl)
;source-doc/ufi-drv/./class_ufi.c:70: const uint8_t max_length =
ld a,0x24
sub e
jr NC,l_ufi_read_frmt_caps_00105
ld e,0x24
l_ufi_read_frmt_caps_00105:
;source-doc/ufi-drv/./class_ufi.c:74: memcpy(&cmd, &ufi_cmd_read_format_capacities, sizeof(cmd));
push bc
push de
ld hl,16
add hl, sp
push hl
ld hl,6
add hl, sp
push hl
ld hl,0x000c
push hl
call _memcpy_callee
pop de
pop bc
;source-doc/ufi-drv/./class_ufi.c:75: cmd.allocation_length[1] = max_length;
ld (ix-4),e
;source-doc/ufi-drv/./class_ufi.c:77: result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, false, max_length, (uint8_t *)response, NULL);
ld hl,0x0000
ld d,l
push hl
push bc
push de
xor a
push af
inc sp
ld hl,19
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:80: RETURN_CHECK(result);
l_ufi_read_frmt_caps_00103:
;source-doc/ufi-drv/./class_ufi.c:81: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:83: usb_error ufi_inquiry(device_config *const storage_device, ufi_inquiry_response const *response) {
; ---------------------------------
; Function ufi_inquiry
; ---------------------------------
_ufi_inquiry:
push ix
ld ix,0
add ix,sp
ld hl, -12
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:85: ufi_cmd_inquiry = _ufi_cmd_inquiry;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x000c
ld hl,__ufi_cmd_inquiry
ldir
pop bc
;source-doc/ufi-drv/./class_ufi.c:87: usb_error result =
ld e,(ix+6)
ld d,(ix+7)
ld hl,0x0000
push hl
push de
ld l,0x24
push hl
xor a
push af
inc sp
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:90: RETURN_CHECK(result);
;source-doc/ufi-drv/./class_ufi.c:91: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:93: usb_error ufi_read_write_sector(device_config *const storage_device,
; ---------------------------------
; Function ufi_read_write_sector
; ---------------------------------
_ufi_read_write_sector:
push ix
ld ix,0
add ix,sp
ld hl, -12
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:100: memset(&cmd, 0, sizeof(cmd));
ld hl,0
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x0c
push hl
call _memset_callee
;source-doc/ufi-drv/./class_ufi.c:101: cmd.operation_code = send ? 0x2A : 0x28;
bit 0,(ix+6)
jr Z,l_ufi_read_write_sector_00103
ld bc,0x002a
jr l_ufi_read_write_sector_00104
l_ufi_read_write_sector_00103:
ld bc,0x0028
l_ufi_read_write_sector_00104:
ld (ix-12),c
;source-doc/ufi-drv/./class_ufi.c:102: cmd.lba[2] = sector_number >> 8;
ld a,(ix+8)
ld (ix-8),a
;source-doc/ufi-drv/./class_ufi.c:103: cmd.lba[3] = sector_number & 0xFF;
ld a,(ix+7)
ld (ix-7),a
;source-doc/ufi-drv/./class_ufi.c:104: cmd.transfer_length[1] = sector_count;
;source-doc/ufi-drv/./class_ufi.c:106: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, send, 512 * sector_count, (uint8_t *)buffer, sense_codes);
ld a,(ix+9)
ld (ix-4),a
add a, a
ld c,0x00
ld l,(ix+12)
ld h,(ix+13)
push hl
ld l,(ix+10)
ld h,(ix+11)
push hl
ld b, a
push bc
ld a,(ix+6)
push af
inc sp
ld hl,7
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:108: RETURN_CHECK(result);
;source-doc/ufi-drv/./class_ufi.c:109: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:118: usb_error ufi_format(device_config *const storage_device,
; ---------------------------------
; Function ufi_format
; ---------------------------------
_ufi_format:
push ix
ld ix,0
add ix,sp
ld hl, -26
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:125: memset(&parameter_list, 0, sizeof(parameter_list));
ld hl,2
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x0c
push hl
call _memset_callee
;source-doc/ufi-drv/./class_ufi.c:128: cmd = _ufi_cmd_format;
ld hl,14
add hl, sp
ex de, hl
ld bc,0x000c
ld hl,__ufi_cmd_format
ldir
;source-doc/ufi-drv/./class_ufi.c:131: cmd.track_number = track_number;
ld a,(ix+7)
ld (ix-10),a
;source-doc/ufi-drv/./class_ufi.c:132: cmd.interleave[1] = 0;
ld (ix-8),0x00
;source-doc/ufi-drv/./class_ufi.c:133: cmd.parameter_list_length[1] = sizeof(parameter_list);
ld (ix-4),0x0c
;source-doc/ufi-drv/./class_ufi.c:135: parameter_list.defect_list_header.side = side;
ld hl,2+1
add hl, sp
ex de, hl
ld a,(ix+6)
and 0x01
ld c, a
ld a, (de)
and 0xfe
or c
ld (de), a
;source-doc/ufi-drv/./class_ufi.c:136: parameter_list.defect_list_header.immediate = 0;
ld l, e
ld h, d
res 1, (hl)
;source-doc/ufi-drv/./class_ufi.c:137: parameter_list.defect_list_header.reserved2 = 0;
ld c, e
ld b, d
ld a, (bc)
and 0xf3
ld (bc), a
;source-doc/ufi-drv/./class_ufi.c:138: parameter_list.defect_list_header.single_track = 1;
ld l, e
ld h, d
set 4, (hl)
;source-doc/ufi-drv/./class_ufi.c:139: parameter_list.defect_list_header.dcrt = 1;
ld l, e
ld h, d
set 5, (hl)
;source-doc/ufi-drv/./class_ufi.c:140: parameter_list.defect_list_header.extend = 0;
ld l, e
ld h, d
res 6, (hl)
;source-doc/ufi-drv/./class_ufi.c:141: parameter_list.defect_list_header.fov = 1;
ld a, (de)
or 0x80
ld (de), a
;source-doc/ufi-drv/./class_ufi.c:142: parameter_list.defect_list_header.defect_list_length_msb = 0;
ld (ix-22),0x00
;source-doc/ufi-drv/./class_ufi.c:143: parameter_list.defect_list_header.defect_list_length_lsb = 8;
ld (ix-21),0x08
;source-doc/ufi-drv/./class_ufi.c:144: memcpy(&parameter_list.format_descriptor, (void *)format, sizeof(ufi_format_capacity_descriptor));
ld c,(ix+8)
ld b,(ix+9)
ld hl,6
add hl, sp
push hl
push bc
ld hl,0x0008
push hl
call _memcpy_callee
;source-doc/ufi-drv/./class_ufi.c:146: usb_error result = usb_execute_cbi(storage_device, (uint8_t *)&cmd, true, sizeof(parameter_list), (uint8_t *)&parameter_list,
ld hl,0
add hl, sp
push hl
ld hl,4
add hl, sp
push hl
ld hl,0x000c
push hl
ld a,0x01
push af
inc sp
ld hl,21
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:151: RETURN_CHECK(result);
;source-doc/ufi-drv/./class_ufi.c:152: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:154: usb_error ufi_send_diagnostics(device_config *const storage_device) {
; ---------------------------------
; Function ufi_send_diagnostics
; ---------------------------------
_ufi_send_diagnostics:
push ix
ld ix,0
add ix,sp
ld hl, -12
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./class_ufi.c:158: ufi_cmd_send_diagnostic = _ufi_cmd_send_diagnostic;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,0x000c
ld hl,__ufi_cmd_send_diagnostic
ldir
pop bc
;source-doc/ufi-drv/./class_ufi.c:160: result = usb_execute_cbi(storage_device, (uint8_t *)&ufi_cmd_send_diagnostic, true, 0, NULL, NULL);
ld hl,0x0000
push hl
push hl
push hl
ld a,0x01
push af
inc sp
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usb_execute_cbi
ld iy,11
add iy, sp
;source-doc/ufi-drv/./class_ufi.c:162: RETURN_CHECK(result);
;source-doc/ufi-drv/./class_ufi.c:163: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./class_ufi.c:165: uint32_t convert_from_msb_first(const uint8_t *const buffer) {
; ---------------------------------
; Function convert_from_msb_first
; ---------------------------------
_convert_from_msb_first:
push ix
ld ix,0
add ix,sp
push af
push af
;source-doc/ufi-drv/./class_ufi.c:167: uint8_t *p_output = ((uint8_t *)&result);
ld hl,0
add hl, sp
ex de, hl
;source-doc/ufi-drv/./class_ufi.c:168: const uint8_t *p_input = buffer + 3;
ld c,(ix+4)
ld b,(ix+5)
inc bc
inc bc
inc bc
;source-doc/ufi-drv/./class_ufi.c:170: *p_output++ = *p_input--;
ld a, (bc)
dec bc
ld (de), a
inc de
;source-doc/ufi-drv/./class_ufi.c:171: *p_output++ = *p_input--;
ld a, (bc)
dec bc
ld (de), a
inc de
;source-doc/ufi-drv/./class_ufi.c:172: *p_output++ = *p_input--;
ld a, (bc)
dec bc
ld (de), a
inc de
;source-doc/ufi-drv/./class_ufi.c:173: *p_output = *p_input--;
ld a, (bc)
ld (de), a
;source-doc/ufi-drv/./class_ufi.c:175: return result;
pop hl
push hl
ld e,(ix-2)
ld d,(ix-1)
;source-doc/ufi-drv/./class_ufi.c:176: }
ld sp, ix
pop ix
ret

319
Source/HBIOS/ch376-native/ufi-drv/ufi-init.c.s

@ -0,0 +1,319 @@
;
; Generated from source-doc/ufi-drv/./ufi-init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/ufi-drv/./ufi-init.c:11: void chufi_init(void) {
; ---------------------------------
; Function chufi_init
; ---------------------------------
_chufi_init:
push ix
ld ix,0
add ix,sp
push af
;source-doc/ufi-drv/./ufi-init.c:14: do {
ld (ix-1),0x01
l_chufi_init_00105:
;source-doc/ufi-drv/./ufi-init.c:15: device_config_storage *const storage_device = (device_config_storage *)get_usb_device_config(index);
ld a,(ix-1)
call _get_usb_device_config
;source-doc/ufi-drv/./ufi-init.c:17: if (storage_device == NULL)
ld a, d
or e
jr Z,l_chufi_init_00107
;source-doc/ufi-drv/./ufi-init.c:20: const usb_device_type t = storage_device->type;
ld l, e
ld h, d
ld a, (hl)
and 0x0f
;source-doc/ufi-drv/./ufi-init.c:22: if (t == USB_IS_FLOPPY) {
dec a
jr NZ,l_chufi_init_00106
;source-doc/ufi-drv/./ufi-init.c:23: storage_device->drive_index = storage_count++;
ld hl,0x0010
add hl, de
ld a,(_storage_count+0)
ld (ix-2),a
ld c,l
ld b,h
ld hl,_storage_count+0
inc (hl)
ld a,(ix-2)
ld (bc), a
;source-doc/ufi-drv/./ufi-init.c:25: dio_add_entry(ch_ufi_fntbl, storage_device);
ld hl,_ch_ufi_fntbl
call _dio_add_entry
l_chufi_init_00106:
;source-doc/ufi-drv/./ufi-init.c:28: } while (++index != MAX_NUMBER_OF_DEVICES + 1);
inc (ix-1)
ld a,(ix-1)
sub 0x07
jr NZ,l_chufi_init_00105
l_chufi_init_00107:
;source-doc/ufi-drv/./ufi-init.c:30: if (storage_count == 0)
;source-doc/ufi-drv/./ufi-init.c:31: return;
;source-doc/ufi-drv/./ufi-init.c:33: print_device_mounted(" FLOPPY DRIVE$", storage_count);
ld a,(_storage_count+0)
or a
jr Z,l_chufi_init_00110
push af
inc sp
ld hl,ufi_init_str_0
push hl
call _print_device_mounted
pop af
inc sp
l_chufi_init_00110:
;source-doc/ufi-drv/./ufi-init.c:34: }
ld sp, ix
pop ix
ret
ufi_init_str_0:
DEFM " FLOPPY DRIVE$"
DEFB 0x00
;source-doc/ufi-drv/./ufi-init.c:36: uint32_t chufi_get_cap(device_config *const dev) {
; ---------------------------------
; Function chufi_get_cap
; ---------------------------------
_chufi_get_cap:
push ix
ld ix,0
add ix,sp
ld hl, -72
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./ufi-init.c:38: memset(&response, 0, sizeof(ufi_format_capacities_response));
ld hl,0
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x24
push hl
call _memset_callee
;source-doc/ufi-drv/./ufi-init.c:40: wait_for_device_ready(dev, 25);
ld a,0x19
push af
inc sp
ld l,(ix+4)
ld h,(ix+5)
push hl
call _wait_for_device_ready
pop af
inc sp
;source-doc/ufi-drv/./ufi-init.c:44: ufi_inquiry(dev, &inquiry);
ld hl,36
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ufi_inquiry
pop af
;source-doc/ufi-drv/./ufi-init.c:46: wait_for_device_ready(dev, 15);
ld h,0x0f
ex (sp),hl
inc sp
ld l,(ix+4)
ld h,(ix+5)
push hl
call _wait_for_device_ready
pop af
inc sp
;source-doc/ufi-drv/./ufi-init.c:48: const usb_error result = ufi_read_frmt_caps(dev, &response);
ld hl,0
add hl, sp
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ufi_read_frmt_caps
pop af
pop af
ld a, l
;source-doc/ufi-drv/./ufi-init.c:49: if (result != USB_ERR_OK)
or a
jr Z,l_chufi_get_cap_00102
;source-doc/ufi-drv/./ufi-init.c:50: return 0;
ld hl,0x0000
ld e, l
ld d, l
jr l_chufi_get_cap_00103
l_chufi_get_cap_00102:
;source-doc/ufi-drv/./ufi-init.c:53: return convert_from_msb_first(response.descriptors[0].number_of_blocks);
ld hl,4
add hl, sp
push hl
call _convert_from_msb_first
pop af
l_chufi_get_cap_00103:
;source-doc/ufi-drv/./ufi-init.c:63: }
ld sp, ix
pop ix
ret
;source-doc/ufi-drv/./ufi-init.c:65: uint8_t chufi_read(device_config_storage *const dev, uint8_t *const buffer) {
; ---------------------------------
; Function chufi_read
; ---------------------------------
_chufi_read:
push ix
ld ix,0
add ix,sp
ld hl, -20
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./ufi-init.c:67: if (wait_for_device_ready((device_config *)dev, 20) != 0)
ld c,(ix+4)
ld b,(ix+5)
push bc
ld a,0x14
push af
inc sp
push bc
call _wait_for_device_ready
pop af
inc sp
ld a, l
pop bc
or a
jr Z,l_chufi_read_00102
;source-doc/ufi-drv/./ufi-init.c:68: return -1; // Not READY!
ld l,0xff
jp l_chufi_read_00109
l_chufi_read_00102:
;source-doc/ufi-drv/./ufi-init.c:73: memset(&sense_codes, 0, sizeof(sense_codes));
push bc
ld hl,2
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x02
push hl
call _memset_callee
pop bc
;source-doc/ufi-drv/./ufi-init.c:75: if (ufi_read_write_sector((device_config *)dev, false, dev->current_lba, 1, buffer, (uint8_t *)&sense_codes) != USB_ERR_OK)
ld e,(ix+4)
ld d,(ix+5)
ld hl,12
add hl, de
ld e, (hl)
inc hl
ld d, (hl)
push bc
ld hl,2
add hl, sp
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
ld a,0x01
push af
inc sp
push de
xor a
push af
inc sp
push bc
call _ufi_read_write_sector
ld iy,10
add iy, sp
ld sp, iy
ld a, l
pop bc
or a
jr Z,l_chufi_read_00104
;source-doc/ufi-drv/./ufi-init.c:76: return -1; // general error
ld l,0xff
jr l_chufi_read_00109
l_chufi_read_00104:
;source-doc/ufi-drv/./ufi-init.c:79: memset(&response, 0, sizeof(response));
push bc
ld hl,4
add hl, sp
push hl
ld hl,0x0000
push hl
ld l,0x12
push hl
call _memset_callee
pop bc
;source-doc/ufi-drv/./ufi-init.c:81: if ((result = ufi_request_sense((device_config *)dev, &response)) != USB_ERR_OK)
ld hl,2
add hl, sp
push hl
push bc
call _ufi_request_sense
pop af
pop af
ld a, l
or a
jr Z,l_chufi_read_00106
;source-doc/ufi-drv/./ufi-init.c:82: return -1; // error
ld l,0xff
jr l_chufi_read_00109
l_chufi_read_00106:
;source-doc/ufi-drv/./ufi-init.c:86: const uint8_t sense_key = response.sense_key;
ld hl,4
add hl, sp
ld a, (hl)
;source-doc/ufi-drv/./ufi-init.c:88: if (sense_key != 0)
and 0x0f
jr Z,l_chufi_read_00108
;source-doc/ufi-drv/./ufi-init.c:89: return -1;
ld l,0xff
jr l_chufi_read_00109
l_chufi_read_00108:
;source-doc/ufi-drv/./ufi-init.c:91: return USB_ERR_OK;
ld l,0x00
l_chufi_read_00109:
;source-doc/ufi-drv/./ufi-init.c:92: }
ld sp, ix
pop ix
ret

222
Source/HBIOS/ch376-native/ufi-drv/usb_cbi.c.s

@ -0,0 +1,222 @@
;
; Generated from source-doc/ufi-drv/./usb_cbi.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.3.0 #14210 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
_CH376_DATA_PORT .EQU 0xff88
_CH376_COMMAND_PORT .EQU 0xff89
_USB_MODULE_LEDS .EQU 0xff8a
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_cbi2_adsc:
DEFS 8
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/ufi-drv/./usb_cbi.c:9: usb_error usb_execute_cbi(device_config *const storage_device,
; ---------------------------------
; Function usb_execute_cbi
; ---------------------------------
_usb_execute_cbi:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/ufi-drv/./usb_cbi.c:18: const uint8_t interface_number = storage_device->interface_number;
ld l,(ix+4)
ld h,(ix+5)
ld c,l
ld b,h
inc hl
inc hl
ld e, (hl)
;source-doc/ufi-drv/./usb_cbi.c:21: adsc = cbi2_adsc;
push de
push bc
ex de, hl
ld hl,4
add hl, sp
ex de, hl
ld bc,0x0008
ld hl,_cbi2_adsc
ldir
pop bc
pop de
;source-doc/ufi-drv/./usb_cbi.c:22: adsc.bIndex[0] = interface_number;
ld (ix-4),e
;source-doc/ufi-drv/./usb_cbi.c:24: result = usbdev_control_transfer(storage_device, &adsc, (uint8_t *const)cmd);
ld l,(ix+6)
ld h,(ix+7)
push hl
ld hl,2
add hl, sp
push hl
push bc
call _usbdev_control_transfer
pop af
pop af
pop af
ld a, l
;source-doc/ufi-drv/./usb_cbi.c:26: if (result == USB_ERR_STALL) {
cp 0x02
jr NZ,l_usb_execute_cbi_00104
;source-doc/ufi-drv/./usb_cbi.c:27: if (sense_codes != NULL)
ld a,(ix+14)
or (ix+13)
jr Z,l_usb_execute_cbi_00102
;source-doc/ufi-drv/./usb_cbi.c:28: usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN);
ld a,0x02
push af
inc sp
ld hl,0x0002
push hl
ld l,(ix+13)
ld h,(ix+14)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usbdev_dat_in_trnsfer
ld hl,7
add hl, sp
l_usb_execute_cbi_00102:
;source-doc/ufi-drv/./usb_cbi.c:30: return USB_ERR_STALL;
ld l,0x02
jp l_usb_execute_cbi_00118
l_usb_execute_cbi_00104:
;source-doc/ufi-drv/./usb_cbi.c:33: if (result != USB_ERR_OK) {
or a
jr Z,l_usb_execute_cbi_00106
;source-doc/ufi-drv/./usb_cbi.c:35: return result;
ld l, a
jr l_usb_execute_cbi_00118
l_usb_execute_cbi_00106:
;source-doc/ufi-drv/./usb_cbi.c:38: if (send) {
bit 0,(ix+8)
jr Z,l_usb_execute_cbi_00112
;source-doc/ufi-drv/./usb_cbi.c:39: result = usbdev_blk_out_trnsfer(storage_device, buffer, buffer_size);
ld l,(ix+9)
ld h,(ix+10)
push hl
ld l,(ix+11)
ld h,(ix+12)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usbdev_blk_out_trnsfer
pop af
pop af
pop af
;source-doc/ufi-drv/./usb_cbi.c:41: if (result != USB_ERR_OK) {
ld a, l
or a
jr Z,l_usb_execute_cbi_00113
;source-doc/ufi-drv/./usb_cbi.c:43: return result;
jr l_usb_execute_cbi_00118
l_usb_execute_cbi_00112:
;source-doc/ufi-drv/./usb_cbi.c:46: result = usbdev_dat_in_trnsfer(storage_device, buffer, buffer_size, ENDPOINT_BULK_IN);
ld a,0x01
push af
inc sp
ld l,(ix+9)
ld h,(ix+10)
push hl
ld l,(ix+11)
ld h,(ix+12)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usbdev_dat_in_trnsfer
pop af
pop af
pop af
inc sp
;source-doc/ufi-drv/./usb_cbi.c:48: if (result != USB_ERR_OK) {
ld a, l
or a
;source-doc/ufi-drv/./usb_cbi.c:50: return result;
jr NZ,l_usb_execute_cbi_00118
l_usb_execute_cbi_00113:
;source-doc/ufi-drv/./usb_cbi.c:54: if (sense_codes != NULL) {
ld a,(ix+14)
or (ix+13)
jr Z,l_usb_execute_cbi_00117
;source-doc/ufi-drv/./usb_cbi.c:55: result = usbdev_dat_in_trnsfer(storage_device, sense_codes, 2, ENDPOINT_INTERRUPT_IN);
ld a,0x02
push af
inc sp
ld hl,0x0002
push hl
ld l,(ix+13)
ld h,(ix+14)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _usbdev_dat_in_trnsfer
pop af
pop af
pop af
inc sp
;source-doc/ufi-drv/./usb_cbi.c:57: if (result != USB_ERR_OK) {
ld a, l
or a
;source-doc/ufi-drv/./usb_cbi.c:59: return result;
jr NZ,l_usb_execute_cbi_00118
l_usb_execute_cbi_00117:
;source-doc/ufi-drv/./usb_cbi.c:63: return USB_ERR_OK;
ld l,0x00
l_usb_execute_cbi_00118:
;source-doc/ufi-drv/./usb_cbi.c:64: }
ld sp, ix
pop ix
ret
_cbi2_adsc:
DEFB +0x21
DEFB +0x00
DEFB +0x00
DEFB +0x00
DEFB +0xff
DEFB +0x00
DEFW +0x000c

48
Source/HBIOS/ch376.asm

@ -0,0 +1,48 @@
;
;==================================================================================================
; CH376 NATIVE USB DRIVER
;==================================================================================================
;
#DEFINE DEFM .DB
#DEFINE DEFB .DB
#DEFINE DEFW .DW
_print_string .EQU PRTSTR
_print_hex:
ld a, l
JP PRTHEXBYTE
_delay:
push af
call DELAY
call DELAY
call DELAY
call DELAY
pop af
ret
_delay_20ms:
LD DE, 1250
JP VDELAY
;
; DELAY approx 60ms
_delay_short:
LD DE, 3750
JP VDELAY
;
; DELAY approx 1/2 second
_delay_medium .EQU LDELAY
_dio_add_entry:
LD B, H
LD C, L
JP DIO_ADDENT ; ADD ENTRY TO GLOBAL DISK DEV TABLE
#include "./ch376-native/base-drv.asm"
#include "./ch376-native/print.asm"
#include "./ch376-native/cruntime.asm"
#include "./ch376-native/base-drv.s"
CHNATIVE_INIT .EQU _chnative_init

284
Source/HBIOS/ch376scsi.asm

@ -0,0 +1,284 @@
;
;==================================================================================================
; CH376 NATIVE MASS STORAGE DRIVER
;==================================================================================================
;
#include "./ch376-native/scsi-drv.s"
; find and mount all Mass Storage USB devices
CHSCSI_INIT .EQU _chscsi_init
; DRIVER FUNCTION TABLE
;
_ch_scsi_fntbl
CH_SCSI_FNTBL:
.DW CH_SCSI_STATUS
.DW CH_SCSI_RESET
.DW CH_SCSI_SEEK
.DW CH_SCSI_READ
.DW CH_SCSI_WRITE
.DW CH_SCSI_VERIFY
.DW CH_SCSI_FORMAT
.DW CH_SCSI_DEVICE
.DW CH_SCSI_MEDIA
.DW CH_SCSI_DEFMED
.DW CH_SCSI_CAP
.DW CH_SCSI_GEOM
#IF (($ - CH_SCSI_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID CH_SCSI_FNTBL FUNCTION TABLE ***\n"
#ENDIF
CH_SCSI_STATUS:
LD A, (IY)
XOR A
RET
CH_SCSI_RESET:
LD A, (IY)
XOR A
RET
; ### Function 0x12 -- Disk Seek (DIOSEEK)
;
; Inputs:
; IY: device config pointer
; DEHL: Sector Address
;
; Outputs:
; A: Status
;
; This function will set the desired sector to be used for the next I/O
; operation. The returned Status (A) is a standard HBIOS result code.
;
; The double-word Sector Address (DEHL) can represent either a Logical
; Block Address (LBA) or a Cylinder/Head/Sector (CHS). Bit 7 of D is
; set (1) for LBA mode and cleared (0) for CHS mode.
;
; For LBA mode operation, the high bit is set and the rest of the
; double-word is then treated as the logical sector address.
;
; For CHS mode operation, the Sector Address (DEHL) registers are
; interpreted as: D=Head, E=Sector, and HL=Track. All values (including
; sector) are 0 relative.
;
CH_SCSI_SEEK:
BIT 7,D ; CHECK FOR LBA FLAG
CALL Z,HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA
RES 7,D ; CLEAR FLAG REGARDLESS (DOES NO HARM IF ALREADY LBA)
EX DE, HL
push IY
CALL _chnative_seek
RET
;
; ### Function 0x13 -- Disk Read (DIOREAD)
;
; Inputs
; IY: device config pointer
; D: Buffer Bank ID
; E: Sector Count
; HL: Buffer Address
;
; Outputs
; A: Status
; E: Sectors Read
;
; Read Sector Count (E) sectors into the buffer located in Buffer Bank ID (D)
; at Buffer Address (HL) starting at the Current Sector. The returned
; Status (A) is a standard HBIOS result code.
;
CH_SCSI_READ:
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR
; call scsi_read(IY, HL);
; HL = HL + 512
push hl
push iy
call _scsi_read
ld a, l
pop hl
pop iy
ld bc, 512
add hl, bc
ret
;
; ### Function 0x14 -- Disk Write (DIOWRITE)
;
; Inputs
; IY: device config pointer
; D: Buffer Bank ID
; E: Sector Count
; HL: Buffer Address
;
; Outputs
; A: Status
; E: Sectors Written
;
; Write Sector Count (E) sectors from the buffer located in Buffer Bank ID (D)
; at Buffer Address (HL) starting at the Current Sector. The returned
; Status (A) is a standard HBIOS result code.
;
CH_SCSI_WRITE:
CALL HB_DSKWRITE ; HOOK HBIOS DISK WRITE SUPERVISOR
; call scsi_write(IY, HL);
; HL = HL + 512
push hl
push iy
call _scsi_write
ld a, l
pop hl
pop iy
ld bc, 512
add hl, bc
ret
CH_SCSI_VERIFY:
CH_SCSI_FORMAT:
LD A, $FF
OR A
RET
;
; ### Function 0x17 -- Disk Device (DIODEVICE)
;
; Inputs
; IY: device config pointer
;
; Outputs
; A: Status
; C: Device Attributes
; D: Device Type (DIODEV_USB)
; E: Device Number (1)
; H: Device Unit Mode (0)
; L: Device I/O Base Address
;
; Reports device information. The Status (A) is a standard
; HBIOS result code.
;
; The Device Attribute (C):
;
; | **Bits** | **Definition** |
; |---------:|--------------------------------------------------|
; | 7 | Floppy |
; | 6 | Removable |
; | 5 | High Capacity (>8 MB) |
;
; Low Capacity Devices??
;
; | **Bits** | **Definition** |
; |---------:|--------------------------------------------------|
; | 4-3 | Form Factor: 0=8", 1=5.25", 2=3.5", 3=Other |
; | 2 | Sides: 0=SS, 1=DS |
; | 1-0 | Density: 0=SD, 1=DD, 2=HD, 3=ED |
;
; High Capacity Devices
;
; | **Bits** | **Definition** |
; |---------:|--------------------------------------------------|
; | 4 | LBA Capable |
; | 3-0 | Media Type: 0=Hard Disk, 1=CF, 2=SD, 3=USB, |
; | | 4=ROM, 5=RAM, 6=RAMF, 7=FLASH, 8=CD-ROM, |
; | | 9=Cartridge, 10=usb-scsi, 11=usb-ufi |
;
CH_SCSI_DEVICE:
LD C, %01111010 ; TODO?
LD D, DIODEV_USB
LD E, (iy+16)
LD H, 0
LD L, 0
XOR A
RET
;
; ### Function 0x18 -- Disk Media (DIOMEDIA)
;
; Inputs
; IY: device config pointer
; E: Flags
;
; Outputs
; A: Status
; E: Media ID
;
; Report the Media ID (E) for the for media. If bit 0 of Flags (E) is set,
; then media discovery or verification will be performed. The Status
; (A) is a standard HBIOS result code. If there is no media in device,
; function will return an error status.
;
CH_SCSI_MEDIA:
LD E, MID_HD ;todo verify device still active?
XOR A
RET
CH_SCSI_DEFMED:
LD A, $FF
OR A
RET
;
; ### Function 0x1A -- Disk Capacity (DIOCAPACITY)
;
; Inputs
; IY: device config pointer
;
; Outputs
; A: Status
; DEHL: Sector Count
; BC: Block Size
;
;
; Report the current media capacity information.
;
;
CH_SCSI_CAP:
push ix
ld ix, -8 ; reserve 8 bytes for
add ix, sp ; scsi_read_capacity_result
ld sp, ix
push ix
push iy
call _get_scsi_read_capacity
pop iy
pop ix
ld d, (ix) ; response.number_of_blocks[0]
ld e, (ix+1) ; response.number_of_blocks[1]
ld h, (ix+2) ; response.number_of_blocks[2]
ld l, (ix+3) ; response.number_of_blocks[3]
ld b, (ix+6) ; response.block_size[2]
ld c, (ix+7) ; response.block_size[3]
ld ix, 8
add ix, sp
ld sp, ix
pop ix
xor a ; todo determine a drive status
ret
;
; ### Function 0x1B -- Disk Geometry (DIOGEOMETRY)
;
; Inputs
; IY: device config pointer
;
; Outputs
; A: Status
; D: Heads
; E: Sectors
; HL: Cylinder Count
; BC: Block Size
;
; Report the simulated geometry for the media. The Status (A) is a
; standard HBIOS result code. If the media is unknown, an error will be returned.
;
; ** Does not appear to be used??
;
CH_SCSI_GEOM:
; FOR LBA, WE SIMULATE CHS ACCESS USING 16 HEADS AND 16 SECTORS
; RETURN HS:CC -> DE:HL, SET HIGH BIT OF D TO INDICATE LBA CAPABLE
CALL CH_SCSI_CAP ; GET TOTAL BLOCKS IN DE:HL, BLOCK SIZE TO BC
LD L,H ; DIVIDE BY 256 FOR # TRACKS
LD H,E ; ... HIGH BYTE DISCARDED, RESULT IN HL
LD D,16 | $80 ; HEADS / CYL = 16, SET LBA CAPABILITY BIT
LD E,16 ; SECTORS / TRACK = 16
RET ; DONE, A STILL HAS CHUSB_CAP STATUS

225
Source/HBIOS/ch376ufi.asm

@ -0,0 +1,225 @@
;
;==================================================================================================
; CH376 NATIVE MASS STORAGE DRIVER
;==================================================================================================
;
#include "./ch376-native/ufi-drv.s"
; find and mount all floppy USB drives
CHUFI_INIT .EQU _chufi_init
; DRIVER FUNCTION TABLE
;
_ch_ufi_fntbl
CH_UFI_FNTBL:
.DW CH_UFI_STATUS
.DW CH_UFI_RESET
.DW CH_UFI_SEEK
.DW CH_UFI_READ
.DW CH_UFI_WRITE
.DW CH_UFI_VERIFY
.DW CH_UFI_FORMAT
.DW CH_UFI_DEVICE
.DW CH_UFI_MEDIA
.DW CH_UFI_DEFMED
.DW CH_UFI_CAP
.DW CH_UFI_GEOM
#IF (($ - CH_UFI_FNTBL) != (DIO_FNCNT * 2))
.ECHO "*** INVALID CH_UFI_FNTBL FUNCTION TABLE ***\n"
#ENDIF
CH_UFI_STATUS:
LD A, (IY)
XOR A
RET
CH_UFI_RESET:
LD A, (IY)
XOR A
RET
; ### Function 0x12 -- Disk Seek (DIOSEEK)
;
; Inputs:
; IY: device config pointer
; DEHL: Sector Address
;
; Outputs:
; A: Status
;
; This function will set the desired sector to be used for the next I/O
; operation. The returned Status (A) is a standard HBIOS result code.
;if
; The double-word Sector Address (DEHL) can represent either a Logical
; Block Address (LBA) or a Cylinder/Head/Sector (CHS). Bit 7 of D is
; set (1) for LBA mode and cleared (0) for CHS mode.
;
; For LBA mode operation, the high bit is set and the rest of the
; double-word is then treated as the logical sector address.
;
; For CHS mode operation, the Sector Address (DEHL) registers are
; interpreted as: D=Head, E=Sector, and HL=Track. All values (including
; sector) are 0 relative.
;
CH_UFI_SEEK:
BIT 7, D ; CHECK FOR LBA FLAG
CALL Z, HB_CHS2LBA ; CLEAR MEANS CHS, CONVERT TO LBA - never seems to happen?
RES 7, D
EX DE, HL
push IY
CALL _chnative_seek
RET
;
; ### Function 0x13 -- Disk Read (DIOREAD)
;
; Inputs
; IY: device config pointer
; D: Buffer Bank ID
; E: Sector Count
; HL: Buffer Address
;
; Outputs
; A: Status
; E: Sectors Read
;
; Read Sector Count (E) sectors into the buffer located in Buffer Bank ID (D)
; at Buffer Address (HL) starting at the Current Sector. The returned
; Status (A) is a standard HBIOS result code.
;
CH_UFI_READ:
CALL HB_DSKREAD ; HOOK HBIOS DISK READ SUPERVISOR
push hl
push iy
call _chufi_read
ld l, 0
ld a, l
pop iy
pop hl
ld bc, 512
add hl, bc
ret
CH_UFI_WRITE:
EZ80_UTIL_DEBUG
XOR A
RET
CH_UFI_VERIFY:
CH_UFI_FORMAT:
LD HL, 0
LD DE, 0
LD BC, 0
LD A, $FF
OR A
RET
; ### Function 0x17 -- Disk Device (DIODEVICE)
;
; Inputs
; IY: device config pointer
;
; Outputs
; A: Status
; C: Device Attributes
; D: Device Type (DIODEV_USB)
; E: Device Number (1)
; H: Device Unit Mode (0)
; L: Device I/O Base Address
;
; Reports device information. The Status (A) is a standard
; HBIOS result code.
;
; The Device Attribute (C):
;
; | **Bits** | **Definition** |
; |---------:|--------------------------------------------------|
; | 7 | Floppy |
; | 6 | Removable |
; | 5 | High Capacity (>8 MB) |
;
; Low Capacity Devices??
;
; | **Bits** | **Definition** |
; |---------:|--------------------------------------------------|
; | 4-3 | Form Factor: 0=8", 1=5.25", 2=3.5", 3=Other |
; | 2 | Sides: 0=SS, 1=DS |
; | 1-0 | Density: 0=SD, 1=DD, 2=HD, 3=ED |
;
; High Capacity Devices
;
; | **Bits** | **Definition** |
; |---------:|--------------------------------------------------|
; | 4 | LBA Capable |
; | 3-0 | Media Type: 0=Hard Disk, 1=CF, 2=SD, 3=USB, |
; | | 4=ROM, 5=RAM, 6=RAMF, 7=FLASH, 8=CD-ROM, |
; | | 9=Cartridge, 10=usb-scsi, 11=usb-ufi |
;
CH_UFI_DEVICE:
LD C, %01011011
LD D, DIODEV_USB
LD E, (iy+16)
LD H, 0
LD L, 0
XOR A
RET
;
; ### Function 0x18 -- Disk Media (DIOMEDIA)
;
; Inputs
; IY: device config pointer
; E: Flags
;
; Outputs
; A: Status
; E: Media ID
;
; Report the Media ID (E) for the for media. If bit 0 of Flags (E) is set,
; then media discovery or verification will be performed. The Status
; (A) is a standard HBIOS result code. If there is no media in device,
; function will return an error status.
;
CH_UFI_MEDIA:
LD E, MID_MDRAM ;todo verify device still active?
XOR A
RET
CH_UFI_DEFMED:
LD HL, 0
LD DE, 0
LD BC, 0
LD A, $FF
OR A
RET
;
; ### Function 0x1A -- Disk Capacity (DIOCAPACITY)
;
; Inputs
; IY: device config pointer
;
; Outputs
; A: Status
; DEHL: Sector Count
; BC: Block Size
;
;
; Report the current media capacity information.
;
CH_UFI_CAP:
push iy
call _chufi_get_cap
pop iy
ld bc, 512
xor a
ret
CH_UFI_GEOM:
LD HL, 0
LD DE, 0
LD BC, 0
LD A, $FF
OR A
RET

40
Source/HBIOS/hbios.asm

@ -4165,6 +4165,15 @@ HB_INITTBL:
#IF (ESPENABLE)
.DW ESP_INIT
#ENDIF
#IF (CHNATIVEENABLE)
.DW CHNATIVE_INIT
#ENDIF
#IF (CHSCSIENABLE)
.DW CHSCSI_INIT
#ENDIF
#IF (CHUFIENABLE)
.DW CHUFI_INIT
#ENDIF
;
HB_INITTBLLEN .EQU (($ - HB_INITTBL) / 2)
;
@ -7045,6 +7054,7 @@ HB_BADINTCNT .DB 0
CALL NEWLINE
;CALL CONTINUE
OR $FF ; SIGNAL INTERRUPT HANDLED
EZ80_UTIL_DEBUG
RET
;
;--------------------------------------------------------------------------------------------------
@ -8776,6 +8786,7 @@ PS_DDIMM .TEXT "IMM$"
PS_DDSYQ .TEXT "SYQ$"
PS_DDCHUSB .TEXT "CHUSB$"
PS_DDCHSD .TEXT "CHSD$"
PS_DDCHNATUSB .TEXT "USB$"
;
; DISK TYPE STRINGS
;
@ -8790,7 +8801,10 @@ PS_DTFSH .TEXT "Flash ROM$"
PS_DTRF .TEXT "RAM Floppy$"
PS_DTCD .TEXT "CD-ROM$"
PS_DTCRT .TEXT "Cartridge$"
PS_DTOUSBSCI .TEXT "SCSI$"
PS_DTOUSBUFI .TEXT "UFI$"
PS_DTOTHER .TEXT "???$"
;
; FLOPPY ATTRIBUTE STRINGS
;
@ -9446,6 +9460,32 @@ SIZ_YM2612 .EQU $ - ORG_YM2612
MEMECHO " bytes.\n"
#ENDIF
;
#IF (CHNATIVEENABLE)
ORG_CHNATIVE .EQU $
#INCLUDE "ch376.asm"
SIZ_CHNATIVE .EQU $ - ORG_CHNATIVE
MEMECHO "CH376 Native occupies "
MEMECHO SIZ_CHNATIVE
MEMECHO " bytes.\n"
#ENDIF
;
#IF (CHSCSIENABLE)
ORG_CHSCSI .EQU $
#INCLUDE "ch376scsi.asm"
SIZ_CHSCSI .EQU $ - ORG_CHSCSI
MEMECHO "CH376 SCSI Mass Storage occupies "
MEMECHO SIZ_CHSCSI
MEMECHO " bytes.\n"
#ENDIF
;
#IF (CHUFIENABLE)
ORG_CHUFI .EQU $
#INCLUDE "ch376ufi.asm"
SIZ_CHUFI .EQU $ - ORG_CHUFI
MEMECHO "CH376 UFI Floppy Storage occupies "
MEMECHO SIZ_CHUFI
MEMECHO " bytes.\n"
#ENDIF
;
#IF (CPUFAM == CPU_EZ80)
MEMECHO "EZ80 DRIVERS\n"

1
Source/HBIOS/hbios.inc

@ -420,6 +420,7 @@ DIODEV_IMM .EQU $0B
DIODEV_SYQ .EQU $0C
DIODEV_CHUSB .EQU $0D
DIODEV_CHSD .EQU $0E
DIODEV_USB .EQU $0F
;
; RTC DEVICE IDS
;

Loading…
Cancel
Save