Compare commits
7 Commits
776be92c56
...
ef6286d674
Author | SHA1 | Date |
---|---|---|
Zane Kaminski | ef6286d674 | |
Zane Kaminski | 51d01f815f | |
Zane Kaminski | 636e73ff23 | |
Zane Kaminski | 2cc1076981 | |
Zane Kaminski | 3d1073a665 | |
Zane Kaminski | 147cb0600d | |
Zane Kaminski | 55bc0eaeda |
|
@ -1,2 +1,4 @@
|
|||
*.DS_Store
|
||||
obj/
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/settings.json
|
||||
|
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program 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 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
152
Makefile
152
Makefile
|
@ -5,20 +5,12 @@ LD=$(PREFIX)-ld
|
|||
OBJCOPY=$(PREFIX)-objcopy
|
||||
OBJDUMP=$(PREFIX)-objdump
|
||||
|
||||
all: bin/IIxIIcxSE30/IIxIIcxSE30_8M.bin bin/IIci/IIci_8M.bin bin/IIfx/IIfx_8M.bin bin/IIsi/IIsi_8M.bin bin/GWSys71_8M.bin bin/GWSys6_8M.bin bin/GWSys7Diagnostics_8M.bin obj/rdisk.s obj/driver.s obj/driver_abs.sym
|
||||
all: bin/ROMBUS_8M.bin obj/rombus.s obj/driver.s obj/driver_abs.sym
|
||||
|
||||
obj:
|
||||
mkdir $@
|
||||
mkdir -p $@
|
||||
bin:
|
||||
mkdir $@
|
||||
bin/IIsi: bin
|
||||
mkdir $@
|
||||
bin/IIxIIcxSE30: bin
|
||||
mkdir $@
|
||||
bin/IIci: bin
|
||||
mkdir $@
|
||||
bin/IIfx: bin
|
||||
mkdir $@
|
||||
mkdir -p $@
|
||||
|
||||
|
||||
obj/entry.o: entry.s obj
|
||||
|
@ -28,14 +20,38 @@ obj/entry_rel.sym: obj obj/entry.o
|
|||
$(OBJDUMP) -t obj/entry.o > $@
|
||||
|
||||
|
||||
obj/rdisk.o: rdisk.c obj
|
||||
$(CC) -Wall -march=68030 -c -Os $< -o $@
|
||||
obj/spi.o: spi.c obj
|
||||
$(CC) -Wall -march=68020 -c -Os $< -o $@
|
||||
obj/spi_hal.o: spi_hal.s spi_hal_common.s obj
|
||||
$(AS) $< -o $@
|
||||
obj/spi_rx8.o: spi_rx8.s spi_hal.s spi_hal_common.s obj
|
||||
$(AS) $< -o $@
|
||||
obj/spi_rx16.o: spi_rx16.s spi_hal.s spi_hal_common.s obj
|
||||
$(AS) $< -o $@
|
||||
obj/spi_tx8.o: spi_tx8.s spi_hal.s spi_hal_common.s obj
|
||||
$(AS) $< -o $@
|
||||
obj/spi_tx16.o: spi_tx16.s spi_hal.s spi_hal_common.s obj
|
||||
$(AS) $< -o $@
|
||||
obj/spi_rxtx8.o: spi_rxtx8.s spi_hal.s spi_hal_common.s obj
|
||||
$(AS) $< -o $@
|
||||
obj/spi_delay.o: spi_delay.s obj
|
||||
$(AS) $< -o $@
|
||||
|
||||
obj/rdisk.s: obj obj/rdisk.o
|
||||
$(OBJDUMP) -d obj/rdisk.o > $@
|
||||
|
||||
obj/driver.o: obj obj/entry.o obj/rdisk.o
|
||||
$(LD) -Ttext=40851D70 -o $@ obj/entry.o obj/rdisk.o
|
||||
obj/rombus.o: rombus.c obj
|
||||
$(CC) -Wall -march=68020 -c -Os $< -o $@
|
||||
|
||||
obj/rombus.s: obj obj/rombus.o
|
||||
$(OBJDUMP) -d obj/rombus.o > $@
|
||||
|
||||
obj/driver.o: obj obj/entry.o obj/rombus.o obj/spi.o obj/spi_hal.o \
|
||||
obj/spi_rx8.o obj/spi_rx16.o \
|
||||
obj/spi_tx8.o obj/spi_tx16.o \
|
||||
obj/spi_rxtx8.o
|
||||
$(LD) -Ttext=40851D70 -o $@ obj/entry.o obj/rombus.o obj/spi.o obj/spi_hal.o \
|
||||
obj/spi_rx8.o obj/spi_rx16.o \
|
||||
obj/spi_tx8.o obj/spi_tx16.o \
|
||||
obj/spi_rxtx8.o
|
||||
|
||||
obj/driver.s: obj obj/driver.o
|
||||
$(OBJDUMP) -d obj/driver.o > $@
|
||||
|
@ -43,11 +59,11 @@ obj/driver.s: obj obj/driver.o
|
|||
obj/driver_abs.sym: obj obj/driver.o
|
||||
$(OBJDUMP) -t obj/driver.o > $@
|
||||
|
||||
|
||||
bin/driver.bin: bin obj/driver.o
|
||||
$(OBJCOPY) -O binary obj/driver.o $@
|
||||
|
||||
bin/baserom_romdisk_ramtest.bin: bin roms/baserom.bin bin/driver.bin obj/driver_abs.sym obj/entry_rel.sym
|
||||
|
||||
bin/baserom_rombus_ramtest.bin: bin roms/baserom.bin bin/driver.bin obj/driver_abs.sym obj/entry_rel.sym
|
||||
cp roms/baserom.bin $@ # Copy base rom
|
||||
# Patch driver
|
||||
dd if=bin/driver.bin of=$@ bs=1 seek=335248 skip=32 conv=notrunc # Copy driver code
|
||||
|
@ -59,107 +75,19 @@ bin/baserom_romdisk_ramtest.bin: bin roms/baserom.bin bin/driver.bin obj/driver_
|
|||
cat obj/entry_rel.sym | grep "[0-9]\s*DStatus" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335230 count=2 conv=notrunc
|
||||
cat obj/entry_rel.sym | grep "[0-9]\s*DClose" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335232 count=2 conv=notrunc
|
||||
|
||||
bin/baserom_romdisk_noramtest.bin: bin bin/baserom_romdisk_ramtest.bin
|
||||
cp bin/baserom_romdisk_ramtest.bin $@ # Copy base rom
|
||||
bin/baserom_rombus_noramtest.bin: bin bin/baserom_rombus_ramtest.bin
|
||||
cp bin/baserom_rombus_ramtest.bin $@ # Copy base rom
|
||||
# Disable RAM test
|
||||
printf '\x4E\xD6' | dd of=$@ bs=1 seek=288736 count=2 conv=notrunc
|
||||
printf '\x4E\xD6' | dd of=$@ bs=1 seek=289016 count=2 conv=notrunc
|
||||
|
||||
|
||||
bin/GWSys71_8M.bin: bin bin/baserom_romdisk_noramtest.bin disks/RDisk7M5.dsk
|
||||
bin/ROMBUS_8M.bin: bin bin/baserom_rombus_noramtest.bin disks/RDisk.dsk
|
||||
# Copy base rom with ROM disk driver
|
||||
cp bin/baserom_romdisk_noramtest.bin $@
|
||||
# Patch ROM disk driver parameter table
|
||||
printf '\x00\x01\x2A\x29' | dd of=$@ bs=1 seek=335260 count=4 conv=notrunc # Patch CDR patch offset
|
||||
printf '\x40\x89\x2A\x14' | dd of=$@ bs=1 seek=335268 count=4 conv=notrunc # Patch CDR name address
|
||||
printf '\x44' | dd of=$@ bs=1 seek=335273 count=1 conv=notrunc # Patch CDR disable byte
|
||||
cp bin/baserom_rombus_noramtest.bin $@
|
||||
printf '\x00\x78\x00\x00' | dd of=$@ bs=1 seek=335276 count=4 conv=notrunc # Patch ROM disk size
|
||||
# Copy ROM disk image
|
||||
dd if=disks/RDisk7M5.dsk of=$@ bs=1024 seek=512 conv=notrunc
|
||||
|
||||
|
||||
bin/GWSys6_4M.bin: bin bin/baserom_romdisk_noramtest.bin disks/RDisk3M5.dsk
|
||||
# Copy base rom with ROM disk driver
|
||||
cp bin/baserom_romdisk_noramtest.bin $@
|
||||
# Patch ROM disk driver parameter table
|
||||
printf '\xFF\xFF\xFF\xFF' | dd of=$@ bs=1 seek=335260 count=4 conv=notrunc # Patch CDR patch offset
|
||||
printf '\x00\x00\x00\x00' | dd of=$@ bs=1 seek=335268 count=4 conv=notrunc # Patch CDR name address
|
||||
printf '\x44' | dd of=$@ bs=1 seek=335273 count=1 conv=notrunc # Patch CDR disable byte
|
||||
printf '\x00\x38\x00\x00' | dd of=$@ bs=1 seek=335276 count=4 conv=notrunc # Patch ROM disk size
|
||||
# Copy ROM disk image
|
||||
dd if=disks/RDisk3M5.dsk of=$@ bs=1024 seek=512 conv=notrunc
|
||||
|
||||
bin/GWSys6_8M.bin: bin/GWSys6_4M.bin
|
||||
cat bin/GWSys6_4M.bin > $@
|
||||
cat bin/GWSys6_4M.bin >> $@
|
||||
|
||||
|
||||
bin/GWSys7Diagnostics_8M.bin: bin bin/baserom_romdisk_ramtest.bin disks/RDisk7M5-diagnostics.dsk
|
||||
# Copy base rom with ROM disk driver
|
||||
cp bin/baserom_romdisk_ramtest.bin $@
|
||||
# Patch ROM disk driver parameter table
|
||||
printf '\xFF\xFF\xFF\xFF' | dd of=$@ bs=1 seek=335260 count=4 conv=notrunc # Patch CDR patch offset
|
||||
printf '\x00\x00\x00\x00' | dd of=$@ bs=1 seek=335268 count=4 conv=notrunc # Patch CDR name address
|
||||
printf '\x44' | dd of=$@ bs=1 seek=335273 count=1 conv=notrunc # Patch CDR disable byte
|
||||
printf '\x00\x78\x00\x00' | dd of=$@ bs=1 seek=335276 count=4 conv=notrunc # Patch ROM disk size
|
||||
# Copy ROM disk image
|
||||
dd if=disks/RDisk7M5-diagnostics.dsk of=$@ bs=1024 seek=512 conv=notrunc
|
||||
|
||||
|
||||
bin/IIxIIcxSE30/IIxIIcxSE30_512k.bin: bin/IIxIIcxSE30 roms/IIxIIcxSE30.bin
|
||||
cat roms/IIxIIcxSE30.bin > $@; cat roms/IIxIIcxSE30.bin >> $@
|
||||
|
||||
bin/IIxIIcxSE30/IIxIIcxSE30_1M.bin: bin/IIxIIcxSE30 bin/IIxIIcxSE30/IIxIIcxSE30_512k.bin
|
||||
cat bin/IIxIIcxSE30/IIxIIcxSE30_512k.bin > $@; cat bin/IIxIIcxSE30/IIxIIcxSE30_512k.bin >> $@
|
||||
|
||||
bin/IIxIIcxSE30/IIxIIcxSE30_2M.bin: bin/IIxIIcxSE30 bin/IIxIIcxSE30/IIxIIcxSE30_1M.bin
|
||||
cat bin/IIxIIcxSE30/IIxIIcxSE30_1M.bin > $@; cat bin/IIxIIcxSE30/IIxIIcxSE30_1M.bin >> $@
|
||||
|
||||
bin/IIxIIcxSE30/IIxIIcxSE30_4M.bin: bin/IIxIIcxSE30 bin/IIxIIcxSE30/IIxIIcxSE30_2M.bin
|
||||
cat bin/IIxIIcxSE30/IIxIIcxSE30_2M.bin > $@; cat bin/IIxIIcxSE30/IIxIIcxSE30_2M.bin >> $@
|
||||
|
||||
bin/IIxIIcxSE30/IIxIIcxSE30_8M.bin: bin/IIxIIcxSE30 bin/IIxIIcxSE30/IIxIIcxSE30_4M.bin
|
||||
cat bin/IIxIIcxSE30/IIxIIcxSE30_4M.bin > $@; cat bin/IIxIIcxSE30/IIxIIcxSE30_4M.bin >> $@
|
||||
|
||||
|
||||
bin/IIci/IIci_1M.bin: bin/IIci roms/IIci.bin
|
||||
cat roms/IIci.bin > $@; cat roms/IIci.bin >> $@
|
||||
|
||||
bin/IIci/IIci_2M.bin: bin/IIci bin/IIci/IIci_1M.bin
|
||||
cat bin/IIci/IIci_1M.bin > $@; cat bin/IIci/IIci_1M.bin >> $@
|
||||
|
||||
bin/IIci/IIci_4M.bin: bin/IIci bin/IIci/IIci_2M.bin
|
||||
cat bin/IIci/IIci_2M.bin > $@; cat bin/IIci/IIci_2M.bin >> $@
|
||||
|
||||
bin/IIci/IIci_8M.bin: bin/IIci bin/IIci/IIci_4M.bin
|
||||
cat bin/IIci/IIci_4M.bin > $@; cat bin/IIci/IIci_4M.bin >> $@
|
||||
|
||||
|
||||
bin/IIfx/IIfx_1M.bin: bin/IIfx roms/IIfx.bin
|
||||
cat roms/IIfx.bin > $@; cat roms/IIfx.bin >> $@
|
||||
|
||||
bin/IIfx/IIfx_2M.bin: bin/IIfx bin/IIfx/IIfx_1M.bin
|
||||
cat bin/IIfx/IIfx_1M.bin > $@; cat bin/IIfx/IIfx_1M.bin >> $@
|
||||
|
||||
bin/IIfx/IIfx_4M.bin: bin/IIfx bin/IIfx/IIfx_2M.bin
|
||||
cat bin/IIfx/IIfx_2M.bin > $@; cat bin/IIfx/IIfx_2M.bin >> $@
|
||||
|
||||
bin/IIfx/IIfx_8M.bin: bin/IIfx bin/IIfx/IIfx_4M.bin
|
||||
cat bin/IIfx/IIfx_4M.bin > $@; cat bin/IIfx/IIfx_4M.bin >> $@
|
||||
|
||||
|
||||
bin/IIsi/IIsi_1M.bin: bin/IIsi roms/IIsi.bin
|
||||
cat roms/IIsi.bin > $@; cat roms/IIsi.bin >> $@
|
||||
|
||||
bin/IIsi/IIsi_2M.bin: bin/IIsi bin/IIsi/IIsi_1M.bin
|
||||
cat bin/IIsi/IIsi_1M.bin > $@; cat bin/IIsi/IIsi_1M.bin >> $@
|
||||
|
||||
bin/IIsi/IIsi_4M.bin: bin/IIsi bin/IIsi/IIsi_2M.bin
|
||||
cat bin/IIsi/IIsi_2M.bin > $@; cat bin/IIsi/IIsi_2M.bin >> $@
|
||||
|
||||
bin/IIsi/IIsi_8M.bin: bin/IIsi bin/IIsi/IIsi_4M.bin
|
||||
cat bin/IIsi/IIsi_4M.bin > $@; cat bin/IIsi/IIsi_4M.bin >> $@
|
||||
|
||||
dd if=disks/RDisk.dsk of=$@ bs=1024 seek=512 conv=notrunc
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
#include "RDiskCP.h"
static long RDiskCPMacDev() {
int i;
// Check signature and return 0 if doesn't match
// Don't check for length byte at beginning or null byte at endss
for (i = 1; i < sizeof(RDiskSigStr)-1; i++) {
if (RDiskSigPtr[i] != RDiskSigStr[i]) {
// If signature doesn't match,
// fail if not holding R key
if (!((*((char*)0x175)) & 0x80)) { return 0; }
}
}
return 1; // Otherwise return 1 if signature matches
}
static void RDiskCPUpdate(DialogPtr cpDialog, short numItems) {
GrafPtr savePort;
Handle h;
Rect r;
short type;
char startup, ram;
// Get startup and ram from PRAM
RDiskCPReadXPRam(1, 4, &startup);
RDiskCPReadXPRam(1, 5, &ram);
// Save GrafPort and set port to dialog before updating items
GetPort(&savePort);
SetPort(cpDialog);
GetDItem(cpDialog, BootCheckbox+numItems, &type, &h, &r);
SetCtlValue((ControlHandle)h, startup & 0x01 ? 1 : 0);
GetDItem(cpDialog, MountCheckbox+numItems, &type, &h, &r);
SetCtlValue((ControlHandle)h, !(startup & 0x02) && !(startup & 0x01) ? 1 : 0);
HiliteControl((ControlHandle)h, startup & 0x01 ? 255 : 0);
GetDItem(cpDialog, RAMCheckbox+numItems, &type, &h, &r);
SetCtlValue((ControlHandle)h,
((startup & 0x01) || !(startup & 0x02)) && (ram & 0x01) ? 1 : 0);
HiliteControl((ControlHandle)h, (startup & 0x01) || !(startup & 0x02) ? 0 : 255);
GetDItem(cpDialog, DebugCheckbox+numItems, &type, &h, &r);
SetCtlValue((ControlHandle)h, startup & 0x04 && (startup & 0x01) ? 1 : 0);
HiliteControl((ControlHandle)h, !(startup & 0x01) || !*RDiskDBGDisPos ? 255 : 0);
GetDItem(cpDialog, CDROMCheckbox+numItems, &type, &h, &r);
SetCtlValue((ControlHandle)h, startup & 0x08 && (startup & 0x01) ? 1 : 0);
HiliteControl((ControlHandle)h, !(startup & 0x01) || !*RDiskCDROMDisPos ? 255 : 0);
// Restore old GrafPort
SetPort(savePort);
}
static void RDiskCPHitDev(short message, short item, short numItems,
short cpPrivateVal, EventRecord *theEvent,
void *cdevStorageValue, DialogPtr cpDialog) {
char startup, ram;
RDiskCPReadXPRam(1, 4, &startup);
RDiskCPReadXPRam(1, 5, &ram);
switch (item - numItems) {
case BootCheckbox:
if (startup & 0x01) { startup &= 0x0F & ~0x01; }
else { startup = startup & 0x0F | 0x01; }
break;
case MountCheckbox:
if (!(startup & 0x01)) {
if (startup & 0x02) { startup &= 0x0F & ~0x02; }
else { startup = startup & 0x0F | 0x02; }
}
break;
case RAMCheckbox:
if ((startup & 0x01) || !(startup & 0x02)) {
if (ram & 0x01) { ram = 0x00; }
else { ram = 0x01; }
}
break;
case DebugCheckbox:
if (startup & 0x01) {
if (startup & 0x04) { startup &= 0x0F & ~0x04; }
else { startup = startup & 0x0F | 0x04; }
}
break;
case CDROMCheckbox:
if (startup & 0x01) {
if (startup & 0x08) { startup &= 0x0F & ~0x08; }
else { startup = startup & 0x0F | 0x08; }
}
break;
};
RDiskCPWriteXPRam(1, 4, &startup);
RDiskCPWriteXPRam(1, 5, &ram);
RDiskCPUpdate(cpDialog, numItems);
}
static void RDiskCPInitDev(short message, short item, short numItems,
short cpPrivateVal, EventRecord *theEvent,
void *cdevStorageValue, DialogPtr cpDialog) {
Str15 ramSize;
Str255 dbgName = "\pMacsBug";
Str255 cdromName = "\pCD-ROM Ext.";
int i;
ramSize[0] = 2;
if (RDiskCPMacDev()) {
ramSize[1] = RDiskRAMReq[0];
ramSize[2] = RDiskRAMReq[1];
} else {
ramSize[1] = '1';
ramSize[2] = '6';
}
if (RDiskCPMacDev() && *RDiskDBGNamePos != 0) {
for (i = 0; i < 255; i++) {
dbgName[i] = (*RDiskDBGNamePos)[i];
}
}
if (RDiskCPMacDev() && *RDiskCDROMNamePos != 0) {
for (i = 0; i < 255; i++) {
cdromName[i] = (*RDiskCDROMNamePos)[i];
}
}
ParamText(ramSize, dbgName, cdromName, 0);
}
pascal long main(short message, short item, short numItems,
short cpPrivateVal, EventRecord *theEvent,
void *cdevStorageValue, DialogPtr cpDialog)
{
long ret = (long)cdevStorageValue;
// Switch to our A4 world
EnterCodeResource();
// Handle message
switch (message) {
case initDev:
RDiskCPInitDev(message, item, numItems,
cpPrivateVal, theEvent,
cdevStorageValue, cpDialog);
// (fall through to return cdevUnset)
case closeDev:
ret = cdevUnset; break;
case macDev:
ret = RDiskCPMacDev(); break;
case updateDev:
case activDev:
case deactivDev:
RDiskCPUpdate(cpDialog, numItems);
break;
case hitDev:
RDiskCPHitDev(message, item, numItems,
cpPrivateVal, theEvent,
cdevStorageValue, cpDialog);
break;
};
// Restore old A4 world and return result
ExitCodeResource();
return ret;
}
|
File diff suppressed because one or more lines are too long
|
@ -1 +0,0 @@
|
|||
#ifndef RDISKCP_H
#define RDISKCP_H
#include <A4Stuff.h>
#define BootCheckbox 3
#define BootCaption 6
#define MountCheckbox 5
#define MountCaption 8
#define RAMCheckbox 7
#define RAMCaption 10
#define DebugCheckbox 13
#define DebugCaption 14
#define CDROMCheckbox 15
#define CDROMCaption 16
#define RDiskSigPtr ((char*)0x40851D90)
#define RDiskSigStr "\5RDisk" // sizeof(RDiskSigStr) == 7
#define RDiskDBGNamePos ((char**)0x40851DA0)
#define RDiskDBGDisPos ((char**)0x40851D98)
#define RDiskDBGDisByte ((char*)0x40851DA8)
#define RDiskCDROMNamePos ((char**)0x40851DA4)
#define RDiskCDROMDisPos ((char**)0x40851D9C)
#define RDiskCDROMDisByte ((char*)0x40851DA9)
#define RDiskRAMReq ((char*)0x40851DAA)
#pragma parameter __D0 RDiskCPReadXPRam(__D0, __D1, __A0)
short RDiskCPReadXPRam(short size, short offset, char *where) =
{0x4840, 0x3001, 0xA051};
#pragma parameter __D0 RDiskCPWriteXPRam(__D0, __D1, __A0)
short RDiskCPWriteXPRam(short size, short offset, char *where) =
{0x4840, 0x3001, 0xA052};
#endif
|
|
@ -1 +0,0 @@
|
|||
(This file must be converted with BinHex 4.0)
:#9*%DA0V3e!ZD!"849K868e$3`%!!!!$q!!!!4j-8L0TCQjNC@BJ8N4*8dY$8&p
)$50NC@CTEQ8J8N4*8dY$8&p)$3dMD@jME(9NC5!m3646G(9QCLjS2Jd0)f4PCQP
ZC5"#Efpd3fKPBfYLEhJJ-`dMC'9QD@jP)%*[Eh4$BA"dD@pZ)$B0)f4PCQPZC5"
0Eh9ZG%0SC@0VBQpi)$80)f4PCQPZC5"0Eh9ZG%0KF(4TEfiJ1!dMC'9QD@jP)&*
"680SC@0VBQpi)$F0)f4PCQPZC5"538e$BA"dD@pZ)$%`$50NC@CTEQ8J4'9LG@G
$D'9MDf*[H#!a-`dMC'9QD@jP)%4PBR9R3f&`G'P[EL!a0!dMC'9QD@jP)%0%8Np
03fKPBfYLEhJJ-680)f4PCQPZC5"$4&*2680KF(4TEfiJ-6B0$50NC@CTEQ8J8N4
TFfY6D@G3G()J+#KMD'&b+LN`H$3`1$8a4$N`+3dMC'9QD@jP)&*%DA0V8fPR8h4
b)#*F09*%DA0V)L![,b"cDATPEfBS8N4TFfY6D@G6G()T)$dp)$F0$50NC@CTEQ8
J8N4TFfY%3NG1B@eP8'pc)#JSBfKKFLSU+6"i0$!i06&%36!T$50NC@CTEQ8J8N4
TFfY%3NG%DA03Eh-J+#KMD'&b+LST-(Jd-$Je-83j1#N0)f4PCQPZC5"54'PcDd4
#4d4TFd*jG'8J+#KMD'&b+LN`H$3`1$8a4%%i+3dMC'9QD@jP)&*%DA0V3d456de
1B@eP8'pc)#JSBfKKFLSU+6"i0$!i06&%363T$50NC@CTEQ8J8N4TFfY$4&*2684
TFe"[Fb!S+'0SBA)U+LN`H$3`1$8a4$P$+3dMC'9QD@jP)&*%DA0V3d456de%DA0
#HA4P)#JSBfKKFLST-(Jd-$Je-84"15N0)f4PCQPZC5"54'PcDe*"69*PF5!S+'0
SBA)U+6"i0$!i06&%38%T$3dMF(*KCfeK)("KFQ&YCA4PFL"IAd3`)&*%DA0V3e"
5C@&N@&"5B@dSAep%-#`JAep%-5`JAep"-#N0FfK[FR3J8N4TFfY$8&*PB@4B8&*
KE5KcD'pbG#"cDATP,#"cD'pbG#"[CQCcCA3X)'0SBA)J+RGSCA*P+5!p$3Pl-(J
d1$3`,#!`H$-`-$%X)$"i36!e-Adl$3dMF(*KCfeK)("KFQ&YCA4PFL"IAd3`)&*
%DA0V3e"AFQPdC9K38Q&Y+&pI4$!X)&pI4$%X)&pI36!T$A0SEh*d)&*%DA0V3e"
AFQPdC9K38Q&Y+(0SEh*d)(0THQ8X)(0SEh*d)'pQCR0PG#`JBfKKFL!UGfKPFQ8
T)$dJ$3Pl-(Jd1$3`,#!`H$-`-$%X)$"i36!e-Rdl$3dMC@jND@B0TQX!!!%!!!!
"!!!!!!!!!!!H!3")9d*3!3+#i9Ve9d*D6eT2AH3$U#iH(f!+i6X#rFS*8N4TFfY
$8#jS!J!!!%**6N&6594i!3!!!!"!!!!!!!!!3NP1390*9(J"!!!!!%!!!!!!!!!
!!!!!!!!!!!!!!!$FrS,E!!!$q!!!!4i5#!%!!!#q%J-!!!!!!3j!CQ0,@8h)Z*P
,!33S8!%%mV5$!5#!@8d#5T!!CajB!M&m!)#e@8eB!L&mIrpX6`%GI'C2`p42CB-
"@%qYBr)#3QhjVZ%45'd"qEa-!IqL%4!I!@FSi5-"qEK-!Iq8*!&R'Z%M!IQd6!(
rKL6@i5-"qE"-!3!!!3!!!!%!!!!!!!!!!"i!!!!!!!!!!!!F!"lrrbjV:
|
|
@ -1,126 +0,0 @@
|
|||
(This file must be converted with BinHex 4.0)
|
||||
:"e*%DA0V3e!!68e38Ne03d-"!*!$&[i!!!@q4cKMEfpX!*!$!3#3!a`!!"CU!!!
|
||||
@KJ#3!hJ!N!-'!*!$1!!"!$!!!J!F!129M!#3"%#!QJS!!$2`!F92k!#3!f"@H2r
|
||||
r!FkKH!!!"'`!N!-'!!)!N!-#!"`*6'PLFQ&bD@9c-CLRN!!!N"m#!"`*6'PLFQ&
|
||||
bD@9c-CLRN!!!N"m#!#J!q2r`!*!&!G58!*!'-XB##!!!!3V,@!#3%#"YC@je!*!
|
||||
%*!$Yr`%!!3#3$Jp$E'9KFL"'D@aP)'ePER8!N!3",3#3"3-!!3!#!*!$MJP54'P
|
||||
cDd03,Q-!N"EFAP$i!3%!N!N#!!)!N!11$&*%DA0V3e!ZFR0bB`#3%paH5'J"!3#
|
||||
3#30!!J!!$Qi06@&M5'9KC'9bFcBi5`#3%UZmEmN"!3#3#34!!J!!#rN*3646G(9
|
||||
QCLjS!*!@Ul((UJ!"!*!*"3!#!*!$MJP54'PcDd03,QJ!N"EFAP"b!3%!N![%!!)
|
||||
!AJ#3!`3!!4pG!!!%E!#3!`%!N!3*8N4TFfY$8#jM!*!C"J#3"3(FAP$i!*!$"+Z
|
||||
aakS!N!-$Ula[b3#3!`AFAP"b!&`!AJ"R!!%!!3#3#3%!N!3-8N4TFfY$8#jbFh*
|
||||
M!*!F!YaH5'J!N!5VX3#3"aK[b3l`!!AFA1kQ3cJ!N!J"$!$M4C!!!*!(!J#3#3(
|
||||
rN!B!!J#3$8!!id@3!!%SLR#!5!#3"4)!3`!#!*!(5!#3!dJ!N!8)!!%!#!#3"L%
|
||||
-!*!0*!$M4C!!!!5VXFHU!*!$!kZmEmN!N!-&h&j3FJ"F!*!(*!$M4C!!!*!A-!#
|
||||
3"bJ!id@3!!!"!+3!%`$R!1hY2!#3"a!!N!m`!10&N!!!*!!!!R%"K3*f!!!#F3*
|
||||
fIrm"K!*e!REqlEkY!*!'"@)!!!i)!*!$B!!!"D)!!!KQ!*!'"'`!N!F'!*!84@G
|
||||
&E3#3!`%!N!-'rj!%!*!$&P*%DA0V!%9T!*!$!J#3!e!!N!-J!*!$&Nj@!!!LI%#
|
||||
&(C&d!'!NF!!3-5!!3H`!!")`)!")JE*!C`i31!&e!N!!J'B%F!"J$&*#-%*`"E(
|
||||
!CG4`!8jH6R@08N4TFfY$8%eKBd4PGJ!!4A3!N!-"!!%!N!-@!*!%4@N!N!-0!!!
|
||||
"Y!#3!iJ!!!'B6PErkNMR%#!NEJ!)0Li!$(!"FJ4"l[rl5%!`!D"4F!&b"8(ZrqY
|
||||
)3$!"S&&)E[rXU(3[#UKc,`S`!eC!2`")E[r`5'lrr%KZrr+TM5mZrr`),J!!rrY
|
||||
Q"(!!B!*`!6m!U@-[#M!$@N!r!%KZrr")E[rm5'lrmUQ0,blrr!JZ!!(rqfF)##i
|
||||
!!2rlC`4`!'!#F!%r!+PM,blrr!JZ!!$rqfB%F!"J"$!m!2mr!+PG,`S`!ej!2`"
|
||||
)E[r`5'lrr%KZrr+TM5mZrr`3,[rl!N!!!fF)##i!!2rVCJ4`!'!#F!%r!+PM,bl
|
||||
rr"!ZrrX#3!!$CJB`2!$rB!*`!$m!U9d[#R!0d%-r!%KZrr")E[rm5'lrmUQ0,bl
|
||||
rr!JZ!!,rqfF)##i!!2rlCJ4`!'!#F!%r!+PM,blrr!JZ!!$rqfF%F!"J"$!m!2m
|
||||
r!+PG,`T`$p"$2`")E[r`5'lrr%KZrr+TM5mZrr`),J!$rrYQ#!JZ!!$rqfB%F!"
|
||||
J!R!"2`#TBbmZrr`),J!!rrYR"(!!B!3`2!$r2`#TA5mZrqbSFdcI"!K1ANjeM9*
|
||||
%DA0V3e"9F'4KG'8!!%9T!*!$6`!!!9B!!!'X!!!'X8j@rrj`!A)%3HlrrdK!-!'
|
||||
J8A!"FJ9"l[rq5%!`!D"4-#i!#T!!EJ!-9d"R'&9!Cca93'GUA8"R!!#)98"R!!#
|
||||
`B!!!f"!Zrrm#3!!"C`S#,J!1rrpJ!!$%%#lrr`*!!!m!3!!"(8$rrf!!!,!3,[r
|
||||
r!N!!!@B!!+33,[rr!N!!!QF+!Li!$IrrB!!!N!!3,[rr!N!!$`"!!!)G32rrB(`
|
||||
3,[rr!N!!!fGb%#lrrJ*!!!&R"N)ZrrjJBKem!!(rrQ"D%#lrr`*!!!&R8"!Zrrm
|
||||
#3!!%C`J#,J!,rrpJ2K!Zrrm#3!!2!%!!""e!rrpJ,"!Zrrm#3!!"Cb)3,[rr!N!
|
||||
!#'F)!Li!"rrrB"!3,[rr!N!!$`"!!!JG32rrF!&b"%(Zrrp)3$!"S&*`!A)&3Hl
|
||||
rrNK!-!'J8MmZ!!`[,J!B6U`!!%jH6R@08N4TFfY$8%KTG%4PGJ!!4B%!N!-0!!%
|
||||
!!!&!!*!%4@N!N!04!*!$B!!!!Xi!!!XH6PErm#m+*(a!K4f4(A`!![r`6U`!!%U
|
||||
!C`iGDJ!'rr%GDJ!(rr*J$"em!$(rm4em!$,rmNKZrr")H8#)!#T)H8#*,*C#TkQ
|
||||
,*&p1ANjeMP*%DA0V3e"*EQPd4'9f!*!$4B%!N!-#!!%!N!-8!*!%4@S!N!06!*!
|
||||
$XJ!!!di!!!dK6PB!!%MR(c!k,J!D1#i!&LiZ!"!QEJ!-*'i!##B,6U`!!#`!-!8
|
||||
-3!!)BQM33$!l!!C1q`!#!")!4!!X!&i!1!!i!$J!AJ!`,`S[#bm(2bi!&$m%2bi
|
||||
!'$m&6U`!!%r[!"4f!f!Z6U`!!#B!B#Br"#m+6U`!!&a2B"S[#Lm,,`Fr,J!82`3
|
||||
r,J!B2`91V!!!6qm!&#!'`B`[3`!i60m-q%jH)&p2l`!86Y#%E@&TEJ#3!d@"!*!
|
||||
$6`!"!*!$MJ#3"%@"!*!$$3!"!*!$G!#3"%@"!*!$!J!"!*!$D!#3"%@"!*!$83!
|
||||
"!*!$A!#3"%@"!*!$9!!"!*!$)!#3"%9S8eP05!!!"%!!N!-8!*!9!3#3"aB!N!-
|
||||
%!*!$2!#3!`S!N!18!*!$$J#3!m!!N!-L!!!"*J#3!c!!!!&F!*!$1J!!!9m!N!-
|
||||
m!!!"PIq3"!!!!CB!!J#3!`2rN!2q!*!#3!``!N!-,!*!&!J!"!*!'!CJ!N!-
|
||||
3!!!#4!#3!ai!!!*R!*!$,!!!!XF!N!-b!!!#h!#3!cB!!!,b!*!$6!!!!bd!N!0
|
||||
L!!!$C`#3!hJ!!!1M!*!$PJ!!!r!!N!1Z!!!%,J#3!m3!!!4S!*!$j!!!"+i!N!2
|
||||
q!!!%l!!!!43!!!8S!!!"-J!!"A3!!!&+!!!&Y3!!!@!!!!Aa!!!"IJ!!"N!!!!'
|
||||
@!!!'QJ!!!C`!!!DZrj!%!!!'V`!)!*!$$[q3!rS!N!8+!*!$53#3!`X!N!8$!*!
|
||||
$5J#3!`F!![q3!qX!N!0,!*!$"`!#rj!$q`#3!d`!N!-,!!,rN!2`!*!$6Iq3!rF
|
||||
!![q3!r)!N!-S!*!$C`!#rj!$r!#3!dlrN!2k!!,rN!2X!!%!N!B(+!#3!`3!!!G
|
||||
a!*!$%J!!"j3!N!-J!!!(X`#3!d3!!!IN!*!$@!!!#"J!N!0S!!!)43#3!f`!!!K
|
||||
P!*!$H!!!#)%!N!1-!!!)YJ#3!j`!!!MT!*!$RJ!!#3F!N!1S!!!*)3#3!lJ!!!P
|
||||
&!*!$[J!!#@-!N!2!!!!*J`#3!mS!!!QF!*!$h!!!#G%!N!2X!!!+"!#3!qi!!!S
|
||||
N!*!$q!!!#Md!!!%+!!!+FJ!!!4S!!!Uc!!!"+!!!#YF!!!%f!!!+p`!!!8)!!!X
|
||||
Erj!%!!!,(!!&!*!$8!#3!`X"!J#3!`S!N!0*!*!$#`%#!*!$$!#3!`lrN!2k!3)
|
||||
!N!-B!*!$5J#3!`F!![q3!ri!N!0,!*!$"`!#rj!%!!%!N!B,Q!#3!`B!!![I!*!
|
||||
$$!!!$!8!N!-5!!!-&J#3!aS!!!`Z!*!$)!!!$&N!N!-Q!!!-K!#3!bJ!!!b1!*!
|
||||
$,J!!$+)!N!-d!!!-Z3#3!dJ!!!dHrj!%!!!0(`!#!*!$!rq3!ri!N!8+!*!$8[q
|
||||
3!qi!![q3!r!!!3#3"Jfq!*!$(!!!$F!!N!-H!!!0r`#3!b3!!!iS!*!$5!!!$N`
|
||||
!N!0L!!!1q!#3!fB!!!mL!*!$EJ!!$hN!N!0f!!!2R`#3!hS!!!qj!*!$P!!!%'%
|
||||
!N!1B!!!3GJ#3!j`!!"#$rj!%!!!3K!!*!*!$93#3!`X!N!8&!*!$8!#3!`X"!J#
|
||||
3!aJ!N!0*!*!$#`#3"33!N!0@!*!$#`%#!*!$&!#3!eIrN!2Y!*!&"`#3!ed!N!0
|
||||
N!*!&#`#3!`lrN!2k!*!&#J#3!ei!N!-$!*!&"J#3!em!N!-$!*!&!`!"rj!%!*!
|
||||
$"J#3!`%!N!-(!!(rN!2m!*!$"J#3!`%!N!-'!!(rN!2l!*!$!J#3!`%!N!-'!!,
|
||||
rN!2p!*!$"!#3!c)!"`#3!`ArN!2m!*!("[q3!rX!N!-'!*!$"`#3!fX!N!-)!*!
|
||||
$#!#3!`%!N!--!*!$#3#3!fJ!N!-X!*!$#J#3!`B!N!-`!*!$#`#3!`B!N!-a!!$
|
||||
rN!2q!!(rN!2p!!,rN!2h!*!$&J#3!`J!"!#3!aF!N!-,!*!('!#3!`X!N!-#!*!
|
||||
$'3#3!`X!N!-%!*!$'J#3!`X!N!-'!!,rN!2i!*!$%J#3!`i!!`#3!a-!N!0Q!*!
|
||||
(&!#3!`X!N!-%!*!$&Iq3!rF!N!-'!!,rN!2e!*!$(3#3!`S!!J#3!ai!N!-,!*!
|
||||
((rq3!rF!N!-#!!$rN!2f!!,rN!2e!!(rN!2c!*!$#!#3!`%!N!-'!!,rN!2d!*!
|
||||
$)J#3!`J!!3#3!b2rN!2c!*!&![q3!r)!N!-Q!*!$"!!#!*!$*`#3!`X!N!FS!*!
|
||||
$#`#3!`)!!2q3!qm!!3#3!fS!![q3!r!!N!-l!*!$0!!0!*!$22q3!qm!N!Fprj!
|
||||
$l`#3!`3!N!-qrj!$l`#3!`J!N!-rrj!$l`#3!``!N!0!rj!$l`#3!a!!N!0"rj!
|
||||
$l`#3!a3!N!0#rj!$l`#3!aJ!N!0$rj!$l`#3!a`!N!0%rj!$l`#3!b!!N!0&rj!
|
||||
$l`#3!b3!N!0'rj!$l`#3!bJ!N!0(rj!$l`#3!b`!N!0)rj!$l`#3!c!!!2q3!r%
|
||||
!!Iq3!r!!![q3!rN!N!-2!*!$E!!D!*!$%!#3!`X!N!F4rj!$q!#3!`)!N!-Erj!
|
||||
$p`#3!a!!N!-Frj!$pJ#3!aJ!N!-Jrj!$pJ#3!a`!N!-Krj!$p!#3!b!!N!-Nrj!
|
||||
$p!#3!bJ!N!-Prj!$mJ#3!c!!N!-Trj!$mJ#3!c3!N!-U!*!$#`#3!cJ!N!-Vrj!
|
||||
$p!#3!cS!N!-X!*!$#`#3!d)!N!-Y!*!$#`#3!d3!N!-Z!*!$"J#3!dB!N!-[!*!
|
||||
$"`#3!dF!N!-`!*!$#`#3!dJ!N!-a!*!$#`#3!dS!N!-b!*!$!`#3!d`!N!-c!*!
|
||||
$!`#3!e!!N!-d!*!$!`#3!e3!N!-e!*!$#`#3!eJ!N!-f!*!$#`#3!eS!N!-h!*!
|
||||
$C`#3!e`!N!-i!*!$C`#3!f!!N!-j!*!$C`#3!f3!N!-krj!$m3#3!fJ!!2q3!rS
|
||||
!!Iq3!rN!!Iq3!qi!N!-3!*!$!3#3!`B!![q3!q`!N!0B!*!$%!!&!*!$@3#3!`S
|
||||
!N!G9!*!$!J#3!`)!N!0D!*!$!J#3!`B!N!0Erj!$mJ#3!`S!N!0F!*!$#J#3!`i
|
||||
!!2q3!qd!!Iq3!q`$H%!b-3!"FP*%DA0V3e"0B@0%CAB!!k"SC()!!)&54'PcDdK
|
||||
NFJ!$BA0TC`!$eh*KE9*PFA9TFQ9N!!(#F'&dBfK'D@aP6Q&YC3!$b("KG'0S4QP
|
||||
XC8jKE@9@CA*TCRN!!Ie`BA4MD%CTE'9#HA4P!!0iF'&dBfK'D@aP3RPdC8*PCQp
|
||||
bC3!#(h"KG'0S4QPXC8*jG'9"CR4PFJ!"D@N!!6e54'PcDd039A"NBA4P!!$jBh"
|
||||
%D@&XEfF!!'0(FQ&Q8'pbG!!#X@4PGQPMC3!!6A"[FR4#DA4c!!)Q3QPd6@&`!!#
|
||||
cBQ&cC8&NC()!!(jbEhG#HA4PF`!#+f*[G@jNF`!!Ie*PBh3!!bpdEh!!!!aXC@C
|
||||
d!!)LBQpdG'pY!!(@FQPRD(3!!#4`Eh*d8Q9MG!!#-(CTFe*REJ!#$e*PCfP[EJ!
|
||||
$3A*REP0THQ8!!mjbCfj#3Qpi!!1NBfaTF&*REJ!"Q@*V8'&d!!1U8'&dG'9bEJ!
|
||||
$BA"KG!!$&'CTE'a3BA3!!F"`ENa[B`!"T&"[D@jd!!&fGJ!"D'J!!UY`EP0THQ8
|
||||
!!KP`ENe[C'8!!Ip`EP"KG!!"&h"Z9QPc!!,HG(K'Efjd!!*9G(K'B@0P!!+jCQP
|
||||
XE'9b!!)aG(K0Ef4P!!,MG(K6DATP!!1lFh"&H(4bB3!$AfCR3fpXEh)!!cKLDd0
|
||||
[E'pb!!1pBfpXFN*TG!!#aR"KG&0dFQ9dBfJ!!h4`D@06BACP!!1KFQGZ8f&fC3!
|
||||
!$("[E(P6BACP!!%bCh*KCP"bEf0c!!-M8843FQpMF`!!4h4PH(43FQpM!!#0E'P
|
||||
ZC9"bEf-!!,PbC@0d8(*[B`!"$R*5C@0d8(*[B`!!N@pfB@a3FQpM!!-KBA*M8(*
|
||||
[B`!!m("[E(P3FQpM!!1"FQGZ8(*[B`!!UQ*TG(03FQpM!!2ZBfpYE@9ZG&"bEf-
|
||||
!!MYdH%ePBA03FQpM!!,NCf9d8'PM8(*[B`!#FA"eG&"TBe"bEf-!!'pZG@e*G'9
|
||||
YF`!$BR*KE3!$KA0dBA*dGA!!!'pdHA"P!!&bFJ!!cA0KGQ93Eh*d!!''8N4TFfY
|
||||
$8%KTG%4PGJ!!S'PdC@d!!U&54'PcDd035@jTG%4PGJ!$"A*KE90THQ8!!,0YB@P
|
||||
Z!!"(8f9d3h9bFQ9ZG%%d!!0,E@9cFf&RC3!!2Q0`8(*TGQ&dC9CKE!!!E(4SC89
|
||||
fC@jd!!1P4ACPER45C@0[FQ3!!0PhD'&d!!"6GfKPEJ!"6hGSCA*P!!%XE@pND@C
|
||||
TCA*c!!$0Bf4PGP0dEh*KCf9@B@aeC3!"HQpXC%%d!!2UFQ9d!,kVZZX!N$d"!"J
|
||||
!N!8@8N4TFfY$8%eKBd4PGJ!!!3!B!*!%!CK54'PcDd039A"NBA4P!!!"!"J!N!3
|
||||
'X9*%DA0V3e")DA4%CAB!!!%!'J#3"!XH8N4TFfY$8%PZDA4%CAB!#J!"!"!!!3!
|
||||
!$5&YB@PZ!-N!N!2Ym$`!!!%H!!!"$P"'E(-!N!AYm$3!!!)X!*!$a&"-Fh3!N!S
|
||||
"(!#3!`*38f9Rrrm!N!NF!!!"!&"6C@F!!3#3#!2`!!!4iQpLDQ3IA3#3#"A5!*!
|
||||
$Y'*bGh-IA3!!jf3!!!%!N!-%h!!!!p`!N!2L!*!$!@%!N!3"B3#3"!&K!*!%!@%
|
||||
!N!3"B3#3!`G54'PcDd03!J#3!de08&*0680$!3$rN!3!N!84!!"069"568e$3`%
|
||||
!rj!%!*!5h&c[Q`!!&[i!!!@q!!&K!*!%!@%!N!3"B3#3"!&K!*!%!@%!N!3"B3#
|
||||
3"!&K!*!%!@%!N!3"B3#3"!&K!*!%!@%!N!3"B3#3"!&K!*!%!@%!N!3"B3#3"!&
|
||||
K!*!%!@%!N!3"B3#3"!&K!*!%!@%!N!3"B3#3"!&K!*!%!J!$!*!$5J!"!!N'6@p
|
||||
ZB@0[!*!F"!!S!!S"`J+!!#J!#J(#!S!!N"!"!*!%!J#3"5J!"!%!rrm!N!Mrr`'
|
||||
3"3#3""i"!3#3#*QC!*!&-!!&!*!($8eKBdKPB@4PFR-f1%X!N"`+!!)!N!X8!!3
|
||||
!N!J"!*!-$!!%!3!!!3!"!3#3"JF!!J#3#!F!!J#3"`)%!!)""d4bEh"XCA3!N2N
|
||||
""P0[Fh9YD3#3q`S!"!#3#l`!"!!"#dGA)&*265"%DA0V!*!dFQ4cDf0NCAB!N%K
|
||||
MC'9fm#!!N!HF!2B"2!(F!3#3!`[#!*!$MJ#3$!%!N!-%h!!!!p`!N!2L!10'b!U
|
||||
S!*!$(!$5!!*`FQ9Q!!S!'R"@CA)!N!1H8e45)`#3!kS!!2rr!*!$"J#3"3(rr`#
|
||||
3!eS!N!8#rrm!N!1'!*!&"rrr!*!$ZJ#3"32rr`#3!mJ!N!8%rrm!N!2J!*!&"[r
|
||||
r!*!$m!#3"3Mrr`#3!rX!N!8*rrm!!!%'!*!&b2rr!!!$$J#3"3Arr`!!!a`!N"!
|
||||
$m2rr!*!$9!#3"!p3FQpUC@0d)&CPFR0TEfkbk3:
|
|
@ -1,34 +0,0 @@
|
|||
(This file must be converted with BinHex 4.0)
|
||||
:$&*%DA0V3e!ZFR0bB`"bFh*M8P0&4#'!!*!'#UM`C3#3"!%!N!-*N`!!#*-!!!%
|
||||
98dP8C90*9%`"!*!'"BR#!3!,!90*9'96594-!J!-8N4TFfY$8#jbFh*M!J)!N!0
|
||||
bFh*M8P0&4#'!rj!%!!"bFh*M8P0&4#'!rj!%!*!5h&c[T!#3"JUS8dP8C90*9%`
|
||||
'!*!'"C'#!3!,!90*9'9`BA9Xr`#3"J@E3J%!#`&6594PFfKXBJ%!N!B&NS)"!!X
|
||||
"8dP8CA0SE')#!*!'"C1#!J!,!90*9'9cD'aL!`#3"J@9JJ3!#`&6594PFfKXBJ3
|
||||
!N!B&QB)!3!#3!`S!!Irr!&F!h`&#!*!$J!#382q3#2L)N!D2q)lSlSlSlSrrL*!
|
||||
'M`rrN!F!N!Y!!*!8rrq!!CYY`!&rr`#3&[q3#(rr!*!%!3#38Iq3")!!!!'2(Ma
|
||||
jL4)N5BN5*%Q*%L4*MaimHF!!!!&99G99Irprr`#3@2q3)(rrN!0rrj!$!*!+!J#
|
||||
3r`#33[q3%2L)N!k2q)MZlSL1lZL)lZk)MZlSMrL)lZk)MZlSL1lZL)lZk)riL1l
|
||||
ZL)lZk)MZlSL1lZL2q)MZlSL1lZL)lZk)MZlSMrL)lZk)MZlSL1lZL)lZk)rrL*!
|
||||
1M`q"N!D2ri'3"Sm2rj!($rq3"`#3)`GMC'9f!*!'((*NFfX!N!-"4P*&4J#3"2!
|
||||
J5801)`#3"2!J!*!$Z`#l!*!&)!!J%3'J!))"!!S!N!8J!##3!!!%!*!&)!!J!*!
|
||||
&)!!J!*!&)!!J!*!Zrj!%J!!!!BmH2(Q*%L4*L4)N5BN5*%Q2(Maj`!!!!999e99
|
||||
rrhrr!*!XS!#$r`#3!`3!!2rr!*!$63"0!*-!B!#9!8%4!D!!JU!!MJ%!#J#3"!,
|
||||
3!N#B!"i!N`"J!*8"5!#6!'!!P3&"!*-!B!#9!8%!!!APL!'!!!APL!'!!+!!Mk!
|
||||
!Jrm!!!%!N"B#Dp!!N+d#E2!!N$S#DJ!2!*!&!3!H!#8"')9*)*!54f&bFQ9dG#G
|
||||
c)&G[FQYcD'p`$5#3%e*265"%DA0V)&0PG(4TEQGc!*!'!`%(!#-"*m!#!)!!N!8
|
||||
V!&`!23%p"4*#Efpd)'CbEfdJ8Np0)'4TFfX!N!8j!'m!43%qL#&"E(GKHA-JBQp
|
||||
[G#"cHA0dC@dJCR*[E5"56ddJC'PcDbi!N!C+!&`!A!%p"3j0Eh9ZG#"56ddJC'P
|
||||
cD`#3"9J!E`"N!6k)+8e[G@jd)'4TFfXJGfKPEL"LEfpdD@jR)'CbEfdJEh4SCA)
|
||||
JC(*TGQ8Z!*!'D3"F!(X"23824@jKBQaP)&*"65"NDA0V!*!'G`"[!)-"2SJU3@a
|
||||
XEhFJGh*TG'PZCb"dEb"56ddJC'PcDbiJAM"03L"538dJFQ9a*f3Z!*!&cJ"F!0S
|
||||
"2BJQ3fKKEQGPFb"hD@aX)(4KDf8JC@CQC@0d)'&QG'9b)(*PBQp[G#i!N!8R!&`
|
||||
!+!%p`!)!J3#3"FS!A!$,!6h!!J#"!*!&L!"F!)N"2F!#!)%!N!@-!&`!QJ%p"3p
|
||||
&EQ&LE'8JC'9LG@GRCA)!N!DD!'m!TJ%qL#*&EQ&LE'8J*eia*b"hD'9Z)'*[Eh4
|
||||
TEQFJCR*[E5"56ddZ!*!&U`"F!,N"23894@jKBQaP)%0%,9*265"cGA"`Eh*d!*!
|
||||
'Z3"[!-8"2SJL4@jKBQaP)#GH-LFJGfKPEL"LEfpdD@jR)'CbEfdJ8Np0,J!!!3#
|
||||
3!`Q6!!!)N`!!!48!dqYN$CJ!N!-F!3B!#QjbBh3!N!0DD@0c0!#3!fCTBh-M!*!
|
||||
$FNP$6L-!N!0q4P*&4J#3!iT#6N4-!*!$PQPME$3!N!1L8%P$9!!"!+jYB@0S!*!
|
||||
$aR*NFfX!N!254%P86!#3!pl`)2rr!*!)m#$rr`#3!`i!N!6`)2rr!*!$NJ#3"2!
|
||||
JrrmJ!!$@!*!%m#$rr`!!!pi!N!6`)2rr!!!$k3#3"2!Jrrm!!!(D!*!&J2rr!!!
|
||||
%#3$6rVJ!JIrr!!!%d!$6rXM`)2rr!!!%b!#3#J8K!*!%m#$rr`!!"L8!drm!$Np
|
||||
hEQ9b)(*PFfpeFQ0P8D8!:
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
10
entry.s
10
entry.s
|
@ -32,25 +32,25 @@ dc.l 0x00780000
|
|||
|
||||
DOpen:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDOpen
|
||||
bsr RBOpen
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
rts
|
||||
|
||||
DClose:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDClose
|
||||
bsr RBClose
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
rts
|
||||
|
||||
DPrime:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDPrime
|
||||
bsr RBPrime
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
bra.b IOReturn
|
||||
|
||||
DControl:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDCtl
|
||||
bsr RBCtl
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
cmpi.w #killCode, kcsCode(%A0)
|
||||
bne.b IOReturn
|
||||
|
@ -58,7 +58,7 @@ DControl:
|
|||
|
||||
DStatus:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDStat
|
||||
bsr RBStat
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
|
||||
IOReturn:
|
||||
|
|
89
old/Makefile
89
old/Makefile
|
@ -1,89 +0,0 @@
|
|||
# path to RETRO68
|
||||
RETRO68=~/Retro68-build/toolchain
|
||||
|
||||
PREFIX=$(RETRO68)/bin/m68k-apple-macos
|
||||
AS=$(PREFIX)-as
|
||||
CC=$(PREFIX)-gcc
|
||||
LD=$(PREFIX)-ld
|
||||
OBJCOPY=$(PREFIX)-objcopy
|
||||
OBJDUMP=$(PREFIX)-objdump
|
||||
CFLAGS=-march=68030 -c -Os
|
||||
|
||||
all: bin/rom16M_swap.bin obj/rdisk7M5.s obj/driver7M5.s obj/entry_rel.sym obj/driver_abs.sym
|
||||
|
||||
obj:
|
||||
mkdir obj
|
||||
|
||||
bin:
|
||||
mkdir bin
|
||||
|
||||
|
||||
obj/entry.o: entry.s obj
|
||||
$(AS) $< -o $@
|
||||
|
||||
obj/entry_rel.sym: obj obj/entry.o
|
||||
$(OBJDUMP) -t obj/entry.o > $@
|
||||
|
||||
|
||||
obj/rdisk7M5.o: rdisk.c obj
|
||||
$(CC) -Wall -DRDiskSize=7864320 $(CFLAGS) $< -o $@
|
||||
|
||||
obj/rdisk7M5.s: obj obj/rdisk7M5.o
|
||||
$(OBJDUMP) -d obj/rdisk7M5.o > $@
|
||||
|
||||
|
||||
obj/spi.o: spi.c obj
|
||||
$(CC) -Wall $(CFLAGS) $< -o $@
|
||||
|
||||
obj/spi.s: obj obj/spi.o
|
||||
$(OBJDUMP) -d obj/spi.o > $@
|
||||
|
||||
|
||||
obj/sdmmc.o: sdmmc.c obj
|
||||
$(CC) -Wall $(CFLAGS) -Os $< -o $@
|
||||
|
||||
obj/sdmmc.s: obj obj/sdmmc.o
|
||||
$(OBJDUMP) -d obj/sdmmc.o > $@
|
||||
|
||||
|
||||
|
||||
obj/driver7M5.o: obj obj/entry.o obj/rdisk7M5.o
|
||||
$(LD) -Ttext=40851D70 -o $@ obj/entry.o obj/rdisk7M5.o obj/spi.o obj/sdmmc.o
|
||||
|
||||
obj/driver7M5.s: obj obj/driver7M5.o
|
||||
$(OBJDUMP) -d obj/driver7M5.o > $@
|
||||
|
||||
obj/driver_abs.sym: obj obj/driver7M5.o
|
||||
$(OBJDUMP) -t obj/driver7M5.o > $@
|
||||
|
||||
|
||||
bin/driver7M5.bin: bin obj/driver7M5.o
|
||||
$(OBJCOPY) -O binary obj/driver7M5.o $@
|
||||
|
||||
bin/rom8M.bin: bin baserom.bin RDisk7M5.dsk bin bin/driver7M5.bin obj/driver_abs.sym obj/entry_rel.sym
|
||||
cp baserom.bin $@ # Copy base rom
|
||||
# Patch driver
|
||||
dd if=bin/driver7M5.bin of=$@ bs=1 seek=335248 skip=32 conv=notrunc # Copy driver code
|
||||
printf '\x78' | dd of=$@ bs=1 seek=335168 count=1 conv=notrunc # Set resource flags
|
||||
printf '\x4F' | dd of=$@ bs=1 seek=335216 count=1 conv=notrunc # Set driver flags
|
||||
cat obj/entry_rel.sym | grep "DOpen" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335224 count=2 conv=notrunc
|
||||
cat obj/entry_rel.sym | grep "DPrime" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335226 count=2 conv=notrunc
|
||||
cat obj/entry_rel.sym | grep "DControl" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335228 count=2 conv=notrunc
|
||||
cat obj/entry_rel.sym | grep "DStatus" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335230 count=2 conv=notrunc
|
||||
cat obj/entry_rel.sym | grep "DClose" | cut -c5-8 | xxd -r -p - | dd of=$@ bs=1 seek=335232 count=2 conv=notrunc
|
||||
dd if=RDisk7M5.dsk of=$@ bs=1024 seek=512 count=7680 conv=notrunc # copy disk image
|
||||
|
||||
bin/rom8M_swap.bin: bin bin/rom8M.bin
|
||||
dd if=bin/rom8M.bin of=$@ conv=swab # swap bytes
|
||||
|
||||
bin/iisi_swap.bin: bin iisi.bin
|
||||
dd if=iisi.bin of=$@ conv=swab # swap bytes
|
||||
|
||||
bin/rom16M_swap.bin: bin/iisi_swap.bin bin/rom8M_swap.bin
|
||||
cat bin/rom8M_swap.bin > $@
|
||||
cat bin/iisi_swap.bin >> $@
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -fr bin obj
|
84
old/entry.s
84
old/entry.s
|
@ -1,84 +0,0 @@
|
|||
.EQU killCode, 1
|
||||
.EQU noQueueBit, 9
|
||||
.EQU kioTrap, 6
|
||||
.EQU kioResult, 16
|
||||
.EQU kcsCode, 26
|
||||
.EQU JIODone, 0x08FC
|
||||
.GLOBAL RDiskSig
|
||||
.GLOBAL RDiskDBGNamePos
|
||||
.GLOBAL RDiskDBGDisPos
|
||||
.GLOBAL RDiskDBGDisByte
|
||||
.GLOBAL RDiskCDRNamePos
|
||||
.GLOBAL RDiskCDRDisPos
|
||||
.GLOBAL RDiskCDRDisByte
|
||||
|
||||
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
dc.l 0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
|
||||
RDiskSig:
|
||||
.ascii "\5RDisk\0"
|
||||
.align 4
|
||||
RDiskDBGDisPos:
|
||||
dc.l 0x00000031
|
||||
RDiskCDRDisPos:
|
||||
dc.l 0x00012CAF
|
||||
RDiskDBGNameAddr:
|
||||
dc.l 0x4088002A
|
||||
RDiskCDRNameAddr:
|
||||
dc.l 0x40892C96
|
||||
RDiskDBGDisByte:
|
||||
dc.b 0x44
|
||||
RDiskCDRDisByte:
|
||||
dc.b 0x44
|
||||
RDiskRAMRequired:
|
||||
.ascii "16"
|
||||
|
||||
.align 4
|
||||
DOpen:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDOpen
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
rts
|
||||
|
||||
DClose:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDClose
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
rts
|
||||
|
||||
DPrime:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDPrime
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
bra.b IOReturn
|
||||
|
||||
DControl:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDCtl
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
cmpi.w #killCode, kcsCode(%A0)
|
||||
bne.b IOReturn
|
||||
rts
|
||||
|
||||
DStatus:
|
||||
movem.l %A0-%A1, -(%SP)
|
||||
bsr RDStat
|
||||
movem.l (%SP)+, %A0-%A1
|
||||
|
||||
IOReturn:
|
||||
move.w kioTrap(%A0), %D1
|
||||
btst #noQueueBit, %D1
|
||||
beq.b Queued
|
||||
|
||||
NotQueued:
|
||||
tst.w %D0
|
||||
ble.b ImmedRTS
|
||||
clr.w %D0
|
||||
|
||||
ImmedRTS:
|
||||
move.w %D0, kioResult(%A0)
|
||||
rts
|
||||
|
||||
Queued:
|
||||
move.l JIODone, -(%SP)
|
||||
rts
|
361
old/rombus.c
361
old/rombus.c
|
@ -1,361 +0,0 @@
|
|||
#include <Memory.h>
|
||||
#include <Devices.h>
|
||||
#include <Files.h>
|
||||
#include <Disks.h>
|
||||
#include <Errors.h>
|
||||
#include <Events.h>
|
||||
#include <OSUtils.h>
|
||||
|
||||
#include "rdisk.h"
|
||||
|
||||
// Decode keyboard/PRAM settings
|
||||
static void RDDecodeSettings(Ptr recoveryEN, Ptr unmountEN, Ptr mountEN) {
|
||||
// Read PRAM
|
||||
char legacy_startup;
|
||||
RBReadXPRAM(1, 4, &legacy_startup);
|
||||
|
||||
// Decode settings: boot from recovery, unmount (don't boot), mount (after boot)
|
||||
if (RBIsRPressed()) { // R boots from ROM recovery
|
||||
*recoveryEN = 1; // Enable recovery partition
|
||||
*unmountEN = 0; // Unmount SD so we don't boot from it
|
||||
*mountEN = 1; // Mount SD later
|
||||
} else {
|
||||
*recoveryEN = 0; // Disable recovery partition
|
||||
if (legacy_startup & 0x10) { // Boot from SD disk
|
||||
*unmountEN = 0; // Don't unmount so we boot from this drive
|
||||
*mountEN = 0; // No need to mount later since we are boot disk
|
||||
} else if (legacy_startup & 0x20) { // Mount SD disk under other boot volume
|
||||
*unmountEN = 1; // Unmount to not boot from our disk
|
||||
*mountEN = 1; // Mount in accRun
|
||||
} else {
|
||||
*unmountEN = 1; // Unmount
|
||||
*mountEN = 0; // Don't mount again
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and copy
|
||||
#pragma parameter C24(__A0, __A1, __D0)
|
||||
void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) {
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
BlockMove(sourcePtr, destPtr, byteCount);
|
||||
SwapMMUMode(&mode);
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and get
|
||||
#pragma parameter __D0 G24(__A2)
|
||||
char __attribute__ ((noinline)) G24(Ptr pos) {
|
||||
long ret;
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
ret = *pos; // Peek
|
||||
SwapMMUMode(&mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and set
|
||||
#pragma parameter S24(__A2, __D3)
|
||||
void __attribute__ ((noinline)) S24(Ptr pos, char patch) {
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
*pos = patch; // Poke
|
||||
SwapMMUMode(&mode);
|
||||
}
|
||||
|
||||
// Figure out the first available drive number >= 5
|
||||
static int RBFindDrvNum() {
|
||||
DrvQElPtr dq;
|
||||
int drvNum = 5;
|
||||
for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
||||
if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; }
|
||||
}
|
||||
return drvNum;
|
||||
}
|
||||
|
||||
static void RBOpenRDisk(RDiskStorage_t *c) {
|
||||
int drvNum;
|
||||
|
||||
// Find first available drive number for ROM recovery
|
||||
drvNum = RBFindDrvNum();
|
||||
|
||||
// Set ROM recovery drive status
|
||||
//c->rStatus.track = 0;
|
||||
c->rStatus.writeProt = -1; // nonzero is write protected
|
||||
c->rStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||
c->rStatus.installed = 1; // drive installed
|
||||
//c->rStatus.sides = 0;
|
||||
//c->rStatus.qType = 1;
|
||||
c->rStatus.dQDrive = drvNum;
|
||||
//c->rStatus.dQFSID = 0;
|
||||
c->rStatus.dQRefNum = d->dCtlRefNum;
|
||||
c->rStatus.driveSize = RDiskSize / 512;
|
||||
//c->rStatus.driveS1 = (RDiskSize / 512) >> 16;
|
||||
|
||||
// Decompress icon
|
||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
||||
char *src = &RDiskIconCompressed[0];
|
||||
char *dst = &c->rIcon[0];
|
||||
UnpackBits(&src, &dst, RDISK_ICON_SIZE);
|
||||
#endif
|
||||
|
||||
// Add RDisk to drive queue and return
|
||||
RDiskAddDrive(c->rStatus.dQRefNum, drvNum, (DrvQElPtr)&c->rStatus.qLink);
|
||||
}
|
||||
|
||||
static void RBOpenSDisk(RDiskStorage_t *c) {
|
||||
int drvNum;
|
||||
|
||||
// Find first available drive number for SD disk
|
||||
drvNum = RBFindDrvNum();
|
||||
|
||||
// Set SD disk drive status
|
||||
//c->rStatus.track = 0;
|
||||
c->rStatus.writeProt = 0; // 0 is writable
|
||||
c->rStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||
c->rStatus.installed = 1; // drive installed
|
||||
//c->rStatus.sides = 0;
|
||||
c->rStatus.qType = 1;
|
||||
c->rStatus.dQDrive = drvNum;
|
||||
//c->rStatus.dQFSID = 0;
|
||||
c->rStatus.dQRefNum = d->dCtlRefNum;
|
||||
c->rStatus.driveSize = SDiskSize / 512;
|
||||
c->rStatus.driveS1 = (SDiskSize / 512) >> 16;
|
||||
|
||||
// Decompress icon
|
||||
#ifdef SDISK_COMPRESS_ICON_ENABLE
|
||||
char *src = &SDiskIconCompressed[0];
|
||||
char *dst = &c->sIcon[0];
|
||||
UnpackBits(&src, &dst, SDISK_ICON_SIZE);
|
||||
#endif
|
||||
|
||||
// Add SDisk to drive queue and return
|
||||
RDiskAddDrive(c->rstatus.dQRefNum, drvNum, (DrvQElPtr)&c->sStatus.qLink);
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBOpen(__A0, __A1)
|
||||
OSErr RBOpen(IOParamPtr p, DCtlPtr d) {
|
||||
RDiskStorage_t *c;
|
||||
char legacy_startup;
|
||||
|
||||
// Do nothing if already opened
|
||||
if (d->dCtlStorage) { return noErr; }
|
||||
|
||||
// Do nothing if inhibited
|
||||
RBReadXPRAM(1, 4, &legacy_startup);
|
||||
if (legacy_startup & 0x40) { return noErr; }
|
||||
|
||||
// Allocate storage struct
|
||||
d->dCtlStorage = NewHandleSysClear(sizeof(RDiskStorage_t));
|
||||
if (!d->dCtlStorage) { return openErr; }
|
||||
|
||||
// Lock our storage struct and get master pointer
|
||||
HLock(d->dCtlStorage);
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
|
||||
// Create RDisk and SDisk entries in drive queue, then return
|
||||
RBOpenRDisk(c);
|
||||
RBOpenSDisk(c);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// Init is called at beginning of first prime (read/write) call
|
||||
static void RBInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
||||
char recoveryEN, unmountEN, mountEN;
|
||||
// Mark init done
|
||||
c->initialized = 1;
|
||||
// Decode settings
|
||||
RDDecodeSettings(&recoveryEN, &unmountEN, &mountEN);
|
||||
|
||||
// Unmount if not booting from ROM disk
|
||||
if (!recoveryEN) { c->rStatus.diskInPlace = 0; }
|
||||
|
||||
// Unmount if not booting from ROM disk
|
||||
if (unmountEN) { c->SStatus.diskInPlace = 0; }
|
||||
|
||||
// If mount enabled, enable accRun to post disk inserted event later
|
||||
if (mountEN) {
|
||||
d->dCtlDelay = 150; // Set accRun delay (150 ticks is 2.5 sec.)
|
||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
||||
}
|
||||
}
|
||||
|
||||
static OSErr RDPrime(IOParamPtr p, DCtlPtr d) {
|
||||
// Get pointer to correct position in ROM disk buffer
|
||||
Ptr disk = RDiskBuf + d->dCtlPosition;
|
||||
|
||||
// Return disk offline error if virtual disk not inserted
|
||||
if (!c->rStatus.diskInPlace) { return offLinErr; }
|
||||
|
||||
// Bounds checking
|
||||
if (d->dCtlPosition >= RDiskSize || p->ioReqCount >= RDiskSize ||
|
||||
d->dCtlPosition + p->ioReqCount >= RDiskSize) { return paramErr; }
|
||||
|
||||
// Service read or write request
|
||||
cmd = p->ioTrap & 0x00FF;
|
||||
if (cmd == aRdCmd) {
|
||||
if (*MMU32bit) { BlockMove(disk, p->ioBuffer, p->ioReqCount); }
|
||||
else { copy24(disk, StripAddress(p->ioBuffer), p->ioReqCount); }
|
||||
} else if (cmd == aWrCmd) { return wPrErr;
|
||||
} else { return noErr; } //FIXME: Fail if cmd isn't read or write?
|
||||
|
||||
// Update count and position/offset, then return
|
||||
d->dCtlPosition += p->ioReqCount;
|
||||
p->ioActCount = p->ioReqCount;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
static OSErr SDPrime(IOParamPtr p, DCtlPtr d) {
|
||||
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBPrime(__A0, __A1)
|
||||
OSErr RBPrime(IOParamPtr p, DCtlPtr d) {
|
||||
RDiskStorage_t *c;
|
||||
char cmd;
|
||||
|
||||
// Return disk offline error if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
|
||||
// Initialize if this is the first prime call
|
||||
if (!c->initialized) { RBInit(p, d, c); }
|
||||
|
||||
if (p->ioVRefNum == c->sStatus.dQDrive) {
|
||||
return SDPrime(p, d, c);
|
||||
} else if (p->ioVRefNum == c->rStatus.dQDrive) {
|
||||
return RDPrime(p, d, c);
|
||||
} else { return nsvErr; }
|
||||
}
|
||||
|
||||
static OSErr RDCtl(CntrlParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
||||
// Handle control request based on csCode
|
||||
switch (p->csCode) {
|
||||
case kFormat: return controlErr;
|
||||
case kVerify:
|
||||
if (!c->rStatus.diskInPlace) { return controlErr; }
|
||||
return noErr;
|
||||
case kEject:
|
||||
// "Reinsert" disk if ejected illegally
|
||||
if (c->rStatus.diskInPlace) {
|
||||
PostEvent(diskEvt, c->status.dQDrive);
|
||||
}
|
||||
return controlErr; // Eject not allowed so return error
|
||||
case kDriveIcon: case kMediaIcon: // Get icon
|
||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
||||
*(Ptr*)p->csParam = (Ptr)c->rIcon;
|
||||
#else
|
||||
*(Ptr*)p->csParam = (Ptr)RDiskIcon;
|
||||
#endif
|
||||
return noErr;
|
||||
case kDriveInfo:
|
||||
// high word (bytes 2 & 3) clear
|
||||
// byte 1 = primary + fixed media + internal
|
||||
// byte 0 = drive type (0x11 is ROM disk)
|
||||
*(long*)p->csParam = 0x00000411;
|
||||
return noErr;
|
||||
case 24: // Return SCSI partition size
|
||||
*(long*)p->csParam = RDiskSize / 512;
|
||||
return noErr;
|
||||
default: return controlErr;
|
||||
}
|
||||
}
|
||||
|
||||
static OSErr SDCtl(CntrlParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
||||
// Handle control request based on csCode
|
||||
switch (p->csCode) {
|
||||
case kFormat:
|
||||
// FIXME: implement SD format
|
||||
return controlErr;
|
||||
case kVerify:
|
||||
// FIXME: implement SD verify
|
||||
return noErr;
|
||||
case kEject:
|
||||
// "Reinsert" disk if ejected illegally
|
||||
if (c->sStatus.diskInPlace) {
|
||||
PostEvent(diskEvt, c->sStatus.dQDrive);
|
||||
}
|
||||
return controlErr; // Eject not allowed so return error
|
||||
case kDriveIcon: case kMediaIcon: // Get icon
|
||||
#ifdef SDISK_COMPRESS_ICON_ENABLE
|
||||
*(Ptr*)p->csParam = (Ptr)c->sIcon;
|
||||
#else
|
||||
*(Ptr*)p->csParam = (Ptr)SDiskIcon;
|
||||
#endif
|
||||
return noErr;
|
||||
case kDriveInfo:
|
||||
// high word (bytes 2 & 3) clear
|
||||
// byte 1 = primary + fixed media + internal
|
||||
// byte 0 = drive type (0x01 is unspecified drive)
|
||||
*(long*)p->csParam = 0x00000401;
|
||||
return noErr;
|
||||
case 24: // Return SCSI partition size
|
||||
*(long*)p->csParam = SDiskSize / 512;
|
||||
return noErr;
|
||||
default: return controlErr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBCtl(__A0, __A1)
|
||||
OSErr RBCtl(CntrlParamPtr p, DCtlPtr d) {
|
||||
RDiskStorage_t *c;
|
||||
// Fail if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
// Handle control request based on csCode
|
||||
switch (p->csCode) {
|
||||
case killCode:
|
||||
return noErr;
|
||||
case accRun:
|
||||
d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun
|
||||
c->sStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||
PostEvent(diskEvt, c->sStatus.dQDrive); // Post disk inserted event
|
||||
return noErr;
|
||||
case 2351: // Post-boot
|
||||
c->initialized = 1; // Skip initialization
|
||||
d->dCtlDelay = 30; // Set accRun delay (30 ticks is 0.5 sec.)
|
||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// Otherwise, dispatch to correct drive
|
||||
if (p->ioVRefNum == c->sStatus.dQDrive) {
|
||||
return SDCtl(p, d, c);
|
||||
} else if (p->ioVRefNum == c->rStatus.dQDrive) {
|
||||
return RDCtl(p, d, c);
|
||||
} else { return nsvErr; }
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBStat(__A0, __A1)
|
||||
OSErr RBStat(CntrlParamPtr p, DCtlPtr d) {
|
||||
RDiskStorage_t *c;
|
||||
// Fail if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
// Handle status request based on csCode
|
||||
switch (p->csCode) {
|
||||
case kDriveStatus:
|
||||
// Otherwise, copy correct drive status
|
||||
if (p->ioVRefNum == c->sStatus.dQDrive) {
|
||||
BlockMove(&c->sStatus, &p->csParam, sizeof(DrvSts2));
|
||||
} else if (p->ioVRefNum == c->rStatus.dQDrive) {
|
||||
BlockMove(&c->rStatus, &p->csParam, sizeof(DrvSts2));
|
||||
} else { return nsvErr; }
|
||||
return noErr;
|
||||
default: return statusErr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBClose(__A0, __A1)
|
||||
OSErr RBClose(IOParamPtr p, DCtlPtr d) {
|
||||
// If dCtlStorage not null, dispose of it
|
||||
if (!d->dCtlStorage) { return noErr; }
|
||||
//RDiskStorage_t *c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
HUnlock(d->dCtlStorage);
|
||||
DisposeHandle(d->dCtlStorage);
|
||||
d->dCtlStorage = NULL;
|
||||
return noErr;
|
||||
}
|
179
old/rombus.h
179
old/rombus.h
|
@ -1,179 +0,0 @@
|
|||
#ifndef ROMBUS_H
|
||||
#define ROMBUS_H
|
||||
|
||||
#define RDiskBuf ((char*)0x408C0000)
|
||||
#define SDiskSize (0x80000000L)
|
||||
#define BufPtr ((Ptr*)0x10C)
|
||||
#define MemTop ((Ptr*)0x108)
|
||||
#define MMU32bit ((char*)0xCB2)
|
||||
|
||||
#pragma parameter __D0 RBReadXPRAM(__D0, __D1, __A0)
|
||||
OSErr RBReadXPRAM(short numBytes, short whichByte, Ptr dest) = {0x4840, 0x3001, 0xA051};
|
||||
|
||||
#pragma parameter __D0 RBAddDrive(__D1, __D0, __A0)
|
||||
OSErr RBAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) = {0x4840, 0x3001, 0xA04E};
|
||||
|
||||
static inline char RBIsRPressed() { return *((char*)0x175) & 0x80; }
|
||||
|
||||
typedef struct RBStorage_s {
|
||||
DrvSts2 sStatus;
|
||||
DrvSts2 rStatus;
|
||||
char initialized;
|
||||
} RBStorage_t;
|
||||
|
||||
typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long);
|
||||
#define copy24(s, d, b) { RDiskCopy_t f = C24; f(s, d, b); }
|
||||
|
||||
typedef char (*RDiskPeek_t)(Ptr);
|
||||
#define peek24(a, d) { RDiskPeek_t f = G24; d = f(a); }
|
||||
|
||||
typedef void (*RDiskPoke_t)(Ptr, char);
|
||||
#define poke24(a, d) { RDiskPoke_t f = S24; f(a, d); }
|
||||
|
||||
#define RDISK_ICON_SIZE (285)
|
||||
const char RDiskIcon[RDISK_ICON_SIZE] = {
|
||||
// Icon
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b10000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||
0b10001001, 0b00010010, 0b00100100, 0b01001001,
|
||||
0b10001111, 0b00011110, 0b00111100, 0b01111001,
|
||||
0b11000000, 0b00000000, 0b00000000, 0b00000001,
|
||||
0b01010101, 0b01010101, 0b11010101, 0b01010101,
|
||||
0b01111111, 0b11111111, 0b01111111, 0b11111111,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
// Mask
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b11111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b01111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b01111111, 0b11111111, 0b11111111, 0b11111111,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
27, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
||||
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
||||
'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0
|
||||
};
|
||||
|
||||
#define SDISK_ICON_SIZE (283)
|
||||
const char const SDiskIcon[SDISK_ICON_SIZE] = {
|
||||
// Icon
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000001, 0b00000001, 0b10000000, 0b11010000,
|
||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
||||
0b00000001, 0b01101101, 0b10110110, 0b11010000,
|
||||
0b00000001, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000001, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000100, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001110, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000010, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00000100, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001000, 0b00000000, 0b00000000, 0b00010000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
// Mask
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000001, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000011, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00001111, 0b11111111, 0b11111111, 0b11110000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
25, 'G', 'a', 'r', 'r', 'e', 't', 't', '\'', 's', ' ',
|
||||
'W', 'o', 'r', 'k', 's', 'h', 'o', 'p', ' ',
|
||||
'R', 'O', 'M', 'B', 'U', 'S', 0
|
||||
};
|
||||
|
||||
#endif
|
220
old/sdmmc.c
220
old/sdmmc.c
|
@ -1,220 +0,0 @@
|
|||
#include "sdmmc.h"
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Module Private Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#define INIT_PORT() init_port() /* Initialize MMC control port (CS/CLK/DI:output, DO:input) */
|
||||
#define DLY_US(n) dly_us(n) /* Delay n microseconds */
|
||||
#define FORWARD(d) forward(d) /* Data in-time processing function (depends on the project) */
|
||||
|
||||
/* Definitions for MMC/SDC command */
|
||||
#define CMD0 (0x40+0) /* GO_IDLE_STATE */
|
||||
#define CMD1 (0x40+1) /* SEND_OP_COND (MMC) */
|
||||
#define ACMD41 (0xC0+41) /* SEND_OP_COND (SDC) */
|
||||
#define CMD8 (0x40+8) /* SEND_IF_COND */
|
||||
#define CMD16 (0x40+16) /* SET_BLOCKLEN */
|
||||
#define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
|
||||
#define CMD24 (0x40+24) /* WRITE_BLOCK */
|
||||
#define CMD55 (0x40+55) /* APP_CMD */
|
||||
#define CMD58 (0x40+58) /* READ_OCR */
|
||||
|
||||
/* Card type flags (CardType) */
|
||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
||||
#define CT_SD1 0x02 /* SD ver 1 */
|
||||
#define CT_SD2 0x04 /* SD ver 2 */
|
||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
||||
#define CT_BLOCK 0x08 /* Block addressing */
|
||||
|
||||
|
||||
|
||||
static char CardType; /* 0:MMC, 1:SDv1, 2:SDv2, 3:Block addressing */
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Send a command packet to MMC */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
static char send_cmd(char cmd, long arg)
|
||||
{
|
||||
char n, res;
|
||||
|
||||
if (cmd & 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
|
||||
cmd &= 0x7F;
|
||||
res = send_cmd(CMD55, 0);
|
||||
if (res > 1) return res;
|
||||
}
|
||||
|
||||
/* Select the card */
|
||||
CS_H(); spi_rx();
|
||||
CS_L(); spi_rx();
|
||||
|
||||
/* Send a command packet */
|
||||
spi_tx(cmd); /* Start + Command index */
|
||||
s((BYTE)(arg >> 24)); /* Argument[31..24] */
|
||||
spi_tx((BYTE)(arg >> 16)); /* Argument[23..16] */
|
||||
spi_tx((BYTE)(arg >> 8)); /* Argument[15..8] */
|
||||
spi_tx((BYTE)arg); /* Argument[7..0] */
|
||||
n = 0x01; /* Dummy CRC + Stop */
|
||||
if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */
|
||||
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
|
||||
spi_tx(n);
|
||||
|
||||
/* Receive a command response */
|
||||
n = 10; /* Wait for a valid response in timeout of 10 attempts */
|
||||
do {
|
||||
res = spi_rx();
|
||||
} while ((res & 0x80) && --n);
|
||||
|
||||
return res; /* Return with the response value */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
|
||||
Public Functions
|
||||
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Initialize Disk Drive */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
sdstatus_t sdmmc_init()
|
||||
{
|
||||
char n, cmd, ty, buf[4];
|
||||
uint tmr;
|
||||
|
||||
CS_H();
|
||||
spi_skip(10); /* Dummy clocks */
|
||||
|
||||
ty = 0;
|
||||
if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
|
||||
if (send_cmd(CMD8, 0x1AA) == 1) { /* SDv2 */
|
||||
for (n = 0; n < 4; n++) buf[n] = spi_rx(); /* Get trailing return value of R7 resp */
|
||||
if (buf[2] == 0x01 && buf[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
|
||||
for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state (ACMD41 with HCS bit) */
|
||||
if (send_cmd(ACMD41, 1UL << 30) == 0) break;
|
||||
DLY_US(1000);
|
||||
}
|
||||
if (tmr && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */
|
||||
for (n = 0; n < 4; n++) buf[n] = spi_rx();
|
||||
ty = (buf[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; /* SDv2 (HC or SC) */
|
||||
}
|
||||
}
|
||||
} else { /* SDv1 or MMCv3 */
|
||||
if (send_cmd(ACMD41, 0) <= 1) {
|
||||
ty = CT_SD1; cmd = ACMD41; /* SDv1 */
|
||||
} else {
|
||||
ty = CT_MMC; cmd = CMD1; /* MMCv3 */
|
||||
}
|
||||
for (tmr = 1000; tmr; tmr--) { /* Wait for leaving idle state */
|
||||
if (send_cmd(cmd, 0) == 0) break;
|
||||
DLY_US(1000);
|
||||
}
|
||||
if (!tmr || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */
|
||||
ty = 0;
|
||||
}
|
||||
}
|
||||
CardType = ty;
|
||||
release_spi();
|
||||
|
||||
return ty ? 0 : STA_NOINIT;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Read partial sector */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
sdresult_t sdmmc_readp(Ptr buf, long sector, uint offset, uint count)
|
||||
{
|
||||
DRESULT res;
|
||||
char d;
|
||||
uint bc, tmr;
|
||||
|
||||
|
||||
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
|
||||
|
||||
res = RES_ERROR;
|
||||
if (send_cmd(CMD17, sector) == 0) { /* READ_SINGLE_BLOCK */
|
||||
|
||||
tmr = 1000;
|
||||
do { /* Wait for data packet in timeout of 100ms */
|
||||
DLY_US(100);
|
||||
d = spi_rx();
|
||||
} while (d == 0xFF && --tmr);
|
||||
|
||||
if (d == 0xFE) { /* A data packet arrived */
|
||||
bc = 514 - offset - count;
|
||||
|
||||
/* Skip leading bytes */
|
||||
if (offset) spi_skip(offset);
|
||||
|
||||
/* Receive a part of the sector */
|
||||
if (buff) { /* Store data to the memory */
|
||||
do
|
||||
*buff++ = spi_rx();
|
||||
while (--count);
|
||||
} else { /* Forward data to the outgoing stream */
|
||||
do {
|
||||
d = spi_rx();
|
||||
FORWARD(d);
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
/* Skip trailing bytes and CRC */
|
||||
spi_skip(bc);
|
||||
|
||||
res = RES_OK;
|
||||
}
|
||||
}
|
||||
|
||||
release_spi();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------------*/
|
||||
/* Write partial sector */
|
||||
/*-----------------------------------------------------------------------*/
|
||||
sdresult_t sdmmc_writep(const Ptr buf, long sc)
|
||||
{
|
||||
DRESULT res;
|
||||
UINT bc, tmr;
|
||||
static UINT wc;
|
||||
|
||||
res = RES_ERROR;
|
||||
|
||||
if (buff) { /* Send data bytes */
|
||||
bc = (UINT)sc;
|
||||
while (bc && wc) { /* Send data bytes to the card */
|
||||
spi_tx(*buff++);
|
||||
wc--; bc--;
|
||||
}
|
||||
res = RES_OK;
|
||||
} else {
|
||||
if (sc) { /* Initiate sector write transaction */
|
||||
if (!(CardType & CT_BLOCK)) sc *= 512; /* Convert to byte address if needed */
|
||||
if (send_cmd(CMD24, sc) == 0) { /* WRITE_SINGLE_BLOCK */
|
||||
spi_tx(0xFF); spi_tx(0xFE); /* Data block header */
|
||||
wc = 512; /* Set byte counter */
|
||||
res = RES_OK;
|
||||
}
|
||||
} else { /* Finalize sector write transaction */
|
||||
bc = wc + 2;
|
||||
while (bc--) spi_tx(0); /* Fill left bytes and CRC with zeros */
|
||||
if ((spi_rx() & 0x1F) == 0x05) { /* Receive data resp and wait for end of write process in timeout of 300ms */
|
||||
for (tmr = 10000; spi_rx() != 0xFF && tmr; tmr--) /* Wait for ready (max 1000ms) */
|
||||
DLY_US(100);
|
||||
if (tmr) res = RES_OK;
|
||||
}
|
||||
release_spi();
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
29
old/sdmmc.h
29
old/sdmmc.h
|
@ -1,29 +0,0 @@
|
|||
#ifndef SDMMC_H
|
||||
#define SDMMC_H
|
||||
|
||||
|
||||
/* Status of Disk Functions */
|
||||
typedef char sdstatus_t;
|
||||
|
||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||
|
||||
|
||||
/* Results of Disk Functions */
|
||||
typedef enum sdmmc_result_e {
|
||||
RES_OK = 0, /* 0: Function succeeded */
|
||||
RES_ERROR, /* 1: Disk error */
|
||||
RES_NOTRDY, /* 2: Not ready */
|
||||
RES_PARERR /* 3: Invalid parameter */
|
||||
} sdresult_t;
|
||||
|
||||
|
||||
/*---------------------------------------*/
|
||||
/* Prototypes for disk control functions */
|
||||
/*---------------------------------------*/
|
||||
sdstatus_t sdmmc_init();
|
||||
sdresult_t sdmmc_readp(Ptr buf, long sector, uint offset, uint count);
|
||||
sdresult_t sdmmc_writep(const Ptr buf, long sc);
|
||||
|
||||
|
||||
#endif
|
164
old/spi.c
164
old/spi.c
|
@ -1,164 +0,0 @@
|
|||
#include "spi.h"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
/* Platform dependent macros and functions needed to be modified */
|
||||
/*-------------------------------------------------------------------------*/
|
||||
#define CS_H() bset(P0) /* Set MMC CS "high" */
|
||||
#define CS_L() bclr(P0) /* Set MMC CS "low" */
|
||||
#define CK_H() bset(P1) /* Set MMC SCLK "high" */
|
||||
#define CK_L() bclr(P1) /* Set MMC SCLK "low" */
|
||||
#define DI_H() bset(P2) /* Set MMC DI "high" */
|
||||
#define DI_L() bclr(P2) /* Set MMC DI "low" */
|
||||
#define DO btest(P3) /* Test MMC DO (high:true, low:false) */
|
||||
|
||||
|
||||
// Command listing
|
||||
/* T16: Transfer 16-bit
|
||||
* First, the 16-bit value encoded in the address bits A[17:2] is latched.
|
||||
* The data output mux is set to the current RXR and the cycle completes.
|
||||
* Shortly after /AS rises, the SPI transfer engine begins
|
||||
* transferring the latched value.
|
||||
*/
|
||||
/* T16S: Transfer 16-bit Swapped
|
||||
* Same as T16L but read data is byte-swapped.
|
||||
*/
|
||||
/* MERT: Measure Elapsed time and Reset Timer
|
||||
* The elapsed time since the last MERT command is returned in D[31:24]
|
||||
* and the timer is reset.
|
||||
*/
|
||||
/* SKIP1: Skip Clocks with MOSI "1"
|
||||
*
|
||||
*/
|
||||
/* SKIP0: Skip Clocks with MOSI "0"
|
||||
*
|
||||
*/
|
||||
/* T8S: Transfer 8-bit Swapped
|
||||
* Same as T8 but read data is byte-swapped.
|
||||
*/
|
||||
/* T8: Transfer 8-bit
|
||||
* First, the 8-bit value encoded in the address bits A[9:2] is latched.
|
||||
* The data output mux is set to the current RXR and the cycle completes.
|
||||
* Shortly after /AS rises, the SPI transfer engine begins
|
||||
* transferring the latched value.
|
||||
*/
|
||||
/* WRC: Write Command
|
||||
* The command encoded in address bits A[9:2] is sent to the command target
|
||||
* corresponding to the address bits A[15:10].
|
||||
* Command targets:
|
||||
* $00 - Set bitbang
|
||||
* A[2] - SCS value
|
||||
*/
|
||||
/* RDRXR: Read Receive Data Register
|
||||
* The the current RXR is returned in D[31:16] and the cycle completes.
|
||||
*/
|
||||
/* RDRXRS: Read Receive Data Register Swapped
|
||||
* Same as RDRXR but read data is byte-swapped.
|
||||
*/
|
||||
/* MAGIC: Write Command
|
||||
* Write sequence $FF $00 $55 $AA $C1 $AD
|
||||
* to enable registers at $40890000-$4097FFFF.
|
||||
* Write anything else to disable them.
|
||||
* Always reads 0xC1AD
|
||||
*/
|
||||
|
||||
// SPI controller address map:
|
||||
// 40940000-4097FFFF (256 kB, D[31:16]) T16S. Write transfer data in A[17:2].
|
||||
// 40900000-4093FFFF (256 kB, D[31:16]) T16. Write transfer data in A[17:2].
|
||||
// 408C0000-408FFFFF (320 kB) reserved
|
||||
// 408A0000-408AFFFF ( 64 kB, D[31:24]) WRC. Write port address in A[15:10] and data in A[9:2].
|
||||
// 40891C00-4089FFFF ( 55 kB) reserved
|
||||
// 40892000-408923FF ( 1 kB, D[31:24]) MERT.
|
||||
// 40891C00-40891FFF ( 1 kB) SKIP1. Write bytes to skip in A[9:2].
|
||||
// 40891800-40891BFF ( 1 kB) SKIP0. Write bytes to skip in A[9:2].
|
||||
// 40891400-408917FF ( 1 kB, D[31:16]) T8S. Write transfer data in A[9:2].
|
||||
// 40891000-408913FF ( 1 kB, D[31:16]) T8. Write transfer data in A[9:2].
|
||||
// 40890C00-40890FFF ( 1 kB, D[31:16]) RDRXRS.
|
||||
// 40890800-40890BFF ( 1 kB, D[31:16]) RDRXR.
|
||||
// 40890400-408907FF ( 1 kB) reserved
|
||||
// 40890000-408903FF ( 1 kB, D[31:24]) MAGIC. Write magic numbers in A[9:2].
|
||||
// 40880000-408FFFFF ( 64 kB, D[31:00]) ROMBUS driver data
|
||||
|
||||
#define RB_T16S(x) (*(volatile int*) (0x40940000 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_T16(x) (*(volatile int*) (0x40900000 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_RDS(a) (*(volatile char*) (0x408B0000 + ((a && 0x003F)<<10)) )
|
||||
#define RB_WRC(a,d) (*(volatile char*) (0x408A0000 + ((a && 0x003F)<<10)
|
||||
+ ((d && 0x00FF)<<02)) )
|
||||
#define RB_MERT(x) (*(volatile char*) (0x40892000 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_SKIP1(n) (*(volatile char*) (0x40891C00 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_SKIP0(n) (*(volatile char*) (0x40891800 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_T8S(x) (*(volatile int*) (0x40891400 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_T8(x) (*(volatile int*) (0x40891000 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_RDRXRS (*(volatile int*) (0x40890C00 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_RDRXR (*(volatile int*) (0x40890800 + ((x && 0xFFFF)<<02)) )
|
||||
#define RB_WRMOSI(x) (*(volatile char*) (0x40890400 + ((x && 0x0001)<<02)) )
|
||||
#define RB_MAGIC(x) (*(volatile char*) (0x40890000 + ((x && 0xFFFF)<<02)) )
|
||||
|
||||
#define SPI_GET_MISO(d) (d & 1)
|
||||
|
||||
void spi_select() {
|
||||
ret = *SPI_CMD_SEL0;
|
||||
ret = *SPI_CMD_SEL1;
|
||||
ret = *SPI_CMD_SEL2;
|
||||
ret = *SPI_CMD_SEL3;
|
||||
}
|
||||
void spi_deselect() {
|
||||
ret = *SPI_CMD_DES0;
|
||||
ret = *SPI_CMD_DES1;
|
||||
ret = *SPI_CMD_DES2;
|
||||
ret = *SPI_CMD_DES3;
|
||||
}
|
||||
|
||||
void spi_tx_slow(char d) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*SPI_CMD_BBA((0 & 0x02) | (d & 0x01));
|
||||
*SPI_CMD_BBA((1 & 0x02) | (d & 0x01));
|
||||
d >>= 1;
|
||||
}
|
||||
*SPI_CMD_BBA((0 & 0x02) | (0 & 0x01));
|
||||
}
|
||||
|
||||
char spi_rx_slow() {
|
||||
char ret = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*SPI_CMD_BBA((0 & 0x02) | (1 & 0x01));
|
||||
*SPI_CMD_BBA((1 & 0x02) | (1 & 0x01));
|
||||
ret = (ret << 1) + (*SPI_CMD_BBA((1 & 0x02) | (1 & 0x01)) & 1);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void spi_skip_slow(int n) {
|
||||
while (n-- > 0) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*SPI_CMD_BBA((0 & 0x02) | (1 & 0x01));
|
||||
*SPI_CMD_BBA((1 & 0x02) | (1 & 0x01));
|
||||
}
|
||||
}
|
||||
*SPI_CMD_BBA((0 & 0x02) | (1 & 0x01));
|
||||
}
|
||||
|
||||
void spi_tx_8(char d) {
|
||||
*SPI_CMD_SH8(d);
|
||||
}
|
||||
|
||||
char spi_rx_8() {
|
||||
*SPI_CMD_SH8(0xFF);
|
||||
return *SPI_CMD_RD & 0xFF;
|
||||
}
|
||||
|
||||
void spi_tx_16(int d) {
|
||||
*SPI_CMD_SH16(d);
|
||||
}
|
||||
|
||||
int spi_rx_16() {
|
||||
*SPI_CMD_SH16(0xFFFF);
|
||||
return *SPI_CMD_RD & 0xFFFF;
|
||||
}
|
||||
|
||||
void spi_skip(int n) {
|
||||
while (n-- > 0) {
|
||||
for (int i = 0; i < 8; i++) {
|
||||
*SPI_CMD_SH8(0xFF);
|
||||
}
|
||||
}
|
||||
}
|
17
old/spi.h
17
old/spi.h
|
@ -1,17 +0,0 @@
|
|||
#ifndef SPI_H
|
||||
#define SPI_H
|
||||
|
||||
void spi_select();
|
||||
void spi_deselect();
|
||||
|
||||
void spi_tx_slow(char d);
|
||||
char spi_rx_slow();
|
||||
void spi_skip_slow(int n);
|
||||
|
||||
void spi_tx_8(char d);
|
||||
char spi_rx_8();
|
||||
void spi_tx_16(int d);
|
||||
int spi_rx_16();
|
||||
void spi_skip(int n);
|
||||
|
||||
#endif
|
11
old/xfer.h
11
old/xfer.h
|
@ -1,11 +0,0 @@
|
|||
#ifndef RDISK_H
|
||||
#define RDISK_H
|
||||
|
||||
#pragma parameter xfer_s_256(__A0, __A1)
|
||||
void xfer_s_256(Ptr srcreg, Ptr destmem);
|
||||
|
||||
#pragma parameter xfer_s(__D0, __A0, __A1)
|
||||
void xfer_s(uint8_t numBytes, Ptr srcreg, Ptr destmem);
|
||||
|
||||
|
||||
#endif
|
34
old/xfer.s
34
old/xfer.s
|
@ -1,34 +0,0 @@
|
|||
.macro xfer_in from, to
|
||||
move.w (%A0), (%A1)+
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
.if \to-\from
|
||||
xfer_in "(\from+1)"
|
||||
.else
|
||||
|
||||
.endif
|
||||
.endm
|
||||
|
||||
|
||||
;pragma parameter xfer_s_256(__A0, __A1)
|
||||
;void xfer_s_256(Ptr srcreg, Ptr destmem);
|
||||
xfer_256:
|
||||
movem.l %D0/%A1-%A2, -(%SP)
|
||||
xfer_256_loop:
|
||||
xfer_s_in 0, 255
|
||||
xfer_256_end:
|
||||
movem.l (%SP)+, %D0/%A1-%A2
|
||||
|
||||
|
||||
;pragma parameter xfer_s(__D0, __A0, __A1)
|
||||
;void xfer_s(uint8_t numBytes, Ptr srcreg, Ptr destmem);
|
||||
xfer:
|
||||
movem.l %D0/%A1-%A2, -(%SP)
|
||||
andi.l #0xFF, %D0
|
||||
subi.l #256, %D0
|
||||
neg.l %D0
|
||||
lsl.l #2, %D0
|
||||
addi.l #xfer_256, %D0
|
||||
movea.l %D0, %A2
|
||||
jmp %A2
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef _PRIV_SYSCALL_H
|
||||
#define _PRIV_SYSCALL_H
|
||||
|
||||
#include <Disks.h>
|
||||
#include <OSUtils.h>
|
||||
|
||||
#pragma parameter __D0 PSReadXPRAM(__D0, __D1, __A0)
|
||||
OSErr PSReadXPRAM(short numBytes, short whichByte, Ptr dest) = {0x4840, 0x3001, 0xA051};
|
||||
|
||||
#pragma parameter __D0 PSAddDrive(__D1, __D0, __A0)
|
||||
OSErr PSAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) = {0x4840, 0x3001, 0xA04E};
|
||||
|
||||
// Figure out the first available drive number >= 5
|
||||
static int PSFindDrvNum() {
|
||||
DrvQElPtr dq;
|
||||
int drvNum = 5;
|
||||
for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
||||
if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; }
|
||||
}
|
||||
return drvNum;
|
||||
}
|
||||
|
||||
#endif
|
353
rdisk.c
353
rdisk.c
|
@ -1,353 +0,0 @@
|
|||
#include <Memory.h>
|
||||
#include <Devices.h>
|
||||
#include <Files.h>
|
||||
#include <Disks.h>
|
||||
#include <Errors.h>
|
||||
#include <Events.h>
|
||||
#include <OSUtils.h>
|
||||
|
||||
#include "rdisk.h"
|
||||
|
||||
// Decode keyboard/PRAM settings
|
||||
static void RDDecodeSettings(Ptr unmountEN, Ptr mountEN, Ptr ramEN, Ptr dbgEN, Ptr cdrEN) {
|
||||
// Sample R and A keys repeatedly
|
||||
char r = 0, a = 0;
|
||||
long tmax = TickCount() + 60;
|
||||
for (long i = 0; i < 1000000; i++) {
|
||||
a |= RDiskIsAPressed();
|
||||
r |= RDiskIsRPressed() | a;
|
||||
if (r) { break; }
|
||||
if (TickCount() > tmax) { break; }
|
||||
}
|
||||
|
||||
// Read PRAM
|
||||
char legacy_startup, legacy_ram;
|
||||
RDiskReadXPRAM(1, 4, &legacy_startup);
|
||||
RDiskReadXPRAM(1, 5, &legacy_ram);
|
||||
|
||||
// Decode settings: unmount (don't boot), mount (after boot), RAM disk
|
||||
if (r) { // R boots from ROM disk
|
||||
*unmountEN = 0; // Don't unmount so we boot from this drive
|
||||
*mountEN = 0; // No need to mount later since we are boot disk
|
||||
*ramEN = a; // A enables RAM disk
|
||||
*dbgEN = 0;
|
||||
*cdrEN = 0;
|
||||
} else {
|
||||
if (legacy_startup & 0x01) { // Boot from ROM disk
|
||||
*unmountEN = 0; // Don't unmount so we boot from this drive
|
||||
*mountEN = 0; // No need to mount later since we are boot disk
|
||||
*ramEN = legacy_ram & 0x01; // Allocate RAM disk if bit 0 == 1
|
||||
*dbgEN = legacy_startup & 0x04; // MacsBug enabled if bit 2 == 1
|
||||
*cdrEN = legacy_startup & 0x08; // CD-ROM enabled if bit 3 == 1
|
||||
} else if (!(legacy_startup & 0x02)) { // Mount ROM disk
|
||||
*unmountEN = 1; // Unmount to not boot from our disk
|
||||
*mountEN = 1; // Mount in accRun
|
||||
*ramEN = legacy_ram & 0x01; // Allocate RAM disk if bit 0 == 1
|
||||
*dbgEN = 1; // CD-ROM ext. always enabled in mount mode
|
||||
*cdrEN = 1; // MacsBug always enabled in mount mode
|
||||
} else {
|
||||
*unmountEN = 1; // Unmount
|
||||
*mountEN = 0; // Don't mount again
|
||||
*ramEN = 0; // Don't allocate RAM disk
|
||||
*dbgEN = 1; // CD-ROM ext. always enabled in unmount mode
|
||||
*cdrEN = 1; // MacsBug always enabled in unmount mode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and copy
|
||||
#pragma parameter C24(__A0, __A1, __D0)
|
||||
void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) {
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
BlockMove(sourcePtr, destPtr, byteCount);
|
||||
SwapMMUMode(&mode);
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and get
|
||||
#pragma parameter __D0 G24(__A2)
|
||||
char __attribute__ ((noinline)) G24(Ptr pos) {
|
||||
long ret;
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
ret = *pos; // Peek
|
||||
SwapMMUMode(&mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and set
|
||||
#pragma parameter S24(__A2, __D3)
|
||||
void __attribute__ ((noinline)) S24(Ptr pos, char patch) {
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
*pos = patch; // Poke
|
||||
SwapMMUMode(&mode);
|
||||
}
|
||||
|
||||
// Figure out the first available drive number >= 5
|
||||
static int RDFindDrvNum() {
|
||||
DrvQElPtr dq;
|
||||
int drvNum = 5;
|
||||
for (dq = (DrvQElPtr)(GetDrvQHdr())->qHead; dq; dq = (DrvQElPtr)dq->qLink) {
|
||||
if (dq->dQDrive >= drvNum) { drvNum = dq->dQDrive + 1; }
|
||||
}
|
||||
return drvNum;
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RDOpen(__A0, __A1)
|
||||
OSErr RDOpen(IOParamPtr p, DCtlPtr d) {
|
||||
int drvNum;
|
||||
RDiskStorage_t *c;
|
||||
char legacy_startup;
|
||||
|
||||
// Do nothing if already opened
|
||||
if (d->dCtlStorage) { return noErr; }
|
||||
|
||||
// Do nothing if inhibited
|
||||
RDiskReadXPRAM(1, 4, &legacy_startup);
|
||||
if (legacy_startup & 0x80) { return noErr; }
|
||||
|
||||
// Allocate storage struct
|
||||
d->dCtlStorage = NewHandleSysClear(sizeof(RDiskStorage_t));
|
||||
if (!d->dCtlStorage) { return openErr; }
|
||||
|
||||
// Lock our storage struct and get master pointer
|
||||
HLock(d->dCtlStorage);
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
|
||||
// Find first available drive number
|
||||
drvNum = RDFindDrvNum();
|
||||
|
||||
// Get debug and CD-ROM disable settings from ROM table
|
||||
c->dbgDisByte = RDiskDBGDisByte;
|
||||
c->cdrDisByte = RDiskCDRDisByte;
|
||||
|
||||
// Set drive status
|
||||
//c->status.track = 0;
|
||||
c->status.writeProt = -1; // nonzero is write protected
|
||||
c->status.diskInPlace = 8; // 8 is nonejectable disk
|
||||
c->status.installed = 1; // drive installed
|
||||
//c->status.sides = 0;
|
||||
//c->status.qType = 1;
|
||||
c->status.dQDrive = drvNum;
|
||||
//c->status.dQFSID = 0;
|
||||
c->status.dQRefNum = d->dCtlRefNum;
|
||||
c->status.driveSize = RDiskSize / 512;
|
||||
//c->status.driveS1 = (RDiskSize / 512) >> 16;
|
||||
|
||||
// Decompress icon
|
||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
||||
char *src = &RDiskIconCompressed[0];
|
||||
char *dst = &c->icon[0];
|
||||
UnpackBits(&src, &dst, RDISK_ICON_SIZE);
|
||||
#endif
|
||||
|
||||
// Add drive to drive queue and return
|
||||
RDiskAddDrive(c->status.dQRefNum, drvNum, (DrvQElPtr)&c->status.qLink);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// Init is called at beginning of first prime (read/write) call
|
||||
static void RDInit(IOParamPtr p, DCtlPtr d, RDiskStorage_t *c) {
|
||||
char unmountEN, mountEN, ramEN, dbgEN, cdrEN;
|
||||
// Mark init done
|
||||
c->initialized = 1;
|
||||
// Decode settings
|
||||
RDDecodeSettings(&unmountEN, &mountEN, &ramEN, &dbgEN, &cdrEN);
|
||||
|
||||
// If RAM disk enabled, try to allocate RAM disk buffer if not already
|
||||
if (ramEN & !c->ramdisk) {
|
||||
if (*MMU32bit) { // 32-bit mode
|
||||
unsigned long minBufPtr, newBufPtr;
|
||||
// Compute if there is enough high memory
|
||||
minBufPtr = ((unsigned long)*MemTop / 2) + 1024;
|
||||
newBufPtr = (unsigned long)*BufPtr - RDiskSize;
|
||||
if (newBufPtr > minBufPtr && (unsigned long)*BufPtr > newBufPtr) {
|
||||
// Allocate RAM disk buffer by lowering BufPtr
|
||||
*BufPtr = (Ptr)newBufPtr;
|
||||
// Set RAM disk buffer pointer.
|
||||
c->ramdisk = *BufPtr;
|
||||
// Copy ROM disk image to RAM disk
|
||||
BlockMove(RDiskBuf, c->ramdisk, RDiskSize);
|
||||
// Clearing write protect marks RAM disk enabled
|
||||
c->status.writeProt = 0;
|
||||
}
|
||||
} else { // 24-bit mode
|
||||
// Put RAM disk just past 8MB
|
||||
c->ramdisk = (Ptr)(8 * 1024 * 1024);
|
||||
// Copy ROM disk image to RAM disk
|
||||
//FIXME: what if we don't have enough RAM?
|
||||
// Will this wrap around and overwrite low memory?
|
||||
// That's not the worst, since the system would just crash,
|
||||
// but it would be better to switch to read-only status
|
||||
copy24(RDiskBuf, c->ramdisk, RDiskSize);
|
||||
// Clearing write protect marks RAM disk enabled
|
||||
c->status.writeProt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Patch
|
||||
if (RDiskDBGDisPos < RDiskSize) {
|
||||
if (c->ramdisk && !dbgEN) {
|
||||
poke24(c->ramdisk + RDiskDBGDisPos, c->dbgDisByte);
|
||||
} else if (dbgEN) {
|
||||
peek24(RDiskBuf + RDiskDBGDisPos, c->dbgDisByte);
|
||||
}
|
||||
}
|
||||
if (RDiskCDRDisPos < RDiskSize) {
|
||||
if (c->ramdisk && !cdrEN) {
|
||||
poke24(c->ramdisk + RDiskCDRDisPos, c->cdrDisByte);
|
||||
} else if (cdrEN) {
|
||||
peek24(RDiskBuf + RDiskCDRDisPos, c->cdrDisByte);
|
||||
}
|
||||
}
|
||||
|
||||
// Unmount if not booting from ROM disk
|
||||
if (unmountEN) { c->status.diskInPlace = 0; }
|
||||
|
||||
// If mount enabled, enable accRun to post disk inserted event later
|
||||
if (mountEN) {
|
||||
d->dCtlDelay = 150; // Set accRun delay (150 ticks is 2.5 sec.)
|
||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
||||
}
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RDPrime(__A0, __A1)
|
||||
OSErr RDPrime(IOParamPtr p, DCtlPtr d) {
|
||||
RDiskStorage_t *c;
|
||||
char cmd;
|
||||
Ptr disk;
|
||||
|
||||
// Return disk offline error if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
|
||||
// Initialize if this is the first prime call
|
||||
if (!c->initialized) { RDInit(p, d, c); }
|
||||
|
||||
// Return disk offline error if virtual disk not inserted
|
||||
if (!c->status.diskInPlace) { return offLinErr; }
|
||||
|
||||
// Get pointer to RAM or ROM disk buffer
|
||||
disk = (c->ramdisk ? c->ramdisk : RDiskBuf) + d->dCtlPosition;
|
||||
// Bounds checking
|
||||
if (d->dCtlPosition >= RDiskSize || p->ioReqCount >= RDiskSize ||
|
||||
d->dCtlPosition + p->ioReqCount >= RDiskSize) { return paramErr; }
|
||||
|
||||
// Service read or write request
|
||||
cmd = p->ioTrap & 0x00FF;
|
||||
if (cmd == aRdCmd) { // Read
|
||||
// Read from disk into buffer.
|
||||
if (*MMU32bit) { BlockMove(disk, p->ioBuffer, p->ioReqCount); }
|
||||
else { copy24(disk, StripAddress(p->ioBuffer), p->ioReqCount); }
|
||||
if (!c->ramdisk && RDiskDBGDisPos >= d->dCtlPosition &&
|
||||
RDiskDBGDisPos < d->dCtlPosition + p->ioReqCount) {
|
||||
p->ioBuffer[RDiskDBGDisPos - d->dCtlPosition] = c->dbgDisByte;
|
||||
}
|
||||
if (!c->ramdisk && RDiskCDRDisPos >= d->dCtlPosition &&
|
||||
RDiskCDRDisPos < d->dCtlPosition + p->ioReqCount) {
|
||||
p->ioBuffer[RDiskCDRDisPos - d->dCtlPosition] = c->cdrDisByte;
|
||||
}
|
||||
} else if (cmd == aWrCmd) { // Write
|
||||
// Fail if write protected or RAM disk buffer not set up
|
||||
if (c->status.writeProt || !c->ramdisk) { return wPrErr; }
|
||||
// Write from buffer into disk.
|
||||
if (*MMU32bit) { BlockMove(p->ioBuffer, disk, p->ioReqCount); }
|
||||
else { copy24(StripAddress(p->ioBuffer), disk, p->ioReqCount); }
|
||||
} else { return noErr; } //FIXME: Fail if cmd isn't read or write?
|
||||
|
||||
// Update count and position/offset, then return
|
||||
d->dCtlPosition += p->ioReqCount;
|
||||
p->ioActCount = p->ioReqCount;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RDCtl(__A0, __A1)
|
||||
OSErr RDCtl(CntrlParamPtr p, DCtlPtr d) {
|
||||
RDiskStorage_t *c;
|
||||
// Fail if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
// Handle control request based on csCode
|
||||
switch (p->csCode) {
|
||||
case killCode:
|
||||
return noErr;
|
||||
case kFormat:
|
||||
if (!c->status.diskInPlace || c->status.writeProt ||
|
||||
!c->ramdisk) { return controlErr; }
|
||||
long long z = 0;
|
||||
Ptr pz;
|
||||
if (*MMU32bit) { pz = (Ptr)&z; }
|
||||
else { pz = StripAddress((Ptr)&z); }
|
||||
for (int i = 0; i < 4095; i++) {
|
||||
copy24(c->ramdisk + i * sizeof(z), pz, sizeof(z));
|
||||
}
|
||||
return noErr;
|
||||
case kVerify:
|
||||
if (!c->status.diskInPlace) { return controlErr; }
|
||||
return noErr;
|
||||
case kEject:
|
||||
// "Reinsert" disk if ejected illegally
|
||||
if (c->status.diskInPlace) {
|
||||
PostEvent(diskEvt, c->status.dQDrive);
|
||||
}
|
||||
return controlErr; // Eject not allowed so return error
|
||||
case accRun:
|
||||
d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun
|
||||
c->status.diskInPlace = 8; // 8 is nonejectable disk
|
||||
PostEvent(diskEvt, c->status.dQDrive); // Post disk inserted event
|
||||
return noErr;
|
||||
case kDriveIcon: case kMediaIcon: // Get icon
|
||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
||||
*(Ptr*)p->csParam = (Ptr)c->icon;
|
||||
#else
|
||||
*(Ptr*)p->csParam = (Ptr)RDiskIcon;
|
||||
#endif
|
||||
return noErr;
|
||||
case kDriveInfo:
|
||||
// high word (bytes 2 & 3) clear
|
||||
// byte 1 = primary + fixed media + internal
|
||||
// byte 0 = drive type (0x10 is RAM disk) / (0x11 is ROM disk)
|
||||
if (c->status.writeProt) { *(long*)p->csParam = 0x00000411; }
|
||||
else { *(long*)p->csParam = 0x00000410; }
|
||||
return noErr;
|
||||
case 24: // Return SCSI partition size
|
||||
*(long*)p->csParam = RDiskSize / 512;
|
||||
return noErr;
|
||||
case 2351: // Post-boot
|
||||
c->initialized = 1; // Skip initialization
|
||||
d->dCtlDelay = 30; // Set accRun delay (30 ticks is 0.5 sec.)
|
||||
d->dCtlFlags |= dNeedTimeMask; // Enable accRun
|
||||
return noErr;
|
||||
default: return controlErr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RDStat(__A0, __A1)
|
||||
OSErr RDStat(CntrlParamPtr p, DCtlPtr d) {
|
||||
//RDiskStorage_t *c;
|
||||
// Fail if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
//c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
// Handle status request based on csCode
|
||||
switch (p->csCode) {
|
||||
case kDriveStatus:
|
||||
BlockMove(*d->dCtlStorage, &p->csParam, sizeof(DrvSts2));
|
||||
return noErr;
|
||||
default: return statusErr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RDClose(__A0, __A1)
|
||||
OSErr RDClose(IOParamPtr p, DCtlPtr d) {
|
||||
// If dCtlStorage not null, dispose of it
|
||||
if (!d->dCtlStorage) { return noErr; }
|
||||
//RDiskStorage_t *c = *(RDiskStorage_t**)d->dCtlStorage;
|
||||
HUnlock(d->dCtlStorage);
|
||||
DisposeHandle(d->dCtlStorage);
|
||||
d->dCtlStorage = NULL;
|
||||
return noErr;
|
||||
}
|
|
@ -0,0 +1,252 @@
|
|||
#include <Memory.h>
|
||||
#include <Devices.h>
|
||||
#include <Files.h>
|
||||
#include <Disks.h>
|
||||
#include <Errors.h>
|
||||
#include <Events.h>
|
||||
#include <OSUtils.h>
|
||||
|
||||
#include "rombus.h"
|
||||
#include "spi.h"
|
||||
#include "priv_syscall.h"
|
||||
|
||||
// Decode keyboard settings
|
||||
static void RBDecodeKeySettings(RBStorage_t *c) {
|
||||
// Sample R, S, X keys repeatedly
|
||||
char r = 0, s = 0, x = 0;
|
||||
long tmax = TickCount() + 60;
|
||||
for (long i = 0; i < 1000000; i++) {
|
||||
r |= IsRPressed();
|
||||
s |= IsSPressed();
|
||||
x |= IsXPressed();
|
||||
if (r || s || x) { break; }
|
||||
if (TickCount() > tmax) { break; }
|
||||
}
|
||||
// Decode settings
|
||||
if (x) { // Unmount everything
|
||||
c->unmountROMEN = 1;
|
||||
c->unmountSDEN = 1;
|
||||
c->mountROMEN = 0;
|
||||
c->mountSDEN = 0;
|
||||
} else if (s) { // Boot from SD, don't mount ROM
|
||||
c->unmountROMEN = 1;
|
||||
c->unmountSDEN = 0;
|
||||
c->mountROMEN = 1;
|
||||
c->mountSDEN = 0;
|
||||
} else if (r) { // Boot from ROM, mount SD
|
||||
c->unmountROMEN = 0;
|
||||
c->unmountSDEN = 1;
|
||||
c->mountROMEN = 0;
|
||||
c->mountSDEN = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Decode PRAM settings
|
||||
static OSErr RBDecodePRAMSettings(RBStorage_t *c) {
|
||||
// Read PRAM
|
||||
char legacy_startup, legacy_ram;
|
||||
PSReadXPRAM(1, 4, &legacy_startup);
|
||||
PSReadXPRAM(1, 5, &legacy_ram);
|
||||
|
||||
// Decoded settings
|
||||
const char opt_disable = legacy_startup & (1<<7);
|
||||
const char opt_boot_sd = legacy_startup & (1<<2);
|
||||
const char opt_boot_rom = legacy_startup & (1<<0);
|
||||
const char opt_mount_sd = legacy_startup & (1<<3);
|
||||
const char opt_mount_rom = legacy_startup & (1<<4);
|
||||
|
||||
// Old settings for ROM SIMM (not used here)
|
||||
//const char opt_old_mount_rom = !(legacy_startup & (1<<1));
|
||||
//const char opt_old_ram = legacy_ram & (1<<0);
|
||||
|
||||
// Set based on decoded settings
|
||||
if (opt_disable) { return -1; }
|
||||
else {
|
||||
c->unmountROMEN = !opt_boot_rom;
|
||||
c->unmountSDEN = !opt_boot_sd;
|
||||
c->mountROMEN = opt_mount_rom && !opt_boot_rom;
|
||||
c->mountSDEN = opt_mount_sd && !opt_boot_sd;
|
||||
}
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// Switch to 32-bit mode and copy
|
||||
#pragma parameter C24(__A0, __A1, __D0)
|
||||
void __attribute__ ((noinline)) C24(Ptr sourcePtr, Ptr destPtr, unsigned long byteCount) {
|
||||
signed char mode = true32b;
|
||||
SwapMMUMode(&mode);
|
||||
BlockMove(sourcePtr, destPtr, byteCount);
|
||||
SwapMMUMode(&mode);
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBClose(__A0, __A1)
|
||||
OSErr RBClose(IOParamPtr p, DCtlPtr d) {
|
||||
// If dCtlStorage not null, dispose of it
|
||||
if (!d->dCtlStorage) { return noErr; }
|
||||
HUnlock(d->dCtlStorage);
|
||||
DisposeHandle(d->dCtlStorage);
|
||||
d->dCtlStorage = NULL;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBOpen(__A0, __A1)
|
||||
OSErr RBOpen(IOParamPtr p, DCtlPtr d) {
|
||||
int drvNum;
|
||||
RBStorage_t *c;
|
||||
|
||||
// Do nothing if already opened
|
||||
if (d->dCtlStorage) { return noErr; }
|
||||
|
||||
// Allocate storage struct
|
||||
d->dCtlStorage = NewHandleSysClear(sizeof(RBStorage_t));
|
||||
if (!d->dCtlStorage) { return openErr; }
|
||||
|
||||
// Lock our storage struct and get master pointer
|
||||
HLock(d->dCtlStorage);
|
||||
c = *(RBStorage_t**)d->dCtlStorage;
|
||||
|
||||
// Do nothing if inhibited
|
||||
if (RBDecodePRAMSettings(c) != noErr) {
|
||||
RBClose(p, d);
|
||||
return openErr;
|
||||
}
|
||||
|
||||
// Iff mount enabled, enable accRun to post disk inserted event later
|
||||
if (c->mountROMEN || c->mountSDEN) { d->dCtlFlags |= dNeedTimeMask; }
|
||||
else { d->dCtlFlags &= ~dNeedTimeMask; }
|
||||
|
||||
// Set accRun delay
|
||||
d->dCtlDelay = 150; // (150 ticks is 2.5 sec.)
|
||||
|
||||
// Find first available drive number
|
||||
drvNum = PSFindDrvNum();
|
||||
|
||||
//TODO: set c->sdSize
|
||||
|
||||
// Set drive status
|
||||
c->sdStatus.track = 0;
|
||||
c->sdStatus.writeProt = 0; // nonzero is write protected
|
||||
c->sdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||
c->sdStatus.installed = 1; // drive installed
|
||||
c->sdStatus.sides = 0;
|
||||
c->sdStatus.qType = 1;
|
||||
c->sdStatus.dQDrive = drvNum;
|
||||
c->sdStatus.dQFSID = 0;
|
||||
c->sdStatus.dQRefNum = d->dCtlRefNum;
|
||||
c->sdStatus.driveSize = c->sdSize / 512;
|
||||
c->sdStatus.driveS1 = (c->sdSize / 512) >> 16;
|
||||
|
||||
// Decompress icon
|
||||
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||
char *src = &SDIconCompressed[0];
|
||||
char *dst = &c->sd[0];
|
||||
UnpackBits(&src, &dst, RB_ICON_SIZE);
|
||||
#endif
|
||||
|
||||
// Add drive to drive queue and return
|
||||
PSAddDrive(c->sdStatus.dQRefNum, drvNum, (DrvQElPtr)&c->sdStatus.qLink);
|
||||
return noErr;
|
||||
}
|
||||
|
||||
// Init is called at beginning of first prime (read/write) call
|
||||
static void RBBootInit(IOParamPtr p, DCtlPtr d, RBStorage_t *c) {
|
||||
// Mark init done
|
||||
c->initialized = 1;
|
||||
|
||||
// Decode key settings
|
||||
RBDecodeKeySettings(c);
|
||||
|
||||
// Unmount if not booting from ROM disk
|
||||
if (c->unmountSDEN) { c->sdStatus.diskInPlace = 0; }
|
||||
|
||||
// Iff mount disabled, disable accRun
|
||||
if (!c->mountSDEN || !c->mountROMEN) { d->dCtlFlags &= ~dNeedTimeMask; }
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBPrime(__A0, __A1)
|
||||
OSErr RBPrime(IOParamPtr p, DCtlPtr d) {
|
||||
RBStorage_t *c;
|
||||
|
||||
// Return disk offline error if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RBStorage_t**)d->dCtlStorage;
|
||||
|
||||
// Initialize if this is the first prime call
|
||||
if (!c->initialized) { RBBootInit(p, d, c); }
|
||||
|
||||
// Return disk offline error if virtual disk not inserted
|
||||
if (!c->sdStatus.diskInPlace) { return offLinErr; }
|
||||
|
||||
//TODO: Read/write
|
||||
|
||||
// Update count and position/offset, then return
|
||||
d->dCtlPosition += p->ioReqCount;
|
||||
p->ioActCount = p->ioReqCount;
|
||||
return noErr;
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBCtl(__A0, __A1)
|
||||
OSErr RBCtl(CntrlParamPtr p, DCtlPtr d) {
|
||||
RBStorage_t *c;
|
||||
// Fail if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Dereference dCtlStorage to get pointer to our context
|
||||
c = *(RBStorage_t**)d->dCtlStorage;
|
||||
// Handle control request based on csCode
|
||||
switch (p->csCode) {
|
||||
case kFormat:
|
||||
if (!c->sdStatus.diskInPlace || c->sdStatus.writeProt) {
|
||||
return controlErr;
|
||||
}
|
||||
//TODO: Format
|
||||
return noErr;
|
||||
case kVerify:
|
||||
if (!c->sdStatus.diskInPlace) { return controlErr; }
|
||||
return noErr;
|
||||
case accRun:
|
||||
c->initialized = 1; // Mark init done
|
||||
c->sdStatus.diskInPlace = 8; // 8 is nonejectable disk
|
||||
PostEvent(diskEvt, c->sdStatus.dQDrive); // Post disk inserted event
|
||||
d->dCtlFlags &= ~dNeedTimeMask; // Disable accRun
|
||||
return noErr;
|
||||
case kDriveIcon: case kMediaIcon: // Get icon
|
||||
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||
*(Ptr*)p->csParam = (Ptr)c->sd;
|
||||
#else
|
||||
*(Ptr*)p->csParam = (Ptr)RDiskIcon;
|
||||
#endif
|
||||
return noErr;
|
||||
case kDriveInfo:
|
||||
// high word (bytes 2 & 3) clear
|
||||
// byte 1 = primary + fixed media + internal
|
||||
// byte 0 = drive type (0x10 is RAM disk) / (0x11 is ROM disk)
|
||||
if (c->sdStatus.writeProt) { *(long*)p->csParam = 0x00000400; }
|
||||
else { *(long*)p->csParam = 0x00000400; }
|
||||
return noErr;
|
||||
case 24: // Return SCSI partition size
|
||||
*(long*)p->csParam = c->sdSize / 512;
|
||||
return noErr;
|
||||
case killCode: return noErr;
|
||||
case kEject:
|
||||
// "Reinsert" disk if ejected illegally
|
||||
if (c->sdStatus.diskInPlace) {
|
||||
PostEvent(diskEvt, c->sdStatus.dQDrive);
|
||||
}
|
||||
return controlErr; // Eject not allowed so return error
|
||||
default: return controlErr;
|
||||
}
|
||||
}
|
||||
|
||||
#pragma parameter __D0 RBStat(__A0, __A1)
|
||||
OSErr RBStat(CntrlParamPtr p, DCtlPtr d) {
|
||||
// Fail if dCtlStorage null
|
||||
if (!d->dCtlStorage) { return notOpenErr; }
|
||||
// Handle status request based on csCode
|
||||
switch (p->csCode) {
|
||||
case kDriveStatus:
|
||||
BlockMove(*d->dCtlStorage, &p->csParam, sizeof(DrvSts2));
|
||||
return noErr;
|
||||
default: return statusErr;
|
||||
}
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
#ifndef RDISK_H
|
||||
#define RDISK_H
|
||||
#ifndef _RDISK_H
|
||||
#define _RDISK_H
|
||||
|
||||
#define RDiskBuf ((char*)0x40880000)
|
||||
#define BufPtr ((Ptr*)0x10C)
|
||||
#define MemTop ((Ptr*)0x108)
|
||||
#define MMU32bit ((char*)0xCB2)
|
||||
|
||||
#define RDiskDBGDisPos (*(const unsigned long*)0x40851D98)
|
||||
|
@ -12,42 +10,39 @@
|
|||
#define RDiskCDRDisByte (*(const char*)0x40851DA9)
|
||||
#define RDiskSize (*(const unsigned long*)0x40851DAC)
|
||||
|
||||
#define RDISK_COMPRESS_ICON_ENABLE
|
||||
#define RB_COMPRESS_ICON_ENABLE
|
||||
|
||||
#pragma parameter __D0 RDiskReadXPRAM(__D0, __D1, __A0)
|
||||
OSErr RDiskReadXPRAM(short numBytes, short whichByte, Ptr dest) = {0x4840, 0x3001, 0xA051};
|
||||
static inline char IsRPressed() { return *((volatile char*)0x175) & 0x80; }
|
||||
static inline char IsSPressed() { return *((volatile char*)0x174) & 0x02; }
|
||||
static inline char IsXPressed() { return *((volatile char*)0x174) & 0x80; }
|
||||
|
||||
#pragma parameter __D0 RDiskAddDrive(__D1, __D0, __A0)
|
||||
OSErr RDiskAddDrive(short drvrRefNum, short drvNum, DrvQElPtr dq) = {0x4840, 0x3001, 0xA04E};
|
||||
|
||||
static inline char RDiskIsRPressed() { return *((volatile char*)0x175) & 0x80; }
|
||||
static inline char RDiskIsAPressed() { return *((volatile char*)0x174) & 0x01; }
|
||||
|
||||
#define RDISK_ICON_SIZE (285)
|
||||
#define RB_ICON_SIZE (285)
|
||||
typedef struct RDiskStorage_s {
|
||||
DrvSts2 status;
|
||||
DrvSts2 sdStatus;
|
||||
long long sdSize;
|
||||
|
||||
char initialized;
|
||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
||||
char icon[RDISK_ICON_SIZE+8];
|
||||
|
||||
char unmountSDEN;
|
||||
char mountSDEN;
|
||||
char unmountROMEN;
|
||||
char mountROMEN;
|
||||
|
||||
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||
char sd[RB_ICON_SIZE+8];
|
||||
#endif
|
||||
} RDiskStorage_t;
|
||||
} RBStorage_t;
|
||||
|
||||
typedef void (*RDiskCopy_t)(Ptr, Ptr, unsigned long);
|
||||
#define copy24(s, d, b) { RDiskCopy_t f = C24; f(s, d, b); }
|
||||
|
||||
typedef char (*RDiskPeek_t)(Ptr);
|
||||
#define peek24(a, d) { RDiskPeek_t f = G24; d = f(a); }
|
||||
|
||||
typedef void (*RDiskPoke_t)(Ptr, char);
|
||||
#define poke24(a, d) { RDiskPoke_t f = S24; f(a, d); }
|
||||
|
||||
#define PackBits_Repeat(count) (-1 * (count - 1))
|
||||
#define PackBits_Literal(count) (count - 1)
|
||||
|
||||
#define RDISK_COMPRESSED_ICON_SIZE (87)
|
||||
#ifdef RDISK_COMPRESS_ICON_ENABLE
|
||||
#ifdef RB_COMPRESS_ICON_ENABLE
|
||||
#include <Quickdraw.h>
|
||||
const char RDiskIconCompressed[RDISK_COMPRESSED_ICON_SIZE] = {
|
||||
const char SDIconCompressed[RDISK_COMPRESSED_ICON_SIZE] = {
|
||||
PackBits_Repeat(76), 0b00000000, /*
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
|
@ -130,7 +125,7 @@ const char RDiskIconCompressed[RDISK_COMPRESSED_ICON_SIZE] = {
|
|||
'R', 'O', 'M', ' ', 'D', 'i', 's', 'k', 0
|
||||
};
|
||||
#else
|
||||
const char RDiskIcon[RDISK_ICON_SIZE] = {
|
||||
const char RDiskIcon[RB_ICON_SIZE] = {
|
||||
// Icon
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
||||
0b00000000, 0b00000000, 0b00000000, 0b00000000,
|
BIN
roms/baserom.bin
BIN
roms/baserom.bin
Binary file not shown.
|
@ -0,0 +1,129 @@
|
|||
#include "spi.h"
|
||||
#include "spi_hal.h"
|
||||
|
||||
static int _search_lt(char *buf, int stride, int threshold) {
|
||||
for (int i = 1; i < 256; i++) {
|
||||
if (buf[i * stride] < threshold) { return 1; }
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _spi_hal_rx8_nops, _spi_hal_tx8_nops;
|
||||
int _spi_hal_rx16_nops, _spi_hal_tx16_nops;
|
||||
int _spi_hal_rxtx8_nops;
|
||||
|
||||
short *_spi_reg_rx16;
|
||||
char *_spi_reg_tx16;
|
||||
short *_spi_reg_rd16;
|
||||
|
||||
int spi_init(int swap) {
|
||||
short buf16[256];
|
||||
char *buf8 = (char*)&buf16;
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
spi_hal_rx8(SPI_REG_TIMER8, buf8, 256, i);
|
||||
_spi_hal_rx8_nops = i;
|
||||
_spi_hal_tx8_nops = i > 0 ? i - 1 : 0;
|
||||
if (!_search_lt(buf8, 1, 8)) { break; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
spi_hal_rx16(SPI_REG_TIMER16, buf16, 256, i);
|
||||
_spi_hal_rx16_nops = i;
|
||||
_spi_hal_tx16_nops = i > 0 ? i - 1 : 0;
|
||||
if (!_search_lt(buf8, 2, 8)) { break; }
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
spi_hal_rxtx8(SPI_REG_EMPTY, SPI_REG_TIMER16, buf8, buf8, 256, i);
|
||||
_spi_hal_rxtx8_nops = i;
|
||||
if (!_search_lt(buf8, 1, 8)) { break; }
|
||||
}
|
||||
|
||||
_spi_reg_rx16 = swap ? SPI_REG_RX16S : SPI_REG_RX16;
|
||||
_spi_reg_tx16 = swap ? SPI_REG_TX16S : SPI_REG_TX16;
|
||||
_spi_reg_rd16 = swap ? SPI_REG_RD16S : SPI_REG_RD16;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi_cs(int cs) {
|
||||
if (cs) { SPI_REG_CSR_SET_CS(); }
|
||||
else { SPI_REG_CSR_CLR_CS(); }
|
||||
}
|
||||
|
||||
char spi_txrx8_slow(char txd) {
|
||||
char rxd = 0;
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
spi_delay(64);
|
||||
SPI_REG_CSR_CLR_SCK();
|
||||
spi_delay(64);
|
||||
SPI_REG_SET_MOSI((txd >> i) & 1);
|
||||
rxd = (rxd << 1) | SPI_REG_CSR_GET_MISO();
|
||||
SPI_REG_CSR_SET_SCK();
|
||||
}
|
||||
spi_delay(64);
|
||||
SPI_REG_CSR_CLR_SCK();
|
||||
return rxd;
|
||||
}
|
||||
|
||||
char spi_txrx8(char txd) {
|
||||
spi_hal_tx8(SPI_REG_TX8, &txd, 1, _spi_hal_tx8_nops);
|
||||
return *SPI_REG_RD8;
|
||||
}
|
||||
|
||||
char spi_rxtx8(char txd) {
|
||||
char rxd = *SPI_REG_RD8;
|
||||
spi_hal_tx8(SPI_REG_TX8, &txd, 1, _spi_hal_tx8_nops);
|
||||
return rxd;
|
||||
}
|
||||
|
||||
#define UNROLL_LENGTH 5
|
||||
|
||||
void spi_rx(char txd, char *rxb, unsigned int length) {
|
||||
if (length == 0) { return; } // Return if length 0
|
||||
|
||||
// Word-align rx pointer by transferring 0/1 bytes
|
||||
if ((int)rxb & 1) {
|
||||
*(rxb++) = spi_rxtx8(txd);
|
||||
length--;
|
||||
}
|
||||
|
||||
// Set tx pattern
|
||||
reg_write16(SPI_REG_ST16, smear8to32(txd));
|
||||
|
||||
// Transfer all but 0-65 bytes
|
||||
for (int i = length >> (UNROLL_LENGTH +1); i > 0; i--) {
|
||||
// Transfer 2^UNROLL_LENGTH words (2 * 2^UNROLL_LENGTH bytes)
|
||||
spi_hal_rx16(_spi_reg_rx16, rxb, UNROLL_LENGTH, _spi_hal_rx16_nops);
|
||||
}
|
||||
|
||||
// Transfer remaining 1-32 words (2-64 bytes)
|
||||
spi_hal_rx16(_spi_reg_rx16, rxb, length >> 1, _spi_hal_rx16_nops);
|
||||
|
||||
// Transfer remaining byte if any
|
||||
if (length & 1) { *(rxb++) = spi_rxtx8(txd); }
|
||||
}
|
||||
|
||||
void spi_tx(char *txb, unsigned int length) {
|
||||
if (length == 0) { return; } // Return if length 0
|
||||
|
||||
// Word-align tx pointer by transferring 0/1 bytes
|
||||
if ((int)txb & 1) {
|
||||
spi_rxtx8(*(txb++));
|
||||
length--;
|
||||
}
|
||||
|
||||
// Transfer all but 0-65 bytes
|
||||
for (; length > UNROLL_LENGTH; length -= UNROLL_LENGTH) {
|
||||
spi_hal_tx16(_spi_reg_tx16, txb, UNROLL_LENGTH, _spi_hal_tx16_nops);
|
||||
}
|
||||
|
||||
// Transfer remaining 1-32 words (2-64 bytes)
|
||||
spi_hal_tx16(_spi_reg_tx16, txb, length >> 1, _spi_hal_tx16_nops);
|
||||
|
||||
// Transfer remaining byte if any
|
||||
if (length & 1) { spi_rxtx8(*(txb++)); }
|
||||
}
|
||||
|
||||
char spi_rd8() { return *SPI_REG_RD8; }
|
||||
short spi_rd16() { return *_spi_reg_rd16; }
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef _SPI_H
|
||||
#define _SPI_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
int spi_init();
|
||||
|
||||
void spi_cs(int cs);
|
||||
|
||||
char spi_txrx8_slow(char txd);
|
||||
char spi_txrx8(char txd);
|
||||
char spi_rxtx8(char txd);
|
||||
|
||||
void spi_tx(char *txb, unsigned int length);
|
||||
void spi_rx(char txd, char *rxb, unsigned int length);
|
||||
|
||||
char spi_rd8();
|
||||
short spi_rd16();
|
||||
|
||||
#endif
|
|
@ -0,0 +1,79 @@
|
|||
#ifndef _SPI_HAL_H
|
||||
#define _SPI_HAL_H
|
||||
|
||||
#pragma parameter spi_delay(__D0)
|
||||
extern void spi_delay(char iterations);
|
||||
|
||||
#pragma parameter _reg_write8(__A0, __D0, __D1)
|
||||
extern void _reg_write8(void *addr, char data, int tmp);
|
||||
static inline void reg_write8(void *addr, char data) { _reg_write8(addr, data, 0); }
|
||||
|
||||
#pragma parameter _reg_write16(__A0, __D0, __D1)
|
||||
extern void _reg_write16(void *addr, short data, int tmp);
|
||||
static inline void reg_write16(void *addr, short data) { _reg_write16(addr, data, 0); }
|
||||
|
||||
#pragma parameter __D0 smear8to32(__D0)
|
||||
extern long smear8to32(char data);
|
||||
|
||||
// Read transfer registers
|
||||
#define SPI_REG_RX8 ((char*) 0x00000000) // A[01:00]==2'b00, D[31:24]==ret
|
||||
#define SPI_REG_RX16 ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||
#define SPI_REG_RX16S ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||
#define SPI_REG_RD8 ((char*) 0x00000000) // A[01:00]==2'b00, D[31:24]==ret
|
||||
#define SPI_REG_RD16 ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||
#define SPI_REG_RD16S ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||
#define SPI_REG_TIMER8 ((char*) 0x00000000) // A[01:00]==2'b00, D[31:24]==ret
|
||||
#define SPI_REG_TIMER16 ((short*) 0x00000000) // A[01:00]==2'b00, D[31:16]==ret
|
||||
// Write transfer registers
|
||||
#define SPI_REG_TX8 ((char*) 0x00000000) // A[07:00]==arg
|
||||
#define SPI_REG_TX16 ((char*) 0x00000000) // A[15:00]==arg
|
||||
#define SPI_REG_TX16S ((char*) 0x00000000) // A[05:00]==arg
|
||||
#define SPI_REG_ST16 ((char*) 0x00000000) // A[15:00]==arg
|
||||
#define SPI_REG_EMPTY ((char*) 0x00000000)
|
||||
// Control/status register (read/write)
|
||||
#define SPI_REG_RD_CSR ((char*) 0x00000000)
|
||||
#define SPI_REG_WR_CSR ((char*) 0x00000000)
|
||||
#define SPI_REG_CSR_BIT_nDET (0)
|
||||
#define SPI_REG_CSR_GET_nDET() ((*SPI_REG_RD_CSR>>SPI_REG_CSR_BIT_nDET) & 1)
|
||||
#define SPI_REG_CSR_BIT_MISO (1)
|
||||
#define SPI_REG_CSR_GET_MISO() ((*SPI_REG_RD_CSR>>SPI_REG_CSR_BIT_MISO) & 1)
|
||||
#define SPI_REG_CSR_BIT_SCK (2)
|
||||
#define SPI_REG_CSR_SET_SCK() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR | (1<<SPI_REG_CSR_BIT_SCK))
|
||||
#define SPI_REG_CSR_CLR_SCK() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR & ~(1<<SPI_REG_CSR_BIT_SCK))
|
||||
#define SPI_REG_CSR_BIT_CS (3)
|
||||
#define SPI_REG_CSR_SET_CS() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR | (1<<SPI_REG_CSR_BIT_CS))
|
||||
#define SPI_REG_CSR_CLR_CS() reg_write16(SPI_REG_WR_CSR, *SPI_REG_RD_CSR & ~(1<<SPI_REG_CSR_BIT_CS))
|
||||
|
||||
#define SPI_REG_SET_MOSI(x) reg_write16(SPI_REG_ST16, x ? 0xFFFF : 0x0000)
|
||||
|
||||
#pragma parameter _spi_hal_rx8(__A0, __A2, __A4, __D0, __D1, __D2)
|
||||
extern void _spi_hal_rx8(void *reg, void *rx, void *tmp, int length, int nops, int tmp2);
|
||||
static inline void spi_hal_rx8(void *reg, void *rx, int length, int nops) {
|
||||
_spi_hal_rx8(reg, rx, 0, length, nops, 0);
|
||||
}
|
||||
|
||||
#pragma parameter _spi_hal_rx16(__A0, __A2, __A4, __D0, __D1, __D2)
|
||||
extern void _spi_hal_rx16(void *reg, void *rx, void *tmp, int length, int nops, int tmp2);
|
||||
static inline void spi_hal_rx16(void *reg, void *rx, int length, int nops) {
|
||||
_spi_hal_rx16(reg, rx, 0, length, nops, 0);
|
||||
}
|
||||
|
||||
#pragma parameter _spi_hal_tx8(__A0, __A3, __A4, __D0, __D1, __D2)
|
||||
extern void _spi_hal_tx8(void *reg, void *tx, void *tmp, int length, int nops, int tmp2);
|
||||
static inline void spi_hal_tx8(void *reg, void *tx, int length, int nops) {
|
||||
_spi_hal_tx8(reg, tx, 0, length, nops, 0);
|
||||
}
|
||||
|
||||
#pragma parameter _spi_hal_tx16(__A0, __A3, __A4, __D0, __D1, __D2)
|
||||
extern void _spi_hal_tx16(void *reg, void *tx, void *tmp, int length, int nops, int tmp2);
|
||||
static inline void spi_hal_tx16(void *reg, void *tx, int length, int nops) {
|
||||
_spi_hal_tx16(reg, tx, 0, length, nops, 0);
|
||||
}
|
||||
|
||||
#pragma parameter _spi_hal_rxtx8(__A0, __A1, __A2, __A3, __A4, __D0, __D1, __D2)
|
||||
extern void _spi_hal_rxtx8(void *reg, void *read, void *rx, void *tx, void *tmp, int length, int nops, int tmp2);
|
||||
static inline void spi_hal_rxtx8(void *reg, void *read, void *rx, void *tx, int length, int nops) {
|
||||
_spi_hal_rxtx8(reg, read, rx, tx, 0, length, nops, 0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,49 @@
|
|||
.global spi_delay
|
||||
.global _reg_write16
|
||||
.global _reg_write8
|
||||
.global smear8to32
|
||||
|
||||
* delay calling convention
|
||||
* D0 - iterations
|
||||
|
||||
spi_delay:
|
||||
subq.w #1, %D0
|
||||
bne.b spi_delay
|
||||
rts
|
||||
|
||||
* reg_write calling convention
|
||||
* A0 - address
|
||||
* D0 - data (clobbered)
|
||||
* D1 - clobbered
|
||||
|
||||
_reg_write8:
|
||||
move.l %A0, %D1
|
||||
andi.l #0xFFFFFF00, %D1
|
||||
andi.l #0x000000FF, %D0
|
||||
or %D1, %D0
|
||||
movea %D0, %A0
|
||||
move.l (%A0), %D0
|
||||
rts
|
||||
|
||||
_reg_write16:
|
||||
move.l %A0, %D1
|
||||
andi.l #0xFFFF0000, %D1
|
||||
andi.l #0x0000FFFF, %D0
|
||||
or %D1, %D0
|
||||
movea %D0, %A0
|
||||
move.l (%A0), %D0
|
||||
rts
|
||||
|
||||
* smear8to32 calling convention
|
||||
* D0 - data in/out
|
||||
|
||||
smear8to32:
|
||||
andi.l #0xFF, %D0
|
||||
move.l %D0, %D1
|
||||
lsl.w #8, %D1
|
||||
or.w %D1, %D0
|
||||
lsl.w #8, %D1
|
||||
or.w %D1, %D0
|
||||
lsl.w #8, %D1
|
||||
or.w %D1, %D0
|
||||
rts
|
|
@ -0,0 +1,98 @@
|
|||
* spi calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* A2 - RX buffer
|
||||
* A3 - TX buffer
|
||||
* A4 - clobbered
|
||||
* D0 - length (clobbered)
|
||||
* D1 - nops (clobbered)
|
||||
* D2 - clobbered (save SR)
|
||||
* D3 - clobbered (save CACR)
|
||||
|
||||
.macro spi_call table, maxnops
|
||||
* Limit %D0 (length) to 1-256
|
||||
subq.w #1, %D0
|
||||
andi.l #0xFF, %D0
|
||||
addq.w #1, %D0
|
||||
|
||||
* Limit %D1 (nops) based on maxnops
|
||||
.if \maxnops == 1
|
||||
andi.l #1, %D1
|
||||
.elseif \maxnops == 3
|
||||
andi.l #3, %D1
|
||||
.elseif \maxnops == 7
|
||||
andi.l #7, %D1
|
||||
.elseif \maxnops == 15
|
||||
andi.l #15, %D1
|
||||
.elseif \maxnops != 0
|
||||
.error
|
||||
.endif
|
||||
|
||||
* Convert length to offset
|
||||
* %D0 = -%D0 (-length)
|
||||
neg.l %D0
|
||||
* %D0 = %D0 + 256 (-length + 256)
|
||||
add.l #256, %D0
|
||||
|
||||
.if \maxnops != 0
|
||||
* Combine nops with offset to get lookup table index
|
||||
* %D1 = %D1 * 4 * 256 (nops * 256)
|
||||
lsl.l #8, %D1
|
||||
* %D0 = %D0 + %D1 (offset + nops*256)
|
||||
or.l %D1, %D0
|
||||
.endif
|
||||
|
||||
* Get index of entry point from lookup table
|
||||
* %D0 = table[%D0] (table[4*(length+nops*256)])
|
||||
move.l (\table - ., %PC, %D0.w : 4), %D0
|
||||
|
||||
* Save status register and disable interrupts
|
||||
move.w %SR, %D2
|
||||
ori.w #0x0700, %SR
|
||||
|
||||
* Save CACR in %D3
|
||||
movec %CACR, %D3
|
||||
|
||||
* Copy CACR to %D1
|
||||
move.l %D3, %D1
|
||||
* Clear CACR bits:
|
||||
* DE ('040 enable data cache) (31)
|
||||
* WA ('030 write allocate) (13)
|
||||
* DBE ('030 data burst enable) (12)
|
||||
* CD ('030 clear data cache) (11)
|
||||
* CED ('030 clear entry in data cache) (10)
|
||||
* FD ('030 freeze data cache) (9)
|
||||
* ED ('030 enable data cache) (8)
|
||||
andi.l #0x7FFFC0FF, %D1
|
||||
* Set '030 CACR bits:
|
||||
* FD (freeze data cache) (9)
|
||||
ori.w #0x0200, %D1
|
||||
* Move back into CACR
|
||||
movec.l %D1, %CACR
|
||||
|
||||
* Jump to entry point
|
||||
* (table + table[length*4 + nops*4*256])
|
||||
jmp (\table - ., %PC, %D0.l)
|
||||
|
||||
* Return statement for use with parameter checking
|
||||
ret: rts
|
||||
.endm
|
||||
|
||||
.macro lookup_table base, nbase, stride, n
|
||||
dc.l \nbase - \base
|
||||
dc.l \nbase + \stride - \base
|
||||
dc.l \nbase + \stride+\stride - \base
|
||||
dc.l \nbase + \stride+\stride+\stride - \base
|
||||
.if \n > 0
|
||||
lookup_table \base, \nbase + \stride+\stride+\stride+\stride, \stride, \n-4
|
||||
.endif
|
||||
.endm
|
||||
|
||||
.macro unroll_table macro, nops, n
|
||||
.rept \n
|
||||
\macro \nops
|
||||
.endr
|
||||
move.w %D2, %SR
|
||||
movec.l %D3, %CACR
|
||||
rts
|
||||
.endm
|
|
@ -0,0 +1,73 @@
|
|||
* spi calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* A2 - RX buffer
|
||||
* A3 - TX buffer
|
||||
* A4 - clobbered
|
||||
* D0 - length (clobbered)
|
||||
* D1 - nops (clobbered)
|
||||
|
||||
.global _spi_hal_rx16
|
||||
|
||||
.include "spi_hal_common.s"
|
||||
|
||||
.macro _spi_hal_rx16_iteration nops
|
||||
move.w (%A0), (%A2)+
|
||||
.rept \nops
|
||||
nop
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.align 16
|
||||
_spi_hal_rx16:
|
||||
spi_call _spi_hal_rx16_lookup, 15
|
||||
.align 16
|
||||
_spi_hal_rx16_lookup:
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_0, 2, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_1, 4, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_2, 6, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_3, 8, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_4, 10, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_5, 12, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_6, 14, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_7, 16, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_8, 18, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_9, 20, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_10, 22, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_11, 24, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_12, 26, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_13, 28, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_14, 30, 256
|
||||
lookup_table _spi_hal_rx16_lookup, _spi_hal_rx16_table_15, 32, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_0: unroll_table _spi_hal_rx16_iteration, 0, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_1: unroll_table _spi_hal_rx16_iteration, 1, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_2: unroll_table _spi_hal_rx16_iteration, 2, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_3: unroll_table _spi_hal_rx16_iteration, 3, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_4: unroll_table _spi_hal_rx16_iteration, 4, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_5: unroll_table _spi_hal_rx16_iteration, 5, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_6: unroll_table _spi_hal_rx16_iteration, 6, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_7: unroll_table _spi_hal_rx16_iteration, 7, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_8: unroll_table _spi_hal_rx16_iteration, 8, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_9: unroll_table _spi_hal_rx16_iteration, 9, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_10: unroll_table _spi_hal_rx16_iteration, 10, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_11: unroll_table _spi_hal_rx16_iteration, 11, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_12: unroll_table _spi_hal_rx16_iteration, 12, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_13: unroll_table _spi_hal_rx16_iteration, 13, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_14: unroll_table _spi_hal_rx16_iteration, 14, 256
|
||||
.align 16
|
||||
_spi_hal_rx16_table_15: unroll_table _spi_hal_rx16_iteration, 15, 256
|
|
@ -0,0 +1,49 @@
|
|||
* spi calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* A2 - RX buffer
|
||||
* A3 - TX buffer
|
||||
* A4 - clobbered
|
||||
* D0 - length (clobbered)
|
||||
* D1 - nops (clobbered)
|
||||
|
||||
.global _spi_hal_rx8
|
||||
|
||||
.include "spi_hal_common.s"
|
||||
|
||||
.macro _spi_hal_rx8_iteration nops
|
||||
move.b (%A0), (%A2)+
|
||||
.rept \nops
|
||||
nop
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.align 16
|
||||
_spi_hal_rx8:
|
||||
spi_call _spi_hal_rx8_lookup, 7
|
||||
.align 16
|
||||
_spi_hal_rx8_lookup:
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_0, 2, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_1, 4, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_2, 6, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_3, 8, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_4, 10, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_5, 12, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_6, 14, 256
|
||||
lookup_table _spi_hal_rx8_lookup, _spi_hal_rx8_table_7, 16, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_0: unroll_table _spi_hal_rx8_iteration, 0, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_1: unroll_table _spi_hal_rx8_iteration, 1, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_2: unroll_table _spi_hal_rx8_iteration, 2, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_3: unroll_table _spi_hal_rx8_iteration, 3, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_4: unroll_table _spi_hal_rx8_iteration, 4, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_5: unroll_table _spi_hal_rx8_iteration, 5, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_6: unroll_table _spi_hal_rx8_iteration, 6, 256
|
||||
.align 16
|
||||
_spi_hal_rx8_table_7: unroll_table _spi_hal_rx8_iteration, 7, 256
|
|
@ -0,0 +1,62 @@
|
|||
* spi calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* A2 - RX buffer
|
||||
* A3 - TX buffer
|
||||
* A4 - clobbered
|
||||
* D0 - length (clobbered)
|
||||
* D1 - nops (clobbered)
|
||||
|
||||
* spi single calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* D0 - data
|
||||
* D1 - clobbered
|
||||
|
||||
.global _spi_hal_rxtx8
|
||||
.global _spi_hal_rxtx8single
|
||||
|
||||
.include "spi_hal_common.s"
|
||||
|
||||
.macro _spi_hal_rxtx8_iteration nops
|
||||
move.b (%A1), (%A2)+
|
||||
move.b (%A3)+, %D1
|
||||
move.b (%A0, %D1.W), %D1
|
||||
.rept \nops
|
||||
nop
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.align 16
|
||||
_spi_hal_rxtx8:
|
||||
spi_call _spi_hal_rxtx8_lookup, 7
|
||||
_spi_hal_rxtx8_single:
|
||||
move.b (%A1), %D0
|
||||
move.b (%A0, %D1.W), %D1
|
||||
rts
|
||||
.align 16
|
||||
_spi_hal_rxtx8_lookup:
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_0, 8, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_1, 10, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_2, 12, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_3, 14, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_4, 16, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_5, 18, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_6, 20, 256
|
||||
lookup_table _spi_hal_rxtx8_lookup, _spi_hal_rxtx8_table_7, 22, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_0: unroll_table _spi_hal_rxtx8_iteration, 0, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_1: unroll_table _spi_hal_rxtx8_iteration, 1, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_2: unroll_table _spi_hal_rxtx8_iteration, 2, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_3: unroll_table _spi_hal_rxtx8_iteration, 3, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_4: unroll_table _spi_hal_rxtx8_iteration, 4, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_5: unroll_table _spi_hal_rxtx8_iteration, 5, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_6: unroll_table _spi_hal_rxtx8_iteration, 6, 256
|
||||
.align 16
|
||||
_spi_hal_rxtx8_table_7: unroll_table _spi_hal_rxtx8_iteration, 7, 256
|
|
@ -0,0 +1,74 @@
|
|||
* spi calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* A2 - RX buffer
|
||||
* A3 - TX buffer
|
||||
* A4 - clobbered
|
||||
* D0 - length (clobbered)
|
||||
* D1 - nops (clobbered)
|
||||
|
||||
.global _spi_hal_tx16
|
||||
|
||||
.include "spi_hal_common.s"
|
||||
|
||||
.macro _spi_hal_tx16_iteration nops
|
||||
move.w (%A3)+, %D1
|
||||
move.b (%A0, %D1.W), %D1
|
||||
.rept \nops
|
||||
nop
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.align 16
|
||||
_spi_hal_tx16:
|
||||
spi_call _spi_hal_tx16_lookup, 15
|
||||
.align 16
|
||||
_spi_hal_tx16_lookup:
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_0, 6, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_1, 8, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_2, 10, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_3, 12, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_4, 14, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_5, 16, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_6, 18, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_7, 20, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_8, 22, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_9, 24, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_10, 26, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_11, 28, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_12, 30, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_13, 32, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_14, 34, 256
|
||||
lookup_table _spi_hal_tx16_lookup, _spi_hal_tx16_table_15, 36, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_0: unroll_table _spi_hal_tx16_iteration, 0, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_1: unroll_table _spi_hal_tx16_iteration, 1, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_2: unroll_table _spi_hal_tx16_iteration, 2, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_3: unroll_table _spi_hal_tx16_iteration, 3, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_4: unroll_table _spi_hal_tx16_iteration, 4, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_5: unroll_table _spi_hal_tx16_iteration, 5, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_6: unroll_table _spi_hal_tx16_iteration, 6, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_7: unroll_table _spi_hal_tx16_iteration, 7, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_8: unroll_table _spi_hal_tx16_iteration, 8, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_9: unroll_table _spi_hal_tx16_iteration, 9, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_10: unroll_table _spi_hal_tx16_iteration, 10, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_11: unroll_table _spi_hal_tx16_iteration, 11, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_12: unroll_table _spi_hal_tx16_iteration, 12, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_13: unroll_table _spi_hal_tx16_iteration, 13, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_14: unroll_table _spi_hal_tx16_iteration, 14, 256
|
||||
.align 16
|
||||
_spi_hal_tx16_table_15: unroll_table _spi_hal_tx16_iteration, 15, 256
|
|
@ -0,0 +1,50 @@
|
|||
* spi calling convention
|
||||
* A0 - ROM register
|
||||
* A1 - readback address
|
||||
* A2 - RX buffer
|
||||
* A3 - TX buffer
|
||||
* A4 - clobbered
|
||||
* D0 - length (clobbered)
|
||||
* D1 - nops (clobbered)
|
||||
|
||||
.global _spi_hal_tx8
|
||||
|
||||
.include "spi_hal_common.s"
|
||||
|
||||
.macro _spi_hal_tx8_iteration nops
|
||||
move.b (%A3)+, %D1
|
||||
move.b (%A0, %D1.W), %D1
|
||||
.rept \nops
|
||||
nop
|
||||
.endr
|
||||
.endm
|
||||
|
||||
.align 16
|
||||
_spi_hal_tx8:
|
||||
spi_call _spi_hal_tx8_lookup, 7
|
||||
.align 16
|
||||
_spi_hal_tx8_lookup:
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_0, 6, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_1, 8, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_2, 10, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_3, 12, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_4, 14, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_5, 16, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_6, 18, 256
|
||||
lookup_table _spi_hal_tx8_lookup, _spi_hal_tx8_table_7, 20, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_0: unroll_table _spi_hal_tx8_iteration, 0, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_1: unroll_table _spi_hal_tx8_iteration, 1, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_2: unroll_table _spi_hal_tx8_iteration, 2, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_3: unroll_table _spi_hal_tx8_iteration, 3, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_4: unroll_table _spi_hal_tx8_iteration, 4, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_5: unroll_table _spi_hal_tx8_iteration, 5, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_6: unroll_table _spi_hal_tx8_iteration, 6, 256
|
||||
.align 16
|
||||
_spi_hal_tx8_table_7: unroll_table _spi_hal_tx8_iteration, 7, 256
|
Loading…
Reference in New Issue