diff --git a/flash.tos/LICENSE b/flash.tos/LICENSE deleted file mode 100644 index 1bcc46f..0000000 --- a/flash.tos/LICENSE +++ /dev/null @@ -1,342 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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. - - - Copyright (C) - - 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. - - , 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 Library General -Public License instead of this License. - - diff --git a/flash.tos/Makefile b/flash.tos/Makefile index 3e98c41..f34dd15 100644 --- a/flash.tos/Makefile +++ b/flash.tos/Makefile @@ -1,34 +1,37 @@ -CROSS= N +#CC = gcc +CC = /usr/local/bin/gcc +LD = ld +STRIP = strip +STACK = stack -CROSSBINDIR_IS_Y= m68k-atari-mint- -CROSSBINDIR_IS_N= +VERSION = 0x0202 -CROSSBINDIR= $(CROSSBINDIR_IS_$(CROSS)) +FIREBEE_COD = ./nonfree/firebee1.rbf -CC= $(CROSSBINDIR)gcc -STRIP= $(CROSSBINDIR)strip -STACK= $(CROSSBINDIR)stack - -VERSION= 0x0104 - -SRCDIR= ./ -INCDIR= ./include -OBJDIR= ./obj -OBJDIRCF= ./obj_cf -OBJDIRCF2= ./obj_cf2 -OBJDIRCF3= ./obj_cf3 +SRCDIR = . +INCDIR = ./include +OBJDIR = ./obj +OBJDIRCF = ./obj_cf +OBJDIRCF2 = ./obj_cf2 +OBJDIRCF3 = ./obj_cf3 SUBOBJDIRS= \ - $(OBJDIR)/tos + $(OBJDIR)/tos \ + $(OBJDIR)/tos/patches SUBOBJDIRSCF= \ - $(OBJDIRCF)/tos + $(OBJDIRCF)/tos \ + $(OBJDIRCF)/tos/patches \ + $(OBJDIRCF)/desk \ + $(OBJDIRCF)/aes SUBOBJDIRSCF2= \ - $(OBJDIRCF2)/tos + $(OBJDIRCF2)/tos \ + $(OBJDIRCF2)/tos/patches SUBOBJDIRSCF3= \ - $(OBJDIRCF3)/tos + $(OBJDIRCF3)/tos \ + $(OBJDIRCF3)/tos/patches INCLUDE= -I$(INCDIR) CFLAGS= -m68060 -Wall -O2 -fomit-frame-pointer @@ -39,378 +42,413 @@ CFLAGS_TOS= -m68060 -Wall -O2 -fomit-frame-pointer CFLAGSCF_TOS= -m5200 -Wall -O2 -fomit-frame-pointer -Wa,-m5200 -DCOLDFIRE CFLAGSCF2_TOS= $(CFLAGSCF_TOS) -DMCF5445X CFLAGSCF3_TOS= $(CFLAGSCF_TOS) -DMCF547X +CFLAGSDESK= -D_MINT_=0 -D_MORE_AV=0 -D_EDITLABELS=0 -D_OVSCAN=0 -D__USE_MACROS=0 -DCFGEMP=0 -DPALETTES=0 -D_PREDEF=0 -D_SHOWFIND=0 -D_MENUDEL=0 -D_FONT_SEL=0 -DAES_RECT=0 -D_LOGFILE=0 -FLASH_TOS_FIRE_ENGINE= 0xFFB00000 +FLASH_BOOT= 0x00E80000 +FLASH_DIAG= 0x00ED0000 +FLASH_TOS= 0x00E00000 +FLASH_TOS_FIRE_ENGINE= 0xFF900000 FLASH_TOS_M54455EVB= 0xC0000000 -FLASH_TOS_COLDARI= 0xFF700000 +FLASH_BOOT_TOS_FIREBEE= 0xE0000000 +FLASH_TOS_FIREBEE= 0xE0400000 +FLASH_COD_FIREBEE= 0xE0700000 + FLASH_CF68KLIB= 0x00E90000 FLASH_CF68KLIB2= 0x00E90000 FLASH_CF68KLIB3= 0x00E90000 - -TOS= ct60tos.bin -TOSPCI= ctpcitos.bin -TOSPCI_1GB= ctpci1gb.bin -CF68KLIB= cf68klib.bin -CF68KLIB2= cf68klib2.bin -CF68KLIB3= cf68klib3.bin -TOSCF= firetos_m5484lite.bin -TOSCF2= firetos_m54455evb.bin -TOSCF3= firetos_coldari.bin -TOSCFHEX= firetos_m5484lite.hex -TOSCFHEX2=firetos_m54455evb.hex -TOSCFHEX3=firetos_coldari.hex -PCI= pci.hex -PCICF= pci_cf.hex -PCICF2= pci_cf2.hex -PCICF3= pci_cf3.hex - -BINHEX_BINARY= binhex.ttp -COMPRESS_BINARY= compress.ttp +FLASH_AES= 0x00E1F38A +FLASH2_AES= 0x00E5050A +RAM_AES= 0x8F9A + +TOS= ct60tos.bin +TOSPCI= ctpcitos.bin +ATARIDIAG= sparrow.out +CF68KLIB= cf68klib.hex +CF68KLIB2= cf68klib2.hex +CF68KLIB3= cf68klib3.hex +AESCF= aes_m5484lite.hex +TOSCF= firetos_m5484lite.bin +TOSCF2= firetos_m54455evb.bin +TOSCF3= firetos_firebee.bin +TOSCFHEX= firetos_m5484lite.hex +TOSCFHEX2= firetos_m54455evb.hex +TOSCFHEX3= firetos_firebee.hex +TOSCFHEX3B= rescuetos_firebee.hex +BOOT= boot.hex +BOOTCF= boot_cf.hex +BOOTCF2= boot_cf2.hex +BOOTCF3= boot_cf3.hex +DIAG= diag.hex +FPGACF3= fpga_cf3.hex +DRIVERS= drivers.hex +DRIVERSCF= drivers_cf.hex +DRIVERSCF2= drivers_cf2.hex +DRIVERSCF3= drivers_cf3.hex GENTOS_BINARY= gentos.ttp -GENTOS_BINARY_1GB= gentos1g.ttp GENTOS_BINARYCF= gentoscf.ttp GENTOS_BINARYCF2= gentoscf2.ttp GENTOS_BINARYCF3= gentoscf3.ttp GENTOS_STACKSIZE= 64k -GENTOS_OBJS= \ - $(OBJDIR)/gentos.o \ - $(OBJDIR)/lz.o \ - $(OBJDIR)/srec.o \ - \ - $(OBJDIR)/tos/start.o \ - \ - $(OBJDIR)/tos/pmmu.o \ - $(OBJDIR)/tos/cookies.o \ - $(OBJDIR)/tos/dsp.o \ - $(OBJDIR)/tos/periph.o \ - $(OBJDIR)/tos/cache.o \ - $(OBJDIR)/tos/movep.o \ - $(OBJDIR)/tos/boot.o \ - $(OBJDIR)/tos/init_par.o \ - $(OBJDIR)/tos/blitter.o \ - $(OBJDIR)/tos/bios.o \ - $(OBJDIR)/tos/xbios.o \ - $(OBJDIR)/tos/gemdos.o \ - $(OBJDIR)/tos/aes.o \ - $(OBJDIR)/tos/vectors.o \ - $(OBJDIR)/tos/videl.o \ - $(OBJDIR)/tos/debug.o \ - \ - $(OBJDIR)/tos/half.o \ - \ - $(OBJDIR)/tos/version.o \ - $(OBJDIR)/tos/movep2.o \ - $(OBJDIR)/tos/blitter2.o \ - $(OBJDIR)/tos/bios2.o \ - $(OBJDIR)/tos/xbios2.o \ - $(OBJDIR)/tos/gemdos2.o \ - $(OBJDIR)/tos/aes2.o \ - $(OBJDIR)/tos/vectors2.o \ - $(OBJDIR)/tos/debug2.o \ - $(OBJDIR)/tos/ataboot.o \ - $(OBJDIR)/tos/extvidel.o \ - $(OBJDIR)/tos/magxboot.o \ - $(OBJDIR)/tos/sdram.o \ - $(OBJDIR)/tos/pmmu2.o \ - $(OBJDIR)/tos/lz.o \ - $(OBJDIR)/tos/videl2.o \ - \ - $(OBJDIR)/tos/end.o -GENTOS_OBJS_1GB= \ - $(OBJDIR)/gentos.o \ - $(OBJDIR)/lz.o \ - $(OBJDIR)/srec.o \ - \ - $(OBJDIR)/tos/start.o \ - \ - $(OBJDIR)/tos/pmmu.o \ - $(OBJDIR)/tos/cookies.o \ - $(OBJDIR)/tos/dsp.o \ - $(OBJDIR)/tos/periph.o \ - $(OBJDIR)/tos/cache.o \ - $(OBJDIR)/tos/movep.o \ - $(OBJDIR)/tos/boot.o \ - $(OBJDIR)/tos/init_par.o \ - $(OBJDIR)/tos/blitter.o \ - $(OBJDIR)/tos/bios.o \ - $(OBJDIR)/tos/xbios.o \ - $(OBJDIR)/tos/gemdos.o \ - $(OBJDIR)/tos/aes.o \ - $(OBJDIR)/tos/vectors.o \ - $(OBJDIR)/tos/videl.o \ - $(OBJDIR)/tos/debug.o \ +BOOT_OBJS= \ + $(OBJDIR)/tos/version.o \ + $(OBJDIR)/tos/boot2.o \ \ - $(OBJDIR)/tos/half.o \ + $(OBJDIR)/tos/patches/start.o \ + $(OBJDIR)/tos/patches/boot.o \ + $(OBJDIR)/tos/patches/pmmu.o \ + $(OBJDIR)/tos/patches/cookies.o \ + $(OBJDIR)/tos/patches/dsp.o \ + $(OBJDIR)/tos/patches/periph.o \ + $(OBJDIR)/tos/patches/cache.o \ + $(OBJDIR)/tos/patches/movep.o \ + $(OBJDIR)/tos/patches/params.o \ + $(OBJDIR)/tos/patches/blitter.o \ + $(OBJDIR)/tos/patches/bios.o \ + $(OBJDIR)/tos/patches/xbios.o \ + $(OBJDIR)/tos/patches/gemdos.o \ + $(OBJDIR)/tos/patches/aes.o \ + $(OBJDIR)/tos/patches/vectors.o \ + $(OBJDIR)/tos/patches/videl.o \ + $(OBJDIR)/tos/patches/end.o \ \ - $(OBJDIR)/tos/version.o \ + $(OBJDIR)/tos/cache2.o \ $(OBJDIR)/tos/movep2.o \ $(OBJDIR)/tos/blitter2.o \ $(OBJDIR)/tos/bios2.o \ - $(OBJDIR)/tos/xbios2_1gb.o \ + $(OBJDIR)/tos/conout.o \ + $(OBJDIR)/tos/xbios2.o \ $(OBJDIR)/tos/gemdos2.o \ $(OBJDIR)/tos/aes2.o \ $(OBJDIR)/tos/vectors2.o \ - $(OBJDIR)/tos/debug2.o \ $(OBJDIR)/tos/ataboot.o \ $(OBJDIR)/tos/extvidel.o \ $(OBJDIR)/tos/magxboot.o \ - $(OBJDIR)/tos/sdram.o \ $(OBJDIR)/tos/pmmu2.o \ + $(OBJDIR)/tos/params2.o \ + $(OBJDIR)/tos/ide_scsi.o \ + $(OBJDIR)/tos/i2c.o \ + $(OBJDIR)/tos/temp.o \ + $(OBJDIR)/tos/fan.o \ $(OBJDIR)/tos/lz.o \ - $(OBJDIR)/tos/videl2.o \ - \ - $(OBJDIR)/tos/end.o + $(OBJDIR)/tos/LzmaDecode.o \ + $(OBJDIR)/tos/videl2.o -GENTOS_OBJSCF= \ - $(OBJDIRCF)/gentos.o \ - $(OBJDIRCF)/lz.o \ - $(OBJDIRCF)/srec.o \ +BOOT_OBJSCF= \ + $(OBJDIRCF)/tos/version.o \ + $(OBJDIRCF)/tos/boot2.o \ \ - $(OBJDIRCF)/tos/start.o \ + $(OBJDIRCF)/tos/patches/start.o \ + $(OBJDIRCF)/tos/patches/boot.o \ + $(OBJDIRCF)/tos/patches/pmmu.o \ + $(OBJDIRCF)/tos/patches/cookies.o \ + $(OBJDIRCF)/tos/patches/dsp.o \ + $(OBJDIRCF)/tos/patches/periph.o \ + $(OBJDIRCF)/tos/patches/cartridge.o \ + $(OBJDIRCF)/tos/patches/cache.o \ + $(OBJDIRCF)/tos/patches/movep.o \ + $(OBJDIRCF)/tos/patches/params.o \ + $(OBJDIRCF)/tos/patches/blitter.o \ + $(OBJDIRCF)/tos/patches/bios.o \ + $(OBJDIRCF)/tos/patches/xbios.o \ + $(OBJDIRCF)/tos/patches/gemdos.o \ + $(OBJDIRCF)/tos/patches/aes.o \ + $(OBJDIRCF)/tos/patches/vectors.o \ + $(OBJDIRCF)/tos/patches/videl.o \ + $(OBJDIRCF)/tos/patches/end.o \ \ - $(OBJDIRCF)/tos/pmmu.o \ - $(OBJDIRCF)/tos/cookies.o \ - $(OBJDIRCF)/tos/dsp.o \ - $(OBJDIRCF)/tos/periph.o \ - $(OBJDIRCF)/tos/mfp.o \ - $(OBJDIRCF)/tos/cartridge.o \ - $(OBJDIRCF)/tos/cache.o \ - $(OBJDIRCF)/tos/movep.o \ - $(OBJDIRCF)/tos/boot.o \ - $(OBJDIRCF)/tos/init_par.o \ - $(OBJDIRCF)/tos/blitter.o \ - $(OBJDIRCF)/tos/bios.o \ - $(OBJDIRCF)/tos/xbios.o \ - $(OBJDIRCF)/tos/gemdos.o \ - $(OBJDIRCF)/tos/aes.o \ - $(OBJDIRCF)/tos/vectors.o \ - $(OBJDIRCF)/tos/videl.o \ - $(OBJDIRCF)/tos/debug.o \ - \ - $(OBJDIRCF)/tos/half.o \ - \ - $(OBJDIRCF)/tos/version.o \ + $(OBJDIRCF)/tos/cache2.o \ $(OBJDIRCF)/tos/movep2.o \ $(OBJDIRCF)/tos/blitter2.o \ $(OBJDIRCF)/tos/bios2.o \ + $(OBJDIRCF)/tos/conout.o \ $(OBJDIRCF)/tos/xbios2.o \ $(OBJDIRCF)/tos/gemdos2.o \ $(OBJDIRCF)/tos/aes2.o \ $(OBJDIRCF)/tos/vectors2.o \ - $(OBJDIRCF)/tos/debug2.o \ - $(OBJDIRCF)/tos/magxboot.o \ - $(OBJDIRCF)/tos/sdram.o \ $(OBJDIRCF)/tos/pmmu2.o \ + $(OBJDIRCF)/tos/params2.o \ + $(OBJDIRCF)/tos/ide_scsi.o \ $(OBJDIRCF)/tos/lz.o \ - $(OBJDIRCF)/tos/videl2.o \ - \ - $(OBJDIRCF)/tos/end.o + $(OBJDIRCF)/tos/LzmaDecode.o \ + $(OBJDIRCF)/tos/videl2.o -GENTOS_OBJSCF2= \ - $(OBJDIRCF2)/gentos.o \ - $(OBJDIRCF)/lz.o \ - $(OBJDIRCF)/srec.o \ - \ - $(OBJDIRCF)/tos/start.o \ - \ - $(OBJDIRCF)/tos/pmmu.o \ - $(OBJDIRCF)/tos/cookies.o \ - $(OBJDIRCF)/tos/dsp.o \ - $(OBJDIRCF)/tos/periph.o \ - $(OBJDIRCF)/tos/mfp.o \ - $(OBJDIRCF)/tos/cartridge.o \ - $(OBJDIRCF)/tos/cache.o \ - $(OBJDIRCF)/tos/movep.o \ - $(OBJDIRCF)/tos/boot.o \ - $(OBJDIRCF)/tos/init_par.o \ - $(OBJDIRCF)/tos/blitter.o \ - $(OBJDIRCF)/tos/bios.o \ - $(OBJDIRCF)/tos/xbios.o \ - $(OBJDIRCF)/tos/gemdos.o \ - $(OBJDIRCF)/tos/aes.o \ - $(OBJDIRCF)/tos/vectors.o \ - $(OBJDIRCF)/tos/videl.o \ - $(OBJDIRCF)/tos/debug.o \ +BOOT_OBJSCF2= \ + $(OBJDIRCF2)/tos/version.o \ + $(OBJDIRCF2)/tos/boot2.o \ \ - $(OBJDIRCF)/tos/half.o \ + $(OBJDIRCF)/tos/patches/start.o \ + $(OBJDIRCF2)/tos/patches/boot.o \ + $(OBJDIRCF)/tos/patches/pmmu.o \ + $(OBJDIRCF2)/tos/patches/cookies.o \ + $(OBJDIRCF)/tos/patches/dsp.o \ + $(OBJDIRCF)/tos/patches/periph.o \ + $(OBJDIRCF)/tos/patches/cartridge.o \ + $(OBJDIRCF)/tos/patches/cache.o \ + $(OBJDIRCF)/tos/patches/movep.o \ + $(OBJDIRCF)/tos/patches/params.o \ + $(OBJDIRCF)/tos/patches/blitter.o \ + $(OBJDIRCF)/tos/patches/bios.o \ + $(OBJDIRCF)/tos/patches/xbios.o \ + $(OBJDIRCF)/tos/patches/gemdos.o \ + $(OBJDIRCF)/tos/patches/aes.o \ + $(OBJDIRCF)/tos/patches/vectors.o \ + $(OBJDIRCF)/tos/patches/videl.o \ + $(OBJDIRCF)/tos/patches/end.o \ \ - $(OBJDIRCF2)/tos/version.o \ + $(OBJDIRCF)/tos/cache2.o \ $(OBJDIRCF)/tos/movep2.o \ $(OBJDIRCF2)/tos/blitter2.o \ $(OBJDIRCF2)/tos/bios2.o \ + $(OBJDIRCF2)/tos/conout.o \ $(OBJDIRCF2)/tos/xbios2.o \ $(OBJDIRCF2)/tos/gemdos2.o \ $(OBJDIRCF2)/tos/aes2.o \ $(OBJDIRCF2)/tos/vectors2.o \ - $(OBJDIRCF2)/tos/debug2.o \ - $(OBJDIRCF)/tos/magxboot.o \ - $(OBJDIRCF2)/tos/sdram.o \ $(OBJDIRCF2)/tos/pmmu2.o \ + $(OBJDIRCF2)/tos/params2.o \ + $(OBJDIRCF2)/tos/ide_scsi.o \ $(OBJDIRCF)/tos/lz.o \ - $(OBJDIRCF2)/tos/videl2.o \ - \ - $(OBJDIRCF)/tos/end.o + $(OBJDIRCF)/tos/LzmaDecode.o \ + $(OBJDIRCF2)/tos/videl2.o -GENTOS_OBJSCF3= \ - $(OBJDIRCF3)/gentos.o \ - $(OBJDIRCF)/lz.o \ - $(OBJDIRCF)/srec.o \ - \ - $(OBJDIRCF)/tos/start.o \ - \ - $(OBJDIRCF)/tos/pmmu.o \ - $(OBJDIRCF)/tos/cookies.o \ - $(OBJDIRCF)/tos/dsp.o \ - $(OBJDIRCF)/tos/periph.o \ - $(OBJDIRCF)/tos/mfp.o \ - $(OBJDIRCF)/tos/cartridge.o \ - $(OBJDIRCF)/tos/cache.o \ - $(OBJDIRCF)/tos/movep.o \ - $(OBJDIRCF)/tos/boot.o \ - $(OBJDIRCF)/tos/init_par.o \ - $(OBJDIRCF)/tos/blitter.o \ - $(OBJDIRCF)/tos/bios.o \ - $(OBJDIRCF)/tos/xbios.o \ - $(OBJDIRCF)/tos/gemdos.o \ - $(OBJDIRCF)/tos/aes.o \ - $(OBJDIRCF)/tos/vectors.o \ - $(OBJDIRCF)/tos/videl.o \ - $(OBJDIRCF)/tos/debug.o \ +BOOT_OBJSCF3= \ + $(OBJDIRCF3)/tos/version.o \ + $(OBJDIRCF3)/tos/boot2.o \ \ - $(OBJDIRCF)/tos/half.o \ + $(OBJDIRCF)/tos/patches/start.o \ + $(OBJDIRCF3)/tos/patches/boot.o \ + $(OBJDIRCF)/tos/patches/pmmu.o \ + $(OBJDIRCF3)/tos/patches/cookies.o \ + $(OBJDIRCF)/tos/patches/dsp.o \ + $(OBJDIRCF)/tos/patches/periph.o \ + $(OBJDIRCF)/tos/patches/cartridge.o \ + $(OBJDIRCF)/tos/patches/cache.o \ + $(OBJDIRCF)/tos/patches/movep.o \ + $(OBJDIRCF)/tos/patches/params.o \ + $(OBJDIRCF)/tos/patches/blitter.o \ + $(OBJDIRCF)/tos/patches/bios.o \ + $(OBJDIRCF3)/tos/patches/xbios.o \ + $(OBJDIRCF)/tos/patches/gemdos.o \ + $(OBJDIRCF)/tos/patches/aes.o \ + $(OBJDIRCF)/tos/patches/vectors.o \ + $(OBJDIRCF3)/tos/patches/videl.o \ + $(OBJDIRCF)/tos/patches/end.o \ \ - $(OBJDIRCF3)/tos/version.o \ + $(OBJDIRCF)/tos/cache2.o \ $(OBJDIRCF)/tos/movep2.o \ $(OBJDIRCF)/tos/blitter2.o \ $(OBJDIRCF3)/tos/bios2.o \ + $(OBJDIRCF3)/tos/conout.o \ $(OBJDIRCF3)/tos/xbios2.o \ $(OBJDIRCF3)/tos/gemdos2.o \ $(OBJDIRCF3)/tos/aes2.o \ $(OBJDIRCF3)/tos/vectors2.o \ - $(OBJDIRCF3)/tos/debug2.o \ - $(OBJDIRCF)/tos/magxboot.o \ - $(OBJDIRCF3)/tos/sdram.o \ $(OBJDIRCF3)/tos/pmmu2.o \ + $(OBJDIRCF3)/tos/params2.o \ + $(OBJDIRCF3)/tos/ide_scsi.o \ $(OBJDIRCF)/tos/lz.o \ - $(OBJDIRCF3)/tos/videl2.o \ - \ - $(OBJDIRCF)/tos/end.o - -NFDISTDIR = ./nonfree -NFDISTFILES = \ - $(NFDISTDIR)/tos404.bin \ - $(NFDISTDIR)/sparrow.out - -NFDISTFILESCF = \ - $(NFDISTDIR)/tos404.bin \ + $(OBJDIRCF)/tos/LzmaDecode.o \ + $(OBJDIRCF3)/tos/videl2.o + +AES_OBJSCF= \ + $(OBJDIRCF)/aes/gcc.o \ + $(OBJDIRCF)/aes/hard_dep.o \ + $(OBJDIRCF)/aes/trap_aes.o \ + $(OBJDIRCF)/aes/phandle3.o \ + $(OBJDIRCF)/aes/mouse2.o \ + $(OBJDIRCF)/aes/userdef2.o \ + $(OBJDIRCF)/aes/flagset2.o \ + $(OBJDIRCF)/aes/setjmp2.o \ + $(OBJDIRCF)/aes/aes_main.o \ + $(OBJDIRCF)/aes/initstru.o \ + $(OBJDIRCF)/aes/appl.o \ + $(OBJDIRCF)/aes/evnt.o \ + $(OBJDIRCF)/aes/form.o \ + $(OBJDIRCF)/aes/fsel.o \ + $(OBJDIRCF)/aes/graf.o \ + $(OBJDIRCF)/aes/menu.o \ + $(OBJDIRCF)/aes/objc.o \ + $(OBJDIRCF)/aes/rsrc2.o \ + $(OBJDIRCF)/aes/scrp.o \ + $(OBJDIRCF)/aes/shel.o \ + $(OBJDIRCF)/aes/wind.o \ + $(OBJDIRCF)/aes/utils.o \ + $(OBJDIRCF)/aes/wdlg.o \ + $(OBJDIRCF)/aes/pdlg.o \ + $(OBJDIRCF)/aes/memory.o \ + $(OBJDIRCF)/aes/myaesrsc.o \ + $(OBJDIRCF)/aes/config.o \ + $(OBJDIRCF)/aes/stdlib.o \ + $(OBJDIRCF)/aes/printk.o + +DESK_OBJSCF= \ + $(OBJDIRCF)/desk/deskstart.o \ + $(OBJDIRCF)/desk/deskmain.o \ + $(OBJDIRCF)/desk/config.o \ + $(OBJDIRCF)/desk/resource.o \ + $(OBJDIRCF)/desk/icon.o \ + $(OBJDIRCF)/desk/window.o \ + $(OBJDIRCF)/desk/copy.o \ + $(OBJDIRCF)/desk/printer.o \ + $(OBJDIRCF)/desk/lists.o \ + $(OBJDIRCF)/desk/applik.o \ + $(OBJDIRCF)/desk/prgtype.o \ + $(OBJDIRCF)/desk/icontype.o \ + $(OBJDIRCF)/desk/filetype.o \ + $(OBJDIRCF)/desk/screen.o \ + $(OBJDIRCF)/desk/showinfo.o \ + $(OBJDIRCF)/desk/font.o \ + $(OBJDIRCF)/desk/va.o \ + $(OBJDIRCF)/desk/dragdrop.o \ + $(OBJDIRCF)/desk/environm.o \ + $(OBJDIRCF)/desk/startprg.o \ + $(OBJDIRCF)/desk/floppy.o \ + $(OBJDIRCF)/desk/video.o \ + $(OBJDIRCF)/desk/file.o \ + $(OBJDIRCF)/desk/dir.o \ + $(OBJDIRCF)/desk/open.o \ + $(OBJDIRCF)/desk/viewer.o \ + $(OBJDIRCF)/desk/events.o \ + $(OBJDIRCF)/desk/slider.o \ + $(OBJDIRCF)/desk/stringf.o \ + $(OBJDIRCF)/desk/error.o \ + $(OBJDIRCF)/desk/xerror.o \ + $(OBJDIRCF)/desk/xfilesys.o \ + $(OBJDIRCF)/desk/xdialog.o \ + $(OBJDIRCF)/desk/xdnmdial.o \ + $(OBJDIRCF)/desk/xdevent.o \ + $(OBJDIRCF)/desk/xddraw.o \ + $(OBJDIRCF)/desk/xdutil.o \ + $(OBJDIRCF)/desk/xdemodes.o \ + $(OBJDIRCF)/desk/xwindow.o \ + $(OBJDIRCF)/desk/pathutil.o \ + $(OBJDIRCF)/desk/gettos.o \ + $(OBJDIRCF)/desk/strsncpy.o \ + $(OBJDIRCF)/desk/minmax.o \ + $(OBJDIRCF)/desk/other.o \ + $(OBJDIRCF)/desk/qsort.o \ + $(OBJDIRCF)/desk/getenv.o + +DIR = ./nonfree +FILES = \ + $(DIR)/tos404.bin \ + $(BOOT) \ + $(DIR)/$(ATARIDIAG) + +#FILESCF = \ +# $(DIR)/tos404.bin \ +# $(BOOT) \ +# $(DESKCF) \ +# $(AESCF) \ +# $(CF68KLIB) + +FILESCF = \ + $(DIR)/tos404.bin \ + $(BOOTCF) \ $(CF68KLIB) -NFDISTFILESCF2 = \ - $(NFDISTDIR)/tos404.bin \ +FILESCF2 = \ + $(DIR)/tos404.bin \ + $(BOOTCF2) \ $(CF68KLIB2) -NFDISTFILESCF3 = \ - $(NFDISTDIR)/tos404.bin \ +FILESCF3 = \ + $(DIR)/tos404.bin \ + $(BOOTCF3) \ $(CF68KLIB3) -all: version.h $(BINHEX_BINARY) $(COMPRESS_BINARY) $(PCI) $(PCICF) $(PCICF2) $(PCICF3) $(TOS) $(TOSPCI) $(TOSPCI_1GB) $(CF68KLIB) $(CF68KLIB2) $(CF68KLIB3) $(TOSCF) $(TOSCF2) $(TOSCF3) $(TOSCFHEX) $(TOSCFHEX2) $(TOSCFHEX3) +all: $(GENTOS_BINARY) $(GENTOS_BINARYCF) $(GENTOS_BINARYCF2) $(GENTOS_BINARYCF3) version.h $(BOOT) $(BOOTCF) $(BOOTCF2) $(BOOTCF3) $(DIAG) $(DRIVERS) $(DRIVERSCF) $(DRIVERSCF2) $(DRIVERSCF3) \ + $(TOS) $(TOSPCI) $(CF68KLIB) $(CF68KLIB2) $(CF68KLIB3) $(TOSCF) $(TOSCF2) $(TOSCF3) $(TOSCFHEX) $(TOSCFHEX2) $(TOSCFHEX3) -ct60: version.h $(BINHEX_BINARY) $(COMPRESS_BINARY) $(PCI) $(TOS) $(TOSPCI) $(TOSPCI_1GB) +ct60: $(GENTOS_BINARY) version.h $(BOOT) $(DRIVERS) $(DIAG) $(TOS) $(TOSPCI) -m5484lite: version.h $(BINHEX_BINARY) $(COMPRESS_BINARY) $(PCICF) $(CF68KLIB) $(TOSCF) $(TOSCFHEX) +m5484lite: version.h $(GENTOS_BINARYCF) $(BOOTCF) $(DRIVERSCF) $(CF68KLIB) $(TOSCF) $(TOSCFHEX) +#m5484lite: version.h $(GENTOS_BINARYCF) $(BOOTCF) $(DRIVERSCF) $(CF68KLIB) $(AESCF) $(TOSCF) $(TOSCFHEX) -m54455evb: version.h $(BINHEX_BINARY) $(COMPRESS_BINARY) $(PCICF2) $(CF68KLIB2) $(TOSCF2) $(TOSCFHEX2) +m54455evb: version.h $(GENTOS_BINARYCF2) $(BOOTCF2) $(DRIVERSCF2) $(CF68KLIB2) $(TOSCF2) $(TOSCFHEX2) -coldari: version.h $(BINHEX_BINARY) $(COMPRESS_BINARY) $(PCICF3) $(CF68KLIB3) $(TOSCF3) $(TOSCFHEX3) +firebee: version.h $(GENTOS_BINARYCF3) $(BOOTCF3) $(DRIVERSCF3) $(CF68KLIB3) $(TOSCF3) $(TOSCFHEX3) clean: rm -rf $(OBJDIR) $(OBJDIRCF) $(OBJDIRCF2) $(OBJDIRCF3) - rm -f $(BINHEX_BINARY) $(COMPRESS_BINARY) $(GENTOS_BINARY) $(GENTOS_BINARYCF) $(GENTOS_BINARYCF2) $(GENTOS_BINARYCF3) $(TOS) $(TOSPCI) $(TOSPCI_1GB) $(CF68KLIB) $(CF68KLIB2) $(CF68KLIB3) $(TOSCF) $(TOSCF2) $(TOSCF3) $(TOSCFHEX) $(TOSCFHEX2) $(TOSCFHEX3) - make clean -C pci + rm -f $(GENTOS_BINARY) $(GENTOS_BINARYCF) $(GENTOS_BINARYCF2) $(GENTOS_BINARYCF3) $(BOOT) $(BOOTCF) $(BOOTCF2) $(BOOTCF3) $(CF68KLIB) $(CF68KLIB2) $(CF68KLIB3) \ + $(TOS) $(TOSPCI) $(TOSCF) $(TOSCF2) $(TOSCF3) $(TOSCFHEX) $(TOSCFHEX2) $(TOSCFHEX3) $(TOSCFHEX3B) $(DIAG) $(FPGACF3) boot.map boot_cf.map boot_cf2.map boot_cf3.map + make clean -C drivers -$(BINHEX_BINARY): $(OBJDIR)/binhex.o - $(CC) $(OBJDIR)/binhex.o -o $(BINHEX_BINARY) - $(STRIP) $(BINHEX_BINARY) - $(STACK) -S $(GENTOS_STACKSIZE) $(BINHEX_BINARY) +$(BOOT): $(BOOT_OBJS) + $(LD) --oformat srec -Map boot.map --cref -Ttext $(FLASH_BOOT) -s -o $(BOOT) $(BOOT_OBJS) -$(COMPRESS_BINARY): $(OBJDIR)/compress.o $(OBJDIR)/lz.o - $(CC) $(OBJDIR)/compress.o $(OBJDIR)/lz.o -o $(COMPRESS_BINARY) - $(STRIP) $(COMPRESS_BINARY) - $(STACK) -S $(GENTOS_STACKSIZE) $(COMPRESS_BINARY) +$(BOOTCF): $(BOOT_OBJSCF) + $(LD) --oformat srec -Map boot_cf.map --cref -Ttext $(FLASH_BOOT) -s -o $(BOOTCF) $(BOOT_OBJSCF) -$(GENTOS_BINARY): $(GENTOS_OBJS) - $(CC) $(GENTOS_OBJS) -o $(GENTOS_BINARY) - $(STRIP) $(GENTOS_BINARY) - $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARY) +$(BOOTCF2): $(BOOT_OBJSCF2) + $(LD) --oformat srec -Map boot_cf2.map --cref -Ttext $(FLASH_BOOT) -s -o $(BOOTCF2) $(BOOT_OBJSCF2) -$(GENTOS_BINARY_1GB): $(GENTOS_OBJS_1GB) - $(CC) $(GENTOS_OBJS_1GB) -o $(GENTOS_BINARY_1GB) - $(STRIP) $(GENTOS_BINARY_1GB) - $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARY_1GB) +$(BOOTCF3): $(BOOT_OBJSCF3) + $(LD) --oformat srec -Map boot_cf3.map --cref -Ttext $(FLASH_BOOT) -s -o $(BOOTCF3) $(BOOT_OBJSCF3) -$(GENTOS_BINARYCF): $(GENTOS_OBJSCF) - $(CC) $(GENTOS_OBJSCF) -o $(GENTOS_BINARYCF) - $(STRIP) $(GENTOS_BINARYCF) - $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARYCF) +$(DRIVERS): + make ctpci -C drivers -$(GENTOS_BINARYCF2): $(GENTOS_OBJSCF2) - $(CC) $(GENTOS_OBJSCF2) -o $(GENTOS_BINARYCF2) - $(STRIP) $(GENTOS_BINARYCF2) - $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARYCF2) - -$(GENTOS_BINARYCF3): $(GENTOS_OBJSCF3) - $(CC) $(GENTOS_OBJSCF3) -o $(GENTOS_BINARYCF3) - $(STRIP) $(GENTOS_BINARYCF3) - $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARYCF3) +$(CF68KLIB): $(OBJDIRCF)/tos/cf68klib.o + $(LD) --oformat srec -Ttext $(FLASH_CF68KLIB) -s -o $(CF68KLIB) $(OBJDIRCF)/tos/cf68klib.o -$(TOS): $(GENTOS_BINARY) $(NFDISTFILES) - ./$(GENTOS_BINARY) $(NFDISTFILES) $(TOS) +$(CF68KLIB2): $(OBJDIRCF2)/tos/cf68klib.o + $(LD) --oformat srec -Ttext $(FLASH_CF68KLIB2) -s -o $(CF68KLIB2) $(OBJDIRCF2)/tos/cf68klib.o -$(TOSPCI): $(GENTOS_BINARY) $(NFDISTFILES) ./pci/$(PCI) - ./$(GENTOS_BINARY) $(NFDISTFILES) ./pci/$(PCI) $(TOSPCI) +$(CF68KLIB3): $(OBJDIRCF3)/tos/cf68klib.o + $(LD) --oformat srec -Ttext $(FLASH_CF68KLIB3) -s -o $(CF68KLIB3) $(OBJDIRCF3)/tos/cf68klib.o -$(TOSPCI_1GB): $(GENTOS_BINARY_1GB) $(NFDISTFILES) ./pci/$(PCI) - ./$(GENTOS_BINARY) $(NFDISTFILES) ./pci/$(PCI) $(TOSPCI_1GB) - -$(PCI): - make ctpci -C pci +$(AESCF): $(AES_OBJSCF) $(DESK_OBJSCF) + $(LD) --oformat srec -Ttext $(FLASH_AES) -Tdata $(FLASH2_AES) -Tbss $(RAM_AES) -Map aescf.map --cref -o $(AESCF) $(AES_OBJSCF) -lgem -$(CF68KLIB): $(OBJDIRCF)/tos/cf68klib.o - $(LD) -oformat binary -Ttext $(FLASH_CF68KLIB) -s -o $(CF68KLIB) $(OBJDIRCF)/tos/cf68klib.o +$(DIAG): $(DIR)/$(ATARIDIAG) + objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_DIAG) $(DIR)/$(ATARIDIAG) $(DIAG) -$(CF68KLIB2): $(OBJDIRCF2)/tos/cf68klib.o - $(LD) -oformat binary -Ttext $(FLASH_CF68KLIB2) -s -o $(CF68KLIB2) $(OBJDIRCF2)/tos/cf68klib.o +$(TOS): $(GENTOS_BINARY) $(FILES) + ./$(GENTOS_BINARY) $(FILES) $(TOS) -$(CF68KLIB3): $(OBJDIRCF3)/tos/cf68klib.o - $(LD) -oformat binary -Ttext $(FLASH_CF68KLIB3) -s -o $(CF68KLIB3) $(OBJDIRCF3)/tos/cf68klib.o +$(TOSPCI): $(GENTOS_BINARY) $(FILES) ./drivers/$(DRIVERS) + ./$(GENTOS_BINARY) $(FILES) ./drivers/$(DRIVERS) $(TOSPCI) -$(TOSCF): $(GENTOS_BINARYCF) $(NFDISTFILESCF) ./pci/$(PCICF) - ./$(GENTOS_BINARYCF) $(NFDISTFILESCF) ./pci/$(PCICF) $(TOSCF) +$(TOSCF): $(GENTOS_BINARYCF) $(FILESCF) ./drivers/$(DRIVERSCF) + ./$(GENTOS_BINARYCF) $(FILESCF) ./drivers/$(DRIVERSCF) $(TOSCF) -$(TOSCF2): $(GENTOS_BINARYCF2) $(NFDISTFILESCF2) ./pci/$(PCICF2) - ./$(GENTOS_BINARYCF2) $(NFDISTFILESCF2) ./pci/$(PCICF2) $(TOSCF2) +$(TOSCF2): $(GENTOS_BINARYCF2) $(FILESCF2) ./drivers/$(DRIVERSCF2) + ./$(GENTOS_BINARYCF2) $(FILESCF2) ./drivers/$(DRIVERSCF2) $(TOSCF2) -$(TOSCF3): $(GENTOS_BINARYCF3) $(NFDISTFILESCF3) ./pci/$(PCICF3) - ./$(GENTOS_BINARYCF3) $(NFDISTFILESCF3) ./pci/$(PCICF3) $(TOSCF3) +$(TOSCF3): $(GENTOS_BINARYCF3) $(FILESCF3) ./drivers/$(DRIVERSCF3) + ./$(GENTOS_BINARYCF3) $(FILESCF3) ./drivers/$(DRIVERSCF3) $(TOSCF3) $(TOSCFHEX): $(TOSCF) objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_TOS_FIRE_ENGINE) $(TOSCF) $(TOSCFHEX) + cp $(TOSCFHEX) /home/firetos.hex $(TOSCFHEX2): $(TOSCF2) objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_TOS_M54455EVB) $(TOSCF2) $(TOSCFHEX2) + cp $(TOSCFHEX2) /home/firetos.hex $(TOSCFHEX3): $(TOSCF3) - objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_TOS_COLDARI) $(TOSCF3) $(TOSCFHEX3) - -$(PCICF): - make m5484lite -C pci - -$(PCICF2): - make m54455evb -C pci + objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_TOS_FIREBEE) $(TOSCF3) $(TOSCFHEX3) + objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_BOOT_TOS_FIREBEE) $(TOSCF3) $(TOSCFHEX3B) +# FIREBEE_COD added, if INIT_FPGA_FROM_RAM defined inside boot2.S +# objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_COD_FIREBEE) $(FIREBEE_COD) $(FPGACF3) +# @grep -E -v S7 $(TOSCFHEX3) > temp.hex +# @grep -E S3 $(FPGACF3) > temp2.hex +# @echo "S705E0400000DA" > temp3.hex +# @cat temp.hex temp2.hex temp3.hex > /home/firetos.hex +# @rm temp.hex temp2.hex temp3.hex + cp $(TOSCFHEX3) /home/firetos.hex + +$(DRIVERSCF): + make m5484lite -C drivers + +$(DRIVERSCF2): + make m54455evb -C drivers -$(PCICF3): - make coldari -C pci +$(DRIVERSCF3): + make firebee -C drivers version.h: @date -u +%e,%_m,%Y,%k,%_M > date.tmp @@ -422,6 +460,26 @@ version.h: @rm date.tmp @touch -m $(SRCDIR)/tos/version.S +$(GENTOS_BINARY): $(OBJDIR)/gentos.o $(OBJDIR)/srec.o + $(CC) $(OBJDIR)/gentos.o $(OBJDIR)/srec.o -o $(GENTOS_BINARY) + $(STRIP) $(GENTOS_BINARY) + $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARY) + +$(GENTOS_BINARYCF): $(OBJDIRCF)/gentos.o $(OBJDIRCF)/srec.o + $(CC) $(OBJDIRCF)/gentos.o $(OBJDIRCF)/srec.o -o $(GENTOS_BINARYCF) + $(STRIP) $(GENTOS_BINARYCF) + $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARYCF) + +$(GENTOS_BINARYCF2): $(OBJDIRCF2)/gentos.o $(OBJDIRCF)/srec.o + $(CC) $(OBJDIRCF2)/gentos.o $(OBJDIRCF)/srec.o -o $(GENTOS_BINARYCF2) + $(STRIP) $(GENTOS_BINARYCF2) + $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARYCF2) + +$(GENTOS_BINARYCF3): $(OBJDIRCF3)/gentos.o $(OBJDIRCF)/srec.o + $(CC) $(OBJDIRCF3)/gentos.o $(OBJDIRCF)/srec.o -o $(GENTOS_BINARYCF3) + $(STRIP) $(GENTOS_BINARYCF3) + $(STACK) -S $(GENTOS_STACKSIZE) $(GENTOS_BINARYCF3) + define CREATEOBJDIRS @for d in $(OBJDIR) $(SUBOBJDIRS); do \ if [ ! -d $$d ] ; then \ @@ -466,10 +524,6 @@ $(OBJDIR)/tos/xbios2.o: $(SRCDIR)/tos/xbios2.S $(SRCDIR)/tos/pci_bios.S $(CREATEOBJDIRS) $(CC) $(INCLUDE) $(CFLAGS_TOS) -c $< -o $@ -$(OBJDIR)/tos/xbios2_1gb.o: $(SRCDIR)/tos/xbios2.S $(SRCDIR)/tos/pci_bios.S - $(CREATEOBJDIRS) - $(CC) $(INCLUDE) $(CFLAGS_TOS) -DCTPCI_1GB -c $< -o $@ - $(OBJDIRCF)/tos/xbios2.o: $(SRCDIR)/tos/xbios2.S $(SRCDIR)/tos/pci_bios.S $(CREATEOBJDIRSCF) $(CC) $(INCLUDE) $(CFLAGSCF_TOS) -c $< -o $@ @@ -546,6 +600,22 @@ $(OBJDIRCF3)/tos/%.o: $(SRCDIR)/tos/%.S $(CREATEOBJDIRSCF3) $(CC) $(INCLUDE) $(CFLAGSCF3_TOS) -c $< -o $@ +$(OBJDIR)/tos/patches/%.o: $(SRCDIR)/tos/patches/%.S + $(CREATEOBJDIRS) + $(CC) $(INCLUDE) $(CFLAGS_TOS) -c $< -o $@ + +$(OBJDIRCF)/tos/patches/%.o: $(SRCDIR)/tos/patches/%.S + $(CREATEOBJDIRSCF) + $(CC) $(INCLUDE) $(CFLAGSCF_TOS) -c $< -o $@ + +$(OBJDIRCF2)/tos/patches/%.o: $(SRCDIR)/tos/patches/%.S + $(CREATEOBJDIRSCF2) + $(CC) $(INCLUDE) $(CFLAGSCF2_TOS) -c $< -o $@ + +$(OBJDIRCF3)/tos/patches/%.o: $(SRCDIR)/tos/patches/%.S + $(CREATEOBJDIRSCF3) + $(CC) $(INCLUDE) $(CFLAGSCF3_TOS) -c $< -o $@ + $(OBJDIRCF)/tos/cf68klib.o: $(SRCDIR)/tos/cf68klib.S $(CREATEOBJDIRSCF) $(CC) $(INCLUDE) $(CFLAGSCF_TOS) -c $< -o $@ @@ -558,6 +628,22 @@ $(OBJDIRCF3)/tos/cf68klib.o: $(SRCDIR)/tos/cf68klib.S $(CREATEOBJDIRSCF3) $(CC) $(INCLUDE) $(CFLAGSCF3_TOS) -c $< -o $@ +$(OBJDIRCF)/aes/%.o: $(SRCDIR)/aes/%.c + $(CREATEOBJDIRSCF) + $(CC) $(INCLUDE) $(CFLAGSCF_TOS) -fno-builtin -Wno-multichar -c $< -o $@ + +$(OBJDIRCF)/aes/%o: $(SRCDIR)/aes/%.S + $(CREATEOBJDIRSCF) + $(CC) $(INCLUDE) $(CFLAGSCF_TOS) -fno-builtin -Wno-multichar -c $< -o $@ + +$(OBJDIRCF)/desk/%.o: $(SRCDIR)/desk/%.c + $(CREATEOBJDIRSCF) + $(CC) $(INCLUDE) $(CFLAGSCF_TOS) $(CFLAGSDESK) -fno-builtin -Wno-multichar -c $< -o $@ + +$(OBJDIRCF)/desk/%o: $(SRCDIR)/desk/%.S + $(CREATEOBJDIRSCF) + $(CC) $(INCLUDE) $(CFLAGSCF_TOS) $(CFLAGSDESK) -fno-builtin -Wno-multichar -c $< -o $@ + $(OBJDIR)/%.o: $(SRCDIR)/%.c $(CREATEOBJDIRS) $(CC) $(INCLUDE) $(CFLAGS) -c $< -o $@ diff --git a/flash.tos/binhex.c b/flash.tos/binhex.c deleted file mode 100644 index 94ab5fd..0000000 --- a/flash.tos/binhex.c +++ /dev/null @@ -1,95 +0,0 @@ -#include -#include -#include - -int binhex(const char *source, const char *destination, const char *name); - -int main(int argc, char **argv) -{ - if(argc!=4) - { - Cconws("Usage: binhex input.cod output.c name_tab\r\n"); - return(-1); - } - binhex(argv[1], argv[2], argv[3]); - return(0); -} - -int binhex(const char *source, const char *destination, const char *name) -{ - long i, j, s_len; - unsigned int s, d; - char b[256], l_name[100]; - _DTA dta; - unsigned int d_time, d_date; - Fsetdta(&dta); - if(Fsfirst(source, FA_RDONLY|FA_HIDDEN|FA_SYSTEM)) - return 1; - s_len= dta.dta_size; - d_time= dta.dta_time; - d_date= dta.dta_date; - if(!Fsfirst(destination, FA_RDONLY|FA_HIDDEN|FA_SYSTEM)) - { - if((dta.dta_date > d_date) || - ((dta.dta_date == d_date) && (dta.dta_time > d_time))) - return -1; /* file is already coverted */ - } - i=Fopen(source, 0); - if(i < 0) - return 2; - s=(unsigned int)i; - i=Fcreate(destination, 0); - if(i < 0) - { - Fclose(s); - return 3; - } - d=(unsigned int)i; - strupr(strncat(strcpy(l_name, "LEN_"), name, 99)); - sprintf(b, "/* File %s encoded */\r\n\r\n" - "#define %s\t%luL\r\n\r\n" - "unsigned long len_%s=%s;\r\n" - "unsigned char %s[%s%s]= {\r\n", - source, l_name, s_len, name, l_name, name, l_name, (s_len%2) ? "+1" : ""); - if(Fwrite(d, strlen(b), b) != strlen(b)) - { - Fclose(s); - Fclose(d); - return 4; - } - for(j= 0; j<=(s_len / 16); j++) - { - unsigned char b1[16]; - char format[]= "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x," - "0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,0x%02x,\r\n"; - long x, y; - if((x= Fread(s, 16, b1)) < 0) - { - Fclose(s); - Fclose(d); - return 5; - } - if(j == (s_len / 16)) - { - char *p; - format[0]= '\0'; - for(y= 0; y -#include -#include -#include "lz.h" - -int main(int argc, char **argv) -{ - char *sbuf,*dbuf; - int *work; - long length, clength; - short handle; - if(argc!=3) - { - printf("Usage: compress input output\r\n"); - return(-1); - } - handle=Fopen(argv[1], 0); - if(handle<0) - return(-1); - length = Fseek(0, handle, 2); - if(length <= 0) - { - Fclose(handle); - return(-1); - } - Fseek(0, handle, 0); - sbuf = (char *)Mxalloc(length, 2); - work = (int *)Mxalloc(sizeof(int)*(length+65536), 2); - dbuf = (char *)Mxalloc(length*11/10, 2); - if(sbuf == NULL || work == NULL || dbuf == NULL) - goto error; - if(Fread(handle, length, sbuf) != length) - goto error; - Fclose(handle); - handle=Fcreate(argv[2], 0); - if(handle < 0) - { -error: - if(sbuf) - Mfree(sbuf); - if(work) - Mfree(work); - if(dbuf) - Mfree(dbuf); - if(handle >= 0) - Fclose(handle); - return(-1); - } - *(long *)dbuf = (long)length; - clength = (long)LZ_CompressFast(sbuf, dbuf+4, (int)length, work) + 4; - printf("compress %s (%d) to %s (%d)\r\n", argv[1], (int)length, argv[2], (int)clength); - if(Fwrite(handle, clength, dbuf) != clength) - goto error; - Fclose(handle); - Mfree(sbuf); - Mfree(work); - Mfree(dbuf); - return(0); -} diff --git a/flash.tos/doc/coldfire.readme b/flash.tos/doc/coldfire.readme index 1ba5dd5..d63db60 100644 --- a/flash.tos/doc/coldfire.readme +++ b/flash.tos/doc/coldfire.readme @@ -319,6 +319,29 @@ typedef struct socket_cookie 'STiK' cookie is also implemented with GlueSTiK. +DMACF V4e cookie 'DMAC' (for external drivers using DMA like Ethernet): +----------------------------------------------------------------------- +typedef struct dma_cookie +{ + long version; /* 0x0101 for example */ + long magic; /* 'DMAC' */ + int (*dma_set_initiator)(int initiator); + unsigned long (*dma_get_initiator)(int requestor); + void (*dma_free_initiator)(int requestor); + int (*dma_set_channel)(int requestor, void (*handler)(void)); + int (*dma_get_channel)(int requestor); + void (*dma_free_channel)(int requestor); + void (*dma_clear_channel)(int channel); + int (*MCD_startDma)(int channel, s8 *srcAddr, s16 srcIncr, s8 *destAddr, s16 destIncr, u32 dmaSize, u32 xferSize, u32 initiator, int priority, u32 flags, u32 funcDesc); + int (*MCD_dmaStatus)(int channel); + int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); + int (*MCD_killDma)(int channel); + int (*MCD_continDma)(int channel); + int (*MCD_pauseDma)(int channel); + int (*MCD_resumeDma)(int channel); + int (*MCD_csumQuery)(int channel, u32 *csum); +} DMACF_COOKIE; + XBIOS notes =========== @@ -424,9 +447,9 @@ FIREBEE Notes (M5484LITE/M5485EVB comparison) * B7: (1) SW6 DOWN, (0) SW6 UP * B6: (1) SW5 DOWN, (0) SW5 UP * B0: (1) rescue TOS started from 0xE0000000 (replace BAS or dBUG) - SW6 up is the normal usage - SW6 down allows to TOS to start FTP (build option), HTTP, TFTP servers and create a Ram-Disk - actually in B (this feature is also possible with dBUG at 0xE0000000). + SW6 up is the normal usage (without Ethernet features and USB) + SW6 down allows the TOS to start FTP (build option), HTTP, TFTP servers and create a Ram-Disk + actually in B (this feature is also possible with dBUG at 0xE0000000) install USB drivers. SW5 up is the normal usage for start the TOS at 0xE0400000 (same usage inside BAS or dBUG at 0xE0000000) and a boot menu has 2 choices TOS or EMUTOS (TOS by default). SW5 down is the rescue mode, TOS at 0xE0000000 continue to run and a boot menu displays 3 choices: @@ -608,7 +631,7 @@ Coldfire notes FFFFE000 - FFFFFFFF : SRAM 8192 bytes for fix bus errors with emulated instructions remapped with MMU from 80007000 - FIREBEE MMU Mapping: - 00000000 - 00CF0000 : STRAM 13 MB (cache in writethrough) + 00000000 - 00CFFFFF : STRAM 13 MB (cache in writethrough) 00D00000 - 00DFFFFF : Mirror FPGA 1MB VIDEO RAM (cache in writethrough) 00E00000 - 00EFFFFF : TOS404 1 MB (write protected) 00F00000 - 00F01FFF : Mirror FPGA - ATARI IDE (8K) diff --git a/flash.tos/doc/history.txt b/flash.tos/doc/history.txt index c58d885..77a3539 100644 --- a/flash.tos/doc/history.txt +++ b/flash.tos/doc/history.txt @@ -311,7 +311,7 @@ detected ??? (boot2.S) 2011-07-17 2.01 --------------- -- Try to fix CT60 flash boot problems by reading until 4 x times the TOS in +- Try to fix CT60 flash boot problems by reading until 4 times the TOS in flash if the CRC is bad before apply the patches in SDRAM (boot2.S). - If the Supervidel is found, the TOS use the default Bconout routine who use the blitter (conout.S). @@ -323,7 +323,7 @@ in STRAM and mutiple retry/verifications until 5 times (ide_scsi.S). - On the Fireebee target, rewrited some parts of the TOS in native code like the PSG sound VBL interrupt routine and IKBD interrupt routine. -- On the Fireebee target, enabled Bconmap (xbios.S) with device 6 is MFP, +- On the Firebee target, enabled Bconmap (xbios.S) with device 6 is MFP, 7 is PSC0 who replace the SCC (default like a FALCON), this is the baud table for Rsconf (MFP and PSC0): Index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @@ -358,4 +358,43 @@ programs (cf68klib.S): * fabs/fadd/fcmp/fdiv/fint/fintrz/fmove/fmul/fneg/fsqrt/fsub/ftst #. * cinva/cpushl/cpusha. +2012-06-23 2.02 +--------------- +- On M5484LITE/FIREBEE enabled XLB PCI interrupt (boot.S). +- Inside the CF68KLIB, removed fix_predecrement/fix_postincrement when +address error arrives with MOVE.B/W/L (An)+, and MOVE.B/W/L +-(An), with invalid addessing modes (cf68klib.S). +- On the Firebee target (boot.S), added SCSI/IDE device unselection using +CT60_BOOT_ORDER parameter unused bits (B27-B24 for IDE and B23-B16 for +SCSI). +- On the Firebee target added fix for Device Errata 26, now USB MASS +STORAGE works fine (PCI <=> Flexbus). +- Added bus support inside the PCI BIOS (pci_bios.S), limits now are: + * 4 bus. + * 32 devices by bus. + * 4 functions by devices. +- Fixed invalid IDE call possible (wrong device) inside boot routine +(boot2.S) after SCSI drives detection (for example with ALT key I got +crash). This bug is very old, but since the CTPCI, the IDE routine is +ready for a 2nd port and this 2nd port is not implemented in the +current hardware so t's possible to get a crash (invalid access to a +2nd CTPCI IDE port). +- On all targets, added ATAPI devices to SCSIDRV (ide_scsi.S). +FIREBEE and FALCON with CT60/CTPCI has IDE and IDE2 (IDE not +compatible). SCSI cookie added before hard disk driver boot. +- Added LZMA decoder for a better compression of PCI drivers +(LzmaDecode.c). +- On CTPCI fixed PEND register bits test inverted, and finnally +revoved this test who can caused loop inside interrupt. +- Added boot order entry for CTPCI IDE (boot.S). +- Try to fix CT60 flash boot problems by reading until 16 times the TOS in +flash if the CRC is bad before apply the patches in SDRAM (boot2.S). +- Changed boot order for 4 IDE devices with a CTPCI (boot2.S). +- Rewrited conout routines in C for Videl or graphic card (planes or +without planes, with or without accel routines from drivers part. +TOS404 VT52 routines table at 0xE13268 used, theses routines use the A4 +register as Line A pointer (bios.S, bios2.S, and conout.c). Not used +on Coldfire targets, there are a crash when screen changed. +- Added 5 retry loops to boot keyboard test, sometimes Eiffel +characters are lost on the FIREBEE (boot2.S). diff --git a/flash.tos/doc/video_xbios.txt b/flash.tos/doc/video_xbios.txt index 8bfafab..1bd9220 100644 --- a/flash.tos/doc/video_xbios.txt +++ b/flash.tos/doc/video_xbios.txt @@ -383,6 +383,8 @@ typedef struct screeninfo long pagemem; /* needed memory for one page */ long max_x; /* max. possible width */ long max_y; /* max. possible heigth */ + long refresh; /* refresh in Hz */ + long pixclock; /* pixel clock in pS */ } SCREENINFO; #define BLK_ERR 0 diff --git a/flash.tos/drivers/Makefile b/flash.tos/drivers/Makefile index 80aaf87..626ae7e 100644 --- a/flash.tos/drivers/Makefile +++ b/flash.tos/drivers/Makefile @@ -1,13 +1,17 @@ ### 68060 - GCC 3.3 ### -CC = gcc +#CC = gcc +#CC = /usr/local/bin/gcc +CC_TOOLS = /usr/local/bin/gcc +### 68060 - GCC 4.4 ### +CC = /home/usr/local/bin/gcc ### Coldfire - GCC 4.4 ### -CCF = /home/usr/local/bin/m68k-atari-mint-gcc +CCF = /home/usr/local/bin/gcc LD = ld STRIP = strip STACK = stack rm = rm -VERSION = 0x0101 +VERSION = 0x0102 ATICOD = ../nonfree/ativcm20.cod @@ -30,7 +34,10 @@ SUBOBJDIRS= \ $(OBJDIR)/fvdi/common \ $(OBJDIR)/fvdi/1_plane \ $(OBJDIR)/dma_utils \ - $(OBJDIR)/usb + $(OBJDIR)/usb \ + $(OBJDIR)/cd \ + $(OBJDIR)/lwip \ + $(OBJDIR)/freertos SUBOBJDIRSCF= \ $(OBJDIR)/tools \ @@ -44,7 +51,6 @@ SUBOBJDIRSCF= \ $(OBJDIRCF)/fvdi/common \ $(OBJDIRCF)/mcdapi \ $(OBJDIRCF)/dma_utils \ - $(OBJDIRCF)/net \ $(OBJDIRCF)/lwip \ $(OBJDIRCF)/usb_dev \ $(OBJDIRCF)/usb \ @@ -63,7 +69,6 @@ SUBOBJDIRSCF2= \ $(OBJDIRCF2)/fvdi \ $(OBJDIRCF2)/fvdi/common \ $(OBJDIRCF2)/dma_utils \ - $(OBJDIRCF2)/net \ $(OBJDIRCF2)/lwip \ $(OBJDIRCF2)/usb \ $(OBJDIRCF2)/bdos \ @@ -80,9 +85,9 @@ SUBOBJDIRSCF3= \ $(OBJDIRCF3)/fvdi/common \ $(OBJDIRCF3)/mcdapi \ $(OBJDIRCF3)/dma_utils \ - $(OBJDIRCF3)/net \ $(OBJDIRCF3)/lwip \ $(OBJDIRCF3)/usb \ + $(OBJDIRCF3)/cd \ $(OBJDIRCF3)/ac97 \ $(OBJDIRCF3)/bdos \ $(OBJDIRCF3)/freertos @@ -90,11 +95,15 @@ SUBOBJDIRSCF3= \ INCLUDE = -I$(INCDIR) INCLUDEFVDI = -I$(INCDIRFVDI) INCLUDEUSB = -I$(INCDIRUSB) -CFLAGS = -m68060 -Os -fno-builtin -fomit-frame-pointer -Wall -Wno-multichar -g +### 68060 - GCC 3.3 ### +#CFLAGS = -m68060 -Os -fno-builtin -fomit-frame-pointer -Wall -Wno-multichar -g +CFLAGS_TOOLS = -m68060 -Os -fno-builtin -fomit-frame-pointer -Wall -Wno-multichar -g +### 68060 - GCC 4.4 ### +CFLAGS = -m68060 -Os -fno-builtin -fomit-frame-pointer -fno-strict-aliasing -fno-inline-small-functions -Wall -Wno-multichar ### Coldfire - GCC 3.3 ### #CFLAGSCF = -m5200 -Os -fno-builtin -fomit-frame-pointer -Wall -Wno-multichar -g -Wa,-m5200 -DCOLDFIRE ### Coldfire - GCC 4.4 ### -CFLAGSCF = -mcfv4e -Os -fno-builtin -fomit-frame-pointer -fno-strict-aliasing -fno-inline-small-functions -Wall -Wno-multichar -g -DCOLDFIRE +CFLAGSCF = -mcfv4e -Os -fno-builtin -fomit-frame-pointer -fno-strict-aliasing -fno-inline-small-functions -Wall -Wno-multichar -DCOLDFIRE CFLAGSCF2 = $(CFLAGSCF) -DMCF5445X CFLAGSCF3 = $(CFLAGSCF) -DMCF547X LDFLAGS = -nostdlib -s @@ -127,7 +136,6 @@ OBJSDRIVERFVDI= \ $(OBJDIR)/fvdi/common/falc_pal.o \ $(OBJDIR)/fvdi/1_plane/1_line.o \ $(OBJDIR)/fvdi/1_plane/1_fill.o \ - $(OBJDIR)/timer.o \ $(OBJDIR)/gcc.o OBJSDRIVERFVDICF= \ @@ -207,50 +215,38 @@ OBJSDRIVERFVDICF3= \ $(OBJDIRCF)/fvdi/common/falc_pal.o \ $(OBJDIRCF)/gcc.o -OBJSNETCF= \ - $(OBJDIRCF)/net/tftp.o \ - $(OBJDIRCF)/net/ip.o \ - $(OBJDIRCF)/net/arp.o \ - $(OBJDIRCF)/net/icmp.o \ - $(OBJDIRCF)/net/udp.o \ - $(OBJDIRCF)/net/net_timer.o \ - $(OBJDIRCF)/net/queue.o \ - $(OBJDIRCF)/net/nbuf.o \ - $(OBJDIRCF)/net/nif.o \ - $(OBJDIRCF)/net/fec.o \ - $(OBJDIRCF)/net/fecbd.o \ - $(OBJDIRCF)/net/bcm5222.o \ - $(OBJDIRCF)/net/init.o - -OBJSNETCF2= \ - $(OBJDIRCF2)/net/tftp.o \ - $(OBJDIRCF2)/net/ip.o \ - $(OBJDIRCF2)/net/arp.o \ - $(OBJDIRCF2)/net/icmp.o \ - $(OBJDIRCF2)/net/udp.o \ - $(OBJDIRCF2)/net/net_timer.o \ - $(OBJDIRCF2)/net/queue.o \ - $(OBJDIRCF2)/net/nbuf.o \ - $(OBJDIRCF2)/net/nif.o \ - $(OBJDIRCF2)/net/fec.o \ - $(OBJDIRCF2)/net/fecbd.o \ - $(OBJDIRCF2)/net/init.o - -OBJSNETCF3= \ - $(OBJDIRCF)/net/tftp.o \ - $(OBJDIRCF)/net/ip.o \ - $(OBJDIRCF)/net/arp.o \ - $(OBJDIRCF)/net/icmp.o \ - $(OBJDIRCF)/net/udp.o \ - $(OBJDIRCF)/net/net_timer.o \ - $(OBJDIRCF)/net/queue.o \ - $(OBJDIRCF)/net/nbuf.o \ - $(OBJDIRCF)/net/nif.o \ - $(OBJDIRCF3)/net/fec.o \ - $(OBJDIRCF3)/net/fecbd.o \ - $(OBJDIRCF3)/net/am79c874.o \ - $(OBJDIRCF3)/net/init.o - +OBJSLWIP= \ + $(OBJDIR)/lwip/tcp_out.o \ + $(OBJDIR)/lwip/inet.o \ + $(OBJDIR)/lwip/chksum.o \ + $(OBJDIR)/lwip/mem.o \ + $(OBJDIR)/lwip/memp.o \ + $(OBJDIR)/lwip/netif.o \ + $(OBJDIR)/lwip/pbuf.o \ + $(OBJDIR)/lwip/raw.o \ + $(OBJDIR)/lwip/stats.o \ + $(OBJDIR)/lwip/sys.o \ + $(OBJDIR)/lwip/tcp.o \ + $(OBJDIR)/lwip/tcp_in.o \ + $(OBJDIR)/lwip/udp.o \ + $(OBJDIR)/lwip/ip.o \ + $(OBJDIR)/lwip/ip_addr.o \ + $(OBJDIR)/lwip/icmp.o \ + $(OBJDIR)/lwip/ip_frag.o \ + $(OBJDIR)/lwip/tcpip.o \ + $(OBJDIR)/lwip/api_msg.o \ + $(OBJDIR)/lwip/err.o \ + $(OBJDIR)/lwip/api_lib.o \ + $(OBJDIR)/lwip/loopif.o \ + $(OBJDIR)/lwip/sockets.o \ + $(OBJDIR)/lwip/etharp.o \ + $(OBJDIR)/lwip/resolv.o \ + $(OBJDIR)/lwip/sys_arch.o \ + $(OBJDIR)/lwip/rtl8139.o \ + $(OBJDIR)/lwip/gs_func.o \ + $(OBJDIR)/lwip/gs_mem.o \ + $(OBJDIR)/lwip/gs_stik.o \ + $(OBJDIR)/lwip/init.o OBJSLWIPCF= \ $(OBJDIRCF)/lwip/tcp_out.o \ @@ -433,6 +429,18 @@ OBJSUSBCF3= \ $(OBJDIRCF3)/usb/usb_mem.o \ $(OBJDIRCF)/usb/cmd_usb.o +OBJSSCSI= \ + $(OBJDIR)/cd/cd_scsi.o \ + $(OBJDIR)/cd/cd_disk.o \ + $(OBJDIR)/cd/cd_dos.o \ + $(OBJDIR)/cd/cd_iso.o + +OBJSSCSICF3= \ + $(OBJDIRCF3)/cd/cd_scsi.o \ + $(OBJDIRCF3)/cd/cd_disk.o \ + $(OBJDIRCF3)/cd/cd_dos.o \ + $(OBJDIRCF3)/cd/cd_iso.o + OBJSAC97CF= \ $(OBJDIRCF)/ac97/mcf548x_ac97.o @@ -502,6 +510,14 @@ OBJSBDOSCF3= \ $(OBJDIRCF)/bdos/rwa.o \ $(OBJDIRCF)/bdos/setjmp.o +OBJSRTOS= \ + $(OBJDIR)/freertos/tasks.o \ + $(OBJDIR)/freertos/queue.o \ + $(OBJDIR)/freertos/list.o \ + $(OBJDIR)/freertos/heap_2.o \ + $(OBJDIR)/freertos/port.o + + OBJSRTOSCF= \ $(OBJDIRCF)/freertos/tasks.o \ $(OBJDIRCF)/freertos/queue.o \ @@ -533,9 +549,11 @@ OBJS= \ $(OBJDIR)/gemform.o \ $(OBJDIR)/xbios.o \ $(OBJDIR)/detxbios.o \ + $(OBJDIR)/detgemdos.o \ $(OBJDIR)/detlinea.o \ $(OBJDIR)/detvdi.o \ $(OBJDIR)/work.o \ + $(OBJDIR)/timer_rom.o \ $(OBJDIR)/debug.o \ $(OBJDIR)/m68k_disasm.o \ $(OBJDIR)/emulator/biosemu.o \ @@ -568,7 +586,9 @@ OBJS= \ $(OBJDIR)/dma_utils/dma_utils.o \ $(OBJDIR)/stdlib.o \ $(OBJDIR)/printk.o \ + $(OBJDIR)/malloc.o \ $(OBJSUSB) \ + $(OBJSSCSI) \ $(OBJSDRIVERFVDI) OBJSCF= \ @@ -668,6 +688,7 @@ OBJSCF3= \ $(OBJDIRCF)/gemform.o \ $(OBJDIRCF3)/xbios.o \ $(OBJDIRCF3)/detxbios.o \ + $(OBJDIRCF3)/detgemdos.o \ $(OBJDIRCF)/detlinea.o \ $(OBJDIRCF)/detvdi.o \ $(OBJDIRCF)/work.o \ @@ -704,7 +725,9 @@ OBJSCF3= \ $(OBJDIRCF)/radeon/radeon_theatre.o \ $(OBJDIRCF)/radeon/radeon_vid.o \ $(OBJDIRCF3)/get.o \ + $(OBJDIRCF3)/malloc.o \ $(OBJSUSBCF3) \ + $(OBJSSCSICF3) \ $(OBJSDRIVERFVDICF3) \ $(OBJSNETCF3) @@ -739,37 +762,37 @@ clean: rm -rf $(OBJDIR) $(OBJDIRCF) $(OBJDIRCF2) $(OBJDIRCF3) rm -f $(BINHEX_BINARY) $(COMPRESS_BINARY) $(HEX) $(HEXCF) $(HEXCF2) $(HEXCF3) $(HEXFIREBEE) drivers.map drivers_cf.map drivers_cf2.map drivers_cf3.map $(DRIVERFVDI) $(DRIVERFVDICF) $(DRIVERFVDICF2) $(DRIVERFVDICF3) -$(HEX): $(OBJS) +$(HEX): $(OBJS) $(OBJSRTOS) $(OBJSLWIP) $(LD) --oformat srec -Map drivers.map --cref -T drivers.lk \ --entry Start -o $(HEX) $(OBJS) - $(COMPRESS_BINARY) $(HEX) temp.bin + ./$(COMPRESS_BINARY) $(HEX) temp.bin objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_DRIVERS) temp.bin $(HEX) rm temp.bin $(HEXCF): $(OBJDIRCF)/header.o $(OBJSCF) $(OBJSBDOSCF) $(OBJSRTOSCF) $(OBJSLWIPCF) $(OBJSAC97CF) $(LD) --oformat srec -Map drivers_cf.map --cref -T drivers_cf.lk \ --entry Start -o $(HEXCF) $(OBJSCF) - $(COMPRESS_BINARY) $(HEXCF) temp.bin + ./$(COMPRESS_BINARY) $(HEXCF) temp.bin objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_DRIVERS_CF) temp.bin $(HEXCF) rm temp.bin $(HEXCF2): $(OBJDIRCF)/header.o $(OBJSCF2) $(OBJSBDOSCF2) $(OBJSRTOSCF2) $(OBJSLWIPCF2) $(LD) --oformat srec -Map drivers_cf2.map --cref -T drivers_cf2.lk \ --entry Start -o $(HEXCF2) $(OBJSCF2) - $(COMPRESS_BINARY) $(HEXCF2) temp.bin + ./$(COMPRESS_BINARY) $(HEXCF2) temp.bin objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_DRIVERS_CF) temp.bin $(HEXCF2) rm temp.bin $(HEXCF3): $(OBJDIRCF)/header.o $(OBJSCF3) $(OBJSBDOSCF3) $(OBJSRTOSCF3) $(OBJSLWIPCF3) $(OBJSAC97CF3) $(LD) --oformat srec -Map drivers_cf3.map --cref -T drivers_cf3.lk \ --entry Start -o $(HEXCF3) $(OBJSCF3) - $(COMPRESS_BINARY) $(HEXCF3) temp.bin + ./$(COMPRESS_BINARY) $(HEXCF3) temp.bin objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_DRIVERS_FIREBEE) temp.bin $(HEXFIREBEE) objcopy --verbose -I binary -O srec --adjust-vma=$(FLASH_DRIVERS_CF) temp.bin $(HEXCF3) rm temp.bin -$(DRIVERFVDI): $(OBJDIR)/video/spec.o $(OBJDIR)/video/accel.o $(OBJDIR)/radeon/radeon_base.o $(OBJSDRIVERFVDI) - $(LD) $(LDFLAGS) -o $(DRIVERFVDI) $(OBJDIR)/video/spec.o $(OBJDIR)/video/accel.o $(OBJDIR)/radeon/radeon_base.o $(OBJSDRIVERFVDI) +$(DRIVERFVDI): $(OBJDIR)/video/spec.o $(OBJDIR)/video/accel.o $(OBJDIR)/radeon/radeon_base.o $(OBJDIR)/timer.o $(OBJSDRIVERFVDI) + $(LD) $(LDFLAGS) -o $(DRIVERFVDI) $(OBJDIR)/video/spec.o $(OBJDIR)/video/accel.o $(OBJDIR)/radeon/radeon_base.o $(OBJDIR)/timer.o $(OBJSDRIVERFVDI) $(STRIP) $(DRIVERFVDI) $(DRIVERFVDICF): $(OBJDIRCF)/video/spec.o $(OBJDIRCF)/video/accel.o $(OBJDIRCF)/radeon/radeon_base.o $(OBJDIRCF)/fvdi/common/c_common.o $(OBJDIRCF)/timer.o $(OBJSDRIVERFVDICF) @@ -795,12 +818,12 @@ version.h: @touch -m $(SRCDIR)/header.S $(BINHEX_BINARY): $(OBJDIR)/tools/binhex.o - $(CC) $(OBJDIR)/tools/binhex.o -o $(BINHEX_BINARY) + $(CC_TOOLS) $(OBJDIR)/tools/binhex.o -o $(BINHEX_BINARY) $(STRIP) $(BINHEX_BINARY) $(STACK) -S $(STACKSIZE) $(BINHEX_BINARY) -$(COMPRESS_BINARY): $(OBJDIR)/tools/compress.o $(OBJDIR)/tools/lz.o $(OBJDIR)/tools/srec.o - $(CC) $(OBJDIR)/tools//compress.o $(OBJDIR)/tools/lz.o $(OBJDIR)/tools/srec.o -o $(COMPRESS_BINARY) +$(COMPRESS_BINARY): $(OBJDIR)/tools/compress.o $(OBJDIR)/tools/lz.o $(OBJDIR)/tools/LzmaEnc.o $(OBJDIR)/tools/LzFind.o $(OBJDIR)/tools/srec.o + $(CC_TOOLS) $(OBJDIR)/tools//compress.o $(OBJDIR)/tools/lz.o $(OBJDIR)/tools/LzmaEnc.o $(OBJDIR)/tools/LzFind.o $(OBJDIR)/tools/srec.o -o $(COMPRESS_BINARY) $(STRIP) $(COMPRESS_BINARY) $(STACK) -S $(STACKSIZE) $(COMPRESS_BINARY) @@ -836,6 +859,10 @@ define CREATEOBJDIRSCF3 done endef +$(OBJDIR)/tools/%.o: $(SRCDIR)/tools/%.c + $(CREATEOBJDIRS) + $(CC_TOOLS) $(INCLUDE) $(CFLAGS_TOOLS) -c $< -o $@ + $(OBJDIR)/radeon/%.o: $(SRCDIR)/radeon/%.c $(CREATEOBJDIRS) $(CC) $(INCLUDE) $(INCLUDEFVDI) $(CFLAGS) -c $< -o $@ @@ -1149,8 +1176,8 @@ $(OBJDIRCF3)/radeon/radeon_accel_rom.o: $(SRCDIR)/radeon/radeon_accel.c $(CCF) $(INCLUDE) $(INCLUDEFVDI) $(CFLAGSCF3) -DDRIVER_IN_ROM -c $< -o $@ $(OBJDIR)/radeon/radeon_theatre_dsp.o: $(ATICOD) - $(COMPRESS_BINARY) $(ATICOD) ./ati.bin - $(BINHEX_BINARY) ./ati.bin $(SRCDIR)/radeon/radeon_theatre_dsp.txt theatre_dsp + ./$(COMPRESS_BINARY) $(ATICOD) ./ati.bin + ./$(BINHEX_BINARY) ./ati.bin $(SRCDIR)/radeon/radeon_theatre_dsp.txt theatre_dsp @rm ati.bin @echo "#include \"config.h\"" > $(SRCDIR)/radeon/radeon_theatre_dsp.c @echo "#ifdef RADEON_THEATRE" >> $(SRCDIR)/radeon/radeon_theatre_dsp.c @@ -1204,11 +1231,15 @@ $(OBJDIRCF3)/fvdi/common/c_common_rom.o: $(SRCDIR)/fvdi/common/c_common.S $(CREATEOBJDIRSCF3) $(CCF) $(INCLUDE) $(INCLUDEFVDI) $(CFLAGSCF3) -DDRIVER_IN_ROM -c $< -o $@ +$(OBJDIR)/timer_rom.o: $(SRCDIR)/timer.c + $(CREATEOBJDIRS) + $(CC) $(INCLUDE) $(INCLUDEFVDI) $(CFLAGS) -DDRIVER_IN_ROM -c $< -o $@ + $(OBJDIRCF)/timer_rom.o: $(SRCDIR)/timer.c $(CREATEOBJDIRSCF) $(CCF) $(INCLUDE) $(INCLUDEFVDI) $(CFLAGSCF) -DDRIVER_IN_ROM -c $< -o $@ -$(OBJDIRCF2)/timer_rom.o: $(SRCDIR)timer.c +$(OBJDIRCF2)/timer_rom.o: $(SRCDIR)/timer.c $(CREATEOBJDIRSCF2) $(CCF) $(INCLUDE) $(INCLUDEFVDI) $(CFLAGSCF2) -DDRIVER_IN_ROM -c $< -o $@ diff --git a/flash.tos/drivers/ac97/bas.c b/flash.tos/drivers/ac97/bas.c new file mode 100644 index 0000000..402613d --- /dev/null +++ b/flash.tos/drivers/ac97/bas.c @@ -0,0 +1,93 @@ +void bas_init_ac97(void) +{ +// PSC2: AC97 ---------- + int i,zm,va=-1,vb=-1,vc=-1; + + MCF_PSC_TB0_32BIT = 'AC97'; + MCF_GPIO_PAR_PSC2 = MCF_GPIO_PAR_PSC2_PAR_RTS2_RTS // PSC2=TX,RX BCLK,CTS->AC'97 + | MCF_GPIO_PAR_PSC2_PAR_CTS2_BCLK + | MCF_GPIO_PAR_PSC2_PAR_TXD2 + | MCF_GPIO_PAR_PSC2_PAR_RXD2; + MCF_PSC2_MR = 0x0; + MCF_PSC2_MR = 0x0; + MCF_PSC2_IMR = 0x0300; + MCF_PSC2_SICR = 0x03; //AC97 + MCF_PSC2_RFCR = 0x0f000000; + MCF_PSC2_TFCR = 0x0f000000; + MCF_PSC2_RFAR = 0x00F0; + MCF_PSC2_TFAR = 0x00F0; + + for ( zm = 0; zm<100000; zm++) // wiederholen bis synchron + { + MCF_PSC2_CR = 0x20; + MCF_PSC2_CR = 0x30; + MCF_PSC2_CR = 0x40; + MCF_PSC2_CR = 0x05; +// MASTER VOLUME -0dB + MCF_PSC_TB2_AC97 = 0xE0000000+MCF_PSC_TB_AC97_SOF; //START SLOT1 + SLOT2, FIRST FRAME + MCF_PSC_TB2_AC97 = 0x02000000; //SLOT1:WR REG MASTER VOLUME adr 0x02 + for ( i = 2; i<13; i++ ) + { + MCF_PSC_TB2_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0 + } + // read register + MCF_PSC_TB2_AC97 = 0xc0000000+MCF_PSC_TB_AC97_SOF; //START SLOT1 + SLOT2, FIRST FRAME + MCF_PSC_TB2_AC97 = 0x82000000; //SLOT1:master volume + for ( i = 2; i<13; i++ ) + { + MCF_PSC_TB2_AC97 = 0x00000000; //SLOT2-12:RD REG ALLES 0 + } + udelay(200); + va = MCF_PSC_TB2_AC97; + if ((va & (0x80000000+MCF_PSC_TB_AC97_SOF))==(0x80000000+MCF_PSC_TB_AC97_SOF)) + { + vb = MCF_PSC_TB2_AC97; + vc = MCF_PSC_TB2_AC97; + if (((va & (0xE0000000+MCF_PSC_TB_AC97_SOF))==(0xE0000000+MCF_PSC_TB_AC97_SOF)) /* && (vb==0x02000000) && (vc==0x00000000) */) + { + goto livo; + } + } + } + MCF_PSC_TB0_32BIT = ' not'; +livo: +// AUX VOLUME ->-0dB + MCF_PSC_TB2_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME + MCF_PSC_TB2_AC97 = 0x16000000; //SLOT1:WR REG AUX VOLUME adr 0x16 + MCF_PSC_TB2_AC97 = 0x06060000; //SLOT1:VOLUME + for ( i = 3; i<13; i++ ) + { + MCF_PSC_TB2_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0 + } + +// line in VOLUME +12dB + MCF_PSC_TB2_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME + MCF_PSC_TB2_AC97 = 0x10000000; //SLOT1:WR REG MASTER VOLUME adr 0x02 + for ( i = 2; i<13; i++ ) + { + MCF_PSC_TB2_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0 + } +// cd in VOLUME 0dB + MCF_PSC_TB2_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME + MCF_PSC_TB2_AC97 = 0x12000000; //SLOT1:WR REG MASTER VOLUME adr 0x02 + for ( i = 2; i<13; i++ ) + { + MCF_PSC_TB2_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0 + } +// mono out VOLUME 0dB + MCF_PSC_TB2_AC97 = 0xE0000000; //START SLOT1 + SLOT2, FIRST FRAME + MCF_PSC_TB2_AC97 = 0x06000000; //SLOT1:WR REG MASTER VOLUME adr 0x02 + MCF_PSC_TB2_AC97 = 0x00000000; //SLOT1:WR REG MASTER VOLUME adr 0x02 + for ( i = 3; i<13; i++ ) + { + MCF_PSC_TB2_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0 + } + MCF_PSC2_TFCR |= MCF_PSC_RFCR_WRITETAG; //set EOF + MCF_PSC_TB2_AC97 = 0x00000000; //last data + + MCF_PSC_TB0_32BIT = ' OK!'; + MCF_PSC_TB0_16BIT = 0x0a0d; + + board_printf("va %08X vb %08X vc %08X\r\n", va, vb, vc); + +} diff --git a/flash.tos/drivers/ac97/mcf548x_ac97.c b/flash.tos/drivers/ac97/mcf548x_ac97.c index 96b3543..b87cb4c 100644 --- a/flash.tos/drivers/ac97/mcf548x_ac97.c +++ b/flash.tos/drivers/ac97/mcf548x_ac97.c @@ -53,7 +53,7 @@ extern unsigned long save_imrh; #define EMUL_DMA_STE #ifdef SOUND_AC97 -#ifdef NETWORK /* for DMA API */ +#ifdef LWIP /* for DMA API */ /* ======================================================================== */ /* Structs / Defines */ @@ -260,7 +260,7 @@ extern void psc3_ac97_interrupt(void); extern void timer_ac97_interrupt(void); #ifdef USE_DMA extern void timeout_ac97_interrupt(void); -#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) extern int usb_mem_init(void); extern void *usb_malloc(long amount); extern int usb_free(void *addr); @@ -269,7 +269,7 @@ extern int usb_free(void *addr); extern long install_xbra(short vector, void *handler); extern void *mcf548x_ac97_playback_resample(long play_frequency, int play_res, int num_frames, void *source, long *target); extern void *mcf548x_ac97_record_resample(long record_frequency, int record_res, int num_samples, void *target, long *source); -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern void board_printf(const char *fmt, ...); #endif @@ -1533,7 +1533,7 @@ static int mcf548x_ac97_bdinit(struct mcf548x_ac97_priv *priv) #ifdef DEBUG display_string("mcf548x_ac97_bdinit\r\n"); #endif -#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) usb_mem_init(); priv->buffer = (void *)usb_malloc((AC97_DMA_SIZE * (AC97_TX_NUM_BD + AC97_RX_NUM_BD)) + 15); #else @@ -1983,9 +1983,9 @@ static void mcf548x_ac97_write(struct mcf548x_ac97_priv *priv, unsigned short re count++; } #ifdef EMUL_DME_STE - while(!priv->timer && (priv->ctrl_data != priv->status_data) && (count < AC97_RETRY_WRITE)); + while(!priv->timer && (priv->ctrl_data != priv->status_data) && (count < AC97_RETRY_WRITE) && (reg != AC97_RESET)); #else - while((priv->ctrl_data != priv->status_data) && (count < AC97_RETRY_WRITE)); + while((priv->ctrl_data != priv->status_data) && (count < AC97_RETRY_WRITE) && (reg != AC97_RESET)); #endif #ifdef DEBUG { @@ -2009,6 +2009,8 @@ static void mcf548x_ac97_write(struct mcf548x_ac97_priv *priv, unsigned short re #endif } +#ifdef USE_DMA + static void mcf548x_ac97_powerdown(struct mcf548x_ac97_priv *priv) { priv->ctrl_address = AC97_POWERDOWN; @@ -2021,7 +2023,9 @@ static void mcf548x_ac97_powerdown(struct mcf548x_ac97_priv *priv) priv->timeout_shutdown = 0; } - /* seems works only with dma else sync is lost after a warnreset from an AC-link powerdown */ +#endif /* USE_DMA */ + +/* seems works only with dma else sync is lost after a warnreset from an AC-link powerdown */ static void mcf548x_ac97_warnreset(struct mcf548x_ac97_priv *priv) { int i; @@ -2200,10 +2204,7 @@ void mcf548x_ac97_timer_interrupt(void) static void mcf548x_ac97_hwstop(struct mcf548x_ac97_priv *priv) { - int level; - if(!priv->aclink_stopped) - mcf548x_ac97_powerdown(priv); - level = asm_set_ipl(7); /* mask interrupts */ + int level = asm_set_ipl(7); /* mask interrupts */ /* Stop the PSC */ MCF_PSC_CR(priv->psc_channel) = MCF_PSC_CR_RESET_RX; MCF_PSC_CR(priv->psc_channel) = MCF_PSC_CR_RESET_TX; @@ -3380,7 +3381,7 @@ int mcf548x_ac97_install(long psc_channel) else { struct mcf548x_ac97_priv *priv; -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if defined(COLDFIRE) && defined(LWIP) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) extern unsigned long pxCurrentTCB, tid_TOS; extern void *usb_malloc(long amount); extern int usb_free(void *addr); @@ -3408,7 +3409,7 @@ int mcf548x_ac97_install(long psc_channel) #ifdef DEBUG display_string("mcf548x_ac97_install timeout for read codec ID\r\n"); #else -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) board_printf("CODEC ID read timeout, please try again with TOS started with dBUG\r\n"); #endif #endif /* DEBUG */ @@ -3421,7 +3422,7 @@ int mcf548x_ac97_install(long psc_channel) #ifdef DEBUG display_string("mcf548x_ac97_install bad codec ID\r\n"); #else -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) board_printf("BAD CODEC ID (0x%04X)\r\n", priv->id); #endif #endif /* DEBUG */ @@ -3448,7 +3449,7 @@ int mcf548x_ac97_install(long psc_channel) priv->powerdown = mcf548x_ac97_read(priv, AC97_POWERDOWN); if(!old_timer_vector) { -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if defined(COLDFIRE) && defined(LWIP) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) if(pxCurrentTCB != tid_TOS) { old_timer_vector = *(long *)(69 * 4); @@ -3479,7 +3480,7 @@ int mcf548x_ac97_install(long psc_channel) } if(priv != NULL) { -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if defined(COLDFIRE) && defined(LWIP) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) if(pxCurrentTCB != tid_TOS) usb_free(priv); else @@ -3493,7 +3494,7 @@ int mcf548x_ac97_install(long psc_channel) int mcf548x_ac97_uninstall(long psc_channel, int free) { struct mcf548x_ac97_priv *priv; -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if defined(COLDFIRE) && defined(LWIP) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) extern unsigned long pxCurrentTCB, tid_TOS; extern int usb_free(void *addr); #endif @@ -3502,6 +3503,7 @@ int mcf548x_ac97_uninstall(long psc_channel, int free) priv = Devices[psc_channel]; if(priv == NULL) return(-1); // error + mcf548x_ac97_write(priv, AC97_RESET, 0); mcf548x_ac97_hwstop(priv); if(free) { @@ -3514,7 +3516,7 @@ int mcf548x_ac97_uninstall(long psc_channel, int free) #endif #endif /* USE_DMA */ Devices[psc_channel] = NULL; -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if defined(COLDFIRE) && defined(LWIP) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) if(pxCurrentTCB != tid_TOS) usb_free(priv); else @@ -3524,5 +3526,5 @@ int mcf548x_ac97_uninstall(long psc_channel, int free) return(0); } -#endif /* NETWORK */ +#endif /* LWIP */ #endif /* SOUND_AC97 */ diff --git a/flash.tos/drivers/bdos/bdos.c b/flash.tos/drivers/bdos/bdos.c index 8713d34..5866075 100644 --- a/flash.tos/drivers/bdos/bdos.c +++ b/flash.tos/drivers/bdos/bdos.c @@ -11,7 +11,6 @@ #include "console.h" #include "gemerror.h" -#ifdef NETWORK #ifdef LWIP extern void xSemaphoreTakeBDOS(void); @@ -555,4 +554,3 @@ void Fdatime(short *timeptr, long handle, long wflag) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/bdos/bdosmain.c b/flash.tos/drivers/bdos/bdosmain.c index 31463d9..e3a6d09 100644 --- a/flash.tos/drivers/bdos/bdosmain.c +++ b/flash.tos/drivers/bdos/bdosmain.c @@ -26,11 +26,9 @@ #define _MINT_OSTRUCT_H #include #include "config.h" -#ifdef NETWORK #ifdef LWIP #include "../../include/vars.h" #endif -#endif #include "portab.h" #include "fs.h" #include "asm.h" @@ -377,7 +375,6 @@ static void offree(DMD *d) */ static BPB * MyGetbpb(WORD errdrv) { -#ifdef NETWORK #ifdef LWIP extern long pxCurrentTCB, tid_TOS; if(pxCurrentTCB != tid_TOS) @@ -387,7 +384,6 @@ static BPB * MyGetbpb(WORD errdrv) return((*p)(errdrv)); } #endif -#endif return (BPB *) Getbpb(errdrv); } diff --git a/flash.tos/drivers/bdos/fsbuf.c b/flash.tos/drivers/bdos/fsbuf.c index 73324fe..eb23011 100644 --- a/flash.tos/drivers/bdos/fsbuf.c +++ b/flash.tos/drivers/bdos/fsbuf.c @@ -15,11 +15,9 @@ #define _MINT_OSTRUCT_H #include #include "config.h" -#ifdef NETWORK #ifdef LWIP #include "../../include/vars.h" #endif -#endif #include "portab.h" #include "asm.h" #include "fs.h" @@ -247,7 +245,6 @@ doio: for (p = *(q = phdr); p->b_link; p = *(q = &p->b_link)) } else { /* use a buffer, but first validate media */ -#ifdef NETWORK #ifdef LWIP extern long pxCurrentTCB, tid_TOS; if(pxCurrentTCB != tid_TOS) @@ -258,7 +255,6 @@ doio: for (p = *(q = phdr); p->b_link; p = *(q = &p->b_link)) } else #endif -#endif err = Mediach(b->b_bufdrv); if (err != 0) { if (err == 1) { diff --git a/flash.tos/drivers/bdos/fsdir.c b/flash.tos/drivers/bdos/fsdir.c index bf65ea3..bbb7477 100644 --- a/flash.tos/drivers/bdos/fsdir.c +++ b/flash.tos/drivers/bdos/fsdir.c @@ -127,11 +127,9 @@ #define _MINT_OSTRUCT_H #include #include "config.h" -#ifdef NETWORK #ifdef LWIP #include "../../include/vars.h" #endif -#endif #include "portab.h" #include "asm.h" #include "fs.h" @@ -1165,14 +1163,12 @@ long xgetdir(char *buf, short drv) drv = (drv == 0) ? run->p_curdrv : drv-1 ; { -#ifdef NETWORK #ifdef LWIP extern long pxCurrentTCB, tid_TOS; if(pxCurrentTCB != tid_TOS) drvmap = *(unsigned long *)_drvbits; else #endif -#endif drvmap = Drvmap(); } if( !(drvmap & (1< #include "config.h" -#ifdef NETWORK #ifdef LWIP #include "../../include/vars.h" #endif -#endif #include "portab.h" #include "asm.h" #include "fs.h" @@ -105,7 +103,6 @@ long ckdrv(short d) if (!(mask & drvsel)) { /* drive has not been selected yet */ -#ifdef NETWORK #ifdef LWIP extern long pxCurrentTCB, tid_TOS; if(pxCurrentTCB != tid_TOS) @@ -116,7 +113,6 @@ long ckdrv(short d) } else #endif -#endif b = (BPB *) Getbpb(d); if ( !(long)b ) /* M01.01.1007.01 */ diff --git a/flash.tos/drivers/bdos/fsmain.c b/flash.tos/drivers/bdos/fsmain.c index 018dc9a..3b5d270 100644 --- a/flash.tos/drivers/bdos/fsmain.c +++ b/flash.tos/drivers/bdos/fsmain.c @@ -15,11 +15,9 @@ #define _MINT_OSTRUCT_H #include #include "config.h" -#ifdef NETWORK #ifdef LWIP #include "../../include/vars.h" #endif -#endif #include "portab.h" #include "asm.h" #include "fs.h" @@ -454,14 +452,12 @@ long xsetdrv(short drv) display_string(") => "); #endif { -#ifdef NETWORK #ifdef LWIP extern long pxCurrentTCB, tid_TOS; if(pxCurrentTCB != tid_TOS) drvmap = *(unsigned long *)_drvbits; else #endif -#endif drvmap = Drvmap(); } diff --git a/flash.tos/drivers/bdos/osmem.c b/flash.tos/drivers/bdos/osmem.c index 54bad8f..f592ee4 100644 --- a/flash.tos/drivers/bdos/osmem.c +++ b/flash.tos/drivers/bdos/osmem.c @@ -56,7 +56,7 @@ static short osmem[LENOSM]; /* * root - root array for 'quick' pool. * root is an array of ptrs to memblocks of size 'i' paragraphs, - * where 'i' is the index into the araay (a paragraph is 16 bites). + * where 'i' is the index into the array (a paragraph is 16 bites). * Each list is singly linked. Items on the list are * deleted/added in LIFO order from the root. */ @@ -169,9 +169,9 @@ void xmfreblk(void *m) if( i < 0 || i >= MAXQUICK ) { /* bad index */ -#if DBGOSMEM - kprintf("xmfreblk: bad index (0x%x)\n") ; - kprintf("stack at %08lx\n",&m) ; +#if DBGOSMEM + board_printf("xmfreblk: bad index (0x%lx)\r\n", (long)i) ; + board_printf("stack at 0x%08lx\r\n",&m) ; while(1) ; #endif dbgfreblk++ ; @@ -181,11 +181,11 @@ void xmfreblk(void *m) /* ok to free up */ *((short **) m) = root[i]; root[i] = m; -#if DBGFREMEM +#if DBGFREMEM if( *((short **)m) == m ) { - kprintf("xmfreblk: Circular link in root[%x]\n",i) ; - kprintf("\tat %lx\n",m) ; + board_printf("xmfreblk: Circular link in root[0x%lx]\r\n", (long)i) ; + board_printf("\tat 0x%08lx\r\n", m) ; } #endif diff --git a/flash.tos/drivers/bdos/proc.c b/flash.tos/drivers/bdos/proc.c index d4aca9c..1d62289 100644 --- a/flash.tos/drivers/bdos/proc.c +++ b/flash.tos/drivers/bdos/proc.c @@ -646,13 +646,11 @@ static void proc_go(PD *p) sp->basepage = p; /* the stack contains the basepage */ sp->retaddr = p->p_tbase; /* return address a3 is text start */ -#ifdef NETWORK #ifdef LWIP { extern void install_auto_breakpoint(long address); install_auto_breakpoint(p->p_tbase); } -#endif #endif sp->sr = 0; /* the process will start in user mode */ diff --git a/flash.tos/drivers/bdos/rwa.S b/flash.tos/drivers/bdos/rwa.S index 1ce89b3..8c670f9 100644 --- a/flash.tos/drivers/bdos/rwa.S +++ b/flash.tos/drivers/bdos/rwa.S @@ -147,7 +147,7 @@ #undef DEBUG -#if defined(NETWORK) && defined(LWIP) +#ifdef LWIP .global _xSemaphoreTakeBDOS,_xSemaphoreGiveBDOS #endif @@ -479,7 +479,7 @@ _oscall: //==== fix_trap - make 68010 exception stack frame look like a 68000 frame === fix_trap: -#if defined(NETWORK) && defined(LWIP) +#ifdef LWIP lea -24(sp),sp movem.l d0-d2/a0-a2,(sp) jsr _xSemaphoreTakeBDOS @@ -511,7 +511,7 @@ fix_rte: move.w 6(sp),4(sp) // lsw of return address of TRAP clr.w 6(sp) // store a bogus exception frame type fr_exit: -#if defined(NETWORK) && defined(LWIP) +#ifdef LWIP lea -24(sp),sp movem.l d0-d2/a0-a2,(sp) jsr _xSemaphoreGiveBDOS @@ -572,7 +572,7 @@ _rwabs: move.w d2,-(sp) // count move.l d1,-(sp) // buf move.w d0,-(sp) // mode -#if defined(NETWORK) && defined(LWIP) +#ifdef LWIP move.l _pxCurrentTCB,d0 cmp.l _tid_TOS,d0 beq.s use_trap @@ -685,7 +685,7 @@ _flush_cache_pexec: cmp.l #0x2043,D0 // ' C' bne .test_cacr .fix_code_purec: -#if defined(NETWORK) && defined(LWIP) +#if defined(LWIP) pea purec_found jsr _conws_debug addq.l #4,SP @@ -811,6 +811,8 @@ _flush_cache_pexec: beq.s .ok_subroutine cmp.l #0x4EB9,D2 // jsr beq.s .ok_subroutine + cmp.l #0x2F0A,D2 // move.l A2,-(SP) + beq.s .ok_subroutine cmp.l #0x2F03,D2 // move.l D3,-(SP) beq.s .ok_subroutine cmp.l #0xB03C,D2 // cmp.b #xxx,D0 (HDDRIVER) @@ -1080,7 +1082,7 @@ _flush_cache_pexec: disassemble_byte_on_stack: // A0: address, D0: new instruction (0xA9XX - not used by CF: 0xA910-0xA91F 0xA938-0xA93F) -#if defined(NETWORK) && defined(LWIP) +#if defined(LWIP) link A6,#-10 lea -24(SP),SP movem.l D0-D2/A0-A2,(SP) diff --git a/flash.tos/drivers/cd/cd_disk.c b/flash.tos/drivers/cd/cd_disk.c new file mode 100644 index 0000000..58b11ef --- /dev/null +++ b/flash.tos/drivers/cd/cd_disk.c @@ -0,0 +1,434 @@ +/* + * This file 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 file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +/* Disk cache from GRUB (GRand Unified Bootloader) sources */ + +#include +#include +#include +#include /* for malloc */ +#include "gemerror.h" +#include "scsidrv/scsi.h" +#include "cd_dos.h" +#include "cd_disk.h" +#include "cd_iso.h" + +#define CD_DA 1 +#define CD_DATA 2 +#define CD_I 3 +#define CD_XA 4 +#define DVD_ROM 5 +#define DVD_RAM 6 +#define DVD_R 7 +#define DVD_RW 8 +#define DVD_PLUS_R 9 +#define DVD_PLUS_RW 10 + +#undef STATIC_TMP_BUF + +/* Disk cache */ +struct cd_disk_cache +{ + unsigned long dev_id; + unsigned long disk_id; + unsigned long sector; + char *data; + int lock; +}; + +extern void kprint(const char *fmt, ...); +extern tpScsiCall scsicall; +extern tReqData ReqBuff; +extern int boot_menu(int index, int nb_lines, char *title, char *lines[], int delay_sec); +extern int install_cd_disk(void); + +static char BuffSector[CD_SECTOR_SIZE]; + +int cd_disk_errno; +struct cd_disk global_disk; + +/* Read sectors with DISK_SECTOR_SIZE for XBIOS */ +int cd_disk_read_sectors(unsigned long sector_start, unsigned long num_sectors, void *buffer) +{ + unsigned long sector = sector_start >> (CD_SECTOR_BITS - DISK_SECTOR_BITS); + unsigned long offset = (sector_start & 3) << DISK_SECTOR_BITS; + unsigned long count = ((sector_start + num_sectors - 1) >> (CD_SECTOR_BITS - DISK_SECTOR_BITS)) - sector + 1; + long rc = -1, i; + if(sector_start < global_disk.total_sectors) + { + if(!offset && !(num_sectors & 3) && (count < 65536)) + rc = Read10(sector, count, buffer); + else + { + for(i = 0; i < count; i++) + { + rc = Read10(sector, 1, BuffSector); + if(rc != 0) + break; + while(offset < CD_SECTOR_SIZE) + { + memcpy(buffer, &BuffSector[offset], DISK_SECTOR_SIZE); + offset += DISK_SECTOR_SIZE; + buffer += DISK_SECTOR_SIZE; + num_sectors--; + if(num_sectors <= 0) + break; + } + offset = 0; + sector++; + } + } + } + return((int)rc); +} + +/* CD disk cache */ +static struct cd_disk_cache cd_disk_cache_table[DISK_CACHE_NUM]; + +static unsigned cd_disk_cache_get_index(unsigned long dev_id, unsigned long disk_id, unsigned long sector) +{ + return((dev_id * 524287UL + disk_id * 2606459UL + ((unsigned) (sector >> DISK_CACHE_BITS))) % DISK_CACHE_NUM); +} + +#if 0 +static void cd_disk_cache_invalidate_all(void) +{ + unsigned i; + for(i = 0; i < DISK_CACHE_NUM; i++) + { + struct cd_disk_cache *cache = cd_disk_cache_table + i; + if((cache->data != NULL) && !cache->lock) + { + free(cache->data); + cache->data = NULL; + } + } +} +#endif + +static void cd_disk_cache_free_all(void) +{ + unsigned i; + for(i = 0; i < DISK_CACHE_NUM; i++) + { + struct cd_disk_cache *cache = cd_disk_cache_table + i; + if(cache->data != NULL) + { + free(cache->data); + cache->data = NULL; + } + } +} + +static char *cd_disk_cache_fetch(unsigned long dev_id, unsigned long disk_id, unsigned long sector) +{ + unsigned index = cd_disk_cache_get_index(dev_id, disk_id, sector); + struct cd_disk_cache *cache = cd_disk_cache_table + index; + if(cache->dev_id == dev_id && cache->disk_id == disk_id && cache->sector == sector) + { + cache->lock = 1; + return(cache->data); + } + return(0); +} + +static void cd_disk_cache_unlock(unsigned long dev_id, unsigned long disk_id, unsigned long sector) +{ + unsigned index = cd_disk_cache_get_index(dev_id, disk_id, sector); + struct cd_disk_cache *cache = cd_disk_cache_table + index; + if(cache->dev_id == dev_id && cache->disk_id == disk_id && cache->sector == sector) + cache->lock = 0; +} + +static int cd_disk_cache_store(unsigned long dev_id, unsigned long disk_id, unsigned long sector, const char *data) +{ + unsigned index = cd_disk_cache_get_index(dev_id, disk_id, sector); + struct cd_disk_cache *cache = cd_disk_cache_table + index; + cache->lock = 1; + if(cache->data != NULL) + free(cache->data); + cache->data = NULL; + cache->lock = 0; + cache->data = (char *)malloc(DISK_SECTOR_SIZE << DISK_CACHE_BITS); + if(cache->data == NULL) + return(cd_disk_errno = ENSMEM); + memcpy(cache->data, data, DISK_SECTOR_SIZE << DISK_CACHE_BITS); + cache->dev_id = dev_id; + cache->disk_id = disk_id; + cache->sector = sector; + return(E_OK); +} + +/* This function: + - Make sectors disk relative from partition relative. + - Normalize offset to be less than the sector size. */ +static int cd_disk_adjust_range(cd_disk_t disk, unsigned long *sector, unsigned long *offset, int size) +{ + *sector += *offset >> DISK_SECTOR_BITS; + *offset &= DISK_SECTOR_SIZE - 1; + if((disk->total_sectors <= *sector) || (((*offset + size + DISK_SECTOR_SIZE - 1) >> DISK_SECTOR_BITS) > (disk->total_sectors - *sector))) + return(cd_disk_errno = ERANGE); /* out of disk */ + return(E_OK); +} + +/* Read data from the disk */ +int cd_disk_read(cd_disk_t disk, unsigned long sector, unsigned long offset, int size, void *buf) +{ +#ifdef STATIC_TMP_BUF + static char tmp_buf[DISK_SECTOR_SIZE << DISK_CACHE_BITS]; +#else + char *tmp_buf; +#endif + unsigned real_offset, size_tmp = DISK_SECTOR_SIZE << DISK_CACHE_BITS; + /* First of all, check if the region is within the disk */ + if(cd_disk_adjust_range(disk, §or, &offset, size) != E_OK) + return(cd_disk_errno); + real_offset = offset; +#ifndef STATIC_TMP_BUF + /* Allocate a temporary buffer */ + tmp_buf = (char *)malloc(size_tmp); + if(tmp_buf == NULL) + return(cd_disk_errno = ENSMEM); +#endif + /* Until SIZE is zero... */ + while(size) + { + /* For reading bulk data. */ + unsigned long start_sector = sector & ~(DISK_CACHE_SIZE - 1); + int pos = (sector - start_sector) << DISK_SECTOR_BITS; + int len = ((DISK_SECTOR_SIZE << DISK_CACHE_BITS) - pos - real_offset); + /* Fetch the cache */ + char *data = cd_disk_cache_fetch(disk->dev_id, disk->id, start_sector); + if(len > size) + len = size; + if(data != NULL) + { + /* Just copy it! */ + memcpy(buf, data + pos + real_offset, len); + cd_disk_cache_unlock(disk->dev_id, disk->id, start_sector); + } + else + { + /* Otherwise read data from the disk actually */ + if((start_sector + DISK_CACHE_SIZE > disk->total_sectors) + || cd_disk_read_sectors(start_sector, DISK_CACHE_SIZE, tmp_buf)) + { + /* Failed. Instead, just read necessary data */ + unsigned num = ((size + real_offset + DISK_SECTOR_SIZE - 1) >> DISK_SECTOR_BITS); + char *p = (char *)malloc(num << DISK_SECTOR_BITS); + if(p == NULL) + { + cd_disk_errno = ENSMEM; + goto finish; + } + cd_disk_errno = E_OK; + memcpy(p, tmp_buf, size_tmp); +#ifndef STATIC_TMP_BUF + free(tmp_buf); + tmp_buf = NULL; +#endif + if(!cd_disk_read_sectors(sector, num, p)) + memcpy(buf, p + real_offset, size); + /* This must be the end */ + goto finish; + } + /* Copy it and store it in the disk cache */ + memcpy(buf, tmp_buf + pos + real_offset, len); + cd_disk_cache_store(disk->dev_id, disk->id, start_sector, tmp_buf); + } + sector = start_sector + DISK_CACHE_SIZE; + buf = (char *)buf + len; + size -= len; + real_offset = 0; + } +finish: +#ifndef STATIC_TMP_BUF + if(tmp_buf != NULL) + free(tmp_buf); +#endif + return(cd_disk_errno); +} + +/* called from init.c */ +int cd_disk_boot(void) +{ + static char inqdata[36], vendor[9], product[17], revision[5]; + static unsigned char tocdata[14], dvddata[84]; + unsigned long MaxLen, BlockSize, BlockLen; + long rc; + tBusInfo Bus; + tDevInfo Dev; + tHandle handle; + int ret = 0, found = 0, type = 0; + SetBlockSize(CD_SECTOR_SIZE); + init_scsiio(); + if(scsicall != NULL) + { + rc = InquireSCSI(cInqFirst, &Bus); + while(rc == 0) + { + rc = InquireBus(cInqFirst, Bus.BusNo, &Dev); + while(rc == 0) + { + rc = Open(Bus.BusNo, &Dev.SCSIId, &MaxLen); + if(rc < 0L) + continue; + handle = (tHandle)rc; + SetScsiUnit(handle, 0, MaxLen); + memset(inqdata, 0, sizeof(inqdata)); + rc = Inquiry(inqdata, 0, 0, sizeof(inqdata)); + if(rc == 0) + { + if((*inqdata&0x1f) == ROMDEV) /* CD-ROM / DVD drive */ + { + int medium = 0, in_progress = 0; + unsigned long timeout = *(volatile unsigned long *)_hz_200 + (5 * 200); + strncpy(vendor,inqdata+8,8); + vendor[8] = '\0'; + strncpy(product,inqdata+16,16); + product[16] = '\0'; + strncpy(revision,inqdata+32,4); + revision[4] = '\0'; + while(!medium) + { + rc = ReadCapacity(0, &BlockSize, &BlockLen); + if(rc == 0) + medium = 1; + else if(rc == 2) + { + unsigned char asc = ReqBuff[12]; + unsigned char ascq = ReqBuff[13]; + if(asc == 0x3A) /* MEDIUM NOT PRESENT */ + medium = -1; + else if((asc == 0x04) && (ascq == 0x01) && !in_progress) /* IN PROGRESS OF BECOMING READY */ + { + timeout = *(volatile unsigned long *)_hz_200 + (30 * 200); + in_progress = 1; + } + Wait(20); + if(*(volatile unsigned long *)_hz_200 >= timeout) + medium = -1; + } + else + medium = -1; + } + switch(BlockLen) + { + case 0: + case 2340: + case 2352: + BlockLen = CD_SECTOR_SIZE; + break; + } + if((medium > 0) && (BlockLen == CD_SECTOR_SIZE)) + { + rc = ReadDVDStucture(0, 0, 0, 0, dvddata, sizeof(dvddata)); /* DVD Struct Physical */ + if(rc == 0) + { + switch(dvddata[4] >> 4) /* Book Type */ + { + case 0: type = DVD_ROM; break; + case 1: type = DVD_RAM; break; + case 2: type = DVD_R; break; + case 3: type = DVD_RW; break; + case 8: type = DVD_PLUS_R; break; + case 9: type = DVD_PLUS_RW; break; + default: rc = -1; break; + } + } + if(rc != 0) + { + rc = ReadTOC(1, 2, 0, tocdata, sizeof(tocdata)); /* Full TOC */ + if((rc == 0) && (tocdata[7] == 0xA0)) + { + if(tocdata[13] == 0x00) + { + if(tocdata[5] & 0x04) + type = CD_DATA; + else + type = CD_DA; + } + else if(tocdata[13] == 0x10) + type = CD_I; + else if(tocdata[13] == 0x20) + type = CD_XA; + } + } + if((rc == 0) && ((type == CD_DATA) || (type == CD_XA) || (type >= DVD_ROM)) && !found) + { + char *label = NULL; + long total_sectors = 0; + cd_disk_errno = 0; + memset(&global_disk, 0, sizeof(struct cd_disk)); + global_disk.dev_id = 1; + global_disk.id = 1; + global_disk.total_sectors = BlockSize << (CD_SECTOR_BITS - DISK_SECTOR_BITS); + rc = (long)iso9660_label(&global_disk, &label, &total_sectors); + if((rc == E_OK) || (rc == EMEDIA)) + { + static char *menu[] = {" Ignore ", " Boot CD/DVD "}; + kprint("\33\142\64\0"); + kprint("%s %d.%d", Bus.BusName, Dev.SCSIId.hi, Dev.SCSIId.lo); + kprint("\33\142\77\0 "); + kprint(" %s %s %s ... %s\r\n", vendor, product, revision, (label != NULL) ? label : ""); + if(boot_menu(0, 2, "", menu, 2)) + { + if(rc == EMEDIA) + { + if((global_disk.dev_id = (unsigned long)install_cd_disk()) != 0) /* CD-backup: TOS FAT16 partition */ + found = 1; + else + { + kprint("CD-disk not installed (not TOS FAT16 or ISO9660)\r\n"); + Crawcin(); + } + } + else /* ISO */ + { + extern long install_xbra(short vector, void *handler); + extern void det_gemdos(void); + extern long old_vector_gemdos; + total_sectors <<= (CD_SECTOR_BITS - DISK_SECTOR_BITS); + if(total_sectors && (total_sectors < global_disk.total_sectors)) + global_disk.total_sectors = total_sectors; + old_vector_gemdos = install_xbra(33, det_gemdos); /* TRAP #1 */ + found = 1; + } + } + if(found) + { +// *_bootdev = (short)global_disk.dev_id; +// Dsetdrv((short)global_disk.dev_id); + kprint("\33\142\64\0"); + kprint("CD-disk installed in %c", (char)global_disk.dev_id + 'A'); + kprint("\33\142\77\0\r\n"); + } + } + if(label != NULL) + free(label); + } + } + } + Close(handle); + } + rc = InquireBus(cInqNext, Bus.BusNo, &Dev); + } + rc = InquireSCSI(cInqNext, &Bus); + } + } + if(!found) + cd_disk_cache_free_all(); + return(ret); +} diff --git a/flash.tos/drivers/cd/cd_disk.h b/flash.tos/drivers/cd/cd_disk.h new file mode 100644 index 0000000..2673d33 --- /dev/null +++ b/flash.tos/drivers/cd/cd_disk.h @@ -0,0 +1,56 @@ +/* + * This file 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 file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _CD_DISK_H +#define _CD_DISK_H + +#define DISK_SECTOR_SIZE 512 +#define DISK_SECTOR_BITS 9 +#define CD_SECTOR_SIZE 2048 +#define CD_SECTOR_BITS 11 + +/* The size of a disk cache in sector units. */ +#define DISK_CACHE_SIZE 8 +#define DISK_CACHE_BITS 3 + +/* The maximum number of disk caches. */ +#define DISK_CACHE_NUM 125 // was 1021 + +struct dirhook_info +{ + unsigned dir:1; + unsigned hidden:1; + unsigned mtimeset:1; + unsigned case_insensitive:1; + unsigned long mtime; + unsigned long size; +}; + +struct cd_disk +{ + unsigned long total_sectors; + unsigned long dev_id; + unsigned long id; /* The id used by the disk cache manager */ + void *data; +}; + +typedef struct cd_disk *cd_disk_t; + +int cd_disk_read_sectors(unsigned long sector_start, unsigned long num_sectors, void *buffer); +int cd_disk_read(cd_disk_t disk, unsigned long sector, unsigned long offset, int size, void *buf); +int cd_disk_boot(void); + +#endif /* _CD_DISK_H */ diff --git a/flash.tos/drivers/cd/cd_dos.c b/flash.tos/drivers/cd/cd_dos.c new file mode 100644 index 0000000..b90ca96 --- /dev/null +++ b/flash.tos/drivers/cd/cd_dos.c @@ -0,0 +1,1138 @@ +/* TOS 4.04 DOS ISO9660 boot for the CT60/CTPCI & Coldfire boards + * Didier Mequignon 2011, e-mail: aniplay@wanadoo.fr + * + * This file 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 file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include "gemerror.h" +#include "cd_dos.h" +#include "cd_disk.h" +#include "cd_iso.h" + +#undef DEBUG + +#ifdef COLDFIRE +#define USE_BDOS +#endif + +#ifdef USE_BDOS +#define BIOS_H +#define BPB void +#include "../bdos/fs.h" +#else /* GEMDOS */ + +/* PD - Process Descriptor */ + +#define NUMSTD 6 /* number of standard files */ +#define PDCLSIZE 0x80 /* size of command line in bytes */ +#define NUMCURDIR 16 /* number of entries in curdir array */ +#define OPNFILES 32 +#define FA_RO 0x01 /* write protected */ +#define FA_HIDDEN 0x02 +#define FA_SYSTEM 0x04 +#define FA_VOL 0x08 /* label */ +#define FA_ARCHIVE 0x20 +#define FA_SUBDIR 0x10 /* subdirectory */ +#endif /* USE_BDOS */ + +#define MAX_NAME 128 /* max 255 for SUBDTA structure */ +#define MAX_PATH 256 + +#define PE_LOADGO 0 +#define PE_LOAD 3 +#define PE_GO 4 +#define PE_BASEPAGE 5 +#define PE_GOTHENFREE 6 +#define PE_BASEPAGEFREE 7 + +typedef struct dtainfo +{ + char dt_name[12]; /* file name: filename.typ 00-11 */ + long dt_pos; /* dir position 12-15 */ + void *dt_dnd; /* pointer to DND 16-19 */ + char dt_attr; /* attributes of file 20 */ + /* -- below must not change -- [1] */ + char dt_fattr; /* attrib from fcb 21 */ + short dt_time; /* time field from fcb 22-23 */ + short dt_date; /* date field from fcb 24-25 */ + long dt_fileln; /* file length field from fcb 26-29 */ + char dt_fname[14]; /* file name from fcb 30-43 */ +} DTA; + +typedef struct subdtainfo +{ + char dt_fattr; + unsigned char dt_time[2]; + unsigned char dt_date[2]; + unsigned char dt_fileln[4]; + char dt_fname[14]; + unsigned char dt_len_lfname; + char dt_lfname[1]; +} SUBDTA; + +typedef struct pgmhdr01 +{ + /* magic number is already read */ + long h01_tlen; /* length of text segment */ + long h01_dlen; /* length of data segment */ + long h01_blen; /* length of bss segment */ + long h01_slen; /* length of symbol table */ + long h01_res1; /* reserved - always zero */ +#define PF_FASTLOAD 0x0001 +#define PF_TTRAMLOAD 0x0002 +#define PF_TTRAMMEM 0x0004 + long h01_flags; /* flags */ + short h01_abs; /* not zero if no relocation */ +} PGMHDR01; + +#ifndef USE_BDOS + +typedef struct proc_desc /* this is the basepage format */ +{ + /* 0x00 */ + long p_lowtpa; + long p_hitpa; + long p_tbase; + long p_tlen; + /* 0x10 */ + long p_dbase; + long p_dlen; + long p_bbase; + long p_blen; + /* 0x20 */ + DTA *p_xdta; + struct proc_desc *p_parent; /* parent PD */ + short p_flags; + short p_0fill[1]; + char *p_env; + /* 0x30 */ + char p_uft[NUMSTD]; /* index into sys file table for std files */ +#ifdef USE_BDOS /* BDOS and MiNT */ + char p_lddrv; + char p_curdrv; + short p_1fill[4]; +#else /* GEMDOS TOS404 */ + short p_1fill[1]; + /* 0x38 */ + short p_curdrv; + short max_handle; + long *p_handle; +#endif + /* 0x40 */ + char p_curdir[NUMCURDIR]; /* index into sys dir table */ + /* 0x50 */ + long p_2fill[4]; + /* 0x60 */ + long p_3fill[2]; + long p_dreg[1]; /* dreg[0] */ + long p_areg[5]; /* areg[3..7] */ + /* 0x80 */ + char p_cmdlin[PDCLSIZE]; +} PD __attribute__ ((__packed__)); + +#endif /* USE_BDOS */ + +struct pd_handle +{ + PD *proc; + long handle; + struct cd_file file; + int max_dirs; + int nb_dirs; + int dir_count; + SUBDTA *dirs; + SUBDTA *end_dirs; + char *long_filename; +} cd_pd_handle[OPNFILES]; + +#define malloc(a) Mxalloc(a, 3) +#define free(a) Mfree(a) + +extern PD *run; +extern int cd_disk_errno; +extern struct cd_disk global_disk; +extern void kprint(const char *fmt, ...); + +static char cur_path[MAX_PATH + 1]; + +static long check_drive(const char *path) +{ + long drive = (long)run->p_curdrv; + if(path[1] == ':') + { + if((path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z')) + drive = ((long)path[0] & 0x1F) - 1; + } + if(drive != global_disk.dev_id) + return(EDRIVE); /* for call default GEMDOS routine */ + return(E_OK); +} + +static long search_handle(long handle, long *index) +{ + long i; + if(handle < 0) + return(EDRIVE); /* for call default GEMDOS routine */ +#ifdef USE_BDOS + if((handle < NUMSTD) || (handle >= OPNFILES)) + return(EIHNDL); /* invalid handle */ + if(!sft[handle - NUMSTD].f_use) + return(EIHNDL); /* invalid handle */ +#else /* GEMDOS */ + if((handle >= (long)run->max_handle)) + return(EIHNDL); /* invalid handle */ + if(!run->p_handle[handle]) + return(EIHNDL); /* invalid handle */ +#endif + for(i = 0; i < OPNFILES; i++) + { + if((cd_pd_handle[i].proc == NULL) || (cd_pd_handle[i].handle == '_DTA')) + continue; + if((cd_pd_handle[i].proc == run) && (cd_pd_handle[i].handle == handle)) + { + *index = i; + return(E_OK); + } + } + return(EDRIVE); /* for call default GEMDOS routine */ +} + +static void dir2str(const char *src, char *nm) +{ + long i = 8; + while(i-- && *src != ' ') + *nm++ = *src++; + src += i + 1; + if(*src > ' ') + { + *nm++ = '.'; + i = 3; + while (i-- && *src != ' ') + *nm++ = *src++; + } + *nm = '\0'; +} + +static void str2dir(const char *src, char *nm) +{ + long i = 8; + while(i--) + { + if(*src && *src != '.') + *nm++ = *src++; + else + *nm++ = ' '; + } + if(*src == '.') + src++; + i = 3; + while(i--) + { + if(*src) + *nm++ = *src++; + else + *nm++ = ' '; + } +} + +#ifndef USE_BDOS + +static char uc(char c) +{ + return((c >= 'a') && (c <= 'z') ? c & 0x5F : c); +} + +static void builds(char *src, char *dst) +{ +#define isnotdelim(x) ((x) && (x != '*') && (x != '\\') && ( x!= '.') && ( x!= ' ')) + int i; + char c; + char *p; + for(i = 0; (i < 8) && isnotdelim(*src); *dst++ = uc(*src++), i++); + if(i == 8) + { + while(*src && (*src != '.') && (*src != '\\')) + src++; + } + c = (*src == '*') ? '?' : ' '; + if(*src == '*') /* skip over wildcard char */ + src++; + p = strrchr(src, '.'); + if(p != NULL) + src = p; + if(*src == '.') /* skip over extension delim */ + src++; + for(; i < 8; *dst++ = c, i++); + for(i = 0 ; (i < 3) && isnotdelim(*src); *dst++ = uc(*src++), i++); + c = (*src == '*') ? '?' : ' '; + for(; i < 3; *dst++ = c, i++); /* ext */ +} + +#endif /* USE_BDOS */ + +static int match(const char *s1, const char *s2) +{ + int i; + for(i = 0; i < 11; i++, s1++, s2++) + { + if((*s1 != '?') && (uc(*s1) != uc(*s2))) + return(0); + } + if((*s1 != FA_VOL) && (*s1 != FA_SUBDIR) && !(*s2)) + return(1); + return((int)(*s1 & *s2)); +} + +/* + * pgfix01 - do the next set of fixups + * + * returns: + * addr of last modified longword in code segment (cp) + * 0 if error or done + * stat01: + * > 0: all offsets in bss used up, read in more + * = 0: offset of 0 encountered, no more fixups + * < 0: EPLFMT (load file format error) + */ +static long pgfix01(long nrelbytes, unsigned char *tbase, unsigned char *bbase, unsigned char **lastcp) +{ + unsigned char *cp = *lastcp; /* code pointer */ + unsigned char *rp = bbase ; /* relocation info pointer = start of bss seg */ + long n = nrelbytes; /* nb of relocation bytes */ + while(n-- && *rp) + { + if(*rp == 1) + cp += 0xfe; + else + { + cp += *rp ; /* add the byte at rp to cp, don't sign ext */ + if(cp >= bbase) + return(EPLFMT); + *((long *)cp) += (long)tbase; + } + rp++; + } + *lastcp = cp; /* save code pointer */ + return((++n == 0) ? 1 : 0); +} + +static int hook_fsfirst(const char *filename, const struct dirhook_info *info) +{ + char name[12]; + DTA *dta = (DTA *)run->p_xdta; + struct pd_handle *ph = &cd_pd_handle[dta->dt_pos]; + SUBDTA *ps = ph->end_dirs; + if((dta->dt_pos >= OPNFILES) || (ph->proc != run) || (ph->handle != '_DTA')) + return(1); + if(!filename[0] || ((filename[0] == '.') && (!filename[1] || ((filename[1] == '.') && !filename[2])))) + return(0); + if((dta->dt_attr == FA_SUBDIR) && !info->dir) + return(0); + builds((char *)filename, name); + if((long)ps + strlen(filename) + sizeof(SUBDTA) > (long)&ph->dirs[ph->max_dirs]) + { + long size = sizeof(SUBDTA) * ph->max_dirs; /* size with SUBDTA without long filename in the structure */ + long used_size = (long)ps - (long)ph->dirs; + ps = (SUBDTA *)malloc(size * 2); + if(ps != NULL) + { + memcpy(ps, ph->dirs, size); + memset(&ps[ph->max_dirs], 0, size); + ph->max_dirs <<= 1; + free(ph->dirs); + ph->dirs = ps; + ph->end_dirs = (SUBDTA *)((long)ps + used_size); + ps = ph->end_dirs; + } + else + return(1); /* ouf of memory => stops */ + } + ph->nb_dirs++; + ps->dt_fattr = info->dir ? FA_SUBDIR : info->hidden ? FA_HIDDEN : 0; + dir2str(name, ps->dt_fname); + if(ph->long_filename != NULL) + { + strncpy(ps->dt_lfname, filename, MAX_NAME); + ps->dt_len_lfname = (unsigned char)strlen(ps->dt_lfname); + } + else + { + ps->dt_lfname[0] = '\0'; + ps->dt_len_lfname = 0; + } + *(unsigned long *)ps->dt_fileln = info->size; + *(unsigned short *)ps->dt_time = (unsigned short)info->mtime; + *(unsigned short *)ps->dt_date = (unsigned short)(info->mtime >> 16); + ph->end_dirs = (SUBDTA *)((unsigned long)ps + sizeof(SUBDTA) + (unsigned long)ps->dt_len_lfname); + return(0); +} + +static long i_fsfirst(char *path, long attr, char *long_filename) +{ + char *p; + struct pd_handle *ph; + struct info; + long index, ret; + DTA *dta = (DTA *)run->p_xdta; + dta->dt_dnd = NULL; + dta->dt_attr = (char)attr; + memset(dta->dt_name, 0, 12); + p = strrchr(path, '/'); + if(p != NULL) + { + strncpy(&dta->dt_name[0], ++p, 12); + *p = '\0'; + } + index = 0; + while((index < OPNFILES) && (cd_pd_handle[index].proc != run)) + index++; + ph = &cd_pd_handle[index]; + if((ph->proc == run) && (ph->handle == '_DTA') && (ph->dirs == NULL)) + memset(ph, 0, sizeof(struct pd_handle)); + if((ph->proc == run) && (ph->handle == '_DTA') + && (ph->dirs != NULL) && ph->max_dirs) + { + /* abnormal, directory not read totally before this command with the same PD */ + ph->nb_dirs = ph->dir_count = 0; + ph->end_dirs = ph->dirs; + } + else + { + index = 0; + while((index < OPNFILES) && (cd_pd_handle[index].proc != NULL)) + index++; + ph = &cd_pd_handle[index]; + if(ph->proc != NULL) + return(ENMFIL); /* not found */ + ph->handle = '_DTA'; + ph->max_dirs = 64; + ph->nb_dirs = ph->dir_count = 0; + ph->end_dirs = ph->dirs = (SUBDTA *)malloc(sizeof(SUBDTA) * ph->max_dirs); + if(ph->dirs == NULL) + return(ENMFIL); /* not found */ + memset(ph->dirs, 0, sizeof(SUBDTA) * ph->max_dirs); + ph->proc = run; + } + ph->long_filename = long_filename; + dta->dt_pos = index; + cd_disk_errno = 0; + ret = (long)iso9660_dir(&global_disk, path, hook_fsfirst); + if(ret == E_OK) + { + char name[12], filter[12]; + char *label = NULL; + SUBDTA *ps1 = ph->dirs; + ph->end_dirs = ps1; + int i = 0; + while(i < ph->nb_dirs) /* fix DOS with same names 8:3 */ + { + int j = 0, count = 0; + SUBDTA *ps2 = ph->dirs; + p = ps1->dt_fname; + while(j < ph->nb_dirs) + { + if(ps1 != ps2) + { + if(!strcmp(p, ps2->dt_fname)) + { + count++; + if(count < 10) + { + str2dir(ps2->dt_fname, name); + name[6] = '~'; + name[7] = (char)count + '0'; + dir2str(name, ps2->dt_fname); + } + else if(count < 100) + { + str2dir(ps2->dt_fname, name); + name[5] = '~'; + name[6] = (char)(count / 10) + '0'; + name[7] = (char)(count % 10) + '0'; + dir2str(name, ps2->dt_fname); + } + } + } + ps2 = (SUBDTA *)((unsigned long)ps2 + sizeof(SUBDTA) + (unsigned long)ps2->dt_len_lfname); + j++; + } + if(count) + { + str2dir(p, name); + name[6] = '~'; + name[7] = '0'; + dir2str(name, p); + } + ps1 = (SUBDTA *)((unsigned long)ps1 + sizeof(SUBDTA) + (unsigned long)ps1->dt_len_lfname); + i++; + } + if((attr & FA_VOL) && (path[0] == '/') && !path[1] + && (iso9660_label(&global_disk, &label, NULL) == E_OK) && (label != NULL)) + { + char name[12]; + builds(label, name); + free(label); + dta->dt_fattr = FA_VOL; + dir2str(name, dta->dt_fname); + if(ph->long_filename != NULL) + strncpy(ph->long_filename, label, MAX_NAME); + dta->dt_fileln = 0; + dta->dt_time = dta->dt_date = 0; + ret = E_OK; + } + else /* file or directory */ + { + ret = ENMFIL; /* not found */ + if(ph->nb_dirs) + { + SUBDTA *ps = ph->end_dirs; + builds(dta->dt_name, filter); + filter[11] = (char)dta->dt_attr; + while(ph->dir_count < ph->nb_dirs) + { + ph->dir_count++; + str2dir(ps->dt_fname, name); + name[11] = ps->dt_fattr; + if(match(filter, name)) + { + memcpy(&dta->dt_fattr, ps, sizeof(SUBDTA) - 2); + if(ph->long_filename != NULL) + strncpy(ph->long_filename, ps->dt_lfname, MAX_NAME); + ph->end_dirs = (SUBDTA *)((unsigned long)ps + sizeof(SUBDTA) + (unsigned long)ps->dt_len_lfname); + ret = E_OK; + break; + } + ps = (SUBDTA *)((unsigned long)ps + sizeof(SUBDTA) + (unsigned long)ps->dt_len_lfname); + } + } + } + } + if(((ph->dir_count >= ph->nb_dirs) || (ph->long_filename != NULL)) && (ph->dirs != NULL)) + { + free(ph->dirs); + ph->dirs = NULL; + } + if(ret != E_OK) + { + if(ph->dirs != NULL) + free(ph->dirs); + memset(ph, 0, sizeof(struct pd_handle)); + } + return(ret); +} + +static long dos2unix(char *path) +{ + char save_path[MAX_PATH + 1], original_subdir[MAX_NAME + 1]; + char *p, *p2; + int slash_count = 0; + long ret; + while((p = strrchr(path, '\\')) != NULL) + { + *p = '/'; + slash_count++; + } + if(!slash_count) + return(E_OK); + if((slash_count == 1) && (path[0] == '/')) /* main directory */ + return(E_OK); + strncpy(save_path, path, MAX_PATH); + if(path[0] == '/') + { + path[1] = '\0'; + slash_count--; + p = &save_path[1]; + } + else + { + path[0] = '\0'; + p = save_path; + } + while(slash_count > 0) + { + p2 = strchr(p, '/'); /* extract DOS subdir 8:3 */ + if(p2 == NULL) + return(EPTHNF); /* abnormal */ + *p2 = '\0'; + strcat(path, p); /* add 8:3 DOS subdir to unix path */ + if((ret = i_fsfirst(path, FA_SUBDIR, original_subdir)) != E_OK) + return(EPTHNF); /* not found */ + p = &p2[1]; /* next subdir or name */ + p2 = strrchr(path, '/'); + if((p2 != NULL) && (original_subdir != NULL)) + { + p2[1] = '\0'; + strcat(path, original_subdir); /* add unix subdir */ + strcat(path, "/"); + } + else /* abnormal */ + return(EPTHNF); + slash_count--; + } + strcat(path, p); + return(E_OK); +} + +long cd_dfree(long *buf, long driveno) +{ + long drive = (long)run->p_curdrv; + if(driveno) + drive = driveno - 1; + if(drive != global_disk.dev_id) + return(EDRIVE); /* for call default GEMDOS routine */ + buf[0] = 0; + buf[1] = global_disk.total_sectors / 2; + buf[2] = DISK_SECTOR_SIZE; + buf[3] = 2; +#ifdef DEBUG + kprint("cd_dfree(%d) = %d %d %d %d\r\n", driveno, buf[0], buf[1], buf[2], buf[3]); +#endif + return(E_OK); +} + +long cd_dcreate(const char *path) // xmkdir TOS404 0xE1965A +{ + long ret = check_drive(path); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_dcreate(%s)\r\n", path); +#endif + return(EACCDN); /* access denied */ +} + +long cd_ddelete(const char *path) // xrmdir TOS404 0xE198FA +{ + long ret = check_drive(path); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_dcreate(%s)\r\n", path); +#endif + return(EACCDN); /* access denied */ +} + +long cd_fcreate(const char *fname, long attr) // xcreate TOS404 0xE1AEF6 +{ + long ret = check_drive(fname); + if(attr); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_fcreate(%s, %d)\r\n", fname, attr); +#endif + return(EACCDN); /* access denied */ +} + +long cd_dsetpath(const char *fname) // xchdir TOS404 0xE19218 +{ + DTA *dta = (DTA *)run->p_xdta; + DTA dta_dsetpath; + char path[MAX_PATH]; + long ret = check_drive(fname); + if(ret != E_OK) + return(ret); + run->p_xdta = (void *)&dta_dsetpath; + memset(&dta_dsetpath, 0, sizeof(DTA)); + if(fname[1] == ':') + strcpy(path, fname + 2); + else + strcpy(path, fname); + ret = dos2unix(path); + run->p_xdta = (void *)dta; /* restore dta */ +#ifdef DEBUG + kprint("cd_dsetpath(%s => %s) = %d\r\n", fname, path, ret); +#endif + if(ret == E_OK) + strncpy(cur_path, fname, MAX_PATH); + return(ret); +} + +long cd_fopen(const char *fname, long mode) // xopen TOS404 0xE1AF84 +{ + DTA *dta = (DTA *)run->p_xdta; + DTA dta_fopen; + char path[MAX_PATH + 1], original_filename[MAX_NAME + 1]; + char *p; + long i = 0, index; +#ifdef USE_BDOS + long max = OPNFILES; +#else /* GEMDOS */ + long max = (long)run->max_handle; +#endif + cd_file_t file; + long ret = check_drive(fname); + if(ret != E_OK) + return(ret); + if(mode == 1) /* write */ + return(EACCDN); /* access denied */ + run->p_xdta = (void *)&dta_fopen; + memset(&dta_fopen, 0, sizeof(DTA)); + if(fname[1] == ':') + strcpy(path, fname + 2); + else + strcpy(path, fname); + if((ret = dos2unix(path)) != E_OK) + { + run->p_xdta = (void *)dta; /* restore dta */ +#ifdef DEBUG + kprint("cd_fopen(%s => %s, %d) = %d (dos2unix)\r\n", fname, path, mode, ret); +#endif + return(EPTHNF); + } + if((ret = i_fsfirst(path, FA_SYSTEM + FA_HIDDEN + FA_RO, original_filename)) != E_OK) + { + run->p_xdta = (void *)dta; /* restore dta */ +#ifdef DEBUG + kprint("cd_fopen(%s => %s, %d) = %d (i_fsfirst)\r\n", fname, path, mode, ret); +#endif + return(EFILNF); + } + if((original_filename != NULL) && ((p = strrchr(path, '/')) != NULL)) + { + p[1] = '\0'; + strcat(path, original_filename); + } + run->p_xdta = (void *)dta; /* restore dta */ + ret = ENHNDL; /* too many open files */ + for(i = NUMSTD; i < max; i++) + { +#ifdef USE_BDOS + if(!sft[i - NUMSTD].f_use) +#else /* GEMDOS */ + if(!run->p_handle[i]) +#endif + { + index = 0; + while((index < OPNFILES) && (cd_pd_handle[index].proc != NULL)) + index++; + if(cd_pd_handle[index].proc != NULL) + return(ENHNDL); /* too many open files */ +#ifdef USE_BDOS + sft[i - NUMSTD].f_ofd = NULL; + sft[i - NUMSTD].f_own = run; + sft[i - NUMSTD].f_use = 1; +#else /* GEMDOS */ + run->p_handle[i] = i; +#endif + cd_pd_handle[index].proc = run; + cd_pd_handle[index].handle = i; + file = &cd_pd_handle[index].file; + file->disk = &global_disk; + cd_disk_errno = 0; + ret = (long)iso9660_open(file, path); +#ifdef DEBUG + kprint("cd_fopen(%s => %s, %d) = %d\r\n", fname, path, mode, (ret < 0) ? ret : i); +#endif + break; + } + } + return((ret < 0) ? ret : i); +} + +long cd_fclose(long handle) // xclose TOS404 0xE1A9F4, ixclose TOS404 0xE1AA0A +{ + long index; + cd_file_t file; + long ret = search_handle(handle, &index); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_fclose(%d)\r\n", handle); +#endif +#ifdef USE_BDOS + sft[handle - NUMSTD].f_ofd = NULL; + sft[handle - NUMSTD].f_own = NULL; + sft[handle - NUMSTD].f_use = 0; +#else /* GEMDOS */ + run->p_handle[handle] = 0; +#endif + file = &cd_pd_handle[index].file; + file->disk = &global_disk; + iso9660_close(file); + memset(&cd_pd_handle[index], 0, sizeof(struct pd_handle)); + return(E_OK); +} + +long cd_fread(long handle, long count, void *buf) // xread TOS404 0xE1AD34 +{ + long index; + cd_file_t file; + long ret = search_handle(handle, &index); + if(ret != E_OK) + return(ret); + file = &cd_pd_handle[index].file; + file->disk = &global_disk; + if(count < 0) + return(ERANGE); + if(file->offset + (int)count > file->size) + count = (long)file->size - (long)file->offset; + ret = (long)iso9660_read(file, buf, (int)count); + if(ret >= 0) + file->offset += (int)count; +#ifdef DEBUG + kprint("cd_fread(%d, %d, 0x%08X) = %d\r\n", handle, count, buf, (ret < 0) ? ret : count); +#endif + return((ret < 0) ? ret : count); +} + +long cd_fwrite(long handle, long count, void *buf) // xwrite TOS404 0xE1ADFA +{ + long index; + long ret = search_handle(handle, &index); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_fwrite(%d, %d, 0x%08X)\r\n", handle, count, buf); +#endif + return(EACCDN); /* access denied */ +} + +long cd_fdelete(const char *fname) // xdelete TOS404 0xE1A18C +{ + long ret = check_drive(fname); +#ifdef DEBUG + kprint("cd_fdelete(%s)\r\n", fname); +#endif + if(ret == E_OK) + return(EACCDN); /* access denied */ + return(ret); +} + +long cd_fseek(long offset, long handle, long seekmode) // xlseek TOS404 0xE1B246 +{ + long index; + cd_file_t file; + long ret = search_handle(handle, &index); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_fseek(%d, %d, %d)\r\n", offset, handle, seekmode); +#endif + file = &cd_pd_handle[index].file; + file->disk = &global_disk; + switch(seekmode) + { + case 0: /* from begin */ + if((offset < 0) || (offset > (long)file->size)) + return(ERANGE); + file->offset = (int)offset; + break; + case 1: /* from current */ + if((file->offset + (int)offset < 0) || (file->offset + (int)offset > file->size)) + return(ERANGE); + file->offset += (int)offset; + break; + case 2: /* from end */ + if((file->size - (int)offset < 0) || (file->size - (int)offset > file->size)) + return(ERANGE); + file->offset = file->size - (int)offset; + break; + default: + return(ERANGE); + } + return((long)file->offset); +} + +long cd_fattrib(const char *filename, long wflag, long attrib) // xchmod TOS404 0xE1A0D4 +{ + long ret = check_drive(filename); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_fattrib(%s, %d, %d)\r\n", filename, wflag, attrib); +#endif + switch(wflag) + { + case 0: break; + case 1: return(EACCDN); /* access denied */ + default: return(ERANGE); + } + return(1); +} + +long cd_dgetpath(char *path, long driveno) // xgetdir TOS404 0xE1930E +{ + long drive = (long)run->p_curdrv; + if(driveno) + drive = driveno - 1; + if(drive != global_disk.dev_id) + return(EDRIVE); /* for call default GEMDOS routine */ + strncpy(path, cur_path, MAX_PATH); +#ifdef DEBUG + kprint("cd_dgetpath(%s, %d)\r\n", path, driveno); +#endif + return(E_OK); +} + +long cd_pexec(long mode, const char *prg, const char *cmdl, const char *envp) +{ + PD *pd; + PGMHDR01 header; + short magic; + unsigned char *lastcp, *cp; + long ret, handle, needed, max, relst, len; + if((mode != PE_LOADGO) && (mode != PE_LOAD)) + return(EDRIVE); /* for call default GEMDOS routine */ + ret = check_drive(prg); + if(ret != E_OK) + return(ret); +#ifdef DEBUG + kprint("cd_pexec(%d, %s, %s, %s)\r\n", mode, (prg != NULL) ? prg : "NULL", (cmdl != NULL) ? cmdl : "NULL", (envp != NULL) ? envp : "NULL"); +#endif + handle = cd_fopen(prg, 0); + if(handle < 0) + return(handle); + ret = cd_fread(handle, 2, &magic); + if(ret >= 0) + { + /* check and read program header */ + if(magic == 0x601A) + ret = cd_fread(handle, sizeof(PGMHDR01), &header); + else + ret = EPLFMT; + } + if(ret < sizeof(PGMHDR01)) + ret = EPLFMT; + if(ret < 0) + { + cd_fclose(handle); +#ifdef DEBUG + kprint("cd_pexec() = %d\r\n", ret); +#endif + return(ret); + } + pd = (PD *)Pexec(PE_BASEPAGE, prg, cmdl, envp); /* create basepage */ + if((long)pd < 0) + { + cd_fclose(handle); +#ifdef DEBUG + kprint("cd_pexec() = %d\r\n", (long)pd); +#endif + return((long)pd); + } + max = pd->p_hitpa - pd->p_lowtpa; + needed = header.h01_tlen + header.h01_dlen + header.h01_blen + sizeof(PD); + if(needed > max) + { + ret = ENSMEM; + goto fail; + } + pd->p_flags = header.h01_flags; + pd->p_tlen = header.h01_tlen; + pd->p_dlen = header.h01_dlen; + pd->p_blen = header.h01_blen; + pd->p_tbase = (long)&pd[1]; /* 1st byte after PD */ + pd->p_dbase = pd->p_tbase + pd->p_tlen; + pd->p_bbase = pd->p_dbase + pd->p_dlen; +#ifdef DEBUG + kprint("cd_pexec pd 0x%08X, p_tbase 0x%08X, p_dbase 0x%08X, p_bbase 0x%08X, p_hitpa 0x%08X\r\n", pd, pd->p_tbase, pd->p_dbase, pd->p_bbase, pd->p_hitpa); +#endif + ret = cd_fread(handle, pd->p_tlen + pd->p_dlen, (void *)pd->p_tbase); /* read in the program file (text and data) */ + if(ret < 0) + { +fail: +#ifdef DEBUG + kprint("cd_pexec() = %d\r\n", ret); +#endif + Mfree(pd->p_env); + Mfree(pd->p_lowtpa); + cd_fclose(handle); + return(ret); + } + if(!header.h01_abs) + { + ret = cd_fseek(header.h01_slen, handle, 1); /* seek symbols */ + if(ret < 0) + goto fail; + ret = cd_fread(handle, (long)sizeof(relst), &relst); + if(ret < 0) + goto fail; + if(relst) + { + cp = (unsigned char *)pd->p_tbase + relst; + if((cp < (unsigned char *)pd->p_tbase) || (cp >= (unsigned char *)pd->p_bbase)) /* make sure we didn't wrap memory or overrun the bss */ + { + ret = EPLFMT; + goto fail; + } + *((long *)cp) += pd->p_tbase; /* 1st fixup */ + lastcp = cp; + len = pd->p_hitpa - pd->p_bbase; + do + { + ret = cd_fread(handle, len, (void *)pd->p_bbase); /* read in more relocation info */ + if(ret < 0) + goto fail; + ret = pgfix01(ret, (unsigned char *)pd->p_tbase, (unsigned char *)pd->p_bbase, &lastcp); + } + while(ret > 0); + if(ret < 0) + goto fail; + } + /* clear the bss or the whole heap */ + if(header.h01_flags & PF_FASTLOAD) /* clear only the bss */ + memset((void *)pd->p_bbase, 0, pd->p_blen); + else + memset((void *)pd->p_bbase, 0, (long)pd->p_hitpa - (long)pd->p_bbase); /* clear the whole heap */ + } + cd_fclose(handle); +#ifdef COLDFIRE +#if (__GNUC__ > 3) + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5485\n\t"); /* flush from CF68KLIB */ +#else + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5200\n\t"); /* flush from CF68KLIB */ +#endif +#else /* 68060 */ + asm volatile (" cpusha BC\n\t"); +#endif /* COLDFIRE */ +#ifdef DEBUG + kprint("cd_pexec pd 0x%08X\r\n", pd); +#endif + return((long)pd); +} + +void cd_pterm(void) +{ + long index; + for(index = 0; index < OPNFILES; index++) + { + struct pd_handle *ph = &cd_pd_handle[index]; + if(ph->proc == run) + { +#ifdef DEBUG + kprint("cd_pterm()\r\n"); +#endif + if(ph->handle == '_DTA') + { + if(ph->dirs != NULL) + free(ph->dirs); + } + else + { + cd_file_t file = &ph->file; + file->disk = &global_disk; + iso9660_close(file); + } + memset(ph, 0, sizeof(struct pd_handle)); + } + } +} + +long cd_fsfirst(const char *filename, long attr) // xsfirst TOS404 0xE19ABE +{ + char path[MAX_PATH]; + long ret = check_drive(filename); + if(ret != E_OK) + return(ret); + if(filename[1] == ':') + strcpy(path, filename + 2); + else + strcpy(path, filename); + if(dos2unix(path) != E_OK) + return(EPTHNF); +#ifdef DEBUG + kprint("cd_fsfirst(%s => %s, 0x%02X) = ", filename, path, attr); +#endif + ret = i_fsfirst(path, attr, NULL); +#ifdef DEBUG + kprint("%d\r\n", ret); +#endif + return(ret); +} + +long cd_fsnext(void) // xsnext TOS404 0xE19C54 +{ + DTA *dta = (DTA *)run->p_xdta; + long index; + for(index = 0; index < OPNFILES; index++) + { + if((cd_pd_handle[index].proc == run) && (cd_pd_handle[index].handle == '_DTA')) + { + struct pd_handle *ph = &cd_pd_handle[index]; + SUBDTA *ps = ph->end_dirs; + char name[12], filter[12]; + long ret = ENMFIL; /* not found */ + if(ph->dirs == NULL) + { + memset(ph, 0, sizeof(struct pd_handle)); +#ifdef DEBUG +// kprint("cd_fsnext() = %d\r\n", ret); +#endif + return(ret); /* not found */ + } + builds(dta->dt_name, filter); + filter[11] = (char)dta->dt_attr; + while(ph->dir_count < ph->nb_dirs) + { + ph->dir_count++; + str2dir(ps->dt_fname, name); + name[11] = ps->dt_fattr; + if(match(filter, name)) + { + memcpy(&dta->dt_fattr, ps, sizeof(SUBDTA) - 2); + ph->end_dirs = (SUBDTA *)((unsigned long)ps + sizeof(SUBDTA) + (unsigned long)ps->dt_len_lfname); + ret = E_OK; + break; + } + ps = (SUBDTA *)((unsigned long)ps + sizeof(SUBDTA) + (unsigned long)ps->dt_len_lfname); + } + if(ret != E_OK) + { + free(ph->dirs); + memset(ph, 0, sizeof(struct pd_handle)); +#ifdef DEBUG +// kprint("cd_fsnext() = %d\r\n", ret); +#endif + } + return(ret); + } + } + return(EDRIVE); /* for call default GEMDOS routine */ +} + +long cd_frename(const char *oldname, const char *newname) // xrename TOS404 0xE1A356 +{ + long ret = check_drive(oldname); + if(ret == E_OK) + return(EACCDN); /* access denied */ + return(ret); +} + +long cd_fdatime(short *timeptr, long handle, long wflag) // xdatime TOS404 0xE1B498 +{ + long index; + cd_file_t file; + long ret = search_handle(handle, &index); + if(ret != E_OK) + return(ret); + switch(wflag) + { + case 0: break; + case 1: return(EACCDN); /* access denied */ + default: return(ERANGE); + } + file = &cd_pd_handle[index].file; + timeptr[0] = (unsigned short)file->time; /* time */ + timeptr[1] = (unsigned short)(file->time >> 16); /* date */ + return(E_OK); +} + +// xgetdta TOS404 0xE1B57C +// xsetdta TOS404 0xE1B5B4 +// xsetdrv TOS404 0xE1B5F0 +// xgetdrv TOS404 0xE1B644 diff --git a/flash.tos/drivers/cd/cd_dos.h b/flash.tos/drivers/cd/cd_dos.h new file mode 100644 index 0000000..4a152e7 --- /dev/null +++ b/flash.tos/drivers/cd/cd_dos.h @@ -0,0 +1,52 @@ +/* + * This file 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 file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _CD_DOS_H +#define _CD_DOS_H + +struct cd_file +{ + struct cd_disk *disk; + int offset; + int size; + unsigned int time; + void *data; + /* This is called when a sector is read. Used only for a disk device. */ + void (*read_hook)(unsigned sector, unsigned offset, unsigned length); +}; + +typedef struct cd_file *cd_file_t; + +long cd_dfree(long *buf, long driveno); +long cd_dcreate(const char *path); +long cd_ddelete(const char *path); +long cd_dsetpath(const char *fname); +long cd_fcreate(const char *fname, long attr); +long cd_fopen(const char *fname, long mode); +long cd_fclose(long handle); +long cd_fread(long handle, long count, void *buf); +long cd_fwrite(long handle, long count, void *buf); +long cd_fdelete(const char *fname); +long cd_fseek(long offset, long handle, long seekmode); +long cd_fattrib(const char *filename, long wflag, long attrib); +long cd_pexec(long mode, const char *prg, const char *cmdl, const char *envp); +void cd_pterm(void); +long cd_fsfirst(const char *filename, long attr); +long cd_fsnext(void); +long cd_frename(const char *oldname, const char *newname); +long cd_fdatime(short *timeptr, long handle, long wflag); + +#endif /* _CD_DOS_H */ diff --git a/flash.tos/drivers/cd/cd_iso.c b/flash.tos/drivers/cd/cd_iso.c new file mode 100644 index 0000000..cb10326 --- /dev/null +++ b/flash.tos/drivers/cd/cd_iso.c @@ -0,0 +1,951 @@ +/* cd_iso.c - iso9660 implementation with extensions: SUSP, Rock Ridge. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ +/* Didier Mequignon - Removed nested functions who crashes with GCC68K (code on stack) */ + +#include /* for malloc */ +#include +#include "gemerror.h" +#include "cd_dos.h" +#include "cd_disk.h" +#include "cd_iso.h" + +#define ISO9660_FSTYPE_DIR 0040000 +#define ISO9660_FSTYPE_REG 0100000 +#define ISO9660_FSTYPE_SYMLINK 0120000 +#define ISO9660_FSTYPE_MASK 0170000 + +#define ISO9660_LOG2_BLKSZ 2 +#define ISO9660_BLKSZ 2048 + +#define ISO9660_RR_DOT 2 +#define ISO9660_RR_DOTDOT 4 + +#define ISO9660_VOLDESC_BOOT 0 +#define ISO9660_VOLDESC_PRIMARY 1 +#define ISO9660_VOLDESC_SUPP 2 +#define ISO9660_VOLDESC_PART 3 +#define ISO9660_VOLDESC_END 255 + +#define LONG_MAX 2147483647 + +/* The head of a volume descriptor. */ +struct iso9660_voldesc +{ + unsigned char type; + unsigned char magic[5]; + unsigned char version; +} __attribute__ ((packed)); + +/* A directory entry. */ +struct iso9660_dir +{ + unsigned char len; + unsigned char ext_sectors; + unsigned long first_sector; + unsigned long first_sector_be; + unsigned long size; + unsigned long size_be; + unsigned char year; + unsigned char month; + unsigned char day; + unsigned char hour; + unsigned char minute; + unsigned char second; + unsigned char time_offset; + unsigned char flags; + unsigned char unused2[6]; + unsigned char namelen; +} __attribute__ ((packed)); + +struct iso9660_date +{ + unsigned char year[4]; + unsigned char month[2]; + unsigned char day[2]; + unsigned char hour[2]; + unsigned char minute[2]; + unsigned char second[2]; + unsigned char hundredth[2]; + unsigned char offset; +} __attribute__ ((packed)); + +/* The primary volume descriptor. Only little endian is used. */ +struct iso9660_primary_voldesc +{ + struct iso9660_voldesc voldesc; + unsigned char unused1[33]; + unsigned char volname[32]; + unsigned char unused2[8]; + unsigned long total_sectors; + unsigned long total_sectors_be; + unsigned char escape[32]; + unsigned char unused3[12]; + unsigned long path_table_size; + unsigned char unused4[4]; + unsigned long path_table; + unsigned char unused5[12]; + struct iso9660_dir rootdir; + unsigned char unused6[624]; + struct iso9660_date created; + struct iso9660_date modified; +} __attribute__ ((packed)); + +/* A single entry in the path table. */ +struct iso9660_path +{ + unsigned char len; + unsigned char sectors; + unsigned long first_sector; + unsigned short parentdir; + unsigned char name[0]; +} __attribute__ ((packed)); + +/* An entry in the System Usage area of the directory entry. */ +struct iso9660_susp_entry +{ + unsigned char sig[2]; + unsigned char len; + unsigned char version; + unsigned char data[0]; +} __attribute__ ((packed)); + +/* The CE entry. This is used to describe the next block where data can be found. */ +struct iso9660_susp_ce +{ + struct iso9660_susp_entry entry; + unsigned long blk; + unsigned long blk_be; + unsigned long off; + unsigned long off_be; + unsigned long len; + unsigned long len_be; +} __attribute__ ((packed)); + +struct iso9660_data +{ + struct iso9660_primary_voldesc voldesc; + cd_disk_t disk; + unsigned int first_sector; + int rockridge; + int susp_skip; + int joliet; +}; + +struct iso9660_node +{ + struct iso9660_data *data; + unsigned int size; + unsigned int blk; + unsigned int dir_blk; + unsigned int dir_off; + unsigned int time; +}; + +typedef struct iso9660_node *iso9660_node_t; + +enum iso9660_fileype +{ + FSHELP_UNKNOWN, + FSHELP_REG, + FSHELP_DIR, + FSHELP_SYMLINK, + FSHELP_HIDDEN +}; + +struct params_iterate_file +{ + enum iso9660_fileype *type; + char *name; + iso9660_node_t currnode; + iso9660_node_t oldnode; +}; + +#define FSHELP_CASE_INSENSITIVE 0x100 +#define FSHELP_TYPE_MASK 0xff +#define FSHELP_FLAGS_MASK 0x100 + +extern char *strndup(char const *s, int n); +extern unsigned short swap_short(unsigned short val); +extern unsigned long swap_long(unsigned long val); + +#define le_to_cpu16(x) swap_short(x) +#define le_to_cpu32(x) swap_long(x) +#define be_to_cpu16(x) (x) +#define be_to_cpu32(x) (x) + +inline void *zalloc(int size) +{ + void *ret = malloc(size); + if(!ret) + return NULL; + memset(ret, 0, size); + return ret; +} + +extern int cd_disk_errno; + +static int iso9660_iterate_dir(iso9660_node_t dir, int (*hook)(), void *params); +static char *iso9660_read_symlink(iso9660_node_t node); + +static int file_iterate(const char *filename, enum iso9660_fileype filetype, iso9660_node_t node, void *params) +{ + struct params_iterate_file *params_iterate = params; + if(filetype == FSHELP_UNKNOWN || (strcmp(params_iterate->name, filename) + && (! (filetype & FSHELP_CASE_INSENSITIVE) || strncasecmp(params_iterate->name, filename, LONG_MAX)))) + { + free(node); + return 0; + } + /* The node is found, stop iterating over the nodes. */ + *params_iterate->type = filetype & ~FSHELP_CASE_INSENSITIVE; + params_iterate->oldnode = params_iterate->currnode; + params_iterate->currnode = node; + return 1; +} + +static int find_file(const char *currpath, iso9660_node_t currroot, iso9660_node_t *currfound, iso9660_node_t rootnode, enum iso9660_fileype *foundtype, int *symlinknest) +{ + char fpath[strlen(currpath) + 1]; + char *next; + enum iso9660_fileype type = FSHELP_DIR; + struct params_iterate_file params_iterate = + { + .type = &type, + .name = fpath, + .currnode = currroot, + .oldnode = currroot, + }; + strncpy(fpath, currpath, strlen(currpath) + 1); + /* Remove all leading slashes. */ + while(*params_iterate.name == '/') + params_iterate.name++; + if(!*params_iterate.name) + { + *currfound = params_iterate.currnode; + return 0; + } + while(1) + { + int found; + /* Extract the actual part from the pathname. */ + next = strchr(params_iterate.name, '/'); + if(next) + { + /* Remove all leading slashes. */ + while(*next == '/') + *(next++) = '\0'; + } + /* At this point it is expected that the current node is a directory, check if this is true. */ + if(type != FSHELP_DIR) + { + if(params_iterate.currnode != rootnode && params_iterate.currnode != currroot) + free(params_iterate.currnode); + return(cd_disk_errno = EPTHNF); /* not a directory */ + } + /* Iterate over the directory. */ + found = iso9660_iterate_dir(params_iterate.currnode, file_iterate, ¶ms_iterate); + if(!found) + { + if(cd_disk_errno) + return cd_disk_errno; + break; + } + /* Read in the symlink and follow it. */ + if(type == FSHELP_SYMLINK) + { + char *symlink; + /* Test if the symlink does not loop. */ + if(++(*symlinknest) == 8) + { + if(params_iterate.currnode != rootnode && params_iterate.currnode != currroot) + free(params_iterate.currnode); + if(params_iterate.oldnode != rootnode && params_iterate.oldnode != currroot) + free(params_iterate.oldnode); + return(cd_disk_errno = ERANGE); /* too deep nesting of symlinks */ + } + symlink = iso9660_read_symlink(params_iterate.currnode); + if(params_iterate.currnode != rootnode && params_iterate.currnode != currroot) + free(params_iterate.currnode); + if(!symlink) + { + if(params_iterate.oldnode != rootnode && params_iterate.oldnode != currroot) + free(params_iterate.oldnode); + return cd_disk_errno; + } + /* The symlink is an absolute path, go back to the root inode. */ + if(symlink[0] == '/') + { + if(params_iterate.oldnode != rootnode && params_iterate.oldnode != currroot) + free(params_iterate.oldnode); + params_iterate.oldnode = rootnode; + } + /* Lookup the node the symlink points to. */ + find_file(symlink, params_iterate.oldnode, ¶ms_iterate.currnode, rootnode, foundtype, symlinknest); + type = *foundtype; + free(symlink); + if(cd_disk_errno) + { + if(params_iterate.oldnode != rootnode && params_iterate.oldnode != currroot) + free(params_iterate.oldnode); + return cd_disk_errno; + } + } + if(params_iterate.oldnode != rootnode && params_iterate.oldnode != currroot) + free(params_iterate.oldnode); + /* Found the node! */ + if(!next || *next == '\0') + { + *currfound = params_iterate.currnode; + *foundtype = type; + return 0; + } + params_iterate.name = next; + } + return(cd_disk_errno = EFILNF); +} + +/* Lookup the node PATH. The node ROOTNODE describes the root of the + directory tree. The node found is returned in FOUNDNODE, which is + either a ROOTNODE or a new malloc'ed node. ITERATE_DIR is used to + iterate over all directory entries in the current node. + READ_SYMLINK is used to read the symlink if a node is a symlink. + EXPECTTYPE is the type node that is expected by the called, an + error is generated if the node is not of the expected type. Make + sure you use the NESTED_FUNC_ATTR macro for HOOK, this is required + because GCC has a nasty bug when using regparm=3. */ +static int iso9660_find_file(const char *path, iso9660_node_t rootnode, iso9660_node_t *foundnode, + enum iso9660_fileype expecttype) +{ + int err; + enum iso9660_fileype foundtype = FSHELP_DIR; + int symlinknest = 0; + if(!path || path[0] != '/') + return(cd_disk_errno = EPTHNF); + err = find_file(path, rootnode, foundnode, rootnode, &foundtype, &symlinknest); + if(err) + return err; + /* Check if the node that was found was of the expected type. */ + if(expecttype == FSHELP_REG && foundtype != expecttype) + return(cd_disk_errno = EFILNF); /* not a regular file */ + else if(expecttype == FSHELP_DIR && foundtype != expecttype) + return(cd_disk_errno = EPTHNF); /* not a directory */ + return 0; +} + +static unsigned char *iso9660_utf16_to_utf8(unsigned char *dest, unsigned short *src, int size) +{ + unsigned long code_high = 0; + while (size--) + { + unsigned long code = *src++; + if(code_high) + { + if(code >= 0xDC00 && code <= 0xDFFF) + { + /* Surrogate pair. */ + code = ((code_high - 0xD800) << 12) + (code - 0xDC00) + 0x10000; + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + *dest++ = '?'; /* error */ + code_high = 0; + } + else + { + if (code <= 0x007F) + *dest++ = code; + else if (code <= 0x07FF) + { + *dest++ = (code >> 6) | 0xC0; + *dest++ = (code & 0x3F) | 0x80; + } + else if (code >= 0xD800 && code <= 0xDBFF) + { + code_high = code; + continue; + } + else if (code >= 0xDC00 && code <= 0xDFFF) + *dest++ = '?'; /* error */ + else if (code < 0x10000) + { + *dest++ = (code >> 12) | 0xE0; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + else + { + *dest++ = (code >> 18) | 0xF0; + *dest++ = ((code >> 12) & 0x3F) | 0x80; + *dest++ = ((code >> 6) & 0x3F) | 0x80; + *dest++ = (code & 0x3F) | 0x80; + } + } + } + return dest; +} + +static char *iso9660_convert_string(unsigned short *us, int len) +{ + int i; + char *p = malloc(len * 4 + 1); + if(!p) + return p; + for(i = 0; i < len; us[i] = be_to_cpu16(us[i]), i++); + *iso9660_utf16_to_utf8((unsigned char *)p, us, len) = '\0'; + return p; +} + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for every entry. */ +static int iso9660_susp_iterate(struct iso9660_data *data, int sua_block, int sua_pos, int sua_size) +{ + char *sua; + struct iso9660_susp_entry *entry; + /* Load a part of the System Usage Area. */ + sua = malloc(sua_size); + if(!sua) + return cd_disk_errno; + if(cd_disk_read(data->disk, sua_block, sua_pos, sua_size, sua)) + return cd_disk_errno; + entry = (struct iso9660_susp_entry *)sua; + for(; (char *) entry < (char *)sua + sua_size - 1; entry = (struct iso9660_susp_entry *)((char *)entry + entry->len)) + { + /* The last entry. */ + if(strncmp ((char *)entry->sig, "ST", 2) == 0) + break; + /* Additional entries are stored elsewhere. */ + if(strncmp((char *)entry->sig, "CE", 2) == 0) + { + struct iso9660_susp_ce *ce = (struct iso9660_susp_ce *)entry; + sua_size = le_to_cpu32(ce->len); + sua_pos = le_to_cpu32(ce->off); + sua_block = le_to_cpu32(ce->blk) << ISO9660_LOG2_BLKSZ; + free(sua); + sua = malloc(sua_size); + if(!sua) + return cd_disk_errno; + if(cd_disk_read(data->disk, sua_block, sua_pos, sua_size, sua)) + return cd_disk_errno; + entry = (struct iso9660_susp_entry *)sua; + } + /* The "ER" entry is used to detect extensions. The `IEEE_P1285' extension means Rock ridge. */ + if(strncmp((char *)entry->sig, "ER", 2) == 0) + { + data->rockridge = 1; + free(sua); + return 0; + } + } + free(sua); + return 0; +} + +static struct iso9660_data *iso9660_mount(cd_disk_t disk) +{ + struct iso9660_data *data = 0; + struct iso9660_dir rootdir; + int sua_pos, sua_size, block; + char *sua; + struct iso9660_susp_entry *entry; + struct iso9660_primary_voldesc *voldesc = NULL; + voldesc = malloc(sizeof(struct iso9660_primary_voldesc)); + if(voldesc == NULL) + return 0; + data = zalloc(sizeof(struct iso9660_data)); + if(data == NULL) + { + free(voldesc); + return 0; + } + data->disk = disk; + block = 16; + do + { + int copy_voldesc = 0; + /* Read the superblock. */ + if(cd_disk_read(disk, block << ISO9660_LOG2_BLKSZ, 0, sizeof(struct iso9660_primary_voldesc), (char *)voldesc)) + { + cd_disk_errno = EMEDIA; /* not a ISO9660 filesystem */ + goto fail; + } + if(strncmp((char *)voldesc->voldesc.magic, "CD001", 5) != 0) + { + cd_disk_errno = EMEDIA; /* not a ISO9660 filesystem */ + goto fail; + } + if(voldesc->voldesc.type == ISO9660_VOLDESC_PRIMARY) + copy_voldesc = 1; + else if((voldesc->voldesc.type == ISO9660_VOLDESC_SUPP) && (voldesc->escape[0] == 0x25) && (voldesc->escape[1] == 0x2f) + && ((voldesc->escape[2] == 0x40) || (voldesc->escape[2] == 0x43) || (voldesc->escape[2] == 0x45))) /* UCS-2 Level 1-2-3 */ + { + copy_voldesc = 1; + data->joliet = 1; + } + if(copy_voldesc) + memcpy((char *)&data->voldesc, (char *)voldesc, sizeof(struct iso9660_primary_voldesc)); + block++; + } + while(voldesc->voldesc.type != ISO9660_VOLDESC_END); + free(voldesc); + voldesc = NULL; + /* Read the system use area and test it to see if SUSP is supported. */ + if(cd_disk_read(disk, (le_to_cpu32(data->voldesc.rootdir.first_sector) << ISO9660_LOG2_BLKSZ), 0, sizeof(rootdir), (char *)&rootdir)) + { + cd_disk_errno = EMEDIA; /* not a ISO9660 filesystem */ + goto fail; + } + sua_pos = sizeof(rootdir) + rootdir.namelen + (rootdir.namelen % 2) - 1; + sua_size = rootdir.len - sua_pos; + sua = malloc(sua_size + 1); + if(sua == NULL) + goto fail; + if(cd_disk_read(disk, (le_to_cpu32 (data->voldesc.rootdir.first_sector) << ISO9660_LOG2_BLKSZ), sua_pos, sua_size, sua)) + { + free(sua); + cd_disk_errno = EMEDIA; /* not a ISO9660 filesystem */ + goto fail; + } + entry = (struct iso9660_susp_entry *)sua; + /* Test if the SUSP protocol is used on this filesystem. */ + if(strncmp((char *)entry->sig, "SP", 2) == 0) + { + /* The 2nd data byte stored how many bytes are skipped every time to get to the SUA (System Usage Area). */ + data->susp_skip = entry->data[2]; + entry = (struct iso9660_susp_entry *)((char *)entry + entry->len); + /* Iterate over the entries in the SUA area to detect extensions. */ + if(iso9660_susp_iterate(data, (le_to_cpu32(data->voldesc.rootdir.first_sector) << ISO9660_LOG2_BLKSZ), sua_pos, sua_size)) + { + free(sua); + goto fail; + } + } + free(sua); + return data; +fail: + free(data); + if(voldesc != NULL) + free(voldesc); + return 0; +} + +static char *add_part(char *symlink, const char *part, int len) /* Extend the symlink. */ +{ + int size = strlen(symlink); + char *new_symlink = realloc(symlink, size + len + 1); + if(!new_symlink) + return NULL; + strncat(new_symlink, part, len); + return new_symlink; +} + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for every entry. */ +static int iso9660_susp_iterate_sl(struct iso9660_data *data, int sua_block, int sua_pos, int sua_size, char *symlink, int *addslash) +{ + char *sua; + struct iso9660_susp_entry *entry; + /* Load a part of the System Usage Area. */ + sua = malloc(sua_size); + if(!sua) + return cd_disk_errno; + if(cd_disk_read(data->disk, sua_block, sua_pos, sua_size, sua)) + return cd_disk_errno; + entry = (struct iso9660_susp_entry *)sua; + for(; (char *) entry < (char *)sua + sua_size - 1; entry = (struct iso9660_susp_entry *)((char *)entry + entry->len)) + { + /* The last entry. */ + if(strncmp ((char *)entry->sig, "ST", 2) == 0) + break; + /* Additional entries are stored elsewhere. */ + if(strncmp((char *)entry->sig, "CE", 2) == 0) + { + struct iso9660_susp_ce *ce = (struct iso9660_susp_ce *)entry; + sua_size = le_to_cpu32(ce->len); + sua_pos = le_to_cpu32(ce->off); + sua_block = le_to_cpu32(ce->blk) << ISO9660_LOG2_BLKSZ; + free(sua); + sua = malloc(sua_size); + if(!sua) + return cd_disk_errno; + if(cd_disk_read(data->disk, sua_block, sua_pos, sua_size, sua)) + return cd_disk_errno; + entry = (struct iso9660_susp_entry *)sua; + } + if(strncmp("SL", (char *)entry->sig, 2) == 0) + { + unsigned int pos = 1; + /* The symlink is not stored as a POSIX symlink, translate it. */ + while(pos < le_to_cpu32(entry->len)) + { + if(*addslash) + { + symlink = add_part(symlink, "/", 1); + *addslash = 0; + } + /* The current position is the `Component Flag'. */ + switch(entry->data[pos] & 30) + { + case 0: + { + /* The data on pos + 2 is the actual data, pos + 1 is the length. Both are part of the `Component Record'. */ + symlink = add_part(symlink, (char *)&entry->data[pos + 2], entry->data[pos + 1]); + if((entry->data[pos] & 1)) + *addslash = 1; + break; + } + case 2: symlink = add_part(symlink, "./", 2); break; + case 4: symlink = add_part(symlink, "../", 3); break; + case 8: symlink = add_part(symlink, "/", 1); break; + } + /* In pos + 1 the length of the `Component Record' is stored. */ + pos += entry->data[pos + 1] + 2; + } + /* Check if `realloc' failed. */ + if(cd_disk_errno) + { + free(sua); + return 0; + } + } + } + free(sua); + return 0; +} + +static char *iso9660_read_symlink(iso9660_node_t node) +{ + struct iso9660_dir dirent; + int sua_off, sua_size, addslash = 0; + char *symlink = NULL; + if(cd_disk_read(node->data->disk, node->dir_blk, node->dir_off, sizeof(dirent), (char *)&dirent)) + return NULL; + sua_off = (sizeof (dirent) + dirent.namelen + 1 - (dirent.namelen % 2) + node->data->susp_skip); + sua_size = dirent.len - sua_off; + symlink = malloc(1); + if(!symlink) + return NULL; + *symlink = '\0'; + if(iso9660_susp_iterate_sl(node->data, node->dir_blk, node->dir_off + sua_off, sua_size, symlink, &addslash)) + { + free(symlink); + return NULL; + } + return symlink; +} + +/* Iterate over the susp entries, starting with block SUA_BLOCK on the + offset SUA_POS with a size of SUA_SIZE bytes. Hook is called for every entry. */ +static int iso9660_susp_iterate_dir(struct iso9660_data *data, int sua_block, int sua_pos, int sua_size, + char *filename, enum iso9660_fileype *type, unsigned int *filename_alloc) +{ + char *sua; + struct iso9660_susp_entry *entry; + /* Load a part of the System Usage Area. */ + sua = malloc(sua_size); + if(!sua) + return cd_disk_errno; + if(cd_disk_read(data->disk, sua_block, sua_pos, sua_size, sua)) + return cd_disk_errno; + entry = (struct iso9660_susp_entry *)sua; + for(; (char *) entry < (char *)sua + sua_size - 1; entry = (struct iso9660_susp_entry *)((char *)entry + entry->len)) + { + /* The last entry. */ + if(strncmp ((char *)entry->sig, "ST", 2) == 0) + break; + /* Additional entries are stored elsewhere. */ + if(strncmp((char *)entry->sig, "CE", 2) == 0) + { + struct iso9660_susp_ce *ce = (struct iso9660_susp_ce *)entry; + sua_size = le_to_cpu32(ce->len); + sua_pos = le_to_cpu32(ce->off); + sua_block = le_to_cpu32(ce->blk) << ISO9660_LOG2_BLKSZ; + free(sua); + sua = malloc(sua_size); + if(!sua) + return cd_disk_errno; + if(cd_disk_read(data->disk, sua_block, sua_pos, sua_size, sua)) + return cd_disk_errno; + entry = (struct iso9660_susp_entry *)sua; + } + /* The filename in the rock ridge entry. */ + if(strncmp("NM", (char *)entry->sig, 2) == 0) + { + /* The flags are stored at the data position 0, here the filename type is stored. */ + if(entry->data[0] & ISO9660_RR_DOT) + filename = "."; + else if(entry->data[0] & ISO9660_RR_DOTDOT) + filename = ".."; + else + { + int size = 1; + if(filename) + { + size += strlen(filename); + realloc(filename, strlen(filename) + entry->len); + } + else + { + size = entry->len - 5; + filename = zalloc(size + 1); + } + *filename_alloc = 1; + strncpy(filename, (char *)&entry->data[1], size); + filename[size] = '\0'; + } + } + /* The mode information (st_mode). */ + else if(strncmp((char *)entry->sig, "PX", 2) == 0) + { + /* At position 0 of the PX record the st_mode information is stored (little-endian). */ + unsigned long mode = ((entry->data[0] + (entry->data[1] << 8)) & ISO9660_FSTYPE_MASK); + switch(mode) + { + case ISO9660_FSTYPE_DIR: *type = FSHELP_DIR; break; + case ISO9660_FSTYPE_REG: *type = FSHELP_REG; break; + case ISO9660_FSTYPE_SYMLINK: *type = FSHELP_SYMLINK; break; + default: *type = FSHELP_UNKNOWN; break; + } + } + } + free(sua); + return 0; +} + +static int iso9660_iterate_dir(iso9660_node_t dir, int (*hook)(), void *params) +{ + struct iso9660_dir dirent; + unsigned int offset = 0, filename_alloc = 0; + char *filename; + enum iso9660_fileype type; + while(offset < dir->size) + { + if(cd_disk_read(dir->data->disk, (dir->blk << ISO9660_LOG2_BLKSZ) + offset / DISK_SECTOR_SIZE, offset % DISK_SECTOR_SIZE, sizeof(dirent), (char *)&dirent)) + return 0; + /* The end of the block, skip to the next one. */ + if(!dirent.len) + { + offset = (offset / ISO9660_BLKSZ + 1) * ISO9660_BLKSZ; + continue; + } + { + int dot = 0; + char name[dirent.namelen + 1]; + int nameoffset = offset + sizeof(dirent); + struct iso9660_node *node; + int sua_off = (sizeof(dirent) + dirent.namelen + 1 - (dirent.namelen % 2)); + int sua_size = dirent.len - sua_off; + sua_off += offset + dir->data->susp_skip; + filename = 0; + filename_alloc = 0; + type = FSHELP_UNKNOWN; + if(dir->data->rockridge + && iso9660_susp_iterate_dir(dir->data, (dir->blk << ISO9660_LOG2_BLKSZ) + (sua_off / DISK_SECTOR_SIZE), sua_off % DISK_SECTOR_SIZE, sua_size, filename, &type, &filename_alloc)) + return 0; + /* Read the name. */ + if(cd_disk_read(dir->data->disk, (dir->blk << ISO9660_LOG2_BLKSZ) + nameoffset / DISK_SECTOR_SIZE, nameoffset % DISK_SECTOR_SIZE, dirent.namelen, (char *)name)) + return 0; + node = malloc(sizeof(struct iso9660_node)); + if(!node) + return 0; + /* Setup a new node. */ + node->data = dir->data; + node->size = le_to_cpu32(dirent.size); + node->blk = le_to_cpu32(dirent.first_sector); + node->dir_blk = ((dir->blk << ISO9660_LOG2_BLKSZ) + offset / DISK_SECTOR_SIZE); + node->dir_off = offset % DISK_SECTOR_SIZE; + node->time = ((((unsigned)dirent.year - 80) & 0x7F) << 25) | (((unsigned)dirent.month & 0xF) << 21) | (((unsigned)dirent.day & 0x1F) << 16) + | (((unsigned)dirent.hour & 0x1F) << 11) | (((unsigned)dirent.minute & 0x3F) << 5) | (((unsigned)dirent.second & 0x3F) >> 1); + /* If the filetype was not stored using rockridge, use whatever is stored in the iso9660 filesystem. */ + if(type == FSHELP_UNKNOWN) + { + if((dirent.flags & 3) == 2) + type = FSHELP_DIR; + else if(dirent.flags & 1) + type = FSHELP_HIDDEN; + else + type = FSHELP_REG; + } + /* The filename was not stored in a rock ridge entry. Read it from the iso9660 filesystem. */ + if(!filename) + { + name[dirent.namelen] = '\0'; + filename = strrchr(name, ';'); + if(filename) + *filename = '\0'; + if(dirent.namelen == 1 && name[0] == 0) + { + filename = "."; + dot = 1; + } + else if(dirent.namelen == 1 && name[0] == 1) + { + filename = ".."; + dot = 1; + } + else + filename = name; + } + if((dir->data->joliet) && !dot) + { + char *oldname, *semicolon; + oldname = filename; + filename = iso9660_convert_string((unsigned short *)oldname, dirent.namelen >> 1); + semicolon = strrchr(filename, ';'); + if(semicolon) + *semicolon = '\0'; + if(filename_alloc) + free(oldname); + filename_alloc = 1; + } + if(hook(filename, type, node, params)) + { + if(filename_alloc) + free(filename); + return 1; + } + if(filename_alloc) + free(filename); + } + offset += dirent.len; + } + return 0; +} + +static int dir_iterate(const char *filename, enum iso9660_fileype filetype, iso9660_node_t node, void *params) +{ + int ret; + struct dirhook_info info; + int (*dir_hook)(const char *filename, const struct dirhook_info *info) = params; + memset(&info, 0, sizeof(info)); + info.dir = ((filetype & FSHELP_TYPE_MASK) == FSHELP_DIR); + info.hidden = ((filetype & FSHELP_TYPE_MASK) == FSHELP_HIDDEN); + if(info.dir) + info.size = 0; + else + info.size = (unsigned long)node->size; + info.mtime = (unsigned long)node->time; + info.mtimeset = 1; + ret = dir_hook(filename, &info); + free(node); + return ret; +} + +int iso9660_dir(cd_disk_t disk, const char *path, int (*hook)()) +{ + struct iso9660_data *data = 0; + struct iso9660_node rootnode; + struct iso9660_node *foundnode; + data = iso9660_mount(disk); + if(data == NULL) + goto fail; + rootnode.data = data; + rootnode.blk = le_to_cpu32(data->voldesc.rootdir.first_sector); + rootnode.size = le_to_cpu32(data->voldesc.rootdir.size); + /* Use this function to traverse the path. */ + if(iso9660_find_file(path, &rootnode, &foundnode, FSHELP_DIR)) + goto fail; + /* List the files in the directory. */ + iso9660_iterate_dir(foundnode, dir_iterate, hook); + if(foundnode != &rootnode) + free(foundnode); +fail: + free(data); + return cd_disk_errno; +} + +/* Open a file named NAME and initialize FILE. */ +int iso9660_open(cd_file_t file, const char *name) +{ + struct iso9660_data *data; + struct iso9660_node rootnode; + struct iso9660_node *foundnode; + data = iso9660_mount(file->disk); + if(data == NULL) + goto fail; + rootnode.data = data; + rootnode.blk = le_to_cpu32(data->voldesc.rootdir.first_sector); + rootnode.size = le_to_cpu32(data->voldesc.rootdir.size); + /* Use this function to traverse the path. */ + if(iso9660_find_file(name, &rootnode, &foundnode, FSHELP_REG)) + goto fail; + data->first_sector = foundnode->blk; + file->data = data; + file->size = foundnode->size; + file->offset = 0; + file->time = foundnode->time; + return 0; +fail: + free(data); + return cd_disk_errno; +} + +int iso9660_read(cd_file_t file, char *buf, int len) +{ + struct iso9660_data *data = (struct iso9660_data *)file->data; + /* XXX: The file is stored in as a single extent. */ + cd_disk_read(data->disk, data->first_sector << ISO9660_LOG2_BLKSZ, file->offset, len, buf); + if(cd_disk_errno) + return cd_disk_errno /* -1 */; + return len; +} + +int iso9660_close(cd_file_t file) +{ + free(file->data); + file->data = NULL; + return E_OK; +} + +int iso9660_label(cd_disk_t disk, char **label, long *total_sectors) +{ + struct iso9660_data *data = iso9660_mount(disk); + if(data != NULL) + { + if(label != NULL) + { + if(data->joliet) + *label = iso9660_convert_string((unsigned short *)&data->voldesc.volname, 16); + else + *label = strndup((char *)data->voldesc.volname, 32); + if(*label != NULL) + { + char *ptr; + for(ptr = *label; *ptr;ptr++); + ptr--; + while(ptr >= *label && *ptr == ' ') + *ptr-- = 0; + } + } + if(total_sectors != NULL) + *total_sectors = le_to_cpu32(data->voldesc.total_sectors); + free(data); + } + else + { + if(label != NULL) + *label = NULL; + if(total_sectors != NULL) + *total_sectors = 0; + } + return cd_disk_errno; +} + diff --git a/flash.tos/drivers/cd/cd_iso.h b/flash.tos/drivers/cd/cd_iso.h new file mode 100644 index 0000000..4657717 --- /dev/null +++ b/flash.tos/drivers/cd/cd_iso.h @@ -0,0 +1,26 @@ +/* + * This file 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 file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _CD_ISO_H +#define _CD_ISO_H + +int iso9660_label(cd_disk_t disk, char **label, long *total_sectors); +int iso9660_dir(cd_disk_t disk, const char *path, int (*hook)()); +int iso9660_open(cd_file_t file, const char *name); +int iso9660_read(cd_file_t file, char *buf, int len); +int iso9660_close(cd_file_t file); + +#endif /* _CD_ISO_H */ diff --git a/flash.tos/drivers/cd/cd_scsi.c b/flash.tos/drivers/cd/cd_scsi.c new file mode 100644 index 0000000..7d9ce67 --- /dev/null +++ b/flash.tos/drivers/cd/cd_scsi.c @@ -0,0 +1,308 @@ +#include /* for clobber list */ +#include +#include +#include "scsidrv/scsi.h" + +static tHandle Handle; +static tSCSICmd SCmd; +static long ScsiFlags; + +/* global */ +unsigned long BlockLen; +unsigned long MaxDmaLen; +unsigned short LogicalUnit; +tReqData ReqBuff; /* Request Sense Buffer for all commands */ +tpScsiCall scsicall; + +void Wait(unsigned long Ticks) +{ + long endtime = *(volatile unsigned long *)_hz_200 + Ticks; + while(*(volatile unsigned long *)_hz_200 < endtime); +} + +void SetBlockSize(unsigned long NewLen) +{ + BlockLen = NewLen; +} + +unsigned long GetBlockSize() +{ + return(BlockLen); +} + +void SetScsiUnit(tHandle handle, short Lun, unsigned long MaxLen) +{ + Handle = handle; + LogicalUnit = Lun*32; + MaxDmaLen = MaxLen; +} + +void SetCmd6(tCmd6 *Cmd, unsigned short Opcode, unsigned long BlockAdr, unsigned short TransferLen) +{ + Cmd->Command = (unsigned char)Opcode; + Cmd->LunAdr = (unsigned char)LogicalUnit + (unsigned char)((BlockAdr >> 16) & 0x1F); + Cmd->Adr = w2mot((unsigned short)(BlockAdr & 0xFFFF)); + Cmd->Len = (unsigned char)TransferLen; + Cmd->Flags = 0; +} + +void SetCmd10(tCmd10 *Cmd, unsigned short Opcode, unsigned long BlockAdr, unsigned short TransferLen) +{ + Cmd->Command = (unsigned char)Opcode; + Cmd->Lun = (unsigned char)LogicalUnit; + Cmd->Adr = l2mot(BlockAdr); + Cmd->Reserved = 0; + Cmd->LenHigh = (unsigned char)(TransferLen >> 8); + Cmd->LenLow = (unsigned char)(TransferLen & 0xFF); + Cmd->Flags = 0; +} + +void SetCmd12(tCmd12 *Cmd, unsigned short Opcode, unsigned long BlockAdr, unsigned long TransferLen) +{ + Cmd->Command = (unsigned char)Opcode; + Cmd->Lun = (unsigned char)LogicalUnit; + Cmd->Adr = l2mot(BlockAdr); + Cmd->Len = l2mot(TransferLen); + Cmd->Reserved= 0; + Cmd->Flags = 0; +} + +tpSCSICmd SetCmd(char *Cmd, short CmdLen, void *Buffer, unsigned long Len, unsigned long TimeOut) +{ + SCmd.Handle = Handle; + SCmd.Cmd = Cmd; + SCmd.CmdLen = CmdLen; + SCmd.Buffer = Buffer; + SCmd.TransferLen = Len; + SCmd.SenseBuffer = ReqBuff; + SCmd.Timeout = TimeOut; + SCmd.Flags = (char)ScsiFlags; + return(&SCmd); +} + +long TestUnitReady(void) +{ + tCmd6 Cmd; + SetCmd6(&Cmd, TEST_UNIT_READY, 0, 0); + return(In(SetCmd((char *)&Cmd, 6, NULL, 0, DefTimeout))); +} + +long Inquiry(void *data, int Vital, unsigned short VitalPage, short length) +{ + tCmd6 Cmd; + SetCmd6(&Cmd, INQUIRY, 0, length); + if(Vital) + { + Cmd.LunAdr |= 1; + Cmd.Adr = VitalPage << 8; + } + return(In(SetCmd((char *)&Cmd, 6, data, length, 1000))); +} + +long ModeSelect6(unsigned short SelectFlags, void *Buffer, unsigned short ParmLen) +{ + tCmd6 Cmd; + SetCmd6(&Cmd, MODE_SELECT, 0, ParmLen); + Cmd.LunAdr |= (SelectFlags & 0x1F); + return(Out(SetCmd((char *)&Cmd, 6, Buffer, ParmLen, DefTimeout))); +} + +long ModeSelect10(unsigned short SelectFlags, void *Buffer, unsigned short ParmLen) +{ + tCmd10 Cmd; + SetCmd10(&Cmd, MODE_SELECT_10, 0, ParmLen); + Cmd.Lun = (char)SelectFlags; + return(Out(SetCmd((char *)&Cmd, 10, Buffer, ParmLen, DefTimeout))); +} + +long ModeSelect(unsigned short SelectFlags, void *Buffer, unsigned short ParmLen) +{ + long rc = ModeSelect6(SelectFlags, Buffer, ParmLen); + if(rc) + rc = ModeSelect10(SelectFlags, Buffer, ParmLen); + return(rc); +} + +long ModeSense6(unsigned short PageCode, unsigned short SubPageCode, unsigned short PageControl, void *Buffer, unsigned short ParmLen) +{ + tCmd6 Cmd; + SetCmd6(&Cmd, MODE_SENSE, 0, ParmLen); + Cmd.Adr = ((((PageControl << 6) + PageCode) & 0xFF) << 8) + (SubPageCode & 0xFF); + return(In(SetCmd((char *)&Cmd, 6, Buffer, ParmLen, DefTimeout))); +} + +long ModeSense10(unsigned short PageCode, unsigned short SubPageCode, unsigned short PageControl, void *Buffer, unsigned short ParmLen) +{ + tCmd10 Cmd; + SetCmd10(&Cmd, MODE_SENSE_10, 0, ParmLen); + Cmd.Adr = ((((PageControl << 6) + PageCode) & 0xFF) << 24) + ((SubPageCode & 0xFF) << 16); + return(In(SetCmd((char *)&Cmd, 10, Buffer, ParmLen, DefTimeout))); +} + +long ModeSense(unsigned short PageCode, unsigned short SubPageCode, unsigned short PageControl, void *Buffer, unsigned short ParmLen) +{ + long rc = ModeSense6(PageCode, SubPageCode, PageControl, Buffer, ParmLen); + if(rc) + rc = ModeSense10(PageCode, SubPageCode, PageControl, Buffer, ParmLen); + return(rc); +} + +long PreventMediaRemoval(int Prevent) +{ + tCmd6 Cmd; + SetCmd6(&Cmd, ALLOW_MEDIUM_REMOVAL, 0, Prevent ? 1 : 0); + return(In(SetCmd((char *)&Cmd, 6, NULL, 0, DefTimeout))); +} + +long Read6(unsigned long BlockAdr, unsigned short TransferLen, void *buffer) +{ + long ret; + tCmd6 Cmd; + while(TransferLen > MaxDmaLen / BlockLen) + { + SetCmd6(&Cmd, READ_6, BlockAdr, (unsigned short)(MaxDmaLen / BlockLen)); + if((ret = In(SetCmd((char *)&Cmd, 6, buffer, MaxDmaLen / BlockLen * BlockLen, DefTimeout))) != 0) + return(ret); + BlockAdr += MaxDmaLen / BlockLen; + TransferLen -= (unsigned short)(MaxDmaLen / BlockLen); + buffer = (void *)((long)buffer + MaxDmaLen / BlockLen * BlockLen); + } + SetCmd6(&Cmd, READ_6, BlockAdr, TransferLen); + return(In(SetCmd((char *)&Cmd, 6, buffer, BlockLen * (unsigned long)TransferLen, DefTimeout))); +} + +long Read10(unsigned long BlockAdr, unsigned short TransferLen, void *buffer) +{ + long ret; + tCmd10 Cmd; + while(TransferLen > MaxDmaLen / BlockLen) + { + SetCmd10(&Cmd, READ_10, BlockAdr, (unsigned short)(MaxDmaLen / BlockLen)); + if((ret = In(SetCmd((char *)&Cmd, 10, buffer, MaxDmaLen / BlockLen * BlockLen, 20*200))) != 0) + return(ret); + BlockAdr += MaxDmaLen / BlockLen; + TransferLen -= (unsigned short)(MaxDmaLen / BlockLen); + buffer = (void *)((long)buffer + MaxDmaLen / BlockLen * BlockLen); + } + SetCmd10(&Cmd, READ_10, BlockAdr, TransferLen); + return(In(SetCmd((char *)&Cmd, 10, buffer, BlockLen * (unsigned long)TransferLen, 20*200))); +} + +long Write6(unsigned long BlockAdr, unsigned short TransferLen, void *buffer) +{ + long ret; + tCmd6 Cmd; + while(TransferLen > MaxDmaLen / BlockLen) + { + SetCmd6(&Cmd, WRITE_6, BlockAdr, (unsigned short)(MaxDmaLen / BlockLen)); + if((ret = Out(SetCmd((char *)&Cmd, 6, buffer, MaxDmaLen / BlockLen * BlockLen, 20*200))) != 0) + return(ret); + BlockAdr += MaxDmaLen / BlockLen; + TransferLen -= (unsigned short)(MaxDmaLen / BlockLen); + buffer = (void *)((long)buffer + MaxDmaLen / BlockLen * BlockLen); + } + SetCmd6(&Cmd, WRITE_6, BlockAdr, TransferLen); + return(Out(SetCmd((char *)&Cmd, 6, buffer, BlockLen * (unsigned long)TransferLen, 20*200))); +} + +long Write10(unsigned long BlockAdr, unsigned short TransferLen, void *buffer) +{ + long ret; + tCmd10 Cmd; + while(TransferLen > MaxDmaLen / BlockLen) + { + SetCmd10(&Cmd, WRITE_10, BlockAdr, (unsigned short)(MaxDmaLen / BlockLen)); + if((ret = Out(SetCmd((char *)&Cmd, 10, buffer, MaxDmaLen / BlockLen * BlockLen, 20*200))) != 0) + return(ret); + BlockAdr += MaxDmaLen / BlockLen; + TransferLen -= (unsigned short)(MaxDmaLen / BlockLen); + buffer = (void *)((long)buffer + MaxDmaLen / BlockLen * BlockLen); + } + SetCmd10(&Cmd, WRITE_10, BlockAdr, TransferLen); + return(Out(SetCmd((char *)&Cmd, 10, buffer, BlockLen * (unsigned long)TransferLen, 20*200))); +} + +#define cMaxBlockAdr 0x001FFFFFL /* Max. Blocknummer for Read6/Write6 */ + +long Read(unsigned long BlockAdr, unsigned short TransferLen, void *buffer) +{ + if(BlockAdr > cMaxBlockAdr) + return(Read10(BlockAdr, TransferLen, buffer)); + else + return(Read6(BlockAdr, TransferLen, buffer)); +} + +long Write(unsigned long BlockAdr, unsigned short TransferLen, void *buffer) +{ + if(BlockAdr > cMaxBlockAdr) + return(Write10(BlockAdr, TransferLen, buffer)); + else + return(Write6(BlockAdr, TransferLen, buffer)); +} + +long StartStop(int LoadEject, int StartFlag) +{ + tCmd6 Cmd; + SetCmd6(&Cmd, START_STOP, 0, StartFlag ? 1 : 0); + if(LoadEject) + Cmd.Len |= 2; + return(In(SetCmd((char *)&Cmd, 6, NULL, 0, 60*200))); +} + +long ReadCapacity(int PMI, unsigned long *BlockAdr, unsigned long *BlockLen) +{ + unsigned long Data[2]; + long ret; + tCmd10 Cmd; + SetCmd10(&Cmd, READ_CAPACITY, *BlockAdr, 0); + if(PMI) + Cmd.LenLow = 1; + if((ret = In(SetCmd((char *)&Cmd, 10, Data, sizeof(Data), DefTimeout))) == 0) + { + *BlockAdr = Data[0]; + *BlockLen = Data[1]; + } + return(ret); +} + +long GetConfiguration(int RT, unsigned short StartFeature, void *Buffer, unsigned short Len) +{ + tCmd10 Cmd; + SetCmd10(&Cmd, GET_CONFIGURATION, (unsigned long)StartFeature << 16, Len); + Cmd.Lun |= (RT & 3); + return(In(SetCmd((char *)&Cmd, 10, Buffer, Len, DefTimeout))); +} + +long ReadTOC(int MSF, int Format, unsigned short StartTrack, void *Buffer, unsigned short Len) +{ + tCmd10 Cmd; + SetCmd10(&Cmd, READ_TOC, (unsigned long)Format << 24, Len); + if(MSF) + Cmd.Lun |= 2; + Cmd.Reserved = (char)StartTrack; + return(In(SetCmd((char *)&Cmd, 10, Buffer, Len, DefTimeout))); +} + +long ReadDVDStucture(unsigned long Address, unsigned short LayerNumber, unsigned short Format, int AGID, void *Buffer, unsigned short Len) +{ + tCmd12 Cmd; + SetCmd12(&Cmd, READ_DVD_STRUCTURE, Address, (Len & 0xFFFF) + (((unsigned long)LayerNumber & 0xFF) << 24) + (((unsigned long)Format & 0xFF) << 16)); + Cmd.Reserved = (AGID & 3) << 6; + return(In(SetCmd((char *)&Cmd, 12, Buffer, Len, DefTimeout))); +} + +long ReadDiskInfo(void *Buffer, unsigned short Len) +{ + tCmd10 Cmd; + SetCmd10(&Cmd, READ_DISK_INFO, 0, Len); + return(In(SetCmd((char *)&Cmd, 10, Buffer, Len, DefTimeout))); +} + +long ReadTrackInfo(int AddressNumberType, unsigned long BlockAdr, void *Buffer, unsigned short Len) +{ + tCmd10 Cmd; + SetCmd10(&Cmd, READ_TRACK_INFO, BlockAdr, Len); + Cmd.Lun |= (AddressNumberType & 3); + return(In(SetCmd((char *)&Cmd, 10, Buffer, Len, DefTimeout))); +} + diff --git a/flash.tos/drivers/debug.S b/flash.tos/drivers/debug.S index cf98a0c..053fe87 100644 --- a/flash.tos/drivers/debug.S +++ b/flash.tos/drivers/debug.S @@ -1,5 +1,5 @@ /* TOS 4.04 Videl debug output for the CT60/CTPCI boards - * Didier Mequignon 2010, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2010-2012, e-mail: aniplay@wanadoo.fr * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,7 +21,7 @@ #ifdef DEBUG - .global _debug_traps,_trace_tos,vdu + .global _debug_traps,_trace_tos,_video_found,_vdu,vdu .data @@ -153,6 +153,15 @@ clear_line: movem.l (SP)+,D0-A3 rts #endif + +_vdu: + + tst.w _video_found + beq.s .no_vdu + move.l 4(SP),D0 + bsr.s vdu +.no_vdu: + rts hex: diff --git a/flash.tos/drivers/detgemdos.S b/flash.tos/drivers/detgemdos.S new file mode 100644 index 0000000..f2664c0 --- /dev/null +++ b/flash.tos/drivers/detgemdos.S @@ -0,0 +1,330 @@ +/* TOS 4.04 Gemdos dispatcher for the CT60/CTPCI and Coldfire boards + * Didier Mequignon 2011, e-mail: aniplay@wanadoo.fr + * + * This file 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 file 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + .global _det_gemdos,_old_vector_gemdos + .global _cd_pterm,_cd_dfree,_cd_dcreate,_cd_ddelete,_cd_dsetpath + .global _cd_fcreate,_cd_fopen,_cd_fclose,_cd_fread,_cd_fwrite,_cd_fdelete,_cd_fseek + .global _cd_dgetpath,_cd_fattrib,_cd_pexec,_cd_fsfirst,_cd_fsnext,_cd_frename,_cd_fdatime + + .data + + .align 2 + +_det_gemdos: + +#if defined(COLDFIRE) && (__GNUC__ <= 3) + .chip 68060 + move.l USP,A0 // V4 + .chip 5200 +#else + move.l USP,A0 +#endif + btst #5,(SP) // call in supervisor state + beq.s .gd16 + lea.l 8(SP),A0 +.gd16: +#ifdef COLDFIRE + lea -16(SP),SP + movem.l D1-D2/A1-A2,(SP) + moveq #0,D0 +#else + movem.l D1-D2/A1-A2,-(SP) +#endif + move.w (A0),D0 // function + beq.s .gd21 // Pterm0 +#ifdef COLDFIRE + cmp.l #0x31,D0 // Ptermres +#else + cmp.w #0x31,D0 // Ptermres +#endif + beq.s .gd21 +#ifdef COLDFIRE + cmp.l #0x4C,D0 // Pterm +#else + cmp.w #0x4C,D0 // Pterm +#endif + bne.s .gd22 +.gd21: + jsr _cd_pterm + bra .gd1 // call default GEMDOS routine +.gd22: +#ifdef COLDFIRE + cmp.l #0x36,D0 // Dfree +#else + cmp.w #0x36,D0 // Dfree +#endif + bne.s .gd15 + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_dfree + bra .gd19 +.gd15: +#ifdef COLDFIRE + cmp.l #0x39,D0 // Dcreate +#else + cmp.w #0x39,D0 // Dcreate +#endif + bne.s .gd14 + move.l 2(A0),-(SP) + jsr _cd_dcreate + bra .gd20 +.gd14: +#ifdef COLDFIRE + cmp.l #0x3A,D0 // Ddelete +#else + cmp.w #0x3A,D0 // Ddelete +#endif + bne.s .gd13 + move.l 2(A0),-(SP) + jsr _cd_ddelete + bra .gd20 +.gd13: +#ifdef COLDFIRE + cmp.l #0x3B,D0 // Dsetpath +#else + cmp.w #0x3B,D0 // Dsetpath +#endif + bne.s .gd25 + move.l 2(A0),-(SP) + jsr _cd_dsetpath + bra .gd20 +.gd25: +#ifdef COLDFIRE + cmp.l #0x3C,D0 // Fcreate +#else + cmp.w #0x3C,D0 // Fcreate +#endif + bne.s .gd12 + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_fcreate + bra .gd19 +.gd12: +#ifdef COLDFIRE + cmp.l #0x3D,D0 // Fopen +#else + cmp.w #0x3D,D0 // Fopen +#endif + bne.s .gd11 + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_fopen + bra .gd19 +.gd11: +#ifdef COLDFIRE + cmp.l #0x3E,D0 // Fclose +#else + cmp.w #0x3E,D0 // Fclose +#endif + bne.s .gd10 + move.w 2(A0),D0 + ext.l D0 + move.l D0,-(SP) + jsr _cd_fclose + bra.s .gd20 +.gd10: +#ifdef COLDFIRE + cmp.l #0x3F,D0 // Fread +#else + cmp.w #0x3F,D0 // Fread +#endif + bne.s .gd9 + move.l 8(A0),-(SP) + move.l 4(A0),-(SP) + move.w 2(A0),D0 + ext.l D0 + move.l D0,-(SP) + jsr _cd_fread + bra .gd18 +.gd9: +#ifdef COLDFIRE + cmp.l #0x40,D0 // Fwrite +#else + cmp.w #0x40,D0 // Fwrite +#endif + bne.s .gd8 + move.l 8(A0),-(SP) + move.l 4(A0),-(SP) + move.w 2(A0),D0 + ext.l D0 + move.l D0,-(SP) + jsr _cd_fwrite + bra .gd18 +.gd8: +#ifdef COLDFIRE + cmp.l #0x41,D0 // Fdelete +#else + cmp.w #0x41,D0 // Fdelete +#endif + bne.s .gd7 + move.l 2(A0),-(SP) + jsr _cd_fdelete +.gd20: + addq.l #4,SP + bra .gd17 +.gd7: +#ifdef COLDFIRE + cmp.l #0x42,D0 // Fseek +#else + cmp.w #0x42,D0 // Fseek +#endif + bne.s .gd6 + move.w 8(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_fseek + bra .gd18 +.gd6: +#ifdef COLDFIRE + cmp.l #0x43,D0 // Fattrib +#else + cmp.w #0x43,D0 // Fattrib +#endif + bne.s .gd5 + move.w 8(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_fattrib + bra .gd18 +.gd5: +#ifdef COLDFIRE + cmp.l #0x47,D0 // Dgetpath +#else + cmp.w #0x47,D0 // Dgetpath +#endif + bne.s .gd24 + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_dgetpath + bra .gd19 +.gd24: +#ifdef COLDFIRE + cmp.l #0x4B,D0 // Pexec +#else + cmp.w #0x4B,D0 // Pexec +#endif + bne.s .gd23 + movel A0,-(SP) + move.l 12(A0),-(SP) + move.l 8(A0),-(SP) + move.l 4(A0),-(SP) + move.w 2(A0),D0 + ext.l D0 + move.l D0,-(SP) + jsr _cd_pexec + move.l (SP)+,D1 + lea 12(SP),SP + move.l (SP)+,A0 + tst.l D0 + bmi .gd17 // error + cmp.l #3,D1 // PE_LOAD + beq.s .gd17 + move.l D0,8(A0) // basepage + moveq #4,D0 + move.w D0,2(A0) // PE_GO + bra.s .gd1 +.gd23: +#ifdef COLDFIRE + cmp.l #0x4E,D0 // Fsfirst +#else + cmp.w #0x4E,D0 // Fsfirst +#endif + bne.s .gd4 + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_fsfirst + bra.s .gd19 +.gd4: +#ifdef COLDFIRE + cmp.l #0x4F,D0 // Fsnext +#else + cmp.w #0x4F,D0 // Fsnext +#endif + bne.s .gd3 + jsr _cd_fsnext + bra.s .gd17 +.gd3: +#ifdef COLDFIRE + cmp.l #0x56,D0 // Frename +#else + cmp.w #0x56,D0 // Frename +#endif + bne.s .gd2 + move.l 6(A0),-(SP) + move.l 2(A0),-(SP) + jsr _cd_frename +.gd19: + addq.l #8,SP + bra.s .gd17 +.gd2: +#ifdef COLDFIRE + cmp.l #0x57,D0 // Fdatime +#else + cmp.w #0x57,D0 // Fdatime +#endif + bne.s .gd1 + move.w 8(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.w 6(A0),D0 + ext.l D0 + move.l D0,-(SP) + move.l 2(A0),-(SP) + jsr _cd_fdatime +.gd18: + lea 12(SP),SP +.gd17: + cmp.l #-46,D0 // EDRIVE + beq.s .gd1 // call default GEMDOS routine +.gd26: +#ifdef COLDFIRE + movem.l (SP),D1-D2/A1-A2 + lea 16(SP),SP +#else + movem.l (SP)+,D1-D2/A1-A2 +#endif + rte +.gd1: +#ifdef COLDFIRE + movem.l (SP),D1-D2/A1-A2 + lea 16(SP),SP +#else + movem.l (SP)+,D1-D2/A1-A2 +#endif + move.l _old_vector_gemdos,-(SP) + rts + + diff --git a/flash.tos/drivers/detlinea.S b/flash.tos/drivers/detlinea.S index b54e7e7..fefe035 100644 --- a/flash.tos/drivers/detlinea.S +++ b/flash.tos/drivers/detlinea.S @@ -18,7 +18,6 @@ .global _det_linea,_old_vector_linea,_oldmouse .global show_c,hide_c - .global _os_magic .global adr_var_vdi,adr_linea_fonts,adr_linea_atab #define _sysbase 0x4F2 diff --git a/flash.tos/drivers/detvdi.S b/flash.tos/drivers/detvdi.S index ac842af..3782331 100644 --- a/flash.tos/drivers/detvdi.S +++ b/flash.tos/drivers/detvdi.S @@ -1,5 +1,5 @@ /* TOS 4.04 VDI for the CT60/CTPCI and Coldfire boards - * Didier Mequignon 2005-2011, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2005-2012, e-mail: aniplay@wanadoo.fr * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -274,25 +274,6 @@ _init_det_vdi: move.l A0,adr_var_vdi move.l A1,adr_linea_fonts move.l A2,adr_linea_atab -#if 0 - tst.w _os_magic - beq.s .not_os_magic - move.l _sysbase,A1 - move.l 0x18(A1),D0 // date - swap D0 - cmp.l #0x20010000,D0 // MagiC 6.20 - bcs.s .not_os_magic - lea var_vdi,A1 - move.l a1,adr_var_vdi - lea CUR_FONT(A0),A0 - lea CUR_FONT(A1),A1 - move.l #(-(CUR_FONT)+PAL_MAP+(256*4))/2,D0 -.copy_var_vdi: - move.w (A0)+,(A1)+ - subq.l #1,D0 - bgt.s .copy_var_vdi -.not_os_magic: -#endif #ifdef COLDFIRE movem.l (SP),D0-D2/A0-A2 lea 24(SP),SP @@ -391,7 +372,7 @@ display_char: move.l (SP)+,D1 rts -#else +#else /* !COLDFIRE */ display_string: @@ -441,7 +422,7 @@ hex_char: display_char: #ifndef COLDFIRE - jmp vdu + jmp vdu // debug.S #else #ifdef COLDFIRE lea -24(SP),SP @@ -522,9 +503,16 @@ wait_key: lea 24(SP),SP #else movem.l D0-D2/A0-A2,-(SP) +#if 0 move.w #7,-(SP) // Crawcin trap #1 addq.l #2,SP +#else + move.w #2,-(SP) // CON + move.w #2,-(SP) // Bconin + trap #13 + addq.l #4,SP +#endif movem.l (SP)+,D0-D2/A0-A2 #endif rts @@ -6527,52 +6515,6 @@ det_vsl_ends: move.w D0,(A1) // end line selected rts -#if 0 -aff_x: - - move.l D0,-(SP) - move.w (A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 2(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 4(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 6(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 8(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 10(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 12(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.w 14(A0),D0 - bsr hex_word - moveq #0x20,D0 - bsr display_char - move.l D5,D0 - bsr hex_long - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char - move.l (SP)+,D0 - rts -#endif - det_vro_cpyfm: #ifdef COLDFIRE @@ -6624,7 +6566,6 @@ det_vro_cpyfm: cmp.l D1,D6 ble.s .vrc13 move.l D1,D6 // fix X2 source if screen -// bsr aff_x .vrc13: cmp.l D2,D7 ble.s .vrc14 @@ -9119,6 +9060,8 @@ vb_draw: // VBL routine *-------*/ move.l wk_r_mouse(A1),D2 beq.s .vd3 // no accel + cmp.l #0x600,D2 + bcs.s .vd3 // TO FIX: ugly bug under MagiC move.l D2,A2 moveq #1,D2 // move hidden move.w M_HID_CT(A0),wk_mouse_hide(A1) diff --git a/flash.tos/drivers/detxbios.S b/flash.tos/drivers/detxbios.S index 5e616c4..bbf9f0a 100644 --- a/flash.tos/drivers/detxbios.S +++ b/flash.tos/drivers/detxbios.S @@ -1,6 +1,6 @@ /* TOS 4.04 Xbios dispatcher for the CT60/CTPCI and Coldfire boards * and USB-disk / SD-card / Ram-Disk utility - * Didier Mequignon 2005-2011, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2005-2012, e-mail: aniplay@wanadoo.fr * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -22,6 +22,7 @@ #ifdef COLDFIRE #include "../include/fire.h" #else +#define pun_ptr_ahdi 0x516 #undef pun_ptr #define pun_ptr pun_ptr_usb #endif @@ -36,29 +37,32 @@ #define SD_CARD_VERIFY #define SD_CARD_REPLACE_FLOPPY #define RAM_DISK_REPLACE_B +#define MINT_IKBD_PATCH +#ifdef COLDFIRE #define MAX_LOGICAL_DRIVE 16 +#else +#define MAX_LOGICAL_DRIVE 32 +#endif #define Modecode 0x184C .global _det_xbios,_old_vector_xbios .global _physbase,_logbase,_getrez,_vsetscreen,_wait_vbl,_vsetmode,_montype,_vgetsize,_vsetrgb,_vgetrgb - .global _cursconf,_info_fvdi,_ltoa + .global _cursconf,_info_fvdi,_ltoa,_strcpy,_strcat + .global _M68k_InstrLen #ifdef COLDFIRE .global _acp_new_hardware #ifndef MCF5445X #ifndef MCF547X -#ifdef NETWORK #ifdef LWIP .global _settime,_gettime #endif #endif #endif -#endif #endif /* COLDFIRE */ #ifdef SOUND_AC97 #ifdef COLDFIRE -#ifdef NETWORK #ifndef MCF5445X .global _locksnd,_unlocksnd,_soundcmd,_setbuffer,_setmode,_settracks,_setmontracks .global _setinterrupt,_buffoper,_gpio,_devconnect,_sndstatus,_buffptr @@ -66,7 +70,6 @@ .global _mcf548x_ac97_playback_resample,_mcf548x_ac97_record_resample #endif #endif -#endif #endif /* SOUND_AC97 */ .global _validmode,_vmalloc .global _vixGetVersion,_vixProbe,_vixInit,_vixDestroy,_vixGetCapability @@ -78,26 +81,34 @@ #ifdef MCF547X .global _check_sd_card,_install_sd_card #endif +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + .global _usb_mem_init,_usb_malloc,_usb_free +#endif #if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) - .global _install_usb_stor,_uninstall_usb_stor,_usb_stor_read,_usb_stor_write,_usb_malloc,_usb_1st_disk_drive + .global _install_usb_stor,_uninstall_usb_stor,_usb_stor_read,_usb_stor_write,_usb_1st_disk_drive + .global _usb_error_msg #endif -#ifdef NETWORK -#ifdef COLDFIRE #ifdef LWIP +#ifdef COLDFIRE .global _disable_caches,_enable_caches,_flush_caches,_flush_dc,_flush_ic #if !defined(MCF547X) && !defined(MCF5445X) .global _set_intfrcl,_clr_intfrcl #endif -#endif /* LWIP */ #endif /* COLDFIRE */ .global _install_ram_disk,_address_ram_disk,_size_ram_disk,_change_ram_disk,_ext_write_protect_ram_disk,_ram_disk_drive - .global _alert_tos -#endif /* NETWORK */ +#endif /* LWIP */ +#if !defined(COLDFIRE) || defined(MCF547X) + .global _install_cd_disk,_cd_disk_read_sectors,_cd_disk_drive +#endif .global _call_enumfunc,_call_ikbdvec,_call_mousevec,_direct_conout .global _critical_error,_get_sr #if defined(DEBUG) || defined(DEBUG_XHDI) .global display_string,hex_long,hex_word,hex_byte,display_char,wait_key,_video_found #endif + .global _init_before_autofolder,_install_magic_routine +#ifndef COLDFIRE + .global _get_no_cache_memory,_get_no_cache_memory_size,_led_floppy,_code_led +#endif .data @@ -122,49 +133,20 @@ #define PUN_REMOVABLE 0x40 /* Removable media */ #define PUN_VALID 0x80 /* zero if valid */ -#define pinfo_puns 0 // 2 bytes -#define pinfo_pun 2 // 16 bytes -#define pinfo_pstart 18 // 16 x 4 bytes -#define pinfo_cookie 82 // 4 bytes -#define pinfo_cookptr 86 // 4 bytes -#define pinfo_vernum 90 // 2 bytes -#define pinfo_maxsiz 92 // 2 bytes -#define pinfo_ptype 94 // 16 x 4 bytes -#define pinfo_psize 158 // 16 x 4 bytes -#define pinfo_flags 222 // 16 x 2 bytes, internal use: B15:swap, B7:change, B0:bootable -#define pinfo_bpb 256 // 16 x 18 bytes -#define pinfo_size 544 - -#ifdef DEBUG -debug1: .asciz "XBIOS #0x" -debug2: .asciz "Setscreen 0x" -debug3: .asciz "hdv_rw 0x" -debug4: .ascii "hdv_bpb" - .byte 13,10,0 -debug5: .ascii "hdv_mediach" - .byte 13,10,0 -debug6: .asciz "Vsetmode 0x" -debug7: .asciz "ValidMode 0x" -debug8: .asciz "Gettime 0x" -#endif -#ifdef DEBUG_XHDI -debug130: .asciz "XHDI return 0x" -debug131: .asciz "XHDI XHDrvMap 0x" -debug132: .asciz "XHDI XHReadWrite major 0x" -debug133: .asciz "XHDI XHInqTarget major 0x" -debug133a: .asciz "XHDI XHInqTarget2 major 0x" -debug134: .asciz "XHDI XHInqDev device 0x" -debug135: .asciz "XHDI XHInqDriver device 0x" -debug136: .asciz "XHDI XHInqDev2 device 0x" -debug137: .asciz "XHDI XHDOSLimits which 0x" -debug138: .ascii "XHDI XHGetVersion" - .byte 13,10,0 -debug139: .asciz ", minor 0x" -debug140: .asciz ", rwflag 0x" -debug141: .asciz ", sector 0x" -debug142: .asciz ", count 0x" -debug143: .asciz ", buffer 0x" -#endif +// if MAX_LOGICAL_DRIVE <> 16 orininal AHDI pun_ptr connot be used +#define _pinfo_puns 0 // 2 bytes +#define _pinfo_pun 2 // MAX_LOGICAL_DRIVE bytes +#define _pinfo_pstart (_pinfo_pun+MAX_LOGICAL_DRIVE) // MAX_LOGICAL_DRIVE x 4 bytes +#define _pinfo_cookie (_pinfo_pstart+(MAX_LOGICAL_DRIVE*4)) // 4 bytes +#define _pinfo_cookptr (_pinfo_cookie+4) // 4 bytes +#define _pinfo_vernum (_pinfo_cookptr+4) // 2 bytes +#define _pinfo_maxsiz (_pinfo_vernum+2) // 2 bytes +// not inside AHDI +#define _pinfo_ptype (_pinfo_maxsiz+2) // MAX_LOGICAL_DRIVE x 4 bytes +#define _pinfo_psize (_pinfo_ptype+(MAX_LOGICAL_DRIVE*4)) // MAX_LOGICAL_DRIVE x 4 bytes +#define _pinfo_flags (_pinfo_psize+(MAX_LOGICAL_DRIVE*4)) // MAX_LOGICAL_DRIVE x 2 bytes, internal use: B15:swap, B14:stop, B7:change, B0:bootable +#define _pinfo_bpb (_pinfo_flags+(MAX_LOGICAL_DRIVE*2)) // MAX_LOGICAL_DRIVE x 18 bytes +#define _pinfo_size (_pinfo_bpb+(MAX_LOGICAL_DRIVE*18)) .align 2 @@ -188,6 +170,11 @@ _det_xbios: move.l A0,-(SP) moveq #0,D0 move.w (A0),D0 // function + cmp.l #420,D0 + bhi .x0b + cmp.l #400,D0 // VIDIX +#if 0 + bcc .x0 cmp.l #2,D0 // Physbase beq.s .x0 cmp.l #3,D0 // Logbase @@ -217,6 +204,7 @@ _det_xbios: cmp.l #141,D0 // Buffptr bhi.s .x0b cmp.l #128,D0 // Locksnd +#endif bcs.s .x0b .x0: lea debug1(PC),A0 @@ -376,7 +364,6 @@ _det_xbios: #ifdef USE_RTC #ifndef MCF5445X #ifndef MCF547X -#ifdef NETWORK #ifdef LWIP move.l MCF_SIU_JTAGID,D1 // check the processor and.l #MCF_SIU_JTAGID_PROCESSOR,D1 @@ -411,7 +398,6 @@ _det_xbios: rte .x24: #endif /* LWIP */ -#endif /* NETWORK */ #endif /* MCF547X */ #endif /* MCF5445X */ #endif /* RTC */ @@ -560,9 +546,33 @@ _det_xbios: jsr _validmode addq.l #4,SP rte -.x11: +.x11: +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef COLDFIRE + cmp.l #354,D0 // dma_alloc +#else + cmp.w #354,D0 // dma_alloc +#endif + bne.s .x32 + move.l 2(A0),-(SP) // size + jsr _usb_mem_init + jsr _usb_malloc + addq.l #4,SP + rte +.x32: +#ifdef COLDFIRE + cmp.l #355,D0 // dma_free +#else + cmp.w #355,D0 // dma_free +#endif + bne.s .x33 + move.l 2(A0),-(SP) // addr + jsr _usb_free + addq.l #4,SP + rte +.x33: +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ #ifdef COLDFIRE -#ifdef NETWORK #ifndef MCF5445X #ifdef SOUND_AC97 tst.l _flag_snd_init @@ -575,15 +585,15 @@ _det_xbios: bne.s .x20 move.w 2(A0),D0 // num bsr jdisint - bne .x15 - rte + bne .x15 + rte .x20: cmp.l #27,D0 // Jenabint bne.s .x21 move.w 2(A0),D0 // num bsr jenabint - bne .x15 - rte + bne .x15 + rte .x21: cmp.l #31,D0 // Xbtimer bne.s .x22 @@ -597,7 +607,7 @@ _det_xbios: tst.l D0 bne .x15 rte -.x22: +.x22: cmp.l #141,D0 bhi .x15 cmp.l #128,D0 @@ -814,7 +824,6 @@ buffptr: .x15: #endif /* SOUND_AC97 */ #endif /* MCF5445X */ -#endif /* NETWORK */ tst.l _info_fvdi beq.s .x1 cmp.l #0xc60e,D0 // ct60_vmalloc @@ -1068,8 +1077,8 @@ install_xbra: // A0: handler, D0: vector, D1: ID move.w D0,D3 // vector move.l A0,A3 // handler move.l D1,-(SP) -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) -#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) && defined(CONFIG_USB_MEM_NO_CACHE) +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) move.l _pxCurrentTCB,D1 cmp.l _tid_TOS,D1 beq.s .use_tos_mxalloc @@ -1086,12 +1095,16 @@ install_xbra: // A0: handler, D0: vector, D1: ID move.w #0x4EF9,(A0)+ // JMP move.l A3,(A0)+ // handler lea -10(A0),A0 +#ifdef COLDFIRE bsr _flush_dc bsr _flush_ic +#else + cpusha BC +#endif bra.s .end_install_xbra .use_tos_mxalloc: -#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) && defined(CONFIG_USB_MEM_NO_CACHE) */ -#endif /* defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) */ +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) */ +#endif /* (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) */ move.w #3,-(SP) // TT ram if possible move.l #18,-(SP) // size move.w #0x44,-(SP) // Mxalloc @@ -1243,6 +1256,8 @@ _install_sd_card: moveq #0,D0 // nothing installed bra.s .end_install_sd_card .install_partition_sd_card: + pea 512 // block_size + pea 0 // number_of_blocks pea name_sd_card // product pea 0 // revision pea 0 // vendor @@ -1251,7 +1266,7 @@ _install_sd_card: move.l D1,-(SP) // part_type clr.l -(SP) // dev_num bsr install_pun_drive - lea 28(SP),SP + lea 36(SP),SP .end_install_sd_card: movem.l (SP),D1-D4/A0-A3 lea 32(SP),SP @@ -1725,14 +1740,17 @@ wait_10ms: _install_usb_stor: - lea -32(SP),SP - movem.l D1-D4/A0-A3,(SP) - move.l 36(SP),D0 // dev_num + lea -36(SP),SP + movem.l D1-D5/A0-A3,(SP) + move.l 40(SP),D0 // dev_num cmp.l #PUN_DEV,D0 bhi .error_usb_install // error or.l #PUN_USB,D0 - movem.l 40(SP),D1-D3 // part_type, part_offset, part_size - movem.l 52(SP),A1/A2/A3 // vendor / revision / product + movem.l 44(SP),D1-D3 // part_type, part_offset, part_size + movem.l 56(SP),A1/A2/A3 // vendor / revision / product + movem.l 68(SP),D4/D5 // number_of_blocks / block_size + move.l D5,-(SP) // block_size + move.l D4,-(SP) // number_of_blocks move.l A3,-(SP) // product move.l A2,-(SP) // revision move.l A1,-(SP) // vendor @@ -1741,13 +1759,13 @@ _install_usb_stor: move.l D1,-(SP) // part_type move.l D0,-(SP) // dev_num bsr install_pun_drive - lea 28(SP),SP + lea 36(SP),SP bra.s .end_usb_install .error_usb_install: moveq #0,D0 // not installed .end_usb_install: - movem.l (SP),D1-D4/A0-A3 - lea 32(SP),SP + movem.l (SP),D1-D5/A0-A3 + lea 36(SP),SP rts _uninstall_usb_stor: @@ -1756,23 +1774,25 @@ _uninstall_usb_stor: movem.l D0-D3/A0-A1,(SP) move.l 28(SP),D0 // dev_num cmp.l #PUN_DEV,D0 - bhi.s .error_usb_uninstall // error + bhi .error_usb_uninstall // error move.l _usb_1st_disk_drive,D2 - beq.s .error_usb_uninstall + beq .error_usb_uninstall or.l #PUN_USB,D0 - move.l pun_ptr,A1 + move.l pun_ptr,D1 + beq.s .error_usb_uninstall + move.l D1,A1 .loop_uninstall_usb_part: moveq #0,D1 - move.b pinfo_pun(A1,D2.l),D1 + move.b _pinfo_pun(A1,D2.l),D1 cmp.l D1,D0 bne.s .not_this_usb_devnum - move.w pinfo_puns(A1),D1 + move.w _pinfo_puns(A1),D1 subq.l #1,D1 - move.w D1,pinfo_puns(A1) + move.w D1,_pinfo_puns(A1) moveq #-1,D1 - move.b D1,pinfo_pun(A1,D2.l) - clr.l pinfo_pstart(A1,D2.l*4) - lea pinfo_psize(A1),A0 + move.b D1,_pinfo_pun(A1,D2.l) + clr.l _pinfo_pstart(A1,D2.l*4) + lea _pinfo_psize(A1),A0 clr.l (A0,D2.l*4) move.l _drvbits,D1 bclr D2,D1 @@ -1781,6 +1801,28 @@ _uninstall_usb_stor: addq.l #1,D2 cmp.l #MAX_LOGICAL_DRIVE,D2 bcs.s .loop_uninstall_usb_part +#ifndef COLDFIRE + move.l pun_ptr_ahdi,D1 + beq.s .error_usb_uninstall + move.l D1,A1 +.loop_uninstall_usb_part_ahdi: + moveq #0,D1 + move.b pinfo_pun(A1,D2.l),D1 + cmp.l D1,D0 + bne.s .not_this_usb_devnum_ahdi + move.w pinfo_puns(A1),D1 + subq.l #1,D1 + move.w D1,pinfo_puns(A1) + moveq #-1,D1 + move.b D1,pinfo_pun(A1,D2.l) + clr.l pinfo_pstart(A1,D2.l*4) + lea pinfo_psize(A1),A0 + clr.l (A0,D2.l*4) +.not_this_usb_devnum_ahdi: + addq.l #1,D2 + cmp.l #16,D2 + bcs.s .loop_uninstall_usb_part_ahdi +#endif /* !COLDFIRE */ .error_usb_uninstall: movem.l (SP),D0-D3/A0-A1 lea 24(SP),SP @@ -1792,44 +1834,44 @@ _uninstall_usb_stor: install_pun_drive: - lea -32(SP),SP - movem.l D1-D4/A0-A3,(SP) + lea -36(SP),SP + movem.l D1-D4/A0-A4,(SP) move.l pun_ptr,D0 bne.s .pinfo_ok move.w #3,-(SP) // TT ram if possible - move.l #pinfo_size,-(SP) + move.l #_pinfo_size,-(SP) move.w #0x44,-(SP) // Mxalloc trap #1 addq.l #8,SP move.l D0,pun_ptr beq.s .no_pinfo move.l D0,A3 - clr.w pinfo_puns(A3) - lea pinfo_pun(A3),A0 + clr.w _pinfo_puns(A3) + lea _pinfo_pun(A3),A0 moveq #-1,D0 move.w D0,(A0)+ // drives A/B move.l D0,(A0)+ move.l D0,(A0)+ move.l D0,(A0)+ move.w D0,(A0) - lea pinfo_pstart(A3),A0 - lea pinfo_size(A3),A1 + lea _pinfo_pstart(A3),A0 + lea _pinfo_size(A3),A1 .clrpun: clr.w -(A1) cmp.l A0,A1 bgt.s .clrpun - lea pinfo_cookie(A3),A0 + lea _pinfo_cookie(A3),A0 move.l #0x41484449,(A0) // AHDI move.l A0,4(A0) move.w #0x0300,D0 - move.w D0,pinfo_vernum(A3) + move.w D0,_pinfo_vernum(A3) move.w #0x4000,D0 - move.w D0,pinfo_maxsiz(A3) + move.w D0,_pinfo_maxsiz(A3) move.l A3,D0 // pun_ptr .pinfo_ok: move.l D0,A3 // pun_ptr #if defined(MCF547X) && defined(SD_CARD_REPLACE_FLOPPY) - move.l 36(SP),D2 // dev_num + move.l 40(SP),D2 // dev_num moveq #PUN_USB,D0 and.l D2,D0 bne.s .usb_pun @@ -1850,19 +1892,32 @@ install_pun_drive: moveq #0,D0 // not installed bra .end_usb_disk .drive_not_exist_usb: - move.w pinfo_puns(A3),D0 + move.w _pinfo_puns(A3),D0 addq.l #1,D0 - move.w D0,pinfo_puns(A3) + move.w D0,_pinfo_puns(A3) moveq #0,D0 bset #7,D0 // changed - lea pinfo_flags(A3),A0 - move.l D0,(A0,D4.l*4) // B15:swap, B7:change, B0:bootable - lea pinfo_psize(A3),A0 - move.l 48(SP),D3 // part_size - move.l 44(SP),D1 // part_offset - move.l 40(SP),D2 // part_type - move.l 36(SP),D0 // dev_num - move.l D2,pinfo_ptype(A3,D4.l*4) + lea _pinfo_flags(A3),A0 + move.w D0,(A0,D4.l*2) // B15:swap, B14:stop, B7:change, B0:bootable + lea _pinfo_psize(A3),A0 + move.l 52(SP),D3 // part_size + move.l 48(SP),D1 // part_offset +#ifndef COLDFIRE + lea 0,A4 + cmp.l #16,D4 // maximum drives for AHDI pun structure + bcc.s .no_pun_ptr_ahdi + move.l pun_ptr_ahdi,D0 + move.l D0,A4 + beq.s .no_pun_ptr_ahdi + move.w pinfo_puns(A4),D0 + addq.l #1,D0 + move.w D0,pinfo_puns(A4) + move.l D1,pinfo_pstart(A4,D4.l*4) +.no_pun_ptr_ahdi: +#endif /* !COLDFIRE g*/ + move.l 44(SP),D2 // part_type + move.l 40(SP),D0 // dev_num + move.l D2,_pinfo_ptype(A3,D4.l*4) and.l #0xFFFFFF,D2 // ID // GEMDOS cmp.l #0x47454D,D2 // GEM up to 16M @@ -1882,9 +1937,15 @@ install_pun_drive: move.l #0x400000,D3 // 2GB limit .no_limit_size: move.l D0,D2 - move.b D2,pinfo_pun(A3,D4.l) + move.b D2,_pinfo_pun(A3,D4.l) +#ifndef COLDFIRE + move.l A4,D0 + beq.s .no_pun_ptr_ahdi2 + move.b D2,pinfo_pun(A4,D4.l) +.no_pun_ptr_ahdi2: +#endif /* !COLDFIRE */ move.l D3,(A0,D4.l*4) // size - move.l D1,pinfo_pstart(A3,D4.l*4) + move.l D1,_pinfo_pstart(A3,D4.l*4) move.l _dskbufp,A0 #ifdef MCF547X moveq #PUN_USB,D0 @@ -1945,12 +2006,12 @@ install_pun_drive: bsr install_xbra move.l D0,old_hdv_mediach_usb move.l cookie,D0 - beq.s .no_cookie_jar + beq .no_cookie_jar move.l D0,A0 move.l #0x58484449,D1 // XHDI .find_cookie_jar: tst.l (A0) - beq.s .cookie_slot_free + beq .cookie_slot_free cmp.l (A0),D1 beq.s .cookie_found addq.l #8,A0 @@ -1958,6 +2019,26 @@ install_pun_drive: .cookie_found: move.l A0,-(SP) move.l 4(A0),D0 + +#ifdef DEBUG_XHDI + move.l D0,-(SP) + moveq #0x61,D0 + jsr display_char + moveq #0x20,D0 + jsr display_char + move.l A0,D0 + jsr hex_long + moveq #0x20,D0 + jsr display_char + move.l (SP),D0 + jsr hex_long + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char + move.l (SP)+,D0 +#endif + move.l D0,old_xhdi clr.l -(SP) // XHGetVersion move.l D0,A0 @@ -1965,6 +2046,7 @@ install_pun_drive: addq.l #4,SP move.l D0,old_xhdi_version lea xhdi(PC),A1 +#if 0 move.l A1,-(SP) move.w #9,-(SP) // XHNewCookie move.l old_xhdi,A0 @@ -1974,6 +2056,33 @@ install_pun_drive: move.l (SP)+,A0 tst.l D0 beq.s .no_cookie_jar +#else + move.l (SP)+,A0 +#endif + +#ifdef DEBUG_XHDI + move.l D0,-(SP) + moveq #0x62,D0 + jsr display_char + moveq #0x20,D0 + jsr display_char + move.l A0,D0 + jsr hex_long + moveq #0x20,D0 + jsr display_char + move.l A1,D0 + jsr hex_long + moveq #0x20,D0 + jsr display_char + move.l (SP),D0 + jsr hex_long + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char + move.l (SP)+,D0 +#endif + move.l A1,4(A0) // replace cookie bra.s .no_cookie_jar .cookie_slot_free: @@ -1993,11 +2102,11 @@ install_pun_drive: move.l D4,_usb_1st_disk_drive .sd_1st_drive_ok: move.l _dskbufp,A0 // boot sector - lea pinfo_bpb(A3),A1 + lea _pinfo_bpb(A3),A1 move.l D4,D2 // logical drive mulu #18,D2 // * 18 add.l D2,A1 - move.l pinfo_ptype(A3,D4.l*4),D2 // part_type + move.l _pinfo_ptype(A3,D4.l*4),D2 // part_type move.l D2,D1 and.l #0xFFFFFF,D1 // ID // GEMDOS @@ -2066,7 +2175,7 @@ install_pun_drive: asl.l #8,D2 move.b 0x13(A0),D2 // NSECTS bne.s .nsects_ok_usb - lea pinfo_psize(A3),A2 + lea _pinfo_psize(A3),A2 move.l (A2,D4.l*4),D2 // partition size in sectors sub.l D0,D2 // - 1st data sector .nsects_ok_usb: @@ -2098,7 +2207,7 @@ install_pun_drive: cmp.l D4,D0 bne.s .no_set_drive_usb move.w D0,_bootdev -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) move.l _pxCurrentTCB,D1 cmp.l _tid_TOS,D1 bne.s .no_set_drive_usb @@ -2109,20 +2218,27 @@ install_pun_drive: addq.l #4,SP .no_set_drive_usb: move.l D4,D1 // logical drive - move.l pinfo_ptype(A3,D4.l*4),D2 // part_type - lea pinfo_psize(A3),A0 + move.l _pinfo_ptype(A3,D4.l*4),D2 // part_type + lea _pinfo_psize(A3),A0 move.l (A0,D4.l*4),D3 // partition size in sectors moveq #PUN_USB+PUN_DEV,D0 - and.l 36(SP),D0 // devnum - movem.l 52(SP),A1/A2/A3 // vendor / revision / product + and.l 40(SP),D0 // devnum + movem.l 68(SP),A1/A2 // number_of_blocks / block_size + lea number_of_blocks,A0 + move.l A1,(A0,D0.l*4) + lea block_size,A0 + move.l A2,(A0,D0.l*4) + movem.l 56(SP),A1/A2/A3 // vendor / revision / product + lea vendor_name,A0 // save vendor name pointer for XHDI + move.l A1,(A0,D0.l*4) lea product_name,A0 // save product name pointer for XHDI move.l A3,(A0,D0.l*4) -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) move.l _pxCurrentTCB,D0 cmp.l _tid_TOS,D0 bne.s .no_display_drive_usb #endif - move.l 36(SP),D0 // devnum + move.l 40(SP),D0 // devnum bsr display_drive_usb .no_display_drive_usb: move.l D4,D0 // OK @@ -2133,13 +2249,13 @@ install_pun_drive: .drive_full_usb: pea error2(PC) .display_error_usb: -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) move.l _pxCurrentTCB,D0 cmp.l _tid_TOS,D0 bne.s .no_display_error_usb #endif - move.l 36+4(SP),D0 // devnum - movem.l 52+4(SP),A1/A2/A3// vendor / revision / product + move.l 40+4(SP),D0 // devnum + movem.l 56+4(SP),A1/A2/A3// vendor / revision / product bsr display_drive_usb move.w #0x2C,-(SP) move.w #2,-(SP) @@ -2156,8 +2272,8 @@ install_pun_drive: addq.l #4,SP moveq #0,D0 // not installed .end_usb_disk: - movem.l (SP),D1-D4/A0-A3 - lea 32(SP),SP + movem.l (SP),D1-D4/A0-A4 + lea 36(SP),SP .return: rts @@ -2184,7 +2300,7 @@ display_drive_usb: trap #1 // Cconws addq.l #6,SP move.w #2,-(SP) - trap #1 // Cconout + trap #1 // Cconout (device number) addq.l #4,SP move.w #0x2E,-(SP) // . move.w #2,-(SP) @@ -2203,29 +2319,34 @@ display_drive_usb: trap #1 // Cconout addq.l #4,SP move.w #9,-(SP) - trap #1 // Cconws + trap #1 // Cconws (vendor) addq.l #2,SP .no_vendor: addq.l #4,SP - move.l A2,D0 - beq.s .no_revision + move.l A3,D0 + beq.s .no_product move.w #0x20,-(SP) move.w #2,-(SP) trap #1 // Cconout addq.l #4,SP - move.l A2,-(SP) // revision + move.l A3,-(SP) // product move.w #9,-(SP) trap #1 // Cconws addq.l #6,SP -.no_revision: +.no_product: +#if 0 + move.l A2,D0 + beq.s .no_revision move.w #0x20,-(SP) move.w #2,-(SP) trap #1 // Cconout addq.l #4,SP - move.l A3,-(SP) // product + move.l A2,-(SP) // revision move.w #9,-(SP) trap #1 // Cconws addq.l #6,SP +.no_revision: +#endif pea message4(PC) move.w #9,-(SP) trap #1 // Cconws @@ -2260,7 +2381,7 @@ display_drive_usb: addq.l #6,SP add.l #1024,D3 moveq #11,D0 - lsr.l D0,D3 // sector size / 1024*2 => MB + lsr.l D0,D3 // size in sectors / 1024*2 => MB move.l #10,-(SP) move.l D3,-(SP) pea -16(A6) @@ -2280,7 +2401,9 @@ display_drive_usb: det_hdv_bpb_usb: move.l A0,-(SP) - move.l pun_ptr,A0 + move.l pun_ptr,D0 + beq.s .dhbu7 + move.l D0,A0 moveq #0,D0 move.w 4+4(SP),D0 // drive #ifdef MCF547X @@ -2304,7 +2427,7 @@ det_hdv_bpb_usb: #endif bra.s .dhbu2 // error .dhbu4: - tst.b pinfo_pun(A0,D0.l) + tst.b _pinfo_pun(A0,D0.l) bpl.s .dhbu1 .dhbu2: move.l (SP)+,A0 @@ -2313,7 +2436,7 @@ det_hdv_bpb_usb: rts .dhbu1: move.l D1,-(SP) - move.l pinfo_ptype(A0,D0.l*4),D1 + move.l _pinfo_ptype(A0,D0.l*4),D1 // from ROOT sector cmp.l #0x47454D,D1 // GEM beq.s .dhbu3 @@ -2328,11 +2451,19 @@ det_hdv_bpb_usb: beq.s .dhbu3 .dhbu6: move.l (SP)+,D1 +.dhbu7: move.l (SP)+,A0 moveq #0,D0 // not for TOS rts .dhbu3: - lea pinfo_bpb(A0),A0 + move.l A0,D1 + lea _pinfo_flags(A0),A0 + add.l D0,A0 + add.l D0,A0 + btst #6,(A0) // stop + bne.s .dhbu6 + move.l D1,A0 + lea _pinfo_bpb(A0),A0 mulu #18,D0 // * 18 add.l A0,D0 move.l D0,A0 @@ -2362,7 +2493,9 @@ det_hdv_rw_usb: movem.l D1-D4/A0-A2,(SP) btst #3,5+28(SP) // rwflag bne.s .dhru8 // physical - move.l pun_ptr,A0 + move.l pun_ptr,D0 + beq.s .dhru18 + move.l D0,A0 moveq #0,D0 move.w 14+28(SP),D0 // drive #ifdef MCF547X @@ -2387,7 +2520,7 @@ det_hdv_rw_usb: bra.s .dhru8 // error .dhru9: moveq #0,D4 - move.b pinfo_pun(A0,D0.l),D4 + move.b _pinfo_pun(A0,D0.l),D4 bpl.s .dhru1 // valid .dhru8: movem.l (SP),D1-D4/A0-A2 @@ -2395,6 +2528,12 @@ det_hdv_rw_usb: moveq #0,D0 move.l old_hdv_rw_usb,-(SP) rts +.dhru18: + moveq #-15,D0 // unknown device + bra .dhru3 +.dhru19: + moveq #-2,D0 // device not responding + bra .dhru3 .dhru1: #ifdef DEBUG move.l D0,-(SP) @@ -2442,6 +2581,11 @@ det_hdv_rw_usb: move.l (SP)+,A0 move.l (SP)+,D0 #endif + lea _pinfo_flags(A0),A1 + add.l D0,A1 + add.l D0,A1 + btst #6,(A1) // stop + bne .dhru19 #ifdef MCF547X move.l D4,D2 beq.s .dhru10 @@ -2462,12 +2606,12 @@ det_hdv_rw_usb: bmi .dhru2 // negative logical sector move.l 6+28(SP),D1 // buffer beq .dhru4 // no buffer - move.l pinfo_pstart(A0,D0.l*4),D3 - lea pinfo_bpb(A0),A0 + move.l _pinfo_pstart(A0,D0.l*4),D3 + lea _pinfo_bpb(A0),A0 mulu #18,D0 // * 18 add.l D0,A0 move.w 14(A0),D0 // total clusters - mulu.w 2(A0),D0 // cluster size in sectors + mulu 2(A0),D0 // cluster size in sectors cmp.l D0,D2 // logical sector to hight bcc .dhru2 moveq #0,D0 @@ -2585,7 +2729,9 @@ det_hdv_rw_usb: det_hdv_mediach_usb: move.l A0,-(SP) - move.l pun_ptr,A0 + move.l pun_ptr,D0 + beq.s .dhmu5 + move.l D0,A0 moveq #0,D0 move.w 4+4(SP),D0 // drive #ifdef MCF547X @@ -2609,13 +2755,21 @@ det_hdv_mediach_usb: #endif bra.s .dhmu2 // error .dhmu3: - tst.b pinfo_pun(A0,D0.l) + tst.b _pinfo_pun(A0,D0.l) bpl.s .dhmu1 .dhmu2: move.l (SP)+,A0 moveq #0,D0 move.l old_hdv_mediach_usb,-(SP) rts +.dhmu5: + move.l (SP)+,A0 + moveq #-46,D0 // invalid drive number + rts +.dhmu6: + move.l (SP)+,A0 + moveq #-2,D0 // device not responding + rts .dhmu1: #if 0 // #ifdef DEBUG move.l A0,-(SP) @@ -2623,12 +2777,18 @@ det_hdv_mediach_usb: jsr display_string move.l (SP)+,A0 #endif - lea pinfo_flags(A0),A0 + lea _pinfo_flags(A0),A0 add.l D0,A0 add.l D0,A0 - bclr #7,1(A0) + btst #6,(A0) // stop + bne.s .dhmu6 + bclr #7,1(A0) // change sne.b D0 +#ifdef COLDFIRE // for BDOS + and.l #1,D0 +#else and.l #2,D0 +#endif move.l (SP)+,A0 rts @@ -2655,6 +2815,8 @@ xhdi: move.w tab_xhdi(PC,D1.l*2),D1 bmi.s .default_xhdi jsr tab_xhdi(PC,D1.l) + cmp.l #0xBAD0CA11,D0 // key word BAD CALL => call old_xhdi handler + beq.s .default_xhdi #ifdef DEBUG_XHDI move.l D0,-(SP) lea debug130(PC),A0 @@ -2667,8 +2829,6 @@ xhdi: jsr display_char move.l (SP)+,D0 #endif - cmp.l #0xBAD0CA11,D0 // key word BAD CALL => call old_xhdi handler - beq.s .default_xhdi #ifdef COLDFIRE movem.l (SP),D1-A5 lea 52(SP),SP @@ -2678,6 +2838,23 @@ xhdi: unlk A6 rts .default_xhdi: +#if 0 // #ifdef DEBUG_XHDI + move.l D0,-(SP) + lea debug146(PC),A0 + jsr display_string + move.l old_xhdi,D0 + jsr hex_long + lea debug147(PC),A0 + jsr display_string + move.w 8(A6),D0 + jsr hex_word + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char + move.l (SP)+,D0 +#endif + #ifdef COLDFIRE movem.l (SP),D1-A5 lea 52(SP),SP @@ -2748,7 +2925,7 @@ XHInqTarget2: #ifdef DEBUG_XHDI move.w 10(A6),D0 // major jsr hex_word - lea debug139(PC),A0 + lea debug140(PC),A0 jsr display_string move.w 12(A6),D0 // minor jsr hex_word @@ -2797,61 +2974,220 @@ XHInqTarget2: move.l 18(A6),D1 beq.s .xi9 move.l D1,A0 // device_flags -// move.l #2,(A0) // removable clr.l (A0) +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) + cmp.l #PUN_USB,D0 + bcs.s .xi9 + cmp.l #PUN_USB+PUN_DEV,D0 + bhi.s .xi9 + move.l #3,(A0) // removable / stoppable +#if 0 + move.l pun_ptr,D1 + beq.s .xi9 + move.l D1,A1 + moveq #0,D1 + moveq #0,D2 +.xi15: + move.b _pinfo_pun(A1,D1.l),D2 + bmi.s .xi16 // nothing + cmp.l D0,D2 + bne.s .xi16 + lea _pinfo_flags(A1),A2 + add.l D1,A1 + add.l D1,A1 + btst #6,(A2) // stop + beq.s .xi16 + bset #6,(A0) // device has been stopped by the driver, from XHDI 1.25 up +.xi16: + addq.l #1,D1 + cmp.l #MAX_LOGICAL_DRIVE,D1 + bcs.s .xi15 +#endif +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) */ .xi9: move.l 22(A6),D1 // product_name beq.s .xi6 move.l D1,A0 - clr.b (A0) and.l #PUN_USB+PUN_DEV,D0 - lea product_name,A1 - move.l (A1,D0.l*4),D0 - beq.s .xi6 // no pointer - move.l D0,A1 + lea vendor_name,A1 + moveq #1,D3 +.xi11: + move.l (A1,D0.l*4),D1 + beq.s .xi4 // no pointer + move.l D1,A2 .xi5: - move.b (A1)+,(A0)+ - beq.s .xi4 - subq.l #1,D2 - bgt.s .xi5 + move.b (A2)+,D1 + beq.s .xi13 + move.b D1,(A0)+ + subq.l #1,D2 + bgt.s .xi5 +.xi12: + clr.b -1(A0) + bra.s .xi6 +.xi13: + tst.l D3 + beq.s .xi14 + move.b #0x20,(A0)+ +.xi14: + subq.l #1,D2 + ble.s .xi12 .xi4: - clr.b -1(A0) + lea product_name,A1 + subq.l #1,D3 + bpl.s .xi11 + clr.b (A0) .xi6: moveq #0,D0 rts XHReserve: XHLock: -XHStop: -XHEject: +#ifdef DEBUG_XHDI + lea debug145(PC),A0 + jsr display_string + move.w 10(A6),D0 // major + jsr hex_word + lea debug140(PC),A0 + jsr display_string + move.w 12(A6),D0 // minor + jsr hex_word + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char +#endif + tst.w 12(A6) // minor + bne.s .xlr2 +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) + moveq #0,D0 + move.w 10(A6),D0 // major + tst.l _usb_1st_disk_drive + beq.s .xlr2 // error + cmp.l #PUN_USB,D0 + bcs.s .xlr2 + cmp.l #PUN_USB+PUN_DEV,D0 + bhi.s .xlr2 +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) */ + moveq #0,D0 + rts +.xlr2: tst.l old_xhdi - bne.s .xnu1 + bne.s .xlr1 moveq #0,D0 rts -.xnu1: +.xlr1: move.l #0xBAD0CA11,D0 rts - -XHDrvMap: - move.l _drvbits,D0 - moveq #0,D1 - moveq #0,D2 - move.l pun_ptr,A0 -.xdm1: - move.b pinfo_pun(A0,D1.L),D2 - bmi.s .xdm4 // nothing -#ifdef MCF547X - tst.l _sd_disk_drive -#ifdef SD_CARD_REPLACE_FLOPPY - bmi.s .xdm5 -#else - beq.s .xdm5 -#endif - tst.l D2 - beq.s .xdm2 // OK -.xdm5: +XHStop: +XHEject: + +#ifdef DEBUG_XHDI + lea debug139(PC),A0 + jsr display_string + move.w 10(A6),D0 // major + jsr hex_word + lea debug140(PC),A0 + jsr display_string + move.w 12(A6),D0 // minor + jsr hex_word + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char +#endif + tst.w 12(A6) // minor + bne.s .xlr2 + moveq #0,D0 + move.w 10(A6),D0 // major +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) + tst.l _usb_1st_disk_drive + beq.s .xlr2 // error + cmp.l #PUN_USB,D0 + bcs.s .xlr2 + cmp.l #PUN_USB+PUN_DEV,D0 + bhi.s .xlr2 + tst.w 14(A6) // do_eject + beq.s .xlr2 + move.l pun_ptr,D1 + beq.s .xe1 + move.l D1,A0 + moveq #0,D1 + moveq #0,D2 + moveq #0,D3 + moveq #0,D4 +.xe3: + move.b _pinfo_pun(A0,D1.l),D2 + bmi.s .xe4 // nothing + cmp.l D0,D2 + bne.s .xe4 + lea _pinfo_flags(A0),A1 + add.l D1,A1 + add.l D1,A1 + bset #6,(A1) // stop + lea vendor_name,A1 + move.l (A1,D2.l*4),D3 + lea product_name,A1 + move.l (A1,D2.l*4),D4 +.xe4: + addq.l #1,D1 + cmp.l #MAX_LOGICAL_DRIVE,D1 + bcs.s .xe3 +.xe1: + link A5,#-128 + lea -128(A5),A2 + pea mess_eject(PC) + pea (A2) + jsr _strcpy + addq.l #8,SP + tst.l D3 + beq.s .xe5 // no vendor + move.l D3,-(SP) + pea (A2) + jsr _strcat + addq.l #8,SP +.xe5: + pea space(PC) + pea (A2) + jsr _strcat + addq.l #8,SP + tst.l D4 + beq.s .xe6 // no product + move.l D4,-(SP) + pea (A2) + jsr _strcat + addq.l #8,SP +.xe6: + pea (A2) + jsr _usb_error_msg // send message for an alert under TOS + addq.l #4,SP + unlk A5 +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) */ + moveq #0,D0 + rts + +XHDrvMap: + + move.l pun_ptr,D0 + beq.s .xdm3 + move.l D0,A0 + move.l _drvbits,D0 + moveq #0,D1 + moveq #0,D2 +.xdm1: + move.b _pinfo_pun(A0,D1.l),D2 + bmi.s .xdm4 // nothing +#ifdef MCF547X + tst.l _sd_disk_drive +#ifdef SD_CARD_REPLACE_FLOPPY + bmi.s .xdm5 +#else + beq.s .xdm5 +#endif + tst.l D2 + beq.s .xdm2 // OK +.xdm5: #endif /* MCF547X */ #if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) tst.l _usb_1st_disk_drive @@ -2902,7 +3238,9 @@ XHInqDev: moveq #10,D0 jsr display_char #endif - move.l pun_ptr,A0 + move.l pun_ptr,D0 + beq.s .xd11 + move.l D0,A0 moveq #0,D0 move.w 10(A6),D0 // bios_device #ifdef MCF547X @@ -2927,11 +3265,12 @@ XHInqDev: bra.s .xd2 // error .xd8: moveq #0,D1 - move.b pinfo_pun(A0,D0.l),D1 + move.b _pinfo_pun(A0,D0.l),D1 bpl.s .xd1 .xd2: tst.l old_xhdi bne.s .xd3 +.xd11: moveq #-46,D0 // invalid drive number rts .xd3: @@ -2961,23 +3300,32 @@ XHInqDev: .xd5: tst.l 20(A6) beq.s .xd6 - move.l pinfo_pstart(A0,D0.l*4),D1 + move.l _pinfo_pstart(A0,D0.l*4),D1 move.l 20(A6),A1 // start_sector move.l D1,(A1) .xd6: - lea pinfo_bpb(A0),A0 - mulu #18,D0 // * 18 - add.l D0,A0 + lea _pinfo_bpb(A0),A2 + move.l D0,D1 + mulu #18,D1 // * 18 + add.l D1,A2 tst.l 24(A6) beq.s .xd7 move.l 24(A6),A1 // bpb - move.l (A0)+,(A1)+ - move.l (A0)+,(A1)+ - move.l (A0)+,(A1)+ - move.l (A0)+,(A1)+ - move.w (A0)+,(A1)+ + move.l (A2)+,(A1)+ + move.l (A2)+,(A1)+ + move.l (A2)+,(A1)+ + move.l (A2)+,(A1)+ + move.w (A2)+,(A1)+ .xd7: - moveq #0,D0 + lea _pinfo_flags(A0),A1 + add.l D0,A1 + add.l D0,A1 + btst #6,(A1) // stop + beq.s .xd12 + moveq #-2,D0 // device not responding + rts +.xd12: + moveq #0,D0 // OK rts XHInqDriver: @@ -2992,7 +3340,9 @@ XHInqDriver: moveq #10,D0 jsr display_char #endif - move.l pun_ptr,A0 + move.l pun_ptr,D0 + beq.s .xdr12 + move.l D0,A0 moveq #0,D0 move.w 10(A6),D0 // bios_device #ifdef MCF547X @@ -3017,11 +3367,12 @@ XHInqDriver: bra.s .xdr2 // error .xdr9: moveq #0,D1 - move.b pinfo_pun(A0,D0.l),D1 + move.b _pinfo_pun(A0,D0.l),D1 bpl.s .xdr1 .xdr2: tst.l old_xhdi bne.s .xdr8 +.xdr12: moveq #-46,D0 // invalid drive number rts .xdr8: @@ -3043,12 +3394,12 @@ XHInqDriver: beq.s .xdr3 move.l D0,A1 lea message1(PC),A0 - moveq #17,D1 + moveq #17,D2 .xdr6: move.b (A0)+,D0 beq.s .xdr7 move.b D0,(A1)+ - subq.l #1,D1 + subq.l #1,D2 bpl.s .xdr6 .xdr7: clr.b (A1) @@ -3069,11 +3420,19 @@ XHInqDriver: .xdr5: move.l 24(A6),A1 // ahdi_version move.l pun_ptr,A0 - move.w pinfo_vernum(A0),(A1) + move.w _pinfo_vernum(A0),(A1) move.l 28(A6),A1 // maxIPL - moveq #5,D0 + moveq #4,D0 move.w D0,(A1) - moveq #0,D0 + lea _pinfo_flags(A0),A1 + add.l D1,A1 + add.l D1,A1 + btst #6,(A1) // stop + beq.s .xdr13 + moveq #-2,D0 // device not responding + rts +.xdr13: + moveq #0,D0 // OK rts XHReadWrite: // read / write physical sectors @@ -3083,23 +3442,23 @@ XHReadWrite: // read / write physical sectors jsr display_string move.w 10(A6),D0 // major jsr hex_word - lea debug139(PC),A0 + lea debug140(PC),A0 jsr display_string move.w 12(A6),D0 // minor jsr hex_word - lea debug140(PC),A0 + lea debug141(PC),A0 jsr display_string move.w 14(A6),D0 // rwflag jsr hex_word - lea debug141(PC),A0 + lea debug142(PC),A0 jsr display_string move.l 16(A6),D0 // recno jsr hex_long - lea debug142(PC),A0 + lea debug143(PC),A0 jsr display_string move.w 20(A6),D0 // count jsr hex_word - lea debug143(PC),A0 + lea debug144(PC),A0 jsr display_string move.l 22(A6),D0 // buffer jsr hex_long @@ -3136,10 +3495,33 @@ XHReadWrite: // read / write physical sectors bne.s .xr6 moveq #-15,D0 // unknown device rts +.xr15: + moveq #-2,D0 // device not responding + rts .xr6: move.l #0xBAD0CA11,D0 rts .xr1: + move.l pun_ptr,D0 + beq.s .xr16 + move.l D0,A0 + moveq #0,D1 + moveq #0,D2 +.xr13: + move.b _pinfo_pun(A0,D1.l),D2 + bmi.s .xr14 // nothing + cmp.l D4,D2 + bne.s .xr14 + lea _pinfo_flags(A0),A1 + add.l D1,A1 + add.l D1,A1 + btst #6,(A1) // stop + bne.s .xr15 +.xr14: + addq.l #1,D1 + cmp.l #MAX_LOGICAL_DRIVE,D1 + bcs.s .xr13 +.xr16: move.l 22(A6),A0 // buffer moveq #0,D3 move.w 20(A6),D3 // count @@ -3221,7 +3603,9 @@ XHInqDev2: moveq #10,D0 jsr display_char #endif - move.l pun_ptr,A0 + move.l pun_ptr,D0 + beq.s .xdd14 + move.l D0,A0 moveq #0,D0 move.w 10(A6),D0 // bios_device #ifdef MCF547X @@ -3246,11 +3630,12 @@ XHInqDev2: bra.s .xdd2 // error .xdd12: moveq #0,D1 - move.b pinfo_pun(A0,D0.l),D1 + move.b _pinfo_pun(A0,D0.l),D1 bpl.s .xdd1 .xdd2: tst.l old_xhdi bne.s .xdd4 +.xdd14: moveq #-46,D0 // invalid drive number rts .xdd4: @@ -3280,13 +3665,13 @@ XHInqDev2: .xdd6: tst.l 20(A6) beq.s .xdd7 - move.l pinfo_pstart(A0,D0.l*4),D1 + move.l _pinfo_pstart(A0,D0.l*4),D1 move.l 20(A6),A1 // start_sector move.l D1,(A1) .xdd7: tst.l 24(A6) beq.s .xdd8 - lea pinfo_bpb(A0),A2 + lea _pinfo_bpb(A0),A2 move.l D0,D1 mulu #18,D1 // * 18 add.l D1,A2 @@ -3300,25 +3685,83 @@ XHInqDev2: tst.l 28(A6) beq.s .xdd9 move.l 28(A6),A1 // blocks - lea pinfo_psize(A0),A2 + lea _pinfo_psize(A0),A2 move.l (A2,D0.l*4),(A1) .xdd9: tst.l 32(A6) beq.s .xdd10 move.l 32(A6),A1 // partid - move.b pinfo_ptype+1(A0,D0.l*4),(A1)+ - move.b pinfo_ptype+2(A0,D0.l*4),D1 + move.b _pinfo_ptype+1(A0,D0.l*4),(A1)+ + move.b _pinfo_ptype+2(A0,D0.l*4),D1 bne.s .xdd3 // Atari partition moveq #0x44,D1 // D for MSDOS .xdd3: move.b D1,(A1)+ - move.b pinfo_ptype+3(A0,D0.l*4),(A1) + move.b _pinfo_ptype+3(A0,D0.l*4),(A1) .xdd10: + lea _pinfo_flags(A0),A1 + add.l D0,A1 + add.l D0,A1 + btst #6,(A1) // stop + beq.s .xdd15 + moveq #-2,D0 // device not responding + rts +.xdd15: + moveq #0,D0 // OK + rts + +XHGetCapacity: + +#ifdef DEBUG_XHDI + lea debug148(PC),A0 + jsr display_string + move.w 10(A6),D0 // major + jsr hex_word + lea debug140(PC),A0 + jsr display_string + move.w 12(A6),D0 // minor + jsr hex_word + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char +#endif + tst.w 12(A6) // minor + bne.s .xgc2 moveq #0,D0 + move.w 10(A6),D0 // major +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) + tst.l _usb_1st_disk_drive + beq.s .xgc2 // error + cmp.l #PUN_USB,D0 + bcs.s .xgc2 + cmp.l #PUN_USB+PUN_DEV,D0 + bhi.s .xgc2 + move.l 14(A6),D1 // blocks + beq.s .xgc3 + move.l D1,A1 + lea number_of_blocks,A0 + move.l (A0,D0.l*4),(A1) +.xgc3: + move.l 18(A6),D1 // blocksize + beq.s .xgc4 + move.l D1,A1 + lea block_size,A0 + move.l (A0,D0.l*4),(A1) +.xgc4: + moveq #0,D0 + rts +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) */ +.xgc2: + tst.l old_xhdi + bne.s .xgc1 + moveq #-32,D0 // invalid function number + rts +.xgc1: + move.l #0xBAD0CA11,D0 rts XHDriverSpecial: -XHGetCapacity: XHMediumChanged: XHMiNTInfo: XHNewCookie: @@ -3341,7 +3784,7 @@ XHDOSLimits: moveq #13,D0 jsr display_char moveq #10,D0 - jsr display_char + jsr display_char #endif tst.l old_xhdi bne.s .xn1 @@ -3400,8 +3843,336 @@ XHDOSLimits: #endif /* ((defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE)) || defined(MCF547X) */ +#if !defined(COLDFIRE) || defined(MCF547X) + +_install_cd_disk: + + lea -32(SP),SP + movem.l D1-D4/A0-A3,(SP) + move.l _dskbufp,-(SP) // buffer + moveq #1,D0 + move.l D0,-(SP) // num_sectors + clr.l -(SP) // sector_start + jsr _cd_disk_read_sectors + addq.l #8,SP + move.l (SP)+,A0 // buffer + tst.l D0 + bne .error_install_cd_disk + moveq #0,D2 + move.l #256,D1 +.loop_sum_root_cd_disk: + moveq #0,D0 + move.w (A0)+,D0 + add.l D0,D2 + subq.l #1,D1 + bgt.s .loop_sum_root_cd_disk + move.l _dskbufp,A0 + move.l (A0),D0 + and.l #0xFFFF,D0 + cmp.l #0x4344,D0 // CD + bne.s .check_crc_cd_disk + move.l 4(A0),D0 + cmp.l #0x6261636B,D0 // back + beq.s .cd_backup_found +.check_crc_cd_disk: + and.l #0xFFFF,D2 + cmp.l #0x1234,D2 // checksum + bne.s .error_install_cd_disk + lea 0x1C6(A0),A0 // partition table + moveq #4,D4 +.loop_partitions_tos_cd_disk: + move.l (A0),D1 + and.l #0xFFFFFF,D1 // part_type + beq.s .next_partition_tos_cd_disk + cmp.l #0x58474D,D1 // XGM + beq.s .next_partition_tos_cd_disk + move.l 4(A0),D2 // part_offset + move.l 8(A0),D3 // part_size + bra.s .install_partition_cd_disk +.next_partition_tos_cd_disk: + lea 12(A0),A0 + subq.l #1,D4 + bgt.s .loop_partitions_tos_cd_disk +.cd_backup_found: + moveq #0,D2 // no partition table + moveq #0,D2 + move.l #0x42474D,D1 // BGM + bra.s .install_partition_cd_disk +.error_install_cd_disk: + moveq #0,D0 // nothing installed + bra .end_install_cd_disk +.install_partition_cd_disk: + move.l D1,part_type_cd + move.l D2,part_offset_cd + move.l D3,part_size_cd + move.l _dskbufp,-(SP) // buffer + moveq #1,D0 + move.l D0,-(SP) // num_sectors + move.l D2,-(SP) // part_offset + jsr _cd_disk_read_sectors + lea 12(SP),SP + tst.l D0 + bne .error_install_cd_disk + move.l _dskbufp,A0 // boot sector + lea tab_bpb_cd,A1 + move.l part_type_cd,D1 + and.l #0xFFFFFF,D1 // ID GEMDOS + cmp.l #0x47454D,D1 // GEM up to 16M + beq.s .partition_ok_cd + cmp.l #0x42474D,D1 // BGM over 16M + bne .error_install_cd_disk +.partition_ok_cd: + moveq #0,D2 + move.b 0xC(A0),D2 + asl.l #8,D2 + move.b 0xB(A0),D2 // BPS + move.w D2,(A1) // sector size in bytes + beq .error_install_cd_disk + moveq #0,D1 + move.b 0xD(A0),D1 // SPC + move.w D1,2(A1) // cluster size in sectors + move.w D1,D0 + mulu D2,D0 + move.w D0,4(A1) // cluster size in bytes + moveq #0,D0 + move.b 0x12(A0),D0 + asl.l #8,D0 + move.b 0x11(A0),D0 // NDIRS + asl.l #5,D0 // * 32 + tst.l D2 + beq .error_install_cd_disk +#ifdef COLDFIRE + .chip 68060 +#endif + divu D2,D0 // / sector size +#ifdef COLDFIRE + .chip 5200 +#endif + move.w D0,6(A1) // size directory in sectors + moveq #0,D2 + move.b 0x17(A0),D2 + asl.l #8,D2 + move.b 0x16(A0),D2 // SPF + move.w D2,8(A1) // FAT size + moveq #0,D0 + move.b 0xF(A0),D0 + asl.l #8,D0 + move.b 0xE(A0),D0 // RES + move.l D0,D3 + add.l D2,D3 // + FAT size + move.w D3,10(A1) // 1st sector of FAT2 + moveq #0,D3 + move.b 0x10(A0),D3 // NFATS + mulu D2,D3 // * FAT size + add.l D0,D3 // + RES + moveq #0,D0 + move.w 6(A1),D0 // size directory in sectors + add.l D3,D0 + move.w D0,12(A1) // 1st data sector + moveq #0,D2 + move.b 0x14(A0),D2 + asl.l #8,D2 + move.b 0x13(A0),D2 // NSECTS + bne.s .nsects_ok_cd + move.l part_size_cd,D2 // partition size in sectors + beq .error_install_cd_disk + sub.l D0,D2 // - 1st data sector +.nsects_ok_cd: + tst.l D1 + beq .error_install_cd_disk +#ifdef COLDFIRE + .chip 68060 +#endif + divu D1,D2 +#ifdef COLDFIRE + .chip 5200 +#endif + move.w D2,14(A1) // total clusters + moveq #1,D0 + move.w D0,16(A1) // FAT 16 + move.w SR,D0 + move.w D0,-(SP) + or.l #0x700,D0 // mask interrupts + move.w D0,SR + move.l #0x5F43445F,D1 // _CD_ + lea det_hdv_bpb_cd(PC),A0 + move.w #hdv_bpb,D0 + bsr install_xbra + move.l D0,old_hdv_bpb_cd + lea det_hdv_rw_cd(PC),A0 + move.w #hdv_rw,D0 + bsr install_xbra + move.l D0,old_hdv_rw_cd + lea det_hdv_mediach_cd(PC),A0 + move.w #hdv_mediach,D0 + bsr install_xbra + move.l D0,old_hdv_mediach_cd + move.w (SP)+,D0 + move.w D0,SR + moveq #1,D1 // drive B + move.l D1,_cd_disk_drive + moveq #2,D0 + move.l D0,_change_cd_disk + move.l _drvbits,D0 + bset D1,D0 + move.l D0,_drvbits + move.l _cd_disk_drive,D0 // OK +.end_install_cd_disk: + movem.l (SP),D1-D4/A0-A3 + lea 32(SP),SP + rts + +det_hdv_bpb_cd: + + moveq #0,D0 + move.w 4(SP),D0 // drive + cmp.l _cd_disk_drive,D0 + beq.s .dhbc1 + move.l old_hdv_bpb_cd,-(SP) + rts +.dhbc1: + move.l A0,-(SP) +#ifdef DEBUG + lea debug4(PC),A0 + jsr display_string +#endif + lea tab_bpb_cd,A0 + move.l A0,D0 + move.l (SP)+,A0 + rts + +det_hdv_rw_cd: + + moveq #0,D0 + move.w 14(SP),D0 // drive + cmp.l _cd_disk_drive,D0 + beq.s .dhrc1 + move.l old_hdv_rw_cd,-(SP) + rts +.dhrc1: +#ifdef COLDFIRE + lea -20(SP),SP + movem.l D1-D3/A0-A1,(SP) +#else + movem.l D1-D3/A0-A1,-(SP) +#endif +#ifdef DEBUG + lea debug3(PC),A0 + jsr display_string + move.w 4+20(SP),D0 // rwflag + jsr hex_word + moveq #0x20,D0 + jsr display_char + moveq #0x30,D0 + jsr display_char + moveq #0x78,D0 + jsr display_char + move.l 6+20(SP),D0 // buffer + jsr hex_long + moveq #0x20,D0 + jsr display_char + moveq #0x30,D0 + jsr display_char + moveq #0x78,D0 + jsr display_char + move.w 10+20(SP),D0 // num sectors + jsr hex_word + moveq #0x20,D0 + jsr display_char + moveq #0x30,D0 + jsr display_char + moveq #0x78,D0 + jsr display_char + move.w 12+20(SP),D0 // logical sector + jsr hex_word + moveq #0x20,D0 + jsr display_char + moveq #0x30,D0 + jsr display_char + moveq #0x78,D0 + jsr display_char + move.w 14+20(SP),D0 // drive + jsr hex_word + moveq #13,D0 + jsr display_char + moveq #10,D0 + jsr display_char +#endif + moveq #0,D2 + move.w 12+20(SP),D2 // logical sector + bpl.s .dhrc5 + move.l 16+20(SP),D2 // logical sector +.dhrc5: + tst.l D2 + bmi.s .dhrc6 // negative logical sector + move.l 6+20(SP),D1 // buffer + beq.s .dhrc4 + move.l part_offset_cd,D3 + lea tab_bpb_cd,A0 + move.w 14(A0),D0 // total clusters + mulu 2(A0),D0 // cluster size in sectors + cmp.l D0,D2 // logical sector to hight + bcc.s .dhrc6 + moveq #0,D0 + move.w (A0),D0 // sector size + lsr.l #8,D0 + lsr.l #1,D0 // / 512 + move.l D1,A0 // buffer + move.w 10+20(SP),D1 // num sectors + beq.s .dhrc4 // no sectors + mulu D0,D1 + mulu.l D0,D2 + add.l D3,D2 // start sector + move.l D1,D3 // count + btst #0,5+20(SP) // rwflag + beq.s .dhrc2 // read + moveq #-13,D0 // write protect + bra.s .dhrc3 +.dhrc6: + moveq #-1,D0 // error + bra.s .dhrc3 +.dhrc2: + move.l A0,-(SP) // buffer + move.l D3,-(SP) // num_sectors + move.l D2,-(SP) // sector_start + jsr _cd_disk_read_sectors + lea 12(SP),SP + tst.l D0 + ble.s .dhrc3 + moveq #-11,D0 // read error +.dhrc4: + moveq #0,D0 +.dhrc3: +#ifdef COLDFIRE + movem.l (SP),D1-D3/A0-A1 + lea 20(SP),SP +#else + movem.l (SP)+,D1-D3/A0-A1 +#endif + rts -#ifdef NETWORK +det_hdv_mediach_cd: + + moveq #0,D0 + move.w 4(SP),D0 // drive + cmp.l _cd_disk_drive,D0 + beq.s .dhmc1 + move.l old_hdv_mediach_cd,-(SP) + rts +.dhmc1: +#if 0 // #ifdef DEBUG + move.l A0,-(SP) + lea debug5(PC),A0 + jsr display_string + move.l (SP)+,A0 +#endif + move.l _change_cd_disk,D0 + clr.l _change_cd_disk + rts + +#endif /* !defined(COLDFIRE) || defined(MCF547X) */ + +#if defined(COLDFIRE) && defined(LWIP) _install_ram_disk: @@ -3782,21 +4553,7 @@ det_hdv_mediach: move.l _change_ram_disk,D0 clr.l _change_ram_disk rts - -_alert_tos: - - lea -52(SP),SP - movem.l D1-A5,(SP) - move.l 56(SP),A0 // string - pea.l (A0) - move.w #1,-(SP) - jsr 0xE22A68 // form_alert - addq.l #6,SP - movem.l (SP),D1-A5 - lea 52(SP),SP - ext.l D0 - rts - + #ifdef SOUND_AC97 #ifdef COLDFIRE #ifndef MCF5445X @@ -4165,11 +4922,11 @@ _mcf548x_ac97_record_resample: lea 40(SP),SP rts -#endif/* MCF5445X */ +#endif/* MCF5445X */ #endif /* COLDFIRE */ #endif /* SOUND_AC97 */ -#endif /* NETWORK */ +#endif /* defined(COLFIRE) && defined(LWIP) */ _asm_set_ipl: @@ -4191,7 +4948,6 @@ _asm_set_ipl: rts #ifdef COLDFIRE -#ifdef NETWORK #ifdef LWIP #include "../include/fire.h" @@ -4291,7 +5047,6 @@ _clr_intfrcl: // unforce interrupt #endif /* !defined(MCF547X) && !defined(MCF5445X) */ #endif /* LWIP */ -#endif /* NETWORK */ #ifdef MCF547X @@ -4343,6 +5098,71 @@ _call_ikbdvec: lea -24(SP),SP movem.l D0-D2/A0-A2,(SP) +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(MINT_IKBD_PATCH) + tst.l mint_ikbd_scan + bne .mint_ok + move.l 36(SP),A2 // &kbdvecs[-1] + move.l 0x118,A0 // ACIA MFP interrupt vector +.find_mint_acia: + cmp.l #0x58425241,-12(A0) // XBRA + bne .mint_ok + cmp.l #0x4D694E54,-8(A0) // MiNT + beq.s .mint_acia_found + move.l -4(A0),D0 // next + move.l D0,A0 + bne.s .find_mint_acia + bra .mint_ok +.mint_acia_found: + move.l (A2),A1 // ikbdvec +.find_mint_ikbdvec: + cmp.l #0x58425241,-12(A1) // XBRA + bne.s .mint_ikbdvec_not_found + cmp.l #0x4D694E54,-8(A1) // MiNT + beq.s .mint_ok + move.l -4(A1),D0 // next + move.l D0,A1 + bne.s .find_mint_ikbdvec +.mint_ikbdvec_not_found: + move.l A0,-(SP) // ACIA MFP interrupt vector + pea mess_mint(PC) + jsr _usb_error_msg // send message for an alert under TOS + addq.l #4,SP + move.l (SP)+,A0 // ACIA MFP interrupt vector +.loop_find_mint_rte: + moveq #0,D0 + move.w (A0),D0 + cmp.l #0x4E73,D0 // RTE + beq.s .loop_find_mint_jsr + move.l A0,-(SP) + jsr _M68k_InstrLen + move.l (SP)+,A0 + add.l D0,A0 + add.l D0,A0 + bra.s .loop_find_mint_rte +.loop_find_mint_jsr: + moveq #0,D0 + move.w (A0),D0 + cmp.l #0x4E75,D0 // rts + beq.s .mint_ok + cmp.l #0x4EB9,D0 // jsr + beq.s .mint_jsr_found + move.l A0,-(SP) + jsr _M68k_InstrLen + move.l (SP)+,A0 + add.l D0,A0 + add.l D0,A0 + bra.s .loop_find_mint_jsr +.mint_jsr_found: + move.l 6(A0),D0 + cmp.l #0x5C8F4E75,D0 // addq.l #6,SP rts + bne.s .mint_ok + move.l 2(A0),A0 // jsr address + move.l A0,mint_ikbd_scan + lea ikbd_scan(PC),A0 + move.l 36(SP),A2 // &kbdvecs[-1] + move.l A0,(A2) +.mint_ok: +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(MINT_IKBD_PATCH) */ move.l 28(SP),D0 // ikbd code and.l #0xFF,D0 move.l 32(SP),A0 // iorec @@ -4353,6 +5173,10 @@ _call_ikbdvec: lea 24(SP),SP rts + dc.l 0x58425241 // XBRA + dc.l 0x4D694E54 // MiNT + dc.l 0 + _call_mousevec: lea -24(SP),SP @@ -4364,24 +5188,44 @@ _call_mousevec: movem.l (SP),D0-D2/A0-A2 lea 24(SP),SP rts + +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(MINT_IKBD_PATCH) + +ikbd_scan: + + movem.l D1-D2/A0-A2,-(SP) + move.l A0,-(SP) + and.l #0xFF,D0 + move.w D0,-(SP) + move.l mint_ikbd_scan,A0 + jsr (A0) + addq.l #6,SP + movem.l (SP)+,D1-D2/A0-A2 + rts + +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(MINT_IKBD_PATCH) */ _direct_conout: lea -60(SP),SP movem.l D0-A6,(SP) move.l 64(SP),D1 - and.l #0xff,D1 + and.l #0xFF,D1 #if defined(DEBUG) && !defined(COLDFIRE) tst.w _video_found beq.s .normal_conout move.l D1,D0 - bsr display_char + bsr display_char // display_char can use always the Videl movem.l (SP),D0-A6 lea 60(SP),SP rts .normal_conout: #endif move.l con_state,A0 + tst.w _os_magic + bne.s .os_magic + lea 0x3E86,A4 // TOS404 LINEA vars !!! +.os_magic: jsr (A0) movem.l (SP),D0-A6 lea 60(SP),SP @@ -4398,6 +5242,174 @@ _get_sr: move SR,D0 rts +magic_routine: + + movem.l D0-D1/A0-A1,-(SP) + jsr _init_before_autofolder + movem.l (SP)+,D0-D1/A0-A1 + rts +end_magic_routine: + +_install_magic_routine: + + lea magic_routine(PC),A0 + pea end_magic_routine(PC) + move.l phystop,A1 + lea -1024(A1),A1 // let the space for a boot routine (512 bytes) + move.l #0x12123456,(A1) // magic key + move.l A1,4(A1) + move.w #((512-8)/2)-2,D1 + move.w (A1)+,D0 + add.w (A1)+,D0 + add.w (A1)+,D0 + add.w (A1)+,D0 +.copy_magic_routine: + cmp.l (SP),A0 + bcc.s .fill_end_magic_routine + add.w (A0),D0 + move.w (A0)+,(A1)+ + dbf D1,.copy_magic_routine + bra.s .end_copy_magic_routine +.fill_end_magic_routine: + clr.w (A1)+ + dbf D1,.fill_end_magic_routine +.end_copy_magic_routine: + move.w #0x5678,D1 // checksum + sub.w D0,D1 + move.w D1,(A1)+ + addq.l #4,SP + rts + +#ifndef COLDFIRE +_get_no_cache_memory: + + movem.l A0-A5,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + lea .no_memory(PC),A1 + move.l 8,A5 // bus error + move.l A1,8 + move.l SP,A4 // save ssp + moveq #0,D0 + move.l ramtop,A0 + clr.l (A0) // if access fault it's PMMU tree + move.l A0,D0 // buffer +.no_memory: + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp + move.w (SP)+,SR + movem.l (SP)+,A0-A5 + rts + +_get_no_cache_memory_size: + + move.l D1,-(SP) + bsr _get_no_cache_memory + tst.l D0 + beq.s .no_memory_size + move.l D0,D1 + movec.l SRP,D0 // PMMU tree + sub.l D1,D0 + moveq #32,D1 +.loop_find_first_msb: + subq.l #1,D1 + add.l D0,D0 // search the first MSB to 1 + bcs.s .found_first_msb + tst.l D1 + bne.s .loop_find_first_msb + moveq #0,D0 // not found ? + bra.s .no_memory_size +.found_first_msb: + moveq #0,D0 + bset D1,D0 // size alignment +.no_memory_size: + move.l (SP)+,D1 + rts + +led_floppy: + + move.l A0,-(SP) + move.l D0,-(SP) + bsr _led_floppy + move.l (SP)+,D0 + move.l (SP)+,A0 + rts + +_led_floppy: + + lea 0xFFFF8800,A0 // PSG sound + moveq #7,D0 + move.b D0,(A0) // ports A & B + move.b #0xC0,D0 // are outputs + move.b D0,2(A0) + moveq #14,D0 // port A + move.b D0,(A0) + tst.l 4(SP) + seq.b D0 + and.b #7,D0 // disable floppy: 7 + move.b D0,2(A0) + rts + +tempo_mfp: + + movem.l D0/A0,-(SP) + lea 0xfffffa01,A0 // MFP 68901 + clr.b 24(A0) // TACR stop timer A + bclr #5,18(A0) // IMRA interrupt mask timer A + bclr #5,6(A0) // IERA + bclr #5,10(A0) // IPRA no pending + bclr #5,14(A0) // ISRA + moveq #49,D0 // 0.5 S +.tm1: + move.b #124,30(A0) // TADR init timer A MFP for 10091 uS + move.b #7,24(A0) // TACR (prediv /200) + bset #5,6(A0) // IERA enable + bclr #5,10(A0) // IPRA clear timer A +.tm2: + btst #5,10(A0) // IPRA wait timer A + beq.s .tm2 + clr.b 24(A0) // TACR stop timer A + dbf D0,.tm1 + movem.l (SP)+,D0/A0 + rts + +_code_led: + move.l 4(SP),D0 + // 1: SDRAM refresh error + // 3: SDRAM read/write error + // 6: Keyboard error + // 7: Exception error + // 9: BIOS checksum error + // 11: Memory test error + subq.l #1,D0 + bmi.s .cl1 +.cl2: + move.l D0,-(SP) + moveq #1,D0 + bsr led_floppy + bsr tempo_mfp + moveq #0,D0 + bsr led_floppy + bsr tempo_mfp + move.l (SP)+,D0 + dbf D0,.cl2 +.cl1: + bsr tempo_mfp + bsr tempo_mfp + bsr tempo_mfp + bsr tempo_mfp + rts + +#endif /* COLDFIRE*/ + +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) +mess_eject: .byte 13 // trick for remove ERROR: + .asciz "Please remove USB drive " +#endif +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(MINT_IKBD_PATCH) +mess_mint: .byte 13 // trick for remove ERROR: + .asciz "WARNING! The MiNT IKBD handler is for a TOS < 2.00. Try to patch MiNT for TOS 4.04 USB Kbdvbase-1 usage..." +#endif message: .asciz "Ram-disk installed in " #if ((defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE)) || defined(MCF547X) message1: .ascii "TOS4.04 " @@ -4409,6 +5421,7 @@ message6: .asciz ", " message7: .ascii " MB" #endif /* ((defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE)) || defined(MCF547X) */ crlf: .byte 13,10,0 +space: .asciz " " error: .asciz "No ram-disk installed, " error1: .ascii "no enough memory" .byte 13,10,0 @@ -4421,6 +5434,42 @@ error4: .ascii "partition type not supported" blue: .byte 0x1B,0x62,0x34,0 black: .byte 0x1B,0x62,0x3F,0 +#ifdef DEBUG +debug1: .asciz "XBIOS #0x" +debug2: .asciz "Setscreen 0x" +debug3: .asciz "hdv_rw 0x" +debug4: .ascii "hdv_bpb" + .byte 13,10,0 +debug5: .ascii "hdv_mediach" + .byte 13,10,0 +debug6: .asciz "Vsetmode 0x" +debug7: .asciz "ValidMode 0x" +debug8: .asciz "Gettime 0x" +#endif +#ifdef DEBUG_XHDI +debug130: .asciz "XHDI return 0x" +debug131: .asciz "XHDI XHDrvMap 0x" +debug132: .asciz "XHDI XHReadWrite major 0x" +debug133: .asciz "XHDI XHInqTarget major 0x" +debug133a: .asciz "XHDI XHInqTarget2 major 0x" +debug134: .asciz "XHDI XHInqDev device 0x" +debug135: .asciz "XHDI XHInqDriver device 0x" +debug136: .asciz "XHDI XHInqDev2 device 0x" +debug137: .asciz "XHDI XHDOSLimits which 0x" +debug138: .ascii "XHDI XHGetVersion" + .byte 13,10,0 +debug139: .asciz "XHDI XHEject major 0x" +debug140: .asciz ", minor 0x" +debug141: .asciz ", rwflag 0x" +debug142: .asciz ", sector 0x" +debug143: .asciz ", count 0x" +debug144: .asciz ", buffer 0x" +debug145: .asciz "XHDI XHLock major 0x" +debug146: .asciz "XHDI call default routine 0x" +debug147: .asciz " function 0x" +debug148: .asciz "XHDI XHGetCapacity major 0x" +#endif + .align 2 .lcomm _address_ram_disk,4 @@ -4431,8 +5480,19 @@ black: .byte 0x1B,0x62,0x3F,0 .lcomm old_hdv_bpb,4 .lcomm old_hdv_rw,4 .lcomm old_hdv_mediach,4 +#if !defined(COLDFIRE) || defined(MCF547X) + .lcomm _change_cd_disk,4 + .lcomm _cd_disk_drive,4 + .lcomm old_hdv_bpb_cd,4 + .lcomm old_hdv_rw_cd,4 + .lcomm old_hdv_mediach_cd,4 + .lcomm part_type_cd,4 + .lcomm part_offset_cd,4 + .lcomm part_size_cd,4 + .lcomm tab_bpb_cd,32 +#endif /* !defined(COLDFIRE) || defined(MCF547X) */ #ifdef MCF547X - .lcomm name_sd_card,8 + .lcomm name_sd_card,10 #endif #if ((defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE)) || defined(MCF547X) #ifndef COLDFIRE @@ -4450,5 +5510,12 @@ black: .byte 0x1B,0x62,0x3F,0 .lcomm old_hdv_mediach_usb,4 .lcomm old_xhdi,4 .lcomm old_xhdi_version,4 + .lcomm vendor_name,4*(PUN_USB+PUN_DEV+1) .lcomm product_name,4*(PUN_USB+PUN_DEV+1) + .lcomm number_of_blocks,4*(PUN_USB+PUN_DEV+1) + .lcomm block_size,4*(PUN_USB+PUN_DEV+1) +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + .lcomm mint_ikbd_scan,4 +#endif #endif /* ((defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE)) || defined(MCF547X) */ + diff --git a/flash.tos/drivers/dma_utils/dma_utils.c b/flash.tos/drivers/dma_utils/dma_utils.c index 205cdef..8d34e8e 100644 --- a/flash.tos/drivers/dma_utils/dma_utils.c +++ b/flash.tos/drivers/dma_utils/dma_utils.c @@ -52,7 +52,7 @@ extern void critical_error(int error); #ifdef COLDFIRE -#ifdef NETWORK +#ifdef LWIP #ifdef MCF5445X #include "mcf5445x.h" @@ -82,10 +82,37 @@ static int Channel; #endif #ifdef MCF5445X + static char used_reqs[16]; + #else /* MCF548X */ + static char used_reqs[32]; -#endif + +typedef struct dma_cookie +{ + long version; /* 0x0101 for example */ + long magic; /* 'DMAC' */ + int (*dma_set_initiator)(int initiator); + unsigned long (*dma_get_initiator)(int requestor); + void (*dma_free_initiator)(int requestor); + int (*dma_set_channel)(int requestor, void (*handler)(void)); + int (*dma_get_channel)(int requestor); + void (*dma_free_channel)(int requestor); + void (*dma_clear_channel)(int channel); + int (*MCD_startDma)(int channel, s8 *srcAddr, s16 srcIncr, s8 *destAddr, s16 destIncr, u32 dmaSize, u32 xferSize, u32 initiator, int priority, u32 flags, u32 funcDesc); + int (*MCD_dmaStatus)(int channel); + int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); + int (*MCD_killDma)(int channel); + int (*MCD_continDma)(int channel); + int (*MCD_pauseDma)(int channel); + int (*MCD_resumeDma)(int channel); + int (*MCD_csumQuery)(int channel, u32 *csum); + void *(*dma_malloc)(long amount); + int (*dma_free)(void *addr); +} DMACF_COOKIE; + +#endif /* MCF5445X */ typedef struct { @@ -588,35 +615,6 @@ void dma_interrupt_handler(void) } } -void init_dma(void) -{ -#ifdef MCF5445X - int i; -#endif -#ifndef LWIP - (void)dmainterrupt; -#endif -#ifdef CHAINED_DMA - Descriptors = 0; - Channel = -1; -#endif - dma_init_tables(); - memset(dma_block_int, 0, sizeof(dma_block_int)); -#ifdef MCF5445X - /* Configure Interrupt vectors */ - for(i=0; i CT60 / CTPCI / PLX via XBIOS or PCI BIOS */ @@ -1001,7 +1075,7 @@ void dma_clear_channel(int channel) #define DMASCR0 0x128 /* DMA Channel 0 Command/Status */ #undef DMA_XBIOS -#undef DMA_MALLOC +#define DMA_MALLOC #ifdef DMA_MALLOC static unsigned long Descriptors; @@ -1227,15 +1301,16 @@ void wait_dma(void) if(use_dma) { unsigned long start_timer = *(volatile unsigned long *)_hz_200; -// extern void display_string(char *s); -// display_string("Wait DMA\r\n"); while(dma_status() > 0) { if((*(volatile unsigned long *)_hz_200 - start_timer) >= 200) /* 1S timeout */ { - -// display_string("DMA timeout\r\n"); - critical_error(-1); +#ifdef DMA_XBIOS + dma_buffoper(0); +#else + Write_config_byte(0, DMASCR0, 4); /* abort */ +#endif +// critical_error(-1); use_dma = 0; break; } diff --git a/flash.tos/drivers/dma_utils/dma_utils.h b/flash.tos/drivers/dma_utils/dma_utils.h index 17097f4..6007d45 100644 --- a/flash.tos/drivers/dma_utils/dma_utils.h +++ b/flash.tos/drivers/dma_utils/dma_utils.h @@ -3,7 +3,7 @@ #ifdef COLDFIRE -#ifdef NETWORK +#ifdef LWIP #ifdef MCF5445X @@ -71,22 +71,24 @@ #endif /* MCF5445X */ void dma_init_tables(void); -void dma_irq_enable(unsigned char, unsigned char); +void dma_irq_enable(unsigned char lvl, unsigned char pri); void dma_irq_disable(void); -int dma_set_initiator(int); -unsigned long dma_get_initiator(int); -void dma_free_initiator(int); -int dma_set_channel(int, void (*)(void)); -int dma_get_channel(int); -void dma_free_channel(int); -void dma_clear_channel(int); void dma_interrupt_handler(void); void dma_reg_dump(void); + +int dma_set_initiator(int initiator); +unsigned long dma_get_initiator(int requestor); +void dma_free_initiator(int requestor); +int dma_set_channel(int requestor, void (*handler)(void)); +int dma_get_channel(int requestor); +void dma_free_channel(int requestor); +void dma_clear_channel(int channel); + int dma_transfer(char *src, char *dest, int size, int width, int src_incr, int dest_incr, int step); int dma_status(void); void wait_dma(void); -#endif /* NETWORK */ +#endif /* LWIP */ #else /* !COLDFIRE */ diff --git a/flash.tos/drivers/drivers.lk b/flash.tos/drivers/drivers.lk index 62bd6c4..d3f2f99 100644 --- a/flash.tos/drivers/drivers.lk +++ b/flash.tos/drivers/drivers.lk @@ -9,35 +9,57 @@ MEMORY } SECTIONS { + _run = 0x6EE4; /* TOS 4.04 PD */ _d_rezword = 0xA4EA; /* AES, for videocnf.c */ + .data : + { + obj/freertos/tasks.o (.text .data) + obj/freertos/queue.o (.text .data) + obj/freertos/list.o (.text .data) + obj/freertos/heap_2.o (.text .data) + obj/freertos/port.o (.text .data) + obj/lwip/tcp_out.o (.text .data) + obj/lwip/inet.o (.text .data) + obj/lwip/chksum.o (.text .data) + obj/lwip/mem.o (.text .data) + obj/lwip/memp.o (.text .data) + obj/lwip/netif.o (.text .data) + obj/lwip/pbuf.o (.text .data) + obj/lwip/raw.o (.text .data) + obj/lwip/stats.o (.text .data) + obj/lwip/sys.o (.text .data) + obj/lwip/tcp.o (.text .data) + obj/lwip/tcp_in.o (.text .data) + obj/lwip/udp.o (.text .data) + obj/lwip/ip.o (.text .data) + obj/lwip/ip_addr.o (.text .data) + obj/lwip/icmp.o (.text .data) + obj/lwip/ip_frag.o (.text .data) + obj/lwip/tcpip.o (.text .data) + obj/lwip/api_msg.o (.text .data) + obj/lwip/err.o (.text .data) + obj/lwip/api_lib.o (.text .data) + obj/lwip/loopif.o (.text .data) + obj/lwip/sockets.o (.text .data) + obj/lwip/etharp.o (.text .data) + obj/lwip/resolv.o (.text .data) + obj/lwip/sys_arch.o (.text .data) + obj/lwip/rtl8139.o (.text .data) + obj/lwip/gs_func.o (.text .data) + obj/lwip/gs_mem.o (.text .data) + obj/lwip/gs_stik.o (.text .data) + obj/lwip/init.o (.text .data) + *(.data) + _edata = .; + __edata = .; + } > flash2 .text : { CREATE_OBJECT_SYMBOLS *(.text) - /* The next six sections are for SunOS dynamic linking. The order - is important. */ - *(.dynrel) - *(.hash) - *(.dynsym) - *(.dynstr) - *(.rules) - *(.need) _etext = .; __etext = .; } > flash - . = ALIGN(2); - .data : - { - /* The first three sections are for SunOS dynamic linking. */ - *(.dynamic) - *(.got) - *(.plt) - *(.data) - *(.linux-dynamic) /* For Linux dynamic linking. */ - CONSTRUCTORS - _edata = .; - __edata = .; - } > flash2 .bss : { __bss_start = .; diff --git a/flash.tos/drivers/emulator/biosemu.c b/flash.tos/drivers/emulator/biosemu.c index e99e15e..10783a8 100644 --- a/flash.tos/drivers/emulator/biosemu.c +++ b/flash.tos/drivers/emulator/biosemu.c @@ -5,15 +5,16 @@ #include #include #include -#include "../../include/pci_bios.h" /* for LITTLE_ENDIAN_LANE_SWAPPED */ +#include "../../include/pci_bios.h" /* for LITTLE_ENDIAN_LANE_SWAPPED and PCI_MAX_FUNCTION */ +#include "pci_ids.h" // #include "vgatables.h" #define USE_SDRAM #ifdef COLDFIRE -#ifdef LITTLE_ENDIAN_LANE_SWAPPED /* PCI BIOS */ -#define DIRECT_ACCESS -#endif +//#ifdef LITTLE_ENDIAN_LANE_SWAPPED /* PCI BIOS */ +//#define DIRECT_ACCESS +//#endif #ifndef PCI_XBIOS #define PCI_XBIOS // else sometimes system is locked ??? #endif @@ -196,23 +197,23 @@ u32 inl(u16 port) } else if((port == 0xCFC) && ((config_address_reg & 0x80000000) !=0)) { - if((config_address_reg & 0xFC) == PCIBAR1) - val = (u32)offset_port+1; - else + switch(config_address_reg & 0xFC) { -#ifdef DEBUG_X86EMU_PCI - DPRINTVALHEX("inl(", port); -#endif + case PCIIDR: val = ((u32)rinfo_biosemu->chipset << 16) + PCI_VENDOR_ID_ATI; break; + case PCIBAR1: val = (u32)offset_port+1; break; + default: #ifdef PCI_XBIOS val = fast_read_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC); #else val = Fast_read_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC); #endif + break; + } #ifdef DEBUG_X86EMU_PCI - DPRINTVALHEX(") = ", val); - DPRINT("\r\n"); + DPRINTVALHEX("inl(", port); + DPRINTVALHEX(") = ", val); + DPRINT("\r\n"); #endif - } } return val; } @@ -248,7 +249,7 @@ void outw(u16 val, u16 port) DPRINT("\r\n"); #endif #ifdef DIRECT_ACCESS -#ifndef COLDFIRE // write_io_word sometimes lock the system on the Coldfire ???? +#if 1 // #ifndef COLDFIRE // write_io_word sometimes lock the system on the Coldfire ???? *(u16 *)(offset_io+(u32)port) = swap_short(val); #else *(u8 *)(offset_io+(u32)port) = val; @@ -257,7 +258,7 @@ void outw(u16 val, u16 port) *(u8 *)(offset_io+(u32)port) = val; #endif /* COLDFIRE */ #else /* !DIRECT_ACCESS */ -#ifndef COLDFIRE // write_io_word sometimes lock the system on the Coldfire ???? +#if 1 // #ifndef COLDFIRE // write_io_word sometimes lock the system on the Coldfire ???? #ifdef PCI_XBIOS write_io_word(rinfo_biosemu->handle,offset_io+(u32)port,val); #else @@ -287,6 +288,7 @@ void outl(u32 val, u16 port) #ifdef DEBUG_X86EMU_PCI DPRINTVALHEX("outl(", port); DPRINTVALHEX(") = ", val); + DPRINT("\r\n"); #endif #ifdef DIRECT_ACCESS *(u32 *)(offset_io+(u32)port) = swap_long(val); @@ -303,6 +305,7 @@ void outl(u32 val, u16 port) #ifdef DEBUG_X86EMU_PCI DPRINTVALHEX("outl(", port); DPRINTVALHEX(") = ", val); + DPRINT("\r\n"); #endif config_address_reg = val; } @@ -315,6 +318,7 @@ void outl(u32 val, u16 port) #ifdef DEBUG_X86EMU_PCI DPRINTVALHEX("outl(", port); DPRINTVALHEX(") = ", val); + DPRINT("\r\n"); #endif #ifdef PCI_XBIOS write_config_longword(rinfo_biosemu->handle, config_address_reg & 0xFC, val); @@ -323,9 +327,6 @@ void outl(u32 val, u16 port) #endif } } -#ifdef DEBUG_X86EMU_PCI - DPRINT("\r\n"); -#endif } /* Interrupt multiplexer */ @@ -656,18 +657,18 @@ void run_bios(struct radeonfb_info *rinfo) struct pci_data *rom_data; unsigned long rom_size=0; unsigned long image_size=0; - unsigned long biosmem=0x01000000; /* when run_bios() is called, SDRAM is valid but not add to the system */ + unsigned long biosmem=0x01000000; /* when run_bios() is called, SDRAM is valid but not added to the system */ unsigned long addr; unsigned short initialcs; unsigned short initialip; - unsigned short devfn = (unsigned short)(rinfo->handle << 3); // was dev->bus->secondary << 8 | dev->path.u.pci.devfn; + unsigned short devfn = (unsigned short)( ((rinfo->handle & 0xFF) << 3) + ((((rinfo->handle >> 16) / PCI_MAX_FUNCTION) & 0xFF) << 8)); // was dev->bus->secondary << 8 | dev->path.u.pci.devfn; X86EMU_intrFuncs intFuncs[256]; if((rinfo->mmio_base == NULL) || (rinfo->io_base == NULL)) return; #ifndef COLDFIRE - /* try to not init the board with thr X86 VGA BIOS, too long on CT60 (more than 10 seconds, 2 seconds on Coldfire) */ - if(os_magic == 1) + /* try to not init the board with the X86 VGA BIOS, too long on CT60 (more than 20 seconds, 2 seconds on Coldfire) */ + if(os_magic) return; if(restart /* CTRL-ALT-DEL else 0 if reset */ && (*memvalid == MEMVALID_MAGIC) && (*memval2 == MEMVAL2_MAGIC) @@ -699,7 +700,7 @@ void run_bios(struct radeonfb_info *rinfo) { #ifdef USE_SDRAM #if 0 - if(os_magic == 1) + if(os_magic) { biosmem = Mxalloc(SIZE_EMU, 3); if(biosmem == 0) @@ -720,36 +721,6 @@ void run_bios(struct radeonfb_info *rinfo) #if 0 // 8 bits copy ptr = (char *)biosmem; for(i = (long)rom_header, j = PCI_VGA_RAM_IMAGE_START; i < (long)rom_header+rom_size; ptr[j++] = BIOS_IN8(i++)); -#if 0 - { - extern u32 swap_long(u32 val); - unsigned long sum = 0, data; - unsigned char *ptr2; - ptr = (char *)0x01100000; - ptr2 = ptr; - memset((char *)ptr, 0, SIZE_EMU); - for(i = (long)rom_header, j = PCI_VGA_RAM_IMAGE_START; i < (long)rom_header+rom_size; i+=4, j+=4) - { - data = swap_long(BIOS_IN32(i)); - sum += data; - *((unsigned long *)&ptr[j]) = data; - } - ptr = (char *)biosmem; - for(i = (long)rom_header, j = PCI_VGA_RAM_IMAGE_START; i < (long)rom_header+rom_size; i++) - { - if(ptr[j] != ptr2[j]) - { - DPRINTVALHEXBYTE("VGA ROM error read ", ptr[j]); - DPRINTVALHEXBYTE(" / ", ptr2[j]); - DPRINTVALHEXLONG(" at ", (long)&ptr[j]); - DPRINT("\r\n"); - } - j++; - } - DPRINTVALHEXLONG("VGA ROM checksum ", sum); - DPRINT("\r\n"); - } -#endif #else // 32 bits copy { extern u32 swap_long(u32 val); @@ -768,7 +739,7 @@ void run_bios(struct radeonfb_info *rinfo) { #ifdef USE_SDRAM #if 0 - if(os_magic == 1) + if(os_magic) { biosmem = Mxalloc(SIZE_EMU, 3); if(biosmem == 0) @@ -843,7 +814,7 @@ void run_bios(struct radeonfb_info *rinfo) // biosfn_set_video_mode(0x13); /* 320 x 200 x 256 colors */ #ifdef USE_SDRAM #if 0 - if(os_magic == 1) + if(os_magic) { memset((char *)biosmem, 0, SIZE_EMU); Mfree(biosmem); diff --git a/flash.tos/drivers/emulator/pcbios/pcibios.c b/flash.tos/drivers/emulator/pcbios/pcibios.c index d8fb9fe..16712bf 100644 --- a/flash.tos/drivers/emulator/pcbios/pcibios.c +++ b/flash.tos/drivers/emulator/pcbios/pcibios.c @@ -1,22 +1,22 @@ -#include -#include +#include "../../radeon/radeonfb.h" +#include #include #include -#include "../../radeon/radeonfb.h" +#include "../../include/pci_bios.h" /* for PCI_MAX_FUNCTION */ #include "pcibios.h" extern unsigned short offset_port; #ifdef COLDFIRE #ifndef PCI_XBIOS -#define PCI_XBIOS // else sometimes system is locked ??? +//#define PCI_XBIOS // else sometimes system is locked ??? #endif #endif int pcibios_handler() { int ret = 0; - static long dev; + unsigned long dev = (((unsigned long)X86_BH << 16) * PCI_MAX_FUNCTION) + ((unsigned long)X86_BL >> 3); switch (X86_AX) { case PCI_BIOS_PRESENT: @@ -47,7 +47,7 @@ int pcibios_handler() #ifdef DEBUG_X86EMU_PCI DPRINT(" ... OK\r\n"); #endif - X86_BH = 0; // dev->bus->secondary; + X86_BH = (char)((dev >> 16) / PCI_MAX_FUNCTION); // dev->bus->secondary; X86_BL = (char)dev; // dev->path.u.pci.devfn; X86_AH = SUCCESSFUL; X86_EFLAGS &= ~FB_CF; /* clear carry flag */ @@ -75,7 +75,7 @@ int pcibios_handler() #ifdef DEBUG_X86EMU_PCI DPRINT(" ... OK\r\n"); #endif - X86_BH = 0; // dev->bus->secondary; + X86_BH = (char)((dev >> 16) / PCI_MAX_FUNCTION); // dev->bus->secondary; X86_BL = (char)dev; // dev->path.u.pci.devfn; X86_AH = SUCCESSFUL; X86_EFLAGS &= ~FB_CF; /* clear carry flag */ @@ -92,13 +92,14 @@ int pcibios_handler() case READ_CONFIG_BYTE: // bus, devfn #ifdef DEBUG_X86EMU_PCI - DPRINTVAL("READ_CONFIG_BYTE devfn ", X86_BL); + DPRINTVAL("READ_CONFIG_BYTE bus ", X86_BH); + DPRINTVAL(" devfn ", X86_BL); DPRINTVALHEX(" reg ", X86_DI); #endif #ifdef PCI_XBIOS - X86_CL = fast_read_config_byte((long)X86_BL, X86_DI); + X86_CL = fast_read_config_byte(dev, X86_DI); #else - X86_CL = Fast_read_config_byte((long)X86_BL, X86_DI); + X86_CL = Fast_read_config_byte(dev, X86_DI); #endif #ifdef DEBUG_X86EMU_PCI DPRINTVALHEX(" value ", X86_CL); @@ -111,16 +112,17 @@ int pcibios_handler() case READ_CONFIG_WORD: // bus, devfn #ifdef DEBUG_X86EMU_PCI - DPRINTVAL("READ_CONFIG_WORD devfn ", X86_BL); + DPRINTVAL("READ_CONFIG_WORD bus ", X86_BH); + DPRINTVAL(" devfn ", X86_BL); DPRINTVALHEX(" reg ", X86_DI); #endif if(X86_DI == PCIBAR1) X86_CX = offset_port+1; else #ifdef PCI_XBIOS - X86_CX = fast_read_config_word((long)X86_BL, X86_DI); + X86_CX = fast_read_config_word(dev, X86_DI); #else - X86_CX = Fast_read_config_word((long)X86_BL, X86_DI); + X86_CX = Fast_read_config_word(dev, X86_DI); #endif #ifdef DEBUG_X86EMU_PCI DPRINTVALHEX(" value ", X86_CX); @@ -133,16 +135,17 @@ int pcibios_handler() case READ_CONFIG_DWORD: // bus, devfn #ifdef DEBUG_X86EMU_PCI - DPRINTVAL("READ_CONFIG_DWORD devfn ", X86_BL); + DPRINTVAL("READ_CONFIG_DWORD bus ", X86_BH); + DPRINTVAL(" devfn ", X86_BL); DPRINTVALHEX(" reg ", X86_DI); #endif if(X86_DI == PCIBAR1) X86_CX = (unsigned long)offset_port+1; else #ifdef PCI_XBIOS - X86_ECX = fast_read_config_longword((long)X86_BL, X86_DI); + X86_ECX = fast_read_config_longword(dev, X86_DI); #else - X86_ECX = Fast_read_config_longword((long)X86_BL, X86_DI); + X86_ECX = Fast_read_config_longword(dev, X86_DI); #endif #ifdef DEBUG_X86EMU_PCI DPRINTVALHEX(" value ", X86_ECX); @@ -155,14 +158,15 @@ int pcibios_handler() case WRITE_CONFIG_BYTE: // bus, devfn #ifdef DEBUG_X86EMU_PCI - DPRINTVAL("READ_CONFIG_BYTE devfn ", X86_BL); + DPRINTVAL("READ_CONFIG_BYTE bus ", X86_BH); + DPRINTVAL(" devfn ", X86_BL); DPRINTVALHEX(" reg ", X86_DI); DPRINTVALHEX(" value ", X86_CL); #endif #ifdef PCI_XBIOS - if((ret=write_config_byte((long)X86_BL, X86_DI, X86_CL)) == 0) { + if((ret=write_config_byte(dev, X86_DI, X86_CL)) == 0) { #else - if((ret=Write_config_byte((long)X86_BL, X86_DI, X86_CL)) == 0) { + if((ret=Write_config_byte(dev, X86_DI, X86_CL)) == 0) { #endif #ifdef DEBUG_X86EMU_PCI DPRINT(" ... OK\r\n"); @@ -183,7 +187,8 @@ int pcibios_handler() case WRITE_CONFIG_WORD: // bus, devfn #ifdef DEBUG_X86EMU_PCI - DPRINTVAL("WRITE_CONFIG_WORD devfn ", X86_BL); + DPRINTVAL("WRITE_CONFIG_WORD bus ", X86_BH); + DPRINTVAL(" devfn ", X86_BL); DPRINTVALHEX(" reg ", X86_DI); DPRINTVALHEX(" value ", X86_CX); #endif @@ -198,9 +203,9 @@ int pcibios_handler() break; } #ifdef PCI_XBIOS - if((ret=write_config_word((long)X86_BL, X86_DI, X86_CX)) == 0) { + if((ret=write_config_word(dev, X86_DI, X86_CX)) == 0) { #else - if((ret=Write_config_word((long)X86_BL, X86_DI, X86_CX)) == 0) { + if((ret=Write_config_word(dev, X86_DI, X86_CX)) == 0) { #endif #ifdef DEBUG_X86EMU_PCI DPRINT(" ... OK\r\n"); @@ -221,7 +226,8 @@ int pcibios_handler() case WRITE_CONFIG_DWORD: // bus, devfn #ifdef DEBUG_X86EMU_PCI - DPRINTVAL("WRITE_CONFIG_DWORD devfn ", X86_BL); + DPRINTVAL("WRITE_CONFIG_DWORD bus ", X86_BH); + DPRINTVAL(" devfn ", X86_BL); DPRINTVALHEX(" reg ", X86_DI); DPRINTVALHEX(" value ", X86_ECX); #endif @@ -236,9 +242,9 @@ int pcibios_handler() break; } #ifdef PCI_XBIOS - if((ret=write_config_longword((long)X86_BL, X86_DI, X86_ECX)) == 0) { + if((ret=write_config_longword(dev, X86_DI, X86_ECX)) == 0) { #else - if((ret=Write_config_longword((long)X86_BL, X86_DI, X86_ECX)) == 0) { + if((ret=Write_config_longword(dev, X86_DI, X86_ECX)) == 0) { #endif #ifdef DEBUG_X86EMU_PCI DPRINT(" ... OK\r\n"); diff --git a/flash.tos/drivers/emulator/x86emu/sys.c b/flash.tos/drivers/emulator/x86emu/sys.c index 4c35061..6e7f2db 100644 --- a/flash.tos/drivers/emulator/x86emu/sys.c +++ b/flash.tos/drivers/emulator/x86emu/sys.c @@ -65,7 +65,7 @@ #define DIRECT_ACCESS #endif #ifndef PCI_XBIOS -#define PCI_XBIOS // else sometimes system is locked ??? +//#define PCI_XBIOS // else sometimes system is locked ??? #endif #else /* !COLDFIRE */ #ifdef LITTLE_ENDIAN_LANE_SWAPPED /* PCI BIOS */ diff --git a/flash.tos/drivers/freertos/FreeRTOSConfig.h b/flash.tos/drivers/freertos/FreeRTOSConfig.h index c036e8b..c2fab97 100644 --- a/flash.tos/drivers/freertos/FreeRTOSConfig.h +++ b/flash.tos/drivers/freertos/FreeRTOSConfig.h @@ -1,6 +1,6 @@ /* FreeRTOS V4.1.0 - Copyright (C) 2003-2006 Richard Barry. - MCF5485 Port - (c) 2008 Didier Mequignon. + MCF5485 Port - (c) 2008-2012 Didier Mequignon. This file is part of the FreeRTOS distribution. @@ -47,6 +47,7 @@ #define configUSE_PREEMPTION 1 #define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 +#ifdef COLDFIRE #ifdef MCF5445X #define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 266000000 ) #else @@ -56,14 +57,20 @@ #define configCPU_CLOCK_HZ ( ( unsigned portLONG ) 200000000 ) #endif /* MCF547X */ #endif /* MCF5445X */ +#endif /* COLDFIRE */ #define configTICK_RATE_HZ ( ( portTickType ) 200 ) #define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 32 ) +#ifdef COLDFIRE #define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 4096 ) +#else +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 2048 ) +#endif #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_TRACE_FACILITY 1 #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 #define configUSE_ALTERNATIVE_API 1 +#define configTOTAL_HEAP_SIZE 0x20000 /* Co-routine definitions. */ #define configUSE_CO_ROUTINES 0 diff --git a/flash.tos/drivers/freertos/heap_2.c b/flash.tos/drivers/freertos/heap_2.c index f53f434..a992ed3 100644 --- a/flash.tos/drivers/freertos/heap_2.c +++ b/flash.tos/drivers/freertos/heap_2.c @@ -45,11 +45,14 @@ #include "FreeRTOS.h" #include "task.h" -#ifdef NETWORK -#ifdef LWIP +#if defined(LWIP) || defined(FREERTOS) extern unsigned char __FREERTOS_BASE[]; +#ifdef COLDFIRE extern unsigned char __FREERTOS_SIZE[]; +#else +#define __FREERTOS_SIZE configTOTAL_HEAP_SIZE +#endif /* Setup the correct byte alignment mask for the defined byte alignment. */ #if portBYTE_ALIGNMENT == 4 @@ -234,5 +237,4 @@ xBlockLink *pxLink; } /*-----------------------------------------------------------*/ -#endif /* LWIP */ -#endif /* NETWORK */ +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/freertos/heap_2b.c b/flash.tos/drivers/freertos/heap_2b.c index cb8bc3f..4890e30 100644 --- a/flash.tos/drivers/freertos/heap_2b.c +++ b/flash.tos/drivers/freertos/heap_2b.c @@ -45,8 +45,7 @@ #include "FreeRTOS.h" #include "task.h" -#ifdef NETWORK -#ifdef LWIP +#if defined(LWIP) || defined(FREERTOS) extern unsigned char __LWIP_BASE[]; extern unsigned char __LWIP_SIZE[]; @@ -234,5 +233,4 @@ xBlockLink *pxLink; } /*-----------------------------------------------------------*/ -#endif /* LWIP */ -#endif /* NETWORK */ +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/freertos/list.c b/flash.tos/drivers/freertos/list.c index ecfcbd5..476c8be 100644 --- a/flash.tos/drivers/freertos/list.c +++ b/flash.tos/drivers/freertos/list.c @@ -86,8 +86,7 @@ Changes from V4.0.4 #include "FreeRTOS.h" #include "list.h" -#ifdef NETWORK -#ifdef LWIP +#if defined(LWIP) || defined(FREERTOS) /*----------------------------------------------------------- * PUBLIC LIST API documented in list.h @@ -206,5 +205,4 @@ xList * pxList; } /*-----------------------------------------------------------*/ -#endif /* LWIP */ -#endif /* NETWORK */ +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/freertos/port.c b/flash.tos/drivers/freertos/port.c index c94759d..554f898 100644 --- a/flash.tos/drivers/freertos/port.c +++ b/flash.tos/drivers/freertos/port.c @@ -1,6 +1,6 @@ /* FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry. - MCF548x Port - Copyright (C) 2008 Didier Mequignon. + MCF548x Port - Copyright (C) 2008-2012 Didier Mequignon. This file is part of the FreeRTOS distribution. @@ -31,6 +31,8 @@ *************************************************************************** */ +#include +#include #include "config.h" #include "FreeRTOS.h" #include "FreeRTOSConfig.h" @@ -40,21 +42,27 @@ #include "../lwip/perf.h" +#ifndef _timer_ms +#define _timer_ms 0x442 +#endif + typedef volatile unsigned long vuint32; typedef volatile unsigned short vuint16; typedef volatile unsigned char vuint8; +#ifdef COLDFIRE #ifdef MCF5445X #include "mcf5445x.h" #else /* MCF548X */ #include "mcf548x.h" extern unsigned char __MBAR[]; #endif +#endif /* COLDFIRE */ -#ifdef NETWORK -#ifdef LWIP +#if defined(LWIP) || defined(FREERTOS) /* ------------------------ Defines --------------------------------------- */ +#ifdef COLDFIRE #ifdef MCF5445X #define SYSTEM_CLOCK 133 // system bus frequency in MHz #define portVECTOR_TIMER ( 64 + INT0_HI_DTMR2 ) @@ -66,6 +74,10 @@ extern unsigned char __MBAR[]; #endif /* MCF547X */ #define portVECTOR_TIMER ( 64 + 54 ) #endif +#else /* !COLDFIRE */ +#define portVECTOR_VBL ( 28 ) +#define portVECTOR_TIMER_D ( 68 ) +#endif /* COLDFIRE */ #define portVECTOR_SYSCALL ( 32 + portTRAP_YIELD ) #define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 ) @@ -73,7 +85,11 @@ extern unsigned char __MBAR[]; /* ------------------------ Static variables ------------------------------ */ volatile unsigned portLONG ulCriticalNesting; +#ifdef COLDFIRE static unsigned portLONG portIntCounter; +#else +static unsigned long prvOldTrap; +#endif /* ------------------------ Static functions ------------------------------ */ #if configUSE_PREEMPTION == 0 @@ -117,8 +133,8 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD } #endif - /* Create a Motorola Coldfire exception stack frame. First comes the return - * address. */ +#ifdef COLDFIRE + /* Create a Motorola Coldfire exception stack frame. First comes the return address. */ *pxTopOfStack = ( portSTACK_TYPE ) pxCode; pxTopOfStack--; @@ -132,6 +148,21 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD *pxTopOfStack = 0x40000000UL | (portVECTOR_SYSCALL << 18) | ((uxMaskIntLevel & 7) << 8); #endif +#else /* !COLDFIRE */ + + *pxTopOfStack = (( portSTACK_TYPE ) pxCode << 16) | (portVECTOR_SYSCALL << 2); + pxTopOfStack--; + +#if( HAVE_USP == 1 ) + if(uxSuper) +#endif + *pxTopOfStack = 0x20000000UL | (( portSTACK_TYPE ) pxCode >> 16) | ((uxMaskIntLevel & 7) << 24); +#if( HAVE_USP == 1 ) + else + *pxTopOfStack = (( portSTACK_TYPE ) pxCode >> 16) | ((uxMaskIntLevel & 7) << 8); +#endif +#endif /* COLDFIRE */ + *pxContext++ = ( portSTACK_TYPE ) 0xD0; /* D0 */ *pxContext++ = ( portSTACK_TYPE ) 0xD1; /* D1 */ *pxContext++ = ( portSTACK_TYPE ) 0xD2; /* D2 */ @@ -157,10 +188,15 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD #endif #if( SAVE_FPU == 1 ) +#ifdef COLDFIRE *pxContext++ = ( portSTACK_TYPE ) 0x05000000; /* FSAVE IDLE state */ *pxContext++ = ( portSTACK_TYPE ) 0x00; *pxContext++ = ( portSTACK_TYPE ) 0x00; *pxContext++ = ( portSTACK_TYPE ) 0x00; +#else + *pxContext++ = ( portSTACK_TYPE ) 0xFC; /* FPICR */ + *pxContext++ = ( portSTACK_TYPE ) 0xFC; /* FPISR */ +#endif *pxContext++ = ( portSTACK_TYPE ) 0xFA; /* FPIAR */ *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP0 */ *pxContext++ = ( portSTACK_TYPE ) 0xF0; /* FP0 */ @@ -178,7 +214,7 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD *pxContext++ = ( portSTACK_TYPE ) 0xF6; /* FP6 */ *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP7 */ *pxContext++ = ( portSTACK_TYPE ) 0xF7; /* FP7 */ -#endif +#endif /* ( SAVE_FPU == 1 ) */ /* Set the initial critical section nesting counter to zero. This value * is used to restore the value of ulCriticalNesting. */ @@ -188,6 +224,9 @@ portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_COD } extern long pxCurrentTCB, tid_TOS; + +#ifdef COLDFIRE + extern volatile portTickType xTickCount; #ifdef MCF5445X unsigned long save_imrl0, save_imrl0_tos, save_imrh0, save_imrh0_tos, save_imrh1, save_imrh1_tos; @@ -231,8 +270,6 @@ portSaveRestoreInt( int iSave ) } else { -#define _timer_ms 0x442 -#define _hz_200 0x4BA #ifdef MCF5445X if( pxCurrentTCB == tid_TOS ) { @@ -311,50 +348,51 @@ prvPortYield( void ) #if _GCC_USES_FP == 1 asm volatile (" unlk fp\n\t"); #endif - asm volatile (" move.l d0, -(sp)\n\t"); - asm volatile (" move.l a0, -(sp)\n\t"); - asm volatile (" move.l usp, a0\n\t"); - asm volatile (" btst #5, 10(sp)\n\t"); // call in supervisor state - asm volatile (" beq.s .user\n\t" ); - asm volatile (" move.b 8(sp), d0\r\n"); // get SP alignment bits from A7 stack frame - asm volatile (" lsr.l #4, d0\n\t"); - asm volatile (" and.l #3, d0\n\t"); - asm volatile (" addq.l #8, d0\n\t"); - asm volatile (" addq.l #8, d0\n\t"); - asm volatile (" add.l sp, d0\n\t"); - asm volatile (" move.l d0, a0\n\t"); - asm volatile (".user:\n\t" ); - asm volatile (" moveq #0, d0\n\t"); - asm volatile (" move.w (a0), d0\n\t"); - asm volatile (" cmp.l #0xFE, d0\n\t"); // function - asm volatile (" beq .set_ipl\n\t" ); - asm volatile (" cmp.l #0xFF, d0\n\t"); // function - asm volatile (" beq .yield\n\t" ); - asm volatile (" move.l (sp)+, a0\n\t"); - asm volatile (" addq.l #4, sp\n\t"); - asm volatile (" moveq #-1, d0\n\t"); - asm volatile (" rte\n\t"); - asm volatile (".set_ipl:\n\t"); - asm volatile (" move.l d6, -(sp)\n\t"); - asm volatile (" move.l d7, -(sp)\n\t"); - asm volatile (" move.w 18(sp), d7\n\t"); // current SR - asm volatile (" move.l d7, d0\n\t"); // prepare return value - asm volatile (" and.l #0x700, d0\n\t"); // mask out IPL - asm volatile (" lsr.l #8, d0\n\t"); // IPL - asm volatile (" move.l 2(a0), d6\n\t"); // get argument - asm volatile (" and.l #7, d6\n\t"); // least significant three bits - asm volatile (" lsl.l #8, d6\n\t"); // move over to make mask - asm volatile (" and.l #0xF8FF, d7\n\t"); // zero out current IPL - asm volatile (" or.l d6, d7\n\t"); // place new IPL in SR - asm volatile (" move.w d7, 18(sp)\n\t"); - asm volatile (" move.l (sp)+, d7\n\t"); - asm volatile (" move.l (sp)+, d6\n\t"); - asm volatile (" move.l (sp)+, a0\n\t"); - asm volatile (" addq.l #4, sp\n\t"); - asm volatile (" rte\n\t");; - asm volatile (".yield:\n\t"); - asm volatile (" move.l (sp)+, a0\n\t"); - asm volatile (" move.l (sp)+, d0\n\t"); + asm volatile ( + " move.l d0, -(sp)\n\t" + " move.l a0, -(sp)\n\t" + " move.l usp, a0\n\t" + " btst #5, 10(sp)\n\t" // call in supervisor state + " beq.s .user\n\t" + " move.b 8(sp), d0\r\n" // get SP alignment bits from A7 stack frame + " lsr.l #4, d0\n\t" + " and.l #3, d0\n\t" + " addq.l #8, d0\n\t" + " addq.l #8, d0\n\t" + " add.l sp, d0\n\t" + " move.l d0, a0\n\t" + ".user:\n\t" + " moveq #0, d0\n\t" + " move.w (a0), d0\n\t" + " cmp.l #0xFE, d0\n\t" // function + " beq .set_ipl\n\t" + " cmp.l #0xFF, d0\n\t" // function + " beq .yield\n\t" + " move.l (sp)+, a0\n\t" + " addq.l #4, sp\n\t" + " moveq #-1, d0\n\t" + " rte\n\t" + ".set_ipl:\n\t" + " move.l d6, -(sp)\n\t" + " move.l d7, -(sp)\n\t" + " move.w 18(sp), d7\n\t" // current SR + " move.l d7, d0\n\t" // prepare return value + " and.l #0x700, d0\n\t" // mask out IPL + " lsr.l #8, d0\n\t" // IPL + " move.l 2(a0), d6\n\t" // get argument + " and.l #7, d6\n\t" // least significant three bits + " lsl.l #8, d6\n\t" // move over to make mask + " and.l #0xF8FF, d7\n\t" // zero out current IPL + " or.l d6, d7\n\t" // place new IPL in SR + " move.w d7, 18(sp)\n\t" + " move.l (sp)+, d7\n\t" + " move.l (sp)+, d6\n\t" + " move.l (sp)+, a0\n\t" + " addq.l #4, sp\n\t" + " rte\n\t" + ".yield:\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0" ); /* Perform the context switch. First save the context of the current task. */ portSAVE_CONTEXT( ); /* Find the highest priority task that is ready to run. */ @@ -363,6 +401,93 @@ prvPortYield( void ) portRESTORE_CONTEXT( ); } +#else /* !COLDFIRE */ + +/* + * Called by portYIELD() or taskYIELD() to manually force a context switch. + */ +static void +prvPortYield( void ) +{ +#if _GCC_USES_FP == 1 + asm volatile (" unlk fp\n\t"); +#endif + asm volatile ( + " move.l d0, -(sp)\n\t" + " move.l a0, -(sp)\n\t" + " move.l usp, a0\n\t" + " btst #5, 8(sp)\n\t" // call in supervisor state + " beq.s .user\n\t" + " move.l 10(sp), a0\n\t" // return address + " move.l -6(a0), d0\n\t" // instruction before trap + " cmp.l #0x46FC2300, d0\n\t" // move.w #0x2300,SR MAGXBOOT.PRG + " beq.s .oldtrap\n\t" + " lea 8+8(sp), a0\n\t" + ".user:\n\t" + " moveq #0, d0\n\t" + " move.w (a0), d0\n\t" + " cmp.l #0xFE, d0\n\t" // function + " beq .set_ipl\n\t" + " cmp.l #0xFF, d0\n\t" // function + " beq .yield\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0\n\t" + " rte\n\t" + ".oldtrap:\n\t" + " move.l d1, -(sp)\n\t" + " move.l a1, -(sp)\n\t" + " jsr _vPortEndScheduler\n\t" + " move.l (sp)+, a1\n\t" + " move.l (sp)+, d1\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0\n\t" + " move.l _prvOldTrap, -(%sp)\n\t" + " rts\n\t" + ".set_ipl:\n\t" + " move.l d6, -(sp)\n\t" + " move.l d7, -(sp)\n\t" + " move.w 16(sp), d7\n\t" // current SR + " move.l d7, d0\n\t" // prepare return value + " and.l #0x700, d0\n\t" // mask out IPL + " lsr.l #8, d0\n\t" // IPL + " move.l 2(a0), d6\n\t" // get argument + " and.l #7, d6\n\t" // least significant three bits + " lsl.l #8, d6\n\t" // move over to make mask + " and.l #0xF8FF, d7\n\t" // zero out current IPL + " or.l d6, d7\n\t" // place new IPL in SR + " move.w d7, 16(sp)\n\t" + " move.l (sp)+, d7\n\t" + " move.l (sp)+, d6\n\t" + " move.l (sp)+, a0\n\t" + " addq.l #4, sp\n\t" + " rte\n\t" + ".yield:\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0\n\t" + " or.w #0x0700, sr" ); // mask interrupts + /* Perform the context switch. First save the context of the current task. */ + portSAVE_CONTEXT( ); + /* Find the highest priority task that is ready to run. */ + vTaskSwitchContext( ); + /* Restore the context of the new task. */ + portRESTORE_CONTEXT( ); +} + +void MfpTimer(void) +{ + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = (unsigned long)prvPortYield; + *(volatile unsigned char *)0xFFFFFA11 = 0xEF; /* clear Timer D ISRB MFP */ +} + +static void +prvPortVBL( void ) +{ + *(unsigned long *)((portVECTOR_TIMER_D) * 4) = (unsigned long)prvPortPreemptiveTick; + asm volatile ( " jmp 0xE00CB0\n\t"); /* VBL TOS 4.04 */ +} + +#endif /* COLDFIRE */ + void portYIELD(void) { asm volatile ( @@ -373,17 +498,15 @@ void portYIELD(void) int vPortSetIPL( unsigned long int uiNewIPL ) { -#if 0 // ugly hack fixed by using portOldIPLTOS - portSTACK_TYPE *p = (portSTACK_TYPE *) pxCurrentTCB; - unsigned portBASE_TYPE uxStartIntLevel = (unsigned portBASE_TYPE) p[65]; - if(( pxCurrentTCB != tid_TOS ) && ( (unsigned portBASE_TYPE) uiNewIPL < uxStartIntLevel ) ) - uiNewIPL = (unsigned long int) uxStartIntLevel; -#endif #if ( HAVE_USP == 1 ) if( !xTaskIsSuper() || ( pxCurrentTCB == tid_TOS ) ) #else +#ifdef COLDFIRE if(*(unsigned long *)(((portVECTOR_SYSCALL) * 4) + coldfire_vector_base) == (unsigned long)prvPortYield) -#endif +#else /* !COLDFIRE */ + if( pxCurrentTCB == tid_TOS ) +#endif /* COLDFIRE */ +#endif /* ( HAVE_USP == 1 ) */ { register int iOldIPL __asm__("d0"); asm volatile ( @@ -411,7 +534,7 @@ int vPortSetIPL( unsigned long int uiNewIPL ) } } -#if configUSE_PREEMPTION == 0 +#if (configUSE_PREEMPTION == 0) /* * The ISR used for the scheduler tick depends on whether the cooperative or * the preemptive scheduler is being used. @@ -423,11 +546,15 @@ prvPortPreemptiveTick ( void ) * simply increment the system tick. */ vTaskIncrementTick( ); +#ifdef COLDFIRE #ifdef MCF5445X MCF_DTIM_DTER(2) = DTIM_DTER_REF; #else /* MCF548X */ MCF_SLT_SSR(0) |= MCF_SLT_SSR_ST; /* clear interrupt */ #endif +#else /* !COLDFIRE */ + MfpTimer( ); +#endif /* COLDFIRE */ } #else @@ -435,21 +562,26 @@ prvPortPreemptiveTick ( void ) static void prvPortPreemptiveTick( void ) { - asm volatile ( "move.w #0x2700, sr\n\t" ); + asm volatile ( " move.w #0x2700, sr\n\t" ); #if _GCC_USES_FP == 1 - asm volatile ( "unlk fp\n\t" ); + asm volatile ( " unlk fp\n\t" ); #endif portSAVE_CONTEXT( ); +#ifdef COLDFIRE #ifdef MCF5445X MCF_DTIM_DTER(2) = DTIM_DTER_REF; #else /* MCF548X */ MCF_SLT_SSR(0) |= MCF_SLT_SSR_ST; /* clear interrupt */ #endif +#else /* !COLDFIRE */ + MfpTimer( ); +#endif /* COLDFIRE */ vTaskIncrementTick( ); vTaskSwitchContext( ); - portRESTORE_CONTEXT( ); + portRESTORE_CONTEXT( ); } -#endif + +#endif /* (configUSE_PREEMPTION == 0) */ static int portOldIPL, portOldIPLTOS; @@ -484,6 +616,8 @@ vPortExitCritical() } } +#ifdef COLDFIRE + static void rte_int(void) { #if _GCC_USES_FP == 1 @@ -492,11 +626,14 @@ static void rte_int(void) asm volatile (" rte\n\t"); } +#endif + portBASE_TYPE xPortStartScheduler( void ) { asm volatile ( "move.w #0x2700, sr\n\t" ); +#ifdef COLDFIRE *(unsigned long *)_hz_200 = 0; /* Add entry in vector table for yield system call. */ *(unsigned long *)(((portVECTOR_SYSCALL) * 4) + coldfire_vector_base) = (unsigned long)prvPortYield; @@ -504,12 +641,21 @@ xPortStartScheduler( void ) *(unsigned long *)(((portVECTOR_TIMER) * 4) + coldfire_vector_base) = (unsigned long)prvPortPreemptiveTick; /* sometimes spurious interrupt not fixed ! */ *(unsigned long *)((24 * 4) + coldfire_vector_base) = (long)rte_int; +#else /* !COLDFIRE */ + /* Add entry in vector table for yield system call. */ + prvOldTrap = *(unsigned long *)((portVECTOR_SYSCALL) * 4); + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = (unsigned long)prvPortYield; + /* Add entry in vector table for periodic timer. */ + *(unsigned long *)((portVECTOR_TIMER_D) * 4) = (unsigned long)prvPortPreemptiveTick; +// *(unsigned long *)((portVECTOR_VBL) * 4) = (unsigned long)prvPortVBL; +#endif /* COLDFIRE */ ulCriticalNesting = portINITIAL_CRITICAL_NESTING; /* Configure the timer for the system clock. */ - if ( configTICK_RATE_HZ > 0) + if(configTICK_RATE_HZ > 0) { +#ifdef COLDFIRE #ifdef MCF5445X /* Initialize the periodic timer interrupt. */ MCF_DTIM_DTMR(2) = DTIM_DTMR_ORRI | DTIM_DTMR_FRR | DTIM_DTMR_CLK(1); @@ -533,7 +679,11 @@ xPortStartScheduler( void ) MCF_INTC_IMRL &= ~MCF_INTC_IMRL_MASKALL; save_imrl = save_imrl_tos = MCF_INTC_IMRL; save_imrh = save_imrh_tos = MCF_INTC_IMRH; -#endif +#endif /* MCF5445X */ +#else /* !COLDFIRE */ + Xbtimer(3, 5, 2457600 / (64 * configTICK_RATE_HZ), -1); + Jenabint(4); /* timer D */ +#endif /* COLDFIRE */ } /* Restore the context of the first task that is going to run. */ @@ -545,17 +695,23 @@ xPortStartScheduler( void ) void vPortEndScheduler( void ) { +#ifndef COLDFIRE + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = prvOldTrap; /* for MAGXBOOT */ +#endif } unsigned portBASE_TYPE uxPortReadTimer( void ) /* vTaskStartTrace */ { +#ifdef COLDFIRE #ifdef MCF5445X - return((unsigned portBASE_TYPE)MCF_DTIM_DTCN(2) / SYSTEM_CLOCK); + return((unsigned portBASE_TYPE)MCF_DTIM_DTCN(2) / SYSTEM_CLOCK); #else /* MCF548X */ - return((unsigned portBASE_TYPE)(MCF_SLT_SLTCNT(0) - MCF_SLT_SCNT(0)) / SYSTEM_CLOCK); -#endif + return((unsigned portBASE_TYPE)(MCF_SLT_SLTCNT(0) - MCF_SLT_SCNT(0)) / SYSTEM_CLOCK); +#endif /* MCF5445X */ +#else /* !COLDFIRE */ + return(0); +#endif /* COLDFIRE */ } -#endif /* LWIP */ -#endif /* NETWORK */ +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/freertos/port.c.old b/flash.tos/drivers/freertos/port.c.old new file mode 100644 index 0000000..65211d0 --- /dev/null +++ b/flash.tos/drivers/freertos/port.c.old @@ -0,0 +1,769 @@ +/* + FreeRTOS V4.1.1 - Copyright (C) 2003-2006 Richard Barry. + MCF548x Port - Copyright (C) 2008-2012 Didier Mequignon. + + This file is part of the FreeRTOS distribution. + + FreeRTOS 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. + + FreeRTOS 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 FreeRTOS; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + +#include +#include +#include "config.h" +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" +#include "portmacro.h" +#include "../../include/ramcf68k.h" + +#include "../lwip/perf.h" + +#ifndef _timer_ms +#define _timer_ms 0x442 +#endif + +typedef volatile unsigned long vuint32; +typedef volatile unsigned short vuint16; +typedef volatile unsigned char vuint8; + +#ifdef COLDFIRE +#ifdef MCF5445X +#include "mcf5445x.h" +#else /* MCF548X */ +#include "mcf548x.h" +extern unsigned char __MBAR[]; +#endif +#else /* !COLDFIRE */ +extern short os_magic; +#endif /* COLDFIRE */ + +#if defined(LWIP) || defined(FREERTOS) + +/* ------------------------ Defines --------------------------------------- */ +#ifdef COLDFIRE +#ifdef MCF5445X +#define SYSTEM_CLOCK 133 // system bus frequency in MHz +#define portVECTOR_TIMER ( 64 + INT0_HI_DTMR2 ) +#else /* MCF548X */ +#ifdef MCF547X +#define SYSTEM_CLOCK 133 // system bus frequency in MHz +#else /* MCF548X */ +#define SYSTEM_CLOCK 100 // system bus frequency in MHz +#endif /* MCF547X */ +#define portVECTOR_TIMER ( 64 + 54 ) +#endif +#else /* !COLDFIRE */ +#define portVECTOR_TIMER_C ( 69 ) +#define portVECTOR_TIMER_D ( 68 ) +#endif /* COLDFIRE */ +#define portVECTOR_SYSCALL ( 32 + portTRAP_YIELD ) + +#define portNO_CRITICAL_NESTING ( ( unsigned portLONG ) 0 ) +#define portINITIAL_CRITICAL_NESTING ( ( unsigned portLONG ) 10 ) + +/* ------------------------ Static variables ------------------------------ */ +volatile unsigned portLONG ulCriticalNesting; +#ifdef COLDFIRE +static unsigned portLONG portIntCounter; +#else +static unsigned long prvOldTrap; +static unsigned long prvOldTimer; +#endif + +/* ------------------------ Static functions ------------------------------ */ +#if configUSE_PREEMPTION == 0 +static void prvPortPreemptiveTick ( void ) __attribute__ ((interrupt_handler)); +#else +static void prvPortPreemptiveTick ( void ); +#endif + +/* ------------------------ Start implementation -------------------------- */ +#if( HAVE_USP == 1 ) +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, + void *pvParameters, portSTACK_TYPE * pxContext, unsigned portBASE_TYPE uxSuper, portSTACK_TYPE * pxTopOfUserStack, unsigned portBASE_TYPE uxMaskIntLevel ) +#else +portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE * pxTopOfStack, pdTASK_CODE pxCode, + void *pvParameters, portSTACK_TYPE * pxContext, unsigned portBASE_TYPE uxMaskIntLevel ) +#endif +{ +#if( HAVE_USP == 1 ) + if(uxSuper) + { +#endif + /* Place the parameter on the stack in the expected location. */ + *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; + pxTopOfStack--; + + /* Place dummy return address on stack. Tasks should never terminate so + * we can set this to anything. */ + *pxTopOfStack = ( portSTACK_TYPE ) 0xDEADDEAC; + pxTopOfStack--; +#if( HAVE_USP == 1 ) + } + else + { + /* Place the parameter on the stack in the expected location. */ + *pxTopOfUserStack = ( portSTACK_TYPE ) pvParameters; + pxTopOfUserStack--; + + /* Place dummy return address on stack. Tasks should never terminate so + * we can set this to anything. */ + *pxTopOfUserStack = ( portSTACK_TYPE ) 0xDEADDEAC; + } +#endif + +#ifdef COLDFIRE + /* Create a Motorola Coldfire exception stack frame. First comes the return address. */ + *pxTopOfStack = ( portSTACK_TYPE ) pxCode; + pxTopOfStack--; + + /* Format, fault-status, vector number for exception stack frame */ +#if( HAVE_USP == 1 ) + if(uxSuper) +#endif + *pxTopOfStack = 0x40002000UL | (portVECTOR_SYSCALL << 18) | ((uxMaskIntLevel & 7) << 8); +#if( HAVE_USP == 1 ) + else + *pxTopOfStack = 0x40000000UL | (portVECTOR_SYSCALL << 18) | ((uxMaskIntLevel & 7) << 8); +#endif + +#else /* !COLDFIRE */ + + *pxTopOfStack = (( portSTACK_TYPE ) pxCode << 16) | (portVECTOR_SYSCALL << 2); + pxTopOfStack--; + +#if( HAVE_USP == 1 ) + if(uxSuper) +#endif + *pxTopOfStack = 0x20000000UL | (( portSTACK_TYPE ) pxCode >> 16) | ((uxMaskIntLevel & 7) << 24); +#if( HAVE_USP == 1 ) + else + *pxTopOfStack = (( portSTACK_TYPE ) pxCode >> 16) | ((uxMaskIntLevel & 7) << 8); +#endif +#endif /* COLDFIRE */ + + *pxContext++ = ( portSTACK_TYPE ) 0xD0; /* D0 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD1; /* D1 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD2; /* D2 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD3; /* D3 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD4; /* D4 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD5; /* D5 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD6; /* D6 */ + *pxContext++ = ( portSTACK_TYPE ) 0xD7; /* D7 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA0; /* A0 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA1; /* A1 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA2; /* A2 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA3; /* A3 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA4; /* A4 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA5; /* A5 */ + *pxContext++ = ( portSTACK_TYPE ) 0xA6; /* A6 */ +#if( HAVE_USP == 1 ) + if(uxSuper) +#endif + *pxContext++ = ( portSTACK_TYPE ) (pxTopOfStack+3); /* A7/USP just for info */ +#if( HAVE_USP == 1 ) + else + *pxContext++ = ( portSTACK_TYPE ) (pxTopOfUserStack); /* A7/USP */ +#endif + +#if( SAVE_FPU == 1 ) +#ifdef COLDFIRE + *pxContext++ = ( portSTACK_TYPE ) 0x05000000; /* FSAVE IDLE state */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; + *pxContext++ = ( portSTACK_TYPE ) 0x00; + *pxContext++ = ( portSTACK_TYPE ) 0x00; +#else + *pxContext++ = ( portSTACK_TYPE ) 0xFC; /* FPICR */ + *pxContext++ = ( portSTACK_TYPE ) 0xFC; /* FPISR */ +#endif + *pxContext++ = ( portSTACK_TYPE ) 0xFA; /* FPIAR */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP0 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF0; /* FP0 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP1 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF1; /* FP1 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP2 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF2; /* FP2 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP3 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF3; /* FP3 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP4 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF4; /* FP4 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP5 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF5; /* FP5 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP6 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF6; /* FP6 */ + *pxContext++ = ( portSTACK_TYPE ) 0x00; /* FP7 */ + *pxContext++ = ( portSTACK_TYPE ) 0xF7; /* FP7 */ +#endif /* ( SAVE_FPU == 1 ) */ + + /* Set the initial critical section nesting counter to zero. This value + * is used to restore the value of ulCriticalNesting. */ + *pxContext++ = 0; + + return pxTopOfStack; +} + +extern long pxCurrentTCB, tid_TOS; + +#ifdef COLDFIRE + +extern volatile portTickType xTickCount; +#ifdef MCF5445X +unsigned long save_imrl0, save_imrl0_tos, save_imrh0, save_imrh0_tos, save_imrh1, save_imrh1_tos; +#else +unsigned long save_imrl, save_imrl_tos, save_imrh, save_imrh_tos; +extern void set_intfrcl(unsigned long mask); +extern void clr_intfrcl(unsigned long mask); +#endif + +void +portSaveRestoreInt( int iSave ) +{ + if( iSave ) + { +// PERF_START_INT; +#ifdef MCF5445X + if( pxCurrentTCB == tid_TOS ) + { + save_imrl0_tos = MCF_INTC_IMRL0; + save_imrh0_tos = MCF_INTC_IMRH0; + save_imrh1_tos = MCF_INTC_IMRH1; + } + else + { + save_imrl0 = MCF_INTC_IMRL0; + save_imrh0 = MCF_INTC_IMRH0; + save_imrh1 = MCF_INTC_IMRH1; + } +#else /* MCF548X */ + if( pxCurrentTCB == tid_TOS ) + { + save_imrl_tos = MCF_INTC_IMRL; + save_imrh_tos = MCF_INTC_IMRH; + } + else + { + save_imrl = MCF_INTC_IMRL; + save_imrh = MCF_INTC_IMRH; + } +#endif /* MCF5445X */ + } + else + { +#ifdef MCF5445X + if( pxCurrentTCB == tid_TOS ) + { + MCF_INTC_IMRL0 = save_imrl0_tos & save_imrl0; + MCF_INTC_IMRH0 = save_imrh0_tos & save_imrh0; + MCF_INTC_IMRH1 = save_imrh1_tos & save_imrh1; + if( *(unsigned short *)_timer_ms + && *(unsigned long *)_hz_200 < (unsigned long)xTickCount ) + { + MCF_INTC_INTFRCL0 |= INTC_INTFRCL_INTFRC6; /* force INT 6 */ + portIntCounter++; + if(portIntCounter >= (configTICK_RATE_HZ / 50) ) + { + portIntCounter = 0; + MCF_INTC_INTFRCL0 |= INTC_INTFRCL_INTFRC6; /* force INT 4 */ + } + } + } + else + { + MCF_INTC_IMRL0 = save_imrl0; + MCF_INTC_IMRH0 = save_imrh0; + MCF_INTC_IMRH1 = save_imrh1; + MCF_INTC_INTFRCL0 &= ~(INTC_INTFRCL_INTFRC4 | INTC_INTFRCL_INTFRC6); + } +#else /* MCF548X */ + if( pxCurrentTCB == tid_TOS ) + { + MCF_INTC_IMRL = save_imrl_tos & save_imrl; + MCF_INTC_IMRH = save_imrh_tos & save_imrh; + if(*(unsigned short *)_timer_ms + && *(unsigned long *)_hz_200 < (unsigned long)xTickCount ) + { +#ifndef MCF547X /* because INT7 is used on MCF5484LITE for PCI */ + set_intfrcl(MCF_INTC_INTFRCL_INTFRC6); // same cycle +#else + MCF_INTC_INTFRCL |= MCF_INTC_INTFRCL_INTFRC6; /* force INT 6 */ +#endif /* MCF547X */ + portIntCounter++; + if(portIntCounter >= (configTICK_RATE_HZ / 50) ) + { + portIntCounter = 0; +#ifndef MCF547X /* because INT7 is used on MCF5484LITE for PCI */ + set_intfrcl(MCF_INTC_INTFRCL_INTFRC4); // same cycle +#else + MCF_INTC_INTFRCL |= MCF_INTC_INTFRCL_INTFRC4; /* force INT 4 */ +#endif /* MCF547X */ + } + } + } + else + { + MCF_INTC_IMRL = save_imrl; + MCF_INTC_IMRH = save_imrh; +#ifndef MCF547X /* because INT7 is used on MCF5484LITE for PCI */ + clr_intfrcl(~(MCF_INTC_INTFRCL_INTFRC4 | MCF_INTC_INTFRCL_INTFRC6)); // same cycle +#else + MCF_INTC_INTFRCL &= ~(MCF_INTC_INTFRCL_INTFRC4 | MCF_INTC_INTFRCL_INTFRC6); +#endif /* MCF547X */ + } +#endif /* MCF5445X */ +// PERF_STOP_INT("inter"); + } +} + +/* + * Called by portYIELD() or taskYIELD() to manually force a context switch. + */ +static void +prvPortYield( void ) +{ +#if (__GNUC__ <= 3) + asm volatile (".chip 68060\n\t"); +#endif + asm volatile (" move.w #0x2700, sr\n\t"); +#if _GCC_USES_FP == 1 + asm volatile (" unlk fp\n\t"); +#endif + asm volatile ( + " move.l d0, -(sp)\n\t" + " move.l a0, -(sp)\n\t" + " move.l usp, a0\n\t" + " btst #5, 10(sp)\n\t" // call in supervisor state + " beq.s .user\n\t" + " move.b 8(sp), d0\r\n" // get SP alignment bits from A7 stack frame + " lsr.l #4, d0\n\t" + " and.l #3, d0\n\t" + " addq.l #8, d0\n\t" + " addq.l #8, d0\n\t" + " add.l sp, d0\n\t" + " move.l d0, a0\n\t" + ".user:\n\t" + " moveq #0, d0\n\t" + " move.w (a0), d0\n\t" + " cmp.l #0xFE, d0\n\t" // function + " beq .set_ipl\n\t" + " cmp.l #0xFF, d0\n\t" // function + " beq .yield\n\t" + " move.l (sp)+, a0\n\t" + " addq.l #4, sp\n\t" + " moveq #-1, d0\n\t" + " rte\n\t" + ".set_ipl:\n\t" + " move.l d6, -(sp)\n\t" + " move.l d7, -(sp)\n\t" + " move.w 18(sp), d7\n\t" // current SR + " move.l d7, d0\n\t" // prepare return value + " and.l #0x700, d0\n\t" // mask out IPL + " lsr.l #8, d0\n\t" // IPL + " move.l 2(a0), d6\n\t" // get argument + " and.l #7, d6\n\t" // least significant three bits + " lsl.l #8, d6\n\t" // move over to make mask + " and.l #0xF8FF, d7\n\t" // zero out current IPL + " or.l d6, d7\n\t" // place new IPL in SR + " move.w d7, 18(sp)\n\t" + " move.l (sp)+, d7\n\t" + " move.l (sp)+, d6\n\t" + " move.l (sp)+, a0\n\t" + " addq.l #4, sp\n\t" + " rte\n\t" + ".yield:\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0" ); + /* Perform the context switch. First save the context of the current task. */ + portSAVE_CONTEXT( ); + /* Find the highest priority task that is ready to run. */ + vTaskSwitchContext( ); + /* Restore the context of the new task. */ + portRESTORE_CONTEXT( ); +} + +#else /* !COLDFIRE */ + +extern short usb_found, ethernet_found; + +/* + * Called by portYIELD() or taskYIELD() to manually force a context switch. + */ +static void +prvPortYield( void ) +{ +#if _GCC_USES_FP == 1 + asm volatile (" unlk fp\n\t"); +#endif + asm volatile ( + " move.l d0, -(sp)\n\t" + " move.l a0, -(sp)\n\t" + " move.l usp, a0\n\t" + " btst #5, 8(sp)\n\t" // call in supervisor state + " beq.s .user\n\t" + " move.l 10(sp), a0\n\t" // return address + " move.l -6(a0), d0\n\t" // instruction before trap + " cmp.l #0x46FC2300, d0\n\t" // move.w #0x2300,SR MAGXBOOT.PRG + " beq.s .oldtrap\n\t" + " lea 8+8(sp), a0\n\t" + ".user:\n\t" + " moveq #0, d0\n\t" + " move.w (a0), d0\n\t" + " cmp.l #0xFE, d0\n\t" // function + " beq .set_ipl\n\t" + " cmp.l #0xFF, d0\n\t" // function + " beq .yield\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0\n\t" + " rte\n\t" + ".oldtrap:\n\t" + " move.l d1, -(sp)\n\t" + " move.l a1, -(sp)\n\t" + " jsr _vPortEndScheduler\n\t" + " move.l (sp)+, a1\n\t" + " move.l (sp)+, d1\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0\n\t" + " move.l _prvOldTrap, -(%sp)\n\t" + " rts\n\t" + ".set_ipl:\n\t" + " move.l d6, -(sp)\n\t" + " move.l d7, -(sp)\n\t" + " move.w 16(sp), d7\n\t" // current SR + " move.l d7, d0\n\t" // prepare return value + " and.l #0x700, d0\n\t" // mask out IPL + " lsr.l #8, d0\n\t" // IPL + " move.l 2(a0), d6\n\t" // get argument + " and.l #7, d6\n\t" // least significant three bits + " lsl.l #8, d6\n\t" // move over to make mask + " and.l #0xF8FF, d7\n\t" // zero out current IPL + " or.l d6, d7\n\t" // place new IPL in SR + " move.w d7, 16(sp)\n\t" + " move.l (sp)+, d7\n\t" + " move.l (sp)+, d6\n\t" + " move.l (sp)+, a0\n\t" + " addq.l #4, sp\n\t" + " rte\n\t" + ".yield:\n\t" + " move.l (sp)+, a0\n\t" + " move.l (sp)+, d0\n\t" + " or.w #0x0700, sr" ); // mask interrupts + /* Perform the context switch. First save the context of the current task. */ + portSAVE_CONTEXT( ); + /* Find the highest priority task that is ready to run. */ + vTaskSwitchContext( ); + /* Restore the context of the new task. */ + portRESTORE_CONTEXT( ); +} + +void MfpTimer(void) +{ +// if(os_magic == 1) + { + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = (unsigned long)prvPortYield; + *(volatile unsigned char *)0xFFFFFA11 = 0xEF; /* clear Timer D ISRB MFP */ + return; + } +#if 0 + asm volatile ( + " addq.l #1,0x4BA\n\t" // _hz_200 + " rol.w 0x11BA\n\t" + " bpl.s .mtc1\n\t" + " movem.l d0-d7/a0-a6,-(sp)\n\t" + " jsr 0xE03CAE\n\t" + " btst #1,0x484\n\t" // conterm + " beq.s .mtc2\n\t" + " tst.b 0x11B1\n\t" + " beq.s .mtc2\n\t" + " tst.b 0x11B2\n\t" + " beq.s .mtc3\n\t" + " subq.b #1,0x11B2\n\t" + " bne.s .mtc2\n\t" + ".mtc3:\n\t" + " subq.b #1,0x11B3\n\t" + " bne.s .mtc2\n\t" + " move.b 0x11B5,0x11B3\n\t" + " move.b 0x11B1,d0\n\t" + " lea 0xF96,a0\n\t" + " jsr 0xE03508\n\t" + ".mtc2:\n\t" + " move.w 0x442,-(sp)\n\t" // _timr_ms + " movea.l 0x400,a0\n\t" // etv_timer + " jsr (a0)\n\t" + " addq.l #2,sp\n\t" + " movem.l (sp)+,d0-d7/a0-a6\n\t" + ".mtc1:" ); + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = (unsigned long)prvPortYield; + *(volatile unsigned char *)0xFFFFFA11 = 0xDF; /* clear Timer C ISRB MFP */ +#endif +} + +#endif /* COLDFIRE */ + +void portYIELD(void) +{ + asm volatile ( + " move.w #0xFF, -(sp)\n\t" + " trap %0\n\t" + " addq.l #2, sp" : : "i" (portTRAP_YIELD) : "d0", "d1", "a0", "a1", "memory", "cc" ); +} + +int vPortSetIPL( unsigned long int uiNewIPL ) +{ +#if ( HAVE_USP == 1 ) + if( !xTaskIsSuper() || ( pxCurrentTCB == tid_TOS ) ) +#else +#ifdef COLDFIRE + if(*(unsigned long *)(((portVECTOR_SYSCALL) * 4) + coldfire_vector_base) == (unsigned long)prvPortYield) +#else /* !COLDFIRE */ + if( pxCurrentTCB == tid_TOS ) +#endif /* COLDFIRE */ +#endif /* ( HAVE_USP == 1 ) */ + { + register int iOldIPL __asm__("d0"); + asm volatile ( + " move.l %1, -(sp)\n\t" + " move.w #0xFE, -(sp)\n\t" + " trap %2\n\t" + " addq.l #6, sp" : "=d" (iOldIPL) : "d" (uiNewIPL), "i" (portTRAP_YIELD) : "d1", "a0", "a1", "memory", "cc" ); + return( iOldIPL ); + } + else + { + register int iOldIPL __asm__("d0"); + asm volatile ( + " move.l %1, d6\n\t" /* get argument */ + " move.w sr, d7\n\t" /* current SR */ + " move.l d7, d0\n\t" /* prepare return value */ + " and.l #0x700, d0\n\t" /* mask out IPL */ + " lsr.l #8, d0\n\t" /* IPL */ + " and.l #7, d6\n\t" /* least significant three bits */ + " lsl.l #8, d6\n\t" /* move over to make mask */ + " and.l #0xF8FF, d7\n\t" /* zero out current IPL */ + " or.l d6, d7\n\t" /* place new IPL in SR */ + " move.w d7, sr" : "=d" (iOldIPL) : "d" (uiNewIPL) : "d6", "d7", "memory", "cc" ); + return( iOldIPL ); + } +} + +#if (configUSE_PREEMPTION == 0) +/* + * The ISR used for the scheduler tick depends on whether the cooperative or + * the preemptive scheduler is being used. + */ +static void +prvPortPreemptiveTick ( void ) +{ + /* The cooperative scheduler requires a normal IRQ service routine to + * simply increment the system tick. + */ + vTaskIncrementTick( ); +#ifdef COLDFIRE +#ifdef MCF5445X + MCF_DTIM_DTER(2) = DTIM_DTER_REF; +#else /* MCF548X */ + MCF_SLT_SSR(0) |= MCF_SLT_SSR_ST; /* clear interrupt */ +#endif +#else /* !COLDFIRE */ + MfpTimer(); +#endif /* COLDFIRE */ +} + +#else + +static void +prvPortPreemptiveTick( void ) +{ + asm volatile ( " move.w #0x2700, sr\n\t" ); +#if _GCC_USES_FP == 1 + asm volatile ( " unlk fp\n\t" ); +#endif + portSAVE_CONTEXT( ); +#ifdef COLDFIRE +#ifdef MCF5445X + MCF_DTIM_DTER(2) = DTIM_DTER_REF; +#else /* MCF548X */ + MCF_SLT_SSR(0) |= MCF_SLT_SSR_ST; /* clear interrupt */ +#endif +#else /* !COLDFIRE */ + MfpTimer(); +#endif /* COLDFIRE */ + vTaskIncrementTick( ); + vTaskSwitchContext( ); + portRESTORE_CONTEXT( ); +} + +static void +prvPortPreemptiveTick2( void ) +{ + *(volatile unsigned char *)0xFFFFFA11 = 0xEF; /* clear Timer D ISRB MFP */ + asm volatile ( " rte\n\t"); +} + +#endif /* (configUSE_PREEMPTION == 0) */ + +static int portOldIPL, portOldIPLTOS; + +void +vPortEnterCritical() +{ + int level = portSET_IPL( portIPL_MAX ); + if( ulCriticalNesting == portNO_CRITICAL_NESTING ) + { + if( pxCurrentTCB != tid_TOS ) + portOldIPL = level; + else + portOldIPLTOS = level; + } + /* Now interrupts are disabled ulCriticalNesting can be accessed + * directly. Increment ulCriticalNesting to keep a count of how many times + * portENTER_CRITICAL() has been called. */ + ulCriticalNesting++; +} + +void +vPortExitCritical() +{ + if( ulCriticalNesting > portNO_CRITICAL_NESTING ) + { + /* Decrement the nesting count as we are leaving a critical section. */ + ulCriticalNesting--; + /* If the nesting level has reached zero then interrupts should be + re-enabled. */ + if( ulCriticalNesting == portNO_CRITICAL_NESTING ) + ( void )portSET_IPL( pxCurrentTCB != tid_TOS ? portOldIPL : portOldIPLTOS ); + } +} + +#ifdef COLDFIRE + +static void rte_int(void) +{ +#if _GCC_USES_FP == 1 + asm volatile (" unlk fp\n\t"); +#endif + asm volatile (" rte\n\t"); +} + +#endif + +portBASE_TYPE +xPortStartScheduler( void ) +{ + asm volatile ( "move.w #0x2700, sr\n\t" ); + +#ifdef COLDFIRE + *(unsigned long *)_hz_200 = 0; + /* Add entry in vector table for yield system call. */ + *(unsigned long *)(((portVECTOR_SYSCALL) * 4) + coldfire_vector_base) = (unsigned long)prvPortYield; + /* Add entry in vector table for periodic timer. */ + *(unsigned long *)(((portVECTOR_TIMER) * 4) + coldfire_vector_base) = (unsigned long)prvPortPreemptiveTick; + /* sometimes spurious interrupt not fixed ! */ + *(unsigned long *)((24 * 4) + coldfire_vector_base) = (long)rte_int; +#else /* !COLDFIRE */ + /* Add entry in vector table for yield system call. */ + prvOldTrap = *(unsigned long *)((portVECTOR_SYSCALL) * 4); + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = (unsigned long)prvPortYield; + /* Add entry in vector table for periodic timer. */ +// if(os_magic == 1) + *(unsigned long *)((portVECTOR_TIMER_D) * 4) = (unsigned long)prvPortPreemptiveTick; +// else + { + prvOldTimer = *(unsigned long *)((portVECTOR_TIMER_C) * 4); +// *(unsigned long *)((portVECTOR_TIMER_C) * 4) = (unsigned long)prvPortPreemptiveTick; + } +#endif /* COLDFIRE */ + + ulCriticalNesting = portINITIAL_CRITICAL_NESTING; + + /* Configure the timer for the system clock. */ + if(configTICK_RATE_HZ > 0) + { +#ifdef COLDFIRE +#ifdef MCF5445X + /* Initialize the periodic timer interrupt. */ + MCF_DTIM_DTMR(2) = DTIM_DTMR_ORRI | DTIM_DTMR_FRR | DTIM_DTMR_CLK(1); + MCF_DTIM_DTCN(2) = 0; + MCF_DTIM_DTXMR(2) = 0; + MCF_DTIM_DTRR(2) = (SYSTEM_CLOCK * 1000000UL) / configTICK_RATE_HZ; + MCF_DTIM_DTMR(2) |= DTIM_DTMR_RST; /* run */ + /* Configure interrupt priority and level and unmask interrupt. */ + MCF_INTC_ICR0n(INT0_HI_DTMR2) = INTC_ICR_IL( 0x6 ); + MCF_INTC_IMRH0 &= ~INTC_IMRH_INT_MASK34; + save_imrl0 = save_imrl0_tos = MCF_INTC_IMRL0; + save_imrh0 = save_imrh0_tos = MCF_INTC_IMRH0; + save_imrh1 = save_imrh1_tos = MCF_INTC_IMRH1; +#else /* MCF548X */ + /* Initialize the periodic timer interrupt. */ + MCF_SLT_SLTCNT(0) = (SYSTEM_CLOCK * 1000000UL) / configTICK_RATE_HZ; + MCF_SLT_SCR(0) = MCF_SLT_SCR_TEN | MCF_SLT_SCR_IEN | MCF_SLT_SCR_RUN; + /* Configure interrupt priority and level and unmask interrupt. */ + MCF_INTC_ICR54 = MCF_INTC_ICRn_IL( 0x6 ) | MCF_INTC_ICRn_IP( 0x6 ); + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK54; + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_MASKALL; + save_imrl = save_imrl_tos = MCF_INTC_IMRL; + save_imrh = save_imrh_tos = MCF_INTC_IMRH; +#endif /* MCF5445X */ +#else /* !COLDFIRE */ + /* TOS use the MFP timer C already started. */ +// if(os_magic == 1) /* MagiC use the MFP timer D */ + { + Xbtimer(3, 5, 2457600 / (64 * configTICK_RATE_HZ), -1); + Jenabint(4); /* timer D */ + } +#endif /* COLDFIRE */ + } + + /* Restore the context of the first task that is going to run. */ + portRESTORE_CONTEXT( ); + /* Should not get here. */ + return pdTRUE; +} + +void +vPortEndScheduler( void ) +{ +#ifndef COLDFIRE + if(*(unsigned long *)((portVECTOR_TIMER_C) * 4) == (unsigned long)prvPortPreemptiveTick) + *(unsigned long *)((portVECTOR_TIMER_C) * 4) = prvOldTimer; + *(unsigned long *)((portVECTOR_SYSCALL) * 4) = prvOldTrap; /* for MAGXBOOT */ +#endif +} + +unsigned portBASE_TYPE +uxPortReadTimer( void ) /* vTaskStartTrace */ +{ +#ifdef COLDFIRE +#ifdef MCF5445X + return((unsigned portBASE_TYPE)MCF_DTIM_DTCN(2) / SYSTEM_CLOCK); +#else /* MCF548X */ + return((unsigned portBASE_TYPE)(MCF_SLT_SLTCNT(0) - MCF_SLT_SCNT(0)) / SYSTEM_CLOCK); +#endif /* MCF5445X */ +#else /* !COLDFIRE */ + return(0); +#endif /* COLDFIRE */ +} + +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/freertos/portmacro.h b/flash.tos/drivers/freertos/portmacro.h index ebb3dab..6419b28 100644 --- a/flash.tos/drivers/freertos/portmacro.h +++ b/flash.tos/drivers/freertos/portmacro.h @@ -44,13 +44,17 @@ #define portBASE_TYPE int #define tskSTACK_FILL_TYPE ( 0xa5a5a5a5 ) +#ifdef COLDFIRE #define HAVE_USP 1 - #ifdef MCF5445X #define SAVE_FPU 0 #else #define SAVE_FPU 1 #endif +#else /* !COLDFIRE */ +#define HAVE_USP 0 +#define SAVE_FPU 0 +#endif /* COLDFIRE */ #if( USE_16_BIT_TICKS == 1 ) typedef unsigned portSHORT portTickType; @@ -78,6 +82,8 @@ * the stack for the CPU registers and other task dependent values (e.g * ulCriticalNesting) and updates the top of the stack in the TCB. */ +#ifdef COLDFIRE + #if (__GNUC__ <= 3) #if( HAVE_USP == 1 ) @@ -506,6 +512,106 @@ #endif /* __GNUC >= 3 */ +#else /* !COLDFIRE */ + +#if( SAVE_FPU == 1 ) +#define portSAVE_CONTEXT() \ + asm volatile ( \ + " .chip 68060\n\t" \ + " move.l a0, -(sp)\n\t" \ + " move.l a1, -(sp)\n\t" \ + " move.l _pxCurrentTCB, a0\n\t" \ + " lea.l 8(sp), a1\n\t" \ + " move.l a1, (a0)+\n\t" \ + " move.l usp, a1\n\t" \ + " move.l a1, 60(a0)\n\t" \ + " lea.l 64(a0), a1\n\t" \ + " fmove.l fpcr, (a1)+\n\t" \ + " fmove.l fpsr, (a1)+\n\t" \ + " fmove.l fpiar, (a1)+\n\t" \ + " fmovem.x fp0-fp7, (a1)\n\t" \ + " lea.l 64(a1), a1\n\t" \ + " move.l _ulCriticalNesting, (a1)\n\t" \ + " move.l (sp)+, a1\n\t" \ + " movem.l d0-d7, (a0)\n\t" \ + " movem.l a1-a6, 36(a0)\n\t" \ + " move.l (sp)+, 32(a0)"); +#else +#define portSAVE_CONTEXT() \ + asm volatile ( \ + " .chip 68060\n\t" \ + " move.l a0, -(sp)\n\t" \ + " move.l a1, -(sp)\n\t" \ + " move.l _pxCurrentTCB, a0\n\t" \ + " lea.l 8(sp), a1\n\t" \ + " move.l a1, (a0)+\n\t" \ + " move.l usp, a1\n\t" \ + " move.l a1, 60(a0)\n\t" \ + " lea.l 64(a0), a1\n\t" \ + " move.l _ulCriticalNesting, (a1)\n\t" \ + " move.l (sp)+, a1\n\t" \ + " movem.l d0-d7, (a0)\n\t" \ + " movem.l a1-a6, 36(a0)\n\t" \ + " move.l (sp)+, 32(a0)"); +#endif + +/*. + * This function restores the current active and continues its execution. + * It loads the current TCB and restores the processor registers, the + * task dependent values (e.g ulCriticalNesting). Finally execution + * is continued by executing an rte instruction. + */ +#if( SAVE_FPU == 1 ) +#define portRESTORE_CONTEXT() \ + asm volatile ( " move.l _pxCurrentTCB, a0\n\t" \ + " move.l (a0)+, sp\n\t" \ + " move.l 60(a0), a1\n\t" \ + " move.l a1, usp\n\t" \ + " lea.l 64(a0), a1\n\t" \ + " fmove.l (a1)+, fpcr\n\t" \ + " fmove.l (a1)+, fpsr\n\t" \ + " fmove.l (a1)+, fpiar\n\t" \ + " fmovem.x (a1), fp0-fp7\n\t" \ + " lea.l 64(a1), a1\n\t" \ + " move.l (a1), _ulCriticalNesting\n\t" \ + " movem.l (a0), d0-d7/a0-a6\n\t" \ + " rte\n\t" ); +#else +#define portRESTORE_CONTEXT() \ + asm volatile ( " move.l _pxCurrentTCB, a0\n\t" \ + " move.l (a0)+, sp\n\t" \ + " move.l 60(a0), a1\n\t" \ + " move.l a1, usp\n\t" \ + " lea.l 64(a0), a1\n\t" \ + " move.l (a1), _ulCriticalNesting\n\t" \ + " movem.l (a0), d0-d7/a0-a6\n\t" \ + " rte\n\t" ); +#endif + +#if( SAVE_FPU == 1 ) +#define portRESTORE_FAST_CONTEXT() \ + asm volatile ( " move.l _pxCurrentTCB, a0\n\t" \ + " move.l (a0)+, sp\n\t" \ + " lea.l 140(a0), a1\n\t" \ + " move.l (a1), _ulCriticalNesting\n\t" \ + " movem.l (a0), d0-d1\n\t" \ + " lea.l 32(a0),a0\n\t" \ + " movem.l (a0), a0-a1\n\t" \ + " rte\n\t" ); +#else +#define portRESTORE_FAST_CONTEXT() \ + asm volatile ( " move.l _pxCurrentTCB, a0\n\t" \ + " move.l (a0)+, sp\n\t" \ + " lea.l 64(a0), a1\n\t" \ + " move.l (a1), _ulCriticalNesting\n\t" \ + " movem.l (a0), d0-d1\n\t" \ + " lea.l 32(a0),a0\n\t" \ + " movem.l (a0), a0-a1\n\t" \ + " rte\n\t" ); +#endif + +#endif /* COLDFIRE */ + #define portENTER_CRITICAL() \ vPortEnterCritical(); @@ -528,14 +634,14 @@ #if _GCC_USES_FP == 1 #define portENTER_SWITCHING_ISR() \ - asm volatile ( " move.w #0x2700, sr\n\t" \ + asm volatile ( " move.w #0x2700, sr\n\t" \ " unlk fp\n\t" ); \ /* Save the context of the interrupted task. */ \ portSAVE_CONTEXT( ); \ { #else #define portENTER_SWITCHING_ISR() \ - asm volatile (" move.w #0x2700, sr\n\t"); \ + asm volatile (" move.w #0x2700, sr\n\t"); \ /* Save the context of the interrupted task. */ \ portSAVE_CONTEXT( ); \ { diff --git a/flash.tos/drivers/freertos/queue.c b/flash.tos/drivers/freertos/queue.c index 075c554..249510a 100644 --- a/flash.tos/drivers/freertos/queue.c +++ b/flash.tos/drivers/freertos/queue.c @@ -83,8 +83,7 @@ Changes from V4.1.3: #include "task.h" #include "croutine.h" -#ifdef NETWORK -#ifdef LWIP +#if defined(LWIP) || defined(FREERTOS) #define MAGIC_KEY 0x16101964 @@ -1171,5 +1170,4 @@ signed portBASE_TYPE xReturn; #endif /*-----------------------------------------------------------*/ -#endif /* LWIP */ -#endif /* NETWORK */ +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/freertos/task.h b/flash.tos/drivers/freertos/task.h index 8991acc..12ab024 100644 --- a/flash.tos/drivers/freertos/task.h +++ b/flash.tos/drivers/freertos/task.h @@ -964,6 +964,16 @@ void vTaskMissedYield( void ); */ portBASE_TYPE xTaskGetSchedulerState( void ); +/* + * Return the handle from the task name. + */ +xTaskHandle xTaskGetTaskHandleFromName( const signed portCHAR * const pcName ); + +/* + * Return the task name from the TCB number. + */ +signed portCHAR * pTaskGetTraceName( unsigned portBASE_TYPE uxTCBNumber ); + /* * Return if the task runs in Supervisor */ diff --git a/flash.tos/drivers/freertos/tasks.c b/flash.tos/drivers/freertos/tasks.c index e8e9743..5d1b8c2 100644 --- a/flash.tos/drivers/freertos/tasks.c +++ b/flash.tos/drivers/freertos/tasks.c @@ -216,8 +216,7 @@ Changes since V4.3.1: #include "FreeRTOS.h" #include "task.h" -#ifdef NETWORK -#ifdef LWIP +#if defined(LWIP) || defined(FREERTOS) #define MAGIC_KEY 0x19641016 @@ -597,7 +596,11 @@ static unsigned portBASE_TYPE uxTaskNumber = 0; /*lint !e956 Static is deliberat but had been interrupted by the scheduler. The return address is set to the start of the task function. Once the stack has been initialised the top of stack variable is updated. */ +#ifdef COLDFIRE pxNewTCB->uxStartIntLevel = strcmp( (void *)pcName, "TOS" ) == 0 ? 0 : 3; +#else + pxNewTCB->uxStartIntLevel = 3; /* HBL mask */ +#endif #if( HAVE_USP == 1 ) pxNewTCB->pxTopOfStack = pxPortInitialiseStack( pxTopOfStack, pvTaskCode, pvParameters, pxNewTCB->Context, pxNewTCB->uxSuper, pxTopOfUserStack, pxNewTCB->uxStartIntLevel ); #else @@ -1631,7 +1634,18 @@ void vTaskSwitchContext( void ) /* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the tasks of the same priority get an equal share of the processor time. */ +#ifdef COLDFIRE listGET_OWNER_OF_NEXT_ENTRY( pxCurrentTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); +#else + { + tskTCB * pxTempTCB; + listGET_OWNER_OF_NEXT_ENTRY( pxTempTCB, &( pxReadyTasksLists[ uxTopReadyPriority ] ) ); + if(pxTempTCB) + pxCurrentTCB = pxTempTCB; + else + conws_debug("pxCurrentTCB NULL\r\n"); + } +#endif vWriteTraceToBuffer(); } /*-----------------------------------------------------------*/ @@ -2062,6 +2076,100 @@ tskTCB *pxNewTCB; } while( pxNextTCB != pxFirstTCB ); pxListTCB->pxTCB = NULL; } +static xTaskHandle prvTaskSearchName( const signed portCHAR * const pcName , xList * pxList ) +{ + volatile tskTCB *pxNextTCB, *pxFirstTCB; + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + if( strcmp( pcName, ( const signed portCHAR * ) pxNextTCB->pcTaskName ) == 0 ) + return( (xTaskHandle ) pxNextTCB ); + } + while( pxNextTCB != pxFirstTCB ); + return 0; +} + +xTaskHandle xTaskGetTaskHandleFromName( const signed portCHAR * const pcName ) +{ + xTaskHandle xReturn = 0; + unsigned portBASE_TYPE uxQueue; + vTaskSuspendAll(); + uxQueue = uxTopUsedPriority + 1; + do + { + uxQueue--; + if(!listLIST_IS_EMPTY(&(pxReadyTasksLists[uxQueue]))) + { + xReturn = prvTaskSearchName( pcName, (xList *)&(pxReadyTasksLists[uxQueue]) ); + if(xReturn) + break; + } + } + while( uxQueue > ( unsigned portSHORT ) tskIDLE_PRIORITY ); + if( !xReturn && !listLIST_IS_EMPTY( pxDelayedTaskList )) + xReturn = prvTaskSearchName( pcName, (xList *)pxDelayedTaskList ); + if( !xReturn && !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + xReturn = prvTaskSearchName( pcName, (xList *)pxOverflowDelayedTaskList ); +#if ( INCLUDE_vTaskDelete == 1 ) + if( !xReturn && !listLIST_IS_EMPTY( &xTasksWaitingTermination ) ) + xReturn = prvTaskSearchName( pcName, (xList *)&xTasksWaitingTermination ); +#endif +#if ( INCLUDE_vTaskSuspend == 1 ) + if( !xReturn && !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + xReturn = prvTaskSearchName( pcName, (xList *)&xSuspendedTaskList ); +#endif + xTaskResumeAll(); + return xReturn; +} + +signed portCHAR * prvTaskSearchTCBNumber( unsigned portBASE_TYPE uxTCBNumber , xList * pxList ) +{ + volatile tskTCB *pxNextTCB, *pxFirstTCB; + listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList ); + do + { + listGET_OWNER_OF_NEXT_ENTRY( pxNextTCB, pxList ); + if( uxTCBNumber == pxNextTCB->uxTCBNumber ) + return (signed portCHAR * ) pxNextTCB->pcTaskName; + } + while( pxNextTCB != pxFirstTCB ); + return NULL; +} + +signed portCHAR * pTaskGetTraceName( unsigned portBASE_TYPE uxTCBNumber ) +{ + signed portCHAR * pReturn = NULL; + unsigned portBASE_TYPE uxQueue; + vTaskSuspendAll(); + uxQueue = uxTopUsedPriority + 1; + do + { + uxQueue--; + if(!listLIST_IS_EMPTY(&(pxReadyTasksLists[uxQueue]))) + { + pReturn = prvTaskSearchTCBNumber( uxTCBNumber, (xList *)&(pxReadyTasksLists[uxQueue]) ); + if(pReturn) + break; + } + } + while( uxQueue > ( unsigned portSHORT ) tskIDLE_PRIORITY ); + if( !pReturn && !listLIST_IS_EMPTY( pxDelayedTaskList )) + pReturn = prvTaskSearchTCBNumber( uxTCBNumber, (xList *)pxDelayedTaskList ); + if( !pReturn && !listLIST_IS_EMPTY( pxOverflowDelayedTaskList ) ) + pReturn = prvTaskSearchTCBNumber( uxTCBNumber, (xList *)pxOverflowDelayedTaskList ); +#if ( INCLUDE_vTaskDelete == 1 ) + if( !pReturn && !listLIST_IS_EMPTY( &xTasksWaitingTermination ) ) + pReturn = prvTaskSearchTCBNumber( uxTCBNumber, (xList *)&xTasksWaitingTermination ); +#endif +#if ( INCLUDE_vTaskSuspend == 1 ) + if( !pReturn && !listLIST_IS_EMPTY( &xSuspendedTaskList ) ) + pReturn = prvTaskSearchTCBNumber( uxTCBNumber, (xList *)&xSuspendedTaskList ); +#endif + xTaskResumeAll(); + return pReturn; +} + #endif /*-----------------------------------------------------------*/ @@ -2166,7 +2274,6 @@ tskTCB *pxNewTCB; #endif -#endif /* LWIP */ -#endif /* NETWORK */ +#endif /* defined(LWIP) || defined(FREERTOS) */ diff --git a/flash.tos/drivers/fvdi/include/macros.inc b/flash.tos/drivers/fvdi/include/macros.inc index a0a3190..8972999 100644 --- a/flash.tos/drivers/fvdi/include/macros.inc +++ b/flash.tos/drivers/fvdi/include/macros.inc @@ -1,3 +1,5 @@ +#undef mc68000 + // ifb stack .global stack_address .global vdi_stack diff --git a/flash.tos/drivers/fvdi/utility.c b/flash.tos/drivers/fvdi/utility.c index 5a11879..5018f71 100644 --- a/flash.tos/drivers/fvdi/utility.c +++ b/flash.tos/drivers/fvdi/utility.c @@ -294,7 +294,7 @@ static void *fmalloc(long size, long type) static long free(void *addr) { - if((os_magic == 1) && !memory_ok) + if(os_magic && !memory_ok) return(0); return(Mfree(addr)); } diff --git a/flash.tos/drivers/gcc.S b/flash.tos/drivers/gcc.S index c531d51..822896a 100644 --- a/flash.tos/drivers/gcc.S +++ b/flash.tos/drivers/gcc.S @@ -4,6 +4,7 @@ #define EQUAL 0 /* TOS 4.04 calls */ +#define _form_alert_tos 0xE22A68 #define _form_center_tos 0xE491BE #define _form_dial_tos 0xE49180 #define _form_do_tos 0xE49164 @@ -20,7 +21,7 @@ #define _gr_slidebox 0xE2574E #define _copy16 0xE49216 - .global _form_center,_form_dial,_form_do + .global _form_alert,_form_center,_form_dial,_form_do .global _objc_draw,_objc_offset .global _menu_icheck,_menu_popup .global _wind_get,_wind_update @@ -266,6 +267,16 @@ ___isnanf: #endif /* MCF5445X */ #endif /* COLDFIRE */ +// short form_alert(short fo_adefbttn, char *fo_astring) +_form_alert: + move.l 4(SP),D0 + move.l 8(SP),A0 + pea (A0) + mov.w D0,-(SP) + jsr _form_alert_tos + addq.l #6,SP + rts + // short form_center(OBJECT *fo_ctree, short *fo_cx, short *fo_cy, short *fo_cw, short *fo_ch) _form_center: move.l D2,-(SP) diff --git a/flash.tos/drivers/get.c b/flash.tos/drivers/get.c index af7586f..f9b47fa 100644 --- a/flash.tos/drivers/get.c +++ b/flash.tos/drivers/get.c @@ -5,7 +5,7 @@ #include "get.h" #include "../include/ramcf68k.h" -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern void board_printf(const char *fmt, ...); #else #define board_printf @@ -15,7 +15,7 @@ extern void board_printf(const char *fmt, ...); #define client_ip_addr *(unsigned long *)(ip_address) #define server_ip_addr *(unsigned long *)(server_ip_address) -#ifdef NETWORK +#ifdef LWIP unsigned char *board_get_ethaddr(unsigned char *ethaddr) { @@ -101,7 +101,7 @@ unsigned char *board_get_netmask(unsigned char *netmask) if((client_ip_addr != 0xFFFFFFFF) && (client_ip_addr & 0xFFFF0000)) { netmask[0] = 0xFF; - if(client_ip_addr <= 0x80000000) + if(client_ip_addr < 0x80000000) { if((client_ip_addr & 0xFF000000) == 0x0A000000) { @@ -114,7 +114,7 @@ unsigned char *board_get_netmask(unsigned char *netmask) netmask[2] = 0x00; } } - else if(client_ip_addr <= 0xC0000000) + else if(client_ip_addr < 0xC0000000) { netmask[1] = 0xFF; netmask[2] = 0x00; @@ -163,5 +163,5 @@ char *board_get_filename(char *filename) return filename; } -#endif /* NETWORK */ +#endif /* LWIP */ diff --git a/flash.tos/drivers/header.S b/flash.tos/drivers/header.S index 873995a..bc57baa 100644 --- a/flash.tos/drivers/header.S +++ b/flash.tos/drivers/header.S @@ -1,5 +1,5 @@ /* TOS 4.04 header for for the CT60/CF boards drivers -* Didier Mequignon 2006-2010, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2006-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,10 +19,10 @@ #include "config.h" #include "version.h" - .global Start,_init_devices,_init_with_sdram,_init_before_autofolder + .global Start,_init_devices,_init_with_sdram,_init_before_autofolder,init_after_autofolder .global _clear_screen,_move_screen,_print_screen .global _dbug,_event_aes,_disassemble_pc - .global _init_rtos,_set_video + .global _init_rtos,_rtos_handler,_set_video .global _VERSION,_DATE .text @@ -38,17 +38,15 @@ Start: jmp _dbug // 40 - 6 jmp _event_aes // 46 - 7 jmp _disassemble_pc // 52 - 8 -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) jmp _init_rtos // 58 - 9 #else rts nop nop -#endif +#endif /* defined(COLDFIRE) && defined(LWIP) */ jmp _set_video // 64 - 10 - rts // 70 - 11 - nop - nop + jmp _init_after_autofolder // 70 - 11 rts // 76 - 12 nop nop diff --git a/flash.tos/drivers/history.txt b/flash.tos/drivers/history.txt index 92ac405..2d91e0e 100644 --- a/flash.tos/drivers/history.txt +++ b/flash.tos/drivers/history.txt @@ -670,7 +670,7 @@ Added another boot menu and rescue features on the Fireebee target: 2011 July - 1.01 ---------------- Coldfire targets: -- Rewrited in native code vr_trn_fm (blit.S). +- Rewrited in native code of the fVDI function vr_trnfm (blit.S). - Added CF instructions to the 68K disassembler. Now pulse, tfp, wddata, wdebug, intouch, halt, mvs, mvz, mov3q, movec, sat and all mac group are supported. @@ -679,7 +679,7 @@ started, so the previous malloc from TOS (PCI BIOS structure) was dead, and bug and play crashed under MiNT. - Fixed VDI function v_show_c without graphic card (detvdi.S). - Increased BDOS buffers limits (fsbuf.c). -- Added Pexec patch for Pure C programs bdos\rwa.S): +- Added Pexec patch for Pure C programs (bdos\rwa.S): * Some case for Line A 0xA000 replaced by opcode 0xA920. * move.b DX,-(SP) replaced by opcode 0xA910-0xA917. * move.b (SP)+,DX replaced by opcode 0xA918-0xA91F. @@ -692,3 +692,50 @@ dead, and bug and play crashed under MiNT. * move.b (SP)+,abs.l replaced by opcode 0xA9F9. * mulu/s.l ea,dh:dl replaced by opcode 0xABC0-0xABFF. * divu/s.l ea:dr:dq replaced by opcode 0xAFC0-0xAFFF. + +2011 August +----------- +Fixed offscreen_free (offscreen.c). +Fixed port 5 change on USB EHCI controller (ehci-hcd.c). +Added alert message from USB (init.c, usb.c, usb_storage.c). +On Coldfire V4e targets, added 'DMAC' cookie for external usage of the +DMA. +AC97 driver started again a 2nd time (2nd warn reset) if there are an +error. +Added MiNT patch for his TOS < 2.0 IKBD interrupt routine for get +compatibility with TOS 4.04 for USB2 using Kbdvbase()[-1] (detxbios.S); +On the Firebee target and TOS started from 'TOS404 for MiNT' boot menu +entry, the FEC driver is stopped and his task killed when 'MiNT' +cookie detected (lwip/init.c). + +2011 November +------------- +Added SCSI cd driver for boot with Extendos CD-backups (scsi +directory) and ISO9660 cd driver for restore features with a popup +menu during boot when a CD/DVD is found (cd directory). +Added LZMA encoder for a better compression (tools directory). + +2011 December +------------- +Firebee target: +- Added 'PEXE' cookie, this value is a pointer who use a basepage as +parameter on stack for try to patch Pure C program with an external +OS. + +2012 February +------------- +Added FreeRTOS on CT60/CTPCI target: +- USB HUB task. +- Ethernet PCI interrupt task (via CPX setting and flash CTPCI parameter). + +2012 March +---------- +CT60/CTPCI target: +- MagiC USB drivers enabled (Mouse / Keyboard / Mass Storage). +- Added LwIP / gluestick support for TOS (IP via CPX setting and flash CTPCI parameter). + +2012 May +-------- +Telnetd fixes, added on CT60/CTPCI target. + + diff --git a/flash.tos/drivers/include/config.h b/flash.tos/drivers/include/config.h index 391e448..d4ff262 100644 --- a/flash.tos/drivers/include/config.h +++ b/flash.tos/drivers/include/config.h @@ -10,32 +10,31 @@ /* PCI XBIOS */ #undef PCI_XBIOS /* faster by cookie */ -/* NETWORK */ #ifdef COLDFIRE -#define NETWORK + +/* NETWORK */ +#define LWIP #define ETHERNET_PORT 0 /* FEC channel */ -#undef TEST_NETWORK #undef DEBUG_PRINT -#define LWIP #define WEB_LIGHT #undef FTP_SERVER #define ERRNO #define MCD_PROGQUERY #undef MCD_DEBUG -#ifdef MCF5445X /* target untested */ -#ifndef LWIP -#undef NETWORK /* to do */ -#endif /* LWIP */ -#endif /* MCF5445X */ - -/* XBIOS */ -#define TOS_ATARI_LOGO /* defined for use TOS4.04 logo */ - /* BDOS */ #define NEWCODE + +#else /* !COLDFIRE */ + +#define LWIP +#define FREERTOS + #endif /* COLDFIRE */ +/* XBIOS */ +#define TOS_ATARI_LOGO /* defined for use TOS4.04 logo */ + /* fVDI */ #define FVDI_STRUCT_2006 @@ -43,7 +42,7 @@ #define PATCH_NVDI /* VDI */ -#undef TOS_TABLES /* defined for use TOS4.04 index tables */ +#define TOS_TABLES /* defined for use TOS4.04 index tables */ /* X86 emulator */ #undef DEBUG_X86EMU @@ -53,7 +52,9 @@ /* Radeon */ #define DEFAULT_MONITOR_LAYOUT "" +#ifndef MCF547X #define ATI_LOGO +#endif #define CONFIG_FB_RADEON_I2C #define CONFIG_FB_MODE_HELPERS #undef RADEON_TILING /* normally faster but tile 16 x 16 is not compatible with accel.c read_pixel, blit/expand_area and writes on screen frame buffer */ @@ -88,24 +89,41 @@ /* USB */ #undef USB_DEVICE /* Coldfire USB device */ -#define USB_BUFFER_SIZE 0x10000 +#define USB_BUFFER_SIZE 0x80000 +#ifndef COLDFIRE +#undef USE_RADEON_MEMORY +#endif #define CONFIG_USB_OHCI /* PCI USB 1.1 */ #define CONFIG_USB_EHCI /* PCI USB 2.0 */ #undef CONFIG_EHCI_DCACHE #define CONFIG_SYS_OHCI_SWAP_REG_ACCESS -#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 15 -#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 15 +#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 5 +#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 5 #if defined(COLDFIRE) && !defined(MCF547X) -#undef CONFIG_USB_INTERRUPT_POLLING +#undef CONFIG_USB_INTERRUPT_POLLING /* M5484LITE */ +#else +#ifdef COLDFIRE +#define CONFIG_USB_INTERRUPT_POLLING /* FIREBEE */ #else -#define CONFIG_USB_INTERRUPT_POLLING +#undef CONFIG_USB_INTERRUPT_POLLING /* CT60 */ #endif /* COLDFIRE */ +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ #undef CONFIG_LEGACY_USB_INIT_SEQ #define CONFIG_USB_KEYBOARD #define CONFIG_USB_MOUSE #define CONFIG_USB_STORAGE #ifdef COLDFIRE #define CONFIG_USB_MEM_NO_CACHE +#if (defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(LWIP) +#define USB_POLL_HUB /* HUB task */ +#endif +#else /* !COLDFIRE */ +#if defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifndef FREERTOS +#define FREERTOS /* for HUB task */ +#endif /* defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ +#define USB_POLL_HUB /* HUB task */ +#endif #endif /* COLDFIRE */ #endif /* _CONFIG_H_ */ diff --git a/flash.tos/drivers/include/ct60.h b/flash.tos/drivers/include/ct60.h index c4ea620..d01885e 100644 --- a/flash.tos/drivers/include/ct60.h +++ b/flash.tos/drivers/include/ct60.h @@ -108,7 +108,7 @@ typedef struct screeninfo long max_y; /* max. possible heigth */ long refresh; /* refresh in Hz */ long pixclock; /* pixel clock in pS */ -}SCREENINFO; +} SCREENINFO; #define BLK_ERR 0 #define BLK_OK 1 @@ -230,12 +230,13 @@ typedef struct _scrclipblk #define CT60_SAVE_NVRAM_2 8 #define CT60_SAVE_NVRAM_3 9 #define CT60_PARAM_OFFSET_TLV 10 -#define CT60_MAC_ADDRESS 10 -#define CT60_SERIAL_SPEED 11 +#define CT60_MAC_ADDRESS 10 /* Firebee */ +#define CT60_IP_ADDRESS2 11 +#define CT60_SERIAL_SPEED 11 /* Firebee */ #define CT60_USER_DIV_CLOCK 12 -#define CT60_IP_ADDRESS 12 +#define CT60_IP_ADDRESS 12 /* Firebee */ #define CT60_CLOCK 13 -#define CT60_SERVER_IP_ADDRESS 13 +#define CT60_SERVER_IP_ADDRESS 13 /* Firebee */ #define CT60_PARAM_CTPCI 14 /* 15 is reserved - do not use */ @@ -247,6 +248,8 @@ typedef struct unsigned short speed_fan; unsigned long cpu_frequency; /* in MHz * 10 */ unsigned short beep; + unsigned short timeblank; + char *error_msg; } CT60_COOKIE; #define ct60_read_core_temperature(type_deg) (long)trap_14_ww((short)(0xc60a),(short)(type_deg)) diff --git a/flash.tos/drivers/bdos/gemerror.h b/flash.tos/drivers/include/gemerror.h similarity index 100% rename from flash.tos/drivers/bdos/gemerror.h rename to flash.tos/drivers/include/gemerror.h diff --git a/flash.tos/drivers/include/pcixbios.h b/flash.tos/drivers/include/pcixbios.h index 57c6f29..75d9f16 100644 --- a/flash.tos/drivers/include/pcixbios.h +++ b/flash.tos/drivers/include/pcixbios.h @@ -1,5 +1,5 @@ /* TOS 4.04 Xbios PCI for the CT60 board -* Didier Mequignon 2005, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2005-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -64,6 +64,24 @@ #define PVPDAD 0x4E /* PCI Vital Product Data Address */ #define PVPDATA 0x50 /* PCI VPD Data */ +/* Header type 1 (PCI-to-PCI bridges) */ +#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ +#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ +#define PCI_SUBORDINATE_BUS 0x1A /* Highest bus number behind the bridge */ +#define PCI_SEC_LATENCY_TIMER 0x1B /* Latency timer for secondary interface */ +#define PCI_IO_BASE 0x1C /* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1D +#define PCI_SEC_STATUS 0x1E /* Secondary status register, only bit 14 used */ +#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ +#define PCI_PREF_MEMORY_LIMIT 0x26 +#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ +#define PCI_PREF_LIMIT_UPPER32 0x2C +#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ +#define PCI_IO_LIMIT_UPPER16 0x32 +#define PCI_BRIDGE_CONTROL 0x3E /* Bridge Control */ + typedef struct { unsigned long *subcookie; @@ -193,9 +211,9 @@ __extension__ \ short _c = (short) (c); \ \ __asm__ volatile ( \ - "movl %4,sp@-\n\t" \ + "movw %4,sp@-\n\t" \ "movw %3,sp@-\n\t" \ - "movw %2,sp@-\n\t" \ + "movl %2,sp@-\n\t" \ "movw %1,sp@-\n\t" \ "trap #14\n\t" \ "lea sp@(10),sp" \ @@ -273,8 +291,8 @@ __extension__ \ #define get_card_used(handle,callback) (long)trap_14_wll((short)(317),(long)(handle),(long *)(address)) #define set_card_used(handle,callback) (long)trap_14_wll((short)(318),(long)(handle),(long *)(callback)) #define read_mem_byte(handle,offset,address) (long)trap_14_wlll((short)(319),(long)(handle),(unsigned long)(offset),(unsigned char *)(address)) -#define read_mem_word(handle,offset,address) (long)trap_14_wlll((short)(320),(unsigned long)(offset),(unsigned short *)(address)) -#define read_mem_longword(handle,offset,address) (long)trap_14_wlll((short)(321),(unsigned long)(offset),(unsigned long *)(address)) +#define read_mem_word(handle,offset,address) (long)trap_14_wlll((short)(320),(long)(handle),(unsigned long)(offset),(unsigned short *)(address)) +#define read_mem_longword(handle,offset,address) (long)trap_14_wlll((short)(321),(long)(handle),(unsigned long)(offset),(unsigned long *)(address)) #define fast_read_mem_byte(handle,offset) (unsigned char)trap_14_wll((short)(322),(long)(handle),(unsigned long)(offset)) #define fast_read_mem_word(handle,offset) (unsigned short)trap_14_wll((short)(323),(long)(handle),(unsigned long)(offset)) #define fast_read_mem_longword(handle,offset) (unsigned long)trap_14_wll((short)(324),(long)(handle),(unsigned long)(offset)) @@ -300,6 +318,9 @@ __extension__ \ #define dma_buffoper(mode) (long)trap_14_ww((short)(351),(short)(mode)) #define read_mailbox(mailbox,pointer) (long)trap_14_wwl((short)(352),(short)(mailbox),(unsigned long *)(pointer)) #define write_mailbox(mailbox,data) (long)trap_14_wwl((short)(353),(short)(mailbox),(unsigned long)(data)) +#define dma_alloc(size) (long)trap_14_wl((short)(354),(unsigned long)(size)) +#define dma_free(addr) (long)trap_14_wl((short)(355),(unsigned long)(addr)) +#define dma_lock(mode) (long)trap_14_ww((short)(356),(short)(mode)) extern long Find_pci_device(unsigned long id, unsigned short index); extern long Find_pci_classcode(unsigned long class, unsigned short index); diff --git a/flash.tos/drivers/include/scsidrv/scsi.h b/flash.tos/drivers/include/scsidrv/scsi.h new file mode 100644 index 0000000..6d26e4d --- /dev/null +++ b/flash.tos/drivers/include/scsidrv/scsi.h @@ -0,0 +1,274 @@ +#ifndef __SCSI_H +#define __SCSI_H + +#include "scsidrv/scsidefs.h" + +#define DIRECTACCESSDEV 0 +#define SEQACCESSDEV 1 +#define PRINTERDEV 2 +#define PROCESSORDEV 3 +#define WORMDEV 4 +#define ROMDEV 5 +#define SCANNERDEF 6 +#define OPTICALMEMDEV 7 +#define MEDIUMCHNGDEV 8 +#define COMMDEV 9 +#define GRAPHDEV1 10 +#define GRAPHDEV2 11 +#define UNKNOWNDEV 31 + +/* SCSI opcodes */ +/* Commands (CDB's here are 6-bytes) */ +#define TEST_UNIT_READY 0x00 +#define REZERO_UNIT 0x01 +#define REQUEST_SENSE 0x03 +#define FORMAT_UNIT 0x04 +#define READ_BLOCK_LIMITS 0x05 +#define REASSIGN_BLOCKS 0x07 +#define READ_6 0x08 +#define WRITE_6 0x0a +#define SEEK_6 0x0b +#define READ_REVERSE 0x0f +#define WRITE_FILEMARKS 0x10 +#define SPACE 0x11 +#define INQUIRY 0x12 +#define RECOVER_BUFFERED_DATA 0x14 +#define MODE_SELECT 0x15 +#define RESERVE 0x16 +#define RELEASE 0x17 +#define COPY 0x18 +#define ERASE 0x19 +#define MODE_SENSE 0x1a +#define START_STOP 0x1b +#define RECEIVE_DIAGNOSTIC 0x1c +#define SEND_DIAGNOSTIC 0x1d +#define ALLOW_MEDIUM_REMOVAL 0x1e +/* Group 2 Commands (CDB's here are 10-bytes) */ +#define SET_WINDOW 0x24 +#define READ_CAPACITY 0x25 +#define READ_10 0x28 +#define WRITE_10 0x2a +#define SEEK_10 0x2b +#define WRITE_VERIFY 0x2e +#define VERIFY 0x2f +#define SEARCH_HIGH 0x30 +#define SEARCH_EQUAL 0x31 +#define SEARCH_LOW 0x32 +#define SET_LIMITS 0x33 +#define PRE_FETCH 0x34 +#define READ_POSITION 0x34 +#define SYNCHRONIZE_CACHE 0x35 +#define LOCK_UNLOCK_CACHE 0x36 +#define READ_DEFECT_DATA 0x37 +#define MEDIUM_SCAN 0x38 +#define COMPARE 0x39 +#define COPY_VERIFY 0x3a +#define WRITE_BUFFER 0x3b +#define READ_BUFFER 0x3c +#define UPDATE_BLOCK 0x3d +#define READ_LONG 0x3e +#define WRITE_LONG 0x3f +#define CHANGE_DEFINITION 0x40 +#define WRITE_SAME 0x41 +#define READ_SUBCHANNEL 0x42 +#define READ_TOC 0x43 +#define READ_HEADER 0x44 +#define PLAY_AUDIO_10 0x45 +#define GET_CONFIGURATION 0x46 +#define PLAY_AUDIO_MSF 0x47 +#define PLAY_AUDIO_TI 0x48 +#define PLAY_TRACK_REL_10 0x49 +#define GET_EVENT_STATUS 0x4a +#define PAUSE_RESUME 0x4b +#define LOG_SELECT 0x4c +#define LOG_SENSE 0x4d +#define READ_DISK_INFO 0x51 +#define READ_TRACK_INFO 0x52 +#define MODE_SELECT_10 0x55 +#define MODE_SENSE_10 0x5a +/* Group 5 Commands (CDB's here are 12-bytes) */ +#define PLAY_AUDIO_12 0xa5 +#define LOAD_UNLOAD 0xa6 +#define READ_12 0xa8 +#define TRACK_REL_12 0xa9 +#define WRITE_12 0xaa +#define READ_DVD_STRUCTURE 0xad +#define WRITE_VERIFY_12 0xae +#define SEARCH_HIGH_12 0xb0 +#define SEARCH_EQUAL_12 0xb1 +#define SEARCH_LOW_12 0xb2 +#define SEND_VOLUME_TAG 0xb6 +#define READ_MSF 0xb9 +#define SET_SPEED 0xbb +#define READ_CD 0xbe + +typedef struct +{ + unsigned char Device; + unsigned char Qualifier; + unsigned char Version; + unsigned char Format; + unsigned char AddLen; + unsigned char Res1; + unsigned short Res2; + char Vendor[8]; + char Product[16]; + char Revision[4]; +} tInqData; + +typedef struct +{ + char CDP0DRes2; + char InactTMul; /* unteres Nibble */ + unsigned short SperMSF; + unsigned short FperMSF; +} tCDPage0D; + +typedef struct +{ + unsigned char ImmedFlags; + char CD0ERes3; + char CD0ERes4; + unsigned char LBAFlags; + unsigned short BlocksPerSecond; + unsigned char Port0Channel; + unsigned char Port0Volume; + unsigned char Port1Channel; + unsigned char Port1Volume; + unsigned char Port2Channel; + unsigned char Port2Volume; + unsigned char Port3Channel; + unsigned char Port3Volume; +} tCDPage0E; + +typedef struct +{ + char ModeLength; + char MediumType; + unsigned char DeviceSpecs; + char BlockDescLen; +} tParmHead; + +typedef struct +{ + unsigned long Blocks; /* Byte HH = DensityCode */ + unsigned long BlockLen; /* Byte HH = Reserved */ +} tBlockDesc; + +typedef union +{ + tCDPage0D CDP0D; + tCDPage0E CDP0E; +} tPage; + +typedef struct +{ + tParmHead ParmHead; + tBlockDesc BlockDesc; + tPage Page; +} tModePage; + +typedef union +{ + struct + { + char Resrvd; + char M; + char S; + char F; + } s; + unsigned long longval; +} tMSF; + +#define MAXTOC 100 +typedef struct +{ + char Res0; + unsigned char ADRControl; + unsigned char TrackNo; + char Res3; + tMSF AbsAddress; +} tTOCEntry; + +typedef struct +{ + unsigned short TOCLen; + unsigned char FirstTrack; + unsigned char LastTrack; +} tTOCHead; + +typedef struct +{ + tTOCHead Head; + tTOCEntry Entry[MAXTOC]; +} tTOC; + +typedef struct +{ + unsigned char Command; + char LunAdr; + unsigned short Adr; + unsigned char Len; + char Flags; +} tCmd6; + +typedef struct +{ + unsigned char Command; + char Lun; + unsigned long Adr; + char Reserved; + unsigned char LenHigh; + unsigned char LenLow; + char Flags; +} tCmd10; + +typedef struct +{ + unsigned char Command; + char Lun; + unsigned long Adr; + unsigned long Len; + char Reserved; + char Flags; +} tCmd12; + +void Wait(unsigned long Ticks); +void SetBlockSize(unsigned long NewLen); +unsigned long GetBlockSize(); +void SetScsiUnit(tHandle handle, short Lun, unsigned long MaxLen); +void SetCmd6(tCmd6 *Cmd, unsigned short Opcode, unsigned long BlockAdr, unsigned short TransferLen); +void SetCmd10(tCmd10 *Cmd, unsigned short Opcode, unsigned long BlockAdr, unsigned short TransferLen); +void SetCmd12(tCmd12 *Cmd, unsigned short Opcode, unsigned long BlockAdr, unsigned long TransferLen); +tpSCSICmd SetCmd(char *Cmd, short CmdLen, void *Buffer, unsigned long Len, unsigned long TimeOut); +long TestUnitReady(void); +long Inquiry(void *data, int Vital, unsigned short VitalPage, short length); + #define MODESEL_SMP 0x01 /* Save Mode Parameters */ + #define MODESEL_PF 0x10 /* Page Format */ +long ModeSelect(unsigned short SelectFlags, void *Buffer, unsigned short ParmLen); +long ModeSelect6(unsigned short SelectFlags, void *Buffer, unsigned short ParmLen); +long ModeSelect10(unsigned short SelectFlags, void *Buffer, unsigned short ParmLen); + #define MODESENSE_CURVAL 0 /* current values */ + #define MODESENSE_CHANGVAL 1 /* changeable values */ + #define MODESENSE_DEFVAL 2 /* default values */ + #define MODESENSE_SAVEDVAL 3 /* save values */ +long ModeSense(unsigned short PageCode, unsigned short SubPageCode, unsigned short PageControl, void *Buffer, unsigned short ParmLen); +long ModeSense6(unsigned short PageCode, unsigned short SubPageCode, unsigned short PageControl, void *Buffer, unsigned short ParmLen); +long ModeSense10(unsigned short PageCode, unsigned short SubPageCode, unsigned short PageControl, void *Buffer, unsigned short ParmLen); +long PreventMediaRemoval(int Prevent); +long Read6(unsigned long BlockAdr, unsigned short TransferLen, void *buffer); +long Read10(unsigned long BlockAdr, unsigned short TransferLen, void *buffer); +long Write6(unsigned long BlockAdr, unsigned short TransferLen, void *buffer); +long Write10(unsigned long BlockAdr, unsigned short TransferLen, void *buffer); +long Read(unsigned long BlockAdr, unsigned short TransferLen, void *buffer); +long Write(unsigned long BlockAdr, unsigned short TransferLen, void *buffer); +long StartStop(int LoadEject, int StartFlag); +long ReadCapacity(int PMI, unsigned long *BlockAdr, unsigned long *BlockLen); +long GetConfiguration(int RT, unsigned short StartFeature, void *Buffer, unsigned short Len); +long ReadTOC(int MSF, int Format, unsigned short StartTrack, void *Buffer, unsigned short Len); +long ReadDVDStucture(unsigned long Address, unsigned short LayerNumber, unsigned short Format, int AGID, void *Buffer, unsigned short Len); +long ReadDiskInfo(void *Buffer, unsigned short Len); +long ReadTrackInfo(int AddressNumberType, unsigned long BlockAdr, void *Buffer, unsigned short Len); + +#endif + diff --git a/flash.tos/drivers/include/scsidrv/scsidefs.h b/flash.tos/drivers/include/scsidrv/scsidefs.h new file mode 100644 index 0000000..0cc772a --- /dev/null +++ b/flash.tos/drivers/include/scsidrv/scsidefs.h @@ -0,0 +1,338 @@ +#ifndef __SCSIDEFS_H +#define __SCSIDEFS_H + +#define SCSIRevision 0x0101 /* Version 1.01 */ + +#define MAXBUSNO 31 + +#define NOSCSIERROR 0L +#define SELECTERROR -1L +#define STATUSERROR -2L +#define PHASEERROR -3L +#define BSYERROR -4L +#define BUSERROR -5L +#define TRANSERROR -6L +#define FREEERROR -7L +#define TIMEOUTERROR -8L +#define DATATOOLONG -9L +#define LINKERROR -10L +#define TIMEOUTARBIT -11L +#define PENDINGERROR -12L +#define PARITYERROR -13L + +#define w2mot(A) (A) +#define l2mot(A) (A) + +typedef struct +{ + unsigned long hi; + unsigned long lo; +} DLONG; + + +typedef struct{ + unsigned long BusIds; + char resrvd[28]; +} tPrivate; + +typedef short *tHandle; + +typedef struct +{ + tHandle Handle; + char *Cmd; + unsigned short CmdLen; + void *Buffer; + unsigned long TransferLen; + char *SenseBuffer; + unsigned long Timeout; /* Timeout in 1/200 sec */ + #define Disconnect 0x10 + unsigned short Flags; +} tSCSICmd; + +typedef tSCSICmd *tpSCSICmd; + +typedef struct +{ + tPrivate Private; + char BusName[20]; /* 'SCSI', 'ACSI', 'PAK-SCSI' */ + unsigned short BusNo; + #define cArbit 0x01 + #define cAllCmds 0x02 + #define cTargCtrl 0x04 + #define cTarget 0x08 + #define cCanDisconnect 0x10 + #define cScatterGather 0x20 + unsigned short Features; + unsigned long MaxLen; +}tBusInfo; + +typedef struct +{ + char Private[32]; + DLONG SCSIId; +} tDevInfo; + +typedef struct ttargethandler +{ + struct ttargethandler *next; + int (*TSel)(short bus, unsigned short CSB, unsigned short CSD); + int (*TCmd)(short bus, char *Cmd); + unsigned short(*TCmdLen)(short bus, unsigned short Cmd); + void (*TReset) (unsigned short bus); + void (*TEOP) (unsigned short bus); + void (*TPErr)(unsigned short bus); + void (*TPMism)(unsigned short bus); + void (*TBLoss)(unsigned short bus); + void (*TUnknownInt)(unsigned short bus); +} tTargetHandler; + +typedef tTargetHandler *tpTargetHandler; + +typedef char tReqData[18]; + +typedef struct +{ + unsigned short Version; /* Revision in BCD: $0100 = 1.00 */ + long (*In)(tpSCSICmd Parms); + long (*Out)(tpSCSICmd Parms); + #define cInqFirst 0 + #define cInqNext 1 + long (*InquireSCSI)(short what, tBusInfo *Info); + long (*InquireBus)(short what, short BusNo, tDevInfo *Dev); + long (*CheckDev)(short BusNo, const DLONG *SCSIId, char *Name, unsigned short *Features); + long (*RescanBus)(short BusNo); + long (*Open)(short BusNo, const DLONG *SCSIId, unsigned long *MaxLen); + long (*Close)(tHandle handle); + #define cErrRead 0 + #define cErrWrite 1 + #define cErrMediach 0 + #define cErrReset 1 + long (*Error)(tHandle handle, short rwflag, short ErrNo); + long (*Install)(short bus, tpTargetHandler Handler); + long (*Deinstall)(short bus, tpTargetHandler Handler); + long (*GetCmd)(short bus, char *Cmd); + long (*SendData)(short bus, char *Buffer, unsigned long Len); + long (*GetData)(short bus, void *Buffer, unsigned long Len); + long (*SendStatus)(short bus, unsigned short Status); + long (*SendMsg)(short bus, unsigned short Msg); + long (*GetMsg)(short bus, unsigned short *Msg); + tReqData *ReqData; +} tScsiCall; + +typedef tScsiCall *tpScsiCall; + +#define DefTimeout 4000 + +#ifndef OSBIND_CLOBBER_LIST +#define OSBIND_CLOBBER_LIST "d0", "d1", "d2", "a0", "a1", "a2", "memory" +#endif + +#define init_scsiio() \ +do { \ + struct { \ + long cktag; \ + long ckvalue; \ + } *jar = (void *)Setexc(0x5A0 /4, (void (*)())-1); \ + scsicall = (tScsiCall *)0; \ + while(jar->cktag) { \ + if(jar->cktag == 0x53435349) { \ + scsicall = (tScsiCall *)jar->ckvalue; \ + break; \ + } \ + jar++; \ + } \ +} while(0) + +#define In(Parms) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _Parms = (long) (Parms); \ + long _fct = (long) (scsicall->In); \ + \ + __asm__ volatile ( \ + "movl %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #4,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_Parms) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define Out(Parms) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _Parms = (long) (Parms); \ + long _fct = (long) (scsicall->Out); \ + \ + __asm__ volatile ( \ + "movl %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #4,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_Parms) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define InquireSCSI(what, Info) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _what = (long) (what); \ + long _Info = (long) (Info); \ + long _fct = (long) (scsicall->InquireSCSI); \ + \ + __asm__ volatile ( \ + "movl %3,sp@-\n\t" \ + "movw %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #6,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_what), "r"(_Info) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define InquireBus(what, BusNo, Dev) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _what = (long) (what); \ + long _BusNo = (long) (BusNo); \ + long _Dev = (long) (Dev); \ + long _fct = (long) (scsicall->InquireBus); \ + \ + __asm__ volatile ( \ + "movl %4,sp@-\n\t" \ + "movw %3,sp@-\n\t" \ + "movw %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #8,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_what), "r"(_BusNo), "r"(_Dev) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define CheckDev(BusNo, SCSIId, Name, Features) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _BusNo = (long) (BusNo); \ + long _SCSIId = (long) (SCSIId); \ + long _Name = (long) (Name); \ + long _Features = (long) (Name); \ + long _fct = (long) (scsicall->CheckDev); \ + \ + __asm__ volatile ( \ + "movl %5,sp@-\n\t" \ + "movl %4,sp@-\n\t" \ + "movl %3,sp@-\n\t" \ + "movw %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "lea sp@(14),sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_BusNo), "r"(_SCSIId), "r"(_Name), "r"(_Features) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define RescanBus(BusNo) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _BusNo = (long) (BusNo); \ + long _fct = (long) (scsicall->RescanBus); \ + \ + __asm__ volatile ( \ + "movw %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #2,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_BusNo) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define Open(bus, SCSIId, MaxLen) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _bus = (long) (bus); \ + long _SCSIId = (long) (SCSIId); \ + long _MaxLen = (long) (MaxLen); \ + long _fct = (long) (scsicall->Open); \ + \ + __asm__ volatile ( \ + "movl %4,sp@-\n\t" \ + "movl %3,sp@-\n\t" \ + "movw %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "lea sp@(10),sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_bus), "r"(_SCSIId), "r"(_MaxLen) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define Close(handle) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _handle = (long) (handle); \ + long _fct = (long) (scsicall->Close); \ + \ + __asm__ volatile ( \ + "movl %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #4,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_handle) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#define Error(handle, rwflag, ErrNo) \ +__extension__ \ +({ \ + register long retvalue __asm__("d0"); \ + long _handle = (long) (handle); \ + long _rwflag = (long) (rwflag); \ + long _ErrNo = (long) (ErrNo); \ + long _fct = (long) (scsicall->Error); \ + \ + __asm__ volatile ( \ + "movw %4,sp@-\n\t" \ + "movw %3,sp@-\n\t" \ + "movl %2,sp@-\n\t" \ + "movl %1,a0\n\t" \ + "jsr a0@\n\t" \ + "addql #8,sp" \ + : "=r"(retvalue) \ + : "r"(_fct), "r"(_handle), "r"(_rwflag), "r"(_ErrNo) \ + : OSBIND_CLOBBER_LIST \ + ); \ + retvalue; \ +}) + +#endif diff --git a/flash.tos/drivers/include/version.h b/flash.tos/drivers/include/version.h index f829066..175cbec 100644 --- a/flash.tos/drivers/include/version.h +++ b/flash.tos/drivers/include/version.h @@ -1,3 +1,3 @@ -#define VERSION 0x0101 +#define VERSION 0x0102 #define DATE \ -21, 7,2011,21, 1 + 2, 7,2012, 9,52 diff --git a/flash.tos/drivers/init.c b/flash.tos/drivers/init.c index 3d41585..92a0408 100644 --- a/flash.tos/drivers/init.c +++ b/flash.tos/drivers/init.c @@ -1,5 +1,5 @@ /* TOS 4.04 PCI init for the CT60/CTPCI & Coldfire boards - * Didier Mequignon 2005-2011, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2005-2012, e-mail: aniplay@wanadoo.fr * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,13 @@ #include #include #include +#ifndef hdv_bpb +#define hdv_bpb (((void (**)()) 0x472L)) +#define hdv_rw (((void (**)()) 0x476)) +#define hdv_mediach (((void (**)()) 0x47E)) +#endif #include +#include /* for malloc */ #include "driver.h" /* fVDI */ #include "fb.h" #include "radeon/radeonfb.h" @@ -30,11 +36,22 @@ #include "m68k_disasm.h" #include "ct60.h" #include "vidix.h" +#if defined(LWIP) || defined(FREERTOS) +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "freertos/queue.h" +#ifdef FREERTOS +long save_stack; +long save_regs[16]; +#endif +#endif -// #define BETA_VERSION "beta 8" +#define BETA_VERSION "beta 11" #undef DEBUG +#define CTPCI_1M 0x00000002 + #ifndef Vsetscreen #ifdef VsetScreen #define Vsetscreen VsetScreen @@ -51,17 +68,14 @@ #endif #endif -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern void board_printf(const char *fmt, ...); #else -#define board_printf kprint extern void kprint(const char *fmt, ...); #endif extern int sprintD(char *s, const char *fmt, ...); -#ifdef NETWORK - -// #define TEST_NETWORK +#if defined(COLDFIRE) && defined(LWIP) #define uint8 unsigned char #define uint16 unsigned short @@ -89,23 +103,29 @@ extern long install_ram_disk(void); extern long check_sd_card(void); extern long install_sd_card(void); #endif -extern void init_dma(void); extern int init_network(void); -#ifndef LWIP -extern void end_network(void); -#endif -extern int alert_tos(char *string); extern void init_dma_transfer(void); extern void minus(char *s); extern int InitSound(long gsxb); unsigned long write_protect_ram_disk; -#endif /* NETWORK */ +#endif /* defined(COLDFIRE) && defined(LWIP) */ + +#if defined(LWIP) || defined(FREERTOS) +extern short form_alert(short fo_adefbttn, char *fo_astring); +#endif +extern int drivers_mem_init(void); extern void init_resolution(long modecode); extern long find_best_mode(long modecode); extern const struct fb_videomode *get_db_from_modecode(long modecode); +extern int cd_disk_boot(void); +extern void install_magic_routine(void); +#ifndef COLDFIRE +extern long get_no_cache_memory(void); +extern long get_no_cache_memory_size(void); +#endif typedef struct { @@ -141,7 +161,6 @@ typedef struct } XBRA; extern void ltoa(char *buf, long n, unsigned long base); - extern Virtual *init_var_fvdi(void); extern void det_xbios(void); extern void det_linea(void); @@ -158,6 +177,13 @@ extern void display_ati_logo(void); #if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_INTERRUPT_POLLING) extern void install_vbl_timer(void *func, int remove); #endif +#if !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) +int rtl8139_eth_start(long handle, const struct pci_device_id *ent); +void init_lwip(unsigned long ip_addr, unsigned long mask_addr, unsigned long gateway_addr); +int init_network(void); +#endif +extern void trace_tos(void); +void empty(void) {} /* global */ extern unsigned short VERSION[]; @@ -166,6 +192,9 @@ extern long second_screen; extern struct mode_option resolution; extern short accel_s, accel_c; COOKIE vidix; +#ifdef COLDFIRE +COOKIE bdos_pexec; +#endif extern char monitor_layout[]; extern short default_dynclk; extern short ignore_edid; @@ -177,30 +206,39 @@ extern struct pci_device_id radeonfb_pci_table[]; /* radeon_base.c */ extern struct pci_device_id lynxfb_pci_table[]; /* smi_base.c */ extern struct pci_device_id ohci_usb_pci_table[]; /* ohci-hcd.c */ extern struct pci_device_id ehci_usb_pci_table[]; /* ehci-hcd.c */ +#if !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) +extern struct pci_device_id rtl8139_eth_pci_table[]; /* rtl8139.c */ +#endif extern Access *access; /* fVDI */ Access _access_; /* fVDI */ extern struct fb_info *info_fvdi; extern long blocks,block_size; extern long fix_modecode; Virtual *base_vwk; -long old_vector_xbios,old_vector_linea,old_vector_vdi; -short video_found, usb_found, ata_found; +long old_vector_xbios,old_vector_gemdos,old_vector_linea,old_vector_vdi; +short video_found, usb_found, ethernet_found; +#ifdef USE_RADEON_MEMORY +short lock_video; +#endif short use_dma, restart, redirect, os_magic, memory_ok, drive_ok, video_log, swi; -#if defined(COLDFIRE) && defined(MCF547X) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(MCF547X) && defined(LWIP) short boot_os; #endif NVM nvm; +short key_init_with_sdram; COOKIE eddi; void (**mousevec)(void *); _IOREC *iorec; void (**ikbdvec)(); unsigned char **keytbl; long debug_traps[16]; -extern void trace_tos(void); m68k_word *old_address; +#ifndef COLDFIRE +unsigned long hardware_flags; +void (*magic_timer_c_routine)(); +#endif extern unsigned char _bss_start[]; extern unsigned char _end[]; -void empty(void) {} #ifndef COLDFIRE static char mess_ignore[] = @@ -251,7 +289,7 @@ long boot_alloc(long size) /* without free */ #ifdef COLDFIRE long ret; #else /* !COLDFIRE */ - if((os_magic == 1) && !memory_ok) + if(os_magic && !memory_ok) { long ret = *_membot; #endif /* COLDFIRE */ @@ -292,13 +330,41 @@ long install_xbra(short vector, void *handler) #else /* 68060 */ asm volatile (" cpusha BC\n\t"); #endif /* COLDFIRE */ - xbra->old_address = (long)Setexc(vector,(void(*)())&xbra->jump[0]); + xbra->old_address = (long)Setexc(vector, (void(*)())&xbra->jump[0]); return(xbra->old_address); } return(0); } -#ifdef NETWORK +#if 0 +void uninstall_xbra(void **vector, long ident) +{ + XBRA *previous_xbra = NULL; + XBRA *xbra = (XBRA *)((long)*vector - 12); + while((xbra != NULL) && (xbra->xbra == 'XBRA')) + { + + board_printf("XBRA %c%c%c%c %08X %08X\r\n", (xbra->ident >> 24) & 255, (xbra->ident >> 16) & 255, (xbra->ident >> 8) & 255, (xbra->ident >> 0) & 255, + (long)xbra + 12, xbra->old_address); + + if(xbra->ident == ident) + { + if(previous_xbra == NULL) + *vector = (void *)xbra->old_address; + else + previous_xbra->old_address = xbra->old_address; + break; + } + previous_xbra = xbra; + if(xbra->old_address) + xbra = (XBRA *)(xbra->old_address - 12); + else + xbra = NULL; + } +} +#endif + +#if defined(COLDFIRE) && defined(LWIP) int tftp_load_file(int drive, char *name, char *path_server, IP_ADDR server, long free, long *size) { @@ -419,7 +485,7 @@ int tftp_write_file(int drive, char *name, char *path_server, IP_ADDR server) return(ret); } -#endif +#endif /* defined(COLDFIRE) && defined(LWIP) */ #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) #ifdef CONFIG_USB_INTERRUPT_POLLING @@ -493,16 +559,18 @@ static void wait_key(void) Crawcin(); } -#if defined(COLDFIRE) && defined(MCF547X) && defined(NETWORK) && defined(LWIP) - -int boot_menu(int index, int nb_lines, char *title, char *lines[]) +int boot_menu(int index, int nb_lines, char *title, char *lines[], int delay_sec) { #define DELAY_MENU 400 /* 2 seconds */ int i, j, end = 0; char key; long ret; unsigned long start_hz_200 = *_hz_200; - unsigned long delay_menu = (unsigned long)nvm.bootdelay * 200; + unsigned long delay_menu; + if(delay_sec > 0) + delay_menu = (unsigned long)delay_sec * 200; + else + delay_menu= (unsigned long)nvm.bootdelay * 200; if(delay_menu < DELAY_MENU) delay_menu = DELAY_MENU; Cconws(title); @@ -564,6 +632,11 @@ int boot_menu(int index, int nb_lines, char *title, char *lines[]) j = 0; break; } + if((ret == 0x61) && ((Getshift() & 0xC) == 0xC)) /* CTRL-ALT-UNDO */ + { + (void)NVMaccess(2, 0, sizeof(NVM), (void *)&nvm); /* init */ + return(index); + } } } for(i = 0; i < nb_lines; i++) @@ -576,6 +649,8 @@ int boot_menu(int index, int nb_lines, char *title, char *lines[]) } } +#if defined(COLDFIRE) && defined(MCF547X) && defined(LWIP) + void boot_os_menu(void) { static char atari[] = { 0x1B,0x62,0x34,0x41,0x1B,0x62,0x32,0x54,0x1B,0x62,0x33,0x41,0x1B,0x62,0x31,0x52,0x1B,0x62,0x35,0x49,0x20,0x1B,0x62,0x3F }; @@ -590,10 +665,10 @@ void boot_os_menu(void) if(!(swi & 0x40) || !(swi & 1)) /* !SW5 (UP) */ { if(swi & 0x80) /* SW6 (DOWN) */ - boot_os = boot_menu(0, 2, (nvm.language == 2) ? title_fr : title, menu); + boot_os = boot_menu(0, 2, (nvm.language == 2) ? title_fr : title, menu, -1); else /* SW6 (UP) */ { - boot_os = boot_menu(0, 3, (nvm.language == 2) ? title_fr : title, (nvm.language == 2) ? menu2_fr : menu2); + boot_os = boot_menu(0, 3, (nvm.language == 2) ? title_fr : title, (nvm.language == 2) ? menu2_fr : menu2, -1); if(boot_os == 2) { Cconout(27); @@ -602,7 +677,7 @@ void boot_os_menu(void) } } else /* SW5 (DOWN) */ - boot_os = boot_menu(0, 3, "Rescue boot, start with...\r\n", menu3); + boot_os = boot_menu(0, 3, "Rescue boot, start with...\r\n", menu3, -1); if(!boot_os) { Cconout(27); @@ -612,7 +687,7 @@ void boot_os_menu(void) vTaskDelay(10); /* wait a little bit than ROOT task reboot on choice */ } -#endif /* defined(COLDFIRE) && defined(MCF547X) && defined(NETWORK) && defined(LWIP) */ +#endif /* defined(COLDFIRE) && defined(MCF547X) && defined(LWIP) */ void get_mouseikbdvec(void) /* for USB drivers and HTTP server (screen view) */ { @@ -624,57 +699,153 @@ void get_mouseikbdvec(void) /* for USB drivers and HTTP server (screen view) */ keytbl = (unsigned char **)Keytbl(-1,-1,-1); } +static short init_video(short vmode) /* called by init_devices */ +{ + long ret; + extern void *write_pixel_r, *read_pixel_r, *set_colours_r, *get_colours_r, *get_colour_r; + /* fVDI spec */ + accel_s = 0; + accel_c = A_SET_PIX | A_GET_PIX | A_MOUSE | A_LINE | A_BLIT | A_FILL | A_EXPAND | A_FILLPOLY | A_TEXT | A_SET_PAL | A_GET_COL; + read_pixel_r = write_pixel_r = set_colours_r = get_colours_r = get_colour_r = empty; + if(!os_magic) + { + long screen_addr = Mxalloc(32000 + 256, 0) + 255; /* STRAM - use Mxalloc because Srealloc can be used by monochome emulation later */ + screen_addr &= ~0xFF; +#ifndef COLDFIRE + if((debug && !redirect) /* || usb_found */) + wait_key(); +#endif + ret = Vsetscreen(screen_addr, screen_addr, 2, 0); /* for reduce F030 Videl bus load */ +#ifndef COLDFIRE + Cconws(mess_ignore); +#endif + } + old_vector_xbios = install_xbra(46, det_xbios); /* TRAP #14 */ + vidix.ident = 'VIDX'; + vidix.v.l = VIDIX_VERSION; + add_cookie(&vidix); +#if 0 // #ifndef COLDFIRE + if(use_dma) + { + Cconws("\rDMA (y/n)"); + if((Cconin() & 0xFF) != 'y') + { + use_dma = 0; + Cconout(27); + Cconout('E'); + } + } +#endif + if(!vmode) + { + vmode = (short)find_best_mode((long)vmode); + if(!vmode) + vmode = PAL | VGA | COL80 | BPS16; + else + vmode |= BPS16; + } + vmode = fix_boot_modecode(vmode); + ret = Vsetscreen(0, 0, 3, vmode); /* new Vsetscreen with internal driver installed */ + if(ret); + return(vmode); +} + /* Init TOS call is here ... */ -int init_devices(int no_reset, unsigned long hardware_flags) /* after the original setscreen with the modecode from NVRAM */ +int init_devices(int no_reset, unsigned long flags) /* after the original setscreen with the modecode from NVRAM */ { -#ifdef COLDFIRE +#ifdef COLDFIRE /* use BDOS, FreeRTOS already started before the CF68KLIB */ COOKIE *p; #ifdef LWIP extern void *run; extern void *start_run; #endif extern void osinit(void); + extern void flush_cache_pexec(void); long end_used_stram = (long)Mxalloc(16, 0); memset(_bss_start, 0, (int)(_end - _bss_start)); *_membot = end_used_stram; osinit(); /* BDOS */ + bdos_pexec.ident = 'PEXE'; + bdos_pexec.v.l = (long)flush_cache_pexec; + add_cookie(&bdos_pexec); #ifdef LWIP start_run = run; /* PD for BDOS malloc */ #endif -#else /* 68060 - use GEMDOS */ - if(*((unsigned short *)0xE80000) < 0x200) /* check boot version */ +#else /* !COLDFIRE - 68060, use GEMDOS */ + /* check boot version, 0x202 for Timer D vector overwrited by the boot after init_devices and used by FreeRTOS */ + if(*((unsigned short *)0xE80000) < 0x202) return(0); - memset(_bss_start, 0, (int)(_end-_bss_start)); -#endif /* COLDFIRE */ - get_mouseikbdvec(); restart = (short)no_reset; - swi = 0; - (void)NVMaccess(0, 0, sizeof(NVM), (void *)&nvm); -#ifdef COLDFIRE - p = get_cookie('_SWI'); - if(p != NULL) - swi = (short)p->v.l; /* B7: SW6, B6: SW5, B0: BOOT from 0xE0000000 */ -#endif if(restart == 2) { + flags = hardware_flags; /* save for bss memset to 0 */ + memset(_bss_start, 0, (int)(_end-_bss_start)); +// drivers_mem_init(); + hardware_flags = flags; memory_ok = 0; /* not use M(x)alloc */ os_magic = 1; } else { + memset(_bss_start, 0, (int)(_end-_bss_start)); +// drivers_mem_init(); + hardware_flags = flags; memory_ok = 1; /* use M(x)alloc */ os_magic = 0; } +#ifdef FREERTOS + { + asm volatile( + ".global _goto_tos\n\t" + " move.l SP,_save_stack\n\t" + " movem.l D0-A6,_save_regs\n\t" + " jsr _init_rtos\n\t" /* not returns */ + "_goto_tos:\n\t" + " move.w SR,D0\n\t" + " or.w #0x700,SR\n\t" + " move.l _save_stack,D1\n\t" + " move.l SP,A1\n\t" /* new FreeRTOS TOS task stack */ + " lea 0x8870,A0\n\t" /* initial TOS 4.04 stack */ + " tst.w _os_magic\n\t" + " beq.s .copy_stack\n\t" + " move.l D1,A0\n\t" /* MagiC current stack */ + " lea 256(A0),A0\n\t" /* normally space is enough */ + ".copy_stack:\n\t" + " move.w -(A0),-(A1)\n\t" + " cmp.l D1,A0\n\t" + " bhi.s .copy_stack\n\t" + " move.l A1,SP\n\t" + " move.w D0,SR\n\t " + " movem.l _save_regs,D0-A6" ); + } +#endif /* FREERTOS */ +#endif /* COLDFIRE */ + get_mouseikbdvec(); + swi = 0; + (void)NVMaccess(0, 0, sizeof(NVM), (void *)&nvm); +#ifdef COLDFIRE + p = get_cookie('_SWI'); + if(p != NULL) + swi = (short)p->v.l; /* B7: SW6, B6: SW5, B0: BOOT from 0xE0000000 */ +#endif drive_ok = 0; redirect = 0; /* for debug to memory during boot (redirection impossible to file by GEMDOS) */ +#ifdef USE_RADEON_MEMORY + lock_video = 0; +#endif + old_vector_xbios = old_vector_gemdos = old_vector_linea = old_vector_vdi = 0; do { static char *spec_monitor_layout[] = {"CRT,NONE","CRT,CRT","CRT,TMDS","TMDS,CRT","TMDS,TMDS"}; int loop_counter = 0; +#ifdef MCF547X + int second_usb = 0; +#endif unsigned long temp; short index, vmode = 0, key = 0; - long handle, err, ret; + long handle, err; + int usb_ok = 1; struct pci_device_id *board; old_address = (m68k_word *)0xFFFFFFFF; /* dbug */ access = &_access_; @@ -684,13 +855,13 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin #else debug = 0; #endif - video_found = usb_found = ata_found = video_log = 0; + video_found = usb_found = ethernet_found = video_log = 0; /* init options Radeon */ use_dma = (short)ct60_rw_parameter(CT60_MODE_READ, CT60_PARAM_CTPCI, 0); strcpy(monitor_layout, DEFAULT_MONITOR_LAYOUT); /* CRT, TMDS, LVDS */ if(use_dma >= 0) { - int mlayout = (int)(use_dma >> 2) - 1; + int mlayout = (int)((use_dma >> 2) & 0x1F) - 1; if((mlayout >= 0) && (mlayout < 5)) strcpy(monitor_layout, spec_monitor_layout[mlayout]); use_dma = (use_dma >> 1) & 1; @@ -739,7 +910,6 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin { unsigned long id = 0; err = read_config_longword(handle, PCIIDR, &id); -#if 1 /* test Radeon ATI devices */ if((err >= 0) && !video_found && (key != 'V') && (key != 'v')) /* V => Videl use */ { @@ -756,7 +926,7 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin Cconws(mess_ignore); #endif resolution.used = 1; - init_resolution(PAL|VGA|COL80|BPS16); /* for monitor */ + init_resolution(PAL|VGA|COL80|BPS8); /* for monitor */ if(radeonfb_pci_register(handle, board) >= 0) video_found = 1; resolution.used = 0; @@ -788,58 +958,149 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin } #endif /* CONFIG_VIDEO_SMI_LYNXEM */ } -#endif /* test USB devices */ - if((err >= 0) && !os_magic && loop_counter && (usb_found < USB_MAX_BUS)) + if((err >= 0) +#if 0 // #ifdef MCF547X + && ((swi & 0x80) || (boot_os == 2)) /* SW6 (DOWN) */ +#endif +#ifndef COLDFIRE + && (hardware_flags & CTPCI_1M) +#endif + && usb_ok && (usb_found < USB_MAX_BUS)) { unsigned long class; - if(read_config_longword(handle, PCIREV, &class) >= 0 + if((read_config_longword(handle, PCIREV, &class) >= 0) && ((class >> 16) == PCI_CLASS_SERIAL_USB)) - { - if(loop_counter == 2) /* install EHCI before */ + { + switch(loop_counter) { - if((class >> 8) == PCI_CLASS_SERIAL_USB_OHCI) - { -#ifdef CONFIG_USB_OHCI - board = ohci_usb_pci_table; /* compare table */ - while(board->vendor) + case 0: +#ifdef MCF547X + if((handle & 0xFFFCFFFF) != 1) + second_usb = 1; +#endif +#if 0 // #ifndef COLDFIRE + if((usb_ok == 1) && video_found) { - if((board->vendor == (id & 0xFFFF)) - && (board->device == (id >> 16))) + Cconws("\rUSB (y/n)"); + if((Cconin() & 0xFF) != 'y') + usb_ok = 0; + else { - if(usb_init(handle, board) >= 0) - usb_found++; - break; + usb_ok = 2; +#ifdef USE_RADEON_MEMORY /* CTPCI bug fix */ + if(video_found) + { + vmode &= ~NUMCOLS; + vmode |= BPS8; /* no endian convert */ + vmode = init_video(vmode); + lock_video = 1; + } +#endif /* USE_RADEON_MEMORY */ } - board++; } +#endif /* !COLDFIRE */ + break; + case 1: +#ifdef MCF547X + if(((handle & 0xFFFCFFFF) == 1) && second_usb) + break; +#endif + if((class >> 8) == PCI_CLASS_SERIAL_USB_EHCI) + { +#ifdef CONFIG_USB_EHCI + board = ehci_usb_pci_table; /* compare table */ + while(board->vendor) + { + if((board->vendor == (id & 0xFFFF)) + && (board->device == (id >> 16))) + { + if(usb_init(handle, board) >= 0) + { +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef CONFIG_USB_INTERRUPT_POLLING + if(!usb_found) + install_vbl_timer(vbl_usb_event_poll, 0); +#endif +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ + usb_found++; + } + break; + } + board++; + } +#endif /* CONFIG_USB_EHCI */ + } + break; + case 2: /* install EHCI before */ +#ifdef MCF547X + if(((handle & 0xFFFCFFFF) == 1) && second_usb) + break; +#endif + if((class >> 8) == PCI_CLASS_SERIAL_USB_OHCI) + { +#ifdef CONFIG_USB_OHCI + board = ohci_usb_pci_table; /* compare table */ + while(board->vendor) + { + if((board->vendor == (id & 0xFFFF)) + && (board->device == (id >> 16))) + { + if(usb_init(handle, board) >= 0) + { +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef CONFIG_USB_INTERRUPT_POLLING + if(!usb_found) + install_vbl_timer(vbl_usb_event_poll, 0); +#endif +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ + usb_found++; + } + break; + } + board++; + } #endif /* CONFIG_USB_OHCI */ - } + } + break; } - else if((class >> 8) == PCI_CLASS_SERIAL_USB_EHCI) + } + } + if((err >= 0) && !os_magic && !ethernet_found +#ifndef COLDFIRE + && (hardware_flags & CTPCI_1M) +#endif + && (loop_counter == 1)) + { +#if !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) + board = rtl8139_eth_pci_table; /* compare table */ + while(board->vendor) + { + if((board->vendor == (id & 0xFFFF)) + && (board->device == (id >> 16))) { -#ifdef CONFIG_USB_EHCI - board = ehci_usb_pci_table; /* compare table */ - while(board->vendor) + if((ct60_rw_parameter(CT60_MODE_READ, CT60_PARAM_CTPCI, 0) & 0x80) && (rtl8139_eth_start(handle, board) >= 0)) { - if((board->vendor == (id & 0xFFFF)) - && (board->device == (id >> 16))) + unsigned long ip_addr = ct60_rw_parameter(CT60_MODE_READ, CT60_IP_ADDRESS2, 0); + unsigned long mask_addr = 0xFFFFFF00; + if(ip_addr < 0x80000000) { - if(usb_init(handle, board) >= 0) - usb_found++; - break; + if((ip_addr & 0xFF000000) == 0x0A000000) + mask_addr = 0xFFFFFF00; + else + mask_addr = 0xFF000000; } - board++; + else if(ip_addr < 0xC0000000) + mask_addr = 0xFFFF0000; + init_lwip(ip_addr, mask_addr, 0); + if(init_network()) + ethernet_found = 1; } -#endif /* CONFIG_USB_EHCI */ + break; } + board++; } - } - /* test ATA device */ - if((err >= 0) && !ata_found) - { - if(id == 0x12345678) /* device / vendor */ - ata_found = 1; +#endif } } } @@ -847,72 +1108,23 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin loop_counter++; } while(loop_counter <= 2); - old_vector_xbios = old_vector_linea = old_vector_vdi = 0; if(usb_found) { #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) -#ifdef CONFIG_USB_INTERRUPT_POLLING - install_vbl_timer(vbl_usb_event_poll, 0); -#else +#ifndef CONFIG_USB_INTERRUPT_POLLING usb_enable_interrupt(1); #endif #endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ } if(video_found) { - extern void *write_pixel_r, *read_pixel_r, *set_colours_r, *get_colours_r, *get_colour_r; -#if 0 - COOKIE *p; - p = get_cookie('_VDO'); - if(p != NULL) - p->v.l = 0x00040000; /* like MILAN, bad idea, less compatible */ -#endif - /* fVDI spec */ - accel_s = 0; - accel_c = A_SET_PIX | A_GET_PIX | A_MOUSE | A_LINE | A_BLIT | A_FILL | A_EXPAND | A_FILLPOLY | A_TEXT | A_SET_PAL | A_GET_COL; - read_pixel_r = write_pixel_r = set_colours_r = get_colours_r = get_colour_r = empty; - if(!os_magic) - { - long screen_addr = Mxalloc(32000 + 256, 0) + 255; /* STRAM - use Mxalloc because Srealloc can be used by monochome emulation later */ - screen_addr &= ~0xFF; -#ifndef COLDFIRE - if(debug && !redirect) - wait_key(); +#ifdef USE_RADEON_MEMORY + if(!lock_video) #endif - ret = Vsetscreen(screen_addr, screen_addr, 2, 0); /* for reduce F030 Videl bus load */ -#ifndef COLDFIRE - Cconws(mess_ignore); -#endif - } - old_vector_xbios = install_xbra(46, det_xbios); /* TRAP #14 */ - vidix.ident = 'VIDX'; - vidix.v.l = VIDIX_VERSION; - add_cookie(&vidix); -#if 0 // #ifndef COLDFIRE - if(use_dma) - { - Cconws("\rDMA (y/n)"); - if((Cconin() & 0xFF) != 'y') - { - use_dma = 0; - Cconout(27); - Cconout('E'); - } - } -#endif - if(!vmode) - { - vmode = (short)find_best_mode((long)vmode); - if(!vmode) - vmode = PAL | VGA | COL80 | BPS16; - else - vmode |= BPS16; - } - vmode = fix_boot_modecode(vmode); - ret = Vsetscreen(0, 0, 3, vmode); /* new Vsetscreen with internal driver installed */ + vmode = init_video(vmode); if(!os_magic) { -#if defined(COLDFIRE) && defined(MCF547X) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(MCF547X) && defined(LWIP) boot_os_menu(); #endif display_atari_logo(); @@ -954,7 +1166,7 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin (void)Vsetscreen(0, 0, 3, vmode); if(!os_magic) { -#if defined(COLDFIRE) && defined(MCF547X) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(MCF547X) && defined(LWIP) boot_os_menu(); #endif display_atari_logo(); @@ -965,16 +1177,15 @@ int init_devices(int no_reset, unsigned long hardware_flags) /* after the origin debug = redirect = 0; } while(0); -#if defined(NETWORK) && defined(LWIP) && !defined(MCF5445X) && defined(SOUND_AC97) +#if defined(COLDFIRE) && defined(LWIP) && !defined(MCF5445X) && defined(SOUND_AC97) if(old_vector_xbios) InitSound(1); // AC97 -#endif /* defined(NETWORK) && defined(LWIP) && !defined(MCF5445X) && defined(SOUND_AC97) */ +#endif /* defined(COLDFIRE) && defined(LWIP) && !defined(MCF5445X) && defined(SOUND_AC97) */ return((int)video_found); } void init_with_sdram(void) /* before booting, after the SDRAM init and the PCI devices list */ { - short key = 0; #ifdef BETA_VERSION int i; char buf[8]; @@ -1016,19 +1227,25 @@ void init_with_sdram(void) /* before booting, after the SDRAM init and the PCI d // Cconws(buf); Cconws(")\r\n"); #endif /* BETA_VERSION */ +#ifndef COLDFIRE + if(!os_magic && !(hardware_flags & CTPCI_1M)) + Cconws("Update the CTPCI hardware to 1M or more, if USB or Ethernet PCI boards used.\r\n"); +#endif memory_ok = 1; /* use M(x)alloc */ if(os_magic) drive_ok = 1; + key_init_with_sdram = 0; if(!os_magic && Cconis()) { - key = Crawcin() & 0xFF; + key_init_with_sdram = Crawcin() & 0xFF; while(Cconis()) Crawcin(); } #ifdef COLDFIRE if((info_fvdi != NULL) /* Videl / Radeon / Lynx driver */ #else /* !COLDFIRE */ - if(*((unsigned short *)0xE80000) < 0x200) /* check boot version */ + /* check boot version, 0x202 for Timer D vector overwrited by the boot after init_devices and used by FreeRTOS */ + if(*((unsigned short *)0xE80000) < 0x202) return; if(video_found /* Radeon driver */ #endif /* COLDFIRE */ @@ -1053,42 +1270,46 @@ void init_with_sdram(void) /* before booting, after the SDRAM init and the PCI d #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) if(usb_found) { - int error = 0; + int uif_cmd_usb(int argc, char **argv); + char *argv[] = { "usb", "tree" }; +#ifdef USB_POLL_HUB + vTaskDelay(os_magic ? configTICK_RATE_HZ*4 : configTICK_RATE_HZ); +#endif + uif_cmd_usb(2, argv); if(usb_error_str[0]) { - Cconws(usb_error_str); if(strstr(usb_error_str, "CTL:TIMEOUT") == NULL) { + Cconws(usb_error_str); wait_key(); - error = 1; } - } - if(!error) - { - int uif_cmd_usb(int argc, char **argv); - char *argv[] = { "usb", "tree" }; - uif_cmd_usb(2, argv); + usb_error_str[0] = '\0'; } } -#endif - if(ata_found) - { - if(!old_vector_xbios) - old_vector_xbios = install_xbra(46, det_xbios); /* TRAP #14 */ - +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ +#if !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) + if(ethernet_found) + { + extern unsigned long rtl8139_read_timer(void); + unsigned long timer_value; + int uif_cmd_ifconfig(int argc, char **argv); + char *argv[] = { "ifconfig", "-a" }; + vPortEnterCritical(); + timer_value = rtl8139_read_timer(); + udelay(1000); + timer_value = rtl8139_read_timer() - timer_value; + vPortExitCritical(); + kprint("PCI clock %d MHz found from RTL8139 timer\r\n", timer_value / 1000); + uif_cmd_ifconfig(2, argv); } -#if defined(NETWORK) && !defined(LWIP) - init_dma(); -#if !defined(MCF5445X) && defined(SOUND_AC97) - if(old_vector_xbios) - InitSound(1); // AC97 -#endif /* !defined(MCF5445X) && defined(SOUND_AC97) */ -#endif /* defined(NETWORK) && !defined(LWIP) */ +#endif #ifdef COLDFIRE #ifdef MCF547X check_sd_card(); #endif #endif + if(os_magic) + install_magic_routine(); /* init_before_autofolder call */ #ifdef DEBUG #ifndef COLDFIRE if(os_magic) @@ -1106,7 +1327,7 @@ void init_with_sdram(void) /* before booting, after the SDRAM init and the PCI d void init_before_autofolder(void) /* after booting, before start AUTO folder */ { -#ifdef NETWORK +#if defined(COLDFIRE) && defined(LWIP) IP_ADDR server; char path_server[80], name[80], speed[10]; char *buf; @@ -1114,22 +1335,26 @@ void init_before_autofolder(void) /* after booting, before start AUTO folder */ int i, j, drive; #endif #ifndef COLDFIRE - if(*((unsigned short *)0xE80000) < 0x200) /* check boot version */ + /* check boot version, 0x202 for Timer D vector overwrited by the boot after init_devices and used by FreeRTOS */ + if(*((unsigned short *)0xE80000) < 0x202) return; #endif Cconws("\r\n"); -#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) -#ifdef CONFIG_USB_STORAGE +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) if(usb_found) usb_stor_scan(); -#endif /* CONFIG_USB_STORAGE */ -#endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI */ -#ifdef COLDFIRE -#ifdef MCF547X +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_STORAGE) */ +#if defined( COLDFIRE) && defined(MCF547X) install_sd_card(); #endif +#if !defined(COLDFIRE) || defined(MCF547X) + if(!os_magic) + { +// if((key_init_with_sdram == 'c') || (key_init_with_sdram == 'C')) + cd_disk_boot(); + } #endif -#ifdef NETWORK +#if defined(COLDFIRE) && defined(LWIP) #ifdef MCF547X if(((swi & 0x80) || (boot_os == 2)) /* SW6 (DOWN) */ && ((drive = install_ram_disk()) != 0)) @@ -1173,7 +1398,7 @@ void init_before_autofolder(void) /* after booting, before start AUTO folder */ if(Fread(handle, len, buf) >= 0) { i=0; -#ifdef LWIP +#if 1 if((len >= 3) && (buf[0] == 'U') && (buf[1] == 'S') && (buf[2] == 'B')) { write_protect_ram_disk = FALSE; @@ -1275,61 +1500,6 @@ void init_before_autofolder(void) /* after booting, before start AUTO folder */ } if(Fsfirst("C:\\tftpsend",0x10) != 0) (void)Dcreate("C:\\tftpsend"); /* for later */ -#ifndef LWIP -#ifdef TEST_NETWORK - { - static char sname[80],data[1024],buf[10]; - int i=0,j,ch; - char *p; - Cconws("Network test...\r\n"); - strcpy(sname, path_server); - strcat(sname, "tftpsend\\test.bin"); - minus(sname); - for(j = 0; j < 10; j++) - { - Cconws("Send TOS...\r\n"); - if(tftp_write(&nif[ETHERNET_PORT], sname, server, 0xE00000, 0xEF0000) == TRUE) - { - Cconws("Get TOS...\r\n"); - if(tftp_read(&nif[ETHERNET_PORT], sname, server) == TRUE) - i = 0; - p = (char *)0xE00000; - while((ch = tftp_in_char()) != -1) - { - data[i++] = (char)ch; - if(i >= 1024) - { - for(i = 0; i < 1024; i++) - { - if(*p++ != data[i]) - { - Cconws("Error at offset 0x"); - ltoa(buf,(long)p & 0xFFFFF,16); - Cconws(buf); - Cconws("\r\n"); - } - } - i = 0; - } - } - p = tftp_get_error(); - if(*p) - { - Cconws(tftp_get_error()); - Cconws("\r\n"); - } - } - else - { - Cconws(tftp_get_error()); - Cconws("\r\n"); - } - } - wait_key(); - } -#endif /* TEST_NETWORK */ - end_network(); -#endif /* LWIP */ write_protect_ram_disk = FALSE; } } @@ -1340,11 +1510,15 @@ void init_before_autofolder(void) /* after booting, before start AUTO folder */ else wait_key(); #endif /* MCF547X */ -#endif /* NETWORK */ +#endif /* defined(COLDFIRE) && defined(LWIP) */ drive_ok = 1; } -#ifdef DBUG +void init_after_autofolder(void) /* after booting, after start AUTO folder */ +{ + +} + static void init_disassembler(struct DisasmPara_68k *dp, char *opcode, char *operands) { dp->instr = NULL; /* pointer to instruction to disassemble */ @@ -1363,11 +1537,9 @@ static void init_disassembler(struct DisasmPara_68k *dp, char *opcode, char *ope dp->areg = 0; /* address reg. for displacement (PC=-1) */ dp->displacement = 0; /* branch- or d16-displacement */ } -#endif long dbug(long key) { -#ifdef DBUG static struct DisasmPara_68k dp; static char buffer[16]; m68k_word *p,*ip; @@ -1376,17 +1548,22 @@ long dbug(long key) static char iwordbuf[32]; int n,i; char *s; -#ifndef COLDFIRE -#ifdef DEBUG + if((key >= 'A') && (key <= 'Z')) + key |= 0x20; if((char)key == 'v') { +#ifndef COLDFIRE +#ifdef DEBUG extern void display_char(char c); if(video_found) + { display_char((key >> 16) & 0xFF); - return(0); - } + return(1); + } #endif /* DEBUG */ #endif /* !COLDFIRE */ + return(0); + } switch((char)key) { case '\r': @@ -1427,11 +1604,9 @@ long dbug(long key) ip++; } ltoa(buffer,(unsigned long)dp.iaddr,16); - Cconout('\r'); - Cconout('\n'); + Cconws("\r\n"); Cconws(buffer); - Cconout(':'); - Cconout(' '); + Cconws(": "); Cconws(iwordbuf); strcpy(buffer, " "); n = 0; @@ -1454,21 +1629,88 @@ long dbug(long key) Cconws("\r\n (D)isassemble memory"); Cconws("\r\n (M)emory dump"); Cconws("\r\n (P)atch memory"); +#if defined(DBUG) && !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) + Cconws("\r\n (T)asks display"); +#endif key = 0; break; case 'm': case 'p': old_address = (m68k_word *)0xFFFFFFFF; break; +#if defined(DBUG) && !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) + case 't': + { + extern void uif_cmd_qt(int argc, char **argv); + Cconws("\r\n"); + uif_cmd_qt(0, NULL); + key = 0; + } + break; +#endif /* defined(DBUG) && !defined(COLDFIRE) && defined(LWIP) && defined(FREERTOS) */ + default: + if(key > ' ') + key = 0; + break; } -#endif return(key); } +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) + +static void build_alert(char *dest, char *begin, char *content, char *end) +{ + int i = 0, j = 0; + char *p = &dest[strlen(begin)]; + strcpy(dest, begin); + while(*content && (j < 5)) /* build alert */ + { + char c = *content++; + if(c == '\r') + continue; + *p++ = c; + i++; + if(((i >= 25) && (c == ' ')) || (c == '\n')) + { + if(j < 4) + { + p[-1] = '|'; /* separator */ + i = 0; + } + else if(c == '\n') + { + if(*p) + p[-1] = ' '; + else + p[-1] = '\0'; + } + j++; /* next line */ + } + } + if(p[-1] == '|') + p--; + *p = '\0'; + strcat(dest, end); +} + +#endif /* (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) */ + void event_aes(void) { -#ifdef COLDFIRE -#ifdef NETWORK +#if !defined(COLDFIRE) && defined(FREERTOS) + extern xQueueHandle xQueueAlert; + static char buf_alert[256]; + char msg[256]; + if(xQueueAlert != NULL) + { + if(xQueueAltReceive(xQueueAlert, msg, 0) == pdTRUE) + { + build_alert(buf_alert, "[1][", msg, "][OK]"); + form_alert(1, buf_alert); + } + } +#endif /* !defined(COLDFIRE) && defined(FREERTOS) */ +#if defined(COLDFIRE) && defined(LWIP) static int lock = 0; static long mem_size = 0; static unsigned long old_hz_200 = 0; @@ -1477,10 +1719,20 @@ void event_aes(void) _DTA tp_dta; static char subdir[] = "C:\\tftpsend\\"; static char path[80], path_server[80], name[80], buf_alert[256]; - char *p, *p2; - char c; int i, j, ok, nb_files; long total_size; +#ifdef LWIP + extern xQueueHandle xQueueAlert; + char msg[256]; + if(xQueueAlert != NULL) + { + if(xQueueAltReceive(xQueueAlert, msg, 0) == pdTRUE) + { + build_alert(buf_alert, "[1][", msg, "][OK]"); + form_alert(1, buf_alert); + } + } +#endif /* LWIP */ #ifdef MCF547X if(!(swi & 0x80)) return; @@ -1512,9 +1764,9 @@ void event_aes(void) if(nb_files && (total_size == mem_size)) { if(nvm.language == 2) - i = alert_tos("[1][Envoi des fichiers|au serveur TFTP ?][Oui|Non]"); + i = form_alert(1, "[1][Envoi des fichiers|au serveur TFTP ?][Oui|Non]"); else - i = alert_tos("[1][Send files to|the TFTP server?][Yes|No]"); + i = form_alert(1, "[1][Send files to|the TFTP server?][Yes|No]"); if(i == 1) { board_get_filename(path_server); @@ -1545,30 +1797,8 @@ void event_aes(void) ok = tftp_write_file((int)(name[0]-'A'), name+3, path_server, server); if(ok != TRUE) { - i = j = 0; - p = tftp_get_error(); - strcpy(buf_alert, "[3]["); - p2 = &buf_alert[4]; - while(*p && j < 5) /* build alert */ - { - c = *p2++ = *p++; - i++; - if(i >= 20 && c == ' ') - { - if(j < 4) - { - p2[-1] = '|'; /* separator */ - i = 0; - } - j++; /* next line */ - } - } - *p2 = 0; - if(nvm.language == 2) - strcat(buf_alert, "][Suivant|Abandon]"); - else - strcat(buf_alert, "][Next|Cancel]"); - if(alert_tos(buf_alert) == 1) + build_alert(buf_alert, "[3][", tftp_get_error(), (nvm.language == 2) ? "][Suivant|Abandon]" : "][Next|Cancel]"); + if(form_alert(1, buf_alert) == 1) ok = TRUE; } } @@ -1582,11 +1812,11 @@ void event_aes(void) else { if(nvm.language == 2) - alert_tos("[3][Ethernet en d‚faut!][Abandon]"); + form_alert(1, "[3][Ethernet en d‚faut!][Abandon]"); else - alert_tos("[3][Ethernet failure!][Cancel]"); + form_alert(1, "[3][Ethernet failure!][Cancel]"); } -#endif +#endif /* LWIP */ } /* if cancel or finished transfer, delete files in the tftp directory */ if(Fsfirst(path, 1) == 0) @@ -1610,14 +1840,12 @@ void event_aes(void) mem_size = total_size; Fsetdta(save_dta); lock = 0; -#endif -#endif +#endif /* defined(COLDFIRE) && defined(LWIP) */ } char *disassemble_pc(unsigned long pc) { static char line[80]; -#ifdef DBUG static struct DisasmPara_68k dp; static char buffer[16]; m68k_word *ip, *p = (m68k_word *)pc; @@ -1665,9 +1893,6 @@ char *disassemble_pc(unsigned long pc) buffer[n] = '\0'; strcat(line, buffer); strcat(line, operands); -#else - line[0] ='\0'; -#endif return(line); } diff --git a/flash.tos/drivers/lwip/am79c874.c b/flash.tos/drivers/lwip/am79c874.c index 925268a..bf43d8b 100644 --- a/flash.tos/drivers/lwip/am79c874.c +++ b/flash.tos/drivers/lwip/am79c874.c @@ -8,7 +8,6 @@ #include "fec.h" #include "am79c874.h" -#ifdef NETWORK #ifdef LWIP #undef DEBUG @@ -126,4 +125,3 @@ int am79c874_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex) /********************************************************************/ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/api_lib.c b/flash.tos/drivers/lwip/api_lib.c index d314f20..42530a7 100644 --- a/flash.tos/drivers/lwip/api_lib.c +++ b/flash.tos/drivers/lwip/api_lib.c @@ -39,7 +39,6 @@ #include "api_msg.h" #include "memp.h" -#ifdef NETWORK #ifdef LWIP struct @@ -745,4 +744,3 @@ netconn_err(struct netconn *conn) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/api_msg.c b/flash.tos/drivers/lwip/api_msg.c index 6c876b2..75ed5e5 100644 --- a/flash.tos/drivers/lwip/api_msg.c +++ b/flash.tos/drivers/lwip/api_msg.c @@ -38,7 +38,6 @@ #include "sys.h" #include "tcpip.h" -#ifdef NETWORK #ifdef LWIP #if LWIP_RAW @@ -810,6 +809,5 @@ api_msg_post(struct api_msg *msg) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/bcm5222.c b/flash.tos/drivers/lwip/bcm5222.c index de98e53..21974c4 100644 --- a/flash.tos/drivers/lwip/bcm5222.c +++ b/flash.tos/drivers/lwip/bcm5222.c @@ -13,7 +13,6 @@ #include "fec.h" #include "bcm5222.h" -#ifdef NETWORK #ifdef LWIP #undef DEBUG @@ -168,4 +167,3 @@ void bcm5222_get_reg(uint16* status0, uint16* status1) /********************************************************************/ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/dp83849.c b/flash.tos/drivers/lwip/dp83849.c index 1441731..fc59b76 100644 --- a/flash.tos/drivers/lwip/dp83849.c +++ b/flash.tos/drivers/lwip/dp83849.c @@ -8,7 +8,6 @@ #include "fec.h" #include "dp83849.h" -#ifdef NETWORK #ifdef LWIP #undef DEBUG @@ -84,4 +83,3 @@ int dp83849_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex) /********************************************************************/ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/err.c b/flash.tos/drivers/lwip/err.c index 097b46e..b21407b 100644 --- a/flash.tos/drivers/lwip/err.c +++ b/flash.tos/drivers/lwip/err.c @@ -33,7 +33,6 @@ #include "config.h" #include "err.h" -#ifdef NETWORK #ifdef LWIP @@ -65,4 +64,3 @@ lwip_strerr(err_t err) #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/etharp.c b/flash.tos/drivers/lwip/etharp.c index 31befda..8a96866 100644 --- a/flash.tos/drivers/lwip/etharp.c +++ b/flash.tos/drivers/lwip/etharp.c @@ -52,7 +52,6 @@ #include "stats.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP /* ARP needs to inform DHCP of any ARP replies? */ @@ -913,6 +912,5 @@ err_t etharp_request(struct netif *netif, struct ip_addr *ipaddr) return result; } -#endif -#endif +#endif /* LWIP */ diff --git a/flash.tos/drivers/lwip/fec.c b/flash.tos/drivers/lwip/fec.c index 5183289..39795e6 100644 --- a/flash.tos/drivers/lwip/fec.c +++ b/flash.tos/drivers/lwip/fec.c @@ -70,7 +70,6 @@ #endif #define TASK_PRIORITY (30) -#ifdef NETWORK #ifdef LWIP /* ------------------------ Type definitions ------------------------------ */ @@ -82,7 +81,8 @@ typedef struct xSemaphoreHandle tx_sem; /* Control access to transmitter */ xSemaphoreHandle rx_sem; /* Semaphore to signal receive thread */ // sys_sem_t tx_sem; /* Control access to transmitter */ -// sys_sem_t rx_sem; /* Semaphore to signal receive thread */ +// sys_sem_t rx_sem; /* Semaphore to signal receive thread */ + sys_thread_t task; /* FEC task */ } fec_if_t; /* ------------------------ Static variables ------------------------------ */ @@ -243,7 +243,7 @@ void dma_interrupt(void) * destination MAC address. The ARP module will later call our low level * output function fec_output_raw. */ -static err_t fec_output(struct netif * netif, struct pbuf * p, struct ip_addr * ipaddr ) +static err_t fec_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) { err_t res; // fec_if_t *fecif = netif->state; @@ -1283,6 +1283,7 @@ err_t fec_eth_start(uint8 ch, uint8 trcvr, uint8 speed, uint8 duplex, struct net fecif->self = (struct eth_addr *)&netif->hwaddr[0]; fecif->netif = netif; fecif->ch = ch; + fecif->task = NULL; // if((fecif->tx_sem = sys_sem_new(1)) == NULL) // res = ERR_MEM; // else if((fecif->rx_sem = sys_sem_new(0)) == NULL) @@ -1293,7 +1294,7 @@ err_t fec_eth_start(uint8 ch, uint8 trcvr, uint8 speed, uint8 duplex, struct net xSemaphoreAltTake(fecif->rx_sem, 1); if((fecif->tx_sem == NULL) || (fecif->rx_sem == NULL)) res = ERR_MEM; - else if(sys_thread_new(fec_rx_task, fecif, TASK_PRIORITY) == NULL) + else if((fecif->task = sys_thread_new(fec_rx_task, fecif, TASK_PRIORITY)) == NULL) res = ERR_MEM; else { @@ -1343,15 +1344,18 @@ err_t fec_eth_start(uint8 ch, uint8 trcvr, uint8 speed, uint8 duplex, struct net } } } - if(res != ERR_OK) + if((res != ERR_OK) && (fecif != NULL)) { - mem_free(fecif); + if(fecif->task != NULL) + sys_arch_thread_remove(fecif->task); if(fecif->tx_sem != NULL) - vQueueDelete((xQueueHandle)fecif->tx_sem); + vQueueDelete((xQueueHandle)fecif->tx_sem); // sys_sem_free(fecif->tx_sem); if(fecif->rx_sem != NULL) - vQueueDelete((xQueueHandle)fecif->rx_sem); + vQueueDelete((xQueueHandle)fecif->rx_sem); // sys_sem_free(fecif->rx_sem); + mem_free(fecif); + fecif_g[ch] = NULL; } } else @@ -1368,6 +1372,7 @@ err_t fec_eth_start(uint8 ch, uint8 trcvr, uint8 speed, uint8 duplex, struct net */ void fec_eth_stop(uint8 ch) { + fec_if_t *fecif; int level; /* Disable interrupts */ level = asm_set_ipl(7); @@ -1382,6 +1387,22 @@ void fec_eth_stop(uint8 ch) nbuf_flush(ch); /* Restore interrupt level */ asm_set_ipl(level); + /* Remove task / semaphores */ + fecif = fecif_g[ch]; + if(fecif != NULL) + { + fecif->netif->flags &= ~NETIF_FLAG_LINK_UP; + if(fecif->task != NULL) + sys_arch_thread_remove(fecif->task); + if(fecif->tx_sem != NULL) + vQueueDelete((xQueueHandle)fecif->tx_sem); +// sys_sem_free(fecif->tx_sem); + if(fecif->rx_sem != NULL) + vQueueDelete((xQueueHandle)fecif->rx_sem); +// sys_sem_free(fecif->rx_sem); + mem_free(fecif); + fecif_g[ch] = NULL; + } } err_t mcf_fec0_init(struct netif *netif) @@ -1403,4 +1424,3 @@ err_t mcf_fec1_init(struct netif *netif) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/ftpd.c b/flash.tos/drivers/lwip/ftpd.c index bf12e45..5769ea7 100644 --- a/flash.tos/drivers/lwip/ftpd.c +++ b/flash.tos/drivers/lwip/ftpd.c @@ -43,7 +43,6 @@ #undef DEBUG -#ifdef NETWORK #ifdef LWIP #ifdef FTP_SERVER @@ -2617,4 +2616,3 @@ sint_t ftpd_start(char *username, char *password) #endif /* FTP_SERVER */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/gif.c b/flash.tos/drivers/lwip/gif.c index 514db32..1a7d158 100644 --- a/flash.tos/drivers/lwip/gif.c +++ b/flash.tos/drivers/lwip/gif.c @@ -32,7 +32,6 @@ #include "net.h" #include "gif.h" -#ifdef NETWORK #ifdef LWIP /* @@ -590,5 +589,4 @@ void write_gif(char **file, Gif *gif) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/gs.h b/flash.tos/drivers/lwip/gs.h index 453ace5..28d05e9 100644 --- a/flash.tos/drivers/lwip/gs.h +++ b/flash.tos/drivers/lwip/gs.h @@ -32,15 +32,19 @@ #include "transprt.h" -#if 0 -#define GS_DEBUG -#endif +#undef GS_DEBUG #ifndef GS_DEBUG #define PRINT_DEBUG(x) #else +#if defined(COLDFIRE) && defined(LWIP) extern void board_printf(const char *fmt, ...); -#define PRINT_DEBUG(x) { board_printf x; board_printf ("\r\n"); } +#define PRINT_DEBUG(x) { board_printf x; board_printf("\r\n"); } +#else +#include +extern void kprint(const char *fmt, ...); +#define PRINT_DEBUG(x) { long stack=0; if(Super(1L) >= 0) stack=Super(0L); kprint x; kprint("\r\n"); if(stack) Super((void *)stack); } +#endif #endif typedef unsigned char uchar; diff --git a/flash.tos/drivers/lwip/gs_func.c b/flash.tos/drivers/lwip/gs_func.c index 7c92f6f..8c738e7 100644 --- a/flash.tos/drivers/lwip/gs_func.c +++ b/flash.tos/drivers/lwip/gs_func.c @@ -34,7 +34,6 @@ #include "gs_mem.h" #include "gs_stik.h" -#ifdef NETWORK #ifdef LWIP extern int errno; @@ -111,7 +110,7 @@ static long gs_read_socket (int fd, void *buf, int size) int ret, n, len, avail, bytes = 0; GS *gs = gs_get (fd); - if (gs->flags & GS_NOSOCKET) + if (!gs || (gs->flags & GS_NOSOCKET)) { PRINT_DEBUG (("read_socket: bad handle")); return E_BADHANDLE; @@ -240,7 +239,7 @@ int gs_accept (int fd) PRINT_DEBUG (("gs_accept(%i)", fd)); if (!gs - || gs->flags & GS_NOSOCKET + || (gs->flags & GS_NOSOCKET) || !(gs->flags & GS_LISTENING)) { PRINT_DEBUG (("gs_accept: bad handle")); @@ -317,7 +316,7 @@ int gs_establish (int fd) PRINT_DEBUG (("gs_establish(%i)", fd)); - if (!gs || gs->flags & GS_NOSOCKET || !(gs->flags & GS_PEND_OPEN)) + if (!gs || (gs->flags & GS_NOSOCKET) || !(gs->flags & GS_PEND_OPEN)) { PRINT_DEBUG (("gs_establish: bad handle")); return E_BADHANDLE; @@ -612,7 +611,7 @@ long gs_canread (int fd) PRINT_DEBUG (("gs_canread(%i)", fd)); - if (gs->flags & GS_NOSOCKET) + if (!gs || (gs->flags & GS_NOSOCKET)) { PRINT_DEBUG (("gs_canread: bad handle")); return E_BADHANDLE; @@ -720,7 +719,7 @@ NDB *gs_readndb (int fd) PRINT_DEBUG (("gs_readndb(%i)", fd)); - if (gs->flags & GS_NOSOCKET) + if (!gs || (gs->flags & GS_NOSOCKET)) { PRINT_DEBUG (("gs_readndb: bad handle")); return NULL; @@ -793,7 +792,7 @@ long gs_write (int fd, char *buf, long buflen) PRINT_DEBUG (("gs_write(%i, %p, %li)", fd, (void *) buf, buflen)); - if (gs->flags & GS_NOSOCKET) + if (!gs || (gs->flags & GS_NOSOCKET)) { PRINT_DEBUG (("gs_write: bad handle")); return E_BADHANDLE; @@ -873,7 +872,7 @@ long gs_read (int fd, char *buf, long buflen) // PRINT_DEBUG (("gs_read(%i, %p, %li)", fd, (void *) buf, buflen)); - if (gs->flags & GS_NOSOCKET) + if (!gs || (gs->flags & GS_NOSOCKET)) { PRINT_DEBUG (("gs_read: bad handle")); @@ -1028,5 +1027,4 @@ int gs_resolve (char *dn, char **rdn, uint32 *alist, int16 lsize) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/gs_mem.c b/flash.tos/drivers/lwip/gs_mem.c index 807042a..d4952b3 100644 --- a/flash.tos/drivers/lwip/gs_mem.c +++ b/flash.tos/drivers/lwip/gs_mem.c @@ -39,7 +39,6 @@ #define is_freed(H) (((H)->size & 0xFF000000L) == FREED) #define chunksize(H) ((H)->size & 0x00FFFFFFL) -#ifdef NETWORK #ifdef LWIP typedef struct chunk_header chunk_header; @@ -338,5 +337,4 @@ gs_mem_realloc (void *mem, unsigned long newsize) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/gs_stik.c b/flash.tos/drivers/lwip/gs_stik.c index 6b19be3..7ae75db 100644 --- a/flash.tos/drivers/lwip/gs_stik.c +++ b/flash.tos/drivers/lwip/gs_stik.c @@ -34,7 +34,6 @@ #define VER_MAJOR "0" #define VER_MINOR "30" -#ifdef NETWORK #ifdef LWIP /* STIK global configuration structure. @@ -466,5 +465,4 @@ void gs_cleanup_stik_if (void) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/icmp.c b/flash.tos/drivers/lwip/icmp.c index 3499df1..d81adc3 100644 --- a/flash.tos/drivers/lwip/icmp.c +++ b/flash.tos/drivers/lwip/icmp.c @@ -50,7 +50,6 @@ #include "stats.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP /** @@ -312,7 +311,6 @@ icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) #endif /* IP_FORWARD */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/inet.c b/flash.tos/drivers/lwip/inet.c index 769f574..bd41fd9 100644 --- a/flash.tos/drivers/lwip/inet.c +++ b/flash.tos/drivers/lwip/inet.c @@ -49,7 +49,6 @@ #include "sys.h" -#ifdef NETWORK #ifdef LWIP /* These are some reference implementations of the checksum algorithm, with the @@ -541,4 +540,3 @@ ntohl(u32_t n) #endif /* (LWIP_PLATFORM_BYTESWAP == 0) && (BYTE_ORDER == LITTLE_ENDIAN) */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/init.c b/flash.tos/drivers/lwip/init.c index 54e2720..aa92537 100644 --- a/flash.tos/drivers/lwip/init.c +++ b/flash.tos/drivers/lwip/init.c @@ -6,6 +6,9 @@ /* ------------------------ Platform includes ----------------------------- */ #include "config.h" +#include "m68k_disasm.h" +#include "../../include/vars.h" +#ifdef COLDFIRE #include "net.h" #ifdef MCF5445X #include "mcf5445x.h" @@ -13,11 +16,9 @@ #define MCF_UART_USR_TXRDY UART_USR_TXRDY #else #include "mcf548x.h" -#endif +#endif /* MCF5445X */ #include "get.h" -#include "m68k_disasm.h" #include "../../include/ramcf68k.h" -#include "../../include/vars.h" #ifndef MCF5445X #ifdef SOUND_AC97 #include "../ac97/mcf548x_ac97.h" @@ -27,7 +28,13 @@ #else /* MCF548X */ #define AC97_DEVICE 3 /* M5484LITE */ #endif /* MCF547X */ -#endif +#endif /* MCF5445X */ +#else /* ! COLDFIRE */ +#include +#include "ct60.h" +#include "../../include/pci_bios.h" +#define cookie 0x5A0 +#endif /* COLDFIRE */ /* ------------------------ FreeRTOS includes ----------------------------- */ #include "../freertos/FreeRTOS.h" @@ -58,10 +65,9 @@ /* ------------------------ BDOS includes ----------------------------------*/ /* cannot use TOS trap out of CF68KLIB !!! */ +#ifdef COLDFIRE #include "../bdos/bdos.h" - -#ifdef NETWORK -#ifdef LWIP +#endif /* ------------------------ Defines --------------------------------------- */ #undef KILL_TOS_ON_FAULT /* for debug */ @@ -70,13 +76,31 @@ #define TOS_TASK_PRIORITY ( 5 ) #define RTC_TASK_PRIORITY ( 6 ) #define VBL_TASK_PRIORITY ( 25 ) -#define ROOT_TASK_PRIORITY ( 10 ) #define WEB_TASK_PRIORITY ( 10 ) #define FTP_TASK_PRIORITY ( 10 ) #define TFTP_TASK_PRIORITY ( 10 ) #define TELNET_TASK_PRIORITY ( 15 ) #define DEBUG_TASK_PRIORITY ( 20 ) +#ifdef COLDFIRE +#define ROOT_TASK_PRIORITY ( 10 ) #define STACK_DEFAULT ( 4096 ) +#else /* !COLDFIRE */ +#define ROOT_TASK_PRIORITY ( 31 ) +#define STACK_DEFAULT ( 2048 ) +#endif /* COLDFIRE */ + +typedef struct +{ + long ident; + union + { + long l; + short i[2]; + char c[4]; + } v; +} COOKIE; + +#ifdef LWIP #define FTP_USERNAME "coldfire" #define FTP_PASSWORD "atari" @@ -101,33 +125,23 @@ #define CTRL_R 0x12 /* last command repeat */ /* ------------------------ PCI ------------------------------------------- */ -typedef struct -{ - long ident; - union - { - long l; - short i[2]; - char c[4]; - } v; -} COOKIE; - -#ifdef MCF547X /* for start Emutos and recreate PCI cookie */ +#if defined(COLDFIRE) && defined(MCF547X) /* for start Emutos and recreate PCI cookie */ #ifndef PCI_COOKIE_TOTALSIZE /* #include ../../include/pci_bios.h create problems */ -#define PCI_MAX_HANDLE (7+1) /* Firebee specific ! */ +#define PCI_MAX_BUS 4 #define PCI_MAX_FUNCTION 4 /* 4 functions per PCI slot */ +#define PCI_MAX_DEVICE 32 #define PCI_DEV_DES_SIZE 20 #define PCI_RSC_DESC_SIZE 24 #define PCI_RSC_DESC_TOTALSIZE (PCI_RSC_DESC_SIZE*6) #define PCI_COOKIE_ROUTINE 8 /* offset PCI BIOS routines */ #define PCI_COOKIE_MAX_ROUTINES 45 /* maximum of routines */ #define PCI_COOKIE_SIZE ((4*PCI_COOKIE_MAX_ROUTINES)+PCI_COOKIE_ROUTINE) -#define PCI_RSC_HANDLESTOTALSIZE (PCI_RSC_DESC_TOTALSIZE*PCI_MAX_HANDLE*PCI_MAX_FUNCTION) -#define PCI_DEV_HANDLESTOTALSIZE (PCI_DEV_DES_SIZE*PCI_MAX_HANDLE*PCI_MAX_FUNCTION) -#define PCI_INT_HANDLESTOTALSIZE (PCI_MAX_HANDLE*PCI_MAX_FUNCTION) -#define PCI_COOKIE_TOTALSIZE (PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE) -#endif +#define PCI_RSC_HANDLESTOTALSIZE (PCI_RSC_DESC_TOTALSIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_DEV_HANDLESTOTALSIZE (PCI_DEV_DES_SIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_INT_HANDLESTOTALSIZE (PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_COOKIE_TOTALSIZE (PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE*2) #endif +#endif /* defined(COLDFIRE) && defined(MCF547X) */ /* ------------------------ TFTP ------------------------------------------ */ #define TimeOut 2 /* seconds */ @@ -217,7 +231,11 @@ struct tftphdr #define TERM_CONSOLE 1 #define TERM_VT100 2 +#ifdef COLDFIRE #define TELNET_BUF_SIZE 4096 +#else +#define TELNET_BUF_SIZE 2048 +#endif struct term { @@ -251,10 +269,12 @@ extern unsigned long size_ram_disk, ext_write_protect_ram_disk; extern xTaskHandle pxCurrentTCB, tid_TOS; xTaskHandle tid_TELNET, tid_DEBUG, tid_HTTPd; +#ifdef COLDFIRE + #ifdef MCF547X xTaskHandle tid_ETOS; unsigned long pseudo_dma_vec; -extern short boot_os; +extern short boot_os, drive_ok; #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) void *pci_data; #endif @@ -273,6 +293,18 @@ extern unsigned long save_imrl0, save_imrl0_tos, save_imrh0, save_imrh0_tos, sav extern unsigned long save_imrl, save_imrl_tos, save_imrh, save_imrh_tos; #endif static int restart_debug, get_serial_vector, get_ikbd_vector, tos_suspend; + +void *start_run; + +xSemaphoreHandle xSemaphoreBDOS; +xQueueHandle xQueueAlert; + +#else /* !COLDFIRE */ + +unsigned long ip_addr_client; + +#endif /* COLDFIRE */ + struct termstate *ts; static const char PROMPT[] = "> "; @@ -293,13 +325,12 @@ static int md_last_size; static unsigned long disasm_last_address; typedef char HISTENT[UIF_MAX_LINE]; +#ifdef COLDFIRE static HISTENT history[MAX_HISTORY]; -extern int errno; -int lwip_ok; -void *start_run; +#endif +int lwip_ok; int errno; -xSemaphoreHandle xSemaphoreBDOS; typedef struct socket_cookie { @@ -355,27 +386,35 @@ typedef struct #define DEST_STRING (2) /* ------------------------ Prototypes ------------------------------------ */ +extern int add_cookie(COOKIE *cook); +extern COOKIE *get_cookie(long id); +extern char *disassemble_pc(unsigned long pc); static void uif_cmd_help(int argc, char **argv); static int make_argv(char *cmdline, char *argv[]); +extern int printk(PRINTK_INFO *info, const char *fmt, va_list ap); +extern int sprintD(char *s, const char *fmt, ...); +#ifdef COLDFIRE extern err_t mcf_fec0_init(struct netif *netif); extern err_t mcf_fec1_init(struct netif *netif); extern int ftpd_start(char *username, char *password); -extern COOKIE *get_cookie(long id); -extern int add_cookie(COOKIE *cook); -extern int printk(PRINTK_INFO *info, const char *fmt, va_list ap); -extern int printD(const char *fmt, ...); -extern int sprintD(char *s, const char *fmt, ...); extern void flush_caches(void); extern void enable_caches(void); extern void disable_caches(void); -extern char *disassemble_pc(unsigned long pc); +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) extern void uif_cmd_usb(int argc, char **argv); -extern void usb_enable_interrupt(void); +#endif +#else /* !COLDFIRE */ +#define conout_debug vdu +extern void vdu(char c); /* Videl if not used */ +extern void kprint(const char *fmt, ...); +extern err_t rtl8139if_init(struct netif *netif); +#endif /* COLDFIRE */ /* ------------------------ Implementation -------------------------------- */ -// static -int auxistat(void) +#ifdef COLDFIRE + +static int auxistat(void) { register int ret __asm__("d0"); #ifdef MCF547X @@ -481,6 +520,8 @@ static int rs232get(void) return(ret); } +#ifndef MCF547X + static void install_inters_cf68klib(void) { int tos_run = (int)(*(unsigned short *)_timer_ms); @@ -540,7 +581,7 @@ static void install_inters_cf68klib(void) } } -static void deinstall_inters_cf68klib(void) +static void uninstall_inters_cf68klib(void) { int tos_run = (int)(*(unsigned short *)_timer_ms); if(tos_run && get_serial_vector) @@ -595,6 +636,8 @@ static void deinstall_inters_cf68klib(void) } } +#endif /* MCF547X */ + static int conin_debug(void) { int tos_run; @@ -653,6 +696,8 @@ void conout_debug(int c) } } +#endif /* COLDFIRE */ + void conws_debug(char *buf) { int i = 0; @@ -660,6 +705,20 @@ void conws_debug(char *buf) conout_debug(buf[i++]); } +void printf_debug(const char *fmt, ...) +{ + static char buf[TELNET_BUF_SIZE]; // minimize stack usage + va_list ap; + PRINTK_INFO info; + info.dest = DEST_STRING; + va_start(ap, fmt); + info.loc = buf; + printk(&info, fmt, ap); + *info.loc = '\0'; + va_end(ap); + conws_debug(buf); +} + #ifdef DBUG static int telnet_write_socket(char *response, int size, int flush) @@ -723,7 +782,18 @@ void board_printf(const char *fmt, ...) printk(&info, fmt, ap); *info.loc = '\0'; va_end(ap); - conws_debug(buf_tos); +#ifdef COLDFIRE + conws_debug(buf_tos); /* serial */ +#else /* !COLDFIRE */ + { + long stack=0; + if(Super(1L) >= 0) + stack = Super(0L); + kprint(buf_tos); /* video */ + if(stack) + Super((void *)stack); + } +#endif /* COLDFIRE */ } else { @@ -740,7 +810,7 @@ void board_printf(const char *fmt, ...) telnet_write_socket(buf, strlen(buf), 1); } else - conws_debug(buf); + conws_debug(buf); /* serial on CF else videl if not used */ vPortFree(buf); } } @@ -748,9 +818,13 @@ void board_printf(const char *fmt, ...) static char board_getchar(void) { +#ifdef COLDFIRE if(pxCurrentTCB == tid_TELNET) +#endif return(CTRL_C); +#ifdef COLDFIRE return((char)conin_debug()); +#endif } void board_putchar(char c) @@ -760,14 +834,18 @@ void board_putchar(char c) if(ts->sock > 0) telnet_write_socket(&c, 1, (c == '\n') ? 1 : 0); } +#ifdef COLDFIRE else conout_debug(c); +#endif } static void board_putchar_flush(void) { } +#ifdef COLDFIRE + static void history_init(void) { int index; @@ -897,6 +975,8 @@ static char *get_history_line(char *userline) return userline; } +#endif /* COLDFIRE */ + static char *get_line(char *line) { int pos; @@ -1029,26 +1109,27 @@ static void dump_mem(unsigned long begin, unsigned long end, int size) switch(size) { case SIZE_8: - board_printf("%02X ", (int)data); - *(uint8 *)lcur = (uint8)data; - curr++; - lcur++; - i++; - break; - case SIZE_16: - board_printf("%04X ", (int)data); - *(uint16 *)lcur = (uint16)data; - curr += 2; - lcur += 2; - i += 2; - break; - case SIZE_32: - board_printf("%08X ", (int)data); - *(unsigned long *)lcur = data; - curr += 4; - lcur += 4; - i += 4; - break; + board_printf("%02X ", (int)data); + *(uint8 *)lcur = (uint8)data; + curr++; + lcur++; + i++; + break; + case SIZE_16: + default: + board_printf("%04X ", (int)data); + *(uint16 *)lcur = (uint16)data; + curr += 2; + lcur += 2; + i += 2; + break; + case SIZE_32: + board_printf("%08X ", (int)data); + *(unsigned long *)lcur = data; + curr += 4; + lcur += 4; + i += 4; + break; } } for(i = 0; i < 16; i++) @@ -1064,6 +1145,8 @@ static void dump_mem(unsigned long begin, unsigned long end, int size) while(curr < end); } +#ifdef COLDFIRE + #define BKPT_NONE (0) #define BKPT_PERM (1) #define BKPT_TEMP (2) @@ -1215,7 +1298,7 @@ static void breakpoint_add(unsigned long address, int type) /* Test for valid breakpoint address */ if(address & 1) /* 16-bit boudary */ { - board_printf("Error: Invalid breakpoint address!\r\n"); + board_printf("Error: Invalid breakpoint address!\r\n"); return; } // unprotect_code(); @@ -1223,7 +1306,7 @@ static void breakpoint_add(unsigned long address, int type) brktab[i].instruction = *(unsigned short *)address; *(unsigned short *)address = (unsigned short)ILLEGAL; if(*(volatile unsigned short *)address != (unsigned short)ILLEGAL) - board_printf("Error: Address is read-only!\n"); + board_printf("Error: Address is read-only!\n"); else { *(unsigned short *)address = brktab[i].instruction; @@ -1414,7 +1497,7 @@ static void uif_cmd_cb(int argc, char **argv) { if((index >= UIF_MAX_BRKPTS) || (brktab[index].valid != BKPT_PERM)) { - board_printf("Error: Bad index!\r\n"); + board_printf("Error: Bad index!\r\n"); return; } breakpoint_remove(brktab[index].address); @@ -1449,7 +1532,7 @@ static void uif_cmd_db(int argc, char **argv) brkpnt = get_value(argv[i],&success,16); if(success == 0) { - board_printf("Error: Bad Value: %s\r\n",argv[i]); + board_printf("Error: Bad Value: %s\r\n",argv[i]); return; } /* add breakpoint, if not already there */ @@ -1536,7 +1619,7 @@ static void uif_cmd_db(int argc, char **argv) *(unsigned char *)(trap_breakpoint) = 1; /* for trap #1 mshrink */ break; default: - board_printf("Error: Invalid option: %s\r\n",argv[1]); + board_printf("Error: Invalid option: %s\r\n",argv[1]); break; } i++; @@ -1706,13 +1789,13 @@ void inter_vbl(void) #define MMUSR_HITN 0x02 -static void mmu_map(long virt_addr, long phys_addr, long flag_itlb, long flags_mmutr, long flags_mmudr) +static void mmu_map(long virt_addr, long phys_addr, long flag_itlb, long flags_mmudr) { extern unsigned char __MBAR[]; unsigned long MMU_BASE = (unsigned long)__MBAR + 0x40000; MMUAR = virt_addr + 1; MMUOR = MMUOR_STLB + MMUOR_ADR + flag_itlb; - MMUTR = virt_addr + flags_mmutr + MMUTR_V; + MMUTR = virt_addr + MMUTR_SG + MMUTR_V; MMUDR = phys_addr + flags_mmudr; MMUOR = MMUOR_ACC + MMUOR_UAA + flag_itlb; } @@ -1724,12 +1807,16 @@ static portTASK_FUNCTION(vVBL, pvParmeters) extern long get_videl_size(void); extern void get_mouseikbdvec(void); #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) /* for usb_malloc */ +#if 0 // #ifdef CONFIG_USB_STORAGE + extern short usb_found; + extern int usb_stor_scan(void); +#endif /* CONFIG_USB_STORAGE */ #ifdef SOUND_AC97 extern void det_xbios(void); extern long sndstatus(long reset); extern long old_vector_xbios; extern long flag_snd_init, flag_gsxb; - int sound_err; + int sound_err, i; #endif /* SOUND_AC97 */ #endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ volatile unsigned char *rtc_reg = (volatile unsigned char *)0xFFFF8961; /* PFGA emulation */ @@ -1743,7 +1830,12 @@ static portTASK_FUNCTION(vVBL, pvParmeters) old_vector_xbios = *(long *)0xB4; /* XBIOS */ #if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) #ifdef SOUND_AC97 - sound_err = mcf548x_ac97_install(2); + for(i = 0; i < 2; i++) + { + sound_err = mcf548x_ac97_install(2); + if(!sound_err) + break; + } #endif #endif while(1) @@ -1787,6 +1879,10 @@ static portTASK_FUNCTION(vVBL, pvParmeters) p++; } } +#if 0 // #ifdef CONFIG_USB_STORAGE + if(usb_found) + usb_stor_scan(); +#endif /* CONFIG_USB_STORAGE */ #endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ while((*(unsigned long *)_hz_200 - start_timer) < 200UL) { @@ -1804,13 +1900,13 @@ static portTASK_FUNCTION(vVBL, pvParmeters) int level = asm_set_ipl(7); /* disable interrupts */ flush_caches(); memcpy((void *)(new_physbase + 0x60000000), (void *)new_physbase, 0x100000); - mmu_map(new_physbase,(new_physbase + 0x60000000),MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); - mmu_map(new_physbase,(new_physbase + 0x60000000),0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + mmu_map(new_physbase,(new_physbase + 0x60000000),MMUOR_ITLB,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); + mmu_map(new_physbase,(new_physbase + 0x60000000),0,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); if((end_physbase != new_physbase) && (end_physbase < 0xd00000)) /* 2nd page */ { memcpy((void *)(end_physbase + 0x60000000), (void *)new_physbase, 0x100000); - mmu_map(end_physbase,(end_physbase + 0x60000000),MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); - mmu_map(end_physbase,(end_physbase + 0x60000000),0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + mmu_map(end_physbase,(end_physbase + 0x60000000),MMUOR_ITLB,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); + mmu_map(end_physbase,(end_physbase + 0x60000000),0,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); } asm_set_ipl(level); // board_printf("new videl screen at 0x%lX\r\n", physbase); @@ -1904,59 +2000,57 @@ static void go_emutos(unsigned long source) #endif unsigned long top = (unsigned long)__LWIP_BASE - 0x100000; /* - 1MB */ int i; - mcf548x_ac97_uninstall(2, 0); - vTaskDelay(1); - deinstall_inters_cf68klib(); + mcf548x_ac97_uninstall(2, 0); + vTaskDelay(1); +// uninstall_inters_cf68klib(); vTaskDelete(tid_TOS); - end_vdi(); /* for screen WEB server and mousexy() */ + end_vdi(); /* for screen WEB server and mousexy() */ if(source != 0xE0600000) { void (*fp)(void) = (void(*)(void))source; asm_set_ipl(7); /* disable interrupts */ (*fp)(); } -#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) pci_data = NULL; while(pci_cookie != NULL) { if(pci_cookie->ident == '_PCI') { - pci_data = usb_malloc(PCI_COOKIE_TOTALSIZE); - if(pci_data != NULL) - memcpy(pci_data, (void *)pci_cookie->v.l, PCI_COOKIE_TOTALSIZE); - break; + pci_data = usb_malloc(PCI_COOKIE_TOTALSIZE); + if(pci_data != NULL) + memcpy(pci_data, (void *)pci_cookie->v.l, PCI_COOKIE_TOTALSIZE); + break; } if(!pci_cookie->ident) - { - pci_cookie = NULL; - break; - } - pci_cookie++; + pci_cookie = NULL; + else + pci_cookie++; } -#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) */ +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ #if 1 init_videl(640, 480, 4, 60, 0xD00000); - memset((void *)0xD00000, 0, (640 * 480 * 4) /sizeof(short)); + memset((void *)0xD00000, 0, (640 * 480 * 4) /sizeof(short)); #else init_videl(640, 480, 16, 60, 0xD00000); - memset((void *)0xD00000, -1, 640 * 480 * sizeof(short)); + memset((void *)0xD00000, -1, 640 * 480 * sizeof(short)); #endif - info_fvdi = NULL; + info_fvdi = NULL; asm_set_ipl(7); /* disable interrupts */ - for(i = 1; i < 16; *(unsigned long *)(((32+i) * 4) + coldfire_vector_base) = (unsigned long)new_trap, i++); + for(i = 1; i < 16; *(unsigned long *)(((32+i) * 4) + coldfire_vector_base) = (unsigned long)new_trap, i++); *(unsigned long *)((5 * 4) + coldfire_vector_base) = (unsigned long)new_zero_divide; /* Zero Divide */ *(unsigned long *)((10 * 4) + coldfire_vector_base) = (unsigned long)new_trap; /* LineA */ *(unsigned long *)((15 * 4) + coldfire_vector_base) = (unsigned long)new_trap; /* LineF */ *(unsigned long *)(((64+6) * 4) + coldfire_vector_base) = (unsigned long)new_mfp; /* IRQ6 EPORT */ pseudo_dma_vec = *(unsigned long *)0x13C; - MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE6; + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE6; if(save_imrl_tos & MCF_INTC_IMRL_INT_MASK5) - MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_MASKALL); - else /* PCI used */ - { - /* move PCI CF68KLIB interrupt vector to native coldfire vector */ + MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_MASKALL); + else /* PCI used */ + { + /* move PCI CF68KLIB interrupt vector to native coldfire vector */ *(unsigned long *)(((64+5) * 4) + coldfire_vector_base) = *(unsigned long *)((64+5+OFFSET_INT_CF68KLIB) * 4); /* IRQ5 EPORT */ - MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL); + MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL); } top &= 0xFFF00000; disable_caches(); @@ -1967,7 +2061,7 @@ static void go_emutos(unsigned long source) asm volatile ( " moveq #0,D0\n\t" " movec.l D0,ACR0\n\t" ); - mmu_map(top,top,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_NOCACHE+MMUDR_LK); + mmu_map(top,top,0,MMUDR_SZ1M+MMUDR_NOCACHE+MMUDR_LK); *(unsigned long *)ramtop = top; enable_caches(); xTaskCreate(vETOS, (void *)"ETOS", STACK_DEFAULT, NULL, TOS_TASK_PRIORITY, &tid_ETOS); @@ -1990,7 +2084,7 @@ static void uif_cmd_go(int argc, char **argv) #ifdef MCF547X if(((unsigned long)fp == 0xE0600000) || ((unsigned long)fp == 0xE0400000)) { - go_emutos((unsigned long)fp); + go_emutos((unsigned long)fp); return; } #endif @@ -2042,11 +2136,12 @@ static void uif_cmd_st(int argc, char **argv) } } if(!found) - board_printf("Error: No task supended by a breakpoint to trace\r\n"); + board_printf("Error: No task supended by a breakpoint to trace\r\n"); } -#ifndef MCF5445X -#ifdef SOUND_AC97 +#endif /* COLDFIRE */ + +#if defined(COLDFIRE) && !defined(MCF5445X) && defined(SOUND_AC97) static void uif_cmd_ac97_pr(int argc, char **argv) { @@ -2112,8 +2207,7 @@ static void uif_cmd_ac97_pr(int argc, char **argv) board_printf(SYNTAX,argv[0]); } -#endif /* MCF5445X */ -#endif /* SOUND_AC97 */ +#endif /* defined(COLDFIRE) && !defined(MCF5445X) && defined(SOUND_AC97) */ static void uif_cmd_md(int argc, char **argv) { @@ -2129,7 +2223,7 @@ static void uif_cmd_md(int argc, char **argv) if(success) { contents = cpu_read_data(begin,SIZE_32); - board_printf("%08X contains %08X\n", (int)begin, (int)contents); + board_printf("%08X contains %08X\r\n", (int)begin, (int)contents); begin = contents; end = contents+(DEFAULT_MD_LINES*16); goto show_mem; @@ -2167,7 +2261,8 @@ static void uif_cmd_md(int argc, char **argv) else { begin = md_last_address; - size = md_last_size; + if(md_last_size) + size = md_last_size; end = begin + (DEFAULT_MD_LINES * 16); } show_mem: @@ -2208,12 +2303,12 @@ static void uif_cmd_pm(int argc, char **argv) while(!done) { datar = cpu_read_data(address, size); - board_printf("%08X: ", (int)address); + board_printf("%08X: ", (int)address); switch(size) { - case SIZE_8: board_printf("[%02X] ", (int)datar); break; - case SIZE_16: board_printf("[%04X] ", (int)datar); break; - case SIZE_32: board_printf("[%08X] ", (int)datar); break; + case SIZE_8: board_printf("[%02X] ", (int)datar); break; + case SIZE_16: board_printf("[%04X] ", (int)datar); break; + case SIZE_32: board_printf("[%08X] ", (int)datar); break; } get_line(string); if(make_argv(string, NULL) == 0) @@ -2341,25 +2436,35 @@ static void uif_cmd_dis(int argc, char **argv) static void uif_cmd_dr(int argc, char **argv) { +#ifdef COLDFIRE unsigned long reg[40]; + int vector; +#endif portSTACK_TYPE p[64]; portSTACK_TYPE *p1; portSTACK_TYPE pc; portSTACK_TYPE frame_format; - int i, j, vector; + int i, j; if(argv); if(argc); vTaskSuspendAll(); +#ifdef COLDFIRE memcpy(reg, (void *)(library_data_area), 40 * sizeof(unsigned long)); -#ifdef MCF547X +#endif +#if defined(COLDFIRE) && defined(MCF547X) memcpy(p, (tid_ETOS != NULL) ? tid_ETOS : tid_TOS, 64 * sizeof(portSTACK_TYPE)); #else memcpy(p, tid_TOS, 64 * sizeof(portSTACK_TYPE)); -#endif +#endif /* defined(COLDFIRE) && defined(MCF547X) */ p1 = (portSTACK_TYPE *)p[0]; frame_format = p1[0]; +#ifdef COLDFIRE pc = p1[1]; +#else + pc = (frame_format << 16) | ((p1[1] >> 16) & 0xFFFF); +#endif /* COLDFIRE */ xTaskResumeAll(); +#ifdef COLDFIRE #ifdef MCF547X if(tid_ETOS == NULL) #endif @@ -2406,34 +2511,110 @@ static void uif_cmd_dr(int argc, char **argv) if(reg[16] < (unsigned long)__SDRAM_SIZE) board_printf("%s\r\n", disassemble_pc(reg[16])); } +#endif /* COLDFIRE */ board_printf("TOS task context saving:\r\n"); +#ifdef COLDFIRE board_printf("Status Register (SR): %04X\r\n", (int)(frame_format & 0xFFFF)); +#else + board_printf("Status Register (SR): %04X\r\n", (int)((frame_format >> 16) & 0xFFFF)); +#endif board_printf("Program Counter (PC): %08X\r\n", (int)pc); board_printf("Supervisor Stack (SSP): %08X\r\n", (int)p[0]); board_printf("User Stack (USP): %08X\r\n", (int)p[16]); for(i = j = 0; i < 8; i++, j += 2) { +#ifdef COLDFIRE board_printf("D%d: %08X A%d: %08X FP%d: %08X%08X\r\n", - i, (int)p[i+1], i, (int)p[i+9], - i, (int)p[j+22], (int)p[j+23]); + i, (int)p[i+1], i, (int)p[i+9], i, (int)p[j+22], (int)p[j+23]); +#else + board_printf("D%d: %08X A%d: %08X\r\n", i, (int)p[i+1], i, (int)p[i+9]); +#endif /* COLDFIRE */ } +#ifdef COLDFIRE if(pc < (portSTACK_TYPE)__SDRAM_SIZE) +#else + if(pc < *(unsigned long *)ramtop) +#endif /* COLDFIRE */ board_printf("%s\r\n", disassemble_pc(pc)); } -static void uif_cmd_qt(int argc, char **argv) +void uif_cmd_qt(int argc, char **argv) { if(argc); if(argv); - static char buf[80*50]; + char *buf; #if( HAVE_USP == 1 ) board_printf("Name\t\tTID\tPrio\tStatus\tSys/User Stack\t#\r\n"); #else board_printf("Name\t\tTID\tPrio\tStatus\tStack\t\t#\r\n"); #endif board_printf("------------------------------------------------------------"); - vTaskList((void *)buf); - board_printf(buf); + if((buf = (char *)pvPortMalloc(80*uxTaskGetNumberOfTasks())) != NULL) + { + vTaskList((void *)buf); + board_printf(buf); + vPortFree(buf); + } +} + +static void uif_cmd_kill(int argc, char **argv) +{ + xTaskHandle tid; + if(argc); + if((tid = xTaskGetTaskHandleFromName((const signed portCHAR *)argv[1])) == 0) + board_printf("Unknow task name\r\n"); + else + vTaskDelete(tid); +} + +static void uif_cmd_setpri(int argc, char **argv) +{ + xTaskHandle tid; + int success; + uint32 prio; + if(argc); + if((tid = xTaskGetTaskHandleFromName((const signed portCHAR *)argv[1])) == 0) + board_printf("Unknow task name\r\n"); + else + { + prio = get_value(argv[2], &success, 10); + if((prio > 0) && (prio < configMAX_PRIORITIES)) + vTaskPrioritySet(tid, (unsigned portBASE_TYPE)prio); + else + board_printf("Invalid priority value\r\n"); + } +} + +static void uif_cmd_resume(int argc, char **argv) +{ + xTaskHandle tid; + if(argc); + if((tid = xTaskGetTaskHandleFromName((const signed portCHAR *)argv[1])) == 0) + board_printf("Unknow task name\r\n"); + else + { + vTaskResume(tid); +#ifndef COLDFIRE + if(strcmp(argv[1], "TOS") == 0) + *(unsigned short *)vblsem = 1; +#endif + } +} + +static void uif_cmd_suspend(int argc, char **argv) +{ + xTaskHandle tid; + if(argc); + if((tid = xTaskGetTaskHandleFromName((const signed portCHAR *)argv[1])) == 0) + board_printf("Unknow task name\r\n"); + else + { +#ifndef COLDFIRE + if(strcmp(argv[1], "TOS") == 0) + *(unsigned short *)vblsem = 0; +#endif + vTaskSuspend(tid); + } } #if 0 @@ -2447,7 +2628,7 @@ static void uif_cmd_trace(int argc, char **argv) long file_w; int success; unsigned long val; - if(strcmp(argv[1],"on") == 0) + if(strcmp(argv[1], "on") == 0) { if(buffer_trace != NULL) { @@ -2480,7 +2661,7 @@ static void uif_cmd_trace(int argc, char **argv) } vTaskStartTrace(buffer_trace, size_trace); } - else if(strcmp(argv[1],"off") == 0) + else if(strcmp(argv[1], "off") == 0) { if(buffer_trace == NULL) { @@ -2500,10 +2681,12 @@ static void uif_cmd_trace(int argc, char **argv) buffer_trace = NULL; } else - board_printf("Usage : trace on/off \r\n"); + board_printf("Usage: trace on/off \r\n"); } #endif +#ifdef COLDFIRE /* BDOS */ + static void uif_cmd_cat(int argc, char **argv) { #define SIZE_BUFFER_CAT 10000 @@ -2800,6 +2983,8 @@ static void uif_cmd_rmdir(int argc, char **argv) board_printf("Cannot remove directory %s (error: %d)\r\n", argv[1], err); } +#endif /* COLDFIRE */ + /*---------------------------------------------------------------------*/ /* Fonction arp */ /*---------------------------------------------------------------------*/ @@ -2861,6 +3046,8 @@ static void uif_cmd_arp(int argc, char **argv) } } +#endif /* DBUG */ + /*---------------------------------------------------------------------*/ /* Fonction ifconfig */ /*---------------------------------------------------------------------*/ @@ -2954,7 +3141,7 @@ static void usage_ifconfig(void) board_printf(" [dstaddr
] [netmask
] [gateway
] [up|down]\r\n\n"); } -static void uif_cmd_ifconfig(int argc, char **argv) +void uif_cmd_ifconfig(int argc, char **argv) { #define IFNAMSIZ 4 char ifr_name[IFNAMSIZ]; @@ -3055,6 +3242,8 @@ static void uif_cmd_ifconfig(int argc, char **argv) } } +#ifdef DBUG + /*---------------------------------------------------------------------*/ /* Fonction ping */ /*---------------------------------------------------------------------*/ @@ -3148,7 +3337,9 @@ static int max, min, moyenne, envoye, perte; static void uif_cmd_ping(int argc, char **argv) { // Définition des différentes variables +#ifdef COLDFIRE unsigned long IP; +#endif struct ip_addr xIpAddr; int sock; struct sockaddr_in sin, from; @@ -3169,7 +3360,7 @@ static void uif_cmd_ping(int argc, char **argv) // Accès à l'aide if(argc < 2 || strcmp(argv[1],"--help") == 0) { - board_printf("Usage : ping <-n echos> <-w delay> host\r\n"); + board_printf("Usage: ping <-n echos> <-w delay> host\r\n"); return; } // Identification des différentes options @@ -3191,8 +3382,12 @@ static void uif_cmd_ping(int argc, char **argv) taille = sizeof(IpHeader) + sizeof(IcmpHeader); strcpy(ascii_IP, inet_ntoa(sin.sin_addr)); board_printf("Envoi d'une requete 'ping' sur %s avec %d octets de donnees :\r\n\r\n", ascii_IP, taille); +#ifdef COLDFIRE board_get_client((unsigned char *)&IP); xIpAddr.addr = htonl(IP); +#else + xIpAddr.addr = htonl(ip_addr_client); +#endif /* COLDFIRE */ if(sin.sin_addr.s_addr == xIpAddr.addr) sin.sin_addr.s_addr = INADDR_LOOPBACK; // Initialisation du nombre de ping à faire @@ -3319,8 +3514,10 @@ static void uif_cmd_ping(int argc, char **argv) } memset(recvbuf,0,MAX_PACKET); } +#ifdef COLDFIRE if(auxistat() && ((rs232get() & 0xFF) == CTRL_C)) Nbping = envoye; +#endif } while(findelai == 0); // Latence d'une seconde entre chaque ping @@ -3361,6 +3558,8 @@ static unsigned short checksum(unsigned short *buffer, int size) return (unsigned short)(~cksum); } +#ifdef COLDFIRE + static void uif_cmd_stats(int argc, char **argv) { if(argc); @@ -3381,7 +3580,7 @@ static void uif_cmd_cache(int argc, char **argv) board_printf("CACR: 0x%08X\r\n", cacr); } else - board_printf("Usage : cache \r\n"); + board_printf("Usage: cache \r\n"); } static void uif_cmd_debug(int argc, char **argv) @@ -3411,15 +3610,17 @@ static void uif_cmd_debug(int argc, char **argv) *(unsigned char *)(debug_cf68klib) = *(unsigned char *)(debug_cf68klib_count) = 0; } else - board_printf("Usage : debug on/off\r\n"); + board_printf("Usage: debug on/off\r\n"); } static void uif_cmd_inter(int argc, char **argv) { +#ifndef MCF547X if((argc == 2) && strcmp(argv[1],"on") == 0) install_inters_cf68klib(); else if((argc == 2) && strcmp(argv[1],"off") == 0) - deinstall_inters_cf68klib(); + uninstall_inters_cf68klib(); +#endif #ifdef MCF5445X else if((argc == 2) && strcmp(argv[1],"abort") == 0) { @@ -3433,8 +3634,9 @@ static void uif_cmd_inter(int argc, char **argv) vPortSetIPL(level); } else - board_printf("Usage : inter on/off/abort\r\n"); + board_printf("Usage: inter on/off/abort\r\n"); #else /* MCF548X */ +#ifndef MCF547X else if((argc == 2) && strcmp(argv[1],"abort") == 0) { int level = vPortSetIPL(portIPL_MAX); @@ -3447,6 +3649,7 @@ static void uif_cmd_inter(int argc, char **argv) vPortSetIPL(level); } else if(argc < 2) +#endif /* MCF547X */ { static char *names_int[] = { "", /* 64 */ @@ -3464,6 +3667,25 @@ static void uif_cmd_inter(int argc, char **argv) "", /* 76 */ "", /* 77 */ "", /* 78 */ +#ifdef MCF547X /* interrupts not used on FIREBEE */ + "", /* 79 */ + "", /* 80 */ + "", /* 81 */ + "", /* 82 */ + "", /* 83 */ + "", /* 84 */ + "", /* 85 */ + "", /* 86 */ + "", /* 87 */ + "", /* 88 */ + "", /* 89 */ + "", /* 90 */ + "", /* 91 */ + "", /* 92 */ + "", /* 93 */ + "", /* 94 */ + "", /* 95 */ +#else "USB 2.0", /* 79 */ "USB 2.0", /* 80 */ "USB 2.0", /* 81 */ @@ -3481,13 +3703,19 @@ static void uif_cmd_inter(int argc, char **argv) "DSPI", /* 93 */ "DSPI", /* 94 */ "DSPI", /* 95 */ +#endif "PSC3", /* 96 */ "PSC2", /* 97 */ "PSC1", /* 98 */ "PSC0", /* 99 */ "Comm Timer", /* 100 */ +#ifdef MCF547X /* not used on FIREBEE */ + "", /* 101 */ + "", /* 102 */ +#else "SEC", /* 101 */ "FEC1", /* 102 */ +#endif "FEC0", /* 103 */ "I2C", /* 104 */ "PCIARB", /* 105 */ @@ -3532,27 +3760,36 @@ static void uif_cmd_inter(int argc, char **argv) { if(strlen(names_int[i])) { + unsigned long imr, imr_tos; + int j; if(i < 32) - board_printf("%s\t\t%s\t\t%d\t%d\t%s Int(%d)\r\n", - !(save_imrl & (1 << i)) ? "ON" : "OFF", - !(save_imrl_tos & (1 << i)) ? "ON" : "OFF", - (MCF_INTC_ICRn(i) >> 3) & 7, MCF_INTC_ICRn(i) & 7, - names_int[i], i + 64); + { + imr = save_imrl; + imr_tos = save_imrl_tos; + j = i; + } else - board_printf("%s\t\t%s\t\t%d\t%d\t%s Int(%d)\r\n", - !(save_imrh & (1 << (i - 32))) ? "ON" : "OFF", - !(save_imrh_tos & (1 << (i - 32))) ? "ON" : "OFF", - (MCF_INTC_ICRn(i) >> 3) & 7, MCF_INTC_ICRn(i) & 7, - names_int[i], i + 64); + { + imr = save_imrh; + imr_tos = save_imrh_tos; + j = i - 32; + } + board_printf("%s\t\t%s\t\t%d\t%d\t%s Int(%d)\r\n", + !(imr & (1 << j)) ? "ON" : "OFF", + !(imr_tos & (1 << j)) ? "ON" : "OFF", + (MCF_INTC_ICRn(i) >> 3) & 7, MCF_INTC_ICRn(i) & 7, + names_int[i], i + 64); } } } +#ifndef MCF547X else - board_printf("Usage : inter \r\n"); + board_printf("Usage: inter \r\n"); +#endif #endif /* MCF5445X */ } -static void uif_cmd_reset(int argc, char **argv) +void uif_cmd_reset(int argc, char **argv) { if(argc); if(argv); @@ -3572,7 +3809,8 @@ static void uif_cmd_reset(int argc, char **argv) #endif /* MCF5445X */ while(1) { - asm volatile(" nop\n\t"); + asm volatile(" nop\n\t"); + MCF_UART_UTB(0) = '.'; } } @@ -3603,9 +3841,11 @@ static void uif_cmd_trap(int argc, char **argv) *(unsigned char *)(debug_trap) = *(unsigned char *)(debug_trap_count) = 0; } else - board_printf("Usage : trap on/off\r\n"); + board_printf("Usage: trap on/off\r\n"); } +#endif /* COLDFIRE */ + static UIF_CMD UIF_CMDTAB[] = { /* <1> command name user types, ie. GO */ @@ -3616,26 +3856,37 @@ static UIF_CMD UIF_CMDTAB[] = /* <6> actual function to call */ /* <7> brief description of command */ /* <8> syntax of command */ -#ifndef MCF5445X -#ifdef SOUND_AC97 +#if defined(COLDFIRE) && !defined(MCF5445X) && defined(SOUND_AC97) {"acpr",4,1,2,0,uif_cmd_ac97_pr,"AC97 Patch Register","addr "}, #endif -#endif -#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#if defined(COLDFIRE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) {"usb",3,0,4,0,uif_cmd_usb,"USB sub-system",""}, #endif +#ifdef COLDFIRE {"cb",2,0,1,0,uif_cmd_cb,"Clear Breakpoint",""}, {"db",2,0,UIF_MAX_ARGS-1,0,uif_cmd_db,"Define Breakpoint"," <-c|t value> <-r addr..> <-i> <-m>"}, +#endif /* COLDFIRE */ {"dm",2,0,2,UIF_CMD_FLAG_REPEAT,uif_cmd_md,"Display Memory","begin "}, {"md",2,0,2,UIF_CMD_FLAG_REPEAT|UIF_CMD_FLAG_HIDDEN,uif_cmd_md,"Memory Display","begin "}, {"dis",2,0,1,UIF_CMD_FLAG_REPEAT,uif_cmd_dis,"Disassemble",""}, +#ifdef COLDFIRE {"dr",2,0,0,0,uif_cmd_dr,"Display Registers CF68KLIB",""}, {"go",1,0,1,0,uif_cmd_go,"Execute, Insert Breakpt",""}, {"lb",2,0,0,0,uif_cmd_lb,"List Breakpoints",""}, +#else /* !COLDFIRE */ + {"dr",2,0,0,0,uif_cmd_dr,"Display Registers (context)",""}, +#endif /* COLDFIRE */ {"pm",2,1,2,0,uif_cmd_pm,"Patch Memory","addr "}, {"qt",2,0,0,UIF_CMD_FLAG_REPEAT,uif_cmd_qt,"Query Tasks",""}, +#ifdef COLDFIRE {"st",2,0,1,UIF_CMD_FLAG_REPEAT,uif_cmd_st,"Single Step (after db)",""}, +#endif + {"kill",4,1,1,0,uif_cmd_kill,"Kill Task","task_name"}, + {"setpri",6,2,2,0,uif_cmd_setpri,"Set Priority Task","task_name priority"}, + {"resume",6,1,1,0,uif_cmd_resume,"Resume Task","task_name"}, + {"suspend",7,1,1,0,uif_cmd_suspend,"Suspend Task","task_name"}, // {"trace",2,1,3,0,uif_cmd_trace,"Task Trace","on/off "}, +#ifdef COLDFIRE {"cat",2,1,UIF_MAX_ARGS-1,0,uif_cmd_cat,"Concatenate File(s)","file(s)"}, {"cd",2,1,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_chdir,"Change Directory","dir"}, {"chdir",2,1,1,0,uif_cmd_chdir,"Change Directory","dir"}, @@ -3651,16 +3902,23 @@ static UIF_CMD UIF_CMDTAB[] = {"rm",2,1,1,0,uif_cmd_rm,"Remove File","file"}, {"rmdir",2,1,1,0,uif_cmd_rmdir,"Remove Directory","dir"}, {"type",4,1,UIF_MAX_ARGS-1,UIF_CMD_FLAG_HIDDEN,uif_cmd_cat,"Concatenate File(s)","file(s)"}, +#endif /* COLDFIRE */ {"arp",2,0,2,0,uif_cmd_arp,"Address Resol. Protocol","<-a> "}, {"ifconfig",2,0,UIF_MAX_ARGS-1,0,uif_cmd_ifconfig,"Interface Configuration","<-a> ..."}, {"ping",2,1,5,0,uif_cmd_ping,"Ping","<-n echos> <-w delay> host"}, +#ifdef COLDFIRE {"netstat",2,0,0,0,uif_cmd_stats,"Network Stats",""}, {"cache",2,0,1,0,uif_cmd_cache,"Cache",""}, {"debug",2,1,2,0,uif_cmd_debug,"Debug CF68KLIB","on/off "}, +#ifdef MCF547X + {"inter",1,0,1,0,uif_cmd_inter,"Interrupts CF68KLIB",""}, +#else {"inter",2,0,1,0,uif_cmd_inter,"Interrupts CF68KLIB",""}, +#endif {"reset",5,0,0,0,uif_cmd_reset,"System Reset",""}, {"shutdown",8,0,0,UIF_CMD_FLAG_HIDDEN,uif_cmd_reset,"System Reset",""}, {"trap",4,1,2,0,uif_cmd_trap,"Traps CF68KLIB","on/off "}, +#endif /* COLDFIRE */ {"help",2,0,1,0,uif_cmd_help,"Help",""}, }; static const int UIF_NUM_CMD = UIF_CMDTAB_SIZE; @@ -3763,6 +4021,8 @@ static int make_argv(char *cmdline, char *argv[]) return argc; } +#ifdef COLDFIRE + static int run_cmd(void) { /* Global array of pointers to emulate C argc,argv interface */ @@ -4102,13 +4362,17 @@ static portTASK_FUNCTION(vTFTPd, pvParameters) } } +#endif /* COLDFIRE */ + /*---------------------------------------------------------------------*/ /* Telnet Server */ /*---------------------------------------------------------------------*/ static void sendopt(struct termstate *ts, int code, int option) { + static char *codename[4] = {"WILL", "WONT", "DO", "DONT"}; unsigned char buf[3]; + printf_debug("TELNETd: sendopt %s %d\r\n", codename[code - 251], option); buf[0] = TELNET_IAC; buf[1] = (unsigned char) code; buf[2] = (unsigned char) option; @@ -4117,6 +4381,8 @@ static void sendopt(struct termstate *ts, int code, int option) static void parseopt(struct termstate *ts, int code, int option) { + static char *codename[4] = {"WILL", "WONT", "DO", "DONT"}; + printf_debug("TELNETd: parseopt %s %d\r\n", codename[code - 251], option); switch(option) { case TELOPT_ECHO: @@ -4143,6 +4409,7 @@ static void parseopt(struct termstate *ts, int code, int option) static void parseoptdat(struct termstate *ts, int option, unsigned char *data, int len) { + printf_debug("TELNETd: OPTION %d data (%d bytes)\r\n", option, len); switch(option) { case TELOPT_NAWS: @@ -4226,6 +4493,7 @@ static void parse(struct termstate *ts) static portTASK_FUNCTION(vTELNETd, pvParameters) { + char ascii_IP[16]; struct sockaddr_in sin; fd_set fdsr; struct timeval tv_timeout; @@ -4238,13 +4506,14 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) ts = (struct termstate *)pvPortMalloc(sizeof(struct termstate)); if(ts == NULL) { - printD("TELNETd: malloc error\r\n"); + printf_debug("TELNETd: malloc error\r\n"); vTaskDelete(0); } sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { - printD("TELNETd: error %d in socket\r\n", errno); + printf_debug("TELNETd: error %d in socket\r\n", errno); + vPortFree(ts); vTaskDelete(0); } sin.sin_family = AF_INET; @@ -4253,28 +4522,34 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) rc = bind(sock, (struct sockaddr *) &sin, sizeof sin); if(rc < 0) { - printD("TELNETd: error %d in bind\r\n", errno); + printf_debug("TELNETd: error %d in bind\r\n", errno); + vPortFree(ts); vTaskDelete(0); } rc = listen(sock, 5); if(rc < 0) { - printD("TELNETd: error %d in listen\r\n", errno); + printf_debug("TELNETd: error %d in listen\r\n", errno); close(sock); + vPortFree(ts); vTaskDelete(0); } while(1) { int off = 0; + int timeout = 0; struct sockaddr_in sin; int len = sizeof(sin); s = accept(sock, (struct sockaddr *)&sin, &len); if(s < 0) { - printD("TELNETd: error %d in accept\r\n", errno); + printf_debug("TELNETd: error %d in accept\r\n", errno); close(sock); + vPortFree(ts); vTaskDelete(0); } + strcpy(ascii_IP, inet_ntoa(sin.sin_addr)); + printf_debug("TELNETd: accept %s\r\n", ascii_IP); setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&off, sizeof(off)); /* Initialize terminal state */ memset(ts, 0, sizeof(struct termstate)); @@ -4285,6 +4560,9 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) ts->term.lines = 25; /* Send initial options */ sendopt(ts, TELNET_WILL, TELOPT_ECHO); + sendopt(ts, TELNET_WILL, TELOPT_SUPPRESS_GO_AHEAD); + sendopt(ts, TELNET_WONT, TELOPT_LINEMODE); + sendopt(ts, TELNET_DO, TELOPT_NAWS); ts->bo.start = ts->bo.data; board_putchar_flush(); board_printf(PROMPT); @@ -4297,14 +4575,26 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) tv_timeout.tv_usec = 0; if((i = select(FD_SETSIZE, &fdsr, NULL, NULL, &tv_timeout)) == -1) { - printD("TELNETd: error %d in select\r\n", errno); + printf_debug("TELNETd: error %d in select\r\n", errno); done: close(ts->sock); ts->sock = -1; break; } + if(!i) + { + timeout++; + if(timeout > 60) + { + printf_debug("TELNETd: timeout\r\n"); + close(ts->sock); + ts->sock = -1; + break; + } + } if((i > 0) && FD_ISSET(ts->sock, &fdsr)) { + timeout = 0; if(ts->bi.start == ts->bi.end) { /* Read data from user */ @@ -4332,9 +4622,7 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) if(pos > 0) { pos -= 1; -// board_putchar(0x08); /* backspace */ -// board_putchar(' '); -// board_putchar(0x08); /* backspace */ + board_printf("%c", (char)ch); } break; default: @@ -4344,14 +4632,17 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) if((ch > 0x1f) && (ch < 0x80)) { cmdline1[pos++] = (char)ch; -// board_putchar((char)ch); + board_printf("%c", (char)ch); } } break; } + board_putchar_flush(); } else { + if(((j + 1) < n) && (ch == '\r') && (ts->bi.start[j + 1] == '\n')) + j++; cmdline1[pos] = '\0'; board_putchar('\r'); board_putchar('\n'); @@ -4421,6 +4712,8 @@ static portTASK_FUNCTION(vTELNETd, pvParameters) } } +#ifdef COLDFIRE + static void *test_debug_fault(unsigned long address, unsigned long vector, unsigned char *RegList) { #ifndef MCF547X @@ -4491,8 +4784,8 @@ static void *test_debug_fault(unsigned long address, unsigned long vector, unsig #endif else if(pxCurrentTCB == tid_DEBUG) restart_debug = 1; - vTaskDelete(0); - while(1); + vTaskDelete(0); /* no return */ + return(NULL); } static portTASK_FUNCTION(vDEBUG, pvParameters) @@ -4500,12 +4793,6 @@ static portTASK_FUNCTION(vDEBUG, pvParameters) /* The parameters are not used in this function */ (void)pvParameters; *(unsigned long *)(handler_fault) = (unsigned long)test_debug_fault; - BASE = 16; - md_last_address = 0; - md_last_size = 0; - disasm_last_address = 0; - cmdline1[0] = cmdline2[0] = '\0'; - history_init(); while(1) { board_putchar_flush(); @@ -4515,12 +4802,22 @@ static portTASK_FUNCTION(vDEBUG, pvParameters) } } +#endif /* COLDFIRE */ + static void start_debug(vid) { + BASE = 16; + md_last_address = 0; + md_last_size = 0; + disasm_last_address = 0; + cmdline1[0] = cmdline2[0] = '\0'; +#ifdef COLDFIRE + history_init(); xTaskCreate(vDEBUG, (void *)"DBUG", STACK_DEFAULT, NULL, DEBUG_TASK_PRIORITY, &tid_DEBUG); +#endif /* COLDFIRE */ } -#endif +#endif /* DBUG */ static int geterrno(void) { @@ -4554,13 +4851,15 @@ static SOCKET_COOKIE sc = geterrno }; +#ifdef COLDFIRE + void start_servers(void) { #ifdef DBUG xTaskCreate(vTELNETd, (void *)"TELNETd", STACK_DEFAULT, NULL, TELNET_TASK_PRIORITY, &tid_TELNET); #endif #ifdef FTP_SERVER - xTaskCreate(vFTPd, (void *)"FTPd", STACK_DEFAULT, NULL, FTP_TASK_PRIORITY, NULL); + xTaskCreate(vFTPd, (void *)"FTPd", STACK_DEFAULT, NULL, FTP_TASK_PRIORITY, NULL); #endif xTaskCreate(vTFTPd, (void *)"TFTPd", STACK_DEFAULT, NULL, TFTP_TASK_PRIORITY, NULL); /* Start the webserver */ @@ -4568,13 +4867,22 @@ void start_servers(void) } void init_lwip(void) +#else /* !COLDFIRE */ +void init_lwip(unsigned long ip_addr, unsigned long mask_addr, unsigned long gateway_addr) +#endif /* COLDFIRE */ { - unsigned long IP; struct ip_addr xIpAddr, xNetMast, xGateway; - static struct netif loop_if, fec54xx0_if; + static struct netif loop_if; +#ifdef COLDFIRE + unsigned long IP; + static struct netif fec54xx0_if; #ifndef MCF547X static struct netif fec54xx1_if; #endif +#else /* !COLDFIRE */ + static struct netif rtl8139_if; + ip_addr_client = ip_addr; +#endif /* COLDFIRE */ errno = 0; /* Initialize lwIP and its interface layer */ sys_init(); @@ -4585,9 +4893,11 @@ void init_lwip(void) ip_init(); tcpip_init(NULL, NULL); socket_init(); +#ifdef COLDFIRE board_get_server((unsigned char *)&IP); xIpAddr.addr = htonl(IP); // not used actually // => DNS_SERVER_ADDRESS in dns.c +#endif /* Initialize the loopback interface structure */ xIpAddr.addr = INADDR_LOOPBACK; xGateway.addr = 0; @@ -4599,6 +4909,7 @@ void init_lwip(void) /* bring it up */ netif_set_up(&loop_if); } +#ifdef COLDFIRE else { board_printf("Loopback init error\r\n"); @@ -4648,7 +4959,7 @@ void init_lwip(void) while(1) vTaskDelay(1); } -#endif +#endif /* MCF547X */ #endif enable_caches(); #ifdef DBUG @@ -4656,13 +4967,28 @@ void init_lwip(void) #endif #ifdef MCF547X if(MCF_GPIO_PPDSDR_PSC3PSC2 & MCF_GPIO_PPDSDR_PSC3PSC2_PPDSDR_PSC3PSC27) -#endif +#endif /* MCF547X */ { start_servers(); } +#else /* !COLDFIRE */ + /* Initialize the network interface structure */ + xIpAddr.addr = ip_addr; + xGateway.addr = gateway_addr; + xNetMast.addr = mask_addr; + if(netif_add(&rtl8139_if, &xIpAddr, &xNetMast, &xGateway, NULL, rtl8139if_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&rtl8139_if); + /* bring it up */ + netif_set_up(&rtl8139_if); + } +#endif /* COLDFIRE */ lwip_ok = 1; } +#ifdef COLDFIRE + static portTASK_FUNCTION(vTOS, pvParameters) { void (*return_address)(void) = (void (*)(void))pvParameters; @@ -4673,6 +4999,10 @@ static portTASK_FUNCTION(vTOS, pvParameters) static portTASK_FUNCTION(vROOT, pvParameters) { +#ifdef MCF547X + extern short swi; + int shutdown_ethernet = 0; +#endif #ifdef USB_DEVICE #ifndef MCF5445X #ifndef MCF547X @@ -4685,12 +5015,12 @@ static portTASK_FUNCTION(vROOT, pvParameters) extern void hbl_int(void); extern unsigned long get_timer(void); int tick_count = 0; - unsigned long start_timer = get_timer(); + unsigned long start_timer = get_timer(); int level = vPortSetIPL(portIPL_MAX); old_hbl = *(unsigned long *)((64+2)*4 + coldfire_vector_base); *(unsigned long *)((64+2)*4 + coldfire_vector_base) = (unsigned long)hbl_int; MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE2; - MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF2; /* clear interrupt */ + MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF2; /* clear interrupt */ MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK2; /* enable interrupt */ asm_set_ipl(level); #endif /* MCF547X */ @@ -4702,6 +5032,8 @@ static portTASK_FUNCTION(vROOT, pvParameters) #endif #endif #endif + vSemaphoreCreateBinary(xSemaphoreBDOS); + xQueueAlert = xQueueCreate(2, 256); restart_debug = 0; init_lwip(); xTaskCreate(vTOS, (void *)"TOS", STACK_DEFAULT, pvParameters, TOS_TASK_PRIORITY, &tid_TOS); @@ -4765,11 +5097,19 @@ static portTASK_FUNCTION(vROOT, pvParameters) #endif /* CONFIG_USB_INTERRUPT_POLLING */ } #endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI */ +#ifndef MCF5445X + /* enable XLB PCI for all tasks */ + if((save_imrh & (1 << 11)) && !(save_imrh_tos & (1 << 11))) + { + int level = asm_set_ipl(7); /* disable interrupts */ + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK43; /* enable interrupt */ + asm_set_ipl(level); + } +#endif /* MCF5445X */ #ifdef MCF547X if(boot_os) { unsigned long start_addr = 0; - extern short swi; switch(boot_os) { case 1: @@ -4784,26 +5124,60 @@ static portTASK_FUNCTION(vROOT, pvParameters) else if(tid_HTTPd == NULL) #endif start_servers(); - break; + break; } if(start_addr) - { - if(*(short *)start_addr == 0x602E) + { + if(*(short *)start_addr == 0x602E) go_emutos(start_addr); boot_os = 0; } } -#endif + else if(!shutdown_ethernet && lwip_ok && drive_ok + && (!(swi & 0x40) || !(swi & 1)) /* !SW5 (UP) */ + && !(swi & 0x80)) /* !SW6 (UP) */ + { /* TOS for MiNT */ + COOKIE *mint_cookie = *(COOKIE **)cookie; + while(mint_cookie != NULL) + { + if(mint_cookie->ident == 'MiNT') + { + COOKIE *eth_cookie = *(COOKIE **)cookie; + extern void fec_eth_stop(uint8 ch); + board_printf("Shutdown FEC...\r\n"); + fec_eth_stop(0); + while(eth_cookie != NULL) + { + if((eth_cookie->ident == 'SOCK') || (eth_cookie->ident == 'STiK')) + { + eth_cookie->ident = 'NULL'; + eth_cookie->v.l = 0; + } + if(!eth_cookie->ident) + eth_cookie = NULL; + else + eth_cookie++; + } + shutdown_ethernet = 1; + break; + } + if(!mint_cookie->ident) + mint_cookie = NULL; + else + mint_cookie++; + } + } +#endif /* MCF547X */ #if 0 // #ifdef MCF547X tick_count++; if(tick_count > configTICK_RATE_HZ*10) { - unsigned long time = get_timer(); - board_printf("VBL interval %d uS (%d %d)\r\n", (int)((time - start_timer)/(hbl_count * SYSTEM_CLOCK)), hbl_count, (time - start_timer)/SYSTEM_CLOCK); + unsigned long time = get_timer(); + board_printf("VBL interval %d uS (%d %d)\r\n", (int)((time - start_timer)/(hbl_count * SYSTEM_CLOCK)), hbl_count, (time - start_timer)/SYSTEM_CLOCK); level = vPortSetIPL(portIPL_MAX); - start_timer = get_timer(); + start_timer = get_timer(); tick_count = 0; - hbl_count = 0; + hbl_count = 0; asm_set_ipl(level); } #endif @@ -4869,12 +5243,20 @@ int usb_load_files(void) #endif /* USB_DEVICE */ } +#endif /* COLDFIRE */ + int init_network(void) { extern DRV_LIST stik_driver; extern int gs_init_stik_if(void); extern int gs_init_mem(void); COOKIE pck; +#if defined(COLDFIRE) && !defined(MCF5445X) + extern char dma_cf_cookie[]; + pck.ident = 'DMAC'; + pck.v.l = (long)&dma_cf_cookie; + add_cookie(&pck); +#endif /* defined(COLDFIRE) && !defined(MCF5445X) */ if(!lwip_ok) return(FALSE); pck.ident = 'SOCK'; @@ -4888,6 +5270,8 @@ int init_network(void) return(TRUE); } +#ifdef COLDFIRE + int init_rtos(void *params) { extern unsigned char _bss_start_freertos[]; @@ -4901,16 +5285,232 @@ int init_rtos(void *params) #ifdef MCF547X tid_ETOS = NULL; boot_os = 0; + drive_ok = 0; #endif start_run = NULL; lwip_ok = get_serial_vector = get_ikbd_vector = tos_suspend = 0; *(unsigned short *)_timer_ms = 0; - vSemaphoreCreateBinary(xSemaphoreBDOS); init_dma(); - xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, params, ROOT_TASK_PRIORITY, NULL); - vTaskStartScheduler(); + if(xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, params, ROOT_TASK_PRIORITY, NULL) == pdPASS) + vTaskStartScheduler(); return 0; } +#endif /* COLDFIRE */ + #endif /* LWIP */ -#endif /* NETWORK */ + +#if !defined(COLDFIRE) && defined(FREERTOS) + +extern short ethernet_found, drive_ok, os_magic; +xTaskHandle pxCurrentTCB, tid_TOS; +xQueueHandle xQueueAlert; +portBASE_TYPE xNeedSwitchPCI; /* drivers must use this variable */ +unsigned long __FREERTOS_BASE[configTOTAL_HEAP_SIZE>>2]; /* heap_2.c */ +short OldBoot; +static unsigned long pcibios_callback[4], old_vector[4]; + +void pci_int(portBASE_TYPE num) +{ + xNeedSwitchPCI = pdFALSE; + if((num >= 0) && (num <= 3)) + { + void (*f)(long num) = (void (*)(long))pcibios_callback[num]; + if(f != NULL) + f(num + 1); + } +} + +static void pci_inta_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t" ); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " clr.l -(SP)\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static void pci_intb_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t"); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " pea 1\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static void pci_intc_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t"); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " pea 2\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static void pci_intd_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t"); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " pea 3\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static portTASK_FUNCTION(vTOS, pvParameters) +{ + /* The parameters are not used in this function */ + (void)pvParameters; + asm volatile(" jmp _goto_tos"); +} + +static portTASK_FUNCTION(vROOT, pvParameters) +{ + int shutdown_ethernet = 0, count = 0, vectors_ok = 0; + int i, level; + if(pvParameters); + xQueueAlert = xQueueCreate(2, 256); + xTaskCreate(vTOS, (void *)"TOS", STACK_DEFAULT, NULL, TOS_TASK_PRIORITY, &tid_TOS); +#ifdef DBUG + start_debug(); +#endif + while(1) + { + if(ethernet_found && drive_ok && !vectors_ok) + { + level = portSET_IPL(portIPL_MAX); + for(i = 0; i < 4; i++) + { + unsigned long *vector = (unsigned long *)*(unsigned long *)((PCI_IRQ_BASE_VECTOR + i + 1) * 4); + if((vector[-2] == '_PCI') && (vector[-3] == 'XBRA') && (vector[-5] == '_PCI')) /* extra code for FreeRTOS subroutine */ + { + OldBoot = 0; + pcibios_callback[i] = vector[-4]; + old_vector[i] = *(unsigned long *)((PCI_IRQ_BASE_VECTOR + i + 1) * 4); + if(ethernet_found) + { + switch(i) + { + case 0: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 1) * 4) = (unsigned long)pci_inta_int; break; + case 1: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 2) * 4) = (unsigned long)pci_intb_int; break; + case 2: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 3) * 4) = (unsigned long)pci_intc_int; break; + case 3: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 4) * 4) = (unsigned long)pci_intd_int; break; + } + } + } + } + portSET_IPL(level); +#ifdef DBUG + xTaskCreate(vTELNETd, (void *)"TELNETd", STACK_DEFAULT, NULL, TELNET_TASK_PRIORITY, &tid_TELNET); +#endif + vectors_ok = 1; + } + if(!shutdown_ethernet) + { + COOKIE *mint_cookie = *(COOKIE **)cookie; + while(mint_cookie != NULL) + { + if(mint_cookie->ident == 'MiNT') + { + extern void rtl8139_eth_stop(uint8 ch); + COOKIE *eth_cookie = *(COOKIE **)cookie; + if(ethernet_found) + rtl8139_eth_stop(0); + while(eth_cookie != NULL) + { + if((eth_cookie->ident == 'SOCK') || (eth_cookie->ident == 'STiK')) + { + eth_cookie->ident = 'NULL'; + eth_cookie->v.l = 0; + } + if(!eth_cookie->ident) + eth_cookie = NULL; + else + eth_cookie++; + } + /* restore boot PCI BIOS vectors */ + { + int i, level = portSET_IPL(portIPL_MAX); + for(i = 0; i < 4; i++) + { + if(old_vector[i]) + { + *(unsigned long *)((PCI_IRQ_BASE_VECTOR + i + 1) * 4) = old_vector[i]; + old_vector[i] = 0; + } + } + portSET_IPL(level); + } + shutdown_ethernet = 1; + ethernet_found = 0; + break; + } + if(!mint_cookie->ident) + mint_cookie = NULL; + else + mint_cookie++; + } + } +#if 0 + if(ethernet_found) + { + extern void led_floppy(long state); + if(!count) + led_floppy(1); + else if(count == configTICK_RATE_HZ) + led_floppy(0); + } +#endif + count++; + if(count >= configTICK_RATE_HZ*2) + count = 0; + vTaskDelay(1); + } +} + +int init_rtos(void) /* CT60 / CTPCI */ +{ + pxCurrentTCB = tid_TELNET = tid_TOS = NULL; + OldBoot = 1; + if(xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, NULL, ROOT_TASK_PRIORITY, NULL) == pdPASS) + vTaskStartScheduler(); + return(0); +} + +#endif /* !defined(COLDFIRE) && defined(FREERTOS) */ diff --git a/flash.tos/drivers/lwip/init.c.ok b/flash.tos/drivers/lwip/init.c.ok new file mode 100644 index 0000000..1371cab --- /dev/null +++ b/flash.tos/drivers/lwip/init.c.ok @@ -0,0 +1,5260 @@ +/* ------------------------ System includes ------------------------------- */ +#include +#include +#include +#include + +/* ------------------------ Platform includes ----------------------------- */ +#include "config.h" +#ifdef COLDFIRE +#include "net.h" +#ifdef MCF5445X +#include "mcf5445x.h" +#define MCF_UART_USR_RXRDY UART_USR_RXRDY +#define MCF_UART_USR_TXRDY UART_USR_TXRDY +#else +#include "mcf548x.h" +#endif /* MCF5445X */ +#include "get.h" +#include "m68k_disasm.h" +#include "../../include/ramcf68k.h" +#include "../../include/vars.h" +#ifndef MCF5445X +#ifdef SOUND_AC97 +#include "../ac97/mcf548x_ac97.h" +#endif +#ifdef MCF547X +#define AC97_DEVICE 2 /* FIREBEE */ +#else /* MCF548X */ +#define AC97_DEVICE 3 /* M5484LITE */ +#endif /* MCF547X */ +#endif /* MCF5445X */ +#else /* ! COLDFIRE */ +#include +#include "ct60.h" +#define cookie 0x5A0 +#endif /* COLDFIRE */ + +/* ------------------------ FreeRTOS includes ----------------------------- */ +#include "../freertos/FreeRTOS.h" +#include "../freertos/task.h" +#include "../freertos/semphr.h" + +/* ------------------------ lwIP includes --------------------------------- */ +#include "api.h" +#include "tcpip.h" +#include "memp.h" +#include "stats.h" +#include "loopif.h" +#include "etharp.h" +#include "resolv.h" +#include "err.h" +#include "sockets.h" +#include "netdb.h" +#include "tftp.h" +#include "web.h" +#include "usb.h" +#undef int8 +#undef uint8 +#undef int16 +#undef uint16 +#undef int32 +#undef uint32 +#include "transprt.h" + +/* ------------------------ BDOS includes ----------------------------------*/ +/* cannot use TOS trap out of CF68KLIB !!! */ +#ifdef COLDFIRE +#include "../bdos/bdos.h" +#endif + +/* ------------------------ Defines --------------------------------------- */ +#undef KILL_TOS_ON_FAULT /* for debug */ + +/* Priorities for the demo application tasks. */ +#define TOS_TASK_PRIORITY ( 5 ) +#define RTC_TASK_PRIORITY ( 6 ) +#define VBL_TASK_PRIORITY ( 25 ) +#define WEB_TASK_PRIORITY ( 10 ) +#define FTP_TASK_PRIORITY ( 10 ) +#define TFTP_TASK_PRIORITY ( 10 ) +#define TELNET_TASK_PRIORITY ( 15 ) +#define DEBUG_TASK_PRIORITY ( 20 ) +#ifdef COLDFIRE +#define ROOT_TASK_PRIORITY ( 10 ) +#define STACK_DEFAULT ( 4096 ) +#else /* !COLDFIRE */ +#define STACK_DEFAULT ( 2048 ) +#define INTPCI_TASK_PRIORITY ( 30 ) +#define ROOT_TASK_PRIORITY ( 31 ) +#undef SWITCH_CONTEXT +#endif /* COLDFIRE */ + +typedef struct +{ + long ident; + union + { + long l; + short i[2]; + char c[4]; + } v; +} COOKIE; + +#ifdef LWIP + +#define FTP_USERNAME "coldfire" +#define FTP_PASSWORD "atari" + +#define SIZE_8 (8) +#define SIZE_16 (16) +#define SIZE_32 (32) +#define SIZE_64 (64) +#define ILLEGAL (0x4AFC) +#define DEFAULT_MD_LINES (8) +#define UIF_MAX_ARGS (10) +#define UIF_MAX_LINE (72) +#define UIF_MAX_BRKPTS (16) +#define UIF_CMDTAB_SIZE (sizeof(UIF_CMDTAB)/sizeof(UIF_CMD)) +#define UIF_CMD_FLAG_REPEAT (0x0001) +#define UIF_CMD_FLAG_HIDDEN (0x0002) + +#define MAX_HISTORY (5) +#define CTRL_C 0x03 +#define CTRL_D 0x04 /* command line next */ +#define CTRL_U 0x15 /* command line previous */ +#define CTRL_R 0x12 /* last command repeat */ + +/* ------------------------ PCI ------------------------------------------- */ +#if defined(COLDFIRE) && defined(MCF547X) /* for start Emutos and recreate PCI cookie */ +#ifndef PCI_COOKIE_TOTALSIZE /* #include ../../include/pci_bios.h create problems */ +#define PCI_MAX_BUS 4 +#define PCI_MAX_FUNCTION 4 /* 4 functions per PCI slot */ +#define PCI_MAX_DEVICE 32 +#define PCI_DEV_DES_SIZE 20 +#define PCI_RSC_DESC_SIZE 24 +#define PCI_RSC_DESC_TOTALSIZE (PCI_RSC_DESC_SIZE*6) +#define PCI_COOKIE_ROUTINE 8 /* offset PCI BIOS routines */ +#define PCI_COOKIE_MAX_ROUTINES 45 /* maximum of routines */ +#define PCI_COOKIE_SIZE ((4*PCI_COOKIE_MAX_ROUTINES)+PCI_COOKIE_ROUTINE) +#define PCI_RSC_HANDLESTOTALSIZE (PCI_RSC_DESC_TOTALSIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_DEV_HANDLESTOTALSIZE (PCI_DEV_DES_SIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_INT_HANDLESTOTALSIZE (PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_COOKIE_TOTALSIZE (PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE*2) +#endif +#endif /* defined(COLDFIRE) && defined(MCF547X) */ + +/* ------------------------ TFTP ------------------------------------------ */ +#define TimeOut 2 /* seconds */ +#define NumberTimeOut 3 /* retries */ +#define PortTFTP 69 +#define TFTP_READ 0 +#define TFTP_WRITE 1 + +/* Trivial File Transfer Protocol (IEN-133) */ +#define SEGSIZE 512 /* data segment size */ +#define PKTSIZE SEGSIZE+4 /* full packet size */ + +/* Packet types. */ +#define RRQ 1 /* read request */ +#define WRQ 2 /* write request */ +#define DATA 3 /* data packet */ +#define ACK 4 /* acknowledgement */ +#define ERROR 5 /* error code */ + +struct tftphdr +{ + short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +} __attribute__((packed)); + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* ------------------------ Telnet ---------------------------------------- */ +#define PortTELNET 23 + +/* States */ +#define STATE_NORMAL 0 +#define STATE_IAC 1 +#define STATE_OPT 2 +#define STATE_SB 3 +#define STATE_OPTDAT 4 +#define STATE_SE 5 + +/* Special telnet characters */ +#define TELNET_SE 240 // End of subnegotiation parameters +#define TELNET_NOP 241 // No operation +#define TELNET_MARK 242 // Data mark +#define TELNET_BRK 243 // Break +#define TELNET_IP 244 // Interrupt process +#define TELNET_AO 245 // Abort output +#define TELNET_AYT 246 // Are you there +#define TELNET_EC 247 // Erase character +#define TELNET_EL 248 // Erase line +#define TELNET_GA 249 // Go ahead +#define TELNET_SB 250 // Start of subnegotiation parameters +#define TELNET_WILL 251 // Will option code +#define TELNET_WONT 252 // Won't option code +#define TELNET_DO 253 // Do option code +#define TELNET_DONT 254 // Don't option code +#define TELNET_IAC 255 // Interpret as command + +/* Telnet options */ +#define TELOPT_TRANSMIT_BINARY 0 // Binary Transmission (RFC856) +#define TELOPT_ECHO 1 // Echo (RFC857) +#define TELOPT_SUPPRESS_GO_AHEAD 3 // Suppress Go Ahead (RFC858) +#define TELOPT_STATUS 5 // Status (RFC859) +#define TELOPT_TIMING_MARK 6 // Timing Mark (RFC860) +#define TELOPT_NAOCRD 10 // Output Carriage-Return Disposition (RFC652) +#define TELOPT_NAOHTS 11 // Output Horizontal Tab Stops (RFC653) +#define TELOPT_NAOHTD 12 // Output Horizontal Tab Stop Disposition (RFC654) +#define TELOPT_NAOFFD 13 // Output Formfeed Disposition (RFC655) +#define TELOPT_NAOVTS 14 // Output Vertical Tabstops (RFC656) +#define TELOPT_NAOVTD 15 // Output Vertical Tab Disposition (RFC657) +#define TELOPT_NAOLFD 16 // Output Linefeed Disposition (RFC658) +#define TELOPT_EXTEND_ASCII 17 // Extended ASCII (RFC698) +#define TELOPT_TERMINAL_TYPE 24 // Terminal Type (RFC1091) +#define TELOPT_NAWS 31 // Negotiate About Window Size (RFC1073) +#define TELOPT_TERMINAL_SPEED 32 // Terminal Speed (RFC1079) +#define TELOPT_TOGGLE_FLOW_CONTROL 33 // Remote Flow Control (RFC1372) +#define TELOPT_LINEMODE 34 // Linemode (RFC1184) +#define TELOPT_AUTHENTICATION 37 // Authentication (RFC1416) + +#define TERM_UNKNOWN 0 +#define TERM_CONSOLE 1 +#define TERM_VT100 2 + +#define TELNET_BUF_SIZE 4096 + +struct term +{ + int type; + int cols; + int lines; +}; + +struct telbuf +{ + unsigned char data[TELNET_BUF_SIZE]; + unsigned char *start; + unsigned char *end; +}; + +struct termstate +{ + int sock; + int state; + int code; + unsigned char optdata[256]; + int optlen; + struct term term; + struct telbuf bi; + struct telbuf bo; +}; + +/* ------------------------ Variables ------------------------------------- */ +extern unsigned char __SDRAM_SIZE[]; +extern unsigned long size_ram_disk, ext_write_protect_ram_disk; +extern xTaskHandle pxCurrentTCB, tid_TOS; +xTaskHandle tid_TELNET, tid_DEBUG, tid_HTTPd; + +#ifdef COLDFIRE +#ifdef MCF547X +xTaskHandle tid_ETOS; +unsigned long pseudo_dma_vec; +extern short boot_os, drive_ok; +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +void *pci_data; +#endif +#endif /* MCF547X */ + +#ifdef CONFIG_USB_OHCI +extern char ohci_inited; +#endif +#ifdef CONFIG_USB_EHCI +// extern char ehci_inited; +#endif + +#ifdef MCF5445X +extern unsigned long save_imrl0, save_imrl0_tos, save_imrh0, save_imrh0_tos, save_imrh1, save_imrh1_tos; +#else +extern unsigned long save_imrl, save_imrl_tos, save_imrh, save_imrh_tos; +#endif +static int restart_debug, get_serial_vector, get_ikbd_vector, tos_suspend; +struct termstate *ts; + +static const char PROMPT[] = "> "; +static const char SYNTAX[] = "Error: Invalid syntax for: %s\r\n"; +static const char PAUSEMSG[] = "Press to continue."; +static const char HELPMSG[] = "Enter 'help' for help.\r\n"; +static const char INVCMD[] = "Error: No such command: %s\r\n"; +static const char INVARG[] = "Error: Invalid argument: %s\r\n"; +static const char INVALUE[] = "Error: Invalid value: %s\r\n"; +static const char HELPFORMAT[] = "%8s %-25s %s %s\r\n"; + +static char cmdline1[UIF_MAX_LINE]; +static char cmdline2[UIF_MAX_LINE]; + +static int BASE; +static unsigned long md_last_address; +static int md_last_size; +static unsigned long disasm_last_address; + +typedef char HISTENT[UIF_MAX_LINE]; +static HISTENT history[MAX_HISTORY]; +void *start_run; + +xSemaphoreHandle xSemaphoreBDOS; +xQueueHandle xQueueAlert; +#endif /* COLDFIRE */ + +int lwip_ok; +int errno; + +typedef struct socket_cookie +{ + long version; /* 0x0101 for example */ + long magic; /* 'SOCK' */ + int (*socket)(int domain, int type, int protocol); + int (*bind)(int s, struct sockaddr *name, socklen_t namelen); + int (*listen)(int s, int backlog); + int (*accept)(int s, struct sockaddr *addr, socklen_t *addrlen); + int (*connect)(int s, struct sockaddr *name, socklen_t namelen); + int (*write)(int s, void *dataptr, int size); + int (*send)(int s, void *dataptr, int size, unsigned int flags); + int (*sendto)(int s, void *dataptr, int size, unsigned int flags, struct sockaddr *to, socklen_t tolen); + int (*read)(int s, void *mem, int len); + int (*recv)(int s, void *mem, int len, unsigned int flags); + int (*recvfrom)(int s, void *mem, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen); + int (*shutdown)(int s, int how); + int (*close)(int s); + int (*getsockname)(int s, struct sockaddr *name, socklen_t *namelen); + int (*getpeername)(int s, struct sockaddr *name, socklen_t *namelen); + int (*getsockopt)(int s, int level, int optname, void *optval, socklen_t *optlen); + int (*setsockopt)(int s, int level, int optname, const void *optval, socklen_t optlen); + int (*select)(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout); + int (*ioctlsocket)(int s, long cmd, void *argp); + struct hostent *(*gethostbyname)(const char *name); + int (*geterrno)(void); +} SOCKET_COOKIE; + +/* + * The command table entry data structure, and the prototype for the + * command table. + */ +typedef const struct +{ + char * cmd; /* command name user types, ie. GO */ + int unique; /* num chars to uniquely match */ + int min_args; /* min num of args command accepts */ + int max_args; /* max num of args command accepts */ + int flags; /* command flags (repeat, hidden) */ + void (*func)(int, char **); /* actual function to call */ + char * description; /* brief description of command */ + char * syntax; /* syntax of command */ +} UIF_CMD; + +typedef struct +{ + int dest; + void (*func)(char); + char *loc; +} PRINTK_INFO; + +#define DEST_CONSOLE (1) +#define DEST_STRING (2) + +/* ------------------------ Prototypes ------------------------------------ */ +extern int add_cookie(COOKIE *cook); +extern COOKIE *get_cookie(long id); +#ifdef COLDFIRE +static void uif_cmd_help(int argc, char **argv); +static int make_argv(char *cmdline, char *argv[]); +extern err_t mcf_fec0_init(struct netif *netif); +extern err_t mcf_fec1_init(struct netif *netif); +extern int ftpd_start(char *username, char *password); +extern int printk(PRINTK_INFO *info, const char *fmt, va_list ap); +extern int printD(const char *fmt, ...); +extern int sprintD(char *s, const char *fmt, ...); +extern void flush_caches(void); +extern void enable_caches(void); +extern void disable_caches(void); +extern char *disassemble_pc(unsigned long pc); +extern void uif_cmd_usb(int argc, char **argv); +extern void usb_enable_interrupt(void); +#else /* !COLDFIRE */ +#define board_printf kprint +extern void kprint(const char *fmt, ...); +extern err_t rtl8139if_init(struct netif *netif); +#endif /* COLDFIRE */ + +/* ------------------------ Implementation -------------------------------- */ + +#ifdef COLDFIRE + +static int auxistat(void) +{ + register int ret __asm__("d0"); +#ifdef MCF547X + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0x165A,A0\n\t" /* iorec RS232 */ + " moveq #-1,D0\n\t" /* OK */ + " moveq #0,D1\n\t" + " moveq #0,D2\n\t" + " move.w 8(A0),D1\n\t" /* tail index */ + " move.w 6(A0),D2\n\t" /* head index */ + " cmp.l D2,D1\n\t" /* buffer empty */ + " bne.s .ais1\n\t" /* no */ + " moveq #0,D0\n\t" + ".ais1:\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "memory", "cc" ); +#else /* MCF548X */ + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0xF72,A0\n\t" /* iorec RS232 */ + " moveq #-1,D0\n\t" /* OK */ + " moveq #0,D1\n\t" + " moveq #0,D2\n\t" + " move.w 8(A0),D1\n\t" /* tail index */ + " move.w 6(A0),D2\n\t" /* head index */ + " cmp.l D2,D1\n\t" /* buffer empty */ + " bne.s .ais1\n\t" /* no */ + " moveq #0,D0\n\t" + ".ais1:\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "memory", "cc" ); +#endif /* MCF548X */ + return(ret); +} + +static int rs232get(void) +{ + register int ret __asm__("d0"); +#ifdef MCF547X + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0x165A,A0\n\t" /* iorec RS232 */ + " move.w SR,D2\n\t" + " move.l D2,-(SP)\n\t" + " or.l #0x700,D2\n\t" /* mask interrupts */ + " move.w D2,SR\n\t" + " moveq #0,D1\n\t" + " move.w 6(A0),D1\n\t" /* head index */ + " moveq #0,D2\n\t" + " move.w 8(A0),D2\n\t" /* tail index */ + " cmp.l D2,D1\n\t" + " beq.s .rg1\n\t" /* bufer empty */ + " addq.l #1,D1\n\t" + " moveq #0,D2\n\t" + " move.w 4(A0),D2\n\t" /* size */ + " cmp.l D2,D1\n\t" + " bcs.s .rg2\n\t" + " moveq #0,D1\n\t" + ".rg2:\n\t" + " move.l (A0),A1\n\t" /* buffer */ + " moveq #0,D0\n\t" + " move.b (A1,D1.l),D0\n\t" /* get data */ + " move.w D1,6(A0)\n\t" /* head index */ + " bra.s .rg3\n\t" + ".rg1:\n\t" + " moveq #-1,D0\n\t" /* no receive */ + ".rg3:\n\t" + " move.l (SP)+,D2\n\t" + " move.w D2,SR\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "a1", "memory", "cc" ); +#else /* MCF548X */ + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0xF72,A0\n\t" /* iorec RS232 */ + " move.w SR,D2\n\t" + " move.l D2,-(SP)\n\t" + " or.l #0x700,D2\n\t" /* mask interrupts */ + " move.w D2,SR\n\t" + " moveq #0,D1\n\t" + " move.w 6(A0),D1\n\t" /* head index */ + " moveq #0,D2\n\t" + " move.w 8(A0),D2\n\t" /* tail index */ + " cmp.l D2,D1\n\t" + " beq.s .rg1\n\t" /* bufer empty */ + " addq.l #1,D1\n\t" + " moveq #0,D2\n\t" + " move.w 4(A0),D2\n\t" /* size */ + " cmp.l D2,D1\n\t" + " bcs.s .rg2\n\t" + " moveq #0,D1\n\t" + ".rg2:\n\t" + " move.l (A0),A1\n\t" /* buffer */ + " moveq #0,D0\n\t" + " move.b (A1,D1.l),D0\n\t" /* get data */ + " move.w D1,6(A0)\n\t" /* head index */ + " bra.s .rg3\n\t" + ".rg1:\n\t" + " moveq #-1,D0\n\t" /* no receive */ + ".rg3:\n\t" + " move.l (SP)+,D2\n\t" + " move.w D2,SR\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "a1", "memory", "cc" ); +#endif /* MCF547X */ + return(ret); +} + +#ifndef MCF547X + +static void install_inters_cf68klib(void) +{ + int tos_run = (int)(*(unsigned short *)_timer_ms); + if(tos_run && !get_serial_vector) + { + int level = vPortSetIPL(portIPL_MAX); +#ifdef MCF5445X + unsigned long *v1 = (unsigned long *)((64+INT0_LO_UART0+OFFSET_INT_CF68KLIB)*4); + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART0)*4 + coldfire_vector_base); +#else + unsigned long *v1 = (unsigned long *)((64+35+OFFSET_INT_CF68KLIB)*4); + unsigned long *v2 = (unsigned long *)((64+35)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 &= ~INTC_IMRL_INT_MASK26; /* serial */ + save_imrl0 = MCF_INTC_IMRL0; +#else + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK35; /* serial */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_serial_vector = 1; + vPortSetIPL(level); + } + if(tos_run && !get_ikbd_vector) + { + int level = vPortSetIPL(portIPL_MAX); +#ifdef MCF5445X + unsigned long *v1 = (unsigned long *)((64+INT0_LO_UART2+OFFSET_INT_CF68KLIB)*4); /* UART 2 */ + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART2)*4 + coldfire_vector_base); +#else + unsigned long *v1b = (unsigned long *)((64+55+OFFSET_INT_CF68KLIB)*4); /* ERROR CAN1 */ + unsigned long *v1a = (unsigned long *)((64+56+OFFSET_INT_CF68KLIB)*4); /* BUSOFF CAN1 */ + unsigned long *v1 = (unsigned long *)((64+57+OFFSET_INT_CF68KLIB)*4); /* MBOR CAN1 */ + unsigned long *v2b = (unsigned long *)((64+55)*4 + coldfire_vector_base); + unsigned long *v2a = (unsigned long *)((64+56)*4 + coldfire_vector_base); + unsigned long *v2 = (unsigned long *)((64+57)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 &= ~INTC_IMRL_INT_MASK28; /* UART 2 */ + save_imrl0 = MCF_INTC_IMRL0; +#else + *v2a = *v1a; + *v2b = *v1b; + MCF_INTC_IMRH &= ~(MCF_INTC_IMRH_INT_MASK55 | MCF_INTC_IMRH_INT_MASK56 | MCF_INTC_IMRH_INT_MASK57); /* CAN (IKBD) */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_ikbd_vector = 1; + vPortSetIPL(level); + } +} + +static void uninstall_inters_cf68klib(void) +{ + int tos_run = (int)(*(unsigned short *)_timer_ms); + if(tos_run && get_serial_vector) + { + int level = vPortSetIPL(portIPL_MAX); + unsigned long *v1 = (unsigned long *)(64*4 + coldfire_vector_base); /* default CF68KLIB vector normally unchanged */ +#ifdef MCF5445X + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART0)*4 + coldfire_vector_base); +#else + unsigned long *v2 = (unsigned long *)((64+35)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 |= INTC_IMRL_INT_MASK26; /* serial */ + save_imrl0 = MCF_INTC_IMRL0; +#else + MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK35; /* serial */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_serial_vector = 0; + vPortSetIPL(level); + } + if(tos_run && get_ikbd_vector) + { + int level = vPortSetIPL(portIPL_MAX); + unsigned long *v1 = (unsigned long *)(64*4 + coldfire_vector_base); /* default CF68KLIB vector normally unchanged */ +#ifdef MCF5445X + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART2)*4 + coldfire_vector_base); +#else + unsigned long *v2b = (unsigned long *)((64+55)*4 + coldfire_vector_base); + unsigned long *v2a = (unsigned long *)((64+56)*4 + coldfire_vector_base); + unsigned long *v2 = (unsigned long *)((64+57)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 |= INTC_IMRL_INT_MASK28; /* UART 2 */ + save_imrl0 = MCF_INTC_IMRL0; +#else + *v2a = *v1; + *v2b = *v1; + MCF_INTC_IMRH |= (MCF_INTC_IMRH_INT_MASK55 | MCF_INTC_IMRH_INT_MASK56 | MCF_INTC_IMRH_INT_MASK57); /* CAN (IKBD) */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_ikbd_vector = 0; + vPortSetIPL(level); + } +} + +#endif /* MCF547X */ + +static int conin_debug(void) +{ + int tos_run; + while(*(unsigned char *)(serial_mouse)) + vTaskDelay(1); +#ifdef MCF547X + if((tos_suspend && !get_serial_vector) || (tid_ETOS != NULL)) +#else + if(tos_suspend && !get_serial_vector) +#endif + tos_run = 0; + else + tos_run = (int)(*(unsigned short *)_timer_ms); + /* if TOS runs we can use TOS interrupts routines also out of the CF68KLIB */ + while((!tos_run && !(MCF_UART_USR(0) & MCF_UART_USR_RXRDY)) + || (tos_run && !auxistat())) + { + vTaskDelay(1); +#ifdef MCF547X + if((tos_suspend && !get_serial_vector) || (tid_ETOS != NULL)) +#else + if(tos_suspend && !get_serial_vector) +#endif + tos_run = 0; + else + tos_run = (int)(*(unsigned short *)_timer_ms); +// install_inters_cf68klib(); + } + return(tos_run ? rs232get() & 0xFF : (int)MCF_UART_URB(0) & 0xFF); +} + +void conout_debug(int c) +{ + if(!*(unsigned char *)(serial_mouse)) + { +#ifdef MCF547X + if((pxCurrentTCB != tid_TOS) && (pxCurrentTCB != tid_ETOS)) +#else + if(pxCurrentTCB != tid_TOS) +#endif + { + int level = vPortSetIPL(portIPL_MAX); + vPortSetIPL(level); + while(!(MCF_UART_USR(0) & MCF_UART_USR_TXRDY)) + { + if(!level) + vTaskDelay(1); + } + MCF_UART_UTB(0) = (char)c; // send the character + } + else + { + while(!(MCF_UART_USR(0) & MCF_UART_USR_TXRDY)); + MCF_UART_UTB(0) = (char)c; // send the character + } + } +} + +void conws_debug(char *buf) +{ + int i = 0; + while(buf[i]) + conout_debug(buf[i++]); +} + +#ifdef DBUG + +static int telnet_write_socket(char *response, int size, int flush) +{ + int i, n = 0, len; + fd_set data_write; + struct timeval tv; + char *ptr = response; + do + { + len = TELNET_BUF_SIZE - (int)(ts->bo.start - ts->bo.data); + if(size < len) + len = size; + if(len >= 0) + { + memcpy(ts->bo.start, response, len); + size -= len; + ts->bo.start += len; + response += len; + } + if(((int)(ts->bo.start - ts->bo.data) >= TELNET_BUF_SIZE) + || flush) + { + len = n = 0; + ptr = (char *)ts->bo.data; + do + { + FD_ZERO(&data_write); + FD_SET(ts->sock, &data_write); + tv.tv_sec = 1; + tv.tv_usec = 0; + i = select(FD_SETSIZE, NULL, &data_write, NULL, &tv); + if((i > 0) && (FD_ISSET(ts->sock, &data_write) != 0)) + { + n = send(ts->sock, ptr, (int)(ts->bo.start - ts->bo.data) - len, 0); + if(n >= 0) + { + ptr += n; + len += n; + } + } + } + while((n >= 0) && (len < (int)(ts->bo.start - ts->bo.data)) && (i > 0)); + ts->bo.start = ts->bo.data; + } + } + while(size > 0); + return(n < 0 ? n : len); +} + +void board_printf(const char *fmt, ...) +{ + va_list ap; + PRINTK_INFO info; + info.dest = DEST_STRING; + va_start(ap, fmt); + if(pxCurrentTCB == tid_TOS) + { + static char buf_tos[TELNET_BUF_SIZE]; // minimize stack usage + info.loc = buf_tos; + printk(&info, fmt, ap); + *info.loc = '\0'; + va_end(ap); + conws_debug(buf_tos); + } + else + { + char *buf = (char *)pvPortMalloc(TELNET_BUF_SIZE); + if(buf != NULL) + { + info.loc = buf; + printk(&info, fmt, ap); + *info.loc = '\0'; + va_end(ap); + if(pxCurrentTCB == tid_TELNET) + { + if(ts->sock > 0) + telnet_write_socket(buf, strlen(buf), 1); + } + else + conws_debug(buf); + vPortFree(buf); + } + } +} + +static char board_getchar(void) +{ + if(pxCurrentTCB == tid_TELNET) + return(CTRL_C); + return((char)conin_debug()); +} + +void board_putchar(char c) +{ + if(pxCurrentTCB == tid_TELNET) + { + if(ts->sock > 0) + telnet_write_socket(&c, 1, (c == '\n') ? 1 : 0); + } + else + conout_debug(c); +} + +static void board_putchar_flush(void) +{ +} + +static void history_init(void) +{ + int index; + for(index = 0; index < MAX_HISTORY; ++index) + history[index][0] = '\0'; +} + +static int history_down(int *curr_hist, char *line) +{ + *curr_hist -= 1; + if(*curr_hist < 0) + { + *curr_hist = -1; + line[0] = '\0'; + return 0; + } + strcpy(line, history[*curr_hist]); + board_printf("%s",line); + board_putchar_flush(); + return strlen(line); +} + +static int history_up(int *curr_hist, char *line) +{ + if(*curr_hist == -1) + *curr_hist = 0; + else + { + *curr_hist += 1; + if(*curr_hist >= MAX_HISTORY) + *curr_hist = (MAX_HISTORY-1); + } + strcpy(line, history[*curr_hist]); + board_printf("%s",line); + board_putchar_flush(); + return strlen(line); +} + +static int history_repeat(char *line) +{ + strcpy(line, history[0]); + board_printf("%s",line); + board_putchar_flush(); + return strlen(line); +} + +static void history_add(char *line) +{ + /* This routine is called after use has entered a line */ + int index; + /* Move all history line buffers down */ + for(index = (MAX_HISTORY-1); index > 0; --index) + strcpy(history[index],history[index-1]); + /* Copy in the new one */ + strcpy(history[0], line); +} + +static char *get_history_line(char *userline) +{ + char line[UIF_MAX_LINE]; + int pos, ch, i, curr_hist, repeat; + curr_hist = -1; /* invalid */ + repeat = FALSE; + pos = 0; + ch = (int)board_getchar(); + while((ch != 0x0D /* CR */) && (ch != 0x0A /* LF/NL */) && (pos < UIF_MAX_LINE)) + { + switch(ch) + { + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(pos > 0) + { + pos -= 1; + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + break; + case CTRL_U: + case CTRL_D: + case CTRL_R: + for(i = 0; i < pos; ++i) + { + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + if(ch == CTRL_U) + { + pos = history_up(&curr_hist,line); + break; + } + if(ch == CTRL_D) + { + pos = history_down(&curr_hist,line); + break; + } + if(ch == CTRL_R) + { + pos = history_repeat(line); + repeat = TRUE; + } + break; + default: + if((pos+1) < UIF_MAX_LINE) + { + /* only printable characters */ + if((ch > 0x1f) && (ch < 0x80)) + { + line[pos++] = (char)ch; + board_putchar((char)ch); + } + } + break; + } + if(repeat) + break; + ch = (int)board_getchar(); + } + line[pos] = '\0'; + board_putchar(0x0D); /* CR */ + board_putchar(0x0A); /* LF */ + if((strlen(line) != 0) && !repeat) + history_add(line); + strcpy(userline,line); + return userline; +} + +static char *get_line(char *line) +{ + int pos; + int ch; + pos = 0; + board_putchar_flush(); + ch = (int)board_getchar(); + while((ch != 0x0D /* CR */) && (ch != 0x0A /* LF/NL */) && (pos < UIF_MAX_LINE)) + { + switch(ch) + { + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(pos > 0) + { + pos--; + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + break; + default: + if((pos+1) < UIF_MAX_LINE) + { + if((ch > 0x1f) && (ch < 0x80)) + { + line[pos++] = (char)ch; + board_putchar((char)ch); + } + } + break; + } + ch = (int)board_getchar(); + } + line[pos] = '\0'; + board_putchar(0x0D); /* CR */ + board_putchar(0x0A); /* LF */ + return line; +} + +static unsigned long get_value(char *s, int *success, int base) +{ + unsigned long value; + char *p; + value = strtoul(s,&p,base); + if((value == 0) && (p == s)) + { + *success = FALSE; + return 0; + } + else + { + *success = TRUE; + return value; + } +} + +static void cpu_write_data(unsigned long address, int size, unsigned long data) +{ + switch(size) + { + case SIZE_8: *((uint8 *)address) = (uint8)data; break; + case SIZE_16: *((uint16 *)address) = (uint16)data; break; + case SIZE_32: *((unsigned long *)address) = (unsigned long)data; break; + default: break; + } +} + +static unsigned long cpu_read_data(unsigned long address, int size) +{ + switch(size) + { + case SIZE_8: return *((uint8 *)address); + case SIZE_16: return *((uint16 *)address); + case SIZE_32: return *((unsigned long *)address); + default: return 0; + } +} + +static unsigned long cpu_align_address(unsigned long address, int size) +{ + switch(size) + { + case SIZE_32: + case SIZE_16: return(address & ~0x00000001); + case SIZE_8: + default: return (address); + } +} + +static int cpu_parse_size(char *arg) +{ + int i, size = SIZE_16; + for (i = 0; arg[i] != '\0'; i++) + { + if(arg[i] == '.') + { + switch(arg[i+1]) + { + case 'b': + case 'B': size = SIZE_8; break; + case 'w': + case 'W': size = SIZE_16; break; + case 'l': + case 'L': size = SIZE_32; break; + default: size = SIZE_16; break; + } + break; + } + } + return size; +} + +static void dump_mem(unsigned long begin, unsigned long end, int size) +{ + unsigned long data; + unsigned long curr; + char line[16]; + char *lcur; + int i, ch; + curr = begin; + do + { + board_printf("%08X: ",(int)curr); + lcur = line; + i = 0; + while(i < 16) + { + data = cpu_read_data(curr,size); + switch(size) + { + case SIZE_8: + board_printf("%02X ", (int)data); + *(uint8 *)lcur = (uint8)data; + curr++; + lcur++; + i++; + break; + case SIZE_16: + default: + board_printf("%04X ", (int)data); + *(uint16 *)lcur = (uint16)data; + curr += 2; + lcur += 2; + i += 2; + break; + case SIZE_32: + board_printf("%08X ", (int)data); + *(unsigned long *)lcur = data; + curr += 4; + lcur += 4; + i += 4; + break; + } + } + for(i = 0; i < 16; i++) + { + ch = line[i]; + if((ch >= ' ') && (ch <= '~')) + board_printf("%c",ch); + else + board_printf("."); + } + board_printf("\r\n"); + } + while(curr < end); +} + +#define BKPT_NONE (0) +#define BKPT_PERM (1) +#define BKPT_TEMP (2) + +/* Data structure used to maintain break points and trace information */ +typedef struct +{ + xTaskHandle tid; + unsigned long address; + unsigned short instruction; + int count; + int trigger; + int valid; /* and type info */ +} BRKENT; + +static BRKENT brktab[UIF_MAX_BRKPTS]; +static int auto_breakpoint; + +static void breakpoint_clear(int index) +{ + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + { + if(brktab[index].tid) + { +// board_printf("Resume task TID: %X\r\n", brktab[index].tid); + vTaskResume(brktab[index].tid); + } + brktab[index].tid = 0; + brktab[index].address = 0; + brktab[index].instruction = 0; + brktab[index].count = 0; + brktab[index].trigger = 0; + brktab[index].valid = BKPT_NONE; + } +} + +static int breakpoint_find(unsigned long address) +{ + /* This function searches the breakpoint table for `address'. + * If it is found, then an index into the table is returned, + * otherwise -1 is returned. */ + int index; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].address == address) + return(index); + } + return(-1); +} + +static void breakpoint_display_info(int index) +{ + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + { + board_printf(" %d %08X %08X %08X\r\n", + (int)index, (int)brktab[index].address, brktab[index].count, brktab[index].trigger); + } +} + +static void breakpoint_display(int argc, char **argv) +{ + unsigned long address; + int i,j; + (void)argc; + board_printf("INSTR_BREAK__ADDRESS___COUNT___TRIGGER_____________________________________\r\n"); + if(auto_breakpoint) + board_printf(" ? Pexec TOS armed ? ?\r\n"); + if(*(unsigned char *)(trap_breakpoint)) + board_printf(" ? Mshrink MiNT armed ? ?\r\n"); + /* break points are listed one by one starting at argv[1] */ + /* if no break points listed, argv[1] == NULL, display all */ + if(argv[1] == NULL) + { + /* display all */ + for(i = 0; i < UIF_MAX_BRKPTS; i++) + { + if(brktab[i].valid) + breakpoint_display_info(i); + } + } + else + { + i = 1; + while(argv[i] != NULL) + { + address = (unsigned long )strtoul(argv[i],NULL,16); + for(j = 0; j < UIF_MAX_BRKPTS; j++) + { + if(brktab[j].address == address) + breakpoint_display_info(j); + } + i++; + } + } +} + +static void breakpoint_set_count(unsigned long brkpnt, int count) +{ + int index = breakpoint_find(brkpnt); + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + brktab[index].count = count; +} + +static void breakpoint_set_all_count(int value) +{ + int index; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + brktab[index].count = value; +} + +static void breakpoint_set_trigger(unsigned long brkpnt, int count) +{ + int index = breakpoint_find(brkpnt); + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + brktab[index].trigger = count; +} + +static void breakpoint_set_all_trigger(int value) +{ + int index; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + brktab[index].trigger = value; +} + +static void breakpoint_remove(unsigned long address) +{ + int index; + if((index = breakpoint_find(address)) != -1) + breakpoint_clear(index); +} + +static void breakpoint_add(unsigned long address, int type) +{ + int i; + /* first check to make sure not already in table */ + if(breakpoint_find(address) != -1) + return; + /* find an open slot and put it in */ + for(i = 0; i < UIF_MAX_BRKPTS; i++) + { + if(!brktab[i].valid) + break; + } + if(i == UIF_MAX_BRKPTS) + { + board_printf("Break table full\r\n"); + return; + } + /* Test for valid breakpoint address */ + if(address & 1) /* 16-bit boudary */ + { + board_printf("Error: Invalid breakpoint address!\r\n"); + return; + } +// unprotect_code(); + /* Test for read-only memory */ + brktab[i].instruction = *(unsigned short *)address; + *(unsigned short *)address = (unsigned short)ILLEGAL; + if(*(volatile unsigned short *)address != (unsigned short)ILLEGAL) + board_printf("Error: Address is read-only!\n"); + else + { + *(unsigned short *)address = brktab[i].instruction; + brktab[i].address = address; + brktab[i].count = 0; + brktab[i].trigger = 1; + brktab[i].valid = type; + } +// protect_code(); +} + +static int breakpoint_install(unsigned long address) +{ + /* This function inserts the breakpoints in user code. Extensive + * checking of breakpoints is done before entry into the table, so + * all breakpoints in table should be OK to just implant. If + * a breakpoint with the same `address' is found, it is not + * inserted, and TRUE is returned, otherwise FALSE. + * This routine is generally called right before executing user + * code. */ + int index, found = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { + if(brktab[index].address == address) + found = TRUE; + else + { +// unprotect_code(); + brktab[index].instruction = *(unsigned short *)brktab[index].address; + *(unsigned short *)brktab[index].address = (unsigned short)ILLEGAL; +// protect_code(); + } + } + } + flush_caches(); + return(found); +} + +static int breakpoint_install_from_cf68klib(unsigned long address) +{ + /* This function inserts the breakpoints in user code. Extensive + * checking of breakpoints is done before entry into the table, so + * all breakpoints in table should be OK to just implant. If + * a breakpoint with the same `address' is found, it is not + * inserted, and TRUE is returned, otherwise FALSE. + * This routine is generally called right before executing user + * code. */ + int index, found = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { + if(brktab[index].address == address) + found = TRUE; + else + { +// unprotect_code(); + brktab[index].instruction = *(unsigned short *)brktab[index].address; + *(unsigned short *)brktab[index].address = (unsigned short)ILLEGAL; +// protect_code(); + } + } + } +#if (__GNUC__ > 3) + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5485\n\t"); +#else + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5200\n\t"); +#endif + return(found); +} + +static int breakpoint_deinstall(unsigned long address, int *triggered, xTaskHandle tid) +{ + /* This function removes breakpoints from user code. If + * `address' is/was installed, TRUE is returned, else FALSE + * if `address' was encountered, its count is incremented. */ + int index, found = FALSE; + *triggered = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { +// unprotect_code(); + *(unsigned short *)brktab[index].address = (unsigned short)brktab[index].instruction; +// protect_code(); + if(brktab[index].address == address) + { + brktab[index].tid = tid; + found = TRUE; + if(++brktab[index].count >= brktab[index].trigger) + *triggered = TRUE; + } + if(brktab[index].valid == BKPT_TEMP) + { + /* knock out Temporary breakpoints */ + breakpoint_clear(index); + } + } + } + flush_caches(); + return found; +} + +static int breakpoint_deinstall_from_cf68klib(unsigned long address, xTaskHandle tid) +{ + /* This function removes breakpoints from user code. If + * `address' is/was installed, TRUE is returned, else FALSE + * if `address' was encountered, its count is incremented. */ + int index, found = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { +// unprotect_code(); + *(unsigned short *)brktab[index].address = (unsigned short)brktab[index].instruction; +// protect_code(); + if(brktab[index].address == address) + { + brktab[index].tid = tid; + found = TRUE; + } + if(brktab[index].valid == BKPT_TEMP) + { + /* knock out Temporary breakpoints */ + breakpoint_clear(index); + } + } + } +#if (__GNUC__ > 3) + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5485\n\t"); +#else + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5200\n\t"); +#endif + return found; +} + +static void suspend_task(xTaskHandle tid) +{ + if(pxCurrentTCB == tid_TOS) + tos_suspend = 1; + vTaskSuspend(tid); +} + +static void resume_task(xTaskHandle tid) +{ + if(tid == tid_TOS) + { + *(unsigned long *)_hz_200 = xTaskGetTickCount(); + tos_suspend = 0; + } + vTaskResume(tid); +} + +void install_auto_breakpoint(unsigned long address) /* called from DBOS / CF68KLIB */ +{ + if(auto_breakpoint && address && (address < (unsigned long)__SDRAM_SIZE) + && ((address < 0xE00000) || (address >= 0x1000000))) + { + breakpoint_deinstall_from_cf68klib(address, pxCurrentTCB); + breakpoint_add(address, BKPT_PERM); + breakpoint_install_from_cf68klib((unsigned long)-1); + } +} + +static void breakpoint_init(void) +{ + int index; + *(unsigned long *)(v_breakpoint_install) = (unsigned long)breakpoint_install; + *(unsigned long *)(v_breakpoint_deinstall) = (unsigned long)breakpoint_deinstall; + *(unsigned long *)(v_breakpoint_add) = (unsigned long)breakpoint_add; + *(unsigned long *)(v_breakpoint_remove) = (unsigned long)breakpoint_remove; + *(unsigned long *)(v_suspend_task) = (unsigned long)suspend_task; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + breakpoint_clear(index); + auto_breakpoint = 0; + *(unsigned char *)(trap_breakpoint) = 0; +} + +static void uif_cmd_cb(int argc, char **argv) +{ + int success, index; + if((argc == 2) && (argv[1][0] != '*')) + { + index = get_value(argv[1],&success,10); + if(success) + { + if((index >= UIF_MAX_BRKPTS) || (brktab[index].valid != BKPT_PERM)) + { + board_printf("Error: Bad index!\r\n"); + return; + } + breakpoint_remove(brktab[index].address); + } + } + else + breakpoint_init(); + *(unsigned short *)(save_format) = 0; +} + +static void uif_cmd_db(int argc, char **argv) +{ + int i, value, success; + unsigned long brkpnt; + char *p; + brkpnt = (unsigned long)-1; /* improbable breakpoint address */ + if(argc == 1) + { + auto_breakpoint = 1; /* for BDOS pexec, 1st word of program */ + /* display all break points */ + breakpoint_display(argc, argv); + return; + } + /* parse through arguments */ + i = 1; + while(i < argc) + { + if(argv[i][0] != '-') + { + /* must be a breakpoint address */ + success = 1; + brkpnt = get_value(argv[i],&success,16); + if(success == 0) + { + board_printf("Error: Bad Value: %s\r\n",argv[i]); + return; + } + /* add breakpoint, if not already there */ + breakpoint_add(brkpnt, BKPT_PERM); + i++; + } + else + { + /* must be an option of some sort */ + switch(argv[i][1]) + { + case 'c': + case 'C': + /* set break point count */ + if(argv[i+1] == NULL) + value = 0; + else + { + value = strtoul(argv[++i],&p,BASE); + if((value == 0) && (p == argv[i])) + value = 0; + } + if(brkpnt == (unsigned long)-1) + { + /* set all counts */ + breakpoint_set_all_count(value); + return; + } + else + breakpoint_set_count(brkpnt,value); + break; + case 't': + case 'T': + /* set break point trigger */ + if(argv[i+1] == NULL) + value = 1; + else + { + value = strtoul(argv[++i],&p,BASE); + if((value == 0) && (p == argv[i])) + value = 1; + } + if(brkpnt == (unsigned long)-1) + { + /* set all triggers */ + breakpoint_set_all_trigger(value); + return; + } + else + breakpoint_set_trigger(brkpnt,value); + break; + case 'r': + case 'R': + /* remove break points */ + if(brkpnt == (unsigned long)-1) + { + /* check for address given after '-r' */ + if(argv[i+1] == NULL) + breakpoint_init(); + else + { + while(++i < argc) + { + success = 1; + brkpnt = get_value(argv[i],&success,16); + if(success == 0) + breakpoint_init(); + else + breakpoint_remove(brkpnt); + } + } + } + else + breakpoint_remove(brkpnt); + *(unsigned short *)(save_format) = 0; + break; + case 'i': + case 'I': + breakpoint_set_all_trigger(1); + breakpoint_set_all_count(0); + break; + case 'm': + case 'M': + *(unsigned char *)(trap_breakpoint) = 1; /* for trap #1 mshrink */ + break; + default: + board_printf("Error: Invalid option: %s\r\n",argv[1]); + break; + } + i++; + } + } +} + +static void uif_cmd_lb(int argc, char **argv) +{ + breakpoint_display(argc, argv); +} + +#ifdef MCF547X /* FIREBEE */ + +void zero_devide(void) +{ + asm volatile ( + "_new_zero_divide:\n\t" + " move.w #0x2700,SR\n\t" /* disable interrupt */ + " move.l D0,-(SP)\n\t" + " move.l A0,-(SP)\n\t" + " move.l 12(SP),A0\n\t" /* PC */ + " move.w (A0)+,D0\n\t" /* opcode */ + " btst #7,D0\n\t" + " bne.s .word\n\t" + " addq.l #2,A0\n\t" /* longword */ + ".word:\n\t" + " and.l #0x3F,D0\n\t" /* source effective address */ + " cmp.l #8,D0\n\t" + " bls.s .end\n\t" /* Dy */ + " addq.l #2,A0\n\t" + " cmp.l #0x39,D0\n\t" /* absolute */ + " beq.s .absolute\n\t" + " cmp.l #0x3C,D0\n\t" /* immediate */ + " bne.s .end\n\t" + ".absolute:\n\t" + " addq.l #2,A0\n\t" + ".end:\n\t" + " move.l A0,12(SP)\n\t" /* fix PC */ + " move.l (SP)+,A0\n\t" + " move.l (SP)+,D0\n\t" + " rte\n\t" ); +} + +void trap_exception(void) +{ + asm volatile ( + "_new_trap:\n\t" + " clr.l -(SP)\n\t" + " move.l D0,-(SP)\n\t" + " move.l A0,-(SP)\n\t" + " move.w 12(SP),D0\n\t" + " and.l #0x3FC,D0\n\t" + " move.l D0,A0\n\t" + " move.l (A0),8(SP)\n\t" + " move.l (SP)+,A0\n\t" + " move.l (SP)+,D0\n\t" + " rts\n\t" ); +} + +void clear_int6(void) +{ + MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF6; /* clear interrupt */ +} + +void inter_mfp(void) +{ + asm volatile ( + "_new_mfp:\n\t" + " move.l 0x114,-(SP)\n\t" + " lea -24(SP),SP\n\t" + " movem.l D0-D2/A0-A2,(SP)\n\t" ); + clear_int6(); + asm volatile ( + " moveq #0,D1\n\t" + " move.b 0xFFFFFA13,D1\n\t" /* MFP IMRA (FPGA emulation) */ + " asl.l #8,D1\n\t" + " move.b 0xFFFFFA15,D1\n\t" /* MFP IMRB (FPGA emulation) */ + " move.b 0xFFFFFA0B,D0\n\t" /* MFP IPRA (FPGA emulation) */ + " asl.l #8,D0\n\t" + " move.b 0xFFFFFA0D,D0\n\t" /* MFP IPRB (FPGA emulation) */ + " and.l D1,D0\n\t" + " tst.l D0\n\t" + " beq.s .is_not_mfp\n\t" + " move.l 0xF0020000,D0\n\t" /* ACP_MFP_INTACK_VECTOR (MFP vector base register + MFP int channel) * 4 */ + " and.l #0x3FC,D0\n\t" + " cmp.l #0x13C,D0\n\t" + " bne.s .not_pseudo_dma\n\t" /* TOS pseudo dma routine */ + " move.l _pseudo_dma_vec,D0\n\t" + " move.l D0,24(SP)\n\t" /* move vector content to return address */ + " bra.s .is_not_mfp\n\t" + ".not_pseudo_dma:\n\t" + " move.l D0,A0\n\t" + " move.l (A0),24(SP)\n\t" /* move vector content to return address */ + ".is_not_mfp:\n\t" + " movem.l (SP),D0-D2/A0-A2\n\t" + " lea 24(SP),SP\n\t" + " rts\n\t" ); /* jump to MFP vector */ +} + +void function_vbl(void) +{ +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_INTERRUPT_POLLING) +void usb_event_poll(int interrupt); +#endif + MCF_INTC_INTFRCL &= ~MCF_INTC_INTFRCL_INTFRC4; /* clear interrupt */ +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_INTERRUPT_POLLING) + MCF_GPT_GMS(0) = 0; + MCF_GPT_GCIR(0) = 20000 | (SYSTEM_CLOCK << 16); /* 20 mS */ + MCF_GPT_GMS(0) = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_CE | MCF_GPT_GMS_WDEN; /* watchdog timer */ +#ifdef CONFIG_USB_OHCI + if(ohci_inited) +#endif + usb_event_poll(1); /* if CTRL-ALT-(SHIFT-)DEL no return ! */ + MCF_GPT_GMS(0) = 0; /* clear watchdog timer */ +#endif +} + +void inter_vbl(void) +{ + asm volatile ( + "_new_vbl:\n\t" + " lea -24(SP),SP\n\t" + " movem.l D0-D2/A0-A2,(SP)\n\t" ); + function_vbl(); + asm volatile ( + " movem.l (SP),D0-D2/A0-A2\n\t" + " lea 24(SP),SP\n\t" + " move.l 0x70,-(SP)\n\t" + " rts\n\t" ); /* jump to VBL vector */ +} + +#define MMUCR (*(volatile unsigned long *)(MMU_BASE+0x0000)) +#define MMUOR (*(volatile unsigned long *)(MMU_BASE+0x0004)) +#define MMUSR (*(volatile unsigned long *)(MMU_BASE+0x0008)) +#define MMUAR (*(volatile unsigned long *)(MMU_BASE+0x0010)) +#define MMUTR (*(volatile unsigned long *)(MMU_BASE+0x0014)) +#define MMUDR (*(volatile unsigned long *)(MMU_BASE+0x0018)) + +#define MMUCR_EN 0x01 + +#define MMUOR_STLB 0x100 +#define MMUOR_CA 0x80 +#define MMUOR_CNL 0x40 +#define MMUOR_CAS 0x20 +#define MMUOR_ITLB 0x10 +#define MMUOR_ADR 0x08 +#define MMUOR_RW 0x04 +#define MMUOR_ACC 0x02 +#define MMUOR_UAA 0x01 + +#define MMUTR_SG 0x02 +#define MMUTR_V 0x01 + +#define MMUDR_SZ1M 0x000 +#define MMUDR_SZ4K 0x100 +#define MMUDR_SZ8K 0x200 +#define MMUDR_SZ1K 0x300 +#define MMUDR_WRITETHROUGH 0x00 +#define MMUDR_WRITEBACK 0x40 +#define MMUDR_NOCACHE 0x80 +#define MMUDR_SP 0x20 +#define MMUDR_R 0x10 +#define MMUDR_W 0x08 +#define MMUDR_X 0x04 +#define MMUDR_LK 0x02 + +#define MMUSR_HITN 0x02 + +static void mmu_map(long virt_addr, long phys_addr, long flag_itlb, long flags_mmudr) +{ + extern unsigned char __MBAR[]; + unsigned long MMU_BASE = (unsigned long)__MBAR + 0x40000; + MMUAR = virt_addr + 1; + MMUOR = MMUOR_STLB + MMUOR_ADR + flag_itlb; + MMUTR = virt_addr + MMUTR_SG + MMUTR_V; + MMUDR = phys_addr + flags_mmudr; + MMUOR = MMUOR_ACC + MMUOR_UAA + flag_itlb; +} + +static portTASK_FUNCTION(vVBL, pvParmeters) +{ + extern void new_vbl(void); + extern long get_videl_base(void); + extern long get_videl_size(void); + extern void get_mouseikbdvec(void); +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) /* for usb_malloc */ +#if 0 // #ifdef CONFIG_USB_STORAGE + extern short usb_found; + extern int usb_stor_scan(void); +#endif /* CONFIG_USB_STORAGE */ +#ifdef SOUND_AC97 + extern void det_xbios(void); + extern long sndstatus(long reset); + extern long old_vector_xbios; + extern long flag_snd_init, flag_gsxb; + int sound_err, i; +#endif /* SOUND_AC97 */ +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ + volatile unsigned char *rtc_reg = (volatile unsigned char *)0xFFFF8961; /* PFGA emulation */ + volatile unsigned char *rtc_data = (volatile unsigned char *)0xFFFF8963; + long count = 0, physbase = get_videl_base(); + long date = 0, time = 0; + *(unsigned long *)(((64+4) * 4) + coldfire_vector_base) = (unsigned long)new_vbl; + MCF_GPIO_PODR_FEC1L &= ~MCF_GPIO_PODR_FEC1L_PODR_FEC1L4; /* led */ + vTaskDelay(configTICK_RATE_HZ); + get_mouseikbdvec(); /* XBIOS calls !!! (for USB and screen WEB server) */ + old_vector_xbios = *(long *)0xB4; /* XBIOS */ +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef SOUND_AC97 + for(i = 0; i < 2; i++) + { + sound_err = mcf548x_ac97_install(2); + if(!sound_err) + break; + } +#endif +#endif + while(1) + { + unsigned long start_timer = *(unsigned long *)_hz_200; +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef SOUND_AC97 + if(!sound_err) + { + *(long *)0xB4 = (long)det_xbios; + flag_snd_init = 1; + flag_gsxb = 1; + sndstatus(1); + } + else + flag_snd_init = 0; +#endif /* SOUND_AC97 */ + board_printf("Add cookies\r\n"); + if(pci_data != NULL) + { + COOKIE pcookie; + COOKIE *p = *(COOKIE **)cookie; + int i = 0; + pcookie.ident = '_PCI'; + pcookie.v.l = (long)pci_data; + while(p != NULL) + { + if(p->ident == '_PCI') + continue; + if((!p->ident) && (i+1 < p->v.l)) /* free space ? */ + { + *(p+1) = *p; /* add cookie */ + *p++ = pcookie; + break; + } +#ifdef SOUND_AC97 + if((p->ident == '_SND') && !sound_err) + p->v.l |= 0x27; /* bit 5: extended mode, bit 2: 16 bits DMA, bit 1: 8 bits DMA, bit 0: YM2149 */ +#endif /* SOUND_AC97 */ + i++; + p++; + } + } +#if 0 // #ifdef CONFIG_USB_STORAGE + if(usb_found) + usb_stor_scan(); +#endif /* CONFIG_USB_STORAGE */ +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ + while((*(unsigned long *)_hz_200 - start_timer) < 200UL) + { + start_timer = *(unsigned long *)_hz_200; + /* Videl screen change - FPGA memory */ + long new_physbase = get_videl_base(); + if(new_physbase != physbase) + { + long end_physbase = new_physbase + get_videl_size(); + physbase = new_physbase; + new_physbase &= 0xf00000; + end_physbase &= 0xf00000; + if(new_physbase < 0xd00000) + { + int level = asm_set_ipl(7); /* disable interrupts */ + flush_caches(); + memcpy((void *)(new_physbase + 0x60000000), (void *)new_physbase, 0x100000); + mmu_map(new_physbase,(new_physbase + 0x60000000),MMUOR_ITLB,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); + mmu_map(new_physbase,(new_physbase + 0x60000000),0,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + if((end_physbase != new_physbase) && (end_physbase < 0xd00000)) /* 2nd page */ + { + memcpy((void *)(end_physbase + 0x60000000), (void *)new_physbase, 0x100000); + mmu_map(end_physbase,(end_physbase + 0x60000000),MMUOR_ITLB,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); + mmu_map(end_physbase,(end_physbase + 0x60000000),0,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + } + asm_set_ipl(level); +// board_printf("new videl screen at 0x%lX\r\n", physbase); + } + } + if(!(count % 50)) + { +#define NVRAM_RTC_SECONDS 0 +#define NVRAM_RTC_MINUTES 2 +#define NVRAM_RTC_HOURS 4 +#define NVRAM_RTC_DAYS 7 +#define NVRAM_RTC_MONTHS 8 +#define NVRAM_RTC_YEARS 9 + int i; + long new_date = 0, new_time = 0, delta_time; + int level = asm_set_ipl(7); /* disable interrupts */ + unsigned char reg = *rtc_reg; + *rtc_reg = NVRAM_RTC_HOURS; + new_time |= (unsigned long)*rtc_reg; + new_time <<= 8; + *rtc_reg = NVRAM_RTC_MINUTES; + new_time |= (unsigned long)*rtc_reg; + new_time <<= 8; + *rtc_reg = NVRAM_RTC_SECONDS; + new_time |= (unsigned long)*rtc_reg; + *rtc_reg = NVRAM_RTC_YEARS; + new_date |= (unsigned long)*rtc_reg; + new_date <<= 8; + *rtc_reg = NVRAM_RTC_MONTHS; + new_date |= (unsigned long)*rtc_reg; + new_date <<= 8; + *rtc_reg = NVRAM_RTC_DAYS; + new_date |= (unsigned long)*rtc_reg; + if(!time) + time = new_time; + if(!date) + date = new_date; + delta_time = new_time - time; + if(delta_time < 0) + delta_time = - delta_time; + if((delta_time > 2) || (date != new_date)) + { + MCF_UART3_UTB = 0x82; /* header */ + for(i = 0; i < 64; i++) + { + while(!(MCF_UART3_USR & MCF_UART_USR_TXEMP)); + *rtc_reg = (unsigned char)i; + MCF_UART3_UTB = *rtc_data; /* send data */ + } + } + *rtc_reg = reg; + asm_set_ipl(level); +// if((delta_time > 2) || (date != new_date)) +// board_printf("RTC update to the PIC\r\n"); + time = new_time; + date = new_date; + } + /* Toggle led */ + if(!(count & 7)) + MCF_GPIO_PODR_FEC1L &= ~MCF_GPIO_PODR_FEC1L_PODR_FEC1L4; + else if((count & 7) == 4) + MCF_GPIO_PODR_FEC1L |= MCF_GPIO_PODR_FEC1L_PODR_FEC1L4; + /* RTC update to the PIC */ + /* Send VBL interrupt */ + MCF_INTC_INTFRCL |= MCF_INTC_INTFRCL_INTFRC4; /* force INT 4 */ + /* VBL delay */ + vTaskDelay((20*configTICK_RATE_HZ)/1000); + count++; + } + } +} + +static portTASK_FUNCTION(vETOS,pvParmeters) +{ + void (*fp)(void) = (void(*)(void))0xE00000; + (*fp)(); +} + +static void go_emutos(unsigned long source) +{ + extern void end_vdi(); + extern long init_videl(long width, long height, long bpp, long refresh, long extended); + extern void new_zero_divide(void); + extern void new_trap(void); + extern void new_mfp(void); + extern unsigned char __LWIP_BASE[]; + extern void *info_fvdi; +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + extern void *usb_malloc(long amount); + COOKIE *pci_cookie = *(COOKIE **)cookie; +#endif + unsigned long top = (unsigned long)__LWIP_BASE - 0x100000; /* - 1MB */ + int i; + mcf548x_ac97_uninstall(2, 0); + vTaskDelay(1); +// uninstall_inters_cf68klib(); + vTaskDelete(tid_TOS); + end_vdi(); /* for screen WEB server and mousexy() */ + if(source != 0xE0600000) + { + void (*fp)(void) = (void(*)(void))source; + asm_set_ipl(7); /* disable interrupts */ + (*fp)(); + } +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) + pci_data = NULL; + while(pci_cookie != NULL) + { + if(pci_cookie->ident == '_PCI') + { + pci_data = usb_malloc(PCI_COOKIE_TOTALSIZE); + if(pci_data != NULL) + memcpy(pci_data, (void *)pci_cookie->v.l, PCI_COOKIE_TOTALSIZE); + break; + } + if(!pci_cookie->ident) + pci_cookie = NULL; + else + pci_cookie++; + } +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) */ +#if 1 + init_videl(640, 480, 4, 60, 0xD00000); + memset((void *)0xD00000, 0, (640 * 480 * 4) /sizeof(short)); +#else + init_videl(640, 480, 16, 60, 0xD00000); + memset((void *)0xD00000, -1, 640 * 480 * sizeof(short)); +#endif + info_fvdi = NULL; + asm_set_ipl(7); /* disable interrupts */ + for(i = 1; i < 16; *(unsigned long *)(((32+i) * 4) + coldfire_vector_base) = (unsigned long)new_trap, i++); + *(unsigned long *)((5 * 4) + coldfire_vector_base) = (unsigned long)new_zero_divide; /* Zero Divide */ + *(unsigned long *)((10 * 4) + coldfire_vector_base) = (unsigned long)new_trap; /* LineA */ + *(unsigned long *)((15 * 4) + coldfire_vector_base) = (unsigned long)new_trap; /* LineF */ + *(unsigned long *)(((64+6) * 4) + coldfire_vector_base) = (unsigned long)new_mfp; /* IRQ6 EPORT */ + pseudo_dma_vec = *(unsigned long *)0x13C; + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE6; + if(save_imrl_tos & MCF_INTC_IMRL_INT_MASK5) + MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_MASKALL); + else /* PCI used */ + { + /* move PCI CF68KLIB interrupt vector to native coldfire vector */ + *(unsigned long *)(((64+5) * 4) + coldfire_vector_base) = *(unsigned long *)((64+5+OFFSET_INT_CF68KLIB) * 4); /* IRQ5 EPORT */ + MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL); + } + top &= 0xFFF00000; + disable_caches(); + asm volatile ( + " move.l #0x0000E040,D0\n\t" /* zone at $00000000 to $00FFFFFF in cache inhibit */ + " movec.l D0,ACR0\n\t" ); + memcpy((void *)0xE00000,(void *)source,0x80000); /* copy Emutos */ + asm volatile ( + " moveq #0,D0\n\t" + " movec.l D0,ACR0\n\t" ); + mmu_map(top,top,0,MMUDR_SZ1M+MMUDR_NOCACHE+MMUDR_LK); + *(unsigned long *)ramtop = top; + enable_caches(); + xTaskCreate(vETOS, (void *)"ETOS", STACK_DEFAULT, NULL, TOS_TASK_PRIORITY, &tid_ETOS); + xTaskCreate(vVBL, (void *)"VBL", STACK_DEFAULT, NULL, VBL_TASK_PRIORITY, NULL); +} + +#endif /* MCF547X */ + +static void uif_cmd_go(int argc, char **argv) +{ + int index, success; + if(argc == 2) + { + void (*fp)(void) = (void(*)(void))get_value(argv[1],&success,16); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } +#ifdef MCF547X + if(((unsigned long)fp == 0xE0600000) || ((unsigned long)fp == 0xE0400000)) + { + go_emutos((unsigned long)fp); + return; + } +#endif + (*fp)(); + } + *(unsigned long *)(cpu_trace_count) = 0; + if(breakpoint_install(*(unsigned short *)(save_format) ? *(unsigned long *)(save_pc) : (unsigned long)-1)) /* insert all breakpoints */ + *(unsigned long *)(cpu_trace_thru) = *(unsigned long *)(save_pc); /* PC is at breakpoint */ + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid == BKPT_PERM) + { + if(brktab[index].tid) + { +// board_printf("Resume task TID: %X\r\n", brktab[index].tid); + resume_task(brktab[index].tid); + brktab[index].tid = 0; + } + } + } +} + +static void uif_cmd_st(int argc, char **argv) +{ + int index, success, found = 0; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid == BKPT_PERM) + { + if(brktab[index].tid) + { + *(unsigned long *)(cpu_trace_count) = 1; + if(argc == 2) + { + *(unsigned long *)(cpu_trace_count) = get_value(argv[1],&success,10); + if(!success) + *(unsigned long *)(cpu_trace_count) = 1; + } + if(breakpoint_find(*(unsigned long *)(save_pc)) == -1) + { + *(unsigned long *)(cpu_step_over) = *(unsigned long *)(save_pc); + breakpoint_add(*(unsigned long *)(cpu_step_over), BKPT_TEMP); + } + breakpoint_install((unsigned long)-1); +// board_printf("Resume task TID: %X\r\n", brktab[index].tid); + resume_task(brktab[index].tid); + found = 1; + } + } + } + if(!found) + board_printf("Error: No task supended by a breakpoint to trace\r\n"); +} + +#ifndef MCF5445X +#ifdef SOUND_AC97 + +static void uif_cmd_ac97_pr(int argc, char **argv) +{ + unsigned long datar, dataw; + int done, success; + unsigned long address; + char string[UIF_MAX_LINE]; + (void)argc; + address = get_value(argv[1],&success,16); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } + address = cpu_align_address(address,SIZE_16); + if(argv[2] != NULL) + { + /* the data has been specified */ + dataw = get_value(argv[2],&success,BASE); + if(success == 0) + board_printf(INVALUE,argv[2]); + else + mcf548x_ac97_debug_write(AC97_DEVICE,address,dataw); + return; + } + else if(pxCurrentTCB != tid_TELNET) + { + done = FALSE; + while(!done) + { + address &= 0x7f; + datar = mcf548x_ac97_debug_read(AC97_DEVICE,address); + board_printf("%02X: ", (int)address); + board_printf("[%04X] ", (int)datar); + get_line(string); + if(make_argv(string, NULL) == 0) + goto next_addr; + else + { + dataw = get_value(string, &success, BASE); + if(!success) + { + /* Check for special cases */ + if(string[0] == '=') + goto same_addr; + if(string[0] == '^') + { + address -= 2; + goto same_addr; + } + done = TRUE; + } + else + mcf548x_ac97_debug_write(AC97_DEVICE,address,dataw); + } +next_addr: + address += 2; +same_addr: + ; + } + } + else + board_printf(SYNTAX,argv[0]); +} + +#endif /* MCF5445X */ +#endif /* SOUND_AC97 */ + +static void uif_cmd_md(int argc, char **argv) +{ + int success, size; + unsigned long begin, end; + unsigned long contents; + size = cpu_parse_size(argv[0]); + if(argc > 1) + { + if((argc == 2) && (argv[1][0] == '*')) + { + begin = get_value(&argv[1][1],&success,BASE); + if(success) + { + contents = cpu_read_data(begin,SIZE_32); + board_printf("%08X contains %08X\r\n", (int)begin, (int)contents); + begin = contents; + end = contents+(DEFAULT_MD_LINES*16); + goto show_mem; + } + else + { + board_printf(INVALUE,argv[1]); + return; + } + } + begin = get_value(argv[1],&success,16); + if(!success) + { + board_printf(INVALUE,argv[1]); + return; + } + if(argc == 3) + { + end = get_value(argv[2],&success,16); + if(!success) + { + board_printf(INVALUE,argv[2]); + return; + } + if(begin > end) + { + unsigned long temp = end; + end = begin; + begin = temp; + } + } + else + end = begin + (DEFAULT_MD_LINES * 16); + } + else + { + begin = md_last_address; + if(md_last_size) + size = md_last_size; + end = begin + (DEFAULT_MD_LINES * 16); + } +show_mem: + begin = cpu_align_address(begin,size); + dump_mem(begin,end,size); + md_last_address = end; + md_last_size = size; +} + +static void uif_cmd_pm(int argc, char **argv) +{ + unsigned long datar, dataw; + int size, done, success; + unsigned long address; + char string[UIF_MAX_LINE]; + (void)argc; + size = cpu_parse_size(argv[0]); + address = get_value(argv[1],&success,16); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } + address = cpu_align_address(address,size); + if(argv[2] != NULL) + { + /* the data has been specified */ + dataw = get_value(argv[2],&success,BASE); + if(success == 0) + board_printf(INVALUE,argv[2]); + else + cpu_write_data(address,size,dataw); + return; + } + else if(pxCurrentTCB != tid_TELNET) + { + done = FALSE; + while(!done) + { + datar = cpu_read_data(address, size); + board_printf("%08X: ", (int)address); + switch(size) + { + case SIZE_8: board_printf("[%02X] ", (int)datar); break; + case SIZE_16: board_printf("[%04X] ", (int)datar); break; + case SIZE_32: board_printf("[%08X] ", (int)datar); break; + } + get_line(string); + if(make_argv(string, NULL) == 0) + goto next_addr; + else + { + dataw = get_value(string, &success, BASE); + if(!success) + { + /* Check for special cases */ + if(string[0] == '=') + goto same_addr; + if(string[0] == '^') + { + switch(size) + { + case SIZE_8: address -= 1; break; + case SIZE_16: address -= 2; break; + case SIZE_32: address -= 4; break; + } + goto same_addr; + } + done = TRUE; + } + else + cpu_write_data(address,size,dataw); + } +next_addr: + switch(size) + { + case SIZE_8: address += 1; break; + case SIZE_16: address += 2; break; + case SIZE_32: address += 4; break; + } +same_addr: + ; + } + } + else + board_printf(SYNTAX,argv[0]); +} + +static void uif_cmd_dis(int argc, char **argv) +{ + struct DisasmPara_68k dp; + char buffer[16]; + m68k_word *ip, *p; + char opcode[16]; + char operands[128]; + char iwordbuf[32]; + char *s; + unsigned long pc; + int i, n, success; + pc = 0; // cpu_pc_get(); + if(argc == 2) + { + /* Address to start disasm at */ + pc = get_value(argv[1],&success,BASE); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } + } + else + { + /* command given with no args -- repeat */ + if(disasm_last_address != 0) + pc = disasm_last_address; + } + p = (m68k_word *)pc; + db_radix = BASE; + dp.instr = NULL; /* pointer to instruction to disassemble */ + dp.iaddr = NULL; /* instr.addr., usually the same as instr */ + dp.opcode = opcode; /* buffer for opcode, min. 16 chars. */ + dp.operands = operands; /* operand buffer, min. 128 chars. */ + dp.radix = 16; /* base 2, 8, 10, 16 ... */ +/* call-back functions for symbolic debugger support */ + dp.get_areg = NULL; /* returns current value of reg. An */ + dp.find_symbol = NULL; /* finds closest symbol to addr and */ + /* returns (positive) difference and name */ +/* changed by disassembler: */ + dp.type = 0; /* type of instruction, see below */ + dp.flags = 0; /* additional flags */ + dp.reserved = 0; + dp.areg = 0; /* address reg. for displacement (PC=-1) */ + dp.displacement = 0; /* branch- or d16-displacement */ + for(i=0;i<16;i++) + { + for(n = 0; n 5) + n = 5; + ip = dp.instr; + s = iwordbuf; + while(n--) + { + sprintD(buffer,"%04X",(int)((((unsigned long)*(unsigned char *)ip)<<8) | ((unsigned long)*((unsigned char *)ip+1)))); + *s++ = buffer[0]; + *s++ = buffer[1]; + *s++ = buffer[2]; + *s++ = buffer[3]; + s++; + ip++; + } + board_printf("%08X: %s", (int)dp.iaddr, iwordbuf); + strcpy(buffer, " "); + n = 0; + while(opcode[n]) + { + buffer[n] = opcode[n]; + n++; + } + buffer[n] = 0; + board_printf("%s %s\r\n", buffer, operands); + } + disasm_last_address = (unsigned long)p; +} + +static void uif_cmd_dr(int argc, char **argv) +{ + unsigned long reg[40]; + portSTACK_TYPE p[64]; + portSTACK_TYPE *p1; + portSTACK_TYPE pc; + portSTACK_TYPE frame_format; + int i, j, vector; + if(argv); + if(argc); + vTaskSuspendAll(); + memcpy(reg, (void *)(library_data_area), 40 * sizeof(unsigned long)); +#ifdef MCF547X + memcpy(p, (tid_ETOS != NULL) ? tid_ETOS : tid_TOS, 64 * sizeof(portSTACK_TYPE)); +#else + memcpy(p, tid_TOS, 64 * sizeof(portSTACK_TYPE)); +#endif + p1 = (portSTACK_TYPE *)p[0]; + frame_format = p1[0]; + pc = p1[1]; + xTaskResumeAll(); +#ifdef MCF547X + if(tid_ETOS == NULL) +#endif + { + vector = (int)((reg[38] >> 2) & 255); + board_printf("CF68KLIB data area, fault #%d: ", vector); + switch(vector) + { + case 2: board_printf("Access Fault"); break; + case 3: board_printf("Address Error"); break; + case 4: board_printf("Illegal Instruction"); break; + case 5: board_printf("Integer Zero Divide"); break; + case 8: board_printf("Privilege Violation"); break; + case 9: board_printf("Trace"); break; + case 10: board_printf("Line A"); break; + case 11: board_printf("Line F"); break; + case 14: board_printf("Format Error"); break; + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: board_printf("Trap #%d", vector - 32); break; + } + board_printf("\r\nStatus Register (SR): %04X\r\n", (int)reg[17]>>16); + board_printf("Program Counter (PC): %08X\r\n", (int)reg[16]); + board_printf("Supervisor Stack (SSP): %08X\r\n", (int)reg[19]); + board_printf("User Stack (USP): %08X\r\n", (int)reg[18]); + for(i = j = 0; i < 8; i++) + board_printf("D%d: %08X A%d: %08X\r\n", i, (int)reg[i], i, (int)reg[i+8]); + if(((vector == 4) || (vector == 8)) + && (*(unsigned long *)(save_pc_cf68klib) < (unsigned long)__SDRAM_SIZE)) + board_printf("%s (emul)\r\n", disassemble_pc(*(unsigned long *)(save_pc_cf68klib))); + if(reg[16] < (unsigned long)__SDRAM_SIZE) + board_printf("%s\r\n", disassemble_pc(reg[16])); + } + board_printf("TOS task context saving:\r\n"); + board_printf("Status Register (SR): %04X\r\n", (int)(frame_format & 0xFFFF)); + board_printf("Program Counter (PC): %08X\r\n", (int)pc); + board_printf("Supervisor Stack (SSP): %08X\r\n", (int)p[0]); + board_printf("User Stack (USP): %08X\r\n", (int)p[16]); + for(i = j = 0; i < 8; i++, j += 2) + { + board_printf("D%d: %08X A%d: %08X FP%d: %08X%08X\r\n", + i, (int)p[i+1], i, (int)p[i+9], + i, (int)p[j+22], (int)p[j+23]); + } + if(pc < (portSTACK_TYPE)__SDRAM_SIZE) + board_printf("%s\r\n", disassemble_pc(pc)); +} + +static void uif_cmd_qt(int argc, char **argv) +{ + if(argc); + if(argv); + static char buf[80*50]; +#if( HAVE_USP == 1 ) + board_printf("Name\t\tTID\tPrio\tStatus\tSys/User Stack\t#\r\n"); +#else + board_printf("Name\t\tTID\tPrio\tStatus\tStack\t\t#\r\n"); +#endif + board_printf("------------------------------------------------------------"); + vTaskList((void *)buf); + board_printf(buf); +} + +#if 0 +static void uif_cmd_trace(int argc, char **argv) +{ +#define DEFAULT_TRACE_SIZE 0x10000 + static char *buffer_trace = NULL; + static unsigned long size_trace = DEFAULT_TRACE_SIZE; + static char default_name[] = "trace.bin"; + static char filename_trace[UIF_MAX_LINE]; + long file_w; + int success; + unsigned long val; + if(strcmp(argv[1],"on") == 0) + { + if(buffer_trace != NULL) + { + board_printf("Trace tasks already running, use before\r\n"); + return; + } + if((argc == 3) && (val = get_value(argv[2],&success,10)) != 0) + { + size_trace = val; + strcpy(filename_trace, default_name); + } + else if(argc > 3) + { + val = get_value(argv[3],&success,10); + if(val) + size_trace = val; + else + size_trace = DEFAULT_TRACE_SIZE; + strcpy(filename_trace, argv[2]); + } + else + { + size_trace = DEFAULT_TRACE_SIZE; + strcpy(filename_trace, default_name); + } + if((buffer_trace = (char *)pvPortMalloc(size_trace)) == NULL) + { + board_printf("Not enough memory for create trace buffer\r\n"); + return; + } + vTaskStartTrace(buffer_trace, size_trace); + } + else if(strcmp(argv[1],"off") == 0) + { + if(buffer_trace == NULL) + { + board_printf("Trace tasks already stopped, use before\r\n"); + return; + } + val = ulTaskEndTrace(); + Fdelete(filename_trace); + if((file_w = Fcreate(filename_trace, 0)) < 0) + board_printf("Cannot create file %s\r\n", filename_trace); + else + { + Fwrite(file_w, val, buffer_trace); + Fclose(file_w); + } + vPortFree(buffer_trace); + buffer_trace = NULL; + } + else + board_printf("Usage: trace on/off \r\n"); +} +#endif + +static void uif_cmd_cat(int argc, char **argv) +{ +#define SIZE_BUFFER_CAT 10000 +#define SIZE_BUF_CAT 80 + long file_r = 0, file_w = 0; + int i, timeout, len, edit=0, cat=0, size=0; + char *p, *buffer=NULL; + static char buf[SIZE_BUF_CAT+1]; + static char buf2[SIZE_BUF_CAT*2+1]; + buf[SIZE_BUF_CAT] = '\0'; + if(argc > 2) + { + p = argv[argc-2]; + if(p[0] == '>') + { + cat++; + if(p[1] == '>') + cat++; + if(argc == 3) + edit = 1; + } + switch(cat) + { + case 1: + file_w = Fcreate(argv[argc-1], 0); + if(file_w < 0) + { + board_printf("Cannot create file %s (error: %d)\r\n", argv[argc-1], file_w); + return; + } + break; + case 2: + file_w = Fopen(argv[argc-1], 2); + if(file_w == ENOENT) + file_w = Fcreate(argv[argc-1], 0); + if(file_w < 0) + { + board_printf("Cannot write file %s (error: %d)\r\n", argv[argc-1], file_w); + return; + } + Fseek(0, file_w, 2); /* end */ + break; + } + } + if(edit && ((buffer = pvPortMalloc(SIZE_BUFFER_CAT)) != NULL)) + { + char ch; + size = 0; + while(((ch = board_getchar()) != CTRL_D) && (ch != CTRL_C) + && (size < SIZE_BUFFER_CAT)) + { + switch(ch) + { + case '\r': + board_putchar('\r'); + board_putchar('\n'); + if(size < SIZE_BUFFER_CAT) + buffer[size++] = '\r'; + if(size < SIZE_BUFFER_CAT) + buffer[size++] = '\n'; + break; + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(size > 0) + { + size--; + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + break; + default: + if(size < SIZE_BUFFER_CAT) + { + if((ch > 0x1f) && ((unsigned char)ch < 0x80)) + { + buffer[size++] = ch; + board_putchar(ch); + } + } + break; + } + } + board_putchar('\r'); + board_putchar('\n'); + Fwrite(file_w, size, buffer); + } + for(i = 1; i < (cat ? argc-2 : argc); i++) + { + if((file_r = Fopen(argv[i], 0)) >= 0) + { + do + { + len = Fread(file_r, SIZE_BUF_CAT, buf); + if(cat && (len > 0)) + len = Fwrite(file_w, len, buf); + else if(!cat && (len == SIZE_BUF_CAT)) + { + char ch = 0; + int j = 0, k = 0; + while(buf[j]) + { + if((buf[j] == '\n') && (ch != '\r')) + buf2[k++] = '\r'; + buf2[k++] = ch = buf[j++]; + } + buf2[k] = 0; + board_printf(buf2); + timeout = 0; + while(!(ch = auxistat()) && (timeout < (configTICK_RATE_HZ*1920)/(SIZE_BUF_CAT*1000))) + vTaskDelay(1); + if(ch && ((ch = rs232get() & 0xFF) == CTRL_C)) + { + len = 0; + i = argc; + break; + } + } + } + while(len == SIZE_BUF_CAT); + if(!cat) + { + char ch = 0; + int j = 0, k = 0; + buf[len] = '\0'; + while(buf[j]) + { + if((buf[j] == '\n') && (ch != '\r')) + buf2[k++] = '\r'; + buf2[k++] = ch = buf[j++]; + } + buf2[k] = 0; + board_printf(buf2); + if(i >= argc-1) + board_printf("\r\n"); + vTaskDelay((configTICK_RATE_HZ*1920)/(SIZE_BUF_CAT*1000)); + } + Fclose(file_r); + } + else + board_printf("Cannot open file %s (error: %d)\r\n", argv[1], file_r); + } + if(cat) + Fclose(file_w); + if(buffer != NULL) + vPortFree(buffer); +} + +static void uif_cmd_chdir(int argc, char **argv) +{ + int err; + if(argc); + if((err = Dsetpath(argv[1])) < 0) + board_printf("Cannot change to directory %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_chmod(int argc, char **argv) +{ + int err; + long attr = 0; + if(argc); + if(strchr(argv[2], 'a')) + attr |= FA_ARCHIVE; + if(strchr(argv[2], 's')) + attr |= FA_SYSTEM; + if(strchr(argv[2], 'h')) + attr |= FA_HIDDEN; + if(strchr(argv[2], 'r')) + attr |= FA_RO; + if((err = Fattrib(argv[1], 1, attr)) < 0) + board_printf("Cannot change attributes of file %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_cp(int argc, char **argv) +{ + long file_r, file_w; + int len; + char buf[512]; + if((file_r = Fopen(argv[1], 0)) >= 0) + { + if((file_w = Fcreate(argv[2], 0)) >= 0) + { + do + { + len = Fread(file_r, 512, buf); + if(len) + Fwrite(file_w, len, buf); + } + while(len == 512); + Fclose(file_w); + } + else + board_printf("Cannot create file\r\n"); + Fclose(file_r); + } + else + board_printf("File not found\r\n"); +} + +static void uif_cmd_ls(int argc, char **argv) +{ + int i, err; + static DTAINFO dta; + char name[14]; + if(argc); + if(argv); + Fsetdta(&dta); + if(argc > 1) + err = Fsfirst(argv[1], FA_SUBDIR|FA_SYSTEM|FA_HIDDEN|FA_RO); + else + err = Fsfirst(".\\*.*", FA_SUBDIR|FA_SYSTEM|FA_HIDDEN|FA_RO); + while(!err) + { + if(dta.dt_fname[0] == '.') + { + err = Fsnext(); + continue; + } + if(dta.dt_fattr & FA_ARCHIVE) + board_printf("a"); + else + board_printf("-"); + if(dta.dt_fattr & FA_SUBDIR) + board_printf("d"); + else + board_printf("-"); + if(dta.dt_fattr & FA_VOL) + board_printf("v"); + else + board_printf("-"); + if(dta.dt_fattr & FA_SYSTEM) + board_printf("s"); + else + board_printf("-"); + if(dta.dt_fattr & FA_HIDDEN) + board_printf("h"); + else + board_printf("-"); + if(dta.dt_fattr & FA_RO) + board_printf("r"); + else + board_printf("-"); + i = 0; + while(dta.dt_fname[i]) + { + if((dta.dt_fname[i] >= 'A') && (dta.dt_fname[i] <= 'Z')) + name[i] = dta.dt_fname[i] + 0x20; + else + name[i] = dta.dt_fname[i]; + i++; + } + name[i] = '\0'; + board_printf(" %d\t%02d/%02d/%04d %02d:%02d\t%s\r\n", + (int)dta.dt_fileln, + (int)dta.dt_date & 0x1F, + (int)(dta.dt_date >> 5) & 0xF, + (int)((dta.dt_date >> 9) & 0x3F) + 1980, + (int)(dta.dt_time >> 11) & 0x1F, + (int)(dta.dt_time >> 5) & 0x3F, + name); + err = Fsnext(); + } +} + +static void uif_cmd_mkdir(int argc, char **argv) +{ + int err; + if(argc); + if((err = Dcreate(argv[1])) < 0) + board_printf("Cannot create directory %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_mv(int argc, char **argv) +{ + int err; + if(argc); + if((err = Frename(argv[1], argv[2])) < 0) + board_printf("Cannot rename file %s to %s (error: %d)\r\n", argv[1], argv[2], err); +} + +static void uif_cmd_rm(int argc, char **argv) +{ + int err; + if(argc); + if((err = Fdelete(argv[1])) < 0) + board_printf("Cannot remove file %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_rmdir(int argc, char **argv) +{ + int err; + if(argc); + if((err = Ddelete(argv[1])) < 0) + board_printf("Cannot remove directory %s (error: %d)\r\n", argv[1], err); +} + +/*---------------------------------------------------------------------*/ +/* Fonction arp */ +/*---------------------------------------------------------------------*/ + +static void uif_cmd_arp(int argc, char **argv) +{ + extern struct netif *netif_list; + struct netif *netif; + struct in_addr addr; + struct ip_addr ipaddr; + struct eth_addr *eth_ret; + struct ip_addr *ip_ret; + if(strcmp(argv[1], "-a") == 0) + { + argc--; + argv++; + } + if(argc == 2) + { + if(netif_list != NULL) + { + for(netif = netif_list; netif != NULL; netif = netif->next) + { + if((netif->name[0] == 'l') && (netif->name[1] == 'o')) + continue; + addr.s_addr = netif->ip_addr.addr; + board_printf("Interface: %s:\r\n", inet_ntoa(addr)); + addr.s_addr = inet_addr(argv[1]); + ipaddr.addr = addr.s_addr; + if(etharp_find_addr(netif, &ipaddr, ð_ret, &ip_ret) >= 0) + board_printf(" %s at %02X:%02X:%02X:%02X:%02X:%02X\r\n", inet_ntoa(addr), + eth_ret->addr[0], eth_ret->addr[1], eth_ret->addr[2], + eth_ret->addr[3], eth_ret->addr[4], eth_ret->addr[5]); + } + } + } + else + { + char i; + if(netif_list != NULL) + { + for(netif = netif_list; netif != NULL; netif = netif->next) + { + if((netif->name[0] == 'l') && (netif->name[1] == 'o')) + continue; + addr.s_addr = netif->ip_addr.addr; + board_printf("Interface: %s:\r\n", inet_ntoa(addr)); + i = 0; + while((i = etharp_find_index_addr(netif, i, ð_ret, &ip_ret)) >= 0) + { + addr.s_addr = ip_ret->addr; + board_printf(" %s at %02X:%02X:%02X:%02X:%02X:%02X\r\n", inet_ntoa(addr), + eth_ret->addr[0], eth_ret->addr[1], eth_ret->addr[2], + eth_ret->addr[3], eth_ret->addr[4], eth_ret->addr[5]); + i++; + } + } + } + } +} + +#endif /* DBUG */ +#endif /* COLDFIRE */ + +/*---------------------------------------------------------------------*/ +/* Fonction ifconfig */ +/*---------------------------------------------------------------------*/ + +static void ife_print(struct netif *ptr) +{ + struct in_addr addr; + board_printf("%c%c%d ", ptr->name[0], ptr->name[1], ptr->num); + board_printf("flags=%d ( ", ptr->flags); + if(ptr->flags == 0) + board_printf("[NO FLAGS] "); + if(ptr->flags & NETIF_FLAG_UP) + board_printf("UP "); + if(ptr->flags & NETIF_FLAG_BROADCAST) + board_printf("BROADCAST "); + if(ptr->flags & NETIF_FLAG_POINTTOPOINT) + board_printf("POINTOPOINT "); + if(ptr->flags & NETIF_FLAG_LINK_UP) + board_printf("RUNNING "); + board_printf(") mtu %d \r\n", ptr->mtu); + addr.s_addr = ptr->ip_addr.addr; + board_printf(" inet %s ", inet_ntoa(addr)); + addr.s_addr = ptr->netmask.addr; + board_printf(" netmask %s ", inet_ntoa(addr)); + addr.s_addr = ptr->gw.addr; + board_printf(" gateway %s", inet_ntoa(addr)); + board_printf("\r\n"); + if((ptr->hwaddr[0] != 0) || (ptr->hwaddr[1] != 0) || (ptr->hwaddr[2] != 0) + || (ptr->hwaddr[3] != 0) || (ptr->hwaddr[4] != 0) || (ptr->hwaddr[5] != 0)) + board_printf(" ether %02X:%02X:%02X:%02X:%02X:%02X\r\n", + ptr->hwaddr[0], ptr->hwaddr[1], ptr->hwaddr[2], ptr->hwaddr[3], ptr->hwaddr[4], ptr->hwaddr[5]); +} + +static int if_print(char *ifname) +{ + int res = 0; + if(!ifname) + { + extern struct netif *netif_list; + struct netif *netif; + if(netif_list != NULL) + { + for(netif = netif_list; netif != NULL; netif = netif->next) + ife_print(netif); + } + else + res = -1; + } + else + { + struct netif *ife = netif_find(ifname); + if(ife != NULL) + ife_print(ife); + else + res = -1; + } + return(res); +} + +/* Set a certain interface flag. */ +static int netif_set_flag(char *ifname, int flag) +{ + struct netif *ifr = netif_find(ifname); + if(ifr == NULL) + return(-1); + switch(flag) + { + case NETIF_FLAG_UP: netif_set_up(ifr); break; + default : return(-1); + } + return(0); +} + +/* Clear a certain interface flag. */ +static int netif_clr_flag(char *ifname, int flag) +{ + struct netif *ifr = netif_find(ifname); + if(ifr == NULL) + return(-1); + switch(flag) + { + case NETIF_FLAG_UP: netif_set_down(ifr); break; + default : return(-1); + } + return(0); +} + +static void usage_ifconfig(void) +{ + board_printf("Usage:\r\n ifconfig [-a] \r\n"); + board_printf(" [dstaddr
] [netmask
] [gateway
] [up|down]\r\n\n"); +} + +void uif_cmd_ifconfig(int argc, char **argv) +{ +#define IFNAMSIZ 4 + char ifr_name[IFNAMSIZ]; + int opt_a = 0; /* show all interfaces */ + struct netif *netif; + struct ip_addr addr; + char host[64]; + int goterr = 0; + char **spp; + /* Find any options. */ + argc--; + argv++; + while(argc && *argv[0] == '-') + { + if(!strcmp(*argv, "-a")) + opt_a = 1; + if(!strcmp(*argv, "-?") || !strcmp(*argv, "-h") + || !strcmp(*argv, "-help") || !strcmp(*argv, "--help")) + { + usage_ifconfig(); + return; + } + argv++; + argc--; + } + /* Do we have to show the current setup? */ + if(argc == 0) + { + if_print((char *) NULL); + return; + } + /* No. Fetch the interface name */ + spp = argv; + strncpy(ifr_name, *spp++, IFNAMSIZ); + if(*spp == NULL) + { + if_print(ifr_name); + return; + } + /* Process the remaining arguments */ + while(*spp != NULL) + { + if(!strcmp(*spp, "up")) + goterr = netif_set_flag(ifr_name, NETIF_FLAG_UP); + else if(!strcmp(*spp, "down")) + goterr = netif_clr_flag(ifr_name, NETIF_FLAG_UP); + else if(!strcmp(*spp, "dstaddr")) + { + if(*++spp == NULL) + { + usage_ifconfig(); + return; + } + strncpy(host, *spp, (sizeof host)); + netif = netif_find(ifr_name); + addr.addr = inet_addr(host); + if(netif != NULL) + netif_set_ipaddr(netif, &addr); + else + goterr = -1; + } + else if(!strcmp(*spp, "netmask")) + { + if(*++spp == NULL) + { + usage_ifconfig(); + return; + } + strncpy(host, *spp, (sizeof host)); + netif = netif_find(ifr_name); + addr.addr = inet_addr(host); + if(netif != NULL) + netif_set_netmask(netif, &addr); + else + goterr = -1; + } + else if(!strcmp(*spp, "gateway")) + { + if(*++spp == NULL) + { + usage_ifconfig(); + return; + } + strncpy(host, *spp, (sizeof host)); + netif = netif_find(ifr_name); + addr.addr = inet_addr(host); + if(netif != NULL) + netif_set_gw(netif, &addr); + else + goterr = -1; + } + if(goterr) + { + board_printf("Error: Interface %s not found\r\n", ifr_name); + return; + } + spp++; + } +} + + +#ifdef COLDFIRE +#ifdef DBUG + +/*---------------------------------------------------------------------*/ +/* Fonction ping */ +/*---------------------------------------------------------------------*/ + +// Structure de l'en-tête IP +typedef struct iphdr +{ + unsigned int version:4; // !!!! + unsigned int h_len:4; // swap if big-endian ???? + unsigned char tos:8; + unsigned short total_len:16; + unsigned short ident:16; + unsigned short offset:16; + unsigned char ttl:8; + unsigned char proto:8; + unsigned short checksum:16; + unsigned int sourceIP:32; + unsigned int destIP:32; +} IpHeader __attribute__((__packed__)); + +// Structure de l'en-tête ICMP +typedef struct icmphdr +{ + unsigned char type:8; + unsigned char code:8; + unsigned short checksum:16; + unsigned short id; + unsigned short sequence; + unsigned long timestamp; +} IcmpHeader __attribute__((__packed__)); + +#define MAX_PACKET 1024 +#define DATASIZE_ICMP 16 +#define NBDEFAULT 4 +#define DELAI 1000 +#define IPPROTO_ICMP 1 /* control message protocol */ + +#if 0 +// Définition des messages d'erreur +char Erreur3[16][55]= +{ + "Reseau inaccessible", + "Impossible de joindre l'hote de destination", + "Protocole inaccessible", + "Port inaccessible", + "Fragmentation necessaire", + "Echec de la route source", + "Reseau de destination inconnu", + "Machine de destination inconnue", + "Machine source isolee", + "Reseau de destination administrativement interdit", + "Machine de destination administrativement interdite", + "Reseau inaccessible pour TOS", + "Machine inaccessible pour TOS", + "Communication administrativement interdite par filtrage", + "Violation de la precedence de la machine", + "Coupure de la precedence en action" +}; + +char Erreur4[1][16]= +{ + "Debit trop eleve" +}; + +char Erreur5[4][40]= +{ + "Redirige pour un reseau", + "Redirige pour une machine", + "Redirige pour type de service et reseau", + "Redirige pour type de service et machine" +}; + +char Erreur11[2][40]= +{ + "Time-to-live a 0 pendant le transit", + "Time-to-live a 0 pendant le reassemblage" +}; + +char Erreur12[2][25]= +{ + "Mauvais en-tete IP", + "Option requise manquante" +}; +#endif + +static unsigned short checksum(unsigned short *, int); +static unsigned long GetTickCount(void); + +static int max, min, moyenne, envoye, perte; + +static void uif_cmd_ping(int argc, char **argv) +{ +// Définition des différentes variables + unsigned long IP; + struct ip_addr xIpAddr; + int sock; + struct sockaddr_in sin, from; + int envoi, recept; + IcmpHeader *icmp_hdr; + char ascii_IP[16]; + char icmp_data[DATASIZE_ICMP]; + char recvbuf[MAX_PACKET]; + int fromlen = sizeof(from); + fd_set fdsr; + struct timeval tv_timeout; + int Nbping = 0; + int id, i, taille; + int recus, pourcent; + int findelai, tpslimite = 0; + min = 0x7ffffff; + max = moyenne = envoye = perte = recus = pourcent = 0; + // Accès à l'aide + if(argc < 2 || strcmp(argv[1],"--help") == 0) + { + board_printf("Usage: ping <-n echos> <-w delay> host\r\n"); + return; + } + // Identification des différentes options + for(i = 1; i < argc; i++) + { + if(strcmp(argv[i],"-n") == 0) + Nbping = (int)atol(argv[i+1]); + if(strcmp(argv[i],"-w") == 0) + tpslimite = (int)atol(argv[i+1]); + } + sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if(sock == -1) + return; + memset(&sin,0,sizeof(sin)); + // Récupération de l'IP + if(!inet_aton(argv[argc-1],&sin.sin_addr)) + return; + sin.sin_family = AF_INET; + taille = sizeof(IpHeader) + sizeof(IcmpHeader); + strcpy(ascii_IP, inet_ntoa(sin.sin_addr)); + board_printf("Envoi d'une requete 'ping' sur %s avec %d octets de donnees :\r\n\r\n", ascii_IP, taille); + board_get_client((unsigned char *)&IP); + xIpAddr.addr = htonl(IP); + if(sin.sin_addr.s_addr == xIpAddr.addr) + sin.sin_addr.s_addr = INADDR_LOOPBACK; + // Initialisation du nombre de ping à faire + if(Nbping == 0) + Nbping = NBDEFAULT; + // Initialisation du délai d'attente + if(tpslimite == 0) + tpslimite = DELAI; + while(envoye != Nbping) + { + memset(icmp_data,0,DATASIZE_ICMP); + id =(unsigned short)((int)pxCurrentTCB + envoye); + // Construction du paquet ICMP + icmp_hdr = (IcmpHeader*)icmp_data; + icmp_hdr->type = 8; // Type du paquet ICMP : echo request + icmp_hdr->code = 0; // Il n'y a pas de code spécifique pour ce type de paquet + icmp_hdr->id = id; + icmp_hdr->sequence = 1; + icmp_hdr->timestamp = GetTickCount(); // Initialisation du temps lors de l'envoi + // Somme de contrôle sur 16 bits + ((IcmpHeader*)icmp_data)->checksum = checksum((unsigned short*)icmp_data, DATASIZE_ICMP); + // On envoie le paquet ICMP que l'on a construit + envoi = sendto(sock, icmp_data, DATASIZE_ICMP, 0, (struct sockaddr *)&sin, DATASIZE_ICMP); + findelai = 0; + do + { + FD_ZERO(&fdsr); + FD_SET(sock, &fdsr); + tv_timeout.tv_sec = tpslimite/1000; + tv_timeout.tv_usec = 0; + if((i = select(FD_SETSIZE, &fdsr, NULL, NULL, &tv_timeout)) <= 0) + { + // Dans le cas où le temps est écoulé, on veut sortir de la boucle + // on compte le paquet comme envoyé mais perdu + board_printf("Delai d'attente de la demande depasse.\r\n"); + perte++; + envoye++; + findelai = 1; + } + if((i > 0) && FD_ISSET(sock, &fdsr)) + { + IpHeader *iphdr; + IcmpHeader *icmphdr; + unsigned short iphdrlen; + int ttl, time, taille; + char tps[32]; + char buffer[32]; + // Dans le cas où le buffer du socket contient des données, on les décode + recept = recvfrom(sock, recvbuf, MAX_PACKET, 0, (struct sockaddr *)&from, &fromlen); + // Décodage du paquet ICMP de réponse + iphdr = (IpHeader *)recvbuf; + iphdrlen = iphdr->h_len * 4 ; + icmphdr = (IcmpHeader*)(recvbuf + iphdrlen); + if(id != (icmphdr->id)) + findelai = 0; // Cas où le paquet n'est pas à nous + else + { + findelai = 1; + envoye++; + if((icmphdr->type != 8) && (icmphdr->type != 0)) + board_printf("Reponse de %s : ", ascii_IP); + switch(icmphdr->type) + { +#if 0 + case 3: + board_printf("%s.\r\n", Erreur3[icmphdr->code]); + break; + case 4: + board_printf("%s.\r\n", Erreur4[icmphdr->code]); + break; + case 5: + board_printf(" %s.\r\n", Erreur5[icmphdr->code]); + break; + case 11: + board_printf("%s.\r\n", Erreur11[icmphdr->code]); + break; + case 12: + board_printf("%s.\r\n", Erreur12[icmphdr->code]); + break; +#else + case 3: + case 4: + case 5: + case 11: + case 12: + board_printf("Erreur %d.\r\n", icmphdr->code); + break; +#endif + case 0: + case 8: + if((icmphdr->code) == 0) + { + ttl = (iphdr->ttl); + time = GetTickCount(); // Récupération du temps courant + time -= (icmphdr->timestamp); // Différence entre réception et émission + if(time > 1000/configTICK_RATE_HZ) + { + strcpy(tps, "="); + sprintD(buffer, "%d", time); + strcat(tps, buffer); + } + else + { + strcpy(tps, "<"); + sprintD(buffer, "%d", (int)(1000/configTICK_RATE_HZ)); + strcat(tps, buffer); + time = 0; + } + if(time > max) + max = time; + if(time < min) + min = time; + moyenne += time; + taille = iphdrlen + sizeof(IcmpHeader); + board_printf("Reponse de %s: icmp=%d octets=%d ", ascii_IP, envoye, taille); + board_printf("temps%s ms TTL=%d\r\n", tps, ttl); + } + break; + default: + // Cas où le type n'est pas une erreur reconnue par la RFC (cas très improblable !!!) + board_printf("Erreur inconnue.\r\n"); + break; + } + } + memset(recvbuf,0,MAX_PACKET); + } + if(auxistat() && ((rs232get() & 0xFF) == CTRL_C)) + Nbping = envoye; + } + while(findelai == 0); + // Latence d'une seconde entre chaque ping + if(envoye != Nbping) + vTaskDelay(configTICK_RATE_HZ); + } + board_printf("\n\rStatistiques Ping pour %s :\r\n",ascii_IP); + recus = envoye-perte; + pourcent = (perte*100)/envoye; + board_printf(" Paquets : envoyes = %d, recus = %d, perdus = %d (perte %d%%),\r\n", envoye, recus, perte, pourcent); + board_printf("Duree approximative des boucles en millisecondes :\r\n"); + if(recus!=0) + moyenne=moyenne/recus; + if(min > max) + min = 0; + board_printf(" minimum = %dms, maximum = %dms, moyenne = %dms\r\n", min, max, moyenne); + board_printf("\r\n"); +} + +static unsigned long GetTickCount(void) +{ + return(xTaskGetTickCount() * (1000 / configTICK_RATE_HZ)); +} + +// Fonction faisant la somme de contrôle sur 16 bits +static unsigned short checksum(unsigned short *buffer, int size) +{ + unsigned long cksum=0; + while(size >1) + { + cksum+=*buffer++; + size -=sizeof(unsigned short); + } + if(size) + cksum += *(unsigned char*)buffer; + cksum = (cksum >> 16) + (cksum & 0xffff); + cksum += (cksum >>16); + return (unsigned short)(~cksum); +} + +static void uif_cmd_stats(int argc, char **argv) +{ + if(argc); + if(argv); + stats_display(); +} + +static void uif_cmd_cache(int argc, char **argv) +{ + if(argc); + if((argc == 2) && (strcmp(argv[1],"on") == 0)) + enable_caches(); + else if((argc == 2) && (strcmp(argv[1],"off") == 0)) + disable_caches(); + else if(argc < 2) + { + unsigned long cacr = *(unsigned long *)(library_data_area + 96); // CACR cf68klib + board_printf("CACR: 0x%08X\r\n", cacr); + } + else + board_printf("Usage: cache \r\n"); +} + +static void uif_cmd_debug(int argc, char **argv) +{ + int success; + unsigned long val; + unsigned char debug = *(unsigned char *)(debug_cf68klib); + if(strcmp(argv[1],"on") == 0) + { + if(!debug) + { + if(argc == 3) + { + val = get_value(argv[2],&success,10); + if(val > 255) /* 0 => infinite */ + val = 255; + *(unsigned char *)(debug_cf68klib_count) = (unsigned char)val; + } + else + *(unsigned char *)(debug_cf68klib_count) = 255; + *(unsigned char *)(debug_cf68klib) = 1; + } + } + else if(strcmp(argv[1],"off") == 0) + { + if(debug) + *(unsigned char *)(debug_cf68klib) = *(unsigned char *)(debug_cf68klib_count) = 0; + } + else + board_printf("Usage: debug on/off\r\n"); +} + +static void uif_cmd_inter(int argc, char **argv) +{ +#ifndef MCF547X + if((argc == 2) && strcmp(argv[1],"on") == 0) + install_inters_cf68klib(); + else if((argc == 2) && strcmp(argv[1],"off") == 0) + uninstall_inters_cf68klib(); +#endif +#ifdef MCF5445X + else if((argc == 2) && strcmp(argv[1],"abort") == 0) + { + int level = vPortSetIPL(portIPL_MAX); + *(unsigned char *)(debug_int7) = 1; + /* Enable EPORT interrupt 7 requests */ + MCF_EPORT_EPIER |= EPORT_EPIER_EPIE7; + /* Allow interrupts from IRQ7 */ + MCF_INTC_IMRL0 &= ~INTC_IMRL_INT_MASK7; + save_imrl0 = MCF_INTC_IMRL0; + vPortSetIPL(level); + } + else + board_printf("Usage: inter on/off/abort\r\n"); +#else /* MCF548X */ +#ifndef MCF547X + else if((argc == 2) && strcmp(argv[1],"abort") == 0) + { + int level = vPortSetIPL(portIPL_MAX); + *(unsigned char *)(debug_int7) = 1; + /* Enable EPORT interrupt 7 requests */ + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE7; + /* Allow interrupts from IRQ7 */ + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK7; + save_imrl = MCF_INTC_IMRL; + vPortSetIPL(level); + } + else if(argc < 2) +#endif /* MCF547X */ + { + static char *names_int[] = { + "", /* 64 */ + "Edge port 1", /* 65 */ + "Edge port 2", /* 66 */ + "Edge port 3", /* 67 */ + "Edge port 4", /* 68 */ + "Edge port 5", /* 69 */ + "Edge port 6", /* 70 */ + "Edge port 7", /* 71 */ + "", /* 72 */ + "", /* 73 */ + "", /* 74 */ + "", /* 75 */ + "", /* 76 */ + "", /* 77 */ + "", /* 78 */ +#ifdef MCF547X /* interrupts not used on FIREBEE */ + "", /* 79 */ + "", /* 80 */ + "", /* 81 */ + "", /* 82 */ + "", /* 83 */ + "", /* 84 */ + "", /* 85 */ + "", /* 86 */ + "", /* 87 */ + "", /* 88 */ + "", /* 89 */ + "", /* 90 */ + "", /* 91 */ + "", /* 92 */ + "", /* 93 */ + "", /* 94 */ + "", /* 95 */ +#else + "USB 2.0", /* 79 */ + "USB 2.0", /* 80 */ + "USB 2.0", /* 81 */ + "USB 2.0", /* 82 */ + "USB 2.0", /* 83 */ + "USB 2.0", /* 84 */ + "USB 2.0", /* 85 */ + "USB 2.0", /* 86 */ + "USB 2.0", /* 87 */ + "USB 2.0", /* 88 */ + "DSPI", /* 89 */ + "DSPI", /* 90 */ + "DSPI", /* 91 */ + "DSPI", /* 92 */ + "DSPI", /* 93 */ + "DSPI", /* 94 */ + "DSPI", /* 95 */ +#endif + "PSC3", /* 96 */ + "PSC2", /* 97 */ + "PSC1", /* 98 */ + "PSC0", /* 99 */ + "Comm Timer", /* 100 */ +#ifdef MCF547X /* not used on FIREBEE */ + "", /* 101 */ + "", /* 102 */ +#else + "SEC", /* 101 */ + "FEC1", /* 102 */ +#endif + "FEC0", /* 103 */ + "I2C", /* 104 */ + "PCIARB", /* 105 */ + "CBPCI", /* 106 */ + "XLBPCI", /* 107 */ + "", /* 108 */ + "", /* 109 */ + "", /* 110 */ + "XLBARB", /* 111 */ + "DMA", /* 112 */ +#ifdef MCF547X + "", /* 113 */ + "", /* 114 */ + "", /* 115 */ +#else /* MCF548X */ + "CAN0 ERROR", /* 113 */ + "CAN0 BUSOFF", /* 114 */ + "CAN0 MBOR", /* 115 */ +#endif /* MCF547X */ + "", /* 116 */ + "SLT1", /* 117 */ + "SLT0", /* 118 */ +#ifdef MCF547X + "", /* 119 */ + "", /* 120 */ + "", /* 121 */ +#else /* MCF548X */ + "CAN1 ERROR", /* 119 */ + "CAN1 BUSOFF", /* 120 */ + "CAN1 MBOR", /* 121 */ +#endif /* MCF547X */ + "", /* 122 */ + "GPT3", /* 123 */ + "GPT2", /* 124 */ + "GPT1", /* 125 */ + "GPT0", /* 126 */ + "" /* 127 */ + }; + int i; + board_printf("NATIVE/RTOS\tCF68KLIB/TOS\tLEV\tPRI\tINTERRUPTS\r\n"); + for(i = 0; i < 64; i++) + { + if(strlen(names_int[i])) + { + unsigned long imr, imr_tos; + int j; + if(i < 32) + { + imr = save_imrl; + imr_tos = save_imrl_tos; + j = i; + } + else + { + imr = save_imrh; + imr_tos = save_imrh_tos; + j = i - 32; + } + board_printf("%s\t\t%s\t\t%d\t%d\t%s Int(%d)\r\n", + !(imr & (1 << j)) ? "ON" : "OFF", + !(imr_tos & (1 << j)) ? "ON" : "OFF", + (MCF_INTC_ICRn(i) >> 3) & 7, MCF_INTC_ICRn(i) & 7, + names_int[i], i + 64); + } + } + } +#ifndef MCF547X + else + board_printf("Usage: inter \r\n"); +#endif +#endif /* MCF5445X */ +} + +void uif_cmd_reset(int argc, char **argv) +{ + if(argc); + if(argv); + board_putchar('\r'); + board_putchar('\n'); + board_putchar_flush(); + (void)vPortSetIPL(portIPL_MAX); + /* Watchdog Reset */ +#ifdef MCF5445X + MCF_INTC_IMRH0 = MCF_INTC_IMRL0 = MCF_INTC_IMRH1 = MCF_INTC_IMRL1 = 0xFFFFFFFF; + MCF_SCM_CWCR = SCM_CWCR_CWE | SCM_CWCR_CWRI(2) | SCM_CWCR_CWT(8); +#else /* MCF548X */ + MCF_INTC_IMRH = MCF_INTC_IMRL = 0xFFFFFFFF; + MCF_GPT_GMS(0) = 0; + MCF_GPT_GCIR(0) = 10 | (SYSTEM_CLOCK << 16); /* 10 uS */ + MCF_GPT_GMS(0) = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_CE | MCF_GPT_GMS_WDEN; /* watchdog timer */ +#endif /* MCF5445X */ + while(1) + { + asm volatile(" nop\n\t"); + MCF_UART_UTB(0) = '.'; + } +} + +static void uif_cmd_trap(int argc, char **argv) +{ + int success; + unsigned long val; + unsigned char debug = *(unsigned char *)(debug_trap); + if(strcmp(argv[1],"on") == 0) + { + if(!debug) + { + if(argc == 3) + { + val = get_value(argv[2],&success,10); + if(val > 255) /* 0 => infinite */ + val = 255; + *(unsigned char *)(debug_trap_count) = (unsigned char)val; + } + else + *(unsigned char *)(debug_trap_count) = 255; + *(unsigned char *)(debug_trap) = 1; + } + } + else if(strcmp(argv[1],"off") == 0) + { + if(debug) + *(unsigned char *)(debug_trap) = *(unsigned char *)(debug_trap_count) = 0; + } + else + board_printf("Usage: trap on/off\r\n"); +} + +static UIF_CMD UIF_CMDTAB[] = +{ + /* <1> command name user types, ie. GO */ + /* <2> num chars to uniquely match */ + /* <3> min num of args command accepts */ + /* <4> max num of args command accepts */ + /* <5> command flags (repeat, hidden) */ + /* <6> actual function to call */ + /* <7> brief description of command */ + /* <8> syntax of command */ +#ifndef MCF5445X +#ifdef SOUND_AC97 + {"acpr",4,1,2,0,uif_cmd_ac97_pr,"AC97 Patch Register","addr "}, +#endif +#endif +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + {"usb",3,0,4,0,uif_cmd_usb,"USB sub-system",""}, +#endif + {"cb",2,0,1,0,uif_cmd_cb,"Clear Breakpoint",""}, + {"db",2,0,UIF_MAX_ARGS-1,0,uif_cmd_db,"Define Breakpoint"," <-c|t value> <-r addr..> <-i> <-m>"}, + {"dm",2,0,2,UIF_CMD_FLAG_REPEAT,uif_cmd_md,"Display Memory","begin "}, + {"md",2,0,2,UIF_CMD_FLAG_REPEAT|UIF_CMD_FLAG_HIDDEN,uif_cmd_md,"Memory Display","begin "}, + {"dis",2,0,1,UIF_CMD_FLAG_REPEAT,uif_cmd_dis,"Disassemble",""}, + {"dr",2,0,0,0,uif_cmd_dr,"Display Registers CF68KLIB",""}, + {"go",1,0,1,0,uif_cmd_go,"Execute, Insert Breakpt",""}, + {"lb",2,0,0,0,uif_cmd_lb,"List Breakpoints",""}, + {"pm",2,1,2,0,uif_cmd_pm,"Patch Memory","addr "}, + {"qt",2,0,0,UIF_CMD_FLAG_REPEAT,uif_cmd_qt,"Query Tasks",""}, + {"st",2,0,1,UIF_CMD_FLAG_REPEAT,uif_cmd_st,"Single Step (after db)",""}, +// {"trace",2,1,3,0,uif_cmd_trace,"Task Trace","on/off "}, + {"cat",2,1,UIF_MAX_ARGS-1,0,uif_cmd_cat,"Concatenate File(s)","file(s)"}, + {"cd",2,1,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_chdir,"Change Directory","dir"}, + {"chdir",2,1,1,0,uif_cmd_chdir,"Change Directory","dir"}, + {"chmod",5,2,2,0,uif_cmd_chmod,"Change Attibutes","filename attributes"}, + {"cp",2,2,2,0,uif_cmd_cp,"Copy File","source dest"}, + {"copy",4,2,2,UIF_CMD_FLAG_HIDDEN,uif_cmd_cp,"Copy File","source dest"}, + {"del",3,1,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_rm,"Remove File","file"}, + {"dir",3,0,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_ls,"List Directory",""}, + {"ls",2,0,1,0,uif_cmd_ls,"List Directory",""}, + {"mkdir",2,1,1,0,uif_cmd_mkdir,"Make Directory","dir"}, + {"mv",2,2,2,0,uif_cmd_mv,"Rename File","source dest"}, + {"rename",3,2,2,UIF_CMD_FLAG_HIDDEN,uif_cmd_mv,"Rename File","source dest"}, + {"rm",2,1,1,0,uif_cmd_rm,"Remove File","file"}, + {"rmdir",2,1,1,0,uif_cmd_rmdir,"Remove Directory","dir"}, + {"type",4,1,UIF_MAX_ARGS-1,UIF_CMD_FLAG_HIDDEN,uif_cmd_cat,"Concatenate File(s)","file(s)"}, + {"arp",2,0,2,0,uif_cmd_arp,"Address Resol. Protocol","<-a> "}, + {"ifconfig",2,0,UIF_MAX_ARGS-1,0,uif_cmd_ifconfig,"Interface Configuration","<-a> ..."}, + {"ping",2,1,5,0,uif_cmd_ping,"Ping","<-n echos> <-w delay> host"}, + {"netstat",2,0,0,0,uif_cmd_stats,"Network Stats",""}, + {"cache",2,0,1,0,uif_cmd_cache,"Cache",""}, + {"debug",2,1,2,0,uif_cmd_debug,"Debug CF68KLIB","on/off "}, +#ifdef MCF547X + {"inter",1,0,1,0,uif_cmd_inter,"Interrupts CF68KLIB",""}, +#else + {"inter",2,0,1,0,uif_cmd_inter,"Interrupts CF68KLIB",""}, +#endif + {"reset",5,0,0,0,uif_cmd_reset,"System Reset",""}, + {"shutdown",8,0,0,UIF_CMD_FLAG_HIDDEN,uif_cmd_reset,"System Reset",""}, + {"trap",4,1,2,0,uif_cmd_trap,"Traps CF68KLIB","on/off "}, + {"help",2,0,1,0,uif_cmd_help,"Help",""}, +}; +static const int UIF_NUM_CMD = UIF_CMDTAB_SIZE; + +static void help_display(int index) +{ + board_printf(HELPFORMAT, UIF_CMDTAB[index].cmd, UIF_CMDTAB[index].description, + UIF_CMDTAB[index].cmd, UIF_CMDTAB[index].syntax); +} + +static void uif_cmd_help(int argc, char **argv) +{ + int index, displayed; + if(argc == 1) + { + /* Display all command summaries */ + board_printf(HELPFORMAT,"Command","Description","Syntax",""); + displayed = 1; + for(index = 0; index < UIF_NUM_CMD; index++) + { + if(!(UIF_CMDTAB[index].flags & UIF_CMD_FLAG_HIDDEN)) + help_display(index); + } + return; + } + else + { + /* Display specific command summary */ + for(index = 0; index < UIF_NUM_CMD; index++) + { + if(strcasecmp(UIF_CMDTAB[index].cmd,argv[1]) == 0) + { + board_printf(HELPFORMAT,"Command","Description","Syntax",""); + help_display(index); + return; + } + } + for(index = 0; index < UIF_NUM_CMD; index++) + { + if(strncasecmp(UIF_CMDTAB[index].cmd,argv[1], UIF_CMDTAB[index].unique) == 0) + { + board_printf(HELPFORMAT,"Command","Description","Syntax",""); + help_display(index); + return; + } + } + board_printf(INVCMD,argv[1]); + } +} + +static int make_argv(char *cmdline, char *argv[]) +{ + int argc, i, in_text; + /* break cmdline into strings and argv */ + /* it is permissible for argv to be NULL, in which case */ + /* the purpose of this routine becomes to count args */ + argc = 0; + i = 0; + in_text = FALSE; + while(cmdline[i] != '\0') /* getline() must place 0x00 on end */ + { + if(((cmdline[i] == ' ') || (cmdline[i] == '\t')) ) + { + if(in_text) + { + /* end of command line argument */ + cmdline[i] = '\0'; + in_text = FALSE; + } + else + { + /* still looking for next argument */ + } + } + else + { + /* got non-whitespace character */ + if(in_text) + { + } + else + { + /* start of an argument */ + in_text = TRUE; + if(argc < UIF_MAX_ARGS) + { + if(argv != NULL) + argv[argc] = &cmdline[i]; + argc++; + } + else + /*return argc;*/ + break; + } + } + i++; /* proceed to next character */ + } + if(argv != NULL) + argv[argc] = NULL; + return argc; +} + +static int run_cmd(void) +{ + /* Global array of pointers to emulate C argc,argv interface */ + int argc; + char *argv[UIF_MAX_ARGS + 1]; /* one extra for null terminator */ + get_history_line(cmdline1); + if(!(argc = make_argv(cmdline1, argv))) + { + /* no command entered, just a blank line */ + strcpy(cmdline1, cmdline2); + argc = make_argv(cmdline1, argv); + } + cmdline2[0] = '\0'; + if(argc) + { + int i; + /* + * First try for an exact match on command name + */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strcasecmp(UIF_CMDTAB[i].cmd,argv[0]) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + return(TRUE); + } + else + { + board_printf(SYNTAX,argv[0]); + return(TRUE); + } + } + } + /* + * Now try for short-hand match on command name + */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strncasecmp(UIF_CMDTAB[i].cmd,argv[0], UIF_CMDTAB[i].unique) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + return(TRUE); + } + else + { + board_printf(SYNTAX,argv[0]); + return(TRUE); + } + } + } + board_printf(INVCMD,argv[0]); + board_printf(HELPMSG); + } + return(FALSE); +} + +/*---------------------------------------------------------------------*/ +/* FTP Server */ +/*---------------------------------------------------------------------*/ + +#ifdef FTP_SERVER +static portTASK_FUNCTION(vFTPd, pvParameters) +{ + if(pvParameters); + ftpd_start(FTP_USERNAME, FTP_PASSWORD); + vTaskDelete(0); +} +#endif + +/*---------------------------------------------------------------------*/ +/* TFTP Server */ +/*---------------------------------------------------------------------*/ + +static portTASK_FUNCTION(vTFTPd, pvParameters) +{ + extern long ram_disk_drive; + long file; + unsigned long bytes_read; + static struct sockaddr_in address, adresse, from, to; + socklen_t lg=sizeof(struct sockaddr_in); + socklen_t fromlen=lg, tolen=lg; + static char buf[PKTSIZE],ackbuf[PKTSIZE]; + struct tftphdr *tp = (struct tftphdr *)&buf; + char filename[256]; + char *dat, *cp, *p; + struct tftphdr *dp, *ap; + int i=0, size, Oldsize=PKTSIZE, n, ntimeout, peer, sock, nextBlockNumber; + struct timeval tv; + fd_set data_read; + if(pvParameters); + if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + board_printf("TFTPd: create server socket error (err %d)\r\n",errno); + vTaskDelete(0); + } + address.sin_family=AF_INET; + address.sin_addr.s_addr=htonl(INADDR_ANY); + address.sin_port=htons(PortTFTP); + if(bind(sock, (struct sockaddr *)&address, lg) < 0) + { + board_printf("TFTPd: bind server error (err %d)\r\n",errno); + close(sock); + vTaskDelete(0); + } + while(1) + { + do + n=recvfrom(sock, tp, PKTSIZE, 0, (struct sockaddr *)&to, &tolen); + while(n < 0); + tp->th_opcode = htons((u_short)tp->th_opcode); + cp = (char *)&tp->th_stuff[0]; + p = &cp[SEGSIZE-5]; + while((cp < p) && *cp && (*cp != ' ')) + cp++; + if(*cp && (*cp != ' ')) + continue; + *cp = '\0'; + filename[0] = 'C'; + filename[1] = ':'; + filename[2] = '\\'; + filename[3] = '\0'; + if(ram_disk_drive >= 1) + filename[0] =(char)ram_disk_drive + 'A'; + strcat(filename, &tp->th_stuff[0]); + dp = (struct tftphdr *)buf; + ap = (struct tftphdr *)ackbuf; + dat = (char*)&dp->th_data[0]; + cp = (char *)&dp->th_stuff[0]; + if((peer = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + board_printf("TFTPd: create socket client error (err %d)\r\n",errno); + continue; + } + adresse.sin_family=AF_INET; + adresse.sin_addr.s_addr=htonl(INADDR_ANY); + adresse.sin_port=htons(0); + if(bind(peer, (struct sockaddr *)&adresse, lg) < 0) + { + board_printf("TFTPd: bind client error (err %d)\r\n",errno); + close(peer); + continue; + } + switch(tp->th_opcode) + { + case WRQ: + Fdelete(filename); + if((file = Fcreate(filename, 0)) < 0) + { + board_printf("TFTPd: cannot create file %s\r\n", filename); + close(peer); + break; + } + ap->th_opcode=htons((u_short)ACK); + ap->th_block=0; + size=4; + nextBlockNumber = 1; + do + { + ntimeout = 0; + do + { + if(ntimeout == NumberTimeOut) + /* could not make connection */ + goto tftp_close; + if(sendto(peer, ap, size, 0, (struct sockaddr *)&to, tolen) != size) + { + board_printf("TFTPd: sendto error\r\n"); + goto tftp_close; + } + do + { + n = -1; + FD_ZERO(&data_read); + FD_SET(peer, &data_read); + tv.tv_sec = TimeOut; + tv.tv_usec = 0; + if((i = select(FD_SETSIZE, &data_read, NULL, NULL, &tv)) == -1) + { + board_printf("TFTPd: select error (err %d)\r\n",errno); + goto tftp_close; + } + if((i > 0) && FD_ISSET(peer, &data_read)) + n = recvfrom(peer, dp, PKTSIZE, 0, (struct sockaddr *)&from, &fromlen); + } + while((n < 0) && (i > 0)); + if(i > 0) + { + to.sin_port = from.sin_port; + dp->th_opcode = ntohs((unsigned short)dp->th_opcode); + dp->th_block = ntohs((unsigned short)dp->th_block); + if(dp->th_opcode != DATA) + { + if(dp->th_opcode == ERROR) + board_printf("TFTPd: TFTP error #%d : %s\r\n",(int)dp->th_code, &dp->th_data[0]); + goto tftp_close; + } + if((int)dp->th_block < nextBlockNumber) + { + /* Re-ACK this packet */ + ap->th_block = htons(dp->th_block); + ap->th_opcode = htons((unsigned short)ACK); + if(sendto(peer, ap, 4, 0,(struct sockaddr *)&to, tolen) != size) + { + // write Re-ACK error + board_printf("TFTPd: sendto error (err %d)\r\n",errno); + goto tftp_close; + } + continue; + } + else if((int)dp->th_block != nextBlockNumber) + /* This is NOT the block number expected */ + continue; + } + ntimeout++; + } + while((int)dp->th_block != nextBlockNumber); + ap->th_block = htons((unsigned short)nextBlockNumber); + size = 4; + if(n-4 > 0) + { + bytes_read += (n-4); + Fwrite(file, n-4, (char *)dat); + } + nextBlockNumber++; + } + while(n == PKTSIZE); + /* send the "final" ack */ + sendto(peer, ap, 4, 0,(struct sockaddr *)&to, tolen); +tftp_close: + close(peer); + Fclose(file); + break; + case RRQ: + if((file = Fopen(filename, 0)) < 0) + { + board_printf("TFTPd: cannot open file %s\r\n", filename); + close(peer); + break; + } + dp->th_opcode=htons((unsigned short)DATA); + dp->th_block=htons((unsigned short)1); + size = Fread(file, SEGSIZE, (char *)dat); + if(size == 0) + goto tftp_close; + size += 4; + nextBlockNumber = 1; + do + { + ntimeout = 0; + do + { + if(ntimeout == NumberTimeOut) + /* could not make connection */ + goto tftp_close; + if(sendto(peer, dp, size, 0, (struct sockaddr *)&to, tolen) != size) + { + board_printf("TFTPd: sendto error\r\n"); + goto tftp_close; + }; + do + { + n = -1; + FD_ZERO(&data_read); + FD_SET(peer,&data_read); + tv.tv_sec = TimeOut; + tv.tv_usec = 0; + if((i = select(FD_SETSIZE, &data_read, NULL, NULL, &tv)) == -1) + { + board_printf("TFTPd: select error (err %d)\r\n",errno); + goto tftp_close; + } + if((i > 0) && FD_ISSET(peer, &data_read)) + n = recvfrom(peer, ap, PKTSIZE, 0,(struct sockaddr *)&from, &fromlen); + } + while((n < 0) && (i > 0)); + if(i > 0) + { + to.sin_port=from.sin_port; + ap->th_opcode = ntohs((unsigned short)ap->th_opcode); + ap->th_block = ntohs((unsigned short)ap->th_block); + if(ap->th_opcode != ACK) + { + if(ap->th_opcode == ERROR) + board_printf("TFTPd: TFTP error #%d : %s\r\n",(int)ap->th_code, &ap->th_data[0]); + goto tftp_close; + } + if((int)ap->th_block < nextBlockNumber) + { + /* Re-ACK this packet */ + dp->th_block = htons(ap->th_block); + dp->th_opcode = htons((unsigned short)ACK); + if(sendto(peer, dp, 4, 0,(struct sockaddr *)&to, tolen) != size) + { + board_printf("TFTPd: sendto error (err %d)\r\n",errno); + goto tftp_close; + } + continue; + } + else if((int)ap->th_block != nextBlockNumber) + continue; + } + ntimeout++; + } + while((int)ap->th_block != nextBlockNumber); + if((size < PKTSIZE) && (nextBlockNumber != 0)) + break; // all is already send inside the 1st packet of DATA + nextBlockNumber++; + dp->th_block = htons((unsigned short)nextBlockNumber); + if(nextBlockNumber == 1) + { + dp->th_opcode=htons((u_short)DATA); // used only if InClient=1 + size = Fread(file, SEGSIZE, (char *)dat); + } + else + { + Oldsize = size; + if(Oldsize == PKTSIZE) + size = Fread(file, SEGSIZE, (char *)dat); + } + size += 4; + } + while(Oldsize == PKTSIZE); + close(peer); + Fclose(file); + break; + } + } +} + +/*---------------------------------------------------------------------*/ +/* Telnet Server */ +/*---------------------------------------------------------------------*/ + +static void sendopt(struct termstate *ts, int code, int option) +{ + unsigned char buf[3]; + buf[0] = TELNET_IAC; + buf[1] = (unsigned char) code; + buf[2] = (unsigned char) option; + send(ts->sock, buf, 3, 0); +} + +static void parseopt(struct termstate *ts, int code, int option) +{ + switch(option) + { + case TELOPT_ECHO: + break; + case TELOPT_SUPPRESS_GO_AHEAD: + if(code == TELNET_WILL || code == TELNET_WONT) + sendopt(ts, TELNET_DO, option); + else + sendopt(ts, TELNET_WILL, option); + break; + case TELOPT_TERMINAL_TYPE: + case TELOPT_NAWS: + case TELOPT_TERMINAL_SPEED: + sendopt(ts, TELNET_DO, option); + break; + default: + if(code == TELNET_WILL || code == TELNET_WONT) + sendopt(ts, TELNET_DONT, option); + else + sendopt(ts, TELNET_WONT, option); + break; + } +} + +static void parseoptdat(struct termstate *ts, int option, unsigned char *data, int len) +{ + switch(option) + { + case TELOPT_NAWS: + if(len == 4) + { + int cols = ntohs(*(unsigned short *) data); + int lines = ntohs(*(unsigned short *) (data + 2)); + if(cols) + ts->term.cols = cols; + if(lines) + ts->term.lines = lines; + } + break; + case TELOPT_TERMINAL_SPEED: + break; + case TELOPT_TERMINAL_TYPE: + break; + } +} + +static void parse(struct termstate *ts) +{ + unsigned char *p = ts->bi.start; + unsigned char *q = p; + while(p < ts->bi.end) + { + int c = *p++; + switch (ts->state) + { + case STATE_NORMAL: + if (c == TELNET_IAC) + ts->state = STATE_IAC; + else + *q++ = c; + break; + case STATE_IAC: + switch (c) + { + case TELNET_IAC: + *q++ = c; + ts->state = STATE_NORMAL; + break; + case TELNET_WILL: + case TELNET_WONT: + case TELNET_DO: + case TELNET_DONT: + ts->code = c; + ts->state = STATE_OPT; + break; + case TELNET_SB: + ts->state = STATE_SB; + break; + default: + ts->state = STATE_NORMAL; + } + break; + case STATE_OPT: + parseopt(ts, ts->code, c); + ts->state = STATE_NORMAL; + break; + case STATE_SB: + ts->code = c; + ts->optlen = 0; + ts->state = STATE_OPTDAT; + break; + case STATE_OPTDAT: + if(c == TELNET_IAC) + ts->state = STATE_SE; + else if(ts->optlen < sizeof(ts->optdata)) + ts->optdata[ts->optlen++] = c; + break; + case STATE_SE: + if(c == TELNET_SE) + parseoptdat(ts, ts->code, ts->optdata, ts->optlen); + ts->state = STATE_NORMAL; + break; + } + } + ts->bi.end = q; +} + +static portTASK_FUNCTION(vTELNETd, pvParameters) +{ + struct sockaddr_in sin; + fd_set fdsr; + struct timeval tv_timeout; + static char cmdline1[UIF_MAX_LINE]; + static char cmdline2[UIF_MAX_LINE]; + int sock, s, rc, n, argc, pos, ch, i, j; + char *argv[UIF_MAX_ARGS + 1]; /* one extra for null terminator */ + pos = 0; + if(pvParameters); + ts = (struct termstate *)pvPortMalloc(sizeof(struct termstate)); + if(ts == NULL) + { + printD("TELNETd: malloc error\r\n"); + vTaskDelete(0); + } + sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) + { + printD("TELNETd: error %d in socket\r\n", errno); + vTaskDelete(0); + } + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(PortTELNET); + rc = bind(sock, (struct sockaddr *) &sin, sizeof sin); + if(rc < 0) + { + printD("TELNETd: error %d in bind\r\n", errno); + vTaskDelete(0); + } + rc = listen(sock, 5); + if(rc < 0) + { + printD("TELNETd: error %d in listen\r\n", errno); + close(sock); + vTaskDelete(0); + } + while(1) + { + int off = 0; + struct sockaddr_in sin; + int len = sizeof(sin); + s = accept(sock, (struct sockaddr *)&sin, &len); + if(s < 0) + { + printD("TELNETd: error %d in accept\r\n", errno); + close(sock); + vTaskDelete(0); + } + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&off, sizeof(off)); + /* Initialize terminal state */ + memset(ts, 0, sizeof(struct termstate)); + ts->sock = s; + ts->state = STATE_NORMAL; + ts->term.type = TERM_VT100; + ts->term.cols = 80; + ts->term.lines = 25; + /* Send initial options */ + sendopt(ts, TELNET_WILL, TELOPT_ECHO); + ts->bo.start = ts->bo.data; + board_putchar_flush(); + board_printf(PROMPT); + board_putchar_flush(); + while(1) + { + FD_ZERO(&fdsr); + FD_SET(ts->sock, &fdsr); + tv_timeout.tv_sec = 1; + tv_timeout.tv_usec = 0; + if((i = select(FD_SETSIZE, &fdsr, NULL, NULL, &tv_timeout)) == -1) + { + printD("TELNETd: error %d in select\r\n", errno); +done: + close(ts->sock); + ts->sock = -1; + break; + } + if((i > 0) && FD_ISSET(ts->sock, &fdsr)) + { + if(ts->bi.start == ts->bi.end) + { + /* Read data from user */ + n = recv(ts->sock, ts->bi.data, sizeof(ts->bi.data), 0); + if(n < 0) + goto done; + ts->bi.start = ts->bi.data; + ts->bi.end = ts->bi.data + n; + } + /* Parse user input for telnet options */ + parse(ts); + if(ts->bi.start != ts->bi.end) + { + /* Write data to application */ + n = (int)(ts->bi.end - ts->bi.start); + for(j = 0; j < n; j++) + { + ch = (int)ts->bi.start[j]; + if((ch != '\r') && (ch != '\n') && (pos < UIF_MAX_LINE)) + { + switch(ch) + { + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(pos > 0) + { + pos -= 1; +// board_putchar(0x08); /* backspace */ +// board_putchar(' '); +// board_putchar(0x08); /* backspace */ + } + break; + default: + if((pos+1) < UIF_MAX_LINE) + { + /* only printable characters */ + if((ch > 0x1f) && (ch < 0x80)) + { + cmdline1[pos++] = (char)ch; +// board_putchar((char)ch); + } + } + break; + } + } + else + { + cmdline1[pos] = '\0'; + board_putchar('\r'); + board_putchar('\n'); + if(!(argc = make_argv(cmdline1, argv))) + { + /* no command entered, just a blank line */ + strcpy(cmdline1, cmdline2); + argc = make_argv(cmdline1, argv); + } + cmdline2[0] = '\0'; + if(argc) + { + /* First try for an exact match on command name */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strcasecmp(UIF_CMDTAB[i].cmd,argv[0]) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + goto next_cmd; + } + else + { + board_printf(SYNTAX,argv[0]); + goto next_cmd; + } + } + } + /* Now try for short-hand match on command name */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strncasecmp(UIF_CMDTAB[i].cmd,argv[0], UIF_CMDTAB[i].unique) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + goto next_cmd; + } + else + { + board_printf(SYNTAX,argv[0]); + goto next_cmd; + } + } + } + board_printf(INVCMD,argv[0]); + board_printf(HELPMSG); + } +next_cmd: + board_putchar_flush(); + board_printf(PROMPT); + board_putchar_flush(); + pos = 0; + } + } + ts->bi.start += n; + } + } + } + } +} + +static void *test_debug_fault(unsigned long address, unsigned long vector, unsigned char *RegList) +{ +#ifndef MCF547X + (void)RegList; +#endif + if(pxCurrentTCB == tid_TOS) + { +#ifndef KILL_TOS_ON_FAULT + if(address >= (unsigned long)__SDRAM_SIZE) + vector = 0; /* => kill TOS */ + switch(vector) + { + case 3: /* Address Error */ + case 4: /* Illegal Instruction */ + case 5: /* Integer Zero Divide */ + case 8: /* Privilege Violation */ + case 11: /* Line F */ + return(NULL); /* hope than TOS fix fault himself */ + case 2: /* Access Fault */ + if((address < CF68KLIB) || (address >= CF68KLIB+0x10000)) /* 65KB */ + return(NULL); /* hope than TOS fix fault himself */ + /* else access fault inside CF68KLIB => kill TOS */ + default: /* other faults => kill TOS */ +#endif /* KILL_TOS_ON_FAULT */ +#ifdef MCF5445X + save_imrl0 |= (INTC_IMRL_INT_MASK26 | INTC_IMRL_INT_MASK28); /* mask UART 0 (serial) & UART 2 (IKBD) */ + MCF_INTC_IMRL0 = save_imrl0; + MCF_INTC_IMRH0 = save_imrh0; + MCF_INTC_IMRH1 = save_imrh1; +#else + MCF_INTC_IMRL = save_imrl; + save_imrh |= (MCF_INTC_IMRH_INT_MASK35 | MCF_INTC_IMRH_INT_MASK55 | MCF_INTC_IMRH_INT_MASK56 | MCF_INTC_IMRH_INT_MASK57); /* mask serial & CAN (IKBD) */ + MCF_INTC_IMRH = save_imrh; +#endif + *(unsigned short *)_timer_ms = 0; /* TOS is dead, flag used for polling serial ... */ +#ifndef KILL_TOS_ON_FAULT + break; + } +#endif /* KILL_TOS_ON_FAULT */ + *(unsigned long *)memvalid = 0; /* force cold reset to next reset */ + } +#ifdef MCF547X + else if((pxCurrentTCB == tid_ETOS) && (vector != 3) && (vector != 4)) /* rebuild return exception frame, EMUTOS not use the CF68KLIB */ + { + unsigned long ssp = (*(unsigned long *)&RegList[76]) + 8; + unsigned long pc = *(unsigned long *)&RegList[64]; + unsigned long sr = (unsigned long)(*(unsigned short *)&RegList[68]); + unsigned long format = (vector << 18) | sr; + unsigned long jump = *(unsigned long *)(vector * 4); + switch(ssp & 3) + { + case 0: format |= 0x40000000UL; break; + case 1: format |= 0x50000000UL; ssp--; break; + case 2: format |= 0x60000000UL; ssp -= 2; break; + case 3: format |= 0x70000000UL; ssp -= 3; break; + } + if(*(unsigned long *)phystop <= 0x80000) + *(unsigned long *)phystop = 0xE00000; /* FPGA 0xFFFF8006 has bad infos */ + asm volatile ( + " move.l %0,SP\n\t" + " move.l %1,-(SP)\n\t" + " move.l %2,-(SP)\n\t" + " move.l %3,-(SP)\n\t" + " move.l %4,A0\n\t" + " movem.l (A0),D0-D7/A0-A6\n\t" + " rts" : : "d" (ssp), "d" (pc), "d" (format), "d" (jump), "d" (RegList) : "a0", "sp" ); + } +#endif + else if(pxCurrentTCB == tid_DEBUG) + restart_debug = 1; + vTaskDelete(0); + while(1); +} + +static portTASK_FUNCTION(vDEBUG, pvParameters) +{ + /* The parameters are not used in this function */ + (void)pvParameters; + *(unsigned long *)(handler_fault) = (unsigned long)test_debug_fault; + BASE = 16; + md_last_address = 0; + md_last_size = 0; + disasm_last_address = 0; + cmdline1[0] = cmdline2[0] = '\0'; + history_init(); + while(1) + { + board_putchar_flush(); + board_printf(PROMPT); + board_putchar_flush(); + run_cmd(); + } +} + +static void start_debug(vid) +{ + xTaskCreate(vDEBUG, (void *)"DBUG", STACK_DEFAULT, NULL, DEBUG_TASK_PRIORITY, &tid_DEBUG); +} + +#endif /* DBUG */ + +void start_servers(void) +{ +#ifdef DBUG + xTaskCreate(vTELNETd, (void *)"TELNETd", STACK_DEFAULT, NULL, TELNET_TASK_PRIORITY, &tid_TELNET); +#endif +#ifdef FTP_SERVER + xTaskCreate(vFTPd, (void *)"FTPd", STACK_DEFAULT, NULL, FTP_TASK_PRIORITY, NULL); +#endif + xTaskCreate(vTFTPd, (void *)"TFTPd", STACK_DEFAULT, NULL, TFTP_TASK_PRIORITY, NULL); + /* Start the webserver */ + xTaskCreate(vBasicWEBServer, (void *)"HTTPd", STACK_DEFAULT, NULL, WEB_TASK_PRIORITY, &tid_HTTPd); +} + +#endif /* COLDFIRE */ + +static int geterrno(void) +{ + return(errno); +} + +static SOCKET_COOKIE sc = +{ + 0x0101, /* version */ + 'SOCK', /* magic */ + lwip_socket, + lwip_bind, + lwip_listen, + lwip_accept, + lwip_connect, + lwip_write, + lwip_send, + lwip_sendto, + lwip_read, + lwip_recv, + lwip_recvfrom, + lwip_shutdown, + lwip_close, + lwip_getsockname, + lwip_getpeername, + lwip_getsockopt, + lwip_setsockopt, + lwip_select, + lwip_ioctl, + gethostbyname, + geterrno +}; + +#ifdef COLDFIRE +void init_lwip(void) +#else +void init_lwip(unsigned long ip_addr, unsigned long mask_addr, unsigned long gateway_addr) +#endif +{ + struct ip_addr xIpAddr, xNetMast, xGateway; + static struct netif loop_if; +#ifdef COLDFIRE + unsigned long IP; + static struct netif fec54xx0_if; +#ifndef MCF547X + static struct netif fec54xx1_if; +#endif +#else /* !COLDFIRE */ + static struct netif rtl8139_if; +#endif /* COLDFIRE */ + errno = 0; + /* Initialize lwIP and its interface layer */ + sys_init(); + mem_init(); + memp_init(); + pbuf_init(); + netif_init(); + ip_init(); + tcpip_init(NULL, NULL); + socket_init(); +#ifdef COLDFIRE + board_get_server((unsigned char *)&IP); + xIpAddr.addr = htonl(IP); // not used actually + // => DNS_SERVER_ADDRESS in dns.c +#endif + /* Initialize the loopback interface structure */ + xIpAddr.addr = INADDR_LOOPBACK; + xGateway.addr = 0; + xNetMast.addr = 0; // 0xFF000000 + if(netif_add(&loop_if, &xIpAddr, &xNetMast, &xGateway, NULL, loopif_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&loop_if); + /* bring it up */ + netif_set_up(&loop_if); + } +#ifdef COLDFIRE + else + { + board_printf("Loopback init error\r\n"); + while(1) + vTaskDelay(1); + } + /* Initialize the network interface structure */ + board_get_client((unsigned char *)&IP); + xIpAddr.addr = htonl(IP); + board_get_gateway((unsigned char *)&IP); + xGateway.addr = htonl(IP); + board_get_netmask((unsigned char *)&IP); + xNetMast.addr = htonl(IP); + /* caches must be disabled */ + if(netif_add(&fec54xx0_if, &xIpAddr, &xNetMast, &xGateway, NULL, mcf_fec0_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&fec54xx0_if); + /* bring it up */ + netif_set_up(&fec54xx0_if); + } + else + { + board_printf("FEC0 init error\r\n"); + while(1) + vTaskDelay(1); + } +#if 0 +#ifndef MCF547X + board_get_client((unsigned char *)&IP); + IP += 0x100; + xIpAddr.addr = htonl(IP); + board_get_gateway((unsigned char *)&IP); + xGateway.addr = htonl(IP); + board_get_netmask((unsigned char *)&IP); + xNetMast.addr = htonl(IP); + if(netif_add(&fec54xx1_if, &xIpAddr, &xNetMast, &xGateway, NULL, mcf_fec1_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&fec54xx1_if); + /* bring it up */ + netif_set_up(&fec54xx1_if); + } + else + { + board_printf("FEC1 init error\r\n"); + while(1) + vTaskDelay(1); + } +#endif /* MCF547X */ +#endif + enable_caches(); +#ifdef DBUG + breakpoint_init(); +#endif +#ifdef MCF547X + if(MCF_GPIO_PPDSDR_PSC3PSC2 & MCF_GPIO_PPDSDR_PSC3PSC2_PPDSDR_PSC3PSC27) +#endif /* MCF547X */ + { + start_servers(); + } +#else /* !COLDFIRE */ + /* Initialize the network interface structure */ + xIpAddr.addr = ip_addr; + xGateway.addr = gateway_addr; + xNetMast.addr = mask_addr; + if(netif_add(&rtl8139_if, &xIpAddr, &xNetMast, &xGateway, NULL, rtl8139if_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&rtl8139_if); + /* bring it up */ + netif_set_up(&rtl8139_if); + } +#endif /* COLDFIRE */ + lwip_ok = 1; +} + +#ifdef COLDFIRE + +static portTASK_FUNCTION(vTOS, pvParameters) +{ + void (*return_address)(void) = (void (*)(void))pvParameters; + vTaskDelay(configTICK_RATE_HZ/10); + return_address(); + while(1); +} + +static portTASK_FUNCTION(vROOT, pvParameters) +{ +#ifdef MCF547X + extern short swi; + int shutdown_ethernet = 0; +#endif +#ifdef USB_DEVICE +#ifndef MCF5445X +#ifndef MCF547X + int init_usb = 0; +#endif +#endif +#endif +// int error = 0; +#if 0 // #ifdef MCF547X + extern void hbl_int(void); + extern unsigned long get_timer(void); + int tick_count = 0; + unsigned long start_timer = get_timer(); + int level = vPortSetIPL(portIPL_MAX); + old_hbl = *(unsigned long *)((64+2)*4 + coldfire_vector_base); + *(unsigned long *)((64+2)*4 + coldfire_vector_base) = (unsigned long)hbl_int; + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE2; + MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF2; /* clear interrupt */ + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK2; /* enable interrupt */ + asm_set_ipl(level); +#endif /* MCF547X */ +#ifdef USE_RTC +#ifndef MCF5445X +#ifndef MCF547X + extern void RTC_task(void); + xTaskCreate((pdTASK_CODE)RTC_task, (void *)"RTCd", STACK_DEFAULT, NULL, RTC_TASK_PRIORITY, NULL); +#endif +#endif +#endif + restart_debug = 0; + init_lwip(); + xTaskCreate(vTOS, (void *)"TOS", STACK_DEFAULT, pvParameters, TOS_TASK_PRIORITY, &tid_TOS); +#ifdef DBUG + start_debug(); +#endif + while(1) + { +#ifdef USB_DEVICE +#ifndef MCF5445X +#ifndef MCF547X + if(size_ram_disk && !init_usb) + { + vTaskDelay(configTICK_RATE_HZ); + init_usb_device(); + init_usb = 1; + } +#endif /* MCF547X */ +#endif /* MCF5445X */ +#endif /* USB_DEVICE */ +#ifdef DBUG + if(restart_debug == 1) + { + restart_debug = 0; + vTaskDelay(configTICK_RATE_HZ/2); + start_debug(); + } +#if 0 + if(!error + && (*(unsigned long *)VBL_VEC >= (unsigned long)__SDRAM_SIZE)) + { + board_printf("VBL vector destroyed!\r\n"); + error = 1; + } +#endif +#endif /* DBUG */ +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + if(1 +#ifdef CONFIG_USB_OHCI + && ohci_inited +#endif +#ifdef CONFIG_USB_EHCI +// && ehci_inited +#endif + ) + { +#ifndef CONFIG_USB_INTERRUPT_POLLING +#ifndef MCF5445X +#ifndef MCF547X + /* move INT7 to native interrupt (M5484LITE/M5485EVB) */ + /* INT7 call INT2 who is masked by other task than TOS (level 3) */ + if((save_imrl & (1 << 7)) && !(save_imrl_tos & (1 << 7))) + { + int level = asm_set_ipl(7); /* disable interrupts */ + *(unsigned long *)(((64+7) * 4) + coldfire_vector_base) = *(unsigned long *)((64+7+OFFSET_INT_CF68KLIB) * 4); + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK7; /* enable interrupt */ + asm_set_ipl(level); + } +#endif /* MCF547X */ +#endif /* MCF5445X */ +#endif /* CONFIG_USB_INTERRUPT_POLLING */ + } +#endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI */ +#ifndef MCF5445X + /* enable XLB PCI for all tasks */ + if((save_imrh & (1 << 11)) && !(save_imrh_tos & (1 << 11))) + { + int level = asm_set_ipl(7); /* disable interrupts */ + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK43; /* enable interrupt */ + asm_set_ipl(level); + } +#endif /* MCF5445X */ +#ifdef MCF547X + if(boot_os) + { + unsigned long start_addr = 0; + switch(boot_os) + { + case 1: + start_addr = 0xE0600000; + break; + default: + if(swi & 1) /* boot from rescue TOS at 0xE0000000 */ + start_addr = 0xE0400000; +#ifdef DBUG + else if((tid_TELNET == NULL) && (tid_HTTPd == NULL)) +#else + else if(tid_HTTPd == NULL) +#endif + start_servers(); + break; + } + if(start_addr) + { + if(*(short *)start_addr == 0x602E) + go_emutos(start_addr); + boot_os = 0; + } + } + else if(!shutdown_ethernet && lwip_ok && drive_ok + && (!(swi & 0x40) || !(swi & 1)) /* !SW5 (UP) */ + && !(swi & 0x80)) /* !SW6 (UP) */ + { /* TOS for MiNT */ + COOKIE *mint_cookie = *(COOKIE **)cookie; + while(mint_cookie != NULL) + { + if(mint_cookie->ident == 'MiNT') + { + COOKIE *eth_cookie = *(COOKIE **)cookie; + extern void fec_eth_stop(uint8 ch); + board_printf("Shutdown FEC...\r\n"); + fec_eth_stop(0); + while(eth_cookie != NULL) + { + if((eth_cookie->ident == 'SOCK') || (eth_cookie->ident == 'STiK')) + { + eth_cookie->ident = 'NULL'; + eth_cookie->v.l = 0; + } + if(!eth_cookie->ident) + eth_cookie = NULL; + else + eth_cookie++; + } + shutdown_ethernet = 1; + break; + } + if(!mint_cookie->ident) + mint_cookie = NULL; + else + mint_cookie++; + } + } +#endif /* MCF547X */ +#if 0 // #ifdef MCF547X + tick_count++; + if(tick_count > configTICK_RATE_HZ*10) + { + unsigned long time = get_timer(); + board_printf("VBL interval %d uS (%d %d)\r\n", (int)((time - start_timer)/(hbl_count * SYSTEM_CLOCK)), hbl_count, (time - start_timer)/SYSTEM_CLOCK); + level = vPortSetIPL(portIPL_MAX); + start_timer = get_timer(); + tick_count = 0; + hbl_count = 0; + asm_set_ipl(level); + } +#endif + vTaskDelay(1); + } +} + +void xSemaphoreTakeBDOS(void) +{ + while(xSemaphoreAltTake(xSemaphoreBDOS, portMAX_DELAY) != pdTRUE); +} + +void xSemaphoreGiveBDOS(void) +{ + xSemaphoreAltGive(xSemaphoreBDOS); +} + +int tftpreceive(unsigned char *server, char *sname, short handle, long *size) +{ + struct sockaddr_in address_server; + address_server.sin_family = AF_INET; + address_server.sin_port = htons(PortTFTP); + memcpy(&address_server.sin_addr.s_addr, server, 4); + address_server.sin_addr.s_addr = htonl(address_server.sin_addr.s_addr); + return(tftp_receive(&address_server, sname, "octet", handle, size) == 0 ? TRUE : FALSE); +} + +int tftpsend(unsigned char *server, char *sname, short handle) +{ + struct sockaddr_in address_server; + address_server.sin_family = AF_INET; + address_server.sin_port = htons(PortTFTP); + memcpy(&address_server.sin_addr.s_addr, server, 4); + address_server.sin_addr.s_addr = htonl(address_server.sin_addr.s_addr); + return(tftp_send(&address_server, sname, "octet", handle) == 0 ? TRUE : FALSE); +} + +int usb_load_files(void) +{ +#ifdef USB_DEVICE +#ifdef MCF5445X + return(FALSE); +#else /* MCF548X */ +#ifdef MCF547X + return(FALSE); +#else /* MCF548X */ + int sec = 60; /* seconds */ + board_printf("Waiting USB mass storage link...\r\n"); + while(ext_write_protect_ram_disk == FALSE) + { + vTaskDelay(configTICK_RATE_HZ); + sec--; + if(sec <= 0) + return(FALSE); /* timeout */ + } + while(ext_write_protect_ram_disk == TRUE) + vTaskDelay(1); + return(TRUE); /* continue boot with updated ram-disk */ +#endif /* MCF547X */ +#endif /* MCF5445X */ +#else + return(FALSE); +#endif /* USB_DEVICE */ +} + +#endif /* COLDFIRE */ + +int init_network(void) +{ + extern DRV_LIST stik_driver; + extern int gs_init_stik_if(void); + extern int gs_init_mem(void); + COOKIE pck; +#if defined(COLDFIRE) && !defined(MCF5445X) + extern char dma_cf_cookie[]; + pck.ident = 'DMAC'; + pck.v.l = (long)&dma_cf_cookie; + add_cookie(&pck); +#endif /* defined(COLDFIRE) && !defined(MCF5445X) */ + if(!lwip_ok) + return(FALSE); + pck.ident = 'SOCK'; + pck.v.l = (long)≻ + add_cookie(&pck); + gs_init_stik_if(); + gs_init_mem(); + pck.ident = 'STiK'; + pck.v.l = (long)&stik_driver; + add_cookie(&pck); + return(TRUE); +} + +#ifdef COLDFIRE + +int init_rtos(void *params) +{ + extern unsigned char _bss_start_freertos[]; + extern unsigned char _end_freertos[]; + extern void init_dma(void); + memset(_bss_start_freertos, 0, (int)(_end_freertos-_bss_start_freertos)); + size_ram_disk = 0; + pxCurrentTCB = NULL; + tid_TOS = (void *)-1; /* for vPortSetIPL() */ + tid_TELNET = tid_DEBUG = tid_HTTPd = NULL; +#ifdef MCF547X + tid_ETOS = NULL; + boot_os = 0; + drive_ok = 0; +#endif + start_run = NULL; + lwip_ok = get_serial_vector = get_ikbd_vector = tos_suspend = 0; + *(unsigned short *)_timer_ms = 0; + vSemaphoreCreateBinary(xSemaphoreBDOS); + xQueueAlert = xQueueCreate(2, 256); + init_dma(); + if(xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, params, ROOT_TASK_PRIORITY, NULL) == pdPASS) + vTaskStartScheduler(); + return 0; +} + +#endif /* COLDFIRE */ + +#endif /* LWIP */ + +#if !defined(COLDFIRE) && defined(FREERTOS) + +xTaskHandle pxCurrentTCB, tid_TOS, tid_INTPCI; +xQueueHandle xQueueAlert, xQueueEvent; +static portBASE_TYPE xTaskWoken; + +static portBASE_TYPE pci_int(portBASE_TYPE channel) +{ + xTaskWoken = pdFALSE; + + return(xTaskWoken); +} + +static void pci_inta_int(void) +{ + portENTER_SWITCHING_ISR(); + portEXIT_SWITCHING_ISR(pci_int(0)); +} + +static void pci_intb_int(void) +{ + portENTER_SWITCHING_ISR(); + portEXIT_SWITCHING_ISR(pci_int(1)); +} + +static void pci_intc_int(void) +{ + portENTER_SWITCHING_ISR(); + portEXIT_SWITCHING_ISR(pci_int(2)); +} + +static void pci_intd_int(void) +{ + portENTER_SWITCHING_ISR(); + portEXIT_SWITCHING_ISR(pci_int(3)); +} + +static portTASK_FUNCTION(vINTPCI, pvParameters) /* PCI interrupt */ +{ + static long params[2]; + /* The parameters are not used in this function */ + (void)pvParameters; + while(1) + { + if(xQueueAltReceive(xQueueEvent, params, portMAX_DELAY) == pdPASS) + { + long num = params[1]; + void (*f)(long num) = (void (*)(long))params[0]; + if(f != NULL) + f(num); + } + } +} + +static portTASK_FUNCTION(vTOS, pvParameters) +{ + /* The parameters are not used in this function */ + (void)pvParameters; + asm volatile(" jmp _goto_tos"); +} + +static portTASK_FUNCTION(vROOT, pvParameters) +{ + extern void led_floppy(long state); + extern short ethernet_found; + int shutdown_ethernet = 0; + int count = 0; + unsigned long config_pci = *(unsigned long *)pvParameters; + if(config_pci) + { + if(xQueueEvent != NULL) + xTaskCreate(vINTPCI, "INTPCI", STACK_DEFAULT, NULL, INTPCI_TASK_PRIORITY, &tid_INTPCI); + } + xTaskCreate(vTOS, (void *)"TOS", STACK_DEFAULT >> 1, NULL, TOS_TASK_PRIORITY, &tid_TOS); + while(1) + { + if(!shutdown_ethernet && lwip_ok) + { + COOKIE *mint_cookie = *(COOKIE **)cookie; + while(mint_cookie != NULL) + { + if(mint_cookie->ident == 'MiNT') + { + COOKIE *eth_cookie = *(COOKIE **)cookie; + extern void rtl8139_eth_stop(uint8 ch); +// board_printf("Shutdown RTL8139...\r\n"); + rtl8139_eth_stop(0); + while(eth_cookie != NULL) + { + if((eth_cookie->ident == 'SOCK') || (eth_cookie->ident == 'STiK')) + { + eth_cookie->ident = 'NULL'; + eth_cookie->v.l = 0; + } + if(!eth_cookie->ident) + eth_cookie = NULL; + else + eth_cookie++; + } + shutdown_ethernet = 1; + ethernet_found = 0; + break; + } + if(!mint_cookie->ident) + mint_cookie = NULL; + else + mint_cookie++; + } + } + if(config_pci && !ethernet_found) + { + if(!count) + led_floppy(1); + else if(count == configTICK_RATE_HZ) + led_floppy(0); + } + count++; + if(count >= configTICK_RATE_HZ*2) + count = 0; + vTaskDelay(1); + } +} + +int rtos_handler(void *f, long num) /* from PCI BIOS interrupt */ +{ + extern short ethernet_found; + static long params[2]; + params[0] = (long)f; /* before change the stack */ + params[1] = num; + if((tid_INTPCI != NULL) && !ethernet_found) + { +#ifdef SWITCH_CONTEXT + asm volatile(" move.w #0x2700,SR\n\t"); + asm volatile(" lea 4*(16+3)(SP),SP\n\t"); /* fix PCI BIOS stack !!! */ + /* Save the context of the interrupted task. */ + portSAVE_CONTEXT(); +#endif + /* If a switch is required we call vTaskSwitchContext(). */ + portBASE_TYPE xNeedSwitch = pdFALSE; + xNeedSwitch = xQueueSendFromISR(xQueueEvent, params, xNeedSwitch); +#ifdef SWITCH_CONTEXT + /* If a switch is required we call vTaskSwitchContext(). */ + if(xNeedSwitch) + vTaskSwitchContext(); + portRESTORE_CONTEXT(); /* not return */ +#endif + return(0); + } + return(-1); /* error */ +} + +int init_rtos(void) /* CT60 / CTPCI */ +{ + unsigned long config_pci = ct60_rw_parameter(CT60_MODE_READ, CT60_PARAM_CTPCI, 0) & 0x80; + pxCurrentTCB = tid_TOS = tid_INTPCI = NULL; + xQueueAlert = xQueueCreate(2, 256); + xQueueEvent = xQueueCreate(8, sizeof(long) * 2); + if(xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, &config_pci, ROOT_TASK_PRIORITY, NULL) == pdPASS) + vTaskStartScheduler(); + return(0); +} + +#endif /* !defined(COLDFIRE) && defined(FREERTOS) */ diff --git a/flash.tos/drivers/lwip/init.c.old b/flash.tos/drivers/lwip/init.c.old new file mode 100644 index 0000000..22b2d61 --- /dev/null +++ b/flash.tos/drivers/lwip/init.c.old @@ -0,0 +1,5348 @@ +/* ------------------------ System includes ------------------------------- */ +#include +#include +#include +#include + +/* ------------------------ Platform includes ----------------------------- */ +#include "config.h" +#ifdef COLDFIRE +#include "net.h" +#ifdef MCF5445X +#include "mcf5445x.h" +#define MCF_UART_USR_RXRDY UART_USR_RXRDY +#define MCF_UART_USR_TXRDY UART_USR_TXRDY +#else +#include "mcf548x.h" +#endif /* MCF5445X */ +#include "get.h" +#include "m68k_disasm.h" +#include "../../include/ramcf68k.h" +#include "../../include/vars.h" +#ifndef MCF5445X +#ifdef SOUND_AC97 +#include "../ac97/mcf548x_ac97.h" +#endif +#ifdef MCF547X +#define AC97_DEVICE 2 /* FIREBEE */ +#else /* MCF548X */ +#define AC97_DEVICE 3 /* M5484LITE */ +#endif /* MCF547X */ +#endif /* MCF5445X */ +#else /* ! COLDFIRE */ +#include +#include "ct60.h" +#include "../../include/pci_bios.h" +#define cookie 0x5A0 +#endif /* COLDFIRE */ + +/* ------------------------ FreeRTOS includes ----------------------------- */ +#include "../freertos/FreeRTOS.h" +#include "../freertos/task.h" +#include "../freertos/semphr.h" + +/* ------------------------ lwIP includes --------------------------------- */ +#include "api.h" +#include "tcpip.h" +#include "memp.h" +#include "stats.h" +#include "loopif.h" +#include "etharp.h" +#include "resolv.h" +#include "err.h" +#include "sockets.h" +#include "netdb.h" +#include "tftp.h" +#include "web.h" +#include "usb.h" +#undef int8 +#undef uint8 +#undef int16 +#undef uint16 +#undef int32 +#undef uint32 +#include "transprt.h" + +/* ------------------------ BDOS includes ----------------------------------*/ +/* cannot use TOS trap out of CF68KLIB !!! */ +#ifdef COLDFIRE +#include "../bdos/bdos.h" +#endif + +/* ------------------------ Defines --------------------------------------- */ +#undef KILL_TOS_ON_FAULT /* for debug */ + +/* Priorities for the demo application tasks. */ +#define TOS_TASK_PRIORITY ( 5 ) +#define RTC_TASK_PRIORITY ( 6 ) +#define VBL_TASK_PRIORITY ( 25 ) +#define WEB_TASK_PRIORITY ( 10 ) +#define FTP_TASK_PRIORITY ( 10 ) +#define TFTP_TASK_PRIORITY ( 10 ) +#define TELNET_TASK_PRIORITY ( 15 ) +#define DEBUG_TASK_PRIORITY ( 20 ) +#ifdef COLDFIRE +#define ROOT_TASK_PRIORITY ( 10 ) +#define STACK_DEFAULT ( 4096 ) +#else /* !COLDFIRE */ +#define STACK_DEFAULT ( 2048 ) +#define INTPCI_TASK_PRIORITY ( 30 ) +#define ROOT_TASK_PRIORITY ( 31 ) +#undef SWITCH_CONTEXT +#endif /* COLDFIRE */ + +typedef struct +{ + long ident; + union + { + long l; + short i[2]; + char c[4]; + } v; +} COOKIE; + +#ifdef LWIP + +#define FTP_USERNAME "coldfire" +#define FTP_PASSWORD "atari" + +#define SIZE_8 (8) +#define SIZE_16 (16) +#define SIZE_32 (32) +#define SIZE_64 (64) +#define ILLEGAL (0x4AFC) +#define DEFAULT_MD_LINES (8) +#define UIF_MAX_ARGS (10) +#define UIF_MAX_LINE (72) +#define UIF_MAX_BRKPTS (16) +#define UIF_CMDTAB_SIZE (sizeof(UIF_CMDTAB)/sizeof(UIF_CMD)) +#define UIF_CMD_FLAG_REPEAT (0x0001) +#define UIF_CMD_FLAG_HIDDEN (0x0002) + +#define MAX_HISTORY (5) +#define CTRL_C 0x03 +#define CTRL_D 0x04 /* command line next */ +#define CTRL_U 0x15 /* command line previous */ +#define CTRL_R 0x12 /* last command repeat */ + +/* ------------------------ PCI ------------------------------------------- */ +#if defined(COLDFIRE) && defined(MCF547X) /* for start Emutos and recreate PCI cookie */ +#ifndef PCI_COOKIE_TOTALSIZE /* #include ../../include/pci_bios.h create problems */ +#define PCI_MAX_BUS 4 +#define PCI_MAX_FUNCTION 4 /* 4 functions per PCI slot */ +#define PCI_MAX_DEVICE 32 +#define PCI_DEV_DES_SIZE 20 +#define PCI_RSC_DESC_SIZE 24 +#define PCI_RSC_DESC_TOTALSIZE (PCI_RSC_DESC_SIZE*6) +#define PCI_COOKIE_ROUTINE 8 /* offset PCI BIOS routines */ +#define PCI_COOKIE_MAX_ROUTINES 45 /* maximum of routines */ +#define PCI_COOKIE_SIZE ((4*PCI_COOKIE_MAX_ROUTINES)+PCI_COOKIE_ROUTINE) +#define PCI_RSC_HANDLESTOTALSIZE (PCI_RSC_DESC_TOTALSIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_DEV_HANDLESTOTALSIZE (PCI_DEV_DES_SIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_INT_HANDLESTOTALSIZE (PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_COOKIE_TOTALSIZE (PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE*2) +#endif +#endif /* defined(COLDFIRE) && defined(MCF547X) */ + +/* ------------------------ TFTP ------------------------------------------ */ +#define TimeOut 2 /* seconds */ +#define NumberTimeOut 3 /* retries */ +#define PortTFTP 69 +#define TFTP_READ 0 +#define TFTP_WRITE 1 + +/* Trivial File Transfer Protocol (IEN-133) */ +#define SEGSIZE 512 /* data segment size */ +#define PKTSIZE SEGSIZE+4 /* full packet size */ + +/* Packet types. */ +#define RRQ 1 /* read request */ +#define WRQ 2 /* write request */ +#define DATA 3 /* data packet */ +#define ACK 4 /* acknowledgement */ +#define ERROR 5 /* error code */ + +struct tftphdr +{ + short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +} __attribute__((packed)); + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* ------------------------ Telnet ---------------------------------------- */ +#define PortTELNET 23 + +/* States */ +#define STATE_NORMAL 0 +#define STATE_IAC 1 +#define STATE_OPT 2 +#define STATE_SB 3 +#define STATE_OPTDAT 4 +#define STATE_SE 5 + +/* Special telnet characters */ +#define TELNET_SE 240 // End of subnegotiation parameters +#define TELNET_NOP 241 // No operation +#define TELNET_MARK 242 // Data mark +#define TELNET_BRK 243 // Break +#define TELNET_IP 244 // Interrupt process +#define TELNET_AO 245 // Abort output +#define TELNET_AYT 246 // Are you there +#define TELNET_EC 247 // Erase character +#define TELNET_EL 248 // Erase line +#define TELNET_GA 249 // Go ahead +#define TELNET_SB 250 // Start of subnegotiation parameters +#define TELNET_WILL 251 // Will option code +#define TELNET_WONT 252 // Won't option code +#define TELNET_DO 253 // Do option code +#define TELNET_DONT 254 // Don't option code +#define TELNET_IAC 255 // Interpret as command + +/* Telnet options */ +#define TELOPT_TRANSMIT_BINARY 0 // Binary Transmission (RFC856) +#define TELOPT_ECHO 1 // Echo (RFC857) +#define TELOPT_SUPPRESS_GO_AHEAD 3 // Suppress Go Ahead (RFC858) +#define TELOPT_STATUS 5 // Status (RFC859) +#define TELOPT_TIMING_MARK 6 // Timing Mark (RFC860) +#define TELOPT_NAOCRD 10 // Output Carriage-Return Disposition (RFC652) +#define TELOPT_NAOHTS 11 // Output Horizontal Tab Stops (RFC653) +#define TELOPT_NAOHTD 12 // Output Horizontal Tab Stop Disposition (RFC654) +#define TELOPT_NAOFFD 13 // Output Formfeed Disposition (RFC655) +#define TELOPT_NAOVTS 14 // Output Vertical Tabstops (RFC656) +#define TELOPT_NAOVTD 15 // Output Vertical Tab Disposition (RFC657) +#define TELOPT_NAOLFD 16 // Output Linefeed Disposition (RFC658) +#define TELOPT_EXTEND_ASCII 17 // Extended ASCII (RFC698) +#define TELOPT_TERMINAL_TYPE 24 // Terminal Type (RFC1091) +#define TELOPT_NAWS 31 // Negotiate About Window Size (RFC1073) +#define TELOPT_TERMINAL_SPEED 32 // Terminal Speed (RFC1079) +#define TELOPT_TOGGLE_FLOW_CONTROL 33 // Remote Flow Control (RFC1372) +#define TELOPT_LINEMODE 34 // Linemode (RFC1184) +#define TELOPT_AUTHENTICATION 37 // Authentication (RFC1416) + +#define TERM_UNKNOWN 0 +#define TERM_CONSOLE 1 +#define TERM_VT100 2 + +#define TELNET_BUF_SIZE 4096 + +struct term +{ + int type; + int cols; + int lines; +}; + +struct telbuf +{ + unsigned char data[TELNET_BUF_SIZE]; + unsigned char *start; + unsigned char *end; +}; + +struct termstate +{ + int sock; + int state; + int code; + unsigned char optdata[256]; + int optlen; + struct term term; + struct telbuf bi; + struct telbuf bo; +}; + +/* ------------------------ Variables ------------------------------------- */ +extern unsigned char __SDRAM_SIZE[]; +extern unsigned long size_ram_disk, ext_write_protect_ram_disk; +extern xTaskHandle pxCurrentTCB, tid_TOS; +xTaskHandle tid_TELNET, tid_DEBUG, tid_HTTPd; + +#ifdef COLDFIRE +#ifdef MCF547X +xTaskHandle tid_ETOS; +unsigned long pseudo_dma_vec; +extern short boot_os, drive_ok; +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +void *pci_data; +#endif +#endif /* MCF547X */ + +#ifdef CONFIG_USB_OHCI +extern char ohci_inited; +#endif +#ifdef CONFIG_USB_EHCI +// extern char ehci_inited; +#endif + +#ifdef MCF5445X +extern unsigned long save_imrl0, save_imrl0_tos, save_imrh0, save_imrh0_tos, save_imrh1, save_imrh1_tos; +#else +extern unsigned long save_imrl, save_imrl_tos, save_imrh, save_imrh_tos; +#endif +static int restart_debug, get_serial_vector, get_ikbd_vector, tos_suspend; +struct termstate *ts; + +static const char PROMPT[] = "> "; +static const char SYNTAX[] = "Error: Invalid syntax for: %s\r\n"; +static const char PAUSEMSG[] = "Press to continue."; +static const char HELPMSG[] = "Enter 'help' for help.\r\n"; +static const char INVCMD[] = "Error: No such command: %s\r\n"; +static const char INVARG[] = "Error: Invalid argument: %s\r\n"; +static const char INVALUE[] = "Error: Invalid value: %s\r\n"; +static const char HELPFORMAT[] = "%8s %-25s %s %s\r\n"; + +static char cmdline1[UIF_MAX_LINE]; +static char cmdline2[UIF_MAX_LINE]; + +static int BASE; +static unsigned long md_last_address; +static int md_last_size; +static unsigned long disasm_last_address; + +typedef char HISTENT[UIF_MAX_LINE]; +static HISTENT history[MAX_HISTORY]; +void *start_run; + +xSemaphoreHandle xSemaphoreBDOS; +xQueueHandle xQueueAlert; +#endif /* COLDFIRE */ + +int lwip_ok; +int errno; + +typedef struct socket_cookie +{ + long version; /* 0x0101 for example */ + long magic; /* 'SOCK' */ + int (*socket)(int domain, int type, int protocol); + int (*bind)(int s, struct sockaddr *name, socklen_t namelen); + int (*listen)(int s, int backlog); + int (*accept)(int s, struct sockaddr *addr, socklen_t *addrlen); + int (*connect)(int s, struct sockaddr *name, socklen_t namelen); + int (*write)(int s, void *dataptr, int size); + int (*send)(int s, void *dataptr, int size, unsigned int flags); + int (*sendto)(int s, void *dataptr, int size, unsigned int flags, struct sockaddr *to, socklen_t tolen); + int (*read)(int s, void *mem, int len); + int (*recv)(int s, void *mem, int len, unsigned int flags); + int (*recvfrom)(int s, void *mem, int len, unsigned int flags, struct sockaddr *from, socklen_t *fromlen); + int (*shutdown)(int s, int how); + int (*close)(int s); + int (*getsockname)(int s, struct sockaddr *name, socklen_t *namelen); + int (*getpeername)(int s, struct sockaddr *name, socklen_t *namelen); + int (*getsockopt)(int s, int level, int optname, void *optval, socklen_t *optlen); + int (*setsockopt)(int s, int level, int optname, const void *optval, socklen_t optlen); + int (*select)(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, struct timeval *timeout); + int (*ioctlsocket)(int s, long cmd, void *argp); + struct hostent *(*gethostbyname)(const char *name); + int (*geterrno)(void); +} SOCKET_COOKIE; + +/* + * The command table entry data structure, and the prototype for the + * command table. + */ +typedef const struct +{ + char * cmd; /* command name user types, ie. GO */ + int unique; /* num chars to uniquely match */ + int min_args; /* min num of args command accepts */ + int max_args; /* max num of args command accepts */ + int flags; /* command flags (repeat, hidden) */ + void (*func)(int, char **); /* actual function to call */ + char * description; /* brief description of command */ + char * syntax; /* syntax of command */ +} UIF_CMD; + +typedef struct +{ + int dest; + void (*func)(char); + char *loc; +} PRINTK_INFO; + +#define DEST_CONSOLE (1) +#define DEST_STRING (2) + +/* ------------------------ Prototypes ------------------------------------ */ +extern int add_cookie(COOKIE *cook); +extern COOKIE *get_cookie(long id); +#ifdef COLDFIRE +static void uif_cmd_help(int argc, char **argv); +static int make_argv(char *cmdline, char *argv[]); +extern err_t mcf_fec0_init(struct netif *netif); +extern err_t mcf_fec1_init(struct netif *netif); +extern int ftpd_start(char *username, char *password); +extern int printk(PRINTK_INFO *info, const char *fmt, va_list ap); +extern int printD(const char *fmt, ...); +extern int sprintD(char *s, const char *fmt, ...); +extern void flush_caches(void); +extern void enable_caches(void); +extern void disable_caches(void); +extern char *disassemble_pc(unsigned long pc); +extern void uif_cmd_usb(int argc, char **argv); +extern void usb_enable_interrupt(void); +#else /* !COLDFIRE */ +#define board_printf kprint +extern void kprint(const char *fmt, ...); +extern err_t rtl8139if_init(struct netif *netif); +#endif /* COLDFIRE */ + +/* ------------------------ Implementation -------------------------------- */ + +#ifdef COLDFIRE + +static int auxistat(void) +{ + register int ret __asm__("d0"); +#ifdef MCF547X + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0x165A,A0\n\t" /* iorec RS232 */ + " moveq #-1,D0\n\t" /* OK */ + " moveq #0,D1\n\t" + " moveq #0,D2\n\t" + " move.w 8(A0),D1\n\t" /* tail index */ + " move.w 6(A0),D2\n\t" /* head index */ + " cmp.l D2,D1\n\t" /* buffer empty */ + " bne.s .ais1\n\t" /* no */ + " moveq #0,D0\n\t" + ".ais1:\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "memory", "cc" ); +#else /* MCF548X */ + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0xF72,A0\n\t" /* iorec RS232 */ + " moveq #-1,D0\n\t" /* OK */ + " moveq #0,D1\n\t" + " moveq #0,D2\n\t" + " move.w 8(A0),D1\n\t" /* tail index */ + " move.w 6(A0),D2\n\t" /* head index */ + " cmp.l D2,D1\n\t" /* buffer empty */ + " bne.s .ais1\n\t" /* no */ + " moveq #0,D0\n\t" + ".ais1:\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "memory", "cc" ); +#endif /* MCF548X */ + return(ret); +} + +static int rs232get(void) +{ + register int ret __asm__("d0"); +#ifdef MCF547X + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0x165A,A0\n\t" /* iorec RS232 */ + " move.w SR,D2\n\t" + " move.l D2,-(SP)\n\t" + " or.l #0x700,D2\n\t" /* mask interrupts */ + " move.w D2,SR\n\t" + " moveq #0,D1\n\t" + " move.w 6(A0),D1\n\t" /* head index */ + " moveq #0,D2\n\t" + " move.w 8(A0),D2\n\t" /* tail index */ + " cmp.l D2,D1\n\t" + " beq.s .rg1\n\t" /* bufer empty */ + " addq.l #1,D1\n\t" + " moveq #0,D2\n\t" + " move.w 4(A0),D2\n\t" /* size */ + " cmp.l D2,D1\n\t" + " bcs.s .rg2\n\t" + " moveq #0,D1\n\t" + ".rg2:\n\t" + " move.l (A0),A1\n\t" /* buffer */ + " moveq #0,D0\n\t" + " move.b (A1,D1.l),D0\n\t" /* get data */ + " move.w D1,6(A0)\n\t" /* head index */ + " bra.s .rg3\n\t" + ".rg1:\n\t" + " moveq #-1,D0\n\t" /* no receive */ + ".rg3:\n\t" + " move.l (SP)+,D2\n\t" + " move.w D2,SR\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "a1", "memory", "cc" ); +#else /* MCF548X */ + asm volatile ( + " move.l D2,-(SP)\n\t" + " lea 0xF72,A0\n\t" /* iorec RS232 */ + " move.w SR,D2\n\t" + " move.l D2,-(SP)\n\t" + " or.l #0x700,D2\n\t" /* mask interrupts */ + " move.w D2,SR\n\t" + " moveq #0,D1\n\t" + " move.w 6(A0),D1\n\t" /* head index */ + " moveq #0,D2\n\t" + " move.w 8(A0),D2\n\t" /* tail index */ + " cmp.l D2,D1\n\t" + " beq.s .rg1\n\t" /* bufer empty */ + " addq.l #1,D1\n\t" + " moveq #0,D2\n\t" + " move.w 4(A0),D2\n\t" /* size */ + " cmp.l D2,D1\n\t" + " bcs.s .rg2\n\t" + " moveq #0,D1\n\t" + ".rg2:\n\t" + " move.l (A0),A1\n\t" /* buffer */ + " moveq #0,D0\n\t" + " move.b (A1,D1.l),D0\n\t" /* get data */ + " move.w D1,6(A0)\n\t" /* head index */ + " bra.s .rg3\n\t" + ".rg1:\n\t" + " moveq #-1,D0\n\t" /* no receive */ + ".rg3:\n\t" + " move.l (SP)+,D2\n\t" + " move.w D2,SR\n\t" + " move.l (SP)+,D2" : "=d" (ret) : : "d1", "d2", "a0", "a1", "memory", "cc" ); +#endif /* MCF547X */ + return(ret); +} + +#ifndef MCF547X + +static void install_inters_cf68klib(void) +{ + int tos_run = (int)(*(unsigned short *)_timer_ms); + if(tos_run && !get_serial_vector) + { + int level = vPortSetIPL(portIPL_MAX); +#ifdef MCF5445X + unsigned long *v1 = (unsigned long *)((64+INT0_LO_UART0+OFFSET_INT_CF68KLIB)*4); + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART0)*4 + coldfire_vector_base); +#else + unsigned long *v1 = (unsigned long *)((64+35+OFFSET_INT_CF68KLIB)*4); + unsigned long *v2 = (unsigned long *)((64+35)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 &= ~INTC_IMRL_INT_MASK26; /* serial */ + save_imrl0 = MCF_INTC_IMRL0; +#else + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK35; /* serial */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_serial_vector = 1; + vPortSetIPL(level); + } + if(tos_run && !get_ikbd_vector) + { + int level = vPortSetIPL(portIPL_MAX); +#ifdef MCF5445X + unsigned long *v1 = (unsigned long *)((64+INT0_LO_UART2+OFFSET_INT_CF68KLIB)*4); /* UART 2 */ + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART2)*4 + coldfire_vector_base); +#else + unsigned long *v1b = (unsigned long *)((64+55+OFFSET_INT_CF68KLIB)*4); /* ERROR CAN1 */ + unsigned long *v1a = (unsigned long *)((64+56+OFFSET_INT_CF68KLIB)*4); /* BUSOFF CAN1 */ + unsigned long *v1 = (unsigned long *)((64+57+OFFSET_INT_CF68KLIB)*4); /* MBOR CAN1 */ + unsigned long *v2b = (unsigned long *)((64+55)*4 + coldfire_vector_base); + unsigned long *v2a = (unsigned long *)((64+56)*4 + coldfire_vector_base); + unsigned long *v2 = (unsigned long *)((64+57)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 &= ~INTC_IMRL_INT_MASK28; /* UART 2 */ + save_imrl0 = MCF_INTC_IMRL0; +#else + *v2a = *v1a; + *v2b = *v1b; + MCF_INTC_IMRH &= ~(MCF_INTC_IMRH_INT_MASK55 | MCF_INTC_IMRH_INT_MASK56 | MCF_INTC_IMRH_INT_MASK57); /* CAN (IKBD) */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_ikbd_vector = 1; + vPortSetIPL(level); + } +} + +static void uninstall_inters_cf68klib(void) +{ + int tos_run = (int)(*(unsigned short *)_timer_ms); + if(tos_run && get_serial_vector) + { + int level = vPortSetIPL(portIPL_MAX); + unsigned long *v1 = (unsigned long *)(64*4 + coldfire_vector_base); /* default CF68KLIB vector normally unchanged */ +#ifdef MCF5445X + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART0)*4 + coldfire_vector_base); +#else + unsigned long *v2 = (unsigned long *)((64+35)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 |= INTC_IMRL_INT_MASK26; /* serial */ + save_imrl0 = MCF_INTC_IMRL0; +#else + MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK35; /* serial */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_serial_vector = 0; + vPortSetIPL(level); + } + if(tos_run && get_ikbd_vector) + { + int level = vPortSetIPL(portIPL_MAX); + unsigned long *v1 = (unsigned long *)(64*4 + coldfire_vector_base); /* default CF68KLIB vector normally unchanged */ +#ifdef MCF5445X + unsigned long *v2 = (unsigned long *)((64+INT0_LO_UART2)*4 + coldfire_vector_base); +#else + unsigned long *v2b = (unsigned long *)((64+55)*4 + coldfire_vector_base); + unsigned long *v2a = (unsigned long *)((64+56)*4 + coldfire_vector_base); + unsigned long *v2 = (unsigned long *)((64+57)*4 + coldfire_vector_base); +#endif + if(*v1 != *v2) + { + *v2 = *v1; +#ifdef MCF5445X + MCF_INTC_IMRL0 |= INTC_IMRL_INT_MASK28; /* UART 2 */ + save_imrl0 = MCF_INTC_IMRL0; +#else + *v2a = *v1; + *v2b = *v1; + MCF_INTC_IMRH |= (MCF_INTC_IMRH_INT_MASK55 | MCF_INTC_IMRH_INT_MASK56 | MCF_INTC_IMRH_INT_MASK57); /* CAN (IKBD) */ + save_imrh = MCF_INTC_IMRH; +#endif + } + get_ikbd_vector = 0; + vPortSetIPL(level); + } +} + +#endif /* MCF547X */ + +static int conin_debug(void) +{ + int tos_run; + while(*(unsigned char *)(serial_mouse)) + vTaskDelay(1); +#ifdef MCF547X + if((tos_suspend && !get_serial_vector) || (tid_ETOS != NULL)) +#else + if(tos_suspend && !get_serial_vector) +#endif + tos_run = 0; + else + tos_run = (int)(*(unsigned short *)_timer_ms); + /* if TOS runs we can use TOS interrupts routines also out of the CF68KLIB */ + while((!tos_run && !(MCF_UART_USR(0) & MCF_UART_USR_RXRDY)) + || (tos_run && !auxistat())) + { + vTaskDelay(1); +#ifdef MCF547X + if((tos_suspend && !get_serial_vector) || (tid_ETOS != NULL)) +#else + if(tos_suspend && !get_serial_vector) +#endif + tos_run = 0; + else + tos_run = (int)(*(unsigned short *)_timer_ms); +// install_inters_cf68klib(); + } + return(tos_run ? rs232get() & 0xFF : (int)MCF_UART_URB(0) & 0xFF); +} + +void conout_debug(int c) +{ + if(!*(unsigned char *)(serial_mouse)) + { +#ifdef MCF547X + if((pxCurrentTCB != tid_TOS) && (pxCurrentTCB != tid_ETOS)) +#else + if(pxCurrentTCB != tid_TOS) +#endif + { + int level = vPortSetIPL(portIPL_MAX); + vPortSetIPL(level); + while(!(MCF_UART_USR(0) & MCF_UART_USR_TXRDY)) + { + if(!level) + vTaskDelay(1); + } + MCF_UART_UTB(0) = (char)c; // send the character + } + else + { + while(!(MCF_UART_USR(0) & MCF_UART_USR_TXRDY)); + MCF_UART_UTB(0) = (char)c; // send the character + } + } +} + +void conws_debug(char *buf) +{ + int i = 0; + while(buf[i]) + conout_debug(buf[i++]); +} + +#ifdef DBUG + +static int telnet_write_socket(char *response, int size, int flush) +{ + int i, n = 0, len; + fd_set data_write; + struct timeval tv; + char *ptr = response; + do + { + len = TELNET_BUF_SIZE - (int)(ts->bo.start - ts->bo.data); + if(size < len) + len = size; + if(len >= 0) + { + memcpy(ts->bo.start, response, len); + size -= len; + ts->bo.start += len; + response += len; + } + if(((int)(ts->bo.start - ts->bo.data) >= TELNET_BUF_SIZE) + || flush) + { + len = n = 0; + ptr = (char *)ts->bo.data; + do + { + FD_ZERO(&data_write); + FD_SET(ts->sock, &data_write); + tv.tv_sec = 1; + tv.tv_usec = 0; + i = select(FD_SETSIZE, NULL, &data_write, NULL, &tv); + if((i > 0) && (FD_ISSET(ts->sock, &data_write) != 0)) + { + n = send(ts->sock, ptr, (int)(ts->bo.start - ts->bo.data) - len, 0); + if(n >= 0) + { + ptr += n; + len += n; + } + } + } + while((n >= 0) && (len < (int)(ts->bo.start - ts->bo.data)) && (i > 0)); + ts->bo.start = ts->bo.data; + } + } + while(size > 0); + return(n < 0 ? n : len); +} + +void board_printf(const char *fmt, ...) +{ + va_list ap; + PRINTK_INFO info; + info.dest = DEST_STRING; + va_start(ap, fmt); + if(pxCurrentTCB == tid_TOS) + { + static char buf_tos[TELNET_BUF_SIZE]; // minimize stack usage + info.loc = buf_tos; + printk(&info, fmt, ap); + *info.loc = '\0'; + va_end(ap); + conws_debug(buf_tos); + } + else + { + char *buf = (char *)pvPortMalloc(TELNET_BUF_SIZE); + if(buf != NULL) + { + info.loc = buf; + printk(&info, fmt, ap); + *info.loc = '\0'; + va_end(ap); + if(pxCurrentTCB == tid_TELNET) + { + if(ts->sock > 0) + telnet_write_socket(buf, strlen(buf), 1); + } + else + conws_debug(buf); + vPortFree(buf); + } + } +} + +static char board_getchar(void) +{ + if(pxCurrentTCB == tid_TELNET) + return(CTRL_C); + return((char)conin_debug()); +} + +void board_putchar(char c) +{ + if(pxCurrentTCB == tid_TELNET) + { + if(ts->sock > 0) + telnet_write_socket(&c, 1, (c == '\n') ? 1 : 0); + } + else + conout_debug(c); +} + +static void board_putchar_flush(void) +{ +} + +static void history_init(void) +{ + int index; + for(index = 0; index < MAX_HISTORY; ++index) + history[index][0] = '\0'; +} + +static int history_down(int *curr_hist, char *line) +{ + *curr_hist -= 1; + if(*curr_hist < 0) + { + *curr_hist = -1; + line[0] = '\0'; + return 0; + } + strcpy(line, history[*curr_hist]); + board_printf("%s",line); + board_putchar_flush(); + return strlen(line); +} + +static int history_up(int *curr_hist, char *line) +{ + if(*curr_hist == -1) + *curr_hist = 0; + else + { + *curr_hist += 1; + if(*curr_hist >= MAX_HISTORY) + *curr_hist = (MAX_HISTORY-1); + } + strcpy(line, history[*curr_hist]); + board_printf("%s",line); + board_putchar_flush(); + return strlen(line); +} + +static int history_repeat(char *line) +{ + strcpy(line, history[0]); + board_printf("%s",line); + board_putchar_flush(); + return strlen(line); +} + +static void history_add(char *line) +{ + /* This routine is called after use has entered a line */ + int index; + /* Move all history line buffers down */ + for(index = (MAX_HISTORY-1); index > 0; --index) + strcpy(history[index],history[index-1]); + /* Copy in the new one */ + strcpy(history[0], line); +} + +static char *get_history_line(char *userline) +{ + char line[UIF_MAX_LINE]; + int pos, ch, i, curr_hist, repeat; + curr_hist = -1; /* invalid */ + repeat = FALSE; + pos = 0; + ch = (int)board_getchar(); + while((ch != 0x0D /* CR */) && (ch != 0x0A /* LF/NL */) && (pos < UIF_MAX_LINE)) + { + switch(ch) + { + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(pos > 0) + { + pos -= 1; + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + break; + case CTRL_U: + case CTRL_D: + case CTRL_R: + for(i = 0; i < pos; ++i) + { + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + if(ch == CTRL_U) + { + pos = history_up(&curr_hist,line); + break; + } + if(ch == CTRL_D) + { + pos = history_down(&curr_hist,line); + break; + } + if(ch == CTRL_R) + { + pos = history_repeat(line); + repeat = TRUE; + } + break; + default: + if((pos+1) < UIF_MAX_LINE) + { + /* only printable characters */ + if((ch > 0x1f) && (ch < 0x80)) + { + line[pos++] = (char)ch; + board_putchar((char)ch); + } + } + break; + } + if(repeat) + break; + ch = (int)board_getchar(); + } + line[pos] = '\0'; + board_putchar(0x0D); /* CR */ + board_putchar(0x0A); /* LF */ + if((strlen(line) != 0) && !repeat) + history_add(line); + strcpy(userline,line); + return userline; +} + +static char *get_line(char *line) +{ + int pos; + int ch; + pos = 0; + board_putchar_flush(); + ch = (int)board_getchar(); + while((ch != 0x0D /* CR */) && (ch != 0x0A /* LF/NL */) && (pos < UIF_MAX_LINE)) + { + switch(ch) + { + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(pos > 0) + { + pos--; + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + break; + default: + if((pos+1) < UIF_MAX_LINE) + { + if((ch > 0x1f) && (ch < 0x80)) + { + line[pos++] = (char)ch; + board_putchar((char)ch); + } + } + break; + } + ch = (int)board_getchar(); + } + line[pos] = '\0'; + board_putchar(0x0D); /* CR */ + board_putchar(0x0A); /* LF */ + return line; +} + +static unsigned long get_value(char *s, int *success, int base) +{ + unsigned long value; + char *p; + value = strtoul(s,&p,base); + if((value == 0) && (p == s)) + { + *success = FALSE; + return 0; + } + else + { + *success = TRUE; + return value; + } +} + +static void cpu_write_data(unsigned long address, int size, unsigned long data) +{ + switch(size) + { + case SIZE_8: *((uint8 *)address) = (uint8)data; break; + case SIZE_16: *((uint16 *)address) = (uint16)data; break; + case SIZE_32: *((unsigned long *)address) = (unsigned long)data; break; + default: break; + } +} + +static unsigned long cpu_read_data(unsigned long address, int size) +{ + switch(size) + { + case SIZE_8: return *((uint8 *)address); + case SIZE_16: return *((uint16 *)address); + case SIZE_32: return *((unsigned long *)address); + default: return 0; + } +} + +static unsigned long cpu_align_address(unsigned long address, int size) +{ + switch(size) + { + case SIZE_32: + case SIZE_16: return(address & ~0x00000001); + case SIZE_8: + default: return (address); + } +} + +static int cpu_parse_size(char *arg) +{ + int i, size = SIZE_16; + for (i = 0; arg[i] != '\0'; i++) + { + if(arg[i] == '.') + { + switch(arg[i+1]) + { + case 'b': + case 'B': size = SIZE_8; break; + case 'w': + case 'W': size = SIZE_16; break; + case 'l': + case 'L': size = SIZE_32; break; + default: size = SIZE_16; break; + } + break; + } + } + return size; +} + +static void dump_mem(unsigned long begin, unsigned long end, int size) +{ + unsigned long data; + unsigned long curr; + char line[16]; + char *lcur; + int i, ch; + curr = begin; + do + { + board_printf("%08X: ",(int)curr); + lcur = line; + i = 0; + while(i < 16) + { + data = cpu_read_data(curr,size); + switch(size) + { + case SIZE_8: + board_printf("%02X ", (int)data); + *(uint8 *)lcur = (uint8)data; + curr++; + lcur++; + i++; + break; + case SIZE_16: + default: + board_printf("%04X ", (int)data); + *(uint16 *)lcur = (uint16)data; + curr += 2; + lcur += 2; + i += 2; + break; + case SIZE_32: + board_printf("%08X ", (int)data); + *(unsigned long *)lcur = data; + curr += 4; + lcur += 4; + i += 4; + break; + } + } + for(i = 0; i < 16; i++) + { + ch = line[i]; + if((ch >= ' ') && (ch <= '~')) + board_printf("%c",ch); + else + board_printf("."); + } + board_printf("\r\n"); + } + while(curr < end); +} + +#define BKPT_NONE (0) +#define BKPT_PERM (1) +#define BKPT_TEMP (2) + +/* Data structure used to maintain break points and trace information */ +typedef struct +{ + xTaskHandle tid; + unsigned long address; + unsigned short instruction; + int count; + int trigger; + int valid; /* and type info */ +} BRKENT; + +static BRKENT brktab[UIF_MAX_BRKPTS]; +static int auto_breakpoint; + +static void breakpoint_clear(int index) +{ + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + { + if(brktab[index].tid) + { +// board_printf("Resume task TID: %X\r\n", brktab[index].tid); + vTaskResume(brktab[index].tid); + } + brktab[index].tid = 0; + brktab[index].address = 0; + brktab[index].instruction = 0; + brktab[index].count = 0; + brktab[index].trigger = 0; + brktab[index].valid = BKPT_NONE; + } +} + +static int breakpoint_find(unsigned long address) +{ + /* This function searches the breakpoint table for `address'. + * If it is found, then an index into the table is returned, + * otherwise -1 is returned. */ + int index; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].address == address) + return(index); + } + return(-1); +} + +static void breakpoint_display_info(int index) +{ + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + { + board_printf(" %d %08X %08X %08X\r\n", + (int)index, (int)brktab[index].address, brktab[index].count, brktab[index].trigger); + } +} + +static void breakpoint_display(int argc, char **argv) +{ + unsigned long address; + int i,j; + (void)argc; + board_printf("INSTR_BREAK__ADDRESS___COUNT___TRIGGER_____________________________________\r\n"); + if(auto_breakpoint) + board_printf(" ? Pexec TOS armed ? ?\r\n"); + if(*(unsigned char *)(trap_breakpoint)) + board_printf(" ? Mshrink MiNT armed ? ?\r\n"); + /* break points are listed one by one starting at argv[1] */ + /* if no break points listed, argv[1] == NULL, display all */ + if(argv[1] == NULL) + { + /* display all */ + for(i = 0; i < UIF_MAX_BRKPTS; i++) + { + if(brktab[i].valid) + breakpoint_display_info(i); + } + } + else + { + i = 1; + while(argv[i] != NULL) + { + address = (unsigned long )strtoul(argv[i],NULL,16); + for(j = 0; j < UIF_MAX_BRKPTS; j++) + { + if(brktab[j].address == address) + breakpoint_display_info(j); + } + i++; + } + } +} + +static void breakpoint_set_count(unsigned long brkpnt, int count) +{ + int index = breakpoint_find(brkpnt); + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + brktab[index].count = count; +} + +static void breakpoint_set_all_count(int value) +{ + int index; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + brktab[index].count = value; +} + +static void breakpoint_set_trigger(unsigned long brkpnt, int count) +{ + int index = breakpoint_find(brkpnt); + if((index >= 0) && (index < UIF_MAX_BRKPTS)) + brktab[index].trigger = count; +} + +static void breakpoint_set_all_trigger(int value) +{ + int index; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + brktab[index].trigger = value; +} + +static void breakpoint_remove(unsigned long address) +{ + int index; + if((index = breakpoint_find(address)) != -1) + breakpoint_clear(index); +} + +static void breakpoint_add(unsigned long address, int type) +{ + int i; + /* first check to make sure not already in table */ + if(breakpoint_find(address) != -1) + return; + /* find an open slot and put it in */ + for(i = 0; i < UIF_MAX_BRKPTS; i++) + { + if(!brktab[i].valid) + break; + } + if(i == UIF_MAX_BRKPTS) + { + board_printf("Break table full\r\n"); + return; + } + /* Test for valid breakpoint address */ + if(address & 1) /* 16-bit boudary */ + { + board_printf("Error: Invalid breakpoint address!\r\n"); + return; + } +// unprotect_code(); + /* Test for read-only memory */ + brktab[i].instruction = *(unsigned short *)address; + *(unsigned short *)address = (unsigned short)ILLEGAL; + if(*(volatile unsigned short *)address != (unsigned short)ILLEGAL) + board_printf("Error: Address is read-only!\n"); + else + { + *(unsigned short *)address = brktab[i].instruction; + brktab[i].address = address; + brktab[i].count = 0; + brktab[i].trigger = 1; + brktab[i].valid = type; + } +// protect_code(); +} + +static int breakpoint_install(unsigned long address) +{ + /* This function inserts the breakpoints in user code. Extensive + * checking of breakpoints is done before entry into the table, so + * all breakpoints in table should be OK to just implant. If + * a breakpoint with the same `address' is found, it is not + * inserted, and TRUE is returned, otherwise FALSE. + * This routine is generally called right before executing user + * code. */ + int index, found = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { + if(brktab[index].address == address) + found = TRUE; + else + { +// unprotect_code(); + brktab[index].instruction = *(unsigned short *)brktab[index].address; + *(unsigned short *)brktab[index].address = (unsigned short)ILLEGAL; +// protect_code(); + } + } + } + flush_caches(); + return(found); +} + +static int breakpoint_install_from_cf68klib(unsigned long address) +{ + /* This function inserts the breakpoints in user code. Extensive + * checking of breakpoints is done before entry into the table, so + * all breakpoints in table should be OK to just implant. If + * a breakpoint with the same `address' is found, it is not + * inserted, and TRUE is returned, otherwise FALSE. + * This routine is generally called right before executing user + * code. */ + int index, found = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { + if(brktab[index].address == address) + found = TRUE; + else + { +// unprotect_code(); + brktab[index].instruction = *(unsigned short *)brktab[index].address; + *(unsigned short *)brktab[index].address = (unsigned short)ILLEGAL; +// protect_code(); + } + } + } +#if (__GNUC__ > 3) + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5485\n\t"); +#else + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5200\n\t"); +#endif + return(found); +} + +static int breakpoint_deinstall(unsigned long address, int *triggered, xTaskHandle tid) +{ + /* This function removes breakpoints from user code. If + * `address' is/was installed, TRUE is returned, else FALSE + * if `address' was encountered, its count is incremented. */ + int index, found = FALSE; + *triggered = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { +// unprotect_code(); + *(unsigned short *)brktab[index].address = (unsigned short)brktab[index].instruction; +// protect_code(); + if(brktab[index].address == address) + { + brktab[index].tid = tid; + found = TRUE; + if(++brktab[index].count >= brktab[index].trigger) + *triggered = TRUE; + } + if(brktab[index].valid == BKPT_TEMP) + { + /* knock out Temporary breakpoints */ + breakpoint_clear(index); + } + } + } + flush_caches(); + return found; +} + +static int breakpoint_deinstall_from_cf68klib(unsigned long address, xTaskHandle tid) +{ + /* This function removes breakpoints from user code. If + * `address' is/was installed, TRUE is returned, else FALSE + * if `address' was encountered, its count is incremented. */ + int index, found = FALSE; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid) + { +// unprotect_code(); + *(unsigned short *)brktab[index].address = (unsigned short)brktab[index].instruction; +// protect_code(); + if(brktab[index].address == address) + { + brktab[index].tid = tid; + found = TRUE; + } + if(brktab[index].valid == BKPT_TEMP) + { + /* knock out Temporary breakpoints */ + breakpoint_clear(index); + } + } + } +#if (__GNUC__ > 3) + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5485\n\t"); +#else + asm volatile (" .chip 68060\n\t cpusha BC\n\t .chip 5200\n\t"); +#endif + return found; +} + +static void suspend_task(xTaskHandle tid) +{ + if(pxCurrentTCB == tid_TOS) + tos_suspend = 1; + vTaskSuspend(tid); +} + +static void resume_task(xTaskHandle tid) +{ + if(tid == tid_TOS) + { + *(unsigned long *)_hz_200 = xTaskGetTickCount(); + tos_suspend = 0; + } + vTaskResume(tid); +} + +void install_auto_breakpoint(unsigned long address) /* called from DBOS / CF68KLIB */ +{ + if(auto_breakpoint && address && (address < (unsigned long)__SDRAM_SIZE) + && ((address < 0xE00000) || (address >= 0x1000000))) + { + breakpoint_deinstall_from_cf68klib(address, pxCurrentTCB); + breakpoint_add(address, BKPT_PERM); + breakpoint_install_from_cf68klib((unsigned long)-1); + } +} + +static void breakpoint_init(void) +{ + int index; + *(unsigned long *)(v_breakpoint_install) = (unsigned long)breakpoint_install; + *(unsigned long *)(v_breakpoint_deinstall) = (unsigned long)breakpoint_deinstall; + *(unsigned long *)(v_breakpoint_add) = (unsigned long)breakpoint_add; + *(unsigned long *)(v_breakpoint_remove) = (unsigned long)breakpoint_remove; + *(unsigned long *)(v_suspend_task) = (unsigned long)suspend_task; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + breakpoint_clear(index); + auto_breakpoint = 0; + *(unsigned char *)(trap_breakpoint) = 0; +} + +static void uif_cmd_cb(int argc, char **argv) +{ + int success, index; + if((argc == 2) && (argv[1][0] != '*')) + { + index = get_value(argv[1],&success,10); + if(success) + { + if((index >= UIF_MAX_BRKPTS) || (brktab[index].valid != BKPT_PERM)) + { + board_printf("Error: Bad index!\r\n"); + return; + } + breakpoint_remove(brktab[index].address); + } + } + else + breakpoint_init(); + *(unsigned short *)(save_format) = 0; +} + +static void uif_cmd_db(int argc, char **argv) +{ + int i, value, success; + unsigned long brkpnt; + char *p; + brkpnt = (unsigned long)-1; /* improbable breakpoint address */ + if(argc == 1) + { + auto_breakpoint = 1; /* for BDOS pexec, 1st word of program */ + /* display all break points */ + breakpoint_display(argc, argv); + return; + } + /* parse through arguments */ + i = 1; + while(i < argc) + { + if(argv[i][0] != '-') + { + /* must be a breakpoint address */ + success = 1; + brkpnt = get_value(argv[i],&success,16); + if(success == 0) + { + board_printf("Error: Bad Value: %s\r\n",argv[i]); + return; + } + /* add breakpoint, if not already there */ + breakpoint_add(brkpnt, BKPT_PERM); + i++; + } + else + { + /* must be an option of some sort */ + switch(argv[i][1]) + { + case 'c': + case 'C': + /* set break point count */ + if(argv[i+1] == NULL) + value = 0; + else + { + value = strtoul(argv[++i],&p,BASE); + if((value == 0) && (p == argv[i])) + value = 0; + } + if(brkpnt == (unsigned long)-1) + { + /* set all counts */ + breakpoint_set_all_count(value); + return; + } + else + breakpoint_set_count(brkpnt,value); + break; + case 't': + case 'T': + /* set break point trigger */ + if(argv[i+1] == NULL) + value = 1; + else + { + value = strtoul(argv[++i],&p,BASE); + if((value == 0) && (p == argv[i])) + value = 1; + } + if(brkpnt == (unsigned long)-1) + { + /* set all triggers */ + breakpoint_set_all_trigger(value); + return; + } + else + breakpoint_set_trigger(brkpnt,value); + break; + case 'r': + case 'R': + /* remove break points */ + if(brkpnt == (unsigned long)-1) + { + /* check for address given after '-r' */ + if(argv[i+1] == NULL) + breakpoint_init(); + else + { + while(++i < argc) + { + success = 1; + brkpnt = get_value(argv[i],&success,16); + if(success == 0) + breakpoint_init(); + else + breakpoint_remove(brkpnt); + } + } + } + else + breakpoint_remove(brkpnt); + *(unsigned short *)(save_format) = 0; + break; + case 'i': + case 'I': + breakpoint_set_all_trigger(1); + breakpoint_set_all_count(0); + break; + case 'm': + case 'M': + *(unsigned char *)(trap_breakpoint) = 1; /* for trap #1 mshrink */ + break; + default: + board_printf("Error: Invalid option: %s\r\n",argv[1]); + break; + } + i++; + } + } +} + +static void uif_cmd_lb(int argc, char **argv) +{ + breakpoint_display(argc, argv); +} + +#ifdef MCF547X /* FIREBEE */ + +void zero_devide(void) +{ + asm volatile ( + "_new_zero_divide:\n\t" + " move.w #0x2700,SR\n\t" /* disable interrupt */ + " move.l D0,-(SP)\n\t" + " move.l A0,-(SP)\n\t" + " move.l 12(SP),A0\n\t" /* PC */ + " move.w (A0)+,D0\n\t" /* opcode */ + " btst #7,D0\n\t" + " bne.s .word\n\t" + " addq.l #2,A0\n\t" /* longword */ + ".word:\n\t" + " and.l #0x3F,D0\n\t" /* source effective address */ + " cmp.l #8,D0\n\t" + " bls.s .end\n\t" /* Dy */ + " addq.l #2,A0\n\t" + " cmp.l #0x39,D0\n\t" /* absolute */ + " beq.s .absolute\n\t" + " cmp.l #0x3C,D0\n\t" /* immediate */ + " bne.s .end\n\t" + ".absolute:\n\t" + " addq.l #2,A0\n\t" + ".end:\n\t" + " move.l A0,12(SP)\n\t" /* fix PC */ + " move.l (SP)+,A0\n\t" + " move.l (SP)+,D0\n\t" + " rte\n\t" ); +} + +void trap_exception(void) +{ + asm volatile ( + "_new_trap:\n\t" + " clr.l -(SP)\n\t" + " move.l D0,-(SP)\n\t" + " move.l A0,-(SP)\n\t" + " move.w 12(SP),D0\n\t" + " and.l #0x3FC,D0\n\t" + " move.l D0,A0\n\t" + " move.l (A0),8(SP)\n\t" + " move.l (SP)+,A0\n\t" + " move.l (SP)+,D0\n\t" + " rts\n\t" ); +} + +void clear_int6(void) +{ + MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF6; /* clear interrupt */ +} + +void inter_mfp(void) +{ + asm volatile ( + "_new_mfp:\n\t" + " move.l 0x114,-(SP)\n\t" + " lea -24(SP),SP\n\t" + " movem.l D0-D2/A0-A2,(SP)\n\t" ); + clear_int6(); + asm volatile ( + " moveq #0,D1\n\t" + " move.b 0xFFFFFA13,D1\n\t" /* MFP IMRA (FPGA emulation) */ + " asl.l #8,D1\n\t" + " move.b 0xFFFFFA15,D1\n\t" /* MFP IMRB (FPGA emulation) */ + " move.b 0xFFFFFA0B,D0\n\t" /* MFP IPRA (FPGA emulation) */ + " asl.l #8,D0\n\t" + " move.b 0xFFFFFA0D,D0\n\t" /* MFP IPRB (FPGA emulation) */ + " and.l D1,D0\n\t" + " tst.l D0\n\t" + " beq.s .is_not_mfp\n\t" + " move.l 0xF0020000,D0\n\t" /* ACP_MFP_INTACK_VECTOR (MFP vector base register + MFP int channel) * 4 */ + " and.l #0x3FC,D0\n\t" + " cmp.l #0x13C,D0\n\t" + " bne.s .not_pseudo_dma\n\t" /* TOS pseudo dma routine */ + " move.l _pseudo_dma_vec,D0\n\t" + " move.l D0,24(SP)\n\t" /* move vector content to return address */ + " bra.s .is_not_mfp\n\t" + ".not_pseudo_dma:\n\t" + " move.l D0,A0\n\t" + " move.l (A0),24(SP)\n\t" /* move vector content to return address */ + ".is_not_mfp:\n\t" + " movem.l (SP),D0-D2/A0-A2\n\t" + " lea 24(SP),SP\n\t" + " rts\n\t" ); /* jump to MFP vector */ +} + +void function_vbl(void) +{ +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_INTERRUPT_POLLING) +void usb_event_poll(int interrupt); +#endif + MCF_INTC_INTFRCL &= ~MCF_INTC_INTFRCL_INTFRC4; /* clear interrupt */ +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_INTERRUPT_POLLING) + MCF_GPT_GMS(0) = 0; + MCF_GPT_GCIR(0) = 20000 | (SYSTEM_CLOCK << 16); /* 20 mS */ + MCF_GPT_GMS(0) = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_CE | MCF_GPT_GMS_WDEN; /* watchdog timer */ +#ifdef CONFIG_USB_OHCI + if(ohci_inited) +#endif + usb_event_poll(1); /* if CTRL-ALT-(SHIFT-)DEL no return ! */ + MCF_GPT_GMS(0) = 0; /* clear watchdog timer */ +#endif +} + +void inter_vbl(void) +{ + asm volatile ( + "_new_vbl:\n\t" + " lea -24(SP),SP\n\t" + " movem.l D0-D2/A0-A2,(SP)\n\t" ); + function_vbl(); + asm volatile ( + " movem.l (SP),D0-D2/A0-A2\n\t" + " lea 24(SP),SP\n\t" + " move.l 0x70,-(SP)\n\t" + " rts\n\t" ); /* jump to VBL vector */ +} + +#define MMUCR (*(volatile unsigned long *)(MMU_BASE+0x0000)) +#define MMUOR (*(volatile unsigned long *)(MMU_BASE+0x0004)) +#define MMUSR (*(volatile unsigned long *)(MMU_BASE+0x0008)) +#define MMUAR (*(volatile unsigned long *)(MMU_BASE+0x0010)) +#define MMUTR (*(volatile unsigned long *)(MMU_BASE+0x0014)) +#define MMUDR (*(volatile unsigned long *)(MMU_BASE+0x0018)) + +#define MMUCR_EN 0x01 + +#define MMUOR_STLB 0x100 +#define MMUOR_CA 0x80 +#define MMUOR_CNL 0x40 +#define MMUOR_CAS 0x20 +#define MMUOR_ITLB 0x10 +#define MMUOR_ADR 0x08 +#define MMUOR_RW 0x04 +#define MMUOR_ACC 0x02 +#define MMUOR_UAA 0x01 + +#define MMUTR_SG 0x02 +#define MMUTR_V 0x01 + +#define MMUDR_SZ1M 0x000 +#define MMUDR_SZ4K 0x100 +#define MMUDR_SZ8K 0x200 +#define MMUDR_SZ1K 0x300 +#define MMUDR_WRITETHROUGH 0x00 +#define MMUDR_WRITEBACK 0x40 +#define MMUDR_NOCACHE 0x80 +#define MMUDR_SP 0x20 +#define MMUDR_R 0x10 +#define MMUDR_W 0x08 +#define MMUDR_X 0x04 +#define MMUDR_LK 0x02 + +#define MMUSR_HITN 0x02 + +static void mmu_map(long virt_addr, long phys_addr, long flag_itlb, long flags_mmudr) +{ + extern unsigned char __MBAR[]; + unsigned long MMU_BASE = (unsigned long)__MBAR + 0x40000; + MMUAR = virt_addr + 1; + MMUOR = MMUOR_STLB + MMUOR_ADR + flag_itlb; + MMUTR = virt_addr + MMUTR_SG + MMUTR_V; + MMUDR = phys_addr + flags_mmudr; + MMUOR = MMUOR_ACC + MMUOR_UAA + flag_itlb; +} + +static portTASK_FUNCTION(vVBL, pvParmeters) +{ + extern void new_vbl(void); + extern long get_videl_base(void); + extern long get_videl_size(void); + extern void get_mouseikbdvec(void); +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) /* for usb_malloc */ +#if 0 // #ifdef CONFIG_USB_STORAGE + extern short usb_found; + extern int usb_stor_scan(void); +#endif /* CONFIG_USB_STORAGE */ +#ifdef SOUND_AC97 + extern void det_xbios(void); + extern long sndstatus(long reset); + extern long old_vector_xbios; + extern long flag_snd_init, flag_gsxb; + int sound_err, i; +#endif /* SOUND_AC97 */ +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ + volatile unsigned char *rtc_reg = (volatile unsigned char *)0xFFFF8961; /* PFGA emulation */ + volatile unsigned char *rtc_data = (volatile unsigned char *)0xFFFF8963; + long count = 0, physbase = get_videl_base(); + long date = 0, time = 0; + *(unsigned long *)(((64+4) * 4) + coldfire_vector_base) = (unsigned long)new_vbl; + MCF_GPIO_PODR_FEC1L &= ~MCF_GPIO_PODR_FEC1L_PODR_FEC1L4; /* led */ + vTaskDelay(configTICK_RATE_HZ); + get_mouseikbdvec(); /* XBIOS calls !!! (for USB and screen WEB server) */ + old_vector_xbios = *(long *)0xB4; /* XBIOS */ +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef SOUND_AC97 + for(i = 0; i < 2; i++) + { + sound_err = mcf548x_ac97_install(2); + if(!sound_err) + break; + } +#endif +#endif + while(1) + { + unsigned long start_timer = *(unsigned long *)_hz_200; +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) +#ifdef SOUND_AC97 + if(!sound_err) + { + *(long *)0xB4 = (long)det_xbios; + flag_snd_init = 1; + flag_gsxb = 1; + sndstatus(1); + } + else + flag_snd_init = 0; +#endif /* SOUND_AC97 */ + board_printf("Add cookies\r\n"); + if(pci_data != NULL) + { + COOKIE pcookie; + COOKIE *p = *(COOKIE **)cookie; + int i = 0; + pcookie.ident = '_PCI'; + pcookie.v.l = (long)pci_data; + while(p != NULL) + { + if(p->ident == '_PCI') + continue; + if((!p->ident) && (i+1 < p->v.l)) /* free space ? */ + { + *(p+1) = *p; /* add cookie */ + *p++ = pcookie; + break; + } +#ifdef SOUND_AC97 + if((p->ident == '_SND') && !sound_err) + p->v.l |= 0x27; /* bit 5: extended mode, bit 2: 16 bits DMA, bit 1: 8 bits DMA, bit 0: YM2149 */ +#endif /* SOUND_AC97 */ + i++; + p++; + } + } +#if 0 // #ifdef CONFIG_USB_STORAGE + if(usb_found) + usb_stor_scan(); +#endif /* CONFIG_USB_STORAGE */ +#endif /* defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) */ + while((*(unsigned long *)_hz_200 - start_timer) < 200UL) + { + start_timer = *(unsigned long *)_hz_200; + /* Videl screen change - FPGA memory */ + long new_physbase = get_videl_base(); + if(new_physbase != physbase) + { + long end_physbase = new_physbase + get_videl_size(); + physbase = new_physbase; + new_physbase &= 0xf00000; + end_physbase &= 0xf00000; + if(new_physbase < 0xd00000) + { + int level = asm_set_ipl(7); /* disable interrupts */ + flush_caches(); + memcpy((void *)(new_physbase + 0x60000000), (void *)new_physbase, 0x100000); + mmu_map(new_physbase,(new_physbase + 0x60000000),MMUOR_ITLB,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); + mmu_map(new_physbase,(new_physbase + 0x60000000),0,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + if((end_physbase != new_physbase) && (end_physbase < 0xd00000)) /* 2nd page */ + { + memcpy((void *)(end_physbase + 0x60000000), (void *)new_physbase, 0x100000); + mmu_map(end_physbase,(end_physbase + 0x60000000),MMUOR_ITLB,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_X+MMUDR_LK); + mmu_map(end_physbase,(end_physbase + 0x60000000),0,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + } + asm_set_ipl(level); +// board_printf("new videl screen at 0x%lX\r\n", physbase); + } + } + if(!(count % 50)) + { +#define NVRAM_RTC_SECONDS 0 +#define NVRAM_RTC_MINUTES 2 +#define NVRAM_RTC_HOURS 4 +#define NVRAM_RTC_DAYS 7 +#define NVRAM_RTC_MONTHS 8 +#define NVRAM_RTC_YEARS 9 + int i; + long new_date = 0, new_time = 0, delta_time; + int level = asm_set_ipl(7); /* disable interrupts */ + unsigned char reg = *rtc_reg; + *rtc_reg = NVRAM_RTC_HOURS; + new_time |= (unsigned long)*rtc_reg; + new_time <<= 8; + *rtc_reg = NVRAM_RTC_MINUTES; + new_time |= (unsigned long)*rtc_reg; + new_time <<= 8; + *rtc_reg = NVRAM_RTC_SECONDS; + new_time |= (unsigned long)*rtc_reg; + *rtc_reg = NVRAM_RTC_YEARS; + new_date |= (unsigned long)*rtc_reg; + new_date <<= 8; + *rtc_reg = NVRAM_RTC_MONTHS; + new_date |= (unsigned long)*rtc_reg; + new_date <<= 8; + *rtc_reg = NVRAM_RTC_DAYS; + new_date |= (unsigned long)*rtc_reg; + if(!time) + time = new_time; + if(!date) + date = new_date; + delta_time = new_time - time; + if(delta_time < 0) + delta_time = - delta_time; + if((delta_time > 2) || (date != new_date)) + { + MCF_UART3_UTB = 0x82; /* header */ + for(i = 0; i < 64; i++) + { + while(!(MCF_UART3_USR & MCF_UART_USR_TXEMP)); + *rtc_reg = (unsigned char)i; + MCF_UART3_UTB = *rtc_data; /* send data */ + } + } + *rtc_reg = reg; + asm_set_ipl(level); +// if((delta_time > 2) || (date != new_date)) +// board_printf("RTC update to the PIC\r\n"); + time = new_time; + date = new_date; + } + /* Toggle led */ + if(!(count & 7)) + MCF_GPIO_PODR_FEC1L &= ~MCF_GPIO_PODR_FEC1L_PODR_FEC1L4; + else if((count & 7) == 4) + MCF_GPIO_PODR_FEC1L |= MCF_GPIO_PODR_FEC1L_PODR_FEC1L4; + /* RTC update to the PIC */ + /* Send VBL interrupt */ + MCF_INTC_INTFRCL |= MCF_INTC_INTFRCL_INTFRC4; /* force INT 4 */ + /* VBL delay */ + vTaskDelay((20*configTICK_RATE_HZ)/1000); + count++; + } + } +} + +static portTASK_FUNCTION(vETOS,pvParmeters) +{ + void (*fp)(void) = (void(*)(void))0xE00000; + (*fp)(); +} + +static void go_emutos(unsigned long source) +{ + extern void end_vdi(); + extern long init_videl(long width, long height, long bpp, long refresh, long extended); + extern void new_zero_divide(void); + extern void new_trap(void); + extern void new_mfp(void); + extern unsigned char __LWIP_BASE[]; + extern void *info_fvdi; +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + extern void *usb_malloc(long amount); + COOKIE *pci_cookie = *(COOKIE **)cookie; +#endif + unsigned long top = (unsigned long)__LWIP_BASE - 0x100000; /* - 1MB */ + int i; + mcf548x_ac97_uninstall(2, 0); + vTaskDelay(1); +// uninstall_inters_cf68klib(); + vTaskDelete(tid_TOS); + end_vdi(); /* for screen WEB server and mousexy() */ + if(source != 0xE0600000) + { + void (*fp)(void) = (void(*)(void))source; + asm_set_ipl(7); /* disable interrupts */ + (*fp)(); + } +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) + pci_data = NULL; + while(pci_cookie != NULL) + { + if(pci_cookie->ident == '_PCI') + { + pci_data = usb_malloc(PCI_COOKIE_TOTALSIZE); + if(pci_data != NULL) + memcpy(pci_data, (void *)pci_cookie->v.l, PCI_COOKIE_TOTALSIZE); + break; + } + if(!pci_cookie->ident) + pci_cookie = NULL; + else + pci_cookie++; + } +#endif /* (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) */ +#if 1 + init_videl(640, 480, 4, 60, 0xD00000); + memset((void *)0xD00000, 0, (640 * 480 * 4) /sizeof(short)); +#else + init_videl(640, 480, 16, 60, 0xD00000); + memset((void *)0xD00000, -1, 640 * 480 * sizeof(short)); +#endif + info_fvdi = NULL; + asm_set_ipl(7); /* disable interrupts */ + for(i = 1; i < 16; *(unsigned long *)(((32+i) * 4) + coldfire_vector_base) = (unsigned long)new_trap, i++); + *(unsigned long *)((5 * 4) + coldfire_vector_base) = (unsigned long)new_zero_divide; /* Zero Divide */ + *(unsigned long *)((10 * 4) + coldfire_vector_base) = (unsigned long)new_trap; /* LineA */ + *(unsigned long *)((15 * 4) + coldfire_vector_base) = (unsigned long)new_trap; /* LineF */ + *(unsigned long *)(((64+6) * 4) + coldfire_vector_base) = (unsigned long)new_mfp; /* IRQ6 EPORT */ + pseudo_dma_vec = *(unsigned long *)0x13C; + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE6; + if(save_imrl_tos & MCF_INTC_IMRL_INT_MASK5) + MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_MASKALL); + else /* PCI used */ + { + /* move PCI CF68KLIB interrupt vector to native coldfire vector */ + *(unsigned long *)(((64+5) * 4) + coldfire_vector_base) = *(unsigned long *)((64+5+OFFSET_INT_CF68KLIB) * 4); /* IRQ5 EPORT */ + MCF_INTC_IMRL &= ~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL); + } + top &= 0xFFF00000; + disable_caches(); + asm volatile ( + " move.l #0x0000E040,D0\n\t" /* zone at $00000000 to $00FFFFFF in cache inhibit */ + " movec.l D0,ACR0\n\t" ); + memcpy((void *)0xE00000,(void *)source,0x80000); /* copy Emutos */ + asm volatile ( + " moveq #0,D0\n\t" + " movec.l D0,ACR0\n\t" ); + mmu_map(top,top,0,MMUDR_SZ1M+MMUDR_NOCACHE+MMUDR_LK); + *(unsigned long *)ramtop = top; + enable_caches(); + xTaskCreate(vETOS, (void *)"ETOS", STACK_DEFAULT, NULL, TOS_TASK_PRIORITY, &tid_ETOS); + xTaskCreate(vVBL, (void *)"VBL", STACK_DEFAULT, NULL, VBL_TASK_PRIORITY, NULL); +} + +#endif /* MCF547X */ + +static void uif_cmd_go(int argc, char **argv) +{ + int index, success; + if(argc == 2) + { + void (*fp)(void) = (void(*)(void))get_value(argv[1],&success,16); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } +#ifdef MCF547X + if(((unsigned long)fp == 0xE0600000) || ((unsigned long)fp == 0xE0400000)) + { + go_emutos((unsigned long)fp); + return; + } +#endif + (*fp)(); + } + *(unsigned long *)(cpu_trace_count) = 0; + if(breakpoint_install(*(unsigned short *)(save_format) ? *(unsigned long *)(save_pc) : (unsigned long)-1)) /* insert all breakpoints */ + *(unsigned long *)(cpu_trace_thru) = *(unsigned long *)(save_pc); /* PC is at breakpoint */ + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid == BKPT_PERM) + { + if(brktab[index].tid) + { +// board_printf("Resume task TID: %X\r\n", brktab[index].tid); + resume_task(brktab[index].tid); + brktab[index].tid = 0; + } + } + } +} + +static void uif_cmd_st(int argc, char **argv) +{ + int index, success, found = 0; + for(index = 0; index < UIF_MAX_BRKPTS; index++) + { + if(brktab[index].valid == BKPT_PERM) + { + if(brktab[index].tid) + { + *(unsigned long *)(cpu_trace_count) = 1; + if(argc == 2) + { + *(unsigned long *)(cpu_trace_count) = get_value(argv[1],&success,10); + if(!success) + *(unsigned long *)(cpu_trace_count) = 1; + } + if(breakpoint_find(*(unsigned long *)(save_pc)) == -1) + { + *(unsigned long *)(cpu_step_over) = *(unsigned long *)(save_pc); + breakpoint_add(*(unsigned long *)(cpu_step_over), BKPT_TEMP); + } + breakpoint_install((unsigned long)-1); +// board_printf("Resume task TID: %X\r\n", brktab[index].tid); + resume_task(brktab[index].tid); + found = 1; + } + } + } + if(!found) + board_printf("Error: No task supended by a breakpoint to trace\r\n"); +} + +#ifndef MCF5445X +#ifdef SOUND_AC97 + +static void uif_cmd_ac97_pr(int argc, char **argv) +{ + unsigned long datar, dataw; + int done, success; + unsigned long address; + char string[UIF_MAX_LINE]; + (void)argc; + address = get_value(argv[1],&success,16); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } + address = cpu_align_address(address,SIZE_16); + if(argv[2] != NULL) + { + /* the data has been specified */ + dataw = get_value(argv[2],&success,BASE); + if(success == 0) + board_printf(INVALUE,argv[2]); + else + mcf548x_ac97_debug_write(AC97_DEVICE,address,dataw); + return; + } + else if(pxCurrentTCB != tid_TELNET) + { + done = FALSE; + while(!done) + { + address &= 0x7f; + datar = mcf548x_ac97_debug_read(AC97_DEVICE,address); + board_printf("%02X: ", (int)address); + board_printf("[%04X] ", (int)datar); + get_line(string); + if(make_argv(string, NULL) == 0) + goto next_addr; + else + { + dataw = get_value(string, &success, BASE); + if(!success) + { + /* Check for special cases */ + if(string[0] == '=') + goto same_addr; + if(string[0] == '^') + { + address -= 2; + goto same_addr; + } + done = TRUE; + } + else + mcf548x_ac97_debug_write(AC97_DEVICE,address,dataw); + } +next_addr: + address += 2; +same_addr: + ; + } + } + else + board_printf(SYNTAX,argv[0]); +} + +#endif /* MCF5445X */ +#endif /* SOUND_AC97 */ + +static void uif_cmd_md(int argc, char **argv) +{ + int success, size; + unsigned long begin, end; + unsigned long contents; + size = cpu_parse_size(argv[0]); + if(argc > 1) + { + if((argc == 2) && (argv[1][0] == '*')) + { + begin = get_value(&argv[1][1],&success,BASE); + if(success) + { + contents = cpu_read_data(begin,SIZE_32); + board_printf("%08X contains %08X\r\n", (int)begin, (int)contents); + begin = contents; + end = contents+(DEFAULT_MD_LINES*16); + goto show_mem; + } + else + { + board_printf(INVALUE,argv[1]); + return; + } + } + begin = get_value(argv[1],&success,16); + if(!success) + { + board_printf(INVALUE,argv[1]); + return; + } + if(argc == 3) + { + end = get_value(argv[2],&success,16); + if(!success) + { + board_printf(INVALUE,argv[2]); + return; + } + if(begin > end) + { + unsigned long temp = end; + end = begin; + begin = temp; + } + } + else + end = begin + (DEFAULT_MD_LINES * 16); + } + else + { + begin = md_last_address; + if(md_last_size) + size = md_last_size; + end = begin + (DEFAULT_MD_LINES * 16); + } +show_mem: + begin = cpu_align_address(begin,size); + dump_mem(begin,end,size); + md_last_address = end; + md_last_size = size; +} + +static void uif_cmd_pm(int argc, char **argv) +{ + unsigned long datar, dataw; + int size, done, success; + unsigned long address; + char string[UIF_MAX_LINE]; + (void)argc; + size = cpu_parse_size(argv[0]); + address = get_value(argv[1],&success,16); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } + address = cpu_align_address(address,size); + if(argv[2] != NULL) + { + /* the data has been specified */ + dataw = get_value(argv[2],&success,BASE); + if(success == 0) + board_printf(INVALUE,argv[2]); + else + cpu_write_data(address,size,dataw); + return; + } + else if(pxCurrentTCB != tid_TELNET) + { + done = FALSE; + while(!done) + { + datar = cpu_read_data(address, size); + board_printf("%08X: ", (int)address); + switch(size) + { + case SIZE_8: board_printf("[%02X] ", (int)datar); break; + case SIZE_16: board_printf("[%04X] ", (int)datar); break; + case SIZE_32: board_printf("[%08X] ", (int)datar); break; + } + get_line(string); + if(make_argv(string, NULL) == 0) + goto next_addr; + else + { + dataw = get_value(string, &success, BASE); + if(!success) + { + /* Check for special cases */ + if(string[0] == '=') + goto same_addr; + if(string[0] == '^') + { + switch(size) + { + case SIZE_8: address -= 1; break; + case SIZE_16: address -= 2; break; + case SIZE_32: address -= 4; break; + } + goto same_addr; + } + done = TRUE; + } + else + cpu_write_data(address,size,dataw); + } +next_addr: + switch(size) + { + case SIZE_8: address += 1; break; + case SIZE_16: address += 2; break; + case SIZE_32: address += 4; break; + } +same_addr: + ; + } + } + else + board_printf(SYNTAX,argv[0]); +} + +static void uif_cmd_dis(int argc, char **argv) +{ + struct DisasmPara_68k dp; + char buffer[16]; + m68k_word *ip, *p; + char opcode[16]; + char operands[128]; + char iwordbuf[32]; + char *s; + unsigned long pc; + int i, n, success; + pc = 0; // cpu_pc_get(); + if(argc == 2) + { + /* Address to start disasm at */ + pc = get_value(argv[1],&success,BASE); + if(success == 0) + { + board_printf(INVALUE,argv[1]); + return; + } + } + else + { + /* command given with no args -- repeat */ + if(disasm_last_address != 0) + pc = disasm_last_address; + } + p = (m68k_word *)pc; + db_radix = BASE; + dp.instr = NULL; /* pointer to instruction to disassemble */ + dp.iaddr = NULL; /* instr.addr., usually the same as instr */ + dp.opcode = opcode; /* buffer for opcode, min. 16 chars. */ + dp.operands = operands; /* operand buffer, min. 128 chars. */ + dp.radix = 16; /* base 2, 8, 10, 16 ... */ +/* call-back functions for symbolic debugger support */ + dp.get_areg = NULL; /* returns current value of reg. An */ + dp.find_symbol = NULL; /* finds closest symbol to addr and */ + /* returns (positive) difference and name */ +/* changed by disassembler: */ + dp.type = 0; /* type of instruction, see below */ + dp.flags = 0; /* additional flags */ + dp.reserved = 0; + dp.areg = 0; /* address reg. for displacement (PC=-1) */ + dp.displacement = 0; /* branch- or d16-displacement */ + for(i=0;i<16;i++) + { + for(n = 0; n 5) + n = 5; + ip = dp.instr; + s = iwordbuf; + while(n--) + { + sprintD(buffer,"%04X",(int)((((unsigned long)*(unsigned char *)ip)<<8) | ((unsigned long)*((unsigned char *)ip+1)))); + *s++ = buffer[0]; + *s++ = buffer[1]; + *s++ = buffer[2]; + *s++ = buffer[3]; + s++; + ip++; + } + board_printf("%08X: %s", (int)dp.iaddr, iwordbuf); + strcpy(buffer, " "); + n = 0; + while(opcode[n]) + { + buffer[n] = opcode[n]; + n++; + } + buffer[n] = 0; + board_printf("%s %s\r\n", buffer, operands); + } + disasm_last_address = (unsigned long)p; +} + +static void uif_cmd_dr(int argc, char **argv) +{ + unsigned long reg[40]; + portSTACK_TYPE p[64]; + portSTACK_TYPE *p1; + portSTACK_TYPE pc; + portSTACK_TYPE frame_format; + int i, j, vector; + if(argv); + if(argc); + vTaskSuspendAll(); + memcpy(reg, (void *)(library_data_area), 40 * sizeof(unsigned long)); +#ifdef MCF547X + memcpy(p, (tid_ETOS != NULL) ? tid_ETOS : tid_TOS, 64 * sizeof(portSTACK_TYPE)); +#else + memcpy(p, tid_TOS, 64 * sizeof(portSTACK_TYPE)); +#endif + p1 = (portSTACK_TYPE *)p[0]; + frame_format = p1[0]; + pc = p1[1]; + xTaskResumeAll(); +#ifdef MCF547X + if(tid_ETOS == NULL) +#endif + { + vector = (int)((reg[38] >> 2) & 255); + board_printf("CF68KLIB data area, fault #%d: ", vector); + switch(vector) + { + case 2: board_printf("Access Fault"); break; + case 3: board_printf("Address Error"); break; + case 4: board_printf("Illegal Instruction"); break; + case 5: board_printf("Integer Zero Divide"); break; + case 8: board_printf("Privilege Violation"); break; + case 9: board_printf("Trace"); break; + case 10: board_printf("Line A"); break; + case 11: board_printf("Line F"); break; + case 14: board_printf("Format Error"); break; + case 32: + case 33: + case 34: + case 35: + case 36: + case 37: + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 44: + case 45: + case 46: + case 47: board_printf("Trap #%d", vector - 32); break; + } + board_printf("\r\nStatus Register (SR): %04X\r\n", (int)reg[17]>>16); + board_printf("Program Counter (PC): %08X\r\n", (int)reg[16]); + board_printf("Supervisor Stack (SSP): %08X\r\n", (int)reg[19]); + board_printf("User Stack (USP): %08X\r\n", (int)reg[18]); + for(i = j = 0; i < 8; i++) + board_printf("D%d: %08X A%d: %08X\r\n", i, (int)reg[i], i, (int)reg[i+8]); + if(((vector == 4) || (vector == 8)) + && (*(unsigned long *)(save_pc_cf68klib) < (unsigned long)__SDRAM_SIZE)) + board_printf("%s (emul)\r\n", disassemble_pc(*(unsigned long *)(save_pc_cf68klib))); + if(reg[16] < (unsigned long)__SDRAM_SIZE) + board_printf("%s\r\n", disassemble_pc(reg[16])); + } + board_printf("TOS task context saving:\r\n"); + board_printf("Status Register (SR): %04X\r\n", (int)(frame_format & 0xFFFF)); + board_printf("Program Counter (PC): %08X\r\n", (int)pc); + board_printf("Supervisor Stack (SSP): %08X\r\n", (int)p[0]); + board_printf("User Stack (USP): %08X\r\n", (int)p[16]); + for(i = j = 0; i < 8; i++, j += 2) + { + board_printf("D%d: %08X A%d: %08X FP%d: %08X%08X\r\n", + i, (int)p[i+1], i, (int)p[i+9], + i, (int)p[j+22], (int)p[j+23]); + } + if(pc < (portSTACK_TYPE)__SDRAM_SIZE) + board_printf("%s\r\n", disassemble_pc(pc)); +} + +static void uif_cmd_qt(int argc, char **argv) +{ + if(argc); + if(argv); + static char buf[80*50]; +#if( HAVE_USP == 1 ) + board_printf("Name\t\tTID\tPrio\tStatus\tSys/User Stack\t#\r\n"); +#else + board_printf("Name\t\tTID\tPrio\tStatus\tStack\t\t#\r\n"); +#endif + board_printf("------------------------------------------------------------"); + vTaskList((void *)buf); + board_printf(buf); +} + +#if 0 +static void uif_cmd_trace(int argc, char **argv) +{ +#define DEFAULT_TRACE_SIZE 0x10000 + static char *buffer_trace = NULL; + static unsigned long size_trace = DEFAULT_TRACE_SIZE; + static char default_name[] = "trace.bin"; + static char filename_trace[UIF_MAX_LINE]; + long file_w; + int success; + unsigned long val; + if(strcmp(argv[1],"on") == 0) + { + if(buffer_trace != NULL) + { + board_printf("Trace tasks already running, use before\r\n"); + return; + } + if((argc == 3) && (val = get_value(argv[2],&success,10)) != 0) + { + size_trace = val; + strcpy(filename_trace, default_name); + } + else if(argc > 3) + { + val = get_value(argv[3],&success,10); + if(val) + size_trace = val; + else + size_trace = DEFAULT_TRACE_SIZE; + strcpy(filename_trace, argv[2]); + } + else + { + size_trace = DEFAULT_TRACE_SIZE; + strcpy(filename_trace, default_name); + } + if((buffer_trace = (char *)pvPortMalloc(size_trace)) == NULL) + { + board_printf("Not enough memory for create trace buffer\r\n"); + return; + } + vTaskStartTrace(buffer_trace, size_trace); + } + else if(strcmp(argv[1],"off") == 0) + { + if(buffer_trace == NULL) + { + board_printf("Trace tasks already stopped, use before\r\n"); + return; + } + val = ulTaskEndTrace(); + Fdelete(filename_trace); + if((file_w = Fcreate(filename_trace, 0)) < 0) + board_printf("Cannot create file %s\r\n", filename_trace); + else + { + Fwrite(file_w, val, buffer_trace); + Fclose(file_w); + } + vPortFree(buffer_trace); + buffer_trace = NULL; + } + else + board_printf("Usage: trace on/off \r\n"); +} +#endif + +static void uif_cmd_cat(int argc, char **argv) +{ +#define SIZE_BUFFER_CAT 10000 +#define SIZE_BUF_CAT 80 + long file_r = 0, file_w = 0; + int i, timeout, len, edit=0, cat=0, size=0; + char *p, *buffer=NULL; + static char buf[SIZE_BUF_CAT+1]; + static char buf2[SIZE_BUF_CAT*2+1]; + buf[SIZE_BUF_CAT] = '\0'; + if(argc > 2) + { + p = argv[argc-2]; + if(p[0] == '>') + { + cat++; + if(p[1] == '>') + cat++; + if(argc == 3) + edit = 1; + } + switch(cat) + { + case 1: + file_w = Fcreate(argv[argc-1], 0); + if(file_w < 0) + { + board_printf("Cannot create file %s (error: %d)\r\n", argv[argc-1], file_w); + return; + } + break; + case 2: + file_w = Fopen(argv[argc-1], 2); + if(file_w == ENOENT) + file_w = Fcreate(argv[argc-1], 0); + if(file_w < 0) + { + board_printf("Cannot write file %s (error: %d)\r\n", argv[argc-1], file_w); + return; + } + Fseek(0, file_w, 2); /* end */ + break; + } + } + if(edit && ((buffer = pvPortMalloc(SIZE_BUFFER_CAT)) != NULL)) + { + char ch; + size = 0; + while(((ch = board_getchar()) != CTRL_D) && (ch != CTRL_C) + && (size < SIZE_BUFFER_CAT)) + { + switch(ch) + { + case '\r': + board_putchar('\r'); + board_putchar('\n'); + if(size < SIZE_BUFFER_CAT) + buffer[size++] = '\r'; + if(size < SIZE_BUFFER_CAT) + buffer[size++] = '\n'; + break; + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(size > 0) + { + size--; + board_putchar(0x08); /* backspace */ + board_putchar(' '); + board_putchar(0x08); /* backspace */ + } + break; + default: + if(size < SIZE_BUFFER_CAT) + { + if((ch > 0x1f) && ((unsigned char)ch < 0x80)) + { + buffer[size++] = ch; + board_putchar(ch); + } + } + break; + } + } + board_putchar('\r'); + board_putchar('\n'); + Fwrite(file_w, size, buffer); + } + for(i = 1; i < (cat ? argc-2 : argc); i++) + { + if((file_r = Fopen(argv[i], 0)) >= 0) + { + do + { + len = Fread(file_r, SIZE_BUF_CAT, buf); + if(cat && (len > 0)) + len = Fwrite(file_w, len, buf); + else if(!cat && (len == SIZE_BUF_CAT)) + { + char ch = 0; + int j = 0, k = 0; + while(buf[j]) + { + if((buf[j] == '\n') && (ch != '\r')) + buf2[k++] = '\r'; + buf2[k++] = ch = buf[j++]; + } + buf2[k] = 0; + board_printf(buf2); + timeout = 0; + while(!(ch = auxistat()) && (timeout < (configTICK_RATE_HZ*1920)/(SIZE_BUF_CAT*1000))) + vTaskDelay(1); + if(ch && ((ch = rs232get() & 0xFF) == CTRL_C)) + { + len = 0; + i = argc; + break; + } + } + } + while(len == SIZE_BUF_CAT); + if(!cat) + { + char ch = 0; + int j = 0, k = 0; + buf[len] = '\0'; + while(buf[j]) + { + if((buf[j] == '\n') && (ch != '\r')) + buf2[k++] = '\r'; + buf2[k++] = ch = buf[j++]; + } + buf2[k] = 0; + board_printf(buf2); + if(i >= argc-1) + board_printf("\r\n"); + vTaskDelay((configTICK_RATE_HZ*1920)/(SIZE_BUF_CAT*1000)); + } + Fclose(file_r); + } + else + board_printf("Cannot open file %s (error: %d)\r\n", argv[1], file_r); + } + if(cat) + Fclose(file_w); + if(buffer != NULL) + vPortFree(buffer); +} + +static void uif_cmd_chdir(int argc, char **argv) +{ + int err; + if(argc); + if((err = Dsetpath(argv[1])) < 0) + board_printf("Cannot change to directory %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_chmod(int argc, char **argv) +{ + int err; + long attr = 0; + if(argc); + if(strchr(argv[2], 'a')) + attr |= FA_ARCHIVE; + if(strchr(argv[2], 's')) + attr |= FA_SYSTEM; + if(strchr(argv[2], 'h')) + attr |= FA_HIDDEN; + if(strchr(argv[2], 'r')) + attr |= FA_RO; + if((err = Fattrib(argv[1], 1, attr)) < 0) + board_printf("Cannot change attributes of file %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_cp(int argc, char **argv) +{ + long file_r, file_w; + int len; + char buf[512]; + if((file_r = Fopen(argv[1], 0)) >= 0) + { + if((file_w = Fcreate(argv[2], 0)) >= 0) + { + do + { + len = Fread(file_r, 512, buf); + if(len) + Fwrite(file_w, len, buf); + } + while(len == 512); + Fclose(file_w); + } + else + board_printf("Cannot create file\r\n"); + Fclose(file_r); + } + else + board_printf("File not found\r\n"); +} + +static void uif_cmd_ls(int argc, char **argv) +{ + int i, err; + static DTAINFO dta; + char name[14]; + if(argc); + if(argv); + Fsetdta(&dta); + if(argc > 1) + err = Fsfirst(argv[1], FA_SUBDIR|FA_SYSTEM|FA_HIDDEN|FA_RO); + else + err = Fsfirst(".\\*.*", FA_SUBDIR|FA_SYSTEM|FA_HIDDEN|FA_RO); + while(!err) + { + if(dta.dt_fname[0] == '.') + { + err = Fsnext(); + continue; + } + if(dta.dt_fattr & FA_ARCHIVE) + board_printf("a"); + else + board_printf("-"); + if(dta.dt_fattr & FA_SUBDIR) + board_printf("d"); + else + board_printf("-"); + if(dta.dt_fattr & FA_VOL) + board_printf("v"); + else + board_printf("-"); + if(dta.dt_fattr & FA_SYSTEM) + board_printf("s"); + else + board_printf("-"); + if(dta.dt_fattr & FA_HIDDEN) + board_printf("h"); + else + board_printf("-"); + if(dta.dt_fattr & FA_RO) + board_printf("r"); + else + board_printf("-"); + i = 0; + while(dta.dt_fname[i]) + { + if((dta.dt_fname[i] >= 'A') && (dta.dt_fname[i] <= 'Z')) + name[i] = dta.dt_fname[i] + 0x20; + else + name[i] = dta.dt_fname[i]; + i++; + } + name[i] = '\0'; + board_printf(" %d\t%02d/%02d/%04d %02d:%02d\t%s\r\n", + (int)dta.dt_fileln, + (int)dta.dt_date & 0x1F, + (int)(dta.dt_date >> 5) & 0xF, + (int)((dta.dt_date >> 9) & 0x3F) + 1980, + (int)(dta.dt_time >> 11) & 0x1F, + (int)(dta.dt_time >> 5) & 0x3F, + name); + err = Fsnext(); + } +} + +static void uif_cmd_mkdir(int argc, char **argv) +{ + int err; + if(argc); + if((err = Dcreate(argv[1])) < 0) + board_printf("Cannot create directory %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_mv(int argc, char **argv) +{ + int err; + if(argc); + if((err = Frename(argv[1], argv[2])) < 0) + board_printf("Cannot rename file %s to %s (error: %d)\r\n", argv[1], argv[2], err); +} + +static void uif_cmd_rm(int argc, char **argv) +{ + int err; + if(argc); + if((err = Fdelete(argv[1])) < 0) + board_printf("Cannot remove file %s (error: %d)\r\n", argv[1], err); +} + +static void uif_cmd_rmdir(int argc, char **argv) +{ + int err; + if(argc); + if((err = Ddelete(argv[1])) < 0) + board_printf("Cannot remove directory %s (error: %d)\r\n", argv[1], err); +} + +/*---------------------------------------------------------------------*/ +/* Fonction arp */ +/*---------------------------------------------------------------------*/ + +static void uif_cmd_arp(int argc, char **argv) +{ + extern struct netif *netif_list; + struct netif *netif; + struct in_addr addr; + struct ip_addr ipaddr; + struct eth_addr *eth_ret; + struct ip_addr *ip_ret; + if(strcmp(argv[1], "-a") == 0) + { + argc--; + argv++; + } + if(argc == 2) + { + if(netif_list != NULL) + { + for(netif = netif_list; netif != NULL; netif = netif->next) + { + if((netif->name[0] == 'l') && (netif->name[1] == 'o')) + continue; + addr.s_addr = netif->ip_addr.addr; + board_printf("Interface: %s:\r\n", inet_ntoa(addr)); + addr.s_addr = inet_addr(argv[1]); + ipaddr.addr = addr.s_addr; + if(etharp_find_addr(netif, &ipaddr, ð_ret, &ip_ret) >= 0) + board_printf(" %s at %02X:%02X:%02X:%02X:%02X:%02X\r\n", inet_ntoa(addr), + eth_ret->addr[0], eth_ret->addr[1], eth_ret->addr[2], + eth_ret->addr[3], eth_ret->addr[4], eth_ret->addr[5]); + } + } + } + else + { + char i; + if(netif_list != NULL) + { + for(netif = netif_list; netif != NULL; netif = netif->next) + { + if((netif->name[0] == 'l') && (netif->name[1] == 'o')) + continue; + addr.s_addr = netif->ip_addr.addr; + board_printf("Interface: %s:\r\n", inet_ntoa(addr)); + i = 0; + while((i = etharp_find_index_addr(netif, i, ð_ret, &ip_ret)) >= 0) + { + addr.s_addr = ip_ret->addr; + board_printf(" %s at %02X:%02X:%02X:%02X:%02X:%02X\r\n", inet_ntoa(addr), + eth_ret->addr[0], eth_ret->addr[1], eth_ret->addr[2], + eth_ret->addr[3], eth_ret->addr[4], eth_ret->addr[5]); + i++; + } + } + } + } +} + +#endif /* DBUG */ +#endif /* COLDFIRE */ + +/*---------------------------------------------------------------------*/ +/* Fonction ifconfig */ +/*---------------------------------------------------------------------*/ + +static void ife_print(struct netif *ptr) +{ + struct in_addr addr; + board_printf("%c%c%d ", ptr->name[0], ptr->name[1], ptr->num); + board_printf("flags=%d ( ", ptr->flags); + if(ptr->flags == 0) + board_printf("[NO FLAGS] "); + if(ptr->flags & NETIF_FLAG_UP) + board_printf("UP "); + if(ptr->flags & NETIF_FLAG_BROADCAST) + board_printf("BROADCAST "); + if(ptr->flags & NETIF_FLAG_POINTTOPOINT) + board_printf("POINTOPOINT "); + if(ptr->flags & NETIF_FLAG_LINK_UP) + board_printf("RUNNING "); + board_printf(") mtu %d \r\n", ptr->mtu); + addr.s_addr = ptr->ip_addr.addr; + board_printf(" inet %s ", inet_ntoa(addr)); + addr.s_addr = ptr->netmask.addr; + board_printf(" netmask %s ", inet_ntoa(addr)); + addr.s_addr = ptr->gw.addr; + board_printf(" gateway %s", inet_ntoa(addr)); + board_printf("\r\n"); + if((ptr->hwaddr[0] != 0) || (ptr->hwaddr[1] != 0) || (ptr->hwaddr[2] != 0) + || (ptr->hwaddr[3] != 0) || (ptr->hwaddr[4] != 0) || (ptr->hwaddr[5] != 0)) + board_printf(" ether %02X:%02X:%02X:%02X:%02X:%02X\r\n", + ptr->hwaddr[0], ptr->hwaddr[1], ptr->hwaddr[2], ptr->hwaddr[3], ptr->hwaddr[4], ptr->hwaddr[5]); +} + +static int if_print(char *ifname) +{ + int res = 0; + if(!ifname) + { + extern struct netif *netif_list; + struct netif *netif; + if(netif_list != NULL) + { + for(netif = netif_list; netif != NULL; netif = netif->next) + ife_print(netif); + } + else + res = -1; + } + else + { + struct netif *ife = netif_find(ifname); + if(ife != NULL) + ife_print(ife); + else + res = -1; + } + return(res); +} + +/* Set a certain interface flag. */ +static int netif_set_flag(char *ifname, int flag) +{ + struct netif *ifr = netif_find(ifname); + if(ifr == NULL) + return(-1); + switch(flag) + { + case NETIF_FLAG_UP: netif_set_up(ifr); break; + default : return(-1); + } + return(0); +} + +/* Clear a certain interface flag. */ +static int netif_clr_flag(char *ifname, int flag) +{ + struct netif *ifr = netif_find(ifname); + if(ifr == NULL) + return(-1); + switch(flag) + { + case NETIF_FLAG_UP: netif_set_down(ifr); break; + default : return(-1); + } + return(0); +} + +static void usage_ifconfig(void) +{ + board_printf("Usage:\r\n ifconfig [-a] \r\n"); + board_printf(" [dstaddr
] [netmask
] [gateway
] [up|down]\r\n\n"); +} + +void uif_cmd_ifconfig(int argc, char **argv) +{ +#define IFNAMSIZ 4 + char ifr_name[IFNAMSIZ]; + int opt_a = 0; /* show all interfaces */ + struct netif *netif; + struct ip_addr addr; + char host[64]; + int goterr = 0; + char **spp; + /* Find any options. */ + argc--; + argv++; + while(argc && *argv[0] == '-') + { + if(!strcmp(*argv, "-a")) + opt_a = 1; + if(!strcmp(*argv, "-?") || !strcmp(*argv, "-h") + || !strcmp(*argv, "-help") || !strcmp(*argv, "--help")) + { + usage_ifconfig(); + return; + } + argv++; + argc--; + } + /* Do we have to show the current setup? */ + if(argc == 0) + { + if_print((char *) NULL); + return; + } + /* No. Fetch the interface name */ + spp = argv; + strncpy(ifr_name, *spp++, IFNAMSIZ); + if(*spp == NULL) + { + if_print(ifr_name); + return; + } + /* Process the remaining arguments */ + while(*spp != NULL) + { + if(!strcmp(*spp, "up")) + goterr = netif_set_flag(ifr_name, NETIF_FLAG_UP); + else if(!strcmp(*spp, "down")) + goterr = netif_clr_flag(ifr_name, NETIF_FLAG_UP); + else if(!strcmp(*spp, "dstaddr")) + { + if(*++spp == NULL) + { + usage_ifconfig(); + return; + } + strncpy(host, *spp, (sizeof host)); + netif = netif_find(ifr_name); + addr.addr = inet_addr(host); + if(netif != NULL) + netif_set_ipaddr(netif, &addr); + else + goterr = -1; + } + else if(!strcmp(*spp, "netmask")) + { + if(*++spp == NULL) + { + usage_ifconfig(); + return; + } + strncpy(host, *spp, (sizeof host)); + netif = netif_find(ifr_name); + addr.addr = inet_addr(host); + if(netif != NULL) + netif_set_netmask(netif, &addr); + else + goterr = -1; + } + else if(!strcmp(*spp, "gateway")) + { + if(*++spp == NULL) + { + usage_ifconfig(); + return; + } + strncpy(host, *spp, (sizeof host)); + netif = netif_find(ifr_name); + addr.addr = inet_addr(host); + if(netif != NULL) + netif_set_gw(netif, &addr); + else + goterr = -1; + } + if(goterr) + { + board_printf("Error: Interface %s not found\r\n", ifr_name); + return; + } + spp++; + } +} + + +#ifdef COLDFIRE +#ifdef DBUG + +/*---------------------------------------------------------------------*/ +/* Fonction ping */ +/*---------------------------------------------------------------------*/ + +// Structure de l'en-tête IP +typedef struct iphdr +{ + unsigned int version:4; // !!!! + unsigned int h_len:4; // swap if big-endian ???? + unsigned char tos:8; + unsigned short total_len:16; + unsigned short ident:16; + unsigned short offset:16; + unsigned char ttl:8; + unsigned char proto:8; + unsigned short checksum:16; + unsigned int sourceIP:32; + unsigned int destIP:32; +} IpHeader __attribute__((__packed__)); + +// Structure de l'en-tête ICMP +typedef struct icmphdr +{ + unsigned char type:8; + unsigned char code:8; + unsigned short checksum:16; + unsigned short id; + unsigned short sequence; + unsigned long timestamp; +} IcmpHeader __attribute__((__packed__)); + +#define MAX_PACKET 1024 +#define DATASIZE_ICMP 16 +#define NBDEFAULT 4 +#define DELAI 1000 +#define IPPROTO_ICMP 1 /* control message protocol */ + +#if 0 +// Définition des messages d'erreur +char Erreur3[16][55]= +{ + "Reseau inaccessible", + "Impossible de joindre l'hote de destination", + "Protocole inaccessible", + "Port inaccessible", + "Fragmentation necessaire", + "Echec de la route source", + "Reseau de destination inconnu", + "Machine de destination inconnue", + "Machine source isolee", + "Reseau de destination administrativement interdit", + "Machine de destination administrativement interdite", + "Reseau inaccessible pour TOS", + "Machine inaccessible pour TOS", + "Communication administrativement interdite par filtrage", + "Violation de la precedence de la machine", + "Coupure de la precedence en action" +}; + +char Erreur4[1][16]= +{ + "Debit trop eleve" +}; + +char Erreur5[4][40]= +{ + "Redirige pour un reseau", + "Redirige pour une machine", + "Redirige pour type de service et reseau", + "Redirige pour type de service et machine" +}; + +char Erreur11[2][40]= +{ + "Time-to-live a 0 pendant le transit", + "Time-to-live a 0 pendant le reassemblage" +}; + +char Erreur12[2][25]= +{ + "Mauvais en-tete IP", + "Option requise manquante" +}; +#endif + +static unsigned short checksum(unsigned short *, int); +static unsigned long GetTickCount(void); + +static int max, min, moyenne, envoye, perte; + +static void uif_cmd_ping(int argc, char **argv) +{ +// Définition des différentes variables + unsigned long IP; + struct ip_addr xIpAddr; + int sock; + struct sockaddr_in sin, from; + int envoi, recept; + IcmpHeader *icmp_hdr; + char ascii_IP[16]; + char icmp_data[DATASIZE_ICMP]; + char recvbuf[MAX_PACKET]; + int fromlen = sizeof(from); + fd_set fdsr; + struct timeval tv_timeout; + int Nbping = 0; + int id, i, taille; + int recus, pourcent; + int findelai, tpslimite = 0; + min = 0x7ffffff; + max = moyenne = envoye = perte = recus = pourcent = 0; + // Accès à l'aide + if(argc < 2 || strcmp(argv[1],"--help") == 0) + { + board_printf("Usage: ping <-n echos> <-w delay> host\r\n"); + return; + } + // Identification des différentes options + for(i = 1; i < argc; i++) + { + if(strcmp(argv[i],"-n") == 0) + Nbping = (int)atol(argv[i+1]); + if(strcmp(argv[i],"-w") == 0) + tpslimite = (int)atol(argv[i+1]); + } + sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); + if(sock == -1) + return; + memset(&sin,0,sizeof(sin)); + // Récupération de l'IP + if(!inet_aton(argv[argc-1],&sin.sin_addr)) + return; + sin.sin_family = AF_INET; + taille = sizeof(IpHeader) + sizeof(IcmpHeader); + strcpy(ascii_IP, inet_ntoa(sin.sin_addr)); + board_printf("Envoi d'une requete 'ping' sur %s avec %d octets de donnees :\r\n\r\n", ascii_IP, taille); + board_get_client((unsigned char *)&IP); + xIpAddr.addr = htonl(IP); + if(sin.sin_addr.s_addr == xIpAddr.addr) + sin.sin_addr.s_addr = INADDR_LOOPBACK; + // Initialisation du nombre de ping à faire + if(Nbping == 0) + Nbping = NBDEFAULT; + // Initialisation du délai d'attente + if(tpslimite == 0) + tpslimite = DELAI; + while(envoye != Nbping) + { + memset(icmp_data,0,DATASIZE_ICMP); + id =(unsigned short)((int)pxCurrentTCB + envoye); + // Construction du paquet ICMP + icmp_hdr = (IcmpHeader*)icmp_data; + icmp_hdr->type = 8; // Type du paquet ICMP : echo request + icmp_hdr->code = 0; // Il n'y a pas de code spécifique pour ce type de paquet + icmp_hdr->id = id; + icmp_hdr->sequence = 1; + icmp_hdr->timestamp = GetTickCount(); // Initialisation du temps lors de l'envoi + // Somme de contrôle sur 16 bits + ((IcmpHeader*)icmp_data)->checksum = checksum((unsigned short*)icmp_data, DATASIZE_ICMP); + // On envoie le paquet ICMP que l'on a construit + envoi = sendto(sock, icmp_data, DATASIZE_ICMP, 0, (struct sockaddr *)&sin, DATASIZE_ICMP); + findelai = 0; + do + { + FD_ZERO(&fdsr); + FD_SET(sock, &fdsr); + tv_timeout.tv_sec = tpslimite/1000; + tv_timeout.tv_usec = 0; + if((i = select(FD_SETSIZE, &fdsr, NULL, NULL, &tv_timeout)) <= 0) + { + // Dans le cas où le temps est écoulé, on veut sortir de la boucle + // on compte le paquet comme envoyé mais perdu + board_printf("Delai d'attente de la demande depasse.\r\n"); + perte++; + envoye++; + findelai = 1; + } + if((i > 0) && FD_ISSET(sock, &fdsr)) + { + IpHeader *iphdr; + IcmpHeader *icmphdr; + unsigned short iphdrlen; + int ttl, time, taille; + char tps[32]; + char buffer[32]; + // Dans le cas où le buffer du socket contient des données, on les décode + recept = recvfrom(sock, recvbuf, MAX_PACKET, 0, (struct sockaddr *)&from, &fromlen); + // Décodage du paquet ICMP de réponse + iphdr = (IpHeader *)recvbuf; + iphdrlen = iphdr->h_len * 4 ; + icmphdr = (IcmpHeader*)(recvbuf + iphdrlen); + if(id != (icmphdr->id)) + findelai = 0; // Cas où le paquet n'est pas à nous + else + { + findelai = 1; + envoye++; + if((icmphdr->type != 8) && (icmphdr->type != 0)) + board_printf("Reponse de %s : ", ascii_IP); + switch(icmphdr->type) + { +#if 0 + case 3: + board_printf("%s.\r\n", Erreur3[icmphdr->code]); + break; + case 4: + board_printf("%s.\r\n", Erreur4[icmphdr->code]); + break; + case 5: + board_printf(" %s.\r\n", Erreur5[icmphdr->code]); + break; + case 11: + board_printf("%s.\r\n", Erreur11[icmphdr->code]); + break; + case 12: + board_printf("%s.\r\n", Erreur12[icmphdr->code]); + break; +#else + case 3: + case 4: + case 5: + case 11: + case 12: + board_printf("Erreur %d.\r\n", icmphdr->code); + break; +#endif + case 0: + case 8: + if((icmphdr->code) == 0) + { + ttl = (iphdr->ttl); + time = GetTickCount(); // Récupération du temps courant + time -= (icmphdr->timestamp); // Différence entre réception et émission + if(time > 1000/configTICK_RATE_HZ) + { + strcpy(tps, "="); + sprintD(buffer, "%d", time); + strcat(tps, buffer); + } + else + { + strcpy(tps, "<"); + sprintD(buffer, "%d", (int)(1000/configTICK_RATE_HZ)); + strcat(tps, buffer); + time = 0; + } + if(time > max) + max = time; + if(time < min) + min = time; + moyenne += time; + taille = iphdrlen + sizeof(IcmpHeader); + board_printf("Reponse de %s: icmp=%d octets=%d ", ascii_IP, envoye, taille); + board_printf("temps%s ms TTL=%d\r\n", tps, ttl); + } + break; + default: + // Cas où le type n'est pas une erreur reconnue par la RFC (cas très improblable !!!) + board_printf("Erreur inconnue.\r\n"); + break; + } + } + memset(recvbuf,0,MAX_PACKET); + } + if(auxistat() && ((rs232get() & 0xFF) == CTRL_C)) + Nbping = envoye; + } + while(findelai == 0); + // Latence d'une seconde entre chaque ping + if(envoye != Nbping) + vTaskDelay(configTICK_RATE_HZ); + } + board_printf("\n\rStatistiques Ping pour %s :\r\n",ascii_IP); + recus = envoye-perte; + pourcent = (perte*100)/envoye; + board_printf(" Paquets : envoyes = %d, recus = %d, perdus = %d (perte %d%%),\r\n", envoye, recus, perte, pourcent); + board_printf("Duree approximative des boucles en millisecondes :\r\n"); + if(recus!=0) + moyenne=moyenne/recus; + if(min > max) + min = 0; + board_printf(" minimum = %dms, maximum = %dms, moyenne = %dms\r\n", min, max, moyenne); + board_printf("\r\n"); +} + +static unsigned long GetTickCount(void) +{ + return(xTaskGetTickCount() * (1000 / configTICK_RATE_HZ)); +} + +// Fonction faisant la somme de contrôle sur 16 bits +static unsigned short checksum(unsigned short *buffer, int size) +{ + unsigned long cksum=0; + while(size >1) + { + cksum+=*buffer++; + size -=sizeof(unsigned short); + } + if(size) + cksum += *(unsigned char*)buffer; + cksum = (cksum >> 16) + (cksum & 0xffff); + cksum += (cksum >>16); + return (unsigned short)(~cksum); +} + +static void uif_cmd_stats(int argc, char **argv) +{ + if(argc); + if(argv); + stats_display(); +} + +static void uif_cmd_cache(int argc, char **argv) +{ + if(argc); + if((argc == 2) && (strcmp(argv[1],"on") == 0)) + enable_caches(); + else if((argc == 2) && (strcmp(argv[1],"off") == 0)) + disable_caches(); + else if(argc < 2) + { + unsigned long cacr = *(unsigned long *)(library_data_area + 96); // CACR cf68klib + board_printf("CACR: 0x%08X\r\n", cacr); + } + else + board_printf("Usage: cache \r\n"); +} + +static void uif_cmd_debug(int argc, char **argv) +{ + int success; + unsigned long val; + unsigned char debug = *(unsigned char *)(debug_cf68klib); + if(strcmp(argv[1],"on") == 0) + { + if(!debug) + { + if(argc == 3) + { + val = get_value(argv[2],&success,10); + if(val > 255) /* 0 => infinite */ + val = 255; + *(unsigned char *)(debug_cf68klib_count) = (unsigned char)val; + } + else + *(unsigned char *)(debug_cf68klib_count) = 255; + *(unsigned char *)(debug_cf68klib) = 1; + } + } + else if(strcmp(argv[1],"off") == 0) + { + if(debug) + *(unsigned char *)(debug_cf68klib) = *(unsigned char *)(debug_cf68klib_count) = 0; + } + else + board_printf("Usage: debug on/off\r\n"); +} + +static void uif_cmd_inter(int argc, char **argv) +{ +#ifndef MCF547X + if((argc == 2) && strcmp(argv[1],"on") == 0) + install_inters_cf68klib(); + else if((argc == 2) && strcmp(argv[1],"off") == 0) + uninstall_inters_cf68klib(); +#endif +#ifdef MCF5445X + else if((argc == 2) && strcmp(argv[1],"abort") == 0) + { + int level = vPortSetIPL(portIPL_MAX); + *(unsigned char *)(debug_int7) = 1; + /* Enable EPORT interrupt 7 requests */ + MCF_EPORT_EPIER |= EPORT_EPIER_EPIE7; + /* Allow interrupts from IRQ7 */ + MCF_INTC_IMRL0 &= ~INTC_IMRL_INT_MASK7; + save_imrl0 = MCF_INTC_IMRL0; + vPortSetIPL(level); + } + else + board_printf("Usage: inter on/off/abort\r\n"); +#else /* MCF548X */ +#ifndef MCF547X + else if((argc == 2) && strcmp(argv[1],"abort") == 0) + { + int level = vPortSetIPL(portIPL_MAX); + *(unsigned char *)(debug_int7) = 1; + /* Enable EPORT interrupt 7 requests */ + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE7; + /* Allow interrupts from IRQ7 */ + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK7; + save_imrl = MCF_INTC_IMRL; + vPortSetIPL(level); + } + else if(argc < 2) +#endif /* MCF547X */ + { + static char *names_int[] = { + "", /* 64 */ + "Edge port 1", /* 65 */ + "Edge port 2", /* 66 */ + "Edge port 3", /* 67 */ + "Edge port 4", /* 68 */ + "Edge port 5", /* 69 */ + "Edge port 6", /* 70 */ + "Edge port 7", /* 71 */ + "", /* 72 */ + "", /* 73 */ + "", /* 74 */ + "", /* 75 */ + "", /* 76 */ + "", /* 77 */ + "", /* 78 */ +#ifdef MCF547X /* interrupts not used on FIREBEE */ + "", /* 79 */ + "", /* 80 */ + "", /* 81 */ + "", /* 82 */ + "", /* 83 */ + "", /* 84 */ + "", /* 85 */ + "", /* 86 */ + "", /* 87 */ + "", /* 88 */ + "", /* 89 */ + "", /* 90 */ + "", /* 91 */ + "", /* 92 */ + "", /* 93 */ + "", /* 94 */ + "", /* 95 */ +#else + "USB 2.0", /* 79 */ + "USB 2.0", /* 80 */ + "USB 2.0", /* 81 */ + "USB 2.0", /* 82 */ + "USB 2.0", /* 83 */ + "USB 2.0", /* 84 */ + "USB 2.0", /* 85 */ + "USB 2.0", /* 86 */ + "USB 2.0", /* 87 */ + "USB 2.0", /* 88 */ + "DSPI", /* 89 */ + "DSPI", /* 90 */ + "DSPI", /* 91 */ + "DSPI", /* 92 */ + "DSPI", /* 93 */ + "DSPI", /* 94 */ + "DSPI", /* 95 */ +#endif + "PSC3", /* 96 */ + "PSC2", /* 97 */ + "PSC1", /* 98 */ + "PSC0", /* 99 */ + "Comm Timer", /* 100 */ +#ifdef MCF547X /* not used on FIREBEE */ + "", /* 101 */ + "", /* 102 */ +#else + "SEC", /* 101 */ + "FEC1", /* 102 */ +#endif + "FEC0", /* 103 */ + "I2C", /* 104 */ + "PCIARB", /* 105 */ + "CBPCI", /* 106 */ + "XLBPCI", /* 107 */ + "", /* 108 */ + "", /* 109 */ + "", /* 110 */ + "XLBARB", /* 111 */ + "DMA", /* 112 */ +#ifdef MCF547X + "", /* 113 */ + "", /* 114 */ + "", /* 115 */ +#else /* MCF548X */ + "CAN0 ERROR", /* 113 */ + "CAN0 BUSOFF", /* 114 */ + "CAN0 MBOR", /* 115 */ +#endif /* MCF547X */ + "", /* 116 */ + "SLT1", /* 117 */ + "SLT0", /* 118 */ +#ifdef MCF547X + "", /* 119 */ + "", /* 120 */ + "", /* 121 */ +#else /* MCF548X */ + "CAN1 ERROR", /* 119 */ + "CAN1 BUSOFF", /* 120 */ + "CAN1 MBOR", /* 121 */ +#endif /* MCF547X */ + "", /* 122 */ + "GPT3", /* 123 */ + "GPT2", /* 124 */ + "GPT1", /* 125 */ + "GPT0", /* 126 */ + "" /* 127 */ + }; + int i; + board_printf("NATIVE/RTOS\tCF68KLIB/TOS\tLEV\tPRI\tINTERRUPTS\r\n"); + for(i = 0; i < 64; i++) + { + if(strlen(names_int[i])) + { + unsigned long imr, imr_tos; + int j; + if(i < 32) + { + imr = save_imrl; + imr_tos = save_imrl_tos; + j = i; + } + else + { + imr = save_imrh; + imr_tos = save_imrh_tos; + j = i - 32; + } + board_printf("%s\t\t%s\t\t%d\t%d\t%s Int(%d)\r\n", + !(imr & (1 << j)) ? "ON" : "OFF", + !(imr_tos & (1 << j)) ? "ON" : "OFF", + (MCF_INTC_ICRn(i) >> 3) & 7, MCF_INTC_ICRn(i) & 7, + names_int[i], i + 64); + } + } + } +#ifndef MCF547X + else + board_printf("Usage: inter \r\n"); +#endif +#endif /* MCF5445X */ +} + +void uif_cmd_reset(int argc, char **argv) +{ + if(argc); + if(argv); + board_putchar('\r'); + board_putchar('\n'); + board_putchar_flush(); + (void)vPortSetIPL(portIPL_MAX); + /* Watchdog Reset */ +#ifdef MCF5445X + MCF_INTC_IMRH0 = MCF_INTC_IMRL0 = MCF_INTC_IMRH1 = MCF_INTC_IMRL1 = 0xFFFFFFFF; + MCF_SCM_CWCR = SCM_CWCR_CWE | SCM_CWCR_CWRI(2) | SCM_CWCR_CWT(8); +#else /* MCF548X */ + MCF_INTC_IMRH = MCF_INTC_IMRL = 0xFFFFFFFF; + MCF_GPT_GMS(0) = 0; + MCF_GPT_GCIR(0) = 10 | (SYSTEM_CLOCK << 16); /* 10 uS */ + MCF_GPT_GMS(0) = MCF_GPT_GMS_TMS_GPIO | MCF_GPT_GMS_CE | MCF_GPT_GMS_WDEN; /* watchdog timer */ +#endif /* MCF5445X */ + while(1) + { + asm volatile(" nop\n\t"); + MCF_UART_UTB(0) = '.'; + } +} + +static void uif_cmd_trap(int argc, char **argv) +{ + int success; + unsigned long val; + unsigned char debug = *(unsigned char *)(debug_trap); + if(strcmp(argv[1],"on") == 0) + { + if(!debug) + { + if(argc == 3) + { + val = get_value(argv[2],&success,10); + if(val > 255) /* 0 => infinite */ + val = 255; + *(unsigned char *)(debug_trap_count) = (unsigned char)val; + } + else + *(unsigned char *)(debug_trap_count) = 255; + *(unsigned char *)(debug_trap) = 1; + } + } + else if(strcmp(argv[1],"off") == 0) + { + if(debug) + *(unsigned char *)(debug_trap) = *(unsigned char *)(debug_trap_count) = 0; + } + else + board_printf("Usage: trap on/off\r\n"); +} + +static UIF_CMD UIF_CMDTAB[] = +{ + /* <1> command name user types, ie. GO */ + /* <2> num chars to uniquely match */ + /* <3> min num of args command accepts */ + /* <4> max num of args command accepts */ + /* <5> command flags (repeat, hidden) */ + /* <6> actual function to call */ + /* <7> brief description of command */ + /* <8> syntax of command */ +#ifndef MCF5445X +#ifdef SOUND_AC97 + {"acpr",4,1,2,0,uif_cmd_ac97_pr,"AC97 Patch Register","addr "}, +#endif +#endif +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + {"usb",3,0,4,0,uif_cmd_usb,"USB sub-system",""}, +#endif + {"cb",2,0,1,0,uif_cmd_cb,"Clear Breakpoint",""}, + {"db",2,0,UIF_MAX_ARGS-1,0,uif_cmd_db,"Define Breakpoint"," <-c|t value> <-r addr..> <-i> <-m>"}, + {"dm",2,0,2,UIF_CMD_FLAG_REPEAT,uif_cmd_md,"Display Memory","begin "}, + {"md",2,0,2,UIF_CMD_FLAG_REPEAT|UIF_CMD_FLAG_HIDDEN,uif_cmd_md,"Memory Display","begin "}, + {"dis",2,0,1,UIF_CMD_FLAG_REPEAT,uif_cmd_dis,"Disassemble",""}, + {"dr",2,0,0,0,uif_cmd_dr,"Display Registers CF68KLIB",""}, + {"go",1,0,1,0,uif_cmd_go,"Execute, Insert Breakpt",""}, + {"lb",2,0,0,0,uif_cmd_lb,"List Breakpoints",""}, + {"pm",2,1,2,0,uif_cmd_pm,"Patch Memory","addr "}, + {"qt",2,0,0,UIF_CMD_FLAG_REPEAT,uif_cmd_qt,"Query Tasks",""}, + {"st",2,0,1,UIF_CMD_FLAG_REPEAT,uif_cmd_st,"Single Step (after db)",""}, +// {"trace",2,1,3,0,uif_cmd_trace,"Task Trace","on/off "}, + {"cat",2,1,UIF_MAX_ARGS-1,0,uif_cmd_cat,"Concatenate File(s)","file(s)"}, + {"cd",2,1,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_chdir,"Change Directory","dir"}, + {"chdir",2,1,1,0,uif_cmd_chdir,"Change Directory","dir"}, + {"chmod",5,2,2,0,uif_cmd_chmod,"Change Attibutes","filename attributes"}, + {"cp",2,2,2,0,uif_cmd_cp,"Copy File","source dest"}, + {"copy",4,2,2,UIF_CMD_FLAG_HIDDEN,uif_cmd_cp,"Copy File","source dest"}, + {"del",3,1,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_rm,"Remove File","file"}, + {"dir",3,0,1,UIF_CMD_FLAG_HIDDEN,uif_cmd_ls,"List Directory",""}, + {"ls",2,0,1,0,uif_cmd_ls,"List Directory",""}, + {"mkdir",2,1,1,0,uif_cmd_mkdir,"Make Directory","dir"}, + {"mv",2,2,2,0,uif_cmd_mv,"Rename File","source dest"}, + {"rename",3,2,2,UIF_CMD_FLAG_HIDDEN,uif_cmd_mv,"Rename File","source dest"}, + {"rm",2,1,1,0,uif_cmd_rm,"Remove File","file"}, + {"rmdir",2,1,1,0,uif_cmd_rmdir,"Remove Directory","dir"}, + {"type",4,1,UIF_MAX_ARGS-1,UIF_CMD_FLAG_HIDDEN,uif_cmd_cat,"Concatenate File(s)","file(s)"}, + {"arp",2,0,2,0,uif_cmd_arp,"Address Resol. Protocol","<-a> "}, + {"ifconfig",2,0,UIF_MAX_ARGS-1,0,uif_cmd_ifconfig,"Interface Configuration","<-a> ..."}, + {"ping",2,1,5,0,uif_cmd_ping,"Ping","<-n echos> <-w delay> host"}, + {"netstat",2,0,0,0,uif_cmd_stats,"Network Stats",""}, + {"cache",2,0,1,0,uif_cmd_cache,"Cache",""}, + {"debug",2,1,2,0,uif_cmd_debug,"Debug CF68KLIB","on/off "}, +#ifdef MCF547X + {"inter",1,0,1,0,uif_cmd_inter,"Interrupts CF68KLIB",""}, +#else + {"inter",2,0,1,0,uif_cmd_inter,"Interrupts CF68KLIB",""}, +#endif + {"reset",5,0,0,0,uif_cmd_reset,"System Reset",""}, + {"shutdown",8,0,0,UIF_CMD_FLAG_HIDDEN,uif_cmd_reset,"System Reset",""}, + {"trap",4,1,2,0,uif_cmd_trap,"Traps CF68KLIB","on/off "}, + {"help",2,0,1,0,uif_cmd_help,"Help",""}, +}; +static const int UIF_NUM_CMD = UIF_CMDTAB_SIZE; + +static void help_display(int index) +{ + board_printf(HELPFORMAT, UIF_CMDTAB[index].cmd, UIF_CMDTAB[index].description, + UIF_CMDTAB[index].cmd, UIF_CMDTAB[index].syntax); +} + +static void uif_cmd_help(int argc, char **argv) +{ + int index, displayed; + if(argc == 1) + { + /* Display all command summaries */ + board_printf(HELPFORMAT,"Command","Description","Syntax",""); + displayed = 1; + for(index = 0; index < UIF_NUM_CMD; index++) + { + if(!(UIF_CMDTAB[index].flags & UIF_CMD_FLAG_HIDDEN)) + help_display(index); + } + return; + } + else + { + /* Display specific command summary */ + for(index = 0; index < UIF_NUM_CMD; index++) + { + if(strcasecmp(UIF_CMDTAB[index].cmd,argv[1]) == 0) + { + board_printf(HELPFORMAT,"Command","Description","Syntax",""); + help_display(index); + return; + } + } + for(index = 0; index < UIF_NUM_CMD; index++) + { + if(strncasecmp(UIF_CMDTAB[index].cmd,argv[1], UIF_CMDTAB[index].unique) == 0) + { + board_printf(HELPFORMAT,"Command","Description","Syntax",""); + help_display(index); + return; + } + } + board_printf(INVCMD,argv[1]); + } +} + +static int make_argv(char *cmdline, char *argv[]) +{ + int argc, i, in_text; + /* break cmdline into strings and argv */ + /* it is permissible for argv to be NULL, in which case */ + /* the purpose of this routine becomes to count args */ + argc = 0; + i = 0; + in_text = FALSE; + while(cmdline[i] != '\0') /* getline() must place 0x00 on end */ + { + if(((cmdline[i] == ' ') || (cmdline[i] == '\t')) ) + { + if(in_text) + { + /* end of command line argument */ + cmdline[i] = '\0'; + in_text = FALSE; + } + else + { + /* still looking for next argument */ + } + } + else + { + /* got non-whitespace character */ + if(in_text) + { + } + else + { + /* start of an argument */ + in_text = TRUE; + if(argc < UIF_MAX_ARGS) + { + if(argv != NULL) + argv[argc] = &cmdline[i]; + argc++; + } + else + /*return argc;*/ + break; + } + } + i++; /* proceed to next character */ + } + if(argv != NULL) + argv[argc] = NULL; + return argc; +} + +static int run_cmd(void) +{ + /* Global array of pointers to emulate C argc,argv interface */ + int argc; + char *argv[UIF_MAX_ARGS + 1]; /* one extra for null terminator */ + get_history_line(cmdline1); + if(!(argc = make_argv(cmdline1, argv))) + { + /* no command entered, just a blank line */ + strcpy(cmdline1, cmdline2); + argc = make_argv(cmdline1, argv); + } + cmdline2[0] = '\0'; + if(argc) + { + int i; + /* + * First try for an exact match on command name + */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strcasecmp(UIF_CMDTAB[i].cmd,argv[0]) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + return(TRUE); + } + else + { + board_printf(SYNTAX,argv[0]); + return(TRUE); + } + } + } + /* + * Now try for short-hand match on command name + */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strncasecmp(UIF_CMDTAB[i].cmd,argv[0], UIF_CMDTAB[i].unique) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + return(TRUE); + } + else + { + board_printf(SYNTAX,argv[0]); + return(TRUE); + } + } + } + board_printf(INVCMD,argv[0]); + board_printf(HELPMSG); + } + return(FALSE); +} + +/*---------------------------------------------------------------------*/ +/* FTP Server */ +/*---------------------------------------------------------------------*/ + +#ifdef FTP_SERVER +static portTASK_FUNCTION(vFTPd, pvParameters) +{ + if(pvParameters); + ftpd_start(FTP_USERNAME, FTP_PASSWORD); + vTaskDelete(0); +} +#endif + +/*---------------------------------------------------------------------*/ +/* TFTP Server */ +/*---------------------------------------------------------------------*/ + +static portTASK_FUNCTION(vTFTPd, pvParameters) +{ + extern long ram_disk_drive; + long file; + unsigned long bytes_read; + static struct sockaddr_in address, adresse, from, to; + socklen_t lg=sizeof(struct sockaddr_in); + socklen_t fromlen=lg, tolen=lg; + static char buf[PKTSIZE],ackbuf[PKTSIZE]; + struct tftphdr *tp = (struct tftphdr *)&buf; + char filename[256]; + char *dat, *cp, *p; + struct tftphdr *dp, *ap; + int i=0, size, Oldsize=PKTSIZE, n, ntimeout, peer, sock, nextBlockNumber; + struct timeval tv; + fd_set data_read; + if(pvParameters); + if((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + board_printf("TFTPd: create server socket error (err %d)\r\n",errno); + vTaskDelete(0); + } + address.sin_family=AF_INET; + address.sin_addr.s_addr=htonl(INADDR_ANY); + address.sin_port=htons(PortTFTP); + if(bind(sock, (struct sockaddr *)&address, lg) < 0) + { + board_printf("TFTPd: bind server error (err %d)\r\n",errno); + close(sock); + vTaskDelete(0); + } + while(1) + { + do + n=recvfrom(sock, tp, PKTSIZE, 0, (struct sockaddr *)&to, &tolen); + while(n < 0); + tp->th_opcode = htons((u_short)tp->th_opcode); + cp = (char *)&tp->th_stuff[0]; + p = &cp[SEGSIZE-5]; + while((cp < p) && *cp && (*cp != ' ')) + cp++; + if(*cp && (*cp != ' ')) + continue; + *cp = '\0'; + filename[0] = 'C'; + filename[1] = ':'; + filename[2] = '\\'; + filename[3] = '\0'; + if(ram_disk_drive >= 1) + filename[0] =(char)ram_disk_drive + 'A'; + strcat(filename, &tp->th_stuff[0]); + dp = (struct tftphdr *)buf; + ap = (struct tftphdr *)ackbuf; + dat = (char*)&dp->th_data[0]; + cp = (char *)&dp->th_stuff[0]; + if((peer = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + { + board_printf("TFTPd: create socket client error (err %d)\r\n",errno); + continue; + } + adresse.sin_family=AF_INET; + adresse.sin_addr.s_addr=htonl(INADDR_ANY); + adresse.sin_port=htons(0); + if(bind(peer, (struct sockaddr *)&adresse, lg) < 0) + { + board_printf("TFTPd: bind client error (err %d)\r\n",errno); + close(peer); + continue; + } + switch(tp->th_opcode) + { + case WRQ: + Fdelete(filename); + if((file = Fcreate(filename, 0)) < 0) + { + board_printf("TFTPd: cannot create file %s\r\n", filename); + close(peer); + break; + } + ap->th_opcode=htons((u_short)ACK); + ap->th_block=0; + size=4; + nextBlockNumber = 1; + do + { + ntimeout = 0; + do + { + if(ntimeout == NumberTimeOut) + /* could not make connection */ + goto tftp_close; + if(sendto(peer, ap, size, 0, (struct sockaddr *)&to, tolen) != size) + { + board_printf("TFTPd: sendto error\r\n"); + goto tftp_close; + } + do + { + n = -1; + FD_ZERO(&data_read); + FD_SET(peer, &data_read); + tv.tv_sec = TimeOut; + tv.tv_usec = 0; + if((i = select(FD_SETSIZE, &data_read, NULL, NULL, &tv)) == -1) + { + board_printf("TFTPd: select error (err %d)\r\n",errno); + goto tftp_close; + } + if((i > 0) && FD_ISSET(peer, &data_read)) + n = recvfrom(peer, dp, PKTSIZE, 0, (struct sockaddr *)&from, &fromlen); + } + while((n < 0) && (i > 0)); + if(i > 0) + { + to.sin_port = from.sin_port; + dp->th_opcode = ntohs((unsigned short)dp->th_opcode); + dp->th_block = ntohs((unsigned short)dp->th_block); + if(dp->th_opcode != DATA) + { + if(dp->th_opcode == ERROR) + board_printf("TFTPd: TFTP error #%d : %s\r\n",(int)dp->th_code, &dp->th_data[0]); + goto tftp_close; + } + if((int)dp->th_block < nextBlockNumber) + { + /* Re-ACK this packet */ + ap->th_block = htons(dp->th_block); + ap->th_opcode = htons((unsigned short)ACK); + if(sendto(peer, ap, 4, 0,(struct sockaddr *)&to, tolen) != size) + { + // write Re-ACK error + board_printf("TFTPd: sendto error (err %d)\r\n",errno); + goto tftp_close; + } + continue; + } + else if((int)dp->th_block != nextBlockNumber) + /* This is NOT the block number expected */ + continue; + } + ntimeout++; + } + while((int)dp->th_block != nextBlockNumber); + ap->th_block = htons((unsigned short)nextBlockNumber); + size = 4; + if(n-4 > 0) + { + bytes_read += (n-4); + Fwrite(file, n-4, (char *)dat); + } + nextBlockNumber++; + } + while(n == PKTSIZE); + /* send the "final" ack */ + sendto(peer, ap, 4, 0,(struct sockaddr *)&to, tolen); +tftp_close: + close(peer); + Fclose(file); + break; + case RRQ: + if((file = Fopen(filename, 0)) < 0) + { + board_printf("TFTPd: cannot open file %s\r\n", filename); + close(peer); + break; + } + dp->th_opcode=htons((unsigned short)DATA); + dp->th_block=htons((unsigned short)1); + size = Fread(file, SEGSIZE, (char *)dat); + if(size == 0) + goto tftp_close; + size += 4; + nextBlockNumber = 1; + do + { + ntimeout = 0; + do + { + if(ntimeout == NumberTimeOut) + /* could not make connection */ + goto tftp_close; + if(sendto(peer, dp, size, 0, (struct sockaddr *)&to, tolen) != size) + { + board_printf("TFTPd: sendto error\r\n"); + goto tftp_close; + }; + do + { + n = -1; + FD_ZERO(&data_read); + FD_SET(peer,&data_read); + tv.tv_sec = TimeOut; + tv.tv_usec = 0; + if((i = select(FD_SETSIZE, &data_read, NULL, NULL, &tv)) == -1) + { + board_printf("TFTPd: select error (err %d)\r\n",errno); + goto tftp_close; + } + if((i > 0) && FD_ISSET(peer, &data_read)) + n = recvfrom(peer, ap, PKTSIZE, 0,(struct sockaddr *)&from, &fromlen); + } + while((n < 0) && (i > 0)); + if(i > 0) + { + to.sin_port=from.sin_port; + ap->th_opcode = ntohs((unsigned short)ap->th_opcode); + ap->th_block = ntohs((unsigned short)ap->th_block); + if(ap->th_opcode != ACK) + { + if(ap->th_opcode == ERROR) + board_printf("TFTPd: TFTP error #%d : %s\r\n",(int)ap->th_code, &ap->th_data[0]); + goto tftp_close; + } + if((int)ap->th_block < nextBlockNumber) + { + /* Re-ACK this packet */ + dp->th_block = htons(ap->th_block); + dp->th_opcode = htons((unsigned short)ACK); + if(sendto(peer, dp, 4, 0,(struct sockaddr *)&to, tolen) != size) + { + board_printf("TFTPd: sendto error (err %d)\r\n",errno); + goto tftp_close; + } + continue; + } + else if((int)ap->th_block != nextBlockNumber) + continue; + } + ntimeout++; + } + while((int)ap->th_block != nextBlockNumber); + if((size < PKTSIZE) && (nextBlockNumber != 0)) + break; // all is already send inside the 1st packet of DATA + nextBlockNumber++; + dp->th_block = htons((unsigned short)nextBlockNumber); + if(nextBlockNumber == 1) + { + dp->th_opcode=htons((u_short)DATA); // used only if InClient=1 + size = Fread(file, SEGSIZE, (char *)dat); + } + else + { + Oldsize = size; + if(Oldsize == PKTSIZE) + size = Fread(file, SEGSIZE, (char *)dat); + } + size += 4; + } + while(Oldsize == PKTSIZE); + close(peer); + Fclose(file); + break; + } + } +} + +/*---------------------------------------------------------------------*/ +/* Telnet Server */ +/*---------------------------------------------------------------------*/ + +static void sendopt(struct termstate *ts, int code, int option) +{ + unsigned char buf[3]; + buf[0] = TELNET_IAC; + buf[1] = (unsigned char) code; + buf[2] = (unsigned char) option; + send(ts->sock, buf, 3, 0); +} + +static void parseopt(struct termstate *ts, int code, int option) +{ + switch(option) + { + case TELOPT_ECHO: + break; + case TELOPT_SUPPRESS_GO_AHEAD: + if(code == TELNET_WILL || code == TELNET_WONT) + sendopt(ts, TELNET_DO, option); + else + sendopt(ts, TELNET_WILL, option); + break; + case TELOPT_TERMINAL_TYPE: + case TELOPT_NAWS: + case TELOPT_TERMINAL_SPEED: + sendopt(ts, TELNET_DO, option); + break; + default: + if(code == TELNET_WILL || code == TELNET_WONT) + sendopt(ts, TELNET_DONT, option); + else + sendopt(ts, TELNET_WONT, option); + break; + } +} + +static void parseoptdat(struct termstate *ts, int option, unsigned char *data, int len) +{ + switch(option) + { + case TELOPT_NAWS: + if(len == 4) + { + int cols = ntohs(*(unsigned short *) data); + int lines = ntohs(*(unsigned short *) (data + 2)); + if(cols) + ts->term.cols = cols; + if(lines) + ts->term.lines = lines; + } + break; + case TELOPT_TERMINAL_SPEED: + break; + case TELOPT_TERMINAL_TYPE: + break; + } +} + +static void parse(struct termstate *ts) +{ + unsigned char *p = ts->bi.start; + unsigned char *q = p; + while(p < ts->bi.end) + { + int c = *p++; + switch (ts->state) + { + case STATE_NORMAL: + if (c == TELNET_IAC) + ts->state = STATE_IAC; + else + *q++ = c; + break; + case STATE_IAC: + switch (c) + { + case TELNET_IAC: + *q++ = c; + ts->state = STATE_NORMAL; + break; + case TELNET_WILL: + case TELNET_WONT: + case TELNET_DO: + case TELNET_DONT: + ts->code = c; + ts->state = STATE_OPT; + break; + case TELNET_SB: + ts->state = STATE_SB; + break; + default: + ts->state = STATE_NORMAL; + } + break; + case STATE_OPT: + parseopt(ts, ts->code, c); + ts->state = STATE_NORMAL; + break; + case STATE_SB: + ts->code = c; + ts->optlen = 0; + ts->state = STATE_OPTDAT; + break; + case STATE_OPTDAT: + if(c == TELNET_IAC) + ts->state = STATE_SE; + else if(ts->optlen < sizeof(ts->optdata)) + ts->optdata[ts->optlen++] = c; + break; + case STATE_SE: + if(c == TELNET_SE) + parseoptdat(ts, ts->code, ts->optdata, ts->optlen); + ts->state = STATE_NORMAL; + break; + } + } + ts->bi.end = q; +} + +static portTASK_FUNCTION(vTELNETd, pvParameters) +{ + struct sockaddr_in sin; + fd_set fdsr; + struct timeval tv_timeout; + static char cmdline1[UIF_MAX_LINE]; + static char cmdline2[UIF_MAX_LINE]; + int sock, s, rc, n, argc, pos, ch, i, j; + char *argv[UIF_MAX_ARGS + 1]; /* one extra for null terminator */ + pos = 0; + if(pvParameters); + ts = (struct termstate *)pvPortMalloc(sizeof(struct termstate)); + if(ts == NULL) + { + printD("TELNETd: malloc error\r\n"); + vTaskDelete(0); + } + sock = socket(AF_INET, SOCK_STREAM, 0); + if(sock < 0) + { + printD("TELNETd: error %d in socket\r\n", errno); + vTaskDelete(0); + } + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons(PortTELNET); + rc = bind(sock, (struct sockaddr *) &sin, sizeof sin); + if(rc < 0) + { + printD("TELNETd: error %d in bind\r\n", errno); + vTaskDelete(0); + } + rc = listen(sock, 5); + if(rc < 0) + { + printD("TELNETd: error %d in listen\r\n", errno); + close(sock); + vTaskDelete(0); + } + while(1) + { + int off = 0; + struct sockaddr_in sin; + int len = sizeof(sin); + s = accept(sock, (struct sockaddr *)&sin, &len); + if(s < 0) + { + printD("TELNETd: error %d in accept\r\n", errno); + close(sock); + vTaskDelete(0); + } + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char *)&off, sizeof(off)); + /* Initialize terminal state */ + memset(ts, 0, sizeof(struct termstate)); + ts->sock = s; + ts->state = STATE_NORMAL; + ts->term.type = TERM_VT100; + ts->term.cols = 80; + ts->term.lines = 25; + /* Send initial options */ + sendopt(ts, TELNET_WILL, TELOPT_ECHO); + ts->bo.start = ts->bo.data; + board_putchar_flush(); + board_printf(PROMPT); + board_putchar_flush(); + while(1) + { + FD_ZERO(&fdsr); + FD_SET(ts->sock, &fdsr); + tv_timeout.tv_sec = 1; + tv_timeout.tv_usec = 0; + if((i = select(FD_SETSIZE, &fdsr, NULL, NULL, &tv_timeout)) == -1) + { + printD("TELNETd: error %d in select\r\n", errno); +done: + close(ts->sock); + ts->sock = -1; + break; + } + if((i > 0) && FD_ISSET(ts->sock, &fdsr)) + { + if(ts->bi.start == ts->bi.end) + { + /* Read data from user */ + n = recv(ts->sock, ts->bi.data, sizeof(ts->bi.data), 0); + if(n < 0) + goto done; + ts->bi.start = ts->bi.data; + ts->bi.end = ts->bi.data + n; + } + /* Parse user input for telnet options */ + parse(ts); + if(ts->bi.start != ts->bi.end) + { + /* Write data to application */ + n = (int)(ts->bi.end - ts->bi.start); + for(j = 0; j < n; j++) + { + ch = (int)ts->bi.start[j]; + if((ch != '\r') && (ch != '\n') && (pos < UIF_MAX_LINE)) + { + switch(ch) + { + case 0x08: /* Backspace */ + case 0x7F: /* Delete */ + if(pos > 0) + { + pos -= 1; +// board_putchar(0x08); /* backspace */ +// board_putchar(' '); +// board_putchar(0x08); /* backspace */ + } + break; + default: + if((pos+1) < UIF_MAX_LINE) + { + /* only printable characters */ + if((ch > 0x1f) && (ch < 0x80)) + { + cmdline1[pos++] = (char)ch; +// board_putchar((char)ch); + } + } + break; + } + } + else + { + cmdline1[pos] = '\0'; + board_putchar('\r'); + board_putchar('\n'); + if(!(argc = make_argv(cmdline1, argv))) + { + /* no command entered, just a blank line */ + strcpy(cmdline1, cmdline2); + argc = make_argv(cmdline1, argv); + } + cmdline2[0] = '\0'; + if(argc) + { + /* First try for an exact match on command name */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strcasecmp(UIF_CMDTAB[i].cmd,argv[0]) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + goto next_cmd; + } + else + { + board_printf(SYNTAX,argv[0]); + goto next_cmd; + } + } + } + /* Now try for short-hand match on command name */ + for(i = 0; i < UIF_NUM_CMD; i++) + { + if(strncasecmp(UIF_CMDTAB[i].cmd,argv[0], UIF_CMDTAB[i].unique) == 0) + { + if(((argc-1) >= UIF_CMDTAB[i].min_args) && ((argc-1) <= UIF_CMDTAB[i].max_args)) + { + if(UIF_CMDTAB[i].flags & UIF_CMD_FLAG_REPEAT) + strcpy(cmdline2,argv[0]); + board_putchar_flush(); + UIF_CMDTAB[i].func(argc,argv); + goto next_cmd; + } + else + { + board_printf(SYNTAX,argv[0]); + goto next_cmd; + } + } + } + board_printf(INVCMD,argv[0]); + board_printf(HELPMSG); + } +next_cmd: + board_putchar_flush(); + board_printf(PROMPT); + board_putchar_flush(); + pos = 0; + } + } + ts->bi.start += n; + } + } + } + } +} + +static void *test_debug_fault(unsigned long address, unsigned long vector, unsigned char *RegList) +{ +#ifndef MCF547X + (void)RegList; +#endif + if(pxCurrentTCB == tid_TOS) + { +#ifndef KILL_TOS_ON_FAULT + if(address >= (unsigned long)__SDRAM_SIZE) + vector = 0; /* => kill TOS */ + switch(vector) + { + case 3: /* Address Error */ + case 4: /* Illegal Instruction */ + case 5: /* Integer Zero Divide */ + case 8: /* Privilege Violation */ + case 11: /* Line F */ + return(NULL); /* hope than TOS fix fault himself */ + case 2: /* Access Fault */ + if((address < CF68KLIB) || (address >= CF68KLIB+0x10000)) /* 65KB */ + return(NULL); /* hope than TOS fix fault himself */ + /* else access fault inside CF68KLIB => kill TOS */ + default: /* other faults => kill TOS */ +#endif /* KILL_TOS_ON_FAULT */ +#ifdef MCF5445X + save_imrl0 |= (INTC_IMRL_INT_MASK26 | INTC_IMRL_INT_MASK28); /* mask UART 0 (serial) & UART 2 (IKBD) */ + MCF_INTC_IMRL0 = save_imrl0; + MCF_INTC_IMRH0 = save_imrh0; + MCF_INTC_IMRH1 = save_imrh1; +#else + MCF_INTC_IMRL = save_imrl; + save_imrh |= (MCF_INTC_IMRH_INT_MASK35 | MCF_INTC_IMRH_INT_MASK55 | MCF_INTC_IMRH_INT_MASK56 | MCF_INTC_IMRH_INT_MASK57); /* mask serial & CAN (IKBD) */ + MCF_INTC_IMRH = save_imrh; +#endif + *(unsigned short *)_timer_ms = 0; /* TOS is dead, flag used for polling serial ... */ +#ifndef KILL_TOS_ON_FAULT + break; + } +#endif /* KILL_TOS_ON_FAULT */ + *(unsigned long *)memvalid = 0; /* force cold reset to next reset */ + } +#ifdef MCF547X + else if((pxCurrentTCB == tid_ETOS) && (vector != 3) && (vector != 4)) /* rebuild return exception frame, EMUTOS not use the CF68KLIB */ + { + unsigned long ssp = (*(unsigned long *)&RegList[76]) + 8; + unsigned long pc = *(unsigned long *)&RegList[64]; + unsigned long sr = (unsigned long)(*(unsigned short *)&RegList[68]); + unsigned long format = (vector << 18) | sr; + unsigned long jump = *(unsigned long *)(vector * 4); + switch(ssp & 3) + { + case 0: format |= 0x40000000UL; break; + case 1: format |= 0x50000000UL; ssp--; break; + case 2: format |= 0x60000000UL; ssp -= 2; break; + case 3: format |= 0x70000000UL; ssp -= 3; break; + } + if(*(unsigned long *)phystop <= 0x80000) + *(unsigned long *)phystop = 0xE00000; /* FPGA 0xFFFF8006 has bad infos */ + asm volatile ( + " move.l %0,SP\n\t" + " move.l %1,-(SP)\n\t" + " move.l %2,-(SP)\n\t" + " move.l %3,-(SP)\n\t" + " move.l %4,A0\n\t" + " movem.l (A0),D0-D7/A0-A6\n\t" + " rts" : : "d" (ssp), "d" (pc), "d" (format), "d" (jump), "d" (RegList) : "a0", "sp" ); + } +#endif + else if(pxCurrentTCB == tid_DEBUG) + restart_debug = 1; + vTaskDelete(0); + while(1); +} + +static portTASK_FUNCTION(vDEBUG, pvParameters) +{ + /* The parameters are not used in this function */ + (void)pvParameters; + *(unsigned long *)(handler_fault) = (unsigned long)test_debug_fault; + BASE = 16; + md_last_address = 0; + md_last_size = 0; + disasm_last_address = 0; + cmdline1[0] = cmdline2[0] = '\0'; + history_init(); + while(1) + { + board_putchar_flush(); + board_printf(PROMPT); + board_putchar_flush(); + run_cmd(); + } +} + +static void start_debug(vid) +{ + xTaskCreate(vDEBUG, (void *)"DBUG", STACK_DEFAULT, NULL, DEBUG_TASK_PRIORITY, &tid_DEBUG); +} + +#endif /* DBUG */ + +void start_servers(void) +{ +#ifdef DBUG + xTaskCreate(vTELNETd, (void *)"TELNETd", STACK_DEFAULT, NULL, TELNET_TASK_PRIORITY, &tid_TELNET); +#endif +#ifdef FTP_SERVER + xTaskCreate(vFTPd, (void *)"FTPd", STACK_DEFAULT, NULL, FTP_TASK_PRIORITY, NULL); +#endif + xTaskCreate(vTFTPd, (void *)"TFTPd", STACK_DEFAULT, NULL, TFTP_TASK_PRIORITY, NULL); + /* Start the webserver */ + xTaskCreate(vBasicWEBServer, (void *)"HTTPd", STACK_DEFAULT, NULL, WEB_TASK_PRIORITY, &tid_HTTPd); +} + +#endif /* COLDFIRE */ + +static int geterrno(void) +{ + return(errno); +} + +static SOCKET_COOKIE sc = +{ + 0x0101, /* version */ + 'SOCK', /* magic */ + lwip_socket, + lwip_bind, + lwip_listen, + lwip_accept, + lwip_connect, + lwip_write, + lwip_send, + lwip_sendto, + lwip_read, + lwip_recv, + lwip_recvfrom, + lwip_shutdown, + lwip_close, + lwip_getsockname, + lwip_getpeername, + lwip_getsockopt, + lwip_setsockopt, + lwip_select, + lwip_ioctl, + gethostbyname, + geterrno +}; + +#ifdef COLDFIRE +void init_lwip(void) +#else +void init_lwip(unsigned long ip_addr, unsigned long mask_addr, unsigned long gateway_addr) +#endif +{ + struct ip_addr xIpAddr, xNetMast, xGateway; + static struct netif loop_if; +#ifdef COLDFIRE + unsigned long IP; + static struct netif fec54xx0_if; +#ifndef MCF547X + static struct netif fec54xx1_if; +#endif +#else /* !COLDFIRE */ + static struct netif rtl8139_if; +#endif /* COLDFIRE */ + errno = 0; + /* Initialize lwIP and its interface layer */ + sys_init(); + mem_init(); + memp_init(); + pbuf_init(); + netif_init(); + ip_init(); + tcpip_init(NULL, NULL); + socket_init(); +#ifdef COLDFIRE + board_get_server((unsigned char *)&IP); + xIpAddr.addr = htonl(IP); // not used actually + // => DNS_SERVER_ADDRESS in dns.c +#endif + /* Initialize the loopback interface structure */ + xIpAddr.addr = INADDR_LOOPBACK; + xGateway.addr = 0; + xNetMast.addr = 0; // 0xFF000000 + if(netif_add(&loop_if, &xIpAddr, &xNetMast, &xGateway, NULL, loopif_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&loop_if); + /* bring it up */ + netif_set_up(&loop_if); + } +#ifdef COLDFIRE + else + { + board_printf("Loopback init error\r\n"); + while(1) + vTaskDelay(1); + } + /* Initialize the network interface structure */ + board_get_client((unsigned char *)&IP); + xIpAddr.addr = htonl(IP); + board_get_gateway((unsigned char *)&IP); + xGateway.addr = htonl(IP); + board_get_netmask((unsigned char *)&IP); + xNetMast.addr = htonl(IP); + /* caches must be disabled */ + if(netif_add(&fec54xx0_if, &xIpAddr, &xNetMast, &xGateway, NULL, mcf_fec0_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&fec54xx0_if); + /* bring it up */ + netif_set_up(&fec54xx0_if); + } + else + { + board_printf("FEC0 init error\r\n"); + while(1) + vTaskDelay(1); + } +#if 0 +#ifndef MCF547X + board_get_client((unsigned char *)&IP); + IP += 0x100; + xIpAddr.addr = htonl(IP); + board_get_gateway((unsigned char *)&IP); + xGateway.addr = htonl(IP); + board_get_netmask((unsigned char *)&IP); + xNetMast.addr = htonl(IP); + if(netif_add(&fec54xx1_if, &xIpAddr, &xNetMast, &xGateway, NULL, mcf_fec1_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&fec54xx1_if); + /* bring it up */ + netif_set_up(&fec54xx1_if); + } + else + { + board_printf("FEC1 init error\r\n"); + while(1) + vTaskDelay(1); + } +#endif /* MCF547X */ +#endif + enable_caches(); +#ifdef DBUG + breakpoint_init(); +#endif +#ifdef MCF547X + if(MCF_GPIO_PPDSDR_PSC3PSC2 & MCF_GPIO_PPDSDR_PSC3PSC2_PPDSDR_PSC3PSC27) +#endif /* MCF547X */ + { + start_servers(); + } +#else /* !COLDFIRE */ + /* Initialize the network interface structure */ + xIpAddr.addr = ip_addr; + xGateway.addr = gateway_addr; + xNetMast.addr = mask_addr; + if(netif_add(&rtl8139_if, &xIpAddr, &xNetMast, &xGateway, NULL, rtl8139if_init, tcpip_input) != NULL) + { + /* make it the default interface */ + netif_set_default(&rtl8139_if); + /* bring it up */ + netif_set_up(&rtl8139_if); + } +#endif /* COLDFIRE */ + lwip_ok = 1; +} + +#ifdef COLDFIRE + +static portTASK_FUNCTION(vTOS, pvParameters) +{ + void (*return_address)(void) = (void (*)(void))pvParameters; + vTaskDelay(configTICK_RATE_HZ/10); + return_address(); + while(1); +} + +static portTASK_FUNCTION(vROOT, pvParameters) +{ +#ifdef MCF547X + extern short swi; + int shutdown_ethernet = 0; +#endif +#ifdef USB_DEVICE +#ifndef MCF5445X +#ifndef MCF547X + int init_usb = 0; +#endif +#endif +#endif +// int error = 0; +#if 0 // #ifdef MCF547X + extern void hbl_int(void); + extern unsigned long get_timer(void); + int tick_count = 0; + unsigned long start_timer = get_timer(); + int level = vPortSetIPL(portIPL_MAX); + old_hbl = *(unsigned long *)((64+2)*4 + coldfire_vector_base); + *(unsigned long *)((64+2)*4 + coldfire_vector_base) = (unsigned long)hbl_int; + MCF_EPORT_EPIER |= MCF_EPORT_EPIER_EPIE2; + MCF_EPORT_EPFR |= MCF_EPORT_EPFR_EPF2; /* clear interrupt */ + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK2; /* enable interrupt */ + asm_set_ipl(level); +#endif /* MCF547X */ +#ifdef USE_RTC +#ifndef MCF5445X +#ifndef MCF547X + extern void RTC_task(void); + xTaskCreate((pdTASK_CODE)RTC_task, (void *)"RTCd", STACK_DEFAULT, NULL, RTC_TASK_PRIORITY, NULL); +#endif +#endif +#endif + restart_debug = 0; + init_lwip(); + xTaskCreate(vTOS, (void *)"TOS", STACK_DEFAULT, pvParameters, TOS_TASK_PRIORITY, &tid_TOS); +#ifdef DBUG + start_debug(); +#endif + while(1) + { +#ifdef USB_DEVICE +#ifndef MCF5445X +#ifndef MCF547X + if(size_ram_disk && !init_usb) + { + vTaskDelay(configTICK_RATE_HZ); + init_usb_device(); + init_usb = 1; + } +#endif /* MCF547X */ +#endif /* MCF5445X */ +#endif /* USB_DEVICE */ +#ifdef DBUG + if(restart_debug == 1) + { + restart_debug = 0; + vTaskDelay(configTICK_RATE_HZ/2); + start_debug(); + } +#if 0 + if(!error + && (*(unsigned long *)VBL_VEC >= (unsigned long)__SDRAM_SIZE)) + { + board_printf("VBL vector destroyed!\r\n"); + error = 1; + } +#endif +#endif /* DBUG */ +#if defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI) + if(1 +#ifdef CONFIG_USB_OHCI + && ohci_inited +#endif +#ifdef CONFIG_USB_EHCI +// && ehci_inited +#endif + ) + { +#ifndef CONFIG_USB_INTERRUPT_POLLING +#ifndef MCF5445X +#ifndef MCF547X + /* move INT7 to native interrupt (M5484LITE/M5485EVB) */ + /* INT7 call INT2 who is masked by other task than TOS (level 3) */ + if((save_imrl & (1 << 7)) && !(save_imrl_tos & (1 << 7))) + { + int level = asm_set_ipl(7); /* disable interrupts */ + *(unsigned long *)(((64+7) * 4) + coldfire_vector_base) = *(unsigned long *)((64+7+OFFSET_INT_CF68KLIB) * 4); + MCF_INTC_IMRL &= ~MCF_INTC_IMRL_INT_MASK7; /* enable interrupt */ + asm_set_ipl(level); + } +#endif /* MCF547X */ +#endif /* MCF5445X */ +#endif /* CONFIG_USB_INTERRUPT_POLLING */ + } +#endif /* CONFIG_USB_UHCI || CONFIG_USB_OHCI || CONFIG_USB_EHCI */ +#ifndef MCF5445X + /* enable XLB PCI for all tasks */ + if((save_imrh & (1 << 11)) && !(save_imrh_tos & (1 << 11))) + { + int level = asm_set_ipl(7); /* disable interrupts */ + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK43; /* enable interrupt */ + asm_set_ipl(level); + } +#endif /* MCF5445X */ +#ifdef MCF547X + if(boot_os) + { + unsigned long start_addr = 0; + switch(boot_os) + { + case 1: + start_addr = 0xE0600000; + break; + default: + if(swi & 1) /* boot from rescue TOS at 0xE0000000 */ + start_addr = 0xE0400000; +#ifdef DBUG + else if((tid_TELNET == NULL) && (tid_HTTPd == NULL)) +#else + else if(tid_HTTPd == NULL) +#endif + start_servers(); + break; + } + if(start_addr) + { + if(*(short *)start_addr == 0x602E) + go_emutos(start_addr); + boot_os = 0; + } + } + else if(!shutdown_ethernet && lwip_ok && drive_ok + && (!(swi & 0x40) || !(swi & 1)) /* !SW5 (UP) */ + && !(swi & 0x80)) /* !SW6 (UP) */ + { /* TOS for MiNT */ + COOKIE *mint_cookie = *(COOKIE **)cookie; + while(mint_cookie != NULL) + { + if(mint_cookie->ident == 'MiNT') + { + COOKIE *eth_cookie = *(COOKIE **)cookie; + extern void fec_eth_stop(uint8 ch); + board_printf("Shutdown FEC...\r\n"); + fec_eth_stop(0); + while(eth_cookie != NULL) + { + if((eth_cookie->ident == 'SOCK') || (eth_cookie->ident == 'STiK')) + { + eth_cookie->ident = 'NULL'; + eth_cookie->v.l = 0; + } + if(!eth_cookie->ident) + eth_cookie = NULL; + else + eth_cookie++; + } + shutdown_ethernet = 1; + break; + } + if(!mint_cookie->ident) + mint_cookie = NULL; + else + mint_cookie++; + } + } +#endif /* MCF547X */ +#if 0 // #ifdef MCF547X + tick_count++; + if(tick_count > configTICK_RATE_HZ*10) + { + unsigned long time = get_timer(); + board_printf("VBL interval %d uS (%d %d)\r\n", (int)((time - start_timer)/(hbl_count * SYSTEM_CLOCK)), hbl_count, (time - start_timer)/SYSTEM_CLOCK); + level = vPortSetIPL(portIPL_MAX); + start_timer = get_timer(); + tick_count = 0; + hbl_count = 0; + asm_set_ipl(level); + } +#endif + vTaskDelay(1); + } +} + +void xSemaphoreTakeBDOS(void) +{ + while(xSemaphoreAltTake(xSemaphoreBDOS, portMAX_DELAY) != pdTRUE); +} + +void xSemaphoreGiveBDOS(void) +{ + xSemaphoreAltGive(xSemaphoreBDOS); +} + +int tftpreceive(unsigned char *server, char *sname, short handle, long *size) +{ + struct sockaddr_in address_server; + address_server.sin_family = AF_INET; + address_server.sin_port = htons(PortTFTP); + memcpy(&address_server.sin_addr.s_addr, server, 4); + address_server.sin_addr.s_addr = htonl(address_server.sin_addr.s_addr); + return(tftp_receive(&address_server, sname, "octet", handle, size) == 0 ? TRUE : FALSE); +} + +int tftpsend(unsigned char *server, char *sname, short handle) +{ + struct sockaddr_in address_server; + address_server.sin_family = AF_INET; + address_server.sin_port = htons(PortTFTP); + memcpy(&address_server.sin_addr.s_addr, server, 4); + address_server.sin_addr.s_addr = htonl(address_server.sin_addr.s_addr); + return(tftp_send(&address_server, sname, "octet", handle) == 0 ? TRUE : FALSE); +} + +int usb_load_files(void) +{ +#ifdef USB_DEVICE +#ifdef MCF5445X + return(FALSE); +#else /* MCF548X */ +#ifdef MCF547X + return(FALSE); +#else /* MCF548X */ + int sec = 60; /* seconds */ + board_printf("Waiting USB mass storage link...\r\n"); + while(ext_write_protect_ram_disk == FALSE) + { + vTaskDelay(configTICK_RATE_HZ); + sec--; + if(sec <= 0) + return(FALSE); /* timeout */ + } + while(ext_write_protect_ram_disk == TRUE) + vTaskDelay(1); + return(TRUE); /* continue boot with updated ram-disk */ +#endif /* MCF547X */ +#endif /* MCF5445X */ +#else + return(FALSE); +#endif /* USB_DEVICE */ +} + +#endif /* COLDFIRE */ + +int init_network(void) +{ + extern DRV_LIST stik_driver; + extern int gs_init_stik_if(void); + extern int gs_init_mem(void); + COOKIE pck; +#if defined(COLDFIRE) && !defined(MCF5445X) + extern char dma_cf_cookie[]; + pck.ident = 'DMAC'; + pck.v.l = (long)&dma_cf_cookie; + add_cookie(&pck); +#endif /* defined(COLDFIRE) && !defined(MCF5445X) */ + if(!lwip_ok) + return(FALSE); + pck.ident = 'SOCK'; + pck.v.l = (long)≻ + add_cookie(&pck); + gs_init_stik_if(); + gs_init_mem(); + pck.ident = 'STiK'; + pck.v.l = (long)&stik_driver; + add_cookie(&pck); + return(TRUE); +} + +#ifdef COLDFIRE + +int init_rtos(void *params) +{ + extern unsigned char _bss_start_freertos[]; + extern unsigned char _end_freertos[]; + extern void init_dma(void); + memset(_bss_start_freertos, 0, (int)(_end_freertos-_bss_start_freertos)); + size_ram_disk = 0; + pxCurrentTCB = NULL; + tid_TOS = (void *)-1; /* for vPortSetIPL() */ + tid_TELNET = tid_DEBUG = tid_HTTPd = NULL; +#ifdef MCF547X + tid_ETOS = NULL; + boot_os = 0; + drive_ok = 0; +#endif + start_run = NULL; + lwip_ok = get_serial_vector = get_ikbd_vector = tos_suspend = 0; + *(unsigned short *)_timer_ms = 0; + vSemaphoreCreateBinary(xSemaphoreBDOS); + xQueueAlert = xQueueCreate(2, 256); + init_dma(); + if(xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, params, ROOT_TASK_PRIORITY, NULL) == pdPASS) + vTaskStartScheduler(); + return 0; +} + +#endif /* COLDFIRE */ + +#endif /* LWIP */ + +#if !defined(COLDFIRE) && defined(FREERTOS) + +xTaskHandle pxCurrentTCB, tid_TOS, tid_INTPCI; +xQueueHandle xQueueAlert, xQueueEvent; +portBASE_TYPE xNeedSwitchPCI; /* drivers must use this variable */ +static unsigned long pcibios_callback[4], old_vector[4]; +short OldBoot; + +void pci_int(portBASE_TYPE num) +{ + xNeedSwitchPCI = pdFALSE; + void (*f)(long num) = (void (*)(long))pcibios_callback[num]; + if(f != NULL) + f(num + 1); +} + +static void pci_inta_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t" ); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " clr.l -(SP)\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static void pci_intb_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t"); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " pea 1\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static void pci_intc_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t"); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " pea 2\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static void pci_intd_int(void) +{ + asm volatile(" move.w #0x2700,SR\n\t"); +#if _GCC_USES_FP == 1 + asm volatile(" unlk fp\n\t"); +#endif + portSAVE_CONTEXT(); + { + asm volatile( + " pea 3\n\t" + " jsr _pci_int\n\t" + " addq.l #4,SP\n\t" ); + if(xNeedSwitchPCI) + vTaskSwitchContext(); + } + portRESTORE_CONTEXT(); +} + +static portTASK_FUNCTION(vINTPCI, pvParameters) /* PCI interrupt */ +{ + static long params[2]; + /* The parameters are not used in this function */ + (void)pvParameters; + while(1) + { + if(xQueueAltReceive(xQueueEvent, params, portMAX_DELAY) == pdPASS) + { + long num = params[1]; + void (*f)(long num) = (void (*)(long))params[0]; + if(f != NULL) + f(num); + } + } +} + +static portTASK_FUNCTION(vTOS, pvParameters) +{ + /* The parameters are not used in this function */ + (void)pvParameters; + asm volatile(" jmp _goto_tos"); +} + +static portTASK_FUNCTION(vROOT, pvParameters) +{ + extern void led_floppy(long state); + extern short ethernet_found, drive_ok; + int shutdown_ethernet = 0, count = 0, vectors_ok =0; + unsigned long config_pci = *(unsigned long *)pvParameters; + if(config_pci) + { + if(xQueueEvent != NULL) + xTaskCreate(vINTPCI, "INTPCI", STACK_DEFAULT, NULL, INTPCI_TASK_PRIORITY, &tid_INTPCI); + } + xTaskCreate(vTOS, (void *)"TOS", STACK_DEFAULT >> 1, NULL, TOS_TASK_PRIORITY, &tid_TOS); + while(1) + { + if(config_pci && drive_ok && !vectors_ok) /* check drive_ok (set by init_before_autofolder) else theses vectors are detroyed by the boot init exceptions */ + { + int i, level = portSET_IPL(portIPL_MAX); + OldBoot = 1; + for(i = 0; i < 4; i++) + { + unsigned long *vector = (unsigned long *)*(unsigned long *)((PCI_IRQ_BASE_VECTOR + i + 1) * 4); + if((vector[-2] == '_PCI') && (vector[-3] == 'XBRA') && (vector[-5] == '_PCI')) /* extra code for FreeRTOS subroutine */ + { + OldBoot = 0; + pcibios_callback[i] = vector[-4]; + old_vector[i] = *(unsigned long *)((PCI_IRQ_BASE_VECTOR + i + 1) * 4); + switch(i) + { + case 0: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 1) * 4) = (unsigned long)pci_inta_int; break; + case 1: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 2) * 4) = (unsigned long)pci_intb_int; break; + case 2: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 3) * 4) = (unsigned long)pci_intc_int; break; + case 3: *(unsigned long *)((PCI_IRQ_BASE_VECTOR + 4) * 4) = (unsigned long)pci_intd_int; break; + } + } + } + portSET_IPL(level); + vectors_ok = 1; + } + if(!shutdown_ethernet && lwip_ok) + { + COOKIE *mint_cookie = *(COOKIE **)cookie; + while(mint_cookie != NULL) + { + if(mint_cookie->ident == 'MiNT') + { + COOKIE *eth_cookie = *(COOKIE **)cookie; + extern void rtl8139_eth_stop(uint8 ch); +// board_printf("Shutdown RTL8139...\r\n"); + rtl8139_eth_stop(0); + while(eth_cookie != NULL) + { + if((eth_cookie->ident == 'SOCK') || (eth_cookie->ident == 'STiK')) + { + eth_cookie->ident = 'NULL'; + eth_cookie->v.l = 0; + } + if(!eth_cookie->ident) + eth_cookie = NULL; + else + eth_cookie++; + } + if(config_pci) + { + int i, level = portSET_IPL(portIPL_MAX); + for(i = 0; i < 4; i++) + { + if(old_vector[i]) + { + *(unsigned long *)((PCI_IRQ_BASE_VECTOR + i + 1) * 4) = old_vector[i]; + old_vector[i] = 0; + } + } + portSET_IPL(level); + } + shutdown_ethernet = 1; + ethernet_found = 0; + break; + } + if(!mint_cookie->ident) + mint_cookie = NULL; + else + mint_cookie++; + } + } + if(config_pci && !ethernet_found) + { + if(!count) + led_floppy(1); + else if(count == configTICK_RATE_HZ) + led_floppy(0); + } + count++; + if(count >= configTICK_RATE_HZ*2) + count = 0; + vTaskDelay(1); + } +} + +int rtos_handler(void *f, long num) /* from PCI BIOS interrupt */ +{ + extern short ethernet_found; + static long params[2]; + params[0] = (long)f; /* before change the stack */ + params[1] = num; + if((tid_INTPCI != NULL) && !ethernet_found) + { +#ifdef SWITCH_CONTEXT + asm volatile(" move.w #0x2700,SR\n\t"); + asm volatile(" lea 4*(16+3)(SP),SP\n\t"); /* fix PCI BIOS stack !!! */ + /* Save the context of the interrupted task. */ + portSAVE_CONTEXT(); +#endif + /* If a switch is required we call vTaskSwitchContext(). */ + portBASE_TYPE xNeedSwitch = pdFALSE; + xNeedSwitch = xQueueSendFromISR(xQueueEvent, params, xNeedSwitch); +#ifdef SWITCH_CONTEXT + /* If a switch is required we call vTaskSwitchContext(). */ + if(xNeedSwitch) + vTaskSwitchContext(); + portRESTORE_CONTEXT(); /* not return */ +#endif + return(0); + } + return(-1); /* error */ +} + +int init_rtos(void) /* CT60 / CTPCI */ +{ + unsigned long config_pci = ct60_rw_parameter(CT60_MODE_READ, CT60_PARAM_CTPCI, 0) & 0x80; + pxCurrentTCB = tid_TOS = tid_INTPCI = NULL; + xQueueAlert = xQueueCreate(2, 256); + xQueueEvent = xQueueCreate(8, sizeof(long) * 2); + if(xTaskCreate(vROOT, (void *)"ROOT", STACK_DEFAULT, &config_pci, ROOT_TASK_PRIORITY, NULL) == pdPASS) + vTaskStartScheduler(); + return(0); +} + +#endif /* !defined(COLDFIRE) && defined(FREERTOS) */ diff --git a/flash.tos/drivers/lwip/ip.c b/flash.tos/drivers/lwip/ip.c index 3afb459..3d7c8da 100644 --- a/flash.tos/drivers/lwip/ip.c +++ b/flash.tos/drivers/lwip/ip.c @@ -60,7 +60,6 @@ # include "dhcp.h" #endif /* LWIP_DHCP */ -#ifdef NETWORK #ifdef LWIP /** @@ -515,7 +514,6 @@ ip_debug_print(struct pbuf *p) #endif /* IP_DEBUG */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/ip_addr.c b/flash.tos/drivers/lwip/ip_addr.c index 91e38af..9b616b3 100644 --- a/flash.tos/drivers/lwip/ip_addr.c +++ b/flash.tos/drivers/lwip/ip_addr.c @@ -35,7 +35,6 @@ #include "inet.h" #include "netif.h" -#ifdef NETWORK #ifdef LWIP #define IP_ADDR_ANY_VALUE 0x00000000UL @@ -82,5 +81,4 @@ u8_t ip_addr_isbroadcast(struct ip_addr *addr, struct netif *netif) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/ip_frag.c b/flash.tos/drivers/lwip/ip_frag.c index a51d225..0e7ea07 100644 --- a/flash.tos/drivers/lwip/ip_frag.c +++ b/flash.tos/drivers/lwip/ip_frag.c @@ -47,7 +47,6 @@ #include "snmp.h" #include "stats.h" -#ifdef NETWORK #ifdef LWIP static u8_t ip_reassbuf[IP_HLEN + IP_REASS_BUFSIZE]; @@ -392,5 +391,4 @@ ip_frag(struct pbuf *p, struct netif *netif, struct ip_addr *dest) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/ks8721.c b/flash.tos/drivers/lwip/ks8721.c index 86b8ab7..f09e4f9 100644 --- a/flash.tos/drivers/lwip/ks8721.c +++ b/flash.tos/drivers/lwip/ks8721.c @@ -11,7 +11,6 @@ #include "fec.h" #include "ks8721.h" -#ifdef NETWORK #ifdef LWIP #undef DEBUG @@ -190,4 +189,3 @@ int ks8721_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex) #endif #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/loopif.c b/flash.tos/drivers/lwip/loopif.c index f868497..f1624fe 100644 --- a/flash.tos/drivers/lwip/loopif.c +++ b/flash.tos/drivers/lwip/loopif.c @@ -45,7 +45,6 @@ #include "tcp.h" #include "ip.h" -#ifdef NETWORK #ifdef LWIP #undef DEBUG @@ -164,5 +163,4 @@ loopif_init(struct netif *netif) #endif /* LWIP_HAVE_LOOPIF */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/mem.c b/flash.tos/drivers/lwip/mem.c index 29e4843..ed147c8 100644 --- a/flash.tos/drivers/lwip/mem.c +++ b/flash.tos/drivers/lwip/mem.c @@ -48,7 +48,15 @@ #include "sys.h" #include "stats.h" -#ifdef NETWORK +#define USE_MALLOC + +#ifdef COLDFIRE +#define pvPortMalloc pvPortMalloc2 +#else +#include +#define pvPortMalloc(a) Mxalloc(a, 3) +#endif + #ifdef LWIP #if (MEM_LIBC_MALLOC == 0) @@ -73,8 +81,11 @@ struct mem { }; static struct mem *ram_end; +#ifdef USE_MALLOC static u8_t *ram; -// static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT]; +#else +static u8_t ram[MEM_SIZE + sizeof(struct mem) + MEM_ALIGNMENT]; +#endif /* USE_MALLOC */ #define MIN_SIZE 12 #if 0 /* this one does not align correctly for some, resulting in crashes */ @@ -127,9 +138,11 @@ mem_init(void) { struct mem *mem; - u8_t *ram_heap = (u8_t *)pvPortMalloc2(MEM_SIZE+ sizeof(struct mem) + MEM_ALIGNMENT); +#ifdef USE_MALLOC + u8_t *ram_heap = (u8_t *)pvPortMalloc(MEM_SIZE+ sizeof(struct mem) + MEM_ALIGNMENT); LWIP_ASSERT("mem_init: ram != NULL", ram_heap != NULL); ram = MEM_ALIGN(ram_heap); +#endif /* USE_MALLOC */ memset(ram, 0, MEM_SIZE); mem = (struct mem *)ram; mem->next = MEM_SIZE; @@ -411,5 +424,4 @@ mem_malloc(mem_size_t size) #endif /* MEM_LIBC_MALLOC == 0 */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/memp.c b/flash.tos/drivers/lwip/memp.c index 03039ff..67c1b2e 100644 --- a/flash.tos/drivers/lwip/memp.c +++ b/flash.tos/drivers/lwip/memp.c @@ -47,7 +47,15 @@ #include "sys.h" #include "stats.h" -#ifdef NETWORK +#define USE_MALLOC + +#ifdef COLDFIRE +#define pvPortMalloc pvPortMalloc2 +#else +#include +#define pvPortMalloc(a) Mxalloc(a, 3) +#endif + #ifdef LWIP struct memp { @@ -89,8 +97,9 @@ static const u16_t memp_num[MEMP_MAX] = { #define MEMP_TYPE_SIZE(qty, type) \ ((qty) * (MEMP_SIZE + MEM_ALIGN_SIZE(sizeof(type)))) +#ifdef USE_MALLOC static u8_t *memp_memory; -#if 0 +#else static u8_t memp_memory[MEM_ALIGNMENT - 1 + MEMP_TYPE_SIZE(MEMP_NUM_PBUF, struct pbuf) + MEMP_TYPE_SIZE(MEMP_NUM_RAW_PCB, struct raw_pcb) + @@ -144,7 +153,8 @@ memp_init(void) } #endif /* MEMP_STATS */ - memp_memory = (u8_t *)pvPortMalloc2(MEM_ALIGNMENT - 1 + +#ifdef USE_MALLOC + memp_memory = (u8_t *)pvPortMalloc(MEM_ALIGNMENT - 1 + MEMP_TYPE_SIZE(MEMP_NUM_PBUF, struct pbuf) + MEMP_TYPE_SIZE(MEMP_NUM_RAW_PCB, struct raw_pcb) + MEMP_TYPE_SIZE(MEMP_NUM_UDP_PCB, struct udp_pcb) + @@ -156,6 +166,7 @@ memp_init(void) MEMP_TYPE_SIZE(MEMP_NUM_API_MSG, struct api_msg) + MEMP_TYPE_SIZE(MEMP_NUM_TCPIP_MSG, struct tcpip_msg) + MEMP_TYPE_SIZE(MEMP_NUM_SYS_TIMEOUT, struct sys_timeo)); +#endif /* USE_MALLOC */ memp = MEM_ALIGN(memp_memory); for (i = 0; i < MEMP_MAX; ++i) { memp_tab[i] = NULL; @@ -258,6 +269,5 @@ memp_free(memp_t type, void *mem) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/nbuf.c b/flash.tos/drivers/lwip/nbuf.c index 6207c63..7f83411 100644 --- a/flash.tos/drivers/lwip/nbuf.c +++ b/flash.tos/drivers/lwip/nbuf.c @@ -17,7 +17,6 @@ #include "mem.h" -#ifdef NETWORK #ifdef LWIP /* ------------------------ Static variables ------------------------------ */ @@ -259,4 +258,3 @@ nbuf_t *nbuf_tx_free(uint8 ch) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/netif.c b/flash.tos/drivers/lwip/netif.c index c9964c6..fb1a5ba 100644 --- a/flash.tos/drivers/lwip/netif.c +++ b/flash.tos/drivers/lwip/netif.c @@ -45,7 +45,6 @@ #include "tcp.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP struct netif *netif_list; @@ -328,4 +327,3 @@ netif_init(void) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/pbuf.c b/flash.tos/drivers/lwip/pbuf.c index 5c27c37..1595429 100644 --- a/flash.tos/drivers/lwip/pbuf.c +++ b/flash.tos/drivers/lwip/pbuf.c @@ -76,11 +76,22 @@ #include "sys.h" #include "perf.h" -#ifdef NETWORK +#define USE_MALLOC + +#ifdef COLDFIRE +#define pvPortMalloc pvPortMalloc2 +#else +#include +#define pvPortMalloc(a) Mxalloc(a, 3) +#endif + #ifdef LWIP +#ifdef USE_MALLOC static u8_t *pbuf_pool_memory; -//static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))]; +#else +static u8_t pbuf_pool_memory[MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))]; +#endif /* USE_MALLOC */ #if !SYS_LIGHTWEIGHT_PROT static volatile u8_t pbuf_pool_free_lock, pbuf_pool_alloc_lock; @@ -107,8 +118,10 @@ pbuf_init(void) struct pbuf *p, *q = NULL; u32_t i; - pbuf_pool_memory = (u8_t *)pvPortMalloc2(MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))); +#ifdef USE_MALLOC + pbuf_pool_memory = (u8_t *)pvPortMalloc(MEM_ALIGNMENT - 1 + PBUF_POOL_SIZE * MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE + sizeof(struct pbuf))); LWIP_ASSERT("pbuf_init: pbuf_pool_memory != NULL", pbuf_pool_memory != NULL); +#endif pbuf_pool = (struct pbuf *)MEM_ALIGN(pbuf_pool_memory); #if PBUF_STATS @@ -1062,6 +1075,5 @@ pbuf_copy(struct pbuf *p_to, struct pbuf *p_from) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/perf.h b/flash.tos/drivers/lwip/perf.h index f5600fa..2daca58 100644 --- a/flash.tos/drivers/lwip/perf.h +++ b/flash.tos/drivers/lwip/perf.h @@ -50,6 +50,8 @@ struct perf { extern struct perf lwip_perfs[PERFS_MAX]; +#ifdef COLDFIRE + #define PERF_START do { \ int i = 0; \ SYS_ARCH_DECL_PROTECT(level); \ @@ -137,4 +139,12 @@ extern struct perf lwip_perfs[PERFS_MAX]; #endif /* MCF548X */ +#else /* !COLDFIRE */ + +#define PERF_START +#define PERF_STOP(x) +#define PERF_STOP_INT(x) + +#endif /* COLDFIRE */ + #endif /* __PERF_H__ */ diff --git a/flash.tos/drivers/lwip/raw.c b/flash.tos/drivers/lwip/raw.c index 6af7a83..24dcf06 100644 --- a/flash.tos/drivers/lwip/raw.c +++ b/flash.tos/drivers/lwip/raw.c @@ -55,7 +55,6 @@ #include "perf.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP #if LWIP_RAW @@ -333,5 +332,4 @@ raw_new(u16_t proto) { #endif /* LWIP_RAW */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/resolv.c b/flash.tos/drivers/lwip/resolv.c index 3c86761..965d0aa 100644 --- a/flash.tos/drivers/lwip/resolv.c +++ b/flash.tos/drivers/lwip/resolv.c @@ -87,7 +87,6 @@ #define DNS_SERVER_PORT 53 #endif -#ifdef NETWORK #ifdef LWIP PACK_STRUCT_BEGIN @@ -600,4 +599,3 @@ struct hostent *gethostbyname(const char *hostname) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/rtl8139.c b/flash.tos/drivers/lwip/rtl8139.c new file mode 100644 index 0000000..c279809 --- /dev/null +++ b/flash.tos/drivers/lwip/rtl8139.c @@ -0,0 +1,1318 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + A RealTek RTL-8139 Fast Ethernet driver for Linux. + + Maintained by Jeff Garzik + Copyright 2000,2001 Jeff Garzik + + Much code comes from Donald Becker's rtl8139.c driver, + versions 1.13 and older. This driver was originally based + on rtl8139.c version 1.07. Header of rtl8139.c version 1.13: + + ---------- + + Written 1997-2001 by Donald Becker. + This software may be used and distributed according to the + terms of the GNU General Public License (GPL), incorporated + herein by reference. Drivers based on or derived from this + code fall under the GPL and must retain the authorship, + copyright and license notice. This file is not a complete + program and may only be used when the entire operating + system is licensed under the GPL. + + This driver is for boards based on the RTL8129 and RTL8139 + PCI ethernet chips. + + The author may be reached as becker@scyld.com, or C/O Scyld + Computing Corporation 410 Severn Ave., Suite 210 Annapolis + MD 21403 + Support and updates available at + http://www.scyld.com/network/rtl8139.html + Twister-tuning table provided by Kinston + . + + ---------- + This software may be used and distributed according to the terms + of the GNU General Public License, incorporated herein by reference. + + Contributors: + + Donald Becker - he wrote the original driver, kudos to him! + (but please don't e-mail him for support, this isn't his driver) + + Tigran Aivazian - bug fixes, skbuff free cleanup + + Martin Mares - suggestions for PCI cleanup + + David S. Miller - PCI DMA and softnet updates + + Ernst Gill - fixes ported from BSD driver + + Daniel Kobras - identified specific locations of + posted MMIO write bugginess + + Gerard Sharp - bug fix, testing and feedback + + David Ford - Rx ring wrap fix + + Dan DeMaggio - swapped RTL8139 cards with me, and allowed me + to find and fix a crucial bug on older chipsets. + + Donald Becker/Chris Butterworth/Marcus Westergren - + Noticed various Rx packet size-related buglets. + + Santiago Garcia Mantinan - testing and feedback + + Jens David - 2.2.x kernel backports + + Martin Dennett - incredibly helpful insight on undocumented + features of the 8139 chips + + Jean-Jacques Michel - bug fix + + Tobias Ringström - Rx interrupt status checking suggestion + + Andrew Morton - Clear blocked signals, avoid + buffer overrun setting current->comm. + +--------------------------------------------------------------------------- */ + +/* ------------------------ System includes ------------------------------- */ +#include +#include +#include + +/* ------------------------ Platform includes ----------------------------- */ +#include "config.h" +#include "pcixbios.h" +#include "mod_devicetable.h" +#include "pci_ids.h" + +/* ------------------------ FreeRTOS includes ----------------------------- */ +#include "../freertos/FreeRTOS.h" +#include "../freertos/task.h" +#include "../freertos/queue.h" +#include "../freertos/semphr.h" + +/* ------------------------ lwIP includes --------------------------------- */ +#include "opt.h" +#include "def.h" +#include "mem.h" +#include "pbuf.h" +#include "sys.h" +#include "stats.h" +//#include "perf.h" +#include "etharp.h" +#include "debug.h" + +#include "rtl8139.h" + +/* ------------------------ Defines --------------------------------------- */ +#define ARRAY_SIZE(arr) (sizeof(arr) / (sizeof(arr)[0])) + +#define TASK_PRIORITY (30) + +#if defined(LWIP) && defined(FREERTOS) + +struct rtl8139if { + struct netif *netif; /* lwIP network interface */ + struct eth_addr *ethaddr; +}; + +typedef struct +{ + long ident; + union + { + long l; + short i[2]; + char c[4]; + } v; +} COOKIE; + +#ifdef USE_RX_BUFFERS +struct memory +{ + void *mem; +}; +#endif + +struct pci_device_id rtl8139_eth_pci_table[] = { + { RTL8139_VENDOR_ID, RTL8139_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0 } +}; + +/* Forward declarations. */ +static void rtl8139if_input(struct netif *netif, struct pbuf *p); +static err_t rtl8139if_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr); + +static int rtl8139_read_eeprom(void *ioaddr, int location, int addr_len); +static int rtl8139_mdio_read(struct rtl8139_private *rtl_8139, int phy_id, int location); +static void rtl8139_mdio_write(struct rtl8139_private *rtl_8139, int phy_id, int location, int val); + +/* Maximum events (Rx packets, etc.) to handle at each interrupt. */ +static int rtl8139_max_interrupt_work = 10; +static unsigned char rtl8139_ip_addr[2][4]; +static int rtl8139_n_filters; +static unsigned char rtl8139_opened; +static struct rtl8139_private rtl_8139_tp; +extern portBASE_TYPE xNeedSwitchPCI; + +#ifdef USE_RX_BUFFERS + +static void rtl8139_initialize_rx_buffer(struct rtl8139_private *rtl_8139_tp) +{ + struct rx_buffer_t *fifo_rx_buffer = (struct rx_buffer_t *)&rtl_8139_tp->rx_buffer; + struct rx_slot_t *tmp; + int i; + tmp = fifo_rx_buffer->first = fifo_rx_buffer->add = fifo_rx_buffer->extract = nbuf_alloc(sizeof(struct rx_slot_t)); + for(i = 0; i < (MAX_RX_BUFFER_ENTRIES - 1); i++) + { + tmp->next = nbuf_alloc(sizeof(struct rx_slot_t)); + tmp->read = 0x01; + tmp->length = 0; + tmp->data = nbuf_alloc(PKT_BUF_SZ); + tmp = tmp->next; + } + tmp->next = fifo_rx_buffer->first; + tmp->read = 0x01; + tmp->data = nbuf_alloc(PKT_BUF_SZ); +} + +static void rtl8139_dealloc_rx_buffer(struct rtl8139_private *rtl_8139_tp) +{ + struct rx_buffer_t *fifo_rx_buffer = (struct rx_buffer_t *)&rtl_8139_tp->rx_buffer; + struct rx_slot_t *tmp = fifo_rx_buffer->first->next, *actual; + int i; + for(i = 0;i < (MAX_RX_BUFFER_ENTRIES - 1); i++) + { + actual = tmp->next; + if(tmp->data != NULL) + nbuf_free(tmp->data); + nbuf_free(tmp); + tmp = actual; + } + if(fifo_rx_buffer->first->data != NULL) + nbuf_free(fifo_rx_buffer->first->data); + nbuf_free(fifo_rx_buffer->first); +} + +static int rtl8139_add_frame_to_buffer(struct rtl8139_private *rtl_8139_tp, unsigned char *data, int len) +{ + struct rx_buffer_t *fifo_rx_buffer = (struct rx_buffer_t *)&rtl_8139_tp->rx_buffer; + /* If the packet in the position that we're writting hasn't still been read is + because we're receiving too much packets, so we need to drop it. */ + if(fifo_rx_buffer->add->read != 0x00) + { + fifo_rx_buffer->add->length = len; + memcpy(fifo_rx_buffer->add->data,data, len); + fifo_rx_buffer->add->read = 0x00; + fifo_rx_buffer->add = fifo_rx_buffer->add->next; + return(0); + } + /* The packet is dropped */ + return(-1); +} + +static int rtl8139_extract_frame_of_buffer(struct rtl8139_private *rtl_8139_tp, void *data) +{ + struct rx_buffer_t *fifo_rx_buffer = (struct rx_buffer_t *)&rtl_8139_tp->rx_buffer; + struct rx_slot_t *tmp = fifo_rx_buffer->extract; + ((struct memory *)data)->mem = tmp->data; + tmp->read = 0x01; + fifo_rx_buffer->extract = fifo_rx_buffer->extract->next; + return(tmp->length); +} + +#endif /* USE_RX_BUFFERS */ + +int rtl8139_obtain_mac_address(unsigned char *mac) +{ + int i; + for(i = 0; i < 6; i++) + mac[i] = rtl_8139_tp.dev_addr[i]; + return(0); +} + +int rtl8139_set_ip_filter(long ipaddr) +{ + if(rtl8139_n_filters <= 1) + { + rtl8139_ip_addr[rtl8139_n_filters][3] = ipaddr & 0x000000ff; + rtl8139_ip_addr[rtl8139_n_filters][2] = (ipaddr >> 8) & 0x000000ff; + rtl8139_ip_addr[rtl8139_n_filters][1] = (ipaddr >> 16) & 0x000000ff; + rtl8139_ip_addr[rtl8139_n_filters][0] = (ipaddr >> 24) & 0x000000ff; + rtl8139_n_filters++; + return(0); + } + board_printf("RTL8139: You cannot set more than 2 IP filters !!"); + return(-1); +} + +/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the field alignments and semantics. */ +static void rtl8139_rx_interrupt(struct rtl8139_private *rtl_8139_tp) +{ + unsigned char *rx_ring; + unsigned short cur_rx; + unsigned char mine = 1, multicast_packet= 1, arp_request_for_me = 1; + void *ioaddr = rtl_8139_tp->mmio_addr; + int i, j; + rx_ring = rtl_8139_tp->rx_ring; + cur_rx = rtl_8139_tp->cur_rx; + while((RTL_R8(ChipCmd) & RxBufEmpty) == 0) + { + int ring_offset = cur_rx % RX_BUF_LEN; + unsigned long rx_status; + unsigned int rx_size, pkt_size; + unsigned char *skb; + /* read size+status of next frame from DMA ring buffer */ + rx_status = le32_to_cpu(*(unsigned long *)(rx_ring + ring_offset)); + rx_size = rx_status >> 16; + pkt_size = rx_size - 4; + if(rx_size == 0xfff0) + break; + if((rx_size > (MAX_ETH_FRAME_SIZE+4)) || (!(rx_status & RxStatusOK))) + return; + skb = &rx_ring[ring_offset+4]; +#if LINK_STATS + lwip_stats.link.recv++; +#endif + for(i = 0; i < 6; i++) + { + if(skb[i] == rtl_8139_tp->dev_addr[i]) + continue; + else + { + mine = 0; + break; + } + } + if(mine) + goto accept_frame; + if((skb[12] == 0x08) && (skb[13] == 0x06)) + { + for(j = 0; j < rtl8139_n_filters; j++) + { + for(i = 0; i < 4;i++) + { + if(skb[38+i] == rtl8139_ip_addr[j][i]) + continue; + else + { + arp_request_for_me = 0; + break; + } + } + } + } + else + arp_request_for_me = 0; + for(i = 0; i < 6; i++) + { + if(skb[i] == 0xff) + continue; + else + { + multicast_packet = 0; + break; + } + } +accept_frame: + if(mine || (multicast_packet && arp_request_for_me)) + { + extern short OldBoot; +#ifdef USE_RX_BUFFERS + if((rtl8139_add_frame_to_buffer(rtl_8139_tp, skb, pkt_size) == 0) && (rtl_8139_tp->rx_sem != NULL)) + { + if(OldBoot) + xNeedSwitchPCI = pdFALSE; + xNeedSwitchPCI = xSemaphoreGiveFromISR(rtl_8139_tp->rx_sem, xNeedSwitchPCI); + } +#else + if(rtl_8139_tp->rx_queue != NULL) + { + unsigned long msg[2]; + msg[0] = (unsigned long)pkt_size; + msg[1] = (unsigned long)skb; + if(OldBoot) + xNeedSwitchPCI = pdFALSE; + xNeedSwitchPCI = xQueueSendFromISR(rtl_8139_tp->rx_queue, &msg, xNeedSwitchPCI); + } +#endif /* USE_RX_BUFFERS */ + rtl_8139_tp->rx_frames_for_us++; + } + cur_rx = (cur_rx + rx_size + 4 + 3) & ~3; + RTL_W16_F(RxBufPtr, cur_rx - 16); + mine = multicast_packet = arp_request_for_me = 1; + } + rtl_8139_tp->cur_rx = cur_rx; +} + +static void rtl8139_tx_interrupt(struct rtl8139_private *rtl_8139_tp) +{ + void *ioaddr = rtl_8139_tp->mmio_addr; + unsigned long dirty_tx, tx_left; + dirty_tx = rtl_8139_tp->dirty_tx; + tx_left = rtl_8139_tp->cur_tx - dirty_tx; + while(tx_left > 0) + { + int entry = dirty_tx % NUM_TX_DESC; + int txstatus = RTL_R32(TxStatus0 + (entry * sizeof(unsigned long))); + if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted))) + break; /* It still hasn't been Txed */ + /* Note: TxCarrierLost is always asserted at 100mbps. */ + if(txstatus & (TxOutOfWindow | TxAborted)) + { + /* There was an major error, log it. */ +// board_printf("RTL8139: Transmit error, Tx status %8.8x.\r\n", txstatus); +#if LINK_STATS + lwip_stats.link.err++; /* tx error */ +#endif + if(txstatus & TxAborted) + { +#if LINK_STATS +// tx_aborted_errors++; +#endif + RTL_W32(TxConfig, TxClearAbt | (TX_DMA_BURST << TxDMAShift)); + } +#if LINK_STATS +// if(txstatus & TxCarrierLost) +// tx_carrier_errors++; +// if(txstatus & TxOutOfWindow) +// tx_window_errors++; +#if ETHER_STATS +// if((txstatus & 0x0f000000) == 0x0f000000) +// collisions16++; +#endif +#endif + } + else + { + if(txstatus & TxUnderrun) + { + /* Add 64 to the Tx FIFO threshold. */ + if(rtl_8139_tp->tx_flag < 0x00300000) + rtl_8139_tp->tx_flag += 0x00020000; +#if LINK_STATS +// tx_fifo_errors++; +#endif + } +#if LINK_STATS +// collisions += (txstatus >> 24) & 15; + lwip_stats.link.xmit++; +#endif + } + /* Free the original skb. */ + dirty_tx++; + tx_left--; + } +#ifdef RTL8139_DEBUG + if(rtl_8139_tp->cur_tx - dirty_tx > NUM_TX_DESC) + { +// board_printf("RTL8139: Out-of-sync dirty pointer, %ld vs. %ld.\r\n", dirty_tx, rtl_8139_tp->cur_tx); + dirty_tx += NUM_TX_DESC; + } +#endif /* RTL8139_DEBUG */ + /* only wake the queue if we did work, and the queue is stopped */ + if(rtl_8139_tp->dirty_tx != dirty_tx) + rtl_8139_tp->dirty_tx = dirty_tx; +} + +/* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ +int rtl8139_interrupt(struct rtl8139_private *rtl_8139_tp) +{ + int boguscnt = rtl8139_max_interrupt_work; + void *ioaddr = rtl_8139_tp->mmio_addr; + int status = 0, link_changed = 0; /* avoid bogus "uninit" warning */ + do + { + if(rtl_8139_tp->ctpci_dma_lock != NULL) + { + int i = 0; + while((i <= 100) && rtl_8139_tp->ctpci_dma_lock(1)) + { + udelay(1); /* try to fix CTPCI freezes */ + i++; + } + } + status = RTL_R16(IntrStatus); + /* h/w no longer present (hotplug?) or major error, bail */ + if(status == 0xFFFF) + { + if(rtl_8139_tp->ctpci_dma_lock != NULL) + rtl_8139_tp->ctpci_dma_lock(0); + break; + } + /* Acknowledge all of the current interrupt sources ASAP, but an first get an additional status bit from CSCR. */ + if(status & RxUnderrun) + link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit; + RTL_W16_F(IntrStatus, (status & RxFIFOOver) ? (status | RxOverflow) : status); + if((status & (PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK)) == 0) + { + if(rtl_8139_tp->ctpci_dma_lock != NULL) + rtl_8139_tp->ctpci_dma_lock(0); + break; + } + if(status & (RxOK | RxUnderrun | RxOverflow | RxFIFOOver)) + rtl8139_rx_interrupt(rtl_8139_tp); + if(status & (TxOK | TxErr)) + rtl8139_tx_interrupt(rtl_8139_tp); + if(rtl_8139_tp->ctpci_dma_lock != NULL) + rtl_8139_tp->ctpci_dma_lock(0); + boguscnt--; + } + while(boguscnt > 0); + if((status != 0xFFFF) && (status & PCIErr)) + { +#ifdef PCI_XBIOS + short sr = fast_read_config_word(rtl_8139_tp->handle, PCISR); + write_config_word(rtl_8139_tp->handle, PCISR, sr); +#else + short sr = Fast_read_config_word(rtl_8139_tp->handle, PCISR); + Write_config_word(rtl_8139_tp->handle, PCISR, sr); +#endif +// board_printf("RTL8139: PCI ERROR SR %#04x\r\n", sr); + } + if(boguscnt <= 0) + { +// board_printf("RTL8139: Too much work at interrupt, IntrStatus=0x%4.4x.\r\n", status); + /* Clear all interrupt sources. */ + RTL_W16(IntrStatus, 0xffff); + } + return(1); +} + +/* Syncronize the MII management interface by shifting 32 one bits out. */ +static void rtl8139_mdio_sync(void *mdio_addr) +{ + int i; + for(i = 32; i >= 0; i--) + { + writeb(MDIO_WRITE1, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + writeb(MDIO_WRITE1 | MDIO_CLK, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + } +} + +static int rtl8139_mdio_read(struct rtl8139_private *rtl_8139_tp, int phy_id, int location) +{ + void *mdio_addr = (void *)((unsigned long)rtl_8139_tp->mmio_addr + Config4); + int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location; + int retval = 0; + int i; + if(phy_id > 31) + /* Really a 8139. Use internal registers. */ + return location < 8 && mii_2_8139_map[location] ? readw((unsigned long)rtl_8139_tp->mmio_addr + mii_2_8139_map[location]) : 0; + rtl8139_mdio_sync(mdio_addr); + /* Shift the read command bits out. */ + for(i = 15; i >= 0; i--) + { + int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0; + writeb(MDIO_DIR | dataval, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + writeb(MDIO_DIR | dataval | MDIO_CLK, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + } + /* Read the two transition, 16 data, and wire-idle bits. */ + for(i = 19; i > 0; i--) + { + writeb(0, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + retval = (retval << 1) | ((readb((unsigned long)mdio_addr) & MDIO_DATA_IN) ? 1 : 0); + writeb(MDIO_CLK, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + } + return((retval >> 1) & 0xffff); +} + +static void rtl8139_mdio_write(struct rtl8139_private *rtl_8139_tp, int phy_id, int location, int value) +{ + void *mdio_addr = (void *)((unsigned long)rtl_8139_tp->mmio_addr + Config4); + int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value; + int i; + if(phy_id > 31) + { /* Really a 8139. Use internal registers. */ + void *ioaddr = rtl_8139_tp->mmio_addr; + if(location == 0) + { + RTL_W8_F(Cfg9346, Cfg9346_Unlock); + switch(rtl_8139_tp->AutoNegoAbility) + { + case 1: RTL_W16(NWayAdvert, AutoNegoAbility10half); break; + case 2: RTL_W16(NWayAdvert, AutoNegoAbility10full); break; + case 4: RTL_W16(NWayAdvert, AutoNegoAbility100half); break; + case 8: RTL_W16(NWayAdvert, AutoNegoAbility100full); break; + default: break; + } + RTL_W16_F(BasicModeCtrl, AutoNegotiationEnable|AutoNegotiationRestart); + RTL_W8_F(Cfg9346, Cfg9346_Lock); + } + else if(location < 8 && mii_2_8139_map[location]) + RTL_W16_F(mii_2_8139_map[location], value); + } + else + { + rtl8139_mdio_sync(mdio_addr); + /* Shift the command bits out. */ + for(i = 31; i >= 0; i--) + { + int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0; + writeb(dataval, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + writeb(dataval | MDIO_CLK, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + } + /* Clear out extra bits. */ + for(i = 2; i > 0; i--) + { + writeb(0, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + writeb(MDIO_CLK, mdio_addr); + rtl8139_mdio_delay(mdio_addr); + } + } +} + +/* Serial EEPROM section. */ + +/* EEPROM_Ctrl bits. */ +#define EE_SHIFT_CLK 0x04 /* EEPROM shift clock. */ +#define EE_CS 0x08 /* EEPROM chip select. */ +#define EE_DATA_WRITE 0x02 /* EEPROM chip data in. */ +#define EE_WRITE_0 0x00 +#define EE_WRITE_1 0x02 +#define EE_DATA_READ 0x01 /* EEPROM chip data out. */ +#define EE_ENB (0x80 | EE_CS) + +/* Delay between EEPROM clock transitions. + No extra delay is needed with 33Mhz PCI, but 66Mhz may change this. + */ + +#define rtl8139_eeprom_delay() readl(ee_addr) + +/* The EEPROM commands include the alway-set leading bit. */ +#define EE_WRITE_CMD (5) +#define EE_READ_CMD (6) +#define EE_ERASE_CMD (7) + +static int rtl8139_read_eeprom(void *ioaddr, int location, int addr_len) +{ + int i; + unsigned retval = 0; + void *ee_addr = (void *)((unsigned long)ioaddr + Cfg9346); + int read_cmd = location | (EE_READ_CMD << addr_len); + writeb(EE_ENB & ~EE_CS, ee_addr); + writeb(EE_ENB, ee_addr); + rtl8139_eeprom_delay(); + /* Shift the read command bits out. */ + for(i = 4 + addr_len; i >= 0; i--) + { + int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0; + writeb(EE_ENB | dataval, ee_addr); + rtl8139_eeprom_delay(); + writeb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr); + rtl8139_eeprom_delay(); + } + writeb(EE_ENB, ee_addr); + rtl8139_eeprom_delay(); + for(i = 16; i > 0; i--) + { + writeb(EE_ENB | EE_SHIFT_CLK, ee_addr); + rtl8139_eeprom_delay(); + retval = (retval << 1) | ((readb(ee_addr) & EE_DATA_READ) ? 1 : 0); + writeb(EE_ENB, ee_addr); + rtl8139_eeprom_delay(); + } + /* Terminate the EEPROM access. */ + writeb(~EE_CS, ee_addr); + rtl8139_eeprom_delay(); + return(retval); +} + +/* Start the hardware at open or resume. */ +static void rtl8139_hw_start(struct rtl8139_private *rtl_8139_tp) +{ + void *ioaddr = rtl_8139_tp->mmio_addr; + unsigned long i; + unsigned char tmp; + int rx_mode; + /* Soft reset the chip. */ + RTL_W8(ChipCmd, (RTL_R8(ChipCmd) & ChipCmdClear) | CmdReset); + vTaskDelay((100*configTICK_RATE_HZ)/1000); + /* Check that the chip has finished the reset. */ + for(i = 1000; i > 0; i--) + { + if((RTL_R8(ChipCmd) & CmdReset) == 0) + break; + } + /* unlock Config[01234] and BMCR register writes */ + RTL_W8_F(Cfg9346, Cfg9346_Unlock); + /* Restore our idea of the MAC address. */ + RTL_W32_F(MAC0 + 0, cpu_to_le32(*(unsigned long *)(rtl_8139_tp->dev_addr + 0))); + RTL_W32_F(MAC0 + 4, cpu_to_le32(*(unsigned long *)(rtl_8139_tp->dev_addr + 4))); + /* Must enable Tx/Rx before setting transfer thresholds! */ + RTL_W8_F(ChipCmd, (RTL_R8(ChipCmd) & ChipCmdClear) | CmdRxEnb | CmdTxEnb); + RTL_W32_F(RxConfig, rtl8139_rx_config | (RTL_R32(RxConfig) & rtl_chip_info[rtl_8139_tp->chipset].RxConfigMask)); + /* Check this value: the documentation for IFG contradicts ifself. */ + RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift)); + rtl_8139_tp->cur_rx = 0; + /* This is check_duplex() */ + if((rtl_8139_tp->phys[0] >= 0) || (rtl_8139_tp->drv_flags & HAS_MII_XCVR)) + { + unsigned short mii_reg5 = rtl8139_mdio_read(rtl_8139_tp, rtl_8139_tp->phys[0], 5); + if(mii_reg5 == 0xffff); /* Not there */ + else if(((mii_reg5 & 0x0100) == 0x0100) || ((mii_reg5 & 0x00C0) == 0x0040)) + rtl_8139_tp->full_duplex = 1; + board_printf("RTL8139: Setting %s%s-duplex based on auto-negotiated partner ability %4.4x.\r\n", mii_reg5 == 0 ? "" : + (mii_reg5 & 0x0180) ? "100mbps " : "10mbps ", rtl_8139_tp->full_duplex ? "full" : "half", mii_reg5); + } + if(rtl_8139_tp->chipset >= CH_8139A) + { + tmp = RTL_R8(Config1) & Config1Clear; + tmp |= Cfg1_Driver_Load; + tmp |= (rtl_8139_tp->chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */ + RTL_W8_F(Config1, tmp); + } + else + { + unsigned char foo = RTL_R8(Config1) & Config1Clear; + RTL_W8(Config1, rtl_8139_tp->full_duplex ? (foo|0x60) : (foo|0x20)); + } + if(rtl_8139_tp->chipset >= CH_8139B) + { + tmp = RTL_R8(Config4) & ~(1<<2); + /* chip will clear Rx FIFO overflow automatically */ + tmp |= (1<<7); + RTL_W8(Config4, tmp); + /* disable magic packet scanning, which is enabled when PM is enabled above (Config1) */ + RTL_W8(Config3, RTL_R8(Config3) & ~(1<<5)); + } + /* Lock Config[01234] and BMCR register writes */ + RTL_W8_F(Cfg9346, Cfg9346_Lock); + vTaskDelay((10*configTICK_RATE_HZ)/1000); + /* init Rx ring buffer DMA address */ + RTL_W32_F(RxBuf, rtl_8139_tp->rx_ring_dma); + /* init Tx buffer DMA addresses */ + for(i = 0; i < NUM_TX_DESC; i++) + RTL_W32_F(TxAddr0 + (i * 4), rtl_8139_tp->tx_bufs_dma + (rtl_8139_tp->tx_buf[i] - rtl_8139_tp->tx_bufs)); + RTL_W32_F(RxMissed, 0); + /* Set rx mode */ + rx_mode = AcceptBroadcast | AcceptMyPhys | AcceptAllPhys; + /* We can safely update without stopping the chip. */ + RTL_W32_F(RxConfig, rtl8139_rx_config | rx_mode | (RTL_R32(RxConfig) & rtl_chip_info[rtl_8139_tp->chipset].RxConfigMask)); + /* no early-rx interrupts */ + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & MultiIntrClear); + /* make sure RxTx has started */ + RTL_W8_F(ChipCmd, (RTL_R8(ChipCmd) & ChipCmdClear) | CmdRxEnb | CmdTxEnb); + /* Enable all known interrupts by setting the interrupt mask. */ + RTL_W16_F(IntrMask, rtl8139_intr_mask); + rtl_8139_tp->trans_start = jiffies; +} + +static void rtl8129_tx_timeout(struct rtl8139_private *rtl_8139_tp) +{ + void *ioaddr = rtl_8139_tp->mmio_addr; + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16(IntrMask, 0x0000); + rtl_8139_tp->dirty_tx = rtl_8139_tp->cur_tx = 0; + rtl8139_hw_start(rtl_8139_tp); +} + +static int rtl8139_send_packet(const char *buffer, size_t size) +{ + void *ioaddr = rtl_8139_tp.mmio_addr; + unsigned char *buff; + int entry; + if((rtl_8139_tp.cur_tx - rtl_8139_tp.dirty_tx) >= NUM_TX_DESC) + { + if((jiffies - rtl_8139_tp.trans_start) > TX_TIMEOUT) + rtl8129_tx_timeout(&rtl_8139_tp); /* timeout */ + else + return(0); + } + vPortEnterCritical(); + if((rtl_8139_tp.ctpci_dma_lock != NULL) && rtl_8139_tp.ctpci_dma_lock(1)) + { + vPortExitCritical(); + return(0); + } + /* Calculate the next Tx descriptor entry. */ + entry = rtl_8139_tp.cur_tx % NUM_TX_DESC; + buff = rtl_8139_tp.tx_buf[entry]; + if(buff != NULL) + memcpy(buff, buffer, size); + RTL_W32(TxAddr0 + (entry * 4), rtl_8139_tp.tx_buf[entry]); + rtl_8139_tp.cur_tx++; + /* Note: the chip doesn't have auto-pad! */ + RTL_W32(TxStatus0 + (entry * sizeof(unsigned long)), rtl_8139_tp.tx_flag | (size >= ETH_ZLEN ? size : ETH_ZLEN)); + rtl_8139_tp.trans_start = jiffies; + if(rtl_8139_tp.ctpci_dma_lock != NULL) + rtl_8139_tp.ctpci_dma_lock(0); + vPortExitCritical(); + return(size); +} + +unsigned long rtl8139_read_timer(void) +{ + void *ioaddr = rtl_8139_tp.mmio_addr; + return(RTL_R32(Timer)); +} + +#ifndef PCI_XBIOS +static COOKIE *get_cookie(long id) +{ + COOKIE *p= *(COOKIE **)0x5a0; + while(p) + { + if(p->ident == id) + return(p); + if(!p->ident) + return((COOKIE *)0); + p++; + } + return((COOKIE *)0); +} +#endif + +err_t rtl8139_eth_start(long handle, const struct pci_device_id *ent) +{ + unsigned long pio_start = 0, pio_len = 0; + unsigned long pio_base_addr = 0xFFFFFFFF; + unsigned long mmio_start = 0, mmio_len = 0, dma_offset = 0; + unsigned long mmio_base_addr = 0xFFFFFFFF; + PCI_RSC_DESC *pci_rsc_desc; + unsigned char tmp8; + int i, option, addr_len; + static int board_idx = 0; + unsigned long tmp; + void *ioaddr = NULL; +#ifdef PCI_XBIOS + pci_rsc_desc = (PCI_RSC_DESC *)get_resource(handle); +#else + COOKIE *p = get_cookie('_PCI'); + PCI_COOKIE *bios_cookie = (PCI_COOKIE *)p->v.l; + if(bios_cookie == NULL) /* faster than XBIOS calls */ + return(-1); + tab_funcs_pci = &bios_cookie->routine[0]; + pci_rsc_desc = (PCI_RSC_DESC *)Get_resource(handle); +#endif + if((long)pci_rsc_desc >= 0) + { + unsigned short flags; + do + { +// board_printf("RTL8139: PCI descriptors: flags 0x%04x start 0x%08lx \r\n offset 0x%08lx dmaoffset 0x%08lx length 0x%08lx", +// pci_rsc_desc->flags, pci_rsc_desc->start, pci_rsc_desc->offset, pci_rsc_desc->dmaoffset, pci_rsc_desc->length); + if(!(pci_rsc_desc->flags & FLG_IO)) + { + if(mmio_base_addr == 0xFFFFFFFF) + { + mmio_base_addr = pci_rsc_desc->start; + mmio_start = pci_rsc_desc->offset + pci_rsc_desc->start; + mmio_len = pci_rsc_desc->length; + dma_offset = pci_rsc_desc->dmaoffset; + } + } + else + { + if(pio_base_addr == 0xFFFFFFFF) + { + pio_base_addr = pci_rsc_desc->start; + pio_start = pci_rsc_desc->offset + pci_rsc_desc->start; + pio_len = pci_rsc_desc->length; + } + } + flags = pci_rsc_desc->flags; + pci_rsc_desc = (PCI_RSC_DESC *)((unsigned long)pci_rsc_desc->next + (unsigned long)pci_rsc_desc); + } + while(!(flags & FLG_LAST)); + } + if((pio_base_addr == 0xFFFFFFFF) || (mmio_base_addr == 0xFFFFFFFF)) + return(-1); + ioaddr = (void *)mmio_start; + memset(&rtl_8139_tp, 0, sizeof(struct rtl8139_private)); + rtl_8139_tp.handle = handle; + rtl_8139_tp.mmio_len = mmio_len; + /* set this immediately, we need to know before we talk to the chip directly */ + if(pio_len == RTL8139B_IO_SIZE) + rtl_8139_tp.chipset = CH_8139B; + /* check for weird/broken PCI region reporting */ + if((pio_len < RTL_MIN_IO_SIZE) || (mmio_len < RTL_MIN_IO_SIZE)) + { + board_printf("RTL8139: Invalid PCI region size(s), aborting\r\n"); + return(-1); + } + nbuf_init(); +#ifdef USE_RX_BUFFERS + rtl8139_initialize_rx_buffer(&rtl_8139_tp); +#endif + tmp = dma_lock(-1); /* CTPCI */ + if((tmp == 0) || (tmp == 1)) + rtl_8139_tp.ctpci_dma_lock = (void *)dma_lock(-2); /* function exist */ + /* Soft reset the chip. */ + RTL_W8(ChipCmd, (RTL_R8(ChipCmd) & ChipCmdClear) | CmdReset); + /* Check that the chip has finished the reset. */ + for(i = 1000; i > 0; i--) + { + if((RTL_R8(ChipCmd) & CmdReset) == 0) + break; + else + udelay(10); + } + /* Bring the chip out of low-power mode. */ + if(rtl_8139_tp.chipset == CH_8139B) + { + RTL_W8(Config1, RTL_R8(Config1) & ~(1<<4)); + RTL_W8(Config4, RTL_R8(Config4) & ~(1<<2)); + } + else + { + /* handle RTL8139A and RTL8139 cases */ + /* XXX from becker driver. is this right?? */ + RTL_W8(Config1, 0); + } + /* make sure chip thinks PIO and MMIO are enabled */ + tmp8 = RTL_R8(Config1); + if((tmp8 & Cfg1_PIO) == 0) + { + board_printf("RTL8139: PIO not enabled, Cfg1=%02X, aborting\r\n", tmp8); + return(-1); + } + if((tmp8 & Cfg1_MMIO) == 0) + { + board_printf("RTL8139: MMIO not enabled, Cfg1=%02X, aborting\r\n", tmp8); + return(-1); + } + /* identify chip attached to board */ + /* tmp = RTL_R8(ChipVersion); */ + tmp = RTL_R32(TxConfig); + tmp = ((tmp & 0x7c000000) + ((tmp & 0x00800000) << 2)) >>24; + rtl_8139_tp.drv_flags = board_info[0].hw_flags; + rtl_8139_tp.mmio_addr = ioaddr; + for(i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) + { + if(tmp == rtl_chip_info[i].version) + rtl_8139_tp.chipset = i; + } + if(rtl_8139_tp.chipset > (ARRAY_SIZE(rtl_chip_info) - 2)) + rtl_8139_tp.chipset = ARRAY_SIZE(rtl_chip_info) - 2; + /* Find the connected MII xcvrs. */ + if(rtl_8139_tp.drv_flags & HAS_MII_XCVR) + { + int phy, phy_idx = 0; + for(phy = 0; phy < 32 && phy_idx < sizeof(rtl_8139_tp.phys); phy++) + { + int mii_status = rtl8139_mdio_read(&rtl_8139_tp, phy, 1); + if(mii_status != 0xffff && mii_status != 0x0000) + { + rtl_8139_tp.phys[phy_idx++] = phy; + rtl_8139_tp.advertising = rtl8139_mdio_read(&rtl_8139_tp, phy, 4); + board_printf("RTL8139: MII transceiver %d status 0x%4.4x advertising %4.4x.\r\n", phy, mii_status, rtl_8139_tp.advertising); + } + } + if(phy_idx == 0) + { + board_printf("RTL8139: No MII transceivers found! Assuming SYM transceiver.\r\n"); + rtl_8139_tp.phys[0] = 32; + } + } + else + rtl_8139_tp.phys[0] = 32; + /* Put the chip into low-power mode. */ + RTL_W8_F(Cfg9346, Cfg9346_Unlock); + tmp = RTL_R8(Config1) & Config1Clear; + tmp |= (rtl_8139_tp.chipset == CH_8139B) ? 3 : 1; /* Enable PM/VPD */ + RTL_W8_F(Config1, tmp); + RTL_W8_F(HltClk, 'H'); /* 'R' would leave the clock running. */ + /* The lower four bits are the media type. */ + option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx]; + rtl_8139_tp.AutoNegoAbility = option&0xF; + if(option > 0) + { + rtl_8139_tp.full_duplex = (option & 0x210) ? 1 : 0; + rtl_8139_tp.default_port = option & 0xFF; + if(rtl_8139_tp.default_port) + rtl_8139_tp.medialock = 1; + } + if(board_idx < MAX_UNITS && full_duplex[board_idx] > 0) + rtl_8139_tp.full_duplex = full_duplex[board_idx]; + if(rtl_8139_tp.full_duplex) + { + board_printf("RTL8139: Media type forced to Full Duplex.\r\n"); + /* Changing the MII-advertised media because might prevent re-connection. */ + rtl_8139_tp.duplex_lock = 1; + } + if(rtl_8139_tp.default_port) + { + board_printf("RTL8139: Forcing %dMbs %s-duplex operation.\r\n", (option & 0x0C ? 100 : 10), (option & 0x0A ? "full" : "half")); + rtl8139_mdio_write(&rtl_8139_tp, rtl_8139_tp.phys[0], 0, ((option & 0x20) ? 0x2000 : 0) | /* 100mbps? */ ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */ + } + addr_len = rtl8139_read_eeprom(ioaddr, 0, 8) == 0x8129 ? 8 : 6; + for(i = 0; i < 3; ((unsigned short *)(rtl_8139_tp.dev_addr))[i] = le16_to_cpu(rtl8139_read_eeprom(ioaddr, i + 7, addr_len)), i++); + board_printf("RTL8139: %s at 0x%lx, %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\r\n", board_info[0].name, rtl_8139_tp.mmio_addr, + rtl_8139_tp.dev_addr[0], rtl_8139_tp.dev_addr[1], rtl_8139_tp.dev_addr[2], rtl_8139_tp.dev_addr[3], rtl_8139_tp.dev_addr[4], rtl_8139_tp.dev_addr[5]); +#ifdef PCI_XBIOS + hook_interrupt(handle, rtl8139_interrupt, &rtl_8139_tp); +#else + Hook_interrupt(handle, (void *)rtl8139_interrupt, (unsigned long *)&rtl_8139_tp); +#endif /* PCI_BIOS */ + rtl_8139_tp.must_free_irq = 1; + rtl_8139_tp.tx_bufs = nbuf_alloc(TX_BUF_TOT_LEN); + rtl_8139_tp.rx_ring = nbuf_alloc(RX_BUF_TOT_LEN); + if((rtl_8139_tp.tx_bufs == NULL) || (rtl_8139_tp.rx_ring == NULL)) + { +#ifdef PCI_XBIOS + unhook_interrupt(handle); +#else + Unhook_interrupt(handle); +#endif /* PCI_BIOS */ + if(rtl_8139_tp.tx_bufs) + nbuf_free(rtl_8139_tp.tx_bufs); + if(rtl_8139_tp.rx_ring) + nbuf_free(rtl_8139_tp.rx_ring); + board_printf("RTL8139: EXIT, out of memory\r\n"); + return(-1); + } + /* board_printf("RTL8139: TX buffers at %#lx, RX buffers at %#lx, DMA offset %#lx\r\n", rtl_8139_tp.tx_bufs, rtl_8139_tp.rx_ring, dma_offset); */ + rtl_8139_tp.tx_bufs_dma = (unsigned long)rtl_8139_tp.tx_bufs - dma_offset; + rtl_8139_tp.rx_ring_dma = (unsigned long)rtl_8139_tp.rx_ring - dma_offset; + rtl_8139_tp.full_duplex = rtl_8139_tp.duplex_lock; + rtl_8139_tp.tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000; + rtl_8139_tp.twistie = 1; +/* Initialize the Rx and Tx rings */ + rtl_8139_tp.cur_rx = 0; + rtl_8139_tp.cur_tx = 0; + rtl_8139_tp.dirty_tx = 0; + for(i = 0; i < NUM_TX_DESC; i++) + rtl_8139_tp.tx_buf[i] = &rtl_8139_tp.tx_bufs[i * TX_BUF_SIZE]; + rtl8139_hw_start(&rtl_8139_tp); + board_printf("RTL8139: ioaddr %#lx handle %#lx %s-duplex.\r\n", mmio_start, handle, rtl_8139_tp.full_duplex ? "full" : "half"); + rtl8139_opened = 1; + return(0); +} + +void rtl8139_eth_stop(void) +{ + void *ioaddr = rtl_8139_tp.mmio_addr; + vPortEnterCritical(); + /* Stop the chip's Tx and Rx DMA processes. */ + RTL_W8(ChipCmd, (RTL_R8(ChipCmd) & ChipCmdClear)); + /* Disable interrupts by clearing the interrupt mask. */ + RTL_W16(IntrMask, 0x0000); + RTL_W32(RxMissed, 0); + if(rtl_8139_tp.must_free_irq) + { +#ifdef PCI_XBIOS + unhook_interrupt(rtl_8139_tp.handle); +#else + Unhook_interrupt(rtl_8139_tp.handle); +#endif /* PCI_BIOS */ + rtl_8139_tp.must_free_irq = 0; + } + rtl_8139_tp.cur_tx = 0; + rtl_8139_tp.dirty_tx = 0; + if(rtl_8139_tp.rx_ring != NULL) + { + nbuf_free(rtl_8139_tp.rx_ring); + rtl_8139_tp.rx_ring = NULL; + } + if(rtl_8139_tp.tx_bufs != NULL) + { + nbuf_free(rtl_8139_tp.tx_bufs); + rtl_8139_tp.tx_bufs = NULL; + } + /* Green! Put the chip in low-power mode. */ + RTL_W8(Cfg9346, Cfg9346_Unlock); + RTL_W8(Config1, 0x03); + RTL_W8(HltClk, 'H'); /* 'R' would leave the clock running. */ + vPortExitCritical(); + if(rtl_8139_tp.task != NULL) + { + sys_arch_thread_remove(rtl_8139_tp.task); + rtl_8139_tp.task = NULL; + } + if(rtl_8139_tp.tx_sem != NULL) + { + vQueueDelete((xQueueHandle)rtl_8139_tp.tx_sem); + rtl_8139_tp.tx_sem = NULL; + } +#ifdef USE_RX_BUFFERS + if(rtl_8139_tp.rx_sem != NULL) + { + vQueueDelete((xQueueHandle)rtl_8139_tp.rx_sem); + rtl_8139_tp.rx_sem = NULL; + } + if(rtl8139_opened) + rtl8139_dealloc_rx_buffer(&rtl_8139_tp); +#else + if(rtl_8139_tp.rx_queue != NULL) + { + vQueueDelete(rtl_8139_tp.rx_queue); + rtl_8139_tp.rx_queue = NULL; + } +#endif /* USE_RX_BUFFERS */ + if(rtl_8139_tp.rtl8139if != NULL) + { + mem_free(rtl_8139_tp.rtl8139if); + rtl_8139_tp.rtl8139if = NULL; + } + rtl8139_opened = 0; +} + +/*-----------------------------------------------------------------------------------*/ +/* + * rtl8139if_low_level_output(): + * + * Should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + */ +/*-----------------------------------------------------------------------------------*/ +err_t rtl8139if_low_level_output(struct netif *rtl8139if, struct pbuf *p) +{ + struct pbuf *q; + static unsigned char buf[PKT_BUF_SZ]; + unsigned char *bufptr; +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + while(xSemaphoreAltTake(rtl_8139_tp.tx_sem, portMAX_DELAY) != pdTRUE); + /* initiate transfer */ + bufptr = buf; + for(q = p; q != NULL; q = q->next) + { + /* Send the data from the pbuf to the interface, one pbuf at a time. The size of the data in each pbuf is kept in the ->len variable. */ + memcpy(bufptr, q->payload, q->len); + bufptr += q->len; + } + /* signal that packet should be sent */ + while(rtl8139_send_packet((const char *)buf,p->tot_len) == 0); + xSemaphoreAltGive(rtl_8139_tp.tx_sem); +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); +#endif + return(ERR_OK); +} + +/*-----------------------------------------------------------------------------------*/ +/* + * rtl8139if_input(): + * + * This function should be called when a packet is ready to be read + * from the interface. It uses the function rtl8139if_low_level_input() that + * should handle the actual reception of bytes from the network + * interface. + * + */ +/*-----------------------------------------------------------------------------------*/ +static void rtl8139if_input(struct netif *netif, struct pbuf *p) +{ + struct eth_hdr *eth_hdr = p->payload; + LWIP_ASSERT("eth_input: p != NULL ", p != NULL); + switch(htons(eth_hdr->type)) + { + case ETHTYPE_IP: + /* Pass to ARP layer. */ + etharp_ip_input(netif, p); + /* Skip Ethernet header. */ + pbuf_header(p, (s16_t) - sizeof(struct eth_hdr)); + /* Pass to network layer. */ + netif->input(p, netif); + break; + case ETHTYPE_ARP: + /* Pass to ARP layer. */ + etharp_arp_input(netif, (struct eth_addr *)netif->hwaddr, p); + break; + default: + pbuf_free(p); + break; + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + * rtl8139_rx_task(): + * + * Receive Frame interrupt task. + * + */ +/*-----------------------------------------------------------------------------------*/ +static void rtl8139_rx_task(void *arg) +{ + struct rtl8139if *rtl8139if = (struct rtl8139if *)arg; + struct pbuf *p, *q; +#ifdef USE_RX_BUFFERS + struct memory receive_buffer; +#else + unsigned long msg[2]; +#endif + unsigned char *bufptr; + u16_t len; + while(1) + { + /* Obtain the size of the packet and put it into the "len" variable. */ +#ifdef USE_RX_BUFFERS + while(xSemaphoreAltTake(rtl_8139_tp.rx_sem, portMAX_DELAY) != pdTRUE); + len = (u16_t)rtl8139_extract_frame_of_buffer(&rtl_8139_tp, &receive_buffer); +#else + while(xQueueAltReceive(rtl_8139_tp.rx_queue, &msg, portMAX_DELAY) != pdPASS); + len = (u16_t)msg[0]; +#endif /* USE_RX_BUFFERS */ + /* We allocate a pbuf chain of pbufs from the pool. */ + p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL); + if(p != NULL) + { +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); +#endif + /* We iterate over the pbuf chain until we have read the entire packet into the pbuf. */ +#ifdef USE_RX_BUFFERS + bufptr = receive_buffer.mem; +#else + bufptr = (unsigned char *)msg[1]; +#endif /* USE_RX_BUFFERS */ + for(q = p; q != NULL; q = q->next) + { + /* Read enough bytes to fill this pbuf in the chain. The avaliable data in the pbuf is given by the q->len variable. */ + memcpy(q->payload, bufptr, q->len); + bufptr += q->len; + } +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); +#endif + /* Ethernet frame received. Handling it is not device dependent and therefore done in another function */ + rtl8139if_input(rtl8139if->netif, p); + } + else + board_printf("RTL8139: pbuf_alloc out of memory!!!\r\n"); + } +} +/*-----------------------------------------------------------------------------------*/ +/* + * rtl8139if_output(): + * + * This function is called by the TCP/IP stack when an IP packet + * should be sent. It calls the function called rtl8139if_low_level_output() to + * do the actuall transmission of the packet. + * + */ +/*-----------------------------------------------------------------------------------*/ +static err_t rtl8139if_output(struct netif *netif, struct pbuf *p, struct ip_addr *ipaddr) +{ + return(etharp_output(netif, ipaddr, p)); +} + +/*-----------------------------------------------------------------------------------*/ +void rtl8139_ifetharp_timer(int signo) +{ + etharp_tmr(); + sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)rtl8139_ifetharp_timer, NULL); +} + +/*-----------------------------------------------------------------------------------*/ +/* + * rtl8139if_init(): + * + * Should be called at the beginning of the program to set up the + * network interface. It calls the function rtl8139if_low_level_init() to do the + * actual setup of the hardware. + * + */ +/*-----------------------------------------------------------------------------------*/ +err_t rtl8139if_init(struct netif *netif) +{ + struct rtl8139if *rtl8139if; + if(!rtl8139_opened) /* rtl8139_eth_start called before by the PCI scan */ + return(ERR_MEM); + rtl_8139_tp.rtl8139if = rtl8139if = mem_malloc(sizeof(struct rtl8139if)); + if(rtl8139if == NULL) + { + rtl8139_eth_stop(); + return(ERR_MEM); + } + rtl8139if->netif = netif; + netif->state = rtl8139if; + netif->name[0] = 'e'; + netif->name[1] = 'n'; + netif->hwaddr_len = ETH_ADDR_LEN; + netif->mtu = RTL_MTU; + netif->flags = NETIF_FLAG_BROADCAST; + netif->output = rtl8139if_output; + netif->linkoutput = rtl8139if_low_level_output; + rtl8139if->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); + netif->hwaddr_len = 6; + /* Obtain MAC address from network interface. */ + rtl8139_obtain_mac_address(rtl8139if->ethaddr->addr); + /* We set an IP filter to the ethernet card */ + rtl8139_set_ip_filter(netif->ip_addr.addr); +// board_printf("RTL8139: MAC %x:%x:%x:%x:%x:%x \r\n",rtl8139if->ethaddr->addr[0],rtl8139if->ethaddr->addr[1],rtl8139if->ethaddr->addr[2],rtl8139if->ethaddr->addr[3],rtl8139if->ethaddr->addr[4],rtl8139if->ethaddr->addr[5]); + /* Create RX semaphore */ + vSemaphoreCreateBinary(rtl_8139_tp.tx_sem); +#ifdef USE_RX_BUFFERS + /* Create RX semaphore */ + vSemaphoreCreateBinary(rtl_8139_tp.rx_sem); + if((rtl_8139_tp.tx_sem != NULL) && (rtl_8139_tp.rx_sem != NULL)) + { + xSemaphoreAltTake(rtl_8139_tp.rx_sem, 1); +#else + if((rtl_8139_tp.tx_sem != NULL) && (rtl_8139_tp.rx_queue = xQueueCreate(64, sizeof(unsigned long) * 2)) != NULL) + { +#endif /* USE_RX_BUFFERS */ + rtl_8139_tp.task = sys_thread_new(rtl8139_rx_task, rtl8139if, TASK_PRIORITY); + if(rtl_8139_tp.task == NULL) + { + rtl8139_eth_stop(); + return(ERR_MEM); + } + } + else + { + rtl8139_eth_stop(); + return(ERR_MEM); + } + etharp_init(); + sys_timeout(ARP_TMR_INTERVAL, (sys_timeout_handler)rtl8139_ifetharp_timer, NULL); + rtl8139_opened = 2; + return(ERR_OK); +} + +/*-----------------------------------------------------------------------------------*/ +void rtl8139if_close(void) +{ + /* Closing the RTL8139 card */ + rtl8139_eth_stop(); +} + +#endif /* defined(LWIP) && defined(FREERTOS) */ + diff --git a/flash.tos/drivers/lwip/rtl8139.h b/flash.tos/drivers/lwip/rtl8139.h new file mode 100644 index 0000000..e7fb770 --- /dev/null +++ b/flash.tos/drivers/lwip/rtl8139.h @@ -0,0 +1,616 @@ +/* + * Copyright (c) 2001, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + A RealTek RTL-8139 Fast Ethernet driver for Linux. + + Maintained by Jeff Garzik + Copyright 2000,2001 Jeff Garzik + + Much code comes from Donald Becker's rtl8139.c driver, + versions 1.13 and older. This driver was originally based + on rtl8139.c version 1.07. Header of rtl8139.c version 1.13: + + ---------- + + Written 1997-2001 by Donald Becker. + This software may be used and distributed according to the + terms of the GNU General Public License (GPL), incorporated + herein by reference. Drivers based on or derived from this + code fall under the GPL and must retain the authorship, + copyright and license notice. This file is not a complete + program and may only be used when the entire operating + system is licensed under the GPL. + + This driver is for boards based on the RTL8129 and RTL8139 + PCI ethernet chips. + + The author may be reached as becker@scyld.com, or C/O Scyld + Computing Corporation 410 Severn Ave., Suite 210 Annapolis + MD 21403 + + Support and updates available at + http://www.scyld.com/network/rtl8139.html + + Twister-tuning table provided by Kinston + . + + ---------- + This software may be used and distributed according to the terms + of the GNU General Public License, incorporated herein by reference. + + Contributors: + + Donald Becker - he wrote the original driver, kudos to him! + (but please don't e-mail him for support, this isn't his driver) + + Tigran Aivazian - bug fixes, skbuff free cleanup + + Martin Mares - suggestions for PCI cleanup + + David S. Miller - PCI DMA and softnet updates + + Ernst Gill - fixes ported from BSD driver + + Daniel Kobras - identified specific locations of + posted MMIO write bugginess + + Gerard Sharp - bug fix, testing and feedback + + David Ford - Rx ring wrap fix + + Dan DeMaggio - swapped RTL8139 cards with me, and allowed me + to find and fix a crucial bug on older chipsets. + + Donald Becker/Chris Butterworth/Marcus Westergren - + Noticed various Rx packet size-related buglets. + + Santiago Garcia Mantinan - testing and feedback + + Jens David - 2.2.x kernel backports + + Martin Dennett - incredibly helpful insight on undocumented + features of the 8139 chips + + Jean-Jacques Michel - bug fix + + Tobias Ringström - Rx interrupt status checking suggestion + + Andrew Morton - Clear blocked signals, avoid + buffer overrun setting current->comm. + +*/ + +extern void kprint(const char *fmt, ...); +extern void board_printf(const char *fmt, ...); + +#define NBUF_NOCACHE + +#ifndef PCI_XBIOS +extern long *tab_funcs_pci; +#endif /* PCI_XBIOS */ +extern void udelay(long usec); +#if defined(NBUF_NOCACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +void *usb_malloc(long amount); +int usb_free(void *addr); +int usb_mem_init(void); +#define nbuf_alloc(x) usb_malloc(x) +#define nbuf_free(x) usb_free(x) +#define nbuf_init() usb_mem_init() +#else +#define nbuf_alloc(x) ((void *)Mxalloc(x,0)) /* ST-RAM cache WT */ +#define nbuf_free(x) Mfree(x) +#define nbuf_init() +#endif + +extern unsigned short swap_short(unsigned short val); +extern unsigned long swap_long(unsigned long val); + +static inline unsigned short cpu_to_le16(unsigned short val) +{ + return(swap_short(val)); +} +static inline unsigned long cpu_to_le32(unsigned long val) +{ + return(swap_long(val)); +} + +#define le16_to_cpu cpu_to_le16 +#define le32_to_cpu cpu_to_le32 + +#define readb(x) (*((volatile unsigned char *)(x))) +#define writeb(a, b) (*((volatile unsigned char *)(b)) = ((volatile unsigned char)a)) +#if defined CONFIG_RTL_BIG_ENDIAN +#define readw(x) (*((volatile unsigned short *)(x))) +#define writew(a, b) (*((volatile unsigned short *)(b)) = ((volatile unsigned short)a)) +#define readl(x) (*((volatile unsigned long *)(x))) +#define writel(a, b) (*((volatile unsigned long *)(b)) = ((volatile unsigned long)a)) +#else +#define readw(x) swap_short((*((volatile unsigned short *)(x)))) +#define writew(a, b) (*((volatile unsigned short *)(b)) = swap_short(((volatile unsigned short)a))) +#define readl(x) swap_long((*((volatile unsigned long *)(x)))) +#define writel(a, b) (*((volatile unsigned long *)(b)) = swap_long(((volatile unsigned long)a))) +#endif + +/* write MMIO register, with flush */ +/* Flush avoids rtl8139 bug w/ posted MMIO writes */ +#define RTL_W8_F(reg, val8) do { writeb((val8), (unsigned long)ioaddr + (reg)); (void)readb((unsigned long)ioaddr + (reg)); } while(0) +#define RTL_W16_F(reg, val16) do { writew((val16), (unsigned long)ioaddr + (reg)); (void)readw((unsigned long)ioaddr + (reg)); } while(0) +#define RTL_W32_F(reg, val32) do { writel((val32), (unsigned long)ioaddr + (reg)); (void)readl((unsigned long)ioaddr + (reg)); } while(0) + +#if MMIO_FLUSH_AUDIT_COMPLETE + +/* write MMIO register */ +#define RTL_W8(reg, val8) writeb((val8), (unsigned long)ioaddr + (reg)) +#define RTL_W16(reg, val16) writew((val16), (unsigned long)ioaddr + (reg)) +#define RTL_W32(reg, val32) writel((val32), (unsigned long)ioaddr + (reg)) + +#else + +/* write MMIO register, then flush */ +#define RTL_W8 RTL_W8_F +#define RTL_W16 RTL_W16_F +#define RTL_W32 RTL_W32_F + +#endif /* MMIO_FLUSH_AUDIT_COMPLETE */ + +/* read MMIO register */ +#define RTL_R8(reg) readb((unsigned long)ioaddr + (reg)) +#define RTL_R16(reg) readw((unsigned long)ioaddr + (reg)) +#define RTL_R32(reg) readl((unsigned long)ioaddr + (reg)) + +#define RTL8139_VENDOR_ID 0x10EC +#define RTL8139_DEVICE_ID 0X8139 + +#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/ +/* Size of the in-memory receive ring. */ +#define RX_BUF_LEN_IDX 2 /* 0==8K, 1==16K, 2==32K, 3==64K */ +#define RX_BUF_LEN (8192 << RX_BUF_LEN_IDX) +#define RX_BUF_PAD 16 +#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */ +#define RX_BUF_TOT_LEN (RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD) + +#define MAX_ADDR_LEN 8 /* Largest hardware address length */ + +/* Number of Tx descriptor registers. */ +#define NUM_TX_DESC 4 + +/* max supported ethernet frame size -- must be at least (mtu+14+4).*/ +#define MAX_ETH_FRAME_SIZE 1536 + +#define RTL_MTU (MAX_ETH_FRAME_SIZE-14-4) + +/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */ +#define TX_BUF_SIZE MAX_ETH_FRAME_SIZE +#define TX_BUF_TOT_LEN (TX_BUF_SIZE * NUM_TX_DESC) + +/* Ethernet standard lengths in bytes*/ +#define ETH_ADDR_LEN 6 +#define ETH_TYPE_LEN 2 +#define ETH_CRC_LEN 4 +#define ETH_MAX_DATA 1500 +#define ETH_MIN_DATA 46 +#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN) +#define ETH_ZLEN 60 /* Min bytes in frames */ + +/* PCI Tuning Parameters + Threshold is bytes transferred to chip before transmission starts. */ +#define TX_FIFO_THRESH 256 /* In bytes, rounded down to 32 byte units. */ + +/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024, 7==end of packet. */ +#define RX_FIFO_THRESH 6 /* Rx buffer level before first PCI xfer. */ +#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ +#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */ + +typedef enum +{ + CH_8139 = 0, + CH_8139_K, + CH_8139A, + CH_8139B, + CH_8130, + CH_8139C, + CH_8139CP, +} chip_t; + +enum +{ + HAS_MII_XCVR = 0x010000, + HAS_CHIP_XCVR = 0x020000, + HAS_LNK_CHNG = 0x040000, +}; + +#define RTL_MIN_IO_SIZE 0x80 +#define RTL8139B_IO_SIZE 256 + +#define RTL8129_CAPS HAS_MII_XCVR +#define RTL8139_CAPS HAS_CHIP_XCVR|HAS_LNK_CHNG + +typedef enum +{ + RTL8139 = 0, + RTL8139_CB, + SMC1211TX, + /*MPX5030,*/ + DELTA8139, + ADDTRON8139, + DFE538TX, + RTL8129, +} board_t; + +/* indexed by board_t, above */ +static struct +{ + const char *name; + unsigned long hw_flags; +} board_info[] = { + { "RealTek RTL8139CP Fast Ethernet", RTL8139_CAPS }, + { "RealTek RTL8139B PCI/CardBus", RTL8139_CAPS }, + { "SMC1211TX EZCard 10/100 (RealTek RTL8139)", RTL8139_CAPS }, +/* { MPX5030, "Accton MPX5030 (RealTek RTL8139)", RTL8139_CAPS },*/ + { "Delta Electronics 8139 10/100BaseTX", RTL8139_CAPS }, + { "Addtron Technolgy 8139 10/100BaseTX", RTL8139_CAPS }, + { "D-Link DFE-538TX (RealTek RTL8139)", RTL8139_CAPS }, + { "RealTek RTL8129", RTL8129_CAPS }, +}; + +/* directly indexed by chip_t, above */ +const static struct +{ + const char *name; + unsigned char version; /* from RTL8139C docs */ + unsigned long RxConfigMask; /* should clear the bits supported by this chip */ +} rtl_chip_info[] = { + { "RTL-8139", + 0x40, + 0xf0fe0040, /* XXX copied from RTL8139A, verify */ + }, + { "RTL-8139 rev K", + 0x60, + 0xf0fe0040, + }, + { "RTL-8139A", + 0x70, + 0xf0fe0040, + }, + { "RTL-8139B", + 0x78, + 0xf0fc0040 + }, + { "RTL-8130", + 0x7C, + 0xf0fe0040, /* XXX copied from RTL8139A, verify */ + }, + { "RTL-8139C", + 0x74, + 0xf0fc0040, /* XXX copied from RTL8139B, verify */ + }, + { "RTL-8139CP", + 0x76, + 0xf0fc0040, /* XXX copied from RTL8139B, verify */ + }, +}; + +/* The rest of these values should never change. */ + +/* Symbolic offsets to registers. */ +enum RTL8139_registers +{ + MAC0 = 0, /* Ethernet hardware address. */ + MAR0 = 8, /* Multicast filter. */ + TxStatus0 = 0x10, /* Transmit status (Four 32bit registers). */ + TxAddr0 = 0x20, /* Tx descriptors (also four 32bit). */ + RxBuf = 0x30, + RxEarlyCnt = 0x34, + RxEarlyStatus = 0x36, + ChipCmd = 0x37, + RxBufPtr = 0x38, + RxBufAddr = 0x3A, + IntrMask = 0x3C, + IntrStatus = 0x3E, + TxConfig = 0x40, + ChipVersion = 0x43, + RxConfig = 0x44, + Timer = 0x48, /* A general-purpose counter. */ + RxMissed = 0x4C, /* 24 bits valid, write clears. */ + Cfg9346 = 0x50, + Config0 = 0x51, + Config1 = 0x52, + FlashReg = 0x54, + MediaStatus = 0x58, + Config3 = 0x59, + Config4 = 0x5A, /* absent on RTL-8139A */ + HltClk = 0x5B, + MultiIntr = 0x5C, + TxSummary = 0x60, + BasicModeCtrl = 0x62, + BasicModeStatus = 0x64, + NWayAdvert = 0x66, + NWayLPAR = 0x68, + NWayExpansion = 0x6A, + /* Undocumented registers, but required for proper operation. */ + FIFOTMS = 0x70, /* FIFO Control and test. */ + CSCR = 0x74, /* Chip Status and Configuration Register. */ + PARA78 = 0x78, + PARA7c = 0x7c, /* Magic transceiver parameter register. */ + Config5 = 0xD8, /* absent on RTL-8139A */ +}; + +enum ClearBitMasks +{ + MultiIntrClear = 0xF000, + ChipCmdClear = 0xE2, + Config1Clear = (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1), +}; + +enum ChipCmdBits { + CmdReset = 0x10, + CmdRxEnb = 0x08, + CmdTxEnb = 0x04, + RxBufEmpty = 0x01, +}; + +/* Interrupt register bits, using my own meaningful names. */ +enum IntrStatusBits +{ + PCIErr = 0x8000, + PCSTimeout = 0x4000, + RxFIFOOver = 0x40, + RxUnderrun = 0x20, + RxOverflow = 0x10, + TxErr = 0x08, + TxOK = 0x04, + RxErr = 0x02, + RxOK = 0x01, +}; +enum TxStatusBits +{ + TxHostOwns = 0x2000, + TxUnderrun = 0x4000, + TxStatOK = 0x8000, + TxOutOfWindow = 0x20000000, + TxAborted = 0x40000000, + TxCarrierLost = 0x80000000, +}; +enum RxStatusBits +{ + RxMulticast = 0x8000, + RxPhysical = 0x4000, + RxBroadcast = 0x2000, + RxBadSymbol = 0x0020, + RxRunt = 0x0010, + RxTooLong = 0x0008, + RxCRCErr = 0x0004, + RxBadAlign = 0x0002, + RxStatusOK = 0x0001, +}; + +/* Bits in RxConfig. */ +enum rx_mode_bits { + AcceptErr = 0x20, + AcceptRunt = 0x10, + AcceptBroadcast = 0x08, + AcceptMulticast = 0x04, + AcceptMyPhys = 0x02, + AcceptAllPhys = 0x01, +}; + +/* Bits in TxConfig. */ +enum tx_config_bits +{ + TxIFG1 = (1 << 25), /* Interframe Gap Time */ + TxIFG0 = (1 << 24), /* Enabling these bits violates IEEE 802.3 */ + TxLoopBack = (1 << 18) | (1 << 17), /* enable loopback test mode */ + TxCRC = (1 << 16), /* DISABLE appending CRC to end of Tx packets */ + TxClearAbt = (1 << 0), /* Clear abort (WO) */ + TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */ + TxVersionMask = 0x7C800000, /* mask out version bits 30-26, 23 */ +}; + +/* Bits in Config1 */ +enum Config1Bits +{ + Cfg1_PM_Enable = 0x01, + Cfg1_VPD_Enable = 0x02, + Cfg1_PIO = 0x04, + Cfg1_MMIO = 0x08, + Cfg1_LWAKE = 0x10, + Cfg1_Driver_Load = 0x20, + Cfg1_LED0 = 0x40, + Cfg1_LED1 = 0x80, +}; + +enum RxConfigBits +{ + /* Early Rx threshold, none or X/16 */ + RxCfgEarlyRxNone = 0, + RxCfgEarlyRxShift = 24, + /* rx fifo threshold */ + RxCfgFIFOShift = 13, + RxCfgFIFONone = (7 << RxCfgFIFOShift), + /* Max DMA burst */ + RxCfgDMAShift = 8, + RxCfgDMAUnlimited = (7 << RxCfgDMAShift), + /* rx ring buffer length */ + RxCfgRcv8K = 0, + RxCfgRcv16K = (1 << 11), + RxCfgRcv32K = (1 << 12), + RxCfgRcv64K = (1 << 11) | (1 << 12), + /* Disable packet wrap at end of Rx buffer */ + RxNoWrap = (1 << 7), +}; + +/* Twister tuning parameters from RealTek. + Completely undocumented, but required to tune bad links. */ +enum CSCRBits +{ + CSCR_LinkOKBit = 0x0400, + CSCR_LinkChangeBit = 0x0800, + CSCR_LinkStatusBits = 0x0f000, + CSCR_LinkDownOffCmd = 0x003c0, + CSCR_LinkDownCmd = 0x0f3c0, +}; + +enum Cfg9346Bits +{ + Cfg9346_Lock = 0x00, + Cfg9346_Unlock = 0xC0, +}; + +enum NegotiationBits +{ + AutoNegotiationEnable = 0x1000, + AutoNegotiationRestart = 0x0200, + AutoNegoAbility10half = 0x21, + AutoNegoAbility10full = 0x41, + AutoNegoAbility100half = 0x81, + AutoNegoAbility100full = 0x101, +}; + +enum MediaStatusBits +{ + DuplexMode = 0x0100, //in BasicModeControlRegister + Speed_10 = 0x08, //in Media Status Register +}; + +/* A few user-configurable values. */ +/* media options */ +#define MAX_UNITS 8 +static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; +static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1}; + +/* MII serial management: mostly bogus for now. */ +/* Read and write the MII management registers using software-generated + serial MDIO protocol. + The maximum data clock rate is 2.5 Mhz. The minimum timing is usually + met by back-to-back PCI I/O cycles, but we insert a delay to avoid + "overclocking" issues. */ +#define MDIO_DIR 0x80 +#define MDIO_DATA_OUT 0x04 +#define MDIO_DATA_IN 0x02 +#define MDIO_CLK 0x01 +#define MDIO_WRITE0 (MDIO_DIR) +#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT) + +#define rtl8139_mdio_delay(mdio_addr) readb(mdio_addr) +#define mdio_delay(mdio_addr) readb(mdio_addr) + +static char mii_2_8139_map[8] = +{ + BasicModeCtrl, + BasicModeStatus, + 0, + 0, + NWayAdvert, + NWayLPAR, + NWayExpansion, + 0 +}; + +static const unsigned short rtl8139_intr_mask = + /* PCIErr | */ PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver | TxErr | TxOK | RxErr | RxOK; + +static const unsigned long rtl8139_rx_config = + RxCfgEarlyRxNone | RxCfgRcv32K | RxNoWrap | (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift); + +#define TX_TIMEOUT ((1000*200)/1000) +#define jiffies (*_hz_200) + +#ifdef USE_RX_BUFFERS + +#define MAX_RX_BUFFER_ENTRIES 50 + +struct rx_buffer_t +{ + struct rx_slot_t *first; + struct rx_slot_t *add; + struct rx_slot_t *extract; +} rx_buffer; + +struct rx_slot_t +{ + struct rx_slot_t *next; + unsigned int length; + unsigned char *data; + unsigned char read; +} rx_slot; + +#endif /* USE_RX_BUFFERS */ + +struct rtl8139_private +{ + long handle; + void *mmio_addr; + unsigned long mmio_len; + int drv_flags; + unsigned char *rx_ring; + unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ + unsigned int tx_flag; + unsigned long cur_tx; + unsigned long dirty_tx; + unsigned long trans_start; + /* The saved address of a sent-in-place packet/buffer, for skfree(). */ + unsigned char *tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */ + unsigned char *tx_bufs; /* Tx bounce buffer region. */ + unsigned long tx_bufs_dma; + unsigned long rx_ring_dma; +#ifdef USE_RX_BUFFERS + struct rx_buffer_t rx_buffer; +#endif + signed char phys[4]; /* MII device addresses. */ + unsigned short advertising; /* NWay media advertisement */ + char twistie, twist_row, twist_col; /* Twister tune state. */ + unsigned int full_duplex:1; /* Full-duplex operation requested. */ + unsigned int duplex_lock:1; + unsigned int default_port:4; /* Last dev->if_port value. */ + unsigned int media2:4; /* Secondary monitored media port. */ + unsigned int medialock:1; /* Don't sense media type. */ + unsigned int mediasense:1; /* Media sensing in progress. */ + chip_t chipset; +/* For 8139C+ */ + int AutoNegoAbility; +/* For lwIP */ + unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */ + long ioaddr; + unsigned long rx_frames_for_us; + int must_free_irq; + struct rtl8139if *rtl8139if; +/* For FreeRTOS */ +#ifdef USE_RX_BUFFERS + xSemaphoreHandle rx_sem; /* Semaphore to signal receive thread */ +#else + xQueueHandle rx_queue; +#endif + xSemaphoreHandle tx_sem; /* Control access to transmitter */ + sys_thread_t task; /* RTL RX task */ +/* For CTPCI */ + long (*ctpci_dma_lock)(long mode); +}; + diff --git a/flash.tos/drivers/lwip/sockets.c b/flash.tos/drivers/lwip/sockets.c index bfd2bf1..f72b309 100644 --- a/flash.tos/drivers/lwip/sockets.c +++ b/flash.tos/drivers/lwip/sockets.c @@ -50,7 +50,6 @@ extern void board_printf(const char *fmt, ...); extern unsigned long pxCurrentTCB, tid_TOS; #endif -#ifdef NETWORK #ifdef LWIP #define NUM_SOCKETS MEMP_NUM_NETCONN @@ -1467,6 +1466,5 @@ void socket_init(void) #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/stats.c b/flash.tos/drivers/lwip/stats.c index 35fd421..b7cbe7c 100644 --- a/flash.tos/drivers/lwip/stats.c +++ b/flash.tos/drivers/lwip/stats.c @@ -42,7 +42,6 @@ #include "perf.h" -#ifdef NETWORK #ifdef LWIP struct perf lwip_perfs[PERFS_MAX]; @@ -60,6 +59,8 @@ stats_init(void) memset(&lwip_stats, 0, sizeof(struct stats_)); memset(lwip_perfs, 0, sizeof(struct perf) * PERFS_MAX); } + +#ifdef COLDFIRE #if LWIP_STATS_DISPLAY void stats_display_proto(struct stats_proto *proto, char *name) @@ -148,8 +149,9 @@ stats_display(void) } } #endif /* LWIP_STATS_DISPLAY */ +#endif /* COLDFIRE */ + #endif /* LWIP_STATS */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/sys.c b/flash.tos/drivers/lwip/sys.c index c0e4aa7..3287f76 100644 --- a/flash.tos/drivers/lwip/sys.c +++ b/flash.tos/drivers/lwip/sys.c @@ -36,7 +36,6 @@ #include "def.h" #include "memp.h" -#ifdef NETWORK #ifdef LWIP #if (NO_SYS == 0) @@ -297,5 +296,4 @@ sys_msleep(u32_t ms) #endif /* NO_SYS */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/sys_arch.c b/flash.tos/drivers/lwip/sys_arch.c index 6ba315a..1d82e2c 100644 --- a/flash.tos/drivers/lwip/sys_arch.c +++ b/flash.tos/drivers/lwip/sys_arch.c @@ -39,7 +39,6 @@ #include #include "config.h" -#ifdef NETWORK #ifdef LWIP extern void ltoa(char *buf, long n, unsigned long base); @@ -74,7 +73,11 @@ extern void ltoa(char *buf, long n, unsigned long base); ( portTickType )( ( portTickType ) ( ms ) / portTICK_RATE_MS ) #define TICKS_TO_MS( ticks ) \ ( unsigned portLONG )( ( portTickType ) ( ticks ) * portTICK_RATE_MS ) +#ifdef COLDFIRE #define THREAD_STACK_SIZE ( 4096 ) +#else +#define THREAD_STACK_SIZE ( 2048 ) +#endif #define THREAD_NAME "lwIP" #define THREAD_INIT( tcb ) \ @@ -170,7 +173,8 @@ extern void board_printf(const char *fmt, ...); void sys_assert( const char *msg ) { - board_printf("%s\r\n"); + board_printf(msg); + board_printf("\r\n"); // vPortEnterCritical( ); // while(1) // asm volatile(" nop\n\t"); @@ -201,8 +205,8 @@ sys_debug( const char *const fmt, ... ) printk(&info, fmt, ap); *info.loc = '\0'; board_printf(buf); -// board_putchar('\r\n'); va_end(ap); + if(fmt); } /* ------------------------ Start implementation ( Threads ) -------------- */ @@ -577,12 +581,15 @@ sys_jiffies( void ) u32_t sys_read_timer( void ) { +#ifdef COLDFIRE #ifdef MCF5445X return(MCF_DTIM_DTCN(1)); #else return(MCF_SLT_SCNT(1)); #endif /* MCF5445X */ +#else /* !COLDFIRE */ + return(0); +#endif /* COLDFIRE */ } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/tcp.c b/flash.tos/drivers/lwip/tcp.c index 67c17ef..e952580 100644 --- a/flash.tos/drivers/lwip/tcp.c +++ b/flash.tos/drivers/lwip/tcp.c @@ -52,7 +52,6 @@ #include "tcp.h" -#ifdef NETWORK #ifdef LWIP #if LWIP_TCP @@ -1191,7 +1190,6 @@ tcp_pcbs_sane(void) #endif /* LWIP_TCP */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/tcp_in.c b/flash.tos/drivers/lwip/tcp_in.c index 7cb0908..5e6139f 100644 --- a/flash.tos/drivers/lwip/tcp_in.c +++ b/flash.tos/drivers/lwip/tcp_in.c @@ -58,7 +58,6 @@ #include "perf.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP #if LWIP_TCP @@ -1226,5 +1225,4 @@ tcp_parseopt(struct tcp_pcb *pcb) #endif /* LWIP_TCP */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/tcp_out.c b/flash.tos/drivers/lwip/tcp_out.c index b77dabe..ff787cd 100644 --- a/flash.tos/drivers/lwip/tcp_out.c +++ b/flash.tos/drivers/lwip/tcp_out.c @@ -54,7 +54,6 @@ #include "stats.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP #if LWIP_TCP @@ -724,7 +723,6 @@ tcp_keepalive(struct tcp_pcb *pcb) #endif /* LWIP_TCP */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/tcpip.c b/flash.tos/drivers/lwip/tcpip.c index a1559c2..03f6df0 100644 --- a/flash.tos/drivers/lwip/tcpip.c +++ b/flash.tos/drivers/lwip/tcpip.c @@ -47,7 +47,6 @@ #include "resolv.h" #include "tcpip.h" -#ifdef NETWORK #ifdef LWIP static void (* tcpip_init_done)(void *arg) = NULL; @@ -216,7 +215,5 @@ tcpip_init(void (* initfunc)(void *), void *arg) } #endif /* LWIP */ -#endif /* NETWORK */ - diff --git a/flash.tos/drivers/lwip/tftp.c b/flash.tos/drivers/lwip/tftp.c index 8c10e1d..10eec55 100644 --- a/flash.tos/drivers/lwip/tftp.c +++ b/flash.tos/drivers/lwip/tftp.c @@ -25,7 +25,6 @@ #include "sockets.h" #include "tftp.h" -#ifdef NETWORK #ifdef LWIP #define TIMEOUT 2 /* seconds */ @@ -394,4 +393,3 @@ char *tftp_get_error(void) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/udp.c b/flash.tos/drivers/lwip/udp.c index 9c9334a..3deb9f3 100644 --- a/flash.tos/drivers/lwip/udp.c +++ b/flash.tos/drivers/lwip/udp.c @@ -58,7 +58,6 @@ #include "perf.h" #include "snmp.h" -#ifdef NETWORK #ifdef LWIP /* The list of UDP PCBs */ @@ -663,5 +662,4 @@ udp_debug_print(struct udp_hdr *udphdr) #endif /* LWIP_UDP */ #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/web.c b/flash.tos/drivers/lwip/web.c index fcb60f5..2fd9c48 100644 --- a/flash.tos/drivers/lwip/web.c +++ b/flash.tos/drivers/lwip/web.c @@ -58,7 +58,6 @@ #define Tgetdate() *(unsigned short *)0x1176 #define Tgettime() *(unsigned short *)0x1178 -#ifdef NETWORK #ifdef LWIP #ifdef MCF5445X /* MCF5445X has no FPU */ @@ -4404,4 +4403,3 @@ void vBasicWEBServer(void *pvParameters) } #endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/lwip/web.c.light b/flash.tos/drivers/lwip/web.c.light new file mode 100644 index 0000000..4dc542b --- /dev/null +++ b/flash.tos/drivers/lwip/web.c.light @@ -0,0 +1,2195 @@ +/* ------------------------ System includes ------------------------------- */ +#include +#include +#include +#define atol _atol +#define atof _atof +#include "m68k_disasm.h" + +/* ------------------------ FreeRTOS includes ----------------------------- */ +#include "../freertos/FreeRTOS.h" +#include "../freertos/task.h" +#include "../freertos/queue.h" + +/* ------------------------ Project includes ------------------------------ */ +#include "config.h" +#include "../../include/version.h" +#include "../../include/fire.h" +#undef __MBAR +#include "net.h" +#ifdef MCF5445X +#include "flash.h" +#else +#ifdef MCF547X +#include "amd_flash.h" +#else /* MCF548X */ +#include "intel_c3_flash.h" +#endif /* MCF547X */ +#endif /* MCF5445X */ +#include "get.h" +#include "gif.h" + +/* ------------------------ lwIP includes --------------------------------- */ +#include "sockets.h" +#include "tcp.h" + +/* ------------------------ BDOS includes ----------------------------------*/ +/* cannot use TOS trap out of CF68KLIB !!! */ +#include "../bdos/bdos.h" +/* hope than the TOS update this variables ! */ +#define Tgetdate() *(unsigned short *)0x1176 +#define Tgettime() *(unsigned short *)0x1178 + +#ifdef LWIP + +/* ------------------------ Defines --------------------------------------- */ +/* Connection socket */ +#define TIMEOUT 2 /* sec */ +#define READBUF_SIZE 6400 +#define WRITEBUF_SIZE 32000 +#define SOCK_BUF_SIZE 32000 +#define TASKS_SERVER 5 + +#define BUF_SIZE 1024 +#define MAX_LENGTH 1000 + +#define VERSION_WEB 0x0100 + +/* The port on which we listen. */ +#define webHTTP_PORT 80 + +/* the http versions we support */ +enum http_version {VERSION_UNKNOWN, VERSION_10, VERSION_11}; + +#define SIZE_TOS_FLASH 0x00100000 // last 65KB for TOS parameters + +static int Flash, Error; +static unsigned char rec_len; /* longueur S-record */ +static unsigned char CS; /* checksum */ +static char sbuf[256]; +static char *sbuf_ptr; +static unsigned long lowest_address, hight_address, Mem_Data; + +typedef struct sock_msg_struct +{ + int sock; + int reserved[3]; +} sock_msg; + +typedef struct sock_conn_struct +{ + int sock; + int errno; + int version; + int content_length; + char boundary[256]; + char *response; + int response_size; + int response_max_size; + char *buf_write; + int offset_buf_write; +} sock_conn; + +typedef struct http_list_struct +{ + const char *method; + const char *url; + void (*handle_url)(sock_conn *conn, char *request); + const char *content_type; +} http_list; + +typedef struct http_status_struct +{ + int code; + const char *text; +} http_status; + +extern int errno; +extern void conout_debug(int c); +extern void conws_debug(char *buf); + +static char *types1[] = { "HEXA", "BIT", "BYTE", "SHORT", "LONG", "FLOAT", "DOUBLE", NULL }; +static char *types2[] = { "BYTE", "SHORT", "LONG", "FLOAT", "DOUBLE", NULL }; + +static unsigned char red_led_gif[] = { +71,73,70,56,57,97,10,0,10,0,230,0,0,248,132,129,171,51,23,187,46,22,240,36,31, +247,115,112,245,81,80,245,85,84,241,38,34,204,39,21,215,34,19,226,31,19,246,104, +102,200,73,43,213,34,19,246,107,102,244,68,68,247,116,112,248,138,135,221,65,40, +248,143,136,197,72,42,228,187,149,243,51,50,229,232,219,236,26,18,191,44,22,228, +29,19,197,160,125,215,222,209,182,47,23,205,206,186,248,182,159,167,54,24,197, +41,21,209,165,130,233,241,238,239,232,193,246,109,106,231,27,18,247,123,119,238, +30,24,210,35,20,226,30,19,199,40,21,193,43,21,246,181,161,243,49,48,244,72,72, +178,49,23,243,57,57,238,200,169,210,203,175,217,34,20,214,68,40,239,240,228,244, +63,63,238,209,173,235,240,224,221,206,174,238,245,234,247,250,250,191,172,140, +249,160,149,177,50,23,232,27,18,195,42,21,195,159,121,238,29,22,250,166,152,241, +40,37,200,205,186,243,56,55,248,134,131,248,149,142,248,176,157,241,193,167,190, +157,121,227,233,222,241,41,39,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,33,249,4,0,0,0,0,0,44,0,0,0,0,10,0,10,0,0,7,98,128,79,79,60, +54,50,31,56,57,130,79,59,75,45,62,72,4,5,58,79,35,74,68,73,0,16,6,49,7,23,36,17, +0,39,37,5,71,7,24,34,19,4,11,6,15,46,3,64,9,18,14,47,55,22,69,40,42,41,33,53,21, +78,3,67,26,52,8,25,29,66,77,38,10,13,8,65,2,63,1,30,79,51,43,44,2,48,1,32,61,138, +28,27,12,20,76,70,130,129,0,59, +}; + +static unsigned char green_led_gif[] = { +71,73,70,56,57,97,10,0,10,0,230,78,0,0,143,13,0,148,14,0,134,13,0,190,18,0,224, +21,37,255,58,0,155,14,2,226,23,19,243,40,0,173,16,165,244,186,38,225,59,0,169, +16,0,132,12,85,252,106,0,200,19,0,153,14,0,193,18,0,179,17,20,244,41,111,182,127, +0,215,20,0,180,17,0,159,15,98,180,114,208,237,229,14,238,35,206,237,226,0,176, +16,154,202,171,38,160,54,63,255,84,0,202,19,0,161,15,0,170,16,98,176,113,75,255, +96,124,246,144,183,225,202,0,211,20,0,162,15,0,138,13,0,168,16,0,207,19,0,219, +21,0,139,13,38,150,52,0,191,18,130,223,150,0,147,14,38,167,54,12,236,33,38,152, +53,0,186,17,62,244,83,27,251,48,101,252,122,52,255,73,182,235,202,167,220,186, +191,240,211,0,187,18,98,195,115,147,244,168,40,255,61,150,201,168,0,206,19,44, +255,65,134,204,152,98,181,114,0,150,14,0,163,15,112,217,131,86,255,107,0,141,13, +70,255,91,59,255,80,170,213,188,223,235,243,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,33,249,4,1,0,0,78,0,44,0,0,0,0,10,0,10,0,64,7,98,128, +78,78,25,10,56,14,37,58,130,78,68,16,1,0,45,2,13,20,78,54,8,51,7,21,15,53,9,40, +50,27,75,31,57,5,19,7,43,3,59,72,17,61,18,34,71,6,49,74,24,78,60,73,36,76,64,8, +4,48,78,63,67,5,55,26,4,66,3,28,62,11,44,39,32,47,22,12,23,70,30,38,9,42,33,6, +142,41,2,65,130,77,69,52,46,35,29,130,129,0,59, +}; + +static xQueueHandle mbox; + +extern int Flash, Error; +extern char sbuf[256]; +extern char *sbuf_ptr; +extern unsigned long lowest_address, hight_address, Mem_Data; + +static http_status m_http_status10[] = { + { 200, "HTTP/1.0 200 OK\r\n" }, + { 201, "HTTP/1.0 201 Created\r\n" }, + { 202, "HTTP/1.0 202 Accepted\r\n" }, + { 204, "HTTP/1.0 204 No Content\r\n" }, + { 205, "HTTP/1.0 205 Reset Content\r\n" }, + { 206, "HTTP/1.0 206 Partial Content\r\n" }, + { 301, "HTTP/1.0 301 Moved Permanently\r\n" }, + { 302, "HTTP/1.0 302 Found\r\n" }, + { 304, "HTTP/1.0 304 Not Modified\r\n" }, + { 400, "HTTP/1.0 400 Bad Request\r\n" }, + { 401, "HTTP/1.0 401 Unauthorized\r\n" }, + { 403, "HTTP/1.0 403 Forbidden\r\n" }, + { 404, "HTTP/1.0 404 Not Found\r\n" }, + { 500, "HTTP/1.0 500 Internal Server Error\r\n" }, + { 501, "HTTP/1.0 501 Not Implemented\r\n" }, + { 502, "HTTP/1.0 502 Bad Gateway\r\n" }, + { 503, "HTTP/1.0 503 Service Unavailable\r\n" }, +}; + +static http_status m_http_status11[] = { + { 100, "HTTP/1.1 100 Continue\r\n" }, + { 101, "HTTP/1.1 101 Switching Protocols\r\n" }, + { 200, "HTTP/1.1 200 OK\r\n" }, + { 201, "HTTP/1.1 201 Created\r\n" }, + { 202, "HTTP/1.1 202 Accepted\r\n" }, + { 203, "HTTP/1.1 203 Non-Authorative Information\r\n" }, + { 204, "HTTP/1.1 204 No Content\r\n" }, + { 205, "HTTP/1.1 205 Reset Content\r\n" }, + { 206, "HTTP/1.1 206 Partial Content\r\n" }, + { 300, "HTTP/1.1 300 Multiple Choices\r\n" }, + { 301, "HTTP/1.1 301 Moved Permanently\r\n" }, + { 302, "HTTP/1.1 302 Found\r\n" }, + { 303, "HTTP/1.1 303 See Other\r\n" }, + { 304, "HTTP/1.1 304 Not Modified\r\n" }, + { 305, "HTTP/1.1 305 Use Proxy\r\n" }, + { 307, "HTTP/1.1 307 Temporary Redirect\r\n" }, + { 400, "HTTP/1.1 400 Bad Request\r\n" }, + { 401, "HTTP/1.1 401 Unauthorized\r\n" }, + { 402, "HTTP/1.1 402 Payment Required\r\n" }, + { 403, "HTTP/1.1 403 Forbidden\r\n" }, + { 404, "HTTP/1.1 404 Not Found\r\n" }, + { 405, "HTTP/1.1 405 Method Not Allowed\r\n" }, + { 406, "HTTP/1.1 406 Not Acceptable\r\n" }, + { 407, "HTTP/1.1 407 Proxy Authentication Required\r\n" }, + { 408, "HTTP/1.1 408 Request Time-out\r\n" }, + { 409, "HTTP/1.1 409 Conflict\r\n" }, + { 410, "HTTP/1.1 410 Gone\r\n" }, + { 411, "HTTP/1.1 411 Length Required\r\n" }, + { 412, "HTTP/1.1 412 Precondition Failed\r\n" }, + { 413, "HTTP/1.1 413 Request Entity Too Large\r\n" }, + { 414, "HTTP/1.1 414 Request-URI Too Large\r\n" }, + { 415, "HTTP/1.1 415 Unsupported Media Type\r\n" }, + { 416, "HTTP/1.1 416 Requested range not satisfiable\r\n" }, + { 417, "HTTP/1.1 417 Expectation Failed\r\n" }, + { 500, "HTTP/1.1 500 Internal Server Error\r\n" }, + { 501, "HTTP/1.1 501 Not Implemented\r\n" }, + { 502, "HTTP/1.1 502 Bad Gateway\r\n" }, + { 503, "HTTP/1.1 503 Service Unavailable\r\n" }, + { 504, "HTTP/1.1 504 Gateway time-out\r\n" }, + { 505, "HTTP/1.1 505 HTTP Version not supported\r\n" }, +}; + +static void ltoa(char *buf, long n, unsigned long base) +{ + unsigned long un; + char *tmp, ch; + un = n; + if((base == 10) && (n < 0)) + { + *buf++ = '-'; + un = -n; + } + tmp = buf; + do + { + ch = un % base; + un = un / base; + if(ch <= 9) + ch += '0'; + else + ch += 'a' - 10; + *tmp++ = ch; + } + while(un); + *tmp = '\0'; + while(tmp > buf) + { + ch = *buf; + *buf++ = *--tmp; + *tmp = ch; + } +} + +typedef union +{ + long L; + float F; +} LF_t; + +static void ftoa(float f, int max, char *buf) +{ + long mantissa, int_part, frac_part; + short exp2; + LF_t x; + x.F = f; + if(x.L == 0) + { + *buf++ = '0'; + *buf++ = '\0'; + return; + } + exp2 = (unsigned char)(x.L >> 23) - 127; + mantissa = (x.L & 0xFFFFFF) | 0x800000; + frac_part = 0; + int_part = 0; + if((exp2 >= 31) || (exp2 < -23)) + { + *buf++ = 'n'; + *buf++ = 'a'; + *buf++ = 'n'; + *buf++ = '\0'; + return; + } + else if(exp2 >= 23) + int_part = mantissa << (exp2 - 23); + else if(exp2 >= 0) + { + int_part = mantissa >> (23 - exp2); + frac_part = (mantissa << (exp2 + 1)) & 0xFFFFFF; + } + else + frac_part = (mantissa & 0xFFFFFF) >> -(exp2 + 1); + if(x.L < 0) + *buf++ = '-'; + if(int_part == 0) + *buf++ = '0'; + else + { + ltoa(buf, int_part, 10); + while(*buf) + buf++; + } + if((frac_part != 0) && (max != 0)) + { + char m; + *buf++ = '.'; + for(m = 0; m < max; m++) + { + frac_part = (frac_part << 3) + (frac_part << 1); + *buf++ = (frac_part >> 24) + '0'; + frac_part &= 0xFFFFFF; + } + for(--buf; buf[0] == '0' && buf[-1] != '.'; --buf); + ++buf; + } + *buf = '\0'; +} + +static long numeric(long ch) +{ + if((ch >= '0') && (ch <= '9')) + return(1); + return(0); +} + +static int isspace(int c) +{ + switch(c) + { + case ' ': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + return(1); + } + return(0); +} + +static long check_base(char ch, long base) +{ + if(numeric(ch) && (ch < '0' + base)) + return(ch - '0'); + if((ch >= 'a') && (ch <= 'z')) + ch -= ('a' - 'A'); + if((ch >= 'A') && (ch < 'A' + base - 10)) + return(ch - 'A' + 10); + return(-1); +} + +static long atol(const char *text) +{ + long n; + int minus, base, ch; + while(isspace(*text)) + text++; + minus = 0; + if(*text == '-') + { + minus = 1; + text++; + } + base = 10; + if(*text == '$') + { + base = 16; + text++; + } + else if(*text == '%') + { + base = 2; + text++; + } + n = 0; + while((ch = check_base(*text++, base)) >= 0) + n = n * base + ch; + if(minus) + n = -n; + return(n); +} + +static float atof(const char *text) +{ + long n; + float nf; + int minus, base, ch; + while(isspace(*text)) + text++; + minus = 0; + if(*text == '-') + { + minus = 1; + text++; + } + base = 10; + if(*text == '$') + { + base = 16; + text++; + } + else if(*text == '%') + { + base = 2; + text++; + } + n = 0; + while((ch = check_base(*text++, base)) >= 0) + n = n * base + ch; + nf = (float)n; + if(text[-1] == '.') + { + n = base; + while((ch = check_base(*text++, base)) >= 0) + { + nf += (float)ch/(float)n; + n *= base; + } + } + if(minus) + nf = -nf; + return(nf); +} + +static void minus(char *s) +{ + while(*s) + { + if(*s>='A' && *s<='Z') + *s += 0x20; + if(*s=='\\') + *s='/'; + s++; + } +} + +static int read_socket(sock_conn *conn, char *request, int size, int *size_header) +{ + int i, n = 0, len = 0; + fd_set data_read; + struct timeval tv; + char *ptr = request, *ptr2; + if(size_header != NULL) + *size_header = 0; + if(conn->errno) + return(-1); + do + { + FD_ZERO(&data_read); + FD_SET(conn->sock, &data_read); + tv.tv_sec = TIMEOUT; + tv.tv_usec = 0; + i = select(FD_SETSIZE, &data_read, NULL, NULL, &tv); + if((i > 0) && (FD_ISSET(conn->sock, &data_read) != 0)) + { + n = recv(conn->sock, ptr, size - len, 0); + if(n >= 0) + { + len += n; + ptr += n; + *ptr = 0; + if((size_header != NULL) + && ((ptr2 = strstr(request, "\r\n\r\n")) != NULL)) + { + *size_header = (int)(ptr2 - request) + 4; + break; + } + } + else + conn->errno = errno; + } + } + while((n >= 0) && (n < size) && (i > 0)); + return((n < 0) ? n : len); +} + +static int write_socket(sock_conn *conn, char *response, int size, int flush) +{ + int i, n = 0, len; + fd_set data_write; + struct timeval tv; + char *ptr = response; + if((conn->buf_write == NULL) || (response == NULL) || conn->errno) + return(-1); + do + { + len = WRITEBUF_SIZE - conn->offset_buf_write; + if(size < len) + len = size; + if(len >= 0) + { + memcpy(&conn->buf_write[conn->offset_buf_write], response, len); + size -= len; + conn->offset_buf_write += len; + response += len; + } + if((conn->offset_buf_write >= WRITEBUF_SIZE) + || ((size <= 0) && flush)) + { + len = n = 0; + ptr = conn->buf_write; + do + { + FD_ZERO(&data_write); + FD_SET(conn->sock, &data_write); + tv.tv_sec = TIMEOUT; + tv.tv_usec = 0; + i = select(FD_SETSIZE, NULL, &data_write, NULL, &tv); + if((i > 0) && (FD_ISSET(conn->sock, &data_write) != 0)) + { + n = send(conn->sock, ptr, conn->offset_buf_write - len, 0); + if(n >= 0) + { + ptr += n; + len += n; + } + else + conn->errno = errno; + } + } + while((n >= 0) && (len < conn->offset_buf_write) && (i > 0)); + conn->offset_buf_write = 0; + } + } + while(size > 0); + return(n < 0 ? n : len); +} + +static void write_string(sock_conn *conn, char *text) +{ + write_socket(conn, text, strlen(text), 0); +} + +static int send_status_code(sock_conn *conn, int status_code) +{ + int i; + if(conn->version == VERSION_10) + { + for(i = 0; i < sizeof(m_http_status10)/sizeof(m_http_status10[0]); i++) + { + if(m_http_status10[i].code == status_code) + { + write_socket(conn, (char *)m_http_status10[i].text, strlen((void *)m_http_status10[i].text), status_code == 200 ? 0 : 1); + return 1; + } + } + } + else + { + for(i = 0; i < sizeof(m_http_status11)/sizeof(m_http_status11[0]); i++) + { + if(m_http_status11[i].code == status_code) + { + write_socket(conn, (char *)m_http_status11[i].text, strlen((void *)m_http_status11[i].text), status_code == 200 ? 0 : 1); + return 1; + } + } + } + /* Unsupported status code? Pretty internal error, isn't it? Send 500 */ + send_status_code(conn, 500); + return 0; +} + +static void send_content_type(sock_conn *conn, const char *content_type) +{ + char buf[64]; + strcpy(buf, "Content-Type: "); + strcat(buf, content_type); + strcat(buf, "\r\n"); + write_string(conn, buf); +} + +static int dayofweek(int year,int mon,int mday) +{ + static int doylookup[2][13] = { + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }}; + int doe,isleapyear; + int era,cent,quad,rest; + /* break down the year into 400, 100, 4, and 1 year multiples */ + rest = year-1; + quad = rest/4; + rest %= 4; + cent = quad/25; + quad %= 25; + era = cent/4; + cent %= 4; + /* leap year every 4th year, except every 100th year, + not including every 400th year. */ + isleapyear = !(year % 4) && ((year % 100) || !(year % 400)); + /* set up doe */ + doe = mday + doylookup[isleapyear][mon - 1]; + doe += era * (400 * 365 + 97); + doe += cent * (100 * 365 + 24); + doe += quad * (4 * 365 + 1); + doe += rest * 365; + return(doe %7); +} + +static unsigned long gettime(void) +{ + return(((unsigned long)Tgetdate() << 16) + ((unsigned long)Tgettime() & 0xffff)); +} + +static void send_date(sock_conn *conn, const char *name, unsigned long datetime) +{ + static char *days[] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; + static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + char buf[64], buf2[10]; + int year, mon, mday; + year = (int)((datetime >> 25) + 1980UL); /* year */ + mon = (int)((datetime >> 21) & 0xf); /* month */ + if(mon < 1) + mon = 1; + mday = (int)((datetime >> 16) & 0x1f); /* day of month */ + strcpy(buf, name); + strcat(buf, days[dayofweek(year,mon,mday)]); + strcat(buf, ", "); + ltoa(buf2, mday + 100, 10); + strcat(buf, &buf2[1]); + strcat(buf, " "); + strcat(buf, months[mon-1]); + strcat(buf, " "); + ltoa(buf2, year, 10); + strcat(buf, buf2); + strcat(buf, " "); + ltoa(buf2, ((datetime >> 11) & 0x1f) + 100, 10); /* hour */ + strcat(buf, &buf2[1]); + strcat(buf, ":"); + ltoa(buf2, ((datetime >> 5) & 0x3f) + 100, 10); /* mn */ + strcat(buf, &buf2[1]); + strcat(buf, ":"); + ltoa(buf2, ((datetime & 0x1f) << 1) + 100, 10); /* sec */ + strcat(buf, &buf2[1]); + strcat(buf, " GMT\r\n"); + write_string(conn, buf); +} + +static void send_content_length(sock_conn *conn, int length) +{ + char buf[64], buf2[10]; + strcpy(buf, "Content-Length: "); + ltoa(buf2, length, 10); + strcat(buf, buf2); + strcat(buf, "\r\n"); + write_string(conn, buf); +} + +static int copy_file(char *path, char *buf, long size) +{ + long file; + char *p = path; + while(*path) + { + if((*path == '\\') || (*path == '/')) + p = path+1; + path++; + } + if((file = Fcreate(p, 0)) >= 0) + { + if(size) + Fwrite(file, size, buf); + Fclose(file); + return(0); + } + return(-1); +} + +#ifdef MCF5445X + +static int Programmation(unsigned long int begin, unsigned long int end, unsigned long int mem) +{ + if((begin < FLASH_TOS_FIRE_ENGINE) || (begin >= FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + return(-1); + if((end < FLASH_TOS_FIRE_ENGINE) || (end >= FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + return(-1); + UnprotectCSBOOT(); + FlashIdentify(); + UnlockFlashBlockAll(); + if(EraseFlash(begin, end) != SUCCESS) + { + ResetFlash(); + ProtectCSBOOT(); + return(-1); + } + else + { + unsigned long *p =(unsigned long *)mem; + for(; begin < end; begin += 4) + { + if(ProgFlash(begin, *p++) != SUCCESS) + { + ResetFlash(); + ProtectCSBOOT(); + return(-1); + } + } + } + ResetFlash(); + ProtectCSBOOT(); + return(0); +} + +#else + +#ifdef MCF547X + +static int Programmation(unsigned long int begin, unsigned long int end, unsigned long int mem) +{ + if((begin < FLASH_TOS_FIRE_ENGINE) || (begin >= FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + return(-1); + if((end < FLASH_TOS_FIRE_ENGINE) || (end >= FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + return(-1); + UnprotectCSBOOT(); + if(FlashIdentify() != SUCCESS) + { + ProtectCSBOOT(); + return(-1); + } + if(EraseFlash(begin, end) != SUCCESS) + { + ProtectCSBOOT(); + return(-1); + } + else + { + if(ProgFlash(begin, end, (void *)mem) != SUCCESS) + { + ProtectCSBOOT(); + return(-1); + } + } + ProtectCSBOOT(); + return(0); +} + +#else /* MCF548X */ + +static int Programmation(unsigned long int begin, unsigned long int end, unsigned long int mem) +{ + int bytes = (int)(end-begin); + if((begin < FLASH_TOS_FIRE_ENGINE) || (begin >= FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + return(-1); + if((end < FLASH_TOS_FIRE_ENGINE) || (end >= FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + return(-1); + if(begin >= end) + return(-1); + if(begin & INTEL_C3_FLASH_CELL_MASK) + return(-1); + bytes += INTEL_C3_FLASH_CELL_MASK; + bytes &= ~INTEL_C3_FLASH_CELL_MASK; + intel_c3_flash_init(BOOT_FLASH_BASE); + if(intel_c3_flash_program(begin, mem, bytes, 1, NULL, NULL) != bytes) + return(-1); + return(0); +} + +#endif /* MCF547X */ +#endif /* MCF5445X */ + +/***********************************************************************/ +/* getbh: Read 2 ASCII characters from the S-record buffer and */ +/* convert them into their corresponding binary value */ +/* */ +/* INPUT: None */ +/* OUTPUT: value: Binary value of byte pair */ +/* sbuf_ptr: Incremented by 2 */ +/* */ +/***********************************************************************/ +static unsigned char getbh(void) +{ + unsigned long c, i, value = 0; + for(i = 0; i < 2; i++) + { + c = *sbuf_ptr++; + value <<= 4; + value += c; + if((c >= '0') && (c <= '9')) + value -= '0'; + else + { + if((c >= 'A') && (c <= 'F')) + value -= ('A' - 10); + else + { + Error=1; + return(0); + } + } + } + return value; +} + +/***********************************************************************/ +/* getcsbh: Read a byte pair from the record buffer, updating */ +/* the calculated checksum and remaining record length */ +/* */ +/* INPUT: None */ +/* OUTPUT: val: Binary value of byte pair */ +/* */ +/***********************************************************************/ +static unsigned char getcsbh(void) +{ + unsigned char val; + CS += (val = getbh()); + return val; +} + +/***********************************************************************/ +/* read_rec: Read an S-record from the S-record buffer and write */ +/* the data it represents to memory */ +/* */ +/* INPUT: None */ +/* OUTPUT: None */ +/* */ +/***********************************************************************/ +static void read_rec(void) +{ + unsigned long rec_type, addr, i; + unsigned char data; + int bypass_data; + /*---------------------------------------------------------------------*/ + /* Position sbuf_ptr to just after 'S' of S-record. */ + /*---------------------------------------------------------------------*/ + for(sbuf_ptr = sbuf; *sbuf_ptr != 'S';) + if(!(*++sbuf_ptr)) + return; + sbuf_ptr++; + /*---------------------------------------------------------------------*/ + /* Get the record type and lenght of the record. Adjust the checksum */ + /* byte accordingly. */ + /*---------------------------------------------------------------------*/ + rec_type = *sbuf_ptr++ - '0'; + CS = (rec_len = getbh()); + rec_len--; + switch(rec_type) + { + case 7: + case 8: + case 9: + /*-------------------------------------------------------------*/ + /* Termination records. Nothing to do. */ + /*-------------------------------------------------------------*/ + i = 11 - rec_type; + addr = 0; + while(i--) + { + addr = (addr << 8) + getcsbh(); + if(Error) + return; + } + break; + case 0: + break; + case 5: + /*-------------------------------------------------------------*/ + /* All of these records can be skipped */ + /*-------------------------------------------------------------*/ + while(rec_len != 0) + { + getcsbh(); + rec_len--; + if(Error) + return; + } + break; + case 1: + case 2: + case 3: + /*-------------------------------------------------------------*/ + /* Data record - first read the load address from the record */ + /* and add in the offset. The load address is 2, 3, or 4 byte */ + /* pairs, depending on the record type. */ + /*-------------------------------------------------------------*/ + addr = 0; + for(i = 0; i <= rec_type; i++) + { + addr = (addr << 8) + getcsbh(); + rec_len--; + } + bypass_data = 0; + if(addr < lowest_address) + { + if(!Flash || (Flash && (addr >= FLASH_TOS_FIRE_ENGINE))) + lowest_address = addr; + else + bypass_data = 1; + } + if((addr + rec_len) > hight_address) + hight_address = addr + rec_len; + if(Error) + return; + /* controle si le telechargement est en flash */ + if((addr >= FLASH_TOS_FIRE_ENGINE) + && (addr < FLASH_TOS_FIRE_ENGINE+SIZE_TOS_FLASH)) + Flash=1; + addr &= (SIZE_TOS_FLASH-1); + addr += Mem_Data; + /*-------------------------------------------------------------*/ + /* Read each byte of data. */ + /*-------------------------------------------------------------*/ + while(rec_len != 0) + { + data = getcsbh(); + if(!bypass_data) + *((unsigned char *)addr++) = data; + rec_len--; + if(Error) + return; + } + break; + default: + Error = 1; + break; + } + /*---------------------------------------------------------------------*/ + /* Last thing to do is verify the checksum. */ + /*---------------------------------------------------------------------*/ + if((rec_type != 0) && (getbh() != (unsigned char)(~CS))) + Error = 1; +} + +/***********************************************************************/ +/* conv_rec: Process a buffer full of records */ +/* */ +/* INPUT: buf_ptr: pointer to buffer */ +/* count: length of buffer */ +/* OUTPUT: None */ +/* */ +/***********************************************************************/ +static void conv_rec(char *buf_ptr, long count) +{ + unsigned char c; +/*---------------------------------------------------------------------*/ +/* Transfer data from the buffer into the record buffer until a CR, */ +/* NL, or NULL is transferred (any of these is assumed to terminate */ +/* a record). Then call read_rec() to process the record, and start */ +/* filling the record buffer again. */ +/* NOTE: If the buffer ends with a partial record, it will be saved in */ +/* sbuf[]. */ +/*---------------------------------------------------------------------*/ + while(count-- > 0) + { + c = (*sbuf_ptr++ = *buf_ptr++); + if(c == '\n' || c == '\r' || c == 0) + { + *sbuf_ptr = '\0'; + read_rec(); + if(Error) + return; + while(*buf_ptr == '\n' || *buf_ptr == '\r') + { + buf_ptr++; + if(--count <= 0) + break; + } + sbuf_ptr = sbuf; + } + } +} + +/***********************************************************************/ +/* HTML pages */ +/***********************************************************************/ + +static void add_block(sock_conn *conn, const char *data, int size) +{ + if(size + conn->response_size > conn->response_max_size) + { + void *buf = conn->response; + int len = conn->response_max_size; + do + conn->response_max_size += WRITEBUF_SIZE; + while(size + conn->response_size > conn->response_max_size); + conn->response = pvPortMalloc2(conn->response_max_size); + memcpy(conn->response, buf, len); + vPortFree2(buf); + } + if(conn->response != NULL) + { + memcpy(&conn->response[conn->response_size], data, size); + conn->response_size += size; + } +} + +static void a2p(sock_conn *conn, const char *text) +{ + add_block(conn, text, strlen(text)); +} + +static void add_types(sock_conn *conn) +{ + int i=0; + while(types1[i]) + { + a2p(conn, "\n"); + } +} + +static void add_types_write(sock_conn *conn) +{ + int i=0; + while(types2[i]) + { + a2p(conn, "\n"); + } +} + +static void handle_menu(sock_conn *conn, char *request) +{ + static char html[] = +#ifdef MCF5445X + "M54455EVB - Menu\n" +#else +#ifdef MCF547X + "FIREBEE - Menu\n" +#else /* MCF548X */ + "M5484LITE - Menu\n" +#endif +#endif + "\n" + "\n"; + static char menu[] = + "\n" + "\n" + "

" +#ifdef MCF5445X + "M54455EVB" +#else +#ifdef MCF547X + "FIREBEE" +#else /* MCF548X */ + "M5484LITE" +#endif +#endif + "
\nBasic WEB Server version "; + static char menu1[] = + "


\n" + "

Menu :

\n" + "
\n" + "

\n" + " \n" + "Reading memory : \n" + "\n Start address $\n" + " Length \n" + " Refresh rate S\n" + "\n" + "

\n" + " \n" + "Change memory : \n" + "\n Address $\n" + " Value \n" + "\n" + "

\n" + " \n" + "Disassemble memory : \n" + " Start address $\n" + " Length \n" + "\n" + "

\n" + " \n" + "Commands shell : \n" + " \n" + "\n" + " \n" + "Upload : \n" + "


\n" + "
\n"; + static char end[] = ""; + unsigned long IP; + struct in_addr addr; + char buf[64]; + a2p(conn, html); + a2p(conn, menu); + ltoa(buf, VERSION_WEB, 16); + a2p(conn, buf); + a2p(conn, menu1); + add_types(conn); + a2p(conn, menu2); + add_types_write(conn); + a2p(conn, menu3); + board_get_client((unsigned char *)&IP); + addr.s_addr = htonl(IP); + a2p(conn, inet_ntoa(addr)); + a2p(conn, "\"'>\n"); + a2p(conn, menu4); + a2p(conn, end); +} + +static void handle_mem(sock_conn *conn, char *req) +{ + static char html[] = + "\nphyCORE-MCF548x\n" + "\n"; + static char refresh[] = + "\nphyCORE-MCF548x - Mem\n" + "\n" + "\n" + "\n" + "\n\n"; + static char imprimer[] = + "

\n" + "\n" + "\n" + "\n" + "

\n"; + static char imprimer2[] = + "

\n" + "\n" + "\n" + "

\n"; + static char retour[] = + "
\n" + "\n" + "
\n"; + static char end[] = ""; + int Refresh=1; + int i,j,max_align,max,choix,ChoixMem,OffsetLect=0,LengthLect=1,IndexMem=0; + int OffsetDis=0,LengthDis=8; + unsigned long bits; + float val; + char body[64],buf[BUF_SIZE],buf2[BUF_SIZE]; + char *ptr, *ptr2; + short *sptr; + double *dptr; + int len; + long *mem=NULL; + ptr = strchr(req, '?'); + if(ptr == NULL) + ptr = req; + else + ptr++; + ptr2 = buf; + i = 0; + while(*ptr && (*ptr != ' ') && (i++ < BUF_SIZE-1)) + *ptr2++ = *ptr++; + *ptr2 = 0; + if((ptr = strstr(buf, "ColorMem=")) != NULL + && ptr[9]!='&' && ptr[9]) + { + buf2[6] = 0; + memcpy(buf2, &ptr[9], 6); + strcpy(body, "\n

\n"); + } + else + strcpy(body, "\n

\n"); +/*************************** ENVOI FICHIER ************************************/ + if(strstr(buf, "EnvoiFichier=") != NULL) + a2p(conn, redirection_fichier); +/**************************** DISASSEMBLE *************************************/ + else if(strstr(buf, "ChoixDis=") != NULL) + { + struct DisasmPara_68k dp; + char buffer[16]; + m68k_word *ip, *p; + char opcode[16]; + char operands[128]; + char iwordbuf[32]; + char *s; + int n, i; + if((ptr = strstr(buf, "OffsetDis=")) != NULL + && ptr[10]!='&') + { + ptr[9] = '$'; + OffsetDis = (int)atol(&ptr[9]); + ptr[9] = '='; + } + else + OffsetDis = 0; + if((ptr = strstr(buf, "LengthDis=")) != NULL + && ptr[10]!='&') + { + LengthDis = (int)atol(&ptr[10]); + if(LengthDis < 0) + LengthDis = 8; + else if(LengthDis > 999) + LengthDis = 999; + } + else + LengthDis = 1; + a2p(conn, html); + a2p(conn, body); + a2p(conn, "

\r\n");
+    p=(m68k_word *)OffsetDis;
+    db_radix = 16;
+    dp.instr = NULL;              /* pointer to instruction to disassemble */
+    dp.iaddr = NULL;              /* instr.addr., usually the same as instr */
+    dp.opcode = opcode;           /* buffer for opcode, min. 16 chars. */
+    dp.operands = operands;       /* operand buffer, min. 128 chars. */
+    dp.radix = 16;                /* base 2, 8, 10, 16 ... */
+/* call-back functions for symbolic debugger support */
+    dp.get_areg = NULL;           /* returns current value of reg. An */
+    dp.find_symbol = NULL;        /* finds closest symbol to addr and */
+                                  /*  returns (positive) difference and name */
+/* changed by disassembler: */
+    dp.type = 0;                  /* type of instruction, see below */
+    dp.flags = 0;                 /* additional flags */
+    dp.reserved = 0;
+    dp.areg = 0;                  /* address reg. for displacement (PC=-1) */
+    dp.displacement = 0;          /* branch- or d16-displacement */
+    for(i=0;i 5)
+        n = 5;
+      ip = dp.instr;
+      s = iwordbuf;
+      while(n--)
+      {
+        ltoa(buffer,(((unsigned long)*(unsigned char *)ip)<<8) | ((unsigned long)*((unsigned char *)ip+1)) | 0x10000UL,16);
+        *s++ = buffer[1];
+        *s++ = buffer[2];
+        *s++ = buffer[3];
+        *s++ = buffer[4];
+        s++;
+          ip++;
+      }
+      a2p(conn, "$");
+      ltoa(buffer,(unsigned long)dp.iaddr,16);
+      a2p(conn, buffer);
+      a2p(conn, ": ");
+      a2p(conn, iwordbuf);
+      strcpy(buffer, "       ");
+      n = 0;
+      while(opcode[n])
+      {
+        buffer[n] = opcode[n];
+        n++;
+      }
+      buffer[n] = 0;
+      a2p(conn, buffer);
+      a2p(conn, " ");
+      a2p(conn, operands);
+      a2p(conn, "\r\n");
+    }
+    a2p(conn, "
\r\n"); + a2p(conn, imprimer); + goto EndMem; + } +/*************************** MODIFICATION VARIABLE ****************************/ + else if(strstr(buf, "ChoixModif=") != NULL) + { + ChoixMem = 0; + choix = 1; + while(types2[choix] != NULL) + { + strcpy(buf2, "ModifMem="); + strcat(buf2, types2[choix]); + len = strlen(buf2); + if((ptr2 = strstr(buf, buf2)) != NULL + && (ptr2[len]=='&' || ptr2[len]==0)) + { + if((ptr = strstr(buf, "IndexModif=")) != NULL + && ptr[11]!='&') + { + ptr[10] = '$'; + mem = (long *)atol(&ptr[10]); + ptr[10] = '='; + if((ptr = strstr(buf, "ValeurModif=")) != NULL + && ptr[12]!='&') + { + val = atof(&ptr[12]); + if(1) + { + if(strcmp(types2[choix], "BYTE") == 0) + *(char *)mem = (char)val; + else if(strcmp(types2[choix], "SHORT") == 0) + *(short *)mem = (short)val; + else if(strcmp(types2[choix], "FLOAT") == 0) + *(float *)mem = val; + else if(strcmp(types2[choix], "DOUBLE") == 0) + *(double *)mem = (double)val; + else + *mem = (long)val; + ChoixMem = 0; + while(types1[ChoixMem] != NULL) + { + if(strcmp(types1[ChoixMem], types2[choix]) == 0) + { + ChoixMem++; + OffsetLect = (int)mem; + IndexMem = (int)mem; + LengthLect = 16; + a2p(conn, html); + goto AffMem; + } + ChoixMem++; + } + ChoixMem = 0; + OffsetLect = (int)mem; + IndexMem = (int)mem; + LengthLect = 16; + a2p(conn, html); + goto AffMem; + } + else + { + a2p(conn, html); + a2p(conn, "\n

Bad address

\n"); + a2p(conn, retour); + goto EndMem; + } + } + else + { + a2p(conn, html); + a2p(conn, "\n

No value for this address

\n"); + a2p(conn, retour); + goto EndMem; + } + } + else + { + a2p(conn, html); + a2p(conn, "\n

No address

\n"); + goto EndMem; + } + } + choix++; + } + a2p(conn, html); + a2p(conn, "\n

Impossible to change this address

\n"); + a2p(conn, retour); + } +/*************************** LECTURE VARIABLES ********************************/ + else if(strstr(buf, "ChoixLect=") != NULL) + { + a2p(conn, refresh); + if((ptr = strstr(buf, "Rafraichir=")) != NULL + && ptr[11]!='&') + Refresh = (int)atol(&ptr[11]); + if(Refresh == 0) + Refresh++; + ltoa(buf2, Refresh, 10); + a2p(conn, buf2); + a2p(conn, "'>\n\n"); + if((ptr = strstr(buf, "OffsetLect=")) != NULL + && ptr[11]!='&') + { + ptr[10] = '$'; + OffsetLect = (int)atol(&ptr[10]); + ptr[10] = '='; + } + else + OffsetLect = 0; + if((ptr = strstr(buf, "LengthLect=")) != NULL + && ptr[11]!='&') + { + LengthLect = (int)atol(&ptr[11]); + if(LengthLect < 0) + LengthLect = 1; + else if(LengthLect > MAX_LENGTH) + LengthLect = MAX_LENGTH; + } + else + LengthLect = 1; + ChoixMem = 0; +AffMem: + a2p(conn, body); + mem = (long *)OffsetLect; + choix = 0; + while(types1[choix] != NULL) + { + strcpy(buf2, "LectMem="); + strcat(buf2, (ptr = types1[choix])); + len = strlen(buf2); + if(((ptr2 = strstr(buf, buf2)) != NULL + && (ptr2[len]=='&' || ptr2[len]==0)) || ChoixMem) + { + if(!ChoixMem || (choix+1)==ChoixMem) + { + a2p(conn, "
\n\n"); + if(strcmp(types1[choix], "BIT") == 0) + { + for(i=0; i\n"); + bits = (unsigned long)mem[i]; + bits = ((bits & 0xFF)<<24) + ((bits & 0xFF00)<<8) + + ((bits & 0xFF0000)>>8) + ((bits & 0xFF000000)>>24); + for(j=0; j<32; j++) + { + if(j==16) + a2p(conn, "\n\n"); + a2p(conn, "\n"); + else + a2p(conn, "
\n"); + bits >>= 1; + } + a2p(conn, "\n"); + } + } + else + { + max_align = (LengthLect + 15) & ~15; + max = LengthLect; + for(i=0; i\n"); + } + if(i"); + if(strcmp(types1[choix], "BYTE") == 0) + { + ptr = (char *)mem; + ltoa(buf2, (long)ptr[i], 10); + } + else if(strcmp(types1[choix], "SHORT") == 0) + { + sptr = (short *)mem; + ltoa(buf2, (long)sptr[i], 10); + } + else if(strcmp(types1[choix], "LONG") == 0) + ltoa(buf2, mem[i], 10); + else if(strcmp(types1[choix], "FLOAT") == 0) + ftoa(*(float *)&mem[i], 2, buf2); + else if(strcmp(types1[choix], "DOUBLE") == 0) + { + dptr = (double *)mem; + ftoa((float)dptr[i], 2, buf2); + } + else + { + buf2[0] = '$'; + ltoa(&buf2[1], mem[i], 16); + } + a2p(conn, buf2); + a2p(conn, ""); + } + else + { + a2p(conn, ""); + } + } + else + a2p(conn, ""); + if((i&15)==15) + a2p(conn, "\n\n"); + } + } + a2p(conn, "

Table "); + a2p(conn, ptr); + a2p(conn, "

"); + ltoa(buf2, i*32 + j + 1, 10); + a2p(conn, buf2); + if(bits&1) + a2p(conn, "
$"); + ltoa(buf2, (long)&mem[i], 16); + a2p(conn, buf2); + a2p(conn, ""); + if(strcmp(types1[choix], "BYTE") == 0) + { + ptr = (char *)mem; + ltoa(buf2, (long)ptr[i], 10); + } + else if(strcmp(types1[choix], "SHORT") == 0) + { + sptr = (short *)mem; + ltoa(buf2, (long)sptr[i], 10); + } + else if(strcmp(types1[choix], "LONG") == 0) + ltoa(buf2, mem[i], 10); + else if(strcmp(types1[choix], "FLOAT") == 0) + ftoa(*(float *)&mem[i], 2, buf2); + else if(strcmp(types1[choix], "DOUBLE") == 0) + { + dptr = (double *)mem; + ftoa((float)dptr[i], 2, buf2); + } + else + { + buf2[0] = '$'; + ltoa(&buf2[1], mem[i], 16); + } + a2p(conn, buf2); + a2p(conn, "-
\n"); + if(strcmp(types1[choix], "BIT") == 0) + a2p(conn, imprimer2); + else + a2p(conn, imprimer); + } + } + choix++; + } + } + else + { + a2p(conn, html); + a2p(conn, body); + } +EndMem: + a2p(conn, end); +} + +static void show_red_led(sock_conn *conn, char *request) +{ + if(request); + add_block(conn, (const char *)red_led_gif, sizeof(red_led_gif)); +} + +static void show_green_led(sock_conn *conn, char *request) +{ + if(request); + add_block(conn, (const char *)green_led_gif, sizeof(green_led_gif)); +} + +static void select_file(sock_conn *conn, char *request) +{ + static char html[] = + "phyCORE-MCF548x - File\n" + "\n"; + static char form[] = + "\n" + "

" + "Upload file / system" + "


\n" + "

\n" + "

Send file : \n" + "\n" + "\n" + "\n" + "\n" + "

\n"; + static char end[] = ""; + if(request); + a2p(conn, html); + a2p(conn, form); + a2p(conn, end); +} + +static void handle_file(sock_conn *conn, char *req) +{ + static char html[] = + "phyCORE-MCF548x - End File Transfer\n"; + static char retour[] = + "

\n" + "\n" + "
\n"; + static char end[] = ""; + char *buffer, *ptr, *ptr2, *ptr3; + char buf[BUF_SIZE], buf2[BUF_SIZE]; + unsigned long len = (unsigned long)conn->content_length; + int err,i; + a2p(conn, html); + if((buffer = (char *)strstr(req, "\r\n\r\n")) == NULL) /* jump header */ + buffer = req; + memcpy(buf, buffer, BUF_SIZE-1); + buf[BUF_SIZE-1] = 0; + minus(buf); + if((ptr = (char *)strstr(buf, "content-disposition: ")) != NULL) + { + ptr2 = (char *)strstr(ptr-buf+buffer, "CheminFichier"); + if((ptr = (char *)strstr(ptr, "content-type: ")) != NULL) + { + ptr = ptr-buf+buffer; + i=0; /* mime decoding light !!! */ + while((*ptr++ != '\n') && (i < 4096)) + i++; + while((*ptr++ != '\n') && (i < 4096)) + i++; + len -= (unsigned long)(ptr-buffer); + ptr3 = ptr; /* beginning of file */ + if((i = strlen(conn->boundary)) != 0) + { + while(ptr3 < &ptr[len]) + { + if(*ptr3 == '-') + { + if(memcmp(ptr3, conn->boundary, i) == 0) + { + len = (unsigned long)(ptr3-ptr); /* fix size */ + if(ptr3[-4]== '\r' && ptr3[-3]== '\n' && ptr3[-2]== '-' && ptr3[-1]== '-') + len -= 4; + break; + } + } + ptr3++; + } + } + else /* normally unused in boundary found before */ + { + while(ptr3 < &ptr[len]) + { + if(*ptr3 == '-') + { + i=0; + while(ptr3[i++] == '-'); /* boundary -------------XXXXXXXXX */ + if(i >= 20) + { + if(ptr3[-1] == '\n') + ptr3--; + if(ptr3[-1] == '\r') + ptr3--; + len = (unsigned long)(ptr3-ptr); /* fix size */ + break; + } + } + ptr3++; + } + } + i=0; + while(i<40) /* beginning of file */ + { + if(((unsigned char)ptr[i])>=' '&& ((unsigned char)ptr[i])<='z' + && ptr[i]!='<' && ptr[i]!='>' && ptr[i]!='/' && ptr[i]!=';') + buf2[i] = ptr[i]; + else + buf2[i] = ' '; + i++; + } + buf2[i] = 0; + buf[0] = 0; + if(ptr2 != NULL) /* extract host path from POST string */ + { + i=0; + while((*ptr2++ != '\n') && (i < 4096)) + i++; + while((*ptr2++ != '\n') && (i < 4096)) + i++; + i=0; + while((ptr2[i] != '\n') && (ptr2[i] != '\r') && (i < BUF_SIZE)) + { + buf[i] = ptr2[i]; + i++; + } + buf[i] = 0; + } + /* chargement .HEX */ + Mem_Data = 0; + Flash = Error = 0; + sbuf_ptr = sbuf; + lowest_address = 0xFFFFFFFF; + hight_address = 0; + conv_rec(ptr, (long)len); + if(Error) + { + a2p(conn, "\n

Srecord file .HEX error : "); + a2p(conn, buf); + err = (int)copy_file(buf, ptr, (long)len); + a2p(conn, "

\nBeginning of the file [ "); + a2p(conn, buf2); + a2p(conn, " ]

\n"); + a2p(conn, buf); + if(err==0) + a2p(conn, "
File copied inside the disk
\n"); + a2p(conn, retour); + } + else + { + if(Flash) + { + if((err=Programmation(lowest_address,hight_address,lowest_address-FLASH_TOS_FIRE_ENGINE+Mem_Data)) < 0) + { + a2p(conn, "\n

Programming/verify error

\n"); + a2p(conn, retour); + } + else + { + a2p(conn, "\n
\n"); + a2p(conn, "

System copied in flash : "); + a2p(conn, buf); + a2p(conn, "


\n"); + a2p(conn, retour); + } + } + else + { + a2p(conn, "\n

File not for the flash : "); + a2p(conn, buf); + err = (int)copy_file(buf, ptr, (long)len); + a2p(conn, "


\n"); + if(err==0) + a2p(conn, "
File copied inside the ram disk
\n"); + a2p(conn, retour); + } + } + a2p(conn, end); + return; + } + } + a2p(conn, "\n

Content not valid


\n"); + a2p(conn, retour); + a2p(conn, end); +} + +static http_list m_http_list[] = { + { "GET", "/index.html", handle_menu, "text/html"}, + { "GET", "/menu.html", handle_menu, "text/html"}, + { "GET", "/mem.html", handle_mem, "text/html" }, + { "GET", "/gif/red_led.gif", show_red_led, "image/gif" }, + { "GET", "/gif/green_led.gif", show_green_led, "image/gif" }, + { "GET", "/sel_file.html", select_file, "text/html" }, + { "POST","/file.html", handle_file, "text/html" }, + { "GET", "/", handle_menu, "text/html" }, + { NULL, NULL, NULL, NULL } +}; + +static void handle_url(sock_conn *conn, char *request) +{ + int i = 0, size; + char *ptr; + char path[256]; + if((memcmp(request, "GET", 3) != 0) && (memcmp(request, "POST", 4) != 0)) + { + send_status_code(conn, 501); /* not implemented */ + return; + } + while(m_http_list[i].url != NULL) + { + size = strlen(m_http_list[i].method); + if(memcmp(request, m_http_list[i].method, size) == 0) + { + ptr = &request[size]; + if(*ptr == ' ') + ptr++; + if(memcmp(ptr, m_http_list[i].url, strlen(m_http_list[i].url)) == 0) + { + unsigned long time = gettime(); + send_status_code(conn, 200); /* OK */ + m_http_list[i].handle_url(conn, request); + send_date(conn, "Date: ", gettime()); + write_string(conn, "Server: LWIP/1.2.0\r\nAllow: GET, POST\r\nConnection: close\r\n"); + send_content_type(conn, m_http_list[i].content_type); + send_content_length(conn, conn->response_size); + send_date(conn, "Last-Modified: ", time); +// write_string(conn, "\r\n"); + write_socket(conn, "\r\n", 2 , 1); /* flush */ + /* write out the dynamically generated page */ + write_socket(conn, conn->response, conn->response_size, 1); /* flush */ + return; + } + } + i++; + } + if(memcmp(request, "GET", 3) == 0) + { + ptr = &request[3]; + if(*ptr == ' ') + ptr++; + if(strlen(ptr) < 200) + { + long handle, len; + char *buf; + strcpy(path, "C:\\html"); + strcat(path, ptr); + i = 3; + while(path[i]) + { + if(path[i] == '/') + path[i] = '\\'; + else if((path[i] == '?') || (path[i] == ' ')) + { + path[i] = '\0'; + break; + } + else if((path[i] >= 'A') && (path[i] <= 'Z')) + path[i] += 0x20; /* minus */ + i++; + } + handle = Fopen(path, 0); + if(handle >= 0) + { + len = Fseek(0, handle, 2); + if(len > 0) + { + Fseek(0, handle, 0); + buf = (char *)pvPortMalloc2(len); + if(buf) + { + if(Fread(handle, len, buf) >= 0) + { + char *p = &path[strlen(path)-3]; + unsigned long time = gettime(); + send_status_code(conn, 200); /* OK */ + send_date(conn, "Date: ", gettime()); + write_string(conn, "Server: LWIP/1.2.0\r\nAllow: GET, POST\r\nConnection: close\r\n"); + if(strcmp(p, "htm") == 0) + send_content_type(conn, "text/html"); + else if(strcmp(p, "css") == 0) + send_content_type(conn, "text/css"); + else if(strcmp(p, "gif") == 0) + send_content_type(conn, "image/gif"); + else if(strcmp(p, "jpg") == 0) + send_content_type(conn, "image/jpeg"); + else if(strcmp(p, "png") == 0) + send_content_type(conn, "image/png"); + else if(strcmp(p, "wav") == 0) + send_content_type(conn, "audio/x-wav"); + else if(strcmp(p, "mpg") == 0) + send_content_type(conn, "video/mpg"); + else if(strcmp(p, "pdf") == 0) + send_content_type(conn, "application/pdf"); + else if(strcmp(p, "jar") == 0) + send_content_type(conn, "application/x-java-archive"); + else + send_content_type(conn, "application/octet-stream"); + send_content_length(conn, len); + send_date(conn, "Last-Modified: ", time); + write_string(conn, "\r\n"); + write_socket(conn, buf, len, 1); /* flush */ + vPortFree2(buf); + Fclose(handle); + return; + } + } + vPortFree2(buf); + } + Fclose(handle); + } + } + } + send_status_code(conn, 404); /* not found */ +} + +/* + * Process an incoming connection on port 80. + * + * This simply checks to see if the incoming data contains a GET request, and + * if so sends back a single dynamically created page. The connection is then + * closed. + */ +static void vProcessConnection(void *pvParameters) +{ + sock_msg *msg; + sock_conn conn; + char *pcRxString, *pcRxStringMinus; + char *ptr, *ptr2; + int sock, len, size_header, i; + int task = (int)pvParameters; + if(task); + conn.buf_write = (char *)pvPortMalloc2(WRITEBUF_SIZE); + pcRxString = (char *)pvPortMalloc2(READBUF_SIZE+1); + pcRxStringMinus = (char *)pvPortMalloc2(READBUF_SIZE+1); + if((mbox == NULL) || (conn.buf_write == NULL) + || (pcRxString == NULL) || (pcRxStringMinus == NULL)) + { + while(1) + vTaskDelay(1); + } + while(1) + { + if(!xQueueReceive(mbox, &msg, portMAX_DELAY)) + continue; + sock = msg->sock; + conn.response_max_size = WRITEBUF_SIZE; + conn.response = (char *)pvPortMalloc2(conn.response_max_size); + conn.content_length = size_header = 0; + conn.errno = conn.response_size = conn.offset_buf_write = 0; + conn.sock = sock; + conn.boundary[0] = 0; + if(conn.response != NULL) + { + /* We expect to immediately get data */ + if((len = read_socket(&conn, pcRxString, READBUF_SIZE, &size_header)) >= 0) + { + if(strstr(pcRxString, "HTTP/1.0") != NULL) + conn.version = VERSION_10; + else if(strstr(pcRxString, "HTTP/1.1") != NULL) + conn.version = VERSION_11; + else + conn.version = VERSION_UNKNOWN; + strcpy(pcRxStringMinus, pcRxString); + minus(pcRxStringMinus); + if((ptr = (char *)strstr(pcRxStringMinus, "content-length: ")) != NULL) + conn.content_length = (int)atol(&ptr[16]); + if(conn.content_length) + { + if(((ptr = (char *)strstr(pcRxStringMinus, "content-type: multipart/form-data")) != NULL) + && ((ptr = (char *)strstr(ptr, "boundary=")) != NULL)) + { + ptr+=9; + ptr2 = conn.boundary; + i = 0; + while(*ptr && (*ptr != '\r') && (*ptr != '\n') && (*ptr != ';') && (i < 255)) + *ptr2++ = *ptr++; + *ptr2 = 0; + } + ptr = (char *)pvPortMalloc2(size_header+conn.content_length+1); + if(ptr != NULL) + { + memcpy(ptr, pcRxString, len); + if(conn.content_length-len+size_header > 0) + read_socket(&conn, &ptr[len], conn.content_length-len+size_header, NULL); + } + ptr2 = ptr; + } + else + { + ptr = NULL; + ptr2 = pcRxString; + } + conn.errno = 0; + handle_url(&conn, ptr2); + if(ptr != NULL) + vPortFree2(ptr); + } + vPortFree2(conn.response); + } + close(sock); + } +} + +/*------------------------------------------------------------*/ + +void vBasicWEBServer(void *pvParameters) +{ + static sock_msg msg; + sock_msg *pmsg; + char name[5]; + int sock, newsock, len = sizeof(struct sockaddr_in); + static struct sockaddr_in address; + int task; + if(pvParameters); + mbox = xQueueCreate(10, sizeof(sock_msg)); + for(task = 0; task < TASKS_SERVER; task++) + { + name[0] = 'H'; + name[1] = 'T'; + name[2] = '0' + (char)((task + 1) / 10); + name[3] = '0' + (char)((task + 1) % 10); + name[4] = '\0'; + xTaskCreate(vProcessConnection, (void *)name, configMINIMAL_STACK_SIZE, (void *)task, 9, NULL); + } + /* Create a new tcp connection handle */ + if((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) + { + while(1) + vTaskDelay(1); + } + else + { + int iOptVal = TRUE; + setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&iOptVal, sizeof(iOptVal)); + int nodelay = TRUE; + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char *)&nodelay, sizeof(nodelay)); + } + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(INADDR_ANY); + address.sin_port = htons(webHTTP_PORT); + if((bind(sock, (struct sockaddr *)&address, len) == -1) + || (listen(sock, 5) == -1)) + { + close(sock); + while(1) + vTaskDelay(1); + } + /* Loop forever */ + while(1) + { + len = sizeof(address); + newsock = accept(sock, (struct sockaddr*)&address, &len); + if(newsock != -1) + { + /* Service connection */ + if(mbox != NULL) + { + pmsg = &msg; + pmsg->sock = newsock; + xQueueSend(mbox, &pmsg, 100); + } + } + vTaskDelay(1); + } +} + +#endif /* LWIP */ diff --git a/flash.tos/drivers/m68k_disasm.c b/flash.tos/drivers/m68k_disasm.c index e851aae..8d74466 100644 --- a/flash.tos/drivers/m68k_disasm.c +++ b/flash.tos/drivers/m68k_disasm.c @@ -72,14 +72,10 @@ * Christian E. Hopps. */ - /* M.D. (04.07.2011) added CF instructions and length opcode functions - TODO: mac instruction group (line A) - */ + /* M.D. (04.07.2011) added CF instructions and length opcode functions */ #include "config.h" -#ifdef DBUG - #define M68K_DISASM_C #include #include @@ -4532,5 +4528,3 @@ void print_RnPlus(dis_buffer_t *dbuf, u_short opc, int An, int sb, int inc) *dbuf->casm = 0; } -#endif /* DBUG */ - diff --git a/flash.tos/drivers/malloc.c b/flash.tos/drivers/malloc.c new file mode 100644 index 0000000..a2e1639 --- /dev/null +++ b/flash.tos/drivers/malloc.c @@ -0,0 +1,297 @@ +/* + * malloc.c + * + * based from Emutos / BDOS + * + * Copyright (c) 2001 Lineo, Inc. + * + * Authors: Karl T. Braun, Martin Doering, Laurent Vogel + * + * This file is distributed under the GPL, version 2 or at your + * option any later version. + */ + +#include +#include +#include +#include "../include/pci_bios.h" + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define USE_MXALLOC +#undef DRIVERS_MEM_DEBUG + +#ifdef DRIVERS_MEM_DEBUG +extern void kprint(const char *fmt, ...); +extern short drive_ok; +//#define DRIVERS_MEM_PRINTF(fmt,args...) if(drive_ok) kprint(fmt ,##args) +#define DRIVERS_MEM_PRINTF(fmt,args...) kprint(fmt ,##args) +#else +#define DRIVERS_MEM_PRINTF(fmt,args...) +#endif + +#ifdef USE_MXALLOC + +int free(void *addr) +{ + DRIVERS_MEM_PRINTF("free(0x%08X)\r\n", addr); + Mfree(addr); + return(0); +} + +void *malloc(long amount) +{ + void *ret = (void *)Mxalloc(amount, 3); + DRIVERS_MEM_PRINTF("malloc(%d) = 0x%08X\r\n", amount, ret); + return(ret); +} + +#else /* !USE_MXALLOC */ + +extern char _bss_start[]; +extern char _end[]; + +static void *drivers_buffer; +extern int asm_set_ipl(int level); + +/* MD - Memory Descriptor */ + +#define MD struct _md_ + +MD +{ + MD *m_link; + long m_start; + long m_length; + void *m_own; +}; + +/* MPB - Memory Partition Block */ + +#define MPB struct _mpb + +MPB +{ + MD *mp_mfl; + MD *mp_mal; + MD *mp_rover; +}; + +#define MAXMD 256 + +static MD tab_md[MAXMD]; +static MPB pmd; + +static void *xmgetblk(void) +{ + int i; + for(i = 0; i < MAXMD; i++) + { + if(tab_md[i].m_own == NULL) + { + tab_md[i].m_own = (void*)1L; + return(&tab_md[i]); + } + } + return(NULL); +} + +static void xmfreblk(void *m) +{ + int i = (int)(((long)m - (long)tab_md) / sizeof(MD)); + if((i > 0) && (i < MAXMD)) + tab_md[i].m_own = NULL; +} + +static MD *ffit(long amount, MPB *mp) +{ + MD *p,*q,*p1; /* free list is composed of MD's */ + int maxflg; + long maxval; + if(amount != -1) + { + amount += 15; /* 16 bytes alignment */ + amount &= 0xFFFFFFF0; + } + if((q = mp->mp_rover) == 0) /* get rotating pointer */ + return(0) ; + maxval = 0; + maxflg = ((amount == -1) ? TRUE : FALSE) ; + p = q->m_link; /* start with next MD */ + do /* search the list for an MD with enough space */ + { + if(p == 0) + { + /* at end of list, wrap back to start */ + q = (MD *) &mp->mp_mfl; /* q => mfl field */ + p = q->m_link; /* p => 1st MD */ + } + if((!maxflg) && (p->m_length >= amount)) + { + /* big enough */ + if(p->m_length == amount) + q->m_link = p->m_link; /* take the whole thing */ + else + { + /* break it up - 1st allocate a new + MD to describe the remainder */ + p1 = xmgetblk(); + if(p1 == NULL) + return(NULL); + /* init new MD */ + p1->m_length = p->m_length - amount; + p1->m_start = p->m_start + amount; + p1->m_link = p->m_link; + p->m_length = amount; /* adjust allocated block */ + q->m_link = p1; + } + /* link allocate block into allocated list, + mark owner of block, & adjust rover */ + p->m_link = mp->mp_mal; + mp->mp_mal = p; + mp->mp_rover = (q == (MD *) &mp->mp_mfl ? q->m_link : q); + return(p); /* got some */ + } + else if(p->m_length > maxval) + maxval = p->m_length; + p = ( q=p )->m_link; + } + while(q != mp->mp_rover); + /* return either the max, or 0 (error) */ + if(maxflg) + { + maxval -= 15; /* 16 bytes alignment */ + if(maxval < 0) + maxval = 0; + else + maxval &= 0xFFFFFFF0; + } + return(maxflg ? (MD *) maxval : 0); +} + +static void freeit(MD *m, MPB *mp) +{ + MD *p, *q; + q = 0; + for(p = mp->mp_mfl; p ; p = (q=p) -> m_link) + { + if(m->m_start <= p->m_start) + break; + } + m->m_link = p; + if(q) + q->m_link = m; + else + mp->mp_mfl = m; + if(!mp->mp_rover) + mp->mp_rover = m; + if(p) + { + if(m->m_start + m->m_length == p->m_start) + { /* join to higher neighbor */ + m->m_length += p->m_length; + m->m_link = p->m_link; + if(p == mp->mp_rover) + mp->mp_rover = m; + xmfreblk(p); + } + } + if(q) + { + if(q->m_start + q->m_length == m->m_start) + { /* join to lower neighbor */ + q->m_length += m->m_length; + q->m_link = m->m_link; + if(m == mp->mp_rover) + mp->mp_rover = q; + xmfreblk(m); + } + } +} + +int free(void *addr) +{ + int level; + MD *p, **q; + MPB *mpb; + mpb = &pmd; + if(drivers_buffer == NULL) + return(EFAULT); + level = asm_set_ipl(7); + for(p = *(q = &mpb->mp_mal); p; p = *(q = &p->m_link)) + { + if((long)addr == p->m_start) + break; + } + if(!p) + { + asm_set_ipl(level); + return(EFAULT); + } + *q = p->m_link; + freeit(p, mpb); + asm_set_ipl(level); + DRIVERS_MEM_PRINTF("free(0x%08X)\r\n", addr); + return(0); +} + +void *malloc(long amount) +{ + void *ret = NULL; + int level; + MD *m; + if(drivers_buffer == NULL) + return(NULL); + if(amount == -1L) + return((void *)ffit(-1L,&pmd)); + if(amount <= 0 ) + return(0); + if((amount & 1)) + amount++; + level = asm_set_ipl(7); + m = ffit(amount, &pmd); + if(m != NULL) + ret = (void *)m->m_start; + asm_set_ipl(level); + DRIVERS_MEM_PRINTF("malloc(%d) = 0x%08X\r\n", amount, ret); + return(ret); +} + +#endif /* USE_MXALLOC */ + +void *realloc(void *ptr, int size) +{ + void *ret = malloc(size); + if(ret != NULL) + { + memcpy(ret, ptr, size); + free(ptr); + DRIVERS_MEM_PRINTF("realloc(0x%08X, %d) = 0x%08X\r\n", ptr, size, ret); + return ret; + } + free(ptr); + DRIVERS_MEM_PRINTF("realloc(0x%08X, %d) = 0x00000000\r\n", ptr, size); + return NULL; +} + +int drivers_mem_init(void) +{ +#ifndef USE_MXALLOC + if(drivers_buffer != NULL) + return(0); + pmd.mp_mfl = pmd.mp_rover = &tab_md[0]; + tab_md[0].m_link = (MD *)NULL; + drivers_buffer = (void *)(((long)_end + 15) & 0xFFFFFFF0); /* 16 bytes alignment */ + tab_md[0].m_start = (long)drivers_buffer; + tab_md[0].m_length = PCI_DRIVERS_SIZE - ((long)drivers_buffer - (long)_bss_start); + tab_md[0].m_own = (void *)1L; + pmd.mp_mal = (MD *)NULL; + memset(drivers_buffer, 0, tab_md[0].m_length); +#endif /* USE_MXALLOC */ + return(0); +} diff --git a/flash.tos/drivers/mcdapi/MCD_dmaApi.c b/flash.tos/drivers/mcdapi/MCD_dmaApi.c index 8a04dd2..16cb522 100644 --- a/flash.tos/drivers/mcdapi/MCD_dmaApi.c +++ b/flash.tos/drivers/mcdapi/MCD_dmaApi.c @@ -44,7 +44,7 @@ #include "MCD_tasksInit.h" #include "MCD_progCheck.h" -#ifdef NETWORK +#ifdef LWIP /********************************************************************/ /* @@ -979,4 +979,4 @@ static void MCD_memcpy (int *dest, int *src, u32 size) } /********************************************************************/ -#endif /* NETWORK */ +#endif /* LWIP */ diff --git a/flash.tos/drivers/mcdapi/MCD_tasks.c b/flash.tos/drivers/mcdapi/MCD_tasks.c index 90cfac9..f164ff0 100644 --- a/flash.tos/drivers/mcdapi/MCD_tasks.c +++ b/flash.tos/drivers/mcdapi/MCD_tasks.c @@ -41,7 +41,7 @@ #include "config.h" #include "MCD_dma.h" -#ifdef NETWORK +#ifdef LWIP u32 MCD_varTab0[]; u32 MCD_varTab1[]; diff --git a/flash.tos/drivers/mcdapi/MCD_tasksInit.c b/flash.tos/drivers/mcdapi/MCD_tasksInit.c index 563155d..2674b96 100644 --- a/flash.tos/drivers/mcdapi/MCD_tasksInit.c +++ b/flash.tos/drivers/mcdapi/MCD_tasksInit.c @@ -45,7 +45,7 @@ #include "config.h" #include "MCD_dma.h" -#ifdef NETWORK +#ifdef LWIP extern dmaRegs *MCD_dmaBar; @@ -288,4 +288,4 @@ void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr, volati } -#endif /* NETWORK */ +#endif /* LWIP */ diff --git a/flash.tos/drivers/net/am79c874.c b/flash.tos/drivers/net/am79c874.c deleted file mode 100644 index 46d5527..0000000 --- a/flash.tos/drivers/net/am79c874.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * File: am79c874.c - * Purpose: Driver for the AMD AM79C874 10/100 Ethernet PHY - */ - -#include "config.h" -#include "net.h" -#include "fec.h" -#include "am79c874.h" - -#ifdef NETWORK -#ifndef LWIP - -#undef DEBUG - -#ifdef DEBUG -extern void conws_debug(char *buf); -#endif - -/********************************************************************/ -/* Initialize the AM79C874 PHY - * - * This function sets up the Auto-Negotiate Advertisement register - * within the PHY and then forces the PHY to auto-negotiate for - * it's settings. - * - * Params: - * fec_ch FEC channel - * phy_addr Address of the PHY. - * speed Desired speed (10BaseT or 100BaseTX) - * duplex Desired duplex (Full or Half) - * - * Return Value: - * 0 if MII commands fail - * 1 otherwise - */ -int am79c874_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex) -{ - int timeout; - uint16 settings; - if(speed); /* to do */ - if(duplex); /* to do */ - - /* Initialize the MII interface */ - fec_mii_init(fec_ch, SYSTEM_CLOCK); -#ifdef DEBUG - conws_debug("PHY reset\r\n"); -#endif - /* Reset the PHY */ - if(!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_RESET)) - return 0; - /* Wait for the PHY to reset */ - for(timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) - { - fec_mii_read(fec_ch, phy_addr, MII_AM79C874_CR, &settings); - if(!(settings & MII_AM79C874_CR_RESET)) - break; - } - if(timeout >= FEC_MII_TIMEOUT) - return 0; -#ifdef DEBUG - conws_debug("PHY reset OK\r\n"); -#endif -#ifdef DEBUG - conws_debug("PHY Enable Auto-Negotiation\r\n"); -#endif - /* Enable Auto-Negotiation */ - if(!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_AUTON | MII_AM79C874_CR_RST_NEG)) - return 0; -#ifdef DEBUG - conws_debug("PHY Wait for auto-negotiation to complete\r\n"); -#endif - /* Wait for auto-negotiation to complete */ - for(timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) - { - settings = 0; - fec_mii_read(fec_ch, phy_addr, MII_AM79C874_SR, &settings); - if((settings & AUTONEGLINK) == AUTONEGLINK) - break; - } - if(timeout >= FEC_MII_TIMEOUT) - { -#ifdef DEBUG - conws_debug("PHY Set the default mode\r\n"); -#endif - /* Set the default mode (Full duplex, 100 Mbps) */ - if(!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_100MB | MII_AM79C874_CR_DPLX)) - return 0; - } -#ifdef DEBUG - settings = 0; - fec_mii_read(fec_ch, phy_addr, MII_AM79C874_DR, &settings); - conws_debug("PHY Mode: "); - if(settings & MII_AM79C874_DR_DATA_RATE) - conws_debug("100Mbps "); - else - conws_debug("10Mbps "); - if(settings & MII_AM79C874_DR_DPLX) - conws_debug("Full-duplex\r\n"); - else - conws_debug("Half-duplex\r\n"); - conws_debug("PHY auto-negociation complete\r\n"); -#endif - return 1; -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/am79c874.h b/flash.tos/drivers/net/am79c874.h deleted file mode 100644 index 2cfca74..0000000 --- a/flash.tos/drivers/net/am79c874.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * File: am79c874.h - * Purpose: Driver for the AM79C874 10/100 Ethernet PHY - * - * Notes: - */ - -#ifndef _AM79C874_H_ -#define _AM79C874_H_ - -/********************************************************************/ - -int am79c874_init(uint8, uint8, uint8, uint8); - -/********************************************************************/ - -/* MII Register Addresses */ -#define MII_AM79C874_CR 0 /* MII Management Control Register */ -#define MII_AM79C874_SR 1 /* MII Management Status Register */ -#define MII_AM79C874_PHYIDR1 2 /* PHY Identifier 1 Register */ -#define MII_AM79C874_PHYIDR2 3 /* PHY Identifier 2 Register */ -#define MII_AM79C874_ANAR 4 /* Auto-Negociation Advertissement Register */ -#define MII_AM79C874_ANLPAR 5 /* Auto-Negociation Link Partner Register */ -#define MII_AM79C874_ANER 6 /* Auto-Negociation Expansion Register */ -#define MII_AM79C874_ANNPTR 7 /* Next Page Advertisement Register */ -#define MII_AM79C874_MFR 16 /* Miscellaneous Feature Register */ -#define MII_AM79C874_ICSR 17 /* Interrupt/Status Register */ -#define MII_AM79C874_DR 18 /* Diagnostic Register */ -#define MII_AM79C874_PMLR 19 /* Power and Loopback Register */ -#define MII_AM79C874_MCR 21 /* ModeControl Register */ -#define MII_AM79C874_DC 23 /* Disconnect Counter */ -#define MII_AM79C874_REC 24 /* Recieve Error Counter */ - -/* Bit definitions and macros for MII_AM79C874_CR */ -#define MII_AM79C874_CR_RESET (0x8000) -#define MII_AM79C874_CR_LOOP (0x4000) -#define MII_AM79C874_CR_100MB (0x2000) -#define MII_AM79C874_CR_AUTON (0x1000) -#define MII_AM79C874_CR_POWD (0x0800) -#define MII_AM79C874_CR_ISO (0x0400) -#define MII_AM79C874_CR_RST_NEG (0x0200) -#define MII_AM79C874_CR_DPLX (0x0100) -#define MII_AM79C874_CR_COL_TST (0x0080) -#define MII_AM79C874_CR_SPEED_MASK (0x2040) -#define MII_AM79C874_CR_1000_MPS (0x0040) -#define MII_AM79C874_CR_100_MPS (0x2000) -#define MII_AM79C874_CR_10_MPS (0x0000) - -/* Bit definitions and macros for MII_AM79C874_SR */ -#define MII_AM79C874_SR_100T4 (0x8000) -#define MII_AM79C874_SR_100TXF (0x4000) -#define MII_AM79C874_SR_100TXH (0x2000) -#define MII_AM79C874_SR_10TF (0x1000) -#define MII_AM79C874_SR_10TH (0x0800) -#define MII_AM79C874_SR_PRE_SUP (0x0040) -#define MII_AM79C874_SR_AUTN_COMP (0x0020) -#define MII_AM79C874_SR_RF (0x0010) -#define MII_AM79C874_SR_AUTN_ABLE (0x0008) -#define MII_AM79C874_SR_LS (0x0004) -#define MII_AM79C874_SR_JD (0x0002) -#define MII_AM79C874_SR_EXT (0x0001) - -/* Bit definitions and macros for MII_AM79C874_ANLPAR */ -#define MII_AM79C874_ANLPAR_NP (0x8000) -#define MII_AM79C874_ANLPAR_ACK (0x4000) -#define MII_AM79C874_ANLPAR_RF (0x2000) -#define MII_AM79C874_ANLPAR_T4 (0x0200) -#define MII_AM79C874_ANLPAR_TXFD (0x0100) -#define MII_AM79C874_ANLPAR_TX (0x0080) -#define MII_AM79C874_ANLPAR_10FD (0x0040) -#define MII_AM79C874_ANLPAR_10 (0x0020) -#define MII_AM79C874_ANLPAR_100 (0x0380) -#define MII_AM79C874_ANLPAR_PSB_MASK (0x001F) -#define MII_AM79C874_ANLPAR_PSB_802_3 (0x0001) -#define MII_AM79C874_ANLPAR_PSB_802_9 (0x0002) - -/* Bit definitions and macros for MII_AM79C874_DR */ -#define MII_AM79C874_DR_DPLX (0x0800) -#define MII_AM79C874_DR_DATA_RATE (0x0400) -#define MII_AM79C874_DR_RX_PASS (0x0200) -#define MII_AM79C874_DR_RX_LOCK (0x0100) - -#define AUTONEGLINK (MII_AM79C874_SR_AUTN_COMP | MII_AM79C874_SR_LS) - -/********************************************************************/ - -#endif /* _AM79C874_H_ */ diff --git a/flash.tos/drivers/net/arp.c b/flash.tos/drivers/net/arp.c deleted file mode 100644 index a21c0ec..0000000 --- a/flash.tos/drivers/net/arp.c +++ /dev/null @@ -1,475 +0,0 @@ -/* - * File: arp.c - * Purpose: Address Resolution Protocol routines. - * - * Notes: - */ -#include -#include "config.h" -#include "net.h" -#include "net_timer.h" - -#ifdef NETWORK -#ifndef LWIP - -/********************************************************************/ -static uint8 * -arp_find_pair (ARP_INFO *arptab, uint16 protocol, uint8 *hwa, uint8 *pa) -{ - /* - * This function searches through the ARP table for the - * specified or address pair. - * If it is found, then a a pointer to the non-specified - * address is returned. Otherwise NULL is returned. - * If you pass in then you get out. - * If you pass in then you get out. - */ - int slot, i, match = FALSE; - uint8 *rvalue; - - if (((hwa == 0) && (pa == 0)) || (arptab == 0)) - return NULL; - - rvalue = NULL; - - /* - * Check each protocol address for a match - */ - for (slot = 0; slot < arptab->tab_size; slot++) - { - if ((arptab->table[slot].longevity != ARP_ENTRY_EMPTY) && - (arptab->table[slot].protocol == protocol)) - { - match = TRUE; - if (hwa != 0) - { - /* - * Check the Hardware Address field - */ - rvalue = &arptab->table[slot].pa[0]; - for (i = 0; i < arptab->table[slot].hwa_size; i++) - { - if (arptab->table[slot].hwa[i] != hwa[i]) - { - match = FALSE; - break; - } - } - } - else - { - /* - * Check the Protocol Address field - */ - rvalue = &arptab->table[slot].hwa[0]; - for (i = 0; i < arptab->table[slot].pa_size; i++) - { - if (arptab->table[slot].pa[i] != pa[i]) - { - match = FALSE; - break; - } - } - } - if (match) - { - break; - } - } - } - - if (match) - return rvalue; - else - return NULL; -} -/********************************************************************/ -void -arp_merge(ARP_INFO *arptab, uint16 protocol, int hwa_size, uint8 *hwa, - int pa_size, uint8 *pa, int longevity) -{ - /* - * This function merges an entry into the ARP table. If - * either piece is NULL, the function exits, otherwise - * the entry is merged or added, provided there is space. - */ - int i, slot; - uint8 *ta; - - if ((hwa == NULL) || (pa == NULL) || (arptab == NULL) || - ((longevity != ARP_ENTRY_TEMP) && - (longevity != ARP_ENTRY_PERM))) - { - return; - } - - /* First search ARP table for existing entry */ - if ((ta = arp_find_pair(arptab,protocol,NULL,pa)) != 0) - { - /* Update hardware address */ - for (i = 0; i < hwa_size; i++) - ta[i] = hwa[i]; - return; - } - - /* Next try to find an empty slot */ - slot = -1; - for (i = 0; i < MAX_ARP_ENTRY; i++) - { - if (arptab->table[i].longevity == ARP_ENTRY_EMPTY) - { - slot = i; - break; - } - } - - /* if no empty slot was found, pick a temp slot */ - if (slot == -1) - { - for (i = 0; i < MAX_ARP_ENTRY; i++) - { - if (arptab->table[i].longevity == ARP_ENTRY_TEMP) - { - slot = i; - break; - } - } - } - - /* if after all this, still no slot found, add in last slot */ - if (slot == -1) - slot = (MAX_ARP_ENTRY -1); - - /* add the entry into the slot */ - arptab->table[slot].protocol = protocol; - - arptab->table[slot].hwa_size = (uint8) hwa_size; - for (i = 0; i < hwa_size; i++) - arptab->table[slot].hwa[i] = hwa[i]; - - arptab->table[slot].pa_size = (uint8) pa_size; - for (i = 0; i < pa_size; i++) - arptab->table[slot].pa[i] = pa[i]; - - arptab->table[slot].longevity = longevity; -} - -/********************************************************************/ -void -arp_remove (ARP_INFO *arptab, uint16 protocol, uint8 *hwa, uint8 *pa) -{ - /* - * This function removes an entry from the ARP table. The - * ARP table is searched according to the non-NULL address - * that is provided. - */ - int slot, i, match; - - if (((hwa == 0) && (pa == 0)) || (arptab == 0)) - return; - - /* check each hardware adress for a match */ - for (slot = 0; slot < arptab->tab_size; slot++) - { - if ((arptab->table[slot].longevity != ARP_ENTRY_EMPTY) && - (arptab->table[slot].protocol == protocol)) - { - match = TRUE; - if (hwa != 0) - { - /* Check Hardware Address field */ - for (i = 0; i < arptab->table[slot].hwa_size; i++) - { - if (arptab->table[slot].hwa[i] != hwa[i]) - { - match = FALSE; - break; - } - } - } - else - { - /* Check Protocol Address field */ - for (i = 0; i < arptab->table[slot].pa_size; i++) - { - if (arptab->table[slot].pa[i] != pa[i]) - { - match = FALSE; - break; - } - } - } - if (match) - { - for (i = 0; i < arptab->table[slot].hwa_size; i++) - arptab->table[slot].hwa[i] = 0; - for (i = 0; i < arptab->table[slot].pa_size; i++) - arptab->table[slot].pa[i] = 0; - arptab->table[slot].longevity = ARP_ENTRY_EMPTY; - break; - } - } - } -} -/********************************************************************/ -void -arp_request (NIF *nif, uint8 *pa) -{ - /* - * This function broadcasts an ARP request for the protocol - * address "pa" - */ - uint8 *addr; - NBUF *pNbuf; - arp_frame_hdr *arpframe; - int i, result; - - pNbuf = nbuf_alloc(); - if (pNbuf == NULL) - { - #if defined(DEBUG_PRINT) - Cconws("ARP: arp_request couldn't allocate Tx buffer\r\n"); - #endif - return; - } - - arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET]; - - /* Build the ARP request packet */ - arpframe->ar_hrd = ETHERNET; - arpframe->ar_pro = ETH_FRM_IP; - arpframe->ar_hln = 6; - arpframe->ar_pln = 4; - arpframe->opcode = ARP_REQUEST; - - addr = &nif->hwa[0]; - for (i = 0; i < 6; i++) - arpframe->ar_sha[i] = addr[i]; - - addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); - for (i = 0; i < 4; i++) - arpframe->ar_spa[i] = addr[i]; - - for (i = 0; i < 6; i++) - arpframe->ar_tha[i] = 0x00; - - for (i = 0; i < 4; i++) - arpframe->ar_tpa[i] = pa[i]; - - pNbuf->length = ARP_HDR_LEN; - - /* Send the ARP request */ - result = nif->send(nif->broadcast, nif->hwa, ETH_FRM_ARP, pNbuf); - - if (result == 0) - nbuf_free(pNbuf); -} -/********************************************************************/ -static int -arp_resolve_pa (NIF *nif, uint16 protocol, uint8 *pa, uint8 **ha) -{ - /* - * This function accepts a pointer to a protocol address and - * searches the ARP table for a hardware address match. If no - * no match found, FALSE is returned. - */ - ARP_INFO *arptab; - - if ((pa == NULL) || (nif == NULL) || (protocol == 0)) - return 0; - - arptab = nif_get_protocol_info (nif,ETH_FRM_ARP); - *ha = arp_find_pair(arptab,protocol,0,pa); - - if (*ha == NULL) - return 0; - else - return 1; -} -/********************************************************************/ -uint8 * -arp_resolve (NIF *nif, uint16 protocol, uint8 *pa) -{ - int i; - uint8 *hwa; - - /* - * Check to see if the necessary MAC-to-IP translation information - * is in table already - */ - if (arp_resolve_pa (nif, protocol, pa, &hwa)) - return hwa; - - /* - * Ok, it's not, so we need to try to obtain it by broadcasting - * an ARP request. Hopefully the desired host is listening and - * will respond with it's MAC address - */ - for (i = 0; i < 3; i++) - { - arp_request (nif, pa); - - timer_set_secs(TIMER_NETWORK, ARP_TIMEOUT); - while (timer_get_reference(TIMER_NETWORK)) - { - if (arp_resolve_pa (nif, protocol, pa, &hwa)) - return hwa; - } - } - - return NULL; -} -/********************************************************************/ -void -arp_init (ARP_INFO *arptab) -{ - int slot, i; - - arptab->tab_size = MAX_ARP_ENTRY; - for (slot = 0; slot < arptab->tab_size; slot++) - { - for (i = 0; i < MAX_HWA_SIZE; i++) - arptab->table[slot].hwa[i] = 0; - for (i = 0; i < MAX_PA_SIZE; i++) - arptab->table[slot].pa[i] = 0; - arptab->table[slot].longevity = ARP_ENTRY_EMPTY; - arptab->table[slot].hwa_size = 0; - arptab->table[slot].pa_size = 0; - } -} -/********************************************************************/ -void -arp_handler (NIF *nif, NBUF *pNbuf) -{ - /* - * ARP protocol handler - */ - uint8 *addr; - ARP_INFO *arptab; - int longevity; - arp_frame_hdr *rx_arpframe, *tx_arpframe; - - arptab = nif_get_protocol_info(nif, ETH_FRM_ARP); - rx_arpframe = (arp_frame_hdr *)&pNbuf->data[pNbuf->offset]; - - /* - * Check for an appropriate ARP packet - */ - if ((pNbuf->length < ARP_HDR_LEN) || - (rx_arpframe->ar_hrd != ETHERNET) || - (rx_arpframe->ar_hln != 6) || - (rx_arpframe->ar_pro != ETH_FRM_IP) || - (rx_arpframe->ar_pln != 4)) - { - nbuf_free(pNbuf); - return; - } - - /* - * Check to see if it was addressed to me - if it was, keep this - * ARP entry in the table permanently; if not, mark it so that it - * can be displaced later if necessary - */ - addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); - if ((rx_arpframe->ar_tpa[0] == addr[0]) && - (rx_arpframe->ar_tpa[1] == addr[1]) && - (rx_arpframe->ar_tpa[2] == addr[2]) && - (rx_arpframe->ar_tpa[3] == addr[3]) ) - { - longevity = ARP_ENTRY_PERM; - } - else - longevity = ARP_ENTRY_TEMP; - - /* - * Add ARP info into the table - */ - arp_merge(arptab, - rx_arpframe->ar_pro, - rx_arpframe->ar_hln, - &rx_arpframe->ar_sha[0], - rx_arpframe->ar_pln, - &rx_arpframe->ar_spa[0], - longevity - ); - - switch (rx_arpframe->opcode) - { - case ARP_REQUEST: - /* - * Check to see if request is directed to me - */ - if ((rx_arpframe->ar_tpa[0] == addr[0]) && - (rx_arpframe->ar_tpa[1] == addr[1]) && - (rx_arpframe->ar_tpa[2] == addr[2]) && - (rx_arpframe->ar_tpa[3] == addr[3]) ) - { - /* - * Reuse the current network buffer to assemble an ARP reply - */ - tx_arpframe = (arp_frame_hdr *)&pNbuf->data[ARP_HDR_OFFSET]; - - /* - * Build new ARP frame from the received data - */ - tx_arpframe->ar_hrd = ETHERNET; - tx_arpframe->ar_pro = ETH_FRM_IP; - tx_arpframe->ar_hln = 6; - tx_arpframe->ar_pln = 4; - tx_arpframe->opcode = ARP_REPLY; - tx_arpframe->ar_tha[0] = rx_arpframe->ar_sha[0]; - tx_arpframe->ar_tha[1] = rx_arpframe->ar_sha[1]; - tx_arpframe->ar_tha[2] = rx_arpframe->ar_sha[2]; - tx_arpframe->ar_tha[3] = rx_arpframe->ar_sha[3]; - tx_arpframe->ar_tha[4] = rx_arpframe->ar_sha[4]; - tx_arpframe->ar_tha[5] = rx_arpframe->ar_sha[5]; - tx_arpframe->ar_tpa[0] = rx_arpframe->ar_spa[0]; - tx_arpframe->ar_tpa[1] = rx_arpframe->ar_spa[1]; - tx_arpframe->ar_tpa[2] = rx_arpframe->ar_spa[2]; - tx_arpframe->ar_tpa[3] = rx_arpframe->ar_spa[3]; - - /* - * Now copy in the new information - */ - addr = &nif->hwa[0]; - tx_arpframe->ar_sha[0] = addr[0]; - tx_arpframe->ar_sha[1] = addr[1]; - tx_arpframe->ar_sha[2] = addr[2]; - tx_arpframe->ar_sha[3] = addr[3]; - tx_arpframe->ar_sha[4] = addr[4]; - tx_arpframe->ar_sha[5] = addr[5]; - - addr = ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)); - tx_arpframe->ar_spa[0] = addr[0]; - tx_arpframe->ar_spa[1] = addr[1]; - tx_arpframe->ar_spa[2] = addr[2]; - tx_arpframe->ar_spa[3] = addr[3]; - - /* - * Save the length of my packet in the buffer structure - */ - pNbuf->length = ARP_HDR_LEN; - - nif->send(&tx_arpframe->ar_tha[0], - &tx_arpframe->ar_sha[0], - ETH_FRM_ARP, - pNbuf); - } - else - nbuf_free(pNbuf); - break; - case ARP_REPLY: - /* - * The ARP Reply case is already taken care of - */ - default: - nbuf_free(pNbuf); - break; - } - - return; -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/arp.h b/flash.tos/drivers/net/arp.h deleted file mode 100644 index d9096c4..0000000 --- a/flash.tos/drivers/net/arp.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * File: arp.h - * Purpose: ARP definitions. - * - * Notes: - */ - -#ifndef _ARP_H -#define _ARP_H - -/********************************************************************/ - -/* - * This data definition is defined for Ethernet only! - */ -typedef struct -{ - uint16 ar_hrd; - uint16 ar_pro; - uint8 ar_hln; - uint8 ar_pln; - uint16 opcode; - uint8 ar_sha[6]; /* ethernet hw address */ - uint8 ar_spa[4]; /* ip address */ - uint8 ar_tha[6]; /* ethernet hw address */ - uint8 ar_tpa[4]; /* ip address */ -} arp_frame_hdr; - -#define ARP_HDR_LEN sizeof(arp_frame_hdr) - -/* - * ARP table entry definition. Note that this table only designed - * with Ethernet and IP in mind. - */ -#define MAX_HWA_SIZE (6) /* 6 is enough for Ethernet address */ -#define MAX_PA_SIZE (4) /* 4 is enough for Protocol address */ -typedef struct -{ - uint16 protocol; - uint8 hwa_size; - uint8 hwa[MAX_HWA_SIZE]; - uint8 pa_size; - uint8 pa[MAX_PA_SIZE]; - int longevity; -} ARPENTRY; -#define MAX_ARP_ENTRY (10) - -typedef struct -{ - unsigned int tab_size; - ARPENTRY table[MAX_ARP_ENTRY]; -} ARP_INFO; - -#define ARP_ENTRY_EMPTY (0) -#define ARP_ENTRY_PERM (1) -#define ARP_ENTRY_TEMP (2) - - -#define ETHERNET (1) -#define ARP_REQUEST (1) -#define ARP_REPLY (2) - -#define ARP_TIMEOUT (1) /* Timeout in seconds */ - -/* Protocol Header information */ -#define ARP_HDR_OFFSET ETH_HDR_LEN - -/********************************************************************/ - -uint8 * -arp_get_mypa (void); - -uint8 * -arp_get_myha (void); - -uint8 * -arp_get_broadcast (void); - -void -arp_merge (ARP_INFO *, uint16, int, uint8 *, int, uint8 *, int); - -void -arp_remove (ARP_INFO *, uint16, uint8 *, uint8 *); - -void -arp_request (NIF *, uint8 *); - -void -arp_handler (NIF *, NBUF *); - -uint8 * -arp_resolve (NIF *, uint16, uint8 *); - -void -arp_init (ARP_INFO *); - -/********************************************************************/ - -#endif /* _ARP_H */ diff --git a/flash.tos/drivers/net/bcm5222.c b/flash.tos/drivers/net/bcm5222.c deleted file mode 100644 index 5634973..0000000 --- a/flash.tos/drivers/net/bcm5222.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * File: bcm5222.c - * Purpose: Driver for the Micrel BCM5222 10/100 Ethernet PHY - * - * Notes: This driver was written specifically for the M5475EVB - * and M5485EVB. These boards use the MII signals from - * FEC0 to control the PHY. Therefore the fec_ch parameter - * is ignored when doing MII reads and writes. - */ - -#include -#include "config.h" -#include "net.h" -#include "fec.h" -#include "bcm5222.h" - -#ifdef NETWORK -#ifndef LWIP - -/********************************************************************/ -/* Initialize the BCM5222 PHY - * - * This function sets up the Auto-Negotiate Advertisement register - * within the PHY and then forces the PHY to auto-negotiate for - * it's settings. - * - * Params: - * fec_ch FEC channel - * phy_addr Address of the PHY. - * speed Desired speed (10BaseT or 100BaseTX) - * duplex Desired duplex (Full or Half) - * - * Return Value: - * 0 if MII commands fail - * 1 otherwise - */ -int -bcm5222_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex) -{ - int timeout; - uint16 settings; - -// ASSERT(speed == FEC_MII_10BASE_T || speed == FEC_MII_100BASE_TX); -// ASSERT(duplex == FEC_MII_HALF_DUPLEX || duplex == FEC_MII_FULL_DUPLEX); - - /* - * Initialize the MII interface - */ - fec_mii_init(fec_ch, SYSTEM_CLOCK); - - /* Reset the PHY */ - if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, BCM5222_CTRL_RESET | - BCM5222_CTRL_ANE)) - return 0; - - /* - * Wait for the PHY to reset - */ - for (timeout = 0; timeout < FEC_MII_TIMEOUT; ++timeout) - { - fec_mii_read(fec_ch, phy_addr, BCM5222_CTRL, &settings); - if (!(settings & BCM5222_CTRL_RESET)) - break; - } - if (FEC_MII_TIMEOUT <= timeout) - return 0; - - settings = (BCM5222_AN_ADV_NEXT_PAGE | BCM5222_AN_ADV_PAUSE); - - if (speed == FEC_MII_10BASE_T) - { - settings |= (uint16)((duplex == FEC_MII_FULL_DUPLEX) - ? (BCM5222_AN_ADV_10BT_FDX | BCM5222_AN_ADV_10BT) - : BCM5222_AN_ADV_10BT); - } - else /* (speed == FEC_MII_100BASE_TX) */ - { - settings = (uint16)((duplex == FEC_MII_FULL_DUPLEX) - ? (BCM5222_AN_ADV_100BTX_FDX | BCM5222_AN_ADV_100BTX | - BCM5222_AN_ADV_10BT_FDX | BCM5222_AN_ADV_10BT ) - : (BCM5222_AN_ADV_100BTX | BCM5222_AN_ADV_10BT)); - } - - /* Set the Auto-Negotiation Advertisement Register */ - if (!fec_mii_write(fec_ch, phy_addr, BCM5222_AN_ADV, settings)) - return 0; - - /* - * Enable Auto-Negotiation - */ - if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, (BCM5222_CTRL_ANE | - BCM5222_CTRL_RESTART_AN))) - return 0; - - /* - * Wait for auto-negotiation to complete - */ - for (timeout = 0; timeout < FEC_MII_TIMEOUT; ++timeout) - { - if (!fec_mii_read(fec_ch, phy_addr, BCM5222_STAT, &settings)) - return 0; - if (settings & BCM5222_STAT_AN_COMPLETE) - break; - } - if (FEC_MII_TIMEOUT <= timeout) - return 0; - - /* - * Read Auxiliary Control/Status Register - */ - if (!fec_mii_read(fec_ch, phy_addr, BCM5222_ACSR, &settings)) - return 0; - - /* - * Set the proper duplex in the FEC now that we have auto-negotiated - */ - if (settings & BCM5222_ACSR_FDX) - fec_duplex(fec_ch, FEC_MII_FULL_DUPLEX); - else - fec_duplex(fec_ch, FEC_MII_HALF_DUPLEX); - - #ifdef DEBUG_PRINT - Cconws("PHY Mode: "); - if (settings & BCM5222_ACSR_100BTX) - Cconws("100Mbps "); - else - Cconws("10Mbps "); - if (settings & BCM5222_ACSR_FDX) - Cconws("Full-duplex\r\n"); - else - Cconws("Half-duplex\r\n"); - #endif - - return 1; -} -/********************************************************************/ -void -bcm5222_get_reg(uint16* status0, uint16* status1) -{ - - fec_mii_read(0, 0x00, 0x00000000, &status0[0]); - fec_mii_read(0, 0x00, 0x00000001, &status0[1]); - fec_mii_read(0, 0x00, 0x00000004, &status0[4]); - fec_mii_read(0, 0x00, 0x00000005, &status0[5]); - fec_mii_read(0, 0x00, 0x00000006, &status0[6]); - fec_mii_read(0, 0x00, 0x00000007, &status0[7]); - fec_mii_read(0, 0x00, 0x00000008, &status0[8]); - fec_mii_read(0, 0x00, 0x00000010, &status0[16]); - fec_mii_read(0, 0x00, 0x00000011, &status0[17]); - fec_mii_read(0, 0x00, 0x00000012, &status0[18]); - fec_mii_read(0, 0x00, 0x00000013, &status0[19]); - fec_mii_read(0, 0x00, 0x00000018, &status0[24]); - fec_mii_read(0, 0x00, 0x00000019, &status0[25]); - fec_mii_read(0, 0x00, 0x0000001B, &status0[27]); - fec_mii_read(0, 0x00, 0x0000001C, &status0[28]); - fec_mii_read(0, 0x00, 0x0000001E, &status0[30]); - - fec_mii_read(0, 0x01, 0x00000000, &status1[0]); - fec_mii_read(0, 0x01, 0x00000001, &status1[1]); - fec_mii_read(0, 0x01, 0x00000004, &status1[4]); - fec_mii_read(0, 0x01, 0x00000005, &status1[5]); - fec_mii_read(0, 0x01, 0x00000006, &status1[6]); - fec_mii_read(0, 0x01, 0x00000007, &status1[7]); - fec_mii_read(0, 0x01, 0x00000008, &status1[8]); - fec_mii_read(0, 0x01, 0x00000010, &status1[16]); - fec_mii_read(0, 0x01, 0x00000011, &status1[17]); - fec_mii_read(0, 0x01, 0x00000012, &status1[18]); - fec_mii_read(0, 0x01, 0x00000013, &status1[19]); - fec_mii_read(0, 0x01, 0x00000018, &status1[24]); - fec_mii_read(0, 0x01, 0x00000019, &status1[25]); - fec_mii_read(0, 0x01, 0x0000001B, &status1[27]); - fec_mii_read(0, 0x01, 0x0000001C, &status1[28]); - fec_mii_read(0, 0x01, 0x0000001E, &status1[30]); -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/bcm5222.h b/flash.tos/drivers/net/bcm5222.h deleted file mode 100644 index cb12a19..0000000 --- a/flash.tos/drivers/net/bcm5222.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * File: bcm5222.h - * Purpose: Driver for the BCM5222 10/100 Ethernet PHY - * - * Notes: - */ - -#ifndef _BCM5222_H_ -#define _BCM5222_H_ - -/********************************************************************/ - -int -bcm5222_init(uint8, uint8, uint8, uint8); - -void -bcm5222_get_reg(uint16*, uint16*); - -/********************************************************************/ - -/* MII Register Addresses */ -#define BCM5222_CTRL (0x00) -#define BCM5222_STAT (0x01) -#define BCM5222_PHY_ID1 (0x02) -#define BCM5222_PHY_ID2 (0x03) -#define BCM5222_AN_ADV (0x04) -#define BCM5222_AN_LINK_PAR (0x05) -#define BCM5222_AN_EXP (0x06) -#define BCM5222_AN_NPR (0x07) -#define BCM5222_LINK_NPA (0x08) -#define BCM5222_ACSR (0x18) - -/* Bit definitions and macros for BCM5222_CTRL */ -#define BCM5222_CTRL_RESET (0x8000) -#define BCM5222_CTRL_LOOP (0x4000) -#define BCM5222_CTRL_SPEED (0x2000) -#define BCM5222_CTRL_ANE (0x1000) -#define BCM5222_CTRL_PD (0x0800) -#define BCM5222_CTRL_ISOLATE (0x0400) -#define BCM5222_CTRL_RESTART_AN (0x0200) -#define BCM5222_CTRL_FDX (0x0100) -#define BCM5222_CTRL_COL_TEST (0x0080) - - -/* Bit definitions and macros for BCM5222_STAT */ -#define BCM5222_STAT_100BT4 (0x8000) -#define BCM5222_STAT_100BTX_FDX (0x4000) -#define BCM5222_STAT_100BTX (0x2000) -#define BCM5222_STAT_10BT_FDX (0x1000) -#define BCM5222_STAT_10BT (0x0800) -#define BCM5222_STAT_NO_PREAMBLE (0x0040) -#define BCM5222_STAT_AN_COMPLETE (0x0020) -#define BCM5222_STAT_REMOTE_FAULT (0x0010) -#define BCM5222_STAT_AN_ABILITY (0x0008) -#define BCM5222_STAT_LINK (0x0004) -#define BCM5222_STAT_JABBER (0x0002) -#define BCM5222_STAT_EXTENDED (0x0001) - -/* Bit definitions and macros for BCM5222_AN_ADV */ -#define BCM5222_AN_ADV_NEXT_PAGE (0x8001) -#define BCM5222_AN_ADV_REM_FAULT (0x2001) -#define BCM5222_AN_ADV_PAUSE (0x0401) -#define BCM5222_AN_ADV_100BT4 (0x0201) -#define BCM5222_AN_ADV_100BTX_FDX (0x0101) -#define BCM5222_AN_ADV_100BTX (0x0081) -#define BCM5222_AN_ADV_10BT_FDX (0x0041) -#define BCM5222_AN_ADV_10BT (0x0021) -#define BCM5222_AN_ADV_802_3 (0x0001) - -/* Bit definitions and macros for BCM5222_ACSR */ -#define BCM5222_ACSR_100BTX (0x0002) -#define BCM5222_ACSR_FDX (0x0001) - -/********************************************************************/ - -#endif /* _BCM5222_H_ */ diff --git a/flash.tos/drivers/net/dma_utils.c b/flash.tos/drivers/net/dma_utils.c deleted file mode 100644 index da1f9ed..0000000 --- a/flash.tos/drivers/net/dma_utils.c +++ /dev/null @@ -1,610 +0,0 @@ -/* - * File: dma_utils.c - * Purpose: General purpose utilities for the multi-channel DMA - * - * Notes: The methodology used in these utilities assumes that - * no single initiator will be tied to more than one - * task/channel - */ - -#include -#include "config.h" -#include "net.h" -#include "dma_utils.h" -#ifdef MCF5445X -#include "mcf5445x.h" -#else -#include "../mcdapi/MCD_dma.h" -#include "mcf548x.h" -#endif - -extern void ltoa(char *buf, long n, unsigned long base); - -#ifdef NETWORK -#ifndef LWIP - -/* - * This global keeps track of which initiators have been - * used of the available assignments. Initiators 0-15 are - * hardwired. Initiators 16-31 are multiplexed and controlled - * via the Initiatior Mux Control Register (IMCR). The - * assigned requestor is stored with the associated initiator - * number. - */ -static int8 used_reqs[32]; - -DMA_CHANNEL_STRUCT dma_channel[NCHANNELS]; - -void dma_init_tables(void) -{ - int i; - used_reqs[0] = DMA_ALWAYS; - used_reqs[1] = DMA_DSPI_RX; - used_reqs[2] = DMA_DSPI_TX; - used_reqs[3] = DMA_DREQ0; - used_reqs[4] = DMA_PSC0_RX; - used_reqs[5] = DMA_PSC0_TX; - used_reqs[6] = DMA_USBEP0; - used_reqs[7] = DMA_USBEP1; - used_reqs[8] = DMA_USBEP2; - used_reqs[9] = DMA_USBEP3; - used_reqs[10] = DMA_PCI_TX; - used_reqs[11] = DMA_PCI_RX; - used_reqs[12] = DMA_PSC1_RX; - used_reqs[13] = DMA_PSC1_TX; - used_reqs[14] = DMA_I2C_RX; - used_reqs[15] = DMA_I2C_TX; - for(i=16; i<32; used_reqs[i++] = 0); - for(i=0; i 0 && lvl < 8); -// ASSERT(pri < 8); - - /* Setup the DMA ICR (#48) */ - MCF_INTC_ICR48 = 0 - | MCF_INTC_ICRn_IP(pri) - | MCF_INTC_ICRn_IL(lvl); - - /* Unmask all task interrupts */ - MCF_DMA_DIMR = 0; - - /* Clear the interrupt pending register */ - MCF_DMA_DIPR = 0; - - /* Unmask the DMA interrupt in the interrupt controller */ - MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK48; -} -/********************************************************************/ -/* - * Disable all DMA interrupts - */ -void -dma_irq_disable(void) -{ - /* Mask all task interrupts */ - MCF_DMA_DIMR = (uint32)~0; - - /* Clear any pending task interrupts */ - MCF_DMA_DIPR = (uint32)~0; - - /* Mask the DMA interrupt in the interrupt controller */ - MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK48; -} -/********************************************************************/ -/* - * Attempt to enable the provided Initiator in the Initiator - * Mux Control Register - * - * Parameters: - * initiator Initiator identifier - * - * Return Value: - * 1 if unable to make the assignment - * 0 successful - */ -int -dma_set_initiator(int initiator) -{ - switch (initiator) - { - case DMA_ALWAYS: - case DMA_DSPI_RX: - case DMA_DSPI_TX: - case DMA_DREQ0: - case DMA_PSC0_RX: - case DMA_PSC0_TX: - case DMA_USBEP0: - case DMA_USBEP1: - case DMA_USBEP2: - case DMA_USBEP3: - case DMA_PCI_TX: - case DMA_PCI_RX: - case DMA_PSC1_RX: - case DMA_PSC1_TX: - case DMA_I2C_RX: - case DMA_I2C_TX: - /* These initiators are always active */ - break; - case DMA_FEC0_RX: - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC16(3)) - | MCF_DMA_IMCR_SRC16_FEC0RX; - used_reqs[16] = DMA_FEC0_RX; - break; - case DMA_FEC0_TX: - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC17(3)) - | MCF_DMA_IMCR_SRC17_FEC0TX; - used_reqs[17] = DMA_FEC0_TX; - break; - case DMA_FEC1_RX: - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC20(3)) - | MCF_DMA_IMCR_SRC20_FEC1RX; - used_reqs[20] = DMA_FEC1_RX; - break; - case DMA_FEC1_TX: - if (used_reqs[21] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3)) - | MCF_DMA_IMCR_SRC21_FEC1TX; - used_reqs[21] = DMA_FEC1_TX; - } - else if (used_reqs[25] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3)) - | MCF_DMA_IMCR_SRC25_FEC1TX; - used_reqs[25] = DMA_FEC1_TX; - } - else if (used_reqs[31] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3)) - | MCF_DMA_IMCR_SRC31_FEC1TX; - used_reqs[31] = DMA_FEC1_TX; - } - else /* No empty slots */ - return 1; - break; - case DMA_DREQ1: - if (used_reqs[29] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3)) - | MCF_DMA_IMCR_SRC29_DREQ1; - used_reqs[29] = DMA_DREQ1; - } - else if (used_reqs[21] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3)) - | MCF_DMA_IMCR_SRC21_DREQ1; - used_reqs[21] = DMA_DREQ1; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM0: - if (used_reqs[24] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC24(3)) - | MCF_DMA_IMCR_SRC24_CTM0; - used_reqs[24] = DMA_CTM0; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM1: - if (used_reqs[25] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3)) - | MCF_DMA_IMCR_SRC25_CTM1; - used_reqs[25] = DMA_CTM1; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM2: - if (used_reqs[26] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3)) - | MCF_DMA_IMCR_SRC26_CTM2; - used_reqs[26] = DMA_CTM2; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM3: - if (used_reqs[27] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3)) - | MCF_DMA_IMCR_SRC27_CTM3; - used_reqs[27] = DMA_CTM3; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM4: - if (used_reqs[28] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3)) - | MCF_DMA_IMCR_SRC28_CTM4; - used_reqs[28] = DMA_CTM4; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM5: - if (used_reqs[29] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3)) - | MCF_DMA_IMCR_SRC29_CTM5; - used_reqs[29] = DMA_CTM5; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM6: - if (used_reqs[30] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3)) - | MCF_DMA_IMCR_SRC30_CTM6; - used_reqs[30] = DMA_CTM6; - } - else /* No empty slots */ - return 1; - break; - case DMA_CTM7: - if (used_reqs[31] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3)) - | MCF_DMA_IMCR_SRC31_CTM7; - used_reqs[31] = DMA_CTM7; - } - else /* No empty slots */ - return 1; - break; - case DMA_USBEP4: - if (used_reqs[26] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3)) - | MCF_DMA_IMCR_SRC26_USBEP4; - used_reqs[26] = DMA_USBEP4; - } - else /* No empty slots */ - return 1; - break; - case DMA_USBEP5: - if (used_reqs[27] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3)) - | MCF_DMA_IMCR_SRC27_USBEP5; - used_reqs[27] = DMA_USBEP5; - } - else /* No empty slots */ - return 1; - break; - case DMA_USBEP6: - if (used_reqs[28] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3)) - | MCF_DMA_IMCR_SRC28_USBEP6; - used_reqs[28] = DMA_USBEP6; - } - else /* No empty slots */ - return 1; - break; - case DMA_PSC2_RX: - if (used_reqs[28] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3)) - | MCF_DMA_IMCR_SRC28_PSC2RX; - used_reqs[28] = DMA_PSC2_RX; - } - else /* No empty slots */ - return 1; - break; - case DMA_PSC2_TX: - if (used_reqs[29] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3)) - | MCF_DMA_IMCR_SRC29_PSC2TX; - used_reqs[29] = DMA_PSC2_TX; - } - else /* No empty slots */ - return 1; - break; - case DMA_PSC3_RX: - if (used_reqs[30] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3)) - | MCF_DMA_IMCR_SRC30_PSC3RX; - used_reqs[30] = DMA_PSC3_RX; - } - else /* No empty slots */ - return 1; - break; - case DMA_PSC3_TX: - if (used_reqs[31] == 0) - { - MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3)) - | MCF_DMA_IMCR_SRC31_PSC3TX; - used_reqs[31] = DMA_PSC3_TX; - } - else /* No empty slots */ - return 1; - break; - default: - return 1; - } - return 0; -} -/********************************************************************/ -/* - * Return the initiator number for the given requestor - * - * Parameters: - * requestor Initiator/Requestor identifier - * - * Return Value: - * The initiator number (0-31) if initiator has been assigned - * 0 (always initiator) otherwise - */ -uint32 -dma_get_initiator(int requestor) -{ - uint32 i; - - for (i=0; i= 0 && channel < NCHANNELS) - { - dma_channel[channel].req = -1; - dma_channel[channel].handler = NULL; - } -} -/********************************************************************/ -/* - * This is the catch-all interrupt handler for the mult-channel DMA - */ -void dma_interrupt_handler (void) -{ - uint32 i, interrupts; - - /* - * Determine which interrupt(s) triggered by AND'ing the - * pending interrupts with those that aren't masked. - */ - interrupts = MCF_DMA_DIPR & ~MCF_DMA_DIMR; - - /* Make sure we are here for a reason */ -// ASSERT(interrupts != 0); - - /* Clear the interrupt in the pending register */ - MCF_DMA_DIPR = interrupts; - - for (i=0; i<16; ++i, interrupts>>=1) - { - if (interrupts & 0x1) - { - /* If there is a handler, call it */ - if (dma_channel[i].handler != NULL) - { -#if 0 // #ifdef DEBUG - display_string("dma_int 0x"); - hex_long(i); - display_string("\r\n"); -#endif - dma_channel[i].handler(); - } - } - } -} -/********************************************************************/ -/* - * Display some of the registers for debugging - */ -void -dma_reg_dump (void) -{ -#if 0 // #ifdef DEBUG_PRINT - char buf[10]; - Cconws("\r\n------------- DMA -------------"); - Cconws("\r\nTASKBAR 0x"); - ltoa(buf, MCF_DMA_TASKBAR, 16); - Cconws(buf); - Cconws("\r\nCP 0x"); - ltoa(buf, MCF_DMA_CP, 16); - Cconws(buf); - Cconws("\r\nEP 0x"); - ltoa(buf, MCF_DMA_EP, 16); - Cconws(buf); - Cconws("\r\nVP 0x"); - ltoa(buf, MCF_DMA_VP, 16); - Cconws(buf); - Cconws("\r\nDIPR 0x"); - ltoa(buf, MCF_DMA_DIPR, 16); - Cconws(buf); - Cconws("\r\nDIMR 0x"); - ltoa(buf, MCF_DMA_DIMR, 16); - Cconws(buf); - Cconws("\r\nTCR0 0x"); - ltoa(buf, MCF_DMA_TCR0, 16); - Cconws(buf); - Cconws("\r\nTCR1 0x"); - ltoa(buf, MCF_DMA_TCR1, 16); - Cconws(buf); - Cconws("\r\nTCR2 0x"); - ltoa(buf, MCF_DMA_TCR2, 16); - Cconws(buf); - Cconws("\r\nCR3 0x"); - ltoa(buf, MCF_DMA_TCR3, 16); - Cconws(buf); - Cconws("\r\nTCR4 0x"); - ltoa(buf, MCF_DMA_TCR4, 16); - Cconws(buf); - Cconws("\r\nTCR5 0x"); - ltoa(buf, MCF_DMA_TCR5, 16); - Cconws(buf); - Cconws("\r\nTCR6 0x"); - ltoa(buf, MCF_DMA_TCR6, 16); - Cconws(buf); - Cconws("\r\nTCR7 0x"); - ltoa(buf, MCF_DMA_TCR7, 16); - Cconws(buf); - Cconws("\r\nTCR8 0x"); - ltoa(buf, MCF_DMA_TCR8, 16); - Cconws(buf); - Cconws("\r\nTCR9 0x"); - ltoa(buf, MCF_DMA_TCR9, 16); - Cconws(buf); - Cconws("\r\nTCR10 0x"); - ltoa(buf, MCF_DMA_TCR10, 16); - Cconws(buf); - Cconws("\r\nTCR11 0x"); - ltoa(buf, MCF_DMA_TCR11, 16); - Cconws(buf); - Cconws("\r\nTCR12 0x"); - ltoa(buf, MCF_DMA_TCR12, 16); - Cconws(buf); - Cconws("\r\nTCR13 0x"); - ltoa(buf, MCF_DMA_TCR13, 16); - Cconws(buf); - Cconws("\r\nTCR14 0x"); - ltoa(buf, MCF_DMA_TCR14, 16); - Cconws(buf); - Cconws("\r\nTCR15 0x"); - ltoa(buf, MCF_DMA_TCR15, 16); - Cconws(buf); - Cconws("\r\nIMCR 0x"); - ltoa(buf, MCF_DMA_IMCR, 16); - Cconws(buf); - Cconws("\r\nPTDDBG 0x"); - ltoa(buf, MCF_DMA_PTDDBG, 16); - Cconws(buf); - Cconws("\r\n--------------------------------\r\n"); -#endif -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ - diff --git a/flash.tos/drivers/net/dma_utils.h b/flash.tos/drivers/net/dma_utils.h deleted file mode 100644 index 13dbb4b..0000000 --- a/flash.tos/drivers/net/dma_utils.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * File: dma_utils.h - * Purpose: - * - * Notes: - */ - -#ifndef _DMA_UTILS_H_ -#define _DMA_UTILS_H_ - -/* - * This global keeps track of which channels have been assigned - * to tasks. This methology assumes that no single initiator - * will be tied to more than one task/channel - */ -typedef struct -{ - int req; - void (*handler)(void); -} DMA_CHANNEL_STRUCT; - -/********************************************************************/ - -void dma_init_tables(void); -void dma_irq_enable(unsigned char, unsigned char); -void dma_irq_disable(void); -int dma_set_initiator(int); -unsigned long dma_get_initiator(int); -void dma_free_initiator(int); -int dma_set_channel(int, void (*)(void)); -int dma_get_channel(int); -void dma_free_channel(int); -void dma_clear_channel(int); -void dma_interrupt_handler(void); -void dma_reg_dump(void); - -/********************************************************************/ - -/* - * Create identifiers for each initiator/requestor - */ -#ifdef MCF5445X - -#define DMA_ALWAYS (0) -#define DMA_DREQ0 (0) -#define DMA_DREQ1 (1) -#define DMA_UART0_RX (2) -#define DMA_UART0_TX (3) -#define DMA_UART1_RX (4) -#define DMA_UART1_TX (5) -#define DMA_UART2_RX (6) -#define DMA_UART2_TX (7) -#define DMA_TIM0_SSI0RX (8) -#define DMA_TIM1_SSI1RX (9) -#define DMA_TIM2_SSI0TX (10) -#define DMA_TIM3_SSI1TX (11) -#define DMA_DSPI_RX (12) -#define DMA_DSPI_TX (13) -#define DMA_ATA_RX (14) -#define DMA_ATA_TX (15) - -#define NCHANNELS 16 - -#else /* MCF548X */ - -#define DMA_ALWAYS (0) -#define DMA_DSPI_RX (1) -#define DMA_DSPI_TX (2) -#define DMA_DREQ0 (3) -#define DMA_PSC0_RX (4) -#define DMA_PSC0_TX (5) -#define DMA_USBEP0 (6) -#define DMA_USBEP1 (7) -#define DMA_USBEP2 (8) -#define DMA_USBEP3 (9) -#define DMA_PCI_TX (10) -#define DMA_PCI_RX (11) -#define DMA_PSC1_RX (12) -#define DMA_PSC1_TX (13) -#define DMA_I2C_RX (14) -#define DMA_I2C_TX (15) -#define DMA_FEC0_RX (16) -#define DMA_FEC0_TX (17) -#define DMA_FEC1_RX (18) -#define DMA_FEC1_TX (19) -#define DMA_DREQ1 (20) -#define DMA_CTM0 (21) -#define DMA_CTM1 (22) -#define DMA_CTM2 (23) -#define DMA_CTM3 (24) -#define DMA_CTM4 (25) -#define DMA_CTM5 (26) -#define DMA_CTM6 (27) -#define DMA_CTM7 (28) -#define DMA_USBEP4 (29) -#define DMA_USBEP5 (30) -#define DMA_USBEP6 (31) -#define DMA_PSC2_RX (32) -#define DMA_PSC2_TX (33) -#define DMA_PSC3_RX (34) -#define DMA_PSC3_TX (35) -#define DMA_FEC_RX(x) ((x == 0) ? DMA_FEC0_RX : DMA_FEC1_RX) -#define DMA_FEC_TX(x) ((x == 0) ? DMA_FEC0_TX : DMA_FEC1_TX) - -#endif /* MCF5445X */ - -/********************************************************************/ - -#endif /* _DMA_UTILS_H_ */ diff --git a/flash.tos/drivers/net/eth.h b/flash.tos/drivers/net/eth.h deleted file mode 100644 index 1abc04b..0000000 --- a/flash.tos/drivers/net/eth.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * File: eth.h - * Purpose: Definitions for Ethernet Frames. - * - * Modifications: - */ - -#ifndef _ETH_H -#define _ETH_H - -/*******************************************************************/ - -/* Ethernet standard lengths in bytes*/ -#define ETH_ADDR_LEN (6) -#define ETH_TYPE_LEN (2) -#define ETH_CRC_LEN (4) -#define ETH_MAX_DATA (1500) -#define ETH_MIN_DATA (46) -#define ETH_HDR_LEN (ETH_ADDR_LEN * 2 + ETH_TYPE_LEN) - -/* Defined Ethernet Frame Types */ -#define ETH_FRM_IP (0x0800) -#define ETH_FRM_ARP (0x0806) -#define ETH_FRM_RARP (0x8035) -#define ETH_FRM_TEST (0xA5A5) - -/* Maximum and Minimum Ethernet Frame Sizes */ -#define ETH_MAX_FRM (ETH_HDR_LEN + ETH_MAX_DATA + ETH_CRC_LEN) -#define ETH_MIN_FRM (ETH_HDR_LEN + ETH_MIN_DATA + ETH_CRC_LEN) -#define ETH_MTU (ETH_HDR_LEN + ETH_MAX_DATA) - -/* Ethernet Addresses */ -typedef uint8 ETH_ADDR[ETH_ADDR_LEN]; - -/* 16-bit Ethernet Frame Type, ie. Protocol */ -typedef uint16 ETH_FRM_TYPE; - -/* Ethernet Frame Header definition */ -typedef struct -{ - ETH_ADDR dest; - ETH_ADDR src; - ETH_FRM_TYPE type; -} ETH_HDR; - -/* Ethernet Frame definition */ -typedef struct -{ - ETH_HDR head; - uint8* data; -} ETH_FRAME; - -/*******************************************************************/ - -#endif /* _ETH_H */ diff --git a/flash.tos/drivers/net/fec.c b/flash.tos/drivers/net/fec.c deleted file mode 100644 index 2872179..0000000 --- a/flash.tos/drivers/net/fec.c +++ /dev/null @@ -1,1620 +0,0 @@ -/* - * File: fec.c - * Purpose: Driver for the Fast Ethernet Controller (FEC) - * - * Notes: - */ - -#include "config.h" - -#ifdef NETWORK -#ifndef LWIP - -#include -#include "net.h" -#include "fec.h" -#include "fecbd.h" -#include "net_timer.h" -#include "../dma_utils/dma_utils.h" -#ifdef MCF5445X -#include "mcf5445x.h" -#error MCF5445X not supported, change settings inside config.h to LWIP -#else -#include "../mcdapi/MCD_dma.h" -#include "mcf548x.h" -#endif - -extern void ltoa(char *buf, long n, unsigned long base); -extern int phy_init(uint8 fec_ch, uint8 phy_addr, uint8 speed, uint8 duplex); -extern NIF nif[]; - -/********************************************************************/ - -FEC_EVENT_LOG fec_log[2]; - -/********************************************************************/ -/* - * Write a value to a PHY's MII register. - * - * Parameters: - * ch FEC channel - * phy_addr Address of the PHY. - * reg_addr Address of the register in the PHY. - * data Data to be written to the PHY register. - * - * Return Values: - * 0 on failure - * 1 on success. - * - * Please refer to your PHY manual for registers and their meanings. - * mii_write() polls for the FEC's MII interrupt event (which should - * be masked from the interrupt handler) and clears it. If after a - * suitable amount of time the event isn't triggered, a value of 0 - * is returned. - */ -int -fec_mii_write(uint8 ch, uint8 phy_addr, uint8 reg_addr, uint16 data) -{ - int timeout; - uint32 eimr; - -// ASSERT(ch == 0 || ch == 1); - - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - - /* - * Write to the MII Management Frame Register to kick-off - * the MII write - */ - MCF_FEC_MMFR(ch) = 0 - | MCF_FEC_MMFR_ST_01 - | MCF_FEC_MMFR_OP_WRITE - | MCF_FEC_MMFR_PA(phy_addr) - | MCF_FEC_MMFR_RA(reg_addr) - | MCF_FEC_MMFR_TA_10 - | MCF_FEC_MMFR_DATA(data); - - /* - * Mask the MII interrupt - */ - eimr = MCF_FEC_EIMR(ch); - MCF_FEC_EIMR(ch) &= ~MCF_FEC_EIMR_MII; - - /* - * Poll for the MII interrupt (interrupt should be masked) - */ - for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) - { - if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) - break; - } - if(timeout == FEC_MII_TIMEOUT) - return 0; - - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - - /* - * Restore the EIMR - */ - MCF_FEC_EIMR(ch) = eimr; - - return 1; -} -/********************************************************************/ -/* - * Read a value from a PHY's MII register. - * - * Parameters: - * ch FEC channel - * phy_addr Address of the PHY. - * reg_addr Address of the register in the PHY. - * data Pointer to storage for the Data to be read - * from the PHY register (passed by reference) - * - * Return Values: - * 0 on failure - * 1 on success. - * - * Please refer to your PHY manual for registers and their meanings. - * mii_read() polls for the FEC's MII interrupt event (which should - * be masked from the interrupt handler) and clears it. If after a - * suitable amount of time the event isn't triggered, a value of 0 - * is returned. - */ -int -fec_mii_read(uint8 ch, uint8 phy_addr, uint8 reg_addr, uint16 *data) -{ - int timeout; - -// ASSERT(ch == 0 || ch == 1); - - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - - /* - * Write to the MII Management Frame Register to kick-off - * the MII read - */ - MCF_FEC_MMFR(ch) = 0 - | MCF_FEC_MMFR_ST_01 - | MCF_FEC_MMFR_OP_READ - | MCF_FEC_MMFR_PA(phy_addr) - | MCF_FEC_MMFR_RA(reg_addr) - | MCF_FEC_MMFR_TA_10; - - /* - * Poll for the MII interrupt (interrupt should be masked) - */ - for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) - { - if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) - break; - } - - if(timeout == FEC_MII_TIMEOUT) - return 0; - - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - - *data = (uint16)(MCF_FEC_MMFR(ch) & 0x0000FFFF); - - return 1; -} -/********************************************************************/ -/* - * Initialize the MII interface controller - * - * Parameters: - * ch FEC channel - * sys_clk System Clock Frequency (in MHz) - */ -void -fec_mii_init(uint8 ch, uint32 sys_clk) -{ -// ASSERT(ch == 0 || ch == 1); - - /* - * Initialize the MII clock (EMDC) frequency - * - * Desired MII clock is 2.5MHz - * MII Speed Setting = System_Clock / (2.5MHz * 2) - * (plus 1 to make sure we round up) - */ - MCF_FEC_MSCR(ch) = MCF_FEC_MSCR_MII_SPEED((sys_clk/5)+1); - - /* - * Make sure the external interface signals are enabled - */ - if (ch == 1) - MCF_GPIO_PAR_FECI2CIRQ |= 0 - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO; - else - MCF_GPIO_PAR_FECI2CIRQ |= 0 - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO; -} -/********************************************************************/ -/* Initialize the MIB counters - * - * Parameters: - * ch FEC channel - */ -void -fec_mib_init(uint8 ch) -{ -// ASSERT(ch == 0 || ch == 1); -//To do -} -/********************************************************************/ -/* Display the MIB counters - * - * Parameters: - * ch FEC channel - */ -void -fec_mib_dump(uint8 ch) -{ -// ASSERT(ch == 0 || ch == 1); -//To do -} -/********************************************************************/ -/* Initialize the FEC log - * - * Parameters: - * ch FEC channel - */ -void -fec_log_init(uint8 ch) -{ - int i; - char *ptr = (char *)&fec_log[ch]; -// ASSERT(ch == 0 || ch == 1); - for(i=0; i>= 1; - crc = crc ^ 0xEDB88320; - } - else - crc >>= 1; - byte >>= 1; - } - } - return (uint8)(crc >> 26); -} -/********************************************************************/ -/* - * Set the Physical (Hardware) Address and the Individual Address - * Hash in the selected FEC - * - * Parameters: - * ch FEC channel - * pa Physical (Hardware) Address for the selected FEC - */ -void -fec_set_address (uint8 ch, const uint8 *pa) -{ - uint8 crc; - -// ASSERT(ch == 0 || ch == 1); - - /* - * Set the Physical Address - */ - MCF_FEC_PALR(ch) = (uint32)((pa[0]<<24) | (pa[1]<<16) | (pa[2]<<8) | pa[3]); - MCF_FEC_PAUR(ch) = (uint32)((pa[4]<<24) | (pa[5]<<16)); - - /* - * Calculate and set the hash for given Physical Address - * in the Individual Address Hash registers - */ - crc = fec_hash_address(pa); - if(crc >= 32) - MCF_FEC_IAUR(ch) |= (uint32)(1 << (crc - 32)); - else - MCF_FEC_IALR(ch) |= (uint32)(1 << crc); -} -/********************************************************************/ -/* - * Reset the selected FEC controller - * - * Parameters: - * ch FEC channel - */ -void -fec_reset (uint8 ch) -{ - int i; - -// ASSERT(ch == 0 || ch == 1); - - /* Clear any events in the FIFO status registers */ - MCF_FEC_FECRFSR(ch) = (0 - | MCF_FEC_FECRFSR_OF - | MCF_FEC_FECRFSR_UF - | MCF_FEC_FECRFSR_RXW - | MCF_FEC_FECRFSR_FAE - | MCF_FEC_FECRFSR_IP); - MCF_FEC_FECTFSR(ch) = (0 - | MCF_FEC_FECRFSR_OF - | MCF_FEC_FECRFSR_UF - | MCF_FEC_FECRFSR_RXW - | MCF_FEC_FECRFSR_FAE - | MCF_FEC_FECRFSR_IP); - - /* Reset the FIFOs */ - MCF_FEC_FRST(ch) |= MCF_FEC_FRST_SW_RST; - MCF_FEC_FRST(ch) &= ~MCF_FEC_FRST_SW_RST; - - /* Set the Reset bit and clear the Enable bit */ - MCF_FEC_ECR(ch) = MCF_FEC_ECR_RESET; - - /* Wait at least 8 clock cycles */ - for (i = 0; i < 10; i++) - { - asm volatile (" nop\n\t"); - } -} -/********************************************************************/ -/* - * Initialize the selected FEC - * - * Parameters: - * ch FEC channel - * mode External interface mode (MII, 7-wire, or internal loopback) - * pa Physical (Hardware) Address for the selected FEC - */ -void -fec_init (uint8 ch, uint8 mode, uint8 duplex, const uint8 *pa) -{ -// ASSERT(ch == 0 || ch == 1); - - /* - * Enable all the external interface signals - */ - if (mode == FEC_MODE_7WIRE) - { - if (ch == 1) - MCF_GPIO_PAR_FECI2CIRQ |= MCF_GPIO_PAR_FECI2CIRQ_PAR_E17; - else - MCF_GPIO_PAR_FECI2CIRQ |= MCF_GPIO_PAR_FECI2CIRQ_PAR_E07; - } - else if (mode == FEC_MODE_MII) - { - if (ch == 1) - MCF_GPIO_PAR_FECI2CIRQ |= 0 - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MII - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E17; - else - MCF_GPIO_PAR_FECI2CIRQ |= 0 - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MII - | MCF_GPIO_PAR_FECI2CIRQ_PAR_E07; - } - - /* - * Clear the Individual and Group Address Hash registers - */ - MCF_FEC_IALR(ch) = 0; - MCF_FEC_IAUR(ch) = 0; - MCF_FEC_GALR(ch) = 0; - MCF_FEC_GAUR(ch) = 0; - - /* - * Set the Physical Address for the selected FEC - */ - fec_set_address(ch, pa); - - /* - * Mask all FEC interrupts - */ - MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL; - - /* - * Clear all FEC interrupt events - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL; - - /* - * Initialize the Receive Control Register - */ - MCF_FEC_RCR(ch) = 0 - | MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM) - #ifdef FEC_PROMISCUOUS - | MCF_FEC_RCR_PROM - #endif - | MCF_FEC_RCR_FCE; - - if (mode == FEC_MODE_MII) - MCF_FEC_RCR(ch) |= MCF_FEC_RCR_MII_MODE; - - else if (mode == FEC_MODE_LOOPBACK) - MCF_FEC_RCR(ch) |= (MCF_FEC_RCR_LOOP | MCF_FEC_RCR_PROM); - - /* - * Set the duplex - */ - if (mode == FEC_MODE_LOOPBACK) - /* Loopback mode must operate in full-duplex */ - fec_duplex(ch, FEC_MII_FULL_DUPLEX); - else - fec_duplex(ch, duplex); - - /* - * Set Rx FIFO alarm and granularity - */ - MCF_FEC_FECRFCR(ch) = 0 - | MCF_FEC_FECRFCR_FRM - | MCF_FEC_FECRFCR_RXW_MSK - | MCF_FEC_FECRFCR_GR(7); - MCF_FEC_FECRFAR(ch) = MCF_FEC_FECRFAR_ALARM(768); - - /* - * Set Tx FIFO watermark, alarm and granularity - */ - MCF_FEC_FECTFCR(ch) = 0 - | MCF_FEC_FECTFCR_FRM - | MCF_FEC_FECTFCR_TXW_MSK - | MCF_FEC_FECTFCR_GR(7); - MCF_FEC_FECTFAR(ch) = MCF_FEC_FECTFAR_ALARM(256); - MCF_FEC_FECTFWR(ch) = MCF_FEC_FECTFWR_X_WMRK_256; - - /* - * Enable the transmitter to append the CRC - */ - MCF_FEC_CTCWR(ch) = 0 - | MCF_FEC_CTCWR_TFCW - | MCF_FEC_CTCWR_CRC; -} -/********************************************************************/ -/* - * Start the FEC Rx DMA task - * - * Parameters: - * ch FEC channel - * rxbd First Rx buffer descriptor in the chain - */ -void -fec_rx_start(uint8 ch, int8 *rxbd, uint8 pri) -{ - uint32 initiator; - int channel, result; - void fec0_rx_frame(void); - void fec1_rx_frame(void); - -// ASSERT(ch == 0 || ch == 1); - - /* - * Make the initiator assignment - */ - result = dma_set_initiator(DMA_FEC_RX(ch)); -// ASSERT(result == 0); - - /* - * Grab the initiator number - */ - initiator = dma_get_initiator(DMA_FEC_RX(ch)); - - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_set_channel(DMA_FEC_RX(ch), - (ch == 0) ? fec0_rx_frame : fec1_rx_frame); -// ASSERT(channel != -1); - - /* - * Start the Rx DMA task - */ - MCD_startDma(channel, - (s8*)rxbd, - 0, - (s8*)MCF_FEC_FECRFDR_ADDR(ch), - 0, - RX_BUF_SZ, - 0, - initiator, - (int)pri, - 0 - | MCD_FECRX_DMA - | MCD_INTERRUPT - | MCD_TT_FLAGS_CW - | MCD_TT_FLAGS_RL - | MCD_TT_FLAGS_SP - , - 0 - | MCD_NO_CSUM - | MCD_NO_BYTE_SWAP - ); -} -/********************************************************************/ -/* - * Continue the Rx DMA task - * - * This routine is called after the DMA task has halted after - * encountering an Rx buffer descriptor that wasn't marked as - * ready. There is no harm in calling the DMA continue routine - * if the DMA is not halted. - * - * Parameters: - * ch FEC channel - */ -void -fec_rx_continue(uint8 ch) -{ - int channel; - -// ASSERT(ch == 0 || ch == 1); - - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_RX(ch)); -// ASSERT(channel != -1); - - /* - * Continue/restart the DMA task - */ - if (channel != -1) - MCD_continDma(channel); -} -/********************************************************************/ -/* - * Stop all frame receptions on the selected FEC - * - * Parameters: - * ch FEC channel - */ -void -fec_rx_stop (uint8 ch) -{ - uint32 mask; - int channel; - -// ASSERT(ch == 0 || ch == 1); - - /* Save off the EIMR value */ - mask = MCF_FEC_EIMR(ch); - - /* Mask all interrupts */ - MCF_FEC_EIMR(ch) = 0; - - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_RX(ch)); - - /* Kill the FEC Tx DMA task */ - if (channel != -1) - MCD_killDma(channel); - - /* - * Free up the FEC requestor from the software maintained - * initiator list - */ - dma_free_initiator(DMA_FEC_RX(ch)); - - /* Free up the DMA channel */ - dma_free_channel(DMA_FEC_RX(ch)); - - /* Restore the interrupt mask register value */ - MCF_FEC_EIMR(ch) = mask; -} -/********************************************************************/ -/* - * Receive Frame interrupt handler - * - * Parameters: - * nif Pointer to Network Interface structure - * ch FEC channel - */ -void -fec_rx_frame(uint8 ch, NIF *nif) -{ - ETH_HDR *eth_hdr; - FECBD *pRxBD; - NBUF *cur_nbuf, *new_nbuf; - int keep; - -#ifdef DEBUG_PRINT - display_string("fec_rx_frame\r\n"); -#endif - -#if (__GNUC__ > 3) - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ -#else - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5200\n\t"); /* from CF68KLIB */ -#endif - - while ((pRxBD = fecbd_rx_alloc(ch)) != NULL) - { - fec_log[ch].drxf++; - keep = TRUE; - - /* - * Check the Receive Frame Status Word for errors - * - The L bit should always be set - * - No undefined bits should be set - * - The upper 5 bits of the length should be cleared - */ - if (!(pRxBD->status & RX_BD_L) || (pRxBD->status & 0x0608) - || (pRxBD->length & 0xF800)) - { - keep = FALSE; - fec_log[ch].rfsw_inv++; - } - else if (pRxBD->status & RX_BD_ERROR) - { - keep = FALSE; - if (pRxBD->status & RX_BD_NO) - fec_log[ch].rfsw_no++; - if (pRxBD->status & RX_BD_CR) - fec_log[ch].rfsw_cr++; - if (pRxBD->status & RX_BD_OV) - fec_log[ch].rfsw_ov++; - if (pRxBD->status & RX_BD_TR) - fec_log[ch].rfsw_tr++; - } - else - { - if (pRxBD->status & RX_BD_LG) - fec_log[ch].rfsw_lg++; - if (pRxBD->status & RX_BD_M) - fec_log[ch].rfsw_m++; - if (pRxBD->status & RX_BD_BC) - fec_log[ch].rfsw_bc++; - if (pRxBD->status & RX_BD_MC) - fec_log[ch].rfsw_mc++; - } - - if (keep) - { - /* - * Pull the network buffer off the Rx ring queue - */ - cur_nbuf = nbuf_remove(NBUF_RX_RING); -// ASSERT(cur_nbuf); -// ASSERT(cur_nbuf->data == pRxBD->data); - - /* - * Copy the buffer descriptor information to the network buffer - */ - cur_nbuf->length = (pRxBD->length - (ETH_HDR_LEN + ETH_CRC_LEN)); - cur_nbuf->offset = ETH_HDR_LEN; - - /* - * Get a new buffer pointer for this buffer descriptor - */ - new_nbuf = nbuf_alloc(); - if (new_nbuf == NULL) - { - #ifdef DEBUG_PRINT - Cconws("nbuf_alloc() failed\r\n"); - #endif - /* - * Can't allocate a new network buffer, so we - * have to trash the received data and reuse the buffer - * hoping that some buffers will free up in the system - * and this frame will be re-transmitted by the host - */ - pRxBD->length = RX_BUF_SZ; - pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); - pRxBD->status |= RX_BD_E; - nbuf_add(NBUF_RX_RING, cur_nbuf); - fec_rx_continue(ch); - continue; - } - -#ifdef DEBUG_PRINT - { - int i; - for(i = 0; i < pRxBD->length; hex_byte(pRxBD->data[i++]), display_char(' ')); - display_string("\r\n"); - } -#endif - - /* - * Add the new network buffer to the Rx ring queue - */ - nbuf_add(NBUF_RX_RING, new_nbuf); - - /* - * Re-initialize the buffer descriptor - pointing it - * to the new data buffer. The previous data buffer - * will be passed up the stack - */ - pRxBD->data = new_nbuf->data; - pRxBD->length = RX_BUF_SZ; - pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); - pRxBD->status |= RX_BD_E; - - - /* - * Let the DMA know that there is a new Rx BD (in case the - * ring was full and the DMA was waiting for an empty one) - */ - fec_rx_continue(ch); - - /* - * Get pointer to the frame data inside the network buffer - */ - eth_hdr = (ETH_HDR *)cur_nbuf->data; - - /* - * Pass the received packet up the network stack if the - * protocol is supported in our network interface (NIF) - */ - if (nif_protocol_exist(nif,eth_hdr->type)) - { - nif_protocol_handler(nif, eth_hdr->type, cur_nbuf); - } - else - nbuf_free(cur_nbuf); - } - else - { - /* - * This frame isn't a keeper - * Reset the status and length, but don't need to get another - * buffer since we are trashing the data in the current one - */ - pRxBD->length = RX_BUF_SZ; - pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); - pRxBD->status |= RX_BD_E; - - /* - * Move the current buffer from the beginning to the end of the - * Rx ring queue - */ - cur_nbuf = nbuf_remove(NBUF_RX_RING); - nbuf_add(NBUF_RX_RING, cur_nbuf); - - /* - * Let the DMA know that there are new Rx BDs (in case - * it is waiting for an empty one) - */ - fec_rx_continue(ch); - } - } -} - -void -fec0_rx_frame(void) -{ - fec_rx_frame(0, &nif[0]); -} - -void -fec1_rx_frame(void) -{ - fec_rx_frame(1, &nif[1]); -} -/********************************************************************/ -/* - * Start the FEC Tx DMA task - * - * Parameters: - * ch FEC channel - * txbd First Tx buffer descriptor in the chain - */ -void -fec_tx_start(uint8 ch, int8 *txbd, uint8 pri) -{ - uint32 initiator; - int channel, result; - void fec0_tx_frame(void); - void fec1_tx_frame(void); - - /* - * Make the initiator assignment - */ - result = dma_set_initiator(DMA_FEC_TX(ch)); -// ASSERT(result == 0); - - /* - * Grab the initiator number - */ - initiator = dma_get_initiator(DMA_FEC_TX(ch)); -// ASSERT(initiator != 0); - - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_set_channel(DMA_FEC_TX(ch), - (ch == 0) ? fec0_tx_frame : fec1_tx_frame); -// ASSERT(channel != -1); - - /* - * Start the Tx DMA task - */ - MCD_startDma(channel, - (s8*)txbd, - 0, - (s8*)MCF_FEC_FECTFDR_ADDR(ch), - 0, - ETH_MTU, - 0, - initiator, - (int)pri, - 0 | MCD_FECTX_DMA - | MCD_INTERRUPT - | MCD_TT_FLAGS_CW - | MCD_TT_FLAGS_RL - | MCD_TT_FLAGS_SP - , - 0 | MCD_NO_CSUM - | MCD_NO_BYTE_SWAP - ); -} -/********************************************************************/ -/* - * Stop all transmissions on the selected FEC and kill the DMA task - * - * Parameters: - * ch FEC channel - */ -void -fec_tx_stop (uint8 ch) -{ - uint32 mask; - int channel; - -// ASSERT(ch == 0 || ch == 1); - - /* Save off the EIMR value */ - mask = MCF_FEC_EIMR(ch); - - /* Mask all interrupts */ - MCF_FEC_EIMR(ch) = 0; - - /* If the Ethernet is still enabled... */ - if (MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN) - { - /* Issue the Graceful Transmit Stop */ - MCF_FEC_TCR(ch) |= MCF_FEC_TCR_GTS; - - /* Wait for the Graceful Stop Complete interrupt */ - while(!(MCF_FEC_EIR(ch) & MCF_FEC_EIR_GRA)) - { - if (!(MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN)) - break; - } - - /* Clear the Graceful Stop Complete interrupt */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_GRA; - } - - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_TX(ch)); -// ASSERT(channel != -1); - - /* Kill the FEC Tx DMA task */ - if (channel != -1) - MCD_killDma(channel); - - /* - * Free up the FEC requestor from the software maintained - * initiator list - */ - dma_free_initiator(DMA_FEC_TX(ch)); - - /* Free up the DMA channel */ - dma_free_channel(DMA_FEC_TX(ch)); - - /* Restore the interrupt mask register value */ - MCF_FEC_EIMR(ch) = mask; -} -/********************************************************************/ -/* - * Trasmit Frame interrupt handler - this handler is called when the - * DMA FEC Tx task generates an interrupt - * - * Parameters: - * ch FEC channel - */ -void -fec_tx_frame(uint8 ch) -{ - FECBD *pTxBD; - NBUF *pNbuf; - -#ifdef DEBUG_PRINT - display_string("fec_tx_frame\r\n"); -#endif - - while ((pTxBD = fecbd_tx_free(ch)) != NULL) - { - fec_log[ch].dtxf++; - - /* - * Grab the network buffer associated with this buffer descriptor - */ - pNbuf = nbuf_remove(NBUF_TX_RING); -// ASSERT(pNbuf); -// ASSERT(pNbuf->data == pTxBD->data); - - /* - * Free up the network buffer that was just transmitted - */ - nbuf_free(pNbuf); - - /* - * Re-initialize the Tx BD - */ - pTxBD->data = NULL; - pTxBD->length = 0; - } -} - -void -fec0_tx_frame(void) -{ - fec_tx_frame(0); -} - -void -fec1_tx_frame(void) -{ - fec_tx_frame(1); -} -/********************************************************************/ -/* - * Send a packet out the selected FEC - * - * Parameters: - * ch FEC channel - * nif Pointer to Network Interface (NIF) structure - * dst Destination MAC Address - * src Source MAC Address - * type Ethernet Frame Type - * length Number of bytes to be transmitted (doesn't include type, - * src, or dest byte count) - * pkt Pointer packet network buffer - * - * Return Value: - * 1 success - * 0 otherwise - */ -int -fec_send (uint8 ch, uint8 *dst, uint8 *src, uint16 type, NBUF *nbuf) -{ - FECBD *pTxBD; - int i, channel; - uint32 mask; -// ASSERT(ch == 0 || ch == 1); - - /* Check the length */ - if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU) - return 0; - - /* - * Copy the destination address, source address, and Ethernet - * type into the packet - */ - memcpy(&nbuf->data[0], dst, 6); - memcpy(&nbuf->data[6], src, 6); - memcpy(&nbuf->data[12], &type, 2); - - /* - * Grab the next available Tx Buffer Descriptor - */ -#if 0 - timer_set_secs(TIMER_NETWORK+1, 1); - while ((pTxBD = fecbd_tx_alloc(ch)) == NULL) - { - if(!timer_get_reference(1)) - { - #ifdef DEBUG_PRINT - Cconws("Unable to allocate a free TxBD\r\n"); -// fecbd_dump(ch); -// nbuf_debug_dump(); -// fec_reg_dump(ch); -// dma_reg_dump(); -// fec_log_dump(ch); - #endif - return 0; - } - } -#else - for (i = 0; i < 1000; ++i) - { - if ((pTxBD = fecbd_tx_alloc(ch)) != NULL) - break; - } - if (i == 1000) - { - #ifdef DEBUG_PRINT - Cconws("Unable to allocate a free TxBD\r\n"); -// fecbd_dump(ch); -// nbuf_debug_dump(); -// fec_reg_dump(ch); -// dma_reg_dump(); -// fec_log_dump(ch); - #endif - return 0; - } -#endif - - /* - * Put the network buffer into the Tx waiting queue - */ - nbuf_add(NBUF_TX_RING, nbuf); - -#ifdef DEBUG_PRINT - display_string("fec_send\r\n"); - for(i = 0; i < nbuf->length + ETH_HDR_LEN; hex_byte(nbuf->data[i++]), display_char(' ')); - display_string("\r\n"); -#endif - -#if (__GNUC__ > 3) - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ -#else - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5200\n\t"); /* from CF68KLIB */ -#endif - - /* Save off the EIMR value */ - mask = MCF_FEC_EIMR(ch); - - /* Mask all interrupts */ - MCF_FEC_EIMR(ch) = 0; - - /* - * Setup the buffer descriptor for transmission - */ - pTxBD->data = nbuf->data; - pTxBD->length = nbuf->length + ETH_HDR_LEN; - pTxBD->status |= (TX_BD_R | TX_BD_L); - - /* Restore the interrupt mask register value */ - MCF_FEC_EIMR(ch) = mask; - - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_TX(ch)); -// ASSERT(channel != -1); - - /* - * Continue/restart the DMA task - */ - if (channel != -1) - MCD_continDma((int)channel); - - return 1; -} - -int -fec0_send(uint8 *dst, uint8 *src, uint16 type, NBUF *nbuf) -{ - return fec_send(0, dst, src, type, nbuf); -} - -int -fec1_send(uint8 *dst, uint8 *src, uint16 type, NBUF *nbuf) -{ - return fec_send(1, dst, src, type, nbuf); -} -/********************************************************************/ -/* - * Enable interrupts on the selected FEC - * - * Parameters: - * ch FEC channel - * pri Interrupt Priority - * lvl Interrupt Level - */ -void -fec_irq_enable(uint8 ch, uint8 lvl, uint8 pri) -{ -// ASSERT(ch == 0 || ch == 1); -// ASSERT(lvl > 0 && lvl < 8); -// ASSERT(pri < 8); - - /* - * Setup the appropriate ICR - */ - MCF_INTC_ICRn((ch == 0) ? 39 : 38) = (uint8)(0 - | MCF_INTC_ICRn_IP(pri) - | MCF_INTC_ICRn_IL(lvl)); - - /* - * Clear any pending FEC interrupt events - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL; - - /* - * Unmask all FEC interrupts - */ - MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_UNMASK_ALL; - - /* - * Unmask the FEC interrupt in the interrupt controller - */ - if (ch == 0) - MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK39; - else - MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK38; -} -/********************************************************************/ -/* - * Disable interrupts on the selected FEC - * - * Parameters: - * ch FEC channel - */ -void -fec_irq_disable(uint8 ch) -{ -// ASSERT(ch == 0 || ch == 1); - - /* - * Mask all FEC interrupts - */ - MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL; - - /* - * Mask the FEC interrupt in the interrupt controller - */ - if (ch == 0) - MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK39; - else - MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK38; -} -/********************************************************************/ -/* - * FEC interrupt handler - * All interrupts are multiplexed into a single vector for each - * FEC module. The lower level interrupt handler passes in the - * channel to this handler. Note that the receive interrupt is - * generated by the Multi-channel DMA FEC Rx task. - * - * Parameters: - * ch FEC channel - */ -void -fec_irq_handler(uint8 ch) -{ - uint32 event; - - /* - * Determine which interrupt(s) asserted by AND'ing the - * pending interrupts with those that aren't masked. - */ - event = MCF_FEC_EIR(ch) & MCF_FEC_EIMR(ch); - - #ifdef DEBUG_PRINT - display_string("fec_int\r\n"); - if (event != MCF_FEC_EIR(ch)) - display_string("Pending but not enabled\r\n"); -// Cconws("Pending but not enabled\r\n"); -// printf("Pending but not enabled: 0x%08X\r\n",(event ^ MCF_FEC_EIR(ch))); - #endif - - /* - * Clear the event(s) in the EIR immediately - */ - MCF_FEC_EIR(ch) = event; - - if (event & MCF_FEC_EIR_RFERR) - { - fec_log[ch].errors++; - fec_log[ch].rferr++; - #ifdef DEBUG_PRINT - display_string("RFERR\r\n"); -// Cconws("RFERR\r\n"); -// printf("FECRFSR%d = 0x%08x\n",ch,MCF_FEC_FECRFSR(ch)); - fec_eth_stop(ch); - #endif - } - if (event & MCF_FEC_EIR_XFERR) - { - fec_log[ch].errors++; - fec_log[ch].xferr++; - #ifdef DEBUG_PRINT - display_string("XFERR\r\n"); -// Cconws("XFERR\r\n"); - #endif - } - if (event & MCF_FEC_EIR_XFUN) - { - fec_log[ch].errors++; - fec_log[ch].xfun++; - #ifdef DEBUG_PRINT - display_string("XFUN\r\n"); -// Cconws("XFUN\r\n"); - fec_eth_stop(ch); - #endif - } - if (event & MCF_FEC_EIR_RL) - { - fec_log[ch].errors++; - fec_log[ch].rl++; - #ifdef DEBUG_PRINT - display_string("RL\r\n"); -// Cconws("RL\r\n"); - #endif - } - if (event & MCF_FEC_EIR_LC) - { - fec_log[ch].errors++; - fec_log[ch].lc++; - #ifdef DEBUG_PRINT - display_string("LC\r\n"); -// Cconws("LC\r\n"); - #endif - } - if (event & MCF_FEC_EIR_MII) - { - fec_log[ch].mii++; - } - if (event & MCF_FEC_EIR_TXF) - { - fec_log[ch].txf++; - } - if (event & MCF_FEC_EIR_GRA) - { - fec_log[ch].gra++; - } - if (event & MCF_FEC_EIR_BABT) - { - fec_log[ch].errors++; - fec_log[ch].babt++; - #ifdef DEBUG_PRINT - display_string("BABT\r\n"); -// Cconws("BABT\r\n"); - #endif - } - if (event & MCF_FEC_EIR_BABR) - { - fec_log[ch].errors++; - fec_log[ch].babr++; - #ifdef DEBUG_PRINT - display_string("BABR\r\n"); -// Cconws("BABR\r\n"); - #endif - } - if (event & MCF_FEC_EIR_HBERR) - { - fec_log[ch].errors++; - fec_log[ch].hberr++; - #ifdef DEBUG_PRINT - display_string("HBERR\r\n"); -// Cconws("HBERR\r\n"); - #endif - } -} - -/********************************************************************/ -/* - * Configure the selected Ethernet port and enable all operations - * - * Parameters: - * ch FEC channel - * trcvr Transceiver mode (MII, 7-Wire or internal loopback) - * speed Maximum operating speed (valid in MII mode only) - * duplex Full or Half-duplex (MII only) - * mac Physical (MAC) Address - * sys_clk System clock frequency - used for MII speed calculation - * phya Address of the MII Phy (valid in MII mode only) - * flvl FEC interrupt level - * fpri FEC interrupt priority - * dtxpri Tx DMA task priority - * drxpri Rx DMA task priority - * - * Return Value: - * 1 if the Ethernet was successfully started - * 0 otherwise - */ -int -fec_eth_start(uint8 ch, uint8 trcvr, uint8 speed, uint8 duplex, uint8 *mac, - int sys_clk, uint8 phya, uint8 flvl, uint8 fpri, - uint8 dtxpri, uint8 drxpri) -{ -// ASSERT(ch == 0 || ch == 1); - - /* - * Disable FEC interrupts - */ - fec_irq_disable(ch); - - /* - * Initialize the event log - */ - fec_log_init(ch); - - /* - * Initialize the network buffers and fec buffer descriptors - */ - if (nbuf_init() != 0) - return 0; - - fecbd_init(ch); - - /* - * Initialize the FEC - */ - fec_reset(ch); - fec_init(ch, trcvr, duplex, mac); - - if (trcvr == FEC_MODE_MII) - { - /* Initialize the PHY interface */ - if (!phy_init(ch, phya, speed, duplex)) - { - /* Flush the network buffers */ - nbuf_flush(); - return 0; - } - } - - /* - * Enable the multi-channel DMA tasks - */ - fec_rx_start(ch, (int8*)fecbd_get_start(ch,Rx), drxpri); - fec_tx_start(ch, (int8*)fecbd_get_start(ch,Tx), dtxpri); - - /* - * Initialize and enable FEC interrupts - */ - fec_irq_enable(ch, flvl, fpri); - - /* - * Enable the FEC channel - */ - MCF_FEC_ECR(ch) |= MCF_FEC_ECR_ETHER_EN; - - return 1; -} -/********************************************************************/ -/* - * Stop the selected Ethernet port - * - * Parameters: - * ch FEC channel - */ -void -fec_eth_stop(uint8 ch) -{ - int level; - - /* - * Disable interrupts - */ - level = asm_set_ipl(7); - - /* - * Gracefully disable the receiver and transmitter - */ - fec_tx_stop(ch); - fec_rx_stop(ch); - - /* - * Disable FEC interrupts - */ - fec_irq_disable(ch); - - /* - * Disable the FEC channel - */ - MCF_FEC_ECR(ch) &= ~MCF_FEC_ECR_ETHER_EN; - - /* - * Flush the network buffers - */ - nbuf_flush(); - - /* - * Restore interrupt level - */ - asm_set_ipl(level); -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/fec.h b/flash.tos/drivers/net/fec.h deleted file mode 100644 index 1c6294d..0000000 --- a/flash.tos/drivers/net/fec.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * File: fec.h - * Purpose: Driver for the Fast Ethernet Controller (FEC) - * - * Notes: - */ - -#ifndef _FEC_H_ -#define _FEC_H_ - -/********************************************************************/ -/* MII Speed Settings */ -#define FEC_MII_10BASE_T 0 -#define FEC_MII_100BASE_TX 1 - -/* MII Duplex Settings */ -#define FEC_MII_HALF_DUPLEX 0 -#define FEC_MII_FULL_DUPLEX 1 - -/* Timeout for MII communications */ -#define FEC_MII_TIMEOUT 0x10000 - -/* External Interface Modes */ -#define FEC_MODE_7WIRE 0 -#define FEC_MODE_MII 1 -#define FEC_MODE_LOOPBACK 2 /* Internal Loopback */ - -/* - * FEC Event Log - */ -typedef struct { - int errors; /* total count of errors */ - int hberr; /* heartbeat error */ - int babr; /* babbling receiver */ - int babt; /* babbling transmitter */ - int gra; /* graceful stop complete */ - int txf; /* transmit frame */ - int mii; /* MII */ - int lc; /* late collision */ - int rl; /* collision retry limit */ - int xfun; /* transmit FIFO underrrun */ - int xferr; /* transmit FIFO error */ - int rferr; /* receive FIFO error */ - int dtxf; /* DMA transmit frame */ - int drxf; /* DMA receive frame */ - int rfsw_inv; /* Invalid bit in RFSW */ - int rfsw_l; /* RFSW Last in Frame */ - int rfsw_m; /* RFSW Miss */ - int rfsw_bc; /* RFSW Broadcast */ - int rfsw_mc; /* RFSW Multicast */ - int rfsw_lg; /* RFSW Length Violation */ - int rfsw_no; /* RFSW Non-octet */ - int rfsw_cr; /* RFSW Bad CRC */ - int rfsw_ov; /* RFSW Overflow */ - int rfsw_tr; /* RFSW Truncated */ -} FEC_EVENT_LOG; - - -int -fec_mii_write(uint8 , uint8 , uint8 , uint16 ); - -int -fec_mii_read(uint8 , uint8 , uint8 , uint16 *); - -void -fec_mii_init(uint8, uint32); - -void -fec_mib_init(uint8); - -void -fec_mib_dump(uint8); - -void -fec_log_init(uint8); - -void -fec_log_dump(uint8); - -void -fec_reg_dump(uint8); - -void -fec_duplex (uint8, uint8); - -uint8 -fec_hash_address(const uint8 *); - -void -fec_set_address (uint8 ch, const uint8 *); - -void -fec_reset (uint8); - -void -fec_init (uint8, uint8, uint8, const uint8 *); - -void -fec_rx_start(uint8, int8 *, uint8); - -void -fec_rx_continue(uint8); - -void -fec_rx_restart(uint8); - -void -fec_rx_stop (uint8); - -void -fec_rx_frame(uint8, NIF *); - -void -fec0_rx_frame(void); - -void -fec1_rx_frame(void); - -void -fec_tx_start(uint8, int8 *, uint8); - -void -fec_tx_continue(uint8); - -void -fec_tx_restart(uint8); - -void -fec_tx_stop (uint8); - -void -fec_tx_frame(uint8); - -void -fec0_tx_frame(void); - -void -fec1_tx_frame(void); - -int -fec_send (uint8 , uint8 *, uint8 *, uint16 , NBUF *); - -int -fec0_send(uint8 *, uint8 *, uint16 , NBUF *); - -int -fec1_send(uint8 *, uint8 *, uint16 , NBUF *); - -void -fec_irq_handler(uint8 ch); - -void -fec_irq_enable(uint8, uint8, uint8); - -void -fec_irq_disable(uint8); - -int -fec_eth_start(uint8, uint8, uint8, uint8, uint8 *, int, - uint8, uint8, uint8, uint8, uint8); - -void -fec_eth_stop(uint8); - -/********************************************************************/ - -#endif /* _FEC_H_ */ diff --git a/flash.tos/drivers/net/fecbd.c b/flash.tos/drivers/net/fecbd.c deleted file mode 100644 index b7084ea..0000000 --- a/flash.tos/drivers/net/fecbd.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * File: fecbd.c - * Purpose: Provide a simple buffer management driver - * - * Notes: - */ - -#include -#include "config.h" -#include "net.h" -#include "../mcdapi/MCD_dma.h" -#include "fecbd.h" -#include "nbuf.h" -#include "eth.h" - -extern void ltoa(char *buf, long n, unsigned long base); - -#ifdef NETWORK -#ifndef LWIP - -/* - * This implements a simple static buffer descriptor - * ring for each channel and each direction - * - * FEC Buffer Descriptors need to be aligned to a 4-byte boundary. - * In order to accomplish this, data is over-allocated and manually - * aligned at runtime - * - * Enough space is allocated for each of the two FEC channels to have - * NRXBD Rx BDs and NTXBD Tx BDs - * - */ -FECBD unaligned_bds[(2 * NRXBD) + (2 * NTXBD) + 1]; - -/* - * These pointers are used to reference into the chunck of data set - * aside for buffer descriptors - */ -FECBD *RxBD; -FECBD *TxBD; - -/* - * Macros to easier access to the BD ring - */ -#define RxBD(ch, i) RxBD[(ch * NRXBD) + i] -#define TxBD(ch, i) TxBD[(ch * NRXBD) + i] - -/* - * Buffer descriptor indexes - */ -static int iTxbd_new; -static int iTxbd_old; -static int iRxbd; - -/********************************************************************/ -/* - * Initialize the FEC Buffer Descriptor ring - * Buffer Descriptor format is defined by the MCDAPI - * - * Parameters: - * ch FEC channel - */ -void -fecbd_init(uint8 ch) -{ - NBUF *nbuf; - int i; - - /* - * Align Buffer Descriptors to 4-byte boundary - */ - RxBD = (FECBD *)(((int)unaligned_bds + 3) & 0xFFFFFFFC); - TxBD = (FECBD *)((int)RxBD + (sizeof(FECBD) * 2 * NTXBD)); - - /* - * Initialize the Rx Buffer Descriptor ring - */ - for (i = 0; i < NRXBD; ++i) - { - /* Grab a network buffer from the free list */ - nbuf = nbuf_alloc(); -// ASSERT(nbuf); - - /* Initialize the BD */ - RxBD(ch, i).status = RX_BD_E | RX_BD_INTERRUPT; - RxBD(ch, i).length = RX_BUF_SZ; - RxBD(ch, i).data = nbuf->data; - - /* Add the network buffer to the Rx queue */ - nbuf_add(NBUF_RX_RING, nbuf); - } - - /* - * Set the WRAP bit on the last one - */ - RxBD(ch, i-1).status |= RX_BD_W; - - /* - * Initialize the Tx Buffer Descriptor ring - */ - for (i = 0; i < NTXBD; ++i) - { - TxBD(ch, i).status = TX_BD_INTERRUPT; - TxBD(ch, i).length = 0; - TxBD(ch, i).data = NULL; - } - - /* - * Set the WRAP bit on the last one - */ - TxBD(ch, i-1).status |= TX_BD_W; - - /* - * Initialize the buffer descriptor indexes - */ - iTxbd_new = iTxbd_old = iRxbd = 0; -} -/********************************************************************/ -void -fecbd_dump(uint8 ch) -{ -#ifdef DEBUG_PRINT - int i; - char buf[10]; - if(ch == 0) - Cconws("\r\n------------ FEC0"); - else - Cconws("\r\n------------ FEC1"); - Cconws(" BDs -----------\r\n"); - Cconws("RxBD Ring\r\n"); - for (i=0; i -#include "config.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -/********************************************************************/ -void -dump_icmp_frame (icmp_message *msg) -{ - switch (msg->type) - { - case ICMP_DEST_UNREACHABLE: - Cconws("ICMP : "); - switch (msg->code) - { - case ICMP_NET_UNREACHABLE: - Cconws("Net Unreachable\r\n"); - break; - case ICMP_HOST_UNREACHABLE: - Cconws("Host Unreachable\r\n"); - break; - case ICMP_PROTOCOL_UNREACHABLE: - Cconws("Protocol Unreachable\r\n"); - break; - case ICMP_PORT_UNREACHABLE: - Cconws("Port Unreachable\r\n"); - break; - case ICMP_FRAG_NEEDED: - Cconws("Fragmentation needed and DF set\r\n"); - break; - case ICMP_ROUTE_FAILED: - Cconws("Source route failed\r\n"); - break; - default: - Cconws("Destination Unreachable\r\n"); - break; - } - break; - case ICMP_TIME_EXCEEDED: - Cconws("ICMP_TIME_EXCEEDED\r\n"); - break; - case ICMP_PARAMETER_PROBLEM: - Cconws("ICMP_PARAMETER_PROBLEM\r\n"); - break; - case ICMP_SOURCE_QUENCH: - Cconws("ICMP_SOURCE_QUENCH\r\n"); - break; - case ICMP_REDIRECT: - Cconws("ICMP_REDIRECT\r\n"); - break; - case ICMP_ECHO: - Cconws("ICMP_ECHO\r\n"); - break; - case ICMP_ECHO_REPLY: - Cconws("ICMP_ECHO_REPLY\r\n"); - break; - case ICMP_INFORMATION_REQUEST: - Cconws("ICMP_INFORMATION_REQUEST\r\n"); - break; - case ICMP_INFORMATION_REPLY: - Cconws("ICMP_INFORMATION_REPLY\r\n"); - break; - case ICMP_TIMESTAMP: - Cconws("ICMP_TIMESTAMP\r\n"); - break; - case ICMP_TIMESTAMP_REPLY: - Cconws("ICMP_TIMESTAMP_REPLY\r\n"); - break; - default: - Cconws("Unknown ICMP message\r\n"); - break; - } -} - -/********************************************************************/ -void -icmp_handler (NIF *nif, NBUF *pNbuf) -{ - /* - * This function handles the ICMP packets. - */ - icmp_message *icmpmsg; - ip_frame_hdr *ipframe; - uint8 src[4], dest[4]; - - icmpmsg = (icmp_message *)&pNbuf->data[pNbuf->offset]; - - switch (icmpmsg->type) - { - case ICMP_ECHO: - /* - * Change ICMP echo message into a echo reply message - */ - icmpmsg->type = ICMP_ECHO_REPLY; - - /* - * Recompute checksum - */ - icmpmsg->chksum = 0; - icmpmsg->chksum = ip_chksum((uint16 *)icmpmsg,pNbuf->length); - - /* - * Send the Echo Reply - */ - ipframe = (ip_frame_hdr *)&pNbuf->data[IP_HDR_OFFSET]; - memcpy(dest, &ipframe->source_addr[0], 4); - memcpy(src, &ipframe->dest_addr[0], 4); - ip_send(nif, dest, src, ipframe->protocol, pNbuf); - break; - case ICMP_DEST_UNREACHABLE: - case ICMP_TIME_EXCEEDED: - case ICMP_PARAMETER_PROBLEM: - case ICMP_SOURCE_QUENCH: - case ICMP_REDIRECT: - case ICMP_ECHO_REPLY: - case ICMP_INFORMATION_REQUEST: - case ICMP_INFORMATION_REPLY: - case ICMP_TIMESTAMP: - case ICMP_TIMESTAMP_REPLY: - default: - dump_icmp_frame(icmpmsg); - nbuf_free(pNbuf); - break; - } -} - -/******************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/icmp.h b/flash.tos/drivers/net/icmp.h deleted file mode 100644 index 955009f..0000000 --- a/flash.tos/drivers/net/icmp.h +++ /dev/null @@ -1,121 +0,0 @@ -/* - * File: icmp.h - * Purpose: Handle Internet Control Message Protocol packets. - * - * Notes: See RFC 792 "Internet Control Message Protocol" - * for more details. - */ - -#ifndef _ICMP_H -#define _ICMP_H - -/********************************************************************/ - -typedef struct -{ - uint32 unused; - uint8 ih_dg; -} icmp_dest_unreachable; -#define ICMP_DEST_UNREACHABLE (3) /* type */ -#define ICMP_NET_UNREACHABLE (0) /* code */ -#define ICMP_HOST_UNREACHABLE (1) -#define ICMP_PROTOCOL_UNREACHABLE (2) -#define ICMP_PORT_UNREACHABLE (3) -#define ICMP_FRAG_NEEDED (4) -#define ICMP_ROUTE_FAILED (5) - -typedef struct -{ - uint32 unused; - uint8 ih_dg; -} icmp_time_exceeded; -#define ICMP_TIME_EXCEEDED (11) /* type */ -#define ICMP_TTL_EXCEEDED (0) /* code */ -#define ICMP_FRAG_TIME_EXCEEDED (1) - -typedef struct -{ - uint8 pointer; - uint8 unused1; - uint16 unused2; - uint8 ih_dg; -} icmp_parameter_problem; -#define ICMP_PARAMETER_PROBLEM (12) /* type */ -#define ICMP_POINTER (0) /* code -- not */ - -typedef struct -{ - uint32 unused; - uint8 ih_dg; -} icmp_source_quench; -#define ICMP_SOURCE_QUENCH (4) /* type */ - -typedef struct -{ - uint32 gateway_addr; - uint8 ih_dg; -} icmp_redirect; -#define ICMP_REDIRECT (5) /* type */ -#define ICMP_REDIRECT_NET (0) /* code */ -#define ICMP_REDIRECT_HOST (1) -#define ICMP_REDIRECT_TOS_NET (2) -#define ICMP_REDIRECT_TOS_HOST (3) - -typedef struct -{ - uint16 identifier; - uint16 sequence; - uint8 data; -} icmp_echo; -#define ICMP_ECHO (8) /* type */ -#define ICMP_ECHO_REPLY (0) /* type */ - -typedef struct -{ - uint16 identifier; - uint16 sequence; -} icmp_information; -#define ICMP_INFORMATION_REQUEST (15) /* type */ -#define ICMP_INFORMATION_REPLY (16) /* type */ - -typedef struct -{ - uint16 identifier; - uint16 sequence; - uint32 originate_ts; - uint32 receive_ts; - uint32 transmit_ts; -} icmp_timestamp; -#define ICMP_TIMESTAMP (13) /* type */ -#define ICMP_TIMESTAMP_REPLY (14) /* type */ - -typedef struct -{ - uint8 type; - uint8 code; - uint16 chksum; - union - { - icmp_dest_unreachable dest_unreachable; - icmp_source_quench source_quench; - icmp_redirect redirect; - icmp_time_exceeded time_exceeded; - icmp_parameter_problem parameter_problem; - icmp_timestamp timestamp; - icmp_information information; - icmp_echo echo; - } msg; -} icmp_message; - -/********************************************************************/ - -/* Protocol Header information */ -#define ICMP_HDR_OFFSET (ETH_HDR_LEN + IP_HDR_SIZE) -#define ICMP_HDR_SIZE 8 - -void -icmp_handler(NIF *, NBUF *); - -/********************************************************************/ - -#endif /* _ICMP_H */ diff --git a/flash.tos/drivers/net/init.c b/flash.tos/drivers/net/init.c deleted file mode 100644 index 2678bb5..0000000 --- a/flash.tos/drivers/net/init.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * File: init.c - * Purpose: Board specific routines for M5485EVB and the M5475EVB - * - * Notes: - * - */ - -#include -#include "config.h" -#include "ct60.h" -#include "net.h" -#include "get.h" -#include "fec.h" -#include "dma_utils.h" -#include "../mcdapi/MCD_dma.h" - -#define OFFSET_INT_CF68KLIB (64) -#define V_FEC0 (64+39+OFFSET_INT_CF68KLIB) -#define V_FEC1 (64+38+OFFSET_INT_CF68KLIB) -#define V_DMA (64+48+OFFSET_INT_CF68KLIB) - -extern void fec0_int(void); -extern void fec1_int(void); -extern void ltoa(char *buf, long n, unsigned long base); - -#ifdef NETWORK -#ifndef LWIP - -/* Define one network interface */ - -IP_INFO ip_info; -ARP_INFO arp_info; - -static void fec0_interrupt(void) -{ - asm volatile ( - "_fec0_int:\n\t" - " lea -24(SP),SP\n\t" - " movem.l D0-D2/A0-A2,(SP)\n\t" - " clr.l -(SP)\n\t" - " jsr _fec_irq_handler\n\t" - " addq.l #4,SP\n\t" - " movem.l (SP),D0-D2/A0-A2\n\t" - " lea 24(SP),SP\n\t" - " rte\n\t" ); -} - -static void fec1_interrupt(void) -{ - "_fec1_int:\n\t" - " lea -24(SP),SP\n\t" - " movem.l D0-D2/A0-A2,(SP)\n\t" - " pea 1\n\t" - " jsr _fec_irq_handler\n\t" - " addq.l #4,SP\n\t" - " movem.l (SP),D0-D2/A0-A2\n\t" - " lea 24(SP),SP\n\t" - " rte\n\t" ); -} - -#ifdef TEST_NETWORK - -/********************************************************************/ -/* - * Physical (MAC) Addresses - */ -ETH_ADDR src = {0x00,0xCF,0x54,0x85,0xCF,0x00}; -ETH_ADDR dst = {0x00,0xCF,0x54,0x85,0xCF,0x01}; -ETH_ADDR bcst = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - -/* - * The packet to send - the Tx buffer must be 32-bit aligned, so - * it is declared as a uin32 here so the linker will automatically - * align it on that boundary. - */ -uint32 packet[1520/sizeof(uint32)]; - -/* - * Get access to the log kept by fec.c - */ -extern FEC_EVENT_LOG fec_log[]; - -/********************************************************************/ -/* - * Transmit Test on an individual FEC channel - * - * Parameters: - * ch FEC channel - * mode Transceiver mode (MII, 7-Wire or internal loopback) - * speed Maximum operating speed (MII only) - * duplex Full or Half-duplex (MII only) - * - * Return Value: - * 0 if tests are successful - * 1 otherwise - */ -int tx_test(uint8 ch, uint8 mode, uint8 speed, uint8 duplex) -{ - int i, status; - NBUF *pNbuf; - - /* - * Display our test parameters - */ - Cconws("\r\n\r\nFEC"); - Cconout(ch+'0'); - Cconws(" Tx Test\r\nMode: "); - - if (mode == FEC_MODE_LOOPBACK) - Cconws("Internal Loopback"); - else if (mode == FEC_MODE_MII) - Cconws("MII"); - else - Cconws("7-Wire"); - Cconws("\r\n"); - - if (mode == FEC_MODE_MII) - { - Cconws("Speed: "); - if (speed == FEC_MII_10BASE_T) - Cconws("10"); - else - Cconws("100"); - Cconws("\r\nDuplex: "); - - if (duplex == FEC_MII_HALF_DUPLEX) - Cconws("HALF"); - else - Cconws("FULL"); - Cconws("\r\n"); - } - - /* Build the Tx Packet */ - for (i=0; ilength = i; - memcpy(pNbuf->data,(uint8 *)packet,i); - if (!fec_send(ch,dst,src,ETH_FRM_TEST,pNbuf)) - { - nbuf_free(pNbuf); - break; - } - if (++i > ETH_MAX_DATA) - break; - } - - /* Wait a bit to let the FEC finish up */ - for (i = 0; i < 1000000; asm volatile (" nop\n\t"); i++); - - /* Stop the Ethernet */ - fec_eth_stop(ch); - - /* - * Dump the FEC log - */ - fec_log_dump(ch); - - if ((fec_log[ch].dtxf != (ETH_MAX_DATA - ETH_MIN_DATA + 1)) || - (fec_log[ch].errors != 0) || - ((mode == FEC_MODE_LOOPBACK) && (fec_log[ch].dtxf != fec_log[ch].drxf))) - { - Cconws("Test failed\r\n"); - Cnecin(); - return 1; - } - else - { - Cconws("Test passed\r\n"); - return 0; - } -} - -#endif - -int net_init(uint8 ch) -{ - IP_ADDR client; - IP_ADDR gateway; - IP_ADDR netmask; - board_get_client(client); - board_get_gateway(gateway); - board_get_netmask(netmask); - arp_init(&arp_info); - nif_bind_protocol(&nif[ch],ETH_FRM_ARP,arp_handler,(void *)&arp_info); - ip_init(&ip_info,client,gateway,netmask); - nif_bind_protocol(&nif[ch],ETH_FRM_IP,ip_handler,(void *)&ip_info); - udp_init(); - return TRUE; -} - -int init_network(void) -{ - int status; - unsigned long cacr; - uint8 mac[6]; - if(fec0_interrupt); - if(fec1_interrupt); - Setexc(V_FEC0, fec0_int); - Setexc(V_FEC1, fec1_int); - /* disable the caches */ - cacr=ct60_cache(-1); - ct60_cache(0); -#ifdef TEST_NETWORK - tx_test(0,FEC_MODE_LOOPBACK,0,0); - tx_test(1,FEC_MODE_LOOPBACK,0,0); - tx_test(0,FEC_MODE_MII,FEC_MII_100BASE_TX,FEC_MII_FULL_DUPLEX); - tx_test(0,FEC_MODE_MII,FEC_MII_100BASE_TX,FEC_MII_HALF_DUPLEX); - tx_test(0,FEC_MODE_MII,FEC_MII_10BASE_T,FEC_MII_FULL_DUPLEX); - tx_test(0,FEC_MODE_MII,FEC_MII_10BASE_T,FEC_MII_HALF_DUPLEX); - tx_test(1,FEC_MODE_MII,FEC_MII_100BASE_TX,FEC_MII_FULL_DUPLEX); - tx_test(1,FEC_MODE_MII,FEC_MII_100BASE_TX,FEC_MII_HALF_DUPLEX); - tx_test(1,FEC_MODE_MII,FEC_MII_10BASE_T,FEC_MII_FULL_DUPLEX); - tx_test(1,FEC_MODE_MII,FEC_MII_10BASE_T,FEC_MII_HALF_DUPLEX); -#endif - /* Get user programmed MAC address */ - board_get_ethaddr(mac); - /* Initialize the network interface structure */ - nif_init(&nif[ETHERNET_PORT]); - nif[ETHERNET_PORT].mtu = ETH_MTU; - nif[ETHERNET_PORT].send = (ETHERNET_PORT == 0) ? fec0_send : fec1_send; - /* Initialize the Ethernet port */ - status = fec_eth_start(ETHERNET_PORT, /* Which FEC to use */ - FEC_MODE_MII, /* Use MII mode */ - FEC_MII_100BASE_TX, /* Allow 10 and 100Mbps */ - FEC_MII_FULL_DUPLEX, /* Allow Full and Half Duplex */ - mac, - SYSTEM_CLOCK, - FEC_PHY(ETHERNET_PORT), - FEC_INTC_LVL, - FEC_INTC_PRI, - FECTX_DMA_PRI, - FECRX_DMA_PRI); - /* enable the caches */ - if(cacr & 0x80008000) - ct60_cache(1); - if(!status) - { - /* Couldn't communicate with the PHY or the PHY - couldn't establish a link with a link partner */ - Cconws("Failed to start the Ethernet channel\r\n"); - return FALSE; - } - /* Copy the Ethernet address to the NIF structure */ - memcpy(nif[ETHERNET_PORT].hwa, mac, 6); -#ifdef DEBUG_PRINT - { - char buf[10]; - int i; - Cconws("Ethernet Address is "); - for (i = 0; i < 6; i++) - { - ltoa(buf, nif[ETHERNET_PORT].hwa[i], 16); - Cconws(buf); - if(i < 5) - Cconout(':'); - } - Cconws("\r\n"); - } -#endif - /* Initialize network stack */ - net_init(ETHERNET_PORT); - return TRUE; -} - -void end_network(void) -{ - /* Disable the Ethernet port */ - fec_eth_stop(ETHERNET_PORT); -} - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/ip.c b/flash.tos/drivers/net/ip.c deleted file mode 100644 index 4b06f73..0000000 --- a/flash.tos/drivers/net/ip.c +++ /dev/null @@ -1,352 +0,0 @@ -/* - * File: ip.c - * Purpose: Internet Protcol device driver - * - * Notes: - * - * Modifications: - */ -#include -#include "config.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -extern void ltoa(char *buf, long n, unsigned long base); - -/********************************************************************/ -void -ip_init(IP_INFO *info, - IP_ADDR_P myip, - IP_ADDR_P gateway, - IP_ADDR_P netmask) -{ - int index; - - for (index = 0; index < sizeof(IP_ADDR); index++) - { - info->myip[index] = myip[index]; - info->gateway[index] = gateway[index]; - info->netmask[index] = netmask[index]; - info->broadcast[index] = 0xFF; - } - - info->rx = 0; - info->rx_unsup = 0; - info->tx = 0; - info->err = 0; -} -/********************************************************************/ -uint8 * -ip_get_myip (IP_INFO *info) -{ - if (info != 0) - { - return (uint8 *)&info->myip[0]; - } - return 0; -} -/********************************************************************/ -int -ip_addr_compare (IP_ADDR_P addr1, IP_ADDR_P addr2) -{ - int i; - - for (i = 0; i < sizeof(IP_ADDR); i++) - { - if (addr1[i] != addr2[i]) - return 0; - } - return 1; -} -/********************************************************************/ -uint8 * -ip_resolve_route (NIF *nif, IP_ADDR_P destip) -{ - /* - * This function determines whether or not an outgoing IP - * packet needs to be transmitted on the local net or sent - * to the router for transmission. - */ - IP_INFO *info; - IP_ADDR mask,result; - int i; - - info = nif_get_protocol_info(nif,ETH_FRM_IP); - - /* create mask for local IP */ - for (i = 0; i < sizeof(IP_ADDR); i++) - { - mask[i] = info->myip[i] & info->netmask[i]; - } - - /* apply mask to the destination IP */ - for (i = 0; i < sizeof(IP_ADDR); i++) - { - result[i] = mask[i] & destip[i]; - } - - /* See if destination IP is local or not */ - if (ip_addr_compare(mask,result)) - { - /* The destination IP is on the local net */ - return arp_resolve(nif,ETH_FRM_IP,destip); - } - else - { - /* The destination IP is not on the local net */ - return arp_resolve(nif,ETH_FRM_IP,info->gateway); - } -} -/******************************************************************/ -int -ip_send (NIF *nif, uint8 *dest, uint8 *src, uint8 protocol, NBUF *pNbuf) -{ - /* - * This function assembles an IP datagram and passes it - * onto the hardware to be sent over the network. - */ - uint8 *route; - ip_frame_hdr *ipframe; - - /* - * Construct the IP header - */ - ipframe = (ip_frame_hdr*)&pNbuf->data[IP_HDR_OFFSET]; - - /* IP version 4, Internet Header Length of 5 32-bit words */ - ipframe->version_ihl = 0x45; - - /* Type of Service == 0, normal and routine */ - ipframe->service_type = 0x00; - - /* Total length of data */ - ipframe->total_length = (uint16)(pNbuf->length + IP_HDR_SIZE); - - /* User defined identification */ - ipframe->identification = 0x0000; - - /* Fragment Flags and Offset -- Don't fragment, last frag */ - ipframe->flags_frag_offset = 0x0000; - - /* Time To Live */ - ipframe->ttl = 0xFF; - - /* Protocol */ - ipframe->protocol = protocol; - - /* Checksum, computed later, zeroed for computation */ - ipframe->checksum = 0x0000; - - /* source IP address */ - ipframe->source_addr[0] = src[0]; - ipframe->source_addr[1] = src[1]; - ipframe->source_addr[2] = src[2]; - ipframe->source_addr[3] = src[3]; - - /* dest IP address */ - ipframe->dest_addr[0] = dest[0]; - ipframe->dest_addr[1] = dest[1]; - ipframe->dest_addr[2] = dest[2]; - ipframe->dest_addr[3] = dest[3]; - - /* Compute checksum */ - ipframe->checksum = ip_chksum((uint16 *)ipframe,IP_HDR_SIZE); - - /* Increment the packet length by the size of the IP header */ - pNbuf->length += IP_HDR_SIZE; - - /* - * Determine the hardware address of the recipient - */ - route = ip_resolve_route(nif, dest); - if (route == NULL) - { - char buf[10]; - int i; - Cconws("Unable to locate "); - for (i = 0; i < 4; i++) - { - ltoa(buf, dest[i], 10); - Cconws(buf); - if(i < 3) - Cconout('.'); - } - Cconws("\r\n"); - return 0; - } - - return nif->send(route, - &nif->hwa[0], - ETH_FRM_IP, - pNbuf - ); -} -/******************************************************************/ -#if defined(DEBUG_PRINT) -void -dump_ip_frame (ip_frame_hdr *ipframe) -{ - char buf[10]; - int i; - Cconws("Version: 0x"); - ltoa(buf, ((ipframe->version_ihl & 0x00f0) >> 4), 16); - Cconws(buf); - Cconws("IHL: 0x"); - ltoa(buf, ipframe->version_ihl & 0x000f, 16); - Cconws(buf); - Cconws("Service: 0x"); - ltoa(buf, ipframe->service_type, 16); - Cconws(buf); - Cconws("Length: 0x"); - ltoa(buf, ipframe->total_length, 16); - Cconws(buf); - Cconws("Ident: 0x"); - ltoa(buf, ipframe->identification, 16); - Cconws(buf); - Cconws("Flags: 0x"); - ltoa(buf, ((ipframe->flags_frag_offset & 0xC000) >> 14), 16); - Cconws(buf); - Cconws("Frag: 0x"); - ltoa(buf, ipframe->flags_frag_offset & 0x3FFF, 16); - Cconws(buf); - Cconws("TTL: 0x"); - ltoa(buf, ipframe->ttl, 16); - Cconws(buf); - Cconws("Protocol: 0x"); - ltoa(buf, ipframe->protocol, 16); - Cconws(buf); - Cconws("Chksum: 0x"); - ltoa(buf, ipframe->checksum, 16); - Cconws(buf); - Cconws("Source : "); - for (i = 0; i < 4; i++) - { - ltoa(buf, ipframe->source_addr[i], 10); - Cconws(buf); - if(i < 3) - Cconout('.'); - } - Cconws("\r\n"); - Cconws("Dest : "); - for (i = 0; i < 4; i++) - { - ltoa(buf, ipframe->dest_addr[i], 10); - Cconws(buf); - if(i < 3) - Cconout('.'); - } - Cconws("\r\n"); - Cconws("Options: 0x"); - ltoa(buf, ipframe->options, 16); - Cconws(buf); -} -#endif -/******************************************************************/ -uint16 -ip_chksum (uint16 *data, int num) -{ - int chksum, ichksum; - uint16 temp; - - chksum = 0; - num = num >> 1; /* from bytes to words */ - for (; num; num--, data++) - { - temp = *data; - ichksum = chksum + temp; - ichksum = ichksum & 0x0000FFFF; - if ((ichksum < temp) || (ichksum < chksum)) - { - ichksum += 1; - ichksum = ichksum & 0x0000FFFF; - } - chksum = ichksum; - } - return (uint16)~chksum; -} -/******************************************************************/ -static int -validate_ip_hdr (NIF *nif, ip_frame_hdr *ipframe) -{ - int index, chksum; - IP_INFO *info; - - /* - * Check the IP Version - */ - if (IP_VERSION(ipframe) != 4) - return 0; - - /* - * Check Internet Header Length - */ - if (IP_IHL(ipframe) < 5) - return 0; - - /* - * Check the destination IP address - */ - info = nif_get_protocol_info(nif,ETH_FRM_IP); - for (index = 0; index < sizeof(IP_ADDR); index++) - if (info->myip[index] != ipframe->dest_addr[index]) - return 0; - - /* - * Check the checksum - */ - chksum = (int)((uint16)IP_CHKSUM(ipframe)); - IP_CHKSUM(ipframe) = 0; - - if (ip_chksum((uint16 *)ipframe,IP_IHL(ipframe)*4) != chksum) - return 0; - - IP_CHKSUM(ipframe) = (uint16)chksum; - - return 1; -} -/******************************************************************/ -void -ip_handler (NIF *nif, NBUF *pNbuf) -{ - /* - * IP packet handler - */ - ip_frame_hdr *ipframe; - - ipframe = (ip_frame_hdr *)&pNbuf->data[pNbuf->offset]; - - /* - * Verify valid IP header and destination IP - */ - if (!validate_ip_hdr(nif,ipframe)) - { - nbuf_free(pNbuf); - return; - } - - pNbuf->offset += (IP_IHL(ipframe) * 4); - pNbuf->length = (uint16)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4)); - - /* - * Call the appriopriate handler - */ - switch (IP_PROTOCOL(ipframe)) - { - case IP_PROTO_ICMP: - icmp_handler(nif,pNbuf); - break; - case IP_PROTO_UDP: - udp_handler(nif,pNbuf); - break; - default: - nbuf_free(pNbuf); - break; - } - return; -} -/******************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/ip.h b/flash.tos/drivers/net/ip.h deleted file mode 100644 index 184549f..0000000 --- a/flash.tos/drivers/net/ip.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * File: ip.h - * Purpose: Definitions for the Internet Protocol, IP. - * - * Notes: See RFC 791 "DARPA Internet Program Protocol - * Specification" for more details. - */ - -#ifndef _IP_H -#define _IP_H - -/********************************************************************/ - -/* 32-bit IP Addresses */ -typedef uint8 IP_ADDR[4]; - -/* Pointer to an IP Address */ -typedef uint8 IP_ADDR_P[]; - -/* Definition of an IP packet header */ -typedef struct -{ - uint8 version_ihl; - uint8 service_type; - uint16 total_length; - uint16 identification; - uint16 flags_frag_offset; - uint8 ttl; - uint8 protocol; - uint16 checksum; - IP_ADDR source_addr; - IP_ADDR dest_addr; - uint8 options; /* actually an array of undetermined length */ -} ip_frame_hdr; - -/* Macros for accessing an IP datagram. */ -#define IP_VERSION(a) ((a->version_ihl & 0x00F0) >> 4) -#define IP_IHL(a) ((a->version_ihl & 0x000F)) -#define IP_SERVICE(a) (a->service_type) -#define IP_LENGTH(a) (a->total_length) -#define IP_IDENT(a) (a->identification) -#define IP_FLAGS(a) ((a->flags_frag_offset & 0x0000E000) >> 13) -#define IP_FRAGMENT(a) ((a->flags_frag_offset & 0x00001FFF)) -#define IP_TTL(a) (a->ttl) -#define IP_PROTOCOL(a) (a->protocol) -#define IP_CHKSUM(a) (a->checksum) -#define IP_SRC(a) (&a->source_addr[0]) -#define IP_DEST(a) (&a->dest_addr[0]) -#define IP_OPTIONS(a) (&a->options) -#define IP_DATA(a) (&((uint8 *)a)[IP_IHL(a) * 4]) - -/* Defined IP protocols */ -#define IP_PROTO_ICMP (1) -#define IP_PROTO_UDP (17) - -/* Protocol Header information */ -#define IP_HDR_OFFSET ETH_HDR_LEN -#define IP_HDR_SIZE 20 /* no options */ - -/********************************************************************/ - -typedef struct -{ - IP_ADDR myip; - IP_ADDR gateway; - IP_ADDR netmask; - IP_ADDR broadcast; - unsigned int rx; - unsigned int rx_unsup; - unsigned int tx; - unsigned int err; -} IP_INFO; - -/********************************************************************/ - -void -ip_handler (NIF *, NBUF *); - -uint16 -ip_chksum (uint16 *, int); - -int -ip_send (NIF *, - uint8 *, /* destination IP */ - uint8 *, /* source IP */ - uint8, /* protocol */ - NBUF * /* buffer descriptor */); - -void -ip_init (IP_INFO *, IP_ADDR_P, IP_ADDR_P, IP_ADDR_P); - -uint8 * -ip_get_myip (IP_INFO *); - -uint8 * -ip_resolve_route (NIF *, IP_ADDR_P); - -/********************************************************************/ - -#endif /* _IP_H */ diff --git a/flash.tos/drivers/net/nbuf.c b/flash.tos/drivers/net/nbuf.c deleted file mode 100644 index ec8b376..0000000 --- a/flash.tos/drivers/net/nbuf.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * File: nbuf.c - * Purpose: Implementation of network buffer scheme. - * - * Notes: - */ - -#include -#include "config.h" -#include "queue.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -extern void ltoa(char *buf, long n, unsigned long base); - -/********************************************************************/ -/* - * Queues used for network buffer storage - */ -QUEUE nbuf_queue[NBUF_MAXQ]; - -/* - * Some devices require line-aligned buffers. In order to accomplish - * this, the nbuf data is over-allocated and adjusted. The following - * array keeps track of the original data pointer returned by malloc - */ -ADDRESS unaligned_buffers[NBUF_MAX]; - -/********************************************************************/ -/* - * Initialize all the network buffer queues - * - * Return Value: - * 0 success - * 1 failure - */ -int -nbuf_init(void) -{ - int i; - NBUF *nbuf; - - for (i=0; idata = (uint8 *)((uint32)(unaligned_buffers[i] + 15) & 0xFFFFFFF0); - if (!nbuf->data) - { -// ASSERT(nbuf->data); - return 1; - } - - /* Initialize the network buffer */ - nbuf->offset = 0; - nbuf->length = 0; - - /* Add the network buffer to the free list */ - queue_add(&nbuf_queue[NBUF_FREE], (QNODE *)nbuf); - } - - return 0; -} -/********************************************************************/ -/* - * Return all the allocated memory to the heap - */ -void -nbuf_flush(void) -{ - NBUF *nbuf; - int i, level = asm_set_ipl(7); - int n = 0; - - for (i=0; ioffset = 0; - nbuf->length = NBUF_SZ; - queue_add(&nbuf_queue[NBUF_FREE],(QNODE *)nbuf); - - asm_set_ipl(level); -} -/********************************************************************/ -/* - * Remove a network buffer from the specified queue - * - * Parameters: - * q The index that identifies the queue to pull the buffer from - */ -NBUF * -nbuf_remove(int q) -{ - NBUF *nbuf; - int level = asm_set_ipl(7); - - nbuf = (NBUF *)queue_remove(&nbuf_queue[q]); - asm_set_ipl(level); - return nbuf; -} -/********************************************************************/ -/* - * Add a network buffer to the specified queue - * - * Parameters: - * q The index that identifies the queue to add the buffer to - */ -void -nbuf_add(int q, NBUF *nbuf) -{ - int level = asm_set_ipl(7); - queue_add(&nbuf_queue[q],(QNODE *)nbuf); - asm_set_ipl(level); -} -/********************************************************************/ -/* - * Put all the network buffers back into the free list - */ -void -nbuf_reset(void) -{ - NBUF *nbuf; - int i, level = asm_set_ipl(7); - - for (i=1; idata, 16); - Cconws(buf); - Cconws("\t0x"); - ltoa(buf, nbuf->offset, 16); - Cconws(buf); - Cconws("\t0x"); - ltoa(buf, nbuf->length, 16); - Cconws(buf); - Cconws("\r\n"); - nbuf = (NBUF *)nbuf->node.next; - } - } - - asm_set_ipl(level); -#endif -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/nbuf.h b/flash.tos/drivers/net/nbuf.h deleted file mode 100644 index 6a38ebd..0000000 --- a/flash.tos/drivers/net/nbuf.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * File: nbuf.h - * Purpose: Definitions for network buffer management - * - * Notes: These routines implement a network buffer scheme - */ - -#ifndef _NBUF_H_ -#define _NBUF_H_ - -/********************************************************************/ -/* - * Include the Queue structure definitions - */ -#include "queue.h" - -/* - * Number of network buffers to use - */ -#define NBUF_MAX 30 // 100 - -/* - * Size of each buffer in bytes - */ -#define NBUF_SZ 2048 - -/* - * Defines to identify all the buffer queues - * - FREE must always be defined as 0 - */ -#define NBUF_FREE 0 /* available buffers */ -#define NBUF_TX_RING 1 /* buffers in the Tx BD ring */ -#define NBUF_RX_RING 2 /* buffers in the Rx BD ring */ -#define NBUF_SCRATCH 3 /* misc */ -#define NBUF_MAXQ 4 /* total number of queueus */ - -/* - * Buffer Descriptor Format - * - * Fields: - * next Pointer to next node in the queue - * data Pointer to the data buffer - * offset Index into buffer - * length Remaining bytes in buffer from (data + offset) - */ -typedef struct -{ - QNODE node; - uint8 *data; - uint16 offset; - uint16 length; -} NBUF; - -/* - * Functions to manipulate the network buffers. - */ -int -nbuf_init(void); - -void -nbuf_flush(void); - -NBUF * -nbuf_alloc (void); - -void -nbuf_free(NBUF *); - -NBUF * -nbuf_remove(int); - -void -nbuf_add(int, NBUF *); - -void -nbuf_reset(void); - -void -nbuf_debug_dump(void); - -/********************************************************************/ - -#endif /* _NBUF_H_ */ diff --git a/flash.tos/drivers/net/net.h b/flash.tos/drivers/net/net.h deleted file mode 100644 index 77aa398..0000000 --- a/flash.tos/drivers/net/net.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * File: net.h - * Purpose: Network definitions and prototypes for dBUG. - * - * Notes: - */ - -#ifndef _NET_H -#define _NET_H - -#define int8 char -#define int16 short -#define int32 long -#define uint8 unsigned char -#define uint16 unsigned short -#define uint32 unsigned long -#define vuint8 volatile unsigned char -#define vuint16 volatile unsigned short -#define vuint32 volatile unsigned long -#define NULL (void *)0 -#define FALSE 0 -#define TRUE 1 - -#define TIMER_NETWORK 0 - -/* - * Ethernet Info - */ -#define FEC_PHY0 (0x00) -#define FEC_PHY1 (0x01) -#define FEC_PHY(x) ((x == 0) ? FEC_PHY0 : FEC_PHY1) -#ifdef MCF5445X -#define phy_init dp83849_init -#else /* MCF547X - MCF548X */ -#ifdef MCF547X -#define phy_init am79c874_init -#else /* MCF548X */ -#define phy_init bcm5222_init -#endif /* MCF547X */ -#endif /* MCF5445X */ - -/* - * Interrupt Priorities - */ -#define DMA_INTC_LVL 5 -#define DMA_INTC_PRI 3 -#define FEC_INTC_LVL 5 -#define FEC_INTC_PRI 0 - -/* - * DMA Task Priorities - */ -#define FECRX_DMA_PRI 3 -#define FECTX_DMA_PRI 4 - -/* - * System Bus Clock Info - */ -#ifdef MCF5445X -#define SYSTEM_CLOCK 132 // system bus frequency in MHz -#else /* MCF547X - MCF548X */ -#ifdef MCF547X -#define SYSTEM_CLOCK 132 // system bus frequency in MHz -#else /* MCF548X */ -#define SYSTEM_CLOCK 100 // system bus frequency in MHz -#endif /* MCF547X */ -#endif /* MCF5445X */ - -extern unsigned char __MBAR[]; -extern unsigned char __MCDAPI_START[]; - -extern long length(const char *text); -extern void copy(const char *src, char *dest); - -#define strcpy(dest,src) copy((const char *)src,(char *)dest) -#define strlen(a) length((const char *)a) -extern int asm_set_ipl(int level); - -/********************************************************************/ - -/* - * Include information and prototypes for all protocols - */ -#include "eth.h" -#include "nbuf.h" -#include "nif.h" -#include "ip.h" -#include "icmp.h" -#include "arp.h" -#include "udp.h" -#include "tftp.h" - -#endif /* _NET_H */ - diff --git a/flash.tos/drivers/net/net_timer.c b/flash.tos/drivers/net/net_timer.c deleted file mode 100644 index 7900ad5..0000000 --- a/flash.tos/drivers/net/net_timer.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * File: net_timer.c - * Purpose: Provide a timer use by the dBUG network as a timeout - * indicator - * - * Notes: - */ -#include -#include "config.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -static uint32 start_timer[4]; -static uint32 timeout[4]; - -uint32 read_hz_200(void) -{ - return(*(uint32 *)0x4BA); /* _hz_200 */ -} - -uint32 timer_set_secs(uint8 ch, uint32 secs) -{ - ch &=3; - timeout[ch] = secs * 200; - start_timer[ch] = read_hz_200(); // Supexec(read_hz_200); - return TRUE; -} - -uint32 timer_get_reference(uint8 ch) -{ - uint32 val_timer; - ch &= 3; - val_timer = read_hz_200(); // Supexec(read_hz_200); - if(val_timer >= (start_timer[ch]+timeout[ch])) - return FALSE; /* the desired seconds have expired */ - return TRUE; -} - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/net_timer.h b/flash.tos/drivers/net/net_timer.h deleted file mode 100644 index 97adbf8..0000000 --- a/flash.tos/drivers/net/net_timer.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * File: net_timer.h - * Purpose: Provide a timer use by the dBUG network as a timeout - * indicator - * - * Notes: - */ - -#ifndef _TIMER_H_ -#define _TIMER_H_ - -#if 0 -#define ISR_DBUG_ISR (0x01) - -/********************************************************************/ - -typedef struct -{ - uint8 ch; /* which channel is this structure for? */ - uint8 lvl; /* Interrupt level for this channel */ - uint8 pri; /* Interrupt priority for this channel */ - uint8 reference; /* timeout indicator */ - uint32 gms; /* mode select register value */ - uint16 pre; /* prescale value */ - uint16 cnt; /* prescaled clocks for timeout */ -} NET_TIMER; - -/********************************************************************/ - -uint32 timer_init(uint8, uint8, uint8); - -#endif - - -uint32 timer_set_secs(uint8 ch, uint32 secs); -uint32 timer_get_reference(uint8 ch); - -#if 0 -uint32 timer_init(uint8 ch, uint8 lvl, uint8 pri); - -/********************************************************************/ - -/* Vector numbers for all the timer channels */ -#define TIMER_VECTOR(x) (126-x) - -/********************************************************************/ - -#endif - -#endif diff --git a/flash.tos/drivers/net/nif.c b/flash.tos/drivers/net/nif.c deleted file mode 100644 index 313ef85..0000000 --- a/flash.tos/drivers/net/nif.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * File: nif.c - * Purpose: Network InterFace routines - * - * Notes: - * - * Modifications: - * - */ - -#include "config.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -/********************************************************************/ - -/* - * Declare two network interfaces - */ -NIF nif[2]; - -/********************************************************************/ -int -nif_protocol_exist (NIF *nif, uint16 protocol) -{ - /* - * This function searches the list of supported protocols - * on the particular NIF and if a protocol handler exists, - * TRUE is returned. This function is useful for network cards - * that needn't read in the entire frame but can discard frames - * arbitrarily. - */ - int index; - - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - { - return TRUE; - } - } - return FALSE; -} - -/********************************************************************/ -void -nif_protocol_handler (NIF *nif, uint16 protocol, NBUF *pNbuf) -{ - /* - * This function searches the list of supported protocols - * on the particular NIF and if a protocol handler exists, - * the protocol handler is invoked. This routine called by - * network device driver after receiving a frame. - */ - int index; - - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - nif->protocol[index].handler(nif,pNbuf); - } -} - -/********************************************************************/ -void * -nif_get_protocol_info (NIF *nif, uint16 protocol) -{ - /* - * This function searches the list of supported protocols - * on the particular NIF and returns a pointer to the - * config info for 'protocol', otherwise NULL is returned. - */ - int index; - - for (index = 0; index < nif->num_protocol; ++index) - { - if (nif->protocol[index].protocol == protocol) - return (void *)nif->protocol[index].info; - } - return (void *)0; -} - -/********************************************************************/ -int -nif_bind_protocol (NIF *nif, uint16 protocol, - void (*handler)(NIF *,NBUF *), - void *info) -{ - /* - * This function registers 'protocol' as a supported - * protocol in 'nif'. - */ - if (nif->num_protocol < (MAX_SUP_PROTO - 1)) - { - nif->protocol[nif->num_protocol].protocol = protocol; - nif->protocol[nif->num_protocol].handler = (void(*)(NIF*,NBUF*))handler; - nif->protocol[nif->num_protocol].info = info; - ++nif->num_protocol; - return TRUE; - } - return FALSE; -} - -/********************************************************************/ -NIF * -nif_init (NIF *nif) -{ - int i; - - for (i = 0; i < ETH_ADDR_LEN; ++i) - { - nif->hwa[i] = 0; - nif->broadcast[i] = 0xFF; - } - - for (i = 0; i < MAX_SUP_PROTO; ++i) - { - nif->protocol[i].protocol = 0; - nif->protocol[i].handler = 0; - nif->protocol[i].info = 0; - } - nif->num_protocol = 0; - - nif->mtu = 0; - - return nif; -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/nif.h b/flash.tos/drivers/net/nif.h deleted file mode 100644 index 23c17b9..0000000 --- a/flash.tos/drivers/net/nif.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * File: nif.h - * Purpose: Definition of a Network InterFace. - * - * Notes: - * - */ - -#ifndef _NIF_H -#define _NIF_H - -/********************************************************************/ - -/* - * Maximum number of supported protoocls: IP, ARP, RARP - */ -#define MAX_SUP_PROTO (3) - -typedef struct NIF_t -{ - ETH_ADDR hwa; /* ethernet card hardware address */ - ETH_ADDR broadcast; /* broadcast address */ - int mtu; /* hardware maximum transmission unit */ - - struct SUP_PROTO_t - { - uint16 protocol; - void (*handler)(struct NIF_t *, NBUF *); - void *info; - } protocol[MAX_SUP_PROTO]; - - int (*send)(uint8 *, uint8 *, uint16, NBUF *); - - unsigned short num_protocol; - -} NIF; - -/* - * Give everyone access to the two NIFs - */ -extern NIF nif[]; - -/********************************************************************/ - -NIF * -nif_init (NIF *); - -int -nif_protocol_exist (NIF *, uint16); - -void -nif_protocol_handler (NIF *, uint16, NBUF *); - -void * -nif_get_protocol_info (NIF *, uint16); - -int -nif_bind_protocol (NIF *, uint16, void (*)(NIF *, NBUF *), void *); - -/********************************************************************/ - -#endif /* _NIF_H */ diff --git a/flash.tos/drivers/net/queue.c b/flash.tos/drivers/net/queue.c deleted file mode 100644 index 9829d14..0000000 --- a/flash.tos/drivers/net/queue.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * File: queue.c - * Purpose: Implement a first in, first out linked list - * - * Notes: - */ - -#include "config.h" -#include "queue.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -/********************************************************************/ -/* - * Initialize the specified queue to an empty state - * - * Parameters: - * q Pointer to queue structure - */ -void -queue_init(QUEUE *q) -{ - q->head = NULL; -} -/********************************************************************/ -/* - * Check for an empty queue - * - * Parameters: - * q Pointer to queue structure - * - * Return Value: - * 1 if Queue is empty - * 0 otherwise - */ -int -queue_isempty(QUEUE *q) -{ - return (q->head == NULL); -} -/********************************************************************/ -/* - * Add an item to the end of the queue - * - * Parameters: - * q Pointer to queue structure - * node New node to add to the queue - */ -void -queue_add(QUEUE *q, QNODE *node) -{ - if (queue_isempty(q)) - { - q->head = q->tail = node; - } - else - { - q->tail->next = node; - q->tail = node; - } - - node->next = NULL; -} - -/********************************************************************/ -/* - * Remove and return first (oldest) entry from the specified queue - * - * Parameters: - * q Pointer to queue structure - * - * Return Value: - * Node at head of queue - NULL if queue is empty - */ -QNODE* -queue_remove(QUEUE *q) -{ - QNODE *oldest; - - if (queue_isempty(q)) - return NULL; - - oldest = q->head; - q->head = oldest->next; - return oldest; -} -/********************************************************************/ -/* - * Peek into the queue and return pointer to first (oldest) entry. - * The queue is not modified - * - * Parameters: - * q Pointer to queue structure - * - * Return Value: - * Node at head of queue - NULL if queue is empty - */ -QNODE* -queue_peek(QUEUE *q) -{ - return q->head; -} -/********************************************************************/ -/* - * Move entire contents of one queue to the other - * - * Parameters: - * src Pointer to source queue - * dst Pointer to destination queue - */ -void -queue_move(QUEUE *dst, QUEUE *src) -{ - if (queue_isempty(src)) - return; - - if (queue_isempty(dst)) - dst->head = src->head; - else - dst->tail->next = src->head; - - dst->tail = src->tail; - src->head = NULL; - return; -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/queue.h b/flash.tos/drivers/net/queue.h deleted file mode 100644 index e7a08b4..0000000 --- a/flash.tos/drivers/net/queue.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * File: queue.h - * Purpose: Implement a first in, first out linked list - * - * Notes: - */ - -#ifndef _QUEUE_H_ -#define _QUEUE_H_ - -/********************************************************************/ - -/* - * Individual queue node - */ -typedef struct NODE -{ - struct NODE *next; -} QNODE; - -/* - * Queue Struture - linked list of qentry items - */ -typedef struct -{ - QNODE *head; - QNODE *tail; -} QUEUE; - -/* - * Functions provided by queue.c - */ -void -queue_init(QUEUE *); - -int -queue_isempty(QUEUE *); - -void -queue_add(QUEUE *, QNODE *); - -QNODE* -queue_remove(QUEUE *); - -QNODE* -queue_peek(QUEUE *); - -void -queue_move(QUEUE *, QUEUE *); - -/********************************************************************/ - -#endif /* _QUEUE_H_ */ diff --git a/flash.tos/drivers/net/tftp.c b/flash.tos/drivers/net/tftp.c deleted file mode 100644 index d459bdc..0000000 --- a/flash.tos/drivers/net/tftp.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * File: tftp.c - * Purpose: Trivial File Transfer Protocol driver for reading a file - * from a remote host. - * - * Notes: See RFC 1350 - * - * Modifications: - * - */ -#include -#include "config.h" -#include "net.h" -#include "net_timer.h" - -#ifdef NETWORK -#ifndef LWIP - -extern void ltoa(char *buf, long n, unsigned long base); -extern void cat(const char *src, char *dest); - -static char tftp_string_error[1024]; - -/********************************************************************/ - -/* The one and only TFTP connection */ -TFTP_Connection tcxn; - -/* Progress Indicators */ -//char hash[] = {'-','\\','|','/'}; -//int ihash = 0; - -/********************************************************************/ -static int -tftp_rwrq (void) -{ - NBUF *pNbuf; - RWRQ *rwrq; - int i, j, result; - - pNbuf = nbuf_alloc(); - if (pNbuf == NULL) - { - #if defined(DEBUG_PRINT) - Cconws("TFTP: tftp_rwrq() couldn't allocate Tx buffer\r\n"); - #endif - return 0; - } - - rwrq = (RWRQ *)&pNbuf->data[TFTP_HDR_OFFSET]; - - /* Indicate a R/WRQ */ - rwrq->opcode = tcxn.dir; - - /* Copy in filename */ - strcpy(&rwrq->filename_mode[0], tcxn.file); - i = strlen(tcxn.file) + 1; - - /* Indicate transfer type */ - strcpy (&rwrq->filename_mode[i], OCTET); - - for (j=0; j<3; ++j) - { - pNbuf->length = (uint16)(i + strlen(OCTET) + 1 + 2); - result = udp_send(tcxn.nif, - tcxn.server_ip, - tcxn.my_port, - tcxn.server_port, - pNbuf); - if (result == 1) - break; - } - - if (result == 0) - nbuf_free(pNbuf); - - return result; -} -/********************************************************************/ -static int -tftp_ack (uint16 blocknum) -{ - ACK *ack; - NBUF *pNbuf; - int i, result; - - pNbuf = nbuf_alloc(); - if (pNbuf == NULL) - { - #if defined(DEBUG_PRINT) - Cconws("TFTP: tftp_ack() couldn't allocate Tx buffer\r\n"); - #endif - return 0; - } - - ack = (ACK *)&pNbuf->data[TFTP_HDR_OFFSET]; - ack->opcode = TFTP_ACK; - ack->blocknum = blocknum; - - for (i=0; i<3; ++i) - { - pNbuf->length = 4; - result = udp_send(tcxn.nif, - tcxn.server_ip, - tcxn.my_port, - tcxn.server_port, - pNbuf); - if (result == 1) - break; - } - - if (result == 0) - nbuf_free(pNbuf); - - return result; -} -/********************************************************************/ -static int -tftp_error (uint16 error_code, uint16 server_port) -{ - ERROR *err; - NBUF *pNbuf; - int i, result; - - pNbuf = nbuf_alloc(); - if (pNbuf == NULL) - { - #if defined(DEBUG_PRINT) - Cconws("TFTP: tftp_error() couldn't allocate Tx buffer\r\n"); - #endif - return 0; - } - - err = (ERROR *)&pNbuf->data[TFTP_HDR_OFFSET]; - err->opcode = TFTP_ERROR; - err->code = error_code; - err->msg[0] = '\0'; - - for (i=0; i<3; ++i) - { - pNbuf->length = 5; - result = udp_send(tcxn.nif, - tcxn.server_ip, - tcxn.my_port, - server_port, - pNbuf); - if (result == 1) - break; - } - - if (result == 0) - nbuf_free(pNbuf); - - return result; -} -/********************************************************************/ -void -tftp_handler (NIF *nif, NBUF *pNbuf) -{ - union TFTPpacket *tftp_pkt; - udp_frame_hdr *udpframe; - static int cnt; - (void) nif; - - tftp_pkt = (union TFTPpacket *)&pNbuf->data[pNbuf->offset]; - udpframe = (udp_frame_hdr *)&pNbuf->data[pNbuf->offset - UDP_HDR_SIZE]; - - switch (tftp_pkt->generic.opcode) - { - case TFTP_DATA: - /* Is this the expected block number? */ - if (tftp_pkt->data.blocknum == tcxn.exp_blocknum) - { - /* Is this is the first data block received? */ - if (tftp_pkt->data.blocknum == 1) - { - /* Save the server's transfer ID */ - tcxn.server_port = UDP_SOURCE(udpframe); - - /* Mark the connection as open */ - tcxn.open = TRUE; - - /* Start progress indicator */ -// board_putchar(hash[0]); - cnt = 0; - } - else - { - /* Check the server's transfer ID */ - if (tcxn.server_port != UDP_SOURCE(udpframe)) - { - #if defined(DEBUG_PRINT) - char buf[10]; - Cconws("TFTP: Invalid server port: "); - ltoa(buf, UDP_SOURCE(udpframe), 10); - Cconws(buf); - Cconws("\r\n"); - #endif - - /* Send ERROR packet to source */ - tftp_error(TFTP_ERR_TID, UDP_SOURCE(udpframe)); - break; - } - } - - /* Add the buffer to the TFTP queue */ - queue_add(&tcxn.queue, (QNODE *)pNbuf); - - /* Update number of the next block expected */ - tcxn.exp_blocknum++; - - /* Increment number of bytes received counter */ - tcxn.bytes_recv += (pNbuf->length - 4); - - /* Update progress indicator */ - if (++cnt == 50) - { -// ihash = (ihash + 1) % 4; -// board_putchar(CTRL_BS); -// board_putchar(hash[ihash]); - cnt = 0; - } - } - else - { - if (tftp_pkt->data.blocknum < tcxn.exp_blocknum) - { - /* Re-ACK this packet */ - tftp_ack(tftp_pkt->data.blocknum); - } - - #if defined(DEBUG_PRINT) - { - /* This is NOT the block expected */ - char buf[10]; - Cconws("Exp: "); - ltoa(buf, tcxn.exp_blocknum, 10); - Cconws(buf); - Cconws(", Rcv: "); - ltoa(buf, tftp_pkt->data.blocknum, 10); - Cconws(buf); - Cconws("\r\n"); - } - #endif - - /* Free the network buffer */ - nbuf_free(pNbuf); - } - break; - case TFTP_ERROR: - { - char buf[10]; - cat("TFTP Error #", tftp_string_error); - ltoa(buf, tftp_pkt->error.code, 10); - cat(buf, tftp_string_error); - cat(": ", tftp_string_error); - cat(tftp_pkt->error.msg, tftp_string_error); - } - tcxn.error = TRUE; - /* Free the network buffer */ - nbuf_free(pNbuf); - break; - case TFTP_ACK: - if (tftp_pkt->ack.blocknum == tcxn.exp_blocknum) - { - if (tftp_pkt->data.blocknum == 0) - { /* This is the first ACK received */ - - /* Save the server's transfer ID */ - tcxn.server_port = UDP_SOURCE(udpframe); - - /* Mark the connection as open */ - tcxn.open = TRUE; - } - else - { /* Check the server's transfer ID */ - if (tcxn.server_port != UDP_SOURCE(udpframe)) - { - #if defined(DEBUG_PRINT) - char buf[10]; - Cconws("TFTP: Invalid server port: "); - ltoa(buf, UDP_SOURCE(udpframe), 10); - Cconws(buf); - Cconws("\r\n"); - #endif - - /*Send ERROR packet to source */ - tftp_error(TFTP_ERR_TID, UDP_SOURCE(udpframe)); - break; - } - } - - tcxn.exp_blocknum++; - } - else - { - #if defined(DEBUG_PRINT) - /* This is NOT the block number expected */ - char buf[10]; - Cconws("ACK Exp: "); - ltoa(buf, tcxn.exp_blocknum, 10); - Cconws(buf); - Cconws(", ACK Rcv: "); - ltoa(buf, tftp_pkt->data.blocknum, 10); - Cconws(buf); - Cconws("\r\n"); - #endif - } - - /* Free the network buffer */ - nbuf_free(pNbuf); - break; - case TFTP_RRQ: - case TFTP_WRQ: - default: - /* Free the network buffer */ - nbuf_free(pNbuf); - break; - } -} - -/********************************************************************/ -void -tftp_end (int success) -{ - /* - * Following a successful transfer the caller should pass in - * TRUE, there should have been no ERROR packets received, and - * the connection should have been marked as closed by the - * tftp_in_char() routine. - */ - if (success && !tcxn.error && (tcxn.open == FALSE)) - { -// char buf[10]; -// Cconws("\bTFTP transfer completed.\r\n"); -// Cconws("Read "); -// ltoa(buf, tcxn.bytes_recv, 10); -// Cconws(buf); -// Cconws(" bytes ("); -// ltoa(buf, tcxn.exp_blocknum - 1, 10); -// Cconws(buf); -// Cconws(" blocks)\r\n"); - } - else - { -// char buf[10]; - /* Send error packet to stifle the server */ - tftp_error(TFTP_ERR_ILL, tcxn.server_port); - if(*tftp_string_error == 0) - cat(" Errors in TFTP transfer.", tftp_string_error); -// Cconws("Read "); -// ltoa(buf, tcxn.bytes_recv, 10); -// Cconws(buf); -// Cconws(" bytes ("); -// ltoa(buf, tcxn.exp_blocknum - 1, 10); -// Cconws(buf); -// Cconws(" blocks)\r\n"); - } - - /* Free up any buffers left in the queue */ - while (!queue_isempty(&tcxn.queue)) - nbuf_free((NBUF *)queue_remove(&tcxn.queue)); - - /* Free the UDP port */ - udp_free_port(tcxn.my_port); -} - -/********************************************************************/ -int -tftp_write (NIF *nif, char *fn, IP_ADDR_P server, uint32 begin, uint32 end) -{ - DATA *data; - NBUF *pNbuf; - - uint32 i, retries, bytes_to_send; - uint16 blocknum, this_size; - uint8 success, *current; - int result = 0; - *tftp_string_error = 0; - - if (fn == 0 || server == 0 || end < begin) - return 0; - - /* Setup initial connection status */ - tcxn.nif = nif; - tcxn.file = fn; - tcxn.server_ip[0] = server[0]; - tcxn.server_ip[1] = server[1]; - tcxn.server_ip[2] = server[2]; - tcxn.server_ip[3] = server[3]; - tcxn.server_port = UDP_PORT_TFTP; - tcxn.exp_blocknum = 0; - tcxn.dir = TFTP_WRQ; - tcxn.open = FALSE; - tcxn.bytes_sent = 0; - tcxn.error = FALSE; - - /* Use Mac address as pseudo-random port */ - udp_prime_port((uint16)((nif->hwa[4] << 8) | nif->hwa[5])); - tcxn.my_port = udp_obtain_free_port(); - udp_bind_port(tcxn.my_port,&tftp_handler); - - retries = 4; - success = FALSE; - - while (--retries) - { - /* Make the TFTP Read/Write Request */ - if (!tftp_rwrq()) - { - cat("Error: Couldn't send TFTP Write Request", tftp_string_error); - udp_free_port(tcxn.my_port); - return FALSE; - } - - timer_set_secs(TIMER_NETWORK, TFTP_TIMEOUT); - while (timer_get_reference(TIMER_NETWORK)) - { - /* Has the server responded */ - if (tcxn.open) - { - success = TRUE; - break; - } - } - - /* If the connection is open, we are done here */ - if (success || tcxn.error) - break; - } - if (!retries) - { - if(*tftp_string_error == 0) - cat("TFTP could not make connection to server.", tftp_string_error); - udp_free_port(tcxn.my_port); - return FALSE; - } - else if (tcxn.error) - { - if(*tftp_string_error == 0) - cat(" Errors in TFTP upload.", tftp_string_error); - udp_free_port(tcxn.my_port); - return FALSE; - } - - bytes_to_send = end - begin; - current = (uint8 *)begin; - blocknum = 1; - retries = 4; - success = FALSE; - - while (--retries) - { - pNbuf = nbuf_alloc(); - if (pNbuf == NULL) - { - #if defined(DEBUG_PRINT) - Cconws("TFTP: tftp_write() couldn't allocate Tx buffer\r\n"); - #endif - return FALSE; - } - - /* Build the packet */ - data = (DATA *)&pNbuf->data[TFTP_HDR_OFFSET]; - data->blocknum = blocknum; - data->opcode = TFTP_DATA; - - this_size = (bytes_to_send > TFTP_PKTSIZE) ? \ - TFTP_PKTSIZE : (uint16)bytes_to_send; - - for (i = 0; i < this_size; i++) - { - data->data[i] = current[i]; - } - - /* Set the packet length */ - pNbuf->length = (uint16)(4 + this_size); - - /* Attempt to send the packet */ - for (i=0; i<3; ++i) - { - result = udp_send(tcxn.nif, - tcxn.server_ip, - tcxn.my_port, - tcxn.server_port, - pNbuf); - - if (result == 1) - break; - } - - if (result == 0) - nbuf_free(pNbuf); - - timer_set_secs(TIMER_NETWORK, TFTP_TIMEOUT); - while (timer_get_reference(TIMER_NETWORK)) - { - /* Has the server responded */ - if ((tcxn.exp_blocknum - 1) == blocknum) - { - success = TRUE; - break; - } - } - - /* TFTP Write Compeleted successfully */ - if (success && (this_size < TFTP_PKTSIZE)) - { - tcxn.bytes_sent += this_size; - break; - } - - if (tcxn.error) - break; - - /* If an ACK was received, keep sending packets */ - if (success) - { - tcxn.bytes_sent += TFTP_PKTSIZE; - bytes_to_send -= TFTP_PKTSIZE; - current += TFTP_PKTSIZE; - blocknum++; - retries = 4; - success = FALSE; - } - } - if (tcxn.error) - { -// char buf[10]; -// Cconws("TFTP lost connection to server.\r\n"); -// Cconws("Sent "); -// ltoa(buf, tcxn.bytes_sent, 10); -// Cconws(buf); -// Cconws(" bytes ("); -// ltoa(buf, tcxn.exp_blocknum - 1, 10); -// Cconws(buf); -// Cconws(" blocks)\r\n"); - udp_free_port(tcxn.my_port); - return FALSE; - } - else - { -// char buf[10]; -// Cconws("\bTFTP upload successful.\r\n"); -// Cconws("Sent "); -// ltoa(buf, tcxn.bytes_sent, 10); -// Cconws(buf); -// Cconws(" bytes ("); -// ltoa(buf, tcxn.exp_blocknum - 1, 10); -// Cconws(buf); -// Cconws(" blocks)\r\n"); - udp_free_port(tcxn.my_port); - return TRUE; - } -} - -/********************************************************************/ -int -tftp_read (NIF *nif, char *fn, IP_ADDR_P server) -{ - uint32 retries; - - *tftp_string_error = 0; - if (fn == 0 || server == 0) - return 0; - - /* Setup initial connection status */ - tcxn.nif = nif; - tcxn.file = fn; - tcxn.server_ip[0] = server[0]; - tcxn.server_ip[1] = server[1]; - tcxn.server_ip[2] = server[2]; - tcxn.server_ip[3] = server[3]; - tcxn.server_port = UDP_PORT_TFTP; - tcxn.exp_blocknum = 1; - tcxn.last_ack = 0; - tcxn.dir = TFTP_RRQ; - tcxn.open = FALSE; - tcxn.bytes_recv = 0; - tcxn.rem_bytes = 0; - tcxn.next_char = NULL; - tcxn.error = FALSE; - queue_init(&tcxn.queue); - - /* Use Mac address as pseudo-random port */ - udp_prime_port((uint16)((nif->hwa[4] << 8) | nif->hwa[5])); - tcxn.my_port = udp_obtain_free_port(); - udp_bind_port(tcxn.my_port,&tftp_handler); - - retries = 4; - - while (--retries) - { - /* Make the TFTP Read/Write Request */ - if (!tftp_rwrq()) - { - cat("Error: Couldn't send TFTP Read Request", tftp_string_error); - udp_free_port(tcxn.my_port); - return FALSE; - } - - timer_set_secs(TIMER_NETWORK, TFTP_TIMEOUT); - while (timer_get_reference(TIMER_NETWORK)) - { - /* Has the server responded */ - if (tcxn.open == TRUE) - break; - } - - /* If the connection is open, we are done here */ - if ((tcxn.open == TRUE) || tcxn.error) - break; - } - - -// if(tcxn.open) -// Cconws("TFTP server responded\r\n"); -// if(!tcxn.open) -// Cconws("TFTP server not responded\r\n"); - - - if (!retries) - { - if(*tftp_string_error == 0) - cat("TFTP could not make connection to server.", tftp_string_error); - udp_free_port(tcxn.my_port); - return FALSE; - } - else if (tcxn.error) - { - if(*tftp_string_error == 0) - cat(" Errors in TFTP download.", tftp_string_error); - udp_free_port(tcxn.my_port); - return FALSE; - } - else - return TRUE; -} - -/********************************************************************/ -int -tftp_in_char (void) -{ - union TFTPpacket *tftp_pkt; - int retval; - NBUF *pNbuf; - - if (tcxn.next_char != NULL) - { - /* - * A buffer is already being worked on - grab next - * byte from it - */ - retval = *tcxn.next_char++; - - if (--tcxn.rem_bytes <= 0) - { - /* The buffer is depleted; add it back to the free queue */ - pNbuf = (NBUF *)queue_remove(&tcxn.queue); -// ASSERT(pNbuf); - nbuf_free(pNbuf); - tcxn.next_char = NULL; - } - } - else - { - /* Is the connection still open? */ - if (tcxn.open == FALSE) - { - /* - * The last packet has been received and the last data - * buffer has been exhausted - */ - retval = -1; - } - else - { - /* Get pointer to the next buffer */ - pNbuf = (NBUF *)queue_peek(&tcxn.queue); - - if (pNbuf == NULL) - { - int i; - - /* There was no buffer in the queue */ - for (i = 0; i < 3; ++i) - { - timer_set_secs(TIMER_NETWORK, 1); - while (timer_get_reference(TIMER_NETWORK)) - { - /* Has the server sent another DATA packet? */ - if (!queue_isempty(&tcxn.queue)) - { - pNbuf = (NBUF *)queue_peek(&tcxn.queue); - break; - } - } - if (pNbuf != NULL) - break; - - /* Ack the last packet again */ - #ifdef DEBUG_PRINT - { - char buf[10]; - Cconws("Re-acking "); - ltoa(buf, tcxn.last_ack - 1, 10); - Cconws(buf); - Cconws("\r\n"); - } - #endif - retval = tftp_ack(tcxn.last_ack - 1); -// ASSERT(retval); - } - } - if (pNbuf == NULL) - { - /* The server didn't respond with the expected packet */ - tcxn.open = FALSE; - tcxn.error = TRUE; - cat("TFTP lost connection to server.", tftp_string_error); - retval = -1; - } - else - { - tftp_pkt = (union TFTPpacket *)&pNbuf->data[pNbuf->offset]; - - /* Subtract the TFTP header from the data length */ - tcxn.rem_bytes = pNbuf->length - 4; - - /* Point to first data byte in the packet */ - tcxn.next_char = tftp_pkt->data.data; - - /* Save off the block number */ - tcxn.last_ack = tftp_pkt->data.blocknum; - - /* Check to see if this is the last packet of the transfer */ - if (tcxn.rem_bytes < TFTP_PKTSIZE) - tcxn.open = FALSE; - - /* Check for empty termination packet */ - if (tcxn.rem_bytes == 0) - { - pNbuf = (NBUF *)queue_remove(&tcxn.queue); -// ASSERT(pNbuf); - nbuf_free(pNbuf); - tcxn.next_char = NULL; - retval = tftp_ack(tcxn.last_ack++); -// ASSERT(retval); - retval = -1; - } - else - { - retval = tftp_ack(tcxn.last_ack++); -// ASSERT(retval); - retval = *tcxn.next_char++; - - /* Check for a single byte packet */ - if (--tcxn.rem_bytes == 0) - { - /* The buffer is depleted; add it back to the free queue */ - pNbuf = (NBUF *)queue_remove(&tcxn.queue); -// ASSERT(pNbuf); - nbuf_free(pNbuf); - tcxn.next_char = NULL; - } - } - } - } - } - return retval; -} -/********************************************************************/ - -char *tftp_get_error(void) -{ - return(tftp_string_error); -} - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/tftp.h b/flash.tos/drivers/net/tftp.h deleted file mode 100644 index 4dafaa5..0000000 --- a/flash.tos/drivers/net/tftp.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * File: tftp.h - * Purpose: Data definitions for TFTP - * - * Notes: - */ - -#ifndef _TFTP_H -#define _TFTP_H - -/********************************************************************/ - -#define TFTP_RRQ (1) -#define TFTP_WRQ (2) -#define TFTP_DATA (3) -#define TFTP_ACK (4) -#define TFTP_ERROR (5) - -#define TFTP_ERR_FNF 1 -#define TFTP_ERR_AV 2 -#define TFTP_ERR_DF 3 -#define TFTP_ERR_ILL 4 -#define TFTP_ERR_TID 5 -#define TFTP_FE 6 -#define TFTP_NSU 7 -#define TFTP_ERR_UD 0 - -#define OCTET "octet" -#define NETASCII "netascii" - -/* Protocol Header information */ -#define TFTP_HDR_OFFSET (ETH_HDR_LEN + IP_HDR_SIZE + UDP_HDR_SIZE) - -/* Timeout in seconds */ -#define TFTP_TIMEOUT 2 - -/* Maximum TFTP Packet Size (payload only - no header) */ -#define TFTP_PKTSIZE 512 - -/* Number of TFTP Data Buffers */ -#define NUM_TFTPBD 6 - -/********************************************************************/ - -/* Data Buffer Pointer Structure */ -typedef struct -{ - uint8 data[TFTP_PKTSIZE]; - uint16 bytes; -} DATA_BUF; - -/* TFTP RRQ/WRQ Packet */ -typedef struct -{ - uint16 opcode; - char filename_mode[TFTP_PKTSIZE - 2]; -} RWRQ; - -/* TFTP DATA Packet */ -typedef struct -{ - uint16 opcode; - uint16 blocknum; - uint8 data[TFTP_PKTSIZE - 4]; -} DATA; - -/* TFTP Acknowledge Packet */ -typedef struct -{ - uint16 opcode; - uint16 blocknum; -} ACK; - -/* TFTP Error Packet */ -typedef struct -{ - uint16 opcode; - uint16 code; - char msg[TFTP_PKTSIZE - 4]; -} ERROR; - -/* TFTP Generic Packet */ -typedef struct -{ - uint16 opcode; -} GEN; - -union TFTPpacket -{ - RWRQ rwrq; - DATA data; - ACK ack; - ERROR error; - GEN generic; -}; - -/* TFTP Connection Status */ -typedef struct -{ - /* Pointer to next character in buffer ring */ - uint8 *next_char; - - /* Direction of current connection, read or write */ - uint8 dir; - - /* Connection established flag */ - uint8 open; - - /* Pointer to our Network InterFace */ - NIF *nif; - - /* File being transferred */ - char *file; - - /* Server IP address */ - IP_ADDR server_ip; - - /* Queue to hold the TFTP packets */ - QUEUE queue; - - /* Bytes received counter */ - uint32 bytes_recv; - - /* Bytes sent counter */ - uint32 bytes_sent; - - /* Bytes remaining in current Rx buffer */ - uint32 rem_bytes; - - /* Server UDP port */ - uint16 server_port; - - /* My UDP port */ - uint16 my_port; - - /* Expected TFTP block number */ - uint16 exp_blocknum; - - /* Keep track of the last packet acknowledged */ - uint16 last_ack; - - /* Error Flag */ - uint8 error; - -} TFTP_Connection; - - -/********************************************************************/ - -void tftp_handler(NIF *, NBUF *) ; -int tftp_write (NIF *, char *, IP_ADDR_P, uint32, uint32); -int tftp_read(NIF *, char *, IP_ADDR_P); -void tftp_end(int); -int tftp_in_char(void); -char *tftp_get_error(void); - -/********************************************************************/ - -#endif /* _TFTP_H */ diff --git a/flash.tos/drivers/net/udp.c b/flash.tos/drivers/net/udp.c deleted file mode 100644 index dcfc6f8..0000000 --- a/flash.tos/drivers/net/udp.c +++ /dev/null @@ -1,184 +0,0 @@ -/* - * File: udp.c - * Purpose: User Datagram Protocol driver - * - * Notes: - * - * Modifications: - * - */ -#include -#include "config.h" -#include "net.h" - -#ifdef NETWORK -#ifndef LWIP - -/********************************************************************/ -typedef struct -{ - uint16 port; - void (*handler)(NIF *, NBUF *); - -} UDP_BOUND_PORT; - -/********************************************************************/ - -#define UDP_MAX_PORTS (5) /* plenty for this implementation */ - - -static UDP_BOUND_PORT -udp_port_table[UDP_MAX_PORTS]; - -static uint16 -udp_port; - -/********************************************************************/ -void -udp_init (void) -{ - int index; - - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - udp_port_table[index].port = 0; - } - - udp_port = DEFAULT_UDP_PORT; /* next free port */ -} -/********************************************************************/ -void -udp_prime_port (uint16 init_port) -{ - udp_port = init_port; -} -/********************************************************************/ -void -udp_bind_port (uint16 port, void (*handler)(NIF *, NBUF *)) -{ - int index; - - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - if (udp_port_table[index].port == 0) - { - udp_port_table[index].port = port; - udp_port_table[index].handler = handler; - return; - } - } -} -/********************************************************************/ -void -udp_free_port (uint16 port) -{ - int index; - - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - if (udp_port_table[index].port == port) - { - udp_port_table[index].port = 0; - return; - } - } -} -/********************************************************************/ -static void * -udp_port_handler (uint16 port) -{ - int index; - - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - if (udp_port_table[index].port == port) - { - return (void *)udp_port_table[index].handler; - } - } - return NULL; -} -/********************************************************************/ -uint16 -udp_obtain_free_port (void) -{ - uint16 port; - - port = udp_port; - if (--udp_port <= 255) - udp_port = DEFAULT_UDP_PORT; - - return port; -} -/********************************************************************/ -int -udp_send ( NIF *nif, uint8 *dest, int sport, int dport, NBUF *pNbuf) -{ - /* - * This function takes data and creates a UDP frame and - * passes it onto the IP layer - */ - udp_frame_hdr *udpframe; - - udpframe = (udp_frame_hdr *)&pNbuf->data[UDP_HDR_OFFSET]; - - /* Set UDP source port */ - udpframe->src_port = (uint16)sport; - - /* Set UDP destination port */ - udpframe->dest_port = (uint16)dport; - - /* Set length */ - udpframe->length = (uint16)(pNbuf->length + UDP_HDR_SIZE); - - /* No checksum calcualation needed */ - udpframe->chksum = (uint16)0; - - /* Add the length of the UDP packet to the total length of the packet */ - pNbuf->length += 8; - - return (ip_send(nif, - dest, - ip_get_myip(nif_get_protocol_info(nif,ETH_FRM_IP)), - IP_PROTO_UDP, - pNbuf)); -} -/********************************************************************/ -void -udp_handler (NIF *nif, NBUF *pNbuf) -{ - /* - * This function handles incoming UDP packets - */ - udp_frame_hdr *udpframe; - void (*handler)(NIF *, NBUF *); - - udpframe = (udp_frame_hdr *)&pNbuf->data[pNbuf->offset]; - - /* - * Adjust the length and valid data offset of the packet we are - * passing on - */ - pNbuf->length -= UDP_HDR_SIZE; - pNbuf->offset += UDP_HDR_SIZE; - - /* - * Traverse the list of bound ports to see if there is a higher - * level protocol to pass the packet on to - */ - if ((handler = (void(*)(NIF*,NBUF*))udp_port_handler(UDP_DEST(udpframe))) != NULL) - handler(nif, pNbuf); - else - { - #ifdef DEBUG_PRINT - Cconws("Received UDP packet for non-supported port\r\n"); - #endif - nbuf_free(pNbuf); - } - - return; -} -/********************************************************************/ - -#endif /* LWIP */ -#endif /* NETWORK */ diff --git a/flash.tos/drivers/net/udp.h b/flash.tos/drivers/net/udp.h deleted file mode 100644 index 6126b47..0000000 --- a/flash.tos/drivers/net/udp.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * File: udp.h - * Purpose: User Datagram Protocol, UDP, data definitions - * - * Notes: - */ - -#ifndef _UDP_H -#define _UDP_H - -/********************************************************************/ - -typedef struct -{ - uint16 src_port; - uint16 dest_port; - uint16 length; - uint16 chksum; -} udp_frame_hdr; - -#define UDP_SOURCE(a) (a->src_port) -#define UDP_DEST(a) (a->dest_port) -#define UDP_LENGTH(a) (a->length) -#define UDP_CHKSUM(a) (a->chksum) - -#define DEFAULT_UDP_PORT (0x4321) -#define UDP_PORT_TELNET (23) -#define UDP_PORT_FTP (21) -#define UDP_PORT_TFTP (69) - -/* Protocol Header information */ -#define UDP_HDR_OFFSET (ETH_HDR_LEN + IP_HDR_SIZE) -#define UDP_HDR_SIZE 8 - - -/********************************************************************/ - -void -udp_init (void); - -void -udp_prime_port (uint16); - -uint16 -udp_obtain_free_port (void); - -void -udp_bind_port ( uint16, void (*)(NIF *,NBUF *)); - -void -udp_free_port (uint16); - -int -udp_send (NIF *, uint8 *, int, int, NBUF *); - -void -udp_handler (NIF *, NBUF *); - -/********************************************************************/ - -#endif /* _UDP_H */ diff --git a/flash.tos/drivers/printk.c b/flash.tos/drivers/printk.c index 906ed07..bc490de 100644 --- a/flash.tos/drivers/printk.c +++ b/flash.tos/drivers/printk.c @@ -13,7 +13,6 @@ #define FALSE (0) #define TRUE (1) -#define NULL (0) /********************************************************************/ @@ -69,7 +68,7 @@ typedef struct extern void direct_conout(char c); -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern void board_putchar(char c); @@ -80,7 +79,7 @@ static void board_putchar(char c) direct_conout(c); } -#endif /* defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) */ +#endif /* defined(COLDFIRE) && defined(LWIP) */ /********************************************************************/ static void printk_putc(char c, int *count, PRINTK_INFO *info) diff --git a/flash.tos/drivers/radeon.sys b/flash.tos/drivers/radeon.sys deleted file mode 100644 index 5ee3f93..0000000 Binary files a/flash.tos/drivers/radeon.sys and /dev/null differ diff --git a/flash.tos/drivers/radeon/radeon_base.c b/flash.tos/drivers/radeon/radeon_base.c index 597a2ad..6029402 100644 --- a/flash.tos/drivers/radeon/radeon_base.c +++ b/flash.tos/drivers/radeon/radeon_base.c @@ -1950,6 +1950,9 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo) int radeonfb_pci_register(long handle, const struct pci_device_id *ent) { +#ifdef DRIVER_IN_ROM + extern short os_magic; +#endif struct fb_info *info; struct radeonfb_info *rinfo; PCI_RSC_DESC *pci_rsc_desc; @@ -2017,18 +2020,24 @@ int radeonfb_pci_register(long handle, const struct pci_device_id *ent) else if((pci_rsc_desc->length >= RADEON_REGSIZE) && (pci_rsc_desc->length < 0x100000)) { - if(rinfo->bios_seg == NULL) + if(pci_rsc_desc->flags & FLG_ROM) { - rinfo->bios_seg_phys = pci_rsc_desc->start; - if(BIOS_IN16(0) == 0xaa55) - rinfo->bios_seg = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); - else - rinfo->bios_seg_phys = 0; + if(rinfo->bios_seg == NULL) + { + rinfo->bios_seg_phys = pci_rsc_desc->start; + if(BIOS_IN16(0) == 0xaa55) + rinfo->bios_seg = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); + else + rinfo->bios_seg_phys = 0; + } } - if(rinfo->mmio_base_phys == 0xFFFFFFFF) - { - rinfo->mmio_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); - rinfo->mmio_base_phys = pci_rsc_desc->start; + else + { + if(rinfo->mmio_base_phys == 0xFFFFFFFF) + { + rinfo->mmio_base = (void *)(pci_rsc_desc->offset + pci_rsc_desc->start); + rinfo->mmio_base_phys = pci_rsc_desc->start; + } } } } @@ -2093,13 +2102,20 @@ int radeonfb_pci_register(long handle, const struct pci_device_id *ent) #ifdef DRIVER_IN_ROM /* Run VGA BIOS */ - if(rinfo->bios_seg != NULL) + if((rinfo->bios_seg != NULL) && !os_magic) { Cconws("Run VGA BIOS, please wait...\r\n"); DPRINT("radeonfb: radeonfb_pci_register: run VGA BIOS\r\n"); run_bios(rinfo); } +#if defined(COLDFIRE) && defined(LWIP) + else /* abnormal */ + { + extern void uif_cmd_reset(void); + uif_cmd_reset(); + } #endif +#endif /* DRIVER_IN_ROM */ #if 1 DPRINT("radeonfb: radeonfb_pci_register: fixup display base address\r\n"); @@ -2128,7 +2144,7 @@ int radeonfb_pci_register(long handle, const struct pci_device_id *ent) framebuffer_release(info); return(-EIO); } - + /* Get informations about the board's PLL */ DPRINT("radeonfb: radeonfb_pci_register: get informations about the board's PLL\r\n"); radeon_get_pllinfo(rinfo); @@ -2146,7 +2162,7 @@ int radeonfb_pci_register(long handle, const struct pci_device_id *ent) /* set offscreen memory descriptor */ DPRINT("radeonfb: radeonfb_pci_register: set offscreen memory descriptor\r\n"); offscreen_init(info); - + /* Probe screen types */ DPRINT("radeonfb: radeonfb_pci_register: probe screen types, monitor_layout: "); DPRINT(monitor_layout); diff --git a/flash.tos/drivers/radeon/radeon_theatre_dsp.c b/flash.tos/drivers/radeon/radeon_theatre_dsp.c new file mode 100644 index 0000000..f7af6d5 --- /dev/null +++ b/flash.tos/drivers/radeon/radeon_theatre_dsp.c @@ -0,0 +1,2081 @@ +#include "config.h" +#ifdef RADEON_THEATRE +/* File ./ati.bin encoded */ + +#define LEN_THEATRE_DSP 33141L + +unsigned long len_theatre_dsp=LEN_THEATRE_DSP; +unsigned char theatre_dsp[LEN_THEATRE_DSP+1]= { +0x00,0x00,0xfb,0x60,0xcd,0x4a,0x4d,0x00,0x00,0x02,0x10,0x00,0x00,0x1c,0x00,0x00, +0x00,0x04,0x00,0x00,0x00,0x00,0x40,0xcd,0x04,0x05,0x00,0x00,0xb3,0xe4,0x37,0x72, +0xcd,0x05,0x0c,0x10,0x00,0x00,0x57,0x3e,0x0a,0x37,0xcd,0x05,0x0c,0x20,0x00,0x00, +0x9c,0xfa,0xe1,0xf9,0x20,0x3b,0x00,0x00,0x00,0x30,0x00,0x00,0x6d,0x23,0xb5,0x93, +0x10,0x00,0x7f,0x01,0x47,0x02,0xff,0x02,0x0b,0x03,0x0d,0x03,0x19,0x03,0x09,0x04, +0x1b,0x03,0x5a,0x03,0x99,0x03,0xc2,0x03,0xeb,0x03,0xf9,0x03,0x07,0x04,0x07,0x04, +0xcd,0x04,0x04,0xcd,0x08,0x08,0xcd,0x04,0x04,0x81,0x01,0x19,0x03,0x19,0x03,0x0b, +0x03,0x0b,0x03,0x49,0x02,0x4b,0x02,0x83,0x01,0xfc,0xff,0x9d,0x19,0x00,0xf8,0x83, +0x19,0xfc,0x3f,0x1c,0x1b,0x00,0x00,0x9c,0x1b,0x20,0x00,0xc0,0x02,0x00,0x00,0x00, +0x00,0x38,0xcd,0x07,0x08,0x2d,0xcd,0x07,0x08,0x63,0x13,0xcd,0x06,0x08,0xa9,0x12, +0xcd,0x06,0x08,0x15,0x12,0x80,0xcd,0x05,0x08,0x40,0xfc,0x05,0x1b,0x54,0xfc,0x09, +0x1b,0x00,0x00,0x01,0x1b,0xff,0xff,0x0d,0x1b,0x00,0x28,0x80,0x19,0x00,0x08,0x00, +0x1a,0x30,0x10,0x00,0x1a,0x00,0x48,0x80,0x19,0x00,0x48,0x82,0x19,0x00,0x50,0x80, +0x19,0x00,0x50,0x82,0x19,0x00,0x00,0x00,0x03,0xcd,0x04,0x34,0x81,0x9f,0x91,0x19, +0x00,0x98,0xc3,0x19,0x9c,0xfa,0x20,0x1b,0x00,0x00,0xa0,0x1b,0x80,0x27,0x00,0x1b, +0x00,0x00,0x80,0x1b,0x34,0x00,0x24,0x1b,0xf0,0xcd,0x07,0x68,0xcd,0x08,0x2c,0x00, +0x40,0x91,0x19,0x00,0x48,0x81,0x19,0x04,0x48,0x83,0x19,0x10,0x00,0x00,0x1b,0x7f, +0x01,0x80,0x1b,0x47,0x02,0x04,0x1b,0xff,0x02,0x84,0x1b,0x10,0x02,0x80,0x1a,0x0b, +0x03,0x00,0x1b,0x0d,0x03,0x80,0x1b,0x10,0x0a,0x80,0x1a,0x19,0x03,0x04,0x1b,0x09, +0x04,0xcd,0x06,0x18,0x1b,0x03,0x00,0x1b,0x5a,0xcd,0x07,0x18,0x99,0x03,0x04,0x1b, +0xc2,0x03,0xcd,0x06,0x18,0xeb,0x03,0x00,0x1b,0xf9,0xcd,0x07,0x18,0x07,0x04,0x04, +0x1b,0x07,0xcd,0x07,0x30,0x07,0x04,0x00,0x1b,0x07,0x04,0xcd,0x18,0x18,0xcd,0x12, +0x18,0x81,0x01,0x00,0x1b,0x19,0xcd,0x0b,0x78,0x0b,0xcd,0x07,0x60,0x0b,0x03,0x00, +0x1b,0x49,0x02,0xcd,0x06,0x18,0x4b,0x02,0x04,0x1b,0x83,0x01,0xcd,0x06,0x18,0xcd, +0x04,0x10,0xcd,0x05,0x81,0x4c,0x00,0x81,0x19,0x00,0x08,0x81,0x19,0x04,0x08,0x83, +0x19,0x0f,0x20,0x80,0x19,0x10,0x0a,0x01,0x26,0x02,0x74,0x01,0x01,0xcd,0x05,0x81, +0x6c,0xf4,0xbf,0xcd,0x05,0x08,0xf5,0xcd,0x07,0x82,0x74,0xc1,0xa5,0x28,0x1b,0x01, +0x00,0x2c,0x1b,0x00,0x40,0x30,0x1b,0x00,0x00,0x04,0x1b,0xce,0x09,0x84,0x08,0x44, +0xfc,0x00,0x1b,0x10,0x80,0x09,0x24,0xcd,0x04,0x20,0x01,0xf8,0x3f,0xcd,0x05,0x30, +0xd9,0x00,0xc0,0x02,0x18,0x03,0x04,0x1b,0xe0,0x03,0x14,0x14,0xcd,0x04,0x0c,0x1c, +0xcd,0x05,0x0c,0x18,0x14,0xa0,0x28,0x10,0x26,0x54,0xfc,0x00,0x1b,0xff,0xff,0x09, +0x1b,0x02,0x10,0x00,0x01,0x20,0x00,0x00,0x1a,0xce,0x00,0xcd,0x06,0x83,0x38,0xe0, +0x2f,0x80,0x09,0xf0,0x03,0x80,0x34,0x04,0xe8,0x00,0x01,0x22,0x00,0x34,0x1b,0xc0, +0x00,0x90,0x34,0x09,0xdc,0x00,0x01,0xd0,0x2b,0x84,0x09,0xb0,0x08,0x10,0x26,0xc0, +0x29,0x88,0x09,0x02,0xcc,0x00,0x01,0xc1,0x00,0x0c,0x1b,0x30,0x10,0x10,0x26,0x01, +0x1c,0x00,0x01,0xc2,0xcd,0x08,0x0c,0x44,0x00,0xcd,0x05,0x78,0xca,0x00,0x80,0x02, +0x24,0x00,0x34,0x1b,0x10,0x01,0xcd,0x06,0x81,0x30,0x60,0x08,0x08,0x26,0x02,0x98, +0x00,0x01,0x29,0x00,0x34,0x1b,0xf0,0x5b,0x88,0x34,0x02,0x8c,0x00,0x01,0x21,0x00, +0x34,0x1b,0x00,0x00,0x00,0x1b,0xf0,0x5b,0x2c,0x14,0xc0,0x87,0x85,0x08,0xcd,0x04, +0x34,0x10,0x00,0x00,0x1a,0xcd,0x04,0x20,0x01,0x6c,0x00,0x01,0x00,0x10,0x08,0x1b, +0x20,0x30,0x88,0x34,0xf0,0x03,0x0c,0x14,0xc4,0x1f,0x8c,0x09,0x04,0x58,0x00,0x01, +0x30,0x30,0x08,0x14,0x00,0x40,0x04,0x1b,0x10,0x10,0x88,0x34,0x08,0x48,0x00,0x01, +0xe0,0x03,0x08,0x14,0x06,0x00,0x00,0x1b,0x00,0xe0,0x80,0x1b,0x0e,0x15,0x00,0x09, +0x00,0x00,0x04,0x1b,0x00,0x10,0x84,0x1b,0xeb,0x00,0xc0,0x02,0xe0,0x33,0x08,0x14, +0xcd,0x04,0x10,0xac,0x0d,0xcd,0x16,0x82,0x1c,0xcd,0x04,0x78,0x21,0x00,0x34,0x1b, +0x2a,0x01,0xc0,0x02,0xe0,0x6b,0x00,0x14,0x7a,0xcd,0x07,0x82,0x00,0xcd,0x08,0x84, +0x60,0x64,0xfc,0x08,0x1b,0x60,0xfc,0x0c,0x1b,0x00,0x8f,0x84,0x1b,0x00,0x28,0x10, +0x18,0xcd,0x05,0x85,0x40,0x10,0x00,0x1a,0x10,0x18,0x00,0x1a,0xcd,0x04,0x24,0x40, +0x28,0x80,0x18,0xcd,0x05,0x20,0x0f,0x84,0x1b,0xcd,0x04,0x2c,0xcd,0x08,0x24,0xcd, +0x04,0x20,0x38,0x9f,0x81,0x29,0x01,0xfc,0x3f,0x01,0x00,0x10,0x00,0x0e,0xcd,0x08, +0x2c,0x00,0x28,0x04,0x18,0x01,0x08,0x80,0x1a,0xa0,0x13,0xc0,0x02,0xcd,0x04,0x28, +0x01,0x00,0x84,0xcd,0x05,0x1c,0x10,0xcd,0x04,0x1c,0x80,0x0d,0x18,0xcd,0x09,0x64, +0x84,0xfd,0x19,0x10,0x08,0x02,0x1a,0x20,0x10,0x02,0x1a,0x00,0x00,0x02,0x1a,0xcd, +0x05,0x3c,0x00,0x00,0x03,0x30,0x80,0x81,0x18,0x00,0x40,0x89,0xcd,0x09,0x85,0x74, +0x02,0x50,0x80,0x19,0x00,0x00,0x00,0x1b,0x18,0x00,0x0c,0x1b,0x00,0x00,0x10,0x1b, +0x00,0x80,0x90,0x1b,0xb7,0x1d,0x18,0x1b,0xc1,0x04,0x98,0x1b,0xff,0x20,0x80,0x19, +0x34,0x00,0x04,0x0b,0x00,0x20,0x08,0x18,0x01,0x10,0x80,0x1a,0x07,0x20,0x80,0x19, +0x40,0x08,0x08,0x24,0xf4,0x0b,0x04,0x0b,0x60,0x08,0x04,0x86,0xcd,0x08,0x84,0x50, +0x01,0x00,0x88,0x0e,0x20,0x20,0x80,0x18,0xcd,0x05,0x85,0x04,0xd0,0xbf,0x01,0xf0, +0x03,0x00,0x14,0xcd,0x0a,0x86,0x60,0xcd,0x0a,0x6c,0x03,0xcd,0x07,0x85,0x1c,0x01, +0x08,0x83,0x19,0x00,0x20,0x80,0x18,0x00,0x40,0x01,0x18,0xff,0xff,0x05,0x1b,0xff, +0x00,0x10,0x1b,0x08,0x00,0x14,0x1b,0x00,0x08,0x09,0x0e,0xf0,0x0f,0x8c,0x09,0x30, +0x10,0x08,0x06,0x40,0x10,0x08,0x04,0xe4,0x17,0x00,0x09,0x00,0x40,0x81,0x18,0x00, +0x02,0x88,0x0e,0x54,0x08,0x04,0x0b,0x00,0xe0,0xbf,0x01,0x20,0x08,0x04,0x06,0xcd, +0x08,0x5c,0xf0,0x1f,0x00,0x09,0xe0,0x15,0x00,0x09,0xd0,0x0b,0x00,0x09,0xd0,0xcd, +0x07,0x85,0x24,0x00,0x00,0xcd,0x05,0x87,0x6c,0x08,0xcd,0x05,0x10,0x00,0xcd,0x05, +0x10,0xcd,0x06,0x81,0x08,0xfc,0xcd,0x04,0x0c,0x08,0x1b,0xf8,0x07,0x08,0x09,0xcd, +0x04,0x14,0x20,0x08,0x00,0x1a,0xc8,0x1f,0x00,0x1b,0x40,0x04,0x80,0xcd,0x05,0x85, +0x7c,0x00,0x70,0x84,0xcd,0x05,0x20,0xeb,0x00,0xc0,0x02,0x00,0x10,0x88,0xcd,0x09, +0x38,0xcd,0x05,0x24,0x14,0xcd,0x0b,0x24,0x04,0xcd,0x17,0x24,0x24,0xcd,0x07,0x24, +0xa0,0xcd,0x0b,0x48,0x18,0xcd,0x0f,0x24,0x34,0xcd,0x0b,0x24,0xcd,0x08,0x48,0xcd, +0x0b,0x24,0xc0,0x23,0x0c,0x1b,0x30,0x00,0x80,0x0e,0xb0,0xcd,0x05,0x08,0x84,0x0e, +0xb8,0x23,0x0c,0xcd,0x05,0x24,0x30,0x00,0x88,0xcd,0x05,0x83,0x64,0xcd,0x04,0x24, +0xc4,0xcd,0x07,0x24,0xb4,0xcd,0x07,0x24,0xbc,0xcd,0x13,0x24,0xa6,0xff,0x00,0x1b, +0x01,0x40,0x80,0x1b,0x00,0x01,0x04,0x1b,0x00,0x18,0xcd,0x0b,0x81,0x10,0x30,0xcd, +0x0a,0x6c,0xcd,0x09,0x24,0x05,0xcd,0x1a,0x24,0x00,0x00,0x40,0xcd,0x08,0x08,0xcd, +0x05,0x08,0x01,0x00,0x80,0x1a,0x01,0x08,0x80,0x1a,0x01,0x10,0x80,0x1a,0x01,0x18, +0x80,0x1a,0x01,0x20,0x80,0x1a,0x01,0x28,0x80,0x1a,0x01,0x30,0x80,0x1a,0x01,0x38, +0x80,0x1a,0x01,0x40,0x80,0x1a,0x01,0x48,0x80,0x1a,0x01,0x50,0x80,0x1a,0x01,0x58, +0x80,0x1a,0x01,0x60,0x80,0x1a,0x01,0x68,0x80,0x1a,0x01,0x70,0x80,0x1a,0x01,0x78, +0x80,0x1a,0x01,0x80,0x80,0x1a,0x01,0x88,0x80,0x1a,0x01,0x90,0x80,0x1a,0x01,0x98, +0x80,0x1a,0x01,0xa0,0x80,0x1a,0x01,0xa8,0x80,0x1a,0x01,0xb0,0x80,0x1a,0x01,0xb8, +0x80,0x1a,0x01,0xc0,0x80,0x1a,0x01,0xc8,0x80,0x1a,0x01,0xd0,0x80,0x1a,0x01,0xd8, +0x80,0x1a,0x01,0xe0,0x80,0x1a,0x01,0xe8,0x80,0x1a,0x01,0xf0,0x80,0x1a,0x01,0xf8, +0x80,0x1a,0x00,0x00,0x80,0x17,0xe0,0x00,0x84,0x17,0xcd,0x09,0x81,0x08,0x00,0x80, +0x17,0xe1,0xcd,0x0b,0x10,0x02,0x00,0x80,0x17,0xe2,0xcd,0x0b,0x10,0x03,0x00,0x80, +0x17,0xe3,0xcd,0x0b,0x10,0x00,0x20,0x00,0x18,0xcd,0x04,0x0c,0x00,0x00,0x01,0xcd, +0x06,0x08,0x10,0xcd,0x07,0x08,0x20,0xcd,0x07,0x08,0x30,0xcd,0x07,0x08,0x40,0xcd, +0x07,0x08,0x50,0xcd,0x07,0x08,0x60,0xcd,0x07,0x08,0x70,0xcd,0x07,0x08,0x08,0xcd, +0x07,0x08,0x18,0xcd,0x07,0x08,0x28,0xcd,0x07,0x08,0x38,0xcd,0x07,0x08,0x48,0xcd, +0x07,0x08,0x58,0xcd,0x07,0x08,0x68,0xcd,0x07,0x08,0x78,0xcd,0x07,0x08,0x80,0xcd, +0x07,0x08,0x90,0xcd,0x07,0x08,0x88,0xcd,0x07,0x08,0x98,0xcd,0x08,0x40,0xcd,0x07, +0x81,0x28,0x50,0xcd,0x07,0x08,0x28,0xcd,0x07,0x08,0x58,0xcd,0x06,0x08,0x1a,0x1a, +0xcd,0x06,0x8a,0x10,0x01,0x00,0x80,0x0e,0x00,0x58,0x80,0xcd,0x04,0x14,0x0e,0x00, +0x28,0xcd,0x07,0x08,0x50,0xcd,0x07,0x08,0x48,0xcd,0x07,0x08,0x98,0x81,0xcd,0x06, +0x08,0x88,0xcd,0x07,0x08,0x90,0xcd,0x07,0x08,0x80,0xcd,0x07,0x08,0x78,0xcd,0x07, +0x08,0x68,0xcd,0x07,0x08,0x58,0xcd,0x07,0x08,0x48,0xcd,0x07,0x08,0x38,0xcd,0x07, +0x08,0x28,0xcd,0x07,0x08,0x18,0xcd,0x07,0x08,0x08,0xcd,0x07,0x08,0x70,0xcd,0x07, +0x08,0x60,0xcd,0x07,0x08,0x50,0xcd,0x07,0x08,0x40,0xcd,0x07,0x08,0x30,0xcd,0x07, +0x08,0x20,0xcd,0x07,0x08,0x10,0xcd,0x07,0x08,0x00,0xcd,0x08,0x18,0x80,0x18,0x01, +0x00,0x84,0x0e,0xcd,0x04,0x0c,0x1f,0x00,0x80,0x10,0xcd,0x08,0x0c,0x1a,0xcd,0x0b, +0x0c,0x15,0xcd,0x0b,0x0c,0x10,0xcd,0x05,0x0c,0xfc,0x0e,0x01,0x00,0xf8,0x0e,0x01, +0x00,0xf4,0x0e,0x01,0x00,0xf0,0x0e,0x01,0x00,0xec,0x0e,0x01,0x00,0xe8,0x0e,0x01, +0x00,0xe4,0x0e,0x01,0x00,0xe0,0x0e,0x01,0x00,0xdc,0x0e,0x01,0x00,0xd8,0x0e,0x01, +0x00,0xd4,0x0e,0x01,0x00,0xd0,0x0e,0x01,0x00,0xcc,0x0e,0x01,0x00,0xc8,0x0e,0x01, +0x00,0xc4,0x0e,0x01,0x00,0xc0,0x0e,0x01,0x00,0xbc,0x0e,0x01,0x00,0xb8,0x0e,0x01, +0x00,0xb4,0x0e,0x01,0x00,0xb0,0x0e,0x01,0x00,0xac,0x0e,0x01,0x00,0xa8,0x0e,0x01, +0x00,0xa4,0x0e,0x01,0x00,0xa0,0x0e,0x01,0x00,0x9c,0x0e,0x01,0x00,0x98,0x0e,0x01, +0x00,0x94,0x0e,0x01,0x00,0x90,0x0e,0x01,0x00,0x8c,0x0e,0x01,0x00,0x88,0x0e,0xcd, +0x08,0x81,0x04,0xcd,0x10,0x86,0x18,0xcd,0x0c,0x86,0x20,0xcd,0x09,0x83,0x3c,0xcd, +0x07,0x84,0x6c,0xcd,0x18,0x86,0x30,0x08,0x20,0x80,0x19,0xd9,0x00,0xc0,0x02,0x54, +0x08,0x04,0x1b,0xfe,0x07,0x84,0x29,0x02,0x18,0x00,0x01,0xb4,0x24,0x08,0x1b,0x00, +0xec,0xcd,0x06,0x8a,0x54,0x62,0x02,0xcd,0x06,0x8c,0x48,0xfe,0x07,0x04,0x08,0x20, +0x08,0x80,0x1a,0xb8,0x24,0x18,0x1b,0x60,0x00,0x94,0x0e,0x00,0x28,0x88,0x29,0x02, +0x34,0xcd,0x06,0x8e,0x20,0xc4,0x24,0x10,0x1b,0x02,0x00,0x0c,0x1b,0x40,0x00,0x84, +0x0e,0x00,0x02,0x10,0x1b,0x34,0x08,0x04,0x0b,0x40,0x08,0x90,0x34,0x04,0x14,0x02, +0xcd,0x07,0x8b,0x18,0x08,0x1b,0x00,0x10,0x14,0x09,0x60,0x28,0x80,0x1a,0xbc,0x24, +0x08,0x1b,0x20,0x00,0x80,0x0e,0xb0,0x24,0x04,0x1b,0x10,0x00,0x88,0x0e,0x20,0x00, +0x00,0x14,0xcd,0x0c,0x40,0xcd,0x04,0x3c,0xcd,0x04,0x44,0x20,0x08,0x8c,0x34,0x40, +0x18,0x8c,0x14,0x00,0x04,0x10,0x1b,0x09,0x0c,0x00,0x01,0x80,0x01,0x14,0x1b,0x40, +0x18,0x0c,0x14,0x08,0x18,0x18,0x16,0x50,0x30,0x90,0x34,0x04,0x0c,0xcd,0x06,0x7c, +0x30,0x10,0x08,0x14,0x04,0x00,0x18,0x1b,0x00,0x04,0x0c,0x1b,0x00,0x04,0x04,0x1b, +0x60,0x10,0x08,0x34,0x09,0x10,0xcd,0x06,0x1c,0x93,0x02,0x80,0x02,0x10,0x10,0x08, +0x14,0x30,0x10,0x8c,0xcd,0x09,0x30,0x10,0x10,0x88,0x14,0x00,0x00,0x0c,0xcd,0x06, +0x81,0x00,0x10,0x80,0x1a,0xa8,0x24,0x10,0x1b,0xac,0x24,0x14,0x1b,0x40,0x00,0x80, +0x0e,0x50,0x00,0x84,0x0e,0x10,0x00,0x08,0x14,0x20,0x18,0x80,0x1a,0xc0,0xcd,0x05, +0x81,0x28,0x8c,0x0e,0xac,0x1d,0x88,0x29,0x02,0xb8,0xcd,0x06,0x3c,0x60,0x08,0x04, +0x14,0xcd,0x04,0x68,0x30,0x08,0x8c,0x34,0x02,0x94,0xcd,0x06,0x14,0x00,0x04,0x08, +0xcd,0x05,0x8a,0x4c,0x20,0x00,0x80,0x34,0x01,0x14,0xcd,0x08,0x14,0x00,0x1b,0xc9, +0xcd,0x07,0x82,0x38,0x00,0x14,0x00,0x1b,0xcd,0x08,0x4c,0xc6,0x18,0x98,0x29,0x02, +0x5c,0xcd,0x06,0x24,0xc6,0x18,0x8c,0x08,0xcd,0x04,0x68,0xcd,0x18,0x83,0x1c,0x40, +0xfc,0x00,0x1b,0x58,0x83,0x85,0x08,0x10,0x00,0x00,0x1a,0x5b,0xcd,0x07,0x90,0x78, +0x64,0xcd,0x07,0x08,0xcd,0x18,0x84,0x10,0x50,0x08,0x80,0x1a,0x40,0x00,0x80,0x1a, +0xf2,0xcd,0x07,0x7c,0xcd,0x0d,0x81,0x30,0x80,0xcd,0x13,0x81,0x30,0x3c,0xcd,0x06, +0x14,0xcd,0x08,0x74,0x10,0xfc,0x00,0x1b,0x08,0x81,0x85,0x29,0x02,0xcd,0x07,0x82, +0x40,0x76,0xcd,0x0f,0x70,0x00,0x04,0x00,0x1b,0xf0,0xcd,0x05,0x5c,0x04,0x1b,0xcd, +0x18,0x34,0x6d,0xcd,0x10,0x34,0x14,0x00,0xcd,0x05,0x70,0xcd,0x08,0x81,0x1c,0xcd, +0x1d,0x85,0x50,0xcd,0x05,0x87,0x04,0xcd,0x0b,0x88,0x34,0xcd,0x1c,0x8b,0x70,0xcd, +0x23,0x86,0x10,0xcd,0x38,0x38,0xcd,0x14,0x38,0xcd,0x08,0x86,0x50,0x37,0xcd,0x07, +0x81,0x60,0xc0,0x24,0x00,0x1b,0x00,0x00,0x88,0x0e,0x42,0x10,0x84,0x08,0x00,0x08, +0x80,0x1a,0xa0,0xcd,0x05,0x10,0x04,0x1b,0xcd,0x04,0x0c,0x9c,0x24,0x00,0x1b,0x0a, +0x00,0x08,0x1b,0x00,0x00,0x84,0x0e,0xf0,0x0f,0x80,0x09,0x00,0x10,0x84,0x34,0x04, +0x30,0xcd,0x06,0x82,0x20,0xb8,0x24,0x00,0x1b,0x90,0x24,0x0c,0xcd,0x08,0x3c,0x29, +0x30,0x00,0x88,0x0e,0xf0,0x13,0x08,0x14,0x02,0x64,0x00,0x01,0xf0,0x13,0x88,0x04, +0x51,0x03,0x80,0x02,0x30,0x10,0x80,0x1a,0xcd,0x04,0x28,0xcd,0x04,0x24,0x10,0x12, +0x84,0x29,0x01,0x2c,0xcd,0x06,0x3c,0x40,0xfc,0x00,0x1b,0xfe,0x87,0xcd,0x06,0x84, +0x14,0x44,0xfc,0xcd,0x06,0x70,0xfe,0x0f,0x84,0xcd,0x05,0x10,0xcd,0x04,0x38,0xcd, +0x0a,0x24,0x05,0xcd,0x05,0x14,0x54,0xcd,0x0f,0x24,0xcd,0x0a,0x82,0x5c,0xcd,0x1a, +0x82,0x04,0xcd,0x1c,0x81,0x7c,0x40,0xcd,0x1c,0x81,0x7c,0x10,0xcd,0x42,0x81,0x7c, +0x90,0xcd,0x37,0x81,0x7c,0xcd,0x04,0x38,0xcd,0x60,0x81,0x7c,0x49,0xcd,0x0f,0x81, +0x7c,0x84,0xcd,0x07,0x81,0x7c,0xa4,0xcd,0x0f,0x83,0x78,0x0b,0xcd,0x0b,0x81,0x7c, +0x20,0x00,0x84,0x34,0x04,0xcd,0x07,0x81,0x40,0xcd,0x19,0x81,0x7c,0x0c,0xcd,0x06, +0x81,0x7c,0x30,0xcd,0x04,0x74,0xcd,0x3f,0x81,0x24,0x52,0xcd,0x1c,0x81,0x24,0xcd, +0x0b,0x83,0x20,0xcd,0x74,0x81,0x24,0xcd,0x08,0x89,0x44,0xcd,0x30,0x38,0xcd,0x0a, +0x89,0x74,0xcd,0x37,0x87,0x70,0xcd,0x08,0x94,0x18,0xcd,0x14,0x94,0x14,0xf8,0xcd, +0x12,0x8e,0x28,0xcd,0x09,0x92,0x74,0xcd,0x07,0x92,0x3c,0x03,0x00,0x80,0xcd,0x05, +0x93,0x38,0xe3,0xcd,0x07,0x08,0xcd,0x0c,0x9d,0x04,0xc0,0x29,0x80,0x09,0x8c,0x24, +0x04,0x1b,0x0f,0x00,0x08,0x1b,0x10,0x00,0x8c,0x0e,0x30,0x10,0x04,0x26,0x02,0xcd, +0x07,0x82,0x4c,0x52,0xcd,0x05,0x84,0x14,0x08,0xcd,0x05,0x9c,0x50,0x53,0xcd,0x08, +0x0c,0xcd,0x07,0x8a,0x24,0xbe,0x0b,0x80,0x02,0x2d,0x00,0x00,0x1b,0x29,0xcd,0x05, +0x18,0x88,0x34,0x04,0x44,0x08,0xcd,0x05,0x18,0xb0,0x46,0x85,0xcd,0x0a,0xa0,0x04, +0x20,0x80,0x19,0xcd,0x04,0x60,0x10,0x02,0x88,0x0e,0xc0,0x11,0x8c,0x09,0x30,0x00, +0x04,0x26,0xe0,0x17,0x84,0x09,0x01,0x18,0x00,0x01,0xcd,0x04,0x14,0x00,0xf0,0xbf, +0x01,0xcd,0x04,0x18,0xcd,0x04,0x4c,0x24,0x00,0x00,0x1b,0x00,0x08,0x00,0xcd,0x05, +0x82,0x28,0xd0,0x2b,0x80,0x09,0x10,0x06,0x08,0x26,0x02,0x54,0x03,0xcd,0x04,0x54, +0xcd,0x09,0x9b,0x48,0x03,0x20,0x80,0x19,0x00,0x20,0xcd,0x06,0x9b,0x34,0x0e,0x20, +0x80,0x19,0x32,0xcd,0x07,0x82,0x58,0x00,0xf8,0xcd,0x06,0x9a,0x28,0x07,0x10,0xc0, +0x02,0xff,0xff,0x18,0x1b,0x01,0x00,0x84,0x0e,0x10,0x20,0xcd,0x05,0x9b,0x24,0x1b, +0x00,0xd0,0xcd,0x06,0x90,0x04,0x40,0xfc,0x00,0x1b,0x90,0x85,0x05,0x08,0xbc,0x0f, +0x04,0xcd,0x0d,0x86,0x5c,0x90,0x0d,0x84,0x08,0xbc,0xcd,0x07,0x86,0x60,0xcd,0x07, +0x9b,0x58,0x1b,0x1a,0x0f,0xc0,0x02,0x80,0x03,0x80,0x08,0xe0,0x03,0x04,0x34,0x02, +0x20,0x00,0x01,0x27,0x00,0xcd,0x08,0x8e,0x00,0x84,0x0e,0xc2,0x08,0x04,0x08,0xe8, +0x0e,0xcd,0x06,0x90,0x48,0x21,0x00,0x00,0x1b,0xbe,0x0b,0xcd,0x06,0x87,0x38,0xcd, +0x04,0x08,0xcd,0x04,0x10,0xd0,0x2b,0x88,0x09,0xf0,0x16,0x84,0x34,0x09,0x98,0x02, +0x01,0x14,0x16,0x10,0x0b,0x80,0x0e,0x00,0x1b,0x40,0x00,0x00,0x14,0x00,0x00,0x8c, +0x0e,0xc0,0x1b,0x84,0x09,0x00,0x08,0x40,0xcd,0x06,0x9f,0x54,0xcd,0x04,0x5c,0x0c, +0x00,0x01,0x25,0x00,0x00,0x1b,0xcd,0x0c,0x48,0xcd,0x09,0x40,0x58,0xcd,0x12,0x40, +0xe0,0x1f,0xcd,0x22,0x40,0xcd,0x08,0x81,0x28,0xe8,0x0e,0x88,0x09,0xcd,0x08,0x18, +0xd0,0x13,0x00,0x09,0xd0,0x2b,0x8c,0x09,0x30,0xf8,0x89,0x34,0x98,0x24,0x08,0x1b, +0x04,0xfc,0x01,0x01,0xcd,0x04,0x24,0x4a,0x09,0x84,0x08,0x08,0x19,0x04,0x09,0xf4, +0x0e,0xc0,0x02,0x20,0x08,0x80,0x1a,0xe0,0x03,0x0c,0x34,0x02,0x40,0xcd,0x06,0x54, +0x9c,0xcd,0x05,0x87,0x00,0x84,0x0e,0xf0,0x0f,0x04,0xcd,0x05,0x87,0x00,0x90,0x0e, +0xcd,0x06,0x82,0x6c,0xcd,0x05,0x78,0x1c,0xcd,0x06,0x24,0x40,0xfc,0x00,0x1b,0xbc, +0xcd,0x07,0x89,0x2c,0xc0,0xcd,0x0b,0x82,0x08,0xcd,0x08,0xa1,0x68,0x40,0x00,0x04, +0x1b,0xc6,0x00,0x80,0x08,0x8c,0x01,0xcd,0x06,0x9c,0x44,0xcd,0x04,0x10,0x14,0x46, +0x10,0x0b,0x30,0xcd,0x10,0x82,0x14,0xcd,0x04,0x31,0xcd,0x07,0x81,0x58,0x45,0xcd, +0x07,0x68,0x88,0xcd,0x07,0x92,0x64,0x85,0x0b,0xcd,0x04,0x10,0xa0,0x09,0xcd,0x0a, +0x50,0x00,0x08,0x8c,0x01,0x00,0xcd,0x09,0x50,0xcd,0x08,0x9a,0x60,0xd0,0x2b,0xa0, +0x09,0x10,0x00,0x04,0x1b,0x80,0x08,0x88,0x34,0x04,0x1c,0x01,0x01,0xcd,0x09,0x81, +0x40,0x47,0x04,0x09,0x00,0x08,0x80,0x1a,0xbb,0x04,0xcd,0x08,0x88,0x58,0xcd,0x06, +0x82,0x20,0xaa,0x0d,0xa0,0x29,0x01,0x5c,0x00,0x01,0x21,0x00,0x00,0x1b,0xf4,0xcd, +0x09,0x81,0x5c,0x0c,0x34,0x02,0x48,0xcd,0x06,0x81,0x5c,0xf0,0x43,0x0c,0x26,0x02, +0x24,0xcd,0x06,0x85,0x6c,0xcd,0x0d,0x81,0x7c,0x28,0xcd,0x06,0x20,0xfb,0x04,0xcd, +0x06,0x83,0x70,0xb9,0xcd,0x0c,0x1c,0xcd,0x13,0x83,0x10,0x01,0x05,0xcd,0x06,0x20, +0xcd,0x08,0x10,0x9c,0xcd,0x07,0x81,0x00,0xf0,0x0f,0x90,0x09,0xe0,0x0d,0xa0,0x09, +0x80,0x20,0x84,0x04,0xff,0x00,0x08,0x1b,0x20,0x08,0x04,0x26,0xcd,0x04,0x40,0xcd, +0x04,0x3c,0x28,0x00,0x00,0x1b,0xd0,0x23,0x00,0xcd,0x05,0x9e,0x5c,0xe0,0x45,0x00, +0x09,0xcd,0x08,0x34,0xd0,0x0b,0xa0,0x09,0xcd,0x05,0x2c,0x40,0xcd,0x0e,0x2c,0xcd, +0x05,0x83,0x64,0x43,0xcd,0x04,0x28,0x00,0x1b,0xd0,0x2b,0xa0,0x09,0x30,0x46,0x84, +0x34,0x09,0x18,0x00,0x01,0x00,0x00,0x84,0x0e,0x40,0x40,0xcd,0x06,0x82,0x00,0xcd, +0x08,0x85,0x20,0xcd,0x04,0x08,0x22,0xcd,0x05,0x85,0x28,0xa0,0x09,0xc0,0x46,0x8c, +0x34,0x09,0xf0,0x3f,0x01,0xe0,0x2d,0xa4,0x09,0xc0,0x4e,0x8c,0x34,0x09,0xe4,0x3f, +0x01,0xa8,0x23,0x04,0x1b,0xe0,0x43,0x00,0x34,0x01,0x24,0x00,0x01,0x10,0x00,0x88, +0x0e,0x50,0x02,0x08,0x09,0xf0,0x03,0x0c,0xcd,0x05,0x70,0xc0,0x11,0x8c,0x09,0x00, +0x00,0x0c,0x1b,0xf0,0x1f,0x08,0x09,0x10,0x10,0x80,0x1a,0xac,0xcd,0x04,0x2c,0x4b, +0xcd,0x26,0x2c,0xcd,0x08,0x81,0x00,0xcd,0x04,0x60,0x30,0x2e,0x90,0x09,0xd0,0x2b, +0x80,0x09,0x02,0x00,0x0c,0xcd,0x05,0x96,0x40,0x50,0x1a,0x08,0x09,0xc0,0x01,0x08, +0x09,0xf0,0x07,0x08,0x09,0xac,0x25,0xcd,0x0b,0x5c,0x2d,0x80,0x09,0xcd,0x18,0x20, +0xcd,0x0c,0x50,0xac,0x23,0xcd,0x06,0x89,0x3c,0x20,0x00,0x90,0x0e,0xf0,0x1f,0xa0, +0x09,0xac,0x1d,0xa8,0x09,0xf0,0x27,0xa4,0xcd,0x05,0x86,0x00,0xd0,0x43,0x00,0x09, +0xe0,0x4d,0x00,0xcd,0x05,0x88,0x64,0xf0,0x57,0x00,0x09,0xd0,0x2b,0x84,0x09,0x05, +0x00,0x08,0x1b,0x10,0x10,0x80,0x34,0x04,0x4c,0x01,0x01,0x22,0x00,0x20,0x1b,0xcd, +0x08,0x84,0x5c,0xcd,0x0c,0x85,0x28,0xcd,0x04,0x14,0xd0,0x00,0x04,0x1b,0x08,0xcd, +0x07,0x84,0x6c,0xcd,0x04,0x0c,0xc0,0xcd,0x05,0x82,0x60,0x84,0x09,0x00,0x00,0xa4, +0x0e,0x90,0x0a,0x24,0x09,0x14,0x0e,0x04,0x0b,0x00,0x0a,0x00,0x1b,0x10,0x00,0x04, +0x14,0x00,0x08,0x30,0x0e,0xcd,0x04,0x34,0xe0,0x00,0x04,0x1b,0x40,0x05,0x00,0x08, +0xf0,0x06,0x00,0x08,0xc0,0x00,0x80,0x04,0xcd,0x04,0x3c,0xcd,0x04,0x14,0xcd,0x04, +0x1c,0x34,0x00,0x04,0x1b,0xe0,0x03,0x30,0xcd,0x05,0xa7,0x78,0x38,0xcd,0x05,0x0c, +0x7c,0x14,0xe0,0x2d,0x94,0x29,0xcd,0x05,0xa6,0x5c,0x00,0x00,0x00,0xf0,0x2b,0x04, +0x26,0x03,0x00,0x04,0x1b,0x90,0x0a,0x7c,0x09,0x84,0x60,0xb0,0x08,0xcd,0x04,0x70, +0x01,0x58,0x00,0x01,0x18,0x00,0x08,0x1b,0x10,0x2e,0x04,0x26,0x01,0x4c,0x00,0x01, +0x0c,0x00,0x08,0x1b,0xc0,0xcd,0x04,0x0c,0x40,0x00,0x01,0x08,0x00,0x08,0x1b,0x30, +0xcd,0x04,0x0c,0x34,0x00,0x01,0x06,0x00,0x08,0x1b,0xe0,0xcd,0x04,0x0c,0x28,0x00, +0x01,0x04,0x00,0x08,0x1b,0x50,0xcd,0x04,0x0c,0x1c,0x00,0x01,0x03,0x00,0x08,0x1b, +0x00,0x48,0x80,0x1a,0xad,0x05,0x80,0x02,0x2c,0x00,0x20,0x1b,0x84,0x60,0x30,0x08, +0xf0,0xff,0x88,0x09,0xd8,0x2b,0x24,0x09,0xcd,0x04,0x18,0xf0,0x17,0x7c,0x09,0xe0, +0x63,0x00,0x14,0xd0,0xcd,0x08,0x81,0x20,0xfb,0xcd,0x06,0x0c,0x38,0x00,0x04,0x1b, +0x21,0xcd,0x07,0x82,0x1c,0xcd,0x06,0x82,0x08,0xcd,0x06,0x82,0x1c,0xcd,0x04,0x0c, +0xcd,0x0a,0x82,0x30,0xcd,0x0a,0x87,0x08,0xbe,0x0b,0x80,0x02,0xe0,0x43,0x00,0x14, +0xc0,0x24,0xcd,0x04,0x38,0x00,0xcd,0x05,0x83,0x10,0x90,0x1a,0xa0,0x09,0xd8,0x1b, +0xa4,0x09,0xd0,0x43,0xcd,0x06,0x83,0x00,0xe0,0x4d,0x00,0xcd,0x09,0x87,0x48,0xcd, +0x0c,0x82,0x6c,0xcd,0x04,0x38,0xcd,0x04,0x0c,0xe8,0xcd,0x17,0x5c,0xcd,0x08,0x87, +0x64,0xe0,0x03,0x04,0xcd,0x05,0x97,0x70,0x07,0x00,0x08,0x1b,0x20,0x00,0x04,0x26, +0x01,0x2c,0x00,0x01,0x0b,0xcd,0x08,0x0c,0x20,0x00,0x01,0x0f,0xcd,0x05,0x0c,0x84, +0x34,0x09,0xcd,0x05,0x99,0x44,0x88,0x09,0xe0,0x13,0xcd,0x06,0x87,0x14,0xcd,0x04, +0x3c,0x0f,0xcd,0x05,0xa5,0x4c,0xcd,0x07,0x88,0x2c,0x05,0xc0,0x02,0xd0,0x2b,0x80, +0x09,0x20,0x07,0x04,0x26,0x01,0xcc,0x00,0x01,0xe0,0x03,0x20,0x14,0xcd,0x04,0x14, +0xe0,0x2d,0xcd,0x07,0x14,0xb8,0xcd,0x04,0x14,0x24,0x14,0xf0,0x2f,0xa8,0xcd,0x05, +0x81,0x30,0x18,0x08,0xcd,0x06,0x83,0x38,0x00,0x40,0x84,0x29,0x01,0x28,0xcd,0x07, +0x99,0x04,0x60,0xb0,0x08,0xc4,0x40,0x84,0x09,0x82,0x08,0x30,0x09,0x42,0x40,0x84, +0x09,0xc6,0x08,0x30,0x09,0x8c,0x61,0xb0,0x08,0xfc,0x05,0x80,0x02,0xb4,0x66,0xb0, +0x08,0xb4,0x66,0x30,0x08,0xcd,0x05,0xab,0x60,0xcd,0x05,0x3c,0x2c,0x14,0x00,0x48, +0xcd,0x0b,0x3c,0x58,0xac,0x08,0xc4,0x48,0xcd,0x04,0x3c,0x2c,0x09,0x42,0x48,0xcd, +0x04,0x3c,0x2c,0x09,0x8c,0x59,0xac,0x08,0x0c,0x06,0xcd,0x07,0x9a,0x70,0x58,0x2c, +0x08,0x7a,0x67,0x30,0x08,0xe0,0x53,0x04,0x34,0x01,0x58,0xcd,0x06,0x34,0x70,0x56, +0xcd,0x06,0x83,0x5c,0x30,0x00,0x20,0x1b,0x90,0xcd,0x04,0x0c,0x1c,0x00,0x01,0x20, +0x00,0x20,0x1b,0x60,0x57,0x04,0xcd,0x05,0x8f,0x14,0x18,0x00,0x20,0xcd,0x09,0x87, +0x5c,0xcd,0x04,0x78,0xe8,0x00,0x04,0x1b,0xc8,0x42,0x00,0x09,0xc1,0x05,0xc0,0x02, +0xe0,0x03,0x20,0x14,0x60,0x55,0x30,0x09,0x30,0x66,0x30,0x08,0x25,0x06,0x80,0x02, +0xfc,0x67,0xb0,0x08,0x30,0x66,0xb0,0x08,0xfc,0xcd,0x04,0x64,0xcd,0x07,0x83,0x7c, +0xcd,0x05,0x81,0x64,0x5b,0xcd,0x06,0x0c,0x1c,0x08,0xcd,0x06,0x83,0x50,0xcd,0x06, +0x8d,0x50,0xa0,0x09,0x80,0xf8,0x85,0x34,0x04,0xa4,0xcd,0x0a,0xad,0x40,0x0c,0xcd, +0x04,0x2c,0x43,0x0c,0x34,0x00,0x40,0x00,0x09,0x02,0x14,0x00,0x01,0x8c,0x01,0x80, +0x08,0xe6,0x04,0x00,0x08,0x3c,0x06,0x80,0x02,0x20,0x04,0x00,0x08,0xe6,0x04,0x80, +0x08,0x20,0x04,0xcd,0x06,0x83,0x60,0xcd,0x04,0x2c,0xcd,0x08,0x81,0x10,0x0c,0x00, +0x04,0x1b,0xc0,0x08,0xcd,0x0a,0x81,0x14,0xcd,0x08,0x64,0x15,0x10,0xcd,0x07,0x8d, +0x3c,0x29,0x80,0x09,0x59,0xcd,0x08,0x90,0x50,0xec,0xcd,0x06,0x70,0xfc,0xcd,0x0b, +0x90,0x50,0x23,0xcd,0x37,0x90,0x50,0xcd,0x08,0x10,0xcd,0x08,0x84,0x5c,0xc4,0xcd, +0x0f,0x8d,0x14,0xcd,0x08,0x85,0x64,0xc6,0x00,0xcd,0x0a,0x87,0x6c,0x00,0x48,0x00, +0x0e,0xcd,0x04,0x0c,0xd4,0xcd,0x0d,0x20,0xcd,0x12,0x86,0x04,0x98,0x0c,0x04,0x1b, +0x10,0x48,0x88,0x34,0x09,0x0c,0x00,0x01,0x84,0x00,0x00,0x08,0xcd,0x18,0x8d,0x20, +0xcd,0x08,0x81,0x04,0x01,0x40,0xcd,0x06,0x93,0x00,0xcd,0x04,0x1c,0x4a,0xcd,0x0b, +0x81,0x04,0xf0,0x43,0xa4,0x14,0x14,0x4e,0x10,0x0b,0x90,0x0f,0xcd,0x06,0x8e,0x1c, +0x40,0x0c,0x04,0x1b,0x40,0x08,0x24,0x14,0x01,0x48,0x80,0x1a,0xcd,0x10,0x90,0x3c, +0xb6,0x0d,0xcd,0x06,0x8c,0x54,0xcc,0x24,0x00,0x1b,0x80,0x00,0x08,0x1b,0xc0,0x11, +0x04,0x09,0xd0,0x13,0x04,0x09,0xe0,0x15,0x04,0x09,0xf0,0x17,0xcd,0x06,0x8b,0x70, +0xd0,0xcd,0x07,0x8e,0x00,0xcd,0x04,0x1c,0x10,0xf2,0x05,0xcd,0x05,0x14,0x01,0x00, +0xa4,0x0e,0x60,0x06,0xcd,0x06,0x3c,0xcd,0x0a,0x81,0x04,0xcd,0x0a,0x81,0x2c,0x01, +0x00,0xa0,0x0e,0xc8,0xcd,0x07,0x38,0x00,0x41,0xcd,0x06,0x48,0x18,0xcd,0x05,0x8e, +0x54,0xcd,0x06,0x86,0x6c,0x1a,0xcd,0x08,0x0c,0x20,0x00,0x01,0x1b,0xcd,0x08,0x0c, +0xcd,0x08,0xa0,0x30,0x80,0x20,0x1b,0xbc,0x06,0x80,0x02,0x1b,0x00,0x24,0x1b,0x00, +0x40,0x20,0x1b,0x3b,0x00,0x24,0xcd,0x09,0x87,0x58,0xc0,0x00,0xcd,0x05,0x8c,0x28, +0xcd,0x05,0x0c,0xd0,0x00,0x04,0x1b,0xbc,0x09,0xc0,0x02,0x80,0x00,0x10,0x1b,0x2d, +0xcd,0x07,0x08,0x63,0xcd,0x07,0x08,0xcd,0x04,0x04,0xfc,0x09,0xc0,0x02,0x00,0x00, +0x0c,0x1b,0x3f,0x0a,0xcd,0x06,0x14,0x94,0xcd,0x07,0x81,0x10,0x04,0x08,0xc0,0x02, +0xc0,0x08,0x90,0x09,0xcd,0x08,0x81,0x58,0x07,0x09,0xc0,0x02,0xdc,0x0b,0x90,0xcd, +0x05,0x8e,0x24,0xcd,0x07,0x90,0x00,0x29,0x01,0x48,0x00,0x01,0x1b,0x00,0x08,0x1b, +0x80,0x10,0x88,0x34,0x04,0xcd,0x07,0xa0,0x18,0x81,0xcd,0x07,0x81,0x70,0x0f,0xcd, +0x05,0x90,0x48,0x00,0x00,0xa8,0x23,0xcd,0x06,0x90,0x58,0xb1,0x0a,0xc0,0x02,0xee, +0x05,0xa0,0x09,0x88,0x24,0x08,0x1b,0x5a,0x0b,0xc0,0x02,0x20,0x00,0xa0,0x0e,0xcd, +0x10,0x8e,0x24,0xcd,0x09,0x82,0x0c,0x09,0xcd,0x0e,0x92,0x4c,0xcd,0x08,0x81,0x14, +0xc0,0x08,0x88,0x09,0x50,0x16,0x0c,0x26,0x01,0xa0,0xcd,0x05,0x95,0x28,0xcd,0x05, +0x6c,0x0e,0x00,0x20,0x1b,0x22,0x12,0x00,0x1b,0x41,0x00,0x80,0x1b,0xd0,0x00,0xc0, +0x02,0xb4,0x05,0x04,0x1b,0x7a,0xff,0x00,0xcd,0x05,0x0c,0xc8,0x04,0x04,0x1b,0xf4, +0x21,0x80,0x19,0xcd,0x08,0x95,0x28,0x00,0xf8,0xcd,0x06,0x95,0x1c,0xd9,0x00,0xc0, +0x02,0xa8,0x04,0x04,0x1b,0x40,0x00,0x88,0x29,0x01,0xcd,0x06,0x95,0x74,0xcd,0x05, +0x14,0x6c,0x05,0x04,0x1b,0x54,0x06,0x28,0x0b,0x6c,0x56,0x28,0x0b,0xcd,0x04,0x10, +0x70,0x05,0x04,0x1b,0xf0,0x06,0xac,0xcd,0x05,0x89,0x14,0x54,0x05,0x04,0x1b,0xa0, +0x06,0xb0,0x09,0x20,0x5f,0x04,0x26,0x02,0xcd,0x07,0x83,0x04,0xcd,0x05,0x88,0x30, +0x14,0xcd,0x06,0x40,0xe0,0x5b,0x04,0x34,0x08,0x50,0x04,0x16,0x02,0x00,0x01,0xcd, +0x06,0xb3,0x38,0x08,0x8c,0x34,0x09,0xf4,0x00,0x01,0x6c,0x02,0x04,0x1b,0x10,0x60, +0x80,0x34,0x05,0xec,0x02,0x01,0x76,0x02,0x08,0x1b,0x20,0x60,0x80,0x34,0x09,0xe0, +0xcd,0x06,0xa5,0x64,0xe4,0x07,0xc0,0x02,0x05,0x00,0x18,0x1b,0x00,0x24,0x04,0x1b, +0xf4,0x00,0x84,0xcd,0x05,0x85,0x58,0xc0,0xea,0x04,0x1b,0x05,0x38,0x00,0x01,0x21, +0x01,0xcd,0x06,0x10,0x09,0xcd,0x07,0x98,0x1c,0xe0,0x43,0x08,0x34,0x60,0xe3,0x04, +0x1b,0x05,0x1c,0x00,0x01,0x16,0xcd,0x04,0x2c,0x40,0x88,0xcd,0x09,0xa5,0x34,0xd1, +0x07,0x80,0xcd,0x05,0x82,0x08,0xe0,0x4b,0x08,0x34,0x00,0x09,0x04,0x1b,0x05,0x3c, +0x00,0x01,0x3d,0xcd,0x07,0x50,0x40,0x42,0x04,0x1b,0xcd,0x04,0x44,0x0f,0xcd,0x07, +0x34,0x40,0x54,0xcd,0x06,0x44,0x89,0xcd,0x13,0x44,0x05,0x00,0x20,0xcd,0x05,0xb1, +0x04,0x9a,0x03,0xcd,0x06,0x82,0x4c,0xa8,0x05,0x04,0x1b,0xcd,0x08,0x81,0x24,0xcd, +0x04,0x5c,0xc0,0xe1,0x04,0x1b,0x05,0x24,0x02,0x01,0xe4,0xcd,0x0b,0x81,0x2c,0x09, +0x14,0x02,0xcd,0x05,0x81,0x2c,0xcd,0x04,0x40,0x0b,0x00,0x20,0x1b,0x20,0x5f,0x04, +0x26,0x00,0xb0,0x08,0x1b,0x04,0x00,0x88,0x1b,0x02,0xf8,0x01,0x01,0x08,0x50,0x04, +0x16,0x20,0x08,0x8c,0x34,0x05,0xec,0x01,0x01,0x08,0xcd,0x08,0x82,0x0c,0xe0,0x01, +0x01,0x12,0xcd,0x08,0x82,0x0c,0xd4,0xcd,0x06,0xb7,0x60,0x81,0x06,0xc0,0x02,0x0c, +0x00,0x20,0x1b,0x42,0x86,0x00,0x1b,0x89,0xcd,0x0b,0x83,0x4c,0xd9,0x00,0xc0,0x02, +0xb0,0x05,0x04,0x1b,0xe0,0x03,0x28,0x14,0xc0,0xcd,0x07,0x87,0x40,0xcd,0x04,0x10, +0x00,0x00,0x20,0xcd,0x05,0xb3,0x64,0xcd,0x08,0x83,0x5c,0xcd,0x04,0x28,0xa4,0x05, +0x04,0x1b,0x98,0x03,0x84,0x09,0x10,0x0e,0x00,0x26,0x02,0x10,0x00,0x01,0x05,0x00, +0x08,0x1b,0x87,0x07,0x80,0x02,0xf0,0x43,0x20,0x14,0x20,0x08,0x00,0xcd,0x05,0x92, +0x28,0xcd,0x05,0x8f,0x78,0x43,0x20,0x14,0x00,0xc8,0xcd,0x06,0x84,0x0c,0xe0,0x53, +0xcd,0x06,0x86,0x28,0xcd,0x04,0x54,0xf0,0x00,0x04,0x1b,0x10,0x40,0x80,0x34,0x05, +0xcd,0x0b,0x82,0x14,0x0c,0x00,0x20,0x1b,0x81,0x06,0xc0,0x02,0x0d,0xcd,0x05,0x82, +0x1c,0xcd,0x26,0x74,0xa4,0xcd,0x3f,0x74,0xcd,0x04,0x6c,0xcd,0x04,0x74,0x03,0xcd, +0x07,0x90,0x10,0xb4,0xcd,0x07,0x82,0x00,0x22,0x12,0x00,0x1b,0x81,0xcd,0x0b,0x82, +0x1c,0xcd,0x18,0x85,0x5c,0x9c,0x05,0x04,0x1b,0x00,0x04,0xcd,0x06,0x97,0x44,0xc4, +0xcd,0x04,0x28,0x03,0x04,0x0b,0x0c,0x0e,0x24,0x0b,0x08,0x48,0x24,0x16,0xcd,0x08, +0x7c,0xcd,0x04,0x40,0x00,0x05,0xcd,0x06,0x7c,0x40,0x42,0x04,0x1b,0x05,0x4c,0xcd, +0x07,0x84,0x24,0x48,0x80,0xcd,0x05,0x8a,0x5c,0x01,0x00,0x20,0x1b,0x03,0xcd,0x07, +0x81,0x08,0xcd,0x28,0x87,0x50,0xec,0xcd,0x07,0x8e,0x50,0xc8,0xcd,0x07,0x96,0x40, +0x00,0xf1,0x05,0x09,0xcd,0x08,0x96,0x30,0x20,0x08,0x80,0x1a,0x00,0xcd,0x05,0x82, +0x44,0x24,0x1b,0x1f,0xcd,0x07,0xac,0x40,0xcd,0x0a,0x81,0x1c,0x14,0xcd,0x05,0x86, +0x70,0xc8,0x05,0x04,0x1b,0xf0,0x33,0x0c,0x26,0xcd,0x04,0x14,0x01,0x18,0x00,0x01, +0x0c,0x0e,0x00,0x0b,0xcd,0x08,0x81,0x60,0xcd,0x09,0x81,0x68,0x28,0x0c,0x14,0x00, +0x28,0x90,0x14,0x08,0x18,0x0c,0x16,0x08,0x20,0x10,0x16,0x30,0x40,0x20,0x14,0x00, +0xb4,0xbf,0x01,0x40,0x48,0x24,0x14,0xfb,0xff,0x01,0x1b,0x04,0x40,0x20,0x0b,0x00, +0x00,0x00,0x03,0x04,0x48,0x24,0x0b,0x04,0x08,0xc0,0x02,0xd0,0x2b,0x90,0xcd,0x05, +0x8d,0x20,0xcd,0x05,0x82,0x78,0x23,0x7c,0x14,0x0a,0x00,0x10,0x1b,0xf0,0x21,0x8c, +0x34,0x94,0x24,0x00,0x1b,0x04,0xe4,0x00,0x01,0xf4,0xfb,0x08,0x0b,0x00,0xf8,0x80, +0x1a,0x00,0x0c,0x00,0x1b,0x20,0x00,0x00,0x14,0x04,0x00,0x14,0xcd,0x05,0x94,0x58, +0x00,0x04,0x04,0x1b,0xc0,0x29,0x84,0x09,0xd0,0x2b,0x88,0x09,0x80,0x08,0x00,0x09, +0x88,0x11,0xcd,0x06,0xb7,0x28,0xcd,0x04,0x18,0x80,0xf8,0x84,0x29,0x01,0xa0,0x00, +0x01,0xc0,0x0d,0x14,0x1b,0xcc,0x00,0x08,0x1b,0x20,0x28,0x0c,0x14,0x00,0x18,0x2c, +0xcd,0x05,0x38,0x14,0x04,0x04,0x1b,0x05,0x00,0x24,0x1b,0xf0,0x49,0x84,0x34,0x04, +0x28,0xcd,0x06,0x91,0x6c,0x84,0x40,0x20,0x08,0x54,0x00,0x00,0x1b,0x64,0x00,0x08, +0x1b,0x00,0x28,0x04,0x14,0xcd,0x05,0x30,0x08,0x24,0x0e,0x33,0x08,0x80,0x02,0x00, +0x18,0x28,0x0e,0x84,0x40,0xa0,0x08,0x1f,0x28,0x24,0x1b,0x18,0x00,0x28,0xcd,0x05, +0x83,0x70,0x64,0x05,0x04,0x1b,0xa0,0x5e,0x84,0x09,0x10,0x0e,0x84,0x14,0xa0,0x0e, +0x00,0x09,0xe0,0x03,0x2c,0x14,0xcd,0x08,0x8b,0x5c,0xcd,0x04,0x60,0xcd,0x08,0x8b, +0x5c,0x54,0xcd,0x04,0x0c,0xcd,0x07,0x83,0x50,0x64,0xcd,0x04,0x0c,0xcd,0x07,0x90, +0x50,0xcd,0x04,0x40,0x00,0x00,0x00,0x03,0x21,0xcd,0x07,0x93,0x04,0x22,0x00,0x00, +0xcd,0x09,0x8b,0x58,0xc0,0x08,0xcd,0x0e,0x8a,0x5c,0xcd,0x04,0x70,0xd4,0xcd,0x05, +0x84,0x60,0x2c,0xcd,0x05,0x96,0x28,0xd8,0x05,0x04,0x1b,0x57,0x08,0x80,0x02,0xcd, +0x08,0x96,0x38,0xdc,0xcd,0x0b,0x1c,0xe0,0xcd,0x0b,0x1c,0xd0,0x2b,0xfc,0x09,0x10, +0xfe,0x0c,0x26,0x01,0x38,0x00,0x01,0x00,0x00,0x25,0x1b,0xc0,0xcd,0x04,0x0c,0x2c, +0x00,0x01,0xf0,0xff,0x25,0x1b,0x05,0x00,0x10,0x1b,0x40,0xf8,0x0c,0xcd,0x05,0x96, +0x28,0xcd,0x04,0x1c,0xe0,0xcd,0x04,0x1c,0x28,0xcd,0x06,0x1c,0xcd,0x08,0x8b,0x6c, +0x94,0x58,0x00,0x0b,0xff,0x07,0x04,0x1b,0x78,0x08,0xc0,0x02,0x10,0x00,0x00,0x04, +0x75,0xcd,0x05,0x58,0x20,0x14,0x94,0x60,0xcd,0x06,0x18,0x10,0x00,0x20,0x04,0x2c, +0x0c,0x04,0x1b,0x00,0x08,0x00,0x0e,0xc0,0x03,0x88,0x09,0xf0,0x13,0x88,0x14,0x24, +0x40,0x20,0x0b,0xcd,0x09,0x81,0x3c,0x47,0x00,0x09,0x20,0x0c,0x04,0x1b,0x28,0x0c, +0x0c,0x1b,0xe0,0x8f,0x89,0x09,0xc0,0x9b,0x91,0x09,0x2f,0x00,0x00,0x10,0x23,0x00, +0x80,0x17,0x04,0x06,0x00,0xcd,0x05,0x84,0x04,0x40,0x00,0x00,0x14,0xcd,0x0e,0x44, +0xb0,0xcd,0x05,0x81,0x48,0x18,0x06,0x04,0x1b,0x00,0x02,0xa8,0x09,0xa0,0xcd,0x07, +0x8b,0x5c,0x1c,0x06,0x04,0x1b,0x40,0x02,0xa0,0x09,0xa0,0x06,0xa4,0x09,0xd0,0x2b, +0xfc,0x09,0xe0,0xfb,0x0c,0x34,0x01,0xe0,0x00,0x01,0xe0,0x43,0x14,0x14,0x01,0xcd, +0x08,0x81,0x4c,0x4c,0x00,0x01,0x02,0xcd,0x08,0x0c,0x48,0x00,0x01,0x03,0xcd,0x0b, +0x18,0x04,0xcd,0x08,0x0c,0xac,0x00,0x01,0xe0,0x4b,0x14,0x14,0xcd,0x09,0x82,0x00, +0x9c,0x00,0x01,0xc4,0x58,0x14,0x0b,0x06,0xcd,0x08,0x10,0xcd,0x07,0xc0,0x1c,0xcd, +0x08,0x82,0x04,0x78,0x08,0xc0,0x02,0xe0,0x53,0x00,0x14,0xc7,0xcd,0x05,0x81,0x7c, +0xcd,0x06,0xc1,0x20,0x00,0x06,0x04,0x1b,0x00,0x05,0x84,0x09,0x1f,0x40,0x00,0x10, +0x43,0x00,0x84,0x17,0xcd,0x05,0x82,0x20,0x50,0xcd,0x0a,0x24,0x74,0x4e,0x20,0xcd, +0x05,0x86,0x2c,0x04,0x06,0x04,0x1b,0xcd,0x08,0xa5,0x14,0x4b,0x14,0xc0,0x02,0xc0, +0x03,0xa4,0x09,0xcd,0x08,0xb4,0x10,0x80,0x58,0xcd,0x06,0x4c,0xd8,0xcd,0x05,0x8d, +0x34,0x84,0x09,0x10,0x28,0x88,0x34,0x05,0xcd,0x07,0x89,0x08,0xe0,0x0b,0x14,0x14, +0xc4,0x28,0x14,0xcd,0x0a,0x82,0x48,0x2f,0x00,0x09,0xcd,0x14,0x82,0x24,0x20,0xcd, +0x07,0x82,0x24,0xcd,0x04,0x0c,0x24,0x06,0x04,0x1b,0x80,0x02,0xcd,0x06,0x88,0x50, +0xe0,0x05,0xcd,0x04,0x0c,0xa4,0xcd,0x05,0x82,0x3c,0xcd,0x09,0x82,0x2c,0x98,0xcd, +0x06,0x82,0x2c,0xf0,0xfb,0x0c,0x26,0x01,0x50,0xcd,0x0b,0x82,0x28,0x4c,0xcd,0x0b, +0x82,0x28,0x50,0xcd,0x0a,0x82,0x28,0x90,0x58,0x90,0x14,0x01,0x64,0x00,0x01,0x04, +0x26,0x14,0x0b,0xcd,0x09,0x82,0x2c,0x54,0x00,0x01,0xc4,0x48,0xcd,0x0e,0x82,0x2c, +0xc4,0x58,0x14,0x0b,0xcd,0x10,0x82,0x2c,0x00,0x09,0xcd,0x0a,0x82,0x2c,0x0c,0xcd, +0x07,0x82,0x2c,0x04,0x46,0x08,0x0b,0x1f,0x10,0xcd,0x0e,0x82,0x30,0xcd,0x04,0x24, +0xcd,0x0c,0x81,0x64,0x07,0x09,0xcd,0x0e,0x88,0x0c,0xc0,0x26,0x88,0x34,0x09,0x64, +0x00,0x01,0xe0,0x23,0x20,0x14,0xcd,0x08,0x91,0x64,0xdc,0x23,0xcd,0x06,0x93,0x04, +0xcd,0x04,0x5c,0x10,0x06,0x04,0x1b,0xe0,0x43,0x04,0x34,0xcd,0x08,0xac,0x4c,0xf0, +0x43,0xcd,0x08,0x92,0x7c,0x80,0x08,0x01,0x00,0x04,0x1b,0x1d,0x09,0x80,0x02,0xcc, +0x09,0x00,0x09,0x02,0xcd,0x0b,0x0c,0x00,0xcd,0x07,0x95,0x50,0xcd,0x04,0x3c,0xcd, +0x10,0x87,0x00,0xcd,0x09,0x64,0x0b,0xcd,0x0e,0x87,0x00,0x2d,0xcd,0x0b,0x81,0x18, +0xcd,0x04,0x18,0xcc,0xcd,0x08,0x87,0x28,0x21,0x04,0x09,0xe0,0x0d,0xa4,0x29,0xcd, +0x05,0x94,0x48,0x10,0x00,0x01,0xc4,0x26,0x10,0x0b,0x4b,0x14,0xc0,0x02,0x07,0x47, +0x20,0x1b,0xc8,0x24,0x0c,0x1b,0xcd,0x05,0xbe,0x34,0x11,0xa8,0x09,0x03,0x00,0x08, +0x1b,0x20,0x50,0x88,0x34,0x80,0x20,0xa4,0x14,0x04,0x18,0x00,0x01,0x0a,0xcd,0x05, +0x10,0x08,0x26,0x01,0xcd,0x08,0x83,0x70,0x23,0x24,0x14,0x80,0x03,0x04,0x1b,0x10, +0x48,0xa4,0x14,0xe0,0x4b,0x24,0x34,0x04,0x20,0x00,0x01,0x00,0xf8,0x21,0x1b,0xff, +0x07,0x20,0x1b,0x80,0x48,0x88,0x34,0x04,0xcd,0x07,0xa2,0x74,0xff,0x07,0x24,0x1b, +0x52,0x09,0x80,0x02,0x90,0x40,0x88,0x34,0xff,0x0f,0x20,0x1b,0x04,0x0c,0x00,0x01, +0x80,0x48,0x24,0x04,0x00,0x08,0x24,0xcd,0x05,0x89,0x14,0x08,0x05,0x04,0x1b,0xc0, +0x4a,0xcd,0x06,0x8a,0x04,0xcd,0x04,0x0c,0xcd,0x08,0x94,0x08,0xcd,0x09,0x81,0x30, +0xcd,0x0f,0x93,0x34,0x63,0xcd,0x17,0x81,0x58,0xd0,0x23,0x04,0xcd,0x05,0xa3,0x08, +0xc8,0x24,0x0c,0xcd,0x05,0xac,0x5c,0xcd,0x10,0x81,0x48,0x1f,0x3b,0x14,0x1b,0x01, +0x00,0x94,0x1b,0x6d,0xbc,0x24,0x1b,0x01,0x00,0xa4,0x1b,0x04,0x68,0xcd,0x06,0x9e, +0x60,0x20,0x50,0x08,0x26,0x7d,0x23,0xcd,0x06,0x1c,0x18,0x9b,0xcd,0x06,0x1c,0x01, +0x4c,0xcd,0x07,0x9d,0x10,0x50,0x08,0x26,0xc2,0x52,0xcd,0x06,0x1c,0xc1,0xdd,0xcd, +0x07,0x1c,0x30,0x00,0x01,0x16,0x00,0x08,0x1b,0xa0,0x10,0x88,0x34,0x00,0x80,0xcd, +0x06,0x1c,0x00,0x80,0x24,0x1b,0x04,0x18,0x00,0x01,0xcd,0x04,0x20,0x59,0x39,0xcd, +0x06,0x14,0xed,0xb9,0xcd,0x06,0x30,0x5f,0x20,0x00,0x10,0x23,0x00,0x94,0x17,0x9f, +0xcd,0x05,0x08,0xa4,0x17,0x5f,0x40,0x00,0x10,0x23,0x02,0x94,0x17,0x9f,0xcd,0x05, +0x08,0xfc,0x17,0xd9,0x00,0xc0,0x02,0x8c,0xcd,0x05,0x85,0x7c,0x80,0x29,0xcd,0x08, +0x8f,0x54,0x01,0x00,0x00,0x1b,0xe0,0x2b,0x20,0x14,0x4b,0x14,0xc0,0x02,0xe0,0x03, +0x24,0x14,0xe0,0x43,0x04,0x14,0xe0,0xfb,0xcd,0x0b,0x10,0x0b,0x24,0x14,0xff,0x03, +0x00,0x1b,0x00,0x40,0x84,0xcd,0x09,0xb8,0x4c,0xff,0x03,0x20,0x1b,0x00,0x48,0xcd, +0x0c,0x10,0xcd,0x06,0x82,0x60,0x80,0x05,0x04,0x1b,0x40,0x42,0x00,0x09,0x60,0x4e, +0xcd,0x06,0x82,0x64,0xcd,0x04,0x10,0xcd,0x10,0x82,0x64,0xd0,0xcd,0x0f,0x84,0x3c, +0xbc,0xcd,0x17,0x82,0x64,0xe0,0x25,0x04,0xcd,0x19,0x82,0x60,0xd6,0x0b,0x24,0x1b, +0x04,0x38,0xcd,0x0a,0x82,0x54,0xf4,0x0a,0x24,0x1b,0x01,0x28,0xcd,0x0a,0x84,0x38, +0xcd,0x05,0x10,0x18,0xcd,0x0a,0x82,0x3c,0x04,0x0c,0x00,0x01,0xbb,0x0b,0x24,0x1b, +0xc6,0x0b,0x24,0x1b,0x9f,0x20,0x00,0x10,0x03,0x00,0xa0,0xcd,0x05,0x82,0x0c,0x34, +0x04,0x04,0x1b,0x40,0xcd,0x0f,0x82,0x0c,0xcd,0x08,0x81,0x78,0xff,0x0f,0xcd,0x0f, +0x81,0x74,0x0f,0xcd,0x06,0x91,0x48,0x0c,0x05,0x04,0x1b,0xc0,0x42,0xcd,0x06,0x81, +0x60,0xcd,0x04,0x0c,0xcd,0x0a,0x81,0x58,0x94,0xcd,0x05,0x86,0x08,0xc0,0x09,0x90, +0xcd,0x05,0x84,0x38,0xe0,0x2b,0x10,0xcd,0x09,0xc7,0x04,0xcd,0x09,0x81,0x54,0x0d, +0xcd,0x10,0xaa,0x60,0x90,0x09,0xfc,0x09,0xc0,0x02,0x20,0x2c,0xcd,0x06,0x9d,0x00, +0xcd,0x04,0x1c,0xe0,0x23,0x30,0xcd,0x05,0x87,0x4c,0xe0,0x1b,0x24,0x34,0xcd,0x08, +0x86,0x44,0x10,0x4a,0xcd,0x06,0x87,0x54,0x80,0x00,0x08,0x1b,0x40,0x10,0x90,0x14, +0x01,0x0c,0x00,0x01,0xff,0xff,0x09,0x1b,0xfe,0xff,0x09,0x1b,0x2c,0x20,0xcd,0x06, +0x90,0x78,0x54,0x04,0x04,0x1b,0x50,0x02,0xa0,0x09,0xc8,0x24,0x04,0x1b,0x0e,0x00, +0x28,0xcd,0x05,0xa6,0x24,0x00,0x11,0xac,0x09,0xa0,0x58,0x84,0x34,0x04,0x48,0x00, +0x01,0x16,0x00,0x28,0x1b,0xb0,0x50,0x84,0xcd,0x05,0x99,0x64,0x10,0x00,0x28,0x1b, +0xa0,0x60,0xcd,0x06,0xb2,0x00,0x70,0xcd,0x07,0x0c,0x05,0x14,0x00,0x01,0x90,0xcd, +0x08,0x18,0xcd,0x07,0x98,0x1c,0x03,0x00,0x20,0x1b,0x23,0x0a,0xcd,0x08,0xca,0x50, +0x20,0x1b,0x50,0x42,0x00,0x09,0xce,0x49,0x00,0x09,0xe0,0x2d,0xcd,0x06,0x82,0x00, +0xcd,0x04,0x74,0xcd,0x09,0x9a,0x4c,0xcd,0x0b,0x86,0x44,0x10,0x0a,0x8c,0xcd,0x06, +0xa6,0x48,0x13,0xcd,0x07,0xa3,0x44,0x1d,0x00,0x09,0xc8,0x24,0x00,0x1b,0x04,0xcd, +0x05,0xc9,0x64,0xcd,0x06,0x9a,0x1c,0x20,0x18,0x90,0x34,0x04,0xcd,0x05,0xa8,0x70, +0x00,0x00,0x3f,0x0a,0xcd,0x0e,0x84,0x04,0xcd,0x04,0x08,0x2c,0xcd,0x0b,0x84,0x0c, +0xf0,0x27,0x04,0x09,0x7f,0x00,0x14,0x1b,0x50,0x20,0x8c,0x34,0x80,0x00,0x08,0xcd, +0x05,0x84,0x14,0x08,0x0c,0x00,0x01,0x20,0x20,0x80,0x14,0x20,0x20,0xcd,0x06,0x90, +0x30,0x84,0xcd,0x13,0x84,0x6c,0xf0,0x0f,0xcd,0x12,0x90,0x28,0xcd,0x06,0x9a,0x10, +0xcd,0x06,0x8c,0x08,0xcd,0x06,0x9a,0x40,0xa4,0x09,0x0f,0xcd,0x05,0x9d,0x18,0xa0, +0xcd,0x05,0x8a,0x6c,0xd0,0x4b,0xcd,0x07,0x81,0x34,0x45,0xcd,0x12,0x30,0xcd,0x06, +0x9a,0x40,0xa4,0x09,0x08,0x00,0x10,0x1b,0x80,0x20,0xcd,0x08,0xbf,0x0c,0x14,0x1b, +0xe0,0x4b,0xcd,0x0b,0x8b,0x28,0x2d,0xcd,0x06,0x38,0xcd,0x04,0x2c,0xcd,0x08,0x8c, +0x70,0xcd,0x06,0x44,0xa4,0xcd,0x09,0x74,0xc6,0x00,0xa8,0xcd,0x05,0x44,0x90,0x20, +0x90,0x34,0x14,0x00,0x10,0x1b,0x04,0xb4,0xcd,0x06,0x48,0x40,0x40,0x90,0x34,0x04, +0xa8,0x00,0x01,0x04,0x00,0x14,0x1b,0xf0,0x53,0x90,0x34,0x02,0x9c,0xcd,0x06,0x18, +0xcd,0x04,0x38,0xcc,0x05,0x04,0x1b,0x40,0x01,0xcd,0x06,0x50,0xcd,0x04,0x0c,0x50, +0x03,0xcd,0x06,0x50,0x88,0x05,0x04,0x1b,0xde,0x03,0xa8,0x09,0xe0,0x43,0x10,0x34, +0x01,0x00,0x10,0x1b,0x01,0x68,0x00,0x01,0x01,0xcd,0x04,0x4c,0x50,0x10,0x26,0x0c, +0xcd,0x04,0x10,0x58,0xcd,0x07,0x10,0x48,0x90,0xcd,0x05,0x20,0x04,0x48,0xcd,0x07, +0x10,0x40,0x10,0x26,0x02,0xcd,0x04,0x20,0x38,0x00,0x01,0x02,0xcd,0x07,0x10,0x03, +0xcd,0x04,0x10,0x28,0xcd,0x0a,0x10,0x04,0xcd,0x04,0x10,0x18,0x00,0x01,0x03,0xcd, +0x07,0x10,0x01,0x0c,0xcd,0x06,0x0c,0xcd,0x04,0x40,0xcd,0x09,0x81,0x70,0x2b,0xcd, +0x06,0xaa,0x20,0x10,0xf8,0x89,0x34,0x04,0x90,0xcd,0x06,0x9c,0x48,0xb1,0x0a,0xc0, +0x02,0xe0,0x0b,0xcd,0x0a,0xa3,0x2c,0xd9,0x00,0xc0,0x02,0xec,0x05,0x04,0x1b,0xa4, +0x44,0xcd,0x06,0x84,0x38,0xcd,0x04,0x0c,0xa8,0x23,0x00,0x1b,0xac,0x23,0x04,0xcd, +0x06,0xb9,0x70,0x00,0x8c,0x0e,0xee,0x45,0x08,0x09,0xee,0x45,0x0c,0x09,0x00,0x10, +0x80,0xcd,0x05,0xcf,0x18,0x10,0x18,0x80,0x1a,0xcd,0x08,0x97,0x28,0xee,0x05,0x84, +0xcd,0x0a,0x83,0x48,0x0b,0xcd,0x0a,0xa8,0x10,0xc4,0x00,0x80,0x08,0xca,0xcd,0x13, +0xa3,0x14,0x46,0xcd,0x0f,0xa8,0x78,0xfc,0xcd,0x05,0xa2,0x54,0xcd,0x0a,0xa4,0x60, +0xcd,0x04,0x10,0xcd,0x08,0x18,0x42,0x00,0x80,0x08,0x62,0xcd,0x0f,0x18,0x00,0x04, +0x04,0x1b,0x78,0x07,0xcd,0x06,0x14,0xcd,0x04,0x0c,0xcd,0x05,0x8e,0x4c,0x04,0xcd, +0x05,0x8a,0x38,0xcd,0x06,0x8e,0x1c,0x04,0x04,0x1b,0x8c,0x24,0x00,0x1b,0x0f,0xcd, +0x08,0xa3,0x2c,0xcd,0x07,0x8e,0x70,0xcd,0x06,0x38,0xcd,0x06,0x8e,0x40,0xcd,0x08, +0x38,0xcd,0x06,0x64,0x00,0x08,0x62,0x04,0xcd,0x06,0x18,0xcd,0x0c,0x7c,0x00,0x00, +0x00,0x08,0x20,0xcd,0x0f,0x18,0xcd,0x14,0x81,0x40,0xcd,0x06,0x81,0x6c,0x00,0x08, +0xca,0xcd,0x0b,0xa2,0x78,0xcd,0x0a,0x81,0x14,0xcd,0x07,0x8f,0x30,0xcd,0x07,0x81, +0x14,0x01,0xcd,0x0f,0x81,0x14,0x14,0x04,0x04,0x1b,0xc8,0x24,0x08,0x1b,0x18,0x00, +0x10,0xcd,0x06,0x99,0x50,0x09,0x8c,0x09,0x30,0x20,0x04,0x26,0x00,0x00,0x08,0x1b, +0x01,0x3c,0x00,0x01,0x1a,0x00,0x10,0x1b,0xcd,0x04,0x10,0x01,0x30,0x00,0x01,0x1b, +0xcd,0x08,0x0c,0xcd,0x07,0x8e,0x50,0x8c,0x24,0x08,0x1b,0x01,0x00,0x0c,0x1b,0x20, +0x00,0x90,0x0e,0xcd,0x05,0x18,0x0c,0x00,0x01,0x02,0xcd,0x05,0xba,0x44,0x08,0x1b, +0x9a,0x13,0xcd,0x06,0x83,0x4c,0xcd,0x04,0x60,0xcd,0x0a,0xa2,0x50,0x84,0x09,0xf0, +0x0b,0x08,0xcd,0x05,0x96,0x28,0xcd,0x04,0x38,0x10,0x0e,0xcd,0x06,0xb8,0x08,0x02, +0xcd,0x04,0x44,0x0f,0x08,0xcd,0x05,0x92,0x4c,0xcd,0x04,0x28,0x8f,0xcd,0x07,0x91, +0x40,0xcd,0x0a,0x82,0x44,0x88,0x0e,0x01,0x18,0x80,0x1a,0xcd,0x05,0x9c,0x6c,0xcd, +0x07,0x9c,0x44,0xea,0x0a,0xcd,0x06,0x9b,0x2c,0xcd,0x06,0x81,0x54,0x8c,0x0e,0xcd, +0x05,0x9b,0x3c,0x18,0x80,0x1a,0x48,0xcd,0x07,0x3c,0xc5,0xcd,0x07,0x20,0xcd,0x08, +0x84,0x64,0xcd,0x04,0x28,0x00,0x00,0x84,0x0e,0xcd,0x0c,0x84,0x28,0xd0,0x2a,0x84, +0x09,0x10,0xf8,0x91,0x34,0x04,0xf8,0x00,0x01,0xd8,0xcd,0x05,0xb6,0x24,0x10,0x35, +0x04,0xec,0xcd,0x06,0x60,0x5a,0x0b,0xc0,0x02,0xe0,0x2b,0xcd,0x0e,0x85,0x24,0xe8, +0x05,0x04,0x1b,0x10,0x42,0x84,0x29,0x88,0xf1,0x01,0x09,0xcd,0x05,0x82,0x20,0xcd, +0x05,0x81,0x0c,0x0c,0x1b,0xd8,0x43,0x88,0x09,0xe0,0x47,0x8c,0x09,0x00,0x08,0x00, +0x09,0xc2,0x10,0x00,0x09,0xd0,0x1d,0x00,0x09,0x88,0x24,0x10,0x1b,0x40,0x00,0xa0, +0x0e,0x10,0x0a,0x20,0x09,0xd8,0x13,0x20,0x09,0xe0,0x1f,0x20,0x09,0x40,0x40,0x80, +0x1a,0xcd,0x05,0xad,0x14,0xcd,0x0b,0x89,0x0c,0xcd,0x08,0xb5,0x14,0x10,0x02,0x84, +0x29,0xcd,0x0d,0x54,0x03,0x88,0x09,0xe0,0x07,0xcd,0x06,0x8a,0x28,0xd8,0x13,0x00, +0x09,0xe0,0x1f,0xcd,0x06,0x88,0x78,0xd0,0x0a,0xcd,0x0b,0x86,0x50,0x40,0xcd,0x06, +0x81,0x2c,0x85,0x0b,0xcd,0x12,0x86,0x50,0x1c,0x07,0x04,0x1b,0x00,0x40,0xcd,0x06, +0x83,0x04,0xcd,0x04,0x0c,0x88,0xcd,0x07,0xbd,0x7c,0x00,0x40,0xcd,0x06,0xd2,0x60, +0x00,0xcd,0x07,0xb1,0x70,0x22,0x00,0x00,0x1b,0xcd,0x08,0x81,0x04,0x00,0x00,0xcd, +0x0e,0x86,0x48,0xcd,0x05,0x68,0x0e,0x08,0x35,0x04,0xd8,0xcd,0x06,0xaa,0x38,0x9f, +0xcd,0x13,0x68,0xec,0x05,0x04,0x1b,0xcd,0x05,0x94,0x38,0xcd,0x05,0x81,0x38,0x08, +0x1b,0xa8,0xcd,0x05,0xaf,0x34,0x0c,0x14,0xcd,0x05,0xc9,0x5c,0x00,0x0c,0x1b,0xac, +0x15,0x00,0x09,0x68,0x1d,0xcd,0x0a,0x87,0x58,0xcd,0x08,0x81,0x78,0xb2,0xcd,0x07, +0x9e,0x6c,0xcd,0x0c,0xb7,0x5c,0xcd,0x04,0x20,0xac,0x05,0x84,0x09,0xf0,0x0b,0x0c, +0xcd,0x09,0xbc,0x14,0xbb,0x0b,0x80,0x02,0x68,0x05,0x88,0x09,0xcd,0x04,0x50,0xcd, +0x08,0x94,0x6c,0xd0,0x13,0x00,0x09,0x2a,0xcd,0x09,0xbe,0x00,0x80,0xcd,0x05,0xbd, +0x78,0x0f,0x08,0x80,0x10,0xcd,0x0d,0xce,0x18,0xcd,0x08,0xcd,0x60,0xcd,0x0d,0xc6, +0x3c,0xfc,0xcd,0x17,0xcc,0x50,0xcd,0x22,0xcc,0x4c,0xcd,0x0c,0xbd,0x04,0x08,0x00, +0x00,0x1b,0x4a,0x04,0x04,0x1b,0xe0,0x0f,0x00,0x09,0x77,0x04,0x04,0xcd,0x05,0xdb, +0x60,0x09,0x00,0x00,0xcd,0x05,0x10,0x9f,0xcd,0x07,0x10,0x10,0xcd,0x07,0x10,0xd7, +0xcd,0x07,0x10,0x11,0xcd,0x07,0x10,0xfd,0xcd,0x07,0x10,0x12,0xcd,0x07,0x10,0x18, +0x05,0xcd,0x06,0x10,0x13,0xcd,0x07,0x10,0x0e,0xcd,0x07,0x10,0x14,0xcd,0x07,0x10, +0x23,0xcd,0x07,0x10,0x15,0xcd,0x07,0x10,0x41,0xcd,0x07,0x10,0x16,0xcd,0x07,0x10, +0x55,0xcd,0x07,0x10,0x17,0xcd,0x07,0x10,0x61,0xcd,0x07,0x10,0x18,0xcd,0x07,0x10, +0xb9,0xcd,0x07,0x10,0x19,0xcd,0x07,0x10,0x79,0xcd,0x07,0x81,0x00,0x1a,0xcd,0x07, +0x10,0x89,0xcd,0x07,0x10,0x1b,0xcd,0x07,0x10,0x99,0xcd,0x07,0x10,0x1c,0xcd,0x07, +0x10,0xe2,0xcd,0x07,0x40,0x28,0xcd,0x07,0x10,0x2d,0x06,0xcd,0x06,0x10,0x29,0xcd, +0x07,0x10,0xcd,0x05,0x8b,0x0c,0x02,0x80,0x1a,0xcd,0x0c,0xae,0x54,0x32,0x00,0x00, +0x1b,0x5e,0x06,0xcd,0x06,0x82,0x20,0x7f,0xcd,0x07,0x30,0x33,0xcd,0x08,0x82,0x10, +0xcd,0x07,0x10,0x34,0xcd,0x07,0x10,0xec,0xcd,0x07,0x10,0x35,0xcd,0x07,0x10,0xf2, +0xcd,0x07,0x10,0x36,0xcd,0x08,0x60,0x08,0xcd,0x06,0x10,0x37,0xcd,0x07,0x10,0x43, +0xcd,0x07,0x10,0x38,0xcd,0x07,0x10,0x49,0xcd,0x07,0x10,0x39,0xcd,0x07,0x10,0x81, +0xcd,0x07,0x10,0x3a,0xcd,0x07,0x10,0x50,0xcd,0x07,0x10,0x3b,0xcd,0x07,0x10,0xca, +0xcd,0x07,0x10,0x3c,0xcd,0x07,0x10,0x03,0x09,0xcd,0x06,0x10,0x41,0xcd,0x08,0x82, +0x70,0xcd,0x07,0x10,0x42,0xcd,0x07,0x10,0x29,0xcd,0x07,0x10,0x43,0xcd,0x07,0x10, +0x59,0xcd,0x07,0x10,0x44,0xcd,0x07,0x10,0x5f,0xcd,0x07,0x10,0x45,0xcd,0x07,0x10, +0xb2,0xcd,0x07,0x10,0x46,0xcd,0x07,0x10,0xb8,0xcd,0x07,0x10,0x47,0xcd,0x07,0x10, +0xf1,0xcd,0x07,0x10,0x48,0xcd,0x07,0x10,0xf7,0xcd,0x07,0x10,0x49,0xcd,0x07,0x10, +0x2a,0x0a,0xcd,0x06,0x10,0x4a,0xcd,0x07,0x10,0x32,0xcd,0x07,0x10,0x4b,0xcd,0x07, +0x10,0x4d,0xcd,0x07,0x10,0x4c,0xcd,0x07,0x10,0x53,0xcd,0x07,0x10,0x4d,0xcd,0x08, +0x81,0x10,0xcd,0x07,0x10,0x4e,0xcd,0x07,0x10,0x6d,0xcd,0x07,0x10,0x4f,0xcd,0x07, +0x10,0xa9,0xcd,0x07,0x10,0x50,0xcd,0x07,0x10,0xbf,0xcd,0x07,0x10,0x51,0xcd,0x07, +0x10,0x2b,0x0b,0xcd,0x06,0x10,0x52,0xcd,0x07,0x10,0x4a,0xcd,0x07,0x10,0x53,0xcd, +0x07,0x10,0x4f,0xcd,0x07,0x10,0x54,0xcd,0x07,0x10,0x70,0xcd,0x07,0x10,0x55,0xcd, +0x07,0x10,0x7d,0xcd,0x07,0x10,0x56,0xcd,0x07,0x10,0x91,0xcd,0x07,0x10,0x57,0xcd, +0x07,0x10,0x97,0xcd,0x07,0x10,0x58,0xcd,0x07,0x10,0xae,0xcd,0x07,0x10,0x59,0xcd, +0x0f,0x84,0x50,0x80,0xcd,0x0b,0x84,0x50,0x63,0x0e,0x00,0x1b,0xf0,0x0e,0x80,0xcd, +0x05,0x28,0x90,0x0e,0x00,0x1b,0xf4,0xcd,0x07,0x0c,0xb9,0xcd,0x0b,0x0c,0x27,0x0f, +0x00,0x1b,0x43,0x0f,0xcd,0x06,0x0c,0x53,0x0f,0x00,0x1b,0x8b,0xcd,0x07,0x0c,0x9c, +0x0f,0x00,0x1b,0xf6,0xcd,0x07,0x0c,0x6f,0xcd,0x0b,0x18,0xba,0xcd,0x07,0x18,0xcd, +0x08,0x70,0x30,0xcd,0x0b,0x70,0xd9,0x0d,0x00,0xcd,0x05,0x24,0xdf,0xcd,0x07,0x08, +0xe5,0xcd,0x07,0x08,0xeb,0xcd,0x07,0x08,0xf1,0xcd,0x07,0x08,0xf7,0xcd,0x07,0x08, +0xfd,0xcd,0x07,0x08,0x03,0x0e,0xcd,0x06,0x08,0x09,0xcd,0x07,0x08,0x0f,0xcd,0x07, +0x08,0x15,0xcd,0x07,0x08,0x1b,0xcd,0x07,0x08,0x21,0xcd,0x07,0x08,0x27,0xcd,0x07, +0x08,0x2d,0xcd,0x07,0x08,0x33,0xcd,0x07,0x08,0x39,0xcd,0x07,0x08,0x3f,0x0e,0xcd, +0x06,0x89,0x70,0xcd,0x05,0x81,0x78,0x47,0xcd,0x0a,0x81,0x20,0x34,0xcd,0x07,0x70, +0xcd,0x08,0x08,0x3e,0xcd,0x07,0x08,0x48,0xcd,0x07,0x08,0x52,0xcd,0x08,0x08,0xcd, +0x10,0x10,0xcd,0x17,0x18,0x5c,0xcd,0x07,0x08,0x66,0xcd,0x07,0x08,0x70,0xcd,0x07, +0x08,0x7a,0xcd,0x08,0x08,0xcd,0x10,0x10,0xcd,0x20,0x20,0xcd,0x0f,0x10,0x84,0xcd, +0x07,0x08,0x8e,0xcd,0x07,0x08,0x98,0xcd,0x07,0x08,0xa2,0xcd,0x07,0x08,0xac,0x0d, +0xcd,0x0a,0x81,0x68,0x60,0xe4,0x20,0x1b,0xc0,0x0d,0x00,0x1b,0xe4,0x00,0xc0,0x02, +0x40,0x01,0x24,0x1b,0x24,0xf5,0x20,0x1b,0x20,0x0c,0xcd,0x06,0x10,0x10,0x00,0x24, +0xcd,0x09,0x8c,0x40,0xa0,0xe5,0xcd,0x0e,0x28,0x34,0xcd,0x17,0x28,0xe0,0xe6,0xcd, +0x26,0x50,0x20,0xe8,0xcd,0x0e,0x28,0x44,0xcd,0x17,0x28,0x60,0xe9,0xcd,0x0e,0x28, +0x54,0xcd,0x18,0x81,0x20,0xea,0xcd,0x0e,0x28,0x64,0xcd,0x18,0x81,0x20,0xeb,0xcd, +0x26,0x78,0x20,0xed,0xcd,0x27,0x81,0x20,0xee,0xcd,0x27,0x82,0x40,0xef,0xcd,0x0e, +0x28,0x74,0xcd,0x18,0x81,0x20,0xf0,0xcd,0x0e,0x28,0x84,0xcd,0x18,0x81,0x20,0xf2, +0xcd,0x0e,0x28,0x94,0xcd,0x18,0x81,0x20,0xf3,0xcd,0x0e,0x28,0xa4,0xcd,0x17,0x28, +0xcd,0x09,0xe0,0x04,0xcd,0x08,0xdf,0x4c,0xcd,0x08,0xe0,0x0c,0xcd,0x07,0xdf,0x54, +0xc0,0x05,0x85,0xcd,0x09,0xea,0x48,0x01,0x15,0x85,0x19,0x00,0x18,0x81,0x19,0x02, +0x18,0x83,0x19,0x4f,0x20,0x80,0x19,0x00,0x08,0x01,0xcd,0x05,0xba,0x68,0x00,0x18, +0x05,0x0e,0xcd,0x08,0xe6,0x04,0xcd,0x08,0x90,0x60,0x94,0xcd,0x07,0x97,0x24,0xcd, +0x04,0x0c,0xcd,0x0d,0xde,0x30,0xcd,0x08,0xdd,0x78,0xcd,0x08,0xde,0x38,0x00,0x81, +0xcd,0x05,0xe7,0x10,0xcd,0x04,0x3c,0xdc,0xe1,0x20,0x1b,0x80,0x0a,0xcd,0x06,0x81, +0x24,0x84,0xcd,0x0b,0x81,0x24,0xf8,0xd4,0xcd,0x16,0x18,0x00,0xd6,0xcd,0x16,0x18, +0x08,0xd7,0xcd,0x16,0x18,0x10,0xd8,0xcd,0x16,0x18,0x94,0xcd,0x17,0x18,0x18,0xd9, +0xcd,0x16,0x18,0x9c,0xcd,0x17,0x18,0x20,0xda,0xcd,0x16,0x18,0xa4,0xcd,0x17,0x18, +0x28,0xdb,0xcd,0x16,0x18,0xac,0xcd,0x17,0x18,0xb4,0xdc,0xcd,0x16,0x18,0xbc,0xdd, +0xcd,0x16,0x18,0xc4,0xde,0xcd,0x16,0x18,0xcc,0xdf,0xcd,0x16,0x18,0xd4,0xe0,0xcd, +0x16,0x18,0xe4,0xe2,0xcd,0x17,0x83,0x00,0xcd,0x1f,0x84,0x3c,0x80,0x02,0xcd,0x0a, +0x84,0x3c,0x31,0x12,0xcd,0x0a,0x84,0x3c,0x20,0xcd,0x17,0x84,0x3c,0xcd,0x28,0x84, +0x28,0xcd,0x08,0xcf,0x68,0x40,0x01,0xcd,0x06,0xcf,0x68,0xcd,0x08,0x95,0x44,0xcd, +0x0c,0xe8,0x40,0xaa,0xff,0x00,0x1b,0x21,0x46,0x80,0x1b,0x30,0x00,0x80,0x1a,0xb0, +0x23,0x0c,0xcd,0x09,0xe8,0x04,0x30,0x08,0x80,0x1a,0xb8,0xcd,0x04,0x10,0x00,0x08, +0x1b,0x00,0x50,0x88,0x1b,0x30,0x10,0x80,0x1a,0xc4,0xcd,0x08,0x30,0x56,0xcd,0x06, +0x30,0xb4,0xcd,0x04,0x20,0xcd,0x07,0xe8,0x10,0xcd,0x04,0x30,0xbc,0xcd,0x0f,0x30, +0xcd,0x06,0xd5,0x60,0x84,0x0e,0xa8,0x0d,0x04,0x08,0x28,0x0d,0xcd,0x06,0xd5,0x64, +0xca,0xcd,0x07,0xcc,0x4c,0xcd,0x06,0xd8,0x3c,0x84,0x0e,0xce,0x09,0xcd,0x06,0x18, +0xcd,0x07,0x81,0x14,0xcd,0x05,0xba,0x0c,0xcd,0x45,0x81,0x34,0x60,0xcd,0x2f,0x81, +0x34,0xcd,0x07,0x30,0xcd,0x0c,0x81,0x34,0x6a,0xcd,0x0f,0x81,0x34,0xcd,0x29,0x81, +0x24,0xcd,0x0b,0x44,0xac,0xcd,0x17,0x44,0xcd,0x08,0x24,0xc2,0x08,0xcd,0x06,0xd0, +0x7c,0xa8,0xcd,0x04,0x10,0x04,0xcd,0x06,0xd7,0x7c,0xcd,0x05,0xf0,0x40,0xcd,0x04, +0x10,0x08,0x80,0x1a,0xb0,0xcd,0x07,0x08,0xb4,0xcd,0x07,0x08,0xc4,0xcd,0x07,0x08, +0x90,0xcd,0x07,0x08,0xb8,0x24,0x00,0x1b,0x42,0x08,0x84,0x08,0x50,0x0a,0xcd,0x06, +0x48,0x72,0x14,0xcd,0x06,0x68,0x40,0xfc,0x00,0x1b,0xd0,0x82,0x85,0xcd,0x09,0xd3, +0x78,0xcd,0x08,0xde,0x10,0xcd,0x08,0xda,0x20,0xcd,0x08,0xdc,0x24,0xcd,0x08,0xd9, +0x0c,0xcd,0x08,0x81,0x3c,0xcd,0x08,0xd0,0x28,0xcd,0x08,0x10,0xcd,0x04,0x48,0x50, +0x83,0xcd,0x0a,0xd4,0x54,0x03,0xcd,0x07,0xd5,0x14,0x04,0x00,0x00,0x1b,0xcd,0x04, +0x08,0x05,0xcd,0x07,0x08,0x00,0xcd,0x07,0x08,0x02,0xcd,0x07,0x08,0x01,0xcd,0x07, +0x08,0x03,0x00,0x00,0xcd,0x0a,0xb8,0x48,0xcd,0x07,0xbb,0x0c,0xcd,0x08,0xd5,0x18, +0x50,0x0b,0xcd,0x0a,0xd5,0x18,0xcd,0x10,0x82,0x54,0x02,0xcd,0x07,0xa6,0x6c,0xcd, +0x08,0xd1,0x4c,0xa8,0x0d,0xcd,0x06,0xd5,0x10,0xcd,0x08,0x81,0x18,0x01,0x00,0x80, +0x1a,0xcd,0x0c,0xbc,0x14,0x0c,0xcd,0x05,0xd7,0x6c,0x08,0x14,0x01,0x00,0x80,0x0e, +0x20,0x00,0x04,0x24,0x02,0x0c,0x00,0x01,0xff,0xcd,0x07,0x83,0x2c,0xcd,0x10,0x86, +0x10,0xd4,0x02,0xcd,0x1e,0x83,0x38,0xee,0xcd,0x07,0x83,0x34,0xc4,0xff,0x00,0x1b, +0x00,0xa8,0xcd,0x07,0xef,0x04,0x20,0x84,0x1b,0x00,0x03,0xcd,0x0a,0xef,0x04,0xa6, +0xcd,0x04,0x1c,0xba,0x80,0x1b,0x00,0x03,0xcd,0x0f,0xee,0x10,0x50,0xcd,0x09,0xee, +0x10,0xcd,0x05,0x82,0x00,0x0a,0xcd,0x07,0x08,0x0b,0xcd,0x0b,0x84,0x38,0xcd,0x08, +0x81,0x00,0xcd,0x10,0x81,0x64,0xee,0xcd,0x0f,0x81,0x64,0xcd,0x08,0x30,0x50,0xcd, +0x1f,0x81,0x30,0x30,0x0e,0xcd,0x0a,0x81,0x30,0x20,0x88,0xcd,0x07,0x81,0x30,0x60, +0x84,0x1b,0x80,0x02,0xcd,0x0f,0x81,0x30,0x98,0x80,0x1b,0x80,0x02,0xcd,0x19,0xef, +0x40,0xcd,0x09,0x81,0x20,0xcd,0x20,0x70,0xb4,0xcd,0x27,0x70,0x20,0x9a,0xcd,0x13, +0x70,0x60,0xcd,0x0e,0x82,0x20,0x08,0xcd,0x07,0x08,0x09,0xcd,0x13,0x81,0x00,0x02, +0x1c,0xcd,0x0e,0x82,0x20,0x30,0x0e,0x04,0x08,0xb4,0xcd,0x07,0xd9,0x18,0xcd,0x10, +0x82,0x24,0xcc,0xcd,0x1f,0x87,0x0c,0x36,0x0f,0x04,0x08,0x72,0x0e,0xcd,0x04,0x04, +0xcd,0x0b,0x83,0x5c,0x68,0xcd,0x07,0x81,0x3c,0x30,0x84,0x1b,0x00,0xcd,0x10,0x81, +0x3c,0x7a,0x80,0x1b,0x00,0xcd,0x1b,0x81,0x3c,0xcd,0x30,0x78,0xcd,0x0c,0x82,0x34, +0xcd,0x09,0x78,0x80,0xcd,0x12,0x78,0x00,0x78,0xcd,0x13,0x78,0x40,0xcd,0x3a,0x78, +0x38,0x0f,0xcd,0x3b,0x78,0x20,0xcd,0x0e,0x83,0x2c,0x06,0xcd,0x07,0x08,0x07,0xcd, +0x13,0x81,0x08,0xcd,0x10,0x83,0x2c,0xcd,0x08,0x81,0x00,0xcd,0x10,0x87,0x34,0xcd, +0x08,0xdf,0x40,0x60,0xcd,0x06,0xdd,0x3c,0xcd,0x07,0x81,0x3b,0xcd,0x0a,0xfc,0x6c, +0xcd,0x0d,0xa2,0x24,0xcd,0x07,0x38,0xcd,0x0a,0xfc,0x44,0x7c,0x14,0xcd,0x09,0xf4, +0x18,0xcd,0x23,0xf4,0x0c,0x21,0x00,0x40,0x1b,0xc0,0x29,0x80,0x09,0xc3,0xcd,0x08, +0xdf,0x58,0x34,0x00,0x01,0xc4,0xcd,0x08,0x0c,0xc8,0x02,0x01,0xc5,0xcd,0x08,0x0c, +0xf4,0x01,0x01,0xc6,0xcd,0x08,0x0c,0x14,0x04,0xcd,0x05,0x81,0x08,0x5e,0x11,0xcd, +0x0a,0xce,0x50,0x1c,0x06,0x04,0x1b,0x6b,0x11,0xc0,0x02,0xe0,0x03,0x3c,0x14,0xd0, +0x2c,0xd0,0x29,0x01,0x78,0x00,0x01,0x20,0x00,0x08,0x1b,0xe0,0xcb,0x0c,0x14,0x7c, +0xcd,0x04,0x18,0xa3,0x00,0x14,0x89,0xcd,0x05,0x20,0x50,0x14,0xe0,0xfb,0x04,0x34, +0xc0,0xfb,0xd4,0x09,0x02,0x94,0x00,0x01,0xe0,0xff,0xd8,0x09,0x9b,0xcd,0x04,0x18, +0xc3,0x20,0x14,0x40,0xc1,0x88,0x34,0xc0,0x0d,0x20,0x1b,0x1c,0x01,0x00,0x1b,0x00, +0x40,0x04,0x14,0x00,0x08,0x00,0x0e,0xcd,0x05,0xc5,0x00,0x02,0xd4,0x09,0x50,0x10, +0x80,0x02,0x80,0xc9,0x80,0x14,0x40,0xc9,0x80,0x14,0xcf,0x01,0x00,0x10,0x43,0xcd, +0x07,0xbe,0x50,0xcb,0x11,0xc0,0x02,0x00,0xa8,0x54,0x14,0x9a,0xcd,0x08,0xd0,0x3c, +0xcd,0x07,0x40,0x24,0x01,0x08,0xcd,0x05,0x44,0x20,0x40,0x0c,0xcd,0x05,0x48,0x00, +0x18,0x08,0x0e,0xcd,0x04,0x48,0x89,0x11,0xc0,0x02,0x40,0x12,0xd0,0xcd,0x06,0x74, +0xa3,0x20,0x14,0xcd,0x05,0x40,0x00,0x00,0x00,0xcd,0x04,0x40,0x21,0x00,0x40,0x1b, +0xb0,0xa9,0xd4,0x34,0x08,0xcd,0x07,0x84,0x30,0x6e,0xcd,0x05,0x54,0x54,0x1b,0x5f, +0xb9,0xcd,0x04,0x70,0xd4,0x17,0xe0,0xb3,0xcd,0x06,0xe0,0x08,0xcd,0x04,0x1c,0xcd, +0x08,0x81,0x34,0xc2,0xcd,0x0b,0x40,0xcd,0x05,0xa4,0x74,0xb1,0xd8,0xcd,0x09,0x40, +0x7e,0xcd,0x05,0x14,0x58,0x1b,0x6f,0xcd,0x05,0x40,0xd8,0x17,0x50,0xb1,0xd8,0x14, +0xf0,0xb3,0x88,0xcd,0x09,0x20,0x01,0x00,0x58,0x1b,0x2c,0x00,0x40,0xcd,0x05,0x82, +0x40,0xd4,0xcd,0x05,0xb1,0x08,0x8c,0x09,0x80,0x02,0x84,0x09,0x10,0x18,0x8c,0x14, +0x20,0x00,0x08,0x1b,0xcf,0x11,0xcd,0x04,0x38,0x88,0x17,0xcd,0x05,0x82,0x40,0xb3, +0x00,0x14,0xe0,0x03,0x58,0x14,0xcf,0xa1,0xcd,0x06,0xbc,0x50,0x60,0x09,0x84,0xcd, +0x09,0xc7,0x1c,0x71,0x10,0x80,0x02,0xcd,0x04,0x48,0xa3,0x11,0xc0,0x02,0x74,0xb6, +0x20,0x0b,0xcd,0x08,0x81,0x14,0xcd,0x09,0xbc,0x30,0x03,0x20,0xcd,0x0b,0xbf,0x44, +0x88,0x09,0xc0,0x11,0xcd,0x06,0xab,0x78,0xc6,0x40,0x80,0x08,0xc6,0x40,0xcd,0x0a, +0xbc,0x1c,0x40,0x7a,0x84,0x09,0xe0,0x83,0x00,0x14,0x5e,0x11,0x80,0x02,0xd0,0x0c, +0xcd,0x06,0xaf,0x14,0x24,0xcd,0x10,0x83,0x58,0x48,0x00,0x01,0x40,0x00,0x08,0x1b, +0xf4,0xcb,0x0c,0x0b,0xcd,0x08,0x83,0x58,0x95,0xcd,0x0b,0x83,0x58,0x02,0x60,0x00, +0x01,0xc0,0xfb,0xd4,0x09,0xc0,0x0d,0x20,0x1b,0x20,0xcd,0x0b,0x83,0x48,0xdc,0x11, +0xc0,0x02,0x00,0x02,0xd4,0x09,0xd8,0xcd,0x0b,0x83,0x28,0xcd,0x04,0x20,0x3c,0xcd, +0x17,0x83,0x28,0xcd,0x04,0x54,0x80,0x12,0xd0,0x09,0xcd,0x05,0x38,0x00,0x00,0x00, +0xcd,0x04,0x38,0xcd,0x10,0x83,0x20,0xd6,0xcd,0x0f,0x83,0x20,0xd2,0xcd,0x07,0x2c, +0x80,0xcd,0x13,0x81,0x48,0x1c,0xcd,0x05,0x82,0x08,0x3c,0xcd,0x09,0xc2,0x78,0xe0, +0x07,0xdc,0x09,0xc0,0x03,0xe0,0x09,0x80,0xf1,0xe5,0xcd,0x06,0x81,0x58,0x58,0x00, +0x01,0xfc,0xff,0x05,0x1b,0xe0,0xbb,0x0c,0x14,0x14,0x18,0x08,0xcd,0x09,0x81,0x5c, +0x8f,0xcd,0x10,0x85,0x34,0x74,0xcd,0x06,0x85,0x34,0xad,0x11,0xc0,0x02,0xf4,0xbb, +0x24,0x0b,0xcd,0x10,0x85,0x30,0x08,0x12,0xc0,0x02,0xa0,0x06,0xd4,0x09,0x31,0x11, +0xcd,0x22,0x85,0x10,0xcd,0x04,0x28,0xcd,0x04,0x60,0xa0,0x16,0xd0,0x09,0xe0,0xbb, +0x50,0x14,0xcd,0x08,0x54,0xcd,0x04,0x44,0xcd,0x04,0x3c,0xcd,0x04,0x44,0x21,0x00, +0x40,0x1b,0xe0,0xb3,0x04,0x34,0xf0,0xcb,0x08,0x14,0x24,0xa8,0x54,0x0b,0x02,0x20, +0x00,0x01,0x24,0xb0,0x58,0x0b,0xcd,0x08,0x2c,0xf9,0xcd,0x07,0x81,0x74,0xcd,0x08, +0x70,0xcd,0x1c,0x84,0x64,0xcd,0x06,0xc2,0x78,0xcd,0x0a,0x84,0x64,0xfc,0xff,0x05, +0x1b,0x14,0xb8,0xcd,0x07,0x81,0x6c,0xcd,0x07,0x84,0x60,0xf4,0xa3,0x08,0x0b,0x60, +0x11,0xcd,0x0a,0x84,0x5c,0x11,0x11,0xcd,0x06,0x84,0x5c,0xcd,0x04,0x70,0xe0,0xb3, +0x24,0x14,0xcd,0x08,0x70,0xa0,0x7e,0xcd,0x0e,0x82,0x64,0xc0,0x0d,0x20,0x1b,0x0c, +0xcd,0x09,0x82,0x08,0x58,0x0e,0x80,0xb2,0xdc,0x09,0xa0,0xb6,0xe8,0xcd,0x0b,0xc3, +0x44,0xcd,0x06,0x82,0x6c,0x70,0xd1,0xbc,0xcd,0x05,0x82,0x70,0xf4,0xa3,0x50,0x0b, +0x01,0x34,0xcd,0x06,0xb0,0x7c,0xe0,0x7b,0xcd,0x0a,0x88,0x24,0xcd,0x0c,0x82,0x6c, +0xf0,0xcb,0x08,0x14,0x02,0x1c,0x00,0x01,0x24,0xa8,0x54,0x0b,0x54,0x11,0x80,0x02, +0x40,0xd1,0xd4,0x14,0xe0,0x7b,0x50,0x14,0xcd,0x04,0x0c,0xe0,0xbb,0x54,0x14,0x0f, +0xcd,0x07,0x82,0x28,0x40,0xa9,0x0c,0x14,0xa0,0x1e,0x58,0x09,0x80,0xaa,0x58,0x09, +0xe0,0xb3,0xcd,0x06,0xb8,0x3c,0xe0,0x05,0x04,0x1b,0xe0,0x83,0x00,0x14,0x04,0xa6, +0x04,0x0b,0xcd,0x08,0x81,0x24,0xcd,0x26,0xf9,0x58,0xcd,0x06,0xf9,0x4c,0xcd,0x08, +0xad,0x64,0x20,0x0c,0x04,0x1b,0x24,0x0c,0x0c,0xcd,0x05,0x81,0x44,0x00,0x18,0x08, +0x0e,0xc0,0x03,0xdc,0x09,0xc0,0x13,0xe0,0x09,0xe0,0x17,0xe4,0x09,0x28,0xcd,0x09, +0x84,0x4c,0xe8,0x09,0xc0,0x03,0xec,0x09,0xc0,0x0d,0x04,0x1b,0x28,0x01,0x08,0x1b, +0x20,0x08,0x0c,0x14,0x00,0x18,0xcd,0x06,0x81,0x84,0x60,0x00,0x05,0xf0,0xcd,0x05, +0xf0,0x38,0x05,0xcd,0x08,0xd3,0x1c,0x13,0x00,0x14,0x87,0xcd,0x07,0x82,0x54,0x30, +0x00,0xcd,0x0a,0x82,0x68,0xe0,0x1b,0x00,0x14,0xcd,0x04,0x14,0xcd,0x09,0x94,0x54, +0xa2,0x3c,0x09,0xe0,0x7b,0xcd,0x07,0xdb,0x08,0xcd,0x07,0xc3,0x38,0xcd,0x05,0x82, +0x78,0xa6,0xcd,0x16,0x18,0x80,0xcd,0x0b,0x30,0x24,0xcd,0x0b,0x18,0x40,0x41,0x84, +0x34,0x05,0x28,0x00,0x01,0xe0,0xe3,0x24,0x14,0x40,0xc1,0x84,0x34,0x05,0xcd,0x07, +0x8d,0x04,0x9f,0x40,0xcd,0x06,0xbe,0x34,0xcd,0x05,0xbe,0x1c,0xa3,0x24,0x14,0x00, +0x45,0xcd,0x06,0xb8,0x7c,0xcd,0x05,0x88,0x24,0x4d,0xcd,0x07,0xcc,0x54,0xcd,0x07, +0x48,0xe0,0x4b,0x7c,0x14,0xf4,0xa3,0x0c,0x0b,0xcd,0x04,0x08,0x90,0x18,0x84,0x34, +0xc0,0x0d,0x04,0x1b,0x2c,0xcd,0x05,0x81,0x68,0xcd,0x06,0x85,0x74,0x09,0x1c,0x00, +0x01,0xc0,0x03,0xa0,0x09,0x8f,0x18,0xcd,0x0a,0x54,0xcd,0x05,0x85,0x7c,0x43,0xcd, +0x06,0xb9,0x5c,0x04,0x06,0x04,0x1b,0xc0,0x43,0xcd,0x06,0x54,0xcd,0x04,0x0c,0xcd, +0x0c,0x8d,0x34,0xd4,0xcd,0x05,0xba,0x54,0x88,0x09,0xa0,0x06,0x8c,0x09,0xff,0xcd, +0x05,0x89,0x5c,0x80,0x17,0x00,0x18,0x8c,0x14,0xe3,0x11,0xc0,0x02,0xff,0x01,0xcd, +0x06,0xb6,0x14,0xcd,0x05,0xca,0x18,0xaa,0xcd,0x07,0x81,0x85,0x10,0xcd,0x0f,0x40, +0xdc,0xcd,0x0b,0x40,0xcd,0x06,0x8a,0x1c,0xcd,0x07,0xca,0x68,0xcd,0x0f,0x44,0xcd, +0x05,0xc8,0x38,0xcd,0x07,0x44,0xcd,0x05,0x0c,0xcd,0x07,0x44,0x30,0x10,0xcd,0x0a, +0xd1,0x64,0xec,0x11,0x80,0x02,0xe0,0x13,0x0c,0x14,0x10,0x18,0x80,0xcd,0x0b,0xc9, +0x18,0x0c,0x14,0x50,0x11,0x80,0xcd,0x0b,0x83,0x40,0x54,0xcd,0x05,0xc0,0x04,0xcd, +0x05,0x83,0x40,0xa8,0xcd,0x0a,0x3c,0xe0,0x1b,0x54,0xcd,0x0d,0x83,0x40,0xcd,0x08, +0x86,0x70,0xcd,0x08,0x81,0x1c,0xf0,0x19,0xcd,0x07,0x81,0x10,0x07,0x04,0x1b,0x20, +0xa8,0x84,0x14,0x00,0x08,0x88,0xcd,0x05,0xfd,0x20,0xcd,0x05,0x3c,0xc3,0x08,0x34, +0x01,0x0c,0x00,0x01,0x80,0xa9,0xcd,0x06,0x44,0xcd,0x08,0x81,0x74,0xa0,0xae,0xcd, +0x12,0x81,0x74,0xe0,0xbb,0x08,0x14,0x40,0xd1,0xcd,0x0a,0x4c,0xcd,0x08,0x18,0xfc, +0xff,0x9d,0x19,0xff,0xff,0x9f,0x19,0xfc,0x3f,0x1c,0x1b,0xff,0x3f,0xcd,0x0a,0x81, +0x90,0x14,0xcd,0x08,0xb6,0x54,0x0e,0x20,0xcd,0x06,0x81,0x89,0x14,0xcd,0x10,0xee, +0x2c,0xff,0xff,0x05,0xcd,0x05,0xeb,0x64,0x03,0xcd,0x05,0xc1,0x08,0xcd,0x06,0xc1, +0x14,0x00,0x00,0x04,0xcd,0x05,0xd9,0x74,0x98,0x24,0x08,0x1b,0x88,0xcd,0x07,0xc3, +0x30,0x20,0x08,0x80,0x1a,0x30,0x08,0x80,0x1a,0xcd,0x22,0xdc,0x6c,0x04,0xcd,0x05, +0x1c,0xcd,0x04,0x10,0xcd,0x06,0xcf,0x5c,0x04,0x1b,0xc0,0xf8,0xcd,0x06,0xdc,0x78, +0xcd,0x09,0x9b,0x50,0xcd,0x07,0xec,0x4c,0xa8,0x23,0x04,0x1b,0xff,0x02,0x00,0x1b, +0x00,0xff,0x80,0xcd,0x07,0xe7,0x3c,0x80,0x1a,0x20,0xcd,0x07,0xf1,0x18,0xcd,0x10, +0xa3,0x78,0xd2,0x0c,0xcd,0x06,0x81,0x38,0xb6,0xcd,0x07,0x08,0xda,0xcd,0x07,0xb5, +0x0c,0xfa,0xcd,0x07,0x10,0x22,0xcd,0x07,0x08,0xcd,0x08,0xe0,0x64,0xd8,0xfb,0x01, +0xcd,0x05,0x82,0x3c,0xcd,0x08,0xe4,0x4c,0x50,0x08,0xcd,0x06,0xbc,0x30,0xcd,0x04, +0x14,0xcd,0x04,0x0c,0xcd,0x08,0xe3,0x50,0xcd,0x09,0x81,0x89,0x58,0x08,0x04,0x1b, +0x03,0x28,0x80,0x19,0x40,0xfc,0x00,0x1b,0xce,0x81,0xcd,0x06,0xf7,0x1c,0x2a,0x01, +0xc0,0xcd,0x05,0xb6,0x34,0xcd,0x14,0xf4,0x68,0xc0,0x24,0x0c,0x1b,0x04,0xcd,0x07, +0xe3,0x48,0x30,0xcd,0x06,0xf5,0x20,0x29,0xcd,0x08,0x81,0x8d,0x40,0x84,0x10,0x08, +0x08,0x30,0x10,0x80,0x1a,0x82,0xcd,0x07,0x81,0x92,0x70,0xcd,0x04,0x20,0x42,0xcd, +0x0b,0x20,0x42,0xcd,0x07,0x20,0xe9,0xcd,0x07,0x86,0x28,0xcd,0x08,0xf8,0x24,0x52, +0x12,0x84,0x29,0xcd,0x08,0xde,0x48,0x52,0x12,0x08,0x08,0xcd,0x05,0x9d,0x28,0x10, +0x80,0x1a,0x98,0xcd,0x07,0x20,0x4a,0x11,0x84,0x29,0x01,0x74,0xcd,0x06,0x44,0x8c, +0xcd,0x04,0x0c,0x68,0xcd,0x06,0x0c,0x8a,0x11,0x08,0x08,0xcd,0x04,0x28,0xcd,0x08, +0x9d,0x18,0xcd,0x06,0xed,0x74,0x88,0x0e,0x10,0x00,0x0c,0x1b,0xf0,0x17,0x84,0x09, +0x10,0x18,0x80,0x34,0x04,0xcd,0x08,0xb7,0x1c,0x04,0xcd,0x06,0xb8,0x10,0xcd,0x08, +0xed,0x10,0xcd,0x08,0xb7,0x14,0x6c,0xcd,0x07,0x81,0x2c,0xc7,0xcd,0x07,0x08,0x68, +0xf6,0x20,0x1b,0x9c,0x30,0x00,0x1b,0xa0,0x13,0xc0,0x02,0x80,0x00,0x24,0x1b,0xe8, +0xf6,0x20,0x1b,0x00,0x25,0x00,0x1b,0xf0,0x13,0xc0,0x02,0xa8,0x00,0x24,0x1b,0xb4, +0xd4,0x20,0x1b,0x30,0x0a,0xcd,0x06,0x20,0x44,0x00,0x24,0x1b,0x68,0xe3,0x20,0x1b, +0x00,0xcd,0x07,0x10,0x18,0x00,0x24,0x1b,0xc0,0xcd,0x04,0x10,0x0d,0xcd,0x06,0x10, +0xa0,0x00,0x24,0x1b,0xa0,0xf4,0x20,0x1b,0x40,0x0c,0xcd,0x06,0x10,0x6c,0x00,0x24, +0x1b,0x0c,0xf5,0x20,0x1b,0x00,0xcd,0x07,0x10,0xcd,0x04,0x30,0xcd,0x0b,0x99,0x2c, +0x00,0xff,0xff,0xff,0xff,0xcd,0x04,0x04,0xcd,0x08,0x08,0xcd,0x10,0x10,0xe0,0x4b, +0x38,0x14,0xe0,0x73,0xfc,0x34,0xff,0x00,0x25,0x1b,0x90,0x40,0x30,0x04,0xc4,0x60, +0xa4,0x0b,0xff,0xff,0x20,0x1b,0x80,0x48,0x20,0x04,0x02,0x10,0x00,0x01,0x80,0x40, +0xbc,0x0b,0x61,0x13,0xcd,0x07,0xd6,0x5c,0x03,0x20,0x14,0xc0,0x46,0x24,0x04,0xe0, +0x4b,0xfc,0x34,0x02,0xc4,0xcd,0x06,0x82,0x04,0x24,0x76,0x20,0x0b,0xc0,0x76,0x24, +0x04,0x00,0x18,0x81,0x19,0x04,0x18,0xc3,0x19,0x00,0x10,0x81,0x18,0xf0,0x43,0xa0, +0x14,0x74,0x46,0x20,0x0b,0x8c,0x46,0x20,0x0b,0x80,0xcd,0x09,0x96,0x78,0x80,0x01, +0xf0,0x18,0x01,0x1a,0xcd,0x04,0x3c,0x01,0xd0,0xcd,0x07,0x81,0x93,0x70,0x10,0x21, +0x18,0x84,0x46,0x28,0x0b,0x40,0x40,0x20,0x08,0xe0,0x47,0x20,0x08,0xa0,0x40,0x04, +0x14,0x40,0x08,0x20,0x08,0x60,0x0c,0x20,0x09,0xc0,0x46,0x84,0x04,0xcd,0x06,0x81, +0x8f,0x0c,0xc3,0x19,0x10,0x00,0x81,0x18,0xf0,0x4b,0xcd,0x0e,0x54,0x94,0x66,0x20, +0x0b,0x00,0x00,0x2d,0x18,0xac,0x46,0x24,0x0b,0x00,0x00,0xcd,0x10,0x48,0x20,0x14, +0x00,0x00,0x28,0x1b,0x01,0x00,0xa8,0x1b,0xa0,0x58,0x28,0x14,0x67,0x14,0xc0,0x02, +0xa0,0x00,0x81,0x18,0x00,0xcc,0xcd,0x06,0x97,0x74,0xcd,0x08,0x81,0x50,0x40,0x00, +0x20,0x08,0x60,0x04,0xcd,0x12,0x6c,0x30,0x4e,0x34,0x15,0xd0,0x70,0xfc,0x34,0x10, +0xcd,0x08,0x89,0x38,0x73,0x34,0x14,0xf0,0x6b,0xcd,0x12,0x81,0x00,0xcd,0x06,0x7c, +0x2c,0x1b,0x00,0x00,0x21,0x18,0x01,0x00,0xac,0x1b,0xcd,0x12,0x81,0x04,0x29,0x18, +0xb0,0x50,0xcd,0x12,0x81,0x00,0xd0,0x70,0xa4,0x14,0x24,0x4e,0x20,0x0b,0xe0,0x43, +0xfc,0x34,0x01,0x40,0x00,0x01,0xc0,0x4e,0x24,0x04,0xcd,0x04,0x2c,0x84,0x56,0x2c, +0x0b,0x40,0x50,0x28,0x08,0xe0,0x57,0x28,0x08,0xb0,0x50,0x04,0x14,0xcd,0x08,0x82, +0x54,0x10,0xcd,0x15,0x82,0x54,0xcd,0x0b,0x82,0x50,0xcd,0x08,0x81,0x83,0x44,0xcd, +0x3f,0x82,0x50,0xcd,0x38,0x81,0x50,0xcd,0x08,0x84,0x70,0xb0,0x3e,0x9c,0x14,0x01, +0x88,0x80,0x1a,0x84,0xd4,0x20,0x1b,0x0c,0xd4,0x44,0x1b,0x00,0x00,0xa0,0x1b,0x00, +0x00,0xc4,0x1b,0x80,0x88,0xfc,0x34,0x10,0xcd,0x07,0x81,0x85,0x60,0xe0,0x8b,0x20, +0x14,0xe0,0x3b,0x00,0x14,0xa0,0x13,0xc0,0x02,0x0c,0x00,0x25,0x1b,0x50,0x3e,0x20, +0x14,0x00,0x40,0x24,0x0e,0x90,0xf0,0xfd,0x34,0x10,0xcd,0x07,0x8b,0x44,0x30,0x3e, +0x28,0x14,0x00,0x38,0x20,0x0e,0xa0,0x13,0xc0,0x02,0x00,0x50,0x00,0x0e,0xb0,0x8e, +0x44,0x14,0xcd,0x04,0x54,0x00,0x00,0xa0,0xcd,0x06,0x4c,0xcd,0x07,0x87,0x00,0x6c, +0xcd,0x07,0x83,0x48,0x84,0xd4,0x44,0x1b,0xa8,0xcd,0x05,0x20,0xc4,0xcd,0x0a,0x24, +0xcd,0x33,0x70,0xf0,0xcd,0x0b,0x70,0xcd,0x06,0x50,0xcd,0x0e,0x70,0x88,0xcd,0x07, +0x70,0x01,0x00,0xc4,0xcd,0x05,0x91,0x10,0xb0,0x3e,0x1c,0x14,0xcd,0x08,0xfc,0x4c, +0x00,0xfc,0x08,0x1b,0x54,0xfc,0x14,0x1b,0x04,0xfc,0x0c,0x1b,0x08,0xfc,0x10,0x1b, +0x00,0x00,0x28,0x1b,0x40,0x00,0xa8,0x1b,0x44,0xfc,0x04,0x1b,0xa0,0x28,0x00,0xcd, +0x06,0x83,0x28,0x04,0xcd,0x07,0x85,0x78,0x40,0x2d,0x1b,0x90,0x58,0xcd,0x0a,0x58, +0xb6,0x13,0x80,0x02,0xb0,0xcd,0x05,0xd3,0x3c,0x2c,0x14,0x00,0x00,0x29,0x1b,0xe0, +0x53,0x24,0x14,0xe0,0x43,0xfc,0x34,0xcd,0x08,0xc3,0x6c,0x94,0xcd,0x07,0x81,0x9c, +0x28,0x2c,0x46,0x28,0x0b,0xa0,0x18,0x00,0x1a,0xe0,0x03,0x28,0x14,0x2c,0x56,0x28, +0x0b,0x00,0x00,0x30,0x1b,0x00,0x10,0xb0,0x1b,0xc0,0x50,0x28,0x14,0xa0,0x20,0x00, +0x1a,0x94,0xfa,0x28,0x1b,0x00,0x00,0xa8,0x1b,0xa0,0x40,0xfc,0x34,0xcd,0x08,0xfc, +0x70,0xf0,0x5b,0xac,0x14,0xff,0x3f,0x29,0x1b,0xa0,0x58,0x28,0x04,0xfc,0x56,0x28, +0x0b,0x44,0x00,0x2c,0x1b,0x00,0xe0,0xac,0x1b,0xb0,0x50,0xa8,0x04,0xd9,0x13,0x80, +0x02,0xa0,0x10,0x00,0x1a,0xcd,0x0e,0x24,0x2c,0x0b,0x04,0x00,0x28,0x1b,0x00,0xe0, +0xa8,0x1b,0xa0,0x58,0xa8,0x04,0xcd,0x04,0x20,0xcd,0x08,0x81,0x4c,0xa0,0x88,0x29, +0x04,0xe0,0x53,0xfc,0x34,0x01,0xf0,0xcd,0x06,0x8a,0x2c,0xcd,0x09,0x18,0x28,0xcd, +0x0e,0x7c,0xcd,0x09,0xa0,0x24,0x40,0x29,0x1b,0xcd,0x05,0x84,0x38,0x40,0x29,0x1b, +0xaa,0xcd,0x04,0x6c,0x00,0x00,0x14,0xcd,0x09,0x81,0x88,0x00,0xcd,0x08,0x9f,0x24, +0xe8,0x80,0x1a,0x54,0xfc,0x04,0x1b,0xe0,0x0b,0x2c,0xcd,0x05,0x87,0x34,0xcd,0x04, +0x50,0x01,0xf0,0x80,0x1a,0xa0,0x58,0xcd,0x07,0x82,0x34,0x3c,0xcd,0x08,0x82,0x34, +0x29,0x1b,0x90,0x50,0xfc,0x34,0x10,0xcd,0x09,0xe7,0x18,0x74,0x14,0x03,0x14,0x80, +0x02,0xa0,0xcd,0x05,0x82,0x38,0x74,0x14,0xcd,0x05,0xdd,0x04,0xcd,0x0b,0x82,0x34, +0x98,0xcd,0x07,0x82,0x34,0xfe,0xff,0x78,0x1b,0xec,0x41,0x78,0x0b,0x04,0xcd,0x05, +0x64,0x28,0x14,0xe0,0x51,0x00,0x1a,0xcd,0x05,0x14,0x01,0x78,0x0b,0x08,0xfc,0x04, +0xcd,0x05,0x83,0x28,0xcd,0x05,0x85,0x74,0x08,0xa8,0x1b,0x00,0x10,0xac,0x1b,0xa0, +0xf0,0xa8,0x04,0xb0,0x50,0x28,0x14,0xe0,0x0b,0x2c,0x14,0xa0,0x58,0x00,0x1a,0xf0, +0xeb,0xf4,0x14,0xff,0x3f,0x78,0x1b,0xe0,0xe9,0x74,0x04,0x07,0x00,0x78,0x1b,0xec, +0xe9,0x74,0x0b,0x04,0x00,0xcd,0x04,0x10,0xf4,0x04,0x98,0xcd,0x0c,0x82,0x70,0xcd, +0x07,0xc8,0x14,0x00,0xfc,0x04,0x1b,0x40,0x00,0x2c,0xcd,0x05,0x6c,0xcd,0x05,0x82, +0x68,0xe8,0xac,0x04,0x31,0x14,0x80,0x02,0xb0,0x50,0x00,0x1a,0xcd,0x06,0x81,0x97, +0x64,0xcd,0x0e,0x1c,0xcd,0x04,0x18,0x44,0xcd,0x07,0x81,0x08,0xcd,0x0d,0x82,0x64, +0xcd,0x07,0xef,0x2c,0x54,0xcd,0x07,0x1c,0xe0,0x0b,0x2c,0x14,0xcd,0x05,0x20,0x58, +0x00,0x1a,0xcd,0x0c,0x78,0xcd,0x14,0x82,0x6c,0xf7,0xcd,0x09,0x82,0x6c,0xcd,0x06, +0x81,0x91,0x04,0xcd,0x09,0x8c,0x10,0x50,0x28,0x18,0xe0,0x43,0x2c,0x34,0x00,0x50, +0x82,0x19,0x10,0x50,0x80,0x19,0x01,0x50,0x80,0x1a,0x00,0x20,0x28,0x18,0x00,0x00, +0x2c,0xcd,0x05,0x8f,0x00,0x1f,0x20,0x80,0x19,0x00,0x40,0x30,0x27,0x20,0x00,0x2c, +0x1b,0xc0,0x58,0xac,0x14,0xf2,0x63,0xb0,0x14,0xb4,0x40,0x20,0x0b,0xcd,0x06,0xc9, +0x70,0x2c,0x1b,0xc0,0x20,0x80,0x18,0x80,0x40,0x20,0x34,0xb8,0x58,0x2c,0x14,0x90, +0x58,0xb0,0x34,0xe8,0x43,0x20,0x14,0x00,0xf0,0xbf,0x01,0x90,0x58,0xac,0x94,0x01, +0x00,0xb0,0x0e,0xa0,0x20,0x80,0x18,0xe0,0x5b,0x24,0xcd,0x05,0x93,0x54,0xc0,0x50, +0x80,0x18,0xf0,0x43,0x28,0x04,0x20,0x46,0x20,0x04,0xf0,0x53,0x28,0x06,0xc4,0x56, +0x28,0x0b,0x04,0x40,0x2c,0x0e,0xa4,0x58,0x2c,0x0b,0xa0,0xf0,0xa9,0x14,0xd0,0x4b, +0x2c,0x09,0xcd,0x04,0x0c,0xcd,0x04,0x2c,0xb4,0x40,0x00,0xcd,0x0e,0x81,0x83,0x14, +0x88,0xcd,0x0e,0x81,0x96,0x5c,0x54,0x28,0x10,0x1b,0x00,0x00,0x45,0x1b,0x38,0x2f, +0x14,0x1b,0xe0,0x23,0x00,0x14,0xe0,0x8b,0x20,0x14,0xd0,0x12,0xc0,0x02,0xd8,0x06, +0x25,0x1b,0xe0,0x2b,0xcd,0x0a,0x10,0xc8,0x00,0x25,0x1b,0x00,0x00,0x21,0x1b,0x00, +0x30,0x00,0x1b,0x00,0x00,0x31,0x1b,0x80,0x00,0x00,0x1a,0xe0,0x63,0x24,0x14,0x30, +0x2f,0x00,0x1b,0x14,0x29,0x00,0x1a,0xcd,0x04,0x10,0x5e,0x06,0x21,0x1b,0x67,0x14, +0xc0,0x02,0x80,0x20,0x20,0x14,0xcd,0x04,0x1c,0x5f,0xcd,0x0f,0x10,0xc9,0xcd,0x0b, +0x10,0xd2,0x06,0x21,0x1b,0xcd,0x04,0x08,0x14,0x41,0x00,0x1a,0xd4,0xcd,0x05,0x0c, +0x24,0x14,0x01,0x00,0x21,0x1b,0x84,0x48,0x00,0x1a,0xd0,0xcd,0x0b,0x1c,0x1c,0x8e, +0x20,0x0b,0x54,0x20,0x00,0x1b,0x00,0x40,0x24,0x14,0xaa,0xaa,0x20,0x1b,0xaa,0xaa, +0xa0,0x1b,0xf0,0x8b,0x44,0x14,0x80,0x48,0x00,0x1a,0x00,0x01,0x21,0xcd,0x05,0x88, +0x44,0x04,0xdc,0xcd,0x06,0x83,0x50,0x01,0xa0,0x80,0x1a,0x9c,0x24,0x50,0x1b,0x40, +0x01,0xf0,0xcd,0x05,0x9a,0x24,0xb0,0x26,0x00,0x14,0xa4,0xe6,0x20,0x0b,0xcd,0x06, +0x8f,0x00,0x20,0x04,0x84,0x00,0x00,0x1a,0x06,0x00,0x24,0x0e,0x30,0x4e,0xfc,0x34, +0x01,0xcd,0x07,0x81,0x8a,0x20,0x05,0x00,0x21,0x1b,0x80,0x48,0xfc,0x34,0x01,0xcd, +0x07,0xa2,0x30,0xe0,0xcd,0x04,0x1c,0xcd,0x07,0x86,0x08,0xf0,0x4e,0xfc,0xcd,0x09, +0xab,0x58,0x78,0x06,0x21,0x1b,0x01,0x00,0x25,0xcd,0x09,0x81,0x40,0xc0,0xe6,0x24, +0x04,0xc8,0xcd,0x0b,0x81,0x50,0x04,0x18,0xcd,0x06,0x91,0x20,0xa6,0x29,0xc0,0x02, +0xe0,0x2b,0x00,0x14,0x54,0x20,0x18,0x1b,0x01,0xa0,0x80,0x1a,0xbc,0x24,0x50,0x1b, +0x40,0x31,0x80,0x1a,0x01,0x00,0xd0,0x0e,0x00,0x00,0x75,0xcd,0x05,0x14,0xb4,0xcd, +0x04,0x14,0xe9,0xcd,0x06,0x14,0x30,0x2f,0x00,0x1b,0x00,0x00,0x78,0x0e,0xcd,0x04, +0x18,0xc4,0xcd,0x04,0x18,0xf1,0xcd,0x06,0x18,0x01,0x00,0xf8,0x0e,0x00,0x30,0x00, +0x1b,0xcd,0x0a,0x81,0x95,0x68,0xc4,0xcd,0x0d,0xc8,0x4c,0xcd,0x06,0x84,0x78,0x20, +0x0e,0xcd,0x11,0x83,0x5c,0xcd,0x0c,0x81,0x9a,0x60,0xcd,0x1b,0xa6,0x50,0x4c,0x00, +0x3d,0x1b,0x01,0xe8,0x80,0x1a,0xf0,0x38,0x9c,0x14,0x01,0xf0,0xcd,0x0a,0xa7,0x04, +0xb8,0xcd,0x05,0x82,0x40,0xd4,0x0e,0x42,0xa8,0x54,0x08,0x40,0xa9,0x80,0x1a,0xcd, +0x08,0x9c,0x70,0x54,0x28,0x14,0x1b,0x38,0x2f,0x10,0xcd,0x05,0x81,0x40,0x98,0xcd, +0x05,0x24,0xf8,0xcd,0x05,0x18,0xfb,0xff,0x21,0x1b,0x84,0xf0,0x20,0x0b,0xf0,0x43, +0x20,0x04,0xf0,0x43,0xfc,0x34,0x02,0xcd,0x05,0xe5,0x50,0x00,0x00,0x98,0x2f,0xcd, +0x07,0xca,0x44,0xcd,0x07,0x58,0xcd,0x06,0x34,0xd4,0x0e,0x8c,0xf9,0x55,0x09,0xcd, +0x0c,0x58,0xf1,0x17,0x80,0x02,0x01,0x00,0x21,0xcd,0x05,0x58,0xcd,0x06,0x83,0x3c, +0xd8,0xcd,0x05,0x18,0xc0,0xb6,0xcd,0x0b,0x82,0x60,0x28,0x20,0x14,0xcd,0x08,0x48, +0xa8,0x23,0x50,0x1b,0xac,0x23,0x54,0x1b,0x40,0x01,0xe8,0x0e,0x50,0x01,0xe4,0xcd, +0x09,0x9e,0x10,0xa4,0xd6,0x24,0x0b,0xff,0xcd,0x05,0x83,0x4c,0x24,0x04,0xb8,0x06, +0x21,0x1b,0xcd,0x04,0x34,0x94,0x40,0x00,0x1a,0xa4,0xce,0xcd,0x0a,0x18,0xba,0xcd, +0x0b,0x18,0xe9,0xff,0x21,0x1b,0x84,0xd0,0x20,0x0b,0xf0,0x43,0x24,0x04,0xb4,0xcd, +0x0b,0x18,0xea,0xff,0x21,0x1b,0xb6,0x06,0x25,0xcd,0x05,0x1c,0x90,0x28,0x24,0x14, +0xf0,0x43,0x20,0x04,0x84,0x48,0x00,0xcd,0x05,0x82,0x20,0xcd,0x05,0x83,0x38,0xcd, +0x07,0x81,0x78,0xe0,0xf3,0x4c,0x14,0xcd,0x05,0xeb,0x10,0x20,0xa0,0x1b,0x80,0x98, +0xcd,0x0a,0x8c,0x70,0x53,0x15,0xcd,0x06,0x8d,0x48,0x10,0x26,0x20,0xcd,0x05,0x8a, +0x38,0x56,0x15,0x80,0x02,0xcd,0x04,0x58,0x10,0x26,0xcd,0x0a,0x85,0x60,0x16,0x00, +0x21,0x1b,0x80,0x00,0x5c,0xcd,0x05,0x74,0x06,0x40,0x60,0x0e,0x40,0x2f,0xcd,0x04, +0x08,0x20,0x0e,0x80,0x41,0xe0,0x0b,0x80,0x00,0xdc,0xcd,0x05,0x82,0x0c,0xa0,0xcd, +0x0d,0x6c,0x18,0xcd,0x05,0x82,0x00,0xa4,0xcd,0x0d,0x14,0x00,0x14,0xe0,0x03,0x44, +0xcd,0x05,0x18,0xc0,0xcd,0x0b,0x18,0x24,0xf6,0x20,0x0b,0xf0,0x43,0x48,0x04,0x30, +0xcd,0x07,0x54,0xcd,0x05,0x83,0x14,0xd4,0xcd,0x06,0x81,0x1c,0xf4,0x9b,0x20,0x0b, +0x58,0x06,0x25,0x1b,0x90,0x28,0x24,0xcd,0x06,0x86,0x40,0x00,0x24,0x1b,0x00,0x20, +0xa4,0x1b,0x90,0x40,0xcd,0x0a,0x81,0x40,0x83,0xcd,0x0f,0x81,0x40,0x86,0xcd,0x13, +0x81,0x40,0x00,0x1c,0xc0,0x02,0x88,0x07,0x21,0x1b,0xff,0xff,0x24,0xcd,0x05,0x86, +0x58,0x00,0x02,0x25,0xcd,0x06,0x44,0xcd,0x07,0x86,0x38,0x98,0x07,0x21,0x1b,0x15, +0x1c,0xc0,0x02,0x10,0x00,0x25,0x1b,0xb0,0x3e,0x04,0x14,0x0f,0xcd,0x06,0x9b,0x54, +0x00,0xe0,0x8b,0x00,0x14,0xff,0xff,0x20,0x1b,0x00,0x43,0x20,0x04,0x84,0x08,0x00, +0x1a,0x10,0x0e,0x04,0x14,0xf0,0xff,0x21,0x1b,0x05,0x43,0x20,0x0b,0x30,0x06,0x00, +0x14,0xcd,0x04,0x14,0x00,0xe0,0xbf,0x01,0xcd,0x04,0x18,0xf4,0x1d,0xc0,0x02,0xb0, +0x3e,0x00,0x14,0x43,0x19,0xcd,0x06,0x86,0x50,0xba,0x24,0xcd,0x06,0x08,0xb4,0x17, +0xcd,0x07,0x99,0x2c,0xcd,0x07,0x81,0x60,0x10,0x46,0xfc,0x34,0x02,0x24,0x05,0xcd, +0x05,0x78,0xc8,0x06,0x01,0x1b,0x00,0x28,0x00,0x14,0x0e,0x00,0x20,0x0e,0xc0,0x46, +0xfc,0x34,0xcd,0x08,0xd4,0x4c,0xcd,0x04,0x10,0xcd,0x04,0x7c,0xe0,0x43,0xfc,0x34, +0xe0,0x03,0x20,0x14,0xe0,0x43,0x44,0x14,0x02,0x64,0x01,0x01,0xe0,0x43,0x50,0x14, +0xcd,0x04,0x18,0x00,0x00,0x21,0x1b,0xe0,0x03,0x04,0x14,0x30,0x3e,0x00,0x14,0xf0, +0x43,0x20,0x14,0xf0,0xff,0x29,0x1b,0x10,0x00,0x25,0x1b,0x15,0x53,0x28,0x0b,0x1d, +0x4b,0x24,0x0b,0x8c,0x4e,0x24,0x0b,0x70,0x46,0xfc,0x34,0x94,0xcd,0x07,0x88,0x40, +0xe0,0x3e,0x00,0x14,0x30,0x0e,0x04,0x14,0xa4,0xcd,0x05,0x10,0x28,0x0e,0xaa,0x50, +0x18,0x10,0x02,0x00,0xa8,0x17,0xcc,0x06,0x01,0x1b,0x9a,0x48,0x18,0x10,0x00,0x28, +0x00,0x14,0x02,0x00,0xa4,0x17,0xa0,0x48,0x28,0x14,0xf1,0xff,0x25,0x1b,0x9c,0x50, +0x24,0x0b,0x90,0x80,0x25,0x15,0x6c,0x4e,0xcd,0x05,0x08,0x14,0xe0,0x0b,0x44,0x14, +0x90,0x00,0x00,0x1a,0xcd,0x04,0x7c,0x04,0x8c,0x3f,0x01,0xcd,0x04,0x7c,0xcd,0x04, +0x3c,0x00,0x01,0x21,0xcd,0x05,0x81,0x40,0x80,0x80,0x7d,0x35,0x08,0x68,0xcd,0x07, +0x81,0x9a,0x3c,0x2f,0x24,0x14,0x03,0x00,0x21,0x1b,0x34,0x2f,0x00,0xcd,0x05,0x82, +0x7c,0x70,0x2e,0x24,0x14,0xcd,0x04,0x08,0x84,0x00,0x00,0x1a,0x2c,0x2f,0x00,0x1b, +0xcd,0x05,0x81,0x10,0x4b,0xcd,0x0a,0x89,0x40,0x7e,0x34,0xcd,0x07,0x81,0x87,0x60, +0x8b,0x00,0x14,0xe0,0x03,0x20,0x14,0x10,0x16,0x80,0x02,0xe0,0x43,0x50,0x14,0xcd, +0x04,0x18,0x01,0x00,0x21,0x1b,0xcd,0x10,0x18,0xcd,0x04,0x60,0x00,0xcd,0x2f,0x60, +0x02,0xcd,0x13,0x48,0xcd,0x10,0x78,0xcd,0x04,0x14,0xd2,0x06,0x45,0x1b,0x10,0x29, +0x00,0x14,0x06,0x00,0xcd,0x07,0x85,0x08,0xc8,0xcd,0x06,0x44,0xc8,0x06,0x05,0x1b, +0x10,0x28,0x04,0x14,0x0e,0x08,0xcd,0x07,0x83,0x28,0xcd,0x07,0x8a,0x64,0xcd,0x04, +0x10,0xcd,0x05,0x90,0x68,0xa0,0xcd,0x08,0xb2,0x08,0x21,0x1b,0x84,0x00,0x00,0x1a, +0xe0,0x2b,0x00,0x14,0xcd,0x05,0x8c,0x24,0x28,0xcd,0x06,0x85,0x04,0xa6,0x27,0xc0, +0x02,0x84,0x48,0x00,0x1a,0x40,0x2f,0x24,0x14,0x16,0x00,0x29,0x1b,0xf6,0x04,0x21, +0x1b,0xa0,0x28,0x28,0xcd,0x05,0x81,0x38,0xd2,0x05,0xcd,0x06,0x86,0x5c,0x84,0x50, +0x00,0x1a,0x06,0x48,0x60,0x0e,0x80,0xc0,0xcd,0x06,0x86,0x54,0x04,0x07,0x21,0x1b, +0x08,0x00,0x24,0xcd,0x05,0x85,0x18,0x01,0x08,0xa4,0x1b,0x10,0x07,0x21,0x1b,0xfc, +0x6f,0xcd,0x06,0x10,0x1f,0x00,0xa4,0x1b,0x14,0x07,0x21,0x1b,0xf8,0xdf,0xcd,0x06, +0x10,0x1e,0x00,0xa4,0x1b,0x40,0x00,0x49,0x1b,0x08,0x00,0x25,0xcd,0x05,0x10,0xe0, +0x93,0x20,0x14,0xcd,0x04,0x04,0xcd,0x04,0x0c,0x00,0x00,0x25,0x1b,0xcd,0x0c,0x84, +0x68,0xf0,0x43,0xcd,0x0b,0x81,0x40,0x00,0xcd,0x07,0x85,0x10,0xe8,0xcd,0x06,0x92, +0x58,0x40,0x2f,0x28,0x14,0x10,0x29,0x24,0x14,0xd4,0x06,0x01,0x1b,0x01,0x00,0xcd, +0x06,0x83,0x5c,0xcd,0x06,0x88,0x00,0x25,0xcd,0x05,0x81,0x34,0x90,0x28,0x24,0x14, +0x84,0x50,0x00,0x1a,0xcd,0x05,0x89,0x20,0x00,0x5c,0xcd,0x05,0x83,0x00,0x06,0x50, +0xcd,0x06,0x81,0x34,0x06,0x00,0xcd,0x06,0x82,0x0c,0xcd,0x05,0x87,0x64,0x68,0x00, +0x01,0xcd,0x11,0x81,0x44,0x09,0xcd,0x06,0x81,0x44,0xe9,0x2f,0x48,0x1b,0x1d,0x00, +0xc8,0xcd,0x07,0x81,0x28,0x24,0x14,0xcd,0x04,0x04,0xcd,0x04,0x0c,0x14,0x07,0x21, +0xcd,0x1d,0x81,0x44,0xcd,0x08,0x85,0x78,0x84,0x00,0x00,0x1a,0xa6,0x27,0xcd,0x06, +0x86,0x5c,0xe0,0xa3,0xcd,0x1a,0x86,0x0c,0xcd,0x08,0x86,0x08,0x15,0x53,0x28,0x0b, +0xcd,0x0c,0x86,0x08,0x70,0x46,0xfc,0x34,0xcd,0x10,0x86,0x08,0x80,0xcd,0x1b,0x86, +0x08,0x7c,0x4e,0x28,0x0b,0x00,0x00,0x24,0x0e,0x90,0x50,0xa8,0x14,0x6c,0x56,0x28, +0x0b,0xa0,0x48,0x24,0xcd,0x05,0x86,0x4c,0x90,0x00,0x00,0x1a,0xcc,0x06,0x29,0x1b, +0xcd,0x04,0x64,0xa0,0x28,0x28,0x14,0x04,0x80,0x3f,0x01,0x90,0x50,0xcd,0x06,0x85, +0x10,0x01,0x00,0x21,0x1b,0xcc,0x06,0x01,0xcd,0x06,0x88,0x7c,0x28,0x00,0x14,0xcd, +0x05,0x88,0x70,0x80,0x7d,0x35,0x08,0xcd,0x07,0x81,0x84,0x6c,0xd0,0xcd,0x07,0x89, +0x54,0x10,0x2f,0xcd,0x06,0x82,0x60,0x06,0xcd,0x07,0x88,0x00,0xcd,0x08,0x8f,0x3c, +0x7e,0x34,0xc0,0x02,0x03,0x00,0x21,0x1b,0xc8,0x16,0xcd,0x06,0x88,0x3c,0xcd,0x09, +0x85,0x10,0xcd,0x07,0xd9,0x64,0xcd,0x08,0x85,0x54,0xcd,0x08,0x20,0xcd,0x05,0x87, +0x0c,0x28,0x00,0x14,0x40,0x87,0xfd,0x34,0x08,0xcd,0x07,0xa9,0x08,0xcd,0x04,0x64, +0x00,0x00,0xcd,0x06,0x83,0x34,0xcd,0x04,0x30,0xcd,0x05,0x81,0x0c,0x00,0x45,0x1b, +0x00,0x30,0x24,0x0e,0x7c,0x4e,0xcd,0x06,0x9b,0x6c,0x10,0x3e,0x00,0x14,0x84,0x38, +0x00,0x1a,0x8c,0x4e,0xcd,0x04,0x0c,0x04,0x14,0x84,0x00,0x00,0x1a,0xed,0x18,0xc0, +0x02,0xe0,0x3b,0x00,0x14,0xcd,0x04,0x1c,0x06,0x38,0x24,0x0e,0xcd,0x04,0x7c,0x90, +0x40,0xa0,0x0b,0x80,0x30,0x00,0x1a,0x84,0xb1,0x39,0x12,0x74,0xf9,0x19,0x13,0x2d, +0x00,0xa0,0x17,0xcd,0x04,0x20,0x2c,0x00,0xa4,0x17,0xcd,0x04,0x40,0x30,0x36,0x18, +0x14,0x06,0x38,0x20,0x0e,0x50,0x3e,0x04,0x14,0x94,0x00,0x00,0x1a,0x00,0x3f,0x08, +0x14,0x06,0x00,0x24,0x0e,0xaa,0xcd,0x07,0x83,0x28,0xcd,0x04,0x18,0xcd,0x05,0x93, +0x2c,0x9b,0x20,0x14,0x06,0x08,0x24,0x0e,0x00,0x3f,0x04,0x14,0xe6,0x29,0xc0,0x02, +0x06,0x08,0x28,0x0e,0xf0,0x8b,0x44,0x14,0x70,0x8e,0xfc,0x34,0x04,0xcd,0x07,0xa2, +0x74,0xcd,0x10,0x8a,0x30,0xcd,0x05,0x82,0x18,0x48,0xcd,0x06,0xfe,0x40,0x00,0x00, +0x51,0x1b,0x7c,0xb6,0x21,0xcd,0x0e,0x81,0x3c,0xb6,0x21,0xcd,0x17,0x81,0x3c,0x20, +0x0e,0x06,0x00,0x24,0x0e,0x80,0x48,0xcd,0x0e,0x81,0x3c,0x2c,0x00,0xa4,0xcd,0x05, +0x81,0x3c,0x2d,0x00,0xa0,0x17,0x30,0x2e,0x28,0xcd,0x05,0x44,0xcd,0x14,0x81,0x40, +0x00,0x50,0x0c,0xcd,0x05,0x40,0x00,0x18,0x40,0xcd,0x22,0x81,0x44,0xa3,0x50,0x14, +0x70,0xa6,0xfc,0x34,0x04,0x64,0xcd,0x06,0x81,0x44,0x78,0xcd,0x07,0x8f,0x20,0x0e, +0x40,0xcd,0x06,0x86,0x14,0x01,0x38,0xcd,0x06,0x81,0x40,0xb0,0x2e,0xcd,0x06,0x81, +0x54,0x30,0x46,0xfc,0x34,0x02,0x74,0xcd,0x08,0x9d,0x14,0x00,0x14,0x00,0x00,0x49, +0x1b,0xe0,0x03,0x10,0xcd,0x05,0x85,0x44,0x10,0x00,0x21,0x1b,0x4d,0x43,0xcd,0x06, +0x83,0x20,0xe0,0xcd,0x07,0x81,0x58,0xe0,0x3e,0x00,0xcd,0x05,0x8c,0x78,0x45,0x43, +0x20,0x0b,0x30,0x26,0x10,0xcd,0x05,0x14,0x22,0x19,0xc0,0x02,0xcd,0x04,0x30,0xcd, +0x04,0x04,0xcd,0x05,0x86,0x7c,0x3e,0x00,0x14,0x68,0x2e,0xc0,0x02,0x06,0x00,0x24, +0x0e,0xf0,0x93,0x48,0x14,0x70,0x96,0xfc,0x34,0x04,0xb0,0xcd,0x06,0x81,0x10,0x6f, +0xcd,0x07,0x82,0x54,0xe0,0x93,0xfc,0xcd,0x05,0xf3,0x3c,0xcd,0x68,0x78,0xcd,0x0c, +0xba,0x28,0xcd,0x06,0x8f,0x74,0xd4,0x0e,0x00,0x00,0x58,0x1b,0x84,0xb0,0x54,0xcd, +0x07,0x92,0x54,0xcd,0x0a,0xb0,0x20,0x70,0x2e,0xcd,0x07,0x50,0x43,0xcd,0x0e,0x86, +0x08,0x00,0x00,0x21,0x1b,0xcd,0x08,0x84,0x14,0xcd,0x14,0x86,0x28,0x01,0xcd,0x0f, +0x20,0xcd,0x05,0x89,0x50,0xcd,0x07,0x8b,0x38,0xcd,0x08,0x86,0x28,0xcd,0x10,0x84, +0x54,0xcd,0x05,0x83,0x00,0xa4,0xcd,0x08,0x8b,0x34,0x45,0xcd,0x2b,0x84,0x54,0xcd, +0x1a,0x86,0x10,0xcd,0x08,0x86,0x0c,0xcd,0x08,0x84,0x7c,0x30,0x36,0x18,0xcd,0x05, +0x84,0x4c,0x50,0x3e,0x04,0x14,0xd2,0x1d,0xcd,0x0e,0x86,0x08,0x06,0x08,0x24,0x0e, +0xe0,0x9b,0x20,0xcd,0x05,0x84,0x40,0xe0,0x4b,0x28,0x14,0xcd,0x09,0x86,0x04,0x78, +0xcd,0x06,0x82,0x38,0xcd,0x08,0x81,0x78,0xcd,0x12,0x95,0x64,0xd4,0xcd,0x0d,0x95, +0x64,0x5e,0x06,0xcd,0x06,0x99,0x60,0xcd,0x06,0x84,0x6c,0x70,0x0e,0x5f,0xcd,0x07, +0x84,0x78,0x00,0x00,0x74,0x0e,0x0e,0x40,0x6c,0xcd,0x05,0x97,0x24,0xcd,0x08,0x83, +0x00,0xcd,0x08,0x44,0xe0,0xeb,0x58,0x14,0x00,0xb0,0x54,0x09,0xe0,0xe3,0x58,0x14, +0x10,0xb2,0x54,0x09,0xe0,0xdb,0x58,0x14,0x52,0xb2,0xcd,0x12,0x83,0x10,0xcd,0x04, +0x3c,0x94,0xcd,0x0b,0x93,0x28,0x20,0xf7,0xcd,0x07,0x96,0x30,0xcd,0x07,0xa2,0x4c, +0xac,0x06,0x45,0x1b,0xb8,0x0b,0x21,0x1b,0x10,0x29,0x10,0x14,0x06,0x20,0x24,0x0e, +0x80,0x48,0xfc,0xcd,0x09,0x81,0xa3,0x44,0x5e,0x1a,0xcd,0x06,0x81,0x70,0x79,0xcd, +0x07,0x81,0xaf,0x7c,0xe0,0x43,0x24,0x14,0xbc,0xcd,0x0b,0x96,0x1c,0xcd,0x05,0x8b, +0x48,0x20,0x00,0x1a,0xcd,0x0a,0x8e,0x6c,0x20,0xcd,0x05,0x82,0x6c,0xcd,0x05,0x81, +0x74,0x00,0xf8,0x0e,0xcd,0x05,0x97,0x6c,0xcd,0x21,0x81,0xae,0x30,0xcd,0x10,0x81, +0xae,0x2c,0xcd,0x0e,0x98,0x6c,0xf0,0x38,0xcd,0x0a,0xa3,0x10,0x38,0x2f,0x10,0x1b, +0x9c,0x18,0x80,0x02,0x54,0x28,0x14,0xcd,0x05,0x8f,0x0c,0xe0,0x2b,0x00,0x14,0x30, +0x2f,0x24,0x14,0x02,0x00,0x21,0x1b,0x27,0x18,0x80,0xcd,0x07,0x8f,0x1c,0x20,0x14, +0x7b,0x02,0x25,0x1b,0x94,0x40,0xcd,0x06,0x95,0x70,0xe9,0x02,0x25,0xcd,0x05,0x82, +0x4c,0x36,0x18,0xcd,0x06,0x94,0x50,0xcd,0x10,0x20,0x66,0x01,0xcd,0x1e,0x20,0x00, +0xcd,0x0f,0x20,0xc8,0xcd,0x0f,0x88,0x14,0xcd,0x08,0x81,0xa2,0x50,0xc0,0x46,0x7c, +0x35,0xcd,0x05,0xf7,0x24,0x00,0x00,0x00,0x14,0x46,0x20,0x0b,0x00,0xcd,0x05,0x9c, +0x3c,0x20,0x14,0x00,0x40,0xcd,0x05,0xb5,0x68,0xcd,0x06,0xa9,0x1c,0x2f,0xcd,0x06, +0x82,0x28,0xfc,0x43,0x20,0x0b,0xcd,0x06,0x82,0x28,0x25,0x1b,0x16,0x00,0xcd,0x06, +0x8b,0x74,0xcd,0x0c,0x18,0x78,0xcd,0x0b,0x82,0x64,0xaa,0x18,0xcd,0x06,0x85,0x74, +0x23,0xcd,0x05,0x8e,0x40,0x00,0x00,0x30,0x2e,0x20,0x14,0x25,0x1c,0xcd,0x06,0x81, +0xc0,0x5c,0x03,0x00,0x25,0x1b,0x00,0x40,0x00,0x1a,0x30,0x2f,0xcd,0x06,0x98,0x44, +0x40,0x2f,0x24,0x14,0x7b,0x02,0xcd,0x0a,0x97,0x6c,0xcd,0x08,0x81,0x5c,0xcd,0x04, +0x1c,0xcd,0x04,0x6c,0x7a,0xcd,0x0b,0x98,0x70,0x70,0x2e,0xcd,0x06,0x08,0xae,0xcd, +0x07,0x14,0xcd,0x04,0x68,0xcd,0x04,0x10,0xcd,0x09,0x68,0x2f,0x20,0x14,0xcd,0x04, +0x60,0xb5,0x1c,0x00,0xcd,0x05,0x82,0x0c,0xcd,0x04,0x78,0xcd,0x04,0x74,0x7b,0x02, +0xcd,0x06,0x74,0x40,0xcd,0x07,0x74,0xcd,0x05,0x98,0x54,0xcd,0x1b,0x64,0xcd,0x11, +0x58,0x2e,0x20,0x14,0x45,0x1d,0xcd,0x18,0x81,0x40,0x20,0x14,0x88,0x01,0xcd,0x0a, +0x82,0x7c,0xcd,0x24,0x58,0x30,0x2f,0x24,0x14,0x04,0xcd,0x07,0x98,0x20,0xcd,0x14, +0x40,0xcd,0x08,0x28,0x78,0x1f,0xcd,0x08,0xe6,0x5c,0x25,0x1b,0xcd,0x05,0x70,0x20, +0x00,0x1a,0xcd,0x08,0x1c,0xcd,0x08,0x8b,0x50,0xcd,0x0c,0x83,0x50,0x70,0xcd,0x0f, +0x83,0x50,0x10,0xcd,0x13,0x83,0x50,0x00,0x00,0x35,0xcd,0x05,0xa1,0x14,0x68,0xcd, +0x07,0x81,0x1c,0xd0,0x40,0x00,0x1a,0x6c,0xcd,0x0b,0x0c,0x70,0xcd,0x0b,0x0c,0x74, +0xcd,0x0b,0x0c,0xac,0xcd,0x07,0x0c,0xc4,0xcd,0x04,0x7c,0xcd,0x0b,0x0c,0xb2,0xcd, +0x07,0x94,0x6c,0xff,0x01,0xcd,0x06,0x81,0x50,0xb4,0x06,0x21,0x1b,0xb8,0x06,0xcd, +0x06,0x83,0x44,0xcd,0x04,0x20,0xb6,0xcd,0x07,0x2c,0x90,0x28,0x24,0xcd,0x05,0x10, +0xff,0xcd,0x07,0x81,0x78,0xba,0xcd,0x07,0x91,0x08,0xcd,0x04,0x0c,0xbc,0x06,0x21, +0x1b,0x00,0xcd,0x08,0xa0,0x30,0x28,0x20,0x14,0xc0,0x06,0x21,0x1b,0x40,0x00,0xcd, +0x06,0x44,0xcd,0x04,0x7c,0xc4,0xcd,0x0b,0x84,0x5c,0xc6,0xcd,0x07,0x2c,0xcd,0x08, +0x82,0x58,0xff,0x00,0x25,0x1b,0x64,0xcd,0x0b,0x82,0x68,0x50,0x2f,0xcd,0x06,0x78, +0x1e,0xcd,0x07,0x82,0x4c,0xcd,0x04,0x0c,0x60,0xcd,0x07,0x83,0x2c,0xcd,0x0c,0x87, +0x24,0xcd,0x05,0x9e,0x48,0x20,0x80,0xcd,0x05,0x92,0x00,0x54,0x28,0x10,0x1b,0x68, +0x06,0x09,0x1b,0x7c,0x46,0x24,0x0b,0x20,0x20,0x0c,0x14,0x06,0x08,0x20,0x0e,0x90, +0x98,0x25,0x15,0x7c,0x46,0x20,0x0b,0x6c,0x06,0x09,0x1b,0x00,0x80,0x29,0x1b,0xa0, +0x48,0x24,0x14,0x8c,0x4e,0x24,0x0b,0x90,0x98,0x25,0x14,0x20,0x20,0x08,0x14,0x90, +0x18,0x00,0x1a,0x80,0x90,0x21,0x15,0x00,0x80,0x25,0x1b,0xcd,0x04,0x54,0x90,0x40, +0x20,0x14,0xcd,0x05,0xad,0x44,0x90,0x21,0x14,0x80,0x10,0x00,0x1a,0x8c,0x9e,0x25, +0xcd,0x05,0x95,0x18,0x90,0x40,0xa0,0xcd,0x05,0x88,0x60,0x8c,0x96,0x21,0x0b,0x06, +0x08,0xcd,0x05,0x90,0x14,0xcd,0x06,0x9b,0x3c,0xcd,0x07,0x81,0x04,0xcd,0x06,0x81, +0x00,0x0c,0xcd,0x05,0x81,0x00,0x20,0x18,0x08,0x14,0xcd,0x04,0x74,0xcd,0x08,0x58, +0xcd,0x10,0x54,0x00,0x10,0x20,0x0e,0xcd,0x04,0x10,0xcd,0x04,0x40,0x06,0x08,0xcd, +0x09,0x90,0x64,0xcd,0x07,0x89,0x40,0xcd,0x12,0x81,0x54,0x70,0xcd,0x17,0x81,0x54, +0x74,0xcd,0x5f,0x81,0x54,0xcd,0x0c,0xa2,0x68,0xe0,0x03,0x14,0xcd,0x05,0xaf,0x0c, +0x01,0x90,0xcd,0x06,0x8a,0x0c,0xcd,0x10,0x9e,0x10,0xe0,0x43,0xfc,0x34,0x08,0xcd, +0x07,0xb1,0x60,0x80,0xf0,0xa1,0x14,0x66,0xcd,0x07,0x94,0x50,0x06,0x00,0x28,0xcd, +0x05,0x81,0x60,0xa0,0x40,0xa0,0x14,0xf6,0xff,0x29,0x1b,0xac,0x40,0x20,0x0b,0x80, +0x48,0x20,0x14,0xc8,0xcd,0x08,0x84,0x38,0x00,0x00,0x1a,0x0e,0x48,0xcd,0x06,0x9a, +0x70,0x02,0xc0,0x00,0x01,0x06,0x00,0x20,0x0e,0x80,0x01,0x25,0xcd,0x05,0xa5,0x20, +0x08,0xb0,0xcd,0x06,0x50,0xc9,0xcd,0x0b,0x98,0x7c,0xcd,0x05,0x8f,0x5c,0xcd,0x07, +0xab,0x44,0xe0,0x03,0x20,0x14,0x01,0x00,0x31,0xcd,0x05,0x84,0x54,0xe0,0x63,0x24, +0xcd,0x05,0xa6,0x70,0xcd,0x09,0xa7,0x10,0x28,0x20,0x14,0x90,0xcd,0x05,0x88,0x38, +0x45,0x1b,0x14,0x41,0x00,0x1a,0x14,0x21,0xcd,0x06,0x9f,0x44,0x04,0x07,0x21,0x1b, +0xff,0xbf,0x25,0x1b,0x90,0x40,0x24,0x04,0x15,0xcd,0x07,0x10,0xcd,0x04,0x18,0x40, +0x00,0xcd,0x06,0x85,0x2c,0x90,0x40,0xc8,0x04,0xcd,0x08,0x98,0x50,0xcd,0x04,0x14, +0xf0,0x8b,0x44,0x14,0x64,0x00,0xcd,0x07,0xa6,0x74,0xf4,0xcd,0x06,0x8e,0x5c,0xbf, +0xff,0x21,0x1b,0x80,0x90,0xcd,0x06,0x40,0xcd,0x04,0x24,0xb8,0x19,0xcd,0x06,0x8a, +0x28,0xcd,0x0c,0x81,0x28,0xcd,0x05,0x8d,0x68,0xcd,0x07,0x81,0xb7,0x3c,0xe0,0x03, +0x20,0x14,0x00,0xcd,0x0b,0x81,0x28,0x5f,0xcd,0x0c,0xa6,0x58,0x28,0xcd,0x06,0xa8, +0x28,0xcd,0x0c,0x81,0x38,0xcd,0x08,0x81,0x28,0x00,0x40,0x25,0x1b,0x90,0x40,0xa4, +0xcd,0x17,0x81,0x28,0xc4,0x04,0xe0,0x8b,0xcd,0x0a,0x81,0x28,0x00,0x00,0x21,0x1b, +0xf0,0x43,0x20,0x14,0xc8,0xcd,0x05,0x1c,0xcd,0x0f,0x81,0x2c,0x88,0xcd,0x0a,0x81, +0x2c,0x5e,0xcd,0x05,0x81,0x24,0x18,0x14,0x0e,0x30,0xcd,0x07,0x82,0x4c,0xcd,0x05, +0xf9,0x74,0x00,0x00,0x5c,0xcd,0x07,0x86,0x7c,0x04,0x40,0x20,0x0e,0x70,0x46,0x7c, +0x35,0x10,0x84,0xcd,0x07,0xa8,0x04,0xcd,0x07,0x89,0x3c,0xe0,0x33,0x20,0xcd,0x05, +0xb3,0x28,0x01,0xcd,0x04,0x60,0xcd,0x67,0x82,0x58,0xcd,0x06,0x81,0x2c,0xcd,0x0b, +0x82,0x50,0xcd,0x09,0x84,0x10,0xcd,0x0e,0x8e,0x08,0x02,0xcd,0x07,0x95,0x10,0x26, +0xcd,0x07,0x88,0x2c,0xcd,0x09,0xa4,0x04,0xcd,0x07,0xb5,0x48,0xcd,0x11,0x82,0x70, +0x03,0xcd,0x06,0x81,0x4c,0x00,0x00,0x25,0xcd,0x05,0x81,0x24,0xcd,0x38,0x82,0x6c, +0x64,0xcd,0x1f,0x82,0x6c,0xcd,0x18,0x90,0x58,0x01,0x00,0x21,0x1b,0x30,0x3e,0x9c, +0xcd,0x09,0x90,0x5c,0xcd,0x09,0xa9,0x48,0xcd,0x07,0xad,0x1c,0x38,0x2f,0xcd,0x06, +0xaa,0x48,0xcd,0x0e,0xa6,0x10,0x14,0xcd,0x05,0xa5,0x78,0xcd,0x0c,0xa7,0x10,0xcd, +0x09,0xa7,0x0c,0xf0,0xcd,0x0a,0xa5,0x4c,0x36,0x1a,0xcd,0x07,0xa5,0x4c,0x36,0xcd, +0x06,0xa5,0x4c,0x39,0x1a,0xcd,0x07,0xa5,0x4c,0x36,0x20,0x14,0x01,0x00,0xcd,0x06, +0x8d,0x20,0x00,0x00,0x45,0x1b,0xb0,0x26,0x24,0x14,0x06,0x48,0x24,0x0e,0xff,0xff, +0x20,0x1b,0x70,0x4e,0xfc,0x34,0x80,0xa8,0x21,0x04,0x02,0x14,0x00,0x01,0x30,0x2e, +0x14,0x14,0x4c,0x47,0x20,0x0b,0x4a,0x1a,0x80,0x02,0x8c,0x46,0x20,0x0b,0xbc,0x00, +0x25,0x1b,0x9a,0x40,0x18,0x10,0x02,0x00,0xa0,0x17,0x80,0xcd,0x06,0xac,0x54,0x14, +0x6c,0x46,0x20,0x0b,0xe0,0x23,0x00,0xcd,0x06,0x95,0x14,0x3b,0x04,0xcd,0x05,0x95, +0x54,0xe0,0x33,0x00,0x14,0xe0,0xf3,0xcd,0x13,0x95,0x10,0x98,0xcd,0x06,0x82,0x1c, +0x30,0x3e,0x1c,0xcd,0x07,0xb0,0x40,0xcd,0x16,0x82,0x10,0x68,0x06,0x05,0x1b,0xe8, +0x03,0x25,0x1b,0x10,0x00,0x00,0xcd,0x05,0x88,0x68,0x8c,0x86,0x21,0x0b,0xcd,0x05, +0x82,0x5c,0x24,0x00,0x01,0x08,0x07,0x45,0xcd,0x05,0x83,0x10,0xe0,0x8b,0x20,0x14, +0x70,0x46,0xa4,0xcd,0x05,0x83,0x08,0xcd,0x04,0x0c,0x76,0xcd,0x07,0x81,0x6c,0x18, +0xfc,0xcd,0x06,0x88,0x30,0x04,0xcd,0x07,0x9d,0x38,0xcd,0x0a,0x2c,0xcd,0x06,0x83, +0x34,0xcd,0x04,0x0c,0xcd,0x08,0xb6,0x64,0xcd,0x05,0x89,0x58,0xcd,0x13,0x81,0xc7, +0x14,0xcd,0x0e,0x89,0x50,0x44,0x04,0xcd,0x04,0x10,0x80,0x07,0x21,0x1b,0x84,0x46, +0x50,0x0b,0xcd,0x06,0x14,0x48,0x04,0x0c,0x96,0x20,0x0b,0xcd,0x05,0x85,0x30,0xcd, +0x07,0x8f,0x1c,0xff,0x7f,0x21,0x1b,0x80,0xa0,0x20,0x14,0x0c,0x46,0x20,0x0b,0x10, +0x41,0xfc,0xcd,0x09,0xcb,0x58,0x94,0x1a,0x80,0x02,0x01,0x00,0x4d,0x1b,0x00,0xcd, +0x04,0x04,0x1c,0xc0,0x02,0x00,0x04,0x21,0x1b,0xe0,0x43,0x54,0xcd,0x05,0x87,0x58, +0x0c,0x04,0x21,0x1b,0x44,0xae,0x24,0x0b,0xc0,0x46,0x30,0x04,0x20,0x4f,0x2c,0x04, +0x0f,0xff,0x28,0x1b,0xec,0xff,0x25,0x1b,0x94,0xa8,0x24,0x0b,0x20,0x4f,0x24,0x04, +0x0f,0xff,0xa8,0x1b,0xc0,0x4e,0xfc,0x34,0xa0,0xa8,0x28,0x04,0x02,0x1c,0x00,0x01, +0x40,0x46,0x54,0x04,0xc0,0x5e,0xcd,0x0a,0xb5,0x08,0x23,0x1b,0xcd,0x04,0x5c,0x25, +0x1b,0x10,0x4e,0xfc,0xcd,0x0a,0xd5,0x34,0xcd,0x0f,0x20,0x02,0x00,0x25,0x1b,0xf0, +0x4b,0xcd,0x1a,0x20,0x03,0x00,0x25,0x1b,0xcd,0x05,0x8a,0x70,0xcd,0x17,0x20,0x04, +0x00,0x25,0xcd,0x05,0x81,0x04,0xcd,0x08,0x20,0xf0,0x63,0xcd,0x0e,0x20,0x05,0xcd, +0x0f,0x81,0x00,0xcd,0x10,0x20,0x06,0xcd,0x0f,0x81,0x00,0xcd,0x10,0x20,0x07,0xcd, +0x0f,0x60,0x10,0x66,0xcd,0x0e,0x20,0x08,0xcd,0x0f,0x81,0x20,0xcd,0x10,0x40,0x09, +0xcd,0x0f,0x81,0x00,0xcd,0x10,0x40,0x0a,0xcd,0x0f,0x60,0xc0,0xcd,0x0f,0x20,0x0b, +0xcd,0x0f,0x81,0x20,0xcd,0x10,0x40,0x0c,0xcd,0x0f,0x81,0x00,0xcd,0x10,0x20,0x0d, +0xcd,0x10,0x83,0x00,0xcd,0x0f,0x20,0x0e,0xcd,0x10,0x83,0x00,0xcd,0x0f,0x20,0x0f, +0xcd,0x10,0x83,0x00,0xcd,0x0f,0x20,0x10,0x00,0x25,0xcd,0x05,0xa5,0x44,0x10,0xa1, +0xfc,0x34,0x08,0xcd,0x05,0xac,0x60,0x21,0x1b,0xf0,0x4b,0xa4,0x14,0x2e,0xcd,0x05, +0x83,0x7c,0x21,0x1b,0x20,0x89,0xcd,0x0a,0x84,0x6c,0xf0,0x4b,0xcd,0x06,0xa4,0x2c, +0xcd,0x04,0x70,0xcd,0x08,0x8f,0x00,0x01,0x00,0x25,0x1b,0x70,0x4e,0x7c,0x35,0xcd, +0x08,0x10,0xcd,0x04,0x50,0xcd,0x05,0x8a,0x10,0x04,0xcd,0x06,0x81,0x84,0x30,0xeb, +0x1b,0xcd,0x08,0xc5,0x7c,0x20,0x1b,0x30,0x00,0xa0,0x1b,0x80,0x50,0xcd,0x06,0x89, +0x78,0xcd,0x05,0x85,0x28,0xab,0xcd,0x06,0x86,0x34,0x0c,0x04,0x21,0x1b,0xf8,0xcd, +0x0b,0x28,0x20,0xcd,0x27,0x28,0x10,0xcd,0x25,0x28,0x21,0xcd,0x21,0x24,0x80,0xcd, +0x0b,0x81,0x1c,0x09,0xcd,0x04,0x30,0xa8,0xc4,0xcd,0x0a,0x30,0xcd,0x07,0x8b,0x0c, +0xcd,0x10,0x30,0xcd,0x08,0x81,0x24,0xcd,0x28,0x30,0xcd,0x08,0x81,0x2c,0xcd,0x24, +0x30,0x00,0xaf,0xc4,0x04,0xcd,0x0c,0x81,0x14,0xcd,0x1e,0x5c,0xcd,0x06,0x81,0x60, +0xcd,0x2c,0x58,0xcd,0x11,0x82,0x60,0xcd,0x17,0x81,0x34,0xcd,0x08,0x81,0x00,0x0b, +0xcd,0x2b,0x5c,0xcd,0x11,0x83,0x14,0xcd,0x19,0x2c,0xcd,0x0f,0x83,0x18,0xcd,0x1f, +0x82,0x68,0xcd,0x24,0x81,0x04,0xcd,0x0c,0x81,0x00,0xcd,0x26,0x30,0xcd,0x06,0x81, +0x04,0xcd,0x24,0x2c,0xf0,0x4b,0xa4,0x14,0xe0,0x4b,0xcd,0x0a,0x9a,0x38,0x20,0x4f, +0xcd,0x0b,0x9a,0x38,0x4e,0x20,0x0b,0x04,0x30,0xcd,0x12,0x9a,0x38,0xe0,0x9b,0x20, +0x14,0xcd,0x14,0x81,0xce,0x28,0xcd,0x09,0xc0,0x40,0xf0,0x80,0x1a,0x60,0xfc,0x00, +0x1b,0x64,0xfc,0x04,0x1b,0x00,0x28,0x78,0xcd,0x06,0x81,0xd8,0x5c,0x00,0x24,0x1b, +0x00,0x0f,0xa4,0x1b,0x90,0x40,0xa0,0x04,0x80,0x00,0x00,0x1a,0xe4,0xff,0x21,0x1b, +0x84,0x80,0x21,0xcd,0x05,0xb8,0x00,0xcd,0x05,0xa7,0x1c,0xcd,0x07,0xc1,0x40,0x11, +0x1c,0x80,0x02,0x00,0x08,0x20,0x0e,0xe0,0x29,0x80,0x18,0xcd,0x05,0xb9,0x4c,0xcd, +0x1b,0x54,0x90,0xcd,0x05,0x96,0x68,0x24,0x1b,0x00,0x8f,0xcd,0x0a,0x58,0xcd,0x0c, +0x38,0xcd,0x05,0xae,0x3c,0xcd,0x08,0xd2,0x08,0xcd,0x0b,0x90,0x2c,0xe0,0x03,0x10, +0x14,0xcd,0x05,0x97,0x10,0x13,0xcd,0x06,0x97,0x10,0xe0,0x0b,0x18,0x14,0x01,0x90, +0x80,0x1a,0xe0,0x4b,0x44,0x14,0xcd,0x08,0x8d,0x50,0xa0,0x1c,0x80,0x02,0x01,0xa8, +0x80,0x1a,0x90,0x26,0x10,0x14,0xe0,0x33,0x00,0x14,0x06,0x20,0x28,0x0e,0x5b,0x67, +0x25,0x1b,0x9a,0xcd,0x07,0xad,0x2c,0xa4,0x18,0xcd,0x0b,0x8f,0x54,0x50,0x24,0x14, +0x00,0x40,0xcd,0x05,0xb8,0x2c,0x14,0xf1,0xff,0x21,0x1b,0x8c,0x48,0x20,0x0b,0xe5, +0x1d,0xc0,0x02,0x84,0x30,0x00,0x1a,0x06,0x30,0x20,0x0e,0x84,0x20,0xcd,0x06,0x08, +0xab,0x1c,0x80,0x02,0x84,0x28,0x00,0x1a,0x90,0x26,0x00,0x14,0x5b,0x67,0x51,0xcd, +0x06,0xb2,0x24,0x03,0x48,0x14,0x4a,0x49,0xcd,0x04,0x48,0xa4,0x17,0xa4,0x18,0x55, +0x1b,0x00,0x40,0x4d,0x1b,0x5a,0x41,0xcd,0x06,0x58,0xcd,0x04,0x78,0x80,0x48,0x20, +0x14,0x30,0x41,0xcd,0x16,0x58,0xe0,0x93,0x00,0xcd,0x05,0x97,0x7c,0x1a,0x00,0x01, +0x1b,0x00,0x20,0x10,0x14,0x06,0x20,0x20,0x0e,0xe0,0x2b,0x00,0x14,0x4a,0xcd,0x07, +0x40,0x5a,0x89,0xcd,0x06,0x58,0x90,0x40,0xcd,0x04,0x44,0x20,0xcd,0x06,0xae,0x4c, +0x40,0xcd,0x07,0x44,0x28,0x00,0x1a,0x06,0x28,0xcd,0x07,0x81,0x14,0x20,0xcd,0x08, +0x81,0x14,0x4d,0xcd,0x07,0x81,0x14,0x54,0x14,0x3a,0xcd,0x09,0x81,0x14,0x49,0x1b, +0x00,0x40,0x51,0x1b,0x2a,0xcd,0x08,0x81,0x14,0x3b,0xcd,0x06,0x81,0x14,0x40,0xcd, +0x10,0x50,0x38,0x00,0x1a,0x06,0x38,0x20,0x0e,0xe0,0xab,0xcd,0x12,0x81,0x14,0x10, +0x3e,0x00,0x14,0x3a,0xcd,0x07,0x40,0x2a,0xcd,0x0b,0x81,0x14,0xcd,0x0c,0x44,0xcd, +0x04,0x34,0xcd,0x04,0x48,0xcd,0x04,0x2c,0xcd,0x05,0xa7,0x3c,0x00,0xcd,0x06,0x82, +0x38,0xcd,0x0c,0xac,0x44,0xcd,0x04,0x34,0xcd,0x05,0x90,0x28,0x3e,0x00,0x14,0xcd, +0x05,0x82,0x04,0xcd,0x09,0x18,0xa0,0xcd,0x05,0x18,0xcd,0x08,0x82,0x60,0x70,0xcd, +0x05,0x93,0x18,0x28,0x0e,0xcd,0x05,0xc3,0x34,0x40,0x3e,0xcd,0x06,0x8b,0x40,0x56, +0xfc,0x34,0x01,0x88,0xcd,0x06,0x0c,0xc0,0xcd,0x04,0x0c,0x10,0xcd,0x07,0xaa,0x1c, +0xcd,0x15,0x81,0xd3,0x70,0xcd,0x0e,0x92,0x5c,0x30,0x3e,0x1c,0x14,0xcd,0x30,0x84, +0x40,0x30,0x1d,0xcd,0x52,0x84,0x40,0x3b,0x1d,0xcd,0x81,0x12,0x84,0x40,0xcd,0x05, +0x81,0x14,0xcd,0x81,0x47,0x84,0x40,0xcd,0x08,0x82,0x60,0xcd,0x78,0x84,0x40,0xcd, +0x0c,0x96,0x4c,0xbd,0x1d,0x80,0x02,0xe0,0x4b,0x54,0x14,0xcd,0x0c,0x84,0x40,0x52, +0x63,0xcd,0x08,0x84,0x40,0xa4,0x17,0xad,0x1c,0x29,0x1b,0xaa,0xcd,0x08,0x84,0x40, +0x48,0xcd,0x26,0x84,0x40,0xc8,0xcd,0x0b,0x84,0x40,0x52,0x63,0x45,0xcd,0x07,0x83, +0x2c,0x4c,0x14,0x1a,0xcd,0x07,0x83,0x2c,0xad,0x1c,0x51,0x1b,0x00,0x40,0x49,0x1b, +0xcd,0x08,0x84,0x00,0xcd,0x08,0x84,0x40,0x20,0xcd,0x10,0x83,0x2c,0xcd,0x08,0x84, +0x40,0x9b,0xcd,0x16,0x84,0x40,0x1a,0xcd,0x07,0x40,0x4a,0xa9,0xcd,0x0a,0x83,0x2c, +0xcd,0x11,0x44,0xcd,0x07,0x84,0x40,0xcd,0x05,0x81,0x14,0xcd,0x07,0x84,0x40,0xcd, +0x0a,0x81,0x14,0x48,0xcd,0x0f,0x81,0x14,0x4d,0xcd,0x0a,0x81,0x14,0xcd,0x07,0x84, +0x40,0xcd,0x11,0x85,0x10,0xcd,0x08,0x84,0x40,0xcd,0x13,0x85,0x54,0x10,0x3e,0xcd, +0x16,0x81,0x14,0xcd,0x0c,0x44,0xcd,0x1e,0x84,0x40,0xcd,0x06,0xb0,0x70,0xfc,0x4b, +0x24,0x0b,0x80,0x48,0xa0,0xcd,0x05,0x20,0xcd,0x05,0x82,0x04,0x00,0xcd,0x0a,0x82, +0x54,0xcd,0x0d,0x84,0x34,0x4c,0xcd,0x0b,0x84,0x34,0x94,0xcd,0x0b,0x84,0x34,0x1c, +0xcd,0x2e,0x84,0x34,0x90,0x06,0x00,0xcd,0x05,0xb7,0x40,0x52,0x63,0x29,0x1b,0xaa, +0x48,0xcd,0x06,0x88,0x38,0xad,0x1c,0xcd,0x0c,0x88,0x38,0x20,0x14,0xcd,0x06,0x9e, +0x74,0xcd,0x0e,0x81,0x48,0x06,0x00,0x20,0x0e,0x0a,0x40,0xc0,0x10,0x0e,0x00,0xa0, +0x17,0xcd,0x04,0x4c,0xcd,0x05,0xa6,0x24,0x00,0x24,0x0e,0xff,0x7f,0x21,0xcd,0x05, +0x9e,0x6c,0x08,0x0c,0x00,0x01,0x94,0x00,0xcd,0x06,0xbf,0x2c,0xcd,0x04,0x2c,0xcd, +0x06,0xa6,0x60,0xcd,0x0a,0x96,0x10,0x00,0x80,0xcd,0x06,0xbb,0x60,0xcd,0x09,0x8e, +0x7c,0x20,0x80,0x1a,0x34,0x00,0x21,0x1b,0x01,0x28,0x80,0x1a,0x54,0x28,0x14,0xcd, +0x09,0xa0,0x20,0xcd,0x05,0x8f,0x38,0x58,0x00,0x01,0xe0,0x03,0x10,0x14,0xda,0x1f, +0xc0,0x02,0xe0,0x23,0x00,0x14,0x60,0x06,0x01,0x1b,0x26,0x00,0xcd,0x06,0xa5,0x18, +0xcd,0x08,0xbd,0x38,0xf0,0x83,0x21,0x14,0x80,0xcd,0x05,0x50,0x24,0x0e,0xe8,0x03, +0xcd,0x06,0xca,0x38,0xcd,0x08,0x9e,0x6c,0x11,0x1e,0xcd,0x06,0x91,0x08,0x5c,0x06, +0x21,0x1b,0x50,0xcd,0x0b,0xa9,0x4c,0xcd,0x11,0xa1,0x08,0xcd,0x07,0xb1,0x54,0x34, +0xcd,0x05,0x8f,0x54,0xcd,0x06,0x28,0xcd,0x04,0x70,0xcd,0x04,0x2c,0x60,0xcd,0x0b, +0xaa,0x08,0x25,0x1e,0xc0,0x02,0x90,0xcd,0x17,0xa9,0x60,0xcd,0x05,0xa0,0x28,0x88, +0xcd,0x06,0xa0,0x20,0x3a,0xcd,0x04,0x14,0xd8,0x80,0x1a,0x80,0x20,0x20,0x14,0x01, +0xe0,0x80,0x1a,0xcd,0x04,0x68,0x01,0xe8,0x80,0x1a,0xcd,0x06,0x91,0x0c,0x80,0x1a, +0x5c,0x00,0x3d,0x1b,0x02,0x1c,0x00,0x01,0xf0,0x38,0x9c,0x14,0x0c,0x02,0xcd,0x06, +0xcc,0x68,0x00,0x00,0x21,0x1b,0x42,0x1e,0xcd,0x06,0xb1,0x28,0xcd,0x04,0x40,0x0c, +0x02,0x29,0xcd,0x05,0xcc,0x70,0xa0,0x20,0x28,0x14,0x06,0x40,0x24,0x0e,0x94,0x50, +0x00,0xcd,0x05,0x48,0xfc,0x43,0x04,0x0b,0x00,0x08,0x00,0x14,0x38,0x00,0xcd,0x06, +0xcd,0x10,0xcd,0x04,0x14,0x70,0x46,0x24,0x15,0x08,0xcd,0x05,0x48,0xcd,0x06,0x81, +0x60,0xcd,0x06,0x54,0xcd,0x06,0x1c,0x60,0x47,0xfc,0x34,0x08,0xcd,0x07,0x81,0xba, +0x5c,0x22,0xcd,0x0b,0x34,0xcd,0x05,0x81,0x0c,0xcd,0x07,0xc6,0x1c,0x6c,0x02,0x05, +0x1b,0x5a,0x1e,0x80,0x02,0x10,0x20,0x0c,0x14,0x12,0x02,0x05,0x1b,0xcd,0x04,0x08, +0x0e,0xcd,0x05,0x08,0x08,0x14,0x06,0x10,0xcd,0x07,0x2c,0xcd,0x07,0x81,0xad,0x68, +0x10,0xcd,0x07,0x5c,0x04,0x00,0x28,0x0e,0xcd,0x08,0x81,0x10,0x30,0x08,0x04,0x14, +0xcd,0x08,0x81,0x00,0x04,0x08,0x24,0xcd,0x05,0x18,0x84,0x50,0x20,0x0b,0x80,0x48, +0xa0,0xcd,0x05,0xc6,0x54,0xcd,0x05,0xb4,0x0c,0x10,0x00,0x1a,0xcd,0x04,0x3c,0x2c, +0x00,0x25,0xcd,0x09,0x81,0x04,0x90,0x40,0xfc,0x34,0x01,0x90,0x00,0x01,0xe0,0x03, +0x14,0x14,0x04,0x00,0x24,0x0e,0x10,0x06,0x14,0xcd,0x05,0x81,0x58,0x0c,0x02,0x01, +0xcd,0x05,0x24,0x00,0x20,0x04,0xcd,0x05,0x28,0x06,0x08,0x28,0x0e,0x80,0xf0,0xa1, +0x14,0x84,0x48,0x20,0x0b,0x1f,0x00,0x25,0xcd,0x05,0xd4,0x18,0xcd,0x08,0x9b,0x10, +0x00,0x00,0x25,0x1b,0x94,0x28,0x00,0x1a,0x04,0x28,0x24,0x0e,0x0a,0x02,0x01,0x1b, +0x08,0x02,0x29,0x1b,0xa0,0x20,0x28,0x14,0x00,0x20,0x00,0x14,0x06,0x50,0x28,0x0e, +0xa4,0x48,0x28,0x0b,0xcd,0x05,0xab,0x40,0x50,0xa0,0x04,0xfc,0x4b,0x24,0x0b,0x30, +0x48,0xcd,0x06,0xae,0x0c,0xcd,0x0c,0xb5,0x14,0x06,0x08,0xcd,0x07,0x0c,0x08,0x00, +0x1a,0xcd,0x04,0x44,0x2d,0x00,0x25,0x1b,0xcd,0x05,0x7c,0x08,0xcd,0x06,0x81,0x24, +0x02,0xb0,0x3e,0x01,0xe0,0x2b,0x00,0x14,0x0c,0x02,0x01,0x1b,0x1f,0xcd,0x05,0x1c, +0xcd,0x06,0x82,0x18,0xf0,0x43,0xa0,0x14,0xcd,0x06,0x81,0x44,0xcd,0x06,0x20,0xcd, +0x05,0xd1,0x34,0x00,0x01,0x1b,0xcd,0x08,0x82,0x24,0x00,0x20,0x00,0xcd,0x05,0xd0, +0x30,0x14,0x09,0xcd,0x06,0x86,0x24,0xf0,0x4e,0x7c,0x35,0xcd,0x06,0x81,0xa9,0x2c, +0x21,0xcd,0x05,0x89,0x0c,0x50,0x4e,0x24,0x14,0xc1,0x1e,0x80,0x02,0xcd,0x08,0xc1, +0x3c,0x50,0x4e,0xcd,0x06,0xa2,0x50,0xcd,0x05,0xb9,0x68,0x10,0x24,0x0e,0xf0,0x4b, +0x24,0x14,0x94,0x10,0xcd,0x08,0x1c,0xa4,0x14,0x10,0x2e,0x14,0xcd,0x05,0xb8,0x70, +0xcd,0x05,0x83,0x10,0x1c,0xcd,0x06,0x74,0xe0,0x8b,0x20,0x14,0xc6,0x02,0x01,0x1b, +0x82,0x00,0x25,0x1b,0xd0,0x12,0xc0,0x02,0xcd,0x04,0x74,0xcd,0x11,0x83,0x68,0xcd, +0x08,0xd0,0x48,0x3b,0x04,0x14,0x6c,0x02,0x01,0x1b,0x4f,0x1f,0xcd,0x06,0x28,0xd9, +0xcd,0x07,0x86,0x20,0xcd,0x04,0x18,0x12,0xcd,0x0b,0x18,0x04,0x38,0x24,0x0e,0xc6, +0xcd,0x0b,0x84,0x50,0x30,0x8e,0xfc,0x34,0x08,0xf8,0xcd,0x06,0x44,0x44,0xcd,0x05, +0xd2,0x6c,0x21,0xcd,0x05,0x6c,0x20,0x00,0x25,0xcd,0x05,0xa7,0x38,0x0b,0x00,0x21, +0x1b,0x64,0x30,0x00,0x1b,0x8a,0x88,0xcd,0x06,0x88,0x3c,0x90,0x40,0x20,0x14,0xfc, +0x43,0x20,0x0b,0x80,0x38,0x20,0x14,0x04,0x40,0x28,0x0e,0xfc,0x4b,0x20,0x0b,0x10, +0x46,0xa0,0x14,0xf0,0x4b,0x24,0x14,0xb0,0x4e,0xfc,0x34,0x00,0x40,0x20,0x14,0x04, +0xcc,0x3f,0x01,0xa4,0x40,0x00,0x1a,0x65,0x00,0x99,0x19,0x14,0x00,0x83,0x19,0x16, +0x08,0x81,0x19,0x14,0x08,0x83,0x19,0x45,0x10,0x99,0x19,0x00,0x10,0x83,0xcd,0x09, +0x81,0x85,0x24,0x00,0x06,0xec,0x0e,0xcd,0x06,0x9e,0x24,0x70,0x1b,0x00,0x10,0x79, +0x0e,0x09,0x20,0x80,0x19,0xb4,0x09,0x75,0x2b,0xe8,0xf1,0x78,0x14,0x00,0xfc,0xbf, +0x01,0xcd,0x08,0x0c,0xf0,0xe3,0xf0,0x34,0xf0,0xdb,0xec,0x14,0x02,0xdc,0x3f,0x01, +0xe0,0x19,0x01,0xcd,0x05,0xb4,0x18,0x0f,0x20,0x80,0x19,0x1c,0x4e,0x20,0x0b,0x10, +0x41,0xcd,0x06,0x81,0x10,0x10,0x46,0x20,0x14,0x44,0x30,0x00,0x1b,0x80,0x20,0x28, +0x14,0xcd,0x05,0x81,0x60,0x50,0x28,0x14,0xfc,0x4b,0x20,0x0b,0x00,0x40,0x20,0xcd, +0x05,0x81,0x1c,0x04,0x40,0x20,0x0e,0x00,0xd0,0xbf,0x01,0x84,0x50,0x00,0x1a,0xdd, +0x1e,0x80,0x02,0xf0,0x8b,0x44,0x14,0x10,0x21,0xcd,0x07,0xf2,0x18,0x27,0xcd,0x06, +0xa7,0x20,0x22,0x00,0x01,0xcd,0x05,0xa7,0x24,0x38,0x00,0x25,0xcd,0x05,0x84,0x6c, +0x90,0x20,0x24,0xcd,0x06,0x87,0x24,0x48,0x24,0x0e,0x70,0x4e,0x24,0x15,0x00,0x20, +0x04,0x14,0xcd,0x05,0x87,0x2c,0x08,0xcd,0x07,0x83,0x40,0xcd,0x05,0xb0,0x44,0x24, +0x0e,0x10,0x4e,0xfc,0x34,0xe0,0x2b,0x00,0x14,0x04,0x64,0x3c,0xcd,0x05,0xa0,0x30, +0x84,0x08,0x00,0x1a,0x49,0x1e,0x80,0xcd,0x05,0xb9,0x28,0x01,0x00,0xf8,0x0e,0x3a, +0x00,0x21,0x1b,0x5c,0xcd,0x07,0xba,0x14,0xcd,0x06,0xd4,0x78,0xf0,0x0e,0xcd,0x06, +0xba,0x2c,0xec,0x0e,0xcd,0x05,0xcf,0x6c,0x00,0xc4,0x0e,0x0a,0xcd,0x0b,0x87,0x58, +0x01,0x00,0x94,0x0e,0xf0,0x43,0xa4,0x14,0xcd,0x08,0x84,0x6c,0xcd,0x06,0xb2,0x78, +0x25,0x1b,0x0e,0xcd,0x07,0x10,0xf0,0x38,0x1c,0xcd,0x07,0x14,0xcd,0x06,0x89,0x28, +0xe0,0x4b,0x20,0x14,0xff,0x01,0x25,0x1b,0x2c,0xcd,0x07,0xcd,0x78,0x44,0x4e,0x20, +0x0b,0x90,0x40,0x24,0x06,0x20,0x4f,0x28,0x04,0x05,0x00,0x25,0x1b,0x94,0x50,0x24, +0x0b,0x90,0x40,0xa0,0x04,0x44,0x46,0x2c,0x0b,0x80,0x58,0x20,0x06,0x20,0x47,0x20, +0xcd,0x06,0x18,0x40,0x24,0x0b,0x90,0x58,0xa4,0x04,0x34,0x46,0x20,0x0b,0x44,0x4e, +0x2c,0x0b,0xa0,0x40,0xa0,0x04,0x90,0x58,0xcd,0x04,0x38,0x24,0x04,0x05,0x00,0x29, +0x1b,0xa4,0x48,0x28,0x0b,0xa0,0x58,0xa8,0x04,0x54,0x4e,0xcd,0x05,0x8d,0x40,0x04, +0x44,0x56,0x24,0x0b,0xa0,0x48,0x28,0x06,0x20,0x57,0x2c,0xcd,0x06,0x20,0x58,0x28, +0x0b,0xa0,0x48,0xa4,0x04,0xb4,0x5e,0x28,0x0b,0x80,0x50,0xa0,0x04,0x06,0x00,0x28, +0x0e,0x80,0x50,0x20,0x06,0x10,0xcd,0x08,0xce,0x5c,0x78,0xcd,0x06,0xce,0x5c,0xcd, +0x08,0x8a,0x4c,0x54,0x28,0xcd,0x06,0xd7,0x4c,0xcd,0x05,0x8b,0x24,0x00,0xcd,0x06, +0xb4,0x58,0x34,0xcd,0x05,0x0c,0xcd,0x0a,0xcf,0x6c,0x42,0xcd,0x0b,0x1c,0x40,0xcd, +0x0b,0x0c,0x3c,0xcd,0x0b,0x0c,0x32,0xcd,0x0b,0x0c,0xcd,0x05,0x8a,0x2c,0xcd,0x07, +0x0c,0x3a,0xcd,0x0b,0x0c,0xfc,0x63,0x24,0x0b,0x90,0x00,0xcd,0x06,0x8a,0x7c,0x48, +0x00,0x29,0x1b,0x00,0x00,0x35,0xcd,0x05,0xb3,0x2c,0xcd,0x04,0x64,0xcd,0x08,0x1c, +0xc8,0x00,0xcd,0x06,0xb3,0x40,0xc0,0x00,0x04,0xcd,0x05,0x18,0xe0,0x6b,0x24,0x14, +0x48,0x01,0xcd,0x07,0xb0,0x0c,0x08,0x20,0x14,0xcd,0x04,0x10,0x88,0xcd,0x0f,0x10, +0xc8,0xcd,0x0b,0x10,0xf0,0x63,0x30,0x14,0xcd,0x05,0x81,0x24,0x60,0xfc,0x34,0x04, +0x90,0xcd,0x08,0xde,0x48,0x29,0xcd,0x05,0xca,0x7c,0x22,0x00,0x25,0x1b,0xcd,0x04, +0x64,0xcd,0x04,0x58,0x24,0xcd,0x07,0x0c,0xa4,0x48,0x00,0x1a,0x4e,0x03,0xcd,0x0a, +0x18,0x80,0x07,0xcd,0x06,0x14,0x30,0xcd,0x0b,0x20,0xd0,0x04,0xcd,0x0a,0x0c,0xd2, +0xcd,0x0b,0x0c,0xd4,0xcd,0x0b,0x0c,0xd6,0xcd,0x0b,0x0c,0x5c,0x06,0xcd,0x04,0x0c, +0x28,0xcd,0x05,0xac,0x70,0x94,0x50,0x00,0x1a,0x60,0xcd,0x0b,0x10,0x90,0x50,0x00, +0x1a,0x66,0xcd,0x08,0x10,0x0d,0x25,0xcd,0x05,0x9d,0x54,0xcd,0x04,0x24,0xcd,0x0c, +0x8d,0x54,0xcd,0x05,0xb4,0x5c,0xcd,0x07,0x94,0x44,0xcd,0x06,0xdb,0x1c,0x4d,0x1b, +0x60,0x9f,0xfc,0x34,0x08,0x90,0xcd,0x06,0xfd,0x4c,0x04,0x28,0x48,0x0e,0x10,0x2e, +0x14,0xcd,0x05,0x8a,0x00,0x70,0x8e,0xfc,0x34,0x08,0x70,0xcd,0x06,0x18,0x40,0xcd, +0x05,0x92,0x28,0xcd,0x08,0xbd,0x40,0x24,0x0b,0xf0,0x93,0x20,0x04,0x80,0x48,0xa4, +0x04,0xff,0x01,0x21,0xcd,0x05,0xe8,0x70,0x9c,0xcd,0x08,0xaf,0x20,0x96,0x48,0x0b, +0x01,0x18,0x00,0x01,0x84,0x00,0x00,0x1a,0x9d,0xcd,0x07,0x14,0x02,0xd0,0xcd,0x06, +0x8d,0x34,0xf0,0x43,0x24,0x04,0x48,0x03,0xcd,0x0a,0xd9,0x54,0xcd,0x05,0x83,0x7c, +0xcd,0x05,0x86,0x04,0x30,0x0e,0xf0,0x63,0xa0,0xcd,0x05,0xd2,0x40,0x04,0x88,0xcd, +0x06,0xb4,0x70,0x80,0x20,0x80,0x18,0xf0,0x63,0xb0,0x14,0xfc,0x63,0x20,0x0b,0xcd, +0x04,0x24,0xcd,0x06,0xb2,0x6c,0xcd,0x04,0x2c,0x24,0x0e,0xcd,0x05,0x84,0x1c,0xcd, +0x07,0x86,0x3c,0x80,0x48,0xfc,0x34,0x02,0x4c,0xcd,0x06,0x34,0xc0,0x20,0x04,0x14, +0xcd,0x04,0x60,0x88,0x01,0xcd,0x07,0x8c,0x74,0x08,0x00,0x14,0x0e,0x40,0x24,0x0e, +0xcd,0x05,0xb4,0x0c,0x03,0x20,0xcd,0x05,0x83,0x6c,0x80,0x08,0x20,0x14,0x0e,0x00, +0x24,0x0e,0x0e,0xcd,0x08,0x3c,0xcd,0x07,0x8e,0x0c,0xc8,0x01,0x01,0x1b,0xcd,0x05, +0x30,0xcd,0x05,0x8c,0x4c,0x24,0xcd,0x05,0xb1,0x34,0xcd,0x04,0x34,0xcd,0x04,0x10, +0x50,0x46,0xfc,0x34,0x04,0xcd,0x07,0xea,0x34,0xcd,0x0c,0xb1,0x50,0x5c,0x20,0xcd, +0x07,0xf9,0x5c,0x20,0x00,0xcd,0x05,0x84,0x28,0x80,0x00,0xcd,0x06,0xb2,0x28,0xf0, +0xcd,0x04,0x30,0xcd,0x07,0xb2,0x10,0xfc,0x63,0x00,0x0b,0x00,0x20,0x00,0x14,0x48, +0x00,0x21,0x1b,0x05,0x00,0x25,0x1b,0x80,0x00,0xcd,0x06,0x82,0x44,0x90,0x40,0xcd, +0x07,0x8d,0x30,0x00,0x20,0x0e,0x20,0x47,0xfc,0x34,0x04,0xcd,0x07,0x81,0xee,0x78, +0x32,0xcd,0x05,0x88,0x28,0xcd,0x06,0x8e,0x58,0xcd,0x06,0x89,0x1c,0xcd,0x0a,0xdd, +0x2c,0xcd,0x05,0x85,0x70,0x20,0x20,0x14,0x07,0x21,0x80,0x02,0x34,0x41,0x00,0x1a, +0xcd,0x08,0x78,0xcd,0x09,0xbc,0x08,0x00,0x20,0x14,0xcd,0x10,0x81,0x14,0xcd,0x0c, +0x1c,0xcd,0x04,0x14,0x88,0xcd,0x09,0x81,0x28,0x24,0x0e,0xcd,0x09,0x85,0x7c,0x00, +0x20,0x14,0x67,0xcd,0x07,0x38,0x00,0x8c,0xbe,0xcd,0x06,0x82,0x4c,0xf0,0xfd,0x34, +0x04,0x18,0xcd,0x06,0xca,0x08,0x42,0x00,0x21,0x1b,0xc8,0xcd,0x0b,0x8f,0x6c,0xcd, +0x05,0x8c,0x10,0x20,0x20,0x14,0x90,0x40,0x20,0x14,0x05,0x00,0x31,0x1b,0x3c,0x00, +0x25,0x1b,0x88,0x01,0xcd,0x06,0x8a,0x40,0x06,0x48,0x24,0x0e,0x94,0x40,0xcd,0x07, +0x87,0x58,0xcd,0x0d,0x30,0x24,0xcd,0x05,0x82,0x04,0x80,0x48,0xcd,0x06,0x87,0x30, +0x48,0x03,0xcd,0x06,0x20,0x0e,0x40,0x24,0x0e,0xcd,0x0c,0x2c,0xcd,0x04,0x08,0xcd, +0x05,0xe9,0x24,0x40,0xcd,0x0c,0x84,0x20,0xcd,0x04,0x18,0x04,0xcd,0x0a,0x83,0x40, +0x40,0x24,0x0e,0xcd,0x05,0x81,0x48,0xcd,0x05,0x0c,0xcd,0x07,0x8f,0x58,0xcd,0x07, +0xc5,0x68,0xcd,0x18,0x83,0x48,0xcd,0x0e,0x4c,0xcd,0x08,0x83,0x30,0xcd,0x06,0x28, +0xcd,0x05,0x83,0x60,0xcd,0x07,0x8e,0x14,0xcd,0x0c,0x83,0x60,0xe1,0xcd,0x07,0x82, +0x14,0x42,0x00,0x01,0x1b,0xcd,0x05,0x82,0x4c,0xcd,0x05,0x90,0x48,0x24,0x0e,0x90, +0x20,0x00,0x14,0xcd,0x0d,0x83,0x6c,0xcd,0x07,0xb7,0x58,0xfc,0x4b,0x00,0x0b,0x48, +0x00,0xcd,0x04,0x28,0xcd,0x04,0x20,0xcd,0x06,0x83,0x68,0xc0,0xcd,0x08,0x83,0x68, +0x08,0xcd,0x12,0x82,0x08,0x06,0x40,0xcd,0x3a,0x83,0x7c,0xcd,0x05,0x83,0x14,0x01, +0xcd,0x06,0x94,0x58,0xcd,0x08,0x82,0x38,0xcd,0x08,0x83,0x6c,0xa0,0x40,0x20,0x14, +0xcd,0x0a,0x81,0x3c,0xcd,0x1e,0x28,0x42,0xcd,0x05,0x87,0x58,0xcd,0x06,0x92,0x20, +0x80,0xcd,0x1b,0x84,0x20,0xcd,0x0c,0x92,0x58,0xcd,0x0a,0x82,0x4c,0x24,0x0e,0x3f, +0xcd,0x07,0xe1,0x60,0xcd,0x08,0xf2,0x58,0xcd,0x08,0xb9,0x44,0x3c,0xcd,0x0b,0x88, +0x30,0xcd,0x09,0x93,0x1c,0x00,0x24,0x0e,0xd8,0x02,0xcd,0x0e,0x30,0xcd,0x08,0xd4, +0x24,0xe8,0x1f,0xcd,0x06,0x8f,0x24,0xe2,0xcd,0x04,0x08,0x9b,0x4c,0x14,0x01,0x00, +0xcc,0x0e,0xcd,0x06,0x82,0x10,0xc8,0xcd,0x05,0x81,0x34,0xcd,0x06,0x99,0x7c,0xcd, +0x0a,0x97,0x2c,0xcd,0x05,0x8e,0x38,0xcd,0x0f,0xb7,0x54,0x08,0x02,0x3d,0x1b,0x01, +0x90,0xcd,0x06,0xe0,0x74,0x30,0x3e,0xcd,0x06,0xd4,0x6c,0x54,0x28,0x14,0xcd,0x05, +0x60,0xc6,0x02,0xcd,0x06,0xb9,0x60,0x04,0xcd,0x06,0x84,0x18,0xcd,0x0a,0x89,0x08, +0x28,0x20,0x14,0x2e,0x21,0xcd,0x06,0x82,0x2c,0x4a,0x03,0xcd,0x0a,0x98,0x20,0x37, +0x21,0xcd,0x06,0xb7,0x4c,0xcd,0x04,0x14,0xcd,0x05,0x83,0x14,0xcd,0x0b,0x14,0xcd, +0x05,0x85,0x3c,0xcd,0x0c,0xd0,0x30,0xc8,0xcd,0x07,0x82,0x83,0x30,0xcd,0x04,0x0c, +0xd0,0xcd,0x06,0x0c,0xcd,0x04,0x68,0x4c,0x03,0x05,0x1b,0x10,0x47,0x20,0x04,0x10, +0x28,0x04,0x14,0x04,0x46,0x24,0x0b,0xcd,0x05,0x85,0x0c,0x0b,0x20,0xcd,0x05,0x81, +0x04,0x44,0x46,0xcd,0x06,0xe0,0x1c,0x49,0xcd,0x0b,0x81,0x08,0x4e,0x03,0xcd,0x0a, +0xd4,0x04,0x84,0x48,0x00,0x1a,0x0e,0x08,0xcd,0x07,0xda,0x1c,0x4c,0x00,0x01,0x10, +0x06,0x00,0x14,0x3f,0xcd,0x07,0x8f,0x70,0x04,0x00,0x24,0x0e,0x1c,0x46,0x28,0x0b, +0x08,0x01,0x05,0x1b,0x10,0x38,0x04,0x14,0xa0,0x08,0x28,0x14,0xcd,0x04,0x20,0x04, +0x50,0x28,0x0e,0xcd,0x04,0x14,0x80,0x4a,0x28,0x09,0xcd,0x04,0x18,0x1c,0x46,0x24, +0x0b,0x90,0x08,0xcd,0x05,0xe0,0x64,0x14,0x00,0xcc,0xbf,0x01,0xa4,0x48,0xcd,0x06, +0xe6,0x44,0xcd,0x0d,0xbb,0x50,0xcd,0x07,0x8b,0x60,0x68,0x22,0xcd,0x08,0x81,0xba, +0x0c,0x29,0x1b,0xcd,0x05,0xe8,0x4c,0x00,0x00,0x00,0x1c,0x56,0x04,0x0b,0x50,0x3e, +0x08,0xcd,0x05,0x81,0x30,0x10,0x10,0x04,0xcd,0x06,0x64,0x08,0x24,0x0e,0x80,0x42, +0x24,0x09,0xf0,0x53,0x28,0xcd,0x05,0x92,0x10,0x80,0x00,0x21,0x1b,0x04,0x00,0x24, +0x0e,0x80,0x08,0x20,0xcd,0x06,0x20,0x40,0x20,0x0e,0x80,0x4a,0x20,0x09,0xcd,0x05, +0xb9,0x40,0x08,0x24,0x14,0x00,0xbc,0xbf,0x01,0x84,0x48,0x00,0x1a,0x50,0x3e,0x00, +0x14,0xe0,0x3b,0x04,0xcd,0x05,0xe0,0x54,0x00,0x00,0x49,0x1b,0x4a,0x23,0xcd,0x06, +0xd8,0x34,0x10,0x3e,0x10,0xcd,0x05,0xd8,0x38,0xe0,0x23,0x04,0x14,0x88,0x00,0x01, +0x1b,0x00,0x38,0x18,0x14,0xcd,0x05,0x1c,0x33,0x00,0x14,0x30,0x3e,0x04,0xcd,0x05, +0xde,0x40,0x2a,0xcd,0x04,0x10,0x0b,0x48,0xcd,0x05,0xa1,0x60,0xcd,0x05,0x0c,0x93, +0xcd,0x04,0x18,0x04,0xcd,0x06,0xd4,0x04,0x03,0xcd,0x06,0x83,0x58,0x10,0xcd,0x04, +0x18,0x03,0xcd,0x04,0x24,0x04,0xcd,0x05,0x9f,0x4c,0x90,0xcd,0x0d,0x18,0x44,0x14, +0xe0,0x93,0x00,0x14,0xec,0xcd,0x04,0x0c,0x8b,0x04,0x14,0x77,0xcd,0x07,0x81,0x6c, +0xe0,0x3b,0x04,0x14,0x08,0x01,0x01,0xcd,0x06,0xe8,0x78,0x38,0x00,0xcd,0x06,0x78, +0x03,0x44,0x14,0x10,0xcd,0x07,0x78,0xcd,0x04,0x74,0xcd,0x04,0x14,0x1b,0x00,0x21, +0x1b,0x50,0x3e,0x10,0x14,0xe0,0x8b,0x08,0xcd,0x05,0x9c,0x4c,0x88,0x00,0x05,0x1b, +0x10,0x38,0x18,0x14,0xb2,0xcd,0x05,0x81,0x28,0x04,0xcd,0x06,0x81,0x28,0x23,0xcd, +0x08,0x81,0x28,0x44,0xcd,0x0a,0x81,0x28,0x8b,0x04,0xcd,0x06,0x97,0x40,0xcd,0x0c, +0x9e,0x08,0xcd,0x07,0x81,0xd7,0x08,0xe0,0x23,0xcd,0x06,0x81,0x40,0xd0,0x03,0x01, +0x1b,0x10,0x23,0xc0,0x02,0x00,0x28,0x00,0x14,0xe0,0x93,0x08,0xcd,0x06,0x81,0x40, +0x10,0x20,0x0e,0x10,0x04,0xcd,0x0a,0x18,0xdc,0xcd,0x07,0x85,0x20,0xcd,0x08,0x34, +0x50,0xcd,0x0b,0x1c,0x10,0x3e,0x20,0x14,0x90,0x04,0x01,0x1b,0x88,0x00,0x05,0xcd, +0x06,0x81,0x70,0x38,0x04,0xcd,0x05,0x81,0x74,0xcd,0x04,0x70,0x24,0xcd,0x08,0x88, +0x50,0xcd,0x07,0x9e,0x2c,0xcd,0x04,0x6c,0x50,0x04,0xcd,0x06,0x28,0x49,0x24,0xc0, +0x02,0x10,0x28,0xcd,0x81,0x32,0x82,0x0c,0x1f,0xcd,0x08,0x81,0x30,0xcd,0x33,0x82, +0x0c,0xcd,0x08,0xdf,0x60,0xcd,0x05,0xec,0x04,0xcd,0x07,0x84,0x20,0x49,0x24,0xc0, +0x02,0xe0,0x03,0xcd,0x38,0x82,0x08,0x18,0xcd,0x06,0x82,0x08,0x33,0xcd,0x08,0x82, +0x08,0x10,0xcd,0x06,0x82,0x08,0x23,0xcd,0x07,0x82,0x08,0xcd,0x08,0x81,0x7c,0x0b, +0x44,0xcd,0x0a,0x82,0x14,0xcd,0x1c,0x82,0x08,0x33,0xcd,0x17,0x82,0x08,0x23,0xcd, +0x12,0x82,0x08,0x61,0xcd,0x08,0x81,0x30,0xcd,0x07,0x34,0xcd,0x54,0x84,0x14,0x4c, +0xcd,0x0f,0x89,0x68,0xcd,0x18,0xd2,0x04,0x7c,0x30,0x04,0x1b,0x10,0xcd,0x05,0xb3, +0x7c,0x04,0x0e,0xcd,0x08,0x81,0xe0,0x64,0x30,0x3e,0x00,0x14,0x5c,0x06,0xcd,0x06, +0x9e,0x1c,0xcd,0x04,0x44,0x07,0x23,0xcd,0x06,0x8a,0x3c,0xf8,0xcd,0x09,0x88,0x68, +0x25,0xcd,0x0a,0x88,0x68,0x4e,0xcd,0x06,0x88,0x68,0x10,0x10,0x04,0xcd,0x05,0xa1, +0x0c,0x04,0x08,0x20,0x0e,0x80,0x52,0x20,0x09,0xcd,0x08,0x98,0x58,0xcd,0x05,0xb5, +0x28,0x08,0xcd,0x08,0x9b,0x58,0x28,0x0e,0x04,0x00,0x20,0x0e,0x80,0x42,0x28,0xcd, +0x05,0x20,0xcd,0x08,0x1c,0x00,0xbc,0xbf,0xcd,0x05,0x9d,0x04,0x50,0x3e,0x14,0xcd, +0x06,0x88,0x68,0xcd,0x07,0x9f,0x44,0xcd,0x05,0x83,0x40,0x8b,0x20,0xcd,0x07,0x83, +0x40,0x20,0xcd,0x07,0x88,0x64,0x10,0xcd,0x06,0x83,0x58,0x23,0x00,0xcd,0x05,0x28, +0x30,0x3e,0x14,0xcd,0x06,0x83,0x1c,0x2b,0xcd,0x0b,0x85,0x3c,0x2b,0x04,0xcd,0x05, +0x81,0x34,0xcd,0x12,0x84,0x14,0xcd,0x0b,0x3c,0x23,0x00,0xcd,0x05,0x58,0xcd,0x0a, +0x84,0x10,0x14,0x14,0xe0,0x23,0x08,0xcd,0x05,0x54,0xcd,0x12,0x86,0x18,0x10,0xcd, +0x05,0x18,0xcd,0x05,0x5c,0x23,0xcd,0x0b,0x84,0x1c,0x23,0xcd,0x68,0x68,0xcd,0x72, +0x81,0x50,0xcd,0x0a,0x84,0x40,0xcd,0x06,0x8d,0x48,0xcd,0x09,0x84,0x40,0x4e,0xcd, +0x0e,0xb8,0x3c,0x8c,0xcd,0x13,0x84,0x40,0x01,0x00,0xc8,0x0e,0xcd,0x05,0x8f,0x50, +0xcd,0x05,0x85,0x30,0xcd,0x1e,0xd8,0x30,0xcd,0x05,0xae,0x28,0xcd,0x05,0xae,0x20, +0xcd,0x06,0x99,0x5c,0xe0,0x43,0xcd,0x06,0x8c,0x64,0x1c,0x96,0x20,0x0b,0x50,0x40, +0x20,0x14,0xe0,0x8b,0xcd,0x06,0xa0,0x10,0xca,0x23,0xc0,0x02,0x40,0x42,0xa0,0x09, +0xfc,0x93,0x24,0x0b,0xf0,0x93,0x48,0x14,0x60,0x97,0xfc,0x34,0x40,0x48,0x24,0x14, +0x04,0xd8,0x3f,0xcd,0x05,0x8d,0x24,0xcd,0x0a,0xaa,0x64,0xcd,0x16,0xa8,0x14,0xcd, +0x08,0xaf,0x10,0xcd,0x08,0xaf,0x0c,0x00,0x00,0x45,0x1b,0x1c,0x8e,0x00,0x0b,0x40, +0x00,0x14,0x14,0x04,0x28,0x20,0x0e,0xdf,0xcd,0x07,0x60,0x04,0x28,0x24,0x0e,0x94, +0x4a,0xa4,0x09,0x90,0x40,0x20,0x06,0xcd,0x05,0xa9,0x14,0xcd,0x07,0xa7,0x1c,0x06, +0x30,0xcd,0x07,0x92,0x0c,0x30,0x00,0x1a,0xf0,0x8b,0x44,0x14,0x1b,0xcd,0x08,0xcb, +0x14,0xbc,0xcd,0x08,0xab,0x70,0xcd,0x16,0xc7,0x30,0x50,0xcd,0x0c,0xb0,0x14,0x0b, +0xcd,0x07,0xb0,0x14,0xcd,0x0b,0xd0,0x24,0xcd,0x0c,0xb0,0x10,0xe0,0x43,0x50,0x14, +0x00,0x00,0x4d,0x1b,0xfc,0x9b,0x20,0x0b,0x00,0x00,0x49,0x1b,0x80,0x38,0x20,0x14, +0x24,0x41,0x00,0x1a,0xfc,0x9b,0x00,0x0b,0x00,0x38,0x18,0x14,0x30,0xa1,0x00,0x14, +0x20,0x01,0x00,0x14,0x1c,0x06,0x00,0x0b,0x50,0x00,0x00,0x14,0x06,0x30,0x54,0xcd, +0x05,0x86,0x50,0xe0,0x03,0x44,0x14,0xcd,0x08,0x81,0x40,0xcd,0x05,0xec,0x38,0x00, +0xcd,0x0a,0x81,0x44,0x80,0xa8,0x20,0x14,0xc0,0x96,0x48,0xcd,0x05,0x81,0x38,0xcd, +0x05,0x81,0x34,0x90,0xcd,0x0a,0xe0,0x34,0xcd,0x06,0x58,0xcd,0x06,0x93,0x68,0x30, +0x46,0x7c,0x35,0xcd,0x06,0xc2,0x44,0x00,0x00,0x01,0x00,0x21,0x1b,0x7c,0x23,0x80, +0x02,0xcd,0x08,0xdc,0x28,0xcd,0x06,0x08,0x29,0x1b,0x30,0xa1,0x00,0x14,0xfc,0x9b, +0x20,0x0b,0xa0,0x00,0x00,0x14,0x80,0x38,0x20,0xcd,0x05,0x81,0x08,0x06,0x40,0x2c, +0x0e,0x50,0x00,0x00,0x14,0xc0,0x56,0x28,0xcd,0x05,0x90,0x6c,0xcd,0x05,0x7c,0x42, +0xa0,0x09,0xb0,0x40,0x20,0x06,0x94,0x42,0x24,0x09,0xcd,0x05,0x74,0x50,0xfc,0x34, +0x04,0xc4,0x3f,0xcd,0x05,0xad,0x10,0xf0,0x9b,0x4c,0x14,0xc0,0x9e,0xfc,0x34,0x04, +0xcd,0x07,0xae,0x28,0xcd,0x08,0xdd,0x20,0xfc,0x43,0x24,0x0b,0x06,0x20,0x28,0x0e, +0x90,0x38,0x24,0x14,0xfc,0x53,0x28,0x0b,0x06,0x48,0x24,0xcd,0x05,0x82,0x70,0xc0, +0x46,0xfc,0x34,0x90,0x50,0x24,0x14,0x04,0xe0,0x3f,0x01,0x94,0x20,0x00,0x1a,0x06, +0x20,0xcd,0x06,0xe0,0x54,0x01,0xcd,0x08,0xc4,0x14,0xcd,0x04,0x0c,0xcd,0x08,0xc3, +0x64,0x46,0x20,0x15,0xcd,0x04,0x4c,0x50,0xcd,0x05,0xca,0x44,0xcd,0x22,0xaf,0x00, +0xcd,0x06,0xbc,0x3c,0x2d,0xcd,0x05,0x89,0x4c,0x1c,0x5e,0x28,0x0b,0x20,0x50,0x0c, +0x14,0x00,0x50,0x20,0x14,0x04,0x18,0x24,0x0e,0xcd,0x06,0x92,0x0c,0xa4,0x09,0x80, +0x4a,0x20,0x09,0x00,0x50,0xcd,0x06,0x93,0x54,0x10,0xcd,0x04,0x1c,0x40,0x24,0x0e, +0xcd,0x05,0x89,0x38,0x18,0x20,0x14,0xf0,0x5b,0x2c,0xcd,0x06,0x92,0x34,0x42,0xa0, +0x09,0x80,0x42,0x24,0x09,0xcd,0x04,0x20,0x00,0xb8,0xbf,0x01,0xcd,0x06,0xcc,0x3c, +0xcd,0x07,0xcd,0x40,0x4e,0x7c,0x35,0x00,0x02,0x29,0x1b,0xff,0x01,0x2d,0x1b,0xa0, +0x40,0x28,0x04,0x34,0x56,0x28,0x0b,0x08,0x10,0x00,0x01,0xb0,0x40,0x20,0x04,0xd3, +0x23,0xcd,0x06,0xc8,0x44,0x30,0x4e,0x2c,0x15,0xb4,0x40,0x2c,0x0b,0xe0,0x53,0x20, +0x14,0xe0,0x4b,0x28,0x14,0xcd,0x05,0xb0,0x60,0x14,0x00,0x01,0xf0,0x4b,0xa4,0x14, +0x0c,0x46,0x28,0x0b,0xd6,0x23,0x80,0x02,0xa0,0x40,0xa0,0x04,0x00,0x00,0x00,0x03, +0xb0,0x40,0xa0,0x04,0xe0,0x43,0x24,0x14,0x04,0x00,0x2d,0xcd,0x05,0x88,0x04,0x05, +0xcd,0x07,0x8b,0x08,0xb0,0xf0,0xa9,0x14,0xa4,0x48,0x28,0x0b,0xf0,0x5b,0x2c,0x14, +0xf0,0x53,0x28,0x04,0x00,0xf0,0xbf,0x01,0xa0,0x40,0x20,0xcd,0x09,0x82,0x96,0x14, +0xcd,0x0d,0xd5,0x24,0x0b,0xcd,0x07,0xb5,0x14,0x03,0xcd,0x06,0xb5,0x14,0x38,0x2f, +0x00,0x1b,0x54,0x28,0x10,0x1b,0xe0,0x03,0x48,0xcd,0x05,0x86,0x18,0xfc,0x8b,0x20, +0x0b,0x60,0x40,0xcd,0x06,0xd1,0x64,0x14,0x46,0x20,0x0b,0x74,0x46,0x20,0x0b,0xd0, +0x04,0x01,0x1b,0x8c,0x46,0x24,0x0b,0x00,0x20,0x08,0x14,0x2c,0x4e,0x24,0x0b,0xcd, +0x04,0x24,0x06,0x10,0x28,0x0e,0x50,0x40,0x20,0x14,0xd2,0x04,0x01,0x1b,0xcd,0x05, +0xa7,0x34,0x20,0x04,0x14,0xcd,0x04,0x30,0xfc,0x8b,0x00,0xcd,0x05,0x34,0x00,0x20, +0x00,0xcd,0x05,0xd6,0x50,0x2c,0x46,0x38,0x0b,0x51,0x24,0x21,0x1b,0x8a,0xcd,0x05, +0xb5,0x58,0xb0,0x17,0x11,0x56,0xcd,0x08,0xb1,0x6c,0xac,0x17,0xc0,0x58,0xb0,0x14, +0xf2,0xff,0x2d,0x1b,0xbc,0x60,0x34,0x0b,0x06,0x08,0x2c,0x0e,0x89,0x74,0x31,0x1b, +0xca,0x58,0x18,0x10,0x42,0x04,0xac,0x17,0xd0,0x58,0x30,0x14,0xd8,0x04,0x2d,0x1b, +0xb0,0x00,0x2c,0x14,0xc4,0x58,0x00,0x1a,0xcd,0x05,0xab,0x04,0x58,0x24,0x0e,0x94, +0x08,0x00,0x1a,0xd6,0x04,0x09,0x1b,0xd4,0x04,0x05,0x1b,0x10,0x20,0x04,0xcd,0x05, +0xd7,0x4c,0x06,0x08,0x24,0x0e,0x8a,0xcd,0x05,0x54,0xa0,0x17,0xaa,0x70,0xcd,0x06, +0xb4,0x00,0x89,0x74,0x29,0x1b,0x80,0x48,0xa4,0x14,0xf2,0xcd,0x07,0xb6,0x30,0x06, +0x10,0x24,0x0e,0xcd,0x04,0x78,0x42,0x04,0xa4,0x17,0x80,0x48,0x20,0x14,0x18,0x05, +0xcd,0x06,0xa2,0x70,0x84,0x50,0x00,0x1a,0xe4,0x08,0x00,0x1a,0x06,0x50,0xcd,0x07, +0xb4,0x5c,0xcd,0x07,0x68,0x06,0x50,0x28,0x0e,0x58,0xcd,0x07,0xfc,0x70,0xe6,0x29, +0xc0,0x02,0x00,0x40,0x20,0xcd,0x05,0xea,0x44,0x60,0x8f,0xfc,0x34,0x04,0xdc,0xcd, +0x06,0xb3,0x74,0xcd,0x1c,0x84,0x5c,0xcd,0x10,0x99,0x64,0xcd,0x06,0xd1,0x34,0x14, +0x1b,0x00,0x00,0x3d,0x1b,0xfc,0x7b,0x20,0x0b,0xfc,0x7b,0x18,0xcd,0x05,0xa9,0x74, +0x60,0x20,0x18,0xcd,0x0f,0x82,0x6c,0x09,0xcd,0x05,0x82,0x6c,0x20,0xcd,0x08,0x82, +0x6c,0x7b,0x20,0x0b,0x10,0x40,0x20,0x14,0x06,0x10,0x28,0xcd,0x05,0x85,0x18,0xd2, +0x04,0x0d,0x1b,0xcd,0x04,0x2c,0x30,0x20,0x0c,0x14,0xcd,0x04,0x30,0x11,0x56,0x35, +0x1b,0xcd,0x06,0x82,0x68,0x30,0xcd,0x0b,0x82,0x68,0xac,0x17,0xda,0xcd,0x07,0xb4, +0x50,0xb0,0x50,0xa8,0xcd,0x06,0x82,0x64,0x50,0x38,0x0b,0x06,0x18,0x2c,0x0e,0x89, +0x74,0x29,0x1b,0xaa,0xcd,0x05,0x82,0x64,0xa8,0x17,0xe0,0x50,0x2c,0x14,0x58,0x05, +0x29,0x1b,0xa0,0x30,0x28,0x14,0xb4,0x50,0xcd,0x07,0x82,0x64,0x50,0x24,0x0e,0x94, +0x18,0x00,0x1a,0xd4,0x04,0x09,0x1b,0xd6,0x04,0x0d,0x1b,0x20,0x20,0x08,0x14,0xcd, +0x04,0x6c,0x06,0x10,0x24,0x0e,0x06,0x18,0x28,0xcd,0x09,0x82,0x68,0xda,0x60,0xcd, +0x06,0x82,0x68,0x80,0x48,0xa0,0x14,0xf2,0xcd,0x05,0xb5,0x1c,0x24,0x0b,0x89,0x74, +0xcd,0x06,0x81,0x00,0x42,0x04,0xcd,0x06,0xad,0x00,0xd8,0x05,0x25,0x1b,0x90,0x30, +0xcd,0x06,0x86,0x40,0xc4,0xcd,0x04,0x5c,0x48,0x20,0x0e,0xf0,0x7b,0x3c,0x14,0x84, +0x18,0xcd,0x07,0xa8,0x34,0x78,0xfc,0x34,0x04,0xf4,0xcd,0x06,0x82,0x4c,0xcd,0x05, +0x93,0x68,0xcd,0x0c,0xae,0x30,0xcd,0x07,0x81,0xf8,0x4c,0xcd,0x06,0x85,0x14,0x24, +0x0b,0xe0,0x2b,0x00,0x14,0x90,0x20,0x24,0x14,0x58,0x06,0x21,0x1b,0x58,0x05,0x29, +0x1b,0xd8,0x05,0x2d,0xcd,0x06,0xb3,0x1c,0xcd,0x05,0xba,0x1c,0x20,0x0e,0xfc,0x8b, +0xcd,0x06,0x88,0x38,0xa0,0x20,0x28,0x14,0xb0,0x50,0x28,0xcd,0x06,0xec,0x34,0x50, +0xcd,0x06,0xed,0x78,0xcd,0x05,0x6c,0x88,0xfc,0x34,0x04,0xb8,0xcd,0x06,0x88,0x78, +0xcd,0x04,0x6c,0xcd,0x05,0x9c,0x30,0xcd,0x09,0xab,0x34,0xcd,0x1a,0x83,0x44,0xe0, +0x03,0x10,0xcd,0x05,0xd1,0x14,0x88,0xcd,0x05,0xd1,0x68,0x28,0x0b,0x00,0x08,0x2d, +0xcd,0x07,0xd2,0x00,0x24,0x04,0xff,0xff,0x20,0x1b,0x80,0x50,0x20,0x04,0x80,0x58, +0xfc,0x34,0x10,0xcd,0x07,0xf5,0x1c,0x80,0x01,0xcd,0x07,0x81,0x86,0x34,0x90,0xcd, +0x06,0x10,0x4c,0x03,0xcd,0x06,0x9e,0x50,0xcd,0x09,0xdb,0x18,0xcd,0x0b,0xea,0x54, +0x04,0x00,0x21,0x1b,0x20,0x25,0xcd,0x06,0x8e,0x74,0xcd,0x09,0xf4,0x24,0xcd,0x0b, +0x20,0x05,0xcd,0x0f,0x20,0xcd,0x05,0x8d,0x14,0xcd,0x0b,0x20,0x06,0xcd,0x0f,0x20, +0xcd,0x05,0xeb,0x34,0xe4,0xcd,0x0a,0x20,0x07,0xcd,0x0b,0x20,0xcd,0x0d,0x81,0x24, +0xcd,0x05,0xaa,0x50,0xcd,0x26,0x81,0x24,0x09,0xcd,0x1f,0x81,0x24,0x0a,0xcd,0x1f, +0x81,0x24,0x0b,0xcd,0x14,0x81,0x24,0xcd,0x0b,0xf2,0x60,0x0c,0xcd,0x0b,0x20,0x00, +0x06,0x29,0x1b,0xa0,0x40,0xfc,0x34,0x10,0xcd,0x07,0x90,0x64,0x80,0x01,0xcd,0x06, +0xb9,0x50,0xcd,0x08,0xb8,0x4c,0xcd,0x04,0x30,0x08,0xcd,0x05,0x90,0x58,0xcd,0x0a, +0x81,0x89,0x4c,0x00,0x00,0x01,0x1b,0xc0,0x00,0x99,0x19,0x00,0x00,0x83,0x19,0x50, +0x08,0x81,0x19,0x04,0x08,0xc3,0x19,0x04,0xcd,0x06,0x81,0xb6,0x54,0x1a,0xcd,0x04, +0x04,0xcd,0x05,0x08,0xf4,0xbf,0x01,0xcd,0x04,0x08,0x80,0x80,0x01,0x1b,0x11,0x01, +0xcd,0x06,0x2c,0x0c,0x08,0x81,0x19,0x02,0x08,0xc3,0x19,0x02,0xcd,0x08,0x2c,0xfc, +0xcd,0x06,0x24,0xcd,0x0c,0x81,0xa9,0x48,0x01,0x08,0xcd,0x0f,0x82,0x89,0x38,0xcd, +0x3b,0x82,0x9d,0x28,0x9d,0x80,0x99,0x19,0x00,0x80,0xc3,0x19,0x1d,0x8d,0x91,0x19, +0x00,0x88,0xc3,0x19,0x04,0x00,0x78,0x1b,0x01,0x80,0xf8,0x1b,0x08,0x00,0x7c,0x1b, +0x02,0x80,0xfc,0xcd,0x09,0x81,0x44,0x38,0xcd,0x07,0x81,0x44,0xc0,0x10,0x99,0x19, +0x04,0x10,0x83,0x19,0x38,0xcd,0x08,0x81,0x93,0x64,0x18,0x31,0x0e,0x00,0x18,0x35, +0x0e,0xc0,0x08,0x01,0x1a,0xd0,0x08,0x01,0x1a,0xcd,0x08,0x10,0x80,0xcd,0x0f,0x10, +0xcd,0x04,0x20,0x90,0xcd,0x0f,0x10,0xcd,0x10,0x20,0xcd,0x0c,0x10,0xcd,0x04,0x08, +0xcd,0x04,0x30,0xcd,0x04,0x14,0xcd,0x08,0x3c,0xd9,0xcd,0x07,0x81,0x0c,0x14,0xcd, +0x07,0x82,0x24,0x4c,0x45,0x91,0x19,0x00,0x40,0x83,0x19,0x24,0x48,0x81,0x19,0x04, +0x48,0xc3,0x19,0x15,0x0a,0x19,0x10,0x15,0x0a,0x99,0x11,0x15,0x0a,0x19,0x11,0xcd, +0x08,0x08,0xcd,0x10,0x10,0x85,0x02,0xa8,0x17,0x25,0x00,0xa0,0x17,0xa0,0xcd,0x04, +0x6c,0x40,0x28,0x07,0xa0,0x00,0xaa,0x14,0xac,0x40,0x20,0x0b,0xe3,0xff,0x25,0x1b, +0xa0,0x48,0xa4,0x14,0x99,0x10,0xa6,0x07,0x80,0xf0,0xa1,0x07,0x08,0x40,0x28,0x16, +0xa9,0xf0,0xa9,0x07,0x90,0x10,0xa6,0x07,0xe0,0x43,0x28,0x14,0xe0,0x4b,0x2c,0x14, +0xa5,0x40,0x18,0x12,0x05,0x00,0xa0,0x17,0xcd,0x0c,0x38,0xcd,0x04,0x34,0xb0,0x48, +0x24,0xcd,0x15,0x38,0xf9,0x00,0x99,0x19,0x04,0x00,0x83,0x19,0xf0,0x09,0x81,0x18, +0x00,0x08,0x31,0x0e,0x00,0x08,0xcd,0x0a,0x81,0x68,0x80,0x08,0x01,0x1a,0x00,0x10, +0x4a,0x0e,0x13,0x11,0x99,0x19,0x02,0x10,0x83,0x19,0xe0,0x19,0x81,0x18,0xcd,0x09, +0x82,0x0c,0x18,0x01,0x1a,0xc9,0x90,0xc8,0x07,0xd0,0x18,0x01,0x1a,0xd9,0x90,0xc8, +0x07,0x90,0x18,0x01,0x1a,0x99,0x90,0xc8,0x07,0x00,0x00,0x83,0xcd,0x07,0xb6,0x00, +0x25,0x0e,0x20,0x49,0xa8,0x14,0x00,0x08,0x2d,0x0e,0xa9,0x08,0xaa,0x07,0xac,0x58, +0x2c,0x0b,0xcd,0x0a,0x14,0x31,0xcd,0x06,0x14,0x60,0x30,0xcd,0x0b,0x14,0x35,0xcd, +0x06,0x14,0x68,0x34,0x0b,0x84,0xcd,0x07,0x82,0x34,0x0c,0xcd,0x08,0x82,0x34,0x5a, +0x18,0x10,0x15,0x62,0x98,0x11,0x15,0x6a,0x18,0x11,0x25,0xcd,0x0f,0x81,0x5c,0xf2, +0xcd,0x07,0x82,0x14,0x20,0x49,0xcd,0x16,0x81,0x60,0x80,0x08,0x01,0x1a,0x90,0x18, +0x01,0x1a,0x00,0x4c,0xa4,0x14,0xf0,0x4b,0x28,0x04,0xe1,0x53,0xa8,0x07,0x10,0xf4, +0xad,0x07,0xbc,0x40,0x20,0x0b,0xb0,0x48,0xa4,0x14,0x1c,0x4c,0x44,0x0b,0xe0,0x43, +0xa0,0x34,0x00,0x80,0x38,0x1b,0x01,0xb4,0x00,0x21,0x00,0x40,0x3c,0x1b,0x00,0x40, +0x34,0x07,0x00,0x6c,0x28,0x15,0xcd,0x04,0x60,0xff,0x3f,0xcd,0x06,0x81,0x89,0x68, +0x00,0xcd,0x07,0x81,0x14,0xcd,0x06,0x81,0xc7,0x54,0xc3,0x19,0xf0,0x7b,0x18,0x10, +0x10,0x42,0x18,0x11,0x10,0x72,0x98,0x11,0x40,0x04,0xb0,0x17,0xcd,0x04,0x10,0xc0, +0x40,0xcd,0x10,0x10,0xcd,0x20,0x20,0xcd,0x0a,0x10,0x00,0x62,0x30,0x14,0xf0,0x53, +0x2c,0x24,0x3c,0x44,0x24,0x0b,0x01,0x14,0x00,0x21,0x90,0x60,0x30,0x14,0x05,0xb5, +0x40,0x1b,0xc0,0x80,0x00,0x10,0xcd,0x05,0x30,0x53,0x20,0x14,0x14,0x44,0x20,0x0b, +0x09,0xcd,0x07,0xb0,0x14,0x80,0xf0,0xa1,0x14,0x8c,0x60,0x20,0x0b,0x19,0x11,0xcd, +0x14,0x84,0x0c,0x48,0x14,0xe0,0x4b,0x4c,0x14,0xa9,0xcd,0x07,0x85,0x0c,0x10,0xcd, +0x07,0x85,0x0c,0xbb,0xcd,0x07,0xb9,0x1c,0x08,0x18,0x81,0x19,0x01,0x18,0xc3,0x19, +0x9d,0xcd,0x07,0x81,0x54,0xf0,0x49,0x81,0x18,0xa7,0x55,0x91,0x19,0x00,0x50,0x83, +0x19,0xe0,0x59,0x81,0x18,0x03,0x20,0x80,0x19,0xcd,0x05,0xa5,0x20,0x9b,0x24,0x14, +0x00,0x08,0x29,0x0e,0x00,0x18,0x2d,0x0e,0xcd,0x30,0x84,0x58,0xcd,0x08,0x38,0xb9, +0x48,0xb0,0x07,0x90,0x58,0xb4,0x07,0x80,0x50,0xb8,0x07,0xa0,0x40,0xa8,0x07,0xc0, +0x68,0xbc,0x14,0xf9,0x08,0xa2,0x07,0x8c,0x70,0x38,0x0b,0xa0,0x70,0x38,0x14,0x00, +0x70,0xcd,0x07,0x50,0x70,0x20,0x0b,0xa0,0x60,0xcd,0x16,0x85,0x5c,0x10,0x42,0x80, +0x1a,0x00,0x70,0xbf,0x01,0x30,0x4a,0x80,0x1a,0xed,0xcd,0x07,0x81,0x54,0xcd,0x08, +0x89,0x04,0x70,0xcd,0x07,0x81,0x44,0x14,0xcd,0x1b,0x86,0x60,0xcd,0x6c,0x86,0x50, +0x01,0x01,0xcd,0x22,0x86,0x50,0x17,0xcd,0x6f,0x86,0x50,0x90,0xcd,0x82,0x47,0x86, +0x50,0xcd,0x00,0xcd,0x0f,0x84,0x7c,0x38,0xcd,0x57,0x84,0x7c,0x09,0xcd,0x1f,0x84, +0x44,0x1b,0xcd,0x17,0x84,0x40,0xd0,0x18,0xcd,0x07,0x83,0x1c,0xcd,0x07,0x84,0x34, +0xcd,0x18,0x87,0x60,0x02,0x20,0x80,0x19,0xe0,0x03,0x80,0x0e,0x00,0x10,0x06,0x0e, +0x10,0x02,0xa0,0x0e,0x30,0x02,0xa4,0x0e,0xcd,0x38,0x87,0x68,0xe0,0x03,0xcd,0x06, +0x81,0x98,0x7c,0xcd,0x44,0x87,0x68,0xe0,0x43,0x00,0x14,0x00,0x70,0xbf,0x01,0xe0, +0x4b,0x04,0x14,0x10,0x02,0xa8,0x0e,0x30,0x02,0xac,0x0e,0x89,0x20,0xb2,0x07,0xe0, +0xfb,0xb5,0x07,0xa9,0xcd,0x05,0x08,0xb9,0x07,0xd0,0x70,0x38,0x14,0x08,0x40,0x20, +0x16,0x08,0x50,0x28,0x16,0x10,0x50,0x80,0x19,0x00,0x00,0x31,0xcd,0x05,0xc2,0x28, +0xa0,0x50,0x28,0x14,0x80,0x40,0x20,0x14,0xa0,0x40,0xb4,0x34,0xe8,0x63,0x30,0x14, +0xc0,0x60,0x30,0x14,0xcd,0x06,0x9b,0x4c,0xa0,0x94,0x00,0x60,0xcd,0x07,0x7c,0x60, +0x20,0x0b,0x20,0x4c,0xa4,0x14,0xcd,0x06,0x81,0x50,0xa4,0x14,0xf0,0x73,0x38,0x04, +0x80,0xf0,0xb1,0x14,0xe9,0xf0,0xb9,0x07,0xc0,0x40,0xa0,0x07,0xcd,0x1c,0x85,0x70, +0xe0,0x93,0x28,0x14,0xe0,0x9b,0xcd,0x32,0x88,0x10,0x90,0x00,0x2a,0x14,0xcd,0x05, +0x87,0x08,0x40,0x24,0x0b,0xc1,0xcd,0x0f,0x84,0x40,0x24,0xcd,0x25,0x84,0x40,0xa0, +0x17,0x80,0x08,0x01,0x1a,0xcd,0x3e,0x82,0xab,0x24,0xcd,0x0c,0x81,0xde,0x30,0xcd, +0x06,0x81,0xde,0x28,0x80,0x00,0x00,0x1a,0xcd,0x06,0xdc,0x24,0xcd,0x06,0x93,0x34, +0x23,0x25,0xcd,0x0e,0x81,0xc5,0x58,0xcd,0x0d,0xa3,0x00,0x13,0xcd,0x07,0xa3,0x00, +0x0b,0x14,0x14,0xe0,0x03,0x18,0xcd,0x05,0xab,0x68,0x39,0x25,0xcd,0x06,0x81,0x80, +0x74,0xe1,0x27,0xcd,0x07,0x95,0x00,0x38,0xcd,0x0a,0xce,0x58,0x84,0x28,0x00,0x1a, +0xcd,0x0c,0x10,0xef,0x27,0xcd,0x06,0xd1,0x48,0xcd,0x0c,0x14,0x30,0x3e,0x00,0x14, +0xcd,0x05,0x28,0xcd,0x0b,0xcf,0x10,0xcd,0x08,0x28,0xcd,0x05,0xb5,0x48,0x38,0x28, +0x0e,0xcd,0x04,0x1c,0x80,0x50,0x24,0x14,0x80,0x50,0xa0,0x14,0x0c,0x4e,0x24,0x0b, +0x0c,0x46,0x20,0x0b,0x0a,0x48,0xcd,0x04,0x2c,0xa4,0x17,0xcd,0x08,0x34,0x94,0x28, +0x00,0x1a,0xcd,0x30,0x60,0x70,0x36,0xcd,0x06,0xb7,0x48,0xcd,0x1c,0xa7,0x20,0x1c, +0x31,0xcd,0x12,0xdf,0x5c,0xcd,0x10,0x99,0x68,0x50,0xcd,0x07,0xd5,0x3c,0xbc,0x06, +0x29,0xcd,0x06,0x9d,0x34,0xcd,0x07,0x9d,0x2c,0x01,0x90,0x80,0x1a,0xa0,0x20,0x28, +0x14,0x01,0xf0,0x80,0x1a,0x0e,0x50,0xcd,0x06,0xd1,0x78,0xe0,0x4b,0x48,0x14,0x01, +0x18,0x00,0x01,0xcd,0x06,0xa7,0x28,0x45,0x1b,0xff,0x00,0x21,0x1b,0x92,0x29,0xc0, +0x02,0xe0,0x8b,0x48,0x14,0xb4,0xcd,0x07,0x9e,0x2c,0xcd,0x09,0x9b,0x40,0x2c,0x00, +0x01,0xe0,0x8b,0xcd,0x06,0xcf,0x44,0x5c,0x28,0xcd,0x06,0xab,0x4c,0xcd,0x04,0x38, +0xcd,0x09,0x10,0x93,0xcd,0x04,0x10,0x48,0xcd,0x05,0xab,0x5c,0xb6,0x06,0x25,0xcd, +0x09,0xbd,0x04,0xcd,0x05,0xb6,0x38,0x24,0xcd,0x06,0x64,0x8f,0xcd,0x04,0x28,0x23, +0x00,0xcd,0x09,0x38,0xcd,0x05,0x10,0xcd,0x0b,0x38,0xb8,0xcd,0x07,0x38,0x88,0x28, +0xc0,0x02,0x04,0xcd,0x04,0x3c,0x43,0x44,0x14,0xba,0x06,0x25,0x1b,0xcd,0x04,0x24, +0xcd,0x0e,0x18,0x24,0xcd,0x06,0x81,0x88,0x54,0x8b,0x20,0xcd,0x05,0xac,0x64,0x91, +0x28,0xc0,0x02,0x10,0x3e,0x08,0x14,0xcd,0x05,0xfb,0x5c,0xcd,0x05,0x81,0x34,0xcd, +0x12,0x81,0x9a,0x68,0xb0,0x06,0xcd,0x0a,0xba,0x60,0xf0,0x43,0xcd,0x06,0x81,0x89, +0x0c,0x84,0x08,0x00,0x1a,0x1c,0x4e,0xcd,0x08,0x81,0x9c,0x78,0x20,0xcd,0x0b,0x81, +0x85,0x2c,0x28,0x0e,0xa0,0x48,0xa4,0x0b,0x90,0x40,0xcd,0x06,0xbc,0x30,0xcd,0x06, +0xf0,0x04,0xfc,0xcd,0x09,0x81,0xf1,0x34,0xcd,0x06,0x81,0x9b,0x30,0x25,0x1b,0x90, +0x00,0x00,0x1a,0x00,0x01,0xcd,0x07,0x1c,0xcd,0x0c,0xba,0x48,0x08,0x00,0x1a,0xcd, +0x0a,0xef,0x7c,0xcd,0x08,0x85,0x70,0xcd,0x0a,0x9d,0x08,0xb2,0x06,0x05,0x1b,0x05, +0x00,0x31,0xcd,0x05,0xef,0x78,0x04,0x00,0x24,0x0e,0x44,0x4e,0x28,0x0b,0xa0,0x48, +0x24,0x06,0x20,0x4f,0x2c,0xcd,0x06,0xc8,0x20,0x58,0x24,0x0b,0x90,0x50,0xa4,0x04, +0x94,0x00,0x00,0x1a,0x04,0x00,0x28,0x0e,0x44,0x56,0xcd,0x04,0x10,0x28,0x06,0x20, +0x57,0x28,0x04,0xc4,0x50,0x30,0x0b,0xc0,0x48,0xa4,0xcd,0x05,0xa4,0x7c,0xcd,0x04, +0x20,0xb0,0x50,0xb0,0x04,0xcd,0x0e,0x44,0x24,0x04,0x05,0x00,0x2d,0x1b,0xb4,0x48, +0x2c,0x0b,0xb0,0x50,0xcd,0x06,0xc8,0x44,0xa4,0x00,0x00,0x1a,0xc0,0x48,0xac,0x04, +0xcd,0x10,0x4c,0x05,0x00,0x31,0x1b,0xcd,0x08,0x50,0xcd,0x04,0x4c,0xb4,0x56,0x24, +0x0b,0xb0,0x48,0xa4,0x04,0x90,0x40,0x20,0x06,0x90,0x40,0x20,0xcd,0x05,0xc8,0x40, +0xf4,0x46,0x20,0x0b,0xcd,0x08,0xa0,0x24,0xcd,0x08,0xf2,0x0c,0x0a,0x40,0xc0,0x10, +0xcd,0x04,0x1c,0x2e,0xcd,0x07,0xd5,0x30,0x00,0x00,0x00,0x00,0x82,0x29,0xcd,0x06, +0x86,0x74,0xd1,0x28,0xcd,0x06,0x08,0x94,0x08,0xcd,0x06,0xa1,0x00,0x92,0x29,0xcd, +0x06,0x81,0x87,0x14,0x90,0xcd,0x07,0x20,0xc8,0x06,0x29,0x1b,0xa0,0x00,0x28,0x14, +0xcd,0x08,0x85,0x04,0x02,0xcd,0x07,0x81,0xb1,0x34,0xcd,0x08,0xdb,0x6c,0x84,0x08, +0x00,0x1a,0x84,0xcd,0x13,0x38,0xcd,0x04,0x18,0xcd,0x08,0x50,0x03,0xcd,0x0b,0x18, +0xd0,0xcd,0x07,0x50,0x06,0xcd,0x07,0x50,0x01,0x60,0xcd,0x08,0x81,0x94,0x7c,0x0d, +0x1b,0x30,0xcd,0x05,0xc0,0x58,0x28,0x0e,0xf0,0xcd,0x04,0x68,0xcd,0x07,0x86,0x48, +0xcd,0x0c,0x60,0x01,0xcd,0x0b,0x48,0xcd,0x04,0x28,0x10,0x56,0xfc,0x34,0x02,0x34, +0xcd,0x06,0xc6,0x24,0xcd,0x0c,0x70,0x02,0xcd,0x0b,0x28,0xcd,0x18,0x81,0x58,0x70, +0x06,0xcd,0x0b,0x81,0x04,0x04,0xcd,0x06,0xa1,0x18,0xcd,0x0c,0xdc,0x78,0xf0,0xcd, +0x04,0x18,0x54,0xcd,0x06,0x0c,0xcd,0x08,0x34,0x1e,0xcd,0x1f,0x54,0xcd,0x50,0x82, +0x2c,0xcd,0x0c,0x82,0x14,0xcd,0x05,0x81,0x28,0xcd,0x09,0x81,0x95,0x50,0x28,0x0e, +0xc0,0x56,0xcd,0x16,0x82,0x24,0xcd,0x0c,0x58,0xcd,0x10,0x82,0x4c,0xcd,0x0c,0x81, +0x38,0xcd,0x15,0x82,0x4c,0xcd,0x07,0x81,0x96,0x20,0xcd,0x18,0x82,0x4c,0xcd,0x0d, +0x82,0x34,0xfc,0xcd,0x0b,0xda,0x78,0x08,0xcd,0x06,0x82,0x28,0xcd,0x05,0xdb,0x10, +0x4c,0xcd,0x0e,0x82,0x34,0xcd,0x29,0x82,0x2c,0xcd,0x1f,0x81,0x4c,0x71,0xcd,0x2b, +0x82,0x2c,0xcd,0x2d,0x81,0x74,0xcd,0x0b,0x78,0xcd,0x14,0x81,0x74,0x0e,0x00,0x24, +0x0e,0xcd,0x05,0xf3,0x28,0xcc,0xcd,0x12,0x81,0x20,0xcd,0x0c,0x81,0x00,0xcd,0x18, +0x81,0x68,0xcd,0x18,0x18,0x4c,0x03,0xcd,0x0e,0x82,0x00,0xcd,0x09,0x8c,0x44,0x56, +0xcd,0x0b,0x8c,0x44,0x56,0x28,0x0b,0x2c,0x31,0x0c,0x1b,0x30,0x50,0x28,0x14,0x00, +0x50,0x0c,0x0e,0x00,0x18,0xcd,0x06,0x8c,0x44,0xcd,0x08,0x44,0xb0,0xcd,0x0b,0x83, +0x10,0xcd,0x09,0x81,0x87,0x18,0xcd,0x0f,0x40,0x3c,0xcd,0x13,0x40,0xcd,0x09,0xa6, +0x60,0xf0,0x80,0x1a,0xe0,0x43,0x78,0xcd,0x09,0x81,0xa3,0x44,0xcd,0x08,0xa2,0x4c, +0xcd,0x06,0x81,0xa3,0x70,0xd4,0x0e,0xd0,0xab,0x58,0x08,0xe0,0xf3,0x5c,0x14,0xd0, +0xbb,0x58,0x09,0x40,0xb1,0x80,0x1a,0xcd,0x12,0x90,0x20,0xcd,0x0a,0xec,0x40,0xcd, +0x05,0x8a,0x67,0x06,0xcd,0x06,0xd0,0x48,0x00,0x00,0x29,0xcd,0x05,0xbc,0x2c,0x50, +0x06,0xcd,0x06,0xa8,0x7c,0xb0,0xcd,0x08,0x08,0xcd,0x07,0xcf,0x40,0xa0,0x48,0x00, +0x1a,0xb4,0xcd,0x0b,0x0c,0xb8,0xcd,0x05,0x0c,0x28,0x14,0xcd,0x09,0x81,0xa1,0x78, +0x50,0xcd,0x06,0xb1,0x14,0xcd,0x04,0x48,0xcd,0x04,0x24,0x70,0x4e,0xcd,0x06,0xcf, +0x44,0xcd,0x04,0x14,0x90,0x00,0x2c,0xcd,0x05,0xc3,0x18,0x24,0x00,0x25,0x1b,0x00, +0x47,0xfc,0x34,0x90,0x58,0x24,0x14,0x04,0xd4,0x3f,0xcd,0x05,0xc3,0x24,0x00,0x00, +0x2d,0x1b,0xfc,0x5b,0x20,0xcd,0x05,0x38,0x80,0x00,0x20,0x14,0x38,0xcd,0x07,0x8a, +0x00,0xa4,0x40,0x00,0x1a,0xcd,0x04,0x18,0x80,0x00,0x24,0xcd,0x05,0xb0,0x38,0x60, +0x00,0x21,0x1b,0x40,0x5f,0xfc,0x34,0x80,0x48,0x20,0x14,0x04,0xd0,0xcd,0x06,0xd7, +0x04,0x00,0x00,0x25,0x1b,0xcd,0x05,0xd6,0x08,0xcd,0x05,0x3c,0x2c,0x14,0x88,0x00, +0x21,0x1b,0x80,0x58,0xcd,0x07,0x3c,0x4b,0xcd,0x04,0x3c,0x2c,0xcd,0x05,0xba,0x48, +0x9c,0x00,0x21,0x1b,0x00,0x4f,0xfc,0x34,0xcd,0x04,0x1c,0xcd,0x0a,0x3c,0xcd,0x06, +0x82,0x50,0x70,0xcd,0x07,0x91,0x70,0xcd,0x05,0xb5,0x70,0xcd,0x08,0xd0,0x38,0x43, +0x44,0x14,0xe0,0x4b,0x20,0x14,0xe0,0x53,0x24,0xcd,0x05,0xe4,0x64,0xcd,0x05,0x86, +0x3c,0x74,0xcd,0x06,0xcc,0x20,0x30,0x3e,0x9c,0xcd,0x05,0x8e,0x18,0x50,0x3e,0x0c, +0x14,0xe0,0x3b,0x28,0xcd,0x05,0x92,0x14,0x34,0x50,0x00,0x1a,0x00,0x3f,0x0c,0x14, +0x10,0x3e,0x28,0x14,0xe0,0x3e,0x08,0xcd,0x05,0x10,0xec,0x2c,0xc0,0x02,0x14,0x00, +0x29,0x1b,0x83,0x2a,0x80,0x02,0x30,0x3e,0x1c,0xcd,0x06,0xbb,0x14,0x23,0xcd,0x07, +0xe6,0x78,0x08,0x24,0x0e,0xd8,0x2a,0xc0,0x02,0xe0,0x8b,0x28,0x14,0x50,0x26,0x14, +0x14,0x06,0x28,0xcd,0x0a,0x90,0x00,0x00,0x00,0x00,0x00,0xbc,0x00,0x21,0x1b,0xbe, +0xcd,0x07,0xaa,0x6c,0xcd,0x05,0x8f,0x64,0x40,0x20,0x0e,0xf4,0x27,0xc0,0x02,0x06, +0x48,0x24,0xcd,0x05,0xd6,0x5c,0x84,0x28,0x00,0x1a,0xcd,0x08,0xc0,0x7c,0x06,0x08, +0x20,0x0e,0xcd,0x04,0x48,0xe0,0x3e,0x04,0x14,0xcd,0x04,0x54,0xcd,0x04,0x5c,0xcd, +0x0d,0x54,0xb4,0xcd,0x06,0x88,0x20,0xcd,0x24,0x54,0xd3,0x2a,0xcd,0x07,0xff,0x64, +0x3e,0x04,0x14,0xf4,0x8b,0x44,0xcd,0x05,0xff,0x0c,0xcd,0x1d,0x81,0x30,0xcd,0x07, +0x81,0x83,0x4c,0xcd,0x08,0x82,0x14,0x70,0xcd,0x07,0x82,0x14,0xb0,0x3e,0x04,0x14, +0xcd,0x14,0x70,0xcd,0x04,0x6c,0x34,0x50,0x00,0x1a,0x30,0xcd,0x07,0x82,0x2c,0x10, +0x3f,0xcd,0x06,0x82,0x2c,0x42,0x2d,0xc0,0x02,0x0a,0x00,0x29,0x1b,0x30,0x3e,0x1c, +0x14,0x50,0xcd,0x07,0xe4,0x68,0x00,0x3f,0x00,0x14,0xcd,0x05,0x81,0x20,0x00,0x24, +0x0e,0xb0,0xcd,0x07,0x14,0x10,0xcd,0x0b,0x14,0xcd,0x31,0x82,0x08,0xac,0xcd,0x81, +0x02,0x81,0x2c,0xcd,0x09,0x82,0x60,0x26,0xcd,0x0b,0x93,0x74,0xe8,0x3d,0xcd,0x0a, +0xca,0x50,0xcd,0x07,0xea,0x4c,0xcd,0x08,0x28,0xcb,0xcd,0x07,0x08,0xe0,0x23,0x00, +0xcd,0x05,0x81,0x54,0xcd,0x11,0x83,0x00,0xcd,0x07,0xcf,0x48,0xcd,0x2c,0x83,0x5c, +0xcd,0x08,0x4c,0xf4,0x8b,0x28,0x0b,0xcd,0x81,0x1a,0x82,0x20,0xcd,0x12,0x8f,0x68, +0xcd,0x05,0x8f,0x5c,0x44,0xcd,0x0c,0xbc,0x3c,0xcd,0x0a,0x97,0x10,0x70,0xcd,0x05, +0x6c,0xcd,0x0f,0xec,0x4c,0x88,0x80,0x1a,0x22,0x00,0x01,0xcd,0x05,0x97,0x14,0x00, +0x20,0x00,0x14,0x60,0x04,0x00,0x09,0x40,0xf8,0x01,0x09,0x00,0x08,0x81,0x19,0xfe, +0x0f,0xdf,0x19,0x00,0x00,0x81,0x18,0x36,0xcd,0x07,0xcf,0x38,0xcd,0x09,0x1c,0x18, +0x81,0x19,0xfe,0x1f,0xdf,0x19,0x00,0x10,0x81,0x18,0x00,0x00,0x2d,0x18,0x84,0x5e, +0x30,0x0b,0x40,0x58,0x2c,0x08,0xe0,0x5f,0x2c,0x08,0xc0,0x58,0x00,0x14,0x10,0x06, +0x80,0xcd,0x0a,0x2c,0x28,0x81,0x19,0xfe,0x2f,0xdf,0x19,0x00,0x20,0x81,0x18,0x00, +0x10,0xcd,0x1f,0x2c,0x38,0x81,0x19,0xfe,0x3f,0xdf,0x19,0x00,0x30,0x81,0x18,0x08, +0xcd,0x07,0xb9,0x00,0x00,0x28,0x2d,0x0e,0x00,0x38,0x31,0x0e,0xb0,0xcd,0x07,0xae, +0x6c,0xc0,0x18,0x01,0x1a,0x30,0x26,0x14,0x14,0x80,0x00,0x01,0x1a,0x90,0x10,0x01, +0xcd,0x05,0xec,0x08,0xcd,0x05,0x83,0x18,0xfc,0xcd,0x07,0x95,0x74,0x27,0xcd,0x06, +0x97,0x50,0x06,0x88,0x20,0x0e,0xe0,0x3b,0x04,0x14,0x30,0x3e,0x08,0x14,0x09,0x00, +0x49,0x1b,0xca,0x2c,0xcd,0x06,0x81,0xa5,0x2c,0xcd,0x05,0x18,0x23,0xcd,0x06,0x81, +0xa4,0x68,0xcd,0x04,0x10,0x10,0x3e,0x04,0x14,0xcd,0x05,0x1c,0x3e,0x08,0x14,0x06, +0x38,0x28,0x0e,0x10,0x27,0x04,0xcd,0x06,0x96,0x7c,0x08,0xcd,0x06,0xeb,0x38,0xa0, +0x40,0xa0,0x14,0xcd,0x06,0xea,0x34,0xa4,0x17,0xf5,0xcd,0x07,0xb7,0x70,0x80,0x50, +0x24,0xcd,0x05,0x83,0x6c,0x80,0x20,0x20,0xcd,0x05,0xd0,0x54,0x94,0x40,0xcd,0x06, +0x81,0xa5,0x0c,0xe0,0xcd,0x23,0x38,0xbe,0xcd,0x07,0x38,0xcd,0x05,0x34,0x28,0xcd, +0x06,0xe4,0x64,0xcd,0x08,0xed,0x50,0xcd,0x05,0x81,0x48,0xcd,0x07,0x92,0x08,0x50, +0x26,0xcd,0x06,0x8c,0x70,0xc4,0x2c,0xcd,0x06,0xe8,0x34,0xcd,0x04,0x10,0xcd,0x08, +0xc9,0x28,0x30,0xcd,0x0f,0x1c,0x00,0x27,0x20,0x14,0x00,0x00,0x2d,0x1b,0xb0,0x00, +0x25,0x1b,0xb4,0x40,0x00,0x1a,0x10,0x27,0x20,0x14,0x90,0x20,0x00,0x14,0xcd,0x04, +0x0c,0xa0,0x80,0x21,0x14,0xb4,0x00,0xcd,0x06,0xe6,0x34,0x80,0x50,0xcd,0x06,0x81, +0xbb,0x7c,0x00,0x60,0xcd,0x06,0x81,0xb8,0x6c,0xcd,0x08,0xb1,0x7c,0x67,0x2b,0xcd, +0x08,0xc7,0x00,0x28,0x1b,0x00,0xa0,0xcd,0x04,0x1c,0x20,0x14,0x30,0x26,0x28,0xcd, +0x05,0xea,0x78,0x02,0xcd,0x04,0x74,0x2b,0x80,0x02,0x84,0x50,0x00,0x1a,0xb4,0xcd, +0x07,0x81,0x3c,0x00,0x40,0xcd,0x05,0x9c,0x7c,0x1b,0x00,0x40,0xa0,0xcd,0x05,0xbf, +0x04,0xcd,0x08,0x48,0x78,0xcd,0x07,0x48,0x90,0x20,0x30,0xcd,0x05,0x9d,0x14,0xcd, +0x05,0x44,0x60,0x00,0x1a,0xcd,0x05,0x81,0x38,0xcd,0x09,0x44,0x01,0x1b,0xcd,0x06, +0x81,0x8a,0x38,0x00,0x14,0x00,0x20,0xa0,0x1b,0x80,0x80,0xa9,0x14,0x90,0x20,0x20, +0x14,0xa0,0x40,0x00,0x1a,0x30,0x26,0x20,0x14,0x50,0x26,0x28,0xcd,0x05,0x81,0x38, +0xcd,0x05,0x34,0x50,0x00,0x1a,0xcd,0x04,0x4c,0x00,0x60,0xcd,0x07,0x70,0x10,0xcd, +0x07,0x70,0x04,0xcd,0x08,0x81,0xa4,0x4c,0x20,0x1b,0x00,0x08,0xcd,0x07,0x14,0xcd, +0x07,0x82,0x81,0x68,0xcd,0x05,0x14,0x04,0xcd,0x07,0x14,0xcd,0x07,0x81,0xad,0x50, +0xcd,0x05,0x14,0x02,0xcd,0x07,0x14,0xcd,0x08,0x82,0xac,0x60,0x27,0x20,0x14,0xe0, +0x63,0xcd,0x06,0x82,0x24,0x10,0x27,0x24,0xcd,0x05,0xbb,0x4c,0x84,0x80,0x21,0x0b, +0x91,0xcd,0x09,0x82,0x54,0x28,0xcd,0x05,0x82,0x44,0x01,0x00,0x31,0x1b,0xf2,0xff, +0x25,0x1b,0xc4,0x50,0x00,0x1a,0x80,0x80,0xa1,0x14,0x94,0x40,0x20,0x0b,0xcd,0x04, +0x30,0xcd,0x04,0x24,0xcd,0x04,0x2c,0xcd,0x06,0x81,0x70,0x00,0x14,0xcd,0x05,0x82, +0x3c,0x06,0xa8,0x1b,0xa0,0x80,0xfd,0x34,0x10,0xcd,0x07,0x8d,0x20,0xcd,0x04,0x44, +0x02,0xcd,0x07,0xdf,0x14,0xcd,0x04,0x3c,0xcd,0x04,0x48,0xcd,0x08,0x40,0xcd,0x0c, +0x68,0xcd,0x05,0x92,0x6c,0x20,0x00,0xcd,0x05,0xbc,0x30,0xcd,0x05,0x81,0x2c,0xfa, +0xa0,0x1b,0x80,0x80,0x25,0xcd,0x06,0x81,0x14,0x48,0xcd,0x14,0x70,0xcd,0x08,0x82, +0x14,0x34,0x1b,0x00,0x0c,0xb4,0x1b,0xd0,0x50,0xfc,0x34,0x10,0x78,0xcd,0x08,0x81, +0x6c,0x34,0x1b,0x00,0x0a,0xcd,0x07,0x14,0xcd,0x07,0xed,0x78,0xcd,0x04,0x64,0x04, +0x00,0x25,0x1b,0xe0,0x63,0x00,0xcd,0x05,0xe5,0x3c,0xcd,0x1a,0x81,0x0c,0x20,0x14, +0x05,0x00,0x29,0xcd,0x05,0x81,0x0c,0xcd,0x06,0x8f,0x7c,0x20,0x1b,0x00,0xf6,0xcd, +0x20,0x81,0x0c,0x00,0xcd,0x06,0x81,0xb5,0x14,0x0e,0xcd,0x04,0x28,0xfd,0x34,0x10, +0xcd,0x07,0xd9,0x38,0x00,0x27,0x24,0x14,0x06,0xcd,0x08,0x81,0xb3,0x3c,0xcd,0x04, +0x20,0xf4,0xcd,0x12,0x48,0xcd,0x0c,0x78,0xcd,0x04,0x48,0x07,0x00,0x29,0xcd,0x05, +0x82,0x6c,0xcd,0x09,0x7c,0xf2,0xcd,0x04,0x34,0x21,0x14,0x94,0x40,0x24,0x0b,0x10, +0x27,0xcd,0x06,0x86,0x34,0xcd,0x15,0x82,0x04,0x08,0xcd,0x07,0x81,0x70,0xcd,0x08, +0x81,0xc3,0x10,0xcd,0x04,0x14,0x14,0xcd,0x13,0x82,0x18,0x12,0xcd,0x12,0x82,0x18, +0x08,0xcd,0x25,0x82,0x18,0x28,0x14,0x09,0xcd,0x10,0x83,0x24,0xee,0xcd,0x0c,0x81, +0x50,0xcd,0x14,0x81,0x20,0xcd,0x07,0x82,0x18,0x06,0xcd,0x10,0x82,0x18,0x20,0x14, +0x0a,0xcd,0x07,0x81,0x90,0x08,0xcd,0x04,0x6c,0xcd,0x05,0x24,0xec,0xcd,0x08,0x81, +0x68,0xcd,0x16,0x82,0x18,0x0b,0xcd,0x10,0x82,0x18,0xea,0xcd,0x0e,0x30,0xcd,0x0e, +0x83,0x10,0x28,0x14,0x00,0x50,0x20,0x0e,0x00,0x00,0x30,0x1b,0x00,0x1c,0xb0,0x1b, +0xc0,0x40,0xfc,0x34,0x10,0xcd,0x08,0x81,0xc8,0x50,0xcd,0x04,0x14,0x1a,0xcd,0x07, +0x14,0xcd,0x07,0x81,0xba,0x34,0x00,0x27,0x24,0x14,0x0c,0x00,0x21,0x1b,0xe0,0x53, +0xcd,0x06,0xf2,0x70,0xcd,0x09,0x81,0x14,0xe8,0xcd,0x0e,0x82,0x7c,0xcd,0x04,0x60, +0xcd,0x05,0xc5,0x00,0xcd,0x07,0x81,0x14,0x0d,0xcd,0x10,0x81,0x14,0xe6,0xcd,0x1c, +0x83,0x2c,0xcd,0x07,0x82,0x0c,0x1e,0xcd,0x12,0x82,0x0c,0x0e,0xcd,0x09,0x81,0x92, +0x14,0x20,0x1b,0x00,0xe4,0xcd,0x1c,0x84,0x24,0xcd,0x06,0x87,0x10,0x0f,0x00,0x21, +0xcd,0x05,0x78,0xcd,0x09,0x83,0x08,0xe2,0xcd,0x12,0x82,0x0c,0x30,0xcd,0x0c,0x90, +0x38,0xcd,0x07,0xa2,0x28,0x50,0x26,0x20,0x14,0xc4,0x2c,0x80,0x02,0xb4,0xcd,0x05, +0x81,0x44,0x48,0xcd,0x06,0x8c,0x24,0x90,0xcd,0x0c,0x8c,0x24,0x45,0xcd,0x06,0x8c, +0x24,0x8b,0x24,0xcd,0x06,0x18,0xcd,0x08,0x8c,0x24,0x8b,0xcd,0x14,0x8c,0x24,0xcd, +0x06,0xce,0x14,0x06,0x00,0x24,0x0e,0x06,0x08,0xcd,0x24,0x8c,0x24,0x04,0xcd,0x0f, +0x8c,0x24,0xcd,0x08,0x81,0x9c,0x74,0xa4,0x14,0xcd,0x08,0xf7,0x1c,0xf5,0xcd,0x08, +0x81,0xb7,0x34,0x40,0xcd,0x0e,0x8c,0x24,0xcd,0x14,0xcd,0x00,0x50,0x3e,0x1c,0x14, +0x70,0x06,0x0c,0x14,0x0f,0xf0,0xc1,0x10,0x0a,0xf0,0xc1,0x10,0x60,0x1c,0x0c,0x09, +0x40,0xf8,0x0d,0xcd,0x05,0x8f,0x34,0x02,0x08,0xc3,0x19,0x30,0x00,0x81,0x18,0x24, +0x00,0xcd,0x06,0x9c,0x34,0xcd,0x0c,0x8f,0x34,0x02,0xcd,0x07,0x81,0xcf,0x50,0xfc, +0x43,0x0c,0x0b,0xa8,0x25,0x00,0x1b,0x00,0x18,0xcd,0x0b,0x20,0x48,0x81,0x19,0x02, +0x48,0xc3,0x19,0x00,0x40,0x81,0x18,0x20,0x48,0xc3,0x19,0x90,0xcd,0x07,0x81,0xcf, +0x68,0x0f,0x0a,0x19,0x11,0x00,0xfc,0xbf,0x01,0x1a,0x1a,0x19,0x11,0x4f,0x04,0xa0, +0x17,0x84,0x08,0x00,0x1a,0x4e,0x04,0xcd,0x07,0xf8,0x1c,0x10,0x00,0x1a,0xfc,0x53, +0x0c,0x0b,0x05,0xf0,0xc1,0x10,0x10,0x1e,0x8c,0xcd,0x05,0x81,0x10,0x30,0x00,0x0c, +0xcd,0x05,0x8d,0x0c,0x38,0x00,0x01,0x1b,0x0a,0x58,0xc0,0x10,0xcd,0x04,0x64,0xcd, +0x04,0x10,0xcd,0x04,0x68,0x00,0x58,0xc0,0x10,0xcd,0x10,0x90,0x5c,0x60,0x00,0x01, +0xcd,0x0e,0x81,0x08,0xcd,0x39,0x90,0x5c,0x31,0x18,0x84,0x66,0x2c,0x0b,0x40,0x60, +0x30,0x08,0xe0,0x67,0x30,0x08,0xb0,0x60,0xcd,0x1a,0x90,0x5c,0x10,0x56,0xac,0x14, +0xb0,0xcd,0x08,0x81,0xd1,0x48,0x28,0x2d,0xcd,0x06,0x90,0x5c,0x38,0x2d,0x0e,0x00, +0xf4,0xbf,0x01,0xb0,0x18,0x01,0x1a,0xcd,0x08,0x90,0x5c,0xcd,0x05,0xbf,0x44,0x18, +0xc3,0x19,0xea,0x26,0x00,0xcd,0x05,0x81,0x40,0xcd,0x05,0x48,0x68,0x81,0x19,0x02, +0x68,0xc3,0x19,0x00,0x60,0x81,0x18,0xf0,0x53,0xa0,0x14,0xcd,0x08,0x81,0xd2,0x10, +0x4a,0x02,0x19,0x11,0x50,0x12,0x19,0x11,0x45,0x0a,0x19,0x11,0xcd,0x04,0x48,0x5f, +0x1a,0x19,0x11,0x4d,0x04,0xa4,0x17,0xcd,0x06,0x82,0x2c,0x01,0xcd,0x05,0xa7,0x08, +0x4c,0xcd,0x04,0x0c,0x38,0xcd,0x06,0xc8,0x08,0x04,0x00,0x20,0xcd,0x05,0xe6,0x14, +0x02,0xcd,0x05,0xd4,0x7c,0x00,0x14,0x4f,0x04,0xa4,0x17,0xcd,0x04,0x14,0xcd,0x05, +0xeb,0x20,0x40,0xcd,0x1a,0x82,0x58,0x88,0xcd,0x27,0x82,0x58,0x9c,0xcd,0x81,0x23, +0x82,0x58,0x3a,0x27,0xcd,0x72,0x82,0x58,0xcd,0x06,0xf1,0x00,0xcd,0x0e,0x9e,0x4c, +0x84,0x06,0xcd,0x12,0x9e,0x4c,0x8c,0x06,0xcd,0x06,0xe7,0x10,0xcd,0x0c,0x14,0x94, +0xcd,0x13,0x14,0xf0,0x5b,0x2c,0x14,0x9c,0x06,0x21,0x1b,0x30,0x5e,0xcd,0x07,0x9e, +0x74,0xa8,0xcd,0x08,0x9e,0x38,0x29,0x1b,0x7c,0xcd,0x08,0xfc,0x5c,0x00,0xcd,0x06, +0x91,0x60,0x80,0xcd,0x04,0x40,0xcd,0x07,0x0c,0xa4,0xcd,0x07,0x0c,0x94,0x40,0x00, +0x1a,0xa8,0xcd,0x0b,0x18,0xcd,0x0c,0xc8,0x20,0x54,0x28,0x0c,0x1b,0x03,0xcd,0x05, +0x9f,0x3c,0x28,0x0b,0x10,0x56,0xa8,0x14,0xa0,0x18,0x2c,0x14,0x84,0x06,0x31,0x1b, +0x84,0x06,0x29,0x1b,0xa0,0x58,0x28,0x14,0xfc,0x4b,0x2c,0x0b,0x06,0x50,0x28,0x0e, +0xb0,0x18,0x2c,0x14,0xc0,0x58,0x2c,0x14,0xa4,0x58,0x00,0x1a,0xcd,0x0c,0x2c,0x8c, +0xcd,0x11,0x28,0x30,0x14,0xf0,0x4b,0xa4,0x14,0x8c,0x06,0x2d,0x1b,0x90,0xf0,0xfd, +0x34,0xb0,0x60,0x2c,0x14,0x04,0xa4,0x3f,0x01,0xcd,0x04,0x38,0xcd,0x05,0x82,0x04, +0x18,0xcd,0x07,0xfa,0x3c,0x08,0x24,0x0e,0xcd,0x06,0x89,0x50,0xb0,0x17,0x01,0xcd, +0x07,0x81,0x00,0xa0,0x18,0x10,0xcd,0x05,0xa0,0x24,0xcd,0x05,0x82,0x18,0x20,0x20, +0x14,0xc0,0x4e,0x7c,0x35,0x06,0x40,0x2c,0x0e,0x20,0x50,0x20,0x14,0x10,0x50,0x28, +0xcd,0x06,0x99,0x6c,0x50,0x28,0x0e,0x8a,0x58,0x18,0x10,0x84,0x06,0x2d,0x1b,0xb0, +0x20,0x2c,0x14,0x02,0x00,0xa0,0x17,0x06,0x58,0x2c,0x0e,0xaa,0x58,0xcd,0x07,0x81, +0xbb,0x24,0x50,0xa0,0x14,0x08,0xb4,0x3f,0x01,0x80,0x60,0x30,0x14,0x8c,0x06,0x05, +0x1b,0x00,0x10,0x21,0x1b,0x10,0x18,0x04,0x14,0x80,0x60,0x20,0x14,0xf3,0xcd,0x08, +0x81,0x81,0x04,0xcd,0x07,0x81,0xa7,0x14,0xe0,0x43,0xcd,0x06,0x81,0x80,0x54,0x84, +0x00,0x00,0x1a,0xcd,0x05,0xfc,0x1c,0xcd,0x07,0xee,0x18,0x7c,0x06,0x05,0xcd,0x05, +0x34,0x7c,0x46,0x20,0x0b,0x00,0x08,0xcd,0x06,0x81,0x87,0x00,0x8c,0x46,0xcd,0x06, +0x81,0xa5,0x54,0x01,0x00,0x90,0x0e,0x80,0x08,0x00,0x1a,0x8c,0x46,0xcd,0x08,0x81, +0xae,0x64,0xcd,0x1e,0x82,0x4c,0x94,0x06,0x31,0x1b,0x94,0xcd,0x27,0x82,0x4c,0x9c, +0xcd,0x17,0x82,0x4c,0x9c,0xcd,0x13,0x82,0x4c,0x94,0xcd,0x27,0x82,0x4c,0x9c,0xcd, +0x23,0x82,0x4c,0x94,0xcd,0x23,0x82,0x4c,0x9c,0xcd,0x37,0x82,0x4c,0x80,0xcd,0x33, +0x82,0x4c,0x9a,0xcd,0x05,0x8d,0x30,0xa4,0x17,0x30,0x3e,0x9c,0x14,0x8a,0x40,0x18, +0x10,0x01,0x20,0x80,0x1a,0x02,0x00,0xa0,0x17,0x01,0x28,0x80,0x1a,0x90,0x40,0x24, +0xcd,0x05,0x9c,0x50,0xf1,0xff,0x21,0xcd,0x05,0x9c,0x50,0x8c,0x48,0x44,0x0b,0x13, +0x2f,0x80,0x02,0xcd,0x05,0xd4,0x04,0xcd,0x08,0x81,0xd7,0x38,0x31,0x04,0x1b,0xc2, +0x2d,0xc0,0x02,0xa8,0x31,0x08,0xcd,0x05,0x14,0x10,0x3e,0x00,0x14,0xb0,0x31,0x04, +0x1b,0x15,0x2e,0xc0,0x02,0xb8,0x31,0x08,0x1b,0xcd,0x0c,0x81,0x86,0x34,0x1c,0x46, +0x20,0x0b,0x90,0x40,0xfc,0x34,0x08,0xcd,0x07,0x9a,0x14,0x70,0x26,0xcd,0x06,0x81, +0xc5,0x18,0x22,0x2f,0xcd,0x06,0x90,0x14,0xcd,0x0c,0x81,0x8b,0x20,0xcd,0x12,0x2c, +0x20,0xcd,0x05,0x96,0x7c,0xcd,0x04,0x2c,0x94,0x40,0x00,0x1a,0xcd,0x04,0x10,0xcd, +0x05,0xf6,0x20,0x40,0x00,0x1a,0xcd,0x04,0x14,0xcd,0x04,0x24,0xae,0x06,0x01,0x1b, +0xa4,0x06,0x05,0x1b,0x00,0x20,0x14,0x14,0x06,0x28,0x24,0x0e,0x06,0x28,0x20,0x0e, +0x90,0x88,0xa4,0x14,0xa8,0x06,0x01,0x1b,0xdc,0x4e,0x24,0x0b,0xcd,0x05,0xb0,0x78, +0x20,0xcd,0x06,0xb6,0x28,0x10,0x81,0x21,0x14,0x10,0x20,0x04,0xcd,0x05,0x9a,0x14, +0xcd,0x0c,0xed,0x78,0xcd,0x04,0x0c,0xcd,0x05,0xf0,0x2c,0xcd,0x07,0x81,0xde,0x04, +0xdc,0x86,0x49,0x0b,0x00,0x00,0x45,0xcd,0x05,0xd6,0x44,0x14,0x09,0xcd,0x06,0x81, +0xd1,0x24,0xcd,0x05,0xb4,0x58,0x3b,0x00,0x14,0xc0,0xcd,0x07,0x81,0x7c,0xc8,0x31, +0x08,0xcd,0x05,0xb4,0x48,0x10,0x3e,0x00,0x14,0xd0,0xcd,0x07,0x81,0x7c,0xd8,0x31, +0x08,0x1b,0x06,0x28,0x20,0x0e,0x32,0x00,0xcd,0x07,0x81,0xaa,0x7c,0xcd,0x07,0xce, +0x50,0xcd,0x0c,0x81,0x64,0xcd,0x06,0x81,0x88,0x44,0xcd,0x0e,0x81,0x64,0x03,0xcd, +0x0b,0x81,0x64,0xcd,0x12,0x81,0x88,0x70,0xcd,0x1a,0x82,0x10,0xcd,0x04,0x54,0x00, +0x47,0xfc,0x34,0x08,0xcd,0x07,0x9a,0x10,0xcd,0x08,0x81,0x89,0x38,0xcd,0x05,0x14, +0xcd,0x07,0x92,0x34,0xcd,0x04,0x34,0xcd,0x04,0x30,0x14,0x41,0xcd,0x06,0x82,0x40, +0xcd,0x04,0x08,0xcd,0x08,0x82,0x3c,0xcd,0x10,0x10,0xcd,0x08,0x83,0x60,0x80,0xcd, +0x07,0x81,0x64,0x88,0xcd,0x0b,0x83,0x60,0x90,0xcd,0x07,0x81,0x64,0x98,0xcd,0x21, +0x83,0x60,0xcd,0x1a,0x81,0x50,0x1c,0xcd,0x05,0xfd,0x00,0xcd,0x2e,0x83,0x60,0xb0, +0xcd,0x07,0x94,0x08,0x30,0x46,0xcd,0x07,0xf8,0x48,0xcd,0x17,0xe5,0x2c,0xe0,0xcd, +0x13,0xb9,0x4c,0xcd,0x06,0xb6,0x34,0xcd,0x16,0xdf,0x7c,0xcd,0x08,0x86,0x04,0xa4, +0x06,0x05,0x1b,0x8a,0xcd,0x07,0x81,0x8a,0x50,0x30,0x3e,0x9c,0x14,0xcd,0x05,0x86, +0x00,0xcd,0x08,0xaa,0x24,0x88,0x80,0x1a,0xa8,0x06,0x01,0x1b,0xf1,0xff,0xcd,0x06, +0xf3,0x7c,0xcd,0x05,0x94,0x14,0x80,0xcd,0x12,0x84,0x44,0x01,0x90,0x80,0x1a,0xcd, +0x0d,0x84,0x48,0xd8,0xcd,0x06,0x81,0x18,0xcd,0x3c,0x84,0x48,0xcd,0x0d,0x84,0x08, +0x43,0xcd,0x16,0x86,0x44,0x76,0xcd,0x13,0x86,0x44,0xcd,0x12,0x2c,0xcd,0x06,0x82, +0x64,0xcd,0x04,0x2c,0xcd,0x08,0x83,0x10,0x32,0xcd,0x07,0x81,0x85,0x5c,0xcd,0x05, +0x83,0x0c,0xcd,0x08,0x81,0x85,0x4c,0x38,0xcd,0x07,0x10,0xcd,0x0b,0x84,0x38,0xcd, +0x04,0x34,0xcd,0x0c,0x84,0x38,0xcd,0x0e,0x82,0x50,0xcd,0x0a,0x82,0x4c,0xcd,0x06, +0x8f,0x10,0x25,0x1b,0xb0,0x06,0xcd,0x06,0x81,0xaf,0x24,0xcd,0x05,0xe9,0x00,0xcd, +0x0b,0x8e,0x1c,0x00,0x00,0x21,0x1b,0xcc,0xcd,0x05,0xfd,0x40,0xcd,0x06,0x81,0xd0, +0x40,0x68,0xcd,0x0b,0x0c,0x6c,0xcd,0x0b,0x0c,0xcd,0x0d,0x81,0xaf,0x44,0x00,0xcd, +0x0f,0x81,0xd8,0x0c,0x00,0xcd,0x06,0xb8,0x40,0xcd,0x11,0x81,0xab,0x78,0xcd,0x10, +0xd2,0x74,0xcd,0x09,0x81,0xd9,0x20,0x14,0xcd,0x0b,0x81,0xd4,0x74,0xf4,0xcd,0x05, +0xb0,0x10,0x44,0xee,0xcd,0x06,0x81,0xd4,0x70,0xcd,0x06,0xf3,0x5c,0xcd,0x06,0x87, +0x6c,0x4c,0xcd,0x07,0x81,0xc1,0x3c,0x51,0xcd,0x07,0x81,0xcd,0x08,0xcd,0x16,0x81, +0xca,0x2c,0x44,0x1b,0x1d,0x00,0xc4,0xcd,0x06,0x81,0xca,0x10,0x8b,0x24,0xcd,0x05, +0x98,0x50,0xcd,0x08,0x81,0xca,0x2c,0xcc,0xcd,0x05,0x90,0x20,0x49,0xcd,0x05,0xe6, +0x10,0x20,0x41,0xcd,0x10,0x81,0xd1,0x64,0x24,0x04,0x00,0xcd,0x08,0xd5,0x24,0x1c, +0xcd,0x06,0x70,0x5a,0xcd,0x08,0x81,0xce,0x08,0x43,0xfc,0x34,0x01,0xcd,0x07,0x81, +0xad,0x74,0xcd,0x0a,0x81,0xd3,0x24,0xcd,0x06,0x81,0x28,0x71,0x34,0xc0,0x02,0xe0, +0xeb,0x10,0xcd,0x05,0xbe,0x44,0x10,0xcd,0x07,0x81,0xc4,0x14,0xf0,0xff,0x25,0x1b, +0x4d,0x43,0x20,0x0b,0x45,0x4b,0x24,0x0b,0x8c,0x46,0xcd,0x07,0x81,0xc4,0x08,0xcd, +0x07,0x81,0x91,0x74,0x94,0x00,0x00,0x1a,0x3b,0xcd,0x05,0xd7,0x70,0x24,0xcd,0x0a, +0x81,0xc7,0x48,0xcd,0x08,0xf5,0x3c,0x93,0x48,0x14,0xb8,0x0b,0x25,0x1b,0x20,0x49, +0xcd,0x0a,0xbc,0x54,0xc7,0xcd,0x07,0x86,0x5c,0x50,0xcd,0x08,0x81,0xb4,0x24,0x48, +0xcd,0x06,0x18,0x2c,0x2f,0x00,0xcd,0x05,0xe7,0x18,0x84,0x00,0x00,0x1a,0x34,0x2f, +0x00,0x1b,0xcd,0x18,0x81,0xca,0x10,0x0c,0x30,0xcd,0x06,0x40,0xcd,0x08,0x81,0xc3, +0x58,0xcd,0x08,0x10,0x00,0x00,0x21,0x1b,0xcd,0x04,0x44,0xcd,0x0a,0x40,0xcd,0x07, +0xb5,0x1c,0xcd,0x0f,0x81,0xc4,0x28,0xcd,0x0c,0x40,0xcd,0x10,0x81,0xc5,0x20,0xcd, +0x08,0x81,0xd7,0x70,0x00,0x00,0x58,0x1b,0x08,0xb1,0xcd,0x12,0x81,0xc2,0x10,0xb0, +0x2e,0xcd,0x06,0x81,0x87,0x64,0x1a,0x34,0xcd,0x06,0x85,0x50,0x7c,0xcd,0x07,0x81, +0xd8,0x30,0xcd,0x08,0x81,0xac,0x18,0xe0,0x43,0x50,0x14,0x80,0x46,0x20,0x04,0x50, +0x46,0xcd,0x06,0x81,0xa3,0x04,0xcd,0x04,0x14,0xcd,0x0a,0x81,0xac,0x40,0x4c,0x14, +0xff,0xff,0x24,0x1b,0x0f,0xff,0xa4,0xcd,0x05,0x83,0x1c,0x30,0xcd,0x05,0xf9,0x64, +0xcd,0x0a,0x81,0xa3,0x2c,0xcd,0x0a,0x81,0xb0,0x30,0xcd,0x06,0x83,0x08,0xcd,0x04, +0x10,0xc8,0xcd,0x0b,0x10,0x1f,0x00,0x21,0x1b,0x0c,0x34,0x80,0x02,0x80,0xe8,0x20, +0x04,0xcd,0x04,0x58,0xcd,0x04,0x38,0x09,0xcd,0x07,0x81,0xb2,0x00,0xcd,0x04,0x40, +0x0f,0xff,0xcd,0x06,0x81,0xb3,0x3c,0xcd,0x05,0xe4,0x04,0xcd,0x0b,0x58,0x4c,0xcd, +0x07,0xdb,0x2c,0xcd,0x08,0x84,0x64,0xcd,0x0c,0xdc,0x30,0xcd,0x0e,0xdc,0x2c,0x28, +0x04,0x00,0x08,0xcd,0x07,0x84,0x30,0xcd,0x07,0x87,0x18,0xcd,0x05,0xa7,0x64,0xcd, +0x07,0x82,0x40,0xb0,0x2e,0x20,0x14,0x05,0xcd,0x0b,0x81,0x7c,0xcd,0x04,0x58,0x04, +0xcd,0x0b,0x58,0x98,0x2d,0xcd,0x08,0xc5,0x60,0x45,0x1b,0x70,0xcd,0x0b,0x81,0x92, +0x14,0x10,0x41,0xcd,0x0a,0x81,0xbd,0x40,0xcd,0x04,0x0c,0xcd,0x08,0x81,0xc0,0x3c, +0xcd,0x2e,0x85,0x0c,0x49,0xcd,0x09,0x85,0x0c,0xcd,0x08,0x81,0xc9,0x20,0x10,0x3e, +0x04,0xcd,0x05,0x85,0x04,0xcd,0x14,0x81,0xc9,0x1c,0xcd,0x06,0x81,0xc7,0x2c,0xcd, +0x06,0xef,0x30,0x06,0x38,0x20,0x0e,0x29,0x2f,0xcd,0x06,0xb1,0x28,0xcd,0x09,0x81, +0xc9,0x1c,0xb4,0xcd,0x07,0x85,0x20,0x8b,0x44,0x14,0x88,0x13,0x21,0x1b,0x10,0x41, +0xcd,0x0a,0x85,0x20,0x6a,0xcd,0x07,0x84,0x20,0x70,0xcd,0x07,0x81,0xbf,0x58,0xcd, +0x05,0xe7,0x48,0xcd,0x07,0x89,0x18,0xcd,0x0c,0xdc,0x60,0xb0,0x2e,0x20,0xcd,0x05, +0xa6,0x14,0xcd,0x0c,0x82,0x10,0xcd,0x42,0x87,0x4c,0x45,0xcd,0x09,0x82,0x28,0xcd, +0x19,0x87,0x4c,0xcd,0x07,0x8b,0x60,0xcd,0x38,0x82,0x40,0xcd,0x29,0x87,0x4c,0xcd, +0x08,0x82,0x2c,0xcd,0x08,0x87,0x4c,0xcd,0x05,0x82,0x2c,0x25,0x1b,0x10,0xcd,0x0b, +0x87,0x4c,0xba,0xcd,0x07,0x82,0x2c,0xcd,0x09,0x87,0x4c,0xcd,0x07,0x84,0x38,0x01, +0x00,0x25,0x1b,0xd0,0x06,0xcd,0x06,0x87,0x10,0xcd,0x08,0xf4,0x14,0xee,0x30,0xcd, +0x06,0x81,0x91,0x48,0x00,0xcd,0x13,0x1c,0xcd,0x04,0x18,0xcd,0x10,0x82,0x40,0xcd, +0x29,0x82,0x10,0x54,0xcd,0x34,0x89,0x5c,0xcd,0x46,0x82,0x10,0x10,0x27,0xcd,0x0e, +0x82,0x10,0xfe,0xcd,0x08,0x89,0x0c,0x03,0xcd,0x07,0x82,0x10,0xcd,0x07,0xc3,0x40, +0xb0,0x2e,0x24,0x14,0x03,0xcd,0x07,0x81,0x8b,0x54,0xcd,0x0c,0x81,0xd9,0x34,0xa4, +0x48,0x00,0x1a,0xcd,0x08,0x81,0xd4,0x08,0xa4,0x00,0x00,0x1a,0xcd,0x09,0xc8,0x64, +0xcd,0x0b,0x89,0x34,0xe0,0x53,0x20,0x14,0x1a,0x34,0xcd,0x0e,0x89,0x34,0xcd,0x08, +0x10,0xcd,0x08,0x89,0x10,0xcd,0x06,0x81,0xc5,0x58,0xcd,0x0e,0x81,0xda,0x14,0xcd, +0x08,0x58,0xcd,0x05,0x97,0x2c,0xcd,0x13,0x58,0x02,0x00,0x21,0xcd,0x05,0x85,0x3c, +0xcd,0x18,0x58,0xff,0xcd,0x0f,0x85,0x5c,0x11,0xcd,0x13,0x88,0x44,0xcd,0x09,0x81, +0xde,0x4c,0x10,0xcd,0x06,0x81,0x70,0xcd,0x08,0xe3,0x44,0x08,0x07,0x21,0x1b,0x21, +0x47,0xcd,0x06,0x85,0x7c,0x05,0x00,0xa4,0xcd,0x13,0x88,0x7c,0x24,0xcd,0x07,0x81, +0xf4,0x54,0x24,0x04,0x00,0x03,0xcd,0x07,0x83,0x48,0xcd,0x09,0x86,0x58,0x24,0x14, +0x0e,0xcd,0x07,0x81,0x1c,0x84,0x48,0x00,0x1a,0xcd,0x04,0x4c,0xdd,0x33,0xcd,0x06, +0x4c,0x06,0xcd,0x33,0x4c,0x0d,0xcd,0x0f,0x4c,0xc6,0x69,0xcd,0x1c,0x81,0x18,0xcd, +0x10,0x8a,0x14,0x20,0x04,0x00,0x10,0xcd,0x07,0xe6,0x34,0xcd,0x07,0x83,0x64,0x9d, +0x31,0xcd,0x07,0xe5,0x34,0xcd,0x04,0x14,0xcd,0x0b,0x88,0x0c,0x0c,0xcd,0x0b,0x82, +0x30,0x08,0x07,0x45,0x1b,0x4b,0xf6,0x24,0xcd,0x05,0x95,0x40,0x15,0x1c,0xc0,0x02, +0x04,0xcd,0x13,0x6c,0xcd,0x11,0x82,0x3c,0xcd,0x09,0x81,0xd3,0x14,0x20,0x14,0xcd, +0x1c,0x82,0x3c,0xcd,0x09,0x86,0x00,0xcd,0x13,0x81,0x6c,0x0b,0xcd,0x0f,0x81,0x6c, +0x3a,0x2e,0xcd,0x36,0x48,0x06,0xcd,0x0d,0x48,0x45,0x1b,0x41,0xdd,0xcd,0x0a,0x81, +0x4c,0xcd,0x1a,0x4c,0xcd,0x0b,0x81,0x4c,0xcd,0x07,0x85,0x78,0xcd,0x04,0x34,0x51, +0xa5,0xcd,0x20,0x81,0x04,0x20,0x04,0x00,0x08,0xcd,0x07,0x38,0xcd,0x0b,0x82,0x50, +0x07,0xcd,0x0b,0x82,0x50,0xcd,0x04,0x10,0x08,0xcd,0x0f,0x10,0xcd,0x1c,0x85,0x20, +0x08,0x07,0x21,0xcd,0x05,0x83,0x00,0xcd,0x29,0x82,0x7c,0xcd,0x0b,0x81,0x7c,0x09, +0xcd,0x40,0x81,0x7c,0xec,0xcd,0x07,0x81,0xc5,0x5c,0xcd,0x30,0x83,0x48,0xa4,0xcd, +0x0a,0x94,0x14,0x10,0xcd,0x05,0xc4,0x28,0x49,0x1b,0x5a,0xcd,0x08,0x81,0xe2,0x00, +0xcd,0x0f,0x89,0x54,0xcd,0x0c,0x90,0x28,0x64,0xcd,0x0b,0x93,0x30,0x7c,0xa6,0x21, +0x0b,0x10,0x3e,0xcd,0x06,0xf1,0x5c,0xcd,0x08,0x8e,0x20,0x8c,0xa6,0x21,0xcd,0x09, +0x8e,0x1c,0xcd,0x08,0x81,0xd5,0x48,0x06,0x38,0x20,0x0e,0x3b,0xcd,0x04,0x38,0x43, +0x24,0xcd,0x0a,0x81,0xbf,0x68,0xc4,0xcd,0x0a,0x93,0x34,0x20,0x4e,0xcd,0x0e,0x93, +0x34,0x33,0x32,0xcd,0x07,0x89,0x58,0xcd,0x08,0x8b,0x68,0xcd,0x0b,0x82,0x30,0x10, +0xcd,0x0b,0x82,0x30,0x4c,0x34,0xc0,0x02,0x0f,0xcd,0x07,0x81,0x3c,0xcc,0xcd,0x07, +0x8f,0x74,0x20,0x41,0x00,0x1a,0xcd,0x08,0x81,0xcd,0x64,0xcd,0x04,0x0c,0xcd,0x08, +0x81,0xcd,0x64,0xcd,0x04,0x0c,0xcd,0x81,0x08,0x81,0x60,0x6b,0xcd,0x10,0x81,0x60, +0xcd,0x07,0x9d,0x54,0xb0,0x2e,0x24,0xcd,0x05,0xb0,0x30,0xcd,0x08,0x81,0x60,0xb0, +0x2e,0xcd,0x06,0xb2,0x7c,0xcd,0x1c,0x85,0x08,0x02,0xcd,0x59,0x97,0x50,0x20,0x04, +0xcd,0x08,0x81,0x20,0xcd,0x36,0x90,0x04,0xcd,0x46,0x97,0x50,0x88,0x13,0xcd,0x0e, +0x82,0x3c,0xbb,0xcd,0x07,0x82,0x3c,0xcd,0x24,0x90,0x04,0xef,0x32,0xcd,0x22,0x90, +0x04,0xcd,0x0c,0x82,0x40,0xcd,0x81,0x34,0x90,0x04,0xff,0xcd,0x08,0x84,0x4c,0xcd, +0x11,0x90,0x04,0xcd,0x06,0x9e,0x0c,0xcd,0x08,0x8f,0x2c,0xcd,0x0c,0x81,0xea,0x20, +0xcd,0x20,0x8f,0x2c,0xcd,0x0c,0x8f,0x1c,0xcd,0x08,0x99,0x48,0xcd,0x0a,0x8f,0x2c, +0x24,0x14,0x00,0x00,0x29,0x1b,0x02,0xcd,0x33,0x90,0x5c,0xcd,0x10,0x58,0xcd,0x0c, +0x90,0x6c,0xcd,0x14,0x85,0x5c,0x03,0xcd,0x64,0x9d,0x2c,0xcd,0x81,0x0b,0x85,0x5c, +0x72,0x33,0xcd,0x2a,0x85,0x5c,0xa6,0x33,0xcd,0x22,0x85,0x5c,0xcd,0x0c,0x82,0x40, +0xcd,0x29,0x85,0x5c,0x50,0xcd,0x81,0x0a,0x85,0x5c,0xb6,0xcd,0x07,0x82,0x10,0xcd, +0x09,0x85,0x5c,0xcd,0x07,0x81,0x9a,0x20,0xcd,0x06,0x95,0x60,0xcd,0x12,0x81,0xef, +0x10,0xcd,0x40,0x85,0x58,0xcd,0x04,0x54,0xcd,0x08,0x50,0xcd,0x58,0x95,0x5c,0xf0, +0x43,0xcd,0x07,0x81,0xc1,0x04,0xcd,0x07,0xbf,0x54,0x15,0x00,0xcd,0x06,0x82,0x78, +0xcd,0x0c,0xe1,0x2c,0xf0,0xcd,0x13,0xa7,0x60,0xcd,0x04,0x48,0xe0,0xa3,0x24,0xcd, +0x05,0xdf,0x20,0xcd,0x08,0x9f,0x6c,0xe0,0x9b,0xcd,0x06,0x85,0x70,0xcd,0x08,0x9f, +0x50,0xcd,0x14,0xd4,0x38,0xf0,0xaf,0xcd,0x06,0xd4,0x38,0xf0,0xbf,0xcd,0x16,0xd4, +0x38,0xcd,0x0a,0xde,0x6c,0xcd,0x07,0xa0,0x08,0xcd,0x0d,0xe4,0x68,0xcd,0x16,0xa8, +0x48,0x54,0x28,0x00,0x1b,0xcc,0xcd,0x07,0xa8,0x4c,0x10,0x00,0x00,0xcd,0x05,0xaf, +0x6c,0xcd,0x09,0x81,0xaa,0x64,0x80,0x21,0x15,0xf4,0xcd,0x07,0xaf,0x50,0x80,0x80, +0xcd,0x08,0x81,0xb2,0x0c,0xcd,0x06,0xb5,0x50,0x8c,0x46,0x20,0x0b,0xe0,0x43,0x20, +0x14,0xcd,0x08,0x82,0xfb,0x38,0xcd,0x0a,0x81,0x84,0x7c,0x25,0x1b,0xf0,0x4b,0x24, +0x14,0x80,0x96,0x20,0x1b,0x98,0x00,0xa0,0xcd,0x06,0x81,0x9a,0x5c,0xcd,0x09,0x82, +0x83,0x64,0xcd,0x0a,0x81,0xc2,0x14,0xcd,0x10,0x81,0xf7,0x48,0xcd,0x05,0xb0,0x1c, +0xf0,0x20,0x0b,0xcd,0x08,0xd5,0x7c,0xf0,0x43,0x20,0x04,0xcd,0x18,0x81,0xe8,0x00, +0x42,0xcd,0x13,0x81,0xe8,0x00,0xcd,0x09,0x5c,0xcd,0x2b,0x81,0xe8,0x34,0xcd,0x0c, +0x81,0x10,0xcd,0x1c,0xd7,0x30,0xe0,0xad,0xcd,0x06,0x82,0x78,0xe0,0xbd,0xcd,0x22, +0xd7,0x30,0xe0,0x43,0xfc,0xcd,0x05,0xee,0x60,0x00,0x40,0x3d,0x1b,0x02,0x10,0x00, +0x01,0x05,0xb5,0x40,0x1b,0xc5,0xcd,0x07,0x84,0x40,0x00,0x40,0x34,0x07,0x20,0x6f, +0xcd,0x0a,0xee,0x6c,0x64,0x27,0x00,0xcd,0x06,0x8f,0x1c,0xcd,0x07,0xe8,0x64,0x00, +0x40,0x81,0x18,0xf5,0x7b,0x18,0x10,0x15,0x42,0x18,0x11,0x15,0x72,0x98,0x11,0x41, +0x04,0xb0,0x17,0xcd,0x04,0x10,0xc5,0x40,0xcd,0x10,0x10,0xcd,0x20,0x20,0xcd,0x0a, +0x10,0x00,0x62,0x30,0x14,0x09,0x00,0xcd,0x06,0x81,0x81,0x48,0x90,0x60,0x30,0x14, +0xf0,0x53,0xcd,0x06,0x82,0x8e,0x74,0xcd,0x08,0x81,0x88,0x60,0xc5,0x80,0x00,0x10, +0xcd,0x04,0x28,0xf0,0x53,0x20,0x14,0x04,0x46,0xcd,0x12,0xee,0x74,0xcd,0x0c,0xd9, +0x08,0xcd,0x0d,0x82,0xa5,0x74,0xcd,0x15,0x15,0xcd,0x2a,0x2a,0xcd,0x54,0x54,0xcd, +0x41,0x41,0x30,0x00,0x00,0x01,0x30,0x00,0x00,0x02,0x30,0xcd,0x0e,0x17,0xb4,0xf5, +0xcd,0x06,0x83,0xa8,0x30,0x54,0xcd,0x07,0x10,0x54,0x20,0x00,0x00,0xb0,0x0f,0x00, +0x00,0x08,0xf6,0x00,0x00,0x04,0x30,0xcd,0x09,0x83,0xa8,0x67,0x00,0x44,0x30,0x00, +0x00,0x36,0x00,0x00,0x00,0x48,0xf6,0x00,0x00,0x7c,0x30,0xcd,0x05,0x33,0x00,0x90, +0xf7,0x00,0x00,0x1c,0x31,0x00,0x00,0x10,0x00,0x00,0x00,0xa0,0xf7,0x00,0x00,0x2c, +0x31,0xcd,0x06,0x48,0xb0,0xf9,0x00,0x00,0x80,0x31,0x00,0x00,0x70,0xcd,0x04,0x5b, +0xfa,0x00,0x00,0xf0,0x31,0x00,0x00,0x58,0xcd,0x0f,0x81,0x0f,0xf4,0xf7,0x00,0x00, +0xa8,0x25,0x00,0x00,0xba,0x01,0x00,0x00,0x78,0xfa,0x00,0x00,0x64,0x27,0xcd,0x06, +0x83,0xa9,0x5c,0xcd,0x0d,0x25,0x07,0x04,0x07,0x08,0x07,0x0c,0x07,0x10,0x07,0x14, +0x07,0x1c,0x07,0x20,0x07,0x24,0x07,0x28,0x07,0x2c,0x07,0x30,0x07,0x34,0x07,0x38, +0x07,0x3c,0x07,0x40,0x07,0x44,0x07,0x48,0x07,0x4c,0x07,0x50,0x07,0x54,0x07,0x58, +0x07,0x5c,0x07,0x60,0x07,0x64,0x07,0x68,0x07,0x6c,0x07,0x80,0x07,0x84,0x07,0x8c, +0x07,0x90,0x07,0x94,0x07,0x98,0x07,0xcd,0x06,0x47,0x08,0x00,0x01,0x08,0xb0,0xf8, +0x1a,0xcd,0x06,0x82,0x88,0x77,0x6f,0x1f,0x00,0xf8,0xdf,0x1e,0xcd,0x05,0x0c,0xf2, +0xff,0x2c,0x00,0x24,0x00,0xb4,0xff,0x9c,0xff,0x70,0x00,0xdc,0x00,0x88,0xff,0x5a, +0xfe,0x3a,0x00,0xe2,0x02,0xa4,0x00,0xfc,0xfa,0xb2,0xfc,0x22,0x0b,0xa0,0x1a,0xcd, +0x20,0x20,0xcd,0x05,0x5b,0xcd,0x07,0x81,0x2b,0x0a,0xcd,0x07,0x82,0x94,0x46,0xcd, +0x04,0x04,0xcd,0x08,0x08,0xcd,0x0c,0x81,0x4b,0x08,0x00,0x01,0x09,0xcd,0x08,0x81, +0x04,0xe9,0x2f,0x1d,0xcd,0x04,0x04,0xcd,0x74,0x81,0x04,0x08,0x97,0xf9,0xcd,0x06, +0x81,0x04,0x16,0x70,0x1f,0x00,0x2c,0xe0,0xcd,0x06,0x82,0x08,0xf0,0xff,0xf2,0xff, +0x36,0x00,0x1c,0x00,0x92,0xff,0xba,0xff,0xd0,0x00,0x92,0x00,0x9a,0xfe,0xe0,0xfe, +0x56,0x02,0x36,0x02,0xe2,0xfb,0x0e,0xfb,0xe8,0x09,0x3a,0x1c,0xcd,0x20,0x20,0xcd, +0x30,0x82,0x08,0xcd,0x08,0x81,0x04,0x6a,0x30,0x1d,0xcd,0x04,0x04,0xcd,0x74,0x81, +0x04,0x08,0xb6,0xcd,0x13,0x84,0x10,0xcd,0x06,0x64,0x1e,0x00,0x92,0xff,0xb8,0xff, +0xce,0x00,0x94,0x00,0x9c,0xfe,0xde,0xfe,0x54,0x02,0x38,0x02,0xe6,0xfb,0x0a,0xfb, +0xe4,0x09,0x3e,0xcd,0x07,0x81,0x04,0xcd,0x1a,0x20,0xcd,0x30,0x82,0x08,0xcd,0x08, +0x81,0x04,0xec,0x2f,0x1d,0xcd,0x04,0x04,0xcd,0x71,0x81,0x04,0x88,0xcd,0x0b,0x85, +0x14,0x1d,0xf8,0x01,0x00,0xf0,0xcd,0x07,0x82,0x08,0x06,0x00,0x64,0x00,0x26,0x00, +0xba,0xff,0x4c,0xff,0x6e,0xff,0x56,0x00,0x6a,0x01,0x82,0x01,0xe8,0xff,0x6e,0xfd, +0x52,0xfc,0xd4,0xfe,0x4a,0x05,0x48,0x0d,0xca,0x12,0xcd,0x20,0x20,0xcd,0x08,0x83, +0xb1,0x23,0xcd,0x04,0x04,0xcd,0x06,0x83,0x8a,0x61,0xcd,0x1a,0x81,0x04,0x18,0x00, +0x05,0x0a,0x9c,0xb8,0x1a,0x00,0xa3,0x00,0x02,0xcd,0x05,0x81,0x04,0xcd,0x08,0x18, +0xf2,0xff,0x40,0x00,0x64,0x00,0x02,0x00,0x18,0xff,0x9c,0xfe,0xc4,0xff,0x52,0x02, +0xc4,0x03,0x36,0x01,0x02,0xfb,0x90,0xf6,0x40,0xfb,0xe2,0x0b,0x6e,0x22,0xa6,0x32, +0xea,0xff,0x62,0x00,0x9a,0x00,0x04,0x00,0x9c,0xfe,0xde,0xfd,0xa4,0xff,0x92,0x03, +0xcc,0x05,0xdc,0x01,0x52,0xf8,0x7c,0xf1,0xb0,0xf8,0x4a,0x12,0xfa,0x34,0xec,0x4d, +0xcd,0x0c,0x81,0x04,0x3c,0xcd,0x23,0x81,0x04,0xc5,0xd1,0x1a,0x00,0x7e,0xbf,0x01, +0x00,0x2c,0x94,0xcd,0x0a,0x81,0x04,0x70,0x00,0xb4,0xff,0x34,0xff,0x0e,0xff,0xce, +0xff,0x60,0x01,0xbc,0x02,0x68,0x02,0x96,0xff,0x4a,0xfb,0x6e,0xf8,0x8e,0xfa,0x8a, +0x03,0xe8,0x11,0xde,0x20,0x66,0x2a,0x80,0x00,0xa8,0xff,0x16,0xff,0xe8,0xfe,0xc6, +0xff,0x96,0x01,0x28,0x03,0xc6,0x02,0x86,0xff,0x90,0xfa,0x44,0xf7,0xb8,0xf9,0x16, +0x04,0xaa,0x14,0xec,0x25,0xec,0x30,0xcd,0x2c,0x81,0x04,0x00,0x00,0x05,0x0a,0xbf, +0x22,0xcd,0x06,0x81,0x04,0x2f,0xcd,0x0b,0x81,0x04,0xda,0xff,0xc4,0xff,0xcc,0xff, +0x16,0x00,0x94,0x00,0x00,0x01,0xea,0x00,0x06,0x00,0x7c,0xfe,0x0e,0xfd,0xe6,0xfc, +0x08,0xff,0xae,0x03,0xf0,0x09,0xee,0x0f,0x9c,0x13,0x16,0xff,0x94,0xfe,0xce,0xfe, +0x88,0x00,0x7e,0x03,0xfe,0x05,0x78,0x05,0x20,0x00,0xe2,0xf6,0x50,0xee,0x62,0xed, +0x2e,0xfa,0x14,0x16,0x9a,0x3b,0x98,0x5f,0xa6,0x75,0xcd,0x2c,0x81,0x04,0x08,0x00, +0x03,0x12,0xbf,0x22,0xcd,0x06,0x84,0x10,0xcd,0x0c,0x18,0x2a,0x00,0xe2,0xff,0xb2, +0xff,0xa2,0xff,0xec,0xff,0x88,0x00,0x0e,0x01,0xec,0x00,0xd8,0xff,0x30,0xfe,0x16, +0xfd,0xe8,0xfd,0x5c,0x01,0xe4,0x06,0xa4,0x0c,0x4e,0x10,0xcd,0x20,0x20,0xcd,0x0c, +0x81,0x04,0x0b,0xcd,0x23,0x81,0x04,0xb5,0x09,0x1b,0xcd,0x81,0x01,0x81,0x04,0xcd, +0x81,0x00,0x82,0x08,0x18,0x4e,0x02,0x30,0x21,0x47,0x05,0x00,0xb1,0x86,0xcd,0x08, +0x95,0x03,0xcd,0x07,0x82,0xa0,0x1e,0xcd,0x1f,0x84,0x74,0x44,0x00,0x2c,0x00,0x90, +0xff,0x90,0xff,0x5a,0x00,0x9c,0x00,0x90,0xff,0x0a,0xff,0xf6,0x00,0xe4,0x02,0x2c, +0x00,0x2c,0xf9,0xda,0xf7,0xec,0x06,0x8e,0x23,0x08,0x3b,0x0a,0x00,0x10,0x05,0xcd, +0x05,0xcc,0x47,0x5d,0xcd,0x08,0x82,0xb7,0x67,0xcd,0x1b,0x81,0x04,0x0e,0xcd,0x81, +0x03,0x81,0x04,0x4e,0x02,0x30,0x44,0xe9,0x05,0x00,0xee,0xfb,0xcd,0x0e,0x93,0x2b, +0x78,0x00,0xae,0xff,0x24,0xff,0xfc,0xfe,0xca,0xff,0x7a,0x01,0xf2,0x02,0x98,0x02, +0x8e,0xff,0xec,0xfa,0xda,0xf7,0x22,0xfa,0xd0,0x03,0x4a,0x13,0x64,0x23,0xaa,0x2d, +0xe0,0xff,0x00,0x00,0x40,0x00,0xc0,0xff,0x00,0x00,0x60,0x00,0xa0,0xff,0xe0,0xff, +0xc0,0x00,0x40,0xff,0xc0,0xff,0x20,0x02,0xe0,0xfc,0x20,0xff,0xf6,0x26,0x68,0x5b, +0x00,0x00,0x10,0x05,0x0a,0xcd,0x2b,0x82,0x08,0xcd,0x81,0x01,0x81,0x04,0x4e,0x02, +0x30,0xde,0x33,0x06,0x00,0xe3,0xb4,0xcd,0x0e,0x83,0x0c,0xcd,0x20,0x81,0x04,0x48, +0x00,0x30,0x00,0x88,0xff,0x88,0xff,0x60,0x00,0xa8,0x00,0x88,0xff,0xf8,0xfe,0x08, +0x01,0x18,0x03,0x30,0x00,0xae,0xf8,0x46,0xf7,0x6a,0x07,0x18,0x26,0x3e,0x3f,0xcd, +0x30,0x84,0x10,0xcd,0x81,0x00,0x81,0x04,0x00,0x4e,0x02,0x30,0xbf,0x22,0x1a,0x00, +0xff,0x4e,0xcd,0x0e,0x88,0x24,0x3e,0x00,0xd6,0xff,0x90,0xff,0x7a,0xff,0xe4,0xff, +0xc2,0x00,0x80,0x01,0x52,0x01,0xc6,0xff,0x68,0xfd,0xd8,0xfb,0x02,0xfd,0xf2,0x01, +0xd6,0x09,0x0e,0x12,0x4c,0x17,0x92,0x00,0x62,0x00,0x0c,0xff,0x0c,0xff,0xc2,0x00, +0x54,0x01,0x0c,0xff,0xea,0xfd,0x16,0x02,0x44,0x06,0x62,0x00,0x30,0xf1,0x56,0xee, +0x00,0x0f,0x1a,0x4d,0xfe,0x7f,0xcd,0x2d,0x81,0x04,0x0e,0xcd,0x81,0x03,0x81,0x04, +0xcd,0x17,0x82,0x08,0x3a,0x00,0xd8,0xff,0x98,0xff,0x84,0xff,0xe6,0xff,0xb4,0x00, +0x68,0x01,0x3c,0x01,0xca,0xff,0x96,0xfd,0x1e,0xfc,0x36,0xfd,0xd0,0x01,0x30,0x09, +0xda,0x10,0xbe,0x15,0xcd,0x64,0x82,0x08,0xcd,0x6d,0x81,0x04,0x52,0xcd,0x16,0x81, +0x04,0x1c,0x00,0xec,0xff,0xcc,0xff,0xc2,0xff,0xf4,0xff,0x5a,0x00,0xb4,0x00,0x9e, +0x00,0xe4,0xff,0xca,0xfe,0x10,0xfe,0x9a,0xfe,0xe8,0x00,0x98,0x04,0x6e,0x08,0xe0, +0x0a,0xcd,0x4d,0x81,0x04,0x12,0xcd,0x81,0x02,0x81,0x04,0x09,0x02,0xcd,0x7a,0x99, +0x64,0x10,0xcd,0x0a,0x81,0x04,0x19,0xcd,0x08,0x81,0x04,0xcd,0x0c,0x97,0x5c,0xcd, +0x6c,0x81,0x04,0x08,0x00,0xfb,0x10,0xcd,0x14,0x8f,0x3c,0x80,0xff,0x71,0xff,0x40, +0xff,0x25,0xff,0x35,0xff,0x84,0xff,0x23,0x00,0x1d,0x01,0x72,0x02,0x16,0x04,0xf0, +0x05,0xdc,0x07,0xb1,0x09,0x42,0x0b,0x67,0x0c,0x01,0x0d,0xcd,0x20,0x20,0xcd,0x28, +0x8f,0x3c,0x6d,0x78,0x0e,0x0e,0x44,0xa8,0x1a,0x0a,0x23,0xf0,0x0d,0x07,0x39,0x58, +0x16,0x05,0x0d,0x70,0x04,0x04,0x0d,0x70,0x04,0x02,0x30,0x00,0x30,0x00,0x30,0x00, +0x20,0x00,0x30,0x00,0x10,0x00,0x30,0x00,0x00,0x00,0x81,0x00,0x30,0x00,0x81,0x00, +0x20,0x00,0x81,0x00,0x10,0x00,0x82,0xcd,0x05,0x0c,0x00,0x00,0x82,0x00,0x20,0x00, +0x83,0x00,0x30,0x00,0x82,0xcd,0x05,0x14,0x00,0x00,0x83,0xcd,0x05,0x10,0x10,0x00, +0x83,0xcd,0x05,0xac,0x59,0x04,0x04,0x08,0x04,0x0c,0x04,0x10,0x04,0x14,0x04,0x18, +0x04,0x1c,0x04,0x20,0x04,0x24,0x04,0x28,0x04,0x2c,0x04,0x30,0x04,0x34,0x04,0x38, +0x04,0x3c,0x04,0x40,0x04,0x44,0x04,0x48,0x04,0x4c,0x04,0x50,0x04,0x54,0x04,0x58, +0x04,0x5c,0x04,0x60,0x04,0x64,0x04,0x68,0x04,0x80,0x04,0x84,0x04,0x88,0x04,0x8c, +0x04,0x90,0x04,0x94,0x04,0x98,0x04,0xac,0x04,0xb0,0x04,0xc0,0x04,0xc4,0x04,0xc8, +0x04,0xcc,0x04,0xd0,0x04,0x08,0x05,0x0c,0x05,0x10,0x05,0x14,0x05,0x40,0x05,0x44, +0x05,0x48,0x05,0x4c,0x05,0x50,0x05,0x60,0x05,0x64,0x05,0x80,0x05,0x84,0x05,0x88, +0x05,0x8c,0x05,0x90,0x05,0x94,0x05,0x98,0x05,0xa8,0x05,0xac,0x05,0xb0,0x05,0xb4, +0x05,0xd0,0x05,0xd4,0x05,0xd8,0x05,0xdc,0x05,0xe0,0x05,0xe4,0x05,0xe8,0x05,0xec, +0x05,0x18,0x06,0x20,0x06,0x1c,0x06,0x00,0x06,0x04,0x06,0x08,0x06,0x0c,0x06,0x10, +0x06,0x24,0x06,0x31,0x11,0x21,0x02,0x15,0x11,0x61,0x06,0x50,0xcd,0x07,0x83,0x22, +0x98,0x86,0x01,0xcd,0x08,0xa0,0x3d,0x10,0xff,0x1f,0xcd,0x06,0x82,0x1c,0x8f,0x01, +0x10,0xff,0x98,0x1a,0x82,0x00,0xff,0x07,0x00,0x00,0x75,0x05,0xff,0x01,0xc9,0x00, +0x97,0x00,0x15,0x01,0x47,0x01,0x0d,0x02,0x0d,0x00,0xa3,0xb5,0xc1,0xc8,0xa1,0xb4, +0xc0,0x00,0x83,0x97,0xa6,0xaf,0x82,0x96,0xa5,0x00,0x64,0x01,0xff,0x01,0x0f,0x29, +0xfb,0x00,0x19,0xf6,0x07,0x04,0x14,0xec,0x07,0x04,0x44,0x1e,0x0e,0x00,0x3f,0x00, +0x28,0x00,0x8a,0x03,0x18,0x07,0x8e,0xcd,0x05,0x8f,0x07,0x04,0x00,0x33,0x55,0x00, +0x00,0x48,0x00,0xb7,0x01,0xcd,0x04,0x5f,0x8f,0x91,0x1f,0x7e,0x22,0x23,0x03,0x81, +0x14,0x28,0x18,0x03,0x0e,0x00,0x23,0x00,0x2a,0x0f,0x00,0x00,0x7a,0xf3,0x00,0x00, +0x44,0xff,0x00,0x00,0x0d,0x02,0x27,0x00,0x0b,0x02,0x11,0x00,0xf2,0x8f,0x80,0x80, +0x89,0x07,0xf9,0x06,0xff,0x03,0x01,0x00,0x15,0x01,0x80,0x00,0xaa,0x02,0x1d,0x00, +0x0d,0x02,0x11,0xcd,0x05,0xa9,0x39,0xcd,0x04,0x53,0x17,0xcd,0x04,0x09,0x10,0x0d, +0x32,0x35,0x52,0x07,0x02,0x36,0x02,0x91,0x11,0xcd,0x06,0x84,0x58,0x20,0x00,0xc9, +0x10,0x00,0x00,0xff,0x05,0x00,0x01,0x28,0x40,0xff,0x51,0x43,0x05,0x54,0xb7,0xcd, +0x04,0x7d,0x77,0x92,0x00,0x01,0xc8,0x40,0xff,0x53,0x63,0x87,0x89,0x00,0x0a,0x02, +0x0d,0x00,0x69,0x00,0xd8,0x04,0x2a,0x00,0x0c,0x02,0x64,0x00,0x66,0x03,0x10,0x00, +0x29,0xcd,0x09,0x82,0xcb,0x7d,0xa2,0x00,0x00,0x00,0x7b,0x00,0x2a,0x00,0x7b,0x00, +0x00,0x00,0xd0,0x02,0xf0,0x00,0x83,0x0f,0x01,0x00,0x00,0x80,0xcd,0x06,0x9a,0x16, +0xcd,0x04,0x0c,0xbd,0x00,0x07,0x07,0xa0,0x05,0x00,0x00,0xcd,0x3c,0x82,0x40,0x0b, +0x02,0x0c,0xcd,0x29,0x82,0x40,0x62,0x04,0xc8,0x08,0x67,0xcd,0x05,0x85,0x4a,0xcd, +0x06,0x82,0x40,0x70,0x00,0x23,0x02,0xcd,0x0c,0x82,0x40,0x12,0x28,0x2c,0x03,0x11, +0x00,0x20,0x00,0x3c,0x0f,0x00,0x00,0x53,0xf4,0x00,0x00,0x5b,0xff,0x00,0x00,0x0c, +0x02,0x26,0x00,0x0d,0x02,0x14,0xcd,0x11,0x82,0x40,0x4d,0x03,0x1f,0x00,0x0c,0x02, +0x14,0xcd,0x05,0x82,0x3c,0x07,0xcd,0x0d,0x82,0x40,0x06,0xcd,0x21,0x82,0x40,0x40, +0x76,0xcd,0x0c,0x82,0x40,0x12,0x00,0x7d,0x00,0x01,0x07,0x2c,0xcd,0x07,0x82,0x40, +0x14,0x00,0x2b,0xcd,0x0f,0x82,0x40,0x2c,0xcd,0x09,0x82,0x40,0x4c,0x50,0xcd,0x0a, +0x82,0x40,0xcd,0x04,0x0c,0xcd,0x44,0x82,0x40,0xcd,0x68,0x85,0x00,0x80,0x80,0x80, +0x80,0xf9,0x06,0xcd,0x26,0x85,0x00,0x0b,0x02,0x73,0xcd,0x81,0x01,0x85,0x00,0x01, +0xcd,0x0f,0x82,0x40,0xff,0x01,0xc0,0xcd,0x0c,0x82,0x40,0x03,0xc9,0x00,0xa0,0x00, +0x15,0x01,0x4d,0x01,0x70,0x02,0x08,0xcd,0x15,0x82,0x40,0x1f,0x2d,0x00,0x00,0x14, +0xf0,0x07,0x04,0x28,0xce,0x07,0x04,0x71,0x7f,0x05,0xcd,0x05,0x81,0x4c,0x6b,0x04, +0xda,0x08,0x6f,0xcd,0x07,0x85,0x00,0x3e,0x67,0x00,0x00,0x7a,0x00,0x27,0xcd,0x13, +0x85,0x00,0x26,0x00,0x3d,0x0f,0x00,0x00,0x5b,0xf4,0x00,0x00,0x5f,0xff,0x00,0x00, +0x70,0x02,0x2f,0x00,0x6e,0x02,0x0b,0xcd,0x05,0x82,0x40,0x7f,0x07,0x7f,0x07,0xcd, +0x08,0x82,0x40,0x53,0x03,0x1f,0xcd,0x05,0x1c,0x01,0xcd,0x07,0x82,0x40,0x7b,0xcd, +0x05,0x82,0x40,0x71,0x32,0x35,0x52,0x6d,0x02,0x32,0x02,0x8f,0xcd,0x09,0x82,0x40, +0x8e,0x50,0xcd,0x16,0x85,0x00,0x58,0x40,0xff,0x18,0x42,0x86,0x89,0x00,0x6a,0x02, +0x0b,0x00,0x94,0x00,0x69,0x04,0x30,0x00,0x6f,0x02,0x82,0x00,0x34,0x04,0x0d,0x00, +0xcd,0x06,0x54,0xcd,0x08,0x82,0x40,0xa4,0x00,0x30,0x00,0xa4,0xcd,0x05,0x82,0x40, +0x20,0x01,0xcd,0x1b,0x85,0x00,0x42,0xcd,0x2f,0x82,0x40,0x01,0xcd,0x0a,0x82,0x40, +0x05,0xcd,0x19,0x82,0x40,0x20,0xf6,0x07,0x04,0x28,0xf8,0x07,0x04,0x00,0x00,0x05, +0x00,0x3f,0x00,0x30,0x00,0x91,0x03,0x26,0x07,0x95,0xcd,0x07,0x85,0x00,0x3e,0x67, +0x00,0x00,0x63,0x00,0xba,0xcd,0x11,0x85,0x00,0x08,0x00,0x10,0xcd,0x05,0x85,0x00, +0x81,0xf3,0x00,0x00,0x47,0xff,0x00,0x00,0x6d,0x02,0x2e,0x00,0x6b,0x02,0x0c,0xcd, +0x11,0x82,0x40,0xaf,0x02,0x1d,0x00,0x6f,0x02,0x2e,0x00,0x37,0x01,0xcd,0x06,0x87, +0x40,0xcd,0x0a,0x82,0x40,0x6e,0xcd,0x21,0x82,0x40,0x5d,0x92,0xcd,0x0c,0x82,0x40, +0x09,0x00,0x7b,0x00,0x94,0x03,0x2f,0x00,0x6e,0xcd,0x05,0x82,0x40,0x0c,0x00,0x2e, +0xcd,0x0f,0x82,0x40,0x2f,0xcd,0x09,0x82,0x40,0xb4,0xcd,0x0b,0x85,0x00,0xcd,0x04, +0x0c,0xcd,0x44,0x82,0x40,0xcd,0x18,0x8a,0x00,0xcd,0x14,0x82,0x40,0x89,0x03,0x16, +0x07,0x8d,0xcd,0x0b,0x82,0x40,0x62,0x00,0xb6,0xcd,0x11,0x82,0x40,0x11,0x00,0x20, +0xcd,0x05,0x82,0x40,0x79,0xf3,0x00,0x00,0x46,0xcd,0x0b,0x8a,0x00,0xcd,0x10,0x82, +0x40,0xa9,0x02,0x1d,0x00,0x0b,0x02,0x2e,0x00,0x05,0xcd,0x07,0x82,0x40,0xcd,0x0c, +0x8a,0x00,0xcd,0x20,0x82,0x40,0xa0,0xcd,0x0b,0x82,0x40,0x0a,0x02,0x12,0x00,0x69, +0x00,0x6f,0x04,0xcd,0x24,0x8a,0x00,0x37,0xcd,0x0b,0x82,0x40,0xcd,0x04,0x0c,0xcd, +0x3b,0x87,0x40,0xcd,0x35,0x82,0x40,0xcd,0x1e,0x87,0x40,0xf3,0x87,0x19,0x32,0xcd, +0x06,0x82,0x40,0xcd,0x0c,0x87,0x40,0xcd,0x18,0x82,0x40,0x53,0x03,0x1f,0xcd,0x39, +0x82,0x40,0xcd,0x0c,0x87,0x40,0x0a,0x02,0x12,0x00,0x94,0x00,0x24,0xcd,0x23,0x8c, +0x40,0xcd,0x1d,0x87,0x40,0xcd,0x11,0x82,0x40,0x02,0xcd,0x29,0x87,0x40,0xcd,0x16, +0x8a,0x00,0x00,0x00,0x3f,0xcd,0x11,0x95,0x08,0x6a,0x04,0xd8,0xcd,0x2d,0x8a,0x00, +0x88,0xcd,0x12,0x8a,0x00,0xc7,0xcd,0x24,0x8a,0x00,0x8f,0x01,0xe5,0xcd,0x07,0x82, +0x82,0x24,0x20,0x00,0x30,0x01,0xcd,0x0e,0x82,0x40,0x88,0xa2,0xe7,0x03,0xcf,0xa7, +0x17,0x00,0xc8,0x40,0xff,0x18,0x22,0x12,0x45,0x00,0x6a,0x02,0x2a,0x00,0x15,0x00, +0xea,0x03,0xcd,0x3c,0x8a,0x00,0x46,0x11,0x29,0xcd,0x0d,0x82,0x40,0x18,0x86,0x01, +0x00,0x03,0xcd,0x27,0x8f,0x00,0x0c,0xcd,0x18,0x85,0x00,0x28,0x00,0xcd,0x06,0x8f, +0x00,0x00,0x00,0x04,0x4b,0x1e,0x0e,0x00,0x18,0x00,0x00,0xcd,0x24,0x8f,0x00,0x83, +0x13,0x00,0x22,0xcd,0x0d,0x8f,0x00,0x0c,0x02,0x28,0x00,0x0c,0x02,0x12,0xcd,0x05, +0x82,0x40,0x78,0x07,0x78,0xcd,0x09,0x85,0x00,0xaa,0x02,0x1d,0xcd,0x17,0x91,0x40, +0x04,0x02,0xe9,0x01,0xe9,0x81,0xcd,0x05,0x83,0x74,0x00,0xff,0xcd,0x05,0x8f,0x00, +0x00,0x02,0x00,0x02,0xcd,0x0b,0x85,0x00,0x00,0xcd,0x0c,0x8f,0x00,0x0b,0x02,0x26, +0x00,0x77,0x00,0x6c,0x03,0x2a,0x00,0x0a,0x02,0x66,0x00,0x5b,0x03,0x13,0x00,0x2a, +0xcd,0x19,0x87,0x40,0xcd,0x18,0x8f,0x00,0xcd,0x05,0x82,0x40,0x15,0xcd,0x0f,0x82, +0x40,0xcd,0x06,0x43,0xcd,0x1b,0x82,0x40,0xc9,0x00,0x15,0x01,0x15,0x01,0x1a,0x04, +0x16,0xcd,0x4d,0x82,0x40,0x18,0x00,0x26,0x00,0x29,0x0f,0x00,0x00,0x8b,0x13,0xcd, +0x06,0x82,0x40,0x1a,0x04,0x52,0x00,0xcd,0x04,0x64,0xcd,0x15,0x82,0x40,0x04,0x16, +0xcd,0x05,0x81,0x1c,0x02,0x00,0x00,0x00,0x24,0x04,0x00,0x00,0x00,0x10,0x1a,0x34, +0x35,0x53,0x0c,0x04,0xcd,0x20,0x82,0x40,0x3b,0x49,0xcd,0x0a,0x82,0x40,0x1a,0x04, +0x48,0x00,0x75,0x00,0x71,0x03,0x54,0x00,0x19,0x04,0x64,0x00,0x60,0x03,0x18,0x00, +0x52,0xcd,0x0d,0x82,0x40,0x75,0x00,0x54,0x00,0x75,0xcd,0x05,0x82,0x40,0xe0,0x01, +0xcd,0x1d,0x82,0x40,0x11,0x01,0x00,0xcd,0x1c,0x85,0x00,0xcd,0x31,0x91,0x40,0x2c, +0xcd,0x10,0x91,0x40,0x00,0xcd,0x27,0x91,0x40,0x22,0xcd,0x3f,0x91,0x40,0x6b,0xcd, +0x0d,0x85,0x00,0x8e,0x50,0xcd,0x12,0x82,0x40,0xcd,0x50,0x91,0x40,0xcd,0x2a,0x85, +0x00,0xb2,0xcd,0x11,0x85,0x00,0xdc,0x05,0x09,0xcd,0x2d,0x85,0x00,0x7d,0xcd,0x06, +0xca,0x2a,0x00,0x04,0x13,0x00,0x00,0x1e,0x00,0x2e,0xcd,0x05,0x85,0x00,0x87,0x91, +0x1f,0x7e,0x33,0x34,0x04,0x81,0x28,0x50,0x18,0xc3,0x09,0x00,0x16,0x00,0x24,0x0f, +0x00,0x00,0x7a,0x12,0x00,0x00,0x26,0xff,0x00,0x00,0xd1,0x05,0x32,0x00,0xcd,0x04, +0x64,0xcd,0x10,0x85,0x00,0xdd,0x01,0x1a,0x00,0xdc,0x05,0x16,0xcd,0x05,0x84,0x7c, +0xcd,0x04,0x04,0xe6,0x05,0x00,0x00,0x00,0x10,0xdc,0x35,0x35,0x53,0xda,0x05,0xcd, +0x2c,0x85,0x00,0xdc,0x05,0x32,0x00,0x6b,0x00,0x5b,0x02,0x34,0x00,0xd2,0x05,0xcd, +0x04,0x08,0x09,0x00,0x32,0xcd,0x0d,0x82,0x40,0x7d,0x00,0x34,0x00,0x7d,0x00,0x00, +0x00,0xd2,0x01,0xd0,0x02,0xcd,0x14,0x85,0x00,0xa4,0x03,0xcd,0x3e,0x82,0x40,0x65, +0x04,0x0b,0xcd,0x2d,0x82,0x40,0x52,0xcd,0x07,0x87,0x40,0x04,0x15,0x00,0x00,0x20, +0x00,0x99,0xcd,0x11,0x82,0x40,0x0c,0x00,0x19,0x00,0x28,0x0f,0x00,0x00,0x4f,0x13, +0x00,0x00,0x3d,0xff,0x00,0x00,0x65,0x04,0x28,0x00,0xcd,0x04,0x64,0xcd,0x10,0x82, +0x40,0x7d,0x02,0x1c,0xcd,0x05,0x18,0xcd,0x08,0x99,0x00,0xcd,0x05,0x85,0x58,0x10, +0x65,0x34,0x35,0x53,0x61,0xcd,0x21,0x87,0x40,0x2d,0xcd,0x0b,0x82,0x40,0xcd,0x04, +0x60,0x52,0x00,0x3a,0x03,0x26,0x00,0x61,0x04,0x41,0x00,0x29,0x03,0x0c,0x00,0x27, +0xcd,0x0d,0x82,0x40,0x64,0x00,0x28,0x00,0x64,0x00,0x00,0x00,0xba,0x02,0x1c,0x02, +0xba,0xcd,0x0b,0x82,0x40,0xcd,0x04,0x0c,0xbd,0x00,0x07,0x07,0x74,0x05,0x00,0x00, +0x21,0x20,0x0d,0x06,0xcd,0x04,0x04,0x35,0x68,0x11,0x04,0xcd,0x08,0x08,0xcd,0x04, +0x04,0xcd,0x08,0x08,0xcd,0x08,0x08,0x5b,0x38,0x24,0x06,0x52,0xb8,0x15,0xcd,0x15, +0x1c,0xcd,0x14,0x14,0xcd,0x05,0x58,0xc0,0x08,0x02,0xcd,0x05,0x0c,0xc0,0x08,0x02, +0x3b,0xa8,0x0f,0x02,0x00,0x00,0x01,0x03,0x02,0x00,0x03,0x00,0x05,0x00,0x04,0x00, +0x04,0x02,0x05,0x01,0x06,0x04,0x04,0x01,0x05,0x02,0x00,0x00,0xaa,0x03,0xaf,0x8b, +0xc0,0x02,0xd0,0x02,0x2e,0x09,0x00,0x80,0x01,0x00,0xf0,0x00,0x8a,0x04,0xc6,0x70, +0xcd,0x10,0x10,0xcd,0x0a,0x10,0x20,0x01,0xab,0x03,0x96,0xcd,0x0b,0x30,0x20,0x01, +0xa9,0x03,0xd6,0xcd,0x0d,0x40,0x55,0x07,0xd7,0x45,0xcd,0x04,0x10,0x8d,0x04,0x00, +0x80,0x00,0x00,0xe0,0x01,0xcd,0x10,0x40,0xcd,0x04,0x20,0xd2,0x01,0xd2,0x01,0x1b, +0x01,0x99,0x2e,0x00,0x00,0xd0,0x02,0x56,0x07,0xc9,0x45,0xba,0x02,0xba,0x02,0x1b, +0x01,0x88,0x2e,0x01,0x00,0x1c,0x02,0x1f,0x18,0x00,0x00,0x17,0xcd,0x04,0x04,0x18, +0x00,0x00,0x0f,0x18,0x00,0x00,0x09,0xcd,0x04,0x04,0xcd,0x08,0x08,0x18,0x00,0x00, +0x45,0x18,0x00,0x00,0x5f,0x18,0x00,0x00,0x75,0xcd,0x04,0x04,0x18,0x00,0x00,0x8b, +0xcd,0x04,0x04,0xcd,0x07,0x08,0x95,0xcd,0x04,0x04,0xcd,0x08,0x08,0xcd,0x0b,0x0c, +0x3b,0xcd,0x05,0xce,0x5e,0x00,0x00,0x4f,0x1b,0x00,0x00,0x59,0x1b,0x00,0x00,0x62, +0x1b,0x00,0x00,0x6e,0x1b,0x00,0x00,0x7a,0x1b,0x00,0x00,0x86,0x1b,0x00,0x00,0x91, +0x1b,0x00,0x00,0x9c,0x1b,0x00,0x00,0xa7,0x1b,0x00,0x00,0xb3,0x1b,0x00,0x00,0xbe, +0x1b,0x00,0x00,0xc8,0x1b,0x00,0x00,0xd4,0x1b,0x00,0x00,0xe0,0x1b,0x00,0x00,0x65, +0x21,0x00,0x00,0xe3,0x21,0x00,0x00,0xa0,0x21,0x00,0x00,0x25,0x22,0x00,0x00,0x7f, +0x22,0x00,0x00,0xc4,0x22,0x00,0x00,0xaa,0x22,0x00,0x00,0xde,0x22,0x00,0x00,0x0f, +0x00,0xf0,0xff,0x80,0xff,0x0e,0x00,0xff,0xff,0x0e,0x00,0xa8,0xa7,0x04,0x75,0xfc, +0x8a,0x58,0x58,0x58,0x5c,0xaf,0x78,0xaf,0x78,0x58,0x5c,0xf7,0xee,0xee,0xf7,0xf7, +0xf2,0xf2,0xf7,0xcd,0x50,0xc5,0x5b,0x80,0x80,0x80,0x80,0xcd,0x04,0x04,0xcd,0x04, +0x04,0x3e,0x87,0x1c,0x00,0xdf,0x99,0xbe,0xff,0x6a,0x53,0x50,0x00,0x37,0x9b,0xa6, +0xff,0xe1,0xf7,0xb4,0xff,0x18,0x05,0x35,0xcd,0x05,0xb5,0x36,0x0f,0x00,0xff,0xff, +0x10,0xcd,0x07,0xbd,0x12,0x00,0xc6,0xcd,0x06,0xa7,0x4f,0x80,0x94,0xc7,0xff,0x00, +0x59,0x0c,0x00,0x2b,0x06,0x00,0x00,0x1e,0x9f,0x2e,0x00,0x3c,0x50,0xff,0xff,0x56, +0x10,0x92,0xff,0xd6,0x57,0x01,0x00,0x1c,0x3a,0xe8,0xff,0x54,0x90,0xf8,0xff,0xc4, +0x8a,0x2c,0x00,0x3f,0x5c,0x0b,0x00,0x0a,0x03,0x09,0x00,0x94,0x4b,0x16,0x00,0x2f, +0x71,0xc7,0xff,0xc8,0x30,0xb4,0xff,0xe7,0xc6,0x1a,0x00,0x82,0x96,0xfe,0xff,0xa9, +0x60,0x32,0x00,0xff,0x6e,0xf5,0xff,0xf4,0xac,0x8d,0xff,0x81,0xfa,0x0b,0x00,0x5f, +0x62,0x28,0x00,0xaf,0x19,0xc0,0xff,0x60,0x62,0x28,0x00,0x13,0x78,0x04,0x00,0x71, +0x08,0xc0,0xff,0xcd,0x04,0x08,0x55,0x55,0x55,0x55,0xcd,0x04,0x04,0xcd,0x04,0x04, +0xb6,0x27,0x00,0x00,0xd7,0x27,0x00,0x00,0xbf,0x27,0x00,0x00,0xc9,0x27,0x00,0x00, +0x3f,0x29,0x00,0x00,0x65,0x29,0x00,0x00,0x45,0x29,0x00,0x00,0x6b,0x29,0x00,0x00, +0x93,0x28,0xcd,0x04,0x04,0xcd,0x08,0x08,0x00,0x00,0xde,0xcd,0x04,0x04,0xcd,0x08, +0x08,0x28,0x00,0x00,0x2b,0x29,0xcd,0x04,0x04,0xcd,0x06,0x08,0x31,0xcd,0x04,0x04, +0xcd,0x08,0x08,0xcd,0x0b,0x0c,0x4c,0x00,0x2d,0x00,0x33,0x00,0x3d,0x00,0x46,0x00, +0x4e,0x00,0x53,0x00,0x56,0x00,0x56,0x00,0x52,0x00,0x4a,0xcd,0x05,0x97,0x46,0x1d, +0x00,0x06,0x00,0xda,0xff,0xce,0xfe,0x1f,0xff,0xe9,0xfe,0xa9,0xfe,0x6e,0xfe,0x3c, +0xfe,0x16,0xfe,0x01,0xfe,0xfe,0xfd,0x0f,0xfe,0x35,0xfe,0x71,0xfe,0xc3,0xfe,0x2b, +0xff,0xab,0xff,0x8d,0x00,0xdf,0x02,0x99,0x02,0x79,0x03,0x67,0x04,0x45,0x05,0x03, +0x06,0x96,0x06,0xf3,0x06,0x12,0x07,0xec,0x06,0x7c,0x06,0xbf,0x05,0xb6,0x04,0x5e, +0x03,0xb0,0x01,0xf6,0xfe,0xca,0xfa,0xec,0xf9,0x3c,0xf7,0x74,0xf4,0xd1,0xf1,0x7a, +0xef,0x8d,0xed,0x28,0xec,0x67,0xeb,0x65,0xeb,0x35,0xec,0xed,0xed,0x99,0xf0,0x48, +0xf4,0x15,0xf9,0x52,0x00,0x98,0x08,0x9e,0x0e,0x7e,0x17,0x22,0x21,0x39,0x2b,0x88, +0x35,0xdd,0x3f,0x01,0x4a,0xc0,0x53,0xe5,0x5c,0x40,0x65,0x9f,0x6c,0xda,0x72,0xc2, +0x77,0x19,0x7b,0xf6,0x7a,0xf6,0x7a,0x19,0x7b,0xc2,0x77,0xda,0x72,0x9f,0x6c,0x40, +0x65,0xe5,0x5c,0xc0,0x53,0x01,0x4a,0xdd,0x3f,0x88,0x35,0x39,0x2b,0x22,0x21,0x7e, +0x17,0x9e,0x0e,0x98,0x08,0x52,0x00,0x15,0xf9,0x48,0xf4,0x99,0xf0,0xed,0xed,0x35, +0xec,0x65,0xeb,0x67,0xeb,0x28,0xec,0x8d,0xed,0x7a,0xef,0xd1,0xf1,0x74,0xf4,0x3c, +0xf7,0xec,0xf9,0xca,0xfa,0xf6,0xfe,0xb0,0x01,0x5e,0x03,0xb6,0x04,0xbf,0x05,0x7c, +0x06,0xec,0x06,0x12,0x07,0xf3,0x06,0x96,0x06,0x03,0x06,0x45,0x05,0x67,0x04,0x79, +0x03,0x99,0x02,0xdf,0x02,0x8d,0x00,0xab,0xff,0x2b,0xff,0xc3,0xfe,0x71,0xfe,0x35, +0xfe,0x0f,0xfe,0xfe,0xfd,0x01,0xfe,0x16,0xfe,0x3c,0xfe,0x6e,0xfe,0xa9,0xfe,0xe9, +0xfe,0x1f,0xff,0xce,0xfe,0xda,0xff,0x06,0x00,0x1d,0x00,0x30,0x00,0x3f,0x00,0x4a, +0x00,0x52,0xcd,0x05,0x82,0x20,0x53,0x00,0x4e,0x00,0x46,0x00,0x3d,0x00,0x33,0x00, +0x2d,0x00,0x4c,0x00,0x00,0x00,0x61,0xfa,0xf1,0xfc,0x72,0x02,0xed,0x01,0x76,0xfd, +0x21,0xfd,0xbd,0x03,0x1f,0x03,0xc5,0xfb,0x84,0xfb,0xcb,0x05,0x95,0x05,0xb3,0xf8, +0xf3,0xf7,0x7c,0x0a,0xf8,0x0b,0x82,0xef,0x85,0xe9,0xb4,0x26,0xcb,0x72,0xcb,0x72, +0xb4,0x26,0x85,0xe9,0x82,0xef,0xf8,0x0b,0x7c,0x0a,0xf3,0xf7,0xb3,0xf8,0x95,0x05, +0xcb,0x05,0x84,0xfb,0xc5,0xfb,0x1f,0x03,0xbd,0x03,0x21,0xfd,0x76,0xfd,0xed,0x01, +0x72,0x02,0xf1,0xfc,0x61,0xfa,0x0b,0xfe,0x4c,0xfa,0x23,0x00,0xd8,0x08,0xf4,0x07, +0xb4,0xf5,0xc4,0xe7,0x87,0xff,0xd6,0x3e,0xd5,0x77,0xd5,0x77,0xd6,0x3e,0x87,0xff, +0xc4,0xe7,0xb4,0xf5,0xf4,0x07,0xd8,0x08,0x23,0x00,0x4c,0xfa,0x0b,0xfe,0x00,0x00, +0x00,0x20,0x43,0xa1,0xbd,0x5e,0x00,0xe0,0x00,0x20,0x7d,0xc0,0xbf,0x1f,0xcd,0x04, +0x10,0x3c,0xa0,0xc4,0x5f,0xcd,0x04,0x10,0x49,0xc1,0xf9,0xcd,0x05,0x10,0xf5,0xa1, +0x0b,0xcd,0x05,0x20,0xd5,0xcd,0x07,0x20,0x94,0xa0,0x6c,0xcd,0x05,0x20,0x35,0xc2, +0xcd,0x06,0x10,0xc4,0xb4,0x3c,0x4b,0xcd,0x04,0x10,0x88,0xd7,0xcd,0x06,0x10,0x5f, +0xb7,0xa1,0x48,0xcd,0x04,0x10,0xf0,0xd4,0xcd,0x04,0x10,0x9b,0x2e,0x00,0x00,0x76, +0x2e,0x00,0x00,0xee,0xcd,0x04,0x04,0x2e,0x00,0x00,0x39,0x30,0x00,0x00,0x1a,0x34, +0xcd,0x06,0x08,0xcd,0x04,0x04,0x55,0x31,0xcd,0x04,0x04,0xcd,0x08,0x08,0xcd,0x0a, +0x0c,0x9f,0x32,0x00,0x00,0x56,0x33,0xcd,0x06,0x0c,0xfd,0xcd,0x04,0x04,0xcd,0x08, +0x08,0xcd,0x10,0x10,0xcd,0x07,0x08,0xcd,0x1c,0x87,0x10,0xcd,0x0a,0x82,0xde,0x7c, +0x02,0x00,0xfe,0xff,0x04,0x00,0xfc,0xff,0x08,0x00,0xf8,0xff,0x10,0x00,0xf0,0xff, +0x18,0x00,0xe8,0xff,0x0c,0x00,0x03,0x00,0xfd,0xff,0x06,0x00,0x07,0x00,0x0a,0x00, +0x0e,0x00,0x0f,0x00,0x12,0x00,0x14,0x00,0x1c,0x00,0x20,0x00,0x24,0x00,0x28,0x00, +0x50,0xcd,0x51,0xce,0x1f }; +#endif diff --git a/flash.tos/drivers/radeon/radeon_vid.c b/flash.tos/drivers/radeon/radeon_vid.c index d9d7980..cd61a56 100644 --- a/flash.tos/drivers/radeon/radeon_vid.c +++ b/flash.tos/drivers/radeon/radeon_vid.c @@ -1985,13 +1985,13 @@ static int radeon_vid_init_video(vidix_playback_t *config) DisallowFourTapVertFiltering = 1; if((long)((ceil(SourceUVWidthInMemWords/2.0)-1) * 4 + 1) > (long)(OV0LB_Rows-1)) { -// DPRINT("VIDIX: Image U plane width spans more octwords than supported by hardware\r\n") +// DPRINT("VIDIX: Image U plane width spans more octwords than supported by hardware\r\n"); } else if((SourceUVWidthInMemWords-1) * 4 + 1 > OV0LB_Rows-1) DisallowFourTapUVVertFiltering = 1; if((long)((ceil(SourceUVWidthInMemWords/2.0)-1) * 4 + 3) > (long)(OV0LB_Rows-1)) { -// DPRINT("VIDIX: Image V plane width spans more octwords than supported by hardware\r\n") +// DPRINT("VIDIX: Image V plane width spans more octwords than supported by hardware\r\n"); } else if((SourceUVWidthInMemWords-1) * 4 + 3 > OV0LB_Rows-1) DisallowFourTapUVVertFiltering = 1; @@ -2006,7 +2006,7 @@ static int radeon_vid_init_video(vidix_playback_t *config) DisallowFourTapVertFiltering = 1; if((long)((ceil(SourceUVWidthInMemWords/2.0)-1) * 2) + 1 > (long)(OV0LB_Rows-1)) { -// DPRINT("VIDIX: Image UV plane width spans more octwords than supported by hardware.") */ +// DPRINT("VIDIX: Image UV plane width spans more octwords than supported by hardware\r\n"); } else if((SourceUVWidthInMemWords-1) * 2 + 1 > OV0LB_Rows-1) DisallowFourTapUVVertFiltering = 1; @@ -2018,7 +2018,7 @@ static int radeon_vid_init_video(vidix_playback_t *config) case 12: if((ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1) { -// DPRINT("VIDIX: ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\r\n") +// DPRINT("VIDIX: ceil(SourceWidthInMemWords/2)-1) > OV0LB_Rows-1\r\n"); } else if((SourceWidthInMemWords-1) > OV0LB_Rows-1) DisallowFourTapVertFiltering = 1; diff --git a/flash.tos/drivers/radeon_f.sys b/flash.tos/drivers/radeon_f.sys deleted file mode 100644 index 5592e20..0000000 Binary files a/flash.tos/drivers/radeon_f.sys and /dev/null differ diff --git a/flash.tos/drivers/rtc/rtc5c387.c b/flash.tos/drivers/rtc/rtc5c387.c index cb0aa0a..4d5e4ae 100644 --- a/flash.tos/drivers/rtc/rtc5c387.c +++ b/flash.tos/drivers/rtc/rtc5c387.c @@ -54,7 +54,6 @@ struct rtc_tm { #define RTC5C387_CTRL2_VDSL (1<<7) #ifdef USE_RTC -#ifdef NETWORK #ifdef LWIP static xSemaphoreHandle smid; @@ -381,14 +380,13 @@ void RTC_task(void) if(dt.hours && dt.mins && dt.secs && dt.year && dt.mon && dt.mday) date = ((((unsigned long)dt.year - 1980) & 0x7F) << 9) + ((unsigned long)dt.mon << 5) + (unsigned long)dt.mday; } - vTaskDelay(1); + vTaskDelay(1); } else - vTaskDelay(1); + vTaskDelay(1); } } #endif #endif -#endif diff --git a/flash.tos/drivers/rtc/rtc8564.c b/flash.tos/drivers/rtc/rtc8564.c index 9512f04..4b6bbda 100644 --- a/flash.tos/drivers/rtc/rtc8564.c +++ b/flash.tos/drivers/rtc/rtc8564.c @@ -4,7 +4,7 @@ #include "../freertos/FreeRTOSConfig.h" #include "../freertos/task.h" #include "../freertos/semphr.h" -#include ../lwip/net.h" +#include "../lwip/net.h" #include "mcf548x.h" extern void display_string(char *string); @@ -66,7 +66,6 @@ struct rtc_tm { #define RTC8564_TD_1_60HZ (0x3) #ifdef USE_RTC -#ifdef NETWORK #ifdef LWIP static xSemaphoreHandle smid; @@ -394,13 +393,12 @@ void RTC_task(void) if(dt.hours && dt.mins && dt.secs && dt.year && dt.mon && dt.mday) date = ((((unsigned long)dt.year - 1980) & 0x7F) << 9) + ((unsigned long)dt.mon << 5) + (unsigned long)dt.mday; } - vTaskDelay(1); + vTaskDelay(1); } else - vTaskDelay(1); + vTaskDelay(1); } } #endif #endif -#endif diff --git a/flash.tos/drivers/stdlib.c b/flash.tos/drivers/stdlib.c index 2bc35f9..33292d7 100644 --- a/flash.tos/drivers/stdlib.c +++ b/flash.tos/drivers/stdlib.c @@ -5,6 +5,8 @@ * Notes: This supports ASCII only!!! */ +#include + #define FALSE (0) #define TRUE (1) #define NULL (0) @@ -593,6 +595,19 @@ char *strchr(const char *s, int c) return(*s ? (char *)s : NULL); } +/****************************************************************/ +char *strrchr(const char *s, int c) +{ + char *p = NULL; + do + { + if(*s == c) + p = (char *) s; + } + while(*s++); + return(p); +} + /****************************************************************/ int memcmp(const void *s1, const void *s2, long size) { @@ -635,3 +650,17 @@ char *strstr(const char *s1, const char *s2) return(NULL); } +/****************************************************************/ +char *strndup(char const *s, int n) +{ + extern void *memcpy(void *dest, const void *src, unsigned n); + int len = strlen(s); + char *new = (char *)Malloc((len > n) ? n + 1 : len + 1); + if (new == NULL) + return NULL; + new[len] = '\0'; + memcpy(new, s, len); + return(new); +} + +/****************************************************************/ diff --git a/flash.tos/drivers/timer.c b/flash.tos/drivers/timer.c index 8063504..5f20fe6 100644 --- a/flash.tos/drivers/timer.c +++ b/flash.tos/drivers/timer.c @@ -1,5 +1,5 @@ /* time / delay functions for the CT60/CTPCI & Coldfire boards - * Didier Mequignon 2005-2011, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2005-2012, e-mail: aniplay@wanadoo.fr * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -159,16 +159,14 @@ static long save_stack; void install_vbl_timer(void *func, int remove) { -#ifdef COLDFIRE -#if defined(NETWORK) && defined (LWIP) && defined(DRIVER_IN_ROM) -#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) && defined(CONFIG_USB_MEM_NO_CACHE) && defined(CONFIG_USB_MEM_NO_CACHE) +#if ((defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS)) && defined(DRIVER_IN_ROM) +#if (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) extern void *usb_malloc(long amount); extern int usb_free(void *addr); #endif extern void flush_dc(void); extern unsigned long pxCurrentTCB, tid_TOS; -#endif -#endif /* COLDFIRE */ +#endif /* ((defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS)) && defined(DRIVER_IN_ROM) */ XBRA *xbra; int i = (int)*nvbls; void (**func_vbl)(void); @@ -183,7 +181,7 @@ void install_vbl_timer(void *func, int remove) if((xbra->xbra == 'XBRA') && (xbra->ident == '_PCI') && (xbra->caller[0] == 0x23CF) && (*(long *)&xbra->caller[7] == (long)func)) { -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(DRIVER_IN_ROM) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if ((defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS)) && defined(DRIVER_IN_ROM) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) if(pxCurrentTCB != tid_TOS) usb_free(xbra); else @@ -194,7 +192,7 @@ void install_vbl_timer(void *func, int remove) } if(*func_vbl == NULL) { -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) && defined(DRIVER_IN_ROM) && defined(CONFIG_USB_MEM_NO_CACHE) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) +#if ((defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS)) && defined(DRIVER_IN_ROM) && (defined(CONFIG_USB_UHCI) || defined(CONFIG_USB_OHCI) || defined(CONFIG_USB_EHCI)) if(pxCurrentTCB != tid_TOS) xbra = (XBRA *)usb_malloc(sizeof(XBRA)); else @@ -214,7 +212,7 @@ void install_vbl_timer(void *func, int remove) *(long *)&xbra->caller[10] = (long)&save_stack; xbra->caller[12] = 0x4E75; /* rts */ #ifdef COLDFIRE -#if defined(NETWORK) && defined (LWIP) && defined(DRIVER_IN_ROM) +#if defined(LWIP) && defined(DRIVER_IN_ROM) if(pxCurrentTCB != tid_TOS) flush_dc(); else diff --git a/flash.tos/drivers/tools/LzFind.c b/flash.tos/drivers/tools/LzFind.c new file mode 100644 index 0000000..80211b3 --- /dev/null +++ b/flash.tos/drivers/tools/LzFind.c @@ -0,0 +1,779 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + + +#include + +#include "LzFind.h" +#include "LzHash.h" + +#define kEmptyHashValue 0 +#define kMaxValForNormalize ((UInt32)0xFFFFFFFF) +#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */ +#define kNormalizeMask (~(kNormalizeStepMin - 1)) +#define kMaxHistorySize ((UInt32)3 << 30) + +#define kStartMaxLen 3 + +#ifndef ptrdiff_t +#define ptrdiff_t long +#endif + +static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + if (!p->directInput) + { + alloc->Free(alloc, p->bufferBase); + p->bufferBase = 0; + } +} + +/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */ + +static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc) +{ + UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv; + if (p->directInput) + { + p->blockSize = blockSize; + return 1; + } + if (p->bufferBase == 0 || p->blockSize != blockSize) + { + LzInWindow_Free(p, alloc); + p->blockSize = blockSize; + p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize); + } + return (p->bufferBase != 0); +} + +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; } +Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; } + +UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; } + +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue) +{ + p->posLimit -= subValue; + p->pos -= subValue; + p->streamPos -= subValue; +} + +static void MatchFinder_ReadBlock(CMatchFinder *p) +{ + if (p->streamEndWasReached || p->result != SZ_OK) + return; + for (;;) + { + Byte *dest = p->buffer + (p->streamPos - p->pos); + size_t size = (p->bufferBase + p->blockSize - dest); + if (size == 0) + return; + p->result = p->stream->Read(p->stream, dest, &size); + if (p->result != SZ_OK) + return; + if (size == 0) + { + p->streamEndWasReached = 1; + return; + } + p->streamPos += (UInt32)size; + if (p->streamPos - p->pos > p->keepSizeAfter) + return; + } +} + +void MatchFinder_MoveBlock(CMatchFinder *p) +{ + memmove(p->bufferBase, + p->buffer - p->keepSizeBefore, + (size_t)(p->streamPos - p->pos + p->keepSizeBefore)); + p->buffer = p->bufferBase + p->keepSizeBefore; +} + +int MatchFinder_NeedMove(CMatchFinder *p) +{ + /* if (p->streamEndWasReached) return 0; */ + return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter); +} + +void MatchFinder_ReadIfRequired(CMatchFinder *p) +{ + if (p->streamEndWasReached) + return; + if (p->keepSizeAfter >= p->streamPos - p->pos) + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p) +{ + if (MatchFinder_NeedMove(p)) + MatchFinder_MoveBlock(p); + MatchFinder_ReadBlock(p); +} + +static void MatchFinder_SetDefaultSettings(CMatchFinder *p) +{ + p->cutValue = 32; + p->btMode = 1; + p->numHashBytes = 4; + /* p->skipModeBits = 0; */ + p->directInput = 0; + p->bigHash = 0; +} + +#define kCrcPoly 0xEDB88320 + +void MatchFinder_Construct(CMatchFinder *p) +{ + UInt32 i; + p->bufferBase = 0; + p->directInput = 0; + p->hash = 0; + MatchFinder_SetDefaultSettings(p); + + for (i = 0; i < 256; i++) + { + UInt32 r = i; + int j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + p->crc[i] = r; + } +} + +static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->hash); + p->hash = 0; +} + +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc) +{ + MatchFinder_FreeThisClassMemory(p, alloc); + LzInWindow_Free(p, alloc); +} + +static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc) +{ + size_t sizeInBytes = (size_t)num * sizeof(CLzRef); + if (sizeInBytes / sizeof(CLzRef) != num) + return 0; + return (CLzRef *)alloc->Alloc(alloc, sizeInBytes); +} + +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc) +{ + UInt32 sizeReserv; + if (historySize > kMaxHistorySize) + { + MatchFinder_Free(p, alloc); + return 0; + } + sizeReserv = historySize >> 1; + if (historySize > ((UInt32)2 << 30)) + sizeReserv = historySize >> 2; + sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); + + p->keepSizeBefore = historySize + keepAddBufferBefore + 1; + p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; + /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ + if (LzInWindow_Create(p, sizeReserv, alloc)) + { + UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1; + UInt32 hs; + p->matchMaxLen = matchMaxLen; + { + p->fixedHashSize = 0; + if (p->numHashBytes == 2) + hs = (1 << 16) - 1; + else + { + hs = historySize - 1; + hs |= (hs >> 1); + hs |= (hs >> 2); + hs |= (hs >> 4); + hs |= (hs >> 8); + hs >>= 1; + /* hs >>= p->skipModeBits; */ + hs |= 0xFFFF; /* don't change it! It's required for Deflate */ + if (hs > (1 << 24)) + { + if (p->numHashBytes == 3) + hs = (1 << 24) - 1; + else + hs >>= 1; + } + } + p->hashMask = hs; + hs++; + if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size; + if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size; + if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size; + hs += p->fixedHashSize; + } + + { + UInt32 prevSize = p->hashSizeSum + p->numSons; + UInt32 newSize; + p->historySize = historySize; + p->hashSizeSum = hs; + p->cyclicBufferSize = newCyclicBufferSize; + p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize); + newSize = p->hashSizeSum + p->numSons; + if (p->hash != 0 && prevSize == newSize) + return 1; + MatchFinder_FreeThisClassMemory(p, alloc); + p->hash = AllocRefs(newSize, alloc); + if (p->hash != 0) + { + p->son = p->hash + p->hashSizeSum; + return 1; + } + } + } + MatchFinder_Free(p, alloc); + return 0; +} + +static void MatchFinder_SetLimits(CMatchFinder *p) +{ + UInt32 limit = kMaxValForNormalize - p->pos; + UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos; + if (limit2 < limit) + limit = limit2; + limit2 = p->streamPos - p->pos; + if (limit2 <= p->keepSizeAfter) + { + if (limit2 > 0) + limit2 = 1; + } + else + limit2 -= p->keepSizeAfter; + if (limit2 < limit) + limit = limit2; + { + UInt32 lenLimit = p->streamPos - p->pos; + if (lenLimit > p->matchMaxLen) + lenLimit = p->matchMaxLen; + p->lenLimit = lenLimit; + } + p->posLimit = p->pos + limit; +} + +void MatchFinder_Init(CMatchFinder *p) +{ + UInt32 i; + for(i = 0; i < p->hashSizeSum; i++) + p->hash[i] = kEmptyHashValue; + p->cyclicBufferPos = 0; + p->buffer = p->bufferBase; + p->pos = p->streamPos = p->cyclicBufferSize; + p->result = SZ_OK; + p->streamEndWasReached = 0; + MatchFinder_ReadBlock(p); + MatchFinder_SetLimits(p); +} + +static UInt32 MatchFinder_GetSubValue(CMatchFinder *p) +{ + return (p->pos - p->historySize - 1) & kNormalizeMask; +} + +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems) +{ + UInt32 i; + for (i = 0; i < numItems; i++) + { + UInt32 value = items[i]; + if (value <= subValue) + value = kEmptyHashValue; + else + value -= subValue; + items[i] = value; + } +} + +static void MatchFinder_Normalize(CMatchFinder *p) +{ + UInt32 subValue = MatchFinder_GetSubValue(p); + MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons); + MatchFinder_ReduceOffsets(p, subValue); +} + +static void MatchFinder_CheckLimits(CMatchFinder *p) +{ + if (p->pos == kMaxValForNormalize) + MatchFinder_Normalize(p); + if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos) + MatchFinder_CheckAndMoveAndRead(p); + if (p->cyclicBufferPos == p->cyclicBufferSize) + p->cyclicBufferPos = 0; + MatchFinder_SetLimits(p); +} + +static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + son[_cyclicBufferPos] = curMatch; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + return distances; + { + const Byte *pb = cur - delta; + curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)]; + if (pb[maxLen] == cur[maxLen] && *pb == *cur) + { + UInt32 len = 0; + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + return distances; + } + } + } + } +} + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue, + UInt32 *distances, UInt32 maxLen) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return distances; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + if (++len != lenLimit && pb[len] == cur[len]) + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + if (maxLen < len) + { + *distances++ = maxLen = len; + *distances++ = delta - 1; + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return distances; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue) +{ + CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1; + CLzRef *ptr1 = son + (_cyclicBufferPos << 1); + UInt32 len0 = 0, len1 = 0; + for (;;) + { + UInt32 delta = pos - curMatch; + if (cutValue-- == 0 || delta >= _cyclicBufferSize) + { + *ptr0 = *ptr1 = kEmptyHashValue; + return; + } + { + CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1); + const Byte *pb = cur - delta; + UInt32 len = (len0 < len1 ? len0 : len1); + if (pb[len] == cur[len]) + { + while(++len != lenLimit) + if (pb[len] != cur[len]) + break; + { + if (len == lenLimit) + { + *ptr1 = pair[0]; + *ptr0 = pair[1]; + return; + } + } + } + if (pb[len] < cur[len]) + { + *ptr1 = curMatch; + ptr1 = pair + 1; + curMatch = *ptr1; + len1 = len; + } + else + { + *ptr0 = curMatch; + ptr0 = pair; + curMatch = *ptr0; + len0 = len; + } + } + } +} + +#define MOVE_POS \ + ++p->cyclicBufferPos; \ + p->buffer++; \ + if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p); + +#define MOVE_POS_RET MOVE_POS return offset; + +static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; } + +#define GET_MATCHES_HEADER2(minLen, ret_op) \ + UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \ + lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \ + cur = p->buffer; + +#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0) +#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue) + +#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue + +#define GET_MATCHES_FOOTER(offset, maxLen) \ + offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \ + distances + offset, maxLen) - distances); MOVE_POS_RET; + +#define SKIP_FOOTER \ + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS; + +static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 1) +} + +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = 0; + GET_MATCHES_FOOTER(offset, 2) +} + +static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, delta2, maxLen, offset; + GET_MATCHES_HEADER(3) + + HASH3_CALC; + + delta2 = p->pos - p->hash[hash2Value]; + curMatch = p->hash[kFix3HashSize + hashValue]; + + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + + + maxLen = 2; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[0] = maxLen; + distances[1] = delta2 - 1; + offset = 2; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + GET_MATCHES_FOOTER(offset, maxLen) +} + +static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset; + GET_MATCHES_HEADER(4) + + HASH4_CALC; + + delta2 = p->pos - p->hash[ hash2Value]; + delta3 = p->pos - p->hash[kFix3HashSize + hash3Value]; + curMatch = p->hash[kFix4HashSize + hashValue]; + + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + + maxLen = 1; + offset = 0; + if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur) + { + distances[0] = maxLen = 2; + distances[1] = delta2 - 1; + offset = 2; + } + if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur) + { + maxLen = 3; + distances[offset + 1] = delta3 - 1; + offset += 2; + delta2 = delta3; + } + if (offset != 0) + { + for (; maxLen != lenLimit; maxLen++) + if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen]) + break; + distances[offset - 2] = maxLen; + if (maxLen == lenLimit) + { + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS_RET; + } + } + if (maxLen < 3) + maxLen = 3; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances + offset, maxLen) - (distances)); + MOVE_POS_RET +} + +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances) +{ + UInt32 offset; + GET_MATCHES_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p), + distances, 2) - (distances)); + MOVE_POS_RET +} + +static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(2) + HASH2_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value; + SKIP_HEADER(3) + HASH3_CALC; + curMatch = p->hash[kFix3HashSize + hashValue]; + p->hash[hash2Value] = + p->hash[kFix3HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = p->pos; + p->hash[kFix4HashSize + hashValue] = p->pos; + SKIP_FOOTER + } + while (--num != 0); +} + +static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + UInt32 hash2Value, hash3Value; + SKIP_HEADER(4) + HASH4_CALC; + curMatch = p->hash[kFix4HashSize + hashValue]; + p->hash[ hash2Value] = + p->hash[kFix3HashSize + hash3Value] = + p->hash[kFix4HashSize + hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num) +{ + do + { + SKIP_HEADER(3) + HASH_ZIP_CALC; + curMatch = p->hash[hashValue]; + p->hash[hashValue] = p->pos; + p->son[p->cyclicBufferPos] = curMatch; + MOVE_POS + } + while (--num != 0); +} + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable) +{ + vTable->Init = (Mf_Init_Func)MatchFinder_Init; + vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte; + vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes; + vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos; + if (!p->btMode) + { + vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip; + } + else if (p->numHashBytes == 2) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip; + } + else if (p->numHashBytes == 3) + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip; + } + else + { + vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches; + vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip; + } +} diff --git a/flash.tos/drivers/tools/LzFind.h b/flash.tos/drivers/tools/LzFind.h new file mode 100644 index 0000000..7c7aa0e --- /dev/null +++ b/flash.tos/drivers/tools/LzFind.h @@ -0,0 +1,130 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZFIND_H +#define __LZFIND_H + +#include "LzmaTypes.h" + +typedef UInt32 CLzRef; + +typedef struct _CMatchFinder +{ + Byte *buffer; + UInt32 pos; + UInt32 posLimit; + UInt32 streamPos; + UInt32 lenLimit; + + UInt32 cyclicBufferPos; + UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */ + + UInt32 matchMaxLen; + CLzRef *hash; + CLzRef *son; + UInt32 hashMask; + UInt32 cutValue; + + Byte *bufferBase; + ISeqInStream *stream; + int streamEndWasReached; + + UInt32 blockSize; + UInt32 keepSizeBefore; + UInt32 keepSizeAfter; + + UInt32 numHashBytes; + int directInput; + int btMode; + /* int skipModeBits; */ + int bigHash; + UInt32 historySize; + UInt32 fixedHashSize; + UInt32 hashSizeSum; + UInt32 numSons; + SRes result; + UInt32 crc[256]; +} CMatchFinder; + +#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer) +#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)]) + +#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos) + +int MatchFinder_NeedMove(CMatchFinder *p); +Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); +void MatchFinder_MoveBlock(CMatchFinder *p); +void MatchFinder_ReadIfRequired(CMatchFinder *p); + +void MatchFinder_Construct(CMatchFinder *p); + +/* Conditions: + historySize <= 3 GB + keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB +*/ +int MatchFinder_Create(CMatchFinder *p, UInt32 historySize, + UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter, + ISzAlloc *alloc); +void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc); +void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems); +void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue); + +UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son, + UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue, + UInt32 *distances, UInt32 maxLen); + +/* +Conditions: + Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func. + Mf_GetPointerToCurrentPos_Func's result must be used only before any other function +*/ + +typedef void (*Mf_Init_Func)(void *object); +typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index); +typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object); +typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object); +typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances); +typedef void (*Mf_Skip_Func)(void *object, UInt32); + +typedef struct _IMatchFinder +{ + Mf_Init_Func Init; + Mf_GetIndexByte_Func GetIndexByte; + Mf_GetNumAvailableBytes_Func GetNumAvailableBytes; + Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos; + Mf_GetMatches_Func GetMatches; + Mf_Skip_Func Skip; +} IMatchFinder; + +void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable); + +void MatchFinder_Init(CMatchFinder *p); +UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances); +void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); +void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num); + +#endif diff --git a/flash.tos/drivers/tools/LzHash.h b/flash.tos/drivers/tools/LzHash.h new file mode 100644 index 0000000..c3d5586 --- /dev/null +++ b/flash.tos/drivers/tools/LzHash.h @@ -0,0 +1,77 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZHASH_H +#define __LZHASH_H + +#define kHash2Size (1 << 10) +#define kHash3Size (1 << 16) +#define kHash4Size (1 << 20) + +#define kFix3HashSize (kHash2Size) +#define kFix4HashSize (kHash2Size + kHash3Size) +#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size) + +#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8); + +#define HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; } + +#define HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; } + +#define HASH5_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \ + hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \ + hash4Value &= (kHash4Size - 1); } + +/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */ +#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF; + + +#define MT_HASH2_CALC \ + hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1); + +#define MT_HASH3_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); } + +#define MT_HASH4_CALC { \ + UInt32 temp = p->crc[cur[0]] ^ cur[1]; \ + hash2Value = temp & (kHash2Size - 1); \ + hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \ + hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); } + +#endif diff --git a/flash.tos/drivers/tools/LzmaEnc.c b/flash.tos/drivers/tools/LzmaEnc.c new file mode 100644 index 0000000..d7dc6d9 --- /dev/null +++ b/flash.tos/drivers/tools/LzmaEnc.c @@ -0,0 +1,2232 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#include +#include + +#include "LzmaEnc.h" + +#include "LzFind.h" + +#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1) + +#define kBlockSize (9 << 10) +#define kUnpackBlockSize (1 << 18) +#define kMatchArraySize (1 << 21) +#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX) + +#define kNumMaxDirectBits (31) + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 +#define kProbInitValue (kBitModelTotal >> 1) + +#define kNumMoveReducingBits 4 +#define kNumBitPriceShiftBits 4 +#define kBitPrice (1 << kNumBitPriceShiftBits) + +void LzmaEncProps_Init(CLzmaEncProps *p) +{ + p->level = 5; + p->dictSize = p->mc = 0; + p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1; + p->writeEndMark = 0; +} + +void LzmaEncProps_Normalize(CLzmaEncProps *p) +{ + int level = p->level; + if (level < 0) level = 5; + p->level = level; + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); + if (p->lc < 0) p->lc = 3; + if (p->lp < 0) p->lp = 0; + if (p->pb < 0) p->pb = 2; + if (p->algo < 0) p->algo = (level < 5 ? 0 : 1); + if (p->fb < 0) p->fb = (level < 7 ? 32 : 64); + if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); + if (p->numHashBytes < 0) p->numHashBytes = 4; + if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); + if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1); +} + +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2) +{ + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + return props.dictSize; +} + +#define kNumLogBits (9 + (int)sizeof(size_t) / 2) +#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7) + +void LzmaEnc_FastPosInit(Byte *g_FastPos) +{ + int c = 2, slotFast; + g_FastPos[0] = 0; + g_FastPos[1] = 1; + + for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++) + { + UInt32 k = (1 << ((slotFast >> 1) - 1)); + UInt32 j; + for (j = 0; j < k; j++, c++) + g_FastPos[c] = (Byte)slotFast; + } +} + +#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \ + (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \ + res = p->g_FastPos[pos >> i] + (i * 2); } +/* +#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \ + p->g_FastPos[pos >> 6] + 12 : \ + p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; } +*/ + +#define GetPosSlot1(pos) p->g_FastPos[pos] +#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); } +#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); } + +#define LZMA_NUM_REPS 4 + +typedef unsigned CState; + +typedef struct _COptimal +{ + UInt32 price; + + CState state; + int prev1IsChar; + int prev2; + + UInt32 posPrev2; + UInt32 backPrev2; + + UInt32 posPrev; + UInt32 backPrev; + UInt32 backs[LZMA_NUM_REPS]; +} COptimal; + +#define kNumOpts (1 << 12) + +#define kNumLenToPosStates 4 +#define kNumPosSlotBits 6 +#define kDicLogSizeMin 0 +#define kDicLogSizeMax 32 +#define kDistTableSizeMax (kDicLogSizeMax * 2) + + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) +#define kAlignMask (kAlignTableSize - 1) + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex) + +#define kNumFullDistances (1 << (kEndPosModelIndex / 2)) + +#ifdef _LZMA_PROB32 +#define CLzmaProb UInt32 +#else +#define CLzmaProb UInt16 +#endif + +#define LZMA_PB_MAX 4 +#define LZMA_LC_MAX 8 +#define LZMA_LP_MAX 4 + +#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX) + + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define LZMA_MATCH_LEN_MIN 2 +#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1) + +#define kNumStates 12 + +typedef struct +{ + CLzmaProb choice; + CLzmaProb choice2; + CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits]; + CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits]; + CLzmaProb high[kLenNumHighSymbols]; +} CLenEnc; + +typedef struct +{ + CLenEnc p; + UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal]; + UInt32 tableSize; + UInt32 counters[LZMA_NUM_PB_STATES_MAX]; +} CLenPriceEnc; + +typedef struct _CRangeEnc +{ + UInt32 range; + Byte cache; + UInt64 low; + UInt64 cacheSize; + Byte *buf; + Byte *bufLim; + Byte *bufBase; + ISeqOutStream *outStream; + UInt64 processed; + SRes res; +} CRangeEnc; + +typedef struct _CSeqInStreamBuf +{ + ISeqInStream funcTable; + const Byte *data; + SizeT rem; +} CSeqInStreamBuf; + +static SRes MyRead(void *pp, void *data, size_t *size) +{ + size_t curSize = *size; + CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp; + if (p->rem < curSize) + curSize = p->rem; + memcpy(data, p->data, curSize); + p->rem -= curSize; + p->data += curSize; + *size = curSize; + return SZ_OK; +} + +typedef struct +{ + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; +} CSaveState; + +typedef struct _CLzmaEnc +{ + IMatchFinder matchFinder; + void *matchFinderObj; + + CMatchFinder matchFinderBase; + + UInt32 optimumEndIndex; + UInt32 optimumCurrentIndex; + + Bool longestMatchWasFound; + UInt32 longestMatchLength; + UInt32 numDistancePairs; + + COptimal opt[kNumOpts]; + + Byte g_FastPos[1 << kNumLogBits]; + + UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; + UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1]; + UInt32 numFastBytes; + UInt32 additionalOffset; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 state; + + UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax]; + UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances]; + UInt32 alignPrices[kAlignTableSize]; + UInt32 alignPriceCount; + + UInt32 distTableSize; + + unsigned lc, lp, pb; + unsigned lpMask, pbMask; + + CLzmaProb *litProbs; + + CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX]; + CLzmaProb isRep[kNumStates]; + CLzmaProb isRepG0[kNumStates]; + CLzmaProb isRepG1[kNumStates]; + CLzmaProb isRepG2[kNumStates]; + CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX]; + + CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; + CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; + CLzmaProb posAlignEncoder[1 << kNumAlignBits]; + + CLenPriceEnc lenEnc; + CLenPriceEnc repLenEnc; + + unsigned lclp; + + Bool fastMode; + + CRangeEnc rc; + + Bool writeEndMark; + UInt64 nowPos64; + UInt32 matchPriceCount; + Bool finished; + Bool multiThread; + + SRes result; + UInt32 dictSize; + UInt32 matchFinderCycles; + + ISeqInStream *inStream; + CSeqInStreamBuf seqBufInStream; + + CSaveState saveState; +} CLzmaEnc; + +void LzmaEnc_SaveState(CLzmaEncHandle pp) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CSaveState *dest = &p->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb)); +} + +void LzmaEnc_RestoreState(CLzmaEncHandle pp) +{ + CLzmaEnc *dest = (CLzmaEnc *)pp; + const CSaveState *p = &dest->saveState; + int i; + dest->lenEnc = p->lenEnc; + dest->repLenEnc = p->repLenEnc; + dest->state = p->state; + + for (i = 0; i < kNumStates; i++) + { + memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i])); + memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i])); + } + for (i = 0; i < kNumLenToPosStates; i++) + memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i])); + memcpy(dest->isRep, p->isRep, sizeof(p->isRep)); + memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0)); + memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1)); + memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2)); + memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders)); + memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder)); + memcpy(dest->reps, p->reps, sizeof(p->reps)); + memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb)); +} + +SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + CLzmaEncProps props = *props2; + LzmaEncProps_Normalize(&props); + + if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX || + props.dictSize > (1U << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30)) + return SZ_ERROR_PARAM; + p->dictSize = props.dictSize; + p->matchFinderCycles = props.mc; + { + unsigned fb = props.fb; + if (fb < 5) + fb = 5; + if (fb > LZMA_MATCH_LEN_MAX) + fb = LZMA_MATCH_LEN_MAX; + p->numFastBytes = fb; + } + p->lc = props.lc; + p->lp = props.lp; + p->pb = props.pb; + p->fastMode = (props.algo == 0); + p->matchFinderBase.btMode = props.btMode; + { + UInt32 numHashBytes = 4; + if (props.btMode) + { + if (props.numHashBytes < 2) + numHashBytes = 2; + else if (props.numHashBytes < 4) + numHashBytes = props.numHashBytes; + } + p->matchFinderBase.numHashBytes = numHashBytes; + } + + p->matchFinderBase.cutValue = props.mc; + + p->writeEndMark = props.writeEndMark; + + return SZ_OK; +} + +static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5}; +static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10}; +static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11}; +static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11}; + +/* + void UpdateChar() { Index = kLiteralNextStates[Index]; } + void UpdateMatch() { Index = kMatchNextStates[Index]; } + void UpdateRep() { Index = kRepNextStates[Index]; } + void UpdateShortRep() { Index = kShortRepNextStates[Index]; } +*/ + +#define IsCharState(s) ((s) < 7) + + +#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1) + +#define kInfinityPrice (1 << 30) + +static void RangeEnc_Construct(CRangeEnc *p) +{ + p->outStream = 0; + p->bufBase = 0; +} + +#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize) + +#define RC_BUF_SIZE (1 << 16) +static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc) +{ + if (p->bufBase == 0) + { + p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE); + if (p->bufBase == 0) + return 0; + p->bufLim = p->bufBase + RC_BUF_SIZE; + } + return 1; +} + +static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->bufBase); + p->bufBase = 0; +} + +static void RangeEnc_Init(CRangeEnc *p) +{ + /* Stream.Init(); */ + p->low = 0; + p->range = 0xFFFFFFFF; + p->cacheSize = 1; + p->cache = 0; + + p->buf = p->bufBase; + + p->processed = 0; + p->res = SZ_OK; +} + +static void RangeEnc_FlushStream(CRangeEnc *p) +{ + size_t num; + if (p->res != SZ_OK) + return; + num = p->buf - p->bufBase; + if (num != p->outStream->Write(p->outStream, p->bufBase, num)) + p->res = SZ_ERROR_WRITE; + p->processed += num; + p->buf = p->bufBase; +} + +static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p) +{ + if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0) + { + Byte temp = p->cache; + do + { + Byte *buf = p->buf; + *buf++ = (Byte)(temp + (Byte)(p->low >> 32)); + p->buf = buf; + if (buf == p->bufLim) + RangeEnc_FlushStream(p); + temp = 0xFF; + } + while (--p->cacheSize != 0); + p->cache = (Byte)((UInt32)p->low >> 24); + } + p->cacheSize++; + p->low = (UInt32)p->low << 8; +} + +static void RangeEnc_FlushData(CRangeEnc *p) +{ + int i; + for (i = 0; i < 5; i++) + RangeEnc_ShiftLow(p); +} + +static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits) +{ + do + { + p->range >>= 1; + p->low += p->range & (0 - ((value >> --numBits) & 1)); + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } + } + while (numBits != 0); +} + +static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol) +{ + UInt32 ttt = *prob; + UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt; + if (symbol == 0) + { + p->range = newBound; + ttt += (kBitModelTotal - ttt) >> kNumMoveBits; + } + else + { + p->low += newBound; + p->range -= newBound; + ttt -= ttt >> kNumMoveBits; + } + *prob = (CLzmaProb)ttt; + if (p->range < kTopValue) + { + p->range <<= 8; + RangeEnc_ShiftLow(p); + } +} + +static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol) +{ + symbol |= 0x100; + do + { + RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); +} + +static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte) +{ + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); +} + +void LzmaEnc_InitPriceTables(UInt32 *ProbPrices) +{ + UInt32 i; + for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits)) + { + const int kCyclesBits = kNumBitPriceShiftBits; + UInt32 w = i; + UInt32 bitCount = 0; + int j; + for (j = 0; j < kCyclesBits; j++) + { + w = w * w; + bitCount <<= 1; + while (w >= ((UInt32)1 << 16)) + { + w >>= 1; + bitCount++; + } + } + ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount); + } +} + + +#define GET_PRICE(prob, symbol) \ + p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICEa(prob, symbol) \ + ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits]; + +#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits] +#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits] + +static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= 0x100; + do + { + price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1); + symbol <<= 1; + } + while (symbol < 0x10000); + return price; +}; + +static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 offs = 0x100; + symbol |= 0x100; + do + { + matchByte <<= 1; + price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1); + symbol <<= 1; + offs &= ~(matchByte ^ symbol); + } + while (symbol < 0x10000); + return price; +}; + + +static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0 ;) + { + UInt32 bit; + i--; + bit = (symbol >> i) & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + } +}; + +static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol) +{ + UInt32 m = 1; + int i; + for (i = 0; i < numBitLevels; i++) + { + UInt32 bit = symbol & 1; + RangeEnc_EncodeBit(rc, probs + m, bit); + m = (m << 1) | bit; + symbol >>= 1; + } +} + +static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + symbol |= (1 << numBitLevels); + while (symbol != 1) + { + price += GET_PRICEa(probs[symbol >> 1], symbol & 1); + symbol >>= 1; + } + return price; +} + +static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices) +{ + UInt32 price = 0; + UInt32 m = 1; + int i; + for (i = numBitLevels; i != 0; i--) + { + UInt32 bit = symbol & 1; + symbol >>= 1; + price += GET_PRICEa(probs[m], bit); + m = (m << 1) | bit; + } + return price; +} + + +static void LenEnc_Init(CLenEnc *p) +{ + unsigned i; + p->choice = p->choice2 = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++) + p->low[i] = kProbInitValue; + for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++) + p->mid[i] = kProbInitValue; + for (i = 0; i < kLenNumHighSymbols; i++) + p->high[i] = kProbInitValue; +} + +static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState) +{ + if (symbol < kLenNumLowSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice, 0); + RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice, 1); + if (symbol < kLenNumLowSymbols + kLenNumMidSymbols) + { + RangeEnc_EncodeBit(rc, &p->choice2, 0); + RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols); + } + else + { + RangeEnc_EncodeBit(rc, &p->choice2, 1); + RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols); + } + } +} + +static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices) +{ + UInt32 a0 = GET_PRICE_0a(p->choice); + UInt32 a1 = GET_PRICE_1a(p->choice); + UInt32 b0 = a1 + GET_PRICE_0a(p->choice2); + UInt32 b1 = a1 + GET_PRICE_1a(p->choice2); + UInt32 i = 0; + for (i = 0; i < kLenNumLowSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices); + } + for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++) + { + if (i >= numSymbols) + return; + prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices); + } + for (; i < numSymbols; i++) + prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices); +} + +static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices) +{ + LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices); + p->counters[posState] = p->tableSize; +} + +static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices) +{ + UInt32 posState; + for (posState = 0; posState < numPosStates; posState++) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + +static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices) +{ + LenEnc_Encode(&p->p, rc, symbol, posState); + if (updatePrice) + if (--p->counters[posState] == 0) + LenPriceEnc_UpdateTable(p, posState, ProbPrices); +} + + + + +static void MovePos(CLzmaEnc *p, UInt32 num) +{ + if (num != 0) + { + p->additionalOffset += num; + p->matchFinder.Skip(p->matchFinderObj, num); + } +} + +static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes) +{ + UInt32 lenRes = 0, numDistancePairs; + numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances); + if (numDistancePairs > 0) + { + lenRes = p->matchDistances[numDistancePairs - 2]; + if (lenRes == p->numFastBytes) + { + UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1; + const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1; + if (numAvail > LZMA_MATCH_LEN_MAX) + numAvail = LZMA_MATCH_LEN_MAX; + + { + const Byte *pby2 = pby - distance; + for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++); + } + } + } + p->additionalOffset++; + *numDistancePairsRes = numDistancePairs; + return lenRes; +} + + +#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False; +#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False; +#define IsShortRep(p) ((p)->backPrev == 0) + +static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState) +{ + return + GET_PRICE_0(p->isRepG0[state]) + + GET_PRICE_0(p->isRep0Long[state][posState]); +} + +static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState) +{ + UInt32 price; + if (repIndex == 0) + { + price = GET_PRICE_0(p->isRepG0[state]); + price += GET_PRICE_1(p->isRep0Long[state][posState]); + } + else + { + price = GET_PRICE_1(p->isRepG0[state]); + if (repIndex == 1) + price += GET_PRICE_0(p->isRepG1[state]); + else + { + price += GET_PRICE_1(p->isRepG1[state]); + price += GET_PRICE(p->isRepG2[state], repIndex - 2); + } + } + return price; +} + +static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState) +{ + return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] + + GetPureRepPrice(p, repIndex, state, posState); +} + +static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur) +{ + UInt32 posMem = p->opt[cur].posPrev; + UInt32 backMem = p->opt[cur].backPrev; + p->optimumEndIndex = cur; + do + { + if (p->opt[cur].prev1IsChar) + { + MakeAsChar(&p->opt[posMem]) + p->opt[posMem].posPrev = posMem - 1; + if (p->opt[cur].prev2) + { + p->opt[posMem - 1].prev1IsChar = False; + p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2; + p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2; + } + } + { + UInt32 posPrev = posMem; + UInt32 backCur = backMem; + + backMem = p->opt[posPrev].backPrev; + posMem = p->opt[posPrev].posPrev; + + p->opt[posPrev].backPrev = backCur; + p->opt[posPrev].posPrev = cur; + cur = posPrev; + } + } + while (cur != 0); + *backRes = p->opt[0].backPrev; + p->optimumCurrentIndex = p->opt[0].posPrev; + return p->optimumCurrentIndex; +} + +#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300) + +static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes) +{ + UInt32 numAvailableBytes, lenMain, numDistancePairs; + const Byte *data; + UInt32 reps[LZMA_NUM_REPS]; + UInt32 repLens[LZMA_NUM_REPS]; + UInt32 repMaxIndex, i; + UInt32 *matchDistances; + Byte currentByte, matchByte; + UInt32 posState; + UInt32 matchPrice, repMatchPrice; + UInt32 lenEnd; + UInt32 len; + UInt32 normalMatchPrice; + UInt32 cur; + if (p->optimumEndIndex != p->optimumCurrentIndex) + { + const COptimal *opt = &p->opt[p->optimumCurrentIndex]; + UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex; + *backRes = opt->backPrev; + p->optimumCurrentIndex = opt->posPrev; + return lenRes; + } + p->optimumCurrentIndex = p->optimumEndIndex = 0; + + numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + + if (!p->longestMatchWasFound) + { + lenMain = ReadMatchDistances(p, &numDistancePairs); + } + else + { + lenMain = p->longestMatchLength; + numDistancePairs = p->numDistancePairs; + p->longestMatchWasFound = False; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + if (numAvailableBytes < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + if (numAvailableBytes > LZMA_MATCH_LEN_MAX) + numAvailableBytes = LZMA_MATCH_LEN_MAX; + + repMaxIndex = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 lenTest; + const Byte *data2; + reps[i] = p->reps[i]; + data2 = data - (reps[i] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); + repLens[i] = lenTest; + if (lenTest > repLens[repMaxIndex]) + repMaxIndex = i; + } + if (repLens[repMaxIndex] >= p->numFastBytes) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + + matchDistances = p->matchDistances; + if (lenMain >= p->numFastBytes) + { + *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; + MovePos(p, lenMain - 1); + return lenMain; + } + currentByte = *data; + matchByte = *(data - (reps[0] + 1)); + + if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2) + { + *backRes = (UInt32)-1; + return 1; + } + + p->opt[0].state = (CState)p->state; + + posState = (position & p->pbMask); + + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) + + (!IsCharState(p->state) ? + LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); + } + + MakeAsChar(&p->opt[1]); + + matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]); + + if (matchByte == currentByte) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState); + if (shortRepPrice < p->opt[1].price) + { + p->opt[1].price = shortRepPrice; + MakeAsShortRep(&p->opt[1]); + } + } + lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]); + + if (lenEnd < 2) + { + *backRes = p->opt[1].backPrev; + return 1; + } + + p->opt[1].posPrev = 0; + for (i = 0; i < LZMA_NUM_REPS; i++) + p->opt[0].backs[i] = reps[i]; + + len = lenEnd; + do + p->opt[len--].price = kInfinityPrice; + while (len >= 2); + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 repLen = repLens[i]; + UInt32 price; + if (repLen < 2) + continue; + price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2]; + COptimal *opt = &p->opt[repLen]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = i; + opt->prev1IsChar = False; + } + } + while (--repLen >= 2); + } + + normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]); + + len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2); + if (len <= lenMain) + { + UInt32 offs = 0; + while (len > matchDistances[offs]) + offs += 2; + for (; ; len++) + { + COptimal *opt; + UInt32 distance = matchDistances[offs + 1]; + + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(len); + if (distance < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][distance]; + else + { + UInt32 slot; + GetPosSlot2(distance, slot); + curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot]; + } + opt = &p->opt[len]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = 0; + opt->backPrev = distance + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + if (len == matchDistances[offs]) + { + offs += 2; + if (offs == numDistancePairs) + break; + } + } + } + + cur = 0; + for (;;) + { + UInt32 numAvailableBytesFull, newLen, numDistancePairs; + COptimal *curOpt; + UInt32 posPrev; + UInt32 state; + UInt32 curPrice; + Bool nextIsChar; + const Byte *data; + Byte currentByte, matchByte; + UInt32 posState; + UInt32 curAnd1Price; + COptimal *nextOpt; + UInt32 matchPrice, repMatchPrice; + UInt32 numAvailableBytes; + UInt32 startLen; + + cur++; + if (cur == lenEnd) + return Backward(p, backRes, cur); + + numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + newLen = ReadMatchDistances(p, &numDistancePairs); + if (newLen >= p->numFastBytes) + { + p->numDistancePairs = numDistancePairs; + p->longestMatchLength = newLen; + p->longestMatchWasFound = True; + return Backward(p, backRes, cur); + } + position++; + curOpt = &p->opt[cur]; + posPrev = curOpt->posPrev; + if (curOpt->prev1IsChar) + { + posPrev--; + if (curOpt->prev2) + { + state = p->opt[curOpt->posPrev2].state; + if (curOpt->backPrev2 < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + else + state = p->opt[posPrev].state; + state = kLiteralNextStates[state]; + } + else + state = p->opt[posPrev].state; + if (posPrev == cur - 1) + { + if (IsShortRep(curOpt)) + state = kShortRepNextStates[state]; + else + state = kLiteralNextStates[state]; + } + else + { + UInt32 pos; + const COptimal *prevOpt; + if (curOpt->prev1IsChar && curOpt->prev2) + { + posPrev = curOpt->posPrev2; + pos = curOpt->backPrev2; + state = kRepNextStates[state]; + } + else + { + pos = curOpt->backPrev; + if (pos < LZMA_NUM_REPS) + state = kRepNextStates[state]; + else + state = kMatchNextStates[state]; + } + prevOpt = &p->opt[posPrev]; + if (pos < LZMA_NUM_REPS) + { + UInt32 i; + reps[0] = prevOpt->backs[pos]; + for (i = 1; i <= pos; i++) + reps[i] = prevOpt->backs[i - 1]; + for (; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i]; + } + else + { + UInt32 i; + reps[0] = (pos - LZMA_NUM_REPS); + for (i = 1; i < LZMA_NUM_REPS; i++) + reps[i] = prevOpt->backs[i - 1]; + } + } + curOpt->state = (CState)state; + + curOpt->backs[0] = reps[0]; + curOpt->backs[1] = reps[1]; + curOpt->backs[2] = reps[2]; + curOpt->backs[3] = reps[3]; + + curPrice = curOpt->price; + nextIsChar = False; + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + currentByte = *data; + matchByte = *(data - (reps[0] + 1)); + + posState = (position & p->pbMask); + + curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]); + { + const CLzmaProb *probs = LIT_PROBS(position, *(data - 1)); + curAnd1Price += + (!IsCharState(state) ? + LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) : + LitEnc_GetPrice(probs, currentByte, p->ProbPrices)); + } + + nextOpt = &p->opt[cur + 1]; + + if (curAnd1Price < nextOpt->price) + { + nextOpt->price = curAnd1Price; + nextOpt->posPrev = cur; + MakeAsChar(nextOpt); + nextIsChar = True; + } + + matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); + repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); + + if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) + { + UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); + if (shortRepPrice <= nextOpt->price) + { + nextOpt->price = shortRepPrice; + nextOpt->posPrev = cur; + MakeAsShortRep(nextOpt); + nextIsChar = True; + } + } + + { + UInt32 temp = kNumOpts - 1 - cur; + if (temp < numAvailableBytesFull) + numAvailableBytesFull = temp; + } + numAvailableBytes = numAvailableBytesFull; + + if (numAvailableBytes < 2) + continue; + if (numAvailableBytes > p->numFastBytes) + numAvailableBytes = p->numFastBytes; + if (!nextIsChar && matchByte != currentByte) /* speed optimization */ + { + /* try Literal + rep0 */ + UInt32 temp; + UInt32 lenTest2; + const Byte *data2 = data - (reps[0] + 1); + UInt32 limit = p->numFastBytes + 1; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + + for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++); + lenTest2 = temp - 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kLiteralNextStates[state]; + UInt32 posStateNext = (position + 1) & p->pbMask; + UInt32 nextRepMatchPrice = curAnd1Price + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = False; + } + } + } + } + + startLen = 2; /* speed optimization */ + { + UInt32 repIndex; + for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++) + { + UInt32 lenTest; + UInt32 lenTestTemp; + UInt32 price; + const Byte *data2 = data - (reps[repIndex] + 1); + if (data[0] != data2[0] || data[1] != data2[1]) + continue; + for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++); + while (lenEnd < cur + lenTest) + p->opt[++lenEnd].price = kInfinityPrice; + lenTestTemp = lenTest; + price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState); + do + { + UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2]; + COptimal *opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = repIndex; + opt->prev1IsChar = False; + } + } + while (--lenTest >= 2); + lenTest = lenTestTemp; + + if (repIndex == 0) + startLen = lenTest + 1; + + /* if (_maxMode) */ + { + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kRepNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = + price + p->repLenEnc.prices[posState][lenTest - 2] + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (position + lenTest + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 curAndLenPrice; + COptimal *opt; + UInt32 offset = cur + lenTest + 1 + lenTest2; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = repIndex; + } + } + } + } + } + } + /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */ + if (newLen > numAvailableBytes) + { + newLen = numAvailableBytes; + for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2); + matchDistances[numDistancePairs] = newLen; + numDistancePairs += 2; + } + if (newLen >= startLen) + { + UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]); + UInt32 offs, curBack, posSlot; + UInt32 lenTest; + while (lenEnd < cur + newLen) + p->opt[++lenEnd].price = kInfinityPrice; + + offs = 0; + while (startLen > matchDistances[offs]) + offs += 2; + curBack = matchDistances[offs + 1]; + GetPosSlot2(curBack, posSlot); + for (lenTest = /*2*/ startLen; ; lenTest++) + { + UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN]; + UInt32 lenToPosState = GetLenToPosState(lenTest); + COptimal *opt; + if (curBack < kNumFullDistances) + curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; + else + curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; + + opt = &p->opt[cur + lenTest]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur; + opt->backPrev = curBack + LZMA_NUM_REPS; + opt->prev1IsChar = False; + } + + if (/*_maxMode && */lenTest == matchDistances[offs]) + { + /* Try Match + Literal + Rep0 */ + const Byte *data2 = data - (curBack + 1); + UInt32 lenTest2 = lenTest + 1; + UInt32 limit = lenTest2 + p->numFastBytes; + UInt32 nextRepMatchPrice; + if (limit > numAvailableBytesFull) + limit = numAvailableBytesFull; + for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); + lenTest2 -= lenTest + 1; + if (lenTest2 >= 2) + { + UInt32 state2 = kMatchNextStates[state]; + UInt32 posStateNext = (position + lenTest) & p->pbMask; + UInt32 curAndLenCharPrice = curAndLenPrice + + GET_PRICE_0(p->isMatch[state2][posStateNext]) + + LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]), + data[lenTest], data2[lenTest], p->ProbPrices); + state2 = kLiteralNextStates[state2]; + posStateNext = (posStateNext + 1) & p->pbMask; + nextRepMatchPrice = curAndLenCharPrice + + GET_PRICE_1(p->isMatch[state2][posStateNext]) + + GET_PRICE_1(p->isRep[state2]); + + /* for (; lenTest2 >= 2; lenTest2--) */ + { + UInt32 offset = cur + lenTest + 1 + lenTest2; + UInt32 curAndLenPrice; + COptimal *opt; + while (lenEnd < offset) + p->opt[++lenEnd].price = kInfinityPrice; + curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext); + opt = &p->opt[offset]; + if (curAndLenPrice < opt->price) + { + opt->price = curAndLenPrice; + opt->posPrev = cur + lenTest + 1; + opt->backPrev = 0; + opt->prev1IsChar = True; + opt->prev2 = True; + opt->posPrev2 = cur; + opt->backPrev2 = curBack + LZMA_NUM_REPS; + } + } + } + offs += 2; + if (offs == numDistancePairs) + break; + curBack = matchDistances[offs + 1]; + if (curBack >= kNumFullDistances) + GetPosSlot2(curBack, posSlot); + } + } + } + } +} + +#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist)) + +static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes) +{ + UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + UInt32 lenMain, numDistancePairs; + const Byte *data; + UInt32 repLens[LZMA_NUM_REPS]; + UInt32 repMaxIndex, i; + UInt32 *matchDistances; + UInt32 backMain; + + if (!p->longestMatchWasFound) + { + lenMain = ReadMatchDistances(p, &numDistancePairs); + } + else + { + lenMain = p->longestMatchLength; + numDistancePairs = p->numDistancePairs; + p->longestMatchWasFound = False; + } + + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + if (numAvailableBytes > LZMA_MATCH_LEN_MAX) + numAvailableBytes = LZMA_MATCH_LEN_MAX; + if (numAvailableBytes < 2) + { + *backRes = (UInt32)(-1); + return 1; + } + + repMaxIndex = 0; + + for (i = 0; i < LZMA_NUM_REPS; i++) + { + const Byte *data2 = data - (p->reps[i] + 1); + UInt32 len; + if (data[0] != data2[0] || data[1] != data2[1]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); + if (len >= p->numFastBytes) + { + *backRes = i; + MovePos(p, len - 1); + return len; + } + repLens[i] = len; + if (len > repLens[repMaxIndex]) + repMaxIndex = i; + } + matchDistances = p->matchDistances; + if (lenMain >= p->numFastBytes) + { + *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS; + MovePos(p, lenMain - 1); + return lenMain; + } + + backMain = 0; /* for GCC */ + if (lenMain >= 2) + { + backMain = matchDistances[numDistancePairs - 1]; + while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1) + { + if (!ChangePair(matchDistances[numDistancePairs - 3], backMain)) + break; + numDistancePairs -= 2; + lenMain = matchDistances[numDistancePairs - 2]; + backMain = matchDistances[numDistancePairs - 1]; + } + if (lenMain == 2 && backMain >= 0x80) + lenMain = 1; + } + + if (repLens[repMaxIndex] >= 2) + { + if (repLens[repMaxIndex] + 1 >= lenMain || + (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) || + (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15)))) + { + UInt32 lenRes; + *backRes = repMaxIndex; + lenRes = repLens[repMaxIndex]; + MovePos(p, lenRes - 1); + return lenRes; + } + } + + if (lenMain >= 2 && numAvailableBytes > 2) + { + UInt32 i; + numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); + p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs); + if (p->longestMatchLength >= 2) + { + UInt32 newDistance = matchDistances[p->numDistancePairs - 1]; + if ((p->longestMatchLength >= lenMain && newDistance < backMain) || + (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) || + (p->longestMatchLength > lenMain + 1) || + (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain))) + { + p->longestMatchWasFound = True; + *backRes = (UInt32)(-1); + return 1; + } + } + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; + for (i = 0; i < LZMA_NUM_REPS; i++) + { + UInt32 len; + const Byte *data2 = data - (p->reps[i] + 1); + if (data[1] != data2[1] || data[2] != data2[2]) + { + repLens[i] = 0; + continue; + } + for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++); + if (len + 1 >= lenMain) + { + p->longestMatchWasFound = True; + *backRes = (UInt32)(-1); + return 1; + } + } + *backRes = backMain + LZMA_NUM_REPS; + MovePos(p, lenMain - 2); + return lenMain; + } + *backRes = (UInt32)(-1); + return 1; +} + +static void WriteEndMarker(CLzmaEnc *p, UInt32 posState) +{ + UInt32 len; + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + len = LZMA_MATCH_LEN_MIN; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1); + RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask); +} + +static SRes CheckErrors(CLzmaEnc *p) +{ + if (p->result != SZ_OK) + return p->result; + if (p->rc.res != SZ_OK) + p->result = SZ_ERROR_WRITE; + if (p->matchFinderBase.result != SZ_OK) + p->result = SZ_ERROR_READ; + if (p->result != SZ_OK) + p->finished = True; + return p->result; +} + +static SRes Flush(CLzmaEnc *p, UInt32 nowPos) +{ + /* ReleaseMFStream(); */ + p->finished = True; + if (p->writeEndMark) + WriteEndMarker(p, nowPos & p->pbMask); + RangeEnc_FlushData(&p->rc); + RangeEnc_FlushStream(&p->rc); + return CheckErrors(p); +} + +static void FillAlignPrices(CLzmaEnc *p) +{ + UInt32 i; + for (i = 0; i < kAlignTableSize; i++) + p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices); + p->alignPriceCount = 0; +} + +static void FillDistancesPrices(CLzmaEnc *p) +{ + UInt32 tempPrices[kNumFullDistances]; + UInt32 i, lenToPosState; + for (i = kStartPosModelIndex; i < kNumFullDistances; i++) + { + UInt32 posSlot = GetPosSlot1(i); + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices); + } + + for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++) + { + UInt32 posSlot; + const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState]; + UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState]; + for (posSlot = 0; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices); + for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++) + posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits); + + { + UInt32 *distancesPrices = p->distancesPrices[lenToPosState]; + UInt32 i; + for (i = 0; i < kStartPosModelIndex; i++) + distancesPrices[i] = posSlotPrices[i]; + for (; i < kNumFullDistances; i++) + distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i]; + } + } + p->matchPriceCount = 0; +} + +void LzmaEnc_Construct(CLzmaEnc *p) +{ + RangeEnc_Construct(&p->rc); + MatchFinder_Construct(&p->matchFinderBase); + + { + CLzmaEncProps props; + LzmaEncProps_Init(&props); + LzmaEnc_SetProps(p, &props); + } + + LzmaEnc_FastPosInit(p->g_FastPos); + LzmaEnc_InitPriceTables(p->ProbPrices); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc) +{ + void *p; + p = alloc->Alloc(alloc, sizeof(CLzmaEnc)); + if (p != 0) + LzmaEnc_Construct((CLzmaEnc *)p); + return p; +} + +void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->litProbs); + alloc->Free(alloc, p->saveState.litProbs); + p->litProbs = 0; + p->saveState.litProbs = 0; +} + +void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + MatchFinder_Free(&p->matchFinderBase, allocBig); + LzmaEnc_FreeLits(p, alloc); + RangeEnc_Free(&p->rc, alloc); +} + +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig); + alloc->Free(alloc, p); +} + +static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize) +{ + UInt32 nowPos32, startPos32; + if (p->inStream != 0) + { + p->matchFinderBase.stream = p->inStream; + p->matchFinder.Init(p->matchFinderObj); + p->inStream = 0; + } + + if (p->finished) + return p->result; + RINOK(CheckErrors(p)); + + nowPos32 = (UInt32)p->nowPos64; + startPos32 = nowPos32; + + if (p->nowPos64 == 0) + { + UInt32 numDistancePairs; + Byte curByte; + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + return Flush(p, nowPos32); + ReadMatchDistances(p, &numDistancePairs); + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0); + p->state = kLiteralNextStates[p->state]; + curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset); + LitEnc_Encode(&p->rc, p->litProbs, curByte); + p->additionalOffset--; + nowPos32++; + } + + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0) + for (;;) + { + UInt32 pos, len, posState; + + if (p->fastMode) + len = GetOptimumFast(p, &pos); + else + len = GetOptimum(p, nowPos32, &pos); + + posState = nowPos32 & p->pbMask; + if (len == 1 && pos == 0xFFFFFFFF) + { + Byte curByte; + CLzmaProb *probs; + const Byte *data; + + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0); + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; + curByte = *data; + probs = LIT_PROBS(nowPos32, *(data - 1)); + if (IsCharState(p->state)) + LitEnc_Encode(&p->rc, probs, curByte); + else + LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1)); + p->state = kLiteralNextStates[p->state]; + } + else + { + RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1); + if (pos < LZMA_NUM_REPS) + { + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1); + if (pos == 0) + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0); + RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1)); + } + else + { + UInt32 distance = p->reps[pos]; + RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1); + if (pos == 1) + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0); + else + { + RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1); + RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2); + if (pos == 3) + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + } + p->reps[1] = p->reps[0]; + p->reps[0] = distance; + } + if (len == 1) + p->state = kShortRepNextStates[p->state]; + else + { + LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + p->state = kRepNextStates[p->state]; + } + } + else + { + UInt32 posSlot; + RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0); + p->state = kMatchNextStates[p->state]; + LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices); + pos -= LZMA_NUM_REPS; + GetPosSlot(pos, posSlot); + RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); + + if (posSlot >= kStartPosModelIndex) + { + UInt32 footerBits = ((posSlot >> 1) - 1); + UInt32 base = ((2 | (posSlot & 1)) << footerBits); + UInt32 posReduced = pos - base; + + if (posSlot < kEndPosModelIndex) + RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced); + else + { + RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits); + RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask); + p->alignPriceCount++; + } + } + p->reps[3] = p->reps[2]; + p->reps[2] = p->reps[1]; + p->reps[1] = p->reps[0]; + p->reps[0] = pos; + p->matchPriceCount++; + } + } + p->additionalOffset -= len; + nowPos32 += len; + if (p->additionalOffset == 0) + { + UInt32 processed; + if (!p->fastMode) + { + if (p->matchPriceCount >= (1 << 7)) + FillDistancesPrices(p); + if (p->alignPriceCount >= kAlignTableSize) + FillAlignPrices(p); + } + if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0) + break; + processed = nowPos32 - startPos32; + if (useLimits) + { + if (processed + kNumOpts + 300 >= maxUnpackSize || + RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize) + break; + } + else if (processed >= (1 << 15)) + { + p->nowPos64 += nowPos32 - startPos32; + return CheckErrors(p); + } + } + } + p->nowPos64 += nowPos32 - startPos32; + return Flush(p, nowPos32); +} + +#define kBigHashDicLimit ((UInt32)1 << 24) + +static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 beforeSize = kNumOpts; + Bool btMode; + if (!RangeEnc_Alloc(&p->rc, alloc)) + return SZ_ERROR_MEM; + btMode = (p->matchFinderBase.btMode != 0); + { + unsigned lclp = p->lc + p->lp; + if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp) + { + LzmaEnc_FreeLits(p, alloc); + p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb)); + if (p->litProbs == 0 || p->saveState.litProbs == 0) + { + LzmaEnc_FreeLits(p, alloc); + return SZ_ERROR_MEM; + } + p->lclp = lclp; + } + } + + p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit); + + if (beforeSize + p->dictSize < keepWindowSize) + beforeSize = keepWindowSize - p->dictSize; + + { + if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig)) + return SZ_ERROR_MEM; + p->matchFinderObj = &p->matchFinderBase; + MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); + } + return SZ_OK; +} + +void LzmaEnc_Init(CLzmaEnc *p) +{ + UInt32 i; + p->state = 0; + for(i = 0 ; i < LZMA_NUM_REPS; i++) + p->reps[i] = 0; + + RangeEnc_Init(&p->rc); + + + for (i = 0; i < kNumStates; i++) + { + UInt32 j; + for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++) + { + p->isMatch[i][j] = kProbInitValue; + p->isRep0Long[i][j] = kProbInitValue; + } + p->isRep[i] = kProbInitValue; + p->isRepG0[i] = kProbInitValue; + p->isRepG1[i] = kProbInitValue; + p->isRepG2[i] = kProbInitValue; + } + + { + UInt32 num = 0x300 << (p->lp + p->lc); + for (i = 0; i < num; i++) + p->litProbs[i] = kProbInitValue; + } + + { + for (i = 0; i < kNumLenToPosStates; i++) + { + CLzmaProb *probs = p->posSlotEncoder[i]; + UInt32 j; + for (j = 0; j < (1 << kNumPosSlotBits); j++) + probs[j] = kProbInitValue; + } + } + { + for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++) + p->posEncoders[i] = kProbInitValue; + } + + LenEnc_Init(&p->lenEnc.p); + LenEnc_Init(&p->repLenEnc.p); + + for (i = 0; i < (1 << kNumAlignBits); i++) + p->posAlignEncoder[i] = kProbInitValue; + + p->longestMatchWasFound = False; + p->optimumEndIndex = 0; + p->optimumCurrentIndex = 0; + p->additionalOffset = 0; + + p->pbMask = (1 << p->pb) - 1; + p->lpMask = (1 << p->lp) - 1; +} + +void LzmaEnc_InitPrices(CLzmaEnc *p) +{ + if (!p->fastMode) + { + FillDistancesPrices(p); + FillAlignPrices(p); + } + + p->lenEnc.tableSize = + p->repLenEnc.tableSize = + p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN; + LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices); + LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices); +} + +static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + UInt32 i; + for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++) + if (p->dictSize <= ((UInt32)1 << i)) + break; + p->distTableSize = i * 2; + + p->finished = False; + p->result = SZ_OK; + RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig)); + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + p->nowPos64 = 0; + return SZ_OK; +} + +static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + p->rc.outStream = outStream; + return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig); +} + +SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp, + ISeqInStream *inStream, UInt32 keepWindowSize, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + p->inStream = inStream; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen) +{ + p->seqBufInStream.funcTable.Read = MyRead; + p->seqBufInStream.data = src; + p->seqBufInStream.rem = srcLen; +} + +SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen, + UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + LzmaEnc_SetInputBuf(p, src, srcLen); + p->inStream = &p->seqBufInStream.funcTable; + return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig); +} + +void LzmaEnc_Finish(CLzmaEncHandle pp) +{ + (void)pp; +} + +typedef struct _CSeqOutStreamBuf +{ + ISeqOutStream funcTable; + Byte *data; + SizeT rem; + Bool overflow; +} CSeqOutStreamBuf; + +static size_t MyWrite(void *pp, const void *data, size_t size) +{ + CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp; + if (p->rem < size) + { + size = p->rem; + p->overflow = True; + } + memcpy(p->data, data, size); + p->rem -= size; + p->data += size; + return size; +} + + +UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); +} + +const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp) +{ + const CLzmaEnc *p = (CLzmaEnc *)pp; + return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset; +} + +SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit, + Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + UInt64 nowPos64; + SRes res; + CSeqOutStreamBuf outStream; + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = False; + p->finished = False; + p->result = SZ_OK; + + if (reInit) + LzmaEnc_Init(p); + LzmaEnc_InitPrices(p); + nowPos64 = p->nowPos64; + RangeEnc_Init(&p->rc); + p->rc.outStream = &outStream.funcTable; + + res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize); + + *unpackSize = (UInt32)(p->nowPos64 - nowPos64); + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + + return res; +} + +SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress, + ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + SRes res = SZ_OK; + + RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig)); + + for (;;) + { + res = LzmaEnc_CodeOneBlock(pp, False, 0, 0); + if (res != SZ_OK || p->finished != 0) + break; + if (progress != 0) + { + res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc)); + if (res != SZ_OK) + { + res = SZ_ERROR_PROGRESS; + break; + } + } + } + LzmaEnc_Finish(pp); + return res; +} + +SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size) +{ + CLzmaEnc *p = (CLzmaEnc *)pp; + int i; + UInt32 dictSize = p->dictSize; + if (*size < LZMA_PROPS_SIZE) + return SZ_ERROR_PARAM; + *size = LZMA_PROPS_SIZE; + props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc); + + for (i = 11; i <= 30; i++) + { + if (dictSize <= ((UInt32)2 << i)) + { + dictSize = (2 << i); + break; + } + if (dictSize <= ((UInt32)3 << i)) + { + dictSize = (3 << i); + break; + } + } + + for (i = 0; i < 4; i++) + props[1 + i] = (Byte)(dictSize >> (8 * i)); + return SZ_OK; +} + +SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + SRes res; + CLzmaEnc *p = (CLzmaEnc *)pp; + + CSeqOutStreamBuf outStream; + + LzmaEnc_SetInputBuf(p, src, srcLen); + + outStream.funcTable.Write = MyWrite; + outStream.data = dest; + outStream.rem = *destLen; + outStream.overflow = False; + + p->writeEndMark = writeEndMark; + res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable, + progress, alloc, allocBig); + + *destLen -= outStream.rem; + if (outStream.overflow) + return SZ_ERROR_OUTPUT_EOF; + return res; +} + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig) +{ + CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc); + SRes res; + if (p == 0) + return SZ_ERROR_MEM; + + res = LzmaEnc_SetProps(p, props); + if (res == SZ_OK) + { + res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize); + if (res == SZ_OK) + res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen, + writeEndMark, progress, alloc, allocBig); + } + + LzmaEnc_Destroy(p, alloc, allocBig); + return res; +} diff --git a/flash.tos/drivers/tools/LzmaEnc.h b/flash.tos/drivers/tools/LzmaEnc.h new file mode 100644 index 0000000..fc156a4 --- /dev/null +++ b/flash.tos/drivers/tools/LzmaEnc.h @@ -0,0 +1,95 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __LZMAENC_H +#define __LZMAENC_H + +#include "LzmaTypes.h" + +#define LZMA_PROPS_SIZE 5 + +typedef struct _CLzmaEncProps +{ + int level; /* 0 <= level <= 9 */ + UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version + (1 << 12) <= dictSize <= (1 << 30) for 64-bit version + default = (1 << 24) */ + int lc; /* 0 <= lc <= 8, default = 3 */ + int lp; /* 0 <= lp <= 4, default = 0 */ + int pb; /* 0 <= pb <= 4, default = 2 */ + int algo; /* 0 - fast, 1 - normal, default = 1 */ + int fb; /* 5 <= fb <= 273, default = 32 */ + int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */ + int numHashBytes; /* 2, 3 or 4, default = 4 */ + UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */ + unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */ + int numThreads; /* 1 or 2, default = 2 */ +} CLzmaEncProps; + +void LzmaEncProps_Init(CLzmaEncProps *p); +void LzmaEncProps_Normalize(CLzmaEncProps *p); +UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2); + + +/* ---------- CLzmaEncHandle Interface ---------- */ + +/* LzmaEnc_* functions can return the following exit codes: +Returns: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect parameter in props + SZ_ERROR_WRITE - Write callback error. + SZ_ERROR_PROGRESS - some break from progress callback + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +typedef void * CLzmaEncHandle; + +CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc); +void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props); +SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size); +SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); +SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +/* ---------- One Call Interface ---------- */ + +/* LzmaEncode +Return code: + SZ_OK - OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_PARAM - Incorrect parameter + SZ_ERROR_OUTPUT_EOF - output buffer overflow + SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version) +*/ + +SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen, + const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark, + ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig); + +#endif diff --git a/flash.tos/drivers/tools/LzmaTypes.h b/flash.tos/drivers/tools/LzmaTypes.h new file mode 100644 index 0000000..e4f2d9a --- /dev/null +++ b/flash.tos/drivers/tools/LzmaTypes.h @@ -0,0 +1,105 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (c) 1999-2008 Igor Pavlov + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB 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 GRUB. If not, see . + */ + +/* + * This code was taken from LZMA SDK 4.58 beta, and was slightly modified + * to adapt it to GRUB's requirement. + * + * See , for more information about LZMA. + */ + +#ifndef __7Z_TYPES_H +#define __7Z_TYPES_H + +#define SZ_OK 0 + +#define SZ_ERROR_DATA 1 +#define SZ_ERROR_MEM 2 +#define SZ_ERROR_CRC 3 +#define SZ_ERROR_UNSUPPORTED 4 +#define SZ_ERROR_PARAM 5 +#define SZ_ERROR_INPUT_EOF 6 +#define SZ_ERROR_OUTPUT_EOF 7 +#define SZ_ERROR_READ 8 +#define SZ_ERROR_WRITE 9 +#define SZ_ERROR_PROGRESS 10 +#define SZ_ERROR_FAIL 11 +#define SZ_ERROR_THREAD 12 + +#define SZ_ERROR_ARCHIVE 16 +#define SZ_ERROR_NO_ARCHIVE 17 + +typedef int SRes; + +#ifndef RINOK +#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; } +#endif + +typedef unsigned char Byte; +typedef short Int16; +typedef unsigned short UInt16; + +typedef int Int32; +typedef unsigned int UInt32; + +typedef long long int Int64; +typedef unsigned long long int UInt64; + +typedef UInt32 SizeT; + +typedef int Bool; +#define True 1 +#define False 0 +#define MY_CDECL +#define MY_STD_CALL +#define MY_FAST_CALL + +/* The following interfaces use first parameter as pointer to structure */ + +typedef struct +{ + SRes (*Read)(void *p, void *buf, size_t *size); + /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. + (output(*size) < input(*size)) is allowed */ +} ISeqInStream; + +typedef struct +{ + size_t (*Write)(void *p, const void *buf, size_t size); + /* Returns: result - the number of actually written bytes. + (result < size) means error */ +} ISeqOutStream; + +typedef struct +{ + SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize); + /* Returns: result. (result != SZ_OK) means break. + Value (UInt64)(Int64)-1 for size means unknown value. */ +} ICompressProgress; + +typedef struct +{ + void *(*Alloc)(void *p, size_t size); + void (*Free)(void *p, void *address); /* address can be 0 */ +} ISzAlloc; + +#define IAlloc_Alloc(p, size) (p)->Alloc((p), size) +#define IAlloc_Free(p, a) (p)->Free((p), a) + +#endif diff --git a/flash.tos/drivers/tools/compress.c b/flash.tos/drivers/tools/compress.c index 04f117f..1330304 100644 --- a/flash.tos/drivers/tools/compress.c +++ b/flash.tos/drivers/tools/compress.c @@ -2,18 +2,24 @@ #include #include #include "lz.h" +#include "LzmaEnc.h" #include "../../include/main.h" extern int srec_read(const char *path); void *buffer_flash=NULL; extern unsigned long start_addr,end_addr; +static void *SzAlloc(void *p, size_t size) { p = p; return (void *)Mxalloc(size,3); } +static void SzFree(void *p, void *address) { p = p; if(address != NULL) Mfree(address); } +static ISzAlloc g_Alloc = { SzAlloc, SzFree }; + int main(int argc, char **argv) { char *sbuf=NULL,*dbuf=NULL; - int *work=NULL; - long length, clength; + unsigned int *work=NULL; + long length,clength=0; short handle=-1; + int cf=0; unsigned long size_pci_drivers; char *buffer_pci_drivers=NULL; if(argc!=3) @@ -21,6 +27,8 @@ int main(int argc, char **argv) printf("Usage: compress input output\r\n"); return(-1); } + if(strstr(argv[1], "_cf") != NULL) + cf = 1; if(strstr(argv[1], ".hex") != NULL) { if((buffer_flash = (char *)Mxalloc(0x200000,3)) == NULL) @@ -57,28 +65,64 @@ int main(int argc, char **argv) else size_pci_drivers = end_addr-start_addr; buffer_pci_drivers = buffer_flash+start_addr-FLASH_ADR; - if((work = (int *)Mxalloc(sizeof(int)*(size_pci_drivers+65536),3)) == NULL) + if((work = (unsigned int *)Mxalloc(sizeof(int)*(size_pci_drivers+65536),3)) == NULL) { printf("Not enough memory for compress work buffer\r\n"); return(-1); } - if((dbuf = (unsigned char *)Mxalloc(FLASH_SIZE-PARAM_SIZE,3)) == NULL) + if((dbuf = (char *)Mxalloc(FLASH_SIZE-PARAM_SIZE,3)) == NULL) { printf("Not enough memory for target buffer\r\n"); goto error; } printf("compress drivers part %d bytes (0x%08lX-0x%08lX)... \r\n", (int)size_pci_drivers, start_addr, end_addr); - clength = (long)LZ_CompressFast(buffer_pci_drivers, dbuf+8, (int)size_pci_drivers, work); - printf("compress %s (%d) to %s (%d)\r\n", argv[1], (int)size_pci_drivers, argv[2], (int)clength); - if((unsigned long)clength > FLASH_ADR+FLASH_SIZE-PARAM_SIZE-start_addr-8) + if(!cf) { - printf("Not enough memory for put compressed drivers in flash."); - goto error; + clength = (long)LZ_CompressFast((unsigned char *)buffer_pci_drivers, (unsigned char *)&dbuf[8], (unsigned int)size_pci_drivers, work); + printf("compress %s (%d) to %s (%d)\r\n", argv[1], (int)size_pci_drivers, argv[2], (int)clength); + } + if(cf || ((unsigned long)clength > FLASH_ADR+FLASH_SIZE-PARAM_SIZE-start_addr-8)) + { + int i; + SizeT destLen; + CLzmaEncProps props; + unsigned char out_props[5]; + SizeT out_props_size = 5; + SRes rc; + if(!cf) + printf("Not enough memory for put compressed drivers in flash in LZ format (0x%lX bytes), try again with LZMA\r\n", clength); + LzmaEncProps_Init(&props); + props.dictSize = 1 << 16; + props.lc = 3; + props.lp = 0; + props.pb = 2; + props.numThreads = 1; + if((rc = LzmaEncode((unsigned char *)&dbuf[8+LZMA_PROPS_SIZE], &destLen, (unsigned char *)buffer_pci_drivers, size_pci_drivers, &props, out_props, &out_props_size, 1, NULL, &g_Alloc, &g_Alloc)) != SZ_OK) + { + printf("LzmaEncode error %d.\r\n", rc); + goto error; + } + printf("compress %s (%d) to %s (%d)\r\n", argv[1], (int)size_pci_drivers, argv[2], (int)destLen); + if((unsigned long)destLen > FLASH_ADR+FLASH_SIZE-PARAM_SIZE-start_addr-8-LZMA_PROPS_SIZE) + { + printf("Not enough memory for put compressed drivers in flash (0x%lX bytes).\r\n", destLen); + goto error; + } + dbuf[0] = 'L'; /* add header */ + dbuf[1] = 'Z'; + dbuf[2] = 'M'; + dbuf[3] = 'A'; + *(long *)&dbuf[4] = destLen; + for(i = 0; i < LZMA_PROPS_SIZE; dbuf[8 + i] = out_props[i], i++); + clength = LZMA_PROPS_SIZE + destLen; + } + else + { + dbuf[0] = dbuf[3]='_'; /* add header */ + dbuf[1] = 'L'; + dbuf[2] = 'Z'; + *(long *)&dbuf[4] = clength; } - dbuf[0] = dbuf[3]='_'; /* add header */ - dbuf[1] = 'L'; - dbuf[2] = 'Z'; - *(long *)&dbuf[4] = clength; clength += 8; } else /* binary file */ @@ -94,7 +138,7 @@ int main(int argc, char **argv) } Fseek(0, handle, 0); sbuf = (char *)Mxalloc(length, 3); - work = (int *)Mxalloc(sizeof(int)*(length+65536), 3); + work = (unsigned int *)Mxalloc(sizeof(int)*(length+65536), 3); dbuf = (char *)Mxalloc(length*11/10, 3); if(sbuf == NULL || work == NULL || dbuf == NULL) goto error; @@ -102,7 +146,7 @@ int main(int argc, char **argv) goto error; Fclose(handle); *(long *)dbuf = (long)length; - clength = (long)LZ_CompressFast(sbuf, dbuf+4, (int)length, work) + 4; + clength = (long)LZ_CompressFast((unsigned char *)sbuf, (unsigned char *)&dbuf[4], (unsigned int)length, work) + 4; printf("compress %s (%d) to %s (%d)\r\n", argv[1], (int)length, argv[2], (int)clength); } handle=Fcreate(argv[2], 0); diff --git a/flash.tos/drivers/usb/cmd_usb.c b/flash.tos/drivers/usb/cmd_usb.c index d6057e5..b44c87c 100644 --- a/flash.tos/drivers/usb/cmd_usb.c +++ b/flash.tos/drivers/usb/cmd_usb.c @@ -38,14 +38,14 @@ extern int usb_stor_curr_dev; /* current device */ #endif -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern long pxCurrentTCB, tid_TOS; // #define info(format, arg...) do { if(pxCurrentTCB == tid_TOS) kprint(format, ## arg); else board_printf(format, ## arg); } while(0) #else #define info(format, arg...) kprint(format, ## arg) #endif -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) typedef struct { @@ -76,7 +76,7 @@ static void info(const char *const fmt, ...) va_end(ap); } -#endif /* defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) */ +#endif /* defined(COLDFIRE) && defined(LWIP) */ /* some display routines (info command) */ char *usb_get_class_desc(unsigned char dclass) diff --git a/flash.tos/drivers/usb/ehci-hcd.c b/flash.tos/drivers/usb/ehci-hcd.c index 253e4f8..b35ebbd 100644 --- a/flash.tos/drivers/usb/ehci-hcd.c +++ b/flash.tos/drivers/usb/ehci-hcd.c @@ -28,11 +28,10 @@ #include "usb.h" #include "ehci.h" -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if (defined(COLDFIRE) && defined(LWIP)) || defined (FREERTOS) #include "../freertos/FreeRTOS.h" #include "../freertos/queue.h" extern xQueueHandle queue_poll_hub; -#define USB_POLL_HUB #endif #undef DEBUG @@ -141,6 +140,10 @@ static struct ehci { int irq; unsigned long dma_offset; const char *slot_name; +#ifndef COLDFIRE + /* CTPCI anti-freeze */ + long (*ctpci_dma_lock)(long mode); +#endif } gehci; #ifdef DEBUG @@ -148,17 +151,9 @@ static struct ehci { #else #define debug(format, arg...) do {} while (0) #endif /* DEBUG */ -#if defined(DEBUG) || defined(USB_POLL_HUB) -#define err(format, arg...) sprintD(usb_error_str, "ERROR: " format "\r\n", ## arg); board_printf(usb_error_str) -#else -#define err(format, arg...) sprintD(usb_error_str, "ERROR: " format "\r\n", ## arg); kprint(usb_error_str) -#endif /* DEBUG */ +#define err usb_error_msg #ifdef SHOW_INFO -#ifdef COLDFIRE -#define info(format, arg...) board_printf("INFO: " format "\r\n", ## arg) -#else #define info(format, arg...) board_printf("INFO: " format "\r\n", ## arg) -#endif /* COLDFIRE */ #else #define info(format, arg...) do {} while (0) #endif @@ -168,7 +163,6 @@ static struct ehci { static inline void flush_dcache_range(void *begin, void *end) { #ifndef CONFIG_USB_MEM_NO_CACHE -#ifdef NETWORK #ifdef LWIP extern unsigned long pxCurrentTCB, tid_TOS; extern void flush_dc(void); @@ -178,7 +172,6 @@ static inline void flush_dcache_range(void *begin, void *end) flush_dc(); else #endif /* LWIP */ -#endif /* NETWORK */ #if (__GNUC__ > 3) asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ #else @@ -195,18 +188,6 @@ extern void cpush_dc(void *base, long size); #define invalidate_dcache_range flush_dcache_range #endif /* COLDFIRE */ -typedef struct -{ - long ident; - union - { - long l; - short i[2]; - char c[4]; - } v; -} COOKIE; - -extern COOKIE *get_cookie(long id); extern void udelay(long usec); extern void ltoa(char *buf, long n, unsigned long base); @@ -218,6 +199,10 @@ extern void ltoa(char *buf, long n, unsigned long base); */ static void flush_invalidate(u32 addr, int size, int flush) { +#ifndef COLDFIRE + if(addr >= *ramtop) /* memory above ramtop is uncached memory */ + return; +#endif if(flush) flush_dcache_range(addr, addr + size); else @@ -291,7 +276,7 @@ static inline void ehci_invalidate_dcache(struct QH *qh) cache_qh(qh, 0); } -#else /* CONFIG_EHCI_DCACHE */ +#else /* !CONFIG_EHCI_DCACHE */ static inline void ehci_flush_dcache(struct QH *qh) { @@ -301,7 +286,6 @@ static inline void ehci_flush_dcache(struct QH *qh) static inline void ehci_invalidate_dcache(struct QH *qh) { #ifdef COLDFIRE /* no bus snooping on Coldfire */ -#ifdef NETWORK #ifdef LWIP extern unsigned long pxCurrentTCB, tid_TOS; extern void flush_dc(void); @@ -309,7 +293,6 @@ static inline void ehci_invalidate_dcache(struct QH *qh) flush_dc(); else #endif /* LWIP */ -#endif /* NETWORK */ #if (__GNUC__ > 3) asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ #else @@ -323,16 +306,54 @@ static inline void ehci_invalidate_dcache(struct QH *qh) static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec) { uint32_t result; +#ifndef COLDFIRE + extern void mdelay(long msec); + if(gehci.ctpci_dma_lock == NULL) + { + mdelay(10); + usec -= 10000; /* try to fix CTPCI freezes */ + } +#endif do { +#ifndef COLDFIRE + if(gehci.ctpci_dma_lock != NULL) + { + int i = 0; + while((i <= 10000) && gehci.ctpci_dma_lock(1)) + { + udelay(1); /* try to fix CTPCI freezes */ + i++; + } + if(i > 10000) + err("EHCI fail to lock DMA"); + } +#endif result = ehci_readl(ptr); +#ifndef COLDFIRE + if(gehci.ctpci_dma_lock != NULL) + gehci.ctpci_dma_lock(0); +#endif if(result == ~(uint32_t)0) return -1; result &= mask; if(result == done) return 0; +#ifdef COLDFIRE udelay(1); usec--; +#else /* !COLDFIRE */ + if(gehci.ctpci_dma_lock != NULL) + { + udelay(10); + usec -= 10; + } + else + { + mdelay(10); + usec -= 10000; /* try to fix CTPCI freezes */ + } +#endif /* COLDFIRE */ } while(usec > 0); return -1; @@ -360,6 +381,61 @@ static int ehci_reset(void) #endif } #endif /* MCF547X */ +#if !defined(COLDFIRE) && defined(CONFIG_USB_OHCI) && !defined(CONFIG_USB_INTERRUPT_POLLING) + { /* if driver started without PCI reset => disable OHCI interrupts */ +#define OHCI_INTRDISABLE 0x14 +#define OHCI_INTR_MIE (1 << 31) /* master interrupt enable */ + short index = 0; + long handle; + do + { +#ifdef PCI_XBIOS + handle = find_pci_device(0x0000FFFFL, index++); +#else + handle = Find_pci_device(0x0000FFFFL, index++); +#endif + if((handle >= 0) && ((gehci.handle & 0xFFFF) == (handle & 0xFFFF))) + { + unsigned long class; +#ifdef PCI_XBIOS + long error = read_config_longword(handle, PCIREV, &class); +#else + long error = Read_config_longword(handle, PCIREV, &class); +#endif + if((error >= 0) && ((class >> 16) == PCI_CLASS_SERIAL_USB) && ((class >> 8) == PCI_CLASS_SERIAL_USB_OHCI)) + { + unsigned long usb_base_addr = 0xFFFFFFFF; + PCI_RSC_DESC *pci_rsc_desc; +#ifdef PCI_XBIOS + pci_rsc_desc = (PCI_RSC_DESC *)get_resource(handle); /* USB OHCI */ +#else + pci_rsc_desc = (PCI_RSC_DESC *)Get_resource(handle); /* USB OHCI */ +#endif + if((long)pci_rsc_desc >= 0) + { + unsigned short flags; + do + { + if(!(pci_rsc_desc->flags & FLG_IO)) + { + if(usb_base_addr == 0xFFFFFFFF) + { + unsigned long base = pci_rsc_desc->offset + pci_rsc_desc->start; + usb_base_addr = pci_rsc_desc->start; + ehci_writel(base + OHCI_INTRDISABLE, OHCI_INTR_MIE); + } + } + flags = pci_rsc_desc->flags; + pci_rsc_desc = (PCI_RSC_DESC *)((unsigned long)pci_rsc_desc->next + (unsigned long)pci_rsc_desc); + } + while(!(flags & FLG_LAST)); + } + } + } + } + while(handle >= 0); + } +#endif /* !defined(COLDFIRE) && defined(CONFIG_USB_OHCI) && !defined(CONFIG_USB_INTERRUPT_POLLING) */ cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd |= CMD_RESET; ehci_writel(&gehci.hcor->or_usbcmd, cmd); @@ -421,7 +497,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz) td->qt_buffer[idx] = cpu_to_hc32(addr - gehci.dma_offset); next = (addr + 4096) & ~4095; delta = next - addr; - if (delta >= sz) + if(delta >= sz) break; sz -= delta; addr = next; @@ -678,12 +754,12 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *bu srclen = 4; break; case 1: /* Vendor */ - srcptr = "\16\3u\0-\0b\0o\0o\0t\0"; - srclen = 14; + srcptr = "\2\3"; + srclen = 2; break; case 2: /* Product */ - srcptr = "\52\3E\0H\0C\0I\0 \0H\0o\0s\0t\0 \0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0"; - srclen = 42; + srcptr = "\34\3E\0H\0C\0I\0 \0R\0o\0o\0t\0 \0H\0u\0b\0"; + srclen = 28; break; default: debug("unknown value DT_STRING %x\r\n", @@ -871,49 +947,22 @@ static int ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *bu return -1; } -#ifdef CONFIG_USB_INTERRUPT_POLLING -void ehci_usb_event_poll(int interrupt) +/* an interrupt happens */ +static int hc_interrupt(struct ehci *ehci) { - if(interrupt); -} -#else -void ehci_usb_enable_interrupt(int enable) -{ - if(enable); -} -#endif - -static int handle_usb_interrupt(struct ehci *ehci) -{ - uint32_t status; -#ifndef CONFIG_USB_MEM_NO_CACHE -#ifdef COLDFIRE /* no bus snooping on Coldfire */ -#ifdef NETWORK -#ifdef LWIP - extern unsigned long pxCurrentTCB, tid_TOS; - extern void flush_dc(void); - if(pxCurrentTCB != tid_TOS) - flush_dc(); - else -#endif /* LWIP */ -#endif /* NETWORK */ -#if (__GNUC__ > 3) - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ -#else - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5200\n\t"); /* from CF68KLIB */ -#endif -#endif /* COLDFIRE */ -#endif /* CONFIG_USB_MEM_NO_CACHE */ - status = ehci_readl(&ehci->hcor->or_usbsts); + uint32_t status = ehci_readl(&ehci->hcor->or_usbsts); if(status & STS_PCD) /* port change detect */ { uint32_t reg = ehci_readl(&ehci->hccr->cr_hcsparams); uint32_t i = HCS_N_PORTS(reg); - while(i--) + while(i) { uint32_t pstatus = ehci_readl(&ehci->hcor->or_portsc[i-1]); if(pstatus & EHCI_PS_PO) + { + i--; continue; + } if(companion & (1 << i)) { /* Low speed device, give up ownership. */ @@ -921,18 +970,42 @@ static int handle_usb_interrupt(struct ehci *ehci) ehci_writel(&ehci->hcor->or_portsc[i-1], pstatus); } #ifdef USB_POLL_HUB - else if((queue_poll_hub != NULL) && (pstatus & EHCI_PS_CSC)) + else if((queue_poll_hub != NULL) && (pstatus & EHCI_PS_CSC)) { portBASE_TYPE xNeedSwitch = pdFALSE; xNeedSwitch = xQueueSendFromISR(queue_poll_hub, &ehci->usbnum, xNeedSwitch); } /* to fix xNeedSwitch usage */ #endif + i--; } } ehci_writel(&ehci->hcor->or_usbsts, status); - return 1; /* clear interrupt, 0: disable interrupt */ + return(1); /* interrupt was from this card */ +} + +#ifdef CONFIG_USB_INTERRUPT_POLLING + +void ehci_usb_event_poll(int interrupt) +{ + if(interrupt); + if(ehci_inited && gehci.handle) + hc_interrupt(&gehci); } +#else /* !CONFIG_USB_INTERRUPT_POLLING */ + +void ehci_usb_enable_interrupt(int enable) +{ + if(enable); +} + +static int handle_usb_interrupt(struct ehci *ehci) +{ + return(hc_interrupt(ehci)); +} + +#endif /* CONFIG_USB_INTERRUPT_POLLING */ + static void hc_free_buffers(struct ehci *ehci) { int i; @@ -966,17 +1039,20 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** int i; uint32_t reg; uint32_t cmd; +#ifndef COLDFIRE + uint32_t tmp; +#endif unsigned long usb_base_addr = 0xFFFFFFFF; PCI_RSC_DESC *pci_rsc_desc; #ifdef PCI_XBIOS - pci_rsc_desc = (PCI_RSC_DESC *)get_resource(handle); /* USB OHCI */ + pci_rsc_desc = (PCI_RSC_DESC *)get_resource(handle); /* USB EHCI */ #else - COOKIE *p = get_cookie('_PCI'); + USB_COOKIE *p = usb_get_cookie('_PCI'); PCI_COOKIE *bios_cookie = (PCI_COOKIE *)p->v.l; if(bios_cookie == NULL) /* faster than XBIOS calls */ return(-1); tab_funcs_pci = &bios_cookie->routine[0]; - pci_rsc_desc = (PCI_RSC_DESC *)Get_resource(handle); /* USB OHCI */ + pci_rsc_desc = (PCI_RSC_DESC *)Get_resource(handle); /* USB EHCI */ #endif if(handle && (ent != NULL)) { @@ -1029,7 +1105,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** unsigned short flags; do { - debug("PCI USB descriptors: flags 0x%08x start 0x%08x \r\n offset 0x%08x dmaoffset 0x%08x length 0x%08x", + debug("PCI USB descriptors: flags 0x%04x start 0x%08lx \r\n offset 0x%08lx dmaoffset 0x%08lx length 0x%08lx", pci_rsc_desc->flags, pci_rsc_desc->start, pci_rsc_desc->offset, pci_rsc_desc->dmaoffset, pci_rsc_desc->length); if(!(pci_rsc_desc->flags & FLG_IO)) { @@ -1070,6 +1146,11 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** } gehci.hcor = (struct ehci_hcor *)((uint32_t)gehci.hccr + HC_LENGTH(ehci_readl(&gehci.hccr->cr_capbase))); kprint("EHCI usb-%s, regs address 0x%08X, PCI handle 0x%X\r\n", gehci.slot_name, gehci.hccr, handle); +#ifndef COLDFIRE + tmp = dma_lock(-1); /* CTPCI */ + if((tmp == 0) || (tmp == 1)) + gehci.ctpci_dma_lock = (void *)dma_lock(-2); /* function exist */ +#endif /* EHCI spec section 4.1 */ if(ehci_reset() != 0) { @@ -1110,6 +1191,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** wait_ms(5); reg = HC_VERSION(ehci_readl(&gehci.hccr->cr_capbase)); info("USB EHCI %x.%02x", reg >> 8, reg & 0xff); +#ifndef CONFIG_USB_INTERRUPT_POLLING /* turn on interrupts */ #ifdef PCI_XBIOS hook_interrupt(handle, handle_usb_interrupt, &gehci); @@ -1117,6 +1199,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** Hook_interrupt(handle, (void *)handle_usb_interrupt, (unsigned long *)&gehci); #endif /* PCI_BIOS */ ehci_writel(&gehci.hcor->or_usbintr, INTR_PCDE); +#endif /* CONFIG_USB_INTERRUPT_POLLING */ rootdev = 0; if(priv != NULL) *priv = (void *)&gehci; @@ -1130,6 +1213,7 @@ int ehci_usb_lowlevel_stop(void *priv) if(priv); if(!ehci_inited) return(0); +#ifndef CONFIG_USB_INTERRUPT_POLLING /* turn off interrupts */ ehci_writel(&gehci.hcor->or_usbintr, 0); #ifdef PCI_XBIOS @@ -1137,6 +1221,7 @@ int ehci_usb_lowlevel_stop(void *priv) #else Unhook_interrupt(gehci.handle); #endif /* PCI_BIOS */ +#endif /* CONFIG_USB_INTERRUPT_POLLING */ /* stop the controller */ cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd &= ~CMD_RUN; diff --git a/flash.tos/drivers/usb/ohci-hcd.c b/flash.tos/drivers/usb/ohci-hcd.c index 506cf50..e5b257b 100644 --- a/flash.tos/drivers/usb/ohci-hcd.c +++ b/flash.tos/drivers/usb/ohci-hcd.c @@ -49,13 +49,13 @@ #include "usb.h" #include "ohci.h" -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if (defined(COLDFIRE) && defined(LWIP)) || defined (FREERTOS) #include "../freertos/FreeRTOS.h" #include "../freertos/queue.h" extern xQueueHandle queue_poll_hub; -#define USB_POLL_HUB #endif +#undef DEBUG_PCIE #undef OHCI_USE_NPS /* force NoPowerSwitching mode */ @@ -65,8 +65,7 @@ extern xQueueHandle queue_poll_hub; #undef OHCI_FILL_TRACE /* For initializing controller (mask in an HCFS mode too) */ -#define OHCI_CONTROL_INIT \ - (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE +#define OHCI_CONTROL_INIT (OHCI_CTRL_CBSR & 0x3) | OHCI_CTRL_IE | OHCI_CTRL_PLE /* * e.g. PCI controllers need this @@ -79,8 +78,7 @@ extern xQueueHandle queue_poll_hub; # define writel(a, b) (*((volatile u32 *)(b)) = ((volatile u32)a)) #endif /* CONFIG_SYS_OHCI_SWAP_REG_ACCESS */ -#define min_t(type, x, y) \ - ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#define min_t(type, x, y) ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) struct pci_device_id ohci_usb_pci_table[] = { { PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5237, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_SERIAL_USB_OHCI, 0, 0 }, /* ULI1575 PCI OHCI module ids */ @@ -91,21 +89,13 @@ struct pci_device_id ohci_usb_pci_table[] = { }; #ifdef DEBUG -#define dbg(format, arg...) board_printf("DEBUG: " format "\r\n", ## arg) +#define dbg(format, arg...) do board_printf("DEBUG: " format "\r\n", ## arg) #else #define dbg(format, arg...) do {} while (0) #endif /* DEBUG */ -#if defined(DEBUG) || defined(USB_POLL_HUB) -#define err(format, arg...) sprintD(usb_error_str, "ERROR: " format "\r\n", ## arg); if(ohci->irq) board_printf(usb_error_str) -#else -#define err(format, arg...) sprintD(usb_error_str, "ERROR: " format "\r\n", ## arg); if(ohci->irq) kprint(usb_error_str) -#endif +#define err usb_error_msg #ifdef SHOW_INFO -#ifdef COLDFIRE -#define info(format, arg...) board_printf("INFO: " format "\r\n", ## arg) -#else -#define info(format, arg...) board_printf("INFO: " format "\r\n", ## arg) -#endif /* COLDFIRE */ +#define info(format, arg...) do board_printf("INFO: " format "\r\n", ## arg) #else #define info(format, arg...) do {} while (0) #endif @@ -113,18 +103,6 @@ struct pci_device_id ohci_usb_pci_table[] = { #define m16_swap(x) cpu_to_le16(x) #define m32_swap(x) cpu_to_le32(x) -typedef struct -{ - long ident; - union - { - long l; - short i[2]; - char c[4]; - } v; -} COOKIE; - -extern COOKIE *get_cookie(long id); extern void udelay(long usec); /* global ohci_t */ @@ -137,10 +115,11 @@ static inline u32 roothub_status(ohci_t *ohci) { return readl(&ohci->regs->rooth static inline u32 roothub_portstatus(ohci_t *ohci, int i) { return readl(&ohci->regs->roothub.portstatus[i]); } /* forward declaration */ +static void flush_data_cache(ohci_t *ohci); static int hc_interrupt(ohci_t *ohci); static void td_submit_job(ohci_t *ohci, struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, struct devrequest *setup, urb_priv_t *urb, int interval); - + /*-------------------------------------------------------------------------* * URB support functions *-------------------------------------------------------------------------*/ @@ -321,7 +300,8 @@ static void ohci_dump_roothub(ohci_t *controller, int verbose) { __u32 temp, ndp, i; temp = roothub_a(controller); - ndp = (temp & RH_A_NDP); +// ndp = (temp & RH_A_NDP); + ndp = controller->ndp; if(verbose) { dbg("roothub.a: %08x POTPGT=%d%s%s%s%s%s NDP=%d", temp, @@ -806,6 +786,20 @@ static void td_fill(ohci_t *ohci, unsigned int info, void *data, int len, td->hwNextTD = m32_swap((unsigned long)td_pt - ohci->dma_offset); /* append to queue */ td->ed->hwTailP = td->hwNextTD; +#if 0 + if(data) + { + int i; + board_printf("td_fill: %08x %08x %08X %08X at 0x%08X\r\n", + m32_swap(td->hwINFO), m32_swap(td->hwCBP), m32_swap(td->hwNextTD), m32_swap(td->hwBE), td); + for(i = 0; i < len; i++) + board_printf("%02X ", *(unsigned char *)(data + i) & 0xff); + board_printf("\r\n"); + } + else + board_printf("td_fill: %08x %08x %08X %08X at 0x%08X\r\n", + m32_swap(td->hwINFO), m32_swap(td->hwCBP), m32_swap(td->hwNextTD), m32_swap(td->hwBE), td); +#endif } /*-------------------------------------------------------------------------*/ @@ -1152,7 +1146,8 @@ int rh_check_port_status(ohci_t *controller) __u32 temp, ndp, i; int res = -1; temp = roothub_a(controller); - ndp = (temp & RH_A_NDP); +// ndp = (temp & RH_A_NDP); + ndp = controller->ndp; for(i = 0; i < ndp; i++) { temp = roothub_portstatus(controller, i); @@ -1307,7 +1302,8 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, unsigned lon __u32 temp = roothub_a(ohci); data_buf[0] = 9; /* min length; */ data_buf[1] = 0x29; - data_buf[2] = temp & RH_A_NDP; +// data_buf[2] = temp & RH_A_NDP; + data_buf[2] = (__u8)ohci->ndp; data_buf[3] = 0; if(temp & RH_A_PSM) /* per-port power switching? */ data_buf[3] |= 0x1; @@ -1416,26 +1412,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, unsigned long while(ohci->irq) { /* check whether the controller is done */ -#ifndef CONFIG_USB_MEM_NO_CACHE -#ifdef COLDFIRE /* no bus snooping on Coldfire */ -#ifdef NETWORK -#ifdef LWIP - extern unsigned long pxCurrentTCB, tid_TOS; - extern void flush_dc(void); - if(pxCurrentTCB != tid_TOS) - flush_dc(); - else -#endif /* LWIP */ -#endif /* NETWORK */ -#if (__GNUC__ > 3) - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ -#else - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5200\n\t"); /* from CF68KLIB */ -#endif -#else /* !COLDFIRE */ - asm volatile (" cpusha DC\n\t"); -#endif /* COLDFIRE */ -#endif /* CONFIG_USB_MEM_NO_CACHE */ + flush_data_cache(ohci); #ifndef CONFIG_USB_INTERRUPT_POLLING if(ohci->irq_enabled) stat = ohci->stat_irq; @@ -1560,11 +1537,11 @@ static int hc_reset(ohci_t *ohci) { unsigned long id = 0; #ifdef PCI_XBIOS - long err = read_config_longword(handle, PCIIDR, &id); + long error = read_config_longword(handle, PCIIDR, &id); #else - long err = Read_config_longword(handle, PCIIDR, &id); + long error = Read_config_longword(handle, PCIIDR, &id); #endif - if((err >= 0) && (PCI_VENDOR_ID_PHILIPS == (id & 0xFFFF)) + if((error >= 0) && (PCI_VENDOR_ID_PHILIPS == (id & 0xFFFF)) && (PCI_DEVICE_ID_PHILIPS_ISP1561_2 == (id >> 16))) { int timeout = 1000; @@ -1599,7 +1576,7 @@ static int hc_reset(ohci_t *ohci) } } flags = pci_rsc_desc->flags; - (unsigned long)pci_rsc_desc += (unsigned long)pci_rsc_desc->next; + pci_rsc_desc = (PCI_RSC_DESC *)((unsigned long)pci_rsc_desc->next + (unsigned long)pci_rsc_desc); } while(!(flags & FLG_LAST)); } @@ -1612,26 +1589,32 @@ static int hc_reset(ohci_t *ohci) && (ohci->ent->device == PCI_DEVICE_ID_NEC_USB)) { #ifdef MCF547X - dbg("USB OHCI set 48MHz clock\r\n"); + if(ohci->handle == 1) /* NEC on motherboard has FPGA clock */ + { + dbg("USB OHCI set 48MHz clock\r\n"); #ifdef PCI_XBIOS - write_config_longword(ohci->handle, 0xE4, 0x21); // oscillator & disable ehci + write_config_longword(ohci->handle, 0xE4, 0x21); // oscillator & disable ehci #else - Write_config_longword(ohci->handle, 0xE4, 0x21); // oscillator & disable ehci + Write_config_longword(ohci->handle, 0xE4, 0x21); // oscillator & disable ehci #endif -#else /* !MCF547X */ -#if 0 + wait_ms(10); + } + else +#endif /* !MCF547X */ + { #ifdef PCI_XBIOS - write_config_longword(ohci->handle, 0xE4, 0x01); // disable ehci + write_config_longword(ohci->handle, 0xE4, fast_read_config_longword(ohci->handle, 0xE4) | 0x01); // disable ehci #else - Write_config_longword(ohci->handle, 0xE4, 0x01); // disable ehci -#endif + Write_config_longword(ohci->handle, 0xE4, Fast_read_config_longword(ohci->handle, 0xE4) | 0x01); // disable ehci #endif -#endif /* MCF547X */ + wait_ms(10); + } } #else /* CONFIG_USB_EHCI */ #ifdef MCF547X if((ohci->controller == 0) && (ohci->ent->vendor == PCI_VENDOR_ID_NEC) - && (ohci->ent->device == PCI_DEVICE_ID_NEC_USB)) + && (ohci->ent->device == PCI_DEVICE_ID_NEC_USB) + && (ohci->handle == 1)) /* NEC on motherboard has FPGA clock */ { dbg("USB OHCI set 48MHz clock\r\n"); #ifdef PCI_XBIOS @@ -1639,6 +1622,7 @@ static int hc_reset(ohci_t *ohci) #else Write_config_longword(ohci->handle, 0xE4, 0x20); // oscillator #endif + wait_ms(10); } #endif /* MCF547X */ #endif /* CONFIG_USB_EHCI */ @@ -1659,12 +1643,13 @@ static int hc_reset(ohci_t *ohci) } /* Disable HC interrupts */ writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); - dbg("USB OHCI HC reset_hc usb-%s-%c: ctrl = 0x%X ;\r\n", ohci->slot_name, (char)ohci->controller + '0', readl(&ohci->regs->control)); + dbg("USB OHCI HC reset_hc usb-%s-%c: ctrl = 0x%X", ohci->slot_name, (char)ohci->controller + '0', readl(&ohci->regs->control)); /* Reset USB (needed by some controllers) */ ohci->hc_control = 0; writel(ohci->hc_control, &ohci->regs->control); + wait_ms(50); /* HC Reset requires max 10 us delay */ - writel(OHCI_HCR, &ohci->regs->cmdstatus); + writel(OHCI_HCR, &ohci->regs->cmdstatus); while((readl(&ohci->regs->cmdstatus) & OHCI_HCR) != 0) { if(--timeout == 0) @@ -1712,14 +1697,15 @@ static int hc_start(ohci_t *ohci) /* Choose the interrupts we care about now - but w/o MIE */ mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO; writel(mask, &ohci->regs->intrenable); + ohci->ndp = roothub_a(ohci); #ifdef OHCI_USE_NPS /* required for AMD-756 and some Mac platforms */ - writel((roothub_a(ohci) | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a); + writel((ohci->ndp | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a); writel(RH_HS_LPSC, &ohci->regs->roothub.status); #endif /* OHCI_USE_NPS */ -#define mdelay(n) ({unsigned long msec = (n); while (msec--) udelay(1000); }) /* POTPGT delay is bits 24-31, in 2 ms units. */ - mdelay((roothub_a(ohci) >> 23) & 0x1fe); + wait_ms((ohci->ndp >> 23) & 0x1fe); + ohci->ndp &= RH_A_NDP; /* connect the virtual root hub */ ohci->rh.devnum = 0; return 0; @@ -1727,44 +1713,53 @@ static int hc_start(ohci_t *ohci) /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_USB_INTERRUPT_POLLING - -/* Poll USB interrupt. */ -void ohci_usb_event_poll(int interrupt) +static void flush_data_cache(ohci_t *ohci) { - if(ohci_inited) - { - int i; #ifndef CONFIG_USB_MEM_NO_CACHE #ifdef COLDFIRE /* no bus snooping on Coldfire */ -#ifdef NETWORK #ifdef LWIP - extern unsigned long pxCurrentTCB, tid_TOS; - extern void flush_dc(void); - if(pxCurrentTCB != tid_TOS) - flush_dc(); - else + extern unsigned long pxCurrentTCB, tid_TOS; + extern void flush_dc(void); + if(pxCurrentTCB != tid_TOS) + flush_dc(); + else #endif /* LWIP */ -#endif /* NETWORK */ #if (__GNUC__ > 3) asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ #else asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5200\n\t"); /* from CF68KLIB */ #endif #else /* !COLDFIRE */ + if((unsigned long)ohci->hcca_unaligned < *ramtop) /* memory above ramtop is uncached memory */ asm volatile (" cpusha DC\n\t"); #endif /* COLDFIRE */ +#else + if(ohci); #endif /* CONFIG_USB_MEM_NO_CACHE */ +} + +#ifdef CONFIG_USB_INTERRUPT_POLLING + +/* Poll USB interrupt. */ +void ohci_usb_event_poll(int interrupt) +{ + if(ohci_inited) + { + int i; for(i = 0; i < (sizeof(gohci) / sizeof(ohci_t)); i++) { ohci_t *ohci = &gohci[i]; - if(!ohci->handle) + if(!ohci->handle || ohci->disabled) continue; - if(interrupt) - ohci->irq = 0; - hc_interrupt(ohci); - if(interrupt) - ohci->irq = -1; + else + { + flush_data_cache(ohci); + if(interrupt) + ohci->irq = 0; + hc_interrupt(ohci); + if(interrupt) + ohci->irq = -1; + } } } } @@ -1776,11 +1771,9 @@ static int hc_interrupt(ohci_t *ohci) { struct ohci_regs *regs = ohci->regs; int ints, stat = -1; -#if 0 if((ohci->hcca->done_head != 0) && !(m32_swap(ohci->hcca->done_head) & 0x01)) ints = OHCI_INTR_WDH; else -#endif { ints = readl(®s->intrstatus); if(ints == ~(u32)0) @@ -1874,22 +1867,9 @@ static int hc_interrupt(ohci_t *ohci) static int handle_usb_interrupt(ohci_t *ohci) { -#ifndef CONFIG_USB_MEM_NO_CACHE -#ifdef COLDFIRE /* no bus snooping on Coldfire */ -#if 1 -#if (__GNUC__ > 3) - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5485\n\t"); /* from CF68KLIB */ -#else - asm volatile (" .chip 68060\n\t cpusha DC\n\t .chip 5200\n\t"); /* from CF68KLIB */ -#endif -#else - extern void flush_dc(void); - flush_dc(); /* native interrupt */ -#endif -#else /* !COLDFIRE */ - asm volatile (" cpusha DC\n\t"); -#endif /* COLDFIRE */ -#endif /* CONFIG_USB_MEM_NO_CACHE */ + if(!ohci->irq_enabled) + return 0; + flush_data_cache(ohci); ohci->irq = 0; ohci->stat_irq = hc_interrupt(ohci); ohci->irq = -1; @@ -1960,7 +1940,7 @@ int ohci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** PCI_RSC_DESC *pci_rsc_desc = (PCI_RSC_DESC *)get_resource(handle); /* USB OHCI */ #else PCI_RSC_DESC *pci_rsc_desc; - COOKIE *p = get_cookie('_PCI'); + USB_COOKIE *p = usb_get_cookie('_PCI'); PCI_COOKIE *bios_cookie = (PCI_COOKIE *)p->v.l; if(bios_cookie == NULL) /* faster than XBIOS calls */ return(-1); @@ -1976,7 +1956,7 @@ int ohci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** else if(!ohci->handle) /* for restart USB cmd */ return(-1); info("ohci 0x%p", ohci); - ohci->controller = ohci->handle >> 16; /* PCI function */ + ohci->controller = (ohci->handle >> 16) & 3; /* PCI function */ /* this must be aligned to a 256 byte boundary */ ohci->hcca_unaligned = (struct ohci_hcca *)usb_malloc(sizeof(struct ohci_hcca) + 256); if(ohci->hcca_unaligned == NULL) @@ -2016,7 +1996,7 @@ int ohci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** unsigned short flags; do { - dbg("PCI USB descriptors: flags 0x%08x start 0x%08x \r\n offset 0x%08x dmaoffset 0x%08x length 0x%08x", + dbg("PCI USB descriptors: flags 0x%04x start 0x%08lx \r\n offset 0x%08lx dmaoffset 0x%08lx length 0x%08lx", pci_rsc_desc->flags, pci_rsc_desc->start, pci_rsc_desc->offset, pci_rsc_desc->dmaoffset, pci_rsc_desc->length); if(!(pci_rsc_desc->flags & FLG_IO)) { @@ -2077,9 +2057,6 @@ int ohci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void ** } #ifdef DEBUG ohci_dump(ohci, 1); -#else - if(ohci->irq) - wait_ms(1); #endif #ifndef CONFIG_USB_INTERRUPT_POLLING #ifdef PCI_XBIOS diff --git a/flash.tos/drivers/usb/ohci.h b/flash.tos/drivers/usb/ohci.h index 165325f..d6d79b3 100644 --- a/flash.tos/drivers/usb/ohci.h +++ b/flash.tos/drivers/usb/ohci.h @@ -432,6 +432,7 @@ typedef struct ohci { ed_t *ed_controltail; /* last endpoint of control list */ int intrstatus; __u32 hc_control; /* copy of the hc control reg */ + __u32 ndp; /* copy NDP from roothub_a */ struct virt_root_hub rh; const char *slot_name; diff --git a/flash.tos/drivers/usb/usb.c b/flash.tos/drivers/usb/usb.c index cf84b4b..bfd2450 100644 --- a/flash.tos/drivers/usb/usb.c +++ b/flash.tos/drivers/usb/usb.c @@ -45,15 +45,17 @@ * For each transfer (except "Interrupt") we wait for completion. */ +#include +#include #include "config.h" +#include "ct60.h" #include "usb.h" -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if (defined(COLDFIRE) && defined(LWIP)) || defined (FREERTOS) #include "../freertos/FreeRTOS.h" #include "../freertos/task.h" #include "../freertos/queue.h" #include "../freertos/semphr.h" -#define USB_POLL_HUB #ifdef CONFIG_USB_STORAGE extern int usb_stor_curr_dev; extern unsigned long usb_1st_disk_drive; @@ -88,12 +90,25 @@ static int dev_index[USB_MAX_BUS]; static struct hci *controller_priv[USB_MAX_BUS]; #ifdef USB_POLL_HUB xQueueHandle queue_poll_hub; +extern xTaskHandle pxCurrentTCB; #endif static int asynch_allowed; static struct devrequest *setup_packet; char usb_started; /* flag for the started/stopped USB status */ +char usb_error_str[256]; + +typedef struct +{ + int dest; + void (*func)(char); + char *loc; +} PRINTK_INFO; + +#define DEST_CONSOLE (1) +#define DEST_STRING (2) + /********************************************************************** * some forward declerations... */ @@ -103,15 +118,98 @@ int usb_hub_probe(struct usb_device *dev, int ifnum); void usb_hub_reset(int index_bus); static int hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat); +extern int printk(PRINTK_INFO *info, const char *fmt, va_list ap); + /*********************************************************************** * wait_ms */ -inline void wait_ms(unsigned long ms) +void wait_ms(unsigned long ms) { while(ms-- > 0) udelay(1000); } +/*********************************************************************** + * usb_get_cookie (without system call) + */ +USB_COOKIE *usb_get_cookie(long id) +{ + USB_COOKIE *p= *(USB_COOKIE **)0x5a0; + while(p) + { + if(p->ident == id) + return(p); + if(!p->ident) + return((USB_COOKIE *)0); + p++; + } + return((USB_COOKIE *)0); +} + +/*********************************************************************** + * usb_error_msg + */ +void usb_error_msg(const char *const fmt, ... ) +{ +#ifdef USB_POLL_HUB + extern xQueueHandle xQueueAlert; +#if !defined(COLDFIRE) && defined(FREERTOS) + extern xTaskHandle pxCurrentTCB, tid_TOS; + extern short video_found; +#endif +#endif /* USB_POLL_HUB */ + static char usb_str[256]; + char *msg; + va_list ap; + PRINTK_INFO info; + if(*fmt == '\r') /* trick for just a message */ + info.loc = msg = usb_str; + else /* error message */ + { + msg = usb_error_str; + strcpy(msg, "ERROR: "); + info.loc = &msg[strlen(msg)]; + } + info.dest = DEST_STRING; + va_start(ap, fmt); + printk(&info, fmt, ap); + *info.loc = '\0'; + va_end(ap); + strcat(msg, "\r\n"); +#if defined(DEBUG) || defined(USB_POLL_HUB) + if((*fmt != '\r') +#if !defined(COLDFIRE) && defined(FREERTOS) + && (pxCurrentTCB == tid_TOS) && !video_found +#endif + ) + board_printf(msg); +#else + if((*fmt != '\r') +#if !defined(COLDFIRE) && defined(FREERTOS) + && (pxCurrentTCB == tid_TOS) && !video_found +#endif + ) + kprint(usb_error_str); +#endif /* defined(DEBUG) || defined(USB_POLL_HUB) */ +#ifdef USB_POLL_HUB + if(strstr(msg, "CTL:TIMEOUT") == NULL) + { +#ifdef COLDFIRE + USB_COOKIE *p = usb_get_cookie('_CF_'); +#else + USB_COOKIE *p = usb_get_cookie(ID_CT60); +#endif + if((p != NULL) && (p->v.l > 0x10000)) + { + CT60_COOKIE *p2 = (CT60_COOKIE *)p->v.l; + p2->error_msg = msg; + } + if(xQueueAlert != NULL) + xQueueAltSend(xQueueAlert, (const void *)msg, 0); + } +#endif /* USB_POLL_HUB */ +} + /*************************************************************************** * Init USB Device */ @@ -155,7 +253,7 @@ int usb_init(long handle, const struct pci_device_id *ent) } usb_hub_reset(bus_index); /* init low_level USB */ - Cconws("USB: "); + kprint("USB: "); switch(ent->class) { #ifdef CONFIG_USB_UHCI @@ -186,7 +284,7 @@ int usb_init(long handle, const struct pci_device_id *ent) usb_started = 0; return -1; /* out of memoy */ } - Cconws("Scanning bus for devices... "); + kprint("Scanning bus for devices... "); controller_priv[bus_index] = (struct hci *)priv; controller_priv[bus_index]->usbnum = bus_index; usb_scan_devices(priv); @@ -196,7 +294,7 @@ int usb_init(long handle, const struct pci_device_id *ent) } else { - Cconws("Error, couldn't init Lowlevel part\r\n"); + kprint("Error, couldn't init Lowlevel part\r\n"); usb_started = 0; return -1; } @@ -1145,7 +1243,7 @@ void usb_scan_devices(void *priv) dev = usb_alloc_new_device(bus_index, priv); if(usb_new_device(dev)) { - Cconws("No USB Device found\r\n"); + kprint("No USB Device found\r\n"); USB_PRINTF("No USB Device found\r\n"); if(dev != NULL) dev_index[bus_index]--; @@ -1155,21 +1253,24 @@ void usb_scan_devices(void *priv) kprint("%d USB Device(s) found\r\n", dev_index[bus_index]); USB_PRINTF("%d USB Device(s) found\r\n", dev_index[bus_index]); } -#ifndef USB_POLL_HUB - /* insert "driver" if possible */ +#ifdef USB_POLL_HUB + if(pxCurrentTCB == NULL) +#endif + { + /* insert "driver" if possible */ #ifdef CONFIG_USB_KEYBOARD - if(drv_usb_kbd_init() < 0) - USB_PRINTF("No USB keyboard found\r\n"); - else - Cconws("USB HID keyboard driver installed\r\n"); + if(drv_usb_kbd_init() < 0) + USB_PRINTF("No USB keyboard found\r\n"); + else + kprint("USB HID keyboard driver installed\r\n"); #endif /* CONFIG_USB_KEYBOARD */ #ifdef CONFIG_USB_MOUSE - if(drv_usb_mouse_init() < 0) - USB_PRINTF("No USB mouse found\r\n"); - else - Cconws("USB HID mouse driver installed\r\n"); + if(drv_usb_mouse_init() < 0) + USB_PRINTF("No USB mouse found\r\n"); + else + kprint("USB HID mouse driver installed\r\n"); #endif /* CONFIG_USB_MOUSE */ -#endif + } USB_PRINTF("Scan end\r\n"); } @@ -1181,18 +1282,13 @@ void usb_scan_devices(void *priv) #undef USB_HUB_DEBUG #ifdef USB_HUB_DEBUG -#ifdef COLDFIRE #define USB_HUB_PRINTF(fmt, args...) board_printf(fmt , ##args) #else -#define USB_HUB_PRINTF(fmt, args...) board_printf(fmt , ##args); Crawcin() -#endif /* COLDFIRE */ -#else #define USB_HUB_PRINTF(fmt, args...) #endif static struct usb_hub_device hub_dev[USB_MAX_BUS][USB_MAX_HUB]; static int usb_hub_index[USB_MAX_BUS]; -char usb_error_str[256]; int usb_get_hub_descriptor(struct usb_device *dev, void *data, int size) { @@ -1280,10 +1376,11 @@ static int hub_port_reset(struct usb_device *dev, int port, unsigned short *port { usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET); #ifdef USB_POLL_HUB - vTaskDelay((200*configTICK_RATE_HZ)/1000); -#else - wait_ms(200); + if(pxCurrentTCB != NULL) + vTaskDelay((200*configTICK_RATE_HZ)/1000); + else #endif + wait_ms(200); if(usb_get_port_status(dev, port + 1, &portsts) < 0) { USB_HUB_PRINTF("get_port_status failed status %lX\r\n", dev->status); @@ -1299,10 +1396,11 @@ static int hub_port_reset(struct usb_device *dev, int port, unsigned short *port if(portstatus & USB_PORT_STAT_ENABLE) break; #ifdef USB_POLL_HUB - vTaskDelay((200*configTICK_RATE_HZ)/1000); -#else - wait_ms(200); + if(pxCurrentTCB != NULL) + vTaskDelay((200*configTICK_RATE_HZ)/1000); + else #endif + wait_ms(200); } if(tries == MAX_TRIES) { @@ -1342,21 +1440,23 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) return; } #ifdef USB_POLL_HUB - vTaskDelay((200*configTICK_RATE_HZ)/1000); -#else - wait_ms(200); + if(pxCurrentTCB != NULL) + vTaskDelay((200*configTICK_RATE_HZ)/1000); + else #endif + wait_ms(200); /* Reset the port */ if(hub_port_reset(dev, port, &portstatus) < 0) { - board_printf("USB %d cannot reset port %i!?\r\n", dev->usbnum, port + 1); + USB_HUB_PRINTF("USB %d cannot reset port %i!?\r\n", dev->usbnum, port + 1); return; } #ifdef USB_POLL_HUB - vTaskDelay((200*configTICK_RATE_HZ)/1000); -#else - wait_ms(200); + if(pxCurrentTCB != NULL) + vTaskDelay((200*configTICK_RATE_HZ)/1000); + else #endif + wait_ms(200); /* Allocate a new device struct for it */ usb = usb_alloc_new_device(dev->usbnum, dev->priv_hcd); if(portstatus & USB_PORT_STAT_HIGH_SPEED) @@ -1375,7 +1475,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE); } #ifdef USB_POLL_HUB - else + else if(pxCurrentTCB != NULL) { #ifdef CONFIG_USB_KEYBOARD usb_kbd_register(usb); @@ -1592,7 +1692,7 @@ int usb_hub_configure(struct usb_device *dev) USB_HUB_PRINTF("%sover-current condition exists\r\n", (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? "" : "no "); usb_hub_power_on(hub); #ifdef USB_POLL_HUB - if(queue_poll_hub == NULL) + if((queue_poll_hub == NULL) && (pxCurrentTCB != NULL)) { queue_poll_hub = xQueueCreate(64, sizeof(int)); if(queue_poll_hub != NULL) diff --git a/flash.tos/drivers/usb/usb.h b/flash.tos/drivers/usb/usb.h index 827e39f..6cb343a 100644 --- a/flash.tos/drivers/usb/usb.h +++ b/flash.tos/drivers/usb/usb.h @@ -28,6 +28,9 @@ #include #include +#ifndef ramtop +#define ramtop (((unsigned long *) 0x5A4L)) +#endif #include #include #include "pcixbios.h" @@ -69,7 +72,7 @@ extern long *tab_funcs_pci; extern void kprint(const char *fmt, ...); extern int sprintD(char *s, const char *fmt, ...); -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern void board_printf(const char *fmt, ...); #else #define board_printf kprint @@ -231,6 +234,17 @@ struct usb_device { int usbnum; }; +typedef struct +{ + long ident; + union + { + long l; + short i[2]; + char c[4]; + } v; +} USB_COOKIE; + /********************************************************************** * this is how the lowlevel part communicate with the outer world */ @@ -316,6 +330,8 @@ int usb_mem_init(void); void usb_mem_stop(void); /* routines */ +USB_COOKIE *usb_get_cookie(long id); +void usb_error_msg(const char *const fmt, ... ); int usb_init(long handle, const struct pci_device_id *ent); /* initialize the USB Controller */ int usb_stop(void); /* stop the USB Controller */ @@ -328,7 +344,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, void *data, int len, int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval); void usb_disable_asynch(int disable); int usb_maxpacket(struct usb_device *dev, unsigned long pipe); -inline void wait_ms(unsigned long ms); +void wait_ms(unsigned long ms); int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, int cfgno); int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size); int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size); @@ -336,6 +352,13 @@ int usb_clear_halt(struct usb_device *dev, int pipe); int usb_string(struct usb_device *dev, int index, char *buf, size_t size); int usb_set_interface(struct usb_device *dev, int interface, int alternate); +extern unsigned short swap_short(unsigned short val); +extern unsigned long swap_long(unsigned long val); + +#if 1 + #define __swap_16(x) swap_short(x) + #define __swap_32(x) swap_long(x) +#else /* big endian -> little endian conversion */ /* some CPUs are already little endian e.g. the ARM920T */ #define __swap_16(x) \ @@ -351,13 +374,11 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate); ((x_ & 0x00FF0000UL) >> 8) | \ ((x_ & 0xFF000000UL) >> 24)); \ }) +#endif #define swap_16(x) __swap_16(x) #define swap_32(x) __swap_32(x) -extern unsigned short swap_short(unsigned short val); -extern unsigned long swap_long(unsigned long val); - #define le16_to_cpu cpu_to_le16 #define le32_to_cpu cpu_to_le32 #define cpu_to_be32(a) a diff --git a/flash.tos/drivers/usb/usb_kbd.c b/flash.tos/drivers/usb/usb_kbd.c index 249a50b..4d16106 100644 --- a/flash.tos/drivers/usb/usb_kbd.c +++ b/flash.tos/drivers/usb/usb_kbd.c @@ -41,17 +41,6 @@ #define USB_KBD_PRINTF(fmt,args...) #endif -typedef struct -{ - long ident; - union - { - long l; - short i[2]; - char c[4]; - } v; -} COOKIE; - extern void ltoa(char *buf, long n, unsigned long base); extern void call_ikbdvec(unsigned char code, _IOREC *iorec, void (**ikbdvec)()); extern int asm_set_ipl(int level); @@ -165,7 +154,7 @@ static unsigned char usb_kbd_to_atari_scancode[] = // RET ESC BACK TAB SPACE -()) = [(^) 0x1C, 0x01, 0x0E, 0x0F, 0x39, 0x0C, 0x0D, 0x1A, // ]($) \(*) EUR1 ;(M) ' ` ,(;) .(:) - 0x1B, 0x2B, 0x00, 0x27, 0x28, 0x5B, 0x33, 0x34, + 0x1B, 0x2B, 0x2B, 0x27, 0x28, 0x5B, 0x33, 0x34, // /(!) CAPS F1 F2 F3 F4 F5 F6 0x35, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, // F7 F8 F9 F10 F11 F12 PrtSc ScLoc @@ -530,20 +519,6 @@ static unsigned char usb_kbd_to_atari_de_altgr[] = 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF }; -static COOKIE *get_cookie(long id) -{ - COOKIE *p= *(COOKIE **)0x5a0; - while(p) - { - if(p->ident == id) - return(p); - if(!p->ident) - return((COOKIE *)0); - p++; - } - return((COOKIE *)0); -} - static void *memscan(void *addr, int c, int size) { unsigned char *p = (unsigned char *)addr; @@ -670,7 +645,7 @@ static int usb_kbd_translate(unsigned char scancode, unsigned char modifier, int unsigned char *altgr_table = NULL; unsigned char *modifier_table = NULL; unsigned long lang = USA; - COOKIE *p = get_cookie('_AKP'); + USB_COOKIE *p = usb_get_cookie('_AKP'); if(p != NULL) lang = (p->v.l >> 8) & 0xFF; #ifdef USE_COUNTRYCODE diff --git a/flash.tos/drivers/usb/usb_mem.c b/flash.tos/drivers/usb/usb_mem.c index 4431b39..03acea9 100644 --- a/flash.tos/drivers/usb/usb_mem.c +++ b/flash.tos/drivers/usb/usb_mem.c @@ -45,6 +45,9 @@ static void *usb_buffer; extern int asm_set_ipl(int level); extern void *info_fvdi; extern long offscren_reserved(void); +#ifndef COLDFIRE +extern long get_no_cache_memory(void); +#endif /* MD - Memory Descriptor */ @@ -55,6 +58,7 @@ MD MD *m_link; long m_start; long m_length; + void *m_own; }; /* MPB - Memory Partition Block */ @@ -68,12 +72,32 @@ MPB MD *mp_rover; }; -#define MAXMD 100 +#define MAXMD 256 -static int count_md; static MD tab_md[MAXMD]; static MPB pmd; +static void *xmgetblk(void) +{ + int i; + for(i = 0; i < MAXMD; i++) + { + if(tab_md[i].m_own == NULL) + { + tab_md[i].m_own = (void*)1L; + return(&tab_md[i]); + } + } + return(NULL); +} + +static void xmfreblk(void *m) +{ + int i = (int)(((long)m - (long)tab_md) / sizeof(MD)); + if((i > 0) && (i < MAXMD)) + tab_md[i].m_own = NULL; +} + static MD *ffit(long amount, MPB *mp) { MD *p,*q,*p1; /* free list is composed of MD's */ @@ -87,7 +111,7 @@ static MD *ffit(long amount, MPB *mp) if((q = mp->mp_rover) == 0) /* get rotating pointer */ return(0) ; maxval = 0; - maxflg = (amount == -1 ? TRUE : FALSE) ; + maxflg = ((amount == -1) ? TRUE : FALSE) ; p = q->m_link; /* start with next MD */ do /* search the list for an MD with enough space */ { @@ -106,9 +130,9 @@ static MD *ffit(long amount, MPB *mp) { /* break it up - 1st allocate a new MD to describe the remainder */ - if(count_md >= MAXMD) - return(0); - p1 = &tab_md[count_md++]; + p1 = xmgetblk(); + if(p1 == NULL) + return(NULL); /* init new MD */ p1->m_length = p->m_length - amount; p1->m_start = p->m_start + amount; @@ -164,8 +188,7 @@ static void freeit(MD *m, MPB *mp) m->m_link = p->m_link; if(p == mp->mp_rover) mp->mp_rover = m; - if(count_md>=0) - count_md--; + xmfreblk(p); } } if(q) @@ -176,8 +199,7 @@ static void freeit(MD *m, MPB *mp) q->m_link = m->m_link; if(m == mp->mp_rover) mp->mp_rover = q; - if(count_md>=0) - count_md--; + xmfreblk(m); } } } @@ -210,6 +232,7 @@ int usb_free(void *addr) void *usb_malloc(long amount) { + void *ret = NULL; int level; MD *m; if(usb_buffer == NULL) @@ -222,11 +245,11 @@ void *usb_malloc(long amount) amount++; level = asm_set_ipl(7); m = ffit(amount, &pmd); + if(m != NULL) + ret = (void *)m->m_start; asm_set_ipl(level); - USB_MEM_PRINTF("usb_malloc(%d) = 0x%08X\r\n", amount, (m == NULL) ? 0 : m->m_start); - if(m == NULL) - return(NULL); - return((void *)m->m_start); + USB_MEM_PRINTF("usb_malloc(%d) = 0x%08X\r\n", amount, ret); + return(ret); } int usb_mem_init(void) @@ -240,11 +263,16 @@ int usb_mem_init(void) tab_md[0].m_start = (long)usb_buffer; tab_md[0].m_length = (long)__NO_CACHE_MEMORY_SIZE; #else /* !CONFIG_USB_MEM_NO_CACHE */ -#if 0 +#ifdef USE_RADEON_MEMORY usb_buffer = (void *)offscren_reserved(); if(usb_buffer == NULL) -#endif - usb_buffer = (void *)Mxalloc(USB_BUFFER_SIZE + 16, 0); /* STRAM - cache in writethough */ +#else +#ifndef COLDFIRE + usb_buffer = (void *)get_no_cache_memory(); + if(usb_buffer == NULL) +#endif +#endif + usb_buffer = (void *)Mxalloc(USB_BUFFER_SIZE + 16, 0); /* STRAM - cache in writethough */ if(usb_buffer == NULL) return(-1); pmd.mp_mfl = pmd.mp_rover = &tab_md[0]; @@ -252,16 +280,20 @@ int usb_mem_init(void) tab_md[0].m_start = ((long)usb_buffer + 15) & ~15; tab_md[0].m_length = USB_BUFFER_SIZE; #endif /* CONFIG_USB_MEM_NO_CACHE */ + tab_md[0].m_own = (void *)1L; pmd.mp_mal = (MD *)NULL; memset(usb_buffer, 0, tab_md[0].m_length); USB_MEM_PRINTF("USB malloc buffer at 0x%08X size %d\r\n", tab_md[0].m_start, tab_md[0].m_length); - count_md = 1; return(0); } void usb_mem_stop(void) { #ifndef CONFIG_USB_MEM_NO_CACHE +#ifdef USE_RADEON_MEMORY + if(usb_buffer == (void *)offscren_reserved()) + return; +#endif if(usb_buffer != NULL) Mfree(usb_buffer); #endif diff --git a/flash.tos/drivers/usb/usb_storage.c b/flash.tos/drivers/usb/usb_storage.c index 6200b73..645399d 100644 --- a/flash.tos/drivers/usb/usb_storage.c +++ b/flash.tos/drivers/usb/usb_storage.c @@ -67,7 +67,7 @@ #endif extern void udelay(long usec); -extern long install_usb_stor(int dev_num, unsigned long part_type, unsigned long part_offset, unsigned long part_size, char *vendor, char *revision, char *product); +extern long install_usb_stor(int dev_num, unsigned long part_type, unsigned long part_offset, unsigned long part_size, char *vendor, char *revision, char *product, unsigned long number_of_blocks, unsigned long block_size); extern void uninstall_usb_stor(int dev_num); /* direction table -- this indicates the direction of the data @@ -469,7 +469,8 @@ int usb_stor_scan(void) usb_stor_register(dev); } /* for */ } /* for */ - board_printf("%d Storage Device(s) found\r\n", usb_max_devs); + if(usb_max_devs) + board_printf("%d Storage Device(s) found\r\n\n", usb_max_devs); if(usb_max_devs > 0) return 0; return -1; @@ -519,12 +520,33 @@ int usb_stor_register(struct usb_device *dev) { int part_num = 1; unsigned long part_type, part_offset, part_size; + long drive; +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) + extern unsigned long pxCurrentTCB, tid_TOS; + char msg[256]; + int first = 1; + sprintD(msg, "\rUSB MASS STORAGE %s %s detection, disk(s) ", dev->mf /* stor_dev->vendor */, dev->prod /* stor_dev->product */); +#endif /* (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) */ while(!fat_register_device(stor_dev, part_num, &part_type, &part_offset, &part_size)) { USB_STOR_PRINTF("USB STORAGE install partition dev: %d\r\n", usb_max_devs); - install_usb_stor(usb_max_devs, part_type, part_offset, part_size, stor_dev->vendor, stor_dev->revision, stor_dev->product); + drive = install_usb_stor(usb_max_devs, part_type, part_offset, part_size, dev->mf /* stor_dev->vendor */, stor_dev->revision, dev->prod /* stor_dev->product */, (unsigned long)stor_dev->lba, stor_dev->blksz); +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) + if(drive) + { + if(first) + first = 0; + else + strcat(msg, ", "); + sprintD(&msg[strlen(msg)], "%c (type %02X, %d MB)", (char)drive + 'A', part_type, (part_size + 1023) >> 11); + } +#endif /* (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) */ part_num++; } +#if (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) + if(pxCurrentTCB != tid_TOS) + usb_error_msg(msg); +#endif /* (defined(COLDFIRE) && defined(LWIP)) || defined(FREERTOS) */ } usb_max_devs++; dev->deregister = usb_stor_deregister; @@ -1328,6 +1350,40 @@ long usb_stor_read(int device, unsigned long blknr, unsigned long blkcnt, void * usb_disable_asynch(0); /* asynch transfer allowed */ return -2; } +#if 0 // #ifndef COLDFIRE + if(buf_addr < 0x1000000) /* ST-RAM */ + { + USB_STOR_PRINTF("usb_read: dev %d startblk %lx, blccnt %lx buffer %lx\r\n", device, start, blks, buf_addr); + do + { + /* XXX need some comment here */ + retry = 2; + if(blks > USB_MAX_READ_BLK) + smallblks = USB_MAX_READ_BLK; + else + smallblks = (unsigned short)blks; +retry_it_bis: + srb->datalen = usb_dev_desc[device].blksz * smallblks; + srb->pdata = (unsigned char *)buf_addr; + if(usb_read_10(srb, (struct us_data *)dev->privptr, start, smallblks)) + { + USB_STOR_PRINTF("Read ERROR\r\n"); + usb_request_sense(srb, (struct us_data *)dev->privptr); + if(retry--) + goto retry_it_bis; + blkcnt -= blks; + break; + } + start += smallblks; + blks -= smallblks; + buf_addr += srb->datalen; + } + while(blks != 0); + USB_STOR_PRINTF("usb_read: end startblk %lx, blccnt %x buffer %lx\r\n", start, smallblks, buf_addr); + usb_disable_asynch(0); /* asynch transfer allowed */ + return blkcnt; + } +#endif /* COLDFIRE */ tmp_buf = (unsigned char *)usb_malloc(USB_MAX_READ_BLK * usb_dev_desc[device].blksz); if(tmp_buf == NULL) { @@ -1409,6 +1465,40 @@ long usb_stor_write(int device, unsigned long blknr, unsigned long blkcnt, const usb_disable_asynch(0); /* asynch transfer allowed */ return -2; } +#if 0 // #ifndef COLDFIRE + if(buf_addr < 0x1000000) /* ST-RAM */ + { + USB_STOR_PRINTF("usb_write: dev %d startblk %lx, blccnt %lx buffer %lx\r\n", device, start, blks, buf_addr); + do + { + /* XXX need some comment here */ + retry = 2; + if(blks > USB_MAX_READ_BLK) + smallblks = USB_MAX_READ_BLK; + else + smallblks = (unsigned short)blks; +retry_it_bis: + srb->datalen = usb_dev_desc[device].blksz * smallblks; + srb->pdata = (unsigned char *)buf_addr; + if(usb_write_10(srb, (struct us_data *)dev->privptr, start, smallblks)) + { + USB_STOR_PRINTF("Write ERROR\r\n"); + usb_request_sense(srb, (struct us_data *)dev->privptr); + if(retry--) + goto retry_it_bis; + blkcnt -= blks; + break; + } + start += smallblks; + blks -= smallblks; + buf_addr += srb->datalen; + } + while(blks != 0); + USB_STOR_PRINTF("usb_write: end startblk %lx, blccnt %x buffer %lx\r\n", start, smallblks, buf_addr); + usb_disable_asynch(0); /* asynch transfer allowed */ + return blkcnt; + } +#endif /* COLDFIRE */ tmp_buf = (unsigned char *)usb_malloc(USB_MAX_READ_BLK * usb_dev_desc[device].blksz); if(tmp_buf == NULL) { diff --git a/flash.tos/drivers/usb_dev/msc.c b/flash.tos/drivers/usb_dev/msc.c index 4c589ef..e4b6971 100644 --- a/flash.tos/drivers/usb_dev/msc.c +++ b/flash.tos/drivers/usb_dev/msc.c @@ -7,7 +7,6 @@ #include "msc.h" #ifdef USB_DEVICE -#ifdef NETWORK #ifdef LWIP #undef DEBUG @@ -873,5 +872,4 @@ void usb_fifo_event(uint32 epnum, uint8 event) } #endif /* LWIP */ -#endif /* NETWORK */ #endif /* USB_DEVICE */ diff --git a/flash.tos/drivers/usb_dev/msc_desc.c b/flash.tos/drivers/usb_dev/msc_desc.c index 8b9a2d0..b6ead1c 100644 --- a/flash.tos/drivers/usb_dev/msc_desc.c +++ b/flash.tos/drivers/usb_dev/msc_desc.c @@ -7,7 +7,6 @@ #include "msc.h" #ifdef USB_DEVICE -#ifdef NETWORK #ifdef LWIP /* Structure for Mass Storage Interface Type */ @@ -313,5 +312,4 @@ uint32 usb_get_desc_size(void) } #endif /* LWIP */ -#endif /* NETWORK */ #endif /* USB_DEVICE */ diff --git a/flash.tos/drivers/usb_dev/usb.c b/flash.tos/drivers/usb_dev/usb.c index 598086f..fdd0b1f 100644 --- a/flash.tos/drivers/usb_dev/usb.c +++ b/flash.tos/drivers/usb_dev/usb.c @@ -6,7 +6,6 @@ #include "usb.h" #ifdef USB_DEVICE -#ifdef NETWORK #ifdef LWIP /* Global Endpoint Status Structures */ @@ -1940,5 +1939,4 @@ void usb_sendZLP(uint32 epnum) } #endif /* LWIP */ -#endif /* NETWORK */ #endif /* USB_DEVICE */ diff --git a/flash.tos/drivers/video/accel.c b/flash.tos/drivers/video/accel.c index c6e6306..4f42a0f 100644 --- a/flash.tos/drivers/video/accel.c +++ b/flash.tos/drivers/video/accel.c @@ -201,7 +201,7 @@ static int check_table(short *table, int length) #ifdef DRIVER_IN_ROM #ifdef COLDFIRE -#ifndef NETWORK +#ifndef LWIP inline int dma_transfer(char *src, char *dest, int size, int width, int src_incr, int dest_incr, int step) { @@ -211,7 +211,7 @@ inline int dma_transfer(char *src, char *dest, int size, int width, int src_incr inline int dma_status(void) { return(-1); } inline void wait_dma(void) { } -#endif /* NETWORK */ +#endif /* LWIP */ #endif /* COLDFIRE */ #endif /* DRIVER_IN_ROM */ @@ -1567,7 +1567,7 @@ long CDECL c_write_pixel_1(Virtual *vwk, MFDB *dst, long x, long y, long color) if(!dst || !dst->address || (dst->address == wk->screen.mfdb.address)) { offset = ((long)wk->screen.wrap * y) + x; - p = (unsigned short *)((unsigned long)wk->screen.mfdb.address + (unsigned long)offset); + p = (short *)((unsigned long)wk->screen.mfdb.address + (unsigned long)offset); if(color) *p |= mask; else @@ -1576,7 +1576,7 @@ long CDECL c_write_pixel_1(Virtual *vwk, MFDB *dst, long x, long y, long color) else { offset = ((dst->wdwidth * 2 * dst->bitplanes) * y) + x; - p = (unsigned short *)((unsigned long)dst->address + (unsigned long)offset); + p = (short *)((unsigned long)dst->address + (unsigned long)offset); if(color) *p |= mask; else @@ -1928,7 +1928,7 @@ long CDECL c_expand_area(Virtual *vwk, MFDB *src, long src_x, long src_y, MFDB * { #ifndef COLDFIRE case 1: - replace_1(src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); + replace_1((void *)src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); break; #endif case 16: @@ -1947,7 +1947,7 @@ long CDECL c_expand_area(Virtual *vwk, MFDB *src, long src_x, long src_y, MFDB * { #ifndef COLDFIRE case 1: - transparent_1(src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); + transparent_1((void *)src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); break; #endif case 16: @@ -1966,7 +1966,7 @@ long CDECL c_expand_area(Virtual *vwk, MFDB *src, long src_x, long src_y, MFDB * { #ifndef COLDFIRE case 1: - xor_1(src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); + xor_1((void *)src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); break; #endif case 16: @@ -1985,7 +1985,7 @@ long CDECL c_expand_area(Virtual *vwk, MFDB *src, long src_x, long src_y, MFDB * { #ifndef COLDFIRE case 1: - revtransp_1(src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); + revtransp_1((void *)src_addr,src_line_add,dst_addr,dst_line_add,src_x,dst_x,w,h,(unsigned char)foreground,(unsigned char)background); break; #endif case 16: diff --git a/flash.tos/drivers/video/blitter.c b/flash.tos/drivers/video/blitter.c index 9c23bd9..5f7d260 100644 --- a/flash.tos/drivers/video/blitter.c +++ b/flash.tos/drivers/video/blitter.c @@ -36,7 +36,7 @@ #define LINE_NUM *(volatile char *)0xFFFF8A3C // Line Number Register #define SKEW *(volatile char *)0xFFFF8A3D // SKEW Register -#if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ +#if 0 // #if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ void blitter_copy(unsigned char *src_addr, int src_line_add, unsigned char *dst_addr, int dst_line_add, int w, int h, int bpp, int op, int backward) { diff --git a/flash.tos/drivers/video/offscreen.c b/flash.tos/drivers/video/offscreen.c index 1bb7df1..205ca3e 100644 --- a/flash.tos/drivers/video/offscreen.c +++ b/flash.tos/drivers/video/offscreen.c @@ -34,6 +34,7 @@ MD MD *m_link; long m_start; long m_length; + void *m_own; }; /* MPB - Memory Partition Block */ @@ -47,13 +48,33 @@ MPB MD *mp_rover; }; -#define MAXMD 100 +#define MAXMD 256 -static int count_md; static MD tab_md[MAXMD]; static MPB pmd; static long wrap; +static void *xmgetblk(void) +{ + int i; + for(i = 0; i < MAXMD; i++) + { + if(tab_md[i].m_own == NULL) + { + tab_md[i].m_own = (void*)1L; + return(&tab_md[i]); + } + } + return(NULL); +} + +static void xmfreblk(void *m) +{ + int i = (int)(((long)m - (long)tab_md) / sizeof(MD)); + if((i > 0) && (i < MAXMD)) + tab_md[i].m_own = NULL; +} + static MD *ffit(long amount, MPB *mp) { MD *p,*q,*p1; /* free list is composed of MD's */ @@ -73,11 +94,11 @@ static MD *ffit(long amount, MPB *mp) if((q = mp->mp_rover) == 0) /* get rotating pointer */ return(0) ; maxval = 0; - maxflg = (amount == -1 ? TRUE : FALSE) ; + maxflg = ((amount == -1) ? TRUE : FALSE) ; p = q->m_link; /* start with next MD */ do /* search the list for an MD with enough space */ { - if(p == 0) + if(p == NULL) { /* at end of list, wrap back to start */ q = (MD *) &mp->mp_mfl; /* q => mfl field */ @@ -92,9 +113,9 @@ static MD *ffit(long amount, MPB *mp) { /* break it up - 1st allocate a new MD to describe the remainder */ - if(count_md >= MAXMD) - return(0); - p1 = &tab_md[count_md++]; + p1 = xmgetblk(); + if(p1 == NULL) + return(NULL); /* init new MD */ p1->m_length = p->m_length - amount; p1->m_start = p->m_start + amount; @@ -129,7 +150,7 @@ static MD *ffit(long amount, MPB *mp) static void freeit(MD *m, MPB *mp) { MD *p, *q; - q = 0; + q = NULL; for(p = mp->mp_mfl; p ; p = (q=p) -> m_link) { if(m->m_start <= p->m_start) @@ -150,8 +171,7 @@ static void freeit(MD *m, MPB *mp) m->m_link = p->m_link; if(p == mp->mp_rover) mp->mp_rover = m; - if(count_md>=0) - count_md--; + xmfreblk(p); } } if(q) @@ -162,8 +182,7 @@ static void freeit(MD *m, MPB *mp) q->m_link = m->m_link; if(m == mp->mp_rover) mp->mp_rover = q; - if(count_md>=0) - count_md--; + xmfreblk(m); } } } @@ -243,7 +262,8 @@ long offscreen_alloc(struct fb_info *info, long amount) long offscren_reserved(void) { - return(tab_md[0].m_start + tab_md[0].m_length); + extern struct fb_info *info_fvdi; + return((long)info_fvdi->ram_base + (long)info_fvdi->ram_size - USB_BUFFER_SIZE); } void offscreen_init(struct fb_info *info) @@ -260,8 +280,7 @@ void offscreen_init(struct fb_info *info) tab_md[0].m_link = (MD *)NULL; tab_md[0].m_start = (long)((unsigned long)info->ram_base + (unsigned long)size_screen); tab_md[0].m_length = (long)info->ram_size - size_screen; - if(tab_md[0].m_length > USB_BUFFER_SIZE) - tab_md[0].m_length -= USB_BUFFER_SIZE; + tab_md[0].m_own = (void *)1L; max_offscreen_size = ((long)info->var.xres_virtual * 8192L * (long)(info->var.bits_per_pixel / 8)) - size_screen; if(max_offscreen_size < 0) max_offscreen_size = 0; @@ -280,6 +299,5 @@ void offscreen_init(struct fb_info *info) Funcs_puts("\r\n"); #endif pmd.mp_mal = (MD *)NULL; - count_md = 1; } diff --git a/flash.tos/drivers/video/videl.c b/flash.tos/drivers/video/videl.c index 676c2c3..96c1598 100644 --- a/flash.tos/drivers/video/videl.c +++ b/flash.tos/drivers/video/videl.c @@ -27,7 +27,7 @@ #include "../../include/fire.h" #endif -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) extern void board_printf(const char *fmt, ...); #endif @@ -108,31 +108,33 @@ struct videl_table { /* Videl native VGA modes */ static struct videl_table table_rez[] = { +#if 0 { 320, 200, 60, 25, 4, FLAGS_ST_MODES, 0x017, 0x012, 0x001, 0x20E, 0x00D, 0x011, 0x419, 0x3AF, 0x08F, 0x08F, 0x3AF, 0x415, 5, 0x186 }, // ST-LOW 25 MHz { 640, 200, 60, 25, 2, FLAGS_ST_MODES, 0x017, 0x012, 0x001, 0x20E, 0x00D, 0x011, 0x419, 0x3AF, 0x08F, 0x08F, 0x3AF, 0x415, 9, 0x186 }, // ST-MED 25 MHz { 640, 400, 60, 25, 1, FLAGS_ST_MODES, 0x0C6, 0x08D, 0x015, 0x273, 0x050, 0x096, 0x419, 0x3AF, 0x08F, 0x08F, 0x3AF, 0x415, 8, 0x186 }, // ST-HIG 25 MHz - { 640, 240, 60, 25, 1, 0, 0x0C6, 0x08D, 0x015, 0x273, 0x050, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz { 320, 240, 60, 25, 2, 0, 0x017, 0x012, 0x001, 0x20A, 0x009, 0x011, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 5, 0x186 }, // 25 MHz - { 640, 240, 60, 25, 2, 0, 0x017, 0x012, 0x001, 0x20E, 0x00D, 0x011, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz { 320, 240, 60, 25, 4, 0, 0x0C6, 0x08D, 0x015, 0x28A, 0x06B, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 5, 0x186 }, // 25 MHz - { 640, 240, 60, 25, 4, 0, 0x0C6, 0x08D, 0x015, 0x2A3, 0x07C, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz { 320, 240, 60, 25, 8, 0, 0x0C6, 0x08D, 0x015, 0x29A, 0x07B, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 5, 0x186 }, // 25 MHz - { 640, 240, 60, 25, 8, 0, 0x0C6, 0x08D, 0x015, 0x2AB, 0x084, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz { 320, 240, 60, 25, 16, 0, 0x0C6, 0x08D, 0x015, 0x2AC, 0x091, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 5, 0x186 }, // 25 MHz + { 320, 480, 60, 25, 2, 0, 0x017, 0x012, 0x001, 0x20A, 0x009, 0x011, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz + { 320, 480, 60, 25, 4, 0, 0x0C6, 0x08D, 0x015, 0x28A, 0x06B, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz + { 320, 480, 60, 25, 8, 0, 0x0C6, 0x08D, 0x015, 0x29A, 0x07B, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz + { 320, 480, 60, 25, 16, 0, 0x0C6, 0x08D, 0x015, 0x2AC, 0x091, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz + { 640, 240, 60, 25, 1, 0, 0x0C6, 0x08D, 0x015, 0x273, 0x050, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz + { 640, 240, 60, 25, 2, 0, 0x017, 0x012, 0x001, 0x20E, 0x00D, 0x011, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz + { 640, 240, 60, 25, 4, 0, 0x0C6, 0x08D, 0x015, 0x2A3, 0x07C, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz + { 640, 240, 60, 25, 8, 0, 0x0C6, 0x08D, 0x015, 0x2AB, 0x084, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz { 640, 240, 60, 25, 16, 0, 0x0C6, 0x08D, 0x015, 0x2AC, 0x091, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 9, 0x186 }, // 25 MHz { 640, 480, 60, 25, 1, 0, 0x0C6, 0x08D, 0x015, 0x273, 0x050, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 8, 0x186 }, // 25 MHz - { 320, 480, 60, 25, 2, 0, 0x017, 0x012, 0x001, 0x20A, 0x009, 0x011, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz { 640, 480, 60, 25, 2, 0, 0x017, 0x012, 0x001, 0x20E, 0x00D, 0x011, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 8, 0x186 }, // 25 MHz - { 320, 480, 60, 25, 4, 0, 0x0C6, 0x08D, 0x015, 0x28A, 0x06B, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz +#endif { 640, 480, 60, 25, 4, 0, 0x0C6, 0x08D, 0x015, 0x2A3, 0x07C, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 8, 0x186 }, // 25 MHz - { 320, 480, 60, 25, 8, 0, 0x0C6, 0x08D, 0x015, 0x29A, 0x07B, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz { 640, 480, 60, 25, 8, 0, 0x0C6, 0x08D, 0x015, 0x2AB, 0x084, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 8, 0x186 }, // 25 MHz - { 320, 480, 60, 25, 16, 0, 0x0C6, 0x08D, 0x015, 0x2AC, 0x091, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x186 }, // 25 MHz { 640, 480, 60, 25, 16, 0, 0x0C6, 0x08D, 0x015, 0x2AC, 0x091, 0x096, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 8, 0x186 }, // 25 MHz // { 640, 480, 60, 50, 16, 0, 0x189, 0x126, 0x031, 0x000, 0x160, 0x135, 0x419, 0x3FF, 0x03F, 0x03F, 0x3FF, 0x415, 4, 0x182 }, // 50 MHz -#if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ -// { 1280, 1024, 60, 137, 16, FLAGS_ACP_MODES, 1800, 1380, 99, 100, 1379, 1500, 1150, 1074, 49, 50, 1073, 1100, 0, 0 }, // 137 MHz -// { 1280, 1024, 60, 137, 32, FLAGS_ACP_MODES, 1800, 1380, 99, 100, 1379, 1500, 1150, 1074, 49, 50, 1073, 1100, 0, 0 } // 137 MHz +#if 0 // #if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ + { 1280, 1024, 60, 137, 16, FLAGS_ACP_MODES, 1800, 1380, 99, 100, 1379, 1500, 1150, 1074, 49, 50, 1073, 1100, 0, 0 }, // 137 MHz + { 1280, 1024, 60, 137, 32, FLAGS_ACP_MODES, 1800, 1380, 99, 100, 1379, 1500, 1150, 1074, 49, 50, 1073, 1100, 0, 0 } // 137 MHz #endif }; @@ -400,7 +402,7 @@ static struct fb_videomode *find_mode(long width, long height, long clock, long continue; if(db->vmode & (FB_VMODE_DOUBLE | FB_VMODE_INTERLACED)) continue; -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) // board_printf(" %dx%d@%d %dMHz i:%d j:%d k:%d\r\n", db->xres, db->yres, db->refresh, (int)(PICOS2KHZ(db->pixclock)/1000), i, j, k); #endif if(i) // second loop @@ -435,7 +437,7 @@ static struct fb_videomode *find_mode(long width, long height, long clock, long diff = abs; best_db = db; } -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) // board_printf(" ref:%d abs:%d diff:%d best:%08X j:%d k:%d\r\n", db->refresh, abs, diff, best_db, j, k); #endif } @@ -455,7 +457,7 @@ static struct fb_videomode *find_mode(long width, long height, long clock, long } if(best_db == NULL) return(NULL); -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) // board_printf(" best:%08X\r\n", best_db); #endif return(best_db); @@ -769,13 +771,13 @@ void init_videl_i2c(void) I2CsendByte(0xBF, TFP410_CTL1_MODE, TFP_ADDR); /* ctl1: power on, T:M:D:S: enable */ if((data = I2CreceiveByte(TFP410_CTL1_MODE, TFP_ADDR)) != 0xBF) { -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) board_printf("init_videl TFP410 failure ctl1 write 0xBF => read 0x%02X\r\n", data); } else { board_printf("init_videl TFP410 OK\r\n"); -#endif /* defined(NETWORK) && defined(LWIP) && defined(DEBUG) */ +#endif /* defined(LWIP) && defined(DEBUG) */ } #ifdef CONFIG_FB_MODE_HELPERS if(I2CreceiveByte(8, DCC_ADDR) || I2CreceiveByte(9, DCC_ADDR)) /* Manufactor ID */ @@ -789,7 +791,7 @@ void init_videl_i2c(void) else videl_monitor_type = MT_CRT; } -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) else board_printf("init_videl EDID read failure\r\n"); #endif @@ -843,7 +845,7 @@ long init_videl(long width, long height, long bpp, long refresh, long extended) if((width > 640) || (height > 480) || (bpp > 16)) return(0); #endif -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) #if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ board_printf("init_videl search in videl list %dx%dx%d@%dHz on %s\r\n", (int)width, (int)height, (int)bpp, (int)refresh, (videl_monitor_type == MT_DFP) ? "DFP" : "CRT"); #else @@ -853,7 +855,7 @@ long init_videl(long width, long height, long bpp, long refresh, long extended) #if defined(COLDFIRE) && defined(MCF547X) if(acp_new_hardware()) acp_has_pll = 1; -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) board_printf("init_videl PLL%s detected\r\n", acp_has_pll ? "" : " not"); #endif if(!extended) @@ -906,7 +908,7 @@ long init_videl(long width, long height, long bpp, long refresh, long extended) if((db = find_mode(width, height, 0, refresh)) != NULL) { long clock = PICOS2KHZ(db->pixclock)/1000; -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) board_printf("init_videl found in modedb list %dx%dx%d with clock %dMHz\r\n", (int)width, (int)height, (int)bpp, (int)clock); #endif unsigned long hfreq, vfreq, htotal, vtotal, pixclock; @@ -989,7 +991,7 @@ long init_videl(long width, long height, long bpp, long refresh, long extended) for(x = 0; x < (sizeof(video_control) / sizeof(struct acp_table)); x++) { long clock = video_control[x].clock; -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) if(loop) board_printf("init_videl search in modedb list %dx%dx%d with clock %dMHz +/- 5MHz\r\n", (int)width, (int)height, (int)bpp, (int)clock); else @@ -1120,7 +1122,7 @@ long init_videl(long width, long height, long bpp, long refresh, long extended) } #endif *((char **)_v_bas_ad) = (char *)addr; -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) +#if defined(LWIP) && defined(DEBUG) #if defined(COLDFIRE) && defined(MCF547X) if(db != NULL) board_printf("init_videl %dx%dx%d@%dHz %dMHz %s %s\r\n", (int)width, (int)height, (int)bpp, (int)videl_rez->frq, (int)videl_rez->clk, @@ -1215,7 +1217,7 @@ long init_videl(long width, long height, long bpp, long refresh, long extended) break; } asm_set_ipl(level); // restore interrupts -#if defined(NETWORK) && defined(LWIP) && defined(DEBUG) && defined(COLDFIRE) && defined(MCF547X) +#if defined(LWIP) && defined(DEBUG) && defined(COLDFIRE) && defined(MCF547X) board_printf(" ACP_VIDEO_CONTROL:%08X (%08X)\r\n", *(volatile unsigned long *)ACP_VIDEO_CONTROL, acp_video_control); #endif #endif /* defined(COLDFIRE) && defined(MCF547X) */ diff --git a/flash.tos/drivers/videocnf.c b/flash.tos/drivers/videocnf.c index 6a491ba..71744bb 100644 --- a/flash.tos/drivers/videocnf.c +++ b/flash.tos/drivers/videocnf.c @@ -275,7 +275,7 @@ extern long total_modedb; OBJECT *rs_object, *rs_object_menu, *rs_object_menu2; TEDINFO *rs_tedinfo; char **rs_strings; -LISTE_RES liste_rez[MAX_RES]; +LISTE_RES *liste_rez; int offset_select, nb_res, sel_color, type_modes; #if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ extern unsigned long videl_modedb_len; @@ -311,11 +311,18 @@ short set_video(void) if(!video_found && (Physbase() < (void *)0x01000000)) return(-1); vdi_handle = graf_handle(&gr_hwchar, &gr_hhchar, &gr_hwbox, &gr_hhbox); + liste_rez = (LISTE_RES *)Mxalloc(sizeof(LISTE_RES) * MAX_RES, 3); + if(liste_rez == NULL) + return(0); if(!init_rsc()) + { + Mfree(liste_rez); return(0); + } v_opnvwk(work_in, &vdi_handle, work_out); if(vdi_handle <= 0) { + Mfree(liste_rez); free_rsc(); return(0); } @@ -658,6 +665,7 @@ short set_video(void) wind_update(END_UPDATE); v_clsvwk(vdi_handle); free_rsc(); + Mfree(liste_rez); return(chg_res); } diff --git a/flash.tos/drivers/work.c b/flash.tos/drivers/work.c index 94676c5..212ea4e 100644 --- a/flash.tos/drivers/work.c +++ b/flash.tos/drivers/work.c @@ -248,6 +248,9 @@ ATTRIBUTE virt_work; Virtual virt_work_fvdi; char deftxbu[276]; /* stratch buf */ extern short video_found, video_log; +#ifdef USE_RADEON_MEMORY +extern short lock_video; +#endif extern char buf_log[]; extern short LINE_STYLE[]; short ROM_UD_PATRN[16] = { 0x0000,0x05A0,0x05A0,0x05A0,0x05A0,0x0DB0,0x0DB0,0x1DB8, 0x399C,0x799E,0x718E,0x718E,0x6186,0x4182,0x0000,0x0000 }; /* fuji */ @@ -346,10 +349,18 @@ short V_OPNWK(char *adr_var_vdi, short *INTIN, short *INTOUT, short *PTSOUT) break; case SETMODEFLAG: modecode = Vsetmode(-1); /* get current video mode */ +#ifdef USE_RADEON_MEMORY + if(lock_video) + break; +#endif if(modecode != PTSOUT[0]) /* see if cur mode != desired */ (void)Vsetscreen(0, 0, 3, PTSOUT[0]); /* set the video to new mode */ break; default: +#ifdef USE_RADEON_MEMORY + if(lock_video) + return(0); +#endif if(INTIN[0] < SETMODEFLAG) (void)Vsetscreen(-1, -1, INTIN[0] - 2, -1); /* ST modes */ else diff --git a/flash.tos/drivers/xbios.c b/flash.tos/drivers/xbios.c index ff5276f..9f1c5ca 100644 --- a/flash.tos/drivers/xbios.c +++ b/flash.tos/drivers/xbios.c @@ -1,6 +1,6 @@ /* TOS 4.04 Xbios calls for the CT60/CTPCI & Coldfire boards * Coldfire Xbios AC97 Sound - * Didier Mequignon 2005-2011, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2005-2012, e-mail: aniplay@wanadoo.fr * * This file is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,13 +26,11 @@ #include "radeon/radeonfb.h" #include "lynx/smi.h" #include "ct60.h" -#ifdef NETWORK #ifdef COLDFIRE #ifndef MCF5445X #include "ac97/mcf548x_ac97.h" #endif #endif -#endif extern void init_var_linea(long video_found); extern long call_enumfunc(long (*enumfunc)(SCREENINFO *inf, long flag), SCREENINFO *inf, long flag); @@ -40,7 +38,7 @@ extern long call_enumfunc(long (*enumfunc)(SCREENINFO *inf, long flag), SCREENIN extern long init_videl(long width, long height, long bpp, long freq, long extended); extern void setrgb_videl(long index, long rgb, long type); #endif -#if defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(COLDFIRE) && defined(LWIP) extern void board_printf(const char *fmt, ...); #else #define board_printf kprint @@ -82,6 +80,9 @@ extern const struct fb_videomode modedb[]; extern const struct fb_videomode vesa_modes[]; extern long total_modedb; extern short video_found, video_log, os_magic, memory_ok, drive_ok; +#ifdef USE_RADEON_MEMORY +extern short lock_video; +#endif long fix_modecode, second_screen, second_screen_aligned, log_addr; static short modecode_magic; @@ -90,7 +91,7 @@ static long bios_colors[256]; /* some XBIOS functions for the video driver */ #ifdef RADEON_RENDER -int display_composite_texture(long op, char *src_tex, long src_x, long src_y, long w_tex, long h_tex, long dst_x, long dst_y, long width, long height) +int display_composite_texture(long op, unsigned char *src_tex, long src_x, long src_y, long w_tex, long h_tex, long dst_x, long dst_y, long width, long height) { struct fb_info *info = info_fvdi; unsigned long dstFormat; @@ -442,7 +443,7 @@ void display_atari_logo(void) #ifdef RADEON_RENDER if(video_found && (info->screen_mono == NULL) && (bpp >= 16) && (info->fbops->SetupForCPUToScreenTexture != NULL)) { - buf_tex = (char *)Malloc(HEIGHT_LOGO * WIDTH_LOGO * 4); + buf_tex = (unsigned char *)Malloc(HEIGHT_LOGO * WIDTH_LOGO * 4); if(buf_tex != NULL) { incr = WIDTH_LOGO * 4; @@ -780,6 +781,8 @@ void init_screen_info(SCREENINFO *si, long modecode) char buf[16]; long flags = 0; struct fb_info *info = info_fvdi; + if(si->size < sizeof(SCREENINFO) - 8) + return; switch(modecode & NUMCOLS) { #ifndef COLDFIRE @@ -956,7 +959,7 @@ void init_screen_info(SCREENINFO *si, long modecode) si->max_y = 8192; /* max. possible heigth/width ??? */ si->maxmem = si->max_x * si->max_y * (si->scrPlanes / 8); si->pagemem = vgetsize(modecode); - if(!si->devID) + if(!si->devID && si->size && (si->size >= sizeof(SCREENINFO))) { if(info->var.refresh) si->refresh = info->var.refresh; @@ -1280,6 +1283,10 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ modecode = physaddr; rez = 3; logaddr = physaddr = 0; +#ifdef USE_RADEON_MEMORY + if(lock_video) + return(0); +#endif switch(modecode & NUMCOLS) { #ifndef COLDFIRE @@ -1483,6 +1490,10 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ case CMD_TESTMODE: if(milan_mode) return(0); +#ifdef USE_RADEON_MEMORY + if(lock_video) + return(0); +#endif modecode = physaddr; logaddr = physaddr = 0; rez = 3; @@ -1573,7 +1584,7 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ { SCRTEXTUREMEMBLK *blk = (SCRTEXTUREMEMBLK *)physaddr; #ifdef RADEON_RENDER - if(display_composite_texture(blk->blk_op, (char *)blk->blk_src_tex, blk->blk_src_x, blk->blk_src_y, blk->blk_w_tex, blk->blk_h_tex, blk->blk_dst_x, blk->blk_dst_y, blk->blk_w, blk->blk_h)) + if(display_composite_texture(blk->blk_op, (unsigned char *)blk->blk_src_tex, blk->blk_src_x, blk->blk_src_y, blk->blk_w_tex, blk->blk_h_tex, blk->blk_dst_x, blk->blk_dst_y, blk->blk_w, blk->blk_h)) blk->blk_status = BLK_OK; else #endif @@ -1677,6 +1688,10 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ case 2: /* ST-HIG */ if(os_magic == 1) return(Mode); +#ifdef USE_RADEON_MEMORY + if(lock_video) + return(Mode); +#endif resolution.width = 640; resolution.height = 400; resolution.bpp = 1; @@ -1687,6 +1702,17 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ break; #endif case 3: +#ifdef USE_RADEON_MEMORY + if(lock_video) + { + if(init_vdi) + { + init_var_linea((long)video_found); + init_screen(); + } + return(0); + } +#endif switch(modecode & NUMCOLS) { #ifndef COLDFIRE @@ -1728,7 +1754,7 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ if(((!logaddr && !physaddr) || ((logaddr == -1) && (physaddr == -1))) && (rez >= 0)) { resolution.used = 1; -#if defined(DEBUG) && defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(DEBUG) && defined(COLDFIRE) && defined(LWIP) if(init_vdi) board_printf("Setscreen mode 0x%04X %dx%d-%d@%d\r\n", Mode, resolution.width, resolution.height, resolution.bpp, resolution.freq); #endif @@ -1769,7 +1795,7 @@ long vsetscreen(long logaddr, long physaddr, long rez, long modecode, long init_ else if(!test) /* error */ { long addr; -#if defined(DEBUG) && defined(COLDFIRE) && defined(NETWORK) && defined(LWIP) +#if defined(DEBUG) && defined(COLDFIRE) && defined(LWIP) board_printf("Setscreen init_videl error mode 0x%04X %dx%d-%d@%d, try to use default 640x480\r\n", Mode, resolution.width, resolution.height, resolution.bpp, resolution.freq); #endif resolution.width = 640; @@ -2323,7 +2349,6 @@ long InitVideo(void) /* test for Video input */ return(0); } -#ifdef NETWORK #ifdef COLDFIRE #ifndef MCF5445X @@ -3281,33 +3306,37 @@ long buffptr(SndBufPtr *ptr) long InitSound(long type_gsxb) { - if(!mcf548x_ac97_install(AC97_DEVICE)) + int i; + for(i = 0; i < 2; i++) { - COOKIE mcsn; - COOKIE gsxb; - COOKIE *p = get_cookie('_SND'); - if(p != 0) + if(!mcf548x_ac97_install(AC97_DEVICE)) { - p->v.l &= 0x9; /* preserve PSG & DSP bits */ + COOKIE mcsn; + COOKIE gsxb; + COOKIE *p = get_cookie('_SND'); + if(p != 0) + { + p->v.l &= 0x9; /* preserve PSG & DSP bits */ #ifdef MCF547X - p->v.l |= 0x27; /* bit 5: extended mode, bit 2: 16 bits DMA, bit 1: 8 bits DMA, bit 0: YM2149 */ + p->v.l |= 0x27; /* bit 5: extended mode, bit 2: 16 bits DMA, bit 1: 8 bits DMA, bit 0: YM2149 */ #else - p->v.l |= 0x26; /* bit 5: extended mode, bit 2: 16 bits DMA, bit 1: 8 bits DMA */ + p->v.l |= 0x26; /* bit 5: extended mode, bit 2: 16 bits DMA, bit 1: 8 bits DMA */ #endif + } + mcsn.ident = 'McSn'; + mcsn.v.l = (long)&cookie_mac_sound; + add_cookie(&mcsn); + if(type_gsxb) + { + gsxb.ident = 'GSXB'; + gsxb.v.l = 0; + add_cookie(&gsxb); + } + flag_snd_init = 1; + flag_gsxb = type_gsxb; + sndstatus(SND_RESET); + return(0); // OK } - mcsn.ident = 'McSn'; - mcsn.v.l = (long)&cookie_mac_sound; - add_cookie(&mcsn); - if(type_gsxb) - { - gsxb.ident = 'GSXB'; - gsxb.v.l = 0; - add_cookie(&gsxb); - } - flag_snd_init = 1; - flag_gsxb = type_gsxb; - sndstatus(SND_RESET); - return(0); // OK } flag_snd_init = 0; return(-1); // error @@ -3324,5 +3353,4 @@ long InitSound(long gsxb) #endif /* MCF5445X */ #endif /* COLDFIRE */ -#endif /* NETWORK */ diff --git a/flash.tos/gentos.c b/flash.tos/gentos.c index fc18afc..b574b9f 100644 --- a/flash.tos/gentos.c +++ b/flash.tos/gentos.c @@ -1,23 +1,19 @@ -/* - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ +/* CT60 / Coldfire board(s) binary genarator +* +* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ #include #include @@ -26,290 +22,194 @@ #include "main.h" #include "gentos.h" -#include "ct60tos.h" #ifdef COLDFIRE #include "fire.h" #endif -#include "lz.h" -extern int srec_read(const char *path); void *buffer_flash=NULL; -extern unsigned long start_addr,end_addr; char *program_name; void gentos_error(char *error, char *solution) { - fprintf(stderr, "%s: Error: %s\n", program_name, error); - if(solution != NULL) - fprintf(stderr, "%s: Solution: %s\n", program_name, solution); - exit(1); -} - -unsigned long apply_patch(unsigned char *buffer, unsigned char *patch) -{ - unsigned char *p=patch; - unsigned char *adr; - unsigned long len; - unsigned char *top=buffer; - - adr=buffer+(*((unsigned long *)p)++); - while(adr != (buffer-1)) - { - len=*((unsigned long *)p)++; - if(len&0x80000000) - { - len&=0x7FFFFFFF; - if(len&0x40000000) - { - len&=0x3FFFFFFF; - *((unsigned long *)p)+=(0xE80000-(unsigned long)ct60tos_half_flash); - } - else - *((unsigned long *)(p+2))+=(0xE80000-(unsigned long)ct60tos_half_flash); - } - while(len--) - *adr++=*p++; - top=(adr > top ? adr : top); - if((unsigned long)p & 3) - p=(unsigned char *)(((unsigned long)p & 0xFFFFFFFC)+4); - adr=&buffer[*((unsigned long *)p)++]; - } - - return (top-buffer); -} - -unsigned long modify_tos(unsigned char *buffer) -{ - unsigned long size=TOS4_SIZE; - unsigned long sizepatch; - unsigned long time; - unsigned long day,month,year,year1,year2; - - time=Gettime(); - day=(time>>16)&0x1F; - month=(time>>21)&0xF; - year=(time>>25)+1980; - buffer[24]=(unsigned char)(((month/10)<<4)+(month%10)); - buffer[25]=(unsigned char)(((day/10)<<4)+(day%10)); - year1=year/100; - year2=year%100; - buffer[26]=(unsigned char)(((year1/10)<<4)+(year1%10)); - buffer[27]=(unsigned char)(((year2/10)<<4)+(year2%10)); - - sizepatch=apply_patch(buffer, (unsigned char *)ct60tos_patch); - - size=(sizepatch > size ? sizepatch : size); - - return size; + fprintf(stderr, "%s: Error: %s\n", program_name, error); + if(solution != NULL) + fprintf(stderr, "%s: Solution: %s\n", program_name, solution); + exit(1); } unsigned long load_file(char *filename, unsigned char *buffer, unsigned long length) { - unsigned short handle; - unsigned long return_value; - - if((return_value=Fopen(filename, 0)) < 0) - { - char error[MAX_ERROR_LENGTH]; - snprintf(error, MAX_ERROR_LENGTH, "Unable to open file %s.", filename); - gentos_error(error, NULL); - } - handle=(unsigned short)return_value; - - return_value=Fread(handle, length, buffer); - - Fclose(handle); - - if(return_value < 0) - { - char error[MAX_ERROR_LENGTH]; - snprintf(error, MAX_ERROR_LENGTH, "Unable to read file %s.", filename); - gentos_error(error, NULL); - } - - return return_value; + unsigned short handle; + unsigned long return_value; + + if((return_value=Fopen(filename, 0)) < 0) + { + char error[MAX_ERROR_LENGTH]; + snprintf(error, MAX_ERROR_LENGTH, "Unable to open file %s.", filename); + gentos_error(error, NULL); + } + handle=(unsigned short)return_value; + return_value=Fread(handle, length, buffer); + Fclose(handle); + if(return_value < 0) + { + char error[MAX_ERROR_LENGTH]; + snprintf(error, MAX_ERROR_LENGTH, "Unable to read file %s.", filename); + gentos_error(error, NULL); + } + return(return_value); } unsigned long load_tests(char *filename, unsigned char *buffer, unsigned long length) { - if((length=load_file(filename, buffer, length)) >= TESTS_SIZE) - { - char error[MAX_ERROR_LENGTH]; - snprintf(error, MAX_ERROR_LENGTH, "File %s is not a valid tests image.", filename); - gentos_error(error, NULL); - } - return length; + if((length=load_file(filename, buffer, length)) >= TESTS_SIZE) + { + char error[MAX_ERROR_LENGTH]; + snprintf(error, MAX_ERROR_LENGTH, "File %s is not a valid tests image.", filename); + gentos_error(error, NULL); + } + return(length); } void load_tos(char *filename, unsigned char *buffer, unsigned long length) { - if((load_file(filename, buffer, length) != TOS4_SIZE) || - (buffer[2]!=0x04) || - (buffer[3]!=0x04)) - { - char error[MAX_ERROR_LENGTH]; - snprintf(error, MAX_ERROR_LENGTH, "File %s is not a valid TOS 4.04 image.", filename); - gentos_error(error, NULL); - } + if((load_file(filename, buffer, length) != TOS4_SIZE) || (buffer[2]!=0x04) || (buffer[3]!=0x04)) + { + char error[MAX_ERROR_LENGTH]; + snprintf(error, MAX_ERROR_LENGTH, "File %s is not a valid TOS 4.04 image.", filename); + gentos_error(error, NULL); + } } void save_tos(char *filename, unsigned char *buffer, unsigned long length) { - unsigned short handle; - unsigned long return_value; - - if((return_value=Fcreate(filename, 0)) < 0) - { - char error[MAX_ERROR_LENGTH]; - snprintf(error, MAX_ERROR_LENGTH, "Unable to create file %s.", filename); - gentos_error(error, NULL); - } - handle=(unsigned short)return_value; - - if(Fwrite(handle, length, buffer) != length) - { - char error[MAX_ERROR_LENGTH]; - Fclose(handle); - snprintf(error, MAX_ERROR_LENGTH, "Unable to write file %s.", filename); - gentos_error(error, NULL); - } - - Fclose(handle); + unsigned short handle; + unsigned long return_value; + + if((return_value=Fcreate(filename, 0)) < 0) + { + char error[MAX_ERROR_LENGTH]; + snprintf(error, MAX_ERROR_LENGTH, "Unable to create file %s.", filename); + gentos_error(error, NULL); + } + handle=(unsigned short)return_value; + if(Fwrite(handle, length, buffer) != length) + { + char error[MAX_ERROR_LENGTH]; + Fclose(handle); + snprintf(error, MAX_ERROR_LENGTH, "Unable to write file %s.", filename); + gentos_error(error, NULL); + } + Fclose(handle); } int main(int argc, char **argv) { - static unsigned short crctab[256] = { - 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7, - 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef, - 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6, - 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de, - 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485, - 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d, - 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4, - 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc, - 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823, - 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b, - 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12, - 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a, - 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41, - 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49, - 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70, - 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78, - 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f, - 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067, - 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e, - 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256, - 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d, - 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405, - 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c, - 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634, - 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab, - 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3, - 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a, - 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92, - 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9, - 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1, - 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8, - 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 }; -#if 0 //#ifdef COLDFIRE - static char cmd[256]; -#endif - unsigned long length; - unsigned char *buffer; - unsigned short crc,crc2; - unsigned long i; - - program_name=argv[0]; - if(argc != 3 && argc != 4 && argc !=5) - { - fprintf(stderr, "Usage: %s tos404.bin [sparrow.out] ct60tos.bin\n", program_name); - exit(1); - } - - if((buffer=(unsigned char *)malloc(FLASH_SIZE-PARAM_SIZE)) == NULL) - gentos_error("Not enough memory for work buffer.", NULL); - for(i=0;i<(FLASH_SIZE-PARAM_SIZE);buffer[i++]=0xFF); - - load_tos(argv[1], buffer, FLASH_SIZE-PARAM_SIZE-TESTS_SIZE); - length=modify_tos(buffer); - + unsigned long end_previous=0; + + program_name = argv[0]; + if((argc < 4) || (argc > 7)) + { + fprintf(stderr, "Usage: %s tos404.bin boot.hex [sparrow.out] ct60tos.bin\n", program_name); + exit(1); + } + if((buffer_flash = (unsigned char *)Mxalloc(FLASH_SIZE-PARAM_SIZE,3)) == NULL) + gentos_error("Not enough memory for work buffer.", NULL); + memset(buffer_flash,-1,FLASH_SIZE-PARAM_SIZE); + load_tos(argv[1], buffer_flash, FLASH_SIZE-PARAM_SIZE-TESTS_SIZE); /* load 512KB TOS */ + *((unsigned short *)(buffer_flash+0x30))=0x60FF; /* bra.l to boot (12 bytes version header) */ + *((unsigned long *)(buffer_flash+0x32))=0xE8000C-0xE00030-2; + if(strstr(argv[2], ".hex") == NULL) + gentos_error("Need .hex file for boot", NULL); + printf("read srec file %s...", argv[2]); + if(srec_read(argv[2])) /* boot.hex */ + gentos_error("Error with HEX boot file.", NULL); + printf(" (0x%08lX-0x%08lX)\r\n", start_addr, end_addr); + if((start_addr < FLASH_ADR+TOS4_SIZE) || (start_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX boot file, bad start address.", NULL); + if((end_addr < FLASH_ADR+TOS4_SIZE) || (end_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX boot file, bad end address.", NULL); + if(end_addr <= start_addr) + gentos_error("Error with HEX boot file, end address < start address.", NULL); + end_previous = end_addr; + if(argc == 4) + save_tos(argv[3], buffer_flash, end_previous-FLASH_ADR); /* normal TOS saved with CT60 boot only */ + else if(argc == 5) + { #ifdef COLDFIRE - if(argc==4 && length>(CF68KLIB-FLASH_TOS_FIRE_ENGINE)) - gentos_error("Not enough flash space for load cf68klib.", NULL); + if(strstr(argv[2], ".hex") == NULL) + gentos_error("Need .hex file for CF68KLIB", NULL); + printf("read srec file %s...", argv[3]); + if(srec_read(argv[3])) + gentos_error("Error with HEX CF68KLIB file.", NULL); + printf(" (0x%08lX-0x%08lX)\r\n", start_addr, end_addr); + if((start_addr < end_previous) || (start_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX CF68KLIB file, bad start address.", NULL); + if((end_addr < end_previous) || (end_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX CF68KLIB file, bad end address.", NULL); + if(end_addr <= start_addr) + gentos_error("Error with HEX CF68KLIB file, end address < start address.", NULL); + save_tos(argv[4], buffer_flash, end_addr-FLASH_ADR); /* normal CF TOS saved with boot/CF68KLIB */ #else - if(argc==4 && length>(FLASH_SIZE-PARAM_SIZE-TESTS_SIZE)) - gentos_error("Not enough flash space for load tests.", NULL); + unsigned long length; + if(end_previous > (FLASH_ADR+FLASH_SIZE-PARAM_SIZE-TESTS_SIZE)) + gentos_error("Not enough flash space for load tests.", NULL); + length=load_tests(argv[3],buffer_flash+FLASH_SIZE-PARAM_SIZE-TESTS_SIZE,TESTS_SIZE); + save_tos(argv[4], buffer_flash, FLASH_SIZE-PARAM_SIZE-TESTS_SIZE+length); /* normal TOS saved with CT60 boot and tests */ #endif - - crc=0; - for(i=0;i < (FLASH_SIZE/2)-2;i++) - { - crc2 = crctab[buffer[i] ^ (unsigned char)(crc>>8)]; - crc <<= 8; - crc ^= crc2; - } - buffer[i++] = (unsigned char)(crc>>8); - buffer[i] = (unsigned char)crc; - - if(argc == 3) - save_tos(argv[2], buffer, length); - else - { - int *work; - unsigned long size_pci_drivers; - char *buf, *buffer_pci_drivers; - - if(argc ==4) - { + } + else /* argc > 5 */ + { #ifdef COLDFIRE - length=load_tests(argv[2], buffer+CF68KLIB-FLASH_ADR, 0x10000); - save_tos(argv[3], buffer, CF68KLIB-FLASH_ADR+length); -#else - length=load_tests(argv[2],buffer+FLASH_SIZE-PARAM_SIZE-TESTS_SIZE,TESTS_SIZE); - save_tos(argv[3], buffer, FLASH_SIZE-PARAM_SIZE-TESTS_SIZE+length); -#endif - } - else + int index = 3; + if((strstr(argv[index], ".hex") != NULL) && (strstr(argv[index], "aes") != NULL)) { -#ifdef COLDFIRE - load_tests(argv[2], buffer+CF68KLIB-FLASH_ADR, 0x10000); -#endif - if((buffer_flash = (char *)malloc(0x200000)) == NULL) - gentos_error("Not enough memory for pci drivers buffer.", NULL); - memset(buffer_flash,-1,0x200000); - printf("read srec file %s...\r\n", argv[3]); - if(srec_read(argv[3])) - gentos_error("Error with HEX file pci drivers.", NULL); - if((start_addr < FLASH_ADR) || (start_addr >= (FLASH_ADR2+FLASH_SIZE2))) - gentos_error("Error with HEX file, bad start address.", NULL); - if((end_addr < FLASH_ADR) || (end_addr >= (FLASH_ADR2+FLASH_SIZE2))) - gentos_error("Error with HEX file, bad end address.", NULL); + char *p =(unsigned char *)buffer_flash; + printf("read srec file %s...", argv[index]); + if(srec_read(argv[index++])) + gentos_error("Error with HEX AES file.", NULL); + if((start_addr < FLASH_ADR) || (start_addr >= (FLASH_ADR+(FLASH_SIZE/2)))) + gentos_error("Error with HEX AES file, bad start address.", NULL); + if((end_addr < FLASH_ADR) || (end_addr >= (FLASH_ADR+(FLASH_SIZE/2)))) + gentos_error("Error with HEX AES file, bad end address.", NULL); if(end_addr <= start_addr) - gentos_error("Error with HEX file, end address < start address.", NULL); - if(end_addr >= FLASH_ADR2) + gentos_error("Error with HEX AES file, end address < start address.", NULL); + printf(" (0x%08lX-0x%08lX)\r\n", start_addr, end_addr); + if((p[start_addr-FLASH_ADR] == 0) && (p[start_addr-FLASH_ADR+1] == 0)) { - memcpy(buffer_flash+0x100000,buffer_flash+FLASH_ADR2-FLASH_ADR,end_addr-FLASH_ADR2); - size_pci_drivers = FLASH_ADR+0x100000-start_addr + end_addr-FLASH_ADR2; + p[start_addr-FLASH_ADR] = 0x4E; /* fix code alignment */ + p[start_addr-FLASH_ADR+1] = 0x71; } - else - size_pci_drivers = end_addr-start_addr; - buffer_pci_drivers = buffer_flash+start_addr-FLASH_ADR; - if((work = (int *)malloc(sizeof(int)*(size_pci_drivers+65536))) == NULL) - gentos_error("Not enough memory for compress work buffer.", NULL); - buf = buffer+start_addr-FLASH_ADR; - printf("compress PCI part %d bytes (0x%08lX-0x%08lX)... \r\n", (int)size_pci_drivers, start_addr, end_addr); - length = (unsigned long)LZ_CompressFast(buffer_pci_drivers, buf+8, (int)size_pci_drivers, work); - if(length > FLASH_ADR+FLASH_SIZE-PARAM_SIZE-start_addr-8) - gentos_error("Not enough memory for put compressed pci drivers in flash.", NULL); - buf[0] = buf[3]='_'; - buf[1] = 'L'; - buf[2] = 'Z'; - *(unsigned long *)&buf[4] = length; - length += 8; - printf("save TOS file %s, %d bytes...\r\n", argv[4], (int)(start_addr-FLASH_ADR+length)); - save_tos(argv[4], buffer, start_addr-FLASH_ADR+length); } - } - return 0; + if(strstr(argv[index], ".hex") == NULL) + gentos_error("Need .hex file for CF68KLIB", NULL); + printf("read srec file %s...", argv[index]); + if(srec_read(argv[index++])) + gentos_error("Error with HEX CF68KLIB file.", NULL); + printf(" (0x%08lX-0x%08lX)\r\n", start_addr, end_addr); + if((start_addr < end_previous) || (start_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX CF68KLIB file, bad start address.", NULL); + if((end_addr < end_previous) || (end_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX CF68KLIB file, bad end address.", NULL); + if(end_addr <= start_addr) + gentos_error("Error with HEX CF68KLIB file, end address < start address.", NULL); + end_previous = end_addr; +#else + int index = 4; +#endif + if(strstr(argv[index], ".hex") == NULL) + gentos_error("Need .hex file for drivers", NULL); + printf("read srec file %s...", argv[index]); + if(srec_read(argv[index++])) /* drivers */ + gentos_error("Error with HEX drivers file.", NULL); + printf(" (0x%08lX-0x%08lX)\r\n", start_addr, end_addr); + if((start_addr < end_previous) || (start_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX drivers file, bad start address.", NULL); + if((end_addr < end_previous) || (end_addr >= FLASH_ADR+FLASH_SIZE-PARAM_SIZE)) + gentos_error("Error with HEX drivers file, bad end address.", NULL); + if(end_addr <= start_addr) + gentos_error("Error with HEX drivers file, end address < start address.", NULL); + save_tos(argv[index], buffer_flash, end_addr-FLASH_ADR); /* PCI TOS saved with CT60 boot and drivers (and CF68KLIB for CF) */ + } + return(0); } diff --git a/flash.tos/get.c b/flash.tos/get.c deleted file mode 100644 index 8208b7b..0000000 --- a/flash.tos/get.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "config.h" -#include "get.h" - -#ifdef NETWORK - -unsigned char *board_get_ethaddr(unsigned char *ethaddr) -{ - int i; - for(i = 0; i < 6; i++) - ethaddr[i] = ((PARAM *)PARAMS_ADDRESS)->ethaddr[i]; - return ethaddr; -} - -unsigned char *board_get_client(unsigned char *client) -{ - int i; - for(i = 0; i < 4; i++) - client[i] = ((PARAM *)PARAMS_ADDRESS)->client[i]; - return client; -} - -unsigned char *board_get_server(unsigned char *server) -{ - int i; - for(i = 0; i < 4; i++) - server[i] = ((PARAM *)PARAMS_ADDRESS)->server[i]; - return server; -} - -unsigned char *board_get_gateway(unsigned char *gateway) -{ - int i; - for(i = 0; i < 4; i++) - gateway[i] = ((PARAM *)PARAMS_ADDRESS)->gateway[i]; - return gateway; -} - -unsigned char *board_get_netmask(unsigned char *netmask) -{ - int i; - for(i = 0; i < 4; i++) - netmask[i] = ((PARAM *)PARAMS_ADDRESS)->netmask[i]; - return netmask; -} - -char *board_get_filename(char *filename) -{ - int c, i = 0; - while(i < FILENAME_SIZE) - { - c = ((PARAM *)PARAMS_ADDRESS)->filename[i]; - filename[i] = (char)c; - i++; - if(c == '\0') - i = FILENAME_SIZE; - } - filename[i] = '\0'; - return filename; -} - -int board_get_filetype(void) -{ - return((PARAM *)PARAMS_ADDRESS)->netcfg[2]; -} - -int board_get_autoboot(void) -{ - return((PARAM *)PARAMS_ADDRESS)->netcfg[0]; -} - -#endif /* NETWORK */ - diff --git a/flash.tos/include/ct60.h b/flash.tos/include/ct60.h index d64a15f..ffd927b 100644 --- a/flash.tos/include/ct60.h +++ b/flash.tos/include/ct60.h @@ -80,12 +80,13 @@ #define CT60_SAVE_NVRAM_2 8 #define CT60_SAVE_NVRAM_3 9 #define CT60_PARAM_OFFSET_TLV 10 -#define CT60_MAC_ADDRESS 10 -#define CT60_SERIAL_SPEED 11 +#define CT60_MAC_ADDRESS 10 /* Firebee */ +#define CT60_IP_ADDRESS2 11 +#define CT60_SERIAL_SPEED 11 /* Firebee */ #define CT60_USER_DIV_CLOCK 12 -#define CT60_IP_ADDRESS 12 +#define CT60_IP_ADDRESS 12 /* Firebee */ #define CT60_CLOCK 13 -#define CT60_SERVER_IP_ADDRESS 13 +#define CT60_SERVER_IP_ADDRESS 13 /* Firebee */ #define CT60_PARAM_CTPCI 14 /* 15 is reserved - do not use */ diff --git a/flash.tos/include/fire.h b/flash.tos/include/fire.h index 302eaa0..8fe4bc4 100644 --- a/flash.tos/include/fire.h +++ b/flash.tos/include/fire.h @@ -340,6 +340,8 @@ #define FLASH_UNLOCK1 (0xAAA) #define FLASH_UNLOCK2 (0x554) +/* Device Errata 26 - Flexbus hang up in 4:1 clock ratio + => if MCF_XARB_CFG_PLDIS = 0, enable at least 2 cycle of Flexbus address hold MCF_FBCS_CSCR_RDAH(1) */ /* FALCON I/O 1MB */ #define FPGA_CS1_BASE 0xFFF00000 #define FPGA_CS1_SIZE 0x00100000 @@ -355,7 +357,7 @@ /* VIDEO RAM 128MB */ #define FPGA_CS4_BASE 0x40000000 #define FPGA_CS4_SIZE 0x40000000 -#define FPGA_CS4_ACCESS (MCF_FBCS_CSCR_BSTW + MCF_FBCS_CSCR_BSTR + MCF_FBCS_CSCR_PS_32) +#define FPGA_CS4_ACCESS ( + MCF_FBCS_CSCR_RDAH(1) + MCF_FBCS_CSCR_BSTW + MCF_FBCS_CSCR_BSTR + MCF_FBCS_CSCR_PS_32) #define ACP_VIDEO_RAM (FPGA_CS4_BASE) #define ACP_VIDEO_CFG (FPGA_CS4_BASE + 0x20000000) diff --git a/flash.tos/include/pci_bios.h b/flash.tos/include/pci_bios.h index d09c24b..19f2b6d 100644 --- a/flash.tos/include/pci_bios.h +++ b/flash.tos/include/pci_bios.h @@ -3,7 +3,7 @@ #define LITTLE_ENDIAN_LANE_SWAPPED #define CHECK_PARITY -#undef SAME_CPU_PCI_MEM_ADDR // for fix DMA problems with some drivers +#define SAME_CPU_PCI_MEM_ADDR // for fix DMA problems with some drivers #ifdef COLDFIRE #include "fire.h" @@ -13,6 +13,8 @@ #define PCI_MINGNT 1 #define PCI_MAXLAT 42 #else +#define PCI_CACHE_LINE 8 +#define PCI_MINGNT 1 #define PCI_MAXLAT 32 #endif @@ -22,13 +24,11 @@ #undef PCI_DYNAMIC_MAPPING #define PCI_LOCAL_CONFIG MCF_PCI_PCIIDR #ifdef MCF5445X -#define PCI_IRQ_BASE_VECTOR (64+INT1_HI_PCI_SCR+64+OFFSET_INT_CF68KLIB) #define PCI_MEMORY_OFFSET 0xA0000000 #define PCI_MEMORY_SIZE 0x10000000 /* 256 MB */ #define PCI_IO_OFFSET 0xB0000000 #define PCI_IO_SIZE 0x10000000 /* 256 MB */ #else /* MCF548X */ -#define PCI_IRQ_BASE_VECTOR (64+41+OFFSET_INT_CF68KLIB) #define PCI_MEMORY_OFFSET 0x80000000 #define PCI_MEMORY_SIZE 0x40000000 /* 1024 MB */ #define PCI_IO_OFFSET 0xD0000000 @@ -78,23 +78,21 @@ #define PCI_NOBODYHOME 0xFFFF -#define PCI_MAX_FUNCTION 4 /* 4 functions per PCI slot */ - #ifdef COLDFIRE #ifdef MCF547X /* FIREBEE */ -#define PCI_MAX_HANDLE (7+1) /* 7 slots on the Firebee + host bridge MCF547X */ +#define PCI_MAX_SLOT (7+1) /* 7 slots on the Firebee + host bridge MCF547X */ #else /* MCF548X - MCF5445X */ -#define PCI_MAX_HANDLE (4+1) /* 4 slots on the M5484LITE/M5485EVB/M54455EVB + host bridge MCF548X/MCF5445X */ +#define PCI_MAX_SLOT (4+1) /* 4 slots on the M5484LITE/M5485EVB/M54455EVB + host bridge MCF548X/MCF5445X */ #endif /* MCF547X */ -#define LAST_LOCAL_REGISTER 0x40 +#define LAST_LOCAL_REGISTER 0x100 #define LOCAL_REGISTERS_BIG // local registers are in Big Endian on the Coldfire #else /* PLX9054 */ -#define PCI_MAX_HANDLE 5 /* 4 slots on the CTPCI + host bridge PLX9054 */ +#define PCI_MAX_SLOT (4+1) /* 4 slots on the CTPCI + host bridge PLX9054 */ /* PLX9054 ID */ #define PLX9054 0x905410B5 @@ -185,6 +183,14 @@ #endif /* COLDFIRE */ +#define PCI_MAX_BUS 4 +#define PCI_MAX_FUNCTION 4 /* 4 functions per PCI slot */ +#define PCI_MAX_DEVICE PCI_MAX_SLOT /* was 32 */ + +#if (PCI_MAX_DEVICE < PCI_MAX_SLOT) +#error PCI_MAX_DEVICE < PCI_MAX_SLOT +#endif + /* PCI configuration registers */ #define PCIIDR 0x00 /* PCI Configuration ID Register */ #define PCICSR 0x04 /* PCI Command/Status Register */ @@ -231,6 +237,24 @@ #define PVPDAD 0x4E /* PCI Vital Product Data Address */ #define PVPDATA 0x50 /* PCI VPD Data */ +/* Header type 1 (PCI-to-PCI bridges) */ +#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ +#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ +#define PCI_SUBORDINATE_BUS 0x1A /* Highest bus number behind the bridge */ +#define PCI_SEC_LATENCY_TIMER 0x1B /* Latency timer for secondary interface */ +#define PCI_IO_BASE 0x1C /* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1D +#define PCI_SEC_STATUS 0x1E /* Secondary status register */ +#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ +#define PCI_PREF_MEMORY_LIMIT 0x26 +#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ +#define PCI_PREF_LIMIT_UPPER32 0x2C +#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ +#define PCI_IO_LIMIT_UPPER16 0x32 +#define PCI_BRIDGE_CONTROL 0x3E /* Bridge Control */ + /* Command register bit definitions */ #define PCI_CMDREG_IOSP 1 /* Enable IO space accesses */ #define PCI_CMDREG_MEMSP 2 /* Enable MEM space accesses */ @@ -291,6 +315,8 @@ #define PCI_CLASS_CRYPT 16 /* Encrytion/Decryption class */ #define PCI_CLASS_SIGNAL 17 /* Signal Processing class */ +#define PCI_CLASS_BRIDGE_PCI 0x0604 + /* PCI Sub-class codes - base class 0 (no new devices should use this code) */ #define PCI_NONE_NOTVGA 0 /* All devices except VGA compatible */ #define PCI_NONE_VGA 1 /* VGA compatible */ @@ -470,10 +496,10 @@ #define PCI_COOKIE_ROUTINE 8 /* offset PCI BIOS routines */ #define PCI_COOKIE_MAX_ROUTINES 45 /* maximum of routines */ #define PCI_COOKIE_SIZE ((4*PCI_COOKIE_MAX_ROUTINES)+PCI_COOKIE_ROUTINE) -#define PCI_RSC_HANDLESTOTALSIZE (PCI_RSC_DESC_TOTALSIZE*PCI_MAX_HANDLE*PCI_MAX_FUNCTION) -#define PCI_DEV_HANDLESTOTALSIZE (PCI_DEV_DES_SIZE*PCI_MAX_HANDLE*PCI_MAX_FUNCTION) -#define PCI_INT_HANDLESTOTALSIZE (PCI_MAX_HANDLE*PCI_MAX_FUNCTION) -#define PCI_COOKIE_TOTALSIZE (PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE) +#define PCI_RSC_HANDLESTOTALSIZE (PCI_RSC_DESC_TOTALSIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_DEV_HANDLESTOTALSIZE (PCI_DEV_DES_SIZE*PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_INT_HANDLESTOTALSIZE (PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION) +#define PCI_COOKIE_TOTALSIZE (PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE*2) /* Error codes */ #define PCI_SUCCESSFUL 0 /* everything's fine */ diff --git a/flash.tos/include/ramcf68k.h b/flash.tos/include/ramcf68k.h index d6a9544..8243708 100644 --- a/flash.tos/include/ramcf68k.h +++ b/flash.tos/include/ramcf68k.h @@ -1,4 +1,4 @@ -/* TOS 4.04 Xbios for the Coldfire boards +/* TOS 4.04 CF68KLIB RAM for the Coldfire boards * Didier Mequignon 2011, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or diff --git a/flash.tos/include/vars.h b/flash.tos/include/vars.h index 24c6fc6..619a9e5 100644 --- a/flash.tos/include/vars.h +++ b/flash.tos/include/vars.h @@ -106,6 +106,7 @@ #define pinfo_cookptr 86 // 4 bytes #define pinfo_vernum 90 // 2 bytes #define pinfo_maxsiz 92 // 2 bytes +// not inside AHDI #define pinfo_ptype 94 // 16 x 4 bytes #define pinfo_psize 158 // 16 x 4 bytes #define pinfo_flags 222 // 16 x 2 bytes, internal use: B15:swap, B7:change, B0:bootable @@ -129,10 +130,18 @@ #define RESERVE_MEM_FONTS 0x8000 #define CTPCI_1ABCD 0x00000001 +#define CTPCI_1M 0x00000002 +#define CTPCI_1N 0x00000004 #define ABE_SDR_7 0x00010000 #define ETHERNAT 0x80000000 #define SUPERVIDEL 0x40000000 +#define ScsiDrvID (RESERVE_MEM_FONTS-134) // SCSIDRV +#define Buffer1024 (RESERVE_MEM_FONTS-130) // SCSIDRV +#define ReqData (RESERVE_MEM_FONTS-126) // SCSIDRV (18 bytes) +#define BusNumber (RESERVE_MEM_FONTS-108) // SCSIDRV +#define PacketDevice (RESERVE_MEM_FONTS-104) // SCSIDRV +#define Features (RESERVE_MEM_FONTS-100) // SCSIDRV #define measure_clock (RESERVE_MEM_FONTS-92) #define hardware_type (RESERVE_MEM_FONTS-88) #define pci_io_size (RESERVE_MEM_FONTS-84) @@ -149,8 +158,10 @@ #define save_source (RESERVE_MEM_FONTS-40) #define save_target (RESERVE_MEM_FONTS-36) #define save_contrl (RESERVE_MEM_FONTS-32) +#ifndef COLDFIRE /* for reduce boot size, blitter not exist */ #define adr_source (RESERVE_MEM_FONTS-28) #define adr_target (RESERVE_MEM_FONTS-24) #define adr_fonts (RESERVE_MEM_FONTS-20) /* 5 longs */ +#endif #endif diff --git a/flash.tos/include/version.h b/flash.tos/include/version.h index d605096..7c897e2 100644 --- a/flash.tos/include/version.h +++ b/flash.tos/include/version.h @@ -1,3 +1,3 @@ -#define VERSION 0x0201 +#define VERSION 0x0202 #define DATE \ -21, 7,2011,19,57 + 2, 7,2012, 9,52 diff --git a/flash.tos/lz.c b/flash.tos/lz.c deleted file mode 100644 index dfaf33d..0000000 --- a/flash.tos/lz.c +++ /dev/null @@ -1,447 +0,0 @@ -/************************************************************************* -* Name: lz.c -* Author: Marcus Geelnard -* Description: LZ77 coder implementation. -* Reentrant: Yes -* -* The LZ77 compression scheme is a substitutional compression scheme -* proposed by Abraham Lempel and Jakob Ziv in 1977. It is very simple in -* its design, and uses no fancy bit level compression. -* -* This is my first attempt at an implementation of a LZ77 code/decoder. -* -* The principle of the LZ77 compression algorithm is to store repeated -* occurrences of strings as references to previous occurrences of the same -* string. The point is that the reference consumes less space than the -* string itself, provided that the string is long enough (in this -* implementation, the string has to be at least 4 bytes long, since the -* minimum coded reference is 3 bytes long). Also note that the term -* "string" refers to any kind of byte sequence (it does not have to be -* an ASCII string, for instance). -* -* The coder uses a brute force approach to finding string matches in the -* history buffer (or "sliding window", if you wish), which is very, very -* slow. I recon the complexity is somewhere between O(n^2) and O(n^3), -* depending on the input data. -* -* There is also a faster implementation that uses a large working buffer -* in which a "jump table" is stored, which is used to quickly find -* possible string matches (see the source code for LZ_CompressFast() for -* more information). The faster method is an order of magnitude faster, -* and also does a full string search in the entire input buffer (it does -* not use a sliding window). -* -* The upside is that decompression is very fast, and the compression ratio -* is often very good. -* -* The reference to a string is coded as a (length,offset) pair, where the -* length indicates the length of the string, and the offset gives the -* offset from the current data position. To distinguish between string -* references and literal strings (uncompressed bytes), a string reference -* is preceded by a marker byte, which is chosen as the least common byte -* symbol in the input data stream (this marker byte is stored in the -* output stream as the first byte). -* -* Occurrences of the marker byte in the stream are encoded as the marker -* byte followed by a zero byte, which means that occurrences of the marker -* byte have to be coded with two bytes. -* -* The lengths and offsets are coded in a variable length fashion, allowing -* values of any magnitude (up to 4294967295 in this implementation). -* -* With this compression scheme, the worst case compression result is -* (257/256)*insize + 1. -* -*------------------------------------------------------------------------- -* Copyright (c) 2003-2004 Marcus Geelnard -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would -* be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not -* be misrepresented as being the original software. -* -* 3. This notice may not be removed or altered from any source -* distribution. -* -* Marcus Geelnard -* marcus.geelnard at home.se -*************************************************************************/ - - -/************************************************************************* -* Constants used for LZ77 coding -*************************************************************************/ - -/* Maximum offset (can be any size < 2^32). Lower values gives faster - compression, while higher values gives better compression. - NOTE: LZ_CompressFast does not use this constant. */ -#define LZ_MAX_OFFSET 100000 - - - -/************************************************************************* -* INTERNAL FUNCTIONS * -*************************************************************************/ - - -/************************************************************************* -* _LZ_StringCompare() - Return maximum length string match. -*************************************************************************/ - -static unsigned int _LZ_StringCompare( unsigned char * str1, - unsigned char * str2, unsigned int minlen, unsigned int maxlen ) -{ - unsigned int len; - - for( len = minlen; (len < maxlen) && (str1[len] == str2[len]); ++ len ); - - return len; -} - - -/************************************************************************* -* _LZ_WriteVarSize() - Write unsigned integer with variable number of -* bytes depending on value. -*************************************************************************/ - -static int _LZ_WriteVarSize( unsigned int x, unsigned char * buf ) -{ - unsigned int y; - int num_bytes, i, b; - - /* Determine number of bytes needed to store the number x */ - y = x >> 3; - for( num_bytes = 5; num_bytes >= 2; -- num_bytes ) - { - if( y & 0xfe000000 ) break; - y <<= 7; - } - - /* Write all bytes, seven bits in each, with 8:th bit set for all */ - /* but the last byte. */ - for( i = num_bytes-1; i >= 0; -- i ) - { - b = (x >> (i*7)) & 0x0000007f; - if( i > 0 ) - { - b |= 0x00000080; - } - *buf ++ = (unsigned char) b; - } - - /* Return number of bytes written */ - return num_bytes; -} - - -/************************************************************************* -* PUBLIC FUNCTIONS * -*************************************************************************/ - - -/************************************************************************* -* LZ_Compress() - Compress a block of data using an LZ77 coder. -* in - Input (uncompressed) buffer. -* out - Output (compressed) buffer. This buffer must be 0.4% larger -* than the input buffer, plus one byte. -* insize - Number of input bytes. -* The function returns the size of the compressed data. -*************************************************************************/ - -int LZ_Compress( unsigned char *in, unsigned char *out, - unsigned int insize ) -{ - unsigned char marker, symbol; - unsigned int inpos, outpos, bytesleft, i; - unsigned int maxoffset, offset, bestoffset; - unsigned int maxlength, length, bestlength; - unsigned int histogram[ 256 ]; - unsigned char *ptr1, *ptr2; - - /* Do we have anything to compress? */ - if( insize < 1 ) - { - return 0; - } - - /* Create histogram */ - for( i = 0; i < 256; ++ i ) - { - histogram[ i ] = 0; - } - for( i = 0; i < insize; ++ i ) - { - ++ histogram[ in[ i ] ]; - } - - /* Find the least common byte, and use it as the code marker */ - marker = 0; - for( i = 1; i < 256; ++ i ) - { - if( histogram[ i ] < histogram[ marker ] ) - { - marker = i; - } - } - - /* Remember the repetition marker for the decoder */ - out[ 0 ] = marker; - - /* Start of compression */ - inpos = 0; - outpos = 1; - - /* Main compression loop */ - bytesleft = insize; - do - { - /* Determine most distant position */ - if( inpos > LZ_MAX_OFFSET ) maxoffset = LZ_MAX_OFFSET; - else maxoffset = inpos; - - /* Get pointer to current position */ - ptr1 = &in[ inpos ]; - - /* Search history window for maximum length string match */ - bestlength = 3; - bestoffset = 0; - for( offset = 3; offset <= maxoffset; ++ offset ) - { - /* Get pointer to candidate string */ - ptr2 = &ptr1[ -offset ]; - - /* Quickly determine if this is a candidate (for speed) */ - if( (ptr1[ 0 ] == ptr2[ 0 ]) && - (ptr1[ bestlength ] == ptr2[ bestlength ]) ) - { - /* Determine maximum length for this offset */ - maxlength = (bytesleft < offset ? bytesleft : offset); - - /* Count maximum length match at this offset */ - length = _LZ_StringCompare( ptr1, ptr2, 0, maxlength ); - - /* Better match than any previous match? */ - if( length > bestlength ) - { - bestlength = length; - bestoffset = offset; - } - } - } - - /* Was there a good enough match? */ - if( (bestlength >= 8) || - ((bestlength == 4) && (bestoffset <= 0x0000007f)) || - ((bestlength == 5) && (bestoffset <= 0x00003fff)) || - ((bestlength == 6) && (bestoffset <= 0x001fffff)) || - ((bestlength == 7) && (bestoffset <= 0x0fffffff)) ) - { - out[ outpos ++ ] = (unsigned char) marker; - outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] ); - outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] ); - inpos += bestlength; - bytesleft -= bestlength; - } - else - { - /* Output single byte (or two bytes if marker byte) */ - symbol = in[ inpos ++ ]; - out[ outpos ++ ] = symbol; - if( symbol == marker ) - { - out[ outpos ++ ] = 0; - } - -- bytesleft; - } - } - while( bytesleft > 3 ); - - /* Dump remaining bytes, if any */ - while( inpos < insize ) - { - if( in[ inpos ] == marker ) - { - out[ outpos ++ ] = marker; - out[ outpos ++ ] = 0; - } - else - { - out[ outpos ++ ] = in[ inpos ]; - } - ++ inpos; - } - - return outpos; -} - - -/************************************************************************* -* LZ_CompressFast() - Compress a block of data using an LZ77 coder. -* in - Input (uncompressed) buffer. -* out - Output (compressed) buffer. This buffer must be 0.4% larger -* than the input buffer, plus one byte. -* insize - Number of input bytes. -* work - Pointer to a temporary buffer (internal working buffer), which -* must be able to hold (insize+65536) unsigned integers. -* The function returns the size of the compressed data. -*************************************************************************/ - -int LZ_CompressFast( unsigned char *in, unsigned char *out, - unsigned int insize, unsigned int *work ) -{ - unsigned char marker, symbol; - unsigned int inpos, outpos, bytesleft, i, index, symbols; - unsigned int offset, bestoffset; - unsigned int maxlength, length, bestlength; - unsigned int histogram[ 256 ], *lastindex, *jumptable; - unsigned char *ptr1, *ptr2; - - /* Do we have anything to compress? */ - if( insize < 1 ) - { - return 0; - } - - /* Assign arrays to the working area */ - lastindex = work; - jumptable = &work[ 65536 ]; - - /* Build a "jump table". Here is how the jump table works: - jumptable[i] points to the nearest previous occurrence of the same - symbol pair as in[i]:in[i+1], so in[i] == in[jumptable[i]] and - in[i+1] == in[jumptable[i]+1]. Following the jump table gives a - dramatic boost for the string search'n'match loop compared to doing - a brute force search. */ - for( i = 0; i < 65536; ++ i ) - { - lastindex[ i ] = 0xffffffff; - } - for( i = 0; i < insize-1; ++ i ) - { - symbols = (((unsigned int)in[i]) << 8) | ((unsigned int)in[i+1]); - index = lastindex[ symbols ]; - lastindex[ symbols ] = i; - jumptable[ i ] = index; - } - jumptable[ insize-1 ] = 0xffffffff; - - /* Create histogram */ - for( i = 0; i < 256; ++ i ) - { - histogram[ i ] = 0; - } - for( i = 0; i < insize; ++ i ) - { - ++ histogram[ in[ i ] ]; - } - - /* Find the least common byte, and use it as the code marker */ - marker = 0; - for( i = 1; i < 256; ++ i ) - { - if( histogram[ i ] < histogram[ marker ] ) - { - marker = i; - } - } - - /* Remember the repetition marker for the decoder */ - out[ 0 ] = marker; - - /* Start of compression */ - inpos = 0; - outpos = 1; - - /* Main compression loop */ - bytesleft = insize; - do - { - /* Get pointer to current position */ - ptr1 = &in[ inpos ]; - - /* Search history window for maximum length string match */ - bestlength = 3; - bestoffset = 0; - index = jumptable[ inpos ]; - while( (index != 0xffffffff) && ((inpos - index) < LZ_MAX_OFFSET) ) - { - /* Get pointer to candidate string */ - ptr2 = &in[ index ]; - - /* Quickly determine if this is a candidate (for speed) */ - if( ptr2[ bestlength ] == ptr1[ bestlength ] ) - { - /* Determine maximum length for this offset */ - offset = inpos - index; - maxlength = (bytesleft < offset ? bytesleft : offset); - - /* Count maximum length match at this offset */ - length = _LZ_StringCompare( ptr1, ptr2, 2, maxlength ); - - /* Better match than any previous match? */ - if( length > bestlength ) - { - bestlength = length; - bestoffset = offset; - } - } - - /* Get next possible index from jump table */ - index = jumptable[ index ]; - } - - /* Was there a good enough match? */ - if( (bestlength >= 8) || - ((bestlength == 4) && (bestoffset <= 0x0000007f)) || - ((bestlength == 5) && (bestoffset <= 0x00003fff)) || - ((bestlength == 6) && (bestoffset <= 0x001fffff)) || - ((bestlength == 7) && (bestoffset <= 0x0fffffff)) ) - { - out[ outpos ++ ] = (unsigned char) marker; - outpos += _LZ_WriteVarSize( bestlength, &out[ outpos ] ); - outpos += _LZ_WriteVarSize( bestoffset, &out[ outpos ] ); - inpos += bestlength; - bytesleft -= bestlength; - } - else - { - /* Output single byte (or two bytes if marker byte) */ - symbol = in[ inpos ++ ]; - out[ outpos ++ ] = symbol; - if( symbol == marker ) - { - out[ outpos ++ ] = 0; - } - -- bytesleft; - } - } - while( bytesleft > 3 ); - - /* Dump remaining bytes, if any */ - while( inpos < insize ) - { - if( in[ inpos ] == marker ) - { - out[ outpos ++ ] = marker; - out[ outpos ++ ] = 0; - } - else - { - out[ outpos ++ ] = in[ inpos ]; - } - ++ inpos; - } - - return outpos; -} diff --git a/flash.tos/lz.h b/flash.tos/lz.h deleted file mode 100644 index a697747..0000000 --- a/flash.tos/lz.h +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************* -* Name: lz.h -* Author: Marcus Geelnard -* Description: LZ77 coder/decoder interface. -* Reentrant: Yes -* $Id: lz.h,v 1.2 2004/05/25 22:36:44 marcus256 Exp $ -*------------------------------------------------------------------------- -* Copyright (c) 2003-2004 Marcus Geelnard -* -* This software is provided 'as-is', without any express or implied -* warranty. In no event will the authors be held liable for any damages -* arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, -* including commercial applications, and to alter it and redistribute it -* freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not -* claim that you wrote the original software. If you use this software -* in a product, an acknowledgment in the product documentation would -* be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not -* be misrepresented as being the original software. -* -* 3. This notice may not be removed or altered from any source -* distribution. -* -* Marcus Geelnard -* marcus.geelnard at home.se -*************************************************************************/ - -#ifndef _lz_h_ -#define _lz_h_ - -#ifdef __cplusplus -extern "C" { -#endif - - -/************************************************************************* -* Function prototypes -*************************************************************************/ - -int LZ_Compress( unsigned char *in, unsigned char *out, - unsigned int insize ); -int LZ_CompressFast( unsigned char *in, unsigned char *out, - unsigned int insize, unsigned int *work ); -void LZ_Uncompress( unsigned char *in, unsigned char *out, - unsigned int insize ); - - -#ifdef __cplusplus -} -#endif - -#endif /* _lz_h_ */ diff --git a/flash.tos/nonfree/cf68klib060.S b/flash.tos/nonfree/cf68klib060.S index 777ea66..30bcba2 100644 --- a/flash.tos/nonfree/cf68klib060.S +++ b/flash.tos/nonfree/cf68klib060.S @@ -392,7 +392,7 @@ address_error_exception_handler: move.l %a0,%d0 | Is this a real address error (%PC odd)? andi.l #1,%d0 bne real_68K_address_error | Yes - + | The CF5307 chip has a 'feature' which we need to cope with. For the two instructions.. | | MOVE.B/W/L (An)+, @@ -410,11 +410,20 @@ address_error_exception_handler: beq.s fix_predecrement | Yes cmpi.l #0x18,%d0 | Is postincrement? bne illegal_instruction_common | No,just normal - + +#if 1 +fix_predecrement: + +// move.l d0,-(sp) +// move.l reg_pc(a6),D0 +// bsr debug_display_disassemble_pc /****************************************************/ +// move.l (sp)+,d0 + +#else fix_postincrement: move.w (%a0),%d0 move.w %d0,%d1 - + lea width_conv_tab,%a1 | Get %D1 = 1,2 or 4 for byte lsr.l #8,%d1 lsr.l #4,%d1 @@ -444,6 +453,7 @@ fix_predecrement: bsr compute_reg_a7 fix_An: add.l %d1,(reg_a0,%a6,%d0.l*4) | Undo the predecrement +#endif bra illegal_instruction_common @@ -1235,6 +1245,11 @@ exception_frame_sizes: |################################################### .align 2 handle_stop: +#if 1 + addq.l #4,%a0 | jump STOP instruction + moveq.l #0x0,%d6 + jmp exception_handled +#else // TO FIX problem with 680x0 interrupt (stack ???) | The STOP instruction is particularly difficult to handle. We need to drop the | interrupt fence, so must assume that our private data is invalid once we've executed STOP. | In addition, there's no STOP D0 instruction - in order to stop the processor we @@ -1244,7 +1259,7 @@ handle_stop: move.l %a0,(return_address,%a6) move.w #0x4e75,%d0 | append an RTS move.w %d0,(stop_area+4,%a6) - + bsr cpushl_dc bsr cpushl_ic @@ -1270,6 +1285,7 @@ handle_stop_handled: move.l (return_address,%a6),%d0 move.l (%a7)+,%a6 move.l %d0,4(%a7) +#endif handle_stop_nasty: move %sr,%d0 | This instruction may cause a privilege violation trap! If so | we'll come back to handle_stop_got_exception @@ -1277,7 +1293,7 @@ handle_stop_done: and.l #0x871f,%d0 | Keep only T and IRQ bits plus %CCR bits move %d0,%sr | Back into user mode please! move.l (%a7)+,%d0 - rts + rts | return address handle_stop_got_exception: bsr compute_reg_a7 | Came here because we trapped. @@ -13656,7 +13672,14 @@ popm_long: move.w 2(%a0),%d1 addq.l #2,%a0 jsr compute_reg_a7 +#if 1 // fix stack on odd address + moveq #1,%d0 + add.l reg_a7(%a6),%d0 + bclr #0,%d0 + move.l %d0,%a2 +#else move.l reg_a7(%a6),%a2 +#endif addq.l #2,%a0 and.l #0xffff,%d1 lea reg_d0(%a6),%a4 diff --git a/flash.tos/nonfree/firebee1.rbf b/flash.tos/nonfree/firebee1.rbf new file mode 100644 index 0000000..b6147cb Binary files /dev/null and b/flash.tos/nonfree/firebee1.rbf differ diff --git a/flash.tos/nonfree/tos404.bin b/flash.tos/nonfree/tos404.bin new file mode 100644 index 0000000..1234059 Binary files /dev/null and b/flash.tos/nonfree/tos404.bin differ diff --git a/flash.tos/srec.c b/flash.tos/srec.c index 02dd2c5..e0550cc 100644 --- a/flash.tos/srec.c +++ b/flash.tos/srec.c @@ -1,5 +1,5 @@ /* CT60, HEX part -* Didier Mequignon 2007 April, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2010, e-mail: aniplay@wanadoo.fr * * 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 @@ -98,7 +98,7 @@ void getbytes(char *line,long addr_bytes) p=(unsigned char *)buffer_flash; p+=(offset-FLASH_ADR); if((offset >= FLASH_ADR) - && ((offset+count) < (FLASH_ADR2+FLASH_SIZE2))) + && ((offset+count) < (FLASH_ADR+FLASH_SIZE-PARAM_SIZE))) memcpy(p, &asciiByte[j], count); } diff --git a/flash.tos/tos/LICENSE b/flash.tos/tos/LICENSE deleted file mode 100644 index b1e3f5a..0000000 --- a/flash.tos/tos/LICENSE +++ /dev/null @@ -1,504 +0,0 @@ - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -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 and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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 Library or any portion -of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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 with -this License. - - 11. 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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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 - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), 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 Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. 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. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! - - diff --git a/flash.tos/tos/LzmaDecode.c b/flash.tos/tos/LzmaDecode.c new file mode 100644 index 0000000..4825e31 --- /dev/null +++ b/flash.tos/tos/LzmaDecode.c @@ -0,0 +1,379 @@ +/* + LzmaDecode.c + LZMA Decoder (optimized for Speed version) + + LZMA SDK 4.22 Copyright (c) 1999-2005 Igor Pavlov (2005-06-10) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this Code, expressly permits you to + statically or dynamically link your Code (or bind by name) to the + interfaces of this file without subjecting your linked Code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#include "LzmaDecode.h" + +#ifndef Byte +#define Byte unsigned char +#endif + +#define kNumTopBits 24 +#define kTopValue ((UInt32)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*Buffer++) + +#define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ + { int ii; for(ii = 0; ii < 5; ii++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} + +#define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } + +#define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 + +#define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } + +#define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) +#define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; +#define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; + +#define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ + { UpdateBit0(p); mi <<= 1; A0; } else \ + { UpdateBit1(p); mi = (mi + mi) + 1; A1; } + +#define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) + +#define RangeDecoderBitTreeDecode(probs, numLevels, res) \ + { int i = numLevels; res = 1; \ + do { CProb *pp = probs + res; RC_GET_BIT(pp, res) } while(--i != 0); \ + res -= (1 << numLevels); } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData) +{ + unsigned char prop0 = propsData[0]; + if (prop0 >= (9 * 5 * 5)) + return LZMA_RESULT_DATA_ERROR; + { + for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)); + for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9); + propsRes->lc = prop0; + } + return LZMA_RESULT_OK; +} + +#define kLzmaStreamWasFinishedId (-1) + +int LzmaDecode(CLzmaDecoderState *vs, + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) +{ + CProb *p = vs->Probs; + SizeT nowPos = 0; + Byte previousByte = 0; + UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; + UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; + int lc = vs->Properties.lc; + int state = 0; + UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; + int len = 0; + const Byte *Buffer; + const Byte *BufferLim; + UInt32 Range; + UInt32 Code; + + *inSizeProcessed = 0; + *outSizeProcessed = 0; + + { + UInt32 i; + UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); + for (i = 0; i < numProbs; i++) + p[i] = kBitModelTotal >> 1; + } + + RC_INIT(inStream, inSize); + + while(nowPos < outSize) + { + CProb *prob; + UInt32 bound; + int posState = (int)((nowPos) & posStateMask); + + prob = p + IsMatch + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + int symbol = 1; + UpdateBit0(prob) + prob = p + Literal + (LZMA_LIT_SIZE * + ((((nowPos) & literalPosMask) << lc) + (previousByte >> (8 - lc)))); + + if (state >= kNumLitStates) + { + int matchByte; + matchByte = outStream[nowPos - rep0]; + do + { + int bit; + CProb *probLit; + matchByte <<= 1; + bit = (matchByte & 0x100); + probLit = prob + 0x100 + bit + symbol; + RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) + } + while (symbol < 0x100); + } + while (symbol < 0x100) + { + CProb *probLit = prob + symbol; + RC_GET_BIT(probLit, symbol) + } + previousByte = (Byte)symbol; + + outStream[nowPos++] = previousByte; + if (state < 4) state = 0; + else if (state < 10) state -= 3; + else state -= 6; + } + else + { + UpdateBit1(prob); + prob = p + IsRep + state; + IfBit0(prob) + { + UpdateBit0(prob); + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + state = state < kNumLitStates ? 0 : 3; + prob = p + LenCoder; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG0 + state; + IfBit0(prob) + { + UpdateBit0(prob); + prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; + IfBit0(prob) + { + UpdateBit0(prob); + + if (nowPos == 0) + return LZMA_RESULT_DATA_ERROR; + + state = state < kNumLitStates ? 9 : 11; + previousByte = outStream[nowPos - rep0]; + outStream[nowPos++] = previousByte; + + continue; + } + else + { + UpdateBit1(prob); + } + } + else + { + UInt32 distance; + UpdateBit1(prob); + prob = p + IsRepG1 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep1; + } + else + { + UpdateBit1(prob); + prob = p + IsRepG2 + state; + IfBit0(prob) + { + UpdateBit0(prob); + distance = rep2; + } + else + { + UpdateBit1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = p + RepLenCoder; + } + { + int numBits, offset; + CProb *probLen = prob + LenChoice; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + numBits = kLenNumLowBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenChoice2; + IfBit0(probLen) + { + UpdateBit0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + numBits = kLenNumMidBits; + } + else + { + UpdateBit1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + numBits = kLenNumHighBits; + } + } + RangeDecoderBitTreeDecode(probLen, numBits, len); + len += offset; + } + + if (state < 4) + { + int posSlot; + state += kNumLitStates; + prob = p + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + rep0 = (2 | ((UInt32)posSlot & 1)); + if (posSlot < kEndPosModelIndex) + { + rep0 <<= numDirectBits; + prob = p + SpecPos + rep0 - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + RC_NORMALIZE + Range >>= 1; + rep0 <<= 1; + if (Code >= Range) + { + Code -= Range; + rep0 |= 1; + } + } + while (--numDirectBits != 0); + prob = p + Align; + rep0 <<= kNumAlignBits; + numDirectBits = kNumAlignBits; + } + { + int i = 1; + int mi = 1; + do + { + CProb *prob3 = prob + mi; + RC_GET_BIT2(prob3, mi, ; , rep0 |= i); + i <<= 1; + } + while(--numDirectBits != 0); + } + } + else + rep0 = posSlot; + if (++rep0 == (UInt32)(0)) + { + /* it's for stream version */ + len = kLzmaStreamWasFinishedId; + break; + } + } + + len += kMatchMinLen; + if (rep0 > nowPos) + return LZMA_RESULT_DATA_ERROR; + + do + { + previousByte = outStream[nowPos - rep0]; + len--; + outStream[nowPos++] = previousByte; + } + while(len != 0 && nowPos < outSize); + } + } + RC_NORMALIZE; + + *inSizeProcessed = (SizeT)(Buffer - inStream); + *outSizeProcessed = nowPos; + return LZMA_RESULT_OK; +} diff --git a/flash.tos/tos/LzmaDecode.h b/flash.tos/tos/LzmaDecode.h new file mode 100644 index 0000000..e70dc14 --- /dev/null +++ b/flash.tos/tos/LzmaDecode.h @@ -0,0 +1,78 @@ +/* + LzmaDecode.h + LZMA Decoder interface + + LZMA SDK 4.21 Copyright (c) 1999-2005 Igor Pavlov (2005-06-08) + http://www.7-zip.org/ + + LZMA SDK is licensed under two licenses: + 1) GNU Lesser General Public License (GNU LGPL) + 2) Common Public License (CPL) + It means that you can select one of these two licenses and + follow rules of that license. + + SPECIAL EXCEPTION: + Igor Pavlov, as the author of this code, expressly permits you to + statically or dynamically link your code (or bind by name) to the + interfaces of this file without subjecting your linked code to the + terms of the CPL or GNU LGPL. Any modifications or additions + to this file, however, are subject to the LGPL or CPL terms. +*/ + +#ifndef __LZMADECODE_H +#define __LZMADECODE_H + +/* #define _LZMA_PROB32 */ +/* It can increase speed on some 32-bit CPUs, + but memory usage will be doubled in that case */ + +#ifndef UInt32 +#ifdef _LZMA_UINT32_IS_ULONG +#define UInt32 unsigned long +#else +#define UInt32 unsigned int +#endif +#endif + +#ifndef SizeT +#define SizeT UInt32 +#endif + +#ifdef _LZMA_PROB32 +#define CProb UInt32 +#else +#define CProb unsigned short +#endif + +#define LZMA_RESULT_OK 0 +#define LZMA_RESULT_DATA_ERROR 1 + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LZMA_PROPERTIES_SIZE 5 + +typedef struct _CLzmaProperties +{ + int lc; + int lp; + int pb; +} CLzmaProperties; + +int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData); + +#define LzmaGetNumProbs(Properties) (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp))) + +#define kLzmaNeedInitId (-2) + +typedef struct _CLzmaDecoderState +{ + CLzmaProperties Properties; + CProb *Probs; +} CLzmaDecoderState; + +int LzmaDecode(CLzmaDecoderState *vs, + const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, + unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed); + +#endif diff --git a/flash.tos/tos/aes2.S b/flash.tos/tos/aes2.S index de16ae1..aaa1b79 100644 --- a/flash.tos/tos/aes2.S +++ b/flash.tos/tos/aes2.S @@ -1,6 +1,6 @@ /* TOS 4.04 AES patch for Eiffel POWER OFF alert for the CT60 board * color icons and GEM dispatcher on Coldfire -* Didier Mequignon 2004 February, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2004-2011, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +19,7 @@ .globl det_evnt_multi,patch_tran_check,patch_gr_cicon,patch_set_video #ifdef COLDFIRE + .globl userdef_call .globl det_aes .globl _dsptch,_savestate,_switchto,_gotopgm,_psetup .globl _far_mchange,_far_bchange,_forkq @@ -27,7 +28,7 @@ #include "vars.h" -//#define DEBUG +#undef DEBUG #define saddr 0x08 #define daddr 0x0C @@ -73,7 +74,9 @@ #define P_BLEN 0x1C // length of BSS .chip 68060 -#endif + +#endif /* COLDFIRE */ + .text alert_power_en: @@ -93,6 +96,8 @@ debug3: .asciz "AES gotopgm 0x" debug4: .ascii "AES psetup" .byte 13,10,0 debug5: .asciz "AES #0x" +debug6: .asciz "AES userdef 0x" +debug7: .asciz "AES end userdef 0x" .align 2 @@ -185,8 +190,8 @@ det_evnt_multi: bne.s .no_pci_drivers .pci_drivers: jsr 46(A0) // drivers PCI in flash, call event_aes - movem.l (SP)+,D0-D2/A0-A2 .no_pci_drivers: + movem.l (SP)+,D0-D2/A0-A2 move.l phystop,A1 cmp.l #0xCAFEFADE,power_flag(A1) bne.s .no_power_off @@ -596,11 +601,6 @@ tab_rgb: patch_set_video: - move.w #3,-(SP) // Logbase - trap #14 - addq.l #2,SP - cmp.l #0x01000000,D0 - bcs.s .no_pci_drivers2 move.l #0x5F504349,D0 lea 0xED0000,A0 // 128 KB cmp.l (A0),D0 // _PCI @@ -626,6 +626,62 @@ patch_set_video: #ifdef COLDFIRE +#if 0 +userdef_call: + + link A6,#-16 +#ifdef DEBUG + lea debug6(PC),A0 + bsr debug_display_string + move.l 4(A6),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +#if 0 + move.l SP,-8(A6) // save SSP + move.w #3,-(SP) // TT ram if possible + move.l #0x8000,-(SP) + move.w #0x44,-(SP) // Mxalloc + trap #1 + addq.l #8,SP + move.l D0,-4(A6) + beq.s .no_mem + move.l D0,SP +.no_mem: +#endif + move.l 12(A6),-(SP) // param + move.l 8(A6),A0 + jsr (A0) + move.l D0,-12(A6) + addq.l #4,SP +#if 0 + move.l -4(A6),D0 + beq.s .no_free + move.l -8(A6),SP // restore SSP + move.l D0,-(SP) + move.w #0x49,-(SP) // Mfree + trap #1 + addq.l #6,SP +.no_free: +#endif +#ifdef DEBUG + lea debug7(PC),A0 + bsr debug_display_string + move.l 4(A6),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + move.l -12(A6),D0 + unlk A6 + rts +#endif + dc.l 0x58425241 // XBRA dc.l 0x5F43465F // _CF_ dc.l 0x00E346A8 // TOS AES entry point @@ -1053,6 +1109,6 @@ _forkq: .fq1: move.l (SP)+,A5 unlk a6 - rts - -#endif + rts + +#endif /* COLDFIRE */ diff --git a/flash.tos/tos/ataboot.S b/flash.tos/tos/ataboot.S index 14b9f0c..c305960 100644 --- a/flash.tos/tos/ataboot.S +++ b/flash.tos/tos/ataboot.S @@ -1378,33 +1378,6 @@ lb4: moveq #0,D0 movec D0,CACR lb3: -#if 0 // removed for TOS in RAM - moveq #0xC,D0 // disable_mmu - and.l D1,D0 // bi_cputype - beq.s lb2 - moveq #0,D0 // 68040/60 - movec D0,TC - move.l #0x807FE040,D0 // cache inhibit precise - movec D0,ITT0 - movec D0,DTT0 - move.l #0x007FE040,D0 - movec D0,ITT1 - movec D0,DTT1 - bra.s lb1 -lb2: - subq.l #4,SP - pmove TC,(SP) - bclr #7,(SP) - pmove (SP),TC - addq.l #4,SP - btst #1,D1 - beq.s lb1 - clr.l -(SP) - pmove (SP),TT0 - pmove (SP),TT1 - addq.l #4,SP -lb1: -#endif clr.l resvalid.w lea copyall(PC),A0 lea copyallend(PC),A1 @@ -2193,16 +2166,15 @@ check_video_screen: move #0x58,-(SP) // Vsetmode trap #14 addq #4,SP - move D0,-(SP) + move D0,-(SP) // old modecode move.l (video_modecode-_bss).w(A5),D0 + cmp.l #0x01000000,_v_bas_ad + bcc graphic_card2 or.l #0xFFFF0000,D0 try_again: move.l (internal_clock_frequency-_bss).w(A5),D1 move.l (external_clock_frequency-_bss).w(A5),D2 - lea init_screen,A0 - add.l #0xE80000,A0 - sub.l #_ct60tos_half_flash,A0 - jsr (A0) + jsr init_screen move (SP)+,D1 // old modecode tst D0 bpl.s screen_ok @@ -2211,11 +2183,22 @@ try_again: cmp.l #40,(internal_clock_frequency-_bss).w(A5) // MHz bcs.s screen_error move.l (video_modecode-_bss).w(A5),D0 - or.l #0xFFFF8000,D0 // CLOCK_FORCED + or.l #0xFFFF8000,D0 // CLOCK_FORCED + move D1,-(SP) // old modecode bra.s try_again +graphic_card2: + move D0,-(SP) // new modecode + move #3,-(SP) + clr.l -(SP) + clr.l -(SP) + move #5,-(SP) // Setscreen + trap #14 + lea 14(SP),SP + move (SP)+,D1 // old modecode + bra.s screen_ok screen_error: move D0,-(SP) - move D1,-(SP) + move D1,-(SP) // old modecode move #3,-(SP) clr.l -(SP) clr.l -(SP) @@ -2230,12 +2213,12 @@ screen_error: pea error_58(PC) bsr _printline addq #4,SP - bra.s screen_end + bra screen_end memory_error: pea error_59(PC) bsr _printline addq #4,SP - bra.s screen_end + bra screen_end screen_ok: move D0,-(SP) // clock selected pea screen_ptr(PC) @@ -2247,6 +2230,10 @@ screen_ok: .short 0xA000 // lineA moveq #0,D2 move (A0),D0 // number of planes + cmp #16,D0 + bls.s not_tc + moveq #24,D0 +not_tc: bset D0,D2 // number of colors moveq #0,D0 move dev_tab(A0),D0 // width pixels workstation info @@ -2265,11 +2252,16 @@ screen_ok: bsr display_deci pea screen_info_4(PC) bsr _printline - lea 20(SP),SP + lea 20(SP),SP // printlines(s) stack fix moveq #0,D0 - move (SP)+,D0 + move (SP)+,D0 // clock selected + lea screen_info_6(PC),A0 + cmp.l #0x01000000,_v_bas_ad + bcc graphic_card bsr display_deci - pea screen_info_5(PC) + lea screen_info_5(PC),A0 +graphic_card: + pea (A0) bsr _printline addq #4,SP screen_end: @@ -7159,6 +7151,7 @@ screen_info_4: .asciz " colors, " screen_info_5: .ascii " MHz" +screen_info_6: .byte 13,10,0 .align 2 @@ -7203,6 +7196,8 @@ islower: rotchar: .long 0x7C2F2D5C /* |/-\ */ + + .bss .align 2 diff --git a/flash.tos/tos/bios2.S b/flash.tos/tos/bios2.S index bed7b26..18685a1 100644 --- a/flash.tos/tos/bios2.S +++ b/flash.tos/tos/bios2.S @@ -1,5 +1,5 @@ -/* TOS 4.04 Bios bconout patch for the CT60 board -* Didier Mequignon 2001 December, e-mail: aniplay@wanadoo.fr +/* TOS 4.04 Bios bconout patch for the CT60 and Coldfire boards +* Didier Mequignon 2001-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,10 @@ .text - .globl _bconout2 + .globl _test_accel + .globl _sb_scrup,_sb_scrdn,_sb_neg_cell,_sb_move_cursor,_sb_cell,_sb_blank + .globl _sb_scrup_c,_sb_scrdn_c,_sb_neg_cell_c,_sb_move_cursor_c,_sb_cell_c,_sb_blank_c,_sb_blank_internal + .globl get_cookie #ifdef COLDFIRE .globl det_bios @@ -100,7 +103,7 @@ det_bios: bsr debug_display_char move.l (SP)+,D0 .bconout: -#endif +#endif /* DEBUG */ asl.l #2,D0 add.l D0,A0 move.l (A0),D0 @@ -200,52 +203,18 @@ wait_key: #endif /* COLDFIRE */ -_bconout2: - move.w 6(SP),D1 -#ifdef COLDFIRE - tst.l con_state - bne.s .con_state_ok // to fix - bsr _con_state_init // normally in Setscreen -.con_state_ok: -#endif - move.w D1,-(SP) - bsr _cputc - addq.l #2,SP - rts - -get_cookie: - - move.l D1,-(SP) - move.l D0,D1 - move.l cookie,D0 - beq.s .cookie_not_found - move.l D0,A0 -.loop_cookie: - tst.l (A0) - beq.s .cookie_not_found - cmp.l (A0),D1 - bne.s .next_cookie - move.l 4(A0),D0 - bra.s .end_cookie -.next_cookie: - addq.l #8,A0 - bra.s .loop_cookie -.cookie_not_found: - moveq #0,D0 - move.l D0,A0 -.end_cookie: - move.l (SP)+,D1 - tst.l D0 - rts - +_test_accel: test_accel: + move.l phystop,A0 + move.l hardware_type(a0),D0 + and.l #SUPERVIDEL,D0 + bne.s .no_pci_drivers move.l _v_bas_ad,D0 - cmp.l #0x01000000,D0 - bcs.s .no_pci_drivers + cmp.l #0x01000000,D0 + bcs.s .no_pci_drivers move.l #0x5F504349,D0 // cookie _PCI - bsr get_cookie - move.l A0,D0 + jsr get_cookie beq.s .no_pci_drivers move.l #0x5F504349,D0 lea 0xED0000,A0 // 128 KB @@ -266,5 +235,433 @@ test_accel: .no_pci_drivers: moveq #0,D0 rts + +#ifndef COLDFIRE /* conout.c */ + +#define LINEA_VAR 0x3E86 +#define _v_planes LINEA_VAR // number of planes +#define _v_rez_hz LINEA_VAR-12 // width screen +#define _v_col_bg LINEA_VAR-38 // current background color +#define _v_cel_mx LINEA_VAR-44 // maximum cell # in x (minimum is 0) +#define _v_cel_my LINEA_VAR-42 // maximum cell # in y (minimum is 0) +#define _v_cel_ht LINEA_VAR-46 // cell height (width is 8) +#define _v_lcol_bg LINEA_VAR+0xB0A + +_sb_scrup: + + move.l A0,-(SP) + move.l A1,-(SP) + ext.l D1 + move.l D1,-(SP) // top_line +#ifndef COLDFIRE /* just for backward compatibility because the VDI driver part overwrite VT52 */ + bsr test_accel + beq.s .no_accel_up + moveq #0,D0 + move.w _v_cel_my,D0 + sub.l D1,D0 // top_line + mulu _v_cel_ht,D0 + move.l D0,-(SP) // h + moveq #0,D0 + move.w _v_rez_hz,D0 + move.l D0,-(SP) // w + move.l D1,D0 + move.l D0,-(SP) // dst_y + mulu _v_cel_ht,D0 + clr.l -(SP) // dst_x + move.l D1,D0 + addq.l #1,D0 + mulu _v_cel_ht,D0 + move.l D0,-(SP) // src_y + clr.l -(SP) // src_x + jsr 28(A0) // move_screen + lea 24(SP),SP + tst.w D0 + beq.s .no_accel_up + move.w _v_cel_my,D3 // boty + move.w _v_cel_mx,D2 // botx + move.w D3,D1 // topy + moveq #0,D0 // topx + bsr _sb_blank + bra.s .sb_scrup_end +.no_accel_up: +#endif /* COLDFIRE */ + jsr _sb_scrup_c +.sb_scrup_end: + addq.l #4,SP + move.l (SP)+,A1 + move.l (SP)+,A0 + rts + +_sb_scrdn: + + move.l A0,-(SP) + move.l A1,-(SP) + ext.l D1 // start_line + move.l D1,-(SP) +#ifndef COLDFIRE /* just for backward compatibility because the VDI driver part overwrite VT52 */ + bsr test_accel + beq.s .no_accel_dwn + moveq #0,D0 + move.w _v_cel_my,D0 + sub.l D1,D0 // start_line + mulu _v_cel_ht,D0 + move.l D0,-(SP) // h + moveq #0,D0 + move _v_rez_hz,D0 + move.l D0,-(SP) // w + move.l D1,D0 + addq.l #1,D0 + move.l D0,-(SP) // dst_y + mulu _v_cel_ht,D0 + clr.l -(SP) // dst_x + move.l D1,D0 + mulu _v_cel_ht,D0 + move.l D0,-(SP) // src_y + clr.l -(SP) // src_x + jsr 28(A0) // move_screen + lea 24(SP),SP + tst.w D0 + beq.s .no_accel_dwn + move.l D1,D3 // topy, boty + move.w _v_cel_mx,D2 // botx + moveq #0,D0 // topx + bsr _sb_blank + bra.s .sb_scrdn_end +.no_accel_dwn: +#endif /* COLDFIRE */ + jsr _sb_scrdn_c +.sb_scrdn_end: + addq.l #4,SP + move.l (SP)+,A1 + move.l (SP)+,A0 + rts + +_sb_neg_cell: + + move.l D0,-(SP) + move.l D1,-(SP) + move.l A1,-(SP) + jsr _sb_neg_cell_c + addq.l #4,SP + move.l (SP)+,D1 + move.l (SP)+,D0 + rts + +_sb_move_cursor: + +#ifdef COLDFIRE + lea -16(SP),SP + movem.l D0-D1/A0-A1,(SP) +#else + movem.l D0-D1/A0-A1,-(SP) +#endif + move.l D1,-(sp) + move.l D0,-(sp) + jsr _sb_move_cursor_c + addq.l #8,SP +#ifdef COLDFIRE + movem.l (SP),D0-D1/A0-A1 + lea 16(SP),SP +#else + movem.l (SP)+,D0-D1/A0-A1 +#endif + rts + +_sb_cell: + + move.l A0,-(SP) + move.l A1,-(SP) + move.l D7,-(SP) + move.l D6,-(SP) + move.l A1,-(SP) + move.l A0,-(SP) + jsr _sb_cell_c + lea 16(SP),SP + move.l (SP)+,A1 + move.l (SP)+,A0 + rts + +_sb_blank: + +#ifdef COLDFIRE + lea -16(SP),SP + movem.l D0-D1/A0-A1,(SP) +#else + movem.l D0-D1/A0-A1,-(SP) +#endif + ext.l D0 + ext.l D1 + ext.l D2 + ext.l D3 + move.l D3,-(SP) // boty + move.l D2,-(SP) // botx + move.l D1,-(SP) // topy + move.l D0,-(SP) // topx +#ifndef COLDFIRE /* just for backward compatibility because the VDI driver part overwrite VT52 */ + bsr test_accel + beq.s .no_blank_accel + move.l D3,D0 // boty + sub.l D1,D0 // topy + addq.l #1,D0 + mulu _v_cel_ht,D0 + move.l D0,-(SP) // h + move.l D2,D0 // botx + sub.l 4(SP),D0 // topx + addq.l #1,D0 + asl.l #3,D0 // * 8 + move.l D0,-(SP) // w + move.l D1,D0 // topy + mulu _v_cel_ht,D0 + move.l D0,-(SP) // y + moveq #0,D0 + move.l 12(SP),D0 // topx + asl.l #3,D0 // * 8 + move.l D0,-(SP) // x + moveq #0,D0 + move.w _v_col_bg,D0 // for 256 colors + cmp.w #16,_v_planes + bcs.s .sb_blank_256 + move.l _v_lcol_bg,D0 // for 65K et 16M colors +.sb_blank_256: + move.l D0,-(SP) + jsr 22(A0) // clear_screen + lea 20(SP),SP + tst.w D0 + bne.s .sb_blank_end +.no_blank_accel: +#endif /* COLDFIRE */ + jsr _sb_blank_c +.sb_blank_end: + lea 16(SP),SP +#ifdef COLDFIRE + movem.l (SP),D0-D1/A0-A1 + lea 16(SP),SP +#else + movem.l (SP)+,D0-D1/A0-A1 +#endif + rts + +/* wrapper used when calling the blanking primitive from C */ +/* void sb_blank_internal(short x1, short y1, short x2, short y2) */ +_sb_blank_internal: + +#ifdef COLDFIRE + lea -44(SP),SP + movem.l D2-D7/A2-A6,(SP) +#else + movem.l D2-D7/A2-A6,-(SP) +#endif + movem.l 48(SP),D0-D4 + bsr _sb_blank +#ifdef COLDFIRE + movem.l (SP),D2-D7/A2-A6 + lea 44(SP),SP +#else + movem.l (SP)+,D2-D7/A2-A6 +#endif + rts + +#ifdef COLDFIRE + + .globl _bconout2,_bconout5,normal_ascii,_blink + +test_v_bas_ad: + + cmp.l #0x01000000,_v_bas_ad + rts + +_bconout2: + + tst.l con_state // to fix, normally in Setscreen + bne.s .con_state_ok + lea normal_ascii,A0 + move.l A0,con_state // Init conout state machine +.con_state_ok: +// cmp.w #16,_v_planes +// bcc.s .bconout2 + bsr.s test_v_bas_ad + bcc.s .bconout2 // graphic card +.wait_uart: + move.w 6(SP),D1 +.wait_uart2: + move.b MCF_UART_USR0,D0 + and.b #MCF_UART_USR_TXRDY,D0 + beq.s .wait_uart2 + move.b D1,MCF_UART_UTB0 // send the character + rts +.bconout2: + jmp 0xE08D4C // default TOS routine +_bconout5: + +// cmp.w #16,_v_planes +// bcc.s .bconout5 + bsr.s test_v_bas_ad + bcs.s .wait_uart // no graphic card +.bconout5: + jmp 0xE08D40 // default TOS routine + +normal_ascii: + +// cmp.w #16,_v_planes +// bcc.s .normal_ascii + bsr.s test_v_bas_ad + bcs.s .wait_uart2 // no graphic card +.normal_ascii: + jmp 0xE08D62 // default TOS routine + +_blink: + + bsr.s test_v_bas_ad + bcs.s .bl_out // no graphic card + jmp 0xE090F2 // default TOS routine +.bl_out: + rts + +#endif /* COLDFIRE */ + + .globl _memmove,_memcpy + +_memmove: + lea -36(SP),SP + movem.l D2-D6/A2-A5,(SP) + move.l 4+36(SP),A5 // d + move.l 8+36(SP),A4 // s + move.l 12+36(SP),D5 // size + ble.s .mm1 + cmp.l A4,A5 + bls.s .cp0 + move.l A4,A0 // s + add.l D5,A0 // + size + cmp.l A0,A5 + bcc.s .cp0 + move.l A5,A1 // d, if inc copy overlap + add.l D5,A1 // + size +.mm2: + move.b -(A0),-(A1) + subq.l #1,D5 + bgt.s .mm2 + bra.s .mm1 +.mm3: + cmp.l #16,D5 + bhi.s .cp0 // fast memcpy +.mm4: + move.b (A4)+,(A5)+ + subq.l #1,D5 + bgt.s .mm4 +.mm1: + movem.l (SP),D2-D6/A2-A5 + lea 36(SP),SP + rts + +_memcpy: + + lea -36(SP),SP + movem.l D2-D6/A2-A5,(SP) + move.l 4+36(SP),A5 // d + move.l 8+36(SP),A4 // s + move.l 12+36(SP),D5 // size + ble .cp1 +.cp0: + move.l D5,D6 + move.l #256,D4 + bra.s .cp7 +.cp4: + movem.l (A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,(A5) + movem.l 32(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,32(A5) + movem.l 64(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,64(A5) + movem.l 96(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,96(A5) + movem.l 128(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,128(A5) + movem.l 160(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,160(A5) + movem.l 192(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,192(A5) + movem.l 224(A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,224(A5) + add.l D4,A4 + add.l D4,A5 +.cp7: + sub.l D4,D5 + bpl.s .cp4 + add.l D4,D5 + beq.s .cp1 + moveq #32,D4 + lsr.l #5,D5 // / 32 + beq.s .cp6 + bra.s .cp5 +.cp3: + movem.l (A4),D0-D3/A0-A3 + movem.l D0-D3/A0-A3,(A5) + add.l D4,A4 + add.l D4,A5 +.cp5: + subq.l #1,D5 + bpl.s .cp3 +.cp6: + moveq #31,D0 + and.l D6,D0 + lea .cp2(PC),A0 + move.l D0,D2 + bclr #0,D2 + sub.l D2,A0 + jmp (A0) + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ + move.w (A4)+,(A5)+ +.cp2: + bclr #0,D0 + beq.s .cp1 + move.b (A4)+,(A5)+ +.cp1: + movem.l (SP),D2-D6/A2-A5 + lea 36(SP),SP + rts + +#else /* conout.S */ + + .globl _bconout2 + +_bconout2: +#ifndef COLDFIRE + move.l phystop,A0 + move.l hardware_type(A0),D1 + and.l #SUPERVIDEL,d1 + bne.s .bconout2 +#endif /* COLDFIRE */ + move.w 6(SP),D1 +#ifdef COLDFIRE + tst.l con_state // to fix + bne.s .con_state_ok + bsr _con_state_init // normally in Setscreen +.con_state_ok: +#endif /* COLDFIRE */ + move.w D1,-(SP) + bsr _cputc + addq.l #2,SP + rts +#ifndef COLDFIRE +.bconout2: + jmp 0xE08D4C // default TOS routine for the Supervidel +#endif + #include "conout.S" + +#endif /* conout.c */ diff --git a/flash.tos/tos/blitter2.S b/flash.tos/tos/blitter2.S index 4d1bc53..ef8ff58 100644 --- a/flash.tos/tos/blitter2.S +++ b/flash.tos/tos/blitter2.S @@ -1,5 +1,5 @@ -/* TOS 4.04 Blitter patch for the CT60 board -* Didier Mequignon 2002 December, e-mail: aniplay@wanadoo.fr +/* TOS 4.04 Blitter patch for the CT60 and Coldfire boards +* Didier Mequignon 2002/2011, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,6 @@ .globl logo_atari .globl det_vdi -#include "main.h" #include "vars.h" #ifdef COLDFIRE @@ -39,6 +38,8 @@ .text +#ifndef COLDFIRE /* for reduce boot size, blitter not exist */ + get_font_6x6_a0: move.l A2,-(SP) @@ -128,21 +129,9 @@ copy_fonts: movem.l D0-D3/A0-A2,-(SP) #endif move.l phystop,D0 - sub.l #RESERVE_MEM_FONTS,D0 -#ifndef COLDFIRE - move.l _sysbase,A0 // header ROM - move.l 0x24(A0),A0 // kbshift - move.b (A0),D1 - and.b #0xF,D1 - cmp.b #0x3,D1 // SHIFT-SHIFT - bne.s .sdram - sub.l #RESERVE_MEM-RESERVE_MEM_FONTS,D0 -.sdram: -#endif - move.l D0,_memtop move.l D0,A1 move.l D0,D1 - lea 0xE4AFEC,A0 + lea 0xE4AFEC,A0 // f6x6 FONT_HEAD #ifdef COLDFIRE move.l #0xFFF,D0 cf1: @@ -156,7 +145,7 @@ cf1: dbf D0,cf1 #endif move.l A1,D2 - lea 0xE09410,A0 + lea 0xE09410,A0 // f16x32 FONT_HEAD moveq #0x17,D0 cf2: move.l (A0)+,(A1)+ @@ -192,7 +181,7 @@ cf3: clr.l flag_statvec(A2) clr.l power_flag(A2) lea adr_fonts(A2),A2 - lea 0xE4AFEC,A0 + lea 0xE4AFEC,A0 // f6x6 FONT_HEAD move.l D1,A1 movem.l 0x48(A0),D0/D3 sub.l A0,D0 @@ -202,7 +191,7 @@ cf3: movem.l D0/D3,0x48(A1) move.l A1,(A2)+ add.l #0xE4B6C8-0xE4AFEC,D1 - add.l #0xE4B6C8-0xE4AFEC,A0 + add.l #0xE4B6C8-0xE4AFEC,A0 // f8x8 FONT_HEAD move.l D1,A1 movem.l 0x48(A0),D0/D3 sub.l A0,D0 @@ -212,7 +201,7 @@ cf3: movem.l D0/D3,0x48(A1) move.l A1,(A2)+ add.l #0xE4D124-0xE4B6C8,D1 - add.l #0xE4D124-0xE4B6C8,A0 + add.l #0xE4D124-0xE4B6C8,A0 // f8x16 FONT_HEAD move.l D1,A1 movem.l 0x48(A0),D0/D3 sub.l A0,D0 @@ -221,7 +210,7 @@ cf3: add.l D1,D3 movem.l D0/D3,0x48(A1) move.l A1,(A2)+ - lea 0xE09410,A0 + lea 0xE09410,A0 // f16x32 FONT_HEAD move.l D2,A1 movem.l D0/D3,0x48(A1) move.l A1,(A2)+ @@ -235,12 +224,14 @@ cf3: #endif rts +#endif /* COLDFIRE */ + logo_atari: #ifndef COLDFIRE cmp.l #0x01000000,_v_bas_ad bcc.s .no_logo - move.l _memtop,A0 + move.l phystop,A0 add.l #0x6408,A0 pea.l (A0) jmp 0xE00666 @@ -248,8 +239,8 @@ logo_atari: #endif jmp 0xE0066E -//#ifndef COLDFIRE /* there are a new Coldfire VDI inside the PCI part */ - +#ifndef COLDFIRE /* for reduce boot size, blitter not exist */ + dc.l 0x58425241 // XBRA #ifdef COLDFIRE dc.l 0x5F43465F // _CF_ @@ -541,8 +532,8 @@ free_stram: #endif rts -//#endif /* COLDFIRE */ - +#endif /* COLDFIRE */ + #ifdef COLDFIRE #ifdef DEBUG diff --git a/flash.tos/tos/boot.S b/flash.tos/tos/boot.S deleted file mode 100644 index 379a278..0000000 --- a/flash.tos/tos/boot.S +++ /dev/null @@ -1,95 +0,0 @@ -/* TOS 4.04 Boot order patch for the CT60 board -* HD vectors patchs for the Fire Engine Coldfire board -* Didier Mequignon 2003-2006, e-mail: aniplay@wanadoo.fr -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* This library 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "vars.h" - - .text - -#ifdef COLDFIRE - .chip 68060 -#endif - - .globl menu_boot - - .align 2 - .long 0x798 - .long end1-begin1+0x80000000 -begin1: - jsr menu_boot -end1: - - .globl boot_drive - - .align 2 - .long 0xB42 - .long end2-begin2+0x80000000 -begin2: - jmp boot_drive -end2: - - .align 2 - .long 0x17EA - .long end3-begin3 -begin3: - .short 0x11 -end3: - -#ifdef COLDFIRE - - .globl error_unknow_device - .globl error_ok - - .align 2 - .long 0x312 - .long end4-begin4+0x80000000 -begin4: - move.l #error_unknow_device,hdv_rw -end4: - - .align 2 - .long 0x31A - .long end5-begin5+0x80000000 -begin5: - move.l #error_ok,hdv_bpb -end5: - - .align 2 - .long 0x322 - .long end6-begin6+0x80000000 -begin6: - move.l #error_unknow_device,hdv_mediach -end6: - - .align 2 - .long 0x30A - .long end7-begin7+0x80000000 -begin7: - move.l #error_unknow_device,hdv_init -end7: - - .align 2 - .long 0x760 - .long end8-begin8 -begin8: // FDC/HDC - nop - nop - nop -end8: - -#endif diff --git a/flash.tos/tos/sdram.S b/flash.tos/tos/boot2.S similarity index 63% rename from flash.tos/tos/sdram.S rename to flash.tos/tos/boot2.S index 017a710..d5d9370 100644 --- a/flash.tos/tos/sdram.S +++ b/flash.tos/tos/boot2.S @@ -1,5 +1,6 @@ /* CT60 booting & SDRAM: * - Boot CPU 68060 detection + * - Apply TOS404 patches * - Configure the CT60-CTCM (CT60 CLock Module) * - Configure the CT60-SDRAM * - PCI entry points @@ -10,13 +11,14 @@ * * Coldfire board(s) booting: * - Init board before start the CF68KLIB + * - Apply TOS404 patches * - Boot CPU detection MCF547X/MCF548X or MCF5445X * - PCI entry points * - Boot disk from CompactFlash on MCF548X or from ATA on MCF5445X * - IDE driver with XHDI and SCSIDRV protocols * - Add SDRAM to TOS * - * Didier Mequignon 2001-2009, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2001-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -33,118 +35,38 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef COLDFIRE - .globl init_cf - .globl before_init_cookies -#else - .globl init_060 -#endif - .globl init_sdram - .globl add_sdram - .globl boot_drive - .globl menu_boot - .globl fix_bug_nvdi - .globl display_ram_test - .globl init_flash_parameters -#ifdef COLDFIRE - .globl error_unknow_device - .globl error_ok -#else - .globl ct60_read_info_sdram - .globl ct60_configure_sdram -#endif - #include "main.h" #include "ct60.h" #include "vars.h" #include "pci_bios.h" +#ifdef COLDFIRE #undef DEBUG +#endif // #define INIT_SDRAM_MOVE16 // #define RESET // removed because not works with some motherboards/SDR60 versions +#undef INIT_FPGA_FROM_RAM // FIREBEE #define ADDR_VERSION 0xE80000 #define ADDR_DATE 0xE80002 -#define XFRB_SIZE 0x10000 #define SPEED_BUFFER_SIZE 0x10000 // mini 512 bytes, maxi 0x20000 #define NB_COOKIES 128 #define CT60_COOKIE_SIZE 256 #define DEFAULT_BOOT_DELAY 800 // 4 seconds -#define TIME_OUT_CMD 200 // 1 second -#define TIME_OUT_4S 800 -#define TIME_OUT_10S 2000 #define rw_parameter 0xc60b - -/* SCSIDRV */ - -#define NOSCSIERROR 0 /* No error */ -#define SELECTERROR -1 /* Error during selection */ -#define STATUSERROR -2 /* Default error */ -#define PHASEERROR -3 /* Invalid phase */ -#define BSYERROR -4 /* BSY lost */ -#define BUSERROR -5 /* Bus error during DMA transfer */ -#define TRANSERROR -6 /* Error during DMA-transfer (nothing transferred) */ -#define FREEERROR -7 /* Bus not freed */ -#define TIMEOUTERROR -8 /* Timeout error */ -#define DATATOOLONG -9 /* Data for ACSI Soft-transfer too long */ -#define LINKERROR -10 /* Error while sending the Linked command (ACSI) */ -#define TIMEOUTARBIT -11 /* Timeout during arbitration */ -#define PENDINGERROR -12 /* Error noted on this handle */ -#define PARITIYERROR -13 /* Transfer caused parity errors */ - -#define cArbit 0x01 /* Arbitration will take place on the bus */ -#define cAllCmds 0x02 /* All SCSI-Cmds can be transmitted */ -#define cTargCtrl 0x04 /* The target controls the procedure (so it should!) */ -#define cTarget 0x08 /* One can install oneself as a target on this bus */ -#define cCanDisconnect 0x10 /* Disconnect is possible */ -#define cScatterGather 0x20 /* Scatter gather possible with virtual RAM */ - -/* XHDI */ - -#define XH_DL_SECSIZ 0 // maximal sector size (BIOS level) -#define XH_DL_MINFAT 1 // minimal number of FATs -#define XH_DL_MAXFAT 2 // maximal number of FATs -#define XH_DL_MINSPC 3 // sectors per cluster minimal -#define XH_DL_MAXSPC 4 // sectors per cluster maximal -#define XH_DL_CLUSTS 5 // maximal number of clusters of a 16 bit FAT -#define XH_DL_MAXSEC 6 // maximal number of sectors -#define XH_DL_DRIVES 7 // maximal number of BIOS drives supported by the DOS - -/* AHDI */ - -#define PUN_DEV 0x1F /* device number of HD */ -#define PUN_UNIT 0x07 /* Unit number */ -#define PUN_SCSI 0x08 /* 1=SCSI 0=ACSI */ -#define PUN_IDE 0x10 /* Falcon IDE */ -#define PUN_REMOVABLE 0x40 /* Removable media */ -#define PUN_VALID 0x80 /* zero if valid */ - -#define pinfo_puns 0 // 2 bytes -#define pinfo_pun 2 // 16 bytes -#define pinfo_pstart 18 // 16 x 4 bytes -#define pinfo_cookie 82 // 4 bytes -#define pinfo_cookptr 86 // 4 bytes -#define pinfo_vernum 90 // 2 bytes -#define pinfo_maxsiz 92 // 2 bytes -#define pinfo_ptype 94 // 16 x 4 bytes -#define pinfo_psize 158 // 16 x 4 bytes -#define pinfo_flags 222 // 16 x 2 bytes, internal use: B15:swap, B7:change, B0:bootable -#define pinfo_bpb 256 // 16 x 32 bytes -#define pinfo_size 768 +#define cache 0xc60c #ifdef COLDFIRE #define AUTO_SUBROUTINE // for BDOS else crash -#define PCI_DRIVERS_SIZE 0x40000 - #include "fire.h" #define RESET // for IDE -#else /* 68060 */ +#else /* CT60 - ATARI */ #define USE_ATARI_IO // IDE, SCSI @@ -228,67 +150,102 @@ #define CT60_REFRESH_RATE_ERROR -9 #define _gpip_mfp 0xfffffa01 -#define _ddr_mfp 0xfffffa05 -#define _iera_mfp 0xfffffa07 // MFP registers -#define _ipra_mfp 0xfffffa0b -#define _isra_mfp 0xfffffa0f -#define _imra_mfp 0xfffffa13 -#define _tbcr_mfp 0xfffffa1b -#define _tbdr_mfp 0xfffffa21 // timer B -#define _tcdr_mfp 0xfffffa23 // timer C -#define _scl_low 0xf0000000 // write 0 to SCL line (clock) -#define _scl_high 0xf0400000 // write 1 to SCL line (clock) -#define _sda_low 0xf0800000 // write 0 to SDA line (data) -#define _sda_high 0xf0c00000 // write 1 to SDA line (data) -#define _sda 0xf0000000 // read from SDA line on the D0 CPU data bus -#define _sdcnf 0xf2000000 // SDRAM configuration 0xf2xx0000 -#define _nideoff 0xf3000000 // turn off the new IDE on the CTPCI (default) -#define _nideon 0xf3800000 // turn on the new IDE on the CTPCI -#define _oideon 0xf8000000 // turn on the old IDE of the motherboard (default) -#define _oideoff 0xf8800000 // turn off the old IDE of the motherboard -#define _itf 0xe0000040 // CTPCI IDE Fast Timming -#define ITF 2 // IDE Fast Timming for 75-100 MHz - -#define CTPCI_ATA 0xFCF00000 -#define CTPCI_ATA_DATA 0xFCF00000 -#define CTPCI_ATA_ERROR_REGISTER 0xFCF00005 -#define CTPCI_ATA_SECTOR_COUNT 0xFCF00009 -#define CTPCI_ATA_SECTOR_NUM 0xFCF0000D // LBA bits 0-7 -#define CTPCI_ATA_CYLINDER_LOW 0xFCF00011 // LBA bits 7-15 -#define CTPCI_ATA_CYLINDER_HIGH 0xFCF00015 // LBA bits 16-23 -#define CTPCI_ATA_DEVICE_HEAD 0xFCF00019 // LBA bits 24-27 -#define CTPCI_ATA_STATUS_COMMAND 0xFCF0001D -#define CTPCI_ATA_CONTROL_DEVICE 0xFCF00039 - -#define WAIT_US bsr wait_26us - -#endif /* COLDFIRE */ - -#ifdef USE_ATARI_IO -#define ATA_DATA 0xFFF00000 -#define ATA_ERROR_REGISTER 0xFFF00005 -#define ATA_SECTOR_COUNT 0xFFF00009 -#define ATA_SECTOR_NUM 0xFFF0000D // LBA bits 0-7 -#define ATA_CYLINDER_LOW 0xFFF00011 // LBA bits 7-15 -#define ATA_CYLINDER_HIGH 0xFFF00015 // LBA bits 16-23 -#define ATA_DEVICE_HEAD 0xFFF00019 // LBA bits 24-27 -#define ATA_STATUS_COMMAND 0xFFF0001D -#define ATA_CONTROL_DEVICE 0xFFF00039 +#define _sdcnf 0xF2000000 // SDRAM configuration 0xf2xx0000 +#define _nideoff 0xF3000000 // no swap IDE ports, the new IDE on the CTPCI is seconday, F030 IDE is the primary (default) +#define _nideon 0xF3800000 // swap IDE ports, the new IDE on the CTPCI on primary, F030 IDE is secondary +// old Jedecs +//#define _nideoff 0xF3000000 // turn off the new IDE on the CTPCI (default) +//#define _nideon 0xF3800000 // turn on the new IDE on the CTPCI +#define _oideon 0xF8000000 // turn on the old IDE of the motherboard (default) +#define _oideoff 0xF8800000 // turn off the old IDE of the motherboard -#endif /* USE_ATARI_IO */ +#endif /* COLDFIRE */ #define LINEA_VAR 0x3E86 #define _v_cel_ht LINEA_VAR-46 // cell height (width is 8) +#ifdef COLDFIRE + .globl init_cf + .globl dummy_function + .globl delay_10us + .globl fire_rw_param + .globl before_init_cookies // 1rst function called after reset (and before init_cf or init_060) + .globl disable_interrupts + .globl check_tos_crc +#ifdef MCF547X + .globl rtc_init +#endif +#else /* !COLDFIRE */ + .globl init_060 + .globl code_led +#endif /* COLDFIRE */ + .globl _LZ_Uncompress + .globl _LzmaDecode + .globl _LzmaDecodeProperties + .globl _apply_patches + .globl init_sdram + .globl add_sdram +#ifdef COLDFIRE + .globl bootload +#endif + .globl boot_drive +#ifdef COLDFIRE + .globl install_scsidrv + .globl install_hddriver + .globl conv_ascii_value_optimized +#if defined(MCF5445X) || (defined MCF547X) + .globl ide_reset +#endif +#endif /* COLDFIRE */ + .globl read_sectors + .globl write_sectors + .globl ide_cmd + .globl scsi_cmd + .globl swap_buffer + .globl menu_boot + .globl init_ram_test + .globl display_ram_test + .globl delay_hz_200 +#ifndef COLDFIRE + .globl ct60_read_info_sdram + .globl ct60_configure_sdram + .globl read_seq_device_i2c + .globl write_seq_device_i2c + .globl read_i2c + .globl write_i2c + .globl init_speed_fan +#endif + .globl message0b + .text #ifdef COLDFIRE -init_cf: +init_cf: // entry point - move.w #0x2700,SR + move.w #0x2700,SR // mask Interrupts .chip 5200 + lea .start_ok(PC),A0 + cmp.l #FLASH_ADR,A0 + bcs.s .start_ok + cmp.l #FLASH_ADR+0x100000,A0 + bcc.s .start_ok + // started from TOS space (copy by another boot) normally incompatible with boot 2.0 and patches apply to the same place + jmp FLASH_TOS_FIRE_ENGINE + nop + nop + nop +// .align 16 +dummy_function: // 32 bytes length, 16 bytes alignment, for chip errata, used by PCI config writes + clr.l D0 + move.l D0,MCF_EPORT_EPFR + rts + dc.w 0x51FB,0,0 // tpf.l #0 + dc.w 0x51FB,0,0 // tpf.l #0 + dc.w 0x51FB,0,0 // tpf.l #0 + dc.w 0x51FA,0 // tpf.w #0 +.start_ok: #ifdef MCF5445X /* Initialize RAMBAR - locate it on the data bus */ move.l #SRAM_BASE+0x35,D0 @@ -320,21 +277,37 @@ init_cf: lea 0x20002000,A0 #endif /* MCF5445X */ move.l A0,SP +#if 1 + /* Invalidate the data, instruction, and branch caches */ + /* Turn on the branch cache and instruction cache */ + move.l #CF_CACR_DCINVA + CF_CACR_BEC + CF_CACR_BCINVA + CF_CACR_IEC + CF_CACR_ICINVA + CF_CACR_EUSP,D0 +#else /* Invalidate the data, instruction, and branch caches */ move.l #CACHE_DISABLE_MODE,D0 +#endif movec.l D0,CACR nop // default copyback set later with CACR at X2XXXXXX move.l #0x0000E000,D0 // zone at $00000000 to $00FFFFFF in writethrough movec.l D0,ACR0 movec.l D0,ACR2 +#if defined(MCF547X) && !defined(DEBUG) + move.l #0xF00FE040,D0 // and the zone $F0000000-$FFFFFFFF in cache inhibit precise +#else move.l #0x807FE040,D0 // and the zone $80000000-$FFFFFFFF in cache inhibit precise +#endif movec.l D0,ACR1 movec.l D0,ACR3 +#define MMUCR __MMU_BASE + move.l #__MMU_BASE+1,D0 + dc.l 0x4E7B0008 // movec.l D0,MMUBAR + nop + clr.l MMUCR // disable MMU + nop /* Disable all interrupts */ bsr disable_interrupts #ifdef MCF5445X /* M54455EVB */ /* Falling edge on IRQ1-7 EPORT */ - move.w EPORT_EPPAR_EPPA7(EPORT_EPPAR_FALLING) \ + move.w #EPORT_EPPAR_EPPA7(EPORT_EPPAR_FALLING) \ + EPORT_EPPAR_EPPA6(EPORT_EPPAR_FALLING) \ + EPORT_EPPAR_EPPA5(EPORT_EPPAR_FALLING) \ + EPORT_EPPAR_EPPA4(EPORT_EPPAR_FALLING) \ @@ -433,8 +406,55 @@ init_cf: move.b D0,MCF_UART_UCSR0 /* Mask all UART interrupts */ clr.b MCF_UART_UIMR0 + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_MAC_ADDRESS,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + move.l D0,mac_address + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_IP_ADDRESS,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + move.l D0,ip_address + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_SERVER_IP_ADDRESS,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + move.l D0,server_ip_address /* Calculate baud settings */ - move.l #(SYSTEM_CLOCK*1000000)/(19200 * 32),D0 // ubgs + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_SERIAL_SPEED,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + tst.l D0 + bmi.s .default_speed + cmp.l #16,D0 + bcs.s .speed_ok +.default_speed: +// moveq #1,D0 // 9600 bauds + moveq #0,D0 // 19200 bauds +.speed_ok: + lea tab_baudrate(PC),A0 + and.l #0xF,D0 + asl.l #2,D0 + move.l (A0,D0.l),D1 + asl.l #4,D1 // * 16 + move.l #(SYSTEM_CLOCK*1000000),D0 + .chip 68060 + divu.l D1,D0 // ubgs + .chip 5200 + lsr.l #1,D0 // / 2 + bcc.s .set_speed + addq.l #1,D0 +.set_speed: move.b D0,D1 lsr.l #8,D0 move.b D0,MCF_UART_UBG10 @@ -442,8 +462,59 @@ init_cf: /* Enable receiver and transmitter */ move.b #MCF_UART_UCR_TX_ENABLED+MCF_UART_UCR_RX_ENABLED,D0 move.b D0,MCF_UART_UCR0 +#if 1 /* PCI Config */ /*to finish...*/ + /* Master Enable / Memory Space / MWI */ + move.l #0x16,D0 + move.l D0,MCF_PCI_PCISCR // PCI Command Register + /* Turn on error signaling */ +// move.l #MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE /* + MCF_PCI_PCIICR_REE*/ + PCI_RETRIES,D0 +// move.l D0,MCF_PCI_PCIICR +// move.l #MCF_PCI_PCIGSCR_SEE,D0 +// or.l D0,MCF_PCI_PCIGSCR + /* Configure Initiator Windows */ + move.l #PCI_MEMORY_OFFSET + ((PCI_MEMORY_SIZE - 1) >> 8),D0 + clr.w D0 + move.l D0,MCF_PCI_PCIIW0BTAR // Initiator Window 0 Base / Translation Address Register + move.l #PCI_IO_OFFSET + ((PCI_IO_SIZE - 1) >> 8),D0 + clr.w D0 + move.l D0,MCF_PCI_PCIIW1BTAR // Initiator Window 1 Base / Translation Address Register + clr.l MCF_PCI_PCIIW2BTAR // not used +// move.l #MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE + MCF_PCI_PCIIWCR_WINCTRL1_IO,D0 +// move.l D0,MCF_PCI_PCIIWCR // Initiator Window Configuration Register + // Target zones +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l #0x40000000,D0 + move.l D0,MCF_PCI_PCIBAR0 // 256 KB window + move.l #0xFC000001,D0 + move.l D0,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 + clr.l MCF_PCI_PCIBAR1 // 1 GB window ! + moveq #1,D0 + move.l D0,MCF_PCI_PCITBATR1 // Target Base Address Translation Register 1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ + move.l #0x80000000,D0 + move.l D0,MCF_PCI_PCIBAR0 // 256 KB window + move.l #0xFC000001,D0 + move.l D0,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 + move.l #0x40000000,D0 + move.l D0,MCF_PCI_PCIBAR1 // 1 GB window ! + moveq #1,D0 + move.l D0,MCF_PCI_PCITBATR1 // Target Base Address Translation Register 1 +#endif /* SAME_CPU_PCI_MEM_ADDR */ + /* Clear PCI Reset and wait for devices to reset */ + move.l #0xFFFFFFFE,D0 + and.l D0,MCF_PCI_PCIGSCR +#endif /* PCI config */ #ifdef DEBUG clr.b serial_mouse + lea debug102(PC),A0 + bsr debug_display_string + lea init_cf(PC),A0 + move.l A0,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char lea debug101(PC),A0 bsr debug_display_string #endif @@ -495,14 +566,12 @@ init_cf: bsr debug_display_char moveq #10,D0 bsr debug_display_char - lea debug103(PC),A0 - bsr debug_display_string #endif /* * Check to see if the SDRAM has already been initialized * by a run control tool */ - lea .copy_tos(PC),A0 + lea .copy_boot(PC),A0 move.l A0,D0 moveq #24,D1 lsr.l D1,D0 @@ -510,6 +579,10 @@ init_cf: // move.l MCF_SDRAMC_SDCR,D0 // and.l #SDRAMC_SDCR_REF,D0 // bne .sdram_controller_ok +#ifdef DEBUG + lea debug103(PC),A0 + bsr debug_display_string +#endif move.b #GPIO_MSCR_SDRAM_SDDATA_DDR2 + GPIO_MSCR_SDRAM_SDDQS_DDR2 \ + GPIO_MSCR_SDRAM_SDCLK_DDR2 + GPIO_MSCR_SDRAM_SDCTL_DDR2, D0 move.b D0,MCF_GPIO_MSCR_SDRAM @@ -546,40 +619,74 @@ init_cf: move.l #SDRAMC_SDCR_REF_EN+SDRAMC_SDCR_DQS_OE(0x3),D0 or.l D0,MCF_SDRAMC_SDCR .sdram_controller_ok: + clr.b boot_tos #else /* MCF547X-MCF548X */ +#ifdef MCF547X + move.w #MCF_EPORT_EPPAR_EPPA7(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA6(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA5(MCF_EPORT_EPPAR_EPPAx_LEVEL) \ + + MCF_EPORT_EPPAR_EPPA4(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA3(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA2(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA1(MCF_EPORT_EPPAR_EPPAx_FALLING),D0 +#else /* Falling edge on IRQ1-7 EPORT */ - move.w MCF_EPORT_EPPAR_EPPA7(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + move.w #MCF_EPORT_EPPAR_EPPA7(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA6(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA5(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA4(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA3(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA2(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA1(MCF_EPORT_EPPAR_EPPAx_FALLING),D0 +#endif move.w D0,MCF_EPORT_EPPAR clr.b MCF_EPORT_EPDDR + moveq #-1,D0 + move.b D0,MCF_EPORT_EPFR clr.b MCF_EPORT_EPIER /* Disable watchdog timer */ clr.l MCF_GPT_GMS0 /* Setup XL Bus Arbiter */ + moveq #24,D0 + move.l MCF_PCI_PCIGSCR,D2 + lsr.l D0,D2 + and.l #7,D2 move.l #MCF_XARB_CFG_BA + MCF_XARB_CFG_DT + MCF_XARB_CFG_AT,D0 + cmp.l #4,D2 // clock ratio 4:1 + bne.s .not_ratio_4_1 + or.l #MCF_XARB_CFG_PLDIS,D0 // Device Errata 26 - Flexbus hang up in 4:1 clock ratio +.not_ratio_4_1: move.l D0,MCF_XARB_CFG +#if 0 move.l #0x1FFFFF,D0 move.l D0,MCF_XARB_ADRTO move.l D0,MCF_XARB_DATTO move.l #0xFFFFFF,D0 move.l D0,MCF_XARB_BUSTO // better timeouts +#endif /* Reset PCI devices */ move.l #MCF_PCI_PCIGSCR_PR,D0 or.l D0,MCF_PCI_PCIGSCR -#if 1 +#if 1 /* PCI Config */ /* Setup the PCI arbiter */ move.l #MCF_PCIARB_PACR_INTMPRI \ + MCF_PCIARB_PACR_EXTMPRI(0x1F) \ + MCF_PCIARB_PACR_INTMINTEN \ + MCF_PCIARB_PACR_EXTMINTEN(0x1F),D0 +#ifdef MCF547X + move.b MCF_GPIO_PPDSDR_PCIBR,D1 + and.l #MCF_GPIO_PPDSDR_PCIBR_PPDSDR_PCIBR3,D1 + beq.s .pci_is_master2 + or.l #MCF_PCIARB_PACR_DS,D0 // disable on-chip arbiter and use GNT0/ for PCI request output and REQ0/ for grant input +.pci_is_master2: +#endif move.l D0,MCF_PCIARB_PACR /* GNT and REQ */ +#ifdef MCF547X + move.w #0x3F,D0 /* only BREQ0-2 are connected to PCI */ +#else move.w #0x3FF,D0 +#endif move.w D0,MCF_GPIO_PAR_PCIBG move.w D0,MCF_GPIO_PAR_PCIBR /* Master Enable / Memory Space / MWI */ @@ -591,13 +698,17 @@ init_cf: move.l #MCF_PCI_PCICR2_MINGNT(PCI_MINGNT) + MCF_PCI_PCICR2_MAXLAT(PCI_MAXLAT),D0 move.l D0,MCF_PCI_PCICR2 /* Turn on error signaling */ - move.l #MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE /* + MCF_PCI_PCIICR_REE*/ + PCI_RETRIES,D0 + move.l #MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE /* + MCF_PCI_PCIICR_REE */ + PCI_RETRIES,D0 move.l D0,MCF_PCI_PCIICR move.l #MCF_PCI_PCIGSCR_SEE,D0 or.l D0,MCF_PCI_PCIGSCR /* Configure Initiator Windows */ move.l #PCI_MEMORY_OFFSET + ((PCI_MEMORY_SIZE - 1) >> 8),D0 +#ifdef SAME_CPU_PCI_MEM_ADDR + move.w #(PCI_MEMORY_OFFSET >> 16),D0 +#else clr.w D0 +#endif move.l D0,MCF_PCI_PCIIW0BTAR // Initiator Window 0 Base / Translation Address Register move.l #PCI_IO_OFFSET + ((PCI_IO_SIZE - 1) >> 8),D0 clr.w D0 @@ -605,33 +716,31 @@ init_cf: clr.l MCF_PCI_PCIIW2BTAR // not used move.l #MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE + MCF_PCI_PCIIWCR_WINCTRL1_IO,D0 move.l D0,MCF_PCI_PCIIWCR // Initiator Window Configuration Register -#if 0 // one target zone - clr.l MCF_PCI_PCIBAR0 - clr.l MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 -// move.l #PCI_MEMORY_SIZE,D0 // STRAM/SDRAM mapped on PCI after the zones for devices + // Target zones +#ifdef SAME_CPU_PCI_MEM_ADDR move.l #0x40000000,D0 - move.l D0,MCF_PCI_PCIBAR1 // 1 GB window ! + move.l D0,MCF_PCI_PCIBAR0 // 256 KB window + move.l #__MBAR + MCF_PCI_PCITBATR0_EN,D0 + move.l D0,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 + clr.l MCF_PCI_PCIBAR1 // 1 GB window ! move.l #MCF_PCI_PCITBATR1_EN,D0 move.l D0,MCF_PCI_PCITBATR1 // Target Base Address Translation Register 1 -#else // two target zones - move.l #SDRAM_SIZE,D2 // SDRAM top -// move.l #PCI_MEMORY_SIZE,D0 // SDRAM mapped on PCI after the zones for devices -// add.l 0x01000000,D0 +#else /* !SAME_CPU_PCI_MEM_ADDR */ move.l #0x80000000,D0 - move.l D0,MCF_PCI_PCIBAR0 - move.l #0x01000000 + MCF_PCI_PCITBATR0_EN,D2 -.no_sdram: - move.l D2,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 -// move.l #PCI_MEMORY_SIZE,D0 // STRAM mapped on PCI after the zones for devices + move.l D0,MCF_PCI_PCIBAR0 // 256 KB window + move.l #__MBAR + MCF_PCI_PCITBATR0_EN,D0 + move.l D0,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 move.l #0x40000000,D0 move.l D0,MCF_PCI_PCIBAR1 // 1 GB window ! move.l #MCF_PCI_PCITBATR1_EN,D0 move.l D0,MCF_PCI_PCITBATR1 // Target Base Address Translation Register 1 -#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ +// move.l #MCF_PCI_PCITCR_P,D0 // prefetch reads for BAR1 +// move.l D0,MCF_PCI_PCITCR // Target Control Register /* Clear PCI Reset and wait for devices to reset */ move.l #~MCF_PCI_PCIGSCR_PR,D0 and.l D0,MCF_PCI_PCIGSCR -#endif +#endif /* PCI config */ /* PSC init for debug */ move.b #MCF_GPIO_PAR_PSC0_PAR_TXD0 \ + MCF_GPIO_PAR_PSC0_PAR_RXD0 \ @@ -661,8 +770,55 @@ init_cf: move.b D0,MCF_UART_UCSR0 /* Mask all UART interrupts */ clr.b MCF_UART_UIMR0 + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_MAC_ADDRESS,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + move.l D0,mac_address + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_IP_ADDRESS,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + move.l D0,ip_address + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_SERVER_IP_ADDRESS,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + move.l D0,server_ip_address /* Calculate baud settings */ - move.l #(SYSTEM_CLOCK*1000000)/(19200 * 32),D0 // ubgs + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_SERIAL_SPEED,D1 // type_param + moveq #0,D2 // value + .chip 68060 + bsr.l fire_rw_param + .chip 5200 + tst.l D0 + bmi.s .default_speed + cmp.l #16,D0 + bcs.s .speed_ok +.default_speed: +// moveq #1,D0 // 9600 bauds + moveq #0,D0 // 19200 bauds +.speed_ok: + lea tab_baudrate(PC),A0 + and.l #0xF,D0 + asl.l #2,D0 + move.l (A0,D0.l),D1 + asl.l #4,D1 // * 16 + move.l #(SYSTEM_CLOCK*1000000),D0 + .chip 68060 + divu.l D1,D0 // ubgs + .chip 5200 + lsr.l #1,D0 // / 2 + bcc.s .set_speed + addq.l #1,D0 +.set_speed: move.b D0,D1 lsr.l #8,D0 move.b D0,MCF_UART_UBG10 @@ -675,14 +831,19 @@ init_cf: * the ports, the lines won't be floating and potentially cause * erroneous transmissions */ -#ifdef MCF547X /* MCF547X - COLDARI */ +#ifdef MCF547X /* MCF547X - FIREBEE */ + /* reduce power by disable clock of unused parts */ + move.l #~(MCF_PLL_SPCR_CRYENB+MCF_PLL_SPCR_CRYENA+MCF_PLL_SPCR_CN1EN+MCF_PLL_SPCR_USBEN+MCF_PLL_SPCR_FEC1EN+MCF_PLL_SPCR_CN0EN),D0 + and.l D0,MCF_PLL_SPCR /* Just FEC0, FEC1 PINS are GPIO excecpted MDC and MDIO */ - move.w #MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_SCL \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_SDA \ + move.w #MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO \ + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC \ + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO \ + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MII \ + MCF_GPIO_PAR_FECI2CIRQ_PAR_E07 \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_SDA \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_SCL \ + MCF_GPIO_PAR_FECI2CIRQ_PAR_IRQ6 \ + MCF_GPIO_PAR_FECI2CIRQ_PAR_IRQ5,D0 move.w D0,MCF_GPIO_PAR_FECI2CIRQ @@ -704,8 +865,8 @@ init_cf: move.b #MCF_GPIO_PAR_PSC2_PAR_CTS2_BCLK \ + MCF_GPIO_PAR_PSC2_PAR_RTS2_FSYNC \ + MCF_GPIO_PAR_PSC2_PAR_RXD2 \ - + MCF_GPIO_PAR_PSC2_PAR_TXD2,D0 - move.b D0,MCF_GPIO_PAR_PSC2 // AC97 audio codec + + MCF_GPIO_PAR_PSC2_PAR_TXD2,D0 // AC97 audio codec + move.b D0,MCF_GPIO_PAR_PSC2 move.b #MCF_GPIO_PAR_PSC3_PAR_CTS3_GPIO \ + MCF_GPIO_PAR_PSC3_PAR_RTS3_GPIO \ + MCF_GPIO_PAR_PSC3_PAR_RXD3 \ @@ -716,7 +877,7 @@ init_cf: + MCF_GPIO_PAR_DSPI_PAR_CS2_DSPICS \ + MCF_GPIO_PAR_DSPI_PAR_CS0_DSPICS \ + MCF_GPIO_PAR_DSPI_PAR_SCK_SCK \ - + MCF_GPIO_PAR_DSPI_PAR_SIN_SIN\ + + MCF_GPIO_PAR_DSPI_PAR_SIN_SIN \ + MCF_GPIO_PAR_DSPI_PAR_SOUT_SOUT,D0 move.w D0,MCF_GPIO_PAR_DSPI move.b #MCF_GPIO_PAR_TIMER_PAR_TIN3_IRQ \ @@ -724,15 +885,44 @@ init_cf: + MCF_GPIO_PAR_TIMER_PAR_TIN2_IRQ \ + MCF_GPIO_PAR_TIMER_PAR_TOUT2,D0 move.b D0,MCF_GPIO_PAR_TIMER + move.b #MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 \ + + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L3 \ + + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L2 \ + + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L1,D0 + move.b D0,MCF_GPIO_PDDR_FEC1L // OUT: 4=LED,3=PRG_DQ0,2=#FPGA_CONFIG,1=PRG_CLK(FPGA) /* Flexbus pins are enabled by default */ #ifdef DEBUG clr.b serial_mouse - lea debug101(PC),A0 - bsr debug_display_string +#ifdef MCF547X + move.b MCF_GPIO_PPDSDR_PCIBR,D0 + and.l #MCF_GPIO_PPDSDR_PCIBR_PPDSDR_PCIBR3,D0 + beq.s .pci_is_master + lea debug141(PC),A0 + bra.s .pci_end_slave +.pci_is_master: + lea debug142(PC),A0 +.pci_end_slave: + bsr debug_display_string +#endif + lea debug102(PC),A0 + bsr debug_display_string + lea init_cf(PC),A0 + move.l A0,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char #endif - /* The COLDARI has one 8MB flash */ + /* The FIREBEE has one 8MB flash */ move.l #MCF_FBCS_CSAR_BA(BOOT_FLASH_BASE),D0 move.l D0,MCF_FBCS_CSAR0 + move.l #MCF_FBCS_CSCR_SWS(0) \ + + MCF_FBCS_CSCR_ASET(1) \ + + MCF_FBCS_CSCR_RDAH(1) \ + + MCF_FBCS_CSCR_WRAH(1) \ + + MCF_FBCS_CSCR_AA \ + + MCF_FBCS_CSCR_PS_16,D1 // cscr /* * Determine the necessary wait states based on the defined system * period (XLB clock period) and the CLKIN to XLB ratio. @@ -752,44 +942,141 @@ init_cf: asl.l D2,D0 or.l D0,D1 // cscr move.l D1,MCF_FBCS_CSCR0 - move.l #MCF_FBCS_CSMR_BAM_4M+MCF_FBCS_CSMR_WP+MCF_FBCS_CSMR_V,D0 + move.l #MCF_FBCS_CSMR_BAM_8M+MCF_FBCS_CSMR_WP+MCF_FBCS_CSMR_V,D0 move.l D0,MCF_FBCS_CSMR0 - /* FPGA ATARI I/O on FBCS1/2/3 */ +#ifdef DEBUG + lea debug101(PC),A0 + bsr debug_display_string +#endif + /* FALCON I/O 1MB */ move.l #MCF_FBCS_CSAR_BA(FPGA_CS1_BASE),D0 + cmp.l MCF_FBCS_CSAR1,D0 + beq.s .fbcs1_ok move.l D0,MCF_FBCS_CSAR1 move.l #FPGA_CS1_ACCESS,D0 move.l D0,MCF_FBCS_CSCR1 - move.l #MCF_FBCS_CSMR_BAM_64K+MCF_FBCS_CSMR_V,D0 + move.l #MCF_FBCS_CSMR_BAM_1M+MCF_FBCS_CSMR_V,D0 move.l D0,MCF_FBCS_CSMR1 +#ifdef DEBUG + lea debug146(PC),A0 + bsr debug_display_string + move.l #MCF_FBCS_CSAR_BA(FPGA_CS1_BASE),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +.fbcs1_ok: + /* ACP I/O 128MB */ move.l #MCF_FBCS_CSAR_BA(FPGA_CS2_BASE),D0 + cmp.l MCF_FBCS_CSAR2,D0 + beq.s .fbcs2_ok move.l D0,MCF_FBCS_CSAR2 move.l #FPGA_CS2_ACCESS,D0 move.l D0,MCF_FBCS_CSCR2 - move.l #MCF_FBCS_CSMR_BAM_128K+MCF_FBCS_CSMR_V,D0 + move.l #MCF_FBCS_CSMR_BAM_128M+MCF_FBCS_CSMR_V,D0 move.l D0,MCF_FBCS_CSMR2 +#ifdef DEBUG + lea debug147(PC),A0 + bsr debug_display_string + move.l #MCF_FBCS_CSAR_BA(FPGA_CS2_BASE),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +.fbcs2_ok: + /* SRAM 256Kx16 */ move.l #MCF_FBCS_CSAR_BA(FPGA_CS3_BASE),D0 + cmp.l MCF_FBCS_CSAR3,D0 + beq.s .fbcs3_ok move.l D0,MCF_FBCS_CSAR3 - move.l #FPGA_CS2_ACCESS,D0 + move.l #FPGA_CS3_ACCESS,D0 move.l D0,MCF_FBCS_CSCR3 - move.l #MCF_FBCS_CSMR_BAM_64K+MCF_FBCS_CSMR_V,D0 + move.l #MCF_FBCS_CSMR_BAM_64M+MCF_FBCS_CSMR_V,D0 move.l D0,MCF_FBCS_CSMR3 #ifdef DEBUG - lea debug103(PC),A0 - bsr debug_display_string + lea debug148(PC),A0 + bsr debug_display_string + move.l #MCF_FBCS_CSAR_BA(FPGA_CS3_BASE),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +.fbcs3_ok: + /* VIDEO RAM 128MB */ + move.l #MCF_FBCS_CSAR_BA(FPGA_CS4_BASE),D0 + cmp.l MCF_FBCS_CSAR4,D0 + beq.s .fbcs4_ok + move.l D0,MCF_FBCS_CSAR4 + move.l #FPGA_CS4_ACCESS,D0 + move.l D0,MCF_FBCS_CSCR4 + move.l #MCF_FBCS_CSMR_BAM_1G+MCF_FBCS_CSMR_V,D0 + move.l D0,MCF_FBCS_CSMR4 +#ifdef DEBUG + lea debug149(PC),A0 + bsr debug_display_string + move.l #MCF_FBCS_CSAR_BA(FPGA_CS4_BASE),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char #endif +.fbcs4_ok: /* * Check to see if the SDRAM has already been initialized * by a run control tool */ - lea .copy_tos(PC),A0 + lea .copy_boot(PC),A0 move.l A0,D0 moveq #24,D1 lsr.l D1,D0 beq .sdram_controller_ok // started from RAM (test) -// move.l MCF_SDRAMC_SDCR,D0 -// and.l #MCF_SDRAMC_SDCR_REF,D0 -// bne .sdram_controller_ok + move.l MCF_SDRAMC_SDCR,D0 + and.l #MCF_SDRAMC_SDCR_REF,D0 + bne .sdram_controller_ok +#ifdef DEBUG + lea debug103(PC),A0 + bsr debug_display_string +#endif /* Basic configuration and initialization - 8 x K4H510438 - DDR266 CL2 (512Mbits - 32M * 16) */ +#if 1 // Fredi + move.l #0x000002AA,D0 // SDRAMDS configuration + move.l D0,MCF_SDRAMC_SDRAMDS + move.l #0x0000001A,D0 // SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF) + move.l D0,MCF_SDRAMC_CS0CFG + move.l #0x0800001A,D0 // SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF) + move.l D0,MCF_SDRAMC_CS1CFG + move.l #0x1000001A,D0 // SDRAM CS2 configuration (128Mbytes 1000_0000 - 07FF_FFFF) + move.l D0,MCF_SDRAMC_CS2CFG + move.l #0x1800001A,D0 // SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF) + move.l D0,MCF_SDRAMC_CS3CFG + move.l #0x73622830,D0 // SDCFG1 + move.l D0,MCF_SDRAMC_SDCFG1 + move.l #0x46770000,D0 // SDCFG2 + move.l D0,MCF_SDRAMC_SDCFG2 + move.l #0xE10D0002,D0 // SDCR + IPALL + move.l D0,MCF_SDRAMC_SDCR + move.l #0x40010000,D0 // SDMR (write to LEMR) + move.l D0,MCF_SDRAMC_SDMR + move.l #0x048D0000,D0 // SDRM (write to LMR) + move.l D0,MCF_SDRAMC_SDMR + move.l #0xE10D0002,D0 // SDCR + IPALL + move.l D0,MCF_SDRAMC_SDCR + move.l #0xE10D0004,D0 // SDCR + IREF (first refresh) + move.l D0,MCF_SDRAMC_SDCR + move.l #0xE10D0004,D0 // SDCR + IREF (second refresh) + move.l D0,MCF_SDRAMC_SDCR + move.l #0x008D0000,D0 // SDMR (write to LMR) + move.l D0,MCF_SDRAMC_SDMR + move.l #0x710D0F00,D0 // SDCR (lock SDMR and enable refresh) + move.l D0,MCF_SDRAMC_SDCR +#else // !Fredi move.l #MCF_SDRAMC_SDRAMDS_SB_E(MCF_SDRAMC_SDRAMDS_DRIVE_16MA) \ + MCF_SDRAMC_SDRAMDS_SB_C(MCF_SDRAMC_SDRAMDS_DRIVE_16MA) \ + MCF_SDRAMC_SDRAMDS_SB_A(MCF_SDRAMC_SDRAMDS_DRIVE_16MA) \ @@ -848,6 +1135,7 @@ init_cf: and.l D0,(A0) move.l #MCF_SDRAMC_SDCR_REF+MCF_SDRAMC_SDCR_DQS_OE(0xF),D0 or.l D0,(A0) +#endif // Fredi #ifdef DEBUG lea debug119(PC),A0 bsr debug_display_string @@ -899,40 +1187,226 @@ init_cf: bsr debug_display_char #endif .sdram_controller_ok: -#else /* MCF548X - M5484LITE */ - clr.b MCF_GPIO_PDDR_FECI2C; - move.w #MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MII \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E17 \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MII \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_E07 \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_SDA \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_SCL \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_IRQ6 \ - + MCF_GPIO_PAR_FECI2CIRQ_PAR_IRQ5,D0 - move.w D0,MCF_GPIO_PAR_FECI2CIRQ - move.b #MCF_GPIO_PAR_PSC3_PAR_CTS3_BCLK \ - + MCF_GPIO_PAR_PSC3_PAR_RTS3_FSYNC \ - + MCF_GPIO_PAR_PSC3_PAR_RXD3 \ - + MCF_GPIO_PAR_PSC3_PAR_TXD3,D0 - move.b D0,MCF_GPIO_PAR_PSC3 // AC97 audio codec - /* TOUT0 as LED output */ - move.b #MCF_GPIO_PAR_DMA_PAR_DREQ0(MCF_GPIO_PAR_DMA_PAR_DREQx_TIN) \ - + MCF_GPIO_PAR_DMA_PAR_DREQ1(MCF_GPIO_PAR_DMA_PAR_DREQx_TIN) \ - + MCF_GPIO_PAR_DMA_PAR_DACK0(MCF_GPIO_PAR_DMA_PAR_DACKx_TOUT) \ - + MCF_GPIO_PAR_DMA_PAR_DACK1(MCF_GPIO_PAR_DMA_PAR_DACKx_TOUT),D0 - move.b D0,MCF_GPIO_PAR_DMA + moveq #-1,D0 + move.l D0,MCF_SLT_SLTCNT1 + move.l #MCF_SLT_SCR_TEN + MCF_SLT_SCR_RUN,D0 + move.l D0,MCF_SLT_SCR1 // for delay_10us and rtc_init + clr.b boot_tos + /* Init FPGA */ + lea .copy_boot(PC),A0 + move.l A0,D0 + moveq #24,D1 + lsr.l D1,D0 +#ifdef INIT_FPGA_FROM_RAM + bne fpga_end // started from FLASH + move.l A0,D0 + and.l #0xFF000000,D0 + lea (DATA_FPGA & 0xFFFFFF),A0 // start address fpga data + add.l D0,A0 +#else /* !INIT_FPGA_FROM_RAM */ + beq fpga_end // started from SDRAM + move.l A0,D0 + and.l #0xFFF00000,D0 + lea BOOT_FLASH_BASE,A0 + cmp.l D0,A0 // TOS replace dBUG or other + bne fpga_end + moveq #-1,D0 + move.b D0,boot_tos + lea DATA_FPGA,A0 // start address fpga data +#endif /* INIT_FPGA_FROM_RAM */ #ifdef DEBUG - clr.b serial_mouse - lea debug101(PC),A0 - bsr debug_display_string -#endif - /* The M5474LITE/M5484LITE has one 4MB boot flash */ - /* The M5485EVB has a 2MB boot flash */ - move.l #MCF_FBCS_CSAR_BA(BOOT_FLASH_BASE),D0 + move.l A0,-(SP) + lea debug143(PC),A0 + bsr debug_display_string + move.l (SP),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,A0 +#endif + /* Invalidate the data, instruction, and branch caches */ + /* Turn on the branch cache and instruction cache */ + move.l #CF_CACR_DCINVA + CF_CACR_BEC + CF_CACR_BCINVA + CF_CACR_IEC + CF_CACR_ICINVA + CF_CACR_EUSP,D0 + movec D0,CACR + lea MCF_GPIO_PODR_FEC1L,A1 // register address:write + lea MCF_GPIO_PPDSDR_FEC1L,A2 // reads + bclr #1,(A1) // clk low + bclr #2,(A1) // #config=low +test_nSTATUS: + btst #0,(A2) // nSTATUS==0 + bne.s test_nSTATUS + btst #5,(A2) // conf done==0 + bne.s test_nSTATUS + bsr delay_10us + bset #2,(A1) // #config=high + bsr delay_10us +test_STATUS: + btst #0,(A2) // status high? + beq.s test_STATUS + bsr delay_10us + move.l A0,A3 + add.l #SIZE_FPGA,A3 +byte_send_loop: + cmp.l A3,A0 + bhi.s fpga_error + move.b (A0)+,D0 + moveq #7,D1 +bit_send_loop: + lsr.l #1,D0 // bit loop + bcs.s bit_is_1 + bclr #3,(A1) + bra.s bit_send +bit_is_1: + bset #3,(A1) +bit_send: + bset #1,(A1) // clock=high + bclr #1,(A1) // clock=low + subq.l #1,D1 + bpl.s bit_send_loop + btst #5,(A2) // conf_done=high? + beq.s byte_send_loop + move.l #4000,D1 +overclk: + bset #1,(A1) // clock=high + nop + bclr #1,(A1) // clock=low + subq.l #1,D1 + bgt.s overclk +#ifdef DEBUG + lea debug145(PC),A0 + bsr debug_display_string + bra.s fpga_end +#endif +fpga_error: +#ifdef DEBUG + lea debug144(PC),A0 + bsr debug_display_string +#endif +fpga_end: + moveq #0,D1 + moveq.l #0x55,D0 + move.w D0,ACP_VIDEO_PLL_CLK + move.w ACP_VIDEO_PLL_CLK,D1 // 1st read not works + move.w ACP_VIDEO_PLL_CLK,D1 // 2nd access works + cmp.l D0,D1 + bne .has_no_pll // old hardware - list of clocks +#ifdef DEBUG + lea debug139(PC),A0 + bsr debug_display_string +#endif + lea ACP_VIDEO_PLL_CONFIG,A0 + bsr wait_pll + moveq #27,D0 + move.w D0,0x48(A0) // loopfilter r + bsr wait_pll + moveq #1,D0 + move.w D0,0x08(A0) // charge pump I + bsr wait_pll + moveq #12,D1 + move.w D1,0x00(A0) // N counter high = 12 + bsr wait_pll + move.w D1,0x40(A0) // N counter low = 12 + bsr wait_pll + move.w D0,0x114(A0) // ck1 bypass + bsr wait_pll + move.w D0,0x118(A0) // ck2 bypass + bsr wait_pll + move.w D0,0x11C(A0) // ck3 bypass + bsr wait_pll + move.w D0,0x10(A0) // ck0 high = 1 + bsr wait_pll + move.w D0,0x50(A0) // ck0 low = 1 + bsr wait_pll + move.w D0,0x144(A0) // M odd division + bsr wait_pll + move.w D0,0x44(A0) // M low = 1 + bsr wait_pll + move.w #150-1,D0 + move.w D0,0x04(A0) // M high = 150MHz + bsr wait_pll + clr.b ACP_VIDEO_PLL_RECONFIG // set +.has_no_pll: + /* Init video ram */ + move.l #ACP_CONFIG_ON + ACP_VCS + ACP_VCKE,D0 + swap D0 + move.w D0,ACP_VIDEO_CONTROL + nop + lea ACP_VIDEO_CFG,A0 + nop + move.l #0x00050400,(A0) // IPALL + nop + move.l #0x00072000,(A0) // load EMR pll on + nop + move.l #0x00070122,(A0) // load MR: reset pll, cl=2 BURST=4lw + nop + move.l #0x00050400,(A0) // IPALL + nop + move.l #0x00060000,(A0) // auto refresh + nop + move.l #0x00060000,(A0) // auto refresh + nop + move.l #0x00070022,(A0) // load MR dll on + nop + move.l #ACP_FIFO_ON + ACP_REFRESH_ON + ACP_VCS + ACP_VCKE + ACP_VIDEO_DAC_ON,D0 + move.l D0,ACP_VIDEO_CONTROL + tst.b boot_tos + beq.s .normal_tos // TOS not started from 0xE0000000 + move.b MCF_GPIO_PPDSDR_PSC3PSC2,D0 + and.l #MCF_GPIO_PPDSDR_PSC3PSC2_PPDSDR_PSC3PSC27,D0 + bne.s .normal_tos // SW6 DDWN + // check TOS if SW6 UP + lea 0xE0400000,A0 + move.w (A0),D0 + move.l #0x602E,D1 + cmp.l D0,D1 + bne.s .normal_tos + jmp (A0) // jump to TOS +.normal_tos: +#else /* MCF548X - M5484LITE */ + clr.b MCF_GPIO_PDDR_FECI2C; + move.w #MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MII \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E17 \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MII \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_E07 \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_SDA \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_SCL \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_IRQ6 \ + + MCF_GPIO_PAR_FECI2CIRQ_PAR_IRQ5,D0 + move.w D0,MCF_GPIO_PAR_FECI2CIRQ + move.b #MCF_GPIO_PAR_PSC3_PAR_CTS3_BCLK \ + + MCF_GPIO_PAR_PSC3_PAR_RTS3_FSYNC \ + + MCF_GPIO_PAR_PSC3_PAR_RXD3 \ + + MCF_GPIO_PAR_PSC3_PAR_TXD3,D0 + move.b D0,MCF_GPIO_PAR_PSC3 // AC97 audio codec + /* TOUT0 as LED output */ + move.b #MCF_GPIO_PAR_DMA_PAR_DREQ0(MCF_GPIO_PAR_DMA_PAR_DREQx_TIN) \ + + MCF_GPIO_PAR_DMA_PAR_DREQ1(MCF_GPIO_PAR_DMA_PAR_DREQx_TIN) \ + + MCF_GPIO_PAR_DMA_PAR_DACK0(MCF_GPIO_PAR_DMA_PAR_DACKx_TOUT) \ + + MCF_GPIO_PAR_DMA_PAR_DACK1(MCF_GPIO_PAR_DMA_PAR_DACKx_TOUT),D0 + move.b D0,MCF_GPIO_PAR_DMA +#ifdef DEBUG + clr.b serial_mouse + lea debug102(PC),A0 + bsr debug_display_string + lea init_cf(PC),A0 + move.l A0,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + lea debug101(PC),A0 + bsr debug_display_string +#endif + /* The M5474LITE/M5484LITE has one 4MB boot flash */ + /* The M5485EVB has a 2MB boot flash */ + move.l #MCF_FBCS_CSAR_BA(BOOT_FLASH_BASE),D0 move.l D0,MCF_FBCS_CSAR0 move.l #MCF_FBCS_CSCR_SWS(0) \ + MCF_FBCS_CSCR_ASET(1) \ @@ -1024,14 +1498,12 @@ init_cf: bsr debug_display_char moveq #10,D0 bsr debug_display_char - lea debug103(PC),A0 - bsr debug_display_string #endif /* * Check to see if the SDRAM has already been initialized * by a run control tool */ - lea .copy_tos(PC),A0 + lea .copy_boot(PC),A0 move.l A0,D0 moveq #24,D1 lsr.l D1,D0 @@ -1039,6 +1511,10 @@ init_cf: // move.l MCF_SDRAMC_SDCR,D0 // and.l #MCF_SDRAMC_SDCR_REF,D0 // bne .sdram_controller_ok +#ifdef DEBUG + lea debug103(PC),A0 + bsr debug_display_string +#endif #if 1 /* Basic configuration and initialization */ move.l #MCF_SDRAMC_SDRAMDS_SB_E(MCF_SDRAMC_SDRAMDS_DRIVE_8MA) \ @@ -1211,6 +1687,7 @@ init_cf: bsr debug_display_char #endif .sdram_controller_ok: + clr.b boot_tos #ifdef DEBUG lea debug100(PC),A0 bsr debug_display_string @@ -1256,10 +1733,11 @@ init_cf: */ #endif /* MCF547X */ #endif /* MCF5445X */ +.begin_copy_tos: #ifdef DEBUG lea debug104(PC),A0 bsr debug_display_string - lea .copy_tos(PC),A0 + lea .copy_boot(PC),A0 move.l A0,D0 and.l #0xFF000000,D0 lea (FLASH_TOS_FIRE_ENGINE & 0xFFFFFF),A0 @@ -1267,8 +1745,7 @@ init_cf: bsr debug_hex_long lea debug104b(PC),A0 bsr debug_display_string - lea FLASH_ADR,A0 // TOS404 - move.l A0,D0 + move.l #FLASH_ADR,D0 // TOS404 bsr debug_hex_long moveq #13,D0 bsr debug_display_char @@ -1276,57 +1753,83 @@ init_cf: bsr debug_display_char #endif /* copy FLASH in SDRAM */ - lea .copy_tos(PC),A0 + lea .copy_boot(PC),A0 move.l A0,D0 and.l #0xFF000000,D0 lea (FLASH_TOS_FIRE_ENGINE & 0xFFFFFF),A0 add.l D0,A0 lea FLASH_ADR,A1 // TOS404 - move.l #FLASH_SIZE/16,D0 -.copy_tos: + move.l A1,-(SP) // dest patched in RAM + move.l A0,-(SP) // source + move.l #0x80000,D1 // original TOS404 size (512KB) + add.l D1,A0 + add.l D1,A1 + move.l #(FLASH_SIZE-0x80000)/16,D0 +.copy_boot: move.l (A0)+,(A1)+ move.l (A0)+,(A1)+ move.l (A0)+,(A1)+ move.l (A0)+,(A1)+ subq.l #1,D0 - bgt.s .copy_tos - lea FLASH_ADR,A1 - lea restart_emulation,A0 - add.l #FLASH_ADR+0x80000,A0 - sub.l #_ct60tos_half_flash,A0 - move.l A0,4(A1) - move.l A0,0x10(A1) // header TOS404 - move.w #0x4EF9,D0 - move.w D0,0x30(A1) - move.l A0,0x32(A1) // JMP - lea 0,A2 // vectors - move.l (A1),(A2) - move.l A0,4(A2) // PC - /* update TOS404 checksum */ - lea crctab(PC),A0 - moveq #0,D0 - moveq #0,D1 // crc - moveq #0,D3 - move.l #(FLASH_SIZE/2)-2,D7 -.calc_crc: - move.b (A1)+,D0 - move.w D1,D2 // crc - lsr.l #8,D2 - eor.l D0,D2 - and.l #0xFF,D2 - move.w (A0,D2.L*2),D3 // crc2 - asl.l #8,D1 // crc - eor.l D3,D1 - subq.l #1,D7 - bgt.s .calc_crc - move.w D1,(A1) // crc + bgt.s .copy_boot + move.l #CACHE_DISABLE_MODE,D0 // invalidate whole cache + movec.l D0,CACR + nop + move.l #CACHE_ENABLE_MODE,D0 // enable caches + movec.l D0,CACR + bsr _apply_patches // source/dest are on stack + addq.l #8,SP + lea 0,A1 +.loop_cpushl_dc: + dc.w 0xF469 // cpushl DC,(A1) + addq.l #1,A1 + dc.w 0xF469 // cpushl DC,(A1) + addq.l #1,A1 + dc.w 0xF469 // cpushl DC,(A1) + addq.l #1,A1 + dc.w 0xF469 // cpushl DC,(A1) + add.l #0x10-3,A1 + cmp.l #LAST_DCACHE_ADDR,A1 + ble.s .loop_cpushl_dc + /* Init pseudo STRAM */ +#if 0 // #ifdef MCF547X /* FIREBEE - FPGA mulation */ + lea 0xFFFF8007,A0 + move.b (A0),D0 + or.l #0x21,D0 // like the FALCON + move.b D0,(A0) + beq #6,D0 // F030 Start (0 - Cold, 1 - Warn) + beq.s .init_stram_cf // Cold +#endif /* MCF547X */ +#ifdef MCF547X + lea 0xFFFF8800,A0 // PSG sound + moveq #7,D0 + move.b D0,(A0) // ports A & B + move.b #0xC0,D0 // are outputs + move.b D0,2(A0) + moveq #14,D0 // port A + move.b D0,(A0) + moveq #7,D0 // disable floppy + move.b D0,2(A0) +#endif /* MCF547X */ + move.l memvalid,D0 + cmp.l #0x752019F3,D0 + bne.s .init_stram_cf + move.l memval2,D0 + cmp.l #0x237698AA,D0 + bne.s .init_stram_cf + move.l memval3,D0 + cmp.l #0x5555AAAA,D0 + beq.s .no_init_stram_cf +.init_stram_cf: #ifdef DEBUG lea debug105(PC),A0 bsr debug_display_string #endif - /* Init pseudo STRAM */ bsr init_stram - lea reset_board(PC),A1 +.no_init_stram_cf: + clr.l _hz_200 + clr.l con_state + lea reset_board,A1 lea 8,A0 moveq #125,D0 .loop_init_vectors: @@ -1340,75 +1843,96 @@ init_cf: lea debug107(PC),A0 bsr debug_display_string #endif - move.l #FLASH_ADR+0x80000,D0 - sub.l #_ct60tos_half_flash,D0 // offset ... gentos :-( lea _init_mmu,A0 - add.l D0,A0 lea _update_tlb,A1 - add.l D0,A1 lea _LZ_Uncompress,A2 - add.l D0,A2 + lea _LzmaDecodeProperties,A3 + lea _LzmaDecode,A4 /* Start cf68klib in RAM */ jmp CF68KLIB - -crctab: - dc.w 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7 - dc.w 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef - dc.w 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6 - dc.w 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de - dc.w 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485 - dc.w 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d - dc.w 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4 - dc.w 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc - dc.w 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823 - dc.w 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b - dc.w 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12 - dc.w 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a - dc.w 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41 - dc.w 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49 - dc.w 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70 - dc.w 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78 - dc.w 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f - dc.w 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067 - dc.w 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e - dc.w 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256 - dc.w 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d - dc.w 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405 - dc.w 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c - dc.w 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634 - dc.w 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab - dc.w 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3 - dc.w 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a - dc.w 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92 - dc.w 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9 - dc.w 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1 - dc.w 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8 - dc.w 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 +#ifdef MCF547X +wait_pll: + + move.l D1,-(SP) + move.l D0,-(SP) + move.l MCF_SLT_SCNT1,D1 +.wait_pll_loop: + tst.w ACP_VIDEO_PLL_RECONFIG + bpl.s .not_busy + move.l D1,D0 + sub.l MCF_SLT_SCNT1,D0 + cmp.l #1000*SYSTEM_CLOCK,D0 // 1 mS + bcs.s .wait_pll_loop +.not_busy: + move.l (SP)+,D0 + move.l (SP)+,D1 + rts + +#endif /* MCF547X */ + +tab_baudrate: + dc.l 19200,9600,4800,3600,2400,2000,1800,1200,600,300 + // 200, 150, 134, 110, 75, 50 + dc.l 230400,115200,57600,38400,153600,76800 + restart_emulation: -// lea library_data_area,A0 // 1024 bytes -// move.w 68(A0),D0 // reg_sr -// and.l #0x2000,D0 -// bne.s .super_ok #ifdef DEBUG lea debug112(PC),A0 bsr debug_display_string + move.l (SP),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +.loop_null: + bra.s .loop_null #endif reset_board: +#ifdef DEBUG + lea debug151(PC),A0 + bsr debug_display_string + move.w 6(SP),D0 + and.l #0xFFF,D0 + lsr.l #2,D0 + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + lea library_data_area,A0 // 1024 bytes + move.w 68(A0),D0 // reg_sr + and.l #0x2000,D0 + beq.s .user_mode + move.w #0x2700,SR // mask Interrupts +.user_mode: + lea access_fault_stack,SP + bsr disable_interrupts #ifdef MCF5445X move.w #SCM_CWCR_CWE + SCM_CWCR_CWRI(2) + SCM_CWCR_CWT(8),D0 move.w D0,MCF_SCM_CWCR #else /* MCF548X */ clr.l MCF_GPT_GMS0 - move.l #0x640001,D0 + move.w #SYSTEM_CLOCK,D0 + swap D0 +#ifdef DEBUG + move.w #-1,D0 // 65535 uS +#else + move.w #10,D0 // 10 uS +#endif move.l D0,MCF_GPT_GCIR0 move.l #MCF_GPT_GMS_TMS_GPIO + MCF_GPT_GMS_CE + MCF_GPT_GMS_WDEN,D0 move.l D0,MCF_GPT_GMS0 // reset watchdog #endif /* MCF5454X */ .wait_reset_board: nop + moveq #0x2E,D0 + move.b D0,MCF_UART_UTB0 bra.s .wait_reset_board +#if 0 .super_ok: #ifdef DEBUG lea debug111(PC),A0 @@ -1418,8 +1942,14 @@ reset_board: moveq #0,D0 movec.l D0,VBR bsr disable_interrupts +#if 1 + /* Invalidate the data, instruction, and branch caches */ + /* Turn on the branch cache and instruction cache */ + move.l #CF_CACR_DCINVA + CF_CACR_BEC + CF_CACR_BCINVA + CF_CACR_IEC + CF_CACR_ICINVA + CF_CACR_EUSP,D0 +#else /* Invalidate the data, instruction, and branch caches */ move.l #CACHE_DISABLE_MODE,D0 +#endif movec.l D0,CACR move.l memvalid,D0 cmp.l #0x752019F3,D0 @@ -1442,7 +1972,7 @@ reset_board: bsr debug_display_string #endif jmp 0xE001DA - +#endif /* if 0 */ disable_interrupts: @@ -1502,24 +2032,12 @@ init_stram: move.l D1,A1 move.l D2,A2 move.l D3,A3 - lsr.l #8,D7 // / 256 + lsr.l #6,D7 // / 64 .loop_init_stram: lea -32(A4),A4 movem.l D0-D3/A0-A3,(A4) lea -32(A4),A4 movem.l D0-D3/A0-A3,(A4) - lea -32(A4),A4 - movem.l D0-D3/A0-A3,(A4) - lea -32(A4),A4 - movem.l D0-D3/A0-A3,(A4) - lea -32(A4),A4 - movem.l D0-D3/A0-A3,(A4) - lea -32(A4),A4 - movem.l D0-D3/A0-A3,(A4) - lea -32(A4),A4 - movem.l D0-D3/A0-A3,(A4) - lea -32(A4),A4 - movem.l D0-D3/A0-A3,(A4) subq.l #1,D7 bgt.s .loop_init_stram lea FLASH_ADR,A0 // TOS404 @@ -1533,6 +2051,9 @@ before_init_cookies: #ifdef DEBUG lea debug113(PC),A0 bsr debug_display_string +#endif +#if defined(COLDFIRE) && defined(MCF547X) + jsr rtc_init // PSC3 for RTC #endif lea FLASH_ADR,A0 lea 0x940,A1 @@ -1556,7 +2077,7 @@ before_init_cookies: .code_940: jmp 0x12345678 bra.s .code_940 - + #ifdef DEBUG debug100: .ascii "FlexCAN config init" @@ -1564,14 +2085,14 @@ debug100: .ascii "FlexCAN config init" #ifdef MF5445X /* M54455EVB */ debug101: .ascii "16MB boot flash base address init" #else -#ifdef MCF547X /* MCF548X - COLDARI */ +#ifdef MCF547X /* MCF548X - FIREBEE */ debug101: .ascii "8MB boot flash base address init" #else /* MCF548X - M5484LITE */ debug101: .ascii "4MB boot flash base address init" #endif /* MCF547X */ #endif /* MCF5445X */ .byte 13,10,0 - +debug102: .asciz "TOS started from 0x" debug103: .ascii "SDRAM controller init" .byte 13,10,0 debug104: .asciz "Copy FLASH in SDRAM, 0x" @@ -1587,8 +2108,7 @@ debug109: .asciz "CPLD HW revision " debug110: .asciz "CPLD SW revision " debug111: .ascii "Reset" .byte 13,10,0 -debug112: .ascii "Null pointer ?" - .byte 13,10,0 +debug112: .asciz "Null pointer ? return address 0x" debug113: .ascii "Init cookies" .byte 13,10,13,13,0 debug114: .ascii "Install PCI BIOS" @@ -1598,46 +2118,53 @@ debug116: .ascii "Init SDRAM" .byte 13,10,0 debug117: .ascii "Menu boot" .byte 13,10,0 -debug118: .asciz "Memory for PCI drivers at 0x" debug119: .asciz "SDRAMC_SDRAMDS 0x" debug120: .asciz "SDRAMC_CS0CFG 0x" debug121: .asciz "SDRAMC_SDMR 0x" debug122: .asciz "SDRAMC_SDCR 0x" debug123: .asciz "SDRAMC_SDCFG1 0x" debug124: .asciz "SDRAMC_SDCFG2 0x" -debug125: .asciz "BPB: " -debug126: .asciz "IDE error (code - STATUS - ERROR) " -debug127: .asciz "hdv_rw 0x" -debug128: .asciz "pun_ptr 0x" -debug129: .asciz "drvbits 0x" -debug130: .asciz "SCSCDRV In cmd " -debug131: .asciz "SCSIDRV Out cmd " -debug132: .asciz "XHDI XHReadWrite 0x" -debug133: .ascii "XHDI XHInqTarget" +debug131: .ascii "bootload floprd" + .byte 13,10,0 +debug132: .ascii "Bad clock, fix clock from build date" + .byte 13,10,0 +#if defined(MCF5445X) || defined(MCF547X) +debug133: .ascii "IDE reset" .byte 13,10,0 -debug134: .ascii "XHDI XHInqDev" +#endif +debug134: .ascii "bootload hdv_init" + .byte 13,10,0 +debug135: .ascii "=> boot sector invalid" .byte 13,10,0 -debug135: .ascii "XHDI XHInqDriver" +debug136: .ascii "=> not loadable" .byte 13,10,0 -debug136: .ascii "XHDI XHInqDev2" +debug137: .ascii "=> no drive" .byte 13,10,0 -debug137: .ascii "XHDI XHDOSLimits" +debug138: .ascii "=> boot OK" .byte 13,10,0 -debug138: .ascii "SCSCDRV Open" +#ifdef MCF547X +debug139: .ascii "Init video PLL" .byte 13,10,0 -debug139: .ascii "SCSIDRV Close" +debug140: .ascii "IDE / CF ports swapped" .byte 13,10,0 -debug140: .ascii "SCSIDRV Error" +debug141: .ascii "PCI is slave" .byte 13,10,0 -debug141: .ascii "SCSIDRV RescanBus" +debug142: .ascii "PCI is master" .byte 13,10,0 -debug142: .ascii "SCSIDRV CheckDev" +debug143: .asciz "Init FPGA from 0x" +debug144: .ascii "PPGA error" .byte 13,10,0 -debug143: .ascii "SCSIDRV InquireBus" +debug145: .ascii "PPGA OK" .byte 13,10,0 -debug144: .ascii "SCSIDRV InquireSCSI" +debug146: .asciz "Set FBCS FALCON I/O at 0x" +debug147: .asciz "Set FBCS ACP I/O at 0x" +debug148: .asciz "Set FBCS SRAM at 0x" +debug149: .asciz "Set FBCS VIDEO RAM at 0x" +#endif /* MCF547X */ +debug151: .asciz "Reset from vector 0x" +debug152: .asciz " Apply patch in 0x" +debug153: .ascii "Check TOS CRC" .byte 13,10,0 -debug145: .asciz " ret: 0x" .align 2 @@ -1691,13 +2218,15 @@ debug_display_char: .no_debug: rts +#undef DEBUG + #endif /* DEBUG */ .chip 68060 #else /* ATARI - 68060 */ -init_060: +init_060: // entry point move.w #0x2700,SR #ifdef RESET @@ -1732,627 +2261,1141 @@ init_060: move.w #0x20,0xFFFF828C move.w #0x10,0xFFFF8282 or.b #0x21,0xFFFF8007 - btst #6,0xFFFF8007 - beq .end_init_060 - lea .ret(PC),A6 - jmp 0x00E00C1C -.ret: - bne .end_init_060 - move.b memctrl,0xFFFF8001 // config STRAM - cmp.l #0x31415926,resvalid - bne .end_init_060 - move.l resvector,D0 - btst #0,D0 - bne .end_init_060 - cmp.l #0x1357BD13,ramvalid - bne .not_sdram_found - lea _sdcnf,A0 - moveq #0,D0 - move.b memctrl+1,D0 // config SDRAM saved A23-A16 - swap D0 - add.l D0,A0 - clr.l (A0) // config SDRAM - move.l resvector,A0 - cmp.l #0x01000000,A0 // base SDRAM - beq .end_init_060 -.not_sdram_found: - cmp.l #0x31415926,resvalid - bne .end_init_060 - move.l resvector,D0 - btst #0,D0 - bne .end_init_060 - move.l D0,A0 - lea .not_sdram_found(PC),A6 - jmp (A0) // resvector -.end_init_060: - jmp 0x00E000C8 - -#endif /* COLDFIRE */ - -init_sdram: - -#ifdef COLDFIRE - lea -56(SP),SP - movem.l D1-A6,(SP) - move.w SR,D0 - move.w D0,-(SP) - or.l #0x700,D0 // mask interrupts - move.w D0,SR - move.l #CACHE_DISABLE_MODE,D0 // invalidate whole cache - movec D0,CACR - nop - move.l #CACHE_ENABLE_MODE,D0 // enable caches - movec D0,CACR - move.w (SP)+,D0 - move.w D0,SR - pea linea000(PC) - move.w #47,-(SP) // TRAP #15 - move.w #5,-(SP) // Setexec - trap #13 - addq.l #8,SP // MAC instruction on Coldfire use opcodes 0xAxxx -#ifdef MCF5445X /* M54455EVB */ - moveq #2,D0 // SDRAM 256MB -#else -#ifdef MCF547X /* MCF547X - COLDARI */ - moveq #3,D0 // SDRAM 512MB -#else /* MCF548X - M5484LITE */ - moveq #0,D0 // SDRAM 64MB -#endif /* MCF547X */ -#endif /* MCF5445X */ -#else /* ATARI */ - movem.l D1-A6,-(SP) - bclr #5,0xFFFFFA07 // mask timer A - move.w SR,-(SP) - or #0x700,SR // no interrupts + lea 0xFFFF8800,A0 // PSG + move.b #7,(A0) // ports A & B + move.b #0xC0,2(A0) // A & B are outputs + move.b #14,(A0) // port A + move.b #7,2(A0) // unselect floppy drives +#ifndef RESET + clr.b 0xFFFF8901 // stops DMA sound +#endif + lea _gpip_mfp,A0 // MFP + moveq #23,D0 +.clear_mfp: + clr.b (A0) + addq.l #2,A0 + subq.l #1,D0 + bpl.s .clear_mfp +#if 1 // this sequence crashes after mmu_init and cache enabled without SDRAM (see above) + lea 0x00E00C3A(PC),A0 + lea 0xFFFF8240,A1 // VIDEL + moveq #15,D0 +.init_st_palette: + move.w (A0)+,(A1)+ + dbf D0,.init_st_palette + clr.b 0xFFFF8266 + lea 0xFFFF9800,A1 + moveq #15,D0 +.init_f030_palette: + move.l (A0)+,(A1)+ + dbf D0,.init_f030_palette + clr.b 0xFFFF8260 + move.b #1,0xFFFF8201 + clr.b 0xFFFF8203 +#endif + lea 0x8870,SP // stack + lea reset_f030,A1 // clear lower memory and reset + lea 8,A0 // bus error / acces fault + moveq #63,D0 +.init_vectors_to_reset: + move.l A1,(A0)+ + dbf D0,.init_vectors_to_reset + lea _rte(PC),A1 + move.l A1,0x14 // TRAPV + lea 0x60,A0 // INT0-7 auto vectors + moveq #7,D0 +.init_int_vectors_to_rte: + move.l A1,(A0)+ + dbf D0,.init_int_vectors_to_rte + move.w 0xFFFF8006,D0 // config + lsr.w #8,D0 + lsr.b #1,D0 + move.b D0,D1 + and.b #1,D1 + lsr.b #2,D0 + and.b #6,D0 + or.b D0,D1 + move.l #0x80000,D0 + asl.l D1,D0 + cmp.b #5,D1 + bne.s .not_14mb + move.l #0xE00000,D0 // max 14MB +.not_14mb: + move.l D0,phystop // STRAM cpusha BC move.l #0xA0808000,D0 // caches on - movec.l D0,CACR - move.w (SP)+,SR - move.l #0x00E00FB6,8 // set access fault vector - move.b 0xFFFF8006,D0 - lsr.b #6,D0 // 0:ST mono, 1:ST col, 2:VGA, 3:TV - cmp.b #2,D0 // VGA - beq.s .ok_screen - move.l #0x5F465251,D0 // _FRQ cookie, internal clock - bsr get_cookie - cmp.l #32,D0 - bls.s .ok_screen - move.l #0x5F465245,D0 // _FRE cookie, external clock - bsr get_cookie - cmp.l #32,D0 - bne.s .ok_screen - bset #0,0xFFFF820A // external clock -.ok_screen: - clr.l -(SP) - move.l #CT60_BLITTER_SPEED,-(SP) - move.w #CT60_MODE_READ,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP - btst #0,D0 - beq.s .blitter_slow - bset #2,0xFFFF8007 // blitter 16 MHz -.blitter_slow: + movec.l D0,CACR // enable caches (else it's too slow for uncompress / copy / patch TOS) bsr ct60_configure_sdram -#endif /* COLDFIRE */ - clr.l ramtop - clr.l ramvalid - move.l D0,D5 // save return value of ct60_configure_sdram - bmi .error_pci // error SDRAM => no PCI -#ifdef COLDFIRE - move.l #SDRAM_SIZE-SDRAM_RESERVED,D1 -#else + move.l D0,ramtop // negative values are errors (used by init_sdram) + bpl.s .sdram_ok_init_mmu + moveq #1,D0 + bsr code_led + bra .normal_mmu_init // error SDRAM => with STRAM +.sdram_ok_init_mmu: add.w #26,D0 // size 0-3 for 64MB-512MB moveq #0,D1 bset D0,D1 add.l #0x01000000,D1 - move.l phystop,D0 - sub.l _memtop,D0 - cmp.l #RESERVE_MEM,D0 - beq .error_pci // pmmu tree in STRAM & no SDRAM - movec.l PCR,D0 - btst #16,D0 - bne .error_pci // EC or LC -#endif move.l D1,ramtop - move.l #0x1357BD13,ramvalid - move.l _sysbase,A0 // header ROM - move.l 0x24(A0),A0 // kbshift - move.b (A0),D1 - and.b #0xF,D1 - cmp.b #4,D1 // CTRL - beq .error_pci - cmp.b #8,D1 // ALT - beq .error_pci -#ifdef COLDFIRE -#ifdef DEBUG - lea debug114(PC),A0 - bsr debug_display_string -#endif -#endif - move.w #1,-(SP) - move.w #299,-(SP) // install PCI BIOS - trap #14 - addq.l #4,SP -#ifdef COLDFIRE - tst.w D0 - bmi .error_pci - clr.w -(SP) // STRAM - move.l #PCI_DRIVERS_SIZE,-(SP) // size for bss - move.w #0x44,-(SP) // Mxalloc - trap #1 - addq.l #8,SP - tst.l D0 - beq .error_pci -#ifdef DEBUG - move.l D0,-(SP) - lea debug118(PC),A0 - bsr debug_display_string - move.l (SP),D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif - move.l D0,A0 - move.l #0x5F504349,(A0) // _PCI -#else /* 68060 */ - tst.w D0 - bmi.s .no_swap_ide_ctpci - clr.l -(SP) - move.l #CT60_PARAM_CTPCI,-(SP) - move.w #CT60_MODE_READ,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP - tst.l D0 - bmi.s .no_swap_ide_ctpci - btst #0,D0 - beq.s .no_swap_ide_ctpci - // swap IDE address - clr.l _nideon // turn on the new IDE on the CTPCI - clr.l _oideoff // turn off the old IDE of the motherboard -.no_swap_ide_ctpci: + lea .no_ctpci_hardware(PC),A0 + move.l 8,A5 // bus error + move.l A0,8 + move.l SP,A4 // save ssp + clr.b PCI_CTPCI_CONFIG_ENABI // mask INTD /INTC / INTB / INTA / LINT + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp move.l #0x5F4C5A5F,D0 // _LZ_ - lea 0xED0000,A0 // 128 KB - cmp.l (A0),D0 // _LZ_ - beq.s .uncompress_pci_drivers - lea 0xEC0000,A0 // 192 KB - cmp.l (A0),D0 // _LZ_ - beq.s .uncompress_pci_drivers - lea 0xEB0000,A0 // 256 KB - cmp.l (A0),D0 // _LZ_ - beq.s .uncompress_pci_drivers - lea 0xEA0000,A0 // 320 KB - cmp.l (A0),D0 // _LZ_ - bne.s .not_compressed_pci_drivers -.uncompress_pci_drivers: + move.l #0x4C5A4D41,D1 // LZMA + moveq #3,D2 + lea 0xED0000,A0 // 128KB / 192KB / 256KB / 320KB +.test_lz_loop: + cmp.l (A0),D0 // _LZ_ + beq.s .pci_drivers_found + cmp.l (A0),D1 // LZMA + beq.s .pci_drivers_found2 + sub.l #0x10000,A0 + dbf D2,.test_lz_loop + bra .normal_mmu_init // with SDRAM +.pci_drivers_found: + bsr fast_test_sdram + bpl.s .test_sdram_ok_init_mmu + moveq #3,D0 // SDRAM read/write error + bsr code_led + bra .normal_mmu_init // SDRAM failure +.test_sdram_ok_init_mmu: move.l 4(A0),-(SP) // insize pea 0x1000000 // out: SDRAM temp pea 8(A0) // in - lea _LZ_Uncompress,A0 - add.l #FLASH_ADR+0x80000,A0 - sub.l #_ct60tos_half_flash,A0 - jsr (A0) + jsr _LZ_Uncompress move.l (SP)+,A0 subq.l #8,A0 addq.l #8,SP - move.l D0,-(SP) // size PCI drivers - move.l A0,-(SP) // base PCI drivers => force TOS in RAM - lea _init_mmu_tree,A0 - add.l #FLASH_ADR+0x80000,A0 - sub.l #_ct60tos_half_flash,A0 - jsr (A0) + move.l D0,-(SP) // size PCI drivers in a protected area + move.l A0,-(SP) // base PCI drivers + bra.s .go_init_mmu +.pci_drivers_found2: + bsr fast_test_sdram + bmi.s .normal_mmu_init // SDRAM failure + link A6,#-24 + move.l A0,-(SP) // base PCI drivers + pea 8(A0) // propsData + pea -16(A6) // Properties + jsr _LzmaDecodeProperties + addq.l #8,SP + tst.l D0 + bne.s .error_header_lzma // error + move.l #0x1100000,-4(A6) // Probs buffer, size = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb) + move.l (SP),A0 // base PCI drivers + pea -24(A6) // outSizeProcessed + move.l #0x100000,-(SP) // outSize + pea 0x1000000 // outStream: SDRAM temp + pea -20(A6) // inSizeProcessed + move.l 4(A0),-(SP) // inSize + pea 8+5(A0) // inStream + pea -16(A6) // CLzmaDecoderState structure + jsr _LzmaDecode + lea 28(SP),SP + move.l -24(A6),D1 // outSizeProcessed +.error_header_lzma: + move.l (SP)+,A0 + unlk a6 + tst.l D0 + bne.s .normal_mmu_init // error + move.l D1,-(SP) // size PCI drivers in a protected area + move.l A0,-(SP) // base PCI drivers + bra.s .go_init_mmu +.no_ctpci_hardware: + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp +.normal_mmu_init: + clr.l -(SP) // size PCI drivers + clr.l -(SP) // base PCI drivers +.go_init_mmu: + jsr _init_mmu_tree addq.l #8,SP -.not_compressed_pci_drivers: + move.l phystop,D0 + sub.l #RESERVE_MEM_FONTS,D0 // for blitter2.S and more... + move.l D0,phystop + btst #6,0xFFFF8007 // F030 Start (0 - Cold, 1 - Warn) + beq .no_reset_vector // Cold + cmp.l #0x752019F3,memvalid + bne .no_reset_vector + cmp.l #0x237698AA,memval2 + bne .no_reset_vector + cmp.l #0x5555AAAA,memval3 + bne .no_reset_vector + move.b memctrl,0xFFFF8001 // config STRAM + cmp.l #0x31415926,resvalid + bne .no_reset_vector + move.l resvector,D0 + btst #0,D0 + bne .no_reset_vector // bad address +#if 0 + cmp.l #0x58425241,-12(A0) // XBRA + bne.s .check_ramvalid + cmp.l #0x55534844,-8(A0) // USHD + bne.s .check_ramvalid + clr.l resvalid + clr.l resvector + bra.s .no_reset_vector +.check_ramvalid: +#endif + cmp.l #0x1357BD13,ramvalid + bne .not_sdram_found + cmp.l #0x01000000,A0 // base SDRAM + beq.s .no_reset_vector + bra.s .jump_to_reset +.not_sdram_found: + cmp.l #0x31415926,resvalid + bne .no_reset_vector + move.l resvector,D0 + btst #0,D0 + bne .no_reset_vector +.jump_to_reset: + move.l D0,A0 + lea .not_sdram_found(PC),A6 + jmp (A0) // resvector +.no_reset_vector: + lea 0xFFFF8800,A0 // PSG + move.b #7,(A0) // ports A & B + move.b #0xC0,2(A0) // A & B are outputs + move.b #14,(A0) // port A + move.b #7,2(A0) // unselect floppy drives +#if 0 // this sequence crashes after mmu_init and cache enabled without SDRAM (see before) + lea 0x00E00C3A(PC),A0 + lea 0xFFFF8240,A1 // VIDEL + moveq #15,D0 +.init_st_palette: + move.w (A0)+,(A1)+ + dbf D0,.init_st_palette2 + clr.b 0xFFFF8266 + lea 0xFFFF9800,A1 + moveq #15,D0 +.init_f030_palette: + move.l (A0)+,(A1)+ + dbf D0,.init_f030_palette2 + clr.b 0xFFFF8260 + move.b #1,0xFFFF8201 + clr.b 0xFFFF8203 +#endif + bset #6,0xFFFF8007 // F030 Start (0 - Cold, 1 - Warn) + beq.s .init_stram // Cold + cmp.l #0x752019F3,memvalid + bne.s .init_stram + cmp.l #0x237698AA,memval2 + bne.s .init_stram + cmp.l #0x5555AAAA,memval3 + beq.s .no_init_stram +.init_stram: + move.l phystop,D5 // save phystop + move.l ramtop,D6 // save ramtop + lea 0x400,A4 // start adress + move.l D5,D4 // phystop + add.l #RESERVE_MEM_FONTS,D4 + sub.l A4,D4 // - start address + lsr.l #8,D4 // / 256 (block transfer) + subq.l #1,D4 // for dbf + moveq #0,D0 + moveq #0,D1 + moveq #0,D2 + moveq #0,D3 + move.l D0,A0 + move.l D1,A1 + move.l D2,A2 + move.l D3,A3 + lea 256(A4),A4 + lea 512,A5 +.loop_init_stram: // init STRAM + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + movem.l D0-D3/A0-A3,-(A4) + add.l A5,A4 // next 256 bytes block + dbf D4,.loop_init_stram + move.l D5,phystop // restore phystop + move.l D6,ramtop // restore ramtop + move.l D5,A0 + clr.l hardware_type(A0) +.no_init_stram: + jmp 0x00E001DA + #endif /* COLDFIRE */ - bsr test_pci_drivers - bne.s .error_pci - jsr 4(A0) // drivers PCI in flash, init -.error_pci: + +_rte: + rte + +#ifndef COLDFIRE + +reset_f030: + + moveq #7,D0 // exception error + bsr code_led + jmp 0x00E0398C // clear lower memory and reset + +led_floppy: + + move.l A0,-(SP) + move.l D0,-(SP) + lea 0xFFFF8800,A0 // PSG sound + moveq #7,D0 + move.b D0,(A0) // ports A & B + move.b #0xC0,D0 // are outputs + move.b D0,2(A0) + moveq #14,D0 // port A + move.b D0,(A0) + tst.l (SP) + seq.b D0 + and.b #7,D0 // disable floppy: 7 + move.b D0,2(A0) + move.l (SP)+,D0 + move.l (SP)+,A0 + rts + +tempo_mfp: + + movem.l D0/A0,-(SP) + lea _gpip_mfp,A0 // MFP 68901 + clr.b 24(A0) // TACR stop timer A + bclr #5,18(A0) // IMRA interrupt mask timer A + bclr #5,6(A0) // IERA + bclr #5,10(A0) // IPRA no pending + bclr #5,14(A0) // ISRA + moveq #49,D0 // 0.5 S +.tm1: + move.b #124,30(A0) // TADR init timer A MFP for 10091 uS + move.b #7,24(A0) // TACR (prediv /200) + bset #5,6(A0) // IERA enable + bclr #5,10(A0) // IPRA clear timer A +.tm2: + btst #5,10(A0) // IPRA wait timer A + beq.s .tm2 + clr.b 24(A0) // TACR stop timer A + dbf D0,.tm1 + movem.l (SP)+,D0/A0 + rts + +code_led: + // 1: SDRAM refresh error + // 3: SDRAM read/write error + // 6: Keyboard error + // 7: Exception error + // 9: BIOS checksum error + // 11: Memory test error + subq.l #1,D0 + bmi.s .cl1 +.cl2: + move.l D0,-(SP) + moveq #1,D0 + bsr led_floppy + bsr tempo_mfp + moveq #0,D0 + bsr led_floppy + bsr tempo_mfp + move.l (SP)+,D0 + dbf D0,.cl2 +.cl1: + bsr tempo_mfp + bsr tempo_mfp + bsr tempo_mfp + bsr tempo_mfp + rts + +#endif /* COLDFIRE */ + +_apply_patches: + #ifdef COLDFIRE - move.l _v_bas_ad,D0 - cmp.l #0x01000000,D0 - bcc.s .graphic_card - moveq #0x1B,D0 // clear screen - bsr display_char - moveq #0x45,D0 - bsr display_char -.graphic_card: + lea -48(SP),SP + movem.l D0-A3,(SP) +#else + movem.l D0-A3,-(SP) + moveq #15,D5 // retry counter +.retry_loop: +#endif /* COLDFIRE */ + move.l 52(SP),A0 // TOS source + move.l 56(SP),A1 // target in RAM + move.l #0x80000/16,D0 // 512K / 16, TOS size +.copy_original_tos: + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + subq.l #1,D0 + bgt.s .copy_original_tos + move.l 56(SP),A1 // target in RAM + move.l #0x46FC2700,D0 // move.w #0x2700,SR + move.l #0x30388006,D1 // move.w 0xFFFF8006,D0 + move.l D0,0x30(A1) // restore begin of TOS, jump used for boot outside the original TOS + move.l D1,0x34(A1) + lea crctab(PC),A0 + moveq #0,D0 + moveq #0,D1 // crc + moveq #0,D3 + move.l #0x80000-2,D7 +.calc_crc_source: + move.b (A1)+,D0 + move.w D1,D2 // crc + lsr.l #8,D2 + eor.l D0,D2 + move.w (A0,D2.l*2),D3 // crc2 + asl.l #8,D1 // crc + eor.l D3,D1 + subq.l #1,D7 + bgt.s .calc_crc_source + moveq #0,D0 + move.w (A1),D0 // crc at the end of the TOS + and.l #0xFFFF,D1 + cmp.l D1,D0 // crc + seq.b D6 // set if CRC is correct +#ifndef COLDFIRE + dbeq D5,.retry_loop // cmp result BAD => try again (CT60 flash bad access ???) + beq.s .crc_ok + moveq #9,D0 // bad checksum + bsr code_led +.crc_ok: +#endif + move.l 56(SP),A0 // target in RAM + lea _ct60tos_patch,A1 + lea _ct60tos_end_patch,A2 + move.l #0xFFFFFFFC,D1 // long mask alignment +.loop_patch: + move.l (A1)+,D0 // offset + lea (A0,D0.l),A3 // TOS address + move.l (A1)+,D0 // len + ble.s .next_patch +#ifdef COLDFIRE +#if 0 // #ifdef DEBUG + move.l D0,-(SP) + move.l A0,-(SP) + lea debug152(PC),A0 + bsr debug_display_string + move.l A1,D0 + subq.l #8,D0 + bsr debug_hex_long + lea debug104b(PC),A0 + bsr debug_display_string + move.l A3,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 #endif - bsr spaces - lea message0(PC),A0 - cmp.w #2,0x3E86 // number of planes - bhi.s .title_colors - lea message0b(PC),A0 -.title_colors: - bsr display_string_single - bsr spaces +#endif + btst #0,D0 + bne.s .copy_bytes_patch + btst #1,D0 + bne.s .copy_word_patch +.copy_long_patch: + move.l (A1)+,(A3)+ // copy patch + subq.l #4,D0 + bgt.s .copy_long_patch + bra.s .next_patch +.copy_word_patch: + move.w (A1)+,(A3)+ // copy patch + subq.l #2,D0 + bgt.s .copy_word_patch + bra.s .next_patch +.copy_bytes_patch: + move.b (A1)+,(A3)+ // copy patch + subq.l #1,D0 + bgt.s .copy_bytes_patch +.next_patch: + move.l A1,D0 + addq.l #3,D0 + and.l D1,D0 + move.l D0,A1 // long alignment + cmp.l A2,A1 + bcs.s .loop_patch + move.l 56(SP),A1 // target in RAM #ifdef COLDFIRE -#ifdef MCF5445X - move.w MCF_CCM_CIR,D0 - and.l #CCM_CIR_PIN_MASK,D0 - lea message8(PC),A0 - cmp.l #CCM_CIR_PIN_MCF54454,D0 - beq.s .v4m - lea message8a(PC),A0 - cmp.l #CCM_CIR_PIN_MCF54453,D0 - beq.s .v4m - lea message8b(PC),A0 - cmp.l #CCM_CIR_PIN_MCF54452,D0 - beq.s .v4m - lea message8c(PC),A0 - cmp.l #CCM_CIR_PIN_MCF54451,D0 - beq.s .v4m - lea message8d(PC),A0 - cmp.l #CCM_CIR_PIN_MCF54450,D0 - lea message10(PC),A0 -.v4m: -#else /* MCF548X */ - move.l MCF_SIU_JTAGID,D0 - and.l #MCF_SIU_JTAGID_PROCESSOR,D0 - lea message8(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5485,D0 - beq .v4e - lea message8a(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5484,D0 - beq.s .v4e - lea message8b(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5483,D0 - beq.s .v4e - lea message8c(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5482,D0 - beq.s .v4e - lea message8d(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5481,D0 - beq.s .v4e - lea message8e(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5480,D0 - beq.s .v4e - lea message9(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5475,D0 - beq.s .v4e - lea message9a(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5474,D0 - beq.s .v4e - lea message9b(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5473,D0 - beq.s .v4e - lea message9c(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5472,D0 - beq.s .v4e - lea message9d(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5471,D0 - beq.s .v4e - lea message9e(PC),A0 - cmp.l #MCF_SIU_JTAGID_MCF5470,D0 - beq.s .v4e - lea message10(PC),A0 -.v4e: -#endif /* MCF5445X */ -#else /* ATARI */ - movec.l PCR,D0 + lea restart_emulation,A0 + move.l A0,D0 + and.l #0x000FFFFF,D0 + or.l #0x00E00000,D0 + move.l D0,4(A1) // reset vector + move.l D0,0x10(A1) // header TOS404 + move.l D0,0x32(A1) // JMP + move.w #0x4EF9,D0 + move.w D0,0x30(A1) + move.l A1,A0 + add.l #0x0008000C,A0 // init_cf + move.w #0x60FE,(A0) // bra.s +#endif + lea ADDR_DATE,A0 + moveq #0,D0 + move.w 2(A0),D0 // month + divu #10,D0 + moveq #0,D1 + move.w D0,D1 + asl.l #4,D1 swap D0 - lea message8(PC),A0 // 68060 - cmp.w #0x0430,D0 - beq.s .full_060 - lea message9(PC),A0 // 68EC060 / 68LC060 - cmp.w #0x0431,D0 - beq.s .ec_lc_060 - lea message10(PC),A0 -.full_060: -.ec_lc_060: -#endif /* COLDFIRE */ - bsr display_string -#ifdef COLDFIRE -#ifdef MCF5445X - move.w MCF_CCM_CIR,D0 - and.l #CCM_CIR_PRN_MASK,D0 // revision -#else /* MCF548X */ - move.l MCF_SIU_JTAGID,D0 - and.l #MCF_SIU_JTAGID_REV,D0 - moveq #28,D1 - lsr.l D1,D0 // revision -#endif /* MCF548X */ -#else /* ATARI */ - clr.w D0 + or.l D1,D0 + move.b D0,24(A1) // month header + moveq #0,D0 + move.w (A0),D0 // day + divu #10,D0 + moveq #0,D1 + move.w D0,D1 + asl.l #4,D1 swap D0 - lsr.w #8,D0 // revision -#endif /* COLDFIRE */ + or.l D1,D0 + move.b D0,25(A1) // day header + moveq #0,D0 + move.w 4(A0),D0 // year + divu #100,D0 + move.l D0,D2 + and.l #0xFFFF,D0 divu #10,D0 - and.w #7,D0 - beq.s .rev_less_10 - or.w #0x30,D0 - bsr display_char -.rev_less_10: + moveq #0,D1 + move.w D0,D1 + asl.l #4,D1 swap D0 - or.w #0x30,D0 - bsr display_char -#ifndef COLDFIRE - movec.l PCR,D0 - move.l D0,D1 - lsr.l #8,D1 - lea message11(PC),A0 - and.w #0x1FF,D1 - beq.s .display_mask // revision 0, mask D00W/D11W - lea message13(PC),A0 - cmp.w #2,D1 // revision 2, mask F84W - beq.s .display_mask - lea message14(PC),A0 - cmp.w #6,D1 // revision 1,5 mask F43G/G65V - bcc.s .display_mask // revision 6 and more mask E41J ? - bset #5,D0 // disable store/load bypass (masks 1,3,4,5) - movec.l D0,PCR - lea message12(PC),A0 -.display_mask: - btst #8,D1 - bne.s .mask_060_ok // mask info only for 060 full - bsr display_string -.mask_060_ok: - moveq #0,D7 - clr.l -(SP) - move.l #CT60_CLOCK,-(SP) - move.w #CT60_MODE_READ,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP -// cmp.l #MIN_FREQ_DALLAS/2,D0 - cmp.l #MIN_FREQ,D0 - bcs.s .measure_mhz - cmp.l #MAX_FREQ,D0 - bhi.s .measure_mhz - move.l _sysbase,A0 // header ROM - move.l 0x24(A0),A0 // kbshift - move.b (A0),D1 - and.b #0xF,D1 - cmp.b #4,D1 // CTRL - beq.s .reset_clock - cmp.b #8,D1 // ALT - beq.s .reset_clock - moveq #CT60_CLOCK_WRITE_RAM,D1 - bsr ct60_configure_clock - move.l D0,D7 - bsr tempo_20ms - bra.s .measure_mhz -.reset_clock: - moveq #0,D2 + or.l D1,D0 + move.b D0,26(A1) // year/100 header + clr.w D2 + swap D2 + move.l D2,D0 + divu #10,D0 moveq #0,D1 - move.w #CT60_CLOCK_RESET+CYPRESS,D0 - bsr ct60_rw_clock - move.l D0,D7 - bsr tempo_20ms -.measure_mhz: + move.w D0,D1 + asl.l #4,D1 + swap D0 + or.l D1,D0 + move.b D0,27(A1) // year%100 header + tst.b D6 + beq.s .source_crc_bad // source is bad => don't update target (for TOS error message) + /* update TOS404 checksum */ + lea crctab(PC),A0 + moveq #0,D0 + moveq #0,D1 // crc + moveq #0,D3 + move.l #0x80000-2,D7 +.calc_crc_dest: + move.b (A1)+,D0 + move.w D1,D2 // crc + lsr.l #8,D2 + eor.l D0,D2 + move.w (A0,D2.l*2),D3 // crc2 + asl.l #8,D1 // crc + eor.l D3,D1 + subq.l #1,D7 + bgt.s .calc_crc_dest + move.w D1,(A1) // update crc at the end of the TOS +.source_crc_bad: +#ifdef COLDFIRE + movem.l (SP),D0-A3 + lea 48(SP),SP +#else + movem.l (SP)+,D0-A3 #endif - link A6,#-6 - bsr measure_cpu_frequency - move.l D0,-4(A6) // CPU frequency in MHz * 10 + rts + #ifdef COLDFIRE - move.l #0x5F43465F,D0 // _CF_ -#else /* 68060 */ -#if 0 - cmp.l #750,D0 - bcs.s .lower_75mhz - move.l #0x5F504349,D0 // cookie _PCI - bsr get_cookie - move.l A0,D0 - beq.s .lower_75mhz // no CTPCI registers - moveq #ITF,D0 // IDE Fast Timmings - move.l D0,_itf // CTPCI -.lower_75mhz: + +check_tos_crc: + +#ifdef DEBUG + lea debug153(PC),A0 + bsr debug_display_string #endif - move.l #0x43543630,D0 // CT60 + move.l 4(SP),A0 // TOS address + move.l 8(SP),D2 // size + move.w 12(SP),A1 // incr + moveq #0,D0 + moveq #0,D1 + moveq #0,D3 + moveq #0,D4 + lea crctab(PC),A2 +.loop_tos_crc: + move.w D0,D1 + lsl.l #8,D0 + lsr.l #8,D1 + move.b (A0),D3 + add.l A1,A0 + eor.l D3,D1 + move.w (A2,D1.l*2),D4 + eor.l D4,D0 + subq.l #1,D2 + bgt.s .loop_tos_crc + rts + #endif /* COLDFIRE */ - bsr get_cookie - move.l A0,D0 - beq.s .no_cookie_ct60 - move.l -4(A6),4(A0) // value -.no_cookie_ct60: - move.l -4(A6),D0 - clr.w -2(A6) - cmp.w #1000,D0 - bcs.s .low_100 - move.l D0,-(SP) - moveq #0x20,D0 - bsr display_char - move.l (SP)+,D0 -.low_100: - lea -6(A6),A0 - moveq #4,D1 - bsr conv_ascii_value - move.b -3(A6),-2(A6) - move.b #0x2E,-3(A6) - bsr display_string_single - unlk A6 - lea message18(PC),A0 // MHz - bsr display_string_single -#ifndef COLDFIRE - link A6,#-48 - pea -48(A6) // buffer - move.w #48,-(SP) // size - clr.w -(SP) // start - clr.w -(SP) // read - move.w #46,-(SP) // NVMaccess - trap #14 - lea 12(SP),SP - lea -48(A6),A0 // buffer - movem.l 32(A0),D3/D4 // ABE code, SDR code - unlk A6 - move.l D3,D0 - move.l D4,D1 - and.l #0xFF000000,D0 - and.l #0xFF000000,D1 - cmp.l #0x41000000,D0 - beq.s .code_hard - cmp.l #0x53000000,D1 - bne .no_code -.code_hard: - cmp.l #0x41000000,D0 - bne.s .no_abe_code - clr.l -(SP) - move.l #CT60_ABE_CODE,-(SP) - move.w #CT60_MODE_READ,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP - cmp.l D0,D3 - beq.s .no_abe_code - move.l D3,-(SP) - move.l #CT60_ABE_CODE,-(SP) - move.w #CT60_MODE_WRITE,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP -.no_abe_code: - move.l D4,D1 - and.l #0xFF000000,D1 - cmp.l #0x53000000,D1 - bne.s .no_code - clr.l -(SP) - move.l #CT60_SDR_CODE,-(SP) + +crctab: + dc.w 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7 + dc.w 0x8108,0x9129,0xa14a,0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef + dc.w 0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,0x72f7,0x62d6 + dc.w 0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de + dc.w 0x2462,0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485 + dc.w 0xa56a,0xb54b,0x8528,0x9509,0xe5ee,0xf5cf,0xc5ac,0xd58d + dc.w 0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,0x46b4 + dc.w 0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc + dc.w 0x48c4,0x58e5,0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823 + dc.w 0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,0x9969,0xa90a,0xb92b + dc.w 0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12 + dc.w 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a + dc.w 0x6ca6,0x7c87,0x4ce4,0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41 + dc.w 0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,0x8d68,0x9d49 + dc.w 0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70 + dc.w 0xff9f,0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78 + dc.w 0x9188,0x81a9,0xb1ca,0xa1eb,0xd10c,0xc12d,0xf14e,0xe16f + dc.w 0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,0x6067 + dc.w 0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e + dc.w 0x02b1,0x1290,0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256 + dc.w 0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,0xe54f,0xd52c,0xc50d + dc.w 0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405 + dc.w 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c + dc.w 0x26d3,0x36f2,0x0691,0x16b0,0x6657,0x7676,0x4615,0x5634 + dc.w 0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,0xb98a,0xa9ab + dc.w 0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3 + dc.w 0xcb7d,0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a + dc.w 0x4a75,0x5a54,0x6a37,0x7a16,0x0af1,0x1ad0,0x2ab3,0x3a92 + dc.w 0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,0x8dc9 + dc.w 0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1 + dc.w 0xef1f,0xff3e,0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8 + dc.w 0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,0x3eb2,0x0ed1,0x1ef0 + +init_sdram: + +#ifdef COLDFIRE + lea -56(SP),SP + movem.l D1-A6,(SP) + move.w SR,D0 + move.w D0,-(SP) + or.l #0x700,D0 // mask interrupts + move.w D0,SR + move.l #CACHE_DISABLE_MODE,D0 // invalidate whole cache + movec.l D0,CACR + nop + move.l #CACHE_ENABLE_MODE,D0 // enable caches + movec.l D0,CACR + move.w (SP)+,D0 + move.w D0,SR + pea linea000(PC) + move.w #47,-(SP) // TRAP #15 + move.w #5,-(SP) // Setexec + trap #13 + addq.l #8,SP // MAC instruction on Coldfire use opcodes 0xAxxx +#ifdef MCF547X + move.l #0x5F535749,D0 // _SWI + bsr get_cookie + move.l A0,D0 + beq.s .no_swi_cookie // no _SWI cookie + moveq #1,D1 + move.b boot_tos,D0 + and.l D0,D1 + move.l 4(A0),D0 // value + and.l #0xC0,D0 + or.l D1,D0 + move.l D0,4(A0) +.no_swi_cookie: +#endif /* MCF547X */ +#ifdef MCF5445X /* M54455EVB */ + moveq #2,D0 // SDRAM 256MB +#else +#ifdef MCF547X /* MCF547X - FIREBEE */ + moveq #3,D0 // SDRAM 512MB +#else /* MCF548X - M5484LITE */ + moveq #0,D0 // SDRAM 64MB +#endif /* MCF547X */ +#endif /* MCF5445X */ + clr.l ramtop +#else /* ATARI */ + movem.l D1-A6,-(SP) + bclr #5,0xFFFFFA07 // mask timer A + move.w SR,-(SP) + or #0x700,SR // no interrupts + cpusha BC + move.l #0xA0808000,D0 // caches on + movec.l D0,CACR + move.w (SP)+,SR + move.l #0x00E00FB6,8 // set access fault vector + move.b 0xFFFF8006,D0 + lsr.b #6,D0 // 0:ST mono, 1:ST col, 2:VGA, 3:TV + cmp.b #2,D0 // VGA + beq.s .ok_screen + move.l #0x5F465251,D0 // _FRQ cookie, internal clock + bsr get_cookie + cmp.l #32,D0 + bls.s .ok_screen + move.l #0x5F465245,D0 // _FRE cookie, external clock + bsr get_cookie + cmp.l #32,D0 + bne.s .ok_screen + bset #0,0xFFFF820A // external clock +.ok_screen: + clr.l -(SP) + move.l #CT60_BLITTER_SPEED,-(SP) move.w #CT60_MODE_READ,-(SP) move.w #rw_parameter,-(SP) trap #14 - lea 12(SP),SP - cmp.l D0,D4 - beq.s .no_code - move.l D4,-(SP) - move.l #CT60_SDR_CODE,-(SP) - move.w #CT60_MODE_WRITE,-(SP) + lea 12(SP),SP + btst #0,D0 + beq.s .blitter_slow + bset #2,0xFFFF8007 // blitter 16 MHz +.blitter_slow: + move.l ramtop,D0 // negative value is error code of ct60_configure_sdram from init_060 + bpl.s .no_error_cfg_sdram + clr.l ramtop // if error clear ramtop +.no_error_cfg_sdram: + move.l _sysbase,A0 // header ROM + move.l 0x24(A0),A0 // kbshift + move.b (A0),D1 + and.b #0xF,D1 + cmp.b #0x3,D1 // LSHIFT-RSHIFT + beq .test_ok // boot without SDRAM +#endif /* COLDFIRE */ + clr.l ramvalid + move.l D0,D5 // save return value of ct60_configure_sdram + bmi .error_pci // error SDRAM => no PCI +#ifdef COLDFIRE + move.l #SDRAM_SIZE-SDRAM_RESERVED,D1 + move.l D1,ramtop +#else + moveq #26,D1 + lsr.l D1,D5 + subq.l #1,D5 // for boot info, size 0-3 for 64MB-512MB + lea size_info(PC),A0 + move.b (A0,D5),D5 +#endif + move.l #0x1357BD13,ramvalid +#ifndef COLDFIRE + /* Clock generator */ + moveq #0,D4 // error code programmable clock generator + clr.l -(SP) + move.l #CT60_CLOCK,-(SP) + move.w #CT60_MODE_READ,-(SP) move.w #rw_parameter,-(SP) trap #14 - lea 12(SP),SP -.no_code: + lea 12(SP),SP +// cmp.l #MIN_FREQ_DALLAS/2,D0 + cmp.l #MIN_FREQ,D0 + bcs.s .bad_clock + cmp.l #MAX_FREQ,D0 + bhi.s .bad_clock + move.l _sysbase,A0 // header ROM + move.l 0x24(A0),A0 // kbshift + move.b (A0),D1 + and.b #0xF,D1 + cmp.b #4,D1 // CTRL + beq.s .reset_clock + cmp.b #8,D1 // ALT + beq.s .reset_clock + move.l D0,-(SP) // frequency clr.l -(SP) - move.l #CT60_ABE_CODE,-(SP) + move.l #CT60_USER_DIV_CLOCK,-(SP) move.w #CT60_MODE_READ,-(SP) move.w #rw_parameter,-(SP) trap #14 lea 12(SP),SP - move.l D0,D3 + move.l D0,D2 // divider + move.l (SP)+,D0 // frequency + cmp.l #2,D2 + blt.s .default_div_freq + cmp.l #6,D2 + ble.s .div_freq_ok +.default_div_freq: + move.l D0,D1 // frequency + divu #33000,D1 // PCI clock + moveq #0,D2 + move.w D1,D2 + swap D1 + tst.w D1 + beq.s .div_freq_ok + addq.l #1,D2 // divider +.div_freq_ok: + moveq #CT60_CLOCK_WRITE_RAM,D1 + bsr ct60_configure_clock + bra.s .delay_stable_clock +.reset_clock: + moveq #0,D2 + moveq #0,D1 + move.w #CT60_CLOCK_RESET+CYPRESS,D0 + bsr ct60_rw_clock +.delay_stable_clock: + move.l D0,D4 // error code programmable clock generator + bsr tempo_20ms +.bad_clock: +#endif /* !COLDFIRE */ + /* PCI */ + move.l _sysbase,A0 // header ROM + move.l 0x24(A0),A0 // kbshift + move.b (A0),D1 + and.b #0xF,D1 + cmp.b #4,D1 // CTRL + beq .error_pci + cmp.b #8,D1 // ALT + beq .error_pci +#ifdef COLDFIRE +#ifdef DEBUG + lea debug114(PC),A0 + bsr debug_display_string +#endif +#endif + move.w #1,-(SP) + move.w #299,-(SP) // install PCI BIOS + trap #14 + addq.l #4,SP + tst.w D0 + sgt.b D7 + and.l #1,D7 // (0) from reset, (1) from CTRL-ALT-DEL +#ifdef COLDFIRE + tst.w D0 + bmi .error_pci // no PCI ??? +#ifdef MCF547X + move.l #~ACP_CF_IDE,D0 + and.l D0,ACP_CONFIG // no swap IDE address +// move.l #ACP_DD_HD+ACP_IDE_INT_ENABLE+ACP_SCSI_INT_ENABLE,D0 + move.l #ACP_IDE_INT_ENABLE+ACP_SCSI_INT_ENABLE,D0 + or.l D0,ACP_CONFIG // floppy DD/HD selected by 0xFFFF860F clr.l -(SP) - move.l #CT60_SDR_CODE,-(SP) + move.l #CT60_PARAM_CTPCI,-(SP) move.w #CT60_MODE_READ,-(SP) move.w #rw_parameter,-(SP) trap #14 lea 12(SP),SP - move.l D0,D4 - move.l D3,D0 - move.l D4,D1 - and.l #0xFF000000,D0 - and.l #0xFF000000,D1 - moveq #0,D6 // flag display hardware - cmp.l #0x41000000,D0 - beq.s .code_hard_display - cmp.l #0x53000000,D1 - bne .no_code_display -.code_hard_display: - moveq #-1,D6 // flag display hardware - bsr crlf_spaces - lea message38(PC),A0 - bsr display_string_single - cmp.l #0x41000000,D0 - bne.s .no_abe_code_display - lea message39(PC),A0 - bsr display_string_single - move.l D3,D0 - swap D0 - and.w #0xFF,D0 - cmp.w #0x30,D0 - bcs.s .old_abe_code - cmp.w #0x39,D0 - bhi.s .old_abe_code - bsr display_char -.old_abe_code: - move.w D3,D0 - lsr.w #8,D0 - bsr display_char - move.w D3,D0 - and.w #0xFF,D0 - bsr display_char -.no_abe_code_display: - cmp.l #0x53000000,D1 - bne.s .no_code_display - lea message40(PC),A0 - bsr display_string_single - move.l D4,D0 - swap d0 - and.w #0xFF,D0 - cmp.w #0x30,D0 - bcs.s .old_sdr_code - cmp.w #0x39,D0 - bhi.s .old_sdr_code - bsr display_char -.old_sdr_code: - move.w D4,D0 - lsr.w #8,D0 - bsr display_char - move.w D4,D0 - and.w #0xFF,D0 - bsr display_char -.no_code_display: + btst #0,D0 + bne.s .no_swap_ide_cf + move.l #ACP_CF_IDE,D0 + or.l D0,ACP_CONFIG // swap IDE address +#ifdef DEBUG + lea debug140(PC),A0 + bsr debug_display_string +#endif +.no_swap_ide_cf: +#endif /* MCF547X */ +#else /* !COLDFIRE - 68060 */ + tst.w D0 + bmi.s .no_change_swap_ide_ctpci // no CTPCI clr.l -(SP) - move.l #CT60_CLOCK,-(SP) + move.l #CT60_PARAM_CTPCI,-(SP) move.w #CT60_MODE_READ,-(SP) move.w #rw_parameter,-(SP) trap #14 lea 12(SP),SP - cmp.l #MIN_FREQ_DALLAS/2,D0 - bcs .no_pclock_display - cmp.l #MAX_FREQ,D0 - bhi .no_pclock_display - tst.w D6 - bne.s .no_display_hard - bsr crlf_spaces - lea message38(PC),A0 - bsr display_string_single -.no_display_hard: - tst.l D7 // error code programmable clock generator - bpl.s .pclock_ok - moveq #0x20,D0 + tst.l D0 + bmi.s .no_change_swap_ide_ctpci + btst #0,D0 + beq.s .no_swap_ide_ctpci + clr.l _nideon // swap IDE ports, the new IDE on the CTPCI on primary, F030 IDE is secondary + clr.l _oideoff + bra.s .no_change_swap_ide_ctpci +.no_swap_ide_ctpci: + clr.l _nideoff // no swap IDE ports, the new IDE on the CTPCI is seconday, F030 IDE is the primary (default) + clr.l _oideon +.no_change_swap_ide_ctpci: +#endif /* COLDFIRE */ + bsr test_pci_drivers + bne.s .error_pci + move.l phystop,A1 + move.l hardware_type(A1),-(SP) // hardware flags + move.l D7,-(SP) // (0) from reset, (1) from CTRL-ALT-DEL + jsr 4(A0) // drivers PCI in flash, init_devices + addq.l #8,SP + tst.l D0 + bne.s .graphic_card + move.l _v_bas_ad,D0 + cmp.l #0x1000000,D0 + bcc.s .graphic_card +.error_pci: + /* display boot infos */ + moveq #0x1B,D0 // clear screen bsr display_char - lea error12(PC),A0 - cmp.w #CT60_CALC_CLOCK_ERROR,D7 - beq.s .pclock_error - lea error11(PC),A0 -.pclock_error: - bsr display_string - bra.s .no_pclock_display -.pclock_ok: - lea message99(PC),A0 - bsr display_string_single - cmp.l #100000,D0 // KHz - bcs.s .low_100000 - move.l D0,-(SP) - moveq #0x20,D0 + moveq #0x45,D0 bsr display_char - move.l (SP)+,D0 -.low_100000: - link A6,#-8 - clr.w -2(A6) - lea -8(A6),A0 - moveq #6,D1 - bsr conv_ascii_value - move.b -4(A6),-3(A6) - move.b -5(A6),-4(A6) - move.b #0x2E,-5(A6) - bsr display_string_single - unlk A6 - lea message18(PC),A0 // MHz - bsr display_string_single -.no_pclock_display: -#endif - lea crlf(PC),A0 +.graphic_card: + bsr spaces + lea message0(PC),A0 + cmp.w #2,0x3E86 // number of planes + bhi.s .title_colors + lea message0b(PC),A0 +.title_colors: + bsr display_string_single + bsr spaces +#ifdef COLDFIRE +#ifdef MCF5445X + move.w MCF_CCM_CIR,D0 + and.l #CCM_CIR_PIN_MASK,D0 + lea message8(PC),A0 + cmp.l #CCM_CIR_PIN_MCF54454,D0 + beq.s .v4m + lea message8a(PC),A0 + cmp.l #CCM_CIR_PIN_MCF54453,D0 + beq.s .v4m + lea message8b(PC),A0 + cmp.l #CCM_CIR_PIN_MCF54452,D0 + beq.s .v4m + lea message8c(PC),A0 + cmp.l #CCM_CIR_PIN_MCF54451,D0 + beq.s .v4m + lea message8d(PC),A0 + cmp.l #CCM_CIR_PIN_MCF54450,D0 + lea message10(PC),A0 +.v4m: +#else /* MCF548X */ + move.l MCF_SIU_JTAGID,D0 + and.l #MCF_SIU_JTAGID_PROCESSOR,D0 + lea message8(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5485,D0 + beq .v4e + lea message8a(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5484,D0 + beq.s .v4e + lea message8b(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5483,D0 + beq.s .v4e + lea message8c(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5482,D0 + beq.s .v4e + lea message8d(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5481,D0 + beq.s .v4e + lea message8e(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5480,D0 + beq.s .v4e + lea message9(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5475,D0 + beq.s .v4e + lea message9a(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5474,D0 + beq.s .v4e + lea message9b(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5473,D0 + beq.s .v4e + lea message9c(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5472,D0 + beq.s .v4e + lea message9d(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5471,D0 + beq.s .v4e + lea message9e(PC),A0 + cmp.l #MCF_SIU_JTAGID_MCF5470,D0 + beq.s .v4e + lea message10(PC),A0 +.v4e: +#endif /* MCF5445X */ +#else /* ATARI */ + movec.l PCR,D0 + swap D0 + lea message8(PC),A0 // 68060 + cmp.w #0x0430,D0 + beq.s .full_060 + lea message9(PC),A0 // 68EC060 / 68LC060 + cmp.w #0x0431,D0 + beq.s .ec_lc_060 + lea message10(PC),A0 +.full_060: +.ec_lc_060: +#endif /* COLDFIRE */ + bsr display_string +#ifdef COLDFIRE +#ifdef MCF5445X + move.w MCF_CCM_CIR,D0 + and.l #CCM_CIR_PRN_MASK,D0 // revision +#else /* MCF548X */ + move.l MCF_SIU_JTAGID,D0 + and.l #MCF_SIU_JTAGID_REV,D0 + moveq #28,D1 + lsr.l D1,D0 // revision +#endif /* MCF548X */ +#else /* ATARI */ + clr.w D0 + swap D0 + lsr.w #8,D0 // revision +#endif /* COLDFIRE */ + divu #10,D0 + and.w #7,D0 + beq.s .rev_less_10 + or.w #0x30,D0 + bsr display_char +.rev_less_10: + swap D0 + or.w #0x30,D0 + bsr display_char +#ifndef COLDFIRE + movec.l PCR,D0 + move.l D0,D1 + lsr.l #8,D1 + lea message11(PC),A0 + and.w #0x1FF,D1 + beq.s .display_mask // revision 0, mask D00W/D11W + lea message13(PC),A0 + cmp.w #2,D1 // revision 2, mask F84W + beq.s .display_mask + lea message14(PC),A0 + cmp.w #6,D1 // revision 1,5 mask F43G/G65V + bcc.s .display_mask // revision 6 and more mask E41J ? + bset #5,D0 // disable store/load bypass (masks 1,3,4,5) + movec.l D0,PCR + lea message12(PC),A0 +.display_mask: + btst #8,D1 + bne.s .mask_060_ok // mask info only for 060 full + bsr display_string +.mask_060_ok: +#endif /* !COLDFIRE */ + link A6,#-6 + bsr measure_cpu_frequency + move.l phystop,A0 + move.l D0,measure_clock(A0) + move.l D0,-4(A6) // CPU frequency in MHz * 10 +#ifdef COLDFIRE + move.l #0x5F43465F,D0 // _CF_ +#else /* 68060 */ +#if 1 + cmp.l #750,D0 + bcs.s .lower_75mhz + move.l #0x5F504349,D0 // cookie _PCI + bsr get_cookie + move.l A0,D0 + beq.s .lower_75mhz // no CTPCI registers + moveq #ITF+4,D0 // IDE Fast Timmings + normal space for CTPCI +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + cmp.l #PCI_MEMORY_OFFSET_2,pci_memory_offset(A0) + bne.s .normal_space + cmp.l #PCI_MEMORY_SIZE_2,pci_memory_size(A0) + bne.s .normal_space + cmp.l #PCI_IO_OFFSET_2,pci_io_offset(A0) + bne.s .normal_space + cmp.l #PCI_IO_SIZE_2,pci_io_size(A0) + bne.s .normal_space + bclr #2,D0 // enable all space for CTPCI +.normal_space: +#endif + move.l D0,PCI_CTPCI_CONFIG_RESET +.lower_75mhz: +#endif + move.l #0x43543630,D0 // CT60 +#endif /* COLDFIRE */ + bsr get_cookie + move.l A0,D0 + beq.s .no_cookie_ct60 + move.l -4(A6),4(A0) // value +.no_cookie_ct60: + move.l -4(A6),D0 + clr.w -2(A6) + cmp.w #1000,D0 + bcs.s .low_100 + move.l D0,-(SP) + moveq #0x20,D0 + bsr display_char + move.l (SP)+,D0 +.low_100: + lea -6(A6),A0 + moveq #4,D1 + bsr conv_ascii_value + move.b -3(A6),-2(A6) + move.b #0x2E,-3(A6) + bsr display_string_single + unlk A6 + lea message18(PC),A0 // MHz + bsr display_string_single +#ifndef COLDFIRE + moveq #0,D6 // flag display hardware + move.l phystop,A0 + move.l hardware_type(A0),D2 + move.l #ABE_SDR_7,D1 + and.l D2,D1 + beq.s .no_abe_sdr_7 + bsr display_1st_hardware_info + lea message39(PC),A0 + bsr display_string_single +.no_abe_sdr_7: + move.l #0x5F504349,D0 // cookie _PCI + bsr get_cookie + move.l A0,D0 + beq.s .no_pci_cookie + moveq #CTPCI_1ABCD,D1 + and.l D2,D1 + bne.s .no_ctpci_1e + bsr display_1st_hardware_info + lea message39a(PC),A0 + moveq #CTPCI_1M,D1 + and.l D2,D1 + beq.s .no_ctpci_1x + lea message39b(PC),A0 + moveq #CTPCI_1N,D1 + and.l D2,D1 + beq.s .no_ctpci_1x + lea message39c(PC),A0 +.no_ctpci_1x: + bsr display_string_single +.no_ctpci_1e: + move.l #ETHERNAT,D1 + and.l D2,D1 + beq.s .no_ethernat + bsr display_1st_hardware_info + lea message40(PC),A0 + bsr display_string_single +.no_ethernat: + move.l #SUPERVIDEL,D1 + and.l D2,D1 + beq.s .no_pci_cookie + bsr display_1st_hardware_info + lea message40a(PC),A0 + bsr display_string_single +.no_pci_cookie: + clr.l -(SP) + move.l #CT60_CLOCK,-(SP) + move.w #CT60_MODE_READ,-(SP) + move.w #rw_parameter,-(SP) + trap #14 + lea 12(SP),SP +// cmp.l #MIN_FREQ_DALLAS/2,D0 + cmp.l #MIN_FREQ,D0 + bcs .no_pclock_display + cmp.l #MAX_FREQ,D0 + bhi .no_pclock_display + bsr display_1st_hardware_info + tst.l D4 // error code programmable clock generator + bpl.s .pclock_ok + moveq #0x20,D0 + bsr display_char + lea error12(PC),A0 + cmp.w #CT60_CALC_CLOCK_ERROR,D4 + beq.s .pclock_error + lea error11(PC),A0 +.pclock_error: + bsr display_string + bra.s .no_pclock_display +.pclock_ok: + lea message99(PC),A0 + bsr display_string_single + cmp.l #100000,D0 // KHz + bcs.s .low_100000 + move.l D0,-(SP) + moveq #0x20,D0 + bsr display_char + move.l (SP)+,D0 +.low_100000: + link A6,#-8 + clr.w -2(A6) + lea -8(A6),A0 + moveq #6,D1 + bsr conv_ascii_value + move.b -4(A6),-3(A6) + move.b -5(A6),-4(A6) + move.b #0x2E,-5(A6) + bsr display_string_single + unlk A6 + lea message18(PC),A0 // MHz + bsr display_string_single +.no_pclock_display: +#endif /* !COLDFIRE */ + lea crlf(PC),A0 bsr display_string_single #ifdef COLDFIRE move.l D5,D0 // return value from ct60_configure_sdram -#else - move.l phystop,D0 - sub.l _memtop,D0 - cmp.l #RESERVE_MEM,D0 - beq .init_mmu // pmmu tree in STRAM & no SDRAM - move.l D5,D0 // return value from ct60_configure_sdram +#else + move.l D5,D0 // return value from ct60_configure_sdram bpl .ok_sdram move.w D0,D1 lea error9(PC),A0 @@ -2411,7 +3454,7 @@ init_sdram: bra.s .display_values_sdram .halt_no_sdram: bra.s .halt_no_sdram -#endif +#endif /* COLDFIRE */ .ok_sdram: move.l D0,D4 bsr crlf_spaces @@ -2432,51 +3475,8 @@ init_sdram: lea message6(PC),A0 bsr display_string #ifndef COLDFIRE - cmp.l #0x1357BD13,ramvalid - bne .bypass_test - cmp.l #0x752019F3,memvalid - bne.s .make_test - cmp.l #0x237698AA,memval2 - bne.s .make_test - cmp.l #0x5555AAAA,memval3 - beq .bypass_test -.make_test: - lea 0x1000000,A0 - move.l #0x01234567,D0 - move.l #0x89ABCDEF,D1 - move.l ramtop,A1 // end SDRAM -.loop_sdram_write: - movem.l D0-D1,(A0) // long - movem.w D0-D1,8(A0) // word - move.b D0,12(A0) // byte - rol.l #3,D0 - rol.l #3,D1 - add.l #0x2000,A0 // 8K step - cmp.l A1,A0 - bcs.s .loop_sdram_write - lea 0x1000000,A0 - move.l #0x01234567,D0 - move.l #0x89ABCDEF,D1 - cpusha BC // flush -.loop_sdram_test: - movem.l (A0),D2-D3 - cmp.l D0,D2 - bne.s .error_test - cmp.l D1,D3 - bne.s .error_test - movem.w 8(A0),D2-D3 - cmp.w D0,D2 - bne.s .error_test - cmp.w D1,D3 - bne.s .error_test - cmp.b 12(A0),D0 - bne.s .error_test - rol.l #3,D0 - rol.l #3,D1 - add.l #0x2000,A0 // 8K step - cmp.l A1,A0 - bcs.s .loop_sdram_test -.bypass_test: + bsr fast_test_sdram + bmi.s .error_test moveq #18,D0 // CAS laytency bsr read_i2c_sdram bmi.s .test_ok // error @@ -2516,37 +3516,7 @@ init_sdram: bra .error_sdram2 .test_ok: #endif /* COLDFIRE */ -.init_mmu: -#ifndef COLDFIRE - moveq #0,D7 - movec.l PCR,D0 - btst #16,D0 - bne.s .end_sdram // EC or LC - movec.l TC,D0 - btst #15,D0 // enable - bne.s .pmmu_already_in_use - move.l _sysbase,A0 // header ROM - move.l 0x24(A0),A0 // kbshift - move.b (A0),D0 - and.b #0xF,D0 - cmp.b #0x6,D0 // CTRL-LSHIFT - beq.s .end_sdram - clr.l -(SP) - clr.l -(SP) - lea _init_mmu_tree,A0 - add.l #FLASH_ADR+0x80000,A0 - sub.l #_ct60tos_half_flash,A0 - jsr (A0) - addq.l #8,SP - tst.l D0 - beq.s .end_sdram -.pmmu_already_in_use: -#endif bsr crlf_spaces - lea message51(PC),A0 // TOS in RAM - bsr display_string - moveq #-1,D7 -.end_sdram: clr.l -(SP) move.l #CT60_SAVE_NVRAM_1,-(SP) move.w #CT60_MODE_READ,-(SP) @@ -2554,99 +3524,94 @@ init_sdram: trap #14 lea 12(SP),SP swap D0 - cmp.w #0x4E56,D0 // NV magic code + cmp.w #0x4E56,D0 // NV magic code bne .no_nvm_read_saved - tst.w d7 - beq .no_tos_in_ram - lea separator(PC),A0 - bsr display_string_single - bra.s .tos_in_ram -.no_tos_in_ram: - bsr crlf_spaces -.tos_in_ram: - lea message51b(PC),A0 // NVRAM restored + lea message51(PC),A0 // NVRAM restored bsr display_string .no_nvm_read_saved: lea crlf(PC),A0 bsr display_string_single -#ifdef COLDFIRE -#ifdef MCF5445X - clr.b MCF_ATA_CR // control reset - move.l _hz_200,D1 -.delay_reset_ide: - move.l _hz_200,D0 - sub.l D1,D0 - cmp.l #2,D0 // 10 mS - ble.s .delay_reset_ide - /* IDE set */ - lea piotms+(2*9*2)(PC),A0 // PIO 2 - move.l #1000/SYSTEM_CLOCK,D1 // period in ns - moveq #0,D0 - move.w (A0)+,D0 // t1 - add.l D1,D0 // + period - sub.l #1,D0 - divu D1,D0 // / period - move.b D0,MCF_ATA_TIME_1 - moveq #0,D0 - move.w (A0)+,D0 // t2 - add.l D1,D0 // + period - sub.l #1,D0 - divu D1,D0 // / period - move.b D0,MCF_ATA_TIME_2W - move.b D0,MCF_ATA_TIME_2R - addq.l #2,A0 // t3 - moveq #0,D0 - move.w (A0)+,D0 // t4 - add.l D1,D0 // + period - sub.l #1,D0 - divu D1,D0 // / period - move.b D0,MCF_ATA_TIME_4 - addq.l #4,A0 // t5, t6 - moveq #0,D0 - move.w (A0)+,D0 // t9 - add.l D1,D0 // + period - sub.l #1,D0 - divu D1,D0 // / period - move.b D0,MCF_ATA_TIME_9 - moveq #0,D0 - move.w (A0)+,D0 // tRD - add.l D1,D0 // + period - sub.l #1,D0 - divu D1,D0 // / period - move.b D0,MCF_ATA_TIME_PIORDX - moveq #0,D0 - move.w (A0)+,D0 // tA - add.l D1,D0 // + period - sub.l #1,D0 - divu D1,D0 // / period - move.b D0,MCF_ATA_TIME_AX - moveq #0x40,D0 // IORDY enable - move.b D0,MCF_ATA_CR - move.l _hz_200,D1 -.delay_end_reset_ide: - move.l _hz_200,D0 - sub.l D1,D0 - cmp.l #40,D0 // 200 mS - ble.s .delay_end_reset_ide - bset #0,MCF_ATA_CR // IORDY enable +#if defined(COLDFIRE) && (defined(MCF5445X) || (defined MCF547X)) +#ifdef DEBUG + lea debug133(PC),A0 + bsr debug_display_string #endif + jsr ide_reset #endif movem.l (SP)+,D1-A6 rts - -#ifdef COLDFIRE -#ifdef MCF5445X - /* t1, t2, t3, t4, t5,t6, t9,tRD, tA */ -piotms: - dc.w 70, 165, 60, 30, 50, 5, 20, 0, 35 /* PIO 0 */ - dc.w 50, 125, 45, 20, 35, 5, 15, 0, 35 /* PIO 1 */ - dc.w 30, 100, 30, 15, 20, 5, 10, 0, 35 /* PIO 2 */ - dc.w 30, 80, 30, 10, 20, 5, 10, 0, 35 /* PIO 3 */ - dc.w 25, 70, 20, 10, 20, 5, 10, 0, 35 /* PIO 4 */ -#endif +#ifndef COLDFIRE /* ATARI - CT60 */ -#else /* ATARI - CT60 */ +size_info: + dc.b 0,1,1,2,2,2,2,3 + +display_1st_hardware_info: + + tst.w D6 + bne.s .no_1st_hardware_info + moveq #-1,D6 // flag display hardware + bsr crlf_spaces + lea message38(PC),A0 + bsr display_string_single +.no_1st_hardware_info: + rts + +fast_test_sdram: + + movem.l D0-D3/A0-A1,-(SP) + cmp.l #0x1357BD13,ramvalid + bne .bypass_test + cmp.l #0x752019F3,memvalid + bne.s .make_test + cmp.l #0x237698AA,memval2 + bne.s .make_test + cmp.l #0x5555AAAA,memval3 + beq .bypass_test +.make_test: + lea 0x1000000,A0 + move.l #0x01234567,D0 + move.l #0x89ABCDEF,D1 + move.l ramtop,A1 // end SDRAM +.loop_sdram_write: + movem.l D0-D1,(A0) // long + movem.w D0-D1,8(A0) // word + move.b D0,12(A0) // byte + rol.l #3,D0 + rol.l #3,D1 + add.l #0x2000,A0 // 8K step + cmp.l A1,A0 + bcs.s .loop_sdram_write + lea 0x1000000,A0 + move.l #0x01234567,D0 + move.l #0x89ABCDEF,D1 + cpusha BC // flush +.loop_sdram_test: + movem.l (A0),D2-D3 + cmp.l D0,D2 + bne.s .error_test_sdram + cmp.l D1,D3 + bne.s .error_test_sdram + movem.w 8(A0),D2-D3 + cmp.w D0,D2 + bne.s .error_test_sdram + cmp.w D1,D3 + bne.s .error_test_sdram + cmp.b 12(A0),D0 + bne.s .error_test_sdram + rol.l #3,D0 + rol.l #3,D1 + add.l #0x2000,A0 // 8K step + cmp.l A1,A0 + bcs.s .loop_sdram_test +.bypass_test: + moveq #0,D0 + movem.l (SP)+,D0-D3/A0-A1 + rts +.error_test_sdram: + moveq #-1,D0 + movem.l (SP)+,D0-D3/A0-A1 + rts display_infos_sdram: @@ -2997,18 +3962,25 @@ dump: measure_cpu_frequency: // return CPU frequency in MHz * 10 +#ifdef COLDFIRE + lea -12(SP),SP + movem.l D1-D3,(SP) + move.w SR,D2 + move.w D2,-(SP) +#else movem.l D1-D3,-(SP) move.w SR,-(SP) +#endif /* COLDFIRE */ move.w #0x2500,SR moveq #0,D0 + moveq #9,D2 move.l _hz_200,D1 .sync_timer: cmp.l _hz_200,D1 beq.s .sync_timer - moveq #9,D2 .next_mes: - move.l _hz_200,D1 moveq #0,D3 + move.l _hz_200,D1 .loop_mes: addq.l #1,D3 cmp.l _hz_200,D1 @@ -3017,13 +3989,17 @@ measure_cpu_frequency: // return CPU frequency in MHz * 10 bcs.s .not_maxi move.l D3,D0 .not_maxi: - dbf D2,.next_mes - move.w (SP)+,SR #ifdef COLDFIRE + subq.l #1,D2 + bpl.s .next_mes + move.w (SP)+,D2 + move.w D2,SR divu #125,D0 // MHz * 10 #else + dbf D2,.next_mes + move.w (SP)+,SR divu #250,D0 // MHz * 10 -#endif +#endif /* COLDFIRE */ swap D0 tst.w D0 beq.s .end_mes @@ -3032,7 +4008,12 @@ measure_cpu_frequency: // return CPU frequency in MHz * 10 clr.w D0 swap D0 tst.l D0 +#ifdef COLDFIRE + movem.l (SP),D1-D3 + lea 12(SP),SP +#else movem.l (SP)+,D1-D3 +#endif /* COLDFIRE */ rts get_cookie: @@ -3066,14 +4047,62 @@ tab_boot_order: .word message101-tab_boot_order .word message102-tab_boot_order .word message103-tab_boot_order +#ifndef COLDFIRE .word message104-tab_boot_order .word message105-tab_boot_order .word message106-tab_boot_order .word message107-tab_boot_order -#endif +tab_boot_order_ctpci: + .word message100b-tab_boot_order_ctpci + .word message101b-tab_boot_order_ctpci + .word message102b-tab_boot_order_ctpci + .word message103b-tab_boot_order_ctpci + .word message104b-tab_boot_order_ctpci + .word message105b-tab_boot_order_ctpci + .word message106b-tab_boot_order_ctpci + .word message107b-tab_boot_order_ctpci +#endif /* COLDFIRE */ +#endif /* USE_ATARI_IO */ +tab_partition: + .word message109-tab_partition + .word message110-tab_partition + .word message111-tab_partition + .word message112-tab_partition + .word message113-tab_partition + .word message114-tab_partition + .word message115-tab_partition + .word message116-tab_partition + .word message117-tab_partition + .word message118-tab_partition + .word message119-tab_partition + .word message120-tab_partition + .word message121-tab_partition + .word message122-tab_partition + .word message123-tab_partition + .word message124-tab_partition + .word message125-tab_partition -#ifndef COLDFIRE +#if 0 +tab_vdo_cookie: + .word message128-tab_vdo_cookie + .word message129-tab_vdo_cookie + .word message130-tab_vdo_cookie + .word message131-tab_vdo_cookie + .word message132-tab_vdo_cookie + .word message133-tab_vdo_cookie +#endif +#ifdef COLDFIRE +env: .asciz "PATH=" + .asciz "#:\\" + .asciz "SDL_AUDIODRIVER=" + .asciz "mint_gsxb" + .asciz "SDL_VIDEODRIVER=" + .asciz "gem" + .asciz "SDL_ATARI_EVENTSDRIVER=" + .asciz "gemdos" + .byte 0 +#else error1: .asciz "SDRAM not found" .asciz "SDRAM non trouv‚e" error2: .asciz "SDRAM chip density error" @@ -3098,7 +4127,7 @@ error11: .asciz "CTCM not found" .asciz "CTCM non trouv‚e" error12: .asciz "CTCM frequency error" .asciz "CTCM erreur fr‚quence" -#endif +#endif /* COLDFIRE */ error13: .byte 13,10 .ascii "CTPCI not found" .byte 13,10,0 @@ -3117,8 +4146,8 @@ message0: .byte 0x1B,0x62,0x34,0x41 #ifdef MCF5445X /* M54455EVB */ .ascii "M54455EVB" #else -#ifdef MCF547X /* MCF547X - COLDARI */ - .ascii "COLDARI" +#ifdef MCF547X /* MCF547X - FIREBEE */ + .ascii "FIREBEE" #else /* MCF548X - M5484LITE */ .ascii "M5484LITE/M5485EVB" #endif /* MCF547X */ @@ -3136,8 +4165,8 @@ message0b: #ifdef MCF5445X /* M54455EVB */ .ascii "ATARI M54455EVB TOS4.04" #else -#ifdef MCF547X /* MCF547X - COLDARI */ - .ascii "COLDARI TOS4.04" +#ifdef MCF547X /* MCF547X - FIREBEE */ + .ascii "FIREBEE TOS4.04" #else /* MCF548X - M5484LITE */ .ascii "ATARI M5484LITE/M5485EVB TOS4.04" #endif /* MCF547X */ @@ -3155,6 +4184,7 @@ message4: .asciz "256" message5: .asciz "512" message6: .asciz "MB detected" .asciz "Mo d‚tect‚e" +message7: .asciz "TOS drivers v" #ifdef COLDFIRE #ifdef MCF5445X message8: .asciz "MCF54455 Rev." @@ -3214,10 +4244,8 @@ message14: .asciz " Mask E41J" // revision 6 #endif message15: .byte 27 .asciz "p Boot v" -message15a: - .asciz " alpha " -message15b: - .ascii " " +message15a: .asciz " beta 11 " // additionnal information about version (alpha, beta...) +message15b: .ascii " " .byte 27 .ascii "q" .byte 13,10,0 @@ -3317,9 +4345,13 @@ message37: .byte 13,10 .byte 13,10 .asciz "Octet 21, Attributs du module : $" message38: .asciz "CT60 hardware" -message39: .asciz " ABEv" -message40: .asciz " SDRv" -#endif +message39: .asciz " ABE/SDR7+" +message39a: .asciz " CTPCI_1E-1L" +message39b: .asciz " CTPCI_1M" +message39c: .asciz " CTPCI_1N" +message40: .asciz " ETHERNAT" +message40a: .asciz " SUPERVIDEL" +#endif /* COLDFIRE */ #ifdef USE_ATARI_IO message41: .byte 13,10 .asciz "SCSI " @@ -3340,12 +4372,7 @@ message48: .asciz "boot in progress " message49: .asciz " -> " message50: .asciz "no XBRA" .asciz "pas de XBRA" -message51: -// .asciz "TOS copied to SDRAM (0-1FFF E00000-EEFFFF)" - .asciz "TOS copied to SDRAM" -// .asciz "TOS copi‚ en SDRAM (0-1FFF E00000-EEFFFF)" - .asciz "TOS copi‚ en SDRAM" -message51b: .asciz "NVRAM unused" +message51: .asciz "NVRAM unused" .asciz "NVRAM non utilis‚e" message52: .byte 13,10 .asciz "Reset" @@ -3399,10 +4426,27 @@ message75: .byte 13,10 .asciz "Keyboard OK " .byte 13,10 .asciz "Clavier OK " +#ifndef MCF547X +message76b: +#endif message76: .byte 13,10 +#ifdef MCF547X + .asciz "Atari keyboard failure, interrupt disabled" +#else .asciz "Keyboard failure" +#endif .byte 13,10 +#ifdef MCF547X + .asciz "Pas de r‚ponse du clavier Atari, interruption inhib‚e" +#else .asciz "Pas de r‚ponse du clavier" +#endif +#ifdef MCF547X +message76b: .byte 13,10 + .asciz "Keyboard failure for Eiffel test" + .byte 13,10 + .asciz "Pas de r‚ponse du clavier pour le test Eiffel" +#endif message77: .byte 13,10,27 .ascii "p Choice of the system : " .byte 27 @@ -3494,6 +4538,16 @@ message98: .byte 13,10 message99: .asciz " CTCM" #endif #ifdef USE_ATARI_IO +#ifdef COLDFIRE +message100: .asciz " New boot SCSI0-7 -> IDE0-3 " + .asciz " Nouveau boot SCSI0-7 -> IDE0-3 " +message101: .asciz " New boot IDE0-3 -> SCSI0-7 " + .asciz " Nouveau boot IDE0-3 -> SCSI0-7 " +message102: .asciz " New boot SCSI7-0 -> IDE3-0 " + .asciz " Nouveau boot SCSI7-0 -> IDE3-0 " +message103: .asciz " New boot IDE3-0 -> SCSI7-0 " + .asciz " Nouveau boot IDE3-0 -> SCSI7-0 " +#else message100: .asciz " New boot SCSI0-7 -> IDE0-1 " .asciz " Nouveau boot SCSI0-7 -> IDE0-1 " message101: .asciz " New boot IDE0-1 -> SCSI0-7 " @@ -3509,7 +4563,24 @@ message105: .asciz " Old boot IDE0-1 -> SCSI0-7 " message106: .asciz " Old boot SCSI7-0 -> IDE1-0 " .asciz " Vieux boot SCSI7-0 -> IDE1-0 " message107: .asciz " Old boot IDE1-0 -> SCSI7-0 " - .asciz " Vieux boot IDE1-0 -> SCSI7-0 " + .asciz " Vieux boot IDE0-1 -> SCSI7-0 " +message100b: .asciz " New boot SCSI0-7 -> IDE0-3 " + .asciz " Nouveau boot SCSI0-7 -> IDE0-3 " +message101b: .asciz " New boot IDE0-3 -> SCSI0-7 " + .asciz " Nouveau boot IDE0-3 -> SCSI0-7 " +message102b: .asciz " New boot SCSI7-0 -> IDE3-0 " + .asciz " Nouveau boot SCSI7-0 -> IDE3-0 " +message103b: .asciz " New boot IDE3-0 -> SCSI7-0 " + .asciz " Nouveau boot IDE3-0 -> SCSI7-0 " +message104b: .asciz " Old boot SCSI0-7 -> IDE0 " + .asciz " Vieux boot SCSI0-7 -> IDE0 " +message105b: .asciz " Old boot IDE0--> SCSI0-7 " + .asciz " Vieux boot IDE0 -> SCSI0-7 " +message106b: .asciz " Old boot SCSI7-0 -> IDE0 " + .asciz " Vieux boot SCSI7-0 -> IDE0 " +message107b: .asciz " Old boot IDE0 -> SCSI7-0 " + .asciz " Vieux boot IDE0 -> SCSI7-0 " +#endif message108: .byte 13,10,27 .ascii "p Boot order selection for IDE and SCSI drives : " .byte 27 @@ -3520,6 +4591,74 @@ message108: .byte 13,10,27 .byte 27 .ascii "q" .byte 13,10,0 +#endif /* USE_ATARI_IO */ +message109: .asciz " Ignore this disk " + .asciz " Ignorer ce disque " +message110: .asciz " Partition 1 " + .asciz " Partition 1 " +message111: .asciz " Partition 2 " + .asciz " Partition 2 " +message112: .asciz " Partition 3 " + .asciz " Partition 3 " +message113: .asciz " Partition 4 " + .asciz " Partition 4 " +message114: .asciz " Partition 5 " + .asciz " Partition 5 " +message115: .asciz " Partition 6 " + .asciz " Partition 6 " +message116: .asciz " Partition 7 " + .asciz " Partition 7 " +message117: .asciz " Partition 8 " + .asciz " Partition 8 " +message118: .asciz " Partition 9 " + .asciz " Partition 9 " +message119: .asciz " Partition 10 " + .asciz " Partition 10 " +message120: .asciz " Partition 11 " + .asciz " Partition 11 " +message121: .asciz " Partition 12 " + .asciz " Partition 12 " +message122: .asciz " Partition 13 " + .asciz " Partition 13 " +message123: .asciz " Partition 14 " + .asciz " Partition 14 " +message124: .asciz " Partition 15 " + .asciz " Partition 15 " +message125: .asciz " Partition 16 " + .asciz " Partition 16 " +message126: .byte 13,10,27 + .ascii "p No boot partition found, selection for this disk : " + .byte 27 + .ascii "q" + .byte 13,10,0 + .byte 13,10,27 + .ascii "p Pas de partition de boot, s‚lection pour ce disque : " + .byte 27 + .ascii "q" + .byte 13,10,0 +#if 0 +message127: .byte 13,10,27 + .ascii "p _VDO cookie for NVDI : " + .byte 27 + .ascii "q" + .byte 13,10,0 + .byte 13,10,27 + .ascii "p Cookie _VDO pour NVDI : " + .byte 27 + .ascii "q" + .byte 13,10,0 +message128: .asciz " ST " + .asciz " ST " +message129: .asciz " STE " + .asciz " STE " +message130: .asciz " TT " + .asciz " TT " +message131: .asciz " FALCON " + .asciz " FALCON " +message132: .asciz " MILAN " + .asciz " MILAN " +message133: .asciz " ARANYM " + .asciz " ARANYM " #endif blue: .byte 0x1B,0x62,0x34,0 @@ -3562,14 +4701,25 @@ debug17: .byte 13,10 .asciz "Initialize Device Parameters: " #endif -#ifndef USE_ATARI_IO -boot_ide: .byte 16,17,255 -#else +#ifdef USE_ATARI_IO +#if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ +boot_scsi: .byte 8,9,10,11,12,13,14,15,16,17,18,19,255 +boot_ide: .byte 16,17,18,19,8,9,10,11,12,13,14,15,255 +boot_scsi_2: .byte 15,14,13,12,11,10,9,8,19,18,17,16,255 +boot_ide_2: .byte 19,18,17,16,15,14,13,12,11,10,9,8,255 +#else /* <> FIREBEE */ boot_scsi: .byte 8,9,10,11,12,13,14,15,16,17,255 boot_ide: .byte 16,17,8,9,10,11,12,13,14,15,255 boot_scsi_2: .byte 15,14,13,12,11,10,9,8,17,16,255 boot_ide_2: .byte 17,16,15,14,13,12,11,10,9,8,255 -#endif +boot_scsi_ctpci: .byte 8,9,10,11,12,13,14,15,16,17,18,19,255 +boot_ide_ctpci: .byte 16,17,18,19,8,9,10,11,12,13,14,15,255 +boot_scsi_2_ctpci: .byte 15,14,13,12,11,10,9,8,19,18,17,16,255 +boot_ide_2_ctpci: .byte 19,18,17,16,15,14,13,12,11,10,9,8,255 +#endif /* defined(COLDFIRE) && defined(MCF547X) */ +#else /* !USE_ATARI_IO */ +boot_ide: .byte 16, /* 17, */ 255 +#endif /* USE_ATARI_IO */ tab_os: .byte 0x80,8,0x10 @@ -3635,7 +4785,7 @@ list_device_type: boot_drive: movem.l D0-A5,-(SP) - link A6,#-18 + link A6,#-24 #ifdef COLDFIRE bset #5,0xFFFFFA01 // for IDE emulation (SRAM) // clr.l save_ide_registers @@ -3645,8 +4795,9 @@ boot_drive: // move.l D0,old_access_error // lea access_error_ide(PC),A0 // move.l A0,2*4(A1) // to fix with MMU update_tlb access fault !!! - bsr install_scsidrv #endif + jsr install_scsidrv + move.l hdv_rw,-22(A6) move.w #3,-(SP) // TT ram if possible move.l #pinfo_size,-(SP) move.w #0x44,-(SP) // Mxalloc @@ -3669,6 +4820,13 @@ boot_drive: clr.w -(A1) cmp.l A0,A1 bgt.s .clrpun + lea pinfo_cookie(A3),A0 + move.l #0x41484449,(A0) // AHDI + move.l A0,4(A0) + move.w #0x0300,D0 + move.w D0,pinfo_vernum(A3) + move.w #0x4000,D0 + move.w D0,pinfo_maxsiz(A3) .no_pinfo: clr.l -(SP) move.l #CT60_BOOT_ORDER,-(SP) @@ -3676,7 +4834,24 @@ boot_drive: move.w #rw_parameter,-(SP) trap #14 lea 12(SP),SP - move.b D0,-18(A6) + cmp.l #-1,D0 + bne.s .param_boot_ok + moveq #1,D0 // force new boot IDE0-1/SCSI0-7 +.param_boot_ok: + // 0: New boot SCSI0-7 -> IDE0-1 + // 1: New boot IDE0-1 -> SCSI0-7 + // 2: New boot SCSI7-0 -> IDE1-0 + // 3: New boot IDE1-0 -> SCSI7-0 + // 4: Old boot SCSI0-7 -> IDE0-1 + // 5: Old boot IDE0-1 -> SCSI0-7 + // 6; Old boot SCSI7-0 -> IDE1-0 + // 7: Old boot IDE1-0 -> SCSI7-0 +#ifdef COLDFIRE + and.l #0xFFFF0003,D0 +#endif + move.b D0,-18(A6) // boot order 0-7 (0-3 on Coldfire) + swap D0 + move.w D0,-24(A6) // device mask (B11-B8: IDE3-0, B7-B0: SCSI7-0) #ifdef USE_ATARI_IO bsr test_key beq.s .no_key_pressed @@ -3686,14 +4861,43 @@ boot_drive: cmp.w #0x63,D0 // c bne.s .no_key_pressed .c_key_pressed: + lea tab_boot_order(PC),A1 +#ifndef COLDFIRE + move.l #0x5F504349,D0 // cookie _PCI + bsr get_cookie + beq.s .no_pci_cookie_for_menu + lea tab_boot_order_ctpci(PC),A1 +.no_pci_cookie_for_menu: +#endif /* COLDFIRE */ moveq #0,D0 move.b -18(A6),D0 +#ifdef COLDFIRE + moveq #4,D1 // nb lines +#else moveq #8,D1 // nb lines +#endif lea message108(PC),A0 - lea tab_boot_order(PC),A1 bsr common_menu move.b D0,-18(A6) .no_key_pressed: +#ifndef COLDFIRE + move.l #0x5F504349,D0 // cookie _PCI + bsr get_cookie + beq.s .no_pci_cookie_for_ide + move.b -18(A6),D0 + lea boot_scsi_ctpci(PC),A5 + and.w #3,D0 + beq.s .loop_drive + lea boot_ide_ctpci(PC),A5 + cmp.w #1,D0 + beq.s .loop_drive + lea boot_scsi_2_ctpci(PC),A5 + cmp.w #2,D0 + beq.s .loop_drive + lea boot_ide_2_ctpci(PC),A5 + bra.s .loop_drive +.no_pci_cookie_for_ide: +#endif /* COLDFIRE */ move.b -18(A6),D0 lea boot_scsi(PC),A5 and.w #3,D0 @@ -3721,11 +4925,32 @@ boot_drive: trap #1 addq.l #8,SP move.l D0,-16(A6) // IDE buffer normally in SDRAM + move.w 0x840,D4 + move.b (A5,D4.w),D4 moveq #1,D1 // counter logical unit +#if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ + move.l _sysbase,A0 // header ROM + move.l 0x24(A0),A0 // kbshift + move.b (A0),D0 + btst #2,D0 // CTRL + bne.s .loop2_drive + moveq #0,D0 + bset D4,D0 + lsr.l #8,D0 + and.w -24(A6),D0 // device mask + bne .next_drive // disabled +#endif /* defined(COLDFIRE) && defined(MCF547X) */ .loop2_drive: move.w D1,-(SP) // logical unit - move.w 0x840,D4 - move.b (A5,D4.w),D4 + move.l _dskbufp,A0 + move.l #(1024/16),D0 +.loop_clear_dskbufp: + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + subq.l #1,D0 + bgt.s .loop_clear_dskbufp cmp.w #2,0x3E86 // number of planes bls.s .black_and_white lea blue(PC),A0 @@ -3780,22 +5005,24 @@ boot_drive: move.b D1,4(A1) // length clr.b 5(A1) moveq #6,D2 // cmd bytes length - bsr scsi_cmd + jsr scsi_cmd bmi .no_answer // time-out #ifdef DEBUG move.l _dskbufp,A1 moveq #5,D1 bsr dump +#ifndef COLDFIRE bsr wait_key +#endif moveq #13,D0 bsr display_char moveq #10,D0 - bsr display_char + bsr display_char #endif move.l _dskbufp,A0 cmp.b #0x7F,(A0) // qualifier = 3 & no device type beq .no_logical_unit - addq.w #8,A0 + addq.l #8,A0 lea 24(A0),A1 moveq #23,D1 .last_space_infos_device_scsi: @@ -3824,16 +5051,15 @@ boot_drive: move.l _dskbufp,A0 // IDE buffer lea -8(A6),A1 // cmd buffer move.b #0x08,(A1) // device reset - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.w 4(A1) // sec num & count clr.b 6(A1) // features moveq #0,D0 // bytes - bsr ide_cmd + jsr ide_cmd #endif #ifdef DEBUG lea debug6(PC),A0 @@ -3843,16 +5069,15 @@ boot_drive: move.l _dskbufp,A0 // IDE buffer lea -8(A6),A1 // cmd buffer move.b #0xA1,(A1) // identify packet device - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.w 4(A1) // sec num & count clr.b 6(A1) // features move.l #512,D0 // bytes - bsr ide_cmd + jsr ide_cmd beq.s .found_ide_drive #ifdef DEBUG lea debug7(PC),A0 @@ -3863,16 +5088,15 @@ boot_drive: clr.w (A0) lea -8(A6),A1 // cmd buffer move.b #0xEC,(A1) // identify device - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.w 4(A1) // sec num & count clr.b 6(A1) // features move.l #512,D0 // bytes - bsr ide_cmd + jsr ide_cmd move.l _dskbufp,A0 // IDE buffer cmp.w #0x848A,(A0) // CompactFlash beq.s .compactflash_found @@ -3899,7 +5123,9 @@ boot_drive: move.l _dskbufp,A1 moveq #15,D1 bsr dump +#ifndef COLDFIRE bsr wait_key +#endif moveq #13,D0 bsr display_char moveq #10,D0 @@ -3950,7 +5176,9 @@ boot_drive: bset #31,D7 // removable media flags lea message83(PC),A0 // removable bsr display_string -.check_total_sectors: +.check_total_sectors: + btst #4,D4 + beq .read_root // SCSI move.l _dskbufp,A0 // IDE buffer cmp.w #0x848A,(A0) // CompactFlash beq .read_root @@ -4002,19 +5230,18 @@ boot_drive: #endif lea -8(A6),A1 // cmd buffer move.b #0x91,(A1) // initialize device parameters - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 or.b D2,D0 // max head - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.b 4(A1) // sec num move.b D1,5(A1) // sector count, logical sectors / track clr.b 6(A1) // features moveq #0,D0 // bytes - bsr ide_cmd -#ifdef DEBUG + jsr ide_cmd +#if 0 // #ifdef DEBUG btst #0,D0 // state, ERR beq .no_error_init_dev moveq #0,D0 @@ -4043,7 +5270,7 @@ boot_drive: .test_media_scsi: #ifdef DEBUG move.l #200,D0 - bsr delay_hz_200 + jsr delay_hz_200 lea debug3(PC),A0 bsr display_string_single #endif @@ -4057,7 +5284,7 @@ boot_drive: clr.w 2(A1) clr.w 4(A1) // length moveq #6,D2 // cmd bytes length - bsr scsi_cmd + jsr scsi_cmd bmi .no_answer_2 // time-out beq .no_removable_media // good #ifdef DEBUG @@ -4078,7 +5305,7 @@ boot_drive: move.b D1,4(A1) // length clr.b 5(A1) moveq #6,D2 // cmd bytes length - bsr scsi_cmd + jsr scsi_cmd bmi .no_answer_2 // time-out move.l _dskbufp,A0 // DMA buffer #ifdef DEBUG @@ -4160,39 +5387,37 @@ boot_drive: clr.w (A0) lea -8(A6),A1 // cmd buffer move.b #0xEF,(A1) // set features - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.w 4(A1) // sec num & count move.b #0x95,6(A1) // features, enable media status notification moveq #0,D0 // bytes - bsr ide_cmd + jsr ide_cmd #ifdef DEBUG bsr hex_byte #endif .test_media_ide: #ifdef DEBUG move.l #200,D0 - bsr delay_hz_200 + jsr delay_hz_200 lea debug2(PC),A0 bsr display_string_single #endif move.l _dskbufp,A0 // IDE buffer lea -8(A6),A1 // cmd buffer move.b #0xDA,(A1) // get media status - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.w 4(A1) // sec num & count clr.b 6(A1) // features moveq #0,D0 // bytes - bsr ide_cmd + jsr ide_cmd bmi.s .no_answer_3 #ifdef DEBUG move.w D0,-(SP) @@ -4230,16 +5455,15 @@ boot_drive: move.l _dskbufp,A0 // IDE buffer lea -8(A6),A1 // cmd buffer move.b #0xA0,(A1) // packet - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xA0,D0 move.b D0,1(A1) // drive (C/D/H) move.w #0x200,2(A1) // cyl high & low, byte count limit clr.w 4(A1) // sec num & count clr.b 6(A1) // features moveq #0,D0 // bytes - bsr ide_cmd + jsr ide_cmd .no_packet: #ifdef USE_ATARI_IO tst.l -16(A6) // IDE buffer @@ -4254,17 +5478,17 @@ boot_drive: move.l -16(A6),A0 // IDE buffer normally in SDRAM lea -8(A6),A1 // cmd buffer move.b #0x20,(A1) // read sector(s) - moveq #7,D0 + moveq #3,D0 and.w D4,D0 // drive asl.w #4,D0 - or.b #0xE0,D0 // LBA + or.b #0x40,D0 // LBA move.b D0,1(A1) // drive (C/D/H) clr.w 2(A1) // cyl high & low clr.b 4(A1) // sec num move.b #SPEED_BUFFER_SIZE/512,5(A1) // sec count clr.b 6(A1) // features move.l #SPEED_BUFFER_SIZE,D0 // bytes - bsr ide_cmd + jsr ide_cmd bne.s .drive_not_ok_ide dbf D3,.loop_speed_ide move.l D1,D0 @@ -4285,3668 +5509,1074 @@ boot_drive: bra .no_read_error .read_ide_error: lea message46(PC),A0 // read error -#ifdef DEBUG +#if 0 // #ifdef DEBUG btst #16,D7 // flag PACKET - beq .no_read_error - btst #0,D0 // state, ERR - beq .no_read_error - moveq #0,D0 - move.b ATA_ERROR_REGISTER,D0 // error register - bsr hex_byte - moveq #0x20,D0 - bsr display_char - moveq #0,D0 -#endif - bra .no_read_error -#ifdef USE_ATARI_IO -.scsi_drive_2: - tst.l -12(A6) // SCSI buffer - beq .default_tos_routine -#ifdef DEBUG - lea debug11(PC),A0 - bsr display_string_single - move.l -12(A6),A0 - moveq #127,D0 -.loop_raz_buffer: - clr.l (A0)+ - dbf D0,.loop_raz_buffer -#endif - moveq #1,D3 -.loop_speed_scsi: - move.w D4,D0 // drive - move.l -12(A6),A0 // DMA buffer - lea -6(A6),A1 // cmd buffer - move.b #0x08,(A1) // read - move.w (SP),D1 // logical unit - asl.w #5,D1 - move.b D1,1(A1) // logical unit - clr.w 2(A1) // logical block address - move.b #SPEED_BUFFER_SIZE/512,4(A1) // num blocks - clr.b 5(A1) // control - move.l #SPEED_BUFFER_SIZE,D1 // DMA bytes length - moveq #6,D2 // cmd bytes length - bsr scsi_cmd - bne .drive_not_ok_scsi // error - dbf D3,.loop_speed_scsi - move.l D1,D0 - bsr display_mb_by_sec_disk - moveq #0,D0 // no error - move.l -12(A6),A0 // SCSI buffer - move.l _dskbufp,A1 - moveq #127,D1 // 512 bytes -.copy_buffer_scsi: - move.l (A0)+,(A1)+ - dbf D1,.copy_buffer_scsi -.drive_not_ok_scsi: -#ifdef DEBUG - move.l D0,-(SP) - move.l -12(A6),A1 - moveq #15,D1 - bsr dump - bsr wait_key - lea debug16(PC),A0 - bsr display_string_single - move.l (SP),D0 - bsr hex_long - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char - move.l (SP)+,D0 -#endif - move.w (SP)+,D1 - tst.l D0 - beq .drive_ok - lea message44(PC),A0 // time-out - tst.l D0 - bmi.s .no_read_error - lea message46(PC),A0 // read error - bra.s .no_read_error -.default_tos_routine: -#ifdef DEBUG - lea debug9(PC),A0 - bsr display_string_single -#endif - movem.l D3/A5/A6,-(SP) - move.w D4,-(SP) - move.l _dskbufp,-(SP) - move.w #1,-(SP) - clr.l -(SP) - jsr 0xE017CE // read root sector - lea 12(SP),SP - movem.l (SP)+,D3/A5/A6 - move.w (SP)+,D1 - tst.l D0 - beq .drive_ok - lea message44(PC),A0 // time-out - cmp.l #-1,D0 - beq.s .no_read_error - lea message45(PC),A0 // error - cmp.l #-11,D0 - bne.s .no_read_error - lea message46(PC),A0 // read error -#endif /* USE_ATARI_IO */ -.no_read_error: - bsr display_string - addq.l #1,D0 - dbeq D1,.loop2_drive - move.l -16(A6),D0 // IDE buffer - beq.s .no_ide_buffer_2 - move.l D0,-(SP) - move.w #0x49,-(SP) // Mfree - trap #1 - addq.l #6,SP -.no_ide_buffer_2: - move.l -12(A6),D0 // SCSI buffer - beq .next_drive - move.l D0,-(SP) - move.w #0x49,-(SP) // Mfree - trap #1 - addq.l #6,SP - bra .next_drive -.root_msdos_combined: // last bytes of root sector are 0xAA55 - btst #4,D4 - beq .not_ide_drive // SCSI - tst.w D7 - bpl .next_drive // LBA not supported (needed by read_sectors) -.not_ide_drive: - move.l _dskbufp,A0 - moveq #1,D0 - bsr swap_buffer - lea message90(PC),A0 // boot MSDOS combined - bsr display_string -#ifdef DEBUG - move.l _dskbufp,A1 - moveq #31,D1 - bsr dump - bsr wait_key -#endif - move.l _sysbase,A0 // header ROM - move.l 0x24(A0),A0 // kbshift - move.b (A0),D0 - move.l #0x444D4172,D3 // DMAr - move.w D4,D7 - asl.w #5,D7 - move.w 0xA80,D5 // bootpref NVM - btst #3,D0 // ALT - bne .next_drive - btst #2,D0 // CTRL - bne .normal_bootpref_2 - and.w #0x67,D5 // remove TOS, Linux, MagiC flags for menu_boot -.normal_bootpref_2: - moveq #2,D1 // drive C - move.l pun_ptr,D0 - beq.s .no_pun_ptr_2 - move.l D0,A0 - addq.w #1,pinfo_puns(A0) -.find_empty_pun_2: - tst.b pinfo_pun(A0,D1.w) - bmi.s .no_pun_ptr_2 - addq.l #1,D1 - cmp.l #16,D1 - bcs.s .find_empty_pun_2 - bra .next_drive -.no_pun_ptr_2: - move.l _dskbufp,A0 - bsr check_root - beq .root_combined_valid - move.w D4,D0 // drive - bsr search_dos_partition - bmi .next_drive - move.l D0,D2 - bra.s .boot_tos_partition -.root_combined_valid: - moveq #-1,D0 // swap bytes - move.w D4,D0 // drive - move.w D5,D2 // bootpref - bsr search_tos_partition - bmi .next_drive - move.l D0,D2 -.boot_tos_partition: -#ifdef DEBUG - lea debug13(PC),A0 - bsr display_string_single - move.l D2,D0 - bsr hex_long -#endif - move.l pun_ptr,-(sp) - clr.l pun_ptr - move.l hdv_rw,-(SP) - move.l D2,D1 // start of partition - moveq #-1,D0 // swap bytes - move.w D4,D0 // drive - bsr exec_sys - move.l (SP)+,D0 - move.l (SP)+,D1 - cmp.l hdv_rw,D0 - bne .end_boot_drive_dos - move.l D1,pun_ptr -#ifndef USE_ATARI_IO - cmp.w #PUN_IDE,D4 // IDE 0 - bne .next_drive - move.l hdv_rw,-(SP) - bsr install_hddriver - move.l (SP)+,D0 - cmp.l hdv_rw,D0 - bne .end_boot_drive -#endif /* USE_ATARI_IO */ - bra .next_drive -.end_boot_drive_dos: - move.w _bootdev,-(SP) - move.w #7,-(SP) // Getbpb - trap #13 - addq.l #4,SP - tst.l D0 - bne .end_boot_drive - lea message92(PC),A0 - bsr display_string - bsr wait_key - clr.w _bootdev - bra .end_boot_drive -.root_ok: - lea message48(PC),A0 - bsr display_string -#ifdef DEBUG - move.l _dskbufp,A1 - moveq #31,D1 - bsr dump - bsr wait_key -#endif - move.l _sysbase,A0 // header ROM - move.l 0x24(A0),A0 // kbshift - move.b (A0),D0 - move.l _dskbufp,A0 - move.l #0x444D4172,D3 // DMAr - move.w D4,D7 - asl.w #5,D7 - move.w 0xA80,D5 // bootpref NVM - btst #2,D0 // CTRL - bne .normal_bootpref - and.w #0x67,D5 // remove TOS, Linux, MagiC flags for menu_boot -.normal_bootpref: - movem.l A5/A6,-(SP) - move.l pun_ptr,-(sp) - clr.l pun_ptr - move.l hdv_rw,-(SP) - jsr (A0) - move.l (SP)+,D0 - move.l (SP)+,D1 - movem.l (SP)+,A5/A6 - cmp.l hdv_rw,D0 - bne .end_boot_drive - move.l D1,pun_ptr -#ifndef USE_ATARI_IO -.test_ide_cf: - cmp.w #PUN_IDE,D4 // IDE 0 - bne .next_drive - move.l _dskbufp,A0 - moveq #0,D2 // root sector - moveq #1,D1 // 1 sector - moveq #0,D0 // no swap bytes - move.w D4,D0 // drive - bsr read_sectors // reload (buffer maybe destroyed) - bmi .next_drive - moveq #2,D1 // drive C - move.l pun_ptr,D0 - beq.s .no_pun_ptr - move.l D0,A0 - addq.w #1,pinfo_puns(A0) -.find_empty_pun: - tst.b pinfo_pun(A0,D1.w) - bmi.s .no_pun_ptr - addq.l #1,D1 - cmp.l #16,D1 - bcs.s .find_empty_pun - bra .next_drive -.no_pun_ptr: - moveq #0,D0 // no swap bytes - move.w D4,D0 // drive - move.w D5,D2 // bootpref - bsr search_tos_partition - bmi .next_drive - move.l hdv_rw,-(SP) - bsr install_hddriver - move.l (SP)+,D0 - cmp.l hdv_rw,D0 - bne .end_boot_drive -#endif /* USE_ATARI_IO */ - bra.s .next_drive -.drive_ok: - move.l -16(A6),D0 // IDE buffer - beq.s .no_ide_buffer - move.l D0,-(SP) - move.w #0x49,-(SP) // Mfree - trap #1 - addq.l #6,SP -.no_ide_buffer: - move.l -12(A6),D0 // SCSI buffer - beq.s .no_scsi_buffer - move.l D0,-(SP) - move.w #0x49,-(SP) // Mfree - trap #1 - addq.l #6,SP -.no_scsi_buffer: - move.l _dskbufp,A0 - bsr check_root - beq .root_ok -#ifdef USE_ATARI_IO - btst #2,-18(A6) // old boot - bne .no_boot_found -#endif /* USE_ATARI_IO */ - move.l _dskbufp,A0 - cmp.w #0xAA55,510(A0) - beq .root_msdos_combined -.no_boot_found: - lea message47(PC),A0 // no boot found - bsr display_string -.next_drive: -#ifdef DEBUG - bsr wait_key -#endif - move.w 0x840,D4 - addq.w #1,D4 - move.w D4,0x840 - tst.b (A5,D4) - bpl .loop_drive -.end_boot_drive: -// cmp.l #0x31415926,resvalid -// bne.s .no_resvector -// tst.l resvector -// beq.s .no_resvector -// lea message52(PC),A0 -// bsr display_string_single -// move.l resvector,A0 -// bsr display_xbra -// lea crlf(PC),A0 -// bsr display_string_single -//.no_resvector: - move.l #0x5F504349,D0 // cookie _PCI - bsr get_cookie - move.l A0,D0 - beq.s .no_pci_drivers - bsr test_pci_drivers - bne.s .no_pci_drivers - jsr 16(A0) // drivers PCI in flash, init before auto folder -.no_pci_drivers: - unlk A6 - movem.l (SP)+,D0-A5 - rts - -search_tos_partition: // D0: drive, D0.H: flag swap bytes - // D1: logical drive, D2: bootpref - movem.l D1-A3,-(SP) - move.l D0,D3 // D0: drive, D0.H: flag swap bytes - moveq #0,D6 - move.w D1,D6 // logical drive - move.w D2,D5 // bootpref - moveq #0,D7 // start of 1st bootable partition - move.l pun_ptr,A3 - move.l _dskbufp,A2 - lea 0x1C6(A2),A2 // infos partitions TOS - moveq #0,D2 // ext sector for XGM - moveq #3,D4 // 4 partitions -.loop_partition_tos: - btst #0,(A2) // active partition - beq .next_partition_tos - move.l (A2),D1 - and.l #0xFFFFFF,D1 // ID - cmp.l #0x47454D,D1 // GEM - beq.s .partition_ok - cmp.l #0x42474D,D1 // BGM - beq.s .partition_ok - cmp.l #0x58474D,D1 // XGM - bne.s .next_partition_tos - move.l 4(A2),D2 // start of partition = ext sector for XGM -.next_partition_tos: - lea 12(A2),A2 - subq.l #1,D4 - bpl.s .loop_partition_tos - tst.l D2 - beq .end_partitions_tos // no ext sector for XGM - moveq #1,D1 // 1 sector - move.l D3,D0 // drive - move.l _dskbufp,A0 // read ext sector for XGM - bsr read_sectors - bmi .error_next_drive_tos - move.l A0,A2 - lea 0x1C6(A2),A2 // infos partitions - moveq #0,D2 // ext sector for XGM - moveq #1,D4 // 1 entry by ext sector - bra .loop_partition_tos -.partition_ok: - move.l A3,D0 // pun_ptr - beq .test_1st_bootable - cmp.l #16,D6 - bcc .test_1st_bootable - move.l (A2),D1 - and.l #0xFFFFFF,D1 // ID - lea pinfo_ptype(A3),A1 - move.l D1,(A1,D6.w*4) - move.l 4(A2),pinfo_pstart(A3,D6.w*4) - lea pinfo_psize(A3),A1 - move.l 8(A2),(A1,D6.w*4) - move.b D3,pinfo_pun(A3,D6.w) // drive -#ifdef DEBUG - lea debug12(PC),A0 - bsr display_string_single - move.l D1,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #0x30,D0 - bsr display_char - moveq #0x78,D0 - bsr display_char - move.l 4(A2),D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #0x30,D0 - bsr display_char - moveq #0x78,D0 - bsr display_char - move.l 8(A2),D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #0x41,D0 - add.l D6,D0 - bsr display_char -#endif - lea pinfo_flags(A3),A1 - tst.l D3 - smi.b D0 - ext.w D0 - and.l #0x8000,D0 // flag swap - bset #7,D0 // disk change - move.w D0,(A1,D6.w*2) - addq.l #1,D6 // next logical drive -.test_1st_bootable: - tst.l D7 // start of 1st bootable partition - bne .next_partition_tos - move.b (A2),D1 - tst.b D5 // bootpref - beq.s .all_types - and.b #0xF8,D1 // remove unused bits - cmp.b D5,D1 // partition type - beq.s .partition_bootable - bra .next_partition_tos -.all_types: - and.b #0xF8,D1 // remove unused bits - beq .next_partition_tos -.partition_bootable: - move.l 4(A2),D7 // start of partition - move.l D3,D0 // D0: drive, D0.H: flag swap bytes - move.l D7,D2 // start of partition - moveq #1,D1 // 1 sector - move.l _dskbufp,A0 // read boot sector - lea 512(A0),A0 - bsr read_sectors - bmi .error_next_drive_tos - move.l _dskbufp,A0 // buffer - bsr check_root - bne .not_bootable_tos - lea pinfo_flags(A3),A1 - bset #0,-1(A1,D6.w*2) - bra .next_partition_tos -.not_bootable_tos: - moveq #0,D7 // try another partition - bra .next_partition_tos -.end_partitions_tos: - move.l D7,D0 // start of partition - beq.s .error_next_drive_tos - move.l _dskbufp,A0 // buffer - lea 512(A0),A1 - moveq #127,D1 -.copy_boot_sector_tos: - move.l (A1)+,(A0)+ - subq.l #1,D1 - bpl.s .copy_boot_sector_tos - tst.l D0 - bra.s .end_search_tos_partition -.error_next_drive_tos: - moveq #-1,D0 // error -.end_search_tos_partition: - movem.l (SP)+,D1-A3 - rts - -search_dos_partition: // D0: drive, D0.H: flag swap bytes - // D1: logical drive - movem.l D1-A3,-(SP) - move.w D0,D3 // drive - moveq #0,D6 - move.w D1,D6 // logical drive - moveq #0,D7 // start of 1st bootable partition - move.l pun_ptr,A3 - move.l _dskbufp,A2 - lea 0x1BE(A2),A2 // infos partitions MSDOS - moveq #0,D2 // ext sector - moveq #3,D4 // 4 partitions -.loop_partition_msdos: - tst.l 12(A2) // nr sect - beq .next_partition_msdos - moveq #0,D1 - move.b 4(A2),D1 // partition type - cmp.l #0x5,D1 // extended partition - beq .extended_partition_msdos - cmp.l #0xF,D1 // WIN95 extended partition - beq .extended_partition_msdos - cmp.b #0x80,(A2) // active partition bootable - bne.s .next_partition_msdos - cmp.l #0x4,D1 // FAT16 up to 32M - beq.s .partition_ok_msdos - cmp.l #0x6,D1 // FAT16 over 32M - beq.s .partition_ok_msdos - cmp.l #0xE,D1 // WIN95 FAT16 - beq.s .partition_ok_msdos - bra.s .next_partition_msdos -.extended_partition_msdos: - move.l 8(A2),D2 // start sect = extended partition - ror.w #8,D2 - swap D2 - ror.w #8,D2 -.next_partition_msdos: - lea 16(A2),A2 - subq.l #1,D4 - bpl.s .loop_partition_msdos - tst.l D2 - beq .end_partitions_msdos // no extended partition - moveq #1,D1 // 1 sector - moveq #-1,D0 // swap bytes - move.w D3,D0 // drive - move.l _dskbufp,A0 // read extended partition - bsr read_sectors - bmi .error_next_drive_msdos - move.l A0,A2 - cmp.w #0x55AA,510(A2) // magic - bne .next_drive - lea 0x1BE(A2),A2 // infos partitions - moveq #0,D2 - moveq #1,D4 // 1 entry by ext sector - bra .loop_partition_msdos -.partition_ok_msdos: - move.l 8(A2),D2 // start sect - ror.w #8,D2 - swap D2 - ror.w #8,D2 - move.l A3,D0 // pun_ptr - beq .test_1st_bootable_msdos - cmp.l #16,D6 - bcc .test_1st_bootable_msdos - lea pinfo_ptype(A3),A1 - move.l D1,(A1,D6.l*4) - move.l D2,pinfo_pstart(A3,D6.l*4) - move.l 12(A2),D0 // nr sect - ror.w #8,D0 - swap D0 - ror.w #8,D0 - lea pinfo_psize(A3),A1 - move.l D0,(A1,D6.l*4) - move.b D3,pinfo_pun(A3,D6.l) // drive -#ifdef DEBUG - move.l D0,-(SP) - lea debug15(PC),A0 - bsr display_string_single - move.l D1,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #0x30,D0 - bsr display_char - moveq #0x78,D0 - bsr display_char - move.l D2,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #0x30,D0 - bsr display_char - moveq #0x78,D0 - bsr display_char - move.l (SP)+,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #0x41,D0 - add.l D6,D0 - bsr display_char -#endif - lea pinfo_flags(A3),A1 - move.w #0x8080,(A1,D6.l*2) // flag swap & disk change - addq.l #1,D6 // next logical drive -.test_1st_bootable_msdos: - tst.l D7 // start of 1st bootable partition - bne .next_partition_msdos - move.l D2,D7 // start of partition - moveq #1,D1 // 1 sector - move.l D7,D2 // start of partition - moveq #-1,D0 // swap bytes - move.w D3,D0 // drive - move.l _dskbufp,A0 // read boot sector - lea 512(A0),A0 - bsr read_sectors - bmi.s .error_next_drive_msdos - cmp.w #0x55AA,510(A0) // magic - bne .not_bootable_msdos - lea pinfo_flags(A3),A1 - bset #0,-1(A1,D6.l*2) - bra .next_partition_msdos -.not_bootable_msdos: - moveq #0,D7 // try another partition - bra .next_partition_msdos -.end_partitions_msdos: - move.l D7,D0 // start of partition - beq.s .error_next_drive_msdos - move.l _dskbufp,A0 // buffer - lea 512(A0),A1 - moveq #127,D1 -.copy_boot_sector_msdos: - move.l (A1)+,(A0)+ - subq.l #1,D1 - bpl.s .copy_boot_sector_msdos - tst.l D0 - bra.s .end_search_dos_partition -.error_next_drive_msdos: - moveq #-1,D0 -.end_search_dos_partition: - movem.l (SP)+,D1-A3 - rts - -check_root: - -#ifdef COLDFIRE - lea -16(SP),SP - movem.l D0-D2/A0,(SP) - move.l #255,D0 - moveq #0,D1 -.loop_checksum: - moveq #0,D2 - move.w (A0)+,D2 - add.l D2,D1 - subq.l #1,D0 - bpl.s .loop_checksum - and.l #0xFFFF,D1 -#ifdef DEBUG - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.w D1,D0 - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif - cmp.l #0x1234,D1 - movem.l (SP),D0-D2/A0 - lea 16(SP),SP -#else - movem.l D0-D1/A0,-(SP) - move.w #255,D0 - moveq #0,D1 -.loop_checksum: - add.w (A0)+,D1 - dbf D0,.loop_checksum - cmp.w #0x1234,D1 - movem.l (SP)+,D0-D1/A0 -#endif /* COLDFIRE */ - rts - -exec_sys: // D0 drive, D0.H: flag swap bytes, D1.L: start of partition - -#ifdef USE_ATARI_IO - movem.l D1-D7/A4,-(SP) - link A6,#-32 - move.l D0,D4 // drive & flag swap bytes - move.l D1,D6 // start of partition - move.w #3,-(SP) // TT ram if possible - move.l #-1,-(SP) // size - move.w #0x44,-(SP) // Mxalloc - trap #1 - addq.l #8,SP - move.l D0,D5 // greater block - move.l D0,-4(A6) - move.w #3,-(SP) // TT ram if possible - move.l D5,-(SP) // size - move.w #0x44,-(SP) // Mxalloc - trap #1 - addq.l #8,SP - tst.l D0 - beq .boot_error - move.l D0,A4 // buffer - move.l D0,-16(A6) - move.l _dskbufp,A0 // boot sector - moveq #0,D1 - move.b 0xC(A0),D1 // BPS * 256 - lsr.w #1,D1 // / 512 - move.l D1,-12(A6) // BPS / 512 - moveq #0,D2 - move.b 0x12(A0),D2 - asl.w #8,D2 - move.b 0x11(A0),D2 // NDIRS - move.w 0xE(A0),D3 // RES - ror.w #8,D3 - mulu D1,D3 // * (BPS / 512) - add.l D6,D3 - move.l D3,-8(A6) - move.w 0x16(A0),D6 // SPF - ror.w #8,D6 - mulu D1,D6 // * (BPS / 512) - moveq #0,D1 - move.b 0x10(A0),D1 // NFATS - mulu D1,D6 - add.l D3,D6 // + RES + start sector of partition - lsr.l #4,D2 // NDIRS / 32 - add.l D6,D2 -#ifdef DEBUG - lea debug14(PC),A0 - bsr display_string_single - move.l D6,D0 - bsr hex_long -#endif - move.l D2,-20(A6) // end directory - move.l D6,D2 // 1st sector directory -.loop_read_dir: - move.l -16(A6),A0 // buffer Mxalloc - moveq #1,D1 // 1 sector - move.l D4,D0 // drive & flag swap bytes - bsr read_sectors // read directory - bmi .mfree_boot - move.l -16(A6),A0 // buffer Mxalloc - moveq #15,D1 -.next_entry_dir: - cmp.b #0x53,8(A0) // S - bne.s .bad_ext - cmp.b #0x59,9(A0) // Y - bne.s .bad_ext - cmp.b #0x53,10(A0) // S - beq.s .ext_ok -.bad_ext: - lea 32(A0),A0 - dbf D1,.next_entry_dir - addq.l #1,D2 - cmp.l -20(A6),D2 - bcs.s .loop_read_dir - bra .mfree_boot -.bad_file: - lea message93(PC),A0 // not a TOS binary - bsr display_string - move.l -16(A6),A0 // buffer Mxalloc - moveml -28(A6),D2 // restore loop_read_dir context - moveq #1,D1 // 1 sector - move.l D4,D0 // drive & flag swap bytes - bsr read_sectors // reload directory - bmi .mfree_boot - movem.l -32(A6),D1/D2/A0 // restore loop_read_dir context - bra.s .bad_ext -.ext_ok: - movem.l D1/D2/A0,-32(A6) // save loop_read_dir context - move.l A0,-(SP) - lea message91(PC),A0 // boot found - bsr display_string // display driver name - move.l (SP)+,A0 - moveq #10,D1 - moveq #0,D2 -.loop_name_driver: - cmp.w #8,D2 - bne.s .not_point - moveq #0x2E,D0 - bsr display_char -.not_point: - move.b (A0,D2),D0 - bsr display_char - addq.w #1,D2 - dbf D1,.loop_name_driver - move.l 28(A0),D5 // size file - ror.w #8,D5 - swap D5 - ror.w #8,D5 - add.l #0x1800,D5 // stack size - cmp.l -4(A6),D5 // size block Mxalloc - bhi .mfree_boot - move.l -16(A6),A4 // buffer Mxalloc - add.l -4(A6),A4 // size block Mxalloc - lea -0x8000(A4),A4 // top of the block - move.l -16(A6),A2 // buffer Mxalloc - move.w 26(A0),D6 // 1st cluster - ror.w #8,D6 - moveq #-1,D3 -.loop_read_file: - move.l _dskbufp,A0 // boot sector - moveq #0,D1 - move.b 0xD(A0),D1 // SPC - mulu -10(A6),D1 // BPS / 512 = sec count - move.w D6,D2 // cluster - subq.w #2,D2 - mulu D1,D2 // * sec count * SPC - add.l -20(A6),D2 // + end directory = start sector - move.l A2,A0 // buffer file - move.l D4,D0 // drive & flag swap bytes - bsr read_sectors - bmi .mfree_boot - asl.l #8,D1 // * 512 - add.l D1,D1 // bytes - add.l D1,A2 // + file offset - move.w D6,D2 - ext.l D2 - lsr.l #8,D2 - add.l -8(A6),D2 // + RES + start sector of partition - cmp.l D3,D2 // start sector - beq.s .not_reload_fat - move.l D2,D3 - move.l A4,A0 // buffer FAT - moveq #1,D1 // sec count - move.l D4,D0 // drive & flag swap bytes - bsr read_sectors - bmi .mfree_boot -.not_reload_fat: - and.w #255,D6 - add.w D6,D6 - move.w (A4,D6),D6 // cluster from FAT entry - ror.w #8,D6 - bpl.s .loop_read_file - move.l -16(A6),A2 // buffer Mxalloc - move.l A2,A0 // buffer file - cmp.w #0x601A,(A0)+ // binary test - bne .bad_file - lea 0x1C(A2),A1 // + header size - add.l (A0)+,A1 // + text segment - add.l (A0)+,A1 // + data segment - add.l 4(A0),A1 // + bss segment - tst.l (A1) - beq.s .end_reloc - lea 0x1C(A2),A0 // + header size - move.l A0,D1 - moveq #0,D0 - add.l (A1)+,A0 -.loop_reloc: - add.l D1,(A0) -.loop_reloc_2: - move.b (A1)+,D0 - beq.s .end_reloc - cmp.b #1,D0 - bne.s .next_reloc - lea 254(A0),A0 - bra.s .loop_reloc_2 -.next_reloc: - add.w D0,A0 - bra.s .loop_reloc -.end_reloc: - cpusha BC // flush - move.l -4(A6),D0 // size block Mxalloc - unlk A6 - movem.l (SP)+,D1-D7/A4 - jmp 0x20(A2) // start file after the 1st BRA -.mfree_boot: - move.l -16(A6),-(SP) // buffer Mxalloc - move.w #0x49,-(SP) // Mfree - trap #1 - addq.l #6,SP -.boot_error: - unlk A6 - movem.l (SP)+,D1-D7/A4 -#endif /* USE_ATARI_IO */ - rts - -#ifdef COLDFIRE - - // SCSIDRV - -install_scsidrv: - -#ifdef COLDFIRE - lea -24(SP),SP - movem.l D0-D2/A0-A2,(SP) -#else - movem.l D0-D2/A0-A2,-(SP) -#endif - move.w #3,-(SP) // TT ram if possible - move.l #74+18,-(SP) // size - move.w #0x44,-(SP) // Mxalloc - trap #1 - addq.l #8,SP - tst.l D0 - beq .error_install - move.l D0,A2 - move.l D0,A1 - move.w #0x101,(A1)+ // version - lea In(PC),A0 - move.l A0,(A1)+ - lea Out(PC),A0 - move.l A0,(A1)+ - lea InquireSCSI(PC),A0 - move.l A0,(A1)+ - lea InquireBus(PC),A0 - move.l A0,(A1)+ - lea CheckDev(PC),A0 - move.l A0,(A1)+ - lea RescanBus(PC),A0 - move.l A0,(A1)+ - lea Open(PC),A0 - move.l A0,(A1)+ - lea Close(PC),A0 - move.l A0,(A1)+ - lea Error(PC),A0 - move.l A0,(A1)+ - lea Install(PC),A0 - move.l A0,(A1)+ - lea Deinstall(PC),A0 - move.l A0,(A1)+ - lea GetCmd(PC),A0 - move.l A0,(A1)+ - lea SendData(PC),A0 - move.l A0,(A1)+ - lea GetData(PC),A0 - move.l A0,(A1)+ - lea SendStatus(PC),A0 - move.l A0,(A1)+ - lea SendMsg(PC),A0 - move.l A0,(A1)+ - lea GetMsg(PC),A0 - move.l A0,(A1)+ - addq.l #4,A1 - move.l A1,-4(A1) // ReqData - move.l cookie,D0 - beq.s .error_install - move.l D0,A0 -.find_cookiejar: - tst.l (A0) - beq.s .cookie_slotfree - addq.w #8,A0 - bra.s .find_cookiejar -.cookie_slotfree: - move.l 4(A0),12(A0) // copy size - move.l #0x53435349,(A0)+ // SCSI - move.l A2,(A0)+ - clr.l (A0) -.error_install: -#ifdef COLDFIRE - movem.l (SP),D0-D2/A0-A2 - lea 24(SP),SP -#else - movem.l (SP)+,D0-D2/A0-A2 -#endif - rts - -In: - -#ifdef COLDFIRE - lea -40(SP),SP - movem.l D1-D5/A0-A4,(SP) -#ifdef DEBUG - lea debug130(PC),A0 - bsr debug_display_string - move.l 4+40(SP),A2 // Parms - moveq #0,D2 - move.w 8(A2),D2 // CmdLen - move.l 4(A2),A2 // Cmd -.in0: - move.b (A2)+,D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - subq.l #1,D2 - bgt.s .in0 -#endif -#else - movem.l D1-D5/A0-A4,-(SP) -#endif - move.w SR,D0 // supervisor only - moveq #TIMEOUTERROR,D5 // error code - move.w #3,-(SP) // TT ram if possible - move.l #1024,-(SP) // size - move.w #0x44,-(SP) // Mxalloc - trap #1 - addq.l #8,SP - tst.l D0 - beq .in1 // error - move.l D0,A0 // buffer IDE - move.l 4+40(SP),A2 // Parms - move.l (A2),D0 // Handle - ble .in7 // error - move.l 4(A2),A3 // Cmd - moveq #0,D0 - move.w 8(A2),D0 // CmdLen - cmp.l #6,D0 - bcs .in7 // error - moveq #0,D4 - move.b 1(A3),D4 - lsr.l #5,D4 // logical unit - bne .in7 // error -// cmp.l #2,D4 -// bcc .in7 // error - or.l #0x10,D4 // drive - move.l 10(A2),A4 // Buffer - move.l 14(A2),D1 // TransferLen - move.l 18(A2),A1 // SenseBuffer (18 bytes) - move.l 22(A2),D2 // Timeout - move.w 26(A2),D3 // Flags - move.l A0,-(SP) - link A6,#-8 - moveq #0,D0 - move.b (A3),D0 // command : test unit ready - bne.s .in2 - lea -8(A6),A1 // cmd buffer - move.b #0xE5,(A1) // check power mode - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - clr.b 6(A1) // features - moveq #0,D0 // bytes - bsr ide_cmd - bmi .in6 -// moveq #BSYERROR,D5 -// tst.b ATA_SECTOR_COUNT -// beq .in6 // not ready - bra .in9 // OK -.in2: - cmp.l #0x03,D0 // request sense - bne.s .in12 -#if 1 - move.b #0x72,(A1) // response code - clr.b 1(A1) // segment number - move.b #2,2(A1) // sense key: no sense - clr.l 3(A1) // information - move.b #10,7(A1) // additional sense length (n-7) - move.w #0x0206,8(A1) // sense specific sense descriptor - clr.w 10(A1) - move.b #0x80,12(A1) // sense-key specific - clr.l 14(A1) -#else - move.b #0xF0,(A1) // error code - clr.b 1(A1) // segment number - move.b #2,2(A1) // sense key 2:not ready 6: unit attention - clr.l 3(A1) // information - move.b #10,7(A1) // additional sense length (n-7) - clr.l 8(A1) // command-specific information - move.w 0x2800,12(A1) // additional sense code - // 0x2800:medium changed, 0x2900:reset bus occured - // 0x0401: in progress, 0x3A00: no media, 0x3A01: no media, try closed - clr.b 14(A1) // field replaceable unit code - clr.b 15(A1) // sense-key specific - clr.w 16(A1) -#endif - bra .in9 // OK -.in12: - cmp.l #0x08,D0 // read - bne.s .in4 - moveq #0,D2 - move.b 1(A3),D2 - and.l #0x1F,D2 - swap D2 - move.w 2(A3),D2 // LBA 21 bits - bra.s .in8 -.in4: - cmp.l #0x28,D0 // read - bne .in5 - move.l 2(A3),D2 // LBA 32 bits -.in8: - add.l #0x1FF,D1 // TransferLen - lsr.l #8,D1 - lsr.l #1,D1 // / 512 - beq .in6 - cmp.l #0x100,D1 - bcc .in6 // error - lea -8(A6),A1 // cmd buffer - move.l A4,A0 // buffer IDE - move.b #0x20,(A1) // read sector(s) - moveq #7,D0 - and.w D4,D0 // physical drive - asl.w #4,D0 - or.b #0xE0,D0 // LBA - move.b D0,1(A1) // drive (C/D/H) - move.l D2,D0 // LBA - move.b D0,4(A1) // sec num, LBA low - lsr.l #8,D0 - move.w D0,2(A1) // cyl high & low, LBA high & mid - move.b D1,5(A1) // sec count 0 <=> 256 - clr.b 6(A1) // features - moveq #0,D0 - move.w D1,D0 // count - add.l D0,D0 - asl.l #8,D0 // * 512 = bytes - bsr ide_cmd - bmi .in6 // time-out - beq .in9 // OK -.in3: - moveq #PARITIYERROR,D5 - bra .in6 -.in5: - cmp.l #0x12,D0 // inquiry - bne.s .in11 - cmp.l #36,D1 // TransferLen - bcs .in6 - lea -8(A6),A1 // cmd buffer - move.b #0xEC,(A1) // identify device - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - clr.b 6(A1) // features - move.l #512,D0 // bytes - bsr ide_cmd - bmi .in6 // time-out - bne .in3 // error - clr.w (A4) // peripheral: direct access device -// move.w (A0),(A4) // device type - move.b #3,2(A4) // ANSI - clr.b 3(A4) - move.b #32,4(A4) // length - 4 - clr.b 5(A4) - clr.w 6(A4) - move.l 46(A0),32(A4) // revision - moveq #15,D0 - lea 54(A0),A0 - lea 8(A4),A1 - moveq #23,D0 -.in10: - move.b (A0)+,(A1)+ // model - subq.l #1,D0 - bpl.s .in10 - bra .in9 // OK -.in11: - cmp.l #0x1A,D0 // mode sense - bne .in13 - cmp.l #20,D1 // TransferLen - bcs .in6 - moveq #0x3F,D0 - and.b 2(A3),D0 - cmp.l #0x08,D0 // caching mode page - bne .in6 - lea -8(A6),A1 // cmd buffer - move.b #0xEC,(A1) // identify device - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - clr.b 6(A1) // features - move.l #512,D0 // bytes - bsr ide_cmd - bmi .in6 // time-out - bne .in3 // error - move.b #8,(A4) // page code - move.b #12,1(A4) // page length - btst #5,171(A0) // write cache enable - sne.b D0 - and.l #4,D0 // WCE - move.b D0,2(A4) - clr.b 3(A4) - clr.l 6(A4) - clr.w 10(A4) - btst #6,171(A0) // look ahead enable - seq.b D0 - and.l #0x20,D0 // DRA - move.b D0,12(A4) - clr.b 13(A4) - clr.w 14(A4) - clr.l 16(A4) - bra .in9 -.in13: - cmp.l #0x25,D0 // read capacity - bne.s .in6 - cmp.l #4,D1 // TransferLen - bcs.s .in6 - lea -8(A6),A1 // cmd buffer - move.b #0xEC,(A1) // identify device - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - clr.b 6(A1) // features - move.l #512,D0 // bytes - bsr ide_cmd - bmi .in6 // time-out - bne .in3 // error - move.l 120(A0),D0 // total sectors - swap D0 - move.l D0,(A4) // logical block address - move.l #512,4(A4) // block length -.in9: - moveq #NOSCSIERROR,D5 -.in6: - unlk A6 - move.l (SP)+,A0 -.in7: - move.l A0,-(SP) - move.w #0x49,-(SP) // Mfree - trap #1 - addq.l #6,SP -.in1: - move.l D5,D0 // error code -#ifdef COLDFIRE -#ifdef DEBUG - lea debug145(PC),A0 - bsr debug_display_string - move.l D5,D0 - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l D5,D0 -#endif - movem.l (SP),D1-D5/A0-A4 - lea 40(SP),SP -#else - movem.l (SP)+,D1-D5/A0-A4 -#endif - rts - -Out: - -#ifdef COLDFIRE - lea -40(SP),SP - movem.l D1-D5/A0-A4,(SP) -#ifdef DEBUG - lea debug131(PC),A0 - bsr debug_display_string - move.l 4+40(SP),A2 // Parms - moveq #0,D2 - move.w 8(A2),D2 // CmdLen - move.l 4(A2),A2 // Cmd -.out0: - move.b (A2)+,D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - subq.l #1,D2 - bgt.s .out0 -#endif -#else - movem.l D1-D5/A0-A4,-(SP) -#endif - move.w SR,D0 // supervisor only - moveq #TIMEOUTERROR,D5 // error code - move.l 4+40(SP),A2 // Parms - move.l (A2),D0 // Handle - ble .out1 // error - move.l 4(A2),A3 // Cmd - moveq #0,D0 - move.w 8(A2),D0 // CmdLen - cmp.l #6,D0 - bcs .out1 // error - moveq #0,D4 - move.b 1(A3),D4 - lsr.l #5,D4 // logical unit - bne .in7 // error -// cmp.l #2,D4 -// bcc .in7 // error - or.l #0x10,D4 // drive - move.l 10(A2),A4 // Buffer - move.l 14(A2),D1 // TransferLen - move.l 18(A2),A1 // SenseBuffer (18 bytes) - move.l 22(A2),D2 // Timeout - move.w 26(A2),D3 // Flags - link A6,#-8 - moveq #0,D0 - move.b (A3),D0 // command - cmp.l #0xA,D0 // write - bne.s .out4 - moveq #0,D2 - move.b 1(A3),D2 - and.l #0x1F,D2 - swap D2 - move.w 2(A3),D2 // LBA 21 bits - bra.s .out2 -.out4: - cmp.l #0x2A,D0 // read - bne .out6 - move.l 2(A3),D2 // LBA 32 bits -.out2: - add.l #0x1FF,D1 // TransferLen - lsr.l #8,D1 - lsr.l #1,D1 // / 512 - beq .out5 - cmp.l #0x100,D1 - bcc .out5 // error - lea -8(A6),A1 // cmd buffer - move.l A4,A0 // buffer IDE - move.b #0x30,(A1) // write sector(s) - moveq #7,D0 - and.w D4,D0 // physical drive - asl.w #4,D0 - or.b #0xE0,D0 // LBA - move.b D0,1(A1) // drive (C/D/H) - move.l D2,D0 // LBA - move.b D0,4(A1) // sec num, LBA low - lsr.l #8,D0 - move.w D0,2(A1) // cyl high & low, LBA high & mid - move.b D1,5(A1) // sec count 0 <=> 256 - clr.b 6(A1) // features - moveq #0,D0 - move.w D1,D0 // count - add.l D0,D0 - asl.l #8,D0 // * 512 = bytes - bsr ide_cmd - bmi .out5 // time-out - beq .out3 // OK - moveq #PARITIYERROR,D5 - bra .out5 -.out6: - cmp.l #0x15,D0 // mode select - bne .out5 - cmp.l #20,D1 // TransferLen - bcs .out5 - moveq #0x3F,D0 - and.b 2(A3),D0 - cmp.l #8,D0 // caching mode page - bne.s .out5 - moveq #2,D2 // enable write cache - btst #2,2(A4) // WCE - bne.s .out7 - move.w #0x82,D2 // disable write cache -.out7: - moveq #0x55,D3 // disable read look ahead - btst #5,12(A1) // DRA - bne.s .out8 - move.w #0xAA,D3 // enable read look ahead -.out8: - lea -8(A6),A1 // cmd buffer - move.b #0xEF,(A1) // set features - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - move.b D2,6(A1) // features - moveq #0,D0 // bytes - bsr ide_cmd - bmi .out5 // time-out - lea -8(A6),A1 // cmd buffer - move.b #0xEF,(A1) // set features - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - move.b D3,6(A1) // features - moveq #0,D0 // bytes - bsr ide_cmd - bmi .out5 // time-out -.out3: - moveq #NOSCSIERROR,D5 -.out5: - unlk A6 -.out1: - move.l D5,D0 // error code -#ifdef COLDFIRE -#ifdef DEBUG - lea debug145(PC),A0 - bsr debug_display_string - move.l D5,D0 - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l D5,D0 -#endif - movem.l (SP),D1-D5/A0-A4 - lea 40(SP),SP -#else - movem.l (SP)+,D1-D5/A0-A4 -#endif - rts - -InquireSCSI: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug144(PC),A0 - bsr debug_display_string -#endif -#endif - move.l A0,-(SP) - tst.w 4+4(SP) // what - bne.s .is1 // cInqNext - move.l 6+4(SP),A0 // Info - clr.l (A0)+ // Private.BusIds - clr.l (A0)+ // Private.resrvd - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - move.l #0x49444500,(A0)+ // BusName, IDE - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - move.w #3,(A0)+ // BusNo, IDE not compatible - move.w Features(PC),(A0)+ - move.l #XFRB_SIZE,(A0)+ // MaxLen - moveq #0,D0 - move.l (SP)+,A0 - rts -.is1: - moveq #-1,D0 - move.l (SP)+,A0 - rts - -InquireBus: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug143(PC),A0 - bsr debug_display_string -#endif -#endif - move.l A0,-(SP) - tst.w 4+4(SP) // what - bne.s .ib1 // cInqNext - moveq #0,D0 - move.w 6+4(SP),D0 // BusNo - cmp.l #3,D0 // IDE not compatible - bne.s .ib1 - move.l 8+4(SP),A0 // Dev - clr.l (A0)+ // Private - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ // SCSIId - clr.l (A0)+ - moveq #0,D0 - move.l (SP)+,A0 - rts -.ib1: - moveq #-1,D0 - move.l (SP)+,A0 - rts - -CheckDev: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug142(PC),A0 - bsr debug_display_string -#endif -#endif - move.l A0,-(SP) - moveq #0,D0 - move.w 4+4(SP),D0 // BusNo - cmp.l #3,D0 // IDE not compatible - bne.s .cd1 // error - move.l 6+4(SP),A0 // SCSIId - tst.b 7(A0) // ID - bne.s .cd1 // error - move.l 10+4(SP),A0 // Name - move.l #0x49444500,(A0)+ // BusName, IDE - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - clr.l (A0)+ - move.l 14+4(SP),A0 // Features - move.w Features(PC),(A0)+ - moveq #0,D0 - move.l (SP)+,A0 - rts -.cd1: - moveq #-15,D0 // unknown device - move.l (SP)+,A0 - rts - -RescanBus: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug141(PC),A0 - bsr debug_display_string -#endif -#endif - moveq #0,D0 - move.w 4(SP),D0 // BusNo - cmp.l #3,D0 // IDE not compatible - bne.s .rb1 // error - moveq #0,D0 - rts -.rb1: - moveq #-15,D0 // unknown device - rts - -Open: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug138(PC),A0 - bsr debug_display_string -#endif + beq .no_read_error + btst #0,D0 // state, ERR + beq .no_read_error + moveq #0,D0 + move.b ATA_ERROR_REGISTER,D0 // error register + bsr hex_byte + moveq #0x20,D0 + bsr display_char + moveq #0,D0 #endif - move.l A0,-(SP) - moveq #0,D0 - move.w 4+4(SP),D0 // BusNo - cmp.l #3,D0 // IDE not compatible - bne.s .op1 // error - move.l 6+4(SP),A0 // SCSIId - tst.b 7(A0) // ID - bne.s .op1 // error - move.l 10+4(SP),A0 // MaxLen - move.l #XFRB_SIZE,(A0) - lea Features(PC),A0 - move.l A0,D0 // Handle - move.l (SP)+,A0 - rts -.op2: - moveq #-35,D0 // no more handles - move.l (SP)+,A0 - rts -.op1: - moveq #-15,D0 // unknown device - move.l (SP)+,A0 - rts - -Close: - -#ifdef COLDFIRE + bra .no_read_error +#ifdef USE_ATARI_IO +.scsi_drive_2: + tst.l -12(A6) // SCSI buffer + beq .default_tos_routine #ifdef DEBUG - lea debug139(PC),A0 - bsr debug_display_string -#endif + lea debug11(PC),A0 + bsr display_string_single + move.l -12(A6),A0 + moveq #127,D0 +.loop_raz_buffer: + clr.l (A0)+ + dbf D0,.loop_raz_buffer #endif - moveq #NOSCSIERROR,D0 - rts - -Error: - -#ifdef COLDFIRE + moveq #1,D3 +.loop_speed_scsi: + move.w D4,D0 // drive + move.l -12(A6),A0 // DMA buffer + lea -6(A6),A1 // cmd buffer + move.b #0x08,(A1) // read + move.w (SP),D1 // logical unit + asl.w #5,D1 + move.b D1,1(A1) // logical unit + clr.w 2(A1) // logical block address + move.b #SPEED_BUFFER_SIZE/512,4(A1) // num blocks + clr.b 5(A1) // control + move.l #SPEED_BUFFER_SIZE,D1 // DMA bytes length + moveq #6,D2 // cmd bytes length + jsr scsi_cmd + bne .drive_not_ok_scsi // error + dbf D3,.loop_speed_scsi + move.l D1,D0 + bsr display_mb_by_sec_disk + moveq #0,D0 // no error + move.l -12(A6),A0 // SCSI buffer + move.l _dskbufp,A1 + moveq #127,D1 // 512 bytes +.copy_buffer_scsi: + move.l (A0)+,(A1)+ + dbf D1,.copy_buffer_scsi +.drive_not_ok_scsi: #ifdef DEBUG - lea debug140(PC),A0 - bsr debug_display_string -#endif -#endif - move.l 4(SP),D0 // handle - move.w 8(SP),D0 // rwflag - move.w 10(SP),D0 // ErrNo - moveq #NOSCSIERROR,D0 - rts - -Features: - dc.w cAllCmds - -Install: -Deinstall: -GetCmd: -SendData: -GetData: -SendStatus: -SendMsg: -GetMsg: - - moveq #-1,D0 // error - rts - - // XHDI - - dc.l 0x27011992 - -xhdi: - - link A6,#0 -#ifdef COLDFIRE - lea -52(SP),SP - movem.l D1-A5,(SP) -#else - movem.l D1-A5,-(SP) + move.l D0,-(SP) + move.l -12(A6),A1 + moveq #15,D1 + bsr dump +#ifndef COLDFIRE + bsr wait_key #endif - moveq #0,D1 - move.w 8(A6),D1 - moveq #-32,D0 // invalid function - cmp.l #18,d1 - bcc.s .bad_xhdi - move.w SR,D0 // supervisor only - moveq #-1,d0 // error - move.w tab_xhdi(PC,D1.W*2),D1 - jsr tab_xhdi(PC,D1.W) -.bad_xhdi: -#ifdef COLDFIRE - movem.l (SP)+,D1-A5 - lea 52(SP),SP -#else - movem.l (SP)+,D1-A5 + lea debug16(PC),A0 + bsr display_string_single + move.l (SP),D0 + bsr hex_long + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char + move.l (SP)+,D0 #endif - unlk A6 - rts -tab_xhdi: - dc.w XHGetVersion-tab_xhdi // 0 - dc.w XHInqTarget-tab_xhdi // 1 - dc.w XHReserve-tab_xhdi // 2 - dc.w XHLock-tab_xhdi // 3 - dc.w XHStop-tab_xhdi // 4 - dc.w XHEject-tab_xhdi // 5 - dc.w XHDrvMap-tab_xhdi // 6 - dc.w XHInqDev-tab_xhdi // 7 - dc.w XHInqDriver-tab_xhdi // 8 - dc.w XHNewCookie-tab_xhdi // 9 - dc.w XHReadWrite-tab_xhdi // 10 - dc.w XHInqTarget2-tab_xhdi // 11 - dc.w XHInqDev2-tab_xhdi // 12 - dc.w XHDriverSpecial-tab_xhdi // 13 - dc.w XHGetCapacity-tab_xhdi // 14 - dc.w XHMediumChanged-tab_xhdi // 15 - dc.w XHMiNTInfo-tab_xhdi // 16 - dc.w XHDOSLimits-tab_xhdi // 17 - -XHGetVersion: - - move.l #0x120,D0 // protocol version - rts - -XHInqTarget: - - moveq #32,D3 // stringlen - bra.s .xi1 - -XHInqTarget2: - -#ifdef COLDFIRE + move.w (SP)+,D1 + tst.l D0 + beq .drive_ok + lea message44(PC),A0 // time-out + tst.l D0 + bmi.s .no_read_error + lea message46(PC),A0 // read error + bra.s .no_read_error +.default_tos_routine: #ifdef DEBUG - lea debug133(PC),A0 - bsr debug_display_string + lea debug9(PC),A0 + bsr display_string_single #endif + movem.l D3/A5/A6,-(SP) + move.w D4,-(SP) + move.l _dskbufp,-(SP) + move.w #1,-(SP) + clr.l -(SP) + jsr 0xE017CE // read root sector + lea 12(SP),SP + movem.l (SP)+,D3/A5/A6 + move.w (SP)+,D1 + tst.l D0 + beq .drive_ok + lea message44(PC),A0 // time-out + cmp.l #-1,D0 + beq.s .no_read_error + lea message45(PC),A0 // error + cmp.l #-11,D0 + bne.s .no_read_error + lea message46(PC),A0 // read error +#endif /* USE_ATARI_IO */ +.no_read_error: + bsr display_string + addq.l #1,D0 + dbeq D1,.loop2_drive + move.l -16(A6),D0 // IDE buffer + beq.s .no_ide_buffer_2 + move.l D0,-(SP) + move.w #0x49,-(SP) // Mfree + trap #1 + addq.l #6,SP +.no_ide_buffer_2: + move.l -12(A6),D0 // SCSI buffer + beq .next_drive + move.l D0,-(SP) + move.w #0x49,-(SP) // Mfree + trap #1 + addq.l #6,SP + bra .next_drive +.drive_ok: + move.l -16(A6),D0 // IDE buffer + beq.s .no_ide_buffer + move.l D0,-(SP) + move.w #0x49,-(SP) // Mfree + trap #1 + addq.l #6,SP +.no_ide_buffer: + move.l -12(A6),D0 // SCSI buffer + beq.s .no_scsi_buffer + move.l D0,-(SP) + move.w #0x49,-(SP) // Mfree + trap #1 + addq.l #6,SP +.no_scsi_buffer: + move.l _dskbufp,A0 + bsr check_root + bne.s .root_bad + bsr atari_root // root OK + bne.s .end_boot_drive + bra.s .next_drive +.root_bad: +#if !defined(USE_ATARI_IO) || defined(COLDFIRE) + bsr atari_root2 // install hard disk driver + bne.s .end_boot_drive #endif - move.l 26(A6),D3 // stringlen -.xi1: - tst.w 12(A6) // minor - bne.s .xi2 - moveq #0,D0 - move.w 10(A6),D0 // major - cmp.l #PUN_IDE,D0 - bne.s .xi3 -.xi2: - moveq #-15,D0 // unknown device - rts -.xi3: - move.w D0,D4 - lea 14(A6),A0 // blocksize - move.l #512,(A0) - lea 18(A6),A0 // device_flags - clr.l (A0) - move.l 22(A6),D0 // product_name, 32 characters - beq.s .xi3 - move.l D0,A2 - clr.b (A2) - move.l _dskbufp,A0 // IDE buffer - clr.w (A0) - lea -8(A6),A1 // cmd buffer - move.b #0xEC,(A1) // identify device - moveq #7,D0 - and.w D4,D0 // drive - asl.w #4,D0 - or.b #0xA0,D0 - move.b D0,1(A1) // drive (C/D/H) - clr.w 2(A1) // cyl high & low - clr.w 4(A1) // sec num & count - clr.b 6(A1) // features - move.l #512,D0 // bytes - bsr ide_cmd - bne.s .xi4 - move.l _dskbufp,A0 - lea 54(A0),A0 - lea 24(A0),A1 - moveq #23,D1 // jump end spaces -.xi5: - cmp.b #0x20,-(A1) - bne.s .xi6 - subq.l #1,D1 - bpl.s .xi5 -.xi6: - addq.w #1,A1 - clr.b (A1) - moveq #23,D1 // model -.xi7: - move.b (A0)+,D0 - beq.s .xi8 - move.b D0,(A2)+ - subq.l #1,D3 - ble.s .xi8 - subq.l #1,D1 - bpl.s .xi7 -.xi8: - clr.b (A2) -.xi4: - moveq #0,D0 - rts - -XHReserve: -XHLock: -XHStop: -XHEject: - - moveq #0,D0 - rts - -XHDrvMap: - - move.l _drvbits,D0 - rts - - -XHInqDev: - -#ifdef COLDFIRE +#ifdef USE_ATARI_IO + btst #2,-18(A6) // old boot + bne .no_boot_found +#endif /* USE_ATARI_IO */ + move.l _dskbufp,A0 + cmp.w #0xAA55,510(A0) + bne.s .no_boot_found + // last bytes of root sector are 0xAA55 + bsr msdos_root + bne.s .end_boot_drive + bra.s .next_drive +.no_boot_found: +#if 0 // #ifdef DEBUG + move.l D1,-(SP) + move.l _dskbufp,A0 + moveq #31,D1 + bsr dump + move.l (SP)+,D1 + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char +#endif + lea message47(PC),A0 // no boot found + bsr display_string +.next_drive: #ifdef DEBUG - lea debug134(PC),A0 - bsr debug_display_string +#ifndef COLDFIRE + bsr wait_key #endif #endif - move.l pun_ptr,A0 - moveq #0,D0 - move.w 10(A6),D0 // bios_device - cmp.l #2,D0 // C - bcs.s .xd2 - cmp.l #16,D0 - bcc.s .xd2 - moveq #0,D1 - move.b pinfo_pun(A0,D0.w),D1 - bpl.s .xd1 -.xd2: - moveq #-46,D0 // invalid drive number - rts -.xd1: - move.l 12(A6),A1 // major - move.w D1,(A1) - move.l 16(A6),A1 // minor - clr.w (A1) - move.l pinfo_pstart(A0,D0.w*4),D1 - move.l 20(A6),A1 // start_sector - move.l D1,(A1) - lea pinfo_bpb(A0),A0 - asl.l #5,D0 // * 32 - add.l A0,D0 - move.l 20(A6),A1 // bpb - move.l D0,(A1) - moveq #0,D0 + move.w 0x840,D4 + addq.w #1,D4 + move.w D4,0x840 + tst.b (A5,D4) + bpl .loop_drive +.end_boot_drive: +#if !defined(USE_ATARI_IO) || defined(COLDFIRE) + move.l hdv_rw,D0 + cmp.l -22(A6),D0 + bne.s .external_driver + jsr install_hddriver // if no external driver +.external_driver: +#endif /* USE_ATARI_IO */ +// cmp.l #0x31415926,resvalid +// bne.s .no_resvector +// tst.l resvector +// beq.s .no_resvector +// lea message52(PC),A0 +// bsr display_string_single +// move.l resvector,A0 +// bsr display_xbra +// lea crlf(PC),A0 +// bsr display_string_single +//.no_resvector: + move.l #0x5F504349,D0 // cookie _PCI + bsr get_cookie + move.l A0,D0 + beq.s .no_pci_drivers + bsr test_pci_drivers + bne.s .no_pci_drivers + jsr 16(A0) // drivers PCI in flash, init before auto folder +.no_pci_drivers: + unlk A6 + movem.l (SP)+,D0-A5 rts - -XHInqDriver: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug135(PC),A0 - bsr debug_display_string -#endif + +search_tos_partition: // D0: drive, D0.H: flag swap bytes + // D1: logical drive, D2: bootpref + movem.l D1-A5,-(SP) + move.l D0,D3 // D0: drive, D0.H: flag swap bytes + moveq #0,D6 + move.w D1,D6 // logical drive + move.w D2,D5 // bootpref + moveq #0,D7 // start of 1st bootable partition + move.l pun_ptr,A3 + move.l _dskbufp,A2 + lea 0x1C6(A2),A2 // infos partitions TOS + lea 0,A4 // partition count + move.l D6,A5 // logical drive start + moveq #0,D2 // ext sector for XGM + moveq #3,D4 // 4 partitions +.loop_partition_tos: + move.l (A2),D1 + and.l #0xFFFFFF,D1 // ID + beq.s .next_partition_tos +#if 1 + cmp.l #0x4C4E58,D1 // LNX + beq.s .partition_ok_tos + cmp.l #0x524157,D1 // RAW + beq.s .partition_ok_tos + cmp.l #0x463332,D1 // F32 + beq.s .partition_ok_tos #endif - move.l pun_ptr,A0 - moveq #0,D0 - move.w 10(A6),D0 // bios_device - cmp.l #2,D0 // C - bcs.s .xd2 - cmp.l #16,D0 - bcc.s .xd2 - moveq #0,D1 - move.b pinfo_pun(A0,D0.w),D1 - bpl.s .xd1 -.xdr2: - moveq #-46,D0 // invalid drive number - rts -.xdr1: - move.l 12(A6),D0 // name, 17 characters - beq.s .xdr3 - move.l D0,A1 - lea message0b(PC),A0 - moveq #17,D1 -.xdr6: - move.b (A0)+,D0 - beq.s .xdr7 - move.b D0,(A1)+ - subq.l #1,D1 - bpl.s .xdr6 -.xdr7: - clr.b (A1) -.xdr3: - move.l 16(A6),D0 // version, 7 characters - beq.s .xdr4 - move.l D0,A1 - move.b #0x34,(A1)+ // ??? TOS 4.04 - move.b #0x2E,(A1)+ - move.b #0x30,(A1)+ - move.b #0x34,(A1)+ - clr.b (A1) -.xdr4: - move.l 20(A6),D0 // company, 17 characters - beq.s .xdr5 - move.l D0,A1 - clr.b (A1) -.xdr5: - move.l 24(A6),A1 // ahdi_version - move.w pinfo_vernum(A0),(A1) - move.l 28(A6),A1 // maxIPL - moveq #5,D0 - move.w D0,(A1) - moveq #0,D0 - rts - -XHNewCookie: - - moveq #-32,D0 // invalid function number - rts - -XHReadWrite: - - tst.w 12(A6) // minor - bne.s .xr4 - moveq #0,D4 - move.w 10(A6),D4 // major - cmp.l #PUN_IDE,D4 - bne.s .xr1 -.xr4: - moveq #-15,D0 // unknown device - rts -.xr1: -#ifdef COLDFIRE + cmp.l #0x47454D,D1 // GEM + beq.s .partition_ok_tos + cmp.l #0x42474D,D1 // BGM + beq.s .partition_ok_tos + cmp.l #0x58474D,D1 // XGM + bne.s .next_partition_tos + move.l 4(A2),D2 // start of partition = ext sector for XGM + subq.l #1,D4 + bpl.s .loop_partition_tos + bra.s .test_extended_partition_tos +.next_partition_tos: + moveq #0,D2 + lea 12(A2),A2 + subq.l #1,D4 + bpl.s .loop_partition_tos +.test_extended_partition_tos: + tst.l D2 + beq .end_partitions_tos // no ext sector for XGM + moveq #1,D1 // 1 sector + move.l D3,D0 // drive + move.l _dskbufp,A0 // read ext sector for XGM + jsr read_sectors + bmi .error_next_drive_tos + move.l A0,A2 + lea 0x1C6(A2),A2 // infos partitions + moveq #0,D2 // ext sector for XGM + moveq #1,D4 // 1 entry by ext sector + bra .loop_partition_tos +.partition_ok_tos: // know this partition type + move.l (A2),D1 + and.l #0xFFFFFF,D1 // ID + move.l 4(A2),D2 // start sect + move.l A3,D0 // pun_ptr + beq .test_1st_bootable_tos + cmp.l #16,D6 + bcc .test_1st_bootable_tos + addq.l #1,A4 // partition count + lea pinfo_ptype(A3),A1 + move.l D1,(A1,D6.l*4) + move.l D2,pinfo_pstart(A3,D6.l*4) + lea pinfo_psize(A3),A1 + move.l 8(A2),D0 + cmp.l #0x47454D,D1 // GEM + beq.s .check_partition_size_tos + cmp.l #0x42474D,D1 // BGM + bne.s .no_limit_size_tos +.check_partition_size_tos: + cmp.l #0x400000,D0 + bcs.s .no_limit_size_tos + move.l #0x400000,D0 // 2GB limit +.no_limit_size_tos: + move.l D0,(A1,D6.l*4) + move.b D3,pinfo_pun(A3,D6.l) // drive + move.w pinfo_puns(A3),D0 + addq.l #1,D0 + move.w D0,pinfo_puns(A3) #ifdef DEBUG - lea debug132(PC),A0 - bsr debug_display_string - move.w 14(A6),D0 // rwflag - bsr debug_hex_word + lea debug12(PC),A0 + bsr display_string_single + move.l D1,D0 + bsr hex_long moveq #0x20,D0 - bsr debug_display_char + bsr display_char moveq #0x30,D0 - bsr debug_display_char + bsr display_char moveq #0x78,D0 - bsr debug_display_char - move.l 24(A6),D0 // buffer - bsr debug_hex_long + bsr display_char + move.l 4(A2),D0 + bsr hex_long moveq #0x20,D0 - bsr debug_display_char + bsr display_char moveq #0x30,D0 - bsr debug_display_char + bsr display_char moveq #0x78,D0 - bsr debug_display_char - move.w 20(A6),D0 // num sectors - bsr debug_hex_word + bsr display_char + move.l 8(A2),D0 + bsr hex_long moveq #0x20,D0 - bsr debug_display_char - moveq #0x30,D0 - bsr debug_display_char - moveq #0x78,D0 - bsr debug_display_char - move.l 16(A6),D0 // logical sector - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif -#endif - move.l 24(A6),A0 // buffer - moveq #0,D3 - move.w 20(A6),D3 // count - beq .xr2 // no sectors - move.l 16(A6),D2 // start sector - btst #0,15(A6) // rwflag - beq.s .xr7 // read - tst.l D2 // sector - beq.s .xr2 // root sector -.xr5: - move.l D3,D1 // count - cmp.l #0x100,D1 - bcs.s .xr6 - move.l #0xFF,D1 // count -.xr6: - move.l D4,D0 - bsr write_sectors - bmi.s .xr3 - move.l D1,D0 - add.l D0,D0 - asl.l #8,D0 // * 512 - add.l D0,A0 // buffer - add.l D1,D2 // start sector - sub.l D1,D3 - bgt.s .xr5 - moveq #0,D0 // OK - rts -.xr2: - moveq #-1,D0 // error - rts -.xr7: - move.l D3,D1 // count - cmp.l #0x100,D1 - bcs.s .xr8 - move.l #0xFF,D1 // count -.xr8: - move.l D4,D0 - bsr read_sectors - bmi.s .xr3 - move.l D1,D0 - add.l D0,D0 - asl.l #8,D0 // * 512 - add.l D0,A0 // buffer - add.l D1,D2 // start sector - sub.l D1,D3 - bgt.s .xr7 - moveq #0,D0 // OK -.xr3: - rts - -XHInqDev2: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug136(PC),A0 - bsr debug_display_string -#endif -#endif - move.l pun_ptr,A0 - moveq #0,D0 - move.w 10(A6),D0 // bios_device - cmp.l #2,D0 // C - bcs.s .xdd2 - cmp.l #16,D0 - bcc.s .xdd2 - moveq #0,D1 - move.b pinfo_pun(A0,D0.w),D1 - bpl.s .xdd1 -.xdd2: - moveq #-46,D0 // invalid drive number - rts -.xdd1: - move.l 12(A6),A1 // major - move.w D1,(A1) - move.l 16(A6),A1 // minor - clr.w (A1) - move.l pinfo_pstart(A0,D0.w*4),D1 - move.l 20(A6),A1 // start_sector - move.l D1,(A1) - lea pinfo_bpb(A0),A2 - move.l D0,D1 - asl.l #5,D1 // * 32 - add.l A2,D1 - move.l 20(A6),A1 // bpb - move.l D1,(A1) - move.l 24(A6),A1 // blocks - lea pinfo_psize(A0),A2 - move.l (A2,D0.w*4),(A1) - move.l 28(A6),A1 // partid - move.b pinfo_ptype+1(A2,D0.w*4),(A1) - move.b pinfo_ptype+2(A2,D0.w*4),D1 - bne.s .xdd3 - moveq #0x44,D1 // D -.xdd3: - move.b D1,1(A1) - move.b pinfo_ptype+3(A2,D0.w*4),(A1) - moveq #0,D0 - rts - -XHDriverSpecial: -XHGetCapacity: -XHMediumChanged: -XHMiNTInfo: - - moveq #-32,D0 // invalid function number - rts - -XHDOSLimits: - -#ifdef COLDFIRE -#ifdef DEBUG - lea debug137(PC),A0 - bsr debug_display_string -#endif + bsr display_char + moveq #0x41,D0 + add.l D6,D0 + bsr display_char #endif + lea pinfo_flags(A3),A1 + tst.l D3 + smi.b D0 + ext.w D0 + and.l #0x8000,D0 // flag swap + bset #7,D0 // disk change + move.w D0,(A1,D6.l*2) + addq.l #1,D6 // next logical drive +.test_1st_bootable_tos: + btst #0,(A2) // active partition + beq .next_partition_tos + tst.l D7 // start of 1st bootable partition + bne .next_partition_tos + cmp.l #0x47454D,D1 // GEM + beq.s .partition_gem + cmp.l #0x42474D,D1 // BGM + bne .next_partition_tos +.partition_gem: + move.b (A2),D1 + tst.b D5 // bootpref + beq.s .all_types + and.b #0xF8,D1 // remove unused bits + cmp.b D5,D1 // partition type + beq.s .partition_bootable + bra .next_partition_tos +.all_types: + and.b #0xF8,D1 // remove unused bits + beq .next_partition_tos +.partition_bootable: + move.l 4(A2),D7 // start of partition + move.l D3,D0 // D0: drive, D0.H: flag swap bytes + move.l D7,D2 // start of partition + moveq #1,D1 // 1 sector + move.l _dskbufp,A0 // read boot sector + lea 512(A0),A0 + jsr read_sectors + bmi .error_next_drive_tos + move.l _dskbufp,A0 // buffer + bsr check_root + bne .not_bootable_tos + move.l A3,D0 // pun_ptr + beq .next_partition_tos + lea pinfo_flags(A3),A1 + bset #0,-1(A1,D6.l*2) // bootable + bra .next_partition_tos +.not_bootable_tos: + moveq #0,D7 // try another partition + bra .next_partition_tos +.end_partitions_tos: + move.l D7,D0 // start of 1st bootable partition + bne.s .boot_partition_found_tos + // no bootable partition found => menu for select + bsr search_bootable_pun + bpl .error_next_drive_tos // another disk bootable found moveq #0,D0 - move.w 10(A6),D0 // which - cmp.l #XH_DL_SECSIZ,D0 // maximal sector size (BIOS level) - bne.s .xl1 - move.l #0x4000,D0 - rts -.xl1: - cmp.l #XH_DL_MINFAT,D0 // minimal number of FATs - bne.s .xl2 - moveq #1,D0 - rts -.xl2: - cmp.l #XH_DL_MAXFAT,D0 // maximal number of FATs - bne.s .xl3 - moveq #2,D0 - rts -.xl3: - cmp.l #XH_DL_MINSPC,D0 // sectors per cluster minimal - bne.s .xl4 - moveq #2,D0 - rts -.xl4: - cmp.l #XH_DL_MAXSPC,D0 // sectors per cluster maximal - bne.s .xl5 - moveq #64,D0 // for this Coldfire version of BDOS, else 2 - rts -.xl5: - cmp.l #XH_DL_CLUSTS,D0 // maximal number of clusters of a 16 bit FAT - bne.s .xl6 - move.l #0x8000,D0 - rts -.xl6: - cmp.l #XH_DL_MAXSEC,D0 // maximal number of sectors - bne.S .xl7 - move.l #0x200000,D0 // for this Coldfire version of BDOS, else 0x10000 - rts -.xl7: - cmp.l #XH_DL_DRIVES,D0 // maximal number of BIOS drives supported by the DOS - bne.s .xl8 - moveq #16,D0 - rts -.xl8: - moveq #-32,D0 // invalid function number + move.l A4,D1 // nb lines + beq .error_next_drive_tos // not found + addq.l #1,D1 + lea message126(PC),A0 + lea tab_partition(PC),A1 + bsr common_menu + ext.l D0 + beq.s .error_next_drive_tos // ignore => not found + subq.l #1,D0 + add.l A5,D0 // logical drive start + move.l D0,D6 + move.l pinfo_pstart(A3,D6.l*4),D2 // start of partition + move.l D3,D0 // D0: drive, D0.H: flag swap bytes + moveq #1,D1 // 1 sector + move.l _dskbufp,A0 // read boot sector + lea 512(A0),A0 + jsr read_sectors + bmi.s .error_next_drive_tos +// move.l _dskbufp,A0 // buffer +// bsr check_root +// bne.s .error_next_drive_tos + move.l D2,D0 // start of partition + move.l A3,D1 // pun_ptr + beq.s .boot_partition_found_tos + lea pinfo_flags(A3),A1 + bset #0,1(A1,D6.l*2) // bootable +.boot_partition_found_tos: + move.l _dskbufp,A0 // buffer + lea 512(A0),A1 + moveq #127,D1 +.copy_boot_sector_tos: + move.l (A1)+,(A0)+ + subq.l #1,D1 + bpl.s .copy_boot_sector_tos + tst.l D0 + bra.s .end_search_tos_partition +.error_next_drive_tos: + moveq #-1,D0 // error +.end_search_tos_partition: + movem.l (SP)+,D1-A5 rts - // IDE emulation - .chip 5200 - -#if 0 // unfinished, to fix with MMU update_tlb access fault !!! -access_error_ide: // called out of cf68klib - - move.w #0x2700,SR // mask interrupts - move.l SP,save_sp - move.l D0,save_registers - move.l D1,save_registers+4 - move.l A0,save_registers+32 - move.l save_sp,A0 - move.w (A0),D0 // format - move.w D0,D1 - lsr.l #8,D0 - and.l #0xC,D0 - and.l #3,D1 - or.l D0,D1 // FS - cmp.l #0xA,D1 // TLB miss on data write - beq.s .error_on_data - cmp.l #0xC,D1 // TLB miss on data read - bne .not_ide_access -.error_on_data: - move.l __MMU_BASE+0x10,D0 // MMUAR - move.l D0,save_mmuar - cmp.l #FALCON_ATA_DATA,D0 - bcs .not_ide_access - cmp.l #FALCON_ATA_DATA+0x3F,D0 - bhi .not_ide_access - lea access_fault_stack,SP - move.w 2(A0),D0 // SR - move.w D0,save_sr - lea save_registers,A0 - movem.l D2-D7,8(A0) - movem.l A1-A6,36(A0) - move.l save_sp,A0 - move.l 4(A0),A0 // PC - moveq #0,D0 - move.w (A0)+,D0 // opcode - move.l D0,D1 - and.l #0xF000,D0 - cmp.l #0x1000,D0 // move.b - bne .not_move_b - move.l D1,D0 // opcode - and.l #0xFFF8,D0 - cmp.l #0x13C0,D0 // move.b Dx,FALCON_ATA - beq.s .move_b_dx_ata - move.l D1,D0 // opcode - and.l #0xF1F8,D0 - cmp.l #0x1080,D0 // move.b Dx,(Ax) - beq.s .write_register_b - cmp.l #0x1100,D0 // move.b Dx,-(Ax) - beq.s .write_register_b - cmp.l #0x10C0,D0 // move.b Dx,(Ax)+ - bne.s .not_move_b_dx_ax - move.l D1,D0 // opcode - swap D0 - lsr.l #1,D0 - and.l #7,D0 // address register index - move.l A0,-(SP) - lea save_registers,A0 - lea 32(A0,D0.w*4),A0 - addq.l #1,(A0) // (Ax)+ - move.l (SP)+,A0 // PC - bra.s .move_b_dx_ata -.not_move_b_dx_ax: - cmp.l #0x1140,D0 // move.b Dx,d16(Ax) - beq.s .move_b_dx_dax - cmp.l #0x1180,D0 // move.b Dx,d8(Ax,Xi) - bne .not_move_b_dx_dax -.move_b_dx_dax: - addq.l #2,A0 // fix PC - bra.s .write_register_b -.move_b_dx_ata: - addq.l #4,A0 // fix PC -.write_register_b: - move.l A0,save_pc - -#ifdef DEBUG - move.l save_sp,A0 - move.l 4(A0),A0 // PC - move.w (A0),D0 // opcode - bsr debug_hex_word - moveq #0x20,D0 - bsr debug_display_char - move.l save_pc,D0 // PC updated - bsr debug_hex_long - - moveq #0x20,D0 - bsr debug_display_char - move.l save_sp,A0 - move.l 4(A0),A0 // PC - move.w (A0),D0 // opcode - bsr debug_hex_word - - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif - - - lea save_registers,A0 - moveq #7,D0 - and.l D1,D0 // opcode => register index - move.l (A0,D0.w*4),D1 // value - +atari_root: + lea message48(PC),A0 + bsr display_string #ifdef DEBUG - move.l save_sp,A0 - move.l 4(A0),A0 // PC - move.w (A0),D0 // opcode - bsr debug_hex_word - moveq #0x20,D0 - bsr debug_display_char - move.l save_pc,D0 // PC updated - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char + move.l _dskbufp,A1 + moveq #31,D1 + bsr dump +#ifndef COLDFIRE + bsr wait_key #endif - - - move.l save_mmuar,D0 - lsr.l #2,D0 // / 4 - not.l D0 - and.l #0xF,D0 - bclr #3,D0 - beq .end_opcode - lea save_ide_registers,A0 - move.b D1,(A0,D0.w) - tst.l D0 - bne .end_opcode // <> cmd - bra .send_ide_cmd -.not_move_b_dx_dax: - move.l D1,D0 // opcode - and.l #0xF1FF,D0 - cmp.l #0x1039,D0 // move.b FALCON_ATA,Dx - beq.s .move_b_ata_dx - move.l D1,D0 // opcode - and.l #0xF1F8,D0 - cmp.l #0x1010,D0 // move.b (Ax),Dx - beq.s .read_register_b - cmp.l #0x1020,D0 // move.b -(Ax),Dx - beq.s .read_register_b - cmp.l #0x1018,D0 // move.b (Ax)+,Dx - bne.s .not_move_b_ax_dx - moveq #7,D0 - and.l D1,D0 // opcode => address register index - move.l A0,-(SP) - lea save_registers,A0 - lea 32(A0,D0.w*4),A0 - addq.l #1,(A0) // (Ax)+ - move.l (SP)+,A0 // PC - bra.s .move_b_ata_dx -.not_move_b_ax_dx: - cmp.l #0x1028,D0 // move.b d16(Ax),Dx - beq.s .move_b_dax_dx - cmp.l #0x1030,D0 // move.b d8(Ax,Xi),Dx - bne.s .not_move_b_dax_dx -.move_b_dax_dx: - addq.l #2,A0 // fix PC - bra.s .read_register_b -.move_b_ata_dx: - addq.l #4,A0 // fix PC -.read_register_b: - move.l A0,save_pc - lsr.l #8,D1 - lsr.l #1,D1 - and.l #7,D1 // register index - bra.s .read_register_dx -.not_move_b_dax_dx: -.not_move_b: - bra .unknow_opcode -.read_register_dx: - move.l save_mmuar,D0 - lea ATA_ERROR_REGISTER,A0 - cmp.l #FALCON_ATA_ERROR_REGISTER,D0 - beq.s .update_register - lea ATA_SECTOR_COUNT,A0 - cmp.l #FALCON_ATA_SECTOR_COUNT,D0 - beq.s .update_register - lea ATA_SECTOR_NUM,A0 - cmp.l #FALCON_ATA_SECTOR_NUM,D0 - beq.s .update_register - lea ATA_CYLINDER_LOW,A0 - cmp.l #FALCON_ATA_CYLINDER_LOW,D0 - beq.s .update_register - lea ATA_CYLINDER_HIGH,A0 - cmp.l #FALCON_ATA_CYLINDER_HIGH,D0 - beq.s .update_register - lea ATA_DEVICE_HEAD,A0 - cmp.l #FALCON_ATA_DEVICE_HEAD,D0 - beq.s .update_register - lea ATA_CONTROL_DEVICE,A0 - cmp.l #FALCON_ATA_CONTROL_DEVICE,D0 - bne .end_opcode -.update_register: +#endif /* DEBUG */ + move.l _sysbase,A0 // header ROM + move.l 0x24(A0),A0 // kbshift move.b (A0),D0 - lea save_registers,A0 - move.b D0,3(A0,D1.w*4) - move.l save_sp,A0 - move.b (A0),D0 // format - lsr.l #4,D0 - and.l #3,D0 // stack alignment - sub.l D0,A0 - subq.l #8,A0 // original stack before access fault - move.l A0,save_sp - lea save_registers,A0 - movem.l 4(A0),D1-A6 - clr.l save_mmuar - move.l save_sp,SP - move.w save_sr,D0 - move.w D0,SR - move.l save_registers,D0 - move.l save_pc,-(SP) - rts -.send_ide_cmd: - move.w 2(A0),D0 // sector high / sector low - move.w D0,ATA_CYLINDER_HIGH - move.w 4(A0),D0 // sector num / sector count - move.w D0,ATA_SECTOR_NUM - move.b 6(A0),D0 // features (error when read) - move.w D0,ATA_ERROR_REGISTER - moveq #2,D0 // control device, disable interrupt - move.b D0,ATA_CONTROL_DEVICE - move.w (A0),D0 // command, C/D/H - move.w D0,ATA_STATUS_COMMAND -.end_opcode: -#ifdef DEBUG - move.l save_sp,A0 - move.l 4(A0),A0 // PC - move.w (A0),D0 // opcode - bsr debug_hex_word - moveq #0x20,D0 - bsr debug_display_char - move.l save_pc,D0 // PC updated - bsr debug_hex_long - moveq #0x20,D0 - bsr debug_display_char - move.l save_sp,A0 - move.w (A0),D0 - bsr debug_hex_word // format - moveq #0x20,D0 - bsr debug_display_char - move.w 2(A0),D0 - bsr debug_hex_word // SR - moveq #0x20,D0 - bsr debug_display_char - move.l A0,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif - move.l save_sp,A0 - move.b (A0),D0 // format - lsr.l #4,D0 - and.l #3,D0 // stack alignment - sub.l D0,A0 - subq.l #8,A0 // original stack before access fault - move.l A0,save_sp - clr.l save_mmuar - lea save_registers,A0 - move.l 4(A0),D1 - movem.l 32(A0),A0-A6 - move.l save_sp,SP - move.w save_sr,D0 - move.w D0,SR - move.l save_registers,D0 - move.l save_pc,-(SP) - rts -.unknow_opcode: - move.l save_sp,SP -.not_ide_access: - move.l save_registers+32,A0 - move.l save_registers+4,D1 - move.l save_registers,D0 - move.l old_access_error,-(SP) - rts -#endif /* #if 0 */ - - // IDE driver - .chip 68060 + move.l _dskbufp,A0 + move.l #0x444D4172,D3 // DMAr + move.w D4,D7 + asl.w #5,D7 + move.w 0xA80,D5 // bootpref NVM + btst #2,D0 // CTRL + bne .normal_bootpref + and.w #0x67,D5 // remove TOS, Linux, MagiC flags for menu_boot +.normal_bootpref: + movem.l A5/A6,-(SP) + move.l pun_ptr,-(sp) + clr.l pun_ptr + move.l hdv_rw,-(SP) + jsr (A0) // exec boot sector + move.l (SP)+,D0 + move.l (SP)+,D1 + movem.l (SP)+,A5/A6 + cmp.l hdv_rw,D0 + bne .end_boot_drive_atari // driver installed by boot sector + move.l D1,pun_ptr +#if !defined(USE_ATARI_IO) || defined(COLDFIRE) -install_xbra: // A0: handler, D0: vector +atari_root2: -#ifdef COLDFIRE - lea -28(SP),SP - movem.l D1-D3/A0-A3,(SP) -#else - movem.l D1-D3/A0-A3,-(SP) -#endif - moveq #0,D3 - move.w D0,D3 // vector - move.l A0,A3 // handler - move.w #3,-(SP) // TT ram if possible - move.l #18,-(SP) // size - move.w #0x44,-(SP) // Mxalloc - trap #1 - addq.l #8,SP - tst.l D0 - beq.s .error_xbra - move.l D0,A0 - move.l #0x58425241,(A0)+ // XBRA - move.l #0x5F445256,(A0)+ // _DRV - clr.l (A0)+ - move.w #0x4EF9,(A0)+ // JMP - move.l A3,(A0)+ // handler - lea -10(A0),A0 - cpusha BC - move.l D3,A1 - move.l (A1),D0 - move.l D0,(A0)+ // old vector - move.l A0,(A1) // JMP, new vector -.error_xbra: - tst.l D0 -#ifdef COLDFIRE - movem.l (SP),D1-D3/A0-A3 - lea 28(SP),SP -#else - movem.l (SP)+,D1-D3/A0-A3 -#endif + moveq #PUN_IDE,D0 + and.w D4,D0 + beq .next_drive_atari + move.l _dskbufp,A0 + moveq #0,D2 // root sector + moveq #1,D1 // 1 sector + moveq #0,D0 // no swap bytes + move.w D4,D0 // drive + jsr read_sectors // reload (buffer maybe destroyed) + bmi.s .next_drive_atari + bsr search_empty_pun + bmi.s .next_drive_atari + move.l D0,D1 // logical drive + moveq #0,D0 // no swap bytes + move.w D4,D0 // drive + move.w D5,D2 // bootpref + bsr search_tos_partition // D0: drive, D0.H: flag swap bytes, D1: logical drive, D2: bootpref +#endif /* USE_ATARI_IO */ +.next_drive_atari: + moveq #0,D0 + rts +.end_boot_drive_atari: + moveq #1,D0 rts -install_hddriver: - -#ifdef COLDFIRE - lea -32(SP),SP - movem.l D1-D4/A0-A3,(SP) -#ifdef DEBUG - lea debug128(PC),A0 - bsr debug_display_string - move.l pun_ptr,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif -#else - movem.l D1-D4/A0-A3,-(SP) -#endif - move.l pun_ptr,D0 - beq .no_drive - move.l D0,A3 - lea pinfo_bpb(A3),A1 - move.l #((16*32)/4),D0 -.clr_tab_bpb: - clr.l (A1)+ - subq.l #1,D0 - bpl.s .clr_tab_bpb - moveq #2,D4 // logical drive -.loop_partition: - moveq #0,D0 - move.b pinfo_pun(A3,D4.l),D0 - bmi .next_partition - swap D0 - lea pinfo_flags(A3),A0 - tst.w (A0,D4.l*2) - smi.b D0 // flag swap - ext.w D0 - swap D0 // swap/drive - move.l pinfo_pstart(A3,D4.l*4),D2 - moveq #1,D1 // 1 sector - move.l _dskbufp,A0 // read boot sector - bsr read_sectors - bmi .next_partition - move.l _dskbufp,A0 // boot sector - lea pinfo_bpb(A3),A1 - move.l D4,D2 // logical drive - asl.l #5,D2 // * 32 - add.l D2,A1 - moveq #0,D2 - move.b 0xC(A0),D2 - asl.l #8,D2 - move.b 0xB(A0),D2 // BPS - move.w D2,(A1) // sector size +search_dos_partition: // D0: drive, D0.H: flag swap bytes + // D1: logical drive + movem.l D1-A5,-(SP) + move.w D0,D3 // drive + moveq #0,D6 + move.w D1,D6 // logical drive + moveq #0,D7 // start of 1st bootable partition + move.l pun_ptr,A3 + move.l _dskbufp,A2 + lea 0x1BE(A2),A2 // infos partitions MSDOS + lea 0,A4 // partition count + move.l D6,A5 // logical drive start + moveq #3,D4 // 4 partitions +.loop_partition_msdos: + tst.l 12(A2) // nr sect + beq .next_partition_msdos moveq #0,D1 - move.b 0xD(A0),D1 // SPC - move.w D1,2(A1) // cluster size in sectors - move.w D1,D0 - mulu D2,D0 - move.w D0,4(A1) // cluster size in bytes - moveq #0,D0 - move.b 0x12(A0),D0 - asl.l #8,D0 - move.b 0x11(A0),D0 // NDIRS - asl.l #5,D0 // * 32 - divu D2,D0 // / sector size - move.w D0,6(A1) // size directory in sectors - moveq #0,D2 - move.b 0x17(A0),D2 - asl.l #8,D2 - move.b 0x16(A0),D2 // SPF - move.w D2,8(A1) // FAT size - moveq #0,D0 - move.b 0xF(A0),D0 - asl.l #8,D0 - move.b 0xE(A0),D0 // RES - move.l D0,D3 - add.l D2,D3 // + FAT size - move.w D3,10(A1) // 1st sector of FAT2 - moveq #0,D3 - move.b 0x10(A0),D3 // NFATS - mulu D2,D3 // * FAT size - add.l D0,D3 // + RES - moveq #0,D0 - move.w 6(A1),D0 // size directory in sectors - add.l D3,D0 - move.w D0,12(A1) // 1st data sector - moveq #0,D2 - move.b 0x14(A0),D2 - asl.l #8,D2 - move.b 0x13(A0),D2 // NSECTS - bne.s .nsects_ok - lea pinfo_psize(A3),A2 - move.l (A2,D4.w*4),D2 // partition size in sectors - sub.l D0,D2 // - 1st data sector -.nsects_ok: - divu D1,D2 - move.w D2,14(A1) // total clusters - moveq #1,D0 - move.w D0,16(A1) // FAT 16 - clr.w 18(A1) - clr.l 20(A1) - clr.l 24(A1) - clr.l 28(A1) - move.l _drvbits,D0 - bset D4,D0 // logical drive - move.l D0,_drvbits -#ifdef DEBUG - lea debug125(PC),A0 - bsr debug_display_string - moveq #8,D1 -.loop_bpb: - move.w (A1)+,D0 - bsr debug_hex_word - moveq #0x20,D0 - bsr debug_display_char - subq.l #1,D1 - bpl.s .loop_bpb - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - lea debug129(PC),A0 - bsr debug_display_string - move.l _drvbits,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif -.next_partition: - addq.l #1,D4 - cmp.l #16,D4 - bcs .loop_partition - lea pinfo_cookie(A3),A0 - move.l #0x41484449,(A0) // AHDI - move.l A0,4(A0) - move.w #0x0300,pinfo_vernum(A3) - move.w #0x4000,pinfo_maxsiz(A3) - move.w SR,D0 - move.w D0,-(SP) - or.l #0x700,D0 // mask interrupts - move.w D0,SR - lea det_hdv_bpb(PC),A0 - move.w #hdv_bpb,D0 - bsr install_xbra - move.l D0,old_hdv_bpb_hd - lea det_hdv_rw(PC),A0 - move.w #hdv_rw,D0 - bsr install_xbra - move.l D0,old_hdv_rw_hd - lea det_hdv_mediach(PC),A0 - move.w #hdv_mediach,D0 - bsr install_xbra - move.l D0,old_hdv_mediach_hd - move.l cookie,D0 - beq.s .no_cookie_jar - move.l D0,A0 -.find_cookie_jar: - tst.l (A0) - beq.s .cookie_slot_free - addq.w #8,A0 - bra.s .find_cookie_jar -.cookie_slot_free: - move.l 4(A0),12(A0) // copy size - move.l #0x58484449,(A0)+ // XHDI - lea xhdi(PC),A2 - move.l A2,(A0)+ - clr.l (A0) -.no_cookie_jar: - move.w (SP)+,D0 - move.w D0,SR - lea pinfo_flags(A3),A0 - moveq #0,D4 // logical drive -.search_partition_boot: - move.w (A0)+,D0 - btst #0,D0 - bne.s .found_partition_boot - addq.l #1,D4 - cmp.l #16,D4 - bcs.s .search_partition_boot - bra.s .no_drive -.found_partition_boot: - move.w D4,_bootdev - move.w D4,-(SP) // logical boot drive - move.w #0xE,-(SP) // Dsetdrv - trap #1 - addq.l #4,SP -.no_drive: -#ifdef COLDFIRE - movem.l (SP),D1-D4/A0-A3 - lea 32(SP),SP + move.b 4(A2),D1 // partition type + cmp.l #0x5,D1 // extended partition + beq .extended_partition_msdos + cmp.l #0xF,D1 // WIN95 extended partition + beq .extended_partition_msdos +#if 1 + tst.l D1 + bne.s .partition_ok_msdos #else - movem.l (SP)+,D1-D4/A0-A3 + cmp.l #0x1,D1 // FAT12 up to 15M + beq.s .partition_ok_msdos + cmp.l #0x4,D1 // FAT16 up to 32M + beq.s .partition_ok_msdos + cmp.l #0x6,D1 // FAT16 over 32M + beq.s .partition_ok_msdos + cmp.l #0xE,D1 // WIN95 FAT16 + beq.s .partition_ok_msdos #endif - rts - -det_hdv_bpb: - - move.l A0,-(SP) - move.l pun_ptr,A0 - moveq #0,D0 - move.w 4+4(SP),D0 // drive - cmp.l #2,D0 // C - bcs.s .dhb2 - cmp.l #16,D0 - bcc.s .dhb2 - tst.b pinfo_pun(A0,D0.l) - bpl.s .dhb1 -.dhb2: - move.l (SP)+,A0 - moveq #0,D0 - move.l old_hdv_bpb_hd,-(SP) - rts -.dhb1: - lea pinfo_bpb(A0),A0 - asl.l #5,D0 // * 32 - add.l A0,D0 - move.l (SP)+,A0 - rts - -det_hdv_rw: - - lea -20(SP),SP - movem.l D1-D4/A0,(SP) - move.l pun_ptr,A0 - moveq #0,D0 - move.w 14+20(SP),D0 // drive - cmp.l #2,D0 // C - bcs.s .dhr10 - cmp.l #16,D0 - bcc.s .dhr10 - moveq #0,D4 - move.b pinfo_pun(A0,D0.l),D4 - bpl.s .dhr1 -.dhr10: - movem.l (SP),D1-D4/A0 - lea 20(SP),SP - moveq #0,D0 - move.l old_hdv_rw_hd,-(SP) - rts -.dhr1: - moveq #0,D2 - move.w 12+20(SP),D2 // logical sector - bpl.s .dhr9 - move.l 16+20(SP),D2 // logical sector -.dhr9: + bra.s .next_partition_msdos +.extended_partition_msdos: + move.l 8(A2),D2 // start sect = extended partition + ror.w #8,D2 + swap D2 + ror.w #8,D2 + lea 16(A2),A2 + subq.l #1,D4 + bpl.s .loop_partition_msdos + bra.s .test_extended_partition_msdos +.next_partition_msdos: + moveq #0,D2 + lea 16(A2),A2 + subq.l #1,D4 + bpl.s .loop_partition_msdos +.test_extended_partition_msdos: tst.l D2 - bmi .dhr2 // negative logical sector - move.l 6+20(SP),D1 // buffer - beq .dhr4 // no buffer - move.l pinfo_pstart(A0,D0.l*4),D3 - swap D4 - lea pinfo_flags(A0),A0 - tst.w (A0,D0.l*2) - smi.b D4 // flag swap - ext.w D4 - swap D4 // swap/drive - lea pinfo_bpb-pinfo_flags(A0),A0 - asl.l #5,D0 // * 32 - add.l D0,A0 - move.w 14(A0),D0 // total clusters - mulu.w 2(A0),D0 // cluster size in sectors - cmp.l D0,D2 // logical sector to hight - bcc .dhr2 + beq .end_partitions_msdos // no extended partition + moveq #1,D1 // 1 sector + moveq #-1,D0 // swap bytes + move.w D3,D0 // drive + move.l _dskbufp,A0 // read extended partition + jsr read_sectors + bmi .error_next_drive_msdos + move.l A0,A2 + cmp.w #0x55AA,510(A2) // magic + bne .error_next_drive_msdos + lea 0x1BE(A2),A2 // infos partitions + moveq #0,D2 + moveq #1,D4 // 1 entry by ext sector + bra .loop_partition_msdos +.partition_ok_msdos: // know this partition type + move.l 8(A2),D2 // start sect + ror.w #8,D2 + swap D2 + ror.w #8,D2 + move.l A3,D0 // pun_ptr + beq .test_1st_bootable_msdos + cmp.l #16,D6 // logical drive + bcc .test_1st_bootable_msdos + addq.l #1,A4 // partition count + lea pinfo_ptype(A3),A1 + move.l D1,(A1,D6.l*4) + move.l D2,pinfo_pstart(A3,D6.l*4) + move.l 12(A2),D0 // nr sect + ror.w #8,D0 + swap D0 + ror.w #8,D0 + lea pinfo_psize(A3),A1 + cmp.l #0x1,D1 // FAT12 up to 15M + beq.s .check_partition_size_msdos + cmp.l #0x4,D1 // FAT16 up to 32M + beq.s .check_partition_size_msdos + cmp.l #0x6,D1 // FAT16 over 32M + beq.s .check_partition_size_msdos + cmp.l #0xE,D1 // WIN95 FAT16 + bne.s .no_limit_size_msdos +.check_partition_size_msdos: + cmp.l #0x400000,D0 + bcs.s .no_limit_size_msdos + move.l #0x400000,D0 // 2GB limit +.no_limit_size_msdos: + move.l D0,(A1,D6.l*4) + move.b D3,pinfo_pun(A3,D6.l) // drive + move.w pinfo_puns(A3),D0 + addq.l #1,D0 + move.w D0,pinfo_puns(A3) #ifdef DEBUG - move.l A0,-(SP) - lea debug127(PC),A0 - bsr debug_display_string - move.w 4+24(SP),D0 // rwflag - bsr debug_hex_word - moveq #0x20,D0 - bsr debug_display_char - moveq #0x30,D0 - bsr debug_display_char - moveq #0x78,D0 - bsr debug_display_char - move.l D1,D0 // buffer - bsr debug_hex_long - moveq #0x20,D0 - bsr debug_display_char - moveq #0x30,D0 - bsr debug_display_char - moveq #0x78,D0 - bsr debug_display_char - move.w 10+24(SP),D0 // num sectors - bsr debug_hex_word + move.l D0,-(SP) + lea debug15(PC),A0 + bsr display_string_single + move.l D1,D0 + bsr hex_long moveq #0x20,D0 - bsr debug_display_char + bsr display_char moveq #0x30,D0 - bsr debug_display_char + bsr display_char moveq #0x78,D0 - bsr debug_display_char - move.l D2,D0 // logical sector - bsr debug_hex_long + bsr display_char + move.l D2,D0 + bsr hex_long moveq #0x20,D0 - bsr debug_display_char + bsr display_char moveq #0x30,D0 - bsr debug_display_char + bsr display_char moveq #0x78,D0 - bsr debug_display_char - move.w 14+24(SP),D0 // drive - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,A0 -#endif - moveq #0,D0 - move.w (A0),D0 // sector size - lsr.l #8,D0 - lsr.l #1,D0 // / 512 - move.l D1,A0 // buffer - move.w 10+20(SP),D1 // num sectors - beq .dhr4 // no sectors - mulu D0,D1 - mulu.l D0,D2 - add.l D3,D2 // start sector - move.l D1,D3 // count - btst #0,5+20(SP) // rwflag - beq.s .dhr7 // read - tst.l D2 // logical sector - beq.s .dhr2 // root sector -.dhr5: - move.l D3,D1 // count - cmp.l #0x100,D1 - bcs.s .dhr6 - move.l #0xFF,D1 // count -.dhr6: - move.l D4,D0 - bsr write_sectors - bmi.s .dhr3 - move.l D1,D0 - add.l D0,D0 - asl.l #8,D0 // * 512 - add.l D0,A0 // buffer - add.l D1,D2 // start sector - sub.l D1,D3 - bgt.s .dhr5 - bra.s .dhr4 -.dhr2: - moveq #-1,D0 // error - bra.s .dhr3 -.dhr7: - move.l D3,D1 // count - cmp.l #0x100,D1 - bcs.s .dhr8 - move.l #0xFF,D1 // count -.dhr8: - move.l D4,D0 - bsr read_sectors - bmi.s .dhr3 - move.l D1,D0 - add.l D0,D0 - asl.l #8,D0 // * 512 - add.l D0,A0 // buffer - add.l D1,D2 // start sector - sub.l D1,D3 - bgt.s .dhr7 -.dhr4: - moveq #0,D0 // OK -.dhr3: - movem.l (SP),D1-D4/A0 - lea 20(SP),SP - rts - -det_hdv_mediach: - - move.l A0,-(SP) - move.l pun_ptr,A0 - moveq #0,D0 - move.w 4+4(SP),D0 // drive - cmp.l #2,D0 // C - bcs.s .dhm2 - cmp.l #16,D0 - bcc.s .dhm2 - tst.b pinfo_pun(A0,D0.l) - bpl.s .dhm1 -.dhm2: - move.l (SP)+,A0 - moveq #0,D0 - move.l old_hdv_mediach_hd,-(SP) - rts -.dhm1: - lea pinfo_flags(A0),A0 - add.l D0,A0 - add.l D0,A0 - bclr #7,1(A0) - sne.b D0 - and.l #2,D0 - move.l (SP)+,A0 - rts - -#endif /* COLDFIRE */ - -swap_buffer: // A0: buffer, D0: count - -#ifdef COLDFIRE - lea -16(SP),SP - movem.l D0-D2/A0,(SP) - and.l #0xFFFF,D0 - bra.s .end_loop_swap -.loop_swap: - move.l #255,D2 -.loop_swap_2: - move.b 1(A0),D1 - asl.l #8,D1 - move.b (A0),D1 - move.w D1,(A0)+ - subq.l #1,D2 - bpl.s .loop_swap_2 -.end_loop_swap: - subq.l #1,D0 - bpl.s .loop_swap - movem.l (SP),D0-D2/A0 - lea 16(SP),SP -#else - movem.l D0-D2/A0,-(SP) - bra.s .end_loop_swap -.loop_swap: - move.w #255,D2 -.loop_swap_2: - move.w (A0),D1 - ror.w #8,D1 - move.w D1,(A0)+ - dbf D2,.loop_swap_2 -.end_loop_swap: - dbf D0,.loop_swap - movem.l (SP)+,D0-D2/A0 -#endif - rts - -read_sectors: // A0: buffer, D0: drive, D0.H: flag swap bytes, D1: count, D2.L: start sector - // return error code inside D0 -#ifdef COLDFIRE - lea -36(SP),SP - movem.l D1-D4/A0-A4,(SP) -#else - movem.l D1-D4/A0-A4,-(SP) -#endif - move.l A0,A4 // buffer - move.l D0,D4 // physical drive & flag swap bytes - move.w D1,D3 // count - btst #4,D4 - beq .use_DMAread // SCSI - link A6,#-8 - move.l A4,A0 // IDE buffer - lea -8(A6),A1 // cmd buffer - move.b #0x20,(A1) // read sector(s) - moveq #7,D0 - and.l D4,D0 // physical drive - asl.l #4,D0 - or.l #0xE0,D0 // LBA - move.b D0,1(A1) // drive (C/D/H) - move.l D2,D0 // LBA - move.b D0,4(A1) // sec num, LBA low - lsr.l #8,D0 - move.w D0,2(A1) // cyl high & low, LBA high & mid - move.b D1,5(A1) // sec count 0 <=> 256 - clr.b 6(A1) // features - moveq #0,D0 - move.w D1,D0 // count - add.l D0,D0 - asl.l #8,D0 // * 512 = bytes - bsr ide_cmd - unlk A6 - ble.s .end_read_sectors // OK or time-out - moveq #-11,D0 // read error - bra.s .end_read_sectors -.use_DMAread: - move.w D4,-(SP) // physical drive - move.l A4,-(SP) // buffer - move.w D1,-(SP) // count - move.l D2,-(SP) // sector - move.w #0x2A,-(SP) // DMAread - trap #14 - lea 14(SP),SP - ext.l D0 -.end_read_sectors: - tst.l D0 - bmi.s .end_read_sectors_swap - tst.l D4 // flag swap bytes - bpl.s .end_read_sectors_swap - move.l D0,-(SP) - move.l A4,A0 // buffer - move.w D3,D0 // count - bsr swap_buffer - move.l (SP)+,D0 -.end_read_sectors_swap: -#if 0 // #ifdef DEBUG - tst.l D0 - bmi.s .error_sectors_read - move.l D0,-(SP) - ext.l D3 - bra.s .end_dump_sectors_read -.loop_dump_sectors_read: - move.l A4,A1 - moveq #31,D1 - bsr dump - bsr wait_key - lea 512(A4),A4 -.end_dump_sectors_read: - subq.l #1,D3 - bpl.s .loop_dump_sectors_read -.error_sectors_read: + bsr display_char move.l (SP)+,D0 -#endif - tst.l D0 -#ifdef COLDFIRE - movem.l (SP),D1-D4/A0-A4 - lea 36(SP),SP -#else - movem.l (SP)+,D1-D4/A0-A4 + bsr hex_long + moveq #0x20,D0 + bsr display_char + moveq #0x41,D0 + add.l D6,D0 + bsr display_char #endif - rts - -write_sectors: // A0: buffer, D0: drive, D0.H: flag swap bytes, D1: count, D2.L: start sector - // return error code inside D0 -#ifdef COLDFIRE - lea -36(SP),SP - movem.l D1-D4/A0-A4,(SP) -#else - movem.l D1-D4/A0-A4,-(SP) -#endif - move.l A0,A4 // buffer - move.w D1,D3 // count - move.l D0,D4 // physical drive & flag swap bytes - bpl.s .begin_write_sectors_swap - move.l A4,A0 // buffer - move.w D3,D0 // count - bsr swap_buffer -.begin_write_sectors_swap: - btst #4,D4 - beq .use_DMAwrite // SCSI - link A6,#-8 - move.l A4,A0 // IDE buffer - lea -8(A6),A1 // cmd buffer - move.b #0x30,(A1) // write sector(s) - moveq #7,D0 - and.l D4,D0 // physical drive - asl.l #4,D0 - or.l #0xE0,D0 // LBA - move.b D0,1(A1) // drive (C/D/H) - move.l D2,D0 // LBA - move.b D0,4(A1) // sec num, LBA low - lsr.l #8,D0 - move.w D0,2(A1) // cyl high & low, LBA high & mid - move.b D1,5(A1) // sec count 0 <=> 256 - clr.b 6(A1) // features + lea pinfo_flags(A3),A1 + move.w #0x8080,(A1,D6.l*2) // flag swap & disk change + addq.l #1,D6 // next logical drive +.test_1st_bootable_msdos: + cmp.b #0x80,(A2) // active partition bootable + bne .next_partition_msdos + tst.l D7 // start of 1st bootable partition + bne .next_partition_msdos + cmp.l #0x1,D1 // FAT12 up to 15M + beq.s .read_boot_sector_msdos + cmp.l #0x4,D1 // FAT16 up to 32M + beq.s .read_boot_sector_msdos + cmp.l #0x6,D1 // FAT16 over 32M + beq.s .read_boot_sector_msdos + cmp.l #0xE,D1 // WIN95 FAT16 + bne .next_partition_msdos +.read_boot_sector_msdos: + move.l D2,D7 // start of partition + moveq #1,D1 // 1 sector + moveq #-1,D0 // swap bytes + move.w D3,D0 // drive + move.l _dskbufp,A0 // read boot sector + lea 512(A0),A0 + jsr read_sectors + bmi .error_next_drive_msdos + cmp.w #0x55AA,510(A0) // magic + bne .not_bootable_msdos + move.l A3,D0 // pun_ptr + beq .next_partition_msdos + lea pinfo_flags(A3),A1 + bset #0,-1(A1,D6.l*2) // bootable + bra .next_partition_msdos +.not_bootable_msdos: + moveq #0,D7 // try another partition + bra .next_partition_msdos +.end_partitions_msdos: + move.l D7,D0 // start of 1st bootable partition + bne.s .boot_partition_found_msdos + // no bootable partition found => menu for select + bsr search_bootable_pun + bpl .error_next_drive_msdos // another disk bootable found moveq #0,D0 - move.w D1,D0 // count - add.l D0,D0 - asl.l #8,D0 // * 512 = bytes - bsr ide_cmd - unlk A6 - ble.s .end_write_sectors // OK or time-out - moveq #-10,D0 // write error - bra.s .end_write_sectors -.use_DMAwrite: - move.w D4,-(SP) // physical drive - move.l A4,-(SP) // buffer - move.w D1,-(SP) // count - move.l D2,-(SP) // sector - move.w #0x2B,-(SP) // DMAwrite - trap #14 - lea 14(SP),SP + move.l A4,D1 // nb lines + beq.s .error_next_drive_msdos // not found + addq.l #1,D1 + lea message126(PC),A0 + lea tab_partition(PC),A1 + bsr common_menu ext.l D0 -.end_write_sectors: - tst.l D4 // flag swap bytes - bpl.s .end_write_sectors_swap - move.l D0,-(SP) - move.l A4,A0 // buffer - move.w D3,D0 // count - bsr swap_buffer - move.l (SP)+,D0 -.end_write_sectors_swap: -#if 0 // #ifdef DEBUG - tst.l D0 - bmi.s .error_sectors_write - move.l D0,-(SP) - ext.l D3 - bra.s .end_dump_sectors_write -.loop_dump_sectors_write: - move.l A4,A1 - moveq #31,D1 - bsr dump - bsr wait_key - lea 512(A4),A4 -.end_dump_sectors_write: - subq.l #1,D3 - bpl.s .loop_dump_sectors_write -.error_sectors_write: - move.l (SP)+,D0 -#endif + beq.s .error_next_drive_msdos // ignore => not found + subq.l #1,D0 + add.l A5,D0 // logical drive start + move.l D0,D6 + move.l pinfo_pstart(A3,D6.l*4),D2 // start of partition + moveq #1,D1 // 1 sector + moveq #-1,D0 // swap bytes + move.w D3,D0 // drive + move.l _dskbufp,A0 // read boot sector + lea 512(A0),A0 + jsr read_sectors + bmi.s .error_next_drive_msdos +// cmp.w #0x55AA,510(A0) // magic +// bne.s .error_next_drive_msdos + move.l D2,D0 // start of partition + move.l A3,D1 // pun_ptr + beq.s .boot_partition_found_msdos + lea pinfo_flags(A3),A1 + bset #0,1(A1,D6.l*2) // bootable +.boot_partition_found_msdos: + move.l _dskbufp,A0 // buffer + lea 512(A0),A1 // boot sector already read + moveq #127,D1 +.copy_boot_sector_msdos: + move.l (A1)+,(A0)+ + subq.l #1,D1 + bpl.s .copy_boot_sector_msdos tst.l D0 -#ifdef COLDFIRE - movem.l (SP),D1-D4/A0-A4 - lea 36(SP),SP -#else - movem.l (SP)+,D1-D4/A0-A4 -#endif - rts - -#ifdef COLDFIRE - -error_unknow_device: - - moveq #-15,D0 + bra.s .end_search_dos_partition +.error_next_drive_msdos: + moveq #-1,D0 +.end_search_dos_partition: + movem.l (SP)+,D1-A5 rts -error_ok: +msdos_root: // last bytes of root sector are 0xAA55 + btst #4,D4 + beq .not_ide_drive // SCSI + tst.w D7 + bpl .next_drive_msdos // LBA not supported (needed by read_sectors) +.not_ide_drive: + move.l _dskbufp,A0 + moveq #1,D0 + jsr swap_buffer + lea message90(PC),A0 // boot MSDOS combined + bsr display_string +#ifdef DEBUG + move.l _dskbufp,A1 + moveq #31,D1 + bsr dump +#ifndef COLDFIRE + bsr wait_key +#endif +#endif /* DEBUG */ + move.l _sysbase,A0 // header ROM + move.l 0x24(A0),A0 // kbshift + move.b (A0),D0 + move.l #0x444D4172,D3 // DMAr + move.w D4,D7 + asl.w #5,D7 + move.w 0xA80,D5 // bootpref NVM + btst #3,D0 // ALT + bne .next_drive_msdos + btst #2,D0 // CTRL + bne .normal_bootpref_2 + and.w #0x67,D5 // remove TOS, Linux, MagiC flags for menu_boot +.normal_bootpref_2: + bsr search_empty_pun + bmi .next_drive_msdos + move.l D0,D1 // logical drive + move.l _dskbufp,A0 + bsr check_root + beq .root_combined_valid + // DOS only + move.w D4,D0 // drive + bsr search_dos_partition // D0: drive, D0.H: flag swap bytes, D1: logical drive + bmi .next_drive_msdos + move.l D0,D2 + bra.s .boot_tos_partition +.root_combined_valid: + moveq #-1,D0 // swap bytes + move.w D4,D0 // drive + move.w D5,D2 // bootpref + bsr search_tos_partition // D0: drive, D0.H: flag swap bytes, D1: logical drive, D2: bootpref + bmi .next_drive_msdos + move.l D0,D2 // start of partition +.boot_tos_partition: +#ifdef DEBUG + lea debug13(PC),A0 + bsr display_string_single + move.l D2,D0 + bsr hex_long +#endif + move.l pun_ptr,-(sp) + clr.l pun_ptr + move.l hdv_rw,-(SP) + move.l D2,D1 // start of partition + moveq #-1,D0 // swap bytes + move.w D4,D0 // drive + bsr exec_sys // try to load xxxxdriver.sys without boot sector + move.l (SP)+,D0 + move.l (SP)+,D1 + cmp.l hdv_rw,D0 + bne .end_boot_drive_dos // driver installed + move.l D1,pun_ptr +.next_drive_msdos: moveq #0,D0 rts - -#endif /* COLDFIRE */ - -#ifdef USE_ATARI_IO - -scsi_cmd: // D0: drive, D1.L: DMA bytes, D2: bytes cmd, A0: DMA buffer, A1: buffer bytes cmd - // return error code inside D0, and time speed test inside D1.L - - movem.l D2-D3/A0,-(SP) - moveq #0,D3 - st.b flock - bsr send_cmd_scsi - bmi .sr4 // time-out - move.w #0x89,0xFFFF8606 // Init-Command Register NCR5380 - move.w #0,0xFFFF8604 - move.w #0x8B,0xFFFF8606 // Target-Command Register - move.w #1,0xFFFF8604 - move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset - move.w 0xFFFF8604,D0 - move.w #0x8A,0xFFFF8606 // Mode Register - move.w #2,0xFFFF8604 // enable DMA - move.l A0,-(SP) - move.b 3(SP),0xFFFF860D - move.b 2(SP),0xFFFF860B - move.b 1(SP),0xFFFF8609 +.end_boot_drive_dos: // driver installed + move.w _bootdev,-(SP) + move.w #7,-(SP) // Getbpb + trap #13 addq.l #4,SP - move.w #0x190,0xFFFF8606 - bsr mfp_delay - move.w #0x90,0xFFFF8606 // DMA reading - bsr mfp_delay - move.l D1,D0 // num bytes DMA - and.w #0x1FF,D1 - lsr.l #8,D0 - lsr.l #1,D0 // / 512 - tst.w D1 - beq.s .sr3 - addq #1,D0 -.sr3: - move.w D0,0xFFFF8604 // sectors -.sr1: - btst #3,0xFFFF860F - bne.s .sr1 - move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset - move.w #0,0xFFFF8604 - move.w #0,0xFFFF8606 // read transfer -#ifdef COLDFIRE - bsr get_slice_timer -#else - bsr get_timer_c -#endif - move.l D0,D3 // speed test - bsr wait_end_cmd_scsi - bmi.s .sr4 // time-out - and #0xF,D1 - beq.s .sr2 - move.w #0x20,0xFFFF8606 -.sr2: -#ifdef COLDFIRE - bsr get_slice_timer -#else - bsr get_timer_c -#endif - sub.l D3,D0 - move.l D0,D3 // time speed test - bsr get_status_scsi - cpusha DC - and.l #0xFF,D0 // error code -.sr4: - move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset - move.w 0xFFFF8604,D1 - move.w #0x180,0xFFFF8606 - bsr mfp_delay - move.w #0x80,0xFFFF8606 // Data register - clr.w flock - move.l D3,D1 // time speed test tst.l D0 - movem.l (SP)+,D2-D3/A0 + bne .end_boot_drive_msdos + lea message92(PC),A0 // BPB invalid + bsr display_string + bsr wait_key + clr.w _bootdev +.end_boot_drive_msdos: + moveq #1,D0 rts -get_status_scsi: +search_empty_pun: - move.l D1,-(SP) - move.w #0x8B,0xFFFF8606 // Target-Command Register - move.w #3,0xFFFF8604 - move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset - move.w 0xFFFF8604,D0 - move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register - move.l _hz_200,D1 -.gs5: - move.w 0xFFFF8604,D0 // DMA state - btst #5,D0 - bne.s .gs2 - move.l _hz_200,D0 - sub.l D1,D0 - cmp.l #TIME_OUT_CMD,D0 - blt.s .gs5 - bra.s .gs6 -.gs2: - move.w #0x88,0xFFFF8606 // Data register - move.w 0xFFFF8604,D0 - and.l #0xFF,D0 - move.l D0,-(SP) - bsr attention_scsi - move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register - move.l _hz_200,D1 -.gs3: - move.w 0xFFFF8604,D0 // DMA state - btst #5,D0 - bne.s .gs4 - move.l _hz_200,D0 - sub.l D1,D0 - cmp.l #TIME_OUT_CMD,D0 // time-out 500 mS - blt.s .gs3 - addq.l #4,SP -.gs6: - moveq #-1,D0 - bra.s .gs1 -.gs4: - move.w #0x88,0xFFFF8606 // Data register - move.w 0xFFFF8604,D0 - bsr attention_scsi - move.l (SP)+,D0 -.gs1: - move.l (SP)+,D1 + move.l pun_ptr,D0 + beq.s .no_pun_ptr + move.l D0,A0 + moveq #2,D0 // drive C +.find_empty_pun: + tst.b pinfo_pun(A0,D0.l) + bmi.s .pun_free + addq.l #1,D0 + cmp.l #16,D0 + bcs.s .find_empty_pun +.no_pun_ptr: + moveq #-1,D0 // full +.pun_free: tst.l D0 rts - -send_cmd_scsi: // D0: drive, D2: bytes cmd, A1: buffer bytes cmd -// return D0 < 0 => time-out - - movem.l D1-D3/A1,-(SP) - move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register - move.l _hz_200,D1 -.cs1: - move.w 0xFFFF8604,D3 // DMA state - btst #6,D3 - beq.s .cs2 - move.l _hz_200,D3 - sub.l D1,D3 - cmp.l #TIME_OUT_CMD,D3 - blt.s .cs1 - bra .cs7 -.cs2: - move.w #0x8B,0xFFFF8606 // Target-Command Register - move.w #0,0xFFFF8604 - move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register - move.w #0,0xFFFF8604 - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #0x0C,0xFFFF8604 - moveq #0,D1 - and.w #7,D0 // SCSI drive - bset D0,D1 - move.w #0x88,0xFFFF8606 // Data register - move.w D1,0xFFFF8604 - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #5,0xFFFF8604 - move.w #0x8A,0xFFFF8606 // Mode Register - move.w 0xFFFF8604,D0 - and.b #0xFE,D0 // disable arbitration - move.w D0,0xFFFF8604 - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w 0xFFFF8604,D0 - and.w #0xF7,D0 - move.w D0,0xFFFF8604 - bsr mfp_delay - move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register - move.l _hz_200,D1 -.cs6: - move.w 0xFFFF8604,D0 // DMA state - btst #6,D0 - bne.s .cs3 - move.l _hz_200,D0 - sub.l D1,D0 - cmp.l #TIME_OUT_CMD,D0 - blt.s .cs6 -.cs7: - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #0,0xFFFF8604 - moveq #-1,D0 // time-out - bra .cs5 -.cs3: - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #0,0xFFFF8604 - move.w #0x8B,0xFFFF8606 // Target-Command Register - move.w #2,0xFFFF8604 - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #1,0xFFFF8604 - subq.w #1,D2 // bytes cmd counter - bmi.s .cs8 -.cs4: - move.l #TIME_OUT_CMD,D0 - bsr wait_hdc - bmi.s .cs5 // time-out - moveq #0,D0 - move.b (A1)+,D0 // byte cmd - move.w #0x88,0xFFFF8606 // Data register - move.w D0,0xFFFF8604 - bsr attention_scsi - dbf D2,.cs4 -.cs8: - moveq #0,D0 -.cs5: - movem.l (SP)+,D1-D3/A1 - rts - -attention_scsi: - - move.w D0,-(SP) - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w 0xFFFF8604,D0 - or.b #0x11,D0 - move.w D0,0xFFFF8604 - and.b #0xEF,D0 - move.w D0,0xFFFF8604 - move.w (SP)+,D0 - rts - -mfp_delay: - - tst.b 0xFFFFFA01 - tst.b 0xFFFFFA01 - tst.b 0xFFFFFA01 - tst.b 0xFFFFFA01 - rts - -#endif /* USE_ATARI_IO */ - -delay_hz_200: // inside D0.L - - movem.l D1/D2,-(SP) - move.l _hz_200,D1 -.dh1: move.l _hz_200,D2 - sub.l D1,D2 - cmp.l D0,D2 - blt.s .dh1 - movem.l (SP)+,D1/D2 - rts - -#ifdef USE_ATARI_IO - -wait_hdc: // time-out inside D0.L, return D0 < 0 => time-out - - movem.l D1/D2,-(SP) - move.l D0,D2 // time-out - move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register - move.l _hz_200,D1 -.wh1: - move.w 0xFFFF8604,D0 - btst #5,D0 - bne.s .wh2 - move.l _hz_200,D0 - sub.l D1,D0 - cmp.l D2,D0 - blt.s .wh1 - moveq #-1,D0 // time-out - bra.s .wh3 -.wh2: - moveq #0,D0 -.wh3: - movem.l (SP)+,D1/D2 - rts -wait_end_cmd_scsi: // return D0 < 0 => time-out +search_bootable_pun: - move.l #TIME_OUT_4S,D0 - cmp #6,D2 // bytes cmd - beq.s .wec3 - move.l #TIME_OUT_10S,D0 -.wec3: - move.l _hz_200,D1 -.wec5: - btst #5,0xFFFFFA01 // GPIP MFP 68901 - beq .wec2 - move.l _hz_200,D2 - sub.l D1,D2 - cmp.l D0,D2 - blt.s .wec5 -.wec4: - btst #3,0xFFFF860F - bne.s .wec4 - move.w #0x190,0xFFFF8606 - bsr mfp_delay - move.w #0x90,0xFFFF8606 // DMA reading - bsr mfp_delay - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #0x80,0xFFFF8604 - move.l #TIME_OUT_CMD,D0 - bsr delay_hz_200 // reset - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #0,0xFFFF8604 - move.l #200,D0 // 1 S - bsr delay_hz_200 - moveq #-1,D0 // error - bra.s .wec1 -.wec2: - move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset - move.w 0xFFFF8604,D0 - move.w #0x8A,0xFFFF8606 // Mode Register - move.w #0,0xFFFF8604 // disable DMA - move.w #0x89,0xFFFF8606 // Init-Command Register - move.w #0,0xFFFF8604 - moveq #0,D0 // OK -.wec1: + move.l A1,-(SP) + move.l pun_ptr,D0 + beq.s .no_pun_ptr2 + move.l D0,A0 + moveq #2,D0 // drive C + lea pinfo_flags(A0),A1 +.find_bootable_pun: + tst.b pinfo_pun(A0,D0.l) + bmi.s .next_pun + btst #0,1(A1,D0.l*2) // bootable + bne.s .pun_found +.next_pun: + addq.l #1,D0 + cmp.l #16,D0 + bcs.s .find_bootable_pun +.no_pun_ptr2: + moveq #-1,D0 // error +.pun_found: + move.l (SP)+,A1 + tst.l D0 rts + +check_root: -#endif /* USE_ATARI_IO */ - -ide_cmd: // D0.L: bytes, A0: IDE buffer, A1: cmd buffer - // return error code inside D0, and time speed test inside D1.L - -#ifndef USE_ATARI_IO +#ifdef COLDFIRE lea -16(SP),SP - movem.l D2-D3/A0-A1,(SP) -#if 0 // #ifdef DEBUG -#ifndef MCF5445X -// bsr debug_ide -#endif - move.l D0,-(SP) - move.l A0,D0 - bsr debug_hex_long - moveq #0x20,D0 + movem.l D0-D2/A0,(SP) + move.l #255,D0 + moveq #0,D1 +.loop_checksum: + moveq #0,D2 + move.w (A0)+,D2 + add.l D2,D1 + subq.l #1,D0 + bpl.s .loop_checksum + and.l #0xFFFF,D1 +#ifdef DEBUG + moveq #13,D0 bsr debug_display_char - moveq #0,D2 -.ir00: - move.b (A1,D2),D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - add.l #1,D2 - cmp.l #7,D2 - bcs.s .ir00 + moveq #10,D0 + bsr debug_display_char + move.w D1,D0 + bsr debug_hex_word moveq #13,D0 bsr debug_display_char moveq #10,D0 bsr debug_display_char - move.l (SP)+,D0 -#endif /* DEBUG */ - moveq #-1,D2 - move.b D2,flock - move.l D0,D2 // 0: non-data -#ifdef MCF5445X - move.b 1(A1),ATA_DEVICE_HEAD // C/D/H - move.b 2(A1),ATA_CYLINDER_HIGH // cyl high - move.b 3(A1),ATA_CYLINDER_LOW // cyl low - move.b 4(A1),ATA_SECTOR_NUM // sector num - move.b 5(A1),D3 - move.b D3,ATA_SECTOR_COUNT // sector count -#else /* MCF548X */ - move.b fire_engine_hw_rev,D3 - and.l #0xF0,D3 - cmp.l #0xA0,D3 - beq.s .ide_cpld_ok - clr.w flock - moveq #0,D1 - moveq #-1,D0 // error - bra .ir0 -.ide_cpld_ok: - // word access are used for writing register - // else byte writing on odd address register not works - // byte writing on even address write also on odd address register - // reading works in byte or word access - // => CPLD bug ? - move.w 2(A1),D3 // sector high / sector low - move.w D3,ATA_CYLINDER_HIGH - move.w 4(A1),D3 // sector num / sector count - move.w D3,ATA_SECTOR_NUM -#endif /* MCF5445X */ -#else /* USE_ATARI_IO */ -#ifdef COLDFIRE - lea -16(SP),SP - movem.l D2-D3/A0-A1,(SP) -#else - movem.l D2-D3/A0-A1,-(SP) -#endif - st.b flock - move.l D0,D2 // 0: non-data - move.b 1(A1),ATA_DEVICE_HEAD // C/D/H - move.b 2(A1),ATA_CYLINDER_HIGH // cyl high - move.b 3(A1),ATA_CYLINDER_LOW // cyl low - move.b 4(A1),ATA_SECTOR_NUM // sector num - move.b 5(A1),D3 - move.b D3,ATA_SECTOR_COUNT // sector count -#endif /* USE_ATARI_IO */ - moveq #0,D1 // sector counter - move.b #0xA1,D3 // identify packet device - cmp.b (A1),D3 - beq.s .ir7 - move.b #0xEC,D3 // identify device - cmp.b (A1),D3 - beq.s .ir7 - tst.l D2 - beq.s .ir7 // non-data - move.w D0,D1 - and.l #0x1FF,D1 - lsr.l #8,D0 // bytes - lsr.l #1,D0 // / 512 - tst.l D1 - beq.s .ir6 - addq.l #1,D0 -.ir6: - moveq #0,D1 - move.b D0,D1 - beq .ir5 - subq.l #1,D1 // sector counter -.ir7: -#ifndef USE_ATARI_IO -#ifdef MCF5445X - move.b 6(A1),D0 // features (error when read) - move.b D0,ATA_ERROR_REGISTER - moveq #2,D0 - move.b D0,ATA_CONTROL_DEVICE // control device, disable interrupt - move.w (A1),D0 // command, C/D/H - move.w D0,ATA_STATUS_COMMAND - bsr get_dtim_timer - move.l D0,D3 // speed test - moveq #0,D0 - move.b (A1),D0 - cmp.l #0x30,D0 // write sector(s) -#else /* MCF548X */ - move.b 6(A1),D0 // features (error when read) -// move.b D0,ATA_ERROR_REGISTER - asl.l #8,D0 - move.w D0,ATA_ERROR_REGISTER - moveq #2,D0 -// move.b D0,ATA_CONTROL_DEVICE // control device, disable interrupt - move.w D0,ATA_CONTROL_DEVICE-1 // control device, disable interrupt - move.w (A1),D0 // command, C/D/H - move.w D0,ATA_STATUS_COMMAND - bsr get_slice_timer - move.l D0,D3 // speed test - moveq #0,D0 - move.b (A1),D0 - cmp.l #0x30,D0 // write sector(s) -#endif /* MCF5445X */ -#else /* USE_ATARI_IO */ - move.b 6(A1),ATA_ERROR_REGISTER // features (error when read) - clr.b ATA_CONTROL_DEVICE // control device, INTRQ on MFP IO5 - move.b (A1),ATA_STATUS_COMMAND // command -#ifdef COLDFIRE - bsr get_slice_timer -#else - bsr get_timer_c #endif - move.l D0,D3 // speed test - moveq #0x30,D0 // write sector(s) - cmp.b (A1),D0 -#endif /* USE_ATARI_IO */ - bne .ir10 // read -.ir4: // write - move.b ATA_STATUS_COMMAND,D0 // state - btst #3,D0 // DRQ - beq.s .ir4 -#ifndef USE_ATARI_IO -.ir8: // write - lea ATA_DATA,A1 // IDE buffer - moveq #31,D0 // 512 bytes -.ir11: - move.w (A0)+,(A1) - move.w (A0)+,(A1) - move.w (A0)+,(A1) - move.w (A0)+,(A1) - move.w (A0)+,(A1) - move.w (A0)+,(A1) - move.w (A0)+,(A1) - move.w (A0)+,(A1) - subq.l #1,D0 - bpl.s .ir11 - move.l #TIME_OUT_CMD,D0 - bsr wait_end_cmd_ide - bmi .ir1 // time-out - move.b ATA_STATUS_COMMAND,D0 // state - and.l #9,D0 // DRQ & ERR - btst #3,D0 // DRQ - beq .ir1 // error - subq.l #1,D1 - bpl.s .ir8 - bra.s .ir12 -.ir10: // read - move.l #TIME_OUT_CMD,D0 - bsr wait_end_cmd_ide - bmi.s .ir1 // time-out - tst.l D2 - beq.s .ir9 // no data - move.b ATA_STATUS_COMMAND,D0 // state - and.l #9,D0 // DRQ & ERR - btst #3,D0 // DRQ - beq.s .ir1 // error - lea ATA_DATA,A1 // IDE buffer - moveq #31,D0 // 512 bytes -.ir3: - move.w (A1),(A0)+ - move.w (A1),(A0)+ - move.w (A1),(A0)+ - move.w (A1),(A0)+ - move.w (A1),(A0)+ - move.w (A1),(A0)+ - move.w (A1),(A0)+ - move.w (A1),(A0)+ - subq.l #1,D0 - bpl.s .ir3 - subq.l #1,D1 - bpl.s .ir10 -.ir12: -#ifdef MCF5445X - bsr get_dtim_timer - sub.l D0,D3 - neg.l D0 // time speed test -#else /* MCF548X */ - bsr get_slice_timer - sub.l D0,D3 - neg.l D0 // time speed test - move.l #SYSTEM_CLOCK,D0 - divu.l D0,D3 // uS -#endif /* MCF5445X */ -#else /* USE_ATARI_IO */ -.ir8: // write - lea ATA_DATA,A1 // IDE buffer - moveq #15,D0 // 512 bytes -.ir11: - move.l (A0)+,(A1) - move.l (A0)+,(A1) - move.l (A0)+,(A1) - move.l (A0)+,(A1) - move.l (A0)+,(A1) - move.l (A0)+,(A1) - move.l (A0)+,(A1) - move.l (A0)+,(A1) - dbf D0,.ir11 - move.l #TIME_OUT_CMD,D0 - bsr wait_end_cmd_ide - bmi .ir1 // time-out - moveq #9,D0 // DRQ & ERR - and.b ATA_STATUS_COMMAND,D0 // state - btst #3,D0 // DRQ - beq .ir1 // error - dbf D1,.ir8 - bra.s .ir12 -.ir10: // read - move.l #TIME_OUT_CMD,D0 - bsr wait_end_cmd_ide - bmi.s .ir1 // time-out - tst.l D2 - beq.s .ir9 // no data - moveq #9,D0 // DRQ & ERR - and.b ATA_STATUS_COMMAND,D0 // state - btst #3,D0 // DRQ - beq.s .ir1 // error - lea ATA_DATA,A1 // IDE buffer - moveq #15,D0 // 512 bytes -.ir3: - move.l (A1),(A0)+ - move.l (A1),(A0)+ - move.l (A1),(A0)+ - move.l (A1),(A0)+ - move.l (A1),(A0)+ - move.l (A1),(A0)+ - move.l (A1),(A0)+ - move.l (A1),(A0)+ - dbf D0,.ir3 - dbf D1,.ir10 -.ir12: -#ifdef COLDFIRE - bsr get_slice_timer + cmp.l #0x1234,D1 + movem.l (SP),D0-D2/A0 + lea 16(SP),SP #else - bsr get_timer_c + movem.l D0-D1/A0,-(SP) + move.w #255,D0 + moveq #0,D1 +.loop_checksum: + add.w (A0)+,D1 + dbf D0,.loop_checksum + cmp.w #0x1234,D1 + movem.l (SP)+,D0-D1/A0 +#endif /* COLDFIRE */ + rts + +exec_sys: // D0 drive, D0.H: flag swap bytes, D1.L: start of partition + +#if defined(USE_ATARI_IO) && !defined(COLDFIRE) +//#ifdef USE_ATARI_IO + movem.l D1-D7/A4,-(SP) + link A6,#-32 + move.l D0,D4 // drive & flag swap bytes + move.l D1,D6 // start of partition + move.w #3,-(SP) // TT ram if possible + move.l #-1,-(SP) // size + move.w #0x44,-(SP) // Mxalloc + trap #1 + addq.l #8,SP + move.l D0,D5 // greater block + move.l D0,-4(A6) + move.w #3,-(SP) // TT ram if possible + move.l D5,-(SP) // size + move.w #0x44,-(SP) // Mxalloc + trap #1 + addq.l #8,SP + tst.l D0 + beq .boot_error + move.l D0,A4 // buffer + move.l D0,-16(A6) + move.l _dskbufp,A0 // boot sector + moveq #0,D1 + move.b 0xC(A0),D1 // BPS * 256 + lsr.w #1,D1 // / 512 + move.l D1,-12(A6) // BPS / 512 + moveq #0,D2 + move.b 0x12(A0),D2 + asl.w #8,D2 + move.b 0x11(A0),D2 // NDIRS + move.w 0xE(A0),D3 // RES + ror.w #8,D3 + mulu D1,D3 // * (BPS / 512) + add.l D6,D3 + move.l D3,-8(A6) + move.w 0x16(A0),D6 // SPF + ror.w #8,D6 + mulu D1,D6 // * (BPS / 512) + moveq #0,D1 + move.b 0x10(A0),D1 // NFATS + mulu D1,D6 + add.l D3,D6 // + RES + start sector of partition + lsr.l #4,D2 // NDIRS / 32 + add.l D6,D2 +#ifdef DEBUG + lea debug14(PC),A0 + bsr display_string_single + move.l D6,D0 + bsr hex_long #endif - sub.l D3,D0 - move.l D0,D3 // time speed test + move.l D2,-20(A6) // end directory + move.l D6,D2 // 1st sector directory +.loop_read_dir: + move.l -16(A6),A0 // buffer Mxalloc + moveq #1,D1 // 1 sector + move.l D4,D0 // drive & flag swap bytes + jsr read_sectors // read directory + bmi .mfree_boot + move.l -16(A6),A0 // buffer Mxalloc + moveq #15,D1 +.next_entry_dir: + cmp.b #0x53,8(A0) // S + bne.s .bad_ext + cmp.b #0x59,9(A0) // Y + bne.s .bad_ext + cmp.b #0x53,10(A0) // S + beq.s .ext_ok +.bad_ext: + lea 32(A0),A0 + dbf D1,.next_entry_dir + addq.l #1,D2 + cmp.l -20(A6),D2 + bcs.s .loop_read_dir + bra .mfree_boot +.bad_file: + lea message93(PC),A0 // not a TOS binary + bsr display_string + move.l -16(A6),A0 // buffer Mxalloc + moveml -28(A6),D2 // restore loop_read_dir context + moveq #1,D1 // 1 sector + move.l D4,D0 // drive & flag swap bytes + jsr read_sectors // reload directory + bmi .mfree_boot + movem.l -32(A6),D1/D2/A0 // restore loop_read_dir context + bra.s .bad_ext +.ext_ok: + movem.l D1/D2/A0,-32(A6) // save loop_read_dir context + move.l A0,-(SP) + lea message91(PC),A0 // boot found + bsr display_string // display driver name + move.l (SP)+,A0 + moveq #10,D1 + moveq #0,D2 +.loop_name_driver: + cmp.w #8,D2 + bne.s .not_point + moveq #0x2E,D0 + bsr display_char +.not_point: + move.b (A0,D2),D0 + bsr display_char + addq.w #1,D2 + dbf D1,.loop_name_driver + move.l 28(A0),D5 // size file + ror.w #8,D5 + swap D5 + ror.w #8,D5 + add.l #0x1800,D5 // stack size + cmp.l -4(A6),D5 // size block Mxalloc + bhi .mfree_boot + move.l -16(A6),A4 // buffer Mxalloc + add.l -4(A6),A4 // size block Mxalloc + lea -0x8000(A4),A4 // top of the block + move.l -16(A6),A2 // buffer Mxalloc + move.w 26(A0),D6 // 1st cluster + ror.w #8,D6 + moveq #-1,D3 +.loop_read_file: + move.l _dskbufp,A0 // boot sector + moveq #0,D1 + move.b 0xD(A0),D1 // SPC + mulu -10(A6),D1 // BPS / 512 = sec count + move.w D6,D2 // cluster + subq.w #2,D2 + mulu D1,D2 // * sec count * SPC + add.l -20(A6),D2 // + end directory = start sector + move.l A2,A0 // buffer file + move.l D4,D0 // drive & flag swap bytes + jsr read_sectors + bmi .mfree_boot + asl.l #8,D1 // * 512 + add.l D1,D1 // bytes + add.l D1,A2 // + file offset + move.w D6,D2 + ext.l D2 + lsr.l #8,D2 + add.l -8(A6),D2 // + RES + start sector of partition + cmp.l D3,D2 // start sector + beq.s .not_reload_fat + move.l D2,D3 + move.l A4,A0 // buffer FAT + moveq #1,D1 // sec count + move.l D4,D0 // drive & flag swap bytes + jsr read_sectors + bmi .mfree_boot +.not_reload_fat: + and.w #255,D6 + add.w D6,D6 + move.w (A4,D6),D6 // cluster from FAT entry + ror.w #8,D6 + bpl.s .loop_read_file + move.l -16(A6),A2 // buffer Mxalloc + move.l A2,A0 // buffer file + cmp.w #0x601A,(A0)+ // binary test + bne .bad_file + lea 0x1C(A2),A1 // + header size + add.l (A0)+,A1 // + text segment + add.l (A0)+,A1 // + data segment + add.l 4(A0),A1 // + bss segment + tst.l (A1) + beq.s .end_reloc + lea 0x1C(A2),A0 // + header size + move.l A0,D1 + moveq #0,D0 + add.l (A1)+,A0 +.loop_reloc: + add.l D1,(A0) +.loop_reloc_2: + move.b (A1)+,D0 + beq.s .end_reloc + cmp.b #1,D0 + bne.s .next_reloc + lea 254(A0),A0 + bra.s .loop_reloc_2 +.next_reloc: + add.w D0,A0 + bra.s .loop_reloc +.end_reloc: + cpusha BC // flush + move.l -4(A6),D0 // size block Mxalloc + unlk A6 + movem.l (SP)+,D1-D7/A4 + jmp 0x20(A2) // start file after the 1st BRA +.mfree_boot: + move.l -16(A6),-(SP) // buffer Mxalloc + move.w #0x49,-(SP) // Mfree + trap #1 + addq.l #6,SP +.boot_error: + unlk A6 + movem.l (SP)+,D1-D7/A4 #endif /* USE_ATARI_IO */ -.ir5: - moveq #0,D0 - bra.s .ir1 -.ir9: - btst #0,ATA_STATUS_COMMAND // state, ERR - beq.s .ir5 - move.b ATA_ERROR_REGISTER,D0 // error register - and.l #0x6E,D0 // WP, MC, MCR, ABRT, NM - bra.s .ir1 -.ir2: - moveq #-1,D0 // error, time-out -.ir1: -#ifdef COLDFIRE -#ifdef MCF5445X - moveq #2,D1 - move.b D1,ATA_CONTROL_DEVICE // control device, disable interrupt -#else /* MCF548X */ - moveq #2,D1 -// move.b D1,ATA_CONTROL_DEVICE // control device, disable interrupt - move.w D1,ATA_CONTROL_DEVICE-1 // control device, disable interrupt -#endif /* MCF5445X */ -#else /* ATARI */ - move.b #2,ATA_CONTROL_DEVICE // control device, no INTRQ on MFP IO5 -#endif /* COLDFIRE */ - clr.w flock - move.l D3,D1 // time speed test -#ifndef USE_ATARI_IO -#ifdef DEBUG -// bsr debug_ide -#if 1 - tst.l D0 - beq.s .ir0 - move.l D0,-(SP) - lea debug126(PC),A0 - bsr debug_display_string - move.l (SP),D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - move.b ATA_STATUS_COMMAND,D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - move.b ATA_ERROR_REGISTER,D0 // error register - bsr debug_hex_byte - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif -#endif -#endif -.ir0: -#ifdef COLDFIRE - movem.l (SP),D2-D3/A0-A1 - lea 16(SP),SP -#else - movem.l (SP)+,D2-D3/A0-A1 -#endif - tst.l D0 - rts - -#ifndef USE_ATARI_IO -#ifndef MCF5445X -#ifdef DEBUG - -debug_ide: - - move.l A0,-(SP) - move.l A1,-(SP) - move.l D0,-(SP) - move.l D1,-(SP) - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - moveq #15,D1 - lea COMPACTFLASH_BASE+0x1800,A1 -.loop: - move.b (A1)+,D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - subq.l #1,D1 - bpl.s .loop - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D1 - move.l (SP)+,D0 - move.l (SP)+,A1 - move.l (SP)+,A0 rts -#endif /* DEBUG */ -#endif /* MCF5445X */ -#endif /* COLDFIRE */ - -wait_end_cmd_ide: // time-out inside D0.L, return D0 < 0 => time-out - move.l D1,-(SP) - move.l D2,-(SP) - move.l _hz_200,D1 -.weci1: -#ifndef USE_ATARI_IO - tst.b ATA_STATUS_COMMAND // busy bit - bpl.s .weci2 -#else - btst #5,0xFFFFFA01 // GPIP MFP 68901 - beq.s .weci2 -#endif - move.l _hz_200,D2 - sub.l D1,D2 - cmp.l D0,D2 - blt.s .weci1 - moveq #-1,D0 // time-out - bra.s .weci3 -.weci2: - moveq #0,D0 -.weci3: - move.l (SP)+,D2 - move.l (SP)+,D1 - rts - common_menu: movem.l D1-A5,-(SP) @@ -8024,7 +6654,6 @@ common_menu: dbf D1,.menu_cursor_up_loop moveq #13,D0 bsr display_char - lea tab_os(PC),A0 move.w D3,D4 // index bra .display_common_menu_again .end_common_menu: @@ -8033,13 +6662,17 @@ common_menu: beq.s .menu_no_change moveq #0,D0 .menu_no_change: - move.w D4,D0 + move.w D4,D0 // new selected index tst.l D0 movem.l (SP)+,D1-A5 rts menu_boot: +#if defined(COLDFIRE) && !defined(MCF547X) + bsr wait_key +#endif +#ifndef COLDFIRE link A6,#-12 move.l _sysbase,A0 // header ROM move.l 0x24(A0),A0 // kbshift @@ -8226,7 +6859,7 @@ menu_boot: #else move.w -12(A6),D0 // bootpref cmp.w #0x80,D0 // TOS - beq.s .normal_boot + beq .normal_boot lea magxboot,A1 cmp.w #8,D0 // MagiC beq.s .call_boot @@ -8235,6 +6868,33 @@ menu_boot: lea ataboot,A1 #endif .call_boot: + moveq #0,D4 // boot on IDE master + move.l A1,-(SP) + clr.l -(SP) + move.l #CT60_BOOT_ORDER,-(SP) + move.w #CT60_MODE_READ,-(SP) + move.w #rw_parameter,-(SP) + trap #14 + lea 12(SP),SP + move.l (SP)+,A1 + tst.l D0 + bmi.s .err_boot_order + // 0: New boot SCSI0-7 -> IDE0-1 + // 1: New boot IDE0-1 -> SCSI0-7 + // 2: New boot SCSI7-0 -> IDE1-0 + // 3: New boot IDE1-0 -> SCSI7-0 + // 4: Old boot SCSI0-7 -> IDE0-1 + // 5: Old boot IDE0-1 -> SCSI0-7 + // 6; Old boot SCSI7-0 -> IDE1-0 + // 7: Old boot IDE1-0 -> SCSI7-0 + btst #1,D0 + sne.b D4 + ext.w D4 + ext.l D4 // boot on IDE slave +.err_boot_order: + move.l #0x5F504349,D0 // _PCI cookie + bsr get_cookie + move.l D0,D3 move.l #0x5F465245,D0 // _FRE cookie, external clock bsr get_cookie move.l D0,D2 @@ -8243,11 +6903,10 @@ menu_boot: move.l D0,D1 move.l #0x5F465055,D0 // _FPU cookie bsr get_cookie - add.l #FLASH_ADR+0x80000,A1 - sub.l #_ct60tos_half_flash,A1 jsr (A1) .normal_boot: unlk A6 +#endif /* COLDFIRE */ tst.w _cmdload beq.s .no_command lea message95(PC),A0 // start AUTO folder @@ -8263,12 +6922,24 @@ menu_boot: lea message95(PC),A0 // start AUTO folder bsr display_string bsr auto_exec + move.l #0x5F504349,D0 // cookie _PCI + bsr get_cookie + move.l A0,D0 + beq.s .no_pci_drv + bsr test_pci_drivers + bne.s .no_pci_drv + jsr 70(A0) // drivers PCI in flash, init after auto folder +.no_pci_drv: move.l #0xE00000,_sysbase +#ifdef COLDFIRE + lea env,A0 +#else lea 0xE00836,A0 // PATH= ... +#endif lea 0x840,A1 move.l A1,A2 .loop_copy_env: - cmp.b #0x23,(A0) + cmp.b #0x23,(A0) // # bne.s .no_drive_letter move.l A1,A2 .no_drive_letter: @@ -8426,13 +7097,14 @@ auto_exec_prg: #ifdef AUTO_SUBROUTINE movem.l D0-A6,-(SP) #else +#define AUTO_STACK 4096 // was 256 clr.l -(SP) move.w #0x20,-(SP) // Super trap #1 addq.l #6,SP move.l 4(SP),A6 // basepage - lea 256(A6),SP - move.l #256,-(SP) // size + lea AUTO_STACK(A6),SP + move.l #AUTO_STACK,-(SP) // size pea (A6) // old stack clr.w -(SP) // dummy move.w #0x4A,-(SP) // Mshrink @@ -8525,13 +7197,82 @@ auto_exec_prg: move.w #2,-(SP) // Cconout trap #1 addq.l #8,SP - pea null(PC) // env - pea null(PC) // command - pea 0xB1C // auto name - clr.w -(SP) // load'n go - move.w #0x4B,-(SP) // Pexec + lea 0,A2 // cookie pointer + lea 0xB0E,A0 // name from dta buffer + cmp.l #0x53504447,(A0) // SPDG + bne.s .not_speedo + cmp.l #0x444F532E,4(A0) // DOS. + bne.s .not_speedo + cmp.l #0x50524700,8(A0) // PRG + bne.s .not_speedo + clr.w -(SP) // caches off + move.w #cache,-(SP) + trap #14 + addq.l #4,SP +.not_speedo: +#if 0 // #ifdef COLDFIRE + cmp.l #0x4E564449,(A0) // NVDI + bne.s .not_nvdi + cmp.l #0x2E505247,4(A0) // .PRG + bne.s .not_nvdi + move.l #0x5F435055,D0 // _CPU cookie + bsr get_cookie + move.l A0,D2 + beq.s .not_nvdi +#if 1 + moveq #0,D0 // 68000 for mulu/s.l dx,dy:dz && divu/s.l dx,dy:dz +#else + clr.w D0 + swap D0 + moveq #6,D1 + lea message127(PC),A0 + lea tab_vdo_cookie(PC),A1 + bsr common_menu + swap D0 + clr.w D0 +#endif + move.l D2,A2 + move.l 4(A2),D2 // old value + move.l D0,4(A2) // value + clr.w -(SP) // caches off + move.w #cache,-(SP) + trap #14 + addq.l #4,SP +.not_nvdi: +#endif + pea null(PC) // env + pea null(PC) // command + pea 0xB1C // auto name + clr.w -(SP) // load'n go + move.w #0x4B,-(SP) // Pexec trap #1 lea 16(SP),SP + lea 0xB0E,A0 // name from dta buffer + cmp.l #0x53504447,(A0) // SPDG + bne.s .not_speedo2 + cmp.l #0x444F532E,4(A0) // DOS. + bne.s .not_speedo2 + cmp.l #0x50524700,8(A0) // PRG + bne.s .not_speedo2 + move.l D0,-(SP) + move.w #1,-(SP) // caches on + move.w #cache,-(SP) + trap #14 + addq.l #4,SP + move.l (SP)+,D0 +.not_speedo2: +#if 0 // #ifdef COLDFIRE + move.l A2,D1 + beq.s .no_cookie_restore + move.l D2,4(A2) + move.l D0,-(SP) + move.w #1,-(SP) // caches on + move.w #cache,-(SP) + trap #14 + addq.l #4,SP + move.l (SP)+,D0 +.no_cookie_restore: +#endif tst.l D0 bpl.s .pexec_ok cmp.l #-66,D0 @@ -8566,44 +7307,6 @@ auto_exec_prg: #endif rts -init_flash_parameters: - - moveq #14,D7 -.loop_init_params: - move.l #-1,-(SP) - move.l D7,-(SP) - move.w #CT60_MODE_WRITE,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP - cmp.l #-1,D0 - dblt D7,.loop_init_params - jmp 0xE0398C // reset - -fix_bug_nvdi: - - move.l _v_bas_ad,D0 - cmp.l #0x01000000,D0 - bcc.s .normal_v_opnwk - movec.l CACR,D0 - move.l D0,-(SP) - jsr 0xE0085A // caches off - moveq #3,D0 - jsr 0xE34348 // v_opnwk -#ifdef COLDFIRE - move.l #CACHE_ENABLE_MODE,D0 - cmp.l (SP)+,D0 -#else - cmp.l #0xA0808000,(SP)+ -#endif - bne.s .no_caches - jsr 0xE250C8 // caches on -.no_caches: - rts -.normal_v_opnwk: - moveq #3,D0 - jmp 0xE34348 // v_opnwk - display_device_type: // type inside D0 movem.l D0-D3/A0,-(SP) @@ -8638,6 +7341,13 @@ display_device_type: // type inside D0 bne.s .device_type_found movem.l (SP)+,D0-D3/A0 rts + +init_ram_test: + + move.l phystop,D0 + and.l #0xFFFE0000,D0 + move.l D0,0x183E + rts display_ram_test: @@ -8718,6 +7428,7 @@ conv_ascii_value: // A0:target ascii, D0.L:value, D1:len .dv2: rts +#if 0 display_xbra: movem.l D0/A0/A1,-(SP) @@ -8743,25 +7454,10 @@ display_xbra: unlk A6 movem.l (SP)+,D0/A0/A1 rts +#endif #ifdef COLDFIRE -#ifdef MCF5445X - -get_dtim_timer: - - move.l MCF_DTIM_DTCN1,D0 // uS - rts - -#else /* MCF548X */ - -get_slice_timer: - - move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK - rts - -#endif /* MCF5445X */ - display_mb_by_sec_disk: // D0: total time lea -12(SP),SP @@ -8787,24 +7483,6 @@ display_mb_by_sec_disk: // D0: total time #else /* ATARI */ -get_timer_c: - - move.l D1,-(SP) - move.w SR,-(SP) - or.w #0x700,SR // no interrupts - move.l _hz_200,D0 - asl.l #8,D0 - moveq #0,D1 - move.b 0xFFFFFA23,D1 // TCDR timer C MFP - subq.b #1,D1 // 0-191 - asl.l #8,D1 // * 256 - divu #192,D1 // 0-255 - not.b D1 - move.b D1,D0 - move.w (SP)+,SR - move.l (SP)+,D1 - rts - display_mb_by_sec_disk: // D0: total time movem.l D0-D1/A0,-(SP) @@ -8898,6 +7576,75 @@ display_latency: #endif /* COLDFIRE */ +display_version: + + move.b (A0)+,D0 + and.l #0xF,D0 + or.l #0x30,D0 + bsr display_char + moveq #0x2E,D0 // . + bsr display_char + move.b (A0),D0 + and.l #0xF0,D0 + lsr.l #4,D0 + or.l #0x30,D0 + bsr display_char + move.b (A0),D0 + and.l #0xF,D0 + or.l #0x30,D0 + bsr display_char + rts + +display_date: + + move.l D1,-(SP) + move.l A1,-(SP) + link A6,#-18 + move.l A0,A1 + clr -2(A6) + lea -18(A6),A0 + moveq #0,D0 + move.w (A1),D0 // day + moveq #2,D1 + bsr conv_ascii_value + lea -15(A6),A0 + moveq #0,D0 + move.w 2(A1),D0 // month + moveq #2,D1 + bsr conv_ascii_value + lea -12(A6),A0 + moveq #0,D0 + move.w 4(A1),D0 // year + moveq #4,D1 + bsr conv_ascii_value + lea -7(A6),A0 + moveq #0,D0 + move.w 6(A1),D0 // hour + moveq #2,D1 + bsr conv_ascii_value + lea -4(A6),A0 + moveq #0,D0 + move.w 8(A1),D0 // mn + moveq #2,D1 + bsr conv_ascii_value + bset #4,-18(A6) + bset #4,-15(A6) + bset #4,-7(A6) + bset #4,-4(A6) + moveq #0x2F,D0 // / + move.b D0,-16(A6) + move.b D0,-13(A6) + moveq #0x20,D0 + move.b D0,-8(A6) + moveq #0x3A,D0 // : + move.b D0,-5(A6) + lea -18(A6),A0 + bsr display_string_single + unlk A6 + move.l (SP)+,A1 + move.l (SP)+,D1 + rts + display_string: movem.l D0/A0,-(SP) @@ -9029,10 +7776,18 @@ test_keyboard: trap #14 addq.l #2,SP move.l D0,D7 -#ifdef COLDFIRE +#if defined(COLDFIRE) && !defined(MCF547X) + beq.s .invalid_clock and.l #0x01FFFFE0,D0 cmp.l #0x00210000,D0 -// bne.s .not_january_1st_00h00 + bne.s .not_january_1st_00h00 +.invalid_clock: +#ifdef COLDFIRE +#ifdef DEBUG + lea debug132(PC),A0 + bsr debug_display_string +#endif +#endif lea ADDR_DATE,A0 moveq #0,D0 move.w 4(A0),D0 // year @@ -9068,7 +7823,7 @@ test_keyboard: trap #1 addq.l #4,SP .not_january_1st_00h00: -#else /* ATARI */ +#else /* ATARI - FIREBEE */ clr.l -(SP) move.l #CT60_SAVE_NVRAM_1,-(SP) move.w #CT60_MODE_READ,-(SP) @@ -9081,19 +7836,26 @@ test_keyboard: move.l D7,-(SP) // => Gettime jsr 0xE022CA // Settime IKBD addq.l #4,SP + moveq #5,D4 // retry counter +.rtc_bypass: jsr 0xE022A0 // Gettime IKBD tst.b 0x11C4 bpl.s .keyboard_answer .keyboard_error_2: + subq.l #1,D4 // retry counter + bgt.s .rtc_bypass lea message76(PC),A0 // keyboard failure bsr display_string +#if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE disabled interrupt else infinite 0x00 bytes received */ + moveq #-1,D0 + move.b D0,stop_mfp_ikbd +#endif bra .no_buffer // => rts .keyboard_answer: sub.l D7,D0 bmi.s .keyboard_error_2 cmp.l #1,D0 bhi.s .keyboard_error_2 -.rtc_bypass: #endif /* COLDFIRE */ clr.w -(SP) // STRAM move.l #0x2000,-(SP) // 8K @@ -9104,6 +7866,8 @@ test_keyboard: ble .no_buffer move.l D0,A5 // buffer move.l phystop,A4 // use internal statvec + moveq #5,D4 // retry counter +.retry_eiffel_test: move.l A5,pbuf_statvec(A4) move.l #0xCAFEFADE,flag_statvec(A4) move.b #0x12,-4(A6) // IKBD mouse off @@ -9120,11 +7884,19 @@ test_keyboard: move.l _hz_200,D0 sub.l D1,D0 cmp.l #20,D0 // time-out 100 mS - bge .keyboard_error + bge.s .keyboard_error_3 cmp.l pbuf_statvec(A4),A5 beq.s .wait_answer_16f + bra.s .keyboard_ok +.keyboard_error_3: + subq.l #1,D4 // retry counter + bgt.s .retry_eiffel_test + bra .keyboard_error +.keyboard_ok: lea message75(PC),A0 // keyboard OK bsr display_string + moveq #5,D4 // retry counter +.retry_eiffel_test_2: move.l A5,pbuf_statvec(A4) moveq #0,D6 // flag 16F move.b #0x21,-4(A6) // IKBD read memory @@ -9146,7 +7918,7 @@ test_keyboard: move.l _hz_200,D0 sub.l D1,D0 cmp.l #20,D0 // time-out 100 mS - bge .keyboard_error + bge .keyboard_error_4 cmp.l pbuf_statvec(A4),A5 beq.s .wait_answer_18f move.l A5,pbuf_statvec(A4) @@ -9173,7 +7945,7 @@ test_keyboard: move.l _hz_200,D0 sub.l D1,D0 cmp.l #20,D0 // time-out 100 mS - bge .keyboard_error + bge .keyboard_error_4 cmp.l pbuf_statvec(A4),A3 beq.s .wait_answer_keyb move.l pbuf_statvec(A4),A3 @@ -9197,6 +7969,10 @@ test_keyboard: addq.l #2,A0 dbf D1,.loop_find_name bra .end_test_keyboard +.keyboard_error_4: + subq.l #1,D4 // retry counter + bgt .retry_eiffel_test_2 + bra .keyboard_error .eiffel_found: // display eiffel version addq.l #1,A0 move.b (A0)+,D0 @@ -9233,8 +8009,8 @@ test_keyboard: trap #14 addq.l #8,SP bra.s .end_test_keyboard -.keyboard_error: - lea message76(PC),A0 // keyboard failure +.keyboard_error: + lea message76b(PC),A0 // keyboard failure bsr display_string .end_test_keyboard: move.b #0x08,-4(A6) // IKBD mouse on @@ -9258,10 +8034,21 @@ test_keyboard: add_sdram: movem.l D1-D7/A1-A5,-(SP) -#ifdef COLDFIRE move.l _v_bas_ad,D0 cmp.l #0x01000000,D0 +#ifdef COLDFIRE bcs.s .font_16x8 +#else + bcs.s .check_font // <> graphic card + // why cursor isn't at the good place ??? + moveq #0x1B,D0 + bsr display_char + moveq #0x48,D0 // ESC H cursor home + bsr display_char + lea xlf(PC),A0 + bsr display_string_single + bsr display_string_single +.check_font: #endif cmp.w #8,_v_cel_ht // font 8 x 8 bhi.s .font_16x8 @@ -9271,67 +8058,27 @@ add_sdram: lea message15(PC),A0 // boot version bsr display_string_single lea ADDR_VERSION,A0 - move.b (A0)+,D0 - and.l #0xF,D0 - or.l #0x30,D0 - bsr display_char - moveq #0x2E,D0 // . - bsr display_char - move.b (A0),D0 - and.l #0xF0,D0 - lsr.l #4,D0 - or.l #0x30,D0 - bsr display_char - move.b (A0),D0 - and.l #0xF,D0 - or.l #0x30,D0 - bsr display_char + bsr display_version lea message15a(PC),A0 // additionnal information about version (alpha, beta...) bsr display_string_single - lea ADDR_DATE,A1 - link A6,#-18 - clr -2(A6) - lea -18(A6),A0 - moveq #0,D0 - move.w (A1),D0 // day - moveq #2,D1 - bsr conv_ascii_value - lea -15(A6),A0 - moveq #0,D0 - move.w 2(A1),D0 // month - moveq #2,D1 - bsr conv_ascii_value - lea -12(A6),A0 - moveq #0,D0 - move.w 4(A1),D0 // year - moveq #4,D1 - bsr conv_ascii_value - lea -7(A6),A0 - moveq #0,D0 - move.w 6(A1),D0 // hour - moveq #2,D1 - bsr conv_ascii_value - lea -4(A6),A0 - moveq #0,D0 - move.w 8(A1),D0 // mn - moveq #2,D1 - bsr conv_ascii_value - bset #4,-18(A6) - bset #4,-15(A6) - bset #4,-7(A6) - bset #4,-4(A6) - moveq #0x2F,D0 // / - move.b D0,-16(A6) - move.b D0,-13(A6) - moveq #0x20,D0 - move.b D0,-8(A6) - moveq #0x3A,D0 // : - move.b D0,-5(A6) - lea -18(A6),A0 - bsr display_string_single - unlk A6 + lea ADDR_DATE,A0 + bsr display_date lea message15b(PC),A0 bsr display_string_single + bsr test_pci_drivers + bne.s .no_drivers + lea 100(A0),A1 + lea message7(PC),A0 // drivers version + bsr display_string_single + move.l A1,A0 + bsr display_version + moveq #0x20,D0 + bsr display_char + lea 2(A1),A0 + bsr display_date + lea crlf(PC),A0 + bsr display_string_single +.no_drivers: clr.l -(SP) move.l #CT60_BOOT_ORDER,-(SP) move.w #CT60_MODE_READ,-(SP) @@ -9422,7 +8169,6 @@ add_sdram: move.w D7,D6 clr.w D7 swap D7 - clr.w vblsem .init_sdram: lea -256(A4),A4 movem.l D0-D3/A0-A3,(A4) @@ -9438,10 +8184,9 @@ add_sdram: and.l #0xFFFF,D6 moveq #0x2E,D0 bsr display_char + moveq #0,D0 subq.l #1,D7 bpl.s .init_sdram - moveq #1,D0 - move.w D0,vblsem #else /* !COLDFIRE */ subq.l #1,D7 move.w D7,D6 @@ -9493,6 +8238,7 @@ add_sdram: dbf D6,.init_sdram moveq #0x2E,D0 bsr display_char + moveq #0,D0 dbf D7,.init_sdram #endif /* COLDFIRE */ move.l _hz_200,D1 @@ -9537,6 +8283,17 @@ add_sdram: #endif divu.l D1,D0 divu.l #500,D0 +#ifndef COLDFIRE + move.l phystop,A0 + cmp.l measure_clock(A0),D0 + bhi.s .fast_abe_sdr + movec.l CACR,D1 + cmp.l #0xA0808000,D1 + bne.s .fast_abe_sdr // no cache + move.l #ABE_SDR_7,D1 + or.l D1,hardware_type(A0) +.fast_abe_sdr: +#endif link A6,#-6 clr.w -2(A6) lea -6(A6),A0 @@ -9590,7 +8347,7 @@ add_sdram: .find_cookie: tst.l (A0) beq.s .cookie_free - addq.w #8,A0 + addq.l #8,A0 bra.s .find_cookie .cookie_free: move.l 4(A0),12(A0) // copy size @@ -9622,16 +8379,15 @@ add_sdram: bpl.s .no_error_pci_bios lea error13(PC),A0 bsr display_string - #ifdef COLDFIRE bra.s .no_pci_bios #endif - .no_error_pci_bios: move.l #0x5F504349,D0 // cookie _PCI bsr get_cookie move.l A0,D0 beq.s .no_pci_bios + clr.b 0xA82 // no memory test (boot delay null), not works (Mxalloc) bsr test_pci_drivers bne.s .no_pci_bios jsr 10(A0) // drivers PCI in flash, call after SDRAM added @@ -9647,7 +8403,7 @@ add_sdram: jsr 0xE00BD2 // cartridge #endif move.l hdv_boot,A0 - jsr (A0) + jsr (A0) // in a 1st time call hdv_init and test _nflops tst.w D0 bne.s .no_boot move.l _dskbufp,A0 @@ -9655,6 +8411,88 @@ add_sdram: .no_boot: movem.l (SP)+,D1-D7/A1-A5 rts + +#ifdef COLDFIRE + +bootload: // hdv_boot TOS404 0xE04F54 + +#ifdef DEBUG + move.l A0,-(SP) + lea debug134(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + move.l hdv_init,A0 + jsr (A0) // flopini => set _drvbits and _nflops + +#if 1 + move.l #1,D0 + move.l D0,_drvbits + moveq #1,D0 + move.w D0,_nflops +#endif + + tst.w _nflops + beq.s .bl1 +#ifdef DEBUG + move.l A0,-(SP) + lea debug131(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + move.w #1,-(SP) // count + clr.w -(SP) // face A + clr.w -(SP) // track 0 + move.w #1,-(SP) // sector 1 + clr.w -(SP) // drive A + clr.l -(SP) // filler + move.l _dskbufp,-(SP) + move.w #8,-(SP) // Floprd TOS404 0xE03DB4 + trap #15 + lea 20(SP),SP + ext.l D0 + bne.s .bl2 // error + move.l _dskbufp,A0 + bsr check_root + bne.s .bl3 // bad checksum +#ifdef DEBUG + move.l A0,-(SP) + lea debug138(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + moveq #0,D0 // OK + bra.s .bl4 +.bl2: +#ifdef DEBUG + move.l A0,-(SP) + lea debug137(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + moveq #2,D0 // no drive + bra.s .bl4 +.bl1: +#ifdef DEBUG + move.l A0,-(SP) + lea debug136(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + moveq #1,D0 // not loadable + bra.s .bl4 +.bl3: +#ifdef DEBUG + move.l A0,-(SP) + lea debug135(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + moveq #4,D0 // bootsector invalid +.bl4: + rts + +#endif /* COLDFIRE */ test_pci_drivers: @@ -9676,11 +8514,20 @@ test_pci_drivers: #ifndef COLDFIRE /* ATARI - CT60 - CTCM */ -ct60_configure_clock: // D0.L: frequency, D1: mode +ct60_configure_clock: // D0.L: frequency, D1.W: mode, D2.W: divider (user frequency) - movem.l D1-A0,-(SP) + movem.l D1-A1,-(SP) move.l D0,D6 // frequency move.w D1,D7 // mode + cmp.w #2,D2 // divider + bgt.s .ccc21 + moveq #2,D2 +.ccc21: + cmp.w #6,D2 // divider + blt.s .ccc20 + moveq #6,D2 +.ccc20: + move.w D2,A1 // divider moveq #ADR,D1 move.w #CT60_CLOCK_READ+DALLAS,D0 // Dallas DS1085 bsr ct60_rw_clock @@ -9745,12 +8592,8 @@ ct60_configure_clock: // D0.L: frequency, D1: mode bmi .ccc10 // error bsr tempo_20ms .ccc13: - // MUX : PDN0/1 = 0, SEL0 = 1, EN0 = 0, 0M = 1, 1M = 0, DIV1 = 1 - move.w #0x1240,D2 // mux - cmp.l #51000,D6 // frequency - bcs.s .ccc17 - or.w #0x80,D2 // 1M = 1 => /2 -.ccc17: + // MUX : PDN0/1 = 0, SEL0 = 1, EN0 = 0, 0M = 1, 1M = 0, DIV1 = 0 + move.w #0x1200,D2 // mux moveq #MUXWORD,D1 move.w #CT60_CLOCK_WRITE_RAM+DALLAS,D0 bsr ct60_rw_clock @@ -9765,6 +8608,17 @@ ct60_configure_clock: // D0.L: frequency, D1: mode moveq #OFFSET,D1 move.w #CT60_CLOCK_WRITE_RAM+DALLAS,D0 bsr ct60_rw_clock + bmi .ccc10 // error + move.w A1,D2 // divider + cmp.l #66000,D6 // frequency + bhi.s .ccc19 + moveq #2,D2 // divider +.ccc19: + subq.w #2,D2 + asl.w #6,D2 + moveq #DIVWORD,D1 + move.w #CT60_CLOCK_WRITE_RAM+DALLAS,D0 + bsr ct60_rw_clock bmi .ccc10 // error cmp.w #CT60_CLOCK_WRITE_EEPROM,D7 // mode bne.s .ccc12 @@ -9830,23 +8684,38 @@ ct60_configure_clock: // D0.L: frequency, D1: mode bsr ct60_rw_clock bmi .ccc10 .ccc18: - move.w #0xDF,D2 - move.w #0x6F,D1 // clocks 5 & 6 DIV2CLK/2 - cmp.l #51000,D6 // frequency - bls.s .ccc9 + // CLKSRC2-0 + // 0: Reference input + // 1: DIV1CLK/DIV1N + // 2: DIV1CLK/2 + // 3: DIV1CLK/3 + // 4: DIV2CLK/DIV2N (/8) + // 5: DIV2CLK/2 + // 6: DIV2CLK/4 move.w #0xDE,D2 - move.w #0xDF,D1 // clocks 5 & 6 DIV1CLK/3 - cmp.l #77000,D6 // frequency - bls.s .ccc9 + move.w #0x4F,D1 // clocks 5 & 6 DIV1CLK/DIV1N + cmp.l #66000,D6 // frequency + bhi.s .ccc9 + move.w #3,A1 // /6 move.w #0xDF,D2 move.w #0xB7,D1 // clocks 5 & 6 DIV2CLK/4 .ccc9: - move.w D1,D6 - moveq #MATRIX2,D1 + move.w D1,D6 // MATRIX3 + swap D6 + move.w D2,D6 // MATRIX2 + move.w A1,D2 // DIV1N + add.w D2,D2 + moveq #DIV1N,D1 move.w D7,D0 bsr ct60_rw_clock bmi .ccc10 move.w D6,D2 + moveq #MATRIX2,D1 + move.w D7,D0 + bsr ct60_rw_clock + bmi .ccc10 + swap D6 + move.w D6,D2 moveq #MATRIX3,D1 move.w D7,D0 bsr ct60_rw_clock @@ -9912,7 +8781,7 @@ ct60_configure_clock: // D0.L: frequency, D1: mode .ccc1: moveq #CT60_CALC_CLOCK_ERROR,D0 .ccc10: - movem.l (SP)+,D1-A0 + movem.l (SP)+,D1-A1 rts ct60_rw_clock: // D0.W: mode (0: read, 1:write ram, 2: write eeprom, 3: reset) @@ -9954,12 +8823,12 @@ ct60_rw_clock: // D0.W: mode (0: read, 1:write ram, 2: write eepro cmp.w #OFFSET,D0 bne.s .rwc7 // word .rwc8: - bra read_i2c + jmp read_i2c .rwc7: link A6,#-2 lea -2(A6),A0 moveq #2,D1 // len - bsr read_seq_device_i2c + jsr read_seq_device_i2c bmi.s .rwc11 move.w (A0),D0 // data .rwc11: @@ -9977,13 +8846,13 @@ ct60_rw_clock: // D0.W: mode (0: read, 1:write ram, 2: write eepro bne.s .rwc9 // word .rwc10: move.w D2,D1 // data - bra write_i2c + jmp write_i2c .rwc9: link A6,#-2 lea -2(A6),A0 move.w D2,(A0) // data moveq #2,D1 // len - bsr write_seq_device_i2c + jsr write_seq_device_i2c unlk A6 rts .rwc6: @@ -9994,7 +8863,7 @@ ct60_rw_clock: // D0.W: mode (0: read, 1:write ram, 2: write eepro move.w #WRITEE2,D0 // address moveq #0,D1 // len lea 0,A0 // no data - bra write_seq_device_i2c + jmp write_seq_device_i2c .rwc1: moveq #CT60_READ_ERROR,D0 rts @@ -10004,203 +8873,15 @@ ct60_read_info_sdram: // A0: 128 bytes buffer, D0 return error moveq #SLAVE_SDRAM_ADDRESS,D0 swap D0 move.w #128,D1 - bra.s read_seq_device_i2c + jmp read_seq_device_i2c ct60_read_info_clock: // A0: 128 bytes buffer, D0 return error moveq #SLAVE_CY_SRAM_ADDRESS,D0 swap D0 move.w #128,D1 + jmp read_seq_device_i2c -read_seq_device_i2c: // D0.L: address, D0.H: device, D1: len (bytes), A0: 128 bytes buffer, D0 return error - - movem.l D1-D4/A0-A3,-(SP) - move.l D0,D4 - swap D4 // device - move.w D1,D3 // len (bytes) - move.l A0,A3 - move SR,-(SP) - or #0x700,SR // no interrupts - lea .ri1(PC),A0 - move.l 8,A1 // bus error - move.l A0,8 - move.l SP,A2 - lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) - tst.b _tbcr_mfp - bne.s .ri6 // timer B used - bclr #0,_imra_mfp - bclr #0,_iera_mfp - bclr #0,_ipra_mfp - bclr #0,_isra_mfp - lea _tbdr_mfp,A0 - move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) - move.b #3,_tbcr_mfp // 2.4576MHz/16 -.ri6: - bsr start_bit_i2c - move.l A1,8 - move.l A2,SP - move.w D4,D0 // device - bsr write_device_i2c - moveq #0,D0 // write address - bsr write_bit_i2c // r/w - bsr read_bit_i2c // ack - btst #0,D0 - bne .ri3 // no acknoledge - swap D4 // address - moveq #0,D0 - add.b D4,D4 - addx.b D0,D0 // address 1st bit - bsr write_bit_wait_slave_i2c - moveq #6,D2 // 8 bits -.ri4: - moveq #0,D0 - add.b D4,D4 - addx.b D0,D0 // address - bsr write_bit_i2c - dbf D2,.ri4 - bsr read_bit_i2c // ack - bne.s .ri3 // no acknoledge - bsr start_bit_wait_slave_i2c - swap D4 - move.w D4,D0 // device - bsr write_device_i2c - moveq #1,D0 // read data - bsr write_bit_i2c // r/w - bsr read_bit_i2c // ack - btst #0,D0 - bne.s .ri3 // no acknoledge - subq.w #1,D3 // len (bytes) -1 - bpl.s .ri8 - moveq #0,D3 -.ri8: - moveq #0,D1 // data - bsr read_bit_wait_slave_i2c // 1st bit - lsr.l #1,D0 // data - addx.w D1,D1 - moveq #6,D2 // 8 bits -.ri5: - bsr read_bit_i2c - lsr.l #1,D0 // data - addx.w D1,D1 - dbf D2,.ri5 - move.b D1,(A3)+ - tst D3 - seq.b D0 - and #1,D0 // ack master = 1 => no other byte - bsr write_bit_i2c - dbf D3,.ri8 - bsr stop_bit_i2c - moveq #0,D0 // OK - bra.s .ri2 -.ri3: - bsr stop_bit_i2c - moveq #CT60_READ_ERROR,D0 // error - bra.s .ri2 -.ri1: - moveq #CT60_READ_ERROR,D0 // bus error - move.l A1,8 - move.l A2,SP -.ri2: - lea _tbdr_mfp,A1 - cmp.l A0,A1 - bne.s .ri7 - clr.b _tbcr_mfp // timer B stopped -.ri7: - move.w (SP)+,SR - tst.l D0 - movem.l (SP)+,D1-D4/A0-A3 - rts - -write_seq_device_i2c: // D0.L: address, D0.H: device, D1: len (bytes), A0: buffer, D0 return error - - movem.l D1-D4/A0-A3,-(SP) - move.l D0,D4 - swap D4 // device - move.w D1,D3 // len (bytes) - move.l A0,A3 - move SR,-(SP) - or #0x700,SR // no interrupts - lea .wi1(PC),A0 - move.l 8,A1 // bus error - move.l A0,8 - move.l SP,A2 - lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) - tst.b _tbcr_mfp - bne.s .wi6 // timer B used - bclr #0,_imra_mfp - bclr #0,_iera_mfp - bclr #0,_ipra_mfp - bclr #0,_isra_mfp - lea _tbdr_mfp,A0 - move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) - move.b #3,_tbcr_mfp // 2.4576MHz/16 -.wi6: - bsr start_bit_i2c - move.l A1,8 - move.l A2,SP - move.w D4,D0 // device - bsr write_device_i2c - moveq #0,D0 // write address - bsr write_bit_i2c // r/w - bsr read_bit_i2c // ack - btst #0,D0 - bne .wi3 // no acknoledge - swap D4 // address - moveq #0,D0 - add.b D4,D4 - addx.b D0,D0 // address 1st bit - bsr write_bit_wait_slave_i2c - moveq #6,D2 // 8 bits -.wi4: - moveq #0,D0 - add.b D4,D4 - addx.b D0,D0 // address - bsr write_bit_i2c - dbf D2,.wi4 - bsr read_bit_i2c // ack - bne.s .wi3 // no acknoledge - subq.w #1,D3 // len (bytes) -1 - bmi.s .wi10 -.wi8: - move.b (A3)+,D1 // data - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // data 1st bit - bsr write_bit_wait_slave_i2c - moveq #6,D2 // 8 bits -.wi5: - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // data - bsr write_bit_i2c - dbf D2,.wi5 - bsr read_bit_i2c // ack - dbne D3,.wi8 - bne.s .wi3 // no acknoledge -.wi10: - bsr stop_bit_i2c - moveq #0,D0 // OK - bra.s .wi2 -.wi3: - bsr stop_bit_i2c -.wi9: - moveq #CT60_READ_ERROR,D0 // error - bra.s .wi2 -.wi1: - moveq #CT60_READ_ERROR,D0 // bus error - move.l A1,8 - move.l A2,SP -.wi2: - lea _tbdr_mfp,A1 - cmp.l A0,A1 - bne.s .wi7 - clr.b _tbcr_mfp // timer B stopped -.wi7: - move (SP)+,SR - tst.l D0 - movem.l (SP)+,D1-D4/A0-A3 - rts - ct60_configure_sdram: movem.l D1-D2/A0-A1,-(SP) @@ -10333,9 +9014,6 @@ ct60_configure_sdram: asl.l #2,D1 add.l D1,A0 // size on A19-A18 mdy2-1 clr.l (A0) // write config - move.l A0,D1 - swap D1 - move.b D1,memctrl+1 // save config A23-A16 tst.l D0 // return size 0-3 for 64MB-512MB .c1: movem.l (SP)+,D1-D2/A0-A1 @@ -10346,333 +9024,35 @@ read_i2c_sdram: // D0: address, D0 return data or error swap D0 move.w #SLAVE_SDRAM_ADDRESS,D0 swap D0 - bra.s read_i2c + jmp read_i2c read_i2c_cy_sram: // D0: address, D0 return data or error swap D0 move.w #SLAVE_CY_SRAM_ADDRESS,D0 swap D0 + jmp read_i2c -read_i2c: // D0.L: address, D0.H: device, D0 return data or error - - movem.l D1-D3/A0-A2,-(SP) - move.l D0,D3 // device - swap D3 - move SR,-(SP) - or #0x700,SR // no interrupts - lea .r1(PC),A0 - move.l 8,A1 // bus error - move.l A0,8 - move.l SP,A2 - lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) - tst.b _tbcr_mfp - bne.s .r6 // timer B used - bclr #0,_imra_mfp - bclr #0,_iera_mfp - bclr #0,_ipra_mfp - bclr #0,_isra_mfp - lea _tbdr_mfp,A0 - move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) - move.b #3,_tbcr_mfp // 2.4576MHz/16 -.r6: - move.w D0,D1 // address - bsr start_bit_i2c - move.l A1,8 - move.l A2,SP - move.w D3,D0 // device - bsr write_device_i2c - moveq #0,D0 // write address - bsr write_bit_i2c // r/w - bsr read_bit_i2c // ack - btst #0,D0 - bne .r3 // no acknoledge - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // address 1st bit - bsr write_bit_wait_slave_i2c - moveq #6,D2 // 8 bits -.r4: - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // address - bsr write_bit_i2c - dbf D2,.r4 - bsr read_bit_i2c // ack - bne.s .r3 // no acknoledge - bsr start_bit_wait_slave_i2c - move.w D3,D0 // device - bsr write_device_i2c - moveq #1,D0 // read data - bsr write_bit_i2c // r/w - bsr read_bit_i2c // ack - btst #0,D0 - bne.s .r3 // no acknoledge - moveq #0,D1 // data - bsr read_bit_wait_slave_i2c // 1st bit - lsr.l #1,D0 // data - addx.w D1,D1 - moveq #6,D2 // 8 bits -.r5: - bsr read_bit_i2c - lsr.l #1,D0 // data - addx.w D1,D1 - dbf D2,.r5 - moveq #1,D0 // ack master = 1 => no other byte - bsr write_bit_i2c - bsr stop_bit_i2c - moveq #0,D0 - move.w D1,D0 // 8 bits data - bra.s .r2 -.r3: - bsr stop_bit_i2c - moveq #CT60_READ_ERROR,D0 // error - bra.s .r2 -.r1: - moveq #CT60_READ_ERROR,D0 // bus error - move.l A1,8 - move.l A2,SP -.r2: - lea _tbdr_mfp,A1 - cmp.l A0,A1 - bne.s .r7 - clr.b _tbcr_mfp // timer B stopped -.r7: - move.w (SP)+,SR - tst.l D0 - movem.l (SP)+,D1-D3/A0-A2 - rts - write_i2c_sdram: // D0: address, D1:data, D0 return data or error swap D0 move.w #SLAVE_SDRAM_ADDRESS,D0 swap D0 - bra.s write_i2c + jmp write_i2c write_i2c_cy_eeprom: // D0: address, D1:data, D0 return data or error swap D0 move.w #SLAVE_CY_EEPROM_ADDRESS,D0 swap D0 - bra.s write_i2c + jmp write_i2c write_i2c_cy_sram: // D0: address, D1:data, D0 return data or error swap D0 move.w #SLAVE_CY_SRAM_ADDRESS,D0 swap D0 - -write_i2c: // D0.L: address, D0.H: device, D1:data, D0 return error - - movem.l D1-D4/A0-A2,-(SP) - move.l D0,D3 // device - swap D3 - move.w D1,D4 // data - move SR,-(SP) - or #0x700,SR // no interrupts - lea .w1(PC),A0 - move.l 8,A1 // bus error - move.l A0,8 - move.l SP,A2 - lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) - tst.b _tbcr_mfp - bne.s .w6 // timer B used - bclr #0,_imra_mfp - bclr #0,_iera_mfp - bclr #0,_ipra_mfp - bclr #0,_isra_mfp - lea _tbdr_mfp,A0 - move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) - move.b #3,_tbcr_mfp // 2.4576MHz/16 -.w6: - move.w D0,D1 // address - bsr start_bit_i2c - move.l A1,8 - move.l A2,SP - move.w D3,D0 // device - bsr write_device_i2c - moveq #0,D0 // write address - bsr write_bit_i2c // r/w - bsr read_bit_i2c // ack - btst #0,D0 - bne .w3 // no acknoledge - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // address 1st bit - bsr write_bit_wait_slave_i2c - moveq #6,D2 // 8 bits -.w4: - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // address - bsr write_bit_i2c - dbf D2,.w4 - bsr read_bit_i2c // ack - bne.s .w3 // no acknoledge - move.w D4,D1 // data - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // data 1st bit - bsr write_bit_wait_slave_i2c - moveq #6,D2 // 8 bits -.w5: - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // data - bsr write_bit_i2c - dbf D2,.w5 - bsr read_bit_i2c // ack - bne.s .w3 // no acknoledge - bsr stop_bit_i2c - moveq #0,D0 - move.w D1,D0 // 8 bits data - bra.s .w2 -.w3: - bsr stop_bit_i2c - moveq #CT60_READ_ERROR,D0 // error - bra.s .w2 -.w1: - moveq #CT60_READ_ERROR,D0 // bus error - move.l A1,8 - move.l A2,SP -.w2: - lea _tbdr_mfp,A1 - cmp.l A0,A1 - bne.s .w7 - clr.b _tbcr_mfp // timer B stopped -.w7: - move (SP)+,SR - tst.l D0 - movem.l (SP)+,D1-D4/A0-A2 - rts - -write_device_i2c: // D0: device - - movem.l D0-D2,-(SP) - move.w D0,D1 - add.b D1,D1 - moveq #6,D2 // 7 bits 1010xxx (SDRAM) -.wd1: - moveq #0,D0 - add.b D1,D1 - addx.b D0,D0 // device - bsr write_bit_i2c - dbf D2,.wd1 - movem.l (SP)+,D0-D2 - rts - -read_bit_i2c: - - clr.l _sda_high // data=1 initial state (open drain) - WAIT_US // 100 KHz max ! - clr.l _scl_high // clk=1 - WAIT_US - move.l _sda,D0 // data on D0 - clr.l _scl_low // clk=0 - btst #0,D0 - rts - -read_bit_wait_slave_i2c: - - move.l D1,-(SP) - clr.l _sda_high // data=1 initial state (open drain) - WAIT_US - clr.l _scl_high // clk=1 - moveq #31,D1 // time-out slave busy -.rs1: - WAIT_US // 100 KHz max ! - move.l _sda,D0 // SCL slave on B1 - btst #1,D0 - dbne D1,.rs1 - move.l _sda,D0 // data on B0 - clr.l _scl_low // clk=0 - move.l (SP)+,D1 - btst #0,D0 - rts - -write_bit_i2c: - - tst.w D0 - bne.s .wb1 - clr.l _sda_low // data=0 - bra.s .wb2 -.wb1: - clr.l _sda_high // data=1 -.wb2: - WAIT_US // 100 KHz max ! - clr.l _scl_high // clk=1 - WAIT_US - clr.l _scl_low // clk=0 - rts - -write_bit_wait_slave_i2c: - - move.l D1,-(SP) - tst.w D0 - bne.s .ws1 - clr.l _sda_low // data=0 - bra.s .ws2 -.ws1: - clr.l _sda_high // data=1 -.ws2: - WAIT_US - clr.l _scl_high // clk=1 - moveq #31,D1 // time-out slave busy -.ws3: - WAIT_US // 100 KHz max ! - move.l _sda,D0 // SCL slave on B1 - btst #1,D0 - dbne D1,.ws3 - clr.l _scl_low // clk=0 - move.l (SP)+,D1 - rts - -start_bit_i2c: - - clr.l _sda_high // data=1 initial state - clr.l _scl_high // clk=1 - WAIT_US // 100 KHz max ! - clr.l _sda_low // data=0 => start condition - WAIT_US - clr.l _scl_low // clk=0 - rts - -start_bit_wait_slave_i2c: - - move.l D1,-(SP) - clr.l _sda_high // data=1 initial state - WAIT_US // 100 KHz max ! - clr.l _scl_high // clk=1 - moveq #31,D1 // time-out slave busy -.s1: - WAIT_US // 100 KHz max ! - move.l _sda,D0 // SCL slave on B1 - btst #1,D0 - dbne D1,.s1 - clr.l _sda_low // data=0 => start condition - WAIT_US - clr.l _scl_low // clk=0 - move.l (SP)+,D1 - rts - -stop_bit_i2c: - - clr.l _sda_low // data=0 - WAIT_US // 100 KHz max ! - clr.l _scl_high // clk=1 - WAIT_US - clr.l _sda_high // data=1 => stop condition - WAIT_US - rts - -wait_26us: // 26uS (timer C) or 6.5uS (timer B) - - move.b (A0),D0 -.wu1: - cmp.b (A0),D0 - beq.s .wu1 - rts + jmp write_i2c tempo_20ms: @@ -10691,14 +9071,13 @@ tempo_20ms: clock_registers: dc.b CLKOE, 0x69 // clocks 1, 4, 5, 6 - dc.b DIV1N, 0x06 // post divider /6 dc.b PINCTRL,0x50 // output enable pin dc.b OSCDRV, 0x28 // clock REF dc.b INLOAD, 0x6B // capacity load dc.b ADCREG, 0x00 - dc.b MATRIX1,0xB6 // clocks 1 to 4 DIV2CLK/2 - dc.b DIV2N, 0x08 // post divider /4 - dc.b WPREG, 0x1C // write protect soft on, in last position */ + dc.b MATRIX1,0xB6 // clocks 1 to 3 DIV2CLK/2 + dc.b DIV2N, 0x08 // post divider /8 + dc.b WPREG, 0x1C // write protect soft on, in last position dc.b 0,0 chip_density: // A23-A22 cdy2-1 @@ -10772,31 +9151,7 @@ init_cookie_ct60: move.l 4(A0),A0 // buffer move.l D2,8(A0) // CPU frequency in MHz * 10 #ifndef COLDFIRE - move.l phystop,A0 - clr.w count_io3_mfp(A0) - move.l _hz_200,start_hz_200(A0) - pea inter_io3_mfp(PC) - move.w #67,-(SP) // IO3 MFP - move.w #5,-(SP) // Setexec - trap #13 - addq.l #8,SP - move.w #3,-(SP) // IO3 MFP - move.w #27,-(SP) // Jenabint - trap #14 - addq.l #4,SP - move.l _hz_200,D0 - add.l #100,D0 // tempo 0.5 S -.tempo_test_fan: - move.l _hz_200,D1 - cmp.l D0,D1 - blt.s .tempo_test_fan - move.l phystop,A0 - cmp.w #5,count_io3_mfp(A0) - bcc.s .error_cookie_ct60 - move.w #3,-(SP) // IO3 MFP - move.w #26,-(SP) // Jdisint - trap #14 - addq.l #4,SP + jsr init_speed_fan #endif .error_cookie_ct60: movem.l (SP)+,D0-D2/A0-A2 @@ -10812,47 +9167,6 @@ linea000: jsr 0xE09512 // address function Linea 0xA000 rte -#else - - dc.l 0x58425241 // XBRA - dc.l 0x43543630 // CT60 - dc.l 0 - -inter_io3_mfp: - - movem.l D0/A0,-(SP) - move.l phystop,A0 - addq.w #1,count_io3_mfp(A0) - move.l _hz_200,D0 - sub.l start_hz_200(A0),D0 - cmp.l #1000,D0 // 5 S - bcs.s .end_inter - move.l _hz_200,start_hz_200(A0) - move.l cookie,D0 - beq.s .end_inter - move.l D0,A0 -.loop_cookie_inter: - tst.l (A0) - beq.s .end_inter - cmp.l #0x43543630,(A0) // CT60 - bne.s .next_cookie_inter - move.l 4(A0),D0 - beq.s .end_inter - move.l phystop,A0 - move.w count_io3_mfp(A0),-(SP) - clr.w count_io3_mfp(A0) - move.l D0,A0 - move.w (SP)+,D0 - mulu #6,D0 // tr/mn - move.w D0,6(A0) // speed_fan - bra.s .end_inter -.next_cookie_inter: - addq.l #8,A0 - bra.s .loop_cookie_inter -.end_inter: - movem.l (SP)+,D0/A0 - bclr #3,0xFFFFFA11 // ISRB - rte #endif diff --git a/flash.tos/tos/cache2.S b/flash.tos/tos/cache2.S new file mode 100644 index 0000000..565061a --- /dev/null +++ b/flash.tos/tos/cache2.S @@ -0,0 +1,65 @@ +/* +* Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "vars.h" + +#ifdef COLDFIRE +#include "fire.h" + + .globl caches_disable + .globl caches_enable +#endif + .globl fix_bug_nvdi + +fix_bug_nvdi: + + move.l _v_bas_ad,D0 + cmp.l #0x01000000,D0 + bcc.s .normal_v_opnwk +#ifdef COLDFIRE + .chip 68060 + movec.l CACR,D0 + .chip 5200 +#else + movec.l CACR,D0 +#endif + move.l D0,-(SP) +#ifdef COLDFIRE + jsr caches_disable +#else + jsr 0xE0085A // caches off +#endif + moveq #3,D0 + jsr 0xE34348 // v_opnwk +#ifdef COLDFIRE + move.l #CACHE_ENABLE_MODE,D0 + cmp.l (SP)+,D0 +#else + cmp.l #0xA0808000,(SP)+ +#endif + bne.s .no_caches +#ifdef COLDFIRE + jsr caches_enable +#else + jsr 0xE250C8 // caches on +#endif +.no_caches: + rts +.normal_v_opnwk: + moveq #3,D0 + jmp 0xE34348 // v_opnwk diff --git a/flash.tos/tos/cf68klib.S b/flash.tos/tos/cf68klib.S index 9488b15..fec1eeb 100644 --- a/flash.tos/tos/cf68klib.S +++ b/flash.tos/tos/cf68klib.S @@ -1,7 +1,7 @@ -/* Install and uncompress the PCI part of the TOS +/* Install and uncompress the drivers part of the TOS * and start the CF68KLIB * - * Didier Mequignon, 2006-2009, e-mail: aniplay@wanadoo.fr + * Didier Mequignon, 2006-2011, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,11 +19,11 @@ */ #include "fire.h" +#include "vars.h" -#define cookie 0x5A0 #define _run 0x6EE4 /* TOS 404 PD */ -#undef DEBUG +#define DEBUG .text @@ -36,7 +36,6 @@ cf68klib: move.l A0,-(SP) // init_mmu routine move.l A1,-(SP) // update_tlb routine #ifndef MCF5445X -#ifndef MCF547X /* Initialize RAMBAR0 - locate it on the data bus */ move.l #SRAM_BASE+0x0035,D0 movec.l D0,RAMBAR0 @@ -44,22 +43,33 @@ cf68klib: move.l #SRAM_BASE2+0x0035,D0 movec.l D0,RAMBAR1 #endif + move.l #0x5F4C5A5F,D0 // _LZ_ + move.l #0x4C5A4D41,D1 // LZMA + moveq #3,D2 + lea 0xED0000,A0 // 128KB / 192KB / 256KB / 320KB +.test_lz_loop: + cmp.l (A0),D0 // _LZ_ + beq.s .uncompress_pci_drivers + cmp.l (A0),D1 // LZMA + beq.s .uncompress_pci_drivers + sub.l #0x10000,A0 + subq.l #1,D2 + bpl.s .test_lz_loop +#ifdef DEBUG + bra.s .not_found_compressed_pci_drivers #endif +.error_uncompress_pci_drivers: +#ifdef DEBUG + move.l D0,-(SP) + bsr debug_hex_long + lea debug24c(PC),A0 + bsr debug_display_string + move.l (SP)+,D0 +.not_found_compressed_pci_drivers: +#endif moveq #0,D0 moveq #0,D1 // normal PCI drivers - move.l #0x5F4C5A5F,D2 // _LZ_ - lea 0xED0000,A0 // 128 KB - cmp.l (A0),D2 // _LZ_ - beq.s .uncompress_pci_drivers - lea 0xEC0000,A0 // 192 KB - cmp.l (A0),D2 // _LZ_ - beq.s .uncompress_pci_drivers - lea 0xEB0000,A0 // 256 KB - cmp.l (A0),D2 // _LZ_ - beq.s .uncompress_pci_drivers - lea 0xEA0000,A0 // 320 KB - cmp.l (A0),D2 // _LZ_ - bne.s .not_compressed_pci_drivers + bra .not_compressed_pci_drivers .uncompress_pci_drivers: #ifdef DEBUG move.l A0,-(SP) @@ -77,13 +87,46 @@ cf68klib: bsr debug_display_string move.l (SP)+,A0 #endif + cmp.l (A0),D1 + beq.s .uncompress_pci_drivers2 move.l 4(A0),-(SP) // insize pea 0x1000000 // out: SDRAM temp pea 8(A0) // in jsr (A2) // LZ_Uncompress routine move.l (SP)+,D1 - subq.l #8,D1 + subq.l #8,D1 // base PCI drivers addq.l #8,SP + bra.s .end_uncompress_pci_drivers +.uncompress_pci_drivers2: + link A6,#-24 + move.l A0,-(SP) // base PCI drivers + pea 8(A0) // propsData + pea -16(A6) // Properties + jsr (A3) // LzmaDecodeProperties routine + addq.l #8,SP + tst.l D0 + bne.s .error_header_lzma // error + move.l #0x1100000,D0 + move.l D0,-4(A6) // Probs buffer, size = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp))) * sizeof(CProb) + move.l (SP),A0 // base PCI drivers + pea -24(A6) // outSizeProcessed + move.l #0x100000,-(SP) // outSize + pea 0x1000000 // outStream: SDRAM temp + pea -20(A6) // inSizeProcessed + move.l 4(A0),-(SP) // inSize + pea 8+5(A0) // inStream + pea -16(A6) // CLzmaDecoderState structure + jsr (A4) // LzmaDecode routine + lea 28(SP),SP + move.l -24(A6),D1 // outSizeProcessed +.error_header_lzma: + move.l (SP)+,A0 + unlk a6 + tst.l D0 + bne .error_uncompress_pci_drivers // error + move.l D1,D0 // outSizeProcessed + move.l A0,D1 // base PCI drivers +.end_uncompress_pci_drivers: #ifdef DEBUG move.l D0,-(SP) bsr debug_hex_long @@ -110,15 +153,18 @@ cf68klib: move.l D0,MCF_XARB_IMR lea cf68k_xarbint(PC),A0 move.l A0,(64+47)*4(A1) + lea cf68k_xlbpci(PC),A0 + move.l A0,(64+43)*4(A1) moveq #0x3F,D0 // level 7, priority 7 - move.b D0,MCF_INTC_ICR47 + move.b D0,MCF_INTC_ICR47 // XLBARB + move.b D0,MCF_INTC_ICR43 // XLBPCI move.l #~MCF_INTC_IMRH_INT_MASK47,D0 and.l D0,MCF_INTC_IMRH // lea cf68k_debugint(PC),A0 // move.l A0,12*4(A1) // Non PC breakpoint debug interrupt #ifndef MCF547X /* MCF548X - M5484LITE */ move.b FIRE_ENGINE_CPLD_HW_REVISION,D0 - move.b D0,fire_engine_hw_rev // for IDE test (sdram.S) + move.b D0,fire_engine_hw_rev // for IDE test (boot2.S) #endif #endif lea library_data_area,A0 // 1024 bytes @@ -151,6 +197,7 @@ cf68klib: clr.b debug_cf68klib_count clr.b debug_trap clr.b debug_trap_count + clr.b debug_int7 clr.b trap_breakpoint clr.l old_cacr clr.l old_gemdos // for store the BDOS/GEMDOS vector @@ -206,27 +253,58 @@ start_emulation: bpl.s .clear_nvram move.w #DEFAULT_LANG_KEYB,D0 move.w D0,pseudo_nvram_data+6 -#ifdef MCF547X - lea 0xFFFF8800,A0 // PSG sound - moveq #7,D0 - move.b D0,(A0) // ports A & B - move.b #0xC0,D0 // are outputs - move.b D0,2(A0) - moveq #14,D0 // port A - move.b D0,(A0) - moveq #7,D0 // disable floppy - move.b D0,2(A0) -#endif + lea 0xE00000,A0 // TOS404 + sub.l #RESERVE_MEM_FONTS,A0 + move.l A0,phystop + clr.l hardware_type(A0) jmp 0xE001DA #ifndef MCF5445X /* there are no XL bus and arbiter on MCF5445X */ + +cf68k_xlbpci: + + .chip 68060 + move.w #0x2700,SR // mask interrupts + .chip 5200 +#if 0 // #ifdef DEBUG + move.l D0,-(SP) + move.l A0,-(SP) + lea debug17(PC),A0 + bsr debug_display_string + move.l 12(SP),D0 + bsr debug_hex_long + lea debug17sr(PC),A0 + bsr debug_display_string + move.w 10(SP),D0 + bsr debug_hex_word + lea debug17f(PC),A0 + bsr debug_display_string + move.w 8(SP),D0 + bsr debug_hex_word + lea crlf(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 + move.l (SP)+,D0 +#endif + move.l D0,-(SP) + move.l 4(SP),D0 + and.l #0xF000FFFF,D0 + or.l #0x000A0000,D0 // Access fault + move.l D0,4(SP) + move.l MCF_PCI_PCIGSCR,D0 // PERR and SERR seems on this interrupt + move.l D0,MCF_PCI_PCIGSCR + move.l MCF_PCI_PCIISR,D0 + move.l D0,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,D0 + move.l coldfire_vector_base+8,-(SP) // access fault + rts cf68k_xarbint: .chip 68060 move.w #0x2700,SR // mask interrupts .chip 5200 -#ifdef DEBUG +#if 0 // #ifdef DEBUG move.l D0,-(SP) move.l A0,-(SP) lea debug17(PC),A0 @@ -316,6 +394,8 @@ tab_debug: cf68k_install_vector: #ifndef MCF5445X + cmp.l #64+43,D0 // XLB PCI interrupt + beq.s .no_install cmp.l #64+47,D0 // XL Bus Arbiter interrupt beq.s .no_install #endif @@ -412,9 +492,77 @@ cf68k_address_error: bsr debug_display_fault moveq #0xC,D0 bra .error - + cf68k_illegal_instruction: + move.l D0,-(SP) + and.l #0xF1FF,D0 + cmp.l #0x013C,D0 // btst dx,imm + bne.s .not_btst_dx_imm + move.l (SP),D0 + and.l #0x0E00,D0 + lsr.l #7,D0 + move.l reg_pc(A0),A1 + move.w 2(A1),D1 // bit number + move.l reg_d0(A0,D0.l),D0 + btst D1,D0 + move ccr,D0 + move.b D0,reg_ccr(A0) + addq.l #4,reg_pc(A0) + addq.l #4,SP + moveq #1,D0 + rts +.not_btst_dx_imm: + move.l (SP),D0 + cmp.l #0x083A,D0 // btst #X,d16(PC) + beq.s .btst_16pc + cmp.l #0x087A,D0 // bchg #X,d16(PC) + beq.s .bchg_16pc + cmp.l #0x08BA,D0 // bclr #X,d16(PC) + beq.s .bclr_16pc + cmp.l #0x08FA,D0 // bset #X,d16(PC) + beq.s .bset_16pc + bra.s .true_illegal +.btst_16pc: + move.l reg_pc(A0),A1 + move.w 2(A1),D0 // bit number + move.w 4(A1),D1 // d16 + ext.l D1 + add.l D1,A1 + btst.b D0,(A1) + bra.s .common_16pc +.bchg_16pc: + move.l reg_pc(A0),A1 + move.w 2(A1),D0 // bit number + move.w 4(A1),D1 // d16 + ext.l D1 + add.l D1,A1 + bchg.b D0,(A1) + bra.s .common_16pc +.bclr_16pc: + move.l reg_pc(A0),A1 + move.w 2(A1),D0 // bit number + move.w 4(A1),D1 // d16 + ext.l D1 + add.l D1,A1 + bclr.b D0,(A1) + bra.s .common_16pc +.bset_16pc: + move.l reg_pc(A0),A1 + move.w 2(A1),D0 // bit number + move.w 4(A1),D1 // d16 + ext.l D1 + add.l D1,A1 + bset.b D0,(A1) +.common_16pc: + move ccr,D0 + move.b D0,reg_ccr(A0) + addq.l #6,reg_pc(A0) + addq.l #4,SP + moveq #1,D0 + rts +.true_illegal: + addq.l #4,SP bsr breakpoint_deinstall beq .not_a_breakpoint tst.l v_breakpoint_install @@ -441,7 +589,7 @@ cf68k_illegal_instruction: lea debug18(PC),A0 bsr debug_display_string move.l current_tcb,A0 - lea 0x138(A0),A0 + lea 0x13C(A0),A0 bsr debug_display_string move.l (SP)+,A0 bra .display_registers_and_suspend_task @@ -518,8 +666,8 @@ cf68k_privilege_violation: bsr breakpoint_deinstall move.l (SP)+,D0 and.l #0xFFC0,D0 - cmp.l #0x40C0,D0 // move from SR - beq.s .move_from_sr // 68000 emulation under TOS + cmp.l #0x40C0,D0 // move from SR + beq.s .move_from_sr // 68000 emulation under TOS bsr debug_display_fault .move_from_sr: moveq #0x20,D0 @@ -527,18 +675,230 @@ cf68k_privilege_violation: cf68k_line_a: + move.l D0,-(SP) + and.l #0xFFF8,D0 + cmp.l #0xA910,D0 // move.b DX,-(SP) replacement + bne.s .not_moveb_sp + moveq #7,D0 + and.l (SP),D0 // register number + move.l reg_d0(A0,D0.l*4),D0 + bra.s .common_moveb_sp +.not_moveb_sp: + cmp.l #0xA930,D0 // move.b (AX),-(SP) replacement + bne.s .not_moveb_ax_sp + moveq #7,D0 + and.l (SP),D0 // register number + move.l reg_a0(A0,D0.l*4),A2 + move.b (A2),D0 + bra.s .common_moveb_sp +.not_moveb_ax_sp: + cmp.l #0xA9B0,D0 // move.b d(AX),-(SP) replacement + bne.s .not_moveb_dax_sp + moveq #7,D0 + and.l (SP),D0 // register number + move.l reg_a0(A0,D0.l*4),A2 + move.l reg_pc(A0),A1 + addq.l #2,A1 + move.l A1,reg_pc(A0) + move.w (A1),D0 // offset + ext.l D0 + move.b (A2,D0.l),D0 + bra.s .common_moveb_sp +.not_moveb_dax_sp: + cmp.l #0xA9F1,D0 // move.b abs.l,-(SP) replacement + bne.s .not_moveb_absl_sp + move.l reg_pc(A0),A1 + addq.l #4,A1 + move.l A1,reg_pc(A0) + move.l -2(A1),A2 // address + move.l (A2),D0 + bra.s .common_moveb_sp +.not_moveb_absl_sp: + cmp.l #0xA9F2,D0 // move.b d(PC),-(SP) replacement + bne.s .not_moveb_dpc_sp + move.l reg_pc(A0),A1 + addq.l #2,A1 + move.l A1,reg_pc(A0) + move.w (A1),D0 // offset + ext.l D0 + move.l (A1,D0.l),D0 +.common_moveb_sp: + move.l reg_a7(A0),A1 + subq.l #2,A1 + move.b D0,(A1) // upper byte on the stack + move ccr,D0 + move.b D0,reg_ccr(A0) + bra.s .common_moveb_sp_spp +.not_moveb_dpc_sp: + cmp.l #0xA918,D0 // move.b (SP)+,DX replacement + bne.s .not_moveb_spp + moveq #7,D0 + and.l (SP),D0 // register number + move.l reg_a7(A0),A1 + move.b (A1),reg_d0(A0,D0.l*4) + bra.s .common_moveb_spp +.not_moveb_spp: + cmp.l #0xA938,D0 // move.b (SP)+,(AX) replacement + bne.s .not_moveb_spp_ax + moveq #7,D0 + and.l (SP),D0 // register number + move.l reg_a0(A0,D0.l*4),A2 + bra.s .common_moveb_spp_abs +.not_moveb_spp_ax: + cmp.l #0xA9B8,D0 // move.b (SP)+,d(AX) replacement + bne.s .not_moveb_spp_dax + moveq #7,D0 + and.l (SP),D0 // register number + move.l reg_a0(A0,D0.l*4),A2 + move.l reg_pc(A0),A1 + addq.l #2,A1 + move.l A1,reg_pc(A0) + move.w (A1),D0 // offset + ext.l D0 + move.l reg_a7(A0),A1 + move.b (A1),(A2,D0.l) + bra.s .common_moveb_spp +.not_moveb_spp_dax: + cmp.l #0xA9F9,D0 // move.b (SP)+,abs.l replaced by 0xA9F9 + bne.s .not_moveb_spp_absl + move.l reg_pc(A0),A1 + addq.l #4,A1 + move.l A1,reg_pc(A0) + move.l -2(A1),A2 +.common_moveb_spp_abs: + move.l reg_a7(A0),A1 + move.b (A1),(A2) // upper byte on the stack +.common_moveb_spp: + move ccr,D0 + move.b D0,reg_ccr(A0) + addq.l #2,A1 +.common_moveb_sp_spp: + move.l A1,reg_a7(A0) + btst #SR_S_BIT,reg_sr(A0) + beq.s .update_usp + move.l reg_a7(A0),reg_ssp(A0) + bra .jump_linea2 +.update_usp: + move.l reg_a7(A0),reg_usp(A0) + bra .jump_linea2 +.not_moveb_spp_absl: + move.l (SP),D0 + and.l #0xFFC0,D0 + cmp.l #0xABC0,D0 // mulu/s.l ,dh:dl + bne.s .not_mul64 + move.l A0,A6 // RegList structure + move.l reg_pc(A6),A0 // PC + addq.l #2,A0 + move.l (SP),D5 // opcode + move.w (A0),D7 // ext + jsr read_operand_long // => A0 (PC) updated, D0 operand + move.l D7,D1 // save ext + lsr.l #8,D7 + lsr.l #4,D7 + moveq #7,D6 + and.l D6,D7 // Dl + and.l D1,D6 // Dh + move.l D0,-(SP) // + move.l reg_d0(A6,D7.l*4),-(SP) + btst #11,D1 // ext + beq.s .mulu_64 + jsr _PA_muls32 + bra.s .mul_64_done +.mulu_64: + jsr _PA_mulu32 +.mul_64_done: + moveq #0,D1 + move.l 4(SP),D0 + move.l D0,reg_d0(A6,D7.l*4) // Dl + sne.b D1 + move.l (SP)+,reg_d0(A6,D6.l*4) // Dh + bne.s .muldiv_done + tst.l D1 + bra.s .muldiv_done +.not_mul64: + cmp.l #0xAFC0,D0 // divu/s.l ,Dr:Dq + bne .not_div64 + move.l A0,A6 // RegList structure + move.l reg_pc(A6),A0 // PC + addq.l #2,A0 + move.l (SP),D5 // opcode + move.w (A0),D7 // ext + jsr read_operand_long // => A0 (PC) updated, D0 operand + move.l D7,D1 // save ext + lsr.l #8,D7 + lsr.l #4,D7 + moveq #7,D6 + and.l D6,D7 // Dq + and.l D1,D6 // Dr + move.l reg_d0(A6,D7.l*4),-(SP) + move.l reg_d0(A6,D6.l*4),-(SP) + move.l D0,-(SP) // + beq.s .div64_overflow // zero divide, to FIX + btst #11,D1 + beq.s .divu_64 + jsr _PA_divs64 + bra.s .div64_done +.divu_64: + jsr _PA_divu64 +.div64_done: + move ccr,D0 + bvs.s .div64_overflow + move.l (SP)+,reg_d0(A6,D6.l*4) // Dr + move.l (SP)+,reg_d0(A6,D7.l*4) // Dq + bra.s .muldiv_done +.div64_overflow: + addq.l #8,SP +.muldiv_done: + addq.l #8,SP + move ccr,D0 + move.b D0,reg_ccr(A6) + move.l A0,reg_pc(A6) + moveq #1,D0 + btst #SR_S_BIT,reg_sr(A6) + beq.s .update_usp2 + move.l reg_a7(A6),reg_ssp(A6) + rts +.update_usp2: + move.l reg_a7(A6),reg_usp(A6) + rts +.not_div64: + move.l (SP),D0 + cmp.l #0xA920,D0 + bne.s .jump_linea + move.l #0x41303030,D0 // A000 + bsr get_cookie + beq.s .jump_linea + move.l A0,-(SP) + move.l D0,A0 + jsr (A0) + move.l (SP)+,A3 + move.l D0,reg_d0(A3) + move.l A0,reg_a0(A3) + move.l A1,reg_a1(A3) + move.l A2,reg_a2(A3) + move.l A3,A0 +.jump_linea: #ifdef DEBUG move.l A0,-(SP) - move.l D0,-(SP) lea debug13(PC),A0 bsr debug_display_string + move.l 4(SP),D0 bsr debug_hex_word + lea debug13b(PC),A0 + bsr debug_display_string + move.l (SP),A0 + move.l reg_pc(A0),D0 + bsr debug_hex_long lea crlf(PC),A0 bsr debug_display_string - move.l (SP)+,D0 move.l (SP)+,A0 #endif - bra .vector_ok +.jump_linea2: + moveq #2,D0 + add.l D0,reg_pc(A0) + addq.l #4,SP + moveq #1,D0 + rts cf68k_line_f: @@ -561,7 +921,6 @@ cf68k_line_f: moveq #7,D0 and.l (SP),D0 move.l A0,-(SP) - move.l A1,-(SP) move.l reg_pc(A0),A1 move.w 2(A1),A1 // offset move.l reg_a0(A0,D0.l*4),A0 @@ -569,7 +928,6 @@ cf68k_line_f: .chip 68060 fsave (A0) .chip 5200 - move.l (SP)+,A1 moveq #4,D0 bra.s .inc_pc .not_fsave: @@ -585,12 +943,11 @@ cf68k_line_f: moveq #2,D0 bra.s .inc_pc .not_frestore_ax: - cmp.l #0xF368,D0 + cmp.l #0xF368,D0 // frestore d(Ax) bne.s .not_frestore moveq #7,D0 and.l (SP),D0 move.l A0,-(SP) - move.l A1,-(SP) move.l reg_pc(A0),A1 move.w 2(A1),A1 // offset move.l reg_a0(A0,D0.l*4),A0 @@ -598,7 +955,6 @@ cf68k_line_f: .chip 68060 frestore (A0) .chip 5200 - move.l (SP)+,A1 moveq #4,D0 .inc_pc: move.l (SP)+,A0 @@ -608,31 +964,55 @@ cf68k_line_f: rts .not_frestore: move.l (SP),D0 -#if 0 - cmp.l #0xF800,D0 // lpstop - bne .not_lpstop - move.l A0,-(SP) - move.l reg_pc(A0),A0 - move.w 2(A0),D0 - cmp.l #0x01C0,D0 - bne .not_lpstop2 - move.w (A0)+,D0 // immediate data - move.l (SP),A0 - addq.l #6,reg_pc(A0) - move.w D0,stop_area+2(A0) // copy user's STOP #n instruction to scratchpad - move.w #0x4E72,D0 - move.w D0,stop_area(A0) - move.w #0x4E75,D0 // append an RTS - move.w D0,stop_area+4(A0) + cmp.l #0xF23C,D0 // fabs, fadd, fcmp, fdiv, fint, fintrz, fmove, fmul, fneg, fsqrt, fsub, ftst # + bne .not_fimm + move.l reg_pc(A0),A1 + move.w 2(A1),D0 // 2nd word opcode + cmp.l #0x4423,D0 // fmul.s #x,fp0 + beq .fmulsimm + and.l #0x7F,D0 // opmode + lea fvalid(PC),A1 + move.b (A1,D0.l),D0 + beq .not_fimm // invalid + move.l reg_pc(A0),A1 + move.w 2(A1),D0 // 2nd word opcode + and.l #0xE000,D0 + cmp.l #0x4000,D0 // R/M + bne.s .not_fimm + move.w 2(A1),D0 // 2nd word opcode + lsr.l #8,D0 + lsr.l #2,D0 + and.l #7,D0 // source specifier + lea flen(PC),A1 + move.b (A1,D0.l),D0 + beq.s .not_fimm // invalid + move.l reg_pc(A0),A1 + lea fpu_area,A2 + addq.l #4,D0 // len data + opcode len + add.l D0,reg_pc(A0) + move.l (A1)+,D0 // opcode + and.l #0xFFC0FFFF,D0 + or.l #0x00110000,D0 // (A1) + move.l D0,(A2) + move.w #0x4E75,D0 + move.w D0,4(A2) // RTS bsr cpushl_dc bsr cpushl_ic - // to do - halt -.not_lpstop2: - move.l (SP)+,A0 + jsr (A2) // call fpu_area + addq.l #4,SP + moveq #1,D0 + rts +.fmulsimm: + .chip 68060 + fmul.s 4(A1),fp0 + .chip 5200 + moveq #8,D0 // len data + opcode len + add.l D0,reg_pc(A0) + addq.l #4,SP + moveq #1,D0 + rts +.not_fimm: move.l (SP),D0 -.not_lpstop: -#endif #if 0 cmp.l #0xF438,D0 bne.s .not_debug_int_on @@ -669,13 +1049,15 @@ cf68k_line_f: #endif and.l #0xFF3F,D0 cmp.l #0xF418,D0 // cinva - beq.s .is_cinva // cinva DC (0xF458), cinva IC (0xF498), cinva BC (0xF4D8) - cmp.l #0xF438,D0 // cpusha + beq.s .is_cpushl // cinva DC (0xF458), cinva IC (0xF498), cinva BC (0xF4D8) + cmp.l #0xF428,D0 // cpushl + beq.s .is_cpushl // cpushl DC (0xF468), cpushl IC (0xF4A8), cpushl BC (0xF4E8) + cmp.l #0xF438,D0 // cpusha DC (0xF478), cpusha IC (0xF4B8 ), cpusha BC (0xF4F8) bne .no_cpushl -.is_cinva: +.is_cpushl: move.l (SP),D0 and.l #0xC0,D0 - beq .no_cpushl + beq.s .inc2_pc cmp.l #0x40,D0 // 0xF478 beq.s .cpushl_dc cmp.l #0x80,D0 // 0xF4B8 @@ -713,6 +1095,138 @@ cf68k_line_f: #endif #endif bra .vector_ok + + +flen: dc.b 4,4,0,0,2,8,1,0 +fvalid: + dc.b 1 // 0x00 fmove + dc.b 1 // 0x01 fint + dc.b 0 // 0x02 + dc.b 1 // 0x03 fintrz + dc.b 1 // 0x04 fsqrt + dc.b 0 // 0x05 + dc.b 0 // 0x06 + dc.b 0 // 0x07 + dc.b 0 // 0x08 + dc.b 0 // 0x09 + dc.b 0 // 0x0A + dc.b 0 // 0x0B + dc.b 0 // 0x0C + dc.b 0 // 0x0D + dc.b 0 // 0x0E + dc.b 0 // 0x0F + dc.b 0 // 0x10 + dc.b 0 // 0x11 + dc.b 0 // 0x12 + dc.b 0 // 0x13 + dc.b 0 // 0x14 + dc.b 0 // 0x15 + dc.b 0 // 0x16 + dc.b 0 // 0x17 + dc.b 1 // 0x18 fabs + dc.b 0 // 0x19 + dc.b 1 // 0x1A fneg + dc.b 0 // 0x1B + dc.b 0 // 0x1C + dc.b 0 // 0x1D + dc.b 0 // 0x1E + dc.b 0 // 0x1F + dc.b 1 // 0x20 fdiv + dc.b 0 // 0x21 + dc.b 1 // 0x22 fadd + dc.b 1 // 0x23 fmul + dc.b 0 // 0x24 + dc.b 0 // 0x25 + dc.b 0 // 0x26 + dc.b 0 // 0x27 + dc.b 1 // 0x28 fsub + dc.b 0 // 0x29 + dc.b 0 // 0x2A + dc.b 0 // 0x2B + dc.b 0 // 0x2C + dc.b 0 // 0x2D + dc.b 0 // 0x2E + dc.b 0 // 0x2F + dc.b 0 // 0x30 + dc.b 0 // 0x31 + dc.b 0 // 0x32 + dc.b 0 // 0x33 + dc.b 0 // 0x34 + dc.b 0 // 0x35 + dc.b 0 // 0x36 + dc.b 0 // 0x37 + dc.b 1 // 0x38 fcmp + dc.b 0 // 0x39 + dc.b 1 // 0x3A ftst + dc.b 0 // 0x3B + dc.b 0 // 0x3C + dc.b 0 // 0x3D + dc.b 0 // 0x3E + dc.b 0 // 0x3F + dc.b 0 // 0x40 + dc.b 1 // 0x41 fsqrt + dc.b 0 // 0x42 + dc.b 0 // 0x43 + dc.b 0 // 0x44 + dc.b 1 // 0x45 fsqrt + dc.b 0 // 0x46 + dc.b 0 // 0x47 + dc.b 0 // 0x48 + dc.b 0 // 0x49 + dc.b 0 // 0x4A + dc.b 0 // 0x4B + dc.b 0 // 0x4C + dc.b 0 // 0x4D + dc.b 0 // 0x4E + dc.b 0 // 0x4F + dc.b 0 // 0x50 + dc.b 0 // 0x51 + dc.b 0 // 0x52 + dc.b 0 // 0x53 + dc.b 0 // 0x54 + dc.b 0 // 0x55 + dc.b 0 // 0x56 + dc.b 0 // 0x57 + dc.b 1 // 0x58 fsabs + dc.b 0 // 0x59 + dc.b 1 // 0x5A fsneg + dc.b 0 // 0x5B + dc.b 1 // 0x5C fdabs + dc.b 0 // 0x5D + dc.b 1 // 0x5E fdneg + dc.b 0 // 0x5F + dc.b 1 // 0x60 fsdiv + dc.b 0 // 0x61 + dc.b 1 // 0x62 fsadd + dc.b 1 // 0x63 fsmul + dc.b 1 // 0x64 fddiv + dc.b 0 // 0x65 + dc.b 1 // 0x66 fdadd + dc.b 1 // 0x67 fdmul + dc.b 1 // 0x68 fssub + dc.b 0 // 0x69 + dc.b 0 // 0x6A + dc.b 0 // 0x6B + dc.b 1 // 0x6C fdsub + dc.b 0 // 0x6D + dc.b 0 // 0x6E + dc.b 0 // 0x6F + dc.b 0 // 0x70 + dc.b 0 // 0x71 + dc.b 0 // 0x72 + dc.b 0 // 0x73 + dc.b 0 // 0x74 + dc.b 0 // 0x75 + dc.b 0 // 0x76 + dc.b 0 // 0x77 + dc.b 0 // 0x78 + dc.b 0 // 0x79 + dc.b 0 // 0x7A + dc.b 0 // 0x7B + dc.b 0 // 0x7C + dc.b 0 // 0x7D + dc.b 0 // 0x7E + dc.b 0 // 0x7F cf68k_trace: @@ -748,24 +1262,40 @@ cf68k_trace: bsr debug_display_disassemble_pc move.l cpu_step_over,D0 beq.s .no_breakpoint_remove +#if 1 + move.l A0,-(SP) +#else lea -20(SP),SP movem.l D1-D2/A0-A2,(SP) +#endif move.l D0,-(SP) move.l v_breakpoint_remove,A0 jsr (A0) addq.l #4,SP +#if 1 + move.l (SP)+,A0 +#else movem.l (SP),D1-D2/A0-A2 lea 20(SP),SP +#endif clr.l cpu_step_over .no_breakpoint_remove: +#if 1 + move.l A0,-(SP) +#else lea -20(SP),SP movem.l D1-D2/A0-A2,(SP) +#endif clr.l -(SP) // suspend current task move.l v_suspend_task,A0 jsr (A0) addq.l #4,SP +#if 1 + move.l (SP)+,A0 +#else movem.l (SP),D1-D2/A0-A2 lea 20(SP),SP +#endif move.l cpu_trace_thru,D0 or.l cpu_trace_count,D0 beq.s .end_trace @@ -893,7 +1423,7 @@ cf68k_trap15: // Let 680x0 virtual machine handle all these exceptions moveq #0,D0 rts - + //######################################################################### //# Callbacks from emulation library for hardware-related instructions # //######################################################################### @@ -916,7 +1446,7 @@ cf68k_cas: cf68k_cas2: cf68k_callm: cf68k_rtm: -#ifdef DEBUG +#if 0 // #ifdef DEBUG move.l A0,-(SP) lea debug4(PC),A0 bsr debug_display_string @@ -934,16 +1464,24 @@ breakpoint_deinstall: moveq #0,D0 // not a breakpoint tst.l v_breakpoint_deinstall beq.s .no_v_breakpoint +#if 1 + move.l A0,-(SP) +#else lea -20(SP),SP movem.l D1-D2/A0-A2,(SP) +#endif move.l current_tcb,-(SP) // pxCurrentTCB pea user_triggered move.l reg_pc(A0),-(SP) // PC move.l v_breakpoint_deinstall,A0 jsr (A0) lea 12(SP),SP +#if 1 + move.l (SP)+,A0 +#else movem.l (SP),D1-D2/A0-A2 lea 20(SP),SP +#endif .no_v_breakpoint: tst.l D0 rts @@ -953,14 +1491,22 @@ breakpoint_install: moveq #0,D0 tst.l v_breakpoint_install beq.s .no_v_breakpoint +#if 1 + move.l A0,-(SP) +#else lea -20(SP),SP movem.l D1-D2/A0-A2,(SP) +#endif move.l reg_pc(A0),-(SP) // reinstall breakpoint and continue move.l v_breakpoint_install,A0 jsr (A0) addq.l #4,SP +#if 1 + move.l (SP)+,A0 +#else movem.l (SP),D1-D2/A0-A2 lea 20(SP),SP +#endif tst.l D0 rts @@ -1022,52 +1568,57 @@ cf68k_write_control_register: move.l (SP)+,A0 #endif and.l #~CF_CACR_EUSP,D0 - cmp.l #(CF_CACR_DCINVA+CF_CACR_ICINVA),D0 - beq .cacr_ok - cmp.l #(CF_CACR_DCINVA+CF_CACR_BCINVA+CF_CACR_ICINVA),D0 - beq .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_DESB+CF_CACR_BEC+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DESB+CF_CACR_BEC+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_DESB+CF_CACR_BEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DESB+CF_CACR_BEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_BEC+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_BEC+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_BEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_BEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_DESB+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DESB+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_DESB),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DESB),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC+CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_IEC),D0 - beq.s .cacr_ok - cmp.l #(CF_CACR_DEC),D0 - beq.s .cacr_ok - tst.l D0 - bne.s .not_cacr + move.l A0,-(SP) + lea tab_cacr_valid-4(PC),A0 +.search_cacr_valid: + addq.l #4,A0 + cmp.l (A0),D0 + beq.s .cacr_ok + tst.l (A0) + bne.s .search_cacr_valid + btst #3,D0 // CI - 68K + beq.s .not_ci + bsr cpushl_ic +.not_ci: + btst #11,D0 // CD - 68K + beq.s .not_cd + bsr cpushl_dc +.not_cd: + move.l (SP)+,A0 + move.l #~0x808,D0 + and.l D0,reg_cacr(A0) + bra.s .not_cacr .cacr_ok: bsr cpushl_dc bsr cpushl_ic or.l #CF_CACR_EUSP,D0 movec.l D0,CACR move.l D0,old_cacr + move.l (SP)+,A0 .not_cacr: move.l (SP)+,D0 rts +tab_cacr_valid: + dc.l CF_CACR_DCINVA+CF_CACR_ICINVA + dc.l CF_CACR_DCINVA+CF_CACR_BCINVA+CF_CACR_ICINVA + dc.l CF_CACR_DEC+CF_CACR_DESB+CF_CACR_BEC+CF_CACR_IEC + dc.l CF_CACR_DESB+CF_CACR_BEC+CF_CACR_IEC + dc.l CF_CACR_DEC+CF_CACR_DESB+CF_CACR_BEC + dc.l CF_CACR_DESB+CF_CACR_BEC + dc.l CF_CACR_DEC+CF_CACR_BEC+CF_CACR_IEC + dc.l CF_CACR_BEC+CF_CACR_IEC + dc.l CF_CACR_DEC+CF_CACR_BEC + dc.l CF_CACR_BEC + dc.l CF_CACR_DEC+CF_CACR_DESB+CF_CACR_IEC + dc.l CF_CACR_DESB+CF_CACR_IEC + dc.l CF_CACR_DEC+CF_CACR_DESB + dc.l CF_CACR_DESB + dc.l CF_CACR_DEC+CF_CACR_IEC + dc.l CF_CACR_IEC + dc.l CF_CACR_DEC + dc.l 0 + cpushl_dc: move.l A1,-(SP) @@ -1104,26 +1655,6 @@ cpushl_ic: move.l (SP)+,A1 rts -#if 0 -cpushl_bc: - - move.l A1,-(SP) - lea 0,A1 -.loop_cpushl_bc: - dc.w 0xF4A9 // cpushl IC,(A1) - addq.l #1,A1 - dc.w 0xF4A9 // cpushl IC,(A1) - addq.l #1,A1 - dc.w 0xF4A9 // cpushl IC,(A1) - addq.l #1,A1 - dc.w 0xF4A9 // cpushl IC,(A1) - add.l #0x10-3,A1 - cmp.l #LAST_ICACHE_ADDR,A1 - ble.s .loop_cpushl_ic - move.l (SP)+,A1 - rts -#endif - debug_disassemble_pc: lea -24(SP),SP @@ -1291,7 +1822,7 @@ debug_display_fault: lea debug18(PC),A0 bsr debug_display_string move.l current_tcb,A0 - lea 0x138(A0),A0 + lea 0x13C(A0),A0 bsr debug_display_string move.l current_tcb,D0 cmp.l tid_tos,D0 @@ -1353,11 +1884,12 @@ debug_display_fault: .not_an_interrupt: move.l handler_fault,D0 beq.s .no_handler_fault + pea (A3) // RegList move.l D3,-(SP) // vector move.l reg_pc(A3),-(SP) move.l D0,A0 jsr (A0) - addq.l #8,SP + lea 12(SP),SP .no_handler_fault: movem.l (SP),D0-D3/A0-A3 lea 32(SP),SP @@ -1560,8 +2092,8 @@ debug1: .byte 13,10,10 .asciz "Breakpoint encountered at 0x" debug2: .asciz " - Base: " debug3: .asciz "cf68k emulation error, opcode 0x" -debug4: .ascii "Hardware-related instructions not emulated" - .byte 13,10,0 +//debug4: .ascii "Hardware-related instructions not emulated" +// .byte 13,10,0 debug5: .ascii "CF68K emulation started" .byte 13,10,0 debug6: .byte 13,10 @@ -1578,15 +2110,18 @@ debug11: .byte 13,10 .asciz "User Stack (USP): " //debug12: .asciz "movec opcode 0x" debug13: .asciz "Line A opcode 0x" +debug13b: .asciz " at 0x" debug14: .asciz "Line F opcode 0x" //debug15: .asciz "movec Dx,CACR 0x" debug16: .ascii "Format error" .byte 13,10,0 +#if 0 debug17: .ascii "Interrupt" .byte 13,10 .asciz "PC 0x" debug17sr: .asciz " SR 0x" debug17f: .asciz " Format 0x" +#endif debug18: .asciz " - Task: " debug19: .asciz "CF68KLIB stack (SP): " debug20: .asciz "VDI 0x" @@ -1752,10 +2287,11 @@ tab_mess_fault: .asciz "Not an access or address error" #ifndef MCF5445X .asciz "Arbiter timeout interrupt" + .asciz "XLB PCI interrupt" #else .byte 0 -#endif .byte 0 +#endif .byte 0 .asciz "Protection fault" .asciz "TLB miss on opword instruction" diff --git a/flash.tos/tos/conout.S b/flash.tos/tos/conout.S index 9b2a022..cde0586 100644 --- a/flash.tos/tos/conout.S +++ b/flash.tos/tos/conout.S @@ -28,7 +28,6 @@ .global _cputc // print a character for bios.c .global _bconout5 // raw console output .global _blink - .global _blink .global normal_ascii // default output type for linea.s #ifdef COLDFIRE @@ -177,13 +176,22 @@ _cputc: * printed regardless of the sign of char. */ _bconout5: - move.l #0,d1 +#ifndef COLDFIRE + move.l phystop,a0 + move.l hardware_type(a0),d1 + and.l #SUPERVIDEL,d1 + bne.s bconout5_tos +#endif /* COLDFIRE */ + moveq.l #0,d1 move.b 7(sp),d1 movem.l d2-d7/a2-a6,-(sp) bsr ascii_out movem.l (sp)+,d2-d7/a2-a6 rts - +#ifndef COLDFIRE +bconout5_tos: + jmp 0xE08D40 // default TOS routine for the Supervidel +#endif cputc: move.w 4(sp), d1 // Get just character from stack @@ -205,13 +213,27 @@ gsx_conout: // Gsx enters here movea.l con_state,a0 // based on our state goto the correct jmp (a0) // stub routine +#ifndef COLDFIRE +normal_ascii_tos: + jmp 0xE08D62 // default TOS routine for the Supervidel +#endif + normal_ascii: +#ifndef COLDFIRE + move.l phystop,a0 + move.l hardware_type(a0),d0 + and.l #SUPERVIDEL,d0 + bne.s normal_ascii_tos +#endif cmp.w #0x20,d1 // If the character is printable ascii bge ascii_out // go print it. #ifdef COLDFIRE + cmp.w #16,_v_planes + bcc.s no_serial cmp.l #0x01000000,_v_bas_ad bcs wait_uart // no graphic card +no_serial: #endif // We handle the following control characters as special. @@ -805,7 +827,12 @@ _blink: #ifdef COLDFIRE cmp.l #0x01000000,_v_bas_ad bcs.s bl_out // no graphic card -#endif +#else + move.l phystop,a0 + move.l hardware_type(a0),d0 + and.l #SUPERVIDEL,d0 + bne.s blink_tos +#endif /* COLDFIRE */ lea _v_stat_0,a0 // (need fix?) btst #F_CVIS,(a0) // test visibility/semaphore bit. beq.s bl_out // if invisible or blocked, return. @@ -818,8 +845,10 @@ _blink: bchg #F_CSTATE, (a0) // toggle cursor state. bsr comp_cr1 // complement cursor. bl_out: rts - - +#ifndef COLDFIRE +blink_tos: + jmp 0xE090F2 // default TOS routine for the Supervidel +#endif /* * alpha_cell - retrieve the address of the source cell @@ -872,8 +901,10 @@ out_of_bounds: */ ascii_out: #ifdef COLDFIRE + cmp.w #16,_v_planes + bcc.s graphic_card cmp.l #0x01000000,_v_bas_ad - bcc graphic_card // graphic card + bcc.s graphic_card // graphic card wait_uart: move.b MCF_UART_USR0,d0 and.b #MCF_UART_USR_TXRDY,d0 @@ -1325,7 +1356,7 @@ _tc: // 16M colors move.l a0,-(sp) move.l d0,-(sp) bsr test_accel - beq.s .no_clear_screen_ntc + beq.s .no_clear_screen_tc move.l d2,d0 swap d0 // delta y addq.l #1,d0 diff --git a/flash.tos/tos/conout.c b/flash.tos/tos/conout.c new file mode 100644 index 0000000..881e67d --- /dev/null +++ b/flash.tos/tos/conout.c @@ -0,0 +1,781 @@ +#include + +#define v_bas_ad (*(volatile unsigned long *)0x44E) +#define LINEA_VARS 0x3E86 /* TOS404 */ +#define LA_OFFSET 910 +#define M_CSTATE 2 +#define V_CELL 0 /* VT52 cell output routines */ +#define V_SCRUP 1 /* VT52 screen up routine */ +#define V_SCRDN 2 /* VT52 screen down routine */ +#define V_BLANK 3 /* VT52 screen blank routine */ +#define V_BLAST 4 /* blit routines */ +#define V_MONO 5 /* monospace font blit routines */ +#define V_RECT 6 /* rectangle draw routines */ +#define V_VLINE 7 /* vertical line draw routines */ +#define V_HLINE 8 /* horizontal line draw routines */ +#define V_TEXT 9 /* text blit routines */ +#define V_VQCOLOR 10 /* color inquire routines */ +#define V_VSCOLOR 11 /* color set routines */ +#define V_INIT 12 /* init routine called upon openwk */ +#define V_SHOWCUR 13 /* display cursor */ +#define V_HIDECUR 14 /* replace cursor with old background */ +#define V_NEGCELL 15 /* negate alpha cursor */ +#define V_MOVEACUR 16 /* move alpha cur to new X,Y (D0, D1) */ +#define V_ABLINE 17 /* arbitrary line routine */ +#define V_HABLINE 18 /* horizontal line routine setup */ +#define V_RECTFILL 19 /* routine to do rectangle fill */ +#define V_PUTPIX 20 /* output pixel value to the screen */ +#define V_GETPIX 21 /* get pixel value at (X,Y) of screen */ +#define V_ROUTS 22 /* (routine array size) */ + +typedef struct vdiVars +{ + short _angle; + short begAng; + void *curFont; /* pointer to current font */ + short delAng; + short deltaY; + short deltaY1; + short deltaY2; + short endAng; + short filIntersect; + short fillMaxY; + short fillMinY; + short nSteps; + short oDeltaY; + short sBegstY; + short sEndstY; + short sFilCol; + short sFillPer; + short sPatMsk; + short *sPatPtr; + short _start; + short xC; + short xRad; + short y; + short yC; + short yRad; + short mPosHx; /* Mouse hot spot - x coord */ + short mPosHy; /* Mouse hot spot - y coord */ + short mPlanes; /* Ms planes (reserved, but we used it) */ + short mCdbBg; /* Mouse background color as pel value */ + short mCdbFg; /* Mouse foreground color as pel value */ + short maskForm[32]; /* Storage for ms cursor mask and form */ + short inqTab[45]; /* info returned by vq_extnd VDI call */ + short devTab[45]; /* info returned by v_opnwk VDI call */ + short gCurX; /* current mouse cursor X position */ + short gCurY; /* current mouse cursor Y position */ + short hideCnt; /* depth at which the ms is hidden */ + short mouseBt; /* current mouse button status */ + short reqCol[16][3]; /* internal data for vq_color */ + short sizTab[15]; /* size in device coordinates */ + short termCh; /* 16 bit character info */ + short chcMode; /* the mode of the Choice device */ + void *curWork; /* pointer to current works attributes */ + void *defFont; /* pointer to default font head */ + void *fontRing[4]; /* ptrs to link list of fnt hdrs */ + short iniFontCount; /* # of fonts in the FONT_RING lists */ + short lineCW; /* current line width */ + short locMode; /* the mode of the Locator device */ + short numQCLines; /* # of line in the quarter circle */ + long trap14Sav; /* space to save the return address */ + long colOrMask; /* some modes this is ored in VS_COLOR */ + long colAndMask; /* some modes this is anded in VS_COLOR */ + long trap14BSav; /* space to sav ret adr (for reentrency)*/ + short reserved0[32]; /* reserved */ + short strMode; /* the mode of the String device */ + short valMode; /* the mode of the Valuator device */ + char curMsStat; /* Current mouse status */ + char reserved1; /* reserved */ + short disabCnt; /* hide depth of alpha cursor */ + short xyDraw[2]; /* x,y communication block. */ + char drawFlag; /* Non-zero means draw ms frm on vblank */ + char mouseFlag; /* Non-zero if mouse ints disabled */ + long trap1Sav; /* space to save return address */ + short savCXY[2]; /* save area for cursor cell coords. */ + short saveLen; /* height of saved form */ + short *saveAddr; /* screen addr of 1st short of plane 0 */ + short saveStat; /* cursor save status */ + long saveArea[64]; /* save up to 4 planes. 16 longs/plane */ + short (*timAddr)(); /* ptr to user installed routine */ + short (*timChain)(); /* jmps here when done with above */ + short (*userBut)(); /* user button vector */ + short (*userCur)(); /* user cursor vector */ + short (*userMot)(); /* user motion vector */ + short vCelHt; /* height of character cell */ + short vCelMx; /* maximum horizontal cell index */ + short vCelMy; /* maximum vertical cell index */ + short vCelWr; /* screen width (bytes) * cel_ht */ + short vColBg; /* character cell text background color */ + short vColFg; /* character cell text foreground color */ + short *vCurAd; /* cursor address */ + short vCurOff; /* byte offset to cur from screen base */ + short vCurCx; /* cursor cell X position */ + short vCurCy; /* cursor cell Y position */ + char vCTInit; /* vCurTim reload value. */ + char vCurTim; /* cursor blink rate (# of vblanks) */ + short *vFntAd; /* address of monospaced font data */ + short vFntNd; /* last ASCII code in font */ + short vFntSt; /* first ASCII code in font */ + short vFntWr; /* width of font form in bytes */ + short vHzRez; /* horizontal pixel resolution */ + short *vOffAd; /* address of font offset table */ + char vStat0; /* cursor display mode (look above) */ + char vDelay; /* cursor redisplay period */ + short vVtRez; /* vertical resolution of the screen */ + short bytesLin; /* copy of vLinWr for concat */ + short vPlanes; /* number of video planes */ + short vLinWr; /* number of bytes/video line */ + short *contrl; /* ptr to the CONTRL array */ + short *intin; /* ptr to the INTIN array */ + short *ptsin; /* ptr to the PTSIN array */ + short *intout; /* ptr to the INTOUT array */ + short *ptsout; /* ptr to the PTSOUT array */ + short fgBp1; /* foreground bit plane #1 value */ + short fgBp2; /* foreground bit plane #2 value */ + short fgBp3; /* foreground bit plane #3 value */ + short fgBp4; /* foreground bit plane #4 value */ + short lstLin; /* 0 => not last line of polyline */ + short lnMask; /* line style mask. */ + short wrtMode; /* writing mode. */ + short x1; /* X1 coordinate */ + short y1; /* Y1 coordinate */ + short x2; /* X2 coordinate */ + short y2; /* Y2 coordinate */ + short *patPtr; /* ptr to pattern. */ + short patMsk; /* pattern index. (mask) */ + short multiFill; /* multiplane fill flag. (0 => 1 plane) */ + short clip; /* clipping flag. */ + short xMnClip; /* x minimum clipping value. */ + short yMnClip; /* y minimum clipping value. */ + short xMxClip; /* x maximum clipping value. */ + short yMxClip; /* y maximum clipping value. */ + short xAccDda; /* accumulator for x DDA */ + short ddaInc; /* the fraction to be added to the DDA */ + short tSclsts; /* scale up or down flag. */ + short monoStatus; /* non-zero - cur font is monospaced */ + short sourceX; /* X coord of character in font */ + short sourceY; /* Y coord of character in font */ + short destX; /* X coord of character on screen */ + short destY; /* X coord of character on screen */ + short delX; /* width of character */ + short delY; /* height of character */ + short *fBase; /* pointer to font data */ + short fWidth; /* offset,segment and form with of font */ + short style; /* special effects */ + short liteMask; /* special effects */ + short skewMask; /* special effects */ + short weight; /* special effects */ + short rOff; /* Skew offset above baseline */ + short lOff; /* Skew offset below baseline */ + short scale; /* replicate pixels */ + short chUp; /* character rotation vector */ + short textFg; /* text foreground color */ + short *scrtchP; /* pointer to base of scratch buffer */ + short scrPt2; /* large buffer base offset */ + short textBg; /* text background color */ + short copyTran; /* cp rstr frm type flag (opaque/trans) */ + short (*quitFill)(); /* ptr to routine for quitting seedfill */ + short (*UserDevInit)(); /* ptr to user routine before dev_init */ + short (*UserEscInit)(); /* ptr to user routine before esc_init */ + long reserved2[8]; /* reserved */ + short (**routines)(); /* ptr to primitives vector list */ + void *curDev; /* ptr to a surrent device structure */ + short bltMode; /* 0: soft BiT BLiT 1: hard BiT BLiT */ + short reserved3; /* reserved */ + short reqXCol[240][3]; /* extended request color array */ + short *svBlkPtr; /* points to the proper save block */ + long fgBPlanes; /* fg bit plns flags (bit 0 is plane 0) */ + short fgBP5; /* foreground bitPlane #5 value. */ + short fgBP6; /* foreground bitPlane #6 value. */ + short fgBP7; /* foreground bitPlane #7 value. */ + short fgBP8; /* foreground bitPlane #8 value. */ + short _saveLen; /* height of saved form */ + short *_saveAddr; /* screen addr of 1st short of plane 0 */ + short _saveStat; /* cursor save status */ + long _saveArea[256]; /* save up to 8 planes. 16 longs/plane */ + short qCircle[80]; /* space to build circle coordinates */ + short bytPerPix; /* number of bytes per pixel (0 if < 1) */ + short formId; /* scrn form 2 ST, 1 stndrd, 3 pix */ + long vlColBg; /* escape background color (long value) */ + long vlColFg; /* escape foreground color (long value) */ + long palMap[256]; /* either a maping of reg's or true val */ + short (*primitives[40])(); /* space to copy vectors into */ +} VDIVARS; + +extern void sb_blank_internal(short x1, short y1, short x2, short y2); +extern int test_accel(void); + +#ifndef COLDFIRE + +void *cell_addr(short x, short y) /* Atari planes */ +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + return((void*)v_bas_ad + ((unsigned long)la->vLinWr * (unsigned long)la->vCelHt * (unsigned long)y) + ((unsigned long)la->vPlanes * ((unsigned long)x & ~1)) + ((unsigned long)x & 1) + (unsigned long)la->vCurOff); +} + +void *cell_addr2(short x, short y) /* no planes */ +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + return((void*)v_bas_ad + ((unsigned long)la->vLinWr * (unsigned long)la->vCelHt * (unsigned long)y) + ((unsigned long)la->vPlanes * (unsigned long)x) + (unsigned long)la->vCurOff); +} + +void sb_cell_c(unsigned char *src, unsigned char *dst, long fg, long bg) +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + short plane; + short fnt_wr = la->vFntWr; + short line_wr = la->vLinWr; + unsigned char *src_sav = src; + unsigned char *dst_sav = dst; + if((test_accel() && (la->vPlanes >= 8)) || (la->vPlanes >= 16)) + { + short y; + switch(la->vPlanes) + { + case 8: + for(y = la->vCelHt; y--;) + { + dst = dst_sav; /* reload dst */ + *dst++ = (*src_sav & 128) ? fg : bg; + *dst++ = (*src_sav & 64) ? fg : bg; + *dst++ = (*src_sav & 32) ? fg : bg; + *dst++ = (*src_sav & 16) ? fg : bg; + *dst++ = (*src_sav & 8) ? fg : bg; + *dst++ = (*src_sav & 4) ? fg : bg; + *dst++ = (*src_sav & 2) ? fg : bg; + *dst++ = (*src_sav & 1) ? fg : bg; + dst_sav += line_wr; /* top of block in next plane */ + src_sav += fnt_wr; + } + break; + case 16: + for(y = la->vCelHt; y--;) + { + short *dst = (short *)dst_sav; /* reload dst */ + *dst++ = (*src_sav & 128) ? fg : bg; + *dst++ = (*src_sav & 64) ? fg : bg; + *dst++ = (*src_sav & 32) ? fg : bg; + *dst++ = (*src_sav & 16) ? fg : bg; + *dst++ = (*src_sav & 8) ? fg : bg; + *dst++ = (*src_sav & 4) ? fg : bg; + *dst++ = (*src_sav & 2) ? fg : bg; + *dst++ = (*src_sav & 1) ? fg : bg; + dst_sav += line_wr; /* top of block in next plane */ + src_sav += fnt_wr; + } + break; + case 32: + for(y = la->vCelHt; y--;) + { + long *dst = (long *)dst_sav; /* reload dst */ + *dst++ = (*src_sav & 128) ? fg : bg; + *dst++ = (*src_sav & 64) ? fg : bg; + *dst++ = (*src_sav & 32) ? fg : bg; + *dst++ = (*src_sav & 16) ? fg : bg; + *dst++ = (*src_sav & 8) ? fg : bg; + *dst++ = (*src_sav & 4) ? fg : bg; + *dst++ = (*src_sav & 2) ? fg : bg; + *dst++ = (*src_sav & 1) ? fg : bg; + dst_sav += line_wr; /* top of block in next plane */ + src_sav += fnt_wr; + } + break; + } + } + else /* Atari planes */ + { + for(plane = la->vPlanes; plane--;) + { + short i; + src = src_sav; /* reload src */ + dst = dst_sav; /* reload dst */ + if(bg & 1) + { + if(fg & 1) + { + /* back:1 fore:1 => all ones */ + for (i = la->vCelHt; i--; ) + { + *dst = 0xff; /* inject a block */ + dst += line_wr; + } + } + else + { + /* back:1 fore:0 => invert block */ + for(i = la->vCelHt; i--;) + { + /* inject the inverted source block */ + *dst = ~*src; + dst += line_wr; + src += fnt_wr; + } + } + } + else + { + if(fg & 1) + { + /* back:0 fore:1 => direct substitution */ + for(i = la->vCelHt; i--;) + { + *dst = *src; + dst += line_wr; + src += fnt_wr; + } + } + else + { + /* back:0 fore:0 => all zeros */ + for(i = la->vCelHt; i--;) + { + *dst = 0x00; /* inject a block */ + dst += line_wr; + } + } + } + bg >>= 1; /* next background color bit */ + fg >>= 1; /* next foreground color bit */ + dst_sav += 2; /* top of block in next plane */ + } + } +} + +/* + * scroll_up - Scroll upwards + * + * + * Scroll copies a source region as wide as the screen to an overlapping + * destination region on a one cell-height offset basis. Two entry points + * are provided: Partial-lower scroll-up, partial-lower scroll-down. + * Partial-lower screen operations require the cell y # indicating the + * top line where scrolling will take place. + * + * After the copy is performed, any non-overlapping area of the previous + * source region is "erased" by calling blank_out which fills the area + * with the background color. + * + * in: + * top_line - cell y of cell line to be used as top line in scroll + */ +void sb_scrup_c(short top_line) +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + /* screen base addr + cell y nbr * cell wrap */ + unsigned char *dst = (unsigned char*)v_bas_ad + ((unsigned long)top_line * (unsigned long)la->vLinWr * (unsigned long)la->vCelHt); + /* form source address from cell wrap + base address */ + unsigned char *src = dst + ((unsigned long)la->vLinWr * (unsigned long)la->vCelHt); + /* form # of bytes to move */ + unsigned long count = ((unsigned long)la->vLinWr * (unsigned long)la->vCelHt) * ((unsigned long)la->vCelMy - (unsigned long)top_line); + /* move BYTEs of memory*/ + memmove(dst, src, count); + /* exit thru blank out, bottom line cell address y to top/left cell */ + sb_blank_internal(0, la->vCelMy, la->vCelMx, la->vCelMy); +} + +/* + * scroll_down - Scroll (partitially) downwards + */ +void sb_scrdn_c(short start_line) +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + /* screen base addr + offset for bottom of second to last cell row */ + unsigned char *src = (unsigned char*)v_bas_ad + ((unsigned long)start_line * (unsigned long)la->vLinWr * (unsigned long)la->vCelHt); + /* form destination from source + cell wrap */ + unsigned char *dst = src + ((unsigned long)la->vLinWr * (unsigned long)la->vCelHt); + /* form # of bytes to move */ + unsigned long count = (unsigned long)la->vLinWr * (unsigned long)la->vCelHt * ((unsigned long)la->vCelMy - (unsigned long)start_line); + /* move BYTEs of memory*/ + memmove(dst, src, count); + /* exit thru blank out */ + sb_blank_internal(0, start_line, la->vCelMx, start_line); +} + +/* + * blank_out - Fills region with the background color. + * + * Fills a cell-word aligned region with the background color. + * + * The rectangular region is specified by a top/left cell x,y and a + * bottom/right cell x,y, inclusive. Routine assumes top/left x is + * even and bottom/right x is odd for cell-word alignment. This is, + * because this routine is heavily optimized for speed, by always + * blanking as much space as possible in one rush. + * + * in: + * topx - top/left cell x position (must be even) + * topy - top/left cell y position + * botx - bottom/right cell x position (must be odd) + * boty - bottom/right cell y position + */ + +void sb_blank_c(short topx, short topy, short botx, short boty) +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + short row, rows, offs; + /* d2 = # of lines in region - 1 */ + rows = (boty - topy + 1) * la->vCelHt; + if((test_accel() && (la->vPlanes >= 8)) || (la->vPlanes >= 16)) + { + unsigned long *addr; /* running pointer to screen */ + unsigned long c; + short cell; + /* # of cell per row in region -1 */ + short cells = (botx - topx); /* # of characters */ + /* calculate the BYTE offset from the end of one row to next start */ + offs = la->vLinWr - cells * la->vPlanes; + switch(la->vPlanes) + { + case 8: + c = ((unsigned long)la->vColBg & 0xFF) + (((unsigned long)la->vColBg & 0xFF) << 8); + c |= (c << 16); + offs >>= 2; /* from BYTE to LONG offset */ + addr = (unsigned long *)cell_addr2(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + for(cell = cells; cell--;) + { + *addr++ = c; + *addr++ = c; + } + addr += offs; /* skip non-region area with stride advance */ + } + break; + case 16: + c = ((unsigned long)la->vlColBg & 0xFFFF) + ((unsigned long)la->vlColBg << 16); + offs >>= 2; /* from BYTE to LONG offset */ + addr = (unsigned long *)cell_addr2(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + for(cell = cells; cell--;) + { + *addr++ = c; + *addr++ = c; + *addr++ = c; + *addr++ = c; + } + addr += offs; /* skip non-region area with stride advance */ + } + break; + case 32: + c = (unsigned long)la->vlColBg; + offs >>= 2; /* from BYTE to LONG offset */ + addr = (unsigned long *)cell_addr2(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + for(cell = cells; cell--;) + { + *addr++ = c; + *addr++ = c; + *addr++ = c; + *addr++ = c; + *addr++ = c; + *addr++ = c; + *addr++ = c; + *addr++ = c; + } + addr += offs; /* skip non-region area with stride advance */ + } + break; + } + } + else /* Atari planes */ + { + short pair; + long pl01 = 0x00000000; /* bits on screen for planes 0 + 1 */ + long pl23 = 0x00000000; /* bits on screen for planes 2 + 3 */ + long pl45 = 0x00000000; /* bits on screen for planes 4 + 5 */ + long pl67 = 0x00000000; /* bits on screen for planes 6 + 7 */ + unsigned short color = la->vColBg; /* background color to d5 */ + /* # of cell-pairs per row in region -1 */ + short pairs = (botx - topx) / 2 + 1; /* pairs of characters */ + /* calculate the BYTE offset from the end of one row to next start */ + offs = la->vLinWr - pairs * 2 * la->vPlanes; + /* test for 1, 2 or 4 planes */ + switch(la->vPlanes) + { + case 8: + { + /* 8 planes */ + unsigned long *addr; /* running pointer to screen */ + /* set the high WORD of our LONG for plane 0 + 1 */ + if(color & 1) + pl01 = 0xffff0000; + /* set the low WORD of our LONG for plane 0 + 1 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl01 |= 0x0000ffff; + /* set the high WORD of our LONG for plane 2 + 3 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl23 = 0xffff0000; + /* set the low WORD of our LONG for plane 2 + 3 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl23 |= 0x0000ffff; + /* set the high WORD of our LONG for plane 4 + 5 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl45 = 0xffff0000; + /* set the low WORD of our LONG for plane 4 + 5 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl45 |= 0x0000ffff; + /* set the high WORD of our LONG for plane 6 + 7 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl67 = 0xffff0000; + /* set the low WORD of our LONG for plane 6 + 7 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl67 |= 0x0000ffff; + offs >>= 2; /* from BYTE to LONG offset */ + addr = (unsigned long *)cell_addr(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + /* loop through all cell pairs (LONG) */ + for(pair = pairs; pair--;) + { + *addr++ = pl01; /* fill background to planes 0 & 1 */ + *addr++ = pl23; /* fill background to planes 2 & 3 */ + *addr++ = pl45; /* fill background to planes 4 & 5 */ + *addr++ = pl67; /* fill background to planes 6 & 7 */ + } + addr += offs; /* skip non-region area with stride advance */ + } + } + break; + case 4: + { + /* 4 planes */ + unsigned long *addr; /* running pointer to screen */ + /* set the high WORD of our LONG for plane 0 + 1 */ + if(color & 0x1) + pl01 = 0xffff0000; + /* set the low WORD of our LONG for plane 0 + 1 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl01 |= 0x0000ffff; + /* set the high WORD of our LONG for plane 2 + 3 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl23 = 0xffff0000; + /* set the low WORD of our LONG for plane 2 + 3 */ + color = color >> 1; /* get next bit */ + if(color & 1) + pl23 |= 0x0000ffff; + offs >>= 2; /* from BYTE to LONG offset */ + addr = (unsigned long *)cell_addr(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + /* loop through all cell pairs (LONG) */ + for(pair = pairs; pair--;) + { + *addr++ = pl01; /* fill background to planes 0 & 1 */ + *addr++ = pl23; /* fill background to planes 2 & 3 */ + } + addr += offs; /* skip non-region area with stride advance */ + } + } + break; + case 2: + { + /* 2 planes */ + unsigned long *addr; /* running pointer to screen */ + /* set the high WORD of our LONG for plane 0 + 1 */ + if(color & 0x1) + pl01 = 0xffff0000; + /* set the low WORD of our LONG for plane 0 + 1 */ + color = color >> 1; /* get next bit */ + if(color & 0x1) + pl01 |= 0x0000ffff; + offs >>= 2; /* from BYTE to LONG offset */ + addr = (unsigned long *)cell_addr(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + /* loop through all cell pairs (LONG) */ + for(pair = pairs; pair--;) + *addr++ = pl01; /* fill background to planes 0 & 1 */ + addr += offs; /* skip non-region area with stride advance */ + } + } + break; + default: + { + /* if monochrome */ + unsigned short *addr; /* running pointer to screen */ + /* set the WORD for plane 0 */ + if(color & 0x0001) + pl01 = 0xffff; + offs >>= 1; /* from BYTE to WORD offset */ + addr = (unsigned short *)cell_addr(topx, topy); /* start address */ + /* do all rows in region */ + for(row = rows; row--;) + { + for(pair = pairs; pair--;) + *addr++ = pl01; /* fill background to planes 0 & 1 */ + addr += offs; /* skip non-region area with stride advance */ + } + } + break; + } + } +} + +void sb_neg_cell_c(short *cell) +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + short i, j; + la->disabCnt++; /* begin critical section */ + if((test_accel() && (la->vPlanes >= 8)) || (la->vPlanes >= 16)) + { + switch(la->vPlanes) + { + case 8: +#if 0 + if(la->vOffAd[1] == 16) + { + long *p = (long *)cell; + for(j = la->vCelHt; j--; p = (unsigned long *)((unsigned char *)p + la->vLinWr)) + { + p[0] = ~p[0]; + p[1] = ~p[1]; + p[2] = ~p[2]; + p[3] = ~p[3]; + } + cell++; + } + else +#endif + { + long *p = (long *)cell; + for(j = la->vCelHt; j--; p = (unsigned long *)((unsigned char *)p + la->vLinWr)) + { + p[0] = ~p[0]; + p[1] = ~p[1]; + } + cell++; + } + break; + case 16: +#if 0 + if(la->vOffAd[1] == 16) + { + long *p = (long *)cell; + for(j = la->vCelHt; j--; p = (unsigned long *)((unsigned char *)p + la->vLinWr)) + for(i =0; i < 8; p[i] = ~p[i], i++); + cell++; + } + else +#endif + { + long *p = (long *)cell; + for(j = la->vCelHt; j--; p = (unsigned long *)((unsigned char *)p + la->vLinWr)) + { + p[0] = ~p[0]; + p[1] = ~p[1]; + p[2] = ~p[2]; + p[3] = ~p[3]; + } + cell++; + } + break; + case 32: +#if 0 + if(la->vOffAd[1] == 16) + { + long *p = (long *)cell; + for(j = la->vCelHt; j--; p = (unsigned long *)((unsigned char *)p + la->vLinWr)) + for(i =0; i < 16; p[i] = ~p[i], i++); + cell++; + } + else +#endif + { + long *p = (long *)cell; + for(j = la->vCelHt; j--; p = (unsigned long *)((unsigned char *)p + la->vLinWr)) + { + p[0] = ~p[0]; + p[1] = ~p[1]; + p[2] = ~p[2]; + p[3] = ~p[3]; + p[4] = ~p[4]; + p[5] = ~p[5]; + p[6] = ~p[6]; + p[7] = ~p[7]; + } + cell++; + } + break; + } + } + else /* Atari planes */ + { + for(i = la->vPlanes; i--;) + { +#if 0 + if(la->vOffAd[1] == 16) + { + short *p = cell; + for(j = la->vCelHt; j--; p = (unsigned short *)((unsigned char *)p + la->vLinWr)) + *p = ~*p; + cell++; + } + else +#endif + { + char *p = (char *)cell; + for(j = la->vCelHt; j--; p += la->vLinWr) + *p = ~*p; + cell++; + } + } + } + la->disabCnt--; /* end critical section */ +} + +void sb_move_cursor_c(short x, short y) +{ + VDIVARS *la = (VDIVARS*)(LINEA_VARS - LA_OFFSET); + la->disabCnt++; /* begin critical section */ + if(la->vStat0 & M_CSTATE) /* cursor flash state */ + { + /* cursor is currently visible, remove it */ + la->vStat0 &= ~M_CSTATE; + sb_neg_cell_c(la->vCurAd); + } + /* clip cursor coordinates */ + if(x > la->vCelMx) + x = la->vCelMx; + if(y > la->vCelMy) + y = la->vCelMy; + /* set cursor position */ + la->vCurCx = x; + la->vCurCy = y; + if((test_accel() && (la->vPlanes >= 8)) || (la->vPlanes >= 16)) + la->vCurAd = cell_addr2(x, y); + else /* Atari planes */ + la->vCurAd = cell_addr(x, y); + /* redisplay cursor if applicable */ + if(!la->vDelay) + { + if(la->disabCnt == 1) + { + sb_neg_cell_c(la->vCurAd); + la->vStat0 |= M_CSTATE; + la->vCurTim = la->vCTInit; + } + } + else + la->vCurTim = la->vDelay; + la->disabCnt--; /* end critical section */ +} + +#endif diff --git a/flash.tos/tos/debug.S b/flash.tos/tos/debug.S deleted file mode 100644 index 1c55f04..0000000 --- a/flash.tos/tos/debug.S +++ /dev/null @@ -1,31 +0,0 @@ -/* Debug the CT60 - * - * Didier Mequignon, January 2003, e-mail: aniplay@wanadoo.fr - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - .text - - .globl exception - - .align 2 - .long 0x100C - .long end1-begin1+0x80000000 -begin1: - jmp exception -end1: - - diff --git a/flash.tos/tos/debug2.S b/flash.tos/tos/debug2.S deleted file mode 100644 index 2065f3c..0000000 --- a/flash.tos/tos/debug2.S +++ /dev/null @@ -1,836 +0,0 @@ -/* Debug the CT60 - * - * Didier Mequignon, 2003-2006, e-mail: aniplay@wanadoo.fr - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - - .globl exception - -#ifdef COLDFIRE - .globl null - -#include "fire.h" -#endif - -#include "vars.h" - -// #define DEBUG - - .text - -#ifdef COLDFIRE - -null: - clr.l 0x380 // not valid - move.l SP,0x3C0 - move.l A6,0x3BC - lea 0x384,A6 - movem.l D0-D7/A0-A5,(A6) - clr.l 0x3C8 // USP - moveq #-1,D1 -#endif - -exception: - - clr.l memvalid - lea.l mess1(PC),A0 - bsr display_string -#ifdef COLDFIRE - ext.l D1 - addq.l #1,D1 - move.l D1,D7 // vector number -#else - addq.w #1,D1 - move.w D1,D7 // vector number -#endif - moveq #0,D0 - move.w D7,D0 -#ifdef COLDFIRE - .chip 68060 - divu #10,D0 - .chip 5200 - move.l D0,D1 - and.l #7,D0 - beq.s .ex1 - or.l #0x30,D0 - bsr display_char -.ex1: - swap D1 - move.w D1,D0 - or.l #0x30,D0 -#else - divu #10,D0 - and.w #7,D0 - beq.s .ex1 - or.w #0x30,D0 - bsr display_char -.ex1: - swap d0 - or.w #0x30,D0 -#endif - bsr display_char - moveq #0x3A,D0 - bsr display_char - moveq #0x20,D0 - bsr display_char - lea.l tab_mess_exc(PC),A0 - move.w D7,D0 - bsr display_tab - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char -#ifdef COLDFIRE - tst.w D7 - beq .ex0 -#endif - lea.l mess2(PC),A0 // SR - bsr display_string -#ifdef COLDFIRE - move.w save_sr,D0 // SR -#else - move.l 0x3C0,A0 //SSP - move.w (A0),D0 -#endif - bsr hex_word // SR - lea.l mess3(PC),A0 - bsr display_string -#ifdef COLDFIRE - move.w save_sr,D2 // SR - and.l #0xB71F,D2 -#else - move.l 0x3C0,A0 //SSP - move.w (A0),D2 // SR - and.w #0xB71F,D2 -#endif - lea.l tab_status(PC),A1 - moveq #15,D1 -.ex5: - btst.l D1,D2 - beq.s .ex6 - moveq #0,D0 - move.b (A1,D1),D0 - move.w D0,D3 -#ifdef COLDFIRE - and.l #0xF8,D3 - cmp.l #0x30,D3 -#else - and.w #0xF8,D3 - cmp.w #0x30,D3 -#endif - bne.s .ex4 - move.w D0,-(SP) - moveq #0x49,D0 // I - bsr display_char - move.w (SP)+,D0 -.ex4: - bsr display_char - moveq #0x20,D0 - bsr display_char -.ex6: -#ifdef COLDFIRE - subq.l #1,D1 - bpl.s .ex5 -.ex0: -#else - dbf D1,.ex5 -#endif - lea.l mess4(PC),A0 // PC - bsr display_string -#ifdef COLDFIRE - move.l save_pc,D0 // PC -#else - move.l 0x3C0,A0 // SSP - move.l 2(A0),D0 // PC -#endif - bsr hex_long - lea.l mess10(PC),A0 // Basepage - bsr display_string - move.l 0x6EE4,D0 - bsr hex_long -#ifdef COLDFIRE - tst.w D7 - beq .ex2 -#endif - lea.l mess5(PC),A0 // CACR - bsr display_string -#ifdef COLDFIRE - .chip 68060 - movec.l CACR,D0 // from value stored in the CF68KLIB - .chip 5200 - bsr hex_long - cmp.l #2,D7 - bne.s .ex2 - lea.l mess6(PC),A0 // address fault - bsr display_string - move.l address_fault,D0 // from value stored in the CF68KLIB - bsr hex_long -#else /* ATARI - CT60 */ - movec.l CACR,D0 - bsr hex_long - cmp.w #2,D7 - beq.s .ex3 // Acces Fault - cmp.w #3,D7 - beq.s .ex3 // Adress Error - cmp.w #5,D7 - beq.s .ex3 // Zero Divide - cmp.w #9,D7 - bne .ex2 // <> Trace -.ex3: - lea.l mess6(PC),A0 // address fault - bsr display_string - move.l 0x3C0,A0 // SSP - move.l 8(A0),D0 // address fault - bsr hex_long - cmp.w #2,D7 - bne .ex2 // <> Acces Fault - lea.l mess7(PC),A0 // FSLW - bsr display_string - move.l 0x3C0,A0 // SSP - move.l 12(A0),D0 // FSLW - bsr hex_long - lea.l mess3(PC),A0 - bsr display_string - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char - move.l 0x3C0,A0 // SSP - move.l 12(A0),D2 // FSLW - and.l #0x0BFFFFFD,D2 - lea.l tab_fslw1(PC),A1 - lea.l tab_fslw2(PC),A2 - lea.l tab_fslw3(PC),A3 - moveq #31,D1 - moveq #0,D3 -.ex13: - btst.l D1,D2 - beq.s .ex14 - moveq #0,D0 - move.b (A1,D3),D0 - bsr display_char - moveq #0,D0 - move.b (A2,D3),D0 - cmp.b #0x20,D0 - beq.s .ex12 - bsr display_char - moveq #0,D0 - move.b (A3,D3),D0 - cmp.b #0x20,D0 - beq.s .ex12 - bsr display_char -.ex12: - moveq #0x20,D0 - bsr display_char -.ex14: - addq.w #1,D3 - dbf D1,.ex13 -#endif /* COLDFIRE */ -.ex2: - lea.l mess8(PC),A0 // SSP - bsr display_string - move.l 0x3C0,D0 // SSP - bsr hex_long - lea.l mess9(PC),A0 // USP - bsr display_string - move.l 0x3C8,D0 // USP - bsr hex_long - lea.l 0x384,A1 // registers - lea.l 32(A1),A2 - moveq #7,D1 -.ex8: - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char - moveq #0x44,D0 - bsr display_char - moveq #7,D0 -#ifdef COLDFIRE - sub.l D1,D0 - or.l #0x30,D0 -#else - sub.w D1,D0 - or.w #0x30,D0 -#endif - move.w D0,-(SP) - bsr display_nb - move.l (A1),D0 - bsr hex_long // data registers - moveq #0x20,D0 - bsr display_char - tst.w D1 - beq.s .ex9 - moveq #0x41,D0 - bsr display_char - move.w (SP),D0 - bsr display_nb - move.l (A2),D0 - bsr hex_long // address registers - moveq #0x20,D0 - bsr display_char -.ex9: - addq.l #2,SP - addq.l #4,A1 - addq.l #4,A2 -#ifdef COLDFIRE - subq.l #1,D1 - bpl.s .ex8 -#else - dbf D1,.ex8 -#endif - moveq #13,D0 - bsr display_char -.loop_wait_key: -#ifdef COLDFIRE -#ifdef DEBUG - move.w #1,-(SP) // AUX -#else - move.w #2,-(SP) // CON -#endif -#else - move.w #2,-(SP) // CON -#endif - move.w #2,-(SP) // Bconin - trap #13 - addq.l #4,SP - ext.l D0 - move.l D0,-(SP) - move.l #0x5F504349,D0 - lea 0xED0000,A0 // 128 KB - cmp.l (A0),D0 // _PCI - beq.s .pci_drivers - lea 0xEC0000,A0 // 192 KB - cmp.l (A0),D0 // _PCI - beq.s .pci_drivers - lea 0xEB0000,A0 // 256 KB - cmp.l (A0),D0 // _PCI - beq.s .pci_drivers - lea 0xEA0000,A0 // 320 KB - cmp.l (A0),D0 // _PCI - bne.s .no_pci_drivers -.pci_drivers: - jsr 40(A0) // drivers PCI in flash, add dbug (68k disassembler) - move.l D0,(SP) - bne .no_pci_drivers - addq.l #4,SP - bra.s .loop_wait_key -.no_pci_drivers: - move.l (SP)+,D0 -#ifdef COLDFIRE - and.l #0xFF,D0 - cmp.l #0x6D,D0 // m -#else - cmp.b #0x6D,D0 // m -#endif - beq.s .memory_dump -#ifdef COLDFIRE - cmp.l #0x70,D0 // p -#else - cmp.b #0x70,D0 // p -#endif - beq.s .patch_memory -#ifdef DEBUG -#ifdef COLDFIRE - cmp.l #0x20,D0 -#else - cmp.b #0x20,D0 -#endif - bne .loop_wait_key - lea mess14(PC),A0 - bsr display_string -#endif - rts -.memory_dump: - lea mess11(PC),A0 // memory dump - bsr display_string - bsr get_hex_value - move.l D0,A0 - bsr dump - bra .loop_wait_key -.patch_memory: - lea mess12(PC),A0 // patch memory - bsr display_string - bsr get_hex_value - move.l D0,A1 - lea mess13(PC),A0 // value - bsr display_string - bsr get_hex_value - cmp.l #0x100,D0 - bcc.s .word_value - move.b D0,(A1) - lea crlf(PC),A0 - bsr display_string - move.l A1,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - move.b (A1),D0 - bsr hex_byte - bra .loop_wait_key -.word_value: - cmp.l #0x10000,D0 - bcc.s .long_value - move.w D0,(A1) - lea crlf(PC),A0 - bsr display_string - move.l A1,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - move.w (A1),D0 - bsr hex_word - bra .loop_wait_key -.long_value: - move.l D0,(A1) - lea crlf(PC),A0 - bsr display_string - move.l A1,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - move.l (A1),D0 - bsr hex_long - bra .loop_wait_key - -display_nb: - - bsr display_char - moveq #0x3A,D0 - bsr display_char - moveq #0x24,D0 - bsr display_char - rts - -display_tab: - -#ifdef COLDFIRE - move.l D1,-(SP) -#endif - move.w D0,-(SP) - moveq #0,D0 -.dt1: -#ifdef COLDFIRE - move.b (A0),D1 - extb.l D1 - cmp.l #-1,D1 - beq.s .dt3 - moveq #0,D1 - move.w (SP),D1 - cmp.l D1,D0 -#else - cmp.b #-1,(A0) - beq.s .dt3 - cmp.w (SP),D0 -#endif - beq.s .dt4 -.dt2: - tst.b (A0)+ - bne.s .dt2 -#ifdef COLDFIRE - addq.l #1,D0 -#else - addq.w #1,D0 -#endif - bra.s .dt1 -.dt4: - bsr display_string -.dt3: - - addq.l #2,SP -#ifdef COLDFIRE - move.l (SP)+,D1 -#endif - rts - -hex_long: - move.l D0,-(SP) - swap D0 - bsr.s hex_word - move.l (SP)+,D0 -hex_word: - move.w D0,-(SP) -#ifdef COLDFIRE - lsr.l #8,D0 - bsr.s hex_byte - move.w (SP)+,D0 -hex_byte: - move.w D0,-(SP) - lsr.l #4,D0 - bsr.s hex_char - move.w (SP)+,D0 -hex_char: - and.l #0xF,D0 - or.l #0x30,D0 - cmp.l #0x3A,D0 - bcs.s display_char - addq.l #7,D0 - -display_char: - and.l #0xFF,D0 -#ifdef DEBUG /* warning !!! If serial mouse */ - move.l D1,-(SP) -.wait_uart: - move.b MCF_UART_USR0,D1 - and.l #MCF_UART_USR_TXRDY,D1 - beq.s .wait_uart - move.b D0,MCF_UART_UTB0 // send the character - move.l (SP)+,D1 -#else - lea -24(SP),SP - movem.l D0-D2/A0-A2,(SP) - move.w D0,-(sp) - move.w #2,-(SP) - move.w #3,-(SP) // Bconout - trap #13 - addq.l #6,SP - movem.l (SP),D0-D2/A0-A2 - lea 24(SP),SP -#endif /* DEBUG */ - rts -#else /* ATARI */ - lsr.w #8,D0 - bsr.s hex_byte - move.w (SP)+,D0 -hex_byte: - move.w D0,-(SP) - lsr.b #4,D0 - bsr.s hex_char - move.w (SP)+,D0 -hex_char: - and.b #0xF,D0 - or.b #0x30,D0 - cmp.b #0x3A,D0 - bcs.s display_char - addq.b #7,D0 - -display_char: - and.w #0xFF,D0 - movem.l D0-D2/A0-A2,-(SP) - move.w D0,-(sp) - move.w #2,-(SP) - move.w #3,-(SP) // Bconout - trap #13 - addq.l #6,SP - movem.l (SP)+,D0-D2/A0-A2 - rts -#endif /* COLDFIRE */ - -display_string: - -#ifdef COLDFIRE - move.l D0,-(SP) - move.l A0,-(SP) -#else - movem.l D0/A0,-(SP) -#endif -.os2: - move.b (A0)+,D0 - beq.s .os1 - bsr display_char - bra.s .os2 -.os1: -#ifdef COLDFIRE - move.l (SP)+,A0 - move.l (SP)+,D0 -#else - movem.l (SP)+,D0/A0 -#endif - rts - -get_hex_value: - -#ifdef COLDFIRE - lea -56(SP),SP - movem.l D1-A5,(SP) - link A6,#-8 - moveq #0,D7 -.loop_get_value: -#ifdef DEBUG - move.w #1,-(SP) // AUX -#else - move.w #2,-(SP) // CON -#endif - move.w #2,-(SP) // Bconin - trap #13 - addq.l #4,SP - and.l #0xFF,D0 - cmp.l #13,D0 - beq.s .conv_get_value - cmp.l #8,D0 - bne.s .not_backspace - tst.w D7 - ble.s .loop_get_value - bsr display_char - subq.l #1,D7 - bra.s .loop_get_value -.not_backspace: - cmp.l #0x30,D0 - bcs.s .loop_get_value - cmp.l #0x39,D0 - bls.s .number_value - cmp.l #0x41,D0 - bcs.s .loop_get_value - cmp.l #0x46,D0 - bls.s .letter_value - cmp.l #0x61,D0 - bcs.s .loop_get_value - cmp.l #0x66,D0 - bhi.s .loop_get_value -.letter_value: - bsr display_char - and.l #0x0F,D0 - add.l #9,D0 - bra.s .store_value -.number_value: - bsr display_char - and.l #0x0F,D0 -.store_value: - move.b D0,-8(A6,D7) - addq.l #1,D7 - cmp.l #8,D7 - bcs .loop_get_value -.conv_get_value: - moveq #0,D0 - subq.l #1,D7 - bmi.s .end_get_value - moveq #0,D6 -.loop_value: - asl.l #4,D0 - moveq #0,D1 - move.b -8(A6,D6),D1 - or.l D1,D0 - addq.l #1,D6 - subq.l #1,D7 - bpl.s .loop_value -.end_get_value: - tst.l D0 - unlk A6 - movem.l (SP),D1-A5 - lea 56(SP),SP -#else /* ATARI */ - movem.l D1-A5,-(SP) - link A6,#-8 - moveq #0,D7 -.loop_get_value: - move.w #2,-(SP) // CON - move.w #2,-(SP) // Bconin - trap #13 - addq.l #4,SP - cmp.b #13,D0 - beq.s .conv_get_value - cmp.b #8,D0 - bne.s .not_backspace - tst.w D7 - ble.s .loop_get_value - bsr display_char - subq.w #1,D7 - bra.s .loop_get_value -.not_backspace: - cmp.b #0x30,D0 - bcs.s .loop_get_value - cmp.b #0x39,D0 - bls.s .number_value - cmp.b #0x41,D0 - bcs.s .loop_get_value - cmp.b #0x46,D0 - bls.s .letter_value - cmp.b #0x61,D0 - bcs.s .loop_get_value - cmp.b #0x66,D0 - bhi.s .loop_get_value -.letter_value: - bsr display_char - and.b #0x0F,D0 - add.b #9,D0 - bra.s .store_value -.number_value: - bsr display_char - and.b #0x0F,D0 -.store_value: - move.b D0,-8(A6,D7) - addq.w #1,D7 - cmp.w #8,D7 - bcs.s .loop_get_value -.conv_get_value: - moveq #0,D0 - subq.w #1,D7 - bmi.s .end_get_value - moveq #0,D6 -.loop_value: - asl.l #4,D0 - or.b -8(A6,D6),D0 - addq.w #1,D6 - dbf D7,.loop_value -.end_get_value: - tst.l D0 - unlk A6 - movem.l (SP)+,D1-A5 -#endif /* COLDFIRE */ - rts - -dump: - -#ifdef COLDFIRE - lea -20(SP),SP - movem.l D0-D2/A0-A1,(SP) -#else - movem.l D0-D2/A0-A1,-(SP) -#endif - move.l A0,A1 - moveq #3,D1 -.loop_dump1: - lea crlf(PC),A0 - bsr display_string - move.l A1,D0 - bsr hex_long - moveq #0x20,D0 - bsr display_char - moveq #15,D2 -.loop_dump2: - move.b (A1)+,D0 - bsr hex_byte - moveq #0x20,D0 - bsr display_char -#ifdef COLDFIRE - subq.l #1,D2 - bpl.s .loop_dump2 -#else - dbf D2,.loop_dump2 -#endif - lea -16(A1),A1 - moveq #15,D2 -.loop_dump3: - move.b (A1)+,D0 -#ifdef COLDFIRE - and.l #0xFF,D0 - cmp.l #0x20,D0 - bcs.s .dump_bad_char - cmp.l #0x7F,D0 -#else - cmp.b #0x20,D0 - bcs.s .dump_bad_char - cmp.b #0x7F,D0 -#endif - bcs.s .dump_ok -.dump_bad_char: - moveq #0x2E,D0 -.dump_ok: - bsr display_char -#ifdef COLDFIRE - subq.l #1,D2 - bpl.s .loop_dump3 - subq.l #1,D1 - bpl.s .loop_dump1 - movem.l (SP),D0-D2/A0-A1 - lea 20(SP),SP -#else - dbf D2,.loop_dump3 - dbf D1,.loop_dump1 - movem.l (SP)+,D0-D2/A0-A1 -#endif - rts - -crlf: .byte 13,10,0 -mess1: .byte 13,10 - .asciz "EXCEPTION PROCESSING " -mess2: .byte 13,10 - .asciz "Status Register (SR): $" -mess3: .asciz ", bits to 1: " -mess4: .byte 13,10 - .asciz "Program Counter (PC): $" -mess5: .byte 13,10 - .asciz "Cache Register (CACR): $" -mess6: .byte 13,10 - .asciz "Address Fault: $" -mess7: .byte 13,10 - .asciz "Fault Status Word (FSLW): " -mess8: .byte 13,10 - .asciz "Supervisor Stack (SSP): $" -mess9: .byte 13,10 - .asciz "User Stack (USP): $" -mess10: .byte 13,10 - .asciz "Basepage: $" -mess11: .byte 13,10 - .asciz "Memory dump (hex) ? " -mess12: .byte 13,10 - .asciz "Patch memory (hex) ? " -mess13: .byte 13,10 - .asciz "Value (hex) ? " -mess14: .byte 13,10 - .ascii "Pterm" - .byte 13,10,0 - -tab_mess_exc: -#ifdef COLDFIRE - .asciz "Null (jump or call)" -#else - .byte 0 -#endif - .byte 0 - .asciz "Access Fault" - .asciz "Address Error" - .asciz "Illegal Instruction" - .asciz "Integer Zero Divide" - .byte 0 - .byte 0 - .asciz "Privilege Violation" - .asciz "Trace" - .asciz "Line A" - .asciz "Line F" - .asciz "Emulator Interrupt" - .byte 0 - .asciz "Format Error" - .asciz "Uninitialised Interrupt" - .byte 0 - .byte 0 - .byte 0 - .byte 0 - .byte 0 - .byte 0 - .byte 0 - .byte 0 - .asciz "Spurious Interrupt" - .asciz "Interrupt level 1" - .asciz "Interrupt level 2" - .asciz "Interrupt level 3" - .asciz "Interrupt level 4" - .asciz "Interrupt level 5" - .asciz "Interrupt level 6" - .asciz "Interrupt level 7" - .asciz "Trap #0" - .asciz "Trap #1" - .asciz "Trap #2" - .asciz "Trap #3" - .asciz "Trap #4" - .asciz "Trap #5" - .asciz "Trap #6" - .asciz "Trap #7" - .asciz "Trap #8" - .asciz "Trap #9" - .asciz "Trap #10" - .asciz "Trap #11" - .asciz "Trap #12" - .asciz "Trap #13" - .asciz "Trap #14" - .asciz "Trap #15" - .byte -1 - -tab_status: .ascii "CVZNX 012 MS T" - -tab_fslw1: .ascii " M LRWSSTTTTTIPSPPIPSWTRWTB S" -tab_fslw2: .ascii " A K ZZTTMMMOBBTTLFPPWEETP S" -tab_fslw3: .ascii " 1010210 EEAB E RE E" diff --git a/flash.tos/tos/end.S b/flash.tos/tos/end.S deleted file mode 100644 index fc00376..0000000 --- a/flash.tos/tos/end.S +++ /dev/null @@ -1,31 +0,0 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ - - .globl end_flash - - .text - -end_flash: - - .align 2 - .long -1 diff --git a/flash.tos/tos/extvidel.S b/flash.tos/tos/extvidel.S index a6fc419..b990d7c 100644 --- a/flash.tos/tos/extvidel.S +++ b/flash.tos/tos/extvidel.S @@ -1,4 +1,4 @@ -/* Extended videl screens CT60 +/* Extended videl screens CT60 (for ataboot) * * Didier Mequignon May 2004, e-mail: aniplay@wanadoo.fr * diff --git a/flash.tos/tos/fan.S b/flash.tos/tos/fan.S new file mode 100644 index 0000000..067f720 --- /dev/null +++ b/flash.tos/tos/fan.S @@ -0,0 +1,99 @@ +/* CT60 Speed FAN on IO3 MFP + * + * Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "vars.h" + +#ifndef COLDFIRE + + .globl init_speed_fan + +init_speed_fan: + + movem.l D0-D2/A0-A2,-(SP) + move.l phystop,A0 + clr.w count_io3_mfp(A0) + move.l _hz_200,start_hz_200(A0) + pea inter_io3_mfp(PC) + move.w #67,-(SP) // IO3 MFP + move.w #5,-(SP) // Setexec + trap #13 + addq.l #8,SP + move.w #3,-(SP) // IO3 MFP + move.w #27,-(SP) // Jenabint + trap #14 + addq.l #4,SP + move.l _hz_200,D0 + add.l #100,D0 // tempo 0.5 S +.tempo_test_fan: + move.l _hz_200,D1 + cmp.l D0,D1 + blt.s .tempo_test_fan + move.l phystop,A0 + cmp.w #5,count_io3_mfp(A0) + bcc.s .no_int + move.w #3,-(SP) // IO3 MFP + move.w #26,-(SP) // Jdisint + trap #14 + addq.l #4,SP +.no_int: + movem.l (SP)+,D0-D2/A0-A2 + rts + + dc.l 0x58425241 // XBRA + dc.l 0x43543630 // CT60 + dc.l 0 + +inter_io3_mfp: + + movem.l D0/A0,-(SP) + move.l phystop,A0 + addq.w #1,count_io3_mfp(A0) + move.l _hz_200,D0 + sub.l start_hz_200(A0),D0 + cmp.l #1000,D0 // 5 S + bcs.s .end_inter + move.l _hz_200,start_hz_200(A0) + move.l cookie,D0 + beq.s .end_inter + move.l D0,A0 +.loop_cookie_inter: + tst.l (A0) + beq.s .end_inter + cmp.l #0x43543630,(A0) // CT60 + bne.s .next_cookie_inter + move.l 4(A0),D0 + beq.s .end_inter + move.l phystop,A0 + move.w count_io3_mfp(A0),-(SP) + clr.w count_io3_mfp(A0) + move.l D0,A0 + move.w (SP)+,D0 + mulu #6,D0 // tr/mn + move.w D0,6(A0) // speed_fan + bra.s .end_inter +.next_cookie_inter: + addq.l #8,A0 + bra.s .loop_cookie_inter +.end_inter: + movem.l (SP)+,D0/A0 + bclr #3,0xFFFFFA11 // ISRB + rte + +#endif /* !COLDFIRE */ + diff --git a/flash.tos/tos/gemdos2.S b/flash.tos/tos/gemdos2.S index 1e5fb99..924c53a 100644 --- a/flash.tos/tos/gemdos2.S +++ b/flash.tos/tos/gemdos2.S @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include "main.h" #include "ct60.h" #include "vars.h" #ifdef COLDFIRE @@ -299,7 +300,7 @@ x20_inq: xi_exit: rte -#ifdef DEBUG +#if 1 // #ifdef DEBUG debug1: .asciz "GEMDOS #0x" @@ -408,9 +409,15 @@ flush_cache_pexec: move.w #rw_parameter,-(SP) trap #14 lea 12(SP),SP + cmp.l #-1,D0 + beq.s .normal btst #0,D0 beq.s .normal +#ifdef COLDFIRE + jsr caches_disable +#else jsr 0xE0085A // caches off +#endif move.l phystop,A0 clr.l save_hz_200(A0) move.l #0x12345678,D0 @@ -565,10 +572,7 @@ det_vbl: movem.l D0/A0,-(SP) tst.b _frclock+3 bne.s .no_test_vectors - lea _init_emulation_vectors,A0 - add.l #0xE80000,A0 - sub.l #_ct60tos_half_flash,A0 - jsr (A0) + jsr _init_emulation_vectors #endif .no_test_vectors: #ifdef COLDFIRE @@ -630,7 +634,11 @@ det_vbl: cmp.l #DELAY_CACHE,D0 // delay bcs.s .vb3 clr.l flag_cache(A0) +#ifdef COLDFIRE + jsr caches_enable +#else jsr 0xE250C8 // caches on +#endif .vb3: #ifdef COLDFIRE move.l (SP)+,A0 @@ -719,6 +727,8 @@ end_fread: move.w #rw_parameter,-(SP) trap #14 lea 12(SP),SP + cmp.l #-1,D0 + beq .ef2 btst #1,D0 beq .ef2 // no Fread test move.l etv_critic,A0 // AES valid ? @@ -780,7 +790,11 @@ end_fread: cmp.w #1,D0 // delay #endif bne.s .ef5 +#ifdef COLDFIRE + jsr caches_disable +#else jsr 0xE0085A // caches off +#endif move.l phystop,A0 clr.l save_hz_200(A0) #ifdef COLDFIRE diff --git a/flash.tos/tos/half.S b/flash.tos/tos/half.S deleted file mode 100644 index 4c318cd..0000000 --- a/flash.tos/tos/half.S +++ /dev/null @@ -1,31 +0,0 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ - - .globl _ct60tos_half_flash - - .text - - .align 2 - .long 0x80000 - .long end_flash-_ct60tos_half_flash -_ct60tos_half_flash: diff --git a/flash.tos/tos/i2c.S b/flash.tos/tos/i2c.S new file mode 100644 index 0000000..7767e93 --- /dev/null +++ b/flash.tos/tos/i2c.S @@ -0,0 +1,536 @@ +/* CT60 I2C routines + * Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef COLDFIRE + +#define _gpip_mfp 0xfffffa01 +#define _ddr_mfp 0xfffffa05 +#define _iera_mfp 0xfffffa07 // MFP registers +#define _ipra_mfp 0xfffffa0b +#define _isra_mfp 0xfffffa0f +#define _imra_mfp 0xfffffa13 +#define _tbcr_mfp 0xfffffa1b +#define _tbdr_mfp 0xfffffa21 // timer B +#define _tcdr_mfp 0xfffffa23 // timer C +#define _scl_low 0xf0000000 // write 0 to SCL line (clock) +#define _scl_high 0xf0400000 // write 1 to SCL line (clock) +#define _sda_low 0xf0800000 // write 0 to SDA line (data) +#define _sda_high 0xf0c00000 // write 1 to SDA line (data) +#define _sda 0xf0000000 // read from SDA line on the D0 CPU data bus + +#define CT60_READ_ERROR -1 + +#define WAIT_US bsr wait_26us + + .globl read_seq_device_i2c + .globl write_seq_device_i2c + .globl read_i2c + .globl write_i2c + + .text + +read_seq_device_i2c: // D0.L: address, D0.H: device, D1: len (bytes), A0: 128 bytes buffer, D0 return error + + movem.l D1-D4/A0-A3,-(SP) + move.l D0,D4 + swap D4 // device + move.w D1,D3 // len (bytes) + move.l A0,A3 + move SR,-(SP) + or #0x700,SR // no interrupts + lea .ri1(PC),A0 + move.l 8,A1 // bus error + move.l A0,8 + move.l SP,A2 + lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) + tst.b _tbcr_mfp + bne.s .ri6 // timer B used + bclr #0,_imra_mfp + bclr #0,_iera_mfp + bclr #0,_ipra_mfp + bclr #0,_isra_mfp + lea _tbdr_mfp,A0 + move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) + move.b #3,_tbcr_mfp // 2.4576MHz/16 +.ri6: + bsr start_bit_i2c + move.l A1,8 + move.l A2,SP + move.w D4,D0 // device + bsr write_device_i2c + moveq #0,D0 // write address + bsr write_bit_i2c // r/w + bsr read_bit_i2c // ack + btst #0,D0 + bne .ri3 // no acknoledge + swap D4 // address + moveq #0,D0 + add.b D4,D4 + addx.b D0,D0 // address 1st bit + bsr write_bit_wait_slave_i2c + moveq #6,D2 // 8 bits +.ri4: + moveq #0,D0 + add.b D4,D4 + addx.b D0,D0 // address + bsr write_bit_i2c + dbf D2,.ri4 + bsr read_bit_i2c // ack + bne.s .ri3 // no acknoledge + bsr start_bit_wait_slave_i2c + swap D4 + move.w D4,D0 // device + bsr write_device_i2c + moveq #1,D0 // read data + bsr write_bit_i2c // r/w + bsr read_bit_i2c // ack + btst #0,D0 + bne.s .ri3 // no acknoledge + subq.w #1,D3 // len (bytes) -1 + bpl.s .ri8 + moveq #0,D3 +.ri8: + moveq #0,D1 // data + bsr read_bit_wait_slave_i2c // 1st bit + lsr.l #1,D0 // data + addx.w D1,D1 + moveq #6,D2 // 8 bits +.ri5: + bsr read_bit_i2c + lsr.l #1,D0 // data + addx.w D1,D1 + dbf D2,.ri5 + move.b D1,(A3)+ + tst D3 + seq.b D0 + and #1,D0 // ack master = 1 => no other byte + bsr write_bit_i2c + dbf D3,.ri8 + bsr stop_bit_i2c + moveq #0,D0 // OK + bra.s .ri2 +.ri3: + bsr stop_bit_i2c + moveq #CT60_READ_ERROR,D0 // error + bra.s .ri2 +.ri1: + moveq #CT60_READ_ERROR,D0 // bus error + move.l A1,8 + move.l A2,SP +.ri2: + lea _tbdr_mfp,A1 + cmp.l A0,A1 + bne.s .ri7 + clr.b _tbcr_mfp // timer B stopped +.ri7: + move.w (SP)+,SR + tst.l D0 + movem.l (SP)+,D1-D4/A0-A3 + rts + +write_seq_device_i2c: // D0.L: address, D0.H: device, D1: len (bytes), A0: buffer, D0 return error + + movem.l D1-D4/A0-A3,-(SP) + move.l D0,D4 + swap D4 // device + move.w D1,D3 // len (bytes) + move.l A0,A3 + move SR,-(SP) + or #0x700,SR // no interrupts + lea .wi1(PC),A0 + move.l 8,A1 // bus error + move.l A0,8 + move.l SP,A2 + lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) + tst.b _tbcr_mfp + bne.s .wi6 // timer B used + bclr #0,_imra_mfp + bclr #0,_iera_mfp + bclr #0,_ipra_mfp + bclr #0,_isra_mfp + lea _tbdr_mfp,A0 + move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) + move.b #3,_tbcr_mfp // 2.4576MHz/16 +.wi6: + bsr start_bit_i2c + move.l A1,8 + move.l A2,SP + move.w D4,D0 // device + bsr write_device_i2c + moveq #0,D0 // write address + bsr write_bit_i2c // r/w + bsr read_bit_i2c // ack + btst #0,D0 + bne .wi3 // no acknoledge + swap D4 // address + moveq #0,D0 + add.b D4,D4 + addx.b D0,D0 // address 1st bit + bsr write_bit_wait_slave_i2c + moveq #6,D2 // 8 bits +.wi4: + moveq #0,D0 + add.b D4,D4 + addx.b D0,D0 // address + bsr write_bit_i2c + dbf D2,.wi4 + bsr read_bit_i2c // ack + bne.s .wi3 // no acknoledge + subq.w #1,D3 // len (bytes) -1 + bmi.s .wi10 +.wi8: + move.b (A3)+,D1 // data + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // data 1st bit + bsr write_bit_wait_slave_i2c + moveq #6,D2 // 8 bits +.wi5: + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // data + bsr write_bit_i2c + dbf D2,.wi5 + bsr read_bit_i2c // ack + dbne D3,.wi8 + bne.s .wi3 // no acknoledge +.wi10: + bsr stop_bit_i2c + moveq #0,D0 // OK + bra.s .wi2 +.wi3: + bsr stop_bit_i2c +.wi9: + moveq #CT60_READ_ERROR,D0 // error + bra.s .wi2 +.wi1: + moveq #CT60_READ_ERROR,D0 // bus error + move.l A1,8 + move.l A2,SP +.wi2: + lea _tbdr_mfp,A1 + cmp.l A0,A1 + bne.s .wi7 + clr.b _tbcr_mfp // timer B stopped +.wi7: + move (SP)+,SR + tst.l D0 + movem.l (SP)+,D1-D4/A0-A3 + rts + +read_i2c: // D0.L: address, D0.H: device, D0 return data or error + + movem.l D1-D3/A0-A2,-(SP) + move.l D0,D3 // device + swap D3 + move SR,-(SP) + or #0x700,SR // no interrupts + lea .r1(PC),A0 + move.l 8,A1 // bus error + move.l A0,8 + move.l SP,A2 + lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) + tst.b _tbcr_mfp + bne.s .r6 // timer B used + bclr #0,_imra_mfp + bclr #0,_iera_mfp + bclr #0,_ipra_mfp + bclr #0,_isra_mfp + lea _tbdr_mfp,A0 + move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) + move.b #3,_tbcr_mfp // 2.4576MHz/16 +.r6: + move.w D0,D1 // address + bsr start_bit_i2c + move.l A1,8 + move.l A2,SP + move.w D3,D0 // device + bsr write_device_i2c + moveq #0,D0 // write address + bsr write_bit_i2c // r/w + bsr read_bit_i2c // ack + btst #0,D0 + bne .r3 // no acknoledge + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // address 1st bit + bsr write_bit_wait_slave_i2c + moveq #6,D2 // 8 bits +.r4: + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // address + bsr write_bit_i2c + dbf D2,.r4 + bsr read_bit_i2c // ack + bne.s .r3 // no acknoledge + bsr start_bit_wait_slave_i2c + move.w D3,D0 // device + bsr write_device_i2c + moveq #1,D0 // read data + bsr write_bit_i2c // r/w + bsr read_bit_i2c // ack + btst #0,D0 + bne.s .r3 // no acknoledge + moveq #0,D1 // data + bsr read_bit_wait_slave_i2c // 1st bit + lsr.l #1,D0 // data + addx.w D1,D1 + moveq #6,D2 // 8 bits +.r5: + bsr read_bit_i2c + lsr.l #1,D0 // data + addx.w D1,D1 + dbf D2,.r5 + moveq #1,D0 // ack master = 1 => no other byte + bsr write_bit_i2c + bsr stop_bit_i2c + moveq #0,D0 + move.w D1,D0 // 8 bits data + bra.s .r2 +.r3: + bsr stop_bit_i2c + moveq #CT60_READ_ERROR,D0 // error + bra.s .r2 +.r1: + moveq #CT60_READ_ERROR,D0 // bus error + move.l A1,8 + move.l A2,SP +.r2: + lea _tbdr_mfp,A1 + cmp.l A0,A1 + bne.s .r7 + clr.b _tbcr_mfp // timer B stopped +.r7: + move.w (SP)+,SR + tst.l D0 + movem.l (SP)+,D1-D3/A0-A2 + rts + +write_i2c: // D0.L: address, D0.H: device, D1:data, D0 return error + + movem.l D1-D4/A0-A2,-(SP) + move.l D0,D3 // device + swap D3 + move.w D1,D4 // data + move SR,-(SP) + or #0x700,SR // no interrupts + lea .w1(PC),A0 + move.l 8,A1 // bus error + move.l A0,8 + move.l SP,A2 + lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19.2 KHz) + tst.b _tbcr_mfp + bne.s .w6 // timer B used + bclr #0,_imra_mfp + bclr #0,_iera_mfp + bclr #0,_ipra_mfp + bclr #0,_isra_mfp + lea _tbdr_mfp,A0 + move.b #2,(A0) // clock = 78.125 KHz (value changed at each 6.4 uS) + move.b #3,_tbcr_mfp // 2.4576MHz/16 +.w6: + move.w D0,D1 // address + bsr start_bit_i2c + move.l A1,8 + move.l A2,SP + move.w D3,D0 // device + bsr write_device_i2c + moveq #0,D0 // write address + bsr write_bit_i2c // r/w + bsr read_bit_i2c // ack + btst #0,D0 + bne .w3 // no acknoledge + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // address 1st bit + bsr write_bit_wait_slave_i2c + moveq #6,D2 // 8 bits +.w4: + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // address + bsr write_bit_i2c + dbf D2,.w4 + bsr read_bit_i2c // ack + bne.s .w3 // no acknoledge + move.w D4,D1 // data + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // data 1st bit + bsr write_bit_wait_slave_i2c + moveq #6,D2 // 8 bits +.w5: + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // data + bsr write_bit_i2c + dbf D2,.w5 + bsr read_bit_i2c // ack + bne.s .w3 // no acknoledge + bsr stop_bit_i2c + moveq #0,D0 + move.w D1,D0 // 8 bits data + bra.s .w2 +.w3: + bsr stop_bit_i2c + moveq #CT60_READ_ERROR,D0 // error + bra.s .w2 +.w1: + moveq #CT60_READ_ERROR,D0 // bus error + move.l A1,8 + move.l A2,SP +.w2: + lea _tbdr_mfp,A1 + cmp.l A0,A1 + bne.s .w7 + clr.b _tbcr_mfp // timer B stopped +.w7: + move (SP)+,SR + tst.l D0 + movem.l (SP)+,D1-D4/A0-A2 + rts + +write_device_i2c: // D0: device + + movem.l D0-D2,-(SP) + move.w D0,D1 + add.b D1,D1 + moveq #6,D2 // 7 bits 1010xxx (SDRAM) +.wd1: + moveq #0,D0 + add.b D1,D1 + addx.b D0,D0 // device + bsr write_bit_i2c + dbf D2,.wd1 + movem.l (SP)+,D0-D2 + rts + +read_bit_i2c: + + clr.l _sda_high // data=1 initial state (open drain) + WAIT_US // 100 KHz max ! + clr.l _scl_high // clk=1 + WAIT_US + move.l _sda,D0 // data on D0 + clr.l _scl_low // clk=0 + btst #0,D0 + rts + +read_bit_wait_slave_i2c: + + move.l D1,-(SP) + clr.l _sda_high // data=1 initial state (open drain) + WAIT_US + clr.l _scl_high // clk=1 + moveq #31,D1 // time-out slave busy +.rs1: + WAIT_US // 100 KHz max ! + move.l _sda,D0 // SCL slave on B1 + btst #1,D0 + dbne D1,.rs1 + move.l _sda,D0 // data on B0 + clr.l _scl_low // clk=0 + move.l (SP)+,D1 + btst #0,D0 + rts + +write_bit_i2c: + + tst.w D0 + bne.s .wb1 + clr.l _sda_low // data=0 + bra.s .wb2 +.wb1: + clr.l _sda_high // data=1 +.wb2: + WAIT_US // 100 KHz max ! + clr.l _scl_high // clk=1 + WAIT_US + clr.l _scl_low // clk=0 + rts + +write_bit_wait_slave_i2c: + + move.l D1,-(SP) + tst.w D0 + bne.s .ws1 + clr.l _sda_low // data=0 + bra.s .ws2 +.ws1: + clr.l _sda_high // data=1 +.ws2: + WAIT_US + clr.l _scl_high // clk=1 + moveq #31,D1 // time-out slave busy +.ws3: + WAIT_US // 100 KHz max ! + move.l _sda,D0 // SCL slave on B1 + btst #1,D0 + dbne D1,.ws3 + clr.l _scl_low // clk=0 + move.l (SP)+,D1 + rts + +start_bit_i2c: + + clr.l _sda_high // data=1 initial state + clr.l _scl_high // clk=1 + WAIT_US // 100 KHz max ! + clr.l _sda_low // data=0 => start condition + WAIT_US + clr.l _scl_low // clk=0 + rts + +start_bit_wait_slave_i2c: + + move.l D1,-(SP) + clr.l _sda_high // data=1 initial state + WAIT_US // 100 KHz max ! + clr.l _scl_high // clk=1 + moveq #31,D1 // time-out slave busy +.s1: + WAIT_US // 100 KHz max ! + move.l _sda,D0 // SCL slave on B1 + btst #1,D0 + dbne D1,.s1 + clr.l _sda_low // data=0 => start condition + WAIT_US + clr.l _scl_low // clk=0 + move.l (SP)+,D1 + rts + +stop_bit_i2c: + + clr.l _sda_low // data=0 + WAIT_US // 100 KHz max ! + clr.l _scl_high // clk=1 + WAIT_US + clr.l _sda_high // data=1 => stop condition + WAIT_US + rts + +wait_26us: // 26uS (timer C) or 6.5uS (timer B) + + move.b (A0),D0 +.wu1: + cmp.b (A0),D0 + beq.s .wu1 + rts + +#endif /* !COLDFIRE */ diff --git a/flash.tos/tos/ide_scsi.S b/flash.tos/tos/ide_scsi.S new file mode 100644 index 0000000..f157e3e --- /dev/null +++ b/flash.tos/tos/ide_scsi.S @@ -0,0 +1,4795 @@ +/* CT60 / Coldfire board(s) IDE/SCSI boot routines + * IDE driver with XHDI and SCSIDRV protocols + * + * Didier Mequignon 2001-2012, e-mail: aniplay@wanadoo.fr + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "ct60.h" +#include "vars.h" +#ifdef COLDFIRE +#include "fire.h" +#endif + +#undef DEBUG + +#define MAX_LOGICAL_DRIVE 16 +#define MAX_SECTOR_SIZE 0x4000 +#define ATAPI_SECTOR_SIZE 2048 + +#if defined(COLDFIRE) && defined(MCF547X) +#define FIX_IDE +#define IDE_16BITS +#define HDV_RW_USE_XHDI +#endif + +/* SCSIDRV */ +#define SCSI_COOKIE_SIZE 74 +#define SCSI_EMULATION /* for IDE <> ATAPI */ +#if (defined(COLDFIRE) && defined(MCF547X)) || !defined(COLDFIRE) +#define SECOND_IDE_BUS +#endif + +#define NOSCSIERROR 0 /* No error */ +#define SELECTERROR -1 /* Error during selection */ +#define STATUSERROR -2 /* Default error */ +#define PHASEERROR -3 /* Invalid phase */ +#define BSYERROR -4 /* BSY lost */ +#define BUSERROR -5 /* Bus error during DMA transfer */ +#define TRANSERROR -6 /* Error during DMA-transfer (nothing transferred) */ +#define FREEERROR -7 /* Bus not freed */ +#define TIMEOUTERROR -8 /* Timeout error */ +#define DATATOOLONG -9 /* Data for ACSI Soft-transfer too long */ +#define LINKERROR -10 /* Error while sending the Linked command (ACSI) */ +#define TIMEOUTARBIT -11 /* Timeout during arbitration */ +#define PENDINGERROR -12 /* Error noted on this handle */ +#define PARITIYERROR -13 /* Transfer caused parity errors */ + +#define cArbit 0x01 /* Arbitration will take place on the bus */ +#define cAllCmds 0x02 /* All SCSI-Cmds can be transmitted */ +#define cTargCtrl 0x04 /* The target controls the procedure (so it should!) */ +#define cTarget 0x08 /* One can install oneself as a target on this bus */ +#define cCanDisconnect 0x10 /* Disconnect is possible */ +#define cScatterGather 0x20 /* Scatter gather possible with virtual RAM */ + +/* XHDI */ + +#define XH_DL_SECSIZ 0 // maximal sector size (BIOS level) +#define XH_DL_MINFAT 1 // minimal number of FATs +#define XH_DL_MAXFAT 2 // maximal number of FATs +#define XH_DL_MINSPC 3 // sectors per cluster minimal +#define XH_DL_MAXSPC 4 // sectors per cluster maximal +#define XH_DL_CLUSTS 5 // maximal number of clusters of a 16 bit FAT +#define XH_DL_MAXSEC 6 // maximal number of sectors +#define XH_DL_DRIVES 7 // maximal number of BIOS drives supported by the DOS + +#ifdef COLDFIRE + +#ifdef MCF547X +#define FIREBEE_ATA 0xFFF00040 +#endif + +#else /* !COLDFIRE */ + +//#define CTPCI_ATA 0xFCF00000 // Rodolphe changed address in 2012 ??? +#define CTPCI_ATA 0xFEF00000 + +#define USE_ATARI_IO // IDE, SCSI + +#endif /* COLDFIRE */ + +#ifdef USE_ATARI_IO + +#define ATA_DATA 0xFFF00000 +#define ATA_ERROR_REGISTER 0xFFF00005 +#define ATA_SECTOR_COUNT 0xFFF00009 +#define ATA_SECTOR_NUM 0xFFF0000D // LBA bits 0-7 +#define ATA_CYLINDER_LOW 0xFFF00011 // LBA bits 7-15 +#define ATA_CYLINDER_HIGH 0xFFF00015 // LBA bits 16-23 +#define ATA_DEVICE_HEAD 0xFFF00019 // LBA bits 24-27 +#define ATA_STATUS_COMMAND 0xFFF0001D +#define ATA_CONTROL_DEVICE 0xFFF00039 + +#define OFFSET_DATA 0x00 +#define OFFSET_ERROR_REGISTER 0x05 +#define OFFSET_SECTOR_COUNT 0x09 +#define OFFSET_SECTOR_NUM 0x0D // LBA bits 0-7 +#define OFFSET_CYLINDER_LOW 0x11 // LBA bits 7-15 +#define OFFSET_CYLINDER_HIGH 0x15 // LBA bits 16-23 +#define OFFSET_DEVICE_HEAD 0x19 // LBA bits 24-27 +#define OFFSET_STATUS_COMMAND 0x1D +#define OFFSET_CONTROL_DEVICE 0x39 + +#endif /* USE_ATARI_IO */ + +#define TIME_OUT_CMD 200 // 1 second +#define TIME_OUT_4S 800 +#define TIME_OUT_10S 2000 + + .globl install_scsidrv +#ifdef COLDFIRE + .globl install_hddriver + .globl conv_ascii_value_optimized + .globl error_unknow_device + .globl error_ok +#if defined(MCF5445X) || defined(MCF547X) + .globl ide_reset +#endif +#endif + .globl read_sectors + .globl write_sectors + .globl ide_cmd + .globl scsi_cmd + .globl swap_buffer + .globl delay_hz_200 + .globl get_cookie + .globl message0b + + .text + + .chip 68060 // some code to fix + + // SCSIDRV + +install_scsidrv: + +#ifdef COLDFIRE + lea -24(SP),SP + movem.l D0-D2/A0-A2,(SP) +#else + movem.l D0-D2/A0-A2,-(SP) +#endif + move.l #0x53435349,D0 // SCSI + jsr get_cookie + bne .error_install // already installed by an hd driver ? + move.w #3,-(SP) // TT ram if possible + move.l #SCSI_COOKIE_SIZE,-(SP) // size + move.w #0x44,-(SP) // Mxalloc + trap #1 + addq.l #8,SP + tst.l D0 + beq .error_install +.malloc_ok: + move.l D0,A2 + move.l D0,A1 + move.w #0x101,(A1)+ // version + lea In(PC),A0 + move.l A0,(A1)+ + lea Out(PC),A0 + move.l A0,(A1)+ + lea InquireSCSI(PC),A0 + move.l A0,(A1)+ + lea InquireBus(PC),A0 + move.l A0,(A1)+ + lea CheckDev(PC),A0 + move.l A0,(A1)+ + lea RescanBus(PC),A0 + move.l A0,(A1)+ + lea Open(PC),A0 + move.l A0,(A1)+ + lea Close(PC),A0 + move.l A0,(A1)+ + lea Error(PC),A0 + move.l A0,(A1)+ + lea Install(PC),A0 + move.l A0,(A1)+ + lea Deinstall(PC),A0 + move.l A0,(A1)+ + lea GetCmd(PC),A0 + move.l A0,(A1)+ + lea SendData(PC),A0 + move.l A0,(A1)+ + lea GetData(PC),A0 + move.l A0,(A1)+ + lea SendStatus(PC),A0 + move.l A0,(A1)+ + lea SendMsg(PC),A0 + move.l A0,(A1)+ + lea GetMsg(PC),A0 + move.l A0,(A1)+ + move.l phystop,A0 + move.w #cAllCmds,D0 + move.w D0,Features(A0) // IDE device 0 + move.w D0,Features+2(A0) // IDE device 1 + move.w D0,Features+4(A0) // IDE2 device 0 + move.w D0,Features+6(A0) // IDE2 device 1 + clr.l ScsiDrvID(A0) + move.l A0,-(SP) + move.w #3,-(SP) // TT ram if possible + move.l #1024,-(SP) // size + move.w #0x44,-(SP) // Mxalloc + trap #1 + addq.l #8,SP + move.l (SP)+,A0 + move.l D0,Buffer1024(A0) + beq.s .error_install + move.l #0x53435349,D0 // SCSI + move.l D0,ScsiDrvID(A0) + lea ReqData(A0),A0 + move.l A0,(A1)+ + move.l cookie,D0 + beq.s .error_install + move.l D0,A0 +.find_cookiejar: + tst.l (A0) + beq.s .cookie_slotfree + addq.l #8,A0 + bra.s .find_cookiejar +.cookie_slotfree: + move.l 4(A0),12(A0) // copy size + move.l #0x53435349,(A0)+ // SCSI + move.l A2,(A0)+ + clr.l (A0) +.error_install: +#ifdef COLDFIRE + movem.l (SP),D0-D2/A0-A2 + lea 24(SP),SP +#else + movem.l (SP)+,D0-D2/A0-A2 +#endif + rts + +In: + +#ifdef COLDFIRE + lea -40(SP),SP + movem.l D1-D5/A0-A4,(SP) +#else /* !COLDFIRE */ + movem.l D1-D5/A0-A4,-(SP) +#endif /* COLDFIRE */ +#ifdef DEBUG + lea debug130(PC),A0 + bsr debug_display_string + move.l 4+40(SP),A2 // Parms + move.l (A2),D0 // Handle + bsr debug_hex_long + lea debug152(PC),A0 + bsr debug_display_string + move.l 10(A2),D0 // Buffer + bsr debug_hex_long + lea debug154(PC),A0 + bsr debug_display_string + move.l 14(A2),D0 // TransferLen + bsr hex_long + lea debug153(PC),A0 + bsr debug_display_string + move.l 22(A2),D0 // Timeout + bsr hex_long + lea debug150(PC),A0 + bsr debug_display_string + moveq #0,D2 + move.w 8(A2),D2 // CmdLen + move.l 4(A2),A0 // Cmd +.in0: + move.b (A0)+,D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + subq.l #1,D2 + bgt.s .in0 + moveq #0x20,D0 + bsr debug_display_char +#endif /* DEBUG */ + move.w SR,D0 // supervisor only + moveq #TIMEOUTERROR,D5 // error code + move.l 4+40(SP),A2 // Parms + move.l 18(A2),D0 // SenseBuffer (18 bytes) + beq.s .in19 + move.l D0,A0 + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.w (A0) +.in19: + move.l (A2),D4 // Handle + move.l phystop,A1 + lea Features(A1),A0 + sub.l A0,D4 + asr.l #1,D4 + bmi .in1 // error +#ifdef SECOND_IDE_BUS +#ifdef COLDFIRE + cmp.l #4,D4 // FIREBEE +#else /* CT60/CTPCI */ + bsr get_ide2_address + sne.b D0 + and.l #2,D0 + addq.l #2,D0 + cmp.l D0,D4 +#endif /* COLDFIRE */ +#else /* !SECOND_IDE_BUS */ + cmp.l #2,D4 +#endif /* SECOND_IDE_BUS */ + bcc .in1 // error + move.l 4(A2),A3 // Cmd + moveq #0,D0 + move.w 8(A2),D0 // CmdLen + cmp.l #6,D0 + bcs .in1 // error +// move.w 26(A2),D3 // Flags + moveq #0,D0 + move.b (A3),D0 // command + cmp.l #0x12,D0 // inquiry + beq .in4 +#ifdef SCSI_EMULATION + tst.b PacketDevice(A1,D4.l) + bne .in2 // ATAPI devices (packet command) + // SCSI emulation + move.l #0x53435349,D0 // SCSI + cmp.l ScsiDrvID(A1),D0 + bne .in1 // data destroyed ? + move.l Buffer1024(A1),D0 + beq .in1 + move.l D0,A0 // buffer IDE + move.l 10(A2),A4 // Buffer + move.l 14(A2),D1 // TransferLen + link A6,#-8 + moveq #0,D0 + move.b (A3),D0 // command : test unit ready + bne.s .in11 + lea -8(A6),A1 // cmd buffer + move.b #0xE5,(A1) // check power mode + moveq #3,D0 + and.w D4,D0 // drive + asl.w #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + moveq #0,D0 // bytes + bsr ide_cmd + bmi .in16 +// moveq #BSYERROR,D5 +// tst.b ATA_SECTOR_COUNT +// beq .in16 // not ready + bra .in17 // OK +.in11: + cmp.l #0x03,D0 // request sense + bne.s .in20 + move.l 18(A2),D0 // SenseBuffer (18 bytes) + beq .in17 + move.l D0,A1 + move.b #0x72,(A1) // response code + clr.b 1(A1) // segment number + move.b #2,2(A1) // sense key: no sense + clr.l 3(A1) // information + move.b #10,7(A1) // additional sense length (n-7) + move.w #0x0206,8(A1) // sense specific sense descriptor + clr.w 10(A1) + move.b #0x80,12(A1) // sense-key specific + clr.l 14(A1) + bra .in17 +.in20: + cmp.l #0x08,D0 // read + bne.s .in12 + moveq #0,D2 + move.b 1(A3),D2 + and.l #0x1F,D2 + swap D2 + move.w 2(A3),D2 // LBA 21 bits + bra.s .in13 +.in12: + cmp.l #0x28,D0 // read + bne .in14 + move.l 2(A3),D2 // LBA 32 bits +.in13: + add.l #0x1FF,D1 // TransferLen + lsr.l #8,D1 + lsr.l #1,D1 // / 512 + beq .in16 + cmp.l #0x100,D1 + bhi .in16 // error + lea -8(A6),A1 // cmd buffer + move.l A4,A0 // buffer IDE + moveq #3,D0 + and.w D4,D0 // physical drive + asl.w #4,D0 + or.b #0x40,D0 // LBA + move.b D0,1(A1) // drive (C/D/H) + move.l D2,D0 // LBA + move.b D0,4(A1) // sec num, LBA low + lsr.l #8,D0 + move.w D0,2(A1) // cyl high & low, LBA high & mid + move.b D1,5(A1) // sec count 0 <=> 256 + cmp.l #0x1000000,D2 + bcc.s .in22 + move.b #0x20,(A1) // read sector(s) + clr.b 6(A1) // features + bra.s .in21 +.in22: + move.b #0x24,(A1) // read sector(s) ext + movel D2,D0 + swap D0 + lsr.l #8,D0 + move.b D0,6(A1) // features, trick for pass LBA B39-B23 as previous data to ide_cmd +.in21: + moveq #0,D0 + move.w D1,D0 // count + add.l D0,D0 + asl.l #8,D0 // * 512 = bytes + bsr ide_cmd + bmi .in16 // time-out + beq .in17 // OK +.in18: + moveq #PARITIYERROR,D5 + bra .in16 +.in14: + cmp.l #0x1A,D0 // mode sense + bne .in15 + cmp.l #20,D1 // TransferLen + bcs .in16 + moveq #0x3F,D0 + and.b 2(A3),D0 + cmp.l #0x08,D0 // caching mode page + bne .in16 + lea -8(A6),A1 // cmd buffer + move.b #0xEC,(A1) // identify device + moveq #3,D0 + and.w D4,D0 // drive + asl.w #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + move.l #512,D0 // bytes + bsr ide_cmd + bmi .in16 // time-out + bne .in18 // error + move.b #8,(A4) // page code + move.b #12,1(A4) // page length + btst #5,171(A0) // write cache enable + sne.b D0 + and.l #4,D0 // WCE + move.b D0,2(A4) + clr.b 3(A4) + clr.l 6(A4) + clr.w 10(A4) + btst #6,171(A0) // look ahead enable + seq.b D0 + and.l #0x20,D0 // DRA + move.b D0,12(A4) + clr.b 13(A4) + clr.w 14(A4) + clr.l 16(A4) + bra .in17 +.in15: + cmp.l #0x25,D0 // read capacity + bne.s .in16 + cmp.l #4,D1 // TransferLen + bcs.s .in16 + lea -8(A6),A1 // cmd buffer + move.b #0xEC,(A1) // identify device + moveq #3,D0 + and.w D4,D0 // drive + asl.w #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + move.l #512,D0 // bytes + bsr ide_cmd + bmi .in16 // time-out + bne .in18 // error + move.l 120(A0),D0 // total sectors + swap D0 + move.l D0,(A4) // logical block address + move.l #512,4(A4) // block length +.in17: + moveq #NOSCSIERROR,D5 +.in16: + unlk A6 + // end of SCSI emulation + bra .in1 +#endif /* SCSI_EMULATION */ +.in2: // packet + moveq #TIMEOUTERROR,D5 // error code + link A6,#-20 + lea -20(A6),A1 // cmd buffer + move.b #0xA0,(A1) // packet + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + move.w #ATAPI_SECTOR_SIZE,D1 + move.w D1,2(A1) // cyl high & low, LBA high & mid = maxByteCount + clr.w 4(A1) // sec num & count + moveq #4,D0 // transfer to the host + move.b D0,6(A1) // features + move.l (A3),8(A1) // ATAPI command + move.l 4(A3),12(A1) + move.l 8(A3),16(A1) + move.l 10(A2),A0 // Buffer for receive data + move.l 14(A2),D0 // TransferLen + move.l 22(A2),D1 // Timeout + bsr ide_cmd + bmi.s .in10 // timeout + lsr.l #4,D0 // sense + bne.s .in3 // error + moveq #NOSCSIERROR,D5 + bra.s .in10 +.in3: + tst.l 18(A2) // SenseBuffer (18 bytes) + beq.s .in10 // no sense buffer + move.b #0xA0,(A1) // packet + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + move.w #ATAPI_SECTOR_SIZE,D1 + move.w D1,2(A1) // cyl high & low, LBA high & mid = maxByteCount + clr.w 4(A1) // sec num & count + moveq #4,D0 // transfer to the host + move.b D0,6(A1) // features + move.l #0x03000000,D0 + move.l D0,8(A1) // request sense + moveq #18,D0 + move.b D0,12(A1) // length + clr.b 13(A1) + clr.w 14(A1) + clr.l 16(A1) + move.l 18(A2),A0 // SenseBuffer (18 bytes) + move.l 22(A2),D1 // Timeout + bsr ide_cmd + bmi.s .in10 // timeout + moveq #2,D5 // CheckCondition +.in10: + unlk A6 + bra .in1 +.in4: // inquiry + move.l phystop,A1 + move.l #0x53435349,D0 // SCSI + cmp.l ScsiDrvID(A1),D0 + bne .in1 // data destroyed ? + move.l Buffer1024(A1),D0 + beq .in1 + move.l D0,A0 // buffer IDE + move.l 10(A2),A4 // Buffer for receive data + move.l 14(A2),D1 // TransferLen + link A6,#-8 + cmp.l #32,D1 // TransferLen + bcs .in6 + lea -8(A6),A1 // cmd buffer + move.b #0xA1,(A1) // identify packet device + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + move.l #512,D0 // bytes + move.l D1,-(SP) // TransferLen + bsr ide_cmd +#ifdef SCSI_EMULATION + moveq #-1,D1 + move.l phystop,A1 + move.b D1,PacketDevice(A1,D4.l) +#endif /* SCSI_EMULATION */ + move.l (SP)+,D1 // TransferLen + tst.l D0 + beq.s .in7 // OK + lea -8(A6),A1 // cmd buffer + move.b #0xEC,(A1) // identify device + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + move.l #512,D0 // bytes + move.l D1,-(SP) // TransferLen + bsr ide_cmd + move.l (SP)+,D1 // TransferLen + tst.l D0 + bne .in6 // time-out + and.b #0xE0,(A0) // force to 0 command packet set (identify device packet) +#ifdef SCSI_EMULATION + move.l phystop,A1 + clr.b PacketDevice(A1,D4.l) +#endif +.in7: + moveq #0x1F,D0 + and.b (A0),D0 // command packet set + asl.l #8,D0 + beq.s .in8 + bset #7,D0 // removable +.in8: + move.w D0,(A4) // device type + move.b #3,2(A4) // ANSI + clr.b 3(A4) + move.b #32,4(A4) // length - 4 + clr.b 5(A4) + clr.w 6(A4) + cmp.l #36,D1 // TransferLen + bcs.s .in9 + move.l 46(A0),32(A4) // revision +.in9: + moveq #15,D0 + lea 54(A0),A0 + lea 8(A4),A1 + moveq #23,D0 +.in5: + move.b (A0)+,(A1)+ // model + subq.l #1,D0 + bpl.s .in5 + moveq #NOSCSIERROR,D5 +#ifdef DEBUG + lea debug155(PC),A0 + bsr debug_display_string + move.l D1,D2 // TransferLen + move.l A4,A0 // Buffer +.in00: + move.b (A0)+,D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + subq.l #1,D2 + bgt.s .in00 + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +.in6: + unlk A6 +// tst.w (A4) // device type +// bne .in2 // ATAPI device, try again with the real inquiry command +.in1: + move.l D5,D0 // error code +#ifdef DEBUG + lea debug145(PC),A0 + bsr debug_display_string + move.l D5,D0 + bsr debug_hex_word + lea debug146(PC),A0 + bsr debug_display_string + move.l 18(A2),D0 // SenseBuffer (18 bytes) + beq.s .ind + move.l D0,A0 + move.b 2(A0),D0 // key + and.l #0xF,D0 + bsr debug_hex_byte + lea debug147(PC),A0 + bsr debug_display_string + move.l 18(A2),A0 // SenseBuffer (18 bytes) + move.b 12(A0),D0 // ASC + bsr debug_hex_byte + lea debug148(PC),A0 + bsr debug_display_string + move.l 18(A2),A0 // SenseBuffer (18 bytes) + move.b 13(A0),D0 // ASCQ + bsr debug_hex_byte +.ind: + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l D5,D0 +#endif +#ifdef COLDFIRE + movem.l (SP),D1-D5/A0-A4 + lea 40(SP),SP +#else + movem.l (SP)+,D1-D5/A0-A4 +#endif + rts + +Out: + +#ifdef COLDFIRE + lea -40(SP),SP + movem.l D1-D5/A0-A4,(SP) +#else + movem.l D1-D5/A0-A4,-(SP) +#endif +#ifdef DEBUG + lea debug131(PC),A0 + bsr debug_display_string + move.l 4+40(SP),A2 // Parms + move.l (A2),D0 // Handle + bsr debug_hex_long + lea debug152(PC),A0 + bsr debug_display_string + move.l 10(A2),D0 // Buffer + bsr debug_hex_long + lea debug154(PC),A0 + bsr debug_display_string + move.l 14(A2),D0 // TransferLen + bsr hex_long + lea debug153(PC),A0 + bsr debug_display_string + move.l 22(A2),D0 // Timeout + bsr hex_long + lea debug150(PC),A0 + bsr debug_display_string + moveq #0,D2 + move.w 8(A2),D2 // CmdLen + move.l 4(A2),A0 // Cmd +.out0: + move.b (A0)+,D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + subq.l #1,D2 + bgt.s .out0 + moveq #0x20,D0 + bsr debug_display_char +#endif + move.w SR,D0 // supervisor only + moveq #TIMEOUTERROR,D5 // error code + move.l 4+40(SP),A2 // Parms + move.l 18(A2),D0 // SenseBuffer (18 bytes) + beq.s .out11 + move.l D0,A0 + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.w (A0) +.out11: + move.l (A2),D4 // Handle + move.l phystop,A1 + lea Features(A1),A0 + sub.l A0,D4 + asr.l #1,D4 + bmi .out1 // error +#ifdef SECOND_IDE_BUS +#ifdef COLDFIRE + cmp.l #4,D4 // FIREBEE +#else /* CT60/CTPCI */ + bsr get_ide2_address + sne.b D0 + and.l #2,D0 + addq.l #2,D0 + cmp.l D0,D4 +#endif /* COLDFIRE */ +#else /* !SECOND_IDE_BUS */ + cmp.l #2,D4 +#endif /* SECOND_IDE_BUS */ + bcc .out1 // error + move.l 4(A2),A3 // Cmd + moveq #0,D0 + move.w 8(A2),D0 // CmdLen + cmp.l #6,D0 + bcs .out1 // error +// move.w 26(A2),D3 // Flags + link A6,#-20 +#ifdef SCSI_EMULATION + move.l phystop,A1 + tst.b PacketDevice(A1,D4.l) + bne .out5 // ATAPI devices (packet command) + // SCSI emulation + move.l 10(A2),A4 // Buffer + move.l 14(A2),D1 // TransferLen + moveq #0,D0 + move.b (A3),D0 // command +#if 0 + cmp.l #0xA,D0 // write + bne.s .out4 + moveq #0,D2 + move.b 1(A3),D2 + and.l #0x1F,D2 + swap D2 + move.w 2(A3),D2 // LBA 21 bits + bra.s .out9 +.out4: + cmp.l #0x2A,D0 // write + bne .out6 + move.l 2(A3),D2 // LBA 32 bits +.out9: + add.l #0x1FF,D1 // TransferLen + lsr.l #8,D1 + lsr.l #1,D1 // / 512 + beq .out3 + cmp.l #0x100,D1 + bcc .out3 // error + lea -8(A6),A1 // cmd buffer + move.l A4,A0 // buffer IDE + moveq #3,D0 + and.w D4,D0 // physical drive + asl.w #4,D0 + or.b #0x40,D0 // LBA + move.b D0,1(A1) // drive (C/D/H) + move.l D2,D0 // LBA + move.b D0,4(A1) // sec num, LBA low + lsr.l #8,D0 + move.w D0,2(A1) // cyl high & low, LBA high & mid + move.b D1,5(A1) // sec count 0 <=> 256 + cmp.l #0x1000000,D2 + bcc.s .out12 + move.b #0x30,(A1) // write sector(s) + clr.b 6(A1) // features + bra.s .out13 +.out12: + move.b #0x34,(A1) // write sector(s) ext + movel D2,D0 + swap D0 + lsr.l #8,D0 + move.b D0,6(A1) // features, trick for pass LBA B39-B23 as previous data to ide_cmd +.out13: + moveq #0,D0 + move.w D1,D0 // count + add.l D0,D0 + asl.l #8,D0 // * 512 = bytes + bsr ide_cmd + bmi .out3 // time-out + beq .out10 // OK + moveq #PARITIYERROR,D5 + bra .out3 +.out6: +#endif + cmp.l #0x15,D0 // mode select + bne .out3 + cmp.l #20,D1 // TransferLen + bcs .out3 + moveq #0x3F,D0 + and.b 2(A3),D0 + cmp.l #8,D0 // caching mode page + bne .out3 + moveq #2,D2 // enable write cache + btst #2,2(A4) // WCE + bne.s .out7 + move.w #0x82,D2 // disable write cache +.out7: + moveq #0x55,D3 // disable read look ahead + btst #5,12(A1) // DRA + bne.s .out8 + move.w #0xAA,D3 // enable read look ahead +.out8: + lea -8(A6),A1 // cmd buffer + move.b #0xEF,(A1) // set features + moveq #7,D0 + and.w D4,D0 // drive + asl.w #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + move.b D2,6(A1) // features + moveq #0,D0 // bytes + bsr ide_cmd + bmi .out3 // time-out + lea -8(A6),A1 // cmd buffer + move.b #0xEF,(A1) // set features + moveq #3,D0 + and.w D4,D0 // drive + asl.w #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + move.b D3,6(A1) // features + moveq #0,D0 // bytes + bsr ide_cmd + bmi .out3 // time-out + bra .out10 // OK + // end of SCSI emulation +#endif /* SCSI_EMULATION */ +.out5: // packet + lea -20(A6),A1 // cmd buffer + move.b #0xA0,(A1) // packet + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + move.w #ATAPI_SECTOR_SIZE,D1 + move.w D1,2(A1) // cyl high & low, LBA high & mid = maxByteCount + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + move.l (A3),8(A1) // ATAPI command + move.l 4(A3),12(A1) + move.l 8(A3),16(A1) + move.l 10(A2),A0 // Buffer for receive data + move.l 14(A2),D0 // TransferLen + move.l 22(A2),D1 // Timeout + bsr ide_cmd + bmi.s .out3 // timeout + lsr.l #4,D0 // sense + bne.s .out2 // error +.out10: + moveq #NOSCSIERROR,D5 + bra.s .out3 +.out2: + tst.l 18(A2) // SenseBuffer (18 bytes) + beq.s .out3 // no sense buffer + move.b #0xA0,(A1) // packet + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + move.w #ATAPI_SECTOR_SIZE,D1 + move.w D1,2(A1) // cyl high & low, LBA high & mid = maxByteCount + clr.w 4(A1) // sec num & count + moveq #4,D0 // transfer to the host + move.b D0,6(A1) // features + move.l #0x03000000,D0 + move.l D0,8(A1) // request sense + moveq #18,D0 + move.b D0,12(A1) // length + clr.b 13(A1) + clr.w 14(A1) + clr.l 16(A1) + move.l 18(A2),A0 // SenseBuffer (18 bytes) + move.l 22(A2),D1 // Timeout + bsr ide_cmd + bmi.s .out3 // timeout + moveq #2,D5 // CheckCondition +.out3: + unlk A6 +.out1: + move.l D5,D0 // error code +#ifdef DEBUG + lea debug145(PC),A0 + bsr debug_display_string + move.l D5,D0 + bsr debug_hex_word + lea debug146(PC),A0 + bsr debug_display_string + move.l 18(A2),D0 // SenseBuffer (18 bytes) + beq.s .outd + move.l D0,A0 + move.b 2(A0),D0 // key + and.l #0xF,D0 + bsr debug_hex_byte + lea debug147(PC),A0 + bsr debug_display_string + move.l 18(A2),A0 // SenseBuffer (18 bytes) + move.b 12(A0),D0 // ASC + bsr debug_hex_byte + lea debug148(PC),A0 + bsr debug_display_string + move.l 18(A2),A0 // SenseBuffer (18 bytes) + move.b 13(A0),D0 // ASCQ + bsr debug_hex_byte +.outd: + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l D5,D0 +#endif +#ifdef COLDFIRE + movem.l (SP),D1-D5/A0-A4 + lea 40(SP),SP +#else + movem.l (SP)+,D1-D5/A0-A4 +#endif + rts + +InquireSCSI: + + move.l A1,-(SP) + move.l A0,-(SP) +#ifdef DEBUG + lea debug144(PC),A0 + bsr debug_display_string +#endif + move.l 6+8(SP),A0 // Info + move.l phystop,A1 + tst.w 4+8(SP) // what + bne.s .is2 // cInqNext + clr.l (A0)+ // Private.BusIds + clr.l (A0)+ // Private.resrvd + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + move.l #0x49444500,(A0)+ // BusName, IDE + clr.l (A0)+ +#ifdef DEBUG + move.l A0,-(SP) + lea -8(A0),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + move.w #2,(A0)+ // BusNo, IDE + clr.w BusNumber(A1) + move.w Features(A1),(A0)+ +.is3: + move.l #XFRB_SIZE,(A0)+ // MaxLen + moveq #0,D0 + bra.s .is4 +.is2: +#ifdef SECOND_IDE_BUS +#ifndef COLDFIRE + bsr get_ide2_address + beq.s .is1 // not found, no 2nd IDE +#endif + tst.w BusNumber(A1) + bne.s .is1 + clr.l (A0)+ // Private.BusIds + clr.l (A0)+ // Private.resrvd + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + move.l #0x49444532,(A0)+ // BusName, IDE2 + clr.l (A0)+ +#ifdef DEBUG + move.l A0,-(SP) + lea -8(A0),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + move.w #3,(A0)+ // BusNo, IDE not compatible + moveq #1,D0 + move.w D0,BusNumber(A1) + move.w Features+2(A1),(A0)+ + bra.s .is3 +.is1: +#endif /* SECOND_IDE_BUS */ + moveq #-1,D0 +.is4: +#ifdef DEBUG + move.l D0,-(SP) + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +#endif + move.l (SP)+,A0 + move.l (SP)+,A1 + rts + +InquireBus: + + move.l A0,-(SP) +#ifdef DEBUG + lea debug143(PC),A0 + bsr debug_display_string + move.w 6+4(SP),D0 // BusNo + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + moveq #0,D0 + move.w 6+4(SP),D0 // BusNo + cmp.l #2,D0 // IDE +#ifdef SECOND_IDE_BUS + beq.s .ib4 +#ifndef COLDFIRE + bsr get_ide2_address + beq.s .ib1 // not found, no 2nd IDE + moveq #0,D0 + move.w 6+4(SP),D0 // BusNo +#endif + cmp.l #3,D0 // IDE not compatible +#endif /* SECOND_IDE_BUS */ + bne.s .ib1 +.ib4: + move.l 8+4(SP),A0 // Dev + clr.l (A0)+ // Private + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ // SCSIId + tst.w 4+4(SP) // what + bne.s .ib2 // cInqNext + clr.l (A0)+ + bra.s .ib3 +.ib2: + tst.l (A0) + bne.s .ib1 + moveq #1,D0 + move.l D0,(A0)+ +.ib3: + moveq #0,D0 + move.l (SP)+,A0 + rts +.ib1: + moveq #-1,D0 + move.l (SP)+,A0 + rts + +CheckDev: + + move.l A1,-(SP) + move.l A0,-(SP) +#ifdef DEBUG + lea debug142(PC),A0 + bsr debug_display_string + move.w 4+8(SP),D0 // BusNo + bsr debug_hex_byte + lea debug149(PC),A0 + bsr debug_display_string + move.l 6+8(SP),A0 // SCSIId + move.l 4(A0),D0 // SCSIId.lo + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + move.l phystop,A1 + move.l 6+8(SP),A0 // SCSIId + move.l 4(A0),D0 // SCSIId.lo + cmp.l #2,D0 + bcc.s .cd1 // error (2 devices max on IDE) + moveq #0,D0 + move.w 4+8(SP),D0 // BusNo + cmp.l #2,D0 // IDE + bne.s .cd2 + move.l 10+8(SP),A0 // Name + move.l #0x49444500,(A0)+ // BusName, IDE + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + move.l 14+8(SP),A0 // Features + move.w Features(A1),(A0)+ + moveq #0,D0 + bra.s .cd3 +.cd2: +#ifdef SECOND_IDE_BUS +#ifndef COLDFIRE + bsr get_ide2_address + beq.s .cd1 // not found, no 2nd IDE + moveq #0,D0 + move.w 4+8(SP),D0 // BusNo +#endif + cmp.l #3,D0 // IDE not compatible + bne.s .cd1 // error + move.l 10+8(SP),A0 // Name + move.l #0x49444532,(A0)+ // BusName, IDE2 + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + clr.l (A0)+ + move.l 14+8(SP),A0 // Features + move.w Features+2(A1),(A0)+ + moveq #0,D0 + bra.s .cd3 +#endif /* SECOND_IDE_BUS */ +.cd1: + moveq #-15,D0 // unknown device +.cd3: + move.l (SP)+,A0 + move.l (SP)+,A1 + rts + +RescanBus: + +#ifdef DEBUG + move.l A0,-(SP) + lea debug141(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 + move.w 4(SP),D0 // BusNo + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + moveq #0,D0 + move.w 4(SP),D0 // BusNo + cmp.l #2,D0 // IDE +#ifdef SECOND_IDE_BUS + beq.s .rb2 +#ifndef COLDFIRE + bsr get_ide2_address + beq.s .rb1 // not found, no 2nd IDE + moveq #0,D0 + move.w 4(SP),D0 // BusNo +#endif + cmp.l #3,D0 // IDE not compatible +#endif /* SECOND_IDE_BUS */ + bne.s .rb1 // error +.rb2: + moveq #0,D0 + rts +.rb1: + moveq #-15,D0 // unknown device + rts + +Open: + +#ifdef COLDFIRE + lea -12(SP),SP + movem.l D1/A0-A1,(SP) +#else + movem.l D1/A0-A1,-(SP) +#endif +#ifdef DEBUG + lea debug138(PC),A0 + bsr debug_display_string + move.w 4+12(SP),D0 // BusNo + bsr debug_hex_byte + lea debug149(PC),A0 + bsr debug_display_string + move.l 6+12(SP),A0 // SCSIId + move.l 4(A0),D0 // SCSIId.lo + bsr debug_hex_byte +#endif + move.l phystop,A1 + move.l 6+12(SP),A0 // SCSIId + move.l 4(A0),D0 // SCSIId.lo + cmp.l #2,D0 + bcc.s .op1 // error (2 devices max on IDE) + moveq #0,D1 + move.w 4+12(SP),D1 // BusNo + cmp.l #2,D1 // IDE + bne.s .op3 +.op5: + move.l 10+12(SP),A0 // MaxLen + move.l #XFRB_SIZE,(A0) +#ifdef SCSI_EMULATION + clr.b PacketDevice(A1,D0.l) +#endif + add.l D0,D0 // * 2 Features size + lea Features(A1),A0 + add.l A0,D0 // Handle + bra.s .op4 +.op3: +#ifdef SECOND_IDE_BUS +#ifndef COLDFIRE + bsr get_ide2_address + beq.s .op2 // not found, no 2nd IDE + move.l 4(A0),D0 // SCSIId.lo +#endif + cmp.l #3,D1 // IDE not compatible + bne.s .op2 + addq.l #2,D0 + bra.s .op5 +#endif /* SECOND_IDE_BUS */ +.op2: + moveq #-35,D0 // no more handles + bra.s .op4 +.op1: + moveq #-15,D0 // unknown device +.op4: +#ifdef DEBUG + move.l D0,-(SP) + lea debug151(PC),A0 + bsr debug_display_string + move.l (SP),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +#endif +#ifdef COLDFIRE + movem.l (SP),D1/A0-A1 + lea 12(SP),SP +#else + movem.l (SP)+,D1/A0-A1 +#endif + rts + +Close: + +#ifdef DEBUG + move.l A0,-(SP) + lea debug139(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + moveq #NOSCSIERROR,D0 + rts + +Error: + +#ifdef DEBUG + move.l A0,-(SP) + lea debug140(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + move.l 4(SP),D0 // handle + move.w 8(SP),D0 // rwflag + move.w 10(SP),D0 // ErrNo + moveq #NOSCSIERROR,D0 + rts + +Install: +Deinstall: +GetCmd: +SendData: +GetData: +SendStatus: +SendMsg: +GetMsg: + +#ifdef DEBUG + move.l A0,-(SP) + lea debug156(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif + moveq #-1,D0 // error + rts + +#ifdef COLDFIRE + + // XHDI + + dc.l 0x27011992 + +xhdi: + + link A6,#0 +#ifdef COLDFIRE + lea -52(SP),SP + movem.l D1-A5,(SP) +#else + movem.l D1-A5,-(SP) +#endif + moveq #0,D1 + move.w 8(A6),D1 + moveq #-32,D0 // invalid function + cmp.l #18,D1 + bcc.s .bad_xhdi + move.w SR,D0 // supervisor only + moveq #-1,D0 // error + move.w tab_xhdi(PC,D1.l*2),D1 + jsr tab_xhdi(PC,D1.l) +.bad_xhdi: +#ifdef COLDFIRE + movem.l (SP),D1-A5 + lea 52(SP),SP +#else + movem.l (SP)+,D1-A5 +#endif + unlk A6 + rts +tab_xhdi: + dc.w XHGetVersion-tab_xhdi // 0 + dc.w XHInqTarget-tab_xhdi // 1 + dc.w XHReserve-tab_xhdi // 2 + dc.w XHLock-tab_xhdi // 3 + dc.w XHStop-tab_xhdi // 4 + dc.w XHEject-tab_xhdi // 5 + dc.w XHDrvMap-tab_xhdi // 6 + dc.w XHInqDev-tab_xhdi // 7 + dc.w XHInqDriver-tab_xhdi // 8 + dc.w XHNewCookie-tab_xhdi // 9 + dc.w XHReadWrite-tab_xhdi // 10 + dc.w XHInqTarget2-tab_xhdi // 11 + dc.w XHInqDev2-tab_xhdi // 12 + dc.w XHDriverSpecial-tab_xhdi // 13 + dc.w XHGetCapacity-tab_xhdi // 14 + dc.w XHMediumChanged-tab_xhdi // 15 + dc.w XHMiNTInfo-tab_xhdi // 16 + dc.w XHDOSLimits-tab_xhdi // 17 + +XHGetVersion: + + move.l #0x120,D0 // protocol version + rts + +XHInqTarget: + + moveq #32,D3 // stringlen + bra.s .xi1 + +XHInqTarget2: + +#ifdef COLDFIRE +#ifdef DEBUG + lea debug133(PC),A0 + bsr debug_display_string +#endif +#endif + move.l 26(A6),D3 // stringlen +.xi1: + tst.w 12(A6) // minor + bne.s .xi2 + moveq #0,D4 + move.w 10(A6),D4 // major + and.l #PUN_IDE,D4 + bne.s .xi3 +.xi2: + moveq #-15,D0 // unknown device + rts +.xi3: + move.w 10(A6),D4 // major + move.l 14(A6),D1 + beq.s .xi10 + move.l D1,A0 // blocksize + move.l #512,(A0) +.xi10: + move.l 18(A6),D1 + beq.s .xi9 + move.l D1,A0 // device_flags + clr.l (A0) +.xi9: + move.l 22(A6),D1 // product_name, 32 characters + beq.s .xi4 + move.l D1,A2 + clr.b (A2) + link A6,#-8 + move.l _dskbufp,A0 // IDE buffer + clr.w (A0) + lea -8(A6),A1 // cmd buffer + move.b #0xEC,(A1) // identify device + moveq #3,D0 + and.l D4,D0 // drive + asl.l #4,D0 + move.b D0,1(A1) // drive (C/D/H) + clr.w 2(A1) // cyl high & low + clr.w 4(A1) // sec num & count + clr.b 6(A1) // features + move.l #512,D0 // bytes + bsr ide_cmd + unlk A6 + bne.s .xi4 + move.l _dskbufp,A0 + lea 54(A0),A0 + lea 24(A0),A1 + moveq #23,D1 // jump end spaces +.xi5: + cmp.b #0x20,-(A1) + bne.s .xi6 + subq.l #1,D1 + bpl.s .xi5 +.xi6: + addq.l #1,A1 + clr.b (A1) + moveq #23,D1 // model +.xi7: + move.b (A0)+,D0 + beq.s .xi8 + move.b D0,(A2)+ + subq.l #1,D3 + ble.s .xi8 + subq.l #1,D1 + bpl.s .xi7 +.xi8: + clr.b (A2) +.xi4: + moveq #0,D0 + rts + +XHReserve: +XHLock: +XHStop: +XHEject: + + moveq #0,D0 + rts + +XHDrvMap: + + move.l _drvbits,D0 + moveq #0,D1 + move.l pun_ptr,A0 +.xdm1: + tst.b pinfo_pun(A0,D1.L) + bpl.s .xdm2 + bclr D1,D0 // remove drive not in pun table +.xdm2: + addq.l #1,D1 + cmp.l #MAX_LOGICAL_DRIVE,D1 + bcs.s .xdm1 + rts + +XHInqDev: + +#ifdef COLDFIRE +#ifdef DEBUG + lea debug134(PC),A0 + bsr debug_display_string +#endif +#endif + move.l pun_ptr,A0 + moveq #0,D0 + move.w 10(A6),D0 // bios_device + cmp.l #2,D0 // C + bcs.s .xd2 + cmp.l #MAX_LOGICAL_DRIVE,D0 + bcc.s .xd2 + moveq #0,D1 + move.b pinfo_pun(A0,D0.l),D1 + bpl.s .xd1 +.xd2: + moveq #-46,D0 // invalid drive number + rts +.xd1: + tst.l 12(A6) + beq.s .xd4 + move.l 12(A6),A1 // major + move.w D1,(A1) +.xd4: + tst.l 16(A6) + beq.s .xd5 + move.l 16(A6),A1 // minor + clr.w (A1) +.xd5: + tst.l 20(A6) + beq.s .xd6 + move.l pinfo_pstart(A0,D0.l*4),D1 + move.l 20(A6),A1 // start_sector + move.l D1,(A1) +.xd6: + lea pinfo_bpb(A0),A0 + mulu #18,D0 // * 18 + add.l D0,A0 + tst.l 24(A6) + beq.s .xd7 + move.l 24(A6),A1 // bpb + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.w (A0)+,(A1)+ +.xd7: + moveq #0,D0 + rts + +XHInqDriver: + +#ifdef COLDFIRE +#ifdef DEBUG + lea debug135(PC),A0 + bsr debug_display_string +#endif +#endif + move.l pun_ptr,A0 + moveq #0,D0 + move.w 10(A6),D0 // bios_device + cmp.l #2,D0 // C + bcs.s .xdr2 + cmp.l #MAX_LOGICAL_DRIVE,D0 + bcc.s .xdr2 + moveq #0,D1 + move.b pinfo_pun(A0,D0.l),D1 + bpl.s .xd1 +.xdr2: + moveq #-46,D0 // invalid drive number + rts +.xdr1: + move.l 12(A6),D0 // name, 17 characters + beq.s .xdr3 + move.l D0,A1 + lea message0b(PC),A0 + moveq #17,D1 +.xdr6: + move.b (A0)+,D0 + beq.s .xdr7 + move.b D0,(A1)+ + subq.l #1,D1 + bpl.s .xdr6 +.xdr7: + clr.b (A1) +.xdr3: + move.l 16(A6),D0 // version, 7 characters + beq.s .xdr4 + move.l D0,A1 + move.b #0x34,(A1)+ // ??? TOS 4.04 + move.b #0x2E,(A1)+ + move.b #0x30,(A1)+ + move.b #0x34,(A1)+ + clr.b (A1) +.xdr4: + move.l 20(A6),D0 // company, 17 characters + beq.s .xdr5 + move.l D0,A1 + clr.b (A1) +.xdr5: + move.l 24(A6),A1 // ahdi_version + move.w pinfo_vernum(A0),(A1) + move.l 28(A6),A1 // maxIPL + moveq #5,D0 + move.w D0,(A1) + moveq #0,D0 + rts + +XHNewCookie: + + moveq #-32,D0 // invalid function number + rts + +XHReadWrite: // read / write physical sectors + +#ifdef COLDFIRE +#ifdef DEBUG + lea debug132(PC),A0 + bsr debug_display_string + move.w 10(A6),D0 // major + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.w 12(A6),D0 // minor + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.w 14(A6),D0 // rwflag + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.l 16(A6),D0 // logical sector + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.w 20(A6),D0 // num sectors + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.l 22(A6),D0 // buffer + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +#endif + tst.w 12(A6) // minor + bne.s .xr4 + moveq #0,D4 + move.w 10(A6),D4 // major + and.l #PUN_IDE,D4 + bne.s .xr1 +.xr4: + moveq #-15,D0 // unknown device + rts +.xr1: + move.w 10(A6),D4 // major + moveq #0,D0 // need to swap bytes ? + moveq #0,D1 + move.l pun_ptr,A0 +.xr9: + move.b pinfo_pun(A0,D1.L),D0 + bmi.s .xr10 // invalid + cmp.l D4,D0 // major + beq.s .xr12 +.xr10: + addq.l #1,D1 + cmp.l #MAX_LOGICAL_DRIVE,D1 + bcs.s .xr9 + bra.s .xr11 +.xr2: + moveq #-1,D0 // error + rts +.xr12: + swap D4 + lea pinfo_flags(A0),A0 + tst.w (A0,D1.l*2) + smi.b D4 // flag swap + ext.w D4 + swap D4 // swap/drive +.xr11: + move.l 22(A6),A0 // buffer + moveq #0,D3 + move.w 20(A6),D3 // count + beq.s .xr2 // no sectors + move.l 16(A6),D2 // start sector +#ifndef FIX_IDE + btst #0,15(A6) // rwflag + beq.s .xr7 // read +.xr5: + move.l D3,D1 // count + cmp.l #0x100,D1 + bcs.s .xr6 + move.l #0xFF,D1 // count +.xr6: + move.l D4,D0 + bsr write_sectors + bmi.s .xr3 + move.l D1,D0 + add.l D0,D0 + asl.l #8,D0 // * 512 + add.l D0,A0 // buffer + add.l D1,D2 // start sector + sub.l D1,D3 + bgt.s .xr5 + moveq #0,D0 // OK + rts +.xr7: + move.l D3,D1 // count + cmp.l #0x100,D1 + bcs.s .xr8 + move.l #0xFF,D1 // count +.xr8: + move.l D4,D0 + bsr read_sectors + bmi.s .xr3 + move.l D1,D0 + add.l D0,D0 + asl.l #8,D0 // * 512 + add.l D0,A0 // buffer + add.l D1,D2 // start sector + sub.l D1,D3 + bgt.s .xr7 + moveq #0,D0 // OK +.xr3: + rts +#else /* FIX_IDE */ +.xr13: + moveq #1,D5 + move.l _dskbufp,A2 + move.l #0x5F465242,D0 // _FRB + jsr get_cookie + beq.s .xr19 + move.l D0,A2 // buffer + move.l #128,D5 // max 65KB - 128 +.xr19: + btst #0,15(A6) // rwflag + beq.s .xr14 // read +.xr17: + move.l D3,D1 // count + cmp.l D5,D1 + bcs.s .xr22 + move.l D5,D1 // count +.xr22: + move.l A2,A1 // temp buffer + move.l D1,D0 + asl.l #5,D0 // * 32 +.xr18: + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + move.l (A0)+,(A1)+ + subq.l #1,D0 + bgt.s .xr18 + move.l A0,-(SP) // source buffer + move.l D4,D0 + move.l A2,A0 + bsr write_sectors + move.l (SP)+,A0 // source buffer + bmi.s .xr15 + add.l D1,D2 // start sector + sub.l D1,D3 + bgt.s .xr17 + moveq #0,D0 // OK +.xr15: + rts +.xr14: + move.l A0,A3 + move.l D2,A4 + move.l D3,A5 + moveq #4,D7 // retry counter +.xr28: + moveq #1,D6 // verify +.xr27: + move.l A0,-(SP) // target buffer + move.l D3,D1 // count + cmp.l D5,D1 + bcs.s .xr23 + move.l D5,D1 // count +.xr23: + move.l D4,D0 + move.l A2,A0 // temp buffer + bsr read_sectors // A0: buffer, D0: drive, D0.H: flag swap bytes, D1: count, D2.L: start sector + move.l (SP)+,A0 + bmi.s .xr15 + move.l A2,A1 // temp buffer + move.l D1,D0 + asl.l #5,D0 // * 32 + tst.l D6 + bne.s .xr16 // 1st read + move.l D1,-(SP) +.xr26: + move.l (A1)+,D1 + cmp.l (A0)+,D1 + bne.s .xr25 + move.l (A1)+,D1 + cmp.l (A0)+,D1 + bne.s .xr25 + move.l (A1)+,D1 + cmp.l (A0)+,D1 + bne.s .xr25 + move.l (A1)+,D1 + cmp.l (A0)+,D1 + bne.s .xr25 + subq.l #1,D0 + bgt.s .xr26 + move.l (SP)+,D1 + bra.s .xr24 +.xr25: + move.l (SP)+,D1 + move.l A3,A0 // read buffer + move.l A4,D2 // start sector + move.l A5,D3 // count + subq.l #1,D7 // retry counter + bpl.s .xr28 + moveq #-11,D0 // read error + rts +.xr16: + move.l (A1)+,(A0)+ + move.l (A1)+,(A0)+ + move.l (A1)+,(A0)+ + move.l (A1)+,(A0)+ + subq.l #1,D0 + bgt.s .xr16 + move.l A3,A0 // read buffer + move.l A4,D2 // start sector + move.l A5,D3 // count + subq.l #1,D6 + bpl.s .xr27 +.xr24: + add.l D1,D2 // start sector + sub.l D1,D3 + bgt.s .xr14 + moveq #0,D0 // OK + rts +#endif /* FIX_IDE */ + +XHInqDev2: + +#ifdef COLDFIRE +#ifdef DEBUG + lea debug136(PC),A0 + bsr debug_display_string +#endif +#endif + move.l pun_ptr,A0 + moveq #0,D0 + move.w 10(A6),D0 // bios_device + cmp.l #2,D0 // C + bcs.s .xdd2 + cmp.l #MAX_LOGICAL_DRIVE,D0 + bcc.s .xdd2 + moveq #0,D1 + move.b pinfo_pun(A0,D0.l),D1 + bpl.s .xdd1 +.xdd2: + moveq #-46,D0 // invalid drive number + rts +.xdd1: + tst.l 12(A6) + beq.s .xdd5 + move.l 12(A6),A1 // major + move.w D1,(A1) +.xdd5: + tst.l 16(A6) + beq.s .xdd6 + move.l 16(A6),A1 // minor + clr.w (A1) +.xdd6: + tst.l 20(A6) + beq.s .xdd7 + move.l pinfo_pstart(A0,D0.l*4),D1 + move.l 20(A6),A1 // start_sector + move.l D1,(A1) +.xdd7: + tst.l 24(A6) + beq.s .xdd8 + lea pinfo_bpb(A0),A2 + move.l D0,D1 + mulu #18,D1 // * 18 + add.l D1,A2 + move.l 24(A6),A1 // bpb + move.l (A2)+,(A1)+ + move.l (A2)+,(A1)+ + move.l (A2)+,(A1)+ + move.l (A2)+,(A1)+ + move.w (A2)+,(A1)+ +.xdd8: + tst.l 28(A6) + beq.s .xdd9 + move.l 28(A6),A1 // blocks + lea pinfo_psize(A0),A2 + move.l (A2,D0.l*4),(A1) +.xdd9: + tst.l 32(A6) + beq.s .xdd10 + move.l 32(A6),A1 // partid + move.b pinfo_ptype+1(A0,D0.l*4),(A1)+ + move.b pinfo_ptype+2(A0,D0.l*4),D1 + bne.s .xdd3 // Atari partition + moveq #0x44,D1 // D for MSDOS +.xdd3: + move.b D1,(A1)+ + move.b pinfo_ptype+3(A0,D0.l*4),(A1) +.xdd10: + moveq #0,D0 + rts + +XHDriverSpecial: +XHGetCapacity: +XHMediumChanged: +XHMiNTInfo: + + moveq #-32,D0 // invalid function number + rts + +XHDOSLimits: + +#ifdef COLDFIRE +#ifdef DEBUG + lea debug137(PC),A0 + bsr debug_display_string +#endif +#endif + moveq #0,D0 + move.w 10(A6),D0 // which + cmp.l #XH_DL_SECSIZ,D0 // maximal sector size (BIOS level) + bne.s .xl1 + move.l #MAX_SECTOR_SIZE,D0 + rts +.xl1: + cmp.l #XH_DL_MINFAT,D0 // minimal number of FATs + bne.s .xl2 + moveq #1,D0 + rts +.xl2: + cmp.l #XH_DL_MAXFAT,D0 // maximal number of FATs + bne.s .xl3 + moveq #2,D0 + rts +.xl3: + cmp.l #XH_DL_MINSPC,D0 // sectors per cluster minimal + bne.s .xl4 + moveq #2,D0 + rts +.xl4: + cmp.l #XH_DL_MAXSPC,D0 // sectors per cluster maximal + bne.s .xl5 +#ifdef COLDFIRE + moveq #64,D0 // for this Coldfire version of BDOS, else 2 +#else + moveq #2,D0 +#endif + rts +.xl5: + cmp.l #XH_DL_CLUSTS,D0 // maximal number of clusters of a 16 bit FAT + bne.s .xl6 + move.l #0x8000,D0 + rts +.xl6: + cmp.l #XH_DL_MAXSEC,D0 // maximal number of sectors + bne.s .xl7 +#ifdef COLDFIRE + move.l #0x200000,D0 // for this Coldfire version of BDOS, else 0x10000 +#else + move.l #0x10000,D0 +#endif + rts +.xl7: + cmp.l #XH_DL_DRIVES,D0 // maximal number of BIOS drives supported by the DOS + bne.s .xl8 + moveq #MAX_LOGICAL_DRIVE,D0 + rts +.xl8: + moveq #-32,D0 // invalid function number + rts + + // IDE emulation + .chip 5200 + +#if 0 // unfinished, to fix with MMU update_tlb access fault !!! +access_error_ide: // called out of cf68klib + + move.w #0x2700,SR // mask interrupts + move.l SP,save_sp + move.l D0,save_registers + move.l D1,save_registers+4 + move.l A0,save_registers+32 + move.l save_sp,A0 + move.w (A0),D0 // format + move.w D0,D1 + lsr.l #8,D0 + and.l #0xC,D0 + and.l #3,D1 + or.l D0,D1 // FS + cmp.l #0xA,D1 // TLB miss on data write + beq.s .error_on_data + cmp.l #0xC,D1 // TLB miss on data read + bne .not_ide_access +.error_on_data: + move.l __MMU_BASE+0x10,D0 // MMUAR + move.l D0,save_mmuar + cmp.l #FALCON_ATA_DATA,D0 + bcs .not_ide_access + cmp.l #FALCON_ATA_DATA+0x3F,D0 + bhi .not_ide_access + lea access_fault_stack,SP + move.w 2(A0),D0 // SR + move.w D0,save_sr + lea save_registers,A0 + movem.l D2-D7,8(A0) + movem.l A1-A6,36(A0) + move.l save_sp,A0 + move.l 4(A0),A0 // PC + moveq #0,D0 + move.w (A0)+,D0 // opcode + move.l D0,D1 + and.l #0xF000,D0 + cmp.l #0x1000,D0 // move.b + bne .not_move_b + move.l D1,D0 // opcode + and.l #0xFFF8,D0 + cmp.l #0x13C0,D0 // move.b Dx,FALCON_ATA + beq.s .move_b_dx_ata + move.l D1,D0 // opcode + and.l #0xF1F8,D0 + cmp.l #0x1080,D0 // move.b Dx,(Ax) + beq.s .write_register_b + cmp.l #0x1100,D0 // move.b Dx,-(Ax) + beq.s .write_register_b + cmp.l #0x10C0,D0 // move.b Dx,(Ax)+ + bne.s .not_move_b_dx_ax + move.l D1,D0 // opcode + swap D0 + lsr.l #1,D0 + and.l #7,D0 // address register index + move.l A0,-(SP) + lea save_registers,A0 + lea 32(A0,D0.w*4),A0 + addq.l #1,(A0) // (Ax)+ + move.l (SP)+,A0 // PC + bra.s .move_b_dx_ata +.not_move_b_dx_ax: + cmp.l #0x1140,D0 // move.b Dx,d16(Ax) + beq.s .move_b_dx_dax + cmp.l #0x1180,D0 // move.b Dx,d8(Ax,Xi) + bne .not_move_b_dx_dax +.move_b_dx_dax: + addq.l #2,A0 // fix PC + bra.s .write_register_b +.move_b_dx_ata: + addq.l #4,A0 // fix PC +.write_register_b: + move.l A0,save_pc + +#ifdef DEBUG + move.l save_sp,A0 + move.l 4(A0),A0 // PC + move.w (A0),D0 // opcode + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l save_pc,D0 // PC updated + bsr debug_hex_long + + moveq #0x20,D0 + bsr debug_display_char + move.l save_sp,A0 + move.l 4(A0),A0 // PC + move.w (A0),D0 // opcode + bsr debug_hex_word + + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + + + lea save_registers,A0 + moveq #7,D0 + and.l D1,D0 // opcode => register index + move.l (A0,D0.w*4),D1 // value + + +#ifdef DEBUG + move.l save_sp,A0 + move.l 4(A0),A0 // PC + move.w (A0),D0 // opcode + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l save_pc,D0 // PC updated + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + + + move.l save_mmuar,D0 + lsr.l #2,D0 // / 4 + not.l D0 + and.l #0xF,D0 + bclr #3,D0 + beq .end_opcode + lea save_ide_registers,A0 + move.b D1,(A0,D0.w) + tst.l D0 + bne .end_opcode // <> cmd + bra .send_ide_cmd +.not_move_b_dx_dax: + move.l D1,D0 // opcode + and.l #0xF1FF,D0 + cmp.l #0x1039,D0 // move.b FALCON_ATA,Dx + beq.s .move_b_ata_dx + move.l D1,D0 // opcode + and.l #0xF1F8,D0 + cmp.l #0x1010,D0 // move.b (Ax),Dx + beq.s .read_register_b + cmp.l #0x1020,D0 // move.b -(Ax),Dx + beq.s .read_register_b + cmp.l #0x1018,D0 // move.b (Ax)+,Dx + bne.s .not_move_b_ax_dx + moveq #7,D0 + and.l D1,D0 // opcode => address register index + move.l A0,-(SP) + lea save_registers,A0 + lea 32(A0,D0.w*4),A0 + addq.l #1,(A0) // (Ax)+ + move.l (SP)+,A0 // PC + bra.s .move_b_ata_dx +.not_move_b_ax_dx: + cmp.l #0x1028,D0 // move.b d16(Ax),Dx + beq.s .move_b_dax_dx + cmp.l #0x1030,D0 // move.b d8(Ax,Xi),Dx + bne.s .not_move_b_dax_dx +.move_b_dax_dx: + addq.l #2,A0 // fix PC + bra.s .read_register_b +.move_b_ata_dx: + addq.l #4,A0 // fix PC +.read_register_b: + move.l A0,save_pc + lsr.l #8,D1 + lsr.l #1,D1 + and.l #7,D1 // register index + bra.s .read_register_dx +.not_move_b_dax_dx: +.not_move_b: + bra .unknow_opcode +.read_register_dx: + move.l save_mmuar,D0 + lea ATA_ERROR_REGISTER,A0 + cmp.l #FALCON_ATA_ERROR_REGISTER,D0 + beq.s .update_register + lea ATA_SECTOR_COUNT,A0 + cmp.l #FALCON_ATA_SECTOR_COUNT,D0 + beq.s .update_register + lea ATA_SECTOR_NUM,A0 + cmp.l #FALCON_ATA_SECTOR_NUM,D0 + beq.s .update_register + lea ATA_CYLINDER_LOW,A0 + cmp.l #FALCON_ATA_CYLINDER_LOW,D0 + beq.s .update_register + lea ATA_CYLINDER_HIGH,A0 + cmp.l #FALCON_ATA_CYLINDER_HIGH,D0 + beq.s .update_register + lea ATA_DEVICE_HEAD,A0 + cmp.l #FALCON_ATA_DEVICE_HEAD,D0 + beq.s .update_register + lea ATA_CONTROL_DEVICE,A0 + cmp.l #FALCON_ATA_CONTROL_DEVICE,D0 + bne .end_opcode +.update_register: + move.b (A0),D0 + lea save_registers,A0 + move.b D0,3(A0,D1.w*4) + move.l save_sp,A0 + move.b (A0),D0 // format + lsr.l #4,D0 + and.l #3,D0 // stack alignment + sub.l D0,A0 + subq.l #8,A0 // original stack before access fault + move.l A0,save_sp + lea save_registers,A0 + movem.l 4(A0),D1-A6 + clr.l save_mmuar + move.l save_sp,SP + move.w save_sr,D0 + move.w D0,SR + move.l save_registers,D0 + move.l save_pc,-(SP) + rts +.send_ide_cmd: + move.w 2(A0),D0 // sector high / sector low + move.w D0,ATA_CYLINDER_HIGH + move.w 4(A0),D0 // sector num / sector count + move.w D0,ATA_SECTOR_NUM + move.b 6(A0),D0 // features (error when read) + move.w D0,ATA_ERROR_REGISTER + moveq #2,D0 // control device, disable interrupt + move.b D0,ATA_CONTROL_DEVICE + move.w (A0),D0 // command, C/D/H + move.w D0,ATA_STATUS_COMMAND +.end_opcode: +#ifdef DEBUG + move.l save_sp,A0 + move.l 4(A0),A0 // PC + move.w (A0),D0 // opcode + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l save_pc,D0 // PC updated + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l save_sp,A0 + move.w (A0),D0 + bsr debug_hex_word // format + moveq #0x20,D0 + bsr debug_display_char + move.w 2(A0),D0 + bsr debug_hex_word // SR + moveq #0x20,D0 + bsr debug_display_char + move.l A0,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + move.l save_sp,A0 + move.b (A0),D0 // format + lsr.l #4,D0 + and.l #3,D0 // stack alignment + sub.l D0,A0 + subq.l #8,A0 // original stack before access fault + move.l A0,save_sp + clr.l save_mmuar + lea save_registers,A0 + move.l 4(A0),D1 + movem.l 32(A0),A0-A6 + move.l save_sp,SP + move.w save_sr,D0 + move.w D0,SR + move.l save_registers,D0 + move.l save_pc,-(SP) + rts +.unknow_opcode: + move.l save_sp,SP +.not_ide_access: + move.l save_registers+32,A0 + move.l save_registers+4,D1 + move.l save_registers,D0 + move.l old_access_error,-(SP) + rts +#endif /* #if 0 */ + + // IDE driver + .chip 68060 + +install_xbra: // A0: handler, D0: vector + +#ifdef COLDFIRE + lea -28(SP),SP + movem.l D1-D3/A0-A3,(SP) +#else + movem.l D1-D3/A0-A3,-(SP) +#endif + moveq #0,D3 + move.w D0,D3 // vector + move.l A0,A3 // handler + move.w #3,-(SP) // TT ram if possible + move.l #18,-(SP) // size + move.w #0x44,-(SP) // Mxalloc + trap #1 + addq.l #8,SP + tst.l D0 + beq.s .error_xbra + move.l D0,A0 + move.l #0x58425241,(A0)+ // XBRA + move.l #0x5F445256,(A0)+ // _DRV + clr.l (A0)+ + move.w #0x4EF9,(A0)+ // JMP + move.l A3,(A0)+ // handler + lea -10(A0),A0 + cpusha BC + move.l D3,A1 + move.l (A1),D0 + move.l D0,(A0)+ // old vector + move.l A0,(A1) // JMP, new vector +.error_xbra: + tst.l D0 +#ifdef COLDFIRE + movem.l (SP),D1-D3/A0-A3 + lea 28(SP),SP +#else + movem.l (SP)+,D1-D3/A0-A3 +#endif + rts + +install_hddriver: + +#ifdef COLDFIRE + lea -32(SP),SP + movem.l D1-D4/A0-A3,(SP) +#ifdef DEBUG + lea debug128(PC),A0 + bsr debug_display_string + move.l pun_ptr,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +#else + movem.l D1-D4/A0-A3,-(SP) +#endif + pea crlf(PC) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + move.l pun_ptr,D0 + beq .no_drive + move.l D0,A3 + lea pinfo_bpb(A3),A1 + move.l #((16*18)/4),D0 +.clr_tab_bpb: + clr.l (A1)+ + subq.l #1,D0 + bpl.s .clr_tab_bpb + moveq #2,D4 // logical drive +.loop_partition: + moveq #0,D0 + move.b pinfo_pun(A3,D4.l),D0 + bmi .next_partition + swap D0 + lea pinfo_flags(A3),A0 + tst.w (A0,D4.l*2) + smi.b D0 // flag swap + ext.w D0 + swap D0 // swap/drive + move.l pinfo_pstart(A3,D4.l*4),D2 + moveq #1,D1 // 1 sector + move.l _dskbufp,A0 // read boot sector + bsr read_sectors + bmi .next_partition + move.b pinfo_pun(A3,D4.l),D0 + move.l D4,D1 // logical drive + move.l pinfo_ptype(A3,D4.l*4),D2 // part_type + lea pinfo_psize(A3),A0 + move.l (A0,D4.l*4),D3 // partition size in sectors + bsr display_drive + move.l _dskbufp,A0 // boot sector + lea pinfo_bpb(A3),A1 + move.l D4,D1 // logical drive + mulu #18,D1 // * 18 + add.l D1,A1 + move.l D2,D1 // part_type + and.l #0xFFFFFF,D1 // ID + // GEMDOS + cmp.l #0x47454D,D1 // GEM up to 16M + beq.s .partition_ok + cmp.l #0x42474D,D1 // BGM over 16M + beq.s .partition_ok + cmp.l #0x524157,D1 // RAW + beq.s .partition_ok + // DOS 1:FAT12, 0xB/0xC:FAT32 + cmp.l #0x1,D2 // FAT12 up to 15M + beq.s .partition_ok + cmp.l #0x4,D2 // FAT16 up to 32M + beq.s .partition_ok + cmp.l #0x6,D2 // FAT16 over 32M + beq.s .partition_ok + cmp.l #0xE,D2 // WIN95 FAT16 + bne .no_bpb +.partition_ok: + move.l D2,-(SP) // part_type + moveq #0,D2 + move.b 0xC(A0),D2 + asl.l #8,D2 + move.b 0xB(A0),D2 // BPS + move.w D2,(A1) // sector size + beq .no_bpb2 + cmp.l #MAX_SECTOR_SIZE,D2 + bhi .no_bpb2 + moveq #0,D1 + move.b 0xD(A0),D1 // SPC + move.w D1,2(A1) // cluster size in sectors + move.w D1,D0 + mulu D2,D0 + move.w D0,4(A1) // cluster size in bytes + moveq #0,D0 + move.b 0x12(A0),D0 + asl.l #8,D0 + move.b 0x11(A0),D0 // NDIRS + asl.l #5,D0 // * 32 + divu D2,D0 // / sector size + move.w D0,6(A1) // size directory in sectors + moveq #0,D2 + move.b 0x17(A0),D2 + asl.l #8,D2 + move.b 0x16(A0),D2 // SPF + move.w D2,8(A1) // FAT size + moveq #0,D0 + move.b 0xF(A0),D0 + asl.l #8,D0 + move.b 0xE(A0),D0 // RES + move.l D0,D3 + add.l D2,D3 // + FAT size + move.w D3,10(A1) // 1st sector of FAT2 + moveq #0,D3 + move.b 0x10(A0),D3 // NFATS + mulu D2,D3 // * FAT size + add.l D0,D3 // + RES + moveq #0,D0 + move.w 6(A1),D0 // size directory in sectors + add.l D3,D0 + move.w D0,12(A1) // 1st data sector + moveq #0,D2 + move.b 0x14(A0),D2 + asl.l #8,D2 + move.b 0x13(A0),D2 // NSECTS + bne.s .nsects_ok + lea pinfo_psize(A3),A2 + move.l (A2,D4.l*4),D2 // partition size in sectors + sub.l D0,D2 // - 1st data sector +.nsects_ok: + divu D1,D2 + move.w D2,14(A1) // total clusters + move.l (SP)+,D2 // part_type + moveq #0,D0 // FAT 12 + cmp.l #0x1,D2 // FAT 12 up to 15M + beq.s .fat12 + moveq #1,D0 // FAT 16 +.fat12: + moveq #0,D3 + move.b 0x10(A0),D3 // NFATS + cmp.l #1,D3 + bne.s .two_fats + bset #1,D0 // one FAT +.two_fats: + move.w D0,16(A1) // FAT 16 + bra.s .end_bpb +.no_bpb2: + move.l (SP)+,D2 +.no_bpb: + clr.w (A1) + clr.l 2(A1) + clr.l 6(A1) + clr.l 10(A1) + clr.l 14(A1) +.end_bpb: + move.l _drvbits,D0 + bset D4,D0 // logical drive + move.l D0,_drvbits +#ifdef DEBUG + lea debug125(PC),A0 + bsr debug_display_string + moveq #8,D1 +.loop_bpb: + move.w (A1)+,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + subq.l #1,D1 + bpl.s .loop_bpb + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + lea debug129(PC),A0 + bsr debug_display_string + move.l _drvbits,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif +.next_partition: + addq.l #1,D4 + cmp.l #MAX_LOGICAL_DRIVE,D4 + bcs .loop_partition + move.w SR,D0 + move.w D0,-(SP) + or.l #0x700,D0 // mask interrupts + move.w D0,SR + lea det_hdv_bpb(PC),A0 + move.w #hdv_bpb,D0 + bsr install_xbra + move.l D0,old_hdv_bpb_hd + lea det_hdv_rw(PC),A0 + move.w #hdv_rw,D0 + bsr install_xbra + move.l D0,old_hdv_rw_hd + lea det_hdv_mediach(PC),A0 + move.w #hdv_mediach,D0 + bsr install_xbra + move.l D0,old_hdv_mediach_hd + move.l cookie,D0 + beq.s .no_cookie_jar + move.l D0,A0 +.find_cookie_jar: + tst.l (A0) + beq.s .cookie_slot_free + addq.l #8,A0 + bra.s .find_cookie_jar +.cookie_slot_free: + move.l 4(A0),12(A0) // copy size + move.l #0x58484449,(A0)+ // XHDI + lea xhdi(PC),A2 + move.l A2,(A0)+ + clr.l (A0) +.no_cookie_jar: + move.w (SP)+,D0 + move.w D0,SR + lea pinfo_flags(A3),A0 + moveq #0,D4 // logical drive +.search_partition_boot: + move.w (A0)+,D0 + btst #0,D0 + bne.s .found_partition_boot + addq.l #1,D4 + cmp.l #MAX_LOGICAL_DRIVE,D4 + bcs.s .search_partition_boot + bra.s .no_drive +.found_partition_boot: + move.w D4,_bootdev + move.w D4,-(SP) // logical boot drive + move.w #0xE,-(SP) // Dsetdrv + trap #1 + addq.l #4,SP +.no_drive: +#ifdef COLDFIRE + movem.l (SP),D1-D4/A0-A3 + lea 32(SP),SP +#else + movem.l (SP)+,D1-D4/A0-A3 +#endif + rts + +det_hdv_bpb: + + move.l A0,-(SP) + move.l pun_ptr,A0 + moveq #0,D0 + move.w 4+4(SP),D0 // drive + cmp.l #2,D0 // C + bcs.s .dhb2 + cmp.l #MAX_LOGICAL_DRIVE,D0 + bcc.s .dhb2 + tst.b pinfo_pun(A0,D0.l) + bpl.s .dhb1 +.dhb2: + move.l (SP)+,A0 + moveq #0,D0 + move.l old_hdv_bpb_hd,-(SP) + rts +.dhb1: + move.l D1,-(SP) + move.l pinfo_ptype(A0,D0.l*4),D1 + // from ROOT sector + cmp.l #0x47454D,D1 // GEM + beq.s .dhb3 + cmp.l #0x42474D,D1 // BGM + beq.s .dhb3 + // from MBR + cmp.l #0x1,D1 // FAT12 up to 15M + beq.s .dhb3 + cmp.l #0x4,D1 // FAT16 up to 32M + beq.s .dhb3 + cmp.l #0x6,D1 // FAT16 over 32M + beq.s .dhb3 + cmp.l #0xE,D1 // WIN95 FAT16 + beq.s .dhb3 +.dhb4: + move.l (SP)+,D1 + move.l (SP)+,A0 + moveq #0,D0 // not for TOS + rts +.dhb3: + lea pinfo_bpb(A0),A0 + mulu #18,D0 // * 18 + add.l A0,D0 + move.l D0,A0 +#ifdef DEBUG + move.l D0,-(SP) + move.l A0,-(SP) + lea debug125(PC),A0 + bsr debug_display_string + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l (SP),A0 + moveq #8,D1 +.loop_getbpb: + move.w (A0)+,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + subq.l #1,D1 + bpl.s .loop_getbpb + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +#endif + tst.w (A0) // sector size + beq.s .dhb4 + move.l (SP)+,D1 + move.l (SP)+,A0 + rts + +det_hdv_rw: + + lea -24(SP),SP + movem.l D1-D4/A0-A1,(SP) + btst #3,5+24(SP) // rwflag + bne.s .dhr10 // physical + move.l pun_ptr,A1 + moveq #0,D0 + move.w 14+24(SP),D0 // drive + cmp.l #2,D0 // C + bcs.s .dhr10 + cmp.l #MAX_LOGICAL_DRIVE,D0 + bcc.s .dhr10 + moveq #0,D4 + move.b pinfo_pun(A1,D0.l),D4 + bpl.s .dhr1 +.dhr10: + movem.l (SP),D1-D4/A0-A1 + lea 24(SP),SP + moveq #0,D0 + move.l old_hdv_rw_hd,-(SP) + rts +.dhr2: + moveq #-1,D0 // error + bra .dhr3 +.dhr1: + moveq #0,D2 + move.w 12+24(SP),D2 // logical sector + bpl.s .dhr9 + move.l 16+24(SP),D2 // logical sector +.dhr9: + tst.l D2 + bmi.s .dhr2 // negative logical sector + move.l 6+24(SP),D1 // buffer + beq .dhr4 // no buffer + move.l pinfo_pstart(A1,D0.l*4),D3 + swap D4 + lea pinfo_flags(A1),A0 + tst.w (A0,D0.l*2) + smi.b D4 // flag swap + ext.w D4 + swap D4 // swap/drive + lea pinfo_bpb(A1),A0 + mulu #18,D0 // * 18 + add.l D0,A0 + move.w 14(A0),D0 // total clusters + mulu.w 2(A0),D0 // cluster size in sectors + cmp.l D0,D2 // logical sector to hight + bcc.s .dhr2 +#ifdef DEBUG + move.l A0,-(SP) + lea debug127(PC),A0 + bsr debug_display_string + move.w 4+28(SP),D0 // rwflag + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.l D1,D0 // buffer + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.w 10+28(SP),D0 // num sectors + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.l D2,D0 // logical sector + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + moveq #0x30,D0 + bsr debug_display_char + moveq #0x78,D0 + bsr debug_display_char + move.w 14+28(SP),D0 // drive + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,A0 +#endif + moveq #0,D0 + move.w (A0),D0 // sector size + lsr.l #8,D0 + lsr.l #1,D0 // / 512 + move.l D1,A0 // buffer + move.w 10+24(SP),D1 // num sectors + beq .dhr4 // no sectors + mulu D0,D1 + mulu.l D0,D2 + add.l D3,D2 // start sector + move.l D1,D3 // count +#ifndef HDV_RW_USE_XHDI + btst #0,5+24(SP) // rwflag + beq.s .dhr7 // read + tst.l D2 // logical sector + beq.s .dhr2 // root sector +.dhr5: + move.l D3,D1 // count + cmp.l #0x100,D1 + bcs.s .dhr6 + move.l #0xFF,D1 // count +.dhr6: + move.l D4,D0 + bsr write_sectors + bmi.s .dhr3 + move.l D1,D0 + add.l D0,D0 + asl.l #8,D0 // * 512 + add.l D0,A0 // buffer + add.l D1,D2 // start sector + sub.l D1,D3 + bgt.s .dhr5 + bra.s .dhr4 +.dhr7: + move.l D3,D1 // count + cmp.l #0x100,D1 + bcs.s .dhr8 + move.l #0xFF,D1 // count +.dhr8: + move.l D4,D0 + bsr read_sectors + bmi.s .dhr3 + move.l D1,D0 + add.l D0,D0 + asl.l #8,D0 // * 512 + add.l D0,A0 // buffer + add.l D1,D2 // start sector + sub.l D1,D3 + bgt.s .dhr7 +#else /* HDV_RW_USE_XHDI */ + move.w 4+24(SP),D1 // rwflag + moveq #0,D0 + move.w 14+24(SP),D0 // logical drive + move.l A6,-(SP) + lea -26(SP),A6 + lea -46(SP),SP + movem.l D5-D7/A2-A5,(SP) + move.b pinfo_pun(A1,D0.L),D0 // physical drive + move.w D0,10(A6) // major + clr.w 12(A6) // minor + move.w D1,14(A6) // rwflag + move.l D2,16(A6) // logical sector + move.w D3,20(A6) // num sectors + move.l A0,22(A6) // buffer + bsr XHReadWrite + movem.l (SP),D5-D7/A2-A5 + lea 46(SP),SP + move.l (SP)+,A6 + tst.l D0 + bmi.s .dhr3 +#endif /* HDV_RW_USE_XHDI */ +.dhr4: + moveq #0,D0 // OK +.dhr3: + movem.l (SP),D1-D4/A0-A1 + lea 24(SP),SP + rts + +det_hdv_mediach: + + move.l A0,-(SP) + move.l pun_ptr,A0 + moveq #0,D0 + move.w 4+4(SP),D0 // drive + cmp.l #2,D0 // C + bcs.s .dhm2 + cmp.l #MAX_LOGICAL_DRIVE,D0 + bcc.s .dhm2 + tst.b pinfo_pun(A0,D0.l) + bpl.s .dhm1 +.dhm2: + move.l (SP)+,A0 + moveq #0,D0 + move.l old_hdv_mediach_hd,-(SP) + rts +.dhm1: + lea pinfo_flags(A0),A0 + add.l D0,A0 + add.l D0,A0 + bclr #7,1(A0) + sne.b D0 +#ifdef COLDFIRE // for BDOS + and.l #1,D0 +#else + and.l #2,D0 +#endif + move.l (SP)+,A0 + rts + +#endif /* COLDFIRE */ + +swap_buffer: // A0: buffer, D0: count + +#ifdef COLDFIRE + lea -16(SP),SP + movem.l D0-D2/A0,(SP) + and.l #0xFFFF,D0 + bra.s .end_loop_swap +.loop_swap: + move.l #255,D2 +.loop_swap_2: + move.b 1(A0),D1 + asl.l #8,D1 + move.b (A0),D1 + move.w D1,(A0)+ + subq.l #1,D2 + bpl.s .loop_swap_2 +.end_loop_swap: + subq.l #1,D0 + bpl.s .loop_swap + movem.l (SP),D0-D2/A0 + lea 16(SP),SP +#else + movem.l D0-D2/A0,-(SP) + bra.s .end_loop_swap +.loop_swap: + move.w #255,D2 +.loop_swap_2: + move.w (A0),D1 + ror.w #8,D1 + move.w D1,(A0)+ + dbf D2,.loop_swap_2 +.end_loop_swap: + dbf D0,.loop_swap + movem.l (SP)+,D0-D2/A0 +#endif + rts + +read_sectors: // A0: buffer, D0: drive, D0.H: flag swap bytes, D1: count, D2.L: start sector + // return error code inside D0 +#ifdef COLDFIRE + lea -36(SP),SP + movem.l D1-D4/A0-A4,(SP) +#else + movem.l D1-D4/A0-A4,-(SP) +#endif + move.l A0,A4 // buffer + move.l D0,D4 // physical drive & flag swap bytes + move.w D1,D3 // count + btst #4,D4 + beq .use_DMAread // SCSI + link A6,#-8 + move.l A4,A0 // IDE buffer + lea -8(A6),A1 // cmd buffer + moveq #3,D0 + and.l D4,D0 // physical drive + asl.l #4,D0 + or.l #0x40,D0 // LBA mode + move.l D0,-(SP) + move.l D2,D0 // LBA + swap D0 + lsr.l #8,D0 + and.l #0xF,D0 // LBA bits 24-27 + or.l (SP)+,D0 + move.b D0,1(A1) // drive (C/D/H) + move.l D2,D0 // LBA + move.b D0,4(A1) // sec num, LBA low + lsr.l #8,D0 + move.w D0,2(A1) // cyl high & low, LBA high & mid + move.b D1,5(A1) // sec count 0 <=> 256 + cmp.l #0x1000000,D2 + bcc.s .read_lba48 + move.b #0x20,(A1) // read sector(s) + clr.b 6(A1) // features + bra.s .read_lba +.read_lba48: + move.b #0x24,(A1) // read sector(s) ext + movel D2,D0 + swap D0 + lsr.l #8,D0 + move.b D0,6(A1) // features, trick for pass LBA B39-B23 as previous data to ide_cmd +.read_lba: + moveq #0,D0 + move.w D1,D0 // count + add.l D0,D0 + asl.l #8,D0 // * 512 = bytes + bsr ide_cmd + unlk A6 + ble.s .end_read_sectors // OK or time-out + moveq #-11,D0 // read error + bra.s .end_read_sectors +.use_DMAread: + move.w D4,-(SP) // physical drive + move.l A4,-(SP) // buffer + move.w D1,-(SP) // count + move.l D2,-(SP) // sector + move.w #0x2A,-(SP) // DMAread + trap #14 + lea 14(SP),SP + ext.l D0 +.end_read_sectors: + tst.l D0 + bmi.s .end_read_sectors_swap + tst.l D4 // flag swap bytes + bpl.s .end_read_sectors_swap + move.l D0,-(SP) + move.l A4,A0 // buffer + move.w D3,D0 // count + bsr swap_buffer + move.l (SP)+,D0 +.end_read_sectors_swap: +#if 0 // #ifdef DEBUG + tst.l D0 + bmi.s .error_sectors_read + move.l D0,-(SP) + ext.l D3 + bra.s .end_dump_sectors_read +.loop_dump_sectors_read: + move.l A4,A1 + moveq #31,D1 + bsr dump +// bsr wait_key + lea 512(A4),A4 +.end_dump_sectors_read: + subq.l #1,D3 + bpl.s .loop_dump_sectors_read +.error_sectors_read: + move.l (SP)+,D0 +#endif + tst.l D0 +#ifdef COLDFIRE + movem.l (SP),D1-D4/A0-A4 + lea 36(SP),SP +#else + movem.l (SP)+,D1-D4/A0-A4 +#endif + rts + +write_sectors: // A0: buffer, D0: drive, D0.H: flag swap bytes, D1: count, D2.L: start sector + // return error code inside D0 +#ifdef COLDFIRE + lea -36(SP),SP + movem.l D1-D4/A0-A4,(SP) +#else + movem.l D1-D4/A0-A4,-(SP) +#endif + move.l A0,A4 // buffer + move.w D1,D3 // count + move.l D0,D4 // physical drive & flag swap bytes + bpl.s .begin_write_sectors_swap + move.l A4,A0 // buffer + move.w D3,D0 // count + bsr swap_buffer +.begin_write_sectors_swap: + btst #4,D4 + beq .use_DMAwrite // SCSI + link A6,#-8 + move.l A4,A0 // IDE buffer + lea -8(A6),A1 // cmd buffer + moveq #3,D0 + and.l D4,D0 // physical drive + asl.l #4,D0 + or.l #0x40,D0 // LBA mode + move.l D0,-(SP) + move.l D2,D0 // LBA + swap D0 + lsr.l #8,D0 + and.l #0xF,D0 // LBA bits 24-27 + or.l (SP)+,D0 + move.b D0,1(A1) // drive (C/D/H) + move.l D2,D0 // LBA + move.b D0,4(A1) // sec num, LBA low + lsr.l #8,D0 + move.w D0,2(A1) // cyl high & low, LBA high & mid + move.b D1,5(A1) // sec count 0 <=> 256 + cmp.l #0x1000000,D2 + bcc.s .write_lba48 + move.b #0x30,(A1) // write sector(s) + clr.b 6(A1) // features + bra.s .write_lba +.write_lba48: + move.b #0x34,(A1) // write sector(s) ext + movel D2,D0 + swap D0 + lsr.l #8,D0 + move.b D0,6(A1) // features, trick for pass LBA B39-B23 as previous data to ide_cmd +.write_lba: + moveq #0,D0 + move.w D1,D0 // count + add.l D0,D0 + asl.l #8,D0 // * 512 = bytes + bsr ide_cmd + unlk A6 + ble.s .end_write_sectors // OK or time-out + moveq #-10,D0 // write error + bra.s .end_write_sectors +.use_DMAwrite: + move.w D4,-(SP) // physical drive + move.l A4,-(SP) // buffer + move.w D1,-(SP) // count + move.l D2,-(SP) // sector + move.w #0x2B,-(SP) // DMAwrite + trap #14 + lea 14(SP),SP + ext.l D0 +.end_write_sectors: + tst.l D4 // flag swap bytes + bpl.s .end_write_sectors_swap + move.l D0,-(SP) + move.l A4,A0 // buffer + move.w D3,D0 // count + bsr swap_buffer + move.l (SP)+,D0 +.end_write_sectors_swap: +#if 0 // #ifdef DEBUG + tst.l D0 + bmi.s .error_sectors_write + move.l D0,-(SP) + ext.l D3 + bra.s .end_dump_sectors_write +.loop_dump_sectors_write: + move.l A4,A1 + moveq #31,D1 + bsr dump +// bsr wait_key + lea 512(A4),A4 +.end_dump_sectors_write: + subq.l #1,D3 + bpl.s .loop_dump_sectors_write +.error_sectors_write: + move.l (SP)+,D0 +#endif + tst.l D0 +#ifdef COLDFIRE + movem.l (SP),D1-D4/A0-A4 + lea 36(SP),SP +#else + movem.l (SP)+,D1-D4/A0-A4 +#endif + rts + +#ifdef COLDFIRE + +error_unknow_device: + + moveq #-15,D0 + rts + +error_ok: + + moveq #0,D0 + rts + +#endif /* COLDFIRE */ + +#ifdef USE_ATARI_IO + +scsi_cmd: // D0: drive, D1.L: DMA bytes, D2: bytes cmd, A0: DMA buffer, A1: buffer bytes cmd + // return error code inside D0, and time speed test inside D1.L + + bset #7,flock + beq.s .sr5 + moveq #0,D1 + moveq #-1,D0 // error + rts +.sr5: + movem.l D2-D3/A0,-(SP) + moveq #0,D3 + bsr send_cmd_scsi + bmi .sr4 // time-out + move.w #0x89,0xFFFF8606 // Init-Command Register NCR5380 + move.w #0,0xFFFF8604 + move.w #0x8B,0xFFFF8606 // Target-Command Register + move.w #1,0xFFFF8604 + move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset + move.w 0xFFFF8604,D0 + move.w #0x8A,0xFFFF8606 // Mode Register + move.w #2,0xFFFF8604 // enable DMA + move.l A0,-(SP) + move.b 3(SP),0xFFFF860D + move.b 2(SP),0xFFFF860B + move.b 1(SP),0xFFFF8609 + addq.l #4,SP + move.w #0x190,0xFFFF8606 + bsr mfp_delay + move.w #0x90,0xFFFF8606 // DMA reading + bsr mfp_delay + move.l D1,D0 // num bytes DMA + and.w #0x1FF,D1 + lsr.l #8,D0 + lsr.l #1,D0 // / 512 + tst.w D1 + beq.s .sr3 + addq #1,D0 +.sr3: + move.w D0,0xFFFF8604 // sectors +.sr1: + btst #3,0xFFFF860F + bne.s .sr1 + move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset + move.w #0,0xFFFF8604 + move.w #0,0xFFFF8606 // read transfer +#ifdef COLDFIRE + move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK +#else + bsr get_timer_c +#endif + move.l D0,D3 // speed test + bsr wait_end_cmd_scsi + bmi.s .sr4 // time-out + and #0xF,D1 + beq.s .sr2 + move.w #0x20,0xFFFF8606 +.sr2: +#ifdef COLDFIRE + move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK +#else + bsr get_timer_c +#endif + sub.l D3,D0 + move.l D0,D3 // time speed test + bsr get_status_scsi + cpusha DC + and.l #0xFF,D0 // error code +.sr4: + move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset + move.w 0xFFFF8604,D1 + move.w #0x180,0xFFFF8606 + bsr mfp_delay + move.w #0x80,0xFFFF8606 // Data register + clr.w flock + move.l D3,D1 // time speed test + tst.l D0 + movem.l (SP)+,D2-D3/A0 + rts + +get_status_scsi: + + move.l D1,-(SP) + move.w #0x8B,0xFFFF8606 // Target-Command Register + move.w #3,0xFFFF8604 + move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset + move.w 0xFFFF8604,D0 + move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register + move.l _hz_200,D1 +.gs5: + move.w 0xFFFF8604,D0 // DMA state + btst #5,D0 + bne.s .gs2 + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l #TIME_OUT_CMD,D0 + blt.s .gs5 + bra.s .gs6 +.gs2: + move.w #0x88,0xFFFF8606 // Data register + move.w 0xFFFF8604,D0 + and.l #0xFF,D0 + move.l D0,-(SP) + bsr attention_scsi + move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register + move.l _hz_200,D1 +.gs3: + move.w 0xFFFF8604,D0 // DMA state + btst #5,D0 + bne.s .gs4 + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l #TIME_OUT_CMD,D0 // time-out 500 mS + blt.s .gs3 + addq.l #4,SP +.gs6: + moveq #-1,D0 + bra.s .gs1 +.gs4: + move.w #0x88,0xFFFF8606 // Data register + move.w 0xFFFF8604,D0 + bsr attention_scsi + move.l (SP)+,D0 +.gs1: + move.l (SP)+,D1 + tst.l D0 + rts + +send_cmd_scsi: // D0: drive, D2: bytes cmd, A1: buffer bytes cmd +// return D0 < 0 => time-out + + movem.l D1-D3/A1,-(SP) + move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register + move.l _hz_200,D1 +.cs1: + move.w 0xFFFF8604,D3 // DMA state + btst #6,D3 + beq.s .cs2 + move.l _hz_200,D3 + sub.l D1,D3 + cmp.l #TIME_OUT_CMD,D3 + blt.s .cs1 + bra .cs7 +.cs2: + move.w #0x8B,0xFFFF8606 // Target-Command Register + move.w #0,0xFFFF8604 + move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register + move.w #0,0xFFFF8604 + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #0x0C,0xFFFF8604 + moveq #0,D1 + and.w #7,D0 // SCSI drive + bset D0,D1 + move.w #0x88,0xFFFF8606 // Data register + move.w D1,0xFFFF8604 + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #5,0xFFFF8604 + move.w #0x8A,0xFFFF8606 // Mode Register + move.w 0xFFFF8604,D0 + and.b #0xFE,D0 // disable arbitration + move.w D0,0xFFFF8604 + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w 0xFFFF8604,D0 + and.w #0xF7,D0 + move.w D0,0xFFFF8604 + bsr mfp_delay + move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register + move.l _hz_200,D1 +.cs6: + move.w 0xFFFF8604,D0 // DMA state + btst #6,D0 + bne.s .cs3 + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l #TIME_OUT_CMD,D0 + blt.s .cs6 +.cs7: + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #0,0xFFFF8604 + moveq #-1,D0 // time-out + bra .cs5 +.cs3: + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #0,0xFFFF8604 + move.w #0x8B,0xFFFF8606 // Target-Command Register + move.w #2,0xFFFF8604 + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #1,0xFFFF8604 + subq.w #1,D2 // bytes cmd counter + bmi.s .cs8 +.cs4: + move.l #TIME_OUT_CMD,D0 + bsr wait_hdc + bmi.s .cs5 // time-out + moveq #0,D0 + move.b (A1)+,D0 // byte cmd + move.w #0x88,0xFFFF8606 // Data register + move.w D0,0xFFFF8604 + bsr attention_scsi + dbf D2,.cs4 +.cs8: + moveq #0,D0 +.cs5: + movem.l (SP)+,D1-D3/A1 + rts + +attention_scsi: + + move.w D0,-(SP) + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w 0xFFFF8604,D0 + or.b #0x11,D0 + move.w D0,0xFFFF8604 + and.b #0xEF,D0 + move.w D0,0xFFFF8604 + move.w (SP)+,D0 + rts + +mfp_delay: + + tst.b 0xFFFFFA01 + tst.b 0xFFFFFA01 + tst.b 0xFFFFFA01 + tst.b 0xFFFFFA01 + rts + +#endif /* USE_ATARI_IO */ + +delay_hz_200: // inside D0.L + + movem.l D1/D2,-(SP) + move.l _hz_200,D1 +.dh1: move.l _hz_200,D2 + sub.l D1,D2 + cmp.l D0,D2 + blt.s .dh1 + movem.l (SP)+,D1/D2 + rts + +#ifdef USE_ATARI_IO + +wait_hdc: // time-out inside D0.L, return D0 < 0 => time-out + + movem.l D1/D2,-(SP) + move.l D0,D2 // time-out + move.w #0x8C,0xFFFF8606 // ID Select/SCSI Control Register + move.l _hz_200,D1 +.wh1: + move.w 0xFFFF8604,D0 + btst #5,D0 + bne.s .wh2 + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l D2,D0 + blt.s .wh1 + moveq #-1,D0 // time-out + bra.s .wh3 +.wh2: + moveq #0,D0 +.wh3: + movem.l (SP)+,D1/D2 + rts + +wait_end_cmd_scsi: // return D0 < 0 => time-out + + move.l #TIME_OUT_4S,D0 + cmp #6,D2 // bytes cmd + beq.s .wec3 + move.l #TIME_OUT_10S,D0 +.wec3: + move.l _hz_200,D1 +.wec5: + btst #5,0xFFFFFA01 // GPIP MFP 68901 + beq .wec2 + move.l _hz_200,D2 + sub.l D1,D2 + cmp.l D0,D2 + blt.s .wec5 +.wec4: + btst #3,0xFFFF860F + bne.s .wec4 + move.w #0x190,0xFFFF8606 + bsr mfp_delay + move.w #0x90,0xFFFF8606 // DMA reading + bsr mfp_delay + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #0x80,0xFFFF8604 + move.l #TIME_OUT_CMD,D0 + bsr delay_hz_200 // reset + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #0,0xFFFF8604 + move.l #200,D0 // 1 S + bsr delay_hz_200 + moveq #-1,D0 // error + bra.s .wec1 +.wec2: + move.w #0x8F,0xFFFF8606 // Initiate Receive/Reset + move.w 0xFFFF8604,D0 + move.w #0x8A,0xFFFF8606 // Mode Register + move.w #0,0xFFFF8604 // disable DMA + move.w #0x89,0xFFFF8606 // Init-Command Register + move.w #0,0xFFFF8604 + moveq #0,D0 // OK +.wec1: + rts + +#endif /* USE_ATARI_IO */ + +ide_cmd: // D0.L: bytes, D1.L: timeout ATAPI, A0: IDE buffer, A1: cmd buffer + // return error code inside D0, and time speed test inside D1.L +#ifndef USE_ATARI_IO + lea -24(SP),SP + movem.l D2-D4/A0-A2,(SP) +#if 0 // #ifdef DEBUG +#ifndef MCF5445X +// bsr debug_ide +#endif + move.l D0,-(SP) + move.l A0,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + moveq #0,D2 +.ir00: + move.b (A1,D2),D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + add.l #1,D2 + cmp.l #7,D2 + bcs.s .ir00 + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +#endif /* DEBUG */ + move.l D0,D2 // 0: non-data + move.l D1,D4 // timeout ATAPI in _hz_200 units + lea flock,A2 + bset #7,(A2) + beq.s .ir13 + moveq #0,D1 + moveq #-1,D0 // error + bra .ir0 +.ir13: +#ifdef MCF5445X + move.b 1(A1),D3 // C/D/H + or.l #0xA0,D3 + move.b D3,ATA_DEVICE_HEAD + moveq #0,D0 + move.b (A1),D0 + move.l #0x24,D3 // read sector(s) ext + cmp.l D0,D3 + beq.s .ir29 + move.l #0x34,D3 // write sector(s) ext + cmp.l D0,D3 + bne.s .ir30 +.ir29: + // previous data + clr.b ATA_CYLINDER_HIGH + clr.b ATA_CYLINDER_LOW + move.b 6(A1),D3 // feature special usage (trick for LBA48 B31-B24) + move.b D3,ATA_SECTOR_NUM + move.l D2,D3 + swap D3 + lsr.l #1,D3 // / 512 / 256 + move.b D3,ATA_SECTOR_COUNT + clr.b 6(A1) // feature + // current data +.ir30: + move.b 2(A1),D3 // cyl high + move.b D3,ATA_CYLINDER_HIGH + move.b 3(A1),D3 // cyl low + move.b D3,ATA_CYLINDER_LOW + move.b 4(A1),D3 // sector num + move.b D3,ATA_SECTOR_NUM + move.b 5(A1),D3 // sector count + move.b D3,ATA_SECTOR_COUNT +#else /* MCF548X */ + move.b fire_engine_hw_rev,D3 + and.l #0xF0,D3 + cmp.l #0xA0,D3 + beq.s .ide_cpld_ok + clr.w flock + moveq #0,D1 +.ir29: + moveq #-1,D0 // error + bra .ir0 +.ide_cpld_ok: + moveq #0,D0 + move.b (A1),D0 + move.l #0x24,D3 // read sector(s) ext + cmp.l D0,D3 + beq.s .ir29 // unimplemented + move.l #0x34,D3 // write sector(s) ext + cmp.l D0,D3 + beq.s .ir29 // unimplemented + // word access are used for writing register + // else byte writing on odd address register not works + // byte writing on even address write also on odd address register + // reading works in byte or word access + // => CPLD bug ? + move.w 2(A1),D3 // sector high / sector low + move.w D3,ATA_CYLINDER_HIGH + move.w 4(A1),D3 // sector num / sector count + move.w D3,ATA_SECTOR_NUM +#endif /* MCF5445X */ +#else /* USE_ATARI_IO */ +#ifdef COLDFIRE + lea -24(SP),SP + movem.l D2-D4/A0-A2,(SP) +#else + movem.l D2-D4/A0-A2,-(SP) +#endif +#if 0 // #ifdef DEBUG + move.l D0,-(SP) + move.l A0,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + moveq #0,D2 +.ir00: + move.b (A1,D2),D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + add.l #1,D2 + cmp.l #7,D2 + bcs.s .ir00 + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +#endif /* DEBUG */ + move.l D0,D2 // 0: non-data + move.l D1,D4 // timeout ATAPI in _hz_200 units + lea flock,A2 + bset #7,(A2) + beq.s .ir13 + moveq #0,D1 + moveq #-1,D0 // error + bra .ir0 +.ir13: + lea ATA_DATA,A2 +#ifdef COLDFIRE +#ifdef MCF547X + move.b 1(A1),D3 // C/D/H + btst #5,D3 // trick for 2nd IDE port + beq.s .first_port + lea FIREBEE_ATA,A2 +.first_port: +#endif /* MCF547X */ + move.b 1(A1),D3 // C/D/H + or.l #0xA0,D3 + move.b D3,OFFSET_DEVICE_HEAD(A2) + moveq #0,D0 + move.b (A1),D0 + move.l #0x24,D3 // read sector(s) ext + cmp.l D0,D3 + beq.s .ir29 + move.l #0x34,D3 // write sector(s) ext + cmp.l D0,D3 + bne.s .ir30 +.ir29: + // previous data + clr.b OFFSET_CYLINDER_HIGH(A2) + clr.b OFFSET_CYLINDER_LOW(A2) + move.b 6(A1),D3 // feature special usage (trick for LBA48 B31-B24) + move.b D3,OFFSET_SECTOR_NUM(A2) + move.l D2,D3 + swap D3 + lsr.l #1,D3 // / 512 / 256 + move.b D3,OFFSET_SECTOR_COUNT(A2) + clr.b 6(A1) // feature + // current data +.ir30: + move.b 2(A1),D3 // cyl high + move.b D3,OFFSET_CYLINDER_HIGH(A2) + move.b 3(A1),D3 // cyl low + move.b D3,OFFSET_CYLINDER_LOW(A2) + move.b 4(A1),D3 // sector num + move.b D3,OFFSET_SECTOR_NUM(A2) + move.b 5(A1),D3 // sector count + move.b D3,OFFSET_SECTOR_COUNT(A2) +#else /* ATARI */ + move.b 1(A1),D3 // C/D/H + btst #5,D3 // trick for 2nd IDE port + beq.s .first_port + lea CTPCI_ATA,A2 +.first_port: + move.b 1(A1),D3 // C/D/H + or.b #0xA0,D3 + move.b D3,OFFSET_DEVICE_HEAD(A2) + moveq #0x24,D3 + cmp.b (A1),D3 // read sector(s) ext + beq.s .ir29 + moveq #0x34,D3 + cmp.b (A1),D3 // write sector(s) ext + bne.s .ir30 +.ir29: + // previous data + clr.b OFFSET_CYLINDER_HIGH(A2) + clr.b OFFSET_CYLINDER_LOW(A2) + move.b 6(A1),OFFSET_SECTOR_NUM(A2) // feature special usage (trick for LBA48 B31-B24) + move.l D2,D3 + swap D3 + lsr.l #1,D3 // / 512 / 256 + move.b D3,OFFSET_SECTOR_COUNT(A2) + clr.b 6(A1) // feature + // current data +.ir30: + move.b 2(A1),OFFSET_CYLINDER_HIGH(A2) // cyl high + move.b 3(A1),OFFSET_CYLINDER_LOW(A2) // cyl low + move.b 4(A1),OFFSET_SECTOR_NUM(A2) // sector num + move.b 5(A1),OFFSET_SECTOR_COUNT(A2) // sector count +#endif /* COLDFIRE */ +#endif /* USE_ATARI_IO */ + moveq #0,D1 // sector counter +#ifdef COLDFIRE + moveq #0,D0 + move.b (A1),D0 + move.l #0xA1,D3 // identify packet device + cmp.l D0,D3 + beq.s .ir7 + move.l #0xEC,D3 // identify device + cmp.l D0,D3 +#else + move.b #0xA1,D3 // identify packet device + cmp.b (A1),D3 + beq.s .ir7 + move.b #0xEC,D3 // identify device + cmp.b (A1),D3 +#endif /* COLDFIRE */ + beq.s .ir7 + move.l D2,D0 + beq.s .ir7 // non-data + move.w D0,D1 + and.l #0x1FF,D1 + lsr.l #8,D0 // bytes + lsr.l #1,D0 // / 512 + tst.l D1 + beq.s .ir6 + addq.l #1,D0 +.ir6: + moveq #0,D1 + move.b D0,D1 + beq .ir5 + subq.l #1,D1 // sector counter +.ir7: +#ifndef USE_ATARI_IO +#ifdef MCF5445X + move.b 6(A1),D0 // features (error when read) + move.b D0,ATA_ERROR_REGISTER + moveq #2,D0 + move.b D0,ATA_CONTROL_DEVICE // control device, disable interrupt + move.w (A1),D0 // command, C/D/H + move.w D0,ATA_STATUS_COMMAND + move.l MCF_DTIM_DTCN1,D0 // uS +#else /* MCF548X */ + // word access are used for writing register + // else byte writing on odd address register not works + // byte writing on even address write also on odd address register + // reading works in byte or word access + // => CPLD bug ? + move.b 6(A1),D0 + asl.l #8,D0 + move.w D0,ATA_ERROR_REGISTER // features (error when read) + moveq #2,D0 + move.w D0,ATA_CONTROL_DEVICE-1 // control device, disable interrupt + move.w (A1),D0 // command, C/D/H + move.w D0,ATA_STATUS_COMMAND + move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK +#endif /* MCF5445X */ +#else /* USE_ATARI_IO */ +#ifdef COLDFIRE + move.b 6(A1),D0 + move.b D0,OFFSET_ERROR_REGISTER(A2) // features (error when read) + clr.b OFFSET_CONTROL_DEVICE(A2) // control device, INTRQ on MFP IO5 + move.b (A1),D0 + move.b D0,OFFSET_STATUS_COMMAND(A2) // command + move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK +#else /* ATARI */ + move.b 6(A1),OFFSET_ERROR_REGISTER(A2) // features (error when read) + clr.b OFFSET_CONTROL_DEVICE(A2) // control device, INTRQ on MFP IO5 + move.b (A1),OFFSET_STATUS_COMMAND(A2) // command + bsr get_timer_c +#endif /* COLDFIRE */ +#endif /* USE_ATARI_IO */ + move.l D0,D3 // speed test + moveq #0,D0 + move.b (A1),D0 + cmp.l #0xA0,D0 // packet + beq .ir14 + cmp.l #0x30,D0 // write sector(s) + bne .ir10 // read +.ir4: +#ifndef USE_ATARI_IO + move.b ATA_STATUS_COMMAND,D0 // state +#else + move.b OFFSET_STATUS_COMMAND(A2),D0 // state +#endif + btst #3,D0 // DRQ + beq.s .ir4 +#ifndef USE_ATARI_IO +.ir8: // write + lea ATA_DATA,A1 // IDE buffer + moveq #31,D0 // 512 bytes +.ir11: + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + subq.l #1,D0 + bpl.s .ir11 + move.l #TIME_OUT_CMD,D0 + bsr wait_end_cmd_ide + bmi .ir1 // time-out + move.b ATA_STATUS_COMMAND,D0 // state + and.l #9,D0 // DRQ & ERR + btst #3,D0 // DRQ + beq .ir1 // error + subq.l #1,D1 + bpl.s .ir8 + bra.s .ir12 +.ir10: // read + move.l #TIME_OUT_CMD,D0 + bsr wait_end_cmd_ide + bmi .ir1 // time-out + tst.l D2 + beq .ir9 // no data + move.b ATA_STATUS_COMMAND,D0 // state + and.l #9,D0 // DRQ & ERR + btst #3,D0 // DRQ + beq .ir1 // error + lea ATA_DATA,A1 // IDE buffer + moveq #31,D0 // 512 bytes +.ir3: + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + subq.l #1,D0 + bpl.s .ir3 + subq.l #1,D1 + bpl.s .ir10 +.ir12: // end without error +#ifdef MCF5445X + move.l MCF_DTIM_DTCN1,D0 // uS + sub.l D0,D3 + neg.l D3 // time speed test +#else /* MCF548X */ + move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK + sub.l D0,D3 // time speed test + move.l #SYSTEM_CLOCK,D0 + divu.l D0,D3 // uS +#endif /* MCF5445X */ +#else /* USE_ATARI_IO */ +.ir8: // write + lea OFFSET_DATA(A2),A1 // IDE buffer +#if defined(COLDFIRE) && defined(MCF547X) // FIREBEE +#ifdef IDE_16BITS + moveq #31,D0 // 512 bytes +.ir11: + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) + move.w (A0)+,(A1) +#else + moveq #15,D0 // 512 bytes +.ir11: + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) +#endif /* IDE_16BITS */ + subq.l #1,D0 + bpl.s .ir11 +#else /* !(defined(COLDFIRE) && defined(MCF547X)) */ + moveq #15,D0 // 512 bytes +.ir11: + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + move.l (A0)+,(A1) + dbf D0,.ir11 +#endif /* defined(COLDFIRE) && defined(MCF547X) */ + move.l #TIME_OUT_CMD,D0 + bsr wait_end_cmd_ide + bmi .ir1 // time-out + move.b OFFSET_STATUS_COMMAND(A2),D0 // state + and.l #9,D0 // DRQ & ERR + btst #3,D0 // DRQ + beq .ir1 // error +#if defined(COLDFIRE) && defined(MCF547X) + subq.l #1,D1 + bpl.s .ir8 +#else + dbf D1,.ir8 +#endif + bra .ir12 +.ir10: // read + move.l #TIME_OUT_CMD,D0 + bsr wait_end_cmd_ide + bmi .ir1 // time-out + tst.l D2 + beq .ir9 // no data + move.b OFFSET_STATUS_COMMAND(A2),D0 // state + and.l #9,D0 // DRQ & ERR + btst #3,D0 // DRQ + beq .ir1 // error + lea OFFSET_DATA(A2),A1 // IDE buffer +#if defined(COLDFIRE) && defined(MCF547X) // FIREBEE +#ifdef IDE_16BITS + moveq #31,D0 // 512 bytes +.ir3: + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ + move.w (A1),(A0)+ +#else + moveq #15,D0 // 512 bytes +.ir3: + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ +#endif /* IDE_16BITS */ + subq.l #1,D0 + bpl.s .ir3 + subq.l #1,D1 + bpl.s .ir10 +#else /* !(defined(COLDFIRE) && defined(MCF547X)) */ + moveq #15,D0 // 512 bytes +.ir3: + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + move.l (A1),(A0)+ + dbf D0,.ir3 + dbf D1,.ir10 +#endif /* defined(COLDFIRE) && defined(MCF547X) */ +.ir12: // end without error +#ifdef COLDFIRE + move.l MCF_SLT_SCNT1,D0 // uS * SYSTEM_CLOCK + sub.l D0,D3 // time speed test + move.l #SYSTEM_CLOCK,D0 + divu.l D0,D3 // uS +#else + bsr get_timer_c + sub.l D3,D0 + move.l D0,D3 // time speed test +#endif +#endif /* USE_ATARI_IO */ +.ir5: + moveq #0,D0 + bra .ir1 +.ir14: // *** ATAPI *** + move.l _hz_200,D1 +.ir21: +#ifndef USE_ATARI_IO + tst.b ATA_STATUS_COMMAND // BSY bit +#else + tst.b OFFSET_STATUS_COMMAND(A2) // BSY bit +#endif + bpl.s .ir22 + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l D4,D0 + blt.s .ir21 + moveq #-1,D0 // time-out + bra .ir1 +.ir22: +#ifndef USE_ATARI_IO + move.b ATA_STATUS_COMMAND,D0 +#else + move.b OFFSET_STATUS_COMMAND(A2),D0 +#endif + and.l #9,D0 + btst #0,D0 // ERROR + bne .ir24 // error + btst #3,D0 // DRQ + bne.s .ir23 + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l D4,D0 + blt.s .ir22 + moveq #-1,D0 // time-out + bra .ir1 +.ir23: + moveq #0,D1 +.ir17: + move.w 8(A1,D1.l),D0 // ATAPI command +#ifdef COLDFIRE + moveq #0,D2 + move.w D0,D2 + lsr.l #8,D2 + asl.l #8,D0 + or.l D2,D0 +#else + ror.w #8,D0 +#endif /* COLDFIRE */ +#ifndef USE_ATARI_IO + move.w D0,ATA_DATA +#else + move.w D0,OFFSET_DATA(A2) +#endif + addq.l #2,D1 + cmp.l #12,D1 + bcs.s .ir17 + move.b 6(A1),D0 // features +#ifndef USE_ATARI_IO + lea ATA_DATA,A1 // IDE buffer +#else + lea OFFSET_DATA(A2),A1 // IDE buffer +#endif + btst #2,D0 + bne.s .ir19 // transfer to the host (read) +.ir18: // write + move.l D4,D0 + bsr wait_end_cmd_ide + bmi .ir1 // time-out +#ifndef USE_ATARI_IO + move.b ATA_STATUS_COMMAND,D0 // state +#else + move.b OFFSET_STATUS_COMMAND(A2),D0 // state +#endif + and.l #9,D0 // DRQ & ERR + btst #3,D0 // DRQ + beq .ir24 // error or command finished + moveq #0,D1 +#ifndef USE_ATARI_IO + move.b ATA_CYLINDER_HIGH,D1 + asl.l #8,D1 + move.b ATA_CYLINDER_LOW,D1 // packet byte count + lsr.l #1,D1 +#else + move.b OFFSET_CYLINDER_HIGH(A2),D1 + asl.l #8,D1 + move.b OFFSET_CYLINDER_LOW(A2),D1 // packet byte count + lsr.l #1,D1 + btst #0,D1 + beq.s .ir25 +#endif /* ATARI_USE_IO */ + subq.l #1,D1 + bmi.s .ir18 +.ir16: // 16 bits write + + move.w (A0)+,D0 +#ifdef COLDFIRE + moveq #0,D2 + move.w D0,D2 + lsr.l #8,D2 + asl.l #8,D0 + or.l D2,D0 +#else + ror.w #8,D0 +#endif /* COLDFIRE */ + move.w D0,(A1) +#ifdef COLDFIRE + subq.l #1,D1 + bpl.s .ir16 +#else + dbf D1,.ir16 +#endif /* COLDFIRE */ + bra.s .ir18 +#ifdef USE_ATARI_IO +.ir25: + lsr.l #1,D1 + subq.l #1,D1 + bmi.s .ir18 +.ir26: // 32 bits write + move.l (A0)+,D0 +#ifdef COLDFIRE + move.l D0,D2 + lsr.l #8,D2 + asl.l #8,D0 + and.l #0x00FF00FF,D2 + and.l #0xFF00FF00,D0 + or.l D2,D0 +#else + ror.w #8,D0 + swap D0 + ror.w #8,D0 + swap D0 +#endif /* COLDFIRE */ + move.l D0,(A1) +#ifdef COLDFIRE + subq.l #1,D1 + bpl.s .ir26 +#else + dbf D1,.ir26 +#endif + bra.s .ir18 +#endif /* USE_ATARI_IO */ +.ir19: // read + move.l D4,D0 + bsr wait_end_cmd_ide + bmi .ir1 // time-out +#ifndef USE_ATARI_IO + move.b ATA_STATUS_COMMAND,D0 // state +#else + move.b OFFSET_STATUS_COMMAND(A2),D0 // state +#endif + and.l #9,D0 // DRQ & ERR + btst #3,D0 // DRQ + beq .ir24 // error or command finished + moveq #0,D1 +#ifndef USE_ATARI_IO + move.b ATA_CYLINDER_HIGH,D1 + asl.l #8,D1 + move.b ATA_CYLINDER_LOW,D1 // packet byte count + lsr.l #1,D1 +#else + move.b OFFSET_CYLINDER_HIGH(A2),D1 + asl.l #8,D1 + move.b OFFSET_CYLINDER_LOW(A2),D1 // packet byte count + lsr.l #1,D1 + btst #0,D1 + beq.s .ir27 +#endif /* USE_ATARI_IO */ + subq.l #1,D1 + bmi.s .ir19 +.ir15: // 16 bits read + move.w (A1),D0 +#ifdef COLDFIRE + moveq #0,D2 + move.w D0,D2 + lsr.l #8,D2 + asl.l #8,D0 + or.l D2,D0 +#else + ror.w #8,D0 +#endif /* COLDFIRE */ + move.w D0,(A0)+ +#ifdef COLDFIRE + subq.l #1,D1 + bpl.s .ir15 +#else + dbf D1,.ir15 +#endif /* CODFIRE */ + bra.s .ir19 +#ifdef USE_ATARI_IO +.ir27: + lsr.l #1,D1 + subq.l #1,D1 + bmi.s .ir19 +.ir28: // 32 bits read + move.l (A1),D0 +#ifdef COLDFIRE + move.l D0,D2 + lsr.l #8,D2 + asl.l #8,D0 + and.l #0x00FF00FF,D2 + and.l #0xFF00FF00,D0 + or.l D2,D0 +#else + ror.w #8,D0 + swap D0 + ror.w #8,D0 + swap D0 +#endif /* COLDFIRE */ + move.l D0,(A0)+ +#ifdef COLDFIRE + subq.l #1,D1 + bpl.s .ir28 +#else + dbf D1,.ir28 +#endif /* COLDFIRE */ + bra.s .ir19 +#endif /* USE_ATARI_IO */ +.ir24: // ATAPI +#ifndef USE_ATARI_IO + btst #0,ATA_STATUS_COMMAND // state, ERR + beq .ir12 // end without error + move.b ATA_ERROR_REGISTER,D0 // error register +#else /* USE_ATARI_IO */ + btst #0,OFFSET_STATUS_COMMAND(A2) // state, ERR + beq .ir12 // end without error + move.b OFFSET_ERROR_REGISTER(A2),D0 // error register +#endif /* USE_ATARI_IO */ + bra.s .ir1 +.ir9: // IDE +#ifndef USE_ATARI_IO + btst #0,ATA_STATUS_COMMAND // state, ERR + beq .ir12 // end without error + move.b ATA_ERROR_REGISTER,D0 // error register +#else /* USE_ATARI_IO */ + btst #0,OFFSET_STATUS_COMMAND(A2) // state, ERR + beq .ir12 // end without error + move.b OFFSET_ERROR_REGISTER(A2),D0 // error register +#endif /* USE_ATARI_IO */ + and.l #0x6E,D0 // WP, MC, MCR, ABRT, NM + bra.s .ir1 +.ir2: + moveq #-1,D0 // error, time-out +.ir1: +#ifndef USE_ATARI_IO +#ifdef MCF5445X + moveq #2,D1 + move.b D1,ATA_CONTROL_DEVICE // control device, disable interrupt +#else /* MCF548X */ + // word access are used for writing register + // else byte writing on odd address register not works + // byte writing on even address write also on odd address register + // reading works in byte or word access + // => CPLD bug ? + moveq #2,D1 + move.w D1,ATA_CONTROL_DEVICE-1 // control device, disable interrupt +#endif /* MCF5445X */ +#else /* USE_ATARI_IO */ +#ifdef COLDFIRE + moveq #2,D1 + move.b D1,OFFSET_CONTROL_DEVICE(A2) // control device, disable interrupt +#else /* ATARI */ + move.b #2,OFFSET_CONTROL_DEVICE(A2) // control device, no INTRQ on MFP IO5 +#endif /* COLDFIRE */ +#endif /* USE_ATARI_IO */ + clr.w flock + move.l D3,D1 // time speed test +#ifndef USE_ATARI_IO +#if 0 // #ifdef DEBUG +// bsr debug_ide +#if 1 + tst.l D0 + beq.s .ir0 + move.l D0,-(SP) + lea debug126(PC),A0 + bsr debug_display_string + move.l (SP),D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + move.b ATA_STATUS_COMMAND,D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + move.b ATA_ERROR_REGISTER,D0 // error register + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +#endif +#endif +#endif +.ir0: +#ifdef COLDFIRE + movem.l (SP),D2-D4/A0-A2 + lea 24(SP),SP +#else + movem.l (SP)+,D2-D4/A0-A2 +#endif + tst.l D0 + rts + +#ifdef COLDFIRE +ide_reset: + +#ifdef MCF547X + lea 0xFFFF8800,A0 // PSG (FPGA emulation) + lea 2(A0),A1 + move.w SR,D1 + move.w D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR + move.b #14,(A0) // port A + move.b (A0),D0 // read port A + bset #7,D0 // reset IDE + move.b D0,(A1) // write port A + move.w (SP)+,D1 + move.w D1,SR // restore interrupts + move.l _hz_200,D1 +.delay_reset_ide: + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l #2,D0 // 10 mS + ble.s .delay_reset_ide + move.w SR,D1 + move.w D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR + move.b #14,(A0) // port A + move.b (A0),D0 // read port A + bclr #7,D0 // reset IDE + move.b D0,(A1) // write port A + move.w (SP)+,D1 + move.w D1,SR // restore interrupts +#endif /* MCF547X */ +#ifdef MCF5445X + clr.b MCF_ATA_CR // control reset + move.l _hz_200,D1 +.delay_reset_ide: + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l #2,D0 // 10 mS + ble.s .delay_reset_ide + /* IDE set */ + lea piotms+(2*9*2)(PC),A0 // PIO 2 + move.l #1000/SYSTEM_CLOCK,D1 // period in ns + moveq #0,D0 + move.w (A0)+,D0 // t1 + add.l D1,D0 // + period + sub.l #1,D0 + divu D1,D0 // / period + move.b D0,MCF_ATA_TIME_1 + moveq #0,D0 + move.w (A0)+,D0 // t2 + add.l D1,D0 // + period + sub.l #1,D0 + divu D1,D0 // / period + move.b D0,MCF_ATA_TIME_2W + move.b D0,MCF_ATA_TIME_2R + addq.l #2,A0 // t3 + moveq #0,D0 + move.w (A0)+,D0 // t4 + add.l D1,D0 // + period + sub.l #1,D0 + divu D1,D0 // / period + move.b D0,MCF_ATA_TIME_4 + addq.l #4,A0 // t5, t6 + moveq #0,D0 + move.w (A0)+,D0 // t9 + add.l D1,D0 // + period + sub.l #1,D0 + divu D1,D0 // / period + move.b D0,MCF_ATA_TIME_9 + moveq #0,D0 + move.w (A0)+,D0 // tRD + add.l D1,D0 // + period + sub.l #1,D0 + divu D1,D0 // / period + move.b D0,MCF_ATA_TIME_PIORDX + moveq #0,D0 + move.w (A0)+,D0 // tA + add.l D1,D0 // + period + sub.l #1,D0 + divu D1,D0 // / period + move.b D0,MCF_ATA_TIME_AX + moveq #0x40,D0 // IORDY enable + move.b D0,MCF_ATA_CR + move.l _hz_200,D1 +.delay_end_reset_ide: + move.l _hz_200,D0 + sub.l D1,D0 + cmp.l #40,D0 // 200 mS + ble.s .delay_end_reset_ide + bset #0,MCF_ATA_CR // IORDY enable +#endif /* MCF5445X */ + rts + +#ifdef MCF5445X + /* t1, t2, t3, t4, t5,t6, t9,tRD, tA */ +piotms: + dc.w 70, 165, 60, 30, 50, 5, 20, 0, 35 /* PIO 0 */ + dc.w 50, 125, 45, 20, 35, 5, 15, 0, 35 /* PIO 1 */ + dc.w 30, 100, 30, 15, 20, 5, 10, 0, 35 /* PIO 2 */ + dc.w 30, 80, 30, 10, 20, 5, 10, 0, 35 /* PIO 3 */ + dc.w 25, 70, 20, 10, 20, 5, 10, 0, 35 /* PIO 4 */ +#endif + +#endif /* COLDFIRE*/ + +#ifndef COLDFIRE +#define EBUG +#endif + +#ifndef USE_ATARI_IO +#ifndef MCF5445X +#ifdef DEBUG + +debug_ide: + + move.l A0,-(SP) + move.l A1,-(SP) + move.l D0,-(SP) + move.l D1,-(SP) + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + moveq #15,D1 + lea COMPACTFLASH_BASE+0x1800,A1 +.loop: + move.b (A1)+,D0 + bsr debug_hex_byte + moveq #0x20,D0 + bsr debug_display_char + subq.l #1,D1 + bpl.s .loop + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D1 + move.l (SP)+,D0 + move.l (SP)+,A1 + move.l (SP)+,A0 + rts +#endif /* DEBUG */ +#endif /* MCF5445X */ +#endif /* COLDFIRE */ + +wait_end_cmd_ide: // time-out inside D0.L, return D0 < 0 => time-out + + move.l D1,-(SP) + move.l D2,-(SP) + move.l _hz_200,D1 +.weci1: +#ifndef USE_ATARI_IO + tst.b ATA_STATUS_COMMAND // busy bit + bpl.s .weci2 +#else /* USE_ATARI_IO */ +#ifdef COLDFIRE + tst.b OFFSET_STATUS_COMMAND(A2) // busy bit + bpl.s .weci2 +#else + btst #5,0xFFFFFA01 // GPIP MFP 68901 + beq.s .weci2 +#endif /* COLDFIRE */ +#endif /* USE_ATARI_IO */ + move.l _hz_200,D2 + sub.l D1,D2 + cmp.l D0,D2 + blt.s .weci1 + moveq #-1,D0 // time-out + bra.s .weci3 +.weci2: + moveq #0,D0 +.weci3: + move.l (SP)+,D2 + move.l (SP)+,D1 + rts + +#ifdef COLDFIRE + +display_drive: + + link A6,#-8 + add.l #0x41,D1 + move.w D1,-(SP) // logical drive + moveq #0x30,D1 + or.l D0,D1 // device number + move.w D1,-(SP) + lea blue(PC),A0 + moveq #PUN_IDE,D1 + and.l D0,D1 + bne.s .display_ide + pea message2(PC) // SCSI-disk installed + bra.s .display_color +.display_ide: + pea message1(PC) // IDE-disk installed +.display_color: + bsr text_color + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + move.w #2,-(SP) + trap #1 // Cconout + addq.l #4,SP + move.w #0x2E,-(SP) // . + move.w #2,-(SP) + trap #1 // Cconout + addq.l #4,SP + move.w #0x30,-(SP) // 0 + move.w #2,-(SP) + trap #1 // Cconout + addq.l #4,SP + lea black(PC),A0 + bsr text_color + pea message3(PC) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + move.w #2,-(SP) + trap #1 // Cconout + addq.l #4,SP + pea message4(PC) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + cmp.l #0xFF,D2 // part_type + bhi.s .gem_part + move.l D2,D0 + bsr hex_byte + bra.s .size_part +.gem_part: + move.l D2,D0 + asl.l #8,D0 + move.l D0,-4(A6) + pea -4(A6) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP +.size_part: + pea message5(PC) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + add.l #1024,D3 + moveq #11,D0 + lsr.l D0,D3 // sector size / 1024*2 => MB + move.l D3,D0 + clr.w -2(A6) + lea -8(A6),A0 + moveq #6,D1 + jsr conv_ascii_value_optimized + pea -8(A6) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + pea message6(PC) // MB + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP + unlk A6 + rts + +text_color: + + moveq #0,D0 + move.w 0x3E86,D0 // number of planes + cmp.l #2,D0 + bls.s .black_and_white + pea (A0) + move.w #9,-(SP) + trap #1 // Cconws + addq.l #6,SP +.black_and_white: + rts + +hex_byte: + move.w D0,-(SP) + lsr.l #4,D0 + bsr.s hex_char + move.w (SP)+,D0 +hex_char: + and.l #0xF,D0 + or.l #0x30,D0 + cmp.l #0x3A,D0 + bcs.s .display_char + addq.l #7,D0 +.display_char: + move.w D0,-(SP) + move.w #2,-(SP) + trap #1 // Cconout + addq.l #4,SP + rts + +message1: .asciz "IDE " +message2: .asciz "SCSI " +message3: .asciz " partition installed in " +message4: .asciz ", type " +message5: .asciz ", " +message6: .ascii " MB" +crlf: .byte 13,10,0 +blue: .byte 0x1B,0x62,0x34,0 +black: .byte 0x1B,0x62,0x3F,0 + + .align 2 + +#ifdef DEBUG + +debug_display_string: + + move.l D0,-(SP) + move.l A0,-(SP) +.dds2: + move.b (A0)+,D0 + beq.s .dds1 + bsr debug_display_char + bra.s .dds2 +.dds1: + move.l (SP)+,A0 + move.l (SP)+,D0 + rts + +debug_hex_long: + move.l D0,-(SP) + swap D0 + bsr.s debug_hex_word + move.l (SP)+,D0 +debug_hex_word: + move.w D0,-(SP) + lsr.l #8,D0 + bsr.s debug_hex_byte + move.w (SP)+,D0 +debug_hex_byte: + move.w D0,-(SP) + lsr.l #4,D0 + bsr.s debug_hex_char + move.w (SP)+,D0 +debug_hex_char: + and.l #0xF,D0 + or.l #0x30,D0 + cmp.l #0x3A,D0 + bcs.s debug_display_char + addq.l #7,D0 + +debug_display_char: + + tst.b serial_mouse + bne.s .no_debug + move.l D1,-(SP) +.wait_uart: + move.b MCF_UART_USR0,D1 + and.l #MCF_UART_USR_TXRDY,D1 + beq.s .wait_uart + move.b D0,MCF_UART_UTB0 // send the character + move.l (SP)+,D1 +.no_debug: + rts + +#endif /* DEBUG */ + +#else /* ATARI */ + +get_timer_c: + + move.l D1,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + move.l _hz_200,D0 + asl.l #8,D0 + moveq #0,D1 + move.b 0xFFFFFA23,D1 // TCDR timer C MFP + subq.b #1,D1 // 0-191 + asl.l #8,D1 // * 256 + divu #192,D1 // 0-255 + not.b D1 + move.b D1,D0 + move.w (SP)+,SR + move.l (SP)+,D1 + rts + +get_ide2_address: + + movem.l A0-A5,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + lea .no_ctpci(PC),A1 + move.l 8,A5 // bus error + move.l A1,8 + move.l SP,A4 // save ssp + moveq #0,D0 + lea CTPCI_ATA,A0 + tst.w (A0) + move.l A0,D0 // address +.no_ctpci: + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp + move.w (SP)+,SR + movem.l (SP)+,A0-A5 + tst.l D0 + rts + +#endif /* COLDFIRE */ + +#ifndef COLDFIRE +#ifdef DEBUG + +dump: + movem.l D0-D2/A0-A1,-(SP) +.loop_dump1: + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char +#if 0 // #ifdef COLDFIRE + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + moveq #15,D2 +.loop_dump2: + move.b (A1)+,D0 + bsr hex_byte +#if 0 // #ifdef COLDFIRE + move.b -1(A1),D0 + bsr debug_hex_byte +#endif + moveq #0x20,D0 + bsr display_char +#if 0 // #ifdef COLDFIRE + bsr debug_display_char +#endif + dbf D2,.loop_dump2 + lea -16(A1),A1 + moveq #15,D2 +.loop_dump3: + move.b (A1)+,D0 + cmp.b #0x20,D0 + bcs.s .dump_bad_char + cmp.b #0x7F,D0 + bcs.s .dump_ok +.dump_bad_char: + moveq #0x2E,D0 +.dump_ok: + bsr display_char +#if 0 // #ifdef COLDFIRE + bsr debug_display_char +#endif + dbf D2,.loop_dump3 + dbf D1,.loop_dump1 + movem.l (SP)+,D0-D2/A0-A1 + rts + +hex_long: + move.l D0,-(SP) + swap D0 + bsr.s hex_word + move.l (SP)+,D0 +hex_word: + move.w D0,-(SP) + lsr.w #8,D0 + bsr.s hex_byte + move.w (SP)+,D0 +hex_byte: + move.w D0,-(SP) + lsr.b #4,D0 + bsr.s hex_char + move.w (SP)+,D0 +hex_char: + and.b #0xF,D0 + or.b #0x30,D0 + cmp.b #0x3A,D0 + bcs.s display_char + addq.b #7,D0 + +display_char: + + movem.l D0-D2/A0-A2,-(SP) + move.w D0,-(SP) + move.w #2,-(SP) + move.w #3,-(SP) // Bconout + trap #13 + addq.l #6,SP + movem.l (SP)+,D0-D2/A0-A2 + rts + +debug_hex_long: + move.l D0,-(SP) + swap D0 + bsr.s hex_word + move.l (SP)+,D0 +debug_hex_word: + move.w D0,-(SP) + lsr.w #8,D0 + bsr.s hex_byte + move.w (SP)+,D0 +debug_hex_byte: + move.w D0,-(SP) + lsr.b #4,D0 + bsr.s hex_char + move.w (SP)+,D0 +debug_hex_char: + and.b #0xF,D0 + or.b #0x30,D0 + cmp.b #0x3A,D0 + bcs.s display_char + addq.b #7,D0 + +debug_display_char: + + movem.l D0-D2/A0-A2,-(SP) + move.w D0,-(SP) + move.l #0x5F504349,D0 + lea 0xED0000,A0 // 128 KB + cmp.l (A0),D0 // _PCI + beq.s .ddc2 + lea 0xEC0000,A0 // 192 KB + cmp.l (A0),D0 // _PCI + beq.s .ddc2 + lea 0xEB0000,A0 // 256 KB + cmp.l (A0),D0 // _PCI + beq.s .ddc2 + lea 0xEA0000,A0 // 320 KB + cmp.l (A0),D0 // _PCI + bne.s .ddc3 +.ddc2: + move.w (SP),D0 // character + swap D0 + move.w #0x0076,D0 // 'v' + move.l D0,-(SP) + jsr 40(A0) // drivers PCI in flash, dbug + addq.l #4,SP + bne.s .ddc1 +.ddc3: + move.w #2,-(SP) + move.w #3,-(SP) // Bconout + trap #13 + addq.l #4,SP +.ddc1: + addq.l #2,SP + movem.l (SP)+,D0-D2/A0-A2 + rts + +debug_display_string: + + move.l D0,-(SP) + move.l A0,-(SP) +.dds2: + move.b (A0)+,D0 + beq.s .dds1 + bsr debug_display_char + bra.s .dds2 +.dds1: + move.l (SP)+,A0 + move.l (SP)+,D0 + rts +#endif +#endif + +#ifdef DEBUG + +debug125: .asciz "BPB: " +debug126: .asciz "IDE error (code - STATUS - ERROR) " +debug127: .asciz "hdv_rw 0x" +debug128: .asciz "pun_ptr 0x" +debug129: .asciz "drvbits 0x" +debug130: .asciz "SCSCDRV In Handle 0x" +debug131: .asciz "SCSIDRV Out Handle 0x" +debug132: .asciz "XHDI XHReadWrite 0x" +debug133: .ascii "XHDI XHInqTarget" + .byte 13,10,0 +debug134: .ascii "XHDI XHInqDev" + .byte 13,10,0 +debug135: .ascii "XHDI XHInqDriver" + .byte 13,10,0 +debug136: .ascii "XHDI XHInqDev2" + .byte 13,10,0 +debug137: .ascii "XHDI XHDOSLimits" + .byte 13,10,0 +debug138: .asciz "SCSCDRV Open BusNo 0x" +debug139: .ascii "SCSIDRV Close" + .byte 13,10,0 +debug140: .ascii "SCSIDRV Error" + .byte 13,10,0 +debug141: .asciz "SCSIDRV RescanBus BusNo 0x" +debug142: .asciz "SCSIDRV CheckDev BusNo 0x" +debug143: .asciz "SCSIDRV InquireBus BusNo 0x" +debug144: .asciz "SCSIDRV InquireSCSI " +debug145: .asciz " Ret " +debug146: .asciz " Sense key " +debug147: .asciz " ASC " +debug148: .asciz " ASCQ " +debug149: .asciz " SCSIId.lo 0x" +debug150: .byte 13,10 + .asciz " Cmd " +debug151: .asciz " => Handle 0x" +debug152: .asciz " Buffer 0x" +debug153: .asciz " Timeout 0x" +debug154: .asciz " TransferLen 0x" +debug155: .asciz " => " +debug156: .ascii "SCCSIDRV Unimplemented" + .byte 13,10,0 +#endif + + diff --git a/flash.tos/tos/magxboot.S b/flash.tos/tos/magxboot.S index 944e324..b18a01c 100644 --- a/flash.tos/tos/magxboot.S +++ b/flash.tos/tos/magxboot.S @@ -1,6 +1,6 @@ /* MagXBoot for the CT60 * - * Didier Mequignon 2004-2005, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2004-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -32,21 +32,26 @@ magxboot: movem.l D0-A6,-(SP) - tst.l D0 + move.l D4,D5 // boot on IDE slave + tst.l D0 // _FPU cookie sne.b D4 ext.w D4 - swap D4 // flag _FPU cookie + tst.l D3 // _PCI cookie + sne.b D4 // flag CTPCI + swap D4 // flags _FPU cookie / CTPCI clr.w D4 tst.l D1 // _FRQ cookie, internal clock beq.s mb2 cmp.l #32,D1 - bls mb2 + bls.s mb2 tst.l D2 // _FRE cookie, external clock beq.s mb2 cmp.l #32,D2 seq.b D4 ext.w D4 // flag clock external patch mb2: + tst.l D5 // boot on IDE slave + sne.b D4 // flag boot on IDE slave lea mess(PC),A0 bsr printline move.l _sysbase,A0 // header ROM @@ -408,6 +413,41 @@ mb44: addq.w #1,D2 bra mb43 mb47: + btst #23,D4 // flag CTPCI + beq.s mb48 + cmp.l #0x46FC2300,D0 // move #0x2300,SR + bne.s mb48 + cmp.w #0x7001,4(A1) + bne.s mb48 + move.w #0x4E40,4(A1) // trap #0 TOS + lea mess20(PC),A0 + bsr printline + addq.w #1,D2 + bra mb23 +mb48: + tst.b D4 // flag boot IDE slave + bpl.s mb52 + cmp.l #0x70102078,D0 // moveq #$70,D0 + bne.s mb52 + cmp.w #0x04C6,4(A1) + bne.s mb52 + move.w #0x7011,(A1) + lea mess21(PC),A0 + bsr printline + addq.w #1,D2 + moveq #49,D0 + move.l A1,A0 +mb50: + addq.l #2,A0 + cmp.l #0x78106100,(A0) // moveq #$70,D4 + dbeq D0,mb50 + bne mb23 + move.w #0x7811,(A0) + lea mess21(PC),A0 + bsr printline + addq.w #1,D2 + bra mb23 +mb52: cmp.l #0x40C1007C,D0 // PSG imprimante bne mb23 cmp.l #0x070043F8,4(A1) @@ -461,10 +501,18 @@ mb23: subq.l #1,D1 bgt mb22 moveq #19,D3 + btst #23,D4 // flag CTPCI + beq.s mb49 + addq.w #1,D3 +mb49: tst.w D4 // flag external clock bpl.s mb42 addq.w #3,D3 mb42: + tst.b D4 // flag boot IDE slave + bpl.s mb51 + addq.w #3,D3 +mb51: cmp.w D3,D2 beq mb21 lea warning(PC),A0 @@ -544,7 +592,7 @@ printline: movem.l D0-D2/A0-A2,-(SP) move.l A0,-(SP) - move #9,-(SP) // Cconws + move.w #9,-(SP) // Cconws trap #1 // Gemdos addq.l #6,SP movem.l (SP)+,D0-D2/A0-A2 @@ -553,9 +601,9 @@ printline: display_char: movem.l D0-D2/A0-A2,-(SP) - move D0,-(SP) - move #2,-(SP) - move #3,-(SP) + move.w D0,-(SP) + move.w #2,-(SP) + move.w #3,-(SP) trap #13 addq.l #6,SP movem.l (SP)+,D0-D2/A0-A2 @@ -693,6 +741,12 @@ mess18: mess19: .byte 13,10 .asciz "Patch PSG printer" +mess20: + .byte 13,10 + .asciz "Patch CTPCI" +mess21: + .byte 13,10 + .asciz "Patch boot IDE slave" magx_name: .byte 0x5C .asciz "magic.ram" diff --git a/flash.tos/tos/movep2.S b/flash.tos/tos/movep2.S index 6b0a4ee..affb053 100644 --- a/flash.tos/tos/movep2.S +++ b/flash.tos/tos/movep2.S @@ -1,26 +1,21 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert - * 2006 Didier Mequignon - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ +/* TOS 4.04 patch for the CT60 / Coldfire board(s) +* Copyright (C) 2001 Xavier Joubert +* 2006 Didier Mequignon +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ .globl movep_e02b1e .text diff --git a/flash.tos/tos/params2.S b/flash.tos/tos/params2.S new file mode 100644 index 0000000..872ce37 --- /dev/null +++ b/flash.tos/tos/params2.S @@ -0,0 +1,592 @@ +/* XBIOS CT60 / Coldfire board(s) Parameters in Flash +* +* Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "main.h" +#include "ct60.h" +#include "command.h" + +#ifdef COLDFIRE +#include "fire.h" +#else +#define FLASH_UNLOCK1 (FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0xAAA) +#define FLASH_UNLOCK2 (FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0x554) +#endif + +#define MAX_PARAM_FLASH 16 +#define NB_BLOCK_PARAM (PARAM_SIZE/(MAX_PARAM_FLASH*4)) +#define SIZE_BLOCK_PARAM (PARAM_SIZE/NB_BLOCK_PARAM) + +#ifdef COLDFIRE + .globl fire_rw_param +#else + .globl ct60_rw_param +#endif + .globl init_flash_parameters + + .text + +#ifdef COLDFIRE + + .chip 68060 // some code to fix + +fire_rw_param: // D0.W: mode, D1.L: type_param, D2.L: value + + lea -52(SP),SP + movem.l D1-A5,(SP) + link A6,#-MAX_PARAM_FLASH*4 + tst.l D1 + bmi out_param + cmp.l #MAX_PARAM_FLASH-1,D1 // type_param + bcc out_param + addq.l #1,D1 + asl.l #2,D1 // param * 4 + move.l MCF_FBCS_CSAR0,D3 + and.l #0xFFFF0000,D3 + lea FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE,A2 + add.l D3,A2 // base parameters + moveq #-1,D3 + move.l #NB_BLOCK_PARAM-1,D4 + moveq #0,D6 +find_last_block: + cmp.l (A2),D3 + beq.s test_free_block +next_block: + lea SIZE_BLOCK_PARAM(A2),A2 + add.l #SIZE_BLOCK_PARAM,D6 // offset free block + subq.l #1,D4 + bpl.s find_last_block + moveq #0,D6 // offset free block + lea -SIZE_BLOCK_PARAM(A2),A2 + moveq #-1,D7 // erase sector if writing + bra.s test_read +test_free_block: + lea 4(A2),A3 + moveq #MAX_PARAM_FLASH-2,D5 +loop_test_free_block: + cmp.l (A3)+,D3 + bne.s next_block + subq.l #1,D5 + bpl.s loop_test_free_block + moveq #0,D7 // writing inside the next block + tst.l D6 + beq.s test_read // 1st block is free block + lea -SIZE_BLOCK_PARAM(A2),A2 +test_read: + and.l #1,D0 // mode + beq read_param + move.l (A2,D1.l),D0 + cmp.l D0,D2 + beq end_param // no change + lea -MAX_PARAM_FLASH*4(A6),A3 + addq.l #4,A2 + clr.l (A3)+ // block used + moveq #MAX_PARAM_FLASH-2,D0 +save_param: + move.l (A2)+,(A3)+ // save params in the stack + subq.l #1,D0 + bpl.s save_param // before erase sector command + move.l D2,-MAX_PARAM_FLASH*4(A6,D1.L) // value + bsr fire_write_param + bra.s end_param +read_param: + move.l (A2,D1.l),D0 + bra.s end_param +out_param: + moveq #-5,D0 // unimplemented opcode +end_param: + unlk A6 + movem.l (SP),D1-A5 + lea 52(SP),SP + rts + +fire_write_param: + +#ifdef MCF5445X /* M54455EVB */ + + move.l D2,-(SP) // save value + lea devices(PC),A1 + add.l 4(A1),A1 // sector of device + movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 + moveq #FLASH_WP,D3 + move.b D3,CPLD_FLASHCFG // unprotect flash + move.l MCF_FBCS_CSAR0,D3 // boot flash + and.l #0xFFFF0000,D3 + add.l D3,A2 // base parameters + add.l D6,A2 // offset free block + add.l D3,A3 // base parameters (last sector) + move.w #CMD_UNLOCK1,(A3) + move.w #CMD_UNLOCK2,(A3) + tst.w D7 + beq.s erase_sector_end + move.w #CMD_SECTOR_ERASE1,(A3) + move.w #CMD_SECTOR_ERASE2,(A3) // Erase sector command +wait_erase_loop: + move.w #CMD_STATUS,(A3) + move.w (A3),D0 + btst #7,D0 + beq.s wait_erase_loop + move.w #CMD_READ,(A3) +erase_sector_end: + lea -MAX_PARAM_FLASH*4(A6),A0 // buffer + moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter +program_byte_loop: + move.w #CMD_PROGRAM,(A2) // Byte program command + move.w (A0),(A2) +wait_program_loop: + move.w #CMD_STATUS,(A2) + move.w (A2),D0 + btst #7,D0 + beq.s wait_program_loop + move.w #CMD_READ,(A2) + move.w (A2),D0 + cmp.w (A0),D0 + beq.s program_byte_ok + addq.l #4,SP + moveq #-10,D0 // write error + bra.s program_param_loop_end +program_byte_ok: + addq.l #2,A2 + addq.l #2,A0 + subq.l #1,D6 + bpl.s program_byte_loop + move.l (SP)+,D0 +program_param_loop_end: + move.w #CMD_LOCK1,(A3) + move.w #CMD_LOCK2,(A3) + move.w #CMD_READ,(A3) + moveq #0,D1 + move.b D1,CPLD_FLASHCFG // protect flash + rts + +devices: + dc.l 0x00890018, intel_28f128j3d-devices + dc.l 0 + +intel_28f128j3d: + dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE + dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 + +#else +#ifdef MCF547X /* FIREBEE */ + + move.l D2,-(SP) // save value + lea devices(PC),A1 + add.l 4(A1),A1 // sector of device + move.l (A1),A2 // sector + move.l 4(A1),A0 // flash_unlock1 + move.l 8(A1),A1 // flash_unlock2 + move.l MCF_FBCS_CSMR0,D3 + and.l #~MCF_FBCS_CSMR_WP,D3 // unprotect flash + move.l D3,MCF_FBCS_CSMR0 + move.l MCF_FBCS_CSAR0,D5 // boot flash + and.l #0xFFFF0000,D5 + add.l D5,A2 // base parameters + add.l D5,A0 + add.l D5,A1 + move.w #CMD_UNLOCK1,D3 + move.w #CMD_UNLOCK2,D4 + move.w #CMD_AUTOSELECT,D5 + move.w #CMD_READ,D1 + move.w D3,(A0) // unlock + move.w D4,(A1) + move.w D5,(A0) // Autoselect command + move.l (A2),D0 // Manufacturer code / Device code + move.w D1,(A2) // Read/Reset command + lea devices(PC),A3 +loop_dev: + tst.l (A3) + beq no_dev + cmp.l (A3),D0 + beq.s found_dev + addq.l #8,A3 + bra.s loop_dev +no_dev: + addq.l #4,SP + moveq #-15,D0 // device error + bra program_param_loop_end_2 +found_dev: + lea devices(PC),A1 + add.l 4(A1),A1 // sector of device + movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 + move.l MCF_FBCS_CSAR0,D5 // boot flash + and.l #0xFFFF0000,D5 + add.l D5,A2 // base parameters + add.l D6,A2 // offset free block + add.l D5,A3 // base parameters (last sector) + add.l D5,A4 + tst.w D7 + beq.s erase_sector_end + move.w #CMD_SECTOR_ERASE1,D5 + move.w #CMD_SECTOR_ERASE2,D6 + move.w D3,(A3) // unlock + move.w D4,(A4) + move.w D5,(A3) + move.w D3,(A3) // unlock + move.w D4,(A4) + move.w D6,(A2) // Erase sector command +wait_erase_loop: + move.w (A2),D0 + btst #7,D0 + bne.s erase_sector_end + btst #5,D0 + beq.s wait_erase_loop + move.w (A2),D0 + btst #7,D0 + bne.s erase_sector_end + addq.l #4,SP + moveq #-10,D0 // write error + bra program_param_loop_end +erase_sector_end: + lea -MAX_PARAM_FLASH*4(A6),A0 // buffer + move.w #CMD_PROGRAM,D5 + moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter +program_byte_loop: + moveq #15,D7 // retry counter +program_byte_retry: + move.w D3,(A3) // unlock + move.w D4,(A4) + move.w D5,(A3) // Byte program command + move.w (A0),D0 + move.w D0,(A2) + and.l #0x80,D0 +wait_program_loop: + move.w (A2),D1 + eor.l D0,D1 + btst #7,D1 + beq.s wait_program_loop_end + btst #5,D1 // error + beq.s wait_program_loop + move.w (A2),D1 + eor.l D0,D1 + btst #7,D1 + beq.s wait_program_loop_end +program_byte_error: + subq.l #1,D7 + bpl.s program_byte_retry + addq.l #4,SP + moveq #-10,D0 // write error + bra.s program_param_loop_end +wait_program_loop_end: + move.w (A2),D1 + cmp.w (A0),D1 + bne.s program_byte_error + addq.l #2,A2 + addq.l #2,A0 + subq.l #1,D6 + bpl program_byte_loop + move.l (SP)+,D0 +program_param_loop_end: + move.w #CMD_READ,D5 + move.w D3,(A3) + move.w D4,(A4) + move.w D5,(A3) // Read/Reset command +program_param_loop_end_2: + move.l MCF_FBCS_CSMR0,D3 + or.l #MCF_FBCS_CSMR_WP,D3 // protect flash + move.l D3,MCF_FBCS_CSMR0 + rts + +devices: + dc.l 0x00C222CB, mx_29lv640-devices + dc.l 0 + +mx_29lv640: + dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE /* bottom boot block */ + dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 + +#else /* MCF548X - M5484LITE */ + + move.l D2,-(SP) // save value + lea devices(PC),A1 + add.l 4(A1),A1 // sector of device + move.l MCF_SIU_JTAGID,D0 // check the processor (not a good method => must check the flash device !) + and.l #MCF_SIU_JTAGID_PROCESSOR,D0 + cmp.l #MCF_SIU_JTAGID_MCF5485,D0 + beq.s .m5485evb // M5485EVB 16F160C3 + lea devices(PC),A1 // M5484LITE 28F320C3 + add.l 4+8(A1),A1 // sector of device +.m5485evb: + movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 + move.l MCF_FBCS_CSAR0,D3 // boot flash + and.l #0xFFFF0000,D3 + add.l D3,A2 // base parameters + add.l D6,A2 // offset free block + add.l D3,A3 // base parameters (last sector) + move.w #CMD_UNLOCK1,(A3) + move.w #CMD_UNLOCK2,(A3) + tst.w D7 + beq.s erase_sector_end + move.w #CMD_SECTOR_ERASE1,(A3) + move.w #CMD_SECTOR_ERASE2,(A3) // Erase sector command +wait_erase_loop: + move.w #CMD_STATUS,(A3) + move.w (A3),D0 + btst #7,D0 + beq.s wait_erase_loop + move.w #CMD_READ,(A3) +erase_sector_end: + lea -MAX_PARAM_FLASH*4(A6),A0 // buffer + moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter +program_byte_loop: + move.w #CMD_PROGRAM,(A2) // Byte program command + move.w (A0),(A2) +wait_program_loop: + move.w #CMD_STATUS,(A2) + move.w (A2),D0 + btst #7,D0 + beq.s wait_program_loop + move.w #CMD_READ,(A2) + move.w (A2),D0 + cmp.w (A0),D0 + beq.s program_byte_ok + addq.l #4,SP + moveq #-10,D0 // write error + bra.s program_param_loop_end +program_byte_ok: + addq.l #2,A2 + addq.l #2,A0 + subq.l #1,D6 + bpl.s program_byte_loop + move.l (SP)+,D0 +program_param_loop_end: + move.w #CMD_LOCK1,(A3) + move.w #CMD_LOCK2,(A3) + move.w #CMD_READ,(A3) + rts + +devices: + dc.l 0x008988C2, intel_28f160c3b-devices // M5485EVB + dc.l 0x008988C4, intel_28f320c3b-devices // M5484LITE + dc.l 0 + +intel_28f160c3b: + dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE + dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 + +intel_28f320c3b: + dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE + dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 + +#endif /* MCF547X */ +#endif /* MCF5445X */ + +#else /* ATARI - CT60 */ + +ct60_rw_param: // D0.W: mode, D1.L: type_param, D2.L: value + + movem.l D1-A5,-(SP) + link A6,#-MAX_PARAM_FLASH*4 + tst.l D1 + bmi out_param + cmp.l #MAX_PARAM_FLASH-1,D1 // type_param + bcc out_param + addq.l #1,D1 + asl.l #2,D1 // param * 4 + lea FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0xFF000000,A2 + moveq #-1,D3 + move.l #NB_BLOCK_PARAM-1,D4 + moveq #0,D6 +find_last_block: + cmp.l (A2),D3 + beq.s test_free_block +next_block: + lea SIZE_BLOCK_PARAM(A2),A2 + add.l #SIZE_BLOCK_PARAM,D6 // offset free block + dbf D4,find_last_block + moveq #0,D6 // offset free block + lea -SIZE_BLOCK_PARAM(A2),A2 + moveq #-1,D7 // erase sector if writing + bra.s test_read +test_free_block: + lea 4(A2),A3 + moveq #MAX_PARAM_FLASH-2,D5 +loop_test_free_block: + cmp.l (A3)+,D3 + dbne D5,loop_test_free_block + bne.s next_block + moveq #0,D7 // writing inside the next block + tst.l D6 + beq.s test_read // 1st block is free block + lea -SIZE_BLOCK_PARAM(A2),A2 +test_read: + and #1,D0 // mode + beq read_param + move.l (A2,D1.l),D0 + cmp.l D0,D2 + beq end_param // no change + lea -MAX_PARAM_FLASH*4(A6),A3 + addq.l #4,A2 + clr.l (A3)+ // block used + moveq #MAX_PARAM_FLASH-2,D0 +save_param: + move.l (A2)+,(A3)+ // save params in the stack + dbf D0,save_param // before erase sector command + move.l D2,-MAX_PARAM_FLASH*4(A6,D1.l) // value +// move.w SR,-(SP) +// or #0x700,SR // lock interrupts + bsr ct60_write_param // since boot 2.0 TOS run always in RAM so it's possible to write flash without run flasher in RAM and lock interrupts +// move.w (SP)+,SR + bra.s end_param +read_param: + move.l (A2,D1.l),D0 + bra.s end_param +out_param: + moveq #-5,D0 // unimplemented opcode +end_param: + unlk A6 + movem.l (SP)+,D1-A5 + rts + +ct60_write_param: + + moveq #3,D3 + movec.l D3,SFC // CPU space 3 + movec.l D3,DFC + move.l D2,-(SP) // save value + lea FLASH_UNLOCK1+0xFF000000,A0 + lea FLASH_UNLOCK2+0xFF000000,A1 + lea FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0xFF000000,A2 + move.w #CMD_UNLOCK1,D3 + move.w #CMD_UNLOCK2,D4 + move.w #CMD_AUTOSELECT,D5 + move.w #CMD_READ,D1 + moves.w D3,(A0) // unlock + moves.w D4,(A1) + moves.w D5,(A0) // Autoselect command + move.l (A2),D0 // Manufacturer code / Device code + moves.w D1,(A2) // Read/Reset command + lea devices(PC),A3 +loop_dev: + tst.l (A3) + beq no_dev + cmp.l (A3),D0 + beq.s found_dev + addq.l #8,A3 + bra.s loop_dev +no_dev: + addq.l #4,SP + moveq #-15,D0 // device error + bra program_param_loop_end_2 +found_dev: + lea devices(PC),A1 + add.l 4(A3),A1 // sector of device + movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 + add.l D6,A2 // offset free block + tst.w D7 + beq.s erase_sector_end + move.w #CMD_SECTOR_ERASE1,D5 + move.w #CMD_SECTOR_ERASE2,D6 + moves.w D3,(A3) // unlock + moves.w D4,(A4) + moves.w D5,(A3) + moves.w D3,(A3) // unlock + moves.w D4,(A4) + moves.w D6,(A2) // Erase sector command +wait_erase_loop: + move.w (A2),D0 + btst #7,D0 + bne.s erase_sector_end + btst #5,D0 + beq.s wait_erase_loop + move.w (A2),D0 + btst #7,D0 + bne.s erase_sector_end + addq.l #4,SP + moveq #-10,D0 // write error + bra.s program_param_loop_end +erase_sector_end: + lea -MAX_PARAM_FLASH*4(A6),A0 // buffer + move.w #CMD_PROGRAM,D5 + moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter +program_byte_loop: + moveq #15,D7 // retry counter +program_byte_retry: + moves.w D3,(A3) // unlock + moves.w D4,(A4) + moves.w D5,(A3) // Byte program command + move.w (A0),D0 + moves.w D0,(A2) + and.b #0x80,D0 +wait_program_loop: + move.w (A2),D1 + eor.b D0,D1 + bpl.s wait_program_loop_end + btst #5,D1 // error + beq.s wait_program_loop + move.w (A2),D1 + eor.b D0,D1 + bpl.s wait_program_loop_end +program_byte_error: + dbf D7,program_byte_retry + addq.l #4,SP + moveq #-10,D0 // write error + bra.s program_param_loop_end +wait_program_loop_end: + move.w (A2),D1 + cmp.w (A0),D1 + bne.s program_byte_error + addq.l #2,A2 + addq.l #2,A0 + dbf D6,program_byte_loop + move.l (SP)+,D0 +program_param_loop_end: + move.w #CMD_READ,D5 + moves.w D3,(A3) + moves.w D4,(A4) + moves.w D5,(A3) // Read/Reset command +program_param_loop_end_2: + rts + +devices: + dc.l 0x000422AB, fujitsu_mbm29f400bc-devices + dc.l 0x00042258, fujitsu_mbm29f800ba-devices + dc.l 0x00012258, amd_am29f800bb-devices + dc.l 0x00202258, st_m29f800db-devices + dc.l 0 + +fujitsu_mbm29f400bc: + dc.l FLASH_ADR+0xFF0F0000, FLASH_UNLOCK1+0xFF000000, FLASH_UNLOCK2+0xFF000000 + +fujitsu_mbm29f800ba: +amd_am29f800bb: +st_m29f800db: + dc.l FLASH_ADR+0xFF0F0000, FLASH_UNLOCK1+0xFF000000, FLASH_UNLOCK2+0xFF000000 + +end_ct60_write_param: + +#endif /* COLDFIRE */ + + .chip 68060 + +init_flash_parameters: + + moveq #14,D7 +.loop_init_params: + moveq #-1,D2 + move.l D7,D1 + moveq #CT60_MODE_WRITE,D0 +#ifdef COLDFIRE + bsr fire_rw_param +#else + bsr ct60_rw_param +#endif + cmp.l #-1,D0 + dblt D7,.loop_init_params + jmp 0xE0398C // reset NVM + diff --git a/flash.tos/tos/aes.S b/flash.tos/tos/patches/aes.S similarity index 91% rename from flash.tos/tos/aes.S rename to flash.tos/tos/patches/aes.S index 024123e..e5fb96f 100644 --- a/flash.tos/tos/aes.S +++ b/flash.tos/tos/patches/aes.S @@ -1,5 +1,4 @@ -/* TOS 4.04 AES Coldfire patchs -* and SHBUF patch for the CT60 board +/* TOS 4.04 AES patchs for the CT60 / Coldfire boards * Didier Mequignon 2003-2008, e-mail: aniplay@wanadoo.fr * SHBUF patch from SHBUF.FIL / Martin Osieka * @@ -331,23 +330,14 @@ begin34: lea.l 0xE28206,A0 end34: - .globl fix_bug_nvdi - - .align 2 - .long 0x34258 - .long end35-begin35+0x80000000 -begin35: - jsr fix_bug_nvdi -end35: - .globl det_evnt_multi .align 2 .long 0x20122 - .long end36-begin36+0x80000000 -begin36: + .long end35-begin35 +begin35: jsr det_evnt_multi -end36: +end35: #ifdef COLDFIRE @@ -357,105 +347,117 @@ end36: .align 2 .long 0x3475A - .long end37-begin37+0x80000000 -begin37: + .long end36-begin36 +begin36: jmp _dsptch -end37: +end36: .globl _savestate .align 2 .long 0x34776 - .long end38-begin38+0x80000000 -begin38: + .long end37-begin37 +begin37: jmp _savestate -end38: +end37: .globl _switchto .align 2 .long 0x347B8 - .long end39-begin39+0x80000000 -begin39: + .long end38-begin38 +begin38: jmp _switchto -end39: +end38: .globl _gotopgm .align 2 .long 0x347E4 - .long end40-begin40+0x80000000 -begin40: + .long end39-begin39 +begin39: jmp _gotopgm -end40: +end39: .globl _psetup .align 2 .long 0x34810 - .long end41-begin41+0x80000000 -begin41: + .long end40-begin40 +begin40: jmp _psetup -end41: +end40: .chip 68060 .align 2 .long 0x1F38C - .long end42-begin42 -begin42: + .long end41-begin41 +begin41: move.l #ustack_aes,SP -end42: +end41: .globl det_aes .align 2 .long 0x34432 - .long end43-begin43+0x80000000 -begin43: + .long end42-begin42 +begin42: move.l #det_aes,0x88 -end43: +end42: .align 2 .long 0x3443C - .long end44-begin44+0x80000000 -begin44: + .long end43-begin43 +begin43: move.l #det_aes,0x88 -end44: +end43: .globl _far_mchange .align 2 .long 0x35664 - .long end45-begin45+0x80000000 -begin45: + .long end44-begin44 +begin44: jmp _far_mchange -end45: +end44: .globl _far_bchange .align 2 .long 0x355D8 - .long end46-begin46+0x80000000 -begin46: + .long end45-begin45 +begin45: jmp _far_bchange -end46: +end45: .globl _forkq .align 2 .long 0x21AD8 - .long end47-begin47+0x80000000 -begin47: + .long end46-begin46 +begin46: jmp _forkq -end47: +end46: +#if 0 + .globl userdef_call + + .align 2 + .long 0x2C2DA + .long end47-begin47 +begin47: + jsr userdef_call +end47: #endif + +#endif /* COLDFIRE */ + .globl patch_tran_check .align 2 .long 0x2E91A - .long end48-begin48+0x80000000 + .long end48-begin48 begin48: jmp patch_tran_check end48: @@ -478,8 +480,18 @@ end50: .align 2 .long 0x4800C - .long end51-begin51+0x80000000 + .long end51-begin51 begin51: jmp patch_set_video end51: + .align 2 + .long 0x24A5E + .long end52-begin52 +begin52: // setres gl_vdo test (cookie _VDO with 0x30000) removed + nop + nop +end52: + + + diff --git a/flash.tos/tos/bios.S b/flash.tos/tos/patches/bios.S similarity index 61% rename from flash.tos/tos/bios.S rename to flash.tos/tos/patches/bios.S index 65cc908..426c391 100644 --- a/flash.tos/tos/bios.S +++ b/flash.tos/tos/patches/bios.S @@ -1,5 +1,5 @@ /* TOS 4.04 Bios patch for the CT60 board -* Didier Mequignon 2002-2006, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2002-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,11 +20,15 @@ .text +#ifndef COLDFIRE /* conout.c */ + +#ifdef COLDFIRE + .globl _bconout2 .align 2 .long 0xEBE - .long end1-begin1+0xC0000000 + .long end1-begin1 begin1: .long _bconout2 end1: @@ -33,7 +37,7 @@ end1: .align 2 .long 0xECA - .long end2-begin2+0xC0000000 + .long end2-begin2 begin2: .long _bconout5 end2: @@ -42,7 +46,7 @@ end2: .align 2 .long 0x1094C - .long end3-begin3+0xC0000000 + .long end3-begin3 begin3: .long normal_ascii end3: @@ -51,18 +55,86 @@ end3: .align 2 .long 0xD18 - .long end4-begin4+0xC0000000 + .long end4-begin4 begin4: .long _blink end4: -#ifdef COLDFIRE +#endif /* COLDFIRE */ + + .globl _sb_cell + .globl _sb_scrup + .globl _sb_scrdn + .globl _sb_blank + + .align 2 + .long 0x13268 + .long end20-begin20 +begin20: + .long _sb_cell + .long _sb_scrup + .long _sb_scrdn + .long _sb_blank +end20: + + .globl _sb_neg_cell + .globl _sb_move_cursor + + .align 2 + .long 0x132A4 + .long end21-begin21 +begin21: + .long _sb_neg_cell + .long _sb_move_cursor +end21: + +#else /* conout.S */ + + .globl _bconout2 + + .align 2 + .long 0xEBE + .long end1-begin1 +begin1: + .long _bconout2 +end1: + + .globl _bconout5 + + .align 2 + .long 0xECA + .long end2-begin2 +begin2: + .long _bconout5 +end2: + + .globl normal_ascii + + .align 2 + .long 0x1094C + .long end3-begin3 +begin3: + .long normal_ascii +end3: + + .globl _blink + + .align 2 + .long 0xD18 + .long end4-begin4 +begin4: + .long _blink +end4: + +#endif /* conout.c */ + +#if defined(COLDFIRE) && !defined(MCF547X) .globl auxistat .align 2 .long 0xE5A - .long end5-begin5+0xC0000000 + .long end5-begin5 begin5: .long auxistat end5: @@ -71,7 +143,7 @@ end5: .align 2 .long 0xE7A - .long end6-begin6+0xC0000000 + .long end6-begin6 begin6: .long auxin end6: @@ -80,7 +152,7 @@ end6: .align 2 .long 0xE9A - .long end7-begin7+0xC0000000 + .long end7-begin7 begin7: .long auxostat end7: @@ -89,65 +161,69 @@ end7: .align 2 .long 0xEBA - .long end8-begin8+0xC0000000 + .long end8-begin8 begin8: .long auxout end8: +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ + +#ifdef COLDFIRE + .globl error_ok .align 2 .long 0xE76 - .long end9-begin9+0xC0000000 + .long end9-begin9 begin9: // centronics .long error_ok end9: .align 2 .long 0xE96 - .long end10-begin10+0xC0000000 + .long end10-begin10 begin10: // centronics .long error_ok end10: .align 2 .long 0xEB6 - .long end11-begin11+0xC0000000 + .long end11-begin11 begin11: // centronics .long error_ok end11: .align 2 .long 0xE62 - .long end12-begin12+0xC0000000 + .long end12-begin12 begin12: // MIDI .long error_ok end12: .align 2 .long 0xE82 - .long end13-begin13+0xC0000000 + .long end13-begin13 begin13: // MIDI .long error_ok end13: .align 2 .long 0xEA6 - .long end14-begin14+0xC0000000 + .long end14-begin14 begin14: // MIDI .long error_ok end14: .align 2 .long 0xEC2 - .long end15-begin15+0xC0000000 + .long end15-begin15 begin15: // MIDI .long error_ok end15: .align 2 .long 0xEA2 - .long end16-begin16+0xC0000000 + .long end16-begin16 begin16: // IKBD .long error_ok end16: @@ -156,7 +232,7 @@ end16: .align 2 .long 0xEC6 - .long end17-begin17+0xC0000000 + .long end17-begin17 begin17: // IKBD .long ikbdwc end17: @@ -165,7 +241,7 @@ end17: .align 2 .long 0x228 - .long end18-begin18+0x80000000 + .long end18-begin18 begin18: .short 0x21FC .long det_bios @@ -178,6 +254,6 @@ begin19: // vector table Rwabs .long hdv_rw+1 end19: -#endif +#endif /* COLDFIRE */ diff --git a/flash.tos/tos/blitter.S b/flash.tos/tos/patches/blitter.S similarity index 75% rename from flash.tos/tos/blitter.S rename to flash.tos/tos/patches/blitter.S index 01b2fa6..20659ca 100644 --- a/flash.tos/tos/blitter.S +++ b/flash.tos/tos/patches/blitter.S @@ -1,5 +1,5 @@ -/* TOS 4.04 Blitter patch for the CT60 board -* Didier Mequignon 2002 December, e-mail: aniplay@wanadoo.fr +/* TOS 4.04 Blitter/VDI patch for the CT60 and Coldfire boards +* Didier Mequignon 2002/2011, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,11 +18,13 @@ .text +#ifndef COLDFIRE /* for reduce boot size, blitter not exist */ + .globl copy_fonts .align 2 .long 0x00000590 /* offset ROM */ - .long end1-begin1+0x80000000 + .long end1-begin1 begin1: jsr copy_fonts end1: @@ -31,7 +33,7 @@ end1: .align 2 .long 0x0000DB54 /* offset ROM */ - .long end2-begin2+0x80000000 + .long end2-begin2 begin2: jsr get_font_6x6_a0 nop @@ -41,7 +43,7 @@ end2: .align 2 .long 0x0000DB78 /* offset ROM */ - .long end3-begin3+0x80000000 + .long end3-begin3 begin3: jsr get_font_6x6_a6 nop @@ -51,7 +53,7 @@ end3: .align 2 .long 0x0000E272 /* offset ROM */ - .long end4-begin4+0x80000000 + .long end4-begin4 begin4: jsr get_font_6x6_a5 end4: @@ -60,7 +62,7 @@ end4: .align 2 .long 0x0000E786 /* offset ROM */ - .long end5-begin5+0x80000000 + .long end5-begin5 begin5: jsr get_font_6x6_a3 end5: @@ -71,7 +73,7 @@ end5: .align 2 .long 0x00010D5E /* offset ROM */ - .long end6-begin6+0x80000000 + .long end6-begin6 begin6: jsr get_font_8x8_a1 end6: @@ -80,7 +82,7 @@ end6: .align 2 .long 0x00010D72 /* offset ROM */ - .long end8-begin8+0x80000000 + .long end8-begin8 begin8: jsr get_font_8x16_a1 end8: @@ -89,7 +91,7 @@ end8: .align 2 .long 0x00010D86 /* offset ROM */ - .long end10-begin10+0x80000000 + .long end10-begin10 begin10: jsr get_font_8x16_a1b end10: @@ -98,21 +100,21 @@ end10: .align 2 .long 0x00010F8E /* offset ROM */ - .long end7-begin7+0x80000000 + .long end7-begin7 begin7: jsr get_font_8x8_a1 end7: .align 2 .long 0x00010FA2 /* offset ROM */ - .long end9-begin9+0x80000000 + .long end9-begin9 begin9: jsr get_font_8x16_a1 end9: .align 2 .long 0x00010FB6 /* offset ROM */ - .long end11-begin11+0x80000000 + .long end11-begin11 begin11: jsr get_font_8x16_a1b end11: @@ -121,31 +123,43 @@ end11: .align 2 .long 0x0000951A /* offset ROM */ - .long end12-begin12+0x80000000 + .long end12-begin12 begin12: jsr get_font_ptr_a1 end12: +#endif /* COLDFIRE */ + .globl logo_atari .align 2 .long 0x00000660 /* offset ROM */ - .long end13-begin13+0x80000000 + .long end13-begin13 begin13: jmp logo_atari end13: -//#ifndef COLDFIRE + +#ifndef COLDFIRE /* for reduce boot size, blitter not exist */ .globl det_vdi .align 2 .long 0x1DF48 - .long end14-begin14+0x80000000 + .long end14-begin14 begin14: .short 0x41F9 .long det_vdi end14: -//#endif +#endif /* COLDFIRE */ + + .align 2 + .long 0x4D4F0 // ROM_INQ_TAB[14] bug entry in TOS404 (MAX_VERT is a pointer ???) + .long end15-begin15 +begin15: + .short 128,-1,2,0 +end15: + + diff --git a/flash.tos/tos/patches/boot.S b/flash.tos/tos/patches/boot.S new file mode 100644 index 0000000..05d9d8b --- /dev/null +++ b/flash.tos/tos/patches/boot.S @@ -0,0 +1,192 @@ +/* TOS 4.04 Boot order patch for the CT60 / Coldfire board(s) +* HD vectors patchs for the Fire Engine Coldfire board +* Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "main.h" +#include "vars.h" +#ifdef COLDFIRE +#include "fire.h" +#endif + + .text + +#ifdef COLDFIRE + .globl init_cf +#else + .globl init_060 +#endif + + .align 2 + .long 0x30 + .long end1-begin1 +begin1: +#ifdef COLDFIRE + move.l #init_cf-FLASH_ADR+FLASH_TOS_FIRE_ENGINE,D1 + lea end1(PC),A0 + cmp.l #FLASH_ADR,A0 + bcs.s .not_original_space + cmp.l #FLASH_ADR+0x100000,A0 + bcc.s .not_original_space + sub.l #FLASH_TOS_FIRE_ENGINE,D1 + add.l #FLASH_ADR,D1 + move.l D1,A0 // started from TOS space (copy by a boot) + jmp (A0) +.not_original_space: // started from flash or 0x1000000 offset (RAM) + move.l A0,D0 + and.l #0xFF000000,D0 // flash base + and.l #0x00FFFFFF,D1 // offset + or.l D1,D0 + move.l D0,A0 + jmp (A0) // init_cf +#else + jmp init_060 +#endif +end1: + + .globl init_sdram + + .align 2 + .long 0x632 + .long end2-begin2 +begin2: + jsr init_sdram +end2: + + .globl add_sdram + + .align 2 + .long 0x96E + .long end3-begin3 +begin3: + jmp add_sdram +end3: + + .globl init_ram_test + + .align 2 + .long 0x7952 + .long end4-begin4 +begin4: + jsr init_ram_test + nop + nop +end4: + + .globl display_ram_test + + .align 2 + .long 0x7D5A + .long end5-begin5 +begin5: + jmp display_ram_test +end5: + + .globl menu_boot + + .align 2 + .long 0x798 + .long end6-begin6 +begin6: + jsr menu_boot +end6: + + .globl boot_drive + + .align 2 + .long 0xB42 + .long end7-begin7 +begin7: + jmp boot_drive +end7: + + .align 2 + .long 0x17EA + .long end8-begin8 +begin8: + .short 0x11 +end8: + +#ifdef COLDFIRE + .chip 68060 + +#ifndef MCF547X + // Floppy BIOS routines removed + + .globl error_unknow_device + .globl error_ok + + .align 2 + .long 0x312 + .long end9-begin9 +begin9: + move.l #error_unknow_device,hdv_rw +end9: + + .align 2 + .long 0x31A + .long end10-begin10 +begin10: + move.l #error_ok,hdv_bpb +end10: + + .align 2 + .long 0x322 + .long end11-begin11 +begin11: + move.l #error_unknow_device,hdv_mediach +end11: + + .align 2 + .long 0x30A + .long end12-begin12 +begin12: + move.l #error_unknow_device,hdv_init +end12: + + .align 2 + .long 0x760 + .long end13-begin13 +begin13: // FDC/HDC + nop + nop + nop +end13: + +#endif /* MCF547X */ + + .globl check_tos_crc + + .align 2 + .long 0x1508 + .long end14-begin14 +begin14: + jmp check_tos_crc +end14: + +#if 1 // not used + .globl bootload + + .align 2 + .long 0x32A + .long end15-begin15 +begin15: + move.l #bootload,hdv_boot +end15: +#endif + +#endif /* COLDFIRE */ diff --git a/flash.tos/tos/cache.S b/flash.tos/tos/patches/cache.S similarity index 70% rename from flash.tos/tos/cache.S rename to flash.tos/tos/patches/cache.S index 779fb71..f2d08d5 100644 --- a/flash.tos/tos/cache.S +++ b/flash.tos/tos/patches/cache.S @@ -1,26 +1,21 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert - * 2005-2006 Didier Mequignon - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ +/* TOS 4.04 patch for the CT60 / Coldire board(s) +* Copyright (C) 2001 Xavier Joubert +* 2005-2006 Didier Mequignon +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ .text @@ -28,8 +23,6 @@ #include "fire.h" - .globl flush_caches_x - .globl flush_caches_z .globl flush_caches .globl flush_data_cache .globl caches_disable @@ -39,72 +32,81 @@ .long 0x638 .long end1-begin1 begin1: - jsr 0xE250C8 + jsr caches_enable nop nop end1: .align 2 - .long 0x904 - .long end2-begin2+0x80000000 + .long 0x908 + .long end2-begin2 begin2: - jsr flush_caches_x + .chip 68060 + cpusha bc + .chip 68060 nop end2: .align 2 - .long 0x920 + .long 0x92A .long end3-begin3 begin3: - jsr flush_caches_z - nop - nop - nop + .chip 68060 + cpusha bc + .chip 5200 nop end3: .align 2 - .long 0x946 - .long end4-begin4+0x80000000 + .long 0x94A + .long end4-begin4 begin4: - jsr flush_caches_x + .chip 68060 + cpusha bc + .chip 5200 nop end4: .align 2 - .long 0xDF4 - .long end5-begin5+0x80000000 + .long 0xDF6 + .long end5-begin5 begin5: - jsr flush_caches_x + .chip 68060 + cpusha bc + .chip 5200 nop end5: .align 2 - .long 0x43B0 - .long end6-begin6+0x80000000 -begin6: - jsr flush_caches_x - clr.l -(sp) + .long 0x43B4 + .long end6-begin6 +begin6: // Floppy + .chip 68060 + cpusha bc + .chip 5200 + nop end6: .align 2 - .long 0x46CA - .long end7-begin7+0x80000000 -begin7: - jsr flush_caches_x + .long 0x46CC + .long end7-begin7 +begin7: // Floppy + .chip 68060 + cpusha bc + .chip 5200 nop end7: .align 2 .long 0x85A - .long end8-begin8+0x80000000 + .long end8-begin8 begin8: jmp caches_disable end8: .align 2 .long 0x18CA - .long end9-begin9+0x80000000 + .long end9-begin9 begin9: jsr flush_caches bra.s begin9-0x18CA+0x18DE @@ -114,11 +116,11 @@ end9: .long 0x1944 .long end10-begin10 begin10: - jsr flush_data_cache+0x80000000 + jsr flush_data_cache bra.s begin10-0x18CA+0x18DE end10: -#else // 68060 +#else /* 68060 */ .align 2 .long 0x638 @@ -207,7 +209,7 @@ begin10: bra.s begin10-0x18CA+0x18DE end10: -#endif // COLDFIRE +#endif /* COLDFIRE */ .align 2 .long 0x3990 @@ -243,27 +245,27 @@ loop13: roxr.l #1,D2 bcs.s set13 move.w D0,(A0)+ - dbf D3,loop13 + dbf D3,loop13 move.w A1,(A0)+ cpusha BC rts set13: move.w D1,(A0)+ - dbf D3,loop13 + dbf D3,loop13 move.w A1,(A0)+ cpusha BC rts code13: and.w D0,(A5)+ or.w D1,(A5)+ - jmp (A3) + jmp (A3) nop nop nop nop end13: -#endif +#endif /* COLDFIRE */ .align 2 .long 0x11BCE @@ -377,7 +379,7 @@ end28: .long 0x44544 .long end29-begin29 begin29: - jsr 0xE250C8 + jsr caches_enable bra.s begin29-0x44544+0x44578 end29: @@ -385,11 +387,11 @@ end29: .long 0x4454E .long end30-begin30 begin30: - jsr 0xE0085A + jsr caches_disable bra.s begin30-0x4454E+0x44584 end30: -#else +#else /* 68060 */ .align 2 .long 0x44528 @@ -409,12 +411,12 @@ begin30: bra.s begin30-0x44544+0x44584 end30: -#endif +#endif /* COLDFIRE */ .align 2 .long 0x250C8 #ifdef COLDFIRE - .long end31-begin31+0x80000000 + .long end31-begin31 begin31: jmp caches_enable #else @@ -441,3 +443,12 @@ begin32: #endif end32: + .globl fix_bug_nvdi + + .align 2 + .long 0x34258 + .long end33-begin33 +begin33: + jsr fix_bug_nvdi // disable cache during v_opnwk +end33: + diff --git a/flash.tos/tos/cartridge.S b/flash.tos/tos/patches/cartridge.S similarity index 100% rename from flash.tos/tos/cartridge.S rename to flash.tos/tos/patches/cartridge.S diff --git a/flash.tos/tos/cookies.S b/flash.tos/tos/patches/cookies.S similarity index 52% rename from flash.tos/tos/cookies.S rename to flash.tos/tos/patches/cookies.S index d61a75d..f7ccde7 100644 --- a/flash.tos/tos/cookies.S +++ b/flash.tos/tos/patches/cookies.S @@ -1,31 +1,33 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert, 2004-2006 Didier Mequignon - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ +/* TOS 4.04 patch for the CT60 / Coldfire board(s) +* Copyright (C) 2001 Xavier Joubert +* 2004-2010 Didier Mequignon +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ .text -#include "ct60.h" +#include "ct60.h" -#define rw_parameter 0xc60b +#ifdef COLDFIRE +#include "fire.h" + + .globl fire_rw_param +#else + .globl ct60_rw_param +#endif .align 2 .long 0x3C4 @@ -60,22 +62,14 @@ begin2: movec.l PCR,D0 btst #16,D0 bne.s .no_fpu // EC or LC - movem.l D1-D2/A0-A2,-(SP) -#else - lea -20(SP),SP - movem.l D1-D2/A0-A2,(SP) #endif - clr.l -(SP) - move.l #CT60_CPU_FPU,-(SP) - move.w #CT60_MODE_READ,-(SP) - move.w #rw_parameter,-(SP) - trap #14 - lea 12(SP),SP -#ifndef COLDFIRE - movem.l (SP)+,D1-D2/A0-A2 + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_CPU_FPU,D1 // type_param + moveq #0,D2 // value +#ifdef COLDFIRE + jsr fire_rw_param #else - movem.l (SP),D1-D2/A0-A2 - lea 20(SP),SP + jsr ct60_rw_param #endif btst #0,D0 bne.s .with_fpu @@ -126,15 +120,19 @@ end5: .long 0x42E .long end6-begin6 begin6: // _SWI +#ifdef MCF547X + move.b MCF_GPIO_PPDSDR_PSC3PSC2,D0 +#else /* MCF548X */ nop nop nop +#endif /* MCF547X */ end6: .globl before_init_cookies .align 2 .long 0x3B0 - .long end7-begin7+0x80000000 + .long end7-begin7 begin7: jsr before_init_cookies nop diff --git a/flash.tos/tos/dsp.S b/flash.tos/tos/patches/dsp.S similarity index 100% rename from flash.tos/tos/dsp.S rename to flash.tos/tos/patches/dsp.S diff --git a/flash.tos/tos/patches/end.S b/flash.tos/tos/patches/end.S new file mode 100644 index 0000000..e80e0f5 --- /dev/null +++ b/flash.tos/tos/patches/end.S @@ -0,0 +1,24 @@ +/* TOS 4.04 patch for the CT60 board +* Didier Mequignon 2010, e-mail: aniplay@wanadoo.fr +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + + .globl _ct60tos_end_patch + + .text + + .align 2 +_ct60tos_end_patch: diff --git a/flash.tos/tos/gemdos.S b/flash.tos/tos/patches/gemdos.S similarity index 88% rename from flash.tos/tos/gemdos.S rename to flash.tos/tos/patches/gemdos.S index 0f829b3..76d2b08 100644 --- a/flash.tos/tos/gemdos.S +++ b/flash.tos/tos/patches/gemdos.S @@ -25,7 +25,7 @@ .align 2 .long 0x1F164 /* Pexec */ - .long end1-begin1+0x80000000 + .long end1-begin1 begin1: jsr flush_cache_pexec end1: @@ -34,7 +34,7 @@ end1: .align 2 .long 0x1DF62 - .long end2-begin2+0x80000000 + .long end2-begin2 begin2: .short 0x41F9 .long det_gemdos @@ -44,7 +44,7 @@ end2: .align 2 .long 0x214 - .long end3-begin3+0x80000000 + .long end3-begin3 begin3: move.l #det_vbl,0x70.w end3: @@ -55,7 +55,7 @@ end3: .align 2 .long 0x1C382 - .long end4-begin4+0x80000000 + .long end4-begin4 begin4: jmp _gouser end4: @@ -64,7 +64,7 @@ end4: .align 2 .long 0x1C3C0 - .long end5-begin5+0x80000000 + .long end5-begin5 begin5: jmp _termuser end5: @@ -73,7 +73,7 @@ end5: .align 2 .long 0x1C3CC - .long end6-begin6+0x80000000 + .long end6-begin6 begin6: jmp _xsuper end6: diff --git a/flash.tos/tos/mfp.S b/flash.tos/tos/patches/movep.S similarity index 60% rename from flash.tos/tos/mfp.S rename to flash.tos/tos/patches/movep.S index 4595268..3d4b652 100644 --- a/flash.tos/tos/mfp.S +++ b/flash.tos/tos/patches/movep.S @@ -1,5 +1,6 @@ -/* TOS 4.04 patch for the Fire Engine Coldfire board -* Didier Mequignon 2006, e-mail: aniplay@wanadoo.fr +/* TOS 4.04 patch for the CT60 / Coldfire board(s) +* Copyright (C) 2001 Xavier Joubert +* 2006 Didier Mequignon * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,50 +17,50 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "fire.h" - .text - - .globl replace_mfp .align 2 - .long 0x526 - .long end1-begin1+0x80000000 + .long 0x25DC + .long end1-begin1 begin1: - jsr replace_mfp - nop - // tempo 5 mS MFP - nop - nop + .long 0x05018800 + lea 0xFFFFFA01.w,a0 + moveq #-24,d0 +loop1: clr.b 24(a0,d0.l) + addq.l #2,d0 + bne.s loop1 end1: - .globl int_timer_c_mfp +#ifndef COLDFIRE .align 2 - .long 0x3C50 - .long end2-begin2+0x80000000 -begin2: jmp int_timer_c_mfp + .long 0x526 + .long end2-begin2 +begin2: + bsr begin2-0x526+0x25E0 end2: - .globl tempo_reset_ikbd +#endif .align 2 - .long 0x544 - .long end3-begin3+0x80000000 -begin3: // tempo 20mS *15 MFP after IKBD reset - jsr tempo_reset_ikbd - nop - nop - nop - nop - nop + .long 0x2632 + .long end3-begin3 +begin3: + lea 0xFFFFFA27.w,a0 + move.l begin3-0x2632+0x25DC(pc),d0 +loop2: move.b d0,(a0) + addq.l #2,a0 + lsr.l #8,d0 + bne.s loop2 + tst.b 0xA87.w end3: + .globl movep_e02b1e + .align 2 - .long 0x62E + .long 0x2B1E .long end4-begin4 begin4: - nop + jsr movep_e02b1e nop end4: - diff --git a/flash.tos/tos/init_par.S b/flash.tos/tos/patches/params.S similarity index 76% rename from flash.tos/tos/init_par.S rename to flash.tos/tos/patches/params.S index 6fd9a10..b418615 100644 --- a/flash.tos/tos/init_par.S +++ b/flash.tos/tos/patches/params.S @@ -1,5 +1,5 @@ -/* TOS 4.04 Boot memory patch for the CT60 board -* Didier Mequignon 2003-2005, e-mail: aniplay@wanadoo.fr +/* XBIOS CT60 / Coldfire board(s) Parameters in Flash +* Didier Mequignon 2003-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,30 +22,10 @@ .align 2 .long 0xADA - .long end1-begin1+0x80000000 + .long end1-begin1 begin1: // CTRL-ALT-UNDO jmp init_flash_parameters end1: - .align 2 - .long 0x1B4 - .long end2-begin2 -begin2: - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -end2: diff --git a/flash.tos/tos/periph.S b/flash.tos/tos/patches/periph.S similarity index 67% rename from flash.tos/tos/periph.S rename to flash.tos/tos/patches/periph.S index 7c66e73..2f52a98 100644 --- a/flash.tos/tos/periph.S +++ b/flash.tos/tos/patches/periph.S @@ -1,25 +1,20 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ +/* TOS 4.04 patch for the CT60 / Coldfire board(s) +* Copyright (C) 2001 Xavier Joubert +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ .MACRO periph adr .align 2 diff --git a/flash.tos/tos/movep.S b/flash.tos/tos/patches/pmmu.S similarity index 61% rename from flash.tos/tos/movep.S rename to flash.tos/tos/patches/pmmu.S index b2f3eb7..9715fc6 100644 --- a/flash.tos/tos/movep.S +++ b/flash.tos/tos/patches/pmmu.S @@ -1,5 +1,5 @@ /* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert + * Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,57 +14,67 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * */ + + .text - .text +#ifdef COLDFIRE .align 2 - .long 0x25DC + .long 0x2BC .long end1-begin1 begin1: - .long 0x05018800 - lea 0xFFFFFA01.w,a0 - moveq #-24,d0 -loop1: clr.b 24(a0,d0.w) - addq.l #2,d0 - bne.s loop1 + nop + nop end1: -#ifndef COLDFIRE +#else .align 2 - .long 0x526 + .long 0x14E6 + .long end1-begin1 +begin1: + // bra.s begin1-0x14E6+0x1506 + rts + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop + nop +end1: + +#endif + + .align 2 + .long 0x39A0 .long end2-begin2 begin2: - bsr begin2-0x526+0x25E0 + bra.s begin2-0x39A0+0x39B8 end2: -#endif - .align 2 - .long 0x2632 + .long 0x7A08 .long end3-begin3 begin3: - lea 0xFFFFFA27.w,a0 - move.l begin3-0x2632+0x25DC(pc),d0 -loop2: move.b d0,(a0) - addq.l #2,a0 - lsr.l #8,d0 - bne.s loop2 - tst.b 0xA87.w + moveq #9,D7 end3: - .globl movep_e02b1e - .align 2 - .long 0x2B1E - .long end4-begin4+0x80000000 + .long 0x7B1C + .long end4-begin4 begin4: - jsr movep_e02b1e - nop + moveq #9,D7 end4: + + diff --git a/flash.tos/tos/start.S b/flash.tos/tos/patches/start.S similarity index 82% rename from flash.tos/tos/start.S rename to flash.tos/tos/patches/start.S index 1be2eb4..2cf5294 100644 --- a/flash.tos/tos/start.S +++ b/flash.tos/tos/patches/start.S @@ -1,5 +1,5 @@ /* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert + * Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -14,11 +14,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * */ .text diff --git a/flash.tos/tos/vectors.S b/flash.tos/tos/patches/vectors.S similarity index 77% rename from flash.tos/tos/vectors.S rename to flash.tos/tos/patches/vectors.S index 9b63c4e..c154da4 100644 --- a/flash.tos/tos/vectors.S +++ b/flash.tos/tos/patches/vectors.S @@ -1,5 +1,5 @@ -/* TOS 4.04 Vectors patch for the CT60 board -* Didier Mequignon 2002 December, e-mail: aniplay@wanadoo.fr +/* TOS 4.04 Vectors / exceptions patch for the CT60 / Coldfire board(s) +* Didier Mequignon 2002-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -22,7 +22,7 @@ .align 2 .long 0x77E - .long end1-begin1+0x80000000 + .long end1-begin1 begin1: jsr init_vectors nop @@ -31,3 +31,12 @@ begin1: nop end1: + .globl exception + + .align 2 + .long 0x100C + .long end2-begin2 +begin2: + jmp exception +end2: + diff --git a/flash.tos/tos/videl.S b/flash.tos/tos/patches/videl.S similarity index 50% rename from flash.tos/tos/videl.S rename to flash.tos/tos/patches/videl.S index a40e9d2..6f1b189 100644 --- a/flash.tos/tos/videl.S +++ b/flash.tos/tos/patches/videl.S @@ -18,67 +18,13 @@ .text -#include "vars.h" - .globl picture_boot .align 2 .long 0x57E - .long end1-begin1+0x80000000 + .long end1-begin1 begin1: jsr picture_boot end1: -#ifdef COLDFIRE - - .align 2 - .long 0xCB0 - .long end2-begin2 -begin2: // VBL without palette and new screen - addq.l #1,_frclock - tst.w vblsem - bgt.s .vbl_ok - rte -.vbl_ok: - lea -60(SP),SP - movem.l D0-D7/A0-A6,(SP) - addq.l #1,_vbclock - clr.l colorptr - moveq #0,D7 - move.w nvbls,D7 - beq.s begin2-0xCB0+0xD1C - subq.l #1,D7 - move.l _vblqueue,A0 -.loop_vbl: - move.l (A0)+,A1 - move.l A1,D0 - beq.s .no_vbl - move.l D7,-(SP) - move.l A0,-(SP) - jsr (A1) - move.l (SP)+,A0 - move.l (SP)+,D7 -.no_vbl: - subq.l #1,D7 - bpl.s .loop_vbl - bra.s begin2-0xCB0+0xD16 // blink cursor BIOS -end2: - - .align 2 - .long 0xD1C // just after blink JSR - .long end3-begin3 -begin3: // VBL without palette and new screen (end) - tst.w _dumpflg - bne.s .no_dump - move.l dump_vec,A0 - jsr (A0) - moveq #-1,D0 - move.w D0,_dumpflg -.no_dump: - movem.l (SP),D0-D7/A0-A6 - lea 60(SP),SP - rte -end3: - -#endif diff --git a/flash.tos/tos/patches/xbios.S b/flash.tos/tos/patches/xbios.S new file mode 100644 index 0000000..cbb7f1d --- /dev/null +++ b/flash.tos/tos/patches/xbios.S @@ -0,0 +1,403 @@ +/* TOS 4.04 Xbios patch for the CT60 board +* Didier Mequignon 2002-2010, e-mail: aniplay@wanadoo.fr +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "vars.h" +#ifdef COLDFIRE +#include "fire.h" +#endif + + .text + +#ifdef COLDFIRE + .chip 68060 +#endif + + .globl det_xbios + + .align 2 + .long 0x230 + .long end1-begin1 +begin1: + .short 0x21FC + .long det_xbios +end1: + + .globl new_statvec + + .align 2 + .long 0x26C4 + .long end2-begin2 +begin2: + jsr new_statvec + nop + nop +end2: + + .globl new_ikbdvect + + .align 2 + .long 0x340A + .long end3-begin3 +begin3: + jsr new_ikbdvect + nop +end3: + + .globl nvm_access + + .align 2 + .long 0x216C + .long end4-begin4 +begin4: + jmp nvm_access +end4: + + .globl test_rtc + + .align 2 +#ifdef COLDFIRE + .long 0x2112 +#else + .long 0x212E +#endif + .long end5-begin5 +begin5: + jmp test_rtc +end5: + + .globl fix_settime + + .align 2 + .long 0x230E + .long end6-begin6 +begin6: + jsr fix_settime +end6: + + .align 2 + .long 0x2316 + .long end7-begin7 +begin7: + nop + nop +end7: + +#if !defined(COLDFIRE) || defined(MCF547X) + + .globl fix_gettime + + .align 2 + .long 0x2264 + .long end8-begin8 +begin8: + jsr fix_gettime +end8: + +#else /* COLDFIRE */ + + .globl gettime + + .align 2 + .long 0x22A0 + .long end9-begin9 +begin9: + jmp gettime +end9: + + .globl end_settime + + .align 2 + .long 0x231A + .long end10-begin10 +begin10: + jmp end_settime +end10: + +#endif /* !defined(COLDFIRE) || defined(MCF547X) */ + +#ifdef COLDFIRE + + .globl error_ok + + .align 2 + .long 0x332 + .long end11-begin11 +begin11: + move.l #error_ok,dump_vec +end11: + + .align 2 + .long 0x33A + .long end12-begin12 +begin12: + move.l #error_ok,ptr_stat +end12: + + .align 2 + .long 0x342 + .long end13-begin13 +begin13: + move.l #error_ok,ptr_vec +end13: + + .globl auxostat + + .align 2 + .long 0x34A + .long end14-begin14 +begin14: + move.l #auxostat,aux_sta +end14: + + .globl auxout + + .align 2 + .long 0x352 + .long end15-begin15 +begin15: + move.l #auxout,aux_vec +end15: + + .align 2 + .long 0x532 + .long end16-begin16 +begin16: // reset IKBD + nop + nop + nop + nop + nop + nop + nop + nop + nop +end16: + + // not need this patch since the VBL routine patch (videl.S) exist +#if 0 // #ifndef MCF547X + .align 2 + .long 0x429A + .long end17-begin17 +begin17: // flopvbl + rts +end17: +#endif /* MCF547X */ + + .globl _Setscreen + + .align 2 + .long 0x5A8 + .long end18-begin18 +begin18: + jsr _Setscreen +end18: + + .align 2 + .long 0x4654 + .long end19-begin19 +begin19: // Floppy (setdmode) + swap D0 + move.w 0x1694,D0 + cmp.w #1,_nflops + bne.s .b19 + move.w 0x88A0,D0 +.b19: + add.w D0,A0 + swap D0 + move.b D0,(A0) + rts +end19: + + .globl delay_80us + + .align 2 + .long 0x45F0 + .long end20-begin20 +begin20: // Floppy + jmp delay_80us +end20: + + .align 2 + .long 0x4542 + .long end21-begin21 +begin21: // Floppy + jsr delay_80us + nop + nop + nop + nop + nop + nop +end21: + + .globl replace_mfp + + .align 2 + .long 0x526 + .long end22-begin22 +begin22: + jsr replace_mfp + nop + // tempo 5 mS MFP + nop + nop +end22: + + .globl int_timer_c_mfp + + .align 2 + .long 0x3C50 + .long end23-begin23 +begin23: jmp int_timer_c_mfp +end23: + + .globl tempo_reset_ikbd + + .align 2 + .long 0x544 + .long end24-begin24 +begin24: // tempo 20mS *15 MFP after IKBD reset + jsr tempo_reset_ikbd + nop + nop + nop + nop + nop +end24: + + .align 2 + .long 0x62E + .long end25-begin25 +begin25: + nop + nop +end25: + + .align 2 + .long 0xCB0 + .long end26-begin26 +begin26: // VBL without palette and new screen + addq.l #1,_frclock + tst.w vblsem + bgt.s .vbl_ok + rte +.vbl_ok: + lea -60(SP),SP + movem.l D0-D7/A0-A6,(SP) + addq.l #1,_vbclock + clr.l colorptr + moveq #0,D7 + move.w nvbls,D7 + beq.s begin26-0xCB0+0xD1C + subq.l #1,D7 + move.l _vblqueue,A0 +.loop_vbl: + move.l (A0)+,A1 + move.l A1,D0 + beq.s .no_vbl + move.l D7,-(SP) + move.l A0,-(SP) + jsr (A1) + move.l (SP)+,A0 + move.l (SP)+,D7 +.no_vbl: + subq.l #1,D7 + bpl.s .loop_vbl + bra.s begin26-0xCB0+0xD16 // blink cursor BIOS +end26: + +#ifdef MCF547X + .global flopvbl + + .align 2 + .long 0xD1C // just after blink JSR + .long end27-begin27 +begin27: + jsr flopvbl +#else /* MCF548X */ + .align 2 + .long 0xD1C // just after blink JSR + .long end27-begin27 +begin27: +#endif /* MCF547X */ + // VBL without palette and new screen (end) + tst.w _dumpflg + bne.s .no_dump + move.l dump_vec,A0 + jsr (A0) + moveq #-1,D0 + move.w D0,_dumpflg +.no_dump: + movem.l (SP),D0-D7/A0-A6 + lea 60(SP),SP + rte +end27: + + .globl delay_5mS + + .align 2 + .long 0x2564 + .long end28-begin28 +begin28: // ACIA 6850 Atari keyboard + jsr delay_5mS + move.b D1,2(A1) + rts +end28: + +#ifdef MCF547X + + .globl end_settime_rtc + + .align 2 + .long 0x210A + .long end29-begin29 +begin29: + jmp end_settime_rtc +end29: + + .globl setporta + + .align 2 + .long 0x459C + .long end30-begin30 +begin30: + jmp setporta +end30: + + .globl waitdma + + .align 2 + .long 0x3F1A + .long end31-begin31 +begin31: + jsr waitdma + nop +end31: + + .align 2 + .long 0x412A + .long end32-begin32 +begin32: + jsr waitdma + nop +end32: + +#endif /* MCF547X */ + +#endif /* COLDFIRE */ + diff --git a/flash.tos/tos/pci_bios.S b/flash.tos/tos/pci_bios.S index 91cbc62..e98d277 100644 --- a/flash.tos/tos/pci_bios.S +++ b/flash.tos/tos/pci_bios.S @@ -1,7 +1,7 @@ /* PCI BIOS for CT60 with CTPCI * Coldfire MCF547X/MCF548X & MCF5445X * - * Didier Mequignon 2005-2009, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2005-2012 e-mail: aniplay@wanadoo.fr * Markus Froschle 2007 * * This library is free software; you can redistribute it and/or @@ -20,32 +20,39 @@ */ .text -#undef TEST_TARGET - #include "main.h" #include "ct60.h" #include "vars.h" #include "pci_bios.h" +#define SLOT_TO_DEBUG 1 + +#undef DISPLAY_SUBCLASS + #ifndef COLDFIRE #define LOCAL_REGISTERS_BIG -#define write_verify_local_config_longword write_local_config_longword +#define SAME_CPU_PCI_MEM_ADDR +#define TARGET_NO_CACHE_PCI_MEM #endif + .globl _install_pci_bios + .globl dummy_function // errata + _install_pci_bios: move.w 2(A0),D0 ext.l D0 -#ifdef COLDFIRE cmp.l #1,D0 // init - bne display_devices + blt display_devices +#ifdef COLDFIRE lea -56(SP),SP movem.l D1-A6,(SP) #else - cmp.w #1,D0 // init - bne display_devices movem.l D1-A6,-(SP) #endif + lea 0,A6 + subq.l #1,D0 // (1) init, (2) init without PCI RESET + move.l D0,D7 move.l #0x5F504349,D0 // _PCI bsr get_cookie beq.s .pci_cookie_not_found // not found @@ -64,9 +71,8 @@ _install_pci_bios: bra .end_install #ifdef COLDFIRE .pci_cookie_not_found: - -#if 0 // moved inside sdram.S before the CF68KLIB is called (init_cf) - // excepted interrupts +#if 0 // CF PCI moved inside boot2.S before the CF68KLIB is called (init_cf) + // excepted interrupts #ifdef DEBUG lea debug27(PC),A0 bsr debug_display_string @@ -78,7 +84,11 @@ _install_pci_bios: + MCF_PCIARB_PACR_EXTMINTEN(0x1F),D0 move.l D0,MCF_PCIARB_PACR // GNT and REQ +#ifdef MCF547X + move.w #0x3F,D0 /* only BREQ0-2 are connected to PCI */ +#else move.w #0x3FF,D0 +#endif move.w D0,MCF_GPIO_PAR_PCIBG move.w D0,MCF_GPIO_PAR_PCIBR // Master Enable / Memory Space / MWI @@ -94,7 +104,7 @@ _install_pci_bios: move.l #MCF_PCI_PCICR2_MINGNT(PCI_MINGNT) + MCF_PCI_PCICR2_MAXLAT(PCI_MAXLAT),D0 move.l D0,MCF_PCI_PCICR2 // Turn on error signaling - move.l #MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE /* + MCF_PCI_PCIICR_REE*/ + PCI_RETRIES,D0 + move.l #MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE /* + MCF_PCI_PCIICR_REE*/ + PCI_ RETRIES,D0 move.l D0,MCF_PCI_PCIICR move.l #MCF_PCI_PCIGSCR_SEE,D0 or.l D0,MCF_PCI_PCIGSCR @@ -104,7 +114,11 @@ _install_pci_bios: #endif // Configure Initiator Windows move.l #PCI_MEMORY_OFFSET + ((PCI_MEMORY_SIZE - 1) >> 8),D0 +#ifdef SAME_CPU_PCI_MEM_ADDR + move.w #(PCI_MEMORY_OFFSET >> 16),D0 +#else clr.w D0 +#endif move.l D0,MCF_PCI_PCIIW0BTAR // Initiator Window 0 Base / Translation Address Register #if 0 // #ifdef DEBUG lea debug37(PC),A0 @@ -130,34 +144,35 @@ _install_pci_bios: #endif move.l #MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE + MCF_PCI_PCIIWCR_WINCTRL1_IO,D0 move.l D0,MCF_PCI_PCIIWCR // Initiator Window Configuration Register -#if 0 // one target zone - clr.l MCF_PCI_PCIBAR0 - clr.l MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 -// move.l #PCI_MEMORY_SIZE,D0 // STRAM/SDRAM mapped on PCI after the zones for devices + // Target zones +#ifdef SAME_CPU_PCI_MEM_ADDR move.l #0x40000000,D0 - move.l D0,MCF_PCI_PCIBAR1 // 1 GB window ! + move.l D0,MCF_PCI_PCIBAR0 // 256 KB window +#ifdef MCF5445X + move.l #0xFC000000 + MCF_PCI_PCITBATR0_EN,D0 +#else + move.l #__MBAR + MCF_PCI_PCITBATR0_EN,D0 +#endif + move.l D0,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 + clr.l MCF_PCI_PCIBAR1 // 1 GB window ! move.l #MCF_PCI_PCITBATR1_EN,D0 move.l D0,MCF_PCI_PCITBATR1 // Target Base Address Translation Register 1 -#else // two target zones - moveq #0,D2 - move.l ramvalid,D0 - cmp.l #0x1357BD13,D0 - bne.s .no_sdram - move.l ramtop,D2 // SDRAM top - beq.s .no_sdram -// move.l #PCI_MEMORY_SIZE,D0 // SDRAM mapped on PCI after the zones for devices -// add.l 0x01000000,D0 +#else /* !SAME_CPU_PCI_MEM_ADDR */ move.l #0x80000000,D0 - move.l D0,MCF_PCI_PCIBAR0 - move.l #0x01000000 + MCF_PCI_PCITBATR0_EN,D2 -.no_sdram: - move.l D2,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 -// move.l #PCI_MEMORY_SIZE,D0 // STRAM mapped on PCI after the zones for devices + move.l D0,MCF_PCI_PCIBAR0 // 256 KB window +#ifdef MCF5445X + move.l #0xFC000000 + MCF_PCI_PCITBATR0_EN,D0 +#else + move.l #__MBAR + MCF_PCI_PCITBATR0_EN,D0 +#endif + move.l D0,MCF_PCI_PCITBATR0 // Target Base Address Translation Register 0 move.l #0x40000000,D0 move.l D0,MCF_PCI_PCIBAR1 // 1 GB window ! move.l #MCF_PCI_PCITBATR1_EN,D0 move.l D0,MCF_PCI_PCITBATR1 // Target Base Address Translation Register 1 -#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ +// move.l #MCF_PCI_PCITCR_P,D0 // prefetch reads for BAR1 +// move.l D0,MCF_PCI_PCITCR // Target Control Register #ifdef DEBUG lea debug30(PC),A0 bsr debug_display_string @@ -174,7 +189,7 @@ _install_pci_bios: move.l #~INTC_IMRH_INT_MASK56,D0 and.l D0,MCF_INTC_IMRH1 /* Falling edge on IRQ1-7 EPORT */ - move.w MCF_EPORT_EPPAR_EPPA7(EPORT_EPPAR_EPPAx_FALLING) \ + move.w #MCF_EPORT_EPPAR_EPPA7(EPORT_EPPAR_EPPAx_FALLING) \ + EPORT_EPPAR_EPPA6(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + EPORT_EPPAR_EPPA5(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + EPORT_EPPAR_EPPA4(MCF_EPORT_EPPAR_EPPAx_FALLING) \ @@ -203,14 +218,25 @@ _install_pci_bios: move.b D0,MCF_INTC_ICR43 // XLBPCI move.l #~MCF_INTC_IMRH_INT_MASK43,D0 and.l D0,MCF_INTC_IMRH +#ifdef MCF547X + /* Falling edge on IRQ1-7 EPORT */ + move.w #MCF_EPORT_EPPAR_EPPA7(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA6(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA5(MCF_EPORT_EPPAR_EPPAx_LEVEL) \ + + MCF_EPORT_EPPAR_EPPA4(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA3(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA2(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + + MCF_EPORT_EPPAR_EPPA1(MCF_EPORT_EPPAR_EPPAx_FALLING),D0 +#else /* Falling edge on IRQ1-7 EPORT */ - move.w MCF_EPORT_EPPAR_EPPA7(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + move.w #MCF_EPORT_EPPAR_EPPA7(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA6(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA5(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA4(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA3(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA2(MCF_EPORT_EPPAR_EPPAx_FALLING) \ + MCF_EPORT_EPPAR_EPPA1(MCF_EPORT_EPPAR_EPPAx_FALLING),D0 +#endif move.w D0,MCF_EPORT_EPPAR clr.b MCF_EPORT_EPDDR clr.b MCF_EPORT_EPIER @@ -222,14 +248,14 @@ _install_pci_bios: /* Clear PCI Reset and wait for devices to reset */ move.l #~MCF_PCI_PCIGSCR_PR,D0 and.l D0,MCF_PCI_PCIGSCR -#if 1 +#ifndef MCF5445X move.l MCF_SLT_SCNT1,D2 .delay_reset: move.l D2,D1 sub.l MCF_SLT_SCNT1,D1 - cmp.l #200000000,D1 + cmp.l #2000000*SYSTEM_CLOCK,D1 bcs.s .delay_reset -#else +#else /* MCF5445X */ move.l _hz_200,D2 add.l #400,D2 // tempo 2 S .delay_reset: @@ -237,8 +263,14 @@ _install_pci_bios: cmp.l D2,D1 blt.s .delay_reset #endif -#endif /* end #if 0 -- moved inside sdram.S before the CF68KLIB is called (init_cf) */ - + moveq #0,D7 // OK, start from reset +#else /* end -- moved inside boot2.S before the CF68KLIB is called (init_cf) */ + move.l #400,D2 // tempo 2 S from reset, maybe it's finished +.delay_reset: + move.l _hz_200,D1 + cmp.l D2,D1 + blt.s .delay_reset +#endif /* end -- moved inside boot2.S before the CF68KLIB is called (init_cf) */ #else /* ATARI - CTCPI/PLX9054 */ .no_hardware: move.l A5,8 // restore bus error @@ -247,6 +279,8 @@ _install_pci_bios: moveq #-1,D0 // error bra .end_install .pci_cookie_not_found: + tst.l D7 + bne .bypass_reset // test and init CTPCI configuration registers move.w SR,-(SP) or.w #0x700,SR // no interrupts @@ -254,25 +288,23 @@ _install_pci_bios: move.l 8,A5 // bus error move.l A0,8 move.l SP,A4 // save ssp - move.l memvalid,D0 - cmp.l #0x752019F3,D0 + cmp.l #0x752019F3,memvalid bne.s .cold_reset - move.l memval2,D0 - cmp.l #0x237698AA,D0 + cmp.l #0x237698AA,memval2 bne.s .cold_reset - move.l memval3,D0 - cmp.l #0x5555AAAA,D0 + cmp.l #0x5555AAAA,memval3 bne.s .cold_reset - move.l #PCI_IRQ_BASE_VECTOR,D0 - and.l #0xF0,D0 - move.l D0,PCI_CTPCI_CONFIG + move.w #PCI_IRQ_BASE_VECTOR,D0 + and.w #0xF0,D0 + move.b D0,PCI_CTPCI_CONFIG_VECTOR + clr.b PCI_CTPCI_CONFIG_ENABI // mask INTD /INTC / INTB / INTA / LINT move.l A5,8 // restore bus error move.l A4,SP // restore ssp move.w (SP)+,SR - bra.s .bypass_reset + bra .bypass_reset .cold_reset: moveq #1,D0 - move.l D0,PCI_CTPCI_CONFIG+0x20 // Reset PLX, PCI slots and PCI arbiter + move.l D0,PCI_CTPCI_CONFIG_RESET // Reset PLX, PCI slots and PCI arbiter move.l A5,8 // restore bus error move.l A4,SP // restore ssp move.w (SP)+,SR @@ -286,17 +318,40 @@ _install_pci_bios: move.l _hz_200,D1 cmp.l D2,D1 blt.s .tempo_reset - move.l #PCI_IRQ_BASE_VECTOR,D0 - and.l #0xF0,D0 - move.l D0,PCI_CTPCI_CONFIG - moveq #0,D0 - move.l D0,PCI_CTPCI_CONFIG+0x20 // Reset/ + moveq #4,D0 + move.l D0,PCI_CTPCI_CONFIG_RESET // Reset/ + normal CTPCI space + move.w #PCI_IRQ_BASE_VECTOR,D0 + and.w #0xF0,D0 + move.b D0,PCI_CTPCI_CONFIG_VECTOR + clr.b PCI_CTPCI_CONFIG_ENABI // mask INTD /INTC / INTB / INTA / LINT move.l _hz_200,D2 add.l #400,D2 // tempo 2 S .delay_reset: move.l _hz_200,D1 cmp.l D2,D1 blt.s .delay_reset + // check CTPCI version + move.b PCI_CTPCI_CONFIG_PEND,D0 + and.w #0xE0,D0 + bne.s .bypass_reset + move.l phystop,A0 + moveq #CTPCI_1M,D0 + or.l D0,hardware_type(A0) + clr.w -(SP) + pea 1 + bsr dma_lock + addq.l #4,SP + move.w D0,(SP) + clr.l -(SP) + bsr dma_lock + addq.l #4,SP + swap D0 + move.w (SP)+,D0 + cmp.l #0x10000,D0 + bne.s .bypass_reset + move.l phystop,A0 + moveq #CTPCI_1N,D0 + or.l D0,hardware_type(A0) .bypass_reset: // test and init PLX9054 move.w SR,-(SP) @@ -314,86 +369,44 @@ _install_pci_bios: bsr read_local_config_longword cmp.l #PLX9054,D0 // Device ID & Vendor ID bne .abort_install2 -#ifdef DEBUG - bsr test_endian_local_config - bne.s .plx_in_little - lea debug30(PC),A0 - bsr debug_display_string -.plx_in_little: -#endif -#if 0 - move.l #0x00300100,D2 // Little Endian - move.l #BIGEND,D1 // Big/Little Endian Descriptor / Local Miscellaneous Control - bsr write_local_config_longword -#endif - // pin BIGEND is active => try to use little endian + move.l #MARBR,D1 + bsr read_local_config_longword +// move.l #0x91200000,D2 // for BIGEND input to WAIT output move.l #0x80200000,D2 // for BIGEND input to WAIT output + cmp.l D0,D2 + seq.b D7 + and.l #1,D7 // (0) start from reset, (1) start from CTRL-ALT-DEL (no changes) move.l #MARBR,D1 // Mode/DMA Arbitration bsr write_local_config_longword -#if 0 -#if 1 // one target zone - move.l phystop,D2 // end STRAM - cmp.l #0x1357BD13,ramvalid - bne.s .no_sdram - move.l ramtop,D2 // end SDRAM -.no_sdram: - moveq #24,D0 - lsr.l D0,D2 - addq.l #1,D2 - lsl.l D0,D2 // size + // Target zone +#ifdef TARGET_NO_CACHE_PCI_MEM + bsr get_no_cache_memory_size + move.l D0,D2 subq.l #1,D2 not.l D2 +#else /* !TARGET_NO_CACHE_PCI_MEM */ + move.l #0xC0000000,D2 // 1GB +#endif /* TARGET_NO_CACHE_PCI_MEM */ move.l #LAS0RR,D1 // Local Address Space 0 Range Register for PCI-to-Local Bus - bsr write_verify_local_config_longword + bsr write_local_config_longword +#ifdef TARGET_NO_CACHE_PCI_MEM + bsr get_no_cache_memory + bset #0,D0 // enable PCI target window + move.l D0,D2 +#else /* !TARGET_NO_CACHE_PCI_MEM */ moveq #1,D2 // enable PCI target window at 0 +#endif /* TARGET_NO_CACHE_PCI_MEM */ move.l #LAS0BA,D1 // Local Address Space 0 Local Base Address (Remap) - bsr write_verify_local_config_longword -#else // two target zones - cmp.l #0x1357BD13,ramvalid - bne .no_sdram_2 - move.l ramtop,D2 - sub.l #0x01000000,D2 - bpl.s .sdram_ok -.no_sdram_2: - moveq #0,D2 -.sdram_ok: - moveq #24,D0 - lsr.l D0,D2 - addq.l #1,D2 - lsl.l D0,D2 // size - subq.l #1,D2 - not.l D2 - move.l #LAS0RR,D1 // Local Address Space 0 Range Register for PCI-to-Local Bus - bsr write_verify_local_config_longword - moveq #0,D2 - cmp.l #0x1357BD13,ramvalid - bne.s .no_sdram - move.l ramtop,D2 // end SDRAM - beq.s .no_sdram - move.l #0x01000001,D2 // enable PCI target window at 0x1000000 -.no_sdram: - move.l #LAS0BA,D1 // Local Address Space 0 Local Base Address (Remap) - bsr write_verify_local_config_longword -#endif -#endif - move.l #~(PCI_IO_SIZE-1),D2 - move.l #DMRR,D1 // Local Range Register for PCI Initiator-to-PCI - bsr write_verify_local_config_longword - move.l #PCI_MEMORY_OFFSET,D2 - move.l #DMLBAM,D1 // Local Bus Base Address Register for PCI Initiator-to-PCI Memory - bsr write_verify_local_config_longword - move.l #PCI_IO_OFFSET,D2 - move.l #DMLBAI,D1 // Local Bus Base Address Register for PCI Initiator-to-PCI I/O Config - bsr write_verify_local_config_longword - moveq #0,D2 - move.l #DMPBAM,D1 // PCI Base Address (Remap) Register for PCI Initiator-to-PCI Memory - bsr write_verify_local_config_longword + bsr write_local_config_longword moveq #0,D2 - move.l #DMCFGA,D1 + move.l #LAS1RR,D1 // Local Address Space 1 Range Register for PCI-to-Local Bus bsr write_local_config_longword - -#if 1 - move.l #0x40C300C3,D2 + moveq #0,D2 // disable PCI target window + move.l #LAS1BA,D1 // Local Address Space 1 Local Base Address (Remap) + bsr write_local_config_longword +#if 1 // Optimizations +// move.l #0x40C300C3,D2 + move.l #0x48C300C3,D2 move.l #LBRD0,D1 bsr write_local_config_longword move.l #0x000000C3,D2 @@ -406,62 +419,145 @@ _install_pci_bios: move.l #DMAMODE1,D1 bsr write_local_config_longword #endif - -#if 0 -#if 1 // one target zone - moveq #0,D2 - move.l #LAS1RR,D1 // Local Address Space 1 Range Register for PCI-to-Local Bus - bsr write_verify_local_config_longword - moveq #0,D2 // disable PCI target window - move.l #LAS1BA,D1 // Local Address Space 1 Local Base Address (Remap) - bsr write_verify_local_config_longword -#else // two target zones - move.l phystop,D2 // end STRAM - moveq #24,D0 - lsr.l D0,D2 - addq.l #1,D2 - lsl.l D0,D2 // size + // Local zones + moveq #0,D2 // disable local zones (else it's possible that Ethernat/Supervidel test not works) + move.l #DMPBAM,D1 // PCI Base Address (Remap) Register for PCI Initiator-to-PCI Memory + bsr write_local_config_longword +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l #PCI_MEMORY_OFFSET_1,pci_memory_offset(A0) + move.l #PCI_MEMORY_SIZE_1,pci_memory_size(A0) + move.l #PCI_IO_OFFSET_1,pci_io_offset(A0) + move.l #PCI_IO_SIZE_1,pci_io_size(A0) + move.l A6,D0 + bne .lowest_zones // 2nd loop (if access fault on I/O zone) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + lea .no_ethernat(PC),A1 + move.l 8,A5 // bus error + move.l A1,8 + move.l SP,A4 // save ssp + moveq #0,D0 + tst.l 0x80000000 // Ethernat + move.l #ETHERNAT,D0 +.no_ethernat: + lea .no_supervidel(PC),A1 + move.l A1,8 + tst.l 0x80010000 // Supervidel + or.l #SUPERVIDEL,D0 +.no_supervidel: + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp + move.w (SP)+,SR + move.l phystop,A0 + or.l D0,hardware_type(A0) + tst.l D0 + bne.s .lowest_zones + // biggest zones + move.l #PCI_MEMORY_OFFSET_2,pci_memory_offset(A0) + move.l #PCI_MEMORY_SIZE_2,pci_memory_size(A0) + move.l #PCI_IO_OFFSET_2,pci_io_offset(A0) + move.l #PCI_IO_SIZE_2,pci_io_size(A0) + move.l #0x4D616758,D0 // MagX + bsr get_cookie + bne.s .lowest_zones // if found, no change because other bits are set by TOS only (boot2.S) + clr.l PCI_CTPCI_CONFIG_RESET // enable all space for CTPCI +.lowest_zones: + move.l pci_io_size(A0),D2 subq.l #1,D2 not.l D2 - move.l #LAS1RR,D1 // Local Address Space 1 Range Register for PCI-to-Local Bus - bsr write_verify_local_config_longword - moveq #1,D2 // enable PCI target window at 0 (STRAM) - move.l #LAS1BA,D1 // Local Address Space 1 Local Base Address (Remap) - bsr write_verify_local_config_longword +#else /* !PCI_DYNAMIC_MAPPING */ + move.l #~(PCI_IO_SIZE-1),D2 +#endif /* PCI_DYNAMIC_MAPPING */ + move.l #DMRR,D1 // Local Range Register for PCI Initiator-to-PCI + bsr write_local_config_longword +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),D2 +#else + move.l #PCI_MEMORY_OFFSET,D2 #endif + move.l #DMLBAM,D1 // Local Bus Base Address Register for PCI Initiator-to-PCI Memory + bsr write_local_config_longword +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),D2 +#else + move.l #PCI_IO_OFFSET,D2 #endif + move.l #DMLBAI,D1 // Local Bus Base Address Register for PCI Initiator-to-PCI I/O Config + bsr write_local_config_longword + moveq #0,D2 + move.l #DMCFGA,D1 + bsr write_local_config_longword +#ifdef SAME_CPU_PCI_MEM_ADDR +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),D2 + add.l #0x2003,D2 +#else + move.l #PCI_MEMORY_OFFSET+0x2003,D2 +#endif +#else /* !SAME_CPU_PCI_MEM_ADDR */ + moveq #3,D2 // enable PCI base for local bus map-to-PCI +#endif /* SAME_CPU_PCI_MEM_ADDR */ + move.l #DMPBAM,D1 // PCI Base Address (Remap) Register for PCI Initiator-to-PCI Memory + bsr write_local_config_longword #ifndef LITTLE_ENDIAN_LANE_SWAPPED // bits inverses sur le PLX ??? - move.l #0x00300500,D2 // Little Endian + Local Init Status => PLX done + move.l #0x00300400,D2 // Little Endian + Local Init Status => PLX done #else // lines are swapped by the bridge - move.l #0x003005FE,D2 // Big Endian excepted Configuration Registers + move.l #0x003004FE,D2 // Big Endian excepted Configuration Registers #endif // + Local Init Status => PLX done move.l #BIGEND,D1 // Big/Little Endian Descriptor / Local Miscellaneous Control bsr write_local_config_longword -#if 0 - // PCI target windows configuration -#if 1 // one target zone - move.l #PCI_MEMORY_SIZE,D2 // STRAM/SDRAM mapped on PCI after the zones for devices - move.l #PCIBAR2,D1 // PCI Base Address Register for Memory Accesses to Local Address Space 0 - bsr write_local_config_longword -#else // two target zones - move.l #PCI_MEMORY_SIZE,D2 // SDRAM mapped on PCI after the zones for devices - add.l #0x01000000,D2 - move.l #PCIBAR2,D1 // PCI Base Address Register for Memory Accesses to Local Address Space 0 - bsr write_local_config_longword - move.l #PCI_MEMORY_SIZE,D2 // STRAM mapped on PCI after the zones for devices - move.l #PCIBAR3,D1 // PCI Base Address Register for Memory Accesses to Local Address Space 1 + // Target zones + moveq #-1,D2 + moveq #PCIBAR0,D1 // PCI Base Address Register for Memory Accesses to Local, Runtime, and DMA bsr write_local_config_longword + moveq #PCIBAR0,D1 // PCI Base Address Register for Memory Accesses to Local, Runtime, and DMA + bsr read_local_config_longword +#if 0 // #ifdef SAME_CPU_PCI_MEM_ADDR +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),D0 +#else + move.l #PCI_MEMORY_OFFSET,D0 #endif +#else /* !SAME_CPU_PCI_MEM_ADDR */ + move.l #0xFFFFFF00,D2 #endif - // Master Enable / Memory Space / I/O Space - move.l #PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP + 0x02900000,D2 + moveq #PCIBAR0,D1 // PCI Base Address Register for Memory Accesses to Local, Runtime, and DMA (256 bytes) + bsr write_local_config_longword + moveq #-1,D2 + moveq #PCIBAR2,D1 // PCI Base Address Register for Memory Accesses to Local Address Space 0 + bsr write_local_config_longword + moveq #PCIBAR2,D1 // PCI Base Address Register for Memory Accesses to Local Address Space 0 + bsr read_local_config_longword +#ifdef TARGET_NO_CACHE_PCI_MEM + bsr get_no_cache_memory + move.l D0,D2 +#else /* !TARGET_NO_CACHE_PCI_MEM */ +#ifdef SAME_CPU_PCI_MEM_ADDR + moveq #0,D2 +#else + move.l #0x40000000,D2 +#endif /* SAME_CPU_PCI_MEM_ADDR */ +#endif /* TARGET_NO_CACHE_PCI_MEM */ + moveq #PCIBAR2,D1 // PCI Base Address Register for Memory Accesses to Local Address Space 0 + bsr write_local_config_longword + // Setup burst parameters + move.l #PCI_CACHE_LINE + (32<<8),D2 // cache line / latency timer + moveq #PCICLSR,D1 // PCI Cache Line Size / Latency Timer Register + bsr write_local_config_longword + move.l #((PCI_MAXLAT<<24) + (PCI_MINGNT<<16)),D2 + moveq #PCIILR,D1 // PCI Max_Lat / Min_Gnt Register + bsr write_local_config_longword + // Master Enable / Memory Space / I/O Space, and clear errors + move.l #PCI_CMDREG_SERR + PCI_CMDREG_PERR + PCI_CMDREG_MEMWINV + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP + 0xFA900000,D2 moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // end of PCI target windows configuration - moveq #3,D2 // enable PCI base for local bus map-to-PCI - move.l #DMPBAM,D1 // PCI Base Address (Remap) Register for PCI Initiator-to-PCI Memory - bsr write_local_config_longword -#ifdef DEBUG +#if 0 // #ifdef DEBUG lea debug1(PC),A0 bsr debug_display_string moveq #PCICSR,D1 @@ -561,13 +657,6 @@ _install_pci_bios: bsr debug_display_char moveq #10,D0 bsr debug_display_char - bsr test_endian_local_config - lea debug31l(PC),A0 - tst.l D0 - bne.s .plx_in_little2 - lea debug31b(PC),A0 -.plx_in_little2: - bsr debug_display_string move.l #PCIIDR,D1 bsr read_local_config_word move.l #PLX9054,D1 @@ -611,6 +700,17 @@ _install_pci_bios: bsr debug_display_string #endif // init driver + move.l A6,D0 + bne.s .malloc_ok // 2nd loop (if access fault on I/O zone) + move.l #0x4D616758,D0 // MagX + bsr get_cookie + beq.s .malloc_tos // not found + move.l #PCI_COOKIE_TOTALSIZE,D0 + move.l _membot,A0 + add.l D0,_membot + move.l A0,D0 + bra.s .malloc_ok +.malloc_tos: move.w #3,-(SP) // TT ram if possible move.l #PCI_COOKIE_TOTALSIZE,-(SP) move.w #0x44,-(SP) // Mxalloc @@ -618,11 +718,29 @@ _install_pci_bios: addq.l #8,SP tst.l D0 ble .abort_install +.malloc_ok: move.l D0,A6 // _PCI cookie + move.l D0,A0 + move.l #(PCI_COOKIE_TOTALSIZE/4)-1,D0 +.loop_init_cookie: + clr.l (A0)+ + subq.l #1,D0 + bpl.s .loop_init_cookie + move.l A6,D0 add.l #PCI_COOKIE_SIZE,D0 move.l D0,A5 // Ressource-Descriptors - add.l #PCI_RSC_HANDLESTOTALSIZE,D0 // PCI_RSC_DESC_TOTALSIZE*PCI_MAX_HANDLE*PCI_MAX_FUNCTION - move.l D0,A4 // Status-Descriptors, size PCI_DEV_DES_SIZE*PCI_MAX_HANDLE*PCI_MAX_FUNCTION + move.l #PCI_MAX_BUS*PCI_MAX_DEVICE*PCI_MAX_FUNCTION*6,D0 +.init_desc: +#ifdef COLDFIRE + move.w PCI_RSC_DESC_FLAGS(A5),D1 + or.l #FLG_LAST,D1 + move.w D1,PCI_RSC_DESC_FLAGS(A5) +#else + or.w #FLG_LAST,PCI_RSC_DESC_FLAGS(A5) +#endif + add.l #PCI_RSC_DESC_SIZE,A5 + subq.l #1,D0 + bgt.s .init_desc move.l A6,A0 // _PCI cookie clr.l PCI_COOKIE_SUBCOOKIE(A0) // Sub-Cookie for PCI_CONF, not used obsolete move.l #PCI_BIOS_REV,D0 @@ -717,7 +835,47 @@ _install_pci_bios: lea debug33(PC),A0 bsr debug_display_string #endif + move.l D7,-(SP) + pea (A6) // _PCI cookie + clr.l -(SP) // primary bus bsr init_devices + addq.l #8,SP +#ifdef PCI_DYNAMIC_MAPPING + tst.l D0 + beq.s .init_ok + // access fault during PCI access + move.l (SP)+,D7 + move.l phystop,A0 + moveq #CTPCI_1ABCD,D1 + or.l D1,hardware_type(A0) + cmp.l #PCI_MEMORY_OFFSET_1,pci_memory_offset(A0) + bne .bypass_reset // 2nd loop + cmp.l #PCI_MEMORY_SIZE_1,pci_memory_size(A0) + bne .bypass_reset // 2nd loop + cmp.l #PCI_IO_OFFSET_1,pci_io_offset(A0) + bne .bypass_reset // 2nd loop + cmp.l #PCI_IO_SIZE_1,pci_io_size(A0) + bne .bypass_reset // 2nd loop with lowest zones (biggest zones not works before CTPCI_1E) + bra.s .end_install // abnormal (nothing works) +.init_ok: +#endif /* PCI_DYNAMIC_MAPPING */ +#ifdef DEBUG + lea debug34(PC),A0 + bsr debug_display_string +#endif + tst.l D0 + bne.s .error_install + move.l A6,D1 // value + move.l #0x5F504349,D0 // cookie _PCI + bsr add_cookie +#ifdef COLDFIRE +//#ifndef MCF547X + moveq #0,D0 + bsr display_devices +//#endif +#endif +.error_install: + move.l (SP)+,D0 .end_install: #ifdef COLDFIRE movem.l (SP),D1-A6 @@ -728,39 +886,148 @@ _install_pci_bios: rts // variables on stack used by init_devices: -#define RESERVE_STACK 28 -#define GRAPHICS_CARD_FLAG -2+RESERVE_STACK // .w flag graphics card -#define SAVE_BITS -6+RESERVE_STACK // .l save value for usage bits in PCI ressources -#define DEVICE_VENDOR_ID -10+RESERVE_STACK // .l device/vendor id -#define OFFSET_IO -14+RESERVE_STACK // .l offset i/o resource -#define OFFSET_MEMORY -18+RESERVE_STACK // .l offset memory resource -#define OFFSET_MEMORY_PREF -22+RESERVE_STACK // .l offset memory ressource with prefetch -#define RESOURCE_INDEX -24+RESERVE_STACK // .w offset or index resource by handle -#define ERROR_CODE -28+RESERVE_STACK // .l error code +#define RESERVE_STACK 52 +#define GRAPHICS_CARD_FLAG -2+RESERVE_STACK // .w flag graphics card +#define SAVE_BITS -6+RESERVE_STACK // .l save value for usage bits in PCI ressources +#define DEVICE_VENDOR_ID -10+RESERVE_STACK // .l device/vendor id +#define OFFSET_IO -14+RESERVE_STACK // .l offset i/o resource +#define OFFSET_MEMORY -18+RESERVE_STACK // .l offset memory resource +#define OFFSET_MEMORY_PREF -22+RESERVE_STACK // .l offset memory ressource with prefetch +#define START_OFFSET_MEMORY -26+RESERVE_STACK // .l start offset memory ressource +#define START_OFFSET_MEMORY_PREF -30+RESERVE_STACK // .l start offset memory ressource with prefetch +#define RESOURCE_INDEX -32+RESERVE_STACK // .w offset or index resource by handle +#define ERROR_CODE -36+RESERVE_STACK // .l error code +#define DMA_OFFSET -40+RESERVE_STACK // .l offset of base memory mapped of PCI +#define BAR_VALUE -44+RESERVE_STACK // .l PCIBARX read value +#define BUS_NUMBER -46+RESERVE_STACK // .w bus number +#define PRIMARY_SLOT_NUMBER -48+RESERVE_STACK // .w slot offset primary bus where located bridge(s) +#define PCI_COOKIE -52+RESERVE_STACK // .l pci cookie init_devices: + lea -56(SP),SP + movem.l D1-A6,(SP) + lea -RESERVE_STACK(SP),A6 + move.l 56+4(SP),D3 // bus number + beq.s .is_bus0 + cmp.l #PCI_MAX_BUS,D3 + bcs.s .bus_number_ok + moveq #-1,D0 // error + bra .end_init_pci_bios2 +.bus_number_ok: + move.l 56+8(SP),D0 // get local pointers from bus 0 (main init_device) + beq.s .is_bus0 + move.l D0,A6 + bra.s .common_bus +.is_bus0: + move.l 56+8(SP),D0 // _PCI cookie + move.l D0,PCI_COOKIE(A6) +.common_bus: lea -RESERVE_STACK(SP),SP - clr.w RESOURCE_INDEX(SP) - clr.l OFFSET_MEMORY_PREF(SP) - move.l #PCI_MEMORY_SIZE/2,D0 - move.l D0,OFFSET_MEMORY(SP) - clr.l OFFSET_IO(SP) - clr.l SAVE_BITS(SP) - clr.w GRAPHICS_CARD_FLAG(SP) - // init devices, handle 0 is for local bridge PLX9054 + move.l PCI_COOKIE(A6),D0 + add.l #PCI_COOKIE_SIZE,D0 + move.l D0,A5 // Ressource-Descriptors + add.l #PCI_RSC_HANDLESTOTALSIZE,D0 // PCI_RSC_DESC_TOTALSIZE*PCI_MAX_DEVICE*PCI_MAX_FUNCTION + move.l D0,A4 // Status-Descriptors, size PCI_DEV_DES_SIZE*PCI_MAX_DEVICE*PCI_MAX_FUNCTION + move.l D3,D0 // bus + mulu #PCI_MAX_DEVICE*PCI_MAX_FUNCTION*PCI_RSC_DESC_TOTALSIZE,D0 + add.l D0,A5 // Ressource-Descriptors + move.l D3,D0 // bus + mulu #PCI_MAX_DEVICE*PCI_MAX_FUNCTION*PCI_DEV_DES_SIZE,D0 + add.l D0,A4 // Status-Descriptors + mulu #PCI_MAX_FUNCTION,D3 + bne.s .not_bus0 + clr.l DMA_OFFSET(A6) + clr.w RESOURCE_INDEX(A6) +#ifdef SAME_CPU_PCI_MEM_ADDR +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),D0 +#else + move.l #PCI_MEMORY_OFFSET,D0 +#endif +#else /* !SAME_CPU_PCI_MEM_ADDR */ + moveq #0,D0 +#endif + move.l D0,START_OFFSET_MEMORY_PREF(A6) + move.l D0,OFFSET_MEMORY_PREF(A6) +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_size(A0),D1 + lsr.l #1,D1 + add.l D1,D0 +#else + add.l #PCI_MEMORY_SIZE/2,D0 +#endif + move.l D0,START_OFFSET_MEMORY(A6) + move.l D0,OFFSET_MEMORY(A6) + clr.l OFFSET_IO(A6) + clr.l SAVE_BITS(A6) + clr.w GRAPHICS_CARD_FLAG(A6) + clr.w BUS_NUMBER(A6) + // init devices, handle 0 is for local bridge +.not_bus0: moveq #0,D4 // slot moveq #0,D6 // function number .loop_handle: - clr.l ERROR_CODE(SP) // error code + clr.l ERROR_CODE(A6) // error code + move.l PCI_COOKIE(A6),A0 + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE+PCI_INT_HANDLESTOTALSIZE,A0 // slot offset 0-3 for interrupt + move.l D4,D0 // slot + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A0 // offset slot + move.l D3,D0 // bus number * PCI_MAX_FUNCTION + mulu #PCI_MAX_DEVICE,D0 + add.l D0,A0 // offset bus + add.l D6,A0 // offset function + tst.l D3 + bne.s .not_primary_bus + move.l D4,D0 // slot +#if defined(COLDFIRE) && defined(MCF547X) // FIREBEE + subq.l #2,D0 // - bridge - internal USB (INTA-B-C) +#else + subq.l #1,D0 // - bridge +#endif + bpl.s .init_slot_offset_int + moveq #0,D0 + bra.s .init_slot_offset_int +.not_primary_bus: + move.w PRIMARY_SLOT_NUMBER(A6),D0 // use offset from primary bus where located bridge(s) +.init_slot_offset_int: + move.w D0,PRIMARY_SLOT_NUMBER(A6) // slot offset primary bus where located bridge(s) + and.l #3,D0 + move.b D0,(A0) // slot offset 0-3 for interrupt +#ifdef PCI_DYNAMIC_MAPPING // test for old CTPCI hardware who not like big PCI local zones + move.l A4,-(SP) + move.l A5,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + lea .hardware_failure(PC),A0 + move.l 8,A5 // bus error + move.l A0,8 + move.l SP,A4 // save ssp + moveq #PCIIDR,D1 + move.l D6,D0 // current function number + add.l D3,D0 // bus number + swap D0 + or.l D4,D0 // slot + bsr fast_read_config_longword // Device ID & Vendor ID + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp + move.w (SP)+,SR + move.l (SP)+,A5 + move.l (SP)+,A4 +#else /* !PCI_DYNAMIC_MAPPING */ moveq #PCIIDR,D1 move.l D6,D0 // current function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword // Device ID & Vendor ID - move.l D0,DEVICE_VENDOR_ID(SP) +#endif /* PCI_DYNAMIC_MAPPING */ + move.l D0,DEVICE_VENDOR_ID(A6) #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG move.l D0,-(SP) move.l A0,-(SP) lea debug39(PC),A0 @@ -784,14 +1051,15 @@ init_devices: beq .no_device_found_here moveq #PCIREV,D1 move.l D6,D0 // current function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword // & class code #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG move.l D0,-(SP) move.l A0,-(SP) - lea debug40(PC),A0 + lea debug36(PC),A0 bsr debug_display_string bsr debug_hex_long moveq #13,D0 @@ -802,13 +1070,177 @@ init_devices: move.l (SP)+,D0 #endif #endif + clr.w D0 + swap D0 + cmp.l #PCI_CLASS_BRIDGE_PCI,D0 + bne .not_pci_bridge + tst.l D6 // do not check for multi-function on bridge + bne .next_slot + // PCI to PCI bridge + move.l D6,D0 // function + add.l D3,D0 // bus number + swap D0 + or.l D4,D0 // slot + move.l OFFSET_IO(A6),D2 + add.l #0x00000FFF,D2 // 4KB alignment + and.l #0xFFFFF000,D2 + bne.s .offset_io_not_null + add.l #0x1000,D2 +.offset_io_not_null: + move.l D2,OFFSET_IO(A6) + lsr.l #8,D2 + moveq #PCI_IO_BASE,D1 // I/O range behind the bridge + move.l D0,-(SP) // handle + bsr write_config_byte + move.l OFFSET_IO(A6),D2 + swap D2 + moveq #PCI_IO_BASE_UPPER16,D1 // I/O range behind the bridge + move.l (SP),D0 // handle + bsr write_config_word + move.l OFFSET_MEMORY(A6),D2 + add.l #0x000FFFFF,D2 // 1MB alignment + and.l #0xFFF00000,D2 + bne.s .offset_mem_not_null + add.l #0x100000,D2 +.offset_mem_not_null: + move.l D2,OFFSET_MEMORY(A6) + swap D2 + moveq #PCI_MEMORY_BASE,D1 // Memory range behind + move.l (SP),D0 // handle + bsr write_config_word + move.l OFFSET_MEMORY_PREF(A6),D2 + add.l #0x000FFFFF,D2 // 1MB alignment + and.l #0xFFF00000,D2 + bne.s .offset_mem_pref_not_null + add.l #0x100000,D2 +.offset_mem_pref_not_null: + move.l D2,OFFSET_MEMORY_PREF(A6) + swap D2 + moveq #PCI_PREF_MEMORY_BASE,D1 // Prefetchable memory range behind + move.l (SP),D0 // handle + bsr write_config_word + moveq #0,D2 + moveq #PCI_PREF_BASE_UPPER32,D1 // Upper half of prefetchable memory range + move.l (SP),D0 // handle + bsr write_config_longword + move.l #(PCI_MAXLAT<<24),D2 + moveq #0,D0 + move.w BUS_NUMBER(A6),D0 + or.l D0,D2 // primary bus + addq.l #1,D0 + move.w D0,BUS_NUMBER(A6) + asl.l #8,D0 // secondary bus + or.l D0,D2 + moveq #PCI_PRIMARY_BUS,D1 + or.l #0x00FF0000,D2 // subordinate bus + move.l (SP),D0 // handle + move.l D2,-(SP) + bsr write_config_longword + pea (A6) + moveq #0,D0 + move.w BUS_NUMBER(A6),D0 + move.l D0,-(SP) + jsr init_devices + addq.l #8,SP + move.w BUS_NUMBER(A6),D0 swap D0 + clr.w D0 + move.l (SP)+,D2 + and.l #0xFF00FFFF,D2 + or.l D0,D2 // max subordinate bus + moveq #PCI_PRIMARY_BUS,D1 + move.l (SP),D0 // handle + bsr write_config_longword + move.l OFFSET_IO(A6),D2 + add.l #0x00000FFF,D2 // 4KB alignment + and.l #0xFFFFF000,D2 + move.l D2,OFFSET_IO(A6) + subq.l #1,D2 + lsr.l #8,D2 + moveq #PCI_IO_LIMIT,D1 + move.l (SP),D0 // handle + bsr write_config_byte + move.l OFFSET_IO(A6),D2 + subq.l #1,D2 + swap D2 + moveq #PCI_IO_LIMIT_UPPER16,D1 + move.l (SP),D0 // handle + bsr write_config_word + move.l OFFSET_MEMORY(A6),D2 + add.l #0x000FFFFF,D2 // 1MB alignment + and.l #0xFFF00000,D2 + move.l D2,OFFSET_MEMORY(A6) + subq.l #1,D2 + swap D2 + moveq #PCI_MEMORY_LIMIT,D1 + move.l (SP),D0 // handle + bsr write_config_word + move.l OFFSET_MEMORY_PREF(A6),D2 + add.l #0x000FFFFF,D2 // 1MB alignment + and.l #0xFFF00000,D2 + move.l D2,OFFSET_MEMORY_PREF(A6) + subq.l #1,D2 + swap D2 + moveq #PCI_PREF_MEMORY_LIMIT,D1 + move.l (SP),D0 // handle + bsr write_config_word + moveq #0,D2 + moveq #PCI_PREF_LIMIT_UPPER32,D1 + move.l (SP),D0 // handle + bsr write_config_longword + move.b #PCI_MAXLAT,D2 + moveq #PCILTR,D1 // Latency Timer + move.l (SP),D0 // handle + bsr write_config_byte + moveq #PCI_CACHE_LINE,D2 + moveq #PCICLSR,D1 + move.l (SP),D0 // handle + bsr write_config_byte + moveq #PCISR,D1 // PCI Status Register + move.l (SP),D0 // handle + bsr fast_read_config_word + move.l D0,D2 + moveq #PCISR,D1 // PCI Status Register + move.l (SP),D0 // handle + bsr write_config_word // clear errors + moveq #0x21,D2 // master abort mode and enable parity error detection on secondary + moveq #PCI_BRIDGE_CONTROL,D1 + move.l (SP),D0 // handle + bsr write_config_word +#ifndef COLDFIRE + move.w #PCI_CMDREG_SERR + PCI_CMDREG_PERR + PCI_CMDREG_MEMWINV + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP,D2 +#else + move.w #PCI_CMDREG_PERR + PCI_CMDREG_MEMWINV + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP,D2 +#endif + moveq #PCICR,D1 // PCI Command Register + move.l (SP)+,D0 // handle + bsr write_config_word + moveq #3,D0 // card in use + move.l D4,D1 // slot + mulu #PCI_MAX_FUNCTION*PCI_DEV_DES_SIZE,D1 + move.l D0,PCI_DEV_DES_STATUS(A4,D1.l) + clr.l PCI_DEV_DES_CALLBACK(A4,D1.l) + clr.l PCI_DEV_DES_HANDLER(A4,D1.l) + clr.l PCI_DEV_DES_PARAMETER(A4,D1.l) + clr.l PCI_DEV_DES_START_IRQ(A4,D1.l) + move.l D4,D0 // slot + mulu #PCI_MAX_FUNCTION*PCI_RSC_DESC_TOTALSIZE,D0 + move.w #FLG_LAST,D1 + move.w D1,PCI_RSC_DESC_FLAGS(A5,D0.l) + clr.l PCI_RSC_DESC_START(A5,D0.l) // offset memory resource + clr.l PCI_RSC_DESC_OFFSET(A5,D0.l) + clr.l PCI_RSC_DESC_DMAOFFSET(A5,D0.l) + clr.l PCI_RSC_DESC_LENGTH(A5,D0.l) + clr.w PCI_RSC_DESC_NEXT(A5,D0.l) + clr.l PCI_RSC_DESC_ERROR(A5,D0.l) // internal error code + bra .next_slot +.not_pci_bridge: lsr.l #8,D0 // base class code and.l #0xFF,D0 cmp.l #PCI_CLASS_DISPLAY,D0 seq.b D0 ext.w D0 - move.w D0,GRAPHICS_CARD_FLAG(SP) // flag graphic card + move.w D0,GRAPHICS_CARD_FLAG(A6) // flag graphic card beq.s .card_is_free moveq #3,D0 // card in use .card_is_free: @@ -821,17 +1253,15 @@ init_devices: clr.l PCI_DEV_DES_HANDLER(A4,D1.l) clr.l PCI_DEV_DES_PARAMETER(A4,D1.l) clr.l PCI_DEV_DES_START_IRQ(A4,D1.l) + tst.l D3 + bne.s .devices // <> bus 0 tst.l D4 // slot bne.s .devices // <> local bridge PLX9054 tst.l D6 // do not check for multi-function on bridge bne .next_slot - move.l D4,D0 // slot - mulu #PCI_MAX_FUNCTION,D0 - add.l D6,D0 // function - mulu #PCI_RSC_DESC_TOTALSIZE,D0 move.w #PCI_RSC_DESC_SIZE,D1 - move.w D1,PCI_RSC_DESC_NEXT(A5,D0.l) -#if 1 // information for bus mastering + move.w D1,PCI_RSC_DESC_NEXT(A5) + // information for bus mastering #ifdef BIG_ENDIAN move.w #FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_MOTOROLA,D1 #else @@ -845,111 +1275,133 @@ init_devices: #endif /* LITTLE_ENDIAN_LANE_SWAPPED */ #endif /* LITTLE_ENDIAN_ADDRESSES_SWAPPED */ #endif /* BIG_ENDIAN */ - move.w D1,PCI_RSC_DESC_FLAGS(A5,D0.l) + move.w D1,PCI_RSC_DESC_FLAGS(A5) #ifdef COLDFIRE - move.l #0x40000000,D1 - move.l D1,PCI_RSC_DESC_START(A5,D0.l) // offset memory resource - move.l #-0x40000000,D1 - move.l D1,PCI_RSC_DESC_OFFSET(A5,D0.l) - move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) + move.l #0x40000000,D1 // 1GB + move.l D1,PCI_RSC_DESC_LENGTH(A5) + move.l MCF_PCI_PCIBAR1,D1 + and.l #PCI_BASE_M_ADDR_M,D1 #else /* ATARI - CTPCI/PLX9054 */ - // STRAM/SDRAM mapped on PCI after the zones for devices - move.l #PCI_MEMORY_SIZE,PCI_RSC_DESC_START(A5,D0.l) // offset memory resource - move.l #-PCI_MEMORY_SIZE,D1 - move.l D1,PCI_RSC_DESC_OFFSET(A5,D0.l) - move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) +#ifdef TARGET_NO_CACHE_PCI_MEM + bsr get_no_cache_memory_size + move.l D0,PCI_RSC_DESC_LENGTH(A5) + bsr get_no_cache_memory + move.l D0,D1 +#else /* !TARGET_NO_CACHE_PCI_MEM */ + move.l #0x40000000,PCI_RSC_DESC_LENGTH(A5) // 1GB +#ifdef SAME_CPU_PCI_MEM_ADDR + moveq #0,D1 +#else // STRAM/SDRAM mapped on PCI after the zones for devices + move.l #0x40000000,D1 +#endif /* SAME_CPU_PCI_MEM_ADDR */ +#endif /* TARGET_NO_CACHE_PCI_MEM */ #endif /* COLDFIRE */ - clr.l PCI_RSC_DESC_LENGTH(A5,D0.l) -#else // information for bridge I/O + move.l D1,PCI_RSC_DESC_START(A5) // offset memory resource +#ifdef SAME_CPU_PCI_MEM_ADDR + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ + neg.l D1 +#endif /* SAME_CPU_PCI_MEM_ADDR */ + move.l D1,PCI_RSC_DESC_OFFSET(A5) + move.l D1,PCI_RSC_DESC_DMAOFFSET(A5) + move.l D1,DMA_OFFSET(A6) + clr.l PCI_RSC_DESC_ERROR(A5) // internal error code + // end information for bus mastering +#if 0 // #if !defined(COLDFIRE) && defined(SAME_CPU_PCI_MEM_ADDR) #ifdef BIG_ENDIAN - move.w #FLG_IO+FLG_LAST+FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_MOTOROLA,D1 + move.w #FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_MOTOROLA,D1 #else #ifdef LITTLE_ENDIAN_ADDRESSES_SWAPPED - move.w #FLG_IO+FLG_LAST+FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_INTEL_AS,D1 + move.w #FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_INTEL_AS,D1 #else #ifdef LITTLE_ENDIAN_LANE_SWAPPED - move.w #FLG_IO+FLG_LAST+FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_INTEL_LS,D1 + move.w #FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_INTEL_LS,D1 #else - move.w #FLG_IO+FLG_LAST+FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_UNKNOWN,D1 + move.w #FLG_8BIT+FLG_16BIT+FLG_32BIT+ORD_UNKNOWN,D1 #endif /* LITTLE_ENDIAN_LANE_SWAPPED */ #endif /* LITTLE_ENDIAN_ADDRESSES_SWAPPED */ #endif /* BIG_ENDIAN */ - move.w D1,PCI_RSC_DESC_FLAGS(A5,D0.l) - move.l OFFSET_IO(SP),D1 - move.l D1,PCI_RSC_DESC_START(A5,D0.l) // offset I/O resource + move.w D1,PCI_RSC_DESC_FLAGS+PCI_RSC_DESC_SIZE(A5) move.l #256,D1 - move.l D1,PCI_RSC_DESC_LENGTH(A5,D0.l) -#ifdef COLDFIRE - move.l #PCI_LOCAL_CONFIG,D1 - move.l D1,PCI_RSC_DESC_OFFSET(A5,D0.l) + move.l D1,PCI_RSC_DESC_LENGTH+PCI_RSC_DESC_SIZE(A5) + move.l OFFSET_MEMORY(A6),D0 + move.l D0,PCI_RSC_DESC_START+PCI_RSC_DESC_SIZE(A5) // offset memory resource + add.l D1,D0 + move.l D0,OFFSET_MEMORY(A6) +#ifdef SAME_CPU_PCI_MEM_ADDR + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l pci_memory_offset(A0),D1 #else - add.l #256,OFFSET_IO(SP) // offset I/O resource - move.l #PCI_IO_OFFSET,PCI_RSC_DESC_OFFSET(A5,D0.l) -#endif /* COLDFIRE */ move.l #PCI_MEMORY_OFFSET,D1 - move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) - clr.l PCI_RSC_DESC_ERROR(A5,D0.l) // internal error code -#ifndef COLDFIRE - move.l PCI_RSC_DESC_START(A5,D0.l),D2 // offset I/O resource now for I/O PLX9054 - moveq #PCIBAR1,D1 // PCI Base Address Register for I/O Accesses to Local, Runtime, and DMA - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot - bsr write_config_longword -#endif /* COLDFIRE */ #endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ + move.l D1,PCI_RSC_DESC_OFFSET+PCI_RSC_DESC_SIZE(A5) + move.l DMA_OFFSET(A6),D1 + move.l D1,PCI_RSC_DESC_DMAOFFSET+PCI_RSC_DESC_SIZE(A5) + clr.l PCI_RSC_DESC_ERROR+PCI_RSC_DESC_SIZE(A5) // internal error code + moveq #2,D0 +#else moveq #1,D0 - move.w D0,RESOURCE_INDEX(SP) // offset resource by handle +#endif /* !defined(COLDFIRE) && defined(SAME_CPU_PCI_MEM_ADDR) */ + move.w D0,RESOURCE_INDEX(A6) // offset resource by handle bra .end_area .devices: #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG lea debug41(PC),A0 bsr debug_display_string #endif #endif moveq #PCIBAR0,D5 // reg - clr.w RESOURCE_INDEX(SP) // index resource by handle + clr.w RESOURCE_INDEX(A6) // index resource by handle .loop_area: move.l D5,D1 // reg move.l D6,D0 // current function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword - move.l D0,D3 // save value and read type bits + move.l D0,BAR_VALUE(A6) // save value and read type bits moveq #-1,D2 move.l D5,D1 // reg move.l D6,D0 // current function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword move.l D5,D1 // reg move.l D6,D0 // function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword - move.l D0,SAVE_BITS(SP) // save value for try to find used bits (resolution) - lea OFFSET_MEMORY_PREF(SP),A3 + move.l D0,SAVE_BITS(A6) // save value for try to find used bits (resolution) + lea OFFSET_MEMORY_PREF(A6),A3 + lea START_OFFSET_MEMORY_PREF(A6),A2 and.l #PCI_BASE_PREF_M,D0 bne.s .memory_with_cache - lea OFFSET_MEMORY(SP),A3 + lea OFFSET_MEMORY(A6),A3 + lea START_OFFSET_MEMORY(A6),A2 .memory_with_cache: - move.l D3,D2 // saved value + move.l BAR_VALUE(A6),D2 // saved value move.l D5,D1 // reg move.l D6,D0 // function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword // restore value - move.l SAVE_BITS(SP),D0 // value used bits PCIBARx register + move.l SAVE_BITS(A6),D0 // value used bits PCIBARx register beq .next_area // register not used cmp.l #PCIERBAR,D5 // PCI Expansion ROM Base Register beq .expansion_rom moveq #PCI_BASE_SPACE_IO,D0 - and.l D3,D0 + and.l BAR_VALUE(A6),D0 beq .not_space_io // <> IO .space_io: moveq #PCI_BASE_IO_ADDR_M,D7 - and.l SAVE_BITS(SP),D7 // value PCIBARx register + and.l SAVE_BITS(A6),D7 // value PCIBARx register move.l D7,D0 moveq #-1,D1 .loop_find_first_lsb_io: @@ -961,26 +1413,31 @@ init_devices: .found_first_lsb_io: moveq #0,D2 bset D1,D2 // minimum step of the PCI base address - move.l OFFSET_IO(SP),D0 // current offset I/O resource + move.l OFFSET_IO(A6),D0 // current offset I/O resource and.l D7,D0 // alignment with the resolution of PCIBARx - cmp.l OFFSET_IO(SP),D0 // current offset I/O resource + cmp.l OFFSET_IO(A6),D0 // current offset I/O resource bcc.s .ok_with_current_offset_io add.l D2,D0 // add the minimum step of the PCI base address move.l D0,D7 bra.s .check_size_io .ok_with_current_offset_io: - move.l OFFSET_IO(SP),D7 // current offset I/O resource + move.l OFFSET_IO(A6),D7 // current offset I/O resource .check_size_io: move.l D7,D0 add.l D2,D0 // minimum step of the PCI base address is the size +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + cmp.l pci_io_size(A0),D0 +#else cmp.l #PCI_IO_SIZE,D0 - bcc .io_space_full // area overflow - move.l D7,OFFSET_IO(SP) // new offset I/O resource +#endif + bhi .io_space_full // area overflow + move.l D7,OFFSET_IO(A6) // new offset I/O resource move.w D4,D0 // slot mulu #PCI_MAX_FUNCTION,D0 add.l D6,D0 // function mulu #PCI_RSC_DESC_TOTALSIZE,D0 - move.w RESOURCE_INDEX(SP),D1 // index resource by handle + move.w RESOURCE_INDEX(A6),D1 // index resource by handle mulu #PCI_RSC_DESC_SIZE,D1 add.l D1,D0 move.w #PCI_RSC_DESC_SIZE,D1 @@ -999,23 +1456,28 @@ init_devices: #endif /* LITTLE_ENDIAN_ADDRESSES_SWAPPED */ #endif /* BIG_ENDIAN */ move.w D1,PCI_RSC_DESC_FLAGS(A5,D0.l) - move.l OFFSET_IO(SP),D1 + move.l OFFSET_IO(A6),D1 move.l D1,PCI_RSC_DESC_START(A5,D0.l) // offset I/O resource - add.l D2,OFFSET_IO(SP) // offset I/O resource + add.l D2,OFFSET_IO(A6) // offset I/O resource move.l D2,PCI_RSC_DESC_LENGTH(A5,D0.l) +#ifdef PCI_DYNAMIC_MAPPING + move.l pci_io_offset(A0),D1 +#else move.l #PCI_IO_OFFSET,D1 +#endif move.l D1,PCI_RSC_DESC_OFFSET(A5,D0.l) - move.l #PCI_MEMORY_OFFSET,D1 + move.l DMA_OFFSET(A6),D1 move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) clr.l PCI_RSC_DESC_ERROR(A5,D0.l) // internal error code move.l PCI_RSC_DESC_START(A5,D0.l),D2 // offset I/O resource move.l D5,D1 // reg move.l D6,D0 // function number + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG move.l D0,-(SP) moveq #0x30,D0 bsr debug_display_char @@ -1023,6 +1485,7 @@ init_devices: bsr debug_display_char move.l D5,D1 // reg move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword @@ -1033,11 +1496,11 @@ init_devices: #endif #endif #ifdef COLDFIRE - move.w RESOURCE_INDEX(SP),D0 + move.w RESOURCE_INDEX(A6),D0 addq.l #1,D0 - move.w D0,RESOURCE_INDEX(SP) // index resource by handle + move.w D0,RESOURCE_INDEX(A6) // index resource by handle #else - addq.w #1,RESOURCE_INDEX(SP) // index resource by handle + addq.w #1,RESOURCE_INDEX(A6) // index resource by handle #endif bra .next_area .expansion_rom: @@ -1046,7 +1509,7 @@ init_devices: .not_space_io: moveq #PCI_BASE_M_ADDR_M,D7 .not_space_io2: - and.l SAVE_BITS(SP),D7 // value PCIBARx register + and.l SAVE_BITS(A6),D7 // value PCIBARx register move.l D7,D0 moveq #-1,D1 .loop_find_first_lsb_memory: @@ -1074,7 +1537,7 @@ init_devices: #endif cmp.l #PCIERBAR,D5 // PCI Expansion ROM Base Register beq .memory_32bit - move.w D3,D0 + move.l BAR_VALUE(A6),D0 and.l #PCI_BASE_TYPE_M,D0 cmp.l #PCI_BASE_TYPE_MEM,D0 // 32-bit memory address beq .memory_32bit @@ -1103,41 +1566,51 @@ init_devices: moveq #PCI_PARITY_ERROR,D0 #endif .shutdown_device: - move.l D0,ERROR_CODE(SP) // error code + move.l D0,ERROR_CODE(A6) // error code // device will be shut down now moveq #PCICR,D1 // PCI Command Register move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot + move.l D0,-(SP) // handle bsr fast_read_config_word // remove Special Cycle / Master Enable / Memory Space / I/O Space and.l #~(PCI_CMDREG_SPCYC + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP),D0 move.w D0,D2 moveq #PCICR,D1 // PCI Command Register - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP)+,D0 // handle bsr write_config_word bra .end_area .memory_32bit: +#if 0 // old feature cmp.l #PCIBAR0,D5 // reg bne.s .no_fix_graphic_card - tst.w GRAPHICS_CARD_FLAG(SP) // flag graphic card + tst.w GRAPHICS_CARD_FLAG(A6) // flag graphic card beq.s .no_fix_graphic_card cmp.l #GRAPHIC_CARD_SIZE/4,D2 bcc.s .no_fix_graphic_card move.l #GRAPHIC_CARD_SIZE,D2 .no_fix_graphic_card: +#endif move.l D7,D0 add.l D2,D0 // minimum step of the PCI base address is the size - cmp.l #PCI_MEMORY_SIZE,D0 - bcc .mem_space_full // area overflow + sub.l (A2),D0 // start offset memory ressource +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_size(A0),D1 + lsr.l #1,D1 + cmp.l D1,D0 +#else + cmp.l #PCI_MEMORY_SIZE/2,D0 +#endif + bhi .mem_space_full // area overflow move.l D7,(A3) // new offset memory resource - move.l D4,D0 // handle + move.l D4,D0 // device mulu #PCI_MAX_FUNCTION,D0 add.l D6,D0 mulu #PCI_RSC_DESC_TOTALSIZE,D0 - move.w RESOURCE_INDEX(SP),D1 // index resource by handle + move.w RESOURCE_INDEX(A6),D1 // index resource by handle mulu #PCI_RSC_DESC_SIZE,D1 add.l D1,D0 move.w #PCI_RSC_DESC_SIZE,D1 @@ -1155,27 +1628,41 @@ init_devices: #endif /* LITTLE_ENDIAN_LANE_SWAPPED */ #endif /* LITTLE_ENDIAN_ADDRESSES_SWAPPED */ #endif /* BIG_ENDIAN */ + cmp.l #PCIERBAR,D5 // PCI Expansion ROM Base Register + bne.s .not_expansion_rom2 + or.l #FLG_ROM,D1 // Expansion ROM +.not_expansion_rom2: move.w D1,PCI_RSC_DESC_FLAGS(A5,D0.l) move.l (A3),D1 move.l D1,PCI_RSC_DESC_START(A5,D0.l) // offset memory resource add.l D2,(A3) // offset memory resource move.l D2,PCI_RSC_DESC_LENGTH(A5,D0.l) +#ifdef SAME_CPU_PCI_MEM_ADDR + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l pci_memory_offset(A0),D1 +#else move.l #PCI_MEMORY_OFFSET,D1 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ move.l D1,PCI_RSC_DESC_OFFSET(A5,D0.l) - move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) + move.l DMA_OFFSET(A6),D1 + move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) clr.l PCI_RSC_DESC_ERROR(A5,D0.l) // internal error code move.l PCI_RSC_DESC_START(A5,D0.l),D2 // offset memory resource cmp.l #PCIERBAR,D5 // PCI Expansion ROM Base Register bne.s .not_expansion_rom - or.l #PCI_BASE_ROM_ENABLE,D2 + or.l #PCI_BASE_ROM_ENABLE,D2 .not_expansion_rom: move.l D5,D1 // reg move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG move.l D0,-(SP) moveq #0x30,D0 // '0' bsr debug_display_char @@ -1183,6 +1670,7 @@ init_devices: bsr debug_display_char move.l D5,D1 // reg move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword @@ -1193,11 +1681,11 @@ init_devices: #endif #endif #ifdef COLDFIRE - move.w RESOURCE_INDEX(SP),D0 + move.w RESOURCE_INDEX(A6),D0 addq.l #1,D0 - move.w D0,RESOURCE_INDEX(SP) // index resource by handle + move.w D0,RESOURCE_INDEX(A6) // index resource by handle #else - addq.w #1,RESOURCE_INDEX(SP) // index resource by handle + addq.w #1,RESOURCE_INDEX(A6) // index resource by handle #endif bra .next_area .memory_64bit: @@ -1206,12 +1694,14 @@ init_devices: moveq #4,D1 add.l D5,D1 // reg + 4 (next PCIBARx) move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword moveq #4,D1 add.l D5,D1 // reg + 4 (next PCIBARx) move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword @@ -1221,14 +1711,22 @@ init_devices: bne .need_more_4gb move.l D7,D0 add.l D2,D0 // minimum step of the PCI base address is the size - cmp.l #PCI_MEMORY_SIZE,D0 - bcc .mem_space_full // area overflow + sub.l (A2),D0 // start offset memory ressource +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_size(A0),D1 + lsr.l #1,D1 + cmp.l D1,D0 +#else + cmp.l #PCI_MEMORY_SIZE/2,D0 +#endif + bhi .mem_space_full // area overflow move.l D7,(A3) // new offset memory resource - move.l D4,D0 // handle + move.l D4,D0 // device mulu #PCI_MAX_FUNCTION,D0 add.l D6,D0 mulu #PCI_RSC_DESC_TOTALSIZE,D0 - move.w RESOURCE_INDEX(SP),D1 // index resource by handle + move.w RESOURCE_INDEX(A6),D1 // index resource by handle mulu #PCI_RSC_DESC_SIZE,D1 add.l D1,D0 move.w #PCI_RSC_DESC_SIZE,D1 @@ -1249,20 +1747,30 @@ init_devices: move.w D1,PCI_RSC_DESC_FLAGS(A5,D0.l) move.l (A3),D1 move.l D1,PCI_RSC_DESC_START(A5,D0.l) // offset memory resource - add.l D2,(A3) // offset memory resource + add.l D2,(A3) // offset memory resource move.l D2,PCI_RSC_DESC_LENGTH(A5,D0.l) +#ifdef SAME_CPU_PCI_MEM_ADDR + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l pci_memory_offset(A0),D1 +#else move.l #PCI_MEMORY_OFFSET,D1 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ move.l D1,PCI_RSC_DESC_OFFSET(A5,D0.l) + move.l DMA_OFFSET(A6),D1 move.l D1,PCI_RSC_DESC_DMAOFFSET(A5,D0.l) clr.l PCI_RSC_DESC_ERROR(A5,D0.l) // internal error code move.l PCI_RSC_DESC_START(A5,D0.l),D2 // offset memory resource move.l D5,D1 // reg move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG move.l D0,-(SP) moveq #0x30,D0 bsr debug_display_char @@ -1270,6 +1778,7 @@ init_devices: bsr debug_display_char move.l D5,D1 // reg move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_longword @@ -1280,16 +1789,17 @@ init_devices: #endif #endif #ifdef COLDFIRE - move.w RESOURCE_INDEX(SP),D0 + move.w RESOURCE_INDEX(A6),D0 addq.l #1,D0 - move.w D0,RESOURCE_INDEX(SP) // index resource by handle + move.w D0,RESOURCE_INDEX(A6) // index resource by handle #else - addq.w #1,RESOURCE_INDEX(SP) // index resource by handle + addq.w #1,RESOURCE_INDEX(A6) // index resource by handle #endif moveq #0,D2 moveq #4,D1 add.l D5,D1 // reg + 4 move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr write_config_longword @@ -1302,23 +1812,32 @@ init_devices: moveq #PCIERBAR,D5 // PCI Expansion ROM Base Register bra .loop_area .end_loop_area: -#ifdef COLDFIRE moveq #PCI_CACHE_LINE,D2 moveq #PCICLSR,D1 move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot + move.l D0,-(SP) bsr write_config_byte + moveq #PCISR,D1 // PCI Status Register + move.l (SP),D0 // handle + bsr fast_read_config_word + move.l D0,D2 + moveq #PCISR,D1 // PCI Status Register + move.l (SP),D0 // handle + bsr write_config_word // clear errors +#ifndef COLDFIRE + move.w #PCI_CMDREG_SERR + PCI_CMDREG_PERR + PCI_CMDREG_MEMWINV + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP,D2 +#else + move.w #PCI_CMDREG_PERR + PCI_CMDREG_MEMWINV + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP,D2 #endif - move.w #PCI_CMDREG_PERR + PCI_CMDREG_MASTR + PCI_CMDREG_MEMSP + PCI_CMDREG_IOSP,D2 moveq #PCICR,D1 // PCI Command Register - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP)+,D0 bsr write_config_word .end_area: #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG move.l D0,-(SP) move.l A0,-(SP) moveq #13,D0 @@ -1327,6 +1846,7 @@ init_devices: bsr debug_display_char moveq #PCICR,D1 move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot bsr fast_read_config_word @@ -1341,14 +1861,24 @@ init_devices: move.l (SP)+,D0 #endif #endif - move.l D4,D0 // handle + move.l D4,D0 // device mulu #PCI_MAX_FUNCTION,D0 add.l D6,D0 mulu #PCI_RSC_DESC_TOTALSIZE,D0 - move.w RESOURCE_INDEX(SP),D1 // index resource by handle + move.w RESOURCE_INDEX(A6),D1 // index resource by handle + bne.s .res_found + clr.w PCI_RSC_DESC_FLAGS(A5,D0.l) + clr.l PCI_RSC_DESC_START(A5,D0.l) // offset memory resource + clr.l PCI_RSC_DESC_OFFSET(A5,D0.l) + clr.l PCI_RSC_DESC_DMAOFFSET(A5,D0.l) + clr.l PCI_RSC_DESC_LENGTH(A5,D0.l) + clr.w PCI_RSC_DESC_NEXT(A5,D0.l) + clr.l PCI_RSC_DESC_ERROR(A5,D0.l) // internal error code + addq.l #1,D1 // if no resource found +.res_found: mulu #PCI_RSC_DESC_SIZE,D1 add.l D1,D0 - move.l ERROR_CODE(SP),D1 // internal error code + move.l ERROR_CODE(A6),D1 // internal error code bne.s .end_area_with_error #ifdef COLDFIRE move.w (PCI_RSC_DESC_FLAGS-PCI_RSC_DESC_SIZE)(A5,D0.l),D1 @@ -1369,67 +1899,12 @@ init_devices: #endif clr.w PCI_RSC_DESC_NEXT(A5,D0.l) .end_area_set_int: - // Some graphic adapters set the Interrupt Pin Register - // in that way, that they will use an Interrupt, although - // they don't. That's nonsens. - // So the PCI-BIOS ignores the Interrupt Pin Register of - // that graphic adapters and does NOT install an Interrupt - // Handler for such an adapter. - move.l D6,D0 - swap D0 - or.l D4,D0 // handle - bsr disable_interrupt - tst.w GRAPHICS_CARD_FLAG(SP) // flag graphic card - bne.s .graphic_card - moveq #PCIIPR,D1 // Interrupt Pin move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 - or.l D4,D0 // slot - bsr fast_read_config_byte - tst.b D0 - beq.s .graphic_card - move.l #PCI_IRQ_BASE_VECTOR,D0 -#ifdef COLDFIRE - lea int_cfpci(PC),A0 - tst.l D4 // slot - beq.s .set_vector // bridge -#ifdef MCF5445X - move.w #64+INT0_LO_EPORT3+OFFSET_INT_CF68KLIB,D0 // IRQ5 EPORT - lea int3_pci(PC),A0 -#else /* MCF548X */ - move.w #64+5+OFFSET_INT_CF68KLIB,D0 // IRQ5 EPORT - lea int5_pci(PC),A0 - cmp.l #2,D4 - bls.s .graphic_card - move.w #64+7+OFFSET_INT_CF68KLIB,D0 // IRQ7 EPORT - lea int7_pci(PC),A0 -#endif /* MCF5445X */ -#else /* ATARI - CTPCI/PLX9054 */ - lea int_ctpci(PC),A0 - tst.l D4 // slot - beq.s .set_vector // bridge - addq.l #1,D0 // jump LSERR - lea inta_ctpci(PC),A0 - cmp.l #1,D4 - beq.s .set_vector - lea intb_ctpci(PC),A0 - cmp.l #2,D4 - beq.s .set_vector - lea intc_ctpci(PC),A0 - cmp.l #3,D4 - beq.s .set_vector - lea intd_ctpci(PC),A0 -#endif /* COLDFIRE */ -.set_vector: - move.l A2,-(SP) - pea (A0) - add.l D4,D0 - move.w D0,-(SP) - move.w #5,-(SP) // Setexec - trap #13 - addq.l #8,SP - move.l (SP)+,A2 -.graphic_card: + or.l D4,D0 // device + move.l D0,-(SP) // handle + bsr disable_interrupt // Interrupt Line Register will be initialised with 0xFF // because of different solutions regarding the Hardware // (Hades/Milan/...) This register is only for information @@ -1437,13 +1912,14 @@ init_devices: // don't care about the value set in this register. move.b #0xFF,D2 moveq #PCIILR,D1 // Interrupt Line - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP)+,D0 // handle bsr write_config_byte #ifdef COLDFIRE + tst.l D3 + bne.s .set_lat // <> bus 0 tst.l D4 - beq .next_handle // host bridge + beq .next_slot // host bridge +.set_lat: #endif // Latency Timer Register is initialised with a useable // value. The new revision also cares about the min and @@ -1451,60 +1927,56 @@ init_devices: // MAX_LAT registers moveq #PCIMGR,D1 // Min_Gnt move.l D6,D0 // function + add.l D3,D0 // bus number swap D0 or.l D4,D0 // slot + move.l D0,-(SP) // handle bsr fast_read_config_byte tst.b D0 bne.s .max_gmt_lat_exist moveq #PCIMLR,D1 // Max_Lat - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP),D0 // handle bsr fast_read_config_byte tst.b D0 bne.s .max_gmt_lat_exist - moveq #PCI_MAXLAT,D2 // Latency Timer value 1uS for 33 MHz bus + move.b #PCI_MAXLAT,D2 // Latency Timer value 1uS for 33 MHz bus bra.s .write_latency_timer .max_gmt_lat_exist: moveq #PCIMLR,D1 // Max_Lat - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP),D0 // handle bsr fast_read_config_byte lsl.l #3,D0 // *8 move.b D0,D2 // Latency Timer value cmp.l #PCI_MAXLAT*2,D0 // 2 uS bls.s .write_latency_timer moveq #PCIMGR,D1 // Min_Gnt - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP),D0 // handle bsr fast_read_config_byte lsl.l #3,D0 // *8 move.b D0,D2 // Latency Timer value .write_latency_timer: moveq #PCILTR,D1 // Latency Timer - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot + move.l (SP)+,D0 // handle bsr write_config_byte tst.l D6 // function bne .next_function -#if 0 - tst.w GRAPHICS_CARD_FLAG(SP) +#if 1 + tst.w GRAPHICS_CARD_FLAG(A6) bne .next_slot // do not check for multi-function on graphic card (too big space) #endif // before we go to the next slot, we first check if we have // a multi-function device. If so, we need to initialize // the remaining functions on the current card first - move.l D4,D0 // handle (slot) + move.l D3,D0 // bus number + swap D0 + or.l D4,D0 // slot moveq #PCICLSR,D1 bsr fast_read_config_longword btst #23,D0 beq .next_slot // now that we now we have a multi function card, iterate functions #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG lea debug46(PC),A0 bsr debug_display_string #endif @@ -1515,7 +1987,7 @@ init_devices: bcc .next_slot bra .loop_handle .no_device_found_here: - move.l D4,D0 // handle + move.l D4,D0 // device mulu #PCI_MAX_FUNCTION,D0 add.l D6,D0 // function mulu #PCI_DEV_DES_SIZE,D0 @@ -1528,40 +2000,121 @@ init_devices: .next_slot: moveq #0,D6 // function number #ifdef COLDFIRE -#if 0 // #ifdef DEBUG +#ifdef DEBUG lea debug47(PC),A0 bsr debug_display_string #endif #endif -.next_handle: - addq.l #1,D4 // handle - cmp.l #PCI_MAX_HANDLE,D4 + addq.l #1,D4 // device + moveq #PCI_MAX_SLOT,D0 + tst.l D3 // bus number + beq.s .primary_bus + moveq #PCI_MAX_DEVICE,D0 +.primary_bus: + cmp.l D0,D4 bcs .loop_handle -#ifdef DEBUG - lea debug34(PC),A0 - bsr debug_display_string -#endif - move.l A6,D1 // value - move.l #0x5F504349,D0 // cookie _PCI - bsr add_cookie + moveq #0,D0 // OK + tst.l D3 // bus number + bne.s .end_init_pci_bios // secondary bus + moveq #0,D4 // INT bridge (0), INT-A-B-C-D (1-4) +.loop_init_int: #ifdef COLDFIRE -#ifdef DEBUG - moveq #0,D0 - bsr display_devices + tst.l D4 // slot + beq.s .set_vector_ok // bridge +#ifdef MCF5445X + move.w #64+INT0_LO_EPORT3+OFFSET_INT_CF68KLIB,D0 // IRQ5 EPORT + lea int3_pci(PC),A0 +#else /* MCF548X */ + move.w #64+5+OFFSET_INT_CF68KLIB,D0 // IRQ5 EPORT + lea int5_pci(PC),A0 // INTC-D (M5484LITE) +#ifndef MCF547X + cmp.l #2,D4 // slot + bls.s .set_vector + // INT7 call by software INT2 (can be masked) + move.l A2,-(SP) + pea int2_pci(PC) // INTA-B (M5484LITE) + move.w #64+2+OFFSET_INT_CF68KLIB,-(SP) // IRQ2 EPORT + move.w #5,-(SP) // Setexec + trap #13 + addq.l #8,SP + move.l (SP)+,A2 + move.w #64+7+OFFSET_INT_CF68KLIB,D0 // IRQ7 EPORT + lea int7_pci(PC),A0 // INTA-B (M5484LITE) +#endif /* MCF547X */ +#endif /* MCF5445X */ +#else /* ATARI - CTPCI/PLX9054 */ + move.l #PCI_IRQ_BASE_VECTOR,D0 + lea int_ctpci(PC),A0 + tst.l D4 // slot + beq.s .set_vector // bridge (LINT) + lea inta_ctpci(PC),A0 + cmp.l #1,D4 + beq.s .set_vector + lea intb_ctpci(PC),A0 + cmp.l #2,D4 + beq.s .set_vector + lea intc_ctpci(PC),A0 + cmp.l #3,D4 + beq.s .set_vector + lea intd_ctpci(PC),A0 +#endif /* COLDFIRE */ +.set_vector: + move.l A2,-(SP) + pea (A0) +#ifndef COLDFIRE + add.l D4,D0 #endif + move.w D0,-(SP) + move.w #5,-(SP) // Setexec + trap #13 + addq.l #8,SP + move.l (SP)+,A2 +.set_vector_ok: + addq.l #1,D4 + cmp.l #4,D4 + bls.s .loop_init_int +#ifdef COLDFIRE + move.l MCF_PCI_PCIISR,D0 + move.l D0,MCF_PCI_PCIISR // clear interrupt +#ifndef MCF5445X + move.l #~MCF_INTC_IMRH_INT_MASK43,D0 // enable XLB PCI interrupt + and.l D0,MCF_INTC_IMRH #endif +#endif /* COLDFIRE */ moveq #0,D0 // OK +.end_init_pci_bios: lea RESERVE_STACK(SP),SP // clear local variables +.end_init_pci_bios2: + movem.l (SP),D1-A6 + lea 56(SP),SP + rts +#ifdef PCI_DYNAMIC_MAPPING +.hardware_failure: + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp + move.w (SP)+,SR + move.l (SP)+,A5 + move.l (SP)+,A4 + moveq #-1,D0 // error + lea RESERVE_STACK(SP),SP // clear local variables + movem.l (SP),D1-A6 + lea 56(SP),SP rts +#endif /* PCI_DYNAMIC_MAPPING */ display_devices: #ifdef COLDFIRE lea -32(SP),SP movem.l D1-A0,(SP) -#else - movem.l D1-A0,-(SP) +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts #endif +#else /* !COLDFIRE */ + movem.l D1-A0,-(SP) +#endif /* COLDFIRE */ move.l D0,D6 // flag more infos move.l #0x5F504349,D0 // _PCI bsr get_cookie @@ -1573,213 +2126,282 @@ display_devices: bsr display_string lea hor_separator(PC),A0 bsr display_string_single - lea begin_table(PC),A0 // Slot | Fctn | VendorID | DeviceID | Description + lea begin_table(PC),A0 // Bus | Slot | Fctn | VendorID | DeviceID | Description bsr display_string_single lea hor_separator(PC),A0 bsr display_string_single moveq #0,D4 // slot moveq #0,D5 // function + moveq #0,D7 // bus .loop_handle_display: - move.l D5,D0 - swap D0 - or.l D4,D0 // handle - bsr get_resource - bmi .next_slot_display - move.l D0,A1 // resource - moveq #PCIIDR,D1 - move.l D5,D0 - swap D0 - or.l D4,D0 // handle - bsr fast_read_config_longword // Device ID & Vendor ID - move.l D0,D3 - // display slot - moveq #0x20,D0 // " " - bsr display_char - moveq #0x5B,D0 // [ - bsr display_char - moveq #0x30,D0 - add.l D4,D0 // slot - bsr display_char - moveq #0x5D,D0 // ] - bsr display_char - lea separator(PC),A0 - bsr display_string_single - // display function - moveq #0x20,D0 // " " - bsr display_char - moveq #0x5B,D0 // [ - bsr display_char - moveq #0x30,D0 - add.l D5,D0 // function - bsr display_char - moveq #0x5D,D0 // ] - bsr display_char - lea separator(PC),A0 - bsr display_string_single + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D5,D0 // function number + swap D0 + or.l D4,D0 // device + bsr get_resource + bmi .next_slot_display + move.l D0,A1 // resource + moveq #PCIIDR,D1 + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D5,D0 // function number + swap D0 + or.l D4,D0 // device + bsr fast_read_config_longword // Device ID & Vendor ID + move.l D0,D3 + tst.l D7 // bus number + beq.s .display_all_devices_primary_bus #ifdef COLDFIRE - moveq #0,D0 - move.w D3,D0 - cmp.l #PCI_NOBODYHOME,D0 // Vendor ID + moveq #0,D0 + move.w D3,D0 + cmp.l #PCI_NOBODYHOME,D0 // Vendor ID #else - cmp.w #PCI_NOBODYHOME,D3 // Vendor ID + cmp.w #PCI_NOBODYHOME,D3 // Vendor ID +#endif + beq .next_slot_display // on secondary bus display only devices found +.display_all_devices_primary_bus: + // display bus + moveq #0x20,D0 // " " + bsr display_char + moveq #0x5B,D0 // [ + bsr display_char + moveq #0x30,D0 + add.l D7,D0 // bus + bsr display_char + moveq #0x5D,D0 // ] + bsr display_char + lea separator(PC),A0 + bsr display_string_single + // display slot + move.l D4,D0 // slot +#ifdef COLDFIRE + .chip 68060 #endif - beq .no_device_found_here_2 - moveq #0x20,D0 // " " - bsr display_char - moveq #0x30,D0 // 0 - bsr display_char - moveq #0x78,D0 // x - bsr display_char - move.w D3,D0 // Vendor ID - bsr hex_word - moveq #0x20,D0 // " " - bsr display_char - lea separator(PC),A0 - bsr display_string_single - moveq #0x20,D0 - bsr display_char - moveq #0x30,D0 // 0 - bsr display_char - moveq #0x78,D0 // x - bsr display_char - move.l D3,D0 - swap D0 // Device ID - bsr hex_word - moveq #0x20,D0 - bsr display_char - lea separator(PC),A0 - bsr display_string_single - moveq #PCIREV,D1 - move.l D5,D0 - swap D0 - or.l D4,D0 // handle - bsr fast_read_config_longword // & class code - move.l D0,D7 - bsr display_infos_class -#if 0 - tst.l D6 - beq.s .no_66mhz - moveq #PCICSR,D1 - move.l D5,D0 - swap D0 - or.l D4,D0 // handle - bsr fast_read_config_longword - btst #21,D0 - beq.s .no_66mhz - lea _66mhz(PC),A0 - bsr display_string_single -.no_66mhz: + divu #10,D0 +#ifdef COLDFIRE + .chip 5200 #endif - moveq #5,D1 -.loop_resource: - move.l PCI_RSC_DESC_ERROR(A1),D0 - bmi .error_device - move.w PCI_RSC_DESC_FLAGS(A1),D0 -#if 0 - tst.l D6 - beq.s .no_infos_desc + move.l D0,D1 + clr.w D1 + swap D1 + ext.l D0 + beq.s .slot_less_10 move.l D0,-(SP) - lea desc_io(PC),A0 + moveq #0x5B,D0 // [ + bsr display_char + moveq #0x30,D0 + add.l (SP)+,D0 // slot / 10 + bsr display_char + bra.s .slot_display +.slot_less_10: + moveq #0x20,D0 // " " + bsr display_char + moveq #0x5B,D0 // [ + bsr display_char +.slot_display: + moveq #0x30,D0 + add.l D1,D0 + bsr display_char // slot + moveq #0x5D,D0 // ] + bsr display_char + lea separator(PC),A0 + bsr display_string_single + // display function + moveq #0x20,D0 // " " + bsr display_char + moveq #0x5B,D0 // [ + bsr display_char + moveq #0x30,D0 + add.l D5,D0 // function + bsr display_char + moveq #0x5D,D0 // ] + bsr display_char + lea separator(PC),A0 + bsr display_string_single #ifdef COLDFIRE - and.l #FLG_IO,D0 + moveq #0,D0 + move.w D3,D0 + cmp.l #PCI_NOBODYHOME,D0 // Vendor ID #else - and.w #FLG_IO,D0 -#endif - bne.s .is_desc_io - lea desc_mem(PC),A0 -.is_desc_io: - bsr display_string_single - move.l PCI_RSC_DESC_START(A1),D0 - add.l PCI_RSC_DESC_OFFSET(A1),D0 - bsr hex_long - lea desc_size(PC),A0 + cmp.w #PCI_NOBODYHOME,D3 // Vendor ID +#endif + beq .no_device_found_here_display + moveq #0x20,D0 // " " + bsr display_char + moveq #0x30,D0 // 0 + bsr display_char + moveq #0x78,D0 // x + bsr display_char + move.w D3,D0 // Vendor ID + bsr hex_word + moveq #0x20,D0 // " " + bsr display_char + lea separator(PC),A0 + bsr display_string_single + moveq #0x20,D0 + bsr display_char + moveq #0x30,D0 // 0 + bsr display_char + moveq #0x78,D0 // x + bsr display_char + move.l D3,D0 + swap D0 // Device ID + bsr hex_word + moveq #0x20,D0 + bsr display_char + lea separator(PC),A0 bsr display_string_single - move.l PCI_RSC_DESC_LENGTH(A1),D0 - bsr hex_long - move.l (SP)+,D0 -.no_infos_desc: -#endif + moveq #PCIREV,D1 + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D5,D0 // function number + swap D0 + or.l D4,D0 // device + bsr fast_read_config_longword // & class code + bsr display_infos_class + tst.l D6 + beq.s .no_66mhz + moveq #PCICSR,D1 + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D5,D0 // function number + swap D0 + or.l D4,D0 // device + bsr fast_read_config_longword + btst #21,D0 + beq.s .no_66mhz + lea _66mhz(PC),A0 + bsr display_string_single +.no_66mhz: + moveq #5,D1 +.loop_resource: + move.l PCI_RSC_DESC_ERROR(A1),D0 + bmi .error_device + move.w PCI_RSC_DESC_FLAGS(A1),D0 + tst.l D6 + beq.s .no_infos_desc + move.l D0,-(SP) + lea desc_io(PC),A0 #ifdef COLDFIRE - and.l #FLG_LAST,D0 - bne.s .next_handle_3 - move.w PCI_RSC_DESC_NEXT(A1),D0 - ext.l D0 - add.l D0,A1 - subq.l #1,D1 - bpl.s .loop_resource + and.l #FLG_IO,D0 #else - and.w #FLG_LAST,D0 - bne.s .next_handle_3 - add.w PCI_RSC_DESC_NEXT(A1),A1 - dbra D1,.loop_resource + and.w #FLG_IO,D0 #endif + bne.s .is_desc_io + lea desc_mem(PC),A0 +.is_desc_io: + move.l A0,-(SP) + lea separators(PC),A0 + bsr display_string_single + move.l (SP)+,A0 + bsr display_string_single + move.l PCI_RSC_DESC_START(A1),D0 + add.l PCI_RSC_DESC_OFFSET(A1),D0 + bsr hex_long + lea desc_size(PC),A0 + bsr display_string_single + move.l PCI_RSC_DESC_LENGTH(A1),D0 + bsr hex_long + move.l (SP)+,D0 +.no_infos_desc: +#ifdef COLDFIRE + and.l #FLG_LAST,D0 + bne.s .next_handle_3 + move.w PCI_RSC_DESC_NEXT(A1),D0 + ext.l D0 + add.l D0,A1 + subq.l #1,D1 + bpl.s .loop_resource +#else /* COLDFIRE */ + and.w #FLG_LAST,D0 + bne.s .next_handle_3 + add.w PCI_RSC_DESC_NEXT(A1),A1 + dbra D1,.loop_resource +#endif /* COLDFIRE */ .next_handle_3: - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char - bra.s .next_handle_2 + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char + bra.s .next_handle_2 .error_device: - lea no_more_io_space(PC),A0 // no more IO-space available - cmp.l #PCI_NO_MORE_IO_SPACE,D0 - beq.s .display_error_device - lea no_more_mem_space(PC),A0 // no more MEM-space - cmp.l #PCI_NO_MORE_MEM_SPACE,D0 - beq.s .display_error_device - lea no_more_memory_below_1mb(PC),A0 // no more memory space below 1 MB - cmp.l #PCI_NO_MORE_MEM_BELOW_1MB,D0 - beq.s .display_error_device - lea need_more_than_4gb(PC),A0 // device requests more than 4GB memory - cmp.l #PCI_NEED_MORE_THAN_4GB,D0 - beq.s .display_error_device - lea unknow_memory_type(PC),A0 // device requests unknown memory type - cmp.l #PCI_UNKNOW_MEMORY_TYPE,D0 + lea no_more_io_space(PC),A0 // no more IO-space available + cmp.l #PCI_NO_MORE_IO_SPACE,D0 + beq.s .display_error_device + lea no_more_mem_space(PC),A0 // no more MEM-space + cmp.l #PCI_NO_MORE_MEM_SPACE,D0 + beq.s .display_error_device + lea no_more_memory_below_1mb(PC),A0 // no more memory space below 1 MB + cmp.l #PCI_NO_MORE_MEM_BELOW_1MB,D0 + beq.s .display_error_device + lea need_more_than_4gb(PC),A0 // device requests more than 4GB memory + cmp.l #PCI_NEED_MORE_THAN_4GB,D0 + beq.s .display_error_device + lea unknow_memory_type(PC),A0 // device requests unknown memory type + cmp.l #PCI_UNKNOW_MEMORY_TYPE,D0 #ifdef CHECK_PARITY - beq.s .display_error_device - lea parity_error(PC),A0 // detected parity error - cmp.l #PCI_PARITY_ERROR,D0 + beq.s .display_error_device + lea parity_error(PC),A0 // detected parity error + cmp.l #PCI_PARITY_ERROR,D0 #endif - bne.s .next_handle_2 + bne.s .next_handle_3 // unknow error .display_error_device: - bsr display_string_single - bra.s .next_slot_display -.no_device_found_here_2: - lea no_device(PC),A0 // no device - bsr display_string_single - bra.s .next_slot_display + move.l A0,-(SP) + lea separators(PC),A0 + bsr display_string_single + move.l (SP)+,A0 + bsr display_string_single + bra.s .next_slot_display +.no_device_found_here_display: + lea no_device(PC),A0 // no device + bsr display_string_single + bra.s .next_slot_display .next_handle_2: - tst.l D4 - beq.s .next_slot_display // do not search for multiple devices on bridge -#if 0 - move.l D7,D0 // PCIREV - swap D0 - lsr.l #8,D0 // base class code - and.l #0xFF,D0 - cmp.l #PCI_CLASS_DISPLAY,D0 - beq.s .next_slot_display // do not check for multi-function on graphic card (too big space) -#endif - // do we have a multi-function device? - move.l D4,D0 // handle (slot) - moveq #PCICLSR,D1 - bsr fast_read_config_longword - btst #23,D0 - beq.s .next_slot_display - addq.l #1,D5 // function - cmp.l #PCI_MAX_FUNCTION,D5 - bcs .loop_handle_display + tst.l D7 // bus number + bne.s .secondary_bus_display + tst.l D4 + beq.s .next_slot_display // do not search for multiple devices on bridge +.secondary_bus_display: + // do we have a multi-function device? + moveq #PCICLSR,D1 + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + swap D0 + or.l D4,D0 // device (slot) + bsr fast_read_config_longword + btst #23,D0 + beq.s .next_slot_display + addq.l #1,D5 // function + cmp.l #PCI_MAX_FUNCTION,D5 + bcs .loop_handle_display .next_slot_display: - moveq #0,D5 - addq.l #1,D4 // handle - cmp.l #PCI_MAX_HANDLE,D4 + moveq #0,D5 // function + moveq #PCI_MAX_SLOT,D0 + tst.l D7 // bus number + beq.s .primary_bus_display + moveq #PCI_MAX_DEVICE,D0 +.primary_bus_display: + addq.l #1,D4 // device + cmp.l D0,D4 + bcs .loop_handle_display + moveq #0,D4 // device + addq.l #1,D7 // bus + cmp.l #PCI_MAX_BUS,D7 bcs .loop_handle_display moveq #0,D0 // OK .end_display_devices: #ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D1 + move.l D1,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif movem.l (SP),D1-A0 lea 32(SP),SP -#else +#else /* !COLDFIRE */ movem.l (SP)+,D1-A0 -#endif +#endif /* COLDFIRE */ rts display_infos_class: @@ -1835,6 +2457,7 @@ display_infos_class: .old_device: lea pciinfo0(PC),A0 // Device built before Class Code definitions bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -1849,9 +2472,13 @@ display_infos_class: .vga_compatible: lea pciinfo2(PC),A0 // (VGA compatible) bra .add_subclass +#else + bra .end_info_class +#endif /* DISPLAY_SUBCLASS */ .mass_storage: lea pciinfo10(PC),A0 // Mass Storage Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -1891,9 +2518,13 @@ display_infos_class: .serial_ata: lea pciinfo17(PC),A0 // (SATA) bra .add_subclass +#else + bra .end_info_class +#endif /* DISPLAY_SUBCLASS */ .network_controller: lea pciinfo20(PC),A0 // Network controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -1933,9 +2564,13 @@ display_infos_class: .picmg_controller: lea pciinfo27(PC),A0 // (PICMG) bra .add_subclass +#else + bra .end_info_class +#endif /* DISPLAY_SUBCLASS */ .display_controller: lea pciinfo30(PC),A0 // Display Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -1955,9 +2590,13 @@ display_infos_class: .controller_3d: lea pciinfo33(PC),A0 // (3D) bra .add_subclass +#else + bra .end_info_class +#endif /* DISPLAY_SUBCLASS */ .multimedia_controller: lea pciinfo40(PC),A0 // Multimedia Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -1977,9 +2616,13 @@ display_infos_class: .computer_telephony: lea pciinfo43(PC),A0 // (Computer Telephony) bra .add_subclass +#else + bra .end_info_class +#endif /* DISPLAY_SUBCLASS */ .memory_controller: lea pciinfo50(PC),A0 // Memory controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -1994,9 +2637,13 @@ display_infos_class: .flash_device: lea pciinfo52(PC),A0 // (FLASH) bra .add_subclass +#else + bra .end_info_class +#endif /* DISPLAY_SUBCLASS */ .bridge_device: lea pciinfo60(PC),A0 // Bridge Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2056,9 +2703,13 @@ display_infos_class: .infiniband_bridge: lea pciinfo611(PC),A0 // (InfiniBand Bridge) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .communications_controller: lea pciinfo70(PC),A0 // Communications Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2093,9 +2744,13 @@ display_infos_class: .smart_card_controller: lea pciinfo76(PC),A0 // (Smart Card) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .peripheral_controller: lea pciinfo80(PC),A0 // Peripheral Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2125,9 +2780,13 @@ display_infos_class: .pci_hot_plug_controller: lea pciinfo85(PC),A0 // (PCI Hot-Plug) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .input_device: lea pciinfo90(PC),A0 // Input Device bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2157,9 +2816,13 @@ display_infos_class: .gameport_controller: lea pciinfo95(PC),A0 // (Gameport) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .docking_station: lea pciinfo100(PC),A0 // Docking Station bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2167,9 +2830,13 @@ display_infos_class: bne .unknow_subclass_device lea pciinfo101(PC),A0 // (Docking Station) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .processor: lea pciinfo110(PC),A0 // Processor bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2209,9 +2876,13 @@ display_infos_class: .coprocessor: lea pciinfo117(PC),A0 // (Coprocessor) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .serial_bus: lea pciinfo120(PC),A0 // Serial Bus bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2266,9 +2937,13 @@ display_infos_class: .canbus: lea pciinfo1210(PC),A0 // (CANbus) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .wireless_controller: lea pciinfo130(PC),A0 // Wireless Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2308,9 +2983,13 @@ display_infos_class: .ethernet_802_11b: lea pciinfo137(PC),A0 // (Ethernet 802.11b) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .intelligent_io_controller: lea pciinfo140(PC),A0 // Intelligent IO Controller bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2318,9 +2997,13 @@ display_infos_class: bne .unknow_subclass_device lea pciinfo141(PC),A0 // (I20 Arch) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .satellite_communication: lea pciinfo150(PC),A0 // Satellite Communication bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2345,9 +3028,13 @@ display_infos_class: .satellite_data: lea pciinfo154(PC),A0 // (DATA) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .encrytion_decryption: lea pciinfo160(PC),A0 // Encrytion/Decryption bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2362,9 +3049,13 @@ display_infos_class: .crypt_entertainment: lea pciinfo162(PC),A0 // (Entertainment en/decrypt) bra .add_subclass +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .signal_processing: lea pciinfo170(PC),A0 // Signal Processing bsr display_string_single +#ifdef DISPLAY_SUBCLASS move.l D4,D1 swap D1 and.l #0xFF,D1 // subclass code @@ -2393,6 +3084,9 @@ display_infos_class: .add_subclass: bsr display_string_single bra.s .end_info_class +#else + bra.s .end_info_class +#endif /* DISPLAY_SUBCLASS */ .unknow_class_device: lea pciinfo999(PC),A0 // Device does not fit in any defined classes bsr display_string_single @@ -2407,94 +3101,134 @@ display_infos_class: _find_pci_device: - move.l 2(A0),D0 // ID - move.w 6(A0),D1 // index + move.l 2(A0),D0 // ID + move.w 6(A0),D1 // index find_pci_device: -#ifdef COLDFIRE - lea -24(SP),SP - movem.l D3-D6/A4-A5,(SP) -#else - movem.l D3-D6/A4-A5,-(SP) + +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug40(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif #endif - move.l D0,D3 // ID - move.w D1,D5 // index +#ifdef COLDFIRE + lea -28(SP),SP + movem.l D3-D7/A4-A5,(SP) +#else /* !COLDFIRE */ + movem.l D3-D7/A4-A5,-(SP) +#endif /* COLDFIRE */ + move.l D0,D3 // ID + move.w D1,D5 // index ext.l D5 + moveq #0,D4 // slot + moveq #0,D6 // function + moveq #0,D7 // bus #ifdef COLDFIRE + move.l #PCI_MAX_SLOT,-(SP) ext.l D0 cmp.l #-1,D0 #else move.w SR,-(SP) - or.w #0x700,SR // no interrupts + or.w #0x700,SR // no interrupts lea .no_pci_devices(PC),A0 - move.l 8,A5 // bus error + move.l 8,A5 // bus error move.l A0,8 - move.l SP,A4 // save ssp + move.l SP,A4 // save ssp + move.l #PCI_MAX_SLOT,-(SP) cmp.w #-1,D3 #endif - beq.s .query_all_cards - moveq #0,D4 // slot - moveq #0,D6 // function -.loop_find_pci_device: - moveq #PCIIDR,D1 // Device ID & Vendor ID - move.l D6,D0 // function - swap D0 - or.l D4,D0 // slot - bsr fast_read_config_longword - cmp.l D0,D3 // ID - bne.s .next_find_pci_device - tst.l D5 // index - beq .end_index_pci_device - subq.l #1,D5 - tst.l D4 - beq .next_slot_find_pci_device // do not look for multi-function devices at bridge + beq.s .loop_query_all_cards +.loop_find_pci_device: + moveq #PCIIDR,D1 // Device ID & Vendor ID + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D4,D0 // slot + bsr fast_read_config_longword + cmp.l D0,D3 // ID + bne.s .next_find_pci_device + tst.l D5 // index + beq .end_index_pci_device + subq.l #1,D5 + move.l D7,D0 // bus number + bne.s .not_bus0_find_pci_device // <> bus 0 + tst.l D4 // slot + beq .next_slot_find_pci_device // do not look for multi-function devices at bridge +.not_bus0_find_pci_device: + mulu #PCI_MAX_FUNCTION,D0 + swap D0 + add.l D4,D0 // device (slot) + moveq #PCICLSR,D1 // check for multi-function device + bsr fast_read_config_longword + btst #23,D0 + beq.s .next_slot_find_pci_device .next_find_pci_device: - addq.l #1,D6 // function - cmp.l #PCI_MAX_FUNCTION,D6 - bcs .loop_find_pci_device + addq.l #1,D6 // function + cmp.l #PCI_MAX_FUNCTION,D6 + bcs .loop_find_pci_device .next_slot_find_pci_device: - moveq #0,D6 - addq.l #1,D4 // handle - cmp.l #PCI_MAX_HANDLE,D4 + moveq #0,D6 + addq.l #1,D4 // device + cmp.l (SP),D4 + bcs .loop_find_pci_device + move.l #PCI_MAX_DEVICE,(SP) + moveq #0,D4 // device + addq.l #1,D7 // bus + cmp.l #PCI_MAX_BUS,D7 bcs .loop_find_pci_device bra.s .no_pci_devices -.query_all_cards: - moveq #0,D4 // slot - moveq #0,D6 // function .loop_query_all_cards: - moveq #PCIIDR,D1 - move.l D6,D0 // current function number - swap D0 - or.l D4,D0 // slot - bsr fast_read_config_longword // Device ID & Vendor ID + moveq #PCIIDR,D1 + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D4,D0 // slot + bsr fast_read_config_longword // Device ID & Vendor ID #ifdef COLDFIRE - moveq #0,D1 - move.w D0,D1 - cmp.l #PCI_NOBODYHOME,D1 // Vendor ID + moveq #0,D1 + move.w D0,D1 + cmp.l #PCI_NOBODYHOME,D1 // Vendor ID #else - cmp.w #PCI_NOBODYHOME,D0 // Vendor ID -#endif - beq.s .next_slot_query_all_cards - tst.l D5 // index - beq.s .end_index_pci_device - subq.l #1,D5 - tst.l D4 - beq .next_slot_query_all_cards // don't look for multi-function-devices at bridge - move.l D4,D0 // handle (slot) - moveq #PCICLSR,D1 // check for multi-function device - bsr fast_read_config_longword - btst #23,D0 - beq.s .next_slot_query_all_cards - addq.l #1,D6 - cmp.l #PCI_MAX_FUNCTION,D6 - bcs.s .loop_query_all_cards + cmp.w #PCI_NOBODYHOME,D0 // Vendor ID +#endif + beq.s .next_slot_query_all_cards + tst.l D5 // index + beq.s .end_index_pci_device + subq.l #1,D5 + move.l D7,D0 // bus number + bne.s .not_bus0_query_all_cards // <> bus 0 + tst.l D4 + beq .next_slot_query_all_cards // don't look for multi-function-devices at bridge +.not_bus0_query_all_cards: + mulu #PCI_MAX_FUNCTION,D0 + swap D0 + add.l D4,D0 // device (slot) + moveq #PCICLSR,D1 // check for multi-function device + bsr fast_read_config_longword + btst #23,D0 + beq.s .next_slot_query_all_cards + addq.l #1,D6 + cmp.l #PCI_MAX_FUNCTION,D6 + bcs.s .loop_query_all_cards .next_slot_query_all_cards: - moveq.l #0,D6 - addq.l #1,D4 // handle - cmp.l #PCI_MAX_HANDLE,D4 - bcs.s .loop_query_all_cards + moveq #0,D6 + addq.l #1,D4 // device + cmp.l (SP),D4 + bcs.s .loop_query_all_cards + move.l #PCI_MAX_DEVICE,(SP) + moveq #0,D4 // device + addq.l #1,D7 // bus + cmp.l #PCI_MAX_BUS,D7 + bcs .loop_query_all_cards .no_pci_devices: -#ifndef COLDFIRE +#ifdef COLDFIRE + addq.l #4,SP +#else move.l A5,8 // restore bus error move.l A4,SP // restore ssp move.w (SP)+,SR @@ -2502,21 +3236,25 @@ find_pci_device: moveq #PCI_DEVICE_NOT_FOUND,D0 bra.s .end_find_pci_device .end_index_pci_device: -#ifndef COLDFIRE +#ifdef COLDFIRE + addq.l #4,SP +#else move.l A5,8 // restore bus error move.l A4,SP // restore ssp move.w (SP)+,SR #endif - move.l D6,D0 + move.w D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // current function number swap D0 - or.l D4,D0 // handle + or.l D4,D0 // slot => handle .end_find_pci_device: #ifdef COLDFIRE - movem.l (SP),D3-D6/A4-A5 - lea 24(SP),SP -#else - movem.l (SP)+,D3-D6/A4-A5 -#endif + movem.l (SP),D3-D7/A4-A5 + lea 28(SP),SP +#else /* !COLDFIRE */ + movem.l (SP)+,D3-D7/A4-A5 +#endif /* COLDFIRE */ rts _find_pci_classcode: @@ -2526,138 +3264,245 @@ _find_pci_classcode: find_pci_classcode: +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug41(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif +#endif #ifdef COLDFIRE - lea -16(SP),SP - movem.l D3-D6,(SP) -#else - movem.l D3-D6,-(SP) + lea -20(SP),SP + movem.l D3-D7,(SP) +#else /* !COLDFIRE */ + movem.l D3-D7,-(SP) #endif /* COLDFIRE */ move.l D0,D4 // class moveq #0,D5 move.w D1,D5 // index moveq #0,D3 // slot moveq #0,D6 // function + moveq #0,D7 // bus + move.l #PCI_MAX_SLOT,-(SP) .loop_pci_classcode: - moveq #PCIIDR,D1 - move.l D6,D0 // current function number - swap D0 - or.l D4,D0 // slot - bsr fast_read_config_longword // Device ID & Vendor ID + moveq #PCIIDR,D1 + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D3,D0 // slot + bsr fast_read_config_longword // Device ID & Vendor ID #ifdef COLDFIRE - moveq #0,D1 - move.w D0,D1 - cmp.l #PCI_NOBODYHOME,D1 // Vendor ID + moveq #0,D1 + move.w D0,D1 + cmp.l #PCI_NOBODYHOME,D1 // Vendor ID #else - cmp.w #PCI_NOBODYHOME,D0 // Vendor ID -#endif - beq.s .next_pci_classcode - move.l D4,D0 - and.l #0x4000000,D0 // if 0 compare base class - bne.s .ignore_base_class - moveq #PCICCR+2,D1 // PCI Class Code Register - move.l D6,D0 - swap D0 - or.l D3,D0 // handle - bsr fast_read_config_byte - move.l D4,D1 // class - swap D1 + cmp.w #PCI_NOBODYHOME,D0 // Vendor ID +#endif + beq.s .next_pci_classcode + move.l D4,D0 + and.l #0x4000000,D0 // if 0 compare base class + bne.s .ignore_base_class + moveq #PCICCR+2,D1 // PCI Class Code Register + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D3,D0 // device + bsr fast_read_config_byte + move.l D4,D1 // class + swap D1 #ifdef COLDFIRE - extb.l D0 - extb.l D1 - cmp.l D1,D0 // base class code + extb.l D0 + extb.l D1 + cmp.l D1,D0 // base class code #else - cmp.b D1,D0 // base class code + cmp.b D1,D0 // base class code #endif - bne.s .next_pci_classcode + bne.s .next_pci_classcode .ignore_base_class: - move.l D4,D0 // class - and.l #0x2000000,D0 // if 0 compare subclass - bne.s .ignore_subclass - moveq #PCICCR+1,D1 // PCI Class Code Register - move.l D6,D0 - swap D0 - or.l D3,D0 // handle - bsr fast_read_config_byte - move.l D4,D1 // class - lsr.l #8,D1 + move.l D4,D0 // class + and.l #0x2000000,D0 // if 0 compare subclass + bne.s .ignore_subclass + moveq #PCICCR+1,D1 // PCI Class Code Register + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D3,D0 // device + bsr fast_read_config_byte + move.l D4,D1 // class + lsr.l #8,D1 #ifdef COLDFIRE - extb.l D0 - extb.l D1 - cmp.l D1,D0 // subclass code + extb.l D0 + extb.l D1 + cmp.l D1,D0 // subclass code #else - cmp.b D1,D0 // subclass code + cmp.b D1,D0 // subclass code #endif - bne.s .next_pci_classcode + bne.s .next_pci_classcode .ignore_subclass: - move.l D4,D0 - and.l #0x1000000,D0 // if 0 compare prog. if - bne.s .ignore_prog_if - moveq #PCICCR,D1 // PCI Class Code Register - move.l D6,D0 - swap D0 - or.l D3,D0 // handle - bsr fast_read_config_byte + move.l D4,D0 + and.l #0x1000000,D0 // if 0 compare prog. if + bne.s .ignore_prog_if + moveq #PCICCR,D1 // PCI Class Code Register + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D3,D0 // device + bsr fast_read_config_byte #ifdef COLDFIRE - moveq #0,D1 - move.b D4,D1 - cmp.l D1,D0 // prog. if + moveq #0,D1 + move.b D4,D1 + cmp.l D1,D0 // prog. if #else - cmp.b D4,D0 // prog. if + cmp.b D4,D0 // prog. if #endif - bne.s .next_pci_classcode + bne.s .next_pci_classcode .ignore_prog_if: - tst.l D5 // index - beq.s .end_index_classcode - subq.l #1,D5 + tst.l D5 // index + beq.s .end_index_classcode + subq.l #1,D5 .next_pci_classcode: - addq.l #1,D6 - cmp.l #PCI_MAX_FUNCTION,D6 - bcs .loop_pci_classcode - clr.l D6 - addq.l #1,D3 // handle - cmp.l #PCI_MAX_HANDLE,D3 + move.l D7,D0 // bus number + bne.s .not_bus0_find_pci_classcode + tst.l D3 + beq.s .next_slot_pci_classcode // don't look for multi-function-devices at bridge +.not_bus0_find_pci_classcode: + mulu #PCI_MAX_FUNCTION,D0 + swap D0 + add.l D3,D0 // device (slot) + moveq #PCICLSR,D1 // check for multi-function device + bsr fast_read_config_longword + btst #23,D0 + beq.s .next_slot_pci_classcode + addq.l #1,D6 + cmp.l #PCI_MAX_FUNCTION,D6 + bcs .loop_pci_classcode +.next_slot_pci_classcode: + moveq #0,D6 + addq.l #1,D3 // device + cmp.l (SP),D3 + bcs .loop_pci_classcode + moveq #0,D3 + move.l #PCI_MAX_DEVICE,(SP) + addq.l #1,D7 + cmp.l #PCI_MAX_BUS,D7 bcs .loop_pci_classcode moveq #PCI_DEVICE_NOT_FOUND,D0 bra.s .end_pci_classcode .end_index_classcode: - move.l D3,D0 + move.w D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // current function number + swap D0 + or.l D3,D0 // slot => handle .end_pci_classcode: + addq.l #4,SP #ifdef COLDFIRE - movem.l (SP),D3-D5 - lea 16(SP),SP -#else - movem.l (SP)+,D3-D5 + movem.l (SP),D3-D7 + lea 20(SP),SP +#else /* !COLDFIRE */ + movem.l (SP)+,D3-D7 #endif /* COLDFIRE */ rts _read_config_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register move.l 8(A0),A0 // pointer to space for read data read_config_byte: +#ifndef COLDFIRE +#ifdef DEBUG + move.l D3,-(SP) + move.l D0,D3 + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ccc + move.l D0,-(SP) + move.l A0,-(SP) + lea debug42(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.ccc: +#endif +#endif +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif move.l A0,A1 // address move.l D0,D2 - ext.l D0 // handle + tst.l D0 // handle bmi .bad_handle_read_config_byte beq .read_local_config_byte - cmp.l #PCI_MAX_HANDLE,D0 + ext.l D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_config_byte swap D2 ext.l D2 bmi .bad_handle_read_config_byte - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_config_byte move.l D3,-(SP) - moveq #2,D3 +#ifdef COLDFIRE + move.w SR,D3 + move.l D3,-(SP) + or.l #0x700,D3 // mask interrupts + move.w D3,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif + moveq #3,D3 and.l D1,D3 move.l D3,-(SP) + move.l D2,D3 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D3 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D3 + move.w D3,D2 + ext.l D2 // function + clr.w D3 // bus number (B23-B16) + tst.l D3 + beq.s .read_config_byte_type0 + asl.l #8,D2 // shift function number into place + or.l D2,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D3,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .read_config_byte_type +.read_config_byte_type0: asl.l #8,D2 // shift function number into place or.l D2,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.read_config_byte_type: moveq #0,D2 move.b (A0,D0.l),D2 moveq #11,D0 @@ -2667,36 +3512,60 @@ read_config_byte: #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif move.l 4(SP),D2 move.b (A0,D2.l),(A1) // address move.l (SP)+,D2 addq.l #4,SP - move.l (SP)+,D3 #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword moveq #PCICSR,D1 // PCI Command / Status Register bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - and.l #0x28000000,D0 // Master Target Abort + and.l #0x38000000,D0 // Master Target Abort beq.s .no_master_abort_byte moveq #-1,D0 move.b D0,(A1) .no_master_abort_byte: moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors + move.w (SP)+,SR +#endif /* COLDFIRE */ + move.l (SP)+,D3 +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D3 + bne.s .cccC + move.l D0,-(SP) + move.b (A1),D0 + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.cccC: +#endif #endif moveq #PCI_SUCCESSFUL,D0 - rts + bra.s .end_read_config_byte .read_local_config_byte: ext.l D1 cmp.l #LAST_LOCAL_REGISTER,D1 @@ -2704,44 +3573,123 @@ read_config_byte: bsr read_local_config_byte move.b D0,(A1) moveq #PCI_SUCCESSFUL,D0 - rts + bra.s .end_read_config_byte .bad_register_read_config_byte: moveq #PCI_BAD_REGISTER_NUMBER,D0 - rts + bra.s .end_read_config_byte .bad_handle_read_config_byte: moveq #PCI_BAD_HANDLE,D0 +.end_read_config_byte: +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D2 + move.l D2,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif +#ifndef COLDFIRE +#ifdef DEBUG + move.l (SP)+,D3 +#endif +#endif rts _read_config_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register move.l 8(A0),A0 // pointer to space for read data read_config_word: +#ifndef COLDFIRE +#ifdef DEBUG + move.l D3,-(SP) + move.l D0,D3 + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ddd + move.l D0,-(SP) + move.l A0,-(SP) + lea debug43(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.ddd: +#endif +#endif +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif move.l A0,A1 // address btst #0,D1 // PCI register bne .bad_register_read_config_word move.l D0,D2 - ext.l D0 // handle + tst.l D0 // handle bmi .bad_handle_read_config_word beq .read_local_config_word - cmp.l #PCI_MAX_HANDLE,D0 + ext.l D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_config_word swap D2 ext.l D2 bmi .bad_handle_read_config_word - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_config_word move.l D3,-(SP) +#ifdef COLDFIRE + move.w SR,D3 + move.l D3,-(SP) + or.l #0x700,D3 // mask interrupts + move.w D3,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif moveq #2,D3 and.l D1,D3 move.l D3,-(SP) + move.l D2,D3 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D3 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D3 + move.w D3,D2 + ext.l D2 // function + clr.w D3 // bus number (B23-B16) + tst.l D3 + beq.s .read_config_word_type0 + asl.l #8,D2 // shift function number into place + or.l D2,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D3,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .read_config_word_type +.read_config_word_type0: asl.l #8,D2 // shift function number into place or.l D2,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.read_config_word_type: moveq #0,D2 move.b (A0,D0.l),D2 moveq #11,D0 @@ -2751,12 +3699,17 @@ read_config_word: #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif move.l 4(SP),D2 //#ifdef BIG_ENDIAN // move.w (A0,D2.l),(A1) @@ -2775,26 +3728,45 @@ read_config_word: //#endif move.l (SP)+,D2 addq.l #4,SP - move.l (SP)+,D3 #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword moveq #PCICSR,D1 // PCI Command / Status Register bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - and.l #0x28000000,D0 // Master Target Abort + and.l #0x38000000,D0 // Master Target Abort beq.s .no_master_abort_word moveq #-1,D0 move.w D0,(A1) .no_master_abort_word: moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors + move.w (SP)+,SR +#endif /* COLDFIRE */ + move.l (SP)+,D3 +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D3 + bne.s .dddD + move.l D0,-(SP) + move.w (A1),D0 + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.dddD: +#endif #endif moveq #PCI_SUCCESSFUL,D0 - rts + bra.s .end_read_config_word .read_local_config_word: ext.l D1 cmp.l #LAST_LOCAL_REGISTER,D1 @@ -2802,68 +3774,163 @@ read_config_word: bsr read_local_config_word move.w D0,(A1) moveq #PCI_SUCCESSFUL,D0 - rts + bra.s .end_read_config_word .bad_register_read_config_word: moveq #PCI_BAD_REGISTER_NUMBER,D0 - rts + bra.s .end_read_config_word .bad_handle_read_config_word: moveq #PCI_BAD_HANDLE,D0 +.end_read_config_word: +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D2 + move.l D2,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif +#ifndef COLDFIRE +#ifdef DEBUG + move.l (SP)+,D3 +#endif +#endif rts _read_config_longword: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register move.l 8(A0),A0 // pointer to space for read data read_config_longword: +#ifndef COLDFIRE +#ifdef DEBUG + move.l D3,-(SP) + move.l D0,D3 + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .eee + move.l D0,-(SP) + move.l A0,-(SP) + lea debug44(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.eee: +#endif +#endif +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif move.l A0,A1 // address moveq #3,D2 and.l D1,D2 // PCI register bne .bad_register_read_config_longword move.l D0,D2 - ext.l D0 // handle + tst.l D0 // handle bmi .bad_handle_read_config_longword beq .read_local_config_longword - cmp.l #PCI_MAX_HANDLE,D0 + ext.l D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_config_longword swap D2 ext.l D2 bmi .bad_handle_read_config_longword - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_config_longword +#ifdef COLDFIRE /* device errata 4 */ + swap D0 // handle + move.w D2,D0 // function + swap D0 + move.l A1,-(SP) // pointer + move.l D0,-(SP) + move.l D1,-(SP) + bsr fast_read_config_word// lower 16 bits + move.w D0,D2 + move.l (SP)+,D1 + addq.l #2,D1 + move.l (SP)+,D0 + move.l (SP),A1 + move.l D2,-(SP) + bsr fast_read_config_word// upper 16 bits + move.l (SP)+,D2 + swap D0 + move.w D2,D0 + move.l (SP)+,A1 // pointe + move.l D0,(A1) +#else /* !COLDFIRE errata */ + move.l D3,-(SP) + move.l D2,D3 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D3 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D3 + move.w D3,D2 + ext.l D2 // function + clr.w D3 // bus number (B23-B16) + tst.l D3 + beq.s .read_config_longword_type0 + asl.l #8,D2 // shift function number into place + or.l D2,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D3,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .read_config_longword_type +.read_config_longword_type0: asl.l #8,D2 // shift function number into place or.l D2,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.read_config_longword_type: + move.l (SP)+,D3 moveq #0,D2 move.b (A0,D0.l),D2 moveq #11,D0 asl.l D0,D2 // Device Number or.l D1,D2 +#ifdef COLDFIRE + move.w SR,D1 + move.l D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif move.l D2,-(SP) #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#if 0 // #ifdef DEBUG - lea debug36(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_long - moveq #0x20,D0 - bsr debug_display_char - moveq #0x30,D0 - bsr debug_display_char - moveq #0x78,D0 - bsr debug_display_char -#endif -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif //#ifdef BIG_ENDIAN // move.l (A0),(A1) //#else @@ -2885,34 +3952,52 @@ read_config_longword: //#endif move.l (SP)+,D2 #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#if 0 // #ifdef DEBUG - move.l D0,-(SP) - move.l (A1),D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif -#else +#if 0 /* another solution for device errata 4 */ + or.l #MCF_PCI_PCICAR_E+0x00FF0000,D2 // enable config space acces with bad bus number + move.l D2,MCF_PCI_PCICAR + tst.l (A0) + and.l #~MCF_PCI_PCICAR_E,D2 // disable config space access with bad bus number + nop + move.l D2,MCF_PCI_PCICAR +#endif + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword moveq #PCICSR,D1 // PCI Command / Status Register bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - and.l #0x28000000,D0 // Master Target Abort + and.l #0x38000000,D0 // Master Target Abort beq.s .no_master_abort_longword moveq #-1,D0 move.l D0,(A1) .no_master_abort_longword: moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors + move.w (SP)+,SR +#endif /* COLDFIRE */ +#endif /* COLDFIRE errata */ +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D3 + bne.s .eeeE + move.l D0,-(SP) + move.l (A1),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.eeeE: +#endif #endif moveq #PCI_SUCCESSFUL,D0 - rts + bra.s .end_read_config_longword .read_local_config_longword: ext.l D1 cmp.l #LAST_LOCAL_REGISTER,D1 @@ -2920,33 +4005,111 @@ read_config_longword: bsr read_local_config_longword move.l D0,(A1) moveq #PCI_SUCCESSFUL,D0 - rts + bra.s .end_read_config_longword .bad_register_read_config_longword: moveq #PCI_BAD_REGISTER_NUMBER,D0 - rts + bra.s .end_read_config_longword .bad_handle_read_config_longword: moveq #PCI_BAD_HANDLE,D0 +.end_read_config_longword: +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D2 + move.l D2,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif +#ifndef COLDFIRE +#ifdef DEBUG + move.l (SP)+,D3 +#endif +#endif rts _fast_read_config_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register fast_read_config_byte: - tst.w D0 // check slot number + tst.l D0 // handle beq read_local_config_byte +#ifndef COLDFIRE +#ifdef DEBUG + move.l D0,-(SP) + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .fff + move.l D0,-(SP) + move.l A0,-(SP) + lea debug45(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.fff: +#endif +#endif +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif + move.w SR,D2 + move.l D2,-(SP) + or.l #0x700,D2 // mask interrupts + move.w D2,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif /* COLDFIRE */ moveq #3,D2 and.l D1,D2 move.l D2,-(SP) - move.l D0,D2 // function(H)/handle(L) + move.l D0,D2 // bus/function(H)/slot(L) ext.l D0 swap D2 + move.l D3,-(SP) + ext.l D2 + move.l D2,D3 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D3 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D3 + move.w D3,D2 + ext.l D2 // function + clr.w D3 // bus number (B23-B16) + tst.l D3 + beq.s .fast_read_config_byte_type0 + asl.l #8,D2 // shift function number into place + or.l D2,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D3,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .fast_read_config_byte_type +.fast_read_config_byte_type0: asl.l #8,D2 // shift function number into place or.l D2,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.fast_read_config_byte_type: + move.l (SP)+,D3 moveq #0,D2 move.b (A0,D0.l),D2 moveq #11,D0 @@ -2956,20 +4119,28 @@ fast_read_config_byte: #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif moveq #0,D0 move.l 4(SP),D2 move.b (A0,D2.l),D0 move.l (SP)+,D2 addq.l #4,SP #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l D0,-(SP) move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword @@ -2977,7 +4148,7 @@ fast_read_config_byte: bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - and.l #0x28000000,D0 // Master Target Abort + and.l #0x38000000,D0 // Master Target Abort beq.s .fast_no_master_abort_byte moveq #-1,D0 move.l D0,(SP) @@ -2985,28 +4156,116 @@ fast_read_config_byte: moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors move.l (SP)+,D0 + move.w (SP)+,SR +#endif /* COLDFIRE */ +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D2 + move.l D2,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif +#ifndef COLDFIRE +#ifdef DEBUG + move.l (SP)+,D2 + cmp.l #SLOT_TO_DEBUG,D2 + bne.s .fffF + move.l D0,-(SP) + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.fffF: +#endif #endif rts _fast_read_config_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register fast_read_config_word: - tst.w D0 // check slot number + tst.l D0 // handle beq read_local_config_word +#ifndef COLDFIRE +#ifdef DEBUG + move.l D0,-(SP) + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ggg + move.l D0,-(SP) + move.l A0,-(SP) + lea debug46(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.ggg: +#endif +#endif +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif + move.w SR,D2 + move.l D2,-(SP) + or.l #0x700,D2 // mask interrupts + move.w D2,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif /* COLDFIRE */ moveq #2,D2 and.l D1,D2 move.l D2,-(SP) - move.l D0,D2 // function(H)/handle(L) + move.l D0,D2 // bus/function(H)/slot(L) ext.l D0 swap D2 + move.l D3,-(SP) + ext.l D2 + move.l D2,D3 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D3 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D3 + move.w D3,D2 + ext.l D2 // function + clr.w D3 // bus number (B23-B16) + tst.l D3 + beq.s .fast_read_config_word_type0 + asl.l #8,D2 // shift function number into place + or.l D2,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D3,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .fast_read_config_word_type +.fast_read_config_word_type0: asl.l #8,D2 // shift function number into place or.l D2,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.fast_read_config_word_type: + move.l (SP)+,D3 moveq #0,D2 move.b (A0,D0.l),D2 moveq #11,D0 @@ -3016,12 +4275,17 @@ fast_read_config_word: #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif moveq #0,D0 move.l 4(SP),D2 move.w (A0,D2.l),D0 @@ -3039,8 +4303,11 @@ fast_read_config_word: move.l (SP)+,D2 addq.l #4,SP #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l D0,-(SP) move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword @@ -3048,7 +4315,7 @@ fast_read_config_word: bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - and.l #0x28000000,D0 // Master Target Abort + and.l #0x38000000,D0 // Master Target Abort beq.s .fast_no_master_abort_word moveq #-1,D0 move.l D0,(SP) @@ -3056,52 +4323,149 @@ fast_read_config_word: moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors move.l (SP)+,D0 + move.w (SP)+,SR +#endif /* COLDFIRE */ +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D2 + move.l D2,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR #endif - rts - -_fast_read_config_longword: - - move.l 2(A0),D0 // function(H)/handle(L) - move.w 6(A0),D1 // PCI register - -fast_read_config_longword: - - move.l D0,D2 - ext.l D0 // check slot number - beq read_local_config_longword - swap D2 +#endif +#ifndef COLDFIRE +#ifdef DEBUG + move.l (SP)+,D2 + cmp.l #SLOT_TO_DEBUG,D2 + bne.s .gggG + move.l D0,-(SP) + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.gggG: +#endif +#endif + rts + +_fast_read_config_longword: + + move.l 2(A0),D0 // bus/function(H)/slot(L) + move.w 6(A0),D1 // PCI register + +fast_read_config_longword: + + tst.l D0 // handle + beq read_local_config_longword +#ifndef COLDFIRE +#ifdef DEBUG + move.l D0,-(SP) + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .hhh + move.l D0,-(SP) + move.l A0,-(SP) + lea debug47(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.hhh: +#endif +#endif +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D2 + and.l D2,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif +#ifdef COLDFIRE /* device errata 4 */ + move.l D0,-(SP) // bus/function(H)/slot(L) + move.l D1,-(SP) + bsr fast_read_config_word// lower 16 bits + move.w D0,D2 + move.l (SP)+,D1 + addq.l #2,D1 + move.l (SP)+,D0 // bus/function(H)/slot(L) + move.l D2,-(SP) + bsr fast_read_config_word// upper 16 bits + move.l (SP)+,D2 + swap D0 + move.w D2,D0 +#else /* !COLDFIRE errata */ + move.l D0,D2 // bus/function(H)/slot(L) + ext.l D0 + swap D2 + move.l D3,-(SP) + ext.l D2 + move.l D2,D3 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D3 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D3 + move.w D3,D2 + ext.l D2 // function + clr.w D3 // bus number (B23-B16) + tst.l D3 + beq.s .fast_read_config_longword_type0 + asl.l #8,D2 // shift function number into place + or.l D2,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D3,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .fast_read_config_longword_type +.fast_read_config_longword_type0: asl.l #8,D2 // shift function number into place or.l D2,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.fast_read_config_longword_type: + move.l (SP)+,D3 moveq #0,D2 move.b (A0,D0.l),D2 moveq #11,D0 asl.l D0,D2 // Device Number or.l D1,D2 - move.l D2,-(SP) -#if 0 // #ifdef DEBUG - lea debug36(PC),A0 - bsr debug_display_string - move.l D2,D0 - bset #31,D0 - bsr debug_hex_long - moveq #0x20,D0 // " " - bsr debug_display_char - moveq #0x30,D0 // "0" - bsr debug_display_char - moveq #0x78,D0 // "x" - bsr debug_display_char +#ifdef COLDFIRE + move.w SR,D1 + move.l D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts #endif + move.l D2,-(SP) #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 // enable config space access move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword #endif /* COLDFIRE */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif move.l (A0),D0 //#ifndef BIG_ENDIAN #ifdef COLDFIRE @@ -3120,8 +4484,19 @@ fast_read_config_longword: //#endif move.l (SP)+,D2 #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else +#if 0 /* another solution for device errata 4 */ + or.l #MCF_PCI_PCICAR_E+0x00FF0000,D2 // enable config space acces with bad bus number + move.l D2,MCF_PCI_PCICAR + tst.l (A0) + and.l #~MCF_PCI_PCICAR_E,D2 // disable config space access with bad bus number + nop + move.l D2,MCF_PCI_PCICAR +#endif + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l D0,-(SP) move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword @@ -3129,7 +4504,7 @@ fast_read_config_longword: bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - and.l #0x28000000,D0 // Master Target Abort + and.l #0x38000000,D0 // Master Target Abort beq.s .fast_no_master_abort_longword moveq #-1,D0 move.l D0,(SP) @@ -3137,8 +4512,21 @@ fast_read_config_longword: moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors move.l (SP)+,D0 + move.w (SP)+,SR #endif /* COLDFIRE */ -#if 0 // #ifdef DEBUG +#endif /* COLDFIRE errata */ +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D2 + move.l D2,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif +#ifndef COLDFIRE +#ifdef DEBUG + move.l (SP)+,D2 + cmp.l #SLOT_TO_DEBUG,D2 + bne.s .hhhH move.l D0,-(SP) bsr debug_hex_long moveq #13,D0 @@ -3146,37 +4534,112 @@ fast_read_config_longword: moveq #10,D0 bsr debug_display_char move.l (SP)+,D0 +.hhhH: +#endif #endif rts _write_config_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register move.w 8(A0),D2 // data to write write_config_byte: +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .zzz + move.l A0,-(SP) + move.l D0,-(SP) + lea debug48(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.zzz: +#endif +#endif move.l D3,-(SP) move.l D4,-(SP) +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D3 + and.l D3,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif move.l D0,D3 // handle - ext.l D0 + tst.l D0 bmi .bad_handle_write_config_byte +#ifdef COLDFIRE + bne.s .write_config_byte_not_bridge + cmp.l #0x60,D1 // MCF need a PCI config cycle for reset bit in SR + bcc .write_local_config_byte +.write_config_byte_not_bridge: +#else beq .write_local_config_byte - cmp.l #PCI_MAX_HANDLE,D0 +#endif + ext.l D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_config_byte swap D3 ext.l D3 // function bmi .bad_handle_write_config_byte - cmp.l #PCI_MAX_FUNCTION,D3 - bcc.s .bad_handle_write_config_byte + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D3 + bcc .bad_handle_write_config_byte +#ifdef COLDFIRE + move.w SR,D4 + move.l D4,-(SP) + or.l #0x700,D4 // mask interrupts + move.w D4,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif moveq #3,D4 and.l D1,D4 move.l D4,-(SP) + move.l D3,D4 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D4 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D4 + move.w D4,D3 + ext.l D3 // function + clr.w D4 // bus number (B23-B16) + tst.l D4 + beq.s .write_config_byte_type0 + asl.l #8,D3 // shift function number into place + or.l D3,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D4,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .write_config_byte_type +.write_config_byte_type0: asl.l #8,D3 // shift function number into place or.l D3,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.write_config_byte_type: moveq #0,D3 move.b (A0,D0.l),D3 moveq #11,D0 @@ -3188,20 +4651,31 @@ write_config_byte: #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ move.l (SP)+,D2 +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif move.l 4(SP),D1 move.b D2,(A0,D1.l) +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 +#endif move.l (SP)+,D2 addq.l #4,SP #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword moveq #PCICSR,D1 // PCI Command / Status Register @@ -3210,7 +4684,8 @@ write_config_byte: move.l D0,D2 moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors -#endif + move.w (SP)+,SR +#endif /* COLDFIRE */ moveq #PCI_SUCCESSFUL,D0 bra.s .end_write_config_byte .write_local_config_byte: @@ -3225,39 +4700,120 @@ write_config_byte: .bad_handle_write_config_byte: moveq #PCI_BAD_HANDLE,D0 .end_write_config_byte: +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D3 + move.l D3,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif move.l (SP)+,D4 move.l (SP)+,D3 rts _write_config_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register move.w 8(A0),D2 // data to write write_config_word: + +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .zzzz + move.l A0,-(SP) + move.l D0,-(SP) + lea debug49(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.zzzz: +#endif +#endif move.l D3,-(SP) move.l D4,-(SP) +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D3 + and.l D3,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif btst #0,D1 // PCI register bne .bad_register_write_config_word move.l D0,D3 - ext.l D0 // handle + tst.l D0 // handle bmi .bad_handle_write_config_word +#ifdef COLDFIRE + bne.s .write_config_word_not_bridge + cmp.l #0x60,D1 // MCF need a PCI config cycle for reset bit in SR + bcc .write_local_config_word +.write_config_word_not_bridge: +#else beq .write_local_config_word - cmp.l #PCI_MAX_HANDLE,D0 +#endif + ext.l D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_config_word swap D3 ext.l D3 // function bmi .bad_handle_write_config_word - cmp.l #PCI_MAX_FUNCTION,D3 - bcc.s .bad_handle_write_config_word + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D3 + bcc .bad_handle_write_config_word +#ifdef COLDFIRE + move.w SR,D4 + move.l D4,-(SP) + or.l #0x700,D4 // mask interrupts + move.w D4,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif moveq #2,D4 and.l D1,D4 move.l D4,-(SP) + move.l D3,D4 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D4 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D4 + move.w D4,D3 + ext.l D3 // function + clr.w D4 // bus number (B23-B16) + tst.l D4 + beq.s .write_config_word_type0 + asl.l #8,D3 // shift function number into place + or.l D3,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D4,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .write_config_word_type +.write_config_word_type0: asl.l #8,D3 // shift function number into place or.l D3,D1 and.l #0x7FC,D1 // function/reg lea tab_pci_device(PC),A0 +.write_config_word_type: moveq #0,D3 move.b (A0,D0.l),D3 moveq #11,D0 @@ -3269,13 +4825,18 @@ write_config_word: #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ move.l (SP)+,D2 +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif //#ifndef BIG_ENDIAN #ifdef COLDFIRE moveq #0,D1 @@ -3289,20 +4850,27 @@ write_config_word: //#endif move.l 4(SP),D1 move.w D2,(A0,D1.l) +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 +#endif move.l (SP)+,D2 addq.l #4,SP #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword - moveq #PCICSR,D1 // PCI Command / Status Register + moveq #PCICSR,D1 // PCI Command / Status Register bsr read_local_config_longword bclr #31,D0 move.l D0,D2 - moveq #PCICSR,D1 // PCI Command / Status Register + moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors -#endif + move.w (SP)+,SR +#endif /* COLDFIRE */ moveq #PCI_SUCCESSFUL,D0 bra.s .end_write_config_word .write_local_config_word: @@ -3317,54 +4885,142 @@ write_config_word: .bad_handle_write_config_word: moveq #PCI_BAD_HANDLE,D0 .end_write_config_word: +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D3 + move.l D3,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif move.l (SP)+,D4 move.l (SP)+,D3 rts _write_config_longword: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // PCI register move.l 8(A0),D2 // data to write write_config_longword: + +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .zzzzz + move.l A0,-(SP) + move.l D0,-(SP) + lea debug50(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.zzzzz: +#endif +#endif move.l D3,-(SP) +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIICR,-(SP) + move.l #~(MCF_PCI_PCIICR_TAE + MCF_PCI_PCIICR_IAE + MCF_PCI_PCIICR_REE),D3 + and.l D3,MCF_PCI_PCIICR // disable PCI XLB interrupts +#endif +#endif moveq #3,D3 and.l D1,D3 // PCI register bne .bad_register_write_config_longword move.l D0,D3 - ext.l D0 // handle + tst.l D0 // handle bmi .bad_handle_write_config_longword +#ifdef COLDFIRE + bne.s .write_config_longword_not_bridge + cmp.l #0x60,D1 // MCF need a PCI config cycle for reset bit in SR + bcc .write_local_config_longword +.write_config_longword_not_bridge: +#else beq .write_local_config_longword - cmp.l #PCI_MAX_HANDLE,D0 +#endif + ext.l D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_config_longword swap D3 ext.l D3 // function bmi .bad_handle_write_config_longword - cmp.l #PCI_MAX_FUNCTION,D3 - bcc.s .bad_handle_write_config_longword - asl.l #8,D3 // shift function number in place - or.l D3,D1 - and.l #0x7FC,D1 // function/reg - lea tab_pci_device(PC),A0 - moveq #0,D3 - move.b (A0,D0.l),D3 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D3 + bcc .bad_handle_write_config_longword + move.l D4,-(SP) + move.l D3,D4 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D4 +#ifdef COLDFIRE + .chip 5200 +#endif + swap D4 + move.w D4,D3 + ext.l D3 // function + clr.w D4 // bus number (B23-B16) + tst.l D4 + beq.s .write_config_longword_type0 + asl.l #8,D3 // shift function number into place + or.l D3,D1 + and.l #0x7FC,D1 // function (B10-B8) / reg (B7-B2) + bset #0,D1 // type 1 (B0) + or.l D4,D1 // bus number + lea tab_pci_device2(PC),A0 + bra.s .write_config_longword_type +.write_config_longword_type0: + asl.l #8,D3 // shift function number in place + or.l D3,D1 + and.l #0x7FC,D1 // function/reg + lea tab_pci_device(PC),A0 +.write_config_longword_type: + move.l (SP)+,D4 + moveq #0,D3 + move.b (A0,D0.l),D3 moveq #11,D0 asl.l D0,D3 // Device Number or.l D3,D1 +#ifdef COLDFIRE + move.w SR,D3 + move.l D3,-(SP) + or.l #0x700,D3 // mask interrupts + move.w D3,SR +#else + move.w SR,-(SP) + or.w #0x700,SR // no interrupts +#endif move.l D1,-(SP) move.l D2,-(SP) move.l D1,D2 #ifdef COLDFIRE or.l #MCF_PCI_PCICAR_E,D2 move.l D2,MCF_PCI_PCICAR -#else +#else /* !COLDFIRE */ bset #31,D2 // Configuration Enable move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword -#endif +#endif /* COLDFIRE */ move.l (SP)+,D2 +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif //#ifndef BIG_ENDIAN #ifdef COLDFIRE move.l D2,D0 @@ -3381,10 +5037,16 @@ write_config_longword: #endif /* COLDFIRE */ //#endif move.l D2,(A0) +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 +#endif move.l (SP)+,D2 #ifdef COLDFIRE + nop move.l D2,MCF_PCI_PCICAR -#else + move.l (SP)+,D1 + move.w D1,SR +#else /* !COLDFIRE */ move.l #DMCFGA,D1 // PCI Configuration Address Register for PCI Initiator-to-PCI I/O Config bsr write_local_config_longword moveq #PCICSR,D1 // PCI Command / Status Register @@ -3393,7 +5055,8 @@ write_config_longword: move.l D0,D2 moveq #PCICSR,D1 // PCI Command / Status Register bsr write_local_config_longword // clear errors -#endif + move.w (SP)+,SR +#endif /* COLDFIRE */ moveq #PCI_SUCCESSFUL,D0 bra.s .end_write_config_longword .write_local_config_longword: @@ -3408,37 +5071,75 @@ write_config_longword: .bad_handle_write_config_longword: moveq #PCI_BAD_HANDLE,D0 .end_write_config_longword: +#ifdef COLDFIRE +#ifndef MCF5445X + move.l MCF_PCI_PCIISR,D3 + move.l D3,MCF_PCI_PCIISR // clear interrupt + move.l (SP)+,MCF_PCI_PCIICR +#endif +#endif move.l (SP)+,D3 rts _hook_interrupt: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 10(A0),A1 // parameter for interrupt handler move.l 6(A0),A0 // pointer to interrupt handler hook_interrupt: + +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .iii + move.l A0,-(SP) + move.l D0,-(SP) + lea debug51(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.iii: +#endif +#endif move.l A2,-(SP) - move.l D0,D1 // handle - move.l D0,D2 - swap D2 // function + move.l D0,-(SP) // handle + move.l D0,D1 + swap D1 // bus/function ext.l D0 bmi.s .bad_handle_hook_interrupt - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_hook_interrupt - ext.l D2 // function + ext.l D1 // function bmi.s .bad_handle_hook_interrupt - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D1 bcc.s .bad_handle_hook_interrupt move.l #0x5F504349,D0 // _PCI bsr get_cookie beq .general_error_hook_interrupt // not found add.l #PCI_COOKIE_SIZE + PCI_RSC_HANDLESTOTALSIZE,D0 move.l D0,A2 // Status-Descriptors - move.w D1,D0 // handle - ext.l D0 - mulu #PCI_MAX_FUNCTION,D1 - add.l D2,D1 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D1 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D1,D2 + swap D1 + ext.l D1 // function + ext.l D2 // bus number + move.l (SP),D0 // handle + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,D1 + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D2 + add.l D2,D1 mulu #PCI_DEV_DES_SIZE,D1 tst.l PCI_DEV_DES_HANDLER(A2,D1.l) bne.s .general_error_hook_interrupt @@ -3453,7 +5154,8 @@ hook_interrupt: moveq #PCI_SUCCESSFUL,D0 bra.s .end_hook_interrupt .enable_hook_interrupt: - bsr enable_interrupt // handle + move.l (SP),D0 // handle + bsr enable_interrupt moveq #PCI_SUCCESSFUL,D0 bra.s .end_hook_interrupt .general_error_hook_interrupt: @@ -3462,43 +5164,73 @@ hook_interrupt: .bad_handle_hook_interrupt: moveq #PCI_BAD_HANDLE,D0 .end_hook_interrupt: + addq.l #4,SP move.l (SP)+,A2 rts _unhook_interrupt: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) unhook_interrupt: - move.w D0,D1 // handle - move.l D0,D2 - swap D2 // function +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .jjj + move.l A0,-(SP) + lea debug52(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.jjj: +#endif +#endif + move.l D0,-(SP) // handle + move.l D0,D1 + swap D1 // function ext.l D0 bmi.s .bad_handle_unhook_interrupt - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_unhook_interrupt - ext.l D2 // function + ext.l D1 // function bmi.s .bad_handle_unhook_interrupt - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D1 bcc.s .bad_handle_unhook_interrupt + move.l (SP),D0 // handle bsr disable_interrupt move.l #0x5F504349,D0 // _PCI bsr get_cookie beq .general_error_unhook_interrupt // not found add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE,D0 move.l D0,A1 // Status-Descriptors - mulu #PCI_MAX_FUNCTION,D1 - add.l D2,D1 +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D1 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D1,D2 + swap D1 + ext.l D1 // function + ext.l D2 // bus number + move.l (SP),D0 // handle + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,D1 + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D2 + add.l D2,D1 mulu #PCI_DEV_DES_SIZE,D1 clr.l PCI_DEV_DES_HANDLER(A1,D1.l) clr.l PCI_DEV_DES_PARAMETER(A1,D1.l) + addq.l #4,SP moveq #PCI_SUCCESSFUL,D0 rts .general_error_unhook_interrupt: + addq.l #4,SP moveq #PCI_GENERAL_ERROR,D0 - bra.s .end_hook_interrupt + rts .bad_handle_unhook_interrupt: + addq.l #4,SP moveq #PCI_BAD_HANDLE,D0 rts @@ -3509,18 +5241,37 @@ _special_cycle: special_cycle: +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug53(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif +#endif moveq #PCI_FUNC_NOT_SUPPORTED,D0 rts _get_routing: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) get_routing: +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .lll + move.l A0,-(SP) + lea debug54(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.lll: +#endif +#endif ext.l D0 // handle bmi.s .bad_handle_set_routing - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_set_routing moveq #PCI_FUNC_NOT_SUPPORTED,D0 rts @@ -3530,16 +5281,28 @@ get_routing: _set_interrupt: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.w 6(A0),D1 // mode set_interrupt: + +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .mmm + move.l A0,-(SP) + lea debug55(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.mmm: +#endif +#endif ext.l D0 // handle bmi.s .bad_handle_set_interrupt #ifndef COLDFIRE beq.s .local_set_interrupt #endif - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_set_interrupt moveq #PCI_FUNC_NOT_SUPPORTED,D0 rts @@ -3567,28 +5330,87 @@ set_interrupt: _get_resource: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) get_resource: +#ifndef COLDFIRE +#ifdef DEBUG + move.l D0,D2 + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .nnn + move.l D0,-(SP) + move.l A0,-(SP) + lea debug56(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + moveq #0x3D,D0 + bsr debug_display_char + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.nnn: +#endif +#endif move.l D0,D1 // slot swap D1 // function ext.l D0 - bmi.s .bad_handle_get_resource - cmp.l #PCI_MAX_HANDLE,D0 + bmi .bad_handle_get_resource + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_get_resource ext.l D1 // function bmi.s .bad_handle_get_resource - cmp.l #PCI_MAX_FUNCTION,D1 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D1 bcc.s .bad_handle_get_resource +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D1 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D1,D2 + swap D1 + ext.l D1 // function + ext.l D2 // bus number mulu #PCI_MAX_FUNCTION,D0 add.l D0,D1 + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D2 + add.l D2,D1 move.l #0x5F504349,D0 // _PCI bsr get_cookie beq .general_error_get_resource // not found mulu #PCI_RSC_DESC_TOTALSIZE,D1 add.l #PCI_COOKIE_SIZE,D0 // Ressource-Descriptors add.l D1,D0 +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D2 + bne.s .nn + move.l D0,-(SP) + move.l D0,A0 + move.l (A0)+,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + moveq #3,D2 +.nnnn: + move.l (A0)+,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + dbf D2,.nnnn + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.nn: +#endif +#endif rts .general_error_get_resource: moveq #PCI_GENERAL_ERROR,D0 @@ -3599,23 +5421,52 @@ get_resource: _get_card_used: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),A0 // address get_card_used: +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ooo + move.l D0,-(SP) + move.l A0,-(SP) + lea debug57(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l (SP)+,A0 + move.l (SP)+,D0 +.ooo: +#endif +#endif move.l D0,D1 // handle swap D1 // function ext.l D0 bmi.s .bad_handle_get_card_used - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_get_card_used ext.l D1 bmi.s .bad_handle_get_card_used - cmp.l #PCI_MAX_FUNCTION,D1 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D1 bcc.s .bad_handle_get_card_used +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D1 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D1,D2 + swap D1 + ext.l D1 // function + ext.l D2 // bus number mulu #PCI_MAX_FUNCTION,D0 add.l D0,D1 + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D2 + add.l D2,D1 move.l #0x5F504349,D0 // _PCI bsr get_cookie beq .general_error_get_card_used // not found @@ -3634,23 +5485,47 @@ get_card_used: _set_card_used: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),A0 // callback set_card_used: +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ppp + move.l A0,-(SP) + lea debug58(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.ppp: +#endif +#endif move.l D0,D1 // handle swap D1 // function ext.l D0 bmi.s .bad_handle_set_card_used - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_set_card_used ext.l D1 bmi.s .bad_handle_set_card_used - cmp.l #PCI_MAX_FUNCTION,D1 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D1 bcc.s .bad_handle_set_card_used +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D1 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D1,D2 + swap D1 + ext.l D1 // function + ext.l D2 // bus number mulu #PCI_MAX_FUNCTION,D0 add.l D0,D1 + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D2 + add.l D2,D1 move.l #0x5F504349,D0 // _PCI bsr get_cookie beq .general_error_set_card_used // not found @@ -3683,31 +5558,44 @@ set_card_used: _read_mem_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.l 10(A0),A0 // pointer to data in memory read_mem_byte: #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A2,-(SP) - move.l D0,A2 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .qqq + move.l A0,-(SP) + lea debug59(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.qqq: #endif #endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi .bad_handle_read_mem_byte - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_mem_byte ext.l D2 bmi .bad_handle_read_mem_byte - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_mem_byte +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A1 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_memory_offset(A1),A1 +#else lea PCI_MEMORY_OFFSET,A1 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.b (A1,D1.l),(A0) // pointer to data in memory #else @@ -3716,60 +5604,6 @@ read_mem_byte: eor.l D2,D1 // offset #endif move.b (A1,D1.l),(A0) // pointer to data in memory -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.read_mem_byte_retry: - move.b (A0),D0 - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .read_mem_byte_ok2 - lea debug35(PC),A0 - bra.s .read_mem_byte_display -.read_mem_byte_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_read_mem_byte - lea debug39(PC),A0 - bra.s .read_mem_byte_display2 -.no_master_abort_read_mem_byte: - move.l A2,D0 - bsr check_parity_target - bpl.s .read_mem_byte_ok - lea debug37(PC),A0 -.read_mem_byte_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.read_mem_byte_display2: - bsr debug_display_string - move.l A1,D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .read_mem_byte_bad - move.l (SP)+,A0 - move.l (SP)+,D0 - move.b (A1,D1.l),(A0) - bra.s .read_mem_byte_retry -.read_mem_byte_bad: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 - moveq #PCI_PARITY_ERROR,D0 - rts -.read_mem_byte_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -3779,33 +5613,46 @@ read_mem_byte: _read_mem_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.l 10(A0),A0 // pointer to data in memory read_mem_word: #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A2,-(SP) - move.l D0,A2 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .rrr + move.l A0,-(SP) + lea debug60(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.rrr: #endif #endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi .bad_handle_read_mem_word - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_mem_word ext.l D2 bmi .bad_handle_read_mem_word - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_mem_word btst #0,D1 bne .bad_alignment_read_mem_word +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A1 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_memory_offset(A1),A1 +#else lea PCI_MEMORY_OFFSET,A1 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.w (A1,D1.l),(A0) // pointer to data in memory #else @@ -3813,7 +5660,6 @@ read_mem_word: moveq #2,D2 eor.l D2,D1 // address to access (in PCI memory address space) #endif -.read_mem_word_retry: move.w (A1,D1.l),D0 #ifdef LITTLE_ENDIAN_LANE_SWAPPED #ifdef COLDFIRE @@ -3827,58 +5673,6 @@ read_mem_word: #endif /* COLDFIRE */ #endif move.w D0,(A0) // pointer to data in memory -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.w (A0),D0 - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .read_mem_word_ok2 - lea debug35(PC),A0 - bra.s .read_mem_word_display -.read_mem_word_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_read_mem_word - lea debug39(PC),A0 - bra.s .read_mem_word_display2 -.no_master_abort_read_mem_word: - move.l A2,D0 - bsr check_parity_target - bpl.s .read_mem_word_ok - lea debug37(PC),A0 -.read_mem_word_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.read_mem_word_display2: - bsr debug_display_string - move.l A1,D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .read_mem_word_bad - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .read_mem_word_retry -.read_mem_word_bad: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 - moveq #PCI_PARITY_ERROR,D0 - rts -.read_mem_word_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -3891,35 +5685,47 @@ read_mem_word: _read_mem_longword: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.l 10(A0),A0 // pointer to data in memory read_mem_longword: #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A2,-(SP) - move.l D0,A2 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .sss + move.l A0,-(SP) + lea debug61(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.sss: #endif #endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi .bad_handle_read_mem_longword - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_mem_longword ext.l D2 bmi .bad_handle_read_mem_longword - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_mem_longword moveq #3,D0 and.l D1,D0 bne .bad_alignment_read_mem_longword +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A1 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_memory_offset(A1),A1 +#else lea PCI_MEMORY_OFFSET,A1 -.read_mem_longword_retry: +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.l (A1,D1.l),(A0) // pointer to data in memory #else @@ -3940,58 +5746,6 @@ read_mem_longword: #endif /* COLDFIRE */ #endif move.l D0,(A0) // pointer to data in memory -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l (A0),D0 - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .read_mem_longword_ok2 - lea debug35(PC),A0 - bra.s .read_mem_longword_display -.read_mem_longword_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_read_mem_longword - lea debug39(PC),A0 - bra.s .read_mem_longword_display2 -.no_master_abort_read_mem_longword: - move.l A2,D0 - bsr check_parity_target - bpl.s .read_mem_longword_ok - lea debug37(PC),A0 -.read_mem_longword_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.read_mem_longword_display2: - bsr debug_display_string - move.l A1,D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .read_mem_longword_bad - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .read_mem_longword_retry -.read_mem_longword_bad: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 - moveq #PCI_PARITY_ERROR,D0 - rts -.read_mem_longword_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -4009,14 +5763,27 @@ _fast_read_mem_byte: fast_read_mem_byte: #ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif +#if 0 // #ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ttt + move.l A0,-(SP) + lea debug62(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.ttt: #endif #endif +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN moveq #0,D0 move.b (A0,D1.l),D0 @@ -4026,53 +5793,6 @@ fast_read_mem_byte: eor.l D0,D1 // address to access (in PCI memory address space) #endif move.b (A0,D1.l),D0 // read data -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.fast_read_mem_byte_retry: - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .fast_read_mem_byte_ok2 - lea debug35(PC),A0 - bra.s .fast_read_mem_byte_display -.fast_read_mem_byte_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_fast_read_mem_byte - lea debug39(PC),A0 - bra.s .fast_read_mem_byte_display2 -.no_master_abort_fast_read_mem_byte: - move.l A1,D0 - bsr check_parity_target - bpl.s .fast_read_mem_byte_ok - lea debug37(PC),A0 -.fast_read_mem_byte_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.fast_read_mem_byte_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .fast_read_mem_byte_ok - move.l (SP)+,A0 - move.l (SP)+,D0 - move.b (A0,D1.l),D0 - bra.s .fast_read_mem_byte_retry -.fast_read_mem_byte_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A1 -#endif -#endif #endif rts @@ -4083,14 +5803,27 @@ _fast_read_mem_word: fast_read_mem_word: #ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif +#if 0 // #ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .uuu + move.l A0,-(SP) + lea debug63(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.uuu: #endif #endif +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN moveq #0,D0 move.w (A0,D1.l),D0 @@ -4099,7 +5832,6 @@ fast_read_mem_word: moveq #2,D0 eor.l D0,D1 // address to access (in PCI memory address space) #endif -.fast_read_mem_word_retry: move.w (A0,D1.l),D0 #ifdef LITTLE_ENDIAN_LANE_SWAPPED #ifdef COLDFIRE @@ -4112,51 +5844,6 @@ fast_read_mem_word: ror.w #8,D0 // read data #endif #endif -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .fast_read_mem_word_ok2 - lea debug35(PC),A0 - bra.s .fast_read_mem_word_display -.fast_read_mem_word_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_fast_read_mem_word - lea debug39(PC),A0 - bra.s .fast_read_mem_word_display2 -.no_master_abort_fast_read_mem_word: - move.l A1,D0 - bsr check_parity_target - bpl.s .fast_read_mem_word_ok - lea debug37(PC),A0 -.fast_read_mem_word_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.fast_read_mem_word_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .fast_read_mem_word_ok - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .fast_read_mem_word_retry -.fast_read_mem_word_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A1 -#endif -#endif #endif rts @@ -4167,15 +5854,27 @@ _fast_read_mem_longword: fast_read_mem_longword: #ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif +#if 0 // #ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .vvv + move.l A0,-(SP) + lea debug64(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.vvv: #endif #endif +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 -.fast_read_mem_longword_retry: +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.l (A0,D1.l),D0 #else @@ -4195,57 +5894,12 @@ fast_read_mem_longword: ror.w #8,D0 // read data #endif /* COLDFIRE */ #endif -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .fast_read_mem_longword_ok2 - lea debug35(PC),A0 - bra.s .fast_read_mem_longword_display -.fast_read_mem_longword_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_fast_read_mem_longword - lea debug39(PC),A0 - bra.s .fast_read_mem_longword_display2 -.no_master_abort_fast_read_mem_longword: - move.l A1,D0 - bsr check_parity_target - bpl.s .fast_read_mem_longword_ok - lea debug37(PC),A0 -.fast_read_mem_longword_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.fast_read_mem_longword_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .fast_read_mem_longword_ok - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .fast_read_mem_longword_retry -.fast_read_mem_longword_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A1 -#endif -#endif #endif rts _write_mem_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.w 10(A0),D2 // data to write @@ -4254,15 +5908,25 @@ _write_mem_byte: move.l D0,A1 ext.l D0 // handle bmi .bad_handle_write_mem_byte - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_write_mem_byte move.l A1,D0 swap D0 // function ext.l D0 bmi.s .bad_handle_write_mem_byte - cmp.l #PCI_MAX_FUNCTION,D0 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D0 bcc.s .bad_handle_write_mem_byte +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.b D2,(A0,D1.l) #else @@ -4271,48 +5935,6 @@ _write_mem_byte: eor.l D0,D1 // address to access (in PCI memory address space) #endif move.b D2,(A0,D1.l) // data to write -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_mem_byte_retry2: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_mem_byte2 - lea debug39(PC),A0 - bra.s .write_mem_byte_display2 -.no_master_abort_write_mem_byte2: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_mem_byte_ok2 - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.write_mem_byte_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_mem_byte_bad2 - move.l (SP)+,A0 - move.b D2,(A0,D1.l) - bra.s .write_mem_byte_retry2 -.write_mem_byte_bad2: - move.l (SP)+,A0 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_mem_byte_ok2: - move.l (SP)+,A0 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -4323,14 +5945,42 @@ _write_mem_byte: write_mem_byte: // faster for X86EMU #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .xxxx + move.l A0,-(SP) + move.l D0,-(SP) + lea debug65(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.xxxx: #endif #endif +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.b D2,(A0,D1.l) #else @@ -4339,57 +5989,13 @@ write_mem_byte: // faster for X86EMU eor.l D0,D1 // address to access (in PCI memory address space) #endif move.b D2,(A0,D1.l) // data to write -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_mem_byte_retry: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_mem_byte - lea debug39(PC),A0 - bra.s .write_mem_byte_display -.no_master_abort_write_mem_byte: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_mem_byte_ok - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.write_mem_byte_display: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_mem_byte_bad - move.l (SP)+,A0 - move.b D2,(A0,D1.l) - bra.s .write_mem_byte_retry -.write_mem_byte_bad: - move.l (SP)+,A0 - move.l (SP)+,A1 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_mem_byte_ok: - move.l (SP)+,A0 - move.l (SP)+,A1 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts _write_mem_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.w 10(A0),D2 // data to write @@ -4398,17 +6004,27 @@ _write_mem_word: move.l D0,A1 ext.l D0 // handle bmi .bad_handle_write_mem_word - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_mem_word move.l A1,D0 swap D0 // function ext.l D0 bmi.s .bad_handle_write_mem_word - cmp.l #PCI_MAX_FUNCTION,D0 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D0 bcc.s .bad_handle_write_mem_word btst #0,D1 bne.s .bad_alignment_write_mem_word +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.w D2,(A0,D1.l) #else @@ -4428,48 +6044,6 @@ _write_mem_word: eor.l D0,D1 // address to access (in PCI memory address space) #endif move.w D2,(A0,D1.l) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_mem_word_retry2: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_mem_word2 - lea debug39(PC),A0 - bra.s .write_mem_word_display2 -.no_master_abort_write_mem_word2: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_mem_word_ok2 - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.write_mem_word_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_mem_word_bad2 - move.l (SP)+,A0 - move.w D2,(A0,D1.l) - bra.s .write_mem_word_retry2 -.write_mem_word_bad2: - move.l (SP)+,A0 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_mem_word_ok2: - move.l (SP)+,A0 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -4483,14 +6057,42 @@ _write_mem_word: write_mem_word: // faster for X86EMU #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .xxxxx + move.l A0,-(SP) + move.l D0,-(SP) + lea debug66(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.xxxxx: #endif #endif +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.w D2,(A0,D1.l) #else @@ -4510,57 +6112,13 @@ write_mem_word: // faster for X86EMU eor.l D0,D1 // address to access (in PCI memory address space) #endif move.w D2,(A0,D1.l) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_mem_word_retry: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_mem_word - lea debug39(PC),A0 - bra.s .write_mem_word_display -.no_master_abort_write_mem_word: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_mem_word_ok - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.write_mem_word_display: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_mem_word_bad - move.l (SP)+,A0 - move.w D2,(A0,D1.l) - bra.s .write_mem_word_retry -.write_mem_word_bad: - move.l (SP)+,A0 - move.l (SP)+,A1 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_mem_word_ok: - move.l (SP)+,A0 - move.l (SP)+,A1 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts _write_mem_longword: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.l 10(A0),D2 // data to write @@ -4569,18 +6127,28 @@ _write_mem_longword: move.l D0,A1 ext.l D0 // handle bmi .bad_handle_write_mem_longword - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_mem_longword move.l A1,D0 swap D0 // function ext.l D0 bmi .bad_handle_write_mem_longword - cmp.l #PCI_MAX_FUNCTION,D0 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D0 bcc.s .bad_handle_write_mem_longword moveq #3,D0 and.l D1,D0 bne.s .bad_alignment_write_mem_longword +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.l D2,(A0,D1.l) #else @@ -4600,48 +6168,6 @@ _write_mem_longword: #endif /* COLDFIRE */ #endif move.l D2,(A0,D1.l) // + address to access (in PCI memory address space) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_mem_longword_retry2: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_mem_longword2 - lea debug39(PC),A0 - bra.s .write_mem_longword_display2 -.no_master_abort_write_mem_longword2: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_mem_longword_ok2 - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.write_mem_longword_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_mem_longword_bad2 - move.l (SP)+,A0 - move.l D2,(A0,D1.l) - bra.s .write_mem_longword_retry2 -.write_mem_longword_bad2: - move.l (SP)+,A0 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_mem_longword_ok2: - move.l (SP)+,A0 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -4655,14 +6181,42 @@ _write_mem_longword: write_mem_longword: // faster for X86EMU #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .xxxxxx + move.l A0,-(SP) + move.l D0,-(SP) + lea debug67(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.xxxxxx: #endif #endif +#ifdef SAME_CPU_PCI_MEM_ADDR + move.l D1,A0 + moveq #0,D1 +#else /* !SAME_CPU_PCI_MEM_ADDR */ +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_memory_offset(A0),A0 +#else lea PCI_MEMORY_OFFSET,A0 +#endif +#endif /* SAME_CPU_PCI_MEM_ADDR */ #ifdef BIG_ENDIAN move.l D2,(A0,D1.l) #else @@ -4682,81 +6236,45 @@ write_mem_longword: // faster for X86EMU #endif /* COLDFIRE */ #endif move.l D2,(A0,D1.l) // + address to access (in PCI memory address space) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_mem_longword_retry: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_mem_longword - lea debug39(PC),A0 - bra.s .write_mem_longword_display -.no_master_abort_write_mem_longword: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_mem_longword_ok - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.write_mem_longword_display: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_mem_longword_bad - move.l (SP)+,A0 - move.l D2,(A0,D1.l) - bra.s .write_mem_longword_retry -.write_mem_longword_bad: - move.l (SP)+,A0 - move.l (SP)+,A1 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_mem_longword_ok: - move.l (SP)+,A0 - move.l (SP)+,A1 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts _read_io_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI I/O address space) move.l 10(A0),A0 // pointer to data in memory read_io_byte: #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A2,-(SP) - move.l D0,A2 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .aaaa + move.l A0,-(SP) + lea debug68(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.aaaa: #endif #endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi .bad_handle_read_io_byte - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_io_byte ext.l D2 bmi .bad_handle_read_io_byte - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_io_byte +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_io_offset(A1),A1 +#else lea PCI_IO_OFFSET,A1 +#endif #ifdef BIG_ENDIAN move.b (A1,D1.l),(A0) // pointer to data in memory #else @@ -4765,60 +6283,6 @@ read_io_byte: eor.l D0,D1 // address to access (in PCI I/O address space) #endif move.b (A1,D1.l),(A0) // pointer to data in memory -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.read_io_byte_retry: - move.b (A0),D0 - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .read_io_byte_ok2 - lea debug35(PC),A0 - bra.s .read_io_byte_display -.read_io_byte_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_read_io_byte - lea debug39(PC),A0 - bra.s .read_io_byte_display2 -.no_master_abort_read_io_byte: - move.l A2,D0 - bsr check_parity_target - bpl.s .read_io_byte_ok - lea debug37(PC),A0 -.read_io_byte_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.read_io_byte_display2: - bsr debug_display_string - move.l A1,D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .read_io_byte_bad - move.l (SP)+,A0 - move.l (SP)+,D0 - move.b (A1,D1.l),(A0) - bra.s .read_io_byte_retry -.read_io_byte_bad: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 - moveq #PCI_PARITY_ERROR,D0 - rts -.read_io_byte_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -4828,33 +6292,41 @@ read_io_byte: _read_io_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI I/O address space) move.l 10(A0),A0 // pointer to data in memory read_io_word: #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A2,-(SP) - move.l D0,A2 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .bbbb + move.l A0,-(SP) + lea debug69(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.bbbb: #endif #endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi .bad_handle_read_io_word - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_io_word ext.l D2 bmi .bad_handle_read_io_word - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_io_word btst #0,D1 bne .bad_alignment_read_io_word +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_io_offset(A1),A1 +#else lea PCI_IO_OFFSET,A1 +#endif #ifdef BIG_ENDIAN move.w (A1,D1.l),(A0) // pointer to data in memory #else @@ -4862,7 +6334,6 @@ read_io_word: moveq #2,D0 eor.l D0,D1 // address to access (in PCI I/O address space) #endif -.read_io_word_retry: move.w (A1,D1.l),D0 #ifdef LITTLE_ENDIAN_LANE_SWAPPED #ifdef COLDFIRE @@ -4876,58 +6347,6 @@ read_io_word: #endif /* COLDFIRE */ #endif move.w D0,(A0) // pointer to data in memory -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.w (A0),D0 - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .read_io_word_ok2 - lea debug35(PC),A0 - bra.s .read_io_word_display -.read_io_word_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_read_io_word - lea debug39(PC),A0 - bra.s .read_io_word_display2 -.no_master_abort_read_io_word: - move.l A2,D0 - bsr check_parity_target - bpl.s .read_io_word_ok - lea debug37(PC),A0 -.read_io_word_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.read_io_word_display2: - bsr debug_display_string - move.l A1,D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .read_io_word_bad - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .read_io_word_retry -.read_io_word_bad: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 - moveq #PCI_PARITY_ERROR,D0 - rts -.read_io_word_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -4940,35 +6359,42 @@ read_io_word: _read_io_longword: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI memory address space) move.l 10(A0),A0 // pointer to data in memory read_io_longword: #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A2,-(SP) - move.l D0,A2 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .cccc + move.l A0,-(SP) + lea debug70(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.cccc: #endif #endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi .bad_handle_read_io_longword - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_read_io_longword ext.l D2 bmi .bad_handle_read_io_longword - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc .bad_handle_read_io_longword moveq #3,D0 and.l D1,D0 bne .bad_alignment_read_io_longword +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_io_offset(A1),A1 +#else lea PCI_IO_OFFSET,A1 -.read_io_longword_retry: +#endif #ifdef BIG_ENDIAN move.l (A1,D1.l),(A0) // pointer to data in memory #else @@ -4989,58 +6415,6 @@ read_io_longword: #endif /* COLDFIRE */ #endif move.l D0,(A0) // pointer to data in memory -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l (A0),D0 - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .read_io_longword_ok2 - lea debug35(PC),A0 - bra.s .read_io_longword_display -.read_io_longword_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_read_io_longword - lea debug39(PC),A0 - bra.s .read_io_longword_display2 -.no_master_abort_read_io_longword: - move.l A2,D0 - bsr check_parity_target - bpl.s .read_io_longword_ok - lea debug37(PC),A0 -.read_io_longword_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.read_io_longword_display2: - bsr debug_display_string - move.l A1,D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .read_io_longword_bad - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .read_io_longword_retry -.read_io_longword_bad: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 - moveq #PCI_PARITY_ERROR,D0 - rts -.read_io_longword_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A2 -#endif -#endif #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -5058,14 +6432,22 @@ _fast_read_io_byte: fast_read_io_byte: #ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif +#if 0 // #ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .dddd + move.l A0,-(SP) + lea debug71(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.dddd: #endif #endif +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN moveq #0,D0 move.b (A0,D1.l),D0 @@ -5075,53 +6457,6 @@ fast_read_io_byte: eor.l D0,D1 // address to access (in PCI I/O address space) #endif move.b (A0,D1.l),D0 // read data -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.fast_read_io_byte_retry: - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .fast_read_io_byte_ok2 - lea debug35(PC),A0 - bra.s .fast_read_io_byte_display -.fast_read_io_byte_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_fast_read_io_byte - lea debug39(PC),A0 - bra.s .fast_read_io_byte_display2 -.no_master_abort_fast_read_io_byte: - move.l A1,D0 - bsr check_parity_target - bpl.s .fast_read_io_byte_ok - lea debug37(PC),A0 -.fast_read_io_byte_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.fast_read_io_byte_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .fast_read_io_byte_ok - move.l (SP)+,A0 - move.l (SP)+,D0 - move.b (A0,D1.l),D0 - bra.s .fast_read_io_byte_retry -.fast_read_io_byte_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A1 -#endif -#endif #endif rts @@ -5132,14 +6467,22 @@ _fast_read_io_word: fast_read_io_word: #ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif +#if 0 // #ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .eeee + move.l A0,-(SP) + lea debug72(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.eeee: #endif #endif +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN moveq #0,D0 move.w (A0,D1.l),D0 @@ -5148,7 +6491,6 @@ fast_read_io_word: moveq #2,D0 eor.l D0,D1 // address to access (in PCI I/O address space) #endif -.fast_read_io_word_retry: move.w (A0,D1.l),D0 #ifdef LITTLE_ENDIAN_LANE_SWAPPED #ifdef COLDFIRE @@ -5161,51 +6503,6 @@ fast_read_io_word: ror.w #8,D0 // read data #endif /* COLDFIRE */ #endif -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .fast_read_io_word_ok2 - lea debug35(PC),A0 - bra.s .fast_read_io_word_display -.fast_read_io_word_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_fast_read_io_word - lea debug39(PC),A0 - bra.s .fast_read_io_word_display2 -.no_master_abort_fast_read_io_word: - move.l A1,D0 - bsr check_parity_target - bpl.s .fast_read_io_word_ok - lea debug37(PC),A0 -.fast_read_io_word_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.fast_read_io_word_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .fast_read_io_word_ok - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .fast_read_io_word_retry -.fast_read_io_word_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A1 -#endif -#endif #endif rts @@ -5216,15 +6513,22 @@ _fast_read_io_longword: fast_read_io_longword: #ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif +#if 0 // #ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .ffff + move.l A0,-(SP) + lea debug73(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.ffff: #endif #endif +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 -.fast_read_io_longword_retry: +#endif #ifdef BIG_ENDIAN move.l (A0,D1.l),D0 #else @@ -5244,57 +6548,12 @@ fast_read_io_longword: ror.w #8,D0 // read data #endif /* COLDFIRE */ #endif -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l D0,-(SP) - move.l A0,-(SP) - bsr check_parity - bpl.s .fast_read_io_longword_ok2 - lea debug35(PC),A0 - bra.s .fast_read_io_longword_display -.fast_read_io_longword_ok2: - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_fast_read_io_longword - lea debug39(PC),A0 - bra.s .fast_read_io_longword_display2 -.no_master_abort_fast_read_io_longword: - move.l A1,D0 - bsr check_parity_target - bpl.s .fast_read_io_longword_ok - lea debug37(PC),A0 -.fast_read_io_longword_display: - bsr debug_display_string - move.l 4(SP),D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.fast_read_io_longword_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .fast_read_io_longword_ok - move.l (SP)+,A0 - move.l (SP)+,D0 - bra.s .fast_read_io_longword_retry -.fast_read_io_longword_ok: - move.l (SP)+,A0 - move.l (SP)+,D0 - move.l (SP)+,A1 -#endif -#endif #endif rts _write_io_byte: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI I/O address space) move.w 10(A0),D2 // data to write @@ -5303,15 +6562,20 @@ _write_io_byte: move.l D0,A1 ext.l D0 // handle bmi .bad_handle_write_io_byte - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_io_byte move.l A1,D0 swap D0 // function ext.l D0 bmi.s .bad_handle_write_io_byte - cmp.l #PCI_MAX_FUNCTION,D0 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D0 bcc.s .bad_handle_write_io_byte +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN move.b D2,(A0,D1.l) #else @@ -5321,47 +6585,8 @@ _write_io_byte: #endif move.b D2,(A0,D1.l) // data to write #endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_io_byte_retry2: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_io_byte2 - lea debug39(PC),A0 - bra.s .write_io_byte_display2 -.no_master_abort_write_io_byte2: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_io_byte_ok2 - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.write_io_byte_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_io_byte_bad2 - move.l (SP)+,A0 - move.b D2,(A0,D1.l) - bra.s .write_io_byte_retry2 -.write_io_byte_bad2: - move.l (SP)+,A0 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_io_byte_ok2: - move.l (SP)+,A0 -#endif -#endif +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -5372,14 +6597,37 @@ _write_io_byte: write_io_byte: // faster for X86EMU #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .yyyy + move.l A0,-(SP) + move.l D0,-(SP) + lea debug74(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.yyyy: #endif #endif +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN move.b D2,(A0,D1.l) #else @@ -5389,56 +6637,15 @@ write_io_byte: // faster for X86EMU #endif move.b D2,(A0,D1.l) // data to write #endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_io_byte_retry: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_io_byte - lea debug39(PC),A0 - bra.s .write_io_byte_display -.no_master_abort_write_io_byte: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_io_byte_ok - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_byte - lea debug35b(PC),A0 -.write_io_byte_display: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_io_byte_bad - move.l (SP)+,A0 - move.b D2,(A0,D1.l) - bra.s .write_io_byte_retry -.write_io_byte_bad: - move.l (SP)+,A0 - move.l (SP)+,A1 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_io_byte_ok: - move.l (SP)+,A0 - move.l (SP)+,A1 -#endif -#endif +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 #endif moveq #PCI_SUCCESSFUL,D0 rts _write_io_word: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI I/O address space) move.w 10(A0),D2 // data to write @@ -5447,20 +6654,25 @@ _write_io_word: move.l D0,A1 ext.l D0 // handle bmi .bad_handle_write_io_word - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_io_word move.l A1,D0 swap D0 // function ext.l D0 bmi.s .bad_handle_write_io_word - cmp.l #PCI_MAX_FUNCTION,D0 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D0 bcc.s .bad_handle_write_io_word btst #0,D1 bne.s .bad_alignment_write_io_word +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN move.w D2,(A0,D1.l) -#else +#else #ifdef LITTLE_ENDIAN_LANE_SWAPPED #ifdef COLDFIRE moveq #0,D0 @@ -5477,48 +6689,9 @@ _write_io_word: eor.l D0,D1 // address to access (in PCI I/O address space) #endif move.w D2,(A0,D1.l) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_io_word_retry2: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_io_word2 - lea debug39(PC),A0 - bra.s .write_io_word_display2 -.no_master_abort_write_io_word2: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_io_word_ok2 - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.write_io_word_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_io_word_bad2 - move.l (SP)+,A0 - move.w D2,(A0,D1.l) - bra.s .write_io_word_retry2 -.write_io_word_bad2: - move.l (SP)+,A0 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_io_word_ok2: - move.l (SP)+,A0 -#endif -#endif +#endif /* BIG_ENDIAN */ +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -5532,14 +6705,37 @@ _write_io_word: write_io_word: // faster for X86EMU #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .yyyyy + move.l A0,-(SP) + move.l D0,-(SP) + lea debug75(PC),A0 + bsr debug_display_string + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 + bsr debug_hex_word + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + move.l (SP)+,A0 +.yyyyy: #endif #endif +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN move.w D2,(A0,D1.l) #else @@ -5559,57 +6755,16 @@ write_io_word: // faster for X86EMU eor.l D0,D1 // address to access (in PCI I/O address space) #endif move.w D2,(A0,D1.l) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_io_word_retry: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_io_word - lea debug39(PC),A0 - bra.s .write_io_word_display -.no_master_abort_write_io_word: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_io_word_ok - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_word - lea debug35b(PC),A0 -.write_io_word_display: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_io_word_bad - move.l (SP)+,A0 - move.w D2,(A0,D1.l) - bra.s .write_io_word_retry -.write_io_word_bad: - move.l (SP)+,A0 - move.l (SP)+,A1 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_io_word_ok: - move.l (SP)+,A0 - move.l (SP)+,A1 -#endif -#endif +#endif /* BIG_ENDIAN */ +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 #endif moveq #PCI_SUCCESSFUL,D0 rts _write_io_longword: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address to access (in PCI I/O address space) move.l 10(A0),D2 // data to write @@ -5618,18 +6773,23 @@ _write_io_longword: move.l D0,A1 ext.l D0 // handle bmi .bad_handle_write_io_longword - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc .bad_handle_write_io_longword move.l A1,D0 swap D0 // function ext.l D0 bmi .bad_handle_write_io_longword - cmp.l #PCI_MAX_FUNCTION,D0 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D0 bcc.s .bad_handle_write_io_longword moveq #3,D0 and.l D1,D0 bne.s .bad_alignment_write_io_longword +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN move.l D2,(A0,D1.l) #else @@ -5649,69 +6809,53 @@ _write_io_longword: #endif /* COLDFIRE */ #endif move.l D2,(A0,D1.l) // + address to access (in PCI I/O address space) +#endif /* BIG_ENDIAN */ +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 #endif + moveq #PCI_SUCCESSFUL,D0 + rts +.bad_alignment_write_io_longword: + moveq #PCI_GENERAL_ERROR,D0 + rts +.bad_handle_write_io_longword: + moveq #PCI_BAD_HANDLE,D0 + rts + +write_io_longword: // faster for X86EMU + #ifndef COLDFIRE -#ifdef CHECK_PARITY #ifdef DEBUG -.write_io_longword_retry2: + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .yyyyyy move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_io_longword2 - lea debug39(PC),A0 - bra.s .write_io_longword_display2 -.no_master_abort_write_io_longword2: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_io_longword_ok2 - lea debug38(PC),A0 + move.l D0,-(SP) + lea debug76(PC),A0 bsr debug_display_string - move.l D2,D0 bsr debug_hex_long - lea debug35b(PC),A0 -.write_io_longword_display2: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 + moveq #0x20,D0 + bsr debug_display_char + move.l D1,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l D2,D0 bsr debug_hex_long moveq #13,D0 bsr debug_display_char moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_io_longword_bad2 - move.l (SP)+,A0 - move.l D2,(A0,D1.l) - bra.s .write_io_longword_retry2 -.write_io_longword_bad2: - move.l (SP)+,A0 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_io_longword_ok2: + bsr debug_display_char + move.l (SP)+,D0 move.l (SP)+,A0 +.yyyyyy: #endif #endif -#endif - moveq #PCI_SUCCESSFUL,D0 - rts -.bad_alignment_write_io_longword: - moveq #PCI_GENERAL_ERROR,D0 - rts -.bad_handle_write_io_longword: - moveq #PCI_BAD_HANDLE,D0 - rts - -write_io_longword: // faster for X86EMU - -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG - move.l A1,-(SP) - move.l D0,A1 -#endif -#endif -#endif +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A0 + move.l pci_io_offset(A0),A0 +#else lea PCI_IO_OFFSET,A0 +#endif #ifdef BIG_ENDIAN move.l D2,(A0,D1.l) #else @@ -5731,50 +6875,9 @@ write_io_longword: // faster for X86EMU #endif /* COLDFIRE */ #endif move.l D2,(A0,D1.l) // + address to access (in PCI I/O address space) -#endif -#ifndef COLDFIRE -#ifdef CHECK_PARITY -#ifdef DEBUG -.write_io_longword_retry: - move.l A0,-(SP) - bsr check_parity - and.l #0x28000000,D0 // Master Target Abort - beq.s .no_master_abort_write_io_longword - lea debug39(PC),A0 - bra.s .write_io_longword_display -.no_master_abort_write_io_longword: - move.l A1,D0 - bsr check_parity_target - bpl.s .write_io_longword_ok - lea debug38(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_long - lea debug35b(PC),A0 -.write_io_longword_display: - bsr debug_display_string - move.l (SP),D0 - add.l D1,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - bsr wait_key - bne.s .write_io_longword_bad - move.l (SP)+,A0 - move.l D2,(A0,D1.l) - bra.s .write_io_longword_retry -.write_io_longword_bad: - move.l (SP)+,A0 - move.l (SP)+,A1 - moveq #PCI_PARITY_ERROR,D0 - rts -.write_io_longword_ok: - move.l (SP)+,A0 - move.l (SP)+,A1 -#endif -#endif +#endif /* BIG_ENDIAN */ +#ifdef COLDFIRE + jsr dummy_function // errata, use D0 #endif moveq #PCI_SUCCESSFUL,D0 rts @@ -5786,37 +6889,76 @@ get_machine_id: // 1: Milan // 2: PAK/Panther // 3: Aranym +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug77(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif +#endif moveq #0,D0 // no ID available rts _get_pagesize: get_pagesize: +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug78(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif +#endif moveq #0,D0 // paging not active rts _virt_to_bus: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // address in virtual CPU space move.l 10(A0),A0 // ptr virt_to_bus: +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .iiii + move.l A0,-(SP) + lea debug79(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.iiii: +#endif +#endif move.l D0,D2 - swap D2 // function + swap D2 // function ext.l D0 // handle bmi.s .bad_handle_virt_to_bus - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_virt_to_bus ext.l D2 bmi.s .bad_handle_virt_to_bus - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc.s .bad_handle_virt_to_bus move.l D1,D0 // address in virtual CPU space - sub.l #PCI_MEMORY_OFFSET,D0 +#ifndef SAME_CPU_PCI_MEM_ADDR +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + sub.l pci_memory_offset(A1),D0 +#else + sub.l #PCI_MEMORY_OFFSET,D0 // cannot work for I/O space +#endif +#endif move.l D0,PCI_CONV_ADDR_ADDR(A0) // PCI bus address +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_memory_size(A1),D0 +#else move.l #PCI_MEMORY_SIZE,D0 +#endif move.l D0,PCI_CONV_ADDR_LEN(A0) // length of contiguous mapped area moveq #PCI_SUCCESSFUL,D0 rts @@ -5826,26 +6968,49 @@ virt_to_bus: _bus_to_virt: - move.l 2(A0),D0 // function(H)/handle(L) + move.l 2(A0),D0 // bus/function(H)/slot(L) move.l 6(A0),D1 // PCI bus address move.l 10(A0),A0 // ptr bus_to_virt: +#ifndef COLDFIRE +#ifdef DEBUG + cmp.l #SLOT_TO_DEBUG,D0 + bne.s .jjjj + move.l A0,-(SP) + lea debug80(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +.jjjj: +#endif +#endif move.l D0,D2 swap D2 // function ext.l D0 // handle bmi.s .bad_handle_bus_to_virt - cmp.l #PCI_MAX_HANDLE,D0 + cmp.l #PCI_MAX_DEVICE,D0 bcc.s .bad_handle_bus_to_virt ext.l D2 bmi.s .bad_handle_bus_to_virt - cmp.l #PCI_MAX_FUNCTION,D2 + cmp.l #PCI_MAX_FUNCTION*PCI_MAX_BUS,D2 bcc.s .bad_handle_bus_to_virt move.l D1,D0 // PCI bus address - add.l #PCI_MEMORY_OFFSET,D0 +#ifndef SAME_CPU_PCI_MEM_ADDR +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + add.l pci_memory_offset(A1),D0 +#else + add.l #PCI_MEMORY_OFFSET,D0 // cannot work for I/O space +#endif +#endif move.l D0,PCI_CONV_ADDR_ADDR(A0) // CPU virtual address +#ifdef PCI_DYNAMIC_MAPPING + move.l phystop,A1 + move.l pci_memory_size(A1),D0 +#else move.l #PCI_MEMORY_SIZE,D0 +#endif move.l D0,PCI_CONV_ADDR_LEN(A0) // length of contiguous mapped area moveq #PCI_SUCCESSFUL,D0 rts @@ -5860,6 +7025,14 @@ _virt_to_phys: virt_to_phys: +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug81(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif +#endif move.l D0,PCI_CONV_ADDR_ADDR(A0) // physical CPU virtual address clr.l PCI_CONV_ADDR_LEN(A0) // length of contiguous mapped area moveq #PCI_SUCCESSFUL,D0 @@ -5872,6 +7045,14 @@ _phys_to_virt: phys_to_virt: +#ifndef COLDFIRE +#ifdef DEBUG + move.l A0,-(SP) + lea debug82(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 +#endif +#endif move.l D0,PCI_CONV_ADDR_ADDR(A0) // CPU virtual address clr.l PCI_CONV_ADDR_LEN(A0) // length of contiguous mapped area moveq #PCI_SUCCESSFUL,D0 @@ -5921,9 +7102,11 @@ _dma_buffoper: .cmd_dma_buffoper: move.l #DMASCR0,D1 // DMA Channel 0 Command/Status bsr write_local_config_byte + bra.s .status_dma_buffoper2 .status_dma_buffoper: move.l #DMASCR0,D1 // DMA Channel 0 Command/Status bsr read_local_config_byte +.status_dma_buffoper2: moveq #0,D1 btst #0,D0 // enable beq.s .end_dma_buffoper // no @@ -5978,6 +7161,40 @@ _write_mailbox: moveq #PCI_BAD_REGISTER_NUMBER,D0 rts +#ifdef COLDFIRE +_dma_lock: +#endif +_dma_alloc: +_dma_free: + + moveq #0,D0 + rts + +#ifndef COLDFIRE + +dma_lock: + + move.l 4(SP),D0 // mode + bra.s .dl1 + +_dma_lock: /* CTPCI DMA freeze workaround */ + + move.w 2(A0),D0 // mode +.dl1: + cmp.w #-2,D0 + bne.s .dl2 + lea dma_lock(PC),A0 + move.l A0,D0 + rts +.dl2: + bmi.s .dl3 + nop +.dl3: + moveq #-1,D0 + rts + +#endif /* COLDFIRE */ + #if 1 // #ifdef COLDFIRE read_local_config_byte: @@ -6061,18 +7278,6 @@ read_local_config_byte: eor.l D0,D1 // offset .read_local_config_byte_little: move.b (A0,D1.l),D0 // read data -#if 0 // #ifdef DEBUG - move.l D0,-(SP) - moveq #0x52,D0 - bsr debug_display_char - move.l (SP),D0 - bsr debug_hex_byte - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif rts read_local_config_word: @@ -6084,18 +7289,6 @@ read_local_config_word: eor.l D0,D1 // offset .read_local_config_word_little: move.w (A0,D1.l),D0 -#if 0 // #ifdef DEBUG - move.l D0,-(SP) - moveq #0x52,D0 - bsr debug_display_char - move.l (SP),D0 - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif cmp.l #PLX9054_SWAPPED,(A0) bne.s .read_local_config_word_big ror.w #8,D0 // read data @@ -6106,18 +7299,6 @@ read_local_config_longword: lea PCI_LOCAL_CONFIG,A0 move.l (A0,D1.l),D0 -#if 0 // #ifdef DEBUG - move.l D0,-(SP) - moveq #0x52,D0 - bsr debug_display_char - move.l (SP),D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif cmp.l #PLX9054_SWAPPED,(A0) bne.s .read_local_config_longword_big ror.w #8,D0 @@ -6135,16 +7316,6 @@ write_local_config_byte: eor.l D0,D1 // offset .write_local_config_byte_little: move.b D2,(A0,D1.l) // data to write -#if 0 // #ifdef DEBUG - moveq #0x57,D0 - bsr debug_display_char - move.l D2,D0 - bsr debug_hex_byte - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif moveq #PCI_SUCCESSFUL,D0 rts @@ -6156,31 +7327,11 @@ write_local_config_word: moveq #2,D0 eor.l D0,D1 // offset move.w D2,(A0,D1.l) -#if 0 // #ifdef DEBUG - moveq #0x57,D0 - bsr debug_display_char - move.l D2,D0 - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif moveq #PCI_SUCCESSFUL,D0 rts .write_local_config_word_little: ror.w #8,D2 // data to write move.w D2,(A0,D1.l) -#if 0 // #ifdef DEBUG - moveq #0x57,D0 - bsr debug_display_char - move.l D2,D0 - bsr debug_hex_word - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif moveq #PCI_SUCCESSFUL,D0 rts @@ -6194,142 +7345,11 @@ write_local_config_longword: ror.w #8,D2 .write_local_config_longword_big: move.l D2,(A0,D1.l) -#if 0 // #ifdef DEBUG - moveq #0x57,D0 - bsr debug_display_char - move.l D2,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char -#endif - moveq #PCI_SUCCESSFUL,D0 - rts - -write_verify_local_config_byte: - - move.l D1,-(SP) - bsr write_local_config_byte - move.b (A0,D1.l),D0 - cmp.b D0,D2 - beq.s .wvb_ok - move.l D0,-(SP) - lea plx_error_register(PC),A0 - bsr display_string - move.l 4(SP),D0 - bsr hex_word - lea plx_error_write_value(PC),A0 - bsr display_string - move.l D2,D0 - bsr hex_byte - lea plx_error_read_value(PC),A0 - bsr display_string - move.l (SP)+,D0 - bsr hex_byte - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char -#if 0 // #ifdef DEBUG - bsr dump_plx -#endif -.wvb_error: - bra.s .wvb_error -.wvb_ok: - addq.l #4,SP - moveq #PCI_SUCCESSFUL,D0 - rts - -write_verify_local_config_word: - - move.l D1,-(SP) - bsr write_local_config_word - move.w (A0,D1.l),D0 - cmp.w D0,D2 - beq.s .wvw_ok - move.l D0,-(SP) - lea plx_error_register(PC),A0 - bsr display_string - move.l 4(SP),D0 - bsr hex_word - lea plx_error_write_value(PC),A0 - bsr display_string - move.l D2,D0 - bsr hex_word - lea plx_error_read_value(PC),A0 - bsr display_string - move.l (SP)+,D0 - bsr hex_word - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char -#if 0 // #ifdef DEBUG - bsr dump_plx -#endif -.wvw_error: - bra.s .wvw_error -.wvw_ok: - addq.l #4,SP - moveq #PCI_SUCCESSFUL,D0 - rts - -write_verify_local_config_longword: - - move.l D1,-(SP) - bsr write_local_config_longword - move.l (A0,D1.l),D0 - cmp.l D0,D2 - beq.s .wvl_ok - move.l D0,-(SP) - lea plx_error_register(PC),A0 - bsr display_string - move.l 4(SP),D0 - bsr hex_word - lea plx_error_write_value(PC),A0 - bsr display_string - move.l D2,D0 - bsr hex_long - lea plx_error_read_value(PC),A0 - bsr display_string - move.l (SP)+,D0 - bsr hex_long - moveq #13,D0 - bsr display_char - moveq #10,D0 - bsr display_char -#if 0 // #ifdef DEBUG - bsr dump_plx -#endif -.wvl_error: - bra.s .wvl_error -.wvl_ok: - addq.l #4,SP moveq #PCI_SUCCESSFUL,D0 rts #ifdef DEBUG -test_endian_local_config: - - lea PCI_LOCAL_CONFIG,A0 - cmp.l #PLX9054_SWAPPED,(A0) - seq.b D0 - ext.w D0 - ext.l D0 // -1: little, 0: big - rts - -wait_key: - - lea debug40(PC),A0 - bsr debug_display_string - move.w #1,-(SP) - trap #1 // Cconin - addq.l #2,SP - cmp.b #0x79,D0 // y - rts - #if 0 dump_plx: @@ -6389,65 +7409,150 @@ check_parity: tst.l D0 // value, bit 31: parity rts -check_parity_target: // D0.l handle - -#ifdef TEST_TARGET - move.l A0,-(SP) - move.l D1,-(SP) - move.l D0,-(SP) // handle - moveq #PCICSR,D1 - bsr fast_read_config_longword - move.l D0,-(SP) // value - move.l D2,-(SP) - move.l D0,D2 - move.l 8(SP),D0 // handle - moveq #PCICSR,D1 // PCI Command / Status Register - bsr write_config_longword - move.l (SP)+,D2 - move.l (SP)+,D0 // value - addq.l #4,SP // handle - move.l (SP)+,D1 - move.l (SP)+,A0 - tst.l D0 // value, bit 31: parity -#else - moveq #0,D0 -#endif - rts - #endif /* CHECK_PARITY */ pci_interrupt: - move.w D0,D4 // Bridge/IntA/IntB/IntC/IntD <=> handle <=> card - lea 0,A2 + move.l D0,D5 // 0: bridge, 1+:num int host for get INTA-D + moveq #0,D2 // interrupt handled + moveq #PCI_MAX_SLOT,D3 // primary bus + moveq #0,D4 // slot + moveq #0,D6 // function + moveq #0,D7 // bus move.l #0x5F504349,D0 // _PCI bsr get_cookie - beq.s .loop_interrupt // not found + beq .interrupt_cookie_not_found add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE,D0 move.l D0,A2 // Status-Descriptors + add.l #PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A4 // used interrupt table + move.l D0,A5 .loop_interrupt: - move.l A2,D0 - beq.s .end_interrupt - move.w D4,D1 // handle - mulu #PCI_DEV_DES_SIZE,D1 - move.l PCI_DEV_DES_HANDLER(A2,D1.l),D0 - beq.s .end_interrupt - move.l D0,A3 - move.l PCI_DEV_DES_PARAMETER(A2,D1.l),A0 - moveq #0,D0 - jsr (A3) - and.l #1,D0 - bne.s .interrupt_ok // interrupt was from this card + moveq #0,D0 + move.b (A4),D0 + beq.s .interrupt_next_handle // not used for this handle + cmp.l D5,D0 // num int + bne.s .interrupt_next_handle // not for this interrupt + move.l PCI_DEV_DES_HANDLER(A2),D0 + beq.s .end_interrupt // abnormal + move.l D0,A3 + moveq #0,D0 // return value + move.l D0,-(SP) // BIOS internal data + move.l PCI_DEV_DES_PARAMETER(A2),-(SP) // parameter for interrupt handler + jsr (A3) + addq.l #8,SP + and.l #1,D0 + or.l D0,D2 + tst.l D0 + bne.s .interrupt_ok // interrupt was from this card + bra.s .interrupt_next_handle .end_interrupt: - move.w D4,D0 // handle - bsr disable_interrupt - rts + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D4,D0 // slot + bsr disable_interrupt + bra.s .interrupt_next_handle .interrupt_ok: - move.w D4,D0 // handle - bsr clear_interrupt - move.w D4,D0 // handle - bsr test_interrupt - beq .loop_interrupt + move.l D5,D0 // num int + bsr clear_interrupt +#ifdef COLDFIRE /* problems with CTPCI */ + move.l D5,D0 // num int + bsr test_interrupt +#if 1 + bne.s .interrupt_next_handle + rts // interrupt not active and finished +#else /* was */ + beq .loop_interrupt // interrupt always active +#endif +#endif /* COLDFIRE */ +.interrupt_next_handle: + add.l #PCI_DEV_DES_SIZE,A2 + addq.l #1,A4 + add.l #1,D6 // function + cmp.l #PCI_MAX_FUNCTION,D6 + bcs .loop_interrupt + moveq #0,D6 // function + addq.l #1,D4 // slot + cmp.l D3,D4 + bcs .loop_interrupt +#if (PCI_MAX_DEVICE != PCI_MAX_SLOT) + mulu #PCI_MAX_FUNCTION,D3 + sub.l D3,A4 + mulu #PCI_DEV_DES_SIZE,D3 + sub.l D3,A2 // Status-Descriptors + moveq #PCI_MAX_DEVICE,D3 + move.l D3,D4 + mulu #PCI_MAX_FUNCTION,D4 + add.l D4,A4 + mulu #PCI_DEV_DES_SIZE,D4 + add.l D4,A2 // Status-Descriptors +#endif + moveq #0,D4 // handle + addq.l #1,D7 + cmp.l #PCI_MAX_BUS,D7 + bcs .loop_interrupt + tst.l D2 + bne.s .end_of_interrupt // interrupt handled +.interrupt_cookie_not_found: + // problem => disable this interrupt on all devices + moveq #PCI_MAX_SLOT,D3 // primary bus + moveq #0,D4 // slot + moveq #0,D6 // function + moveq #0,D7 // bus +.loop_disable: + moveq #0,D0 + move.b (A5),D0 + beq.s .disable_next_handle // not used for this handle + cmp.l D5,D0 // num int + bne.s .disable_next_handle // not for this interrupt + move.l D7,D0 // bus number + mulu #PCI_MAX_FUNCTION,D0 + add.l D6,D0 // function number + swap D0 + or.l D4,D0 + bsr disable_interrupt +.disable_next_handle: + addq.l #1,A5 + add.l #1,D6 // function + cmp.l #PCI_MAX_FUNCTION,D6 + bcs.s .loop_disable + moveq #0,D6 // function + addq.l #1,D4 // slot + cmp.l D3,D4 + bcs.s .loop_disable +#if (PCI_MAX_DEVICE != PCI_MAX_SLOT) + mulu #PCI_MAX_FUNCTION,D3 + sub.l D3,A5 + moveq #PCI_MAX_DEVICE,D3 + move.l D3,D4 + mulu #PCI_MAX_FUNCTION,D4 + add.l D4,A5 +#endif + moveq #0,D4 // handle + addq.l #1,D7 + cmp.l #PCI_MAX_BUS,D7 + bcs.s .loop_disable +.end_of_interrupt: + rts + +test_int_not_used: + + move.l A0,-(SP) + move.l D1,-(SP) + move.l #PCI_INT_HANDLESTOTALSIZE-1,D1 + moveq #0,D0 // search how many times the interrupt is used +.loop_int_not_used: + tst.b (A0)+ // 0:no INT, 1+:num int host for get INTA-D + beq.s .int_not_used + addq.l #1,D0 +.int_not_used: + subq.l #1,D1 + bpl.s .loop_int_not_used + move.l (SP)+,D1 + move.l (SP)+,A0 + tst.l D0 rts #ifdef COLDFIRE @@ -6489,22 +7594,6 @@ test_interrupt: dc.l 0x5F504349 // _PCI dc.l 0 -int_cfpci: - - lea -60(SP),SP - movem.l D0-A6,(SP) - moveq #0,D0 // bridge - bsr pci_interrupt - move.l MCF_PCI_PCIGSCR,D0 - move.l D0,MCF_PCI_PCIGSCR - movem.l (SP),D0-A6 - lea 60(SP),SP - rte - - dc.l 0x58425241 // XBRA - dc.l 0x5F504349 // _PCI - dc.l 0 - int_pciarb: move.l D0,-(SP) @@ -6533,62 +7622,369 @@ int3_pci: // same interrupt for 4 sources IntA-D lea 60(SP),SP rte -#else /* MCF548X */ +#else /* MCF548X-7X */ -enable_interrupt: +#ifdef MCF547X /* FIREBEE */ +enable_interrupt: // D0.L: handle + + move.l A0,-(SP) move.l D1,-(SP) move.w SR,D1 move.l D1,-(SP) or.l #0x700,D1 // mask interrupts move.w D1,SR - ext.l D0 + move.l D0,D1 // handle + beq .end_enable // bridge + move.l #0x5F504349,D0 // _PCI + bsr get_cookie + beq .end_enable // not found + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A0 // used int table + move.l D1,D0 // bus/function(H)/slot(L) + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A0 // offset slot + move.l D1,D0 + swap D0 + ext.l D0 // bus/function +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D0 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D0,-(SP) + ext.l D0 // bus + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D0 + add.l D0,A0 // offset bus + move.l (SP)+,D0 + clr.w D0 + swap D0 // function + add.l D0,A0 // offset function + move.l A0,-(SP) + move.l D1,D0 // handle + moveq #PCIIPR,D1 // Interrupt Pin + bsr fast_read_config_byte// 0:no INT, 1:INTA, 2:INTB, 3:INTC, 4:INTD + moveq #0,D1 + move.b D0,D1 + move.l (SP)+,A0 + tst.l D1 beq.s .end_enable - cmp.l #2,D0 - bhi.s .slot_enable + subq.l #1,D1 + moveq #0,D0 + move.b PCI_INT_HANDLESTOTALSIZE(A0),D0 // slot offset 0-3 + add.l D0,D1 + and.l #3,D1 // INTA-D + moveq #ACP_INT_PCI_INTA,D0 + asl.l D1,D0 + move.b D0,(A0) // use INTx for this handle + or.l #ACP_INT_ACP_IRQ5,D0 + or.l D0,ACP_INTERRUPT_ENABLE + move.b MCF_EPORT_EPIER,D0 + or.l #MCF_EPORT_EPIER_EPIE5,D0 + move.b D0,MCF_EPORT_EPIER + moveq #5,D0 + bset.b D0,MCF_EPORT_EPFR // clear interrupt + move.l #~(MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL),D0 + and.l D0,MCF_INTC_IMRL +.end_enable: + move.l (SP)+,D1 + move.w D1,SR + move.l (SP)+,D1 + move.l (SP)+,A0 + rts + +disable_interrupt: // D0.L: handle + + move.l A1,-(SP) + move.l A0,-(SP) + move.l D1,-(SP) + move.w SR,D1 + move.l D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR + move.l D0,D1 // handle + beq .end_disable // bridge + move.l #0x5F504349,D0 // _PCI + bsr get_cookie + beq .end_disable // not found + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A0 + move.l D0,A1 + move.l D1,D0 // bus/function(H)/slot(L) + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A1 // offset slot + move.l D1,D0 + swap D0 + ext.l D0 // bus/function +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D0 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D0,-(SP) + ext.l D0 // bus + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D0 + add.l D0,A1 // offset bus + move.l (SP)+,D0 + clr.w D0 + swap D0 // function + add.l D0,A1 // offset function + move.l A1,-(SP) + move.l A0,-(SP) + move.l D1,D0 // handle + moveq #PCIIPR,D1 // Interrupt Pin + bsr fast_read_config_byte// 0:no INT, 1:INTA, 2:INTB, 3:INTC, 4:INTD + moveq #0,D1 + move.b D0,D1 + move.l (SP)+,A0 + move.l (SP)+,A1 + tst.l D1 + beq.s .end_disable + subq.l #1,D1 + moveq #0,D0 + move.b PCI_INT_HANDLESTOTALSIZE(A1),D0 // slot offset 0-3 + add.l D0,D1 + and.l #3,D1 // INTA-D + clr.b (A1) // not use INTx for this handle + bsr test_int_not_used + bne.s .end_disable // used on another handle + moveq #~ACP_INT_PCI_INTA,D0 + asl.l D1,D0 + and.l D0,ACP_INTERRUPT_ENABLE +.end_disable: + move.l (SP)+,D1 + move.w D1,SR + move.l (SP)+,D1 + move.l (SP)+,A0 + move.l (SP)+,A1 + rts + +clear_interrupt: + + ext.l D0 + bne.s .int_clear + rts +.int_clear: + or.l D0,ACP_INTERRUPT_CLEAR // clear interrupt + rts + +test_interrupt: + + ext.l D0 + bne.s .test_int + move.l MCF_INTC_IPRH,D0 + btst #41-32,D0 + seq.b D0 + and.l #1,D0 // 1: interrupt is finished + rts +.test_int: + and.l ACP_INTERRUPT_CLEAR,D0 + seq.b D0 + and.l #1,D0 // 1: interrupt is finished + rts + + dc.l 0x58425241 // XBRA + dc.l 0x5F504349 // _PCI + dc.l 0 + +int5_pci: // INTA-D + + move.w #0x2700,SR // for FreeRTOS native interrupts + lea -60(SP),SP + movem.l D0-A6,(SP) + moveq #3,D7 + moveq #ACP_INT_PCI_INTA,D6 +.int_abcd_loop: + move.l ACP_INTERRUPT_CLEAR,D0 // state + and.l ACP_INTERRUPT_ENABLE,D0 + and.l D6,D0 + beq.s .next_int_abcd + move.l D7,-(SP) + move.l D6,-(SP) + bsr pci_interrupt + move.l (SP)+,D6 + move.l (SP)+,D7 +.next_int_abcd: + add.l D6,D6 + subq.l #1,D7 + bpl .int_abcd_loop + moveq #ACP_INT_PCI_INTD+ACP_INT_PCI_INTC+ACP_INT_PCI_INTB+ACP_INT_PCI_INTA,D0 + move.l D0,ACP_INTERRUPT_CLEAR + moveq #5,D0 + bset.b D0,MCF_EPORT_EPFR // clear interrupt + movem.l (SP),D0-A6 + lea 60(SP),SP + rte + +#else /* MCF548X - M5484LITE-M5485EVB */ + +enable_interrupt: // D0.L: handle + + move.l A0,-(SP) + move.l D1,-(SP) + move.w SR,D1 + move.l D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR + move.l D0,D1 // handle + beq .end_enable // bridge + move.l #0x5F504349,D0 // _PCI + bsr get_cookie + beq .end_enable // not found + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A0 // used int table + move.l D1,D0 // bus/function(H)/slot(L) + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A0 // offset slot + move.l D1,D0 + swap D0 + ext.l D0 // bus/function +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D0 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D0,-(SP) + ext.l D0 // bus + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D0 + add.l D0,A0 // offset bus + move.l (SP)+,D0 + clr.w D0 + swap D0 // function + add.l D0,A0 // offset function + move.l D1,D0 + ext.l D0 // handle => slot + cmp.l #3,D0 // TODO: FIX for bus + bcc.s .slot_enable + // on board M5485EVB devices +.enable_int5: + moveq #5,D0 + move.b D0,(A0) // use INT5 for this handle move.b MCF_EPORT_EPIER,D0 or.l #MCF_EPORT_EPIER_EPIE5,D0 move.b D0,MCF_EPORT_EPIER - move.l #~(MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL),D0 + move.l #~(MCF_INTC_IMRL_INT_MASK5 + MCF_INTC_IMRL_MASKALL),D0 and.l D0,MCF_INTC_IMRL bra.s .end_enable -.slot_enable: - move.l MCF_INTC_IMRL,D0 - and.l #MCF_INTC_IMRL_INT_MASK7,D0 +.slot_enable: // M5484LITE: INT7: INTA-B, INT5 INTC-D + move.l A0,-(SP) + move.l D0,-(SP) // slot + move.l D1,D0 // handle + moveq #PCIIPR,D1 // Interrupt Pin + bsr fast_read_config_byte// 0:no INT, 1:INTA, 2:INTB, 3:INTC, 4:INTD + moveq #0,D1 + move.b D0,D1 + move.l (SP)+,D0 // slot + move.l (SP)+,A0 + tst.l D1 beq.s .end_enable + // slot 3: INT7: INTA-B, INT5 INTC-D, slot4 (riser): INT7: INTB-A, INT5 INTD-C + subq.l #1,D1 + cmpl #4,D0 + bne.s .not_a_riser + bchg #0,D1 +.not_a_riser: + cmp.l #2,D1 + bcc.s .enable_int5 + moveq #7,D0 + move.b D0,(A0) // use INT7 for this handle move.b MCF_EPORT_EPIER,D0 or.l #MCF_EPORT_EPIER_EPIE7,D0 move.b D0,MCF_EPORT_EPIER - move.l #~(MCF_INTC_IMRL_INT_MASK7 + MCF_INTC_IMRL_MASKALL),D0 + move.l #~(MCF_INTC_IMRL_INT_MASK7 + MCF_INTC_IMRL_MASKALL),D0 and.l D0,MCF_INTC_IMRL .end_enable: move.l (SP)+,D1 move.w D1,SR move.l (SP)+,D1 + move.l (SP)+,A0 rts -disable_interrupt: +disable_interrupt: // D0.L: handle + move.l A1,-(SP) + move.l A0,-(SP) move.l D1,-(SP) move.w SR,D1 move.l D1,-(SP) or.l #0x700,D1 // mask interrupts move.w D1,SR - ext.l D0 - beq.s .end_disable - cmp.l #2,D0 - bhi.s .slot_disable - move.l #MCF_INTC_IMRL_INT_MASK5,D0 + move.l D0,D1 // handle + beq .end_disable // bridge + move.l #0x5F504349,D0 // _PCI + bsr get_cookie + beq .end_disable // not found + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A0 + move.l D0,A1 + move.l D1,D0 // bus/function(H)/slot(L) + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A1 // offset slot + move.l D1,D0 + swap D0 + ext.l D0 // bus/function +#ifdef COLDFIRE + .chip 68060 +#endif + divu #PCI_MAX_FUNCTION,D0 +#ifdef COLDFIRE + .chip 5200 +#endif + move.l D0,-(SP) + ext.l D0 // bus + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D0 + add.l D0,A1 // offset bus + move.l (SP)+,D0 + clr.w D0 + swap D0 // function + add.l D0,A1 // offset function + move.l D1,D0 + ext.l D0 // handle => slot + cmp.l #3,D0 // TODO: FIX for bus + bcc.s .slot_disable + // on board M5485EVB devices +.disable_int5: + clr.b (A1) // not use INT5 for this handle + bsr test_int_not_used + bne .end_disable // used on another handle + move.l #MCF_INTC_IMRL_INT_MASK5,D0 or.l D0,MCF_INTC_IMRL move.b MCF_EPORT_EPIER,D0 and.l #~MCF_EPORT_EPIER_EPIE5,D0 move.b D0,MCF_EPORT_EPIER bra.s .end_disable .slot_disable: - move.l MCF_INTC_IMRL,D0 - and.l #MCF_INTC_IMRL_INT_MASK7,D0 - bne.s .end_disable - move.l #MCF_INTC_IMRL_INT_MASK7,D0 + move.l A1,-(SP) + move.l A0,-(SP) + move.l D0,-(SP) // slot + move.l D1,D0 // handle + moveq #PCIIPR,D1 // Interrupt Pin + bsr fast_read_config_byte// 0:no INT, 1:INTA, 2:INTB, 3:INTC, 4:INTD + moveq #0,D1 + move.b D0,D1 + move.l (SP)+,D0 // slot + move.l (SP)+,A0 + move.l (SP)+,A1 + tst.l D1 + beq.s .end_disable + // slot 3: INT7: INTA-B, INT5 INTC-D, slot4 (riser): INT7: INTB-A, INT5 INTD-C + subq.l #1,D1 + cmpl #4,D0 + bne.s .not_a_riser2 + bchg #0,D1 +.not_a_riser2: + cmp.l #2,D1 + bcc.s .disable_int5 + clr.b (A1) // not use INT7 for this handle + bsr test_int_not_used + bne.s .end_disable // used on another handle + move.l #MCF_INTC_IMRL_INT_MASK7,D0 or.l D0,MCF_INTC_IMRL move.b MCF_EPORT_EPIER,D0 and.l #~MCF_EPORT_EPIER_EPIE7,D0 @@ -6597,6 +7993,8 @@ disable_interrupt: move.l (SP)+,D1 move.w D1,SR move.l (SP)+,D1 + move.l (SP)+,A0 + move.l (SP)+,A1 rts clear_interrupt: @@ -6605,8 +8003,8 @@ clear_interrupt: bne.s .usb_clear rts .usb_clear: - cmp.l #2,D0 - bhi.s .slot_clear + cmp.l #7,D0 + beq.s .slot_clear moveq #5,D0 bset.b D0,MCF_EPORT_EPFR rts @@ -6621,30 +8019,64 @@ test_interrupt: bne.s .usb_test_interrupt move.l MCF_INTC_IPRH,D0 btst #41-32,D0 + seq.b D0 + and.l #1,D0 // 1: interrupt is finished rts .usb_test_interrupt: - cmp.l #2,D0 - bhi.s .slot_test_interrupt + cmp.l #7,D0 + beq.s .slot_test_interrupt move.l MCF_INTC_IPRL,D0 btst #5,D0 + seq.b D0 + and.l #1,D0 // 1: interrupt is finished rts .slot_test_interrupt: move.l MCF_INTC_IPRL,D0 btst #7,D0 + seq.b D0 + and.l #1,D0 // 1: interrupt is finished rts dc.l 0x58425241 // XBRA dc.l 0x5F504349 // _PCI dc.l 0 -int_cfpci: + // INT7 call by software INT2 (can be masked) +int2_pci: // INTA-B + + move.w #0x2700,SR // for FreeRTOS native interrupts + move.l D0,-(SP) + lea -56(SP),SP + movem.l D1-A6,(SP) + move.l #~MCF_INTC_INTFRCL_INTFRC2,D0 + and.l D0,MCF_INTC_INTFRCL + moveq #7,D0 + bsr pci_interrupt + movem.l (SP),D1-A6 + lea 56(SP),SP + move.l #MCF_INTC_IMRL_INT_MASK7,D0 + and.l MCF_INTC_IMRL,D0 + bne.s .not_int7 // INT7 disabled by the handler + move.b MCF_EPORT_EPIER,D0 + or.l #MCF_EPORT_EPIER_EPIE7,D0 // enable + move.b D0,MCF_EPORT_EPIER +.not_int7: + move.l (SP)+,D0 + rte + + dc.l 0x58425241 // XBRA + dc.l 0x5F504349 // _PCI + dc.l 0 + +int5_pci: // INTC-D + move.w #0x2700,SR // for FreeRTOS native interrupts lea -60(SP),SP movem.l D0-A6,(SP) - moveq #0,D0 // bridge + moveq #5,D0 bsr pci_interrupt - move.l MCF_PCI_PCIGSCR,D0 - move.l D0,MCF_PCI_PCIGSCR + moveq #5,D0 + bset.b D0,MCF_EPORT_EPFR // clear interrupt movem.l (SP),D0-A6 lea 60(SP),SP rte @@ -6653,6 +8085,25 @@ int_cfpci: dc.l 0x5F504349 // _PCI dc.l 0 +int7_pci: // INTA-B + + move.l D0,-(SP) + move.b MCF_EPORT_EPIER,D0 + and.l #~MCF_EPORT_EPIER_EPIE7,D0 // disable + move.b D0,MCF_EPORT_EPIER + moveq #7,D0 + bset.b D0,MCF_EPORT_EPFR // clear interrupt + move.l #MCF_INTC_INTFRCL_INTFRC2,D0 + or.l D0,MCF_INTC_INTFRCL // force INT 2 + move.l (SP)+,D0 + rte + +#endif /* MCF547X */ + + dc.l 0x58425241 // XBRA + dc.l 0x5F504349 // _PCI + dc.l 0 + int_pciarb: move.l D0,-(SP) @@ -6669,21 +8120,33 @@ int_xlbpci: move.l D0,-(SP) move.l D1,-(SP) + move.l D2,-(SP) + move.l MCF_PCI_PCIGSCR,D0 // PERR and SERR seems on this interrupt + move.l D0,MCF_PCI_PCIGSCR move.l MCF_PCI_PCIISR,D0 move.l D0,MCF_PCI_PCIISR - move.l #MCF_PCI_PCIICR_REE,D1 + moveq #0,D0 // bridge + moveq #PCICSR,D1 // PCI Command / Status Register + bsr fast_read_config_longword + move.l D0,-(SP) // value + move.l D0,D2 + moveq #0,D0 // bridge + moveq #PCICSR,D1 // PCI Command / Status Register + bsr write_config_longword // clear errors + move.l (SP)+,D0 + move.l #MCF_PCI_PCISCR_PE,D1 and.l D0,D1 - beq.s .no_retry_abort + beq.s .no_parity_error #if 0 // #ifdef DEBUG move.l A0,-(SP) lea debug42(PC),A0 bsr debug_display_string move.l (SP)+,A0 #else - nop -#endif -.no_retry_abort: - move.l #MCF_PCI_PCIICR_IAE,D1 + nop +#endif +.no_parity_error: + move.l #MCF_PCI_PCISCR_MA,D1 and.l D0,D1 beq.s .no_initiator_abort #if 0 // #ifdef DEBUG @@ -6695,7 +8158,7 @@ int_xlbpci: nop #endif .no_initiator_abort: - move.l #MCF_PCI_PCIICR_TAE,D1 + move.l #MCF_PCI_PCISCR_TR,D1 and.l D0,D1 beq.s .no_target_abort #if 0 // #ifdef DEBUG @@ -6707,75 +8170,164 @@ int_xlbpci: nop #endif .no_target_abort: + move.l (SP)+,D2 move.l (SP)+,D1 move.l (SP)+,D0 rte - - dc.l 0x58425241 // XBRA - dc.l 0x5F504349 // _PCI - dc.l 0 - -int5_pci: - lea -60(SP),SP - movem.l D0-A6,(SP) - moveq #1,D0 - bsr pci_interrupt - moveq #5,D0 - bset.b D0,MCF_EPORT_EPFR - movem.l (SP),D0-A6 - lea 60(SP),SP - rte - - dc.l 0x58425241 // XBRA - dc.l 0x5F504349 // _PCI - dc.l 0 - -int7_pci: - - lea -60(SP),SP - movem.l D0-A6,(SP) - moveq #2,D0 - bsr pci_interrupt - moveq #7,D0 - bset.b D0,MCF_EPORT_EPFR - movem.l (SP),D0-A6 - lea 60(SP),SP - rte #endif /* MCF5445X */ #else /* ATARI - CTPCI/PLX9054 */ -enable_interrupt: // there are just a global enable bit on the CTPCI +enable_interrupt: // D0.L: handle - move.l #PCI_IRQ_BASE_VECTOR,D0 - and.l #0xF0,D0 // base vector bits 4-7 - bset #0,D0 // enable - move.l D0,PCI_CTPCI_CONFIG + move.l A0,-(SP) + move.l D1,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // mask interrupts + move.l D0,D1 // handle + beq .end_enable // bridge + move.l #0x5F504349,D0 // _PCI + bsr get_cookie + beq .local_enable // not found + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A0 // used int table + move.l D1,D0 // bus/function(H)/slot(L) + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A0 // offset slot + move.l D1,D0 + swap D0 + ext.l D0 // bus/function + divu #PCI_MAX_FUNCTION,D0 + move.l D0,-(SP) + ext.l D0 // bus + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D0 + add.l D0,A0 // offset bus + move.l (SP)+,D0 + clr.w D0 + swap D0 // function + add.l D0,A0 // offset function + move.l A0,-(SP) + move.l D1,D0 // handle + moveq #PCIIPR,D1 // Interrupt Pin + bsr fast_read_config_byte// 0:no INT, 1:INTA, 2:INTB, 3:INTC, 4:INTD + moveq #0,D1 + move.b D0,D1 + move.l (SP)+,A0 + tst.l D1 + beq.s .end_enable + subq.l #1,D1 + moveq #0,D0 + move.b PCI_INT_HANDLESTOTALSIZE(A0),D0 // slot offset 0-3 + add.l D0,D1 + and.l #3,D1 // INTA-D + addq.l #1,D1 + bset.b D1,PCI_CTPCI_CONFIG_ENABI // mask INTD /INTC / INTB / INTA / LINT + move.b D1,(A0) // use INTx for this handle + bra.s .end_enable +.local_enable: // hardware not works ??? +// bset.b #0,PCI_CTPCI_CONFIG_ENABI // mask INTD /INTC / INTB / INTA / LINT + nop // else GAS produce bug with the previous bra.s .end_enable +.end_enable: + move.w (SP)+,SR + move.l (SP)+,D1 + move.l (SP)+,A0 rts - -disable_interrupt: +disable_interrupt: // D0.L: handle + + movem.l D1/A0-A1,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // mask interrupts + move.l D0,D1 // handle + beq .local_disable // bridge + move.l #0x5F504349,D0 // _PCI + bsr get_cookie + beq .end_disable // not found + add.l #PCI_COOKIE_SIZE+PCI_RSC_HANDLESTOTALSIZE+PCI_DEV_HANDLESTOTALSIZE,D0 + move.l D0,A0 + move.l D0,A1 + move.l D1,D0 // bus/function(H)/slot(L) + mulu #PCI_MAX_FUNCTION,D0 + add.l D0,A1 // offset slot + move.l D1,D0 + swap D0 + ext.l D0 // bus/function + divu #PCI_MAX_FUNCTION,D0 + move.l D0,-(SP) + ext.l D0 // bus + mulu #PCI_MAX_FUNCTION*PCI_MAX_DEVICE,D0 + add.l D0,A1 // offset bus + move.l (SP)+,D0 + clr.w D0 + swap D0 // function + add.l D0,A1 // offset function + move.l A1,-(SP) + move.l A0,-(SP) + move.l D1,D0 // handle + moveq #PCIIPR,D1 // Interrupt Pin + bsr fast_read_config_byte// 0:no INT, 1:INTA, 2:INTB, 3:INTC, 4:INTD + moveq #0,D1 + move.b D0,D1 + move.l (SP)+,A0 + move.l (SP)+,A1 + tst.l D1 + beq.s .end_disable + subq.l #1,D1 + moveq #0,D0 + move.b PCI_INT_HANDLESTOTALSIZE(A1),D0 // slot offset 0-3 + add.l D0,D1 + and.l #3,D1 // INTA-D + clr.b (A1) // not use INTx for this handle + bsr test_int_not_used + bne.s .end_disable // used on another handle + addq.l #1,D1 + bclr.b D1,PCI_CTPCI_CONFIG_ENABI // mask INTD / INTC / INTB / INTA / LINT + bra.s .end_disable +.local_disable: + bclr.b #0,PCI_CTPCI_CONFIG_ENABI // mask INTD / INTC / INTB / INTA / LINT +.end_disable: + move.w (SP)+,SR + movem.l (SP)+,D1/A0-A1 rts - + clear_interrupt: rts test_interrupt: - tst.w D0 // LINT - bne.s .slots_test_interrupt - move.l #INTCSR,D1 // Interrupt Control/Status +#if 0 + tst.w D0 // LINT + bne.s .slots_test_interrupt + move.l #INTCSR,D1 // Interrupt Control/Status bsr read_local_config_longword and.l #0x00F0E000,D0 seq.b D0 - and.l #1,D0 - rts + and.l #1,D0 // 1: interrupt is finished + rts .slots_test_interrupt: - moveq #1,D0 // interrupt is finished +#endif + btst.b D0,PCI_CTPCI_CONFIG_ENABI + beq.s .test_int_disabled + btst.b D0,PCI_CTPCI_CONFIG_PEND // INTD / INTC / INTB / INTA / LINT + seq.b D0 + and.l #1,D0 // 1: interrupt is finished rts - +.test_int_disabled: + moveq #1,D0 // 1: interrupt is finished + rts + +pci_interrupt_rtos: + + move.l 4(SP),D0 + movem.l D2-D7/A2-A6,-(SP) + bsr pci_interrupt + movem.l (SP)+,D2-D7/A2-A6 + rts + + dc.l 0x5F504349 // _PCI + dc.l pci_interrupt_rtos dc.l 0x58425241 // XBRA dc.l 0x5F504349 // _PCI dc.l 0 @@ -6788,6 +8340,8 @@ int_ctpci: movem.l (SP)+,D0-A6 rte + dc.l 0x5F504349 // _PCI + dc.l pci_interrupt_rtos dc.l 0x58425241 // XBRA dc.l 0x5F504349 // _PCI dc.l 0 @@ -6800,6 +8354,8 @@ inta_ctpci: movem.l (SP)+,D0-A6 rte + dc.l 0x5F504349 // _PCI + dc.l pci_interrupt_rtos dc.l 0x58425241 // XBRA dc.l 0x5F504349 // _PCI dc.l 0 @@ -6812,18 +8368,22 @@ intb_ctpci: movem.l (SP)+,D0-A6 rte + dc.l 0x5F504349 // _PCI + dc.l pci_interrupt_rtos dc.l 0x58425241 // XBRA dc.l 0x5F504349 // _PCI dc.l 0 intc_ctpci: - + movem.l D0-A6,-(SP) moveq #3,D0 bsr pci_interrupt movem.l (SP)+,D0-A6 rte + dc.l 0x5F504349 // _PCI + dc.l pci_interrupt_rtos dc.l 0x58425241 // XBRA dc.l 0x5F504349 // _PCI dc.l 0 @@ -6835,82 +8395,8 @@ intd_ctpci: bsr pci_interrupt movem.l (SP)+,D0-A6 rte - -#endif /* COLDFIRE */ - -get_cookie: - -#ifdef COLDFIRE - move.l D1,-(SP) - move.l A0,-(SP) -#else - movem.l D1/A0,-(SP) -#endif - move.l D0,D1 // cookie - move.l cookie,D0 - beq.s .cookie_not_found - move.l D0,A0 -.loop_cookie: - tst.l (A0) - beq.s .cookie_not_found - cmp.l (A0),D1 - bne.s .next_cookie - move.l 4(A0),D0 - bra.s .end_cookie -.next_cookie: - addq.l #8,A0 - bra.s .loop_cookie -.cookie_not_found: - moveq #0,D0 -.end_cookie: -#ifdef COLDFIRE - move.l (SP)+,A0 - move.l (SP)+,D1 -#else - movem.l (SP)+,D1/A0 -#endif - tst.l D0 - rts - -add_cookie: -#ifdef COLDFIRE - lea -12(SP),SP - movem.l D1-D2/A0,(SP) -#else - movem.l D1-D2/A0,-(SP) -#endif - move.l cookie,D2 - beq.s .cookie_not_found_add - move.l D2,A0 - moveq #0,D2 - bra.s .next_cookie_add -.loop_add_cookie: - addq.l #8,A0 - addq.l #1,D2 -.next_cookie_add: - tst.l (A0) - bne.s .loop_add_cookie - cmp.l 4(A0),D2 - bcc.s .cookie_not_found_add - move.l 4(A0),D2 - move.l D0,(A0) // cookie - move.l D1,4(A0) // value - addq.l #8,A0 - clr.l (A0) - move.l D2,4(A0) - moveq #1,D0 // OK - bra.s .end_add_cookie -.cookie_not_found_add: - moveq #0,D0 // error -.end_add_cookie: -#ifdef COLDFIRE - movem.l (SP),D1-D2/A0 - lea 12(SP),SP -#else - movem.l (SP)+,D1-D2/A0 -#endif - rts +#endif /* COLDFIRE */ display_string: @@ -6996,11 +8482,11 @@ tab_pci_device: .byte 16 // host bridge MCF5445X .byte 17,18,19,20 // device number n where AD[n] select IDSEL #else /* MCF548X */ -#ifdef MCF547X /* COLDARI */ +#ifdef MCF547X /* FIREBEE */ .byte 16 // host bridge MCF547X - // AD17 is the USB Controller ISP1563 + // AD17 is the USB Controller // AD18 and more are slots ? - .byte 17,18,19,20 // device number n where AD[n] select IDSEL + .byte 17,18,19,20,21,22,23,24,25,26,27,28,29,30 // device number n where AD[n] select IDSEL #else /* MCF548X - M5484LITE/M5485EVB */ .byte 16 // host bridge MCF548X // on the Fire Engine AD17 is the USB Controller @@ -7011,16 +8497,24 @@ tab_pci_device: #endif /* MCF547X */ #endif /* MCF5445X */ #else /* ATARI - CTPCI/PLX9054 */ - .byte 20-11 // host bridge PLX9054 + .byte 20-11 // host bridge PLX9054 .byte 21-11,22-11,23-11,24-11 // device number n-11 where AD[n] select IDSEL #endif /* COLDFIRE */ +tab_pci_device2: + .byte 0, 1, 2, 3, 4, 5, 6, 7 + .byte 8, 9,10,11,12,13,14,15 + .byte 16,17,18,19,20,21,22,23 + .byte 24,25,26,27,28,29,30,31 pciinfo0: .asciz "Device built before Class Code definitions" +#ifdef DISPLAY_SUBCLASS pciinfo1: .asciz "(All except VGA)" pciinfo2: .asciz "(VGA compatible)" pciinfo9: .asciz "(unknown)" +#endif pciinfo10: .asciz "Mass Storage Controller " +#ifdef DISPLAY_SUBCLASS pciinfo11: .asciz "(SCSI bus)" pciinfo12: .asciz "(IDE)" pciinfo13: .asciz "(Floppy disk)" @@ -7028,8 +8522,10 @@ pciinfo14: .asciz "(IPI bus)" pciinfo15: .asciz "(RAID)" pciinfo16: .asciz "(ATA)" pciinfo17: .asciz "(SATA)" +#endif pciinfo20: .asciz "Network Controller " +#ifdef DISPLAY_SUBCLASS pciinfo21: .asciz "(Ethernet)" pciinfo22: .asciz "(Token Ring)" pciinfo23: .asciz "(FDDI)" @@ -7037,22 +8533,30 @@ pciinfo24: .asciz "(ATM)" pciinfo25: .asciz "(ISDM)" pciinfo26: .asciz "(WorldFip)" pciinfo27: .asciz "(PICMG)" +#endif pciinfo30: .asciz "Display Controller " +#ifdef DISPLAY_SUBCLASS pciinfo31: .asciz "(VGA)" pciinfo32: .asciz "(XGA)" pciinfo33: .asciz "(3D)" +#endif pciinfo40: .asciz "Multimedia Controller " +#ifdef DISPLAY_SUBCLASS pciinfo41: .asciz "(Video)" pciinfo42: .asciz "(Audio)" pciinfo43: .asciz "(Computer Telephony)" +#endif pciinfo50: .asciz "Memory controller " +#ifdef DISPLAY_SUBCLASS pciinfo51: .asciz "(RAM)" pciinfo52: .asciz "(FLASH)" +#endif pciinfo60: .asciz "Bridge Controller " +#ifdef DISPLAY_SUBCLASS pciinfo61: .asciz "(Host Bridge)" pciinfo62: .asciz "(ISA Bridge)" pciinfo63: .asciz "(EISA Bridge)" @@ -7064,33 +8568,43 @@ pciinfo68: .asciz "(CARDBUS Bridge)" pciinfo69: .asciz "(RACE Bridge)" pciinfo610: .asciz "(STPCI Bridge)" pciinfo611: .asciz "(InfiniBand Bridge)" +#endif pciinfo70: .asciz "Communications Controller " +#ifdef DISPLAY_SUBCLASS pciinfo71: .asciz "(XT Compatible Serial)" pciinfo72: .asciz "(Parallel Port)" pciinfo73: .asciz "(Multiport Serial)" pciinfo74: .asciz "(Modem Controller)" pciinfo75: .asciz "(GPIB Controller)" pciinfo76: .asciz "(Smart Card)" +#endif pciinfo80: .asciz "Peripheral Controller " +#ifdef DISPLAY_SUBCLASS pciinfo81: .asciz "(PIC)" pciinfo82: .asciz "(DMA)" pciinfo83: .asciz "(System Timer)" pciinfo84: .asciz "(RTC)" pciinfo85: .asciz "(PCI Hot-Plug)" +#endif pciinfo90: .asciz "Input Device " +#ifdef DISPLAY_SUBCLASS pciinfo91: .asciz "(Keyboard)" pciinfo92: .asciz "(Digitizer)" pciinfo93: .asciz "(Mouse)" pciinfo94: .asciz "(Scanner)" pciinfo95: .asciz "(Gameport)" +#endif pciinfo100: .asciz "Docking Station " +#ifdef DISPLAY_SUBCLASS pciinfo101: .asciz "(Docking Station)" +#endif pciinfo110: .asciz "Processor " +#ifdef DISPLAY_SUBCLASS pciinfo111: .asciz "(386)" pciinfo112: .asciz "(486)" pciinfo113: .asciz "(Pentium)" @@ -7098,8 +8612,10 @@ pciinfo114: .asciz "(Alpha)" pciinfo115: .asciz "(PowerPC)" pciinfo116: .asciz "(MIPS)" pciinfo117: .asciz "(Coprocessor)" +#endif pciinfo120: .asciz "Serial Bus " +#ifdef DISPLAY_SUBCLASS pciinfo121: .asciz "(FireWire)" pciinfo122: .asciz "(ACCESS)" pciinfo123: .asciz "(SSA)" @@ -7110,8 +8626,10 @@ pciinfo127: .asciz "(InfiniBand)" pciinfo128: .asciz "(IPMI)" pciinfo129: .asciz "(SERCOS)" pciinfo1210: .asciz "(CANbus)" +#endif pciinfo130: .asciz "Wireless Controller " +#ifdef DISPLAY_SUBCLASS pciinfo131: .asciz "(iRDA Compatible)" pciinfo132: .asciz "(Consumer IR)" pciinfo133: .asciz "(RF)" @@ -7119,25 +8637,34 @@ pciinfo134: .asciz "(Bluetooth)" pciinfo135: .asciz "(Broadband)" pciinfo136: .asciz "(Ethernet 802.11a)" pciinfo137: .asciz "(Ethernet 802.11b)" +#endif pciinfo140: .asciz "Intelligent IO Controller " +#ifdef DISPLAY_SUBCLASS pciinfo141: .asciz "(I20 Arch)" +#endif pciinfo150: .asciz "Satellite Communication " +#ifdef DISPLAY_SUBCLASS pciinfo151: .asciz "(TV)" pciinfo152: .asciz "(Audio)" pciinfo153: .asciz "(Voice)" pciinfo154: .asciz "(DATA)" +#endif pciinfo160: .asciz "Encrytion/Decryption " +#ifdef DISPLAY_SUBCLASS pciinfo161: .asciz "(Network and Computing)" pciinfo162: .asciz "(Entertainment en/decrypt)" +#endif pciinfo170: .asciz "Signal Processing " +#ifdef DISPLAY_SUBCLASS pciinfo171: .asciz "(DPIO modules)" -pciinfo172: .asciz "(Performance counters)" -pciinfo173: .asciz "(Comm. synchronization)" +pciinfo172: .asciz "(Perf. counters)" +pciinfo173: .asciz "(Comm. synchro)" pciinfo174: .asciz "(Management)" +#endif pciinfo999: .asciz "Device does not fit in any defined classes" @@ -7154,19 +8681,8 @@ scanning_devices: .ascii "CTPCI found, scanning PCI devices..." .byte 13,10,0 .byte 13,10 - .ascii "CTPCI trouve, recherche cartes PCI..." + .ascii "CTPCI trouv‚e, recherche cartes PCI..." .byte 13,10,0 -plx_error_register: - .byte 13,10 - .asciz "PLX write error, register: 0x" - .byte 13,10 - .asciz "PLX erreur ‚criture, registre: 0x" -plx_error_write_value: - .asciz ", write: 0x" - .asciz ", ‚criture: 0x" -plx_error_read_value: - .asciz ", read: 0x" - .asciz ", lecture: 0x" #endif separator: .asciz " | " @@ -7174,46 +8690,39 @@ hor_separator: .ascii "-----------------------------------------------------------------------" .byte 13,10,0 begin_table: - .ascii "Slot | Fctn | VendorID | DeviceID | Description" + .ascii " Bus | Slot | Fctn | VendorID | DeviceID | Description" .byte 13,10,0 +separators: + .byte 13,10 + .asciz " | | | " no_device: .ascii " 0xFFFF | | no device" .byte 13,10,0 no_more_io_space: - .byte 13,10 - .ascii " | | no more IO-space available !!!" + .ascii "no more IO-space available !!!" .byte 13,10,0 no_more_mem_space: - .byte 13,10 - .ascii " | | no more MEM-space !!!" + .ascii "no more MEM-space !!!" .byte 13,10,0 no_more_memory_below_1mb: - .byte 13,10 - .ascii " | | no more memory space below 1 MB !!!" + .ascii "no more memory space below 1 MB !!!" .byte 13,10,0 need_more_than_4gb: - .byte 13,10 - .ascii " | | device requests more than 4GB memory !!!" + .ascii "device requests more than 4GB memory !!!" .byte 13,10,0 unknow_memory_type: - .byte 13,10 - .ascii " | | device requests unknown memory type !!!" + .ascii "device requests unknown memory type !!!" .byte 13,10,0 #ifdef CHECK_PARITY parity_error: - .byte 13,10 - .ascii " | | detected parity error" + .ascii "detected parity error" .byte 13,10,0 #endif -#if 0 desc_io: - .byte 13,10 - .asciz " | | I/O Address " + .asciz "I/O Address " desc_mem: - .byte 13,10 - .asciz " | | MEM Address " + .asciz "MEM Address " desc_size: .asciz " Size " _66mhz: .asciz " 66 MHz" -#endif diff --git a/flash.tos/tos/pmmu.S b/flash.tos/tos/pmmu.S deleted file mode 100644 index fa25577..0000000 --- a/flash.tos/tos/pmmu.S +++ /dev/null @@ -1,141 +0,0 @@ -/* TOS 4.04 patch for the CT60 board - * Copyright (C) 2001 Xavier Joubert - * 2002-2006 Didier Mequignon - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * - * To contact author write to Xavier Joubert, 5 Cour aux Chais, 44 100 Nantes, - * FRANCE or by e-mail to xavier.joubert@free.fr. - * - */ - -#include "main.h" -#ifdef COLDFIRE -#include "fire.h" -#endif - - .text - -#ifdef COLDFIRE - .globl init_cf -#else - .globl init_060 -#endif - - .align 2 - .long 0x30 - .long end1-begin1+0x80000000 -begin1: -#ifdef COLDFIRE - move.l #init_cf-FLASH_ADR+FLASH_TOS_FIRE_ENGINE,D1 - and.l #0xFFFFFF,D1 - lea end1(PC),A0 - move.l A0,D0 - and.l #0xFF000000,D0 - or.l D1,D0 - move.l D0,A0 - jmp (A0) -#else - jmp init_060 -#endif -end1: - - .globl init_sdram - - .align 2 - .long 0x632 - .long end2-begin2+0x80000000 -begin2: - jsr init_sdram -end2: - -#ifdef COLDFIRE - - .align 2 - .long 0x2BC - .long end3-begin3 -begin3: - nop - nop -end3: - -#else - - .align 2 - .long 0x14E6 - .long end3-begin3 -begin3: - // bra.s begin3-0x14E6+0x1506 - rts - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop - nop -end3: - -#endif - - .align 2 - .long 0x39A0 - .long end4-begin4 -begin4: - bra.s begin4-0x39A0+0x39B8 -end4: - - .globl add_sdram - - .align 2 - .long 0x96E - .long end5-begin5+0x80000000 -begin5: - jmp add_sdram -end5: - - .align 2 - .long 0x7A08 - .long end6-begin6 -begin6: - moveq #9,D7 -end6: - - .align 2 - .long 0x7B1C - .long end7-begin7 -begin7: - moveq #9,D7 -end7: - - .globl display_ram_test - - .align 2 - .long 0x7D5A - .long end8-begin8+0x80000000 -begin8: - jmp display_ram_test -end8: - diff --git a/flash.tos/tos/pmmu2.c b/flash.tos/tos/pmmu2.c index 5ee6346..07ca022 100644 --- a/flash.tos/tos/pmmu2.c +++ b/flash.tos/tos/pmmu2.c @@ -1,6 +1,6 @@ /* PMMU tree on the CT60 / MMU on Coldfire * - * Didier Mequignon 2002-2009, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2002-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,15 +20,11 @@ #include #include "main.h" #include "ct60.h" - #include "pci_bios.h" +#include "vars.h" #undef DEBUG -#define phystop 0x42E -#define cookie 0x5A0 -#define ramtop 0x5A4 - #define ZONE_EPROM 0x00E00000 #define END_ZONE_EPROM 0x00F00000 #define ZONE_IO 0x00F00000 @@ -41,18 +37,38 @@ #define END_ZONE_EPROM2 0x00FF0000 #define F030_UNUSED 0x00FF0000 #define END_F030_UNUSED 0x00FF8000 +#define FIREBEE_UNIMPLEMENTED 0x00FF8C00 +#define END_FIREBEE_UNIMPLEMENTED 0x00FF9000 +#define FIREBEE_UNIMPLEMENTED2 0x00FFA000 +#define END_FIREBEE_UNIMPLEMENTED2 0x00FFF800 #define ZONE_SDRAM 0x01000000 #ifdef COLDFIRE +#ifdef MCF5445X +#define NO_CACHE_MEMORY_BASE 0x40F00000 +#else +#define NO_CACHE_MEMORY_BASE 0x00F10000 +#define NO_CACHE_MEMORY_SIZE 0x00090000 +#endif + #define ZONE_IO_MCF5445X MCF_SCM_MPR #define END_ZONE_IO_MCF5445X (MCF_PLL_PCR+0x4000) #define ZONE_IDE_MCF5445X MCF_ATA_TIME_OFF #define ZONE1_SRAM 0xFFF00000 /* MCF5445X */ #define ZONE2_SRAM 0xFFFFE000 /* MCF5445X */ -#define FPGA_ZONE_IO 0xFFF00000 /* COLDARI - ATARI I/O */ -#define FPGA_ZONE_CART 0xFFFA0000 /* COLDARI - ATARI CARTRIDGE */ +#define VIDEO_RAM 0x00D00000 /* FIREBEE */ +#define END_VIDEO_RAM 0x00E00000 /* FIREBEE */ +#define VIDEO_RAM2 0x60000000 /* FIREBEE */ +#define END_VIDEO_RAM2 0x80000000 /* FIREBEE */ +#define FPGA_VIDEO_RAM 0x60D00000 /* FIREBEE */ +#define END_FPGA_VIDEO_RAM 0x60E00000 /* FIREBEE */ +#define FPGA_ACP_IO 0xF0000000 /* FIREBEE */ +#define END_FPGA_ACP_IO 0xF8000000 /* FIREBEE */ +#define FPGA_SRAM 0xF8000000 /* FIREBEE */ +#define END_FPGA_SRAM 0xFC000000 /* FIREBEE */ +#define FPGA_ZONE_IO 0xFFF00000 /* FIREBEE - ATARI I/O */ #define MMUCR (*(volatile unsigned long *)(MMU_BASE+0x0000)) #define MMUOR (*(volatile unsigned long *)(MMU_BASE+0x0004)) @@ -91,8 +107,8 @@ #define MMUSR_HITN 0x02 -#define PAGE_SIZE 8192 -#define MMUDR_PAGE MMUDR_SZ8K +#define PAGE_SIZE 1024 +#define MMUDR_PAGE MMUDR_SZ1K #define PAGE_SIZE_1M 0x100000 #define mmu_map(virt_addr,phys_addr,flag_itlb,flags_mmutr,flags_mmudr) \ @@ -136,6 +152,8 @@ do { \ #else /* ATARI - 68060 */ +#define NO_CACHE_MEMORY_SIZE 0x00080000 + #define GLOBALBIT 0x400 #define SUPERBIT 0x80 #define CACHEMODEBITS 0x60 @@ -180,31 +198,23 @@ do { \ #define SIZE_TREE ((SIZE_LEVEL1+SIZE_LEVEL2+SIZE_LEVEL3+PAGESIZE-1) & ~(PAGESIZE-1)) #define SIZE_PROT (65536L+SIZE_TREE+PAGESIZE) -#endif +extern void apply_patches(char *src, char *dest); -typedef struct -{ - long ident; - union - { - long l; - short i[2]; - char c[4]; - } v; -} COOKIE; +#endif #ifdef COLDFIRE void update_mmu(void) // MMU access fault { unsigned long format, pc, addr; - asm(" .global _update_tlb"); - asm("_update_tlb:"); - asm(" MOVE.W #0x2700,SR"); - asm(" LEA -32(SP),SP"); // + reserve space for jump to old vector - asm(" MOVEM.L D0-D5/A0,(SP)"); // normally it's enough !!! - asm(" MOVE.L 32(SP),%0" : "=d" (format) : ); - asm(" MOVE.L 36(SP),%0" : "=d" (pc) : ); + asm volatile ( + ".global _update_tlb\n\t" + "_update_tlb:\n\t" + " MOVE.W #0x2700,SR\n\t" + " LEA -32(SP),SP\n\t" /* + reserve space for jump to old vector */ + " MOVEM.L D0-D5/A0,(SP)\n\t" /* normally it's enough !!! */ + " MOVE.L 32(SP),%0" : "=d" (format) : ); + asm volatile (" MOVE.L 36(SP),%0\n\t" : "=d" (pc) : ); unsigned long MMU_BASE = (unsigned long)__MMU_BASE; format >>= 16; switch(format & 0x0C03) @@ -214,16 +224,24 @@ void update_mmu(void) // MMU access fault case 0x0401: /* 5: TLB miss on opword instruction */ addr = pc & ~(PAGE_SIZE_1M-1); if((addr < END_ZONE_EPROM) /* STRAM & TOS (1st part) */ - || ((addr >= ZONE_SDRAM) && (addr < SDRAM_SIZE))) + || ((addr >= ZONE_SDRAM) && (addr < SDRAM_SIZE)) #ifdef MCF5445X + ) mmu_remap(addr,addr+PHYSICAL_OFFSET_SDRAM,MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_X); #else /* MCF548X */ + || ((addr >= BOOT_FLASH_BASE) && (addr < BOOT_FLASH_BASE+BOOT_FLASH_SIZE))) mmu_remap(addr,addr,MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_X); #endif else { addr = pc & ~(PAGE_SIZE-1); +#ifdef MCF547X + if((addr >= ZONE_CART) && (addr < END_ZONE_CART)) + mmu_remap(addr,(addr|FPGA_ZONE_IO),MMUOR_ITLB,MMUTR_SG,MMUDR_PAGE+MMUDR_WRITEBACK+MMUDR_X); + else if((addr >= ZONE_EPROM2) && (addr < END_ZONE_EPROM2)) +#else /* MCF548X */ if((addr >= ZONE_CART) && (addr < END_ZONE_EPROM2)) +#endif mmu_remap(addr,addr,MMUOR_ITLB,MMUTR_SG,MMUDR_PAGE+MMUDR_WRITEBACK+MMUDR_X); else /* invalid */ mmu_remap(addr,addr,MMUOR_ITLB,MMUTR_SG,MMUDR_PAGE+MMUDR_NOCACHE); @@ -269,9 +287,18 @@ void update_mmu(void) // MMU access fault mmu_remap(addr,addr+PHYSICAL_OFFSET_SDRAM,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_R); else if((addr >= ZONE_SDRAM) && (addr < SDRAM_SIZE)) mmu_remap(addr,addr+PHYSICAL_OFFSET_SDRAM,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_R+MMUDR_W); +#else /* MCF548X */ +#ifdef MCF547X /* FIREBEE */ + if(addr < VIDEO_RAM) /* STRAM */ + mmu_remap(addr,addr,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + else if((addr >= VIDEO_RAM) && (addr < ZONE_EPROM)) + mmu_remap(addr,addr-VIDEO_RAM+FPGA_VIDEO_RAM,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); + else if((addr >= VIDEO_RAM2) && (addr < END_VIDEO_RAM2)) + mmu_remap(addr,addr,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); #else /* MCF548X */ if(addr < ZONE_EPROM) /* STRAM */ mmu_remap(addr,addr,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITETHROUGH+MMUDR_R+MMUDR_W); +#endif /* MCF547X */ else if((addr >= ZONE_EPROM) && (addr < END_ZONE_EPROM)) mmu_remap(addr,addr,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_R); else if((addr >= ZONE_SDRAM) && (addr < SDRAM_SIZE)) @@ -283,6 +310,10 @@ void update_mmu(void) // MMU access fault else if(((addr >= PCI_MEMORY_OFFSET+(PCI_MEMORY_SIZE/2)) && (addr < PCI_MEMORY_OFFSET+PCI_MEMORY_SIZE)) #else else if(((addr >= PCI_MEMORY_OFFSET) && (addr < PCI_MEMORY_OFFSET+PCI_MEMORY_SIZE)) +#endif +#ifdef MCF547X /* FIREBEE */ + || ((addr >= FPGA_ACP_IO) && (addr < END_FPGA_ACP_IO)) + || ((addr >= FPGA_SRAM) && (addr < END_FPGA_SRAM)) #endif || ((addr >= PCI_IO_OFFSET) && (addr < PCI_IO_OFFSET+PCI_IO_SIZE)) || ((addr >= BOOT_FLASH_BASE) && (addr < BOOT_FLASH_BASE+BOOT_FLASH_SIZE))) @@ -306,16 +337,19 @@ void update_mmu(void) // MMU access fault || ((addr >= ZONE_IO_MCF5445X) && (addr < END_ZONE_IO_MCF5445X)) || (addr == CPLD_BASE) || (addr == FPGA_BASE) #else /* MCF547X - MCF548X */ -#ifdef MCF547X - if((addr >= ZONE_CART) && (addr < END_ZONE_CART)) - mmu_remap(addr,addr+FPGA_ZONE_CART-ZONE_CART,0,MMUTR_SG,MMUDR_PAGE+MMUDR_WRITEBACK+MMUDR_R); - else if((addr == ZONE_IO) // IDE - || ((addr >= END_F030_UNUSED) && (addr < END_ZONE_IO))) - mmu_remap(addr,addr+FPGA_ZONE_IO-ZONE_IO,0,MMUTR_SG,MMUDR_PAGE+MMUDR_NOCACHE+MMUDR_R+MMUDR_W); - else if(((addr >= ZONE_EPROM2) && (addr < END_ZONE_EPROM2)) - || ((addr >= FPGA_ZONE_CART) && (addr < FPGA_ZONE_CART+END_ZONE_CART-ZONE_CART))) +#ifdef MCF547X /* FIREBEE */ + if((addr == ZONE_IO) // IDE + || ((addr >= ZONE_CART) && (addr < END_ZONE_CART)) + || ((addr >= END_F030_UNUSED) && (addr < FIREBEE_UNIMPLEMENTED)) + || ((addr >= END_FIREBEE_UNIMPLEMENTED) && (addr < FIREBEE_UNIMPLEMENTED2)) + || ((addr >= END_FIREBEE_UNIMPLEMENTED2) && (addr < END_ZONE_IO))) + mmu_remap(addr,(addr|FPGA_ZONE_IO),0,MMUTR_SG,MMUDR_PAGE+MMUDR_NOCACHE+MMUDR_R+MMUDR_W); + else if((addr >= ZONE_EPROM2) && (addr < END_ZONE_EPROM2)) mmu_remap(addr,addr,0,MMUTR_SG,MMUDR_PAGE+MMUDR_WRITEBACK+MMUDR_R); - else if((addr == FPGA_ZONE_IO) || (addr >= FPGA_ZONE_IO+END_F030_UNUSED-ZONE_IO) + else if((addr == FPGA_ZONE_IO) // IDE + || ((addr >= FPGA_ZONE_IO+END_F030_UNUSED-ZONE_IO) && (addr < FPGA_ZONE_IO+FIREBEE_UNIMPLEMENTED-ZONE_IO)) + || ((addr >= FPGA_ZONE_IO+END_FIREBEE_UNIMPLEMENTED-ZONE_IO) && (addr < FPGA_ZONE_IO+FIREBEE_UNIMPLEMENTED2-ZONE_IO)) + || (addr >= FPGA_ZONE_IO+END_FIREBEE_UNIMPLEMENTED2-ZONE_IO) || ((addr >= __MBAR) && (addr < __MBAR+0x20000)) #else /* MCF548X */ if((addr >= ZONE_CART) && (addr < END_ZONE_EPROM2)) @@ -323,6 +357,7 @@ void update_mmu(void) // MMU access fault else if((addr == COMPACTFLASH_BASE) || ((addr >= __MBAR) && (addr < __MBAR+0x20000)) #endif /* MCF547X */ + || ((addr >= NO_CACHE_MEMORY_BASE) && (addr < NO_CACHE_MEMORY_BASE+NO_CACHE_MEMORY_SIZE)) #endif /* MCF5445X */ || ((addr >= __MMU_BASE) && (addr < __MMU_BASE+0x10000))) mmu_remap(addr,addr,0,MMUTR_SG,MMUDR_PAGE+MMUDR_NOCACHE+MMUDR_R+MMUDR_W); @@ -356,14 +391,16 @@ void update_mmu(void) // MMU access fault #endif *(unsigned long *)(address_fault) = MMUAR; addr = *(unsigned long *)(save_coldfire_vector); - asm(" MOVE.L %0,28(SP)" : : "d" (addr)); - asm(" MOVEM.L (SP),D0-D5/A0"); - asm(" LEA 28(SP),SP"); - asm(" RTS"); // CF68KLIB + asm volatile ( + " MOVE.L %0,28(SP)\n\t" + " MOVEM.L (SP),D0-D5/A0\n\t" + " LEA 28(SP),SP\n\t" + " RTS" : : "d" (addr) ); /* CF68KLIB */ } - asm(" MOVEM.L (SP),D0-D5/A0"); - asm(" LEA 32(SP),SP"); - asm(" RTE"); + asm volatile ( + " MOVEM.L (SP),D0-D5/A0\n\t" + " LEA 32(SP),SP\n\t" + " RTE" ); } void init_mmu(unsigned long base_pci_drivers, unsigned long size_pci_drivers) @@ -441,10 +478,11 @@ void init_mmu(unsigned long base_pci_drivers, unsigned long size_pci_drivers) *p2++ = 0xFFFFFFFF; size--; } - asm(" MOVE.L D0,-(SP)"); - asm(" MOVE.L %0,D0" : : "d" (MMU_BASE+1)); - asm(" DC.L 0x4E7B0008"); /* MOVEC.L D0,MMUBAR */ - asm(" MOVE.L (SP)+,D0"); + asm volatile ( + " MOVE.L D0,-(SP)\n\t" + " MOVE.L %0,D0\n\t" + " DC.L 0x4E7B0008\n\t" /* MOVEC.L D0,MMUBAR */ + " MOVE.L (SP)+,D0" : : "d" (MMU_BASE+1) ); MMUOR = MMUOR_CA; MMUOR = MMUOR_CA+MMUOR_ITLB; #ifdef MCF5445X @@ -455,108 +493,122 @@ void init_mmu(unsigned long base_pci_drivers, unsigned long size_pci_drivers) } mmu_map(ZONE_EPROM,ZONE_EPROM+PHYSICAL_OFFSET_SDRAM,MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_X+MMUDR_LK); mmu_map(ZONE_EPROM,ZONE_EPROM+PHYSICAL_OFFSET_SDRAM,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_R+MMUDR_LK); + mmu_map(NO_CACHE_MEMORY_BASE,NO_CACHE_MEMORY_BASE,MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_NOCACHE+MMUDR_X+MMUDR_LK); + mmu_map(NO_CACHE_MEMORY_BASE,NO_CACHE_MEMORY_BASE,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_NOCACHE+MMUDR_R+MMUDR_W+MMUDR_LK); mmu_map(RAM_BASE_CF68KLIB,RAM_BASE_CF68KLIB,MMUOR_ITLB,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_X+MMUDR_LK); mmu_map(RAM_BASE_CF68KLIB,RAM_BASE_CF68KLIB,0,MMUTR_SG,MMUDR_SZ1M+MMUDR_WRITEBACK+MMUDR_R+MMUDR_W+MMUDR_LK); #else /* MCF548X */ for(addr=0;addr=VIDEO_RAM) && (addr> 8) & 0xFF0000) + 0xE040; - asm(" MOVE.L %0,D0" : : "d" (ACR_PCI)); - asm(" MOVEC.L D0,ACR0"); // data + asm volatile ( + " MOVE.L %0,D0\n\t" + " MOVEC.L D0,ACR0" : : "d" (ACR_PCI) : "d0" ); /* data */ } /* zone FLASH in cache inhibit precise */ { unsigned long ACR_FLASH = (BOOT_FLASH_BASE & 0xFFF00000) + (((BOOT_FLASH_SIZE-1) >> 4) & 0xF0000) + 0xE440; - asm(" MOVE.L %0,D0" : : "d" (ACR_FLASH)); - asm(" MOVEC.L D0,ACR1"); // data + asm volatile ( + " MOVE.L %0,D0\n\t" + " MOVEC.L D0,ACR1\n\t" /* data */ + " MOVEC.L D0,ACR3" : : "d" (ACR_FLASH) : "d0" ); /* instruction */ } - asm(" MOVEQ #0,D0"); - asm(" MOVEC.L D0,ACR2"); // instruction - asm(" MOVEC.L D0,ACR3"); // instruction + asm volatile ( + " MOVEQ #0,D0\n\t" + " MOVEC.L D0,ACR2" : : : "d0" ); /* instruction */ #else /* MCF547X - MCF548X */ -#ifdef MCF547X - asm(" MOVEQ #0,D0"); - asm(" MOVEC.L D0,ACR0"); // data - asm(" MOVEC.L D0,ACR1"); // data -#else /* MCF548X */ /* zone TT-RAM 48MB in copyback */ - asm(" MOVE.L #0x0201E020,D0"); - asm(" MOVEC.L D0,ACR0"); // data - asm(" MOVE.L #0x0100E020,D0"); - asm(" MOVEC.L D0,ACR1"); // data -#endif /* MCF547X */ + asm volatile ( + " MOVE.L #0x0201E020,D0\n\t" + " MOVEC.L D0,ACR0\n\t" /* data */ + " MOVE.L #0x0100E020,D0\n\t" + " MOVEC.L D0,ACR1" : : : "d0" ); /* data */ /* SDRAM is cacheable */ { unsigned long ACR_SDRAM = (SDRAM_BASE & 0xFF000000) + (((SDRAM_SIZE-1) >> 8) & 0xFF0000) + 0xE000; - asm(" MOVE.L %0,D0" : : "d" (ACR_SDRAM)); - asm(" MOVEC.L D0,ACR2"); // instruction + asm volatile ( + " MOVE.L %0,D0\n\t" + " MOVEC.L D0,ACR2" : : "d" (ACR_SDRAM) : "d0" ); /* instruction */ } - asm(" MOVEQ #0,D0"); - asm(" MOVEC.L D0,ACR3"); // instruction + asm volatile ( + " MOVEQ #0,D0\n\t" + " MOVEC.L D0,ACR3" : : : "d0"); /* instruction */ #endif - asm(" NOP"); - MMUCR = MMUCR_EN; /* enable */ - asm(" NOP"); - asm(" MOVE.L (SP)+,D0"); - asm(" MOVE.W D0,SR"); + asm volatile (" NOP"); + MMUCR = MMUCR_EN; /* enable */ + asm volatile ( + " NOP\n\t" + " MOVE.L (SP)+,D0\n\t" + " MOVE.W D0,SR\n\t" : : : "d0" ); } #else /* ATARI - 68060 */ -long init_mmu_tree(unsigned long base_pci_drivers, unsigned long size_pci_drivers) +void init_mmu_tree(unsigned long base_pci_drivers, unsigned long size_pci_drivers) { - unsigned long end_tree,offset,end_stram,end_sdram,srp_reg,tos_in_ram,offset_tos,offset_drivers; + unsigned long end_tree,offset,end_stram,end_sdram,srp_reg,tos_in_ram,offset_tos,offset_drivers,no_cache_memory; unsigned long ri,pi,pgi,adr,size; unsigned long *p0,*p1,*p2; - COOKIE *p; - tos_in_ram=offset_tos=offset_drivers=0; - if(base_pci_drivers) - tos_in_ram=1; - else - tos_in_ram=(unsigned long)ct60_rw_parameter(CT60_MODE_READ,CT60_PARAM_TOSRAM,tos_in_ram)&1; - end_sdram=*(unsigned long *)ramtop; - if(tos_in_ram && end_sdram) /* copy TOS inside the top of the SDRAM */ + tos_in_ram=offset_tos=offset_drivers=no_cache_memory=0; + end_stram=*(unsigned long *)phystop; /* save phystop before change if PMMU tree in STRAM */ + end_sdram=*(unsigned long *)ramtop; /* save ramtop before change if PMMU tree in SDRAM */ + if(end_sdram) /* copy TOS inside the top of the SDRAM */ { - if(base_pci_drivers) /* 2 parts is possible */ + if(base_pci_drivers) /* 2 parts are possible */ { - *(unsigned long *)ramtop-=(FLASH_SIZE+END_ZONE_EPROM2-ZONE_EPROM2+PCI_DRIVERS_SIZE); + (*(unsigned long *)ramtop)-=(FLASH_SIZE+END_ZONE_EPROM2-ZONE_EPROM2+PCI_DRIVERS_SIZE); offset_tos=tos_in_ram=end_sdram-FLASH_SIZE-(END_ZONE_EPROM2-ZONE_EPROM2+PCI_DRIVERS_SIZE); offset_drivers=end_sdram-PCI_DRIVERS_SIZE; } else { - *(unsigned long *)ramtop-=(FLASH_SIZE+PAGESIZE); + (*(unsigned long *)ramtop)-=(FLASH_SIZE+PAGESIZE); offset_tos=tos_in_ram=end_sdram-FLASH_SIZE; } - p1=(unsigned long *)ZONE_EPROM; /* source */ - p2=(unsigned long *)tos_in_ram; /* target */ + apply_patches((char *)ZONE_EPROM,(char *)tos_in_ram); /* 512KB original TOS */ + p1=(unsigned long *)(ZONE_EPROM+(FLASH_SIZE>>1)); /* source */ + p2=(unsigned long *)(tos_in_ram+(FLASH_SIZE>>1)); /* target */ if(base_pci_drivers) - size=(base_pci_drivers-ZONE_EPROM)>>4; /* size */ + size=((base_pci_drivers-ZONE_EPROM)-(FLASH_SIZE>>1))>>4; /* size */ else - size=FLASH_SIZE>>4; /* size */ + size=FLASH_SIZE>>5; /* size */ while((long)size > 0) { - *p2++ = *p1++; /* copy patched TOS */ + *p2++ = *p1++; /* copy boot TOS */ *p2++ = *p1++; *p2++ = *p1++; *p2++ = *p1++; @@ -620,23 +672,42 @@ long init_mmu_tree(unsigned long base_pci_drivers, unsigned long size_pci_driver } } } - } - else - tos_in_ram=0; - if(end_sdram!=0) srp_reg = (*(unsigned long *)ramtop)-SIZE_TREE-PAGESIZE; - else + } + else /* STRAM only, copy TOS inside the top of the STRAM */ + { + (*(unsigned long *)phystop)-=(FLASH_SIZE+PAGESIZE); + offset_tos=tos_in_ram=end_stram-FLASH_SIZE; + apply_patches((char *)ZONE_EPROM,(char *)tos_in_ram); /* 512KB original TOS */ + p1=(unsigned long *)(ZONE_EPROM+(FLASH_SIZE>>1)); /* source */ + p2=(unsigned long *)(tos_in_ram+(FLASH_SIZE>>1)); /* target */ + size=FLASH_SIZE>>5; /* 2nd part for boot */ + while((long)size > 0) + { + *p2++ = *p1++; /* copy boot TOS */ + *p2++ = *p1++; + *p2++ = *p1++; + *p2++ = *p1++; + size--; + } srp_reg = (*(unsigned long *)phystop)-SIZE_TREE-PAGESIZE; + } srp_reg += (PAGESIZE-1); srp_reg &= ~(PAGESIZE-1); /* alignment adress on PAGESIZE bytes */ end_tree=srp_reg+SIZE_TREE; p0=(unsigned long *)srp_reg; p1=p0+ROOT_TABLE_SIZE; p2=p1+(PTR_TABLE_SIZE*NB_32MB); - end_stram=*(unsigned long *)phystop; offset=0; - if(end_sdram!=0) - *(unsigned long *)ramtop=srp_reg; + if(end_sdram) + { + if(base_pci_drivers) + *(unsigned long *)ramtop=no_cache_memory=(srp_reg&~(NO_CACHE_MEMORY_SIZE-1))-NO_CACHE_MEMORY_SIZE; + else + *(unsigned long *)ramtop=srp_reg; + } + else + *(unsigned long *)phystop=srp_reg; for(ri=0;ri pages 32 MB */ { if(ri=tos_in_ram) { - adr = (ri<<25UL) + (pi<<18UL) + (pgi<<13UL); - if(adr>=srp_reg && adr=ZONE_EPROM && adr=srp_reg && adr=end_stram && adr=ZONE_EPROM && adr=ZONE_EPROM2 && adr TOS 2nd part */ { *p2++ = offset_tos+(WRITETHROUGH+READONLYBIT+RESIDENT); offset_tos+=PAGESIZE; } - else + else /* STRAM => no 2nd part */ *p2++ = INVALID; } else if(adr>=F030_UNUSED && adr=ZONE_SDRAM && adr=ZONE_SDRAM && adr=tos_in_ram) + if(adr>=tos_in_ram) { for(pgi=0;pgi=srp_reg && adr=no_cache_memory) + *p2++ = offset+(NOCACHE+RESIDENT); /* SDRAM without cache */ +// *p2++ = offset+(WRITETHROUGH+RESIDENT); /* SDRAM in WT */ else /* SDRAM */ *p2++ = offset+(WRITEBACK+RESIDENT); offset+=PAGESIZE; } } - } - else if(tos_in_ram && adr>=PCI_DRIVERS_OFFSET && adr=PCI_DRIVERS_OFFSET && adrident) - { - *(p+1) = *p; - p->ident = 0x504D4D55; /* PMMU */ - p->v.l = srp_reg; - break; - } - p++; - } - } - return(tos_in_ram); + asm volatile ( + " MOVE.W SR,-(SP)\n\t" + " OR.W #0x700,SR\n\t" + " CPUSHA BC\n\t" + " PFLUSHA\n\t" + " MOVEC.L %0,URP" : : "d" (srp_reg) ); + asm volatile (" MOVEC.L %0,SRP" : : "d" (srp_reg) ); +// asm volatile (" MOVE.L #0x401FE020,D0"); /* zone at 0x40000000 to 0x5FFFFFFF in copyback */ +// asm volatile (" MOVE.L #0x401FE000,D0"); /* zone at 0x40000000 to 0x5FFFFFFF in writethrough */ +// asm volatile (" MOVE.L #0x401FE040,D0"); /* zone at 0x40000000 to 0x5FFFFFFF in cache inhibed precise */ +#if 1 + asm volatile ( + " MOVE.L #0x403FE040,D0\n\t" /* zone at 0x40000000 to 0x7FFFFFFF in cache inhibed precise */ + " MOVEC.L D0,ITT1\n\t" + " MOVEC.L D0,DTT1\n\t" + " MOVE.L #0x807FE040,D0" ); /* zone at 0x80000000 to 0xFFFFFFFF in cache inhibed precise */ +#else + asm volatile ( + " MOVE.L #0xE00FE044,D0\n\t" /* zone at 0xE0000000 to 0xEFFFFFFF in cache inhibed precise + write protect */ + " MOVEC.L D0,ITT1\n\t" + " MOVEC.L D0,DTT1\n\t" + " MOVE.L #0xF00FE040,D0" ); /* zone at 0xF0000000 to 0xFFFFFFFF in cache inhibed precise */ +#endif + asm volatile ( + " MOVEC.L D0,ITT0\n\t" + " MOVEC.L D0,DTT0\n\t" + " MOVE.L #0xC210,D0\n\t" /* enable, 8Ko, cache inhibed by default */ + " MOVEC.L D0,TC\n\t" + " MOVE.W (SP)+,SR" ); } #endif diff --git a/flash.tos/tos/temp.S b/flash.tos/tos/temp.S new file mode 100644 index 0000000..4d535ec --- /dev/null +++ b/flash.tos/tos/temp.S @@ -0,0 +1,168 @@ +/* XBIOS CT60, Read the 68060 temperature on the TLV0831 DC from Texas I. +* +* Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License as published by the Free Software Foundation; either +* version 2.1 of the License, or (at your option) any later version. +* +* This library 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 +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this library; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef COLDFIRE + +#include "ct60.h" + +#define MES_TEMP_0 197 +#define MES_TEMP_25 208 +#define MES_TEMP_50 218 +#define MES_TEMP_100 236 +#define MES_TEMP_ERROR 255 + +#define _iera_mfp 0xfffffa07 // MFP registers +#define _ipra_mfp 0xfffffa0b +#define _isra_mfp 0xfffffa0f +#define _imra_mfp 0xfffffa13 +#define _tbcr_mfp 0xfffffa1b +#define _tbdr_mfp 0xfffffa21 // timer B +#define _tcdr_mfp 0xfffffa23 // value changed at each 26 uS by system (timer C at 200 Hz) +#define _texas_tlv0831_data 0xf1000000 // read from D0 (THDA) +#define _texas_tlv0831_cs_low 0xf1400000 // CS at 0 (/THCS) +#define _texas_tlv0831_cs_high 0xf1000000 // CS at 1 (THCS) +#define _texas_tlv0831_clk_low 0xf1800000 // CLK at 0 (/THCK) +#define _texas_tlv0831_clk_high 0xf1c00000 // CLK at 1 (THCK) + +#define CT60_READ_ERROR -1 + + .globl ct60_read_temp + + .text + +ct60_read_temp: + + movem.l D1-D3/A0-A2,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + lea ct1(PC),A0 + move.l 8,A1 // bus error + move.l A0,8 + move.l SP,A2 + lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19,2 KHz) + tst.b _tbcr_mfp + bne ct8 // timer B used + bclr #0,_imra_mfp + bclr #0,_iera_mfp + bclr #0,_ipra_mfp + bclr #0,_isra_mfp + lea _tbdr_mfp,A0 + move.b #2,(A0) // clock = 307,2 KHz 1,6 uS + move.b #1,_tbcr_mfp // 2,4576MHz/4 +ct8: + clr.l _texas_tlv0831_cs_low // cs=0 + move.b (A0),D0 +wait1: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait1 + clr.l _texas_tlv0831_clk_high // clk=1 (10 to 600 KHz for the tlv0831) + move.b (A0),D0 +wait2: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait2 + clr.l _texas_tlv0831_clk_low // clk=0 + move.b (A0),D0 +wait3: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait3 + clr.l _texas_tlv0831_clk_high // clk=1 + move.b (A0),D0 +wait4: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait4 + clr.l _texas_tlv0831_clk_low // clk=0 + move.b (A0),D0 +wait5: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait5 + move.l A1,8 + move.l A2,SP + move.w (SP),SR + moveq #0,D3 // data + moveq #7,D2 // 8 bits +ct4: clr.l _texas_tlv0831_clk_high // clk=1 + move.l _texas_tlv0831_data,d1 + lsr.l #1,D1 // data + addx.w D3,D3 + move.b (A0),D0 +wait6: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait6 + clr.l _texas_tlv0831_clk_low // clk=0 + move.b (A0),D0 +wait7: + cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) + beq.s wait7 + dbf D2,ct4 + clr.l _texas_tlv0831_cs_high // cs=1 + cmp.w #MES_TEMP_ERROR,D3 // error + beq.s ct3 + moveq #0,D2 // value + moveq #CT60_PARAM_OFFSET_TLV,D1 // type_param + moveq #CT60_MODE_READ,D0 // read + bsr ct60_rw_param + add.l D3,D0 // offset + bmi.s ct5 + cmp.w #MES_TEMP_0,D0 + bcs.s ct5 + cmp.w #MES_TEMP_25,D0 + bcc.s ct6 + sub.w #MES_TEMP_0,D0 + mulu #25,D0 + divu #(MES_TEMP_25-MES_TEMP_0),D0 + ext.l D0 + bra.s ct2 +ct6: + cmp.w #MES_TEMP_50,D0 + bcc.s ct7 + sub.w #MES_TEMP_25,D0 + mulu #25,D0 + divu #(MES_TEMP_50-MES_TEMP_25),D0 + add.w #25,D0 + ext.l D0 + bra.s ct2 +ct7: + sub.w #MES_TEMP_50,D0 + mulu #50,D0 + divu #(MES_TEMP_100-MES_TEMP_50),D0 + add.w #50,D0 + ext.l D0 + bra.s ct2 +ct5: + moveq #0,D0 + bra.s ct2 +ct3: + moveq #CT60_READ_ERROR,D0 // error + bra.s ct2 +ct1: + moveq #CT60_READ_ERROR,D0 // bus error + move.l A1,8 + move.l A2,SP +ct2: + lea _tbdr_mfp,A1 + cmp.l A0,A1 + bne.s ct9 // timer C + clr.b _tbcr_mfp // timer B stopped +ct9: + move (SP)+,SR + tst.l D0 + movem.l (SP)+,D1-D3/A0-A2 + rts + +#endif /* !COLDFIRE */ diff --git a/flash.tos/tos/vectors2.S b/flash.tos/tos/vectors2.S index d774d5e..954a661 100644 --- a/flash.tos/tos/vectors2.S +++ b/flash.tos/tos/vectors2.S @@ -1,6 +1,6 @@ -/* Init Vectors, ISP/FPSP patchs on the CT60 board +/* Init Vectors, ISP/FPSP patchs on the CT60 board, Exception handler * - * Didier Mequignon 2001-2004, e-mail: aniplay@wanadoo.fr + * Didier Mequignon 2001-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,36 +16,93 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - .text +#include "main.h" +#include "vars.h" +#ifdef COLDFIRE +#include "fire.h" +#else +#include "pci_bios.h" +#endif + +// #define DEBUG + + .text + .globl init_vectors .globl _init_emulation_vectors - + .globl exception + #ifdef COLDFIRE .globl null -#include "fire.h" -#endif +null: + clr.l 0x380 // not valid + move.l SP,0x3C0 + move.l A6,0x3BC + lea 0x384,A6 + movem.l D0-D7/A0-A5,(A6) + clr.l 0x3C8 // USP + moveq #-1,D1 + jmp exception -#include "main.h" -#include "vars.h" +#endif /* COLDFIRE */ init_vectors: cmp.l (A1)+,D2 - bne.s next_vect + bne.s .next_vect #ifdef COLDFIRE ext.l D0 #endif move.l A0,-4(A1) -next_vect: +.next_vect: add.l D1,A0 #ifdef COLDFIRE subq.l #1,D0 bpl.s init_vectors -#else +#else /* !COLDFIRE */ dbf D0,init_vectors -#endif + move.l A0,0x100 // MFP IO0 + move.l A0,0x11C // MFP IO5 + move.l A0,0x120 // MFP timer B + move.l A0,0x134 // MFP timer A + move.l A0,0x138 // MFP IO6 + move.l A0,0x13C // MFP IO7 + move.l A1,-(SP) + lea 0x140,A1 + moveq #15,D0 +.int_vectors: + move.l A0,(A1)+ +#ifdef COLDFIRE + subq.l #1,D0 + bpl.s .int_vectors +#else + dbf D0,.int_vectors +#endif + lea 0x1C0,A1 + move.l #143,D0 +.int_vectors2: + cmp.l #0xE80000,(A1) + bcs.s .bad_int_vect2 + cmp.l #0xF00000,(A1) + bcs.s .next_vect2 + cmp.l #0xFC0000,(A1) + bcs.s .bad_int_vect2 + cmp.l #0xFF0000,(A1) + bcs.s .next_vect2 +.bad_int_vect2: + move.l A0,(A1) +.next_vect2: + addq.l #4,A1 +#ifdef COLDFIRE + subq.l #1,D0 + bpl.s .int_vectors2 +#else + dbf D0,.int_vectors2 +#endif + move.l (SP)+,A1 +#endif /* COLDFIRE */ _init_emulation_vectors: @@ -346,3 +403,816 @@ _top_fpsp: #include "../nonfree/fpsp.S" #endif // COLDFIRE + +exception: + + clr.l memvalid + lea.l mess1(PC),A0 + bsr display_string +#ifdef COLDFIRE + ext.l D1 + addq.l #1,D1 + move.l D1,D7 // vector number +#else + addq.w #1,D1 + move.w D1,D7 // vector number +#endif + moveq #0,D0 + move.w D7,D0 +#ifdef COLDFIRE + .chip 68060 + divu #10,D0 + .chip 5200 + move.l D0,D1 + and.l #7,D0 + beq.s .ex1 + or.l #0x30,D0 + bsr display_char +.ex1: + swap D1 + move.w D1,D0 + or.l #0x30,D0 +#else + divu #10,D0 + and.w #7,D0 + beq.s .ex1 + or.w #0x30,D0 + bsr display_char +.ex1: + swap d0 + or.w #0x30,D0 +#endif + bsr display_char + moveq #0x3A,D0 + bsr display_char + moveq #0x20,D0 + bsr display_char + lea.l tab_mess_exc(PC),A0 + move.w D7,D0 + bsr display_tab + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char +#ifdef COLDFIRE + tst.w D7 + beq .ex0 +#endif + lea.l mess2(PC),A0 // SR + bsr display_string +#ifdef COLDFIRE + move.w save_sr,D0 // SR +#else + move.l 0x3C0,A0 //SSP + move.w (A0),D0 +#endif + bsr hex_word // SR + lea.l mess3(PC),A0 + bsr display_string +#ifdef COLDFIRE + move.w save_sr,D2 // SR + and.l #0xB71F,D2 +#else + move.l 0x3C0,A0 //SSP + move.w (A0),D2 // SR + and.w #0xB71F,D2 +#endif + lea.l tab_status(PC),A1 + moveq #15,D1 +.ex5: + btst.l D1,D2 + beq.s .ex6 + moveq #0,D0 + move.b (A1,D1),D0 + move.w D0,D3 +#ifdef COLDFIRE + and.l #0xF8,D3 + cmp.l #0x30,D3 +#else + and.w #0xF8,D3 + cmp.w #0x30,D3 +#endif + bne.s .ex4 + move.w D0,-(SP) + moveq #0x49,D0 // I + bsr display_char + move.w (SP)+,D0 +.ex4: + bsr display_char + moveq #0x20,D0 + bsr display_char +.ex6: +#ifdef COLDFIRE + subq.l #1,D1 + bpl.s .ex5 +.ex0: +#else + dbf D1,.ex5 +#endif + lea.l mess4(PC),A0 // PC + bsr display_string +#ifdef COLDFIRE + move.l save_pc,D0 // PC +#else + move.l 0x3C0,A0 // SSP + move.l 2(A0),D0 // PC +#endif + bsr hex_long + lea.l mess10(PC),A0 // Basepage + bsr display_string + move.l 0x6EE4,D0 + bsr hex_long +#ifdef COLDFIRE + tst.w D7 + beq .ex2 +#endif + lea.l mess5(PC),A0 // CACR + bsr display_string +#ifdef COLDFIRE + .chip 68060 + movec.l CACR,D0 // from value stored in the CF68KLIB + .chip 5200 + bsr hex_long + cmp.l #2,D7 + bne.s .ex2 + lea.l mess6(PC),A0 // address fault + bsr display_string + move.l address_fault,D0 // from value stored in the CF68KLIB + bsr hex_long +#else /* ATARI - CT60 */ + movec.l CACR,D0 + bsr hex_long + cmp.w #2,D7 + beq.s .ex3 // Acces Fault + cmp.w #3,D7 + beq.s .ex3 // Adress Error + cmp.w #5,D7 + beq.s .ex3 // Zero Divide + cmp.w #9,D7 + bne .ex2 // <> Trace +.ex3: + lea.l mess6(PC),A0 // address fault + bsr display_string + move.l 0x3C0,A0 // SSP + move.l 8(A0),D0 // address fault + bsr hex_long + cmp.w #2,D7 + bne .ex2 // <> Acces Fault + lea.l mess7(PC),A0 // FSLW + bsr display_string + move.l 0x3C0,A0 // SSP + move.l 12(A0),D0 // FSLW + bsr hex_long + lea.l mess3(PC),A0 + bsr display_string + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char + move.l 0x3C0,A0 // SSP + move.l 12(A0),D2 // FSLW + and.l #0x0BFFFFFD,D2 + lea.l tab_fslw1(PC),A1 + lea.l tab_fslw2(PC),A2 + lea.l tab_fslw3(PC),A3 + moveq #31,D1 + moveq #0,D3 +.ex13: + btst.l D1,D2 + beq.s .ex14 + moveq #0,D0 + move.b (A1,D3),D0 + bsr display_char + moveq #0,D0 + move.b (A2,D3),D0 + cmp.b #0x20,D0 + beq.s .ex12 + bsr display_char + moveq #0,D0 + move.b (A3,D3),D0 + cmp.b #0x20,D0 + beq.s .ex12 + bsr display_char +.ex12: + moveq #0x20,D0 + bsr display_char +.ex14: + addq.w #1,D3 + dbf D1,.ex13 +#endif /* COLDFIRE */ +.ex2: + lea.l mess8(PC),A0 // SSP + bsr display_string + move.l 0x3C0,D0 // SSP + bsr hex_long + lea.l mess9(PC),A0 // USP + bsr display_string + move.l 0x3C8,D0 // USP + bsr hex_long + lea.l 0x384,A1 // registers + lea.l 32(A1),A2 + moveq #7,D1 +.ex8: + moveq #13,D0 + bsr display_char + moveq #10,D0 + bsr display_char + moveq #0x44,D0 + bsr display_char + moveq #7,D0 +#ifdef COLDFIRE + sub.l D1,D0 + or.l #0x30,D0 +#else + sub.w D1,D0 + or.w #0x30,D0 +#endif + move.w D0,-(SP) + bsr display_nb + move.l (A1),D0 + bsr hex_long // data registers + moveq #0x20,D0 + bsr display_char + tst.w D1 + beq.s .ex9 + moveq #0x41,D0 + bsr display_char + move.w (SP),D0 + bsr display_nb + move.l (A2),D0 + bsr hex_long // address registers + moveq #0x20,D0 + bsr display_char +.ex9: + addq.l #2,SP + addq.l #4,A1 + addq.l #4,A2 +#ifdef COLDFIRE + subq.l #1,D1 + bpl.s .ex8 +#else + dbf D1,.ex8 +#endif + moveq #13,D0 + bsr display_char +.loop_wait_key: +#ifdef COLDFIRE +#ifdef DEBUG + move.w #1,-(SP) // AUX +#else + move.w #2,-(SP) // CON +#endif +#else + move.w #2,-(SP) // CON +#endif + move.w #2,-(SP) // Bconin + trap #13 + addq.l #4,SP + ext.l D0 + move.l D0,-(SP) + move.l #0x5F504349,D0 + lea 0xED0000,A0 // 128 KB + cmp.l (A0),D0 // _PCI + beq.s .pci_drivers + lea 0xEC0000,A0 // 192 KB + cmp.l (A0),D0 // _PCI + beq.s .pci_drivers + lea 0xEB0000,A0 // 256 KB + cmp.l (A0),D0 // _PCI + beq.s .pci_drivers + lea 0xEA0000,A0 // 320 KB + cmp.l (A0),D0 // _PCI + bne.s .no_pci_drivers +.pci_drivers: + jsr 40(A0) // drivers PCI in flash, add dbug (68k disassembler) + move.l D0,(SP) + bne .no_pci_drivers + addq.l #4,SP + bra.s .loop_wait_key +.no_pci_drivers: + move.l (SP)+,D0 +#ifdef COLDFIRE + and.l #0xFF,D0 + cmp.l #0x6D,D0 // m +#else + cmp.b #0x6D,D0 // m +#endif + beq.s .memory_dump +#ifdef COLDFIRE + cmp.l #0x70,D0 // p +#else + cmp.b #0x70,D0 // p +#endif + beq.s .patch_memory +#ifdef DEBUG +#ifdef COLDFIRE + cmp.l #0x20,D0 +#else + cmp.b #0x20,D0 +#endif + bne .loop_wait_key + lea mess14(PC),A0 + bsr display_string +#endif + rts +.memory_dump: + lea mess11(PC),A0 // memory dump + bsr display_string + bsr get_hex_value + move.l D0,A0 + bsr dump + bra .loop_wait_key +.patch_memory: + lea mess12(PC),A0 // patch memory + bsr display_string + bsr get_hex_value + move.l D0,A1 + lea mess13(PC),A0 // value + bsr display_string + bsr get_hex_value + cmp.l #0x100,D0 + bcc.s .word_value + move.b D0,(A1) + lea crlf(PC),A0 + bsr display_string + move.l A1,D0 + bsr hex_long + moveq #0x20,D0 + bsr display_char + move.b (A1),D0 + bsr hex_byte + bra .loop_wait_key +.word_value: + cmp.l #0x10000,D0 + bcc.s .long_value + move.w D0,(A1) + lea crlf(PC),A0 + bsr display_string + move.l A1,D0 + bsr hex_long + moveq #0x20,D0 + bsr display_char + move.w (A1),D0 + bsr hex_word + bra .loop_wait_key +.long_value: + move.l D0,(A1) + lea crlf(PC),A0 + bsr display_string + move.l A1,D0 + bsr hex_long + moveq #0x20,D0 + bsr display_char + move.l (A1),D0 + bsr hex_long + bra .loop_wait_key + +display_nb: + + bsr display_char + moveq #0x3A,D0 + bsr display_char + moveq #0x24,D0 + bsr display_char + rts + +display_tab: + +#ifdef COLDFIRE + move.l D1,-(SP) +#endif + move.w D0,-(SP) + moveq #0,D0 +.dt1: +#ifdef COLDFIRE + move.b (A0),D1 + extb.l D1 + cmp.l #-1,D1 + beq.s .dt3 + moveq #0,D1 + move.w (SP),D1 + cmp.l D1,D0 +#else + cmp.b #-1,(A0) + beq.s .dt3 + cmp.w (SP),D0 +#endif + beq.s .dt4 +.dt2: + tst.b (A0)+ + bne.s .dt2 +#ifdef COLDFIRE + addq.l #1,D0 +#else + addq.w #1,D0 +#endif + bra.s .dt1 +.dt4: + bsr display_string +.dt3: + + addq.l #2,SP +#ifdef COLDFIRE + move.l (SP)+,D1 +#endif + rts + +hex_long: + move.l D0,-(SP) + swap D0 + bsr.s hex_word + move.l (SP)+,D0 +hex_word: + move.w D0,-(SP) +#ifdef COLDFIRE + lsr.l #8,D0 + bsr.s hex_byte + move.w (SP)+,D0 +hex_byte: + move.w D0,-(SP) + lsr.l #4,D0 + bsr.s hex_char + move.w (SP)+,D0 +hex_char: + and.l #0xF,D0 + or.l #0x30,D0 + cmp.l #0x3A,D0 + bcs.s display_char + addq.l #7,D0 + +display_char: + and.l #0xFF,D0 +#ifdef DEBUG /* warning !!! If serial mouse */ + move.l D1,-(SP) +.wait_uart: + move.b MCF_UART_USR0,D1 + and.l #MCF_UART_USR_TXRDY,D1 + beq.s .wait_uart + move.b D0,MCF_UART_UTB0 // send the character + move.l (SP)+,D1 +#else +#if 1 + lea -60(SP),SP + movem.l D0-A6,(SP) + move.l D0,D1 + move.l con_state,A0 + jsr (A0) + movem.l (SP),D0-A6 + lea 60(SP),SP +#else + lea -24(SP),SP + movem.l D0-D2/A0-A2,(SP) + move.w D0,-(SP) + move.w #2,-(SP) + move.w #3,-(SP) // Bconout + trap #13 + addq.l #6,SP + movem.l (SP),D0-D2/A0-A2 + lea 24(SP),SP +#endif +#endif /* DEBUG */ + rts +#else /* ATARI */ + lsr.w #8,D0 + bsr.s hex_byte + move.w (SP)+,D0 +hex_byte: + move.w D0,-(SP) + lsr.b #4,D0 + bsr.s hex_char + move.w (SP)+,D0 +hex_char: + and.b #0xF,D0 + or.b #0x30,D0 + cmp.b #0x3A,D0 + bcs.s display_char + addq.b #7,D0 + +display_char: + and.l #0xFF,D0 +#if 1 + lea -60(SP),SP + movem.l D0-A6,(SP) + move.l D0,D1 + move.l con_state,A0 + jsr (A0) + movem.l (SP),D0-A6 + lea 60(SP),SP +#else + movem.l D0-D2/A0-A2,-(SP) + move.w D0,-(SP) + move.w #2,-(SP) + move.w #3,-(SP) // Bconout + trap #13 + addq.l #6,SP + movem.l (SP)+,D0-D2/A0-A2 +#endif + rts +#endif /* COLDFIRE */ + +display_string: + +#ifdef COLDFIRE + move.l D0,-(SP) + move.l A0,-(SP) +#else + movem.l D0/A0,-(SP) +#endif +.os2: + move.b (A0)+,D0 + beq.s .os1 + bsr display_char + bra.s .os2 +.os1: +#ifdef COLDFIRE + move.l (SP)+,A0 + move.l (SP)+,D0 +#else + movem.l (SP)+,D0/A0 +#endif + rts + +get_hex_value: + +#ifdef COLDFIRE + lea -56(SP),SP + movem.l D1-A5,(SP) + link A6,#-8 + moveq #0,D7 +.loop_get_value: +#ifdef DEBUG + move.w #1,-(SP) // AUX +#else + move.w #2,-(SP) // CON +#endif + move.w #2,-(SP) // Bconin + trap #13 + addq.l #4,SP + and.l #0xFF,D0 + cmp.l #13,D0 + beq.s .conv_get_value + cmp.l #8,D0 + bne.s .not_backspace + tst.w D7 + ble.s .loop_get_value + bsr display_char + subq.l #1,D7 + bra.s .loop_get_value +.not_backspace: + cmp.l #0x30,D0 + bcs.s .loop_get_value + cmp.l #0x39,D0 + bls.s .number_value + cmp.l #0x41,D0 + bcs.s .loop_get_value + cmp.l #0x46,D0 + bls.s .letter_value + cmp.l #0x61,D0 + bcs.s .loop_get_value + cmp.l #0x66,D0 + bhi.s .loop_get_value +.letter_value: + bsr display_char + and.l #0x0F,D0 + add.l #9,D0 + bra.s .store_value +.number_value: + bsr display_char + and.l #0x0F,D0 +.store_value: + move.b D0,-8(A6,D7) + addq.l #1,D7 + cmp.l #8,D7 + bcs .loop_get_value +.conv_get_value: + moveq #0,D0 + subq.l #1,D7 + bmi.s .end_get_value + moveq #0,D6 +.loop_value: + asl.l #4,D0 + moveq #0,D1 + move.b -8(A6,D6),D1 + or.l D1,D0 + addq.l #1,D6 + subq.l #1,D7 + bpl.s .loop_value +.end_get_value: + tst.l D0 + unlk A6 + movem.l (SP),D1-A5 + lea 56(SP),SP +#else /* ATARI */ + movem.l D1-A5,-(SP) + link A6,#-8 + moveq #0,D7 +.loop_get_value: + move.w #2,-(SP) // CON + move.w #2,-(SP) // Bconin + trap #13 + addq.l #4,SP + cmp.b #13,D0 + beq.s .conv_get_value + cmp.b #8,D0 + bne.s .not_backspace + tst.w D7 + ble.s .loop_get_value + bsr display_char + subq.w #1,D7 + bra.s .loop_get_value +.not_backspace: + cmp.b #0x30,D0 + bcs.s .loop_get_value + cmp.b #0x39,D0 + bls.s .number_value + cmp.b #0x41,D0 + bcs.s .loop_get_value + cmp.b #0x46,D0 + bls.s .letter_value + cmp.b #0x61,D0 + bcs.s .loop_get_value + cmp.b #0x66,D0 + bhi.s .loop_get_value +.letter_value: + bsr display_char + and.b #0x0F,D0 + add.b #9,D0 + bra.s .store_value +.number_value: + bsr display_char + and.b #0x0F,D0 +.store_value: + move.b D0,-8(A6,D7) + addq.w #1,D7 + cmp.w #8,D7 + bcs.s .loop_get_value +.conv_get_value: + moveq #0,D0 + subq.w #1,D7 + bmi.s .end_get_value + moveq #0,D6 +.loop_value: + asl.l #4,D0 + or.b -8(A6,D6),D0 + addq.w #1,D6 + dbf D7,.loop_value +.end_get_value: + tst.l D0 + unlk A6 + movem.l (SP)+,D1-A5 +#endif /* COLDFIRE */ + rts + +dump: + +#ifdef COLDFIRE + lea -20(SP),SP + movem.l D0-D2/A0-A1,(SP) +#else + movem.l D0-D2/A0-A1,-(SP) +#endif + move.l A0,A1 + moveq #3,D1 +.loop_dump1: + lea crlf(PC),A0 + bsr display_string + move.l A1,D0 + bsr hex_long + moveq #0x20,D0 + bsr display_char + moveq #15,D2 +.loop_dump2: + move.b (A1)+,D0 + bsr hex_byte + moveq #0x20,D0 + bsr display_char +#ifdef COLDFIRE + subq.l #1,D2 + bpl.s .loop_dump2 +#else + dbf D2,.loop_dump2 +#endif + lea -16(A1),A1 + moveq #15,D2 +.loop_dump3: + move.b (A1)+,D0 +#ifdef COLDFIRE + and.l #0xFF,D0 + cmp.l #0x20,D0 + bcs.s .dump_bad_char + cmp.l #0x7F,D0 +#else + cmp.b #0x20,D0 + bcs.s .dump_bad_char + cmp.b #0x7F,D0 +#endif + bcs.s .dump_ok +.dump_bad_char: + moveq #0x2E,D0 +.dump_ok: + bsr display_char +#ifdef COLDFIRE + subq.l #1,D2 + bpl.s .loop_dump3 + subq.l #1,D1 + bpl.s .loop_dump1 + movem.l (SP),D0-D2/A0-A1 + lea 20(SP),SP +#else + dbf D2,.loop_dump3 + dbf D1,.loop_dump1 + movem.l (SP)+,D0-D2/A0-A1 +#endif + rts + +crlf: .byte 13,10,0 +mess1: .byte 13,10 + .asciz "EXCEPTION PROCESSING " +mess2: .byte 13,10 + .asciz "Status Register (SR): $" +mess3: .asciz ", bits to 1: " +mess4: .byte 13,10 + .asciz "Program Counter (PC): $" +mess5: .byte 13,10 + .asciz "Cache Register (CACR): $" +mess6: .byte 13,10 + .asciz "Address Fault: $" +mess7: .byte 13,10 + .asciz "Fault Status Word (FSLW): " +mess8: .byte 13,10 + .asciz "Supervisor Stack (SSP): $" +mess9: .byte 13,10 + .asciz "User Stack (USP): $" +mess10: .byte 13,10 + .asciz "Basepage: $" +mess11: .byte 13,10 + .asciz "Memory dump (hex) ? " +mess12: .byte 13,10 + .asciz "Patch memory (hex) ? " +mess13: .byte 13,10 + .asciz "Value (hex) ? " +mess14: .byte 13,10 + .ascii "Pterm" + .byte 13,10,0 + +tab_mess_exc: +#ifdef COLDFIRE + .asciz "Null (jump or call)" +#else + .byte 0 +#endif + .byte 0 + .asciz "Access Fault" + .asciz "Address Error" + .asciz "Illegal Instruction" + .asciz "Integer Zero Divide" + .byte 0 + .byte 0 + .asciz "Privilege Violation" + .asciz "Trace" + .asciz "Line A" + .asciz "Line F" + .asciz "Emulator Interrupt" + .byte 0 + .asciz "Format Error" + .asciz "Uninitialised Interrupt" + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .byte 0 + .asciz "Spurious Interrupt" + .asciz "Interrupt level 1" + .asciz "Interrupt level 2" + .asciz "Interrupt level 3" + .asciz "Interrupt level 4" + .asciz "Interrupt level 5" + .asciz "Interrupt level 6" + .asciz "Interrupt level 7" + .asciz "Trap #0" + .asciz "Trap #1" + .asciz "Trap #2" + .asciz "Trap #3" + .asciz "Trap #4" + .asciz "Trap #5" + .asciz "Trap #6" + .asciz "Trap #7" + .asciz "Trap #8" + .asciz "Trap #9" + .asciz "Trap #10" + .asciz "Trap #11" + .asciz "Trap #12" + .asciz "Trap #13" + .asciz "Trap #14" + .asciz "Trap #15" + .byte -1 + +tab_status: .ascii "CVZNX 012 MS T" + +tab_fslw1: .ascii " M LRWSSTTTTTIPSPPIPSWTRWTB S" +tab_fslw2: .ascii " A K ZZTTMMMOBBTTLFPPWEETP S" +tab_fslw3: .ascii " 1010210 EEAB E RE E" + diff --git a/flash.tos/tos/version.S b/flash.tos/tos/version.S index 7a48cda..fb6c276 100644 --- a/flash.tos/tos/version.S +++ b/flash.tos/tos/version.S @@ -1,5 +1,5 @@ /* TOS 4.04 boot version for for the CT60 board -* Didier Mequignon 2003-2008, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2003-2010, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -23,4 +23,5 @@ .align 2 .short VERSION - .short DATE + .short DATE // 10 bytes + diff --git a/flash.tos/tos/videl2.S b/flash.tos/tos/videl2.S index eb7a41d..187027d 100644 --- a/flash.tos/tos/videl2.S +++ b/flash.tos/tos/videl2.S @@ -28,7 +28,7 @@ #define measure_frame 0x3EC #define measure_line 0x3F0 -#define measure_clock 0x3F4 +#define measure_freq 0x3F4 #define vbl_count 0x3F8 #define count_measure 0x3FA #define modecode 0x184C @@ -40,6 +40,7 @@ #define LOGO_MOT_WIDTH 4 // words #define LOGO_MOT_HEIGHT 56 // lines + picture_boot: #ifdef COLDFIRE @@ -49,18 +50,19 @@ picture_boot: bsr debug_display_string move.l (SP)+,A0 #endif -#else - move.l #0x8000,D0 // instruction cache - movec.l D0,CACR #endif +#ifndef COLDFIRE move.w #0x2300,SR // enable interrupts +#else + move.w #0x2000,SR // enable interrupts (for PCI part) +#endif bsr fix_modecode #ifndef COLDFIRE bsr screen_ntc_boot #endif moveq #0,D0 rts - + fix_modecode: move.l D1,-(SP) @@ -578,7 +580,7 @@ measure_clock_videl: // return value in MHz movem.l D1-A6,-(SP) clr.l measure_frame // nS clr.l measure_line // nS * 100 - clr.l measure_clock // nS * 100 + clr.l measure_freq // nS * 100 clr.w vbl_count move.w SR,-(SP) or.w #0x700,SR // no IRQ @@ -600,7 +602,7 @@ measure_clock_videl: // return value in MHz sub.l D2,D0 cmp.l #100,D0 // time-out bge.s .timeout_measure - move.l measure_clock,D1 + move.l measure_freq,D1 beq.s .wait_measure .timeout_measure: move.l A4,0x70 @@ -672,7 +674,7 @@ irq_vbl_measure: .no_rest: swap D0 .no_measure: - move.w D0,measure_clock+2 + move.w D0,measure_freq+2 lea 0xFFFFFA01,A0 // MFP bclr #0,0x12(A0) // IMRA bclr #0,6(A0) // IERA diff --git a/flash.tos/tos/xbios.S b/flash.tos/tos/xbios.S deleted file mode 100644 index 0005ad7..0000000 --- a/flash.tos/tos/xbios.S +++ /dev/null @@ -1,201 +0,0 @@ -/* TOS 4.04 Xbios patch for the CT60 board -* Didier Mequignon 2002-2004, e-mail: aniplay@wanadoo.fr -* -* This library is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License as published by the Free Software Foundation; either -* version 2.1 of the License, or (at your option) any later version. -* -* This library 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 -* Lesser General Public License for more details. -* -* You should have received a copy of the GNU Lesser General Public -* License along with this library; if not, write to the Free Software -* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -#include "vars.h" - - .text - -#ifdef COLDFIRE - .chip 68060 -#endif - - .globl det_xbios - - .align 2 - .long 0x230 - .long end1-begin1+0x80000000 -begin1: - .short 0x21FC - .long det_xbios -end1: - - .globl new_statvec - - .align 2 - .long 0x26C4 - .long end2-begin2+0x80000000 -begin2: - jsr new_statvec - nop - nop -end2: - - .globl new_ikbdvect - - .align 2 - .long 0x340A - .long end3-begin3+0x80000000 -begin3: - jsr new_ikbdvect - nop -end3: - - .globl nvm_access - - .align 2 - .long 0x216C - .long end4-begin4+0x80000000 -begin4: - jmp nvm_access -end4: - - .globl test_rtc - - .align 2 -#ifdef COLDFIRE - .long 0x2112 -#else - .long 0x212E -#endif - .long end5-begin5+0x80000000 -begin5: - jmp test_rtc -end5: - - .globl fix_settime - - .align 2 - .long 0x230E - .long end6-begin6+0x80000000 -begin6: - jsr fix_settime -end6: - - .align 2 - .long 0x2316 - .long end7-begin7 -begin7: - nop - nop -end7: - -#ifndef COLDFIRE - - .globl fix_gettime - - .align 2 - .long 0x2264 - .long end8-begin8+0x80000000 -begin8: - jsr fix_gettime -end8: - -#else /* COLDFIRE */ - - .globl gettime - - .align 2 - .long 0x22A0 - .long end9-begin9+0x80000000 -begin9: - jmp gettime -end9: - - .globl end_settime - - .align 2 - .long 0x231A - .long end10-begin10+0x80000000 -begin10: - jmp end_settime -end10: - - .globl error_ok - - .align 2 - .long 0x332 - .long end11-begin11+0x80000000 -begin11: - move.l #error_ok,dump_vec -end11: - - .align 2 - .long 0x33A - .long end12-begin12+0x80000000 -begin12: - move.l #error_ok,ptr_stat -end12: - - .align 2 - .long 0x342 - .long end13-begin13+0x80000000 -begin13: - move.l #error_ok,ptr_vec -end13: - - .globl auxostat - - .align 2 - .long 0x34A - .long end14-begin14+0x80000000 -begin14: - move.l #auxostat,aux_sta -end14: - - .globl auxout - - .align 2 - .long 0x352 - .long end15-begin15+0x80000000 -begin15: - move.l #auxout,aux_vec -end15: - - .align 2 - .long 0x532 - .long end16-begin16 -begin16: // reset IKBD - nop - nop - nop - nop - nop - nop - nop - nop - nop -end16: - - .align 2 - .long 0x429A - .long end17-begin17 -begin17: // flopvbl - rts -end17: - - .globl _Setscreen - - .align 2 - .long 0x5A8 - .long end18-begin18+0x80000000 -begin18: - jsr _Setscreen -end18: - -#endif - diff --git a/flash.tos/tos/xbios2.S b/flash.tos/tos/xbios2.S index 1e201cf..8c45dee 100644 --- a/flash.tos/tos/xbios2.S +++ b/flash.tos/tos/xbios2.S @@ -1,7 +1,7 @@ /* XBIOS CT60 board functions * - Read on the CT60, the 68060 temperature on the TLV0831 DC from Texas I. * 2.8 deg celcius / step -* - Parameters in flash +* - Parameters in Flash * - Backup NVM stored in flash * - Cache * - PCI BIOS @@ -12,7 +12,7 @@ * - Backup NVM (SRAM) stored in flash * - IKBD from CAN on MCF548X (special version of Eiffel) and UART2 on MCF5445X (serial port, normal) * - IKBD from UART2 on MCF5445X -* - IKBD from PSC3 on MCF547X +* - IKBD from PSC1 and FPGA on MCF547X * - Serial from PSC0/UART0 or serial mouse * - MFP timers replaced by GPT timers on MCF547X-MCF548X and PIT timers on MCF5445X * - VBL replaced by SLT0 timer on MCF547X-MCF548X and DTMR0 timer on MCF5445X @@ -20,7 +20,7 @@ * - PCI BIOS * - Eiffel keyboard XBIOS * -* Didier Mequignon 2001-2009, e-mail: aniplay@wanadoo.fr +* Didier Mequignon 2001-2012, e-mail: aniplay@wanadoo.fr * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -37,43 +37,15 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#ifdef COLDFIRE - .globl flush_caches_z - .globl flush_caches_x - .globl flush_caches - .globl flush_data_cache - .globl flush_instr_cache - .globl caches_disable - .globl caches_enable - .globl replace_mfp - .globl int_timer_c_mfp - .globl tempo_reset_ikbd - .globl gettime - .globl end_settime - .globl ikbdwc - .globl ikbdws - .globl auxistat - .globl auxin - .globl auxostat - .globl auxout - .globl _Setscreen -#endif /* COLDFIRE */ - .globl det_xbios - .globl nvm_access - .globl test_rtc - .globl fix_settime -#ifndef COLDFIRE - .globl fix_gettime -#endif - .globl new_ikbdvect - .globl new_statvec - #include "main.h" #include "ct60.h" #include "command.h" #include "vars.h" +#ifdef COLDFIRE +#define USE_MFP /* FIREBEE FPGA emulation */ #undef DEBUG +#endif // #define DEBUG_GEMDOS // => move.b #0x01,0x5695 before the Gemdos call @@ -199,36 +171,8 @@ #define MOUSE_ACCEL 4 -#else // 68060 - -#define MES_TEMP_0 197 -#define MES_TEMP_25 208 -#define MES_TEMP_50 218 -#define MES_TEMP_100 236 -#define MES_TEMP_ERROR 255 - -#define _iera_mfp 0xfffffa07 // MFP registers -#define _ipra_mfp 0xfffffa0b -#define _isra_mfp 0xfffffa0f -#define _imra_mfp 0xfffffa13 -#define _tbcr_mfp 0xfffffa1b -#define _tbdr_mfp 0xfffffa21 // timer B -#define _tcdr_mfp 0xfffffa23 // value changed at each 26 uS by system (timer C at 200 Hz) -#define _texas_tlv0831_data 0xf1000000 // read from D0 (THDA) -#define _texas_tlv0831_cs_low 0xf1400000 // CS at 0 (/THCS) -#define _texas_tlv0831_cs_high 0xf1000000 // CS at 1 (THCS) -#define _texas_tlv0831_clk_low 0xf1800000 // CLK at 0 (/THCK) -#define _texas_tlv0831_clk_high 0xf1c00000 // CLK at 1 (THCK) - -#define FLASH_UNLOCK1 (FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0xAAA) -#define FLASH_UNLOCK2 (FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0x554) - #endif /* COLDFIRE */ -#define MAX_PARAM_FLASH 16 -#define NB_BLOCK_PARAM (PARAM_SIZE/(MAX_PARAM_FLASH*4)) -#define SIZE_BLOCK_PARAM (PARAM_SIZE/NB_BLOCK_PARAM) - #define read_core_temperature 0xc60a #define rw_parameter 0xc60b #define cache 0xc60c @@ -240,25 +184,65 @@ #define flush_cache_bis 0x0c6d #define vmalloc_bis 0xc6e - .text - - .align 4 +#ifdef COLDFIRE + .globl flush_caches + .globl flush_data_cache + .globl flush_instr_cache + .globl caches_disable + .globl caches_enable + .globl replace_mfp + .globl disable_interrupts + .globl install_scsidrv +#ifdef MCF547X + .globl rtc_init + .globl flopvbl + .globl setporta + .globl waitdma +#endif + .globl delay_5mS + .globl delay_80us + .globl delay_10us + .globl int_timer_c_mfp + .globl tempo_reset_ikbd +#ifndef MCF547X + .globl gettime + .globl end_settime +#endif + .globl ikbdwc + .globl ikbdws + .globl auxistat + .globl auxin + .globl auxostat + .globl auxout + .globl _Setscreen +#else /* !COLDFIRE */ + .globl code_led +#endif /* COLDFIRE */ + .globl get_cookie + .globl det_xbios + .globl nvm_access + .globl test_rtc +#if defined(COLDFIRE) && defined(MCF547X) + .globl end_settime_rtc +#endif + .globl fix_settime +#if !defined(COLDFIRE) || defined(MCF547X) + .globl fix_gettime +#endif + .globl new_ikbdvect + .globl new_statvec +#ifdef COLDFIRE + .globl fire_rw_param +#else + .globl ct60_rw_param + .globl ct60_read_temp +#endif + .text + #ifdef COLDFIRE .chip 5200 -flush_caches_z: - - move.l D0,-(SP) - move.w 0xA88,D0 - or.l #0x10,D0 - move.w D0,0xA88 - move.l (SP)+,D0 - -flush_caches_x: - - add.l D2,16(SP) - flush_caches: .chip 68060 @@ -350,7 +334,38 @@ replace_mfp: clr.w MCF_PIT_PCSR1 clr.w MCF_PIT_PCSR2 clr.w MCF_PIT_PCSR3 -#else /* MCF548X */ +#else /* MCF547X-MCF548X */ +#ifdef MCF547X /* FIREBEE */ + lea 0xFFFF8800,A0 // PSG (FPGA emulation) + lea 2(A0),A1 + move.b #7,(A0) + move.b #0xC0,(A1) // ports A / B outputs + move.b #14,(A0) // port A + move.b #7,(A1) // unselect floppy + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + moveq #0,D0 + moveq #23,D1 +.clear_mfp: + clr.b (A0,D0.l) + addq.l #2,D0 + subq.l #1,D1 + bpl.s .clear_mfp + moveq #0x04,D0 + move.b D0,2(A0) // AER + move.b #0x48,D0 + move.b D0,22(A0) // VR + clr.b stop_mfp_ikbd + lea int6_mfp(PC),A0 + move.l A0,(64+6+OFFSET_INT_CF68KLIB)*4 // IRQ6 EPORT + clr.l ACP_INTERRUPT_CLEAR + move.l #ACP_INT_MFP_IRQ6 + ACP_INT_VSYNC_IRQ4 + ACP_INT_HSYNC_IRQ2,D0 + or.l D0,ACP_INTERRUPT_ENABLE + move.b MCF_EPORT_EPIER,D0 + or.l #MCF_EPORT_EPIER_EPIE6,D0 + move.b D0,MCF_EPORT_EPIER + move.l #~(MCF_INTC_IMRL_INT_MASK6 + MCF_INTC_IMRL_MASKALL),D0 + and.l D0,MCF_INTC_IMRL +#endif /* MCF5474X */ lea new_vbl(PC),A0 // for rtos move.l A0,(64+4+OFFSET_INT_CF68KLIB)*4 tst.l tid_tos @@ -383,21 +398,50 @@ replace_mfp: moveq #0x50,D1 // / 64 move.w #192,D2 bsr settimer +#ifndef MCF547X /* vector already used for MFP emulation on FIREBEE */ lea new_timer(PC),A0 // for rtos move.l A0,(64+6+OFFSET_INT_CF68KLIB)*4 +#endif lea 0xE03C50,A0 // timer C interrupt routine move.l A0,TIMER_C_VEC // for rtos because it's impossible to use initint tst.l tid_tos bne.s .use_rtos_timer - moveq #5,D0 + moveq #5,D0 // enable timer C bsr initint .use_rtos_timer: +#ifdef MCF547X + clr.w -(SP) // SCR + move.w #1,-(SP) // TSR, transmitter enable + move.w #1,-(SP) // RSR, receiver enable + move.w #0x98,-(SP) // UCR, no parity, 2 stops, 8 bits + clr.w -(SP) // ctrl, no XON/XOFF, no CTS/RTS + move.w #1,-(SP) // 9600 bauds + jsr 0xE02B06 // Rsconf MFP + lea 12(SP),SP + moveq #14,D1 // port A PSG + bsr Giaccess + move.l #0xE7,D2 // RTS & DTR + and.l D2,D0 + bset #7,D1 // write port A + bsr Giaccess +#else /* MCF548X */ moveq #3,D0 // timer D moveq #1,D1 // 4 moveq #2,D2 // 9600 bauds bsr settimer +#endif /* MCF547X */ + moveq #CT60_MODE_READ,D0 // mode + moveq #CT60_SERIAL_SPEED,D1 // type_param + moveq #0,D2 // value + jsr fire_rw_param + tst.l D0 + bmi.s .default_speed + cmp.l #16,D0 + bcs.s .speed_ok +.default_speed: // moveq #1,D0 // 9600 bauds moveq #0,D0 // 19200 bauds +.speed_ok: moveq #0,D1 // no XON/XOFF, no CTS/RTS moveq #0x18,D2 // no parity, 2 stops, 8 bits bsr Rsconf @@ -405,6 +449,17 @@ replace_mfp: lea 0xE02776,A1 moveq #33,D0 bsr bytes_copy +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 + move.l A0,0x11D2 + lea 0xE02776,A1 + moveq #33,D0 + bsr bytes_copy + lea 0x145A,A0 + move.l A0,0x165A + lea 0x155A,A0 + move.l A0,0x1668 +#endif /* MCF547X */ lea 0x10A4,A0 lea 0xE02768,A1 moveq #13,D0 @@ -413,7 +468,11 @@ replace_mfp: move.w D0,0x115C lea ikbdvect(PC),A0 // 0xE0340A move.l A0,0x1132 // IKBD keyboard (code < 0xF6) +#ifdef MCF547X + lea sysmidi(PC),A0 +#else lea unimplemented(PC),A0 // 0xE03920 +#endif move.l A0,0x1136 // midivec (unused because not called) lea 0xE032EA,A0 // RTS move.l A0,0x113A // vkbderr, keyboard error (unused because not called) @@ -444,6 +503,36 @@ replace_mfp: lea 0xE0275A,A1 moveq #13,D0 bsr bytes_copy +#ifdef MCF547X // Bconmap init 6:MFP, 7:PSC0 (default), FIREBEE has no SCC inside FPGA emulation + lea 0x11D6,A0 + move.l A0,0x11C6 + moveq #2,D0 // 2 tables MFP & PSC0 + move.w D0,0x11CA + lea 0xE02BEA,A1 + moveq #17,D0 +.init_bconmap: + move.l (A1)+,(A0)+ + subq.l #1,D0 + bpl.s .init_bconmap + moveq #7,D0 // PSC0 by default + move.w D0,0x11CC + lea 0x11EE,A0 + lea auxistat(PC),A1 + move.l A1,(A0)+ + move.l A1,0x522 // bconstat(2) + lea auxin(PC),A1 + move.l A1,(A0)+ + move.l A1,0x542 // bconin(2) + lea auxostat(PC),A1 + move.l A1,(A0)+ + move.l A1,0x562 // bcostat(2) + lea auxout(PC),A1 + move.l A1,(A0)+ + move.l A1,0x582 // bconout(2) + lea rsconf(PC),A1 + move.l A1,(A0)+ + move.l A1,0x11CE +#endif /* MCF547X */ link A6,#-4 // bioskeys, init IKBD tables clr.l -4(A6) pea -1(A6) // buffer @@ -476,7 +565,29 @@ replace_mfp: bsr ikbd_init // uart 2 for IKBD #else #ifdef MCF547X - bsr ikbd_init // PSC 3 for IKBD + moveq #3,D0 + move.b D0,0xFFFFFC04 // reset ACIA MIDI + move.b #0x95,D0 + move.b D0,0xFFFFFC04 // / 16, 8 bits, 1 stop, no parity + bsr ikbd_init // PSC1 / ACIA for IKBD +// bsr rtc_init // PSC3 for RTC => moved before_init_cookie + bsr pseudo_dma_init + // MFP UART vectors + lea 0xE028E8,A0 + moveq #12,D0 // MFP vector 12, enable RX full + bsr initint + lea 0xE029E4,A0 + moveq #11,D0 // MFP vector 11, enable RX error + bsr initint + lea 0xE02982,A0 + moveq #10,D0 // MFP vector 10, enable TX empty + bsr initint + lea 0xE02A04,A0 + moveq #9,D0 // MFP vector 9, enable TX error + bsr initint + lea 0xE0299E,A0 + moveq #2,D0 // MFP vector 2, enable CTS + bsr initint #else /* MCF548X */ bsr can_init // used for IKBD #endif /* MCF547X */ @@ -513,6 +624,167 @@ replace_mfp: move.b D0,MCF_UART_UIMR0 // enable TX/RX interrupts move.w #0x400,D0 rts + +#ifdef MCF547X /* FIREBEE */ + +flopvbl: // TOS404 0xE0429A + + moveq #-1,D0 + move.b D0,0x1690 // flag motor on + tst.w flock + bne .fv1 // floppy in action + move.l _frclock,d0 + move.l D0,D1 + and.l #7,D1 + bne .fv1 // <> 8th interrupt + move.w #0x80,D1 // select state register WD1772 + move.w D1,0xFFFF8606 // FDC + lsr.l #3,D0 + and.l #1,D0 // bit 4 used for drive number + lea 0x1680,A0 // write protect status table + add.l D0,A0 + moveq #0,D1 + move.w _nflops,D1 + cmp.l D1,D0 + bne.s .fv3 + moveq #0,D0 +.fv3: + addq.l #1,D0 // select drive A / B (1/2) + add.l D0,D0 // shift face + eor.l #7,D0 // invert bits for hardware + bsr setporta // drive select + bsr delay_80us + move.w 0xFFFF8604,D0 // FDC + btst #6,D0 // write protect bit + sne.b D0 + move.b D0,(A0) + move.b D2,D0 // restore port A + bsr setporta + move.w 0x1680,D0 // write protect status table + move.w 0x1682,D1 // write protect latch table + or.l D1,D0 + move.w D0,0x1682 // write protect latch table + tst.w 0x1692 // unselect flag + bne.s .fv4 // floppy already unselected + move.l _hz_200,D0 + cmp.l 0x168C,D0 + bcc.s .fv2 + bsr delay_80us + move.w 0xFFFF8604,D0 // FDC + btst #7,D0 // motor on + bne.s .fv1 +.fv2: + moveq #7,D0 // unselect all + bsr setporta + moveq #1,D0 + move.w D0,0x1692 // unselect flag +.fv4: + clr.w 0x1690 // motor on flag +.fv1: + rts + +setporta: + + move.w SR,D1 + move.w D1,-(SP) + or.l #0x700,D1 // mask interrupts + move.w D1,SR + moveq #14,D1 // port A + move.b D1,0xFFFF8800 // PSG +#if 1 + move.b psg_save_port_a,D1 +#else + move.b 0xFFFF8800,D1 // read outputs (seems not works on FPGA emulation) +#endif + move.b D1,D2 // save state + and.l #0xF8,D1 + and.l #7,D0 // new bits + or.l D1,D0 + moveq #14,D1 // port A + move.b D1,0xFFFF8800 // PSG + move.b D0,0xFFFF8802 // write +#if 1 + move.b D0,psg_save_port_a +#endif + move.w (SP)+,D1 + move.w D1,SR // restore interrupts + rts + +waitdma: + +#if 1 + move.l A0,-(SP) + lea 0xFFFF860F,A0 +.waitdma: + btst #3,(A0) + bne.s .waitdma + move.l (SP)+,A0 +#else + bsr delay_80us +.wait_dma: + tst.l ACP_DMA_COUNTER + bgt.s .wait_dma +#endif + rts + +#endif /* MCF547X */ + +delay_5mS: + + move.l D2,-(SP) + move.l #5000,D2 // 5 mS + bra.s delay_us + +delay_80us: // 0xE045E8 TOS404 + + move.l D2,-(SP) + moveq #80,D2 // 80 uS + bra.s delay_us + +delay_10us: + + move.l D2,-(SP) + moveq #10,D2 // 10 uS + +delay_us: + +#ifdef COLDFIRE + move.l D1,-(SP) + move.l D0,-(SP) +#ifdef MCF5445X + move.l MCF_DTIM_DTCN1,D1 +.wait_us_loop: + move.l MCF_DTIM_DTCN1,D0 + sub.l D1,D0 + cmp.l D2,D0 + bcs.s .wait_us_loop +#else /* MCF547X-MCF548X */ + MULU #SYSTEM_CLOCK,D2 + move.l MCF_SLT_SCNT1,D1 +.wait_us_loop: + move.l D1,D0 + sub.l MCF_SLT_SCNT1,D0 + cmp.l D2,D0 + bcs.s .wait_us_loop +#endif /* MCF5445X */ + move.l (SP)+,D0 + move.l (SP)+,D1 +#else /* 68060 */ + move.l D1,-(SP) + divu #26,D2 + subq.w #1,D2 + bmi.s .wait_end +.wait_us_loop: + move.b 0xFFFFFA23,D1 // MFP TCDR +.wait_timer_c: + cmp.b 0xFFFFFA23,D1 + beq.s .wait_timer_c + dbf D2,.wait_us_loop +.wait_end: + move.l (SP)+,D1 +#endif /* COLDFIRE */ + move.l (SP)+,D2 + rts int_timer_c_mfp: @@ -529,6 +801,9 @@ int_timer_c_mfp: bne.s .not_timer_c_tos lea -56(SP),SP movem.l D1-D7/A0-A6,(SP) +#ifdef MCF547X + bsr sndirq +#endif move.b conterm,D0 btst #1,D0 // key repeat flag beq.s .no_repeat_key @@ -559,6 +834,73 @@ int_timer_c_mfp: .not_timer_c_tos: move.l (SP)+,D0 rte + +#ifdef MCF547X + +sndirq: + + lea -12(SP),SP + movem.l D0-D1/A0,(SP) + move.l 0x11BC,D0 + beq .sndirq_end // no active sound + move.l D0,A0 // data pointer + moveq #0,D0 + move.b 0x11C0,D0 // timer value + beq.s .sndirq1 // new sound ? + subq.l #1,D0 + move.b D0,0x11C0 + bra.s .sndirq_end +.sndirq1: + moveq #0,D0 + move.b (A0)+,D0 + bmi.s .sndirq2 // command + move.b d0,0xFFFF8800 // PSG (FPGA emulation) + cmp.l #7,D0 // register 7 + bne.s .sndirq3 + move.b (A0)+,D1 // data for register 7 + and.l #0x3F,D1 + move.b 0xFFFF8800,D0 // PSG (FPGA emulation) + and.l #0xC0,D0 + or.l D1,D0 + move.b D0,0xFFFF8802 // PSG (FPGA emulation) + bra.s .sndirq1 +.sndirq3: + move.b (A0)+,0xFFFF8802 // PSG (FPGA emulation) + bra.s .sndirq1 +.sndirq2: + cmp.l #0xFF,D0 // command + beq.s .sndirq4 + cmp.l #0x80,D0 // command + bne.s .sndirq6 + move.b (A0)+,0x11C1 + bra.s .sndirq1 // next sound +.sndirq6: + cmp.l #0x81,D0 // command + bne.s .sndirq4 + move.b (A0)+,0xFFFF8800 // PSG (FPGA emulation) + moveq #0,D1 + move.b 0x11C1,D1 + move.b (A0)+,D0 + add.l D0,D1 + move.b D1,0x11C1 + move.b (A0)+,D0 + move.b D1,0xFFFF8802 // PSG (FPGA emulation) + cmp.l D0,D1 + beq.s .sndirq5 // end + subq.l #4,A0 // previous command + bra.s .sndirq5 +.sndirq4: + move.b (A0)+,0x11C0 // next value for wait timer + bne.s .sndirq5 + lea 0,A0 +.sndirq5: + move.l A0,0x11BC // data pointer +.sndirq_end: + movem.l (SP),D0-D1/A0 + lea 12(SP),SP + rts + +#endif /* MCF547X*/ tempo_reset_ikbd: @@ -619,6 +961,22 @@ led: and.l D0,FPGA_LEDS move.l (SP)+,D0 rts +#else /* MCF548X */ +#ifdef MCF547X + move.l D0,-(SP) + btst #0,D0 + beq.s .led_off + move.b MCF_GPIO_PODR_FEC1L,D0 + and.l #~MCF_GPIO_PODR_FEC1L_PODR_FEC1L4,D0 + move.b D0,MCF_GPIO_PODR_FEC1L + move.l (SP)+,D0 + rts +.led_off: + move.b MCF_GPIO_PODR_FEC1L,D0 + or.l #MCF_GPIO_PODR_FEC1L_PODR_FEC1L4,D0 + move.b D0,MCF_GPIO_PODR_FEC1L + move.l (SP)+,D0 + rts #else /* MCF548X */ move.l D0,-(SP) btst #0,D0 @@ -632,6 +990,7 @@ led: and.l D0,MCF_GPT_GMS0 // TOUT0 to 0 move.l (SP)+,D0 rts +#endif /* MCF547X */ #endif /* M5445X */ dc.l 0x58425241 // XBRA @@ -644,14 +1003,11 @@ unimplemented: new_vbl: +// move.w #0x2700,SR move.l D0,-(SP) #ifdef MCF5445X move.l MCF_DTIM_DTCN1,D0 move.l #1000000/38400,-(SP) -#else /* MCF548X */ - move.l MCF_SLT_SCNT1,D0 - move.l #SYSTEM_CLOCK*1000000/38400,-(SP) -#endif /* MCF5445X */ .chip 68060 divu.l (SP)+,D0 divu #192,D0 @@ -662,10 +1018,37 @@ new_vbl: move.b D0,0xFFFFFA23 // TCDR MFP emulation tst.l tid_tos bne.s .use_rtos_vbl -#ifdef MCF5445X moveq #DTIM_DTER_REF,D0 move.b D0,MCF_DTIM_DTER0 // clear interrupt #else /* MCF548X */ +#if 0 + tst.l tid_tos + beq.s .not_use_rtos_vbl + move.l MCF_INTC_INTFRCL,D0 + and.l #MCF_INTC_INTFRCL_INTFRC4,D0 + bne.s .not_use_rtos_vbl // forced VBL + // true VBL + move.l #ACP_INT_VSYNC_IRQ4,D0 + move.l D0,ACP_INTERRUPT_CLEAR + moveq #4,D0 + bset.b D0,MCF_EPORT_EPFR // clear interrupt + bra.s .not_vbl_tos +.not_use_rtos_vbl: +#endif +#if !(defined(MCF547X) && defined(USE_MFP)) /* <> FIREBEE FPGA emulation */ + move.l MCF_SLT_SCNT1,D0 + move.l #SYSTEM_CLOCK*1000000/38400,-(SP) + .chip 68060 + divu.l (SP)+,D0 + divu #192,D0 + .chip 5200 + clr.w D0 + swap D0 + addq.l #1,D0 + move.b D0,0xFFFFFA23 // TCDR MFP emulation +#endif /* !(defined(MCF547X) && defined(USE_MFP)) */ + tst.l tid_tos + bne.s .use_rtos_vbl move.l #MCF_SLT_SSR_ST,D0 or.l D0,MCF_SLT_SSR0 // clear interrupt #endif /* MCF5445X */ @@ -697,6 +1080,7 @@ new_vbl: move.l VBL_VEC,-(SP) // TOS404 0xE00CB0 rts +#ifndef MCF547X new_timer: move.l D0,-(SP) @@ -710,6 +1094,7 @@ new_timer: move.l (SP)+,D0 move.l TIMER_C_VEC,-(SP) // TOS404 0xE03C50 rts +#endif /* MCF547X */ new_timer_a: @@ -791,11 +1176,66 @@ settimer: lea debug5(PC),A0 bsr debug_display_string #endif +#if defined(MCF547X) && defined(USE_MFP) /* FIREBEE FPGA emulation */ + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + tst.l D0 // timer + beq.s .start_timer_a + cmp.l #1,D0 + beq.s .start_timer_b + cmp.l #2,D0 + beq.s .start_timer_c + cmp.l #3,D0 + beq.s .start_timer_d + bra.s .end_timer +.start_timer_a: + clr.b 24(A0) // TACR + move.b D2,30(A0) // TADR + move.b D1,24(A0) // TACR + bra.s .end_timer +.start_timer_b: + clr.b 26(A0) // TBCR + move.b D2,32(A0) // TBDR + move.b D1,26(A0) // TBCR + bra.s .end_timer +.start_timer_c: + move.b 28(A0),D0 // TCDCR + and.l #0xF,D0 + move.b D0,28(A0) // TCDCR + and.l #0xF0,D1 + or.l D0,D1 // control + move.b D2,34(A0) // TCDR + move.b D1,28(A0) // TCDCR + bra.s .end_timer +.start_timer_d: + move.b 28(A0),D0 // TCDCR + and.l #0xF0,D0 + move.b D0,28(A0) // TCDCR + and.l #0xF,D1 + or.l D0,D1 // control + move.b D2,36(A0) // TCDR + move.b D1,28(A0) // TCDCR +#else /* <> FIREBEE FPGA emulation */ ext.l D0 // timer ext.l D1 // control ext.l D2 // data cmp.l #2,D0 // timer C bne.s .not_timer_c +#if defined(MCF547X) && !defined(USE_MFP) /* FIREBEE FPGA emulation */ + move.l D0,-(SP) // some programs read timer C for delay loop + move.l D1,-(SP) + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + moveq #0x50,D1 // / 64 + move.w #192,D2 + move.b 28(A0),D0 // TCDCR + and.l #0xF,D0 + move.b D0,28(A0) // TCDCR + and.l #0xF0,D1 + or.l D0,D1 // control + move.b D2,34(A0) // TCDR + move.b D1,28(A0) // TCDCR + move.l (SP)+,D1 + move.l (SP)+,D0 +#endif /* defined(MCF547X) && !defined(USE_MFP) */ lsr.l #4,D1 .not_timer_c: tst.l D1 @@ -804,7 +1244,7 @@ settimer: bhi .end_timer asl.l #2,D1 lea tab_prediv_mfp(PC),A0 - move.l (A0,D1),D1 + move.l (A0,D1.l),D1 mulu.l D2,D1 // * data move.l #10000,D2 mulu.l D2,D1 @@ -980,6 +1420,7 @@ settimer: clr.l MCF_GPT_GCIR3 move.l D1,MCF_GPT_GMS3 #endif /* MCF5445X */ +#endif /* defined(MCF547X) && defined(USE_MFP) */ .end_timer: movem.l (SP),D0-D2/A0 lea 16(SP),SP @@ -994,6 +1435,17 @@ initint: move.l (SP)+,A0 #endif bsr Jdisint +#if defined(MCF547X) && defined(USE_MFP) + move.l D1,-(SP) + move.l A1,-(SP) + move.l D0,D1 // MFP vector number + asl.l #2,D1 // * 4 + add.l #0x100,D1 // MFP vectors base + move.l D1,A1 + move.l A0,(A1) // new vector + move.l (SP)+,A1 + move.l (SP)+,D1 +#else /* !(defined(MCF547X) && defined(USE_MFP)) */ cmp.l #13,D0 beq.s .vect_timer_a cmp.l #8,D0 @@ -1005,46 +1457,57 @@ initint: bra.s .end_new_vector .vect_timer_a: move.l A0,TIMER_A_VEC +#if !(defined(MCF547X) || defined(USE_MFP)) /* <> FIREBEE FPGA emulation */ lea new_timer_a(PC),A0 #ifdef MCF5445X move.l A0,(128+INT1_HI_PIT0_PIF+OFFSET_INT_CF68KLIB)*4 #else /* MCF548X */ move.l A0,(64+62+OFFSET_INT_CF68KLIB)*4 #endif +#endif /* defined(MCF547X) && defined(USE_MFP) */ bra.s .end_new_vector .vect_timer_b: move.l A0,TIMER_B_VEC +#if !(defined(MCF547X) || defined(USE_MFP)) /* <> FIREBEE FPGA emulation */ lea new_timer_b(PC),A0 #ifdef MCF5445X move.l A0,(128+INT1_HI_PIT1_PIF+OFFSET_INT_CF68KLIB)*4 #else /* MCF548X */ move.l A0,(64+61+OFFSET_INT_CF68KLIB)*4 #endif +#endif /* defined(MCF547X) && defined(USE_MFP) */ bra.s .end_new_vector .vect_timer_c: move.l A0,TIMER_C_VEC +#if !(defined(MCF547X) || defined(USE_MFP)) /* <> FIREBEE FPGA emulation */ lea new_timer_c(PC),A0 #ifdef MCF5445X move.l A0,(128+INT1_HI_PIT2_PIF+OFFSET_INT_CF68KLIB)*4 #else /* MCF548X */ move.l A0,(64+60+OFFSET_INT_CF68KLIB)*4 #endif +#endif /* defined(MCF547X) && defined(USE_MFP) */ bra.s .end_new_vector .vect_timer_d: move.l A0,TIMER_D_VEC +#if !(defined(MCF547X) || defined(USE_MFP)) /* <> FIREBEE FPGA emulation */ lea new_timer_d(PC),A0 #ifdef MCF5445X move.l A0,(128+INT1_HI_PIT3_PIF+OFFSET_INT_CF68KLIB)*4 #else /* MCF548X */ move.l A0,(64+59+OFFSET_INT_CF68KLIB)*4 #endif +#endif /* defined(MCF547X) && defined(USE_MFP) */ .end_new_vector: +#endif /* defined(MCF547X) && defined(USE_MFP) */ bsr Jenabint rts tab_prediv_mfp: dc.l 0,4,10,16,50,64,100,200 +#ifndef MCF547X + gettime: link A6,#-2 @@ -1097,15 +1560,17 @@ end_settime: .error_time: unlk A6 rts + +#endif /* MCF547X */ jdosgettime: // IKBD to DOS format lea 0x116D,A0 bsr bcdbin sub.l #80,D0 // 1980 - bpl.s .year_before_2000_gettime + bpl.s .year_before_2000_gettime_ikbd add.l #100,D0 -.year_before_2000_gettime: +.year_before_2000_gettime_ikbd: move.l D0,D2 asl.l #4,D2 bsr bcdbin @@ -1276,23 +1741,37 @@ Ikbdws: // D0.W: len-1, A0: buffer beq.s .iw1 // full move.b (A0)+,D0 // data inside the buffer move.b D0,MCF_UART_UTB2 // data - subq.l #8,D2 - bmi.s .iw1 + subq.l #1,D2 + bpl.s .iw1 moveq #0,D0 // OK rts #else #ifdef MCF547X -.iw1: - move.b MCF_UART_USR3,D1 +#if 0 + move.l D2,-(SP) + move.l A0,-(SP) +.iw1: + move.b MCF_UART_USR1,D1 and.l #MCF_UART_USR_TXEMP,D1 beq.s .iw1 // full move.b (A0)+,D0 // data inside the buffer - move.b D0,MCF_UART_UTB3 // data - subq.l #8,D2 - bmi.s .iw1 + move.b D0,MCF_UART_UTB1 // send data + subq.l #1,D2 + bpl.s .iw1 + move.l (SP)+,A0 + move.l (SP)+,D2 +#endif +.iw2: // FIREBEE + move.b 0xFFFFFC00,D1 // ACIA IKBD + btst #1,D1 // ready + beq.s .iw2 + move.b (A0)+,D0 // data inside the buffer + move.b D0,0xFFFFFC02 // send data + subq.l #1,D2 + bpl.s .iw2 moveq #0,D0 // OK rts -#else /* MCF548X */ +#else /* MCF548X CAN1 */ addq.l #1,D2 .iw1: move.l MCF_CAN_ERRSTAT1,D0 @@ -1335,10 +1814,10 @@ Ikbdws: // D0.W: len-1, A0: buffer .iw5: bsr debug_display_string #endif -#endif /* MCF547X */ -#endif /* MCF5445X */ moveq #-1,D0 // error rts +#endif /* MCF547X */ +#endif /* MCF5445X */ Jdisint: @@ -1357,6 +1836,29 @@ Jdisint: #endif move.l D1,-(SP) ext.l D0 +#if defined(MCF547X) && defined(USE_MFP) /* FIREBEE FPGA emulation */ + move.l A0,-(SP) + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + cmp.l #8,D0 + bcc.s .clr_imra + bclr D0,20(A0) // IMRB + bclr D0,8(A0) // IERB + bclr D0,12(A0) // IPRB + bclr D0,16(A0) // ISRB + move.l (SP)+,A0 + bra.s .end_clr_imr_timer +.clr_imra: + cmp.l #16,D0 + bcc.s .end_clr_imr_timer + move.l D0,-(SP) + subq.l #8,D0 + bclr D0,18(A0) // IMRA + bclr D0,6(A0) // IERA + bclr D0,10(A0) // IPRA + bclr D0,14(A0) // ISRA + move.l (SP)+,D0 + move.l (SP)+,A0 +#else /* <> FIREBEE FPGA emulation */ cmp.l #13,D0 beq.s .clr_imr_timer_a cmp.l #8,D0 @@ -1388,12 +1890,13 @@ Jdisint: bra.s .clr_imr_timer .clr_imr_timer_c: move.l #MCF_INTC_IMRH_INT_MASK60,D1 -// bra.s .clr_imr_timer + bra.s .clr_imr_timer .clr_imr_timer_d: -// move.l #MCF_INTC_IMRH_INT_MASK59,D1 + move.l #MCF_INTC_IMRH_INT_MASK59,D1 .clr_imr_timer: or.l D1,MCF_INTC_IMRH #endif /* MCF5445X */ +#endif /* defined(MCF547X) && defined(USE_MFP) */ .end_clr_imr_timer: move.l (SP)+,D1 rts @@ -1415,6 +1918,20 @@ Jenabint: #endif move.l D1,-(SP) ext.l D0 +#if defined(MCF547X) && defined(USE_MFP) /* FIREBEE FPGA emulation */ + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + cmp.l #8,D0 + bcc.s .set_imra + bset D0,8(A0) // IERB + bset D0,20(A0) // IMRB + bra.s .end_set_imr_timer +.set_imra: + cmp.l #16,D0 + bcc.s .end_set_imr_timer + subq.l #8,D0 + bset D0,6(A0) // IERA + bset D0,18(A0) // IMRA +#else /* <> FIREBEE FPGA emulation */ cmp.l #13,D0 beq.s .set_imr_timer_a cmp.l #8,D0 @@ -1460,14 +1977,15 @@ Jenabint: moveq #0x22,D1 // level 4, priority 2 move.b D1,MCF_INTC_ICR60 move.l #~MCF_INTC_IMRH_INT_MASK60,D1 -// bra.s .set_imr_timer + bra.s .set_imr_timer .set_imr_timer_d: -// moveq #0x21,D1 // level 4, priority 1 -// move.b D1,MCF_INTC_ICR59 -// move.l #~MCF_INTC_IMRH_INT_MASK59,D1 + moveq #0x21,D1 // level 4, priority 1 + move.b D1,MCF_INTC_ICR59 + move.l #~MCF_INTC_IMRH_INT_MASK59,D1 .set_imr_timer: and.l D1,MCF_INTC_IMRH #endif /* MCF5445X */ +#endif /* defined(MCF547X) && defined(USE_MFP) */ .end_set_imr_timer: move.l (SP)+,D1 rts @@ -1478,7 +1996,7 @@ Xbtimer: // D0.W: timer, D1.W: control, D2.W: data, A0: vector move.l A0,D0 // vector bmi.s .vector_not_used lea tab_num_int_timer(PC),A1 - move.b (A1,D0.L),D0 + move.b (A1,D0.l),D0 bsr initint // new vector .vector_not_used: rts @@ -1524,9 +2042,9 @@ scale_mouse: get_serial_mouse: + link A6,#-10 lea -56(SP),SP movem.l D0-A5,(SP) - link A6,#-10 and.l #0x7F,D0 tst.w id_serial_mouse bne.s .gsm2 // ID found @@ -1567,7 +2085,7 @@ get_serial_mouse: lea data_serial_mouse,A0 move.w count_serial_mouse,D1 and.l #3,D1 - move.b D0,(A0,D1.L) + move.b D0,(A0,D1.l) addq.l #1,D1 move.w D1,count_serial_mouse moveq #0,D3 @@ -1580,16 +2098,6 @@ get_serial_mouse: cmp.l D2,D1 // end of frame ? bcs .gsm1 clr.w count_serial_mouse -#if 0 - move.b (A0),D0 - bsr _hex_byte - move.b 1(A0),D0 - bsr _hex_byte - move.b 2(A0),D0 - bsr _hex_byte - moveq #0x20,D0 - bsr _display_char -#endif lea -8(A6),A1 move.b (A0),D0 lsr.l #4,D0 // buttons @@ -1623,16 +2131,20 @@ get_serial_mouse: subq.l #1,D2 bgt.s .gsm3 .gsm1: - unlk a6 movem.l (SP),D0-A5 lea 56(SP),SP + unlk A6 rts auxistat: tst.b serial_mouse bne.s .ais2 +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 +#else lea 0xF72,A0 // iorec RS232 +#endif moveq #-1,D0 // OK moveq #0,D1 moveq #0,D2 @@ -1662,7 +2174,11 @@ auxostat: tst.b serial_mouse bne.s .aos3 +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 +#else lea 0xF72,A0 // iorec RS232 +#endif moveq #-1,D0 // OK moveq #0,D1 moveq #0,D2 @@ -1691,10 +2207,25 @@ auxout: bcs.s auxout // not send, try again .ao1: rts + +#ifdef MCF547X + +rsconf: + + move.w 4(SP),D0 // baud + move.w 6(SP),D1 // ctrl + move.w 8(SP),D2 // ucr + bra Rsconf + +#endif rs232put: +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 +#else lea 0xF72,A0 // iorec RS232 +#endif move.w SR,D2 move.l D2,-(SP) or.l #0x700,D2 // mask interrupts @@ -1729,7 +2260,7 @@ rs232put: cmp.l D2,D1 beq.s .rp5 // buffer full move.l 14(A0),A2 // buffer - move.b D0,(A2,D1.L) // store data + move.b D0,(A2,D1.l) // store data move.w D1,22(A0) // tail index move.b psc_uimr,D0 or.l #MCF_UART_UIMR_TXRDY,D0 @@ -1764,7 +2295,11 @@ rs232put: rs232get: +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 +#else lea 0xF72,A0 // iorec RS232 +#endif move.w SR,D2 move.l D2,-(SP) or.l #0x700,D2 // mask interrupts @@ -1784,7 +2319,7 @@ rs232get: .rg2: move.l (A0),A2 // buffer moveq #0,D0 - move.b (A2,D1.L),D0 // get data + move.b (A2,D1.l),D0 // get data move.w D1,6(A0) // head index moveq #0,D1 // OK bra.s .rg3 @@ -1823,7 +2358,11 @@ int_serial: lea -28(SP),SP movem.l D0-D3/A0-A2,(SP) +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 +#else lea 0xF72,A0 // iorec RS232 +#endif move.b MCF_UART_UISR0,D3 // isr // receive data moveq #MCF_UART_UISR_RXRDY_FU,D0 @@ -1897,7 +2436,7 @@ int_serial: cmp.l D2,D1 beq .is1 move.l (A0),A2 // buffer - move.b D0,(A2,D1.L) // store data + move.b D0,(A2,D1.l) // store data #if 0 //#ifdef DEBUG bsr debug_display_char #endif @@ -1958,7 +2497,7 @@ int_serial: moveq #0,D1 .is4: move.l 14(A0),A2 // buffer - move.b (A2,D1.L),D0 // get data + move.b (A2,D1.l),D0 // get data move.b D0,MCF_UART_UTB0 // data move.w D1,20(A0) // head index bra.s .is2 @@ -1999,7 +2538,7 @@ int_serial: moveq #0,D1 .is12: move.l 14(A0),A2 // buffer - move.b (A2,D1.L),D0 // get data + move.b (A2,D1.l),D0 // get data move.b D0,MCF_UART_UTB0 // data move.w D1,20(A0) // head index .is14: @@ -2029,7 +2568,11 @@ Rsconf: // D0.W: baud, D1.W: ctrl, D2.W: ucr clr.b serial_mouse move.l D4,-(SP) move.l D3,-(SP) +#ifdef MCF547X + lea 0x165A,A0 // iorec RS232 +#else lea 0xF72,A0 // iorec RS232 +#endif move.w SR,D3 move.l D3,-(SP) or.l #0x700,D3 // mask interrupts @@ -2103,12 +2646,16 @@ Rsconf: // D0.W: baud, D1.W: ctrl, D2.W: ucr lea tab_baudrate(PC),A0 and.l #0xF,D0 asl.l #2,D0 - move.l (A0,D0.L),D0 + move.l (A0,D0.l),D0 move.l #SYSTEM_CLOCK*1000000,D2 - asl.l #5,D0 // * 32, baud + asl.l #4,D0 // * 16, baud .chip 68060 divu.l D0,D2 // ubgs .chip 5200 + lsr.l #1,D2 // 2 + bcc.s .set_speed + addq.l #1,D2 +.set_speed: move.l D2,D0 lsr.l #8,D0 move.b D0,MCF_UART_UBG10 @@ -2128,8 +2675,9 @@ Rsconf: // D0.W: baud, D1.W: ctrl, D2.W: ucr rts tab_baudrate: - dc.l 19200,9600,4800,3600,2400,2000,1800,1200,600,300,200,150 - dc.l 57600,38400,115200,76800 + dc.l 19200,9600,4800,3600,2400,2000,1800,1200,600,300 + // 200, 150, 134, 110, 75, 50 + dc.l 230400,115200,57600,38400,153600,76800 ikbd_codes: dc.b 1,2,3,3,3,3,4,5,6,7 @@ -2150,15 +2698,15 @@ arcvint: rts .av1: move.l 0x1136,-(SP) // MIDI - rts // (RTS by default) + rts // (sysmidi by default) .av2: sub.l #0xF6,D0 and.l #0xFF,D0 lea ikbd_codes(PC),A3 // IKBD codes table - move.b (A3,D0.L),D1 + move.b (A3,D0.l),D1 move.b D1,0x115A lea ikbd_length(PC),A3 // IKBD length table - move.b (A3,D0.L),D1 + move.b (A3,D0.l),D1 move.b D1,0x115B add.l #0xF6,D0 cmp.l #0xF8,D0 // mouse position ? @@ -2185,9 +2733,9 @@ arcvint: add.l D1,D2 subq.l #1,D2 asl.l #2,D2 - move.l (A2,D2.L),A0 // IKBD record pointer - move.l 4(A2,D2.L),A1 // index IKBD - move.l 8(A2,D2.L),A2 // interrupt routine + move.l (A2,D2.l),A0 // IKBD record pointer + move.l 4(A2,D2.l),A1 // index IKBD + move.l 8(A2,D2.l),A2 // interrupt routine move.l (A2),A2 // interrupt vector moveq #0,D2 move.b 0x115B,D2 // index IKBD @@ -2337,12 +2885,12 @@ ikbdvect2: move.l A0,-(SP) moveq #0,D1 move.b D0,D1 - move.l 0x1188,A0 + move.l 0x1188,A0 // table unshift and.l #0x7F,D0 move.b 0x1187,D2 btst #4,D2 // CAPS LOCK beq.s .iv16 - move.l 0x1190,A0 + move.l 0x1190,A0 // table capslock .iv16: btst #0,D2 // RIGHT SHIFT bne.s .iv17 @@ -2357,9 +2905,9 @@ ikbdvect2: moveq #0,D0 bra .iv20 .iv19: - move.l 0x118C,A0 + move.l 0x118C,A0 // table shift .iv18: - move.b (A0,D0.L),D0 + move.b (A0,D0.l),D0 btst #2,D2 // CTRL beq.s .iv22 cmp.l #0xD,D0 @@ -2554,12 +3102,15 @@ ikbdvect2: clr.w D2 swap D2 cmp.l #0xC53,D2 // CTRL ALT DEL - bne.s .iv45 - jmp 0xE00030 // reset -.iv45: + beq.s .watchdog_reset +// bne.s .iv45 +// jmp 0xE00030 // reset +//.iv45: cmp.l #0xD53,D2 // CTRL ALT LEFT-SHIFT DEL bne.s .iv46 - jmp 0xE0398C // cold reset + clr.l memvalid +// jmp 0xE0398C // cold reset + bra.s .watchdog_reset .iv46: move.b conterm,D2 btst #3,D2 @@ -2572,6 +3123,32 @@ ikbdvect2: .iv21: rts +.watchdog_reset: + + move.w #0x2700,SR + jsr disable_interrupts +#ifdef MCF5445X + move.w #SCM_CWCR_CWE + SCM_CWCR_CWRI(2) + SCM_CWCR_CWT(8),D0 + move.w D0,MCF_SCM_CWCR +#else /* MCF548X */ + clr.l MCF_GPT_GMS0 + move.w #SYSTEM_CLOCK,D0 + swap D0 +#ifdef DEBUG + move.w #-1,D0 // 65535 uS +#else + move.w #10,D0 // 10 uS +#endif + move.l D0,MCF_GPT_GCIR0 + move.l #MCF_GPT_GMS_TMS_GPIO + MCF_GPT_GMS_CE + MCF_GPT_GMS_WDEN,D0 + move.l D0,MCF_GPT_GMS0 // reset watchdog +#endif /* MCF5454X */ +.wait_reset_board: + nop + moveq #0x2E,D0 + move.b D0,MCF_UART_UTB0 + bra.s .wait_reset_board + keymaus1: moveq #5,D3 @@ -2609,8 +3186,8 @@ keymaus: int_ikbd: link A6,#-4 - lea -16(SP),SP - movem.l D0-D2/A0,(SP) + lea -56(SP),SP + movem.l D0-A5,(SP) moveq #MCF_UART_USR_RXRDY,D0 move.b MCF_UART_USR2,D2 // status and.l D2,D0 @@ -2633,23 +3210,23 @@ int_ikbd: lea 0xF96,A0 // iorec keyboard lea -4(A6),A1 // data - 2 for arcvint move.b D0,2(A1) // data - lea -16(SP),SP - movem.l D2/A0-A2,(SP) bsr arcvint // 0xE032EC - movem.l (SP),D2/A0-A2 - lea 16(SP),SP - bra.s .ik1 + bra.s .ik1 .ik2: moveq #MCF_UART_UCR_RESET_ERROR,D0 move.b D0,MCF_UART_UCR2 .ik1: - movem.l (SP),D0-D2/A0 - lea 16(SP),SP + movem.l (SP),D0-A5 + lea 56(SP),SP unlk A6 rte -ikbd_init: +ikbd_init: /* MCF5445X */ +#ifdef DEBUG + lea debug48(PC),A0 + bsr debug_display_string +#endif moveq #MCF_UART_UCR_RESET_TX,D0 move.b D0,MCF_UART_UCR2 // Reset Transmitter moveq #MCF_UART_UCR_RESET_RX,D0 @@ -2684,17 +3261,18 @@ ikbd_init: #else #ifdef MCF547X -int_ikbd: +#if 0 +int_ikbd: // Eiffel link A6,#-4 - lea -16(SP),SP - movem.l D0-D2/A0,(SP) + lea -56(SP),SP + movem.l D0-A5,(SP) moveq #MCF_UART_USR_RXRDY,D0 - move.b MCF_UART_USR3,D2 // status + move.b MCF_UART_USR1,D2 // status and.l D2,D0 beq.s .ik1 moveq #0,D0 - move.b MCF_UART_URB3,D0 // data + move.b MCF_UART_URB1,D0 // data moveq #0,D1 move.b #MCF_UART_USR_RB,D1 // receive break and.l D2,D1 @@ -2711,91 +3289,562 @@ int_ikbd: lea 0xF96,A0 // iorec keyboard lea -4(A6),A1 // data - 2 for arcvint move.b D0,2(A1) // data - lea -16(SP),SP - movem.l D2/A0-A2,(SP) bsr arcvint // 0xE032EC - movem.l (SP),D2/A0-A2 - lea 16(SP),SP bra.s .ik1 .ik2: moveq #MCF_UART_UCR_RESET_ERROR,D0 - move.b D0,MCF_UART_UCR3 + move.b D0,MCF_UART_UCR1 .ik1: - movem.l (SP),D0-D2/A0 - lea 16(SP),SP + movem.l (SP),D0-A5 + lea 56(SP),SP + unlk A6 + rte +#endif + +int6_mfp: + +// move.w #0x2700,SR + move.l TIMER_C_VEC,-(SP) // TOS404 0xE03C50 + move.l D0,-(SP) + move.l MCF_INTC_INTFRCL,D0 + and.l #MCF_INTC_INTFRCL_INTFRC6,D0 + bne .int6_forced + // normal INT6 + moveq #6,D0 + bset.b D0,MCF_EPORT_EPFR // clear interrupt + move.l D1,-(SP) + moveq #0,D1 + move.b 0xFFFFFA13,D1 // MFP IMRA (FPGA emulation) + asl.l #8,D1 + move.b 0xFFFFFA15,D1 // MFP IMRB (FPGA emulation) + move.b 0xFFFFFA0B,D0 // MFP IPRA (FPGA emulation) + asl.l #8,D0 + move.b 0xFFFFFA0D,D0 // MFP IPRB (FPGA emulation) +#if 0 + move.l D0,-(SP) +#if 1 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.w D1,D0 + bsr debug_hex_word + moveq #0x20,D0 + bsr debug_display_char + move.l ACP_INTERRUPT_PENDING,D0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l ACP_INTERRUPT_ENABLE,D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#else + moveq #0x4D,D0 + move.b D0,MCF_UART_UTB0 + move.l (SP),D0 + lsr.l #2,D0 + and.l #0xF,D0 + add.l #0x30,D0 + move.b D0,MCF_UART_UTB0 + moveq #0x20,D0 + move.b D0,MCF_UART_UTB0 +#endif + move.l (SP)+,D0 +#endif + and.l D1,D0 + move.l (SP)+,D1 + tst.l D0 + beq.s .is_not_mfp + move.l ACP_MFP_INTACK_VECTOR,D0 // (MFP vector base register + MFP int channel) * 4 + and.l #0x3FC,D0 + cmp.l #0x100,D0 + bcs.s .is_not_mfp + cmp.l #PSEUDO_DMA_VEC,D0 + bhi.s .is_not_mfp + cmp.l #IKBD_VEC,D0 + bne.s .int_mfp_ok + tst.b stop_mfp_ikbd + beq.s .int_mfp_ok + move.l A0,-(SP) // IKBD not connected, avoid null bytes + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + bclr #6,20(A0) // IMRB I/O bit 4, stop interrupt + bclr #6,8(A0) // IERB + bclr #6,12(A0) // IPRB + bclr #6,16(A0) // ISRB + move.l (SP)+,A0 +.is_not_mfp: + move.l (SP)+,D0 + rts +.int_mfp_ok: + move.l A0,-(SP) + move.l D0,A0 +#if 0 + bsr debug_hex_long + moveq #0x20,D0 + bsr debug_display_char + move.l (A0),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + move.l (A0),8(SP) // move vector content to return address + move.l (SP)+,A0 + move.l (SP)+,D0 + rts // jump to MFP vector +.int6_forced: // forced by rtos + move.l #~MCF_INTC_INTFRCL_INTFRC6,D0 + and.l D0,MCF_INTC_INTFRCL + move.l (SP)+,D0 + rts // jump to original timer C interrupt + +int_pseudo_dma: + + move.l A1,-(SP) + move.l A0,-(SP) + move.l D0,-(SP) +.ipd1: + lea ACP_FIFO_PSEUDO_DMA,A0 + move.l -12(A0),A1 // dma address + move.l -8(A0),D0 // byte counter + ble.s .ipd5 // err + btst #0,-16(A0) // write? + bne.s .ipd4 // write line + // read line +.ipd3: + btst #7,-4(A0) + beq.s .ipd2 + move.l (A0),(A1)+ // read 4 bytes + move.l (A0),(A1)+ // read 4 bytes + move.l (A0),(A1)+ // read 4 bytes + move.l (A0),(A1)+ // read 4 bytes + sub.l #16,D0 + bgt.s .ipd3 + bra.s .ipd2 + // write line +.ipd4: + btst #7,-4(A0) + beq.s .ipd2 + move.l (A1)+,(A0) // write 4 bytes + move.l (A1)+,(A0) // write 4 bytes + move.l (A1)+,(A0) // write 4 bytes + move.l (A1)+,(A0) // write 4 bytes + sub.l #16,D0 + bgt.s .ipd4 +.ipd2: + move.l A1,-12(A0) // dma address + move.l D0,-8(A0) // byte counter + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + btst #7,(A0) // GPIP + beq .ipd1 +.ipd5: + bclr #7,14(A0) // ISRA clear interrupt + move.l (SP)+,D0 + move.l (SP)+,A0 + move.l (SP)+,A1 + rte + +pseudo_dma_init: /* MCF547X */ + + lea int_pseudo_dma(PC),A0 + move.l A0,PSEUDO_DMA_VEC // MFP I/O bit 7 + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + bset #7,6(A0) // IERA I/O bit 7 + bset #7,18(A0) // IMRA I/O bit 7 enable interrupt + rts + +int_mfp_ikbd: + + link A6,#-4 + lea -56(SP),SP + movem.l D0-A5,(SP) + move.b 0xFFFFFC00,D0 // ACIA IKBD + move.b D0,D2 + btst #7,D0 + beq.s .imk1 // not interrupt request + btst #0,D0 + beq.s .imk2 // receiver empty + move.b 0xFFFFFC02,D0 // read data + lea 0xF96,A0 // iorec keyboard + lea -4(A6),A1 // data - 2 for arcvint + move.b D0,2(A1) // data + move.l D2,-(SP) + bsr arcvint // 0xE032EC + move.l (SP)+,D2 +.imk2: + btst #5,D2 + beq.s .imk1 // no error + move.b 0xFFFFFC02,D0 // read data +.imk1: + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + bclr #6,16(A0) // ISRB clear interrupt + movem.l (SP),D0-A5 + lea 56(SP),SP unlk A6 rte -ikbd_init: +ikbd_init: /* MCF547X */ +#ifdef DEBUG + lea debug48(PC),A0 + bsr debug_display_string +#endif +#if 0 + /* PSC1 - Eiffel */ moveq #MCF_UART_UCR_RESET_TX,D0 - move.b D0,MCF_UART_UCR3 // Reset Transmitter + move.b D0,MCF_UART_UCR1 // Reset Transmitter moveq #MCF_UART_UCR_RESET_RX,D0 - move.b D0,MCF_UART_UCR3 // Reset Receiver + move.b D0,MCF_UART_UCR1 // Reset Receiver moveq #MCF_UART_UCR_RESET_MR,D0 - move.b D0,MCF_UART_UCR3 // Reset Mode Register + move.b D0,MCF_UART_UCR1 // Reset Mode Register moveq #MCF_UART_UMR_PM_NONE + MCF_UART_UMR_BC_8,D0 - move.b D0,MCF_UART_UMR3 + move.b D0,MCF_UART_UMR1 moveq #MCF_UART_UMR_CM_NORMAL + MCF_UART_UMR_SB_STOP_BITS_1,D0 - move.b D0,MCF_UART_UMR3 + move.b D0,MCF_UART_UMR1 /* Set Rx and Tx baud by timer */ move.b #MCF_UART_UCSR_RCS_SYS_CLK + MCF_UART_UCSR_TCS_SYS_CLK,D0 - move.b D0,MCF_UART_UCSR3 + move.b D0,MCF_UART_UCSR1 move.l #(SYSTEM_CLOCK*1000000)/250000,D1 // 7812.5 bauds * 32 move.l D1,D0 // ubgs lsr.l #8,D0 - move.b D0,MCF_UART_UBG13 - move.b D1,MCF_UART_UBG23 + move.b D0,MCF_UART_UBG11 + move.b D1,MCF_UART_UBG21 /* Enable receiver and transmitter */ moveq #MCF_UART_UCR_TX_ENABLED + MCF_UART_UCR_RX_ENABLED,D0 - move.b D0,MCF_UART_UCR3 + move.b D0,MCF_UART_UCR1 lea int_ikbd(PC),A0 - move.l A0,(64+32+OFFSET_INT_CF68KLIB)*4 // PSC3 - moveq #0x22,D0 // level 4, priority 4 + move.l A0,(64+34+OFFSET_INT_CF68KLIB)*4 // PSC1 + moveq #0x24,D0 // level 4, priority 4 move.b D0,MCF_INTC_ICR34 move.l #~MCF_INTC_IMRH_INT_MASK32,D0 and.l D0,MCF_INTC_IMRH - move.l #~MCF_INTC_IMRL_MASKALL,D0 - and.l D0,MCF_INTC_IMRL // global mask moveq #MCF_UART_UIMR_RXRDY_FU,D0 - move.b D0,MCF_UART_UIMR3 // enable RX interrupts + move.b D0,MCF_UART_UIMR1 // enable RX interrupts +#endif + /* INT6 - MFP level 6 */ + moveq #3,D0 + move.b D0,0xFFFFFC00 // reset ACIA IKBD + move.b #0x96,D0 + move.b D0,0xFFFFFC00 // / 64, 8 bits, 1 stop, no parity + lea int_mfp_ikbd(PC),A0 + move.l A0,IKBD_VEC // MFP I/O bit 4 + lea 0xFFFFFA01,A0 // MFP (FPGA emulation) + bset #6,8(A0) // IERB I/O bit 4 + bset #6,20(A0) // IMRB I/O bit 4 enable interrupt rts -#else /* MCF548X - use CAN network for the IKBD with a special Eiffel version */ +int_rtc: -can_set_baudrate: + lea -24(SP),SP + movem.l D0-D2/A0-A2,(SP) + moveq #MCF_UART_USR_RXRDY,D0 + move.b MCF_UART_USR3,D2 // status + and.l D2,D0 + beq .ir1 + moveq #0,D0 + move.b MCF_UART_URB3,D0 // data + moveq #0,D1 + move.b #MCF_UART_USR_RB,D1 // receive break + and.l D2,D1 + bne.s .ir2 + moveq #MCF_UART_USR_PE,D1 // parity error + and.l D2,D1 + bne.s .ir2 + moveq #MCF_UART_USR_OE,D1 // overrun error + and.l D2,D1 + bne.s .ir2 + moveq #MCF_UART_USR_FE,D1 // framing error + and.l D2,D1 + bne.s .ir2 + cmp.l #2,D0 // need RTC data + bne.s .ir1 +.ir4: + move.b MCF_UART_USR3,D0 + and.l #MCF_UART_USR_TXEMP,D0 + beq.s .ir4 // full + move.b #0x82,D0 // header + move.b D0,MCF_UART_UTB3 // data + moveq #0,D1 + lea 0xFFFF8961,A1 // F030 RTC (offset 0) / NVM (offset 14) - FPGA emulation + lea 0xFFFF8963,A2 +.ir3: + move.b MCF_UART_USR3,D0 + and.l #MCF_UART_USR_TXEMP,D0 + beq.s .ir3 // full + move.b D1,(A1) // index + move.b (A2),D0 // data + move.b D0,MCF_UART_UTB3 // send data + addq.l #1,D1 + cmp.l #64,D1 + bcs.s .ir3 + bra.s .ir1 +.ir2: + moveq #MCF_UART_UCR_RESET_ERROR,D0 + move.b D0,MCF_UART_UCR3 +.ir1: + movem.l (SP),D0-D2/A0-A2 + lea 24(SP),SP + rte + +rtc_init: /* MCF547X - FIREBEE */ #ifdef DEBUG - lea debug12(PC),A0 + lea debug49(PC),A0 bsr debug_display_string #endif - move.l #MCF_CAN_CANMCR_HALT,D1 // stop - or.l D1,MCF_CAN_CANMCR1 -#if 0 // Sample Point at 85.7% - cmp.l #1000,D0 - bne.s .baud800 - move.l #MCF_CAN_CANCTRL_PRESDIV(4) \ - + MCF_CAN_CANCTRL_PROPSEG(7) \ - + MCF_CAN_CANCTRL_PSEG1(7) \ - + MCF_CAN_CANCTRL_PSEG2(2),D0 - bra.s .setbaud -.baud800: - cmp.l #800,D0 - bne.s .baud500 - move.l #MCF_CAN_CANCTRL_PRESDIV(4) \ - + MCF_CAN_CANCTRL_PROPSEG(7) \ - + MCF_CAN_CANCTRL_PSEG1(7) \ - + MCF_CAN_CANCTRL_PSEG2(7),D0 - bra.s .setbaud -.baud500: - cmp.l #500,D0 - bne.s .baud250 - move.l #MCF_CAN_CANCTRL_PRESDIV(9) \ - + MCF_CAN_CANCTRL_PROPSEG(7) \ - + MCF_CAN_CANCTRL_PSEG1(7) \ - + MCF_CAN_CANCTRL_PSEG2(2),D0 - bra.s .setbaud -.baud250: + link A6,#-66 + moveq #MCF_UART_UCR_RESET_TX,D0 + move.b D0,MCF_UART_UCR3 // Reset Transmitter + moveq #MCF_UART_UCR_RESET_RX,D0 + move.b D0,MCF_UART_UCR3 // Reset Receiver + moveq #MCF_UART_UCR_RESET_MR,D0 + move.b D0,MCF_UART_UCR3 // Reset Mode Register + moveq #MCF_UART_UMR_PM_NONE + MCF_UART_UMR_BC_8,D0 + move.b D0,MCF_UART_UMR3 + moveq #MCF_UART_UMR_CM_NORMAL + MCF_UART_UMR_SB_STOP_BITS_1,D0 + move.b D0,MCF_UART_UMR3 + /* Set Rx and Tx baud by timer */ + move.b #MCF_UART_UCSR_RCS_SYS_CLK + MCF_UART_UCSR_TCS_SYS_CLK,D0 + move.b D0,MCF_UART_UCSR3 + move.l #(SYSTEM_CLOCK*1000000)/(115200*32),D1 // 115200 bauds * 32 + move.l D1,D0 // ubgs + lsr.l #8,D0 + move.b D0,MCF_UART_UBG13 + move.b D1,MCF_UART_UBG23 + /* Enable receiver and transmitter */ + moveq #MCF_UART_UCR_TX_ENABLED + MCF_UART_UCR_RX_ENABLED,D0 + move.b D0,MCF_UART_UCR3 + lea tab_rtc_init(PC),A0 // ACPF + moveq #3,D0 + bsr rtc_ws + lea -4(A6),A0 + clr.l (A0) + moveq #2,D0 + bsr rtc_rd + bpl.s .ri4 // read OK! ? + // timeout +#ifdef DEBUG + lea debug54(PC),A0 + bsr debug_display_string +#endif + bra.s .ri5 +.ri4: +#ifdef DEBUG + lea debug53(PC),A0 + bsr debug_display_string + move.l -4(A6),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + move.l -4(A6),D0 + cmp.l #0x4F4B2100,D0 // OK! + bne .ri3 +#ifdef DEBUG + lea debug50(PC),A0 + bsr debug_display_string +#endif +.ri5: + lea -4(A6),A0 + moveq #1,D0 + move.b D0,(A0) // cmd + moveq #0,D0 + bsr rtc_ws + lea -65(A6),A0 // read buffer + clr.b (A0) + moveq #64,D0 // header + len - 1 + bsr rtc_rd + bmi .ri3 // timeout +#ifdef DEBUG + lea debug53(PC),A0 + bsr debug_display_string + move.b -65(A6),D0 + bsr debug_hex_byte + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char +#endif + moveq #0,D0 + move.b -65(A6),D0 + cmp.l #0x81,D0 // header + bne .ri3 +#ifdef DEBUG + lea debug51(PC),A0 + bsr debug_display_string +#endif + lea -64+14(A6),A0 // stack read buffer, NVM offset + moveq #0,D0 + moveq #47,D1 + moveq #0,D2 // checksum loop +.ri6: + move.b (A0)+,D2 + add.l D2,D0 + subq.l #1,D1 + bpl.s .ri6 + and.l #0xFF,D0 + move.b (A0)+,D1 + not.l D1 +#if 1 // 2nd byte seems is bad ??? + move.b D1,(A0) +#endif + cmp.l D1,D0 + bne.s .ri7 // bad checksum + move.b (A0)+,D1 + cmp.l D1,D0 + beq.s .ri8 // checksum OK +.ri7: +#ifdef DEBUG + lea debug55(PC),A0 + bsr debug_display_string +#endif + lea -64+14(A6),A0 // stack read buffer, NVM offset + moveq #0,D0 // clear NVM read buffer + moveq #47,D1 +.ri9: + clr.b (A0)+ + subq.l #1,D1 + bpl.s .ri9 + move.b D1,(A0)+ // new checksum + clr.b (A0)+ +.ri8: + moveq #0,D1 + lea -64(A6),A0 // stack read buffer + lea 0xFFFF8961,A1 // F030 RTC (offset 0) / NVM (offset 14) - FPGA emulation + lea 0xFFFF8963,A2 +.ri2: + move.b D1,(A1) // index + move.b (A0)+,(A2) // data + addq.l #1,D1 + cmp.l #64,D1 + bcs.s .ri2 + lea int_rtc(PC),A0 + move.l A0,(64+32+OFFSET_INT_CF68KLIB)*4 // PSC3 + moveq #0x9,D0 // level 1, priority 1 + move.b D0,MCF_INTC_ICR32 + move.l #~MCF_INTC_IMRH_INT_MASK32,D0 + and.l D0,MCF_INTC_IMRH + move.l #~MCF_INTC_IMRL_MASKALL,D0 + and.l D0,MCF_INTC_IMRL // global mask + moveq #MCF_UART_UIMR_RXRDY_FU,D0 + move.b D0,MCF_UART_UIMR3 // enable RX interrupts + moveq #0,D0 // OK + bra.s .ri1 +.ri3: +#ifdef DEBUG + lea debug52(PC),A0 + bsr debug_display_string +#endif + moveq #-1,D0 // timeout +.ri1: + unlk A6 + rts + +tab_rtc_init: + .ascii "ACPF" + .align 2 + +rtc_ws: // D0.W: len-1, A0: buffer + + moveq #0,D2 + move.w D0,D2 // len -1 +.rw1: + move.b MCF_UART_USR3,D1 + and.l #MCF_UART_USR_TXEMP,D1 + beq.s .rw1 // full + move.b (A0)+,D0 // data inside the buffer + move.b D0,MCF_UART_UTB3 // data + subq.l #1,D2 + bpl.s .rw1 + moveq #0,D0 // OK + rts + +rtc_rd: // D0.W: len-1, A0: buffer + + moveq #0,D3 + move.w D0,D3 // len -1 +.rr3: + move.l MCF_SLT_SCNT1,D1 +.rr1: + moveq #MCF_UART_USR_RXRDY,D0 + move.b MCF_UART_USR3,D2 // status + and.l D2,D0 + beq.s .rr2 // nothing + moveq #0,D0 + move.b MCF_UART_URB3,D0 // data + move.b D0,(A0)+ // store data inside the buffer + subq.l #1,D3 + bpl.s .rr3 + moveq #0,D0 + rts // OK +.rr2: + move.l D1,D0 + sub.l MCF_SLT_SCNT1,D0 + cmp.l #1000000*SYSTEM_CLOCK,D0 // 1 S + bcs.s .rr1 + moveq #-1,D0 // timeout + rts + +sysmidi: /* MCF547X */ + + moveq #0,D2 + move.w 4(A0),D2 // buffer size + moveq #0,D1 + move.w 8(A0),D1 // tail index + addq.l #1,D1 + cmp.l D2,D1 + bcs.s .smd1 + moveq #0,D1 +.smd1: + move.w 6(A0),D2 // head index + cmp.l D2,D1 + beq.s .smd2 + move.l (A0),A2 // buffer + move.b D0,(A2,D1.l) // store received data + move.w D1,8(A0) // tail index +.smd2: + rts + +#else /* MCF548X - use CAN network for the IKBD with a special Eiffel version */ + +can_set_baudrate: + +#ifdef DEBUG + lea debug12(PC),A0 + bsr debug_display_string +#endif + move.l #MCF_CAN_CANMCR_HALT,D1 // stop + or.l D1,MCF_CAN_CANMCR1 +#if 0 // Sample Point at 85.7% + cmp.l #1000,D0 + bne.s .baud800 + move.l #MCF_CAN_CANCTRL_PRESDIV(4) \ + + MCF_CAN_CANCTRL_PROPSEG(7) \ + + MCF_CAN_CANCTRL_PSEG1(7) \ + + MCF_CAN_CANCTRL_PSEG2(2),D0 + bra.s .setbaud +.baud800: + cmp.l #800,D0 + bne.s .baud500 + move.l #MCF_CAN_CANCTRL_PRESDIV(4) \ + + MCF_CAN_CANCTRL_PROPSEG(7) \ + + MCF_CAN_CANCTRL_PSEG1(7) \ + + MCF_CAN_CANCTRL_PSEG2(7),D0 + bra.s .setbaud +.baud500: + cmp.l #500,D0 + bne.s .baud250 + move.l #MCF_CAN_CANCTRL_PRESDIV(9) \ + + MCF_CAN_CANCTRL_PROPSEG(7) \ + + MCF_CAN_CANCTRL_PSEG1(7) \ + + MCF_CAN_CANCTRL_PSEG2(2),D0 + bra.s .setbaud +.baud250: cmp.l #250,D0 bne.s .baud125 move.l #MCF_CAN_CANCTRL_PRESDIV(0x18) \ @@ -2917,7 +3966,7 @@ can_send_message: // D0:num, D1:ID, D2:DLC, A0:data move.l D1,D0 bsr debug_hex_word moveq #0x20,D0 - bsr display_char + bsr debug_display_char move.l D2,D0 bsr debug_hex_byte moveq #0x20,D0 @@ -2986,8 +4035,8 @@ can_send_message: // D0:num, D1:ID, D2:DLC, A0:data int_can: link A6,#-10 - lea -32(SP),SP - movem.l D0-D3/A0-A3,(SP) + lea -56(SP),SP + movem.l D0-A5,(SP) lea MCF_CAN_MSGBUF1+(15*16),A1 // message 15 move.l (A1),D2 // control/status move.l 4(A1),D1 @@ -3051,8 +4100,8 @@ int_can: move.w MCF_CAN_IFLAG1,D0 and.l #MCF_CAN_IFLAG_BUF15I,D0 move.w D0,MCF_CAN_IFLAG1 // clear interrupt - movem.l (SP),D0-D3/A0-A3 - lea 32(SP),SP + movem.l (SP),D0-A5 + lea 56(SP),SP unlk A6 rte @@ -3142,6 +4191,7 @@ _Setscreen: Setscreen: // D0.W: rez, D1.W: modecode, A0: logbase, A1: physbase #ifdef DEBUG + move.l D0,-(SP) move.l A0,-(SP) lea debug26(PC),A0 @@ -3280,11 +4330,18 @@ debug1r: .asciz "NVMaccess read 0x" debug1w: .asciz "NVMaccess write 0x" debug1c: .ascii "NVMaccess clear" .byte 13,10,0 +#ifdef MCF547X +debug2: .ascii "Init timers, serial and MFP" + .byte 13,10,0 +#else /* !MCF547X */ debug2: .ascii "Init timers, serial and CAN" .byte 13,10,0 +#endif /* MCF547X */ + debug3: .asciz "Flash parameter 0x" debug3r: .asciz " read 0x" debug3w: .asciz " write 0x" +debug3wb: .asciz " = 0x" debug4: .byte 13,13 .ascii "Rsconf" .byte 13,10,13,13,0 @@ -3299,6 +4356,7 @@ debug6: .ascii "initint" debug7: .asciz "Jdisint 0x" debug8: .asciz "Jenabint 0x" #ifndef MCF5445X /* no CAN network on MCF5445X */ +#ifndef MCF547X debug9: .ascii "CAN init" .byte 13,10,0 debug10: .ascii "Ikbdws" @@ -3317,7 +4375,8 @@ debug15: .ascii "CAN enable interrupt message 15" .byte 13,10,0 debug16: .ascii "CAN start the chip" .byte 13,10,0 -#endif +#endif /* MCF547X */ +#endif /* MCF5445X */ debug17: .ascii "Cache enable" .byte 13,10,0 debug18: .ascii "Cache disable" @@ -3330,8 +4389,10 @@ debug22: .asciz "Install vector 0x" debug22b: .asciz " at 0x" debug23: .ascii "Test RTC" .byte 13,10,0 +#ifndef MCF547X debug24: .ascii "Gettime IKBD" .byte 13,10,0 +#endif debug25: .asciz "XBIOS #0x" debug26: .asciz "Setscreen 0x" debug27: .ascii "PCI set up the arbiter" @@ -3356,14 +4417,14 @@ debug35c: .asciz " ERRCNT 0x" debug35d: .asciz " ERRSTAT 0x" debug36: .asciz "PCICAR 0x" debug37: .asciz "PCIIWxBTAR 0x" +debug39: .asciz "PCIIDR 0x" debug38: .ascii "Delay 300 mS reset IKBD" .byte 13,10,0 debug38b: .ascii "End delay IKBD" .byte 13,10,0 -debug39: .asciz "PCIIDR 0x" debug40: .asciz "PCIREV 0x" debug41: .asciz "PCIBARx " -debug42: .ascii "PCI Retry Error received" +debug42: .ascii "PCI Parity error" .byte 13,10,0 debug43: .ascii "PCI Initiator Abort received" .byte 13,10,0 @@ -3374,6 +4435,27 @@ debug46: .ascii "Multi function device found" .byte 13,10,0 debug47: .ascii "This device is not a multi function device" .byte 13,10,0 +#if defined(MCF5445X) || defined(MCF547X) +debug48: .ascii "Init IKBD" + .byte 13,10,0 +#endif +#ifdef MCF547X +debug49: .ascii "Init PIC RTC" + .byte 13,10,0 +debug50: .ascii "Get OK! from PIC" + .byte 13,10,0 +debug51: .ascii "Read PIC RTC frame" + .byte 13,10,0 +debug52: .ascii "Timeout or bad header received from PIC RTC" + .byte 13,10,0 +debug53: .asciz "PIC answer 0x" +debug54: .ascii "Timeout from PIC RTC, OK! not received, continue..." + .byte 13,10,0 +debug55: .ascii "PIC RTC bad checksum, reset all" + .byte 13,10,0 +debug56: .ascii "Write NVM to PIC RTC" + .byte 13,10,0 +#endif .align 2 @@ -3429,6 +4511,10 @@ debug_display_char: #endif /* DEBUG */ +#ifdef COLDFIRE +#undef DEBUG +#endif + #else /* ATARI */ #ifdef DEBUG @@ -3449,25 +4535,80 @@ debug28: .asciz "PCI PLX word access failure, read: 0x" debug29: .byte 13,10 .ascii "PCI init PLX registers" .byte 13,10,0 -debug30: .ascii "PCI PLX local registers by default are in big endian" - .byte 13,10,0 -debug31b: .ascii "PCI PLX local registers are in big endian" - .byte 13,10,0 -debug31l: .ascii "PCI PLX local registers are in little endian" - .byte 13,10,0 debug32: .ascii "PCI init driver" .byte 13,10,0 debug33: .ascii "PCI init devices" .byte 13,10,0 debug34: .ascii "Add cookie _PCI" .byte 13,10,0 -debug35: .asciz "Parity error, read 0x" -debug35b: .asciz " at 0x" -debug36: .asciz "DMCFGA 0x" -debug37: .asciz "Parity error target, read 0x" -debug38: .asciz "Parity error target, write 0x" -debug39: .asciz "Master abort at 0x" -debug40: .ascii "Retry (y/n) ?" +debug40: .ascii "find_pci_device" + .byte 13,10,0 +debug41: .ascii "find_pci_classcode" + .byte 13,10,0 +debug42: .asciz "read_config_byte " +debug43: .asciz "read_config_word " +debug44: .asciz "read_config_longword " +debug45: .asciz "fast_read_config_byte " +debug46: .asciz "fast_read_config_word " +debug47: .asciz "fast_read_config_longword " +debug48: .asciz "write_config_byte " +debug49: .asciz "write_config_word " +debug50: .asciz "write_config_longword " +debug51: .asciz "hook_interrupt " +debug52: .ascii "unhook_interrupt" + .byte 13,10,0 +debug53: .ascii "special_cycle" + .byte 13,10,0 +debug54: .ascii "get_routing" + .byte 13,10,0 +debug55: .ascii "set_interrupt" + .byte 13,10,0 +debug56: .asciz "get_resource " +debug57: .ascii "get_card_used" + .byte 13,10,0 +debug58: .ascii "set_card_used" + .byte 13,10,0 +debug59: .ascii "read_mem_byte" + .byte 13,10,0 +debug60: .ascii "read_mem_word" + .byte 13,10,0 +debug61: .ascii "read_mem_longword" + .byte 13,10,0 +debug62: .ascii "fast_read_mem_byte" + .byte 13,10,0 +debug63: .ascii "fast_read_mem_word" + .byte 13,10,0 +debug64: .ascii "fast_read_mem_longword" + .byte 13,10,0 +debug65: .asciz "write_mem_byte " +debug66: .asciz "write_mem_word " +debug67: .asciz "write_mem_longword " +debug68: .ascii "read_io_byte" + .byte 13,10,0 +debug69: .ascii "read_io_word" + .byte 13,10,0 +debug70: .ascii "read_io_longword" + .byte 13,10,0 +debug71: .ascii "fast_read_io_byte" + .byte 13,10,0 +debug72: .ascii "fast_read_io_word" + .byte 13,10,0 +debug73: .ascii "fast_read_io_longword" + .byte 13,10,0 +debug74: .asciz "write_io_byte " +debug75: .asciz "write_io_word " +debug76: .asciz "write_io_longword " +debug77: .ascii "get_machine_id" + .byte 13,10,0 +debug78: .ascii "get_pagesize" + .byte 13,10,0 +debug79: .ascii "virt_to_bus" + .byte 13,10,0 +debug80: .ascii "bus_to_virt" + .byte 13,10,0 +debug81: .ascii "virt_to_phys" + .byte 13,10,0 +debug82: .ascii "phys_to_virt" .byte 13,10,0 .align 2 @@ -3510,10 +4651,34 @@ debug_display_char: movem.l D0-D2/A0-A2,-(SP) move.w D0,-(SP) + move.l #0x5F504349,D0 + lea 0xED0000,A0 // 128 KB + cmp.l (A0),D0 // _PCI + beq.s .ddc2 + lea 0xEC0000,A0 // 192 KB + cmp.l (A0),D0 // _PCI + beq.s .ddc2 + lea 0xEB0000,A0 // 256 KB + cmp.l (A0),D0 // _PCI + beq.s .ddc2 + lea 0xEA0000,A0 // 320 KB + cmp.l (A0),D0 // _PCI + bne.s .ddc3 +.ddc2: + move.w (SP),D0 // character + swap D0 + move.w #0x0076,D0 // 'v' + move.l D0,-(SP) + jsr 40(A0) // drivers PCI in flash, dbug + addq.l #4,SP + bne.s .ddc1 +.ddc3: move.w #2,-(SP) move.w #3,-(SP) // Bconout trap #13 - addq.l #6,SP + addq.l #4,SP +.ddc1: + addq.l #2,SP movem.l (SP)+,D0-D2/A0-A2 rts @@ -3544,7 +4709,7 @@ det_xbios: move.w (A0),D0 // function cmp.l #0xB,D0 // unused (DEBUG_GEMDOS) beq. .xb0 - cmp.l #353,D0 + cmp.l #356,D0 bhi .xb00 cmp.l #299,D0 // BIOS PCI bcc .xb0 @@ -3577,13 +4742,15 @@ det_xbios: .xb25: #endif #ifdef COLDFIRE +#ifndef MCF547X cmp.l #0x2C,D0 // Bconmap beq.s .xb27 // just one serial port, no Bconmap +#endif cmp.l #0x96,D0 // VsetMask bhi .xb10 - move.w tab_xbios(PC,D0.L*2),D0 + move.w tab_xbios(PC,D0.l*2),D0 bmi .xb1 - jmp tab_xbios(PC,D0.L) + jmp tab_xbios(PC,D0.l) .xb27: moveq #0,D0 // no Bconmap rte @@ -3614,7 +4781,11 @@ tab_xbios: #endif dc.w _Mfpint-tab_xbios // 0xD Mfpint dc.w -1 // 0xE Iorec +#ifdef MCF547X + dc.w -1 // 0xF Rsconf +#else dc.w _Rsconf-tab_xbios // 0xF Rsconf +#endif dc.w -1 // 0x10 Keytbl dc.w -1 // 0x11 Random dc.w -1 // 0x12 Protobt @@ -3809,7 +4980,7 @@ _Rsconf: move.w 4(A0),D1 // ctrl move.w 6(A0),D2 // ucr bsr Rsconf - rte + rte _Ikbdws: @@ -4069,59 +5240,150 @@ _Vgetsize: rte .xb15: #ifdef COLDFIRE - cmp.l #353,D0 + cmp.l #356,D0 bhi .xb26 cmp.l #299,D0 // BIOS PCI bcs .xb1 sub.l #299,D0 - move.w tab_pci_bios(PC,D0.L*2),D0 + move.w tab_pci_bios(PC,D0.l*2),D0 bmi .xb1 // original TOS XBIOS - jsr tab_pci_bios(PC,D0.L) + jsr tab_pci_bios(PC,D0.l) + rte #else - cmp.w #353,D0 + cmp.w #356,D0 bhi .xb26 cmp.w #299,D0 // BIOS PCI bcs .xb1 sub.w #299,D0 + bne.s .xb27 + lea install_pci_bios_magic(PC),A1 + move.l A1,0x80 // trap #0 +.xb27: move.w tab_pci_bios(PC,D0.W*2),D0 - bmi .xb1 // original TOS XBIOS + bmi .xb1 // original TOS XBIOS jsr tab_pci_bios(PC,D0.W) -#endif rte -tab_pci_bios: - dc.w _install_pci_bios-tab_pci_bios // 299 - dc.w _find_pci_device-tab_pci_bios // 300 - dc.w _find_pci_classcode-tab_pci_bios // 301 - dc.w _read_config_byte-tab_pci_bios // 302 - dc.w _read_config_word-tab_pci_bios // 303 - dc.w _read_config_longword-tab_pci_bios // 304 - dc.w _fast_read_config_byte-tab_pci_bios // 305 - dc.w _fast_read_config_word-tab_pci_bios // 306 - dc.w _fast_read_config_longword-tab_pci_bios // 307 - dc.w _write_config_byte-tab_pci_bios // 308 - dc.w _write_config_word-tab_pci_bios // 309 - dc.w _write_config_longword-tab_pci_bios // 310 - dc.w _hook_interrupt-tab_pci_bios // 311 - dc.w _unhook_interrupt-tab_pci_bios // 312 - dc.w _special_cycle-tab_pci_bios // 313 - dc.w _get_routing-tab_pci_bios // 314 - dc.w _set_interrupt-tab_pci_bios // 315 - dc.w _get_resource-tab_pci_bios // 316 - dc.w _get_card_used-tab_pci_bios // 317 - dc.w _set_card_used-tab_pci_bios // 318 - dc.w _read_mem_byte-tab_pci_bios // 319 - dc.w _read_mem_word-tab_pci_bios // 320 - dc.w _read_mem_longword-tab_pci_bios // 321 - dc.w _fast_read_mem_byte-tab_pci_bios // 322 - dc.w _fast_read_mem_word-tab_pci_bios // 323 - dc.w _fast_read_mem_longword-tab_pci_bios // 324 - dc.w _write_mem_byte-tab_pci_bios // 325 - dc.w _write_mem_word-tab_pci_bios // 326 - dc.w _write_mem_longword-tab_pci_bios // 327 - dc.w _read_io_byte-tab_pci_bios // 328 - dc.w _read_io_word-tab_pci_bios // 329 - dc.w _read_io_longword-tab_pci_bios // 330 - dc.w _fast_read_io_byte-tab_pci_bios // 331 + +det_xbios_magic: + + move.l USP,A0 + btst #5,(SP) // call in supervisor state + beq.s .xb28 + lea 8(SP),A0 +.xb28: + move.w (A0),D0 // function + cmp.w #read_core_temperature,D0 + beq.s .xb33 + cmp.w #read_core_temperature_bis,D0 + bne.s .xb34 +.xb33: + move.w 2(A0),-(SP) // deg_type + jsr ct60_read_temp + cmp.w #CT60_CELCIUS,(SP) + beq.s .xb35 + cmp.w #CT60_FARENHEIT,(SP) + bne.s .xb36 + mulu #9,D0 + divu #5,D0 + add.w #32,D0 + ext.l D0 + bra.s .xb35 +.xb36: + moveq #CT60_READ_ERROR,D0 // error +.xb35: + addq.l #2,SP + rte +.xb34: + cmp.w #rw_parameter,D0 + beq.s .xb37 + cmp.w #rw_parameter_bis,D0 + bne.s .xb38 +.xb37: + move.w 2(A0),D0 // mode + move.l 4(A0),D1 // type_param + move.l 8(A0),D2 // value + jsr ct60_rw_param + rte +.xb38: + cmp.w #cache,D0 + beq.s .xb39 + cmp.w #cache_bis,D0 + bne.s .xb40 +.xb39: + move.w 2(A0),D0 + bmi.s .xb42 + bne.s .xb41 + jsr 0xE0085A // caches off + bra.s .xb42 +.xb41: + jsr 0xE250C8 // caches on +.xb42: + movec.l CACR,D0 + rte +.xb40: + cmp.w #flush_cache,D0 + beq.s .xb43 + cmp.w #flush_cache_bis,D0 + bne.s .xb29 +.xb43: + cpusha BC + moveq #0,D0 + rte +.xb29: + cmp.w #356,D0 + bhi.s .xb30 + cmp.w #299,D0 // BIOS PCI + bcs.s .xb30 + sub.w #299,D0 + move.w tab_pci_bios(PC,D0.W*2),D0 + bmi.s .xb30 // original TOS XBIOS + jsr tab_pci_bios(PC,D0.W) + rte +.xb30: + move.l RESERVED_VEC,A0 // where old xbios XBRA vector is saved ! + cmp.l #0x58425241,(A0) // XBRA + bne.s .xb31 // invalid + cmp.l #0x63743630,4(A0) // ct60 + bne.s .xb31 // invalid + move.l 8(A0),-(SP) // jump to MagiC XBIOS vector + rts +.xb31: + bra.s .xb31 // XBRA invalid => infinite loop ! +#endif /* COLDFIRE */ +tab_pci_bios: + dc.w _install_pci_bios-tab_pci_bios // 299 + dc.w _find_pci_device-tab_pci_bios // 300 + dc.w _find_pci_classcode-tab_pci_bios // 301 + dc.w _read_config_byte-tab_pci_bios // 302 + dc.w _read_config_word-tab_pci_bios // 303 + dc.w _read_config_longword-tab_pci_bios // 304 + dc.w _fast_read_config_byte-tab_pci_bios // 305 + dc.w _fast_read_config_word-tab_pci_bios // 306 + dc.w _fast_read_config_longword-tab_pci_bios // 307 + dc.w _write_config_byte-tab_pci_bios // 308 + dc.w _write_config_word-tab_pci_bios // 309 + dc.w _write_config_longword-tab_pci_bios // 310 + dc.w _hook_interrupt-tab_pci_bios // 311 + dc.w _unhook_interrupt-tab_pci_bios // 312 + dc.w _special_cycle-tab_pci_bios // 313 + dc.w _get_routing-tab_pci_bios // 314 + dc.w _set_interrupt-tab_pci_bios // 315 + dc.w _get_resource-tab_pci_bios // 316 + dc.w _get_card_used-tab_pci_bios // 317 + dc.w _set_card_used-tab_pci_bios // 318 + dc.w _read_mem_byte-tab_pci_bios // 319 + dc.w _read_mem_word-tab_pci_bios // 320 + dc.w _read_mem_longword-tab_pci_bios // 321 + dc.w _fast_read_mem_byte-tab_pci_bios // 322 + dc.w _fast_read_mem_word-tab_pci_bios // 323 + dc.w _fast_read_mem_longword-tab_pci_bios // 324 + dc.w _write_mem_byte-tab_pci_bios // 325 + dc.w _write_mem_word-tab_pci_bios // 326 + dc.w _write_mem_longword-tab_pci_bios // 327 + dc.w _read_io_byte-tab_pci_bios // 328 + dc.w _read_io_word-tab_pci_bios // 329 + dc.w _read_io_longword-tab_pci_bios // 330 + dc.w _fast_read_io_byte-tab_pci_bios // 331 dc.w _fast_read_io_word-tab_pci_bios // 332 dc.w _fast_read_io_longword-tab_pci_bios // 333 dc.w _write_io_byte-tab_pci_bios // 334 @@ -4144,6 +5406,9 @@ tab_pci_bios: dc.w _dma_buffoper-tab_pci_bios // 351 dc.w _read_mailbox-tab_pci_bios // 352 dc.w _write_mailbox-tab_pci_bios // 353 + dc.w _dma_alloc-tab_pci_bios // 354 + dc.w _dma_free-tab_pci_bios // 355 + dc.w _dma_lock-tab_pci_bios // 356 .xb26: #ifdef COLDFIRE cmp.l #read_core_temperature,D0 @@ -4152,14 +5417,14 @@ tab_pci_bios: bne.s .xb5 .xb11: moveq #0,D0 -#else +#else /* !COLDFIRE */ cmp.w #read_core_temperature,D0 beq.s .xb11 cmp.w #read_core_temperature_bis,D0 bne.s .xb5 .xb11: move.w 2(A0),-(SP) // deg_type - bsr ct60_read_temp + jsr ct60_read_temp cmp.w #CT60_CELCIUS,(SP) beq.s .xb3 cmp.w #CT60_FARENHEIT,(SP) @@ -4173,7 +5438,7 @@ tab_pci_bios: moveq #CT60_READ_ERROR,D0 // error .xb3: addq.l #2,SP -#endif +#endif /* COLDFIRE */ rte .xb5: #ifdef COLDFIRE @@ -4185,16 +5450,60 @@ tab_pci_bios: beq.s .xb12 cmp.w #rw_parameter_bis,D0 #endif - bne.s .xb6 + bne .xb6 .xb12: move.w 2(A0),D0 // mode move.l 4(A0),D1 // type_param move.l 8(A0),D2 // value #ifdef COLDFIRE - bsr fire_rw_param -#else - bsr ct60_rw_param -#endif +#ifdef DEBUG + move.l D0,-(SP) + move.l D0,-(SP) + lea debug3(PC),A0 + bsr debug_display_string + move.l D1,D0 + bsr debug_hex_char + btst #0,3+4(SP) + beq.s .not_dbg_write + lea debug3w(PC),A0 + bsr debug_display_string + move.l D2,D0 + bsr debug_hex_long +.not_dbg_write: + move.l (SP)+,D0 +#endif /* DEBUG */ + jsr fire_rw_param +#ifdef DEBUG + btst #0,3(SP) + bne.s .not_dbg_read + move.l D0,-(SP) + lea debug3r(PC),A0 + bsr debug_display_string + move.l (SP),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 + bra.s .end_dbg_read +.not_dbg_read: + move.l D0,-(SP) + lea debug3wb(PC),A0 + bsr debug_display_string + move.l (SP),D0 + bsr debug_hex_long + moveq #13,D0 + bsr debug_display_char + moveq #10,D0 + bsr debug_display_char + move.l (SP)+,D0 +.end_dbg_read: + addq.l #4,SP +#endif /* DEBUG */ +#else /* !COLDFIRE */ + jsr ct60_rw_param +#endif /* COLDFIRE */ rte .xb6: #ifdef COLDFIRE @@ -4228,6 +5537,10 @@ tab_pci_bios: .chip 5200 rte .xb9: + cmp.l #vmalloc,D0 + beq.s .xb32 + cmp.l #vmalloc_bis,D0 + beq.s .xb32 cmp.l #flush_cache,D0 beq.s .xb14 cmp.l #flush_cache_bis,D0 @@ -4241,6 +5554,10 @@ tab_pci_bios: movec.l CACR,D0 rte .xb9: + cmp.w #vmalloc,D0 + beq.s .xb32 + cmp.w #vmalloc_bis,D0 + beq.s .xb32 cmp.w #flush_cache,D0 beq.s .xb14 cmp.w #flush_cache_bis,D0 @@ -4248,6 +5565,7 @@ tab_pci_bios: .xb14: cpusha BC #endif +.xb32: moveq #0,D0 rte .xb1: @@ -4299,11 +5617,161 @@ tab_pci_bios: move.w (A1)+,-(SP) // restore SR move.l A1,savptr rte -#else +#else /* !COLDFIRE */ move.l det_xbios-4(PC),-(SP) rts -#endif + +test_pci_drivers: + + move.l #0x5F504349,D0 // _PCI + lea 0xED0000,A0 // 128 KB, 1st part + cmp.l (A0),D0 // _PCI + beq.s .test_pci_ok + lea 0xEC0000,A0 // 192 KB, 1st part + cmp.l (A0),D0 // _PCI + beq.s .test_pci_ok + lea 0xEB0000,A0 // 256 KB, 1st part + cmp.l (A0),D0 // _PCI + beq.s .test_pci_ok + lea 0xEA0000,A0 // 320 KB, 1st part + cmp.l (A0),D0 // _PCI +.test_pci_ok: // (optional 2nd part inside 0xFC0000-0xFEFFFF) + rts +magic_routine: // called before auto folder + + jmp install_scsidrv +end_magic_routine: + +install_magic_routine: + + lea magic_routine(PC),A0 + pea end_magic_routine(PC) + move.l phystop,A1 + lea -512(A1),A1 + move.l #0x12123456,(A1) // magic key + move.l A1,4(A1) + move.w #((512-8)/2)-2,D1 + move.w (A1)+,D0 + add.w (A1)+,D0 + add.w (A1)+,D0 + add.w (A1)+,D0 +.copy_magic_routine: + cmp.l (SP),A0 + bcc.s .fill_end_magic_routine + add.w (A0),D0 + move.w (A0)+,(A1)+ + dbf D1,.copy_magic_routine + bra.s .end_copy_magic_routine +.fill_end_magic_routine: + clr.w (A1)+ + dbf D1,.fill_end_magic_routine +.end_copy_magic_routine: + move.w #0x5678,D1 // checksum + sub.w D0,D1 + move.w D1,(A1)+ + addq.l #4,SP + rts + +install_pci_bios_magic: // trap #0 handler called when MagiC enable interrupts (trap #1 not exist, seems always TOS) + + movem.l D1-A6,-(SP) + move.l #0x4D616758,D0 // MagX + bsr get_cookie + beq .no_install // not found + move.l #0x5F504349,D0 // _PCI cookie + bsr get_cookie + bne .no_install // found + move.l #((3*4)+(3*2))*2,D0 // size for 2 x XBRA jumper + move.l _membot,A0 // boot alloc + add.l D0,_membot + move.l #0x58425241,D0 // XBRA + move.l D0,(A0) + move.l D0,18(A0) + move.l #0x63743630,D0 // ct60 + move.l D0,4(A0) + move.l D0,22(A0) + move.w SR,-(SP) + or.w #0x700,SR + move.l A0,RESERVED_VEC // save address of XBRA jumper + move.l XBIOS_VEC,8(A0) // trap #14 vector saved + move.w #0x4EF9,12(A0) // JMP + lea det_xbios_magic(PC),A1 + move.l A1,14(A0) + lea 12(A0),A0 + move.l A0,XBIOS_VEC // to jumper + addq.l #6,A0 // 2nd jumper + move.l hdv_boot,8(A0) // hdv_boot vector saved + move.w #0x4EF9,12(A0) // JMP + lea det_hdv_boot_magic(PC),A1 + move.l A1,14(A0) + lea 12(A0),A6 + cpusha BC // flush cache for JMP + move.w (SP)+,SR + move.w #2,-(SP) + lea -2(SP),A0 // install PCI BIOS 2nd time (no PCI RESET) + jsr _install_pci_bios(PC) + addq.l #2,SP + bmi .no_install + lea 0xE00FB6,A0 // exception fault vectors handler + lea 8,A1 + moveq #2,D0 // access fault, address fault, illegal instruction +.init_vectors: + move.l A0,(A1)+ + dbf D0,.init_vectors + bsr test_pci_drivers + bne.s .no_install // no PCI drivers + movec.l CACR,D0 + move.l D0,-(SP) // save CACR + cpusha BC + move.l #0xA0808000,D0 // enable caches + movec.l D0,CACR + move.l #2,-(SP) // no reset (started a 2nd time) for MagiC + jsr 4(A0) // drivers PCI in flash, init_devices + addq.l #4,SP + cpusha BC + move.l (SP)+,D0 // restore CACR + movec.l D0,CACR + clr.w -(SP) + lea -2(SP),A0 // display devices + jsr _install_pci_bios(PC) + addq.l #2,SP + move.l A6,hdv_boot // to jumper + cpusha BC // flush cache for JMP +.no_install: + movem.l (SP)+,D1-A6 + moveq #1,D0 + rte + +det_hdv_boot_magic: + + movem.l D1-D2/A0-A2,-(SP) + bsr install_magic_routine + bsr test_pci_drivers + bne.s .no_pci_drivers // no PCI drivers + jsr 10(A0) // drivers PCI in flash, call after SDRAM added +.no_pci_drivers: + move.l hdv_boot,A0 +.loop_xbra: + cmp.l #0x58425241,-12(A0) // XBRA + bne.s .no_xbra + cmp.l #0x63743630,-8(A0) // ct60 + bne.s .next_xbra + move.l -4(A0),D0 // old vector + movem.l (SP)+,D1-D2/A0-A2 + move.l D0,-(SP) // old vector + rts +.next_xbra: + move.l -4(A0),D0 + beq.s .no_xbra // no vector + move.l D0,A0 + bra.s .loop_xbra +.no_xbra: + movem.l (SP)+,D1-D2/A0-A2 + moveq #0,D0 + rts + +#endif /* COLDFIRE */ #include "pci_bios.S" @@ -4311,6 +5779,80 @@ tab_pci_bios: .align 4 +get_cookie: + +#ifdef COLDFIRE + move.l D1,-(SP) + move.l A0,-(SP) +#else + movem.l D1/A0,-(SP) +#endif + move.l D0,D1 // cookie + move.l cookie,D0 + beq.s .cookie_not_found + move.l D0,A0 +.loop_cookie: + tst.l (A0) + beq.s .cookie_not_found + cmp.l (A0),D1 + bne.s .next_cookie + move.l 4(A0),D0 + bra.s .end_cookie +.next_cookie: + addq.l #8,A0 + bra.s .loop_cookie +.cookie_not_found: + moveq #0,D0 +.end_cookie: +#ifdef COLDFIRE + move.l (SP)+,A0 + move.l (SP)+,D1 +#else + movem.l (SP)+,D1/A0 +#endif + tst.l D0 + rts + +add_cookie: + +#ifdef COLDFIRE + lea -12(SP),SP + movem.l D1-D2/A0,(SP) +#else + movem.l D1-D2/A0,-(SP) +#endif + move.l cookie,D2 + beq.s .cookie_not_found_add + move.l D2,A0 + moveq #0,D2 + bra.s .next_cookie_add +.loop_add_cookie: + addq.l #8,A0 + addq.l #1,D2 +.next_cookie_add: + tst.l (A0) + bne.s .loop_add_cookie + cmp.l 4(A0),D2 + bcc.s .cookie_not_found_add + move.l 4(A0),D2 + move.l D0,(A0) // cookie + move.l D1,4(A0) // value + addq.l #8,A0 + clr.l (A0) + move.l D2,4(A0) + moveq #1,D0 // OK + bra.s .end_add_cookie +.cookie_not_found_add: + moveq #0,D0 // error +.end_add_cookie: +#ifdef COLDFIRE + movem.l (SP),D1-D2/A0 + lea 12(SP),SP +#else + movem.l (SP)+,D1-D2/A0 +#endif + rts + #ifdef DEBUG_GEMDOS debug_gemdos: @@ -4402,7 +5944,54 @@ hex_value: .hv1: movem.l (SP)+,D1/A0 rts -#endif +#endif /* DEBUG_GEMDOS */ + +#ifndef COLDFIRE +get_no_cache_memory: + + movem.l A0-A5,-(SP) + move.w SR,-(SP) + or.w #0x700,SR // no interrupts + lea .no_memory(PC),A1 + move.l 8,A5 // bus error + move.l A1,8 + move.l SP,A4 // save ssp + moveq #0,D0 + move.l ramtop,A0 + clr.l (A0) // if access fault it's PMMU tree + move.l A0,D0 // buffer +.no_memory: + move.l A5,8 // restore bus error + move.l A4,SP // restore ssp + move.w (SP)+,SR + movem.l (SP)+,A0-A5 + rts + +get_no_cache_memory_size: + + move.l D1,-(SP) + bsr get_no_cache_memory + tst.l D0 + beq.s .no_memory_size + move.l D0,D1 + movec.l SRP,D0 // PMMU tree + sub.l D1,D0 + moveq #32,D1 +.loop_find_first_msb: + subq.l #1,D1 + add.l D0,D0 // search the first MSB to 1 + bcs.s .found_first_msb + tst.l D1 + bne.s .loop_find_first_msb + moveq #0,D0 // not found ? + bra.s .no_memory_size +.found_first_msb: + moveq #0,D0 + bset D1,D0 // size alignment +.no_memory_size: + move.l (SP)+,D1 + rts +#endif /* COLDFIRE */ nvm_access: @@ -4441,8 +6030,8 @@ nvm_access: moveq #CT60_MODE_READ,D0 // mode moveq #CT60_SAVE_NVRAM_1,D1 // type_param moveq #0,D2 // value -#ifdef COLDFIRE - bsr fire_rw_param +#if defined(COLDFIRE) && !defined(MCF547X) + jsr fire_rw_param move.w D0,(A3) // bootpreff clr.w D0 swap D0 @@ -4450,8 +6039,12 @@ nvm_access: bne .nvm_read lea pseudo_nvram_data,A0 move.w (A3),(A0) +#else /* ATARI - FIREBEE */ +#ifdef COLDFIRE + jsr fire_rw_param #else - bsr ct60_rw_param + jsr ct60_rw_param +#endif move.w D0,(A3) // bootpref swap D0 cmp.w #0x4E56,D0 // NV magic code @@ -4465,29 +6058,29 @@ nvm_access: move.w D1,-(SP) // write jsr 0xE02172 // NVMaccess lea 10(SP),SP -#endif +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ clr.l 2(A3) moveq #CT60_MODE_READ,D0 // mode moveq #CT60_SAVE_NVRAM_2,D1 // type_param moveq #0,D2 // value #ifdef COLDFIRE - bsr fire_rw_param + jsr fire_rw_param #else - bsr ct60_rw_param + jsr ct60_rw_param #endif move.l D0,6(A3) // language, keyboard, datetime, separator moveq #CT60_MODE_READ,D0 // mode moveq #CT60_SAVE_NVRAM_3,D1 // type_param moveq #0,D2 // value #ifdef COLDFIRE - bsr fire_rw_param + jsr fire_rw_param #else - bsr ct60_rw_param + jsr ct60_rw_param #endif rol.l #8,D0 move.b D0,10(A3) // bootdelay move.l D0,14(A3) // vmode, scsi, bootdelay -#ifdef COLDFIRE +#if defined(COLDFIRE) && !defined(MCF547X) lea pseudo_nvram_data+6,A0 lea 6(A3),A1 // buffer: language, keyboard, datetime, separator, bootdelay move.b (A1)+,(A0)+ @@ -4495,7 +6088,7 @@ nvm_access: move.b (A1)+,(A0)+ move.b (A1)+,(A0)+ move.b (A1)+,(A0)+ -#else +#else /* ATARI - FIREBEE */ pea 6(A3) // buffer: language, keyboard, datetime, separator, bootdelay move.w #5,-(SP) // size move.w #6,-(SP) // start @@ -4504,16 +6097,16 @@ nvm_access: move.w D1,-(SP) // write jsr 0xE02172 // NVMaccess lea 10(SP),SP -#endif +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ clr.b 11(A3) clr.w 12(A3) -#ifdef COLDFIRE +#if defined(COLDFIRE) && !defined(MCF547X) lea pseudo_nvram_data+14,A0 lea 14(A3),A1 // buffer: vmode, scsi move.b (A1)+,(A0)+ move.b (A1)+,(A0)+ move.b (A1)+,(A0)+ -#else +#else /* ATARI - FIREBEE */ pea 14(A3) // buffer: vmode, scsi move.w #3,-(SP) // size move.w #14,-(SP) // start @@ -4522,7 +6115,7 @@ nvm_access: move.w D1,-(SP) // write jsr 0xE02172 // NVMaccess lea 10(SP),SP -#endif +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ clr.b 17(A3) clr.l 18(A3) clr.l 24(A3) @@ -4564,9 +6157,8 @@ nvm_access: moveq #-5,D0 // error move.w 4(SP),D1 // mode .nvram_access: -#ifdef COLDFIRE +#if defined(COLDFIRE) && !defined(MCF547X) ext.l D1 - tst.l D1 bne .no_nvm_read #ifdef DEBUG lea debug1r(PC),A0 @@ -4672,37 +6264,161 @@ nvm_access: moveq #0,D0 .end_nvm: rts -#else - jmp 0xE02172 // NVMaccess +#else /* ATARI - FIREBEE */ +#if defined(COLDFIRE) && defined(MCF547X) /* FIREBEE */ + cmp.l #1,D1 // write nvm + bne .no_write_nvm + lea -20(SP),SP + movem.l D1-D2/A0-A2,(SP) + lea 0xFFFF8961,A1 // F030 RTC (offset 0) / NVM (offset 14) - FPGA emulation + lea 0xFFFF8963,A2 + moveq #0,D0 + moveq #14,D1 + moveq #0,D2 +.loop_sum_nvram: + move.b D1,(A1) + move.b (A2),D2 + add.l D2,D0 + addq.l #1,D1 + cmp.l #64-2,D1 + bcs.s .loop_sum_nvram + and.l #0xFF,D0 + move.l D0,D1 + moveq #-12,D0 // error + move.b #63,(a1) + move.b (A2),D2 + cmp.l D2,D1 + bne .write_nvm_error + eor.l #0xFF,D1 + move.b #62,(A1) + move.b (A2),D2 + cmp.l D2,D1 + bne .write_nvm_error + moveq #-5,d0 // error + move.w 6+20(SP),D1 // start + cmp.l #48,D1 + bcc .write_nvm_error + move.w 8+20(SP),D2 // size + bmi .write_nvm_error + add.l D1,D2 + cmp.l #48,D2 + bhi .write_nvm_error + move.w 6+20(SP),D1 // start + add.l #14,D1 // offset + move.w 8+20(SP),D2 // size + move.l 10+20(SP),A0 // buffer + bra.s .next_write_nvm +.loop_write_nvm: + move.b D1,(A1) + move.b (A0)+,(A2) + addq.l #1,D1 +.next_write_nvm: + subq.l #1,D2 + bpl.s .loop_write_nvm + moveq #0,D0 + moveq #14,D1 + moveq #0,D2 +.loop_sum_nvram2: + move.b D1,(A1) + move.b (A2),D2 + add.l D2,D0 + addq.l #1,D1 + cmp.l #64-2,D1 + bcs.s .loop_sum_nvram2 + move.b #63,(A1) + move.b D0,(A2) + not.l D0 + move.b #62,(A1) // update sum + move.b D0,(A2) +#ifdef DEBUG + lea debug56(PC),A0 + bsr debug_display_string #endif + move.b #0x82,D0 // header + move.b D0,MCF_UART_UTB3 // data + moveq #0,D1 +.write_nvm_to_pic: + move.b MCF_UART_USR3,D0 + and.l #MCF_UART_USR_TXEMP,D0 + beq.s .write_nvm_to_pic // full + move.b D1,(A1) // index + move.b (A2),D0 // data + move.b D0,MCF_UART_UTB3 // send data + addq.l #1,D1 + cmp.l #64,D1 + bcs.s .write_nvm_to_pic + moveq #0,D0 // OK +.write_nvm_error: + movem.l (SP),D1-D2/A0-A2 + lea 20(SP),SP + rts +.no_write_nvm: + tst.l D1 +#endif /* defined(COLDFIRE) && defined(MCF547X) */ + jmp 0xE02172 // NVMaccess +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ test_rtc: -#ifdef COLDFIRE +#if defined(COLDFIRE) && !defined(MCF547X) #ifdef DEBUG -// move.l A0,-(SP) -// lea debug23(PC),A0 -// bsr debug_display_string -// move.l (SP)+,A0 + move.l A0,-(SP) + lea debug23(PC),A0 + bsr debug_display_string + move.l (SP)+,A0 #endif -#else +#else /* ATARI - FIREBEE */ movem.l D0-D2,-(SP) moveq #CT60_MODE_READ,D0 // mode moveq #CT60_SAVE_NVRAM_1,D1 // type_param moveq #0,D2 // value - bsr ct60_rw_param +#ifdef COLDFIRE + jsr fire_rw_param +#else + jsr ct60_rw_param +#endif swap D0 cmp.w #0x4E56,D0 // NV magic code movem.l (SP)+,D0-D2 bne .use_rtc -#endif +#endif /* defined(COLDFIRE) && !defined(MCF547X) */ or.b #1,CCR // use IKBD clock rts -#ifndef COLDFIRE +#if !defined(COLDFIRE) || defined(MCF547X) .use_rtc: and.b #0xFE,CCR // use RTC clock rts #endif + +#if defined(COLDFIRE) && defined(MCF547X) +end_settime_rtc: + + lea -24(SP),SP + movem.l D0-D2/A0-A2,(SP) + lea 0xFFFF8961,A1 // F030 RTC (offset 0) / NVM (offset 14) - FPGA emulation + lea 0xFFFF8963,A2 + move.b #0xE,(A2) +#ifdef DEBUG + lea debug56(PC),A0 + bsr debug_display_string +#endif + move.b #0x82,D0 // header + move.b D0,MCF_UART_UTB3 // data + moveq #0,D1 +.write_rtc_to_pic: + move.b MCF_UART_USR3,D0 + and.l #MCF_UART_USR_TXEMP,D0 + beq.s .write_rtc_to_pic // full + move.b D1,(A1) // index + move.b (A2),D0 // data + move.b D0,MCF_UART_UTB3 // send data to PIC + addq.l #1,D1 + cmp.l #64,D1 + bcs.s .write_rtc_to_pic + movem.l (SP),D0-D2/A0-A2 + lea 24(SP),SP + rts +#endif /* defined(COLDFIRE) && defined(MCF57X) */ fix_settime: @@ -4714,405 +6430,23 @@ fix_settime: sub.w #100,D0 .year_before_2000_settime: rts - + #ifdef COLDFIRE -fire_rw_param: // D0.W: mode, D1.L: type_param, D2.L: value - - lea -52(SP),SP - movem.l D1-A5,(SP) - link A6,#-MAX_PARAM_FLASH*4 - tst.l D1 - bmi out_param - cmp.l #MAX_PARAM_FLASH-1,D1 // type_param - bcc out_param - addq.l #1,D1 - asl.l #2,D1 // param * 4 - move.l MCF_FBCS_CSAR0,D3 - and.l #0xFFFF0000,D3 - lea FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE,A2 - add.l D3,A2 // base parameters - moveq #-1,D3 - move.l #NB_BLOCK_PARAM-1,D4 - moveq #0,D6 -find_last_block: - cmp.l (A2),D3 - beq.s test_free_block -next_block: - lea SIZE_BLOCK_PARAM(A2),A2 - add.l #SIZE_BLOCK_PARAM,D6 // offset free block - subq.l #1,D4 - bpl.s find_last_block - moveq #0,D6 // offset free block - lea -SIZE_BLOCK_PARAM(A2),A2 - moveq #-1,D7 // erase sector if writing - bra.s test_read -test_free_block: - lea 4(A2),A3 - moveq #MAX_PARAM_FLASH-2,D5 -loop_test_free_block: - cmp.l (A3)+,D3 - bne.s next_block - subq.l #1,D5 - bpl.s loop_test_free_block - moveq #0,D7 // writing inside the next block - tst.l D6 - beq.s test_read // 1st block is free block - lea -SIZE_BLOCK_PARAM(A2),A2 -test_read: - and.l #1,D0 // mode - beq read_param - move.l (A2,D1.l),D0 -#ifdef DEBUG - move.l D0,-(SP) - lea debug3(PC),A0 - bsr debug_display_string - move.l D1,D0 - lsr.l #2,D0 - subq.l #1,D0 - bsr debug_hex_char - lea debug3w(PC),A0 - bsr debug_display_string - move.l D2,D0 - bsr debug_hex_long - moveq #0x20,D0 - bsr debug_display_char - moveq #0x30,D0 - bsr debug_display_char - moveq #0x78,D0 - bsr debug_display_char - move.b D7,D0 - bsr debug_hex_byte - moveq #0x20,D0 - bsr debug_display_char - moveq #0x30,D0 - bsr debug_display_char - moveq #0x78,D0 - bsr debug_display_char - move.l A2,D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif - cmp.l D0,D2 - beq end_param // no change - lea -MAX_PARAM_FLASH*4(A6),A3 - addq.l #4,A2 - clr.l (A3)+ // block used - moveq #MAX_PARAM_FLASH-2,D0 -save_param: - move.l (A2)+,(A3)+ // save params in the stack - subq.l #1,D0 - bpl.s save_param // before erase sector command - move.l D2,-MAX_PARAM_FLASH*4(A6,D1.L) // value - bsr fire_write_param - bra.s end_param -read_param: -#ifdef DEBUG - lea debug3(PC),A0 - bsr debug_display_string - move.l D1,D0 - lsr.l #2,D0 - subq.l #1,D0 - bsr debug_hex_char -#endif - move.l (A2,D1.l),D0 -#ifdef DEBUG - move.l D0,-(SP) - lea debug3r(PC),A0 - bsr debug_display_string - move.l (SP),D0 - bsr debug_hex_long - moveq #13,D0 - bsr debug_display_char - moveq #10,D0 - bsr debug_display_char - move.l (SP)+,D0 -#endif - bra.s end_param -out_param: - moveq #-5,D0 // unimplemented opcode -end_param: - unlk A6 - movem.l (SP),D1-A5 - lea 52(SP),SP - rts - -fire_write_param: +#ifdef MCF547X -#ifdef MCF5445X /* M54455EVB */ - - move.l D2,-(SP) // save value - lea devices(PC),A1 - add.l 4(A1),A1 // sector of device - movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 - moveq #FLASH_WP,D3 - move.b D3,CPLD_FLASHCFG // unprotect flash - move.l MCF_FBCS_CSAR0,D3 // boot flash - and.l #0xFFFF0000,D3 - add.l D3,A2 // base parameters - add.l D6,A2 // offset free block - add.l D3,A3 // base parameters (last sector) - move.w #CMD_UNLOCK1,(A3) - move.w #CMD_UNLOCK2,(A3) - tst.w D7 - beq.s erase_sector_end - move.w #CMD_SECTOR_ERASE1,(A3) - move.w #CMD_SECTOR_ERASE2,(A3) // Erase sector command -wait_erase_loop: - move.w #CMD_STATUS,(A3) - move.w (A3),D0 - btst #7,D0 - beq.s wait_erase_loop - move.w #CMD_READ,(A3) -erase_sector_end: - lea -MAX_PARAM_FLASH*4(A6),A0 // buffer - moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter -program_byte_loop: - move.w #CMD_PROGRAM,(A2) // Byte program command - move.w (A0),(A2) -wait_program_loop: - move.w #CMD_STATUS,(A2) - move.w (A2),D0 - btst #7,D0 - beq.s wait_program_loop - move.w #CMD_READ,(A2) - move.w (A2),D0 - cmp.w (A0),D0 - beq.s program_byte_ok - addq.l #4,SP - moveq #-10,D0 // write error - bra.s program_param_loop_end -program_byte_ok: - addq.l #2,A2 - addq.l #2,A0 - subq.l #1,D6 - bpl.s program_byte_loop - move.l (SP)+,D0 -program_param_loop_end: - move.w #CMD_LOCK1,(A3) - move.w #CMD_LOCK2,(A3) - move.w #CMD_READ,(A3) - moveq #0,D1 - move.b D1,CPLD_FLASHCFG // protect flash - rts - -devices: - dc.l 0x00890018, intel_28f128j3d-devices - dc.l 0 - -intel_28f128j3d: - dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE - dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 +fix_gettime: -#else -#ifdef MCF547X /* COLDARI */ - - move.l D2,-(SP) // save value - lea devices(PC),A1 - add.l 4(A1),A1 // sector of device - move.l (A1),A2 // sector - move.l 4(A1),A0 // flash_unlock1 - move.l 8(A1),A1 // flash_unlock2 - move.l MCF_FBCS_CSMR0,D3 - and.l #~MCF_FBCS_CSMR_WP,D3 // unprotect flash - move.l D3,MCF_FBCS_CSMR0 - move.l MCF_FBCS_CSAR0,D3 // boot flash - and.l #0xFFFF0000,D3 - add.l D3,A2 // base parameters - add.l D3,A0 - add.l D3,A1 - move.w #CMD_UNLOCK1,D3 - move.w #CMD_UNLOCK2,D4 - move.w #CMD_AUTOSELECT,D5 - move.w #CMD_READ,D1 - move.w D3,(A0) // unlock - move.w D4,(A1) - move.w D5,(A0) // Autoselect command - move.l (A2),D0 // Manufacturer code / Device code - move.w D1,(A2) // Read/Reset command - lea devices(PC),A3 -loop_dev: - tst.l (A3) - beq no_dev - cmp.l (A3),D0 - beq.s found_dev - addq.l #8,A3 - bra.s loop_dev -no_dev: - addq.l #4,SP - moveq #-15,D0 // device error - bra program_param_loop_end_2 -found_dev: - lea devices(PC),A1 - add.l 4(A3),A1 // sector of device - movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 - move.l MCF_FBCS_CSAR0,D3 // boot flash - and.l #0xFFFF0000,D3 - add.l D3,A2 // base parameters - add.l D6,A2 // offset free block - add.l D3,A3 // base parameters (last sector) - add.l D3,A4 - tst.w D7 - beq.s erase_sector_end - move.w #CMD_SECTOR_ERASE1,D5 - move.w #CMD_SECTOR_ERASE2,D6 - move.w D3,(A3) // unlock - move.w D4,(A4) - move.w D5,(A3) - move.w D3,(A3) // unlock - move.w D4,(A4) - move.w D6,(A2) // Erase sector command -wait_erase_loop: - move.w (A2),D0 - btst #7,D0 - bne.s erase_sector_end - btst #5,D0 - beq.s wait_erase_loop - move.w (A2),D0 - btst #7,D0 - bne.s erase_sector_end - addq.l #4,SP - moveq #-10,D0 // write error - bra.s program_param_loop_end -erase_sector_end: - lea -MAX_PARAM_FLASH*4(A6),A0 // buffer - move.w #CMD_PROGRAM,D5 - moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter -program_byte_loop: - moveq #15,D7 // retry counter -program_byte_retry: - move.w D3,(A3) // unlock - move.w D4,(A4) - move.w D5,(A3) // Byte program command - move.w (A0),D0 - move.w D0,(A2) - and.l #0x80,D0 -wait_program_loop: - move.w (A2),D1 - and.l #0xFF,D1 - eor.l D0,D1 - bpl.s wait_program_loop_end - btst #5,D1 // error - beq.s wait_program_loop - move.w (A2),D1 - and.l #0xFF,D1 - eor.l D0,D1 - bpl.s wait_program_loop_end -program_byte_error: - subq.l #1,D7 - bpl.s program_byte_retry - addq.l #4,SP - moveq #-10,D0 // write error - bra.s program_param_loop_end -wait_program_loop_end: - move.w (A2),D1 - cmp.w (A0),D1 - bne.s program_byte_error - addq.l #2,A2 - addq.l #2,A0 - subq.l #1,D6 - bpl.s program_byte_loop - move.l (SP)+,D0 -program_param_loop_end: - move.w #CMD_READ,D5 - move.w D3,(A3) - move.w D4,(A4) - move.w D5,(A3) // Read/Reset command -program_param_loop_end_2: - move.l MCF_FBCS_CSMR0,D3 - or.l #MCF_FBCS_CSMR_WP,D3 // protect flash - move.l D3,MCF_FBCS_CSMR0 - rts - -devices: - dc.l 0x000122d7, amd_29lv640-devices - dc.l 0 - -amd_29lv640: - dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE - dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 - -#else /* MCF548X - M5484LITE */ - - move.l D2,-(SP) // save value - lea devices(PC),A1 - add.l 4(A1),A1 // sector of device - move.l MCF_SIU_JTAGID,D0 // check the processor (not a good method => must check the flash device !) - and.l #MCF_SIU_JTAGID_PROCESSOR,D0 - cmp.l #MCF_SIU_JTAGID_MCF5485,D0 - beq.s .m5485evb // M5485EVB 16F160C3 - lea devices(PC),A1 // M5484LITE 28F320C3 - add.l 4+8(A1),A1 // sector of device -.m5485evb: - movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 - move.l MCF_FBCS_CSAR0,D3 // boot flash - and.l #0xFFFF0000,D3 - add.l D3,A2 // base parameters - add.l D6,A2 // offset free block - add.l D3,A3 // base parameters (last sector) - move.w #CMD_UNLOCK1,(A3) - move.w #CMD_UNLOCK2,(A3) - tst.w D7 - beq.s erase_sector_end - move.w #CMD_SECTOR_ERASE1,(A3) - move.w #CMD_SECTOR_ERASE2,(A3) // Erase sector command -wait_erase_loop: - move.w #CMD_STATUS,(A3) - move.w (A3),D0 - btst #7,D0 - beq.s wait_erase_loop - move.w #CMD_READ,(A3) -erase_sector_end: - lea -MAX_PARAM_FLASH*4(A6),A0 // buffer - moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter -program_byte_loop: - move.w #CMD_PROGRAM,(A2) // Byte program command - move.w (A0),(A2) -wait_program_loop: - move.w #CMD_STATUS,(A2) - move.w (A2),D0 - btst #7,D0 - beq.s wait_program_loop - move.w #CMD_READ,(A2) - move.w (A2),D0 - cmp.w (A0),D0 - beq.s program_byte_ok - addq.l #4,SP - moveq #-10,D0 // write error - bra.s program_param_loop_end -program_byte_ok: - addq.l #2,A2 - addq.l #2,A0 - subq.l #1,D6 - bpl.s program_byte_loop - move.l (SP)+,D0 -program_param_loop_end: - move.w #CMD_LOCK1,(A3) - move.w #CMD_LOCK2,(A3) - move.w #CMD_READ,(A3) + sub.b #80,D0 // 1980 + bpl.s .year_before_2000_gettime + add.b #100,D0 +.year_before_2000_gettime: + move.b D0,D2 rts - -devices: - dc.l 0x008988C2, intel_28f160c3b-devices // M5485EVB - dc.l 0x008988C4, intel_28f320c3b-devices // M5484LITE - dc.l 0 - -intel_28f160c3b: - dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE - dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 - -intel_28f320c3b: - dc.l FLASH_TOS_FIRE_ENGINE-BOOT_FLASH_BASE+FLASH_SIZE-PARAM_SIZE - dc.l FLASH_UNLOCK1, FLASH_UNLOCK2 #endif /* MCF547X */ -#endif /* MCF5445X */ -#else /* ATARI - CT60 */ +#else /* ATARI -CT60 */ fix_gettime: @@ -5123,334 +6457,18 @@ fix_gettime: move.b D0,D2 rts -ct60_read_temp: - - movem.l D1-D3/A0-A2,-(SP) - move.w SR,-(SP) - or.w #0x700,SR // no interrupts - lea ct1(PC),A0 - move.l 8,A1 // bus error - move.l A0,8 - move.l SP,A2 - lea _tcdr_mfp,A0 // timer C value changed at each 26 uS (clock 19,2 KHz) - tst.b _tbcr_mfp - bne ct8 // timer B used - bclr #0,_imra_mfp - bclr #0,_iera_mfp - bclr #0,_ipra_mfp - bclr #0,_isra_mfp - lea _tbdr_mfp,A0 - move.b #2,(A0) // clock = 307,2 KHz 1,6 uS - move.b #1,_tbcr_mfp // 2,4576MHz/4 -ct8: - clr.l _texas_tlv0831_cs_low // cs=0 - move.b (A0),D0 -wait1: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait1 - clr.l _texas_tlv0831_clk_high // clk=1 (10 to 600 KHz for the tlv0831) - move.b (A0),D0 -wait2: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait2 - clr.l _texas_tlv0831_clk_low // clk=0 - move.b (A0),D0 -wait3: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait3 - clr.l _texas_tlv0831_clk_high // clk=1 - move.b (A0),D0 -wait4: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait4 - clr.l _texas_tlv0831_clk_low // clk=0 - move.b (A0),D0 -wait5: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait5 - move.l A1,8 - move.l A2,SP - move.w (SP),SR - moveq #0,D3 // data - moveq #7,D2 // 8 bits -ct4: clr.l _texas_tlv0831_clk_high // clk=1 - move.l _texas_tlv0831_data,d1 - lsr.l #1,D1 // data - addx.w D3,D3 - move.b (A0),D0 -wait6: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait6 - clr.l _texas_tlv0831_clk_low // clk=0 - move.b (A0),D0 -wait7: - cmp.b (A0),D0 // 26uS (timer C) or 1,6uS (timer B) - beq.s wait7 - dbf D2,ct4 - clr.l _texas_tlv0831_cs_high // cs=1 - cmp.w #MES_TEMP_ERROR,D3 // error - beq.s ct3 - moveq #0,D2 // value - moveq #CT60_PARAM_OFFSET_TLV,D1 // type_param - moveq #CT60_MODE_READ,D0 // read - bsr ct60_rw_param - add.l D3,D0 // offset - bmi.s ct5 - cmp.w #MES_TEMP_0,D0 - bcs.s ct5 - cmp.w #MES_TEMP_25,D0 - bcc.s ct6 - sub.w #MES_TEMP_0,D0 - mulu #25,D0 - divu #(MES_TEMP_25-MES_TEMP_0),D0 - ext.l D0 - bra.s ct2 -ct6: - cmp.w #MES_TEMP_50,D0 - bcc.s ct7 - sub.w #MES_TEMP_25,D0 - mulu #25,D0 - divu #(MES_TEMP_50-MES_TEMP_25),D0 - add.w #25,D0 - ext.l D0 - bra.s ct2 -ct7: - sub.w #MES_TEMP_50,D0 - mulu #50,D0 - divu #(MES_TEMP_100-MES_TEMP_50),D0 - add.w #50,D0 - ext.l D0 - bra.s ct2 -ct5: - moveq #0,D0 - bra.s ct2 -ct3: - moveq #CT60_READ_ERROR,D0 // error - bra.s ct2 -ct1: - moveq #CT60_READ_ERROR,D0 // bus error - move.l A1,8 - move.l A2,SP -ct2: - lea _tbdr_mfp,A1 - cmp.l A0,A1 - bne.s ct9 // timer C - clr.b _tbcr_mfp // timer B stopped -ct9: - move (SP)+,SR - tst.l D0 - movem.l (SP)+,D1-D3/A0-A2 - rts - -ct60_rw_param: // D0.W: mode, D1.L: type_param, D2.L: value +#endif /* COLDFIRE */ - movem.l D1-A5,-(SP) - link A6,#-MAX_PARAM_FLASH*4 - tst.l D1 - bmi out_param - cmp.l #MAX_PARAM_FLASH-1,D1 // type_param - bcc out_param - addq.l #1,D1 - asl.l #2,D1 // param * 4 - lea FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0xFF000000,A2 - moveq #-1,D3 - move.l #NB_BLOCK_PARAM-1,D4 - moveq #0,D6 -find_last_block: - cmp.l (A2),D3 - beq.s test_free_block -next_block: - lea SIZE_BLOCK_PARAM(A2),A2 - add.l #SIZE_BLOCK_PARAM,D6 // offset free block - dbf D4,find_last_block - moveq #0,D6 // offset free block - lea -SIZE_BLOCK_PARAM(A2),A2 - moveq #-1,D7 // erase sector if writing - bra.s test_read -test_free_block: - lea 4(A2),A3 - moveq #MAX_PARAM_FLASH-2,D5 -loop_test_free_block: - cmp.l (A3)+,D3 - dbne D5,loop_test_free_block - bne.s next_block - moveq #0,D7 // writing inside the next block - tst.l D6 - beq.s test_read // 1st block is free block - lea -SIZE_BLOCK_PARAM(A2),A2 -test_read: - and #1,D0 // mode - beq read_param - move.l (A2,D1.l),D0 - cmp.l D0,D2 - beq end_param // no change - lea -MAX_PARAM_FLASH*4(A6),A3 - addq.l #4,A2 - clr.l (A3)+ // block used - moveq #MAX_PARAM_FLASH-2,D0 -save_param: - move.l (A2)+,(A3)+ // save params in the stack - dbf D0,save_param // before erase sector command - move.l D2,-MAX_PARAM_FLASH*4(A6,D1.L) // value - move.w SR,-(SP) - or #0x700,SR // lock interrupts - lea ct60_write_param(PC),A0 - lea end_ct60_write_param(PC),A2 - move.l phystop,A1 - movec.l SRP,D3 - sub.l #RESERVE_MEM_FONTS-0x6800,A1 - cmp.l #0x1000000,D3 - bcc.s .sdram - sub.l #RESERVE_MEM-RESERVE_MEM_FONTS,A1 -.sdram: - sub.l A0,A2 - move.l A2,D3 - move.l A1,A2 - lsr.l #1,D3 - subq.l #1,D3 -copy_prog: - move.w (A0)+,(A1)+ // copy program in the top of the STRAM - dbf D3,copy_prog // after the copy of Atari logo - movec.l CACR,D3 - move.l D3,A5 // save CACR - cpusha DC - bclr.l #31,D3 - movec.l D3,CACR // no cache - cinva DC - jsr (A2) // ct60_write_param - cpusha DC - move.l A5,D2 - movec.l D2,CACR - move.w (SP)+,SR - bra.s end_param -read_param: - move.l (A2,D1.l),D0 - bra.s end_param -out_param: - moveq #-5,D0 // unimplemented opcode -end_param: - unlk A6 - movem.l (SP)+,D1-A5 - rts +power_key: -ct60_write_param: - - moveq #3,D3 - movec.l D3,SFC // CPU space 3 - movec.l D3,DFC - move.l D2,-(SP) // save value - lea FLASH_UNLOCK1+0xFF000000,A0 - lea FLASH_UNLOCK2+0xFF000000,A1 - lea FLASH_ADR+FLASH_SIZE-PARAM_SIZE+0xFF000000,A2 - move.w #CMD_UNLOCK1,D3 - move.w #CMD_UNLOCK2,D4 - move.w #CMD_AUTOSELECT,D5 - move.w #CMD_READ,D1 - moves.w D3,(A0) // unlock - moves.w D4,(A1) - moves.w D5,(A0) // Autoselect command - move.l (A2),D0 // Manufacturer code / Device code - moves.w D1,(A2) // Read/Reset command - lea devices(PC),A3 -loop_dev: - tst.l (A3) - beq no_dev - cmp.l (A3),D0 - beq.s found_dev - addq.l #8,A3 - bra.s loop_dev -no_dev: - addq.l #4,SP - moveq #-15,D0 // device error - bra program_param_loop_end_2 -found_dev: - lea devices(PC),A1 - add.l 4(A3),A1 // sector of device - movem.l (A1),A2-A4 // sector, flash_unlock1, flash_unlock2 - add.l D6,A2 // offset free block - tst.w D7 - beq.s erase_sector_end - move.w #CMD_SECTOR_ERASE1,D5 - move.w #CMD_SECTOR_ERASE2,D6 - moves.w D3,(A3) // unlock - moves.w D4,(A4) - moves.w D5,(A3) - moves.w D3,(A3) // unlock - moves.w D4,(A4) - moves.w D6,(A2) // Erase sector command -wait_erase_loop: - move.w (A2),D0 - btst #7,D0 - bne.s erase_sector_end - btst #5,D0 - beq.s wait_erase_loop - move.w (A2),D0 - btst #7,D0 - bne.s erase_sector_end - addq.l #4,SP - moveq #-10,D0 // write error - bra.s program_param_loop_end -erase_sector_end: - lea -MAX_PARAM_FLASH*4(A6),A0 // buffer - move.w #CMD_PROGRAM,D5 - moveq #(MAX_PARAM_FLASH*2)-1,D6 // word counter -program_byte_loop: - moveq #15,D7 // retry counter -program_byte_retry: - moves.w D3,(A3) // unlock - moves.w D4,(A4) - moves.w D5,(A3) // Byte program command - move.w (A0),D0 - moves.w D0,(A2) - and.b #0x80,D0 -wait_program_loop: - move.w (A2),D1 - eor.b D0,D1 - bpl.s wait_program_loop_end - btst #5,D1 // error - beq.s wait_program_loop - move.w (A2),D1 - eor.b D0,D1 - bpl.s wait_program_loop_end -program_byte_error: - dbf D7,program_byte_retry - addq.l #4,SP - moveq #-10,D0 // write error - bra.s program_param_loop_end -wait_program_loop_end: - move.w (A2),D1 - cmp.w (A0),D1 - bne.s program_byte_error - addq.l #2,A2 - addq.l #2,A0 - dbf D6,program_byte_loop + move.l D0,-(SP) + move.l A0,-(SP) + move.l phystop,A0 + move.l #0xCAFEFADE,D0 + move.l D0,power_flag(A0) // tested inside evnt_multi AES + move.l (SP)+,A0 move.l (SP)+,D0 -program_param_loop_end: - move.w #CMD_READ,D5 - moves.w D3,(A3) - moves.w D4,(A4) - moves.w D5,(A3) // Read/Reset command -program_param_loop_end_2: rts - -devices: - dc.l 0x000422AB, fujitsu_mbm29f400bc-devices - dc.l 0x00042258, fujitsu_mbm29f800ba-devices - dc.l 0x00012258, amd_am29f800bb-devices - dc.l 0x00202258, st_m29f800db-devices - dc.l 0 - -fujitsu_mbm29f400bc: - dc.l FLASH_ADR+0xFF0F0000, FLASH_UNLOCK1+0xFF000000, FLASH_UNLOCK2+0xFF000000 - -fujitsu_mbm29f800ba: -amd_am29f800bb: -st_m29f800db: - dc.l FLASH_ADR+0xFF0F0000, FLASH_UNLOCK1+0xFF000000, FLASH_UNLOCK2+0xFF000000 - -end_ct60_write_param: - -#endif /* COLDFIRE */ new_ikbdvect: // test Eiffel keys @@ -5511,13 +6529,7 @@ new_ikbdvect: // test Eiffel keys bne.s .test_shift btst #7,D0 bne.s .test_shift - move.l D0,-(SP) - move.l A0,-(SP) - move.l phystop,A0 - move.l #0xCAFEFADE,D0 - move.l D0,power_flag(A0) // tested inside evnt_multi AES - move.l (SP)+,A0 - move.l (SP)+,D0 + bsr power_key .test_shift: move.b 0x1187,D1 // Shift state cmp.l #0x2A,D0 @@ -5564,10 +6576,7 @@ new_ikbdvect: // test Eiffel keys bne.s .test_shift btst #7,D0 bne.s .test_shift - move.l A0,-(SP) - move.l phystop,A0 - move.l #0xCAFEFADE,power_flag(A0) // tested inside evnt_multi AES - move.l (SP)+,A0 + bsr power_key .test_shift: move.b 0x1187,D1 // Shift state cmp.b #0x2A,D0 @@ -5603,8 +6612,7 @@ det_statvec: movem.l D0/A0,-(SP) cmp.b #0x73,6(A0) // POWER bne.s .not_power - move.l phystop,A0 - move.l #0xCAFEFADE,power_flag(A0) // tested inside evnt_multi AES + bsr power_key bra .not_volume_down .not_power: cmp.b #0x32,6(A0) // VOLUME UP