Compare commits

...

133 Commits

Author SHA1 Message Date
Wayne Warthen
a68ae0cd24 Minor Documentation Updates 2025-07-29 13:21:47 -07:00
Wayne Warthen
45ac5cb3be Merge pull request #603 from mggates39/dev/BoatFest_Talk
Add Sample Hello World Source Code
2025-07-29 10:54:10 -07:00
Marshall G. Gates
21f7dfc4fb Renamed demo_dev combo to example 2025-07-28 21:43:20 -04:00
Marshall G. Gates
d92fb77f11 Added a development combo disk defintion 2025-07-28 20:26:08 -04:00
Marshall G. Gates
4006bc0224 Added Cobol to the Readme 2025-07-28 20:25:40 -04:00
Marshall G. Gates
0d5681d2db Merge branch 'master' into dev/BoatFest_Talk 2025-07-28 20:16:03 -04:00
Wayne Warthen
ab9e6d662d Note Terminology Follow-up, Issue #595
Attempting to straighten out the use of "tone" vs. "note".  I'm sure this isn't perfect, but hopefully better.
2025-07-22 16:09:19 -07:00
Wayne Warthen
4fa7bf0117 Note Terminology Follow-up, Issue #595
Trying to ferret out the last instances of quarter-note being used instead of eighth-note.

The comments in `audio.inc` are now confusing, but I don't know how to fix them...
2025-07-22 11:42:39 -07:00
Wayne Warthen
14a9f51efe Merge pull request #602 from wdl1908/master
Include BASEIMGS in dependency tracking
2025-07-22 11:29:34 -07:00
Willy De la Court
a052b145fe Include BASEIMGS in dependency tracking to generate images that have no *.txt to define the content 2025-07-22 17:15:56 +02:00
Wayne Warthen
1d7b0d970f USB Floppy I/O Return Flags, Issue #456 2025-07-21 17:50:20 -07:00
Wayne Warthen
ddeb6ce48b Merge pull request #601 from dinoboards/dean/ch376-cleanup-port-labels
ch376-native: moved secondary IO port labels from master to ch376.asm
2025-07-21 16:38:41 -07:00
Dean Netherton
b6598cdcc6 ch376-native: moved secondary IO port labels from master to ch376.asm 2025-07-22 09:07:08 +10:00
Wayne Warthen
74f9daaaaa USB Floppy Geometry Fix, Issue #456
USB Floppy Driver modified to:

- return media id for 1.44 MB Floppy (MID_FD144)
- translate CHS to LBA

At present, floppy media is assumed to be high density 1.44MB.
2025-07-21 11:19:42 -07:00
Wayne Warthen
dddffac68f Merge pull request #600 from dinoboards/dean-ch376-include-ports-in-boot
ch376-native: output the configured port numbers for the ch376 driver
2025-07-21 10:16:18 -07:00
Dean Netherton
f03c68c016 ch376-native: output the configured port numbers for the ch376 native usb driver 2025-07-21 19:23:26 +10:00
Wayne Warthen
8c629c637d Improve Custom Hard Disk Image Doc, Issue #597 2025-07-20 17:30:58 -07:00
Wayne Warthen
2dba16c62d Fix ASSIGN for Multiple Floppy Drivers
ASSIGN was assuming that the "FD" floppy driver was the only floppy driver.  This change properly recognizes any driver that indicates it is a floppy driver.
2025-07-20 16:59:46 -07:00
Wayne Warthen
90bb60d423 Fix CBIOS for Multiple Floppy Drivers
CBIOS was assuming that the "FD" floppy driver was the only floppy driver.  This change properly recognizes any driver that indicates it is a floppy driver.
2025-07-20 16:40:08 -07:00
Wayne Warthen
52bf7a56e3 Improve Custom Hard Disk Image Doc, Issue #597 2025-07-20 13:14:48 -07:00
Wayne Warthen
0a0f2f8a4b Merge pull request #598 from dinoboards/dean-ch376-fix-for-windows-pr
ch376-native: fixes for windows build
2025-07-20 11:21:07 -07:00
Dean Netherton
aacf98a82a ch376-native: fixes for windows build
* convert 0x??? hex literals to $??? literals
* More label shortening for windows tasm compatibility
2025-07-20 15:32:08 +10:00
Wayne Warthen
42385fd120 Fix OS Boot on Native USB, Issue #456
Minor change to ch376scsi.asm resolves an issue that caused multi-sector I/O to fail.
2025-07-19 18:20:01 -07:00
Wayne Warthen
d754e475c2 Note Terminology Follow-up, Issue #595
- The SystemGuide.md file was omitted in the last commit.
- Corrected terminology in the comments of the sound drivers.
2025-07-19 16:10:31 -07:00
Wayne Warthen
a75dada16e Correct Note Terminology, Issue #595
Modified System Guide to refer to Eighth Notes instead of Quarter Notes per guidance in associated issue.
2025-07-19 15:58:45 -07:00
Wayne Warthen
e5a98ec501 Minor Follow-up to Native USB Support, Issue #456
- Update device mask in ASSIGN application
- Update doc to credit @dinoboards
2025-07-19 11:51:50 -07:00
Wayne Warthen
0a8b4355c9 Merge pull request #596 from dinoboards/dean-include-usb-for-assign
ch376-native: extended assign to support new device type usb
2025-07-19 07:08:14 -07:00
Dean Netherton
bd6e374d72 ch376-native: extended assign to support new device type usb 2025-07-19 10:22:06 +10:00
Wayne Warthen
e4c5f1e1f8 Native USB Support Follow-up, Issue #456
- Regen documentation
- .EQU -> .SET in cfg_RCEZ80
- Bump version
2025-07-18 16:14:30 -07:00
Wayne Warthen
a29c6f35c7 Merge pull request #592 from dinoboards/dean-ch376-usb-native-8
CH376 Native USB Driver
2025-07-18 15:15:16 -07:00
Wayne Warthen
c5da5b60a8 Minimal Doc of Revised Disk Image Creation Process 2025-07-18 14:35:25 -07:00
Wayne Warthen
8a5f9eed2d Fix Speaker Functionality on Specific Platforms 2025-07-18 11:20:30 -07:00
Wayne Warthen
5a70c0bd38 Fix Images Makefile for MacOS Compatibility (again) 2025-07-17 16:51:47 -07:00
Wayne Warthen
edfb568c82 Fix Images Makefile for MacOS Compatibility (again) 2025-07-17 16:04:26 -07:00
Wayne Warthen
d35207c7a8 Fix Images Makefile for MacOS Compatibility 2025-07-17 15:20:54 -07:00
Wayne Warthen
347223fa02 Image Creation Refinements, Issue #576
- Determine slice images to create dynamically based on the hd_xxx.txt and fd_xxx.txt files.
- Add a volume label directive to the hd_xxx.txt and fd_xxx.txt files.
- Add a system image directive to the hd_xxx.txt and fd_xxx.txt files.
2025-07-17 14:53:23 -07:00
Wayne Warthen
d259411e72 Merge pull request #594 from kiwisincebirth/map/doc-classic
Replaced "Legacy" (disk layout) with "Classic"
2025-07-17 14:32:35 -07:00
Mark Pruden
2bb559d29a Replaced "Legacy" (disk layout) with "Classic" 2025-07-16 16:33:37 +10:00
Wayne Warthen
5855dafac6 Merge pull request #593 from kiwisincebirth/map/slabel-fix
MartinR-UK Fixed formatting issue with SLABEL where Slice # < 10
2025-07-15 19:28:16 -07:00
Mark Pruden
b4fe4dc7e9 MartinR-UK Fixed formatting issue with SLABEL where Slice # < 10 2025-07-16 11:34:32 +10:00
Dean Netherton
2269142a04 ch376-native: moved port definition from C code to cfg_MASTER.asm 2025-07-15 11:53:55 +10:00
Dean Netherton
ae3cd27579 Merge branch 'master' into dean-ch376-usb-native-8 2025-07-15 11:32:43 +10:00
Dean Netherton
7dbe9a5abb ch376-native: updated readme notes and adjusted config for Z80 and eZ80 to not by default, enable the USB drivers 2025-07-15 11:08:41 +10:00
Dean Netherton
1a955efee6 ch376-native: updated cbios to allow for upto 32 device types returned from DIODEVICE HBIOS query 2025-07-15 10:57:36 +10:00
Wayne Warthen
67b89d2a9c Merge pull request #590 from wdl1908/master
Make sure the images in *.def files are build as dependencies
2025-07-10 12:53:27 -07:00
Willy De la Court
7d72d8c347 rename VAR and not sure why but order is important 2025-07-10 21:01:53 +02:00
wdl1908
8475f29e43 Merge branch 'wwarthen:master' into master 2025-07-10 20:19:43 +02:00
Willy De la Court
7f64871014 Use TEMP2 as variable to not create conflict with previous use of TEMP 2025-07-10 20:19:06 +02:00
Wayne Warthen
1ef10c3c14 Fix MacOS Build, Issue #576 2025-07-10 10:39:00 -07:00
Willy De la Court
9f15687b03 Make sure the images in *.def files are build as dependencies 2025-07-10 19:37:10 +02:00
Wayne Warthen
e696dc6c19 Merge pull request #588 from kiwisincebirth/map/infocom1
Final contribution to Infocom documentation
2025-07-09 19:59:12 -07:00
Wayne Warthen
c8014d1947 User Defined Aggregate Disk Images, #576
Initial round of work on user defined aggregate disk images.
2025-07-09 19:37:59 -07:00
Mark Pruden
801ee17487 Some documentation improvements 2025-07-09 16:01:48 +10:00
Wayne Warthen
0a35539d1c Bump Version, Minor Doc Updates
- Update Layout.txt file.
- Add Cowgol Compiler Manual from @Laci1953

Co-Authored-By: ladislau szilagyi <87603175+Laci1953@users.noreply.github.com>
2025-07-08 13:37:56 -07:00
Wayne Warthen
43680193a9 Merge pull request #586 from mabartibin/speaker-refactor
Speaker refactor
2025-07-08 12:59:47 -07:00
Wayne Warthen
7accbc4981 Merge pull request #585 from kiwisincebirth/map/infocom1
Added Infocom Disk Image
2025-07-08 12:55:00 -07:00
Martin Giese
9689034523 removed most references to RTC, adjusted comments 2025-07-08 21:31:39 +02:00
Martin Giese
af3401ac5b 1 bit speaker code refecatored to arbitrary ports and masks 2025-07-08 21:24:38 +02:00
Mark Pruden
b50913e4c3 Finalised the Game Documentation 2025-07-08 12:05:14 +10:00
Mark Pruden
f99afc3d37 Added all the COM Files 2025-07-07 21:22:00 +10:00
Mark Pruden
744736fa23 Minor changes to the documentation, renamed 2 game files 2025-07-07 14:07:39 +10:00
Mark Pruden
84770dc29a Added Infocom Disk Image 2025-07-07 08:17:11 +10:00
Wayne Warthen
cebeee1157 HBIOS Warm Start Cleanup, See Issue #579
- @kiwisincebirth noticed some duplicative code in HBIOS related to warm starts.  This has been refactored.
- A start mode code is now passed from HBIOS to RomLdr to indicate a warm or cold start.  Device inventory now uses this code to display only on cold start.
2025-07-02 13:52:41 -07:00
Wayne Warthen
f6b083d835 Merge pull request #583 from kiwisincebirth/map/trivial
Trivial (Non-Functional) Changes
2025-07-02 13:35:25 -07:00
Mark Pruden
71abbfb8fc Trivial (Non-Functional) Changes 2025-07-02 12:21:43 +10:00
Wayne Warthen
0932a43fe7 Update invntdev.asm
Very minor optimization.
2025-07-01 15:54:40 -07:00
Wayne Warthen
58b016d173 Merge pull request #582 from kiwisincebirth/map/hbios-inv-dev
Move Device Inventory function from HBIOS to Rom App
2025-07-01 13:44:36 -07:00
Mark Pruden
c884571384 Log Message Fix 2025-07-01 11:16:29 +10:00
Mark Pruden
cfaa2b39c1 Merge branch 'master' into map/hbios-inv-dev 2025-07-01 10:57:44 +10:00
Mark Pruden
a68467150e Moved Device Inventory from HBIOS into a stanalone Rom App 2025-07-01 10:54:47 +10:00
Dean Netherton
75c9a4e482 Merge branch 'master' into dean-ch376-usb-native-8 2025-06-24 08:20:43 +10:00
Dean Netherton
d83ed6f774 Merge branch 'dean/ez80-timing-fixes' into dean-ch376-usb-native-8 2025-06-21 13:57:13 +10:00
Dean Netherton
100b2fc46e ch376-native: revert non-related changes applied to RCEZ80 config files 2025-06-21 13:42:01 +10:00
Dean Netherton
53d2f3f57b ch376-native: fixed issue with firmware delegation version (CHNATIVEEZ80) intermittenly failing 2025-06-21 13:37:10 +10:00
Dean Netherton
024074b2cf ch376-native: fixed issue where keyboard int handler could cause corruption of io 2025-06-21 13:37:09 +10:00
Dean Netherton
4436209213 ch376-native: fixed issue with parsing configs containing HID configs (keyboards/mice) 2025-06-21 13:35:37 +10:00
Dean Netherton
c8a551a781 ch376-native: removed some dead code 2025-06-21 13:35:37 +10:00
Dean Netherton
e0d385af38 ch376-native: boot report now indicates if firmware or RomWBW version of driver is running 2025-06-21 13:35:37 +10:00
Dean Netherton
135641d66c ch376-native:updated master and ez80 configs - defaults to off at master, and on for ez80 2025-06-21 13:35:37 +10:00
Dean Netherton
f63ef6ba04 ch376-native: enabled ez80 firmware version for the usb drivers 2025-06-21 13:35:37 +10:00
Dean Netherton
b62b8639a6 ch376-native: updated keyboard driver
1. fix handling of caps-lock
2. removed support for returning scancode/bitfields for hbios call
2025-06-21 13:35:36 +10:00
Dean Netherton
253b92377d ch376-native: reverted usb keyboard extensions 2025-06-21 13:34:20 +10:00
Dean Netherton
b006343740 ch376-native: implemented ez80 delegated version of ufi driver 2025-06-21 13:34:20 +10:00
Dean Netherton
f0133d1b1b ch376-native: ufi driver refactor - removed use of bit fields to ensure compatibility with other c compilers 2025-06-21 13:34:20 +10:00
Dean Netherton
d1722923fd ch376-native: added new config CHNATIVEEZ80 to enable use of ez80's firmware version of usb support 2025-06-21 13:34:20 +10:00
Dean Netherton
242c004749 ch376-native: keyboard: cleaner separation of concerns 2025-06-21 13:34:20 +10:00
Dean Netherton
e24860f474 ch376-native: minor code cleanup 2025-06-21 13:34:20 +10:00
Dean Netherton
ecb95cc161 ch376-native: refactor clear separation of driver and usb functions 2025-06-21 13:34:19 +10:00
Dean Netherton
4e23c9104d ch376-native: refactor usb scsi/ufi function to replace use of config* with dev_index int 2025-06-21 13:34:19 +10:00
Dean Netherton
179abe7087 ch376-native: refactor: separating driver state and hbios state 2025-06-21 13:34:19 +10:00
Dean Netherton
2b5a224a4f ch376-native: refactor: moved drive index tracking logic out of drivers into usb framework 2025-06-21 13:34:19 +10:00
Dean Netherton
c350d153da ch376-native: optimised calling convention for usb_init 2025-06-21 13:34:19 +10:00
Dean Netherton
347b7e6a06 ch376-native: refactor: extracted chnative_init to its own file 2025-06-21 13:34:19 +10:00
Dean Netherton
802c1b41ff ch376-native: refactored usb init/enumerating 2025-06-21 13:34:19 +10:00
Dean Netherton
7e8560f9a9 ch376-native: fixed issue with enumerating devices with interfaces containing no endpoints 2025-06-21 13:34:19 +10:00
Dean Netherton
580d7761e1 ch376-native: cleaned up formatting for ch376inc.h 2025-06-21 13:34:19 +10:00
Dean Netherton
149ab3ca8a ch376-native: bumped to version 3.5.1-rc.0+ch376native 2025-06-21 13:34:17 +10:00
Dean Netherton
b7234d339a ch376-native: fixed usb scsi/ufi issue with reading/writing more than 512 bytes in one invocation 2025-06-21 13:33:18 +10:00
Dean Netherton
9abba42df7 ch376-native: keyboard int handler optimisations 2025-06-21 13:33:18 +10:00
Dean Netherton
22c26dba36 ch376-native: UKY_STATE: usb extension returns a 'buffered' hid report (upto 8) 2025-06-21 13:33:18 +10:00
Dean Netherton
7e9c08993d ch376-native: UKY_STAT extended to also return current USB key report 2025-06-21 13:33:18 +10:00
Dean Netherton
3f6fc215e9 ch376-native: UKY_READ fixed issue with incorrect H value when no characters in buffer 2025-06-21 13:33:18 +10:00
Dean Netherton
62d5a7b825 ch376-native: leds default to off and on during activity 2025-06-21 13:33:18 +10:00
Dean Netherton
2b1d703c4e ch376-native: further reduce some of the hardcoded delay for i/o operations 2025-06-21 13:33:18 +10:00
Dean Netherton
b98c506baf ch376-native: reduce some of the hardcoded delay for i/o operations 2025-06-21 13:33:18 +10:00
Dean Netherton
60cf40f0b8 ez80: EZ80_MEM_MIN_WS adjusted from 0 to 1 2025-06-21 13:33:18 +10:00
Dean Netherton
9c96e7c7a2 ch376-native: fixed issue with TMSMODE_MSXUKY selected when no usb keyboard is present on boot
The TMS driver would always install a USB keyboard pooling interrupt, despite no keyboard present

This would load the CPU and prevent other I/O operations
2025-06-21 13:33:18 +10:00
Dean Netherton
ce0d04226e ch376-native: extended CHNATIVEFORCE option to wait upto approx 5 seconds for at least one connected device 2025-06-21 13:33:18 +10:00
Dean Netherton
eec2147826 ch376-native: applied z88dk version 20250224 2025-06-21 13:33:18 +10:00
Dean Netherton
93d7c7ed77 ch376-native: fixed and extend indicator led operation 2025-06-21 13:33:18 +10:00
Dean Netherton
1a44fbee0f ch376: implemented CTRL key combinations 2025-06-21 13:33:18 +10:00
Dean Netherton
9cbd8937d7 ch376-native: keyboard driver now support CAPS LOCK key 2025-06-21 13:33:18 +10:00
Dean Netherton
ca6979d97e ch376: increased rate of keyboard scanining and considers all keycodes state transmitted 2025-06-21 13:33:18 +10:00
Dean Netherton
72ec983c4f ch376: added build option CHNATIVEFORCE to always force detection of module on boot 2025-06-21 13:33:18 +10:00
Dean Netherton
f63c324764 ch376-native: remove --trace for mac-os 2025-06-21 13:33:18 +10:00
Dean Netherton
ea3ba6e0d4 ch376-native: remove transpiling of c code from mac-os gha build 2025-06-21 13:33:18 +10:00
Dean Netherton
bf2a45f83e ch376-native: updated github action build scripts to also attempt to transpile driver from c to assembly 2025-06-21 13:33:18 +10:00
Dean Netherton
3f8bc43596 ch376-native: enabled usb drivers for z80 config 2025-06-21 13:33:16 +10:00
Dean Netherton
e6143beb25 ch376-native: attempt to fix issue with slices not working - restored drive_index counter 2025-06-21 13:11:40 +10:00
Dean Netherton
3b0f00520e gitignore: added *.cat and some extract img files 2025-06-21 13:11:40 +10:00
Dean Netherton
db0afaedfa ch376-native/ez80: timing adjustments 2025-06-21 13:11:40 +10:00
Dean Netherton
a92bd780c8 ch376-native: removed some intermediate files that should not have beeen committed 2025-06-21 13:11:40 +10:00
Dean Netherton
04dbb0e4bb ch376-native: some cleanup of build process and an initial readme added 2025-06-21 13:11:40 +10:00
Dean Netherton
601ddee38b usb-keyboard: working (limited) 2025-06-21 13:11:38 +10:00
Dean Netherton
1e1554937c usb-keyboard: enumerated 2025-06-21 13:04:38 +10:00
Dean Netherton
b4421a0532 ch376-native: general fixes - mass storage and floppy devices over hub seem to be working 2025-06-21 13:04:38 +10:00
Dean Netherton
7c3eeaff27 ch376-native: fixes 2025-06-21 13:04:38 +10:00
Dean Netherton
ed47d2f8b6 ch376-native: native USB driver for the CH376 module 2025-06-21 13:04:36 +10:00
Marshall G. Gates
c802bd2ce2 Merge branch 'master' into dev/BoatFest_Talk 2025-05-23 16:26:31 -04:00
Marshall G. Gates
6ad93577db Merge branch 'master' into dev/BoatFest_Talk 2025-05-20 23:15:36 -04:00
Marshall Gates
cb2f4e5773 Update build to create my demo images 2025-05-20 23:05:12 -04:00
Marshall Gates
e6a14dda4d Add Hello World example programs 2025-05-20 23:00:57 -04:00
Marshall Gates
8163c20342 Update readmes to have build commands 2025-05-20 22:58:30 -04:00
287 changed files with 18221 additions and 2279 deletions

View File

@@ -26,7 +26,8 @@ jobs:
run: |
export TZ='America/Los_Angeles'
sudo apt-get install srecord
make distlog
make transpile-c-code
make distlog --trace
rm -rf .git*
- name: List Output

View File

@@ -19,7 +19,8 @@ jobs:
export TZ='America/Los_Angeles'
sudo apt-get install libncurses-dev
sudo apt-get install srecord
make distlog
make transpile-c-code
make distlog --trace
rm -rf .git*
- name: Create Package Archive

18
.gitignore vendored
View File

@@ -114,20 +114,24 @@ Source/ZPM3/genbnk.dat
Source/ZSDOS/zsdos.err
# Lets explicit list all generate untracked binary files
Binary/*.upd
Binary/Apps/bbcbasic.txt
Binary/Apps/copysl.doc
Binary/Apps/copysl.doc
Binary/Apps/fdu.doc
Binary/Apps/fdu.doc
Binary/Apps/Tunes/bgm.vgm
Binary/Apps/Tunes/ending.vgm
Binary/Apps/Tunes/inchina.vgm
Binary/Apps/Tunes/shirakaw.vgm
Binary/Apps/Tunes/startdem.vgm
Binary/Apps/Tunes/wonder01.vgm
Binary/Apps/copysl.doc
Binary/Apps/fdu.doc
Binary/Apps/zmconfig.ovr
Binary/Apps/zminit.ovr
Binary/Apps/zmp.doc
Binary/Apps/zmp.hlp
Binary/Apps/zmp.cfg
Binary/Apps/zmp.doc
Binary/Apps/zmp.fon
Binary/Apps/zmp.hlp
Binary/Apps/zmterm.ovr
Binary/Apps/zmxfer.ovr
Binary/CPM3/bdos3.spr
@@ -146,13 +150,12 @@ Binary/CPNET/cpn12ser.lbr
Binary/CPNET/cpn3duo.lbr
Binary/CPNET/cpn3mt.lbr
Binary/CPNET/cpn3ser.lbr
Binary/*.upd
Binary/hd1k_prefix.dat
Binary/ZPM3/bnkbdos3.spr
Binary/ZPM3/bnkbios3.spr
Binary/ZPM3/gencpm.dat
Binary/ZPM3/resbdos3.spr
Binary/ZPM3/zinstal.zpm
Binary/hd1k_prefix.dat
Source/BPBIOS/def-ww.lib
Source/CPNET/cpn12duo.lbr
Source/CPNET/cpn12mt.lbr
@@ -180,6 +183,8 @@ Source/Fonts/fontvgarcc.bin
Source/Fonts/fontvgarcu.asm
Source/HBIOS/*.upd
Source/HBIOS/build_env.cmd
Source/HBIOS/build_env.cmd
Source/HBIOS/hbios_env.sh
Source/HBIOS/hbios_env.sh
Source/HBIOS/netboot.mod
Source/Images/*.cat
@@ -197,4 +202,3 @@ Source/ZPM3/setz3.com
Tools/unix/OpenSpin/build/
Tools/unix/zxcc/config.h
Tools/unix/zxcc/zxcc
Binary/Apps/bbcbasic.txt

36
.vscode/settings.json vendored
View File

@@ -1,4 +1,38 @@
{
"z80-macroasm.format.enabled": true,
"z80-macroasm.format.baseIndent": 1,
"z80-macroasm.format.whitespaceAfterInstruction": "tab",
"z80-macroasm.format.uppercaseKeywords": true,
"z80-macroasm.format.spaceAfterArgument": true,
"z80-macroasm.format.hexaNumberStyle": "motorola",
"z80-macroasm.format.hexaNumberCase": true,
"files.trimTrailingWhitespace": false,
"files.eol": "\r\n"
"files.eol": "\r\n",
"files.associations": {
"*.inc": "z80-macroasm",
"*.asm": "z80-macroasm",
"*.180": "z80-macroasm",
"*.asm.m4": "z80-macroasm",
"*.inc.m4": "z80-macroasm",
"*.mac": "z80-macroasm",
"*.asmpp": "z80-macroasm",
"*.zdsproj": "xml",
"*.Z80": "z80-macroasm",
"ch376.h": "c",
"protocol.h": "c",
"usb_state.h": "c",
"functional": "c",
"class_scsi.h": "c",
"z80.h": "c",
"dev_transfers.h": "c",
"usb-base-drv.h": "c",
"critical-section.h": "c",
"enumerate.h": "c",
"ch376inc.h": "c",
"enumerate_storage.h": "c",
"work-area.h": "c",
"hbios-driver-storage.h": "c",
"class_hid_keyboard.h": "c",
"print.h": "c"
}
}

View File

@@ -14,6 +14,13 @@ Version 3.6
- J?L: Source for ZSDOS2 and BPBIOS Utilities (from disassembly)
- WBW: Support ROM-based font storage
- MAP: New Slice Inventory Rom App "S" display bootable slices, during boot
- MAP: Device Inventory moved from HBIOS to Rom App, saving >1k space in HBIOS
- MAP: Added disk image for all Infocom text adventure Games
- M?R: Fixed formatting issue with SLABEL where Slice # < 10
- WBW: Improved image creation process to allow user defined aggregates
- WBW: Implemented config driven slice name and system image specification
- D?N: Added native USB driver support (keyboard, floppy, mass storage)
- MGG: Added sample program source files for all language disk iamges
Version 3.5.1
-------------

Binary file not shown.

View File

@@ -23,10 +23,14 @@ Borland TurboPascal User Manual ("Turbo_Pascal_Version_3.0_Reference_Manual_1986
Official user manual Borland TurboPascal included in the pascal disk image.
Cowgol Lanaguage ("Cowgol Language.pdf")
The Cowgol Lanaguage ("The Cowgol Language.pdf")
Cowgol Compiler Manual ("Cowgol Compiler Manual.pdf")
--------------------------------------
Documentation for Cowgol Language included in the cowgol disk image
Documentation for Cowgol Language included in the cowgol disk image.
The Cowgol Language describes the Cowgol Language itself while the
Cowgol Compiler Manual describes the compiler operation.
HI-TECH C Compiler User Manual ("HI-TECH Z80 C Compiler Manual.txt")

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,4 +1,4 @@
FROM ubuntu:jammy-20240111 as basebuilder
FROM ubuntu:jammy-20240111 AS basebuilder
# This docker file can be used to build a tool chain docker image for building RomWBW images.
@@ -10,7 +10,7 @@ FROM ubuntu:jammy-20240111 as basebuilder
# After you have built the above image (called romwbw-chain), you can use it to compile and build the RomWBW images
# as per the standard make scripts within RomWBW.
# Start a new terminal, cd to where you have clone RomWBW, and then run this command:
# docker run --rm -v ${PWD}:/src/ --privileged=true -u $(id -u ${USER}):$(id -g ${USER}) -it romwbw-chain:latest
# docker run --rm -v ${PWD}:/src/ --privileged=true -u $(id -u ${USER}):$(id -g ${USER}) -it romwbw-chain
# you can now compile and build the required images:
@@ -21,13 +21,11 @@ FROM ubuntu:jammy-20240111 as basebuilder
# when finish, type 'exit' to return to back to your standard terminal session
LABEL Maintainer="Dean Netherton" \
Description="spike to use clang for ez80 target"
Description="RomWBW builder platform"
ENV DEBIAN_FRONTEND=noninteractive
RUN dpkg --add-architecture i386
RUN sed -i 's/http:\/\/archive\.ubuntu\.com\/ubuntu/http:\/\/au.archive.ubuntu.com\/ubuntu/g' /etc/apt/sources.list
RUN apt update -y
RUN apt dist-upgrade -y
RUN apt install -y --no-install-recommends cmake lzip ca-certificates mtools build-essential dos2unix libboost-all-dev texinfo texi2html libxml2-dev subversion bison flex zlib1g-dev m4 git wget dosfstools curl
@@ -35,10 +33,10 @@ RUN apt install -y --no-install-recommends cmake lzip ca-certificates mtools bui
RUN mkdir work
WORKDIR /work
FROM basebuilder as main
FROM basebuilder AS main
LABEL Maintainer="Dean Netherton" \
Description="spike to build RomWBW"
Description="RomWBW builder platform"
RUN mkdir /src
WORKDIR /src/

View File

@@ -1,7 +1,7 @@
.PHONY: tools source clean clobber diff dist
.ONESHELL:
.SHELLFLAGS = -cex
.SHELLFLAGS = -ce
all: tools source
@@ -22,6 +22,11 @@ clobber: clean
diff:
$(MAKE) --directory Source diff
# Convert c code to assembly code
transpile-c-code:
@cd Source/HBIOS/ch376-native
$(MAKE) -j
dist:
$(MAKE) ROM_PLATFORM=dist
$(MAKE) --directory Tools clean

871
ReadMe.md
View File

@@ -1,431 +1,440 @@
**RomWBW Introduction** \
Version 3.6 \
Wayne Warthen ([wwarthen@gmail.com](mailto:wwarthen@gmail.com)) \
29 Jun 2025
# Overview
RomWBW software provides a complete, commercial quality implementation
of CP/M (and work-alike) operating systems and applications for modern
Z80/180/280 retro-computing hardware systems.
A wide variety of platforms are supported including those produced by
these developer communities:
- [RetroBrew Computers](https://www.retrobrewcomputers.org)
(<https://www.retrobrewcomputers.org>)
- [RC2014](https://rc2014.co.uk) (<https://rc2014.co.uk>),
[RC2014-Z80](https://groups.google.com/g/rc2014-z80)
(<https://groups.google.com/g/rc2014-z80>)
- [Retro Computing](https://groups.google.com/g/retro-comp)
(<https://groups.google.com/g/retro-comp>)
- [Small Computer Central](https://smallcomputercentral.com/)
(<https://smallcomputercentral.com/>)
A complete list of the currently supported platforms is found in [RomWBW
Hardware](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Hardware.pdf)
.
# Description
## Primary Features
By design, RomWBW isolates all of the hardware specific functions in the
ROM chip itself. The ROM provides a hardware abstraction layer such that
all of the operating systems and applications on a disk will run on any
RomWBW-based system. To put it simply, you can take a disk (or CF/SD/USB
Card) and move it between systems transparently.
Supported hardware features of RomWBW include:
- Z80 Family CPUs including Z80, Z180, and Z280
- Banked memory services for several banking designs
- Disk drivers for RAM, ROM, Floppy, IDE ATA/ATAPI, CF, SD, USB, Zip,
Iomega
- Serial drivers including UART (16550-like), ASCI, ACIA, SIO
- Video drivers including TMS9918, SY6545, MOS8563, HD6445, Xosera
- Keyboard (PS/2) drivers via VT8242 or PPI interfaces
- Real time clock drivers including DS1302, BQ4845
- Support for CP/NET networking using Wiznet, MT011 or Serial
- Built-in VT-100 terminal emulation support
A dynamic disk drive letter assignment mechanism allows mapping
operating system drive letters to any available disk media.
Additionally, mass storage devices (IDE Disk, CF Card, SD Card, etc.)
support the use of multiple slices (up to 256 per device). Each slice
contains a complete CP/M filesystem and can be mapped independently to
any drive letter. This overcomes the inherent size limitations in legacy
OSes and allows up to 2GB of addressable storage on a single device,
with up to 128MB accessible at any one time.
## Included Software
Multiple disk images are provided in the distribution. Most disk images
contain a complete, bootable, ready-to-run implementation of a specific
operating system. A “combo” disk image contains multiple slices, each
with a full operating system implementation. If you use this disk image,
you can easily pick whichever operating system you want to boot without
changing media.
Some of the included software:
- Operating Systems (CP/M 2.2, ZSDOS, NZ-COM, CP/M 3, ZPM3, Z3PLUS, QPM
)
- Support for other operating systems, p-System, FreeRTOS, and FUZIX.
- Programming Tools (Z80ASM, Turbo Pascal, Forth, Cowgol)
- C Compilers including Aztec-C, and HI-TECH C
- Microsoft Basic Compiler, and Microsoft Fortran
- Some games such as Colossal Cave, Zork, etc
- Wordstar Word processing software
Some of the provided software can be launched directly from the ROM
firmware itself:
- System Monitor
- Operating Systems (CP/M 2.2, ZSDOS)
- ROM BASIC (Nascom BASIC and Tasty BASIC)
- ROM Forth
A tool is provided that allows you to access a FAT-12/16/32 filesystem.
The FAT filesystem may be coresident on the same disk media as RomWBW
slices or on stand-alone media. This makes exchanging files with modern
OSes such as Windows, MacOS, and Linux very easy.
## ROM Distribution
The [RomWBW Repository](https://github.com/wwarthen/RomWBW)
(<https://github.com/wwarthen/RomWBW>) on GitHub is the official
distribution location for all project source and documentation.
RomWBW is distributed as both source code and pre-built ROM and disk
images.
The pre-built ROM images distributed with RomWBW are based on the
default system configurations as determined by the hardware
provider/designer. The pre-built ROM firmware images are generally
suitable for most users.
The fully-built distribution releases are available on the [RomWBW
Releases Page](https://github.com/wwarthen/RomWBW/releases)
(<https://github.com/wwarthen/RomWBW/releases>) of the repository.
On this page, you will normally see a Development Snapshot as well as
recent stable releases. Unless you have a specific reason, I suggest you
stick to the most recent stable release.
The asset named RomWBW-vX.X.X-Package.zip includes all pre-built ROM and
Disk images as well as full source code. The other assets contain only
source code and do not have the pre-built ROM or disk images.
#### Distribution Directory Layout
The RomWBW distribution is a compressed zip archive file organized in a
set of directories. Each of these directories has its own ReadMe.txt
file describing the contents in detail. In summary, these directories
are:
| **Directory** | **Description** |
|----|----|
| **Binary** | The final output files of the build process are placed here. Most importantly, the ROM images with the file names ending in “.rom” and disk images ending in .img. |
| **Doc** | Contains various detailed documentation, both RomWBW specifically as well as the operating systems and applications. |
| **Source** | Contains the source code files used to build the software and ROM images. |
| **Tools** | Contains the programs that are used by the build process or that may be useful in setting up your system. |
#### Building from Source
It is also very easy to modify and build custom ROM images that fully
tailor the firmware to your specific preferences. All tools required to
build custom ROM firmware under Windows are included no need to
install assemblers, etc. The firmware can also be built using Linux or
MacOS after confirming a few standard tools have been installed.
## Installation & Operation
In general, installation of RomWBW on your platform is very simple. You
just need to program your ROM with the correct ROM image from the RomWBW
distribution. Subsequently, you can write disk images on your disk
drives (IDE disk, CF Card, SD Card, etc.) which then provides even more
functionality.
Complete instructions for installation and operation of RomWBW are found
in the [RomWBW User
Guide](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20User%20Guide.pdf).
It is also a good idea to review the [Release
Notes](https://github.com/wwarthen/RomWBW/blob/master/RELEASE_NOTES.md)
for helpful release-specific information.
## Documentation
There are several documents that form the core of the RomWBW
documentation:
- [RomWBW User
Guide](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20User%20Guide.pdf)
is the main user guide for RomWBW, it covers the major topics of how
to install, manage and use RomWBW, and includes additional guidance to
the use of some of the operating systems supported by RomWBW
- [RomWBW
Hardware](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Hardware.pdf)
contains a description of all the hardware platforms, and devices
supported by RomWBW.
- [RomWBW
Applications](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Applications.pdf)
is a reference for the ROM-hosted and OS-hosted applications created
or customized to enhance the operation of RomWBW.
- [RomWBW Disk
Catalog](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Disk%20Catalog.pdf)
is a reference for the contents of the disk images provided with
RomWBW, with a description of many of the files on each image
- [RomWBW System
Guide](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20System%20Guide.pdf)
discusses much of the internal design and construction of RomWBW. It
includes a reference for the RomWBW HBIOS API functions.
An online HTML version of this documentation is hosted at
<https://wwarthen.github.io/RomWBW>.
Each of the operating systems and ROM applications included with RomWBW
are sophisticated tools in their own right. It is not reasonable to
fully document their usage. However, you will find complete manuals in
PDF format in the Doc directory of the distribution. The intention of
this documentation is to describe the operation of RomWBW and the ways
in which it enhances the operation of the included applications and
operating systems.
Since RomWBW is purely a software product for many different platforms,
the documentation does **not** cover hardware construction,
configuration, or troubleshooting please see your hardware provider
for this information.
# Support
## Getting Assistance
The best way to get assistance with RomWBW or any aspect of the
RetroBrew Computers projects is via one of the community forums:
- [RetroBrew Computers Forum](https://www.retrobrewcomputers.org/forum/)
- [RC2014 Google
Group](https://groups.google.com/forum/#!forum/rc2014-z80)
- [retro-comp Google
Group](https://groups.google.com/forum/#!forum/retro-comp)
Submission of issues and bugs are welcome at the [RomWBW GitHub
Repository](https://github.com/wwarthen/RomWBW).
Also feel free to email Wayne Warthen at <wwarthen@gmail.com>. I am
happy to provide support adapting RomWBW to new or modified systems
# Contributions
All source code and distributions are maintained on GitHub.
Contributions of all kinds to RomWBW are very welcome.
## Acknowledgments
I want to acknowledge that a great deal of the code and inspiration for
RomWBW has been provided by or derived from the work of others in the
RetroBrew Computers Community. I sincerely appreciate all of their
contributions. The list below is probably missing many names please
let me know if I missed you!
- Andrew Lynch started it all when he created the N8VEM Z80 SBC which
became the first platform RomWBW supported. Some of his original code
can still be found in RomWBW.
- Dan Werner wrote much of the code from which RomWBW was originally
derived and he has always been a great source of knowledge and advice.
- Douglas Goodall contributed code, time, testing, and advice in “the
early days”. He created an entire suite of application programs to
enhance the use of RomWBW. Unfortunately, they have become unusable
due to internal changes within RomWBW. As of RomWBW 2.6, these
applications are no longer provided.
- Sergey Kiselev created several hardware platforms for RomWBW including
the very popular Zeta.
- David Giles created support for the Z180 CSIO which is now included SD
Card driver.
- Phil Summers contributed the Forth and BASIC adaptations in ROM, the
AY-3-8910 sound driver, DMA support, and a long list of general code
and documentation enhancements.
- Ed Brindley contributed some of the code that supports the RCBus
platform.
- Spencer Owen created the RC2014 series of hobbyist kit computers which
has exponentially increased RomWBW usage. Some of his kits include
RomWBW.
- Stephen Cousins has likewise created a series of hobbyist kit
computers at Small Computer Central and is distributing RomWBW with
many of them.
- Alan Cox has contributed some driver code and has provided a great
deal of advice.
- The CP/NET client files were developed by Douglas Miller.
- Phillip Stevens contributed support for FreeRTOS.
- Curt Mayer contributed the original Linux / MacOS build process.
- UNA BIOS and FDISK80 are the products of John Coffman.
- FLASH4 is a product of Will Sowerbutts.
- CLRDIR is a product of Max Scane.
- Tasty Basic is a product of Dimitri Theulings.
- Dean Netherton contributed eZ80 CPU support, the sound driver
interface, and the SN76489 sound driver.
- The RomWBW Disk Catalog document was produced by Mykl Orders.
- Rob Prouse has created many of the supplemental disk images including
Aztec C, HiTech C, SLR Z80ASM, Turbo Pascal, Microsoft BASIC Compiler,
Microsoft Fortran Compiler, and a Games compendium.
- Martin R has provided substantial help reviewing and improving the
User Guide and Applications documents.
- Mark Pruden has made a wide variety of contributions including:
- significant content in the Disk Catalog and User Guide
- creation of the Introduction and Hardware documents
- Z3PLUS operating system disk image
- COPYSL, and SLABEL utilities
- Display of bootable slices via “S” command during startup
- a feature for RomWBW configuration by NVRAM
- the /B bulk mode of disk assignment to the ASSIGN utility
- Jacques Pelletier has contributed the DS1501 RTC driver code.
- Jose Collado has contributed enhancements to the TMS driver including
compatibility with standard TMS register configuration.
- Kevin Boone has contributed a generic HBIOS date/time utility (WDATE).
- Matt Carroll has contributed a fix to XM.COM that corrects the port
specification when doing a send.
- Dean Jenkins enhanced the build process to accommodate the Raspberry
Pi 4.
- Tom Plano has contributed a new utility (HTALK) to allow talking
directly to HBIOS COM ports.
- Lars Nelson has contributed several generic utilities such as a
universal (OS agnostic) UNARC application.
- Dylan Hall added support for specifying a secondary console.
- Bill Shen has contributed boot loaders for several of his systems.
- Laszlo Szolnoki has contributed an EF9345 video display controller
driver.
- Ladislau Szilagyi has contributed an enhanced version of CP/M Cowgol
that leverages RomWBW memory banking.
- Les Bird has contributed support for the NABU w/ Option Board
- Rob Gowin created an online documentation site via MkDocs, and
contributed a driver for the Xosera FPGA-based video controller.
- Jörg Linder has contributed disassembled and nicely commented source
for ZSDOS2 and the BPBIOS utilities.
## Related Projects
Outside of the hardware platforms adapted to RomWBW, there are a variety
of projects that either target RomWBW specifically or provide a
RomWBW-specific variation. These efforts are greatly appreciated and are
listed below. Please contact the author if there are any other such
projects that are not listed.
#### Z88DK
Z88DK is a software powerful development kit for Z80 computers
supporting both C and assembly language. This kit now provides specific
library support for RomWBW HBIOS. The Z88DK project is hosted at
<https://github.com/z88dk/z88dk>.
#### Paleo Editor
Steve Garcia has created a Windows-hosted IDE that is tailored to
development of RomWBW. The project can be found at
<https://github.com/alloidian/PaleoEditor>.
#### Z80 fig-FORTH
Dimitri Theulings implementation of fig-FORTH for the Z80 has a
RomWBW-specific variant. The project is hosted at
<https://github.com/dimitrit/figforth>.
#### Assembly Language Programming for the RC2014 Zed
Bruce Hall has written a very nice document that describes how to
develop assembly language applications on RomWBW. It begins with the
setup and configuration of a new RC2014 Zed system running RomWBW. It
describes not only generic CP/M application development, but also RomWBW
HBIOS programming and bare metal programming. The latest copy of this
document is hosted at [http://w8bh.net/Assembly for
RC2014Z.pdf](http://w8bh.net/Assembly%20for%20RC2014Z.pdf).
# Licensing
## License Terms
RomWBW is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your
option) any later version.
RomWBW is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with RomWBW. If not, see <https://www.gnu.org/licenses/>.
Portions of RomWBW were created by, contributed by, or derived from the
work of others. It is believed that these works are being used in
accordance with the intentions and/or licensing of their creators.
If anyone feels their work is being used outside of its intended
licensing, please notify:
> Wayne Warthen
> <wwarthen@gmail.com>
RomWBW is an aggregate work. It is composed of many individual,
standalone programs that are distributed as a whole to function as a
cohesive system. Each program may have its own licensing which may be
different from other programs within the aggregate.
In some cases, a single program (e.g., CP/M Operating System) is
composed of multiple components with different licenses. It is believed
that in all such cases the licenses are compatible with GPL version 3.
RomWBW encourages code contributions from others. Contributors may
assert their own copyright in their contributions by annotating the
contributed source code appropriately. Contributors are further
encouraged to submit their contributions via the RomWBW source code
control system to ensure their contributions are clearly documented.
All contributions to RomWBW are subject to this license.
**RomWBW Introduction** \
Version 3.6 \
Wayne Warthen ([wwarthen@gmail.com](mailto:wwarthen@gmail.com)) \
29 Jul 2025
# Overview
RomWBW software provides a complete, commercial quality implementation
of CP/M (and work-alike) operating systems and applications for modern
Z80/180/280 retro-computing hardware systems.
A wide variety of platforms are supported including those produced by
these developer communities:
- [RetroBrew Computers](https://www.retrobrewcomputers.org)
(<https://www.retrobrewcomputers.org>)
- [RC2014](https://rc2014.co.uk) (<https://rc2014.co.uk>),
[RC2014-Z80](https://groups.google.com/g/rc2014-z80)
(<https://groups.google.com/g/rc2014-z80>)
- [Retro Computing](https://groups.google.com/g/retro-comp)
(<https://groups.google.com/g/retro-comp>)
- [Small Computer Central](https://smallcomputercentral.com/)
(<https://smallcomputercentral.com/>)
A complete list of the currently supported platforms is found in [RomWBW
Hardware](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Hardware.pdf)
.
# Description
## Primary Features
By design, RomWBW isolates all of the hardware specific functions in the
ROM chip itself. The ROM provides a hardware abstraction layer such that
all of the operating systems and applications on a disk will run on any
RomWBW-based system. To put it simply, you can take a disk (or CF/SD/USB
Card) and move it between systems transparently.
Supported hardware features of RomWBW include:
- Z80 Family CPUs including Z80, Z180, and Z280
- Banked memory services for several banking designs
- Disk drivers for RAM, ROM, Floppy, IDE ATA/ATAPI, CF, SD, USB, Zip,
Iomega
- Serial drivers including UART (16550-like), ASCI, ACIA, SIO
- Video drivers including TMS9918, SY6545, MOS8563, HD6445, Xosera
- Keyboard (PS/2) drivers via VT8242 or PPI interfaces
- Real time clock drivers including DS1302, BQ4845
- Support for CP/NET networking using Wiznet, MT011 or Serial
- Built-in VT-100 terminal emulation support
A dynamic disk drive letter assignment mechanism allows mapping
operating system drive letters to any available disk media.
Additionally, mass storage devices (IDE Disk, CF Card, SD Card, etc.)
support the use of multiple slices (up to 256 per device). Each slice
contains a complete CP/M filesystem and can be mapped independently to
any drive letter. This overcomes the inherent size limitations in legacy
OSes and allows up to 2GB of addressable storage on a single device,
with up to 128MB accessible at any one time.
## Included Software
Multiple disk images are provided in the distribution. Most disk images
contain a complete, bootable, ready-to-run implementation of a specific
operating system. A “combo” disk image contains multiple slices, each
with a full operating system implementation. If you use this disk image,
you can easily pick whichever operating system you want to boot without
changing media.
Some of the included software:
- Operating Systems (CP/M 2.2, ZSDOS, NZ-COM, CP/M 3, ZPM3, Z3PLUS, QPM
)
- Support for other operating systems, p-System, FreeRTOS, and FUZIX.
- Programming Tools (Z80ASM, Turbo Pascal, Forth, Cowgol)
- C Compilers including Aztec-C, and HI-TECH C
- Microsoft Basic Compiler, Microsoft Fortran, and Microsoft COBOL
- Some games such as Colossal Cave, Zork, etc
- Wordstar Word processing software
Some of the provided software can be launched directly from the ROM
firmware itself:
- System Monitor
- Operating Systems (CP/M 2.2, ZSDOS)
- ROM BASIC (Nascom BASIC and Tasty BASIC)
- ROM Forth
A tool is provided that allows you to access a FAT-12/16/32 filesystem.
The FAT filesystem may be coresident on the same disk media as RomWBW
slices or on stand-alone media. This makes exchanging files with modern
OSes such as Windows, MacOS, and Linux very easy.
## ROM Distribution
The [RomWBW Repository](https://github.com/wwarthen/RomWBW)
(<https://github.com/wwarthen/RomWBW>) on GitHub is the official
distribution location for all project source and documentation.
RomWBW is distributed as both source code and pre-built ROM and disk
images.
The pre-built ROM images distributed with RomWBW are based on the
default system configurations as determined by the hardware
provider/designer. The pre-built ROM firmware images are generally
suitable for most users.
The fully-built distribution releases are available on the [RomWBW
Releases Page](https://github.com/wwarthen/RomWBW/releases)
(<https://github.com/wwarthen/RomWBW/releases>) of the repository.
On this page, you will normally see a Development Snapshot as well as
recent stable releases. Unless you have a specific reason, I suggest you
stick to the most recent stable release.
The asset named RomWBW-vX.X.X-Package.zip includes all pre-built ROM and
Disk images as well as full source code. The other assets contain only
source code and do not have the pre-built ROM or disk images.
#### Distribution Directory Layout
The RomWBW distribution is a compressed zip archive file organized in a
set of directories. Each of these directories has its own ReadMe.txt
file describing the contents in detail. In summary, these directories
are:
| **Directory** | **Description** |
|----|----|
| **Binary** | The final output files of the build process are placed here. Most importantly, the ROM images with the file names ending in “.rom” and disk images ending in .img. |
| **Doc** | Contains various detailed documentation, both RomWBW specifically as well as the operating systems and applications. |
| **Source** | Contains the source code files used to build the software and ROM images. |
| **Tools** | Contains the programs that are used by the build process or that may be useful in setting up your system. |
#### Building from Source
It is also very easy to modify and build custom ROM images that fully
tailor the firmware to your specific preferences. All tools required to
build custom ROM firmware under Windows are included no need to
install assemblers, etc. The firmware can also be built using Linux or
MacOS after confirming a few standard tools have been installed.
## Installation & Operation
In general, installation of RomWBW on your platform is very simple. You
just need to program your ROM with the correct ROM image from the RomWBW
distribution. Subsequently, you can write disk images on your disk
drives (IDE disk, CF Card, SD Card, etc.) which then provides even more
functionality.
Complete instructions for installation and operation of RomWBW are found
in the [RomWBW User
Guide](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20User%20Guide.pdf).
It is also a good idea to review the [Release
Notes](https://github.com/wwarthen/RomWBW/blob/master/RELEASE_NOTES.md)
for helpful release-specific information.
## Documentation
There are several documents that form the core of the RomWBW
documentation:
- [RomWBW User
Guide](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20User%20Guide.pdf)
is the main user guide for RomWBW, it covers the major topics of how
to install, manage and use RomWBW, and includes additional guidance to
the use of some of the operating systems supported by RomWBW
- [RomWBW
Hardware](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Hardware.pdf)
contains a description of all the hardware platforms, and devices
supported by RomWBW.
- [RomWBW
Applications](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Applications.pdf)
is a reference for the ROM-hosted and OS-hosted applications created
or customized to enhance the operation of RomWBW.
- [RomWBW Disk
Catalog](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20Disk%20Catalog.pdf)
is a reference for the contents of the disk images provided with
RomWBW, with a description of many of the files on each image
- [RomWBW System
Guide](https://github.com/wwarthen/RomWBW/raw/master/Doc/RomWBW%20System%20Guide.pdf)
discusses much of the internal design and construction of RomWBW. It
includes a reference for the RomWBW HBIOS API functions.
An online HTML version of this documentation is hosted at
<https://wwarthen.github.io/RomWBW>.
Each of the operating systems and ROM applications included with RomWBW
are sophisticated tools in their own right. It is not reasonable to
fully document their usage. However, you will find complete manuals in
PDF format in the Doc directory of the distribution. The intention of
this documentation is to describe the operation of RomWBW and the ways
in which it enhances the operation of the included applications and
operating systems.
Since RomWBW is purely a software product for many different platforms,
the documentation does **not** cover hardware construction,
configuration, or troubleshooting please see your hardware provider
for this information.
# Support
## Getting Assistance
The best way to get assistance with RomWBW or any aspect of the
RetroBrew Computers projects is via one of the community forums:
- [RetroBrew Computers Forum](https://www.retrobrewcomputers.org/forum/)
- [RC2014 Google
Group](https://groups.google.com/forum/#!forum/rc2014-z80)
- [retro-comp Google
Group](https://groups.google.com/forum/#!forum/retro-comp)
Submission of issues and bugs are welcome at the [RomWBW GitHub
Repository](https://github.com/wwarthen/RomWBW).
Also feel free to email Wayne Warthen at <wwarthen@gmail.com>. I am
happy to provide support adapting RomWBW to new or modified systems
# Contributions
All source code and distributions are maintained on GitHub.
Contributions of all kinds to RomWBW are very welcome.
## Acknowledgments
I want to acknowledge that a great deal of the code and inspiration for
RomWBW has been provided by or derived from the work of others in the
RetroBrew Computers Community. I sincerely appreciate all of their
contributions. The list below is probably missing many names please
let me know if I missed you!
- Andrew Lynch started it all when he created the N8VEM Z80 SBC which
became the first platform RomWBW supported. Some of his original code
can still be found in RomWBW.
- Dan Werner wrote much of the code from which RomWBW was originally
derived and he has always been a great source of knowledge and advice.
- Douglas Goodall contributed code, time, testing, and advice in “the
early days”. He created an entire suite of application programs to
enhance the use of RomWBW. Unfortunately, they have become unusable
due to internal changes within RomWBW. As of RomWBW 2.6, these
applications are no longer provided.
- Sergey Kiselev created several hardware platforms for RomWBW including
the very popular Zeta.
- David Giles created support for the Z180 CSIO which is now included SD
Card driver.
- Phil Summers contributed the Forth and BASIC adaptations in ROM, the
AY-3-8910 sound driver, DMA support, and a long list of general code
and documentation enhancements.
- Ed Brindley contributed some of the code that supports the RCBus
platform.
- Spencer Owen created the RC2014 series of hobbyist kit computers which
has exponentially increased RomWBW usage. Some of his kits include
RomWBW.
- Stephen Cousins has likewise created a series of hobbyist kit
computers at Small Computer Central and is distributing RomWBW with
many of them.
- Alan Cox has contributed some driver code and has provided a great
deal of advice.
- The CP/NET client files were developed by Douglas Miller.
- Phillip Stevens contributed support for FreeRTOS.
- Curt Mayer contributed the original Linux / MacOS build process.
- UNA BIOS and FDISK80 are the products of John Coffman.
- FLASH4 is a product of Will Sowerbutts.
- CLRDIR is a product of Max Scane.
- Tasty Basic is a product of Dimitri Theulings.
- Dean Netherton contributed multiple components:
- eZ80 CPU support
- Sound driver infrastructure
- SN76489 sound driver
- Native USB driver (keyboard, floppy, mass storage)
- The RomWBW Disk Catalog document was produced by Mykl Orders.
- Rob Prouse has created many of the supplemental disk images including
Aztec C, HiTech C, SLR Z80ASM, Turbo Pascal, Microsoft BASIC Compiler,
Microsoft Fortran Compiler, and a Games compendium.
- Martin R has provided substantial help reviewing and improving the
User Guide and Applications documents.
- Mark Pruden has made a wide variety of contributions including:
- significant content in the Disk Catalog and User Guide
- creation of the Introduction and Hardware documents
- Z3PLUS operating system disk image
- Infocom text adventure game disk image
- COPYSL, and SLABEL utilities
- Display of bootable slices via “S” command during startup
- Optimisations of HBIOS and CBIOS to reduce overall code size
- a feature for RomWBW configuration by NVRAM
- the /B bulk mode of disk assignment to the ASSIGN utility
- Jacques Pelletier has contributed the DS1501 RTC driver code.
- Jose Collado has contributed enhancements to the TMS driver including
compatibility with standard TMS register configuration.
- Kevin Boone has contributed a generic HBIOS date/time utility (WDATE).
- Matt Carroll has contributed a fix to XM.COM that corrects the port
specification when doing a send.
- Dean Jenkins enhanced the build process to accommodate the Raspberry
Pi 4.
- Tom Plano has contributed a new utility (HTALK) to allow talking
directly to HBIOS COM ports.
- Lars Nelson has contributed several generic utilities such as a
universal (OS agnostic) UNARC application.
- Dylan Hall added support for specifying a secondary console.
- Bill Shen has contributed boot loaders for several of his systems.
- Laszlo Szolnoki has contributed an EF9345 video display controller
driver.
- Ladislau Szilagyi has contributed an enhanced version of CP/M Cowgol
that leverages RomWBW memory banking.
- Les Bird has contributed support for the NABU w/ Option Board
- Rob Gowin created an online documentation site via MkDocs, and
contributed a driver for the Xosera FPGA-based video controller.
- Jörg Linder has contributed disassembled and nicely commented source
for ZSDOS2 and the BPBIOS utilities.
- Marshall Gates has contriubed sample program source files for all of
the language disk images.
## Related Projects
Outside of the hardware platforms adapted to RomWBW, there are a variety
of projects that either target RomWBW specifically or provide a
RomWBW-specific variation. These efforts are greatly appreciated and are
listed below. Please contact the author if there are any other such
projects that are not listed.
#### Z88DK
Z88DK is a software powerful development kit for Z80 computers
supporting both C and assembly language. This kit now provides specific
library support for RomWBW HBIOS. The Z88DK project is hosted at
<https://github.com/z88dk/z88dk>.
#### Paleo Editor
Steve Garcia has created a Windows-hosted IDE that is tailored to
development of RomWBW. The project can be found at
<https://github.com/alloidian/PaleoEditor>.
#### Z80 fig-FORTH
Dimitri Theulings implementation of fig-FORTH for the Z80 has a
RomWBW-specific variant. The project is hosted at
<https://github.com/dimitrit/figforth>.
#### Assembly Language Programming for the RC2014 Zed
Bruce Hall has written a very nice document that describes how to
develop assembly language applications on RomWBW. It begins with the
setup and configuration of a new RC2014 Zed system running RomWBW. It
describes not only generic CP/M application development, but also RomWBW
HBIOS programming and bare metal programming. The latest copy of this
document is hosted at [http://w8bh.net/Assembly for
RC2014Z.pdf](http://w8bh.net/Assembly%20for%20RC2014Z.pdf).
# Licensing
## License Terms
RomWBW is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your
option) any later version.
RomWBW is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with RomWBW. If not, see <https://www.gnu.org/licenses/>.
Portions of RomWBW were created by, contributed by, or derived from the
work of others. It is believed that these works are being used in
accordance with the intentions and/or licensing of their creators.
If anyone feels their work is being used outside of its intended
licensing, please notify:
> Wayne Warthen
> <wwarthen@gmail.com>
RomWBW is an aggregate work. It is composed of many individual,
standalone programs that are distributed as a whole to function as a
cohesive system. Each program may have its own licensing which may be
different from other programs within the aggregate.
In some cases, a single program (e.g., CP/M Operating System) is
composed of multiple components with different licenses. It is believed
that in all such cases the licenses are compatible with GPL version 3.
RomWBW encourages code contributions from others. Contributors may
assert their own copyright in their contributions by annotating the
contributed source code appropriately. Contributors are further
encouraged to submit their contributions via the RomWBW source code
control system to ensure their contributions are clearly documented.
All contributions to RomWBW are subject to this license.

View File

@@ -1,441 +1,450 @@
RomWBW Introduction
Wayne Warthen (wwarthen@gmail.com)
29 Jun 2025
OVERVIEW
RomWBW software provides a complete, commercial quality implementation
of CP/M (and work-alike) operating systems and applications for modern
Z80/180/280 retro-computing hardware systems.
A wide variety of platforms are supported including those produced by
these developer communities:
- RetroBrew Computers (https://www.retrobrewcomputers.org)
- RC2014 (https://rc2014.co.uk),
RC2014-Z80 (https://groups.google.com/g/rc2014-z80)
- Retro Computing (https://groups.google.com/g/retro-comp)
- Small Computer Central (https://smallcomputercentral.com/)
A complete list of the currently supported platforms is found in RomWBW
Hardware .
DESCRIPTION
Primary Features
By design, RomWBW isolates all of the hardware specific functions in the
ROM chip itself. The ROM provides a hardware abstraction layer such that
all of the operating systems and applications on a disk will run on any
RomWBW-based system. To put it simply, you can take a disk (or CF/SD/USB
Card) and move it between systems transparently.
Supported hardware features of RomWBW include:
- Z80 Family CPUs including Z80, Z180, and Z280
- Banked memory services for several banking designs
- Disk drivers for RAM, ROM, Floppy, IDE ATA/ATAPI, CF, SD, USB, Zip,
Iomega
- Serial drivers including UART (16550-like), ASCI, ACIA, SIO
- Video drivers including TMS9918, SY6545, MOS8563, HD6445, Xosera
- Keyboard (PS/2) drivers via VT8242 or PPI interfaces
- Real time clock drivers including DS1302, BQ4845
- Support for CP/NET networking using Wiznet, MT011 or Serial
- Built-in VT-100 terminal emulation support
A dynamic disk drive letter assignment mechanism allows mapping
operating system drive letters to any available disk media.
Additionally, mass storage devices (IDE Disk, CF Card, SD Card, etc.)
support the use of multiple slices (up to 256 per device). Each slice
contains a complete CP/M filesystem and can be mapped independently to
any drive letter. This overcomes the inherent size limitations in legacy
OSes and allows up to 2GB of addressable storage on a single device,
with up to 128MB accessible at any one time.
Included Software
Multiple disk images are provided in the distribution. Most disk images
contain a complete, bootable, ready-to-run implementation of a specific
operating system. A “combo” disk image contains multiple slices, each
with a full operating system implementation. If you use this disk image,
you can easily pick whichever operating system you want to boot without
changing media.
Some of the included software:
- Operating Systems (CP/M 2.2, ZSDOS, NZ-COM, CP/M 3, ZPM3, Z3PLUS, QPM
)
- Support for other operating systems, p-System, FreeRTOS, and FUZIX.
- Programming Tools (Z80ASM, Turbo Pascal, Forth, Cowgol)
- C Compilers including Aztec-C, and HI-TECH C
- Microsoft Basic Compiler, and Microsoft Fortran
- Some games such as Colossal Cave, Zork, etc
- Wordstar Word processing software
Some of the provided software can be launched directly from the ROM
firmware itself:
- System Monitor
- Operating Systems (CP/M 2.2, ZSDOS)
- ROM BASIC (Nascom BASIC and Tasty BASIC)
- ROM Forth
A tool is provided that allows you to access a FAT-12/16/32 filesystem.
The FAT filesystem may be coresident on the same disk media as RomWBW
slices or on stand-alone media. This makes exchanging files with modern
OSes such as Windows, MacOS, and Linux very easy.
ROM Distribution
The RomWBW Repository (https://github.com/wwarthen/RomWBW) on GitHub is
the official distribution location for all project source and
documentation.
RomWBW is distributed as both source code and pre-built ROM and disk
images.
The pre-built ROM images distributed with RomWBW are based on the
default system configurations as determined by the hardware
provider/designer. The pre-built ROM firmware images are generally
suitable for most users.
The fully-built distribution releases are available on the RomWBW
Releases Page (https://github.com/wwarthen/RomWBW/releases) of the
repository.
On this page, you will normally see a Development Snapshot as well as
recent stable releases. Unless you have a specific reason, I suggest you
stick to the most recent stable release.
The asset named RomWBW-vX.X.X-Package.zip includes all pre-built ROM and
Disk images as well as full source code. The other assets contain only
source code and do not have the pre-built ROM or disk images.
Distribution Directory Layout
The RomWBW distribution is a compressed zip archive file organized in a
set of directories. Each of these directories has its own ReadMe.txt
file describing the contents in detail. In summary, these directories
are:
-------------------------------------------------------------------------
DIRECTORY DESCRIPTION
----------- -------------------------------------------------------------
BINARY The final output files of the build process are placed here.
Most importantly, the ROM images with the file names ending
in “.rom” and disk images ending in .img.
DOC Contains various detailed documentation, both RomWBW
specifically as well as the operating systems and
applications.
SOURCE Contains the source code files used to build the software and
ROM images.
TOOLS Contains the programs that are used by the build process or
that may be useful in setting up your system.
-------------------------------------------------------------------------
Building from Source
It is also very easy to modify and build custom ROM images that fully
tailor the firmware to your specific preferences. All tools required to
build custom ROM firmware under Windows are included no need to
install assemblers, etc. The firmware can also be built using Linux or
MacOS after confirming a few standard tools have been installed.
Installation & Operation
In general, installation of RomWBW on your platform is very simple. You
just need to program your ROM with the correct ROM image from the RomWBW
distribution. Subsequently, you can write disk images on your disk
drives (IDE disk, CF Card, SD Card, etc.) which then provides even more
functionality.
Complete instructions for installation and operation of RomWBW are found
in the RomWBW User Guide. It is also a good idea to review the Release
Notes for helpful release-specific information.
Documentation
There are several documents that form the core of the RomWBW
documentation:
- RomWBW User Guide is the main user guide for RomWBW, it covers the
major topics of how to install, manage and use RomWBW, and includes
additional guidance to the use of some of the operating systems
supported by RomWBW
- RomWBW Hardware contains a description of all the hardware platforms,
and devices supported by RomWBW.
- RomWBW Applications is a reference for the ROM-hosted and OS-hosted
applications created or customized to enhance the operation of RomWBW.
- RomWBW Disk Catalog is a reference for the contents of the disk images
provided with RomWBW, with a description of many of the files on each
image
- RomWBW System Guide discusses much of the internal design and
construction of RomWBW. It includes a reference for the RomWBW HBIOS
API functions.
An online HTML version of this documentation is hosted at
https://wwarthen.github.io/RomWBW.
Each of the operating systems and ROM applications included with RomWBW
are sophisticated tools in their own right. It is not reasonable to
fully document their usage. However, you will find complete manuals in
PDF format in the Doc directory of the distribution. The intention of
this documentation is to describe the operation of RomWBW and the ways
in which it enhances the operation of the included applications and
operating systems.
Since RomWBW is purely a software product for many different platforms,
the documentation does NOT cover hardware construction, configuration,
or troubleshooting please see your hardware provider for this
information.
SUPPORT
Getting Assistance
The best way to get assistance with RomWBW or any aspect of the
RetroBrew Computers projects is via one of the community forums:
- RetroBrew Computers Forum
- RC2014 Google Group
- retro-comp Google Group
Submission of issues and bugs are welcome at the RomWBW GitHub
Repository.
Also feel free to email Wayne Warthen at wwarthen@gmail.com. I am happy
to provide support adapting RomWBW to new or modified systems
CONTRIBUTIONS
All source code and distributions are maintained on GitHub.
Contributions of all kinds to RomWBW are very welcome.
Acknowledgments
I want to acknowledge that a great deal of the code and inspiration for
RomWBW has been provided by or derived from the work of others in the
RetroBrew Computers Community. I sincerely appreciate all of their
contributions. The list below is probably missing many names please
let me know if I missed you!
- Andrew Lynch started it all when he created the N8VEM Z80 SBC which
became the first platform RomWBW supported. Some of his original code
can still be found in RomWBW.
- Dan Werner wrote much of the code from which RomWBW was originally
derived and he has always been a great source of knowledge and advice.
- Douglas Goodall contributed code, time, testing, and advice in “the
early days”. He created an entire suite of application programs to
enhance the use of RomWBW. Unfortunately, they have become unusable
due to internal changes within RomWBW. As of RomWBW 2.6, these
applications are no longer provided.
- Sergey Kiselev created several hardware platforms for RomWBW including
the very popular Zeta.
- David Giles created support for the Z180 CSIO which is now included SD
Card driver.
- Phil Summers contributed the Forth and BASIC adaptations in ROM, the
AY-3-8910 sound driver, DMA support, and a long list of general code
and documentation enhancements.
- Ed Brindley contributed some of the code that supports the RCBus
platform.
- Spencer Owen created the RC2014 series of hobbyist kit computers which
has exponentially increased RomWBW usage. Some of his kits include
RomWBW.
- Stephen Cousins has likewise created a series of hobbyist kit
computers at Small Computer Central and is distributing RomWBW with
many of them.
- Alan Cox has contributed some driver code and has provided a great
deal of advice.
- The CP/NET client files were developed by Douglas Miller.
- Phillip Stevens contributed support for FreeRTOS.
- Curt Mayer contributed the original Linux / MacOS build process.
- UNA BIOS and FDISK80 are the products of John Coffman.
- FLASH4 is a product of Will Sowerbutts.
- CLRDIR is a product of Max Scane.
- Tasty Basic is a product of Dimitri Theulings.
- Dean Netherton contributed eZ80 CPU support, the sound driver
interface, and the SN76489 sound driver.
- The RomWBW Disk Catalog document was produced by Mykl Orders.
- Rob Prouse has created many of the supplemental disk images including
Aztec C, HiTech C, SLR Z80ASM, Turbo Pascal, Microsoft BASIC Compiler,
Microsoft Fortran Compiler, and a Games compendium.
- Martin R has provided substantial help reviewing and improving the
User Guide and Applications documents.
- Mark Pruden has made a wide variety of contributions including:
- significant content in the Disk Catalog and User Guide
- creation of the Introduction and Hardware documents
- Z3PLUS operating system disk image
- COPYSL, and SLABEL utilities
- Display of bootable slices via “S” command during startup
- a feature for RomWBW configuration by NVRAM
- the /B bulk mode of disk assignment to the ASSIGN utility
- Jacques Pelletier has contributed the DS1501 RTC driver code.
- Jose Collado has contributed enhancements to the TMS driver including
compatibility with standard TMS register configuration.
- Kevin Boone has contributed a generic HBIOS date/time utility (WDATE).
- Matt Carroll has contributed a fix to XM.COM that corrects the port
specification when doing a send.
- Dean Jenkins enhanced the build process to accommodate the Raspberry
Pi 4.
- Tom Plano has contributed a new utility (HTALK) to allow talking
directly to HBIOS COM ports.
- Lars Nelson has contributed several generic utilities such as a
universal (OS agnostic) UNARC application.
- Dylan Hall added support for specifying a secondary console.
- Bill Shen has contributed boot loaders for several of his systems.
- Laszlo Szolnoki has contributed an EF9345 video display controller
driver.
- Ladislau Szilagyi has contributed an enhanced version of CP/M Cowgol
that leverages RomWBW memory banking.
- Les Bird has contributed support for the NABU w/ Option Board
- Rob Gowin created an online documentation site via MkDocs, and
contributed a driver for the Xosera FPGA-based video controller.
- Jörg Linder has contributed disassembled and nicely commented source
for ZSDOS2 and the BPBIOS utilities.
Related Projects
Outside of the hardware platforms adapted to RomWBW, there are a variety
of projects that either target RomWBW specifically or provide a
RomWBW-specific variation. These efforts are greatly appreciated and are
listed below. Please contact the author if there are any other such
projects that are not listed.
Z88DK
Z88DK is a software powerful development kit for Z80 computers
supporting both C and assembly language. This kit now provides specific
library support for RomWBW HBIOS. The Z88DK project is hosted at
https://github.com/z88dk/z88dk.
Paleo Editor
Steve Garcia has created a Windows-hosted IDE that is tailored to
development of RomWBW. The project can be found at
https://github.com/alloidian/PaleoEditor.
Z80 fig-FORTH
Dimitri Theulings implementation of fig-FORTH for the Z80 has a
RomWBW-specific variant. The project is hosted at
https://github.com/dimitrit/figforth.
Assembly Language Programming for the RC2014 Zed
Bruce Hall has written a very nice document that describes how to
develop assembly language applications on RomWBW. It begins with the
setup and configuration of a new RC2014 Zed system running RomWBW. It
describes not only generic CP/M application development, but also RomWBW
HBIOS programming and bare metal programming. The latest copy of this
document is hosted at http://w8bh.net/Assembly for RC2014Z.pdf.
LICENSING
License Terms
RomWBW is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your
option) any later version.
RomWBW is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with RomWBW. If not, see https://www.gnu.org/licenses/.
Portions of RomWBW were created by, contributed by, or derived from the
work of others. It is believed that these works are being used in
accordance with the intentions and/or licensing of their creators.
If anyone feels their work is being used outside of its intended
licensing, please notify:
Wayne Warthen
wwarthen@gmail.com
RomWBW is an aggregate work. It is composed of many individual,
standalone programs that are distributed as a whole to function as a
cohesive system. Each program may have its own licensing which may be
different from other programs within the aggregate.
In some cases, a single program (e.g., CP/M Operating System) is
composed of multiple components with different licenses. It is believed
that in all such cases the licenses are compatible with GPL version 3.
RomWBW encourages code contributions from others. Contributors may
assert their own copyright in their contributions by annotating the
contributed source code appropriately. Contributors are further
encouraged to submit their contributions via the RomWBW source code
control system to ensure their contributions are clearly documented.
All contributions to RomWBW are subject to this license.
RomWBW Introduction
Wayne Warthen (wwarthen@gmail.com)
29 Jul 2025
OVERVIEW
RomWBW software provides a complete, commercial quality implementation
of CP/M (and work-alike) operating systems and applications for modern
Z80/180/280 retro-computing hardware systems.
A wide variety of platforms are supported including those produced by
these developer communities:
- RetroBrew Computers (https://www.retrobrewcomputers.org)
- RC2014 (https://rc2014.co.uk),
RC2014-Z80 (https://groups.google.com/g/rc2014-z80)
- Retro Computing (https://groups.google.com/g/retro-comp)
- Small Computer Central (https://smallcomputercentral.com/)
A complete list of the currently supported platforms is found in RomWBW
Hardware .
DESCRIPTION
Primary Features
By design, RomWBW isolates all of the hardware specific functions in the
ROM chip itself. The ROM provides a hardware abstraction layer such that
all of the operating systems and applications on a disk will run on any
RomWBW-based system. To put it simply, you can take a disk (or CF/SD/USB
Card) and move it between systems transparently.
Supported hardware features of RomWBW include:
- Z80 Family CPUs including Z80, Z180, and Z280
- Banked memory services for several banking designs
- Disk drivers for RAM, ROM, Floppy, IDE ATA/ATAPI, CF, SD, USB, Zip,
Iomega
- Serial drivers including UART (16550-like), ASCI, ACIA, SIO
- Video drivers including TMS9918, SY6545, MOS8563, HD6445, Xosera
- Keyboard (PS/2) drivers via VT8242 or PPI interfaces
- Real time clock drivers including DS1302, BQ4845
- Support for CP/NET networking using Wiznet, MT011 or Serial
- Built-in VT-100 terminal emulation support
A dynamic disk drive letter assignment mechanism allows mapping
operating system drive letters to any available disk media.
Additionally, mass storage devices (IDE Disk, CF Card, SD Card, etc.)
support the use of multiple slices (up to 256 per device). Each slice
contains a complete CP/M filesystem and can be mapped independently to
any drive letter. This overcomes the inherent size limitations in legacy
OSes and allows up to 2GB of addressable storage on a single device,
with up to 128MB accessible at any one time.
Included Software
Multiple disk images are provided in the distribution. Most disk images
contain a complete, bootable, ready-to-run implementation of a specific
operating system. A “combo” disk image contains multiple slices, each
with a full operating system implementation. If you use this disk image,
you can easily pick whichever operating system you want to boot without
changing media.
Some of the included software:
- Operating Systems (CP/M 2.2, ZSDOS, NZ-COM, CP/M 3, ZPM3, Z3PLUS, QPM
)
- Support for other operating systems, p-System, FreeRTOS, and FUZIX.
- Programming Tools (Z80ASM, Turbo Pascal, Forth, Cowgol)
- C Compilers including Aztec-C, and HI-TECH C
- Microsoft Basic Compiler, Microsoft Fortran, and Microsoft COBOL
- Some games such as Colossal Cave, Zork, etc
- Wordstar Word processing software
Some of the provided software can be launched directly from the ROM
firmware itself:
- System Monitor
- Operating Systems (CP/M 2.2, ZSDOS)
- ROM BASIC (Nascom BASIC and Tasty BASIC)
- ROM Forth
A tool is provided that allows you to access a FAT-12/16/32 filesystem.
The FAT filesystem may be coresident on the same disk media as RomWBW
slices or on stand-alone media. This makes exchanging files with modern
OSes such as Windows, MacOS, and Linux very easy.
ROM Distribution
The RomWBW Repository (https://github.com/wwarthen/RomWBW) on GitHub is
the official distribution location for all project source and
documentation.
RomWBW is distributed as both source code and pre-built ROM and disk
images.
The pre-built ROM images distributed with RomWBW are based on the
default system configurations as determined by the hardware
provider/designer. The pre-built ROM firmware images are generally
suitable for most users.
The fully-built distribution releases are available on the RomWBW
Releases Page (https://github.com/wwarthen/RomWBW/releases) of the
repository.
On this page, you will normally see a Development Snapshot as well as
recent stable releases. Unless you have a specific reason, I suggest you
stick to the most recent stable release.
The asset named RomWBW-vX.X.X-Package.zip includes all pre-built ROM and
Disk images as well as full source code. The other assets contain only
source code and do not have the pre-built ROM or disk images.
Distribution Directory Layout
The RomWBW distribution is a compressed zip archive file organized in a
set of directories. Each of these directories has its own ReadMe.txt
file describing the contents in detail. In summary, these directories
are:
-------------------------------------------------------------------------
DIRECTORY DESCRIPTION
----------- -------------------------------------------------------------
BINARY The final output files of the build process are placed here.
Most importantly, the ROM images with the file names ending
in “.rom” and disk images ending in .img.
DOC Contains various detailed documentation, both RomWBW
specifically as well as the operating systems and
applications.
SOURCE Contains the source code files used to build the software and
ROM images.
TOOLS Contains the programs that are used by the build process or
that may be useful in setting up your system.
-------------------------------------------------------------------------
Building from Source
It is also very easy to modify and build custom ROM images that fully
tailor the firmware to your specific preferences. All tools required to
build custom ROM firmware under Windows are included no need to
install assemblers, etc. The firmware can also be built using Linux or
MacOS after confirming a few standard tools have been installed.
Installation & Operation
In general, installation of RomWBW on your platform is very simple. You
just need to program your ROM with the correct ROM image from the RomWBW
distribution. Subsequently, you can write disk images on your disk
drives (IDE disk, CF Card, SD Card, etc.) which then provides even more
functionality.
Complete instructions for installation and operation of RomWBW are found
in the RomWBW User Guide. It is also a good idea to review the Release
Notes for helpful release-specific information.
Documentation
There are several documents that form the core of the RomWBW
documentation:
- RomWBW User Guide is the main user guide for RomWBW, it covers the
major topics of how to install, manage and use RomWBW, and includes
additional guidance to the use of some of the operating systems
supported by RomWBW
- RomWBW Hardware contains a description of all the hardware platforms,
and devices supported by RomWBW.
- RomWBW Applications is a reference for the ROM-hosted and OS-hosted
applications created or customized to enhance the operation of RomWBW.
- RomWBW Disk Catalog is a reference for the contents of the disk images
provided with RomWBW, with a description of many of the files on each
image
- RomWBW System Guide discusses much of the internal design and
construction of RomWBW. It includes a reference for the RomWBW HBIOS
API functions.
An online HTML version of this documentation is hosted at
https://wwarthen.github.io/RomWBW.
Each of the operating systems and ROM applications included with RomWBW
are sophisticated tools in their own right. It is not reasonable to
fully document their usage. However, you will find complete manuals in
PDF format in the Doc directory of the distribution. The intention of
this documentation is to describe the operation of RomWBW and the ways
in which it enhances the operation of the included applications and
operating systems.
Since RomWBW is purely a software product for many different platforms,
the documentation does NOT cover hardware construction, configuration,
or troubleshooting please see your hardware provider for this
information.
SUPPORT
Getting Assistance
The best way to get assistance with RomWBW or any aspect of the
RetroBrew Computers projects is via one of the community forums:
- RetroBrew Computers Forum
- RC2014 Google Group
- retro-comp Google Group
Submission of issues and bugs are welcome at the RomWBW GitHub
Repository.
Also feel free to email Wayne Warthen at wwarthen@gmail.com. I am happy
to provide support adapting RomWBW to new or modified systems
CONTRIBUTIONS
All source code and distributions are maintained on GitHub.
Contributions of all kinds to RomWBW are very welcome.
Acknowledgments
I want to acknowledge that a great deal of the code and inspiration for
RomWBW has been provided by or derived from the work of others in the
RetroBrew Computers Community. I sincerely appreciate all of their
contributions. The list below is probably missing many names please
let me know if I missed you!
- Andrew Lynch started it all when he created the N8VEM Z80 SBC which
became the first platform RomWBW supported. Some of his original code
can still be found in RomWBW.
- Dan Werner wrote much of the code from which RomWBW was originally
derived and he has always been a great source of knowledge and advice.
- Douglas Goodall contributed code, time, testing, and advice in “the
early days”. He created an entire suite of application programs to
enhance the use of RomWBW. Unfortunately, they have become unusable
due to internal changes within RomWBW. As of RomWBW 2.6, these
applications are no longer provided.
- Sergey Kiselev created several hardware platforms for RomWBW including
the very popular Zeta.
- David Giles created support for the Z180 CSIO which is now included SD
Card driver.
- Phil Summers contributed the Forth and BASIC adaptations in ROM, the
AY-3-8910 sound driver, DMA support, and a long list of general code
and documentation enhancements.
- Ed Brindley contributed some of the code that supports the RCBus
platform.
- Spencer Owen created the RC2014 series of hobbyist kit computers which
has exponentially increased RomWBW usage. Some of his kits include
RomWBW.
- Stephen Cousins has likewise created a series of hobbyist kit
computers at Small Computer Central and is distributing RomWBW with
many of them.
- Alan Cox has contributed some driver code and has provided a great
deal of advice.
- The CP/NET client files were developed by Douglas Miller.
- Phillip Stevens contributed support for FreeRTOS.
- Curt Mayer contributed the original Linux / MacOS build process.
- UNA BIOS and FDISK80 are the products of John Coffman.
- FLASH4 is a product of Will Sowerbutts.
- CLRDIR is a product of Max Scane.
- Tasty Basic is a product of Dimitri Theulings.
- Dean Netherton contributed multiple components:
- eZ80 CPU support
- Sound driver infrastructure
- SN76489 sound driver
- Native USB driver (keyboard, floppy, mass storage)
- The RomWBW Disk Catalog document was produced by Mykl Orders.
- Rob Prouse has created many of the supplemental disk images including
Aztec C, HiTech C, SLR Z80ASM, Turbo Pascal, Microsoft BASIC Compiler,
Microsoft Fortran Compiler, and a Games compendium.
- Martin R has provided substantial help reviewing and improving the
User Guide and Applications documents.
- Mark Pruden has made a wide variety of contributions including:
- significant content in the Disk Catalog and User Guide
- creation of the Introduction and Hardware documents
- Z3PLUS operating system disk image
- Infocom text adventure game disk image
- COPYSL, and SLABEL utilities
- Display of bootable slices via “S” command during startup
- Optimisations of HBIOS and CBIOS to reduce overall code size
- a feature for RomWBW configuration by NVRAM
- the /B bulk mode of disk assignment to the ASSIGN utility
- Jacques Pelletier has contributed the DS1501 RTC driver code.
- Jose Collado has contributed enhancements to the TMS driver including
compatibility with standard TMS register configuration.
- Kevin Boone has contributed a generic HBIOS date/time utility (WDATE).
- Matt Carroll has contributed a fix to XM.COM that corrects the port
specification when doing a send.
- Dean Jenkins enhanced the build process to accommodate the Raspberry
Pi 4.
- Tom Plano has contributed a new utility (HTALK) to allow talking
directly to HBIOS COM ports.
- Lars Nelson has contributed several generic utilities such as a
universal (OS agnostic) UNARC application.
- Dylan Hall added support for specifying a secondary console.
- Bill Shen has contributed boot loaders for several of his systems.
- Laszlo Szolnoki has contributed an EF9345 video display controller
driver.
- Ladislau Szilagyi has contributed an enhanced version of CP/M Cowgol
that leverages RomWBW memory banking.
- Les Bird has contributed support for the NABU w/ Option Board
- Rob Gowin created an online documentation site via MkDocs, and
contributed a driver for the Xosera FPGA-based video controller.
- Jörg Linder has contributed disassembled and nicely commented source
for ZSDOS2 and the BPBIOS utilities.
- Marshall Gates has contriubed sample program source files for all of
the language disk images.
Related Projects
Outside of the hardware platforms adapted to RomWBW, there are a variety
of projects that either target RomWBW specifically or provide a
RomWBW-specific variation. These efforts are greatly appreciated and are
listed below. Please contact the author if there are any other such
projects that are not listed.
Z88DK
Z88DK is a software powerful development kit for Z80 computers
supporting both C and assembly language. This kit now provides specific
library support for RomWBW HBIOS. The Z88DK project is hosted at
https://github.com/z88dk/z88dk.
Paleo Editor
Steve Garcia has created a Windows-hosted IDE that is tailored to
development of RomWBW. The project can be found at
https://github.com/alloidian/PaleoEditor.
Z80 fig-FORTH
Dimitri Theulings implementation of fig-FORTH for the Z80 has a
RomWBW-specific variant. The project is hosted at
https://github.com/dimitrit/figforth.
Assembly Language Programming for the RC2014 Zed
Bruce Hall has written a very nice document that describes how to
develop assembly language applications on RomWBW. It begins with the
setup and configuration of a new RC2014 Zed system running RomWBW. It
describes not only generic CP/M application development, but also RomWBW
HBIOS programming and bare metal programming. The latest copy of this
document is hosted at http://w8bh.net/Assembly for RC2014Z.pdf.
LICENSING
License Terms
RomWBW is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your
option) any later version.
RomWBW is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.
You should have received a copy of the GNU General Public License along
with RomWBW. If not, see https://www.gnu.org/licenses/.
Portions of RomWBW were created by, contributed by, or derived from the
work of others. It is believed that these works are being used in
accordance with the intentions and/or licensing of their creators.
If anyone feels their work is being used outside of its intended
licensing, please notify:
Wayne Warthen
wwarthen@gmail.com
RomWBW is an aggregate work. It is composed of many individual,
standalone programs that are distributed as a whole to function as a
cohesive system. Each program may have its own licensing which may be
different from other programs within the aggregate.
In some cases, a single program (e.g., CP/M Operating System) is
composed of multiple components with different licenses. It is believed
that in all such cases the licenses are compatible with GPL version 3.
RomWBW encourages code contributions from others. Contributors may
assert their own copyright in their contributions by annotating the
contributed source code appropriately. Contributors are further
encouraged to submit their contributions via the RomWBW source code
control system to ensure their contributions are clearly documented.
All contributions to RomWBW are subject to this license.

View File

@@ -7,6 +7,6 @@ BF_SND .EQU $50
BF_SNDRESET .EQU BF_SND + 0 ; RESET SOUND SYSTEM
BF_SNDVOL .EQU BF_SND + 1 ; REQUEST SOUND VOL - L CONTAINS VOLUME (255 MAX, 0 SILENT) - SCALED AS REQUIRED BY DRIVER (EG: MAPS TO JUST 4 BIT RESOLUTION FOR SN76489)
BF_SNDPRD .EQU BF_SND + 2 ; REQUEST SOUND PERIOD - HL CONTAINS DRIVER SPECIFIC VALUE
BF_SNDNOTE .EQU BF_SND + 3 ; REQUEST NOTE - L CONTAINS NOTE - EACH VALUE IS QUARTER NOTE
BF_SNDNOTE .EQU BF_SND + 3 ; REQUEST NOTE - L CONTAINS NOTE - EACH VALUE IS AN EIGHTH TONE
BF_SNDPLAY .EQU BF_SND + 4 ; INITIATE THE REQUESTED SOUND COMMAND
BF_SNDQUERY .EQU BF_SND + 5 ; E IS SUBFUNCTION

View File

@@ -38,6 +38,7 @@
; 2024-12-17 [MAP] Added new /B=opt feaure to assign drives
; 2024-12-21 [MAP] Added CBIOS heap estimation to /B to prevent
; overflow when the drives are finally added
; 2025-07-19 [D?N] Support for native USB drivers
;_______________________________________________________________________________
;
; ToDo:
@@ -1179,8 +1180,9 @@ makdphwbw: ; determine appropriate dpb (WBW mode, unit number in A)
jr makdph0 ; jump ahead
makdph00:
ld e,MID_FD144 ; assume floppy
cp DIODEV_FD ; floppy?
jr z,makdph0 ; yes, jump ahead
;cp DIODEV_FD ; floppy?
bit 7,c ; floppy?
jr nz,makdph0 ; yes, jump ahead
ld e,MID_RF ; assume ram floppy
cp DIODEV_RF ; ram floppy?
jr z,makdph0 ; yes, jump ahead
@@ -1560,7 +1562,7 @@ drvmap:
jr nz,drvmapu ; do UNA mode drvmap
;
; determine device code by scanning for string
ld b,16 ; device table always has 16 entries
ld b,devcnt ; number of entries in devtbl
ld c,0 ; c is used to track table entry num
ld de,tmpstr ; de points to specified device name
ld hl,devtbl ; hl points to first entry of devtbl
@@ -1826,7 +1828,7 @@ prtdev:
rst 08 ; call hbios, D := device, E := unit
push de ; save results
ld a,d ; device to A
and $0F ; mask out undesired bits
and $1F ; mask out undesired bits
push hl ; save HL
add a,a ; multiple A by two for word table
ld hl,devtbl ; point to start of device name table
@@ -2427,6 +2429,7 @@ devtbl: ; device table
.dw dev04, dev05, dev06, dev07
.dw dev08, dev09, dev10, dev11
.dw dev12, dev13, dev14, dev15
.dw dev16
;
devunk .db "?",0
dev00 .db "MD",0
@@ -2444,9 +2447,10 @@ dev11 .db "IMM",0
dev12 .db "SYQ",0
dev13 .db "CHUSB",0
dev14 .db "CHSD",0
dev15 .equ devunk
dev15 .db "USB",0
dev16 .equ devunk
;
devcnt .equ 10 ; 10 devices defined
devcnt .equ 17 ; 17 device types defined
;
udevram .db "RAM",0
udevrom .db "ROM",0
@@ -2464,13 +2468,13 @@ stack .equ $ ; stack top
; Messages
;
indent .db " ",0
msgban1 .db "ASSIGN v2.0 for RomWBW CP/M ",0
msgban1 .db "ASSIGN v2.1 for RomWBW CP/M ",0
msg22 .db "2.2",0
msg3 .db "3",0
msbban2 .db ", 21-Dec-2024",0
msbban2 .db ", 19-Jul-2025",0
msghb .db " (HBIOS Mode)",0
msgub .db " (UBIOS Mode)",0
msgban3 .db "Copyright 2024, Wayne Warthen, GNU GPL v3",0
msgban3 .db "Copyright 2025, Wayne Warthen, GNU GPL v3",0
msguse .db "Usage: ASSIGN D:[=[{D:|<device>[<unitnum>]:[<slicenum>]}]][,...]",13,10
.db " ex. ASSIGN (display all active assignments)",13,10
.db " ASSIGN /? (display version and usage)",13,10

View File

@@ -35,6 +35,7 @@
; table once (per device), and work out all the LBA's from this single read.
; Note this doesnt omit the fact that the 3 rd sector of each slice wold need to be read regarless.
; To slightly reduce some IO only slices < 64 are considered.
; - Output formatting misaligned with storage units enumerated as greater than 9 (ie 2 digits)
;
; This code will only execute on a Z80 CPU (or derivitive)
; This code requirs the use of HBIOS
@@ -45,6 +46,7 @@
; 2024-12-11 [MAP] Started - Reboot v1.0 used as the basis for this code
; 2024-12-14 [MAP] Initial 0.9 alpha with basic working functionality
; 2025-04-21 [MAP] Initial v1.0 release for distribution, fixing all issues
; 2025-07-12 [MR] Minor tweak to partially tidy up output formatting
;______________________________________________________________________________
;
; Include Files
@@ -94,7 +96,7 @@ exit:
jp restart ; return to CP/M via restart
;
;===============================================================================
; Initialization
; Initialisation
;
init:
; check for UNA (UBIOS)
@@ -211,10 +213,10 @@ prtslc2a:
ld a,c ; slice number
ld (currslice),a ; save slice number
;
push bc ; save loop
push bc ; save loop counter
call prtslc3 ; print detals of the slice
pop bc ; restore loop
ret nz ; if error dont continie
pop bc ; restore loop counter
ret nz ; if error don't continue
;
inc c ; next slice number
djnz prtslc2a ; loop if more slices
@@ -248,15 +250,25 @@ prtslc3:
cp c ; compare
jr nz,prtslc5 ; ignore missing signature and loop
;
; Print volume label string at HL, '$' terminated, 16 chars max
; Print slice label string at HL, '$' terminated, 16 chars max
ld a,(currunit)
call prtdecb ; print unit number as decimal
call pdot ; print a DOT
ld a,(currslice)
ld a, (currslice) ; fetch the current slice numeric
call prtdecb
;
;-------------------------------------------------------------------------------
; Added by MartinR, July 2025, to help neaten the output formatting.
; Note - this is not a complete fix and will still result in misaligned output
; where the unit number exceeds 9 (ie - uses 2 digits).
cp 10 ; is it less than 10?
ld a,' '
jr nc,jr01 ; If not, then we don't need an extra space printed
call cout ; print the extra space necessary
jr01: call cout ; print a space
call cout ; print a space
call cout ; print a space
;-------------------------------------------------------------------------------
;
ld hl,bb_label ; point to label
call pvol ; print it
call crlf
@@ -438,6 +450,7 @@ pdot:
;
;-------------------------------------------------------------------------------
; Print character in A without destroying any registers
; Use CP/M BDOS function $02 - Console Output
;
prtchr:
cout:
@@ -687,7 +700,7 @@ diskwrite:
;===============================================================================
;
str_banner .db "\r\n"
.db "Slice Label, v1.0, April 2025 - M.Pruden",0
.db "Slice Label, v1.1, July 2025 - M.Pruden",0
;
str_err_una .db " ERROR: UNA not supported by application",0
str_err_inv .db " ERROR: Invalid BIOS (signature missing)",0
@@ -706,7 +719,7 @@ str_usage .db "\r\n\r\n"
.db " Options are case insensitive.\r\n",0
;
PRTSLC_HDR .TEXT "\r\n\r\n"
.TEXT "Un.Sl Drive \r\n"
.TEXT "Un.Sl Label \r\n"
.TEXT "----- ----------------\r\n"
.DB 0
;

View File

@@ -4,7 +4,6 @@ setlocal
:: call BuildDoc || exit /b
call BuildProp || exit /b
call BuildShared || exit /b
call BuildBP || exit /b
call BuildImages || exit /b
call BuildROM %* || exit /b
call BuildZRC || exit /b

View File

@@ -1,4 +0,0 @@
@echo off
setlocal
pushd BPBIOS && call Build || exit /b & popd

View File

@@ -11,6 +11,7 @@ pushd ZSDOS && call Build || exit /b & popd
pushd ZSDOS2 && call Build || exit /b & popd
pushd CPM3 && call Build || exit /b & popd
pushd ZPM3 && call Build || exit /b & popd
pushd BPBIOS && call Build || exit /b & popd
pushd CPNET && call Build || exit /b & popd
pushd pSys && call Build || exit /b & popd
pushd Apps && call Build || exit /b & popd

View File

@@ -3201,8 +3201,9 @@ MAKDPH0: ; HANDLE RAM/ROM
CP DIODEV_MD ; RAM/ROM DISK?
JR Z,MAKDPH0 ; HANDLE SPECIAL
LD DE,DPB_FD144 ; PRELOAD FLOPPY DPB
CP DIODEV_FD ; FLOPPY?
JR Z,MAKDPH1 ; IF SO, PROCEED TO DPH CREATION
;CP DIODEV_FD ; FLOPPY?
BIT 7,C ; FLOPPY?
JR NZ,MAKDPH1 ; IF SO, PROCEED TO DPH CREATION
LD DE,DPB_RF ; PRELOAD RAM FLOPPY DPB
CP DIODEV_RF ; RAM FLOPPY?
JR Z,MAKDPH1 ; IF SO, PROCEED TO DPH CREATION
@@ -3381,7 +3382,7 @@ DEVUNK .DB "UNK$"
RST 08 ; CALL HBIOS
LD A,D ; RESULTANT DEVICE TYPE
PUSH DE ; NEED TO SAVE UNIT NUMBER (IN E)
AND $0F ; ISOLATE DEVICE BITS
AND $1F ; ISOLATE DEVICE BITS
ADD A,A ; MULTIPLY BY TWO FOR WORD TABLE
LD HL,DEVTBL ; POINT TO START OF DEVICE NAME TABLE
CALL ADDHLA ; ADD A TO HL TO POINT TO TABLE ENTRY
@@ -3407,6 +3408,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 +3426,8 @@ DEV11 .DB "IMM$"
DEV12 .DB "SYQ$"
DEV13 .DB "CHUSB$"
DEV14 .DB "CHSD$"
DEV15 .EQU DEVUNK
DEV15 .DB "USB$"
DEV16 .EQU DEVUNK
;
#ENDIF
;

View File

@@ -769,7 +769,7 @@ distribution. Some provide command line help themselves. Some are fairly obvio
## OS General Files
The following files are spcific files share across several OS's.
The following files are specific files shared across several OS's.
In general, there is no documentation for these applications included with
the RomWBW distribution. Some provide command line help themselves.
Some are fairly obvious.
@@ -788,6 +788,7 @@ The following files are found in
| `COPY.COM` | Z | File copier with ZSDOS date stamping awareness |
| `COPY.CFG` | Z | ZCNFG configuration file for COPY application |
| `EDITNDR.COM` | Z3 | Edit named directory register in memory. |
| `HELLO.ASM` | CPM22 | Sample assembly language source file |
| `HP-RPN.HLP` | Z3 | Help File for ZP.COM - HP RPN Calculators |
| `HP-ZP.HLP` | Z3 | Help File for ZP.COM - HP ZP Calculators |
| `KERCPM22.COM` | CPM22 | Kermit communication application |
@@ -1121,7 +1122,7 @@ The following files are found in
| `TESTAS.SUB` | SUBMIT file to build TESTAS sample program |
| `Z80AS.COM` | Z80 assembler which assembles the output of COWFIX and other Z80 source files (see <https://github.com/Laci1953/Z80AS>) |
## Microsoft Fortran 80 (Fortran)
## Microsoft Fortran 80
| Floppy Disk Image: **fd_fortran.img**
| Hard Disk Image: **hd_fortran.img**
@@ -1267,6 +1268,107 @@ The following files are found in
| `UNIXIO.H` | Language include file (see manual) |
| `ZAS.COM` | The assembler - in fact a general purpose macro assembler |
## Infocom (Text Adventure Games)
| Hard Disk Image: **hd_infocom.img**
A collection of all Official releases of the interactive fiction games
produced by Infocom in the 1980's
The following files are found in
* /Source/Images/d_infocom
| **File** | **Description** |
|--------------|----------------------------------------------------|
| amfv.z4 | A Mind Forever Voyaging (*) |
| arthur.z6 | Arthur - The Quest for Excalibur (*) |
| ballyhoo.z3 | Ballyhoo |
| beyond.z5 | Beyond Zork (*) |
| border.z5 | Border Zone (*) |
| bureau.z4 | Bureaucracy (*) |
| cutthr.z3 | Cutthroats |
| deadline.z3 | Deadline |
| enchant.z3 | Enchanter |
| h2g2.z3 | The Hitchhiker's Guide to the Galaxy |
| hollyw.z3 | Hollywood Hijinx |
| infidel.z3 | Infidel |
| journey.z6 | Journey (*) |
| leather.z3 | Leather Goddesses of Phobos |
| lurking.z3 | The Lurking Horror |
| moonmist.z3 | Moonmist |
| nordbert.z4 | Nord and Bert Couldn't Make Head or Tail of It (*) |
| planet.z3 | Planetfall |
| plunder.z3 | Plundered Hearts |
| readme.txt | Documentation about the Infocom games |
| seastalk.z3 | Seastalker |
| sherlock.z5 | Sherlock (*) |
| shogun.z6 | Shogun (*) |
| sorcerer.z3 | Sorcerer |
| spellb.z3 | Spellbreaker |
| starcros.z3 | Starcross |
| stationf.z3 | Stationfall |
| suspect.z3 | Suspect |
| suspend.z3 | Suspended |
| trinity.z4 | Trinity (*) |
| wishb.z3 | Wishbringer |
| witness.z3 | Witness |
| zork0.z6 | Zork Zero (*) |
| zork1.z3 | Zork I |
| zork2.z3 | Zork II |
| zork3.z3 | Zork III |
| zorknote.txt | Documentation about terminal config of COM files |
The above games have been curated from here <https://eblong.com/infocom/>.
Full game documentation can be found here <https://infodoc.plover.net/>
The game files are a virtual machine code commonly known as Z-Machine, they
are portable and will run on any machine that has a Z-Machine interpreter.
* All the Z3 games come with the official CP/M interpreter (the `COM` file)
version C last updated by Inforcom on 5th Feb 1985. You can simply run the
game by running it from the `COM` program
* All latter games Z4, Z5,.. and above, (Marked as * in the listing above)
are more sophisticated and require a better interpreter. i.e. VEZZA.
#### VEZZA (User Area 15)
Vezza is a modern Infocom/Inform/Z-machine text adventure interpreter for 8 bit
z80 based computers. What makes it modern is that it is written in hand-crafted
z80 assembler for maximum speed, and can load not only the classics such as
Zork 1,2 and 3 but also the later games.
It can run Z1 up to Z8 inform format interactive fiction game files. To run
a game with Vezza just type Vezza followed by the game you want to run. e.g.
`VEZZA ZORK0.Z6`
**Note:** One of the bigger constraints is available RAM. An OS such as ZPM
since it uses banked RAM does have a good amount of available RAM and was
used to test these games work.
This tool is free but the developer accepts your support by letting
you pay what you think is fair for the tool. If you find this useful
consider donating at:
<https://sijnstra.itch.io/vezza>
You should (test and) choose one that works on you configuration,
and best to copy and rename it as vezza.com
| **File** | **Description** |
|--------------|-------------------------------------------------------------------|
| vezza-B.com | 80x24, VT52 + Banked CP/M 3 |
| vezza-FG.com | 80x25, VT100/ANSI (16 color) + CP/M 3 |
| vezza-C2.com | 80x24, VT100 - CP/M 2.2 large memory, no timed input |
| vezza-CC.com | 80x24, VT100 (256 colour) - CP/M 2.2 large memory, no timed input |
| vezza-AV.com | 80x24, VT100 (16 colour) - CP/M 2.2 high RAM. |
| vezza-AX.com | 80x25, VT100/ANSI (16 colour) - CP/M 2.2 high RAM. |
| vezza-RW.com | 80x24, VT100 - CP/M 2.2 |
The above is a subset of available builds. The full repository including
documentation is available at <https://gitlab.com/sijnstra1/vezza/>
## MSX ROMS
| Hard Disk Image: **hd_msxroms1.img**
@@ -1329,7 +1431,7 @@ The following files are found in
| `TURBO.OVR` | Part of TURBO Pascal |
| `TURBOMSG.OVR` | Part of TURBO Pascal |
## WordStar 4
## WordStar 4 (Word processor)
| Floppy Disk Image: **fd_ws4.img**
| Hard Disk Image: **hd_ws4.img**

View File

@@ -71,7 +71,7 @@ Some of the included software:
* Support for other operating systems, p-System, FreeRTOS, and FUZIX.
* Programming Tools (Z80ASM, Turbo Pascal, Forth, Cowgol)
* C Compiler's including Aztec-C, and HI-TECH C
* Microsoft Basic Compiler, and Microsoft Fortran
* Microsoft Basic Compiler, Microsoft Fortran, and Microsoft COBOL
* Some games such as Colossal Cave, Zork, etc
* Wordstar Word processing software
@@ -273,8 +273,11 @@ please let me know if I missed you!
* Tasty Basic is a product of Dimitri Theulings.
* Dean Netherton contributed eZ80 CPU support, the sound driver
interface, and the SN76489 sound driver.
* Dean Netherton contributed multiple components:
- eZ80 CPU support
- Sound driver infrastructure
- SN76489 sound driver
- Native USB driver (keyboard, floppy, mass storage)
* The RomWBW Disk Catalog document was produced by Mykl Orders.
@@ -290,8 +293,10 @@ please let me know if I missed you!
- significant content in the Disk Catalog and User Guide
- creation of the Introduction and Hardware documents
- Z3PLUS operating system disk image
- Infocom text adventure game disk image
- COPYSL, and SLABEL utilities
- Display of bootable slices via "S" command during startup
- Optimisations of HBIOS and CBIOS to reduce overall code size
- a feature for RomWBW configuration by NVRAM
- the /B bulk mode of disk assignment to the ASSIGN utility
@@ -334,6 +339,9 @@ please let me know if I missed you!
* Jörg Linder has contributed disassembled and nicely commented
source for ZSDOS2 and the BPBIOS utilities.
* Marshall Gates has contriubed sample program source files for all
of the language disk images.
`\clearpage`{=latex}
## Related Projects

View File

@@ -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
@@ -2276,16 +2277,16 @@ using values that correspond to musical notes. The frequency will be
applied when the next SNDPLAY function is invoked. The returned Status
(A) is a standard HBIOS result code.
The Note (HL) values correspond to quarter notes. Increasing/decreasing
the value by 4 results in a full note increment/decrement.
The Note (HL) values correspond to eighth tones. Increasing/decreasing
the value by 8 results in a full tone increment/decrement.
Increasing/decreasing the value by 48 results in a full octave
increment/decrement. The value 0 corresponds to Bb/A# in octave 0.
The sound chip resolution and its oscillator limit the range and
accuracy of the notes played. The typical range of the AY-3-8910 is six
octaves: Bb2/A#2 to A7, where each value is a unique tone. Values above
and below can still be played but each quarter tone step may not result
in a note change.
and below can still be played but each eighth tone step may not result
in a tone change.
The following table shows the mapping of the Note (HL) value to the
corresponding octave and note.
@@ -2504,9 +2505,8 @@ If the Unit specified is not a hard disk the Media ID will be returned and
the slice parameter ignored. If there is no media in device, or the slice
number is invaid (Parameter Out Of Range) the function will return an error status.
**NOTE:
This function was placed in HBIOS to be shared between the diffeent CP/M
varients supported by RomWBW. It is not strictly a BIOS function,
**NOTE:** This function was placed in HBIOS to be shared between the different CP/M
variants supported by RomWBW. It is not strictly a BIOS function,
and may be moved in future.
`\clearpage`{=latex}

View File

@@ -992,10 +992,10 @@ whether you boot your OS from ROM or from the disk media itself.
## Drive Letter Assignment
In legacy CP/M operating systems only 16 drive letters (A:-P:) available
to be assigned to disks Drive letters were generally mapped to disk
In CP/M operating systems only 16 drive letters (A:-P:) available
to be assigned to disks Drive letters were generally mapped to disk
drives in a completely fixed way. For example, drive A: would **always**
refer to the first floppy disk drive.
refer to the first floppy disk drive.
RomWBW implements a much more flexible drive letter assignment mechanism
so that any drive letter can dynamically be assigned to any disk device,
@@ -1188,8 +1188,8 @@ media, you can use the CP/M 2.2 `STAT` command to display information
including the number of "32 Byte Directory Entries"
for a drive letter on the corresponding hard disk.
- If it indicates 512, your disk layout is legacy (hd512).
- If it indicates 1024, your disk layout is modern (hd1k).
- If it indicates 512, your disk layout is Classic (hd512).
- If it indicates 1024, your disk layout is Modern (hd1k).
Here is an example of checking the disk layout.
@@ -1335,14 +1335,14 @@ system.
Two hard disk layout schemes exist:
* Modern (hd1k)
* Legacy (hd512)
* Classic (hd512)
You **cannot** mix disk layouts on a single disk device,
however It is perfectly fine for one system to have
multiple hard disks with different layouts -- each physical disk
device is handled separately.
If you are setting up a new disk, the modern (hd1k) layout is
If you are setting up a new disk, the Modern (hd1k) layout is
recommended for the following reasons:
* Larger number of directory entries per filesystem
@@ -1350,8 +1350,8 @@ recommended for the following reasons:
* Reduces chances of data corruption
* Each slice occupies exactly 8MB (an exact power of 2) in size
Both the legacy and modern disk layouts continue to be fully supported
by RomWBW. There are no plans to deprecate the legacy layout.
Both the classic and modern disk layouts continue to be fully supported
by RomWBW. There are no plans to deprecate the classic layout.
#### Modern Layout
@@ -1368,14 +1368,14 @@ RomWBW does not support extended partitions -- only a single
primary partition can be used.
The existence of a partition table entry for RomWBW on
a hard disk makes it behave in the modern mode. Removing the RomWBW
partition entry from a modern hard disk layout
a hard disk makes it behaves in the modern disk layout mode.
Removing the RomWBW partition entry from a modern hard disk layout
will cause the existing data to be unavailable and/or corrupted
The CP/M filesystem in the slices of the modern disk layout
contain 1024 directory entries.
#### Legacy Layout
#### Classic Layout
Originally, RomWBW always used the very start of the hard disk media
for the location of the slices. In this layout, slice 0 referred to
@@ -1384,15 +1384,16 @@ chunk of ~8MB on the disk, and so on. The number of slices is limited
to the size of the disk media -- if you attempted to read/write to a
slice that would exceed the disk size, you would see I/O errors.
The legacy format takes steps to allow a partition table to still be
The classic disk layout takes steps to allow a partition table to still be
used for other types of filesystems such as DOS/FAT. It just does not
use a partition table entry to determine the start of the RomWBW slices.
The lack of a RomWBW partition table entry will cause legacy behaviour.
Adding a partition table entry on an existing legacy RomWBW hard disk
The lack of a RomWBW partition table entry will cause the classic disk
layout to be used.
Adding a partition table entry on an existing classic RomWBW hard disk
will cause the existing data to be unavailable and/or corrupted.
The CP/M filesystem in the slices of the legacy disk layout
The CP/M filesystem in the slices of the classic disk layout
contain 512 directory entries.
### Hard Disk Slices
@@ -1466,9 +1467,9 @@ system.
The exact number of CP/M filesystem slices that will fit on your
specific physical hard disk can be determined as follows:
- For modern (hd1k) disk layouts, it is 1024KB + (slices * 8192KB).
- For Modern (hd1k) disk layouts, it is 1024KB + (slices * 8192KB).
Or equivalent to say 1MB + (slices * 8MB).
- For legacy (hd512) disk layouts, it is slices * 8,320KB.
- For Classic (hd512) disk layouts, it is slices * 8,320KB.
**WARNING**: In this document KB means 1024 bytes and MB means 1048576
bytes (frequently expressed as KiB and MiB in modern terminology).
@@ -1611,7 +1612,7 @@ This does not mean to imply it is the only possible way.
First you need to understand
* The disk layout approach (either hd1k or the legacy hd512).
* The disk layout approach (either the Modern hd1k or the Classic hd512).
See [Hard Disk Layouts] section if you are not sure.
hd1k should be the preferred layout.
* The number of 8MB slices that you want to allocate, preferred is 64 slices.
@@ -1640,7 +1641,7 @@ The disk unit number was assigned at boot See [Device Unit Assignments]
Refer to $doc_apps$ for more information on use of the `FDISK80` utility.
If you want to use the legacy hd512 layout skip down to the [Legacy (hd512)] section
If you want to use the Classic (hd512) layout skip down to the [Classic (hd512)] section
#### Modern (hd1k)
@@ -1702,14 +1703,14 @@ At this point, it is best to restart your system to make sure that
the operating system is aware of the partition table updates. Start
CP/M 2.2 or Z-System from ROM again.
#### Legacy (hd512)
#### Classic (hd512)
At this point, use the `I` command to initialize (reset)
the partition table to an empty state.
To use the hd512 layout, use `W` to write the empty table to the disk
and exit. Remember that the lack of a partition for RomWBW implies the
legacy (hd512) layout.
Classic (hd512) layout.
At this point, it is best to restart your system to make sure that
the operating system is aware of the partition table updates. Start
@@ -1806,6 +1807,7 @@ The following table shows the disk images available.
| xxx_fortran.img | Microsoft Fortran-80 Compiler | No |
| xxx_games.img | Games Disk for CP/M | No |
| xxx_hitechc.img | HI-TECH Z80 CP/M C compiler | No |
| xxx_infocom.img | Infocom Games Disk | No |
| xxx_msxroms1.img | MSX ROMs Disk 1 | No |
| xxx_msxroms2.img | MSX ROMs Disk 2 | No |
| xxx_nzcom.img | NZCOM ZCPR 3.4 Operating System | Yes |
@@ -1820,8 +1822,8 @@ You will find 3 sets of these .img files in the distribution. The
"xxx" portion of the filename will be:
* "fd_" for a floppy image.
* "hd1k_" for a modern layout hard disk image.
* "hd512_" for a legacy layout hard disk image.
* "hd1k_" for a Modern layout hard disk image.
* "hd512_" for a Classic layout hard disk image.
In the case of xxx_dos65.img, only an hd512 variant is provided. This
is a constraint of the DOS65 distribution.
@@ -1895,7 +1897,7 @@ These partition sizes and locations were chosen to:
The standard partition table table entries are:
+---------------------------------+-------------------------------+-------------------------------+
| | **--- Modern (hd1k) ---** | **--- Legacy (hd512) ---** |
| | **--- Modern (hd1k) ---** | **--- Classic (hd512) ---** |
| +---------------+---------------+---------------+---------------+
| | Byte(s) | Sector(s) | Byte(s) | Sector(s) |
+=================================+==============:+==============:+==============:+==============:+
@@ -1998,7 +2000,52 @@ that there are more disk (slice) images than the 6 that are included in
the Combo Disk Images. These supplemental disk images are identified by
looking for the files that start with hd1k_ or hd512_.
#### Adding Slices to Combo Image
There are two approaches you can use to create custom hard disk
images with multiple slices.
- You can add/modify a configuration file and run the RomWBW
build process. This requires running the RomWBW build process, but
will cause your custom hard disk images to be created with every
build.
- You can manually combine the individual images using `COPY` (Windows)
or `cat` (Linux/MacOS). This does not require running the RomWBW
build process, but will require manually recreating your custom
hard disk images when you upgrade to new releases of RomWBW.
The following sections provide more detail on each approach.
#### Building Custom Hard Disk Images
The RomWBW build process builds the disk images defined in the
`Source/Images` directory. The resultant images are placed in the `Binary`
directory and are ready to copy to your media.
These aggregate disk images are defined using .def files. You will see there
is a combo.def file in the Images directory that defines the slices for the
Combo disk image. You can create your own .def files as desired to
automatically create custom aggregate disk images. When the RomWBW
build process is run, it will automatically look for all .def files
in the `Source/Images` directory and create aggregate disk images for
each using the same base name as the .def file.
There is an example of this in the `Images` directory called
`all.def.example`. You can remove the ".example" suffix so that the
file is called `all.def`. Now, if you run the RomWBW build process, it
will automatically generate `hd512_all.img` and `hd1k_all.img` files in
the `/Binary` directory. This example creates an aggregate disk image
with all of the possible slices.
You could also modify the contents of the Combo disk image by simply
modifying the `combo.def` configuration file. However, it is recommended
that you leave the Combo image alone and simply define your own.
NOTE: All of the `hd1k_xxx.img` aggregate disk image files created in
this way (including the Combo disk image) will already be prefixed with
`hd1k_prefix.dat`, so you do not need to add the prefix file. They are
ready to write to your media.
#### Combining Hard Disk Images Manually
You can add slices to the Combo Disk Images simply by tacking
slices onto the end. For example, if you want to add a slice
@@ -2017,7 +2064,7 @@ Linus/MaxOS:
Note that you **must** be sure to use either the hd1k_ or hd512_
prefixed files together. You cannot mix them.
#### Creating a new Custom Image
#### Creating a new Custom Image Manually
If you want to create a completely custom hard disk image that is not
based on the existing combo image, you can generate a disk image entirely

View File

@@ -91,6 +91,7 @@ tasm -t%CPUType% -g3 -dAPPBOOT hbios.asm hbios_app.bin hbios_app.lst || exit /b
call :asm dbgmon || exit /b
call :asm romldr || exit /b
call :asm invntdev || exit /b
call :asm invntslc || exit /b
call :asm eastaegg || exit /b
call :asm nascom || exit /b
@@ -125,7 +126,7 @@ if %Platform%==S100 (
copy /b romldr.bin + dbgmon.bin + ..\zsdos\zsys_wbw.bin + ..\cpm22\cpm_wbw.bin rom1.bin || exit /b
copy /b ..\Forth\camel80.bin + nascom.bin + ..\tastybasic\src\tastybasic.bin + game.bin + eastaegg.bin + %NETBOOT% + updater.bin + sysconf.bin + usrrom.bin rom2.bin || exit /b
copy /b %HwMon% + invntslc.bin + romfonts.bin rom3.bin
copy /b %HwMon% + invntdev.bin + invntslc.bin + romfonts.bin rom3.bin
copy /b romldr.bin + dbgmon.bin + ..\zsdos\zsys_wbw.bin appboot.bin || exit /b
::

View File

@@ -55,7 +55,7 @@ CRTACT .SET FALSE ; ACTIVATE CRT (VDU,CVDU,PROPIO,ETC) AT STARTUP
VDAEMU_SERKBD .SET $FF ; VDA EMULATION: SERIAL KBD UNIT #, OR $FF FOR HW KBD
;;
TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM)
TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU]
TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY]
TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958
TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1)
VRCENABLE .SET FALSE ; VRC: ENABLE VGARC VIDEO/KBD DRIVER (VRC.ASM)
@@ -71,6 +71,14 @@ PPIDEENABLE .SET TRUE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM)
SDENABLE .SET FALSE ; SD: ENABLE SD CARD DISK DRIVER (SD.ASM)
SDMODE .SET SDMODE_PIO ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4|SC|MT|USR|PIO|Z80R|EPITX|FZ80|GM|EZ512|K80W]
SDCNT .SET 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD/SC/MT ONLY
;
CHENABLE .SET TRUE ; CH: ENABLE CH375/376 USB SUPPORT
CHNATIVEENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)
CHNATIVEEZ80 .SET TRUE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE
CHNATIVEFORCE .SET FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED
;
PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM)
;
LPTENABLE .SET FALSE ; LPT: ENABLE CENTRONICS PRINTER DRIVER (LPT.ASM)
@@ -82,3 +90,5 @@ SN76489ENABLE .SET FALSE ; SN: ENABLE SN76489 SOUND DRIVER
AY38910ENABLE .SET FALSE ; AY: ENABLE AY-3-8910 / YM2149 SOUND DRIVER
AYMODE .SET AYMODE_RCZ80 ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC|MBC|DUO|NABU]
AY_FORCE .SET FALSE ; AY: BYPASS AUTO-DETECT, FORCED PRESENT
EZ80TIMER .SET EZ80TMR_FIRM ; EZ80: TIMER TICK MODEL: EZ80TMR_[INT|FIRM]

View File

@@ -72,7 +72,7 @@ ACIAENABLE .SET TRUE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM)
;
TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM)
TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU]
TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY]
TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958
TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1)
VRCENABLE .SET FALSE ; VRC: ENABLE VGARC VIDEO/KBD DRIVER (VRC.ASM)
@@ -92,6 +92,10 @@ SDMODE .SET SDMODE_PIO ; SD: DRIVER MODE: SDMODE_[JUHA|N8|CSIO|PPI|UART|DSD|MK4
SDCNT .SET 1 ; SD: NUMBER OF SD CARD DEVICES (1-2), FOR DSD/SC/MT ONLY
;
CHENABLE .SET TRUE ; CH: ENABLE CH375/376 USB SUPPORT
CHNATIVEENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)
CHNATIVEFORCE .SET FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED
;
PRPENABLE .SET FALSE ; PRP: ENABLE ECB PROPELLER IO BOARD DRIVER (PRP.ASM)
;

View File

@@ -3,66 +3,72 @@ Final Output Files
------------------
ROM Output File [512K] -> <config>.rom
hbios_rom [32K]
OSIMG [32K]
OSIMG1 [32K]
OSIMG2 [32K]
romdisk - [384K]
HBIOS_ROM [32K]
ROM1 [32K]
ROM2 [32K]
ROM3 [32K]
ROMDISK [384K] (size varies with ROM in system)
UPD Output File [128K] -> <config>.upd
hbios_rom [32K]
OSIMG [32K]
OSIMG1 [32K]
OSIMG2 [32K]
HBIOS_ROM [32K]
ROM1 [32K]
ROM2 [32K]
ROM3 [32K]
COM Output File -> <config>.com
hbios_app [varies]
OSIMG_SMALL [32K]
HBIOS_APP [<32K] (size varies, no padding]
APPBOOT [ 20K]
-------------------------
Intermediate Output Files
-------------------------
OSIMG [32K] -> osimg.bin
romldr [4K]
dbgmon [4K]
ZSYS (zcpr/zsdos/cbios) [12K]
CPM (ccp/bdos/cbios) [12K]
ROM1 [32K] -> rom1.bin
romldr [ 4K]
dbgmon [ 4K]
ZSYS [12K] (zcpr/zsdos/cbios)
CPM [12K] (ccp/bdos/cbios)
OSIMG_SMALL [20K] -> osimg_small.bin
romldr [4K]
dbgmon [4K]
ZSYS (zcpr/zsdos/cbios) [12K]
OSIMG1 [32K] -> osimg1.bin
ROM2 [32K] -> rom2.bin
camel80 [5.75K]
nascom [8K]
tastybasic [2.5K]
nascom [8.00K]
tastybasic [2.50K]
game [2.25K]
eastaegg [0.5K]
netboot [4K]
eastaegg [0.50K]
netboot [4.00K]
updater.bin [3.25K]
sysconf.bin [2K]
usrrom.bin [3.75K (padded)]
sysconf.bin [2.00K]
usrrom.bin [3.75K]
OSIMG2 [32K] -> osimg2.bin
s100mon [8.25kb (optional)]
(OR) not populated
ROM3 [32K] -> rom3.bin
hwmon [ 8.00K]
invntdev [ 2.75K]
invntslc [ 0.50K]
fonts [ 8.00K]
slack [12.75K]
APPBOOT [20K] -> appboot.bin
romldr [ 4K]
dbgmon [ 4K]
ZSYS [12K] (zcpr/zsdos/cbios)
CPM [12K] -> cpm.bin
ccp [2K]
bdos [3.5K]
cbios [6.5K]
ccp [2.0K]
bdos [3.5K]
cbios [6.5K]
ZSYS [12K] -> zsys.bin
zcpr [2K]
zsdos [3.5K]
cbios [6.5K]
zcpr [2.0K]
zsdos [3.5K]
cbios [6.5K]
-----------------
Compilation Units
-----------------
NOTE: The following need to be reviewed. They are probably out
of date.
hbios.asm -> hbios_rom.bin, hbios_app.bin
std.asm
ver.inc
@@ -76,7 +82,7 @@ hbios.asm -> hbios_rom.bin, hbios_app.bin
bcd.asm
dsky.asm
romldr.asm -> romldr.bin: loader?
romldr.asm -> romldr.bin
std.asm
ver.inc
hbios.inc
@@ -125,18 +131,16 @@ tastybasic.asm -> tastybasic.bin
<config>.asm
plt_<platform>.inc
=======================================================================
HBIOS Loading Modes:
ROMBOOT: Startup from ROM Bank BID_BOOT
APPBOOT: Startup as CP/M application
IMGBOOT: Startup from RAM Bank BID_USR
IMGBOOT: Startup from RAM Bank BID_USR (deprecated)
=======================================================================
- If not (APPBOOT), include page 0
- Base Hardware Init
- Iff (ROMBOOT), init BBR
- Install Proxy
- Set CURBNK:
@@ -149,6 +153,6 @@ HBIOS Loading Modes:
- Copy OS Image to USR Bank
- If (ROM_MODE), copy BID_OS:0 --> BID_USR:0
- Else, copy BID_USR:<os image start> --> BID_USR:0
- Else, copy BID_BIOS:<os image start> --> BID_USR:0
- Chain to BID_USR:0

View File

@@ -32,7 +32,7 @@ else ifeq ($(CPUFAM),3)
TASM=$(BINDIR)/uz80as -t z280
endif
DEPS=prereq dbgmon.bin romldr.bin nascom.bin tastybasic.bin invntslc.bin game.bin eastaegg.bin updater.bin sysconf.bin sysconf.com usrrom.bin romfonts.bin
DEPS=prereq dbgmon.bin romldr.bin nascom.bin tastybasic.bin invntdev.bin invntslc.bin game.bin eastaegg.bin updater.bin sysconf.bin sysconf.com usrrom.bin romfonts.bin
ifeq ($(ROM_PLATFORM),UNA)
ROMDEPS=romldr.bin dbgmon.bin
@@ -72,7 +72,7 @@ $(OBJECTS) : $(ROMDEPS)
cat romldr.bin dbgmon.bin ../ZSDOS/zsys_$(BIOS).bin >appboot.bin
if [ $(ROM_PLATFORM) != UNA ] ; then \
cat camel80.bin nascom.bin tastybasic.bin game.bin eastaegg.bin $(NETBOOT) updater.bin sysconf.bin usrrom.bin >rom2.bin ; \
cat $(HWMON) invntslc.bin romfonts.bin >rom3.bin ; \
cat $(HWMON) invntdev.bin invntslc.bin romfonts.bin >rom3.bin ; \
for f in hbios_rom.bin rom1.bin rom2.bin rom3.bin ; do \
srec_cat $$f -Binary -Crop 0 0x7FFF -Checksum_Negative_Big_Endian 0x7FFF 1 1 -o $$f -Binary ; \
done \
@@ -133,6 +133,7 @@ hbios_env.sh: hbios_env.com
romldr.bin: build.inc
dbgmon.bin: build.inc
nascom.bin: build.inc
invntdev.bin: build.inc
invntslc.bin: build.inc
eastaegg.bin: build.inc
updater.bin: build.inc

View File

@@ -1554,4 +1554,4 @@ ANSI_DEVNUM .DB $FF ; TERMINAL DEVICE NUMBER
; E Light Cyan
; F Bright White
;=============================================================
;
;

View File

@@ -45,8 +45,8 @@ AUD_SCALE .EQU 3
; ON ENTRY, DE IS ADDRESS OF NOTE TABLE, HL IS NOTE TO PLAY
; NOTE VALUE 0 MEANS B0b/A0# IN OCTAVE 0 WHICH IS THE FIRST ENTRY
; OF THE NOTE TABLE. THE NOTE TABLE REPRESENTS THE FREQUENCIES
; FOR 1 FULL OCTAVE IN QUARTER NOTES. SINCE THERE ARE 12 NOTES
; IN AN OCTAVE, THE TABLE HAS 48 ENTRIES FOR ALL QUARTER NOTES.
; FOR 1 FULL OCTAVE IN EIGHTH TONES. SINCE THERE ARE 12 HALF TONES
; IN AN OCTAVE, THE TABLE HAS 48 ENTRIES FOR ALL EIGHTH TONES.
;
; ON EXIT, HL CONTAINS THE PERIOD VALUE TO PROGRAM INTO THE PSG
; DERIVED FROM THE NOTE TABLE SCALED TO THE REQUESTED OCTAVE.

View File

@@ -556,10 +556,10 @@ AYT_REGWR .DB "\r\nOUT AY-3-8910 $"
#ENDIF
;
;======================================================================
; QUARTER TONE FREQUENCY TABLE
; EIGHTH TONE FREQUENCY TABLE
;======================================================================
;
; THE FOLLOWING TABLE MAPS A FULL OCTAVE OF QUARTER-NOTES
; THE FOLLOWING TABLE MAPS A FULL OCTAVE OF EIGHTH-TONES
; STARTING AT A# IN OCTAVE 0 TO THE CORRESPONDING PERIOD
; VALUE TO USE ON THE PSG TO ACHIEVE THE DESIRED NOTE FREQUENCY.
;

View File

@@ -375,6 +375,9 @@ AYMODE .SET AYMODE_DUO ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC|
AY_FORCE .SET FALSE ; AY: BYPASS AUTO-DETECT, FORCED PRESENT
;
SPKENABLE .SET TRUE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM)
SPKPORT .SET RTCIO ; SPK: THE PORT WITH THE SPEAKER IO BIT
SPKSHADOW .SET HB_RTCVAL ; SPK: THE SHADOW VALUE FOR THE PORT THAT HAS TO BE MAINTAINED
SPKMASK .SET %00000100 ; SPK: THE BIT MASK TO ACTUALLY TOGGLE
;
DMAENABLE .SET FALSE ; DMA: ENABLE DMA DRIVER (DMA.ASM)
DMABASE .SET $40 ; DMA: DMA BASE ADDRESS

View File

@@ -463,6 +463,9 @@ AYMODE .EQU AYMODE_NONE ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC
AY_FORCE .EQU FALSE ; AY: BYPASS AUTO-DETECT, FORCED PRESENT
;
SPKENABLE .EQU FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM)
SPKPORT .EQU RTCIO ; SPK: THE PORT WITH THE SPEAKER IO BIT
SPKSHADOW .EQU HB_RTCVAL ; SPK: THE SHADOW VALUE FOR THE PORT THAT HAS TO BE MAINTAINED
SPKMASK .EQU %00000100 ; SPK: THE BIT MASK TO ACTUALLY TOGGLE
;
DMAENABLE .EQU FALSE ; DMA: ENABLE DMA DRIVER (DMA.ASM)
DMABASE .EQU $E0 ; DMA: DMA BASE ADDRESS
@@ -500,3 +503,14 @@ EZ80_WSMD_TYP .EQU EZ80WSMD_CALC ; BUS WAIT STATE CONFIG: EZ80WSMD_[CALC|CYCLES]
EZ80_FLSH_WS .EQU 1 ; WAIT STATES FOR ON CHIP FLASH (0-7)
EZ80_FLSH_MIN_NS .EQU 60 ; MINIMUM WAIT STATES TO APPLY TO ON-CHIP FLASH, IF EZ80_WSMD_TYP = EZ80WSMD_CALC
EZ80_FWSMD_TYP .EQU EZ80WSMD_CALC ; WAIT STATE TYPE: EZ80RMMD_[CALC|WAIT] (CYCLES NOT ALLOWED)
CHNATIVEENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .EQU FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)
CHNATIVEFORCE .EQU FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED (REQUIRES CHNATIVEENABLE)
CHNATIVEEZ80 .EQU FALSE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE
_CH376_DATA_PORT .EQU $FF88 ; CH376: DATA PORT
_CH376_COMMAND_PORT .EQU $FF89 ; CH376: COMMAND PORT
_USB_MODULE_LEDS .EQU $FF8A ; CH376: LED CONTROL PORT

View File

@@ -362,6 +362,9 @@ AY_CLK .SET 1789772 ; AY: PSG CLOCK FREQ, ASSUME MSX STD
AYMODE .SET AYMODE_MBC ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC|MBC|DUO|NABU]
;
SPKENABLE .SET TRUE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM)
SPKPORT .SET RTCIO ; SPK: THE PORT WITH THE SPEAKER IO BIT
SPKSHADOW .SET HB_RTCVAL ; SPK: THE SHADOW VALUE FOR THE PORT THAT HAS TO BE MAINTAINED
SPKMASK .SET %00000100 ; SPK: THE BIT MASK TO ACTUALLY TOGGLE
;
DMAENABLE .SET FALSE ; DMA: ENABLE DMA DRIVER (DMA.ASM)
DMABASE .SET $E0 ; DMA: DMA BASE ADDRESS

View File

@@ -250,7 +250,7 @@ VDUENABLE .SET FALSE ; VDU: ENABLE VDU VIDEO/KBD DRIVER (VDU.ASM)
CVDUENABLE .SET FALSE ; CVDU: ENABLE CVDU VIDEO/KBD DRIVER (CVDU.ASM)
GDCENABLE .SET FALSE ; GDC: ENABLE 7220 GDC VIDEO/KBD DRIVER (GDC.ASM)
TMSENABLE .SET FALSE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM)
TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU]
TMSMODE .SET TMSMODE_MSX ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY]
TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958
TMSTIMENABLE .SET FALSE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1)
VGAENABLE .SET FALSE ; VGA: ENABLE VGA VIDEO/KBD DRIVER (VGA.ASM)
@@ -406,6 +406,12 @@ EZ80TMR_NONE .SET 0 ; DO NOT USE ON-BOARD TIMER TO GENERATE TICKS
EZ80TMR_INT .SET 1 ; MARSHALL TIMER TICK INTERRUPTS FROM EZ80 TO HBIOS
EZ80TMR_FIRM .SET 2 ; DELEGATE SYS TIMER HBIOS CALL TO EZ80 FIRMWARE (TIMER TICK INTS DISABLED)
;
CHNATIVEENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .SET FALSE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)
CHNATIVEFORCE .SET FALSE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED (REQUIRES CHNATIVEENABLE)
CHNATIVEEZ80 .SET TRUE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE
EZ80UARTENABLE .SET TRUE ; EZ80 UART: ENABLE EZ80 UART0 DRIVER (EZ80UART.ASM)
EZ80RTCENABLE .SET TRUE ; EZ80 ON CHIP RTC
EZ80TIMER .SET EZ80TMR_FIRM ; EZ80: TIMER TICK MODEL: EZ80TMR_[INT|FIRM]

View File

@@ -348,6 +348,9 @@ AYMODE .SET AYMODE_SCG ; AY: DRIVER MODE: AYMODE_[SCG|N8|RCZ80|RCZ180|MSX|LINC|
AY_FORCE .SET FALSE ; AY: BYPASS AUTO-DETECT, FORCED PRESENT
;
SPKENABLE .SET FALSE ; SPK: ENABLE RTC LATCH IOBIT SOUND DRIVER (SPK.ASM)
SPKPORT .SET RTCIO ; SPK: THE PORT WITH THE SPEAKER IO BIT
SPKSHADOW .SET HB_RTCVAL ; SPK: THE SHADOW VALUE FOR THE PORT THAT HAS TO BE MAINTAINED
SPKMASK .SET %00000100 ; SPK: THE BIT MASK TO ACTUALLY TOGGLE
;
DMAENABLE .SET FALSE ; DMA: ENABLE DMA DRIVER (DMA.ASM)
DMABASE .SET $E0 ; DMA: DMA BASE ADDRESS

View File

@@ -0,0 +1,107 @@
SHELL := /bin/sh
SHELLFLAGS := -c -e -x
.ONESHELL:
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --no-builtin-rules
MAKEFLAGS += --always-make
ZCCRELFLAGS := -SO3 --max-allocs-per-node600000 --allow-unsafe-read --opt-code-speed
SRC := ./source-doc/
LIBS := -I./$(SRC)base-drv/
ZCCFLAGS := +z80 -vn -startup=0 -clib=sdcc_iy -compiler=sdcc -Cs--std=c23 -Cs--Werror $(ZCCRELFLAGS) $(LIBS)
ZCC_PATH := $(shell command -v zcc)
DOCKER_PATH := $(shell command -v docker)
ZCC := $(shell command -v zcc >/dev/null 2>&1 && echo zcc || echo 'docker run -w /host/${PWD} -v /:/host/ -u $(shell id -u ${USER}):$(shell id -g ${USER}) -t z88dk/z88dk:20250224 zcc')
ifeq ($(ZCC_PATH),)
ifeq ($(DOCKER_PATH),)
.DEFAULT_GOAL := skip
else
$(info ZCC is set to use Docker to run zcc)
endif
else
$(info ZCC is set to $(ZCC_PATH))
endif
ASSDIR := ./
all: $(ASSDIR)base-drv.s $(ASSDIR)scsi-drv.s $(ASSDIR)ufi-drv.s $(ASSDIR)keyboard.s
skip:
@echo "Unable to compile ch376 native to assembly. Install docker or z88dk."
exit 0
clean:
@rm -rf base-drv/*.s
rm -rf base-drv/*.asm
rm -rf scsi-drv/*.s
rm -rf scsi-drv/*.asm
rm -rf ufi-drv/*.s
rm -rf ufi-drv/*.asm
rm -rf keyboard/*.s
rm -rf keyboard/*.asm
rm ufi-drv.s
rm scsi-drv.s
rm base-drv.s
rm keyboard.s
.PRECIOUS: $(ASSDIR)%.c.asm
$(ASSDIR)%.c.s: $(ASSDIR)%.c.asm
@mkdir -p $(dir $@)
echo "Converting $< to $@"
${SRC}convert-for-uz80as.sh $< $@
define compile
@set -e
mkdir -p $(dir $@)
$(ZCC) $(ZCCFLAGS) --c-code-in-asm --assemble-only $< -o $@
echo "Compiled $(notdir $@) from $(notdir $<)"
endef
FIRMWARE_ALT = kyb-init ch376_init scsi-init ufi-init hbios-driver-storage
define build_subsystem =
$$(ASSDIR)$(1).s:
@echo "Creating $(1).s"
echo "; Generated File -- not to be modify directly" > $$(ASSDIR)$(1).s
for dep in $$^; do
dep=$$$${dep#*/}
dep=$$$${dep#*/}
filename=$$$${dep##*/}
basename=$$$${filename%.*.*}
if echo "$(FIRMWARE_ALT)" | grep -w -q "$$$${basename}"; then
if [ -n "$$$${dep%%*.asm}" ]; then
echo '#include "'ch376-native/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s
else
echo '#include "'ch376-native/source-doc/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s
fi
else
echo '#IF (!CHNATIVEEZ80)' >> $$(ASSDIR)$(1).s
if [ -n "$$$${dep%%*.asm}" ]; then
echo '#include "'ch376-native/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s
else
echo '#include "'ch376-native/source-doc/$(1)/$$$${dep}'"' >> $$(ASSDIR)$(1).s
fi
echo '#ENDIF' >> $$(ASSDIR)$(1).s
fi
done
$$(ASSDIR)$(1)/%.c.asm: $$(SRC)$(1)/%.c; $$(compile)
# $$(ASSDIR)$(1)/%.asm: $$(SRC)$(1)/%.asm; echo $$@ $$<
$(1)_C_FILES := $$(wildcard $$(SRC)$(1)/*.c)
$(1)_ASM_FILES := $$(wildcard $$(SRC)$(1)/*.asm)
$(1)_C_S_FILES := $$(patsubst ./source-doc/%, ./%, $$($(1)_C_FILES:.c=.c.s))
./$(1).s: $$($(1)_C_S_FILES) $$($(1)_ASM_FILES)
endef
$(eval $(call build_subsystem,base-drv))
$(eval $(call build_subsystem,scsi-drv))
$(eval $(call build_subsystem,keyboard))
$(eval $(call build_subsystem,ufi-drv))
.PHONY: format
format: SHELL:=/bin/bash
format:
@find \( -name "*.c" -o -name "*.h" \) -exec echo "formating {}" \; -exec clang-format -i {} \;

View File

@@ -0,0 +1,106 @@
DELAY_FACTOR .EQU 640
CMD01_RD_USB_DATA0 .EQU $27 ; Read data block from current USB interrupt endpoint buffer or host endpoint receive buffer
; output: length, data stream
CMD10_WR_HOST_DATA .EQU $2C ; Write a data block to the send buffer of the USB host endpoint
; input: length, data stream
CH_CMD_RD_USB_DATA0 .EQU CMD01_RD_USB_DATA0
CH_CMD_WR_HOST_DATA .EQU CMD10_WR_HOST_DATA
; HL -> timeout
; returns
; L -> error code
; ---------------------------------
; Function ch_wait_int_and_get_status
; ---------------------------------
_ch_wait_and_get_status
ld bc, DELAY_FACTOR
keep_waiting:
ld a, $FF
in a, (_CH376_COMMAND_PORT & $FF)
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_and_get_status
call _delay
ld a, $FF
in a, (_CH376_COMMAND_PORT & $FF)
bit 4, a ; _CH376_COMMAND_PORT & PARA_STATE_BUSY
ld l, $0C ; USB_ERR_CH376_BLOCKED;
ret nz
ld l, $0D ; USB_ERR_CH376_TIMEOUT
ret
; uint8_t ch_read_data(uint8_t *buffer) __sdcccall(1);
_ch_read_data:
push hl
ld l, CH_CMD_RD_USB_DATA0
call _ch_command
pop hl
call _delay
ld bc, _CH376_DATA_PORT
in a, (c)
or a
ret z
ld e, a
push af
read_block:
call _delay
in a, (c)
ld (hl), a
inc hl
dec e
jr nz, read_block
pop af
ret
;const uint8_t *ch_write_data(const uint8_t *buffer, uint8_t length)
_ch_write_data:
ld l, CH_CMD_WR_HOST_DATA
call _ch_command
ld iy, 2
add iy, sp
ld l, (iy+0)
ld h, (iy+1)
ld a, (iy+2)
ld bc, _CH376_DATA_PORT
; _CH376_DATA_PORT = length;
call _delay
out (c), a
or a
ret z
ld d, a
write_block:
call _delay
ld a, (hl)
out (c), a
inc hl
dec d
jr nz, write_block
ret

View File

@@ -0,0 +1,39 @@
; Generated File -- not to be modify directly
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/ch376.c.s"
#ENDIF
#include "ch376-native/base-drv/ch376_init.c.s"
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/class_hub.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/critical-section.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/dev_transfers.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/enumerate.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/enumerate_hub.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/enumerate_storage.c.s"
#ENDIF
#include "ch376-native/base-drv/hbios-driver-storage.c.s"
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/protocol.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/transfers.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/usb-base-drv.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/usb_state.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/base-drv/work-area.c.s"
#ENDIF

View File

@@ -0,0 +1 @@
*.asm

View File

@@ -0,0 +1,769 @@
;
; Generated from source-doc/base-drv/ch376.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/ch376.c:6: void ch_command(const uint8_t command) __z88dk_fastcall {
; ---------------------------------
; Function ch_command
; ---------------------------------
_ch_command:
;source-doc/base-drv/ch376.c:8: while ((CH376_COMMAND_PORT & PARA_STATE_BUSY) && --counter != 0)
ld b,$ff
l_ch_command_00102:
ld a, +((_CH376_COMMAND_PORT) / 256)
in a, (((_CH376_COMMAND_PORT) & $FF))
bit 4, a
jr Z,l_ch_command_00104
djnz l_ch_command_00102
l_ch_command_00104:
;source-doc/base-drv/ch376.c:19: CH376_COMMAND_PORT = command;
ld a, l
ld bc,_CH376_COMMAND_PORT
out (c), a
;source-doc/base-drv/ch376.c:20: }
ret
;source-doc/base-drv/ch376.c:24: usb_error ch_long_get_status(void) { return ch_wait_and_get_status(5000); }
; ---------------------------------
; Function ch_long_get_status
; ---------------------------------
_ch_long_get_status:
ld hl,$1388
jp _ch_wait_and_get_status
;source-doc/base-drv/ch376.c:26: usb_error ch_short_get_status(void) { return ch_wait_and_get_status(100); }
; ---------------------------------
; Function ch_short_get_status
; ---------------------------------
_ch_short_get_status:
ld hl,$0064
jp _ch_wait_and_get_status
;source-doc/base-drv/ch376.c:28: usb_error ch_very_short_status(void) { return ch_wait_and_get_status(10); }
; ---------------------------------
; Function ch_very_short_status
; ---------------------------------
_ch_very_short_status:
ld hl,$000a
jp _ch_wait_and_get_status
;source-doc/base-drv/ch376.c:30: usb_error ch_get_status(void) {
; ---------------------------------
; Function ch_get_status
; ---------------------------------
_ch_get_status:
;source-doc/base-drv/ch376.c:31: ch_command(CH_CMD_GET_STATUS);
ld l,$22
call _ch_command
;source-doc/base-drv/ch376.c:32: uint8_t ch_status = CH376_DATA_PORT;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & $FF))
;source-doc/base-drv/ch376.c:34: if (ch_status >= USB_FILERR_MIN && ch_status <= USB_FILERR_MAX)
cp $41
jr C,l_ch_get_status_00102
cp $b5
jr NC,l_ch_get_status_00102
;source-doc/base-drv/ch376.c:35: return ch_status;
ld l, a
jr l_ch_get_status_00126
l_ch_get_status_00102:
;source-doc/base-drv/ch376.c:37: if (ch_status == CH_CMD_RET_SUCCESS)
cp $51
jr NZ,l_ch_get_status_00105
;source-doc/base-drv/ch376.c:38: return USB_ERR_OK;
ld l,$00
jr l_ch_get_status_00126
l_ch_get_status_00105:
;source-doc/base-drv/ch376.c:40: if (ch_status == CH_USB_INT_SUCCESS)
cp $14
jr NZ,l_ch_get_status_00107
;source-doc/base-drv/ch376.c:41: return USB_ERR_OK;
ld l,$00
jr l_ch_get_status_00126
l_ch_get_status_00107:
;source-doc/base-drv/ch376.c:43: if (ch_status == CH_USB_INT_CONNECT)
cp $15
jr NZ,l_ch_get_status_00109
;source-doc/base-drv/ch376.c:44: return USB_INT_CONNECT;
ld l,$81
jr l_ch_get_status_00126
l_ch_get_status_00109:
;source-doc/base-drv/ch376.c:46: if (ch_status == CH_USB_INT_DISK_READ)
cp $1d
jr NZ,l_ch_get_status_00111
;source-doc/base-drv/ch376.c:47: return USB_ERR_DISK_READ;
ld l,$1d
jr l_ch_get_status_00126
l_ch_get_status_00111:
;source-doc/base-drv/ch376.c:49: if (ch_status == CH_USB_INT_DISK_WRITE)
cp $1e
jr NZ,l_ch_get_status_00113
;source-doc/base-drv/ch376.c:50: return USB_ERR_DISK_WRITE;
ld l,$1e
jr l_ch_get_status_00126
l_ch_get_status_00113:
;source-doc/base-drv/ch376.c:52: if (ch_status == CH_USB_INT_DISCONNECT) {
cp $16
jr NZ,l_ch_get_status_00115
;source-doc/base-drv/ch376.c:53: ch_cmd_set_usb_mode(5);
ld l,$05
call _ch_cmd_set_usb_mode
;source-doc/base-drv/ch376.c:54: return USB_ERR_NO_DEVICE;
ld l,$05
jr l_ch_get_status_00126
l_ch_get_status_00115:
;source-doc/base-drv/ch376.c:57: if (ch_status == CH_USB_INT_BUF_OVER)
cp $17
jr NZ,l_ch_get_status_00117
;source-doc/base-drv/ch376.c:58: return USB_ERR_DATA_ERROR;
ld l,$04
jr l_ch_get_status_00126
l_ch_get_status_00117:
;source-doc/base-drv/ch376.c:60: ch_status &= $2F;
and $2f
;source-doc/base-drv/ch376.c:62: if (ch_status == $2A)
cp $2a
jr NZ,l_ch_get_status_00119
;source-doc/base-drv/ch376.c:63: return USB_ERR_NAK;
ld l,$01
jr l_ch_get_status_00126
l_ch_get_status_00119:
;source-doc/base-drv/ch376.c:65: if (ch_status == $2E)
cp $2e
jr NZ,l_ch_get_status_00121
;source-doc/base-drv/ch376.c:66: return USB_ERR_STALL;
ld l,$02
jr l_ch_get_status_00126
l_ch_get_status_00121:
;source-doc/base-drv/ch376.c:68: ch_status &= $23;
and $23
;source-doc/base-drv/ch376.c:70: if (ch_status == $20)
cp $20
jr NZ,l_ch_get_status_00123
;source-doc/base-drv/ch376.c:71: return USB_ERR_TIMEOUT;
ld l,$03
jr l_ch_get_status_00126
l_ch_get_status_00123:
;source-doc/base-drv/ch376.c:73: if (ch_status == $23)
sub $23
jr NZ,l_ch_get_status_00125
;source-doc/base-drv/ch376.c:74: return USB_TOKEN_OUT_OF_SYNC;
ld l,$07
jr l_ch_get_status_00126
l_ch_get_status_00125:
;source-doc/base-drv/ch376.c:76: return USB_ERR_UNEXPECTED_STATUS_FROM_;
ld l,$08
l_ch_get_status_00126:
;source-doc/base-drv/ch376.c:77: }
ret
;source-doc/base-drv/ch376.c:79: void ch_cmd_reset_all(void) { ch_command(CH_CMD_RESET_ALL); }
; ---------------------------------
; Function ch_cmd_reset_all
; ---------------------------------
_ch_cmd_reset_all:
ld l,$05
jp _ch_command
;source-doc/base-drv/ch376.c:98: uint8_t ch_probe(void) {
; ---------------------------------
; Function ch_probe
; ---------------------------------
_ch_probe:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/ch376.c:100: do {
ld (ix-1),$05
l_ch_probe_00103:
;source-doc/base-drv/ch376.c:83: ch_command(CH_CMD_CHECK_EXIST);
ld l,$06
call _ch_command
;source-doc/base-drv/ch376.c:84: CH376_DATA_PORT = (uint8_t)~$55;
ld a,$aa
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/ch376.c:85: delay();
call _delay
;source-doc/base-drv/ch376.c:86: complement = CH376_DATA_PORT;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & $FF))
;source-doc/base-drv/ch376.c:87: return complement == $55;
sub $55
jr NZ,l_ch_probe_00102
;source-doc/base-drv/ch376.c:101: if (ch_cmd_check_exist())
;source-doc/base-drv/ch376.c:102: return true;
ld l,$01
jr l_ch_probe_00107
l_ch_probe_00102:
;source-doc/base-drv/ch376.c:104: delay_medium();
call _delay_medium
;source-doc/base-drv/ch376.c:105: } while (--i != 0);
dec (ix-1)
jr NZ,l_ch_probe_00103
;source-doc/base-drv/ch376.c:107: return false;
ld l,$00
l_ch_probe_00107:
;source-doc/base-drv/ch376.c:108: }
inc sp
pop ix
ret
;source-doc/base-drv/ch376.c:110: usb_error ch_cmd_set_usb_mode(const uint8_t mode) __z88dk_fastcall {
; ---------------------------------
; Function ch_cmd_set_usb_mode
; ---------------------------------
_ch_cmd_set_usb_mode:
ld c, l
;source-doc/base-drv/ch376.c:111: uint8_t result = 0;
ld b,$00
;source-doc/base-drv/ch376.c:113: CH376_COMMAND_PORT = CH_CMD_SET_USB_MODE;
ld a,$15
push bc
ld bc,_CH376_COMMAND_PORT
out (c), a
;source-doc/base-drv/ch376.c:114: delay();
call _delay
pop bc
;source-doc/base-drv/ch376.c:115: CH376_DATA_PORT = mode;
ld a, c
push bc
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/ch376.c:116: delay();
call _delay
pop bc
;source-doc/base-drv/ch376.c:120: while (result != CH_CMD_RET_SUCCESS && result != CH_CMD_RET_ABORT && --count != 0) {
ld c,$7f
l_ch_cmd_set_usb_mode_00103:
ld a, b
sub $51
jr NZ,l_ch_cmd_set_usb_mode_00146
ld a,$01
jr l_ch_cmd_set_usb_mode_00147
l_ch_cmd_set_usb_mode_00146:
xor a
l_ch_cmd_set_usb_mode_00147:
ld e,a
bit 0,a
jr NZ,l_ch_cmd_set_usb_mode_00105
ld a, b
sub $5f
jr Z,l_ch_cmd_set_usb_mode_00105
dec c
jr Z,l_ch_cmd_set_usb_mode_00105
;source-doc/base-drv/ch376.c:121: result = CH376_DATA_PORT;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & $FF))
ld b, a
;source-doc/base-drv/ch376.c:122: delay();
push bc
call _delay
pop bc
jr l_ch_cmd_set_usb_mode_00103
l_ch_cmd_set_usb_mode_00105:
;source-doc/base-drv/ch376.c:125: return (result == CH_CMD_RET_SUCCESS) ? USB_ERR_OK : USB_ERR_FAIL;
ld a, e
or a
jr Z,l_ch_cmd_set_usb_mode_00108
ld l,$00
jr l_ch_cmd_set_usb_mode_00109
l_ch_cmd_set_usb_mode_00108:
ld l,$0e
l_ch_cmd_set_usb_mode_00109:
;source-doc/base-drv/ch376.c:126: }
ret
;source-doc/base-drv/ch376.c:128: uint8_t ch_cmd_get_ic_version(void) {
; ---------------------------------
; Function ch_cmd_get_ic_version
; ---------------------------------
_ch_cmd_get_ic_version:
;source-doc/base-drv/ch376.c:129: ch_command(CH_CMD_GET_IC_VER);
ld l,$01
call _ch_command
;source-doc/base-drv/ch376.c:130: return CH376_DATA_PORT & $1f;
ld a, +((_CH376_DATA_PORT) / 256)
in a, (((_CH376_DATA_PORT) & $FF))
and $1f
ld l, a
;source-doc/base-drv/ch376.c:131: }
ret
;source-doc/base-drv/ch376.c:133: void ch_issue_token(const uint8_t toggle_bit, const uint8_t endpoint, const ch376_pid pid) {
; ---------------------------------
; Function ch_issue_token
; ---------------------------------
_ch_issue_token:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/ch376.c:134: ch_command(CH_CMD_ISSUE_TKN_X);
ld l,$4e
call _ch_command
;source-doc/base-drv/ch376.c:135: CH376_DATA_PORT = toggle_bit;
ld a,(ix+4)
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/ch376.c:136: CH376_DATA_PORT = endpoint << 4 | pid;
ld a,(ix+5)
add a, a
add a, a
add a, a
add a, a
or (ix+6)
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/ch376.c:137: }
pop ix
ret
;source-doc/base-drv/ch376.c:139: void ch_issue_token_in(const endpoint_param *const endpoint) __z88dk_fastcall {
; ---------------------------------
; Function ch_issue_token_in
; ---------------------------------
_ch_issue_token_in:
;source-doc/base-drv/ch376.c:140: ch_issue_token(endpoint->toggle ? $80 : $00, endpoint->number, CH_PID_IN);
ld e,l
ld d,h
ld a, (hl)
rrca
and $07
ld b, a
ex de, hl
ld a, (hl)
and $01
jr Z,l_ch_issue_token_in_00103
ld a,$80
jr l_ch_issue_token_in_00104
l_ch_issue_token_in_00103:
xor a
l_ch_issue_token_in_00104:
ld h,$09
ld l,b
push hl
push af
inc sp
call _ch_issue_token
pop af
inc sp
;source-doc/base-drv/ch376.c:141: }
ret
;source-doc/base-drv/ch376.c:143: void ch_issue_token_out(const endpoint_param *const endpoint) __z88dk_fastcall {
; ---------------------------------
; Function ch_issue_token_out
; ---------------------------------
_ch_issue_token_out:
;source-doc/base-drv/ch376.c:144: ch_issue_token(endpoint->toggle ? $40 : $00, endpoint->number, CH_PID_OUT);
ld e,l
ld d,h
ld a, (hl)
rrca
and $07
ld b, a
ex de, hl
ld a, (hl)
and $01
jr Z,l_ch_issue_token_out_00103
ld a,$40
jr l_ch_issue_token_out_00104
l_ch_issue_token_out_00103:
xor a
l_ch_issue_token_out_00104:
ld h,$01
ld l,b
push hl
push af
inc sp
call _ch_issue_token
pop af
inc sp
;source-doc/base-drv/ch376.c:145: }
ret
;source-doc/base-drv/ch376.c:147: void ch_issue_token_out_ep0(void) { ch_issue_token($40, 0, CH_PID_OUT); }
; ---------------------------------
; Function ch_issue_token_out_ep0
; ---------------------------------
_ch_issue_token_out_ep0:
ld a,$01
push af
inc sp
xor a
ld d,a
ld e,$40
push de
call _ch_issue_token
pop af
inc sp
ret
;source-doc/base-drv/ch376.c:149: void ch_issue_token_in_ep0(void) { ch_issue_token($80, 0, CH_PID_IN); }
; ---------------------------------
; Function ch_issue_token_in_ep0
; ---------------------------------
_ch_issue_token_in_ep0:
ld a,$09
push af
inc sp
xor a
ld d,a
ld e,$80
push de
call _ch_issue_token
pop af
inc sp
ret
;source-doc/base-drv/ch376.c:151: void ch_issue_token_setup(void) { ch_issue_token(0, 0, CH_PID_SETUP); }
; ---------------------------------
; Function ch_issue_token_setup
; ---------------------------------
_ch_issue_token_setup:
ld a,$0d
push af
inc sp
xor a
push af
inc sp
xor a
push af
inc sp
call _ch_issue_token
pop af
inc sp
ret
;source-doc/base-drv/ch376.c:153: usb_error ch_data_in_transfer(uint8_t *buffer, int16_t buffer_size, endpoint_param *const endpoint) {
; ---------------------------------
; Function ch_data_in_transfer
; ---------------------------------
_ch_data_in_transfer:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/ch376.c:157: if (buffer_size == 0)
ld a,(ix+7)
or (ix+6)
jr NZ,l_ch_data_in_transfer_00102
;source-doc/base-drv/ch376.c:158: return USB_ERR_OK;
ld l,$00
jp l_ch_data_in_transfer_00111
l_ch_data_in_transfer_00102:
;source-doc/base-drv/ch376.c:160: USB_MODULE_LEDS = $01;
ld a,$01
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:161: do {
ld c,(ix+8)
ld b,(ix+9)
l_ch_data_in_transfer_00107:
;source-doc/base-drv/ch376.c:162: ch_issue_token_in(endpoint);
ld l,c
ld h,b
push hl
call _ch_issue_token_in
;source-doc/base-drv/ch376.c:164: result = ch_long_get_status();
call _ch_long_get_status
ld a, l
pop bc
ld l, a
;source-doc/base-drv/ch376.c:165: CHECK(result);
or a
jr NZ,l_ch_data_in_transfer_00110
;source-doc/base-drv/ch376.c:167: endpoint->toggle = !endpoint->toggle;
ld e, c
ld d, b
ld l, e
ld h, d
ld a, (hl)
and $01
xor $01
and $01
ld l, a
ld a, (de)
and $fe
or l
ld (de), a
;source-doc/base-drv/ch376.c:169: count = ch_read_data(buffer);
push bc
ld l,(ix+4)
ld h,(ix+5)
call _ch_read_data
ld e, a
pop bc
;source-doc/base-drv/ch376.c:171: if (count == 0) {
ld a, e
;source-doc/base-drv/ch376.c:172: USB_MODULE_LEDS = $00;
or a
jr NZ,l_ch_data_in_transfer_00106
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:173: return USB_ERR_DATA_ERROR;
ld l,$04
jr l_ch_data_in_transfer_00111
l_ch_data_in_transfer_00106:
;source-doc/base-drv/ch376.c:176: buffer += count;
ld a,(ix+4)
add a, e
ld (ix+4),a
jr NC,l_ch_data_in_transfer_00148
inc (ix+5)
l_ch_data_in_transfer_00148:
;source-doc/base-drv/ch376.c:177: buffer_size -= count;
ld d,$00
ld a,(ix+6)
sub e
ld (ix+6),a
ld a,(ix+7)
sbc a, d
ld (ix+7),a
;source-doc/base-drv/ch376.c:178: } while (buffer_size > 0);
xor a
cp (ix+6)
sbc a,(ix+7)
jp PO, l_ch_data_in_transfer_00149
xor $80
l_ch_data_in_transfer_00149:
jp M, l_ch_data_in_transfer_00107
;source-doc/base-drv/ch376.c:180: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:181: return USB_ERR_OK;
ld l,$00
jr l_ch_data_in_transfer_00111
;source-doc/base-drv/ch376.c:183: done:
l_ch_data_in_transfer_00110:
;source-doc/base-drv/ch376.c:184: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:185: return result;
l_ch_data_in_transfer_00111:
;source-doc/base-drv/ch376.c:186: }
pop ix
ret
;source-doc/base-drv/ch376.c:189: usb_error ch_data_in_transfer_n(uint8_t *const buffer, uint8_t *const buffer_size, endpoint_param *const endpoint) {
; ---------------------------------
; Function ch_data_in_transfer_n
; ---------------------------------
_ch_data_in_transfer_n:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/ch376.c:193: USB_MODULE_LEDS = $01;
ld a,$01
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:195: ch_issue_token_in(endpoint);
ld l,(ix+8)
ld h,(ix+9)
call _ch_issue_token_in
;source-doc/base-drv/ch376.c:197: CHECK(ch_long_get_status());
call _ch_long_get_status
ld a,l
or a
jr NZ,l_ch_data_in_transfer_n_00103
;source-doc/base-drv/ch376.c:199: endpoint->toggle = !endpoint->toggle;
ld l,(ix+8)
ld h,(ix+9)
ld a, (hl)
and $01
xor $01
and $01
ld c, a
ld a, (hl)
and $fe
or c
ld (hl), a
;source-doc/base-drv/ch376.c:201: count = ch_read_data(buffer);
ld l,(ix+4)
ld h,(ix+5)
call _ch_read_data
;source-doc/base-drv/ch376.c:203: *buffer_size = count;
ld c,(ix+6)
ld b,(ix+7)
ld (bc), a
;source-doc/base-drv/ch376.c:205: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:207: return USB_ERR_OK;
ld l,$00
jr l_ch_data_in_transfer_n_00104
;source-doc/base-drv/ch376.c:208: done:
l_ch_data_in_transfer_n_00103:
;source-doc/base-drv/ch376.c:209: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:210: return result;
l_ch_data_in_transfer_n_00104:
;source-doc/base-drv/ch376.c:211: }
pop ix
ret
;source-doc/base-drv/ch376.c:213: usb_error ch_data_out_transfer(const uint8_t *buffer, int16_t buffer_length, endpoint_param *const endpoint) {
; ---------------------------------
; Function ch_data_out_transfer
; ---------------------------------
_ch_data_out_transfer:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/ch376.c:216: const uint8_t max_packet_size = calc_max_packet_size(endpoint->max_packet_sizex);
ld c,(ix+8)
ld b,(ix+9)
ld e, c
ld d, b
inc de
ld a, (de)
ld (ix-1),a
;source-doc/base-drv/ch376.c:218: USB_MODULE_LEDS = $02;
ld a,$02
push bc
ld bc,_USB_MODULE_LEDS
out (c), a
pop bc
;source-doc/base-drv/ch376.c:220: while (buffer_length > 0) {
l_ch_data_out_transfer_00103:
xor a
cp (ix+6)
sbc a,(ix+7)
jp PO, l_ch_data_out_transfer_00139
xor $80
l_ch_data_out_transfer_00139:
jp P, l_ch_data_out_transfer_00105
;source-doc/base-drv/ch376.c:221: const uint8_t size = max_packet_size < buffer_length ? max_packet_size : buffer_length;
ld d,(ix-1)
ld e,$00
ld a, d
sub (ix+6)
ld a, e
sbc a,(ix+7)
jp PO, l_ch_data_out_transfer_00140
xor $80
l_ch_data_out_transfer_00140:
jp P, l_ch_data_out_transfer_00109
jr l_ch_data_out_transfer_00110
l_ch_data_out_transfer_00109:
ld d,(ix+6)
ld e,(ix+7)
l_ch_data_out_transfer_00110:
;source-doc/base-drv/ch376.c:222: buffer = ch_write_data(buffer, size);
push bc
push de
push de
inc sp
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ch_write_data
pop af
inc sp
pop de
pop bc
ld (ix+4),l
ld (ix+5),h
;source-doc/base-drv/ch376.c:223: buffer_length -= size;
ld e,$00
ld a,(ix+6)
sub d
ld (ix+6),a
ld a,(ix+7)
sbc a, e
ld (ix+7),a
;source-doc/base-drv/ch376.c:224: ch_issue_token_out(endpoint);
ld l,c
ld h,b
push hl
call _ch_issue_token_out
;source-doc/base-drv/ch376.c:226: CHECK(ch_long_get_status());
call _ch_long_get_status
ld a, l
pop bc
ld l, a
or a
jr NZ,l_ch_data_out_transfer_00106
;source-doc/base-drv/ch376.c:228: endpoint->toggle = !endpoint->toggle;
ld e, c
ld d, b
ld l, e
ld h, d
ld a, (hl)
and $01
xor $01
and $01
ld l, a
ld a, (de)
and $fe
or l
ld (de), a
jr l_ch_data_out_transfer_00103
l_ch_data_out_transfer_00105:
;source-doc/base-drv/ch376.c:231: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:232: return USB_ERR_OK;
ld l,$00
jr l_ch_data_out_transfer_00107
;source-doc/base-drv/ch376.c:234: done:
l_ch_data_out_transfer_00106:
;source-doc/base-drv/ch376.c:235: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/ch376.c:236: return result;
l_ch_data_out_transfer_00107:
;source-doc/base-drv/ch376.c:237: }
inc sp
pop ix
ret
;source-doc/base-drv/ch376.c:239: void ch_set_usb_address(const uint8_t device_address) __z88dk_fastcall {
; ---------------------------------
; Function ch_set_usb_address
; ---------------------------------
_ch_set_usb_address:
;source-doc/base-drv/ch376.c:240: ch_command(CH_CMD_SET_USB_ADDR);
push hl
ld l,$13
call _ch_command
pop hl
;source-doc/base-drv/ch376.c:241: CH376_DATA_PORT = device_address;
ld a, l
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/ch376.c:242: }
ret

View File

@@ -0,0 +1,319 @@
;
; Generated from source-doc/base-drv/ch376_init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/ch376_init.c:4: static uint16_t wait_for_state(const uint8_t loop_counter, uint8_t state, const uint8_t desired_state) __sdcccall(1) {
; ---------------------------------
; Function wait_for_state
; ---------------------------------
_wait_for_state:
push ix
ld ix,0
add ix,sp
dec sp
ld (ix-1),a
;source-doc/base-drv/ch376_init.c:5: uint16_t r = state;
ld c,l
ld e,l
;source-doc/base-drv/ch376_init.c:7: for (uint8_t i = 0; i < loop_counter; i++) {
ld d,$00
ld b,d
l_wait_for_state_00108:
ld a, b
sub (ix-1)
jr NC,l_wait_for_state_00106
;source-doc/base-drv/ch376_init.c:8: if (state == desired_state)
ld a,(ix+4)
sub c
jr Z,l_wait_for_state_00106
;source-doc/base-drv/ch376_init.c:11: if (i & 1)
bit 0, b
jr Z,l_wait_for_state_00104
;source-doc/base-drv/ch376_init.c:12: print_string("\b $");
push bc
ld hl,ch376_init_str_0
call _print_string
pop bc
jr l_wait_for_state_00105
l_wait_for_state_00104:
;source-doc/base-drv/ch376_init.c:14: print_string("\b*$");
push bc
ld hl,ch376_init_str_1
call _print_string
pop bc
l_wait_for_state_00105:
;source-doc/base-drv/ch376_init.c:16: r = usb_init(state);
push bc
ld l, c
call _usb_init
ex de, hl
pop bc
;source-doc/base-drv/ch376_init.c:17: state = r & 255;
ld c, e
;source-doc/base-drv/ch376_init.c:7: for (uint8_t i = 0; i < loop_counter; i++) {
inc b
jr l_wait_for_state_00108
l_wait_for_state_00106:
;source-doc/base-drv/ch376_init.c:20: return r;
;source-doc/base-drv/ch376_init.c:21: }
inc sp
pop ix
pop hl
inc sp
jp (hl)
ch376_init_str_0:
DEFB $08
DEFM " $"
DEFB $00
ch376_init_str_1:
DEFB $08
DEFM "*$"
DEFB $00
;source-doc/base-drv/ch376_init.c:33: static void _chnative_init(bool forced) {
; ---------------------------------
; Function _chnative_init
; ---------------------------------
__chnative_init:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/base-drv/ch376_init.c:36: const uint8_t loop_counter = forced ? 40 : 5;
bit 0,(ix+4)
jr Z,l__chnative_init_00113
ld a,$28
jr l__chnative_init_00114
l__chnative_init_00113:
ld a,$05
l__chnative_init_00114:
ld (ix-1),a
;source-doc/base-drv/ch376_init.c:38: print_string("\r\nCH376: IO=0x$");
ld hl,ch376_init_str_2
call _print_string
;source-doc/base-drv/ch376_init.c:39: print_hex((uint8_t)&CH376_DAT_PORT_ADDR);
ld l, +((_CH376_DAT_PORT_ADDR) & $FF)
call _print_hex
;source-doc/base-drv/ch376_init.c:40: print_string(comma_0_x_dollar);
ld hl,_comma_0_x_dollar
call _print_string
;source-doc/base-drv/ch376_init.c:41: print_hex((uint8_t)&CH376_CMD_PORT_ADDR);
ld l, +((_CH376_CMD_PORT_ADDR) & $FF)
call _print_hex
;source-doc/base-drv/ch376_init.c:42: print_string(comma_0_x_dollar);
ld hl,_comma_0_x_dollar
call _print_string
;source-doc/base-drv/ch376_init.c:43: print_hex((uint8_t)&USB_MOD_LEDS_ADDR);
ld l, +((_USB_MOD_LEDS_ADDR) & $FF)
call _print_hex
;source-doc/base-drv/ch376_init.c:44: print_string(" *$");
ld hl,ch376_init_str_3
call _print_string
;source-doc/base-drv/ch376_init.c:46: r = wait_for_state(loop_counter, state, 1);
ld a,$01
push af
inc sp
ld l,$00
ld a,(ix-1)
call _wait_for_state
;source-doc/base-drv/ch376_init.c:47: state = r & 255;
;source-doc/base-drv/ch376_init.c:49: print_string("\bPRESENT (VER $");
push de
ld hl,ch376_init_str_4
call _print_string
pop de
;source-doc/base-drv/ch376_init.c:51: r = usb_init(state);
ld l, e
call _usb_init
ex de, hl
;source-doc/base-drv/ch376_init.c:52: state = r & 255;
ld c, e
;source-doc/base-drv/ch376_init.c:53: if (state != 2) {
ld a, c
sub $02
jr Z,l__chnative_init_00102
;source-doc/base-drv/ch376_init.c:54: print_string("\rCH376: $");
ld hl,ch376_init_str_5
call _print_string
;source-doc/base-drv/ch376_init.c:55: print_string("VERSION FAILURE\r\n$");
ld hl,ch376_init_str_6
call _print_string
;source-doc/base-drv/ch376_init.c:56: return;
jr l__chnative_init_00111
l__chnative_init_00102:
;source-doc/base-drv/ch376_init.c:59: print_hex(r >> 8);
push bc
ld l, d
call _print_hex
;source-doc/base-drv/ch376_init.c:60: print_string(ch376_driver_version);
ld hl,_ch376_driver_version
call _print_string
;source-doc/base-drv/ch376_init.c:62: print_string("USB: *$");
ld hl,ch376_init_str_7
call _print_string
pop bc
;source-doc/base-drv/ch376_init.c:64: r = wait_for_state(loop_counter, state, 3);
ld a,$03
push af
inc sp
ld l, c
ld a,(ix-1)
call _wait_for_state
;source-doc/base-drv/ch376_init.c:65: state = r & 255;
;source-doc/base-drv/ch376_init.c:67: if (state == 2) {
ld a, e
sub $02
jr NZ,l__chnative_init_00104
;source-doc/base-drv/ch376_init.c:68: print_string("\bDISCONNECTED$");
ld hl,ch376_init_str_8
call _print_string
;source-doc/base-drv/ch376_init.c:69: return;
jr l__chnative_init_00111
l__chnative_init_00104:
;source-doc/base-drv/ch376_init.c:72: print_string("\bCONNECTED$");
push de
ld hl,ch376_init_str_9
call _print_string
pop de
;source-doc/base-drv/ch376_init.c:75: r = usb_init(state);
ld l, e
call _usb_init
ex de, hl
;source-doc/base-drv/ch376_init.c:76: state = r & 255;
ld c, e
;source-doc/base-drv/ch376_init.c:78: for (uint8_t i = 0; i < loop_counter; i++) {
ld b,$00
l__chnative_init_00109:
ld a, b
sub (ix-1)
jr NC,l__chnative_init_00111
;source-doc/base-drv/ch376_init.c:79: if (r >> 8 != 0)
ld a,$00
or d
jr NZ,l__chnative_init_00111
;source-doc/base-drv/ch376_init.c:82: print_string(".$");
push bc
ld hl,ch376_init_str_10
call _print_string
pop bc
;source-doc/base-drv/ch376_init.c:83: r = usb_init(state);
push bc
ld l, c
call _usb_init
ex de, hl
pop bc
;source-doc/base-drv/ch376_init.c:84: state = r & 255;
ld c, e
;source-doc/base-drv/ch376_init.c:78: for (uint8_t i = 0; i < loop_counter; i++) {
inc b
jr l__chnative_init_00109
l__chnative_init_00111:
;source-doc/base-drv/ch376_init.c:86: }
inc sp
pop ix
ret
_comma_0_x_dollar:
DEFB +$20
DEFB +$30
DEFB +$78
DEFB +$24
ch376_init_str_2:
DEFB $0d
DEFB $0a
DEFM "CH376: IO=0x$"
DEFB $00
ch376_init_str_3:
DEFM " *$"
DEFB $00
ch376_init_str_4:
DEFB $08
DEFM "PRESENT (VER $"
DEFB $00
ch376_init_str_5:
DEFB $0d
DEFM "CH376: $"
DEFB $00
ch376_init_str_6:
DEFM "VERSION FAILURE"
DEFB $0d
DEFB $0a
DEFM "$"
DEFB $00
ch376_init_str_7:
DEFM "USB: *$"
DEFB $00
ch376_init_str_8:
DEFB $08
DEFM "DISCONNECTED$"
DEFB $00
ch376_init_str_9:
DEFB $08
DEFM "CONNECTED$"
DEFB $00
ch376_init_str_10:
DEFM ".$"
DEFB $00
;source-doc/base-drv/ch376_init.c:88: void chnative_init_force(void) { _chnative_init(true); }
; ---------------------------------
; Function chnative_init_force
; ---------------------------------
_chnative_init_force:
ld a,$01
push af
inc sp
call __chnative_init
inc sp
ret
;source-doc/base-drv/ch376_init.c:90: void chnative_init(void) { _chnative_init(false); }
; ---------------------------------
; Function chnative_init
; ---------------------------------
_chnative_init:
xor a
push af
inc sp
call __chnative_init
inc sp
ret

View File

@@ -0,0 +1,85 @@
;
; Generated from source-doc/base-drv/class_hub.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/class_hub.c:7: usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1) {
; ---------------------------------
; Function hub_get_descriptor
; ---------------------------------
_hub_get_descriptor:
;source-doc/base-drv/class_hub.c:8: return usb_control_transfer(&cmd_get_hub_descriptor, hub_description, hub_config->address, hub_config->max_packet_size);
ld a,l
ld c,h
inc hl
ld b, (hl)
ld l, a
ld h, c
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
ld c, a
push bc
push de
ld hl,_cmd_get_hub_descriptor
push hl
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
;source-doc/base-drv/class_hub.c:9: }
ret
_cmd_get_hub_descriptor:
DEFB +$a0
DEFB +$06
DEFB +$00
DEFB +$29
DEFB +$00
DEFB +$00
DEFW +$0008

View File

@@ -0,0 +1,67 @@
;
; Generated from source-doc/base-drv/critical-section.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_in_critical_usb_section:
DEFS 1
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/critical-section.c:6: void critical_begin() { in_critical_usb_section++; }
; ---------------------------------
; Function critical_begin
; ---------------------------------
_critical_begin:
ld hl,_in_critical_usb_section
inc (hl)
ret
;source-doc/base-drv/critical-section.c:8: void critical_end() { in_critical_usb_section--; }
; ---------------------------------
; Function critical_end
; ---------------------------------
_critical_end:
ld hl,_in_critical_usb_section
dec (hl)
ret
_in_critical_usb_section:
DEFB +$00

View File

@@ -0,0 +1,449 @@
;
; Generated from source-doc/base-drv/dev_transfers.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/dev_transfers.c:23: * See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
; ---------------------------------
; Function usbdev_control_transfer
; ---------------------------------
_usbdev_control_transfer:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/dev_transfers.c:24: *
ld l,(ix+4)
ld h,(ix+5)
ld e,l
ld d,h
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
ld e,(ix+8)
ld d,(ix+9)
ld c,a
push bc
push de
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_control_transfer
pop af
pop af
pop af
;source-doc/base-drv/dev_transfers.c:25: * @param device the usb device
pop ix
ret
;source-doc/base-drv/dev_transfers.c:27: * @param buffer Pointer of data to send or receive into
; ---------------------------------
; Function usbdev_blk_out_trnsfer
; ---------------------------------
_usbdev_blk_out_trnsfer:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/dev_transfers.c:30: usb_error usbdev_control_transfer(device_config *const device, const setup_packet *const cmd_packet, uint8_t *const buffer) {
ld c,(ix+4)
ld b,(ix+5)
ld e, c
ld d, b
inc de
inc de
inc de
;source-doc/base-drv/dev_transfers.c:32: }
pop hl
ld l,c
ld h,b
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
push bc
push de
push de
push af
inc sp
ld l,(ix+8)
ld h,(ix+9)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/dev_transfers.c:34: usb_error usbdev_blk_out_trnsfer(device_config *const dev, const uint8_t *const buffer, const uint16_t buffer_size) {
ld a, l
sub $02
jr NZ,l_usbdev_blk_out_trnsfer_00102
;source-doc/base-drv/dev_transfers.c:35: usb_error result;
inc bc
ld a, (bc)
ld b, a
pop hl
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
ld c, a
ld l, e
ld h, d
ld a, (hl)
rrca
and $07
push de
push bc
inc sp
ld h, c
ld l,a
push hl
call _usbtrn_clr_ep_halt
pop af
inc sp
pop de
;source-doc/base-drv/dev_transfers.c:36:
ex de, hl
res 0, (hl)
;source-doc/base-drv/dev_transfers.c:37: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_OUT];
ld l,$02
;source-doc/base-drv/dev_transfers.c:43: endpoint->toggle = 0;
l_usbdev_blk_out_trnsfer_00102:
;source-doc/base-drv/dev_transfers.c:44: return USB_ERR_STALL;
ld sp, ix
pop ix
ret
;source-doc/base-drv/dev_transfers.c:46:
; ---------------------------------
; Function usbdev_bulk_in_transfer
; ---------------------------------
_usbdev_bulk_in_transfer:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/dev_transfers.c:49: done:
ld c,(ix+4)
ld b,(ix+5)
ld hl,$0006
add hl, bc
;source-doc/base-drv/dev_transfers.c:51: }
pop de
ld e,c
ld d,b
ex de,hl
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
push bc
push de
push de
push af
inc sp
ld l,(ix+8)
ld h,(ix+9)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_in_transfer_n
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/dev_transfers.c:53: usb_error usbdev_bulk_in_transfer(device_config *const dev, uint8_t *const buffer, uint8_t *const buffer_size) {
ld a, l
sub $02
jr NZ,l_usbdev_bulk_in_transfer_00102
;source-doc/base-drv/dev_transfers.c:54: usb_error result;
inc bc
ld a, (bc)
ld b, a
pop hl
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
ld c, a
ld l, e
ld h, d
ld a, (hl)
rrca
and $07
push de
push bc
inc sp
ld h, c
ld l,a
push hl
call _usbtrn_clr_ep_halt
pop af
inc sp
pop de
;source-doc/base-drv/dev_transfers.c:55:
ex de, hl
res 0, (hl)
;source-doc/base-drv/dev_transfers.c:56: endpoint_param *const endpoint = &dev->endpoints[ENDPOINT_BULK_IN];
ld l,$02
;source-doc/base-drv/dev_transfers.c:61: usbtrn_clr_ep_halt(endpoint->number, dev->address, dev->max_packet_size);
l_usbdev_bulk_in_transfer_00102:
;source-doc/base-drv/dev_transfers.c:62: endpoint->toggle = 0;
ld sp, ix
pop ix
ret
;source-doc/base-drv/dev_transfers.c:64: }
; ---------------------------------
; Function usbdev_dat_in_trnsfer
; ---------------------------------
_usbdev_dat_in_trnsfer:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/dev_transfers.c:70:
ld c,(ix+4)
ld b,(ix+5)
ld e, c
ld d, b
inc de
inc de
inc de
push de
ld a,(ix+10)
ld e, a
add a, a
add a, e
pop de
add a, e
ld e, a
ld a,$00
adc a, d
ld d, a
;source-doc/base-drv/dev_transfers.c:72: uint8_t *const buffer,
pop hl
ld l,c
ld h,b
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
push bc
push de
push de
push af
inc sp
ld l,(ix+8)
ld h,(ix+9)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/dev_transfers.c:74: const usb_endpoint_type endpoint_type) {
ld a, l
sub $02
jr NZ,l_usbdev_dat_in_trnsfer_00102
;source-doc/base-drv/dev_transfers.c:75: usb_error result;
inc bc
ld a, (bc)
ld b, a
pop hl
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
ld c, a
ld l, e
ld h, d
ld a, (hl)
rrca
and $07
push de
push bc
inc sp
ld h, c
ld l,a
push hl
call _usbtrn_clr_ep_halt
pop af
inc sp
pop de
;source-doc/base-drv/dev_transfers.c:76:
ex de, hl
res 0, (hl)
;source-doc/base-drv/dev_transfers.c:77: endpoint_param *const endpoint = &device->endpoints[endpoint_type];
ld l,$02
;source-doc/base-drv/dev_transfers.c:82: usbtrn_clr_ep_halt(endpoint->number, device->address, device->max_packet_size);
l_usbdev_dat_in_trnsfer_00102:
;source-doc/base-drv/dev_transfers.c:83: endpoint->toggle = 0;
ld sp, ix
pop ix
ret
;source-doc/base-drv/dev_transfers.c:85: }
; ---------------------------------
; Function usbdev_dat_in_trnsfer_0
; ---------------------------------
_usbdev_dat_in_trnsfer_0:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/dev_transfers.c:88: done:
ld c,(ix+4)
ld b,(ix+5)
ld e, c
ld d, b
inc de
inc de
inc de
;source-doc/base-drv/dev_transfers.c:90: }
pop hl
ld l,c
ld h,b
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
ld l,(ix+8)
ld h,$00
push bc
push de
push de
push af
inc sp
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
pop de
pop bc
;source-doc/base-drv/dev_transfers.c:92: usb_error usbdev_dat_in_trnsfer_0(device_config *const device, uint8_t *const buffer, const uint8_t buffer_size) {
ld a, l
sub $02
jr NZ,l_usbdev_dat_in_trnsfer_0_00102
;source-doc/base-drv/dev_transfers.c:93: usb_error result;
inc bc
ld a, (bc)
ld b, a
pop hl
ld a,(hl)
push hl
rlca
rlca
rlca
rlca
and $0f
ld c, a
ld l, e
ld h, d
ld a, (hl)
rrca
and $07
push de
push bc
inc sp
ld h, c
ld l,a
push hl
call _usbtrn_clr_ep_halt
pop af
inc sp
pop de
;source-doc/base-drv/dev_transfers.c:94:
ex de, hl
res 0, (hl)
;source-doc/base-drv/dev_transfers.c:95: endpoint_param *const endpoint = &device->endpoints[0];
ld l,$02
;source-doc/base-drv/dev_transfers.c:98:
l_usbdev_dat_in_trnsfer_0_00102:
;source-doc/base-drv/dev_transfers.c:99: if (result == USB_ERR_STALL) {
ld sp, ix
pop ix
ret

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -0,0 +1,142 @@
;
; Generated from source-doc/base-drv/enumerate_storage.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/enumerate_storage.c:5: void parse_endpoints(device_config_storage *const storage_dev, const endpoint_descriptor const *pEndpoint) {
; ---------------------------------
; Function parse_endpoints
; ---------------------------------
_parse_endpoints:
push ix
ld ix,0
add ix,sp
push af
;source-doc/base-drv/enumerate_storage.c:7: if (!(pEndpoint->bmAttributes & $02))
ld l,(ix+6)
ld h,(ix+7)
ld c,l
ld b,h
inc hl
inc hl
inc hl
ld a, (hl)
ld (ix-2),a
bit 1,a
;source-doc/base-drv/enumerate_storage.c:8: return;
jr Z,l_parse_endpoints_00108
;source-doc/base-drv/enumerate_storage.c:10: const uint8_t x = calc_max_packet_sizex(pEndpoint->wMaxPacketSize);
ld hl,4
add hl,bc
ld a, (hl)
ld (ix-1),a
;source-doc/base-drv/enumerate_storage.c:11: endpoint_param *const eps = storage_dev->endpoints;
ld e,(ix+4)
ld d,(ix+5)
inc de
inc de
inc de
;source-doc/base-drv/enumerate_storage.c:15: if (!(pEndpoint->bEndpointAddress & $80))
inc bc
inc bc
ld a, (bc)
ld c,a
and $80
ld b,$00
;source-doc/base-drv/enumerate_storage.c:14: if (pEndpoint->bmAttributes & $01) { // 3 -> Interrupt
bit 0,(ix-2)
jr Z,l_parse_endpoints_00106
;source-doc/base-drv/enumerate_storage.c:15: if (!(pEndpoint->bEndpointAddress & $80))
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,$0006
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 & $80) ? &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 & $07;
ld l, e
ld h, d
ld a, c
and $07
rlca
and $0e
ld c, a
ld a, (hl)
and $f1
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,$00
ld (de), a
inc de
ld a, b
and $03
ld l, a
ld a, (de)
and $fc
or l
ld (de), a
l_parse_endpoints_00108:
;source-doc/base-drv/enumerate_storage.c:27: }
ld sp, ix
pop ix
ret

View File

@@ -0,0 +1,97 @@
;
; Generated from source-doc/base-drv/hbios-driver-storage.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_hbios_usbstore_devs:
DEFS 12
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/hbios-driver-storage.c:5: uint8_t find_storage_dev(void) {
; ---------------------------------
; Function find_storage_dev
; ---------------------------------
_find_storage_dev:
;source-doc/base-drv/hbios-driver-storage.c:6: for (uint8_t i = 0; i < MAX_NUMBER_OF_DEVICES; i++)
ld c,$00
ld de,_hbios_usbstore_devs+0
ld b,c
l_find_storage_dev_00105:
ld a, b
sub $06
jr NC,l_find_storage_dev_00103
;source-doc/base-drv/hbios-driver-storage.c:7: if (hbios_usbstore_devs[i].drive_index == 0)
ld l, b
ld h,$00
add hl, hl
add hl, de
ld a, (hl)
or a
jr NZ,l_find_storage_dev_00106
;source-doc/base-drv/hbios-driver-storage.c:8: return i;
ld l, c
jr l_find_storage_dev_00107
l_find_storage_dev_00106:
;source-doc/base-drv/hbios-driver-storage.c:6: for (uint8_t i = 0; i < MAX_NUMBER_OF_DEVICES; i++)
inc b
ld c, b
jr l_find_storage_dev_00105
l_find_storage_dev_00103:
;source-doc/base-drv/hbios-driver-storage.c:10: return -1;
ld l,$ff
l_find_storage_dev_00107:
;source-doc/base-drv/hbios-driver-storage.c:11: }
ret
_hbios_usbstore_devs:
DEFB +$00
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00

View File

@@ -0,0 +1,482 @@
;
; Generated from source-doc/base-drv/protocol.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/protocol.c:25: *
; ---------------------------------
; Function usbtrn_get_descriptor
; ---------------------------------
_usbtrn_get_descriptor:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/protocol.c:28: */
ld hl,0
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_get_dev_descriptr
ldir
;source-doc/base-drv/protocol.c:29: usb_error usbtrn_get_descriptor(device_descriptor *const buffer) {
ld (ix-2),$08
xor a
ld (ix-1),a
;source-doc/base-drv/protocol.c:31: setup_packet cmd;
ld c,(ix+4)
ld b,(ix+5)
push bc
push bc
ld e,c
ld d,b
ld a,$08
push af
inc sp
xor a
push af
inc sp
push de
ld hl,8
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
pop de
pop bc
ld l, a
;source-doc/base-drv/protocol.c:33: cmd.wLength = 8;
or a
jr NZ,l_usbtrn_get_descriptor_00103
;source-doc/base-drv/protocol.c:35: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, 8);
push de
push bc
ld hl,4
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_get_dev_descriptr
ldir
pop bc
pop de
;source-doc/base-drv/protocol.c:36:
ld (ix-2),$12
xor a
ld (ix-1),a
;source-doc/base-drv/protocol.c:37: CHECK(result);
ld hl,7
add hl, bc
ld a, (hl)
push af
inc sp
xor a
push af
inc sp
push de
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
;source-doc/base-drv/protocol.c:41: result = usb_control_transfer(&cmd, (uint8_t *)buffer, 0, buffer->bMaxPacketSize0);
l_usbtrn_get_descriptor_00103:
;source-doc/base-drv/protocol.c:42:
;source-doc/base-drv/protocol.c:43: RETURN_CHECK(result);
ld sp, ix
pop ix
ret
_cmd_get_dev_descriptr:
DEFB +$80
DEFB +$06
DEFB +$00
DEFB +$01
DEFB +$00
DEFB +$00
DEFW +$0008
;source-doc/base-drv/protocol.c:47: }
; ---------------------------------
; Function usbtrn_get_descriptor2
; ---------------------------------
_usbtrn_get_descriptor2:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/protocol.c:51: *
ld hl,0
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_get_dev_descriptr
ldir
;source-doc/base-drv/protocol.c:52: * @param buffer the buffer to store the device descriptor in
ld (ix-2),$08
xor a
ld (ix-1),a
;source-doc/base-drv/protocol.c:54: */
ld c,(ix+4)
ld b,(ix+5)
push bc
push bc
ld e,c
ld d,b
ld h,$08
ld l,(ix+6)
push hl
push de
ld hl,8
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
pop de
pop bc
ld l, a
;source-doc/base-drv/protocol.c:56: usb_error result;
or a
jr NZ,l_usbtrn_get_descriptor2_00103
;source-doc/base-drv/protocol.c:58: setup_packet cmd;
push de
push bc
ld hl,4
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_get_dev_descriptr
ldir
pop bc
pop de
;source-doc/base-drv/protocol.c:59: cmd = cmd_get_dev_descriptr;
ld (ix-2),$12
xor a
ld (ix-1),a
;source-doc/base-drv/protocol.c:60: cmd.wLength = 8;
ld hl,7
add hl, bc
ld h,(hl)
ld l,(ix+6)
push hl
push de
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
;source-doc/base-drv/protocol.c:61:
l_usbtrn_get_descriptor2_00103:
;source-doc/base-drv/protocol.c:62: result = usb_control_transfer(&cmd, (uint8_t *)buffer, device_address, 8);
;source-doc/base-drv/protocol.c:63:
ld sp, ix
pop ix
ret
;source-doc/base-drv/protocol.c:69: done:
; ---------------------------------
; Function usbtrn_set_address
; ---------------------------------
_usbtrn_set_address:
push ix
ld ix,0
add ix,sp
push af
push af
push af
push af
ld c, l
;source-doc/base-drv/protocol.c:71: }
push bc
ld hl,2
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_set_device_address
ldir
pop bc
;source-doc/base-drv/protocol.c:72:
ld (ix-6),c
;source-doc/base-drv/protocol.c:74:
xor a
push af
inc sp
xor a
push af
inc sp
ld hl,$0000
push hl
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
;source-doc/base-drv/protocol.c:75: /**
ld sp,ix
pop ix
ret
_cmd_set_device_address:
DEFB +$00
DEFB +$05
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFW +$0000
;source-doc/base-drv/protocol.c:81: usb_error usbtrn_set_address(const uint8_t device_address) __z88dk_fastcall {
; ---------------------------------
; Function usbtrn_set_config
; ---------------------------------
_usbtrn_set_config:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/protocol.c:83: cmd = cmd_set_device_address;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,$0008
ld hl,_cmd_set_configuration
ldir
pop bc
;source-doc/base-drv/protocol.c:84: cmd.bValue[0] = device_address;
ld a,(ix+6)
ld (ix-6),a
;source-doc/base-drv/protocol.c:86: return usb_control_transfer(&cmd, 0, 0, 0);
ld h,(ix+5)
ld l,(ix+4)
push hl
ld hl,$0000
push hl
push bc
call _usb_control_transfer
;source-doc/base-drv/protocol.c:87: }
ld sp,ix
pop ix
ret
_cmd_set_configuration:
DEFB +$00
DEFB +$09
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFW +$0000
;source-doc/base-drv/protocol.c:93: *
; ---------------------------------
; Function usbtrn_get_config_desc
; ---------------------------------
_usbtrn_get_config_desc:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/protocol.c:99: cmd = cmd_set_configuration;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,$0008
ld hl,_cmd_get_config_desc
ldir
pop bc
;source-doc/base-drv/protocol.c:100: cmd.bValue[0] = configuration;
ld a,(ix+6)
ld (ix-6),a
;source-doc/base-drv/protocol.c:101:
ld hl,$0006
add hl, bc
ld e,(ix+7)
xor a
ld (hl), e
inc hl
ld (hl), a
;source-doc/base-drv/protocol.c:103: }
ld e,(ix+4)
ld d,(ix+5)
ld h,(ix+9)
ld l,(ix+8)
push hl
push de
push bc
call _usb_control_transfer
;source-doc/base-drv/protocol.c:104:
ld sp,ix
pop ix
ret
_cmd_get_config_desc:
DEFB +$80
DEFB +$06
DEFB +$00
DEFB +$02
DEFB +$00
DEFB +$00
DEFW +$0000
;source-doc/base-drv/protocol.c:106:
; ---------------------------------
; Function usbtrn_gfull_cfg_desc
; ---------------------------------
_usbtrn_gfull_cfg_desc:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/protocol.c:114: * @param max_packet_size the max packet size for control transfers (endpoint 0)
ld c,(ix+8)
ld b,(ix+9)
push bc
ld a,(ix+6)
push af
inc sp
ld d,(ix+5)
ld e,$09
push de
ld a,(ix+4)
push af
inc sp
push bc
call _usbtrn_get_config_desc
pop af
pop af
pop af
pop bc
ld a, l
or a
jr NZ,l_usbtrn_gfull_cfg_desc_00107
;source-doc/base-drv/protocol.c:116: */
ld l,(ix+8)
ld h,(ix+9)
inc hl
inc hl
ld d, (hl)
;source-doc/base-drv/protocol.c:117: usb_error usbtrn_get_config_desc(config_descriptor *const buffer,
ld a,(ix+7)
sub d
jr NC,l_usbtrn_gfull_cfg_desc_00104
;source-doc/base-drv/protocol.c:118: const uint8_t config_index,
ld d,(ix+7)
l_usbtrn_gfull_cfg_desc_00104:
;source-doc/base-drv/protocol.c:120: const uint8_t device_address,
ld h,(ix+6)
ld l,(ix+5)
push hl
ld e,(ix+4)
push de
push bc
call _usbtrn_get_config_desc
pop af
pop af
pop af
ld a, l
;source-doc/base-drv/protocol.c:122: setup_packet cmd;
or a
jr NZ,l_usbtrn_gfull_cfg_desc_00107
ld l,a
;source-doc/base-drv/protocol.c:123: cmd = cmd_get_config_desc;
;source-doc/base-drv/protocol.c:124: cmd.bValue[0] = config_index;
l_usbtrn_gfull_cfg_desc_00107:
;source-doc/base-drv/protocol.c:125: cmd.wLength = (uint16_t)buffer_size;
pop ix
ret
;source-doc/base-drv/protocol.c:129:
; ---------------------------------
; Function usbtrn_clr_ep_halt
; ---------------------------------
_usbtrn_clr_ep_halt:
push ix
ld ix,0
add ix,sp
ld hl, -8
add hl, sp
ld sp, hl
;source-doc/base-drv/protocol.c:131: const uint8_t device_address,
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,$0008
ld hl,_usb_cmd_clr_ep_halt
ldir
pop bc
;source-doc/base-drv/protocol.c:132: const uint8_t max_packet_size,
ld a,(ix+4)
ld (ix-4),a
;source-doc/base-drv/protocol.c:134: uint8_t *const buffer) {
ld h,(ix+6)
ld l,(ix+5)
push hl
ld hl,$0000
push hl
push bc
call _usb_control_transfer
;source-doc/base-drv/protocol.c:135: usb_error result;
ld sp,ix
pop ix
ret
_usb_cmd_clr_ep_halt:
DEFB +$02
DEFB +$01
DEFB +$00
DEFB +$00
DEFB +$ff
DEFB +$00
DEFW +$0000

View File

@@ -0,0 +1,311 @@
;
; Generated from source-doc/base-drv/transfers.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/transfers.c:23: * See https://www.beyondlogic.org/usbnutshell/usb4.shtml for a description of the USB control transfer
; ---------------------------------
; Function usb_control_transfer
; ---------------------------------
_usb_control_transfer:
push ix
ld ix,0
add ix,sp
push af
push af
;source-doc/base-drv/transfers.c:28: * @param max_packet_size Maximum packet size for endpoint
ld hl,0
add hl, sp
set 0, (hl)
ld hl,0
add hl, sp
ld a, (hl)
and $f1
ld (hl), a
ld c,(ix+9)
ld b,$00
ld hl,1
add hl, sp
ld (hl), c
inc hl
ld a, b
and $03
ld e, a
ld a, (hl)
and $fc
or e
ld (hl), a
;source-doc/base-drv/transfers.c:30: */
ld c,(ix+4)
ld b,(ix+5)
ld a, (bc)
and $80
;source-doc/base-drv/transfers.c:32: void *const buffer,
ld (ix-1),a
or a
jr Z,l_usb_control_transfer_00102
ld a,(ix+7)
or (ix+6)
jr NZ,l_usb_control_transfer_00102
;source-doc/base-drv/transfers.c:33: const uint8_t device_address,
ld l,$0f
jp l_usb_control_transfer_00114
l_usb_control_transfer_00102:
;source-doc/base-drv/transfers.c:35: usb_error result;
push bc
call _critical_begin
;source-doc/base-drv/transfers.c:37:
ld l,(ix+8)
call _ch_set_usb_address
pop bc
;source-doc/base-drv/transfers.c:39:
ld e,(ix+4)
ld d,(ix+5)
push bc
ld a,$08
push af
inc sp
push de
call _ch_write_data
pop af
inc sp
;source-doc/base-drv/transfers.c:40: if (transferIn && buffer == 0)
call _ch_issue_token_setup
;source-doc/base-drv/transfers.c:41: return USB_ERR_OTHER;
call _ch_short_get_status
pop bc
;source-doc/base-drv/transfers.c:42:
ld a, l
or a
jr NZ,l_usb_control_transfer_00113
;source-doc/base-drv/transfers.c:44:
ld hl,6
add hl, bc
ld c, (hl)
inc hl
;source-doc/base-drv/transfers.c:47: ch_write_data((const uint8_t *)cmd_packet, sizeof(setup_packet));
ld a,(hl)
ld b,a
or c
jr Z,l_usb_control_transfer_00116
ld hl,0
add hl, sp
ld e,(ix+6)
ld d,(ix+7)
ld a,(ix-1)
or a
jr Z,l_usb_control_transfer_00118
push hl
push bc
push de
call _ch_data_in_transfer
pop af
pop af
pop af
jr l_usb_control_transfer_00119
l_usb_control_transfer_00118:
push hl
push bc
push de
call _ch_data_out_transfer
pop af
pop af
pop af
l_usb_control_transfer_00119:
jr l_usb_control_transfer_00117
l_usb_control_transfer_00116:
;source-doc/base-drv/transfers.c:48: ch_issue_token_setup();
ld l,$00
l_usb_control_transfer_00117:
;source-doc/base-drv/transfers.c:50: CHECK(result);
ld a, l
or a
jr NZ,l_usb_control_transfer_00113
;source-doc/base-drv/transfers.c:52: const uint16_t length = cmd_packet->wLength;
ld a,(ix-1)
or a
jr Z,l_usb_control_transfer_00112
;source-doc/base-drv/transfers.c:53:
ld l,$2c
call _ch_command
;source-doc/base-drv/transfers.c:54: result = length != 0
ld a,$00
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/transfers.c:55: ? (transferIn ? ch_data_in_transfer(buffer, length, &endpoint) : ch_data_out_transfer(buffer, length, &endpoint))
call _ch_issue_token_out_ep0
;source-doc/base-drv/transfers.c:56: : USB_ERR_OK;
call _ch_long_get_status
;source-doc/base-drv/transfers.c:58: CHECK(result)
ld a,l
or a
jr Z,l_usb_control_transfer_00108
sub $02
jr NZ,l_usb_control_transfer_00113
l_usb_control_transfer_00108:
;source-doc/base-drv/transfers.c:59:
ld l,$00
;source-doc/base-drv/transfers.c:60: if (transferIn) {
jr l_usb_control_transfer_00113
;source-doc/base-drv/transfers.c:63: ch_issue_token_out_ep0();
l_usb_control_transfer_00112:
;source-doc/base-drv/transfers.c:66: if (result == USB_ERR_OK || result == USB_ERR_STALL) {
call _ch_issue_token_in_ep0
;source-doc/base-drv/transfers.c:67: result = USB_ERR_OK;
call _ch_long_get_status
;source-doc/base-drv/transfers.c:71: RETURN_CHECK(result);
l_usb_control_transfer_00113:
;source-doc/base-drv/transfers.c:72: }
push hl
call _critical_end
pop hl
;source-doc/base-drv/transfers.c:73:
l_usb_control_transfer_00114:
;source-doc/base-drv/transfers.c:74: ch_issue_token_in_ep0();
ld sp, ix
pop ix
ret
;source-doc/base-drv/transfers.c:79: done:
; ---------------------------------
; Function usb_data_in_transfer
; ---------------------------------
_usb_data_in_transfer:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/transfers.c:81: return result;
call _critical_begin
;source-doc/base-drv/transfers.c:83:
ld l,(ix+8)
call _ch_set_usb_address
;source-doc/base-drv/transfers.c:85: * @brief Perform a USB data in on the specified endpoint
ld l,(ix+9)
ld h,(ix+10)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ch_data_in_transfer
pop af
pop af
;source-doc/base-drv/transfers.c:87: * @param buffer the buffer to receive the data
ex (sp),hl
call _critical_end
pop hl
;source-doc/base-drv/transfers.c:89: * @param device_address the usb address of the device
;source-doc/base-drv/transfers.c:90: * @param endpoint the usb endpoint to receive from (toggle of endpoint is updated)
pop ix
ret
;source-doc/base-drv/transfers.c:95: usb_error result;
; ---------------------------------
; Function usb_data_in_transfer_n
; ---------------------------------
_usb_data_in_transfer_n:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/transfers.c:98: ch_set_usb_address(device_address);
call _critical_begin
;source-doc/base-drv/transfers.c:100: result = ch_data_in_transfer(buffer, buffer_size, endpoint);
ld l,(ix+8)
call _ch_set_usb_address
;source-doc/base-drv/transfers.c:102: critical_end();
ld l,(ix+9)
ld h,(ix+10)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ch_data_in_transfer_n
pop af
pop af
;source-doc/base-drv/transfers.c:104: return result;
ex (sp),hl
call _critical_end
pop hl
;source-doc/base-drv/transfers.c:106:
;source-doc/base-drv/transfers.c:107: /**
pop ix
ret
;source-doc/base-drv/transfers.c:112: * @param device_address the usb address of the device
; ---------------------------------
; Function usb_data_out_transfer
; ---------------------------------
_usb_data_out_transfer:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/transfers.c:114: * @return usb_error USB_ERR_OK if all good, otherwise specific error code
call _critical_begin
;source-doc/base-drv/transfers.c:116: usb_error
ld l,(ix+8)
call _ch_set_usb_address
;source-doc/base-drv/transfers.c:118: usb_error result;
ld l,(ix+9)
ld h,(ix+10)
push hl
ld l,(ix+6)
ld h,(ix+7)
push hl
ld l,(ix+4)
ld h,(ix+5)
push hl
call _ch_data_out_transfer
pop af
pop af
;source-doc/base-drv/transfers.c:120: critical_begin();
ex (sp),hl
call _critical_end
pop hl
;source-doc/base-drv/transfers.c:122: ch_set_usb_address(device_address);
;source-doc/base-drv/transfers.c:123:
pop ix
ret

View File

@@ -0,0 +1,224 @@
;
; Generated from source-doc/base-drv/usb-base-drv.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/usb-base-drv.c:7: static usb_error usb_host_bus_reset(void) {
; ---------------------------------
; Function usb_host_bus_reset
; ---------------------------------
_usb_host_bus_reset:
;source-doc/base-drv/usb-base-drv.c:8: ch_cmd_set_usb_mode(CH_MODE_HOST);
ld l,$06
call _ch_cmd_set_usb_mode
;source-doc/base-drv/usb-base-drv.c:9: delay_20ms();
call _delay_20ms
;source-doc/base-drv/usb-base-drv.c:11: ch_cmd_set_usb_mode(CH_MODE_HOST_RESET);
ld l,$07
call _ch_cmd_set_usb_mode
;source-doc/base-drv/usb-base-drv.c:12: delay_20ms();
call _delay_20ms
;source-doc/base-drv/usb-base-drv.c:14: ch_cmd_set_usb_mode(CH_MODE_HOST);
ld l,$06
call _ch_cmd_set_usb_mode
;source-doc/base-drv/usb-base-drv.c:15: delay_20ms();
call _delay_20ms
;source-doc/base-drv/ch376.h:108: #define TRACE_USB_ERROR(result)
ld l,$0b
call _ch_command
;source-doc/base-drv/ch376.h:109:
ld a,$25
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/ch376.h:110: #endif
ld a,$df
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/base-drv/usb-base-drv.c:19: return USB_ERR_OK;
ld l,$00
;source-doc/base-drv/usb-base-drv.c:20: }
ret
;source-doc/base-drv/usb-base-drv.c:24: uint16_t usb_init(uint8_t state) __z88dk_fastcall {
; ---------------------------------
; Function usb_init
; ---------------------------------
_usb_init:
;source-doc/base-drv/usb-base-drv.c:27: USB_MODULE_LEDS = $03;
ld a,$03
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/usb-base-drv.c:29: if (state == 0) {
ld a, l
or a
jr NZ,l_usb_init_00104
;source-doc/base-drv/usb-base-drv.c:30: ch_cmd_reset_all();
call _ch_cmd_reset_all
;source-doc/base-drv/usb-base-drv.c:31: delay_medium();
call _delay_medium
;source-doc/base-drv/usb-base-drv.c:33: if (!ch_probe()) {
call _ch_probe
ld a, l
;source-doc/base-drv/usb-base-drv.c:34: USB_MODULE_LEDS = $00;
or a
jr NZ,l_usb_init_00102
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/usb-base-drv.c:35: return $FF00;
ld hl,$ff00
jp l_usb_init_00113
l_usb_init_00102:
;source-doc/base-drv/usb-base-drv.c:37: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/usb-base-drv.c:38: return 1;
ld hl,$0001
jr l_usb_init_00113
l_usb_init_00104:
;source-doc/base-drv/usb-base-drv.c:41: if (state == 1) {
ld a, l
dec a
jr NZ,l_usb_init_00106
;source-doc/base-drv/usb-base-drv.c:42: r = ch_cmd_get_ic_version();
call _ch_cmd_get_ic_version
;source-doc/base-drv/usb-base-drv.c:44: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/usb-base-drv.c:45: return (uint16_t)r << 8 | 2;
xor a
ld h, l
ld l,$02
jr l_usb_init_00113
l_usb_init_00106:
;source-doc/base-drv/usb-base-drv.c:48: if (state == 2) {
ld a, l
sub $02
jr NZ,l_usb_init_00159
ld a,$01
jr l_usb_init_00160
l_usb_init_00159:
xor a
l_usb_init_00160:
ld c,a
or a
jr Z,l_usb_init_00110
;source-doc/base-drv/usb-base-drv.c:49: usb_host_bus_reset();
call _usb_host_bus_reset
;source-doc/base-drv/usb-base-drv.c:51: r = ch_very_short_status();
call _ch_very_short_status
ld a, l
;source-doc/base-drv/usb-base-drv.c:53: if (r != USB_INT_CONNECT) {
sub $81
jr Z,l_usb_init_00108
;source-doc/base-drv/usb-base-drv.c:54: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/usb-base-drv.c:55: return 2;
ld hl,$0002
jr l_usb_init_00113
l_usb_init_00108:
;source-doc/base-drv/usb-base-drv.c:58: return 3;
ld hl,$0003
jr l_usb_init_00113
l_usb_init_00110:
;source-doc/base-drv/usb-base-drv.c:61: memset(get_usb_work_area(), 0, sizeof(_usb_state));
ld b,$32
ld hl,_x
jr l_usb_init_00163
l_usb_init_00162:
ld (hl),$00
inc hl
l_usb_init_00163:
ld (hl),$00
inc hl
djnz l_usb_init_00162
;source-doc/base-drv/usb-base-drv.c:62: if (state != 2) {
bit 0, c
jr NZ,l_usb_init_00112
;source-doc/base-drv/usb-base-drv.c:63: usb_host_bus_reset();
call _usb_host_bus_reset
;source-doc/base-drv/usb-base-drv.c:64: delay_medium();
call _delay_medium
l_usb_init_00112:
;source-doc/base-drv/usb-base-drv.c:66: enumerate_all_devices();
call _enumerate_all_devices
;source-doc/base-drv/usb-base-drv.c:67: USB_MODULE_LEDS = $00;
ld a,$00
ld bc,_USB_MODULE_LEDS
out (c), a
;source-doc/base-drv/usb-base-drv.c:68: return (uint16_t)count_of_devices() << 8 | 4;
call _count_of_devices
ld h, a
xor a
ld l,$04
l_usb_init_00113:
;source-doc/base-drv/usb-base-drv.c:69: }
ret
;source-doc/base-drv/usb-base-drv.c:71: usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba) {
; ---------------------------------
; Function usb_scsi_seek
; ---------------------------------
_usb_scsi_seek:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/usb-base-drv.c:72: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index);
ld a,(ix+4)
call _get_usb_device_config
;source-doc/base-drv/usb-base-drv.c:74: dev->current_lba = lba;
ld hl,$000c
add hl, de
ex de, hl
ld hl,6
add hl, sp
ld bc,$0004
ldir
;source-doc/base-drv/usb-base-drv.c:75: return USB_ERR_OK;
ld l,$00
;source-doc/base-drv/usb-base-drv.c:76: }
pop ix
ret

View File

@@ -0,0 +1,258 @@
;
; Generated from source-doc/base-drv/usb_state.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/base-drv/usb_state.c:17: uint8_t count_of_devices(void) __sdcccall(1) {
; ---------------------------------
; Function count_of_devices
; ---------------------------------
_count_of_devices:
;source-doc/base-drv/usb_state.c:18: _usb_state *const p = get_usb_work_area();
;source-doc/base-drv/usb_state.c:22: const device_config *p_config = first_device_config(p);
ld hl,_x
call _first_device_config
;source-doc/base-drv/usb_state.c:23: while (p_config) {
ld c,$00
l_count_of_devices_00104:
ld a, d
or e
jr Z,l_count_of_devices_00106
;source-doc/base-drv/usb_state.c:24: const uint8_t type = p_config->type;
ld l, e
ld h, d
ld a, (hl)
and $0f
;source-doc/base-drv/usb_state.c:26: if (type != USB_IS_HUB && type)
cp $0f
jr Z,l_count_of_devices_00102
or a
jr Z,l_count_of_devices_00102
;source-doc/base-drv/usb_state.c:27: count++;
inc c
l_count_of_devices_00102:
;source-doc/base-drv/usb_state.c:30: p_config = next_device_config(p, p_config);
push bc
ld hl,_x
call _next_device_config
pop bc
jr l_count_of_devices_00104
l_count_of_devices_00106:
;source-doc/base-drv/usb_state.c:33: return count;
ld a, c
;source-doc/base-drv/usb_state.c:34: }
ret
_device_config_sizes:
DEFB +$00
DEFB +$10
DEFB +$10
DEFB +$0c
DEFB +$06
DEFB $00
DEFB $00
;source-doc/base-drv/usb_state.c:37: device_config *find_first_free(void) {
; ---------------------------------
; Function find_first_free
; ---------------------------------
_find_first_free:
;source-doc/base-drv/usb_state.c:38: _usb_state *const boot_state = get_usb_work_area();
;source-doc/base-drv/usb_state.c:41: device_config *p = first_device_config(boot_state);
ld hl,_x
call _first_device_config
;source-doc/base-drv/usb_state.c:42: while (p) {
l_find_first_free_00103:
ld a, d
or e
jr Z,l_find_first_free_00105
;source-doc/base-drv/usb_state.c:43: if (p->type == 0)
ld l, e
ld h, d
ld a, (hl)
and $0f
jr NZ,l_find_first_free_00102
;source-doc/base-drv/usb_state.c:44: return p;
ex de, hl
jr l_find_first_free_00106
l_find_first_free_00102:
;source-doc/base-drv/usb_state.c:46: p = next_device_config(boot_state, p);
ld hl,_x
call _next_device_config
jr l_find_first_free_00103
l_find_first_free_00105:
;source-doc/base-drv/usb_state.c:49: return NULL;
ld hl,$0000
l_find_first_free_00106:
;source-doc/base-drv/usb_state.c:50: }
ret
;source-doc/base-drv/usb_state.c:52: device_config *first_device_config(const _usb_state *const p) __sdcccall(1) { return (device_config *)&p->device_configs[0]; }
; ---------------------------------
; Function first_device_config
; ---------------------------------
_first_device_config:
ex de, hl
inc de
inc de
ret
;source-doc/base-drv/usb_state.c:54: device_config *next_device_config(const _usb_state *const usb_state, const device_config *const p) __sdcccall(1) {
; ---------------------------------
; Function next_device_config
; ---------------------------------
_next_device_config:
ld c, l
ld b, h
;source-doc/base-drv/usb_state.c:55: if (p->type == 0)
ld l, e
ld h, d
ld a, (hl)
and $0f
jr NZ,l_next_device_config_00102
;source-doc/base-drv/usb_state.c:56: return NULL;
ld de,$0000
jr l_next_device_config_00105
l_next_device_config_00102:
;source-doc/base-drv/usb_state.c:58: const uint8_t size = device_config_sizes[p->type];
ld l, e
ld h, d
ld a, (hl)
and $0f
add a, +((_device_config_sizes) & $FF)
ld l, a
ld a,$00
adc a, +((_device_config_sizes) / 256)
ld h, a
ld a, (hl)
;source-doc/base-drv/usb_state.c:65: const uint8_t *_p = (uint8_t *)p;
;source-doc/base-drv/usb_state.c:66: device_config *const result = (device_config *)(_p + size);
add a, e
ld e, a
ld a,$00
adc a, d
ld d, a
;source-doc/base-drv/usb_state.c:68: if (result >= (device_config *)&usb_state->device_configs_end)
ld hl,$0062
add hl, bc
ld a, e
sub l
ld a, d
sbc a, h
ret C
;source-doc/base-drv/usb_state.c:69: return NULL;
ld de,$0000
;source-doc/base-drv/usb_state.c:71: return result;
l_next_device_config_00105:
;source-doc/base-drv/usb_state.c:72: }
ret
;source-doc/base-drv/usb_state.c:74: device_config *get_usb_device_config(const uint8_t device_index) __sdcccall(1) {
; ---------------------------------
; Function get_usb_device_config
; ---------------------------------
_get_usb_device_config:
ld c, a
;source-doc/base-drv/usb_state.c:75: const _usb_state *const usb_state = get_usb_work_area();
;source-doc/base-drv/usb_state.c:79: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
push bc
ld hl,_x
call _first_device_config
pop bc
ld b,$01
l_get_usb_device_config_00107:
ld a, d
or e
jr Z,l_get_usb_device_config_00105
;source-doc/base-drv/usb_state.c:80: if (p->type != USB_NOT_SUPPORTED) {
ld l, e
ld h, d
ld a, (hl)
and $0f
jr Z,l_get_usb_device_config_00108
;source-doc/base-drv/usb_state.c:81: if (counter == device_index)
ld a, c
sub b
;source-doc/base-drv/usb_state.c:82: return p;
jr Z,l_get_usb_device_config_00109
;source-doc/base-drv/usb_state.c:83: counter++;
inc b
l_get_usb_device_config_00108:
;source-doc/base-drv/usb_state.c:79: for (device_config *p = first_device_config(usb_state); p; p = next_device_config(usb_state, p)) {
push bc
ld hl,_x
call _next_device_config
pop bc
jr l_get_usb_device_config_00107
l_get_usb_device_config_00105:
;source-doc/base-drv/usb_state.c:87: return NULL; // is not a usb device
ld de,$0000
l_get_usb_device_config_00109:
;source-doc/base-drv/usb_state.c:88: }
ret
;source-doc/base-drv/usb_state.c:90: usb_device_type usb_get_device_type(const uint16_t dev_index) {
; ---------------------------------
; Function usb_get_device_type
; ---------------------------------
_usb_get_device_type:
push ix
ld ix,0
add ix,sp
;source-doc/base-drv/usb_state.c:91: const device_config *dev = get_usb_device_config(dev_index);
ld a,(ix+4)
call _get_usb_device_config
ld l, e
;source-doc/base-drv/usb_state.c:93: if (dev == NULL)
ld a,d
ld h,a
or e
jr NZ,l_usb_get_device_type_00102
;source-doc/base-drv/usb_state.c:94: return -1;
ld l,$ff
jr l_usb_get_device_type_00103
l_usb_get_device_type_00102:
;source-doc/base-drv/usb_state.c:96: return dev->type;
ld a, (hl)
and $0f
ld l, a
l_usb_get_device_type_00103:
;source-doc/base-drv/usb_state.c:97: }
pop ix
ret

View File

@@ -0,0 +1,149 @@
;
; Generated from source-doc/base-drv/work-area.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_x:
DEFS 99
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
_x:
DEFB $00
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB +$00

View File

@@ -0,0 +1,133 @@
_memset_callee:
pop af ; return address
pop bc ; address to be set
pop de ; value to be set
pop hl ; number of bytes to set
push af ; restore return address
ld a, b
or c
ret z
ld a, e
push hl
pop de
ret z
ld (hl), a
inc de
dec bc
ld a, b
or c
ret z
push hl
ldir
pop hl
ret
_memcpy_callee:
pop af
pop bc
pop hl
pop de
push af
; enter : bc = size_t n
; hl = void *s2 = src
; de = void *s1 = dst
;
; exit : hl = void *s1 = dst
; de = ptr in s1 to one byte past last byte copied
; bc = 0
; carry reset
;
; uses : af, bc, de, hl
ld a, b
or c
jr z, zero_n
asm0_memcpy:
push de
ldir
pop hl
or a
ret
zero_n:
push de
pop hl
ret
.if 0
; required if --optimise-for-size is targetted
; but there appears to be a regression that stop the driver from working
; if optimised for size is selected
___sdcc_enter_ix:
ex (sp), ix
push ix
ld ix, 2
add ix, sp
ret
____sdcc_lib_setmem_hl:
l_setmem_hl:
ret
____sdcc_load_debc_mhl:
ld c, (hl)
inc hl
ld b, (hl)
inc hl
ld e, (hl)
inc hl
ld d, (hl)
ret
____sdcc_4_push_hlix:
pop af
push af
push af
push af
push de
push ix
pop de
add hl, de
ex de, hl
ld hl, 2+2
add hl, sp
ex de, hl
ldi
ldi
ldi
ld a, (hl)
ld (de), a
inc bc
inc bc
inc bc
pop de
ret
____sdcc_store_debc_mhl:
ld (hl), c
inc hl
ld (hl), b
inc hl
ld (hl), e
inc hl
ld (hl), d
ret
.endif

View File

@@ -0,0 +1,143 @@
; delegate usb function to firmware of ez80 module
; extern uint16_t usb_init(uint8_t state) __z88dk_fastcall;
_usb_init:
EZ80_EX_USB_INIT
RET
; usb_error usb_scsi_seek(const uint16_t dev_index, const uint32_t lba)
_usb_scsi_seek:
; iy+2 : dev_index
; iy+4:5:6:7 : lba
LD IY, 0
ADD IY, SP
EZ80_EXTN_IY_TO_MB_IY
LD C, (IY+2)
LD_DE_IY_P_.L(4) ; LD.L DE, (IY+4)
LD L, (IY+7)
EZ80_EX_USB_STORAGE_SEEK
LD L, A
RET
; usb_error usb_scsi_init(const uint16_t dev_index)
_usb_scsi_init:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
EZ80_EX_USB_SCSI_INIT
LD L, A
RET
; usb_error usb_scsi_read(const uint16_t dev_index, uint8_t *const buffer);
_usb_scsi_read:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
LD E, (IY+4)
LD D, (IY+5)
EZ80_EXTN_DE_TO_MB_DE
EZ80_EX_USB_SCSI_READ
LD L, A
RET
; usb_error usb_scsi_write(const uint16_t dev_index, uint8_t *const buffer)
_usb_scsi_write:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
LD E, (IY+4)
LD D, (IY+5)
EZ80_EXTN_DE_TO_MB_DE
EZ80_EX_USB_SCSI_WRITE
LD L, A
RET
; usb_error usb_scsi_read_capacity(const uint16_t dev_index, scsi_read_capacity_result *cap_result)
_usb_scsi_read_capacity:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
LD E, (IY+4)
LD D, (IY+5)
EZ80_EXTN_DE_TO_MB_DE
EZ80_EX_USB_SCSI_READ_CAP
LD L, A
RET
; extern uint8_t usb_ufi_read(const uint16_t dev_index, uint8_t *const buffer)
_usb_ufi_read:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
LD E, (IY+4)
LD D, (IY+5)
EZ80_EXTN_DE_TO_MB_DE
EZ80_EX_USB_UFI_READ
LD L, A
RET
;extern usb_error usb_ufi_write(const uint16_t dev_index, uint8_t *const buffer);
_usb_ufi_write:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
LD E, (IY+4)
LD D, (IY+5)
EZ80_EXTN_DE_TO_MB_DE
EZ80_EX_USB_UFI_WRITE
LD L, A
RET
; extern uint32_t usb_ufi_get_cap(const uint16_t dev_index)
_usb_ufi_get_cap:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
EZ80_EXTN_DE_TO_MB_DE
EZ80_EX_USB_UFI_GET_CAP ;
LD D, E ; convert E:uHL to DE:HL
EZ80_CPY_UHL_TO_EHL
RET
; extern void usb_kyb_init(const uint8_t dev_index) __sdcccall(1);
_usb_kyb_init:
LD C, A
EZ80_EX_USB_KYB_INIT
RET
; extern uint8_t usb_kyb_flush() __sdcccall(1);
_usb_kyb_flush:
EZ80_EX_USB_KYB_FLUSH
RET
; extern uint8_t usb_kyb_status() __sdcccall(1);
_usb_kyb_status:
EZ80_EX_USB_KYB_STATUS
RET
; extern uint16_t usb_kyb_read();
; H = 0/1 set if char, L=>code
_usb_kyb_read:
EZ80_EX_USB_KYB_READ
LD H, A
RET
;usb_device_type usb_get_device_type(const uint16_t dev_index)
_usb_get_device_type:
LD IY, 0
ADD IY, SP
LD C, (IY+2)
EZ80_EX_USB_GET_DEV_TYPE
LD L, A
RET

View File

@@ -0,0 +1,11 @@
; Generated File -- not to be modify directly
#IF (!CHNATIVEEZ80)
#include "ch376-native/keyboard/class_hid.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/keyboard/class_hid_keyboard.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/keyboard/kyb_driver.c.s"
#ENDIF
#include "ch376-native/keyboard/kyb-init.c.s"

View File

@@ -0,0 +1 @@
*.asm

View File

@@ -0,0 +1,169 @@
;
; Generated from source-doc/keyboard/class_hid.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/keyboard/class_hid.c:6: usb_error hid_set_protocol(const device_config_keyboard *const dev, const uint8_t protocol) __sdcccall(1) {
; ---------------------------------
; Function hid_set_protocol
; ---------------------------------
_hid_set_protocol:
push ix
ld ix,0
add ix,sp
push af
push af
push af
push af
;source-doc/keyboard/class_hid.c:8: cmd = cmd_hid_set;
push hl
ex de,hl
ld hl,2
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_hid_set
ldir
pop de
;source-doc/keyboard/class_hid.c:10: cmd.bRequest = HID_SET_PROTOCOL;
ld (ix-7),$0b
;source-doc/keyboard/class_hid.c:11: cmd.bValue[0] = protocol;
ld a,(ix+4)
ld (ix-6),a
;source-doc/keyboard/class_hid.c:13: return usb_control_transfer(&cmd, NULL, dev->address, dev->max_packet_size);
ld l, e
ld h, d
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
ld c,a
push bc
ld hl,$0000
push hl
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
;source-doc/keyboard/class_hid.c:14: }
ld sp, ix
pop ix
pop hl
inc sp
jp (hl)
_cmd_hid_set:
DEFB +$21
DEFB +$0b
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFW +$0000
;source-doc/keyboard/class_hid.c:16: usb_error hid_set_idle(const device_config_keyboard *const dev, const uint8_t duration) __sdcccall(1) {
; ---------------------------------
; Function hid_set_idle
; ---------------------------------
_hid_set_idle:
push ix
ld ix,0
add ix,sp
push af
push af
push af
push af
;source-doc/keyboard/class_hid.c:18: cmd = cmd_hid_set;
push hl
ex de,hl
ld hl,2
add hl, sp
ex de, hl
ld bc,$0008
ld hl,_cmd_hid_set
ldir
pop de
;source-doc/keyboard/class_hid.c:20: cmd.bRequest = HID_SET_IDLE;
ld (ix-7),$0a
;source-doc/keyboard/class_hid.c:21: cmd.bValue[0] = duration;
ld a,(ix+4)
ld (ix-6),a
;source-doc/keyboard/class_hid.c:23: return usb_control_transfer(&cmd, NULL, dev->address, dev->max_packet_size);
ld l, e
ld h, d
inc hl
ld b, (hl)
ex de, hl
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
ld c,a
push bc
ld hl,$0000
push hl
ld hl,4
add hl, sp
push hl
call _usb_control_transfer
pop af
pop af
pop af
ld a, l
;source-doc/keyboard/class_hid.c:24: }
ld sp, ix
pop ix
pop hl
inc sp
jp (hl)

View File

@@ -0,0 +1,440 @@
;
; Generated from source-doc/keyboard/class_hid_keyboard.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_scancodes_shift_table:
DEFS 128
_scancodes_table:
DEFS 128
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/keyboard/class_hid_keyboard.c:334: };
; ---------------------------------
; Function char_with_caps_lock
; ---------------------------------
_char_with_caps_lock:
;source-doc/keyboard/class_hid_keyboard.c:335:
bit 0, l
;source-doc/keyboard/class_hid_keyboard.c:336: static char char_with_caps_lock(const char c, const bool caps_lock_engaged) __sdcccall(1) {
jr Z,l_char_with_caps_lock_00109
;source-doc/keyboard/class_hid_keyboard.c:338: return c;
cp $41
jr C,l_char_with_caps_lock_00104
cp $5b
jr NC,l_char_with_caps_lock_00104
;source-doc/keyboard/class_hid_keyboard.c:339:
add a,$20
jr l_char_with_caps_lock_00109
l_char_with_caps_lock_00104:
;source-doc/keyboard/class_hid_keyboard.c:341: return c - 'A' + 'a';
cp $61
ret C
cp $7b
ret NC
;source-doc/keyboard/class_hid_keyboard.c:342:
add a,$e0
;source-doc/keyboard/class_hid_keyboard.c:344: return c - 'a' + 'A';
l_char_with_caps_lock_00109:
;source-doc/keyboard/class_hid_keyboard.c:345:
ret
;source-doc/keyboard/class_hid_keyboard.c:347: }
; ---------------------------------
; Function scancode_to_char
; ---------------------------------
_scancode_to_char:
push ix
ld ix,0
add ix,sp
;source-doc/keyboard/class_hid_keyboard.c:348:
ld c,a
ld e,l
and $11
jr Z,l_scancode_to_char_00118
;source-doc/keyboard/class_hid_keyboard.c:349: char scancode_to_char(const uint8_t modifier_keys, const uint8_t code, const bool caps_lock_engaged) __sdcccall(1) {
ld a, e
sub $04
jr C,l_scancode_to_char_00102
ld a,$1d
sub e
jr C,l_scancode_to_char_00102
;source-doc/keyboard/class_hid_keyboard.c:350: if ((modifier_keys & (KEY_MOD_LCTRL | KEY_MOD_RCTRL))) {
ld a, e
add a,$fd
jr l_scancode_to_char_00121
l_scancode_to_char_00102:
;source-doc/keyboard/class_hid_keyboard.c:352: return code - 3;
ld a,e
cp $1f
jr Z,l_scancode_to_char_00104
sub $2c
jr NZ,l_scancode_to_char_00105
l_scancode_to_char_00104:
;source-doc/keyboard/class_hid_keyboard.c:353:
xor a
jr l_scancode_to_char_00121
l_scancode_to_char_00105:
;source-doc/keyboard/class_hid_keyboard.c:355: return 0;
ld a, e
sub $2f
jr NZ,l_scancode_to_char_00108
;source-doc/keyboard/class_hid_keyboard.c:356:
ld a,$1b
jr l_scancode_to_char_00121
l_scancode_to_char_00108:
;source-doc/keyboard/class_hid_keyboard.c:358: return 27;
ld a, e
sub $31
jr NZ,l_scancode_to_char_00110
;source-doc/keyboard/class_hid_keyboard.c:359:
ld a,$1c
jr l_scancode_to_char_00121
l_scancode_to_char_00110:
;source-doc/keyboard/class_hid_keyboard.c:361: return 28;
ld a, e
sub $30
jr NZ,l_scancode_to_char_00112
;source-doc/keyboard/class_hid_keyboard.c:362:
ld a,$1d
jr l_scancode_to_char_00121
l_scancode_to_char_00112:
;source-doc/keyboard/class_hid_keyboard.c:364: return 29;
ld a, e
sub $23
jr NZ,l_scancode_to_char_00114
;source-doc/keyboard/class_hid_keyboard.c:365:
ld a,$1e
jr l_scancode_to_char_00121
l_scancode_to_char_00114:
;source-doc/keyboard/class_hid_keyboard.c:367: return 30;
ld a, e
sub $2d
jr NZ,l_scancode_to_char_00118
;source-doc/keyboard/class_hid_keyboard.c:368:
ld a,$1f
jr l_scancode_to_char_00121
l_scancode_to_char_00118:
;source-doc/keyboard/class_hid_keyboard.c:371: }
ld a, c
and $22
jr Z,l_scancode_to_char_00120
;source-doc/keyboard/class_hid_keyboard.c:372:
ld d,$00
ld hl,_scancodes_shift_table
add hl, de
ld a, (hl)
ld l,(ix+4)
call _char_with_caps_lock
jr l_scancode_to_char_00121
l_scancode_to_char_00120:
;source-doc/keyboard/class_hid_keyboard.c:374: return char_with_caps_lock(scancodes_shift_table[code], caps_lock_engaged);
ld d,$00
ld hl,_scancodes_table
add hl, de
ld a, (hl)
ld l,(ix+4)
call _char_with_caps_lock
l_scancode_to_char_00121:
;source-doc/keyboard/class_hid_keyboard.c:375:
pop ix
pop hl
inc sp
jp (hl)
_scancodes_shift_table:
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$41
DEFB +$42
DEFB +$43
DEFB +$44
DEFB +$45
DEFB +$46
DEFB +$47
DEFB +$48
DEFB +$49
DEFB +$4a
DEFB +$4b
DEFB +$4c
DEFB +$4d
DEFB +$4e
DEFB +$4f
DEFB +$50
DEFB +$51
DEFB +$52
DEFB +$53
DEFB +$54
DEFB +$55
DEFB +$56
DEFB +$57
DEFB +$58
DEFB +$59
DEFB +$5a
DEFB +$21
DEFB +$40
DEFB +$23
DEFB +$24
DEFB +$25
DEFB +$5e
DEFB +$26
DEFB +$2a
DEFB +$28
DEFB +$29
DEFB +$0d
DEFB +$1b
DEFB +$08
DEFB +$09
DEFB +$20
DEFB +$5f
DEFB +$2b
DEFB +$7b
DEFB +$7d
DEFB +$7c
DEFB +$7e
DEFB +$3a
DEFB +$22
DEFB +$7e
DEFB +$3c
DEFB +$3e
DEFB +$3f
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$2f
DEFB +$2a
DEFB +$2d
DEFB +$2b
DEFB +$0d
DEFB +$31
DEFB +$32
DEFB +$33
DEFB +$34
DEFB +$35
DEFB +$36
DEFB +$37
DEFB +$38
DEFB +$39
DEFB +$30
DEFB +$2e
DEFB +$5c
DEFB +$00
DEFB +$00
DEFB +$3d
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
_scancodes_table:
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$61
DEFB +$62
DEFB +$63
DEFB +$64
DEFB +$65
DEFB +$66
DEFB +$67
DEFB +$68
DEFB +$69
DEFB +$6a
DEFB +$6b
DEFB +$6c
DEFB +$6d
DEFB +$6e
DEFB +$6f
DEFB +$70
DEFB +$71
DEFB +$72
DEFB +$73
DEFB +$74
DEFB +$75
DEFB +$76
DEFB +$77
DEFB +$78
DEFB +$79
DEFB +$7a
DEFB +$31
DEFB +$32
DEFB +$33
DEFB +$34
DEFB +$35
DEFB +$36
DEFB +$37
DEFB +$38
DEFB +$39
DEFB +$30
DEFB +$0d
DEFB +$1b
DEFB +$08
DEFB +$09
DEFB +$20
DEFB +$2d
DEFB +$3d
DEFB +$5b
DEFB +$5d
DEFB +$5c
DEFB +$23
DEFB +$3b
DEFB +$27
DEFB +$60
DEFB +$2c
DEFB +$2e
DEFB +$2f
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$2f
DEFB +$2a
DEFB +$2d
DEFB +$2b
DEFB +$0d
DEFB +$31
DEFB +$32
DEFB +$33
DEFB +$34
DEFB +$35
DEFB +$36
DEFB +$37
DEFB +$38
DEFB +$39
DEFB +$30
DEFB +$2e
DEFB +$5c
DEFB +$00
DEFB +$00
DEFB +$3d
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00

View File

@@ -0,0 +1,122 @@
;
; Generated from source-doc/keyboard/kyb-init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/keyboard/kyb-init.c:6: uint8_t keyboard_init(void) __sdcccall(1) {
; ---------------------------------
; Function keyboard_init
; ---------------------------------
_keyboard_init:
push ix
ld ix,0
add ix,sp
dec sp
;source-doc/keyboard/kyb-init.c:7: uint8_t index = 1;
;source-doc/keyboard/kyb-init.c:9: do {
ld c,$01
ld (ix-1),c
l_keyboard_init_00103:
;source-doc/keyboard/kyb-init.c:10: usb_device_type t = usb_get_device_type(index);
ld e, c
ld d,$00
push bc
push de
push de
call _usb_get_device_type
pop af
ld a, l
pop de
pop bc
;source-doc/keyboard/kyb-init.c:12: if (t == USB_IS_KEYBOARD) {
sub $04
jr NZ,l_keyboard_init_00104
;source-doc/keyboard/kyb-init.c:13: print_string("\r\nUSB: KEYBOARD @ $");
push de
ld hl,kyb_init_str_0
call _print_string
pop de
;source-doc/keyboard/kyb-init.c:14: print_uint16(index);
ex de, hl
call _print_uint16
;source-doc/keyboard/kyb-init.c:15: print_string(" $");
ld hl,kyb_init_str_1
call _print_string
;source-doc/keyboard/kyb-init.c:17: usb_kyb_init(index);
ld a,(ix-1)
call _usb_kyb_init
;source-doc/keyboard/kyb-init.c:18: return 1;
ld a,$01
jr l_keyboard_init_00106
l_keyboard_init_00104:
;source-doc/keyboard/kyb-init.c:20: } while (++index != MAX_NUMBER_OF_DEVICES + 1);
inc c
ld (ix-1),c
ld a, c
sub $07
jr NZ,l_keyboard_init_00103
;source-doc/keyboard/kyb-init.c:22: print_string("\r\nUSB: KEYBOARD: NOT FOUND$");
ld hl,kyb_init_str_2
call _print_string
;source-doc/keyboard/kyb-init.c:24: return 0;
xor a
l_keyboard_init_00106:
;source-doc/keyboard/kyb-init.c:25: }
inc sp
pop ix
ret
kyb_init_str_0:
DEFB $0d
DEFB $0a
DEFM "USB: KEYBOARD @ $"
DEFB $00
kyb_init_str_1:
DEFM " $"
DEFB $00
kyb_init_str_2:
DEFB $0d
DEFB $0a
DEFM "USB: KEYBOARD: NOT FOUND$"
DEFB $00

View File

@@ -0,0 +1,406 @@
;
; Generated from source-doc/keyboard/kyb_driver.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_caps_lock_engaged:
DEFS 1
_keyboard_config:
DEFS 2
_buffer:
DEFS 8
_write_index:
DEFS 1
_read_index:
DEFS 1
_report:
DEFS 8
_previous:
DEFS 8
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/keyboard/kyb_driver.c:23: #define EI __asm__("EI")
; ---------------------------------
; Function report_diff
; ---------------------------------
_report_diff:
;source-doc/keyboard/kyb_driver.c:24:
ld de,_report+0
;source-doc/keyboard/kyb_driver.c:25: static uint8_t report_diff() __sdcccall(1) {
;source-doc/keyboard/kyb_driver.c:28:
ld b,$08
ld hl,_previous
l_report_diff_00103:
;source-doc/keyboard/kyb_driver.c:29: uint8_t i = sizeof(report);
ld a, (de)
inc de
ld c, (hl)
inc hl
sub c
jr Z,l_report_diff_00104
;source-doc/keyboard/kyb_driver.c:30: do {
ld a,$01
jr l_report_diff_00106
l_report_diff_00104:
;source-doc/keyboard/kyb_driver.c:31: if (*a++ != *b++)
djnz l_report_diff_00103
;source-doc/keyboard/kyb_driver.c:33: } while (--i != 0);
xor a
l_report_diff_00106:
;source-doc/keyboard/kyb_driver.c:34:
ret
;source-doc/keyboard/kyb_driver.c:36: }
; ---------------------------------
; Function keyboard_buf_put
; ---------------------------------
_keyboard_buf_put:
ld c, a
;source-doc/keyboard/kyb_driver.c:37:
ld b,$00
ld hl,+(_report + 2)
add hl, bc
;source-doc/keyboard/kyb_driver.c:38: static void keyboard_buf_put(const uint8_t indx) __sdcccall(1) {
ld a,(hl)
ld e,a
sub $80
jr NC,l_keyboard_buf_put_00112
ld a, e
or a
;source-doc/keyboard/kyb_driver.c:39: const uint8_t key_code = report.keyCode[indx];
jr Z,l_keyboard_buf_put_00112
;source-doc/keyboard/kyb_driver.c:42:
ld b,$00
ld hl,+(_previous + 2)
add hl, bc
ld a, (hl)
sub e
;source-doc/keyboard/kyb_driver.c:43: // if already reported, just skip it
jr Z,l_keyboard_buf_put_00112
;source-doc/keyboard/kyb_driver.c:45: return;
ld a, e
sub $39
jr NZ,l_keyboard_buf_put_00107
;source-doc/keyboard/kyb_driver.c:46:
ld hl,_caps_lock_engaged
ld a, (hl)
xor $01
ld (hl), a
;source-doc/keyboard/kyb_driver.c:47: if (key_code == KEY_CODE_CAPS_LOCK) {
jr l_keyboard_buf_put_00112
l_keyboard_buf_put_00107:
;source-doc/keyboard/kyb_driver.c:50: }
ld a,(_report)
ld hl,_caps_lock_engaged
ld h, (hl)
push hl
inc sp
ld l, e
call _scancode_to_char
ld b, a
;source-doc/keyboard/kyb_driver.c:52: const unsigned char c = scancode_to_char(report.bModifierKeys, key_code, caps_lock_engaged);
or a
;source-doc/keyboard/kyb_driver.c:53:
ret Z
;source-doc/keyboard/kyb_driver.c:55: return;
ld a, (_write_index)
inc a
and $07
ld c, a
;source-doc/keyboard/kyb_driver.c:56:
ld hl,_read_index
ld a, (hl)
sub c
ret Z
;source-doc/keyboard/kyb_driver.c:57: uint8_t next_write_index = (write_index + 1) & KEYBOARD_BUFFER_SIZE_MASK;
ld hl,(_write_index)
ld h,$00
ld de,_buffer
add hl,de
ld a,b
ld (hl),a
ld hl,_write_index
;source-doc/keyboard/kyb_driver.c:58: if (next_write_index != read_index) { // Check if buffer is not full
ld (hl), c
l_keyboard_buf_put_00112:
;source-doc/keyboard/kyb_driver.c:60: write_index = next_write_index;
ret
;source-doc/keyboard/kyb_driver.c:62: }
; ---------------------------------
; Function usb_kyb_status
; ---------------------------------
_usb_kyb_status:
;source-doc/keyboard/kyb_driver.c:63:
DI
;source-doc/keyboard/kyb_driver.c:67: uint8_t size;
ld a,(_write_index)
ld hl,_read_index
sub (hl)
jr C,l_usb_kyb_status_00102
;source-doc/keyboard/kyb_driver.c:68:
ld a,(_write_index)
ld hl,_read_index
sub (hl)
jr l_usb_kyb_status_00103
l_usb_kyb_status_00102:
;source-doc/keyboard/kyb_driver.c:70: size = write_index - read_index;
ld hl, (_read_index)
ld a,$08
sub l
ld hl, (_write_index)
add a, l
l_usb_kyb_status_00103:
;source-doc/keyboard/kyb_driver.c:72: size = KEYBOARD_BUFFER_SIZE - read_index + write_index;
EI
;source-doc/keyboard/kyb_driver.c:73:
;source-doc/keyboard/kyb_driver.c:74: EI;
ret
;source-doc/keyboard/kyb_driver.c:76: }
; ---------------------------------
; Function usb_kyb_read
; ---------------------------------
_usb_kyb_read:
;source-doc/keyboard/kyb_driver.c:77:
ld a,(_write_index)
ld hl,_read_index
sub (hl)
jr NZ,l_usb_kyb_read_00102
;source-doc/keyboard/kyb_driver.c:78: uint16_t usb_kyb_read() {
ld hl,$ff00
jr l_usb_kyb_read_00103
l_usb_kyb_read_00102:
;source-doc/keyboard/kyb_driver.c:80: return $FF00; // H = -1, L = 0
DI
;source-doc/keyboard/kyb_driver.c:81:
ld hl,(_read_index)
ld h,$00
ld bc,_buffer
add hl,bc
ld a,(hl)
ld c,l
ld b,h
ld hl,_read_index
ld l, a
;source-doc/keyboard/kyb_driver.c:82: DI;
ld a, (_read_index)
inc a
and $07
ld (_read_index), a
;source-doc/keyboard/kyb_driver.c:83: const uint8_t c = buffer[read_index];
EI
;source-doc/keyboard/kyb_driver.c:86:
ld h,$00
l_usb_kyb_read_00103:
;source-doc/keyboard/kyb_driver.c:87: /* H = 0, L = ascii char */
ret
;source-doc/keyboard/kyb_driver.c:89: }
; ---------------------------------
; Function usb_kyb_flush
; ---------------------------------
_usb_kyb_flush:
;source-doc/keyboard/kyb_driver.c:90:
DI
;source-doc/keyboard/kyb_driver.c:91: uint8_t usb_kyb_flush() __sdcccall(1) {
xor a
ld (_read_index),a
ld (_write_index),a
;source-doc/keyboard/kyb_driver.c:94:
ld de,_previous+0
;source-doc/keyboard/kyb_driver.c:95: uint8_t i = sizeof(previous);
;source-doc/keyboard/kyb_driver.c:96: uint8_t *a = (uint8_t *)previous;
ld b,$08
ld hl,_report
l_usb_kyb_flush_00101:
;source-doc/keyboard/kyb_driver.c:97: uint8_t *b = (uint8_t *)report;
xor a
ld (de), a
inc de
;source-doc/keyboard/kyb_driver.c:98: do {
ld (hl),$00
inc hl
;source-doc/keyboard/kyb_driver.c:99: *a++ = 0;
djnz l_usb_kyb_flush_00101
;source-doc/keyboard/kyb_driver.c:101: } while (--i != 0);
EI
;source-doc/keyboard/kyb_driver.c:103: EI;
xor a
;source-doc/keyboard/kyb_driver.c:104:
ret
;source-doc/keyboard/kyb_driver.c:106: }
; ---------------------------------
; Function usb_kyb_tick
; ---------------------------------
_usb_kyb_tick:
;source-doc/keyboard/kyb_driver.c:109: usb_error result;
ld hl,_in_critical_usb_section
ld a, (hl)
or a
;source-doc/keyboard/kyb_driver.c:110:
jr NZ,l_usb_kyb_tick_00112
;././source-doc/base-drv//ch376.h:108: #define TRACE_USB_ERROR(result)
ld l,$0b
call _ch_command
;././source-doc/base-drv//ch376.h:109:
ld a,$25
ld bc,_CH376_DATA_PORT
out (c), a
;././source-doc/base-drv//ch376.h:110: #endif
ld a,$1f
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/keyboard/kyb_driver.c:113:
ld bc,_report+0
ld hl, (_keyboard_config)
ld a,$08
push af
inc sp
push bc
push hl
call _usbdev_dat_in_trnsfer_0
pop af
pop af
inc sp
;././source-doc/base-drv//ch376.h:108: #define TRACE_USB_ERROR(result)
push hl
ld l,$0b
call _ch_command
pop hl
;././source-doc/base-drv//ch376.h:109:
ld a,$25
ld bc,_CH376_DATA_PORT
out (c), a
;././source-doc/base-drv//ch376.h:110: #endif
ld a,$df
ld bc,_CH376_DATA_PORT
out (c), a
;source-doc/keyboard/kyb_driver.c:115: result = usbdev_dat_in_trnsfer_0((device_config *)keyboard_config, (uint8_t *)&report, 8);
ld a, l
or a
jr NZ,l_usb_kyb_tick_00112
;source-doc/keyboard/kyb_driver.c:116: ch_configure_nak_retry_3s();
call _report_diff
or a
jr Z,l_usb_kyb_tick_00112
;source-doc/keyboard/kyb_driver.c:118: if (report_diff()) {
ld b,$06
l_usb_kyb_tick_00103:
;source-doc/keyboard/kyb_driver.c:119: uint8_t i = 6;
ld a, b
dec a
push bc
call _keyboard_buf_put
pop bc
;source-doc/keyboard/kyb_driver.c:120: do {
djnz l_usb_kyb_tick_00103
;source-doc/keyboard/kyb_driver.c:121: keyboard_buf_put(i - 1);
ld de,_previous
ld bc,$0008
ld hl,_report
ldir
l_usb_kyb_tick_00112:
;source-doc/keyboard/kyb_driver.c:124: }
ret
;source-doc/keyboard/kyb_driver.c:126: }
; ---------------------------------
; Function usb_kyb_init
; ---------------------------------
_usb_kyb_init:
;source-doc/keyboard/kyb_driver.c:127:
call _get_usb_device_config
ex de, hl
ld (_keyboard_config), hl
;source-doc/keyboard/kyb_driver.c:129: keyboard_config = (device_config_keyboard *)get_usb_device_config(dev_index);
ld hl,_keyboard_config + 1
ld a, (hl)
dec hl
or (hl)
;source-doc/keyboard/kyb_driver.c:130:
ret Z
;source-doc/keyboard/kyb_driver.c:132: return;
ld a,$01
push af
inc sp
ld hl, (_keyboard_config)
call _hid_set_protocol
;source-doc/keyboard/kyb_driver.c:133:
ld a,$80
push af
inc sp
ld hl, (_keyboard_config)
call _hid_set_idle
;source-doc/keyboard/kyb_driver.c:134: hid_set_protocol(keyboard_config, 1);
ret
_caps_lock_engaged:
DEFB +$01
_keyboard_config:
DEFW +$0000
_buffer:
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
_write_index:
DEFB +$00
_read_index:
DEFB +$00
_report:
DEFB +$00
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
_previous:
DEFB +$00
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00

View File

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

View File

@@ -0,0 +1,125 @@
# Native CH376 Driver
The native CH376 HBIOS driver is written in c, using z88dk's zcc compiler.
The build process, is a 3 stage process.
1. Compile all the C code to assembly files (.asm)
2. Translate the produced .asm files syntax to compile with the RomWBW assembler (.s)
3. Assemble the driver .s files as per the standard HBIOS build process
The original C code and produced/translated .s files are all committed units in the repo. But it is
expected, that only the c files are to be modified/updated.
The .s files are checked in, so builders do not require the C compiler tool chain (z88dk) to be installed.
The c compiling/translating process is only supported on linux, as the script to translate the .asm files
to .s files is a linux bash script. (Although the script can be easily run within Windows's Sub-system for linux)
## Compiling the C code
> Requires linux with docker installed.
> The C code only needs to be recompiled if and when you change any of the `.c` source files.
To compile the `.c` code to generate updated `.s` files:
Within the `Source/HBIOS/ch376-native` directory:
```
make
```
The make script will search for z88dk's `zcc` compiler, if not found, will attempt to use a docker wrapper.
It will not work if z88dk or docker is not installed.
## USB Native Driver systems
The default builds of RomWBW do not enable the CH376 native usb drivers. These drivers take a reasonable chunk of ROM space. As such you
will need to build a new HBIOS image customised for your platform. Please familiarise yourself with the HBIOS/RomWBW build and configuration process.
The usb driver is divided into a few sub-system, which can be individually enabled within the standard HBIOS config files.
For activating the full native USB support, the non native CH365 drivers need to be disabled and the relevant `CHNATIVE` drivers enabled
Example:
```
CHENABLE .SET FALSE ; CH: ENABLE CH375/376 USB SUPPORT
CH0USBENABLE .SET FALSE ; CH375: ENABLE CH375 USB DRIVER
CH1USBENABLE .SET FALSE ; CH376: ENABLE CH376 USB DRIVER
CHNATIVEENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE USB DRIVER
CHSCSIENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE MASS STORAGE DEVICES (REQUIRES CHNATIVEENABLE)
CHUFIENABLE .SET TRUE ; CH376: ENABLE CH376 NATIVE UFI FLOPPY DISK DEVICES (REQUIRES CHNATIVEENABLE)
CHNATIVEEZ80 .SET FALSE ; CH376: DELEGATE USB DRIVERS TO EZ80'S FIRMWARE
CHNATIVEFORCE .SET TRUE ; CH376: DISABLE AUTO-DETECTION OF MODULE - ASSUME ITS INSTALLED
```
As the USB driver is a fairly large, you may need to disable other HBIOS drivers in your configuration. As such, it is
recommend to only enable drivers for your platform's hardware configuration - for example, enable only the serial driver
required for your system.
```
DUARTENABLE .SET FALSE ; DUART: ENABLE 2681/2692 SERIAL DRIVER (DUART.ASM)
UARTENABLE .SET FALSE ; UART: ENABLE 8250/16550-LIKE SERIAL DRIVER (UART.ASM)
ACIAENABLE .SET FALSE ; ACIA: ENABLE MOTOROLA 6850 ACIA DRIVER (ACIA.ASM)
SIOENABLE .SET TRUE ; SIO: ENABLE ZILOG SIO SERIAL DRIVER (SIO.ASM)
```
You may also need to disable other storage drivers:
```
FDENABLE .SET FALSE ; FD: ENABLE FLOPPY DISK DRIVER (FD.ASM)
IDEENABLE .SET FALSE ; IDE: ENABLE IDE DISK DRIVER (IDE.ASM)
PPIDEENABLE .SET FALSE ; PPIDE: ENABLE PARALLEL PORT IDE DISK DRIVER (PPIDE.ASM)
```
### base-drv `CHNATIVEENABLE`
The `base-drv` system contains the core code to discover, enumerate, and communicate with USB devices.
It also includes the driver code to enumerate and operating USB devices through a USB hub.
### scsi-drv `CHSCSIENABLE`
The `scsi-drv` system can be enabled with the HBIOS config `CHSCSIENABLE`
When activated, access to most USB mass storage devices (thumb drives, magnetic usb drives) is enabled.
### ufi-drv `CHUFIENABLE`
The `ufi-drv` system can be enabled with the HBIOS config `CHUFIENABLE`
When activated, access to 3.5" Floppy USB devices will be enabled.
### keyboard `TMSMODE_MSXUKY`
The `keyboard` system can be enabled with the inferred config entry `USBKYBENABLE`
This config item is not to be directly set, but is activated via the TMS keyboard driver
Example configuration, combined with the TMS VDP module driver.
```
TMSENABLE .SET TRUE ; TMS: ENABLE TMS9918 VIDEO/KBD DRIVER (TMS.ASM)
TMSMODE .SET TMSMODE_MSXUKY ; TMS: DRIVER MODE: TMSMODE_[SCG|N8|MSX|MSXKBD|MSXMKY|MBC|COLECO|DUO|NABU|MSXUKY]
TMS80COLS .SET FALSE ; TMS: ENABLE 80 COLUMN SCREEN, REQUIRES V9958
TMSTIMENABLE .SET TRUE ; TMS: ENABLE TIMER INTERRUPTS (REQUIRES IM1)
```
When activated, usb keyboards can be used as input devices.
### Force activation `CHNATIVEFORCE`
The CH376 module, during a cold power on boot, can take many seconds before it will
respond to the CPU. As such, the CPU may fail to detect the presence of the module.
A manual reset (without power cycling) generally enables detection. The config entry
`CHNATIVEFORCE` can be enabled to force the CPU to always wait for the module to come online.
### eZ80 support `CHNATIVEEZ80`
If you have the eZ80 CPU installed with onboard USB firmware support, you
can gain performance by delegating HBIOS to the firmware implementation. To enable
delegation, enable the config entry `CHNATIVEEZ80`

View File

@@ -0,0 +1,8 @@
; Generated File -- not to be modify directly
#IF (!CHNATIVEEZ80)
#include "ch376-native/scsi-drv/class_scsi.c.s"
#ENDIF
#IF (!CHNATIVEEZ80)
#include "ch376-native/scsi-drv/scsi_driver.c.s"
#ENDIF
#include "ch376-native/scsi-drv/scsi-init.c.s"

View File

@@ -0,0 +1 @@
*.asm

View File

@@ -0,0 +1,446 @@
;
; Generated from source-doc/scsi-drv/class_scsi.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_scsi_cmd_blk_wrap:
DEFS 15
_next_tag:
DEFS 2
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/scsi-drv/class_scsi.c:11: usb_error do_scsi_cmd(device_config_storage *const dev,
; ---------------------------------
; Function do_scsi_cmd
; ---------------------------------
_do_scsi_cmd:
push ix
ld ix,0
add ix,sp
ld hl, -21
add hl, sp
ld sp, hl
;source-doc/scsi-drv/class_scsi.c:17: _scsi_command_status_wrapper csw = {{{0}}};
ld a,$00
ld (ix-21),a
ld (ix-20),a
ld (ix-19),a
ld (ix-18),a
xor a
ld (ix-17),a
ld (ix-16),a
xor a
ld (ix-15),a
ld (ix-14),a
ld a,$00
ld (ix-13),a
ld (ix-12),a
ld (ix-11),a
ld (ix-10),a
ld (ix-9),$00
;source-doc/scsi-drv/class_scsi.c:19: cbw->dCBWTag[0] = next_tag++;
ld c,(ix+6)
ld b,(ix+7)
ld hl,$0004
add hl, bc
ld (ix-8),l
ld (ix-7),h
ld a, (_next_tag)
ld e, a
ld hl,_next_tag + 1
ld d, (hl)
ld hl, (_next_tag)
inc hl
ld (_next_tag), hl
ld l,(ix-8)
ld h,(ix-7)
ld (hl), e
inc hl
ld (hl), d
;source-doc/scsi-drv/class_scsi.c:21: if (!send)
bit 0,(ix+10)
jr NZ,l_do_scsi_cmd_00102
;source-doc/scsi-drv/class_scsi.c:22: cbw->bmCBWFlags = $80;
ld hl,$000c
add hl, bc
ld (hl),$80
l_do_scsi_cmd_00102:
;source-doc/scsi-drv/class_scsi.c:24: critical_begin();
push bc
call _critical_begin
pop bc
;source-doc/scsi-drv/class_scsi.c:27: &dev->endpoints[ENDPOINT_BULK_OUT]));
ld a,(ix+4)
ld (ix-6),a
ld e, a
ld a,(ix+5)
ld (ix-5),a
ld d,a
inc de
inc de
inc de
ld a,(ix-6)
ld (ix-4),a
ld l, a
ld a,(ix-5)
ld (ix-3),a
ld h,a
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
ld l,(ix+6)
ld h,(ix+7)
push bc
push de
push de
push af
inc sp
push hl
ld hl,$001f
ex (sp), hl
push hl
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
pop de
pop bc
ld a, l
or a
jp NZ, l_do_scsi_cmd_00120
;source-doc/scsi-drv/class_scsi.c:29: if (cbw->dCBWDataTransferLength != 0) {
ld hl,8
add hl, bc
ld c, (hl)
inc hl
ld b, (hl)
inc hl
inc hl
ld a, (hl)
dec hl
ld l, (hl)
or l
or b
or c
jr Z,l_do_scsi_cmd_00113
;source-doc/scsi-drv/class_scsi.c:32: &dev->endpoints[ENDPOINT_BULK_IN]));
ld (ix-2),c
ld (ix-1),b
ld c,(ix+8)
ld b,(ix+9)
;source-doc/scsi-drv/class_scsi.c:30: if (!send) {
bit 0,(ix+10)
jr NZ,l_do_scsi_cmd_00110
;source-doc/scsi-drv/class_scsi.c:32: &dev->endpoints[ENDPOINT_BULK_IN]));
ld a,(ix-6)
add a,$06
ld e, a
ld a,(ix-5)
adc a,$00
ld d, a
ld l,(ix-4)
ld h,(ix-3)
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
push de
push af
inc sp
ld l,(ix-2)
ld h,(ix-1)
push hl
push bc
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
ld a, l
or a
jr Z,l_do_scsi_cmd_00113
jr l_do_scsi_cmd_00120
l_do_scsi_cmd_00110:
;source-doc/scsi-drv/class_scsi.c:36: &dev->endpoints[ENDPOINT_BULK_OUT]));
ld l,(ix-4)
ld h,(ix-3)
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
push de
push af
inc sp
ld l,(ix-2)
ld h,(ix-1)
push hl
push bc
call _usb_data_out_transfer
pop af
pop af
pop af
inc sp
ld a, l
or a
jr NZ,l_do_scsi_cmd_00120
l_do_scsi_cmd_00113:
;source-doc/scsi-drv/class_scsi.c:41: usb_data_in_transfer((uint8_t *)&csw, sizeof(_scsi_command_status_wrapper), dev->address, &dev->endpoints[ENDPOINT_BULK_IN]));
ld a,(ix-6)
add a,$06
ld c, a
ld a,(ix-5)
adc a,$00
ld b, a
ld l,(ix-4)
ld h,(ix-3)
ld a, (hl)
rlca
rlca
rlca
rlca
and $0f
ld d, a
push bc
push de
inc sp
ld hl,$000d
push hl
ld hl,5
add hl, sp
push hl
call _usb_data_in_transfer
pop af
pop af
pop af
inc sp
ld a, l
or a
jr NZ,l_do_scsi_cmd_00120
;source-doc/scsi-drv/class_scsi.c:43: if (csw.bCSWStatus != 0 || csw.dCSWTag[0] != cbw->dCBWTag[0])
ld a,(ix-9)
or a
jr NZ,l_do_scsi_cmd_00116
ld c,(ix-17)
ld b,(ix-16)
ld l,(ix-8)
ld h,(ix-7)
ld a, (hl)
inc hl
ld h, (hl)
ld l, a
xor a
sbc hl,bc
jr Z,l_do_scsi_cmd_00117
l_do_scsi_cmd_00116:
;source-doc/scsi-drv/class_scsi.c:44: result = USB_ERR_FAIL;
ld l,$0e
jr l_do_scsi_cmd_00120
l_do_scsi_cmd_00117:
;source-doc/scsi-drv/class_scsi.c:46: result = USB_ERR_OK;
ld l,$00
;source-doc/scsi-drv/class_scsi.c:48: done:
l_do_scsi_cmd_00120:
;source-doc/scsi-drv/class_scsi.c:49: critical_end();
push hl
call _critical_end
pop hl
;source-doc/scsi-drv/class_scsi.c:50: return result;
;source-doc/scsi-drv/class_scsi.c:51: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/class_scsi.c:53: usb_error scsi_test(device_config_storage *const dev) {
; ---------------------------------
; Function scsi_test
; ---------------------------------
_scsi_test:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/class_scsi.c:55: cbw_scsi.cbw = scsi_cmd_blk_wrap;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,$000f
ld hl,_scsi_cmd_blk_wrap
ldir
;source-doc/scsi-drv/class_scsi.c:56: memset(&cbw_scsi.test, 0, sizeof(_scsi_packet_test));
ld hl,17
add hl, sp
ld b,$06
l_scsi_test_00103:
xor a
ld (hl), a
inc hl
ld (hl), a
inc hl
djnz l_scsi_test_00103
pop bc
;source-doc/scsi-drv/class_scsi.c:58: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),$00
;source-doc/scsi-drv/class_scsi.c:59: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_test);
ld (ix-13),$0c
;source-doc/scsi-drv/class_scsi.c:60: cbw_scsi.cbw.dCBWDataTransferLength = 0;
ld hl,$0008
add hl, bc
xor a
ld (hl), a
inc hl
ld (hl), a
inc hl
ld (hl), a
inc hl
ld (hl), a
;source-doc/scsi-drv/class_scsi.c:62: return do_scsi_cmd(dev, &cbw_scsi.cbw, 0, false);
xor a
push af
inc sp
ld hl,$0000
push hl
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/class_scsi.c:63: }
ld sp,ix
pop ix
ret
;source-doc/scsi-drv/class_scsi.c:67: usb_error scsi_request_sense(device_config_storage *const dev, scsi_sense_result *const sens_result) {
; ---------------------------------
; Function scsi_request_sense
; ---------------------------------
_scsi_request_sense:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/class_scsi.c:69: cbw_scsi.cbw = scsi_cmd_blk_wrap;
ld hl,0
add hl, sp
ld e,l
ld d,h
push hl
ld bc,$000f
ld hl,_scsi_cmd_blk_wrap
ldir
;source-doc/scsi-drv/class_scsi.c:70: cbw_scsi.request_sense = scsi_pckt_req_sense;
ld hl,17
add hl, sp
ex de, hl
ld bc,$000c
ld hl,_scsi_pckt_req_sense
ldir
pop bc
;source-doc/scsi-drv/class_scsi.c:72: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),$00
;source-doc/scsi-drv/class_scsi.c:73: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_packet_request_sense);
ld (ix-13),$0c
;source-doc/scsi-drv/class_scsi.c:74: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_sense_result);
ld hl,$0008
add hl, bc
ld (hl),$12
inc hl
xor a
ld (hl), a
inc hl
ld (hl), a
inc hl
ld (hl), a
;source-doc/scsi-drv/class_scsi.c:76: return do_scsi_cmd(dev, &cbw_scsi.cbw, sens_result, false);
ld e,(ix+6)
ld d,(ix+7)
xor a
push af
inc sp
push de
push bc
ld l,(ix+4)
ld h,(ix+5)
push hl
call _do_scsi_cmd
;source-doc/scsi-drv/class_scsi.c:77: }
ld sp,ix
pop ix
ret
_scsi_pckt_req_sense:
DEFB +$03
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$12
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
_scsi_cmd_blk_wrap:
DEFB +$55
DEFB +$53
DEFB +$42
DEFB +$43
DEFW +$0000
DEFW +$0000
DEFB +$00,$00, +$00, +$00
DEFB +$00
DEFB +$00
DEFB +$00
_next_tag:
DEFW +$0000

View File

@@ -0,0 +1,148 @@
;
; Generated from source-doc/scsi-drv/scsi-init.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/scsi-drv/scsi-init.c:9: void chscsi_init(void) {
; ---------------------------------
; Function chscsi_init
; ---------------------------------
_chscsi_init:
push ix
ld ix,0
add ix,sp
push af
dec sp
;source-doc/scsi-drv/scsi-init.c:11: do {
ld (ix-1),$01
l_chscsi_init_00103:
;source-doc/scsi-drv/scsi-init.c:12: usb_device_type t = usb_get_device_type(index);
ld a,(ix-1)
ld (ix-3),a
ld (ix-2),$00
pop hl
push hl
push hl
call _usb_get_device_type
pop af
ld a, l
;source-doc/scsi-drv/scsi-init.c:14: if (t == USB_IS_MASS_STORAGE) {
sub $02
jr NZ,l_chscsi_init_00104
;source-doc/scsi-drv/scsi-init.c:15: const uint8_t dev_index = find_storage_dev(); // index == -1 (no more left) should never happen
call _find_storage_dev
;source-doc/scsi-drv/scsi-init.c:17: hbios_usbstore_devs[dev_index].drive_index = dev_index + 1;
ld a, l
ld c,$00
add a, a
rl c
add a, +((_hbios_usbstore_devs) & $FF)
ld e, a
ld a, c
adc a, +((_hbios_usbstore_devs) / 256)
ld d, a
ld c, e
ld b, d
ld a, l
inc a
ld (bc), a
;source-doc/scsi-drv/scsi-init.c:18: hbios_usbstore_devs[dev_index].usb_device = index;
ld c, e
ld b, d
inc bc
ld a,(ix-1)
ld (bc), a
;source-doc/scsi-drv/scsi-init.c:20: print_string("\r\nUSB: MASS STORAGE @ $");
push hl
push de
ld hl,scsi_init_str_0
call _print_string
;source-doc/scsi-drv/scsi-init.c:21: print_uint16(index);
ld l,(ix-3)
ld h,$00
call _print_uint16
;source-doc/scsi-drv/scsi-init.c:22: print_string(":$");
ld hl,scsi_init_str_1
call _print_string
pop de
pop hl
;source-doc/scsi-drv/scsi-init.c:23: print_uint16(dev_index);
ld h,$00
push de
call _print_uint16
;source-doc/scsi-drv/scsi-init.c:24: print_string(" $");
ld hl,scsi_init_str_2
call _print_string
;source-doc/scsi-drv/scsi-init.c:25: usb_scsi_init(index);
ld l,(ix-3)
ld h,$00
push hl
call _usb_scsi_init
pop af
pop de
;source-doc/scsi-drv/scsi-init.c:26: dio_add_entry(ch_scsi_fntbl, &hbios_usbstore_devs[dev_index]);
ld hl,_ch_scsi_fntbl
call _dio_add_entry
l_chscsi_init_00104:
;source-doc/scsi-drv/scsi-init.c:29: } while (++index != MAX_NUMBER_OF_DEVICES + 1);
inc (ix-1)
ld a,(ix-1)
sub $07
jr NZ,l_chscsi_init_00103
;source-doc/scsi-drv/scsi-init.c:30: }
ld sp, ix
pop ix
ret
scsi_init_str_0:
DEFB $0d
DEFB $0a
DEFM "USB: MASS STORAGE @ $"
DEFB $00
scsi_init_str_1:
DEFM ":$"
DEFB $00
scsi_init_str_2:
DEFM " $"
DEFB $00

View File

@@ -0,0 +1,470 @@
;
; Generated from source-doc/scsi-drv/scsi_driver.c.asm -- not to be modify directly
;
;
;--------------------------------------------------------
; File Created by SDCC : free open source ISO C Compiler
; Version 4.5.0 #15248 (Linux)
;--------------------------------------------------------
; Processed by Z88DK
;--------------------------------------------------------
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
;--------------------------------------------------------
; Externals used
;--------------------------------------------------------
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
#IF 0
; .area _INITIALIZED removed by z88dk
_scsi_pkt_read_cap:
DEFS 12
_cbw:
DEFS 27
#ENDIF
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
;--------------------------------------------------------
; Home
;--------------------------------------------------------
;--------------------------------------------------------
; code
;--------------------------------------------------------
;source-doc/scsi-drv/scsi_driver.c:8: usb_error usb_scsi_init(const uint16_t dev_index) {
; ---------------------------------
; Function usb_scsi_init
; ---------------------------------
_usb_scsi_init:
push ix
ld ix,0
add ix,sp
ld hl, -18
add hl, sp
ld sp, hl
;source-doc/scsi-drv/scsi_driver.c:11: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index);
ld a,(ix+4)
call _get_usb_device_config
;source-doc/scsi-drv/scsi_driver.c:16: critical_begin();
push de
call _critical_begin
pop de
;source-doc/scsi-drv/scsi_driver.c:17: while ((result = scsi_test(dev)) && --counter > 0)
ld c,$03
l_usb_scsi_init_00102:
push bc
push de
push de
call _scsi_test
pop af
ld a, l
pop de
pop bc
ld l, a
or a
jr Z,l_usb_scsi_init_00104
dec c
jr Z,l_usb_scsi_init_00104
;source-doc/scsi-drv/scsi_driver.c:18: scsi_request_sense(dev, &response);
push bc
push de
ld hl,4
add hl, sp
push hl
push de
call _scsi_request_sense
pop af
pop af
pop de
pop bc
jr l_usb_scsi_init_00102
l_usb_scsi_init_00104:
;source-doc/scsi-drv/scsi_driver.c:19: critical_end();
push hl
call _critical_end
pop hl
;source-doc/scsi-drv/scsi_driver.c:21: return result;
;source-doc/scsi-drv/scsi_driver.c:22: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/scsi_driver.c:26: usb_error usb_scsi_read_capacity(const uint16_t dev_index, scsi_read_capacity_result *cap_result) {
; ---------------------------------
; Function usb_scsi_read_capacity
; ---------------------------------
_usb_scsi_read_capacity:
push ix
ld ix,0
add ix,sp
ld hl, -27
add hl, sp
ld sp, hl
;source-doc/scsi-drv/scsi_driver.c:27: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index);
ld a,(ix+4)
call _get_usb_device_config
;source-doc/scsi-drv/scsi_driver.c:30: cbw_scsi.cbw = scsi_cmd_blk_wrap;
push de
ld hl,2
add hl, sp
ex de, hl
ld bc,$000f
ld hl,_scsi_cmd_blk_wrap
ldir
pop de
;source-doc/scsi-drv/scsi_driver.c:31: cbw_scsi.read_capacity = scsi_pkt_read_cap;
push de
ld hl,17
add hl, sp
ex de, hl
ld bc,$000c
ld hl,_scsi_pkt_read_cap
ldir
pop de
;source-doc/scsi-drv/scsi_driver.c:33: cbw_scsi.cbw.bCBWLUN = 0;
ld (ix-14),$00
;source-doc/scsi-drv/scsi_driver.c:34: cbw_scsi.cbw.bCBWCBLength = sizeof(_scsi_read_capacity);
ld (ix-13),$0c
;source-doc/scsi-drv/scsi_driver.c:35: cbw_scsi.cbw.dCBWDataTransferLength = sizeof(scsi_read_capacity_result);
ld (ix-19),$08
xor a
ld (ix-18),a
ld (ix-17),a
ld (ix-16),a
;source-doc/scsi-drv/scsi_driver.c:37: return do_scsi_cmd(dev, &cbw_scsi.cbw, cap_result, false);
ld c,(ix+6)
ld b,(ix+7)
xor a
push af
inc sp
push bc
ld hl,3
add hl, sp
push hl
push de
call _do_scsi_cmd
pop af
pop af
pop af
inc sp
;source-doc/scsi-drv/scsi_driver.c:38: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/scsi_driver.c:58: usb_error usb_scsi_read(const uint16_t dev_index, uint8_t *const buffer) {
; ---------------------------------
; Function usb_scsi_read
; ---------------------------------
_usb_scsi_read:
push ix
ld ix,0
add ix,sp
push af
;source-doc/scsi-drv/scsi_driver.c:61: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index);
ld a,(ix+4)
call _get_usb_device_config
pop bc
push de
;source-doc/scsi-drv/scsi_driver.c:63: memset(&cbw, 0, sizeof(cbw_scsi_read_write));
ld de,_cbw
ld l, e
ld h, d
ld b,$0e
jr l_usb_scsi_read_00113
l_usb_scsi_read_00112:
ld (hl),$00
inc hl
l_usb_scsi_read_00113:
ld (hl),$00
inc hl
djnz l_usb_scsi_read_00112
;source-doc/scsi-drv/scsi_driver.c:64: cbw.cbw = scsi_cmd_blk_wrap;
ld bc,$000f
ld hl,_scsi_cmd_blk_wrap
ldir
;source-doc/scsi-drv/scsi_driver.c:66: cbw.cbw.bCBWLUN = 0;
ld hl,_cbw + 13
ld (hl),$00
;source-doc/scsi-drv/scsi_driver.c:67: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write);
ld hl,_cbw + 14
ld (hl),$0c
;source-doc/scsi-drv/scsi_driver.c:68: cbw.cbw.dCBWDataTransferLength = 512;
ld hl,$0200
ld (_cbw + 8),hl
ld h, l
ld (_cbw + 8 + 2),hl
;source-doc/scsi-drv/scsi_driver.c:70: cbw.scsi_cmd.operation_code = $28; // read operation
ld hl,_cbw + 15
ld (hl),$28
;source-doc/scsi-drv/scsi_driver.c:71: cbw.scsi_cmd.transfer_len[1] = 1;
ld hl,_cbw + 23
ld (hl),$01
;source-doc/scsi-drv/scsi_driver.c:72: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24;
pop hl
push hl
ld de,$000c
add hl, de
push hl
inc hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 17)),a
pop hl
;source-doc/scsi-drv/scsi_driver.c:73: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16;
push hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 18)),a
pop hl
;source-doc/scsi-drv/scsi_driver.c:74: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8;
push hl
inc hl
ld a, (hl)
ld ((_cbw + 19)),a
pop hl
;source-doc/scsi-drv/scsi_driver.c:75: cbw.scsi_cmd.lba[3] = dev->current_lba;
ld bc,_cbw + 20
ld a, (hl)
ld (bc), a
;source-doc/scsi-drv/scsi_driver.c:77: result = do_scsi_cmd(dev, &cbw.cbw, buffer, false);
ld c,(ix+6)
ld b,(ix+7)
push hl
xor a
push af
inc sp
push bc
ld de,_cbw
push de
ld e,(ix-2)
ld d,(ix-1)
push de
call _do_scsi_cmd
pop af
pop af
pop af
inc sp
ld a, l
pop hl
ld (ix-1),a
;source-doc/scsi-drv/scsi_driver.c:79: if (result == USB_ERR_OK)
or a
jr NZ,l_usb_scsi_read_00102
;source-doc/scsi-drv/scsi_driver.c:80: dev->current_lba++;
ld c,(hl)
push hl
inc hl
ld b, (hl)
inc hl
ld e, (hl)
inc hl
ld d, (hl)
pop hl
inc c
jr NZ,l_usb_scsi_read_00114
inc b
jr NZ,l_usb_scsi_read_00114
inc de
l_usb_scsi_read_00114:
ld (hl), c
inc hl
ld (hl), b
inc hl
ld (hl), e
inc hl
ld (hl), d
l_usb_scsi_read_00102:
;source-doc/scsi-drv/scsi_driver.c:81: return result;
ld l,(ix-1)
;source-doc/scsi-drv/scsi_driver.c:82: }
ld sp, ix
pop ix
ret
;source-doc/scsi-drv/scsi_driver.c:84: usb_error usb_scsi_write(const uint16_t dev_index, uint8_t *const buffer) {
; ---------------------------------
; Function usb_scsi_write
; ---------------------------------
_usb_scsi_write:
push ix
ld ix,0
add ix,sp
push af
;source-doc/scsi-drv/scsi_driver.c:86: device_config_storage *const dev = (device_config_storage *)get_usb_device_config(dev_index);
ld a,(ix+4)
call _get_usb_device_config
pop bc
push de
;source-doc/scsi-drv/scsi_driver.c:88: memset(&cbw, 0, sizeof(cbw_scsi_read_write));
ld de,_cbw
ld l, e
ld h, d
ld b,$0e
jr l_usb_scsi_write_00113
l_usb_scsi_write_00112:
ld (hl),$00
inc hl
l_usb_scsi_write_00113:
ld (hl),$00
inc hl
djnz l_usb_scsi_write_00112
;source-doc/scsi-drv/scsi_driver.c:89: cbw.cbw = scsi_cmd_blk_wrap;
ld bc,$000f
ld hl,_scsi_cmd_blk_wrap
ldir
;source-doc/scsi-drv/scsi_driver.c:91: cbw.cbw.bCBWLUN = 0;
ld hl,_cbw + 13
ld (hl),$00
;source-doc/scsi-drv/scsi_driver.c:92: cbw.cbw.bCBWCBLength = sizeof(_scsi_packet_read_write);
ld hl,_cbw + 14
ld (hl),$0c
;source-doc/scsi-drv/scsi_driver.c:93: cbw.cbw.dCBWDataTransferLength = 512;
ld hl,$0200
ld (_cbw + 8),hl
ld h, l
ld (_cbw + 8 + 2),hl
;source-doc/scsi-drv/scsi_driver.c:95: cbw.scsi_cmd.operation_code = $2A; // write operation
ld hl,_cbw + 15
ld (hl),$2a
;source-doc/scsi-drv/scsi_driver.c:96: cbw.scsi_cmd.transfer_len[1] = 1;
ld hl,_cbw + 23
ld (hl),$01
;source-doc/scsi-drv/scsi_driver.c:97: cbw.scsi_cmd.lba[0] = dev->current_lba >> 24;
pop hl
push hl
ld de,$000c
add hl, de
push hl
inc hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 17)),a
pop hl
;source-doc/scsi-drv/scsi_driver.c:98: cbw.scsi_cmd.lba[1] = dev->current_lba >> 16;
push hl
inc hl
inc hl
ld a, (hl)
ld ((_cbw + 18)),a
pop hl
;source-doc/scsi-drv/scsi_driver.c:99: cbw.scsi_cmd.lba[2] = dev->current_lba >> 8;
push hl
inc hl
ld a, (hl)
ld ((_cbw + 19)),a
pop hl
;source-doc/scsi-drv/scsi_driver.c:100: cbw.scsi_cmd.lba[3] = dev->current_lba;
ld bc,_cbw + 20
ld a, (hl)
ld (bc), a
;source-doc/scsi-drv/scsi_driver.c:102: result = do_scsi_cmd(dev, &cbw.cbw, buffer, true);
ld c,(ix+6)
ld b,(ix+7)
push hl
ld a,$01
push af
inc sp
push bc
ld de,_cbw
push de
ld e,(ix-2)
ld d,(ix-1)
push de
call _do_scsi_cmd
pop af
pop af
pop af
inc sp
ld a, l
pop hl
ld (ix-1),a
;source-doc/scsi-drv/scsi_driver.c:104: if (result == USB_ERR_OK)
or a
jr NZ,l_usb_scsi_write_00102
;source-doc/scsi-drv/scsi_driver.c:105: dev->current_lba++;
ld c,(hl)
push hl
inc hl
ld b, (hl)
inc hl
ld e, (hl)
inc hl
ld d, (hl)
pop hl
inc c
jr NZ,l_usb_scsi_write_00114
inc b
jr NZ,l_usb_scsi_write_00114
inc de
l_usb_scsi_write_00114:
ld (hl), c
inc hl
ld (hl), b
inc hl
ld (hl), e
inc hl
ld (hl), d
l_usb_scsi_write_00102:
;source-doc/scsi-drv/scsi_driver.c:106: return result;
ld l,(ix-1)
;source-doc/scsi-drv/scsi_driver.c:107: }
ld sp, ix
pop ix
ret
_scsi_pkt_read_cap:
DEFB +$25
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
_cbw:
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB +$00,$00, +$00, +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB +$00
DEFB $00
DEFB $00
DEFB $00
DEFB $00
DEFB +$00
DEFB $00
DEFB $00
DEFB +$00
DEFB $00
DEFB $00

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,90 @@
#include "print.h"
#include "usb-base-drv.h"
static uint16_t wait_for_state(const uint8_t loop_counter, uint8_t state, const uint8_t desired_state) __sdcccall(1) {
uint16_t r = state;
for (uint8_t i = 0; i < loop_counter; i++) {
if (state == desired_state)
break;
if (i & 1)
print_string("\b $");
else
print_string("\b*$");
r = usb_init(state);
state = r & 255;
}
return r;
}
extern const char ch376_driver_version[];
extern uint8_t CH376_DAT_PORT_ADDR;
extern uint8_t CH376_CMD_PORT_ADDR;
extern uint8_t USB_MOD_LEDS_ADDR;
// there is a weird bug with the compilier - somtimes string literals containing
// a dollar sign -- the dollar sign is ignored!
const char comma_0_x_dollar[] = {' ', '0', 'x', '$'};
static void _chnative_init(bool forced) {
uint8_t state = 0;
uint16_t r;
const uint8_t loop_counter = forced ? 40 : 5;
print_string("\r\nCH376: IO=0x$");
print_hex((uint8_t)&CH376_DAT_PORT_ADDR);
print_string(comma_0_x_dollar);
print_hex((uint8_t)&CH376_CMD_PORT_ADDR);
print_string(comma_0_x_dollar);
print_hex((uint8_t)&USB_MOD_LEDS_ADDR);
print_string(" *$");
r = wait_for_state(loop_counter, state, 1);
state = r & 255;
print_string("\bPRESENT (VER $");
r = usb_init(state);
state = r & 255;
if (state != 2) {
print_string("\rCH376: $");
print_string("VERSION FAILURE\r\n$");
return;
}
print_hex(r >> 8);
print_string(ch376_driver_version);
print_string("USB: *$");
r = wait_for_state(loop_counter, state, 3);
state = r & 255;
if (state == 2) {
print_string("\bDISCONNECTED$");
return;
}
print_string("\bCONNECTED$");
// enumerate....
r = usb_init(state);
state = r & 255;
for (uint8_t i = 0; i < loop_counter; i++) {
if (r >> 8 != 0)
break;
print_string(".$");
r = usb_init(state);
state = r & 255;
}
}
void chnative_init_force(void) { _chnative_init(true); }
void chnative_init(void) { _chnative_init(false); }

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}

View File

@@ -0,0 +1,62 @@
#ifndef __CLASS_HUB
#define __CLASS_HUB
#include "ch376.h"
#include "protocol.h"
#include <stdlib.h>
/*
wHubCharacteristics:
D1...D0: Logical Power Switching Mode
00: Ganged power switching (all ports power at once)
01: Individual port power switching
1X: Reserved. Used only on 1.0 compliant hubs that implement no power switching
D2: Identifies a Compound Device
0: Hub is not part of a compound device.
1: Hub is part of a compound device.
D4...D3: Logical Power Switching Mode
00: Global Over-current Protection. The hub reports over-current as a summation
of all ports current draw, without a breakdown of individual port
over-current status.
01: Individual Port Over-current Protection. The hub reports over-current on a
per-port basis. Each port has an over-current status.
1X: No Over-current Protection. This option is allowed only for bus-powered
*/
typedef struct {
uint8_t bDescLength;
uint8_t bDescriptorType; /* HUB Descriptor Type 0x29 */
uint8_t bNbrPorts; /* Number of ports */
uint16_t wHubCharacteristics; /* Bitmap Hub Characteristics (see above) */
uint8_t bPwrOn2PwrGood; /* Time (*2 ms) from port power on to power good */
uint8_t bHubContrCurrent; /* Maximum current used by hub controller (mA).*/
uint8_t DeviceRemovable[1]; /* bits indicating deviceRemovable and portPwrCtrlMask */
} hub_descriptor;
typedef struct {
uint16_t wPortStatus;
uint16_t wPortChange;
} hub_port_status;
#define PORT_STAT_CONNECTION 0x0001
#define PORT_STAT_ENABLE 0x0002
#define PORT_STAT_SUSPEND 0x0004
#define PORT_STAT_OVERCURRENT 0x0008
#define PORT_STAT_RESET 0x0010
#define PORT_STAT_POWER 0x0100
#define PORT_STAT_LOW_SPEED 0x0200
#define PORT_STAT_HIGH_SPEED 0x0400
#define PORT_STAT_TEST 0x0800
#define PORT_STAT_INDICATOR 0x1000
#define PORT_STAT_C_CONNECTION 0x0001
#define PORT_STAT_C_ENABLE 0x0002
#define PORT_STAT_C_SUSPEND 0x0004
#define PORT_STAT_C_OVERCURRENT 0x0008
#define PORT_STAT_C_RESET 0x0010
usb_error hub_get_descriptor(const device_config_hub *const hub_config, hub_descriptor *const hub_description) __sdcccall(1);
#endif

View File

@@ -0,0 +1,8 @@
#include "critical-section.h"
#include <stdint.h>
uint8_t in_critical_usb_section = 0;
void critical_begin() { in_critical_usb_section++; }
void critical_end() { in_critical_usb_section--; }

View File

@@ -0,0 +1,13 @@
#ifndef __CRITICAL_BLOCKS_H__
#define __CRITICAL_BLOCKS_H__
#include <stdint.h>
extern uint8_t in_critical_usb_section;
void critical_begin();
void critical_end();
#define is_in_critical_section() (in_critical_usb_section != 0)
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1 @@
#define debugger() __asm__("PUSH AF \n PUSH BC \n XOR A \n LD B, 7 \n .DB 0x49, 0xD7 \n POP BC \n POP AF")

View File

@@ -0,0 +1,11 @@
#include "hbios-driver-storage.h"
hbios_storage_device_t hbios_usbstore_devs[MAX_NUMBER_OF_DEVICES] = {{NULL}};
uint8_t find_storage_dev(void) {
for (uint8_t i = 0; i < MAX_NUMBER_OF_DEVICES; i++)
if (hbios_usbstore_devs[i].drive_index == 0)
return i;
return -1;
}

View File

@@ -0,0 +1,15 @@
#ifndef __HBIOS_DRIVER_STORAGE
#define __HBIOS_DRIVER_STORAGE
#include "usb_state.h"
typedef struct _hbios_storage_device {
uint8_t drive_index;
uint8_t usb_device;
} hbios_storage_device_t;
extern hbios_storage_device_t hbios_usbstore_devs[MAX_NUMBER_OF_DEVICES];
uint8_t find_storage_dev(void);
#endif

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,95 @@
#ifndef __HW
#define __HW
#include "ch376.h"
#include "dev_transfers.h"
#include "transfers.h"
#include <stdlib.h>
typedef struct {
uint8_t bLength;
uint8_t bDescriptorType;
} usb_descriptor_t;
#define USB_DESCR_DEVICE 1
#define USB_DESCR_CONFIGURATION 2
#define USB_DESCR_STRING 3
#define USB_DESCR_INTERFACE 4
#define USB_DESCR_ENDPOINT 5
#define USB_DESCR_DEV_QUALIFIER 6
#define USB_DESCR_OTHER_SPEED 7
#define USB_DESCR_HID 33
#define USB_DESCR_HID_REPORT 34
#define USB_DESCR_HID_PHYSICAL_DESC 35
typedef struct _device_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t bcdUSB;
uint8_t bDeviceClass;
uint8_t bDeviceSubClass;
uint8_t bDeviceProtocol;
uint8_t bMaxPacketSize0;
uint16_t idVendor;
uint16_t idProduct;
uint16_t bcdDevice;
uint8_t iManufacturer;
uint8_t iProduct;
uint8_t iSerialNumber;
uint8_t bNumConfigurations;
} device_descriptor;
typedef struct _config_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumInterfaces;
uint8_t bConfigurationvalue;
uint8_t iConfiguration;
uint8_t bmAttributes;
uint8_t bMaxPower;
} config_descriptor;
typedef struct _interface_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bInterfaceNumber;
uint8_t bAlternateSetting;
uint8_t bNumEndpoints;
uint8_t bInterfaceClass;
uint8_t bInterfaceSubClass;
uint8_t bInterfaceProtocol;
uint8_t iInterface;
} interface_descriptor, *p_interface_descriptor;
typedef struct _endpoint_descriptor {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bEndpointAddress;
uint8_t bmAttributes;
uint16_t wMaxPacketSize;
uint8_t bInterval;
} endpoint_descriptor;
extern usb_error usbtrn_get_descriptor(device_descriptor *const buffer);
extern usb_error usbtrn_get_descriptor2(device_descriptor *const buffer, const uint8_t device_address);
extern usb_error usbtrn_get_config_desc(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_config(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_clr_ep_halt(const uint8_t endpoint_number, const uint8_t device_address, const uint8_t max_packet_size);
#endif

View File

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

Some files were not shown because too many files have changed in this diff Show More